From a9ce1e56bba94729f41c0fbba11012cf36c99227 Mon Sep 17 00:00:00 2001 From: Erik Norvell Date: Fri, 20 Dec 2024 12:31:24 +0100 Subject: [PATCH 01/33] Adding ivas-float-update, with split rendering and debugging options still kept --- CMakeLists.txt | 246 + Makefile | 48 +- Workspace_msvc/Workspace_msvc.sln | 208 +- Workspace_msvc/decoder.vcxproj | 340 +- Workspace_msvc/encoder.vcxproj | 354 +- Workspace_msvc/lib_com.vcxproj | 616 +- Workspace_msvc/lib_com.vcxproj.filters | 1100 +- Workspace_msvc/lib_debug.vcxproj | 235 +- Workspace_msvc/lib_dec.vcxproj | 698 +- Workspace_msvc/lib_dec.vcxproj.filters | 1142 +- Workspace_msvc/lib_enc.vcxproj | 730 +- Workspace_msvc/lib_enc.vcxproj.filters | 1256 +- Workspace_msvc/lib_lc3plus.vcxproj | 183 + Workspace_msvc/lib_rend.vcxproj | 439 +- Workspace_msvc/lib_rend.vcxproj.filters | 440 +- Workspace_msvc/lib_util.vcxproj | 316 +- Workspace_msvc/renderer.vcxproj | 358 +- lib_com/ACcontextMapping.c | 3 + lib_com/arith_coder.c | 3 + lib_com/basop_mpy.c | 3 + lib_com/basop_mpy.h | 3 + lib_com/basop_tcx_utils.c | 3 + lib_com/basop_util.c | 3 + lib_com/bitalloc.c | 3 + lib_com/bitallocsum.c | 3 + lib_com/bits_alloc.c | 63 + lib_com/bitstream.c | 724 + lib_com/calc_st_com.c | 3 + lib_com/cb_shape.c | 3 + lib_com/cldfb.c | 3 + lib_com/cng_exc.c | 3 + lib_com/cnst.h | 10 + lib_com/codec_tcx_common.c | 3 + lib_com/common_api_types.h | 95 + lib_com/core_com_config.c | 3 + lib_com/deemph.c | 3 + lib_com/delay_comp.c | 15 + lib_com/disclaimer.c | 3 + lib_com/dlpc_bfi.c | 3 + lib_com/edct.c | 7 + lib_com/enhancer.c | 3 + lib_com/enr_1_az.c | 3 + lib_com/env_adj.c | 3 + lib_com/env_stab.c | 9 + lib_com/env_stab_trans.c | 3 + lib_com/est_tilt.c | 3 + lib_com/fd_cng_com.c | 3 + lib_com/fft.c | 3 + lib_com/fft_rel.c | 3 + lib_com/fill_spectrum.c | 3 + lib_com/findpulse.c | 3 + lib_com/fine_gain_bits.c | 3 + lib_com/frame_ener.c | 3 + lib_com/get_gain.c | 3 + lib_com/gs_bitallocation.c | 6 + lib_com/gs_gains.c | 3 + lib_com/gs_inact_switching.c | 3 + lib_com/gs_noisefill.c | 3 + lib_com/gs_preech.c | 3 + lib_com/hp50.c | 3 + lib_com/hq2_bit_alloc.c | 3 + lib_com/hq2_core_com.c | 3 + lib_com/hq2_noise_inject.c | 3 + lib_com/hq_bit_allocation.c | 3 + lib_com/hq_conf.c | 3 + lib_com/hq_tools.c | 3 + lib_com/hvq_pvq_bitalloc.c | 3 + lib_com/ifft_rel.c | 3 + lib_com/igf_base.c | 3 + lib_com/index_pvq_opt.c | 3 + lib_com/int_lsp.c | 3 + lib_com/interleave_spectrum.c | 3 + lib_com/interpol.c | 3 + lib_com/isf_dec_amr_wb.c | 3 + lib_com/ivas_agc_com.c | 24 + lib_com/ivas_arith.c | 3 + lib_com/ivas_avq_pos_reorder_com.c | 3 + lib_com/ivas_cnst.h | 120 + lib_com/ivas_cov_smooth.c | 3 + lib_com/ivas_dirac_com.c | 10 + lib_com/ivas_entropy_coder_common.c | 3 + lib_com/ivas_error.h | 23 + lib_com/ivas_error_utils.h | 24 + lib_com/ivas_fb_mixer.c | 3 + lib_com/ivas_filters.c | 3 + lib_com/ivas_ism_com.c | 20 + lib_com/ivas_lfe_com.c | 3 + lib_com/ivas_masa_com.c | 6 + lib_com/ivas_mc_com.c | 3 + lib_com/ivas_mc_param_com.c | 6 + lib_com/ivas_mcmasa_com.c | 3 + lib_com/ivas_mdct_imdct.c | 3 + lib_com/ivas_mdft_imdft.c | 3 + lib_com/ivas_omasa_com.c | 3 + lib_com/ivas_pca_tools.c | 3 + lib_com/ivas_prot.h | 208 + lib_com/ivas_qmetadata_com.c | 13 + lib_com/ivas_qspherical_com.c | 30 + lib_com/ivas_rom_com.c | 115 + lib_com/ivas_rom_com.h | 14 + lib_com/ivas_sba_config.c | 3 + lib_com/ivas_sns_com.c | 3 + lib_com/ivas_spar_com.c | 47 + lib_com/ivas_spar_com_quant_util.c | 3 + lib_com/ivas_stat_com.h | 4 + lib_com/ivas_stereo_dft_com.c | 32 + lib_com/ivas_stereo_eclvq_com.c | 7 + lib_com/ivas_stereo_ica_com.c | 3 + lib_com/ivas_stereo_mdct_bands_com.c | 6 + lib_com/ivas_stereo_td_bit_alloc.c | 3 + lib_com/ivas_tools.c | 9 + lib_com/ivas_transient_det.c | 3 + lib_com/lag_wind.c | 3 + lib_com/limit_t0.c | 3 + lib_com/logqnorm.c | 3 + lib_com/low_rate_band_att.c | 3 + lib_com/lpc_tools.c | 3 + lib_com/lsf_msvq_ma.c | 3 + lib_com/lsf_tools.c | 27 + lib_com/lsp_conv_poly.c | 3 + lib_com/modif_fs.c | 3 + lib_com/options.h | 122 + lib_com/parameter_bitmaping.c | 3 + lib_com/phase_dispersion.c | 3 + lib_com/ppp.c | 3 + lib_com/pred_lt4.c | 3 + lib_com/preemph.c | 3 + lib_com/prot.h | 86 + lib_com/pvq_com.c | 3 + lib_com/range_com.c | 3 + lib_com/re8_ppv.c | 3 + lib_com/re8_util.c | 3 + lib_com/realft.c | 3 + lib_com/recovernorm.c | 3 + lib_com/reordvct.c | 3 + lib_com/residu.c | 3 + lib_com/rom_com.c | 3 + lib_com/rom_com.h | 3 + lib_com/stab_est.c | 3 + lib_com/stat_com.h | 3 + lib_com/stat_noise_uv_mod.c | 3 + lib_com/swb_bwe_com.c | 3 + lib_com/swb_bwe_com_hr.c | 3 + lib_com/swb_bwe_com_lr.c | 3 + lib_com/swb_tbe_com.c | 3 + lib_com/syn_12k8.c | 3 + lib_com/syn_filt.c | 3 + lib_com/tcq_position_arith.c | 3 + lib_com/tcx_ltp.c | 12 + lib_com/tcx_mdct_window.c | 3 + lib_com/tcx_utils.c | 3 + lib_com/tools.c | 3 + lib_com/trans_direct.c | 3 + lib_com/trans_inv.c | 3 + lib_com/weight.c | 3 + lib_com/weight_a.c | 3 + lib_com/window.c | 3 + lib_com/window_ola.c | 3 + lib_com/wtda.c | 9 + lib_debug/debug.c | 978 + lib_debug/debug.h | 257 + lib_debug/sba_debug.c | 431 + lib_debug/sba_debug.h | 61 + lib_debug/snr.c | 465 + lib_dec/ACcontextMapping_dec.c | 12 + lib_dec/FEC.c | 3 + lib_dec/FEC_HQ_core.c | 3 + lib_dec/FEC_HQ_phase_ecu.c | 3 + lib_dec/FEC_adapt_codebook.c | 3 + lib_dec/FEC_clas_estim.c | 3 + lib_dec/FEC_lsf_estim.c | 3 + lib_dec/FEC_pitch_estim.c | 3 + lib_dec/FEC_scale_syn.c | 3 + lib_dec/LD_music_post_filter.c | 3 + lib_dec/TonalComponentDetection.c | 3 + lib_dec/acelp_core_dec.c | 18 + lib_dec/acelp_core_switch_dec.c | 3 + lib_dec/amr_wb_dec.c | 17 + lib_dec/arith_coder_dec.c | 3 + lib_dec/avq_dec.c | 3 + lib_dec/bass_psfilter.c | 7 + lib_dec/cng_dec.c | 6 + lib_dec/core_dec_init.c | 3 + lib_dec/core_dec_reconf.c | 3 + lib_dec/core_dec_switch.c | 3 + lib_dec/core_switching_dec.c | 3 + lib_dec/d_gain2p.c | 3 + lib_dec/dec2t32.c | 3 + lib_dec/dec4t64.c | 3 + lib_dec/dec_LPD.c | 3 + lib_dec/dec_ace.c | 3 + lib_dec/dec_acelp_tcx_main.c | 3 + lib_dec/dec_amr_wb.c | 3 + lib_dec/dec_gen_voic.c | 3 + lib_dec/dec_higher_acelp.c | 3 + lib_dec/dec_nelp.c | 3 + lib_dec/dec_pit_exc.c | 3 + lib_dec/dec_post.c | 3 + lib_dec/dec_ppp.c | 3 + lib_dec/dec_prm.c | 3 + lib_dec/dec_tcx.c | 38 + lib_dec/dec_tran.c | 3 + lib_dec/decision_matrix_dec.c | 3 + lib_dec/dlpc_stoch.c | 3 + lib_dec/er_dec_acelp.c | 3 + lib_dec/er_dec_tcx.c | 3 + lib_dec/er_util.c | 11 + lib_dec/evs_dec.c | 34 + lib_dec/fd_cng_dec.c | 50 + lib_dec/gain_dec.c | 3 + lib_dec/gaus_dec.c | 3 + lib_dec/gs_dec.c | 3 + lib_dec/gs_dec_amr_wb.c | 3 + lib_dec/hdecnrm.c | 3 + lib_dec/hf_synth.c | 3 + lib_dec/hq_classifier_dec.c | 3 + lib_dec/hq_conf_fec.c | 3 + lib_dec/hq_core_dec.c | 3 + lib_dec/hq_env_dec.c | 3 + lib_dec/hq_hr_dec.c | 3 + lib_dec/hq_lr_dec.c | 3 + lib_dec/igf_dec.c | 13 + lib_dec/igf_scf_dec.c | 3 + lib_dec/init_dec.c | 3 + lib_dec/inov_dec.c | 3 + lib_dec/ivas_agc_dec.c | 20 + lib_dec/ivas_binRenderer_internal.c | 817 + lib_dec/ivas_core_dec.c | 133 + lib_dec/ivas_corecoder_dec_reconfig.c | 11 + lib_dec/ivas_cpe_dec.c | 44 + lib_dec/ivas_dec.c | 1122 + lib_dec/ivas_decision_matrix_dec.c | 3 + lib_dec/ivas_dirac_dec.c | 324 + lib_dec/ivas_dirac_output_synthesis_cov.c | 3 + lib_dec/ivas_entropy_decoder.c | 3 + lib_dec/ivas_init_dec.c | 448 + lib_dec/ivas_ism_dec.c | 54 + lib_dec/ivas_ism_dtx_dec.c | 63 + lib_dec/ivas_ism_metadata_dec.c | 3 + lib_dec/ivas_ism_param_dec.c | 43 + lib_dec/ivas_ism_renderer.c | 245 + lib_dec/ivas_jbm_dec.c | 388 + lib_dec/ivas_lfe_dec.c | 3 + lib_dec/ivas_lfe_plc.c | 3 + lib_dec/ivas_ls_custom_dec.c | 3 + lib_dec/ivas_masa_dec.c | 74 + lib_dec/ivas_mc_param_dec.c | 101 + lib_dec/ivas_mc_paramupmix_dec.c | 679 + lib_dec/ivas_mcmasa_dec.c | 3 + lib_dec/ivas_mct_core_dec.c | 3 + lib_dec/ivas_mct_dec.c | 120 + lib_dec/ivas_mdct_core_dec.c | 50 + lib_dec/ivas_objectRenderer_internal.c | 159 + lib_dec/ivas_omasa_dec.c | 129 + lib_dec/ivas_osba_dec.c | 258 + lib_dec/ivas_out_setup_conversion.c | 3 + lib_dec/ivas_output_config.c | 65 + lib_dec/ivas_pca_dec.c | 6 + lib_dec/ivas_post_proc.c | 57 + lib_dec/ivas_qmetadata_dec.c | 241 + lib_dec/ivas_range_uni_dec.c | 34 + lib_dec/ivas_rom_dec.c | 282 + lib_dec/ivas_rom_dec.h | 28 + lib_dec/ivas_sba_dec.c | 90 + lib_dec/ivas_sba_dirac_stereo_dec.c | 13 + lib_dec/ivas_sba_rendering_internal.c | 181 + lib_dec/ivas_sce_dec.c | 34 + lib_dec/ivas_spar_decoder.c | 104 +- lib_dec/ivas_spar_md_dec.c | 216 + lib_dec/ivas_stat_dec.h | 64 + lib_dec/ivas_stereo_adapt_GR_dec.c | 9 + lib_dec/ivas_stereo_cng_dec.c | 3 + lib_dec/ivas_stereo_dft_dec.c | 250 + lib_dec/ivas_stereo_dft_dec_dmx.c | 6 + lib_dec/ivas_stereo_dft_plc.c | 3 + lib_dec/ivas_stereo_eclvq_dec.c | 6 + lib_dec/ivas_stereo_esf_dec.c | 3 + lib_dec/ivas_stereo_ica_dec.c | 8 + lib_dec/ivas_stereo_icbwe_dec.c | 22 + lib_dec/ivas_stereo_mdct_core_dec.c | 6 + lib_dec/ivas_stereo_mdct_stereo_dec.c | 27 + lib_dec/ivas_stereo_switching_dec.c | 12 + lib_dec/ivas_stereo_td_dec.c | 9 + lib_dec/ivas_svd_dec.c | 3 + lib_dec/ivas_tcx_core_dec.c | 47 + lib_dec/ivas_td_low_rate_dec.c | 3 + lib_dec/jbm_jb4_circularbuffer.c | 3 + lib_dec/jbm_jb4_inputbuffer.c | 11 + lib_dec/jbm_jb4_jmf.c | 3 + lib_dec/jbm_jb4sb.c | 3 + lib_dec/jbm_pcmdsp_apa.c | 3 + lib_dec/jbm_pcmdsp_similarityestimation.c | 3 + lib_dec/jbm_pcmdsp_window.c | 3 + lib_dec/lead_deindexing.c | 3 + lib_dec/lib_dec.c | 1034 +- lib_dec/lib_dec.h | 126 + lib_dec/lp_exc_d.c | 3 + lib_dec/lsf_dec.c | 3 + lib_dec/lsf_msvq_ma_dec.c | 3 + lib_dec/nelp_dec.c | 3 + lib_dec/peak_vq_dec.c | 3 + lib_dec/pit_dec.c | 3 + lib_dec/pitch_extr.c | 3 + lib_dec/post_dec.c | 3 + lib_dec/pvq_core_dec.c | 3 + lib_dec/pvq_decode.c | 3 + lib_dec/range_dec.c | 3 + lib_dec/re8_dec.c | 3 + lib_dec/rom_dec.c | 3 + lib_dec/rom_dec.h | 3 + lib_dec/rst_dec.c | 3 + lib_dec/stat_dec.h | 6 + lib_dec/stat_noise_uv_dec.c | 3 + lib_dec/swb_bwe_dec.c | 3 + lib_dec/swb_bwe_dec_hr.c | 3 + lib_dec/swb_bwe_dec_lr.c | 3 + lib_dec/swb_tbe_dec.c | 3 + lib_dec/syn_outp.c | 3 + lib_dec/tcq_core_dec.c | 3 + lib_dec/tcx_utils_dec.c | 3 + lib_dec/tonalMDCTconcealment.c | 3 + lib_dec/transition_dec.c | 3 + lib_dec/updt_dec.c | 3 + lib_dec/waveadjust_fec_dec.c | 3 + lib_enc/ACcontextMapping_enc.c | 15 + lib_enc/FEC_enc.c | 3 + lib_enc/acelp_core_enc.c | 45 + lib_enc/acelp_core_switch_enc.c | 27 + lib_enc/acelp_enc_util.c | 3 + lib_enc/amr_wb_enc.c | 28 + lib_enc/analy_lp.c | 3 + lib_enc/analy_sp.c | 3 + lib_enc/ari_enc.c | 3 + lib_enc/arith_coder_enc.c | 3 + lib_enc/avq_cod.c | 3 + lib_enc/bass_psfilter_enc.c | 3 + lib_enc/bw_detect.c | 3 + lib_enc/cng_enc.c | 3 + lib_enc/cod2t32.c | 3 + lib_enc/cod4t64.c | 3 + lib_enc/cod4t64_fast.c | 3 + lib_enc/cod_ace.c | 14 + lib_enc/cod_tcx.c | 56 + lib_enc/core_enc_2div.c | 3 + lib_enc/core_enc_init.c | 3 + lib_enc/core_enc_ol.c | 16 + lib_enc/core_enc_reconf.c | 3 + lib_enc/core_enc_switch.c | 3 + lib_enc/core_enc_updt.c | 3 + lib_enc/core_switching_enc.c | 3 + lib_enc/corr_xh.c | 3 + lib_enc/decision_matrix_enc.c | 18 + lib_enc/detect_transient.c | 3 + lib_enc/diffcod.c | 3 + lib_enc/dtx.c | 13 + lib_enc/enc_acelp.c | 3 + lib_enc/enc_acelp_tcx_main.c | 3 + lib_enc/enc_acelpx.c | 3 + lib_enc/enc_amr_wb.c | 3 + lib_enc/enc_gen_voic.c | 3 + lib_enc/enc_gen_voic_rf.c | 3 + lib_enc/enc_higher_acelp.c | 3 + lib_enc/enc_nelp.c | 3 + lib_enc/enc_pit_exc.c | 3 + lib_enc/enc_ppp.c | 3 + lib_enc/enc_prm.c | 29 + lib_enc/enc_tran.c | 3 + lib_enc/enc_uv.c | 6 + lib_enc/eval_pit_contr.c | 3 + lib_enc/evs_enc.c | 55 + lib_enc/ext_sig_ana.c | 6 + lib_enc/fd_cng_enc.c | 9 + lib_enc/find_tar.c | 3 + lib_enc/find_tilt.c | 3 + lib_enc/find_uv.c | 3 + lib_enc/find_wsp.c | 3 + lib_enc/gain_enc.c | 3 + lib_enc/gaus_enc.c | 3 + lib_enc/gp_clip.c | 3 + lib_enc/gs_enc.c | 3 + lib_enc/hf_cod_amrwb.c | 3 + lib_enc/hq_classifier_enc.c | 3 + lib_enc/hq_core_enc.c | 3 + lib_enc/hq_env_enc.c | 3 + lib_enc/hq_hr_enc.c | 7 + lib_enc/hq_lr_enc.c | 7 + lib_enc/hvq_enc.c | 10 + lib_enc/igf_enc.c | 6 + lib_enc/igf_scf_enc.c | 3 + lib_enc/init_enc.c | 3 + lib_enc/inov_enc.c | 9 + lib_enc/isf_enc_amr_wb.c | 3 + lib_enc/ivas_agc_enc.c | 56 + lib_enc/ivas_core_enc.c | 120 + lib_enc/ivas_core_pre_proc.c | 13 + lib_enc/ivas_core_pre_proc_front.c | 18 + lib_enc/ivas_corecoder_enc_reconfig.c | 19 + lib_enc/ivas_cpe_enc.c | 95 + lib_enc/ivas_decision_matrix_enc.c | 36 + lib_enc/ivas_dirac_enc.c | 104 + lib_enc/ivas_enc.c | 29 + lib_enc/ivas_enc_cov_handler.c | 26 + lib_enc/ivas_entropy_coder.c | 3 + lib_enc/ivas_front_vad.c | 10 + lib_enc/ivas_init_enc.c | 12 + lib_enc/ivas_ism_dtx_enc.c | 3 + lib_enc/ivas_ism_enc.c | 48 + lib_enc/ivas_ism_metadata_enc.c | 3 + lib_enc/ivas_ism_param_enc.c | 6 + lib_enc/ivas_lfe_enc.c | 3 + lib_enc/ivas_masa_enc.c | 12 + lib_enc/ivas_mc_param_enc.c | 24 + lib_enc/ivas_mc_paramupmix_enc.c | 204 + lib_enc/ivas_mcmasa_enc.c | 3 + lib_enc/ivas_mct_core_enc.c | 40 + lib_enc/ivas_mct_enc.c | 33 + lib_enc/ivas_mct_enc_mct.c | 82 + lib_enc/ivas_mdct_core_enc.c | 32 + lib_enc/ivas_omasa_enc.c | 32 + lib_enc/ivas_osba_enc.c | 3 + lib_enc/ivas_pca_enc.c | 6 + lib_enc/ivas_qmetadata_enc.c | 475 + lib_enc/ivas_range_uni_enc.c | 49 + lib_enc/ivas_rom_enc.c | 117 + lib_enc/ivas_rom_enc.h | 10 + lib_enc/ivas_sba_enc.c | 17 + lib_enc/ivas_sce_enc.c | 17 + lib_enc/ivas_sns_enc.c | 16 + lib_enc/ivas_spar_encoder.c | 152 + lib_enc/ivas_spar_md_enc.c | 255 + lib_enc/ivas_stat_enc.h | 21 + lib_enc/ivas_stereo_adapt_GR_enc.c | 3 + lib_enc/ivas_stereo_classifier.c | 69 + lib_enc/ivas_stereo_cng_enc.c | 3 + lib_enc/ivas_stereo_dft_enc.c | 462 + lib_enc/ivas_stereo_dft_enc_itd.c | 54 + lib_enc/ivas_stereo_dft_td_itd.c | 35 + lib_enc/ivas_stereo_dmx_evs.c | 3 + lib_enc/ivas_stereo_eclvq_enc.c | 125 + lib_enc/ivas_stereo_ica_enc.c | 13 + lib_enc/ivas_stereo_icbwe_enc.c | 3 + lib_enc/ivas_stereo_mdct_core_enc.c | 31 + lib_enc/ivas_stereo_mdct_stereo_enc.c | 137 + lib_enc/ivas_stereo_switching_enc.c | 6 + lib_enc/ivas_stereo_td_analysis.c | 8 + lib_enc/ivas_stereo_td_enc.c | 39 + lib_enc/ivas_tcx_core_enc.c | 63 + lib_enc/ivas_td_low_rate_enc.c | 3 + lib_enc/lead_indexing.c | 3 + lib_enc/lib_enc.c | 246 + lib_enc/lib_enc.h | 51 + lib_enc/long_enr.c | 3 + lib_enc/lp_exc_e.c | 3 + lib_enc/lsf_enc.c | 10 + lib_enc/lsf_msvq_ma_enc.c | 3 + lib_enc/mdct_classifier.c | 3 + lib_enc/mdct_selector.c | 3 + lib_enc/multi_harm.c | 3 + lib_enc/nelp_enc.c | 3 + lib_enc/noise_adjust.c | 3 + lib_enc/normalizecoefs.c | 3 + lib_enc/peak_vq_enc.c | 30 + lib_enc/pitch_ol2.c | 3 + lib_enc/pre_proc.c | 7 + lib_enc/pvq_core_enc.c | 3 + lib_enc/pvq_encode.c | 3 + lib_enc/q_gain2p.c | 3 + lib_enc/qlpc_stoch.c | 3 + lib_enc/range_enc.c | 3 + lib_enc/re8_cod.c | 3 + lib_enc/reordernorm.c | 3 + lib_enc/rom_enc.c | 3 + lib_enc/rom_enc.h | 3 + lib_enc/rst_enc.c | 3 + lib_enc/setmodeindex.c | 3 + lib_enc/sig_clas.c | 3 + lib_enc/speech_music_classif.c | 42 + lib_enc/stat_enc.h | 9 + lib_enc/stat_noise_uv_enc.c | 3 + lib_enc/swb_bwe_enc.c | 3 + lib_enc/swb_bwe_enc_hr.c | 3 + lib_enc/swb_bwe_enc_lr.c | 3 + lib_enc/swb_pre_proc.c | 3 + lib_enc/swb_tbe_enc.c | 3 + lib_enc/tcq_core_enc.c | 35 + lib_enc/tcx_ltp_enc.c | 6 + lib_enc/tcx_utils_enc.c | 3 + lib_enc/transient_detection.c | 3 + lib_enc/transition_enc.c | 3 + lib_enc/updt_enc.c | 3 + lib_enc/updt_tar.c | 3 + lib_enc/vad.c | 3 + lib_enc/vad_param_updt.c | 3 + lib_enc/vbr_average_rate.c | 3 + lib_enc/vlpc_1st_cod.c | 17 + lib_lc3plus/.clang-format | 2 + lib_lc3plus/adjust_global_gain.c | 86 + lib_lc3plus/al_fec_fl.c | 2329 ++ lib_lc3plus/apply_global_gain.c | 21 + lib_lc3plus/ari_codec.c | 1122 + lib_lc3plus/attack_detector.c | 105 + lib_lc3plus/clib.h | 27 + lib_lc3plus/constants.c | 3803 ++++ lib_lc3plus/constants.h | 203 + lib_lc3plus/cutoff_bandwidth.c | 27 + lib_lc3plus/dct4.c | 95 + lib_lc3plus/dec_entropy.c | 277 + lib_lc3plus/dec_lc3_fl.c | 365 + lib_lc3plus/defines.h | 238 + lib_lc3plus/detect_cutoff_warped.c | 84 + lib_lc3plus/enc_entropy.c | 126 + lib_lc3plus/enc_lc3_fl.c | 270 + lib_lc3plus/estimate_global_gain.c | 128 + lib_lc3plus/fft/cfft.c | 421 + lib_lc3plus/fft/cfft.h | 42 + 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 | 164 + lib_lc3plus/fft/iis_fft.h | 142 + lib_lc3plus/fft/iisfft.c | 166 + lib_lc3plus/fft/iisfft.h | 86 + lib_lc3plus/functions.h | 304 + lib_lc3plus/imdct.c | 102 + lib_lc3plus/lc3.c | 431 + lib_lc3plus/lc3.h | 517 + lib_lc3plus/lc3plus_fft.c | 99 + lib_lc3plus/license.h | 22 + lib_lc3plus/ltpf_coder.c | 264 + lib_lc3plus/ltpf_decoder.c | 356 + lib_lc3plus/mdct.c | 128 + lib_lc3plus/mdct_shaping.c | 23 + lib_lc3plus/near_nyquist_detector.c | 38 + lib_lc3plus/noise_factor.c | 112 + lib_lc3plus/noise_filling.c | 81 + lib_lc3plus/olpa.c | 144 + lib_lc3plus/pc_apply.c | 73 + lib_lc3plus/pc_classify.c | 170 + lib_lc3plus/pc_main.c | 43 + lib_lc3plus/pc_update.c | 37 + lib_lc3plus/per_band_energy.c | 59 + lib_lc3plus/plc_classify.c | 199 + lib_lc3plus/plc_compute_stab_fac.c | 64 + lib_lc3plus/plc_damping_scrambling.c | 206 + lib_lc3plus/plc_main.c | 209 + lib_lc3plus/plc_noise_substitution.c | 22 + lib_lc3plus/plc_phecu_f0_refine_first.c | 75 + lib_lc3plus/plc_phecu_fec_hq.c | 159 + lib_lc3plus/plc_phecu_hq_ecu.c | 116 + lib_lc3plus/plc_phecu_lf_peak_analysis.c | 112 + lib_lc3plus/plc_phecu_rec_frame.c | 147 + lib_lc3plus/plc_phecu_setf0hz.c | 28 + lib_lc3plus/plc_phecu_spec_ana.c | 599 + lib_lc3plus/plc_phecu_subst_spec.c | 247 + lib_lc3plus/plc_phecu_tba_per_band_gain.c | 44 + lib_lc3plus/plc_phecu_tba_spect_Xavg.c | 45 + lib_lc3plus/plc_phecu_tba_trans_dect_gains.c | 320 + lib_lc3plus/plc_phecu_trans_burst_ana_sub.c | 48 + lib_lc3plus/plc_tdc.c | 763 + lib_lc3plus/plc_tdc_tdac.c | 80 + lib_lc3plus/plc_update.c | 125 + lib_lc3plus/quantize_spec.c | 196 + lib_lc3plus/reorder_bitstream.c | 41 + lib_lc3plus/resamp12k8.c | 107 + lib_lc3plus/residual_coding.c | 76 + lib_lc3plus/residual_decoding.c | 97 + lib_lc3plus/setup_com_lc3.c | 30 + lib_lc3plus/setup_dec_lc3.c | 444 + lib_lc3plus/setup_dec_lc3.h | 112 + lib_lc3plus/setup_enc_lc3.c | 546 + lib_lc3plus/setup_enc_lc3.h | 119 + lib_lc3plus/sns_compute_scf.c | 177 + lib_lc3plus/sns_interpolate_scf.c | 90 + lib_lc3plus/sns_quantize_scf.c | 517 + lib_lc3plus/structs.h | 186 + lib_lc3plus/tns_coder.c | 374 + lib_lc3plus/tns_decoder.c | 52 + lib_lc3plus/util.h | 222 + lib_rend/ivas_MSPred.c | 564 + lib_rend/ivas_NoiseGen.c | 100 + lib_rend/ivas_PerceptualModel.c | 257 + lib_rend/ivas_PredDecoder.c | 335 + lib_rend/ivas_PredEncoder.c | 531 + lib_rend/ivas_RMSEnvGrouping.c | 951 + lib_rend/ivas_allrad_dec.c | 41 + lib_rend/ivas_crend.c | 488 + lib_rend/ivas_dirac_ana.c | 3 + lib_rend/ivas_dirac_dec_binaural_functions.c | 1270 +- lib_rend/ivas_dirac_decorr_dec.c | 18 + lib_rend/ivas_dirac_onsets_dec.c | 3 + lib_rend/ivas_dirac_output_synthesis_dec.c | 6 + lib_rend/ivas_dirac_rend.c | 3 + lib_rend/ivas_efap.c | 49 + lib_rend/ivas_lc3plus_common.c | 60 + lib_rend/ivas_lc3plus_common.h | 57 + lib_rend/ivas_lc3plus_dec.c | 703 + lib_rend/ivas_lc3plus_dec.h | 119 + lib_rend/ivas_lc3plus_enc.c | 334 + lib_rend/ivas_lc3plus_enc.h | 76 + lib_rend/ivas_lcld_decoder.c | 1668 ++ lib_rend/ivas_lcld_encoder.c | 2011 ++ lib_rend/ivas_lcld_prot.h | 370 + lib_rend/ivas_lcld_rom_tables.c | 19854 +++++++++++++++++ lib_rend/ivas_lcld_rom_tables.h | 225 + lib_rend/ivas_limiter.c | 9 + lib_rend/ivas_mcmasa_ana.c | 3 + lib_rend/ivas_objectRenderer.c | 175 + lib_rend/ivas_objectRenderer_mix.c | 3 + lib_rend/ivas_objectRenderer_sources.c | 3 + lib_rend/ivas_objectRenderer_vec.c | 3 + lib_rend/ivas_omasa_ana.c | 3 + lib_rend/ivas_orient_trk.c | 3 + lib_rend/ivas_output_init.c | 32 + lib_rend/ivas_prot_rend.h | 484 + lib_rend/ivas_reflections.c | 3 + lib_rend/ivas_render_config.c | 16 + lib_rend/ivas_reverb.c | 6 + lib_rend/ivas_reverb_delay_line.c | 3 + lib_rend/ivas_reverb_fft_filter.c | 3 + lib_rend/ivas_reverb_filter_design.c | 3 + lib_rend/ivas_reverb_iir_filter.c | 3 + lib_rend/ivas_reverb_utils.c | 3 + lib_rend/ivas_rom_TdBinauralRenderer.c | 3 + lib_rend/ivas_rom_TdBinauralRenderer.h | 3 + lib_rend/ivas_rom_binauralRenderer.c | 3 + lib_rend/ivas_rom_binauralRenderer.h | 3 + lib_rend/ivas_rom_rend.c | 3 + lib_rend/ivas_rom_rend.h | 10 + lib_rend/ivas_rotation.c | 166 + lib_rend/ivas_sba_rendering.c | 3 + lib_rend/ivas_splitRend_lcld_dec.c | 239 + lib_rend/ivas_splitRend_lcld_enc.c | 232 + lib_rend/ivas_splitRendererPLC.c | 552 + lib_rend/ivas_splitRendererPost.c | 1799 ++ lib_rend/ivas_splitRendererPre.c | 2474 ++ lib_rend/ivas_splitRenderer_utils.c | 1089 + lib_rend/ivas_stat_rend.h | 265 + lib_rend/ivas_td_decorr.c | 3 + lib_rend/ivas_vbap.c | 7 + lib_rend/lib_rend.c | 2308 +- lib_rend/lib_rend.h | 90 + lib_util/bitstream_reader.c | 16 + lib_util/bitstream_reader.h | 3 + lib_util/masa_file_reader.c | 3 + lib_util/render_config_reader.c | 272 + lib_util/split_rend_bfi_file_reader.c | 164 + lib_util/split_rend_bfi_file_reader.h | 60 + lib_util/split_render_file_read_write.c | 388 + lib_util/split_render_file_read_write.h | 84 + lib_util/tsm_scale_file_reader.c | 148 + lib_util/tsm_scale_file_reader.h | 64 + 655 files changed, 85953 insertions(+), 4239 deletions(-) create mode 100644 CMakeLists.txt create mode 100644 Workspace_msvc/lib_lc3plus.vcxproj create mode 100644 lib_debug/debug.c create mode 100644 lib_debug/debug.h create mode 100644 lib_debug/sba_debug.c create mode 100644 lib_debug/sba_debug.h create mode 100644 lib_debug/snr.c create mode 100644 lib_lc3plus/.clang-format create mode 100644 lib_lc3plus/adjust_global_gain.c create mode 100644 lib_lc3plus/al_fec_fl.c create mode 100644 lib_lc3plus/apply_global_gain.c create mode 100644 lib_lc3plus/ari_codec.c create mode 100644 lib_lc3plus/attack_detector.c create mode 100644 lib_lc3plus/clib.h create mode 100644 lib_lc3plus/constants.c create mode 100644 lib_lc3plus/constants.h create mode 100644 lib_lc3plus/cutoff_bandwidth.c create mode 100644 lib_lc3plus/dct4.c create mode 100644 lib_lc3plus/dec_entropy.c create mode 100644 lib_lc3plus/dec_lc3_fl.c create mode 100644 lib_lc3plus/defines.h create mode 100644 lib_lc3plus/detect_cutoff_warped.c create mode 100644 lib_lc3plus/enc_entropy.c create mode 100644 lib_lc3plus/enc_lc3_fl.c create mode 100644 lib_lc3plus/estimate_global_gain.c create mode 100644 lib_lc3plus/fft/cfft.c create mode 100644 lib_lc3plus/fft/cfft.h create mode 100644 lib_lc3plus/fft/fft_15_16.h create mode 100644 lib_lc3plus/fft/fft_240_480.h create mode 100644 lib_lc3plus/fft/fft_2_9.h create mode 100644 lib_lc3plus/fft/fft_32.h create mode 100644 lib_lc3plus/fft/fft_384_768.h create mode 100644 lib_lc3plus/fft/fft_60_128.h create mode 100644 lib_lc3plus/fft/fft_generic.h create mode 100644 lib_lc3plus/fft/iis_fft.c create mode 100644 lib_lc3plus/fft/iis_fft.h create mode 100644 lib_lc3plus/fft/iisfft.c create mode 100644 lib_lc3plus/fft/iisfft.h create mode 100644 lib_lc3plus/functions.h create mode 100644 lib_lc3plus/imdct.c create mode 100644 lib_lc3plus/lc3.c create mode 100644 lib_lc3plus/lc3.h create mode 100644 lib_lc3plus/lc3plus_fft.c create mode 100644 lib_lc3plus/license.h create mode 100644 lib_lc3plus/ltpf_coder.c create mode 100644 lib_lc3plus/ltpf_decoder.c create mode 100644 lib_lc3plus/mdct.c create mode 100644 lib_lc3plus/mdct_shaping.c create mode 100644 lib_lc3plus/near_nyquist_detector.c create mode 100644 lib_lc3plus/noise_factor.c create mode 100644 lib_lc3plus/noise_filling.c create mode 100644 lib_lc3plus/olpa.c create mode 100644 lib_lc3plus/pc_apply.c create mode 100644 lib_lc3plus/pc_classify.c create mode 100644 lib_lc3plus/pc_main.c create mode 100644 lib_lc3plus/pc_update.c create mode 100644 lib_lc3plus/per_band_energy.c create mode 100644 lib_lc3plus/plc_classify.c create mode 100644 lib_lc3plus/plc_compute_stab_fac.c create mode 100644 lib_lc3plus/plc_damping_scrambling.c create mode 100644 lib_lc3plus/plc_main.c create mode 100644 lib_lc3plus/plc_noise_substitution.c create mode 100644 lib_lc3plus/plc_phecu_f0_refine_first.c create mode 100644 lib_lc3plus/plc_phecu_fec_hq.c create mode 100644 lib_lc3plus/plc_phecu_hq_ecu.c create mode 100644 lib_lc3plus/plc_phecu_lf_peak_analysis.c create mode 100644 lib_lc3plus/plc_phecu_rec_frame.c create mode 100644 lib_lc3plus/plc_phecu_setf0hz.c create mode 100644 lib_lc3plus/plc_phecu_spec_ana.c create mode 100644 lib_lc3plus/plc_phecu_subst_spec.c create mode 100644 lib_lc3plus/plc_phecu_tba_per_band_gain.c create mode 100644 lib_lc3plus/plc_phecu_tba_spect_Xavg.c create mode 100644 lib_lc3plus/plc_phecu_tba_trans_dect_gains.c create mode 100644 lib_lc3plus/plc_phecu_trans_burst_ana_sub.c create mode 100644 lib_lc3plus/plc_tdc.c create mode 100644 lib_lc3plus/plc_tdc_tdac.c create mode 100644 lib_lc3plus/plc_update.c create mode 100644 lib_lc3plus/quantize_spec.c create mode 100644 lib_lc3plus/reorder_bitstream.c create mode 100644 lib_lc3plus/resamp12k8.c create mode 100644 lib_lc3plus/residual_coding.c create mode 100644 lib_lc3plus/residual_decoding.c create mode 100644 lib_lc3plus/setup_com_lc3.c create mode 100644 lib_lc3plus/setup_dec_lc3.c create mode 100644 lib_lc3plus/setup_dec_lc3.h create mode 100644 lib_lc3plus/setup_enc_lc3.c create mode 100644 lib_lc3plus/setup_enc_lc3.h create mode 100644 lib_lc3plus/sns_compute_scf.c create mode 100644 lib_lc3plus/sns_interpolate_scf.c create mode 100644 lib_lc3plus/sns_quantize_scf.c create mode 100644 lib_lc3plus/structs.h create mode 100644 lib_lc3plus/tns_coder.c create mode 100644 lib_lc3plus/tns_decoder.c create mode 100644 lib_lc3plus/util.h create mode 100644 lib_rend/ivas_MSPred.c create mode 100644 lib_rend/ivas_NoiseGen.c create mode 100644 lib_rend/ivas_PerceptualModel.c create mode 100644 lib_rend/ivas_PredDecoder.c create mode 100644 lib_rend/ivas_PredEncoder.c create mode 100644 lib_rend/ivas_RMSEnvGrouping.c create mode 100644 lib_rend/ivas_lc3plus_common.c create mode 100644 lib_rend/ivas_lc3plus_common.h create mode 100644 lib_rend/ivas_lc3plus_dec.c create mode 100644 lib_rend/ivas_lc3plus_dec.h create mode 100644 lib_rend/ivas_lc3plus_enc.c create mode 100644 lib_rend/ivas_lc3plus_enc.h create mode 100644 lib_rend/ivas_lcld_decoder.c create mode 100644 lib_rend/ivas_lcld_encoder.c create mode 100644 lib_rend/ivas_lcld_prot.h create mode 100644 lib_rend/ivas_lcld_rom_tables.c create mode 100644 lib_rend/ivas_lcld_rom_tables.h create mode 100644 lib_rend/ivas_splitRend_lcld_dec.c create mode 100644 lib_rend/ivas_splitRend_lcld_enc.c create mode 100644 lib_rend/ivas_splitRendererPLC.c create mode 100644 lib_rend/ivas_splitRendererPost.c create mode 100644 lib_rend/ivas_splitRendererPre.c create mode 100644 lib_rend/ivas_splitRenderer_utils.c create mode 100644 lib_util/split_rend_bfi_file_reader.c create mode 100644 lib_util/split_rend_bfi_file_reader.h create mode 100644 lib_util/split_render_file_read_write.c create mode 100644 lib_util/split_render_file_read_write.h create mode 100644 lib_util/tsm_scale_file_reader.c create mode 100644 lib_util/tsm_scale_file_reader.h diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 000000000..435773d7b --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,246 @@ +# CMake file for IVAS +# +# Usage with Unix Makefiles (Linux, OS/X): +# # create build directory +# mkdir build ; cd build +# # call CMake to generate build system, e.g. one of the following: +# cmake -D CMAKE_BUILD_TYPE=Debug ../ +# cmake -D CMAKE_BUILD_TYPE=Release ../ +# cmake -D CMAKE_BUILD_TYPE=Debug -D TARGET_PLATFORM=x86_64 ../ +# # build project +# make -j8 +# +# Usage with Visual Studio +# 1) download CMake from https://cmake.org/download/, don't use the Cygwin version! +# 2.1) build project using IDE +# In CMake GUI select the source dir (root of stereo-evs) and a new binary directory +# and press "Configure" and "Generate". Then open the Visual Studio solution file generated +# in the build directory. +# 2.2) build project using command line +# # create build directory +# mkdir build ; cd build +# # call CMake to generate build system, e.g. one of the following: +# cmake ../ +# cmake -G "Visual Studio 12 2013" ../ +# cmake -G "Visual Studio 12 2013 Win64" ../ +# # open the Visual Studio solution file generated in the build directory +# # or build on command line, e.g.: +# cmake --build . --config Debug +# cmake --build . --config Release +# +# INCLUDE_SPLIT is not set by default. If split rendering is used, then add -D INCLUDE_SPLIT=1 to the build command + +cmake_minimum_required(VERSION 3.1) + +set(CMAKE_C_STANDARD 99) + + +# configuration options for UNIX +if(UNIX) + set(TARGET_PLATFORM "" CACHE STRING "i686 / x86_64") + set(CLANG "" CACHE STRING "1=msan / 2=asan / 3=usan") + set(GCOV OFF CACHE BOOL "enable GCOV") + set(STRIP OFF CACHE BOOL "enable STRIP") + + if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE "Debug" CACHE STRING "") + endif() + # TARGET_PLATFORM + if("${TARGET_PLATFORM}" MATCHES "i386" OR + "${TARGET_PLATFORM}" MATCHES "i586" OR + "${TARGET_PLATFORM}" MATCHES "i686" + ) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m32") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -m32") + elseif("${TARGET_PLATFORM}" MATCHES "x86_64") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m64") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -m64") + endif() + # C compiler flags + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ffp-contract=off") # disable floating point operation contraction + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pedantic -Wcast-qual -Wall -W -Wextra -Wno-long-long") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wpointer-arith -Wstrict-prototypes -Wmissing-prototypes") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror-implicit-function-declaration -Wno-unused-parameter") + # CLANG + if(CLANG) + find_program(clangBin NAMES /home/amm-archiv/soft/Linux/clang/current/bin/clang clang REQUIRED) + set(CMAKE_C_COMPILER "${clangBin}" CACHE STRING "") + if("${CLANG}" MATCHES "1" OR "${CLANG}" MATCHES "msan") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=memory") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=memory") + elseif("${CLANG}" MATCHES "2" OR "${CLANG}" MATCHES "asan") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address") + elseif("${CLANG}" MATCHES "3" OR "${CLANG}" MATCHES "usan") + # NOTE: keep in sync with list in Makefile + set(USAN_CHECKS_ENABLE + undefined # Default checks + # Extra checks + float-divide-by-zero + implicit-conversion + local-bounds + ) + list(JOIN USAN_CHECKS_ENABLE "," USAN_CHECKS_ENABLE) + + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=${USAN_CHECKS_ENABLE} -fsanitize-recover=${USAN_CHECKS_ENABLE}") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=${USAN_CHECKS_ENABLE} -fsanitize-recover=${USAN_CHECKS_ENABLE}") + else() + message(FATAL_ERROR "Unknown CLANG setting: ${CLANG}") + endif() + endif() + # GCOV + if(GCOV) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fprofile-arcs -ftest-coverage -fprofile-update=atomic") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fprofile-arcs -ftest-coverage -fprofile-update=atomic") + endif() + # STRIP + if(STRIP) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fdata-sections -ffunction-sections") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-gc-sections -static") + endif() + + message("CMAKE_C_FLAGS: ${CMAKE_C_FLAGS}") + message("CMAKE_EXE_LINKER_FLAGS: ${CMAKE_EXE_LINKER_FLAGS}") + # write settings in CMake cache + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS}" CACHE STRING "") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS}" CACHE STRING "") + set(CMAKE_C_FLAGS_DEBUG "-O0 -g3" CACHE STRING "") + set(CMAKE_C_FLAGS_RELEASE "-O2 -DRELEASE" CACHE STRING "") # TODO should contain -DNDEBUG to disable assert() +elseif(WIN32) + # MSVC compiler flags + add_definitions( + -D_CRT_SECURE_NO_WARNINGS + /MP + ) + # CMake sets /W3 by default, until CMake version 3.15. Instead of setting /W4 separately, replace in existing settings + string(REGEX REPLACE "/W3" "/W4" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}") +endif() + +# configuration options for all platforms +set(WMOPS OFF CACHE BOOL "enable WMOPS") +if(WMOPS) + add_definitions("-DWMOPS=1") +endif() + +project(stereo-evs) +set_property(GLOBAL PROPERTY USE_FOLDERS ON) # make Visual Studio projects look nicer +include(CTest) + +file(GLOB libComSrcs "lib_com/*.c") +file(GLOB libComHeaders "lib_com/*.h") +add_library(lib_com ${libComSrcs} ${libComHeaders}) +if(UNIX) + target_link_libraries(lib_com PRIVATE m) +endif() +target_include_directories(lib_com PUBLIC lib_com PRIVATE lib_enc lib_dec lib_rend lib_debug) +if(INCLUDE_SPLIT) + target_include_directories(lib_com PRIVATE lib_lc3plus) +endif() + +file(GLOB libDebugSrcs "lib_debug/*.c") +file(GLOB libDebugHeaders "lib_debug/*.h") +add_library(lib_debug ${libDebugSrcs} ${libDebugHeaders}) +target_link_libraries(lib_debug lib_com) +target_include_directories(lib_debug PUBLIC lib_debug PRIVATE lib_enc lib_dec lib_rend) + +file(GLOB libEncSrcs "lib_enc/*.c") +file(GLOB libEncHeaders "lib_enc/*.h") +add_library(lib_enc ${libEncSrcs} ${libEncHeaders}) +target_link_libraries(lib_enc lib_com lib_debug) +target_include_directories(lib_enc PUBLIC lib_enc PRIVATE lib_dec lib_rend) +if(INCLUDE_SPLIT) + target_include_directories(lib_enc PRIVATE lib_lc3plus) +endif() + +if(INCLUDE_SPLIT) + file(GLOB libLC3plusSrcs "lib_lc3plus/*.c") + file(GLOB libLC3plusHeaders "lib_lc3plus/*.h") + add_library(lib_lc3plus ${libLC3plusSrcs} ${libLC3plusHeaders}) + target_include_directories(lib_lc3plus PUBLIC lib_lc3plus) + target_link_libraries(lib_lc3plus lib_com) # For including options.h, which is needed for instrumentation to work correctly + if(WMOPS) + target_link_libraries(lib_lc3plus lib_debug) + endif() +endif() + +file(GLOB libRendSrcs "lib_rend/*.c") +file(GLOB libRendHeaders "lib_rend/*.h") +if(NOT INCLUDE_SPLIT) + list(FILTER libRendSrcs EXCLUDE REGEX ".*lib_rend\/.*lc3plus.*\.c$") + list(FILTER libRendSrcs EXCLUDE REGEX ".*lib_rend\/.*ivas_cldfb_codec.*\.c$") + list(FILTER libRendSrcs EXCLUDE REGEX ".*lib_rend\/.*splitRend.*\.c$") + list(FILTER libRendSrcs EXCLUDE REGEX ".*lib_rend\/.*splitrenderer.*\.c$") + list(FILTER libRendSrcs EXCLUDE REGEX ".*lib_rend\/.*ivas_lcld.*\.c$") + list(FILTER libRendSrcs EXCLUDE REGEX ".*lib_rend\/.*ivas_Pred.*\.c$") + list(FILTER libRendSrcs EXCLUDE REGEX ".*lib_rend\/.*ivas_RMSEnv.*\.c$") + list(FILTER libRendSrcs EXCLUDE REGEX ".*lib_rend\/.*ivas_PerceptualModel.*\.c$") + list(FILTER libRendSrcs EXCLUDE REGEX ".*lib_rend\/.*ivas_lcld_rom_tables.*\.c$") + list(FILTER libRendHeaders EXCLUDE REGEX ".*lib_rend\/.*lc3plus.*\.h$") + list(FILTER libRendHeaders EXCLUDE REGEX ".*lib_rend\/.*splitRend.*\.h$") + list(FILTER libRendHeaders EXCLUDE REGEX ".*lib_rend\/.*ivas_cldfb_codec.*\.h$") + list(FILTER libRendHeaders EXCLUDE REGEX ".*lib_rend\/.*ivas_lcld_rom_tables.*\.h$") +endif() + +add_library(lib_rend ${libRendSrcs} ${libRendHeaders}) +target_link_libraries(lib_rend lib_dec lib_com lib_debug) # Todo refactor: This dependency on lib_dec should be removed. +if(INCLUDE_SPLIT) + target_link_libraries(lib_rend lib_lc3plus) +endif() +target_include_directories(lib_rend PUBLIC lib_rend PRIVATE lib_enc) + + +file(GLOB libDecSrcs "lib_dec/*.c") +file(GLOB libDecHeaders "lib_dec/*.h") +add_library(lib_dec ${libDecSrcs} ${libDecHeaders}) +target_link_libraries(lib_dec lib_com lib_rend lib_debug) +target_include_directories(lib_dec PUBLIC lib_dec lib_rend PRIVATE lib_enc) + +file(GLOB libUtilSrcs "lib_util/*.c") +file(GLOB libUtilHeaders "lib_util/*.h") +if(NOT INCLUDE_SPLIT) + list(FILTER libUtilSrcs EXCLUDE REGEX ".*lib_util\/.*split_rend.*\.c$") +endif() +add_library(lib_util ${libUtilSrcs} ${libUtilHeaders}) +target_include_directories(lib_util PUBLIC lib_util PRIVATE lib_com lib_enc lib_dec lib_rend lib_debug) +if(INCLUDE_SPLIT) + target_include_directories(lib_util PRIVATE lib_lc3plus) +endif() + +if(INCLUDE_SPLIT) + if(NOT WMOPS) + file(GLOB unitTestIvasLc3plusSrcs "scripts/split_rendering/lc3plus/*.c") + add_executable(ivas_lc3plus_unit_test ${unitTestIvasLc3plusSrcs}) + target_link_libraries(ivas_lc3plus_unit_test lib_rend lib_dec lib_util lib_com lib_debug) + endif() +endif() + +add_executable(IVAS_cod apps/encoder.c) +target_link_libraries(IVAS_cod lib_enc lib_util) +if(WIN32) + target_link_libraries(IVAS_cod Ws2_32) +endif() + +add_executable(IVAS_dec apps/decoder.c) +target_link_libraries(IVAS_dec lib_dec lib_util) +if(WIN32) + target_link_libraries(IVAS_dec Ws2_32) +endif() + +add_executable(IVAS_rend apps/renderer.c) +target_link_libraries(IVAS_rend lib_rend lib_util) +target_include_directories(IVAS_rend PRIVATE lib_enc) + +if(COPY_EXECUTABLES_FROM_BUILD_DIR) + # Optionally copy executables to the same place where Make puts them (useful for tests that expect executables in specific places) + add_custom_command(TARGET IVAS_cod POST_BUILD VERBATIM COMMAND "${CMAKE_COMMAND}" -E copy "$" "${CMAKE_CURRENT_SOURCE_DIR}/") + add_custom_command(TARGET IVAS_dec POST_BUILD VERBATIM COMMAND "${CMAKE_COMMAND}" -E copy "$" "${CMAKE_CURRENT_SOURCE_DIR}/") + add_custom_command(TARGET IVAS_rend POST_BUILD VERBATIM COMMAND "${CMAKE_COMMAND}" -E copy "$" "${CMAKE_CURRENT_SOURCE_DIR}/") + if(INCLUDE_SPLIT) + if (NOT WMOPS) + add_custom_command(TARGET ivas_lc3plus_unit_test POST_BUILD VERBATIM COMMAND "${CMAKE_COMMAND}" -E copy "$" "${CMAKE_CURRENT_SOURCE_DIR}/scripts/split_rendering/lc3plus") + endif() + endif() +endif() + +# Allow creating packages for CMake install +install(TARGETS lib_enc lib_dec lib_rend lib_com lib_util ARCHIVE DESTINATION lib) diff --git a/Makefile b/Makefile index bef5db441..f72577249 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,3 @@ - # GNU Makefile # Paths @@ -7,12 +6,13 @@ SRC_LIBDEBUG = lib_debug SRC_LIBDEC = lib_dec SRC_LIBENC = lib_enc SRC_LIBREND = lib_rend +SRC_LC3PLUS = lib_lc3plus lib_lc3plus/fft SRC_LIBUTIL = lib_util SRC_APP = apps BUILD = build OBJDIR = obj -SRC_DIRS = $(sort -u $(SRC_LIBCOM) $(SRC_LIBDEBUG) $(SRC_LIBDEC) $(SRC_LIBENC) $(SRC_LIBREND) $(SRC_LIBUTIL) $(SRC_APP)) +SRC_DIRS = $(sort -u $(SRC_LIBCOM) $(SRC_LIBDEBUG) $(SRC_LIBDEC) $(SRC_LIBENC) $(SRC_LIBREND) $(SRC_LC3PLUS) $(SRC_LIBUTIL) $(SRC_APP)) # Name of CLI binaries CLI_APIDEC ?= IVAS_dec @@ -23,6 +23,7 @@ LIB_LIBDEBUG ?= libivasdebug.a LIB_LIBDEC ?= libivasdec.a LIB_LIBENC ?= libivasenc.a LIB_LIBREND ?= libivasrend.a +LIB_LC3PLUS ?= liblc3plus.a LIB_LIBUTIL ?= libivasutil.a # Default tool settings @@ -116,6 +117,15 @@ CFLAGS += $(foreach DIR,$(SRC_DIRS),-I$(DIR)) # Source file search paths VPATH = $(SRC_DIRS) +# Split rendering files +SRCS_SPLIT_REND = ivas_CQMFDecoder.c ivas_CQMFEncoder.c ivas_PerceptualModel.c ivas_PredDecoder.c \ + ivas_PredEncoder.c ivas_RMSEnvGrouping.c ivas_MSPred.c ivas_NoiseGen.c \ + ivas_splitRend_lcld_dec.c ivas_splitRend_lcld_enc.c \ + ivas_splitRendererPLC.c ivas_splitRendererPost.c ivas_splitRendererPre.c \ + 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))) @@ -124,19 +134,26 @@ SRCS_LIBDEC = $(foreach DIR,$(SRC_LIBDEC),$(patsubst $(DIR)/%,%,$(wildcard $(D SRCS_LIBENC = $(foreach DIR,$(SRC_LIBENC),$(patsubst $(DIR)/%,%,$(wildcard $(DIR)/*.c))) SRCS_LIBREND = $(foreach DIR,$(SRC_LIBREND),$(patsubst $(DIR)/%,%,$(wildcard $(DIR)/*.c))) SRCS_LIBUTIL = $(foreach DIR,$(SRC_LIBUTIL),$(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)) OBJS_LIBDEC = $(addprefix $(OBJDIR)/,$(SRCS_LIBDEC:.c=.o)) OBJS_LIBENC = $(addprefix $(OBJDIR)/,$(SRCS_LIBENC:.c=.o)) OBJS_LIBREND = $(addprefix $(OBJDIR)/,$(SRCS_LIBREND:.c=.o)) +OBJS_LC3PLUS = $(addprefix $(OBJDIR)/,$(SRCS_LC3PLUS:.c=.o)) OBJS_LIBUTIL = $(addprefix $(OBJDIR)/,$(SRCS_LIBUTIL:.c=.o)) OBJS_CLI_APIDEC = $(OBJDIR)/decoder.o OBJS_CLI_APIENC = $(OBJDIR)/encoder.o OBJS_CLI_APPREND = $(OBJDIR)/renderer.o DEPS = $(addprefix $(OBJDIR)/,$(SRCS_LIBCOM:.c=.P) $(SRCS_LIBDEBUG:.c=.P) $(SRCS_LIBDEC:.c=.P) \ - $(SRCS_LIBENC:.c=.P) $(SRCS_LIBUTIL:.c=.P) $(SRCS_LIBREND:.c=.P)) + $(SRCS_LIBENC:.c=.P) $(SRCS_LIBUTIL:.c=.P) $(SRCS_LIBREND:.c=.P) $(SRCS_LC3PLUS:.c=.P)) ############################################################################### @@ -162,25 +179,40 @@ $(LIB_LIBENC): $(OBJS_LIBENC) $(LIB_LIBREND): $(OBJS_LIBREND) $(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 $@ $^ -$(CLI_APIENC): $(OBJS_CLI_APIENC) $(LIB_LIBENC) $(LIB_LIBCOM) $(LIB_LIBUTIL) $(LIB_LIBDEBUG) +$(CLI_APIENC): $(OBJS_CLI_APIENC) $(LIB_LIBENC) $(LIB_LIBCOM) $(LIB_LIBUTIL) $(LIB_LIBDEBUG) $(LIB_LC3PLUS) $(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) +$(CLI_APIDEC): $(OBJS_CLI_APIDEC) $(LIB_LIBDEC) $(LIB_LIBCOM) $(LIB_LIBUTIL) $(LIB_LIBDEBUG) $(LIB_LC3PLUS) +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) +$(CLI_APIREND): $(OBJS_CLI_APPREND) $(LIB_LIBREND) $(LIB_LIBCOM) $(LIB_LIBUTIL) $(LIB_LIBDEBUG) $(LIB_LIBDEC) $(LIB_LC3PLUS) +ifeq "$(INCLUDE_SPLIT)" "1" + $(QUIET_LINK)$(CC) $(LDFLAGS) $(OBJS_CLI_APPREND) -L. -livasrend -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 -libs: $(LIB_LIBENC) $(LIB_LIBDEBUG) $(LIB_LIBCOM) $(LIB_LIBDEC) $(LIB_LIBREND) $(LIB_LIBUTIL) +libs: $(LIB_LIBENC) $(LIB_LIBDEBUG) $(LIB_LIBCOM) $(LIB_LIBDEC) $(LIB_LIBREND) $(LIB_LC3PLUS) $(LIB_LIBUTIL) clean: $(QUIET)$(RM) $(OBJS_LIBENC) $(OBJS_LIBDEC) $(DEPS) $(QUIET)$(RM) $(DEPS:.P=.d) $(QUIET)test ! -d $(OBJDIR) || rm -rf $(OBJDIR) - $(QUIET)$(RM) $(CLI_APIENC) $(CLI_APIDEC) $(CLI_APIREND) $(LIB_LIBENC) $(LIB_LIBDEBUG) $(LIB_LIBCOM) $(LIB_LIBDEC) $(LIB_LIBUTIL) $(LIB_LIBREND) + $(QUIET)$(RM) $(CLI_APIENC) $(CLI_APIDEC) $(CLI_APIREND) $(LIB_LIBENC) $(LIB_LIBDEBUG) $(LIB_LIBCOM) $(LIB_LIBDEC) $(LIB_LIBUTIL) $(LIB_LIBREND) $(LIB_LC3PLUS) $(OBJDIR)/%.o : %.c | $(OBJDIR) $(QUIET_CC)$(CC) $(CFLAGS) -c -MD -o $@ $< diff --git a/Workspace_msvc/Workspace_msvc.sln b/Workspace_msvc/Workspace_msvc.sln index a0783ddbf..56eb9f45e 100644 --- a/Workspace_msvc/Workspace_msvc.sln +++ b/Workspace_msvc/Workspace_msvc.sln @@ -1,103 +1,105 @@ -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.28307.902 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lib_dec", "lib_dec.vcxproj", "{E822DDAF-0F5F-4CD0-A694-38AE69DE74D3}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lib_enc", "lib_enc.vcxproj", "{824DA4CF-06F0-45C9-929A-8792F0E19C3E}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lib_com", "lib_com.vcxproj", "{39EC200D-7795-4FF8-B214-B24EDA5526AE}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lib_rend", "lib_rend.vcxproj", "{718DE063-A18B-BB72-9150-62B892E6FFA6}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lib_util", "lib_util.vcxproj", "{2FA8F384-0775-F3B7-F8C3-85209222FC70}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lib_debug", "lib_debug.vcxproj", "{54509728-928B-44D9-A118-A6F92F08B34F}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "decoder", "decoder.vcxproj", "{E3DCBC31-7FC9-D127-E000-529F8460D5FD}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "encoder", "encoder.vcxproj", "{B3FC9DFC-7268-8660-7C0D-B60BAF02C554}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "renderer", "renderer.vcxproj", "{12B4C8A5-1E06-4E30-B443-D1F916F52B47}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{51160D4C-55C9-4C16-A792-D94507225746}" - ProjectSection(SolutionItems) = preProject - ..\.clang-format = ..\.clang-format - EndProjectSection -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Debug|x64 = Debug|x64 - Release|Win32 = Release|Win32 - Release|x64 = Release|x64 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {E822DDAF-0F5F-4CD0-A694-38AE69DE74D3}.Debug|Win32.ActiveCfg = Debug|Win32 - {E822DDAF-0F5F-4CD0-A694-38AE69DE74D3}.Debug|Win32.Build.0 = Debug|Win32 - {E822DDAF-0F5F-4CD0-A694-38AE69DE74D3}.Debug|x64.ActiveCfg = Debug|Win32 - {E822DDAF-0F5F-4CD0-A694-38AE69DE74D3}.Release|Win32.ActiveCfg = Release|Win32 - {E822DDAF-0F5F-4CD0-A694-38AE69DE74D3}.Release|Win32.Build.0 = Release|Win32 - {E822DDAF-0F5F-4CD0-A694-38AE69DE74D3}.Release|x64.ActiveCfg = Release|Win32 - {824DA4CF-06F0-45C9-929A-8792F0E19C3E}.Debug|Win32.ActiveCfg = Debug|Win32 - {824DA4CF-06F0-45C9-929A-8792F0E19C3E}.Debug|Win32.Build.0 = Debug|Win32 - {824DA4CF-06F0-45C9-929A-8792F0E19C3E}.Debug|x64.ActiveCfg = Debug|Win32 - {824DA4CF-06F0-45C9-929A-8792F0E19C3E}.Release|Win32.ActiveCfg = Release|Win32 - {824DA4CF-06F0-45C9-929A-8792F0E19C3E}.Release|Win32.Build.0 = Release|Win32 - {824DA4CF-06F0-45C9-929A-8792F0E19C3E}.Release|x64.ActiveCfg = Release|Win32 - {39EC200D-7795-4FF8-B214-B24EDA5526AE}.Debug|Win32.ActiveCfg = Debug|Win32 - {39EC200D-7795-4FF8-B214-B24EDA5526AE}.Debug|Win32.Build.0 = Debug|Win32 - {39EC200D-7795-4FF8-B214-B24EDA5526AE}.Debug|x64.ActiveCfg = Debug|Win32 - {39EC200D-7795-4FF8-B214-B24EDA5526AE}.Release|Win32.ActiveCfg = Release|Win32 - {39EC200D-7795-4FF8-B214-B24EDA5526AE}.Release|Win32.Build.0 = Release|Win32 - {39EC200D-7795-4FF8-B214-B24EDA5526AE}.Release|x64.ActiveCfg = Release|Win32 - {718DE063-A18B-BB72-9150-62B892E6FFA6}.Debug|Win32.ActiveCfg = Debug|Win32 - {718DE063-A18B-BB72-9150-62B892E6FFA6}.Debug|Win32.Build.0 = Debug|Win32 - {718DE063-A18B-BB72-9150-62B892E6FFA6}.Debug|x64.ActiveCfg = Debug|Win32 - {718DE063-A18B-BB72-9150-62B892E6FFA6}.Release|Win32.ActiveCfg = Release|Win32 - {718DE063-A18B-BB72-9150-62B892E6FFA6}.Release|Win32.Build.0 = Release|Win32 - {718DE063-A18B-BB72-9150-62B892E6FFA6}.Release|x64.ActiveCfg = Release|Win32 - {2FA8F384-0775-F3B7-F8C3-85209222FC70}.Debug|Win32.ActiveCfg = Debug|Win32 - {2FA8F384-0775-F3B7-F8C3-85209222FC70}.Debug|Win32.Build.0 = Debug|Win32 - {2FA8F384-0775-F3B7-F8C3-85209222FC70}.Debug|x64.ActiveCfg = Debug|Win32 - {2FA8F384-0775-F3B7-F8C3-85209222FC70}.Release|Win32.ActiveCfg = Release|Win32 - {2FA8F384-0775-F3B7-F8C3-85209222FC70}.Release|Win32.Build.0 = Release|Win32 - {2FA8F384-0775-F3B7-F8C3-85209222FC70}.Release|x64.ActiveCfg = Release|Win32 - {54509728-928B-44D9-A118-A6F92F08B34F}.Debug|Win32.ActiveCfg = Debug|Win32 - {54509728-928B-44D9-A118-A6F92F08B34F}.Debug|Win32.Build.0 = Debug|Win32 - {54509728-928B-44D9-A118-A6F92F08B34F}.Debug|x64.ActiveCfg = Debug|Win32 - {54509728-928B-44D9-A118-A6F92F08B34F}.Release|Win32.ActiveCfg = Release|Win32 - {54509728-928B-44D9-A118-A6F92F08B34F}.Release|Win32.Build.0 = Release|Win32 - {54509728-928B-44D9-A118-A6F92F08B34F}.Release|x64.ActiveCfg = Release|Win32 - {E3DCBC31-7FC9-D127-E000-529F8460D5FD}.Debug|Win32.ActiveCfg = Debug|Win32 - {E3DCBC31-7FC9-D127-E000-529F8460D5FD}.Debug|Win32.Build.0 = Debug|Win32 - {E3DCBC31-7FC9-D127-E000-529F8460D5FD}.Debug|x64.ActiveCfg = Debug|Win32 - {E3DCBC31-7FC9-D127-E000-529F8460D5FD}.Release|Win32.ActiveCfg = Release|Win32 - {E3DCBC31-7FC9-D127-E000-529F8460D5FD}.Release|Win32.Build.0 = Release|Win32 - {E3DCBC31-7FC9-D127-E000-529F8460D5FD}.Release|x64.ActiveCfg = Release|Win32 - {B3FC9DFC-7268-8660-7C0D-B60BAF02C554}.Debug|Win32.ActiveCfg = Debug|Win32 - {B3FC9DFC-7268-8660-7C0D-B60BAF02C554}.Debug|Win32.Build.0 = Debug|Win32 - {B3FC9DFC-7268-8660-7C0D-B60BAF02C554}.Debug|x64.ActiveCfg = Debug|Win32 - {B3FC9DFC-7268-8660-7C0D-B60BAF02C554}.Release|Win32.ActiveCfg = Release|Win32 - {B3FC9DFC-7268-8660-7C0D-B60BAF02C554}.Release|Win32.Build.0 = Release|Win32 - {B3FC9DFC-7268-8660-7C0D-B60BAF02C554}.Release|x64.ActiveCfg = Release|Win32 - {12B4C8A5-1E06-4E30-B443-D1F916F52B47}.Debug|Win32.ActiveCfg = Debug|Win32 - {12B4C8A5-1E06-4E30-B443-D1F916F52B47}.Debug|Win32.Build.0 = Debug|Win32 - {12B4C8A5-1E06-4E30-B443-D1F916F52B47}.Debug|x64.ActiveCfg = Debug|Win32 - {12B4C8A5-1E06-4E30-B443-D1F916F52B47}.Release|Win32.ActiveCfg = Release|Win32 - {12B4C8A5-1E06-4E30-B443-D1F916F52B47}.Release|Win32.Build.0 = Release|Win32 - {12B4C8A5-1E06-4E30-B443-D1F916F52B47}.Release|x64.ActiveCfg = Release|Win32 - {95030B82-70CD-4C6B-84D4-61096035BEA2}.Debug|Win32.ActiveCfg = Debug|Win32 - {95030B82-70CD-4C6B-84D4-61096035BEA2}.Debug|Win32.Build.0 = Debug|Win32 - {95030B82-70CD-4C6B-84D4-61096035BEA2}.Debug|x64.ActiveCfg = Debug|Win32 - {95030B82-70CD-4C6B-84D4-61096035BEA2}.Release|Win32.ActiveCfg = Release|Win32 - {95030B82-70CD-4C6B-84D4-61096035BEA2}.Release|Win32.Build.0 = Release|Win32 - {95030B82-70CD-4C6B-84D4-61096035BEA2}.Release|x64.ActiveCfg = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {74E3E3B8-3E51-4003-816B-8ED3057AAC21} - EndGlobalSection -EndGlobal +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.28307.902 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lib_dec", "lib_dec.vcxproj", "{E822DDAF-0F5F-4CD0-A694-38AE69DE74D3}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lib_enc", "lib_enc.vcxproj", "{824DA4CF-06F0-45C9-929A-8792F0E19C3E}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lib_com", "lib_com.vcxproj", "{39EC200D-7795-4FF8-B214-B24EDA5526AE}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lib_rend", "lib_rend.vcxproj", "{718DE063-A18B-BB72-9150-62B892E6FFA6}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lib_util", "lib_util.vcxproj", "{2FA8F384-0775-F3B7-F8C3-85209222FC70}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lib_debug", "lib_debug.vcxproj", "{54509728-928B-44D9-A118-A6F92F08B34F}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "decoder", "decoder.vcxproj", "{E3DCBC31-7FC9-D127-E000-529F8460D5FD}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "encoder", "encoder.vcxproj", "{B3FC9DFC-7268-8660-7C0D-B60BAF02C554}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "renderer", "renderer.vcxproj", "{12B4C8A5-1E06-4E30-B443-D1F916F52B47}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LC3plus", "lib_lc3plus.vcxproj", "{95030B82-70CD-4C6B-84D4-61096035BEA2}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{51160D4C-55C9-4C16-A792-D94507225746}" + ProjectSection(SolutionItems) = preProject + ..\.clang-format = ..\.clang-format + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {E822DDAF-0F5F-4CD0-A694-38AE69DE74D3}.Debug|Win32.ActiveCfg = Debug|Win32 + {E822DDAF-0F5F-4CD0-A694-38AE69DE74D3}.Debug|Win32.Build.0 = Debug|Win32 + {E822DDAF-0F5F-4CD0-A694-38AE69DE74D3}.Debug|x64.ActiveCfg = Debug|Win32 + {E822DDAF-0F5F-4CD0-A694-38AE69DE74D3}.Release|Win32.ActiveCfg = Release|Win32 + {E822DDAF-0F5F-4CD0-A694-38AE69DE74D3}.Release|Win32.Build.0 = Release|Win32 + {E822DDAF-0F5F-4CD0-A694-38AE69DE74D3}.Release|x64.ActiveCfg = Release|Win32 + {824DA4CF-06F0-45C9-929A-8792F0E19C3E}.Debug|Win32.ActiveCfg = Debug|Win32 + {824DA4CF-06F0-45C9-929A-8792F0E19C3E}.Debug|Win32.Build.0 = Debug|Win32 + {824DA4CF-06F0-45C9-929A-8792F0E19C3E}.Debug|x64.ActiveCfg = Debug|Win32 + {824DA4CF-06F0-45C9-929A-8792F0E19C3E}.Release|Win32.ActiveCfg = Release|Win32 + {824DA4CF-06F0-45C9-929A-8792F0E19C3E}.Release|Win32.Build.0 = Release|Win32 + {824DA4CF-06F0-45C9-929A-8792F0E19C3E}.Release|x64.ActiveCfg = Release|Win32 + {39EC200D-7795-4FF8-B214-B24EDA5526AE}.Debug|Win32.ActiveCfg = Debug|Win32 + {39EC200D-7795-4FF8-B214-B24EDA5526AE}.Debug|Win32.Build.0 = Debug|Win32 + {39EC200D-7795-4FF8-B214-B24EDA5526AE}.Debug|x64.ActiveCfg = Debug|Win32 + {39EC200D-7795-4FF8-B214-B24EDA5526AE}.Release|Win32.ActiveCfg = Release|Win32 + {39EC200D-7795-4FF8-B214-B24EDA5526AE}.Release|Win32.Build.0 = Release|Win32 + {39EC200D-7795-4FF8-B214-B24EDA5526AE}.Release|x64.ActiveCfg = Release|Win32 + {718DE063-A18B-BB72-9150-62B892E6FFA6}.Debug|Win32.ActiveCfg = Debug|Win32 + {718DE063-A18B-BB72-9150-62B892E6FFA6}.Debug|Win32.Build.0 = Debug|Win32 + {718DE063-A18B-BB72-9150-62B892E6FFA6}.Debug|x64.ActiveCfg = Debug|Win32 + {718DE063-A18B-BB72-9150-62B892E6FFA6}.Release|Win32.ActiveCfg = Release|Win32 + {718DE063-A18B-BB72-9150-62B892E6FFA6}.Release|Win32.Build.0 = Release|Win32 + {718DE063-A18B-BB72-9150-62B892E6FFA6}.Release|x64.ActiveCfg = Release|Win32 + {2FA8F384-0775-F3B7-F8C3-85209222FC70}.Debug|Win32.ActiveCfg = Debug|Win32 + {2FA8F384-0775-F3B7-F8C3-85209222FC70}.Debug|Win32.Build.0 = Debug|Win32 + {2FA8F384-0775-F3B7-F8C3-85209222FC70}.Debug|x64.ActiveCfg = Debug|Win32 + {2FA8F384-0775-F3B7-F8C3-85209222FC70}.Release|Win32.ActiveCfg = Release|Win32 + {2FA8F384-0775-F3B7-F8C3-85209222FC70}.Release|Win32.Build.0 = Release|Win32 + {2FA8F384-0775-F3B7-F8C3-85209222FC70}.Release|x64.ActiveCfg = Release|Win32 + {54509728-928B-44D9-A118-A6F92F08B34F}.Debug|Win32.ActiveCfg = Debug|Win32 + {54509728-928B-44D9-A118-A6F92F08B34F}.Debug|Win32.Build.0 = Debug|Win32 + {54509728-928B-44D9-A118-A6F92F08B34F}.Debug|x64.ActiveCfg = Debug|Win32 + {54509728-928B-44D9-A118-A6F92F08B34F}.Release|Win32.ActiveCfg = Release|Win32 + {54509728-928B-44D9-A118-A6F92F08B34F}.Release|Win32.Build.0 = Release|Win32 + {54509728-928B-44D9-A118-A6F92F08B34F}.Release|x64.ActiveCfg = Release|Win32 + {E3DCBC31-7FC9-D127-E000-529F8460D5FD}.Debug|Win32.ActiveCfg = Debug|Win32 + {E3DCBC31-7FC9-D127-E000-529F8460D5FD}.Debug|Win32.Build.0 = Debug|Win32 + {E3DCBC31-7FC9-D127-E000-529F8460D5FD}.Debug|x64.ActiveCfg = Debug|Win32 + {E3DCBC31-7FC9-D127-E000-529F8460D5FD}.Release|Win32.ActiveCfg = Release|Win32 + {E3DCBC31-7FC9-D127-E000-529F8460D5FD}.Release|Win32.Build.0 = Release|Win32 + {E3DCBC31-7FC9-D127-E000-529F8460D5FD}.Release|x64.ActiveCfg = Release|Win32 + {B3FC9DFC-7268-8660-7C0D-B60BAF02C554}.Debug|Win32.ActiveCfg = Debug|Win32 + {B3FC9DFC-7268-8660-7C0D-B60BAF02C554}.Debug|Win32.Build.0 = Debug|Win32 + {B3FC9DFC-7268-8660-7C0D-B60BAF02C554}.Debug|x64.ActiveCfg = Debug|Win32 + {B3FC9DFC-7268-8660-7C0D-B60BAF02C554}.Release|Win32.ActiveCfg = Release|Win32 + {B3FC9DFC-7268-8660-7C0D-B60BAF02C554}.Release|Win32.Build.0 = Release|Win32 + {B3FC9DFC-7268-8660-7C0D-B60BAF02C554}.Release|x64.ActiveCfg = Release|Win32 + {12B4C8A5-1E06-4E30-B443-D1F916F52B47}.Debug|Win32.ActiveCfg = Debug|Win32 + {12B4C8A5-1E06-4E30-B443-D1F916F52B47}.Debug|Win32.Build.0 = Debug|Win32 + {12B4C8A5-1E06-4E30-B443-D1F916F52B47}.Debug|x64.ActiveCfg = Debug|Win32 + {12B4C8A5-1E06-4E30-B443-D1F916F52B47}.Release|Win32.ActiveCfg = Release|Win32 + {12B4C8A5-1E06-4E30-B443-D1F916F52B47}.Release|Win32.Build.0 = Release|Win32 + {12B4C8A5-1E06-4E30-B443-D1F916F52B47}.Release|x64.ActiveCfg = Release|Win32 + {95030B82-70CD-4C6B-84D4-61096035BEA2}.Debug|Win32.ActiveCfg = Debug|Win32 + {95030B82-70CD-4C6B-84D4-61096035BEA2}.Debug|Win32.Build.0 = Debug|Win32 + {95030B82-70CD-4C6B-84D4-61096035BEA2}.Debug|x64.ActiveCfg = Debug|Win32 + {95030B82-70CD-4C6B-84D4-61096035BEA2}.Release|Win32.ActiveCfg = Release|Win32 + {95030B82-70CD-4C6B-84D4-61096035BEA2}.Release|Win32.Build.0 = Release|Win32 + {95030B82-70CD-4C6B-84D4-61096035BEA2}.Release|x64.ActiveCfg = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {74E3E3B8-3E51-4003-816B-8ED3057AAC21} + EndGlobalSection +EndGlobal diff --git a/Workspace_msvc/decoder.vcxproj b/Workspace_msvc/decoder.vcxproj index e59992847..1ea98099d 100644 --- a/Workspace_msvc/decoder.vcxproj +++ b/Workspace_msvc/decoder.vcxproj @@ -1,171 +1,171 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - decoder - {E3DCBC31-7FC9-D127-E000-529F8460D5FD} - decoder - 10.0.17763.0 - - - - Application - v141 - false - MultiByte - - - Application - v141 - false - MultiByte - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - ..\ - .\Debug_$(ProjectName)\ - false - false - IVAS_dec - - - ..\ - .\Release_$(ProjectName)\ - false - false - IVAS_dec - - - - - - - $(IntDir)$(ProjectName).tlb - - - - Disabled - ..\lib_dec;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;WIN32;$(Macros);%(PreprocessorDefinitions) - - EnableFastChecks - MultiThreadedDebug - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - OldStyle - Default - %(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - - $(OutDir)$(TargetName).exe - true - - true - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - - - $(IntDir)$(ProjectName).tlb - - - - MaxSpeed - AnySuitable - false - Neither - false - false - ..\lib_dec;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - Precise - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - - Default - %(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - $(OutDir)$(TargetName).exe - true - - false - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX86 - libcmtd.lib - - - - - - - - {e822ddaf-0f5f-4cd0-a694-38ae69de74d3} - false - - - {2fa8f384-0775-f3b7-f8c3-85209222fc70} - false - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + decoder + {E3DCBC31-7FC9-D127-E000-529F8460D5FD} + decoder + 10.0.17763.0 + + + + Application + v141 + false + MultiByte + + + Application + v141 + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + ..\ + .\Debug_$(ProjectName)\ + false + false + IVAS_dec + + + ..\ + .\Release_$(ProjectName)\ + false + false + IVAS_dec + + + + + + + $(IntDir)$(ProjectName).tlb + + + + Disabled + ..\lib_dec;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;WIN32;$(Macros);%(PreprocessorDefinitions) + + EnableFastChecks + MultiThreadedDebug + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + OldStyle + Default + %(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + + $(OutDir)$(TargetName).exe + true + + true + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + + + $(IntDir)$(ProjectName).tlb + + + + MaxSpeed + AnySuitable + false + Neither + false + false + ..\lib_dec;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + Precise + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + + Default + %(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + $(OutDir)$(TargetName).exe + true + + false + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX86 + libcmtd.lib + + + + + + + + {e822ddaf-0f5f-4cd0-a694-38ae69de74d3} + false + + + {2fa8f384-0775-f3b7-f8c3-85209222fc70} + false + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/encoder.vcxproj b/Workspace_msvc/encoder.vcxproj index 9578e488d..5ec7a2c01 100644 --- a/Workspace_msvc/encoder.vcxproj +++ b/Workspace_msvc/encoder.vcxproj @@ -1,178 +1,178 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - encoder - {B3FC9DFC-7268-8660-7C0D-B60BAF02C554} - encoder - 10.0.17763.0 - - - - Application - v141 - false - MultiByte - - - Application - v141 - false - MultiByte - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - ..\ - .\Debug_$(ProjectName)\ - false - false - IVAS_cod - - - ..\ - .\Release_$(ProjectName)\ - false - false - IVAS_cod - - - - - - - $(IntDir)$(ProjectName).tlb - - - - Disabled - ..\lib_enc;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;WIN32;$(Macros);%(PreprocessorDefinitions) - - EnableFastChecks - MultiThreadedDebug - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - OldStyle - Default - %(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - - $(OutDir)$(TargetName).exe - true - - false - true - $(IntDir)$(ProjectName).pdb - Console - - false - - MachineX86 - - - - - - - - - - - $(IntDir)$(ProjectName).tlb - - - - MaxSpeed - AnySuitable - false - Neither - false - false - ..\lib_enc;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - Precise - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - - Default - %(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - $(OutDir)$(TargetName).exe - true - - false - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - - - - - - {824da4cf-06f0-45c9-929a-8792f0e19c3e} - false - - - {2fa8f384-0775-f3b7-f8c3-85209222fc70} - false - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + encoder + {B3FC9DFC-7268-8660-7C0D-B60BAF02C554} + encoder + 10.0.17763.0 + + + + Application + v141 + false + MultiByte + + + Application + v141 + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + ..\ + .\Debug_$(ProjectName)\ + false + false + IVAS_cod + + + ..\ + .\Release_$(ProjectName)\ + false + false + IVAS_cod + + + + + + + $(IntDir)$(ProjectName).tlb + + + + Disabled + ..\lib_enc;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;WIN32;$(Macros);%(PreprocessorDefinitions) + + EnableFastChecks + MultiThreadedDebug + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + OldStyle + Default + %(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + + $(OutDir)$(TargetName).exe + true + + false + true + $(IntDir)$(ProjectName).pdb + Console + + false + + MachineX86 + + + + + + + + + + + $(IntDir)$(ProjectName).tlb + + + + MaxSpeed + AnySuitable + false + Neither + false + false + ..\lib_enc;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + Precise + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + + Default + %(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + $(OutDir)$(TargetName).exe + true + + false + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + + + + + + {824da4cf-06f0-45c9-929a-8792f0e19c3e} + false + + + {2fa8f384-0775-f3b7-f8c3-85209222fc70} + false + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/lib_com.vcxproj b/Workspace_msvc/lib_com.vcxproj index 0c5d4dcca..494131992 100644 --- a/Workspace_msvc/lib_com.vcxproj +++ b/Workspace_msvc/lib_com.vcxproj @@ -1,309 +1,309 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - {39EC200D-7795-4FF8-B214-B24EDA5526AE} - common - 10.0.17763.0 - - - - StaticLibrary - v141 - false - MultiByte - - - StaticLibrary - v141 - false - MultiByte - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - .\Debug_$(ProjectName)\ - .\Debug_$(ProjectName)\ - libivascom - - - .\Release_$(ProjectName)\ - .\Release_$(ProjectName)\ - libivascom - - - - - - - Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) - - EnableFastChecks - MultiThreadedDebug - - - $(IntDir)$(ProjectName).pdb - Level4 - true - OldStyle - Default - %(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - WS2_32.lib; %(AdditionalDependencies) - $(OutDir)$(TargetName).lib - true - - - - - - - - MaxSpeed - AnySuitable - false - Neither - false - false - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - - - $(IntDir)$(ProjectName).pdb - Level4 - true - - Default - %(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - WS2_32.lib; %(AdditionalDependencies) - $(OutDir)$(TargetName).lib - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + {39EC200D-7795-4FF8-B214-B24EDA5526AE} + common + 10.0.17763.0 + + + + StaticLibrary + v141 + false + MultiByte + + + StaticLibrary + v141 + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + .\Debug_$(ProjectName)\ + .\Debug_$(ProjectName)\ + libivascom + + + .\Release_$(ProjectName)\ + .\Release_$(ProjectName)\ + libivascom + + + + + + + Disabled + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_lc3plus;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) + + EnableFastChecks + MultiThreadedDebug + + + $(IntDir)$(ProjectName).pdb + Level4 + true + OldStyle + Default + %(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + + + + MaxSpeed + AnySuitable + false + Neither + false + false + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_lc3plus;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + + + $(IntDir)$(ProjectName).pdb + Level4 + true + + Default + %(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/lib_com.vcxproj.filters b/Workspace_msvc/lib_com.vcxproj.filters index 85fd7e8d6..66edeac26 100644 --- a/Workspace_msvc/lib_com.vcxproj.filters +++ b/Workspace_msvc/lib_com.vcxproj.filters @@ -1,551 +1,551 @@ - - - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_evs_c - - - common_evs_c - - - common_evs_c - - - common_evs_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_evs_c - - - common_evs_c - - - common_evs_c - - - common_evs_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - - - common_h - - - common_h - - - common_h - - - common_h - - - common_h - - - common_h - - - common_h - - - common_h - - - common_h - - - common_h - - - common_h - - - common_h - - - common_h - - - common_h - - - common_h - - - common_h - - - common_h - - - common_h - - - common_h - - - - common_h - - - - - - {890c2f45-9385-4fce-859b-6a65469e8dc0} - - - {201ea764-9626-4dca-9cc4-5b4106f8b8b2} - - - {fbb860e2-79d0-45b1-ada1-c3a0a369ce2c} - - - {b95b7bed-a666-4a00-9332-2b528638503e} - - + + + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_evs_c + + + common_evs_c + + + common_evs_c + + + common_evs_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_evs_c + + + common_evs_c + + + common_evs_c + + + common_evs_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + + + common_h + + + common_h + + + common_h + + + common_h + + + common_h + + + common_h + + + common_h + + + common_h + + + common_h + + + common_h + + + common_h + + + common_h + + + common_h + + + common_h + + + common_h + + + common_h + + + common_h + + + common_h + + + common_h + + + + common_h + + + + + + {890c2f45-9385-4fce-859b-6a65469e8dc0} + + + {201ea764-9626-4dca-9cc4-5b4106f8b8b2} + + + {fbb860e2-79d0-45b1-ada1-c3a0a369ce2c} + + + {b95b7bed-a666-4a00-9332-2b528638503e} + + \ No newline at end of file diff --git a/Workspace_msvc/lib_debug.vcxproj b/Workspace_msvc/lib_debug.vcxproj index f54f282f0..7a3f87e44 100644 --- a/Workspace_msvc/lib_debug.vcxproj +++ b/Workspace_msvc/lib_debug.vcxproj @@ -1,116 +1,121 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - {54509728-928B-44D9-A118-A6F92F08B34F} - debug - 10.0.17763.0 - - - - StaticLibrary - v141 - MultiByte - - - StaticLibrary - v141 - MultiByte - true - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - .\Debug_$(ProjectName)\ - .\Debug_$(ProjectName)\ - libivasdebug - - - .\Release_$(ProjectName)\ - .\Release_$(ProjectName)\ - libivasdebug - - - - - - - Disabled - ..\lib_com;..\lib_debug;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) - false - - EnableFastChecks - MultiThreadedDebug - false - $(IntDir)$(ProjectName).pdb - Level4 - OldStyle - Default - %(DisableSpecificWarnings) - - - $(OutDir)$(TargetName).lib - - - - - - - - MaxSpeed - AnySuitable - false - false - ..\lib_com;..\lib_debug;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - $(IntDir)$(ProjectName).pdb - Level4 - - Default - %(DisableSpecificWarnings) - - - $(OutDir)$(TargetName).lib - - - - - - - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + {54509728-928B-44D9-A118-A6F92F08B34F} + debug + 10.0.17763.0 + + + + StaticLibrary + v141 + MultiByte + + + StaticLibrary + v141 + MultiByte + true + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + .\Debug_$(ProjectName)\ + .\Debug_$(ProjectName)\ + libivasdebug + + + .\Release_$(ProjectName)\ + .\Release_$(ProjectName)\ + libivasdebug + + + + + + + Disabled + ..\lib_com;..\lib_debug;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) + false + + EnableFastChecks + MultiThreadedDebug + false + $(IntDir)$(ProjectName).pdb + Level4 + OldStyle + Default + %(DisableSpecificWarnings) + + + $(OutDir)$(TargetName).lib + + + + + + + + MaxSpeed + AnySuitable + false + false + ..\lib_com;..\lib_debug;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + $(IntDir)$(ProjectName).pdb + Level4 + + Default + %(DisableSpecificWarnings) + + + $(OutDir)$(TargetName).lib + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/lib_dec.vcxproj b/Workspace_msvc/lib_dec.vcxproj index 0266955ab..228f821f1 100644 --- a/Workspace_msvc/lib_dec.vcxproj +++ b/Workspace_msvc/lib_dec.vcxproj @@ -1,349 +1,349 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - lib_dec - {E822DDAF-0F5F-4CD0-A694-38AE69DE74D3} - evs_dec - 10.0.17763.0 - - - StaticLibrary - v141 - false - MultiByte - - - - StaticLibrary - v141 - false - MultiByte - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - .\Debug_$(ProjectName)\ - .\Debug_$(ProjectName)\ - false - false - libivasdec - - - .\Release_$(ProjectName)\ - .\Release_$(ProjectName)\ - false - false - libivasdec - - - - - - - .\Debug\$(ProjectName).tlb - - - - Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) - - EnableFastChecks - MultiThreadedDebug - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - OldStyle - Default - %(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - WS2_32.lib; %(AdditionalDependencies) - $(OutDir)$(TargetName).lib - true - - - - - - - - $(IntDir)$(ProjectName).tlb - - - - MaxSpeed - AnySuitable - false - Neither - false - false - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - - Default - %(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - WS2_32.lib; %(AdditionalDependencies) - $(OutDir)$(TargetName).lib - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {39ec200d-7795-4ff8-b214-b24eda5526ae} - false - - - {54509728-928b-44d9-a118-a6f92f08b34f} - false - - - {718DE063-A18B-BB72-9150-62B892E6FFA6} - false - - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + lib_dec + {E822DDAF-0F5F-4CD0-A694-38AE69DE74D3} + evs_dec + 10.0.17763.0 + + + StaticLibrary + v141 + false + MultiByte + + + + StaticLibrary + v141 + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + .\Debug_$(ProjectName)\ + .\Debug_$(ProjectName)\ + false + false + libivasdec + + + .\Release_$(ProjectName)\ + .\Release_$(ProjectName)\ + false + false + libivasdec + + + + + + + .\Debug\$(ProjectName).tlb + + + + Disabled + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_lc3plus;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) + + EnableFastChecks + MultiThreadedDebug + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + OldStyle + Default + %(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + + + + $(IntDir)$(ProjectName).tlb + + + + MaxSpeed + AnySuitable + false + Neither + false + false + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_lc3plus;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + + Default + %(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {39ec200d-7795-4ff8-b214-b24eda5526ae} + false + + + {54509728-928b-44d9-a118-a6f92f08b34f} + false + + + {718DE063-A18B-BB72-9150-62B892E6FFA6} + false + + + + + + + + + + + diff --git a/Workspace_msvc/lib_dec.vcxproj.filters b/Workspace_msvc/lib_dec.vcxproj.filters index 24d58eb97..80340b480 100644 --- a/Workspace_msvc/lib_dec.vcxproj.filters +++ b/Workspace_msvc/lib_dec.vcxproj.filters @@ -1,572 +1,572 @@ - - - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_evs_c - - - decoder_evs_c - - - decoder_evs_c - - - decoder_evs_c - - - decoder_evs_c - - - decoder_evs_c - - - decoder_evs_c - - - decoder_evs_c - - - decoder_evs_c - - - decoder_evs_c - - - decoder_evs_c - - - decoder_evs_c - - - decoder_evs_c - - - decoder_evs_c - - - decoder_evs_c - - - decoder_evs_c - - - decoder_evs_c - - - decoder_evs_c - - - decoder_evs_c - - - decoder_evs_c - - - decoder_evs_c - - - decoder_evs_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - - - - decoder_h - - - decoder_h - - - decoder_h - - - decoder_h - - - decoder_h - - - decoder_h - - - decoder_h - - - decoder_h - - - decoder_h - - - decoder_h - - - decoder_h - - - decoder_h - - - - - - {f63b6db2-97ec-4d8d-be9c-e798ac8bb645} - - - {0853864e-7de7-411d-975b-5045652f22c3} - - - {e29aae34-aeeb-45dd-a986-61b39890c5bb} - - - {c33b80b3-67ce-466b-91c0-4adfc9efcb5c} - - + + + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + + + + decoder_h + + + decoder_h + + + decoder_h + + + decoder_h + + + decoder_h + + + decoder_h + + + decoder_h + + + decoder_h + + + decoder_h + + + decoder_h + + + decoder_h + + + decoder_h + + + + + + {f63b6db2-97ec-4d8d-be9c-e798ac8bb645} + + + {0853864e-7de7-411d-975b-5045652f22c3} + + + {e29aae34-aeeb-45dd-a986-61b39890c5bb} + + + {c33b80b3-67ce-466b-91c0-4adfc9efcb5c} + + \ No newline at end of file diff --git a/Workspace_msvc/lib_enc.vcxproj b/Workspace_msvc/lib_enc.vcxproj index e2db02d61..dae54445c 100644 --- a/Workspace_msvc/lib_enc.vcxproj +++ b/Workspace_msvc/lib_enc.vcxproj @@ -1,365 +1,365 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - lib_enc - {824DA4CF-06F0-45C9-929A-8792F0E19C3E} - evs_enc - 10.0.17763.0 - - - - StaticLibrary - v141 - false - MultiByte - - - StaticLibrary - v141 - false - MultiByte - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - .\Debug_$(ProjectName)\ - .\Debug_$(ProjectName)\ - false - false - libivasenc - - - .\Release_$(ProjectName)\ - .\Release_$(ProjectName)\ - false - false - libivasenc - - - - - - - $(IntDir)$(ProjectName).tlb - - - - Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) - - EnableFastChecks - MultiThreadedDebug - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - OldStyle - Default - %(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - WS2_32.lib; %(AdditionalDependencies) - $(OutDir)$(TargetName).lib - true - - - - - - - - - - - $(IntDir)$(ProjectName).tlb - - - - MaxSpeed - AnySuitable - false - Neither - false - false - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - Precise - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - - Default - %(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - WS2_32.lib; %(AdditionalDependencies) - $(OutDir)$(TargetName).lib - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {39ec200d-7795-4ff8-b214-b24eda5526ae} - false - - - {54509728-928b-44d9-a118-a6f92f08b34f} - false - - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + lib_enc + {824DA4CF-06F0-45C9-929A-8792F0E19C3E} + evs_enc + 10.0.17763.0 + + + + StaticLibrary + v141 + false + MultiByte + + + StaticLibrary + v141 + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + .\Debug_$(ProjectName)\ + .\Debug_$(ProjectName)\ + false + false + libivasenc + + + .\Release_$(ProjectName)\ + .\Release_$(ProjectName)\ + false + false + libivasenc + + + + + + + $(IntDir)$(ProjectName).tlb + + + + Disabled + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_lc3plus;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) + + EnableFastChecks + MultiThreadedDebug + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + OldStyle + Default + %(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + + + + + + + $(IntDir)$(ProjectName).tlb + + + + MaxSpeed + AnySuitable + false + Neither + false + false + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_lc3plus;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + Precise + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + + Default + %(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {39ec200d-7795-4ff8-b214-b24eda5526ae} + false + + + {54509728-928b-44d9-a118-a6f92f08b34f} + false + + + + + + + + + + + diff --git a/Workspace_msvc/lib_enc.vcxproj.filters b/Workspace_msvc/lib_enc.vcxproj.filters index 250aecf0b..4995de5c9 100644 --- a/Workspace_msvc/lib_enc.vcxproj.filters +++ b/Workspace_msvc/lib_enc.vcxproj.filters @@ -1,629 +1,629 @@ - - - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_evs_c - - - enc_evs_c - - - enc_evs_c - - - enc_evs_c - - - enc_evs_c - - - enc_evs_c - - - enc_evs_c - - - enc_evs_c - - - enc_evs_c - - - enc_evs_c - - - enc_evs_c - - - enc_evs_c - - - enc_evs_c - - - enc_evs_c - - - enc_evs_c - - - enc_evs_c - - - enc_evs_c - - - enc_evs_c - - - enc_evs_c - - - enc_evs_c - - - enc_evs_c - - - enc_evs_c - - - enc_evs_c - - - enc_evs_c - - - enc_evs_c - - - enc_evs_c - - - enc_evs_c - - - enc_evs_c - - - enc_evs_c - - - enc_evs_c - - - enc_evs_c - - - enc_evs_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_evs_c - - - enc_evs_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_all_c - - - enc_evs_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - - - enc_h - - - enc_h - - - enc_h - - - enc_h - - - - - - {b7ee0526-8b79-4554-a3ec-04e51d38475f} - - - {dabed049-70a2-48f2-9da6-3b81a3664033} - - - {5717f1cb-c593-400b-b23a-45c422fd95c8} - - - {6cccabbe-510f-43d3-90e1-8ed5ea3837d7} - - + + + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_evs_c + + + enc_evs_c + + + enc_evs_c + + + enc_evs_c + + + enc_evs_c + + + enc_evs_c + + + enc_evs_c + + + enc_evs_c + + + enc_evs_c + + + enc_evs_c + + + enc_evs_c + + + enc_evs_c + + + enc_evs_c + + + enc_evs_c + + + enc_evs_c + + + enc_evs_c + + + enc_evs_c + + + enc_evs_c + + + enc_evs_c + + + enc_evs_c + + + enc_evs_c + + + enc_evs_c + + + enc_evs_c + + + enc_evs_c + + + enc_evs_c + + + enc_evs_c + + + enc_evs_c + + + enc_evs_c + + + enc_evs_c + + + enc_evs_c + + + enc_evs_c + + + enc_evs_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_evs_c + + + enc_evs_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_all_c + + + enc_evs_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + + + enc_h + + + enc_h + + + enc_h + + + enc_h + + + + + + {b7ee0526-8b79-4554-a3ec-04e51d38475f} + + + {dabed049-70a2-48f2-9da6-3b81a3664033} + + + {5717f1cb-c593-400b-b23a-45c422fd95c8} + + + {6cccabbe-510f-43d3-90e1-8ed5ea3837d7} + + \ No newline at end of file diff --git a/Workspace_msvc/lib_lc3plus.vcxproj b/Workspace_msvc/lib_lc3plus.vcxproj new file mode 100644 index 000000000..c61e00bf3 --- /dev/null +++ b/Workspace_msvc/lib_lc3plus.vcxproj @@ -0,0 +1,183 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {95030B82-70CD-4C6B-84D4-61096035BEA2} + Win32Proj + LC3_FL + 10.0.17763.0 + + + + StaticLibrary + true + v141 + Unicode + + + StaticLibrary + false + v141 + true + Unicode + + + + + + + + + + + + + + + liblc3plus + .\Debug_$(ProjectName)\ + .\Debug_$(ProjectName)\ + + + LC3plus + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\Obj\ + + + + + + Level3 + ..\lib_com;%(AdditionalIncludeDirectories) + Disabled + MultiThreadedDebug + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + 4305;4244;4996 + OldStyle + false + + + Console + true + + + + + Level3 + + + ..\lib_com;%(AdditionalIncludeDirectories) + MaxSpeed + MultiThreaded + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + 4244;4305;4996 + + + Console + true + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/lib_rend.vcxproj b/Workspace_msvc/lib_rend.vcxproj index ee40123a8..fdc709e44 100644 --- a/Workspace_msvc/lib_rend.vcxproj +++ b/Workspace_msvc/lib_rend.vcxproj @@ -1,207 +1,234 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - lib_rend - {718DE063-A18B-BB72-9150-62B892E6FFA6} - evs_dec - 10.0.17763.0 - - - StaticLibrary - v141 - false - MultiByte - - - - StaticLibrary - v141 - false - MultiByte - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - .\Debug_$(ProjectName)\ - .\Debug_$(ProjectName)\ - false - false - libivasrend - - - .\Release_$(ProjectName)\ - .\Release_$(ProjectName)\ - false - false - libivasrend - - - - - - - .\Debug\$(ProjectName).tlb - - - - Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) - - EnableFastChecks - MultiThreadedDebug - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - OldStyle - Default - %(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - WS2_32.lib; %(AdditionalDependencies) - $(OutDir)$(TargetName).lib - true - - - - - - - - $(IntDir)$(ProjectName).tlb - - - - MaxSpeed - AnySuitable - false - Neither - false - false - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - - Default - %(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - WS2_32.lib; %(AdditionalDependencies) - $(OutDir)$(TargetName).lib - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {39ec200d-7795-4ff8-b214-b24eda5526ae} - false - - - {54509728-928b-44d9-a118-a6f92f08b34f} - false - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + lib_rend + {718DE063-A18B-BB72-9150-62B892E6FFA6} + evs_dec + 10.0.17763.0 + + + StaticLibrary + v141 + false + MultiByte + + + + StaticLibrary + v141 + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + .\Debug_$(ProjectName)\ + .\Debug_$(ProjectName)\ + false + false + libivasrend + + + .\Release_$(ProjectName)\ + .\Release_$(ProjectName)\ + false + false + libivasrend + + + + + + + .\Debug\$(ProjectName).tlb + + + + Disabled + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_lc3plus;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) + + EnableFastChecks + MultiThreadedDebug + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + OldStyle + Default + %(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + + + + $(IntDir)$(ProjectName).tlb + + + + MaxSpeed + AnySuitable + false + Neither + false + false + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_lc3plus;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + + Default + %(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {39ec200d-7795-4ff8-b214-b24eda5526ae} + false + + + {54509728-928b-44d9-a118-a6f92f08b34f} + false + + + {95030B82-70CD-4C6B-84D4-61096035BEA2} + false + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/lib_rend.vcxproj.filters b/Workspace_msvc/lib_rend.vcxproj.filters index 4707a48b2..e5e6c9401 100644 --- a/Workspace_msvc/lib_rend.vcxproj.filters +++ b/Workspace_msvc/lib_rend.vcxproj.filters @@ -1,221 +1,221 @@ - - - - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - - - - rend_h - - - rend_h - - - rend_h - - - rend_h - - - rend_h - - - rend_h - - - rend_h - - - rend_h - - - rend_h - - - rend_h - - - rend_h - - - - - {54449ece-ef29-44b5-9512-ed8f555851a8} - - - {672b0eb6-cce8-425c-8bf2-aba4b45639bb} - - + + + + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + + + + rend_h + + + rend_h + + + rend_h + + + rend_h + + + rend_h + + + rend_h + + + rend_h + + + rend_h + + + rend_h + + + rend_h + + + rend_h + + + + + {54449ece-ef29-44b5-9512-ed8f555851a8} + + + {672b0eb6-cce8-425c-8bf2-aba4b45639bb} + + \ No newline at end of file diff --git a/Workspace_msvc/lib_util.vcxproj b/Workspace_msvc/lib_util.vcxproj index 6696ee00a..76f69d8be 100644 --- a/Workspace_msvc/lib_util.vcxproj +++ b/Workspace_msvc/lib_util.vcxproj @@ -1,156 +1,162 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - {2FA8F384-0775-F3B7-F8C3-85209222FC70} - utility - 10.0.17763.0 - - - - StaticLibrary - v141 - MultiByte - - - StaticLibrary - v141 - MultiByte - true - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - true - .\Debug_$(ProjectName)\ - .\Debug_$(ProjectName)\ - libivasutil - - - false - .\Release_$(ProjectName)\ - .\Release_$(ProjectName)\ - libivasutil - - - - Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_util;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);ZLIB_WINAPI;%(PreprocessorDefinitions) - false - - EnableFastChecks - MultiThreadedDebug - false - $(IntDir)$(ProjectName).pdb - Level4 - OldStyle - Default - %(DisableSpecificWarnings) - - - $(OutDir)$(TargetName).lib - - - - - MaxSpeed - AnySuitable - false - false - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_util;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);ZLIB_WINAPI;%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - $(IntDir)$(ProjectName).pdb - Level4 - - Default - %(DisableSpecificWarnings) - - - $(OutDir)$(TargetName).lib - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + {2FA8F384-0775-F3B7-F8C3-85209222FC70} + utility + 10.0.17763.0 + + + + StaticLibrary + v141 + MultiByte + + + StaticLibrary + v141 + MultiByte + true + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + true + .\Debug_$(ProjectName)\ + .\Debug_$(ProjectName)\ + libivasutil + + + false + .\Release_$(ProjectName)\ + .\Release_$(ProjectName)\ + libivasutil + + + + Disabled + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_util;..\lib_lc3plus;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);ZLIB_WINAPI;%(PreprocessorDefinitions) + false + + EnableFastChecks + MultiThreadedDebug + false + $(IntDir)$(ProjectName).pdb + Level4 + OldStyle + Default + %(DisableSpecificWarnings) + + + $(OutDir)$(TargetName).lib + + + + + MaxSpeed + AnySuitable + false + false + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_util;..\lib_lc3plus;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);ZLIB_WINAPI;%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + $(IntDir)$(ProjectName).pdb + Level4 + + Default + %(DisableSpecificWarnings) + + + $(OutDir)$(TargetName).lib + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/renderer.vcxproj b/Workspace_msvc/renderer.vcxproj index c62874ec0..6047c5b39 100644 --- a/Workspace_msvc/renderer.vcxproj +++ b/Workspace_msvc/renderer.vcxproj @@ -1,180 +1,180 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - renderer - {12B4C8A5-1E06-4E30-B443-D1F916F52B47} - renderer - 10.0.17763.0 - - - - Application - v141 - false - MultiByte - - - Application - v141 - false - MultiByte - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - ..\ - .\Debug_$(ProjectName)\ - false - false - IVAS_rend - - - ..\ - .\Release_$(ProjectName)\ - false - false - IVAS_rend - - - - $(IntDir)$(ProjectName).tlb - - - - Disabled - ..\lib_com;..\lib_debug;..\lib_util;..\lib_rend;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;WIN32;$(Macros);%(PreprocessorDefinitions) - - EnableFastChecks - MultiThreadedDebug - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - OldStyle - Default - %(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - - $(OutDir)$(TargetName).exe - true - - true - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - - - $(IntDir)$(ProjectName).tlb - - - - MaxSpeed - AnySuitable - false - Neither - false - false - ..\lib_com;..\lib_debug;..\lib_util;..\lib_rend;.%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - Precise - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - - Default - %(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - $(OutDir)$(TargetName).exe - true - - false - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX86 - libcmtd.lib - - - - - - - - {54509728-928B-44D9-A118-A6F92F08B34F} - false - - - {E822DDAF-0F5F-4CD0-A694-38AE69DE74D3} - false - - - {2FA8F384-0775-F3B7-F8C3-85209222FC70} - false - - - {39ec200d-7795-4ff8-b214-b24eda5526ae} - false - - - {718DE063-A18B-BB72-9150-62B892E6FFA6} - false - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + renderer + {12B4C8A5-1E06-4E30-B443-D1F916F52B47} + renderer + 10.0.17763.0 + + + + Application + v141 + false + MultiByte + + + Application + v141 + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + ..\ + .\Debug_$(ProjectName)\ + false + false + IVAS_rend + + + ..\ + .\Release_$(ProjectName)\ + false + false + IVAS_rend + + + + $(IntDir)$(ProjectName).tlb + + + + Disabled + ..\lib_com;..\lib_debug;..\lib_util;..\lib_rend;..\lib_lc3plus;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;WIN32;$(Macros);%(PreprocessorDefinitions) + + EnableFastChecks + MultiThreadedDebug + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + OldStyle + Default + %(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + + $(OutDir)$(TargetName).exe + true + + true + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + + + $(IntDir)$(ProjectName).tlb + + + + MaxSpeed + AnySuitable + false + Neither + false + false + ..\lib_com;..\lib_debug;..\lib_util;..\lib_rend;..\lib_lc3plus;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + Precise + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + + Default + %(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + $(OutDir)$(TargetName).exe + true + + false + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX86 + libcmtd.lib + + + + + + + + {54509728-928B-44D9-A118-A6F92F08B34F} + false + + + {E822DDAF-0F5F-4CD0-A694-38AE69DE74D3} + false + + + {2FA8F384-0775-F3B7-F8C3-85209222FC70} + false + + + {39ec200d-7795-4ff8-b214-b24eda5526ae} + false + + + {718DE063-A18B-BB72-9150-62B892E6FFA6} + false + + + + + + + + + + \ No newline at end of file diff --git a/lib_com/ACcontextMapping.c b/lib_com/ACcontextMapping.c index 13cbe8482..1705a3f7d 100644 --- a/lib_com/ACcontextMapping.c +++ b/lib_com/ACcontextMapping.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "prot.h" #include "wmc_auto.h" diff --git a/lib_com/arith_coder.c b/lib_com/arith_coder.c index f27617b27..cc29c9747 100644 --- a/lib_com/arith_coder.c +++ b/lib_com/arith_coder.c @@ -37,6 +37,9 @@ #include #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "prot.h" diff --git a/lib_com/basop_mpy.c b/lib_com/basop_mpy.c index cb6268d62..db2a14c0b 100644 --- a/lib_com/basop_mpy.c +++ b/lib_com/basop_mpy.c @@ -37,6 +37,9 @@ #include "basop_mpy.h" #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #define WMC_TOOL_SKIP diff --git a/lib_com/basop_mpy.h b/lib_com/basop_mpy.h index c35531fa6..4a8d4473c 100644 --- a/lib_com/basop_mpy.h +++ b/lib_com/basop_mpy.h @@ -40,6 +40,9 @@ #include "stl.h" #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif /** * \brief 32*16 Bit fractional Multiplication using 40 bit OPS diff --git a/lib_com/basop_tcx_utils.c b/lib_com/basop_tcx_utils.c index f57bf10a8..6d2c80f6b 100644 --- a/lib_com/basop_tcx_utils.c +++ b/lib_com/basop_tcx_utils.c @@ -37,6 +37,9 @@ #include #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "basop_proto_func.h" #include "stl.h" diff --git a/lib_com/basop_util.c b/lib_com/basop_util.c index f3247f2d0..0a168852b 100644 --- a/lib_com/basop_util.c +++ b/lib_com/basop_util.c @@ -37,6 +37,9 @@ #include #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "basop_util.h" #include "rom_com.h" #include "basop_settings.h" diff --git a/lib_com/bitalloc.c b/lib_com/bitalloc.c index 351ab9e3a..e560e300a 100644 --- a/lib_com/bitalloc.c +++ b/lib_com/bitalloc.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "rom_com.h" #include "prot.h" diff --git a/lib_com/bitallocsum.c b/lib_com/bitallocsum.c index 2daf67b73..d3f880752 100644 --- a/lib_com/bitallocsum.c +++ b/lib_com/bitallocsum.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "prot.h" #include "wmc_auto.h" diff --git a/lib_com/bits_alloc.c b/lib_com/bits_alloc.c index 0d1611de6..cb3945a6c 100644 --- a/lib_com/bits_alloc.c +++ b/lib_com/bits_alloc.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "rom_com.h" #include "prot.h" #include "ivas_cnst.h" @@ -438,6 +441,16 @@ static ivas_error acelp_FCB_allocator( } } cdbk--; +#ifdef DEBUGGING + if ( cdbk < 0 && coder_type != TRANSITION ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Error: Too low bit-budget for fixed innovation codebook (frame = %d). Exiting! \n", frame ); + } + if ( ( L_subfr == L_SUBFR && cdbk >= ACELP_FIXED_CDK_NB ) || ( L_subfr == 2 * L_SUBFR && fcb_table( cdbk, L_subfr ) == 128 /*stop value*/ ) ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Error: Too high bit-budget for fixed innovation codebook (frame = %d). Exiting! \n", frame ); + } +#endif set_s( p_fixed_cdk_index, cdbk, nb_subfr ); nBits_tmp = 0; @@ -547,6 +560,9 @@ ivas_error config_acelp1( int16_t i, bits, nb_subfr; int16_t flag_hardcoded, coder_type_sw, fix_first; int32_t core_brate; +#ifdef DEBUGGING + int32_t core_brate_inpI = core_brate_inp; +#endif ivas_error error; error = IVAS_ERR_OK; @@ -572,11 +588,28 @@ ivas_error config_acelp1( { nb_subfr = NB_SUBFR; +#ifdef DEBUGGING + if ( ( ( core_brate_inp < 5900 && coder_type > UNVOICED ) && !( core_brate_inp < MIN_TC_BRATE && coder_type == TRANSITION ) ) && !( idchan > 0 && element_mode == IVAS_CPE_TD ) && !( element_mode == IVAS_SCE && tdm_low_rate_mode ) ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Error: Too low bitrate (%d bps) for ACELP@12k8 in frame %d. Exiting!\n", core_brate_inpI, frame ); + } + + if ( core_brate_inp > ACELP_12k8_HIGH_LIMIT && core == ACELP_CORE ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Error: Too high bitrate (%d bps) for ACELP@12k8 in frame %d. Exiting!\n", core_brate_inpI, frame ); + } +#endif } else /* L_frame == L_FRAME16k */ { nb_subfr = NB_SUBFR16k; +#ifdef DEBUGGING + if ( core_brate_inp < ACELP_16k_LOW_LIMIT && core == ACELP_CORE ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Error: Too low bitrate (%d bps) for ACELP@16k in frame %d. Exiting!\n", core_brate_inpI, frame ); + } +#endif } coder_type_sw = coder_type; @@ -999,6 +1032,14 @@ ivas_error config_acelp1( } acelp_cfg->fcb_mode = 1; +#ifdef DEBUGGING + if ( bits >= 55 ) + { + printf( "too much bits -> %d, LPC = %d and pitch = %d\n", bits, tdm_lp_reuse_flag, tdm_Pitch_reuse_flag ); + acelp_FCB_allocator( &bits, acelp_cfg->fixed_cdk_index, 2, 2 * L_SUBFR, GENERIC, -1, 0 ); + } + else +#endif if ( bits >= 16 ) { acelp_FCB_allocator( &bits, acelp_cfg->fixed_cdk_index, 2, 2 * L_SUBFR, GENERIC, -1, 0 ); @@ -1084,6 +1125,10 @@ ivas_error config_acelp1( i--; /* must be odd */ } i = min( i, 13 ); +#ifdef DEBUG_MODE_TD + if ( i < 0 ) + IVAS_ERROR( IVAS_ERR_INTERNAL, "ERROR::: UC negative index should not happen at frame %d\n", frame ); +#endif i = max( i, 0 ); /* If i == 0-> random noise generator will be used as FCB */ set_s( acelp_cfg->fixed_cdk_index, i, NB_SUBFR ); bits -= ( i * NB_SUBFR ); @@ -1120,6 +1165,9 @@ ivas_error config_acelp1( } else /* No FCB */ { +#ifdef DEBUGGING + IVAS_ERROR( IVAS_ERR_INTERNAL, "WARNING!!!, No bit allocated to FCB, check frame %d\n", frame ); +#endif acelp_cfg->fixed_cdk_index[0] = -1; acelp_cfg->fixed_cdk_index[1] = -1; acelp_cfg->fixed_cdk_index[2] = -1; @@ -1273,6 +1321,9 @@ ivas_error config_acelp1( } else if ( flag_hardcoded && core == ACELP_CORE && bits != 0 ) { +#ifdef DEBUGGING + IVAS_ERROR( IVAS_ERR_INTERNAL, "ERROR: bit-budget incorrect (%d bits) in frame %d.\n", (int32_t) bits, frame ); +#endif } else if ( bits > 0 && !( coder_type == UNVOICED && tdm_low_rate_mode == 1 && element_mode == IVAS_CPE_TD ) ) { @@ -1307,6 +1358,12 @@ ivas_error config_acelp1( bits -= allocate_unused( core_brate, coder_type, bits, 1, 0, LSFPRM, &acelp_cfg->lsf_bits ); } } +#ifdef DEBUGGING + if ( idchan > 0 && bits > 0 && ( coder_type > UNVOICED || tdm_low_rate_mode == 0 ) ) + { + IVAS_ERROR( IVAS_ERR_INTERNAL, "WARNING !! Unused bits in secondary channel at frame %d\n", frame ); + } +#endif } else if ( core == ACELP_CORE && coder_type >= UNVOICED && coder_type <= GENERIC && L_frame == L_FRAME ) @@ -1331,6 +1388,9 @@ ivas_error config_acelp1( } else if ( bits < 0 && !( coder_type == UNVOICED && tdm_low_rate_mode == 1 && element_mode == IVAS_CPE_TD ) ) { +#ifdef DEBUGGING + IVAS_ERROR( IVAS_ERR_INTERNAL, "ERROR: bit-budget incorrect (%d bits) in frame %d.\n", (int32_t) bits, frame ); +#endif } } @@ -1400,6 +1460,9 @@ static int16_t allocate_unused( } else { +#ifdef DEBUG_MODE_TD + IVAS_ERROR( IVAS_ERR_WRONG_MODE, "unknown mode in bit_alloc.c" ); +#endif } max_bit_per_pos = min( unused_bits, max_bit_per_pos - prm_bit_mode[subfr] ); diff --git a/lib_com/bitstream.c b/lib_com/bitstream.c index 0aeed3040..4a24d905a 100644 --- a/lib_com/bitstream.c +++ b/lib_com/bitstream.c @@ -37,6 +37,9 @@ #include #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "prot.h" #include "stat_enc.h" @@ -48,6 +51,16 @@ #include "ivas_rom_com.h" #include "wmc_auto.h" +#ifdef DEBUGGING + +#define FEC_SEED 12558 + +/*-------------------------------------------------------------------* + * Global variables + *--------------------------------------------------------------------*/ + +FILE *FEC_pattern = NULL; /* FEC pattern file (for simulation of FEC) */ +#endif #define STEP_MAX_NUM_INDICES 100 /* increase the maximum number of allowed indices in the list by this amount */ @@ -830,6 +843,9 @@ ivas_error check_ind_list_limits( /* the re-allocation can be avoided by increasing the limits in get_ivas_max_num_indices() or get_ivas_max_num_indices_metadata() */ if ( ( &hBstr->ind_list[hBstr->nb_ind_tot] - ivas_ind_list_zero ) >= *( hBstr->ivas_max_num_indices ) ) { +#ifdef DEBUGGING + fprintf( stderr, "Warning: The maximum number of indices %d has been exceeded in frame %d! Increase the limits in get_ivas_max_num_indices() or get_max_num_indices_metadata().\n", *( hBstr->ivas_max_num_indices ), frame ); +#endif /* reallocate the buffer of indices with increased limit */ if ( ( error = ind_list_realloc( *hBstr->ivas_ind_list_zero, *( hBstr->ivas_max_num_indices ) + STEP_MAX_NUM_INDICES, hBstr->st_ivas ) ) != IVAS_ERR_OK ) @@ -843,6 +859,9 @@ ivas_error check_ind_list_limits( { if ( hBstr->nb_ind_tot == 0 ) { +#ifdef DEBUGGING + fprintf( stderr, "Warning: Trying to overwrite an existing indice ID = %d in frame %d!\n", hBstr->ind_list[hBstr->nb_ind_tot].id, frame ); +#endif /* move the pointer to the next available empty slot */ ivas_ind_list_last = &ivas_ind_list_zero[*( hBstr->ivas_max_num_indices )]; while ( hBstr->ind_list[0].nb_bits > 0 && hBstr->ind_list < ivas_ind_list_last ) @@ -852,6 +871,9 @@ ivas_error check_ind_list_limits( if ( hBstr->ind_list >= ivas_ind_list_last ) { +#ifdef DEBUGGING + fprintf( stderr, "Warning: The maximum number of indices %d has been exceeded in frame %d! Increase the limits in get_ivas_max_num_indices() or get_max_num_indices_metadata().\n", *( hBstr->ivas_max_num_indices ), frame ); +#endif /* no available empty slot -> need to re-allocate the buffer */ if ( ( error = ind_list_realloc( *hBstr->ivas_ind_list_zero, *( hBstr->ivas_max_num_indices ) + STEP_MAX_NUM_INDICES, hBstr->st_ivas ) ) != IVAS_ERR_OK ) @@ -876,11 +898,20 @@ ivas_error check_ind_list_limits( * Push a new indice into the buffer *-------------------------------------------------------------------*/ +#ifdef DEBUG_BS_READ_WRITE +ivas_error push_indice_( +#else ivas_error push_indice( +#endif BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ int16_t id, /* i : ID of the indice */ uint16_t value, /* i : value of the quantized indice */ int16_t nb_bits /* i : number of bits used to quantize the indice */ +#ifdef DEBUG_BS_READ_WRITE + , + int16_t line, + const char *func +#endif ) { int16_t i; @@ -889,6 +920,21 @@ ivas_error push_indice( error = IVAS_ERR_OK; +#ifdef DEBUG_BS_READ_WRITE + printf( "%s: %d: %d: %d\n", func, line, nb_bits, value ); +#endif +#ifdef DEBUGGING + if ( nb_bits < ( 32 - 1 ) && ( value >> nb_bits ) > 0 ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Indice ID = %d with value %d exceeds the range of %d bits (frame %d) !\n", id, value, nb_bits, frame ); + } + + if ( nb_bits > 16 ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Indice ID = %d with value %d is trying to allocate %d bits which exceeds 16 bits (frame %d) !\n", id, value, nb_bits, frame ); + } + +#endif /* check the limits of the list of indices */ if ( ( error = check_ind_list_limits( hBstr ) ) != IVAS_ERR_OK ) @@ -933,10 +979,19 @@ ivas_error push_indice( * Push a new indice into the buffer at the next position *-------------------------------------------------------------------*/ +#ifdef DEBUG_BS_READ_WRITE +ivas_error push_next_indice_( +#else ivas_error push_next_indice( +#endif BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ uint16_t value, /* i : value of the quantized indice */ int16_t nb_bits /* i : number of bits used to quantize the indice */ +#ifdef DEBUG_BS_READ_WRITE + , + int16_t line, + const char *func +#endif ) { int16_t prev_id; @@ -944,6 +999,21 @@ ivas_error push_next_indice( error = IVAS_ERR_OK; +#ifdef DEBUG_BS_READ_WRITE + printf( "%s: %d: %d: %d\n", func, line, nb_bits, value ); +#endif +#ifdef DEBUGGING + if ( nb_bits < ( 32 - 1 ) && ( value >> nb_bits ) > 0 ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Indice with value %d exceeds the range of %d bits (frame %d) !\n", value, nb_bits, frame ); + } + + if ( nb_bits > 16 ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Indice with value %d is trying to allocate %d bits which exceeds 16 bits !\n", value, nb_bits ); + } + +#endif /* check the limits of the list of indices */ if ( ( error = check_ind_list_limits( hBstr ) ) != IVAS_ERR_OK ) @@ -979,10 +1049,19 @@ ivas_error push_next_indice( * Push a bit buffer into the buffer at the next position *-------------------------------------------------------------------*/ +#ifdef DEBUG_BS_READ_WRITE +ivas_error push_next_bits_( +#else ivas_error push_next_bits( +#endif BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ const uint16_t bits[], /* i : bit buffer to pack, sequence of single bits */ const int16_t nb_bits /* i : number of bits to pack */ +#ifdef DEBUG_BS_READ_WRITE + , + int16_t line, + const char *func +#endif ) { uint16_t code; @@ -992,6 +1071,9 @@ ivas_error push_next_bits( ivas_error error; error = IVAS_ERR_OK; +#ifdef DEBUG_BS_READ_WRITE + printf( "%s: %d: %d\n", func, line, nb_bits ); +#endif ptr = &hBstr->ind_list[hBstr->nb_ind_tot]; @@ -1018,6 +1100,9 @@ ivas_error push_next_bits( ptr = &hBstr->ind_list[hBstr->nb_ind_tot]; ptr->value = code; +#ifdef DEBUG_BS_READ_WRITE + printf( "code: %d\n", code ); +#endif ptr->nb_bits = 16; ptr->id = prev_id; hBstr->nb_ind_tot++; @@ -1034,6 +1119,9 @@ ivas_error push_next_bits( ptr = &hBstr->ind_list[hBstr->nb_ind_tot]; ptr->value = bits[i]; +#ifdef DEBUG_BS_READ_WRITE + printf( "value: %d\n", ptr->value ); +#endif ptr->nb_bits = 1; ptr->id = prev_id; hBstr->nb_ind_tot++; @@ -1129,9 +1217,18 @@ uint16_t delete_indice( *-------------------------------------------------------------------*/ /*! r: value of the indice */ +#ifdef DEBUG_BS_READ_WRITE +uint16_t get_next_indice_( +#else uint16_t get_next_indice( +#endif Decoder_State *st, /* i/o: decoder state structure */ int16_t nb_bits /* i : number of bits that were used to quantize the indice */ +#ifdef DEBUG_BS_READ_WRITE + , + int16_t line, + const char *func +#endif ) { uint16_t value; @@ -1154,6 +1251,9 @@ uint16_t get_next_indice( value <<= 1; value += st->bit_stream[st->next_bit_pos + i]; } +#ifdef DEBUG_BS_READ_WRITE + printf( "%s: %d: %d: %d\n", func, line, nb_bits, value ); +#endif /* update the position in the bitstream */ st->next_bit_pos += nb_bits; @@ -1210,10 +1310,19 @@ void get_next_indice_tmp( *-------------------------------------------------------------------*/ /*! r: value of the indice */ +#ifdef DEBUG_BS_READ_WRITE +uint16_t get_indice_( +#else uint16_t get_indice( +#endif Decoder_State *st, /* i/o: decoder state structure */ int16_t pos, /* i : absolute position in the bitstream (update after the read) */ int16_t nb_bits /* i : number of bits that were used to quantize the indice */ +#ifdef DEBUG_BS_READ_WRITE + , + int16_t line, + const char *func +#endif ) { uint16_t value; @@ -1237,6 +1346,9 @@ uint16_t get_indice( value <<= 1; value += st->bit_stream[pos + i]; } +#ifdef DEBUG_BS_READ_WRITE + printf( "%s: %d: %d: %d\n", func, line, nb_bits, value ); +#endif return value; } @@ -1355,6 +1467,9 @@ static int16_t write_indices_to_stream( int16_t i, k; int16_t value, nb_bits; uint16_t mask; +#ifdef ENABLE_BITRATE_VERIFICATION + int16_t total_nb_bits = 0; +#endif for ( i = 0; i < num_indices; i++ ) { @@ -1363,6 +1478,9 @@ static int16_t write_indices_to_stream( if ( nb_bits > 0 ) { +#ifdef ENABLE_BITRATE_VERIFICATION + total_nb_bits += nb_bits; +#endif /* mask from MSB to LSB */ mask = 1 << ( nb_bits - 1 ); @@ -1383,8 +1501,22 @@ static int16_t write_indices_to_stream( mask >>= 1; } } +#ifdef DEBUGGING + else if ( nb_bits == 0 ) + { + /* fprintf( stderr, "Warning: %s: nb_bits == 0!\n", __func__ ); */ + } + else + { + /* fprintf( stderr, "Warning: %s: nb_bits == %d!\n", __func__, nb_bits ); */ + } +#endif } +#ifdef ENABLE_BITRATE_VERIFICATION + return total_nb_bits; +#else return 0; +#endif } /*-------------------------------------------------------------------* @@ -1410,6 +1542,9 @@ static ivas_error write_indices_element( Indice *ind_list_metadata; int16_t n, n_channels; +#ifdef ENABLE_BITRATE_VERIFICATION + int16_t total_nb_bits; +#endif ivas_error error; error = IVAS_ERR_OK; @@ -1447,6 +1582,12 @@ static ivas_error write_indices_element( nb_ind_tot_metadata = st_ivas->hCPE[element_id]->hMetaData->nb_ind_tot; } } +#ifdef DEBUGGING + else + { + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Error: Bitstream writing error in frame %d. Exiting!\n", frame ); + } +#endif } n_channels = 1; @@ -1476,15 +1617,33 @@ static ivas_error write_indices_element( pt_stream_loc += nb_bits_tot_metadata - 1; pt_stream_end = pt_stream_loc + 1; +#ifdef ENABLE_BITRATE_VERIFICATION + total_nb_bits = +#endif write_indices_to_stream( ind_list_metadata, &pt_stream_loc, -1, nb_ind_tot_metadata ); +#ifdef ENABLE_BITRATE_VERIFICATION + if ( total_nb_bits != nb_bits_tot_metadata ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Bitstream write size mismatch! Written bits: %d vs. Reference bits: %d\n", total_nb_bits, nb_bits_tot_metadata ); + } +#endif /* restore previous pointer position */ pt_stream_loc = pt_stream_backup; } +#ifdef ENABLE_BITRATE_VERIFICATION + total_nb_bits = +#endif write_indices_to_stream( sts[n]->hBstr->ind_list, &pt_stream_loc, 1, sts[n]->hBstr->nb_ind_tot ); +#ifdef ENABLE_BITRATE_VERIFICATION + if ( total_nb_bits != sts[n]->hBstr->nb_bits_tot ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Bitstream write size mismatch! Written bits: %d vs. Reference bits: %d\n", total_nb_bits, sts[n]->hBstr->nb_bits_tot ); + } +#endif if ( pt_stream_loc > pt_stream_end ) { pt_stream_end = pt_stream_loc; @@ -1539,6 +1698,11 @@ ivas_error write_indices_ivas( { int16_t i, n; uint16_t *pt_stream; +#ifdef ENABLE_BITRATE_VERIFICATION + Encoder_State **sts; + int32_t ivas_total_brate; + int16_t ch; +#endif ivas_error error; error = IVAS_ERR_OK; @@ -1549,6 +1713,45 @@ ivas_error write_indices_ivas( bit_stream[i] = 0; } +#ifdef ENABLE_BITRATE_VERIFICATION + i = 0; + + for ( n = 0; n < st_ivas->nSCE; n++ ) + { + sts = st_ivas->hSCE[n]->hCoreCoder; + i += sts[0]->hBstr->nb_bits_tot; + + if ( st_ivas->hSCE[n]->hMetaData != NULL ) + { + i += st_ivas->hSCE[n]->hMetaData->nb_bits_tot; + } + } + + for ( n = 0; n < st_ivas->nCPE; n++ ) + { + sts = st_ivas->hCPE[n]->hCoreCoder; + for ( ch = 0; ch < CPE_CHANNELS; ch++ ) + { + i += sts[ch]->hBstr->nb_bits_tot; + } + + if ( st_ivas->hCPE[n]->hMetaData != NULL ) + { + i += st_ivas->hCPE[n]->hMetaData->nb_bits_tot; + } + } + + ivas_total_brate = st_ivas->hEncoderConfig->ivas_total_brate; + if ( st_ivas->hEncoderConfig->Opt_SC_VBR ) + { + ivas_total_brate = st_ivas->hSCE[0]->hCoreCoder[0]->total_brate; + } + + if ( i * FRAMES_PER_SEC != ivas_total_brate && i >= ACELP_11k60 / FRAMES_PER_SEC ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Bitstream write size mismatch! Actual bitrate: %ld vs. Reference bitrate: %d\n", i * 50L, ivas_total_brate ); + } +#endif /*-----------------------------------------------------------------* * Encode Payload @@ -1663,6 +1866,9 @@ static void decoder_selectCodec( st->codec_mode = MODE1; break; default: /* validate that total_brate (derived from RTP packet or a file header) is one of the defined bitrates */ +#ifdef DEBUGGING + IVAS_ERROR( IVAS_ERR_INTERNAL, "Error illegal total bitrate (= %d) \n", total_brate ); +#endif st->codec_mode = st->last_codec_mode; st->bfi = 1; break; @@ -1734,6 +1940,12 @@ static void dec_prm_core( break; } } +#ifdef DEBUGGING + if ( n == FRAME_SIZE_NB ) + { + assert( !"Bitrate not supported: not part of EVS" ); + } +#endif /* Get audio bandwidth info */ st->bwidth = get_next_indice( st, FrameSizeConfig[frame_size_index].bandwidth_bits ); @@ -1832,6 +2044,9 @@ static void decision_matrix_core_dec( while ( acelp_sig_tbl[start_idx] != st->total_brate ) { start_idx++; +#ifdef DEBUGGING + assert( ( start_idx < 194 ) && "ERROR: start_idx larger than acelp_sig_tbl[].\n" ); +#endif } /* skip the bitrate */ @@ -1977,8 +2192,233 @@ void mdct_switching_dec( return; } +#ifdef DEBUGGING +#ifdef ALLOW_BYTE_EP +/*-------------------------------------------------------------------* + * ep_type_check() + * + * + *-------------------------------------------------------------------*/ +static Word16 ep_type_check() +{ + static int16_t ep_type = -1; /* 0=G192 (0x6b21 or 0x6b20), 1=byte(0x21 or 0x20) , + 2=ascii "0xa30" or "0xa31" , 3=short( 0x0000 or 0x0001) */ + int16_t tmp; + + if ( ep_type < 0 ) + { + tmp = 0; + + if ( fread( &tmp, sizeof( int16_t ), 1, FEC_pattern ) != 1 ) + { + IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Error reading first two bytes from the FEC pattern file !" ); + } + else + { + switch ( tmp ) + { + case G192_SYNC_BAD_FRAME: + case G192_SYNC_GOOD_FRAME: + ep_type = 0; /* G192 */ + break; + case 0x2020: /* BAD,BAD */ + case 0x2021: /* BAD,SYNC */ + case 0x2120: /* SYNC,BAD */ + case 0x2121: /* SYNC,SYNC */ + ep_type = 1; /* byte */ + break; + case 0xa31: + case 0xa30: + ep_type = 2; /* ascii */ + break; + case 0x0000: + case 0x0001: + ep_type = 3; /* short */ + break; + default: + IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Error reading the FEC pattern file :: illegal format of the first two byte word=0x%02x ", tmp ); + IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Allowed formats are G192(0x6b20,0x6b21), byte(0x20,0x21), ASCII(\"0\n\" \"1\n\") or short(0x0000, 0x0001) \n" ); + break; + } + + fseek( FEC_pattern, 0L, SEEK_SET ); /* rewind */ + } + } + return ep_type; +} + +/*-------------------------------------------------------------------* + * ep_flag_check_apply() + * + * + *-------------------------------------------------------------------*/ +static Word16 ep_flag_check_apply( + Word16 ep_type, + Word16 tmp, + Word16 bfi_so_far ) +{ + if ( ep_type == 0 && ( tmp == G192_SYNC_GOOD_FRAME || tmp == G192_SYNC_BAD_FRAME ) ) + { /* g192 validity check */ + if ( tmp == G192_SYNC_BAD_FRAME ) + { + return 1; + } + } + else if ( ep_type == 1 && ( tmp == 0x0021 || tmp == 0x0020 ) ) + { /* byte validity check*/ + if ( tmp == 0x0020 ) + { + return 1; + } + } + else if ( ep_type == 2 && ( tmp == 0x0a31 || tmp == 0x0a30 ) ) + { /* ascii validity check */ + if ( tmp == 0x0a31 ) + { + return 1; + } + } + else if ( ep_type == 3 && ( tmp == 0 || tmp == 1 ) ) + { /* short validity check */ + if ( tmp == 0x0001 ) + { + return 1; + } + } + else + { + IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Error reading the FEC pattern flag 0x%02x from the type %d FEC pattern file , frame=%d", tmp, ep_type, frame ); + } + + return bfi_so_far; /* no change */ +} + +/*-------------------------------------------------------------------* + * read_error_flag ( ) + * + * + *-------------------------------------------------------------------*/ +static Word16 read_error_flag( + Word16 bfi_so_far ) +{ + Word16 tmp; + Word16 ep_type; + Word16 wrap; + wrap = 0; + + ep_type = ep_type_check(); + tmp = 0; + + if ( ( ep_type == 1 ) ? ( fread( &tmp, sizeof( int8_t ), 1, FEC_pattern ) != 1 ) /* read byte directly stored in short variable */ + : ( fread( &tmp, sizeof( int16_t ), 1, FEC_pattern ) != 1 ) ) + { + if ( feof( FEC_pattern ) != 0 ) + { + wrap = 1; /* wrap event flag */ + fseek( FEC_pattern, 0L, SEEK_SET ); +#ifndef WRAP_AS_EIDXOR + /* good frame injected in wrap event */ + switch ( ep_type ) + { + case 0: + tmp = SYNC_GOOD_FRAME; + break; + case 1: + tmp = 0x21; + break; + case 2: + tmp = 0x0a30; + break; + default: + tmp = 0; + break; /* 4: short */ + } +#endif + } + else + { + IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Error reading the FEC pattern file !" ); + } + } +#ifdef WRAP_AS_EIDXOR + if ( wrap != 0 ) /* wrap file and read again, try to get the next flag , */ + { + tmp = 0; /* needed for byte re-reading */ + if ( ( ep_type == 1 ) ? ( fread( &tmp, sizeof( int8_t ), 1, FEC_pattern ) != 1 ) /* read byte directly stored in short variable */ + : ( fread( &tmp, sizeof( int16_t ), 1, FEC_pattern ) != 1 ) ) + { + IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Error reading the wrapped FEC pattern file !" ); + } + } + + return ep_flag_check_apply( ep_type, tmp, bfi_so_far ); +#else + if ( wrap == 0 ) + { + return ep_flag_check_apply( ep_type, tmp, bfi_so_far ); + } + else + { + return bfi_so_far; + } +#endif +} +#endif +#endif + + +#ifdef DEBUGGING +/*-------------------------------------------------------------------* + * file_read_FECpattern() + * + * Simulate packet losses by reading FEC pattern from external file + *-------------------------------------------------------------------*/ + +static ivas_error file_read_FECpattern( + int16_t *bfi ) +{ + ivas_error error; + + error = IVAS_ERR_OK; + *bfi = 0; + + /* FEC pattern file provided */ + if ( FEC_pattern != NULL ) + { + int16_t tmp = 0; + if ( fread( &tmp, sizeof( int16_t ), 1, FEC_pattern ) != 1 ) + { + if ( feof( FEC_pattern ) != 0 ) + { +#ifdef WRAP_AS_EIDXOR + fseek( FEC_pattern, 0L, SEEK_SET ); + fread( &tmp, sizeof( int16_t ), 1, FEC_pattern ); +#else + tmp = 0; + fseek( FEC_pattern, 0L, SEEK_SET ); +#endif + } + else + { + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Error reading the FEC pattern file !" ); + } + } + + if ( tmp == 2609 || tmp == 1 || tmp == (uint16_t) 0x6B20 /* == G192_SYNC_BAD_FRAME */ ) + { + *bfi = 1; + } + else + { + *bfi = 0; + } + } + + return error; +} +#endif /*-------------------------------------------------------------------* @@ -2060,6 +2500,277 @@ void ivas_set_bitstream_pointers( } +#ifdef DEBUGGING +/*-------------------------------------------------------------------* + * preview_indices() + * + * Read indices from serial bitstream to the buffer to print out info + * about technologies. + * + * !!The read parmeters are temporary only and not used for decoding!! + *-------------------------------------------------------------------*/ + +ivas_error preview_indices( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + uint16_t bit_stream[], /* i : bitstream buffer */ + UWord16 num_bits /* i : number of bits in bitstream */ +) +{ + int16_t k, idx; + int32_t total_brate; + ivas_error error; + + error = IVAS_ERR_OK; + + /* convert the frame length to total bitrate */ + total_brate = (int32_t) ( num_bits * FRAMES_PER_SEC ); + + if ( st_ivas->ivas_format != MONO_FORMAT && is_DTXrate( total_brate ) == 0 ) + { + /* read IVAS format */ + k = 0; + if ( bit_stream[0] == 1 ) + { + k = 1; + } + k <<= 1; + if ( bit_stream[1] == 1 ) + { + k += 1; + } + + switch ( k ) + { + case 0: + st_ivas->ivas_format = STEREO_FORMAT; + break; + case 1: + st_ivas->ivas_format = MC_FORMAT; + break; + case 2: + st_ivas->ivas_format = ISM_FORMAT; + + if ( total_brate >= IVAS_24k4 ) + { + if ( bit_stream[2] ) + { + if ( bit_stream[3] ) + { + st_ivas->ivas_format = SBA_ISM_FORMAT; + } + else + { + st_ivas->ivas_format = MASA_ISM_FORMAT; + } + } + } + break; + case 3: + if ( bit_stream[2] == 0 ) + { + st_ivas->ivas_format = SBA_FORMAT; + } + else + { + st_ivas->ivas_format = MASA_FORMAT; + } + break; + } + } + else if ( total_brate == IVAS_SID_5k2 ) + { + /* read SID format */ + st_ivas->sid_format = 0; + if ( bit_stream[0] == 1 ) + { + st_ivas->sid_format += 4; + } + if ( bit_stream[1] == 1 ) + { + st_ivas->sid_format += 2; + } + if ( bit_stream[2] == 1 ) + { + st_ivas->sid_format += 1; + } + + switch ( st_ivas->sid_format ) + { + case SID_DFT_STEREO: + st_ivas->element_mode_init = IVAS_CPE_DFT; + st_ivas->ivas_format = STEREO_FORMAT; + break; + case SID_MDCT_STEREO: + st_ivas->element_mode_init = IVAS_CPE_MDCT; + st_ivas->ivas_format = STEREO_FORMAT; + break; + case SID_ISM: + st_ivas->ivas_format = ISM_FORMAT; + break; + case SID_MULTICHANNEL: + st_ivas->ivas_format = MC_FORMAT; + break; + case SID_SBA_1TC: + st_ivas->ivas_format = SBA_FORMAT; + st_ivas->element_mode_init = IVAS_SCE; + break; + case SID_SBA_2TC: + st_ivas->ivas_format = SBA_FORMAT; + st_ivas->element_mode_init = IVAS_CPE_MDCT; + break; + case SID_MASA_1TC: + st_ivas->ivas_format = MASA_FORMAT; + st_ivas->element_mode_init = IVAS_SCE; + break; + case SID_MASA_2TC: + st_ivas->ivas_format = MASA_FORMAT; + if ( bit_stream[total_brate / FRAMES_PER_SEC - 1] == 1 ) + { + st_ivas->element_mode_init = IVAS_CPE_MDCT; + } + else + { + st_ivas->element_mode_init = IVAS_CPE_DFT; + } + break; + default: + /* This should actually be impossible, since only 3 bits are read, so if this happens something is broken */ + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Invalid value %c found in SID format field.", st_ivas->sid_format ); + } + } + + /* only read element mode from active frames */ + if ( is_DTXrate( total_brate ) == 0 ) + { + /* read element_mode - needed in init_decoder() */ + if ( st_ivas->ivas_format == STEREO_FORMAT || st_ivas->ivas_format == MC_FORMAT || st_ivas->ivas_format == MASA_FORMAT ) + { + if ( st_ivas->ivas_format == MASA_FORMAT ) + { + /* read number of MASA transport channels */ + if ( bit_stream[num_bits - 1] == 1 ) + { + st_ivas->nchan_transport = 2; + } + else + { + st_ivas->nchan_transport = 1; + } + } + + if ( st_ivas->ivas_format == MC_FORMAT ) + { + /* read MC configuration */ + idx = 0; + for ( k = 0; k < MC_LS_SETUP_BITS; k++ ) + { + if ( bit_stream[IVAS_FORMAT_SIGNALING_NBITS + k] == 1 ) + { + idx += ( 1 << ( MC_LS_SETUP_BITS - 1 - k ) ); + } + } + st_ivas->transport_config = ivas_mc_map_ls_setup_to_output_config( (MC_LS_SETUP) idx ); + } + + if ( !( st_ivas->ivas_format == MASA_FORMAT && st_ivas->nchan_transport == 1 ) && st_ivas->ivas_format != MC_FORMAT ) + { + /* read stereo technology info */ + k = IVAS_FORMAT_SIGNALING_NBITS; + if ( st_ivas->ivas_format == MASA_FORMAT ) + { + k = IVAS_FORMAT_SIGNALING_NBITS_EXTENDED; + } + + if ( total_brate < MIN_BRATE_MDCT_STEREO ) + { + /* 1 bit */ + if ( bit_stream[k] == 1 ) + { + st_ivas->element_mode_init = 1 + IVAS_CPE_DFT; + } + else + { + st_ivas->element_mode_init = 0 + IVAS_CPE_DFT; + } + } + else + { + st_ivas->element_mode_init = IVAS_CPE_MDCT; + } + } + } + else if ( st_ivas->ivas_format == ISM_FORMAT ) + { + /* read number of objects from the bitstream */ + st_ivas->nchan_transport = 1; + + k = (int16_t) ( ( total_brate / FRAMES_PER_SEC ) - 1 ); + while ( bit_stream[k] == 1 && st_ivas->nchan_transport < MAX_NUM_OBJECTS ) + { + st_ivas->nchan_transport++; + k--; + } + st_ivas->transport_config = IVAS_AUDIO_CONFIG_EXTERNAL + st_ivas->nchan_transport; + + st_ivas->ism_mode = ivas_ism_mode_select( st_ivas->nchan_transport, total_brate ); + st_ivas->nSCE = st_ivas->nchan_transport; + } + else if ( st_ivas->ivas_format == SBA_FORMAT ) + { + /* Read SBA planar flag and SBA order */ + st_ivas->sba_planar = ( bit_stream[IVAS_FORMAT_SIGNALING_NBITS_EXTENDED] == 1 ); + st_ivas->sba_order = ( bit_stream[IVAS_FORMAT_SIGNALING_NBITS_EXTENDED + 2] == 1 ); + st_ivas->sba_order += 2 * ( bit_stream[IVAS_FORMAT_SIGNALING_NBITS_EXTENDED + 1] == 1 ); + + st_ivas->sba_analysis_order = ivas_sba_get_analysis_order( total_brate, st_ivas->sba_order ); + + ivas_sba_config( total_brate, st_ivas->sba_analysis_order, -1, &( st_ivas->nchan_transport ), st_ivas->sba_planar, &( st_ivas->nSCE ), &( st_ivas->nCPE ), &( st_ivas->element_mode_init ) ); + } + else if ( st_ivas->ivas_format == SBA_ISM_FORMAT ) + { + /* read number of objects from the bitstream */ + if ( total_brate != SID_2k40 && total_brate != FRAME_NO_DATA ) + { + st_ivas->nchan_ism = 2 * bit_stream[total_brate / FRAMES_PER_SEC - 1] + bit_stream[total_brate / FRAMES_PER_SEC - 2] + 1; + st_ivas->ism_mode = ISM_SBA_MODE_DISC; + } + + /* Read SBA planar flag and SBA order */ + st_ivas->sba_planar = ( bit_stream[IVAS_FORMAT_SIGNALING_NBITS_EXTENDED + IVAS_COMBINED_FORMAT_SIGNALLING_BITS] == 1 ); + + if ( total_brate >= IVAS_256k ) + { + st_ivas->sba_order = ( bit_stream[IVAS_FORMAT_SIGNALING_NBITS_EXTENDED + IVAS_COMBINED_FORMAT_SIGNALLING_BITS + 2] == 1 ); + st_ivas->sba_order += 2 * ( bit_stream[IVAS_FORMAT_SIGNALING_NBITS_EXTENDED + IVAS_COMBINED_FORMAT_SIGNALLING_BITS + 1] == 1 ); + } + else + { + st_ivas->sba_order = 3; + } + + st_ivas->sba_analysis_order = ivas_sba_get_analysis_order( total_brate, st_ivas->sba_order ); + + ivas_sba_config( total_brate, st_ivas->sba_analysis_order, -1, &( st_ivas->nchan_transport ), st_ivas->sba_planar, &( st_ivas->nSCE ), &( st_ivas->nCPE ), &( st_ivas->element_mode_init ) ); + } + else if ( st_ivas->ivas_format == MASA_ISM_FORMAT ) + { + /* read number of objects from the bitstream */ + st_ivas->nchan_transport = 2; /* always 2 MASA transport channels */ + st_ivas->nchan_ism = 0; + + if ( total_brate != SID_2k40 && total_brate != FRAME_NO_DATA ) + { + st_ivas->nchan_ism = 2 * bit_stream[total_brate / FRAMES_PER_SEC - 1] + bit_stream[total_brate / FRAMES_PER_SEC - 2] + 1; + st_ivas->ism_mode = ivas_omasa_ism_mode_select( total_brate, st_ivas->nchan_ism ); + } + } + } + + st_ivas->hDecoderConfig->ivas_total_brate = total_brate; + + return error; +} +#endif /*-------------------------------------------------------------------* @@ -2093,7 +2804,20 @@ ivas_error read_indices( st_ivas->BER_detect = 0; sts = reset_elements( st_ivas ); +#ifdef DEBUGGING + file_read_FECpattern( &st_ivas->bfi ); + st_ivas->bfi |= bfi; + + if ( bfi == FRAMEMODE_MISSING ) + { + for ( k = 0; k < num_bits; k++ ) + { + bit_stream[k] = 0; + } + } +#else st_ivas->bfi = bfi; +#endif /* convert the frame length to total bitrate */ total_brate = (int32_t) ( num_bits * FRAMES_PER_SEC ); diff --git a/lib_com/calc_st_com.c b/lib_com/calc_st_com.c index 59ceb09da..2f2cc5633 100644 --- a/lib_com/calc_st_com.c +++ b/lib_com/calc_st_com.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "prot.h" diff --git a/lib_com/cb_shape.c b/lib_com/cb_shape.c index 77f17eb23..364ed639f 100644 --- a/lib_com/cb_shape.c +++ b/lib_com/cb_shape.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "prot.h" #include "wmc_auto.h" diff --git a/lib_com/cldfb.c b/lib_com/cldfb.c index 716dff7a3..1490703ae 100644 --- a/lib_com/cldfb.c +++ b/lib_com/cldfb.c @@ -37,6 +37,9 @@ #include #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "stat_dec.h" #include "prot.h" diff --git a/lib_com/cng_exc.c b/lib_com/cng_exc.c index 8fdc68921..9f0a22320 100644 --- a/lib_com/cng_exc.c +++ b/lib_com/cng_exc.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "prot.h" diff --git a/lib_com/cnst.h b/lib_com/cnst.h index 5bfffa4dd..0d604896c 100644 --- a/lib_com/cnst.h +++ b/lib_com/cnst.h @@ -76,6 +76,16 @@ #define DEC_IVAS 2 /* Index for IVAS decoder */ +#ifdef DEBUGGING +#define FORCE_SPEECH 100 /* debugging - force speech on the command line */ +#define FORCE_MUSIC 101 /* debugging - force music on the command line */ +#define FORCE_ACELP 102 /* debugging - force ACELP core on the command line */ +#define FORCE_GSC 103 /* debugging - force GSC core on the command line */ +#define FORCE_TCX 104 /* debugging - force TCX core on the command line */ +#define FORCE_HQ 105 /* debugging - force HQ core on the command line */ +#define FORCE_TD_RENDERER 201 +#define FORCE_CLDFB_RENDERER 202 +#endif enum{ NB = 0, /* Indicator of 4 kHz bandwidth */ diff --git a/lib_com/codec_tcx_common.c b/lib_com/codec_tcx_common.c index 2375ef387..7bb6dac40 100644 --- a/lib_com/codec_tcx_common.c +++ b/lib_com/codec_tcx_common.c @@ -38,6 +38,9 @@ #include "options.h" #include #include "prot.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" /*-------------------------------------------------------------------* diff --git a/lib_com/common_api_types.h b/lib_com/common_api_types.h index c4454fd62..4f1a452c6 100644 --- a/lib_com/common_api_types.h +++ b/lib_com/common_api_types.h @@ -147,6 +147,7 @@ typedef enum } IVAS_HEAD_ORIENT_TRK_T; +#ifdef NONBE_UNIFIED_DECODING_PATHS typedef enum { IVAS_RENDER_FRAMESIZE_UNKNOWN = 0, @@ -155,6 +156,7 @@ typedef enum IVAS_RENDER_FRAMESIZE_20MS = 4 } IVAS_RENDER_FRAMESIZE; +#endif typedef struct ivas_masa_metadata_frame_struct *IVAS_MASA_METADATA_HANDLE; typedef struct ivas_masa_decoder_ext_out_meta_struct *IVAS_MASA_DECODER_EXT_OUT_META_HANDLE; @@ -195,11 +197,98 @@ typedef struct _IVAS_JBM_TRACE_DATA } IVAS_JBM_TRACE_DATA; +#ifdef SPLIT_REND_WITH_HEAD_ROT +/*----------------------------------------------------------------------------------* + * Split rendering API constants, structures, and enums + *----------------------------------------------------------------------------------*/ + +#define IVAS_MAX_SPLIT_REND_BITRATE 768000 +#define IVAS_MAX_SPLIT_REND_BITS_BUFFER_SIZE_IN_BYTES ( ( ( (int32_t) IVAS_MAX_SPLIT_REND_BITRATE / IVAS_NUM_FRAMES_PER_SEC ) + 7 ) >> 3 ) +#define IVAS_SPLIT_REND_ADDITIONAL_BYTES_TO_READ 1 + +typedef enum +{ + DEFAULT_AXIS, + YAW, + PITCH, + ROLL, + YAW_PITCH, + YAW_ROLL, + PITCH_ROLL + +} IVAS_SPLIT_REND_ROT_AXIS; + +typedef enum +{ + IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE, + IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB, + +} IVAS_SPLIT_REND_POSE_CORRECTION_MODE; + +typedef enum +{ + IVAS_SPLIT_REND_CODEC_LCLD, + IVAS_SPLIT_REND_CODEC_LC3PLUS, + IVAS_SPLIT_REND_CODEC_DEFAULT, /* Will use LCLD for CLDFB rendering paths and LC3plus for TD rendering paths */ + IVAS_SPLIT_REND_CODEC_NONE + +} IVAS_SPLIT_REND_CODEC; + +typedef enum +{ + IVAS_SPLIT_REND_RENDERER_SELECTION_CREND, + IVAS_SPLIT_REND_RENDERER_SELECTION_FASTCONV, + IVAS_SPLIT_REND_RENDERER_SELECTION_PARAMBIN, + IVAS_SPLIT_REND_RENDERER_SELECTION_TDREND, + IVAS_SPLIT_REND_RENDERER_SELECTION_DEFAULT, + +} IVAS_SPLIT_REND_RENDERER_SELECTION; + +typedef struct _IVAS_SPLIT_REND_BITS_DATA +{ + uint8_t *bits_buf; + int32_t buf_len; /*size of bits_buf in bytes. This field should be set by allocator of bits_buf*/ + int32_t bits_written; + int32_t bits_read; + int16_t codec_frame_size_ms; + IVAS_SPLIT_REND_CODEC codec; + IVAS_SPLIT_REND_POSE_CORRECTION_MODE pose_correction; + +} IVAS_SPLIT_REND_BITS_DATA, *IVAS_SPLIT_REND_BITS_HANDLE; + +typedef struct _IVAS_SPLIT_REND_CONFIG +{ + int32_t splitRendBitRate; /*Bit rate for split rendering mode, if "pcm_out" is set then "splitRendBitRate" is used as a limit for MD bitrate */ + int16_t hq_mode; /*High quality 3DOF mode with additional side information. Requires more pre-renditions. */ + int16_t dof; /*flag to specify if pose correction is needed for 1, 2 or 3 degree of freedoms*/ + /*The axis can be set dynamically per frame based on a file input */ + /*possible values: + 1 - (1dof correction. By default YAW correction) + 2 - (2dof correction. By default YAW and PITCH correction) + 3 - (3dof correction. By default YAW, PITCH and ROLL correction) + */ + int16_t codec_delay_ms; /*PLACEHOLDER (currently being ignored) : look ahead delay of the codec that is used to code BIN signal output of pre-renderer*/ + int16_t codec_frame_size_ms; /*Codec frame size in milliseconds, only relevant with LC3plus */ + IVAS_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode; + IVAS_SPLIT_REND_CODEC codec; + IVAS_SPLIT_REND_RENDERER_SELECTION rendererSelection; + +} IVAS_SPLIT_REND_CONFIG_DATA; +#endif /*----------------------------------------------------------------------------------* * Renderer API structures and enums *----------------------------------------------------------------------------------*/ +#ifdef DEBUGGING +typedef enum +{ + IVAS_RENDER_TYPE_OVERRIDE_NONE, + IVAS_RENDER_TYPE_OVERRIDE_CREND, + IVAS_RENDER_TYPE_OVERRIDE_FASTCONV + +} IVAS_RENDER_TYPE_OVERRIDE; +#endif typedef struct _IVAS_ROOM_ACOUSTICS_CONFIG { @@ -222,7 +311,13 @@ typedef struct _IVAS_ROOM_ACOUSTICS_CONFIG typedef struct _IVAS_RENDER_CONFIG { +#ifdef DEBUGGING + IVAS_RENDER_TYPE_OVERRIDE renderer_type_override; +#endif IVAS_ROOM_ACOUSTICS_CONFIG_DATA roomAcoustics; +#ifdef SPLIT_REND_WITH_HEAD_ROT + IVAS_SPLIT_REND_CONFIG_DATA split_rend_config; +#endif float directivity[IVAS_MAX_NUM_OBJECTS * 3]; } IVAS_RENDER_CONFIG_DATA, *IVAS_RENDER_CONFIG_HANDLE; diff --git a/lib_com/core_com_config.c b/lib_com/core_com_config.c index 13fe05bbb..0ee9b40ae 100644 --- a/lib_com/core_com_config.c +++ b/lib_com/core_com_config.c @@ -37,6 +37,9 @@ #include #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "rom_com.h" #include "prot.h" #include "wmc_auto.h" diff --git a/lib_com/deemph.c b/lib_com/deemph.c index 26baccd04..9f4463d6a 100644 --- a/lib_com/deemph.c +++ b/lib_com/deemph.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "prot.h" #include "wmc_auto.h" diff --git a/lib_com/delay_comp.c b/lib_com/delay_comp.c index 66c81d440..9826da247 100644 --- a/lib_com/delay_comp.c +++ b/lib_com/delay_comp.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "prot.h" #include "ivas_cnst.h" #include "wmc_auto.h" @@ -51,7 +54,12 @@ int32_t get_delay( const int16_t enc_dec, /* i : encoder/decoder flag */ const int32_t io_fs, /* i : input/output sampling frequency */ const IVAS_FORMAT ivas_format, /* i : IVAS format */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + HANDLE_CLDFB_FILTER_BANK hCldfb, /* i : Handle of Cldfb analysis */ + const AUDIO_CONFIG output_config /* i : decoder output config */ +#else HANDLE_CLDFB_FILTER_BANK hCldfb /* i : Handle of Cldfb analysis */ +#endif ) { int32_t delay = 0; @@ -94,11 +102,18 @@ int32_t get_delay( { delay = IVAS_DEC_DELAY_NS; +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( output_config != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) + { +#endif if ( hCldfb != NULL ) { /* compensate for filterbank delay */ delay += IVAS_FB_DEC_DELAY_NS; } +#ifdef SPLIT_REND_WITH_HEAD_ROT + } +#endif if ( ivas_format == MASA_FORMAT || ivas_format == MASA_ISM_FORMAT ) { diff --git a/lib_com/disclaimer.c b/lib_com/disclaimer.c index f8af72f54..10a31d94c 100644 --- a/lib_com/disclaimer.c +++ b/lib_com/disclaimer.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "prot.h" #define WMC_TOOL_SKIP diff --git a/lib_com/dlpc_bfi.c b/lib_com/dlpc_bfi.c index ea701a3fe..b894b845f 100644 --- a/lib_com/dlpc_bfi.c +++ b/lib_com/dlpc_bfi.c @@ -37,6 +37,9 @@ #include #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "prot.h" #include "rom_com.h" #include "wmc_auto.h" diff --git a/lib_com/edct.c b/lib_com/edct.c index a265794f3..6f6d6c32b 100644 --- a/lib_com/edct.c +++ b/lib_com/edct.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "rom_com.h" #include "prot.h" @@ -98,6 +101,10 @@ static ivas_error get_edct_table( case 80: *edct_table = edct_table_40; break; +#ifdef DEBUGGING + default: + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "edct/edst(): length is not in table!" ); +#endif } return error; diff --git a/lib_com/enhancer.c b/lib_com/enhancer.c index 407588bc3..d0eeeb76c 100644 --- a/lib_com/enhancer.c +++ b/lib_com/enhancer.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "prot.h" diff --git a/lib_com/enr_1_az.c b/lib_com/enr_1_az.c index 800fa185c..2b66a14d7 100644 --- a/lib_com/enr_1_az.c +++ b/lib_com/enr_1_az.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "prot.h" #include "wmc_auto.h" diff --git a/lib_com/env_adj.c b/lib_com/env_adj.c index 459c40338..03b7d6cef 100644 --- a/lib_com/env_adj.c +++ b/lib_com/env_adj.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "rom_com.h" #include "prot.h" diff --git a/lib_com/env_stab.c b/lib_com/env_stab.c index ee07218f9..a1957566b 100644 --- a/lib_com/env_stab.c +++ b/lib_com/env_stab.c @@ -36,12 +36,18 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "prot.h" #include "rom_com.h" #include "wmc_auto.h" #include "stl.h" +#ifdef DEBUGGING +#include "assert.h" +#endif /*--------------------------------------------------------------------------* * Local constants @@ -102,6 +108,9 @@ float env_stability( mem_norm[i] = ynrm[i]; } +#ifdef DEBUGGING + assert( nb_sfm == 27 || nb_sfm == 26 ); +#endif inv_nb_sfm = 19418; /* Q19 */ if ( nb_sfm == 26 ) { diff --git a/lib_com/env_stab_trans.c b/lib_com/env_stab_trans.c index 1850ed48b..a2d4492b3 100644 --- a/lib_com/env_stab_trans.c +++ b/lib_com/env_stab_trans.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "prot.h" diff --git a/lib_com/est_tilt.c b/lib_com/est_tilt.c index 2f5b5bbac..8073e39df 100644 --- a/lib_com/est_tilt.c +++ b/lib_com/est_tilt.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "prot.h" #include "wmc_auto.h" diff --git a/lib_com/fd_cng_com.c b/lib_com/fd_cng_com.c index a6029e105..dd82c4f06 100644 --- a/lib_com/fd_cng_com.c +++ b/lib_com/fd_cng_com.c @@ -37,6 +37,9 @@ #include #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "prot.h" #include "rom_com.h" diff --git a/lib_com/fft.c b/lib_com/fft.c index e5607dcc3..a36712b8e 100644 --- a/lib_com/fft.c +++ b/lib_com/fft.c @@ -37,6 +37,9 @@ #include #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "prot.h" diff --git a/lib_com/fft_rel.c b/lib_com/fft_rel.c index e45736be8..46ee5e943 100644 --- a/lib_com/fft_rel.c +++ b/lib_com/fft_rel.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "prot.h" #include "rom_com.h" #include "wmc_auto.h" diff --git a/lib_com/fill_spectrum.c b/lib_com/fill_spectrum.c index 93d4cd572..669482487 100644 --- a/lib_com/fill_spectrum.c +++ b/lib_com/fill_spectrum.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "rom_com.h" #include "prot.h" diff --git a/lib_com/findpulse.c b/lib_com/findpulse.c index 3f8321160..3383397bc 100644 --- a/lib_com/findpulse.c +++ b/lib_com/findpulse.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "prot.h" #include "cnst.h" diff --git a/lib_com/fine_gain_bits.c b/lib_com/fine_gain_bits.c index 5e65b12e4..9f10bcd70 100644 --- a/lib_com/fine_gain_bits.c +++ b/lib_com/fine_gain_bits.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "rom_com.h" #include "prot.h" #include diff --git a/lib_com/frame_ener.c b/lib_com/frame_ener.c index 1592c6e9f..f44cb099c 100644 --- a/lib_com/frame_ener.c +++ b/lib_com/frame_ener.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "prot.h" diff --git a/lib_com/get_gain.c b/lib_com/get_gain.c index 94e23a1c6..e3457128f 100644 --- a/lib_com/get_gain.c +++ b/lib_com/get_gain.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "prot.h" #include "wmc_auto.h" diff --git a/lib_com/gs_bitallocation.c b/lib_com/gs_bitallocation.c index 8bbf1d21c..d099c2200 100644 --- a/lib_com/gs_bitallocation.c +++ b/lib_com/gs_bitallocation.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "rom_com.h" @@ -919,6 +922,9 @@ static float Find_bit_frac( else { inv_bandQ15 = (int16_t) ( ( 1.0f / nb_band ) * 32678 + 0.5f ); +#ifdef DEBUGGING + printf( "1/%d NOT DEFINED in Find_bit_frac\n", nb_band ); +#endif } L_num = inv_bandQ15 * remaining_bits; diff --git a/lib_com/gs_gains.c b/lib_com/gs_gains.c index 72b1ccf35..40626468b 100644 --- a/lib_com/gs_gains.c +++ b/lib_com/gs_gains.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "rom_com.h" diff --git a/lib_com/gs_inact_switching.c b/lib_com/gs_inact_switching.c index 04ad8a3eb..cd380e86e 100644 --- a/lib_com/gs_inact_switching.c +++ b/lib_com/gs_inact_switching.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "rom_com.h" diff --git a/lib_com/gs_noisefill.c b/lib_com/gs_noisefill.c index f452dab7a..a92aec075 100644 --- a/lib_com/gs_noisefill.c +++ b/lib_com/gs_noisefill.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "rom_com.h" diff --git a/lib_com/gs_preech.c b/lib_com/gs_preech.c index ae2bbf6f5..5a98f4093 100644 --- a/lib_com/gs_preech.c +++ b/lib_com/gs_preech.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "rom_com.h" diff --git a/lib_com/hp50.c b/lib_com/hp50.c index b9268c8f9..3624fabb4 100644 --- a/lib_com/hp50.c +++ b/lib_com/hp50.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "prot.h" #include "wmc_auto.h" diff --git a/lib_com/hq2_bit_alloc.c b/lib_com/hq2_bit_alloc.c index d471b170e..34c37babd 100644 --- a/lib_com/hq2_bit_alloc.c +++ b/lib_com/hq2_bit_alloc.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "prot.h" #include "rom_com.h" diff --git a/lib_com/hq2_core_com.c b/lib_com/hq2_core_com.c index 280d492ae..22a596a75 100644 --- a/lib_com/hq2_core_com.c +++ b/lib_com/hq2_core_com.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "rom_com.h" diff --git a/lib_com/hq2_noise_inject.c b/lib_com/hq2_noise_inject.c index ed48dab7b..0404056dd 100644 --- a/lib_com/hq2_noise_inject.c +++ b/lib_com/hq2_noise_inject.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "prot.h" #include "wmc_auto.h" diff --git a/lib_com/hq_bit_allocation.c b/lib_com/hq_bit_allocation.c index 7556ed505..faba9f8da 100644 --- a/lib_com/hq_bit_allocation.c +++ b/lib_com/hq_bit_allocation.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "prot.h" #include "rom_com.h" diff --git a/lib_com/hq_conf.c b/lib_com/hq_conf.c index d0f793921..ac9298159 100644 --- a/lib_com/hq_conf.c +++ b/lib_com/hq_conf.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "rom_com.h" #include "prot.h" diff --git a/lib_com/hq_tools.c b/lib_com/hq_tools.c index df59ac172..4ad78fc90 100644 --- a/lib_com/hq_tools.c +++ b/lib_com/hq_tools.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "prot.h" #include "rom_com.h" diff --git a/lib_com/hvq_pvq_bitalloc.c b/lib_com/hvq_pvq_bitalloc.c index 5ff0d3344..2808030ae 100644 --- a/lib_com/hvq_pvq_bitalloc.c +++ b/lib_com/hvq_pvq_bitalloc.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "prot.h" #include "rom_com.h" diff --git a/lib_com/ifft_rel.c b/lib_com/ifft_rel.c index 597a5d173..28334b06d 100644 --- a/lib_com/ifft_rel.c +++ b/lib_com/ifft_rel.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "prot.h" #include "rom_com.h" #include "wmc_auto.h" diff --git a/lib_com/igf_base.c b/lib_com/igf_base.c index 73f7228d0..ac1965100 100644 --- a/lib_com/igf_base.c +++ b/lib_com/igf_base.c @@ -37,6 +37,9 @@ #include #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "prot.h" #include "rom_com.h" #include "wmc_auto.h" diff --git a/lib_com/index_pvq_opt.c b/lib_com/index_pvq_opt.c index b14fd8fa3..097732442 100644 --- a/lib_com/index_pvq_opt.c +++ b/lib_com/index_pvq_opt.c @@ -37,6 +37,9 @@ #include #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "rom_com.h" diff --git a/lib_com/int_lsp.c b/lib_com/int_lsp.c index 448a97e33..ff1c9cace 100644 --- a/lib_com/int_lsp.c +++ b/lib_com/int_lsp.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "prot.h" #include "rom_com.h" diff --git a/lib_com/interleave_spectrum.c b/lib_com/interleave_spectrum.c index 300295355..6046bf8f2 100644 --- a/lib_com/interleave_spectrum.c +++ b/lib_com/interleave_spectrum.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "prot.h" #include "rom_com.h" diff --git a/lib_com/interpol.c b/lib_com/interpol.c index 332f34d54..4172c4acf 100644 --- a/lib_com/interpol.c +++ b/lib_com/interpol.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "prot.h" #include "wmc_auto.h" diff --git a/lib_com/isf_dec_amr_wb.c b/lib_com/isf_dec_amr_wb.c index 49afd071f..d51731d1c 100644 --- a/lib_com/isf_dec_amr_wb.c +++ b/lib_com/isf_dec_amr_wb.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "rom_com.h" #include "prot.h" diff --git a/lib_com/ivas_agc_com.c b/lib_com/ivas_agc_com.c index 3bb4bdea2..e39b8df82 100644 --- a/lib_com/ivas_agc_com.c +++ b/lib_com/ivas_agc_com.c @@ -35,6 +35,9 @@ #include "cnst.h" #include "ivas_cnst.h" #include "ivas_prot.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "wmc_auto.h" #include "prot.h" @@ -110,3 +113,24 @@ void ivas_agc_calcGainParams( return; } +#ifdef DEBUG_AGC +/*-----------------------------------------------------------------------------------------* + * Function ivas_agc_debug_inout() + * + * + *-----------------------------------------------------------------------------------------*/ +int16_t ivas_agc_debug_inout( FILE *inStream, float **in, int16_t n_channels, int16_t frame_len ) +{ + if ( inStream == NULL ) + { + return TRUE; + } + + for ( int16_t i = 0; i < n_channels; i++ ) + { + fwrite( &in[i][0], sizeof( float ), frame_len, inStream ); + } + + return FALSE; +} +#endif diff --git a/lib_com/ivas_arith.c b/lib_com/ivas_arith.c index 98243b0f4..0957d4ae5 100644 --- a/lib_com/ivas_arith.c +++ b/lib_com/ivas_arith.c @@ -32,6 +32,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" #include "prot.h" #include "ivas_prot.h" diff --git a/lib_com/ivas_avq_pos_reorder_com.c b/lib_com/ivas_avq_pos_reorder_com.c index 015a3988f..c75d20533 100644 --- a/lib_com/ivas_avq_pos_reorder_com.c +++ b/lib_com/ivas_avq_pos_reorder_com.c @@ -32,6 +32,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "prot.h" #include "wmc_auto.h" diff --git a/lib_com/ivas_cnst.h b/lib_com/ivas_cnst.h index 6a50483e5..95008d17f 100644 --- a/lib_com/ivas_cnst.h +++ b/lib_com/ivas_cnst.h @@ -121,6 +121,14 @@ typedef enum RENDERER_OSBA_LS } RENDERER_TYPE; +#ifdef SPLIT_REND_WITH_HEAD_ROT +typedef enum +{ + PCM_INT16, + PCM_FLOAT32, + PCM_NOT_KNOW = 0xffff +} PCM_RESOLUTION; +#endif /*----------------------------------------------------------------------------------* * IVAS general constants @@ -460,6 +468,9 @@ enum #define STEREO_DFT32MS_OVL_NS 3125000L /* 3.125ms - Overlap for the outer edges of windows on decoder */ #define STEREO_DFT32MS_OVL2_NS 9375000L /* 9.375ms - Overlap for the inner edges of windows on decoder */ #define STEREO_DFT32MS_WIN_CENTER_NS ( int32_t )( ( FRAME_SIZE_NS + STEREO_DFT32MS_OVL_NS ) * 0.5f ) /* 11.5625ms - mid point of the two windows wrt the left edge of overlap */ +#if defined( DEBUG_MODE_DFT ) || defined( DEBUG_STEREO_DFT_NOCORE ) +#define STEREO_DFT32MS_HOP_NS 10000000L /* 10ms */ +#endif #define STEREO_DFT32MS_ZP_NS ( int32_t )( 0.5f * ( STEREO_DFT32MS_N_NS - STEREO_DFT32MS_WIN_CENTER_NS - ( STEREO_DFT32MS_OVL2_NS * 0.5f ) ) ) /* 2 sided zp calculated such that window size is satisfied */ #define STEREO_DFT32MS_OVL_MAX NS2SA( 48000, STEREO_DFT32MS_OVL_NS ) @@ -804,6 +815,10 @@ enum fea_names /* MDCT stereo modes */ #define SMDCT_MS_DECISION 0 +#ifdef DEBUG_FORCE_MDCT_STEREO_MODE +#define SMDCT_FORCE_LR 1 +#define SMDCT_FORCE_MS 2 +#endif #define MAX_SFB 70 /* Maximum number of stereo frequency bands = 64 + 6 for TCX after ACELP */ @@ -1320,26 +1335,49 @@ typedef struct { unsigned short length[81]; } HUFF_ELEMENTS; +#ifdef FIX_891_PARAMUPMIX_CLEANUP +typedef struct { + HUFF_ELEMENTS df0; + HUFF_ELEMENTS df; +} HUFF_TABLE; +#else typedef struct { HUFF_ELEMENTS df0; HUFF_ELEMENTS df; + HUFF_ELEMENTS dt; } HUFF_TABLE; +#endif typedef enum { ALPHA, BETA } PAR_TYPE; +#ifndef FIX_891_PARAMUPMIX_CLEANUP +typedef enum { + FINE, + COARSE +} QUANT_TYPE; + +#endif typedef struct { int16_t nquant; int16_t offset; float data[35]; } ACPL_QUANT_TABLE; +#ifdef FIX_891_PARAMUPMIX_CLEANUP typedef struct { const int16_t (*alpha)[2]; const int16_t (*beta)[2]; } HUFF_NODE_TABLE; +#else +typedef struct +{ + const int16_t (*alpha[2])[2]; + const int16_t (*beta[2])[2]; +} HUFF_NODE_TABLE; +#endif /*----------------------------------------------------------------------------------* * Parametric MC Constants @@ -1458,6 +1496,18 @@ typedef enum EFAP_DMX_INTENSITY } EFAP_VTX_DMX_TYPE; +#ifdef SPLIT_REND_WITH_HEAD_ROT +typedef enum +{ + ANY_YAW, + PITCH_ONLY, + ANY_ROLL, + PRED_ONLY, + PRED_ROLL_ONLY, + COM_GAIN_ONLY, + LR_GAIN_ONLY +} IVAS_SPLIT_REND_POSE_TYPE; +#endif #define VBAP_NUM_SEARCH_SECTORS 4 @@ -1500,6 +1550,63 @@ typedef enum #define HEADROT_SHMAT_DIM2 ( HEADROT_SHMAT_DIM * HEADROT_SHMAT_DIM ) +#ifdef SPLIT_REND_WITH_HEAD_ROT +/*----------------------------------------------------------------------------------* + * Split Binaural Rendering Constants + *----------------------------------------------------------------------------------*/ + +#ifdef SPLIT_REND_WITH_HEAD_ROT +#define CLDFB_PLC_XF 2 /* Length of cross-fade into first good frame after frame loss in CLDFB cols. */ +#endif + +#define SPLIT_REND_DECOR_ALPHA 0.25f + +#define SPLIT_REND_MAX_YAW_ONLY_POSES 2 +#define SPLIT_REND_MAX_PITCH_ONLY_POSES 2 +#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 SPLIT_REND_MAX_DOF 3 + +#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 +#define MAX_SPLIT_MD_SUBFRAMES 1 +#define COMPLEX_MD_BAND_THRESH MAX_SPLIT_REND_MD_BANDS +#define COMPLEX_MD_BAND_THRESH_LOW 5 + +#define IVAS_SPLIT_REND_NUM_QUANT_STRATS 4 +#define IVAS_SPLIT_REND_PRED_63QUANT_PNTS 63 +#define IVAS_SPLIT_REND_PRED_31QUANT_PNTS 31 +#define IVAS_SPLIT_REND_ROLL_PRED_QUANT_PNTS 31 +#define IVAS_SPLIT_REND_D_QUANT_PNTS 15 +#define IVAS_SPLIT_REND_PRED_MIN_VAL -1.4f +#define IVAS_SPLIT_REND_PRED_MAX_VAL 1.4f + +#define IVAS_SPLIT_REND_PITCH_G_MIN_VAL 0.5f +#define IVAS_SPLIT_REND_PITCH_G_MAX_VAL 1.5f +#define IVAS_SPLIT_REND_PITCH_G_QUANT_PNTS IVAS_SPLIT_REND_D_QUANT_PNTS +#define IVAS_SPLIT_REND_D_MIN_VAL 0.0f +#define IVAS_SPLIT_REND_D_MAX_VAL 1.0f + +#define IVAS_SPLIT_REND_PRED_ROLL_Q_STEP (( IVAS_SPLIT_REND_PRED_MAX_VAL - IVAS_SPLIT_REND_PRED_MIN_VAL ) / ( IVAS_SPLIT_REND_ROLL_PRED_QUANT_PNTS - 1 )) +#define IVAS_SPLIT_REND_PRED_ROLL_1BYQ_STEP (( IVAS_SPLIT_REND_ROLL_PRED_QUANT_PNTS - 1 )/( IVAS_SPLIT_REND_PRED_MAX_VAL - IVAS_SPLIT_REND_PRED_MIN_VAL )) +#define IVAS_SPLIT_REND_PRED31_Q_STEP (( IVAS_SPLIT_REND_PRED_MAX_VAL - IVAS_SPLIT_REND_PRED_MIN_VAL ) / ( IVAS_SPLIT_REND_PRED_31QUANT_PNTS - 1 )) +#define IVAS_SPLIT_REND_PRED31_1BYQ_STEP (( IVAS_SPLIT_REND_PRED_31QUANT_PNTS - 1 )/( IVAS_SPLIT_REND_PRED_MAX_VAL - IVAS_SPLIT_REND_PRED_MIN_VAL )) +#define IVAS_SPLIT_REND_PRED63_Q_STEP (( IVAS_SPLIT_REND_PRED_MAX_VAL - IVAS_SPLIT_REND_PRED_MIN_VAL ) / ( IVAS_SPLIT_REND_PRED_63QUANT_PNTS - 1 )) +#define IVAS_SPLIT_REND_PRED63_1BYQ_STEP (( IVAS_SPLIT_REND_PRED_63QUANT_PNTS - 1 )/( IVAS_SPLIT_REND_PRED_MAX_VAL - IVAS_SPLIT_REND_PRED_MIN_VAL )) + +#define IVAS_SPLIT_REND_D_Q_STEP (( IVAS_SPLIT_REND_D_MAX_VAL - IVAS_SPLIT_REND_D_MIN_VAL ) / ( IVAS_SPLIT_REND_D_QUANT_PNTS - 1 )) +#define IVAS_SPLIT_REND_D_1BYQ_STEP (( IVAS_SPLIT_REND_D_QUANT_PNTS - 1 )/( IVAS_SPLIT_REND_D_MAX_VAL - IVAS_SPLIT_REND_D_MIN_VAL )) +#define IVAS_SPLIT_REND_PITCH_G_Q_STEP (( IVAS_SPLIT_REND_PITCH_G_MAX_VAL - IVAS_SPLIT_REND_PITCH_G_MIN_VAL ) / ( IVAS_SPLIT_REND_PITCH_G_QUANT_PNTS - 1 )) +#define IVAS_SPLIT_REND_PITCH_G_1BYQ_STEP (( IVAS_SPLIT_REND_PITCH_G_QUANT_PNTS - 1 )/( IVAS_SPLIT_REND_PITCH_G_MAX_VAL - IVAS_SPLIT_REND_PITCH_G_MIN_VAL )) + +#define IVAS_SPLIT_REND_MAX_NUM_BYTES 4000 +#define IVAS_SPLIT_REND_HEAD_POSE_BITS 9 +#define IVAS_SPLIT_REND_DOF_BITS 2 +#define IVAS_SPLIT_REND_HQ_MODE_BITS 1 +#define IVAS_SPLIT_REND_ROT_AXIS_BITS 3 +#endif /*----------------------------------------------------------------------------------* @@ -1704,6 +1811,19 @@ typedef enum #define QUANT_STRAT_0 0 #define QUANT_STRAT_2 2 +#ifdef SPLIT_REND_WITH_HEAD_ROT +/*----------------------------------------------------------------------------------* + * Split rendering bitrate constants + *----------------------------------------------------------------------------------*/ + +#define SPLIT_REND_256k 256000 +#define SPLIT_REND_320k 320000 +#define SPLIT_REND_384k 384000 +#define SPLIT_REND_512k 512000 +#define SPLIT_REND_768k 768000 +#define SPLIT_REND_MAX_BRATE SPLIT_REND_768k + +#endif /*----------------------------------------------------------------------------------* * Limiter constants diff --git a/lib_com/ivas_cov_smooth.c b/lib_com/ivas_cov_smooth.c index f15b21d79..54d0d5f8d 100644 --- a/lib_com/ivas_cov_smooth.c +++ b/lib_com/ivas_cov_smooth.c @@ -32,6 +32,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "ivas_prot.h" #include "wmc_auto.h" diff --git a/lib_com/ivas_dirac_com.c b/lib_com/ivas_dirac_com.c index a490858c8..bcf502033 100644 --- a/lib_com/ivas_dirac_com.c +++ b/lib_com/ivas_dirac_com.c @@ -163,8 +163,10 @@ ivas_error ivas_dirac_config( if ( ivas_format == SBA_FORMAT || ivas_format == SBA_ISM_FORMAT ) /* skip for MASA decoder */ { if ( ( error = ivas_dirac_sba_config( hQMetaData, element_mode, ivas_total_brate, sba_order, hConfig->nbands - spar_dirac_split_band +#ifdef NONBE_FIX_871_ACELP_CRASH_IN_OSBA , ivas_format +#endif ) ) != IVAS_ERR_OK ) { return error; @@ -323,8 +325,10 @@ void ivas_get_dirac_sba_max_md_bits( int16_t *metadata_max_bits, int16_t *qmetadata_max_bit_req, const int16_t nbands +#ifdef NONBE_FIX_871_ACELP_CRASH_IN_OSBA , IVAS_FORMAT ivas_format +#endif ) { if ( sba_total_brate <= IVAS_13k2 ) @@ -341,11 +345,13 @@ void ivas_get_dirac_sba_max_md_bits( { *bits_frame_nominal = ACELP_16k40 / FRAMES_PER_SEC; *metadata_max_bits = 103; +#ifdef NONBE_FIX_871_ACELP_CRASH_IN_OSBA /* OSBA needs an additional 2-bits safety margin to avoid acelp crashes */ if ( ivas_format == SBA_ISM_FORMAT ) { ( *metadata_max_bits ) -= 3; } +#endif } else if ( sba_total_brate <= IVAS_32k ) { @@ -401,8 +407,10 @@ ivas_error ivas_dirac_sba_config( int32_t sba_total_brate, /* i : SBA total bitrate */ const int16_t sba_order, /* i : Ambisonic (SBA) order */ const int16_t nbands /* i : number of frequency bands */ +#ifdef NONBE_FIX_871_ACELP_CRASH_IN_OSBA , IVAS_FORMAT ivas_format +#endif ) { int16_t nbands_coded; @@ -466,8 +474,10 @@ ivas_error ivas_dirac_sba_config( } ivas_get_dirac_sba_max_md_bits( sba_total_brate, &hQMetaData->bits_frame_nominal, &hQMetaData->metadata_max_bits, &hQMetaData->qmetadata_max_bit_req, hQMetaData->q_direction[0].cfg.nbands +#ifdef NONBE_FIX_871_ACELP_CRASH_IN_OSBA , ivas_format +#endif ); return error; diff --git a/lib_com/ivas_entropy_coder_common.c b/lib_com/ivas_entropy_coder_common.c index 7696932cb..a2fa26cad 100644 --- a/lib_com/ivas_entropy_coder_common.c +++ b/lib_com/ivas_entropy_coder_common.c @@ -32,6 +32,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "ivas_prot.h" #include "ivas_rom_com.h" #include "math.h" diff --git a/lib_com/ivas_error.h b/lib_com/ivas_error.h index fbb18cf9f..ff803803f 100644 --- a/lib_com/ivas_error.h +++ b/lib_com/ivas_error.h @@ -89,6 +89,15 @@ typedef enum IVAS_ERR_IO_CONFIG_PAIR_NOT_SUPPORTED, IVAS_ERR_TSM_NOT_ENABLED, IVAS_ERR_FETCH_SIZE_NO_MULTIPLE_OF_5MS, +#ifdef DEBUGGING + IVAS_ERR_INVALID_FORCE_MODE, +#ifdef DEBUG_AGC_ENCODER_CMD_OPTION + IVAS_ERR_INVALID_AGC, +#endif +#ifdef VARIABLE_SPEED_DECODING + IVAS_ERR_VS_FRAME_NEEDED, +#endif +#endif /*----------------------------------------* * input data errors * @@ -132,6 +141,10 @@ typedef enum IVAS_ERR_ACOUSTIC_ENVIRONMENT_MISSING, IVAS_ERR_INVALID_ER_PARAM, IVAS_ERR_DIRECTIVITY_PATTERN_ID_MISSING, +#ifdef SPLIT_REND_WITH_HEAD_ROT + IVAS_ERR_LC3PLUS_INVALID_BITRATE, + IVAS_ERR_INVALID_SPLIT_REND_CONFIG, +#endif /*----------------------------------------* * unknown error * @@ -210,6 +223,10 @@ static inline const char *ivas_error_to_string( ivas_error error_code ) return "Unexpected NULL pointer"; case IVAS_ERR_METADATA_NOT_EXPECTED: return "Metadata input not expected for current configuration"; +#ifdef DEBUGGING + case IVAS_ERR_INVALID_FORCE_MODE: + return "Invalid force mode"; +#endif case IVAS_ERR_NOT_IMPLEMENTED: return "Not implemented"; case IVAS_ERR_ISM_FILE_READER_INVALID_METADATA_FORMAT: @@ -226,6 +243,12 @@ static inline const char *ivas_error_to_string( ivas_error error_code ) return "Wrong mode"; case IVAS_ERR_HEAD_ROTATION_NOT_SUPPORTED: return "Head rotation not supported"; +#ifdef SPLIT_REND_WITH_HEAD_ROT + case IVAS_ERR_LC3PLUS_INVALID_BITRATE: + return "Specified split rendering bit rate is not supported"; + case IVAS_ERR_INVALID_SPLIT_REND_CONFIG: + return "Specified split rendering configuration is invalid"; +#endif case IVAS_ERR_EXT_ORIENTATION_NOT_SUPPORTED: return "External orientation not supported"; case IVAS_ERR_DIRECTIVITY_NOT_SUPPORTED: diff --git a/lib_com/ivas_error_utils.h b/lib_com/ivas_error_utils.h index 204acc40e..b9a6b3f87 100644 --- a/lib_com/ivas_error_utils.h +++ b/lib_com/ivas_error_utils.h @@ -38,6 +38,9 @@ #include "ivas_error.h" +#ifdef DEBUGGING +#include +#endif #ifndef IVAS_ERROR_UTILS_H #define IVAS_ERROR_UTILS_H @@ -63,11 +66,32 @@ * If unexpected values are printed or the macro causes a crash, double check that the * format specifiers are correct. */ +#ifdef DEBUGGING +#define IVAS_ERROR( error_code, ... ) ivas_error_wrapper( error_code, __func__, __FILE__, __LINE__, __VA_ARGS__ ) +#else #define IVAS_ERROR( error_code, ... ) ivas_error_wrapper( error_code ) +#endif +#ifdef DEBUGGING +static inline ivas_error ivas_error_wrapper( const ivas_error error_code, const char *function, const char *file, int32_t line, const char *description, ... ) +{ + fprintf( stderr, "\n%s: ", ivas_error_to_string( error_code ) ); + + va_list args; + va_start( args, description ); + vfprintf( stderr, description, args ); + va_end( args ); + + fprintf( stderr, "\n\nIn function: %s(), %s:%d\n\n", function, file, line ); + // assert( 0 ); + + return error_code; +} +#else static inline ivas_error ivas_error_wrapper( const ivas_error error_code ) { return error_code; } +#endif #endif /* IVAS_ERROR_UTILS_H */ diff --git a/lib_com/ivas_fb_mixer.c b/lib_com/ivas_fb_mixer.c index f914d4e75..9772f2e8d 100644 --- a/lib_com/ivas_fb_mixer.c +++ b/lib_com/ivas_fb_mixer.c @@ -32,6 +32,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "prot.h" #include "ivas_prot.h" diff --git a/lib_com/ivas_filters.c b/lib_com/ivas_filters.c index 8344fe33f..579e9d17c 100644 --- a/lib_com/ivas_filters.c +++ b/lib_com/ivas_filters.c @@ -32,6 +32,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "ivas_prot.h" #include "ivas_cnst.h" #include "ivas_stat_com.h" diff --git a/lib_com/ivas_ism_com.c b/lib_com/ivas_ism_com.c index d8cb958cc..3ec4656a9 100644 --- a/lib_com/ivas_ism_com.c +++ b/lib_com/ivas_ism_com.c @@ -39,6 +39,9 @@ #include "ivas_prot.h" #include "ivas_stat_com.h" #include "ivas_rom_com.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" @@ -338,6 +341,12 @@ ivas_error ivas_ism_config( else { bits_CoreCoder[ch] += diff; +#ifdef DEBUGGING + if ( bits_CoreCoder[ch] == SID_2k40 / FRAMES_PER_SEC ) + { + printf( "\nWarning: ISM bitbudget equal to SID!\n" ); + } +#endif if ( combined_format_flag ) { @@ -375,6 +384,17 @@ ivas_error ivas_ism_config( bitbudget_to_brate( bits_CoreCoder, total_brate, n_ISms ); } +#ifdef DEBUGGING + if ( nb_bits_metadata != NULL ) + { + int32_t tmpL; + tmpL = sum_l( total_brate, n_ISms ) + bits_side * FRAMES_PER_SEC; + if ( ism_total_brate != tmpL ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "\nError: Mismatch in ISM bit-budget distribution. Exiting!\n" ); + } + } +#endif return error; } diff --git a/lib_com/ivas_lfe_com.c b/lib_com/ivas_lfe_com.c index 6b323a13c..45dcae7c0 100644 --- a/lib_com/ivas_lfe_com.c +++ b/lib_com/ivas_lfe_com.c @@ -33,6 +33,9 @@ #include #include "math.h" #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "ivas_stat_com.h" #include "prot.h" #include "ivas_prot.h" diff --git a/lib_com/ivas_masa_com.c b/lib_com/ivas_masa_com.c index abb4dbd55..17e4b4773 100644 --- a/lib_com/ivas_masa_com.c +++ b/lib_com/ivas_masa_com.c @@ -39,6 +39,9 @@ #include "ivas_prot.h" #include "ivas_rom_com.h" #include "ivas_stat_dec.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" /*--------------------------------------------------------------- @@ -290,6 +293,9 @@ void ivas_masa_set_coding_config( config->numCodingBands = nbands; config->numTwoDirBands = nTwoDirBands; +#ifdef DEBUGGING + assert( nbands > 0 ); +#endif if ( config->joinedSubframes == TRUE ) { config->mergeRatiosOverSubframes = FALSE; diff --git a/lib_com/ivas_mc_com.c b/lib_com/ivas_mc_com.c index 664dd3a70..966fd21a5 100644 --- a/lib_com/ivas_mc_com.c +++ b/lib_com/ivas_mc_com.c @@ -33,6 +33,9 @@ #include #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "prot.h" #include "ivas_prot.h" diff --git a/lib_com/ivas_mc_param_com.c b/lib_com/ivas_mc_param_com.c index e81605270..44efdebe2 100644 --- a/lib_com/ivas_mc_param_com.c +++ b/lib_com/ivas_mc_param_com.c @@ -39,6 +39,9 @@ #include "ivas_prot.h" #include "ivas_stat_com.h" #include "ivas_rom_com.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" @@ -69,6 +72,9 @@ uint16_t ivas_param_mc_get_configuration_index( return cur_idx; } } +#ifdef DEBUGGING + assert( 0 && "No Parametric MC configuration for this bitrate/channel setup!" ); +#endif return PARAM_MC_NUM_CONFIGS; } diff --git a/lib_com/ivas_mcmasa_com.c b/lib_com/ivas_mcmasa_com.c index 341964319..7e81e1fd1 100644 --- a/lib_com/ivas_mcmasa_com.c +++ b/lib_com/ivas_mcmasa_com.c @@ -33,6 +33,9 @@ #include "ivas_cnst.h" #include "ivas_prot.h" #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" diff --git a/lib_com/ivas_mdct_imdct.c b/lib_com/ivas_mdct_imdct.c index 656788717..5dcd850c2 100644 --- a/lib_com/ivas_mdct_imdct.c +++ b/lib_com/ivas_mdct_imdct.c @@ -35,6 +35,9 @@ #include "prot.h" #include "ivas_prot.h" #include "ivas_rom_com.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "ivas_stat_com.h" #include "wmc_auto.h" diff --git a/lib_com/ivas_mdft_imdft.c b/lib_com/ivas_mdft_imdft.c index 73a732316..0b03f63d9 100644 --- a/lib_com/ivas_mdft_imdft.c +++ b/lib_com/ivas_mdft_imdft.c @@ -34,6 +34,9 @@ #include "options.h" #include "prot.h" #include "ivas_prot.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "ivas_rom_com.h" #include #include "wmc_auto.h" diff --git a/lib_com/ivas_omasa_com.c b/lib_com/ivas_omasa_com.c index 31874a7b5..7416dad11 100644 --- a/lib_com/ivas_omasa_com.c +++ b/lib_com/ivas_omasa_com.c @@ -37,6 +37,9 @@ #include "prot.h" #include "ivas_rom_com.h" #include +#ifdef DEBUGGING +#include "debug.h" +#endif /*--------------------------------------------------------------- * Local constants diff --git a/lib_com/ivas_pca_tools.c b/lib_com/ivas_pca_tools.c index a9dcffd1e..a1f8efd62 100644 --- a/lib_com/ivas_pca_tools.c +++ b/lib_com/ivas_pca_tools.c @@ -34,6 +34,9 @@ #include "options.h" #include "ivas_prot.h" #include "ivas_cnst.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include #include "ivas_rom_com.h" diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index 68f3a9de6..cdd5a6bfd 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -312,13 +312,23 @@ void stereo_dmx_evs_close_encoder( ivas_error ivas_dec( Decoder_Struct *st_ivas, /* i : IVAS decoder structure */ +#if( defined SPLIT_REND_WITH_HEAD_ROT && !defined NONBE_UNIFIED_DECODING_PATHS_FIX ) + const PCM_RESOLUTION pcm_resolution, /* i : type for the decoded PCM resolution */ + void *data /* o : output synthesis signal */ +#else int16_t *data /* o : output synthesis signal */ +#endif ); ivas_error ivas_dec_setup( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ uint16_t *nSamplesRendered, /* o : number of samples flushed from the previous frame (JBM) */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + const PCM_RESOLUTION pcm_resolution, /* i : type for the decoded PCM resolution */ + void *data /* o : output synthesis signal */ +#else int16_t *data /* o : output synthesis signal */ +#endif ); ivas_error create_sce_dec( @@ -658,7 +668,12 @@ ivas_error ivas_mc_dec_config( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ const int16_t idx, /* i : LS config. index */ uint16_t *nSamplesRendered, /* o : samples flushed from last frame (JBM) */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + const PCM_RESOLUTION pcm_resolution, /* i : type for the decoded PCM resolution */ + void *data /* o : output synthesis signal */ +#else int16_t *data /* o : output synthesis signal */ +#endif ); /*! r: MC format mode (MCT, McMASA, ParamMC) */ @@ -688,6 +703,14 @@ void smooth_dft2td_transition( const int16_t output_frame /* i : output frame length */ ); +#ifdef DEBUG_MODE_INFO +void output_debug_mode_info_dec( + Decoder_State **sts, + const int16_t n_channels, + const int16_t output_frame, + float pitch_buf[CPE_CHANNELS][NB_SUBFR16k] +); +#endif /*! r: flag indicating a valid bitrate */ int16_t is_IVAS_bitrate( @@ -771,7 +794,12 @@ ivas_error ivas_jbm_dec_render( const uint16_t nSamplesAsked, /* i : number of samples wanted */ uint16_t *nSamplesRendered, /* o : number of samples rendered */ uint16_t *nSamplesAvailableNext, /* o : number of samples still available in the rendering pipeline */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + const PCM_RESOLUTION pcm_resolution, /* i : type for the decoded PCM resolution */ + void *data /* o : output synthesis signal */ +#else int16_t *data /* o : output synthesis signal */ +#endif ); ivas_error ivas_jbm_dec_flush_renderer( @@ -783,7 +811,12 @@ ivas_error ivas_jbm_dec_flush_renderer( const MC_MODE mc_mode_old, /* i : old MC mode */ const ISM_MODE ism_mode_old, /* i : old ISM mode */ uint16_t *nSamplesRendered, /* o : number of samples flushed */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + const PCM_RESOLUTION pcm_resolution, /* i : type for the decoded PCM resolution */ + void *data /* o : output synthesis signal */ +#else int16_t *data /* o : output synthesis signal */ +#endif ); void ivas_jbm_dec_feed_tc_to_renderer( @@ -1048,7 +1081,12 @@ ivas_error ivas_ism_dec_config( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ const ISM_MODE last_ism_mode, /* i/o: last ISM mode */ uint16_t *nSamplesRendered, /* o : number of samples flushed on renderer change*/ +#ifdef SPLIT_REND_WITH_HEAD_ROT + const PCM_RESOLUTION pcm_resolution, /* i : type for the decoded PCM resolution */ + void *data /* o : output synthesis signal */ +#else int16_t *data /* o : output synthesis signal */ +#endif ); ivas_error ivas_param_ism_dec_open( @@ -1117,7 +1155,11 @@ int16_t ivas_ism_dtx_enc( int16_t *sid_flag /* o : indication of SID frame */ ); +#ifdef NONBE_FIX_898_ISM_BRATE_CRASH void ivas_ism_dtx_dec( +#else +ivas_error ivas_ism_dtx_dec( +#endif Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ int16_t *nb_bits_metadata /* o : number of metadata bits */ ); @@ -1413,7 +1455,11 @@ int16_t stereo_dft_sg_recovery( void stereo_dft_dec_res( CPE_DEC_HANDLE hCPE, /* i/o: decoder CPE handle */ +#ifdef FIX_887_ARRAY_SIZE_DFT_MDCT_STEREO float res_buf[STEREO_DFT_N_8k], /* i : residual buffer */ +#else + float res_buf[STEREO_DFT_BUF_MAX], /* i : residual buffer */ +#endif float *output /* o : output frame */ ); @@ -1421,7 +1467,11 @@ void stereo_dft_dec_res( int16_t res_bpf_adapt( STEREO_DFT_DEC_DATA_HANDLE hStereoDft, /* i/o: DFT stereo decoder handle */ const float *bpf_error_signal_8k, /* i : BPF modification signal */ +#ifdef FIX_887_ARRAY_SIZE_DFT_MDCT_STEREO float res_buf[STEREO_DFT_N_8k] /* i : residual buffer */ +#else + float res_buf[STEREO_DFT_BUF_MAX] /* i : residual buffer */ +#endif ); void bpf_pitch_coherence( @@ -1437,7 +1487,11 @@ void stereo_dft_dec_read_BS( STEREO_DFT_DEC_DATA_HANDLE hStereoDft, /* i/o: decoder DFT stereo handle */ const int16_t bwidth, /* i : bandwidth */ const int16_t output_frame, /* i : output frame length */ +#ifdef FIX_887_ARRAY_SIZE_DFT_MDCT_STEREO float res_buf[STEREO_DFT_N_8k], /* o : residual buffer */ +#else + float res_buf[STEREO_DFT_BUF_MAX], /* o : residual buffer */ +#endif int16_t *nb_bits, /* o : number of bits read */ float *coh, /* i/o: Coherence */ const int16_t ivas_format /* i : ivas format */ @@ -1628,6 +1682,9 @@ void stereo_td_itd( ITD_DATA *hITD, /* i/o: ITD data structure */ float input_mem_itd[CPE_CHANNELS][STEREO_DFT_OVL_MAX], /* o : ITD memory (only used in DFT Stereo) */ const int16_t hybrid_itd_flag, /* i : flag for hybrid TD/FD ITD processing */ +#ifdef DEBUG_MODE_DFT + const int16_t itd_mode, /* i : main ITD processing flag */ +#endif const int16_t dft_ovl, /* i : size of DFT overlap */ Encoder_State **sts, /* i/o: Encoder state structure */ const int16_t input_frame, /* i : input frame length */ @@ -2206,10 +2263,19 @@ void EstimateStereoTCXNoiseLevel( void TNSAnalysisStereo( Encoder_State **sts, /* i : state handle */ +#ifdef FIX_887_ARRAY_SIZE_DFT_MDCT_STEREO float *mdst_spectrum[CPE_CHANNELS][NB_DIV], /* o : MDST spectrum */ +#else + float *mdst_spectrum[MCT_MAX_CHANNELS][NB_DIV], /* o : MDST spectrum */ +#endif const int16_t bWhitenedDomain, /* i : whitened domain flag */ +#ifdef FIX_887_ARRAY_SIZE_DFT_MDCT_STEREO int16_t tnsSize[CPE_CHANNELS][NB_DIV], /* i : number of tns parameters put into prm */ int16_t tnsBits[CPE_CHANNELS][NB_DIV], /* i : number of tns bits in the frame */ +#else + int16_t tnsSize[MCT_MAX_CHANNELS][NB_DIV], /* i : number of tns parameters put into prm */ + int16_t tnsBits[MCT_MAX_CHANNELS][NB_DIV], /* i : number of tns bits in the frame */ +#endif int16_t param_core[][NB_DIV * NPRM_DIV], /* o : quantized noise filling level */ const int16_t mct_on /* i : flag mct block (1) or stereo (0) */ ); @@ -2492,8 +2558,13 @@ void stereo_decoder_tcx( STEREO_MDCT_DEC_DATA *hStereoMdct, /* i/o: MDCT stereo decoder structure */ int16_t ms_mask[NB_DIV][MAX_SFB], /* i : bandwise MS mask */ float *spec_r_0[NB_DIV], /* i/o: spectrum right channel */ +#ifdef FIX_887_ARRAY_SIZE_DFT_MDCT_STEREO float *spec_l[], /* i/o: spectrum left channel [NB_DIV][N] */ float *spec_r[], /* i/o: spectrum right channel [NB_DIV][N] */ +#else + float *spec_l[NB_DIV], /* i/o: spectrum left channel */ + float *spec_r[NB_DIV], /* i/o: spectrum right channel */ +#endif const int16_t mdct_stereo_mode[], /* i : stereo mode (FB/band wise MS, dual mono */ const int16_t core_l, /* i : core for left channel (TCX20/TCX10) */ const int16_t core_r, /* i : core for right channel (TCX20/TCX10) */ @@ -3025,7 +3096,11 @@ void mctStereoIGF_enc( void ivas_mdct_dec_side_bits_frame_channel( CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ +#ifdef FIX_887_ARRAY_SIZE_DFT_MDCT_STEREO int16_t param_lpc[CPE_CHANNELS][NPRM_LPC_NEW], /* o : lpc_parameters */ +#else + int16_t param_lpc[MCT_MAX_CHANNELS][NPRM_LPC_NEW], /* o : lpc_parameters */ +#endif int16_t p_param[CPE_CHANNELS][NB_DIV], /* o : pointer to param buffer */ Decoder_State *st0, /* i : pointer to bitstream handle */ int16_t nTnsBitsTCX10[CPE_CHANNELS][NB_DIV], /* o : number of bits for TNS */ @@ -3426,7 +3501,12 @@ void ivas_sba_set_cna_cng_flag( ivas_error ivas_sba_dec_reconfigure( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ uint16_t *nSamplesFlushed, /* o : number of samples flushed */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + const PCM_RESOLUTION pcm_resolution, /* i : type for the decoded PCM resolution */ + void *data /* o : output synthesis signal */ +#else int16_t *data /* o : output synthesis signal */ +#endif ); ivas_error ivas_sba_digest_tc( @@ -3599,8 +3679,10 @@ void ivas_get_dirac_sba_max_md_bits( int16_t *metadata_max_bits, int16_t *qmetadata_max_bit_req, const int16_t nbands +#ifdef NONBE_FIX_871_ACELP_CRASH_IN_OSBA , IVAS_FORMAT ivas_format +#endif ); ivas_error ivas_dirac_sba_config( @@ -3609,8 +3691,10 @@ ivas_error ivas_dirac_sba_config( int32_t sba_total_brate, /* i : SBA total bitrate */ const int16_t sba_order, /* i : Ambisonic (SBA) order */ const int16_t nbands /* i : number of frequency bands */ +#ifdef NONBE_FIX_871_ACELP_CRASH_IN_OSBA , IVAS_FORMAT ivas_format +#endif ); ivas_error ivas_dirac_dec_config( @@ -3646,6 +3730,14 @@ void ivas_dirac_dec_set_md_map( const int16_t nCldfbTs /* i : number of CLDFB time slots */ ); +#ifndef NONBE_UNIFIED_DECODING_PATHS_FIX +void ivas_dirac_dec( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + float *output_f[], /* i/o: synthesized core-coder transport channels/DirAC output */ + const int16_t nchan_transport, /* i : number of transport channels */ + const int16_t num_subframes /* i : number of subframes to render */ +); +#endif void ivas_dirac_dec_render( Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ const int16_t nchan_transport, /* i : number of transport channels */ @@ -3727,6 +3819,12 @@ void ivas_mc_paramupmix_enc_close( const int32_t input_Fs /* i : input sampling rate */ ); +#ifndef NONBE_UNIFIED_DECODING_PATHS_FIX +void ivas_mc_paramupmix_dec( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ + float *output_f[] /* i/o: synthesized core-coder transport channels/DirAC output */ +); +#endif ivas_error ivas_mc_paramupmix_dec_open( Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ ); @@ -4086,6 +4184,13 @@ void ivas_spar_config( const int16_t sid_format /* i : IVAS format indicator from SID frame */ ); +#ifndef NONBE_UNIFIED_DECODING_PATHS_FIX +ivas_error ivas_sba_upmixer_renderer( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder struct */ + float *output[], /* i/o: transport/output audio channels */ + const int16_t output_frame /* i : output frame length */ +); +#endif ivas_error ivas_sba_linear_renderer( float *output_f[], /* i/o: synthesized core-coder transport channels/DirAC output */ const int16_t output_frame, /* i : output frame length per channel */ @@ -4107,6 +4212,9 @@ void ivas_sba_mix_matrix_determiner( /* AGC */ /*! r: AGC enable flag */ int16_t ivas_agc_enc_get_flag( +#ifdef DEBUG_AGC_ENCODER_CMD_OPTION + const int16_t agc_configuration, /* i : AGC configuration from command-line */ +#endif const int16_t nchan_transport /* i : number of transport channels */ ); @@ -4900,7 +5008,12 @@ void ivas_masa_enc_reconfigure( ivas_error ivas_masa_dec_reconfigure( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ uint16_t *nSamplesRendered, /* o : number of samples flushed from the previous frame (JBM) */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + const PCM_RESOLUTION pcm_resolution, /* i : type for the decoded PCM resolution */ + void *data /* o : output synthesis signal */ +#else int16_t *data /* o : output synthesis signal */ +#endif ); ivas_error ivas_masa_encode( @@ -5132,13 +5245,40 @@ ivas_error ivas_allocate_binaural_hrtf( const int16_t allocate_init_flag /* i : Memory allocation flag */ ); +#ifdef DEBUGGING +void ivas_binaural_cldfb( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + float *output_f[] /* i/o: synthesized core-coder transport channels/DirAC output */ +); + +void ivas_binaural_cldfb_sf( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + const int16_t n_samples_to_render, /* i : output frame length per channel */ + const int16_t slot_size, /* i : JBM slot size */ + float *output_f[] /* i/o: synthesized core-coder transport channels/DirAC output */ +); +#endif void ivas_binRenderer( BINAURAL_RENDERER_HANDLE hBinRenderer, /* i/o: binaural renderer handle */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + const MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, +#endif COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i : combined head and external orientation handle */ +#ifndef NONBE_UNIFIED_DECODING_PATHS + int16_t subframe_idx, /* i : subframe index */ +#endif const int16_t numTimeSlots, /* i : number of time slots to process */ +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + HEAD_TRACK_DATA_HANDLE hPostRendHeadTrackData, +#endif +#ifdef SPLIT_REND_WITH_HEAD_ROT + float Cldfb_RealBuffer_Binaural[][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : Rotated Binaural signals */ + float Cldfb_ImagBuffer_Binaural[][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : Rotated Binaural signals */ +#else float Cldfb_RealBuffer_Binaural[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : Binaural signals */ float Cldfb_ImagBuffer_Binaural[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : Binaural signals */ +#endif float RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i : LS signals */ float ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX] /* i : LS signals */ ); @@ -5163,6 +5303,13 @@ void ivas_ism_renderer_close( ISM_RENDERER_HANDLE *hIsmRendererData /* i/o: ISM renderer handle */ ); +#ifndef NONBE_UNIFIED_DECODING_PATHS +void ivas_ism_render( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + float *output_f[], /* i/o: core-coder transport channels/object output */ + const int16_t output_frame /* i : output frame length per channel */ +); +#endif void ivas_ism_render_sf( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ float *output_f[], /* i/o: core-coder transport channels/object output */ @@ -5195,6 +5342,17 @@ void ivas_param_mc_mc2sba_cldfb( const float gain_lfe /* i : gain applied to LFE */ ); +#ifndef NONBE_UNIFIED_DECODING_PATHS_FIX +void ivas_ism2sba( + float *buffer_td[], /* i/o: TD signal buffers */ + ISM_RENDERER_HANDLE hIsmRendererData, /* i/o: renderer data */ + const ISM_METADATA_HANDLE hIsmMetaData[], /* i : object metadata */ + const int16_t nchan_ism, /* i : number of objects */ + const int16_t output_frame, /* i : output frame length per channel */ + const int16_t sba_order /* i : SBA order */ +); + +#endif void ivas_ism2sba_sf( float *buffer_in[], /* i : TC buffer */ float *buffer_out[], /* o : TD signal buffers */ @@ -5543,6 +5701,13 @@ ivas_error ivas_osba_dirac_td_binaural_jbm( float *output_f[] /* o : rendered time signal */ ); +#ifndef NONBE_UNIFIED_DECODING_PATHS_FIX +ivas_error ivas_osba_dirac_td_binaural( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + float *output[], /* o : output synthesis signal */ + const int16_t output_frame /* i : output frame length per channel */ +); +#endif ivas_error ivas_osba_ism_metadata_dec( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ @@ -5551,6 +5716,7 @@ ivas_error ivas_osba_ism_metadata_dec( int16_t nb_bits_metadata[] /* o : number of ISM metadata bits */ ); +#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX ivas_error ivas_osba_render_sf( Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ const uint16_t nSamplesAsked, /* i : number of CLDFB slots requested */ @@ -5558,6 +5724,13 @@ ivas_error ivas_osba_render_sf( uint16_t *nSamplesAvailableNext, /* o : number of CLDFB slots still to render */ float *output_f[] /* o : rendered time signal */ ); +#else +ivas_error ivas_osba_render( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + float *output_f[], /* i/o: core-coder transport channels/object output */ + const int16_t output_frame /* i : output frame length per channel */ +); +#endif void ivas_osba_data_close( SBA_ISM_DATA_HANDLE *hSbaIsmData /* i/o: OSBA rendering handle */ @@ -5583,7 +5756,12 @@ ivas_error ivas_omasa_enc_config( ivas_error ivas_omasa_dec_config( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ uint16_t *nSamplesRendered, /* o : number of samples flushed from the previous frame (JBM) */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + const PCM_RESOLUTION pcm_resolution, /* i : type for the decoded PCM resolution */ + void *data /* o : output synthesis signal */ +#else int16_t *data /* o : output synthesis signal */ +#endif ); void ivas_omasa_set_config( @@ -5608,6 +5786,10 @@ void ivas_omasa_enc( void ivas_set_surplus_brate_enc( Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ +#ifdef DEBUG_MODE_INFO + , + const int16_t *nb_bits_metadata /* i : number of metadata bits */ +#endif ); void ivas_set_surplus_brate_dec( @@ -5687,6 +5869,13 @@ ivas_error ivas_omasa_ism_metadata_dec( int16_t nb_bits_metadata[] /* o : number of ISM metadata bits */ ); +#ifndef NONBE_UNIFIED_DECODING_PATHS +ivas_error ivas_omasa_dirac_td_binaural( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + float *output[], /* o : output synthesis signal */ + const int16_t output_frame /* i : output frame length per channel */ +); +#endif ivas_error ivas_omasa_dirac_td_binaural_jbm( Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ const uint16_t nSamplesAsked, /* i : number of samples requested */ @@ -5696,6 +5885,14 @@ ivas_error ivas_omasa_dirac_td_binaural_jbm( float *output_f[] /* o : rendered time signal */ ); +#ifndef NONBE_UNIFIED_DECODING_PATHS_FIX +void ivas_omasa_dirac_rend( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + float *output[], /* o : output synthesis signal */ + const int16_t output_frame /* i : output frame length per channel */ +); + +#endif void ivas_omasa_rearrange_channels( float *output[], /* o : output synthesis signal */ const int16_t nchan_transport_ism, /* i : number of ISM TCs */ @@ -5727,10 +5924,21 @@ void ivas_omasa_separate_object_renderer_close( Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ ); +#ifndef NONBE_UNIFIED_DECODING_PATHS_FIX +void ivas_omasa_separate_object_render( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + float input_f[][L_FRAME48k], /* i : separated object signal */ + float *output_f[], /* i/o: output signals */ + const int16_t output_frame /* i : output frame length per channel */ +); + +#endif void ivas_omasa_separate_object_render_jbm( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ const uint16_t nSamplesRendered, /* i : number of samples rendered */ +#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX float input_f[][L_FRAME48k], /* i : separated object signal */ +#endif float *output_f[], /* o : rendered time signal */ const int16_t subframes_rendered, /* i : number of subframes rendered */ const int16_t slots_rendered /* i : number of CLDFB slots rendered */ diff --git a/lib_com/ivas_qmetadata_com.c b/lib_com/ivas_qmetadata_com.c index 57adf7c6a..d3b11da6d 100644 --- a/lib_com/ivas_qmetadata_com.c +++ b/lib_com/ivas_qmetadata_com.c @@ -101,6 +101,9 @@ ivas_error ivas_qmetadata_allocate_memory( int16_t j, dir; uint8_t do_realloc; +#ifdef DEBUGGING + assert( hQMetaData != NULL ); +#endif /* Check if we need to reallocate memory or do we need to do the first time allocation. */ if ( hQMetaData->q_direction != NULL ) @@ -337,6 +340,12 @@ ivas_error only_reduce_bits_direction( while ( n < rem ) { max_nb = 0; +#ifdef DEBUGGING + if ( delta > MASA_MIN_BITS_TF ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Not enough bits for MASA param." ); + } +#endif for ( j = 0; j < coding_subbands; j++ ) { bits_dir0 = (int16_t *) q_direction->band_data[j].bits_sph_idx; @@ -574,6 +583,10 @@ void ivas_qmetadata_azimuth_elevation_to_direction_vector( { float radius_length; +#ifdef DEBUGGING + assert( fabsf( el ) <= 90.0f ); + /*assert((0.0f <= az) && (az <= 360.0f)); */ +#endif dv[2] = sinf( el * PI_OVER_180 ); radius_length = cosf( el * PI_OVER_180 ); diff --git a/lib_com/ivas_qspherical_com.c b/lib_com/ivas_qspherical_com.c index e754fb692..874f66d05 100644 --- a/lib_com/ivas_qspherical_com.c +++ b/lib_com/ivas_qspherical_com.c @@ -101,10 +101,18 @@ int16_t ivas_dirac_project_elevation_index( ) { int16_t el_idx_proj; +#ifdef DEBUGGING + assert( ( el_idx >= 0 ) && ( el_idx < el_alph ) ); + assert( el_alph == 2 * ( el_alph >> 1 ) + 1 ); /* el_alph of the form 2 * n_points + 1 */ + assert( el_alph_proj == 2 * ( el_alph_proj >> 1 ) + 1 ); +#endif /* evaluate floor((el_idx / (el_alph - 1)) * (el_alph_proj - 1) + 0.5) using only integer */ el_idx_proj = ( 2 * el_idx * ( el_alph_proj - 1 ) + ( el_alph - 1 ) ) / ( 2 * ( el_alph - 1 ) ); +#ifdef DEBUGGING + assert( ( 0 <= el_idx_proj ) && ( el_idx_proj < el_alph_proj ) ); +#endif return el_idx_proj; } @@ -123,6 +131,9 @@ int16_t ivas_chan_project_elevation_index( ) { int16_t el_idx_proj; +#ifdef DEBUGGING + assert( ( el_idx >= 0 ) && ( el_idx < el_alph ) ); +#endif /* evaluate floor((el_idx / (el_alph - 1)) * (el_alph_proj - 1) + 0.5) using only integer */ if ( el_idx == el_alph - 1 ) @@ -134,6 +145,9 @@ int16_t ivas_chan_project_elevation_index( el_idx_proj = ( 2 * el_idx * el_alph_proj + el_alph ) / ( 2 * el_alph ); } +#ifdef DEBUGGING + assert( ( 0 <= el_idx_proj ) && ( el_idx_proj < el_alph_proj ) ); +#endif return el_idx_proj; } @@ -152,6 +166,9 @@ int16_t ivas_dirac_project_azimuth_index( ) { int16_t az_idx_proj; +#ifdef DEBUGGING + assert( ( az_idx >= 0 ) && ( az_idx < az_alph ) ); +#endif if ( az_alph_proj == 1 ) { @@ -166,6 +183,9 @@ int16_t ivas_dirac_project_azimuth_index( az_idx_proj = 0; } +#ifdef DEBUGGING + assert( ( 0 <= az_idx_proj ) && ( az_idx_proj < az_alph_proj ) ); +#endif return az_idx_proj; } @@ -226,6 +246,9 @@ int16_t quantize_phi( float dd; float delta_phi; +#ifdef DEBUGGING + assert( ( phi >= 0.f ) && ( phi <= 360.f ) ); +#endif delta_phi = 360.0f / (float) n; @@ -387,6 +410,10 @@ int16_t quantize_phi_chan_lbr( { int16_t id_phi; +#ifdef DEBUGGING + assert( ( phi >= -180.f ) && ( phi <= 180.f ) ); + assert( n <= 9 ); +#endif if ( n <= 1 ) { @@ -430,6 +457,9 @@ int16_t quantize_phi_chan_compand( int16_t id_phi; float delta_phi; +#ifdef DEBUGGING + assert( ( phi >= 0.f ) && ( phi <= 360.f ) ); +#endif if ( n <= 1 ) { diff --git a/lib_com/ivas_rom_com.c b/lib_com/ivas_rom_com.c index ad8279712..9727f39fd 100644 --- a/lib_com/ivas_rom_com.c +++ b/lib_com/ivas_rom_com.c @@ -32,6 +32,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "ivas_cnst.h" @@ -2515,6 +2518,17 @@ const uint16_t ivas_param_mc_sym_freq_ild_delta_combined_48_16bits[2 * PARAM_MC_ 1, 1, 1, 2, 24, 69, 122, 194, 285, 487, 690, 1173, 2255, 4709, 10599, 24635, 10862, 4709, 2204, 1059, 566, 330, 221, 150, 95, 59, 28, 2, 1, 1, 1 }; +#ifndef FIX_891_PARAMUPMIX_CLEANUP +/*----------------------------------------------------------------------------------* + * Parametric Upmix MC ROM tables + *----------------------------------------------------------------------------------*/ + +const int16_t ivas_param_upmx_mx_qmap[2][33] = +{ + { 0, 1, 2, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 3, 2, 1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 3, 2, 1, 0 }, + { 0, 1, 2, 3, 4, 3, 2, 1, 0, 1, 2, 3, 4, 3, 2, 1, 0 } +}; +#endif /*----------------------------------------------------------------------------------* * MASA ROM tables @@ -6425,6 +6439,7 @@ const int16_t sns_1st_means_32k[2][16] = * MC ParamUpmix ROM tables *-----------------------------------------------------------------------*/ +#ifdef FIX_891_PARAMUPMIX_CLEANUP const int16_t ivas_param_upmx_mx_qmap[33] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 3, 2, 1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 3, 2, 1, 0 @@ -6488,5 +6503,105 @@ const ACPL_QUANT_TABLE ivas_mc_paramupmix_beta_quant_table[9] = { +0.000000e+000f, +5.937500e-002f, +1.375000e-001f, +2.343750e-001f, +3.500000e-001f, +4.843750e-001f, +6.375000e-001f, +8.093750e-001f, +1.000000e+000f } /* data */ } }; +#else +const ACPL_QUANT_TABLE ivas_mc_paramupmix_alpha_quant_table[] = +{ + /* Alfa Fine */ + { + 33, /* nquant */ + 16, /* offset */ + { -2.000000e+000f, -1.809375e+000f, -1.637500e+000f, -1.484375e+000f, -1.350000e+000f, -1.234375e+000f, -1.137500e+000f, -1.059375e+000f, -1.000000e+000f, -9.406250e-001f, + -8.625000e-001f, -7.656250e-001f, -6.500000e-001f, -5.156250e-001f, -3.625000e-001f, -1.906250e-001f, +0.000000e+000f, +1.906250e-001f, +3.625000e-001f, +5.156250e-001f, + +6.500000e-001f, +7.656250e-001f, +8.625000e-001f, +9.406250e-001f, +1.000000e+000f, +1.059375e+000f, +1.137500e+000f, +1.234375e+000f, +1.350000e+000f, +1.484375e+000f, + +1.637500e+000f, +1.809375e+000f, +2.000000e+000f } /* data */ + }, + { /* Alfa Coarse */ + 17, /* nquant */ + 8, /* offset */ + { -2.000000e+000f, -1.637500e+000f, -1.350000e+000f, -1.137500e+000f, -1.000000e+000f, -8.625000e-001f, -6.500000e-001f, -3.625000e-001f, +0.000000e+000f, +3.625000e-001f, + +6.500000e-001f, +8.625000e-001f, +1.000000e+000f, +1.137500e+000f, +1.350000e+000f, +1.637500e+000f, +2.000000e+000f } /* data */ + } +}; + +const ACPL_QUANT_TABLE ivas_mc_paramupmix_beta_quant_table[2][9] = +{ + { + /* Beta Fine #1 */ + { + 9, /* nquant */ + 0, /* offset */ + { +0.000000e+000f, +2.375000e-001f, +5.500000e-001f, +9.375000e-001f, +1.400000e+000f, +1.937500e+000f, +2.550000e+000f, +3.237500e+000f, +4.000000e+000f } /* data */ + }, + { /* Beta Fine #2 */ + 9, /* nquant */ + 0, /* offset */ + { +0.000000e+000f, +2.035449e-001f, +4.713672e-001f, +8.034668e-001f, +1.199844e+000f, +1.660498e+000f, +2.185430e+000f, +2.774639e+000f, +3.428125e+000f } /* data */ + }, + { /* Beta Fine #3 */ + 9, /* nquant */ + 0, /* offset */ + { +0.000000e+000f, +1.729297e-001f, +4.004688e-001f, +6.826172e-001f, +1.019375e+000f, +1.410742e+000f, +1.856719e+000f, +2.357305e+000f, +2.912500e+000f } /* data */ + }, + { /* Beta Fine #4 */ + 9, /* nquant */ + 0, /* offset */ + { +0.000000e+000f, +1.456543e-001f, +3.373047e-001f, +5.749512e-001f, +8.585938e-001f, +1.188232e+000f, +1.563867e+000f, +1.985498e+000f, +2.453125e+000f } /* data */ + }, + { /* Beta Fine #5 */ + 9, /* nquant */ + 0, /* offset */ + { +0.000000e+000f, +1.217188e-001f, +2.818750e-001f, +4.804688e-001f, +7.175000e-001f, +9.929688e-001f, +1.306875e+000f, +1.659219e+000f, +2.050000e+000f } /* data */ + }, + { /* Beta Fine #6 */ + 9, /* nquant */ + 0, /* offset */ + { +0.000000e+000f, +1.011230e-001f, +2.341797e-001f, +3.991699e-001f, +5.960938e-001f, +8.249512e-001f, +1.085742e+000f, +1.378467e+000f, +1.703125e+000f } /* data */ + }, + { /* Beta Fine #7 */ + 9, /* nquant */ + 0, /* offset */ + { +0.000000e+000f, +8.386719e-002f, +1.942188e-001f, +3.310547e-001f, +4.943750e-001f, +6.841797e-001f, +9.004688e-001f, +1.143242e+000f, +1.412500e+000f } /* data */ + }, + { /* Beta Fine #8 */ + 9, /* nquant */ + 0, /* offset */ + { +0.000000e+000f, +6.995117e-002f, +1.619922e-001f, +2.761230e-001f, +4.123438e-001f, +5.706543e-001f, +7.510547e-001f, +9.535449e-001f, +1.178125e+000f } /* data */ + }, + { /* Beta Fine #9 */ + 9, /* nquant */ + 0, /* offset */ + { +0.000000e+000f, +5.937500e-002f, +1.375000e-001f, +2.343750e-001f, +3.500000e-001f, +4.843750e-001f, +6.375000e-001f, +8.093750e-001f, +1.000000e+000f } /* data */ + } + }, + { + /* Beta Coarse #1 */ + { + 5, /* nquant */ + 0, /* offset */ + { +0.000000e+000f, +5.500000e-001f, +1.400000e+000f, +2.550000e+000f, +4.000000e+000f } /* data */ + }, + { /* Beta Coarse #2 */ + 5, /* nquant */ + 0, /* offset */ + { +0.000000e+000f, +4.004688e-001f, +1.019375e+000f, +1.856719e+000f, +2.912500e+000f } /* data */ + }, + { /* Beta Coarse #3 */ + 5, /* nquant */ + 0, /* offset */ + { +0.000000e+000f, +2.818750e-001f, +7.175000e-001f, +1.306875e+000f, +2.050000e+000f } /* data */ + }, + { /* Beta Coarse #4 */ + 5, /* nquant */ + 0, /* offset */ + { +0.000000e+000f, +1.942188e-001f, +4.943750e-001f, +9.004688e-001f, +1.412500e+000f } /* data */ + }, + { /* Beta Coarse #5 */ + 5, /* nquant */ + 0, /* offset */ + { +0.000000e+000f, +1.375000e-001f, +3.500000e-001f, +6.375000e-001f, +1.000000e+000f } /* data */ + } + } +}; +#endif /* clang-format on */ diff --git a/lib_com/ivas_rom_com.h b/lib_com/ivas_rom_com.h index b13d41548..89086987e 100644 --- a/lib_com/ivas_rom_com.h +++ b/lib_com/ivas_rom_com.h @@ -39,6 +39,9 @@ #include "ivas_cnst.h" #include "stat_com.h" #include "ivas_stat_com.h" +#ifdef DEBUGGING +#include "debug.h" +#endif /*----------------------------------------------------------------------------------* @@ -256,6 +259,12 @@ extern const uint16_t ivas_param_mc_sym_freq_icc_combined_48_16bits[PARAM_MC_SZ_ extern const uint16_t ivas_param_mc_cum_freq_icc_delta_combined_48_16bits[2 * PARAM_MC_SZ_ICC_QUANTIZER]; extern const uint16_t ivas_param_mc_sym_freq_icc_delta_combined_48_16bits[2 * PARAM_MC_SZ_ICC_QUANTIZER - 1]; +#ifndef FIX_891_PARAMUPMIX_CLEANUP +/*----------------------------------------------------------------------------------* + * Parametric Upmix MC ROM tables + *----------------------------------------------------------------------------------*/ +extern const int16_t ivas_param_upmx_mx_qmap[2][33]; +#endif /*----------------------------------------------------------------------------------* * MASA ROM tables @@ -444,10 +453,15 @@ extern const int16_t sns_1st_means_32k[2][16]; /*----------------------------------------------------------------------* * MC ParamUpmix ROM tables *-----------------------------------------------------------------------*/ +#ifdef FIX_891_PARAMUPMIX_CLEANUP extern const int16_t ivas_param_upmx_mx_qmap[33]; extern const ACPL_QUANT_TABLE ivas_mc_paramupmix_alpha_quant_table; extern const ACPL_QUANT_TABLE ivas_mc_paramupmix_beta_quant_table[9]; +#else +extern const ACPL_QUANT_TABLE ivas_mc_paramupmix_alpha_quant_table[]; +extern const ACPL_QUANT_TABLE ivas_mc_paramupmix_beta_quant_table[2][9]; +#endif /* IVAS_ROM_COM_H */ #endif diff --git a/lib_com/ivas_sba_config.c b/lib_com/ivas_sba_config.c index fd1bb70fd..778a7bb90 100644 --- a/lib_com/ivas_sba_config.c +++ b/lib_com/ivas_sba_config.c @@ -41,6 +41,9 @@ #include "ivas_prot.h" #include "ivas_stat_com.h" #include "ivas_rom_com.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" diff --git a/lib_com/ivas_sns_com.c b/lib_com/ivas_sns_com.c index 4708b32c2..da7b37e8c 100644 --- a/lib_com/ivas_sns_com.c +++ b/lib_com/ivas_sns_com.c @@ -39,6 +39,9 @@ #include "ivas_rom_com.h" #include #include +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" diff --git a/lib_com/ivas_spar_com.c b/lib_com/ivas_spar_com.c index e80dbf428..f519ffec1 100644 --- a/lib_com/ivas_spar_com.c +++ b/lib_com/ivas_spar_com.c @@ -33,6 +33,9 @@ #include #include "math.h" #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "ivas_stat_com.h" #include "prot.h" #include "ivas_prot.h" @@ -1383,6 +1386,27 @@ void ivas_compute_spar_params( { ivas_calc_c_p_coeffs( hSparMd, cov_real, i_ts, mixer_mat, num_ch, ndm, b, dtx_vad, 1, dyn_active_w_flag ); +#ifdef SPAR_HOA_DBG + /* if (b == 0) */ + { + fprintf( stdout, "\n\nUnquantised C, P coeffs -- band %d:\n", b ); + + for ( int16_t ii = 0; ii < num_ch; ii++ ) + { + fprintf( stdout, "%f |", hSparMd->band_coeffs[b].pred_re[ii] ); + + if ( ii < num_ch - ndm ) + { + for ( int16_t jj = 0; jj < ndm - 1; jj++ ) + { + fprintf( stdout, "%f,\t", hSparMd->band_coeffs[b].C_re[ii][jj] ); + } + fprintf( stdout, "| %f", hSparMd->band_coeffs[b].P_re[ii] ); + } + fprintf( stdout, "\n" ); + } + } +#endif } } @@ -1655,6 +1679,29 @@ void ivas_get_spar_md_from_dirac( } } +#ifdef DEBUG_SBA_MD_DUMP + { + static FILE *fid = 0; + int16_t k = 0; + float tmp_buf[10]; + if ( !fid ) + { + fid = fopen( "cov_real_dirac.txt", "wt" ); + } + + for ( i = 0; i < num_ch; i++ ) + { + for ( j = 0; j < num_ch; j++ ) + { + for ( k = start_band; k < end_band; k++ ) + { + fprintf( fid, "%.6f\n", cov_real_dirac[i][j][k] ); + } + } + } + fprintf( fid, "\n" ); + } +#endif active_w = ( dyn_active_w_flag == 1 ) || ( hSpar_md_cfg->active_w == 1 ); diff --git a/lib_com/ivas_spar_com_quant_util.c b/lib_com/ivas_spar_com_quant_util.c index c01f95d1e..977f36e37 100644 --- a/lib_com/ivas_spar_com_quant_util.c +++ b/lib_com/ivas_spar_com_quant_util.c @@ -32,6 +32,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "math.h" #include "prot.h" #include "ivas_prot.h" diff --git a/lib_com/ivas_stat_com.h b/lib_com/ivas_stat_com.h index f34610c11..566abcb44 100644 --- a/lib_com/ivas_stat_com.h +++ b/lib_com/ivas_stat_com.h @@ -99,6 +99,10 @@ typedef struct stereo_dft_config_data_struct int16_t dmx_active; int16_t band_res; int16_t prm_res; /* Send prm every # DFT frames */ +#ifdef DEBUG_MODE_DFT + int16_t gipd_mode; /* mode : from 0 (off) to 1 (on) */ + int16_t itd_mode; /* mode : from 0 (off) to 1 (on) */ +#endif int16_t res_pred_mode; /* mode : from 0 (off) to 1 (on) */ int16_t res_cod_mode; /* mode : from 0 (off) to 3 */ int16_t hybrid_itd_flag; diff --git a/lib_com/ivas_stereo_dft_com.c b/lib_com/ivas_stereo_dft_com.c index 541f90a12..ae6b772a3 100644 --- a/lib_com/ivas_stereo_dft_com.c +++ b/lib_com/ivas_stereo_dft_com.c @@ -57,7 +57,11 @@ void stereo_dft_config( { hConfig->band_res = STEREO_DFT_BAND_RES_HIGH; hConfig->prm_res = 2; +#ifndef DEBUG_STEREO_DFT_NOSTEREO hConfig->dmx_active = STEREO_DFT_DMX_ACTIVE; +#else + hConfig->dmx_active = 0; +#endif hConfig->ada_wb_res_cod_mode = 0; } @@ -69,6 +73,10 @@ void stereo_dft_config( *bits_frame_nominal = FRAME_NO_DATA; if ( hConfig != NULL ) { +#ifdef DEBUG_MODE_DFT + hConfig->itd_mode = 1; + hConfig->gipd_mode = 1; +#endif hConfig->res_pred_mode = STEREO_DFT_RESPRED_OFF; hConfig->band_res = STEREO_DFT_BAND_RES_LOW; hConfig->res_cod_mode = STEREO_DFT_RES_COD_OFF; @@ -79,6 +87,10 @@ void stereo_dft_config( *bits_frame_nominal = SID_2k40 / FRAMES_PER_SEC; if ( hConfig != NULL ) { +#ifdef DEBUG_MODE_DFT + hConfig->itd_mode = 1; + hConfig->gipd_mode = 1; +#endif hConfig->res_pred_mode = STEREO_DFT_RESPRED_OFF; hConfig->band_res = STEREO_DFT_BAND_RES_LOW; hConfig->res_cod_mode = STEREO_DFT_RES_COD_OFF; @@ -89,6 +101,10 @@ void stereo_dft_config( *bits_frame_nominal = ACELP_9k60 / FRAMES_PER_SEC; if ( hConfig != NULL ) { +#ifdef DEBUG_MODE_DFT + hConfig->itd_mode = 1; + hConfig->gipd_mode = 1; +#endif hConfig->res_pred_mode = STEREO_DFT_RESPRED_ESF; hConfig->band_res = STEREO_DFT_BAND_RES_LOW; hConfig->res_cod_mode = STEREO_DFT_RES_COD_OFF; @@ -99,6 +115,10 @@ void stereo_dft_config( *bits_frame_nominal = ACELP_13k20 / FRAMES_PER_SEC; if ( hConfig != NULL ) { +#ifdef DEBUG_MODE_DFT + hConfig->itd_mode = 1; + hConfig->gipd_mode = 1; +#endif hConfig->res_pred_mode = STEREO_DFT_RESPRED_ESF; hConfig->band_res = STEREO_DFT_BAND_RES_LOW; hConfig->res_cod_mode = STEREO_DFT_RES_COD_OFF; @@ -109,6 +129,10 @@ void stereo_dft_config( *bits_frame_nominal = ACELP_16k40 / FRAMES_PER_SEC; if ( hConfig != NULL ) { +#ifdef DEBUG_MODE_DFT + hConfig->itd_mode = 1; + hConfig->gipd_mode = 1; +#endif hConfig->res_pred_mode = STEREO_DFT_RESPRED_ESF; hConfig->res_cod_mode = STEREO_DFT_RES_COD_OFF; } @@ -119,6 +143,10 @@ void stereo_dft_config( if ( hConfig != NULL ) { hConfig->ada_wb_res_cod_mode = 1; +#ifdef DEBUG_MODE_DFT + hConfig->itd_mode = 1; + hConfig->gipd_mode = 1; +#endif hConfig->res_pred_mode = STEREO_DFT_RESPRED_STEFI; hConfig->res_cod_mode = STEREO_DFT_RES_COD_1kHz; } @@ -128,6 +156,10 @@ void stereo_dft_config( *bits_frame_nominal = ACELP_32k / FRAMES_PER_SEC; if ( hConfig != NULL ) { +#ifdef DEBUG_MODE_DFT + hConfig->itd_mode = 1; + hConfig->gipd_mode = 1; +#endif hConfig->res_pred_mode = STEREO_DFT_RESPRED_STEFI; hConfig->res_cod_mode = STEREO_DFT_RES_COD_1_6kHz; } diff --git a/lib_com/ivas_stereo_eclvq_com.c b/lib_com/ivas_stereo_eclvq_com.c index f3b4e51fe..ff78a66eb 100644 --- a/lib_com/ivas_stereo_eclvq_com.c +++ b/lib_com/ivas_stereo_eclvq_com.c @@ -70,6 +70,9 @@ float ECSQ_dequantize_gain( const int16_t index ) { float global_gain; +#ifdef DEBUGGING + assert( ( index >= 0 ) && ( index <= 126 ) ); +#endif global_gain = powf( 10.0f, (float) index * ECLVQ_INV_GLOBAL_GAIN_FACTOR ); @@ -89,6 +92,10 @@ void ECSQ_dequantize_vector( float *output ) { int16_t i; +#ifdef DEBUGGING + assert( N > 0 ); + assert( global_gain > 0.0f ); +#endif for ( i = 0; i < N; ++i ) { diff --git a/lib_com/ivas_stereo_ica_com.c b/lib_com/ivas_stereo_ica_com.c index 31f9447a5..a68a9a709 100644 --- a/lib_com/ivas_stereo_ica_com.c +++ b/lib_com/ivas_stereo_ica_com.c @@ -37,6 +37,9 @@ #include "ivas_cnst.h" #include "prot.h" #include "ivas_prot.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" #include "rom_com.h" #include "ivas_rom_com.h" diff --git a/lib_com/ivas_stereo_mdct_bands_com.c b/lib_com/ivas_stereo_mdct_bands_com.c index 35524a20a..19a1295f2 100644 --- a/lib_com/ivas_stereo_mdct_bands_com.c +++ b/lib_com/ivas_stereo_mdct_bands_com.c @@ -225,6 +225,9 @@ void stereo_mdct_init_igf_start_band( { int16_t i, bitRateIndex, igfStartLine; const int16_t *swb_offset; +#ifdef DEBUGGING + stbParams->sfbIgfStart = 0; +#endif bitRateIndex = IGF_MapBitRateToIndex( element_brate, bwidth, IVAS_CPE_MDCT, 0 ); swb_offset = &swb_offset_LB_new[bitRateIndex][1]; @@ -241,6 +244,9 @@ void stereo_mdct_init_igf_start_band( stbParams->nBandsStereoCore = stbParams->sfbIgfStart; +#ifdef DEBUGGING + assert( stbParams->sfbIgfStart > 0 ); +#endif return; } diff --git a/lib_com/ivas_stereo_td_bit_alloc.c b/lib_com/ivas_stereo_td_bit_alloc.c index 35bfe9046..ce3a5f20f 100644 --- a/lib_com/ivas_stereo_td_bit_alloc.c +++ b/lib_com/ivas_stereo_td_bit_alloc.c @@ -32,6 +32,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "stat_enc.h" #include "rom_com.h" diff --git a/lib_com/ivas_tools.c b/lib_com/ivas_tools.c index 4e28892da..ee7a06ca7 100644 --- a/lib_com/ivas_tools.c +++ b/lib_com/ivas_tools.c @@ -33,6 +33,9 @@ #include #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "prot.h" #include "ivas_prot.h" @@ -129,6 +132,12 @@ uint32_t ivas_syn_output( { noClipping += mvr2s( synth[n], synth_loc, output_frame ); +#ifdef DEBUG_MODE_LFE + if ( n == LFE_CHANNEL ) + { + dbgwrite( synth_loc, sizeof( int16_t ), output_frame, 1, "./lfe_out.raw" ); + } +#endif for ( i = 0; i < output_frame; i++ ) { synth_out[i * n_channels + n] = synth_loc[i]; diff --git a/lib_com/ivas_transient_det.c b/lib_com/ivas_transient_det.c index 7e38f8ce6..54c12e916 100644 --- a/lib_com/ivas_transient_det.c +++ b/lib_com/ivas_transient_det.c @@ -32,6 +32,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "math.h" #include "wmc_auto.h" #include "prot.h" diff --git a/lib_com/lag_wind.c b/lib_com/lag_wind.c index fdaa4a7a7..c4c5e803b 100644 --- a/lib_com/lag_wind.c +++ b/lib_com/lag_wind.c @@ -37,6 +37,9 @@ #include #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "prot.h" #include "cnst.h" #include "rom_com.h" diff --git a/lib_com/limit_t0.c b/lib_com/limit_t0.c index 1176a8132..0a844bbc5 100644 --- a/lib_com/limit_t0.c +++ b/lib_com/limit_t0.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "prot.h" #include "wmc_auto.h" diff --git a/lib_com/logqnorm.c b/lib_com/logqnorm.c index 04b822a14..c8185dd5a 100644 --- a/lib_com/logqnorm.c +++ b/lib_com/logqnorm.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "prot.h" diff --git a/lib_com/low_rate_band_att.c b/lib_com/low_rate_band_att.c index c715e0ac5..393cae5ff 100644 --- a/lib_com/low_rate_band_att.c +++ b/lib_com/low_rate_band_att.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "rom_com.h" #include "prot.h" diff --git a/lib_com/lpc_tools.c b/lib_com/lpc_tools.c index 9c936da11..82c8cddbd 100644 --- a/lib_com/lpc_tools.c +++ b/lib_com/lpc_tools.c @@ -37,6 +37,9 @@ #include #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "prot.h" diff --git a/lib_com/lsf_msvq_ma.c b/lib_com/lsf_msvq_ma.c index 940233e4c..3396e9fde 100644 --- a/lib_com/lsf_msvq_ma.c +++ b/lib_com/lsf_msvq_ma.c @@ -37,6 +37,9 @@ #include #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "prot.h" #include "rom_com.h" diff --git a/lib_com/lsf_tools.c b/lib_com/lsf_tools.c index eaa94b506..70d1e655c 100644 --- a/lib_com/lsf_tools.c +++ b/lib_com/lsf_tools.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "prot.h" @@ -182,6 +185,12 @@ void a2isp( { xint -= ylow * ( xhigh - xlow ) / ( ymid ); } +#ifdef DEBUGGING + else if ( ymid == 0 && ylow != 0 ) + { + IVAS_ERROR( IVAS_ERR_INTERNAL, "issue in a2lsp_stab()" ); + } +#endif isp[nf] = xint; /* new root */ nf++; @@ -667,6 +676,12 @@ void a2lsp_stab( { xint -= ylow * ( xhigh - xlow ) / ( ymid ); } +#ifdef DEBUGGING + else if ( ymid == 0 && ylow != 0 ) + { + IVAS_ERROR( IVAS_ERR_INTERNAL, "issue in a2lsp_stab()" ); + } +#endif lsp[nf] = xint; /* new root */ nf++; ip = 1 - ip; /* flag to other polynomial */ @@ -1167,6 +1182,12 @@ ivas_error lsf_allocate( levels1[0] = bits_lvq; } } +#ifdef DEBUGGING + else + { + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "lsf_allocate(): invalid number of bits in used predictive mode\n" ); + } +#endif } return error; @@ -1244,6 +1265,12 @@ ivas_error find_pred_mode( } } +#ifdef DEBUGGING + if ( *predmode == -1 ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "\nfind_pred_mode(): incorrect coder_type specification: %d\n", coder_type ); + } +#endif return error; } diff --git a/lib_com/lsp_conv_poly.c b/lib_com/lsp_conv_poly.c index ee567b3e8..d43d74fb5 100644 --- a/lib_com/lsp_conv_poly.c +++ b/lib_com/lsp_conv_poly.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "rom_com.h" #include "prot.h" diff --git a/lib_com/modif_fs.c b/lib_com/modif_fs.c index c0f3c56ce..f1ae7c61d 100644 --- a/lib_com/modif_fs.c +++ b/lib_com/modif_fs.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "prot.h" diff --git a/lib_com/options.h b/lib_com/options.h index b70e22adf..d78e638bb 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -47,18 +47,140 @@ /* ################### Start DEBUGGING switches ########################### */ +#ifndef RELEASE +#define DEBUGGING /* Activate debugging part of the code */ +#endif /*#define WMOPS*/ /* 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 */ /*#define MEM_COUNT_DETAILS*/ /* Output detailed memory analysis for the worst-case frame (writes to the file "mem_analysis.csv") */ +#ifdef DEBUGGING + +/*#define DEBUG_MODE_INFO*/ /* output most important parameters to the subdirectory "res/" */ +#ifdef DEBUG_MODE_INFO +/*#define DEBUG_MODE_ACELP*/ /* output most important ACELP core parameters to the subdirectory "res/" */ +/*#define DEBUG_MODE_TCX*/ /* output most important TCX core parameters to the subdirectory "res/" */ +/*#define DEBUG_MODE_DFT*/ /* output most important DFT stereo parameters to the subdirectory "res/" */ +/*#define DEBUG_MODE_TD*/ /* output most important TD stereo parameters to the subdirectory "res/ */ +/*#define DEBUG_MODE_DIRAC*/ /* output most important DIRAC parameters to the subdirectory "res/" */ +/*#define DEBUG_MODE_MDCT*/ /* output most important MDCT parameters to the subdirectory "res/" */ +/*#define DEBUG_MODE_PARAM_MC*/ /* output Parametric MC paramters to the subdirectory "res/" */ +/*#define DEBUG_MODE_PARAM_ISM*/ /* output Parametric ISM paramters to the subdirectory "res/" */ +/*#define DEBUG_MODE_INFO_TWEAK*/ /* enable command line switch to specify subdirectory for debug info output inside "./res/" */ +/*#define DEBUG_MODE_INFO_PLC */ /* define to output PLC related parameters */ +/*#define DEBUG_MODE_INFO_ALLRAD*/ /* define to output generated HOA decoding mtx */ +/*#define DEBUG_MODE_LFE */ /* define to output LFE relevant parameters */ +#endif + +#ifdef DEBUG_MODE_MDCT +#define DEBUG_PLOT_BITS +#endif + +#define ENABLE_BITRATE_VERIFICATION /* Enable bitrate verification - use when playing with bit budget */ +/*#define DEBUG_PLOT*/ +/*#define ALLOW_BYTE_EP*/ /* allow byte fer pattern files and check fer pattern file validity */ +#define WRAP_AS_EIDXOR /* wraps FER file (as in STL_eid-xor.c/softbit.c) */ + +/*#define DEBUG_FORCE_MDCT_STEREO_MODE*/ /* Force stereo mode decision for MDCT stereo: -stereo 3 1 forces L/R coding and -stereo 3 2 forces full M/S coding */ +/*#define DEBUG_STEREO_DFT_NOCORE*/ /* DFT stereo: by-pass core coder at decoder side*/ +/*#define DEBUG_STEREO_DFT_NOSTEREO*/ /* DFT stereo: by-pass stereo processing at encoder and decoder side*/ +/*#define DEBUG_STEREO_DFT_NOQRES*/ +/*#define DEBUG_STEREO_DFT_OUTRESPRED*/ /* output residual prediction signal instead of L/R*/ + +/*DirAC Debug switches*/ +/*#define DEBUG_DISABLE_DIRAC_DELAY_COMP */ /* temporarily disable delay compensation on DirAC encoder */ +/*#define DEBUG_BS_READ_WRITE*/ +/*#define DEBUG_MODE_DIRAC_NOCORE*/ +/*#define DEBUG_MODE_QMETADATA*/ /* output q_metadata parameters */ + +/*MCT Debug switches*/ +/*#define DEBUG_FORCE_MCT_CP*/ /* force MCT Stereo pairs for verification with SPAR */ +#ifdef DEBUG_FORCE_MCT_CP +/*#define DEBUG_SINGLE_CODE_OMNI*/ /* force 3 TC SBA always code W channel separately */ +#endif + +/*PLC Debug switches*/ +/*#define DEBUG_NO_TONAL_PLC*/ +/*#define DEBUG_NO_TD_TCX_PLC */ +/*#define DEBUG_FORCE_TD_TCX_CONCEALMENT*/ +/*#define DEBUG_PLC_INFO*/ + +/*#define DEBUG_EFAP_POLY_TOFILE*/ /* Write poly_select values to file in EFAP, used for generating ROM LUTs */ +/*#define TDREND_HRTF_TABLE_METHODS*/ /* Enable HRTF lookup from tables, for testing & evaluation. Supply file in table format to use. Note that a suitable HR filter lookup method should be written if the filters sample point grids are not in the formats. */ +/*#define TDREND_STANDALONE*/ /* Used when renderer is built in standalone form, without IVAS encoding/decoding (see scripts/object_renderer_standalone). This is just here to ensure this is cleaned out by prepare_instrumentation.sh */ + +/*#define DEBUG_SBA*/ /* debug DIRAC/SPAR in-out */ +#ifdef DEBUG_SBA +/*#define DEBUG_LBR_SBA*/ /* debug low bitrate SBA (SPAR+DirAC) */ +/*#define DEBUG_SBA_AUDIO_DUMP*/ /* SBA intermediate audio wav file dumping */ +/*#define DEBUG_SBA_MD_DUMP*/ /* SBA metadata and variable file dumping */ +/*#define DEBUG_SPAR_MD_TARGET_TUNING*/ /* SPAR MD target bitrate tuning debug code */ +/*#define DEBUG_SPAR_BYPASS_EVS_CODEC*/ /* bypass EVS coding in float precision, emulating EVS encoder/decoder delay */ +/*#define DEBUG_SPAR_WRITE_OUT_COV*/ /* write covariance per frame into a text file for verification */ +/*#define DEBUG_SPAR_DIRAC_WRITE_OUT_PRED_PARS*//* Log SPAR Prediction coefficients to a text file for verification */ +/*#define DEBUG_AGC*/ /* debug SPAR AGC in-out */ +#endif +/*#define SPAR_HOA_DBG*/ /* SPAR HOA debug statements */ +/* #define DEBUG_OSBA */ +/*#define DEBUG_BINAURAL_FILTER_DESIGN*/ /* debugging of Crend binaural filter design */ +/*#define DEBUG_AGC_ENCODER_CMD_OPTION*/ /* Ability to force enable or disable AGC behaviour in DIRAC/SPAR via command line option */ +/*#define DEBUG_JBM_CMD_OPTION*/ /* ability for telling the decoder the frontend fetch size and to not delay compensate for bad frames at the beginning */ +/*#define VARIABLE_SPEED_DECODING*/ /* variable speed decoding employing the JBM functioniality; move to DEBUGGING after build for disabled is fixed */ + +/*Split Rendering Debug switches*/ +/*#define DBG_WAV_WRITER*/ /* add debugging function dbgwrite_wav() */ +/*#define SPLIT_REND_WITH_HEAD_ROT_DEBUG*/ /* debugging switch for split rendering */ +/*#define SPLIT_POSE_CORRECTION_DEBUG*/ /* debugging switch for split rendering pose correction */ +/*#define SPLIT_MD_CODING_DEBUG*/ /* debugging switch for split rendering metadata coding */ + +#endif /* DEBUGGING */ /* #################### End DEBUGGING switches ############################ */ +/* keep as part of options.h */ #define BASOP_NOGLOB /* Disable global symbols in BASOPs, Overflow/Carry in BASOPs disabled, additional BASOPs in case of Overflow */ +/* ################## Start DEVELOPMENT switches ######################### */ + +/* ################### Start BE switches ################################# */ +/* only BE switches wrt selection floating point code */ + +/*#define FIX_I4_OL_PITCH*/ /* fix open-loop pitch used for EVS core switching */ +#define SPLIT_REND_WITH_HEAD_ROT /* Dlb,FhG: Split Rendering contributions 21 and 35 */ + +#define FIX_902_HACK_IN_CORECODER /* VA: issue 902: remove a hack in ivas_core_dec() */ +#define FIX_881_REMOVE_LFE_ADDITION_IN_ISM /* VA: issue 881: remove LFE addition in ISM format */ +#define FIX_887_ARRAY_SIZE_DFT_MDCT_STEREO /* VA: Fix the definition of buffers/arrays in DFT and MDCT stereo to satisfy gcc v 11.4.0 */ +#define FIX_891_PARAMUPMIX_CLEANUP /* Dlb: issue 891: remove unneeded code from ParamUpmix */ + +/* #################### End BE switches ################################## */ + +/* #################### Start NON-BE switches ############################ */ +/* any switch which is non-be wrt selection floating point code */ +/* all switches in this category should start with "NONBE_" */ + +#define NONBE_FIX_856_TCX_LTP_SYNTH_FILTER /* FhG: issue 856: correct filtering length for tcx-ltp synth filtering*/ +#define NONBE_UNIFIED_DECODING_PATHS /* FhG: unify decoding paths */ +#ifdef NONBE_UNIFIED_DECODING_PATHS +#define NONBE_UNIFIED_DECODING_PATHS_FIX /* VA: issue 876: fixes within NONBE_UNIFIED_DECODING_PATHS */ +#endif +#define NONBE_FIX_874_OMASA_BRSW_2TD /* Nokia: issue 874: Fixes the crashes with the long test vectors that prompted switching to TD*/ +#define NONBE_FIX_871_ACELP_CRASH_IN_OSBA /* FhG: isse 871: crash in ACELP core encoder with OSBA */ +#define NONBE_FIX_906_SBA_LBR_SMOOTHING /* FhG: issue #906: fix SBA low bit rate smoothing for HOA2/HOA3 output */ +#define NONBE_FIX_878_RS_FEC_STEREO_CNG /* Eri: Frame loss and Unified Stereo CNG may cause false BER detection which results in corrupt bitstream decoding */ +#define NONBE_FIX_904_JBM_SBA_RS_FOA /* FhG: issue #904: fix JBM SBA RS to FOA decoding */ +#define NONBE_FIX_898_ISM_BRATE_CRASH /* VA: issue 898: fix decoder crash in ISM bitrate switching with DTX and binaural output */ +#define NONBE_FIX_862_UBSAN_SPAR_DEC_BR_SW_PLC /* DLB: issue 862 : UBSAN: out-of-bound error in SPAR for OSBA bitrate switching with PLC*/ +#define NONBE_FIX_DISCRETE_ISM_NOISE_SEED_HANDLING /* FhG: fix handling of common and differing noise seeds in SCEs for ISM DTX */ +#define NONBE_FIX_913_OMASA_BITBUDGET_VIOLATION /* VA/Nok: issue 913: Resolve "Crash in OMASA encoder - DFT-Stereo bit-budget violated" */ + + +/* ##################### End NON-BE switches ########################### */ + +/* ################## End DEVELOPMENT switches ######################### */ /* clang-format on */ diff --git a/lib_com/parameter_bitmaping.c b/lib_com/parameter_bitmaping.c index 720324b1e..d722c8a3b 100644 --- a/lib_com/parameter_bitmaping.c +++ b/lib_com/parameter_bitmaping.c @@ -37,6 +37,9 @@ #include #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "stat_com.h" #include "prot.h" #include "wmc_auto.h" diff --git a/lib_com/phase_dispersion.c b/lib_com/phase_dispersion.c index eeecc7aaa..a89b98c15 100644 --- a/lib_com/phase_dispersion.c +++ b/lib_com/phase_dispersion.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "prot.h" #include "rom_com.h" diff --git a/lib_com/ppp.c b/lib_com/ppp.c index d9e553124..882c94b69 100644 --- a/lib_com/ppp.c +++ b/lib_com/ppp.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "prot.h" #include "rom_com.h" diff --git a/lib_com/pred_lt4.c b/lib_com/pred_lt4.c index 51a0227ea..832c7d0dc 100644 --- a/lib_com/pred_lt4.c +++ b/lib_com/pred_lt4.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "rom_com.h" #include "prot.h" diff --git a/lib_com/preemph.c b/lib_com/preemph.c index 024ad379c..5e5eb2341 100644 --- a/lib_com/preemph.c +++ b/lib_com/preemph.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "prot.h" #include "wmc_auto.h" diff --git a/lib_com/prot.h b/lib_com/prot.h index a032dcf7e..c795d97f2 100644 --- a/lib_com/prot.h +++ b/lib_com/prot.h @@ -41,6 +41,9 @@ #include #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "typedef.h" #include "stat_enc.h" #include "stat_dec.h" @@ -463,23 +466,53 @@ void delay_signal( const int16_t delay /* i : delay in samples */ ); +#ifdef DEBUG_BS_READ_WRITE +#define push_indice( ... ) push_indice_( __VA_ARGS__, __LINE__, __func__ ) +ivas_error push_indice_( +#else ivas_error push_indice( +#endif BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ int16_t id, /* i : ID of the indice */ uint16_t value, /* i : value of the quantized indice */ int16_t nb_bits /* i : number of bits used to quantize the indice */ +#ifdef DEBUG_BS_READ_WRITE + , + int16_t line, + const char *func +#endif ); +#ifdef DEBUG_BS_READ_WRITE +#define push_next_indice( ... ) push_next_indice_( __VA_ARGS__, __LINE__, __func__ ) +ivas_error push_next_indice_( +#else ivas_error push_next_indice( +#endif BSTR_ENC_HANDLE hBstr, uint16_t value, /* i : value of the quantized indice */ int16_t nb_bits /* i : number of bits used to quantize the indice */ +#ifdef DEBUG_BS_READ_WRITE + , + int16_t line, + const char *func +#endif ); +#ifdef DEBUG_BS_READ_WRITE +#define push_next_bits( ... ) push_next_bits_( __VA_ARGS__, __LINE__, __func__ ) +ivas_error push_next_bits_( +#else ivas_error push_next_bits( +#endif BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ const uint16_t bits[], /* i : bit buffer to pack, sequence of single bits */ const int16_t nb_bits /* i : number of bits to pack */ +#ifdef DEBUG_BS_READ_WRITE + , + int16_t line, + const char *func +#endif ); /*! r: maximum number of indices */ @@ -530,9 +563,19 @@ uint16_t delete_indice( ); /*! r: value of the indice */ +#ifdef DEBUG_BS_READ_WRITE +#define get_next_indice( ... ) get_next_indice_( __VA_ARGS__, __LINE__, __func__ ) +uint16_t get_next_indice_( +#else uint16_t get_next_indice( +#endif Decoder_State *st, /* i/o: decoder state structure */ int16_t nb_bits /* i : number of bits that were used to quantize the indice */ +#ifdef DEBUG_BS_READ_WRITE + , + int16_t line, + const char *func +#endif ); /*! r: value of the indice */ @@ -546,10 +589,20 @@ void get_next_indice_tmp( ); /*! r: value of the indice */ +#ifdef DEBUG_BS_READ_WRITE +#define get_indice( ... ) get_indice_( __VA_ARGS__, __LINE__, __func__ ) +uint16_t get_indice_( +#else uint16_t get_indice( +#endif Decoder_State *st, /* i/o: decoder state structure */ int16_t pos, /* i : absolute position in the bitstream */ int16_t nb_bits /* i : number of bits that were used to quantize the indice */ +#ifdef DEBUG_BS_READ_WRITE + , + int16_t line, + const char *func +#endif ); /*! r: value of the indice */ @@ -589,6 +642,14 @@ ivas_error read_indices( int16_t bfi /* i : bad frame indicator */ ); +#ifdef DEBUGGING +/*! r: 1 = reading OK, 0 = problem */ +ivas_error preview_indices( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + uint16_t bit_stream[], /* i : bitstream buffer */ + UWord16 num_bits /* i : number of bits in bitstream */ +); +#endif void ivas_set_bitstream_pointers( Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ @@ -660,6 +721,10 @@ int32_t get_delay( const int32_t io_fs, /* i : input/output sampling frequency */ const IVAS_FORMAT ivas_format, /* i : IVAS format */ HANDLE_CLDFB_FILTER_BANK hCldfb /* i : Handle of Cldfb analysis */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + const AUDIO_CONFIG output_config /* i : decoder output config */ +#endif ); void decision_matrix_enc( @@ -1695,6 +1760,9 @@ void hq_configure( int16_t hvq_enc( BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ const int16_t bwidth, /* i : audio bandwidth */ +#ifdef DEBUGGING + const int16_t idchan, /* i : channel ID */ +#endif const int32_t core_brate, /* i : core bitrate */ const int16_t hvq_bits, /* i : HVQ bit budget */ const int16_t Npeaks, /* i : Number of peaks */ @@ -2060,6 +2128,9 @@ Word32 encode_magnitude_usq_fx( ivas_error tcq_core_LR_enc( BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ +#ifdef DEBUGGING + const int16_t idchan, +#endif int32_t inp_vector[], const float coefs_norm[], float coefs_quant[], @@ -2152,6 +2223,9 @@ void io_ini_enc( FILE **f_rate, /* o : bitrate switching profile (0 if N/A) */ FILE **f_bwidth, /* o : bandwidth switching profile (0 if N/A) */ FILE **f_metadata, /* o : metadata files (NULL if N/A) */ +#ifdef DEBUGGING + FILE **f_force, /* o : force switching profile (0 if N/A) */ +#endif FILE **f_rf, /* o : channel aware configuration file */ int16_t *quietMode, /* o : limit printouts */ int16_t *noDelayCmp, /* o : turn off delay compensation */ @@ -2182,6 +2256,13 @@ void read_next_bwidth( int32_t input_Fs /* i : input sampling rate */ ); +#ifdef DEBUGGING +void read_next_force( + int16_t *force, /* i/o: force value (0/1, 0 = speech, 1 = music)*/ + FILE *f_force, /* i : force switching profile (0 if N/A) */ + int32_t *force_profile_cnt /* i/o: counter of frames for force switching profile file */ +); +#endif ivas_error init_encoder( Encoder_State *st, /* i/o: state structure */ @@ -2231,7 +2312,9 @@ void pre_proc( float **inp, /* o : ptr. to inp. signal in the current frame*/ float fr_bands[2 * NB_BANDS], /* i : energy in frequency bands */ float *ener, /* o : residual energy from Levinson-Durbin */ +#ifndef FIX_I4_OL_PITCH int16_t pitch_orig[3], /* o : open-loop pitch values for quantization */ +#endif float A[NB_SUBFR16k * ( M + 1 )], /* i/o: A(z) unquantized for the 4 subframes */ float Aw[NB_SUBFR16k * ( M + 1 )], /* i/o: weighted A(z) unquantized for subframes */ float epsP[M + 1], /* i/o: LP prediction errors */ @@ -6114,6 +6197,9 @@ void reverse_transient_frame_energies( int16_t peak_vq_enc( BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ const int16_t bwidth, /* i : audio bandwidth */ +#ifdef DEBUGGING + const int16_t idchan, /* i : channel ID */ +#endif const float *coefs, /* i : Input coefficient vector */ float *coefs_out, /* o : Quantized output vector */ const int32_t core_brate, /* i : Core bitrate */ diff --git a/lib_com/pvq_com.c b/lib_com/pvq_com.c index 7a13fe3f5..2368f8436 100644 --- a/lib_com/pvq_com.c +++ b/lib_com/pvq_com.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "rom_com.h" diff --git a/lib_com/range_com.c b/lib_com/range_com.c index 7b3ca8d5e..b01dc7156 100644 --- a/lib_com/range_com.c +++ b/lib_com/range_com.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "rom_com.h" #include "prot.h" diff --git a/lib_com/re8_ppv.c b/lib_com/re8_ppv.c index 75e78ebec..f6c5ab681 100644 --- a/lib_com/re8_ppv.c +++ b/lib_com/re8_ppv.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "prot.h" #include "wmc_auto.h" diff --git a/lib_com/re8_util.c b/lib_com/re8_util.c index d0737c9d9..d23ae1c0c 100644 --- a/lib_com/re8_util.c +++ b/lib_com/re8_util.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include /* for ldexp() */ #include "cnst.h" #include "rom_com.h" diff --git a/lib_com/realft.c b/lib_com/realft.c index 10a08fbf8..b7a3fef0d 100644 --- a/lib_com/realft.c +++ b/lib_com/realft.c @@ -37,6 +37,9 @@ #include "cnst.h" #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "prot.h" #include "wmc_auto.h" diff --git a/lib_com/recovernorm.c b/lib_com/recovernorm.c index 5b02843c0..52e9edcd2 100644 --- a/lib_com/recovernorm.c +++ b/lib_com/recovernorm.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "prot.h" #include "cnst.h" #include "rom_com.h" diff --git a/lib_com/reordvct.c b/lib_com/reordvct.c index 7655220d5..182050bfb 100644 --- a/lib_com/reordvct.c +++ b/lib_com/reordvct.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "prot.h" #include "wmc_auto.h" diff --git a/lib_com/residu.c b/lib_com/residu.c index a46001c26..e220d81c0 100644 --- a/lib_com/residu.c +++ b/lib_com/residu.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "prot.h" #include "rom_com.h" diff --git a/lib_com/rom_com.c b/lib_com/rom_com.c index 2282b0b3d..f08f41a1d 100644 --- a/lib_com/rom_com.c +++ b/lib_com/rom_com.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "rom_com.h" #include "prot.h" diff --git a/lib_com/rom_com.h b/lib_com/rom_com.h index f5e2eef1d..ad234e26d 100644 --- a/lib_com/rom_com.h +++ b/lib_com/rom_com.h @@ -39,6 +39,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "stat_enc.h" #include "stat_dec.h" #include "stl.h" diff --git a/lib_com/stab_est.c b/lib_com/stab_est.c index 2b11c7f5f..63466220c 100644 --- a/lib_com/stab_est.c +++ b/lib_com/stab_est.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "rom_com.h" diff --git a/lib_com/stat_com.h b/lib_com/stat_com.h index a3e139c18..90203dc47 100644 --- a/lib_com/stat_com.h +++ b/lib_com/stat_com.h @@ -42,6 +42,9 @@ #include "options.h" #include "typedef.h" #include "cnst.h" +#ifdef DEBUGGING +#include "debug.h" +#endif /* Forward declaration of Decoder_State */ struct Decoder_State; diff --git a/lib_com/stat_noise_uv_mod.c b/lib_com/stat_noise_uv_mod.c index b269b3fb0..83c2d321c 100644 --- a/lib_com/stat_noise_uv_mod.c +++ b/lib_com/stat_noise_uv_mod.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "prot.h" #include "wmc_auto.h" diff --git a/lib_com/swb_bwe_com.c b/lib_com/swb_bwe_com.c index f879d274b..4efbaa735 100644 --- a/lib_com/swb_bwe_com.c +++ b/lib_com/swb_bwe_com.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "prot.h" diff --git a/lib_com/swb_bwe_com_hr.c b/lib_com/swb_bwe_com_hr.c index 937660f23..fbdcf70b9 100644 --- a/lib_com/swb_bwe_com_hr.c +++ b/lib_com/swb_bwe_com_hr.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "prot.h" #include "wmc_auto.h" diff --git a/lib_com/swb_bwe_com_lr.c b/lib_com/swb_bwe_com_lr.c index ef3af7ae3..daa7d1673 100644 --- a/lib_com/swb_bwe_com_lr.c +++ b/lib_com/swb_bwe_com_lr.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "prot.h" diff --git a/lib_com/swb_tbe_com.c b/lib_com/swb_tbe_com.c index fb1382ae4..768078e27 100644 --- a/lib_com/swb_tbe_com.c +++ b/lib_com/swb_tbe_com.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "prot.h" diff --git a/lib_com/syn_12k8.c b/lib_com/syn_12k8.c index 7d670e1a3..15892f62c 100644 --- a/lib_com/syn_12k8.c +++ b/lib_com/syn_12k8.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "prot.h" #include "wmc_auto.h" diff --git a/lib_com/syn_filt.c b/lib_com/syn_filt.c index 9b766c1bc..08e687c12 100644 --- a/lib_com/syn_filt.c +++ b/lib_com/syn_filt.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "prot.h" #include "rom_com.h" diff --git a/lib_com/tcq_position_arith.c b/lib_com/tcq_position_arith.c index a1a2d39ab..306f29a60 100644 --- a/lib_com/tcq_position_arith.c +++ b/lib_com/tcq_position_arith.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "prot.h" #include "rom_com.h" diff --git a/lib_com/tcx_ltp.c b/lib_com/tcx_ltp.c index b92c0b607..502328348 100644 --- a/lib_com/tcx_ltp.c +++ b/lib_com/tcx_ltp.c @@ -37,6 +37,9 @@ #include #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "prot.h" #include "rom_com.h" #include "wmc_auto.h" @@ -737,7 +740,11 @@ static void tcx_ltp_synth_filter_11_unequal_pitch( gain = prev_gain; gain_step = -prev_gain / length; +#ifdef NONBE_FIX_856_TCX_LTP_SYNTH_FILTER for ( j = 0; j < length; j++ ) +#else + for ( j = 0; j < length + L; j++ ) +#endif { s = 0; s2 = 0; @@ -758,9 +765,14 @@ static void tcx_ltp_synth_filter_11_unequal_pitch( gain += gain_step; } +#ifdef NONBE_FIX_856_TCX_LTP_SYNTH_FILTER mvr2r( out - L, temp_buf, length + L ); mvr2r( in + length, temp_buf + length + L, L ); temp_ptr = &temp_buf[0] + L; +#else + mvr2r( out - MAX_TCX_LTP_FILTER_LEN, temp_buf, MAX_TRANSITION_LEN + 2 * MAX_TCX_LTP_FILTER_LEN ); + temp_ptr = &temp_buf[0] + MAX_TCX_LTP_FILTER_LEN; +#endif m0 = temp_ptr; m1 = temp_ptr - 1; diff --git a/lib_com/tcx_mdct_window.c b/lib_com/tcx_mdct_window.c index 05a70cdc9..0ef69587a 100644 --- a/lib_com/tcx_mdct_window.c +++ b/lib_com/tcx_mdct_window.c @@ -37,6 +37,9 @@ #include #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "prot.h" diff --git a/lib_com/tcx_utils.c b/lib_com/tcx_utils.c index a96c19e11..ec219456b 100644 --- a/lib_com/tcx_utils.c +++ b/lib_com/tcx_utils.c @@ -37,6 +37,9 @@ #include #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "rom_com.h" diff --git a/lib_com/tools.c b/lib_com/tools.c index a30895bac..ecd2fdbfa 100644 --- a/lib_com/tools.c +++ b/lib_com/tools.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "prot.h" #include "wmc_auto.h" diff --git a/lib_com/trans_direct.c b/lib_com/trans_direct.c index cc63ce39f..964ba36f7 100644 --- a/lib_com/trans_direct.c +++ b/lib_com/trans_direct.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "prot.h" #include "rom_com.h" diff --git a/lib_com/trans_inv.c b/lib_com/trans_inv.c index 5b4d485af..1eea807b2 100644 --- a/lib_com/trans_inv.c +++ b/lib_com/trans_inv.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "rom_com.h" diff --git a/lib_com/weight.c b/lib_com/weight.c index 619857178..6c2e1c291 100644 --- a/lib_com/weight.c +++ b/lib_com/weight.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "rom_com.h" #include "prot.h" diff --git a/lib_com/weight_a.c b/lib_com/weight_a.c index 5b5619eec..96b8014e4 100644 --- a/lib_com/weight_a.c +++ b/lib_com/weight_a.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "prot.h" #include "wmc_auto.h" diff --git a/lib_com/window.c b/lib_com/window.c index a54cb7c07..093dbd4fc 100644 --- a/lib_com/window.c +++ b/lib_com/window.c @@ -37,6 +37,9 @@ #include #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "prot.h" #define WMC_TOOL_SKIP diff --git a/lib_com/window_ola.c b/lib_com/window_ola.c index 8d1b98e38..07798af16 100644 --- a/lib_com/window_ola.c +++ b/lib_com/window_ola.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "rom_com.h" diff --git a/lib_com/wtda.c b/lib_com/wtda.c index ec7bc080a..3bd839e5a 100644 --- a/lib_com/wtda.c +++ b/lib_com/wtda.c @@ -36,11 +36,17 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "prot.h" #include "rom_com.h" #include #include "wmc_auto.h" +#ifdef DEBUG_PLOT +#include "deb_out.h" +#endif /*--------------------------------------------------------------------------* * mvr2r_inv() @@ -284,6 +290,9 @@ void wtda( { allsig_r = new_audio + n; allsig_l = new_audio + n - L; +#ifdef DEBUG_PLOT + sendDebout( "tcx_mdct", 2 * L, 1, "mdct_sig", MTV_FLOAT, allsig_l ); +#endif } else { diff --git a/lib_debug/debug.c b/lib_debug/debug.c new file mode 100644 index 000000000..736f35d43 --- /dev/null +++ b/lib_debug/debug.c @@ -0,0 +1,978 @@ +/****************************************************************************************************** + + (C) 2022-2023 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. + +*******************************************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#ifdef DEBUG_MODE_INFO +#ifdef DEBUG_MODE_INFO_TWEAK +#include +#include +#endif +#endif +#endif +#include "cnst.h" +#include +#include +#include +#ifdef _WIN32 +#include +#else +#endif +#ifdef DBG_WAV_WRITER +#include "tinywaveout_c.h" +#endif +#include "wmc_auto.h" + + +/*-------------------------------------------------------------------* + * Global variables used for debugging but not under DEBUGGING flag + *--------------------------------------------------------------------*/ + +#ifdef DEBUGGING +uint16_t g_nPrintedLines = 0; + +int16_t g_verbose = 0; /* global variable for debugging */ +#ifdef DEBUG_MODE_INFO +#ifdef DEBUG_MODE_INFO_TWEAK +char infoFolder[FILENAME_MAX]; +#endif +#endif +#endif + +FILE *DJB_delay = NULL; /* per-frame de-jitter buffer delay dump out file */ + +#ifdef DEBUGGING +int16_t debug_level = 0; +#endif + +/*-------------------------------------------------------------------* + * Read/write I/O tool + *--------------------------------------------------------------------*/ + +#ifdef DEBUGGING +#define N_FILEPTR 500 +#define N_DBGFLAG 100 +#define N_DBGVAL 100 +#define N_TYPES 6 + +static FILE *in_fileptr[N_FILEPTR]; +static FILE *out_fileptr[N_FILEPTR]; +#ifdef DBG_WAV_WRITER +static WAVEFILEOUT *out_wavfileptr[N_FILEPTR]; +#endif +static char *in_filename[N_FILEPTR]; +static char *out_filename[N_FILEPTR]; +#ifdef DBG_WAV_WRITER +static char *out_wavfilename[N_FILEPTR]; +#endif +static int16_t in_count = 0; +static int16_t out_count = 0; +#ifdef DBG_WAV_WRITER +static int16_t out_wav_count = 0; +#endif + +static int16_t flag_count = 0; +static char *flag_name[N_DBGFLAG]; +static int16_t val_count = 0; +static char *val_name[N_DBGVAL]; +static char *val[N_DBGVAL]; + +static char *type_list[N_TYPES] = { "char", "short", "int", "long", "float", "double" }; + +static void setvalue( + const char *value_name, /* i : Value name */ + const char *value /* i : Value as string */ +); + +static int16_t make_dirs( const char *const pathname ); + +/*-------------------------------------------------------------------* + * dbgwrite() + * + * Writes the buffer content to the specified file. If the file is not in the + * debug file list, it is opened before write. + *--------------------------------------------------------------------*/ + +int16_t dbgwrite( + const void *const buffer, /* i : Write buffer */ + const int16_t size, /* i : Element size */ + const int16_t count, /* i : Number of elements */ + const int16_t repeat, /* i : Number of times the elements are repeated */ +#ifdef DEBUG_MODE_INFO_TWEAK + const char *filename /* i : Output file name */ +#else + const char *const filename +#endif +) +{ + int16_t index, i; + void *tmp_buf; + +#ifdef DEBUG_MODE_INFO +#ifdef DEBUG_MODE_INFO_TWEAK + char filename_mod[FILENAME_MAX]; + int16_t textmode = 0; + int16_t x = *(const int16_t *const) buffer; /* currently the textmode is only defined with "short" as input */ + memset( filename_mod, 0, FILENAME_MAX ); + tweakdbgfolder( filename, filename_mod, &textmode ); + if ( filename_mod[0] != 0 ) + { + filename = filename_mod; + } +#endif +#endif + + index = lookup( filename, (const char *const *) out_filename, out_count ); + + if ( index == -1 ) + { + if ( make_dirs( filename ) != 0 ) + { + fprintf( stderr, "dbgwrite: Could not create directory structure for %s. Exiting..\n", filename ); + exit( -1 ); + } + + index = out_count; + out_fileptr[index] = fopen( filename, "wb" ); + out_filename[index] = malloc( sizeof( char ) * ( strlen( filename ) + 1 ) ); + strcpy( out_filename[index], filename ); + out_count++; + } + + if ( out_fileptr[index] != NULL ) + { + tmp_buf = calloc( count * repeat, size ); + if ( buffer != NULL ) + { + for ( i = 0; i < repeat; i++ ) + { + memcpy( (char *) tmp_buf + i * size * count, buffer, size * count ); + } + } +#ifdef DEBUG_MODE_INFO +#ifdef DEBUG_MODE_INFO_TWEAK + if ( 1 == textmode && 2 == size ) + { /* currently the textmode is only defined with "short" as input */ + fprintf( out_fileptr[index], "%d\n", x ); + } + else + { +#endif +#endif + fwrite( tmp_buf, size * count * repeat, 1, out_fileptr[index] ); +#ifdef DEBUG_MODE_INFO +#ifdef DEBUG_MODE_INFO_TWEAK + } +#endif +#endif + free( tmp_buf ); + } + else + { + fprintf( stderr, "dbgwrite: Could not write to file: %s. Exiting..\n", filename ); + exit( -1 ); + } + + return 0; +} + + +/*-------------------------------------------------------------------* + * dbgwrite_mat_repeat() + * + * Writes buffer a buffer containing a column-wise ordered matrix + * to the specified file. If the file is not in the + * debug file list, it is opened before write. + *--------------------------------------------------------------------*/ + +void dbgwrite_mat_repeat( float *buffer, /* i : write buffer */ + int16_t nRow, /* i : matrix size (rows) */ + int16_t mCol, /* i : matrix size (columns) */ + int16_t row_repeat, /* i : number of times rows are repeated */ + int16_t col_repeat, /* i : number of times columns are repeated */ +#ifdef DEBUG_MODE_INFO_TWEAK + const char *filename /* i : Output file name */ +#else + const char *const filename +#endif +) +{ + float *copy_buffer = calloc( nRow * row_repeat * mCol * col_repeat, sizeof( float ) ); + int16_t r, c, rr, cc; + float *cp = ©_buffer[0]; + float *colp; + for ( c = 0; c < mCol; c++ ) + { + for ( cc = 0; cc < col_repeat; cc++ ) + { + colp = buffer + c * nRow; + for ( r = 0; r < nRow; r++ ) + { + for ( rr = 0; rr < row_repeat; rr++ ) + { + *( cp++ ) = *colp; + } + colp++; + } + } + } + + dbgwrite( copy_buffer, sizeof( float ), nRow * row_repeat * mCol * col_repeat, 1, filename ); + free( copy_buffer ); +} + + +/*-------------------------------------------------------------------* + * dbgappend() + * + * Appends the buffer content to the specified file. If the file is not in the + * debug file list, it is opened before first write. + *--------------------------------------------------------------------*/ + +int16_t dbgappend( + const void *const buffer, /* i : Append buffer */ + const int16_t size, /* i : Element size */ + const int16_t count, /* i : Number of elements */ + const int16_t repeat, /* i : Number of times the elements are repeated */ +#ifdef DEBUG_MODE_INFO_TWEAK + const char *filename /* i : Output file name */ +#else + const char *const filename +#endif +) +{ + int16_t index, i; + +#ifdef DEBUG_MODE_INFO +#ifdef DEBUG_MODE_INFO_TWEAK + char filename_mod[FILENAME_MAX]; + int16_t textmode = 0; /* textmode is only implemented in dbgwrite() currently */ + memset( filename_mod, 0, FILENAME_MAX ); + tweakdbgfolder( filename, filename_mod, &textmode ); + if ( filename_mod[0] != 0 ) + { + filename = filename_mod; + } +#endif +#endif + index = lookup( filename, (const char *const *) out_filename, out_count ); + + if ( index == -1 ) + { + if ( make_dirs( filename ) != 0 ) + { + fprintf( stderr, "dbgwrite: Could not create directory structure for %s. Exiting..\n", filename ); + exit( -1 ); + } + + index = out_count; + out_fileptr[index] = fopen( filename, "ab" ); + out_filename[index] = malloc( sizeof( char ) * ( strlen( filename ) + 1 ) ); + strcpy( out_filename[index], filename ); + out_count++; + } + + if ( out_fileptr[index] != NULL ) + { + for ( i = 0; i < repeat; i++ ) + { + fwrite( buffer, size, count, out_fileptr[index] ); + } + } + else + { + fprintf( stderr, "dbgappend: Could not write to file: %s. Exiting..\n", filename ); + exit( -1 ); + } + + return 0; +} + +/*-------------------------------------------------------------------* + * dbgread() + * + * Reads data from the specified file. If the file is not open, it will be + * opened. + *--------------------------------------------------------------------*/ + +int16_t dbgread( + void *const buffer, /* o : Read buffer */ + const int16_t size, /* i : Element size */ + const int16_t count, /* i : Number of elements */ +#ifdef DEBUG_MODE_INFO_TWEAK + const char *filename /* i : Input file name */ +#else + const char *const filename +#endif +) +{ + int16_t index; + +#ifdef DEBUG_MODE_INFO +#ifdef DEBUG_MODE_INFO_TWEAK + char filename_mod[FILENAME_MAX]; + int16_t textmode = 0; /* textmode is only implemented in dbgwrite() currently */ + memset( filename_mod, 0, FILENAME_MAX ); + tweakdbgfolder( filename, filename_mod, &textmode ); + if ( filename_mod[0] != 0 ) + { + filename = filename_mod; + } +#endif +#endif + + index = lookup( filename, (const char *const *) in_filename, in_count ); + + if ( index == -1 ) + { + index = in_count; + in_fileptr[index] = fopen( filename, "rb" ); + in_filename[index] = malloc( sizeof( char ) * ( strlen( filename ) + 1 ) ); + strcpy( in_filename[index], filename ); + in_count++; + } + + if ( in_fileptr[index] != NULL ) + { + fread( buffer, size, count, in_fileptr[index] ); + } + else + { + fprintf( stderr, "dbgread: Could not read from file: %s. Exiting..\n", filename ); + exit( -1 ); + } + + return 0; +} + +/*-------------------------------------------------------------------* + * dbgclose() + * + * Closes opened files and frees allocated memory + *--------------------------------------------------------------------*/ + +void dbgclose( void ) +{ + int16_t i; + + for ( i = 0; i < in_count; i++ ) + { + fclose( in_fileptr[i] ); + free( in_filename[i] ); + } + + for ( i = 0; i < out_count; i++ ) + { + fclose( out_fileptr[i] ); + free( out_filename[i] ); + } + +#ifdef DBG_WAV_WRITER + for ( i = 0; i < out_wav_count; i++ ) + { + CloseWav( out_wavfileptr[i] ); + free( out_wavfilename[i] ); + } +#endif + for ( i = 0; i < snr_count; i++ ) + { + free( snr_name[i] ); + } + + for ( i = 0; i < flag_count; i++ ) + { + free( flag_name[i] ); + } + + for ( i = 0; i < val_count; i++ ) + { + free( val_name[i] ); + free( val[i] ); + } + + return; +} + + +/*-------------------------------------------------------------------* + * dbgflag() + * + * Checks if a debug flag is set. The flag is identified with a string. + *--------------------------------------------------------------------*/ + +int16_t dbgflag( + const char *flagname /* i : Flag name */ +) +{ + int16_t result; + + result = lookup( flagname, (const char *const *) flag_name, flag_count ); + + return ( result != -1 ); +} + +/*-------------------------------------------------------------------* + * setflag() + * + * Sets the flag with the specified string + *--------------------------------------------------------------------*/ + +void setflag( + const char *flagname /* i : Flag name */ +) +{ + int16_t result; + + result = lookup( flagname, (const char *const *) flag_name, flag_count ); + + if ( result == -1 ) + { + flag_name[flag_count] = malloc( sizeof( char ) * ( strlen( flagname ) + 1 ) ); + strcpy( flag_name[flag_count], flagname ); + flag_count++; + } + + return; +} + +/*----------------------------------------------------------------------------* + * dbgargs() + * + * N.B. Should be run before existing command line interpretation + * + * Command line interpreter for debug arguments. Removes the debug + * arguments after interpretation so that existing command line interpretation + * may be run afterwards. + * + * Arguments: + * -D flag_name Sets the debug flag labelled flag_name. + * The function dbgflag("flag_name") will return 1. + * + * -V val_name val Sets the debug value labelled val_name to val. + * dbgvalue("type","val_name",&value) will retrieve the value + * + *-----------------------------------------------------------------------------*/ + +/*! r: No. debug arguments */ +int16_t dbgargs( + int32_t *argc, /* i/o: No. input arguments / No. arguments without dbg arguments */ + char *argv[] /* i/o: Input arguments / Input arguments without dbg arguments */ +) +{ + int16_t i, j, dbgargs; + + i = 0; + dbgargs = 0; + while ( i < *argc ) + { + if ( strcmp( argv[i], "-D" ) == 0 ) + { + j = i; + dbgargs++; + i++; + setflag( argv[i] ); + for ( ; j < *argc - 2; j++ ) + { + argv[j] = argv[j + 2]; + } + *argc -= 2; + i -= 2; + } + + if ( strcmp( argv[i], "-V" ) == 0 ) + { + j = i; + dbgargs++; + i++; + setvalue( argv[i], argv[i + 1] ); + for ( ; j < *argc - 3; j++ ) + { + argv[j] = argv[j + 3]; + } + *argc -= 3; + i -= 3; + } + i++; + } + + return dbgargs; +} + +/*-------------------------------------------------------------------* + * dbgvalue() + * + * Lookup a debug value + * + * Allowed typestr values: + * "char","short","int","long","float","double" + * + * If the value is not set, the output value is not assigned + * + *-------------------------------------------------------------------*/ + +/*! r: Returns 1 if value is assigned, otherwise 0 */ +int16_t dbgvalue( + const char *typestr, /* i : Type as string:"int","char",... */ + const char *value_name, /* i : Value tag name given on command line */ + ... /* o : Output variable, type: pointer to "typestr" */ +) +{ + int16_t index; + char *value; + int16_t assigned; + char *c; + int16_t *sh; + int *i; + int32_t *l; + float *f; + double *d; + va_list ap; + va_start( ap, value_name ); + + index = lookup( value_name, (const char *const *) val_name, val_count ); + + if ( index != -1 ) + { + value = val[index]; + index = lookup( typestr, (const char *const *) type_list, N_TYPES ); + switch ( index ) + { + case 0: + c = va_arg( ap, char * ); + sscanf( value, "%c", c ); + break; + case 1: + sh = va_arg( ap, int16_t * ); + sscanf( value, "%hi", sh ); + break; + case 2: + i = va_arg( ap, int * ); + sscanf( value, "%i", i ); + break; + case 3: + l = va_arg( ap, int32_t * ); + sscanf( value, "%i", l ); + break; + case 4: + f = va_arg( ap, float * ); + sscanf( value, "%f", f ); + break; + case 5: + d = va_arg( ap, double * ); + sscanf( value, "%lf", d ); + break; + default: + fprintf( stderr, "dbgvalue::Unsupported type string %s. Exiting...\n", typestr ); + exit( -1 ); + } + assigned = 1; + } + else + { + assigned = 0; + } + + va_end( ap ); + + return assigned; +} + +/*-------------------------------------------------------------------* + * lookup() + * + * Returns the index of the given string, or -1 if not found + *--------------------------------------------------------------------*/ + +/*! r: Index of string, -1 if not found */ +int16_t lookup( + const char *const str, /* i : String to lookup */ + const char *const *const list, /* i : List of strings */ + const int16_t n_elem /* i : Number of elements */ +) +{ + int16_t i, result; + + result = -1; + i = 0; + while ( i < n_elem && result == -1 ) + { + if ( strcmp( str, list[i] ) == 0 ) + { + result = i; + } + i++; + } + + return result; +} + +/*-------------------------------------------------------------------* + * setvalue() + * + * Sets the debug name value pair + *--------------------------------------------------------------------*/ + +static void setvalue( + const char *value_name, /* i : Value name */ + const char *value ) /* i : Value as string */ + +{ + int16_t result; + + result = lookup( value_name, (const char *const *) val_name, val_count ); + + if ( result == -1 ) + { + val_name[val_count] = malloc( sizeof( char ) * ( strlen( value_name ) + 1 ) ); + strcpy( val_name[val_count], value_name ); + val[val_count] = malloc( sizeof( char ) * ( strlen( value ) + 1 ) ); + strcpy( val[val_count], value ); + val_count++; + fprintf( stdout, "\nDebug value set: %s = %s\n", value_name, value ); + } + else + { + fprintf( stdout, "\n*** Value %s already set: %s\n", value_name, val[result] ); + } + + return; +} + +#ifdef DEBUG_MODE_INFO +#ifdef DEBUG_MODE_INFO_TWEAK +/*-------------------------------------------------------------------* + * tweakdbgfolder() + * + * in: filename + * out: filename_mod + * + * returns modified path to debug files for reading and writing functions. + * creates in "./res" if given on command line + * with switch -info . + * + *--------------------------------------------------------------------*/ + +int16_t tweakdbgfolder( const char *filename, char *filename_mod, int16_t *textmode ) +{ + int16_t i, j; + char *p_infoFolder = infoFolder; + char *p_filename_mod = filename_mod; + int16_t n_prefix = 0; + char *suffix; + + /* if debug folder name given on command line, write debug info to sub folder */ + if ( infoFolder[0] != 0 ) + { + if ( filename[0] == '.' ) + { + n_prefix = 5; + } + else if ( filename[0] == 'r' ) + { + n_prefix = 3; + } + else + { + fprintf( stderr, "tweakdbgfolder: Unexpected debug folder. Exiting..\n" ); + exit( -1 ); + } + for ( i = 0; i <= n_prefix; i++ ) + { + p_filename_mod[i] = filename[i]; + } + j = i; + while ( *p_infoFolder != 0 ) + { + p_filename_mod[i] = *p_infoFolder; + i++; + p_infoFolder++; + } + p_filename_mod[i] = '/'; + i++; + + while ( filename[j] != 0 ) + { + p_filename_mod[i] = filename[j]; + i++; + j++; + } + /* detect textmode, only working with given debug folder name, otherwise no counter available for length of filename */ + suffix = &p_filename_mod[i - 4]; + if ( strncmp( suffix, ".txt", 4 ) == 0 ) + { + *textmode = 1; + } + else + { + *textmode = 0; + } + } + + + return 0; +} +#endif +#endif + + +#ifdef DEBUG_MODE_INFO +/*-------------------------------------------------------------------* + * fname() + * + * returns file name (string) that identifies - parameter/signal to be outputted + - channel ID (0 or 1) + - element ID (0, 1, etc.) + *--------------------------------------------------------------------*/ + +char debug_dir[6] = "res/"; + +char tmp_fname[FILENAME_MAX]; + +char *fname( + char *dir, + char *file, + const int16_t n, + const int16_t id, + const int16_t enc_dec ) +{ + char idd[5] = ".idX"; + idd[3] = (char) ( id + '0' ); + + strcpy( tmp_fname, dir ); + strcat( tmp_fname, file ); + + if ( enc_dec == DEC ) + strcat( tmp_fname, ".dec" ); + if ( id > 0 ) + strcat( tmp_fname, idd ); + if ( n > 0 ) + strcat( tmp_fname, ".ch2" ); + + return tmp_fname; +} +#endif + + +/*-------------------------------------------------------------------* + * make_dirs() + * + * extract path(s) form the pathname and create them if not existing + *--------------------------------------------------------------------*/ + +int16_t make_dirs( const char *const pathname ) +{ + const char *p; + char *temp; + char sep = 0; +#ifdef _WIN32 + struct _stat s = { 0 }; +#else + struct stat s = { 0 }; +#endif + /* find path separator */ + if ( strchr( pathname, '\\' ) != NULL ) + { + sep = '\\'; + } + else if ( strchr( pathname, '/' ) != NULL ) + { + sep = '/'; + } + + if ( sep != 0 ) + { + temp = calloc( 1, strlen( pathname ) + 1 ); + p = pathname; + while ( ( p = strchr( p, sep ) ) != NULL ) + { + /* skip consecutive separators and '.', '..' symbols */ + if ( p != pathname && ( *( p - 1 ) == sep || *( p - 1 ) == '.' ) ) + { + p++; + continue; + } + + /* put the path up to this point into a temp dir */ + memcpy( temp, pathname, p - pathname ); + temp[p - pathname] = '\0'; + p++; + + /* check if path exists and create it with mkdir() if not */ +#ifdef _WIN32 + if ( _stat( temp, &s ) == -1 ) + { + if ( _mkdir( temp ) != 0 ) + { + if ( errno != 0 ) + { + return 1; + } + } + } +#else + if ( stat( temp, &s ) == -1 ) + { + if ( mkdir( temp, 0755 ) != 0 ) + { + if ( errno != 0 ) + { + return 1; + } + } + } +#endif + } + + free( temp ); + } + + return 0; +} + +#ifdef DBG_WAV_WRITER +int16_t dbgwrite_wav( + const float *buffer[], /* i : Write buffer */ + const int16_t count_per_ch, /* i : Number of elements */ + const char *const filename, + int32_t fs, + int16_t num_chs ) +{ + int16_t index, i; + int16_t *tmp_buf; + + index = lookup( filename, (const char *const *) out_wavfilename, out_wav_count ); + + if ( index == -1 ) + { + if ( make_dirs( filename ) != 0 ) + { + fprintf( stderr, "dbgwrite: Could not create directory structure for %s. Exiting..\n", filename ); + exit( -1 ); + } + + index = out_wav_count; + out_wavfileptr[index] = CreateWav( (const char *) filename, fs, num_chs, 16 /* const uint32_t writeWaveExt */ ); + out_wavfilename[index] = malloc( sizeof( char ) * ( strlen( filename ) + 1 ) ); + strcpy( out_wavfilename[index], filename ); + out_wav_count++; + } + + if ( out_wavfileptr[index] != NULL ) + { + int16_t j, k; + float tmp; + tmp_buf = (int16_t *) calloc( count_per_ch * num_chs, sizeof( int16_t ) ); + k = 0; + for ( j = 0; j < count_per_ch; j++ ) + { + for ( i = 0; i < num_chs; i++, k++ ) + { + tmp = roundf( buffer[i][j] ); + tmp_buf[k] = ( tmp > MAX16B_FLT ) ? MAX16B : ( tmp < MIN16B_FLT ) ? MIN16B + : (short) tmp; + } + } + WriteWavShort( out_wavfileptr[index], tmp_buf, count_per_ch * num_chs ); + free( tmp_buf ); + } + else + { + fprintf( stderr, "dbgwrite_wav: Could not write to file: %s. Exiting..\n", filename ); + exit( -1 ); + } + + return 0; +} + + +int16_t dbgwrite_txt( + const float *buffer, /* i : Write buffer */ + const int16_t count, /* i : Number of elements */ + const char *const filename, + const char *const msg_opt ) +{ + int16_t index, i; + + index = lookup( filename, (const char *const *) out_filename, out_count ); + + if ( index == -1 ) + { + if ( make_dirs( filename ) != 0 ) + { + fprintf( stderr, "dbgwrite: Could not create directory structure for %s. Exiting..\n", filename ); + exit( -1 ); + } + + index = out_count; + out_fileptr[index] = fopen( filename, "w" ); + out_filename[index] = malloc( sizeof( char ) * ( strlen( filename ) + 1 ) ); + strcpy( out_filename[index], filename ); + out_count++; + } + + if ( out_fileptr[index] != NULL ) + { + if ( buffer != NULL ) + { + if ( msg_opt == NULL ) + { + for ( i = 0; i < count; i++ ) + { + fprintf( out_fileptr[index], "%f\n", buffer[i] ); + } + } + else + { + for ( i = 0; i < count; i++ ) + { + fprintf( out_fileptr[index], "%s %f\n", msg_opt, buffer[i] ); + } + } + } + } + else + { + fprintf( stderr, "dbgwrite_txt: Could not write to file: %s. Exiting..\n", filename ); + exit( -1 ); + } + + return 0; +} +#endif +#endif /* DEBUGGING */ diff --git a/lib_debug/debug.h b/lib_debug/debug.h new file mode 100644 index 000000000..ac2ac689b --- /dev/null +++ b/lib_debug/debug.h @@ -0,0 +1,257 @@ +/****************************************************************************************************** + + (C) 2022-2023 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 DEBUG_H +#define DEBUG_H + +#include "options.h" +#include +#include +#ifdef DEBUG_SBA +#include "sba_debug.h" +#endif + +/*------------------------------------------------------------------------------------------* + * Global variables used for debugging + *------------------------------------------------------------------------------------------*/ + +#ifdef DEBUGGING +extern int32_t frame; +#endif + +#ifdef DEBUGGING +extern uint16_t g_nPrintedLines; +extern int16_t g_verbose; +#endif + +#ifdef DEBUGGING +extern int16_t debug_level; +#define DEBUG_LINE( level ) if ( ( level ) <= debug_level ) +#else +#define DEBUG_LINE( level ) if ( 0 ) +#endif + +#ifdef DEBUG_MODE_INFO +extern char tmp_fname[]; +extern char debug_dir[6]; +char *fname( char *dir, char *file, const int16_t n, const int16_t id, const int16_t enc_dec ); +#endif + +/*------------------------------------------------------------------------------------------* + * Read/write I/O tool + *------------------------------------------------------------------------------------------*/ + +#ifdef DEBUGGING + +int16_t lookup( + const char *const str, + const char *const *const list, + const int16_t n_elem ); + +#ifdef DEBUG_MODE_INFO +#ifdef DEBUG_MODE_INFO_TWEAK +int16_t tweakdbgfolder( + const char *filename, + char *filename_mod, + int16_t *textmode ); +#endif +#endif + +int16_t dbgwrite( + const void *const buffer, + const int16_t size, + const int16_t count, + const int16_t repeat, +#ifdef DEBUG_MODE_INFO_TWEAK + const char *filename +#else + const char *const filename +#endif +); + +#ifdef DBG_WAV_WRITER +int16_t dbgwrite_wav( + const float *buffer[], /* i : Write buffer */ + const int16_t count_per_ch, /* i : Number of elements */ + const char *const filename, + int32_t fs, + int16_t num_chs ); +int16_t dbgwrite_txt( + const float *buffer, /* i : Write buffer */ + const int16_t count, /* i : Number of elements */ + const char *const filename, + const char *const msg_opt ); +#endif +void dbgwrite_mat_repeat( + float *buffer, /* i : write buffer */ + int16_t nRow, /* i : matrix size (rows) */ + int16_t mCol, /* i : matrix size (columns) */ + int16_t row_repeat, /* i : number of times rows are repeated */ + int16_t col_repeat, /* i : number of times columns are repeated */ +#ifdef DEBUG_MODE_INFO_TWEAK + const char *filename /* i : Output file name */ +#else + const char *const filename +#endif +); + +int16_t dbgappend( + const void *const buffer, + const int16_t size, + const int16_t count, + const int16_t repeat, +#ifdef DEBUG_MODE_INFO_TWEAK + const char *filename +#else + const char *const filename +#endif +); + +int16_t dbgread( + void *const buffer, + const int16_t size, + const int16_t count, +#ifdef DEBUG_MODE_INFO_TWEAK + const char *filename +#else + const char *const filename +#endif +); + +void dbgclose( void ); + +int16_t dbgflag( + const char *flagname ); + +void setflag( + const char *flagname ); + +int16_t dbgargs( + int32_t *argc, + char *argv[] ); + +int16_t dbgvalue( + const char *typestr, + const char *value_name, + ... ); + +extern FILE *DJB_delay; + +extern FILE *FEC_pattern; + +#endif /* DEBUGGING */ + +/*------------------------------------------------------------------------------------------* + * SNR measurement tool + *------------------------------------------------------------------------------------------*/ + +#ifdef DEBUGGING + +extern int16_t snr_count; +extern char *snr_name[]; + +void snr( + const float *const signal, + const float *const noise, + const int16_t length, + const char *const name ); + +void snr_diff( + const float *const clean, + const float *const degraded, + const int16_t length, + const int16_t delay, + const char *const name ); + +void snr_celp( + const int16_t L_frame, + const int16_t L_subfr, + const float gamma, + const float tilt_fac, + const int16_t vad_flag, + const int16_t coder_type, + const float *input, + const float *output, + const float *A, + const int16_t idchan, + const char *name ); + +void print_snr( void ); + +#else + +#define print_snr( void ) + +#endif + +/*------------------------------------------------------------------------------------------* + * SD analysis tool + *------------------------------------------------------------------------------------------*/ + +#ifdef DEBUGGING + +/*! r: SD in a given frequency range */ +float sd_range( + const float lsf[], /* i : vector of unquantized LSF values */ + const float lsf_q[], /* i : vector of quantized LSF values */ + const int16_t order, /* i : dimension of the vectors */ + const int32_t fs, /* i : sampling frequency */ + const float min_freq, /* i : minimum frequency of interest */ + const float max_freq, /* i : maximum frequency of interest */ + const char *const name, /* i : string for SD entry in the global table */ + const int16_t Opt_AMR_WB /* i : flag indicating AMR-WB IO mode */ +); + +/*! r: SD respecting critical bands */ +float sd_crit( + const float lsf[], /* i : vector of unquantized LSF values */ + const float lsf_q[], /* i : vector of quantized LSF values */ + const int16_t order, /* i : dimension of the vectors */ + const int32_t fs, /* i : sampling frequency */ + const float min_freq, /* i : minimal frequency */ + const float max_freq, /* i : maximal frequency */ + int16_t *min_band, /* o : minimal critical band */ + int16_t *max_band, /* o : maximal critical band */ + float sd_bands[], /* i/o: SD in critical bands */ + const char *const name, /* i : string for SD entry in the global table */ + const int16_t Opt_AMR_WB /* i : flag indicating AMR-WB IO mode */ +); + +void print_sd( void ); + +#else + +#define print_sd( void ) + +#endif + +#endif /* DEBUG_H */ diff --git a/lib_debug/sba_debug.c b/lib_debug/sba_debug.c new file mode 100644 index 000000000..de4b549aa --- /dev/null +++ b/lib_debug/sba_debug.c @@ -0,0 +1,431 @@ +/****************************************************************************************************** + + (C) 2022-2023 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. + +*******************************************************************************************************/ + +#include +#include +#include +#include +#include +#include "options.h" +#include "ivas_cnst.h" +#include "sba_debug.h" +#include +#include "wmc_auto.h" +#ifdef DEBUG_SBA +#include +#include "tinywaveout_c.h" + +/*-------------------------------------------------------------------* + * Global variables used for debugging but not under DEBUGGING flag + *--------------------------------------------------------------------*/ + +#define MAX_IN_FILE_LEN ( 1000 ) +#define MAX_PLUG_IN_FILE_LEN ( MAX_IN_FILE_LEN ) +#define MAX_DEBUG_TAG_LEN ( 50 ) +#define NUM_DEBUG_FILES ( 5 ) +#define MAX_TAG_LEN ( 200 ) + +WAVEFILEOUT *spar_foa_enc_wav[3]; +WAVEFILEOUT *spar_foa_dec_wav[NUM_DEBUG_FILES]; +float max_diff = 0; +int32_t dbg_frm_num; +int32_t dbg_band; +int32_t dbg_type; +int32_t iter_max = 0; +FILE *fFb_pcm = NULL; +int8_t file_names[NUM_DEBUG_FILES][MAX_TAG_LEN + MAX_DEBUG_TAG_LEN]; + + +#ifdef DEBUG_AGC +FILE *agcOut = NULL; /* temporary AGC bitstream */ +#endif + +/*-----------------------------------------------------------------------------------------* + * Function description + * cstrcpy() - Custom implementation of strcpy + * + * Inputs: + * const char* _Source -> Source buffer + * _SizeInBytes -> Destination buffer size in bytes + * + * Outputs: + * char* _Destination -> Destination buffer + *-----------------------------------------------------------------------------------------*/ + +static void cstrcpy( char *_Destination, size_t _SizeInBytes, const char *_Source ) +{ + size_t SourceSizeInBytes = strlen( _Source ); + if ( _SizeInBytes > SourceSizeInBytes ) + { + strcpy( _Destination, _Source ); + } + else + { + assert( 0 ); + } + + return; +} + + +/*-----------------------------------------------------------------------------------------* + * Function description + * cstrcat() - Custom implementation of strcat + * + * Inputs: + * const char* _Source -> Source buffer + * _SizeInBytes -> Destination buffer size in bytes + * + * Outputs: + * char* _Destination -> Destination buffer + *-----------------------------------------------------------------------------------------*/ + +static void cstrcat( char *_Destination, size_t _SizeInBytes, const char *_Source ) +{ + size_t SourceSizeInBytes = strlen( _Source ); + size_t DestSizeInBytes = _SizeInBytes - strlen( _Destination ); + if ( DestSizeInBytes > SourceSizeInBytes ) + { + strcat( _Destination, _Source ); + } + else + { + assert( 0 ); + } + + return; +} + + +#ifdef DEBUG_AGC +void ivas_close_agc_debug_files( void ) +{ + if ( agcOut != NULL ) + { + fclose( agcOut ); + agcOut = NULL; + } + + return; +} + +void ivas_open_agc_debug_files( int16_t agc ) +{ + /* Temporary AGC file */ + if ( agc > 0 ) + { + char agcFilename[50] = "agcBitstream.bin"; + if ( ( agcOut = fopen( agcFilename, "wb" ) ) == NULL ) + { + fprintf( stderr, "Error: Gain Control bitstream file %s could not be opened\n\n", agcFilename ); + exit( -1 ); + } + fprintf( stdout, "Temporary gain control bitstream file %s is opened\n", agcFilename ); + } + + return; +} +#endif + +static void UpdateWave( + const uint32_t sampleRate, + const uint32_t numChannels, + const uint32_t bps, + WAVEFILEOUT *spar_wav ) +{ + uint32_t blockAlignment = 0; + uint16_t writeValue16; + uint32_t writeValue32; + + writeValue16 = LittleEndian16( (int16_t) numChannels ); + /*Fseek to number of channel writing position*/ + fseek( spar_wav->theFile, 22, SEEK_SET ); + fwrite( &writeValue16, sizeof( writeValue16 ), 1, spar_wav->theFile ); + blockAlignment = numChannels * ( bps >> 3 ); + writeValue16 = LittleEndian16( (int16_t) blockAlignment ); + fseek( spar_wav->theFile, 4, SEEK_CUR ); + writeValue32 = LittleEndian32( sampleRate * blockAlignment ); + fwrite( &writeValue32, sizeof( writeValue32 ), 1, spar_wav->theFile ); + fwrite( &writeValue16, sizeof( writeValue16 ), 1, spar_wav->theFile ); + + return; +} + + +void ivas_spar_dump_signal_wav( + const int16_t input_frame, + float **ppPcm, + float pcm_array[IVAS_SPAR_MAX_CH][L_FRAME48k], + const int16_t no_channel, + WAVEFILEOUT *wave_file, + char *location ) +{ + float tmp_value; + int16_t pcm_value, i, j, k; + int16_t debug_tmp[IVAS_SPAR_MAX_CH * L_FRAME48k * 2]; + + k = 0; + int16_t Clipping = 0; + float largest_value = 0; + float db_value = 0; + + for ( j = 0; j < input_frame; j++ ) + { + for ( i = 0; i < no_channel; i++, k++ ) + { + if ( ppPcm ) + { + tmp_value = roundf( ppPcm[i][j] ); + } + else + { + tmp_value = roundf( pcm_array[i][j] ); + } + + if ( tmp_value > MAX16B_FLT ) + { + largest_value = (float) fabs( tmp_value ) > largest_value ? (float) fabs( tmp_value ) : largest_value; + tmp_value = MAX16B; + Clipping++; + } + else if ( tmp_value < MIN16B_FLT ) + { + largest_value = (float) fabs( tmp_value ) > largest_value ? (float) fabs( tmp_value ) : largest_value; + tmp_value = MIN16B; + Clipping++; + } + pcm_value = (int16_t) tmp_value; + /*pcm_value = (tmp_value > MAX16B_FLT) ? MAX16B : (tmp_value < MIN16B_FLT) ? MIN16B + : (short)tmp_value;*/ + debug_tmp[k] = pcm_value; + } + } + if ( Clipping ) + { + db_value = 20.f * (float) log( largest_value ); + fprintf( stderr, "%d\t Clipping detected ", Clipping ); + } + + WriteWavShort( wave_file, debug_tmp, ( no_channel * input_frame ) ); + + if ( db_value ) + { + fprintf( stderr, "\t In %s largest clipped sample in dB %f \n", location, db_value ); + } + + return; +} + + +void ivas_close_sba_decoder_debug_files( + const int32_t fs, + const int16_t n_ch, + const int16_t n_transport, + const int16_t pca_ingest_channels ) +{ + if ( spar_foa_dec_wav[0] != NULL ) + { + UpdateWave( fs, n_transport, 32, spar_foa_dec_wav[0] ); + CloseWav( spar_foa_dec_wav[0] ); + } + if ( spar_foa_dec_wav[1] != NULL ) + { + UpdateWave( fs, n_transport, 16, spar_foa_dec_wav[1] ); + CloseWav( spar_foa_dec_wav[1] ); + } + if ( spar_foa_dec_wav[2] != NULL ) + { + UpdateWave( fs, pca_ingest_channels, 16, spar_foa_dec_wav[2] ); + CloseWav( spar_foa_dec_wav[2] ); + } + if ( spar_foa_dec_wav[3] != NULL ) + { + UpdateWave( fs, n_ch, 16, spar_foa_dec_wav[3] ); + CloseWav( spar_foa_dec_wav[3] ); + } + + if ( spar_foa_dec_wav[4] != NULL ) + { + UpdateWave( fs, n_ch, 16, spar_foa_dec_wav[4] ); + CloseWav( spar_foa_dec_wav[4] ); + } + + return; +} + + +void ivas_close_sba_encoder_debug_files( void ) +{ + + if ( spar_foa_enc_wav[0] != NULL ) + { + CloseWav( spar_foa_enc_wav[0] ); + } + if ( spar_foa_enc_wav[1] != NULL ) + { + CloseWav( spar_foa_enc_wav[1] ); + } + if ( spar_foa_enc_wav[2] != NULL ) + { + CloseWav( spar_foa_enc_wav[2] ); + } + + /* Enable print max diff to a file */ + + /* FILE *fp = fopen("max_diff.txt", "a"); + fprintf(fp, "%s\n", file_names[0]); + fprintf(fp, "max diff = %0.15f\n frame_no = %d\n band num = %d\n coeff type %d\n", max_diff, dbg_frm_num, dbg_band, dbg_type); + fclose(fp); */ + + /* Enable print max eig iters to a file */ + + /*FILE *fp = fopen("max_iters.txt", "a"); + fprintf(fp, "%s\n", file_names[0]); + fprintf(fp, "%d\n", iter_max); + fclose(fp); */ + + return; +} + + +void ivas_open_sba_decoder_debug_files( + const int32_t fs, + const int16_t n_ch, + const int16_t n_transport ) +{ + int8_t fb_wav_dump_path[NUM_DEBUG_FILES][MAX_PLUG_IN_FILE_LEN] = { "", "", "", "", "" }; + + cstrcat( (char *) fb_wav_dump_path[0], sizeof( fb_wav_dump_path[0] ), "dec_out.wav" ); + spar_foa_dec_wav[0] = CreateWav( (const char *) fb_wav_dump_path[0], fs, n_ch, 32 /* const uint32_t writeWaveExt */ ); + + cstrcat( (char *) fb_wav_dump_path[1], sizeof( fb_wav_dump_path[1] ), "agc_dec_out.wav" ); + spar_foa_dec_wav[1] = CreateWav( (const char *) fb_wav_dump_path[1], fs, n_transport, 16 /* const uint32_t writeWaveExt */ ); + + cstrcat( (char *) fb_wav_dump_path[2], sizeof( fb_wav_dump_path[2] ), "pca_dec.wav" ); + spar_foa_dec_wav[2] = CreateWav( (const char *) fb_wav_dump_path[2], fs, n_transport, 16 /* const uint32_t writeWaveExt */ ); + + cstrcat( (char *) fb_wav_dump_path[3], sizeof( fb_wav_dump_path[3] ), "cldfbSynthesis.wav" ); + spar_foa_dec_wav[3] = CreateWav( (const char *) fb_wav_dump_path[3], fs, n_transport, 16 /* const uint32_t writeWaveExt */ ); + + cstrcat( (char *) fb_wav_dump_path[4], sizeof( fb_wav_dump_path[4] ), "cldfbAnalysis.wav" ); + spar_foa_dec_wav[4] = CreateWav( (const char *) fb_wav_dump_path[4], fs, n_transport, 16 /* const uint32_t writeWaveExt */ ); + + return; +} + + +void ivas_open_sba_encoder_debug_files( + const int32_t fs, + const int16_t n_transport, + const char *file_tag, + const int32_t ivas_total_brate, + const int16_t dtx_on ) +{ + int8_t fb_wav_dump_path[3][MAX_PLUG_IN_FILE_LEN] = { "spar_foa_enc", "spar_foa_enc", "spar_foa_enc" }; + + if ( file_tag != NULL ) + { + cstrcpy( (char *) file_names[0], sizeof( file_names[0] ), (const char *) file_tag ); + } + + /* ivas_total_brate */ + switch ( ivas_total_brate ) + { + case IVAS_24k4: + cstrcat( (char *) file_names[0], sizeof( file_names[0] ), "_ivasbr24k" ); + break; + case IVAS_32k: + cstrcat( (char *) file_names[0], sizeof( file_names[0] ), "_ivasbr32k" ); + break; + case IVAS_48k: + cstrcat( (char *) file_names[0], sizeof( file_names[0] ), "_ivasbr48k" ); + break; + case IVAS_64k: + cstrcat( (char *) file_names[0], sizeof( file_names[0] ), "_ivasbr64k" ); + break; + case IVAS_80k: + cstrcat( (char *) file_names[0], sizeof( file_names[0] ), "_ivasbr80k" ); + break; + case IVAS_96k: + cstrcat( (char *) file_names[0], sizeof( file_names[0] ), "_ivasbr96k" ); + break; + case IVAS_128k: + cstrcat( (char *) file_names[0], sizeof( file_names[0] ), "_ivasbr128k" ); + break; + case IVAS_160k: + cstrcat( (char *) file_names[0], sizeof( file_names[0] ), "_ivasbr160k" ); + break; + case IVAS_192k: + cstrcat( (char *) file_names[0], sizeof( file_names[0] ), "_ivasbr192k" ); + break; + case IVAS_256k: + cstrcat( (char *) file_names[0], sizeof( file_names[0] ), "_ivasbr256k" ); + break; + case IVAS_384k: + cstrcat( (char *) file_names[0], sizeof( file_names[0] ), "_ivasbr384k" ); + break; + case IVAS_512k: + cstrcat( (char *) file_names[0], sizeof( file_names[0] ), "_ivasbr512k" ); + break; + } + + /* DTX */ + if ( dtx_on ) + { + cstrcat( (char *) file_names[0], sizeof( file_names[0] ), "_DTX1" ); + } + else + { + cstrcat( (char *) file_names[0], sizeof( file_names[0] ), "_DTX0" ); + } + + cstrcpy( (char *) file_names[1], sizeof( file_names[1] ), (const char *) file_names[0] ); + cstrcpy( (char *) file_names[2], sizeof( file_names[2] ), (const char *) file_names[0] ); + cstrcpy( (char *) file_names[3], sizeof( file_names[3] ), (const char *) file_names[0] ); + cstrcat( (char *) file_names[0], sizeof( file_names[0] ), "_pcm.txt" ); + + cstrcat( (char *) fb_wav_dump_path[0], sizeof( fb_wav_dump_path[0] ), (const char *) file_names[2] ); + cstrcat( (char *) fb_wav_dump_path[0], sizeof( fb_wav_dump_path[0] ), "_pca_enc.wav" ); + spar_foa_enc_wav[0] = CreateWav( (const char *) fb_wav_dump_path[0], fs, n_transport, 16 /* const uint32_t writeWaveExt */ ); + + cstrcat( (char *) fb_wav_dump_path[1], sizeof( fb_wav_dump_path[1] ), (const char *) file_names[2] ); + cstrcat( (char *) fb_wav_dump_path[1], sizeof( fb_wav_dump_path[1] ), "_fb_mixer_enc.wav" ); + spar_foa_enc_wav[1] = CreateWav( (const char *) fb_wav_dump_path[1], fs, n_transport, 16 /* const uint32_t writeWaveExt */ ); + + cstrcat( (char *) fb_wav_dump_path[2], sizeof( fb_wav_dump_path[2] ), (const char *) file_names[2] ); + cstrcat( (char *) fb_wav_dump_path[2], sizeof( fb_wav_dump_path[2] ), "_agc_enc.wav" ); + spar_foa_enc_wav[2] = CreateWav( (const char *) fb_wav_dump_path[2], fs, n_transport, 16 /* const uint32_t writeWaveExt */ ); + + return; +} + +#endif /* DEBUG_SBA */ diff --git a/lib_debug/sba_debug.h b/lib_debug/sba_debug.h new file mode 100644 index 000000000..a314d1568 --- /dev/null +++ b/lib_debug/sba_debug.h @@ -0,0 +1,61 @@ +/****************************************************************************************************** + + (C) 2022-2023 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 SBA_DEBUG_H +#define SBA_DEBUG_H + +#include "options.h" +#include +#include +#ifdef DEBUG_SBA +#include "cnst.h" +#include "ivas_cnst.h" +#include "tinywaveout_c.h" + + +#ifdef DEBUG_SBA_AUDIO_DUMP +extern WAVEFILEOUT *spar_foa_enc_wav[3]; +extern WAVEFILEOUT *spar_foa_dec_wav[5]; +#endif + +#ifdef DEBUG_AGC +void ivas_close_agc_debug_files( void ); +void ivas_open_agc_debug_files( int16_t agc ); +#endif +void ivas_spar_dump_signal_wav( const int16_t input_frame, float **ppPcm, float pcm_array[IVAS_SPAR_MAX_CH][L_FRAME48k], const int16_t no_channel, WAVEFILEOUT *wave_file, char *location ); +void ivas_close_sba_encoder_debug_files( void ); +void ivas_open_sba_encoder_debug_files( const int32_t fs, const int16_t n_transport, const char *file_tag, const int32_t ivas_total_brate, const int16_t dtx_on ); +void ivas_close_sba_decoder_debug_files( const int32_t fs, const int16_t n_ch, const int16_t n_transport, const int16_t pca_ingest_channels ); +void ivas_open_sba_decoder_debug_files( const int32_t fs, const int16_t n_ch, const int16_t n_transport ); +#endif + +#endif /* SBA_DEBUG_H */ diff --git a/lib_debug/snr.c b/lib_debug/snr.c new file mode 100644 index 000000000..3e817287c --- /dev/null +++ b/lib_debug/snr.c @@ -0,0 +1,465 @@ +/****************************************************************************************************** + + (C) 2022-2023 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. + +*******************************************************************************************************/ + +#include +#include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif +#include +#include +#include +#include "wmc_auto.h" +#include "cnst.h" +#include "ivas_cnst.h" + +#ifdef DEBUGGING + +/*-------------------------------------------------------------------* + * Local constants + *--------------------------------------------------------------------*/ + +#define N_SNRPTR 100 +#define MAX_SIGNAL_LENGTH 1024 +#define MAX_DELAY 320 + +/*-------------------------------------------------------------------* + * Global variables + *--------------------------------------------------------------------*/ + +int16_t snr_count = 0; +char *snr_name[N_SNRPTR] = { 0 }; + +#ifdef DEBUG_MODE_INFO +float snr_[2][320]; +#endif + +/*-------------------------------------------------------------------* + * Local variables + *--------------------------------------------------------------------*/ + +static double signal_energy[N_SNRPTR]; +static double noise_energy[N_SNRPTR]; +static double acc_seg_snr[N_SNRPTR]; +static int32_t seg_count[N_SNRPTR]; +static double acc_wseg_snr[N_SNRPTR]; +static double wseg_count[N_SNRPTR]; +static float *mem_delay_comp[N_SNRPTR] = { 0 }; +static float mem_deemph_x[MAX_INPUT_CHANNELS] = { 0 }; +static float mem_deemph_y[MAX_INPUT_CHANNELS] = { 0 }; +static float mem_synth_snr[MAX_INPUT_CHANNELS][M]; + + +/*-------------------------------------------------------------------* + * Local functions - they are copies of functions declared in prot.h but + here we do not want to include prot.h due to its dependencies + *--------------------------------------------------------------------*/ + +#ifdef DEBUG_MODE_INFO +static void set_f( + float y[], /* i/o: Vector to set */ + const float a, /* i : Value to set the vector to */ + const int16_t N /* i : Lenght of the vector */ +) +{ + int16_t i; + + for ( i = 0; i < N; i++ ) + { + y[i] = a; + } + + return; +} +#endif + +static float sum2_f( + const float *vec, /* i : input vector */ + const int16_t lvec /* i : length of input vector */ +) +{ + int16_t i; + float tmp; + + tmp = 0.0f; + for ( i = 0; i < lvec; i++ ) + { + tmp += vec[i] * vec[i]; + } + + return tmp; +} + + +static void mvr2r( + const float x[], /* i : input vector */ + float y[], /* o : output vector */ + const int16_t n /* i : vector size */ +) +{ + int16_t i; + + if ( n <= 0 ) + { + /* cannot transfer vectors with size 0 */ + return; + } + + if ( y < x ) + { + for ( i = 0; i < n; i++ ) + { + y[i] = x[i]; + } + } + else + { + for ( i = n - 1; i >= 0; i-- ) + { + y[i] = x[i]; + } + } + + return; +} + +static void residu( + const float *a, /* i : LP filter coefficients */ + const int16_t m, /* i : order of LP filter */ + const float *x, /* i : input signal (usually speech) */ + float *y, /* o : output signal (usually residual) */ + const int16_t l /* i : size of filtering */ +) +{ + float s; + int16_t i, j; + + for ( i = 0; i < l; i++ ) + { + s = x[i]; + for ( j = 1; j <= m; j++ ) + { + s += a[j] * x[i - j]; + } + y[i] = s; + } + + return; +} + +static void deemph( + float *signal, /* i/o: signal */ + const float mu, /* i : deemphasis factor */ + const int16_t L, /* i : vector size */ + float *mem /* i/o: memory (y[-1]) */ +) +{ + int16_t i; + + signal[0] = signal[0] + mu * ( *mem ); + for ( i = 1; i < L; i++ ) + { + signal[i] = signal[i] + mu * signal[i - 1]; + } + + *mem = signal[L - 1]; + + if ( ( *mem < 1e-10 ) & ( *mem > -1e-10 ) ) + { + *mem = 0; + } + + return; +} + +static void weight_a( + const float *a, /* i : LP filter coefficients */ + float *ap, /* o : weighted LP filter coefficients */ + const float gamma, /* i : weighting factor */ + const int16_t m /* i : order of LP filter */ +) +{ + float f; + int16_t i; + + ap[0] = a[0]; + f = gamma; + + for ( i = 1; i <= m; i++ ) + { + ap[i] = f * a[i]; + f *= gamma; + } + + return; +} + + +/*-------------------------------------------------------------------* + * snr() + * + * Calculates and accumulates SNR values for a signal specified with a + * certain string. The signal is input in segments having certain length, + * for which a global SNR, segmental SNR and weighted segmental SNR is computed. + *--------------------------------------------------------------------*/ + +void snr( + const float *const signal, + const float *const noise, + const int16_t length, + const char *const name ) +{ + int16_t index; + double signal_sumsq, noise_sumsq, frame_snr, seg_en; + + index = lookup( name, (const char *const *) snr_name, snr_count ); + if ( index == -1 ) + { + index = snr_count; + signal_energy[index] = 0; + noise_energy[index] = 0; + acc_seg_snr[index] = 0; + seg_count[index] = 0; + acc_wseg_snr[index] = 0; + wseg_count[index] = 0; + snr_name[index] = malloc( sizeof( char ) * ( strlen( name ) + 1 ) ); + strcpy( snr_name[index], name ); + snr_count++; + } + + signal_sumsq = sum2_f( signal, length ) + 0.001f; + noise_sumsq = sum2_f( noise, length ) + 0.001f; + if ( signal_sumsq < noise_sumsq ) + signal_sumsq = noise_sumsq; + frame_snr = 10 * log10( signal_sumsq / noise_sumsq ); + seg_en = 10 * log10( signal_sumsq / length ); + if ( seg_en < 0.0 ) + seg_en = 0.0; + + signal_energy[index] += signal_sumsq; + noise_energy[index] += noise_sumsq; + acc_seg_snr[index] += frame_snr; + seg_count[index]++; + acc_wseg_snr[index] += frame_snr * seg_en; + wseg_count[index] += seg_en; + + return; +} + + +/*-------------------------------------------------------------------* + * snr_diff() + * + * Calculates and accumulates SNR values for a signal specified with a + * certain string. The signal is input in segments having certain length, + * for which a global SNR, segmental SNR and weighted segmental SNR is computed. + * A delay between both signals is taken into account + * and compensated for (positive value means degraded signal is delayed). + *--------------------------------------------------------------------*/ + +void snr_diff( + const float *const clean, + const float *const degraded, + const int16_t length, + const int16_t delay, + const char *const name ) +{ + int16_t i, index; + float noise[MAX_SIGNAL_LENGTH], comp_buf[MAX_SIGNAL_LENGTH + MAX_DELAY]; + + if ( length > MAX_SIGNAL_LENGTH ) + { + fprintf( stdout, "snr_diff::Input segment too long. Exiting...\n" ); + exit( -1 ); + } + + if ( delay < 0 ) + { + fprintf( stdout, "snr_diff::Degraded signal cannot have negative delay. Exiting...\n" ); + exit( -1 ); + } + + /* search for the name in the database */ + index = (int16_t) lookup( name, (const char *const *) snr_name, snr_count ); + if ( index == -1 ) + { + index = (int16_t) snr_count; + signal_energy[index] = 0.0f; + noise_energy[index] = 0.0f; + acc_seg_snr[index] = 0.0f; + seg_count[index] = 0; + acc_wseg_snr[index] = 0.001f; + wseg_count[index] = 0.001f; + snr_name[index] = malloc( sizeof( char ) * ( strlen( name ) + 1 ) ); + mem_delay_comp[index] = calloc( delay, sizeof( float ) ); + strcpy( snr_name[index], name ); + snr_count++; + } + + /* delay compensation - introduction of delay to the clean signal */ + mvr2r( mem_delay_comp[index], comp_buf, delay ); + mvr2r( clean, comp_buf + delay, length ); + mvr2r( comp_buf + length, mem_delay_comp[index], delay ); + + for ( i = 0; i < length; i++ ) + { + noise[i] = comp_buf[i] - degraded[i]; + } + + snr( comp_buf, noise, length, name ); + + return; +} + + +/*-------------------------------------------------------------------* + * snr_celp() + * + * Calculates SNR, segmental SNR and weighted segmental SNR values for active + * frames (GENERIC, VOICED, TRANSITION and AUDIO) of CELP-coded signals. Both, the input and output + * signals are first converted to the perceptually weighted domain, subtracted to + * obtain the noise signal and de-emphasized. + *--------------------------------------------------------------------*/ + +void snr_celp( + const int16_t L_frame, + const int16_t L_subfr, + const float gamma, + const float tilt_fac, + const int16_t vad_flag, + const int16_t coder_type, + const float *input, + const float *output, + const float *A, + const int16_t idchan, + const char *name ) +{ + int16_t i; + float noise[L_FRAME16k], Ap[M + 1], x[L_FRAME16k], y[L_FRAME16k], synth_buf[M + L_FRAME16k], *synth; + const float *p_A; + int16_t j; +#ifdef DEBUG_MODE_INFO + float signal2, noise2, subframe_snr; +#endif + + synth = synth_buf + M; + mvr2r( mem_synth_snr[idchan], synth_buf, M ); + mvr2r( output, synth, L_frame ); + mvr2r( synth_buf + L_frame, mem_synth_snr[idchan], M ); + + p_A = A; + for ( i = 0; i < L_frame; i += L_subfr ) + { + weight_a( p_A, Ap, gamma, M ); + residu( Ap, M, &input[i], &x[i], L_subfr ); + residu( Ap, M, &synth[i], &y[i], L_subfr ); + p_A += ( M + 1 ); + + deemph( &x[i], tilt_fac, L_subfr, &mem_deemph_x[idchan] ); + deemph( &y[i], tilt_fac, L_subfr, &mem_deemph_y[idchan] ); + + for ( j = 0; j < L_subfr; j++ ) + { + noise[i + j] = x[i + j] - y[i + j]; + } + +#ifdef DEBUG_MODE_INFO + signal2 = sum2_f( &x[i], L_subfr ) + 0.001f; + noise2 = sum2_f( &noise[i], L_subfr ) + 0.001f; + if ( signal2 < noise2 ) + signal2 = noise2; + subframe_snr = 10.0f * log10f( signal2 / noise2 ); + + if ( L_frame == L_FRAME ) + { + set_f( snr_[idchan] + i * 5 / 4, subframe_snr, L_subfr * 5 / 4 ); + } + else + { + set_f( snr_[idchan] + i, subframe_snr, L_subfr ); + } +#endif + } + + if ( vad_flag == 1 && ( coder_type == GENERIC || coder_type == VOICED || coder_type == TRANSITION || coder_type == AUDIO ) ) + { + snr( x, noise, L_frame, name ); + } + + return; +} + +/*-------------------------------------------------------------------* + * print_snr() + * + * Finalizes and presents accumulated SNR data + *--------------------------------------------------------------------*/ + +void print_snr( void ) +{ + int16_t i; + double snr, segsnr, wsegsnr; + + if ( snr_count > 0 ) + { + fprintf( stdout, "\n --- SNR report --- \n" ); + + for ( i = 0; i < snr_count; i++ ) + { + snr = 10 * log10( signal_energy[i] / ( noise_energy[i] + 0.0001f ) ); + segsnr = acc_seg_snr[i] / ( seg_count[i] + 0.0001f ); + wsegsnr = acc_wseg_snr[i] / ( wseg_count[i] + 0.0001f ); + fprintf( stdout, "%-22s %6.3f dB SNR %6.3f dB SegSNR %6.3f dB WSegSNR\n", snr_name[i], snr, segsnr, wsegsnr ); + } + fprintf( stdout, "\n" ); + } + + /* free allocated memory */ + for ( i = 0; i < N_SNRPTR; i++ ) + { + if ( snr_name[i] ) + { + free( snr_name[i] ); + snr_name[i] = NULL; + } + + if ( mem_delay_comp[i] ) + { + free( mem_delay_comp[i] ); + mem_delay_comp[i] = NULL; + } + } + + return; +} + +#endif diff --git a/lib_dec/ACcontextMapping_dec.c b/lib_dec/ACcontextMapping_dec.c index cabbef7c2..5139106d9 100644 --- a/lib_dec/ACcontextMapping_dec.c +++ b/lib_dec/ACcontextMapping_dec.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "rom_com.h" #include "ivas_rom_com.h" @@ -491,6 +494,9 @@ int16_t RCcontextMapping_decode2_no_mem_s17_LCS( st->next_bit_pos = start_bit_pos + bits_tups + rc_uni_dec_virtual_finish( &rc_st_dec ); /* Confirm that there is no overflow */ +#ifdef DEBUGGING + assert( st->next_bit_pos - start_bit_pos + rest_bits <= 0 ); +#endif /* Store decoded data */ x[a1_i] = a; @@ -538,6 +544,9 @@ int16_t RCcontextMapping_decode2_no_mem_s17_LCS( assert( rc_st_dec.bit_error_detected == 0 ); /* Cross-check: No overflow */ +#ifdef DEBUGGING + assert( k == lastnz ); +#endif /* Decode signs */ n = nt; @@ -625,6 +634,9 @@ int16_t RCcontextMapping_decode2_no_mem_s17_LCS( st->next_bit_pos = start_bit_pos + bits_tups + rc_uni_dec_virtual_finish( &rc_st_dec ); /* Confirm that there is no overflow */ +#ifdef DEBUGGING + assert( st->next_bit_pos - start_bit_pos + rest_bits <= 0 ); +#endif /* Store decoded data */ x[k + 0] = a; diff --git a/lib_dec/FEC.c b/lib_dec/FEC.c index 31b05b390..c0db9325f 100644 --- a/lib_dec/FEC.c +++ b/lib_dec/FEC.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "rom_com.h" diff --git a/lib_dec/FEC_HQ_core.c b/lib_dec/FEC_HQ_core.c index edc1c2490..988689b76 100644 --- a/lib_dec/FEC_HQ_core.c +++ b/lib_dec/FEC_HQ_core.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "rom_dec.h" diff --git a/lib_dec/FEC_HQ_phase_ecu.c b/lib_dec/FEC_HQ_phase_ecu.c index 49e363608..28cafd473 100644 --- a/lib_dec/FEC_HQ_phase_ecu.c +++ b/lib_dec/FEC_HQ_phase_ecu.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "rom_dec.h" #include "rom_com.h" diff --git a/lib_dec/FEC_adapt_codebook.c b/lib_dec/FEC_adapt_codebook.c index 3ef001909..1200e2651 100644 --- a/lib_dec/FEC_adapt_codebook.c +++ b/lib_dec/FEC_adapt_codebook.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "rom_dec.h" diff --git a/lib_dec/FEC_clas_estim.c b/lib_dec/FEC_clas_estim.c index e514326be..d20760ddb 100644 --- a/lib_dec/FEC_clas_estim.c +++ b/lib_dec/FEC_clas_estim.c @@ -37,6 +37,9 @@ #include "cnst.h" #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "prot.h" #include "rom_com.h" diff --git a/lib_dec/FEC_lsf_estim.c b/lib_dec/FEC_lsf_estim.c index e8e165991..dce8b8351 100644 --- a/lib_dec/FEC_lsf_estim.c +++ b/lib_dec/FEC_lsf_estim.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "rom_com.h" #include "prot.h" diff --git a/lib_dec/FEC_pitch_estim.c b/lib_dec/FEC_pitch_estim.c index 738000a4d..3076f7bca 100644 --- a/lib_dec/FEC_pitch_estim.c +++ b/lib_dec/FEC_pitch_estim.c @@ -37,6 +37,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "prot.h" #include "wmc_auto.h" diff --git a/lib_dec/FEC_scale_syn.c b/lib_dec/FEC_scale_syn.c index 5ac57bb91..7d43ad3a9 100644 --- a/lib_dec/FEC_scale_syn.c +++ b/lib_dec/FEC_scale_syn.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "prot.h" diff --git a/lib_dec/LD_music_post_filter.c b/lib_dec/LD_music_post_filter.c index dd2493b0e..b7885d35b 100644 --- a/lib_dec/LD_music_post_filter.c +++ b/lib_dec/LD_music_post_filter.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "rom_com.h" diff --git a/lib_dec/TonalComponentDetection.c b/lib_dec/TonalComponentDetection.c index f3b73bf8c..fedfe0c2e 100644 --- a/lib_dec/TonalComponentDetection.c +++ b/lib_dec/TonalComponentDetection.c @@ -39,6 +39,9 @@ #include #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "prot.h" #include "cnst.h" diff --git a/lib_dec/acelp_core_dec.c b/lib_dec/acelp_core_dec.c index 5218f6010..d22d6138f 100644 --- a/lib_dec/acelp_core_dec.c +++ b/lib_dec/acelp_core_dec.c @@ -37,6 +37,9 @@ #include #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "rom_com.h" #include "prot.h" @@ -557,6 +560,9 @@ ivas_error acelp_core_dec( } } +#ifdef DEBUG_MODE_ACELP + dbgwrite( exc, sizeof( float ), st->L_frame, 1, fname( debug_dir, "exc", st->idchan, st->id_element, DEC ) ); +#endif /* synthesis at 12.8kHz sampling rate */ syn_12k8( st->L_frame, Aq, exc2, syn, st->mem_syn2, 1 ); @@ -816,6 +822,9 @@ ivas_error acelp_core_dec( } } +#ifdef DEBUG_MODE_ACELP + dbgwrite( exc, sizeof( float ), st->L_frame, 1, fname( debug_dir, "exc", st->idchan, st->id_element, DEC ) ); +#endif /* synthesis for ACELP core switching and SWB BWE */ syn_12k8( st->L_frame, Aq, exc, temp_buf, st->mem_syn1, 1 ); @@ -1218,6 +1227,9 @@ ivas_error acelp_core_dec( } } +#ifdef DEBUG_MODE_ACELP + dbgwrite( syn, sizeof( float ), st->L_frame, 1, fname( debug_dir, "syn.intFs", st->idchan, st->id_element, DEC ) ); +#endif /*----------------------------------------------------------------* * Resample to the output sampling rate (8/16/32/48 kHz) @@ -1348,6 +1360,9 @@ ivas_error acelp_core_dec( /* save synthesis - needed in case of core switching */ mvr2r( synth, st->previoussynth, output_frame ); +#ifdef DEBUG_MODE_ACELP + dbgwrite( synth, sizeof( float ), output_frame, 1, fname( debug_dir, "output.Fs", st->idchan, st->id_element, DEC ) ); +#endif } else { @@ -1367,6 +1382,9 @@ ivas_error acelp_core_dec( mvr2r( bpf_error_signal, st->p_bpf_noise_buf, st->L_frame ); } +#ifdef DEBUG_MODE_ACELP + dbgwrite( synth, sizeof( float ), output_frame, 1, fname( debug_dir, "output.Fs", st->idchan, st->id_element, DEC ) ); +#endif set_f( synth, 0.0f, output_frame ); } diff --git a/lib_dec/acelp_core_switch_dec.c b/lib_dec/acelp_core_switch_dec.c index 96e6bec4e..51d459b20 100644 --- a/lib_dec/acelp_core_switch_dec.c +++ b/lib_dec/acelp_core_switch_dec.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "rom_com.h" #include "prot.h" diff --git a/lib_dec/amr_wb_dec.c b/lib_dec/amr_wb_dec.c index b585eecf9..5252b2656 100644 --- a/lib_dec/amr_wb_dec.c +++ b/lib_dec/amr_wb_dec.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "rom_com.h" @@ -806,6 +809,20 @@ ivas_error amr_wb_dec( /* final output of synthesis signal */ mvr2r( synth_out, output, output_frame ); +#ifdef DEBUG_MODE_INFO + dbgwrite( &st->clas_dec, sizeof( int16_t ), 1, output_frame, "res/clas.dec" ); + dbgwrite( &st->codec_mode, sizeof( int16_t ), 1, output_frame, "res/codec.dec" ); + dbgwrite( &st->core, sizeof( int16_t ), 1, output_frame, "res/core.dec" ); + dbgwrite( &st->extl, sizeof( int16_t ), 1, output_frame, "res/extl.dec" ); + dbgwrite( &st->bwidth, sizeof( int16_t ), 1, output_frame, "res/bwidth.dec" ); + dbgwrite( &st->cng_type, sizeof( int16_t ), 1, output_frame, "res/cng_type.dec" ); + tmp = st->core_brate / 1000.0f; + dbgwrite( &tmp, sizeof( float ), 1, output_frame, "res/core_brate.dec" ); + dbgwrite( &tmp, sizeof( float ), 1, output_frame, "res/total_brate.dec" ); + dbgwrite( &st->coder_type, sizeof( int16_t ), 1, output_frame, "res/coder_type.dec" ); + dbgwrite( &st->L_frame, sizeof( int16_t ), 1, output_frame, "res/L_frame.dec" ); + dbgwrite( &st->bfi, sizeof( int16_t ), 1, output_frame, "res/bfi" ); +#endif return error; } diff --git a/lib_dec/arith_coder_dec.c b/lib_dec/arith_coder_dec.c index 82f35846c..09f169813 100644 --- a/lib_dec/arith_coder_dec.c +++ b/lib_dec/arith_coder_dec.c @@ -37,6 +37,9 @@ #include #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "prot.h" #include "rom_com.h" diff --git a/lib_dec/avq_dec.c b/lib_dec/avq_dec.c index 6a7245d9d..ec74ea538 100644 --- a/lib_dec/avq_dec.c +++ b/lib_dec/avq_dec.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "prot.h" #include "cnst.h" #include "wmc_auto.h" diff --git a/lib_dec/bass_psfilter.c b/lib_dec/bass_psfilter.c index 94538e1e7..d1fc86e0e 100644 --- a/lib_dec/bass_psfilter.c +++ b/lib_dec/bass_psfilter.c @@ -42,6 +42,9 @@ #include "cnst.h" #include "stat_dec.h" #include "rom_com.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "wmc_auto.h" @@ -519,7 +522,11 @@ void addBassPostFilter( int16_t res_bpf_adapt( STEREO_DFT_DEC_DATA_HANDLE hStereoDft, /* i/o: DFT stereo decoder handle */ const float *bpf_error_signal_8k, /* i : BPF modification signal */ +#ifdef FIX_887_ARRAY_SIZE_DFT_MDCT_STEREO float res_buf[STEREO_DFT_N_8k] /* i : residual buffer */ +#else + float res_buf[STEREO_DFT_BUF_MAX] /* i : residual buffer */ +#endif ) { float error_nrg; diff --git a/lib_dec/cng_dec.c b/lib_dec/cng_dec.c index 486d2d857..b7f462aa9 100644 --- a/lib_dec/cng_dec.c +++ b/lib_dec/cng_dec.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "prot.h" @@ -738,6 +741,9 @@ static void shb_CNG_decod( gain = (float) sqrt( pow( 10, 0.1f * ener ) * L_FRAME16k / ener_excSHB ); st->hTdCngDec->shb_cng_gain = ener; +#ifdef DEBUGGING + /* note: state shb_cng_gain is actually an energy value in dB */ +#endif for ( i = 0; i < L_FRAME16k; i++ ) { diff --git a/lib_dec/core_dec_init.c b/lib_dec/core_dec_init.c index eed6fc8c0..3ceee9a2f 100644 --- a/lib_dec/core_dec_init.c +++ b/lib_dec/core_dec_init.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "stat_com.h" #include "cnst.h" #include "prot.h" diff --git a/lib_dec/core_dec_reconf.c b/lib_dec/core_dec_reconf.c index ffbcfca95..7734d1317 100644 --- a/lib_dec/core_dec_reconf.c +++ b/lib_dec/core_dec_reconf.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "prot.h" #include "rom_com.h" #include "rom_dec.h" diff --git a/lib_dec/core_dec_switch.c b/lib_dec/core_dec_switch.c index d093afc3d..16519aec4 100644 --- a/lib_dec/core_dec_switch.c +++ b/lib_dec/core_dec_switch.c @@ -37,6 +37,9 @@ #include #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "prot.h" #include "rom_com.h" #include "wmc_auto.h" diff --git a/lib_dec/core_switching_dec.c b/lib_dec/core_switching_dec.c index 2625d59a6..e70b1d59d 100644 --- a/lib_dec/core_switching_dec.c +++ b/lib_dec/core_switching_dec.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "rom_com.h" diff --git a/lib_dec/d_gain2p.c b/lib_dec/d_gain2p.c index 826208b9a..d2fe3e875 100644 --- a/lib_dec/d_gain2p.c +++ b/lib_dec/d_gain2p.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "prot.h" #include "cnst.h" diff --git a/lib_dec/dec2t32.c b/lib_dec/dec2t32.c index 57ad88f2f..258e36da4 100644 --- a/lib_dec/dec2t32.c +++ b/lib_dec/dec2t32.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "prot.h" #include "wmc_auto.h" diff --git a/lib_dec/dec4t64.c b/lib_dec/dec4t64.c index a0e969b1b..9f2ab5d1c 100644 --- a/lib_dec/dec4t64.c +++ b/lib_dec/dec4t64.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "prot.h" #include "ivas_prot.h" diff --git a/lib_dec/dec_LPD.c b/lib_dec/dec_LPD.c index e3d0561c2..af6a937e1 100644 --- a/lib_dec/dec_LPD.c +++ b/lib_dec/dec_LPD.c @@ -37,6 +37,9 @@ #include #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "prot.h" #include "rom_com.h" diff --git a/lib_dec/dec_ace.c b/lib_dec/dec_ace.c index 1012b8e77..ee32d6714 100644 --- a/lib_dec/dec_ace.c +++ b/lib_dec/dec_ace.c @@ -37,6 +37,9 @@ #include #include "options.h" #include "prot.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "rom_com.h" #include "wmc_auto.h" diff --git a/lib_dec/dec_acelp_tcx_main.c b/lib_dec/dec_acelp_tcx_main.c index 98e641563..1ab6b5265 100644 --- a/lib_dec/dec_acelp_tcx_main.c +++ b/lib_dec/dec_acelp_tcx_main.c @@ -39,6 +39,9 @@ #include "rom_com.h" #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "stat_dec.h" #include "wmc_auto.h" diff --git a/lib_dec/dec_amr_wb.c b/lib_dec/dec_amr_wb.c index 88605c5ba..29fe0a253 100644 --- a/lib_dec/dec_amr_wb.c +++ b/lib_dec/dec_amr_wb.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "rom_com.h" #include "prot.h" diff --git a/lib_dec/dec_gen_voic.c b/lib_dec/dec_gen_voic.c index 9f9e7cec8..c8220be86 100644 --- a/lib_dec/dec_gen_voic.c +++ b/lib_dec/dec_gen_voic.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "rom_com.h" #include "prot.h" diff --git a/lib_dec/dec_higher_acelp.c b/lib_dec/dec_higher_acelp.c index 5ae6b8b7c..1990de936 100644 --- a/lib_dec/dec_higher_acelp.c +++ b/lib_dec/dec_higher_acelp.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "prot.h" diff --git a/lib_dec/dec_nelp.c b/lib_dec/dec_nelp.c index 3c2688d41..8516f4cfd 100644 --- a/lib_dec/dec_nelp.c +++ b/lib_dec/dec_nelp.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "prot.h" #include "wmc_auto.h" diff --git a/lib_dec/dec_pit_exc.c b/lib_dec/dec_pit_exc.c index 27e49a6ef..2b67a6042 100644 --- a/lib_dec/dec_pit_exc.c +++ b/lib_dec/dec_pit_exc.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "rom_com.h" #include "prot.h" diff --git a/lib_dec/dec_post.c b/lib_dec/dec_post.c index 6116539e9..6c5cd0423 100644 --- a/lib_dec/dec_post.c +++ b/lib_dec/dec_post.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "rom_com.h" diff --git a/lib_dec/dec_ppp.c b/lib_dec/dec_ppp.c index aa20b3194..b36f9190a 100644 --- a/lib_dec/dec_ppp.c +++ b/lib_dec/dec_ppp.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "prot.h" #include "wmc_auto.h" diff --git a/lib_dec/dec_prm.c b/lib_dec/dec_prm.c index 347abd25e..d2e9aa26e 100644 --- a/lib_dec/dec_prm.c +++ b/lib_dec/dec_prm.c @@ -37,6 +37,9 @@ #include #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "rom_com.h" #include "prot.h" diff --git a/lib_dec/dec_tcx.c b/lib_dec/dec_tcx.c index 2e131391e..cffb6a109 100644 --- a/lib_dec/dec_tcx.c +++ b/lib_dec/dec_tcx.c @@ -39,11 +39,17 @@ #include "ivas_prot.h" #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "stat_com.h" #include "cnst.h" #include "wmc_auto.h" #include "ivas_rom_com.h" +#ifdef DEBUG_PLOT +#include "deb_out.h" +#endif /*-----------------------------------------------------------------* @@ -248,6 +254,16 @@ void decoder_tcx_post( /* Update synth, exc and old_Aq */ tcx_decoder_memory_update( st, xn_buf, synth, A ); +#ifdef DEBUG_MODE_TCX + { + int16_t tmp[320]; + for ( i = 0; i < L_EXC_MEM; i++ ) + { + tmp[i] = (int16_t) ( st->old_exc[L_EXC_MEM_DEC - L_EXC_MEM + i] + 0.5f ); + } + dbgwrite( tmp, 2, L_EXC_MEM, 1, "res/exc_old.dec.pcm" ); + } +#endif /* PLC: [TCX: Memory update] */ st->old_pitch_buf[0] = st->old_pitch_buf[st->nb_subfr]; @@ -1501,6 +1517,10 @@ void decoder_tcx_tns( } } +#ifdef DEBUG_PLOT + if ( !whitenedDomain ) + sendDebout( "tnsSpec2", L_frameTCX, 1, "aftInvertGrouping", MTV_FLOAT, x ); +#endif /*-----------------------------------------------------------* * Temporal Noise Shaping Synthesis * @@ -1517,6 +1537,9 @@ void decoder_tcx_tns( } ApplyTnsFilter( hTcxCfg->pCurrentTnsConfig, tnsData, x, 0 ); +#ifdef DEBUG_PLOT + sendDebout( "tnsSpec2", L_frameTCX, 1, "aftTNS", MTV_FLOAT, x ); +#endif if ( ( L_frame == st->L_frame >> 1 ) && st->tcxonly && isTCX5 ) { @@ -1536,6 +1559,10 @@ void decoder_tcx_tns( tcx5SpectrumInterleaving( L >> 1, x ); } +#ifdef DEBUG_PLOT + if ( !whitenedDomain ) + sendDebout( "tnsSpec1", L_frameTCX, 1, "aftTNS", MTV_FLOAT, x ); +#endif /* restore index */ if ( ( L_frame == st->L_frame >> 1 ) && st->tcxonly && frame_cnt && !bfi && st->last_core != ACELP_CORE ) { @@ -1673,6 +1700,9 @@ void decoder_tcx_imdct( * Compute inverse MDCT of x[]. * *-----------------------------------------------------------*/ +#ifdef DEBUG_PLOT + sendDebout( "tnsSpec", L_frameTCX, 1, "befIMDCT", MTV_FLOAT, x ); +#endif if ( st->element_mode == IVAS_CPE_MDCT ) { @@ -1934,6 +1964,14 @@ void decoder_tcx_IGF_stereo( * both channels have the same IGF configuration */ +#ifdef DEBUGGING + /* sanity checks: check if both channels have the same configuration...*/ + assert( ( sts[0]->core == sts[1]->core ) ); + if ( sts[0]->last_core_from_bs == ACELP_CORE || sts[1]->last_core_from_bs == ACELP_CORE ) + { + assert( ( sts[0]->last_core_from_bs == sts[1]->last_core_from_bs ) ); + } +#endif /* initialization */ sfbConf = ( core == TCX_20_CORE ) ? &hStereoMdct->stbParamsTCX20 : &hStereoMdct->stbParamsTCX10; diff --git a/lib_dec/dec_tran.c b/lib_dec/dec_tran.c index 0e105703e..875ce5eab 100644 --- a/lib_dec/dec_tran.c +++ b/lib_dec/dec_tran.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "prot.h" #include "wmc_auto.h" diff --git a/lib_dec/decision_matrix_dec.c b/lib_dec/decision_matrix_dec.c index e6378ed0a..f3b1194b0 100644 --- a/lib_dec/decision_matrix_dec.c +++ b/lib_dec/decision_matrix_dec.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "stat_dec.h" #include "rom_com.h" #include "prot.h" diff --git a/lib_dec/dlpc_stoch.c b/lib_dec/dlpc_stoch.c index c033c5bb0..22a1cda26 100644 --- a/lib_dec/dlpc_stoch.c +++ b/lib_dec/dlpc_stoch.c @@ -37,6 +37,9 @@ #include #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "prot.h" #include "rom_com.h" #include "basop_proto_func.h" diff --git a/lib_dec/er_dec_acelp.c b/lib_dec/er_dec_acelp.c index 5fdce1773..7024cfb3f 100644 --- a/lib_dec/er_dec_acelp.c +++ b/lib_dec/er_dec_acelp.c @@ -37,6 +37,9 @@ #include #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "prot.h" #include "wmc_auto.h" diff --git a/lib_dec/er_dec_tcx.c b/lib_dec/er_dec_tcx.c index bf2fbe9c2..24a481705 100644 --- a/lib_dec/er_dec_tcx.c +++ b/lib_dec/er_dec_tcx.c @@ -39,6 +39,9 @@ #include #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "prot.h" #include "rom_dec.h" diff --git a/lib_dec/er_util.c b/lib_dec/er_util.c index 965b527a7..5326f28e9 100644 --- a/lib_dec/er_util.c +++ b/lib_dec/er_util.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "prot.h" #include "cnst.h" @@ -291,7 +294,11 @@ int16_t GetPLCModeDecision( } else { +#ifndef DEBUG_NO_TD_TCX_PLC core = ACELP_CORE; +#else + core = st->last_core; +#endif if ( st->nbLostCmpt > 1 ) { core = st->last_core_bfi; @@ -316,13 +323,16 @@ int16_t GetPLCModeDecision( if ( ( numIndices > 10 ) || ( ( numIndices > 5 ) && ( fabs( hTcxDec->tcxltp_third_last_pitch - hTcxDec->tcxltp_second_last_pitch ) < 0.5f ) ) || ( ( numIndices > 0 ) && ( ( st->last_good <= UNVOICED_TRANSITION ) || ( hTcxDec->tcxltp_last_gain_unmodified <= 0.4f ) ) && ( fabs( hTcxDec->tcxltp_third_last_pitch - hTcxDec->tcxltp_second_last_pitch ) < 0.5f ) ) ) { core = TCX_20_CORE; +#ifndef DEBUG_NO_TONAL_PLC st->tonal_mdct_plc_active = 1; +#endif } else if ( st->last_good <= UNVOICED_TRANSITION || hTcxDec->tcxltp_last_gain_unmodified <= 0.4f ) { core = TCX_20_CORE; } } +#ifndef DEBUG_FORCE_TD_TCX_CONCEALMENT else if ( st->last_core != ACELP_CORE ) { if ( st->last_good <= UNVOICED_TRANSITION || hTcxDec->tcxltp_last_gain_unmodified <= 0.4f ) @@ -330,6 +340,7 @@ int16_t GetPLCModeDecision( core = st->last_core; } } +#endif } } } diff --git a/lib_dec/evs_dec.c b/lib_dec/evs_dec.c index 7b6dc2b9d..39815e633 100644 --- a/lib_dec/evs_dec.c +++ b/lib_dec/evs_dec.c @@ -36,11 +36,17 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "rom_com.h" #include "prot.h" #include "wmc_auto.h" +#ifdef DEBUG_PLOT +#include "deb_out.h" +#endif /*--------------------------------------------------------------------------* * evs_dec() @@ -938,6 +944,34 @@ ivas_error evs_dec( } +#ifdef DEBUG_MODE_INFO + for ( i = 0; i < ( st->L_frame / L_SUBFR ); i++ ) + { + dbgwrite( &pitch_buf[i], sizeof( float ), 1, output_frame / ( st->L_frame / L_SUBFR ), "res/pitch_buf.dec" ); + } + dbgwrite( &st->clas_dec, sizeof( int16_t ), 1, output_frame, "res/clas.dec" ); + dbgwrite( &st->codec_mode, sizeof( int16_t ), 1, output_frame, "res/codec.dec" ); + dbgwrite( &st->core, sizeof( int16_t ), 1, output_frame, "res/core.dec" ); + dbgwrite( &st->extl, sizeof( int16_t ), 1, output_frame, "res/extl.dec" ); + dbgwrite( &st->bwidth, sizeof( int16_t ), 1, output_frame, "res/bwidth.dec" ); + dbgwrite( &st->cng_type, sizeof( int16_t ), 1, output_frame, "res/cng_type.dec" ); + tmp = st->extl_brate / 1000.0f; + dbgwrite( &tmp, sizeof( float ), 1, output_frame, "res/extl_brate.dec" ); + tmp = st->core_brate / 1000.0f; + dbgwrite( &tmp, sizeof( float ), 1, output_frame, "res/core_brate.dec" ); + tmp = st->total_brate / 1000.0f; + dbgwrite( &tmp, sizeof( float ), 1, output_frame, "res/total_brate.dec" ); + dbgwrite( &st->coder_type, sizeof( int16_t ), 1, output_frame, "res/coder_type.dec" ); + dbgwrite( &st->L_frame, sizeof( int16_t ), 1, output_frame, "res/L_frame.dec" ); + dbgwrite( &st->bfi, sizeof( int16_t ), 1, output_frame, "res/bfi" ); + dbgwrite( &st->BER_detect, sizeof( int16_t ), 1, output_frame, "res/BER_detect" ); + + if ( st->core != ACELP_CORE ) + { + set_f( hb_synth, 0, output_frame ); + dbgwrite( hb_synth, 4, st->L_frame, 1, "res/exc.dec" ); + } +#endif pop_wmops(); return error; diff --git a/lib_dec/fd_cng_dec.c b/lib_dec/fd_cng_dec.c index 7745630fe..348cfd122 100644 --- a/lib_dec/fd_cng_dec.c +++ b/lib_dec/fd_cng_dec.c @@ -37,6 +37,9 @@ #include #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "prot.h" #include "ivas_prot.h" @@ -1101,10 +1104,17 @@ void generate_comfort_noise_dec( c2 = (float) sqrt( 1 - hFdCngCom->coherence ); seed2 = &( hFdCngCom->seed2 ); +#ifdef NONBE_FIX_DISCRETE_ISM_NOISE_SEED_HANDLING if ( st->element_mode == IVAS_CPE_MDCT && st->idchan == 1 ) { seed2 = &( hFdCngCom->seed3 ); } +#else + if ( ( st->element_mode == IVAS_CPE_MDCT && st->idchan == 1 ) || ( st->element_mode == IVAS_SCE && st->cng_ism_flag ) ) + { + seed2 = &( hFdCngCom->seed3 ); + } +#endif /* Generate Gaussian random noise in real and imaginary parts of the FFT bins Amplitudes are adjusted to the estimated noise level cngNoiseLevel in each bin */ @@ -1356,7 +1366,11 @@ void generate_comfort_noise_dec_hf( if ( cng_coh_flag ) { +#ifdef NONBE_FIX_DISCRETE_ISM_NOISE_SEED_HANDLING seed2 = &( hFdCngCom->seed2 ); +#else + seed2 = &( hFdCngCom->seed3 ); +#endif c1 = (float) sqrt( hFdCngCom->coherence ); c2 = (float) sqrt( 1 - hFdCngCom->coherence ); @@ -1823,6 +1837,13 @@ void generate_masking_noise_lb_dirac( n_samples_start = 0; /*LB CLDFB - CNA from STFT*/ +#ifdef DEBUG_MODE_DIRAC + { + int16_t tmp_s; + tmp_s = (int16_t) ( 32768.f * 0.5f * hFdCngCom->likelihood_noisy_speech * cna_flag + 0.5f ); + dbgwrite( &tmp_s, sizeof( int16_t ), 1, hFdCngCom->frameSize / 16, "./res/ivas_dirac_likelihood_noisy.pcm" ); + } +#endif if ( cna_flag ) { /* skip noise generating if level is very low, to avoid problems with possibly running into denormals */ @@ -1892,6 +1913,17 @@ void generate_masking_noise_lb_dirac( /* Perform STFT synthesis */ SynthesisSTFT_dirac( fftBuffer, tdBuffer + n_samples_start, hFdCngCom->olapBufferSynth2, hFdCngCom->olapWinSyn, n_samples_out_loop, hFdCngCom ); +#ifdef DEBUG_MODE_DIRAC + { + int16_t tmp[1000]; + + for ( i = 0; i < hFdCngCom->frameSize; i++ ) + { + tmp[i] = (int16_t) ( tdBuffer[i] + 0.5f ); + } + dbgwrite( tmp, sizeof( int16_t ), hFdCngCom->frameSize, 1, "./res/ivas_dirac_cna_fft.pcm" ); + } +#endif } else @@ -1904,6 +1936,17 @@ void generate_masking_noise_lb_dirac( /* Perform STFT synthesis */ SynthesisSTFT_dirac( fftBuffer, tdBuffer + n_samples_start, hFdCngCom->olapBufferSynth2, hFdCngCom->olapWinSyn, n_samples_out_loop, hFdCngCom ); +#ifdef DEBUG_MODE_DIRAC + { + int16_t tmp[1000]; + + for ( i = 0; i < hFdCngCom->frameSize; i++ ) + { + tmp[i] = (int16_t) ( tdBuffer[i] + 0.5f ); + } + dbgwrite( tmp, sizeof( int16_t ), hFdCngCom->frameSize, 1, "./res/ivas_dirac_cna_fft.pcm" ); + } +#endif } n_samples_out -= hFdCngCom->frameSize; n_samples_start += hFdCngCom->frameSize; @@ -1953,6 +1996,13 @@ void generate_masking_noise_dirac( set_zero( Cldfb_ImagBuffer, CLDFB_NO_CHANNELS_MAX ); /*LB CLDFB - CNA from STFT*/ +#ifdef DEBUG_MODE_DIRAC + { + int16_t tmp_s; + tmp_s = (int16_t) ( 32768.f * 0.5f * hFdCngCom->likelihood_noisy_speech * cna_flag + 0.5f ); + dbgwrite( &tmp_s, sizeof( int16_t ), 1, hFdCngCom->frameSize / 16, "./res/ivas_dirac_likelihood_noisy.pcm" ); + } +#endif if ( cna_flag ) { /* skip noise generating if level is very low, to avoid problems with possibly running into denormals */ diff --git a/lib_dec/gain_dec.c b/lib_dec/gain_dec.c index 2717abe0f..6f769dd6e 100644 --- a/lib_dec/gain_dec.c +++ b/lib_dec/gain_dec.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "rom_com.h" diff --git a/lib_dec/gaus_dec.c b/lib_dec/gaus_dec.c index 141812b30..a05359772 100644 --- a/lib_dec/gaus_dec.c +++ b/lib_dec/gaus_dec.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "rom_com.h" diff --git a/lib_dec/gs_dec.c b/lib_dec/gs_dec.c index ba9c574af..5ed7aa92c 100644 --- a/lib_dec/gs_dec.c +++ b/lib_dec/gs_dec.c @@ -37,6 +37,9 @@ #include #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "rom_com.h" #include "prot.h" diff --git a/lib_dec/gs_dec_amr_wb.c b/lib_dec/gs_dec_amr_wb.c index b0950b350..1d41f367f 100644 --- a/lib_dec/gs_dec_amr_wb.c +++ b/lib_dec/gs_dec_amr_wb.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "rom_com.h" diff --git a/lib_dec/hdecnrm.c b/lib_dec/hdecnrm.c index 215840996..1f247ef1f 100644 --- a/lib_dec/hdecnrm.c +++ b/lib_dec/hdecnrm.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "prot.h" #include "rom_com.h" diff --git a/lib_dec/hf_synth.c b/lib_dec/hf_synth.c index 5be0404f8..a4d75b4e9 100644 --- a/lib_dec/hf_synth.c +++ b/lib_dec/hf_synth.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "prot.h" diff --git a/lib_dec/hq_classifier_dec.c b/lib_dec/hq_classifier_dec.c index 920554280..10a1a783f 100644 --- a/lib_dec/hq_classifier_dec.c +++ b/lib_dec/hq_classifier_dec.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "prot.h" #include "rom_com.h" diff --git a/lib_dec/hq_conf_fec.c b/lib_dec/hq_conf_fec.c index a35206441..7d3c79fcf 100644 --- a/lib_dec/hq_conf_fec.c +++ b/lib_dec/hq_conf_fec.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "rom_com.h" #include "prot.h" diff --git a/lib_dec/hq_core_dec.c b/lib_dec/hq_core_dec.c index 99d74c63b..cdb960167 100644 --- a/lib_dec/hq_core_dec.c +++ b/lib_dec/hq_core_dec.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "prot.h" diff --git a/lib_dec/hq_env_dec.c b/lib_dec/hq_env_dec.c index 74309410c..e584bfa82 100644 --- a/lib_dec/hq_env_dec.c +++ b/lib_dec/hq_env_dec.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "prot.h" #include "rom_com.h" #include "wmc_auto.h" diff --git a/lib_dec/hq_hr_dec.c b/lib_dec/hq_hr_dec.c index 923d3b05e..5153af07e 100644 --- a/lib_dec/hq_hr_dec.c +++ b/lib_dec/hq_hr_dec.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "rom_com.h" #include "prot.h" diff --git a/lib_dec/hq_lr_dec.c b/lib_dec/hq_lr_dec.c index 2d1ab7809..3b9ae0c6f 100644 --- a/lib_dec/hq_lr_dec.c +++ b/lib_dec/hq_lr_dec.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "rom_com.h" diff --git a/lib_dec/igf_dec.c b/lib_dec/igf_dec.c index e5903902e..8095f6da4 100644 --- a/lib_dec/igf_dec.c +++ b/lib_dec/igf_dec.c @@ -37,6 +37,9 @@ #include #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "prot.h" #include "cnst.h" @@ -513,6 +516,9 @@ static void IGF_prepStereo( { for ( tb = swb_offset[sfb]; tb < swb_offset[sfb + 1]; tb++ ) { +#ifdef DEBUGGING + assert( strt_cpy < hGrid->swb_offset[0] ); +#endif if ( coreMsMask[tb] == 0 ) { @@ -595,6 +601,9 @@ static void IGF_prepStereo( { for ( tb = swb_offset[sfb]; tb < swb_offset[sfb + 1]; tb++ ) { +#ifdef DEBUGGING + assert( strt_cpy < hGrid->swb_offset[0] ); +#endif if ( coreMsMask[tb] == 0 ) { @@ -715,6 +724,10 @@ static void IGF_appl( lFactor = hGrid->lFactor; swb_offset = hGrid->swb_offset; +#ifdef DEBUGGING + /* make sure we don't read/write OOB for arrays whose size was reduced by IGF_START_MN to safe on memory */ + assert( swb_offset[start_sfb] >= IGF_START_MN ); +#endif /* collect energy below hGrid->startLine: */ for ( tb = hGrid->startLine - 24; tb < hGrid->startLine; tb++ ) diff --git a/lib_dec/igf_scf_dec.c b/lib_dec/igf_scf_dec.c index 11c6f0845..f152f637a 100644 --- a/lib_dec/igf_scf_dec.c +++ b/lib_dec/igf_scf_dec.c @@ -37,6 +37,9 @@ #include #include "options.h" #include "prot.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "stat_dec.h" #include "wmc_auto.h" diff --git a/lib_dec/init_dec.c b/lib_dec/init_dec.c index 6d2849841..ba18a8e85 100644 --- a/lib_dec/init_dec.c +++ b/lib_dec/init_dec.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "ivas_cnst.h" #include "rom_com.h" diff --git a/lib_dec/inov_dec.c b/lib_dec/inov_dec.c index adbbb4fd3..43c7eb2c7 100644 --- a/lib_dec/inov_dec.c +++ b/lib_dec/inov_dec.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "prot.h" #include "ivas_prot.h" diff --git a/lib_dec/ivas_agc_dec.c b/lib_dec/ivas_agc_dec.c index c41dedf21..9722514db 100644 --- a/lib_dec/ivas_agc_dec.c +++ b/lib_dec/ivas_agc_dec.c @@ -36,9 +36,15 @@ #include "ivas_prot.h" #include #include +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" +#ifdef DEBUG_AGC +extern FILE *agcIn; +#endif /*-----------------------------------------------------------------------------------------* * Function ivas_agc_dec_init() @@ -272,6 +278,20 @@ void ivas_agc_read_bits( } } +#ifdef DEBUG_AGC + FILE *stream = agcIn; + int16_t num_bits = 0, num_dmx_bits[4] = { 0 }; + for ( i = 0; i < n_channels; i++ ) + { + fread( &( pState->gain_data[i].absGainExpCurr ), sizeof( int32_t ), 1, stream ); /* n bits */ + num_bits += pState->agc_com.betaE; + num_dmx_bits[i]++; + + /*fprintf(stdout, "AbsGain[%d]:= %d[%d bits]; ", i, pState->gain_data[i].absGainExp, pState->betaE);*/ + } + /*fprintf(stdout, "AGC bits:= %d ", num_bits);*/ + +#endif return; } diff --git a/lib_dec/ivas_binRenderer_internal.c b/lib_dec/ivas_binRenderer_internal.c index 77e01cd30..ae8ea8cd8 100644 --- a/lib_dec/ivas_binRenderer_internal.c +++ b/lib_dec/ivas_binRenderer_internal.c @@ -42,6 +42,13 @@ #include "ivas_rom_dec.h" #include "ivas_rom_com.h" #include "ivas_rom_binauralRenderer.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT +#include "ivas_rom_dec.h" +#include "lib_rend.h" +#endif +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" @@ -57,7 +64,12 @@ static void ivas_binRenderer_filterModule( float CLDFB_real[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i : real part of LS signals */ float CLDFB_imag[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i : imag part of LS signals */ const int16_t numTimeSlots, /* i : number of time slots to process */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + BINAURAL_RENDERER_HANDLE hBinRenderer, /* i/o: fastconv binaural renderer handle */ + const int16_t pos_idx /* i : pose index */ +#else BINAURAL_RENDERER_HANDLE hBinRenderer /* i/o: fastconv binaural renderer handle */ +#endif ) { int16_t bandIdx, k, chIdx, tapIdx; @@ -68,8 +80,13 @@ static void ivas_binRenderer_filterModule( { for ( chIdx = 0; chIdx < hBinRenderer->nInChannels; chIdx++ ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + filterStatesLeftRealPtr = (float *) &( hBinRenderer->hBinRenConvModule->filterStatesLeftReal[pos_idx][bandIdx][chIdx][0] ); + filterStatesLeftImagPtr = (float *) &( hBinRenderer->hBinRenConvModule->filterStatesLeftImag[pos_idx][bandIdx][chIdx][0] ); +#else filterStatesLeftRealPtr = (float *) &( hBinRenderer->hBinRenConvModule->filterStatesLeftReal[bandIdx][chIdx][0] ); filterStatesLeftImagPtr = (float *) &( hBinRenderer->hBinRenConvModule->filterStatesLeftImag[bandIdx][chIdx][0] ); +#endif filterTapsLeftRealPtr = hBinRenderer->hBinRenConvModule->filterTapsLeftReal[bandIdx][chIdx]; filterTapsLeftImagPtr = hBinRenderer->hBinRenConvModule->filterTapsLeftImag[bandIdx][chIdx]; @@ -124,11 +141,19 @@ static ivas_error ivas_binRenderer_convModuleOpen( const int16_t renderer_type, const int16_t isLoudspeaker, const AUDIO_CONFIG input_config, +#ifdef SPLIT_REND_WITH_HEAD_ROT + const HRTFS_FASTCONV_HANDLE hHrtf, + const int16_t num_poses +#else const HRTFS_FASTCONV_HANDLE hHrtf +#endif ) { int16_t bandIdx, chIdx; BINRENDERER_CONV_MODULE_HANDLE hBinRenConvModule; +#ifdef SPLIT_REND_WITH_HEAD_ROT + int16_t pos_idx; +#endif /*-----------------------------------------------------------------* * prepare library opening @@ -239,6 +264,56 @@ static ivas_error ivas_binRenderer_convModuleOpen( } } +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( hBinRenConvModule->filterStatesLeftReal = (float ****) malloc( num_poses * sizeof( float *** ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); + } + + if ( ( hBinRenConvModule->filterStatesLeftImag = (float ****) malloc( num_poses * sizeof( float *** ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); + } + + for ( pos_idx = 0; pos_idx < num_poses; pos_idx++ ) + { + if ( ( hBinRenConvModule->filterStatesLeftReal[pos_idx] = (float ***) malloc( hBinRenderer->conv_band * sizeof( float ** ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); + } + + if ( ( hBinRenConvModule->filterStatesLeftImag[pos_idx] = (float ***) malloc( hBinRenderer->conv_band * sizeof( float ** ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); + } + + for ( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ ) + { + if ( ( hBinRenConvModule->filterStatesLeftReal[pos_idx][bandIdx] = (float **) malloc( hBinRenderer->nInChannels * sizeof( float * ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); + } + + if ( ( hBinRenConvModule->filterStatesLeftImag[pos_idx][bandIdx] = (float **) malloc( hBinRenderer->nInChannels * sizeof( float * ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); + } + + for ( chIdx = 0; chIdx < hBinRenderer->nInChannels; chIdx++ ) + { + if ( ( hBinRenConvModule->filterStatesLeftReal[pos_idx][bandIdx][chIdx] = (float *) malloc( hBinRenConvModule->numTapsArray[bandIdx] * sizeof( float ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); + } + + if ( ( hBinRenConvModule->filterStatesLeftImag[pos_idx][bandIdx][chIdx] = (float *) malloc( hBinRenConvModule->numTapsArray[bandIdx] * sizeof( float ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Convolution Module \n" ) ); + } + } + } + } +#else if ( ( hBinRenConvModule->filterStatesLeftReal = (float ***) malloc( hBinRenderer->conv_band * sizeof( float ** ) ) ) == NULL ) { @@ -275,6 +350,7 @@ static ivas_error ivas_binRenderer_convModuleOpen( } } } +#endif /* SPLIT_REND_WITH_HEAD_ROT */ /* set memories */ for ( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ ) @@ -305,13 +381,21 @@ static ivas_error ivas_binRenderer_convModuleOpen( { tmp = channelIndex_CICP19[chIdx]; } +#ifdef DEBUGGING + else + { + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Error: Channel configuration not specified!\n\n" ); + } +#endif } if ( renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) { +#ifndef SPLIT_REND_WITH_HEAD_ROT /* set the memories to zero */ set_zero( hBinRenConvModule->filterStatesLeftReal[bandIdx][chIdx], hBinRenConvModule->numTapsArray[bandIdx] ); set_zero( hBinRenConvModule->filterStatesLeftImag[bandIdx][chIdx], hBinRenConvModule->numTapsArray[bandIdx] ); +#endif if ( isLoudspeaker ) { hBinRenConvModule->filterTapsLeftReal[bandIdx][chIdx] = hHrtf->leftBRIRReal[bandIdx][tmp]; @@ -319,12 +403,21 @@ static ivas_error ivas_binRenderer_convModuleOpen( hBinRenConvModule->filterTapsRightReal[bandIdx][chIdx] = hHrtf->rightBRIRReal[bandIdx][tmp]; hBinRenConvModule->filterTapsRightImag[bandIdx][chIdx] = hHrtf->rightBRIRImag[bandIdx][tmp]; } +#ifdef DEBUGGING + else + { + /* HOA3 filter coefficients */ + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Error: The tables corresponding to HOA3 for BRIR are missing \n\n" ); + } +#endif } else { +#ifndef SPLIT_REND_WITH_HEAD_ROT /* set the memories to zero */ set_zero( hBinRenConvModule->filterStatesLeftReal[bandIdx][chIdx], hBinRenConvModule->numTaps ); set_zero( hBinRenConvModule->filterStatesLeftImag[bandIdx][chIdx], hBinRenConvModule->numTaps ); +#endif if ( isLoudspeaker ) { hBinRenConvModule->filterTapsLeftReal[bandIdx][chIdx] = hHrtf->leftHRIRReal[bandIdx][tmp]; @@ -367,6 +460,20 @@ static ivas_error ivas_binRenderer_convModuleOpen( } } +#ifdef SPLIT_REND_WITH_HEAD_ROT + for ( pos_idx = 0; pos_idx < num_poses; pos_idx++ ) + { + for ( bandIdx = 0; bandIdx < hBinRenderer->conv_band; bandIdx++ ) + { + for ( chIdx = 0; chIdx < hBinRenderer->nInChannels; chIdx++ ) + { + /* set the memories to zero */ + set_zero( hBinRenConvModule->filterStatesLeftReal[pos_idx][bandIdx][chIdx], hBinRenConvModule->numTapsArray[bandIdx] ); + set_zero( hBinRenConvModule->filterStatesLeftImag[pos_idx][bandIdx][chIdx], hBinRenConvModule->numTapsArray[bandIdx] ); + } + } + } +#endif hBinRenderer->hBinRenConvModule = hBinRenConvModule; @@ -868,6 +975,98 @@ static void ivas_binaural_obtain_DMX( } +#ifdef SPLIT_REND_WITH_HEAD_ROT +/*------------------------------------------------------------------------- + * ivas_rend_openCldfbRend() + * + * Allocate and initialize CLDFB fast conv renderer handle + *------------------------------------------------------------------------*/ + +ivas_error ivas_rend_openCldfbRend( + CLDFB_REND_WRAPPER *pCldfbRend, + const AUDIO_CONFIG inConfig, + const AUDIO_CONFIG outConfig, + const MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + const int32_t output_Fs ) +{ + BINAURAL_RENDERER_HANDLE hBinRenderer; + int16_t convBand; + ivas_error error; + + error = IVAS_ERR_OK; + + /*-----------------------------------------------------------------* + * prepare library opening + *-----------------------------------------------------------------*/ + + if ( ( hBinRenderer = (BINAURAL_RENDERER_HANDLE) malloc( sizeof( BINAURAL_RENDERER ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Binaural Renderer\n" ) ); + } + + if ( ( hBinRenderer->hInputSetup = (IVAS_OUTPUT_SETUP_HANDLE) malloc( sizeof( IVAS_OUTPUT_SETUP ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for output setup Binaural Renderer\n" ) ); + } + + hBinRenderer->rotInCldfb = 1; + hBinRenderer->ivas_format = SBA_FORMAT; + + hBinRenderer->max_band = (int16_t) ( ( BINAURAL_MAXBANDS * output_Fs ) / 48000 ); + convBand = hBinRenderer->max_band; + + hBinRenderer->timeSlots = MAX_PARAM_SPATIAL_SUBFRAMES; /* Corresponds to 5 msec sound to motion latency */ + + if ( convBand > BINAURAL_CONVBANDS ) + { + hBinRenderer->conv_band = BINAURAL_CONVBANDS; + } + else + { + hBinRenderer->conv_band = convBand; + } + + hBinRenderer->hInputSetup->is_loudspeaker_setup = 0; + hBinRenderer->hInputSetup->output_config = inConfig; + if ( ( error = getAudioConfigNumChannels( inConfig, &hBinRenderer->hInputSetup->nchan_out_woLFE ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( outConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || outConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + hBinRenderer->numPoses = pMultiBinPoseData->num_poses + 1; +#else + hBinRenderer->numPoses = pMultiBinPoseData->num_poses; +#endif + } + else + { + hBinRenderer->numPoses = 1; + } + + /* Load HRTF tables */ + if ( ( error = ivas_binaural_hrtf_open( &pCldfbRend->hHrtfFastConv, hBinRenderer->hInputSetup->output_config, RENDERER_BINAURAL_FASTCONV ) ) != IVAS_ERR_OK ) + { + return error; + } + + /* Allocate memories and buffers needed for convolutional module */ + if ( ( error = ivas_binRenderer_convModuleOpen( hBinRenderer, RENDERER_BINAURAL_FASTCONV, hBinRenderer->hInputSetup->is_loudspeaker_setup, inConfig, pCldfbRend->hHrtfFastConv, hBinRenderer->numPoses ) ) != IVAS_ERR_OK ) + { + return error; + } + + pCldfbRend->binaural_latency_ns = (int32_t) ( FASTCONV_HOA3_latency_s * 1000000000.f ); + hBinRenderer->hReverb = NULL; + hBinRenderer->hEFAPdata = NULL; + + pCldfbRend->hCldfbRend = hBinRenderer; + + return error; +} +#endif /*------------------------------------------------------------------------- @@ -904,6 +1103,20 @@ ivas_error ivas_binRenderer_open( hBinRenderer->rotInCldfb = 1; } +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + hBinRenderer->numPoses = st_ivas->hSplitBinRend.splitrend.multiBinPoseData.num_poses + 1; +#else + hBinRenderer->numPoses = st_ivas->hSplitBinRend.splitrend.multiBinPoseData.num_poses; +#endif + } + else + { + hBinRenderer->numPoses = 1; + } +#endif /* Declare some common variables needed for renderer */ /* Which format used for binaural rendering (needed for late reverb) ? MC or SBA */ @@ -948,7 +1161,11 @@ ivas_error ivas_binRenderer_open( IVAS_OUTPUT_SETUP out_setup; /* Allocate memories and buffers needed for convolutional module in CICP19 */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( error = ivas_binRenderer_convModuleOpen( hBinRenderer, st_ivas->renderer_type, 1, IVAS_AUDIO_CONFIG_7_1_4, st_ivas->hHrtfFastConv, hBinRenderer->numPoses ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_binRenderer_convModuleOpen( hBinRenderer, st_ivas->renderer_type, 1, IVAS_AUDIO_CONFIG_7_1_4, st_ivas->hHrtfFastConv ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -969,7 +1186,11 @@ ivas_error ivas_binRenderer_open( else { /* Allocate memories and buffers needed for convolutional module */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( error = ivas_binRenderer_convModuleOpen( hBinRenderer, st_ivas->renderer_type, st_ivas->hIntSetup.is_loudspeaker_setup, st_ivas->hIntSetup.output_config, st_ivas->hHrtfFastConv, hBinRenderer->numPoses ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_binRenderer_convModuleOpen( hBinRenderer, st_ivas->renderer_type, st_ivas->hIntSetup.is_loudspeaker_setup, st_ivas->hIntSetup.output_config, st_ivas->hHrtfFastConv ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -1066,10 +1287,18 @@ ivas_error ivas_binRenderer_open( *------------------------------------------------------------------------*/ static void ivas_binRenderer_convModuleClose( +#ifdef SPLIT_REND_WITH_HEAD_ROT + BINAURAL_RENDERER_HANDLE *hBinRenderer, /* i/o: fastconv binaural renderer handle */ + const int16_t num_poses /* i : number of poses */ +#else BINAURAL_RENDERER_HANDLE *hBinRenderer /* i/o: fastconv binaural renderer handle */ +#endif ) { int16_t bandIdx, chIdx; +#ifdef SPLIT_REND_WITH_HEAD_ROT + int16_t posIdx; +#endif BINRENDERER_CONV_MODULE_HANDLE hBinRenConvModule; hBinRenConvModule = ( *hBinRenderer )->hBinRenConvModule; @@ -1106,6 +1335,39 @@ static void ivas_binRenderer_convModuleClose( free( hBinRenConvModule->filterTapsRightImag ); hBinRenConvModule->filterTapsRightImag = NULL; +#ifdef SPLIT_REND_WITH_HEAD_ROT + for ( posIdx = 0; posIdx < num_poses; posIdx++ ) + { + for ( bandIdx = 0; bandIdx < ( *hBinRenderer )->conv_band; bandIdx++ ) + { + for ( chIdx = 0; chIdx < ( *hBinRenderer )->nInChannels; chIdx++ ) + { + free( hBinRenConvModule->filterStatesLeftReal[posIdx][bandIdx][chIdx] ); + hBinRenConvModule->filterStatesLeftReal[posIdx][bandIdx][chIdx] = NULL; + + free( hBinRenConvModule->filterStatesLeftImag[posIdx][bandIdx][chIdx] ); + hBinRenConvModule->filterStatesLeftImag[posIdx][bandIdx][chIdx] = NULL; + } + + free( hBinRenConvModule->filterStatesLeftReal[posIdx][bandIdx] ); + hBinRenConvModule->filterStatesLeftReal[posIdx][bandIdx] = NULL; + + free( hBinRenConvModule->filterStatesLeftImag[posIdx][bandIdx] ); + hBinRenConvModule->filterStatesLeftImag[posIdx][bandIdx] = NULL; + } + + free( hBinRenConvModule->filterStatesLeftReal[posIdx] ); + hBinRenConvModule->filterStatesLeftReal[posIdx] = NULL; + + free( hBinRenConvModule->filterStatesLeftImag[posIdx] ); + hBinRenConvModule->filterStatesLeftImag[posIdx] = NULL; + } + free( hBinRenConvModule->filterStatesLeftReal ); + hBinRenConvModule->filterStatesLeftReal = NULL; + + free( hBinRenConvModule->filterStatesLeftImag ); + hBinRenConvModule->filterStatesLeftImag = NULL; +#else for ( bandIdx = 0; bandIdx < ( *hBinRenderer )->conv_band; bandIdx++ ) { for ( chIdx = 0; chIdx < ( *hBinRenderer )->nInChannels; chIdx++ ) @@ -1129,6 +1391,7 @@ static void ivas_binRenderer_convModuleClose( free( hBinRenConvModule->filterStatesLeftImag ); hBinRenConvModule->filterStatesLeftImag = NULL; +#endif free( ( *hBinRenderer )->hBinRenConvModule ); ( *hBinRenderer )->hBinRenConvModule = NULL; @@ -1154,7 +1417,11 @@ void ivas_binRenderer_close( if ( ( *hBinRenderer )->hBinRenConvModule != NULL ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + ivas_binRenderer_convModuleClose( hBinRenderer, ( *hBinRenderer )->numPoses ); +#else ivas_binRenderer_convModuleClose( hBinRenderer ); +#endif } if ( ( *hBinRenderer )->hReverb != NULL ) @@ -1302,6 +1569,335 @@ void ivas_binaural_add_LFE( } +#ifdef DEBUGGING +/*-------------------------------------------------------------------------* + * ivas_binaural_cldfb() + * + * Perform CLDFB analysis, fastconv binaural rendering and CLDFB synthesis + *-------------------------------------------------------------------------*/ + +void ivas_binaural_cldfb( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + float *output_f[] /* i/o: synthesized core-coder transport channels/DirAC output */ +) +{ + float Cldfb_RealBuffer[MAX_INTERN_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; + float Cldfb_ImagBuffer[MAX_INTERN_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; +#ifdef SPLIT_REND_WITH_HEAD_ROT + float Cldfb_RealBuffer_Binaural[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; + float Cldfb_ImagBuffer_Binaural[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; +#else + float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; + float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; +#endif + int16_t slot_idx, subframeIdx, index_slot, idx_in, idx_lfe, maxBand, ch; + + /* Implement a 5 msec loops */ + maxBand = (int16_t) ( ( CLDFB_NO_CHANNELS_MAX * st_ivas->hDecoderConfig->output_Fs ) / 48000 ); + + for ( subframeIdx = 0; subframeIdx < ( CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES ); subframeIdx++ ) + { + for ( slot_idx = 0; slot_idx < MAX_PARAM_SPATIAL_SUBFRAMES; slot_idx++ ) + { + index_slot = subframeIdx * MAX_PARAM_SPATIAL_SUBFRAMES + slot_idx; + + /* Implement CLDFB analysis */ + idx_in = 0; + idx_lfe = 0; + + for ( ch = 0; ch < ( st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe ); ch++ ) + { + if ( ( st_ivas->hIntSetup.num_lfe > 0 ) && ( st_ivas->hIntSetup.index_lfe[idx_lfe] == ch ) ) + { + if ( idx_lfe < ( st_ivas->hIntSetup.num_lfe - 1 ) ) + { + idx_lfe++; + } + } + else + { + cldfbAnalysis_ts( &( output_f[ch][maxBand * index_slot] ), Cldfb_RealBuffer[idx_in][slot_idx], Cldfb_ImagBuffer[idx_in][slot_idx], maxBand, st_ivas->cldfbAnaDec[idx_in] ); + idx_in++; + } + } +#ifdef SPLIT_REND_WITH_HEAD_ROT + /*LFE handling for split rendering cases*/ + if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { + for ( idx_lfe = 0; idx_lfe < st_ivas->hIntSetup.num_lfe; idx_lfe++ ) + { + ch = st_ivas->hIntSetup.index_lfe[idx_lfe]; + cldfbAnalysis_ts( &( output_f[ch][maxBand * index_slot] ), Cldfb_RealBuffer[idx_in][slot_idx], Cldfb_ImagBuffer[idx_in][slot_idx], maxBand, st_ivas->cldfbAnaDec[idx_in] ); + idx_in++; + } + + if ( st_ivas->hSplitBinRend.hCldfbDataOut != NULL ) + { + for ( ch = 0; ch < ( st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe ); ch++ ) + { + mvr2r( Cldfb_RealBuffer[ch][slot_idx], st_ivas->hSplitBinRend.hCldfbDataOut->Cldfb_RealBuffer[ch][( subframeIdx * JBM_CLDFB_SLOTS_IN_SUBFRAME ) + slot_idx], maxBand ); + mvr2r( Cldfb_ImagBuffer[ch][slot_idx], st_ivas->hSplitBinRend.hCldfbDataOut->Cldfb_ImagBuffer[ch][( subframeIdx * JBM_CLDFB_SLOTS_IN_SUBFRAME ) + slot_idx], maxBand ); + } + st_ivas->hSplitBinRend.hCldfbDataOut->config = st_ivas->hIntSetup.output_config; + } + } +#endif + } + + /* Implement binaural rendering */ + ivas_binRenderer( + st_ivas->hBinRenderer, +#ifdef SPLIT_REND_WITH_HEAD_ROT + &st_ivas->hSplitBinRend.splitrend.multiBinPoseData, +#endif + st_ivas->hCombinedOrientationData, +#ifndef NONBE_UNIFIED_DECODING_PATHS + subframeIdx, +#endif + JBM_CLDFB_SLOTS_IN_SUBFRAME, +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + NULL, +#endif + Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, + Cldfb_RealBuffer, Cldfb_ImagBuffer ); + +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { + int16_t pos_idx; + for ( slot_idx = 0; slot_idx < JBM_CLDFB_SLOTS_IN_SUBFRAME; slot_idx++ ) + { + if ( st_ivas->hIntSetup.num_lfe > 0 ) + { + v_multc( Cldfb_RealBuffer[st_ivas->hIntSetup.nchan_out_woLFE][slot_idx], GAIN_LFE, Cldfb_RealBuffer[st_ivas->hIntSetup.nchan_out_woLFE][slot_idx], maxBand ); + v_multc( Cldfb_ImagBuffer[st_ivas->hIntSetup.nchan_out_woLFE][slot_idx], GAIN_LFE, Cldfb_ImagBuffer[st_ivas->hIntSetup.nchan_out_woLFE][slot_idx], maxBand ); + } + } + + for ( pos_idx = 0; pos_idx < st_ivas->hBinRenderer->numPoses; pos_idx++ ) + { + for ( slot_idx = 0; slot_idx < JBM_CLDFB_SLOTS_IN_SUBFRAME; slot_idx++ ) + { + for ( ch = 0; ch < st_ivas->hDecoderConfig->nchan_out; ch++ ) + { + if ( st_ivas->hIntSetup.num_lfe > 0 ) + { + v_add( Cldfb_RealBuffer_Binaural[pos_idx][ch][slot_idx], + Cldfb_RealBuffer[st_ivas->hIntSetup.nchan_out_woLFE][slot_idx], + Cldfb_RealBuffer_Binaural[pos_idx][ch][slot_idx], + maxBand ); + + v_add( Cldfb_ImagBuffer_Binaural[pos_idx][ch][slot_idx], + Cldfb_ImagBuffer[st_ivas->hIntSetup.nchan_out_woLFE][slot_idx], + Cldfb_ImagBuffer_Binaural[pos_idx][ch][slot_idx], + maxBand ); + } + + mvr2r( Cldfb_RealBuffer_Binaural[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend.hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[( pos_idx * BINAURAL_CHANNELS ) + ch][( subframeIdx * JBM_CLDFB_SLOTS_IN_SUBFRAME ) + slot_idx], maxBand ); + mvr2r( Cldfb_ImagBuffer_Binaural[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend.hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[( pos_idx * BINAURAL_CHANNELS ) + ch][( subframeIdx * JBM_CLDFB_SLOTS_IN_SUBFRAME ) + slot_idx], maxBand ); + } + } + } + } +#endif + +#ifdef NONBE_UNIFIED_DECODING_PATHS + /* update combined orientation access index */ + ivas_combined_orientation_update_index( st_ivas->hCombinedOrientationData, maxBand * MAX_PARAM_SPATIAL_SUBFRAMES ); +#endif + + /* Implement CLDFB synthesis */ + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + float *RealBuffer[MAX_PARAM_SPATIAL_SUBFRAMES]; + float *ImagBuffer[MAX_PARAM_SPATIAL_SUBFRAMES]; + + index_slot = subframeIdx * MAX_PARAM_SPATIAL_SUBFRAMES; + + for ( slot_idx = 0; slot_idx < MAX_PARAM_SPATIAL_SUBFRAMES; slot_idx++ ) + { +#ifdef SPLIT_REND_WITH_HEAD_ROT + RealBuffer[slot_idx] = Cldfb_RealBuffer_Binaural[0][ch][slot_idx]; + ImagBuffer[slot_idx] = Cldfb_ImagBuffer_Binaural[0][ch][slot_idx]; +#else + RealBuffer[slot_idx] = Cldfb_RealBuffer_Binaural[ch][slot_idx]; + ImagBuffer[slot_idx] = Cldfb_ImagBuffer_Binaural[ch][slot_idx]; +#endif + } + + cldfbSynthesis( RealBuffer, ImagBuffer, &( output_f[ch][index_slot * maxBand] ), maxBand * MAX_PARAM_SPATIAL_SUBFRAMES, st_ivas->cldfbSynDec[ch] ); + } + } + + return; +} + + +/*-------------------------------------------------------------------------* + * ivas_binaural_cldfb_sf() + * + * Perform CLDFB analysis, fastconv binaural rendering and CLDFB synthesis + *-------------------------------------------------------------------------*/ + +void ivas_binaural_cldfb_sf( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + const int16_t n_samples_to_render, /* i : output frame length per channel */ + const int16_t slot_size, /* i : JBM slot size */ + float *output_f[] /* i/o: synthesized core-coder transport channels/DirAC output */ +) +{ + float Cldfb_RealBuffer[MAX_INTERN_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; + float Cldfb_ImagBuffer[MAX_INTERN_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; +#ifdef SPLIT_REND_WITH_HEAD_ROT + float Cldfb_RealBuffer_Binaural[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; + float Cldfb_ImagBuffer_Binaural[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; +#else + float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; + float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; +#endif + int16_t slot_idx, subframeIdx, index_slot, idx_in, idx_lfe, maxBand, ch; + int16_t slots_to_render, first_sf, last_sf; + int16_t slot_index_start, slot_index_start_cldfb; + + /* Implement a 5 msec loops */ + maxBand = (int16_t) ( ( CLDFB_NO_CHANNELS_MAX * st_ivas->hDecoderConfig->output_Fs ) / 48000 ); + + /* loop for synthesis, assume we always have to render in multiples of 5ms subframes with spills */ + slots_to_render = min( st_ivas->hTcBuffer->num_slots - st_ivas->hTcBuffer->slots_rendered, n_samples_to_render / slot_size ); + first_sf = st_ivas->hTcBuffer->subframes_rendered; + last_sf = first_sf; + slot_index_start = st_ivas->hTcBuffer->slots_rendered; + slot_index_start_cldfb = 0; + st_ivas->hTcBuffer->slots_rendered += slots_to_render; + + while ( slots_to_render > 0 ) + { + slots_to_render -= st_ivas->hTcBuffer->subframe_nbslots[last_sf]; + last_sf++; + } + for ( subframeIdx = first_sf; subframeIdx < last_sf; subframeIdx++ ) + { + for ( slot_idx = 0; slot_idx < st_ivas->hTcBuffer->subframe_nbslots[subframeIdx]; slot_idx++ ) + { + index_slot = slot_index_start + slot_idx; + + /* Implement CLDFB analysis */ + idx_in = 0; + idx_lfe = 0; + + for ( ch = 0; ch < ( st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe ); ch++ ) + { + if ( ( st_ivas->hIntSetup.num_lfe > 0 ) && ( st_ivas->hIntSetup.index_lfe[idx_lfe] == ch ) ) + { + if ( idx_lfe < ( st_ivas->hIntSetup.num_lfe - 1 ) ) + { + idx_lfe++; + } + } + else + { + cldfbAnalysis_ts( &( st_ivas->hTcBuffer->tc[ch][maxBand * index_slot] ), Cldfb_RealBuffer[idx_in][slot_idx], Cldfb_ImagBuffer[idx_in][slot_idx], maxBand, st_ivas->cldfbAnaDec[idx_in] ); + idx_in++; + } + } + +#ifdef SPLIT_REND_WITH_HEAD_ROT + /*LFE handling for split rendering cases*/ + if ( ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || + ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) + { + for ( idx_lfe = 0; idx_lfe < st_ivas->hIntSetup.num_lfe; idx_lfe++ ) + { + ch = st_ivas->hIntSetup.index_lfe[idx_lfe]; + cldfbAnalysis_ts( &( output_f[ch][maxBand * index_slot] ), Cldfb_RealBuffer[idx_in][slot_idx], Cldfb_ImagBuffer[idx_in][slot_idx], maxBand, st_ivas->cldfbAnaDec[idx_in] ); + idx_in++; + } + +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( st_ivas->hSplitBinRend.hCldfbDataOut != NULL ) + { + for ( ch = 0; ch < ( st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe ); ch++ ) + { + mvr2r( Cldfb_RealBuffer[ch][slot_idx], st_ivas->hSplitBinRend.hCldfbDataOut->Cldfb_RealBuffer[ch][slot_index_start + slot_idx], maxBand ); + mvr2r( Cldfb_ImagBuffer[ch][slot_idx], st_ivas->hSplitBinRend.hCldfbDataOut->Cldfb_ImagBuffer[ch][slot_index_start + slot_idx], maxBand ); + } + st_ivas->hSplitBinRend.hCldfbDataOut->config = st_ivas->hIntSetup.output_config; + } +#endif + } +#endif + } + + /* Implement binaural rendering */ + ivas_binRenderer( + st_ivas->hBinRenderer, +#ifdef SPLIT_REND_WITH_HEAD_ROT + &st_ivas->hSplitBinRend.splitrend.multiBinPoseData, +#endif + st_ivas->hCombinedOrientationData, +#ifndef NONBE_UNIFIED_DECODING_PATHS + subframeIdx, +#endif + st_ivas->hTcBuffer->subframe_nbslots[subframeIdx], +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + NULL, +#endif + Cldfb_RealBuffer_Binaural, + Cldfb_ImagBuffer_Binaural, + Cldfb_RealBuffer, + Cldfb_ImagBuffer ); + +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { + int16_t pos_idx; + for ( pos_idx = 0; pos_idx < st_ivas->hBinRenderer->numPoses; pos_idx++ ) + { + for ( slot_idx = 0; slot_idx < st_ivas->hTcBuffer->subframe_nbslots[subframeIdx]; slot_idx++ ) + { + for ( ch = 0; ch < st_ivas->hDecoderConfig->nchan_out; ch++ ) + { + mvr2r( Cldfb_RealBuffer_Binaural[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend.hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[( pos_idx * BINAURAL_CHANNELS ) + ch][slot_index_start + slot_idx], maxBand ); + mvr2r( Cldfb_ImagBuffer_Binaural[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend.hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[( pos_idx * BINAURAL_CHANNELS ) + ch][slot_index_start + slot_idx], maxBand ); + } + } + } + } +#endif + +#ifdef NONBE_UNIFIED_DECODING_PATHS + /* update combined orientation access index */ + ivas_combined_orientation_update_index( st_ivas->hCombinedOrientationData, maxBand * st_ivas->hTcBuffer->subframe_nbslots[subframeIdx] ); +#endif + + /* Implement CLDFB synthesis */ + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + float *RealBuffer[MAX_PARAM_SPATIAL_SUBFRAMES]; + float *ImagBuffer[MAX_PARAM_SPATIAL_SUBFRAMES]; + + for ( slot_idx = 0; slot_idx < st_ivas->hTcBuffer->subframe_nbslots[subframeIdx]; slot_idx++ ) + { +#ifdef SPLIT_REND_WITH_HEAD_ROT + RealBuffer[slot_idx] = Cldfb_RealBuffer_Binaural[0][ch][slot_idx]; + ImagBuffer[slot_idx] = Cldfb_ImagBuffer_Binaural[0][ch][slot_idx]; +#else + RealBuffer[slot_idx] = Cldfb_RealBuffer_Binaural[ch][slot_idx]; + ImagBuffer[slot_idx] = Cldfb_ImagBuffer_Binaural[ch][slot_idx]; +#endif + } + + cldfbSynthesis( RealBuffer, ImagBuffer, &( output_f[ch][slot_index_start_cldfb * maxBand] ), maxBand * st_ivas->hTcBuffer->subframe_nbslots[subframeIdx], st_ivas->cldfbSynDec[ch] ); + } + slot_index_start += st_ivas->hTcBuffer->subframe_nbslots[subframeIdx]; + slot_index_start_cldfb += st_ivas->hTcBuffer->subframe_nbslots[subframeIdx]; + } + + st_ivas->hTcBuffer->subframes_rendered = last_sf; + + return; +} +#endif /*------------------------------------------------------------------------- @@ -1312,20 +1908,53 @@ void ivas_binaural_add_LFE( void ivas_binRenderer( BINAURAL_RENDERER_HANDLE hBinRenderer, /* i/o: binaural renderer handle */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + const MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, +#endif COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i : combined head and external orientation handle*/ +#ifndef NONBE_UNIFIED_DECODING_PATHS + int16_t subframe_idx, /* i : subframe index */ +#endif const int16_t numTimeSlots, /* i : number of time slots to render */ +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + HEAD_TRACK_DATA_HANDLE hPostRendHeadTrackData, +#endif +#ifdef SPLIT_REND_WITH_HEAD_ROT + float Cldfb_RealBuffer_Binaural[][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : Rotated Binaural signals */ + float Cldfb_ImagBuffer_Binaural[][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : Rotated Binaural signals */ +#else float Cldfb_RealBuffer_Binaural[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : Binaural signals */ float Cldfb_ImagBuffer_Binaural[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* o : Binaural signals */ +#endif float RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i : LS signals */ float ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX] /* i : LS signals */ ) { int16_t chIdx, k; +#ifdef SPLIT_REND_WITH_HEAD_ROT + int16_t pos_idx, num_poses; +#endif push_wmops( "fastconv_binaural_rendering" ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + num_poses = hBinRenderer->numPoses; +#endif /* Compute Convolution */ /* memory reset for the binaural output */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + for ( pos_idx = 0; pos_idx < num_poses; pos_idx++ ) + { + for ( chIdx = 0; chIdx < BINAURAL_CHANNELS; chIdx++ ) + { + for ( k = 0; k < numTimeSlots; k++ ) + { + set_zero( Cldfb_RealBuffer_Binaural[pos_idx][chIdx][k], CLDFB_NO_CHANNELS_MAX ); + set_zero( Cldfb_ImagBuffer_Binaural[pos_idx][chIdx][k], CLDFB_NO_CHANNELS_MAX ); + } + } + } +#else for ( chIdx = 0; chIdx < BINAURAL_CHANNELS; chIdx++ ) { for ( k = 0; k < numTimeSlots; k++ ) @@ -1334,26 +1963,43 @@ void ivas_binRenderer( set_zero( Cldfb_ImagBuffer_Binaural[chIdx][k], CLDFB_NO_CHANNELS_MAX ); } } +#endif /* Head rotation in HOA3 or CICPx */ +#ifdef NONBE_UNIFIED_DECODING_PATHS if ( hCombinedOrientationData != NULL && hCombinedOrientationData->enableCombinedOrientation[hCombinedOrientationData->subframe_idx] && hBinRenderer->rotInCldfb ) +#else + if ( hCombinedOrientationData != NULL && hCombinedOrientationData->enableCombinedOrientation[subframe_idx] && hBinRenderer->rotInCldfb ) +#endif { if ( hBinRenderer->hInputSetup->is_loudspeaker_setup == 0 ) { /* Rotation in SHD (HOA3) */ if ( hCombinedOrientationData->shd_rot_max_order == -1 ) { +#ifdef NONBE_UNIFIED_DECODING_PATHS rotateFrame_shd_cldfb( RealBuffer, ImagBuffer, hCombinedOrientationData->Rmat[hCombinedOrientationData->subframe_idx], hBinRenderer->hInputSetup->nchan_out_woLFE, numTimeSlots, 3 ); +#else + rotateFrame_shd_cldfb( RealBuffer, ImagBuffer, hCombinedOrientationData->Rmat[subframe_idx], hBinRenderer->hInputSetup->nchan_out_woLFE, numTimeSlots, 3 ); +#endif } else if ( hCombinedOrientationData->shd_rot_max_order > 0 ) { +#ifdef NONBE_UNIFIED_DECODING_PATHS rotateFrame_shd_cldfb( RealBuffer, ImagBuffer, hCombinedOrientationData->Rmat[hCombinedOrientationData->subframe_idx], hBinRenderer->hInputSetup->nchan_out_woLFE, numTimeSlots, hCombinedOrientationData->shd_rot_max_order ); +#else + rotateFrame_shd_cldfb( RealBuffer, ImagBuffer, hCombinedOrientationData->Rmat[subframe_idx], hBinRenderer->hInputSetup->nchan_out_woLFE, numTimeSlots, hCombinedOrientationData->shd_rot_max_order ); +#endif } } else { /* Rotation in SD (CICPx) */ +#ifdef NONBE_UNIFIED_DECODING_PATHS rotateFrame_sd_cldfb( hCombinedOrientationData->Rmat[hCombinedOrientationData->subframe_idx], RealBuffer, ImagBuffer, hBinRenderer->hInputSetup, hBinRenderer->hEFAPdata, numTimeSlots, hBinRenderer->conv_band ); +#else + rotateFrame_sd_cldfb( hCombinedOrientationData->Rmat[subframe_idx], RealBuffer, ImagBuffer, hBinRenderer->hInputSetup, hBinRenderer->hEFAPdata, numTimeSlots, hBinRenderer->conv_band ); +#endif } } @@ -1363,8 +2009,75 @@ void ivas_binRenderer( ivas_sba2mc_cldfb( *( hBinRenderer->hInputSetup ), RealBuffer, ImagBuffer, hBinRenderer->nInChannels, hBinRenderer->conv_band, numTimeSlots, hBinRenderer->hoa_dec_mtx ); } +#ifdef SPLIT_REND_WITH_HEAD_ROT + ivas_binRenderer_filterModule( Cldfb_RealBuffer_Binaural[0], Cldfb_ImagBuffer_Binaural[0], RealBuffer, ImagBuffer, numTimeSlots, hBinRenderer, 0 ); +#else ivas_binRenderer_filterModule( Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, RealBuffer, ImagBuffer, numTimeSlots, hBinRenderer ); +#endif + +#ifdef SPLIT_REND_WITH_HEAD_ROT + /*TODO : move this to a separate function*/ + if ( pMultiBinPoseData != NULL ) + { + if ( pMultiBinPoseData->num_poses > 1 ) + { + IVAS_QUATERNION Quaternions_rel, Quaternions_abs, *Quaternions_ref; + float Rmat_local[3][3]; + + if ( hCombinedOrientationData && hBinRenderer->rotInCldfb ) + { + Quaternions_ref = &hCombinedOrientationData->Quaternions[0]; + Quaternions_rel.w = -3.0f; /*euler*/ + Quaternions_abs.w = -3.0f; /*euler*/ + Quat2EulerDegree( *Quaternions_ref, &Quaternions_abs.z, &Quaternions_abs.y, &Quaternions_abs.x ); /*order in Quat2Euler seems to be reversed ?*/ + + for ( pos_idx = 1; pos_idx < pMultiBinPoseData->num_poses; pos_idx++ ) + { + Quaternions_rel.x = pMultiBinPoseData->relative_head_poses[pos_idx][0] - pMultiBinPoseData->relative_head_poses[pos_idx - 1][0]; + Quaternions_rel.y = pMultiBinPoseData->relative_head_poses[pos_idx][1] - pMultiBinPoseData->relative_head_poses[pos_idx - 1][1]; + Quaternions_rel.z = pMultiBinPoseData->relative_head_poses[pos_idx][2] - pMultiBinPoseData->relative_head_poses[pos_idx - 1][2]; + Quaternions_abs.x = Quaternions_abs.x + Quaternions_rel.x; + Quaternions_abs.y = Quaternions_abs.y + Quaternions_rel.y; + Quaternions_abs.z = Quaternions_abs.z + Quaternions_rel.z; + + QuatToRotMat( Quaternions_rel, Rmat_local ); + + if ( hBinRenderer->hInputSetup->is_loudspeaker_setup ) + { + rotateFrame_sd_cldfb( Rmat_local, RealBuffer, ImagBuffer, hBinRenderer->hInputSetup, hBinRenderer->hEFAPdata, numTimeSlots, hBinRenderer->conv_band ); + } + else + { + rotateFrame_shd_cldfb( RealBuffer, ImagBuffer, Rmat_local, hBinRenderer->hInputSetup->nchan_out_woLFE, numTimeSlots, 3 ); + } + + ivas_binRenderer_filterModule( Cldfb_RealBuffer_Binaural[pos_idx], Cldfb_ImagBuffer_Binaural[pos_idx], RealBuffer, ImagBuffer, numTimeSlots, hBinRenderer, pos_idx ); + } +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + if ( hPostRendHeadTrackData != NULL ) + { + IVAS_QUATERNION *Quaternions_new1; + IVAS_QUATERNION Quaternions_new; + Quaternions_new1 = &hPostRendHeadTrackData->Quaternions[hPostRendHeadTrackData->num_quaternions++]; + Quaternions_new.w = -3.0f; /*euler*/ + Quat2EulerDegree( *Quaternions_new1, &Quaternions_new.z, &Quaternions_new.y, &Quaternions_new.x ); /*order in Quat2Euler seems to be reversed ?*/ + Quaternions_rel.x = Quaternions_new.x - Quaternions_abs.x; + Quaternions_rel.y = Quaternions_new.y - Quaternions_abs.y; + Quaternions_rel.z = Quaternions_new.z - Quaternions_abs.z; + Quaternions_abs.x = Quaternions_abs.x + Quaternions_rel.x; + Quaternions_abs.y = Quaternions_abs.y + Quaternions_rel.y; + Quaternions_abs.z = Quaternions_abs.z + Quaternions_rel.z; + + QuatToRotMat( Quaternions_rel, Rmat_local ); + rotateFrame_shd_cldfb( RealBuffer, ImagBuffer, Rmat_local, hBinRenderer->hInputSetup->nchan_out_woLFE, 3 ); + ivas_binRenderer_filterModule( Cldfb_RealBuffer_Binaural[num_poses], Cldfb_ImagBuffer_Binaural[num_poses], RealBuffer, ImagBuffer, numTimeSlots, hBinRenderer, num_poses ); + } +#endif + } + } + } +#endif /* Obtain the binaural dmx and compute the reverb */ if ( hBinRenderer->hReverb != NULL ) @@ -1392,9 +2105,18 @@ void ivas_binRenderer( { for ( k = 0; k < numTimeSlots; k++ ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + for ( pos_idx = 0; pos_idx < num_poses; pos_idx++ ) + { + /* Combine first and second parts to generate binaural output signal with room effect */ + v_add( Cldfb_RealBuffer_Binaural[pos_idx][chIdx][k], reverbRe[chIdx][k], Cldfb_RealBuffer_Binaural[pos_idx][chIdx][k], hBinRenderer->conv_band ); + v_add( Cldfb_ImagBuffer_Binaural[pos_idx][chIdx][k], reverbIm[chIdx][k], Cldfb_ImagBuffer_Binaural[pos_idx][chIdx][k], hBinRenderer->conv_band ); + } +#else /* Combine first and second parts to generate binaural output signal with room effect */ v_add( Cldfb_RealBuffer_Binaural[chIdx][k], reverbRe[chIdx][k], Cldfb_RealBuffer_Binaural[chIdx][k], hBinRenderer->conv_band ); v_add( Cldfb_ImagBuffer_Binaural[chIdx][k], reverbIm[chIdx][k], Cldfb_ImagBuffer_Binaural[chIdx][k], hBinRenderer->conv_band ); +#endif } } } @@ -1404,3 +2126,98 @@ void ivas_binRenderer( } +#ifdef SPLIT_REND_WITH_HEAD_ROT +/*------------------------------------------------------------------------- + * ivas_rend_CldfbMultiBinRendProcess() + * + * + *-------------------------------------------------------------------------*/ + +void ivas_rend_CldfbMultiBinRendProcess( + const BINAURAL_RENDERER_HANDLE hCldfbRend, + const COMBINED_ORIENTATION_HANDLE *pCombinedOrientationData, + const MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + float Cldfb_In_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + float Cldfb_In_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + float Cldfb_Out_Real[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* o : Binaural signals */ + float Cldfb_Out_Imag[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + const int16_t low_res_pre_rend_rot, + const int16_t num_subframes ) +{ + int16_t slot_idx, ch_idx, idx, pose_idx, i, j; + int16_t sf_idx; + float Cldfb_RealBuffer_sfIn[MAX_INPUT_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; + float Cldfb_ImagBuffer_sfIn[MAX_INPUT_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + HEAD_TRACK_DATA head_track_post; + float Cldfb_RealBuffer_Binaural[MAX_HEAD_ROT_POSES + 1][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; + float Cldfb_ImagBuffer_Binaural[MAX_HEAD_ROT_POSES + 1][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; +#else + float Cldfb_RealBuffer_Binaural[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; + float Cldfb_ImagBuffer_Binaural[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; +#endif + + for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) + { + for ( slot_idx = 0; slot_idx < MAX_PARAM_SPATIAL_SUBFRAMES; slot_idx++ ) + { + idx = sf_idx * MAX_PARAM_SPATIAL_SUBFRAMES + slot_idx; + for ( ch_idx = 0; ch_idx < hCldfbRend->nInChannels; ch_idx++ ) + { + mvr2r( &Cldfb_In_Real[ch_idx][idx][0], &Cldfb_RealBuffer_sfIn[ch_idx][slot_idx][0], hCldfbRend->max_band ); + mvr2r( &Cldfb_In_Imag[ch_idx][idx][0], &Cldfb_ImagBuffer_sfIn[ch_idx][slot_idx][0], hCldfbRend->max_band ); + } + } + + if ( ( *pCombinedOrientationData ) != NULL ) + { + if ( ( low_res_pre_rend_rot ) && ( pMultiBinPoseData->poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) ) + { + ( *pCombinedOrientationData )->Quaternions[sf_idx] = ( *pCombinedOrientationData )->Quaternions[0]; + for ( i = 0; i < 3; i++ ) + { + for ( j = 0; j < 3; j++ ) + { + ( *pCombinedOrientationData )->Rmat[sf_idx][i][j] = ( *pCombinedOrientationData )->Rmat[0][i][j]; + } + } + } + ( *pCombinedOrientationData )->shd_rot_max_order = -1; + } + +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + head_track_post.num_quaternions = 0; + head_track_post.shd_rot_max_order = -1; + head_track_post.Quaternions[0] = ivas_split_rend_get_sf_rot_data( pHeadRotData->headPositionsPostRend, sf_idx ); +#endif + +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG +#ifdef NONBE_UNIFIED_DECODING_PATHS + ivas_binRenderer( hCldfbRend, pMultiBinPoseData, *pCombinedOrientationData, MAX_PARAM_SPATIAL_SUBFRAMES, &head_track_post, Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, Cldfb_RealBuffer_sfIn, Cldfb_ImagBuffer_sfIn ); +#else + ivas_binRenderer( hCldfbRend, pMultiBinPoseData, *pCombinedOrientationData, sf_idx, MAX_PARAM_SPATIAL_SUBFRAMES, &head_track_post, Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, Cldfb_RealBuffer_sfIn, Cldfb_ImagBuffer_sfIn ); +#endif +#else +#ifdef NONBE_UNIFIED_DECODING_PATHS + ivas_binRenderer( hCldfbRend, pMultiBinPoseData, *pCombinedOrientationData, MAX_PARAM_SPATIAL_SUBFRAMES, Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, Cldfb_RealBuffer_sfIn, Cldfb_ImagBuffer_sfIn ); +#else + ivas_binRenderer( hCldfbRend, pMultiBinPoseData, *pCombinedOrientationData, sf_idx, MAX_PARAM_SPATIAL_SUBFRAMES, Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, Cldfb_RealBuffer_sfIn, Cldfb_ImagBuffer_sfIn ); +#endif +#endif + for ( pose_idx = 0; pose_idx < hCldfbRend->numPoses; pose_idx++ ) + { + for ( slot_idx = 0; slot_idx < MAX_PARAM_SPATIAL_SUBFRAMES; slot_idx++ ) + { + idx = sf_idx * MAX_PARAM_SPATIAL_SUBFRAMES + slot_idx; + for ( ch_idx = 0; ch_idx < BINAURAL_CHANNELS; ch_idx++ ) + { + mvr2r( &Cldfb_RealBuffer_Binaural[pose_idx][ch_idx][slot_idx][0], &Cldfb_Out_Real[( pose_idx * BINAURAL_CHANNELS ) + ch_idx][idx][0], hCldfbRend->max_band ); + mvr2r( &Cldfb_ImagBuffer_Binaural[pose_idx][ch_idx][slot_idx][0], &Cldfb_Out_Imag[( pose_idx * BINAURAL_CHANNELS ) + ch_idx][idx][0], hCldfbRend->max_band ); + } + } + } + } + + return; +} +#endif diff --git a/lib_dec/ivas_core_dec.c b/lib_dec/ivas_core_dec.c index aa3c2a8c8..423a673e8 100644 --- a/lib_dec/ivas_core_dec.c +++ b/lib_dec/ivas_core_dec.c @@ -32,6 +32,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include #include "cnst.h" @@ -40,6 +43,9 @@ #include "ivas_prot.h" #include "ivas_rom_com.h" #include "wmc_auto.h" +#ifdef DEBUG_PLOT +#include "deb_out.h" +#endif /*-------------------------------------------------------------------* @@ -106,7 +112,11 @@ ivas_error ivas_core_dec( sts = hSCE->hCoreCoder; hStereoICBWE = NULL; element_brate = hSCE->element_brate; +#ifdef FIX_902_HACK_IN_CORECODER last_element_brate = hSCE->last_element_brate; /* note: this parameter is unused */ +#else + last_element_brate = hSCE->element_brate; /* hack - the past parameter is not really needed */ +#endif last_element_mode = IVAS_SCE; hStereoTD = NULL; p_output_mem = NULL; @@ -425,6 +435,9 @@ ivas_error ivas_core_dec( for ( n = 0; n < n_channels; n++ ) { +#ifdef DEBUG_PLOT + setDeboutVars( -1, -1, n, -1 ); +#endif st = sts[n]; /*---------------------------------------------------------------------* @@ -709,6 +722,9 @@ ivas_error ivas_core_dec( mvr2r( synth[n], output[n], output_frame ); +#ifdef DEBUG_PLOT + sendDebout( "mdct_dec", output_frame, 1, "aftLPD", MTV_FLOAT, output[n] ); +#endif /*--------------------------------------------------------* * Common updates *--------------------------------------------------------*/ @@ -722,9 +738,126 @@ ivas_error ivas_core_dec( } /* n_channels loop */ +#ifdef DEBUG_MODE_INFO + output_debug_mode_info_dec( sts, n_channels, output_frame, pitch_buf ); +#endif pop_wmops(); return error; } +#ifdef DEBUG_MODE_INFO +/*-------------------------------------------------------------------* + * output_debug_mode_info_dec() + * + * Debugging function to output most important codec parameters + *-------------------------------------------------------------------*/ + +void output_debug_mode_info_dec( + Decoder_State **sts, + const int16_t n_channels, + const int16_t output_frame, + float pitch_buf[CPE_CHANNELS][NB_SUBFR16k] ) +{ + int16_t n; + Decoder_State *st; + + for ( n = 0; n < n_channels; n++ ) + { + float tmpF; + int16_t tmpS, id; + + if ( pitch_buf == NULL ) + { + /* very first frame is lost */ + id = 0; + } + else + { + id = sts[n]->id_element; + } + + st = sts[n]; + + dbgwrite( &st->core, sizeof( int16_t ), 1, output_frame, fname( debug_dir, "core", n, id, DEC ) ); + dbgwrite( &st->extl, sizeof( int16_t ), 1, output_frame, fname( debug_dir, "extl", n, id, DEC ) ); + dbgwrite( &st->bwidth, sizeof( int16_t ), 1, output_frame, fname( debug_dir, "bwidth", n, id, DEC ) ); + dbgwrite( &st->cng_type, sizeof( int16_t ), 1, output_frame, fname( debug_dir, "cng_type", n, id, DEC ) ); + dbgwrite( &st->clas_dec, sizeof( int16_t ), 1, output_frame, fname( debug_dir, "clas", n, id, DEC ) ); + tmpF = st->extl_brate / 1000.0f; + dbgwrite( &tmpF, sizeof( float ), 1, output_frame, fname( debug_dir, "extl_brate", n, id, DEC ) ); + tmpF = st->core_brate / 1000.0f; + dbgwrite( &tmpF, sizeof( float ), 1, output_frame, fname( debug_dir, "core_brate", n, id, DEC ) ); + tmpF = st->total_brate / 1000.0f; + dbgwrite( &tmpF, sizeof( float ), 1, output_frame, fname( debug_dir, "total_brate", n, id, DEC ) ); + tmpS = st->bits_frame_nominal; + dbgwrite( &tmpS, sizeof( int16_t ), 1, output_frame, fname( debug_dir, "bits_nominal", n, id, DEC ) ); + +#ifdef DEBUG_MODE_INFO_PLC + dbgwrite( &st->last_core_bfi, sizeof( int16_t ), 1, output_frame, fname( debug_dir, "last_core_bfi", n, id, DEC ) ); + dbgwrite( &st->second_last_core, sizeof( int16_t ), 1, output_frame, fname( debug_dir, "second_last_core", n, id, DEC ) ); + dbgwrite( &st->con_tcx, sizeof( int16_t ), 1, output_frame, fname( debug_dir, "con_tcx", n, id, DEC ) ); + dbgwrite( &st->last_con_tcx, sizeof( int16_t ), 1, output_frame, fname( debug_dir, "last_con_tcx", n, id, DEC ) ); + dbgwrite( &st->prev_bfi, sizeof( int16_t ), 1, output_frame, fname( debug_dir, "prev_bfi", n, id, DEC ) ); + dbgwrite( &st->prev_old_bfi, sizeof( int16_t ), 1, output_frame, fname( debug_dir, "prev_old_bfi", n, id, DEC ) ); +#endif + + if ( pitch_buf != NULL ) + { + dbgwrite( &st->coder_type, sizeof( int16_t ), 1, output_frame, fname( debug_dir, "coder_type", n, id, DEC ) ); + } + else + { + tmpS = -1; + dbgwrite( &tmpS, sizeof( int16_t ), 1, output_frame, fname( debug_dir, "coder_type", n, id, DEC ) ); + } + + if ( st->hTcxCfg != NULL ) + tmpS = st->hTcxCfg->coder_type; + else + tmpS = -1; +#ifdef DEBUG_MODE_TCX + dbgwrite( &tmpS, sizeof( int16_t ), 1, output_frame, fname( debug_dir, "tcx_core_type", n, id, DEC ) ); +#endif + dbgwrite( &st->L_frame, sizeof( int16_t ), 1, output_frame, fname( debug_dir, "L_frame", n, id, DEC ) ); + dbgwrite( &st->VAD, 2, 1, output_frame, fname( debug_dir, "VAD", n, id, DEC ) ); + dbgwrite( &st->flag_cna, sizeof( int16_t ), 1, output_frame, fname( debug_dir, "cna_flag", n, id, DEC ) ); + +#if ( defined DEBUG_MODE_ACELP ) || ( defined DEBUG_MODE_TCX ) + if ( pitch_buf != NULL && st->core != HQ_CORE ) + { + int16_t i; + for ( i = 0; i < ( st->L_frame / L_SUBFR ); i++ ) + { + dbgwrite( &pitch_buf[n][i], sizeof( float ), 1, output_frame / ( st->L_frame / L_SUBFR ), fname( debug_dir, "pitch_buf", n, id, DEC ) ); + } + } + else + { + tmpF = 0; + dbgwrite( &tmpF, sizeof( float ), 1, output_frame, fname( debug_dir, "pitch_buf", n, id, DEC ) ); + } +#endif + +#ifdef DEBUG_MODE_ACELP + if ( st->core != ACELP_CORE ) + { + tmpF = 0.0f; + dbgwrite( &tmpF, sizeof( float ), 1, st->L_frame, fname( debug_dir, "exc", n, id, DEC ) ); + dbgwrite( &tmpF, sizeof( float ), 1, output_frame, fname( debug_dir, "output.Fs", n, id, DEC ) ); + dbgwrite( &tmpF, sizeof( float ), 1, min( st->L_frame, L_FRAME16k ), fname( debug_dir, "syn.intFs", n, id, DEC ) ); + } + + if ( sts[0]->element_mode == IVAS_CPE_DFT ) + { + tmpF = 0.0f; + dbgwrite( &tmpF, sizeof( float ), 1, output_frame, fname( debug_dir, "output.Fs", 1, id, DEC ) ); + dbgwrite( &tmpF, sizeof( float ), 1, L_FRAME, fname( debug_dir, "syn.intFs", 1, id, DEC ) ); + } +#endif + } + + return; +} +#endif diff --git a/lib_dec/ivas_corecoder_dec_reconfig.c b/lib_dec/ivas_corecoder_dec_reconfig.c index e8d73d28c..14d7ce1dd 100644 --- a/lib_dec/ivas_corecoder_dec_reconfig.c +++ b/lib_dec/ivas_corecoder_dec_reconfig.c @@ -35,6 +35,9 @@ #include "ivas_prot.h" #include "prot.h" #include +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" @@ -61,8 +64,10 @@ ivas_error ivas_corecoder_dec_reconfig( MC_MODE last_mc_mode; DECODER_CONFIG_HANDLE hDecoderConfig; ivas_error error; +#ifdef NONBE_FIX_862_UBSAN_SPAR_DEC_BR_SW_PLC int16_t prev_bfi; Decoder_State *st0; +#endif /*-----------------------------------------------------------------* * Initialization @@ -140,8 +145,10 @@ ivas_error ivas_corecoder_dec_reconfig( } else { +#ifdef NONBE_FIX_862_UBSAN_SPAR_DEC_BR_SW_PLC st0 = ( nSCE_old > 0 ) ? st_ivas->hSCE[0]->hCoreCoder[0] : st_ivas->hCPE[0]->hCoreCoder[0]; prev_bfi = st0->prev_bfi; +#endif nSCE_existing = min( nSCE_old, st_ivas->nSCE ); nCPE_existing = min( nCPE_old, st_ivas->nCPE ); @@ -214,7 +221,9 @@ ivas_error ivas_corecoder_dec_reconfig( { return error; } +#ifdef NONBE_FIX_862_UBSAN_SPAR_DEC_BR_SW_PLC st_ivas->hSCE[sce_id]->hCoreCoder[0]->prev_bfi = prev_bfi; +#endif } if ( st_ivas->sba_dirac_stereo_flag && sba_dirac_stereo_flag_old && st_ivas->nchan_transport == 1 && nSCE_old == 0 ) { @@ -243,8 +252,10 @@ ivas_error ivas_corecoder_dec_reconfig( { return error; } +#ifdef NONBE_FIX_862_UBSAN_SPAR_DEC_BR_SW_PLC st_ivas->hCPE[cpe_id]->hCoreCoder[0]->prev_bfi = prev_bfi; st_ivas->hCPE[cpe_id]->hCoreCoder[1]->prev_bfi = prev_bfi; +#endif } if ( st_ivas->nCPE > 1 && nCPE_old <= 1 ) diff --git a/lib_dec/ivas_cpe_dec.c b/lib_dec/ivas_cpe_dec.c index 85c7b7a11..140b33622 100644 --- a/lib_dec/ivas_cpe_dec.c +++ b/lib_dec/ivas_cpe_dec.c @@ -39,6 +39,9 @@ #include "prot.h" #include "ivas_prot.h" #include "ivas_rom_com.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" #include @@ -135,6 +138,9 @@ ivas_error ivas_cpe_dec( sts[n]->tdm_LRTD_flag = 0; } +#ifdef DEBUGGING + sts[n]->id_element = cpe_id + st_ivas->nSCE; +#endif /* TD stereo parameters */ if ( hCPE->hStereoTD != NULL ) { @@ -242,8 +248,10 @@ ivas_error ivas_cpe_dec( { nb_bits -= SID_FORMAT_NBITS; sts[1]->bit_stream -= SID_FORMAT_NBITS; +#ifdef NONBE_FIX_878_RS_FEC_STEREO_CNG /* set total bitrate of Stereo CNG parameters for BER detection */ sts[1]->total_brate = IVAS_SID_5k2 - SID_2k40; +#endif } if ( ( ( st_ivas->ivas_format == MASA_FORMAT && ivas_total_brate < MASA_STEREO_MIN_BITRATE ) || ( st_ivas->ivas_format == MASA_ISM_FORMAT && cpe_brate < MASA_STEREO_MIN_BITRATE ) ) && ivas_total_brate > IVAS_SID_5k2 ) @@ -252,6 +260,7 @@ ivas_error ivas_cpe_dec( } else { +#ifdef NONBE_FIX_913_OMASA_BITBUDGET_VIOLATION if ( st_ivas->ivas_format == MASA_FORMAT || st_ivas->ivas_format == MASA_ISM_FORMAT ) { nb_bits -= nb_bits_metadata; @@ -261,6 +270,7 @@ ivas_error ivas_cpe_dec( } } +#endif stereo_dft_dec_read_BS( ivas_total_brate, hCPE->element_brate, &sts[0]->total_brate, sts[1], hCPE->hStereoDft, sts[0]->bwidth, output_frame, res_buf, &nb_bits, hCPE->hStereoCng->coh, st_ivas->ivas_format ); } @@ -515,11 +525,14 @@ ivas_error ivas_cpe_dec( applyDmxMdctStereo( hCPE, output, output_frame ); } +#ifndef DEBUG_STEREO_DFT_OUTRESPRED /*----------------------------------------------------------------* * IC-BWE: output LB and HB mix in ACELP mode *----------------------------------------------------------------*/ +#ifndef DEBUG_STEREO_DFT_NOCORE stereo_icBWE_decproc( hCPE, output, outputHB, last_core, last_bwidth, output_frame ); +#endif smooth_dft2td_transition( hCPE, output, output_frame ); @@ -528,6 +541,7 @@ ivas_error ivas_cpe_dec( *----------------------------------------------------------------*/ stereo_tca_dec( hCPE, output, output_frame ); +#endif /*----------------------------------------------------------------* * Common Stereo updates @@ -549,6 +563,36 @@ ivas_error ivas_cpe_dec( st_ivas->BER_detect |= sts[0]->BER_detect; st_ivas->BER_detect |= sts[1]->BER_detect; +#ifdef DEBUG_MODE_INFO + { + float tmpF = hCPE->element_brate / 1000.0f; + + n = 1; + if ( st_ivas->ini_frame == 0 && frame > 0 ) + { + /* in case first frame(s) is/are lost, write info several times */ + n = (int16_t) frame - st_ivas->ini_frame + 1; + } + + for ( i = 0; i < n; i++ ) + { + dbgwrite( &tmpF, sizeof( float ), 1, output_frame, fname( debug_dir, "element_brate", 0, cpe_id, DEC ) ); + dbgwrite( &hCPE->element_mode, sizeof( int16_t ), 1, output_frame, fname( debug_dir, "element_mode", 0, cpe_id, DEC ) ); + + for ( int16_t j = 0; j < CPE_CHANNELS; j++ ) + { + dbgwrite( output[j], sizeof( float ), output_frame, 1, fname( debug_dir, "output.cpe", j, cpe_id, DEC ) ); + } + + if ( st_ivas->ivas_format != MASA_ISM_FORMAT ) + { + tmpF = 0; + dbgwrite( &tmpF, sizeof( float ), 1, output_frame, fname( debug_dir, "output.sce", 0, cpe_id, DEC ) ); + dbgwrite( &tmpF, sizeof( float ), 1, output_frame, fname( debug_dir, "output.mct", 0, cpe_id, DEC ) ); + } + } + } +#endif pop_wmops(); return error; diff --git a/lib_dec/ivas_dec.c b/lib_dec/ivas_dec.c index e32a69539..7ed71d5d6 100644 --- a/lib_dec/ivas_dec.c +++ b/lib_dec/ivas_dec.c @@ -39,6 +39,9 @@ #include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_rom_com.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" @@ -48,6 +51,7 @@ * Principal IVAS decoder routine *--------------------------------------------------------------------------*/ +#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX ivas_error ivas_dec( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ int16_t *data /* o : output synthesis signal */ @@ -59,3 +63,1121 @@ ivas_error ivas_dec( return IVAS_ERR_OK; } +#else +ivas_error ivas_dec( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + const PCM_RESOLUTION pcm_resolution, /* i : type for the decoded PCM resolution */ + void *data /* o : output synthesis signal */ +#else + int16_t *data /* o : output synthesis signal */ +#endif +) +{ + int16_t n, output_frame, nchan_out; + Decoder_State *st; /* used for bitstream handling */ + float *p_output[MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS]; /* 'float' buffer for output synthesis */ + int16_t nchan_remapped; + int16_t nb_bits_metadata[MAX_SCE + 1]; + int32_t output_Fs, ivas_total_brate; + AUDIO_CONFIG output_config; + ivas_error error; + int16_t num_md_sub_frames; + int32_t ism_total_brate; +#ifdef SPLIT_REND_WITH_HEAD_ROT + int16_t nchan_out_syn_output; +#endif + + push_wmops( "ivas_dec" ); + + /*----------------------------------------------------------------* + * Initialization of local vars after struct has been set + *----------------------------------------------------------------*/ + + output_Fs = st_ivas->hDecoderConfig->output_Fs; + nchan_out = st_ivas->hDecoderConfig->nchan_out; + output_config = st_ivas->hDecoderConfig->output_config; + ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate; + + output_frame = (int16_t) ( output_Fs / FRAMES_PER_SEC ); + + for ( n = 0; n < MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS; n++ ) + { + p_output[n] = st_ivas->p_output_f[n]; + } + + /*----------------------------------------------------------------* + * Update combined orientation access index + *----------------------------------------------------------------*/ + +#ifndef NONBE_UNIFIED_DECODING_PATHS + if ( ( error = combine_external_and_head_orientations_dec( st_ivas->hHeadTrackData, st_ivas->hExtOrientationData, st_ivas->hCombinedOrientationData ) ) != IVAS_ERR_OK ) + { + return error; + } +#else + ivas_combined_orientation_set_to_start_index( st_ivas->hCombinedOrientationData ); +#endif + +#ifdef SPLIT_REND_WITH_HEAD_ROT + /*----------------------------------------------------------------* + * Binaural split rendering setup + *----------------------------------------------------------------*/ + + if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { + ivas_set_split_rend_ht_setup( &st_ivas->hSplitBinRend, st_ivas->hCombinedOrientationData ); + } + +#endif + /*----------------------------------------------------------------* + * Decoding + Rendering + *----------------------------------------------------------------*/ + + if ( st_ivas->bfi && st_ivas->ini_frame == 0 ) + { + for ( n = 0; n < nchan_out; n++ ) + { + /* note: these are intra-frame heap memories */ + if ( ( st_ivas->p_output_f[n] = (float *) malloc( ( 48000 / FRAMES_PER_SEC ) * sizeof( float ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for floating-point output audio buffer!\n" ) ); + } + p_output[n] = st_ivas->p_output_f[n]; + } + + /* zero output when first frame(s) is lost */ + for ( n = 0; n < nchan_out; n++ ) + { + set_f( p_output[n], 0.0f, output_frame ); + } + +#ifdef DEBUG_MODE_INFO + create_sce_dec( st_ivas, 0, ivas_total_brate ); + output_debug_mode_info_dec( st_ivas->hSCE[0]->hCoreCoder, 1, output_frame, NULL ); + destroy_sce_dec( st_ivas->hSCE[0] ); + st_ivas->hSCE[0] = NULL; +#endif + } + else if ( st_ivas->ivas_format == STEREO_FORMAT ) + { + st_ivas->hCPE[0]->element_brate = ivas_total_brate; + + if ( ( error = ivas_cpe_dec( st_ivas, 0, p_output, output_frame, 0 ) ) != IVAS_ERR_OK ) + { + return error; + } + + /* HP filtering */ + for ( n = 0; n < min( nchan_out, st_ivas->nchan_transport ); n++ ) + { + hp20( p_output[n], output_frame, st_ivas->mem_hp20_out[n], output_Fs ); + } + + /* Rendering */ + if ( st_ivas->renderer_type == RENDERER_MC ) + { + ivas_ls_setup_conversion( st_ivas, st_ivas->nchan_transport, output_frame, p_output, p_output ); + } + } + else if ( st_ivas->ivas_format == ISM_FORMAT ) + { + /* Metadata decoding and configuration */ + if ( ivas_total_brate == IVAS_SID_5k2 || ivas_total_brate == FRAME_NO_DATA ) + { +#ifdef NONBE_FIX_898_ISM_BRATE_CRASH + ivas_ism_dtx_dec( st_ivas, nb_bits_metadata ); +#else + if ( ( error = ivas_ism_dtx_dec( st_ivas, nb_bits_metadata ) ) != IVAS_ERR_OK ) + { + return error; + } +#endif + + /* decode dominant object first so the noise energy of the other objects can be limited */ + if ( ( error = ivas_sce_dec( st_ivas, st_ivas->hISMDTX.sce_id_dtx, &p_output[st_ivas->hISMDTX.sce_id_dtx], output_frame, nb_bits_metadata[st_ivas->hISMDTX.sce_id_dtx] ) ) != IVAS_ERR_OK ) + { + return error; + } + + ivas_ism_dtx_limit_noise_energy_for_near_silence( st_ivas->hSCE, st_ivas->hISMDTX.sce_id_dtx, st_ivas->nchan_transport ); + } + else if ( st_ivas->ism_mode == ISM_MODE_PARAM ) + { + if ( ( error = ivas_ism_metadata_dec( ivas_total_brate, st_ivas->nchan_ism, &( st_ivas->nchan_transport ), st_ivas->hIsmMetaData, st_ivas->hSCE, st_ivas->bfi, nb_bits_metadata, st_ivas->ism_mode, st_ivas->hISMDTX, st_ivas->hParamIsmDec->hParamIsm, &st_ivas->ism_extmeta_active, &st_ivas->ism_extmeta_cnt, st_ivas->hSCE[0]->hCoreCoder[0] ) ) != IVAS_ERR_OK ) + { + return error; + } + } + else /* ISM_MODE_DISC */ + { + if ( ( error = ivas_ism_metadata_dec( ivas_total_brate, st_ivas->nchan_ism, &( st_ivas->nchan_transport ), st_ivas->hIsmMetaData, st_ivas->hSCE, st_ivas->bfi, nb_bits_metadata, st_ivas->ism_mode, st_ivas->hISMDTX, NULL, &st_ivas->ism_extmeta_active, &st_ivas->ism_extmeta_cnt, st_ivas->hSCE[0]->hCoreCoder[0] ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + for ( n = 0; n < st_ivas->nchan_transport; n++ ) + { + /* for DTX frames, dominant object has already been decoded before */ + if ( !( ( ivas_total_brate == IVAS_SID_5k2 || ivas_total_brate == FRAME_NO_DATA ) && n == st_ivas->hISMDTX.sce_id_dtx ) ) + { + if ( ( error = ivas_sce_dec( st_ivas, n, &p_output[n], output_frame, nb_bits_metadata[n] ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + /* HP filtering */ + hp20( p_output[n], output_frame, st_ivas->mem_hp20_out[n], output_Fs ); + } + + /* Rendering */ + if ( st_ivas->ism_mode == ISM_MODE_PARAM ) + { + if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM || st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC ) + { + /* loudness correction */ + ivas_dirac_dec_binaural_sba_gain( p_output, st_ivas->nchan_transport, output_frame ); + + ivas_param_ism_params_to_masa_param_mapping( st_ivas ); + + ivas_dirac_dec_binaural( st_ivas, st_ivas->hCombinedOrientationData, p_output, st_ivas->nchan_transport, MAX_PARAM_SPATIAL_SUBFRAMES ); + } + else if ( st_ivas->renderer_type == RENDERER_MONO_DOWNMIX ) + { + ivas_mono_downmix_render_passive( st_ivas, p_output, output_frame ); + } + else if ( st_ivas->renderer_type == RENDERER_NON_DIEGETIC_DOWNMIX ) + { + ivas_apply_non_diegetic_panning( p_output, st_ivas->hDecoderConfig->non_diegetic_pan_gain, output_frame ); + } + else if ( st_ivas->renderer_type == RENDERER_PARAM_ISM || st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC ) + { + ivas_param_ism_dec( st_ivas, p_output ); + + if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC ) + { + /* Convert CICP19 -> Ambisonics */ + ivas_mc2sba( st_ivas->hIntSetup, p_output, p_output, output_frame, st_ivas->hOutSetup.ambisonics_order, 0.f ); + } + } + } + else /* ISM_MODE_DISC */ + { + /* Loudspeaker or Ambisonics rendering */ + if ( st_ivas->renderer_type == RENDERER_MONO_DOWNMIX ) + { + ivas_mono_downmix_render_passive( st_ivas, p_output, output_frame ); + } + else if ( st_ivas->renderer_type == RENDERER_NON_DIEGETIC_DOWNMIX ) + { + ivas_apply_non_diegetic_panning( p_output, st_ivas->hDecoderConfig->non_diegetic_pan_gain, output_frame ); + } + else if ( st_ivas->renderer_type == RENDERER_TD_PANNING || st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV_ROOM ) + { + /* Convert to CICPxx; used also for ISM->CICP19->binaural_room rendering */ + ivas_ism_render( st_ivas, p_output, output_frame ); + } +#ifdef DEBUGGING + else if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV ) +#else + else if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC ) +#endif + { + /* Convert to Ambisonics; used also for ISM->HOA3->binaural rendering */ + ivas_ism2sba( p_output, st_ivas->hIsmRendererData, st_ivas->hIsmMetaData, st_ivas->nchan_ism, output_frame, st_ivas->hIntSetup.ambisonics_order ); + } + + /* Binaural rendering */ + if ( st_ivas->renderer_type == RENDERER_BINAURAL_OBJECTS_TD ) + { +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { + if ( ( error = ObjRenderIvasFrame_splitBinaural( st_ivas, p_output, output_frame ) ) != IVAS_ERR_OK ) + { + return error; + } + } + else + { +#endif + if ( ( error = ivas_td_binaural_renderer( st_ivas, p_output, output_frame ) ) != IVAS_ERR_OK ) + { + return error; + } +#ifdef SPLIT_REND_WITH_HEAD_ROT + } +#endif + } + else if ( st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV_ROOM ) + { +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( error = ivas_rend_crendProcess( st_ivas->hCrendWrapper, IVAS_AUDIO_CONFIG_7_1_4, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR, NULL, NULL, NULL, NULL, p_output, output_Fs, MAX_PARAM_SPATIAL_SUBFRAMES, 0 ) ) != IVAS_ERR_OK ) +#else + if ( ( error = ivas_rend_crendProcess( st_ivas->hCrendWrapper, IVAS_AUDIO_CONFIG_7_1_4, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR, NULL, NULL, NULL, NULL, p_output, output_Fs, MAX_PARAM_SPATIAL_SUBFRAMES ) ) != IVAS_ERR_OK ) +#endif + { + return error; + } +#ifndef FIX_881_REMOVE_LFE_ADDITION_IN_ISM + ivas_binaural_add_LFE( st_ivas, output_frame, p_output, p_output ); +#endif + } +#ifdef DEBUGGING + else if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) + { + ivas_binaural_cldfb( st_ivas, p_output ); + } +#endif + } + } + else if ( st_ivas->ivas_format == SBA_FORMAT || st_ivas->ivas_format == MASA_FORMAT ) + { + set_s( nb_bits_metadata, 0, MAX_SCE ); + + /* read parameters from the bitstream */ + if ( st_ivas->ivas_format == MASA_FORMAT && st_ivas->hQMetaData != NULL ) + { + st = ( st_ivas->nSCE > 0 ) ? st_ivas->hSCE[0]->hCoreCoder[0] : st_ivas->hCPE[0]->hCoreCoder[0]; + + if ( ( error = ivas_masa_decode( st_ivas, st, &nb_bits_metadata[0] ) ) != IVAS_ERR_OK ) + { + return error; + } + } + else if ( st_ivas->ivas_format == SBA_FORMAT ) + { + if ( ( error = ivas_spar_dec( st_ivas, nb_bits_metadata ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + if ( st_ivas->nchan_transport == CPE_CHANNELS && st_ivas->nCPE >= 1 ) + { + st_ivas->hCPE[0]->element_brate = ivas_total_brate; + } + + /* core-decoding of transport channels */ + if ( st_ivas->nSCE == 1 ) + { + if ( ( error = ivas_sce_dec( st_ivas, 0, &p_output[0], output_frame, nb_bits_metadata[0] ) ) != IVAS_ERR_OK ) + { + return error; + } + } + else if ( st_ivas->nCPE == 1 ) + { + if ( ( error = ivas_cpe_dec( st_ivas, 0, p_output, output_frame, nb_bits_metadata[0] ) ) != IVAS_ERR_OK ) + { + return error; + } + } + else if ( st_ivas->nCPE > 1 ) + { + if ( ( error = ivas_mct_dec( st_ivas, p_output, output_frame, nb_bits_metadata[0] ) ) != IVAS_ERR_OK ) + { + return error; + } + } +#ifdef DEBUG_LBR_SBA + /* SCE Decoder Output */ + for ( int16_t t = 0; t < 960; t++ ) + { + for ( int16_t c = 0; c < st_ivas->nchan_transport; c++ ) + { + float val = output[c][t] / MAX16B_FLT; + dbgwrite( &val, sizeof( float ), 1, 1, "int_dec_core_out.raw" ); + } + } +#endif +#ifdef DEBUG_SBA_AUDIO_DUMP + /* Dump audio signal after core-decoding */ + ivas_spar_dump_signal_wav( output_frame, NULL, output, st_ivas->nchan_transport, spar_foa_dec_wav[0], "core-decoding" ); +#endif + + /* TCs remapping */ + nchan_remapped = st_ivas->nchan_transport; + if ( st_ivas->sba_dirac_stereo_flag ) + { + nchan_remapped = nchan_out; + + if ( st_ivas->ivas_format == SBA_FORMAT ) + { + ivas_agc_dec_process( st_ivas->hSpar->hAgcDec, p_output, p_output, st_ivas->hSpar->hMdDec->spar_md_cfg.nchan_transport, output_frame ); + + if ( st_ivas->hSpar->hPCA != NULL ) + { + ivas_pca_dec( st_ivas->hSpar->hPCA, output_frame, st_ivas->hSpar->hMdDec->spar_md_cfg.nchan_transport, ivas_total_brate, st_ivas->hDecoderConfig->last_ivas_total_brate, st_ivas->bfi, p_output ); + } + + ivas_spar_dec_gen_umx_mat( st_ivas->hSpar->hMdDec, st_ivas->nchan_transport, IVAS_MAX_NUM_BANDS, st_ivas->bfi, ivas_get_spar_dec_md_num_subframes( st_ivas->sba_order, ivas_total_brate, st_ivas->last_active_ivas_total_brate ) ); + } + + ivas_sba_dirac_stereo_dec( st_ivas, p_output, output_frame, st_ivas->ivas_format == MC_FORMAT ); + } + else if ( st_ivas->ivas_format == MASA_FORMAT && ivas_total_brate < MASA_STEREO_MIN_BITRATE && ( ivas_total_brate > IVAS_SID_5k2 || ( ivas_total_brate <= IVAS_SID_5k2 && st_ivas->nCPE > 0 && st_ivas->hCPE[0]->nchan_out == 1 ) ) ) + { + nchan_remapped = 1; /* Only one channel transported */ + } + + /* HP filtering */ +#ifndef DEBUG_SPAR_BYPASS_EVS_CODEC + for ( n = 0; n < nchan_remapped; n++ ) + { + hp20( p_output[n], output_frame, st_ivas->mem_hp20_out[n], output_Fs ); + } +#endif + if ( st_ivas->ivas_format == SBA_FORMAT ) + { + nchan_remapped = ivas_sba_remapTCs( p_output, st_ivas, output_frame ); + + if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) + { + num_md_sub_frames = ivas_get_spar_dec_md_num_subframes( st_ivas->sba_analysis_order, ivas_total_brate, st_ivas->last_active_ivas_total_brate ); + ivas_sba_mix_matrix_determiner( st_ivas->hSpar, p_output, st_ivas->bfi, nchan_remapped, output_frame, num_md_sub_frames ); + } + else if ( st_ivas->renderer_type != RENDERER_DISABLE ) + { + ivas_spar_dec_agc_pca( st_ivas, p_output, output_frame ); + } + } + + if ( st_ivas->ivas_format == MASA_FORMAT ) + { + ivas_masa_prerender( st_ivas, p_output, output_frame, nchan_remapped ); + } + else if ( st_ivas->ivas_format == SBA_FORMAT && ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) ) + { + /* loudness correction */ + ivas_dirac_dec_binaural_sba_gain( p_output, nchan_remapped, output_frame ); + } + + /* Loudspeakers, Ambisonics or Binaural rendering */ + if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM || st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC ) + { + ivas_dirac_dec_binaural( st_ivas, st_ivas->hCombinedOrientationData, p_output, nchan_remapped, MAX_PARAM_SPATIAL_SUBFRAMES ); + } + else if ( st_ivas->ivas_format == MASA_FORMAT ) + { + if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_DEC ) + { + if ( ( error = ivas_sba_linear_renderer( p_output, output_frame, nchan_remapped, 0, output_config, st_ivas->hOutSetup ) ) != IVAS_ERR_OK ) + { + return error; + } + } + else if ( st_ivas->renderer_type == RENDERER_DIRAC ) + { + ivas_dirac_dec( st_ivas, p_output, nchan_remapped, MAX_PARAM_SPATIAL_SUBFRAMES ); + } + } + else if ( !st_ivas->sba_dirac_stereo_flag && nchan_out != 1 ) + { + if ( ( error = ivas_sba_upmixer_renderer( st_ivas, p_output, output_frame ) ) != IVAS_ERR_OK ) /* Note: ivas_sba_linear_renderer() or ivas_dirac_dec() are called internally */ + { + return error; + } + } + } + else if ( st_ivas->ivas_format == MASA_ISM_FORMAT ) + { + int16_t nchan_ism, nchan_transport_ism; + int16_t dirac_bs_md_write_idx; + + set_s( nb_bits_metadata, 0, MAX_SCE + 1 ); + + /* Set the number of objects for the parametric rendering */ + dirac_bs_md_write_idx = 0; + if ( st_ivas->hSpatParamRendCom != NULL ) + { + st_ivas->hSpatParamRendCom->numIsmDirections = 0; + if ( st_ivas->ism_mode != ISM_MASA_MODE_DISC && st_ivas->ism_mode != ISM_MASA_MODE_MASA_ONE_OBJ ) + { + st_ivas->hSpatParamRendCom->numIsmDirections = st_ivas->nchan_ism; + } + + dirac_bs_md_write_idx = st_ivas->hSpatParamRendCom->dirac_bs_md_write_idx; /* Store the write-index for this frame */ + } + + /* MASA metadata decoding */ + if ( ( error = ivas_masa_decode( st_ivas, st_ivas->hCPE[0]->hCoreCoder[0], &nb_bits_metadata[0] ) ) != IVAS_ERR_OK ) + { + return error; + } + + /* Configuration of combined-format bit-budget distribution */ + ivas_set_surplus_brate_dec( st_ivas, &ism_total_brate ); + + st_ivas->hCPE[0]->hCoreCoder[0]->bit_stream = &( st_ivas->bit_stream[( ism_total_brate / FRAMES_PER_SEC )] ); + + /* set ISM parameters and decode ISM metadata in OMASA format */ + if ( ( error = ivas_omasa_ism_metadata_dec( st_ivas, ism_total_brate, &nchan_ism, &nchan_transport_ism, dirac_bs_md_write_idx, &nb_bits_metadata[1] ) ) != IVAS_ERR_OK ) + { + return error; + } + + /* decode ISM channels */ + for ( n = 0; n < nchan_transport_ism; n++ ) + { + if ( ( error = ivas_sce_dec( st_ivas, n, &p_output[st_ivas->nchan_transport + n], output_frame, nb_bits_metadata[1] ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + /* decode MASA channels */ + if ( ( error = ivas_cpe_dec( st_ivas, 0, p_output, output_frame, nb_bits_metadata[0] ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( st_ivas->hCPE[0]->nchan_out == 1 ) + { + mvr2r( p_output[0], p_output[1], output_frame ); /* Copy mono signal to stereo output channels */ + } + + /* HP filtering */ + for ( n = 0; n < getNumChanSynthesis( st_ivas ); n++ ) + { + hp20( p_output[n], output_frame, st_ivas->mem_hp20_out[n], output_Fs ); + } + + /* Rendering */ + if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM || st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC ) + { + if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC && st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC ) + { + if ( ( error = ivas_omasa_dirac_td_binaural( st_ivas, p_output, output_frame ) ) != IVAS_ERR_OK ) + { + return error; + } + } + else + { + ivas_dirac_dec_binaural( st_ivas, st_ivas->hCombinedOrientationData, p_output, st_ivas->nchan_transport, MAX_PARAM_SPATIAL_SUBFRAMES ); + } + } + else if ( st_ivas->renderer_type == RENDERER_MONO_DOWNMIX ) + { + ivas_mono_downmix_render_passive( st_ivas, p_output, output_frame ); + } + else if ( st_ivas->renderer_type == RENDERER_DIRAC ) + { + ivas_omasa_dirac_rend( st_ivas, p_output, output_frame ); + } + + /* external output */ + if ( output_config == IVAS_AUDIO_CONFIG_EXTERNAL ) + { + /* sanity check in case of bitrate switching */ + if ( st_ivas->ism_mode != ISM_MASA_MODE_DISC ) + { + return IVAS_ERROR( IVAS_ERR_INVALID_OUTPUT_FORMAT, "Incorrect output configuration specified for combined MASA and ISM format" ); + } + + ivas_omasa_rearrange_channels( p_output, nchan_transport_ism, output_frame ); + } + } + else if ( st_ivas->ivas_format == SBA_ISM_FORMAT ) + { + int16_t nchan_ism, sba_ch_idx; + + set_s( nb_bits_metadata, 0, MAX_SCE + 1 ); + nchan_ism = st_ivas->nchan_ism; + if ( st_ivas->ism_mode == ISM_SBA_MODE_DISC ) + { + /* set ISM parameters and decode ISM metadata in OSBA format */ + if ( ( error = ivas_osba_ism_metadata_dec( st_ivas, ivas_total_brate, &nchan_ism, &nb_bits_metadata[1] ) ) != IVAS_ERR_OK ) + { + return error; + } + sba_ch_idx = st_ivas->nchan_ism; + } + else + { + nb_bits_metadata[1] += NO_BITS_MASA_ISM_NO_OBJ; + sba_ch_idx = 0; + } + + /* SBA metadata decoding */ + if ( ( error = ivas_spar_dec( st_ivas, nb_bits_metadata ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( st_ivas->nchan_transport == CPE_CHANNELS && st_ivas->nCPE >= 1 ) + { + st_ivas->hCPE[0]->element_brate = ivas_total_brate; + } + + /* core-decoding of transport channels */ + if ( st_ivas->nSCE == 1 ) + { + if ( ( error = ivas_sce_dec( st_ivas, 0, &p_output[0], output_frame, nb_bits_metadata[0] + nb_bits_metadata[1] ) ) != IVAS_ERR_OK ) + { + return error; + } + } + else if ( st_ivas->nCPE == 1 ) + { + if ( ( error = ivas_cpe_dec( st_ivas, 0, p_output, output_frame, nb_bits_metadata[0] + nb_bits_metadata[1] ) ) != IVAS_ERR_OK ) + { + return error; + } + } + else if ( st_ivas->nCPE > 1 ) + { + if ( ( error = ivas_mct_dec( st_ivas, p_output, output_frame, nb_bits_metadata[0] + nb_bits_metadata[1] ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + if ( st_ivas->sba_dirac_stereo_flag ) + { + ivas_agc_dec_process( st_ivas->hSpar->hAgcDec, &p_output[sba_ch_idx], &p_output[sba_ch_idx], st_ivas->hSpar->hMdDec->spar_md_cfg.nchan_transport, output_frame ); + + if ( st_ivas->hSpar->hPCA != NULL ) + { + ivas_pca_dec( st_ivas->hSpar->hPCA, output_frame, st_ivas->hSpar->hMdDec->spar_md_cfg.nchan_transport, ivas_total_brate, st_ivas->hDecoderConfig->last_ivas_total_brate, st_ivas->bfi, &p_output[sba_ch_idx] ); + } + + ivas_spar_dec_gen_umx_mat( st_ivas->hSpar->hMdDec, st_ivas->nchan_transport, IVAS_MAX_NUM_BANDS, st_ivas->bfi, ivas_get_spar_dec_md_num_subframes( st_ivas->sba_order, ivas_total_brate, st_ivas->last_active_ivas_total_brate ) ); + + ivas_sba_dirac_stereo_dec( st_ivas, &p_output[sba_ch_idx], output_frame, 0 ); + } + + /* HP filtering */ + for ( n = 0; n < getNumChanSynthesis( st_ivas ); n++ ) + { + hp20( p_output[n], output_frame, st_ivas->mem_hp20_out[n], output_Fs ); + } + + nchan_remapped = ivas_sba_remapTCs( &p_output[sba_ch_idx], st_ivas, output_frame ); + +#ifdef DEBUG_OSBA + if ( st_ivas->ism_mode == ISM_SBA_MODE_DISC ) + { + int16_t nchan = st_ivas->nchan_transport + st_ivas->nchan_ism; + for ( int16_t t = 0; t < output_frame; t++ ) + { + for ( int16_t c = 0; c < nchan; c++ ) + { + int16_t val = (int16_t) ( output[c][t] + 0.5f ); + dbgwrite( &val, sizeof( int16_t ), 1, 1, "./res/TC_dec_core_out.raw" ); + } + } + } +#endif + if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) + { + num_md_sub_frames = ivas_get_spar_dec_md_num_subframes( st_ivas->sba_analysis_order, ivas_total_brate, st_ivas->last_active_ivas_total_brate ); + ivas_sba_mix_matrix_determiner( st_ivas->hSpar, &p_output[sba_ch_idx], st_ivas->bfi, nchan_remapped, output_frame, num_md_sub_frames ); + } + else if ( st_ivas->renderer_type != RENDERER_DISABLE ) + { + ivas_spar_dec_agc_pca( st_ivas, &p_output[sba_ch_idx], output_frame ); + } + + if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) + { + /* loudness correction */ + ivas_dirac_dec_binaural_sba_gain( &p_output[sba_ch_idx], nchan_remapped, output_frame ); + } + + /* Loudspeakers, Ambisonics or Binaural rendering */ + if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || + st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM || + st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC ) + { + ivas_dirac_dec_binaural( st_ivas, st_ivas->hCombinedOrientationData, &p_output[sba_ch_idx], nchan_remapped, MAX_PARAM_SPATIAL_SUBFRAMES ); + } + else if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV ) + { + if ( st_ivas->ism_mode == ISM_SBA_MODE_DISC ) + { + if ( ( error = ivas_osba_dirac_td_binaural( st_ivas, p_output, output_frame ) ) != IVAS_ERR_OK ) + { + return error; + } + } + else + { + ivas_sba_upmixer_renderer( st_ivas, &p_output[sba_ch_idx], output_frame ); + } + } + else if ( st_ivas->ism_mode == ISM_SBA_MODE_DISC && ( st_ivas->renderer_type == RENDERER_OSBA_STEREO || st_ivas->renderer_type == RENDERER_MONO_DOWNMIX ) ) + { + if ( st_ivas->renderer_type == RENDERER_MONO_DOWNMIX ) + { + ivas_mono_downmix_render_passive( st_ivas, p_output, output_frame ); + } + else /* stereo output */ + { + /* shift SBA channels to avoid overwrite by ISM upmix in 1 object case */ + if ( nchan_ism == 1 ) + { + mvr2r( p_output[2], p_output[3], output_frame ); + mvr2r( p_output[1], p_output[2], output_frame ); + } + + ivas_ism_render( st_ivas, p_output, output_frame ); + } + + for ( n = 0; n < nchan_out; n++ ) + { + v_add( p_output[n], p_output[n + max( nchan_out, nchan_ism )], p_output[n], output_frame ); + } + } + else if ( st_ivas->renderer_type == RENDERER_OSBA_AMBI || st_ivas->renderer_type == RENDERER_OSBA_LS ) + { + if ( ( error = ivas_osba_render( st_ivas, p_output, output_frame ) ) != IVAS_ERR_OK ) + { + return error; + } + } + else if ( output_config != IVAS_AUDIO_CONFIG_EXTERNAL && !st_ivas->sba_dirac_stereo_flag && nchan_out != 1 ) + { + if ( ( error = ivas_sba_upmixer_renderer( st_ivas, p_output, output_frame ) ) != IVAS_ERR_OK ) + { + return error; + } + } + else if ( output_config == IVAS_AUDIO_CONFIG_EXTERNAL ) /*EXT output = individual objects + HOA3*/ + { + if ( st_ivas->ism_mode == ISM_SBA_MODE_DISC ) + { + for ( n = 0; n < nchan_ism; n++ ) + { + delay_signal( p_output[n], output_frame, st_ivas->hSbaIsmData->delayBuffer[n], st_ivas->hSbaIsmData->delayBuffer_size ); + } + } + + if ( ( error = ivas_sba_upmixer_renderer( st_ivas, p_output, output_frame ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( st_ivas->ism_mode == ISM_MODE_NONE ) + { + for ( n = st_ivas->hIntSetup.nchan_out_woLFE - 1; n >= 0; n-- ) + { + mvr2r( p_output[n], p_output[n + nchan_ism], output_frame ); + } + + for ( n = 0; n < nchan_ism; n++ ) + { + set_zero( p_output[n], output_frame ); + } + } + } + } + else if ( st_ivas->ivas_format == MC_FORMAT ) + { + st = ( st_ivas->nSCE > 0 ) ? st_ivas->hSCE[0]->hCoreCoder[0] : st_ivas->hCPE[0]->hCoreCoder[0]; + + if ( st_ivas->mc_mode == MC_MODE_MCT ) + { + /* LFE channel decoder */ + ivas_lfe_dec( st_ivas->hLFE, st, output_frame, st_ivas->bfi, p_output[LFE_CHANNEL] ); + + if ( ( error = ivas_mct_dec( st_ivas, p_output, output_frame, 0 ) ) != IVAS_ERR_OK ) + { + return error; + } + + /* HP filtering */ + for ( n = 0; n < st_ivas->nchan_transport; n++ ) + { + if ( n != LFE_CHANNEL ) + { + hp20( p_output[n], output_frame, st_ivas->mem_hp20_out[n], output_Fs ); + } + } + + if ( st_ivas->transport_config != st_ivas->intern_config && ( st_ivas->intern_config == IVAS_AUDIO_CONFIG_FOA || st_ivas->intern_config == IVAS_AUDIO_CONFIG_HOA2 || st_ivas->intern_config == IVAS_AUDIO_CONFIG_HOA3 ) ) + { + ivas_mc2sba( st_ivas->hTransSetup, p_output, p_output, output_frame, st_ivas->hIntSetup.ambisonics_order, GAIN_LFE ); + } + + /* Rendering */ + if ( st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV || st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV_ROOM ) + { +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { + if ( ( error = ivas_rend_crendProcessSplitBin( st_ivas->hCrendWrapper, st_ivas->intern_config, st_ivas->hOutSetup.output_config, &st_ivas->hSplitBinRend.splitrend.multiBinPoseData, st_ivas->hDecoderConfig, + st_ivas->hCombinedOrientationData, &st_ivas->hIntSetup, st_ivas->hEFAPdata, p_output, output_Fs ) ) != IVAS_ERR_OK ) + { + return error; + } + } + else + { + if ( ( error = ivas_rend_crendProcess( st_ivas->hCrendWrapper, st_ivas->intern_config, st_ivas->hOutSetup.output_config, st_ivas->hDecoderConfig, + st_ivas->hCombinedOrientationData, &st_ivas->hIntSetup, st_ivas->hEFAPdata, p_output, output_Fs, MAX_PARAM_SPATIAL_SUBFRAMES, 0 ) ) != IVAS_ERR_OK ) +#else + if ( ( error = ivas_rend_crendProcess( st_ivas->hCrendWrapper, st_ivas->intern_config, st_ivas->hOutSetup.output_config, st_ivas->hDecoderConfig, + st_ivas->hCombinedOrientationData, &st_ivas->hIntSetup, st_ivas->hEFAPdata, p_output, output_Fs, MAX_PARAM_SPATIAL_SUBFRAMES ) ) != IVAS_ERR_OK ) +#endif + { + return error; + } + + ivas_binaural_add_LFE( st_ivas, output_frame, p_output, p_output ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + } +#endif + } + else if ( st_ivas->renderer_type == RENDERER_MC ) + { + ivas_ls_setup_conversion( st_ivas, st_ivas->nchan_transport, output_frame, p_output, p_output ); + } + else if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC ) + { + ivas_mc2sba( st_ivas->hIntSetup, p_output, p_output, output_frame, st_ivas->hOutSetup.ambisonics_order, 0.f ); + } + else if ( st_ivas->renderer_type == RENDERER_BINAURAL_OBJECTS_TD ) + { +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { + if ( ( error = ObjRenderIvasFrame_splitBinaural( st_ivas, p_output, output_frame ) ) != IVAS_ERR_OK ) + { + return error; + } + } + else + { +#endif + if ( ( ivas_td_binaural_renderer( st_ivas, p_output, output_frame ) ) != IVAS_ERR_OK ) + { + return error; + } + + ivas_binaural_add_LFE( st_ivas, output_frame, p_output, p_output ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + } +#endif + } + } + else if ( st_ivas->mc_mode == MC_MODE_PARAMUPMIX ) + { + ivas_lfe_dec( st_ivas->hLFE, st, output_frame, st_ivas->bfi, p_output[LFE_CHANNEL] ); + + ivas_mc_paramupmix_dec_read_BS( st_ivas, st, st_ivas->hMCParamUpmix, &nb_bits_metadata[0] ); + + if ( ( error = ivas_mct_dec( st_ivas, p_output, output_frame, nb_bits_metadata[0] ) ) != IVAS_ERR_OK ) + { + return error; + } + + /* HP filtering */ + for ( n = 0; n < st_ivas->nchan_transport; n++ ) + { + if ( n != LFE_CHANNEL ) + { + hp20( p_output[n], output_frame, st_ivas->mem_hp20_out[n], output_Fs ); + } + } + + ivas_mc_paramupmix_dec( st_ivas, p_output ); + + if ( st_ivas->transport_config != st_ivas->intern_config && + ( st_ivas->intern_config == IVAS_AUDIO_CONFIG_FOA || st_ivas->intern_config == IVAS_AUDIO_CONFIG_HOA2 || st_ivas->intern_config == IVAS_AUDIO_CONFIG_HOA3 ) && + ( output_config == IVAS_AUDIO_CONFIG_FOA || output_config == IVAS_AUDIO_CONFIG_HOA2 || output_config == IVAS_AUDIO_CONFIG_HOA3 ) ) + { + ivas_mc2sba( st_ivas->hTransSetup, p_output, p_output, output_frame, st_ivas->hIntSetup.ambisonics_order, GAIN_LFE ); + } + + /* Rendering */ + if ( ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) && !st_ivas->hDecoderConfig->Opt_Headrotation ) + { +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( output_config != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED && output_config != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) +#endif + { + ivas_binaural_add_LFE( st_ivas, output_frame, p_output, p_output ); + } + } + else if ( st_ivas->renderer_type == RENDERER_MC ) + { + if ( output_config == IVAS_AUDIO_CONFIG_MONO || output_config == IVAS_AUDIO_CONFIG_STEREO ) + { + ivas_ls_setup_conversion( st_ivas, audioCfg2channels( IVAS_AUDIO_CONFIG_5_1_2 ), output_frame, p_output, p_output ); + } + else + { + ivas_ls_setup_conversion( st_ivas, MC_PARAMUPMIX_MAX_INPUT_CHANS, output_frame, p_output, p_output ); + } + } + else if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC ) + { + ivas_mc2sba( st_ivas->hIntSetup, p_output, p_output, output_frame, st_ivas->hOutSetup.ambisonics_order, 0.f ); + } + else if ( st_ivas->renderer_type == RENDERER_BINAURAL_OBJECTS_TD ) + { +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { + if ( ( error = ObjRenderIvasFrame_splitBinaural( st_ivas, p_output, output_frame ) ) != IVAS_ERR_OK ) + { + return error; + } + } + else + { +#endif + if ( ( error = ivas_td_binaural_renderer( st_ivas, p_output, output_frame ) ) != IVAS_ERR_OK ) + { + return error; + } + + ivas_binaural_add_LFE( st_ivas, output_frame, p_output, p_output ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + } +#endif + } + } + else if ( st_ivas->mc_mode == MC_MODE_PARAMMC ) + { + /* read Parametric MC parameters from the bitstream */ + ivas_param_mc_dec_read_BS( ivas_total_brate, st, st_ivas->hParamMC, &nb_bits_metadata[0] ); + + if ( st_ivas->nCPE == 1 ) + { + if ( ( error = ivas_cpe_dec( st_ivas, 0, p_output, output_frame, nb_bits_metadata[0] ) ) != IVAS_ERR_OK ) + { + return error; + } + } + else if ( st_ivas->nCPE > 1 ) + { + if ( ( error = ivas_mct_dec( st_ivas, p_output, output_frame, nb_bits_metadata[0] ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + /* HP filtering */ + for ( n = 0; n < st_ivas->nchan_transport; n++ ) + { + hp20( p_output[n], output_frame, st_ivas->mem_hp20_out[n], output_Fs ); + } + + /* Rendering */ + if ( output_config == IVAS_AUDIO_CONFIG_MONO || output_config == IVAS_AUDIO_CONFIG_STEREO ) + { + ivas_ls_setup_conversion( st_ivas, st_ivas->nchan_transport, output_frame, p_output, p_output ); + } + else + { + ivas_param_mc_dec( st_ivas, p_output ); + } + } + else if ( st_ivas->mc_mode == MC_MODE_MCMASA ) + { + if ( st_ivas->hOutSetup.separateChannelEnabled ) + { + st = st_ivas->hCPE[0]->hCoreCoder[0]; /* Metadata is always with CPE in the case of separated channel */ + } + + /* read McMASA parameters from the bitstream */ + if ( ( error = ivas_masa_decode( st_ivas, st, &nb_bits_metadata[0] ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( st_ivas->hOutSetup.separateChannelEnabled ) + { + /* Decode the transport audio signals */ + if ( ( error = ivas_cpe_dec( st_ivas, 0, p_output, output_frame, nb_bits_metadata[0] ) ) != IVAS_ERR_OK ) + { + return error; + } + + /* Identify the index of the separated channel */ + n = st_ivas->hOutSetup.separateChannelIndex; + + /* Decode the separated channel to output[n] to be combined with the synthesized channels */ + if ( ( error = ivas_sce_dec( st_ivas, 0, &p_output[n], output_frame, 0 ) ) != IVAS_ERR_OK ) + { + return error; + } + + /* Delay the separated channel to sync with CLDFB delay of the DirAC synthesis, and synthesize the LFE signal. */ + if ( output_config == IVAS_AUDIO_CONFIG_5_1 || output_config == IVAS_AUDIO_CONFIG_7_1 || + output_config == IVAS_AUDIO_CONFIG_5_1_4 || output_config == IVAS_AUDIO_CONFIG_7_1_4 || + output_config == IVAS_AUDIO_CONFIG_5_1_2 || ( output_config == IVAS_AUDIO_CONFIG_LS_CUSTOM && st_ivas->hOutSetup.num_lfe > 0 ) ) + { + ivas_lfe_synth_with_filters( st_ivas->hMasa->hMasaLfeSynth, p_output, output_frame, n, LFE_CHANNEL ); + } + else if ( output_config == IVAS_AUDIO_CONFIG_LS_CUSTOM && st_ivas->hOutSetup.num_lfe == 0 ) + { + /* Delay the separated channel to sync with the DirAC rendering */ + delay_signal( p_output[n], output_frame, st_ivas->hMasa->hMasaLfeSynth->delayBuffer_syncDirAC, st_ivas->hMasa->hMasaLfeSynth->delayBuffer_syncDirAC_size ); + } + } + else + { + if ( st_ivas->nSCE == 1 ) + { + if ( ( error = ivas_sce_dec( st_ivas, 0, p_output, output_frame, nb_bits_metadata[0] ) ) != IVAS_ERR_OK ) + { + return error; + } + } + else if ( st_ivas->nCPE == 1 ) + { + if ( ( error = ivas_cpe_dec( st_ivas, 0, p_output, output_frame, nb_bits_metadata[0] ) ) != IVAS_ERR_OK ) + { + return error; + } + } + } + + if ( st_ivas->sba_dirac_stereo_flag ) /* use the flag to trigger the DFT upmix */ + { + ivas_sba_dirac_stereo_dec( st_ivas, p_output, output_frame, 1 ); + } + + /* HP filtering */ + for ( n = 0; n < getNumChanSynthesis( st_ivas ); n++ ) + { + hp20( p_output[n], output_frame, st_ivas->mem_hp20_out[n], output_Fs ); + } + + /* Rendering */ + if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM || st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC ) + { + ivas_dirac_dec_binaural( st_ivas, st_ivas->hCombinedOrientationData, p_output, st_ivas->nchan_transport, MAX_PARAM_SPATIAL_SUBFRAMES ); + } + else if ( st_ivas->renderer_type == RENDERER_DIRAC || st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC ) /* rendering to CICPxx and Ambisonics */ + { + ivas_dirac_dec( st_ivas, p_output, st_ivas->nchan_transport, MAX_PARAM_SPATIAL_SUBFRAMES ); + + if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC ) + { + ivas_mc2sba( st_ivas->hIntSetup, p_output, p_output, output_frame, st_ivas->hOutSetup.ambisonics_order, 0.f ); + } + else if ( st_ivas->intern_config == IVAS_AUDIO_CONFIG_5_1 && ( output_config == IVAS_AUDIO_CONFIG_5_1_2 || output_config == IVAS_AUDIO_CONFIG_5_1_4 || output_config == IVAS_AUDIO_CONFIG_7_1 ) ) + { + for ( n = st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe; n < st_ivas->hOutSetup.nchan_out_woLFE + st_ivas->hOutSetup.num_lfe; n++ ) + { + set_zero( p_output[n], output_frame ); + } + } + } + else if ( st_ivas->renderer_type == RENDERER_MCMASA_MONO_STEREO ) + { + ivas_mono_stereo_downmix_mcmasa( st_ivas, p_output, output_frame ); + } + } + } + + /*----------------------------------------------------------------* + * Write IVAS output channels + * - compensation for saturation + * - float to integer conversion + *----------------------------------------------------------------*/ + +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { + nchan_out_syn_output = BINAURAL_CHANNELS * st_ivas->hSplitBinRend.splitrend.multiBinPoseData.num_poses; + } + else + { + nchan_out_syn_output = nchan_out; + } + + if ( st_ivas->hDecoderConfig->Opt_Limiter ) +#endif + { +#ifndef DISABLE_LIMITER +#ifdef SPLIT_REND_WITH_HEAD_ROT + ivas_limiter_dec( st_ivas->hLimiter, p_output, nchan_out_syn_output, output_frame, st_ivas->BER_detect ); +#else + ivas_limiter_dec( st_ivas->hLimiter, p_output, nchan_out, output_frame, st_ivas->BER_detect ); +#endif +#endif + } + +#ifdef SPLIT_REND_WITH_HEAD_ROT + switch ( pcm_resolution ) + { + case PCM_INT16: +#endif +#ifdef DEBUGGING + st_ivas->noClipping += +#endif +#ifdef SPLIT_REND_WITH_HEAD_ROT + ivas_syn_output( p_output, output_frame, nchan_out_syn_output, (int16_t *) data ); +#else + ivas_syn_output( p_output, output_frame, nchan_out, data ); +#endif + +#ifdef SPLIT_REND_WITH_HEAD_ROT + break; + case PCM_FLOAT32: + ivas_syn_output_f( p_output, output_frame, nchan_out_syn_output, (float *) data ); + break; + default: + error = IVAS_ERR_UNKNOWN; + break; + } +#endif + + /*----------------------------------------------------------------* + * Common updates + *----------------------------------------------------------------*/ + + if ( !st_ivas->bfi ) /* do not update if first frame(s) are lost or NO_DATA */ + { + st_ivas->hDecoderConfig->last_ivas_total_brate = ivas_total_brate; + st_ivas->last_active_ivas_total_brate = ( ivas_total_brate <= IVAS_SID_5k2 ) ? st_ivas->last_active_ivas_total_brate : ivas_total_brate; + } + + if ( st_ivas->ini_frame < MAX_FRAME_COUNTER && !( st_ivas->bfi && st_ivas->ini_frame == 0 ) ) /* keep "st_ivas->ini_frame = 0" until first good received frame */ + { + st_ivas->ini_frame++; + } + + if ( st_ivas->ini_active_frame < MAX_FRAME_COUNTER && !( st_ivas->bfi && st_ivas->ini_frame == 0 ) && ivas_total_brate > IVAS_SID_5k2 ) /* needed in MASA decoder in case the first active frame is BFI, and there were SID-frames decoded before */ + { + st_ivas->ini_active_frame++; + } + + st_ivas->last_ivas_format = st_ivas->ivas_format; + +#ifdef NONBE_UNIFIED_DECODING_PATHS + /* update global combined orientation start index */ + ivas_combined_orientation_update_start_index( st_ivas->hCombinedOrientationData, output_frame ); +#endif + + /* in case first frame(s) was/were lost, deallocate output buffers */ + if ( st_ivas->bfi && st_ivas->ini_frame == 0 ) + { + for ( n = 0; n < nchan_out; n++ ) + { + free( st_ivas->p_output_f[n] ); + st_ivas->p_output_f[n] = NULL; + } + } + +#ifdef DEBUG_MODE_INFO + dbgwrite( &st_ivas->bfi, sizeof( int16_t ), 1, output_frame, "res/bfi" ); + dbgwrite( &st_ivas->BER_detect, sizeof( int16_t ), 1, output_frame, "res/BER_detect" ); + { + float tmpF = ivas_total_brate / 1000.0f; + dbgwrite( &tmpF, sizeof( float ), 1, output_frame, "res/ivas_total_brate.dec" ); + } +#endif + + pop_wmops(); + return IVAS_ERR_OK; +} +#endif diff --git a/lib_dec/ivas_decision_matrix_dec.c b/lib_dec/ivas_decision_matrix_dec.c index 0134e2ef6..ba53de1da 100644 --- a/lib_dec/ivas_decision_matrix_dec.c +++ b/lib_dec/ivas_decision_matrix_dec.c @@ -32,6 +32,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "stat_dec.h" #include "rom_com.h" #include "ivas_prot.h" diff --git a/lib_dec/ivas_dirac_dec.c b/lib_dec/ivas_dirac_dec.c index 348a5ed5f..25fc8d99f 100644 --- a/lib_dec/ivas_dirac_dec.c +++ b/lib_dec/ivas_dirac_dec.c @@ -42,6 +42,9 @@ #include "ivas_rom_com.h" #include "ivas_rom_dec.h" #include "ivas_rom_rend.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" @@ -807,7 +810,11 @@ ivas_error ivas_dirac_dec_config( if ( !need_parambin ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + ivas_dirac_dec_close_binaural_data( st_ivas->hDiracDecBin ); +#else ivas_dirac_dec_close_binaural_data( &st_ivas->hDiracDecBin ); +#endif } need_dirac_rend = 0; @@ -859,7 +866,11 @@ ivas_error ivas_dirac_dec_config( } } +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( st_ivas->hDiracDecBin[0] == NULL ) +#else if ( st_ivas->hDiracDecBin == NULL ) +#endif { if ( ( error = ivas_dirac_dec_init_binaural_data( st_ivas, st_ivas->hHrtfParambin ) ) != IVAS_ERR_OK ) { @@ -869,26 +880,56 @@ ivas_error ivas_dirac_dec_config( else { /* This is required to keep BE in rate switching. This probably means that 1TC and 2TC MASA perform differently. */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( st_ivas->hDiracDecBin[0]->h_freq_domain_decorr_ap_params != NULL && !( st_ivas->ivas_format == MASA_FORMAT && st_ivas->nSCE > 0 ) ) +#else if ( st_ivas->hDiracDecBin->h_freq_domain_decorr_ap_params != NULL && !( st_ivas->ivas_format == MASA_FORMAT && st_ivas->nSCE > 0 ) ) +#endif { +#ifdef SPLIT_REND_WITH_HEAD_ROT + ivas_dirac_dec_decorr_close( &st_ivas->hDiracDecBin[0]->h_freq_domain_decorr_ap_params, &st_ivas->hDiracDecBin[0]->h_freq_domain_decorr_ap_state ); +#else ivas_dirac_dec_decorr_close( &st_ivas->hDiracDecBin->h_freq_domain_decorr_ap_params, &st_ivas->hDiracDecBin->h_freq_domain_decorr_ap_state ); +#endif } +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( error = ivas_td_decorr_reconfig_dec( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->nchan_transport, st_ivas->hDecoderConfig->output_Fs, &( st_ivas->hDiracDecBin[0]->hTdDecorr ), &( st_ivas->hDiracDecBin[0]->useTdDecorr ) ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_td_decorr_reconfig_dec( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->nchan_transport, st_ivas->hDecoderConfig->output_Fs, &( st_ivas->hDiracDecBin->hTdDecorr ), &( st_ivas->hDiracDecBin->useTdDecorr ) ) ) != IVAS_ERR_OK ) +#endif { return error; } +#ifdef SPLIT_REND_WITH_HEAD_ROT + /* copy td-decorr flag to split renderer side rendereres */ + for ( int16_t pos_idx = 1; pos_idx < st_ivas->hSplitBinRend.splitrend.multiBinPoseData.num_poses; pos_idx++ ) + { + st_ivas->hDiracDecBin[pos_idx]->useTdDecorr = st_ivas->hDiracDecBin[0]->useTdDecorr; + } + + if ( !st_ivas->hDiracDecBin[0]->useTdDecorr ) +#else if ( !st_ivas->hDiracDecBin->useTdDecorr ) +#endif { +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( st_ivas->hDiracDecBin[0]->h_freq_domain_decorr_ap_params == NULL ) +#else if ( st_ivas->hDiracDecBin->h_freq_domain_decorr_ap_params == NULL ) +#endif { float frequency_axis[CLDFB_NO_CHANNELS_MAX]; ivas_dirac_dec_get_frequency_axis( frequency_axis, st_ivas->hDecoderConfig->output_Fs, st_ivas->hSpatParamRendCom->num_freq_bands ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( error = ivas_dirac_dec_decorr_open( &( st_ivas->hDiracDecBin[0]->h_freq_domain_decorr_ap_params ), &( st_ivas->hDiracDecBin[0]->h_freq_domain_decorr_ap_state ), st_ivas->hSpatParamRendCom->num_freq_bands, BINAURAL_CHANNELS, BINAURAL_CHANNELS, +#else if ( ( error = ivas_dirac_dec_decorr_open( &( st_ivas->hDiracDecBin->h_freq_domain_decorr_ap_params ), &( st_ivas->hDiracDecBin->h_freq_domain_decorr_ap_state ), st_ivas->hSpatParamRendCom->num_freq_bands, BINAURAL_CHANNELS, BINAURAL_CHANNELS, +#endif DIRAC_SYNTHESIS_PSD_LS, frequency_axis, BINAURAL_CHANNELS, st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK ) { return error; @@ -896,11 +937,52 @@ ivas_error ivas_dirac_dec_config( } } +#ifdef SPLIT_REND_WITH_HEAD_ROT + for ( int16_t pos_idx = 0; pos_idx < st_ivas->hSplitBinRend.splitrend.multiBinPoseData.num_poses; pos_idx++ ) + { + st_ivas->hDiracDecBin[pos_idx]->reqularizationFactor = configure_reqularization_factor( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate ); + } +#else st_ivas->hDiracDecBin->reqularizationFactor = configure_reqularization_factor( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate ); +#endif } } } +#ifndef NONBE_UNIFIED_DECODING_PATHS + /* Allocate transport channel buffers for SBA format when in JBM */ + if ( dec_config_flag == DIRAC_OPEN ) + { +#ifndef NONBE_UNIFIED_DECODING_PATHS + if ( st_ivas->hDecoderConfig->Opt_5ms && st_ivas->hTcBuffer == NULL ) +#else + if ( st_ivas->hTcBuffer == NULL ) +#endif + { + if ( st_ivas->ivas_format == SBA_FORMAT ) + { + int16_t nchan_to_allocate; + int16_t nchan_transport; + + nchan_transport = st_ivas->nchan_transport; + + nchan_to_allocate = nchan_transport; + if ( st_ivas->nchan_transport == 1 && ( ( st_ivas->renderer_type == RENDERER_DIRAC && st_ivas->hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD ) || ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) ) ) + { + nchan_to_allocate++; /* we need a channel for the CNG in this case*/ + } + if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) + { + nchan_to_allocate = 2 * BINAURAL_CHANNELS; + } + if ( ( error = ivas_jbm_dec_tc_buffer_open( st_ivas, TC_BUFFER_MODE_RENDERER, nchan_transport, nchan_to_allocate, nchan_to_allocate, st_ivas->hSpatParamRendCom->slot_size ) ) != IVAS_ERR_OK ) + { + return error; + } + } + } + } +#endif return error; } @@ -1023,6 +1105,9 @@ void ivas_dirac_dec_read_BS( *nb_bits += ivas_qmetadata_dec_decode( hQMetaData, st->bit_stream, &( st->next_bit_pos ), hodirac_flag ); } +#ifdef DEBUGGING + assert( *nb_bits >= 0 ); +#endif st->next_bit_pos = next_bit_pos_orig; } @@ -1299,6 +1384,9 @@ void ivas_qmetadata_to_dirac( qBand_idx = band; } diffuseness = 1.0f - q_direction->band_data[qBand_idx].energy_ratio[0]; +#ifdef DEBUG_MODE_DIRAC + dbgwrite( &diffuseness, sizeof( float ), 1, 1, "./res/dirac_dec_diffuseness.dat" ); +#endif diff_idx = q_direction->band_data[qBand_idx].energy_ratio_index[0]; for ( block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; block++ ) @@ -1442,6 +1530,9 @@ void ivas_dirac_dec_set_md_map( hDirAC = st_ivas->hDirAC; hSpatParamRendCom = st_ivas->hSpatParamRendCom; +#ifdef DEBUGGING + assert( hSpatParamRendCom ); +#endif /* adapt subframes */ hSpatParamRendCom->num_slots = nCldfbTs; @@ -1499,6 +1590,86 @@ void ivas_dirac_dec_set_md_map( return; } +#ifndef NONBE_UNIFIED_DECODING_PATHS_FIX +/*------------------------------------------------------------------------- + * ivas_dirac_dec() + * + * DirAC decoding process + *------------------------------------------------------------------------*/ + +void ivas_dirac_dec( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + float *output_f[], /* i/o: synthesized core-coder transport channels/DirAC output */ + const int16_t nchan_transport, /* i : number of transport channels */ + const int16_t num_subframes /* i : number of subframes to render */ +) +{ + int16_t subframe_idx; + float *output_f_local[MAX_OUTPUT_CHANNELS]; + float cng_td_buffer[L_FRAME16k]; + int16_t nchan_out, n, n_samples_sf; + SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom; + + hSpatParamRendCom = st_ivas->hSpatParamRendCom; + nchan_out = st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe; + + n_samples_sf = JBM_CLDFB_SLOTS_IN_SUBFRAME * hSpatParamRendCom->slot_size; + + for ( n = 0; n < nchan_out; n++ ) + { + output_f_local[n] = output_f[n]; + } + + for ( n = 0; n < nchan_transport; n++ ) + { + st_ivas->hTcBuffer->tc[n] = output_f[n]; + } + + if ( st_ivas->nchan_transport == 1 && st_ivas->hSCE[0]->hCoreCoder[0] != NULL && st_ivas->hSCE[0]->hCoreCoder[0]->cna_dirac_flag && st_ivas->ivas_format != SBA_FORMAT ) + { + Decoder_State *st = st_ivas->hSCE[0]->hCoreCoder[0]; + st_ivas->hTcBuffer->tc[nchan_transport] = &cng_td_buffer[0]; + generate_masking_noise_lb_dirac( st->hFdCngDec->hFdCngCom, st_ivas->hTcBuffer->tc[1], DEFAULT_JBM_CLDFB_TIMESLOTS, st->cna_dirac_flag && st->flag_cna ); + } + + ivas_dirac_dec_set_md_map( st_ivas, DEFAULT_JBM_CLDFB_TIMESLOTS ); + + for ( subframe_idx = 0; subframe_idx < num_subframes; subframe_idx++ ) + { + ivas_dirac_dec_render_sf( st_ivas, output_f_local, nchan_transport, NULL, NULL ); + for ( n = 0; n < nchan_out; n++ ) + { + output_f_local[n] += n_samples_sf; + } + +#ifdef NONBE_UNIFIED_DECODING_PATHS + /* update combined orientation access index */ + ivas_combined_orientation_update_index( st_ivas->hCombinedOrientationData, n_samples_sf ); +#endif + } + + if ( st_ivas->hDirAC->hConfig->dec_param_estim == 1 ) + { + hSpatParamRendCom->dirac_read_idx = ( hSpatParamRendCom->dirac_read_idx + DEFAULT_JBM_CLDFB_TIMESLOTS ) % hSpatParamRendCom->dirac_md_buffer_length; + } + else + { + hSpatParamRendCom->dirac_read_idx = ( hSpatParamRendCom->dirac_read_idx + DEFAULT_JBM_SUBFRAMES_5MS ) % hSpatParamRendCom->dirac_md_buffer_length; + } + + for ( n = 0; n < nchan_transport; n++ ) + { + st_ivas->hTcBuffer->tc[n] = NULL; + } + + if ( st_ivas->nchan_transport == 1 && st_ivas->hSCE[0]->hCoreCoder[0] != NULL && st_ivas->hSCE[0]->hCoreCoder[0]->cna_dirac_flag && st_ivas->ivas_format != SBA_FORMAT ) + { + st_ivas->hTcBuffer->tc[nchan_transport] = NULL; + } + + return; +} +#endif /*------------------------------------------------------------------------- * ivas_dirac_dec_render() @@ -1519,15 +1690,24 @@ void ivas_dirac_dec_render( uint16_t slot_size, n_samples_sf, ch, nchan_intern; SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom; float *output_f_local[MAX_OUTPUT_CHANNELS]; +#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX float output_f_local_buff[MAX_OUTPUT_CHANNELS][L_FRAME48k]; // VE2SB: TBV +#endif hSpatParamRendCom = st_ivas->hSpatParamRendCom; nchan_intern = st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe; +#ifdef DEBUGGING + assert( hSpatParamRendCom ); +#endif for ( ch = 0; ch < nchan_intern; ch++ ) { +#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX output_f_local[ch] = output_f_local_buff[ch]; set_zero( output_f_local_buff[ch], nSamplesAsked ); +#else + output_f_local[ch] = output_f[ch]; +#endif } slot_size = NS2SA( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ); @@ -1543,6 +1723,9 @@ void ivas_dirac_dec_render( last_sf++; } +#ifdef DEBUGGING + assert( slots_to_render == 0 ); +#endif for ( subframe_idx = first_sf; subframe_idx < last_sf; subframe_idx++ ) { ivas_dirac_dec_render_sf( st_ivas, output_f_local, nchan_transport, NULL, NULL ); @@ -1552,10 +1735,13 @@ void ivas_dirac_dec_render( output_f_local[ch] += n_samples_sf; } +#ifdef NONBE_UNIFIED_DECODING_PATHS /* update combined orientation access index */ ivas_combined_orientation_update_index( st_ivas->hCombinedOrientationData, n_samples_sf ); +#endif } +#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX for ( ch = 0; ch < nchan_intern; ch++ ) { if ( !( ( st_ivas->hDirACRend->hOutSetup.separateChannelEnabled ) && ( st_ivas->hDirACRend->hOutSetup.separateChannelIndex == ch || st_ivas->hDirACRend->hOutSetup.separateChannelIndex + 1 == ch ) ) ) @@ -1564,6 +1750,7 @@ void ivas_dirac_dec_render( } } +#endif if ( hSpatParamRendCom->slots_rendered == hSpatParamRendCom->num_slots ) { if ( st_ivas->hDirAC->hConfig->dec_param_estim == 1 ) @@ -1610,8 +1797,13 @@ void ivas_dirac_dec_render_sf( /*CLDFB: last output channels reserved to LFT for CICPx*/ float Cldfb_RealBuffer[MAX_OUTPUT_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; float Cldfb_ImagBuffer[MAX_OUTPUT_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; +#ifdef SPLIT_REND_WITH_HEAD_ROT + float Cldfb_RealBuffer_Binaural[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; + float Cldfb_ImagBuffer_Binaural[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; +#else float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; +#endif float Cldfb_RealBuffer_Temp[2][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; float Cldfb_ImagBuffer_Temp[2][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; int16_t index, num_freq_bands; @@ -1651,6 +1843,23 @@ void ivas_dirac_dec_render_sf( coherence_flag = 0; } +#ifdef DEBUG_MODE_DIRAC + { + int16_t n, tmp[IVAS_SPAR_MAX_CH * L_FRAME48k]; + char file_name[50] = { 0 }; + const int16_t output_frame = st_ivas->hDecoderConfig->output_Fs / FRAMES_PER_SEC; + + for ( n = 0; n < nchan_transport; n++ ) + { + for ( i = 0; i < output_frame; i++ ) + { + tmp[nchan_transport * i + n] = (int16_t) ( output_f[n][i] + 0.5f ); + } + } + sprintf( file_name, "./res/ivas_dirac_dec_DMX%d.%d.pcm", nchan_transport, (int16_t) ( output_frame * 0.05 ) ); + dbgwrite( tmp, sizeof( int16_t ), nchan_transport * output_frame, 1, file_name ); + } +#endif /* Subframe loop */ slot_idx_start = hSpatParamRendCom->slots_rendered; @@ -1687,9 +1896,17 @@ void ivas_dirac_dec_render_sf( set_zero( onset_filter_subframe, hSpatParamRendCom->num_freq_bands ); } +#ifdef NONBE_UNIFIED_DECODING_PATHS if ( st_ivas->hCombinedOrientationData && st_ivas->hCombinedOrientationData->enableCombinedOrientation[st_ivas->hCombinedOrientationData->subframe_idx] ) +#else + if ( st_ivas->hCombinedOrientationData && st_ivas->hCombinedOrientationData->enableCombinedOrientation[subframe_idx] ) +#endif { +#ifdef NONBE_UNIFIED_DECODING_PATHS p_Rmat = &st_ivas->hCombinedOrientationData->Rmat[st_ivas->hCombinedOrientationData->subframe_idx][0][0]; +#else + p_Rmat = &st_ivas->hCombinedOrientationData->Rmat[subframe_idx][0][0]; +#endif if ( st_ivas->hCombinedOrientationData->shd_rot_max_order == 0 ) { num_freq_bands = hDirAC->band_grouping[hDirAC->hConfig->enc_param_start_band]; @@ -1753,7 +1970,11 @@ void ivas_dirac_dec_render_sf( } } +#ifdef NONBE_UNIFIED_DECODING_PATHS if ( st_ivas->hCombinedOrientationData && st_ivas->hCombinedOrientationData->enableCombinedOrientation[st_ivas->hCombinedOrientationData->subframe_idx] && st_ivas->hCombinedOrientationData->shd_rot_max_order == 1 ) +#else + if ( st_ivas->hCombinedOrientationData && st_ivas->hCombinedOrientationData->enableCombinedOrientation[subframe_idx] && st_ivas->hCombinedOrientationData->shd_rot_max_order == 1 ) +#endif { ivas_dirac_dec_compute_directional_responses( hSpatParamRendCom, hDirACRend, @@ -1880,7 +2101,11 @@ void ivas_dirac_dec_render_sf( if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD ) { +#ifdef NONBE_UNIFIED_DECODING_PATHS if ( st_ivas->hCombinedOrientationData && st_ivas->hCombinedOrientationData->enableCombinedOrientation[st_ivas->hCombinedOrientationData->subframe_idx] && st_ivas->hCombinedOrientationData->shd_rot_max_order == 0 ) +#else + if ( st_ivas->hCombinedOrientationData && st_ivas->hCombinedOrientationData->enableCombinedOrientation[subframe_idx] && st_ivas->hCombinedOrientationData->shd_rot_max_order == 0 ) +#endif { protoSignalComputation_shd( Cldfb_RealBuffer, Cldfb_ImagBuffer, hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f, @@ -1993,6 +2218,53 @@ void ivas_dirac_dec_render_sf( computeDiffuseness( hDirACRend->buffer_intensity_real, hDirACRend->buffer_energy, num_freq_bands, hSpatParamRendCom->diffuseness_vector[md_idx] ); } +#ifdef DEBUG_MODE_DIRAC + { + static FILE *fp_direction_vector = NULL, *fp_diffuseness = NULL, *fp_referencePower = NULL; + + + if ( fp_direction_vector == NULL ) + fp_direction_vector = fopen( "./res/dbg_direction_vector_C_dec.bin", "wb" ); + if ( fp_diffuseness == NULL ) + fp_diffuseness = fopen( "./res/dbg_diffuseness_C_dec.bin", "wb" ); + if ( fp_referencePower == NULL ) + fp_referencePower = fopen( "./res/dbg_reference_power_C_dec.bin", "wb" ); + + + for ( i = 0; i < hSpatParamRendCom->num_freq_bands; i++ ) + { + float radius_length; + float dv[3]; + + if ( hDirAC->hConfig->dec_param_estim == FALSE ) + { + radius_length = cos( hDirAC->elevation[subframe_idx][i] * PI_OVER_180 ); + dv[0] = radius_length * cos( hDirAC->azimuth[subframe_idx][i] * PI_OVER_180 ); + dv[1] = radius_length * sin( hDirAC->azimuth[subframe_idx][i] * PI_OVER_180 ); + dv[2] = sin( hDirAC->elevation[subframe_idx][i] * PI_OVER_180 ); + + fwrite( dv, sizeof( float ), 3, fp_direction_vector ); + fwrite( &( hDirAC->diffuseness_vector[0][i] ), sizeof( float ), 1, fp_diffuseness ); + if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD ) + { + reference_power[i] = Cldfb_RealBuffer[0][0][i] * Cldfb_RealBuffer[0][0][i] + Cldfb_ImagBuffer[0][0][i] * Cldfb_ImagBuffer[0][0][i]; + } + fwrite( &( reference_power[i] ), sizeof( float ), 1, fp_referencePower ); + } + else + { + radius_length = cos( hDirAC->elevation[index_slot][i] * PI_OVER_180 ); + dv[0] = radius_length * cos( hDirAC->azimuth[index_slot][i] * PI_OVER_180 ); + dv[1] = radius_length * sin( hDirAC->azimuth[index_slot][i] * PI_OVER_180 ); + dv[2] = sin( hDirAC->elevation[index_slot][i] * PI_OVER_180 ); + + fwrite( dv, sizeof( float ), 3, fp_direction_vector ); + fwrite( &( hDirAC->diffuseness_vector[index_slot][i] ), sizeof( float ), 1, fp_diffuseness ); + fwrite( &( reference_power[i] ), sizeof( float ), 1, fp_referencePower ); + } + } + } +#endif /*-----------------------------------------------------------------* * frequency domain decorrelation @@ -2065,7 +2337,11 @@ void ivas_dirac_dec_render_sf( } /*Compute PSDs*/ +#ifdef NONBE_UNIFIED_DECODING_PATHS if ( st_ivas->hCombinedOrientationData && st_ivas->hCombinedOrientationData->enableCombinedOrientation[st_ivas->hCombinedOrientationData->subframe_idx] && st_ivas->hCombinedOrientationData->shd_rot_max_order > 0 ) +#else + if ( st_ivas->hCombinedOrientationData && st_ivas->hCombinedOrientationData->enableCombinedOrientation[subframe_idx] && st_ivas->hCombinedOrientationData->shd_rot_max_order > 0 ) +#endif { ivas_dirac_dec_output_synthesis_process_slot( reference_power, p_onset_filter, @@ -2243,13 +2519,56 @@ void ivas_dirac_dec_render_sf( } } +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { + if ( st_ivas->hSplitBinRend.hCldfbDataOut != NULL ) + { + for ( slot_idx = 0; slot_idx < hSpatParamRendCom->subframe_nbslots[subframe_idx]; slot_idx++ ) + { + for ( ch = 0; ch < st_ivas->hBinRenderer->nInChannels; ch++ ) + { + mvr2r( Cldfb_RealBuffer[ch][slot_idx], st_ivas->hSplitBinRend.hCldfbDataOut->Cldfb_RealBuffer[ch][slot_idx_start + slot_idx], hSpatParamRendCom->num_freq_bands ); + mvr2r( Cldfb_ImagBuffer[ch][slot_idx], st_ivas->hSplitBinRend.hCldfbDataOut->Cldfb_ImagBuffer[ch][slot_idx_start + slot_idx], hSpatParamRendCom->num_freq_bands ); + } + } + st_ivas->hSplitBinRend.hCldfbDataOut->config = st_ivas->hIntSetup.output_config; + } + } +#endif /* Perform binaural rendering */ ivas_binRenderer( st_ivas->hBinRenderer, +#ifdef SPLIT_REND_WITH_HEAD_ROT + &st_ivas->hSplitBinRend.splitrend.multiBinPoseData, +#endif st_ivas->hCombinedOrientationData, +#ifndef NONBE_UNIFIED_DECODING_PATHS + subframe_idx, +#endif hSpatParamRendCom->subframe_nbslots[subframe_idx], +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + NULL, +#endif Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, Cldfb_RealBuffer, Cldfb_ImagBuffer ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { + int16_t pos_idx; + for ( pos_idx = 0; pos_idx < st_ivas->hBinRenderer->numPoses; pos_idx++ ) + { + for ( slot_idx = 0; slot_idx < hSpatParamRendCom->subframe_nbslots[subframe_idx]; slot_idx++ ) + { + for ( ch = 0; ch < st_ivas->hDecoderConfig->nchan_out; ch++ ) + { + mvr2r( Cldfb_RealBuffer_Binaural[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend.hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[( pos_idx * BINAURAL_CHANNELS ) + ch][slot_idx_start + slot_idx], hSpatParamRendCom->num_freq_bands ); + mvr2r( Cldfb_ImagBuffer_Binaural[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend.hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[( pos_idx * BINAURAL_CHANNELS ) + ch][slot_idx_start + slot_idx], hSpatParamRendCom->num_freq_bands ); + } + } + } + } +#endif /* Inverse CLDFB*/ for ( ch = 0; ch < st_ivas->hDecoderConfig->nchan_out; ch++ ) @@ -2260,8 +2579,13 @@ void ivas_dirac_dec_render_sf( for ( i = 0; i < hSpatParamRendCom->subframe_nbslots[subframe_idx]; i++ ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + RealBuffer[i] = Cldfb_RealBuffer_Binaural[0][ch][i]; + ImagBuffer[i] = Cldfb_ImagBuffer_Binaural[0][ch][i]; +#else RealBuffer[i] = Cldfb_RealBuffer_Binaural[ch][i]; ImagBuffer[i] = Cldfb_ImagBuffer_Binaural[ch][i]; +#endif } cldfbSynthesis( RealBuffer, ImagBuffer, &( output_f[ch][index_slot * hSpatParamRendCom->num_freq_bands] ), hSpatParamRendCom->num_freq_bands * hSpatParamRendCom->subframe_nbslots[subframe_idx], st_ivas->cldfbSynDec[ch] ); diff --git a/lib_dec/ivas_dirac_output_synthesis_cov.c b/lib_dec/ivas_dirac_output_synthesis_cov.c index 092ffe411..d71d81655 100644 --- a/lib_dec/ivas_dirac_output_synthesis_cov.c +++ b/lib_dec/ivas_dirac_output_synthesis_cov.c @@ -45,6 +45,9 @@ #include "ivas_cnst.h" #include "ivas_rom_com.h" #include "ivas_rom_dec.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" #include "rom_dec.h" diff --git a/lib_dec/ivas_entropy_decoder.c b/lib_dec/ivas_entropy_decoder.c index 360dfbe87..bf91f3e69 100644 --- a/lib_dec/ivas_entropy_decoder.c +++ b/lib_dec/ivas_entropy_decoder.c @@ -35,6 +35,9 @@ #include "prot.h" #include "ivas_prot.h" #include "ivas_cnst.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "ivas_rom_com.h" #include #include "wmc_auto.h" diff --git a/lib_dec/ivas_init_dec.c b/lib_dec/ivas_init_dec.c index d23a36417..a2e53ceb0 100644 --- a/lib_dec/ivas_init_dec.c +++ b/lib_dec/ivas_init_dec.c @@ -37,9 +37,15 @@ #include "ivas_rom_com.h" #include "ivas_stat_enc.h" #include "prot.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT +#include "common_api_types.h" +#endif #include #include #include +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" @@ -51,6 +57,217 @@ static ivas_error ivas_read_format( Decoder_Struct *st_ivas, int16_t *num_bits_r static ivas_error doSanityChecks_IVAS( Decoder_Struct *st_ivas ); +#ifdef SPLIT_REND_WITH_HEAD_ROT +static ivas_error ivas_dec_reconfig_split_rend( Decoder_Struct *st_ivas ); + + +/*-------------------------------------------------------------------* + * ivas_dec_reconfig_split_rend() + * + * IVAS decoder split rend reconfig + *-------------------------------------------------------------------*/ + +static ivas_error ivas_dec_reconfig_split_rend( + Decoder_Struct *st_ivas /* i : IVAS decoder structure */ +) +{ + ivas_error error; + int16_t cldfb_in_flag, num_ch, ch, isCldfbNeeded, i, pcm_out_flag; + SPLIT_REND_WRAPPER *hSplitRendWrapper; +#ifndef SPLIT_REND_WITH_HEAD_ROT + CLDFB_TYPE cldfbMode; +#endif + + hSplitRendWrapper = &st_ivas->hSplitBinRend.splitrend; + pcm_out_flag = ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0; + cldfb_in_flag = 0; + + if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || + st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM || + st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || + st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) + { + cldfb_in_flag = 1; + } + + ivas_renderSplitGetMultiBinPoseData( &st_ivas->hRenderConfig->split_rend_config, &hSplitRendWrapper->multiBinPoseData, st_ivas->hHeadTrackData->sr_pose_pred_axis ); + + isCldfbNeeded = 0; +#ifndef SPLIT_REND_WITH_HEAD_ROT + cldfbMode = CLDFB_ANALYSIS; +#else + if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV && st_ivas->ivas_format == SBA_ISM_FORMAT ) + { + cldfb_in_flag = 0; + } +#endif + + if ( st_ivas->renderer_type != RENDERER_DISABLE ) + { + if ( cldfb_in_flag == 0 ) + { + isCldfbNeeded = 1; +#ifndef SPLIT_REND_WITH_HEAD_ROT + cldfbMode = CLDFB_ANALYSIS; +#endif + } + else if ( st_ivas->hRenderConfig->split_rend_config.codec == IVAS_SPLIT_REND_CODEC_LC3PLUS && cldfb_in_flag ) + { + isCldfbNeeded = 1; +#ifndef SPLIT_REND_WITH_HEAD_ROT + cldfbMode = CLDFB_SYNTHESIS; +#endif + } + else if ( pcm_out_flag && cldfb_in_flag ) + { + isCldfbNeeded = 1; +#ifndef SPLIT_REND_WITH_HEAD_ROT + cldfbMode = CLDFB_SYNTHESIS; +#endif + } + } + + if ( isCldfbNeeded == 1 && hSplitRendWrapper->hCldfbHandles == 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++ ) + { + hSplitRendWrapper->hCldfbHandles->cldfbAna[ch] = NULL; + } + + num_ch = hSplitRendWrapper->multiBinPoseData.num_poses * BINAURAL_CHANNELS; + + for ( ch = 0; ch < num_ch; ch++ ) + { +#ifndef SPLIT_REND_WITH_HEAD_ROT + if ( ( error = openCldfb( &( hSplitRendWrapper->hCldfbHandles->cldfbAna[ch] ), cldfbMode, st_ivas->hDecoderConfig->output_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) +#else + if ( ( error = openCldfb( &( hSplitRendWrapper->hCldfbHandles->cldfbAna[ch] ), CLDFB_ANALYSIS, st_ivas->hDecoderConfig->output_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) +#endif + + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not open CLDFB handles\n" ) ); + } + } + +#ifdef SPLIT_REND_WITH_HEAD_ROT + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + if ( ( error = openCldfb( &( hSplitRendWrapper->hCldfbHandles->cldfbSyn[ch] ), CLDFB_SYNTHESIS, st_ivas->hDecoderConfig->output_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) + { + return error; + } + } +#endif + } + else if ( isCldfbNeeded == 0 && hSplitRendWrapper->hCldfbHandles != NULL ) + { + num_ch = MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS; + for ( ch = 0; ch < num_ch; ch++ ) + { + if ( hSplitRendWrapper->hCldfbHandles->cldfbAna[ch] != NULL ) + { + deleteCldfb( &hSplitRendWrapper->hCldfbHandles->cldfbAna[ch] ); + hSplitRendWrapper->hCldfbHandles->cldfbAna[ch] = NULL; + } + } + +#ifdef SPLIT_REND_WITH_HEAD_ROT + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + if ( hSplitRendWrapper->hCldfbHandles->cldfbSyn[ch] != NULL ) + { + deleteCldfb( &hSplitRendWrapper->hCldfbHandles->cldfbSyn[ch] ); + hSplitRendWrapper->hCldfbHandles->cldfbSyn[ch] = NULL; + } + } +#endif + + free( hSplitRendWrapper->hCldfbHandles ); + hSplitRendWrapper->hCldfbHandles = NULL; + } + +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( st_ivas->renderer_type != RENDERER_BINAURAL_OBJECTS_TD ) && + ( st_ivas->renderer_type != RENDERER_BINAURAL_FASTCONV || st_ivas->ivas_format != SBA_ISM_FORMAT ) ) +#else + if ( st_ivas->renderer_type != RENDERER_BINAURAL_OBJECTS_TD ) +#endif + { + for ( i = 0; i < MAX_HEAD_ROT_POSES - 1; ++i ) + { + if ( hSplitRendWrapper->hTdRendHandles[i] != NULL ) + { + hSplitRendWrapper->hTdRendHandles[i]->HrFiltSet_p = NULL; + ivas_td_binaural_close( &hSplitRendWrapper->hTdRendHandles[i] ); + } + } + } + + return IVAS_ERR_OK; +} + + +/*-------------------------------------------------------------------* + * ivas_dec_init_split_rend() + * + * IVAS decoder split rend init + *-------------------------------------------------------------------*/ + +static ivas_error ivas_dec_init_split_rend( + Decoder_Struct *st_ivas /* i : IVAS decoder structure */ +) +{ + ivas_error error; + int16_t cldfb_in_flag, pcm_out_flag; + + pcm_out_flag = ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0; + cldfb_in_flag = 0; + + if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || + st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM || + st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || + st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) + { + cldfb_in_flag = 1; + } + + ivas_renderSplitGetMultiBinPoseData( &st_ivas->hRenderConfig->split_rend_config, &st_ivas->hSplitBinRend.splitrend.multiBinPoseData, st_ivas->hHeadTrackData->sr_pose_pred_axis ); + + if ( cldfb_in_flag == 1 && ( st_ivas->hSplitBinRend.splitrend.multiBinPoseData.poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) ) + { + if ( ( st_ivas->hSplitBinRend.hCldfbDataOut = (IVAS_DEC_SPLIT_REND_CLDFB_OUT_DATA_HANDLE) malloc( sizeof( IVAS_DEC_SPLIT_REND_CLDFB_OUT_DATA ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for cldfb data out buffer\n" ) ); + } + } + + if ( ( error = ivas_split_rend_choose_default_codec( &st_ivas->hRenderConfig->split_rend_config.codec, &st_ivas->hRenderConfig->split_rend_config.codec_frame_size_ms, cldfb_in_flag, pcm_out_flag ) ) != IVAS_ERR_OK ) + { + return error; + } + +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV && st_ivas->ivas_format == SBA_ISM_FORMAT ) + { + cldfb_in_flag = 0; + } +#endif + +#ifdef NONBE_UNIFIED_DECODING_PATHS + error = ivas_split_renderer_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 == IVAS_RENDER_FRAMESIZE_5MS ); +#else + error = ivas_split_renderer_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->Opt_5ms ); +#endif + + return error; +} +#endif /*-------------------------------------------------------------------* @@ -62,7 +279,12 @@ static ivas_error doSanityChecks_IVAS( Decoder_Struct *st_ivas ); ivas_error ivas_dec_setup( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ uint16_t *nSamplesRendered, /* o : number of samples flushed from the previous frame (JBM) */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + const PCM_RESOLUTION pcm_resolution, /* i : type for the decoded PCM resolution */ + void *data /* o : output synthesis signal */ +#else int16_t *data /* o : output synthesis signal */ +#endif ) { int16_t k, idx, num_bits_read; @@ -116,7 +338,11 @@ ivas_error ivas_dec_setup( st_ivas->nchan_ism = nchan_ism; +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( error = ivas_ism_dec_config( st_ivas, st_ivas->ism_mode, nSamplesRendered, pcm_resolution, data ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_ism_dec_config( st_ivas, st_ivas->ism_mode, nSamplesRendered, data ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -131,18 +357,29 @@ ivas_error ivas_dec_setup( st_ivas->sba_order = st_ivas->bit_stream[num_bits_read + 1]; st_ivas->sba_order += 2 * st_ivas->bit_stream[num_bits_read]; +#ifndef NONBE_UNIFIED_DECODING_PATHS + /* set Ambisonic (SBA) order used for analysis and coding */ + st_ivas->sba_analysis_order = ivas_sba_get_analysis_order( ivas_total_brate, st_ivas->sba_order ); + +#endif num_bits_read += SBA_ORDER_BITS; if ( st_ivas->ini_frame > 0 && ivas_total_brate != st_ivas->last_active_ivas_total_brate && ivas_total_brate > IVAS_SID_5k2 ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( error = ivas_sba_dec_reconfigure( st_ivas, nSamplesRendered, pcm_resolution, data ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_sba_dec_reconfigure( st_ivas, nSamplesRendered, data ) ) != IVAS_ERR_OK ) +#endif { return error; } } else { +#ifdef NONBE_UNIFIED_DECODING_PATHS /* set Ambisonic (SBA) order used for analysis and coding */ st_ivas->sba_analysis_order = ivas_sba_get_analysis_order( ivas_total_brate, st_ivas->sba_order ); +#endif ivas_sba_config( ivas_total_brate, st_ivas->sba_analysis_order, -1, &( st_ivas->nchan_transport ), st_ivas->sba_planar, &st_ivas->nSCE, &st_ivas->nCPE, &st_ivas->element_mode_init ); } @@ -174,7 +411,11 @@ ivas_error ivas_dec_setup( else { +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( error = ivas_masa_dec_reconfigure( st_ivas, nSamplesRendered, pcm_resolution, data ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_masa_dec_reconfigure( st_ivas, nSamplesRendered, data ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -182,7 +423,11 @@ ivas_error ivas_dec_setup( } else { +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( error = ivas_omasa_dec_config( st_ivas, nSamplesRendered, pcm_resolution, data ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_omasa_dec_config( st_ivas, nSamplesRendered, data ) ) != IVAS_ERR_OK ) +#endif { return error; @@ -204,7 +449,11 @@ ivas_error ivas_dec_setup( /* reconfigure in case a change of operation mode is detected */ if ( ( ivas_total_brate > IVAS_SID_5k2 && ivas_total_brate != st_ivas->hDecoderConfig->last_ivas_total_brate ) || ( st_ivas->ini_active_frame == 0 ) ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( error = ivas_omasa_dec_config( st_ivas, nSamplesRendered, pcm_resolution, data ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_omasa_dec_config( st_ivas, nSamplesRendered, data ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -235,7 +484,11 @@ ivas_error ivas_dec_setup( if ( st_ivas->ini_frame > 0 && ivas_total_brate != st_ivas->last_active_ivas_total_brate ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( error = ivas_sba_dec_reconfigure( st_ivas, nSamplesRendered, pcm_resolution, data ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_sba_dec_reconfigure( st_ivas, nSamplesRendered, data ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -277,10 +530,17 @@ ivas_error ivas_dec_setup( num_bits_read += MC_LS_SETUP_BITS; /* select MC format mode; reconfigure the MC format decoder */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( error = ivas_mc_dec_config( st_ivas, idx, nSamplesRendered, pcm_resolution, data ) ) != IVAS_ERR_OK ) + { + return error; + } +#else if ( ( error = ivas_mc_dec_config( st_ivas, idx, nSamplesRendered, data ) ) != IVAS_ERR_OK ) { return error; } +#endif } /*-------------------------------------------------------------------* @@ -362,7 +622,11 @@ ivas_error ivas_dec_setup( st_ivas->hDecoderConfig->ivas_total_brate = IVAS_24k4; } +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( error = ivas_sba_dec_reconfigure( st_ivas, nSamplesRendered, pcm_resolution, data ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_sba_dec_reconfigure( st_ivas, nSamplesRendered, data ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -372,9 +636,15 @@ ivas_error ivas_dec_setup( } } +#ifdef NONBE_FIX_898_ISM_BRATE_CRASH if ( st_ivas->ivas_format == ISM_FORMAT ) +#else + if ( st_ivas->ini_frame == 0 && st_ivas->ivas_format == ISM_FORMAT ) +#endif { +#ifdef NONBE_FIX_898_ISM_BRATE_CRASH ISM_MODE last_ism_mode = st_ivas->ism_mode; +#endif /* read the number of objects */ st_ivas->nchan_transport = 1; @@ -387,10 +657,12 @@ ivas_error ivas_dec_setup( } k--; +#ifdef NONBE_FIX_898_ISM_BRATE_CRASH if ( st_ivas->ini_frame > 0 && nchan_ism != st_ivas->nchan_ism ) { return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "wrong number of objects signalled!" ); } +#endif st_ivas->nchan_ism = nchan_ism; @@ -403,12 +675,26 @@ ivas_error ivas_dec_setup( st_ivas->ism_mode = (ISM_MODE) ( idx + 1 ); } +#ifdef NONBE_FIX_898_ISM_BRATE_CRASH if ( st_ivas->ini_frame == 0 ) { last_ism_mode = st_ivas->ism_mode; } +#endif +#ifdef SPLIT_REND_WITH_HEAD_ROT +#ifdef NONBE_FIX_898_ISM_BRATE_CRASH + if ( ( error = ivas_ism_dec_config( st_ivas, last_ism_mode, nSamplesRendered, pcm_resolution, data ) ) != IVAS_ERR_OK ) +#else + if ( ( error = ivas_ism_dec_config( st_ivas, st_ivas->ism_mode, nSamplesRendered, pcm_resolution, data ) ) != IVAS_ERR_OK ) +#endif +#else +#ifdef NONBE_FIX_898_ISM_BRATE_CRASH if ( ( error = ivas_ism_dec_config( st_ivas, last_ism_mode, nSamplesRendered, data ) ) != IVAS_ERR_OK ) +#else + if ( ( error = ivas_ism_dec_config( st_ivas, st_ivas->ism_mode, nSamplesRendered, data ) ) != IVAS_ERR_OK ) +#endif +#endif { return error; } @@ -433,6 +719,19 @@ ivas_error ivas_dec_setup( } } +#ifdef SPLIT_REND_WITH_HEAD_ROT + /*-----------------------------------------------------------------* + * reconfig split rendering as renderer might change after bitrate switching + *-----------------------------------------------------------------*/ + + if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { + if ( ( error = ivas_dec_reconfig_split_rend( st_ivas ) ) != IVAS_ERR_OK ) + { + return error; + } + } +#endif /*----------------------------------------------------------------* * Reset bitstream pointers @@ -715,6 +1014,11 @@ ivas_error ivas_init_decoder_front( /* HRTF binauralization latency in ns */ st_ivas->binaural_latency_ns = 0; +#ifdef DEBUGGING + st_ivas->noClipping = 0; + + st_ivas->hDecoderConfig->force_rend = -1; +#endif /*-------------------------------------------------------------------* * Allocate and initialize Custom loudspeaker layout handle *--------------------------------------------------------------------*/ @@ -749,7 +1053,11 @@ ivas_error ivas_init_decoder_front( if ( st_ivas->hDecoderConfig->Opt_ExternalOrientation ) { +#ifdef NONBE_UNIFIED_DECODING_PATHS if ( ( error = ivas_external_orientation_open( &( st_ivas->hExtOrientationData ), st_ivas->hDecoderConfig->render_framesize ) ) != IVAS_ERR_OK ) +#else + if ( ( error = ivas_external_orientation_open( &( st_ivas->hExtOrientationData ), ( st_ivas->hDecoderConfig->Opt_5ms ) ? 1 : MAX_PARAM_SPATIAL_SUBFRAMES ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -761,7 +1069,11 @@ ivas_error ivas_init_decoder_front( if ( st_ivas->hDecoderConfig->Opt_Headrotation || st_ivas->hDecoderConfig->Opt_ExternalOrientation ) { +#ifdef NONBE_UNIFIED_DECODING_PATHS if ( ( error = ivas_combined_orientation_open( &( st_ivas->hCombinedOrientationData ), st_ivas->hDecoderConfig->output_Fs, st_ivas->hDecoderConfig->render_framesize ) ) != IVAS_ERR_OK ) +#else + if ( ( error = ivas_combined_orientation_open( &( st_ivas->hCombinedOrientationData ), ( st_ivas->hDecoderConfig->Opt_5ms ) ? 1 : MAX_PARAM_SPATIAL_SUBFRAMES ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -798,6 +1110,9 @@ ivas_error ivas_init_decoder_front( *--------------------------------------------------------------------*/ if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB +#ifdef SPLIT_REND_WITH_HEAD_ROT + || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM +#endif ) { if ( ( error = ivas_render_config_open( &( st_ivas->hRenderConfig ) ) ) != IVAS_ERR_OK ) @@ -941,6 +1256,23 @@ ivas_error ivas_init_decoder( } } +#ifdef SPLIT_REND_WITH_HEAD_ROT + /*-----------------------------------------------------------------* + * Initialize binuaral split rendering + *-----------------------------------------------------------------*/ + + if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { + if ( ( error = ivas_dec_init_split_rend( st_ivas ) ) != IVAS_ERR_OK ) + { + return error; + } + } + else + { + st_ivas->hSplitBinRend.splitrend.multiBinPoseData.num_poses = 1; + } +#endif /*-----------------------------------------------------------------* * Allocate and initialize SCE/CPE and other handles @@ -1029,6 +1361,7 @@ ivas_error ivas_init_decoder( st_ivas->hISMDTX.sce_id_dtx = 0; +#ifdef NONBE_FIX_DISCRETE_ISM_NOISE_SEED_HANDLING if ( st_ivas->ism_mode == ISM_MODE_PARAM ) { st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->seed2 = st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->seed3; @@ -1040,6 +1373,12 @@ ivas_error ivas_init_decoder( st_ivas->hSCE[sce_id]->hCoreCoder[0]->hFdCngDec->hFdCngCom->seed2 = 2 + sce_id; } } +#else + if ( st_ivas->ism_mode == ISM_MODE_PARAM ) + { + st_ivas->hSCE[1]->hCoreCoder[0]->hFdCngDec->hFdCngCom->seed3 = st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->seed2; + } +#endif } else if ( st_ivas->ivas_format == SBA_FORMAT ) { @@ -1062,8 +1401,10 @@ ivas_error ivas_init_decoder( } if ( ( error = ivas_dirac_sba_config( st_ivas->hQMetaData, &st_ivas->element_mode_init, ivas_total_brate, st_ivas->sba_analysis_order, ivas_get_hodirac_flag( ivas_total_brate, st_ivas->sba_analysis_order ) ? IVAS_MAX_NUM_BANDS : ( IVAS_MAX_NUM_BANDS - SPAR_DIRAC_SPLIT_START_BAND ) +#ifdef NONBE_FIX_871_ACELP_CRASH_IN_OSBA , st_ivas->ivas_format +#endif ) ) != IVAS_ERR_OK ) { return error; @@ -1218,8 +1559,10 @@ ivas_error ivas_init_decoder( } if ( ( error = ivas_dirac_sba_config( st_ivas->hQMetaData, &st_ivas->element_mode_init, ivas_total_brate, st_ivas->sba_analysis_order, ivas_get_hodirac_flag( ivas_total_brate, st_ivas->sba_analysis_order ) ? IVAS_MAX_NUM_BANDS : ( IVAS_MAX_NUM_BANDS - SPAR_DIRAC_SPLIT_START_BAND ) +#ifdef NONBE_FIX_871_ACELP_CRASH_IN_OSBA , st_ivas->ivas_format +#endif ) ) != IVAS_ERR_OK ) { return error; @@ -1604,6 +1947,12 @@ ivas_error ivas_init_decoder( } } } +#ifdef DEBUGGING + else + { + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Error: Invalid IVAS format. Exiting,\n" ); + } +#endif /*-----------------------------------------------------------------* @@ -1679,6 +2028,10 @@ ivas_error ivas_init_decoder( } } +#ifndef NONBE_UNIFIED_DECODING_PATHS + if ( st_ivas->hDecoderConfig->Opt_5ms ) + { +#endif granularity = NS2SA( st_ivas->hDecoderConfig->output_Fs, FRAME_SIZE_NS / MAX_PARAM_SPATIAL_SUBFRAMES ); n_channels_transport_jbm = ivas_jbm_dec_get_num_tc_channels( st_ivas ); @@ -1686,6 +2039,9 @@ ivas_error ivas_init_decoder( { return error; } +#ifndef NONBE_UNIFIED_DECODING_PATHS + } +#endif } else if ( st_ivas->renderer_type == RENDERER_MC ) { @@ -1711,14 +2067,23 @@ ivas_error ivas_init_decoder( } } +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( error = ivas_rend_openCrend( &( st_ivas->hCrendWrapper ), st_ivas->intern_config, st_ivas->hDecoderConfig->output_config, + st_ivas->hRenderConfig, st_ivas->hSetOfHRTF, st_ivas->hDecoderConfig->output_Fs, st_ivas->hSplitBinRend.splitrend.multiBinPoseData.num_poses ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_rend_openCrend( &( st_ivas->hCrendWrapper ), st_ivas->intern_config, st_ivas->hDecoderConfig->output_config, st_ivas->hRenderConfig, st_ivas->hSetOfHRTF, st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK ) +#endif { return error; } st_ivas->binaural_latency_ns = st_ivas->hCrendWrapper->binaural_latency_ns; +#ifndef NONBE_UNIFIED_DECODING_PATHS + if ( st_ivas->hDecoderConfig->Opt_5ms ) + { +#endif if ( ( st_ivas->ivas_format == MC_FORMAT ) && ( st_ivas->mc_mode == MC_MODE_PARAMUPMIX ) ) { granularity = NS2SA( output_Fs, CLDFB_SLOT_NS ); @@ -1741,6 +2106,9 @@ ivas_error ivas_init_decoder( return error; } } +#ifndef NONBE_UNIFIED_DECODING_PATHS + } +#endif } if ( st_ivas->ivas_format == MASA_ISM_FORMAT ) @@ -1811,6 +2179,9 @@ ivas_error ivas_init_decoder( { if ( st_ivas->hBinRenderer->render_lfe ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( st_ivas->hDecoderConfig->output_config != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED && st_ivas->hDecoderConfig->output_config != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) +#endif { /* Account for filterbank delay */ binauralization_delay_ns += IVAS_FB_DEC_DELAY_NS; @@ -1880,7 +2251,11 @@ ivas_error ivas_init_decoder( * Allocate and initialize JBM struct + buffer *-----------------------------------------------------------------*/ +#ifndef NONBE_UNIFIED_DECODING_PATHS + if ( st_ivas->hDecoderConfig->Opt_5ms && st_ivas->hTcBuffer == NULL ) +#else if ( st_ivas->hTcBuffer == NULL ) +#endif { /* no module has yet open the TC buffer, open a default one */ @@ -1916,6 +2291,10 @@ ivas_error ivas_init_decoder( * Allocate floating-point output audio buffers *-----------------------------------------------------------------*/ +#ifndef NONBE_UNIFIED_DECODING_PATHS + if ( !st_ivas->hDecoderConfig->Opt_5ms ) + { +#endif for ( n = 0; n < ivas_get_nchan_buffers_dec( st_ivas, st_ivas->sba_analysis_order, st_ivas->hDecoderConfig->ivas_total_brate ); n++ ) { /* note: these are intra-frame heap memories */ @@ -1924,6 +2303,13 @@ ivas_error ivas_init_decoder( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for floating-point output audio buffer!\n" ) ); } } +#ifndef NONBE_UNIFIED_DECODING_PATHS + } + else + { + n = 0; + } +#endif for ( ; n < MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS; n++ ) { @@ -2134,7 +2520,14 @@ void ivas_initialize_handles_dec( /* rendering handles */ st_ivas->hBinRenderer = NULL; +#ifdef SPLIT_REND_WITH_HEAD_ROT + for ( i = 0; i < MAX_HEAD_ROT_POSES; i++ ) + { + st_ivas->hDiracDecBin[i] = NULL; + } +#else st_ivas->hDiracDecBin = NULL; +#endif st_ivas->hDirACRend = NULL; st_ivas->hSpatParamRendCom = NULL; st_ivas->hLsSetUpConversion = NULL; @@ -2159,6 +2552,14 @@ void ivas_initialize_handles_dec( st_ivas->hExtOrientationData = NULL; st_ivas->hCombinedOrientationData = NULL; +#ifdef SPLIT_REND_WITH_HEAD_ROT + st_ivas->hSplitBinRend.hMultiBinCldfbData = NULL; + st_ivas->hSplitBinRend.hSplitRendBits = NULL; + st_ivas->hSplitBinRend.hCldfbDataOut = NULL; + st_ivas->hSplitBinRend.tdDataOut = NULL; + st_ivas->hSplitBinRend.numTdSamplesPerChannelCached = 0; + ivas_init_split_rend_handles( &st_ivas->hSplitBinRend.splitrend ); +#endif /* JBM handles */ st_ivas->hTcBuffer = NULL; @@ -2296,13 +2697,36 @@ void ivas_destroy_dec( /* Fastconv binaural renderer handle */ ivas_binRenderer_close( &st_ivas->hBinRenderer ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + /* Split binaural renderer handle */ + ivas_split_renderer_close( &st_ivas->hSplitBinRend.splitrend ); + + if ( st_ivas->hSplitBinRend.hCldfbDataOut != NULL ) + { + free( st_ivas->hSplitBinRend.hCldfbDataOut ); + st_ivas->hSplitBinRend.hCldfbDataOut = NULL; + } + + if ( st_ivas->hSplitBinRend.tdDataOut != NULL ) + { + free( st_ivas->hSplitBinRend.tdDataOut ); + } +#endif /* Parametric binaural renderer handle */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + ivas_dirac_dec_close_binaural_data( st_ivas->hDiracDecBin ); +#else ivas_dirac_dec_close_binaural_data( &st_ivas->hDiracDecBin ); +#endif /* Crend handle */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + ivas_rend_closeCrend( &( st_ivas->hCrendWrapper ), st_ivas->hSplitBinRend.splitrend.multiBinPoseData.num_poses ); +#else ivas_rend_closeCrend( &( st_ivas->hCrendWrapper ) ); +#endif /* Reverb handle */ ivas_reverb_close( &st_ivas->hReverb ); @@ -2449,7 +2873,11 @@ void ivas_init_dec_get_num_cldfb_instances( *numCldfbAnalyses = st_ivas->nchan_transport + 1; } } +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( st_ivas->hDiracDecBin[0]->useTdDecorr ) +#else if ( st_ivas->hDiracDecBin->useTdDecorr ) +#endif { *numCldfbAnalyses += 2; } @@ -2683,10 +3111,19 @@ static ivas_error doSanityChecks_IVAS( } } +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) && output_Fs != 48000 ) + { + return IVAS_ERROR( IVAS_ERR_INVALID_SAMPLING_RATE, "Error: Only 48kHz output sampling rate is supported for split rendering." ); + } +#endif if ( st_ivas->hDecoderConfig->Opt_Headrotation ) { if ( !( output_config == IVAS_AUDIO_CONFIG_BINAURAL || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB +#ifdef SPLIT_REND_WITH_HEAD_ROT + || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM +#endif ) ) { return IVAS_ERROR( IVAS_ERR_HEAD_ROTATION_NOT_SUPPORTED, "Wrong set-up: Head-rotation not supported in this configuration" ); @@ -2725,6 +3162,17 @@ static ivas_error doSanityChecks_IVAS( } } +#ifdef DEBUGGING + if ( ( st_ivas->hDecoderConfig->force_rend == FORCE_TD_RENDERER ) && ( ( st_ivas->ivas_format != MC_FORMAT && st_ivas->ivas_format != ISM_FORMAT ) || ( output_config != IVAS_AUDIO_CONFIG_BINAURAL && output_config != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) || ( st_ivas->ivas_format == ISM_FORMAT && st_ivas->ism_mode == ISM_MODE_PARAM ) || ( st_ivas->ivas_format == MC_FORMAT && st_ivas->mc_mode != MC_MODE_MCT ) ) ) + { + return IVAS_ERROR( IVAS_ERR_INVALID_OUTPUT_FORMAT, "Incorrect output configuration: Time Domain object renderer not supported in this configuration" ); + } + + if ( ( st_ivas->hHrtfTD != NULL && st_ivas->hDecoderConfig->force_rend == FORCE_CLDFB_RENDERER ) ) + { + return IVAS_ERROR( IVAS_ERR_INVALID_FORCE_MODE, "Incorrect debug configuration: Cannot force CLDFB renderer in combination with TD renderer HRTF file" ); + } +#endif return IVAS_ERR_OK; } diff --git a/lib_dec/ivas_ism_dec.c b/lib_dec/ivas_ism_dec.c index d784324e9..7d22eb50b 100644 --- a/lib_dec/ivas_ism_dec.c +++ b/lib_dec/ivas_ism_dec.c @@ -35,6 +35,9 @@ #include "prot.h" #include "ivas_prot.h" #include "ivas_prot_rend.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" /*-------------------------------------------------------------------------* @@ -48,7 +51,12 @@ static ivas_error ivas_ism_bitrate_switching_dec( const int16_t nchan_transport_old, /* i : last number of transport channels */ const ISM_MODE last_ism_mode, /* i : last ISM mode */ uint16_t *nSamplesRendered, /* o : number of samples rendered */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + const PCM_RESOLUTION pcm_resolution, /* i : type for the decoded PCM resolution */ + void *data /* o : output synthesis signal */ +#else int16_t *data /* o : output synthesis signal */ +#endif ) { ivas_error error; @@ -120,6 +128,9 @@ static ivas_error ivas_ism_bitrate_switching_dec( ivas_output_init( &( st_ivas->hIntSetup ), st_ivas->hDecoderConfig->output_config ); } +#ifndef NONBE_UNIFIED_DECODING_PATHS + if ( st_ivas->hDecoderConfig->Opt_5ms ) +#endif { /* transfer subframe info from DirAC or ParamMC to central tc buffer */ if ( last_ism_mode == ISM_MODE_PARAM && st_ivas->hSpatParamRendCom != NULL && ( st_ivas->renderer_type != RENDERER_MONO_DOWNMIX && st_ivas->renderer_type != RENDERER_DISABLE ) ) @@ -137,7 +148,11 @@ static ivas_error ivas_ism_bitrate_switching_dec( if ( tc_granularity_new < st_ivas->hTcBuffer->n_samples_granularity ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( error = ivas_jbm_dec_flush_renderer( st_ivas, tc_granularity_new, renderer_type_old, intern_config_old, &hIntSetupOld, MC_MODE_NONE, last_ism_mode, nSamplesRendered, pcm_resolution, data ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_jbm_dec_flush_renderer( st_ivas, tc_granularity_new, renderer_type_old, intern_config_old, &hIntSetupOld, MC_MODE_NONE, last_ism_mode, nSamplesRendered, data ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -169,10 +184,17 @@ static ivas_error ivas_ism_bitrate_switching_dec( ivas_param_ism_dec_close( &( st_ivas->hParamIsmDec ), &( st_ivas->hSpatParamRendCom ), st_ivas->hDecoderConfig->output_config ); if ( st_ivas->hOutSetup.output_config == IVAS_AUDIO_CONFIG_BINAURAL || st_ivas->hOutSetup.output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB +#ifdef SPLIT_REND_WITH_HEAD_ROT + || st_ivas->hOutSetup.output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hOutSetup.output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM +#endif ) { /* close the parametric binaural renderer */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + ivas_dirac_dec_close_binaural_data( st_ivas->hDiracDecBin ); +#else ivas_dirac_dec_close_binaural_data( &st_ivas->hDiracDecBin ); +#endif /* Open the TD Binaural renderer */ if ( st_ivas->hHrtfTD == NULL || st_ivas->hBinRendererTd == NULL ) { @@ -203,10 +225,18 @@ static ivas_error ivas_ism_bitrate_switching_dec( if ( st_ivas->hOutSetup.output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) { /* close the parametric binaural renderer */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + ivas_dirac_dec_close_binaural_data( st_ivas->hDiracDecBin ); +#else ivas_dirac_dec_close_binaural_data( &st_ivas->hDiracDecBin ); +#endif /* Open Crend Binaural renderer */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( error = ivas_rend_openCrend( &( st_ivas->hCrendWrapper ), st_ivas->intern_config, st_ivas->hOutSetup.output_config, st_ivas->hRenderConfig, st_ivas->hSetOfHRTF, st_ivas->hDecoderConfig->output_Fs, st_ivas->hSplitBinRend.splitrend.multiBinPoseData.num_poses ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_rend_openCrend( &( st_ivas->hCrendWrapper ), st_ivas->intern_config, st_ivas->hOutSetup.output_config, st_ivas->hRenderConfig, st_ivas->hSetOfHRTF, st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -225,6 +255,9 @@ static ivas_error ivas_ism_bitrate_switching_dec( } if ( st_ivas->hOutSetup.output_config == IVAS_AUDIO_CONFIG_BINAURAL || st_ivas->hOutSetup.output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB +#ifdef SPLIT_REND_WITH_HEAD_ROT + || st_ivas->hOutSetup.output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hOutSetup.output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM +#endif ) { /* open the parametric binaural renderer */ @@ -270,7 +303,11 @@ static ivas_error ivas_ism_bitrate_switching_dec( } /* close the crend binaural renderer */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + ivas_rend_closeCrend( &( st_ivas->hCrendWrapper ), st_ivas->hSplitBinRend.splitrend.multiBinPoseData.num_poses ); +#else ivas_rend_closeCrend( &( st_ivas->hCrendWrapper ) ); +#endif } } @@ -287,6 +324,9 @@ static ivas_error ivas_ism_bitrate_switching_dec( * floating-point output audio buffers *-----------------------------------------------------------------*/ +#ifndef NONBE_UNIFIED_DECODING_PATHS + if ( !st_ivas->hDecoderConfig->Opt_5ms ) +#endif { nchan_out_buff = ivas_get_nchan_buffers_dec( st_ivas, -1, -1 ); @@ -299,6 +339,9 @@ static ivas_error ivas_ism_bitrate_switching_dec( /*-----------------------------------------------------------------* * JBM TC buffers *-----------------------------------------------------------------*/ +#ifndef NONBE_UNIFIED_DECODING_PATHS + if ( st_ivas->hDecoderConfig->Opt_5ms ) +#endif { int16_t tc_nchan_full_new; DECODER_TC_BUFFER_HANDLE hTcBuffer; @@ -357,7 +400,12 @@ ivas_error ivas_ism_dec_config( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ const ISM_MODE last_ism_mode, /* i/o: last ISM mode */ uint16_t *nSamplesRendered, /* o : number of samples flushed when the renderer granularity changes */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + const PCM_RESOLUTION pcm_resolution, /* i : type for the decoded PCM resolution */ + void *data /* o : output synthesis signal */ +#else int16_t *data /* o : output synthesis signal */ +#endif ) { int32_t ivas_total_brate; @@ -397,6 +445,9 @@ ivas_error ivas_ism_dec_config( if ( ( st_ivas->ism_mode != last_ism_mode ) || ( st_ivas->hDecoderConfig->ivas_total_brate != st_ivas->hDecoderConfig->last_ivas_total_brate ) ) { if ( ( error = ivas_ism_bitrate_switching_dec( st_ivas, nchan_transport_old, last_ism_mode, nSamplesRendered, +#ifdef SPLIT_REND_WITH_HEAD_ROT + pcm_resolution, +#endif data ) ) != IVAS_ERR_OK ) { return error; @@ -421,6 +472,9 @@ ivas_error ivas_ism_dec_config( if ( st_ivas->ism_mode != last_ism_mode ) { if ( ( error = ivas_ism_bitrate_switching_dec( st_ivas, nchan_transport_old, last_ism_mode, nSamplesRendered, +#ifdef SPLIT_REND_WITH_HEAD_ROT + pcm_resolution, +#endif data ) ) != IVAS_ERR_OK ) { return error; diff --git a/lib_dec/ivas_ism_dtx_dec.c b/lib_dec/ivas_ism_dtx_dec.c index 998dc97ee..1c53749d7 100644 --- a/lib_dec/ivas_ism_dtx_dec.c +++ b/lib_dec/ivas_ism_dtx_dec.c @@ -35,6 +35,9 @@ #include "options.h" #include "ivas_prot.h" #include "prot.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" @@ -44,15 +47,29 @@ * ISM DTX Metadata decoding routine *-------------------------------------------------------------------*/ +#ifdef NONBE_FIX_898_ISM_BRATE_CRASH void ivas_ism_dtx_dec( +#else +ivas_error ivas_ism_dtx_dec( +#endif Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ int16_t *nb_bits_metadata /* o : number of metadata bits */ ) { +#ifdef NONBE_FIX_898_ISM_BRATE_CRASH int16_t ch, nchan_ism, nchan_ism_prev; +#else + int16_t ch, pos, nchan_ism, nchan_ism_prev; +#endif int32_t ivas_total_brate; int16_t md_diff_flag[MAX_NUM_OBJECTS]; +#ifdef NONBE_FIX_898_ISM_BRATE_CRASH int16_t flag_noisy_speech, sce_id_dtx; +#else + int16_t idx, flag_noisy_speech, sce_id_dtx; + ISM_MODE last_ism_mode, ism_mode_bstr; + ivas_error error; +#endif Decoder_State *st; ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate; @@ -62,10 +79,50 @@ void ivas_ism_dtx_dec( if ( !st_ivas->bfi && ivas_total_brate == IVAS_SID_5k2 ) { +#ifdef NONBE_FIX_898_ISM_BRATE_CRASH /* 'nchan_ism' was read in ivas_dec_setup() */ nchan_ism = st_ivas->nchan_ism; /* ism_mode was read in ivas_dec_setup() as well as reconfiguration ivas_ism_dec_config() */ +#else + /* read number of objects */ + nchan_ism = 1; + pos = (int16_t) ( ( ivas_total_brate / FRAMES_PER_SEC ) - 1 - SID_FORMAT_NBITS ); + + while ( get_indice( st_ivas->hSCE[0]->hCoreCoder[0], pos, 1 ) == 1 && nchan_ism < MAX_NUM_OBJECTS ) + { + ( nchan_ism )++; + pos--; + } + st_ivas->nchan_ism = nchan_ism; + pos--; + + if ( nchan_ism != nchan_ism_prev ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "wrong number of objects signalled!" ); + } + + last_ism_mode = st_ivas->ism_mode; + + /* read ism_mode */ + if ( nchan_ism > 2 ) + { + pos -= nchan_ism; /* SID metadata flags */ + + idx = get_indice( st_ivas->hSCE[0]->hCoreCoder[0], pos, 1 ); + ism_mode_bstr = (ISM_MODE) ( idx + 1 ); + st_ivas->ism_mode = ism_mode_bstr; + } + +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( error = ivas_ism_dec_config( st_ivas, last_ism_mode, NULL, PCM_NOT_KNOW, NULL ) ) != IVAS_ERR_OK ) +#else + if ( ( error = ivas_ism_dec_config( st_ivas, last_ism_mode, NULL, NULL ) ) != IVAS_ERR_OK ) +#endif + { + return error; + } +#endif } else { @@ -97,6 +154,7 @@ void ivas_ism_dtx_dec( } } +#ifdef NONBE_FIX_DISCRETE_ISM_NOISE_SEED_HANDLING /* synch common seed between SCEs */ if ( st_ivas->ism_mode == ISM_MODE_DISC ) { @@ -105,6 +163,7 @@ void ivas_ism_dtx_dec( st_ivas->hSCE[ch]->hCoreCoder[0]->hFdCngDec->hFdCngCom->seed = st_ivas->hSCE[st_ivas->hISMDTX.sce_id_dtx]->hCoreCoder[0]->hFdCngDec->hFdCngCom->seed; } } +#endif update_last_metadata( nchan_ism, st_ivas->hIsmMetaData, md_diff_flag ); @@ -130,7 +189,11 @@ void ivas_ism_dtx_dec( } } +#ifdef NONBE_FIX_898_ISM_BRATE_CRASH return; +#else + return IVAS_ERR_OK; +#endif } diff --git a/lib_dec/ivas_ism_metadata_dec.c b/lib_dec/ivas_ism_metadata_dec.c index c4b07078d..bde79fcb5 100644 --- a/lib_dec/ivas_ism_metadata_dec.c +++ b/lib_dec/ivas_ism_metadata_dec.c @@ -38,6 +38,9 @@ #include "prot.h" #include "ivas_stat_enc.h" #include +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" diff --git a/lib_dec/ivas_ism_param_dec.c b/lib_dec/ivas_ism_param_dec.c index 9f48c82e1..d355798f6 100644 --- a/lib_dec/ivas_ism_param_dec.c +++ b/lib_dec/ivas_ism_param_dec.c @@ -39,6 +39,9 @@ #include "prot.h" #include "ivas_rom_com.h" #include "ivas_rom_dec.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" @@ -385,7 +388,11 @@ static ivas_error ivas_param_ism_rendering_init( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for interpolator\n" ) ); } +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( !( output_config == IVAS_AUDIO_CONFIG_EXTERNAL || output_config == IVAS_AUDIO_CONFIG_BINAURAL || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) +#else if ( !( output_config == IVAS_AUDIO_CONFIG_EXTERNAL || output_config == IVAS_AUDIO_CONFIG_BINAURAL || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ) +#endif { /* computation of proto matrix */ ivas_ism_get_proto_matrix( hOutSetup, nchan_transport, hParamIsmRendering->proto_matrix ); @@ -538,8 +545,13 @@ ivas_error ivas_param_ism_dec_open( } } +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( !( output_config == IVAS_AUDIO_CONFIG_EXTERNAL || output_config == IVAS_AUDIO_CONFIG_BINAURAL || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB || + output_config == IVAS_AUDIO_CONFIG_MONO || output_config == IVAS_AUDIO_CONFIG_STEREO || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) +#else if ( !( output_config == IVAS_AUDIO_CONFIG_EXTERNAL || output_config == IVAS_AUDIO_CONFIG_BINAURAL || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB || output_config == IVAS_AUDIO_CONFIG_MONO || output_config == IVAS_AUDIO_CONFIG_STEREO ) ) +#endif { /* Initialize efap handle */ if ( ( error = efap_init_data( &( st_ivas->hEFAPdata ), hOutSetup.ls_azimuth, hOutSetup.ls_elevation, hOutSetup.nchan_out_woLFE, EFAP_MODE_EFAP ) ) != IVAS_ERR_OK ) @@ -556,7 +568,11 @@ ivas_error ivas_param_ism_dec_open( hSpatParamRendCom->dirac_bs_md_write_idx = 0; hSpatParamRendCom->dirac_read_idx = 0; +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) +#else if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) +#endif { if ( ( error = ivas_dirac_allocate_parameters( hSpatParamRendCom, 1 ) ) != IVAS_ERR_OK ) { @@ -575,6 +591,10 @@ ivas_error ivas_param_ism_dec_open( st_ivas->hSpatParamRendCom = hSpatParamRendCom; +#ifndef NONBE_UNIFIED_DECODING_PATHS + if ( st_ivas->hDecoderConfig->Opt_5ms ) + { +#endif if ( st_ivas->renderer_type != RENDERER_MONO_DOWNMIX && st_ivas->renderer_type != RENDERER_DISABLE ) { int16_t nchan_transport = st_ivas->nchan_transport; @@ -632,6 +652,14 @@ ivas_error ivas_param_ism_dec_open( } } } +#ifndef NONBE_UNIFIED_DECODING_PATHS + } + else + { + hParamIsmDec->hParamIsmRendering->Cldfb_RealBuffer_tc = NULL; + hParamIsmDec->hParamIsmRendering->Cldfb_ImagBuffer_tc = NULL; + } +#endif pop_wmops(); return error; @@ -1183,7 +1211,11 @@ void ivas_param_ism_dec_digest_tc( } } +#ifndef NONBE_UNIFIED_DECODING_PATHS + if ( st_ivas->hDecoderConfig->Opt_tsm || !st_ivas->hDecoderConfig->Opt_5ms ) +#else if ( st_ivas->hDecoderConfig->Opt_tsm ) +#endif { /*TODO : FhG to check*/ ivas_ism_param_dec_tc_gain_ajust( st_ivas, output_frame, fade_len, transport_channels_f ); @@ -1194,7 +1226,11 @@ void ivas_param_ism_dec_digest_tc( /* CLDFB Analysis */ for ( slot_idx = 0; slot_idx < nCldfbSlots; slot_idx++ ) { +#ifndef NONBE_UNIFIED_DECODING_PATHS + if ( st_ivas->hDecoderConfig->Opt_tsm || !st_ivas->hDecoderConfig->Opt_5ms ) +#else if ( st_ivas->hDecoderConfig->Opt_tsm ) +#endif { float RealBuffer[CLDFB_NO_CHANNELS_MAX]; @@ -1405,6 +1441,10 @@ void ivas_param_ism_dec_render( hParamIsmDec = st_ivas->hParamIsmDec; hSpatParamRendCom = st_ivas->hSpatParamRendCom; hSetup = st_ivas->hIntSetup; +#ifdef DEBUGGING + assert( hParamIsmDec ); + assert( hSpatParamRendCom ); +#endif nchan_transport = st_ivas->nchan_transport; if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_EXTERNAL ) { @@ -1430,6 +1470,9 @@ void ivas_param_ism_dec_render( slots_to_render -= hSpatParamRendCom->subframe_nbslots[last_sf]; last_sf++; } +#ifdef DEBUGGING + assert( slots_to_render == 0 ); +#endif for ( ch = 0; ch < nchan_out; ch++ ) { diff --git a/lib_dec/ivas_ism_renderer.c b/lib_dec/ivas_ism_renderer.c index 767144ddb..63c8f47d2 100644 --- a/lib_dec/ivas_ism_renderer.c +++ b/lib_dec/ivas_ism_renderer.c @@ -40,6 +40,9 @@ #include "ivas_rom_com.h" #include "ivas_rom_dec.h" #include +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" @@ -129,6 +132,108 @@ void ivas_ism_renderer_close( return; } +#ifndef NONBE_UNIFIED_DECODING_PATHS +/*-------------------------------------------------------------------------* + * ivas_ism_render() + * + * Object rendering process. + *-------------------------------------------------------------------------*/ + +void ivas_ism_render( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + float *output_f[], /* i/o: core-coder transport channels/object output */ + const int16_t output_frame /* i : output frame length per channel */ +) +{ + int16_t i, j, k, j2; + float input_f[MAX_NUM_OBJECTS][L_FRAME48k]; + float tmp_output_f[MAX_OUTPUT_CHANNELS][L_FRAME48k]; + float gains[MAX_NUM_OBJECTS][MAX_OUTPUT_CHANNELS]; + float g1, g2; + int16_t nchan_ism, nchan_out_woLFE, lfe_index; + int16_t azimuth, elevation; + + nchan_ism = st_ivas->nchan_ism; + nchan_out_woLFE = st_ivas->hIntSetup.nchan_out_woLFE; + + lfe_index = 0; + + for ( j = 0; j < nchan_out_woLFE; j++ ) + { + set_f( tmp_output_f[j], 0.0f, output_frame ); + } + + for ( i = 0; i < nchan_ism; i++ ) + { + mvr2r( output_f[i], input_f[i], output_frame ); + } + + for ( i = 0; i < nchan_out_woLFE + st_ivas->hIntSetup.num_lfe; i++ ) + { + set_f( output_f[i], 0.0f, output_frame ); + } + + for ( i = 0; i < nchan_ism; i++ ) + { + if ( st_ivas->intern_config == IVAS_AUDIO_CONFIG_STEREO ) + { + ivas_ism_get_stereo_gains( st_ivas->hIsmMetaData[i]->azimuth, st_ivas->hIsmMetaData[i]->elevation, &gains[i][0], &gains[i][1] ); + } + else + { + /* Combined rotation: rotate the object positions depending the head and external orientations */ + if ( st_ivas->hCombinedOrientationData != NULL && st_ivas->hCombinedOrientationData->enableCombinedOrientation[0] == 1 ) + { + rotateAziEle( st_ivas->hIsmMetaData[i]->azimuth, st_ivas->hIsmMetaData[i]->elevation, &azimuth, &elevation, st_ivas->hCombinedOrientationData->Rmat[0], st_ivas->hIntSetup.is_planar_setup ); + } + else + { + // TODO tmu review when #215 is resolved + azimuth = (int16_t) floorf( st_ivas->hIsmMetaData[i]->azimuth + 0.5f ); + elevation = (int16_t) floorf( st_ivas->hIsmMetaData[i]->elevation + 0.5f ); + + if ( st_ivas->hIntSetup.is_planar_setup ) + { + /* If no elevation support in output format, then rendering should be done with zero elevation */ + elevation = 0; + } + } + + if ( st_ivas->hEFAPdata != NULL ) + { + efap_determine_gains( st_ivas->hEFAPdata, gains[i], azimuth, elevation, EFAP_MODE_EFAP ); + } + } + + for ( j = 0; j < nchan_out_woLFE; j++ ) + { + if ( fabsf( gains[i][j] ) > 0.0f || fabsf( st_ivas->hIsmRendererData->prev_gains[i][j] ) > 0.0f ) + { + for ( k = 0; k < output_frame; k++ ) + { + g1 = st_ivas->hIsmRendererData->interpolator[k]; + g2 = 1.0f - g1; + tmp_output_f[j][k] += ( g1 * gains[i][j] + g2 * st_ivas->hIsmRendererData->prev_gains[i][j] ) * input_f[i][k]; + } + } + + st_ivas->hIsmRendererData->prev_gains[i][j] = gains[i][j]; + } + } + + /* Move to output skipping LFE */ + for ( j = 0, j2 = 0; j < nchan_out_woLFE; j++, j2++ ) + { + if ( ( st_ivas->hIntSetup.num_lfe > 0 ) && ( st_ivas->hIntSetup.index_lfe[lfe_index] == j ) ) + { + ( lfe_index < ( st_ivas->hIntSetup.num_lfe - 1 ) ) ? ( lfe_index++, j2++ ) : j2++; + } + mvr2r( tmp_output_f[j], output_f[j2], output_frame ); + } + + return; +} +#endif /*-------------------------------------------------------------------------* * ivas_ism_render_sf() @@ -149,8 +254,10 @@ void ivas_ism_render_sf( int16_t tc_offset; int16_t interp_offset; float gain, prev_gain; +#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX float tc_local[MAX_NUM_OBJECTS][L_FRAME48k]; float *p_tc[MAX_NUM_OBJECTS]; +#endif num_objects = st_ivas->nchan_transport; if ( st_ivas->ivas_format == SBA_ISM_FORMAT ) @@ -163,6 +270,7 @@ void ivas_ism_render_sf( tc_offset = st_ivas->hTcBuffer->n_samples_rendered; interp_offset = st_ivas->hTcBuffer->n_samples_rendered; +#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX if ( st_ivas->hDecoderConfig->Opt_tsm ) { for ( i = 0; i < num_objects; i++ ) @@ -178,13 +286,18 @@ void ivas_ism_render_sf( p_tc[i] = tc_local[i]; } } +#endif for ( i = 0; i < nchan_out_woLFE + st_ivas->hIntSetup.num_lfe; i++ ) { set_f( output_f[i], 0.0f, n_samples_to_render ); } +#ifdef NONBE_UNIFIED_DECODING_PATHS if ( st_ivas->hCombinedOrientationData && st_ivas->hCombinedOrientationData->enableCombinedOrientation[st_ivas->hCombinedOrientationData->subframe_idx] == 1 ) +#else + if ( st_ivas->hCombinedOrientationData && st_ivas->hCombinedOrientationData->enableCombinedOrientation[0] ) +#endif { ivas_jbm_dec_get_adapted_linear_interpolator( n_samples_to_render, n_samples_to_render, st_ivas->hIsmRendererData->interpolator ); interp_offset = 0; @@ -193,7 +306,11 @@ void ivas_ism_render_sf( for ( i = 0; i < num_objects; i++ ) { /* Combined rotation: rotate the object positions depending the head and external orientations */ +#ifdef NONBE_UNIFIED_DECODING_PATHS if ( st_ivas->hCombinedOrientationData != NULL && st_ivas->hCombinedOrientationData->enableCombinedOrientation[st_ivas->hCombinedOrientationData->subframe_idx] == 1 ) +#else + if ( st_ivas->hCombinedOrientationData != NULL && st_ivas->hCombinedOrientationData->enableCombinedOrientation[0] == 1 ) +#endif { rotateAziEle( st_ivas->hIsmMetaData[i]->azimuth, st_ivas->hIsmMetaData[i]->elevation, &azimuth, &elevation, st_ivas->hCombinedOrientationData->Rmat[0], st_ivas->hIntSetup.is_planar_setup ); @@ -216,7 +333,11 @@ void ivas_ism_render_sf( if ( fabsf( gain ) > 0.0f || fabsf( prev_gain ) > 0.0f ) { g1 = &st_ivas->hIsmRendererData->interpolator[interp_offset]; +#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX tc = p_tc[i]; +#else + tc = &st_ivas->hTcBuffer->tc[i][tc_offset]; +#endif for ( k = 0; k < n_samples_to_render; k++ ) { g2 = 1.0f - *g1; @@ -225,15 +346,21 @@ void ivas_ism_render_sf( } /* update here only in case of head rotation */ +#ifdef NONBE_UNIFIED_DECODING_PATHS if ( st_ivas->hCombinedOrientationData != NULL && st_ivas->hCombinedOrientationData->enableCombinedOrientation[st_ivas->hCombinedOrientationData->subframe_idx] == 1 ) +#else + if ( st_ivas->hCombinedOrientationData != NULL && st_ivas->hCombinedOrientationData->enableCombinedOrientation[0] == 1 ) +#endif { st_ivas->hIsmRendererData->prev_gains[i][j] = gain; } } } +#ifdef NONBE_UNIFIED_DECODING_PATHS /* update combined orientation access index */ ivas_combined_orientation_update_index( st_ivas->hCombinedOrientationData, n_samples_to_render ); +#endif return; } @@ -385,6 +512,118 @@ void ivas_omasa_separate_object_renderer_close( return; } +#ifndef NONBE_UNIFIED_DECODING_PATHS_FIX +/*-------------------------------------------------------------------------* + * ivas_omasa_separate_object_render() + * + * Rendering separated objects and mixing them to the parametrically rendered signals + *-------------------------------------------------------------------------*/ + +void ivas_omasa_separate_object_render( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + float input_f[][L_FRAME48k], /* i : separated object signal */ + float *output_f[], /* i/o: output signals */ + const int16_t output_frame /* i : output frame length per channel */ +) +{ + VBAP_HANDLE hVBAPdata; + int16_t nchan_out_woLFE; + ISM_RENDERER_HANDLE hRendererData; + int16_t j, k, j2; + int16_t obj; + float gains[MAX_OUTPUT_CHANNELS]; + float g1, g2; + int16_t lfe_index; + int16_t azimuth, elevation; + int16_t num_objects; + uint8_t single_separated; + int16_t block; + int16_t subframe_len; + int16_t idx_offset; + int16_t dirac_read_idx; + + hVBAPdata = st_ivas->hVBAPdata; + nchan_out_woLFE = st_ivas->hIntSetup.nchan_out_woLFE; + hRendererData = st_ivas->hIsmRendererData; + lfe_index = st_ivas->hDirACRend->hOutSetup.index_lfe[0]; + subframe_len = output_frame / MAX_PARAM_SPATIAL_SUBFRAMES; + + if ( st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ ) + { + single_separated = 1; + num_objects = 1; + } + else + { + single_separated = 0; + num_objects = st_ivas->nchan_ism; + } + + for ( obj = 0; obj < num_objects; obj++ ) + { + delay_signal( input_f[obj], output_frame, st_ivas->hMasaIsmData->delayBuffer[obj], st_ivas->hMasaIsmData->delayBuffer_size ); /* Delay the signal to match CLDFB delay */ + + for ( block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; block++ ) + { + idx_offset = block * subframe_len; + dirac_read_idx = ( st_ivas->hSpatParamRendCom->dirac_read_idx + block ) % st_ivas->hSpatParamRendCom->dirac_md_buffer_length; + + if ( single_separated ) + { + azimuth = st_ivas->hMasaIsmData->azimuth_separated_ism[dirac_read_idx]; + elevation = st_ivas->hMasaIsmData->elevation_separated_ism[dirac_read_idx]; + } + else + { + azimuth = st_ivas->hMasaIsmData->azimuth_ism[obj][dirac_read_idx]; + elevation = st_ivas->hMasaIsmData->elevation_ism[obj][dirac_read_idx]; + } + + if ( st_ivas->hOutSetup.is_planar_setup ) + { + /* If no elevation support in output format, then rendering should be done with zero elevation */ + elevation = 0; + } + + if ( hVBAPdata != NULL ) + { + vbap_determine_gains( hVBAPdata, gains, azimuth, elevation, 1 ); + } + else + { + ivas_dirac_dec_get_response( azimuth, elevation, gains, st_ivas->hDirACRend->hOutSetup.ambisonics_order ); + } + + for ( j = 0; j < nchan_out_woLFE; j++ ) + { + if ( st_ivas->hDirACRend->hOutSetup.num_lfe > 0 ) + { + j2 = j + ( j >= lfe_index ); + } + else + { + j2 = j; + } + + if ( fabsf( gains[j] ) > 0.0f || fabsf( hRendererData->prev_gains[obj][j] ) > 0.0f ) + { + for ( k = 0; k < subframe_len; k++ ) + { + g1 = hRendererData->interpolator[k]; + g2 = 1.0f - g1; + output_f[j2][k + idx_offset] += ( g1 * gains[j] + g2 * hRendererData->prev_gains[obj][j] ) * input_f[obj][k + idx_offset]; + } + } + hRendererData->prev_gains[obj][j] = gains[j]; + } + } + } + + st_ivas->hSpatParamRendCom->dirac_read_idx = ( st_ivas->hSpatParamRendCom->dirac_read_idx + MAX_PARAM_SPATIAL_SUBFRAMES ) % st_ivas->hSpatParamRendCom->dirac_md_buffer_length; + + return; +} +#endif /*-------------------------------------------------------------------------* * ivas_omasa_separate_object_render_jbm() @@ -395,7 +634,9 @@ void ivas_omasa_separate_object_renderer_close( void ivas_omasa_separate_object_render_jbm( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ const uint16_t nSamplesRendered, /* i : number of samples rendered */ +#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX float input_f_in[][L_FRAME48k], /* i : separated object signal */ +#endif float *output_f[], /* o : rendered time signal */ const int16_t subframes_rendered, /* i : number of subframes rendered */ const int16_t slots_rendered /* i : number of CLDFB slots rendered */ @@ -446,12 +687,15 @@ void ivas_omasa_separate_object_render_jbm( output_f_local[j] = output_f[j]; } +#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX if ( st_ivas->hDecoderConfig->Opt_tsm ) { +#endif for ( obj = 0; obj < num_objects; obj++ ) { input_f[obj] = &st_ivas->hTcBuffer->tc[obj + 2][offsetSamples]; } +#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX } else { @@ -460,6 +704,7 @@ void ivas_omasa_separate_object_render_jbm( input_f[obj] = input_f_in[obj]; } } +#endif slots_to_render = nSamplesRendered / hSpatParamRendCom->slot_size; first_sf = subframes_rendered; diff --git a/lib_dec/ivas_jbm_dec.c b/lib_dec/ivas_jbm_dec.c index 8673c8259..f5b5d5d08 100644 --- a/lib_dec/ivas_jbm_dec.c +++ b/lib_dec/ivas_jbm_dec.c @@ -40,6 +40,9 @@ #include "ivas_prot_rend.h" #include "ivas_rom_com.h" #include +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" @@ -70,6 +73,9 @@ ivas_error ivas_jbm_dec_tc( int16_t n, output_frame, nchan_out; Decoder_State *st; /* used for bitstream handling */ float *p_output[MAX_TRANSPORT_CHANNELS]; /* 'float' buffer for output synthesis */ +#ifndef NONBE_UNIFIED_DECODING_PATHS_FIX + float output_f[MAX_TRANSPORT_CHANNELS][L_FRAME48k]; /* TODO: can be allocated dynamically using st_ivas->p_output_f */ +#endif int16_t nchan_remapped; int16_t nb_bits_metadata[MAX_SCE + 1]; int32_t output_Fs, ivas_total_brate; @@ -93,13 +99,18 @@ ivas_error ivas_jbm_dec_tc( for ( n = 0; n < MAX_TRANSPORT_CHANNELS; n++ ) { +#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX p_output[n] = st_ivas->p_output_f[n]; if ( p_output[n] != NULL ) { set_zero( p_output[n], L_FRAME48k ); } +#else + p_output[n] = output_f[n]; +#endif } +#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX if ( !st_ivas->hDecoderConfig->Opt_tsm ) { for ( n = 0; n < ivas_get_nchan_buffers_dec( st_ivas, st_ivas->sba_analysis_order, st_ivas->hDecoderConfig->ivas_total_brate ); n++ ) @@ -108,6 +119,7 @@ ivas_error ivas_jbm_dec_tc( } } +#endif /*----------------------------------------------------------------* * Decoding + pre-rendering *----------------------------------------------------------------*/ @@ -120,6 +132,12 @@ ivas_error ivas_jbm_dec_tc( set_f( p_output[n], 0.0f, output_frame ); } +#ifdef DEBUG_MODE_INFO + create_sce_dec( st_ivas, 0, ivas_total_brate ); + output_debug_mode_info_dec( st_ivas->hSCE[0]->hCoreCoder, 1, output_frame, NULL ); + destroy_sce_dec( st_ivas->hSCE[0] ); + st_ivas->hSCE[0] = NULL; +#endif } else if ( st_ivas->ivas_format == STEREO_FORMAT ) { @@ -145,7 +163,14 @@ ivas_error ivas_jbm_dec_tc( /* Metadata decoding and configuration */ if ( ivas_total_brate == IVAS_SID_5k2 || ivas_total_brate == FRAME_NO_DATA ) { +#ifdef NONBE_FIX_898_ISM_BRATE_CRASH ivas_ism_dtx_dec( st_ivas, nb_bits_metadata ); +#else + if ( ( error = ivas_ism_dtx_dec( st_ivas, nb_bits_metadata ) ) != IVAS_ERR_OK ) + { + return error; + } +#endif /* decode dominant object first so the noise energy of the other objects can be limited */ if ( ( error = ivas_sce_dec( st_ivas, st_ivas->hISMDTX.sce_id_dtx, &p_output[st_ivas->hISMDTX.sce_id_dtx], output_frame, nb_bits_metadata[st_ivas->hISMDTX.sce_id_dtx] ) ) != IVAS_ERR_OK ) @@ -252,6 +277,10 @@ ivas_error ivas_jbm_dec_tc( } } +#ifdef DEBUG_SBA_AUDIO_DUMP + /* Dump audio signal after core-decoding */ + ivas_spar_dump_signal_wav( output_frame, NULL, output, st_ivas->nchan_transport, spar_foa_dec_wav[0], "core-decoding" ); +#endif /* TCs remapping */ nchan_remapped = st_ivas->nchan_transport; if ( st_ivas->sba_dirac_stereo_flag ) @@ -278,10 +307,12 @@ ivas_error ivas_jbm_dec_tc( } /* HP filtering */ +#ifndef DEBUG_SPAR_BYPASS_EVS_CODEC for ( n = 0; n < nchan_remapped; n++ ) { hp20( p_output[n], output_frame, st_ivas->mem_hp20_out[n], output_Fs ); } +#endif if ( st_ivas->ivas_format == SBA_FORMAT ) { @@ -465,6 +496,20 @@ ivas_error ivas_jbm_dec_tc( nchan_remapped = ivas_sba_remapTCs( &p_output[sba_ch_idx], st_ivas, output_frame ); +#ifdef DEBUG_OSBA + if ( st_ivas->ism_mode == ISM_SBA_MODE_DISC ) + { + int16_t nchan = st_ivas->nchan_transport + st_ivas->nchan_ism; + for ( int16_t t = 0; t < output_frame; t++ ) + { + for ( int16_t c = 0; c < nchan; c++ ) + { + int16_t val = (int16_t) ( output[c][t] + 0.5f ); + dbgwrite( &val, sizeof( int16_t ), 1, 1, "./res/TC_dec_core_out.raw" ); + } + } + } +#endif if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) { num_md_sub_frames = ivas_get_spar_dec_md_num_subframes( st_ivas->sba_analysis_order, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->last_active_ivas_total_brate ); @@ -686,7 +731,11 @@ ivas_error ivas_jbm_dec_tc( * Write IVAS transport channels *----------------------------------------------------------------*/ +#ifndef NONBE_UNIFIED_DECODING_PATHS + if ( st_ivas->hDecoderConfig->Opt_tsm == 1 || !st_ivas->hDecoderConfig->Opt_5ms ) +#else if ( st_ivas->hDecoderConfig->Opt_tsm == 1 ) +#endif { ivas_syn_output_f( p_output, output_frame, st_ivas->hTcBuffer->nchan_transport_jbm, data ); } @@ -718,6 +767,14 @@ ivas_error ivas_jbm_dec_tc( st_ivas->last_ivas_format = st_ivas->ivas_format; +#ifdef DEBUG_MODE_INFO + dbgwrite( &st_ivas->bfi, sizeof( int16_t ), 1, output_frame, "res/bfi" ); + dbgwrite( &st_ivas->BER_detect, sizeof( int16_t ), 1, output_frame, "res/BER_detect" ); + { + float tmpF = ivas_total_brate / 1000.0f; + dbgwrite( &tmpF, sizeof( float ), 1, output_frame, "res/ivas_total_brate.dec" ); + } +#endif pop_wmops(); return IVAS_ERR_OK; @@ -748,7 +805,11 @@ void ivas_jbm_dec_feed_tc_to_renderer( } +#ifndef NONBE_UNIFIED_DECODING_PATHS + if ( st_ivas->hDecoderConfig->Opt_tsm || !st_ivas->hDecoderConfig->Opt_5ms ) +#else if ( st_ivas->hDecoderConfig->Opt_tsm ) +#endif { ivas_jbm_dec_copy_tc( st_ivas, nSamplesForRendering, nSamplesResidual, data, p_data_f ); } @@ -805,11 +866,18 @@ void ivas_jbm_dec_feed_tc_to_renderer( /* delay the objects here for all renderers where it is needed */ if ( +#ifdef SPLIT_REND_WITH_HEAD_ROT + ( +#endif st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM || st_ivas->renderer_type == RENDERER_OSBA_AMBI || st_ivas->renderer_type == RENDERER_OSBA_LS || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_EXTERNAL +#ifdef SPLIT_REND_WITH_HEAD_ROT + ) && + ( st_ivas->hDecoderConfig->output_config != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED && st_ivas->hDecoderConfig->output_config != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) +#endif ) { for ( n = 0; n < st_ivas->nchan_ism; n++ ) @@ -830,8 +898,10 @@ void ivas_jbm_dec_feed_tc_to_renderer( } else { +#ifdef NONBE_FIX_904_JBM_SBA_RS_FOA ivas_jbm_dec_td_renderers_adapt_subframes( st_ivas ); +#endif ivas_sba_dec_digest_tc( st_ivas, n_render_timeslots, st_ivas->hTcBuffer->n_samples_available ); } } @@ -885,11 +955,19 @@ ivas_error ivas_jbm_dec_render( const uint16_t nSamplesAsked, /* i : number of samples wanted */ uint16_t *nSamplesRendered, /* o : number of samples rendered */ uint16_t *nSamplesAvailableNext, /* o : number of samples still available in the rendering pipeline */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + const PCM_RESOLUTION pcm_resolution, /* i : type for the decoded PCM resolution */ + void *data /* o : output synthesis signal */ +#else int16_t *data /* o : output synthesis signal */ +#endif ) { int16_t n, nchan_out; int16_t nchan_transport; +#ifndef NONBE_UNIFIED_DECODING_PATHS_FIX + float output[MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS][L_FRAME48k]; /* 'float' buffer for output synthesis */ +#endif int16_t nchan_remapped; int32_t output_Fs; AUDIO_CONFIG output_config; @@ -898,6 +976,9 @@ ivas_error ivas_jbm_dec_render( float *p_output[MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS]; float *p_tc[MAX_TRANSPORT_CHANNELS + MAX_NUM_OBJECTS]; SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom; +#ifdef SPLIT_REND_WITH_HEAD_ROT + int16_t nchan_out_syn_output; +#endif push_wmops( "ivas_dec_render" ); /*----------------------------------------------------------------* @@ -913,9 +994,14 @@ ivas_error ivas_jbm_dec_render( for ( n = 0; n < MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS; n++ ) { +#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX p_output[n] = st_ivas->p_output_f[n]; +#else + p_output[n] = &output[n][0]; +#endif } +#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX if ( !st_ivas->hDecoderConfig->Opt_tsm ) { for ( n = 0; n < st_ivas->hTcBuffer->nchan_buffer_full; n++ ) @@ -930,12 +1016,25 @@ ivas_error ivas_jbm_dec_render( } else { +#endif for ( n = 0; n < st_ivas->hTcBuffer->nchan_buffer_full; n++ ) { p_tc[n] = &st_ivas->hTcBuffer->tc[n][st_ivas->hTcBuffer->n_samples_rendered]; } +#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX } +#endif + +#ifndef NONBE_UNIFIED_DECODING_PATHS + /*----------------------------------------------------------------* + * Combine orientations + *----------------------------------------------------------------*/ + if ( ( error = combine_external_and_head_orientations_dec( st_ivas->hHeadTrackData, st_ivas->hExtOrientationData, st_ivas->hCombinedOrientationData ) ) != IVAS_ERR_OK ) + { + return error; + } +#else /*----------------------------------------------------------------* * Update combined orientation access index *----------------------------------------------------------------*/ @@ -947,6 +1046,7 @@ ivas_error ivas_jbm_dec_render( ivas_combined_orientation_set_to_start_index( st_ivas->hCombinedOrientationData ); } +#endif /*----------------------------------------------------------------* * Rendering @@ -1017,18 +1117,46 @@ ivas_error ivas_jbm_dec_render( /* Binaural rendering */ if ( st_ivas->renderer_type == RENDERER_BINAURAL_OBJECTS_TD ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { + if ( ( error = ivas_td_binaural_renderer_sf_splitBinaural( st_ivas, p_output, *nSamplesRendered ) ) != IVAS_ERR_OK ) + { + return error; + } + } + else + { +#endif if ( ( error = ivas_td_binaural_renderer_sf( st_ivas, p_output, *nSamplesRendered ) ) != IVAS_ERR_OK ) { return error; } +#ifdef SPLIT_REND_WITH_HEAD_ROT + } +#endif } else if ( st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV_ROOM ) { +#if ( defined NONBE_UNIFIED_DECODING_PATHS && defined SPLIT_REND_WITH_HEAD_ROT ) + if ( ( error = ivas_rend_crendProcessSubframe( st_ivas->hCrendWrapper, IVAS_AUDIO_CONFIG_7_1_4, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR, st_ivas->hDecoderConfig, NULL, + NULL, NULL, st_ivas->hTcBuffer, p_output, p_output, *nSamplesRendered, output_Fs, 0 ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_rend_crendProcessSubframe( st_ivas->hCrendWrapper, IVAS_AUDIO_CONFIG_7_1_4, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR, st_ivas->hDecoderConfig, NULL, NULL, NULL, st_ivas->hTcBuffer, p_output, p_output, *nSamplesRendered, output_Fs ) ) != IVAS_ERR_OK ) +#endif { return error; } +#ifndef FIX_881_REMOVE_LFE_ADDITION_IN_ISM + ivas_binaural_add_LFE( st_ivas, *nSamplesRendered, p_output, p_output ); +#endif + } +#ifdef DEBUGGING + else if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) + { + ivas_binaural_cldfb_sf( st_ivas, *nSamplesRendered, st_ivas->hTcBuffer->nb_subframes, p_output ); } +#endif } } else if ( st_ivas->ivas_format == SBA_FORMAT || st_ivas->ivas_format == MASA_FORMAT ) @@ -1109,6 +1237,7 @@ ivas_error ivas_jbm_dec_render( { *nSamplesRendered = min( st_ivas->hTcBuffer->n_samples_available, nSamplesAskedLocal ); +#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX /* shift SBA channels to avoid overwrite by ISM upmix in 1 object case and non-TSM unified channel memory*/ if ( st_ivas->nchan_ism == 1 && st_ivas->hDecoderConfig->Opt_tsm == 0 ) { @@ -1117,6 +1246,7 @@ ivas_error ivas_jbm_dec_render( p_tc[1] = p_output[2]; p_tc[2] = p_output[3]; } +#endif /* render objects */ ivas_ism_render_sf( st_ivas, p_output, *nSamplesRendered ); @@ -1129,10 +1259,38 @@ ivas_error ivas_jbm_dec_render( } else if ( st_ivas->renderer_type == RENDERER_OSBA_AMBI || st_ivas->renderer_type == RENDERER_OSBA_LS || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) { +#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX if ( ( error = ivas_osba_render_sf( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output ) ) != IVAS_ERR_OK ) { return error; } +#else + float output_ism[MAX_OUTPUT_CHANNELS][L_FRAME48k]; + float *p_output_ism[MAX_OUTPUT_CHANNELS]; + + for ( n = 0; n < MAX_OUTPUT_CHANNELS; n++ ) + { + p_output_ism[n] = &output_ism[n][0]; + } + + if ( ( error = ivas_sba_dec_render( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( st_ivas->renderer_type != RENDERER_BINAURAL_FASTCONV_ROOM ) + { + ivas_ism_render_sf( st_ivas, p_output_ism, *nSamplesRendered ); + } + for ( n = 0; n < nchan_out; n++ ) + { + if ( st_ivas->renderer_type != RENDERER_BINAURAL_FASTCONV_ROOM ) + { + v_add( p_output[n], p_output_ism[n], p_output[n], *nSamplesRendered ); + } + v_multc( p_output[n], 0.5f, p_output[n], *nSamplesRendered ); + } +#endif } else if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_EXTERNAL ) /*EXT output = individual objects + HOA3*/ { @@ -1167,13 +1325,24 @@ ivas_error ivas_jbm_dec_render( if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_EXTERNAL ) { +#ifdef DEBUGGING + assert( st_ivas->ism_mode == ISM_MODE_NONE ); +#endif for ( n = st_ivas->hIntSetup.nchan_out_woLFE - 1; n >= 0; n-- ) { +#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX mvr2r( p_output[n], p_output[n + st_ivas->nchan_ism], *nSamplesRendered ); +#else + mvr2r( output[n], output[n + st_ivas->nchan_ism], *nSamplesRendered ); +#endif } for ( n = 0; n < st_ivas->nchan_ism; n++ ) { +#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX set_zero( p_output[n], *nSamplesRendered ); +#else + set_zero( output[n], *nSamplesRendered ); +#endif } } } @@ -1196,16 +1365,36 @@ ivas_error ivas_jbm_dec_render( /* Rendering */ if ( st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV || st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV_ROOM ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { + if ( ( error = ivas_rend_crendProcessSubframesSplitBin( st_ivas->hCrendWrapper, st_ivas->intern_config, st_ivas->hOutSetup.output_config, &st_ivas->hSplitBinRend.splitrend.multiBinPoseData, st_ivas->hDecoderConfig, st_ivas->hCombinedOrientationData, + &st_ivas->hIntSetup, st_ivas->hEFAPdata, st_ivas->hTcBuffer, crendInPlaceRotation ? p_output : p_tc, p_output, *nSamplesRendered, output_Fs ) ) != IVAS_ERR_OK ) + { + return error; + } + } + else + { +#endif +#if ( defined NONBE_UNIFIED_DECODING_PATHS && defined SPLIT_REND_WITH_HEAD_ROT ) + if ( ( error = ivas_rend_crendProcessSubframe( st_ivas->hCrendWrapper, st_ivas->intern_config, st_ivas->hOutSetup.output_config, st_ivas->hDecoderConfig, st_ivas->hCombinedOrientationData, + &st_ivas->hIntSetup, st_ivas->hEFAPdata, st_ivas->hTcBuffer, crendInPlaceRotation ? p_output : p_tc, p_output, *nSamplesRendered, output_Fs, 0 ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_rend_crendProcessSubframe( st_ivas->hCrendWrapper, st_ivas->intern_config, st_ivas->hOutSetup.output_config, st_ivas->hDecoderConfig, st_ivas->hCombinedOrientationData, &st_ivas->hIntSetup, st_ivas->hEFAPdata, st_ivas->hTcBuffer, crendInPlaceRotation ? p_output : p_tc, p_output, *nSamplesRendered, output_Fs ) ) != IVAS_ERR_OK ) +#endif { return error; } ivas_binaural_add_LFE( st_ivas, *nSamplesRendered, p_tc, p_output ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + } +#endif } else if ( st_ivas->renderer_type == RENDERER_MC ) { @@ -1218,12 +1407,26 @@ ivas_error ivas_jbm_dec_render( } else if ( st_ivas->renderer_type == RENDERER_BINAURAL_OBJECTS_TD ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { + if ( ( error = ivas_td_binaural_renderer_sf_splitBinaural( st_ivas, p_output, *nSamplesRendered ) ) != IVAS_ERR_OK ) + { + return error; + } + } + else + { +#endif if ( ( error = ivas_td_binaural_renderer_sf( st_ivas, p_output, *nSamplesRendered ) ) != IVAS_ERR_OK ) { return error; } ivas_binaural_add_LFE( st_ivas, *nSamplesRendered, p_tc, p_output ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + } +#endif } } else if ( st_ivas->mc_mode == MC_MODE_PARAMUPMIX ) @@ -1234,6 +1437,10 @@ ivas_error ivas_jbm_dec_render( /* Rendering */ if ( ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) && !st_ivas->hDecoderConfig->Opt_Headrotation ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + /*handled in CLDFB domain already*/ + if ( output_config != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED && output_config != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) +#endif { ivas_binaural_add_LFE( st_ivas, *nSamplesRendered, p_output, p_output ); } @@ -1248,12 +1455,26 @@ ivas_error ivas_jbm_dec_render( } else if ( st_ivas->renderer_type == RENDERER_BINAURAL_OBJECTS_TD ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { + if ( ( error = ivas_td_binaural_renderer_sf_splitBinaural( st_ivas, p_output, *nSamplesRendered ) ) != IVAS_ERR_OK ) + { + return error; + } + } + else + { +#endif if ( ( error = ivas_td_binaural_renderer( st_ivas, p_output, *nSamplesRendered ) ) != IVAS_ERR_OK ) { return error; } ivas_binaural_add_LFE( st_ivas, *nSamplesRendered, p_output, p_output ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + } +#endif } } else if ( st_ivas->mc_mode == MC_MODE_PARAMMC ) @@ -1278,7 +1499,11 @@ ivas_error ivas_jbm_dec_render( /* we still need to copy the separate channel if available */ if ( st_ivas->hOutSetup.separateChannelEnabled ) { +#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX mvr2r( st_ivas->hTcBuffer->tc[LFE_CHANNEL - 1] + offset, p_output[st_ivas->hOutSetup.separateChannelIndex], *nSamplesRendered ); +#else + mvr2r( st_ivas->hTcBuffer->tc[LFE_CHANNEL - 1] + offset, output[st_ivas->hOutSetup.separateChannelIndex], *nSamplesRendered ); +#endif } ivas_mc2sba( st_ivas->hIntSetup, p_output, p_output, *nSamplesRendered, st_ivas->hOutSetup.ambisonics_order, 0.f ); @@ -1287,7 +1512,11 @@ ivas_error ivas_jbm_dec_render( { for ( n = st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe; n < st_ivas->hOutSetup.nchan_out_woLFE + st_ivas->hOutSetup.num_lfe; n++ ) { +#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX set_zero( p_output[n], *nSamplesRendered ); +#else + set_zero( output[n], *nSamplesRendered ); +#endif } } } @@ -1299,13 +1528,22 @@ ivas_error ivas_jbm_dec_render( output_config == IVAS_AUDIO_CONFIG_5_1_4 || output_config == IVAS_AUDIO_CONFIG_7_1_4 || output_config == IVAS_AUDIO_CONFIG_5_1_2 || ( output_config == IVAS_AUDIO_CONFIG_LS_CUSTOM && st_ivas->hOutSetup.num_lfe > 0 ) ) { +#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX mvr2r( st_ivas->hTcBuffer->tc[LFE_CHANNEL] + offset, p_output[LFE_CHANNEL], *nSamplesRendered ); mvr2r( st_ivas->hTcBuffer->tc[LFE_CHANNEL - 1] + offset, p_output[st_ivas->hOutSetup.separateChannelIndex], *nSamplesRendered ); +#else + mvr2r( st_ivas->hTcBuffer->tc[LFE_CHANNEL] + offset, output[LFE_CHANNEL], *nSamplesRendered ); + mvr2r( st_ivas->hTcBuffer->tc[LFE_CHANNEL - 1] + offset, output[st_ivas->hOutSetup.separateChannelIndex], *nSamplesRendered ); +#endif } else if ( output_config == IVAS_AUDIO_CONFIG_LS_CUSTOM && st_ivas->hOutSetup.num_lfe == 0 ) { /* Delay the separated channel to sync with the DirAC rendering */ +#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX mvr2r( st_ivas->hTcBuffer->tc[LFE_CHANNEL - 1] + offset, p_output[st_ivas->hOutSetup.separateChannelIndex], *nSamplesRendered ); +#else + mvr2r( st_ivas->hTcBuffer->tc[LFE_CHANNEL - 1] + offset, output[st_ivas->hOutSetup.separateChannelIndex], *nSamplesRendered ); +#endif } } } @@ -1320,12 +1558,18 @@ ivas_error ivas_jbm_dec_render( st_ivas->hTcBuffer->n_samples_available -= *nSamplesRendered; st_ivas->hTcBuffer->n_samples_rendered += *nSamplesRendered; +#ifdef NONBE_UNIFIED_DECODING_PATHS /* update global combined orientation start index */ ivas_combined_orientation_update_start_index( st_ivas->hCombinedOrientationData, *nSamplesRendered ); +#endif if ( st_ivas->hTcBuffer->n_samples_discard > 0 ) { +#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX for ( n = 0; n < min( MAX_OUTPUT_CHANNELS, ivas_get_nchan_buffers_dec( st_ivas, st_ivas->sba_analysis_order, st_ivas->hDecoderConfig->ivas_total_brate ) ); n++ ) +#else + for ( n = 0; n < MAX_OUTPUT_CHANNELS; n++ ) +#endif { p_output[n] += st_ivas->hTcBuffer->n_samples_discard; } @@ -1333,6 +1577,18 @@ ivas_error ivas_jbm_dec_render( st_ivas->hTcBuffer->n_samples_discard = 0; } +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { + nchan_out_syn_output = BINAURAL_CHANNELS * st_ivas->hSplitBinRend.splitrend.multiBinPoseData.num_poses; + } + else + { + nchan_out_syn_output = nchan_out; + } + + if ( st_ivas->hDecoderConfig->Opt_Limiter ) +#endif { if ( st_ivas->ivas_format != MONO_FORMAT ) { @@ -1342,8 +1598,30 @@ ivas_error ivas_jbm_dec_render( } } +#ifdef SPLIT_REND_WITH_HEAD_ROT + switch ( pcm_resolution ) + { + case PCM_INT16: +#endif +#ifdef DEBUGGING + st_ivas->noClipping += +#endif +#ifdef SPLIT_REND_WITH_HEAD_ROT + ivas_syn_output( p_output, *nSamplesRendered, nchan_out_syn_output, (int16_t *) data ); +#else ivas_syn_output( p_output, *nSamplesRendered, nchan_out, data ); +#endif +#ifdef SPLIT_REND_WITH_HEAD_ROT + break; + case PCM_FLOAT32: + ivas_syn_output_f( p_output, *nSamplesRendered, nchan_out_syn_output, (float *) data ); + break; + default: + error = IVAS_ERR_UNKNOWN; + break; + } +#endif *nSamplesAvailableNext = st_ivas->hTcBuffer->n_samples_available; @@ -1367,7 +1645,12 @@ ivas_error ivas_jbm_dec_flush_renderer( const MC_MODE mc_mode_old, /* i : old MC mode */ const ISM_MODE ism_mode_old, /* i : old ISM mode */ uint16_t *nSamplesRendered, /* o : number of samples flushed */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + const PCM_RESOLUTION pcm_resolution, /* i : type for the decoded PCM resolution */ + void *data /* o : output synthesis signal */ +#else int16_t *data /* o : output synthesis signal */ +#endif ) { ivas_error error; @@ -1378,10 +1661,12 @@ ivas_error ivas_jbm_dec_flush_renderer( float output[MAX_CICP_CHANNELS][L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES]; float *p_output[MAX_CICP_CHANNELS]; +#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX if ( !st_ivas->hDecoderConfig->Opt_tsm ) { return IVAS_ERR_OK; } +#endif *nSamplesRendered = 0; hTcBuffer = st_ivas->hTcBuffer; @@ -1394,8 +1679,10 @@ ivas_error ivas_jbm_dec_flush_renderer( n_samples_still_available -= n_samples_to_render; assert( n_samples_still_available < tc_granularity_new ); +#ifdef NONBE_UNIFIED_DECODING_PATHS /* update combined orientation access index */ ivas_combined_orientation_set_to_start_index( st_ivas->hCombinedOrientationData ); +#endif if ( n_slots_still_available ) { @@ -1449,11 +1736,19 @@ ivas_error ivas_jbm_dec_flush_renderer( ivas_ism_render_sf( st_ivas, p_output, hTcBuffer->n_samples_granularity ); +#if ( defined NONBE_UNIFIED_DECODING_PATHS && defined SPLIT_REND_WITH_HEAD_ROT ) + if ( ( error = ivas_rend_crendProcessSubframe( st_ivas->hCrendWrapper, IVAS_AUDIO_CONFIG_7_1_4, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR, st_ivas->hDecoderConfig, NULL, + NULL, NULL, st_ivas->hTcBuffer, p_output, p_output, hTcBuffer->n_samples_granularity, st_ivas->hDecoderConfig->output_Fs, 0 ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_rend_crendProcessSubframe( st_ivas->hCrendWrapper, IVAS_AUDIO_CONFIG_7_1_4, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR, st_ivas->hDecoderConfig, NULL, NULL, NULL, st_ivas->hTcBuffer, p_output, p_output, hTcBuffer->n_samples_granularity, st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK ) +#endif { return error; } +#ifndef FIX_881_REMOVE_LFE_ADDITION_IN_ISM + ivas_binaural_add_LFE( st_ivas, hTcBuffer->n_samples_granularity, p_output, p_output ); +#endif } } else @@ -1467,8 +1762,13 @@ ivas_error ivas_jbm_dec_flush_renderer( { if ( renderer_type_old == RENDERER_BINAURAL_MIXER_CONV || renderer_type_old == RENDERER_BINAURAL_MIXER_CONV_ROOM ) { +#if ( defined NONBE_UNIFIED_DECODING_PATHS && defined SPLIT_REND_WITH_HEAD_ROT ) + if ( ( error = ivas_rend_crendProcessSubframe( st_ivas->hCrendWrapper, intern_config_old, st_ivas->hOutSetup.output_config, st_ivas->hDecoderConfig, st_ivas->hCombinedOrientationData, + hIntSetupOld, st_ivas->hEFAPdata, st_ivas->hTcBuffer, hTcBuffer->tc, p_output, hTcBuffer->n_samples_granularity, st_ivas->hDecoderConfig->output_Fs, 0 ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_rend_crendProcessSubframe( st_ivas->hCrendWrapper, intern_config_old, st_ivas->hOutSetup.output_config, st_ivas->hDecoderConfig, st_ivas->hCombinedOrientationData, hIntSetupOld, st_ivas->hEFAPdata, st_ivas->hTcBuffer, hTcBuffer->tc, p_output, hTcBuffer->n_samples_granularity, st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -1529,6 +1829,9 @@ ivas_error ivas_jbm_dec_flush_renderer( last_spar_md_idx = st_ivas->hSpar->render_to_md_map[st_ivas->hSpar->slots_rendered - 1]; last_dirac_md_idx = st_ivas->hSpatParamRendCom->render_to_md_map[st_ivas->hSpatParamRendCom->slots_rendered - 1]; +#ifdef DEBUGGING + assert( ism_mode_old == ISM_SBA_MODE_DISC && st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV ); +#endif /* copy from ISM delay buffer to the correct place in tcs */ for ( ch_idx = 0; ch_idx < st_ivas->nchan_ism; ch_idx++ ) { @@ -1567,12 +1870,17 @@ ivas_error ivas_jbm_dec_flush_renderer( #endif } +#ifdef NONBE_UNIFIED_DECODING_PATHS /* update global combined orientation start index */ ivas_combined_orientation_update_start_index( st_ivas->hCombinedOrientationData, *nSamplesRendered ); +#endif *nSamplesRendered = n_samples_to_render; /* Only write out the valid data*/ +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( st_ivas->hDecoderConfig->Opt_Limiter ) +#endif { if ( st_ivas->ivas_format != MONO_FORMAT ) { @@ -1582,9 +1890,30 @@ ivas_error ivas_jbm_dec_flush_renderer( } } +#ifdef SPLIT_REND_WITH_HEAD_ROT + switch ( pcm_resolution ) + { + case PCM_INT16: +#endif +#ifdef DEBUGGING + st_ivas->noClipping += +#endif ivas_syn_output( p_output, *nSamplesRendered, st_ivas->hDecoderConfig->nchan_out, +#ifdef SPLIT_REND_WITH_HEAD_ROT + (int16_t *) +#endif data ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + break; + case PCM_FLOAT32: + ivas_syn_output_f( p_output, *nSamplesRendered, st_ivas->hDecoderConfig->nchan_out, (float *) data ); + break; + default: + error = IVAS_ERR_UNKNOWN; + break; + } +#endif return IVAS_ERR_OK; } @@ -1630,6 +1959,9 @@ void ivas_jbm_dec_get_adapted_linear_interpolator( { int16_t jbm_segment_len, idx; float dec; +#ifdef DEBUGGING + assert( default_interp_length % 2 == 0 ); +#endif jbm_segment_len = ( default_interp_length >> 1 ); dec = 1.0f / default_interp_length; @@ -1720,6 +2052,9 @@ void ivas_jbm_dec_get_md_map( int16_t jbm_segment_len, map_idx, src_idx, src_idx_map; float dec, src_idx_f; +#ifdef DEBUGGING + assert( default_len % 2 == 0 ); +#endif jbm_segment_len = ( default_len >> 1 ); dec = 1.0f / default_len; @@ -1841,11 +2176,15 @@ int16_t ivas_jbm_dec_get_num_tc_channels( ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate; +#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX if ( st_ivas->ivas_format == MONO_FORMAT ) { num_tc = st_ivas->hDecoderConfig->nchan_out; } else if ( st_ivas->ivas_format == STEREO_FORMAT && st_ivas->hDecoderConfig->nchan_out == 1 ) +#else + if ( st_ivas->ivas_format == STEREO_FORMAT && st_ivas->hDecoderConfig->nchan_out == 1 ) +#endif { num_tc = 1; } @@ -2145,8 +2484,10 @@ ivas_error ivas_jbm_dec_tc_buffer_open( } else { +#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX if ( st_ivas->hDecoderConfig->Opt_tsm ) { +#endif if ( ( hTcBuffer->tc_buffer = (float *) malloc( nsamp_to_allocate * sizeof( float ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for JBM TC Buffer\n" ) ); @@ -2168,11 +2509,13 @@ ivas_error ivas_jbm_dec_tc_buffer_open( { hTcBuffer->tc[ch_idx] = NULL; } +#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX } else { hTcBuffer->tc_buffer = NULL; } +#endif } } @@ -2207,9 +2550,24 @@ ivas_error ivas_jbm_dec_tc_buffer_reconfigure( /* if granularity changes, adapt subframe_nb_slots */ if ( n_samples_granularity != hTcBuffer->n_samples_granularity ) { +#ifdef DEBUGGING + int16_t nMaxSlotsPerSubframeOld; +#endif int16_t nMaxSlotsPerSubframeNew; nMaxSlotsPerSubframeNew = (int16_t) ( st_ivas->hDecoderConfig->output_Fs / ( FRAMES_PER_SEC * MAX_PARAM_SPATIAL_SUBFRAMES ) ) / n_samples_granularity; +#ifdef DEBUGGING + nMaxSlotsPerSubframeOld = (int16_t) ( st_ivas->hDecoderConfig->output_Fs / ( FRAMES_PER_SEC * MAX_PARAM_SPATIAL_SUBFRAMES ) ) / st_ivas->hTcBuffer->n_samples_granularity; + assert( hTcBuffer->subframe_nbslots[hTcBuffer->subframes_rendered - 1] == nMaxSlotsPerSubframeOld ); + if ( n_samples_granularity < hTcBuffer->n_samples_granularity ) + { + assert( ( hTcBuffer->n_samples_granularity % n_samples_granularity ) == 0 ); + } + else + { + assert( ( n_samples_granularity % hTcBuffer->n_samples_granularity ) == 0 ); + } +#endif /* if samples were flushed, take that into account here */ if ( n_samples_granularity < hTcBuffer->n_samples_granularity && hTcBuffer->n_samples_flushed > 0 ) { @@ -2229,12 +2587,20 @@ ivas_error ivas_jbm_dec_tc_buffer_reconfigure( nchan_residual = nchan_transport_internal - nchan_full; hTcBuffer->n_samples_granularity = n_samples_granularity; +#ifdef DEBUGGING + /* what is remaining from last frames needs always be smaller than n_samples_granularity */ + assert( ( hTcBuffer->n_samples_buffered - hTcBuffer->n_samples_rendered ) < n_samples_granularity ); +#endif /* realloc buffers */ +#ifdef NONBE_UNIFIED_DECODING_PATHS if ( hTcBuffer->tc_buffer != NULL ) { +#endif free( hTcBuffer->tc_buffer ); hTcBuffer->tc_buffer = NULL; +#ifdef NONBE_UNIFIED_DECODING_PATHS } +#endif if ( st_ivas->hDecoderConfig->Opt_tsm ) { @@ -2249,6 +2615,7 @@ ivas_error ivas_jbm_dec_tc_buffer_reconfigure( nsamp_to_allocate = hTcBuffer->nchan_buffer_full * n_samp_full; nsamp_to_allocate += nchan_residual * n_samp_residual; +#ifdef NONBE_UNIFIED_DECODING_PATHS if ( nsamp_to_allocate == 0 ) { hTcBuffer->tc_buffer = NULL; @@ -2259,8 +2626,11 @@ ivas_error ivas_jbm_dec_tc_buffer_reconfigure( } else { +#endif +#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX if ( st_ivas->hDecoderConfig->Opt_tsm ) { +#endif if ( ( hTcBuffer->tc_buffer = (float *) malloc( nsamp_to_allocate * sizeof( float ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for JBM TC Buffer\n" ) ); @@ -2282,12 +2652,16 @@ ivas_error ivas_jbm_dec_tc_buffer_reconfigure( { hTcBuffer->tc[ch_idx] = NULL; } +#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX } else { hTcBuffer->tc_buffer = NULL; } +#endif +#ifdef NONBE_UNIFIED_DECODING_PATHS } +#endif return IVAS_ERR_OK; } @@ -2496,6 +2870,10 @@ TC_BUFFER_MODE ivas_jbm_dec_get_tc_buffer_mode( buffer_mode = TC_BUFFER_MODE_RENDERER; } break; +#ifdef DEBUGGING + default: + assert( 0 ); +#endif } return buffer_mode; @@ -2526,14 +2904,18 @@ void ivas_jbm_dec_copy_tc_no_tsm( n_ch_cldfb = hTcBuffer->nchan_transport_jbm - hTcBuffer->nchan_buffer_full; /* copy full tcs*/ +#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX if ( st_ivas->hDecoderConfig->Opt_tsm ) { +#endif for ( ch_idx = 0; ch_idx < n_ch_full_copy; ch_idx++ ) { mvr2r( tc[ch_idx], st_ivas->hTcBuffer->tc[ch_idx], hTcBuffer->n_samples_buffered ); } +#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX } ch_idx = 0; +#endif /* CLDFB ana for ParamMC/ParamISM */ if ( n_ch_cldfb > 0 ) @@ -2559,6 +2941,12 @@ void ivas_jbm_dec_copy_tc_no_tsm( cldfb_imag_buffer = st_ivas->hParamMC->Cldfb_ImagBuffer_tc; num_freq_bands = st_ivas->hParamMC->num_freq_bands; } +#ifdef DEBUGGING + else + { + assert( 0 && "Residual (direct CLDFB transport channels) only possible for ParamMC/ParamISM!" ); + } +#endif /* CLDFB Analysis*/ for ( cldfb_ch = 0; cldfb_ch < n_ch_cldfb; cldfb_ch++, ch_idx++ ) diff --git a/lib_dec/ivas_lfe_dec.c b/lib_dec/ivas_lfe_dec.c index 441b33356..63899b107 100644 --- a/lib_dec/ivas_lfe_dec.c +++ b/lib_dec/ivas_lfe_dec.c @@ -32,6 +32,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "prot.h" #include "ivas_prot.h" #include "ivas_rom_com.h" diff --git a/lib_dec/ivas_lfe_plc.c b/lib_dec/ivas_lfe_plc.c index d973dc4a0..491121af3 100644 --- a/lib_dec/ivas_lfe_plc.c +++ b/lib_dec/ivas_lfe_plc.c @@ -36,6 +36,9 @@ #include "ivas_prot.h" #include "ivas_rom_com.h" #include +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" /*------------------------------------------------------------------------------------------* diff --git a/lib_dec/ivas_ls_custom_dec.c b/lib_dec/ivas_ls_custom_dec.c index e926b1fbe..71e8bd229 100644 --- a/lib_dec/ivas_ls_custom_dec.c +++ b/lib_dec/ivas_ls_custom_dec.c @@ -33,6 +33,9 @@ #include "options.h" #include "ivas_prot.h" #include "prot.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" diff --git a/lib_dec/ivas_masa_dec.c b/lib_dec/ivas_masa_dec.c index 0eb9691b1..a160275ea 100644 --- a/lib_dec/ivas_masa_dec.c +++ b/lib_dec/ivas_masa_dec.c @@ -39,6 +39,9 @@ #include "ivas_rom_com.h" #include "ivas_stat_dec.h" #include "prot.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "wmc_auto.h" @@ -619,7 +622,11 @@ ivas_error ivas_masa_dec_open( st_ivas->hMasa = hMasa; /* allocate transport channels*/ +#ifndef NONBE_UNIFIED_DECODING_PATHS + if ( st_ivas->hDecoderConfig->Opt_5ms && st_ivas->hTcBuffer == NULL && st_ivas->renderer_type != RENDERER_DISABLE && st_ivas->renderer_type != RENDERER_BINAURAL_PARAMETRIC && st_ivas->renderer_type != RENDERER_BINAURAL_PARAMETRIC_ROOM && st_ivas->renderer_type != RENDERER_STEREO_PARAMETRIC ) +#else if ( st_ivas->hTcBuffer == NULL && st_ivas->renderer_type != RENDERER_DISABLE && st_ivas->renderer_type != RENDERER_BINAURAL_PARAMETRIC && st_ivas->renderer_type != RENDERER_BINAURAL_PARAMETRIC_ROOM && st_ivas->renderer_type != RENDERER_STEREO_PARAMETRIC ) +#endif { int16_t nchan_to_allocate, nchan_transport; TC_BUFFER_MODE buffer_mode; @@ -1230,7 +1237,12 @@ static int16_t decode_lfe_to_total_energy_ratio( ivas_error ivas_masa_dec_reconfigure( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ uint16_t *nSamplesRendered, /* o : number of samples flushed from the previous frame (JBM) */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + const PCM_RESOLUTION pcm_resolution, /* i : type for the decoded PCM resolution */ + void *data /* o : output synthesis signal */ +#else int16_t *data /* o : output synthesis signal */ +#endif ) { int16_t n, tmp, num_bits; @@ -1240,6 +1252,9 @@ ivas_error ivas_masa_dec_reconfigure( int32_t ivas_total_brate, last_ivas_total_brate; int16_t numCldfbAnalyses_old, numCldfbSyntheses_old; ivas_error error; +#ifdef SPLIT_REND_WITH_HEAD_ROT + int16_t pos_idx; +#endif int32_t ism_total_brate; error = IVAS_ERR_OK; @@ -1247,20 +1262,32 @@ ivas_error ivas_masa_dec_reconfigure( ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate; last_ivas_total_brate = st_ivas->hDecoderConfig->last_ivas_total_brate; +#ifndef NONBE_UNIFIED_DECODING_PATHS + if ( st_ivas->hDecoderConfig->Opt_5ms == 1 ) + { +#endif if ( st_ivas->hSpatParamRendCom != NULL && st_ivas->hSpatParamRendCom->slot_size == st_ivas->hTcBuffer->n_samples_granularity ) { mvs2s( st_ivas->hSpatParamRendCom->subframe_nbslots, st_ivas->hTcBuffer->subframe_nbslots, MAX_JBM_SUBFRAMES_5MS ); st_ivas->hTcBuffer->nb_subframes = st_ivas->hSpatParamRendCom->nb_subframes; st_ivas->hTcBuffer->subframes_rendered = st_ivas->hSpatParamRendCom->subframes_rendered; } +#ifndef NONBE_UNIFIED_DECODING_PATHS + } +#endif ivas_init_dec_get_num_cldfb_instances( st_ivas, &numCldfbAnalyses_old, &numCldfbSyntheses_old ); /* renderer might have changed, reselect */ ivas_renderer_select( st_ivas ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( st_ivas->renderer_type == RENDERER_DIRAC && st_ivas->hDirACRend == NULL ) || + ( ( st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) && st_ivas->hDiracDecBin[0] == NULL ) ) +#else if ( ( st_ivas->renderer_type == RENDERER_DIRAC && st_ivas->hDirACRend == NULL ) || ( ( st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) && st_ivas->hDiracDecBin == NULL ) ) +#endif { /* init a new DirAC dec */ if ( ( error = ivas_dirac_dec_config( st_ivas, DIRAC_OPEN ) ) != IVAS_ERR_OK ) @@ -1273,7 +1300,11 @@ ivas_error ivas_masa_dec_reconfigure( if ( st_ivas->hDirAC != NULL ) { /* close all unnecessary parametric decoding and rendering */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + ivas_dirac_dec_close_binaural_data( st_ivas->hDiracDecBin ); +#else ivas_dirac_dec_close_binaural_data( &st_ivas->hDiracDecBin ); +#endif ivas_dirac_rend_close( &( st_ivas->hDirACRend ) ); ivas_spat_hSpatParamRendCom_close( &( st_ivas->hSpatParamRendCom ) ); ivas_dirac_dec_close( &( st_ivas->hDirAC ) ); @@ -1297,7 +1328,11 @@ ivas_error ivas_masa_dec_reconfigure( sts[0]->bit_stream = bit_stream + num_bits; num_bits += (int16_t) ( st_ivas->hSCE[sce_id]->element_brate / FRAMES_PER_SEC ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) && st_ivas->hDiracDecBin[0] != NULL ) +#else if ( ( st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) && st_ivas->hDiracDecBin != NULL ) +#endif { if ( ( error = ivas_dirac_dec_config( st_ivas, DIRAC_RECONFIGURE ) ) != IVAS_ERR_OK ) { @@ -1323,7 +1358,11 @@ ivas_error ivas_masa_dec_reconfigure( { st_ivas->hCPE[cpe_id]->nchan_out = 1; +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( st_ivas->renderer_type == RENDERER_DIRAC && st_ivas->hDirACRend != NULL ) || ( ( st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) && st_ivas->hDiracDecBin[0] != NULL ) ) +#else if ( ( st_ivas->renderer_type == RENDERER_DIRAC && st_ivas->hDirACRend != NULL ) || ( ( st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) && st_ivas->hDiracDecBin != NULL ) ) +#endif { if ( ( error = ivas_dirac_dec_config( st_ivas, DIRAC_RECONFIGURE ) ) != IVAS_ERR_OK ) { @@ -1335,7 +1374,11 @@ ivas_error ivas_masa_dec_reconfigure( { st_ivas->hCPE[cpe_id]->nchan_out = CPE_CHANNELS; +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( st_ivas->renderer_type == RENDERER_DIRAC && st_ivas->hDirACRend != NULL ) || ( ( st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) && st_ivas->hDiracDecBin[0] != NULL ) ) +#else if ( ( st_ivas->renderer_type == RENDERER_DIRAC && st_ivas->hDirACRend != NULL ) || ( ( st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) && st_ivas->hDiracDecBin != NULL ) ) +#endif { if ( ( error = ivas_dirac_dec_config( st_ivas, DIRAC_RECONFIGURE ) ) != IVAS_ERR_OK ) { @@ -1345,10 +1388,22 @@ ivas_error ivas_masa_dec_reconfigure( } } +#ifdef SPLIT_REND_WITH_HEAD_ROT + for ( pos_idx = 0; pos_idx < MAX_HEAD_ROT_POSES; pos_idx++ ) + { + if ( st_ivas->hDiracDecBin[pos_idx] != NULL ) + { +#else if ( st_ivas->hDiracDecBin != NULL ) { +#endif /* regularization factor is bitrate-dependent */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + st_ivas->hDiracDecBin[pos_idx]->reqularizationFactor = configure_reqularization_factor( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate ); + } +#else st_ivas->hDiracDecBin->reqularizationFactor = configure_reqularization_factor( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate ); +#endif } if ( st_ivas->ivas_format == MASA_FORMAT && st_ivas->last_ivas_format == MASA_FORMAT ) /* note: switching within OMASA is handled in ivas_omasa_dec_config() */ @@ -1356,9 +1411,17 @@ ivas_error ivas_masa_dec_reconfigure( /*-----------------------------------------------------------------* * TD Decorrelator *-----------------------------------------------------------------*/ +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( st_ivas->hDiracDecBin[0] != NULL ) +#else if ( st_ivas->hDiracDecBin != NULL ) +#endif { +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( error = ivas_td_decorr_reconfig_dec( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->nchan_transport, st_ivas->hDecoderConfig->output_Fs, &( st_ivas->hDiracDecBin[0]->hTdDecorr ), &( st_ivas->hDiracDecBin[0]->useTdDecorr ) ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_td_decorr_reconfig_dec( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->nchan_transport, st_ivas->hDecoderConfig->output_Fs, &( st_ivas->hDiracDecBin->hTdDecorr ), &( st_ivas->hDiracDecBin->useTdDecorr ) ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -1395,6 +1458,9 @@ ivas_error ivas_masa_dec_reconfigure( st_ivas->ism_mode = ISM_MODE_NONE; } +#ifndef NONBE_UNIFIED_DECODING_PATHS + if ( st_ivas->hDecoderConfig->Opt_5ms == 1 ) +#endif { int16_t tc_nchan_to_allocate; int16_t tc_nchan_transport; @@ -1431,7 +1497,11 @@ ivas_error ivas_masa_dec_reconfigure( { if ( n_samples_granularity < st_ivas->hTcBuffer->n_samples_granularity ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( error = ivas_jbm_dec_flush_renderer( st_ivas, n_samples_granularity, st_ivas->renderer_type, st_ivas->intern_config, &st_ivas->hIntSetup, MC_MODE_NONE, ISM_MASA_MODE_DISC, nSamplesRendered, pcm_resolution, data ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_jbm_dec_flush_renderer( st_ivas, n_samples_granularity, st_ivas->renderer_type, st_ivas->intern_config, &st_ivas->hIntSetup, MC_MODE_NONE, ISM_MASA_MODE_DISC, nSamplesRendered, data ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -1514,7 +1584,11 @@ void ivas_spar_param_to_masa_param_mapping( hSpatParamRendCom = st_ivas->hSpatParamRendCom; hSpatParamRendCom->numParametricDirections = 1; hSpatParamRendCom->numSimultaneousDirections = 1; +#ifdef SPLIT_REND_WITH_HEAD_ROT + hDiffuseDist = st_ivas->hDiracDecBin[0]->hDiffuseDist; +#else hDiffuseDist = st_ivas->hDiracDecBin->hDiffuseDist; +#endif nchan_transport = st_ivas->nchan_transport; band_grouping = hDirAC->band_grouping; hSpar = st_ivas->hSpar; diff --git a/lib_dec/ivas_mc_param_dec.c b/lib_dec/ivas_mc_param_dec.c index 5536baa14..3352a7978 100644 --- a/lib_dec/ivas_mc_param_dec.c +++ b/lib_dec/ivas_mc_param_dec.c @@ -43,6 +43,12 @@ #include "ivas_rom_com.h" #include "ivas_rom_dec.h" #include "math.h" +#ifdef DEBUGGING +#include "debug.h" +#endif +#ifdef DEBUG_PLOT +#include "deb_out.h" +#endif #include "wmc_auto.h" #include "rom_dec.h" @@ -205,6 +211,10 @@ ivas_error ivas_param_mc_dec_open( st_ivas->element_mode_init = IVAS_CPE_MDCT; break; +#ifdef DEBUGGING + default: + assert( 0 && "Number of TC not supported for Parametric MC!" ); +#endif } /*-----------------------------------------------------------------* @@ -429,7 +439,11 @@ ivas_error ivas_param_mc_dec_open( ivas_param_mc_dec_init( hParamMC, nchan_transport, nchan_out_cov ); +#ifndef NONBE_UNIFIED_DECODING_PATHS + if ( st_ivas->hDecoderConfig->Opt_5ms && hParamMC->synthesis_conf != PARAM_MC_SYNTH_MONO_STEREO ) +#else if ( hParamMC->synthesis_conf != PARAM_MC_SYNTH_MONO_STEREO ) +#endif { int16_t n_cldfb_slots; @@ -602,6 +616,10 @@ ivas_error ivas_param_mc_dec_reconfig( st_ivas->element_mode_init = IVAS_CPE_MDCT; break; +#ifdef DEBUGGING + default: + assert( 0 && "Number of TC not supported for Parametric MC!" ); +#endif } /*-----------------------------------------------------------------* @@ -615,6 +633,9 @@ ivas_error ivas_param_mc_dec_reconfig( for ( k = 0; k < 2; k++ ) { +#ifdef DEBUGGING + assert( hParamMC->hMetadataPMC->icc_map_full[k] != NULL ); +#endif if ( hParamMC->hMetadataPMC->icc_map_full[k] != NULL ) { free( hParamMC->hMetadataPMC->icc_map_full[k] ); @@ -954,6 +975,7 @@ ivas_error ivas_param_mc_dec_reconfig( } +#ifdef NONBE_UNIFIED_DECODING_PATHS if ( nchan_transport_old != nchan_transport ) { if ( hParamMC->synthesis_conf != PARAM_MC_SYNTH_MONO_STEREO ) @@ -1002,6 +1024,7 @@ ivas_error ivas_param_mc_dec_reconfig( } } } +#endif return error; } @@ -1039,6 +1062,12 @@ int16_t param_mc_get_num_cldfb_syntheses( { num_cldfb_syntheses = st_ivas->hOutSetup.nchan_out_woLFE + st_ivas->hOutSetup.num_lfe; } +#ifdef DEBUGGING + else + { + assert( 0 && "Renderer settings not valid for ParamMC!\n" ); + } +#endif return num_cldfb_syntheses; } @@ -1460,7 +1489,11 @@ void ivas_param_mc_dec_digest_tc( /* slot loop for gathering the input data */ for ( slot_idx = 0; slot_idx < nCldfbSlots; slot_idx++ ) { +#ifndef NONBE_UNIFIED_DECODING_PATHS + if ( st_ivas->hDecoderConfig->Opt_tsm || !st_ivas->hDecoderConfig->Opt_5ms ) +#else if ( st_ivas->hDecoderConfig->Opt_tsm ) +#endif { float RealBuffer[CLDFB_NO_CHANNELS_MAX]; float ImagBuffer[CLDFB_NO_CHANNELS_MAX]; @@ -1551,8 +1584,13 @@ void ivas_param_mc_dec_render( /*CLDFB*/ float Cldfb_RealBuffer[MAX_INTERN_CHANNELS][PARAM_MC_MAX_NSLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; float Cldfb_ImagBuffer[MAX_INTERN_CHANNELS][PARAM_MC_MAX_NSLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; +#ifdef SPLIT_REND_WITH_HEAD_ROT + float Cldfb_RealBuffer_Binaural[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][PARAM_MC_MAX_NSLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; + float Cldfb_ImagBuffer_Binaural[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][PARAM_MC_MAX_NSLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; +#else float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][PARAM_MC_MAX_NSLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][PARAM_MC_MAX_NSLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; +#endif /*Decorrelator*/ float onset_filter[MAX_CICP_CHANNELS * CLDFB_NO_CHANNELS_MAX]; /* format converter */ @@ -1622,6 +1660,9 @@ void ivas_param_mc_dec_render( slots_to_render -= hParamMC->subframe_nbslots[last_sf]; last_sf++; } +#ifdef DEBUGGING + assert( slots_to_render == 0 ); +#endif if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC ) { for ( subframe_idx = first_sf; subframe_idx < last_sf; subframe_idx++ ) @@ -1745,15 +1786,60 @@ void ivas_param_mc_dec_render( if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { + if ( st_ivas->hSplitBinRend.hCldfbDataOut != NULL ) + { + for ( slot_idx = 0; slot_idx < MAX_PARAM_SPATIAL_SUBFRAMES; slot_idx++ ) + { + for ( ch = 0; ch < ( st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe ); ch++ ) + { + mvr2r( Cldfb_RealBuffer[ch][slot_idx], st_ivas->hSplitBinRend.hCldfbDataOut->Cldfb_RealBuffer[ch][slot_idx_start + slot_idx], hParamMC->num_freq_bands ); + mvr2r( Cldfb_ImagBuffer[ch][slot_idx], st_ivas->hSplitBinRend.hCldfbDataOut->Cldfb_ImagBuffer[ch][slot_idx_start + slot_idx], hParamMC->num_freq_bands ); + } + } + st_ivas->hSplitBinRend.hCldfbDataOut->config = st_ivas->hIntSetup.output_config; + } + } +#endif ivas_binRenderer( st_ivas->hBinRenderer, +#ifdef SPLIT_REND_WITH_HEAD_ROT + &st_ivas->hSplitBinRend.splitrend.multiBinPoseData, +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + NULL, +#endif +#endif st_ivas->hCombinedOrientationData, +#ifndef NONBE_UNIFIED_DECODING_PATHS + subframe_idx, +#endif hParamMC->subframe_nbslots[subframe_idx], Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, Cldfb_RealBuffer, Cldfb_ImagBuffer ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { + int16_t pos_idx; + for ( pos_idx = 0; pos_idx < st_ivas->hBinRenderer->numPoses; pos_idx++ ) + { + for ( slot_idx = 0; slot_idx < hParamMC->subframe_nbslots[subframe_idx]; slot_idx++ ) + { + for ( ch = 0; ch < nchan_out_cldfb; ch++ ) + { + mvr2r( Cldfb_RealBuffer_Binaural[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend.hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[( pos_idx * BINAURAL_CHANNELS ) + ch][slot_idx_start + slot_idx], hParamMC->num_freq_bands ); + mvr2r( Cldfb_ImagBuffer_Binaural[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend.hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[( pos_idx * BINAURAL_CHANNELS ) + ch][slot_idx_start + slot_idx], hParamMC->num_freq_bands ); + } + } + } + } +#endif +#ifdef NONBE_UNIFIED_DECODING_PATHS /* update combined orientation access index */ ivas_combined_orientation_update_index( st_ivas->hCombinedOrientationData, hParamMC->num_freq_bands * hParamMC->subframe_nbslots[subframe_idx] ); +#endif } else if ( hParamMC->synthesis_conf == PARAM_MC_SYNTH_LS_CONV_CLDFB ) { @@ -1774,8 +1860,13 @@ void ivas_param_mc_dec_render( { if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + RealBuffer[i] = Cldfb_RealBuffer_Binaural[0][ch][i]; + ImagBuffer[i] = Cldfb_ImagBuffer_Binaural[0][ch][i]; +#else RealBuffer[i] = Cldfb_RealBuffer_Binaural[ch][i]; ImagBuffer[i] = Cldfb_ImagBuffer_Binaural[ch][i]; +#endif } else { @@ -1842,6 +1933,10 @@ void ivas_param_mc_dec( nSamplesAsked = (int16_t) ( st_ivas->hDecoderConfig->output_Fs / FRAMES_PER_SEC ); ivas_param_mc_dec_digest_tc( st_ivas, DEFAULT_JBM_CLDFB_TIMESLOTS, output_f ); ivas_param_mc_dec_render( st_ivas, nSamplesAsked, &nSamplesRendered, &nSamplesAvailableNext, output_f ); +#ifdef DEBUGGING + assert( nSamplesRendered == nSamplesAsked ); + assert( nSamplesAvailableNext == 0 ); +#endif /* set handle pointers back to NULL */ hParamMC->Cldfb_RealBuffer_tc = NULL; @@ -1889,6 +1984,9 @@ static void ivas_param_mc_dec_init( if ( hParamMC->band_grouping[k] <= hParamMC->max_band_decorr ) { max_param_band_residual = k; +#ifdef DEBUGGING + assert( hParamMC->band_grouping[k] == hParamMC->max_band_decorr ); +#endif break; } } @@ -2249,6 +2347,9 @@ static void ivas_param_mc_get_mixing_matrices( if ( hSynthesisOutputSetup->num_lfe ) { float *proto_matrix_ptr_in; +#ifdef DEBUGGING + assert( ( nY_cov == ( hSynthesisOutputSetup->nchan_out_woLFE + hSynthesisOutputSetup->num_lfe ) ) && "Number of channels do not match!" ); +#endif for ( lfe_idx1 = 0; lfe_idx1 < hSynthesisOutputSetup->num_lfe; lfe_idx1++ ) { lfe_indices[lfe_idx1 + 1] = hSynthesisOutputSetup->index_lfe[lfe_idx1]; diff --git a/lib_dec/ivas_mc_paramupmix_dec.c b/lib_dec/ivas_mc_paramupmix_dec.c index d98788695..57065ed32 100644 --- a/lib_dec/ivas_mc_paramupmix_dec.c +++ b/lib_dec/ivas_mc_paramupmix_dec.c @@ -41,6 +41,12 @@ #include "ivas_rom_com.h" #include "ivas_rom_dec.h" #include "math.h" +#ifdef DEBUGGING +#include "debug.h" +#endif +#ifdef DEBUG_PLOT +#include "deb_out.h" +#endif #include "wmc_auto.h" #include "rom_dec.h" @@ -58,14 +64,25 @@ const int16_t MC_PARAMUPMIX_CHIDX2[MC_PARAMUPMIX_COMBINATIONS] = { 2, 3, 6, 7 }; * Local function prototypes *-----------------------------------------------------------------------*/ +#ifndef NONBE_UNIFIED_DECODING_PATHS_FIX +static void ps_pred_process( MC_PARAMUPMIX_DEC_HANDLE hMCParamUpmix, float qmf_mod_re[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], float qmf_mod_im[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], float qmf_side_re[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], float qmf_side_im[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], const int16_t ch ); +#endif static void ps_pred_process_sf( MC_PARAMUPMIX_DEC_HANDLE hMCParamUpmix, DECODER_TC_BUFFER_HANDLE hTcBuffer, float qmf_mod_re[JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float qmf_mod_im[JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float qmf_side_re[JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float qmf_side_im[JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float *param_interpol, const int16_t ch, const int16_t slots_rendered ); +#ifdef SPLIT_REND_WITH_HEAD_ROT +static void ivas_mc_paramupmix_dec_sf( Decoder_Struct *st_ivas, float *output_f[MAX_OUTPUT_CHANNELS], const int16_t slot_index_start ); +#else static void ivas_mc_paramupmix_dec_sf( Decoder_Struct *st_ivas, float *output_f[MAX_OUTPUT_CHANNELS] ); +#endif static void ivas_param_upmix_dec_decorr_subframes( Decoder_Struct *st_ivas, const int16_t nSamplesForRendering ); +#ifndef NONBE_UNIFIED_DECODING_PATHS_FIX +static void paramupmix_td_decorr_process( ivas_td_decorr_state_t *hTdDecorr[], float *pcm_in[], float **pp_out_pcm, const int16_t output_frame ); +#endif static int16_t huff_read( Decoder_State *st, const int16_t ( *ht )[2] ); +#ifdef FIX_891_PARAMUPMIX_CLEANUP static void huffman_decode( Decoder_State *st, const PAR_TYPE parType, int32_t *vq ); static void dequant_alpha( int32_t *vq, float *v ); @@ -73,6 +90,15 @@ static void dequant_alpha( int32_t *vq, float *v ); static void dequant_beta( int32_t *aq, int32_t *bq, float *beta ); static void get_ec_data( Decoder_State *st, const PAR_TYPE parType, int32_t *parQ, int32_t *alphaQEnv, float ab[IVAS_MAX_NUM_BANDS] ); +#else +static void huffman_decode( Decoder_State *st, const int16_t nv, const int16_t ivStart, PAR_TYPE parType, QUANT_TYPE quant_type, const int16_t bNoDt, int32_t *vq ); + +static void dequant_alpha( const int16_t nv, const int16_t ivStart, const QUANT_TYPE quant_type, int32_t *vq, float *v ); + +static void dequant_beta( const int16_t nv, const int16_t ivStart, const QUANT_TYPE quant_type, int32_t *aq, int32_t *bq, float *beta ); + +static void get_ec_data( Decoder_State *st, const PAR_TYPE parType, const QUANT_TYPE quant_type, const int16_t nParBand, const int16_t parBandStart, int32_t *parQ, int32_t *alphaQEnv, float ab[IVAS_MAX_NUM_BANDS] ); +#endif /*------------------------------------------------------------------------- @@ -127,9 +153,17 @@ void ivas_mc_paramupmix_dec_read_BS( for ( i = 0; i < MC_PARAMUPMIX_COMBINATIONS; i++ ) { +#ifdef FIX_891_PARAMUPMIX_CLEANUP get_ec_data( st0, ALPHA, hMCParamUpmix->alpha_quant[i], alpha_quant, hMCParamUpmix->alphas[i] ); get_ec_data( st0, BETA, hMCParamUpmix->beta_quant[i], alpha_quant, hMCParamUpmix->betas[i] ); +#else + get_ec_data( st0, ALPHA, FINE /*quant_type*/, IVAS_MAX_NUM_BANDS /*nParBand*/, + 0 /*parBandStart*/, hMCParamUpmix->alpha_quant[i], alpha_quant, hMCParamUpmix->alphas[i] ); + + get_ec_data( st0, BETA, FINE /*quant_type*/, IVAS_MAX_NUM_BANDS /*nParBand*/, + 0 /*parBandStart*/, hMCParamUpmix->beta_quant[i], alpha_quant, hMCParamUpmix->betas[i] ); +#endif } *nb_bits += st0->next_bit_pos; st0->bit_stream = bit_stream_orig; @@ -150,6 +184,299 @@ void ivas_mc_paramupmix_dec_read_BS( return; } +#ifndef NONBE_UNIFIED_DECODING_PATHS_FIX +/*------------------------------------------------------------------------- + * ivas_mc_paramupmix_dec() + * + * MC ParamUpmix decoding process + *------------------------------------------------------------------------*/ + +void ivas_mc_paramupmix_dec( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ + float *output_f[] /* i/o: synthesized core-coder transport channels */ +) +{ + MC_PARAMUPMIX_DEC_HANDLE hMCParamUpmix; + int16_t i, k, ch; + int16_t slot_idx; + int16_t first_empty_channel; + int16_t nchan_out_transport; + /*CLDFB*/ + float Cldfb_RealBuffer[MC_PARAMUPMIX_MAX_TRANSPORT_CHANS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + float Cldfb_ImagBuffer[MC_PARAMUPMIX_MAX_TRANSPORT_CHANS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + int16_t channel_active[MAX_OUTPUT_CHANNELS]; + int32_t output_Fs; + int16_t output_frame; + float Pcm_decorr[MC_PARAMUPMIX_COMBINATIONS][L_FRAME48k]; /* decorrelated channels */ + float *pPcm_temp[MC_PARAMUPMIX_COMBINATIONS * 2]; /* decorrelated and undecorrelated*/ + int16_t noparamupmix_delay; + AUDIO_CONFIG output_config; + int16_t subframeIdx, idx_in, index_slot, maxBand; + float Cldfb_RealBuffer_subfr[MAX_INTERN_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; + float Cldfb_ImagBuffer_subfr[MAX_INTERN_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; +#ifdef SPLIT_REND_WITH_HEAD_ROT + float Cldfb_RealBuffer_Binaural[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; + float Cldfb_ImagBuffer_Binaural[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; +#else + float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; + float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; +#endif + + hMCParamUpmix = st_ivas->hMCParamUpmix; + assert( hMCParamUpmix ); + push_wmops( "mc_paramupmix_dec" ); + + set_s( channel_active, 0, MAX_CICP_CHANNELS ); + nchan_out_transport = st_ivas->hTransSetup.nchan_out_woLFE + st_ivas->hTransSetup.num_lfe; + set_s( channel_active, 1, nchan_out_transport ); /* change to nchan_out_transport */ + output_Fs = st_ivas->hDecoderConfig->output_Fs; + output_config = st_ivas->hDecoderConfig->output_config; + output_frame = (int16_t) ( output_Fs / FRAMES_PER_SEC ); + + if ( ( output_config == IVAS_AUDIO_CONFIG_STEREO ) || ( output_config == IVAS_AUDIO_CONFIG_MONO ) ) + { + first_empty_channel = 8; /* Don't upmix */ + + /* Compensate loudness for not doing full upmix */ + for ( i = 4; i < 8; i++ ) + { + v_multc( output_f[i], 2.0f, output_f[i], L_FRAME48k ); + } + } + else + { + first_empty_channel = 12; + + for ( i = 0; i < MC_PARAMUPMIX_COMBINATIONS; i++ ) + { + pPcm_temp[i] = Pcm_decorr[i]; /* decorrelated */ + } + + paramupmix_td_decorr_process( hMCParamUpmix->hTdDecorr, &( output_f[4] ), pPcm_temp, output_frame ); + + for ( i = 0; i < MC_PARAMUPMIX_COMBINATIONS; i++ ) + { + pPcm_temp[2 * i] = output_f[i + 4]; /* un-decorrelated */ + pPcm_temp[2 * i + 1] = Pcm_decorr[i]; /* decorrelated */ + } + + /* CLDFB Analysis*/ + for ( ch = 0; ch < MC_PARAMUPMIX_COMBINATIONS * 2; ch++ ) + { + /* slot loop for gathering the input data */ + for ( slot_idx = 0; slot_idx < CLDFB_NO_COL_MAX; slot_idx++ ) + { + cldfbAnalysis_ts( &( pPcm_temp[ch][hMCParamUpmix->num_freq_bands * slot_idx] ), Cldfb_RealBuffer[ch][slot_idx], Cldfb_ImagBuffer[ch][slot_idx], hMCParamUpmix->num_freq_bands, st_ivas->cldfbAnaDec[ch] ); + } + } + for ( ch = 0; ch < MC_PARAMUPMIX_COMBINATIONS; ch++ ) + { + ps_pred_process( hMCParamUpmix, + Cldfb_RealBuffer[2 * ch], /* in/out */ + Cldfb_ImagBuffer[2 * ch], + Cldfb_RealBuffer[2 * ch + 1], /* in/out decorr */ + Cldfb_ImagBuffer[2 * ch + 1], + ch ); + + /*-- m, s -> l, r ----------------------------*/ + for ( i = 0; i < CLDFB_NO_COL_MAX; i++ ) + { + for ( k = 0; k < CLDFB_NO_CHANNELS_MAX; k++ ) + { + float qlre = Cldfb_RealBuffer[2 * ch][i][k]; + float qlim = Cldfb_ImagBuffer[2 * ch][i][k]; + float qrre = Cldfb_RealBuffer[2 * ch + 1][i][k]; + float qrim = Cldfb_ImagBuffer[2 * ch + 1][i][k]; + + Cldfb_RealBuffer[2 * ch][i][k] = qlre + qrre; + Cldfb_ImagBuffer[2 * ch][i][k] = qlim + qrim; + Cldfb_RealBuffer[2 * ch + 1][i][k] = qlre - qrre; + Cldfb_ImagBuffer[2 * ch + 1][i][k] = qlim - qrim; + } + } + + mvr2r( hMCParamUpmix->alphas[ch], hMCParamUpmix->alpha_prev[ch], IVAS_MAX_NUM_BANDS ); + mvr2r( hMCParamUpmix->betas[ch], hMCParamUpmix->beta_prev[ch], IVAS_MAX_NUM_BANDS ); + } + + if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) + { + maxBand = (int16_t) ( ( CLDFB_NO_CHANNELS_MAX * st_ivas->hDecoderConfig->output_Fs ) / 48000 ); + /* fastconv binaural rendering and CLDFB synthesis */ + for ( subframeIdx = 0; subframeIdx < ( CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES ); subframeIdx++ ) + { + index_slot = subframeIdx * MAX_PARAM_SPATIAL_SUBFRAMES; + /* cldfb analysis of non-coupled, non-LFE channels */ + idx_in = 0; + for ( ch = 0; ch < first_empty_channel - 2 * MC_PARAMUPMIX_COMBINATIONS; ch++ ) + { + if ( st_ivas->hIntSetup.index_lfe[0] != ch ) + { + pPcm_temp[ch] = output_f[ch]; + /* slot loop for gathering the input data */ + for ( slot_idx = 0; slot_idx < MAX_PARAM_SPATIAL_SUBFRAMES; slot_idx++ ) + { + cldfbAnalysis_ts( &( pPcm_temp[ch][hMCParamUpmix->num_freq_bands * ( index_slot + slot_idx )] ), + Cldfb_RealBuffer_subfr[idx_in][slot_idx], + Cldfb_ImagBuffer_subfr[idx_in][slot_idx], + maxBand, st_ivas->cldfbAnaDec[2 * MC_PARAMUPMIX_COMBINATIONS + idx_in] ); + } + idx_in++; + } + } + + /* copy and reorder cldfb analysis of coupled channels */ + for ( ch = 0; ch < MAX_PARAM_SPATIAL_SUBFRAMES; ch++ ) + { + for ( slot_idx = 0; slot_idx < MAX_PARAM_SPATIAL_SUBFRAMES; slot_idx++ ) + { + mvr2r( Cldfb_RealBuffer[MC_PARAMUPMIX_CHIDX1[ch]][index_slot + slot_idx], Cldfb_RealBuffer_subfr[idx_in][slot_idx], CLDFB_NO_CHANNELS_MAX ); + mvr2r( Cldfb_ImagBuffer[MC_PARAMUPMIX_CHIDX1[ch]][index_slot + slot_idx], Cldfb_ImagBuffer_subfr[idx_in][slot_idx], CLDFB_NO_CHANNELS_MAX ); + mvr2r( Cldfb_RealBuffer[MC_PARAMUPMIX_CHIDX2[ch]][index_slot + slot_idx], Cldfb_RealBuffer_subfr[idx_in + 1][slot_idx], CLDFB_NO_CHANNELS_MAX ); + mvr2r( Cldfb_ImagBuffer[MC_PARAMUPMIX_CHIDX2[ch]][index_slot + slot_idx], Cldfb_ImagBuffer_subfr[idx_in + 1][slot_idx], CLDFB_NO_CHANNELS_MAX ); + } + idx_in += 2; + } + + if ( st_ivas->hCombinedOrientationData && st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV ) + { + for ( slot_idx = 0; slot_idx < MAX_PARAM_SPATIAL_SUBFRAMES; slot_idx++ ) + { + ivas_param_mc_mc2sba_cldfb( st_ivas->hTransSetup, hMCParamUpmix->hoa_encoder, slot_idx, Cldfb_RealBuffer_subfr, Cldfb_ImagBuffer_subfr, maxBand, GAIN_LFE ); + } + } + +#ifdef SPLIT_REND_WITH_HEAD_ROT + /*LFE handling for split rendering cases*/ + if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { + +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( st_ivas->hSplitBinRend.hCldfbDataOut != NULL ) + { + for ( slot_idx = 0; slot_idx < MAX_PARAM_SPATIAL_SUBFRAMES; slot_idx++ ) + { + for ( ch = 0; ch < ( st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe ); ch++ ) + { + mvr2r( Cldfb_RealBuffer_subfr[ch][slot_idx], st_ivas->hSplitBinRend.hCldfbDataOut->Cldfb_RealBuffer[ch][( subframeIdx * JBM_CLDFB_SLOTS_IN_SUBFRAME ) + slot_idx], maxBand ); + mvr2r( Cldfb_ImagBuffer_subfr[ch][slot_idx], st_ivas->hSplitBinRend.hCldfbDataOut->Cldfb_ImagBuffer[ch][( subframeIdx * JBM_CLDFB_SLOTS_IN_SUBFRAME ) + slot_idx], maxBand ); + } + } + st_ivas->hSplitBinRend.hCldfbDataOut->config = st_ivas->hIntSetup.output_config; + } +#endif + } +#endif + + /* Implement binaural rendering */ + ivas_binRenderer( st_ivas->hBinRenderer, +#ifdef SPLIT_REND_WITH_HEAD_ROT + &st_ivas->hSplitBinRend.splitrend.multiBinPoseData, +#endif + st_ivas->hCombinedOrientationData, +#ifndef NONBE_UNIFIED_DECODING_PATHS + subframeIdx, +#endif + JBM_CLDFB_SLOTS_IN_SUBFRAME, +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + NULL, +#endif + Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, + Cldfb_RealBuffer_subfr, + Cldfb_ImagBuffer_subfr ); + +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { + int16_t pos_idx; + + for ( pos_idx = 0; pos_idx < st_ivas->hBinRenderer->numPoses; pos_idx++ ) + { + for ( slot_idx = 0; slot_idx < JBM_CLDFB_SLOTS_IN_SUBFRAME; slot_idx++ ) + { + for ( ch = 0; ch < st_ivas->hDecoderConfig->nchan_out; ch++ ) + { + mvr2r( Cldfb_RealBuffer_Binaural[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend.hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[( pos_idx * BINAURAL_CHANNELS ) + ch][( subframeIdx * JBM_CLDFB_SLOTS_IN_SUBFRAME ) + slot_idx], maxBand ); + mvr2r( Cldfb_ImagBuffer_Binaural[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend.hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[( pos_idx * BINAURAL_CHANNELS ) + ch][( subframeIdx * JBM_CLDFB_SLOTS_IN_SUBFRAME ) + slot_idx], maxBand ); + } + } + } + } +#endif + +#ifdef NONBE_UNIFIED_DECODING_PATHS + /* update combined orientation access index */ + ivas_combined_orientation_update_index( st_ivas->hCombinedOrientationData, maxBand * MAX_PARAM_SPATIAL_SUBFRAMES ); +#endif + + /* Implement CLDFB synthesis */ + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + float *RealBuffer[MAX_PARAM_SPATIAL_SUBFRAMES]; + float *ImagBuffer[MAX_PARAM_SPATIAL_SUBFRAMES]; + + for ( slot_idx = 0; slot_idx < MAX_PARAM_SPATIAL_SUBFRAMES; slot_idx++ ) + { +#ifdef SPLIT_REND_WITH_HEAD_ROT + RealBuffer[slot_idx] = Cldfb_RealBuffer_Binaural[0][ch][slot_idx]; + ImagBuffer[slot_idx] = Cldfb_ImagBuffer_Binaural[0][ch][slot_idx]; +#else + RealBuffer[slot_idx] = Cldfb_RealBuffer_Binaural[ch][slot_idx]; + ImagBuffer[slot_idx] = Cldfb_ImagBuffer_Binaural[ch][slot_idx]; +#endif + } + + cldfbSynthesis( RealBuffer, ImagBuffer, &( output_f[ch][index_slot * maxBand] ), maxBand * MAX_PARAM_SPATIAL_SUBFRAMES, st_ivas->cldfbSynDec[ch] ); + } + } + } + else + { + pPcm_temp[0] = output_f[4]; + pPcm_temp[1] = output_f[6]; + pPcm_temp[2] = output_f[5]; + pPcm_temp[3] = output_f[7]; + pPcm_temp[4] = output_f[8]; + pPcm_temp[5] = output_f[10]; + pPcm_temp[6] = output_f[9]; + pPcm_temp[7] = output_f[11]; + + /* CLDFB synthesis */ + for ( ch = 0; ch < MC_PARAMUPMIX_COMBINATIONS * 2; ch++ ) + { + for ( slot_idx = 0; slot_idx < CLDFB_NO_COL_MAX; slot_idx++ ) + { + float *ptr_im[1], *ptr_re[1]; + ptr_re[0] = Cldfb_RealBuffer[ch][slot_idx]; + ptr_im[0] = Cldfb_ImagBuffer[ch][slot_idx]; + + cldfbSynthesis( ptr_re, ptr_im, &( pPcm_temp[ch][hMCParamUpmix->num_freq_bands * slot_idx] ), + hMCParamUpmix->num_freq_bands, st_ivas->cldfbSynDec[ch] ); + } + } + + /* adjust delay of other channels */ + noparamupmix_delay = NS2SA( output_Fs, IVAS_FB_DEC_DELAY_NS ); + for ( ch = 0; ch < MC_PARAMUPMIX_COMBINATIONS; ch++ ) + { + float tmp_buf[L_SUBFRAME5MS_48k]; + mvr2r( &output_f[ch][output_frame - noparamupmix_delay], tmp_buf, noparamupmix_delay ); + mvr2r( output_f[ch], &output_f[ch][noparamupmix_delay], output_frame - noparamupmix_delay ); + mvr2r( hMCParamUpmix->pcm_delay[ch], output_f[ch], noparamupmix_delay ); + mvr2r( tmp_buf, hMCParamUpmix->pcm_delay[ch], noparamupmix_delay ); + } + } + } + + for ( ch = first_empty_channel; ch < ivas_get_nchan_buffers_dec( st_ivas, -1, -1 ); ch++ ) + { + set_f( output_f[ch], 0.0f, output_frame ); + } + + pop_wmops(); + return; +} +#endif /*------------------------------------------------------------------------- * ivas_mc_paramupmix_dec_digest_tc() @@ -198,6 +525,9 @@ void ivas_mc_paramupmix_dec_render( int16_t slots_to_render, first_sf, last_sf, subframe_idx; uint16_t slot_size, ch; float *output_f_local[MAX_OUTPUT_CHANNELS]; +#ifdef SPLIT_REND_WITH_HEAD_ROT + int16_t slot_index_start; +#endif MC_PARAMUPMIX_DEC_HANDLE hMCParamUpmix; hMCParamUpmix = st_ivas->hMCParamUpmix; @@ -228,6 +558,9 @@ void ivas_mc_paramupmix_dec_render( slots_to_render -= st_ivas->hTcBuffer->subframe_nbslots[last_sf]; last_sf++; } +#ifdef DEBUGGING + assert( slots_to_render == 0 ); +#endif { for ( ch = 0; ch < MC_PARAMUPMIX_COMBINATIONS; ch++ ) @@ -236,19 +569,34 @@ void ivas_mc_paramupmix_dec_render( mvr2r( hMCParamUpmix->beta_prev[ch], hMCParamUpmix->beta_sf[ch], IVAS_MAX_NUM_BANDS ); } +#ifdef SPLIT_REND_WITH_HEAD_ROT + slot_index_start = 0; +#endif for ( subframe_idx = first_sf; subframe_idx < last_sf; subframe_idx++ ) { int16_t n_samples_sf = slot_size * st_ivas->hTcBuffer->subframe_nbslots[subframe_idx]; +#ifdef SPLIT_REND_WITH_HEAD_ROT + ivas_mc_paramupmix_dec_sf( st_ivas, output_f_local, slot_index_start ); + + slot_index_start += st_ivas->hTcBuffer->subframe_nbslots[subframe_idx]; +#else ivas_mc_paramupmix_dec_sf( st_ivas, output_f_local ); +#endif +#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX for ( ch = 0; ch < min( MAX_OUTPUT_CHANNELS, ivas_get_nchan_buffers_dec( st_ivas, -1, -1 ) ); ch++ ) +#else + for ( ch = 0; ch < MAX_OUTPUT_CHANNELS; ch++ ) +#endif { output_f_local[ch] += n_samples_sf; } +#ifdef NONBE_UNIFIED_DECODING_PATHS /* update combined orientation access index */ ivas_combined_orientation_update_index( st_ivas->hCombinedOrientationData, n_samples_sf ); +#endif } for ( ch = 0; ch < MC_PARAMUPMIX_COMBINATIONS; ch++ ) @@ -303,6 +651,10 @@ ivas_error ivas_mc_paramupmix_dec_open( st_ivas->nSCE = 0; st_ivas->element_mode_init = IVAS_CPE_MDCT; break; +#ifdef DEBUGGING + default: + assert( 0 && "Number of TC not supported for MC ParamUpmix!" ); +#endif } hMCParamUpmix->hoa_encoder = NULL; @@ -341,6 +693,10 @@ ivas_error ivas_mc_paramupmix_dec_open( hMCParamUpmix->free_param_interpolator = 0; hMCParamUpmix->param_interpolator = NULL; +#ifndef NONBE_UNIFIED_DECODING_PATHS + if ( st_ivas->hDecoderConfig->Opt_5ms == 1 ) + { +#endif if ( ( hMCParamUpmix->param_interpolator = (float *) malloc( MAX_JBM_CLDFB_TIMESLOTS * sizeof( float ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for interpolator\n" ) ); @@ -348,8 +704,15 @@ ivas_error ivas_mc_paramupmix_dec_open( hMCParamUpmix->free_param_interpolator = 1; ivas_jbm_dec_get_adapted_linear_interpolator( DEFAULT_JBM_CLDFB_TIMESLOTS, DEFAULT_JBM_CLDFB_TIMESLOTS, hMCParamUpmix->param_interpolator ); +#ifndef NONBE_UNIFIED_DECODING_PATHS + } +#endif +#ifndef NONBE_UNIFIED_DECODING_PATHS + if ( st_ivas->hDecoderConfig->Opt_5ms == 1 && st_ivas->hTcBuffer == NULL ) +#else if ( st_ivas->hTcBuffer == NULL ) +#endif { int16_t nchan_to_allocate; int16_t nchan_tc; @@ -535,6 +898,70 @@ static void ivas_param_upmix_dec_decorr_subframes( /*****************************************************************************************/ /* local functions */ /*****************************************************************************************/ +#ifndef NONBE_UNIFIED_DECODING_PATHS_FIX +static void ps_pred_process( + MC_PARAMUPMIX_DEC_HANDLE hMCParamUpmix, + float qmf_mod_re[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* in/out */ + float qmf_mod_im[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + float qmf_side_re[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* in/out */ + float qmf_side_im[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + const int16_t ch ) +{ + float vmre, vmim, vsre, vsim; + int16_t iqmf, ipar, ismp, iismp; + float alpha_smp, dalpha, beta_smp, dbeta; + float *alpha1, *alpha2; + float *beta1, *beta2; + float *alpha_prev = hMCParamUpmix->alpha_prev[ch]; + float *beta_prev = hMCParamUpmix->beta_prev[ch]; + + const int16_t qmf_to_par_band[] = { + 0, 1, 2, 3, 4, 5, 5, 6, 6, 7, + 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, + 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 11, 11, 11, 11 + }; + + for ( iqmf = 0; iqmf < CLDFB_NO_CHANNELS_MAX; iqmf++ ) + { + /* For changing no of parameter bands (ipar1 != ipar2), TIGGER_FRAMING assumed */ + ipar = qmf_to_par_band[iqmf]; + alpha1 = alpha_prev; + beta1 = beta_prev; + + ismp = 0; + alpha2 = hMCParamUpmix->alphas[ch]; + beta2 = hMCParamUpmix->betas[ch]; + alpha_smp = alpha1[ipar]; + beta_smp = beta1[ipar]; + dalpha = ( alpha2[ipar] - alpha1[ipar] ) / CLDFB_NO_COL_MAX; + dbeta = ( beta2[ipar] - beta1[ipar] ) / CLDFB_NO_COL_MAX; + + for ( iismp = 0; iismp < CLDFB_NO_COL_MAX; iismp++ ) + { + alpha_smp += dalpha; + beta_smp += dbeta; + + vmre = qmf_mod_re[ismp][iqmf]; + vmim = qmf_mod_im[ismp][iqmf]; + vsre = qmf_side_re[ismp][iqmf]; + vsim = qmf_side_im[ismp][iqmf]; + + qmf_side_re[ismp][iqmf] = alpha_smp * vmre + beta_smp * vsre; + qmf_side_im[ismp][iqmf] = alpha_smp * vmim + beta_smp * vsim; + + ismp++; + } + + alpha1 = alpha2; + beta1 = beta2; + } + + return; +} +#endif static void ps_pred_process_sf( MC_PARAMUPMIX_DEC_HANDLE hMCParamUpmix, @@ -618,7 +1045,12 @@ static void ps_pred_process_sf( static void ivas_mc_paramupmix_dec_sf( Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + float *output_f[MAX_OUTPUT_CHANNELS], /* i/o: synthesized core-coder transport channels */ + const int16_t slot_index_start +#else float *output_f[MAX_OUTPUT_CHANNELS] /* i/o: synthesized core-coder transport channels */ +#endif ) { int16_t i, ch, slot_idx, k; @@ -631,8 +1063,13 @@ static void ivas_mc_paramupmix_dec_sf( int16_t subframeIdx, idx_in, maxBand; float Cldfb_RealBuffer_subfr[MAX_INTERN_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; float Cldfb_ImagBuffer_subfr[MAX_INTERN_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; +#ifdef SPLIT_REND_WITH_HEAD_ROT + float Cldfb_RealBuffer_Binaural[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; + float Cldfb_ImagBuffer_Binaural[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; +#else float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; +#endif hMCParamUpmix = st_ivas->hMCParamUpmix; assert( hMCParamUpmix ); @@ -728,15 +1165,57 @@ static void ivas_mc_paramupmix_dec_sf( } } +#ifdef SPLIT_REND_WITH_HEAD_ROT + /*LFE handling for split rendering cases*/ + if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { + if ( st_ivas->hSplitBinRend.hCldfbDataOut != NULL ) + { + for ( slot_idx = 0; slot_idx < st_ivas->hTcBuffer->subframe_nbslots[st_ivas->hTcBuffer->subframes_rendered]; slot_idx++ ) + { + for ( ch = 0; ch < ( st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe ); ch++ ) + { + mvr2r( Cldfb_RealBuffer_subfr[ch][slot_idx], st_ivas->hSplitBinRend.hCldfbDataOut->Cldfb_RealBuffer[ch][slot_index_start + slot_idx], maxBand ); + mvr2r( Cldfb_ImagBuffer_subfr[ch][slot_idx], st_ivas->hSplitBinRend.hCldfbDataOut->Cldfb_ImagBuffer[ch][slot_index_start + slot_idx], maxBand ); + } + } + + st_ivas->hSplitBinRend.hCldfbDataOut->config = st_ivas->hIntSetup.output_config; + } + } +#endif /* Implement binaural rendering */ ivas_binRenderer( st_ivas->hBinRenderer, +#ifdef SPLIT_REND_WITH_HEAD_ROT + &st_ivas->hSplitBinRend.splitrend.multiBinPoseData, +#endif st_ivas->hCombinedOrientationData, +#ifndef NONBE_UNIFIED_DECODING_PATHS + subframeIdx, +#endif st_ivas->hTcBuffer->subframe_nbslots[subframeIdx], Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, Cldfb_RealBuffer_subfr, Cldfb_ImagBuffer_subfr ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { + int16_t pos_idx; + for ( pos_idx = 0; pos_idx < st_ivas->hBinRenderer->numPoses; pos_idx++ ) + { + for ( slot_idx = 0; slot_idx < st_ivas->hTcBuffer->subframe_nbslots[subframeIdx]; slot_idx++ ) + { + for ( ch = 0; ch < st_ivas->hDecoderConfig->nchan_out; ch++ ) + { + mvr2r( Cldfb_RealBuffer_Binaural[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend.hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[( pos_idx * BINAURAL_CHANNELS ) + ch][slot_index_start + slot_idx], maxBand ); + mvr2r( Cldfb_ImagBuffer_Binaural[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend.hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[( pos_idx * BINAURAL_CHANNELS ) + ch][slot_index_start + slot_idx], maxBand ); + } + } + } + } +#endif /* Implement CLDFB synthesis */ for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) @@ -746,8 +1225,13 @@ static void ivas_mc_paramupmix_dec_sf( for ( slot_idx = 0; slot_idx < st_ivas->hTcBuffer->subframe_nbslots[subframeIdx]; slot_idx++ ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + RealBuffer[slot_idx] = Cldfb_RealBuffer_Binaural[0][ch][slot_idx]; + ImagBuffer[slot_idx] = Cldfb_ImagBuffer_Binaural[0][ch][slot_idx]; +#else RealBuffer[slot_idx] = Cldfb_RealBuffer_Binaural[ch][slot_idx]; ImagBuffer[slot_idx] = Cldfb_ImagBuffer_Binaural[ch][slot_idx]; +#endif } cldfbSynthesis( RealBuffer, ImagBuffer, &( output_f[ch][0] ), maxBand * st_ivas->hTcBuffer->subframe_nbslots[subframeIdx], st_ivas->cldfbSynDec[ch] ); @@ -812,6 +1296,53 @@ static void ivas_mc_paramupmix_dec_sf( return; } +#ifndef NONBE_UNIFIED_DECODING_PATHS_FIX +static void paramupmix_td_decorr_process( + ivas_td_decorr_state_t *hTdDecorr[], /* i/o: SPAR Covar. decoder handle */ + float *pcm_in[], /* i : input audio channels */ + float **pp_out_pcm, /* o : output audio channels */ + const int16_t output_frame /* i : output frame length */ +) +{ + int16_t j, k; + int16_t offset; + float in_duck_gain[L_FRAME48k], out_duck_gain[L_FRAME48k]; + + offset = (int16_t) ( output_frame * FRAMES_PER_SEC * IVAS_DECORR_PARM_LOOKAHEAD_TAU ); + + /* Look-ahead delay */ + for ( k = 0; k < MC_PARAMUPMIX_COMBINATIONS; k++ ) + { + mvr2r( pcm_in[k], pp_out_pcm[k], output_frame ); + delay_signal( pp_out_pcm[k], output_frame, hTdDecorr[k]->look_ahead_buf, offset ); + + /* In ducking gains */ + if ( hTdDecorr[k]->ducking_flag ) + { + ivas_td_decorr_get_ducking_gains( hTdDecorr[k]->pTrans_det, pcm_in[k], in_duck_gain, out_duck_gain, output_frame, 0 ); + + for ( j = 0; j < output_frame; j++ ) + { + pp_out_pcm[k][j] = pp_out_pcm[k][j] * in_duck_gain[j]; + } + } + + /* All pass delay section */ + ivas_td_decorr_APD_iir_filter( &hTdDecorr[k]->APD_filt_state[0], pp_out_pcm[k], hTdDecorr[k]->num_apd_sections, output_frame ); + + /* Out ducking gains */ + if ( hTdDecorr[k]->ducking_flag ) + { + for ( j = 0; j < output_frame; j++ ) + { + pp_out_pcm[k][j] = pp_out_pcm[k][j] * out_duck_gain[j]; + } + } + } + + return; +} +#endif static int16_t huff_read( Decoder_State *st, @@ -833,10 +1364,19 @@ static int16_t huff_read( static void huffman_decode( Decoder_State *st, +#ifndef FIX_891_PARAMUPMIX_CLEANUP + const int16_t nv, + const int16_t ivStart, const PAR_TYPE parType, + const QUANT_TYPE quant_type, + const int16_t bNoDt, +#else + const PAR_TYPE parType, +#endif int32_t *vq ) { const int16_t( *huff_node_table )[2]; +#ifdef FIX_891_PARAMUPMIX_CLEANUP int16_t iv, nquant, offset; nquant = 0; @@ -853,8 +1393,38 @@ static void huffman_decode( } offset = nquant - 1; /* range of df [-(nquant - 1), nquant - 1] */ +#else + int16_t iv, bdt, nquant, offset; + nquant = 0; + switch ( parType ) + { + case ALPHA: + nquant = ivas_mc_paramupmix_alpha_quant_table[quant_type].nquant; + break; + case BETA: + nquant = ivas_mc_paramupmix_beta_quant_table[quant_type][0].nquant; + break; + default: + assert( 0 ); + } + + offset = nquant - 1; /* range of df/dt [-(nquant - 1), nquant - 1] */ +#endif +#ifdef FIX_891_PARAMUPMIX_CLEANUP st->next_bit_pos++; +#else + if ( bNoDt ) + { + bdt = 0; + } + else + { + bdt = st->bit_stream[st->next_bit_pos]; + st->next_bit_pos++; + } +#endif +#ifdef FIX_891_PARAMUPMIX_CLEANUP switch ( parType ) { case ALPHA: @@ -885,16 +1455,76 @@ static void huffman_decode( { vq[iv] = huff_read( st, huff_node_table ) + vq[iv - 1] - offset; } +#else + if ( bdt ) + { /* Get dt */ + switch ( parType ) + { + case ALPHA: + huff_node_table = ivas_mc_paramupmix_huff_nodes_dt.alpha[quant_type]; + break; + case BETA: + huff_node_table = ivas_mc_paramupmix_huff_nodes_dt.beta[quant_type]; + break; + default: + huff_node_table = NULL; + assert( 0 ); + } + for ( iv = ivStart; iv < nv; iv++ ) + { + vq[iv] = huff_read( st, huff_node_table ) + vq[iv] - offset; + } + } + else /* Get f0, df */ + { + switch ( parType ) + { + case ALPHA: + huff_node_table = ivas_mc_paramupmix_huff_nodes_df0.alpha[quant_type]; + break; + case BETA: + huff_node_table = ivas_mc_paramupmix_huff_nodes_df0.beta[quant_type]; + break; + default: + huff_node_table = NULL; + assert( 0 ); + } + vq[ivStart] = huff_read( st, huff_node_table ); + + switch ( parType ) + { + case ALPHA: + huff_node_table = ivas_mc_paramupmix_huff_nodes_df.alpha[quant_type]; + break; + case BETA: + huff_node_table = ivas_mc_paramupmix_huff_nodes_df.beta[quant_type]; + break; + default: + assert( 0 ); + } + + for ( iv = ivStart + 1; iv < nv; iv++ ) + { + vq[iv] = huff_read( st, huff_node_table ) + vq[iv - 1] - offset; + } + } +#endif return; } static void dequant_alpha( +#ifndef FIX_891_PARAMUPMIX_CLEANUP + const int16_t nv, + const int16_t ivStart, + const QUANT_TYPE quant_type, +#endif int32_t *vq, float *v ) { int16_t iv; +#ifdef FIX_891_PARAMUPMIX_CLEANUP const ACPL_QUANT_TABLE *quant_table = &ivas_mc_paramupmix_alpha_quant_table; for ( iv = 0; iv < IVAS_MAX_NUM_BANDS; iv++ ) @@ -902,11 +1532,29 @@ static void dequant_alpha( v[iv] = quant_table->data[vq[iv]]; } +#else + const ACPL_QUANT_TABLE *quant_table = &ivas_mc_paramupmix_alpha_quant_table[quant_type]; + + for ( iv = 0; iv < ivStart; iv++ ) + { + v[iv] = 0; + } + + for ( iv = ivStart; iv < nv; iv++ ) + { + v[iv] = quant_table->data[vq[iv]]; + } +#endif return; } static void dequant_beta( +#ifndef FIX_891_PARAMUPMIX_CLEANUP + const int16_t nv, + const int16_t ivStart, + const QUANT_TYPE quant_type, +#endif int32_t *aq, int32_t *bq, float *beta ) @@ -914,12 +1562,25 @@ static void dequant_beta( int16_t iv; const ACPL_QUANT_TABLE *quant_table; +#ifdef FIX_891_PARAMUPMIX_CLEANUP for ( iv = 0; iv < IVAS_MAX_NUM_BANDS; iv++ ) { quant_table = &ivas_mc_paramupmix_beta_quant_table[ivas_param_upmx_mx_qmap[aq[iv]]]; beta[iv] = quant_table->data[bq[iv]]; } +#else + for ( iv = 0; iv < ivStart; iv++ ) + { + beta[iv] = 0; + } + + for ( iv = ivStart; iv < nv; iv++ ) + { + quant_table = &ivas_mc_paramupmix_beta_quant_table[quant_type][ivas_param_upmx_mx_qmap[quant_type][aq[iv]]]; + beta[iv] = quant_table->data[bq[iv]]; + } +#endif return; } @@ -927,20 +1588,38 @@ static void dequant_beta( static void get_ec_data( Decoder_State *st, const PAR_TYPE parType, +#ifndef FIX_891_PARAMUPMIX_CLEANUP + const QUANT_TYPE quant_type, + const int16_t nParBand, + const int16_t parBandStart, +#endif int32_t *parQ, int32_t *alphaQEnv, float ab[IVAS_MAX_NUM_BANDS] ) { +#ifdef FIX_891_PARAMUPMIX_CLEANUP huffman_decode( st, parType, parQ ); +#else + huffman_decode( st, nParBand, parBandStart, parType, quant_type, 0, parQ ); +#endif if ( parType == ALPHA ) { +#ifdef FIX_891_PARAMUPMIX_CLEANUP dequant_alpha( parQ, ab ); mvl2l( parQ, alphaQEnv, (int16_t) IVAS_MAX_NUM_BANDS ); +#else + dequant_alpha( nParBand, parBandStart, quant_type, parQ, ab ); + mvl2l( parQ, alphaQEnv, (int16_t) nParBand ); +#endif } else { +#ifdef FIX_891_PARAMUPMIX_CLEANUP dequant_beta( alphaQEnv, parQ, ab ); +#else + dequant_beta( nParBand, parBandStart, quant_type, alphaQEnv, parQ, ab ); +#endif } return; diff --git a/lib_dec/ivas_mcmasa_dec.c b/lib_dec/ivas_mcmasa_dec.c index 832572ded..14db85a00 100644 --- a/lib_dec/ivas_mcmasa_dec.c +++ b/lib_dec/ivas_mcmasa_dec.c @@ -36,6 +36,9 @@ #include "ivas_prot.h" #include "ivas_prot_rend.h" #include "prot.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" diff --git a/lib_dec/ivas_mct_core_dec.c b/lib_dec/ivas_mct_core_dec.c index 7364813ff..faffe1a1b 100644 --- a/lib_dec/ivas_mct_core_dec.c +++ b/lib_dec/ivas_mct_core_dec.c @@ -35,6 +35,9 @@ #include "options.h" #include "prot.h" #include "rom_com.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" #include "cnst.h" #include "basop_proto_func.h" diff --git a/lib_dec/ivas_mct_dec.c b/lib_dec/ivas_mct_dec.c index 0212b00b5..167d8b672 100644 --- a/lib_dec/ivas_mct_dec.c +++ b/lib_dec/ivas_mct_dec.c @@ -41,14 +41,24 @@ #include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_rom_com.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" +#ifdef DEBUG_PLOT +#include "deb_out.h" +#endif /*-----------------------------------------------------------------------* * Local function prototypes *-----------------------------------------------------------------------*/ +#ifdef SPLIT_REND_WITH_HEAD_ROT +static ivas_error ivas_mc_dec_reconfig( Decoder_Struct *st_ivas, uint16_t *nSamplesRendered, const PCM_RESOLUTION pcm_resolution, void *data ); +#else static ivas_error ivas_mc_dec_reconfig( Decoder_Struct *st_ivas, uint16_t *nSamplesRendered, int16_t *data ); +#endif /*--------------------------------------------------------------------------* @@ -248,6 +258,9 @@ ivas_error ivas_mct_dec( /* CoreCoder common updates */ updt_dec_common( sts[n], NORMAL_HQ_CORE, -1, output[cpe_id * CPE_CHANNELS + n] ); +#ifdef DEBUG_PLOT + sendDebout( "mct_synth", output_frame, 1, "aftPostPro", MTV_FLOAT, output[cpe_id * CPE_CHANNELS + n] ); +#endif } /* n_channels loop */ @@ -257,6 +270,13 @@ ivas_error ivas_mct_dec( synchro_synthesis( ivas_total_brate, hCPE, output + cpe_id * CPE_CHANNELS, output_frame, 0 ); } +#ifdef DEBUG_PLOT + for ( n = 0; n < CPE_CHANNELS; n++ ) + { + setDeboutVars( -1, -1, n, cpe_id ); + sendDebout( "mct_synth", output_frame, 1, "aftSynchro", MTV_FLOAT, output[cpe_id * CPE_CHANNELS + n] ); + } +#endif } /* move channels after LFE to correct output for multi-channel MCT */ @@ -277,6 +297,18 @@ ivas_error ivas_mct_dec( mvr2r( output_lfe_ch, output[LFE_CHANNEL], output_frame ); } +#ifdef DEBUG_MODE_INFO + for ( cpe_id = 0; cpe_id < nCPE; cpe_id++ ) + { + float tmpF = st_ivas->hCPE[cpe_id]->element_brate / 1000.0f; + dbgwrite( &tmpF, sizeof( float ), 1, output_frame, fname( debug_dir, "element_brate", 0, cpe_id, DEC ) ); + + dbgwrite( output[0], sizeof( float ), output_frame, 1, fname( debug_dir, "output.mct", 0, cpe_id, DEC ) ); + tmpF = 0; + dbgwrite( &tmpF, sizeof( float ), 1, output_frame, fname( debug_dir, "output.sce", 0, cpe_id, DEC ) ); + dbgwrite( &tmpF, sizeof( float ), 1, output_frame, fname( debug_dir, "output.cpe", 0, cpe_id, DEC ) ); + } +#endif pop_wmops(); return error; @@ -617,7 +649,12 @@ ivas_error ivas_mc_dec_config( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ const int16_t idx, /* i : LS config. index */ uint16_t *nSamplesRendered, /* o : samples flushed from last frame (JBM) */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + const PCM_RESOLUTION pcm_resolution, /* i : type for the decoded PCM resolution */ + void *data /* o : output synthesis signal */ +#else int16_t *data /* o : output synthesis signal */ +#endif ) { AUDIO_CONFIG signaled_config; @@ -645,7 +682,11 @@ ivas_error ivas_mc_dec_config( { if ( st_ivas->hDecoderConfig->last_ivas_total_brate != st_ivas->hDecoderConfig->ivas_total_brate || st_ivas->transport_config != signaled_config || last_mc_mode != st_ivas->mc_mode ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( error = ivas_mc_dec_reconfig( st_ivas, nSamplesRendered, pcm_resolution, data ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_mc_dec_reconfig( st_ivas, nSamplesRendered, data ) ) != IVAS_ERR_OK ) +#endif { return error; @@ -669,7 +710,12 @@ ivas_error ivas_mc_dec_config( static ivas_error ivas_mc_dec_reconfig( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ uint16_t *nSamplesRendered, /* o : number of samples flushed from the last frame (JBM) */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + const PCM_RESOLUTION pcm_resolution, /* i : type for the decoded PCM resolution */ + void *data /* o : output synthesis signal */ +#else int16_t *data /* o : output synthesis signal */ +#endif ) { int16_t nchan_transport_old, nSCE_old, nCPE_old, sba_dirac_stereo_flag_old, nchan_hp20_old; @@ -727,6 +773,10 @@ static ivas_error ivas_mc_dec_reconfig( /* side effect of the renderer selection can be a changed internal config */ ivas_output_init( &( st_ivas->hIntSetup ), st_ivas->intern_config ); +#ifndef NONBE_UNIFIED_DECODING_PATHS + if ( st_ivas->hDecoderConfig->Opt_5ms ) + { +#endif /* transfer subframe info from DirAC or ParamMC to central tc buffer */ if ( last_mc_mode == MC_MODE_PARAMMC ) { @@ -750,7 +800,11 @@ static ivas_error ivas_mc_dec_reconfig( tc_granularity_new = ivas_jbm_dec_get_render_granularity( st_ivas->renderer_type, st_ivas->ivas_format, st_ivas->mc_mode, st_ivas->hDecoderConfig->output_Fs ); if ( tc_granularity_new < st_ivas->hTcBuffer->n_samples_granularity ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( error = ivas_jbm_dec_flush_renderer( st_ivas, tc_granularity_new, renderer_type_old, intern_config_old, &hIntSetupOld, last_mc_mode, ISM_MODE_NONE, nSamplesRendered, pcm_resolution, data ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_jbm_dec_flush_renderer( st_ivas, tc_granularity_new, renderer_type_old, intern_config_old, &hIntSetupOld, last_mc_mode, ISM_MODE_NONE, nSamplesRendered, data ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -763,6 +817,9 @@ static ivas_error ivas_mc_dec_reconfig( return error; } } +#ifndef NONBE_UNIFIED_DECODING_PATHS + } +#endif if ( st_ivas->mc_mode == MC_MODE_MCT ) { @@ -843,6 +900,12 @@ static ivas_error ivas_mc_dec_reconfig( return error; } } +#ifdef DEBUGGING + else + { + assert( 0 ); + } +#endif } else if ( st_ivas->mc_mode == MC_MODE_PARAMMC ) { @@ -1124,6 +1187,9 @@ static ivas_error ivas_mc_dec_reconfig( /* binaural renderers*/ if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB +#ifdef SPLIT_REND_WITH_HEAD_ROT + || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM +#endif ) { /* remove unneeded binaural renderers */ @@ -1132,10 +1198,18 @@ static ivas_error ivas_mc_dec_reconfig( ivas_binRenderer_close( &st_ivas->hBinRenderer ); } +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( st_ivas->hCrendWrapper != NULL ) && ( st_ivas->hCrendWrapper->hCrend[0] != NULL ) && ( st_ivas->renderer_type != RENDERER_BINAURAL_MIXER_CONV && st_ivas->renderer_type != RENDERER_BINAURAL_MIXER_CONV_ROOM && ( st_ivas->renderer_type != RENDERER_BINAURAL_OBJECTS_TD || st_ivas->hIntSetup.output_config != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ) ) +#else if ( ( st_ivas->hCrendWrapper != NULL ) && ( st_ivas->hCrendWrapper->hCrend != NULL ) && ( st_ivas->renderer_type != RENDERER_BINAURAL_MIXER_CONV && st_ivas->renderer_type != RENDERER_BINAURAL_MIXER_CONV_ROOM && ( st_ivas->renderer_type != RENDERER_BINAURAL_OBJECTS_TD || st_ivas->hIntSetup.output_config != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ) ) +#endif { +#ifdef SPLIT_REND_WITH_HEAD_ROT + ivas_rend_closeCrend( &( st_ivas->hCrendWrapper ), st_ivas->hSplitBinRend.splitrend.multiBinPoseData.num_poses ); +#else ivas_rend_closeCrend( &( st_ivas->hCrendWrapper ) ); +#endif } if ( st_ivas->hBinRendererTd != NULL && ( st_ivas->renderer_type != RENDERER_BINAURAL_OBJECTS_TD ) ) @@ -1144,11 +1218,19 @@ static ivas_error ivas_mc_dec_reconfig( st_ivas->hHrtfTD = NULL; } +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( st_ivas->hDiracDecBin[0] != NULL ) +#else if ( st_ivas->hDiracDecBin != NULL ) +#endif { if ( st_ivas->renderer_type != RENDERER_BINAURAL_PARAMETRIC && st_ivas->renderer_type != RENDERER_BINAURAL_PARAMETRIC_ROOM && st_ivas->renderer_type != RENDERER_STEREO_PARAMETRIC ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + ivas_dirac_dec_close_binaural_data( st_ivas->hDiracDecBin ); +#else ivas_dirac_dec_close_binaural_data( &st_ivas->hDiracDecBin ); +#endif } } @@ -1169,22 +1251,39 @@ static ivas_error ivas_mc_dec_reconfig( if ( st_ivas->hIntSetup.output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( error = ivas_rend_initCrendWrapper( &st_ivas->hCrendWrapper, 1 ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_rend_initCrendWrapper( &st_ivas->hCrendWrapper ) ) != IVAS_ERR_OK ) +#endif { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Crend Wrapper\n" ); } +#ifdef SPLIT_REND_WITH_HEAD_ROT + st_ivas->hCrendWrapper->hCrend[0] = NULL; + st_ivas->hCrendWrapper->hHrtfCrend = NULL; + if ( ( st_ivas->hCrendWrapper->hCrend[0] = (CREND_HANDLE) malloc( sizeof( CREND_DATA ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Crend\n" ); + } +#else st_ivas->hCrendWrapper->hCrend = NULL; st_ivas->hCrendWrapper->hHrtfCrend = NULL; if ( ( st_ivas->hCrendWrapper->hCrend = (CREND_HANDLE) malloc( sizeof( CREND_DATA ) ) ) == NULL ) { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Crend\n" ); } +#endif } } else if ( st_ivas->hCrendWrapper == NULL && ( st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV || st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV_ROOM ) ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( error = ivas_rend_openCrend( &( st_ivas->hCrendWrapper ), st_ivas->intern_config, st_ivas->hDecoderConfig->output_config, st_ivas->hRenderConfig, st_ivas->hSetOfHRTF, st_ivas->hDecoderConfig->output_Fs, st_ivas->hSplitBinRend.splitrend.multiBinPoseData.num_poses ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_rend_openCrend( &( st_ivas->hCrendWrapper ), st_ivas->intern_config, st_ivas->hDecoderConfig->output_config, st_ivas->hRenderConfig, st_ivas->hSetOfHRTF, st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -1199,7 +1298,18 @@ static ivas_error ivas_mc_dec_reconfig( /* LS */ else if ( output_config == IVAS_AUDIO_CONFIG_5_1 || output_config == IVAS_AUDIO_CONFIG_5_1_2 || output_config == IVAS_AUDIO_CONFIG_5_1_4 || output_config == IVAS_AUDIO_CONFIG_7_1 || output_config == IVAS_AUDIO_CONFIG_7_1_4 || output_config == IVAS_AUDIO_CONFIG_LS_CUSTOM ) { +#ifdef DEBUGGING + assert( st_ivas->renderer_type == RENDERER_MC || st_ivas->renderer_type == RENDERER_MC_PARAMMC || st_ivas->renderer_type == RENDERER_DIRAC || st_ivas->renderer_type == RENDERER_DISABLE ); +#endif + } +#ifdef DEBUGGING + else if ( output_config == IVAS_AUDIO_CONFIG_FOA || output_config == IVAS_AUDIO_CONFIG_HOA2 || output_config == IVAS_AUDIO_CONFIG_HOA3 ) + { + /* FOA/HOA output */ + /* Nothing to do, renderer is always RENDERER_SBA_LINEAR_ENC */ + assert( st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC && renderer_type_old == RENDERER_SBA_LINEAR_ENC ); } +#endif } /*-----------------------------------------------------------------* @@ -1215,6 +1325,9 @@ static ivas_error ivas_mc_dec_reconfig( * JBM TC buffers *-----------------------------------------------------------------*/ +#ifndef NONBE_UNIFIED_DECODING_PATHS + if ( st_ivas->hDecoderConfig->Opt_5ms == 1 ) +#endif { int16_t tc_nchan_full_new; DECODER_TC_BUFFER_HANDLE hTcBuffer; @@ -1282,12 +1395,19 @@ static ivas_error ivas_mc_dec_reconfig( * floating-point output audio buffers *-----------------------------------------------------------------*/ +#ifndef NONBE_UNIFIED_DECODING_PATHS + if ( !st_ivas->hDecoderConfig->Opt_5ms ) + { +#endif nchan_out_buff = ivas_get_nchan_buffers_dec( st_ivas, -1, -1 ); if ( ( error = ivas_output_buff_dec( st_ivas->p_output_f, nchan_out_buff_old, nchan_out_buff ) ) != IVAS_ERR_OK ) { return error; } +#ifndef NONBE_UNIFIED_DECODING_PATHS + } +#endif return error; } diff --git a/lib_dec/ivas_mdct_core_dec.c b/lib_dec/ivas_mdct_core_dec.c index 7209018d1..3e6d630a8 100644 --- a/lib_dec/ivas_mdct_core_dec.c +++ b/lib_dec/ivas_mdct_core_dec.c @@ -36,6 +36,9 @@ #include "prot.h" #include "rom_com.h" #include "ivas_rom_com.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" #include "cnst.h" #include "basop_proto_func.h" @@ -106,6 +109,12 @@ static void dec_prm_tcx_sidebits( { CONTEXT_HM_CONFIG hm_cfg; int16_t start_bit_pos; +#ifdef DEBUG_MODE_TCX + int16_t bits_common; + static FILE *pF = NULL; + if ( pF == NULL ) + pF = fopen( "./res/stereo_tcx_dec_ind.txt", "w" ); +#endif /*--------------------------------------------------------------------------------* * Initialization @@ -214,12 +223,21 @@ static void dec_prm_tcx_spec( int16_t target_bitsTCX10[NB_DIV]; int16_t indexBuffer[N_MAX + 1]; CONTEXT_HM_CONFIG hm_cfg; +#ifdef DEBUG_MODE_TCX + static FILE *pF = NULL; + if ( pF == NULL ) + pF = fopen( "./res/stereo_tcx_dec_ind.txt", "w" ); +#endif /*--------------------------------------------------------------------------------* * Initialization *--------------------------------------------------------------------------------*/ hm_cfg.indexBuffer = indexBuffer; +#ifdef DEBUG_MODE_TCX + fprintf( pF, "== stereo Chan %d - Nominal Bits %d - Allocated Bits %d ==\n", st->idchan, st->bits_frame_nominal, (int16_t) ( st->total_brate / FRAMES_PER_SEC ) ); + fprintf( pF, "stereo Common Header: %d bits\n", st->next_bit_pos ); +#endif start_bit_pos = st->next_bit_pos; @@ -268,7 +286,11 @@ static void dec_prm_tcx_spec( void ivas_mdct_dec_side_bits_frame_channel( CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ +#ifdef FIX_887_ARRAY_SIZE_DFT_MDCT_STEREO int16_t param_lpc[CPE_CHANNELS][NPRM_LPC_NEW], /* o : lpc_parameters */ +#else + int16_t param_lpc[MCT_MAX_CHANNELS][NPRM_LPC_NEW], /* o : lpc_parameters */ +#endif int16_t p_param[CPE_CHANNELS][NB_DIV], /* o : pointer to param buffer */ Decoder_State *st0, /* i : pointer to bitstream handle */ int16_t nTnsBitsTCX10[CPE_CHANNELS][NB_DIV], /* o : number of bits for TNS */ @@ -923,6 +945,34 @@ void ivas_mdct_core_reconstruct( mvr2r( synthFB, signal_outFB[ch], st->hTcxDec->L_frameTCX ); } +#ifdef DEBUG_PLC_INFO + { + int16_t i; + int16_t tmp[L_FRAME48k]; + static FILE *sP = NULL; + + for ( i = 0; i < st->hTcxDec->L_frameTCX; i++ ) + { + tmp[i] = (int16_t) ( signal_outFB[ch][i] + 0.5f ); + } + if ( ch == 0 ) + { + dbgwrite( tmp, sizeof( int16_t ), st->hTcxDec->L_frameTCX, 1, "./res/mdct_stereo_dec_synthFB_ch0.pcm" ); +#ifndef DEBUG_MODE_INFO + dbgwrite( &st->bfi, sizeof( int16_t ), 1, st->hTcxDec->L_frameTCX, "./res/bfi.pcm" ); +#endif + dbgwrite( &st->tonal_mdct_plc_active, sizeof( int16_t ), 1, L_frameTCX[ch], "./res/tonal_mdct_active_ch0.pcm" ); + dbgwrite( &st->tonal_mdct_plc_active, sizeof( int16_t ), 1, L_frameTCX[ch], "./res/tonal_mdct_active_ch0.pcm" ); + dbgwrite( &st->con_tcx, sizeof( int16_t ), 1, 640, "./res/con_tcx_ch0.pcm" ); + } + else + { + dbgwrite( tmp, sizeof( int16_t ), st->hTcxDec->L_frameTCX, 1, "./res/mdct_stereo_dec_synthFB_ch1.pcm" ); + dbgwrite( &st->tonal_mdct_plc_active, sizeof( int16_t ), 1, L_frameTCX[ch], "./res/tonal_mdct_active_ch1.pcm" ); + dbgwrite( &st->con_tcx, sizeof( int16_t ), 1, 640, "./res/con_tcx_ch1.pcm" ); + } + } +#endif /* updates */ st->last_voice_factor = 0.0f; diff --git a/lib_dec/ivas_objectRenderer_internal.c b/lib_dec/ivas_objectRenderer_internal.c index c05cd617a..a0f522711 100644 --- a/lib_dec/ivas_objectRenderer_internal.c +++ b/lib_dec/ivas_objectRenderer_internal.c @@ -37,6 +37,9 @@ #include "ivas_prot_rend.h" #include #include "ivas_rom_com.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" @@ -95,8 +98,16 @@ ivas_error ivas_td_binaural_renderer( ism_md_subframe_update = 2; } +#ifdef NONBE_UNIFIED_DECODING_PATHS return ivas_td_binaural_renderer_unwrap( st_ivas->hReverb, st_ivas->transport_config, st_ivas->hBinRendererTd, nchan_transport, LFE_CHANNEL, st_ivas->ivas_format, st_ivas->hIsmMetaData, st_ivas->hCombinedOrientationData, ism_md_subframe_update, output, output_frame, MAX_PARAM_SPATIAL_SUBFRAMES ); +#else + return ivas_td_binaural_renderer_unwrap( st_ivas->hReverb, st_ivas->transport_config, st_ivas->hBinRendererTd, nchan_transport, LFE_CHANNEL, st_ivas->ivas_format, st_ivas->hIsmMetaData, + ( st_ivas->hCombinedOrientationData != NULL ) ? st_ivas->hCombinedOrientationData->enableCombinedOrientation : NULL, + ( st_ivas->hCombinedOrientationData != NULL ) ? st_ivas->hCombinedOrientationData->Quaternions : NULL, + ( st_ivas->hCombinedOrientationData != NULL ) ? st_ivas->hCombinedOrientationData->listenerPos : NULL, + ism_md_subframe_update, output, output_frame, MAX_PARAM_SPATIAL_SUBFRAMES ); +#endif } @@ -215,9 +226,15 @@ ivas_error ivas_td_binaural_renderer_sf( /* Update the listener's location/orientation */ if ( ( error = TDREND_Update_listener_orientation( st_ivas->hBinRendererTd, +#ifdef NONBE_UNIFIED_DECODING_PATHS ( st_ivas->hCombinedOrientationData != NULL ) ? st_ivas->hCombinedOrientationData->enableCombinedOrientation[st_ivas->hCombinedOrientationData->subframe_idx] : 0, ( st_ivas->hCombinedOrientationData != NULL ) ? &st_ivas->hCombinedOrientationData->Quaternions[st_ivas->hCombinedOrientationData->subframe_idx] : NULL, ( st_ivas->hCombinedOrientationData != NULL ) ? &st_ivas->hCombinedOrientationData->listenerPos[st_ivas->hCombinedOrientationData->subframe_idx] : NULL +#else + ( st_ivas->hCombinedOrientationData != NULL ) ? st_ivas->hCombinedOrientationData->enableCombinedOrientation[subframe_idx] : 0, + ( st_ivas->hCombinedOrientationData != NULL ) ? st_ivas->hCombinedOrientationData->Quaternions : NULL, + ( st_ivas->hCombinedOrientationData != NULL ) ? st_ivas->hCombinedOrientationData->listenerPos : NULL +#endif ) ) != IVAS_ERR_OK ) { return error; @@ -257,8 +274,10 @@ ivas_error ivas_td_binaural_renderer_sf( output_f_local[ch] += output_frame; } +#ifdef NONBE_UNIFIED_DECODING_PATHS /* update combined orientation access index */ ivas_combined_orientation_update_index( st_ivas->hCombinedOrientationData, output_frame ); +#endif } st_ivas->hTcBuffer->subframes_rendered = last_sf; @@ -267,3 +286,143 @@ ivas_error ivas_td_binaural_renderer_sf( } +#ifdef NONBE_UNIFIED_DECODING_PATHS +#ifdef SPLIT_REND_WITH_HEAD_ROT +/*---------------------------------------------------------------------* + * ivas_td_binaural_renderer_sf_splitBinaural() + * + * Render to multiple binaural pairs based on relative head positions for split rendering. + *---------------------------------------------------------------------*/ + +ivas_error ivas_td_binaural_renderer_sf_splitBinaural( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + float *output[], /* i/o: SCE channels / Binaural synthesis */ + int16_t nSamplesRendered /* i : number of samples to render */ +) +{ + int16_t i; + int16_t pos_idx; + IVAS_QUATERNION originalHeadRot[MAX_PARAM_SPATIAL_SUBFRAMES]; + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData; + BINAURAL_TD_OBJECT_RENDERER_HANDLE origTdRendHandle; + ivas_error error; + int16_t original_subframes_rendered; + int16_t original_slots_rendered; + float *p_bin_output[BINAURAL_CHANNELS]; +#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX + float output_local[MAX_OUTPUT_CHANNELS][L_FRAME48k]; // VE2SB: TBV +#endif + + push_wmops( "ivas_td_binaural_renderer_sf_splitBinaural" ); + pMultiBinPoseData = &st_ivas->hSplitBinRend.splitrend.multiBinPoseData; + + /* If not yet allocated, open additional instances of TD renderer */ + for ( i = 0; i < pMultiBinPoseData->num_poses - 1; ++i ) + { + if ( st_ivas->hSplitBinRend.splitrend.hTdRendHandles[i] != NULL ) + { + continue; + } + + if ( ( error = ivas_td_binaural_open_unwrap( &st_ivas->hHrtfTD, + st_ivas->hDecoderConfig->output_Fs, + st_ivas->nchan_transport, + st_ivas->ivas_format, + st_ivas->transport_config, + st_ivas->hRenderConfig->directivity, + st_ivas->hTransSetup, + &st_ivas->hSplitBinRend.splitrend.hTdRendHandles[i], + &st_ivas->binaural_latency_ns ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + /* Save current head positions */ + for ( i = 0; i < st_ivas->hCombinedOrientationData->num_subframes; ++i ) + { + originalHeadRot[i] = st_ivas->hCombinedOrientationData->Quaternions[i]; + } + + original_subframes_rendered = st_ivas->hTcBuffer->subframes_rendered; + original_slots_rendered = st_ivas->hTcBuffer->slots_rendered; + origTdRendHandle = st_ivas->hBinRendererTd; + + for ( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses; pos_idx++ ) + { + /* Update head positions */ + if ( pos_idx != 0 ) + { + for ( i = 0; i < st_ivas->hCombinedOrientationData->num_subframes; ++i ) + { + if ( originalHeadRot[i].w == -3.0f ) + { + st_ivas->hCombinedOrientationData->Quaternions[i].w = -3.0f; + st_ivas->hCombinedOrientationData->Quaternions[i].x = originalHeadRot[i].x + pMultiBinPoseData->relative_head_poses[pos_idx][0]; + st_ivas->hCombinedOrientationData->Quaternions[i].y = originalHeadRot[i].y + pMultiBinPoseData->relative_head_poses[pos_idx][1]; + st_ivas->hCombinedOrientationData->Quaternions[i].z = originalHeadRot[i].z + pMultiBinPoseData->relative_head_poses[pos_idx][2]; + } + else + { + st_ivas->hCombinedOrientationData->Quaternions[i].w = -3.0f; + + Quat2EulerDegree( originalHeadRot[i], /* TODO tmu : fix bug with ordering*/ + &st_ivas->hCombinedOrientationData->Quaternions[i].z, + &st_ivas->hCombinedOrientationData->Quaternions[i].y, + &st_ivas->hCombinedOrientationData->Quaternions[i].x ); + + st_ivas->hCombinedOrientationData->Quaternions[i].x += pMultiBinPoseData->relative_head_poses[pos_idx][0]; + st_ivas->hCombinedOrientationData->Quaternions[i].y += pMultiBinPoseData->relative_head_poses[pos_idx][1]; + st_ivas->hCombinedOrientationData->Quaternions[i].z += pMultiBinPoseData->relative_head_poses[pos_idx][2]; + } + } + } + + /* set output channels */ + for ( i = 0; i < BINAURAL_CHANNELS; i++ ) + { +#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX + p_bin_output[i] = output_local[pos_idx * BINAURAL_CHANNELS + i]; +#else + p_bin_output[i] = output[pos_idx * BINAURAL_CHANNELS + i]; +#endif + } + st_ivas->hTcBuffer->subframes_rendered = original_subframes_rendered; + st_ivas->hTcBuffer->slots_rendered = original_slots_rendered; + + /* update combined orientation access index */ + ivas_combined_orientation_set_to_start_index( st_ivas->hCombinedOrientationData ); + + /* Render */ + if ( pos_idx != 0 ) + { + st_ivas->hBinRendererTd = st_ivas->hSplitBinRend.splitrend.hTdRendHandles[pos_idx - 1]; + } + + if ( ( error = ivas_td_binaural_renderer_sf( st_ivas, p_bin_output, nSamplesRendered ) ) != IVAS_ERR_OK ) + { + return error; + } + } + +#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX + for ( i = 0; i < pMultiBinPoseData->num_poses * BINAURAL_CHANNELS; i++ ) + { + mvr2r( output_local[i], output[i], nSamplesRendered ); + } +#endif + + /* Restore original head rotation */ + for ( i = 0; i < st_ivas->hCombinedOrientationData->num_subframes; ++i ) + { + st_ivas->hCombinedOrientationData->Quaternions[i] = originalHeadRot[i]; + } + + /* restore original td renderer handle */ + st_ivas->hBinRendererTd = origTdRendHandle; + + pop_wmops(); + return IVAS_ERR_OK; +} +#endif +#endif diff --git a/lib_dec/ivas_omasa_dec.c b/lib_dec/ivas_omasa_dec.c index 6bf9cdfdd..daf217575 100644 --- a/lib_dec/ivas_omasa_dec.c +++ b/lib_dec/ivas_omasa_dec.c @@ -37,6 +37,9 @@ #include "prot.h" #include "ivas_prot_rend.h" #include "ivas_rom_com.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" @@ -149,7 +152,12 @@ void ivas_omasa_data_close( ivas_error ivas_omasa_dec_config( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ uint16_t *nSamplesRendered, /* o : number of samples flushed from the previous frame (JBM) */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + const PCM_RESOLUTION pcm_resolution, /* i : type for the decoded PCM resolution */ + void *data /* o : output synthesis signal */ +#else int16_t *data /* o : output synthesis signal */ +#endif ) { int16_t k, sce_id, nSCE_old, nchan_hp20_old, numCldfbAnalyses_old, numCldfbSyntheses_old, n_MD; @@ -193,7 +201,11 @@ ivas_error ivas_omasa_dec_config( { st_ivas->hCPE[0]->nchan_out = 1; } +#ifdef SPLIT_REND_WITH_HEAD_ROT + else if ( ( error = ivas_masa_dec_reconfigure( st_ivas, nSamplesRendered, pcm_resolution, data ) ) != IVAS_ERR_OK ) +#else else if ( ( error = ivas_masa_dec_reconfigure( st_ivas, nSamplesRendered, data ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -358,9 +370,17 @@ ivas_error ivas_omasa_dec_config( * TD Decorrelator *-----------------------------------------------------------------*/ +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( st_ivas->hDiracDecBin[0] != NULL ) +#else if ( st_ivas->hDiracDecBin != NULL ) +#endif { +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( error = ivas_td_decorr_reconfig_dec( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->nchan_transport, st_ivas->hDecoderConfig->output_Fs, &( st_ivas->hDiracDecBin[0]->hTdDecorr ), &( st_ivas->hDiracDecBin[0]->useTdDecorr ) ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_td_decorr_reconfig_dec( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->nchan_transport, st_ivas->hDecoderConfig->output_Fs, &( st_ivas->hDiracDecBin->hTdDecorr ), &( st_ivas->hDiracDecBin->useTdDecorr ) ) ) != IVAS_ERR_OK ) +#endif { return error; @@ -380,11 +400,18 @@ ivas_error ivas_omasa_dec_config( * floating-point output audio buffers *-----------------------------------------------------------------*/ +#ifndef NONBE_UNIFIED_DECODING_PATHS + if ( !st_ivas->hDecoderConfig->Opt_5ms ) + { +#endif nchan_out_buff = ivas_get_nchan_buffers_dec( st_ivas, -1, -1 ); if ( ( error = ivas_output_buff_dec( st_ivas->p_output_f, nchan_out_buff_old, nchan_out_buff ) ) != IVAS_ERR_OK ) { return error; } +#ifndef NONBE_UNIFIED_DECODING_PATHS + } +#endif } @@ -552,6 +579,45 @@ ivas_error ivas_omasa_ism_metadata_dec( return IVAS_ERR_OK; } +#ifndef NONBE_UNIFIED_DECODING_PATHS_FIX +/*--------------------------------------------------------------------------* + * ivas_omasa_dirac_rend() + * + * Rendering in OMASA format + *--------------------------------------------------------------------------*/ + +void ivas_omasa_dirac_rend( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + float *output[], /* o : output synthesis signal */ + const int16_t output_frame /* i : output frame length per channel */ +) +{ + int16_t n, dirac_read_idx; + float data_separated_objects[MAX_NUM_OBJECTS][L_FRAME48k]; + + if ( st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ ) + { + mvr2r( output[2], data_separated_objects[0], output_frame ); + } + else + { + for ( n = 0; n < st_ivas->nchan_ism; n++ ) + { + mvr2r( output[n + 2], data_separated_objects[n], output_frame ); + } + } + + dirac_read_idx = st_ivas->hSpatParamRendCom->dirac_read_idx; + + ivas_dirac_dec( st_ivas, output, st_ivas->nchan_transport, MAX_PARAM_SPATIAL_SUBFRAMES ); + + st_ivas->hSpatParamRendCom->dirac_read_idx = dirac_read_idx; /* Original read index is needed for the next function which will update it again */ + + ivas_omasa_separate_object_render( st_ivas, data_separated_objects, output, output_frame ); + + return; +} +#endif /*--------------------------------------------------------------------------* * ivas_omasa_dirac_rend_jbm() @@ -570,6 +636,7 @@ void ivas_omasa_dirac_rend_jbm( { int16_t subframes_rendered; int16_t slots_rendered; +#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX int16_t n; float data_separated_objects[MAX_NUM_OBJECTS][L_FRAME48k]; @@ -584,17 +651,77 @@ void ivas_omasa_dirac_rend_jbm( mvr2r( output_f[n + CPE_CHANNELS], data_separated_objects[n], nSamplesAsked ); } } +#endif subframes_rendered = st_ivas->hSpatParamRendCom->subframes_rendered; slots_rendered = st_ivas->hSpatParamRendCom->slots_rendered; ivas_dirac_dec_render( st_ivas, nchan_transport, nSamplesAsked, nSamplesRendered, nSamplesAvailable, output_f ); +#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX ivas_omasa_separate_object_render_jbm( st_ivas, *nSamplesRendered, data_separated_objects, output_f, subframes_rendered, slots_rendered ); +#else + ivas_omasa_separate_object_render_jbm( st_ivas, *nSamplesRendered, output_f, subframes_rendered, slots_rendered ); +#endif return; } +#ifndef NONBE_UNIFIED_DECODING_PATHS +/*--------------------------------------------------------------------------* + * ivas_omasa_dirac_td_binaural() + * + * Binaural rendering in OMASA format + *--------------------------------------------------------------------------*/ + +ivas_error ivas_omasa_dirac_td_binaural( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + float *output[], /* o : output synthesis signal */ + const int16_t output_frame /* i : output frame length per channel */ +) +{ + int16_t n; + float data_separated_objects[MAX_NUM_OBJECTS][L_FRAME48k]; + float gain = OMASA_TDREND_MATCHING_GAIN; + ivas_error error; + float *p_sepobj[MAX_NUM_OBJECTS]; + + for ( n = 0; n < MAX_NUM_OBJECTS; n++ ) + { + p_sepobj[n] = &data_separated_objects[n][0]; + } + + for ( n = 0; n < st_ivas->nchan_ism; n++ ) + { + mvr2r( output[2 + n], data_separated_objects[n], output_frame ); + v_multc( data_separated_objects[n], gain, data_separated_objects[n], output_frame ); + } + + for ( n = 0; n < st_ivas->nchan_ism; n++ ) + { + delay_signal( data_separated_objects[n], output_frame, st_ivas->hMasaIsmData->delayBuffer[n], st_ivas->hMasaIsmData->delayBuffer_size ); + } + + ivas_dirac_dec_binaural( st_ivas, st_ivas->hCombinedOrientationData, output, st_ivas->nchan_transport, MAX_PARAM_SPATIAL_SUBFRAMES ); + +#ifdef NONBE_UNIFIED_DECODING_PATHS + /* reset combined orientation access index before calling the td renderer */ + ivas_combined_orientation_set_to_start_index( st_ivas->hCombinedOrientationData ); +#endif + + if ( ( error = ivas_td_binaural_renderer( st_ivas, p_sepobj, output_frame ) ) != IVAS_ERR_OK ) + { + return error; + } + + for ( n = 0; n < BINAURAL_CHANNELS; n++ ) + { + v_add( output[n], p_sepobj[n], output[n], output_frame ); + } + + return IVAS_ERR_OK; +} +#endif /*--------------------------------------------------------------------------* * ivas_omasa_dirac_td_binaural_render() @@ -640,8 +767,10 @@ ivas_error ivas_omasa_dirac_td_binaural_jbm( ivas_dirac_dec_binaural_render( st_ivas, nSamplesAsked, nSamplesRendered, nSamplesAvailable, nchan_transport, output_f ); +#ifdef NONBE_UNIFIED_DECODING_PATHS /* reset combined orientation access index before calling the td renderer */ ivas_combined_orientation_set_to_start_index( st_ivas->hCombinedOrientationData ); +#endif if ( ( error = ivas_td_binaural_renderer_sf( st_ivas, p_sepobj, *nSamplesRendered ) ) != IVAS_ERR_OK ) { diff --git a/lib_dec/ivas_osba_dec.c b/lib_dec/ivas_osba_dec.c index 903839686..a30ddfb55 100644 --- a/lib_dec/ivas_osba_dec.c +++ b/lib_dec/ivas_osba_dec.c @@ -37,6 +37,9 @@ #include "prot.h" #include "ivas_prot_rend.h" #include "ivas_rom_com.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" @@ -131,6 +134,7 @@ ivas_error ivas_osba_dirac_td_binaural_jbm( { int16_t n; ivas_error error; +#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX float output_separated_objects[BINAURAL_CHANNELS][L_FRAME48k]; // VE2SB: TBV float *p_sepobj[BINAURAL_CHANNELS]; int16_t channel_offset; @@ -141,15 +145,65 @@ ivas_error ivas_osba_dirac_td_binaural_jbm( } channel_offset = st_ivas->nchan_ism; +#endif +#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX if ( ( error = ivas_sba_dec_render( st_ivas, nSamplesAsked, nSamplesRendered, nSamplesAvailable, &output_f[channel_offset] ) ) != IVAS_ERR_OK ) +#else + if ( ( error = ivas_sba_dec_render( st_ivas, nSamplesAsked, nSamplesRendered, nSamplesAvailable, &output_f[2] ) ) != IVAS_ERR_OK ) +#endif { return error; } +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { + int16_t slot_idx, num_cldfb_bands, b, nchan_transport_orig; + int16_t cldfb_slots, slot_idx_start; + float Cldfb_RealBuffer[CLDFB_NO_CHANNELS_MAX]; + float Cldfb_ImagBuffer[CLDFB_NO_CHANNELS_MAX]; + + num_cldfb_bands = st_ivas->hSplitBinRend.splitrend.hCldfbHandles->cldfbAna[0]->no_channels; + nchan_transport_orig = st_ivas->nchan_transport; + st_ivas->nchan_transport = st_ivas->nchan_ism; + slot_idx_start = st_ivas->hTcBuffer->n_samples_rendered / num_cldfb_bands; + if ( ( error = ivas_td_binaural_renderer_sf_splitBinaural( st_ivas, output_f, *nSamplesRendered ) ) != IVAS_ERR_OK ) + { + return error; + } + st_ivas->nchan_transport = nchan_transport_orig; + cldfb_slots = *nSamplesRendered / num_cldfb_bands; + for ( n = 0; n < st_ivas->hSplitBinRend.splitrend.multiBinPoseData.num_poses * BINAURAL_CHANNELS; ++n ) + { + for ( slot_idx = 0; slot_idx < cldfb_slots; slot_idx++ ) + { + cldfbAnalysis_ts( &( output_f[n][num_cldfb_bands * slot_idx] ), Cldfb_RealBuffer, Cldfb_ImagBuffer, num_cldfb_bands, st_ivas->hSplitBinRend.splitrend.hCldfbHandles->cldfbAna[n] ); + + for ( b = 0; b < num_cldfb_bands; b++ ) + { + st_ivas->hSplitBinRend.hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[n][slot_idx][b] = + ( 0.5f * st_ivas->hSplitBinRend.hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[n][slot_idx_start + slot_idx][b] ) + + ( 0.5f * Cldfb_RealBuffer[b] ); + + st_ivas->hSplitBinRend.hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[n][slot_idx][b] = + ( 0.5f * st_ivas->hSplitBinRend.hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[n][slot_idx_start + slot_idx][b] ) + + ( 0.5f * Cldfb_ImagBuffer[b] ); + } + } + } + } + else + { +#endif + +#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX if ( ( error = ivas_td_binaural_renderer_sf( st_ivas, p_sepobj, *nSamplesRendered ) ) != IVAS_ERR_OK ) +#else + if ( ( error = ivas_td_binaural_renderer_sf( st_ivas, output_f, *nSamplesRendered ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -159,12 +213,154 @@ ivas_error ivas_osba_dirac_td_binaural_jbm( int16_t i; for ( i = 0; i < nSamplesAsked; i++ ) { +#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX output_f[n][i] = 0.5f * output_f[channel_offset + n][i] + 0.5f * p_sepobj[n][i]; +#else + output_f[n][i] = 0.5f * output_f[2 + n][i] + 0.5f * output_f[n][i]; +#endif } } +#ifdef SPLIT_REND_WITH_HEAD_ROT + } +#endif return IVAS_ERR_OK; } +#ifndef NONBE_UNIFIED_DECODING_PATHS_FIX +/*--------------------------------------------------------------------------* + * ivas_osba_dirac_td_binaural() + * + * Binaural rendering in OSBA format + *--------------------------------------------------------------------------*/ + +ivas_error ivas_osba_dirac_td_binaural( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + float *output[], /* o : output synthesis signal */ + const int16_t output_frame /* i : output frame length per channel */ +) +{ + int16_t n; + float data_separated_objects[MAX_NUM_OBJECTS][L_FRAME48k]; + ivas_error error; + float *p_sepobj[MAX_NUM_OBJECTS]; + int16_t channel_offset; + + for ( n = 0; n < MAX_NUM_OBJECTS; n++ ) + { + p_sepobj[n] = &data_separated_objects[n][0]; + } + + channel_offset = st_ivas->nchan_ism; + + for ( n = 0; n < st_ivas->nchan_ism; n++ ) + { + mvr2r( output[n], data_separated_objects[n], output_frame ); + } + +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( st_ivas->hDecoderConfig->output_config != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED && st_ivas->hDecoderConfig->output_config != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) +#endif + { + for ( n = 0; n < st_ivas->nchan_ism; n++ ) + { + delay_signal( data_separated_objects[n], output_frame, st_ivas->hSbaIsmData->delayBuffer[n], st_ivas->hSbaIsmData->delayBuffer_size ); + } + } + + if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV ) + { + if ( ( error = ivas_sba_upmixer_renderer( st_ivas, output, output_frame ) ) != IVAS_ERR_OK ) + { + return error; + } + } + else + { + ivas_dirac_dec_binaural( st_ivas, st_ivas->hCombinedOrientationData, &output[channel_offset], st_ivas->nchan_transport, MAX_PARAM_SPATIAL_SUBFRAMES ); + } + +#ifdef DEBUG_OSBA + { + for ( int16_t t = 0; t < output_frame; t++ ) + { + for ( int16_t c = 0; c < BINAURAL_CHANNELS; c++ ) + { + int16_t val = (int16_t) ( output[channel_offset + c][t] + 0.5f ); + dbgwrite( &val, sizeof( int16_t ), 1, 1, "./res/sba_fast_conv_out.raw" ); + } + } + } +#endif +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { + int16_t slot_idx, num_cldfb_bands, b, nchan_transport_orig; + float Cldfb_RealBuffer[CLDFB_NO_CHANNELS_MAX]; + float Cldfb_ImagBuffer[CLDFB_NO_CHANNELS_MAX]; + + num_cldfb_bands = st_ivas->hSplitBinRend.splitrend.hCldfbHandles->cldfbAna[0]->no_channels; + nchan_transport_orig = st_ivas->nchan_transport; + st_ivas->nchan_transport = st_ivas->nchan_ism; + + if ( ( error = ObjRenderIvasFrame_splitBinaural( st_ivas, output, output_frame ) ) != IVAS_ERR_OK ) + { + return error; + } + + st_ivas->nchan_transport = nchan_transport_orig; + + for ( n = 0; n < st_ivas->hSplitBinRend.splitrend.multiBinPoseData.num_poses * BINAURAL_CHANNELS; ++n ) + { + for ( slot_idx = 0; slot_idx < CLDFB_NO_COL_MAX; slot_idx++ ) + { + cldfbAnalysis_ts( &( output[n][num_cldfb_bands * slot_idx] ), Cldfb_RealBuffer, Cldfb_ImagBuffer, num_cldfb_bands, st_ivas->hSplitBinRend.splitrend.hCldfbHandles->cldfbAna[n] ); + + for ( b = 0; b < num_cldfb_bands; b++ ) + { + st_ivas->hSplitBinRend.hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[n][slot_idx][b] = + ( 0.5f * st_ivas->hSplitBinRend.hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[n][slot_idx][b] ) + + ( 0.5f * Cldfb_RealBuffer[b] ); + + st_ivas->hSplitBinRend.hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[n][slot_idx][b] = + ( 0.5f * st_ivas->hSplitBinRend.hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[n][slot_idx][b] ) + + ( 0.5f * Cldfb_ImagBuffer[b] ); + } + } + } + } + else + { +#endif + if ( ( error = ivas_td_binaural_renderer( st_ivas, p_sepobj, output_frame ) ) != IVAS_ERR_OK ) + { + return error; + } + +#ifdef DEBUG_OSBA + for ( int16_t t = 0; t < output_frame; t++ ) + { + for ( int16_t c = 0; c < BINAURAL_CHANNELS; c++ ) + { + int16_t val = (int16_t) ( p_sepobj[c][t] + 0.5f ); + dbgwrite( &val, sizeof( int16_t ), 1, 1, "./res/ism_td_bin_out.raw" ); + } + } +#endif + for ( n = 0; n < BINAURAL_CHANNELS; n++ ) + { + int16_t i; + for ( i = 0; i < output_frame; i++ ) + { + output[n][i] = 0.5f * output[channel_offset + n][i] + 0.5f * p_sepobj[n][i]; + } + } +#ifdef SPLIT_REND_WITH_HEAD_ROT + } +#endif + + return IVAS_ERR_OK; +} +#endif /*-------------------------------------------------------------------------* * ivas_osba_ism_metadata_dec() @@ -196,6 +392,7 @@ ivas_error ivas_osba_ism_metadata_dec( return IVAS_ERR_OK; } +#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX /*-------------------------------------------------------------------------* * ivas_osba_render_sf() * @@ -247,3 +444,64 @@ ivas_error ivas_osba_render_sf( return IVAS_ERR_OK; } +#else +/*-------------------------------------------------------------------------* + * ivas_osba_render() + * + * Object + SBA rendering process. + *-------------------------------------------------------------------------*/ + +ivas_error ivas_osba_render( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + float *output_f[], /* i/o: core-coder transport channels/object output */ + const int16_t output_frame /* i : output frame length per channel */ +) +{ + float tmp_ism_out[MAX_OUTPUT_CHANNELS][L_FRAME48k]; + float *p_tmp_ism_out[MAX_OUTPUT_CHANNELS]; + int16_t n, nchan_out, nchan_ism; + ivas_error error; + + nchan_out = st_ivas->hDecoderConfig->nchan_out; + nchan_ism = st_ivas->nchan_ism; + + for ( n = 0; n < max( nchan_out, nchan_ism ); n++ ) + { + p_tmp_ism_out[n] = &tmp_ism_out[n][0]; + } + + if ( st_ivas->ism_mode == ISM_SBA_MODE_DISC ) + { + for ( n = 0; n < nchan_ism; n++ ) + { + mvr2r( output_f[n], tmp_ism_out[n], output_frame ); + delay_signal( tmp_ism_out[n], output_frame, st_ivas->hSbaIsmData->delayBuffer[n], st_ivas->hSbaIsmData->delayBuffer_size ); + } + + if ( st_ivas->renderer_type == RENDERER_OSBA_AMBI ) + { + ivas_ism2sba( p_tmp_ism_out, st_ivas->hIsmRendererData, st_ivas->hIsmMetaData, st_ivas->nchan_ism, output_frame, st_ivas->hIntSetup.ambisonics_order ); + } + else + { + ivas_ism_render( st_ivas, p_tmp_ism_out, output_frame ); + } + } + + if ( ( error = ivas_sba_upmixer_renderer( st_ivas, output_f, output_frame ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( st_ivas->ism_mode == ISM_SBA_MODE_DISC ) + { + for ( n = 0; n < nchan_out; n++ ) + { + v_add( output_f[n + nchan_ism], tmp_ism_out[n], output_f[n], output_frame ); + v_multc( output_f[n], 0.5f, output_f[n], output_frame ); + } + } + + return IVAS_ERR_OK; +} +#endif diff --git a/lib_dec/ivas_out_setup_conversion.c b/lib_dec/ivas_out_setup_conversion.c index e1d0c12e5..d622e4cf1 100644 --- a/lib_dec/ivas_out_setup_conversion.c +++ b/lib_dec/ivas_out_setup_conversion.c @@ -39,6 +39,9 @@ #include "ivas_prot_rend.h" #include "ivas_rom_com.h" #include "ivas_rom_rend.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" diff --git a/lib_dec/ivas_output_config.c b/lib_dec/ivas_output_config.c index 94bf27274..15d185efa 100644 --- a/lib_dec/ivas_output_config.c +++ b/lib_dec/ivas_output_config.c @@ -34,7 +34,14 @@ #include "options.h" #include "ivas_cnst.h" #include "ivas_prot.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT +#include "ivas_prot_rend.h" +#endif #include "ivas_stat_dec.h" +#ifdef DEBUGGING +#include "debug.h" +#include +#endif #include "wmc_auto.h" @@ -73,13 +80,20 @@ void ivas_renderer_select( } if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB +#ifdef SPLIT_REND_WITH_HEAD_ROT + || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM +#endif ) { if ( st_ivas->ivas_format == ISM_FORMAT ) { if ( st_ivas->ism_mode == ISM_MODE_PARAM ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) +#else if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL ) +#endif { *renderer_type = RENDERER_BINAURAL_PARAMETRIC; } @@ -91,14 +105,36 @@ void ivas_renderer_select( else /* ISM_MODE_DISC */ { if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB +#ifdef SPLIT_REND_WITH_HEAD_ROT + || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM +#endif ) { +#ifdef DEBUGGING + if ( st_ivas->hDecoderConfig->force_rend == FORCE_CLDFB_RENDERER ) + { + *renderer_type = RENDERER_BINAURAL_FASTCONV; + *internal_config = IVAS_AUDIO_CONFIG_HOA3; /* Render ISM to HOA3 before binauralization*/ + } + else + { + *renderer_type = RENDERER_BINAURAL_OBJECTS_TD; + *internal_config = output_config; + } +#else *renderer_type = RENDERER_BINAURAL_OBJECTS_TD; *internal_config = output_config; +#endif } else { *renderer_type = RENDERER_BINAURAL_MIXER_CONV_ROOM; +#ifdef DEBUGGING + if ( st_ivas->hRenderConfig->renderer_type_override == IVAS_RENDER_TYPE_OVERRIDE_FASTCONV ) + { + *renderer_type = RENDERER_BINAURAL_FASTCONV_ROOM; + } +#endif *internal_config = IVAS_AUDIO_CONFIG_7_1_4; } } @@ -107,7 +143,11 @@ void ivas_renderer_select( { *internal_config = output_config; +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) +#else if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL ) +#endif { *renderer_type = RENDERER_BINAURAL_PARAMETRIC; } @@ -121,6 +161,9 @@ void ivas_renderer_select( *internal_config = IVAS_AUDIO_CONFIG_HOA3; if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB +#ifdef SPLIT_REND_WITH_HEAD_ROT + || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM +#endif ) { *renderer_type = RENDERER_BINAURAL_FASTCONV; @@ -163,7 +206,11 @@ void ivas_renderer_select( { *internal_config = output_config; +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) +#else if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL ) +#endif { *renderer_type = RENDERER_BINAURAL_PARAMETRIC; } @@ -176,9 +223,17 @@ void ivas_renderer_select( { *internal_config = transport_config; +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) +#else if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) +#endif { +#ifdef DEBUGGING + if ( ( ( ( st_ivas->transport_config == IVAS_AUDIO_CONFIG_5_1 || st_ivas->transport_config == IVAS_AUDIO_CONFIG_7_1 ) && ( st_ivas->hDecoderConfig->Opt_Headrotation || st_ivas->hDecoderConfig->Opt_ExternalOrientation ) ) || ( st_ivas->hDecoderConfig->force_rend == FORCE_TD_RENDERER ) ) && ( st_ivas->mc_mode == MC_MODE_MCT || st_ivas->mc_mode == MC_MODE_PARAMUPMIX ) && !( st_ivas->hDecoderConfig->force_rend == FORCE_CLDFB_RENDERER ) ) +#else if ( ( st_ivas->transport_config == IVAS_AUDIO_CONFIG_5_1 || st_ivas->transport_config == IVAS_AUDIO_CONFIG_7_1 ) && ( st_ivas->hDecoderConfig->Opt_Headrotation || st_ivas->hDecoderConfig->Opt_ExternalOrientation ) && ( st_ivas->mc_mode == MC_MODE_MCT || st_ivas->mc_mode == MC_MODE_PARAMUPMIX ) ) +#endif { *renderer_type = RENDERER_BINAURAL_OBJECTS_TD; } @@ -220,6 +275,16 @@ void ivas_renderer_select( { *renderer_type = RENDERER_BINAURAL_FASTCONV_ROOM; } +#ifdef DEBUGGING + if ( st_ivas->hRenderConfig->renderer_type_override == IVAS_RENDER_TYPE_OVERRIDE_CREND ) + { + *renderer_type = RENDERER_BINAURAL_MIXER_CONV_ROOM; + } + else if ( st_ivas->hRenderConfig->renderer_type_override == IVAS_RENDER_TYPE_OVERRIDE_FASTCONV ) + { + *renderer_type = RENDERER_BINAURAL_FASTCONV_ROOM; + } +#endif } } } diff --git a/lib_dec/ivas_pca_dec.c b/lib_dec/ivas_pca_dec.c index acb92fe88..fc7c214b1 100644 --- a/lib_dec/ivas_pca_dec.c +++ b/lib_dec/ivas_pca_dec.c @@ -34,6 +34,9 @@ #include "options.h" #include "prot.h" #include "ivas_prot.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "ivas_cnst.h" #include "wmc_auto.h" @@ -257,6 +260,9 @@ void ivas_pca_dec( return; } +#ifdef DEBUGGING + assert( ivas_total_brate == PCA_BRATE ); /* the remaining code is defined at 256k where there are 4 dmx channel */ +#endif if ( !bfi ) { /* set PCA by-pass mode indicator */ diff --git a/lib_dec/ivas_post_proc.c b/lib_dec/ivas_post_proc.c index 08d1d25ab..0ec2fa24a 100644 --- a/lib_dec/ivas_post_proc.c +++ b/lib_dec/ivas_post_proc.c @@ -38,6 +38,9 @@ #include "prot.h" #include "ivas_prot.h" #include "ivas_cnst.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" /*------------------------------------------------------------------------- @@ -59,7 +62,9 @@ void ivas_post_proc( const int16_t sba_dirac_stereo_flag /* i : signal stereo output for SBA DirAC */ ) { +#ifndef DEBUG_STEREO_DFT_NOCORE int16_t k; +#endif int16_t delay_comp; int32_t output_Fs; Decoder_State **sts; @@ -109,6 +114,7 @@ void ivas_post_proc( } else /* IVAS_CPE_DFT */ { +#ifndef DEBUG_STEREO_DFT_NOCORE int16_t pit_res_max_past_tmp; pit_res_max_past_tmp = sts[0]->pit_res_max_past; @@ -142,6 +148,7 @@ void ivas_post_proc( tcx_ltp_post( sts[0], hTcxLtpDec, TCX_20_CORE, output_frame, NS2SA( output_Fs, STEREO_DFT32MS_OVL_NS ), output[k], hCPE->output_mem[k] ); } } +#endif } return; @@ -172,8 +179,10 @@ void stereo_dft_dec_core_switching( Decoder_State *st; int16_t predelay, ap_fade_len; float pAp_input[L_FRAME16k]; +#ifndef DEBUG_STEREO_DFT_NOCORE float tcx_core_buf[L_FRAME16k]; float synth_tmp[L_FRAME48k]; +#endif st = hCPE->hCoreCoder[0]; /* in DFT stereo, only M channel is decoded by the CoreCoder */ output_Fs = st->output_Fs; @@ -188,6 +197,9 @@ void stereo_dft_dec_core_switching( tmps = NS2SA( output_Fs, DELAY_BWE_TOTAL_NS ); /*cross-fading size @ FB*/ delay_comp = NS2SA( st->L_frame * FRAMES_PER_SEC, DELAY_BWE_TOTAL_NS ); /*cross-fading size @ LB*/ +#if defined( DEBUG_MODE_DFT ) && defined( DEBUG_STEREO_DFT_NOCORE ) + stereo_dft_dec_analyze( hCPE, output, DFT, 0, output_frame, output_frame, DFT_STEREO_DEC_ANA_NOCORE, 0, 0 ); +#else /* resample DFT analysis memories in case of internal sampling rate change */ if ( st->last_L_frame != st->L_frame && st->last_L_frame <= L_FRAME16k && st->L_frame <= L_FRAME16k ) { @@ -204,6 +216,9 @@ void stereo_dft_dec_core_switching( if ( st->core == TCX_20_CORE || st->core == TCX_10_CORE || st->core == HQ_CORE || ( st->bfi == 1 && st->core == ACELP_CORE && st->con_tcx == 1 ) ) { +#ifdef DEBUGGING + assert( L_frameTCX == output_frame ); +#endif if ( ( ( st->last_core != ACELP_CORE || ( st->prev_bfi == 1 && st->last_core == ACELP_CORE && st->last_con_tcx == 1 ) ) && st->last_core != AMR_WB_CORE ) || ( sba_dirac_stereo_dtx_flag && st->cng_type == FD_CNG ) ) /* TCX / HQ-CORE -> TCX / HQ-CORE */ { /* In case of a TCX to ACELP switch next frame */ @@ -424,6 +439,7 @@ void stereo_dft_dec_core_switching( } } } +#endif /*----------------------------------------------------------------* * enhanced stereo filling: allpass filter @@ -431,6 +447,20 @@ void stereo_dft_dec_core_switching( if ( hCPE->hStereoDft->hConfig->res_pred_mode == STEREO_DFT_RESPRED_ESF ) { +#if defined( DEBUG_MODE_INFO ) && defined( DEBUG_STEREO_DFT_NOCORE ) + { + char file_name[100]; + int16_t tmp[320]; + { + sprintf( file_name, "./res/stereo_dft_enc_M_S_%d_c%d_b0.pcm", st->L_frame * FRAMES_PER_SEC, 0 ); + } + dbgread( tmp, sizeof( int16_t ), st->L_frame, file_name ); + for ( i = 0; i < st->L_frame; i++ ) + { + pAp_input[i] = (float) ( tmp[i] ); + } + } +#endif if ( st->sr_core == INT_FS_12k8 ) { ap_fade_len = STEREO_DFT_ALLPASS_FADELEN_12k8; @@ -440,6 +470,7 @@ void stereo_dft_dec_core_switching( ap_fade_len = STEREO_DFT_ALLPASS_FADELEN_16k; } +#if !defined( DEBUG_MODE_INFO ) || !defined( DEBUG_STEREO_DFT_NOCORE ) if ( st->core == TCX_20_CORE || st->core == TCX_10_CORE || st->core == HQ_CORE || ( st->bfi == 1 && st->core == ACELP_CORE && st->con_tcx == 1 ) ) { int16_t numZeros = (int16_t) ( NS2SA( st->sr_core, N_ZERO_MDCT_NS ) ); @@ -476,11 +507,25 @@ void stereo_dft_dec_core_switching( } } } +#endif predelay = NS2SA( st->sr_core, DELAY_BWE_TOTAL_NS ); /* apply predelay to have same overall filter delay for all cases */ delay_signal( pAp_input, st->L_frame, hCPE->hStereoDft->ap_delay_mem, predelay ); +#ifdef DEBUG_MODE_DFT + { + int16_t v; + int16_t out_ap[L_FRAME16k]; + + for ( v = 0; v < st->L_frame; v++ ) + { + out_ap[v] = (int16_t) pAp_input[v]; + } + + dbgwrite( out_ap, sizeof( int16_t ), st->L_frame, 1, "res/stereo_dft_allpass_input.pcm" ); + } +#endif /*DEBUG_MODE_DFT*/ /* input zeroes for transient frames */ if ( hCPE->hStereoDft->attackPresent ) @@ -515,6 +560,18 @@ void stereo_dft_dec_core_switching( filter_with_allpass( pAp_input, pAp_input, st->L_frame, &hCPE->hStereoDft->ap2 ); filter_with_allpass( pAp_input, pAp_input, st->L_frame, &hCPE->hStereoDft->ap3 ); +#ifdef DEBUG_MODE_DFT + { + int16_t v; + int16_t out_ap[L_FRAME16k]; + for ( v = 0; v < st->L_frame; v++ ) + { + out_ap[v] = (int16_t) pAp_input[v]; + } + + dbgwrite( out_ap, sizeof( int16_t ), st->L_frame, 1, "res/stereo_dft_allpass.pcm" ); + } +#endif /*DEBUG_MODE_DFT*/ /* apply DFT to allpass-filtered signal */ stereo_dft_dec_analyze( hCPE, pAp_input, DFT, 1, st->L_frame, output_frame, DFT_STEREO_DEC_ANA_FB, 0, 0 ); } diff --git a/lib_dec/ivas_qmetadata_dec.c b/lib_dec/ivas_qmetadata_dec.c index 011a16d81..c3134fa8a 100644 --- a/lib_dec/ivas_qmetadata_dec.c +++ b/lib_dec/ivas_qmetadata_dec.c @@ -145,6 +145,27 @@ int16_t ivas_qmetadata_dec_decode( int16_t reduce_bits; int16_t ind_order[MASA_MAXIMUM_CODING_SUBBANDS]; +#ifdef DEBUG_MODE_QMETADATA + static FILE *pF = NULL; + static FILE *pF_azi = NULL; + static FILE *pF_ele = NULL; + static FILE *pF_ratio = NULL; + static FILE *pF_spcoh = NULL; + static FILE *pF_surcoh = NULL; + + if ( pF == NULL ) + pF = fopen( "./res/qmetadata_dec.txt", "w" ); + if ( pF_azi == NULL ) + pF_azi = fopen( "./res/qmetadata_azi_dec.txt", "w" ); + if ( pF_ele == NULL ) + pF_ele = fopen( "./res/qmetadata_ele_dec.txt", "w" ); + if ( pF_ratio == NULL ) + pF_ratio = fopen( "./res/qmetadata_ratio_dec.txt", "w" ); + if ( pF_spcoh == NULL ) + pF_spcoh = fopen( "./res/qmetadata_spcoh_dec.txt", "w" ); + if ( pF_surcoh == NULL ) + pF_surcoh = fopen( "./res/qmetadata_surcoh_dec.txt", "w" ); +#endif ec_flag = 0; start_index_0 = *index; @@ -521,6 +542,9 @@ int16_t ivas_qmetadata_dec_decode( } } +#ifdef DEBUGGING + assert( ( diff_bits <= 0 ) || ( q_direction->not_in_2D == 0 ) ); +#endif /* Read raw-coded bits*/ for ( b = start_band; b < nbands; b++ ) { @@ -581,6 +605,44 @@ int16_t ivas_qmetadata_dec_decode( bits_dir_target += bits_dir_raw; bits_dir_used += bits_dir; +#ifdef DEBUG_MODE_QMETADATA + fprintf( pF, "frame %d: diff %d coh %d surcoh %d ", frame, bits_diff, bits_coherence, bits_sur_coherence ); + fprintf( pF, "dir %d %d,%d,%d\n", ec_flag, start_index_0 - *index, total_bits_1dir, bits_dir_raw ); + + fprintf( pF_azi, "frame %d/dir/ec %d/%d: ", frame, d, ec_flag ); + fprintf( pF_ele, "frame %d/dir/ec %d/%d: ", frame, d, ec_flag ); + fprintf( pF_ratio, "frame %d/dir %d: ", frame, d ); + fprintf( pF_spcoh, "frame %d/dir %d: ", frame, d ); + if ( d == 0 ) + { + fprintf( pF_surcoh, "frame %d/dir %d: ", frame, d ); + } + for ( b = start_band; b < nbands; b++ ) + { + for ( m = 0; m < q_direction->cfg.nblocks; m++ ) + { + fprintf( pF_azi, " %+5.2f ", (int16_t) ( 100.f * q_direction->band_data[b].azimuth[m] ) / 100.f ); + fprintf( pF_ele, " %+5.2f ", (int16_t) ( 100.f * q_direction->band_data[b].elevation[m] ) / 100.f ); + fprintf( pF_ratio, " %1.3f ", q_direction->band_data[b].energy_ratio[m] ); + if ( q_direction->coherence_band_data != NULL ) + { + fprintf( pF_spcoh, " %d ", q_direction->coherence_band_data[b].spread_coherence[m] ); + } + if ( d == 0 && hQMetaData->surcoh_band_data != NULL ) + { + fprintf( pF_surcoh, " %d ", hQMetaData->surcoh_band_data[b].surround_coherence[m] ); + } + } + } + fprintf( pF_azi, "\n" ); + fprintf( pF_ele, "\n" ); + fprintf( pF_ratio, "\n" ); + fprintf( pF_spcoh, "\n" ); + if ( d == 0 ) + { + fprintf( pF_surcoh, "\n" ); + } +#endif } /* move 2 dir data to its correct subband */ @@ -681,14 +743,41 @@ int16_t ivas_qmetadata_dec_decode_hr_384_512( const uint8_t ncoding_bands_config ) { int16_t d, b, m; +#ifdef DEBUG_MODE_QMETADATA + int16_t bits_diff_sum; +#endif int16_t nbands, start_band; IVAS_QDIRECTION *q_direction; int16_t start_index_0; +#ifdef DEBUG_MODE_QMETADATA + int16_t bits_no_dirs_coh, bits_sur_coherence; +#endif uint16_t all_coherence_zero; int16_t p[MASA_MAXIMUM_CODING_SUBBANDS], dif_p[MASA_MAXIMUM_CODING_SUBBANDS]; int16_t codedBands, sf_nbands0, sf_nbands1; sf_nbands1 = 1; +#ifdef DEBUG_MODE_QMETADATA + static FILE *pF = NULL; + static FILE *pF_azi = NULL; + static FILE *pF_ele = NULL; + static FILE *pF_ratio = NULL; + static FILE *pF_spcoh = NULL; + static FILE *pF_surcoh = NULL; + + if ( pF == NULL ) + pF = fopen( "./res/qmetadata_dec.txt", "w" ); + if ( pF_azi == NULL ) + pF_azi = fopen( "./res/qmetadata_azi_dec.txt", "w" ); + if ( pF_ele == NULL ) + pF_ele = fopen( "./res/qmetadata_ele_dec.txt", "w" ); + if ( pF_ratio == NULL ) + pF_ratio = fopen( "./res/qmetadata_ratio_dec.txt", "w" ); + if ( pF_spcoh == NULL ) + pF_spcoh = fopen( "./res/qmetadata_spcoh_dec.txt", "w" ); + if ( pF_surcoh == NULL ) + pF_surcoh = fopen( "./res/qmetadata_surcoh_dec.txt", "w" ); +#endif start_index_0 = *index; /* read number of higher inactive/not encoded bands */ @@ -741,11 +830,17 @@ int16_t ivas_qmetadata_dec_decode_hr_384_512( hQMetaData->q_direction[0].cfg.nbands = codedBands; /*Coherence flag decoding*/ +#ifdef DEBUG_MODE_QMETADATA + bits_no_dirs_coh = 0; +#endif all_coherence_zero = 1; if ( hQMetaData->coherence_flag ) { /* read if coherence is zero */ all_coherence_zero = bitstream[( *index )--]; +#ifdef DEBUG_MODE_QMETADATA + bits_no_dirs_coh += 1; +#endif } hQMetaData->all_coherence_zero = (uint8_t) all_coherence_zero; @@ -775,6 +870,9 @@ int16_t ivas_qmetadata_dec_decode_hr_384_512( p[b] = p[b - 1] + dif_p[b] + 1; hQMetaData->twoDirBands[p[b]] = 1; } +#ifdef DEBUG_MODE_QMETADATA + bits_no_dirs_coh += ( d - *index ); +#endif } if ( bits_sph_idx == 16 && hQMetaData->no_directions == 2 ) @@ -785,10 +883,16 @@ int16_t ivas_qmetadata_dec_decode_hr_384_512( hQMetaData->q_direction[1].cfg.nbands = codedBands; } } +#ifdef DEBUG_MODE_QMETADATA + bits_diff_sum = +#endif ivas_qmetadata_entropy_decode_diffuseness_hr_512( bitstream, index, &( hQMetaData->q_direction[0] ) ); if ( hQMetaData->no_directions == 2 ) { +#ifdef DEBUG_MODE_QMETADATA + bits_diff_sum += +#endif ivas_qmetadata_entropy_decode_diffuseness_hr_512( bitstream, index, &( hQMetaData->q_direction[1] ) ); } @@ -879,10 +983,16 @@ int16_t ivas_qmetadata_dec_decode_hr_384_512( if ( all_coherence_zero == 0 ) { +#ifdef DEBUG_MODE_QMETADATA + bits_sur_coherence = +#endif read_surround_coherence_hr( bitstream, index, hQMetaData ); } else { +#ifdef DEBUG_MODE_QMETADATA + bits_sur_coherence = 0; +#endif /*Surround coherence*/ for ( b = 0; b < hQMetaData->q_direction[0].cfg.nbands; b++ ) { @@ -892,6 +1002,9 @@ int16_t ivas_qmetadata_dec_decode_hr_384_512( } } } +#ifdef DEBUG_MODE_QMETADATA + bits_no_dirs_coh += bits_sur_coherence; +#endif for ( d = 0; d < hQMetaData->no_directions; d++ ) { @@ -924,6 +1037,33 @@ int16_t ivas_qmetadata_dec_decode_hr_384_512( /* Decode quantized directions frame-wise */ ivas_qmetadata_raw_decode_dir_512( q_direction, bitstream, index, nbands, start_band, sph_grid16 ); +#ifdef DEBUG_MODE_QMETADATA + fprintf( pF, "frame %d: diff %d surcoh %d ", frame, bits_diff_sum, bits_sur_coherence ); + fprintf( pF, "dir %d\n", start_index_0 - *index ); + fprintf( pF_azi, "frame %d/dir/ec %d: ", frame, d ); + fprintf( pF_ele, "frame %d/dir/ec %d: ", frame, d ); + fprintf( pF_spcoh, "frame %d/dir %d: ", frame, d ); + fprintf( pF_ratio, "frame %d/dir %d: ", frame, d ); + + for ( b = start_band; b < nbands; b++ ) + { + for ( m = 0; m < q_direction->cfg.nblocks; m++ ) + { + + fprintf( pF_ratio, " %1.3f ", q_direction->band_data[b].energy_ratio[m] ); + fprintf( pF_azi, " %+5.2f ", (int16_t) ( 100.f * q_direction->band_data[b].azimuth[m] ) / 100.f ); + fprintf( pF_ele, " %+5.2f ", (int16_t) ( 100.f * q_direction->band_data[b].elevation[m] ) / 100.f ); + if ( q_direction->coherence_band_data != NULL ) + { + fprintf( pF_spcoh, " %d ", q_direction->coherence_band_data[b].spread_coherence[m] ); + } + } + } + fprintf( pF_ratio, "\n" ); + fprintf( pF_azi, "\n" ); + fprintf( pF_ele, "\n" ); + fprintf( pF_spcoh, "\n" ); +#endif } if ( hQMetaData->no_directions == 2 ) @@ -984,6 +1124,38 @@ int16_t ivas_qmetadata_dec_decode_hr_384_512( } } +#ifdef DEBUG_MODE_QMETADATA + for ( d = 0; d < hQMetaData->no_directions; d++ ) + { + q_direction = &hQMetaData->q_direction[d]; + nbands = q_direction->cfg.nbands; + start_band = q_direction->cfg.start_band; + + + if ( d == 0 ) + { + fprintf( pF_surcoh, "frame %d/dir %d: ", frame, d ); + } + for ( b = start_band; b < nbands; b++ ) + { + for ( m = 0; m < q_direction->cfg.nblocks; m++ ) + { + + + if ( d == 0 && hQMetaData->surcoh_band_data != NULL ) + { + fprintf( pF_surcoh, " %d ", hQMetaData->surcoh_band_data[b].surround_coherence[m] ); + } + } + } + + + if ( d == 0 ) + { + fprintf( pF_surcoh, "\n" ); + } + } +#endif /* Store status information for renderer use */ hQMetaData->ec_flag = 0; @@ -1031,6 +1203,21 @@ int16_t ivas_qmetadata_dec_sid_decode( float direction_vector[3]; int16_t metadata_sid_bits; /* bits allocated to SID for metadata */ int16_t bits_delta, bits_dir; +#ifdef DEBUG_MODE_QMETADATA + static FILE *pF = NULL; + static FILE *pF_azi = NULL; + static FILE *pF_ele = NULL; + static FILE *pF_ratio = NULL; + + if ( pF == NULL ) + pF = fopen( "./res/qmetadata_sid_dec.txt", "w" ); + if ( pF_azi == NULL ) + pF_azi = fopen( "./res/qmetadata_sid_azi_dec.txt", "w" ); + if ( pF_ele == NULL ) + pF_ele = fopen( "./res/qmetadata_sid_ele_dec.txt", "w" ); + if ( pF_ratio == NULL ) + pF_ratio = fopen( "./res/qmetadata_sid_ratio_dec.txt", "w" ); +#endif if ( ivas_format == SBA_FORMAT ) { @@ -1231,6 +1418,27 @@ int16_t ivas_qmetadata_dec_sid_decode( b = bitstream[( *index )--]; } +#ifdef DEBUG_MODE_QMETADATA + fprintf( pF, "frame %d: all %d ", frame, start_index - *index ); + + fprintf( pF_azi, "frame %d SID: ", frame ); + fprintf( pF_ele, "frame %d SID: ", frame ); + fprintf( pF_ratio, "frame %d SID: ", frame ); + + for ( b = start_band; b < nbands; b++ ) + { + for ( m = 0; m < nblocks; m++ ) + { + fprintf( pF_azi, " %+5.2f ", (int16_t) ( 100.f * q_direction->band_data[b].azimuth[m] ) / 100.f ); + fprintf( pF_ele, " %+5.2f ", (int16_t) ( 100.f * q_direction->band_data[b].elevation[m] ) / 100.f ); + fprintf( pF_ratio, " %1.3f ", q_direction->band_data[b].energy_ratio[m] ); + } + } + fprintf( pF_azi, "\n" ); + fprintf( pF_ele, "\n" ); + fprintf( pF_ratio, "\n" ); + +#endif return ( start_index - *index ); } @@ -2021,6 +2229,9 @@ static uint16_t ivas_qmetadata_DecodeQuasiUniform( int16_t i, bits; uint16_t tresh, value; +#ifdef DEBUGGING + assert( ( alphabet_size >= 1 ) ); +#endif bits = 30 - norm_l( alphabet_size ); /* bits = floor(log2(alphabet_size)) */ tresh = ( 1U << ( bits + 1 ) ) - alphabet_size; @@ -2036,6 +2247,9 @@ static uint16_t ivas_qmetadata_DecodeQuasiUniform( value = ( value << 1 ) - tresh + bitstream[( *index )--]; } +#ifdef DEBUGGING + assert( value < alphabet_size ); +#endif return value; } @@ -2078,6 +2292,9 @@ int16_t ivas_qmetadata_DecodeExtendedGR( } else { +#ifdef DEBUGGING + assert( bitstream[*index] == 0 ); +#endif ( *index )--; lsb = 0; for ( i = 0; i < gr_param; i++ ) @@ -2089,6 +2306,9 @@ int16_t ivas_qmetadata_DecodeExtendedGR( value = ( msb << gr_param ) + lsb; } +#ifdef DEBUGGING + assert( value < alph_size ); +#endif return value; } @@ -2987,6 +3207,9 @@ static int16_t read_common_direction( *pbit_pos = bit_pos; +#ifdef DEBUGGING + /*assert(nbits == bits_total); */ +#endif return nbits; } @@ -3149,6 +3372,12 @@ static ivas_error read_huf( } } +#ifdef DEBUGGING + if ( nbits == max_len ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Wrong Huffman codeword for average index in coherence encoding." ); + } +#endif *num_bits_read = end_pos; return IVAS_ERR_OK; @@ -3209,6 +3438,9 @@ static int16_t read_GR_min_removed_data( } } +#ifdef DEBUGGING + assert( nbits == *p_bit_pos - bit_pos ); +#endif *p_bit_pos = bit_pos; return nbits; @@ -3322,6 +3554,9 @@ static int16_t decode_fixed_rate_composed_index_coherence( { decoded_index[j] = temp_index[j]; } +#ifdef DEBUGGING + assert( nbits == *p_bit_pos - bit_pos ); +#endif nbits = *p_bit_pos - bit_pos; *p_bit_pos = bit_pos; @@ -3530,6 +3765,9 @@ static int16_t read_coherence_data( uint16_t spr_coh_temp_index[MASA_MAXIMUM_CODING_SUBBANDS]; no_cb = 1; +#ifdef DEBUGGING + assert( coding_subbands % 2 == 0 ); +#endif for ( j = 0; j < coding_subbands / 2; j++ ) { no_cb *= no_cv_vec[j]; @@ -3632,6 +3870,9 @@ static int16_t read_coherence_data( } } } +#ifdef DEBUGGING + assert( nbits == *p_bit_pos - bit_pos ); +#endif nbits = *p_bit_pos - bit_pos; *p_bit_pos = bit_pos; diff --git a/lib_dec/ivas_range_uni_dec.c b/lib_dec/ivas_range_uni_dec.c index 70ce6b84e..6fbbaa563 100644 --- a/lib_dec/ivas_range_uni_dec.c +++ b/lib_dec/ivas_range_uni_dec.c @@ -40,6 +40,9 @@ #include "options.h" #include "prot.h" #include "wmc_auto.h" +#ifdef DEBUGGING +#include "debug.h" +#endif /* @@ -117,6 +120,10 @@ uint16_t rc_uni_dec_read_symbol_fastS( uint16_t ceil_log2_alphabet_size; /* ceil(log2(alphabet_size)) */ uint16_t step; uint32_t reversed_low; +#ifdef DEBUGGING + assert( tot_shift <= 16 ); + assert( rc_st_dec->rc_range >= 0x01000000 ); /* rc_range is normalized */ +#endif low = rc_st_dec->rc_low; range = rc_st_dec->rc_range; @@ -220,6 +227,9 @@ uint16_t rc_uni_dec_read_bit( uint32_t val; uint32_t low; /* local copy (1 to 5 uses) */ uint32_t range; /* local copy (3 to 6 uses) */ +#ifdef DEBUGGING + assert( rc_st_dec->rc_range >= 0x01000000 ); /* rc_range is normalized */ +#endif low = rc_st_dec->rc_low; range = rc_st_dec->rc_range; @@ -278,6 +288,10 @@ uint16_t rc_uni_dec_read_bit_prob_fast( uint32_t val; uint32_t low; /* local copy (2 to 7 uses) */ uint32_t range; /* local copy (5 to 9 uses) */ +#ifdef DEBUGGING + assert( tot_shift <= 16 ); + assert( rc_st_dec->rc_range >= 0x01000000 ); /* rc_range is normalized */ +#endif low = rc_st_dec->rc_low; range = rc_st_dec->rc_range; @@ -345,6 +359,10 @@ uint16_t rc_uni_dec_read_bits( uint32_t val; uint32_t low; /* local copy (2 to 6 uses) */ uint32_t range; /* local copy (4 to 7 uses) */ +#ifdef DEBUGGING + assert( bits <= 16 ); + assert( rc_st_dec->rc_range >= 0x01000000 ); /* rc_range is normalized */ +#endif low = rc_st_dec->rc_low; range = rc_st_dec->rc_range; @@ -401,6 +419,9 @@ int16_t rc_uni_dec_finish( { int16_t total_bit_count; int16_t bits; +#ifdef DEBUGGING + assert( rc_st_dec->rc_range >= 0x01000000 ); /* rc_range is normalized */ +#endif /* floor(log2(x)) = floor(log2(x >> 24)) + 24, for any x >= 2 ^ 24 */ /* 32 - floor(log2(y)) = norm_ul(y) + 1 = norm_l(y >> 24) - 22 */ @@ -409,6 +430,9 @@ int16_t rc_uni_dec_finish( bits++; /* conservative number of bits, because the decoder only has rc_range available */ +#ifdef DEBUGGING + assert( ( bits >= 2 ) && ( bits <= 9 ) ); /* depends on rc_range, which is normalized */ +#endif total_bit_count = ( rc_st_dec->bit_count - 32 ) + bits; @@ -466,6 +490,16 @@ static int16_t rc_uni_dec_read( return 0; /* reading the 8 bits would trigger an out-of-bounds array access */ } +#ifdef DEBUGGING + /* shifted_bit_buffer[i] must contain only binary values */ + { + int16_t i; + for ( i = 0; i < 8; ++i ) + { + assert( shifted_bit_buffer[i] <= 1 ); + } + } +#endif /* pack the first 8 bits from shifted_bit_buffer, first bit is most significant */ byte_read = ( (int16_t) shifted_bit_buffer[0] << 7 ) | ( (int16_t) shifted_bit_buffer[1] << 6 ) | diff --git a/lib_dec/ivas_rom_dec.c b/lib_dec/ivas_rom_dec.c index 0ab45b6f1..d05bf16fe 100644 --- a/lib_dec/ivas_rom_dec.c +++ b/lib_dec/ivas_rom_dec.c @@ -32,6 +32,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "ivas_cnst.h" #include @@ -398,6 +401,142 @@ const float dmxmtx_table[BINAURAL_CHANNELS][11] = }; +#ifdef SPLIT_REND_WITH_HEAD_ROT +/*----------------------------------------------------------------------* + * Binuaral split rendering ROM tables + *-----------------------------------------------------------------------*/ + +/* rotations in this array are relative to ref rotation */ +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 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}; + +const int16_t ivas_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 ivas_split_rend_huff_p_d_consts[IVAS_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 ivas_split_rend_huff_p_d_diff_consts[IVAS_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 }, + { 8, 9, 510 },{ 9, 10, 1022 },{ 10, 11, 2046 },{ 11, 12, 4094 }, + { 12, 13, 8190 },{ 13, 14, 16382 },{ 14, 14, 16383 } +}; + +const int32_t ivas_split_rend_huff_d_consts[IVAS_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 }, + { 8, 9, 510 },{ 9, 10, 1022 },{ 10, 11, 2046 },{ 11, 12, 4094 }, + { 12, 13, 8190 },{ 13, 14, 16382 },{ 14, 14, 16383 } +}; + +const int32_t ivas_split_rend_huff_pred63_consts[IVAS_SPLIT_REND_PRED_63QUANT_PNTS][3] = +{ + {-31,11,2040}, + {-30,11,2041}, + {-29,11,2042}, + {-28,11,2043}, + {-27,10,1012}, + {-26,10,1013}, + {-25,10,1014}, + {-24,10,1015}, + {-23,9,498}, + {-22,9,499}, + {-21,9,500}, + {-20,9,501}, + {-19,8,242}, + {-18,8,243}, + {-17,8,244}, + {-16,8,245}, + {-15,7,112}, + {-14,7,113}, + {-13,7,114}, + {-12,7,115}, + {-11,6,48}, + {-10,6,49}, + {-9,6,50}, + {-8,6,51}, + {-7,5,16}, + {-6,5,17}, + {-5,5,18}, + {-4,5,19}, + {-3,4,2}, + {-2,4,3}, + {-1,4,4}, + {0,3,0}, + {1,4,5}, + {2,4,6}, + {3,4,7}, + {4,5,20}, + {5,5,21}, + {6,5,22}, + {7,5,23}, + {8,6,52}, + {9,6,53}, + {10,6,54}, + {11,6,55}, + {12,7,116}, + {13,7,117}, + {14,7,118}, + {15,7,119}, + {16,7,120}, + {17,8,246}, + {18,8,247}, + {19,8,248}, + {20,9,502}, + {21,9,503}, + {22,9,504}, + {23,9,505}, + {24,10,1016}, + {25,10,1017}, + {26,10,1018}, + {27,10,1019}, + {28,11,2044}, + {29,11,2045}, + {30,11,2046}, + {31,11,2047}, +}; + +const int32_t ivas_split_rend_huff_pred31_consts[IVAS_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}, + {-7,6,56},{-6,6,57},{-5,5,24},{-4,5,25},{-3,4,8}, + {-2,4,9},{-1,3,2},{0,2,0},{1,3,3}, + {2,4,10},{3,4,11},{4,5,26},{5,5,27}, + {6,6,58},{7,6,59},{8,7,122},{9,7,123}, + {10,7,124},{11,8,252},{12,9,508},{13,9,509}, + {14,10,1022},{15,10,1023}, +}; + +const int32_t ivas_split_rend_huff_roll_pred_consts[IVAS_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}, + {-7,6,56},{-6,6,57},{-5,5,24},{-4,5,25},{-3,4,8}, + {-2,4,9},{-1,3,2},{0,2,0},{1,3,3}, + {2,4,10},{3,4,11},{4,5,26},{5,5,27}, + {6,6,58},{7,6,59},{8,7,122},{9,7,123}, + {10,7,124},{11,8,252},{12,9,508},{13,9,509}, +{14,10,1022},{15,10,1023}, +}; + +#endif /*----------------------------------------------------------------------* @@ -441,6 +580,29 @@ static const int16_t huff_nodes_first_band_alpha[32][2] = { -2, -32 } }; +#ifndef FIX_891_PARAMUPMIX_CLEANUP +/* Alpha Coarse Huffman table df0 */ +static const int16_t huff_nodes_first_band_alpha_coarse[16][2] = +{ + { -9, 1 }, + { -8, 2 }, + { -10, 3 }, + { 5, 4 }, + { -7, 6 }, + { -11, 7 }, + { -5, 8 }, + { -6, 9 }, + { -12, 10 }, + { -13, 11 }, + { -4, 12 }, + { -14, 13 }, + { -3, 14 }, + { -15, 15 }, + { -2, -16 }, + { -1, -17 } +}; + +#endif /* Alpha Fine Huffman table df */ static const int16_t huff_nodes_alpha_1D_DF[64][2] = { @@ -510,6 +672,45 @@ static const int16_t huff_nodes_alpha_1D_DF[64][2] = { -2, -62 } }; +#ifndef FIX_891_PARAMUPMIX_CLEANUP +/* Alpha Coarse Huffman table df */ +static const int16_t huff_nodes_alpha_1D_DF_coarse[32][2] = +{ + { -17, 1 }, + { -18, 2 }, + { -16, 3 }, + { -15, 4 }, + { -19, 5 }, + { 7, 6 }, + { -14, -20 }, + { 9, 8 }, + { -13, -21 }, + { 11, 10 }, + { -22, 12 }, + { -12, 13 }, + { -23, 14 }, + { -11, 15 }, + { -10, 16 }, + { -24, 17 }, + { -9, -25 }, + { 19, 18 }, + { -26, 20 }, + { -8, 21 }, + { 23, 22 }, + { 25, 24 }, + { -27, 26 }, + { -7, 27 }, + { -1, -33 }, + { -6, 28 }, + { -28, 29 }, + { -29, 30 }, + { -5, -31 }, + { -30, 31 }, + { -3, -4 }, + { -2, -32 } +}; + +#endif /* Alpha Fine Huffman table dt */ static const int16_t huff_nodes_alpha_1D_DT[64][2] = { @@ -579,25 +780,88 @@ static const int16_t huff_nodes_alpha_1D_DT[64][2] = { -2, -63 } }; +#ifndef FIX_891_PARAMUPMIX_CLEANUP +/* Alpha Coarse Huffman table dt */ +static const int16_t huff_nodes_alpha_1D_DT_coarse[32][2] = +{ + { -17, 1 }, + { -18, 2 }, + { -16, 3 }, + { -19, 4 }, + { -15, 5 }, + { 7, 6 }, + { -14, -20 }, + { 9, 8 }, + { -21, 10 }, + { -13, 11 }, + { 13, 12 }, + { -12, -22 }, + { 15, 14 }, + { -11, -23 }, + { 17, 16 }, + { -24, 18 }, + { -10, 19 }, + { -25, 20 }, + { -9, 21 }, + { 23, 22 }, + { -26, 24 }, + { -8, 25 }, + { 27, 26 }, + { -1, -33 }, + { -7, -27 }, + { 29, 28 }, + { -28, 30 }, + { -6, 31 }, + { -5, -29 }, + { -3, -31 }, + { -4, -30 }, + { -2, -32 } +}; + +#endif /* Beta Fine Huffman table df0 */ static const int16_t huff_nodes_first_band_beta[8][2] = { { -1, 1 }, { -2, 2 }, { -3, 3 }, { -4, 4 }, { -5, 5 }, { -6, 6 }, { -7, 7 }, { -8, -9 } }; +#ifndef FIX_891_PARAMUPMIX_CLEANUP +/* Beta Coarse Huffman table df0 */ +static const int16_t huff_nodes_first_band_beta_coarse[4][2] = +{ + { -1, 1 }, { -2, 2 }, { -3, 3 }, { -4, -5 } +}; + +#endif /* Beta Fine Huffman table df */ static const int16_t huff_nodes_beta_1D_DF[16][2] = { { -9, 1 }, { -10, 2 }, { -8, 3 }, { -11, 4 }, { -7, 5 }, { 7, 6 }, { -6, -12 }, { 9, 8 }, { -5, -13 }, { 11, 10 }, { -4, -14 }, { -15, 12 }, { -3, 13 }, { -16, 14 }, { -2, 15 }, { -1, -17 } }; +#ifndef FIX_891_PARAMUPMIX_CLEANUP +/* Beta Coarse Huffman table df */ +static const int16_t huff_nodes_beta_1D_DF_coarse[8][2] = +{ + { -5, 1 }, { -6, 2 }, { -4, 3 }, { -3, 4 }, { -7, 5 }, { -2, 6 }, { -8, 7 }, { -1, -9 } +}; + +#endif /* Beta Fine Huffman table dt */ static const int16_t huff_nodes_beta_1D_DT[16][2] = { { -9, 1 }, { -10, 2 }, { -8, 3 }, { -11, 4 }, { -7, 5 }, { 7, 6 }, { -6, -12 }, { -13, 8 }, { -5, 9 }, { -14, 10 }, { -4, 11 }, { -15, 12 }, { -3, 13 }, { -16, 14 }, { -2, 15 }, { -1, -17 } }; +#ifndef FIX_891_PARAMUPMIX_CLEANUP +/* Beta Coarse Huffman table dt */ +static const int16_t huff_nodes_beta_1D_DT_coarse[8][2] = +{ + { -5, 1 }, { -6, 2 }, { -4, 3 }, { -7, 4 }, { -3, 5 }, { -8, 6 }, { -2, 7 }, { -1, -9 } +}; +#endif +#ifdef FIX_891_PARAMUPMIX_CLEANUP const HUFF_NODE_TABLE ivas_mc_paramupmix_huff_nodes_df0 = { huff_nodes_first_band_alpha, @@ -615,6 +879,24 @@ const HUFF_NODE_TABLE ivas_mc_paramupmix_huff_nodes_dt = huff_nodes_alpha_1D_DT, huff_nodes_beta_1D_DT }; +#else +const HUFF_NODE_TABLE ivas_mc_paramupmix_huff_nodes_df0 = +{ + { huff_nodes_first_band_alpha, huff_nodes_first_band_alpha_coarse }, + { huff_nodes_first_band_beta, huff_nodes_first_band_beta_coarse } +}; +const HUFF_NODE_TABLE ivas_mc_paramupmix_huff_nodes_df = +{ + { huff_nodes_alpha_1D_DF, huff_nodes_alpha_1D_DF_coarse }, + { huff_nodes_beta_1D_DF, huff_nodes_beta_1D_DF_coarse } +}; + +const HUFF_NODE_TABLE ivas_mc_paramupmix_huff_nodes_dt = +{ + { huff_nodes_alpha_1D_DT, huff_nodes_alpha_1D_DT_coarse }, + { huff_nodes_beta_1D_DT, huff_nodes_beta_1D_DT_coarse } +}; +#endif /* clang-format on */ diff --git a/lib_dec/ivas_rom_dec.h b/lib_dec/ivas_rom_dec.h index 4ff133596..46bc99352 100644 --- a/lib_dec/ivas_rom_dec.h +++ b/lib_dec/ivas_rom_dec.h @@ -35,6 +35,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "ivas_cnst.h" #include "ivas_stat_dec.h" @@ -100,6 +103,31 @@ extern const float dirac_dithering_ele_scale[DIRAC_DIFFUSE_LEVELS]; extern const float dmxmtx_table[BINAURAL_CHANNELS][11]; +#ifdef SPLIT_REND_WITH_HEAD_ROT +/*----------------------------------------------------------------------* + * Binuaral split rendering ROM tables + *-----------------------------------------------------------------------*/ + +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 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 ivas_split_rend_relative_pos_angles[MAX_HEAD_ROT_POSES][3]; +extern const int16_t ivas_split_rend_band_grouping[MAX_SPLIT_REND_MD_BANDS + 1]; +extern const int32_t ivas_split_rend_huff_d_consts[IVAS_SPLIT_REND_D_QUANT_PNTS][3]; +extern const int32_t ivas_split_rend_huff_pred63_consts[IVAS_SPLIT_REND_PRED_31QUANT_PNTS][3]; +extern const int32_t ivas_split_rend_huff_pred31_consts[IVAS_SPLIT_REND_PRED_31QUANT_PNTS][3]; +extern const int32_t ivas_split_rend_huff_roll_pred_consts[IVAS_SPLIT_REND_ROLL_PRED_QUANT_PNTS][3]; +extern const int32_t ivas_split_rend_huff_p_d_consts[IVAS_SPLIT_REND_D_QUANT_PNTS][3]; +extern const int32_t ivas_split_rend_huff_p_d_diff_consts[IVAS_SPLIT_REND_D_QUANT_PNTS][3]; +extern const int32_t split_rend_brate_tbl[]; +#endif /*----------------------------------------------------------------------* diff --git a/lib_dec/ivas_sba_dec.c b/lib_dec/ivas_sba_dec.c index 3be1d2ff3..d5b5d8ff1 100644 --- a/lib_dec/ivas_sba_dec.c +++ b/lib_dec/ivas_sba_dec.c @@ -41,6 +41,9 @@ #include "ivas_rom_com.h" #include "ivas_rom_dec.h" #include +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" @@ -100,7 +103,12 @@ void ivas_sba_set_cna_cng_flag( ivas_error ivas_sba_dec_reconfigure( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ uint16_t *nSamplesFlushed, /* o : number of samples flushed */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + const PCM_RESOLUTION pcm_resolution, /* i : type for the decoded PCM resolution */ + void *data /* o : output synthesis signal */ +#else int16_t *data /* o : output synthesis signal */ +#endif ) { int16_t nchan_transport_old, nSCE_old, nCPE_old, nchan_hp20_old; @@ -111,6 +119,9 @@ ivas_error ivas_sba_dec_reconfigure( int32_t last_ivas_total_brate; int16_t num_channels, num_md_sub_frames; int16_t nchan_out_buff, nchan_out_buff_old; +#ifndef NONBE_UNIFIED_DECODING_PATHS + int16_t sba_analysis_order_old; +#endif int16_t sba_analysis_order_old_flush; DECODER_CONFIG_HANDLE hDecoderConfig; ivas_error error; @@ -122,13 +133,20 @@ ivas_error ivas_sba_dec_reconfigure( ivas_total_brate = hDecoderConfig->ivas_total_brate; last_ivas_total_brate = st_ivas->last_active_ivas_total_brate; sba_analysis_order_old_flush = st_ivas->sba_analysis_order; +#ifndef NONBE_UNIFIED_DECODING_PATHS + sba_analysis_order_old = ivas_sba_get_analysis_order( last_ivas_total_brate, st_ivas->sba_order ); +#endif /*-----------------------------------------------------------------* * Set SBA high-level parameters * Save old SBA high-level parameters *-----------------------------------------------------------------*/ +#ifdef NONBE_UNIFIED_DECODING_PATHS nchan_out_buff_old = ivas_get_nchan_buffers_dec( st_ivas, sba_analysis_order_old_flush, last_ivas_total_brate ); +#else + nchan_out_buff_old = ivas_get_nchan_buffers_dec( st_ivas, sba_analysis_order_old, last_ivas_total_brate ); +#endif ivas_init_dec_get_num_cldfb_instances( st_ivas, &numCldfbAnalyses_old, &numCldfbSyntheses_old ); nchan_hp20_old = getNumChanSynthesis( st_ivas ); @@ -171,7 +189,11 @@ ivas_error ivas_sba_dec_reconfigure( /* copy the logic from ivas_renderer_select(), because calling this function has too many side effects that would affect the flushing */ if ( ivas_get_sba_num_TCs( ivas_total_brate, sba_order_internal ) <= 2 ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) +#else if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL ) +#endif { renderer_type_new = RENDERER_BINAURAL_PARAMETRIC; } @@ -183,6 +205,9 @@ ivas_error ivas_sba_dec_reconfigure( else { if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB +#ifdef SPLIT_REND_WITH_HEAD_ROT + || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM +#endif ) { renderer_type_new = RENDERER_BINAURAL_FASTCONV; @@ -209,7 +234,11 @@ ivas_error ivas_sba_dec_reconfigure( st_ivas->sba_analysis_order = sba_analysis_order_old_flush; st_ivas->hDecoderConfig->ivas_total_brate = last_ivas_total_brate; +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( error = ivas_jbm_dec_flush_renderer( st_ivas, granularity_new, st_ivas->renderer_type, st_ivas->intern_config, &st_ivas->hIntSetup, st_ivas->mc_mode, ism_mode_old, nSamplesFlushed, pcm_resolution, data ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_jbm_dec_flush_renderer( st_ivas, granularity_new, st_ivas->renderer_type, st_ivas->intern_config, &st_ivas->hIntSetup, st_ivas->mc_mode, ism_mode_old, nSamplesFlushed, data ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -224,6 +253,7 @@ ivas_error ivas_sba_dec_reconfigure( { return error; } +#ifdef NONBE_FIX_904_JBM_SBA_RS_FOA /* make sure the changed number of slots in the last subframe is not lost in the following steps */ if ( st_ivas->hSpatParamRendCom != NULL ) @@ -231,6 +261,7 @@ ivas_error ivas_sba_dec_reconfigure( st_ivas->hSpatParamRendCom->subframe_nbslots[st_ivas->hSpatParamRendCom->nb_subframes - 1] = st_ivas->hTcBuffer->subframe_nbslots[st_ivas->hTcBuffer->nb_subframes - 1]; } st_ivas->hSpar->subframe_nbslots[st_ivas->hSpar->nb_subframes - 1] = st_ivas->hTcBuffer->subframe_nbslots[st_ivas->hTcBuffer->nb_subframes - 1]; +#endif } } @@ -371,8 +402,10 @@ ivas_error ivas_sba_dec_reconfigure( } if ( ( error = ivas_dirac_sba_config( st_ivas->hQMetaData, &st_ivas->element_mode_init, ivas_total_brate, st_ivas->sba_analysis_order, ivas_get_hodirac_flag( ivas_total_brate, st_ivas->sba_analysis_order ) ? IVAS_MAX_NUM_BANDS : ( IVAS_MAX_NUM_BANDS - SPAR_DIRAC_SPLIT_START_BAND ) +#ifdef NONBE_FIX_871_ACELP_CRASH_IN_OSBA , st_ivas->ivas_format +#endif ) ) != IVAS_ERR_OK ) { return error; @@ -541,12 +574,21 @@ ivas_error ivas_sba_dec_reconfigure( * TD Decorrelator *-----------------------------------------------------------------*/ +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( st_ivas->hDiracDecBin[0] != NULL ) + { + if ( ( error = ivas_td_decorr_reconfig_dec( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->nchan_transport, st_ivas->hDecoderConfig->output_Fs, &( st_ivas->hDiracDecBin[0]->hTdDecorr ), &( st_ivas->hDiracDecBin[0]->useTdDecorr ) ) ) != IVAS_ERR_OK ) + { + return error; + } +#else if ( st_ivas->hDiracDecBin != NULL ) { if ( ( error = ivas_td_decorr_reconfig_dec( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->nchan_transport, st_ivas->hDecoderConfig->output_Fs, &( st_ivas->hDiracDecBin->hTdDecorr ), &( st_ivas->hDiracDecBin->useTdDecorr ) ) ) != IVAS_ERR_OK ) { return error; } +#endif } /*-----------------------------------------------------------------* @@ -562,6 +604,9 @@ ivas_error ivas_sba_dec_reconfigure( * JBM TC buffers *-----------------------------------------------------------------*/ +#ifndef NONBE_UNIFIED_DECODING_PATHS + if ( st_ivas->hDecoderConfig->Opt_5ms == 1 || st_ivas->ivas_format == SBA_ISM_FORMAT ) +#endif { int16_t tc_nchan_to_allocate; int16_t tc_nchan_tc; @@ -615,6 +660,7 @@ ivas_error ivas_sba_dec_reconfigure( } /* resync SPAR and DirAC JBM info from TC Buffer */ +#ifdef NONBE_FIX_904_JBM_SBA_RS_FOA if ( st_ivas->hSpatParamRendCom != NULL && st_ivas->hSpatParamRendCom->slot_size == st_ivas->hTcBuffer->n_samples_granularity ) { mvs2s( st_ivas->hTcBuffer->subframe_nbslots, st_ivas->hSpatParamRendCom->subframe_nbslots, MAX_JBM_SUBFRAMES_5MS ); @@ -624,6 +670,21 @@ ivas_error ivas_sba_dec_reconfigure( mvs2s( st_ivas->hTcBuffer->subframe_nbslots, st_ivas->hSpar->subframe_nbslots, MAX_JBM_SUBFRAMES_5MS ); st_ivas->hSpar->nb_subframes = st_ivas->hTcBuffer->nb_subframes; st_ivas->hSpar->subframes_rendered = st_ivas->hTcBuffer->subframes_rendered; +#else + if ( st_ivas->hSpatParamRendCom != NULL ) + { + if ( st_ivas->hSpatParamRendCom->slot_size == st_ivas->hTcBuffer->n_samples_granularity ) + { + mvs2s( st_ivas->hTcBuffer->subframe_nbslots, st_ivas->hSpatParamRendCom->subframe_nbslots, MAX_JBM_SUBFRAMES_5MS ); + st_ivas->hSpatParamRendCom->nb_subframes = st_ivas->hTcBuffer->nb_subframes; + st_ivas->hSpatParamRendCom->subframes_rendered = st_ivas->hTcBuffer->subframes_rendered; + + mvs2s( st_ivas->hTcBuffer->subframe_nbslots, st_ivas->hSpar->subframe_nbslots, MAX_JBM_SUBFRAMES_5MS ); + st_ivas->hSpar->nb_subframes = st_ivas->hTcBuffer->nb_subframes; + st_ivas->hSpar->subframes_rendered = st_ivas->hTcBuffer->subframes_rendered; + } + } +#endif if ( st_ivas->ivas_format == SBA_ISM_FORMAT && st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV && st_ivas->ism_mode == ISM_SBA_MODE_DISC ) { @@ -632,7 +693,9 @@ ivas_error ivas_sba_dec_reconfigure( for ( n = 0; n < MAX_JBM_SUBFRAMES_5MS; n++ ) { st_ivas->hSpatParamRendCom->subframe_nbslots[n] = st_ivas->hTcBuffer->subframe_nbslots[n] * granularityMultiplier; +#ifdef NONBE_FIX_904_JBM_SBA_RS_FOA st_ivas->hSpar->subframe_nbslots[n] = st_ivas->hSpatParamRendCom->subframe_nbslots[n]; +#endif } } @@ -640,12 +703,19 @@ ivas_error ivas_sba_dec_reconfigure( * floating-point output audio buffers *-----------------------------------------------------------------*/ +#ifndef NONBE_UNIFIED_DECODING_PATHS + if ( !st_ivas->hDecoderConfig->Opt_5ms ) + { +#endif nchan_out_buff = ivas_get_nchan_buffers_dec( st_ivas, st_ivas->sba_analysis_order, st_ivas->hDecoderConfig->ivas_total_brate ); if ( ( error = ivas_output_buff_dec( st_ivas->p_output_f, nchan_out_buff_old, nchan_out_buff ) ) != IVAS_ERR_OK ) { return error; } +#ifndef NONBE_UNIFIED_DECODING_PATHS + } +#endif return error; } @@ -676,7 +746,11 @@ void ivas_sba_dec_digest_tc( ivas_spar_dec_digest_tc( st_ivas, st_ivas->nchan_transport, nCldfbSlots, nSamplesForRendering ); } +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( st_ivas->hDiracDecBin[0] != NULL && st_ivas->hDiracDecBin[0]->useTdDecorr ) +#else if ( st_ivas->hDiracDecBin != NULL && ( st_ivas->hDiracDecBin->useTdDecorr ) ) +#endif { int16_t nSamplesLeftForTD, default_frame; float *decorr_signal[BINAURAL_CHANNELS]; @@ -695,9 +769,17 @@ void ivas_sba_dec_digest_tc( { int16_t nSamplesToDecorr = min( nSamplesLeftForTD, default_frame ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( st_ivas->hDiracDecBin[0]->hTdDecorr ) +#else if ( st_ivas->hDiracDecBin->hTdDecorr ) +#endif { +#ifdef SPLIT_REND_WITH_HEAD_ROT + ivas_td_decorr_process( st_ivas->hDiracDecBin[0]->hTdDecorr, p_tc, decorr_signal, nSamplesToDecorr ); +#else ivas_td_decorr_process( st_ivas->hDiracDecBin->hTdDecorr, p_tc, decorr_signal, nSamplesToDecorr ); +#endif } for ( ch_idx = 0; ch_idx < BINAURAL_CHANNELS; ch_idx++ ) @@ -754,6 +836,9 @@ ivas_error ivas_sba_dec_render( nchan_internal = ivas_sba_get_nchan_metadata( st_ivas->sba_analysis_order, st_ivas->hDecoderConfig->ivas_total_brate ); nchan_out = st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe; +#ifdef DEBUGGING + assert( hSpar ); +#endif for ( ch = 0; ch < nchan_out; ch++ ) { output_f_local[ch] = output_f[ch]; @@ -772,6 +857,9 @@ ivas_error ivas_sba_dec_render( slots_to_render -= hSpar->subframe_nbslots[last_sf]; last_sf++; } +#ifdef DEBUGGING + assert( slots_to_render == 0 ); +#endif for ( subframe_idx = first_sf; subframe_idx < last_sf; subframe_idx++ ) { @@ -783,8 +871,10 @@ ivas_error ivas_sba_dec_render( output_f_local[ch] += n_samples_sf; } +#ifdef NONBE_UNIFIED_DECODING_PATHS /* update combined orientation access index */ ivas_combined_orientation_update_index( st_ivas->hCombinedOrientationData, n_samples_sf ); +#endif } if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_DEC ) diff --git a/lib_dec/ivas_sba_dirac_stereo_dec.c b/lib_dec/ivas_sba_dirac_stereo_dec.c index d8487479f..6c5ecdb3e 100644 --- a/lib_dec/ivas_sba_dirac_stereo_dec.c +++ b/lib_dec/ivas_sba_dirac_stereo_dec.c @@ -39,6 +39,9 @@ #include "ivas_prot.h" #include "ivas_rom_com.h" #include "ivas_rom_dec.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" @@ -99,10 +102,18 @@ void ivas_sba_dirac_stereo_config( { if ( hConfig != NULL ) { +#ifndef DEBUG_STEREO_DFT_NOSTEREO hConfig->dmx_active = STEREO_DFT_DMX_ACTIVE; +#else + hConfig->dmx_active = 0; +#endif hConfig->band_res = STEREO_DFT_BAND_RES_HIGH; hConfig->prm_res = 2; +#ifdef DEBUG_MODE_DFT + hConfig->itd_mode = 0; + hConfig->gipd_mode = 0; +#endif hConfig->res_pred_mode = STEREO_DFT_RESPRED_ESF; hConfig->res_cod_mode = STEREO_DFT_RES_COD_OFF; @@ -923,11 +934,13 @@ void ivas_sba_dirac_stereo_dec( } } +#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX /* reset the other channels to 0 (they are not used since here) */ for ( int16_t ch = CPE_CHANNELS; ch < st_ivas->nchan_transport; ch++ ) { set_zero( output[ch], output_frame ); } +#endif return; } diff --git a/lib_dec/ivas_sba_rendering_internal.c b/lib_dec/ivas_sba_rendering_internal.c index 692e1a4cf..a87cdaca3 100644 --- a/lib_dec/ivas_sba_rendering_internal.c +++ b/lib_dec/ivas_sba_rendering_internal.c @@ -38,9 +38,19 @@ #include "ivas_stat_dec.h" #include "ivas_cnst.h" #include +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" +#ifdef DEBUG_MODE_DIRAC +/*-----------------------------------------------------------------------* + * Local function prototypes + *-----------------------------------------------------------------------*/ + +static void debug_mode_dirac( float output[MAX_OUTPUT_CHANNELS][L_FRAME48k], const int16_t nchan_transport, const int16_t output_frame ); +#endif /*-------------------------------------------------------------------------* @@ -291,6 +301,9 @@ int16_t ivas_sba_remapTCs( { int16_t nchan_remapped; +#ifdef DEBUG_MODE_DIRAC + debug_mode_dirac( sba_data, st_ivas->nchan_transport, output_frame ); +#endif nchan_remapped = st_ivas->nchan_transport; if ( nchan_remapped == 3 ) @@ -326,6 +339,70 @@ int16_t ivas_sba_remapTCs( return ( nchan_remapped ); } +#ifndef NONBE_UNIFIED_DECODING_PATHS_FIX +/*-------------------------------------------------------------------------* + * ivas_ism2sba() + * + * ISM transformed into SBA in TD domain. + *-------------------------------------------------------------------------*/ + +void ivas_ism2sba( + float *buffer_td[], /* i/o: TD signal buffers */ + ISM_RENDERER_HANDLE hIsmRendererData, /* i/o: renderer data */ + const ISM_METADATA_HANDLE hIsmMetaData[], /* i : object metadata */ + const int16_t nchan_ism, /* i : number of objects */ + const int16_t output_frame, /* i : output frame length per channel */ + const int16_t sba_order /* i : Ambisonic (SBA) order */ +) +{ + int16_t i, j, k; + float buffer_tmp[16][L_FRAME48k]; + float gains[16]; + float g1, g2; + int16_t azimuth, elevation; + int16_t sba_num_chans; + + assert( ( sba_order <= 3 ) && "Only order up to 3 is supported!" ); + assert( hIsmRendererData != NULL && "hIsmRendererData not allocated!" ); + + /* Init*/ + sba_num_chans = ( sba_order + 1 ) * ( sba_order + 1 ); + for ( j = 0; j < sba_num_chans; j++ ) + { + set_zero( buffer_tmp[j], output_frame ); + } + + for ( i = 0; i < nchan_ism; i++ ) + { + // TODO tmu review when #215 is resolved + azimuth = (int16_t) floorf( hIsmMetaData[i]->azimuth + 0.5f ); + elevation = (int16_t) floorf( hIsmMetaData[i]->elevation + 0.5f ); + + /*get HOA gets for direction (ACN/SN3D)*/ + ivas_dirac_dec_get_response( azimuth, elevation, gains, sba_order ); + + for ( j = 0; j < sba_num_chans; j++ ) + { + g1 = 1.f; + g2 = 0.f; + for ( k = 0; k < output_frame; k++ ) + { + buffer_tmp[j][k] += ( g2 * gains[j] + g1 * hIsmRendererData->prev_gains[i][j] ) * buffer_td[i][k]; + g2 += 1.f / ( output_frame - 1 ); + g1 = 1.0f - g2; + } + hIsmRendererData->prev_gains[i][j] = gains[j]; + } + } + + for ( j = 0; j < sba_num_chans; j++ ) + { + mvr2r( buffer_tmp[j], buffer_td[j], output_frame ); + } + + return; +} +#endif /*-------------------------------------------------------------------------* @@ -346,7 +423,9 @@ void ivas_ism2sba_sf( { int16_t i, j, k; float g1, *g2, *tc, *out, gain, prev_gain; +#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX float buffer_tmp[HOA3_CHANNELS][L_FRAME48k]; // VE2SB: TBV +#endif int16_t sba_num_chans; assert( ( sba_order <= 3 ) && "Only order up to 3 is supported!" ); @@ -356,7 +435,11 @@ void ivas_ism2sba_sf( sba_num_chans = ( sba_order + 1 ) * ( sba_order + 1 ); for ( j = 0; j < sba_num_chans; j++ ) { +#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX set_zero( buffer_tmp[j], n_samples_to_render ); +#else + set_zero( buffer_out[j], n_samples_to_render ); +#endif } for ( i = 0; i < num_objects; i++ ) @@ -365,7 +448,11 @@ void ivas_ism2sba_sf( { g2 = hIsmRendererData->interpolator + offset; tc = buffer_in[i] + offset; +#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX out = buffer_tmp[j]; +#else + out = buffer_out[j]; +#endif gain = hIsmRendererData->gains[i][j]; prev_gain = hIsmRendererData->prev_gains[i][j]; for ( k = 0; k < n_samples_to_render; k++ ) @@ -376,14 +463,68 @@ void ivas_ism2sba_sf( } } +#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX for ( j = 0; j < sba_num_chans; j++ ) { mvr2r( buffer_tmp[j], buffer_out[j], n_samples_to_render ); } +#endif return; } +#ifndef NONBE_UNIFIED_DECODING_PATHS_FIX +/*-------------------------------------------------------------------* + * ivas_sba_upmixer_renderer() + * + * SBA upmix & rendering + *-------------------------------------------------------------------*/ + +ivas_error ivas_sba_upmixer_renderer( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder struct */ + float *output[], /* i/o: transport/output audio channels */ + const int16_t output_frame /* i : output frame length */ +) +{ + int16_t nchan_internal; + int16_t sba_ch_idx; + ivas_error error; + + push_wmops( "ivas_sba_upmixer_renderer" ); + nchan_internal = ivas_sba_get_nchan_metadata( st_ivas->sba_analysis_order, st_ivas->hDecoderConfig->ivas_total_brate ); + + /* Upmixer + Renderer */ + ivas_spar_dec_upmixer( st_ivas, output, nchan_internal, output_frame ); + + if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_DEC ) + { + float *output_f[MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS]; + int16_t ch; + AUDIO_CONFIG output_config; + + output_config = ( st_ivas->ivas_format == SBA_ISM_FORMAT ? st_ivas->hOutSetup.output_config : st_ivas->hDecoderConfig->output_config ); + + sba_ch_idx = 0; + if ( st_ivas->ivas_format == SBA_ISM_FORMAT && st_ivas->ism_mode == ISM_SBA_MODE_DISC ) + { + sba_ch_idx = st_ivas->nchan_ism; + } + + for ( ch = 0; ch < ivas_get_nchan_buffers_dec( st_ivas, st_ivas->sba_analysis_order, st_ivas->hDecoderConfig->ivas_total_brate ) - sba_ch_idx; ch++ ) + { + output_f[ch] = output[ch]; + } + + if ( ( error = ivas_sba_linear_renderer( output_f, output_frame, st_ivas->hIntSetup.nchan_out_woLFE, st_ivas->nchan_ism, output_config, st_ivas->hOutSetup ) ) != IVAS_ERR_OK ) + { + return error; + } + } + pop_wmops(); + + return IVAS_ERR_OK; +} +#endif /*-------------------------------------------------------------------* * ivas_sba_linear_renderer() @@ -508,3 +649,43 @@ void ivas_sba_mix_matrix_determiner( } +#ifdef DEBUG_MODE_DIRAC +/*-----------------------------------------------------------------------* + * Debugging function + *-----------------------------------------------------------------------*/ + +static void debug_mode_dirac( + float output[MAX_OUTPUT_CHANNELS][L_FRAME48k], + const int16_t nchan_transport, + const int16_t output_frame ) +{ + int16_t i, n; + int16_t tmp[L_FRAME48k]; + char file_name[50] = { 0 }; + +#ifdef DEBUG_MODE_DIRAC_NOCORE + for ( n = 0; n < nchan_transport; n++ ) + { + sprintf( file_name, "./res/ivas_dirac_enc_%d.%d.pcm", n, (int16_t) ( output_frame * 0.05 ) ); + dbgread( tmp, sizeof( int16_t ), output_frame, file_name ); + for ( i = 0; i < output_frame; i++ ) + { + output[n][i] = (float) ( tmp[i] ); + } + } +#else + for ( n = 0; n < nchan_transport; n++ ) + { + for ( i = 0; i < output_frame; i++ ) + { + tmp[i] = (int16_t) ( output[n][i] + 0.5f ); + } + + sprintf( file_name, "./res/ivas_dirac_dec_%d.%d.pcm", n, (int16_t) ( output_frame * 0.05 ) ); + dbgwrite( tmp, sizeof( int16_t ), output_frame, 1, file_name ); + } +#endif + + return; +} +#endif diff --git a/lib_dec/ivas_sce_dec.c b/lib_dec/ivas_sce_dec.c index 752ce0e95..36ec1386a 100644 --- a/lib_dec/ivas_sce_dec.c +++ b/lib_dec/ivas_sce_dec.c @@ -39,6 +39,9 @@ #include "prot.h" #include "ivas_prot.h" #include "ivas_rom_com.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" @@ -139,6 +142,9 @@ ivas_error ivas_sce_dec( st->idchan = 0; st->element_mode = IVAS_SCE; +#ifdef DEBUGGING + st->id_element = sce_id; +#endif /* Force to MODE1 in IVAS */ st->codec_mode = MODE1; @@ -277,6 +283,34 @@ ivas_error ivas_sce_dec( st_ivas->BER_detect |= st->BER_detect; +#ifdef DEBUG_MODE_INFO + { + float tmpF = hSCE->element_brate / 1000.0f; + int16_t i, n; + + n = 1; + if ( st_ivas->ini_frame == 0 && frame > 0 ) + { + /* in case first frame(s) is/are lost, write info several times */ + n = (int16_t) frame - st_ivas->ini_frame + 1; + } + + for ( i = 0; i < n; i++ ) + { + dbgwrite( &tmpF, sizeof( float ), 1, output_frame, fname( debug_dir, "element_brate", 0, sce_id, DEC ) ); + dbgwrite( &st->element_mode, sizeof( int16_t ), 1, output_frame, fname( debug_dir, "element_mode", 0, sce_id, DEC ) ); + + dbgwrite( output, sizeof( float ), output_frame, 1, fname( debug_dir, "output.sce", 0, sce_id, DEC ) ); + + if ( st_ivas->ivas_format != MASA_ISM_FORMAT ) + { + tmpF = 0; + dbgwrite( &tmpF, sizeof( float ), 1, output_frame, fname( debug_dir, "output.cpe", 0, sce_id, DEC ) ); + dbgwrite( &tmpF, sizeof( float ), 1, output_frame, fname( debug_dir, "output.mct", 0, sce_id, DEC ) ); + } + } + } +#endif pop_wmops(); diff --git a/lib_dec/ivas_spar_decoder.c b/lib_dec/ivas_spar_decoder.c index ab913d08b..76e5c6f1f 100644 --- a/lib_dec/ivas_spar_decoder.c +++ b/lib_dec/ivas_spar_decoder.c @@ -32,6 +32,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "ivas_stat_dec.h" #include "prot.h" #include "string.h" @@ -209,7 +212,11 @@ ivas_error ivas_spar_dec_open( } /* allocate transport channels*/ +#ifndef NONBE_UNIFIED_DECODING_PATHS + if ( st_ivas->hDecoderConfig->Opt_5ms && st_ivas->hTcBuffer == NULL || st_ivas->ivas_format == SBA_ISM_FORMAT ) +#else if ( st_ivas->hTcBuffer == NULL ) +#endif { int16_t nchan_to_allocate; int16_t nchan_tc; @@ -252,6 +259,14 @@ ivas_error ivas_spar_dec_open( granularity = (int16_t) ( st_ivas->hDecoderConfig->output_Fs / ( FRAMES_PER_SEC * MAX_PARAM_SPATIAL_SUBFRAMES ) ); } +#ifndef NONBE_UNIFIED_DECODING_PATHS + /* make sure we have a TC buffer with the correct granularity for rate switching in OSBA */ + if ( !st_ivas->hDecoderConfig->Opt_5ms ) + { + nchan_tc = 0; + nchan_to_allocate = 0; + } +#endif if ( ( error = ivas_jbm_dec_tc_buffer_open( st_ivas, buffer_mode, nchan_tc, nchan_to_allocate, nchan_to_allocate, granularity ) ) != IVAS_ERR_OK ) { return error; @@ -1047,8 +1062,10 @@ static void ivas_spar_calc_smooth_facs( float *cldfb_in_ts_re[CLDFB_NO_COL_MAX], float *cldfb_in_ts_im[CLDFB_NO_COL_MAX], int16_t nbands_spar, +#ifdef NONBE_FIX_906_SBA_LBR_SMOOTHING const int16_t nSlots, const int16_t isFirstSubframe, +#endif ivas_fb_bin_to_band_data_t *bin2band, float *smooth_fac, float smooth_buf[IVAS_MAX_NUM_BANDS][2 * SBA_DIRAC_NRG_SMOOTH_LONG + 1] ) @@ -1070,13 +1087,18 @@ static void ivas_spar_calc_smooth_facs( subframe_band_nrg[b] = 0.f; while ( bin < CLDFB_NO_CHANNELS_MAX && b == bin2band->p_cldfb_map_to_spar_band[bin] ) { +#ifdef NONBE_FIX_906_SBA_LBR_SMOOTHING for ( ts = 0; ts < nSlots; ts++ ) +#else + for ( ts = 0; ts < MAX_PARAM_SPATIAL_SUBFRAMES; ts++ ) +#endif { subframe_band_nrg[b] += cldfb_in_ts_re[ts][bin] * cldfb_in_ts_re[ts][bin] + cldfb_in_ts_im[ts][bin] * cldfb_in_ts_im[ts][bin]; } bin++; } subframe_band_nrg[b] = sqrtf( subframe_band_nrg[b] ); +#ifdef NONBE_FIX_906_SBA_LBR_SMOOTHING if ( isFirstSubframe && nSlots < MAX_PARAM_SPATIAL_SUBFRAMES ) { /* fill up to full 5ms subframe */ @@ -1084,8 +1106,11 @@ static void ivas_spar_calc_smooth_facs( } else { +#endif smooth_buf[b][0] = subframe_band_nrg[b]; +#ifdef NONBE_FIX_906_SBA_LBR_SMOOTHING } +#endif /* calculate short and long energy averages */ smooth_short_avg[b] = EPSILON; for ( i = 0; i < 2 * SBA_DIRAC_NRG_SMOOTH_SHORT; i++ ) @@ -1122,9 +1147,11 @@ static void ivas_spar_calc_smooth_facs( smooth_fac[b] = max( min_smooth_gains1[b], min( max_smooth_gains2[b], smooth_fac[b] ) ); } +#ifdef NONBE_FIX_906_SBA_LBR_SMOOTHING /* only update if we collected a full 5ms worth of energies for the buffer */ if ( isFirstSubframe || nSlots == MAX_PARAM_SPATIAL_SUBFRAMES ) { +#endif for ( b = 0; b < nbands_spar; b++ ) { for ( i = 2 * SBA_DIRAC_NRG_SMOOTH_LONG; i > 0; i-- ) @@ -1132,7 +1159,9 @@ static void ivas_spar_calc_smooth_facs( smooth_buf[b][i] = smooth_buf[b][i - 1]; } } +#ifdef NONBE_FIX_906_SBA_LBR_SMOOTHING } +#endif return; } @@ -1187,10 +1216,18 @@ void ivas_spar_dec_agc_pca( *---------------------------------------------------------------------*/ ivas_agc_dec_process( hSpar->hAgcDec, output, output, nchan_transport, output_frame ); +#ifdef DEBUG_SBA_AUDIO_DUMP + /* Dump audio signal after ivas_agc_dec_process */ + ivas_spar_dump_signal_wav( output_frame, NULL, output, st_ivas->nchan_transport, spar_foa_dec_wav[1], "ivas_agc_dec_process()" ); +#endif if ( hSpar->hPCA != NULL ) { ivas_pca_dec( hSpar->hPCA, output_frame, num_in_ingest, hDecoderConfig->ivas_total_brate, hDecoderConfig->last_ivas_total_brate, st_ivas->bfi, output ); +#ifdef DEBUG_SBA_AUDIO_DUMP + /* Dump audio signal after ivas_pca_dec */ + ivas_spar_dump_signal_wav( output_frame, NULL, output, num_in_ingest, spar_foa_dec_wav[2], "ivas_pca_dec()" ); +#endif } pop_wmops(); @@ -1212,6 +1249,9 @@ void ivas_spar_dec_set_render_map( SPAR_DEC_HANDLE hSpar; hSpar = st_ivas->hSpar; +#ifdef DEBUGGING + assert( hSpar ); +#endif /* adapt subframes */ hSpar->num_slots = nCldfbTs; @@ -1447,8 +1487,10 @@ void ivas_spar_dec_upmixer( output_f_local[n] += n_samples_sf; } +#ifdef NONBE_UNIFIED_DECODING_PATHS /* update combined orientation access index */ ivas_combined_orientation_update_index( st_ivas->hCombinedOrientationData, n_samples_sf ); +#endif } for ( n = 0; n < nchan_internal_total; n++ ) @@ -1541,6 +1583,42 @@ void ivas_spar_dec_upmixer_sf( } } +#ifdef DEBUG_SPAR_BYPASS_EVS_CODEC + /* by-pass core-coder */ + /*write the core coder output to a file for debugging*/ + { + float tmp; + int16_t pcm, j; + for ( j = 0; j < output_frame; j++ ) + { + for ( i = 0; i < nchan_transport; i++ ) + { + tmp = roundf( output[i][j] * PCM16_TO_FLT_FAC ); + pcm = ( tmp > MAX16B_FLT ) ? MAX16B : ( tmp < MIN16B_FLT ) ? MIN16B + : (short) tmp; + dbgwrite( &pcm, sizeof( int16_t ), 1, 1, "dmx_dec.raw" ); + } + } + } + + /*overwrite the core coder output with core input for debugging*/ + { + static FILE *fid_enc = 0; + int16_t smp; + + if ( !fid_enc ) + { + fid_enc = fopen( "evs_input_float.raw", "rb" ); + } + for ( smp = 0; smp < L_FRAME48k; smp++ ) + { + for ( in_ch = 0; in_ch < nchan_transport; in_ch++ ) + { + fread( &output[in_ch][smp], sizeof( float ), 1, fid_enc ); + } + } + } +#endif /*---------------------------------------------------------------------* * TD Decorr and pcm ingest @@ -1558,6 +1636,9 @@ void ivas_spar_dec_upmixer_sf( /*---------------------------------------------------------------------* * PCA decoder *---------------------------------------------------------------------*/ +#ifdef DEBUG_SBA_AUDIO_DUMP + hSpar->pca_ingest_channels = num_in_ingest; +#endif hSpar->hFbMixer->fb_cfg->num_in_chans = num_in_ingest; @@ -1603,6 +1684,10 @@ void ivas_spar_dec_upmixer_sf( numch_out_dirac = hDecoderConfig->nchan_out; +#ifdef DEBUG_SBA_AUDIO_DUMP + /* Dump audio signal after ivas_agc_dec_process */ + ivas_spar_dump_signal_wav( output_frame, p_tc, NULL, numch_in, spar_foa_dec_wav[4], "ivas_spar_upmixer()" ); +#endif /* CLDFB analysis of incoming frame */ for ( in_ch = 0; in_ch < numch_in; in_ch++ ) @@ -1626,7 +1711,11 @@ void ivas_spar_dec_upmixer_sf( if ( ( hDecoderConfig->ivas_total_brate < IVAS_24k4 ) && ( ( hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_HOA2 ) || ( hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_HOA3 ) ) ) { +#ifdef NONBE_FIX_906_SBA_LBR_SMOOTHING ivas_spar_calc_smooth_facs( cldfb_in_ts_re[0], cldfb_in_ts_im[0], num_spar_bands, hSpar->subframe_nbslots[hSpar->subframes_rendered], hSpar->subframes_rendered == 0, &hSpar->hFbMixer->pFb->fb_bin_to_band, hSpar->hMdDec->smooth_fac, hSpar->hMdDec->smooth_buf ); +#else + ivas_spar_calc_smooth_facs( cldfb_in_ts_re[0], cldfb_in_ts_im[0], num_spar_bands, &hSpar->hFbMixer->pFb->fb_bin_to_band, hSpar->hMdDec->smooth_fac, hSpar->hMdDec->smooth_buf ); +#endif } for ( ts = 0; ts < hSpar->subframe_nbslots[hSpar->subframes_rendered]; ts++ ) @@ -1748,6 +1837,9 @@ void ivas_spar_dec_upmixer_sf( else { if ( ( hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_FOA || !( st_ivas->hOutSetup.output_config == IVAS_AUDIO_CONFIG_BINAURAL || st_ivas->hOutSetup.output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR || st_ivas->hOutSetup.output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB +#ifdef SPLIT_REND_WITH_HEAD_ROT + || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM +#endif ) ) && !( st_ivas->ivas_format == SBA_ISM_FORMAT && st_ivas->ism_mode == ISM_SBA_MODE_DISC && st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) ) { @@ -1759,6 +1851,9 @@ void ivas_spar_dec_upmixer_sf( idx_in++; } } +#ifdef DEBUG_SBA_AUDIO_DUMP + hSpar->numOutChannels = outchannels; +#endif } else { @@ -1770,7 +1865,14 @@ void ivas_spar_dec_upmixer_sf( cldfbSynthesis( &cldfb_in_ts_re[out_ch][ts], &cldfb_in_ts_im[out_ch][ts], &output[out_ch][ts * num_cldfb_bands], num_cldfb_bands, st_ivas->cldfbSynDec[out_ch] ); } } - } +#ifdef DEBUG_SBA_AUDIO_DUMP + hSpar->numOutChannels = numch_out_dirac; +#endif + } +#ifdef DEBUG_SBA_AUDIO_DUMP + /* Dump audio signal after cldfbSynthesis */ + ivas_spar_dump_signal_wav( output_frame, NULL, output, hSpar->numOutChannels, spar_foa_dec_wav[3], "cldfbSynthesis()" ); +#endif hSpar->slots_rendered += hSpar->subframe_nbslots[hSpar->subframes_rendered]; hSpar->subframes_rendered++; diff --git a/lib_dec/ivas_spar_md_dec.c b/lib_dec/ivas_spar_md_dec.c index 42ea099a6..a3c7fcf78 100644 --- a/lib_dec/ivas_spar_md_dec.c +++ b/lib_dec/ivas_spar_md_dec.c @@ -32,6 +32,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "math.h" #include "prot.h" #include "ivas_prot.h" @@ -73,7 +76,9 @@ static void ivas_spar_dec_compute_ramp_down_post_matrix( ivas_spar_md_dec_state_ static void ivas_spar_md_fill_invalid_bands( ivas_spar_dec_matrices_t *pSpar_coeffs, ivas_spar_dec_matrices_t *pSpar_coeffs_prev, const int16_t *valid_bands, int16_t *base_band_age, const int16_t num_bands, const int16_t numch_out, const int16_t num_md_sub_frames ); +#ifdef NONBE_FIX_862_UBSAN_SPAR_DEC_BR_SW_PLC static void ivas_spar_md_fill_invalid_bandcoeffs( ivas_band_coeffs_t *pBand_coeffs, ivas_band_coeffs_t *pBand_coeffs_prev, const int16_t *valid_bands, int16_t *base_band_age, int16_t *first_valid_frame, const int16_t num_bands ); +#endif static ivas_error ivas_spar_set_dec_config( ivas_spar_md_dec_state_t *hMdDec, const int16_t nchan_transport, float *pFC ); static void ivas_parse_parameter_bitstream_dtx( ivas_spar_md_t *pSpar_md, Decoder_State *st, const int16_t bw, const int16_t num_bands, int16_t *num_dmx_per_band, int16_t *num_dec_per_band ); @@ -81,6 +86,10 @@ static void ivas_parse_parameter_bitstream_dtx( ivas_spar_md_t *pSpar_md, Decode static ivas_error ivas_deindex_real_index( const int16_t *index, const int16_t q_levels, const float min_value, const float max_value, float *quant, const int16_t num_ch_dim2 ); static void ivas_spar_dec_parse_md_bs( ivas_spar_md_dec_state_t *hMdDec, Decoder_State *st, int16_t *nB, int16_t *bands_bw, int16_t *dtx_vad, const int32_t ivas_total_brate, const int16_t sba_inactive_mode +#ifndef NONBE_FIX_862_UBSAN_SPAR_DEC_BR_SW_PLC + , + const int32_t last_active_brate +#endif ); @@ -102,10 +111,12 @@ ivas_error ivas_spar_md_dec_matrix_open( { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for band_coeffs in SPAR MD" ); } +#ifdef NONBE_FIX_862_UBSAN_SPAR_DEC_BR_SW_PLC if ( ( hMdDec->band_coeffs_prev = (ivas_band_coeffs_t *) malloc( IVAS_MAX_NUM_BANDS * sizeof( ivas_band_coeffs_t ) ) ) == NULL ) { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for band_coeffs in SPAR MD" ); } +#endif if ( ( hMdDec->mixer_mat = (float ***) malloc( num_channels * sizeof( float ** ) ) ) == NULL ) { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR MD matrix" ); @@ -368,11 +379,13 @@ void ivas_spar_md_dec_matrix_close( free( hMdDecoder->spar_md.band_coeffs ); hMdDecoder->spar_md.band_coeffs = NULL; } +#ifdef NONBE_FIX_862_UBSAN_SPAR_DEC_BR_SW_PLC if ( hMdDecoder->band_coeffs_prev != NULL ) { free( hMdDecoder->band_coeffs_prev ); hMdDecoder->band_coeffs_prev = NULL; } +#endif if ( hMdDecoder->mixer_mat != NULL ) { @@ -551,13 +564,17 @@ ivas_error ivas_spar_md_dec_init( /* initialize PLC state */ set_s( hMdDec->valid_bands, 0, IVAS_MAX_NUM_BANDS ); set_s( hMdDec->base_band_age, 0, IVAS_MAX_NUM_BANDS ); +#ifdef NONBE_FIX_862_UBSAN_SPAR_DEC_BR_SW_PLC set_s( hMdDec->base_band_coeffs_age, 0, IVAS_MAX_NUM_BANDS ); +#endif hMdDec->spar_plc_num_lost_frames = 0; hMdDec->spar_plc_enable_fadeout_flag = 1; hMdDec->dtx_md_smoothing_cntr = 1; ivas_clear_band_coeffs( hMdDec->spar_md.band_coeffs, IVAS_MAX_NUM_BANDS ); +#ifdef NONBE_FIX_862_UBSAN_SPAR_DEC_BR_SW_PLC ivas_clear_band_coeffs( hMdDec->band_coeffs_prev, IVAS_MAX_NUM_BANDS ); +#endif ivas_clear_band_coeff_idx( hMdDec->spar_md.band_coeffs_idx, IVAS_MAX_NUM_BANDS ); ivas_clear_band_coeff_idx( hMdDec->spar_md_prev.band_coeffs_idx, IVAS_MAX_NUM_BANDS ); ivas_clear_band_coeff_idx( hMdDec->spar_md_prev.band_coeffs_idx_mapped, IVAS_MAX_NUM_BANDS ); @@ -581,7 +598,9 @@ ivas_error ivas_spar_md_dec_init( set_zero( hMdDec->mixer_mat_prev2[i][j], IVAS_MAX_NUM_BANDS ); } } +#ifdef NONBE_FIX_862_UBSAN_SPAR_DEC_BR_SW_PLC hMdDec->first_valid_frame = 1; +#endif return IVAS_ERR_OK; } @@ -764,8 +783,13 @@ void ivas_spar_md_dec_process( ivas_spar_dec_parse_md_bs( hMdDec, st0, &nB, &bw, &dtx_vad, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->hQMetaData->sba_inactive_mode +#ifndef NONBE_FIX_862_UBSAN_SPAR_DEC_BR_SW_PLC + , + st_ivas->last_active_ivas_total_brate +#endif ); +#ifdef NONBE_FIX_862_UBSAN_SPAR_DEC_BR_SW_PLC assert( nB == hMdDec->spar_md.num_bands ); assert( bw == 1 ); ivas_spar_md_fill_invalid_bandcoeffs( @@ -775,6 +799,7 @@ void ivas_spar_md_dec_process( &hMdDec->base_band_coeffs_age[0], &hMdDec->first_valid_frame, nB ); +#endif ivas_dec_mono_sba_handling( st_ivas ); @@ -786,6 +811,45 @@ void ivas_spar_md_dec_process( /* set correct number of bands*/ nB = IVAS_MAX_NUM_BANDS; +#ifndef NONBE_FIX_862_UBSAN_SPAR_DEC_BR_SW_PLC + if ( bw == IVAS_RED_BAND_FACT ) + { + nB = nB >> 1; + } +#endif +#ifdef DEBUG_LBR_SBA + /* Dumping SPAR Coefficients */ + char f_name[100]; + int16_t nbands = 4; // 6 total, just looking at SPAR + int16_t num_subframes = 1; + int16_t num_elements = 6; + int16_t num_block_group = 1; + int16_t byte_size = sizeof( float ); + + sprintf( f_name, "SBA_MD_values_dec.bin" ); + ( frame == 0 ) ? dbgwrite( &nbands, sizeof( nbands ), 1, 1, f_name ) : false; + ( frame == 0 ) ? dbgwrite( &num_elements, sizeof( num_elements ), 1, 1, f_name ) : false; + ( frame == 0 ) ? dbgwrite( &num_subframes, sizeof( num_subframes ), 1, 1, f_name ) : false; + ( frame == 0 ) ? dbgwrite( &num_block_group, sizeof( num_block_group ), 1, 1, f_name ) : false; + ( frame == 0 ) ? dbgwrite( &byte_size, sizeof( byte_size ), 1, 1, f_name ) : false; + + for ( b = 0; b < nbands; b++ ) + { + for ( int16_t sf = 0; sf < num_subframes; sf++ ) + { + for ( int16_t bl = 0; bl < num_block_group; bl++ ) + { + dbgwrite( &hMdDec->spar_md.band_coeffs[b].pred_re[0], byte_size, 1, 1, f_name ); + dbgwrite( &hMdDec->spar_md.band_coeffs[b].pred_re[1], byte_size, 1, 1, f_name ); + dbgwrite( &hMdDec->spar_md.band_coeffs[b].pred_re[2], byte_size, 1, 1, f_name ); + dbgwrite( &hMdDec->spar_md.band_coeffs[b].P_re[0], byte_size, 1, 1, f_name ); + dbgwrite( &hMdDec->spar_md.band_coeffs[b].P_re[1], byte_size, 1, 1, f_name ); + dbgwrite( &hMdDec->spar_md.band_coeffs[b].P_re[2], byte_size, 1, 1, f_name ); + // fprintf(stdout, "%f\t%f\t%f\t%d\t%d\n", dirac_md_kbps, spar_md_kbps, sba_md_kbps, qsi, code_strat ); + } + } + } +#endif /* expand DirAC MD to all time slots */ for ( i_ts = 1; i_ts < num_md_sub_frames; i_ts++ ) @@ -824,6 +888,17 @@ void ivas_spar_md_dec_process( } fprintf( fid, "%.6f\n", hMdDec->mixer_mat[1][0][band] ); } +#endif +#ifndef NONBE_FIX_862_UBSAN_SPAR_DEC_BR_SW_PLC + if ( bw == IVAS_RED_BAND_FACT ) + { + nB = nB << 1; + } + + for ( b = nB; b < num_bands_out; b++ ) + { + hMdDec->valid_bands[b] = 1; + } #endif ivas_spar_md_fill_invalid_bands( &hMdDec->spar_coeffs, &hMdDec->spar_coeffs_prev, &hMdDec->valid_bands[0], &hMdDec->base_band_age[0], num_bands_out, num_md_chs, num_md_sub_frames ); @@ -1411,6 +1486,25 @@ void ivas_spar_dec_gen_umx_mat( } } +#ifdef DEBUG_SBA_MD_DUMP + { + static FILE *f_mat = 0; + + if ( f_mat == 0 ) + f_mat = fopen( "mixer_mat_dec", "w" ); + + for ( i = 0; i < num_out_ch; i++ ) + { + for ( j = 0; j < num_out_ch; j++ ) + { + for ( b = 0; b < num_bands_out; b++ ) + { + fprintf( f_mat, "%f\n", hMdDec->mixer_mat[i][j][b + i_ts * IVAS_MAX_NUM_BANDS] ); + } + } + } + } +#endif } ivas_spar_dec_compute_ramp_down_post_matrix( hMdDec, num_bands_out, bfi, num_md_sub_frames ); @@ -1418,6 +1512,7 @@ void ivas_spar_dec_gen_umx_mat( return; } +#ifdef NONBE_FIX_862_UBSAN_SPAR_DEC_BR_SW_PLC static void ivas_spar_md_band_upmix( ivas_band_coeffs_t *band_coeffs, int16_t *nB, @@ -1459,6 +1554,7 @@ static void ivas_spar_md_band_upmix( return; } +#endif /*-----------------------------------------------------------------------------------------* * Function ivas_spar_dec_parse_md_bs() @@ -1474,16 +1570,28 @@ static void ivas_spar_dec_parse_md_bs( int16_t *dtx_vad, const int32_t ivas_total_brate, const int16_t sba_inactive_mode +#ifndef NONBE_FIX_862_UBSAN_SPAR_DEC_BR_SW_PLC + , + const int32_t last_active_brate +#endif ) { int16_t i, j, k, num_bands; +#ifndef NONBE_FIX_862_UBSAN_SPAR_DEC_BR_SW_PLC + int16_t ii, jj, ndec, ndm, b, idx; +#else int16_t ii, jj, ndec, ndm; +#endif uint16_t qsi; ivas_quant_strat_t qs; int16_t strat, no_ec; int16_t do_diff[IVAS_MAX_NUM_BANDS]; float quant[IVAS_SPAR_MAX_C_COEFF]; int16_t do_repeat[IVAS_MAX_NUM_BANDS]; +#ifndef NONBE_FIX_862_UBSAN_SPAR_DEC_BR_SW_PLC + int16_t bw_final, bw_fact; + int32_t active_brate; +#endif *dtx_vad = 1; *bands_bw = 1; qsi = 0; @@ -1555,6 +1663,7 @@ static void ivas_spar_dec_parse_md_bs( ivas_parse_parameter_bitstream_dtx( &hMdDec->spar_md, st0, *bands_bw, *nB, hMdDec->spar_md_cfg.num_dmx_chans_per_band, hMdDec->spar_md_cfg.num_decorr_per_band ); +#ifdef NONBE_FIX_862_UBSAN_SPAR_DEC_BR_SW_PLC if ( *bands_bw != 1 ) { ndec = hMdDec->spar_md_cfg.num_decorr_per_band[0]; @@ -1569,6 +1678,42 @@ static void ivas_spar_dec_parse_md_bs( ndm ); } +#else + active_brate = ( ivas_total_brate > IVAS_SID_5k2 ) ? ivas_total_brate : last_active_brate; + + if ( active_brate >= IVAS_24k4 ) + { + bw_final = 1; + } + else + { + bw_final = 2; + } + + bw_fact = *bands_bw / bw_final; + + for ( i = *nB - 1; i >= 0; i-- ) + { + ndec = hMdDec->spar_md_cfg.num_decorr_per_band[bw_fact * i]; + + for ( b = bw_fact - 1; b >= 0; b-- ) + { + idx = i * bw_fact + b; + for ( j = 0; j < FOA_CHANNELS - 1; j++ ) + { + hMdDec->spar_md.band_coeffs[idx].pred_re[j] = hMdDec->spar_md.band_coeffs[i].pred_re[j]; + } + for ( j = 0; j < ndec; j++ ) + { + hMdDec->spar_md.band_coeffs[idx].P_re[j] = hMdDec->spar_md.band_coeffs[i].P_re[j]; + } + hMdDec->valid_bands[idx] = 1; + } + } + + *bands_bw = bw_final; + *nB = num_bands / bw_final; +#endif return; } @@ -1620,11 +1765,18 @@ static void ivas_spar_dec_parse_md_bs( do_diff[i] = ( ( ( i + 1 ) & 3 ) != strat - 4 ); do_repeat[i] = 0; } +#ifdef NONBE_FIX_862_UBSAN_SPAR_DEC_BR_SW_PLC if ( hMdDec->spar_md_cfg.prev_quant_idx >= 0 ) { +#endif ivas_map_prior_coeffs_quant( &hMdDec->spar_md_prev, &hMdDec->spar_md_cfg, qsi, *nB ); +#ifdef NONBE_FIX_862_UBSAN_SPAR_DEC_BR_SW_PLC } +#endif } +#ifdef SPAR_HOA_DBG + fprintf( stdout, "\n\n no_ec = %d, strat = %d\n", no_ec, strat ); +#endif hMdDec->spar_md_cfg.prev_quant_idx = qsi; if ( no_ec == 0 ) @@ -1680,9 +1832,18 @@ static void ivas_spar_dec_parse_md_bs( { hMdDec->spar_md_prev.band_coeffs_idx[i].decd_index_re[j] = hMdDec->spar_md.band_coeffs_idx[i].decd_index_re[j]; } +#ifndef NONBE_FIX_862_UBSAN_SPAR_DEC_BR_SW_PLC + hMdDec->valid_bands[*bands_bw * i] |= ( do_diff[i] == 0 && do_repeat[i] == 0 ) ? 1 : 0; + for ( j = 1; j < *bands_bw; j++ ) + { + hMdDec->valid_bands[*bands_bw * i + j] = hMdDec->valid_bands[*bands_bw * i]; + } +#else hMdDec->valid_bands[i] |= ( do_diff[i] == 0 && do_repeat[i] == 0 ) ? 1 : 0; +#endif } +#ifdef NONBE_FIX_862_UBSAN_SPAR_DEC_BR_SW_PLC ndec = hMdDec->spar_md_cfg.num_decorr_per_band[0]; ndm = hMdDec->spar_md_cfg.num_dmx_chans_per_band[0]; if ( *bands_bw != 1 ) @@ -1697,6 +1858,7 @@ static void ivas_spar_dec_parse_md_bs( ndm ); } +#endif return; } @@ -1969,6 +2131,7 @@ static void ivas_decode_huffman_bs( return; } +#ifdef NONBE_FIX_862_UBSAN_SPAR_DEC_BR_SW_PLC static void ivas_spar_plc_get_band_age( const int16_t *valid_bands, int16_t *base_band_age, @@ -2037,6 +2200,7 @@ static void ivas_spar_get_plc_interp_weights( } return; } +#endif /*-----------------------------------------------------------------------------------------* * Function ivas_spar_md_fill_invalid_bands() @@ -2057,8 +2221,34 @@ static void ivas_spar_md_fill_invalid_bands( int16_t valid_band_idx[IVAS_MAX_NUM_BANDS], idx = -1; int16_t last_valid_band_idx[IVAS_MAX_NUM_BANDS]; float w = 0; +#ifdef NONBE_FIX_862_UBSAN_SPAR_DEC_BR_SW_PLC ivas_spar_plc_get_band_age( valid_bands, base_band_age, num_bands, last_valid_band_idx, valid_band_idx, &all_valid, &idx ); +#else + set_s( valid_band_idx, 0, IVAS_MAX_NUM_BANDS ); + set_s( last_valid_band_idx, 0, IVAS_MAX_NUM_BANDS ); + + all_valid = 1; + for ( b = 0; b < num_bands; b++ ) + { + if ( valid_bands[b] != 0 ) + { + base_band_age[b] = 0; /* reset band age */ + idx++; + valid_band_idx[idx] = b; + } + else + { + base_band_age[b] += 1; /* increment the age of invalid bands */ + + if ( base_band_age[b] > 3 ) + { + last_valid_band_idx[b] = idx; + } + all_valid = 0; + } + } +#endif assert( idx > 0 ); /* some bands should be valid */ if ( all_valid == 0 ) @@ -2068,9 +2258,33 @@ static void ivas_spar_md_fill_invalid_bands( /* check against non zero in if and else if */ if ( base_band_age[b] > 3 ) /* old invalid bands */ { +#ifdef NONBE_FIX_862_UBSAN_SPAR_DEC_BR_SW_PLC int16_t id0, id1; ivas_spar_get_plc_interp_weights( valid_band_idx, last_valid_band_idx[b], idx, b, &w, &id0, &id1 ); +#else + int16_t tmp_id, id0, id1; + + tmp_id = last_valid_band_idx[b]; + if ( tmp_id < 0 ) /* Extrapolation */ + { + id1 = valid_band_idx[0]; + id0 = 0; + w = 1; + } + else if ( tmp_id == idx ) /* Extrapolation */ + { + id1 = valid_band_idx[tmp_id]; + id0 = valid_band_idx[tmp_id]; + w = 0; + } + else /* Interpolation */ + { + id0 = valid_band_idx[tmp_id]; + id1 = valid_band_idx[tmp_id + 1]; + w = ( (float) ( b - id0 ) ) / ( id1 - id0 ); + } +#endif for ( i = 0; i < num_channels; i++ ) { for ( j = 0; j < num_channels; j++ ) @@ -2116,6 +2330,7 @@ static void ivas_spar_md_fill_invalid_bands( return; } +#ifdef NONBE_FIX_862_UBSAN_SPAR_DEC_BR_SW_PLC static void ivas_spar_md_fill_invalid_bandcoeffs( ivas_band_coeffs_t *pBand_coeffs, ivas_band_coeffs_t *pBand_coeffs_prev, @@ -2195,6 +2410,7 @@ static void ivas_spar_md_fill_invalid_bandcoeffs( return; } +#endif /*-----------------------------------------------------------------------------------------* diff --git a/lib_dec/ivas_stat_dec.h b/lib_dec/ivas_stat_dec.h index d350ec18c..c2c31152f 100644 --- a/lib_dec/ivas_stat_dec.h +++ b/lib_dec/ivas_stat_dec.h @@ -603,9 +603,11 @@ typedef struct ivas_spar_md_dec_state_t float smooth_buf[IVAS_MAX_NUM_BANDS][2 * SBA_DIRAC_NRG_SMOOTH_LONG + 1]; float smooth_fac[IVAS_MAX_NUM_BANDS]; float mixer_mat_prev2[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH][IVAS_MAX_NUM_BANDS]; +#ifdef NONBE_FIX_862_UBSAN_SPAR_DEC_BR_SW_PLC int16_t first_valid_frame; ivas_band_coeffs_t *band_coeffs_prev; int16_t base_band_coeffs_age[IVAS_MAX_NUM_BANDS]; +#endif } ivas_spar_md_dec_state_t; @@ -654,6 +656,10 @@ typedef struct ivas_spar_dec_lib_t int32_t core_nominal_brate; /* Nominal bitrate for core coding */ int16_t i_subframe; +#ifdef DEBUG_SBA_AUDIO_DUMP + int16_t numOutChannels; + int16_t pca_ingest_channels; +#endif int16_t subframe_nbslots[MAX_JBM_SUBFRAMES_5MS]; int16_t render_to_md_map[MAX_JBM_CLDFB_TIMESLOTS]; int16_t nb_subframes; @@ -807,6 +813,7 @@ typedef struct renderer_struct } ISM_RENDERER_DATA, *ISM_RENDERER_HANDLE; +#ifndef SPLIT_REND_WITH_HEAD_ROT /* Fastconv binaural data structure */ typedef struct ivas_binaural_rendering_struct { @@ -830,6 +837,7 @@ typedef struct ivas_binaural_rendering_struct REVERB_STRUCT_HANDLE hReverb; } BINAURAL_RENDERER, *BINAURAL_RENDERER_HANDLE; +#endif /*----------------------------------------------------------------------------------* @@ -907,7 +915,11 @@ typedef struct ivas_masa_ism_data_structure typedef struct decoder_tc_buffer_structure { float *tc_buffer; /* the buffer itself */ +#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX float *tc[MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS]; /* pointers into the buffer to the beginning of each tc */ // VE2SB: TBV +#else + float *tc[MAX_TRANSPORT_CHANNELS + MAX_NUM_OBJECTS]; /* pointers into the buffer to the beginning of each tc */ +#endif TC_BUFFER_MODE tc_buffer_mode; /* mode of the buffer (no buffering, render buffering, out buffering) */ int16_t nchan_transport_jbm; /* number of TCs after TC decoding */ int16_t nchan_transport_internal; /* total number of TC buffer channels, can include e.g. TD decorr data */ @@ -947,6 +959,37 @@ typedef struct jbm_metadata_structure } JBM_METADATA, *JBM_METADATA_HANDLE; +#ifdef SPLIT_REND_WITH_HEAD_ROT +/*----------------------------------------------------------------------------------* + * Split rendering structures + *----------------------------------------------------------------------------------*/ + +typedef struct +{ + 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]; + +} IVAS_DEC_SPLIT_REND_MULTI_BIN_CLDFB_DATA, *IVAS_DEC_SPLIT_REND_MULTI_BIN_CLDFB_DATA_HANDLE; + +typedef struct +{ + float Cldfb_RealBuffer[MAX_OUTPUT_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + float Cldfb_ImagBuffer[MAX_OUTPUT_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + AUDIO_CONFIG config; + +} IVAS_DEC_SPLIT_REND_CLDFB_OUT_DATA, *IVAS_DEC_SPLIT_REND_CLDFB_OUT_DATA_HANDLE; + +typedef struct +{ + IVAS_DEC_SPLIT_REND_MULTI_BIN_CLDFB_DATA_HANDLE hMultiBinCldfbData; /*scratch buffer for frame by frame processing*/ + IVAS_SPLIT_REND_BITS_HANDLE hSplitRendBits; /*scratch buffer for frame by frame processing*/ + SPLIT_REND_WRAPPER splitrend; + IVAS_DEC_SPLIT_REND_CLDFB_OUT_DATA_HANDLE hCldfbDataOut; /*buffer to store cldfb data before binauralization*/ + float *tdDataOut; /*buffer to store TD data before binauralization*/ + int16_t numTdSamplesPerChannelCached; + +} IVAS_DEC_SPLIT_REND_WRAPPER; +#endif /*----------------------------------------------------------------------------------* @@ -971,8 +1014,19 @@ typedef struct decoder_config_structure int16_t Opt_ExternalOrientation; /* indiates whether external orientations are used */ int16_t Opt_dpid_on; /* indicates whether Directivity pattern option is used */ int16_t Opt_aeid_on; /* indicates whether Acoustic environment option is used */ +#ifdef DEBUGGING + /* temp. development parameters */ + int16_t force_rend; /* forced TD/CLDFB binaural renderer (for ISM and MC) */ +#endif int16_t Opt_tsm; /* indicates whether time scaling modification is activated */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + int16_t Opt_Limiter; +#endif +#ifdef NONBE_UNIFIED_DECODING_PATHS IVAS_RENDER_FRAMESIZE render_framesize; +#else + int16_t Opt_5ms; +#endif int16_t Opt_delay_comp; /* flag indicating delay compensation active */ } DECODER_CONFIG, *DECODER_CONFIG_HANDLE; @@ -1052,7 +1106,11 @@ typedef struct Decoder_Struct BINAURAL_RENDERER_HANDLE hBinRenderer; /* fastconv binaural renderer handle */ BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd; /* Time domain binaural object renderer handle */ TDREND_HRFILT_FiltSet_t *hHrtfTD; /* pointer to HRTF data for TD renderer */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + DIRAC_DEC_BIN_HANDLE hDiracDecBin[MAX_HEAD_ROT_POSES]; /* parametric binaural renderer handle */ +#else DIRAC_DEC_BIN_HANDLE hDiracDecBin; /* parametric binaural renderer handle */ +#endif LSSETUP_CONVERSION_HANDLE hLsSetUpConversion; /* MC LS configuration convertion handle */ EFAP_HANDLE hEFAPdata; /* EFAP structure */ VBAP_HANDLE hVBAPdata; /* VBAP structure */ @@ -1076,11 +1134,17 @@ typedef struct Decoder_Struct int16_t flag_omasa_brate; +#ifdef SPLIT_REND_WITH_HEAD_ROT + IVAS_DEC_SPLIT_REND_WRAPPER hSplitBinRend; /* split binuaral rendering handle */ +#endif /* JBM module */ DECODER_TC_BUFFER_HANDLE hTcBuffer; /* JBM structure */ JBM_METADATA_HANDLE hJbmMetadata; /* Structure for metadata buffering in JBM */ +#ifdef DEBUGGING + int32_t noClipping; /* number of clipped samples */ +#endif int32_t last_active_ivas_total_brate; int16_t ism_extmeta_active; /* Extended metadata active in decoder */ int16_t ism_extmeta_cnt; /* Change frame counter for extended metadata */ diff --git a/lib_dec/ivas_stereo_adapt_GR_dec.c b/lib_dec/ivas_stereo_adapt_GR_dec.c index 81a3131f8..7e698f616 100644 --- a/lib_dec/ivas_stereo_adapt_GR_dec.c +++ b/lib_dec/ivas_stereo_adapt_GR_dec.c @@ -37,6 +37,9 @@ #include "ivas_prot.h" #include "ivas_rom_com.h" #include "rom_dec.h" +#ifdef DEBUGGING +#include "debug.h" +#endif /*---------------------------------------------------------------------* @@ -197,6 +200,12 @@ static ivas_error find_map( ( *map_idx )++; } +#ifdef DEBUGGING + if ( *map_idx == len ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "find_map(map, %d) : value not found!!", val ); + } +#endif return IVAS_ERR_OK; } diff --git a/lib_dec/ivas_stereo_cng_dec.c b/lib_dec/ivas_stereo_cng_dec.c index 91a560cb2..5953e93ed 100644 --- a/lib_dec/ivas_stereo_cng_dec.c +++ b/lib_dec/ivas_stereo_cng_dec.c @@ -38,6 +38,9 @@ #include "ivas_prot.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" /*------------------------------------------------------------------- diff --git a/lib_dec/ivas_stereo_dft_dec.c b/lib_dec/ivas_stereo_dft_dec.c index 03c0fe15a..388bf8d07 100644 --- a/lib_dec/ivas_stereo_dft_dec.c +++ b/lib_dec/ivas_stereo_dft_dec.c @@ -42,6 +42,9 @@ #include "ivas_cnst.h" #include "ivas_rom_com.h" #include "ivas_rom_dec.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" @@ -656,6 +659,9 @@ void stereo_dft_dec_analyze( float *mem, input_buff[STEREO_DFT32MS_OVL_MAX + L_FRAME48k]; float DFT[STEREO_DFT32MS_N_MAX], *pDFT_out; int16_t NFFT, NFFT_core, ovl, zp; +#if defined( DEBUG_MODE_DFT ) || defined( DEBUG_STEREO_DFT_NOCORE ) + int16_t N; +#endif int16_t offset; float fac; const float *trigo, *win_left, *win_right, *win2; @@ -769,6 +775,9 @@ void stereo_dft_dec_analyze( delay_dec = NS2SA( inputFs, STEREO_DFT32MS_OVL_NS ); zp = NS2SA( inputFs, STEREO_DFT32MS_ZP_NS ); ovl = NS2SA( inputFs, STEREO_DFT32MS_OVL_NS ); +#ifdef DEBUG_MODE_DFT + N = NS2SA( inputFs, STEREO_DFT32MS_HOP_NS ); +#endif NFFT = NS2SA( inputFs, STEREO_DFT32MS_N_NS ); fac = (float) ( hStereoDft->NFFT ) / (float) ( NFFT ); ovl2 = NS2SA( inputFs, STEREO_DFT32MS_OVL2_NS ); @@ -789,6 +798,39 @@ void stereo_dft_dec_analyze( return; } +#ifdef DEBUG_MODE_DFT + { + int16_t tmp[L_FRAME48k]; + char file_name[50] = { 0 }; +#ifdef DEBUG_STEREO_DFT_NOCORE + if ( ana_type == DFT_STEREO_DEC_ANA_NOCORE && delay == 0 ) + { + sprintf( file_name, "./res/stereo_dft_enc_M_S_%d_c%d_b0.pcm", input_frame * FRAMES_PER_SEC, chan ); + dbgread( tmp, sizeof( int16_t ), 2 * N, file_name ); + for ( i = 0; i < input_frame; i++ ) + { + pInput_buff[mem_size + i] = (float) ( tmp[i] ); + } + mvr2r( input_buff + input_frame, mem, mem_size ); + } +#endif + offset = 0; + pInput = pInput_buff + offset; + for ( i = 0; i < 2 * N; i++ ) + { + tmp[i] = (int16_t) ( pInput[i] + 0.5f ); + } + if ( ana_type != DFT_STEREO_DEC_ANA_BPF ) + { + sprintf( file_name, "./res/stereo_dft_dec_M_S_c%d_%d.pcm", input_frame * FRAMES_PER_SEC, chan ); + } + else + { + sprintf( file_name, "./res/stereo_dft_dec_BPF_c%d_%d.pcm", input_frame * FRAMES_PER_SEC, chan ); + } + dbgwrite( tmp, sizeof( int16_t ), 2 * N, 1, file_name ); + } +#endif /*-----------------------------------------------------------------* * DFT Analysis: loop over frame @@ -1045,6 +1087,19 @@ void stereo_dft_dec_synthesize( p_DFT += STEREO_DFT32MS_N_MAX; } +#ifdef DEBUG_MODE_DFT + { + int16_t tmp[1024]; + char file_name[50] = { 0 }; + + for ( i = 0; i < output_frame; i++ ) + { + tmp[i] = (int16_t) ( output[i] + 0.5f ); + } + sprintf( file_name, "./res/stereo_dft_ch%d_output.pcm", chan ); + dbgwrite( tmp, sizeof( int16_t ), output_frame, 1, file_name ); + } +#endif pop_wmops(); return; @@ -1116,6 +1171,16 @@ void stereo_dft_dec( hStereoDft->trans = ( ( ( st0->clas_dec == ONSET ) || ( st0->clas_dec == SIN_ONSET ) || ( st0->clas_dec == UNVOICED_CLAS ) || ( st0->clas_dec == UNVOICED_TRANSITION ) ) || ( st0->stab_fac <= 0.25f ) ) || ( st0->core == TCX_20_CORE && ( ( st0->hTcxCfg->tcx_last_overlap_mode == MIN_OVERLAP ) || ( st0->hTcxCfg->tcx_last_overlap_mode == HALF_OVERLAP ) ) ) || ( st0->core == TCX_10_CORE ); +#ifdef DEBUG_MODE_DFT + { + int16_t tmps; + int16_t tmp_output_frame = (int16_t) ( st0->output_Fs / FRAMES_PER_SEC ); + dbgwrite( &( hStereoDft->attackPresent ), sizeof( int16_t ), 1, tmp_output_frame, "res/stereo_attack.pcm" ); + dbgwrite( &( hStereoDft->trans ), sizeof( int16_t ), 1, tmp_output_frame, "res/stereo_trans.pcm" ); + tmps = (int16_t) ( 100.f * ( st0->stab_fac ) + 0.5f ); + dbgwrite( &tmps, sizeof( int16_t ), 1, tmp_output_frame, "res/stereo_stab.pcm" ); + } +#endif /* Initialization */ k_offset = 1; @@ -1147,6 +1212,9 @@ void stereo_dft_dec( dmx_nrg = stereo_dft_dmx_swb_nrg( DFT[0], DFT[0] + STEREO_DFT32MS_N_MAX, min( hStereoDft->NFFT, STEREO_DFT32MS_N_32k ) ); } +#ifdef DEBUG_MODE_DFT + dbgwrite( hStereoDft->res_pred_gain + STEREO_DFT_BAND_MAX, sizeof( float ), hStereoDft->nbands, 1, "./res/stereo_dft_dec_gainPred.pcm" ); +#endif #ifdef DEBUG_PRINT printf( "\nframe: %d\n", frame ); @@ -1224,6 +1292,17 @@ void stereo_dft_dec( } } +#ifdef DEBUGGING + if ( dbgflag( "write_res" ) ) + { + dbgwrite( pDFT_RES, sizeof( float ), 2 * hStereoDft->band_limits[hStereoDft->res_cod_band_max], 1, "dec_res.float" ); + } + + if ( dbgflag( "read_res" ) ) + { + dbgread( pDFT_RES, sizeof( float ), 2 * hStereoDft->band_limits[hStereoDft->res_cod_band_max], "dec_res.float" ); + } +#endif /* Apply active DMX */ /* pDFT_RES is used for the second channel in inactive frames */ if ( hStereoDft->frame_sid_nodata && !sba_dirac_stereo_flag ) @@ -1258,6 +1337,12 @@ void stereo_dft_dec( hFdCngDec->cna_g_state[b] = g; } +#ifdef DEBUG_MODE_DFT + if ( b < hStereoDft->res_cod_band_max ) + { + dbgwrite( &g, sizeof( float ), 1, 1, "./res/stereo_dft_dec_g.pcm" ); + } +#endif /* No residual coding in inactive frames, instead pDFT_RES is used for the second channel */ if ( b >= hStereoDft->res_cod_band_max && !hStereoDft->frame_sid_nodata && !( sba_dirac_stereo_flag && hMdDec ) ) { @@ -1450,6 +1535,12 @@ void stereo_dft_dec( DFT_L[2 * i + 1] = pDFT_DMX[2 * i + 1] + tmp; DFT_R[2 * i + 1] = pDFT_DMX[2 * i + 1] - tmp; +#ifdef DEBUG_STEREO_DFT_OUTRESPRED + DFT_L[2 * i] = DFT_PRED_RES[2 * i]; + DFT_R[2 * i] = -DFT_PRED_RES[2 * i]; + DFT_L[2 * i + 1] = DFT_PRED_RES[2 * i + 1]; + DFT_R[2 * i + 1] = -DFT_PRED_RES[2 * i + 1]; +#endif /* DEBUG_STEREO_DFT_OUTRESPRED */ } for ( ; i < hStereoDft->band_limits[b + 1]; i++ ) @@ -1464,6 +1555,12 @@ void stereo_dft_dec( DFT_L[2 * i + 1] = pDFT_DMX[2 * i + 1] + tmp; DFT_R[2 * i + 1] = pDFT_DMX[2 * i + 1] - tmp; +#ifdef DEBUG_STEREO_DFT_OUTRESPRED + DFT_L[2 * i] = 0.f; + DFT_R[2 * i] = 0.f; + DFT_L[2 * i + 1] = 0.f; + DFT_R[2 * i + 1] = 0.f; +#endif /* DEBUG_STEREO_DFT_OUTRESPRED */ } /* Active Upmix */ @@ -1520,12 +1617,18 @@ void stereo_dft_dec( pPredGain = NULL; /* to avoid compilation warnings */ pSideGain = NULL; +#ifndef DEBUG_STEREO_DFT_NOSTEREO /* Dummy upmix-> mono binauralization */ for ( i = 0; i < hStereoDft->NFFT; i++ ) { DFT_L[i] = ( pDFT_DMX[i] + pDFT_RES[i] ); DFT_R[i] = ( pDFT_DMX[i] - pDFT_RES[i] ); } +#else + /*Copy DMX to Left channel and reset Right channel*/ + mvr2r( pDFT_DMX, DFT_L, hStereoDft->NFFT ); + mvr2r( pDFT_DMX, DFT_R, hStereoDft->NFFT ); +#endif } /* Comfort Noise Addition */ @@ -1598,10 +1701,12 @@ void stereo_dft_dec( /* Update memories */ hStereoDft->past_DMX_pos = ( hStereoDft->past_DMX_pos + 1 ) % STEREO_DFT_PAST_MAX; mvr2r( pDFT_DMX, hStereoDft->DFT_past_DMX[hStereoDft->past_DMX_pos], min( hStereoDft->NFFT, STEREO_DFT32MS_N_32k ) ); +#ifndef DEBUG_STEREO_DFT_NOSTEREO if ( pPredGain ) { stereo_dft_adapt_sf_delay( hStereoDft, pPredGain ); } +#endif mvr2r( DFT_L, DFT[0] + k * STEREO_DFT32MS_N_MAX, hStereoDft->NFFT ); mvr2r( DFT_R, DFT[1] + k * STEREO_DFT32MS_N_MAX, hStereoDft->NFFT ); @@ -1629,7 +1734,11 @@ void stereo_dft_dec( void stereo_dft_dec_res( CPE_DEC_HANDLE hCPE, /* i/o: decoder CPE handle */ +#ifdef FIX_887_ARRAY_SIZE_DFT_MDCT_STEREO float res_buf[STEREO_DFT_N_8k], /* i : residual buffer */ +#else + float res_buf[STEREO_DFT_BUF_MAX], /* i : residual buffer */ +#endif float *output /* o : output */ ) { @@ -1678,8 +1787,29 @@ void stereo_dft_dec_res( } } +#ifdef DEBUG_STEREO_DFT_NOQRES + { + int16_t tmp[1024]; + dbgread( &tmp, sizeof( int16_t ), L_FRAME8k, "./res/stereo_dft_enc_res_original.pcm" ); + for ( i = 0; i < L_FRAME8k; i++ ) + { + win[i] = (float) ( tmp[i] ); + } + } +#endif mvr2r( win, output, L_FRAME8k ); +#ifdef DEBUG_MODE_DFT + { + int16_t tmp[L_FRAME8k]; + + for ( i = 0; i < L_FRAME8k; i++ ) + { + tmp[i] = (int16_t) ( win[i] ); + } + dbgwrite( tmp, sizeof( int16_t ), L_FRAME8k, 1, "./res/stereo_dft_dec_res_decoded.pcm" ); + } +#endif if ( hCPE->hCoreCoder[0]->core == ACELP_CORE ) { /* bass post-filter */ @@ -1709,6 +1839,25 @@ void stereo_dft_dec_res( set_zero( hCPE->hStereoDft->hBpf->pst_old_syn, STEREO_DFT_NBPSF_PIT_MAX_8k ); hCPE->hStereoDft->hBpf->pst_mem_deemp_err = 0.f; } +#ifdef DEBUG_MODE_DFT + { + int16_t v; + int16_t out_bpf[L_FRAME8k]; + + if ( hCPE->hCoreCoder[0]->core == ACELP_CORE ) + { + for ( v = 0; v < L_FRAME8k; v++ ) + { + out_bpf[v] = (int16_t) bpf_error_signal_8k[v]; + } + } + else + { + set_s( out_bpf, 0, L_FRAME8k ); + } + dbgwrite( out_bpf, sizeof( int16_t ), L_FRAME8k, 1, "res/bpf_res.pcm" ); + } +#endif return; } @@ -1728,7 +1877,11 @@ void stereo_dft_dec_read_BS( STEREO_DFT_DEC_DATA_HANDLE hStereoDft, /* i/o: decoder stereo handle */ const int16_t bwidth, /* i : bandwidth */ const int16_t output_frame, /* i : output frame length */ +#ifdef FIX_887_ARRAY_SIZE_DFT_MDCT_STEREO float res_buf[STEREO_DFT_N_8k], /* o : residual buffer */ +#else + float res_buf[STEREO_DFT_BUF_MAX], /* o : residual buffer */ +#endif int16_t *nb_bits, /* o : number of bits read */ float *coh, /* i/o: Coherence */ const int16_t ivas_format /* i : ivas format */ @@ -1752,6 +1905,21 @@ void stereo_dft_dec_read_BS( float res_pred_gain_tmp[STEREO_DFT_BAND_MAX]; int16_t itd_mode; +#ifdef DEBUG_MODE_DFT + static FILE *pF = NULL; + static FILE *ITD_values = NULL, *side_gain_values = NULL, *RPG_values = NULL; + + if ( pF == NULL ) + pF = fopen( "./res/stereo_dft_dec_ind.txt", "w" ); + if ( ITD_values == NULL ) + ITD_values = fopen( "./res/itd_indicies_dec.txt", "w" ); + if ( side_gain_values == NULL ) + side_gain_values = fopen( "./res/side_gain_indicies_dec.txt", "w" ); + if ( RPG_values == NULL ) + RPG_values = fopen( "./res/rpg_indicies_dec.txt", "w" ); + + assert( *nb_bits <= 800 ); +#endif /*------------------------------------------------------------------* * Initialization *-----------------------------------------------------------------*/ @@ -1838,6 +2006,9 @@ void stereo_dft_dec_read_BS( { hStereoDft->res_cod_mode[k_offset] = get_next_indice( st, 1 ); ( *nb_bits )++; +#ifdef DEBUG_MODE_DFT + fprintf( pF, "res_cod_mode: %d\n", hStereoDft->res_cod_mode[k_offset] ); +#endif } /* read number of bands in the bitstream - depends on the audio bandwidth and not to output_Fs */ @@ -1873,6 +2044,10 @@ void stereo_dft_dec_read_BS( hStereoDft->res_cod_line_max = 8 * ( hStereoDft->res_cod_line_max / 8 ); hStereoDft->res_pred_band_min = max( STEREO_DFT_RES_PRED_BAND_MIN, hStereoDft->res_cod_band_max ); +#ifdef DEBUG_MODE_DFT + fprintf( pF, "stereo Data: %d %d %d %d %d\n", hStereoDft->band_res[k_offset], hStereoDft->prm_res[k_offset], hStereoDft->res_pred_mode[k_offset], hStereoDft->res_cod_mode[k_offset], hStereoDft->res_cod_band_max ); + fprintf( pF, "stereo Bands: %d\n", hStereoDft->nbands ); +#endif /*Copy config. for all DFT frames*/ set_s( hStereoDft->band_res + k_offset + 1, hStereoDft->band_res[k_offset], N_div - 1 ); @@ -1887,11 +2062,17 @@ void stereo_dft_dec_read_BS( /* Sent from the latest to the oldest */ for ( k = hStereoDft->prm_res[k_offset] - 1; k < N_div; k += hStereoDft->prm_res[k + k_offset] ) { +#ifdef DEBUG_MODE_DFT + fprintf( pF, "ch[%d]:", k ); +#endif /* reset parameters */ set_zero( hStereoDft->side_gain + ( k + k_offset ) * STEREO_DFT_BAND_MAX, STEREO_DFT_BAND_MAX ); hStereoDft->gipd[k + k_offset] = 0.f; set_zero( hStereoDft->res_pred_gain + ( k + k_offset ) * STEREO_DFT_BAND_MAX, STEREO_DFT_BAND_MAX ); +#ifdef DEBUG_MODE_DFT + fprintf( pF, "ITD: %d ", hStereoDft->hConfig->itd_mode ); +#endif if ( !( ivas_format == MASA_FORMAT && ivas_total_brate <= IVAS_SID_5k2 ) ) { @@ -1943,6 +2124,13 @@ void stereo_dft_dec_read_BS( hStereoDft->res_gains_ind[0][b + STEREO_DFT_BAND_MAX] = ind1[b]; } +#ifdef DEBUG_MODE_DFT + for ( b = 0; b < hStereoDft->nbands; b++ ) + { + fprintf( pF, "Side gain: %d ", ind1[b] ); + fprintf( side_gain_values, " %d ", ind1[b] ); + } +#endif st->next_bit_pos += n_bits; ( *nb_bits ) += n_bits; } @@ -1961,6 +2149,10 @@ void stereo_dft_dec_read_BS( { ( *nb_bits ) += read_itd( st, &I ); stereo_dft_dequantize_itd( &I, hStereoDft->itd + k + k_offset, st->output_Fs ); +#ifdef DEBUG_MODE_DFT + fprintf( pF, "ITD: %d ", I ); + fprintf( ITD_values, "%d %d ", frame, I ); +#endif } } else if ( *nb_bits <= ( ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC - STEREO_DFT_ITD_MODE_NBITS - STEREO_DFT_SID_ITD_NBITS - 1 - SID_FORMAT_NBITS ) ) @@ -1977,6 +2169,10 @@ void stereo_dft_dec_read_BS( I = I << STEREO_DFT_SID_ITD_FAC; I += 256 * sign_flag; stereo_dft_dequantize_itd( &I, hStereoDft->itd + k + k_offset, st->output_Fs ); +#ifdef DEBUG_MODE_DFT + fprintf( pF, "ITD: %d ", I ); + fprintf( ITD_values, "%d %d ", frame, I ); +#endif } } @@ -2047,6 +2243,9 @@ void stereo_dft_dec_read_BS( hStereoDft->reverb_flag = get_next_indice( st, STEREO_DFT_REVERB_MODE_NBITS ); ( *nb_bits ) += STEREO_DFT_REVERB_MODE_NBITS; nb += STEREO_DFT_REVERB_MODE_NBITS; +#ifdef DEBUG_MODE_DFT + fprintf( RPG_values, " reverb_flag %d ", hStereoDft->reverb_flag ); +#endif if ( hStereoDft->reverb_flag ) { nbands -= STEREO_DFT_RES_PRED_BAND_MIN_CONST; @@ -2060,6 +2259,9 @@ void stereo_dft_dec_read_BS( if ( hStereoDft->res_pred_flag_0 == 0 ) { +#ifdef DEBUG_MODE_DFT + fprintf( RPG_values, "flag: 0" ); +#endif b = read_BS_adapt_GR_rpg( st->bit_stream, nb, ind1_pred, hStereoDft->res_pred_band_min, nbands, &hStereoDft->res_pred_flag_1 ); n_bits += b; } @@ -2067,6 +2269,9 @@ void stereo_dft_dec_read_BS( { if ( hStereoDft->res_pred_flag_0 == 2 ) { +#ifdef DEBUG_MODE_DFT + fprintf( RPG_values, "flag: 2" ); +#endif b = read_BS_GR( st->bit_stream, nb, &ind1_pred[hStereoDft->res_pred_band_min], nbands - hStereoDft->res_pred_band_min, &hStereoDft->res_pred_flag_1 ); n_bits += b; @@ -2077,6 +2282,9 @@ void stereo_dft_dec_read_BS( } else { +#ifdef DEBUG_MODE_DFT + fprintf( RPG_values, "flag: 1" ); +#endif for ( b = hStereoDft->res_pred_band_min; b < nbands; b++ ) { ind1_pred[b] = get_value( &st->bit_stream[nb], STEREO_DFT_RES_GAINS_BITS ); @@ -2098,6 +2306,13 @@ void stereo_dft_dec_read_BS( { I = ind1_pred[b]; stereo_dft_dequantize_res_gains( ind1 + b, &I, hStereoDft->side_gain + ( k + k_offset ) * STEREO_DFT_BAND_MAX + b, hStereoDft->res_pred_gain + ( k + k_offset ) * STEREO_DFT_BAND_MAX + b, 1 ); +#ifdef DEBUG_MODE_DFT + fprintf( pF, "Res pred values: %d ", I ); + if ( hStereoDft->res_pred_flag_0 == 2 ) + fprintf( RPG_values, " %d(%d) ", I, hStereoDft->res_pred_index_previous[b] ); + else + fprintf( RPG_values, " %d ", I ); +#endif hStereoDft->res_pred_index_previous[b] = I; hStereoDft->res_gains_ind[1][b + STEREO_DFT_BAND_MAX] = I; } @@ -2138,6 +2353,9 @@ void stereo_dft_dec_read_BS( } } +#ifdef DEBUG_MODE_DFT + /*fprintf(stderr, "\nbres: %d\n", *nb_bits - nb_bits0);*/ +#endif } if ( !( ivas_format == MASA_FORMAT && ivas_total_brate <= IVAS_SID_5k2 ) ) @@ -2171,6 +2389,9 @@ void stereo_dft_dec_read_BS( I = get_next_indice( st, STEREO_DFT_RES_GLOBAL_GAIN_BITS ); ( *nb_bits ) += STEREO_DFT_RES_GLOBAL_GAIN_BITS; +#ifdef DEBUG_MODE_DFT + fprintf( pF, "\nGain: %d ", I ); +#endif push_wmops( "residual_decode" ); if ( I != ECSQ_GLOBAL_GAIN_INDEX_ALL_ZERO ) @@ -2187,6 +2408,10 @@ void stereo_dft_dec_read_BS( n_bits = rc_uni_dec_finish( &range_uni_dec_state ); +#ifdef DEBUGGING + /* IVAS_fmToDo: the assert has to be changed with proper bitstream error handling */ + assert( range_uni_dec_state.bit_error_detected == 0 ); +#endif set_zero( res_buf, STEREO_DFT_N_8k ); ECSQ_dequantize_vector( dec, hStereoDft->res_global_gain, hStereoDft->res_cod_line_max, res_buf ); @@ -2202,6 +2427,10 @@ void stereo_dft_dec_read_BS( ( *nb_bits ) += n_bits; pop_wmops(); +#ifdef DEBUG_MODE_DFT + fprintf( pF, "%d (max: %d)", n_bits + STEREO_DFT_RES_GLOBAL_GAIN_BITS, max_bits ); + /*fprintf(pF, "%d (max: %d)", n_bits, max_bits);*/ +#endif } if ( hStereoDft->frame_sid && !( ivas_format == MASA_FORMAT && ivas_total_brate <= IVAS_SID_5k2 ) ) @@ -2217,6 +2446,13 @@ void stereo_dft_dec_read_BS( *total_brate = element_brate - ( *nb_bits * FRAMES_PER_SEC ); } +#ifdef DEBUG_MODE_DFT + /*fprintf(pF, "Total bits: %d", (*nb_bits));*/ + fprintf( pF, "\n" ); + fprintf( ITD_values, "\n" ); + fprintf( side_gain_values, "\n" ); + fprintf( RPG_values, "\n" ); +#endif return; } @@ -2506,6 +2742,7 @@ void stereo_dft_generate_res_pred( } } +#ifndef DEBUG_STEREO_DFT_NOCORE if ( hStereoDft->band_limits[nbands_respred] > bin0 ) { /* apply stereo filling in ACELP BWE region */ @@ -2569,6 +2806,7 @@ void stereo_dft_generate_res_pred( } } else +#endif { for ( b = band0; b < nbands_respred; b++ ) { @@ -2615,6 +2853,7 @@ void stereo_dft_generate_res_pred( g_long = 0.0f; g_short = 1.0f; } +#ifndef DEBUG_STEREO_DFT_NOCORE if ( hStereoDft->core_hist[d_short / 2] == ACELP_CORE ) { g_short = 0; @@ -2623,6 +2862,7 @@ void stereo_dft_generate_res_pred( { g_long = 0; } +#endif if ( max( g_short, g_long ) > 0 ) { @@ -2658,7 +2898,9 @@ void stereo_dft_generate_res_pred( } } } +#ifndef DEBUG_STEREO_DFT_NOCORE } +#endif /* update buffers */ for ( b = hStereoDft->res_pred_band_min; b < hStereoDft->nbands; b++ ) @@ -3063,6 +3305,14 @@ static void stereo_dft_adapt_sf_delay( hStereoDft->stefi_short_gain = ( STEREO_DFT_STEFFI_DELAY_LONG - target_delay ) / ( STEREO_DFT_STEFFI_DELAY_LONG - STEREO_DFT_STEFFI_DELAY_SHORT ); hStereoDft->stefi_long_gain = sqrtf( 1.0f - hStereoDft->stefi_short_gain * hStereoDft->stefi_short_gain ); +#ifdef DEBUG_MODE_DFT + dbgwrite( &hStereoDft->lt_pred_gain, sizeof( float ), 1, 1, "res/stereo_dft_lt_pred_gain_b.pcm" ); + dbgwrite( &hStereoDft->lt_pred_gain_variation, sizeof( float ), 1, 1, "res/stereo_dft_lt_pred_gain_variance_b.pcm" ); + dbgwrite( &hStereoDft->lt_var_mean_ratio, sizeof( float ), 1, 1, "res/stereo_dft_lt_var_mean_ratio_b.pcm" ); + dbgwrite( &target_delay, sizeof( float ), 1, 1, "res/stereo_dft_target_delay.pcm" ); + dbgwrite( &hStereoDft->stefi_short_gain, sizeof( float ), 1, 1, "res/stereo_dft_short_gain.pcm" ); + dbgwrite( &hStereoDft->stefi_long_gain, sizeof( float ), 1, 1, "res/stereo_dft_long_gain.pcm" ); +#endif /* DEBUG_MODE_DFT */ return; } diff --git a/lib_dec/ivas_stereo_dft_dec_dmx.c b/lib_dec/ivas_stereo_dft_dec_dmx.c index 120a060b2..e9bb3bc49 100644 --- a/lib_dec/ivas_stereo_dft_dec_dmx.c +++ b/lib_dec/ivas_stereo_dft_dec_dmx.c @@ -41,6 +41,9 @@ #include "ivas_rom_com.h" #include "ivas_rom_dec.h" #include "rom_com.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" @@ -170,6 +173,9 @@ void stereo_dft_unify_dmx( { g = pSideGain[b]; +#ifdef DEBUG_MODE_DFT + dbgwrite( &g, sizeof( float ), 1, 1, "./res/stereo_dft_dec_g.pcm" ); +#endif for ( i = hStereoDft->band_limits[b]; i < hStereoDft->band_limits[b + 1]; i++ ) { diff --git a/lib_dec/ivas_stereo_dft_plc.c b/lib_dec/ivas_stereo_dft_plc.c index 8c7611f73..4c026dfb7 100644 --- a/lib_dec/ivas_stereo_dft_plc.c +++ b/lib_dec/ivas_stereo_dft_plc.c @@ -37,6 +37,9 @@ #include "ivas_cnst.h" #include "ivas_prot.h" #include "math.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" /*--------------------------------------------------------------- diff --git a/lib_dec/ivas_stereo_eclvq_dec.c b/lib_dec/ivas_stereo_eclvq_dec.c index 0a16d2acc..b47c3d219 100644 --- a/lib_dec/ivas_stereo_eclvq_dec.c +++ b/lib_dec/ivas_stereo_eclvq_dec.c @@ -132,6 +132,9 @@ void ECSQ_decode( rc_st_dec = (RangeUniDecState *) ecsq_inst->ac_handle; +#ifdef DEBUGGING + assert( N > 0 ); +#endif segment_count = ( N + ECSQ_SEGMENT_SIZE - 1 ) / ECSQ_SEGMENT_SIZE; @@ -178,6 +181,9 @@ void ECSQ_decode( } else { +#ifdef DEBUGGING + assert( ECSQ_NONZERO_MAX == 3 ); +#endif nonzero = rc_uni_dec_read_bits( rc_st_dec, 2 ); diff --git a/lib_dec/ivas_stereo_esf_dec.c b/lib_dec/ivas_stereo_esf_dec.c index 391398fd0..ff7e810e8 100644 --- a/lib_dec/ivas_stereo_esf_dec.c +++ b/lib_dec/ivas_stereo_esf_dec.c @@ -35,6 +35,9 @@ #include "ivas_prot.h" #include "ivas_stat_dec.h" #include "ivas_cnst.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" /*-------------------------------------------------------------------* diff --git a/lib_dec/ivas_stereo_ica_dec.c b/lib_dec/ivas_stereo_ica_dec.c index 760d81ce6..b400dee72 100644 --- a/lib_dec/ivas_stereo_ica_dec.c +++ b/lib_dec/ivas_stereo_ica_dec.c @@ -38,6 +38,9 @@ #include "ivas_cnst.h" #include "prot.h" #include "ivas_prot.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" #include "rom_com.h" #include "ivas_rom_com.h" @@ -206,6 +209,11 @@ void stereo_tca_dec( l_shift_adapt = l_shift_adapt >> 1; } +#ifdef DEBUGGING + /* Max sample looked in INTERP1 should lie within the bounds of output_frame and memory populated */ + assert( ( ( min( N_MAX_SHIFT_CHANGE, N_MAX_SHIFT_CHANGE * output_Fs / 32000.0f ) + 1 ) + SINC_ORDER1 / INTERP_FACTOR1 ) + l_shift_adapt - currentNCShift < output_frame ); + assert( ( ( min( N_MAX_SHIFT_CHANGE, N_MAX_SHIFT_CHANGE * output_Fs / 32000.0f ) + 1 ) + SINC_ORDER1 / INTERP_FACTOR1 + currentNCShift ) <= L_DEC_MEM_LEN_ICA ); +#endif if ( abs( currentNCShift - prevNCShift ) <= N_MAX_SHIFT_CHANGE && bothChannelShift == 0 ) { adjustTargetSignal( target - currentNCShift, currentNCShift, prevNCShift, l_shift_adapt, 0 ); diff --git a/lib_dec/ivas_stereo_icbwe_dec.c b/lib_dec/ivas_stereo_icbwe_dec.c index 334fb5bd7..aad34a875 100644 --- a/lib_dec/ivas_stereo_icbwe_dec.c +++ b/lib_dec/ivas_stereo_icbwe_dec.c @@ -41,6 +41,9 @@ #include "wmc_auto.h" #include "rom_com.h" #include "ivas_rom_com.h" +#ifdef DEBUGGING +#include "debug.h" +#endif /*-------------------------------------------------------------------* * ic_bwe_dec_reset() @@ -167,6 +170,21 @@ void stereo_icBWE_dec( hCPE->hStereoDft->hb_nrg[0] = hb_nrg; hCPE->hStereoDft->td_gain[0] = 0; hCPE->hStereoDft->core_hist[0] = st->core; +#ifdef DEBUG_MODE_DFT + { + int16_t tmp[L_FRAME48k]; + for ( i = 0; i < output_frame; i++ ) + { + tmp[i] = (int16_t) synthRef[i]; + } + dbgwrite( tmp, sizeof( int16_t ), output_frame, 1, "res/hb_synth.pcm" ); + for ( i = 0; i < output_frame; i++ ) + { + tmp[i] = (int16_t) hCPE->hStereoDft->hb_stefi_sig[i + output_frame / 2]; + } + dbgwrite( tmp, sizeof( int16_t ), output_frame, 1, "res/hb_stefi_sig.pcm" ); + } +#endif /* DEBUG_MODE_DFT */ } /*--------------------------------------------------------------------* @@ -666,7 +684,11 @@ void stereo_icBWE_decproc( { v_add( temp0, output[0], output[0], output_frame ); +#ifdef DEBUG_STEREO_DFT_NOSTEREO + v_add( temp0, output[1], output[1], output_frame ); +#else v_add( temp1, output[1], output[1], output_frame ); +#endif } mvr2r( outputHB[0] + output_frame - memOffset, hStereoICBWE->memOutHB[0], memOffset ); mvr2r( outputHB[1] + output_frame - memOffset, hStereoICBWE->memOutHB[1], memOffset ); diff --git a/lib_dec/ivas_stereo_mdct_core_dec.c b/lib_dec/ivas_stereo_mdct_core_dec.c index 20a6e3e5b..c95729bc2 100644 --- a/lib_dec/ivas_stereo_mdct_core_dec.c +++ b/lib_dec/ivas_stereo_mdct_core_dec.c @@ -39,6 +39,9 @@ #include "stat_com.h" #include "ivas_prot.h" #include "ivas_stat_dec.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" @@ -332,6 +335,9 @@ void stereo_mdct_core_dec( if ( ( !bfi || !( sts[0]->core == ACELP_CORE && sts[1]->core == ACELP_CORE ) ) && !hCPE->hStereoMdct->isSBAStereoMode ) { +#ifdef DEBUGGING + assert( ( sts[0]->core == sts[1]->core ) || ( ( hCPE->hStereoMdct->mdct_stereo_mode[0] == SMDCT_DUAL_MONO ) && ( hCPE->hStereoMdct->mdct_stereo_mode[1] == SMDCT_DUAL_MONO ) ) ); +#endif stereo_decoder_tcx( hCPE->hStereoMdct, ms_mask, x_0[1], x[0], x[1], &hCPE->hStereoMdct->mdct_stereo_mode[0], sts[0]->core, sts[1]->core, sts[0]->igf, L_frameTCX[0], L_frameTCX[1], 0, sts[0]->last_core, sts[1]->last_core, 0 ); } diff --git a/lib_dec/ivas_stereo_mdct_stereo_dec.c b/lib_dec/ivas_stereo_mdct_stereo_dec.c index 42cbf3378..95d7ba6d6 100644 --- a/lib_dec/ivas_stereo_mdct_stereo_dec.c +++ b/lib_dec/ivas_stereo_mdct_stereo_dec.c @@ -64,6 +64,9 @@ void parse_stereo_from_bitstream( { int16_t i, k, nSubframes, mdct_stereo_mode; STEREO_MDCT_BAND_PARAMETERS *sfbConf; +#ifdef DEBUGGING + int16_t nbits_start = st0->next_bit_pos; +#endif if ( !isSBAStereoMode ) { @@ -182,6 +185,13 @@ void parse_stereo_from_bitstream( assert( hStereoMdct->split_ratio > 0 ); } +#ifdef DEBUGGING + { + int16_t nBitsStereo = st0->next_bit_pos - nbits_start; + + assert( nBitsStereo <= st0->bits_frame_nominal ); + } +#endif return; } @@ -199,8 +209,13 @@ void stereo_decoder_tcx( STEREO_MDCT_DEC_DATA *hStereoMdct, /* i/o: MDCT stereo decoder structure */ int16_t ms_mask[NB_DIV][MAX_SFB], /* i : bandwise MS mask */ float *spec_r_0[NB_DIV], /* i/o: spectrum right channel */ +#ifdef FIX_887_ARRAY_SIZE_DFT_MDCT_STEREO float *spec_l[], /* i/o: spectrum left channel [NB_DIV][N] */ float *spec_r[], /* i/o: spectrum right channel [NB_DIV][N] */ +#else + float *spec_l[NB_DIV], /* i/o: spectrum left channel */ + float *spec_r[NB_DIV], /* i/o: spectrum right channel */ +#endif const int16_t mdct_stereo_mode[], /* i : stereo mode (FB/band wise MS, dual mono */ const int16_t core_l, /* i : core for left channel (TCX20/TCX10) */ const int16_t core_r, /* i : core for right channel (TCX20/TCX10) */ @@ -260,6 +275,12 @@ void stereo_decoder_tcx( } } } +#ifdef DEBUGGING + else if ( mdct_stereo_mode[k] != SMDCT_DUAL_MONO ) + { + assert( !"Not supported MDCT stereo mode!\n" ); + } +#endif if ( igf ) { @@ -291,6 +312,12 @@ void stereo_decoder_tcx( } } } +#ifdef DEBUGGING + else if ( hStereoMdct->IGFStereoMode[k] != SMDCT_DUAL_MONO ) + { + assert( !"Not supported MDCT stereo mode!\n" ); + } +#endif } if ( !mct_on ) diff --git a/lib_dec/ivas_stereo_switching_dec.c b/lib_dec/ivas_stereo_switching_dec.c index 96ff3f48f..d311d7b41 100644 --- a/lib_dec/ivas_stereo_switching_dec.c +++ b/lib_dec/ivas_stereo_switching_dec.c @@ -32,6 +32,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "rom_com.h" #include "prot.h" @@ -1835,6 +1838,9 @@ void smooth_dft2td_transition( if ( ( ipit_max + corr_len ) > ilen ) /*ensure the search is performed on the available memory*/ { +#ifdef DEBUG_MODE_TD + /*printf( "**********Pitch too long = %d, skipping this loop at frame %d\n", ipit_max + corr_len, frame );*/ +#endif continue; } @@ -1874,6 +1880,9 @@ void smooth_dft2td_transition( ptO[i] = pt1[i]; } } +#ifdef DEBUG_MODE_TD + /*printf( "ch %d, ipit_max %d ipit_min %d, ipit %d :::: lsearch %d\tidiff %d\t%.4f At frame : \t%d\n", ch, ipit_max, ipit_min, ipit, lsearch, idiff, fmaxcorr, frame );*/ +#endif /* Set buffer for the reserved buffer of the current frame */ ptO2 = tmp_out2 + output_frame - ilen; @@ -1908,6 +1917,9 @@ void smooth_dft2td_transition( ptO2[i] = pt1[i]; } } +#ifdef DEBUG_MODE_TD + /*printf( "ch %d, ipit_max %d ipit_min %d, ipit %d :::: lsearch %d\tidiff %d\t%.4f At frame : \t%d\n", ch, ipit_max, ipit_min, ipit, lsearch, idiff, fmaxcorr, frame );*/ +#endif /* perform OVA between predicted signals */ flen = 1.0f / ilen; diff --git a/lib_dec/ivas_stereo_td_dec.c b/lib_dec/ivas_stereo_td_dec.c index f7a26cdef..41018cae2 100644 --- a/lib_dec/ivas_stereo_td_dec.c +++ b/lib_dec/ivas_stereo_td_dec.c @@ -39,6 +39,9 @@ #include "ivas_prot.h" #include "ivas_rom_com.h" #include "ivas_cnst.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" /*-------------------------------------------------------------------* @@ -247,6 +250,12 @@ void tdm_configure_dec( hCPE->hStereoTCA->targetGain = powf( 10, hCPE->hStereoTCA->targetGain ); } +#ifdef DEBUG_MODE_TD + dbgwrite( &mod_ct, 2, 1, 320, "res/mod_ct.dec" ); + dbgwrite( tdm_ratio_idx, 2, 1, 320, "res/tdm_ratio_idx.dec" ); + dbgwrite( &tdm_inst_ratio_idx, 2, 1, 320, "res/tdm_inst_ratio_idx.dec" ); + dbgwrite( &hStereoTD->tdm_lp_reuse_flag, 2, 1, 320, "res/tdm_lp_reuse_flag.dec" ); +#endif /* set the BW of the secondary channel */ if ( hStereoTD->tdm_LRTD_flag && sts[1]->bits_frame_channel >= IVAS_16k4 / FRAMES_PER_SEC ) diff --git a/lib_dec/ivas_svd_dec.c b/lib_dec/ivas_svd_dec.c index 9ea4af761..d2c72d62a 100644 --- a/lib_dec/ivas_svd_dec.c +++ b/lib_dec/ivas_svd_dec.c @@ -37,6 +37,9 @@ #include "ivas_stat_dec.h" #include "ivas_cnst.h" #include +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" diff --git a/lib_dec/ivas_tcx_core_dec.c b/lib_dec/ivas_tcx_core_dec.c index d705b8f45..71e20a5df 100644 --- a/lib_dec/ivas_tcx_core_dec.c +++ b/lib_dec/ivas_tcx_core_dec.c @@ -33,6 +33,9 @@ #include #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "prot.h" #include "rom_com.h" @@ -246,6 +249,10 @@ void stereo_tcx_core_dec( set_zero( synth, L_FRAME_PLUS + M ); set_zero( synthFB, L_FRAME_PLUS + M ); +#ifdef DEBUG_MODE_INFO_PLC + dbgwrite( synth_buf, sizeof( float ), OLD_SYNTH_SIZE_DEC + L_FRAME_PLUS + M, 1, "res/synth_buf_init" ); + dbgwrite( synth_bufFB, sizeof( float ), OLD_SYNTH_SIZE_DEC + L_FRAME_PLUS + M, 1, "res/synthFB_buf_init" ); +#endif /*--------------------------------------------------------------------------------* * BITSTREAM DECODING @@ -731,6 +738,29 @@ void stereo_tcx_core_dec( } } +#ifdef DEBUG_MODE_TCX + { + int16_t tmp[L_FRAME48k]; + static FILE *sP = NULL; + + for ( i = 0; i < hTcxDec->L_frameTCX; i++ ) + { + tmp[i] = (int16_t) ( signal_outFB[i] + 0.5f ); + } + dbgwrite( tmp, sizeof( int16_t ), hTcxDec->L_frameTCX, 1, "./res/stereo_tcx_dec_synthFB.pcm" ); + + for ( i = 0; i < hTcxDec->L_frameTCX; i++ ) + { + tmp[i] = (int16_t) ( signal_out[i] + 0.5f ); + } + dbgwrite( tmp, sizeof( int16_t ), hTcxDec->L_frameTCX, 1, "./res/stereo_tcx_dec_synthLB.pcm" ); + + if ( sP == NULL ) + sP = fopen( "./res/stereo_tcx_core_dec_swicthes.txt", "w" ); + + fprintf( sP, "frame:%d\t mdct_sw=%d\t rf_mode=%d tcxonly=%d\t tcxMode=%d\t core=%d\t, enableTcxLpc=%d\t igf=%d\t envWeighted=%d\t lpcQuantization=%d\t enablePlcWaveadjust=%d\t tcxltp=%d\t fIsTNSAllowed=%d\t tcx_lpc_shaped_ari=%d\t ctx_hm=%d\t \n", frame, st->mdct_sw, 0, st->tcxonly, 0, st->core, hTcxDec->enableTcxLpc, st->igf, hTcxDec->envWeighted, st->lpcQuantization, st->enablePlcWaveadjust, hTcxLtpDec->tcxltp, st->hTcxCfg->fIsTNSAllowed, 0, st->hTcxCfg->ctx_hm ); + } +#endif pop_wmops(); @@ -756,6 +786,12 @@ static void dec_prm_tcx( int16_t start_bit_pos, bits_common; CONTEXT_HM_CONFIG hm_cfg; int16_t indexBuffer[N_MAX + 1]; +#ifdef DEBUG_MODE_TCX + int16_t nbits_tcx; + static FILE *pF = NULL; + if ( pF == NULL ) + pF = fopen( "./res/stereo_tcx_dec_ind.txt", "w" ); +#endif assert( st->mdct_sw == MODE1 ); @@ -764,6 +800,10 @@ static void dec_prm_tcx( *--------------------------------------------------------------------------------*/ hm_cfg.indexBuffer = indexBuffer; +#ifdef DEBUG_MODE_TCX + fprintf( pF, "== stereo Chan %d - Nominal Bits %d - Allocated Bits %d ==\n", st->idchan, st->bits_frame_nominal, (int16_t) ( st->total_brate / FRAMES_PER_SEC ) ); + fprintf( pF, "stereo Common Header: %d bits\n", st->next_bit_pos ); +#endif if ( st->element_mode != IVAS_CPE_MDCT ) { st->bits_frame_core = (int16_t) ( ( st->total_brate / FRAMES_PER_SEC ) - st->next_bit_pos ); @@ -822,6 +862,10 @@ static void dec_prm_tcx( } } +#ifdef DEBUG_MODE_TCX + fprintf( pF, "\t TCX Header: %d bits: %d %d %d %d\n", st->next_bit_pos - start_bit_pos, st->tcxonly, st->core, st->tcxonly ? st->clas_dec : st->hTcxCfg->coder_type, st->hTcxCfg->tcx_curr_overlap_mode ); + nbits_tcx = st->next_bit_pos; +#endif /*--------------------------------------------------------------------------------* * LPC parameters @@ -831,6 +875,9 @@ static void dec_prm_tcx( bits_common = st->next_bit_pos - start_bit_pos; +#ifdef DEBUG_MODE_TCX + fprintf( pF, "\t TCX LPC: %d bits\n", st->next_bit_pos - nbits_tcx ); +#endif /*--------------------------------------------------------------------------------* * TCX20/10 parameters diff --git a/lib_dec/ivas_td_low_rate_dec.c b/lib_dec/ivas_td_low_rate_dec.c index 646c6561d..8ab266345 100644 --- a/lib_dec/ivas_td_low_rate_dec.c +++ b/lib_dec/ivas_td_low_rate_dec.c @@ -32,6 +32,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "stat_enc.h" #include "rom_com.h" diff --git a/lib_dec/jbm_jb4_circularbuffer.c b/lib_dec/jbm_jb4_circularbuffer.c index da95e4135..b1067f96e 100644 --- a/lib_dec/jbm_jb4_circularbuffer.c +++ b/lib_dec/jbm_jb4_circularbuffer.c @@ -39,6 +39,9 @@ #include "options.h" #include "string.h" #include "prot.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" /* local includes */ #include "jbm_jb4_circularbuffer.h" diff --git a/lib_dec/jbm_jb4_inputbuffer.c b/lib_dec/jbm_jb4_inputbuffer.c index 852c95946..32c870bfa 100644 --- a/lib_dec/jbm_jb4_inputbuffer.c +++ b/lib_dec/jbm_jb4_inputbuffer.c @@ -41,6 +41,9 @@ #include "options.h" #include "prot.h" #include "string.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "jbm_jb4_inputbuffer.h" #include "wmc_auto.h" @@ -208,6 +211,14 @@ int16_t JB4_INPUTBUFFER_Enque( } } +#ifdef DEBUGGING + assert( h->compareFunction( element, JB4_INPUTBUFFER_Element( h, low ), &replace ) != 0 ); + if ( low > 0 ) + assert( h->compareFunction( element, JB4_INPUTBUFFER_Element( h, low - 1 ), &replace ) > 0 ); + assert( h->compareFunction( element, JB4_INPUTBUFFER_Element( h, low ), &replace ) < 0 ); + if ( (uint16_t) ( low + 1 ) < size ) + assert( h->compareFunction( element, JB4_INPUTBUFFER_Element( h, low + 1 ), &replace ) < 0 ); +#endif insertPos = ( h->readPos + low ) % h->capacity; if ( h->readPos < h->writePos ) diff --git a/lib_dec/jbm_jb4_jmf.c b/lib_dec/jbm_jb4_jmf.c index 99abd75e5..5d7dfa2e6 100644 --- a/lib_dec/jbm_jb4_jmf.c +++ b/lib_dec/jbm_jb4_jmf.c @@ -43,6 +43,9 @@ #include #include "options.h" #include "prot.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" /* local includes */ diff --git a/lib_dec/jbm_jb4sb.c b/lib_dec/jbm_jb4sb.c index 04a2aac31..755187b64 100644 --- a/lib_dec/jbm_jb4sb.c +++ b/lib_dec/jbm_jb4sb.c @@ -42,6 +42,9 @@ #include #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" /* local headers */ #include "jbm_jb4_circularbuffer.h" diff --git a/lib_dec/jbm_pcmdsp_apa.c b/lib_dec/jbm_pcmdsp_apa.c index 8a69fa78e..1242004fc 100644 --- a/lib_dec/jbm_pcmdsp_apa.c +++ b/lib_dec/jbm_pcmdsp_apa.c @@ -44,6 +44,9 @@ #include #include "options.h" #include "prot.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" /* local headers */ #include "jbm_pcmdsp_apa.h" diff --git a/lib_dec/jbm_pcmdsp_similarityestimation.c b/lib_dec/jbm_pcmdsp_similarityestimation.c index 13b3a3190..c67e71d59 100644 --- a/lib_dec/jbm_pcmdsp_similarityestimation.c +++ b/lib_dec/jbm_pcmdsp_similarityestimation.c @@ -41,6 +41,9 @@ #include #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" /* local headers */ diff --git a/lib_dec/jbm_pcmdsp_window.c b/lib_dec/jbm_pcmdsp_window.c index 942f25db6..15f692fb8 100644 --- a/lib_dec/jbm_pcmdsp_window.c +++ b/lib_dec/jbm_pcmdsp_window.c @@ -38,6 +38,9 @@ #include #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "jbm_pcmdsp_window.h" #include "cnst.h" #include "wmc_auto.h" diff --git a/lib_dec/lead_deindexing.c b/lib_dec/lead_deindexing.c index 0b3c68d10..830daa812 100644 --- a/lib_dec/lead_deindexing.c +++ b/lib_dec/lead_deindexing.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "prot.h" #include "rom_com.h" diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index 9281c292d..b1ac64db2 100644 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -41,6 +41,9 @@ #include #include #include +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" /*---------------------------------------------------------------------* @@ -80,7 +83,9 @@ struct IVAS_DEC PCMDSP_APA_HANDLE hTimeScaler; bool needNewFrame; bool hasBeenFedFrame; +#ifdef NONBE_UNIFIED_DECODING_PATHS bool updateOrientation; +#endif uint16_t nSamplesAvailableNext; int16_t nSamplesRendered; int16_t nTransportChannelsOld; @@ -103,12 +108,27 @@ static ivas_error evs_dec_main( Decoder_Struct *st_ivas, const int16_t nOutSampl static ivas_error input_format_API_to_internal( IVAS_DEC_INPUT_FORMAT input_format, int16_t *bitstream_format_internal, int16_t *sdp_hf_only, const bool is_voip_enabled ); static void init_decoder_config( DECODER_CONFIG_HANDLE hDecoderConfig ); static ivas_error IVAS_DEC_VoIP_reconfigure( IVAS_DEC_HANDLE hIvasDec, const uint16_t nTransportChannels, const uint16_t l_ts ); +#ifdef SPLIT_REND_WITH_HEAD_ROT +static ivas_error IVAS_DEC_Setup( IVAS_DEC_HANDLE hIvasDec, uint16_t *nTcBufferGranularity, uint8_t *nTransportChannels, uint8_t *nOutChannels, uint16_t *nSamplesRendered, const IVAS_DEC_PCM_TYPE pcmType, void *data ); +#else static ivas_error IVAS_DEC_Setup( IVAS_DEC_HANDLE hIvasDec, uint16_t *nTcBufferGranularity, uint8_t *nTransportChannels, uint8_t *nOutChannels, uint16_t *nSamplesRendered, int16_t *data ); +#endif static ivas_error IVAS_DEC_GetTcSamples( IVAS_DEC_HANDLE hIvasDec, float *pcmBuf, int16_t *nOutSamples ); static ivas_error IVAS_DEC_RendererFeedTcSamples( IVAS_DEC_HANDLE hIvasDec, const int16_t nSamplesForRendering, int16_t *nSamplesResidual, float *pcmBuf ); +#ifdef SPLIT_REND_WITH_HEAD_ROT +static ivas_error IVAS_DEC_GetRenderedSamples( IVAS_DEC_HANDLE hIvasDec, const uint16_t nSamplesForRendering, uint16_t *nSamplesRendered, uint16_t *nSamplesAvailableNext, const IVAS_DEC_PCM_TYPE pcmType, void *pcmBuf ); +#else static ivas_error IVAS_DEC_GetRenderedSamples( IVAS_DEC_HANDLE hIvasDec, const uint16_t nSamplesForRendering, uint16_t *nSamplesRendered, uint16_t *nSamplesAvailableNext, int16_t *pcmBuf ); +#endif static ivas_error IVAS_DEC_GetBufferedNumberOfSamples( IVAS_DEC_HANDLE hIvasDec, int16_t *nSamplesBuffered ); +#ifdef SPLIT_REND_WITH_HEAD_ROT +static PCM_RESOLUTION pcm_type_API_to_internal( const IVAS_DEC_PCM_TYPE pcmType ); +static void *pcm_buffer_offset( void *buffer, const IVAS_DEC_PCM_TYPE pcmType, const int32_t offset ); +static ivas_error set_pcm_buffer_to_zero( void *buffer, const IVAS_DEC_PCM_TYPE pcmType, const int16_t nZeroSamples ); +#endif +#ifdef NONBE_UNIFIED_DECODING_PATHS static int16_t get_render_frame_size_ms( IVAS_RENDER_FRAMESIZE render_framesize ); +#endif /*---------------------------------------------------------------------* @@ -155,7 +175,9 @@ ivas_error IVAS_DEC_Open( hIvasDec->hasBeenFedFirstGoodFrame = false; hIvasDec->hasDecodedFirstGoodFrame = false; hIvasDec->isInitialized = false; +#ifdef NONBE_UNIFIED_DECODING_PATHS hIvasDec->updateOrientation = false; +#endif hIvasDec->mode = mode; @@ -250,6 +272,12 @@ static void init_decoder_config( hDecoderConfig->Opt_non_diegetic_pan = 0; hDecoderConfig->non_diegetic_pan_gain = 0; hDecoderConfig->Opt_tsm = 0; +#ifdef SPLIT_REND_WITH_HEAD_ROT + hDecoderConfig->Opt_Limiter = 1; +#endif +#ifndef NONBE_UNIFIED_DECODING_PATHS + hDecoderConfig->Opt_5ms = 0; +#endif hDecoderConfig->Opt_delay_comp = 0; hDecoderConfig->Opt_ExternalOrientation = 0; hDecoderConfig->Opt_dpid_on = 0; @@ -348,7 +376,11 @@ ivas_error IVAS_DEC_Configure( const uint32_t sampleRate, /* i : output sampling frequency */ const AUDIO_CONFIG outputConfig, /* i : output configuration */ const int16_t tsmEnabled, /* i : enable time scale modification */ +#ifndef NONBE_UNIFIED_DECODING_PATHS + const int16_t enable5ms, /* i : enable 5ms rendering path */ +#else const IVAS_RENDER_FRAMESIZE renderFramesize, /* i : rendering frame size */ +#endif const int16_t customLsOutputEnabled, /* i : enable custom loudspeaker setup handle */ const int16_t hrtfReaderEnabled, /* i : enable HRTF binary file input */ const int16_t enableHeadRotation, /* i : enable head rotation for binaural output */ @@ -407,6 +439,9 @@ ivas_error IVAS_DEC_Configure( } hDecoderConfig->Opt_tsm = tsmEnabled; +#ifndef NONBE_UNIFIED_DECODING_PATHS + hDecoderConfig->Opt_5ms = enable5ms; +#endif hDecoderConfig->Opt_LsCustom = customLsOutputEnabled; hDecoderConfig->Opt_Headrotation = enableHeadRotation; hDecoderConfig->orientation_tracking = orientation_tracking; @@ -419,6 +454,7 @@ ivas_error IVAS_DEC_Configure( hDecoderConfig->Opt_dpid_on = Opt_dpid_on; hDecoderConfig->Opt_aeid_on = acousticEnvironmentId != 65535 ? TRUE : FALSE; +#ifdef NONBE_UNIFIED_DECODING_PATHS if ( renderFramesize == IVAS_RENDER_FRAMESIZE_UNKNOWN ) { return IVAS_ERR_WRONG_PARAMS; @@ -431,7 +467,14 @@ ivas_error IVAS_DEC_Configure( { hDecoderConfig->render_framesize = renderFramesize; } +#endif +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { + hDecoderConfig->Opt_Headrotation = TRUE; + } +#endif /* Set decoder parameters to initial values */ if ( ( error = ivas_init_decoder_front( st_ivas ) ) != IVAS_ERR_OK ) @@ -455,7 +498,87 @@ ivas_error IVAS_DEC_Configure( } +#ifdef SPLIT_REND_WITH_HEAD_ROT +/*---------------------------------------------------------------------* + * IVAS_DEC_EnableSplitRendering( ) + * + * Intitialize Split rendering + *---------------------------------------------------------------------*/ + +ivas_error IVAS_DEC_EnableSplitRendering( + IVAS_DEC_HANDLE hIvasDec /* i/o: IVAS decoder handle */ +) +{ + DECODER_CONFIG_HANDLE hDecoderConfig; + ivas_error error; + + error = IVAS_ERR_OK; + + + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + hDecoderConfig = hIvasDec->st_ivas->hDecoderConfig; + + hDecoderConfig->Opt_Headrotation = 1; +#ifndef NONBE_UNIFIED_DECODING_PATHS + hDecoderConfig->Opt_5ms = false; +#else + hDecoderConfig->render_framesize = IVAS_RENDER_FRAMESIZE_20MS; +#endif + + hDecoderConfig->Opt_Limiter = 0; + + return error; +} +#endif + +#ifndef NONBE_UNIFIED_DECODING_PATHS +/*---------------------------------------------------------------------* + * IVAS_DEC_Set5msFlag( ) + * + * Get the 5ms flag + *---------------------------------------------------------------------*/ + +ivas_error IVAS_DEC_Set5msFlag( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + const int16_t enable5ms /* i : 5ms flag */ +) +{ + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || hIvasDec->st_ivas->hDecoderConfig == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + hIvasDec->st_ivas->hDecoderConfig->Opt_5ms = enable5ms; + + return IVAS_ERR_OK; +} + + +/*---------------------------------------------------------------------* + * IVAS_DEC_Get5msFlag( ) + * + * Get the 5ms flag + *---------------------------------------------------------------------*/ + +ivas_error IVAS_DEC_Get5msFlag( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + int16_t *enable5ms /* o : 5ms flag */ +) +{ + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || enable5ms == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + *enable5ms = (int16_t) hIvasDec->st_ivas->hDecoderConfig->Opt_5ms; + return IVAS_ERR_OK; +} +#else /*---------------------------------------------------------------------* * get_render_framesize_ms( ) * @@ -594,6 +717,7 @@ ivas_error IVAS_DEC_GetNumOrientationSubframes( return IVAS_ERR_OK; } +#endif /*---------------------------------------------------------------------* @@ -625,10 +749,19 @@ ivas_error IVAS_DEC_EnableVoIP( hIvasDec->Opt_VOIP = 1; hDecoderConfig->Opt_tsm = 1; +#ifndef NONBE_UNIFIED_DECODING_PATHS + hDecoderConfig->Opt_5ms = 1; +#endif if ( hDecoderConfig->output_config != IVAS_AUDIO_CONFIG_EXTERNAL ) { hDecoderConfig->nchan_out = audioCfg2channels( hDecoderConfig->output_config ); } +#ifdef VARIABLE_SPEED_DECODING + else + { + hDecoderConfig->nchan_out = 1; + } +#endif if ( ( error = input_format_API_to_internal( inputFormat, &hIvasDec->bitstreamformat, &hIvasDec->sdp_hf_only, true ) ) != IVAS_ERR_OK ) { @@ -767,17 +900,88 @@ ivas_error IVAS_DEC_FeedFrame_Serial( * Main function to decode to PCM data *---------------------------------------------------------------------*/ +#ifndef NONBE_UNIFIED_DECODING_PATHS +static ivas_error _GetSamples( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + const PCM_RESOLUTION pcm_resolution, + void *pcmBuf, /* i/o: buffer for decoded PCM output. The memory must already be allocated and be able to hold the expected number of output samples, based on frame size and number of output channels */ +#else + int16_t *pcmBuf, /* i/o: buffer for decoded PCM output. The memory must already be allocated and be able to hold the expected number of output samples, based on frame size and number of output channels */ +#endif + int16_t *nOutSamples /* o : number of samples per channel written to output buffer */ +) +{ + Decoder_Struct *st_ivas; + ivas_error error; + + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + st_ivas = hIvasDec->st_ivas; + + *nOutSamples = (int16_t) ( st_ivas->hDecoderConfig->output_Fs / FRAMES_PER_SEC ); + + if ( hIvasDec->mode == IVAS_DEC_MODE_EVS ) + { +#if defined DEBUGGING && defined SPLIT_REND_WITH_HEAD_ROT + assert( pcm_resolution == PCM_INT16 ); +#endif +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( error = evs_dec_main( st_ivas, *nOutSamples, NULL, (int16_t *) pcmBuf ) ) != IVAS_ERR_OK ) +#else + if ( ( error = evs_dec_main( st_ivas, *nOutSamples, NULL, pcmBuf ) ) != IVAS_ERR_OK ) +#endif + { + return error; + } + } + else if ( hIvasDec->mode == IVAS_DEC_MODE_IVAS ) + { + /* run the main IVAS decoding routine */ + +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( error = ivas_dec( st_ivas, pcm_resolution, pcmBuf ) ) != IVAS_ERR_OK ) +#else + if ( ( error = ivas_dec( st_ivas, pcmBuf ) ) != IVAS_ERR_OK ) +#endif + { + return error; + } + + hIvasDec->isInitialized = true; /* Initialization done in ivas_dec() */ + } + + if ( hIvasDec->hasBeenFedFirstGoodFrame ) + { + hIvasDec->hasDecodedFirstGoodFrame = true; + } + + return IVAS_ERR_OK; +} +#endif ivas_error IVAS_DEC_GetSamples( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ const int16_t nSamplesAsked, /* i : number of samples wanted by the caller */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + const IVAS_DEC_PCM_TYPE pcmType, /* i : type for the decoded PCM resolution */ + void *pcmBuf, /* o : output synthesis signal */ +#else int16_t *pcmBuf, /* i/o: buffer for decoded PCM output. The memory must already be allocated and be able to hold the expected number of output samples, based on frame size and number of output channels */ +#endif int16_t *nOutSamples, /* o : number of samples per channel written to output buffer */ bool *needNewFrame /* o :indication that the decoder needs a new frame */ ) { ivas_error error; +#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX int16_t nOutSamplesElse, nSamplesToRender; +#else + int16_t nOutSamplesElse, result, nSamplesToRender; +#endif uint16_t nSamplesRendered, nSamplesRendered_loop, l_ts, nTimeScalerOutSamples; uint8_t nTransportChannels, nOutChannels; @@ -792,6 +996,7 @@ ivas_error IVAS_DEC_GetSamples( return IVAS_ERR_UNEXPECTED_NULL_POINTER; } +#ifdef NONBE_UNIFIED_DECODING_PATHS if ( hIvasDec->updateOrientation ) { /*----------------------------------------------------------------* @@ -803,9 +1008,20 @@ ivas_error IVAS_DEC_GetSamples( return error; } +#ifdef SPLIT_REND_WITH_HEAD_ROT + /*----------------------------------------------------------------* + * Binaural split rendering setup + *----------------------------------------------------------------*/ + + 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 ) + { + ivas_set_split_rend_ht_setup( &hIvasDec->st_ivas->hSplitBinRend, hIvasDec->st_ivas->hCombinedOrientationData ); + } +#endif hIvasDec->updateOrientation = false; } +#endif if ( !hIvasDec->hasBeenFedFrame && hIvasDec->nSamplesAvailableNext == 0 ) { @@ -837,12 +1053,42 @@ ivas_error IVAS_DEC_GetSamples( { /* setup */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( error = IVAS_DEC_Setup( hIvasDec, &l_ts, &nTransportChannels, &nOutChannels, &nSamplesRendered_loop, pcmType, pcm_buffer_offset( pcmBuf, pcmType, nSamplesRendered * nOutChannels ) ) ) != IVAS_ERR_OK ) +#else if ( ( error = IVAS_DEC_Setup( hIvasDec, &l_ts, &nTransportChannels, &nOutChannels, &nSamplesRendered_loop, pcmBuf + nSamplesRendered * nOutChannels ) ) != IVAS_ERR_OK ) +#endif { return error; } +#ifdef SPLIT_REND_WITH_HEAD_ROT + /* :TODO: change nSamplesAsked also if we are in 5ms 0dof split rendering... */ +#endif + } +#ifndef NONBE_UNIFIED_DECODING_PATHS + if ( !hIvasDec->st_ivas->hDecoderConfig->Opt_5ms ) + { +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( error = _GetSamples( hIvasDec, pcm_type_API_to_internal( pcmType ), pcmBuf, nOutSamples ) ) != IVAS_ERR_OK ) +#else + if ( ( error = _GetSamples( hIvasDec, pcmBuf, nOutSamples ) ) != IVAS_ERR_OK ) +#endif + { + return error; + } +#ifdef DEBUGGING + assert( *nOutSamples == nSamplesAsked ); +#endif + hIvasDec->nSamplesAvailableNext = 0; + hIvasDec->nSamplesRendered = *nOutSamples; + nSamplesRendered = *nOutSamples; + hIvasDec->needNewFrame = true; + hIvasDec->hasBeenFedFrame = false; + *needNewFrame = true; } + else +#endif { /* check if we need to run the setup function, tc decoding and feeding the renderer */ if ( !hIvasDec->isInitialized || hIvasDec->hasBeenFedFrame ) @@ -850,7 +1096,11 @@ ivas_error IVAS_DEC_GetSamples( int16_t nResidualSamples, nSamplesTcsScaled; nSamplesRendered += nSamplesRendered_loop; +#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX if ( hIvasDec->st_ivas->hDecoderConfig->Opt_tsm && nTransportChannels != hIvasDec->nTransportChannelsOld ) +#else + if ( nTransportChannels != hIvasDec->nTransportChannelsOld ) +#endif { if ( ( error = IVAS_DEC_VoIP_reconfigure( hIvasDec, nTransportChannels, l_ts ) ) != IVAS_ERR_OK ) { @@ -872,6 +1122,7 @@ ivas_error IVAS_DEC_GetSamples( return IVAS_ERR_UNKNOWN; } +#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX if ( apa_exec( hIvasDec->hTimeScaler, hIvasDec->apaExecBuffer, hIvasDec->nSamplesFrame * nTransportChannels, (uint16_t) hIvasDec->tsm_max_scaling, hIvasDec->apaExecBuffer, &nTimeScalerOutSamples ) != 0 ) { return IVAS_ERR_UNKNOWN; @@ -879,11 +1130,26 @@ ivas_error IVAS_DEC_GetSamples( assert( nTimeScalerOutSamples <= APA_BUF ); nSamplesTcsScaled = nTimeScalerOutSamples / nTransportChannels; +#else + result = apa_exec( hIvasDec->hTimeScaler, hIvasDec->apaExecBuffer, hIvasDec->nSamplesFrame * nTransportChannels, (uint16_t) hIvasDec->tsm_max_scaling, hIvasDec->apaExecBuffer, &nTimeScalerOutSamples ); + if ( result != 0 ) + { + return IVAS_ERR_UNKNOWN; + } + assert( nTimeScalerOutSamples <= APA_BUF ); +#endif } else { +#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX nSamplesTcsScaled = hIvasDec->nSamplesFrame; +#else + nTimeScalerOutSamples = hIvasDec->nSamplesFrame * nTransportChannels; +#endif } +#ifndef NONBE_UNIFIED_DECODING_PATHS_FIX + nSamplesTcsScaled = nTimeScalerOutSamples / nTransportChannels; +#endif /* Feed decoded transport channels samples to the renderer */ if ( ( error = IVAS_DEC_RendererFeedTcSamples( hIvasDec, nSamplesTcsScaled, &nResidualSamples, hIvasDec->apaExecBuffer ) ) != IVAS_ERR_OK ) @@ -904,7 +1170,11 @@ ivas_error IVAS_DEC_GetSamples( /* render IVAS frames directly to the output buffer */ nSamplesToRender = nSamplesAsked - nSamplesRendered; +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( error = IVAS_DEC_GetRenderedSamples( hIvasDec, nSamplesToRender, &nSamplesRendered_loop, &hIvasDec->nSamplesAvailableNext, pcmType, pcm_buffer_offset( pcmBuf, pcmType, nSamplesRendered * nOutChannels ) ) ) != IVAS_ERR_OK ) +#else if ( ( error = IVAS_DEC_GetRenderedSamples( hIvasDec, nSamplesToRender, &nSamplesRendered_loop, &hIvasDec->nSamplesAvailableNext, pcmBuf + nSamplesRendered * nOutChannels ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -929,6 +1199,189 @@ ivas_error IVAS_DEC_GetSamples( } +#ifdef SPLIT_REND_WITH_HEAD_ROT +/*---------------------------------------------------------------------* + * IVAS_DEC_GetSplitBinauralBitstream( ) + * + * + *---------------------------------------------------------------------*/ + +ivas_error IVAS_DEC_GetSplitBinauralBitstream( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + void *pcmBuf_out, /* o : output synthesis signal for BINAURAL_SPLIT_PCM */ + uint8_t *splitRendBitsBuf, /* o : output split rendering bits */ + int16_t *nOutSamples, /* o : number of samples per channel written to output buffer */ + bool *needNewFrame /* o : indication that the decoder needs a new frame */ +) +{ + Decoder_Struct *st_ivas; + AUDIO_CONFIG output_config; + int32_t output_Fs; + float *writePtr; + float *readPtr, *readEnd; + float *pOutput[BINAURAL_CHANNELS * MAX_HEAD_ROT_POSES]; + float output[BINAURAL_CHANNELS * MAX_HEAD_ROT_POSES][L_FRAME48k]; + float pcmBuf[BINAURAL_CHANNELS * MAX_HEAD_ROT_POSES * L_FRAME48k]; + int16_t numSamplesPerChannelCacheSize; + int16_t numSamplesPerChannelToDecode; + int16_t numSamplesPerChannelToSplitEncode; + int16_t i, j; + ivas_error error; + IVAS_DEC_SPLIT_REND_WRAPPER *hSplitBinRend; + int16_t max_band; + int16_t pcm_out_flag; + int16_t td_input; + int16_t numPoses; + + error = IVAS_ERR_OK; + st_ivas = hIvasDec->st_ivas; + output_config = st_ivas->hDecoderConfig->output_config; + output_Fs = st_ivas->hDecoderConfig->output_Fs; + numSamplesPerChannelToDecode = (int16_t) ( output_Fs / FRAMES_PER_SEC ); + + *needNewFrame = false; + hSplitBinRend = &st_ivas->hSplitBinRend; + + if ( ( error = ivas_set_split_rend_setup( hSplitBinRend, &st_ivas->hRenderConfig->split_rend_config, st_ivas->hCombinedOrientationData, splitRendBitsBuf ) ) != IVAS_ERR_OK ) + { + return error; + } + + numPoses = hSplitBinRend->splitrend.multiBinPoseData.num_poses; + +#ifdef NONBE_UNIFIED_DECODING_PATHS + if ( st_ivas->hDecoderConfig->render_framesize == IVAS_RENDER_FRAMESIZE_5MS && hIvasDec->st_ivas->hRenderConfig->split_rend_config.codec == IVAS_SPLIT_REND_CODEC_LC3PLUS && + ( hIvasDec->st_ivas->hRenderConfig->split_rend_config.poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE || + hIvasDec->st_ivas->hRenderConfig->split_rend_config.dof == 0 ) ) +#else + if ( st_ivas->hDecoderConfig->Opt_5ms && hIvasDec->st_ivas->hRenderConfig->split_rend_config.codec == IVAS_SPLIT_REND_CODEC_LC3PLUS && + ( hIvasDec->st_ivas->hRenderConfig->split_rend_config.poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE || + hIvasDec->st_ivas->hRenderConfig->split_rend_config.dof == 0 ) ) +#endif + { + numSamplesPerChannelToSplitEncode = (int16_t) ( output_Fs / FRAMES_PER_SEC / MAX_PARAM_SPATIAL_SUBFRAMES ); + numSamplesPerChannelCacheSize = numSamplesPerChannelToDecode - numSamplesPerChannelToSplitEncode; + + if ( hSplitBinRend->tdDataOut == NULL ) + { + /* Allocate enough space to save all decoded samples that will not be split encoded directly after decoding */ + if ( ( hSplitBinRend->tdDataOut = malloc( numSamplesPerChannelCacheSize * BINAURAL_CHANNELS * numPoses * sizeof( float ) ) ) == NULL ) + { + return IVAS_ERR_FAILED_ALLOC; + } + } + } + else + { + numSamplesPerChannelToSplitEncode = (int16_t) ( output_Fs / FRAMES_PER_SEC ); + numSamplesPerChannelCacheSize = 0; + } + + if ( output_config != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED && output_config != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { + return IVAS_ERR_WRONG_PARAMS; + } + + if ( numSamplesPerChannelToDecode == numSamplesPerChannelToSplitEncode || hSplitBinRend->numTdSamplesPerChannelCached == 0 ) + { + /* Decode and render */ + if ( ( error = IVAS_DEC_GetSamples( hIvasDec, numSamplesPerChannelToDecode, IVAS_DEC_PCM_FLOAT, pcmBuf, nOutSamples, needNewFrame ) ) != IVAS_ERR_OK ) + { + return error; + } +#ifdef DEBUGGING + assert( numSamplesPerChannelToDecode == *nOutSamples ); +#endif + + /* copy to cache if cache is in use */ + if ( hSplitBinRend->tdDataOut != NULL ) + { + writePtr = hSplitBinRend->tdDataOut; + readPtr = pcmBuf + numSamplesPerChannelToSplitEncode * BINAURAL_CHANNELS * numPoses; + readEnd = pcmBuf + *nOutSamples * BINAURAL_CHANNELS * numPoses; + + while ( readPtr != readEnd ) + { + *writePtr++ = *readPtr++; + } + hSplitBinRend->numTdSamplesPerChannelCached = *nOutSamples - numSamplesPerChannelToSplitEncode; + } + } + else + { + /* copy from cache */ + assert( hSplitBinRend->tdDataOut != NULL ); + + readPtr = hSplitBinRend->tdDataOut + ( numSamplesPerChannelCacheSize - hSplitBinRend->numTdSamplesPerChannelCached ) * BINAURAL_CHANNELS * numPoses; + readEnd = readPtr + numSamplesPerChannelToSplitEncode * BINAURAL_CHANNELS * numPoses; + writePtr = pcmBuf; + + while ( readPtr != readEnd ) + { + *writePtr++ = *readPtr++; + } + hSplitBinRend->numTdSamplesPerChannelCached -= numSamplesPerChannelToSplitEncode; + } + + /* change buffer layout */ + for ( i = 0; i < numSamplesPerChannelToSplitEncode; ++i ) + { + for ( j = 0; j < BINAURAL_CHANNELS * numPoses; ++j ) + { + output[j][i] = pcmBuf[i * BINAURAL_CHANNELS * numPoses + j]; + } + } + for ( i = 0; i < BINAURAL_CHANNELS * MAX_HEAD_ROT_POSES; ++i ) + { + pOutput[i] = output[i]; + } + + max_band = (int16_t) ( ( BINAURAL_MAXBANDS * output_Fs ) / 48000 ); + pcm_out_flag = ( output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0; + td_input = st_ivas->renderer_type != RENDERER_BINAURAL_FASTCONV && st_ivas->renderer_type != RENDERER_BINAURAL_PARAMETRIC && st_ivas->renderer_type != RENDERER_BINAURAL_PARAMETRIC_ROOM && st_ivas->renderer_type != RENDERER_STEREO_PARAMETRIC; + + if ( ( error = ivas_renderMultiBinToSplitBinaural( &hSplitBinRend->splitrend, + st_ivas->hHeadTrackData->Quaternions[0], + st_ivas->hRenderConfig->split_rend_config.splitRendBitRate, + st_ivas->hRenderConfig->split_rend_config.codec, + st_ivas->hRenderConfig->split_rend_config.codec_frame_size_ms, + hSplitBinRend->hSplitRendBits, + hSplitBinRend->hMultiBinCldfbData->Cldfb_RealBuffer_Binaural, + hSplitBinRend->hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural, + max_band, pOutput, 1, !td_input, pcm_out_flag ) ) != IVAS_ERR_OK ) + { + return error; + } + + /* convert to int16 with limiting for BINAURAL_SPLIT_PCM */ + if ( pcm_out_flag ) + { +#ifdef NONBE_UNIFIED_DECODING_PATHS + if ( st_ivas->hDecoderConfig->render_framesize == IVAS_RENDER_FRAMESIZE_5MS ) +#else + if ( st_ivas->hDecoderConfig->Opt_5ms ) +#endif + { +#ifndef DISABLE_LIMITER + ivas_limiter_dec( st_ivas->hLimiter, pOutput, st_ivas->hDecoderConfig->nchan_out, numSamplesPerChannelToSplitEncode, st_ivas->BER_detect ); +#endif + } + else + { + ivas_limiter_dec( st_ivas->hLimiter, pOutput, st_ivas->hDecoderConfig->nchan_out, numSamplesPerChannelToSplitEncode, st_ivas->BER_detect ); + } + +#ifdef DEBUGGING + st_ivas->noClipping += +#endif + ivas_syn_output( pOutput, numSamplesPerChannelToSplitEncode, st_ivas->hDecoderConfig->nchan_out, (int16_t *) pcmBuf_out ); + } + + free( st_ivas->hSplitBinRend.hMultiBinCldfbData ); + + return error; +} +#endif /*---------------------------------------------------------------------* @@ -943,7 +1396,12 @@ static ivas_error IVAS_DEC_Setup( uint8_t *nTransportChannels, /* o : number of decoded transport PCM channels */ uint8_t *nOutChannels, /* o : number of decoded out channels (PCM or CLDFB) */ uint16_t *nSamplesRendered, /* o : number of samples flushed from the last frame */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + const IVAS_DEC_PCM_TYPE pcmType, /* i : type for the decoded PCM resolution */ + void *data /* o : output synthesis signal */ +#else int16_t *data /* o : output synthesis signal */ +#endif ) { ivas_error error; @@ -979,7 +1437,11 @@ static ivas_error IVAS_DEC_Setup( if ( st_ivas->bfi == 0 ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( error = ivas_dec_setup( st_ivas, nSamplesRendered, pcm_type_API_to_internal( pcmType ), data ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_dec_setup( st_ivas, nSamplesRendered, data ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -1085,7 +1547,12 @@ static ivas_error IVAS_DEC_GetRenderedSamples( const uint16_t nSamplesForRendering, /* i : number of TC samples wanted from the renderer */ uint16_t *nSamplesRendered, /* o : number of samples rendered */ uint16_t *nSamplesAvailableNext, /* o : number of samples still available in the renerer pipeline */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + IVAS_DEC_PCM_TYPE pcmType, + void *pcmBuf +#else int16_t *pcmBuf +#endif ) { Decoder_Struct *st_ivas; @@ -1099,7 +1566,11 @@ static ivas_error IVAS_DEC_GetRenderedSamples( st_ivas = hIvasDec->st_ivas; /* run the main IVAS decoding routine */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + error = ivas_jbm_dec_render( st_ivas, nSamplesForRendering, nSamplesRendered, nSamplesAvailableNext, pcm_type_API_to_internal( pcmType ), pcmBuf ); +#else error = ivas_jbm_dec_render( st_ivas, nSamplesForRendering, nSamplesRendered, nSamplesAvailableNext, pcmBuf ); +#endif return error; } @@ -1377,7 +1848,12 @@ ivas_error IVAS_DEC_FeedHeadTrackData( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ IVAS_QUATERNION orientation, /* i : head-tracking data, listener orientation */ IVAS_VECTOR3 Pos, /* i : listener position */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + const int16_t subframe_idx, /* i : subframe index */ + const IVAS_SPLIT_REND_ROT_AXIS rot_axis /* i : external control for rotation axis for split rendering */ +#else const int16_t subframe_idx /* i : subframe index */ +#endif ) { HEAD_TRACK_DATA_HANDLE hHeadTrackData; @@ -1411,7 +1887,12 @@ ivas_error IVAS_DEC_FeedHeadTrackData( hHeadTrackData->Pos[subframe_idx].y = Pos.y; hHeadTrackData->Pos[subframe_idx].z = Pos.z; +#ifdef SPLIT_REND_WITH_HEAD_ROT + hHeadTrackData->sr_pose_pred_axis = rot_axis; +#endif +#ifdef NONBE_UNIFIED_DECODING_PATHS hIvasDec->updateOrientation = true; +#endif return IVAS_ERR_OK; } @@ -1442,7 +1923,9 @@ ivas_error IVAS_DEC_FeedRefRotData( pOtr->refRot.z = rotation.z; pOtr->refRot.y = rotation.y; +#ifdef NONBE_UNIFIED_DECODING_PATHS hIvasDec->updateOrientation = true; +#endif return IVAS_ERR_OK; } @@ -1471,7 +1954,9 @@ ivas_error IVAS_DEC_FeedRefVectorData( pOtr = hIvasDec->st_ivas->hHeadTrackData->OrientationTracker; +#ifdef NONBE_UNIFIED_DECODING_PATHS hIvasDec->updateOrientation = true; +#endif return ivas_orient_trk_SetReferenceVector( pOtr, listenerPos, refPos ); } @@ -1515,7 +2000,9 @@ ivas_error IVAS_DEC_FeedExternalOrientationData( hExternalOrientationData->enableRotationInterpolation[subframe_idx] = enableRotationInterpolation; hExternalOrientationData->numFramesToTargetOrientation[subframe_idx] = numFramesToTargetOrientation; +#ifdef NONBE_UNIFIED_DECODING_PATHS hIvasDec->updateOrientation = true; +#endif return IVAS_ERR_OK; } @@ -1677,15 +2164,39 @@ static ivas_error copyRendererConfigStruct( return IVAS_ERR_UNEXPECTED_NULL_POINTER; } - hRCout->roomAcoustics.override = hRCin->roomAcoustics.override; - hRCout->roomAcoustics.nBands = hRCin->roomAcoustics.nBands; - hRCout->roomAcoustics.acousticPreDelay = hRCin->roomAcoustics.acousticPreDelay; - hRCout->roomAcoustics.inputPreDelay = hRCin->roomAcoustics.inputPreDelay; - - mvr2r( hRCin->roomAcoustics.pFc_input, hRCout->roomAcoustics.pFc_input, CLDFB_NO_CHANNELS_MAX ); +#ifdef DEBUGGING + switch ( hRCin->renderer_type_override ) + { + case IVAS_RENDER_TYPE_OVERRIDE_CREND: + hRCout->renderer_type_override = IVAS_RENDER_TYPE_OVERRIDE_CREND; + break; + case IVAS_RENDER_TYPE_OVERRIDE_FASTCONV: + hRCout->renderer_type_override = IVAS_RENDER_TYPE_OVERRIDE_FASTCONV; + break; + default: + hRCout->renderer_type_override = IVAS_RENDER_TYPE_OVERRIDE_NONE; + break; + } +#endif + hRCout->roomAcoustics.override = hRCin->roomAcoustics.override; + hRCout->roomAcoustics.nBands = hRCin->roomAcoustics.nBands; + hRCout->roomAcoustics.acousticPreDelay = hRCin->roomAcoustics.acousticPreDelay; + hRCout->roomAcoustics.inputPreDelay = hRCin->roomAcoustics.inputPreDelay; + + mvr2r( hRCin->roomAcoustics.pFc_input, hRCout->roomAcoustics.pFc_input, CLDFB_NO_CHANNELS_MAX ); mvr2r( hRCin->roomAcoustics.pAcoustic_rt60, hRCout->roomAcoustics.pAcoustic_rt60, CLDFB_NO_CHANNELS_MAX ); 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 + hRCout->split_rend_config.splitRendBitRate = SPLIT_REND_768k; + hRCout->split_rend_config.dof = 3; + hRCout->split_rend_config.hq_mode = 0; + hRCout->split_rend_config.codec_delay_ms = 0; + hRCout->split_rend_config.codec_frame_size_ms = 0; /* 0 means "use default for selected codec" */ + hRCout->split_rend_config.codec = IVAS_SPLIT_REND_CODEC_DEFAULT; + hRCout->split_rend_config.poseCorrectionMode = IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB; + hRCout->split_rend_config.rendererSelection = hRCin->split_rend_config.rendererSelection; +#endif hRCout->roomAcoustics.use_er = hRCin->roomAcoustics.use_er; hRCout->roomAcoustics.lowComplexity = hRCin->roomAcoustics.lowComplexity; @@ -1742,6 +2253,9 @@ ivas_error IVAS_DEC_FeedRenderConfig( ) { RENDER_CONFIG_HANDLE hRenderConfig; +#ifdef SPLIT_REND_WITH_HEAD_ROT + ivas_error error; +#endif if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || hIvasDec->st_ivas->hRenderConfig == NULL ) { @@ -1749,6 +2263,17 @@ ivas_error IVAS_DEC_FeedRenderConfig( } hRenderConfig = hIvasDec->st_ivas->hRenderConfig; +#ifdef DEBUGGING + hRenderConfig->renderer_type_override = IVAS_RENDER_TYPE_OVERRIDE_NONE; + if ( renderConfig.renderer_type_override == IVAS_RENDER_TYPE_OVERRIDE_FASTCONV ) + { + hRenderConfig->renderer_type_override = IVAS_RENDER_TYPE_OVERRIDE_FASTCONV; + } + if ( renderConfig.renderer_type_override == IVAS_RENDER_TYPE_OVERRIDE_CREND ) + { + hRenderConfig->renderer_type_override = IVAS_RENDER_TYPE_OVERRIDE_CREND; + } +#endif hRenderConfig->roomAcoustics.override = renderConfig.roomAcoustics.override; hRenderConfig->roomAcoustics.nBands = renderConfig.roomAcoustics.nBands; hRenderConfig->roomAcoustics.acousticPreDelay = renderConfig.roomAcoustics.acousticPreDelay; @@ -1771,6 +2296,20 @@ ivas_error IVAS_DEC_FeedRenderConfig( mvr2r( renderConfig.directivity, hRenderConfig->directivity, 3 * MAX_NUM_OBJECTS ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + hRenderConfig->split_rend_config = renderConfig.split_rend_config; + + /* Overwrite any pose correction settings if 0 DOF (no pose correction) was selected */ + if ( hRenderConfig->split_rend_config.dof == 0 ) + { + hRenderConfig->split_rend_config.poseCorrectionMode = IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE; + } + + if ( ( error = ivas_split_rend_validate_config( &hRenderConfig->split_rend_config, ( hIvasDec->st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0 ) ) != IVAS_ERR_OK ) + { + return error; + } +#endif return IVAS_ERR_OK; } @@ -1805,7 +2344,11 @@ ivas_error IVAS_DEC_GetDelay( st_ivas = hIvasDec->st_ivas; hDecoderConfig = st_ivas->hDecoderConfig; +#ifdef SPLIT_REND_WITH_HEAD_ROT + nSamples[1] = NS2SA( hDecoderConfig->output_Fs, get_delay( DEC, hDecoderConfig->output_Fs, st_ivas->ivas_format, st_ivas->cldfbAnaDec[0], hDecoderConfig->output_config ) ); +#else nSamples[1] = NS2SA( hDecoderConfig->output_Fs, get_delay( DEC, hDecoderConfig->output_Fs, st_ivas->ivas_format, st_ivas->cldfbAnaDec[0] ) ); +#endif nSamples[2] = (int16_t) roundf( (float) st_ivas->binaural_latency_ns * hDecoderConfig->output_Fs / 1000000000.f ); nSamples[0] = nSamples[1] + nSamples[2]; @@ -2072,7 +2615,12 @@ ivas_error IVAS_DEC_TSM_SetQuality( ivas_error IVAS_DEC_VoIP_GetSamples( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ uint16_t nSamplesPerChannel, /* i : number of samples per channel requested to be written to output buffer */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + IVAS_DEC_PCM_TYPE pcmType, + void *pcmBuf, +#else int16_t *pcmBuf, /* i/o: buffer for decoded PCM output. The memory must already be allocated and be able to hold the expected number of output samples, based on frame size and number of output channels */ +#endif const uint32_t systemTimestamp_ms /* i : current system timestamp */ #ifdef SUPPORT_JBM_TRACEFILE , @@ -2223,7 +2771,11 @@ ivas_error IVAS_DEC_VoIP_GetSamples( /* codec mode to use not known yet - simply output silence */ /* directly set output zero */ int16_t nSamplesToZero = min( nSamplesPerChannel, hIvasDec->nSamplesAvailableNext ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + set_pcm_buffer_to_zero( pcm_buffer_offset( pcmBuf, pcmType, nSamplesRendered * nOutChannels ), pcmType, nSamplesToZero * nOutChannels ); +#else set_s( pcmBuf + nSamplesRendered * nOutChannels, 0, nSamplesToZero * nOutChannels ); +#endif nSamplesRendered += nSamplesToZero; hIvasDec->nSamplesRendered += nSamplesToZero; hIvasDec->nSamplesAvailableNext -= nSamplesToZero; @@ -2235,7 +2787,11 @@ ivas_error IVAS_DEC_VoIP_GetSamples( nSamplesToRender = nSamplesPerChannel - nSamplesRendered; /* render IVAS frames directly to the output buffer */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( error = IVAS_DEC_GetSamples( hIvasDec, nSamplesToRender, pcmType, pcm_buffer_offset( pcmBuf, pcmType, nSamplesRendered * nOutChannels ), &nSamplesRendered_loop, &tmp ) ) != IVAS_ERR_OK ) +#else if ( ( error = IVAS_DEC_GetSamples( hIvasDec, nSamplesToRender, pcmBuf + nSamplesRendered * nOutChannels, &nSamplesRendered_loop, &tmp ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -2257,7 +2813,12 @@ ivas_error IVAS_DEC_VoIP_GetSamples( ivas_error IVAS_DEC_Flush( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ const int16_t nSamplesPerChannel, /* i : number of samples per channel requested to be written to output buffer */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + const IVAS_DEC_PCM_TYPE pcmType, + void *pcmBuf, +#else int16_t *pcmBuf, /* i/o: buffer for decoded PCM output. The memory must already be allocated and be able to hold the expected number of output samples, based on frame size and number of output channels */ +#endif int16_t *nSamplesFlushed /* o : number of samples flushed */ ) { @@ -2270,7 +2831,11 @@ ivas_error IVAS_DEC_Flush( nSamplesToRender = (uint16_t) *nSamplesFlushed; /* render IVAS frames */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + error = IVAS_DEC_GetRenderedSamples( hIvasDec, nSamplesToRender, &nSamplesFlushedLocal, &hIvasDec->nSamplesAvailableNext, pcmType, pcmBuf ); +#else error = IVAS_DEC_GetRenderedSamples( hIvasDec, nSamplesToRender, &nSamplesFlushedLocal, &hIvasDec->nSamplesAvailableNext, pcmBuf ); +#endif return error; } @@ -2485,6 +3050,16 @@ static ivas_error get_channel_config( { strcpy( str, "Binaural: room with reverb" ); } +#ifdef SPLIT_REND_WITH_HEAD_ROT + else if ( config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) + { + strcpy( str, "BINAURAL_SPLIT_CODED" ); + } + else if ( config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { + strcpy( str, "Binaural_Split_PCM" ); + } +#endif else if ( config == IVAS_AUDIO_CONFIG_EXTERNAL ) { strcpy( str, "External renderer" ); @@ -2512,7 +3087,9 @@ static ivas_error printConfigInfo_dec( { ivas_error error; char config_str[50]; +#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX AUDIO_CONFIG output_config; +#endif /*-----------------------------------------------------------------* * Print info on screen @@ -2612,14 +3189,26 @@ static ivas_error printConfigInfo_dec( } } +#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX output_config = st_ivas->hDecoderConfig->output_config; get_channel_config( output_config, &config_str[0] ); +#else + get_channel_config( st_ivas->hDecoderConfig->output_config, &config_str[0] ); +#endif fprintf( stdout, "Output configuration: %s\n", config_str ); +#ifdef NONBE_UNIFIED_DECODING_PATHS +#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) +#else if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) +#endif +#endif { fprintf( stdout, "Render framesize: %dms\n", get_render_frame_size_ms( st_ivas->hDecoderConfig->render_framesize ) ); } +#endif if ( st_ivas->hDecoderConfig->Opt_HRTF_binary ) { fprintf( stdout, "HRIR/BRIR file: ON\n" ); @@ -2685,6 +3274,16 @@ static ivas_error printConfigInfo_dec( { fprintf( stdout, "TSM mode: ON\n" ); } +#ifndef NONBE_UNIFIED_DECODING_PATHS + /*-----------------------------------------------------------------* + * Print 5ms API mode info + *-----------------------------------------------------------------*/ + + if ( st_ivas->hDecoderConfig->Opt_5ms ) + { + fprintf( stdout, "API 5ms mode: ON\n" ); + } +#endif return IVAS_ERR_OK; } @@ -2707,6 +3306,59 @@ void IVAS_DEC_PrintConfig( } +#ifdef DEBUGGING +#define WMC_TOOL_SKIP +void IVAS_DEC_PrintConfigWithBitstream( + IVAS_DEC_HANDLE hIvasDec, + const bool quietModeEnabled, + uint16_t bit_stream[], + const int16_t num_bits ) +{ + Decoder_Struct *st_ivas; + + /* Create a copy of decoder struct that will be modified by preview_indices(), + * leaving the original decoder struct unchanged. The additional memory used here + * should not be counted towards memory footprint of the decoder. */ + st_ivas = malloc( sizeof( Decoder_Struct ) ); + memcpy( st_ivas, hIvasDec->st_ivas, sizeof( Decoder_Struct ) ); + + preview_indices( st_ivas, bit_stream, num_bits ); + + /* Print config from modified decoder struct */ + printConfigInfo_dec( st_ivas, hIvasDec->bitstreamformat, hIvasDec->Opt_VOIP, quietModeEnabled ); + + free( st_ivas ); + + return; +} + +void IVAS_DEC_PrintConfigWithVoipBitstream( + IVAS_DEC_HANDLE hIvasDec, + const bool quietModeEnabled, + uint8_t *au, + const uint16_t auSizeBits ) +{ + Decoder_Struct *st_ivas; + uint16_t bit_stream[MAX_BITS_PER_FRAME + 4 * 8]; + + /* Create a copy of decoder struct that will be modified by preview_indices(), + * leaving the original decoder struct unchanged. The additional memory used here + * should not be counted towards memory footprint of the decoder. */ + st_ivas = malloc( sizeof( Decoder_Struct ) ); + memcpy( st_ivas, hIvasDec->st_ivas, sizeof( Decoder_Struct ) ); + + bsCompactToSerial( au, bit_stream, auSizeBits ); + preview_indices( st_ivas, bit_stream, auSizeBits ); + + /* Print config from modified decoder struct */ + printConfigInfo_dec( st_ivas, hIvasDec->bitstreamformat, hIvasDec->Opt_VOIP, quietModeEnabled ); + + free( st_ivas ); + + return; +} +#undef WMC_TOOL_SKIP +#endif /*---------------------------------------------------------------------* @@ -2736,6 +3388,9 @@ static ivas_error evs_dec_main( int16_t *pcmBuf ) { DEC_CORE_HANDLE *hCoreCoder; +#ifndef NONBE_UNIFIED_DECODING_PATHS_FIX + float output[MAX_OUTPUT_CHANNELS_IN_DIEGETIC_PAN][L_FRAME48k]; +#endif float mixer_left, mixer_rigth; float *p_output[MAX_OUTPUT_CHANNELS_IN_DIEGETIC_PAN]; int16_t ch; @@ -2748,7 +3403,11 @@ static ivas_error evs_dec_main( for ( ch = 0; ch < MAX_OUTPUT_CHANNELS_IN_DIEGETIC_PAN; ch++ ) { +#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX p_output[ch] = st_ivas->p_output_f[ch]; +#else + p_output[ch] = output[ch]; +#endif } /* run the main EVS decoding routine */ @@ -2756,14 +3415,22 @@ static ivas_error evs_dec_main( { if ( hCoreCoder[0]->Opt_AMR_WB ) { +#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX if ( ( error = amr_wb_dec( hCoreCoder[0], st_ivas->mem_hp20_out[0], p_output[0] ) ) != IVAS_ERR_OK ) +#else + if ( ( error = amr_wb_dec( hCoreCoder[0], st_ivas->mem_hp20_out[0], output[0] ) ) != IVAS_ERR_OK ) +#endif { return error; } } else { +#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX if ( ( error = evs_dec( hCoreCoder[0], st_ivas->mem_hp20_out[0], p_output[0], FRAMEMODE_NORMAL ) ) != IVAS_ERR_OK ) +#else + if ( ( error = evs_dec( hCoreCoder[0], st_ivas->mem_hp20_out[0], output[0], FRAMEMODE_NORMAL ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -2773,21 +3440,33 @@ static ivas_error evs_dec_main( { if ( hCoreCoder[0]->bfi == 0 ) { +#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX if ( ( error = evs_dec( hCoreCoder[0], st_ivas->mem_hp20_out[0], p_output[0], FRAMEMODE_NORMAL ) ) != IVAS_ERR_OK ) +#else + if ( ( error = evs_dec( hCoreCoder[0], st_ivas->mem_hp20_out[0], output[0], FRAMEMODE_NORMAL ) ) != IVAS_ERR_OK ) +#endif { return error; } } else if ( hCoreCoder[0]->bfi == 2 ) { +#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX if ( ( error = evs_dec( hCoreCoder[0], st_ivas->mem_hp20_out[0], p_output[0], FRAMEMODE_FUTURE ) ) != IVAS_ERR_OK ) +#else + if ( ( error = evs_dec( hCoreCoder[0], st_ivas->mem_hp20_out[0], output[0], FRAMEMODE_FUTURE ) ) != IVAS_ERR_OK ) +#endif { return error; } } else { +#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX if ( ( error = evs_dec( hCoreCoder[0], st_ivas->mem_hp20_out[0], p_output[0], FRAMEMODE_MISSING ) ) != IVAS_ERR_OK ) +#else + if ( ( error = evs_dec( hCoreCoder[0], st_ivas->mem_hp20_out[0], output[0], FRAMEMODE_MISSING ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -2800,11 +3479,20 @@ static ivas_error evs_dec_main( { mixer_left = ( st_ivas->hDecoderConfig->non_diegetic_pan_gain + 1.f ) * 0.5f; mixer_rigth = 1.f - mixer_left; +#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX v_multc( p_output[0], mixer_rigth, p_output[1], nOutSamples ); v_multc( p_output[0], mixer_left, p_output[0], nOutSamples ); +#else + v_multc( output[0], mixer_rigth, output[1], nOutSamples ); + v_multc( output[0], mixer_left, output[0], nOutSamples ); +#endif } +#ifndef NONBE_UNIFIED_DECODING_PATHS + if ( !st_ivas->hDecoderConfig->Opt_tsm && st_ivas->hDecoderConfig->Opt_5ms ) +#else if ( !st_ivas->hDecoderConfig->Opt_tsm ) +#endif { ivas_jbm_dec_copy_tc_no_tsm( st_ivas, p_output, nOutSamples ); } @@ -2814,11 +3502,17 @@ static ivas_error evs_dec_main( int16_t pcm_buf_local[L_FRAME48k * MAX_OUTPUT_CHANNELS_IN_DIEGETIC_PAN]; /* convert 'float' output data to 'short' */ +#ifdef DEBUGGING + st_ivas->noClipping += +#endif ivas_syn_output( p_output, nOutSamples, st_ivas->hDecoderConfig->nchan_out, pcm_buf_local ); mvs2r( pcm_buf_local, floatBuf, nOutSamples * st_ivas->hDecoderConfig->nchan_out ); } else { +#ifdef DEBUGGING + st_ivas->noClipping += +#endif ivas_syn_output( p_output, nOutSamples, st_ivas->hDecoderConfig->nchan_out, pcmBuf ); } @@ -2826,6 +3520,157 @@ static ivas_error evs_dec_main( } +#ifdef DEBUGGING +/*---------------------------------------------------------------------* + * IVAS_DEC_GetBer_detect_flag() + * + * return BER_detect flag + *---------------------------------------------------------------------*/ + +bool IVAS_DEC_GetBerDetectFlag( + IVAS_DEC_HANDLE hIvasDec /* i : IVAS decoder handle */ +) +{ + if ( hIvasDec->st_ivas->BER_detect == 1 ) + { + return 1; + } + else + { + return 0; + } +} + + +/*---------------------------------------------------------------------* + * IVAS_DEC_GetNoCLipping() + * + * return number of clipped samples + *---------------------------------------------------------------------*/ + +int32_t IVAS_DEC_GetNoCLipping( + IVAS_DEC_HANDLE hIvasDec /* i : IVAS decoder handle */ +) +{ + return hIvasDec->st_ivas->noClipping; +} + + +/*---------------------------------------------------------------------* + * IVAS_DEC_GetCntFramesLimited() + * + * return number of frames where limiter is applied + *---------------------------------------------------------------------*/ + +int32_t IVAS_DEC_GetCntFramesLimited( + IVAS_DEC_HANDLE hIvasDec /* i : IVAS decoder handle */ +) +{ + if ( hIvasDec->st_ivas->hLimiter == NULL ) + { + return 0; + } + else + { + return hIvasDec->st_ivas->hLimiter->cnt_frames_limited; + } +} + + +/*---------------------------------------------------------------------* + * forcedRendModeApiToInternalDec() + * + * + *---------------------------------------------------------------------*/ + +static ivas_error forcedRendModeApiToInternalDec( + const IVAS_DEC_FORCED_REND_MODE forcedRendMode, + int16_t *forcedModeInternal ) +{ + switch ( forcedRendMode ) + { + case IVAS_DEC_FORCE_REND_TD_RENDERER: + *forcedModeInternal = FORCE_TD_RENDERER; + break; + case IVAS_DEC_FORCE_REND_CLDFB_RENDERER: + *forcedModeInternal = FORCE_CLDFB_RENDERER; + break; + case IVAS_DEC_FORCE_REND_UNFORCED: + *forcedModeInternal = -1; + break; + default: + return IVAS_ERR_INVALID_FORCE_MODE; + break; + } + + return IVAS_ERR_OK; +} + + +/*---------------------------------------------------------------------* + * IVAS_DEC_SetForcedRendMode() + * + * + *---------------------------------------------------------------------*/ + +ivas_error IVAS_DEC_SetForcedRendMode( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + const IVAS_DEC_FORCED_REND_MODE forcedRendMode /* i : forced renderer mode */ +) +{ + int16_t newForcedRend; + ivas_error error; + + if ( ( error = forcedRendModeApiToInternalDec( forcedRendMode, &newForcedRend ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( hIvasDec->st_ivas->hDecoderConfig->force_rend != newForcedRend ) + { + hIvasDec->st_ivas->hDecoderConfig->force_rend = newForcedRend; + } + + return IVAS_ERR_OK; +} + + +#ifdef DEBUG_SBA_AUDIO_DUMP +/*---------------------------------------------------------------------* + * IVAS_DEC_GetSbaDebugParams( ) + * + * Returns SBA debug parameters + *---------------------------------------------------------------------*/ + +ivas_error IVAS_DEC_GetSbaDebugParams( + const IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + int16_t *numOutputChannels, + int16_t *numTransportChannels, + int16_t *pca_ingest_channels ) +{ + if ( hIvasDec->st_ivas == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + if ( hIvasDec->st_ivas->ivas_format != SBA_FORMAT || hIvasDec->st_ivas->hSpar == NULL ) + { + *numOutputChannels = 1; + *numTransportChannels = 1; + *pca_ingest_channels = 1; + } + else + { + *numOutputChannels = hIvasDec->st_ivas->hSpar->numOutChannels; + *numTransportChannels = hIvasDec->st_ivas->nchan_transport; + *pca_ingest_channels = hIvasDec->st_ivas->hSpar->pca_ingest_channels; + } + + return IVAS_ERR_OK; +} +#endif /* DEBUG_SBA_AUDIO_DUMP */ + +#endif /* DEBUGGING */ /*---------------------------------------------------------------------* @@ -2974,5 +3819,182 @@ static ivas_error IVAS_DEC_VoIP_reconfigure( } +#ifdef SPLIT_REND_WITH_HEAD_ROT +/*---------------------------------------------------------------------* + * IVAS_DEC_GetSplitRendBits() + * + * + *---------------------------------------------------------------------*/ + +/*! r: decoder error code */ +ivas_error IVAS_DEC_GetSplitRendBits( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + IVAS_SPLIT_REND_BITS_HANDLE splitRendBits /* o : split rendering Bits structue */ +) +{ + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL /*|| hIvasDec->st_ivas->hSplitBinRend == NULL */ ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + splitRendBits->bits_buf = hIvasDec->st_ivas->hSplitBinRend.hSplitRendBits->bits_buf; + splitRendBits->bits_read = hIvasDec->st_ivas->hSplitBinRend.hSplitRendBits->bits_read; + splitRendBits->bits_written = hIvasDec->st_ivas->hSplitBinRend.hSplitRendBits->bits_written; + splitRendBits->buf_len = hIvasDec->st_ivas->hSplitBinRend.hSplitRendBits->buf_len; + splitRendBits->codec = hIvasDec->st_ivas->hSplitBinRend.hSplitRendBits->codec; + splitRendBits->pose_correction = hIvasDec->st_ivas->hSplitBinRend.hSplitRendBits->pose_correction; + splitRendBits->codec_frame_size_ms = hIvasDec->st_ivas->hSplitBinRend.hSplitRendBits->codec_frame_size_ms; + + return IVAS_ERR_OK; +} +/*---------------------------------------------------------------------* + * IVAS_DEC_GetCldfbSamples() + * + * + *---------------------------------------------------------------------*/ + +// ToDo: currently unused +ivas_error IVAS_DEC_GetCldfbSamples( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + float *out_real, /* o : buffer for decoded PCM real output in CLDFB domain */ + float *out_imag, /* o : buffer for decoded PCM imag output in CLDFB domain */ + AUDIO_CONFIG *audio_config, /* o : audio configuration */ + int16_t *nOutSamples /* o : number of samples per channel written to output buffer */ +) +{ + Decoder_Struct *st_ivas; + int16_t ch, b, slot_idx, num_chs, maxBand, num_samples; + + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + st_ivas = hIvasDec->st_ivas; + num_samples = 0; + + if ( st_ivas->hSplitBinRend.hCldfbDataOut != NULL ) + { + *audio_config = st_ivas->hSplitBinRend.hCldfbDataOut->config; + if ( st_ivas->hSplitBinRend.hCldfbDataOut->config != IVAS_AUDIO_CONFIG_INVALID ) + { + num_chs = audioCfg2channels( st_ivas->hSplitBinRend.hCldfbDataOut->config ); + maxBand = (int16_t) ( ( CLDFB_NO_CHANNELS_MAX * st_ivas->hDecoderConfig->output_Fs ) / 48000 ); + + for ( slot_idx = 0; slot_idx < CLDFB_NO_COL_MAX; slot_idx++ ) + { + for ( b = 0; b < maxBand; b++ ) + { + for ( ch = 0; ch < num_chs; ch++ ) + { + *out_real++ = st_ivas->hSplitBinRend.hCldfbDataOut->Cldfb_RealBuffer[ch][slot_idx][b]; + *out_imag++ = st_ivas->hSplitBinRend.hCldfbDataOut->Cldfb_ImagBuffer[ch][slot_idx][b]; + } + } + } + num_samples = CLDFB_NO_COL_MAX * maxBand; + } + } + else + { + *audio_config = IVAS_AUDIO_CONFIG_INVALID; + } + + *nOutSamples = num_samples; + + return IVAS_ERR_OK; +} +#endif + + +#ifdef SPLIT_REND_WITH_HEAD_ROT +/*---------------------------------------------------------------------* + * pcm_buffer_offset() + * + * + *---------------------------------------------------------------------*/ + +static void *pcm_buffer_offset( + void *buffer, + const IVAS_DEC_PCM_TYPE pcmType, + const int32_t offset ) +{ + switch ( pcmType ) + { + case IVAS_DEC_PCM_FLOAT: + { + float *tmpBuf = (float *) buffer; + return (void *) ( tmpBuf + offset ); + } + break; + case IVAS_DEC_PCM_INT16: + { + int16_t *tmpBuf = (int16_t *) buffer; + return (void *) ( tmpBuf + offset ); + } + break; + default: + return NULL; + } +} + + +/*---------------------------------------------------------------------* + * set_pcm_buffer_to_zero() + * + * + *---------------------------------------------------------------------*/ + +static ivas_error set_pcm_buffer_to_zero( + void *buffer, + const IVAS_DEC_PCM_TYPE pcmType, + const int16_t nZeroSamples ) +{ + ivas_error error; + + switch ( pcmType ) + { + case IVAS_DEC_PCM_FLOAT: + set_zero( (float *) buffer, nZeroSamples ); + break; + case IVAS_DEC_PCM_INT16: + set_s( (int16_t *) buffer, 0, nZeroSamples ); + break; + default: + error = IVAS_ERR_INTERNAL; + } + + return IVAS_ERR_OK; +} + + +/*---------------------------------------------------------------------* + * pcm_type_API_to_internal() + * + * + *---------------------------------------------------------------------*/ + +PCM_RESOLUTION pcm_type_API_to_internal( + const IVAS_DEC_PCM_TYPE pcmType ) +{ + PCM_RESOLUTION pcm_resolution; + pcm_resolution = PCM_NOT_KNOW; + + switch ( pcmType ) + { + case IVAS_DEC_PCM_FLOAT: + pcm_resolution = PCM_FLOAT32; + break; + case IVAS_DEC_PCM_INT16: + pcm_resolution = PCM_INT16; + break; + default: + pcm_resolution = PCM_NOT_KNOW; + } + + return pcm_resolution; +} + +#endif diff --git a/lib_dec/lib_dec.h b/lib_dec/lib_dec.h index ad4efa505..bccc190f9 100644 --- a/lib_dec/lib_dec.h +++ b/lib_dec/lib_dec.h @@ -64,7 +64,24 @@ typedef enum _IVAS_DEC_COMPLEXITY_LEVEL } IVAS_DEC_COMPLEXITY_LEVEL; +#ifdef DEBUGGING +typedef enum _IVAS_DEC_FORCED_REND_MODE +{ + IVAS_DEC_FORCE_REND_CLDFB_RENDERER, + IVAS_DEC_FORCE_REND_TD_RENDERER, + IVAS_DEC_FORCE_REND_UNFORCED, + IVAS_DEC_FORCE_REND_UNDEFINED = 0xffff +} IVAS_DEC_FORCED_REND_MODE; +#endif +#ifdef SPLIT_REND_WITH_HEAD_ROT +typedef enum _IVAS_DEC_PCM_TYPE +{ + IVAS_DEC_PCM_INT16, + IVAS_DEC_PCM_FLOAT, + IVAS_DEC_PCM_INVALID +} IVAS_DEC_PCM_TYPE; +#endif /* bitstream formats that can be consumed */ @@ -108,7 +125,11 @@ ivas_error IVAS_DEC_Configure( const uint32_t sampleRate, /* i : output sampling frequency */ const IVAS_AUDIO_CONFIG outputConfig, /* i : audio configuration */ const int16_t tsmEnabled, /* i : enable TSM */ +#ifndef NONBE_UNIFIED_DECODING_PATHS + const int16_t enable5ms, /* i : enable 5ms rendering path */ +#else const IVAS_RENDER_FRAMESIZE renderFramesize, /* i : rendering frame size */ +#endif const int16_t customLsOutputEnabled, /* i : enable custom loudspeaker setup handle */ const int16_t hrtfReaderEnabled, /* i : enable HRTF binary file input */ const int16_t enableHeadRotation, /* i : enable head rotation for binaural output */ @@ -141,11 +162,40 @@ ivas_error IVAS_DEC_FeedFrame_Serial( ivas_error IVAS_DEC_GetSamples( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ const int16_t nSamplesAsked, /* i : number of samples wanted by the caller */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + const IVAS_DEC_PCM_TYPE pcmType, /* i : type for the decoded PCM resolution */ + void *pcmBuf, /* o : output synthesis signal */ +#else int16_t *pcmBuf, /* i/o: buffer for decoded PCM output. The memory must already be allocated and be able to hold the expected number of output samples, based on frame size and number of output channels */ +#endif + int16_t *nOutSamples, /* o : number of samples per channel written to output buffer */ + bool *needNewFrame /* o : indication that the decoder needs a new frame */ +); + +#ifdef SPLIT_REND_WITH_HEAD_ROT +ivas_error IVAS_DEC_GetSplitBinauralBitstream( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + void *pcmBuf_out, /* o : output synthesis signal for BINAURAL_SPLIT_PCM */ + uint8_t *splitRendBitsBuf, /* o : output split rendering bits */ int16_t *nOutSamples, /* o : number of samples per channel written to output buffer */ bool *needNewFrame /* o : indication that the decoder needs a new frame */ ); +/*! r: decoder error code */ +ivas_error IVAS_DEC_GetSplitRendBits( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + IVAS_SPLIT_REND_BITS_HANDLE splitRendBits /* o : split rendering Bits structure */ +); + +/*! r: decoder error code */ +ivas_error IVAS_DEC_GetCldfbSamples( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + float *out_real, /* o : buffer for decoded PCM real output in CLDFB domain */ + float *out_imag, /* o : buffer for decoded PCM imag output in CLDFB domain */ + IVAS_AUDIO_CONFIG *audio_config, /* o : audio configuration */ + int16_t *nOutSamples /* o : number of samples per channel written to output buffer */ +); +#endif /*! r: error code */ ivas_error IVAS_DEC_GetObjectMetadata( @@ -167,7 +217,12 @@ ivas_error IVAS_DEC_FeedHeadTrackData( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ IVAS_QUATERNION orientation, /* i : head-tracking data, listener orientation */ IVAS_VECTOR3 Pos, /* i : listener position */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + const int16_t subframe_idx, /* i : subframe index */ + IVAS_SPLIT_REND_ROT_AXIS rot_axis /* i : external control for rotation axis for split rendering */ +#else const int16_t subframe_idx /* i : subframe index */ +#endif ); /*! r: error code */ @@ -220,7 +275,12 @@ ivas_error IVAS_DEC_TSM_SetQuality( ivas_error IVAS_DEC_VoIP_GetSamples( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ uint16_t nSamplesPerChannel, /* i : number of samples per channel requested to be written to output buffer */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + IVAS_DEC_PCM_TYPE pcmType, + void *pcmBuf, +#else int16_t *pcmBuf, /* i/o: buffer for decoded PCM output. The memory must already be allocated and be able to hold the expected number of output samples, based on frame size and number of output channels */ +#endif const uint32_t systemTimestamp_ms /* i : current system timestamp */ #ifdef SUPPORT_JBM_TRACEFILE , JbmTraceFileWriterFn jbmWriterFn, @@ -231,7 +291,12 @@ ivas_error IVAS_DEC_VoIP_GetSamples( ivas_error IVAS_DEC_Flush( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ const int16_t nSamplesPerChannel, /* i : number of samples per channel requested to be written to output buffer */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + const IVAS_DEC_PCM_TYPE pcmType, + void *pcmBuf, +#else int16_t *pcmBuf, /* i/o: buffer for decoded PCM output. The memory must already be allocated and be able to hold the expected number of output samples, based on frame size and number of output channels */ +#endif int16_t *nSamplesFlushed /* o : number of samples flushed */ ); @@ -244,7 +309,24 @@ ivas_error IVAS_DEC_EnableVoIP( const IVAS_DEC_INPUT_FORMAT inputFormat /* i : format of the input bitstream */ ); +#ifdef SPLIT_REND_WITH_HEAD_ROT +/*! r: error code */ +ivas_error IVAS_DEC_EnableSplitRendering( + IVAS_DEC_HANDLE hIvasDec /* i/o: IVAS decoder handle */ +); +#endif + +#ifndef NONBE_UNIFIED_DECODING_PATHS +ivas_error IVAS_DEC_Set5msFlag( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + const int16_t enable5ms /* i : 5ms flag */ +); +ivas_error IVAS_DEC_Get5msFlag( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + int16_t *enable5ms /* o : 5ms flag */ +); +#else ivas_error IVAS_DEC_SetRenderFramesize( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ const IVAS_RENDER_FRAMESIZE render_framesize /* i : render framesize */ @@ -274,7 +356,36 @@ ivas_error IVAS_DEC_GetRenderFramesizeMs( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ uint32_t *render_framesize /* o : render framesize in samples */ ); +#endif + +#ifdef DEBUGGING +bool IVAS_DEC_GetBerDetectFlag( + IVAS_DEC_HANDLE hIvasDec /* i : IVAS decoder handle */ +); + +int32_t IVAS_DEC_GetNoCLipping( + IVAS_DEC_HANDLE hIvasDec /* i : IVAS decoder handle */ +); + +int32_t IVAS_DEC_GetCntFramesLimited( + IVAS_DEC_HANDLE hIvasDec /* i : IVAS decoder handle */ +); +/*! r: error code */ +ivas_error IVAS_DEC_SetForcedRendMode( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + const IVAS_DEC_FORCED_REND_MODE forcedRendMode /* i : forced renderer mode */ +); + +#ifdef DEBUG_SBA_AUDIO_DUMP +ivas_error IVAS_DEC_GetSbaDebugParams( + const IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + int16_t *numOutputChannels, + int16_t *numTransportChannels, + int16_t *pca_ingest_channels +); +#endif +#endif /* Getter functions - retrieve information from a decoder through a handle */ @@ -399,6 +510,21 @@ void IVAS_DEC_PrintConfig( const bool voipMode ); +#ifdef DEBUGGING +void IVAS_DEC_PrintConfigWithBitstream( + IVAS_DEC_HANDLE hIvasDec, /* i : IVAS decoder handle */ + const bool quietModeEnabled, /* i : quiet mode flag: if true, reduces the amount of config info printed */ + uint16_t bit_stream[], /* i : bitstream buffer */ + const int16_t num_bits /* i : number of bits in bitstream */ +); + +void IVAS_DEC_PrintConfigWithVoipBitstream( + IVAS_DEC_HANDLE hIvasDec, /* i : IVAS decoder handle */ + const bool quietModeEnabled, /* i : quiet mode flag: if true, reduces the amount of config info printed */ + uint8_t *au, /* i : buffer containing input access unit */ + const uint16_t auSizeBits /* i : size of the access unit in bits */ +); +#endif void IVAS_DEC_PrintDisclaimer( void diff --git a/lib_dec/lp_exc_d.c b/lib_dec/lp_exc_d.c index 65457e630..c436edcf1 100644 --- a/lib_dec/lp_exc_d.c +++ b/lib_dec/lp_exc_d.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "prot.h" #include "wmc_auto.h" diff --git a/lib_dec/lsf_dec.c b/lib_dec/lsf_dec.c index 4e5871fea..119cf7ecf 100644 --- a/lib_dec/lsf_dec.c +++ b/lib_dec/lsf_dec.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "rom_com.h" #include "prot.h" diff --git a/lib_dec/lsf_msvq_ma_dec.c b/lib_dec/lsf_msvq_ma_dec.c index 945797915..9c911ab5f 100644 --- a/lib_dec/lsf_msvq_ma_dec.c +++ b/lib_dec/lsf_msvq_ma_dec.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "prot.h" #include "rom_com.h" diff --git a/lib_dec/nelp_dec.c b/lib_dec/nelp_dec.c index 77b3703d1..67d8fb5f8 100644 --- a/lib_dec/nelp_dec.c +++ b/lib_dec/nelp_dec.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "prot.h" diff --git a/lib_dec/peak_vq_dec.c b/lib_dec/peak_vq_dec.c index 857bf0d5f..21c8014f8 100644 --- a/lib_dec/peak_vq_dec.c +++ b/lib_dec/peak_vq_dec.c @@ -37,6 +37,9 @@ #include #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "prot.h" diff --git a/lib_dec/pit_dec.c b/lib_dec/pit_dec.c index 2f19d7079..c569e6609 100644 --- a/lib_dec/pit_dec.c +++ b/lib_dec/pit_dec.c @@ -40,6 +40,9 @@ #include "cnst.h" #include "prot.h" #include "rom_com.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" /*----------------------------------------------------------* diff --git a/lib_dec/pitch_extr.c b/lib_dec/pitch_extr.c index 209370d2f..a0370946b 100644 --- a/lib_dec/pitch_extr.c +++ b/lib_dec/pitch_extr.c @@ -38,6 +38,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "prot.h" diff --git a/lib_dec/post_dec.c b/lib_dec/post_dec.c index f661992ac..5bc31d56e 100644 --- a/lib_dec/post_dec.c +++ b/lib_dec/post_dec.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "prot.h" #include "rom_com.h" diff --git a/lib_dec/pvq_core_dec.c b/lib_dec/pvq_core_dec.c index 677b80f5c..115d53ac5 100644 --- a/lib_dec/pvq_core_dec.c +++ b/lib_dec/pvq_core_dec.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "rom_com.h" diff --git a/lib_dec/pvq_decode.c b/lib_dec/pvq_decode.c index b161d12aa..a0da5f09e 100644 --- a/lib_dec/pvq_decode.c +++ b/lib_dec/pvq_decode.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "prot.h" #include "rom_com.h" diff --git a/lib_dec/range_dec.c b/lib_dec/range_dec.c index 87589a840..25cfdb215 100644 --- a/lib_dec/range_dec.c +++ b/lib_dec/range_dec.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "rom_com.h" #include "prot.h" diff --git a/lib_dec/re8_dec.c b/lib_dec/re8_dec.c index a48e6471a..d9a7c750d 100644 --- a/lib_dec/re8_dec.c +++ b/lib_dec/re8_dec.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "prot.h" #include "wmc_auto.h" diff --git a/lib_dec/rom_dec.c b/lib_dec/rom_dec.c index 11661592f..e0ae59e58 100644 --- a/lib_dec/rom_dec.c +++ b/lib_dec/rom_dec.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "wmc_auto.h" diff --git a/lib_dec/rom_dec.h b/lib_dec/rom_dec.h index bbf6759bd..5930eda56 100644 --- a/lib_dec/rom_dec.h +++ b/lib_dec/rom_dec.h @@ -39,6 +39,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" extern const float h_low[]; /* LP filter for filtering periodic part of excitation in artificial onset construction after FEC */ diff --git a/lib_dec/rst_dec.c b/lib_dec/rst_dec.c index 00bc9298d..f3fbd3216 100644 --- a/lib_dec/rst_dec.c +++ b/lib_dec/rst_dec.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "rom_com.h" diff --git a/lib_dec/stat_dec.h b/lib_dec/stat_dec.h index 822b593c5..d83b77ab4 100644 --- a/lib_dec/stat_dec.h +++ b/lib_dec/stat_dec.h @@ -42,6 +42,9 @@ #include "cnst.h" #include "stat_com.h" /* Common structures */ #include "ivas_cnst.h" +#ifdef DEBUGGING +#include "debug.h" +#endif /*---------------------------------------------------------------* * Structure for FD Mode2 frameMode @@ -895,6 +898,9 @@ typedef struct Decoder_State int16_t idchan; /* channel ID (audio channel number) */ int16_t element_mode; /* element mode */ +#ifdef DEBUGGING + int16_t id_element; /* element ID */ +#endif int32_t element_brate; /* element bitrate */ int16_t codec_mode; /* Mode 1 or 2 */ int16_t mdct_sw_enable; /* MDCT switching enable flag */ diff --git a/lib_dec/stat_noise_uv_dec.c b/lib_dec/stat_noise_uv_dec.c index 0c024aaac..2fa711814 100644 --- a/lib_dec/stat_noise_uv_dec.c +++ b/lib_dec/stat_noise_uv_dec.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "prot.h" #include "wmc_auto.h" diff --git a/lib_dec/swb_bwe_dec.c b/lib_dec/swb_bwe_dec.c index 23c59cf5c..a89a17cca 100644 --- a/lib_dec/swb_bwe_dec.c +++ b/lib_dec/swb_bwe_dec.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "prot.h" diff --git a/lib_dec/swb_bwe_dec_hr.c b/lib_dec/swb_bwe_dec_hr.c index 065a24c6b..1c4d5c7f6 100644 --- a/lib_dec/swb_bwe_dec_hr.c +++ b/lib_dec/swb_bwe_dec_hr.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "prot.h" #include "rom_com.h" diff --git a/lib_dec/swb_bwe_dec_lr.c b/lib_dec/swb_bwe_dec_lr.c index 7953ee5d9..c0ccb648c 100644 --- a/lib_dec/swb_bwe_dec_lr.c +++ b/lib_dec/swb_bwe_dec_lr.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "prot.h" diff --git a/lib_dec/swb_tbe_dec.c b/lib_dec/swb_tbe_dec.c index c858a80af..e4f211b2a 100644 --- a/lib_dec/swb_tbe_dec.c +++ b/lib_dec/swb_tbe_dec.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "prot.h" diff --git a/lib_dec/syn_outp.c b/lib_dec/syn_outp.c index aebcc9b04..c28666d1e 100644 --- a/lib_dec/syn_outp.c +++ b/lib_dec/syn_outp.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "prot.h" diff --git a/lib_dec/tcq_core_dec.c b/lib_dec/tcq_core_dec.c index c9dcb27d1..8b0a6f2d4 100644 --- a/lib_dec/tcq_core_dec.c +++ b/lib_dec/tcq_core_dec.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "rom_com.h" #include "prot.h" diff --git a/lib_dec/tcx_utils_dec.c b/lib_dec/tcx_utils_dec.c index e2dc05a8a..5db8a20b0 100644 --- a/lib_dec/tcx_utils_dec.c +++ b/lib_dec/tcx_utils_dec.c @@ -37,6 +37,9 @@ #include #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "prot.h" #include "rom_com.h" diff --git a/lib_dec/tonalMDCTconcealment.c b/lib_dec/tonalMDCTconcealment.c index 56bae2137..ce77ecb97 100644 --- a/lib_dec/tonalMDCTconcealment.c +++ b/lib_dec/tonalMDCTconcealment.c @@ -39,6 +39,9 @@ #include #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "prot.h" #include "ivas_prot.h" diff --git a/lib_dec/transition_dec.c b/lib_dec/transition_dec.c index a7fa472b5..05c7887f4 100644 --- a/lib_dec/transition_dec.c +++ b/lib_dec/transition_dec.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "rom_com.h" diff --git a/lib_dec/updt_dec.c b/lib_dec/updt_dec.c index 9ee8093ff..7ff9c9ee0 100644 --- a/lib_dec/updt_dec.c +++ b/lib_dec/updt_dec.c @@ -37,6 +37,9 @@ #include #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "prot.h" #include "rom_com.h" #include "cnst.h" diff --git a/lib_dec/waveadjust_fec_dec.c b/lib_dec/waveadjust_fec_dec.c index dce0e221d..99a10e886 100644 --- a/lib_dec/waveadjust_fec_dec.c +++ b/lib_dec/waveadjust_fec_dec.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "prot.h" #include "wmc_auto.h" diff --git a/lib_enc/ACcontextMapping_enc.c b/lib_enc/ACcontextMapping_enc.c index ff345d69e..a608db5ea 100644 --- a/lib_enc/ACcontextMapping_enc.c +++ b/lib_enc/ACcontextMapping_enc.c @@ -43,6 +43,9 @@ #include "ivas_prot.h" /* Range coder header file */ #include "ivas_rom_com.h" #include "ivas_rom_enc.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" @@ -362,6 +365,9 @@ void ACcontextMapping_encode2_no_mem_s17_LC( /* Push the rest of the buffer */ push_next_bits( hBstr, (uint16_t *) &ptr[bp], nbbits - bp ); +#ifdef DEBUGGING + /* return (bp+nbbits_lsbs);*/ /*return only for debug plot*/ +#endif return; } @@ -821,6 +827,9 @@ void RCcontextMapping_encode2_no_mem_s17_LCS( rc_uni_enc_encode_symbol_fastS( &rc_st_enc, a1 + A_THRES * b1, cum_freq_ari_pk_s17_LC_ext[pki], sym_freq_ari_pk_s17_LC_ext[pki], 14 ); /* Encode MSB symbol */ /*Confirm that there is no overflow, i.e. bit-budget has not exceeded */ +#ifdef DEBUGGING + assert( rc_uni_enc_virtual_finish( &rc_st_enc ) <= nbbits - nbbits_signs - nbbits_lsbs - nbbits_ntuples ); +#endif /* Update context for next 2-tuple */ if ( p1 == p2 ) @@ -939,6 +948,9 @@ void RCcontextMapping_encode2_no_mem_s17_LCS( rc_uni_enc_encode_symbol_fastS( &rc_st_enc, a1 + A_THRES * b1, cum_freq_ari_pk_s17_LC_ext[pki], sym_freq_ari_pk_s17_LC_ext[pki], 14 ); /* Encode MSB symbol */ /*Confirm that there is no overflow, i.e. bit-budget has not exceeded */ +#ifdef DEBUGGING + assert( rc_uni_enc_virtual_finish( &rc_st_enc ) <= nbbits - nbbits_signs - nbbits_lsbs - nbbits_ntuples ); +#endif /* Update context for next 2-tuple */ if ( esc_nb < 2 ) @@ -962,6 +974,9 @@ void RCcontextMapping_encode2_no_mem_s17_LCS( bp = rc_tot_bits + nbbits_ntuples; /* Update bitstream pointer */ /* Cross-check that there is no overflow */ +#ifdef DEBUGGING + assert( k == lastnz ); +#endif /* Push number of encoded tuples */ value = ( lastnz >> 1 ) - 1; diff --git a/lib_enc/FEC_enc.c b/lib_enc/FEC_enc.c index 30f35f37a..9b753c97b 100644 --- a/lib_enc/FEC_enc.c +++ b/lib_enc/FEC_enc.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "prot.h" diff --git a/lib_enc/acelp_core_enc.c b/lib_enc/acelp_core_enc.c index 7162bdeea..ca7dec18a 100644 --- a/lib_enc/acelp_core_enc.c +++ b/lib_enc/acelp_core_enc.c @@ -36,6 +36,10 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#include "string.h" +#endif #include #include "cnst.h" #include "rom_enc.h" @@ -317,6 +321,9 @@ ivas_error acelp_core_enc( } } +#ifdef DEBUG_MODE_ACELP + dbgwrite( exc, sizeof( float ), st->L_frame, 1, "res/exc.enc" ); +#endif /* Reset HO counter in the first SID frame */ if ( st->hTdCngEnc != NULL ) { @@ -567,7 +574,39 @@ ivas_error acelp_core_enc( encod_gen_voic( st, inp, Aw, Aq, Es_pred, res, syn, exc, exc2, pitch_buf, voice_factors, bwe_exc, unbits, tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf ); } +#ifdef DEBUG_MODE_ACELP + dbgwrite( exc, sizeof( float ), st->L_frame, 1, fname( debug_dir, "exc.enc", st->idchan, st->id_element, ENC ) ); + dbgwrite( res, sizeof( float ), st->L_frame, 1, fname( debug_dir, "resid", st->idchan, st->id_element, ENC ) ); +#endif +#ifdef DEBUGGING + /* SNR measuremenet of CELP output */ + if ( ppp_mode == 0 ) + { + char name[50] = "CELP_output_ch "; + + if ( st->id_element == 0 ) + { + name[14] = (char) ( st->idchan + '0' ); + } + else + { + char name2[50] = "CELP_output.idX_chX "; + name2[14] = (char) ( st->id_element + '0' ); + name2[18] = (char) ( st->idchan + '0' ); + strcpy( name, name2 ); + } + + if ( st->idchan == 0 ) + { + snr_celp( st->L_frame, L_SUBFR, st->gamma, st->preemph_fac, st->vad_flag, st->coder_type, inp, syn, A, 0, name ); + } + else if ( st->idchan == 1 ) + { + snr_celp( st->L_frame, L_SUBFR, st->gamma, st->preemph_fac, st->vad_flag, st->coder_type, inp, syn, A, 1, name ); + } + } +#endif /* update mem_syn1 for ACELP core switching */ mvr2r( hLPDmem->mem_syn, hLPDmem->mem_syn1, M ); @@ -636,6 +675,12 @@ ivas_error acelp_core_enc( i = min( nBits, 16 ); push_indice( hBstr, IND_UNUSED, 0, i ); nBits -= i; +#ifdef DEBUGGING + if ( st->idchan == 1 && st->element_mode == IVAS_CPE_TD ) + { + printf( "Issue with unused bits at Ln 653 in acelp_core_enc channel 1 at frame %d\n", frame ); + } +#endif } } diff --git a/lib_enc/acelp_core_switch_enc.c b/lib_enc/acelp_core_switch_enc.c index b02f9a62c..0d65ed608 100644 --- a/lib_enc/acelp_core_switch_enc.c +++ b/lib_enc/acelp_core_switch_enc.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "rom_enc.h" @@ -120,11 +123,32 @@ void acelp_core_switch_enc( } } +#ifdef FIX_I4_OL_PITCH + if ( st->last_codec_mode == MODE1 ) + { + /* in MODE1 T_op is at 12.8 kHz */ + if ( st->last_L_frame != L_FRAME ) /* ACELP@16k core -> convert T_op to 16 kHz */ + { + T_op[0] = (short) ( 1.25f * T_op[0] + 0.5f ); + T_op[1] = (short) ( 1.25f * T_op[1] + 0.5f ); + } + } + else + { + /* in MODE2 T_op is at 16 kHz */ + if ( st->last_L_frame == L_FRAME ) /* ACELP@12.8k core -> convert T_op to 12.8 kHz */ + { + T_op[0] = (short) ( 0.8f * T_op[0] + 0.5f ); + T_op[1] = (short) ( 0.8f * T_op[1] + 0.5f ); + } + } +#else if ( st->last_L_frame != L_FRAME ) /* ACELP@16k core */ { T_op[0] = (short) ( 1.25f * T_op[0] + 0.5f ); T_op[1] = (short) ( 1.25f * T_op[1] + 0.5f ); } +#endif /*----------------------------------------------------------------* * Excitation encoding *----------------------------------------------------------------*/ @@ -138,6 +162,9 @@ void acelp_core_switch_enc( *----------------------------------------------------------------*/ i = find_indice( hBstr, TAG_ACELP_SUBFR_LOOP_START, &value, &nb_bits ); +#ifdef DEBUGGING + assert( i >= 0 && "Internal error in ACELP core switching - unable to find ACELP subframe indices!" ); +#endif while ( hBstr->ind_list[i].id == TAG_ACELP_SUBFR_LOOP_START ) { push_indice( hBstr, IND_CORE_SWITCHING_CELP_SUBFRAME, hBstr->ind_list[i].value, hBstr->ind_list[i].nb_bits ); diff --git a/lib_enc/acelp_enc_util.c b/lib_enc/acelp_enc_util.c index 3cead2ee7..fdbc3a8b0 100644 --- a/lib_enc/acelp_enc_util.c +++ b/lib_enc/acelp_enc_util.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "prot.h" #include "cnst.h" #include "rom_com.h" diff --git a/lib_enc/amr_wb_enc.c b/lib_enc/amr_wb_enc.c index b133d9413..e921698e5 100644 --- a/lib_enc/amr_wb_enc.c +++ b/lib_enc/amr_wb_enc.c @@ -36,12 +36,18 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "rom_enc.h" #include "rom_com.h" #include "prot.h" #include "wmc_auto.h" +#ifdef DEBUG_MODE_INFO +extern float snr_[2][320]; +#endif /*-------------------------------------------------------------------* * amr_wb_enc() @@ -119,6 +125,9 @@ void amr_wb_enc( st->encoderPastSamples_enc = ( L_FRAME * 9 ) / 16; st->encoderLookahead_enc = L_LOOK_12k8; +#ifdef DEBUG_MODE_INFO + set_f( snr_[0], 0.0f, 320 ); +#endif st->bpf_off = 0; if ( st->last_core == HQ_CORE || st->last_codec_mode == MODE2 ) @@ -469,6 +478,10 @@ void amr_wb_enc( encod_amr_wb( st, inp, Aw, Aq, res, syn, exc, exc2, pitch_buf, hf_gain, inp_16k ); +#ifdef DEBUGGING + /* SNR measuremenet of CELP coded output */ + snr_celp( L_FRAME, L_SUBFR, GAMMA1, TILT_FAC, ( st->vad_flag | vad_flag_dtx ), st->coder_type, inp, syn, A, 0, "CELP_output" ); +#endif /* update mem_syn1 for ACELP core switching */ mvr2r( hLPDmem->mem_syn, hLPDmem->mem_syn1, M ); @@ -519,6 +532,21 @@ void amr_wb_enc( updt_enc_common( st ); +#ifdef DEBUG_MODE_INFO + dbgwrite( &st->codec_mode, sizeof( int16_t ), 1, input_frame, "res/codec" ); + dbgwrite( &st->core, sizeof( int16_t ), 1, input_frame, "res/core" ); + dbgwrite( &st->extl, sizeof( int16_t ), 1, input_frame, "res/extl" ); + dbgwrite( &st->bwidth, sizeof( int16_t ), 1, input_frame, "res/bwidth" ); + ener = st->total_brate / 1000.0f; + dbgwrite( &ener, sizeof( float ), 1, input_frame, "res/total_brate" ); + ener = st->core_brate / 1000.0f; + dbgwrite( &ener, sizeof( float ), 1, input_frame, "res/core_brate" ); + dbgwrite( &st->coder_type, sizeof( int16_t ), 1, input_frame, "res/coder_type" ); + dbgwrite( &st->cng_type, sizeof( int16_t ), 1, input_frame, "res/cng_type" ); + dbgwrite( &st->L_frame, sizeof( int16_t ), 1, input_frame, "res/L_frame" ); + dbgwrite( &st->vad_flag, sizeof( int16_t ), 1, input_frame, "res/vad_flag" ); + dbgwrite( snr_[0], sizeof( float ), 320, 1, "res/snr" ); +#endif return; } diff --git a/lib_enc/analy_lp.c b/lib_enc/analy_lp.c index 536d1e13a..c0541e78f 100644 --- a/lib_enc/analy_lp.c +++ b/lib_enc/analy_lp.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "rom_com.h" #include "prot.h" diff --git a/lib_enc/analy_sp.c b/lib_enc/analy_sp.c index c03ec0c90..4a4bcb357 100644 --- a/lib_enc/analy_sp.c +++ b/lib_enc/analy_sp.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "rom_enc.h" diff --git a/lib_enc/ari_enc.c b/lib_enc/ari_enc.c index b2e692bc1..405b3a899 100644 --- a/lib_enc/ari_enc.c +++ b/lib_enc/ari_enc.c @@ -41,6 +41,9 @@ #include "prot.h" #include "stat_com.h" #include "basop_util.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" diff --git a/lib_enc/arith_coder_enc.c b/lib_enc/arith_coder_enc.c index d4b473549..546e7f07a 100644 --- a/lib_enc/arith_coder_enc.c +++ b/lib_enc/arith_coder_enc.c @@ -37,6 +37,9 @@ #include #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "prot.h" diff --git a/lib_enc/avq_cod.c b/lib_enc/avq_cod.c index f76b4a353..78900b554 100644 --- a/lib_enc/avq_cod.c +++ b/lib_enc/avq_cod.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "prot.h" #include "rom_com.h" diff --git a/lib_enc/bass_psfilter_enc.c b/lib_enc/bass_psfilter_enc.c index dbfb38224..582ed3f22 100644 --- a/lib_enc/bass_psfilter_enc.c +++ b/lib_enc/bass_psfilter_enc.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "prot.h" #include "rom_com.h" diff --git a/lib_enc/bw_detect.c b/lib_enc/bw_detect.c index 94e26fbf5..121754e1d 100644 --- a/lib_enc/bw_detect.c +++ b/lib_enc/bw_detect.c @@ -37,6 +37,9 @@ #include #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "rom_enc.h" diff --git a/lib_enc/cng_enc.c b/lib_enc/cng_enc.c index de5c00b71..d99e05395 100644 --- a/lib_enc/cng_enc.c +++ b/lib_enc/cng_enc.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "rom_enc.h" diff --git a/lib_enc/cod2t32.c b/lib_enc/cod2t32.c index 38d062853..0d5e548be 100644 --- a/lib_enc/cod2t32.c +++ b/lib_enc/cod2t32.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "prot.h" #include "wmc_auto.h" diff --git a/lib_enc/cod4t64.c b/lib_enc/cod4t64.c index 8d851c47d..79d1814f5 100644 --- a/lib_enc/cod4t64.c +++ b/lib_enc/cod4t64.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "rom_enc.h" diff --git a/lib_enc/cod4t64_fast.c b/lib_enc/cod4t64_fast.c index 7594f23e4..9c16758d4 100644 --- a/lib_enc/cod4t64_fast.c +++ b/lib_enc/cod4t64_fast.c @@ -32,6 +32,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "prot.h" diff --git a/lib_enc/cod_ace.c b/lib_enc/cod_ace.c index 75058cfdd..7a5c605d9 100644 --- a/lib_enc/cod_ace.c +++ b/lib_enc/cod_ace.c @@ -38,6 +38,9 @@ #include "prot.h" #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "rom_com.h" #include "wmc_auto.h" @@ -391,6 +394,17 @@ void coder_acelp( p_A -= ( M + 1 ); p_Aq -= ( M + 1 ); +#ifdef DEBUGGING + /* SNR measuremenet of CELP output */ + if ( st->idchan == 0 ) + { + snr_celp( st->L_frame, L_SUBFR, st->gamma, st->preemph_fac, st->vad_flag, st->coder_type, speech, syn, A, 0, "CELP_output" ); + } + else + { + snr_celp( st->L_frame, L_SUBFR, st->gamma, st->preemph_fac, st->vad_flag, st->coder_type, speech, syn, A, 1, "CELP_output_chan2" ); + } +#endif /*----------------------------------------------------------* * Update LPD memory * diff --git a/lib_enc/cod_tcx.c b/lib_enc/cod_tcx.c index 0577aafef..9e4b601a5 100644 --- a/lib_enc/cod_tcx.c +++ b/lib_enc/cod_tcx.c @@ -43,6 +43,12 @@ #include "wmc_auto.h" #include "ivas_prot.h" #include "ivas_rom_com.h" +#ifdef DEBUGGING +#include +#endif +#ifdef DEBUG_PLOT +#include "deb_out.h" +#endif /*-------------------------------------------------------------------* * HBAutocorrelation() @@ -104,10 +110,19 @@ void HBAutocorrelation( void TNSAnalysisStereo( Encoder_State **sts, /* i : encoder state handle */ +#ifdef FIX_887_ARRAY_SIZE_DFT_MDCT_STEREO float *mdst_spectrum[CPE_CHANNELS][NB_DIV], /* o : MDST spectrum */ +#else + float *mdst_spectrum[MCT_MAX_CHANNELS][NB_DIV], /* o : MDST spectrum */ +#endif const int16_t bWhitenedDomain, /* i : whitened domain flag */ +#ifdef FIX_887_ARRAY_SIZE_DFT_MDCT_STEREO int16_t tnsSize[CPE_CHANNELS][NB_DIV], /* i : number of tns parameters put into prm */ int16_t tnsBits[CPE_CHANNELS][NB_DIV], /* i : number of tns bits in the frame */ +#else + int16_t tnsSize[MCT_MAX_CHANNELS][NB_DIV], /* i : number of tns parameters put into prm */ + int16_t tnsBits[MCT_MAX_CHANNELS][NB_DIV], /* i : number of tns bits in the frame */ +#endif int16_t param_core[][NB_DIV * NPRM_DIV], /* o : TNS parameters */ const int16_t mct_on /* i : flag mct block (1) or stereo (0) */ ) @@ -215,6 +230,9 @@ void TNSAnalysisStereo( sts[0]->hTcxCfg->pCurrentTnsConfig = &sts[0]->hTcxCfg->tnsConfig[sts[0]->hTcxEnc->transform_type[k] == TCX_20][( k == 0 ) && ( sts[0]->last_core == ACELP_CORE )]; sts[1]->hTcxCfg->pCurrentTnsConfig = &sts[1]->hTcxCfg->tnsConfig[sts[1]->hTcxEnc->transform_type[k] == TCX_20][( k == 0 ) && ( sts[1]->last_core == ACELP_CORE )]; +#ifdef DEBUGGING + assert( sts[0]->hTcxCfg->pCurrentTnsConfig->nMaxFilters == sts[1]->hTcxCfg->pCurrentTnsConfig->nMaxFilters ); +#endif for ( iFilter = sts[0]->hTcxCfg->pCurrentTnsConfig->nMaxFilters - 1; iFilter >= 0; iFilter-- ) { STnsFilter *pFilter[2]; @@ -224,6 +242,10 @@ void TNSAnalysisStereo( pFilter[1] = sts[1]->hTcxEnc->tnsData[k].filter + iFilter; pTnsParameters[1] = sts[1]->hTcxCfg->pCurrentTnsConfig->pTnsParameters + iFilter; +#ifdef DEBUGGING + assert( pTnsParameters[0]->startLineFrequency == pTnsParameters[1]->startLineFrequency ); + assert( pTnsParameters[0]->nSubdivisions == pTnsParameters[1]->nSubdivisions ); +#endif /* if prediction gain and avgSqrCoef are both close we are pretty sure the filters are quite similar, use the avg of * both filters for the decision */ @@ -1002,6 +1024,12 @@ void EstimateStereoTCXNoiseLevel( } } /* bitrate */ } +#ifdef DEBUG_MODE_MDCT + dbgwrite( &smooth_gain, sizeof( float ), 1, 1, "./res/smooth_gain" ); + dbgwrite( &st->hTcxEnc->tcxltp_gain, sizeof( float ), 1, 1, "./res/tcxltp_gain" ); + dbgwrite( &noiseTransWidth, sizeof( int16_t ), 1, 1, "./res/noiseTrans" ); + dbgwrite( &fac_ns[ch][0], sizeof( float ), 2, 1, "./res/fac_ns" ); +#endif } return; @@ -1610,6 +1638,34 @@ void QuantizeTCXSpectrum( } } +#ifdef DEBUGGING + /*-----------------------------------------------------------* + * TCX SNR for Analysis purposes * + *-----------------------------------------------------------*/ + { + float diff[N_MAX]; + char name[50] = "TCX_output_chX "; + + for ( i = 0; i < min( L_frame, L_spec ); i++ ) + { + diff[i] = x_orig[i] - *gain_tcx * spectrum[i]; + } + + if ( st->id_element == 0 ) + { + name[13] = (char) ( st->idchan + '0' ); + } + else + { + char name2[50] = "TCX_output.idX_chX "; + name2[13] = (char) ( st->id_element + '0' ); + name2[17] = (char) ( st->idchan + '0' ); + strcpy( name, name2 ); + } + + snr( x_orig, diff, min( L_frame, L_spec ), name ); + } +#endif return; } diff --git a/lib_enc/core_enc_2div.c b/lib_enc/core_enc_2div.c index 25d62130c..faa7af358 100644 --- a/lib_enc/core_enc_2div.c +++ b/lib_enc/core_enc_2div.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "prot.h" #include "rom_com.h" diff --git a/lib_enc/core_enc_init.c b/lib_enc/core_enc_init.c index b0ef74245..b307e0361 100644 --- a/lib_enc/core_enc_init.c +++ b/lib_enc/core_enc_init.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "prot.h" #include "ivas_prot.h" diff --git a/lib_enc/core_enc_ol.c b/lib_enc/core_enc_ol.c index 278f47b73..e83fd598b 100644 --- a/lib_enc/core_enc_ol.c +++ b/lib_enc/core_enc_ol.c @@ -37,6 +37,9 @@ #include #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "prot.h" #include "rom_com.h" @@ -955,6 +958,19 @@ void core_acelp_tcx20_switching( st->core = TCX_20_CORE; st->acelpFramesCount = 0; } +#ifdef DEBUGGING + if ( st->force != -1 ) + { + if ( st->force == FORCE_SPEECH ) + { + st->core = ACELP_CORE; + } + else + { + st->core = TCX_20_CORE; + } + } +#endif } /* Fixed Decision (using -C) */ diff --git a/lib_enc/core_enc_reconf.c b/lib_enc/core_enc_reconf.c index 0ad804f95..9dffda020 100644 --- a/lib_enc/core_enc_reconf.c +++ b/lib_enc/core_enc_reconf.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "prot.h" #include "rom_com.h" #include "rom_enc.h" diff --git a/lib_enc/core_enc_switch.c b/lib_enc/core_enc_switch.c index e6b672d85..44952cc1d 100644 --- a/lib_enc/core_enc_switch.c +++ b/lib_enc/core_enc_switch.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "prot.h" #include "rom_com.h" #include "wmc_auto.h" diff --git a/lib_enc/core_enc_updt.c b/lib_enc/core_enc_updt.c index 1e17f7822..3d5476a89 100644 --- a/lib_enc/core_enc_updt.c +++ b/lib_enc/core_enc_updt.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "prot.h" #include "rom_com.h" #include "cnst.h" diff --git a/lib_enc/core_switching_enc.c b/lib_enc/core_switching_enc.c index 9b988a123..e964f33c0 100644 --- a/lib_enc/core_switching_enc.c +++ b/lib_enc/core_switching_enc.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "rom_enc.h" diff --git a/lib_enc/corr_xh.c b/lib_enc/corr_xh.c index def6a44f0..c317878e1 100644 --- a/lib_enc/corr_xh.c +++ b/lib_enc/corr_xh.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "prot.h" #include "cnst.h" #include "wmc_auto.h" diff --git a/lib_enc/decision_matrix_enc.c b/lib_enc/decision_matrix_enc.c index 8dd792144..e2587fbe0 100644 --- a/lib_enc/decision_matrix_enc.c +++ b/lib_enc/decision_matrix_enc.c @@ -37,6 +37,9 @@ #include #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "prot.h" #include "stat_enc.h" #include "stat_dec.h" @@ -181,10 +184,17 @@ void decision_matrix_enc( { st->core = ACELP_CORE; +#ifdef DEBUGGING + if ( st->total_brate >= HQCORE_NB_MIN_RATE && ( st->force == FORCE_MUSIC || ( st->force == -1 && st->sp_aud_decision1 == 1 ) ) ) + { + st->core = HQ_CORE; + } +#else if ( st->total_brate >= HQCORE_NB_MIN_RATE && st->sp_aud_decision1 == 1 ) { st->core = HQ_CORE; } +#endif } /*---------------------------------------------------------------------* @@ -195,7 +205,11 @@ void decision_matrix_enc( { st->core = ACELP_CORE; +#ifdef DEBUGGING + if ( ( st->total_brate >= HQCORE_WB_MIN_RATE && ( st->force == FORCE_MUSIC || ( st->force == -1 && st->sp_aud_decision1 == 1 ) ) ) || st->total_brate >= HQ_96k ) +#else if ( ( st->total_brate >= HQCORE_WB_MIN_RATE && st->sp_aud_decision1 == 1 ) || st->total_brate >= HQ_96k ) +#endif { st->core = HQ_CORE; } @@ -228,7 +242,11 @@ void decision_matrix_enc( else if ( st->bwidth == SWB || st->bwidth == FB ) { +#ifdef DEBUGGING + if ( ( st->total_brate >= HQCORE_WB_MIN_RATE && ( st->force == FORCE_MUSIC || ( st->force == -1 && st->sp_aud_decision1 == 1 ) ) ) || st->total_brate >= HQ_96k ) +#else if ( ( st->total_brate >= HQCORE_SWB_MIN_RATE && st->sp_aud_decision1 == 1 ) || st->total_brate >= HQ_96k ) +#endif { st->core = HQ_CORE; } diff --git a/lib_enc/detect_transient.c b/lib_enc/detect_transient.c index 669b55433..0b73a12e6 100644 --- a/lib_enc/detect_transient.c +++ b/lib_enc/detect_transient.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "prot.h" #include "cnst.h" #include "rom_com.h" diff --git a/lib_enc/diffcod.c b/lib_enc/diffcod.c index 47810a672..fd6646c48 100644 --- a/lib_enc/diffcod.c +++ b/lib_enc/diffcod.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "prot.h" #include "rom_com.h" #include "wmc_auto.h" diff --git a/lib_enc/dtx.c b/lib_enc/dtx.c index 9153316fa..606c8aaaf 100644 --- a/lib_enc/dtx.c +++ b/lib_enc/dtx.c @@ -37,6 +37,9 @@ #include #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "prot.h" @@ -442,6 +445,16 @@ void dtx( } } +#ifdef DEBUG_MODE_ACELP + { + int16_t tmp_s; + + tmp_s = (int16_t) st->bckr_tilt_lt; + dbgwrite( &( tmp_s ), sizeof( int16_t ), 1, st->L_frame, "./res/bckr_tilt.pcm" ); + tmp_s = (int16_t) st->lp_noise; + dbgwrite( &( tmp_s ), sizeof( int16_t ), 1, st->L_frame, "./res/lp_noise.pcm" ); + } +#endif return; } diff --git a/lib_enc/enc_acelp.c b/lib_enc/enc_acelp.c index 8e034e1c7..5e1401828 100644 --- a/lib_enc/enc_acelp.c +++ b/lib_enc/enc_acelp.c @@ -37,6 +37,9 @@ #include #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "prot.h" #include "rom_com.h" diff --git a/lib_enc/enc_acelp_tcx_main.c b/lib_enc/enc_acelp_tcx_main.c index 338d87cc6..5c549b23d 100644 --- a/lib_enc/enc_acelp_tcx_main.c +++ b/lib_enc/enc_acelp_tcx_main.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "prot.h" #include "rom_com.h" #include "wmc_auto.h" diff --git a/lib_enc/enc_acelpx.c b/lib_enc/enc_acelpx.c index d8dcf192b..c72f2fa1c 100644 --- a/lib_enc/enc_acelpx.c +++ b/lib_enc/enc_acelpx.c @@ -37,6 +37,9 @@ #include #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "prot.h" #include "rom_enc.h" #include "wmc_auto.h" diff --git a/lib_enc/enc_amr_wb.c b/lib_enc/enc_amr_wb.c index f90268002..bb09c0886 100644 --- a/lib_enc/enc_amr_wb.c +++ b/lib_enc/enc_amr_wb.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "prot.h" #include "rom_com.h" diff --git a/lib_enc/enc_gen_voic.c b/lib_enc/enc_gen_voic.c index 07dc54f77..4c78b484c 100644 --- a/lib_enc/enc_gen_voic.c +++ b/lib_enc/enc_gen_voic.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "prot.h" #include "rom_com.h" diff --git a/lib_enc/enc_gen_voic_rf.c b/lib_enc/enc_gen_voic_rf.c index c3a6a4f8f..7ceece404 100644 --- a/lib_enc/enc_gen_voic_rf.c +++ b/lib_enc/enc_gen_voic_rf.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "prot.h" #include "rom_com.h" diff --git a/lib_enc/enc_higher_acelp.c b/lib_enc/enc_higher_acelp.c index bd68e5d68..5610bdfe4 100644 --- a/lib_enc/enc_higher_acelp.c +++ b/lib_enc/enc_higher_acelp.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "prot.h" diff --git a/lib_enc/enc_nelp.c b/lib_enc/enc_nelp.c index 253a97a9b..7d828208b 100644 --- a/lib_enc/enc_nelp.c +++ b/lib_enc/enc_nelp.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "rom_com.h" #include "prot.h" diff --git a/lib_enc/enc_pit_exc.c b/lib_enc/enc_pit_exc.c index b640e0b41..eba203b6a 100644 --- a/lib_enc/enc_pit_exc.c +++ b/lib_enc/enc_pit_exc.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "rom_com.h" #include "prot.h" diff --git a/lib_enc/enc_ppp.c b/lib_enc/enc_ppp.c index 51e353dfe..b5b7e4548 100644 --- a/lib_enc/enc_ppp.c +++ b/lib_enc/enc_ppp.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "prot.h" #include "wmc_auto.h" diff --git a/lib_enc/enc_prm.c b/lib_enc/enc_prm.c index 41a211fbf..61bfbf2f0 100644 --- a/lib_enc/enc_prm.c +++ b/lib_enc/enc_prm.c @@ -37,6 +37,9 @@ #include #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "rom_com.h" #include "prot.h" @@ -193,6 +196,9 @@ void writeTCXWindowing( const int16_t overlap_mode /* i : overlap mode */ ) { +#ifdef DEBUGGING + assert( overlap_mode != NOT_SUPPORTED && overlap_mode <= ALDO_WINDOW && overlap_mode >= FULL_OVERLAP ); /*1 is not allowed!*/ +#endif if ( overlap_mode == MIN_OVERLAP ) { @@ -334,6 +340,9 @@ void writeTCXparam( int16_t total_nbbits, nbits_igf, nbits_tcx; int16_t nTnsParams, nTnsBits; int16_t pre_part, post_part; +#ifdef DEBUG_PLOT_BITS + int16_t tmp = hBstr->nb_bits_tot; +#endif if ( pre_past_flag == 0 ) { @@ -410,6 +419,10 @@ void writeTCXparam( { push_next_indice( hBstr, 0, 1 ); } +#ifdef DEBUG_PLOT_BITS + tmp = hBstr->nb_bits_tot - tmp; + dbgwrite( &tmp, sizeof( int16_t ), 1, 1, "./res/bits_LTP" ); +#endif } j += 3; } @@ -462,6 +475,9 @@ void writeTCXparam( } j += nTnsParams; } +#ifdef DEBUG_PLOT_BITS + dbgwrite( &nTnsBits, sizeof( int16_t ), 1, 1, "./res/bits_TNS" ); +#endif if ( post_part ) { @@ -514,6 +530,9 @@ void writeTCXparam( else { /*Context HM flag*/ +#ifdef DEBUGGING + assert( st->hTcxCfg->ctx_hm == 0 ); +#endif p_param[k] = j; } } @@ -548,6 +567,16 @@ void writeTCXparam( } } } +#ifdef DEBUG_PLOT_BITS + if ( pre_part ) + { + if ( nSubframes == 1 ) + { + tmp = 0; + dbgwrite( &tmp, sizeof( int16_t ), 1, 1, "./res/bits_TNS" ); + } + } +#endif return; } diff --git a/lib_enc/enc_tran.c b/lib_enc/enc_tran.c index 6bd536aae..d713584fa 100644 --- a/lib_enc/enc_tran.c +++ b/lib_enc/enc_tran.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "prot.h" #include "rom_com.h" #include "wmc_auto.h" diff --git a/lib_enc/enc_uv.c b/lib_enc/enc_uv.c index 2ca7ecfdc..f6c17e410 100644 --- a/lib_enc/enc_uv.c +++ b/lib_enc/enc_uv.c @@ -37,6 +37,9 @@ #include #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "prot.h" @@ -180,6 +183,9 @@ void encod_unvoiced( index = gain_enc_gacelp_uv( code, code2, L_SUBFR, Es_pred, &gain_pit, &gain_code, &gain_code2, &g_corr, &norm_gain_code, &gain_inov, st->flag_noisy_speech_snr ); +#ifdef DEBUGGING + assert( st->acelp_cfg.gains_mode[i_subfr / L_SUBFR] == 7 && "Error: UC two-stage, only 5+2 gain Q is supported" ); +#endif push_indice( st->hBstr, IND_GAIN, index, st->acelp_cfg.gains_mode[i_subfr / L_SUBFR] ); gp_clip_test_gain_pit( st->element_mode, st->core_brate, gain_pit, st->clip_var ); diff --git a/lib_enc/eval_pit_contr.c b/lib_enc/eval_pit_contr.c index 7f6a026ac..6779afe2a 100644 --- a/lib_enc/eval_pit_contr.c +++ b/lib_enc/eval_pit_contr.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "rom_com.h" diff --git a/lib_enc/evs_enc.c b/lib_enc/evs_enc.c index 56734fe37..cc01594b7 100644 --- a/lib_enc/evs_enc.c +++ b/lib_enc/evs_enc.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "rom_com.h" #include "prot.h" @@ -92,7 +95,9 @@ ivas_error evs_enc( int16_t padBits; float realBuffer[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; /* real buffer */ float imagBuffer[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; /* imag buffer */ +#ifndef FIX_I4_OL_PITCH int16_t pitch_orig[3]; /* original open-loop pitch values that might be altered in core_acelp_tcx20_switching() within MODE2 */ +#endif ivas_error error; error = IVAS_ERR_OK; @@ -165,7 +170,11 @@ ivas_error evs_enc( * Pre-processing *---------------------------------------------------------------------*/ +#ifdef FIX_I4_OL_PITCH + pre_proc( st, input_frame, old_inp_12k8, old_inp_16k, &inp, fr_bands, Etot, &ener, A, Aw, epsP, lsp_new, lsp_mid, &vad_hover_flag, &attack_flag, new_inp_resamp16k, &Voicing_flag, realBuffer, imagBuffer, &hq_core_type ); +#else pre_proc( st, input_frame, old_inp_12k8, old_inp_16k, &inp, fr_bands, &ener, pitch_orig, A, Aw, epsP, lsp_new, lsp_mid, &vad_hover_flag, &attack_flag, new_inp_resamp16k, &Voicing_flag, realBuffer, imagBuffer, &hq_core_type ); +#endif if ( st->mdct_sw == MODE2 ) { @@ -254,10 +263,12 @@ ivas_error evs_enc( core_switching_post_enc( st, old_inp_12k8, old_inp_16k, A ); +#ifndef FIX_I4_OL_PITCH if ( st->core == HQ_CORE ) { mvs2s( pitch_orig, st->pitch, 3 ); /* original open-loop pitch values might be altered in core_acelp_tcx20_switching() */ } +#endif } else /* MODE2 */ @@ -282,7 +293,9 @@ ivas_error evs_enc( /* Call main encoding function */ enc_acelp_tcx_main( st, old_inp_16k + L_INP_MEM, Aw, lsp_new, lsp_mid, bwe_exc_extended, voice_factors, pitch_buf, vad_hover_flag ); +#ifndef FIX_I4_OL_PITCH mvs2s( pitch_orig, st->pitch, 3 ); /* populate the original OL pitch values back */ +#endif /*---------------------------------------------------------------------* * Postprocessing for Mode 1/2 switching @@ -488,6 +501,48 @@ ivas_error evs_enc( st->codec_mode = MODE2; } +#ifdef DEBUG_MODE_INFO + dbgwrite( &st->codec_mode, sizeof( int16_t ), 1, input_frame, "res/codec" ); + dbgwrite( &st->core, sizeof( int16_t ), 1, input_frame, "res/core" ); + dbgwrite( &st->extl, sizeof( int16_t ), 1, input_frame, "res/extl" ); + dbgwrite( &st->bwidth, sizeof( int16_t ), 1, input_frame, "res/bwidth" ); + ener = st->total_brate / 1000.0f; + dbgwrite( &ener, sizeof( float ), 1, input_frame, "res/total_brate" ); + ener = st->core_brate / 1000.0f; + dbgwrite( &ener, sizeof( float ), 1, input_frame, "res/core_brate" ); + ener = st->extl_brate / 1000.0f; + dbgwrite( &ener, sizeof( float ), 1, input_frame, "res/extl_brate" ); + dbgwrite( &st->coder_type, sizeof( int16_t ), 1, input_frame, "res/coder_type" ); + dbgwrite( &st->clas, sizeof( int16_t ), 1, input_frame, "res/clas" ); + dbgwrite( &st->cng_type, sizeof( int16_t ), 1, input_frame, "res/cng_type" ); + dbgwrite( &st->L_frame, sizeof( int16_t ), 1, input_frame, "res/L_frame" ); + dbgwrite( &st->vad_flag, sizeof( int16_t ), 1, input_frame, "res/vad_flag" ); + + { + int16_t _pitch[3]; + if ( ( st->coder_type == INACTIVE ) || ( st->coder_type == UNVOICED ) ) + { + _pitch[0] = 0; + _pitch[1] = 0; + _pitch[2] = 0; + } + else + { + _pitch[0] = st->pitch[0]; + _pitch[1] = st->pitch[1]; + _pitch[2] = st->pitch[2]; + } + dbgwrite( &_pitch[0], sizeof( int16_t ), 1, ( input_frame / 8 * 3 ), "res/pitch" ); + dbgwrite( &_pitch[1], sizeof( int16_t ), 1, ( input_frame / 8 * 3 ), "res/pitch" ); + dbgwrite( &_pitch[2], sizeof( int16_t ), 1, ( input_frame / 8 * 2 ), "res/pitch" ); + } + + if ( st->core != ACELP_CORE ) + { + set_f( new_swb_speech, 0, input_frame ); + dbgwrite( new_swb_speech, 4, st->L_frame, 1, "res/exc.enc" ); + } +#endif pop_wmops(); diff --git a/lib_enc/ext_sig_ana.c b/lib_enc/ext_sig_ana.c index 6488407e3..16f0b1732 100644 --- a/lib_enc/ext_sig_ana.c +++ b/lib_enc/ext_sig_ana.c @@ -37,10 +37,16 @@ #include #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "prot.h" #include "rom_com.h" #include "wmc_auto.h" +#ifdef DEBUG_PLOT +#include "deb_out.h" +#endif /*-------------------------------------------------------------------* diff --git a/lib_enc/fd_cng_enc.c b/lib_enc/fd_cng_enc.c index 12019f480..407121d59 100644 --- a/lib_enc/fd_cng_enc.c +++ b/lib_enc/fd_cng_enc.c @@ -37,6 +37,9 @@ #include #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "rom_enc.h" #include "rom_com.h" @@ -1019,6 +1022,9 @@ void FdCngEncodeMDCTStereoSID( ms_ptr[ch] = &logNoiseEst[ch][0]; lr_out_ptr[ch] = &sts[ch]->hFdCngEnc->hFdCngCom->sidNoiseEst[0]; } +#ifdef DEBUGGING + assert( sts[0]->hFdCngEnc->npartDec == sts[1]->hFdCngEnc->npartDec ); +#endif N = sts[0]->hFdCngEnc->npartDec; set_f( weights, 1.f, NPART ); @@ -1247,6 +1253,9 @@ void FdCngEncodeDiracMDCTStereoSID( lr_out_ptr[ch] = &sts[ch]->hFdCngEnc->hFdCngCom->sidNoiseEst[0]; } set_f( weights, 1.f, NPART ); +#ifdef DEBUGGING + assert( N[0] == N[1] ); +#endif /* apply log and save energy of original left and right channels */ for ( ch = 0; ch < CPE_CHANNELS; ch++ ) diff --git a/lib_enc/find_tar.c b/lib_enc/find_tar.c index fc9419427..008fb17cb 100644 --- a/lib_enc/find_tar.c +++ b/lib_enc/find_tar.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "prot.h" #include "wmc_auto.h" diff --git a/lib_enc/find_tilt.c b/lib_enc/find_tilt.c index fcff9d796..bdfac0569 100644 --- a/lib_enc/find_tilt.c +++ b/lib_enc/find_tilt.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "prot.h" diff --git a/lib_enc/find_uv.c b/lib_enc/find_uv.c index 9551a2a15..a80971880 100644 --- a/lib_enc/find_uv.c +++ b/lib_enc/find_uv.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "prot.h" diff --git a/lib_enc/find_wsp.c b/lib_enc/find_wsp.c index 4837411a5..e08918a4d 100644 --- a/lib_enc/find_wsp.c +++ b/lib_enc/find_wsp.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "prot.h" #include "wmc_auto.h" diff --git a/lib_enc/gain_enc.c b/lib_enc/gain_enc.c index 6ee7c7228..b114b34c7 100644 --- a/lib_enc/gain_enc.c +++ b/lib_enc/gain_enc.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "rom_com.h" diff --git a/lib_enc/gaus_enc.c b/lib_enc/gaus_enc.c index 7f3220094..79b480e51 100644 --- a/lib_enc/gaus_enc.c +++ b/lib_enc/gaus_enc.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "rom_com.h" diff --git a/lib_enc/gp_clip.c b/lib_enc/gp_clip.c index 36133af3e..43394c2bf 100644 --- a/lib_enc/gp_clip.c +++ b/lib_enc/gp_clip.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "prot.h" #include "cnst.h" diff --git a/lib_enc/gs_enc.c b/lib_enc/gs_enc.c index c22285436..25f1f8fc7 100644 --- a/lib_enc/gs_enc.c +++ b/lib_enc/gs_enc.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "rom_com.h" diff --git a/lib_enc/hf_cod_amrwb.c b/lib_enc/hf_cod_amrwb.c index 7357bcd18..c9cbba3cd 100644 --- a/lib_enc/hf_cod_amrwb.c +++ b/lib_enc/hf_cod_amrwb.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "prot.h" diff --git a/lib_enc/hq_classifier_enc.c b/lib_enc/hq_classifier_enc.c index 1df92357d..a8d798e65 100644 --- a/lib_enc/hq_classifier_enc.c +++ b/lib_enc/hq_classifier_enc.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "prot.h" diff --git a/lib_enc/hq_core_enc.c b/lib_enc/hq_core_enc.c index 261e02202..3fb39b535 100644 --- a/lib_enc/hq_core_enc.c +++ b/lib_enc/hq_core_enc.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "prot.h" diff --git a/lib_enc/hq_env_enc.c b/lib_enc/hq_env_enc.c index c0a63e262..4d57dde16 100644 --- a/lib_enc/hq_env_enc.c +++ b/lib_enc/hq_env_enc.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "prot.h" #include "rom_com.h" #include "rom_enc.h" diff --git a/lib_enc/hq_hr_enc.c b/lib_enc/hq_hr_enc.c index 1855f26df..d815295a4 100644 --- a/lib_enc/hq_hr_enc.c +++ b/lib_enc/hq_hr_enc.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "prot.h" #include "rom_enc.h" @@ -190,7 +193,11 @@ void hq_hr_enc( if ( hqswb_clas == HQ_HVQ ) { +#ifdef DEBUGGING + sum = hvq_enc( hBstr, st->bwidth, st->idchan, st->core_brate, *num_bits, Npeaks, ynrm, R, peaks, nf_gains, noise_level, pe_gains, t_audio, t_audio_q ); +#else sum = hvq_enc( hBstr, st->bwidth, st->core_brate, *num_bits, Npeaks, ynrm, R, peaks, nf_gains, noise_level, pe_gains, t_audio, t_audio_q ); +#endif *num_bits -= sum; } else diff --git a/lib_enc/hq_lr_enc.c b/lib_enc/hq_lr_enc.c index 8aa39964b..343a31713 100644 --- a/lib_enc/hq_lr_enc.c +++ b/lib_enc/hq_lr_enc.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "rom_enc.h" @@ -933,7 +936,11 @@ void hq_lr_enc( hq2_bit_alloc( band_energy, bands, Rk_fx, &bit_budget, p2a_flags, bit_alloc_weight_fx, band_width, *num_bits, hqswb_clas, st->bwidth, is_transient ); } +#ifdef DEBUGGING + tcq_core_LR_enc( hBstr, st->idchan, inp_vector, t_audio, y2, bit_budget, bands, band_start, band_end, band_width, Rk_fx, npulses, k_sort, p2a_flags, p2a_bands, hHQ_core->last_bitalloc_max_band, inner_frame, adjustFlag, is_transient ); +#else tcq_core_LR_enc( hBstr, inp_vector, t_audio, y2, bit_budget, bands, band_start, band_end, band_width, Rk_fx, npulses, k_sort, p2a_flags, p2a_bands, hHQ_core->last_bitalloc_max_band, inner_frame, adjustFlag, is_transient ); +#endif if ( ( inner_frame == L_FRAME8k && st->core_brate <= ACELP_13k20 ) || inner_frame == L_FRAME16k ) { diff --git a/lib_enc/hvq_enc.c b/lib_enc/hvq_enc.c index 54c50f31a..42ac52cc3 100644 --- a/lib_enc/hvq_enc.c +++ b/lib_enc/hvq_enc.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "prot.h" @@ -53,6 +56,9 @@ int16_t hvq_enc( BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ const int16_t bwidth, /* i : audio bandwidth */ +#ifdef DEBUGGING + const int16_t idchan, /* i : channel ID */ +#endif const int32_t core_brate, /* i : core bitrate */ const int16_t hvq_bits, /* i : HVQ bit budget */ const int16_t Npeaks, /* i : Number of peaks */ @@ -146,7 +152,11 @@ int16_t hvq_enc( nf_gains[i] *= 2 * lb_nfpe; } +#ifdef DEBUGGING + bits_used += peak_vq_enc( hBstr, bwidth, idchan, coefs, coefs_out, core_brate, hvq_bits - bits_used, Npeaks, ynrm, R, peaks, &nf_gains[0] ); +#else bits_used += peak_vq_enc( hBstr, bwidth, coefs, coefs_out, core_brate, hvq_bits - bits_used, Npeaks, ynrm, R, peaks, &nf_gains[0] ); +#endif return bits_used; diff --git a/lib_enc/igf_enc.c b/lib_enc/igf_enc.c index c1a2e29b8..93306733c 100644 --- a/lib_enc/igf_enc.c +++ b/lib_enc/igf_enc.c @@ -37,12 +37,18 @@ #include #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "prot.h" #include "ivas_prot.h" #include "cnst.h" #include "stat_enc.h" #include "wmc_auto.h" +#ifdef DEBUG_PLOT +#include "deb_out.h" +#endif /*-------------------------------------------------------------------* diff --git a/lib_enc/igf_scf_enc.c b/lib_enc/igf_scf_enc.c index 3c97808ef..f893a8b31 100644 --- a/lib_enc/igf_scf_enc.c +++ b/lib_enc/igf_scf_enc.c @@ -37,6 +37,9 @@ #include #include "options.h" #include "prot.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "stat_enc.h" #include "stat_com.h" #include "cnst.h" diff --git a/lib_enc/init_enc.c b/lib_enc/init_enc.c index e5d8f6294..e722d8350 100644 --- a/lib_enc/init_enc.c +++ b/lib_enc/init_enc.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "rom_com.h" #include "rom_enc.h" diff --git a/lib_enc/inov_enc.c b/lib_enc/inov_enc.c index 2c99ebdac..fedc98e10 100644 --- a/lib_enc/inov_enc.c +++ b/lib_enc/inov_enc.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "prot.h" #include "ivas_prot.h" @@ -311,6 +314,12 @@ void inov_encode( set_f( y2, 0.0f, L_SUBFR ); } } +#ifdef DEBUGGING + else + { + IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "invalid mode for acelp frame!\n" ); + } +#endif } else { diff --git a/lib_enc/isf_enc_amr_wb.c b/lib_enc/isf_enc_amr_wb.c index b9479edef..c10ee6288 100644 --- a/lib_enc/isf_enc_amr_wb.c +++ b/lib_enc/isf_enc_amr_wb.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "rom_enc.h" #include "rom_com.h" diff --git a/lib_enc/ivas_agc_enc.c b/lib_enc/ivas_agc_enc.c index 7c72028a8..09db68d7d 100644 --- a/lib_enc/ivas_agc_enc.c +++ b/lib_enc/ivas_agc_enc.c @@ -33,6 +33,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "ivas_prot.h" #include "prot.h" #include @@ -46,6 +49,16 @@ #define AGC_MIN_DELTA ( 4.656612873077393e-10f ) /*2^-31*/ +#ifdef DEBUG_AGC +/*------------------------------------------------------------------------------------------* + * Local functions declarations + *------------------------------------------------------------------------------------------*/ + +extern FILE *agcOut; + +static int16_t ivas_agc_writeBits( FILE *stream, const int16_t n_channels, ivas_agc_enc_state_t *pState ); + +#endif /*-----------------------------------------------------------------------------------------* * Function ivas_agc_enc_get_flag() @@ -55,6 +68,9 @@ /*! r: AGC enable flag */ int16_t ivas_agc_enc_get_flag( +#ifdef DEBUG_AGC_ENCODER_CMD_OPTION + const int16_t agc_configuration, /* i : AGC configuration from command-line */ +#endif const int16_t nchan_transport /* i : number of transport channels */ ) { @@ -63,6 +79,11 @@ int16_t ivas_agc_enc_get_flag( /* AGC is enabled only if there is one transport channel. */ agc_flag = (int16_t) ( nchan_transport == 1 ); +#ifdef DEBUG_AGC_ENCODER_CMD_OPTION + /* If agc_configuration is not undefined, then this value decides on the state of * enablement, + otherwise AGC is enabled only if there is one transport channel. */ + agc_flag = ( agc_configuration != SBA_AGC_DEFAULT ) ? agc_configuration : agc_flag; +#endif return agc_flag; } @@ -430,7 +451,42 @@ void ivas_agc_enc_process( } } +#ifdef DEBUG_AGC + /* writing to a temporary bitstream file */ + if ( ivas_agc_writeBits( agcOut, n_channels, pState ) ) + { + IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "SPAR ENC AGC Failed to open agcOut\n " ); + } +#endif return; } +#ifdef DEBUG_AGC +static int16_t ivas_agc_writeBits( FILE *stream, const int16_t n_channels, ivas_agc_enc_state_t *pState ) +{ + if ( stream == NULL ) + { + return TRUE; + } + + int16_t num_bits = 0, num_dmx_bits[4] = { 0 }; + for ( int16_t i = 0; i < n_channels; i++ ) + { + if ( pState->gain_data[i].absGainExpCurr < 0 || + pState->gain_data[i].absGainExpCurr >= (int16_t) pow( 2, pState->agc_com.betaE ) ) + { + IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Error Gain values to write!!\n\n" ); + } + + fwrite( &( pState->gain_data[i].absGainExpCurr ), sizeof( int32_t ), 1, stream ); /* n bits */ + num_bits += pState->agc_com.betaE; + num_dmx_bits[i]++; + + /*fprintf(stdout, "absGainExpCurr[%d]:= %d[%d bits]; ", i, pState->gain_data[i].absGainExpCurr, pState->betaE); */ + } + /*fprintf(stdout, "AGC bits:= %d ", num_bits);*/ + + return FALSE; +} +#endif diff --git a/lib_enc/ivas_core_enc.c b/lib_enc/ivas_core_enc.c index fe16b7784..a4be24698 100644 --- a/lib_enc/ivas_core_enc.c +++ b/lib_enc/ivas_core_enc.c @@ -32,6 +32,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "rom_com.h" #include "prot.h" @@ -40,6 +43,9 @@ #include "wmc_auto.h" #include +#ifdef DEBUG_MODE_ACELP +extern float snr_[2][320]; +#endif /*-------------------------------------------------------------------* @@ -159,6 +165,9 @@ ivas_error ivas_core_enc( * Initializiation per core-coder channel *-----------------------------------------------------------------*/ +#ifdef DEBUG_MODE_ACELP + set_f( snr_[n], 0.0f, 320 ); +#endif st->extl = -1; unbits[n] = 0; @@ -437,6 +446,117 @@ ivas_error ivas_core_enc( } } +#ifdef DEBUG_MODE_INFO + for ( n = 0; n < n_CoreChannels; n++ ) + { + float tmpF; + int16_t tmpS, id; +#if defined DEBUG_MODE_ACELP || defined DEBUG_MODE_TCX + int16_t k, _pitch[3], _pitch_buf[5]; +#endif + + st = sts[n]; + id = st->id_element; + + dbgwrite( &st->core, sizeof( int16_t ), 1, input_frame, fname( debug_dir, "core", n, id, ENC ) ); + dbgwrite( &st->extl, sizeof( int16_t ), 1, input_frame, fname( debug_dir, "extl", n, id, ENC ) ); + dbgwrite( &st->bwidth, sizeof( int16_t ), 1, input_frame, fname( debug_dir, "bwidth", n, id, ENC ) ); + tmpF = st->total_brate / 1000.0f; + dbgwrite( &tmpF, sizeof( float ), 1, input_frame, fname( debug_dir, "total_brate", n, id, ENC ) ); + tmpS = st->bits_frame_nominal; + dbgwrite( &tmpS, sizeof( int16_t ), 1, input_frame, fname( debug_dir, "bits_nominal", n, id, ENC ) ); + tmpF = st->core_brate / 1000.0f; + dbgwrite( &tmpF, sizeof( float ), 1, input_frame, fname( debug_dir, "core_brate", n, id, ENC ) ); + tmpF = st->extl_brate / 1000.0f; + dbgwrite( &tmpF, sizeof( float ), 1, input_frame, fname( debug_dir, "extl_brate", n, id, ENC ) ); + + dbgwrite( &st->coder_type, sizeof( int16_t ), 1, input_frame, fname( debug_dir, "coder_type", n, id, ENC ) ); + dbgwrite( &st->coder_type_raw, sizeof( int16_t ), 1, input_frame, fname( debug_dir, "coder_type_raw", n, id, ENC ) ); + dbgwrite( &st->clas, sizeof( int16_t ), 1, input_frame, fname( debug_dir, "clas", n, id, ENC ) ); + dbgwrite( &st->cng_type, sizeof( int16_t ), 1, input_frame, fname( debug_dir, "cng_type", n, id, ENC ) ); + dbgwrite( &st->L_frame, sizeof( int16_t ), 1, input_frame, fname( debug_dir, "L_frame", n, id, ENC ) ); + dbgwrite( &st->vad_flag, sizeof( int16_t ), 1, input_frame, fname( debug_dir, "vad_flag", n, id, ENC ) ); + dbgwrite( &st->localVAD, sizeof( int16_t ), 1, input_frame, fname( debug_dir, "localVAD", n, id, ENC ) ); + + dbgwrite( &st->count_WB, sizeof( int16_t ), 1, input_frame, fname( debug_dir, "count_WB", n, id, ENC ) ); + dbgwrite( &st->count_SWB, sizeof( int16_t ), 1, input_frame, fname( debug_dir, "count_SWB", n, id, ENC ) ); + +#ifdef DEBUG_MODE_ACELP + dbgwrite( snr_[n], sizeof( float ), 320, 1, fname( debug_dir, "snr", n, id, ENC ) ); +#endif + dbgwrite( &st->sp_aud_decision0, sizeof( int16_t ), 1, input_frame, fname( debug_dir, "sp_aud_decision0", n, id, ENC ) ); + dbgwrite( &st->sp_aud_decision1, sizeof( int16_t ), 1, input_frame, fname( debug_dir, "sp_aud_decision1", n, id, ENC ) ); + dbgwrite( &st->sp_aud_decision2, sizeof( int16_t ), 1, input_frame, fname( debug_dir, "sp_aud_decision2", n, id, ENC ) ); + + dbgwrite( &st->lp_noise, sizeof( float ), 1, input_frame, fname( debug_dir, "lp_noise", n, id, ENC ) ); + +#if ( defined DEBUG_MODE_ACELP ) || ( defined DEBUG_MODE_TCX ) + if ( st->coder_type == INACTIVE || st->coder_type == UNVOICED ) + { + _pitch[0] = 0; + _pitch[1] = 0; + _pitch[2] = 0; + } + else + { + _pitch[0] = st->pitch[0]; + _pitch[1] = st->pitch[1]; + _pitch[2] = st->pitch[2]; + } + dbgwrite( &_pitch[0], sizeof( int16_t ), 1, ( input_frame / 8 * 3 ), fname( debug_dir, "pitch", n, id, ENC ) ); + dbgwrite( &_pitch[1], sizeof( int16_t ), 1, ( input_frame / 8 * 3 ), fname( debug_dir, "pitch", n, id, ENC ) ); + dbgwrite( &_pitch[2], sizeof( int16_t ), 1, ( input_frame / 8 * 2 ), fname( debug_dir, "pitch", n, id, ENC ) ); + + if ( ( st->coder_type == INACTIVE ) || ( st->coder_type == UNVOICED ) ) + { + set_s( _pitch_buf, 0, NB_SUBFR16k ); + } + else if ( st->L_frame != L_FRAME ) + { + for ( k = 0; k < NB_SUBFR16k; k++ ) + _pitch_buf[k] = (int16_t) ( pitch_buf[n][k] + 0.5f ); + } + else + { + for ( k = 0; k < NB_SUBFR; k++ ) + _pitch_buf[k] = (int16_t) ( pitch_buf[n][k] * 5.0f / 4.0f + 0.5f ); + } + if ( st->L_frame != L_FRAME ) + { + for ( k = 0; k < NB_SUBFR16k; k++ ) + dbgwrite( &_pitch_buf[k], sizeof( int16_t ), 1, L_SUBFR, fname( debug_dir, "pitchCL", n, id, ENC ) ); + } + else + { + for ( k = 0; k < NB_SUBFR; k++ ) + dbgwrite( &_pitch_buf[k], sizeof( int16_t ), 1, L_SUBFR16k, fname( debug_dir, "pitchCL", n, id, ENC ) ); + } +#endif + +#ifdef DEBUG_MODE_ACELP + if ( st->core != ACELP_CORE ) + { + tmpF = 0.0f; + dbgwrite( &tmpF, sizeof( float ), 1, st->L_frame, fname( debug_dir, "exc.enc", n, id, ENC ) ); + dbgwrite( &tmpF, sizeof( float ), 1, st->L_frame, fname( debug_dir, "resid", n, id, ENC ) ); + } + if ( n_CoreChannels == 1 ) + { + tmpS = -1; + dbgwrite( &tmpS, sizeof( int16_t ), 1, input_frame, fname( debug_dir, "coder_type", 2, id, ENC ) ); + tmpF = 0.0f; + dbgwrite( &tmpF, sizeof( float ), 1, input_frame, fname( debug_dir, "total_brate", 2, id, ENC ) ); + tmpF = 0.0f; + dbgwrite( &tmpF, sizeof( float ), 1, input_frame, fname( debug_dir, "core_brate", 2, id, ENC ) ); + tmpF = 0.0f; + dbgwrite( &tmpF, sizeof( float ), 1, input_frame, fname( debug_dir, "extl_brate", 2, id, ENC ) ); + dbgwrite( &tmpS, sizeof( int16_t ), 1, input_frame, fname( debug_dir, "vad_flag", 2, id, ENC ) ); + dbgwrite( &tmpS, sizeof( int16_t ), 1, input_frame, fname( debug_dir, "localVAD", 2, id, ENC ) ); + } + +#endif + } +#endif pop_wmops(); diff --git a/lib_enc/ivas_core_pre_proc.c b/lib_enc/ivas_core_pre_proc.c index 35f3eace6..129177c0c 100644 --- a/lib_enc/ivas_core_pre_proc.c +++ b/lib_enc/ivas_core_pre_proc.c @@ -32,6 +32,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "ivas_cnst.h" #include "ivas_prot.h" @@ -464,6 +467,10 @@ ivas_error pre_proc_ivas( } } +#ifdef DEBUG_MODE_ACELP + dbgwrite( inp_12k8, sizeof( float ), L_FRAME, 1, fname( debug_dir, "inp_12k8", st->idchan, st->id_element, ENC ) ); + dbgwrite( inp_16k, sizeof( float ), L_FRAME, 1, fname( debug_dir, "inp_16k", st->idchan, st->id_element, ENC ) ); +#endif pop_wmops(); return error; @@ -600,6 +607,12 @@ ivas_error ivas_compute_core_buffers( set_f( temp1F_icatdmResampBuf, 0, L_FILT_MAX ); modify_Fs( temp1F_icatdmResampBuf, NS2SA( input_Fs, DELAY_FIR_RESAMPL_NS ), input_Fs, new_inp_16k + NS2SA( sr_core, FRAME_SIZE_NS ), sr_core, mem_decim16k_dummy, 0 ); } +#ifdef DEBUGGING + else + { + return ( IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Wrong internal sampling rate. Exiting..." ) ); + } +#endif } else if ( st->idchan == 0 ) { diff --git a/lib_enc/ivas_core_pre_proc_front.c b/lib_enc/ivas_core_pre_proc_front.c index d938cf0b1..d0dbd1603 100644 --- a/lib_enc/ivas_core_pre_proc_front.c +++ b/lib_enc/ivas_core_pre_proc_front.c @@ -32,6 +32,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "ivas_cnst.h" #include "rom_enc.h" @@ -722,6 +725,21 @@ ivas_error pre_proc_front_ivas( smc_dec = ivas_smc_gmm( st, hStereoClassif, localVAD_HE_SAD, Etot, lsp_new, *cor_map_sum, epsP, PS, non_staX, *relE, &high_lpn_flag, flag_spitch ); +#ifdef DEBUGGING + if ( st->idchan == 0 ) + { + if ( st->force == FORCE_SPEECH ) + { + /* enforce speech */ + st->sp_aud_decision0 = 0; + } + else if ( st->force == FORCE_MUSIC ) + { + /* enforce music */ + st->sp_aud_decision0 = 1; + } + } +#endif /*----------------------------------------------------------------* * VAD energy updates diff --git a/lib_enc/ivas_corecoder_enc_reconfig.c b/lib_enc/ivas_corecoder_enc_reconfig.c index bb79c0bd9..8619b1122 100644 --- a/lib_enc/ivas_corecoder_enc_reconfig.c +++ b/lib_enc/ivas_corecoder_enc_reconfig.c @@ -35,6 +35,10 @@ #include "ivas_cnst.h" #include "prot.h" #include "ivas_prot.h" +#ifdef DEBUGGING +#include "debug.h" +#include +#endif #include "wmc_auto.h" /*-------------------------------------------------------------------* @@ -145,6 +149,12 @@ ivas_error ivas_corecoder_enc_reconfig( { hBstr = st_ivas->hCPE[0]->hCoreCoder[0]->hBstr; } +#ifdef DEBUGGING + else + { + assert( 0 && "At least one SCE or one CPE should have existed before!\n" ); + } +#endif /* save bitstream information */ nb_bits_tot = hBstr->nb_bits_tot; @@ -173,6 +183,9 @@ ivas_error ivas_corecoder_enc_reconfig( temp_ind_list[i].nb_bits = -1; } +#ifdef DEBUGGING + assert( ( nb_bits == nb_bits_tot ) && "Error saving bitstream information during core-coder reconfiguration!\n" ); +#endif if ( hEncoderConfig->ivas_format == MC_FORMAT && last_mc_mode == MC_MODE_MCMASA && st_ivas->mc_mode == MC_MODE_MCMASA ) { @@ -383,6 +396,9 @@ ivas_error ivas_corecoder_enc_reconfig( st_ivas->hCPE[0]->hCoreCoder[0]->hBstr->nb_bits_tot = nb_bits_tot; } +#ifdef DEBUGGING + assert( ( nb_bits == nb_bits_tot ) && "Error restoring bitstream information during core-coder reconfiguration!\n" ); +#endif if ( last_mc_mode == MC_MODE_MCMASA && st_ivas->mc_mode == MC_MODE_MCMASA ) @@ -482,6 +498,9 @@ ivas_error ivas_corecoder_enc_reconfig( st_ivas->hCPE[0]->hCoreCoder[n]->mct_chan_mode = MCT_CHAN_MODE_REGULAR; } +#ifdef DEBUGGING + st_ivas->hCPE[st_ivas->nCPE - 1]->hStereoMdct->mdct_stereo_mode_cmdl = hEncoderConfig->stereo_mode_cmdl; +#endif initMdctStereoEncData( st_ivas->hCPE[st_ivas->nCPE - 1]->hStereoMdct, hEncoderConfig->ivas_format, st_ivas->hCPE[st_ivas->nCPE - 1]->element_mode, st_ivas->hCPE[st_ivas->nCPE - 1]->element_brate, hEncoderConfig->max_bwidth, 0, NULL, 1 ); st_ivas->hCPE[st_ivas->nCPE - 1]->hStereoMdct->isSBAStereoMode = ( ( hEncoderConfig->ivas_format == SBA_FORMAT || hEncoderConfig->ivas_format == SBA_ISM_FORMAT ) && ( st_ivas->nchan_transport == 2 ) ); } diff --git a/lib_enc/ivas_cpe_enc.c b/lib_enc/ivas_cpe_enc.c index 9e2da33be..251ef2a32 100644 --- a/lib_enc/ivas_cpe_enc.c +++ b/lib_enc/ivas_cpe_enc.c @@ -39,6 +39,9 @@ #include "prot.h" #include "ivas_prot.h" #include "ivas_rom_com.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" @@ -131,6 +134,12 @@ ivas_error ivas_cpe_enc( tdm_ratio_idx_SM = -1; tdm_last_ratio = 0; +#ifdef DEBUGGING + if ( hCPE->hCoreCoder[0]->ini_frame == 0 ) + { + hCPE->stereo_mode_cmdl = hEncoderConfig->stereo_mode_cmdl; + } +#endif /*------------------------------------------------------------------* * CPE initialization - core coder @@ -148,6 +157,10 @@ ivas_error ivas_cpe_enc( sts[n]->bwidth = sts[n]->last_bwidth; /* updated in BWD */ } sts[n]->rate_switching_reset = 0; +#ifdef DEBUGGING + sts[n]->force = hEncoderConfig->force; + sts[n]->id_element = cpe_id + st_ivas->nSCE; +#endif } mvr2r( data_f_ch0, sts[0]->input, input_frame ); @@ -340,6 +353,9 @@ ivas_error ivas_cpe_enc( /* reconfiguration in case of bitrate switching */ if ( hCPE->element_brate != hCPE->last_element_brate && st_ivas->hMCT == NULL ) { +#ifdef DEBUGGING + hCPE->hStereoMdct->mdct_stereo_mode_cmdl = hEncoderConfig->mdct_stereo_mode_cmdl; +#endif initMdctStereoEncData( hCPE->hStereoMdct, ivas_format, hCPE->element_mode, hCPE->element_brate, max_bwidth, 0, NULL, 0 ); hCPE->hStereoMdct->isSBAStereoMode = ( ( ivas_format == SBA_FORMAT || ivas_format == SBA_ISM_FORMAT ) && ( st_ivas->nchan_transport == 2 ) ); } @@ -355,12 +371,19 @@ ivas_error ivas_cpe_enc( stereo_dft_hybrid_ITD_flag( hCPE->hStereoDft->hConfig, input_Fs, hCPE->hStereoDft->hItd->hybrid_itd_max ); /* Time Domain ITD compensation using extrapolation */ +#ifdef DEBUG_MODE_DFT + stereo_td_itd( hCPE->hStereoDft->hItd, hCPE->hStereoDft->input_mem_itd, hCPE->hStereoDft->hConfig->hybrid_itd_flag, hCPE->hStereoDft->hConfig->itd_mode, hCPE->hStereoDft->dft_ovl, sts, input_frame, hCPE->input_mem ); +#else stereo_td_itd( hCPE->hStereoDft->hItd, hCPE->hStereoDft->input_mem_itd, hCPE->hStereoDft->hConfig->hybrid_itd_flag, hCPE->hStereoDft->dft_ovl, sts, input_frame, hCPE->input_mem ); +#endif /* DFT on right and left input channels */ stereo_dft_enc_analyze( sts, CPE_CHANNELS, input_frame, hCPE->hStereoDft, NULL, hCPE->hStereoDft->DFT, hCPE->input_mem ); sts[0]->total_brate = ( sts[0]->bits_frame_nominal + 10 ) * FRAMES_PER_SEC; /* add small overhead; st[0]->total_brate used in coder_type_modif() */ +#ifdef DEBUG_MODE_DFT + hCPE->hStereoDft->res_cod_bits = (int16_t) ( ( hCPE->element_brate ) / FRAMES_PER_SEC - 0.8f * sts[0]->bits_frame_nominal ); +#endif /* Update DFT Stereo memories */ stereo_dft_enc_update( hCPE->hStereoDft, sts[0]->max_bwidth ); @@ -434,6 +457,13 @@ ivas_error ivas_cpe_enc( set_zero( sts[1]->input, input_frame ); } +#ifdef DEBUG_MODE_INFO + for ( n = 0; n < n_CoreChannels; n++ ) + { + dbgwrite( sts[0]->input - NS2SA( sts[0]->input_Fs, ACELP_LOOK_NS ), sizeof( float ), input_frame, 1, fname( debug_dir, "input_DMX", n, sts[n]->id_element, ENC ) ); + } + dbgwrite( &hCPE->element_mode, sizeof( int16_t ), 1, input_frame, fname( debug_dir, "element_mode", 0, sts[0]->id_element, ENC ) ); +#endif /*----------------------------------------------------------------* * Front Pre-processing @@ -592,6 +622,9 @@ ivas_error ivas_cpe_enc( } stereo_dft_cng_side_gain( hCPE->hStereoDft, hCPE->hStereoCng, sts[0]->core_brate, sts[0]->last_core_brate, sts[0]->bwidth ); +#ifdef DEBUG_MODE_DFT + hCPE->hStereoDft->res_cod_bits = 0; +#endif } else { @@ -623,10 +656,14 @@ ivas_error ivas_cpe_enc( if ( ivas_format == MASA_FORMAT || ivas_format == MASA_ISM_FORMAT ) { max_bits -= nb_bits_metadata; +#ifdef NONBE_FIX_913_OMASA_BITBUDGET_VIOLATION if ( hCPE->brate_surplus < 0 ) { +#endif max_bits += (int16_t) ( hCPE->brate_surplus / FRAMES_PER_SEC ); +#ifdef NONBE_FIX_913_OMASA_BITBUDGET_VIOLATION } +#endif } stereo_dft_enc_res( hCPE->hStereoDft, old_inp_12k8[1] + L_INP_MEM - STEREO_DFT_OVL_8k, hCPE->hMetaData, &nb_bits, max_bits ); @@ -638,6 +675,22 @@ ivas_error ivas_cpe_enc( } else { +#ifdef NONBE_FIX_913_OMASA_BITBUDGET_VIOLATION +#ifdef DEBUGGING + if ( ivas_format == MASA_FORMAT || ivas_format == MASA_ISM_FORMAT ) + { + assert( ( ( hCPE->element_brate / FRAMES_PER_SEC - nb_bits - nb_bits_metadata + (int16_t) ( hCPE->brate_surplus / FRAMES_PER_SEC ) ) >= ( 0.8f * sts[0]->bits_frame_nominal ) ) && "Stereo DFT: bit budget is violated" ); + } + else + { + assert( ( ( hCPE->element_brate / FRAMES_PER_SEC - nb_bits ) >= ( 0.8f * sts[0]->bits_frame_nominal ) ) && "Stereo DFT: bit budget is violated" ); + } + +#endif +#else + assert( ( ( hCPE->element_brate / FRAMES_PER_SEC - nb_bits ) >= ( 0.8f * sts[0]->bits_frame_nominal ) ) && "Stereo DFT: bit budget is violated" ); + +#endif /* Flexible total bitrate in M channel */ sts[0]->total_brate = hCPE->element_brate - ( nb_bits * FRAMES_PER_SEC ); } @@ -707,6 +760,41 @@ ivas_error ivas_cpe_enc( sts[n]->hTranDet->transientDetector.prev_bIsAttackPresent = sts[n]->hTranDet->transientDetector.bIsAttackPresent; } +#ifdef DEBUG_MODE_INFO + if ( hCPE->element_mode == IVAS_CPE_DFT ) + { + n = (int16_t) hCPE->hStereoDft->hItd->itd[1]; + dbgwrite( &n, 2, 1, input_frame, "res/itd" ); + n = 0; + dbgwrite( &n, 2, 1, input_frame, "res/TCA_idx_refChan" ); + dbgwrite( &n, 2, 1, input_frame, "res/TCA_idx_NCShift" ); + dbgwrite( &n, 2, 1, input_frame, "res/TCA_idx_ica_gD" ); + n = -1; + // dbgwrite( &n, 2, 1, input_frame, "res/tdm_ratio_idx.enc" ); + } + else if ( hCPE->element_mode == IVAS_CPE_TD ) + { + dbgwrite( &hCPE->hStereoTCA->refChanIndx, 2, 1, input_frame, "res/TCA_idx_refChan" ); + n = hCPE->hStereoTCA->refChanIndx == 0 ? hCPE->hStereoTCA->indx_ica_NCShift : -hCPE->hStereoTCA->indx_ica_NCShift; + dbgwrite( &n, 2, 1, input_frame, "res/TCA_idx_NCShift" ); + dbgwrite( &hCPE->hStereoTCA->indx_ica_gD, 2, 1, input_frame, "res/TCA_idx_ica_gD" ); + + n = hCPE->hStereoTCA->corrLagStats[2]; + dbgwrite( &n, 2, 1, input_frame, "res/itd" ); + + dbgwrite( &tdm_ratio_idx, 2, 1, input_frame, "res/tdm_ratio_idx.enc" ); + } + else if ( hCPE->element_mode == IVAS_CPE_MDCT ) + { + n = -2; + // dbgwrite( &n, 2, 1, input_frame, "res/tdm_ratio_idx.enc" ); + } + + { + float tmpF = ivas_total_brate / 1000.0f; + dbgwrite( &tmpF, sizeof( float ), 1, input_frame, fname( debug_dir, "element_brate", 0, cpe_id, ENC ) ); + } +#endif pop_wmops(); return error; @@ -868,7 +956,11 @@ ivas_error create_cpe_enc( hCPE->hStereoCng = NULL; } +#ifdef DEBUGGING + if ( hEncoderConfig->Opt_DTX_ON && ( hCPE->element_mode == IVAS_CPE_TD || hEncoderConfig->stereo_mode_cmdl == 1 ) && !( ivas_format == MASA_FORMAT && element_mode_init == IVAS_CPE_MDCT ) ) +#else if ( hEncoderConfig->Opt_DTX_ON && element_mode_init != IVAS_CPE_MDCT ) +#endif { for ( n = 0; n < CPE_CHANNELS; n++ ) { @@ -951,6 +1043,9 @@ ivas_error create_cpe_enc( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for MDCT Stereo \n" ) ); } +#ifdef DEBUGGING + hCPE->hStereoMdct->mdct_stereo_mode_cmdl = st_ivas->hEncoderConfig->mdct_stereo_mode_cmdl; +#endif initMdctStereoEncData( hCPE->hStereoMdct, ivas_format, hCPE->element_mode, hCPE->element_brate, max_bwidth, 0, NULL, 1 ); hCPE->hStereoMdct->isSBAStereoMode = ( ( ivas_format == SBA_FORMAT || ivas_format == SBA_ISM_FORMAT ) && ( st_ivas->nchan_transport == 2 ) ); diff --git a/lib_enc/ivas_decision_matrix_enc.c b/lib_enc/ivas_decision_matrix_enc.c index afa2d2d00..b9578423b 100644 --- a/lib_enc/ivas_decision_matrix_enc.c +++ b/lib_enc/ivas_decision_matrix_enc.c @@ -38,6 +38,9 @@ #include "prot.h" #include "ivas_prot.h" #include "ivas_rom_com.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" @@ -174,6 +177,39 @@ void ivas_decision_matrix_enc( st->core = TCX_20_CORE; } +#ifdef DEBUGGING + if ( st->idchan == 0 ) + { + if ( st->force == FORCE_SPEECH && st->element_mode != IVAS_CPE_MDCT && st->total_brate <= MAX_ACELP_BRATE ) + { + st->core = ACELP_CORE; + } + else if ( st->force == FORCE_MUSIC && st->core == ACELP_CORE ) + { + st->core = TCX_20_CORE; + } + else if ( st->force == FORCE_ACELP && st->element_mode != IVAS_CPE_MDCT && st->total_brate <= MAX_ACELP_BRATE ) + { + st->core = ACELP_CORE; + if ( st->coder_type == AUDIO ) + { + st->coder_type = GENERIC; + } + } + else if ( st->force == FORCE_GSC && element_brate < IVAS_24k4 ) + { + st->core = ACELP_CORE; + } + else if ( st->force == FORCE_TCX ) + { + st->core = TCX_20_CORE; + } + else if ( st->force == FORCE_HQ && st->element_mode != IVAS_CPE_MDCT && element_brate >= IVAS_24k4 ) + { + st->core = HQ_CORE; + } + } +#endif /* TCX not available at low bitrates -> replace it by GSC */ if ( st->core == TCX_20_CORE && st->total_brate < STEREO_TCX_MIN_RATE ) diff --git a/lib_enc/ivas_dirac_enc.c b/lib_enc/ivas_dirac_enc.c index 2c6f71d39..5c2493ec1 100644 --- a/lib_enc/ivas_dirac_enc.c +++ b/lib_enc/ivas_dirac_enc.c @@ -39,6 +39,9 @@ #include "ivas_prot.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" /*------------------------------------------------------------------------- @@ -694,6 +697,10 @@ void ivas_dirac_param_est_enc( } else { +#ifdef DEBUGGING + assert( pp_fr_real ); + assert( pp_fr_imag ); +#endif for ( i = 0; i < nchan_fb_in; i++ ) { mvr2r( &pp_fr_real[i][ts * l_ts], Cldfb_RealBuffer[i], l_ts ); @@ -749,6 +756,9 @@ void ivas_dirac_param_est_enc( if ( hodirac_flag ) { +#ifdef DEBUGGING + assert( l_ts <= DIRAC_NO_FB_BANDS_MAX ); +#endif calculate_hodirac_sector_parameters( hDirAC, Cldfb_RealBuffer, @@ -866,6 +876,100 @@ void ivas_dirac_param_est_enc( } } +#ifdef DEBUG_SBA_MD_DUMP + { + char f_name[100]; + int16_t num_subframes = 1, num_block_groups = 1, num_elements = 1, byte_size = sizeof( float ); + sprintf( f_name, "dirac_enc_diffuseness.bin" ); + ( frame == 0 ) ? dbgwrite( &hDirAC->hConfig->nbands, sizeof( hDirAC->hConfig->nbands ), 1, 1, f_name ) : false; + ( frame == 0 ) ? dbgwrite( &num_elements, sizeof( num_elements ), 1, 1, f_name ) : false; + ( frame == 0 ) ? dbgwrite( &num_subframes, sizeof( num_subframes ), 1, 1, f_name ) : false; + ( frame == 0 ) ? dbgwrite( &num_block_groups, sizeof( num_block_groups ), 1, 1, f_name ) : false; + ( frame == 0 ) ? dbgwrite( &byte_size, sizeof( byte_size ), 1, 1, f_name ) : false; + dbgwrite( hDirAC->diffuseness_m, sizeof( float ), hDirAC->hConfig->nbands, 1, f_name ); + sprintf( f_name, "dirac_reference_power.bin" ); + ( frame == 0 ) ? dbgwrite( &hDirAC->hConfig->nbands, sizeof( hDirAC->hConfig->nbands ), 1, 1, f_name ) : false; + num_elements = hDirAC->block_grouping[1] - hDirAC->block_grouping[0]; + ( frame == 0 ) ? dbgwrite( &num_elements, sizeof( num_elements ), 1, 1, f_name ) : false; + ( frame == 0 ) ? dbgwrite( &num_subframes, sizeof( num_subframes ), 1, 1, f_name ) : false; + num_block_groups = hDirAC->block_grouping[1]; + ( frame == 0 ) ? dbgwrite( &num_block_groups, sizeof( num_block_groups ), 1, 1, f_name ) : false; + ( frame == 0 ) ? dbgwrite( &byte_size, sizeof( byte_size ), 1, 1, f_name ) : false; + for ( ts = hDirAC->block_grouping[0]; ts < hDirAC->block_grouping[1]; ts++ ) + { + dbgwrite( reference_power[ts], sizeof( float ), hDirAC->hConfig->nbands, 1, f_name ); + } + num_elements = 1; + num_subframes = MAX_PARAM_SPATIAL_SUBFRAMES; + num_block_groups = 1; + sprintf( f_name, "dirac_enc_dir0.bin" ); + ( frame == 0 ) ? dbgwrite( &hDirAC->hConfig->nbands, sizeof( hDirAC->hConfig->nbands ), 1, 1, f_name ) : false; + ( frame == 0 ) ? dbgwrite( &num_elements, sizeof( num_elements ), 1, 1, f_name ) : false; + ( frame == 0 ) ? dbgwrite( &num_subframes, sizeof( num_subframes ), 1, 1, f_name ) : false; + ( frame == 0 ) ? dbgwrite( &num_block_groups, sizeof( num_block_groups ), 1, 1, f_name ) : false; + ( frame == 0 ) ? dbgwrite( &byte_size, sizeof( byte_size ), 1, 1, f_name ) : false; + for ( block_m_idx = 0; block_m_idx < MAX_PARAM_SPATIAL_SUBFRAMES; block_m_idx++ ) + { + dbgwrite( hDirAC->direction_vector_m[0][block_m_idx], sizeof( float ), hDirAC->hConfig->nbands, 1, f_name ); + } + sprintf( f_name, "dirac_enc_dir1.bin" ); + ( frame == 0 ) ? dbgwrite( &hDirAC->hConfig->nbands, sizeof( hDirAC->hConfig->nbands ), 1, 1, f_name ) : false; + ( frame == 0 ) ? dbgwrite( &num_elements, sizeof( num_elements ), 1, 1, f_name ) : false; + ( frame == 0 ) ? dbgwrite( &num_subframes, sizeof( num_subframes ), 1, 1, f_name ) : false; + ( frame == 0 ) ? dbgwrite( &num_block_groups, sizeof( num_block_groups ), 1, 1, f_name ) : false; + ( frame == 0 ) ? dbgwrite( &byte_size, sizeof( byte_size ), 1, 1, f_name ) : false; + for ( block_m_idx = 0; block_m_idx < MAX_PARAM_SPATIAL_SUBFRAMES; block_m_idx++ ) + { + dbgwrite( hDirAC->direction_vector_m[1][block_m_idx], sizeof( float ), hDirAC->hConfig->nbands, 1, f_name ); + } + sprintf( f_name, "dirac_enc_dir2.bin" ); + ( frame == 0 ) ? dbgwrite( &hDirAC->hConfig->nbands, sizeof( hDirAC->hConfig->nbands ), 1, 1, f_name ) : false; + ( frame == 0 ) ? dbgwrite( &num_elements, sizeof( num_elements ), 1, 1, f_name ) : false; + ( frame == 0 ) ? dbgwrite( &num_subframes, sizeof( num_subframes ), 1, 1, f_name ) : false; + ( frame == 0 ) ? dbgwrite( &num_block_groups, sizeof( num_block_groups ), 1, 1, f_name ) : false; + ( frame == 0 ) ? dbgwrite( &byte_size, sizeof( byte_size ), 1, 1, f_name ) : false; + for ( block_m_idx = 0; block_m_idx < MAX_PARAM_SPATIAL_SUBFRAMES; block_m_idx++ ) + { + dbgwrite( hDirAC->direction_vector_m[2][block_m_idx], sizeof( float ), hDirAC->hConfig->nbands, 1, f_name ); + } + } +#endif +#ifdef DEBUG_MODE_DIRAC + { + static FILE *fp_direction_vector = NULL, *fp_diffuseness = NULL, *fp_referencePower = NULL; + + if ( fp_direction_vector == NULL ) + fp_direction_vector = fopen( "./res/dbg_direction_vector_C.bin", "wb" ); + if ( fp_diffuseness == NULL ) + fp_diffuseness = fopen( "./res/dbg_diffuseness_C.bin", "wb" ); + if ( fp_referencePower == NULL ) + fp_referencePower = fopen( "./res/dbg_reference_power_C.bin", "wb" ); + + dbgwrite( hDirAC->diffuseness_m, sizeof( float ), hDirAC->hConfig->nbands, 1, "./res/dirac_enc_diffuseness.dat" ); + for ( block_m_idx = 0; block_m_idx < MAX_PARAM_SPATIAL_SUBFRAMES; block_m_idx++ ) + { + dbgwrite( hDirAC->direction_vector_m[0][block_m_idx], sizeof( float ), hDirAC->hConfig->nbands, 1, "./res/dirac_enc_dir0.dat" ); + dbgwrite( hDirAC->direction_vector_m[1][block_m_idx], sizeof( float ), hDirAC->hConfig->nbands, 1, "./res/dirac_enc_dir1.dat" ); + dbgwrite( hDirAC->direction_vector_m[2][block_m_idx], sizeof( float ), hDirAC->hConfig->nbands, 1, "./res/dirac_enc_dir2.dat" ); + + for ( ts = hDirAC->block_grouping[block_m_idx]; ts < hDirAC->block_grouping[block_m_idx + 1]; ts++ ) + { + for ( band_m_idx = 0; band_m_idx < hDirAC->hConfig->nbands; band_m_idx++ ) + { + for ( i = hDirAC->band_grouping[band_m_idx]; i < hDirAC->band_grouping[band_m_idx + 1]; i++ ) + { + for ( d = 0; d < DIRAC_NUM_DIMS; d++ ) + { + fwrite( &( hDirAC->direction_vector_m[d][block_m_idx][band_m_idx] ), sizeof( float ), 1, fp_direction_vector ); + } + fwrite( &( hDirAC->diffuseness_m[band_m_idx] ), sizeof( float ), 1, fp_diffuseness ); + fwrite( &( reference_power[ts][band_m_idx] ), sizeof( float ), 1, fp_referencePower ); + } + } + } + } + } +#endif pop_wmops(); return; } diff --git a/lib_enc/ivas_enc.c b/lib_enc/ivas_enc.c index 0672aeda8..c52a722c2 100644 --- a/lib_enc/ivas_enc.c +++ b/lib_enc/ivas_enc.c @@ -38,6 +38,9 @@ #include "prot.h" #include "ivas_prot.h" #include "ivas_rom_com.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" /*-------------------------------------------------------------------* @@ -93,6 +96,17 @@ ivas_error ivas_enc( n = 0; while ( n < nchan_inp ) { +#ifdef DEBUG_MODE_LFE + if ( n == LFE_CHANNEL ) + { + int16_t tmp[L_FRAME48k]; + for ( i = 0; i < n_samples_chan; i++ ) + { + tmp[i] = data[i * nchan_inp + n]; + } + dbgwrite( tmp, sizeof( int16_t ), n_samples_chan, 1, "./lfe_chan_in.raw" ); + } +#endif for ( i = 0; i < n_samples_chan; i++ ) { data_f[n][i] = (float) data[i * nchan_inp + n]; @@ -108,6 +122,9 @@ ivas_error ivas_enc( } } +#ifdef DEBUG_MODE_LFE + dbgwrite( data_f[LFE_CHANNEL], sizeof( float ), n_samples_chan, 1, "./res/lfe_input" ); +#endif if ( ivas_format == SBA_FORMAT ) { @@ -130,6 +147,7 @@ ivas_error ivas_enc( n = getNumChanAnalysis( st_ivas ); +#ifndef DEBUG_SPAR_BYPASS_EVS_CODEC /* bypass EVS coding in float precision, emulating EVS encoder/decoder delay */ for ( i = 0; i < n; i++ ) { @@ -142,6 +160,7 @@ ivas_error ivas_enc( hp20( data_f[i], input_frame, st_ivas->mem_hp20_in[i], input_Fs ); } } +#endif /*----------------------------------------------------------------* * write IVAS format signaling @@ -334,7 +353,11 @@ ivas_error ivas_enc( } /* Configuration of combined-format bit-budget distribution */ +#ifdef DEBUG_MODE_INFO + ivas_set_surplus_brate_enc( st_ivas, nb_bits_metadata ); +#else ivas_set_surplus_brate_enc( st_ivas ); +#endif /* Encode MASA transport channels */ if ( ( ivas_cpe_enc( st_ivas, 0, data_f[n], data_f[n + 1], input_frame, nb_bits_metadata[0] ) ) != IVAS_ERR_OK ) @@ -530,6 +553,12 @@ ivas_error ivas_enc( hEncoderConfig->last_ivas_total_brate = ivas_total_brate; +#ifdef DEBUG_MODE_INFO + { + float tmpF = ivas_total_brate / 1000.0f; + dbgwrite( &tmpF, sizeof( float ), 1, input_frame, "res/ivas_total_brate" ); + } +#endif pop_wmops(); return error; diff --git a/lib_enc/ivas_enc_cov_handler.c b/lib_enc/ivas_enc_cov_handler.c index d4e82c6d9..0eb88dcc1 100644 --- a/lib_enc/ivas_enc_cov_handler.c +++ b/lib_enc/ivas_enc_cov_handler.c @@ -35,6 +35,9 @@ #include "prot.h" #include "ivas_prot.h" #include "ivas_rom_com.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" /*------------------------------------------------------------------------------------------* @@ -308,6 +311,29 @@ void ivas_enc_cov_handler_process( } } +#ifdef DEBUG_SPAR_WRITE_OUT_COV + { + static FILE *fid = 0; + int16_t k = 0; + float tmp_buf[10]; + if ( !fid ) + { + fid = fopen( "cov_real.txt", "wt" ); + } + + for ( i = 0; i < num_ch; i++ ) + { + for ( j = 0; j < num_ch; j++ ) + { + for ( k = start_band; k < end_band; k++ ) + { + fprintf( fid, "%.6f\n", cov_real[i][j][k] ); + } + } + } + fprintf( fid, "\n" ); + } +#endif for ( i = 0; i < num_ch; i++ ) { for ( j = 0; j < num_ch; j++ ) diff --git a/lib_enc/ivas_entropy_coder.c b/lib_enc/ivas_entropy_coder.c index e118c7271..0157711bd 100644 --- a/lib_enc/ivas_entropy_coder.c +++ b/lib_enc/ivas_entropy_coder.c @@ -33,6 +33,9 @@ #include #include "options.h" #include "ivas_cnst.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "prot.h" #include "ivas_prot.h" #include "ivas_rom_com.h" diff --git a/lib_enc/ivas_front_vad.c b/lib_enc/ivas_front_vad.c index 4dcf2cd61..52c3b8cd4 100644 --- a/lib_enc/ivas_front_vad.c +++ b/lib_enc/ivas_front_vad.c @@ -32,6 +32,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "ivas_cnst.h" #include "rom_enc.h" @@ -144,6 +147,13 @@ ivas_error front_vad( /* Only run VAD if DTX is on and TD stereo or unified stereo is selected */ if ( hFrontVads[0] != NULL && element_mode != IVAS_CPE_MDCT ) { +#ifdef DEBUGGING + /* If stereo switching is not enabled and TD is selected restore element_mode to TD every frame before the VAD */ + if ( hCPE != NULL && hCPE->stereo_mode_cmdl == IVAS_CPE_TD ) + { + hCPE->element_mode = IVAS_CPE_TD; + } +#endif /*------------------------------------------------------------------* * VAD diff --git a/lib_enc/ivas_init_enc.c b/lib_enc/ivas_init_enc.c index ba4e0eaa1..e1aa7113a 100644 --- a/lib_enc/ivas_init_enc.c +++ b/lib_enc/ivas_init_enc.c @@ -38,6 +38,9 @@ #include "ivas_prot.h" #include "ivas_stat_enc.h" #include "ivas_rom_com.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" @@ -271,6 +274,9 @@ void copy_encoder_config( st->rf_fec_offset = st_ivas->hEncoderConfig->rf_fec_offset; st->rf_fec_indicator = st_ivas->hEncoderConfig->rf_fec_indicator; +#ifdef DEBUGGING + st->force = st_ivas->hEncoderConfig->force; +#endif st->element_mode = st_ivas->hEncoderConfig->element_mode_init; return; @@ -875,6 +881,12 @@ ivas_error ivas_init_encoder( } } } +#ifdef DEBUGGING + else + { + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Error: Invalid IVAS format. Exiting.\n" ); + } +#endif /*-----------------------------------------------------------------* * Allocate and initialize HP20 filter memories diff --git a/lib_enc/ivas_ism_dtx_enc.c b/lib_enc/ivas_ism_dtx_enc.c index 60737e731..1277d0d88 100644 --- a/lib_enc/ivas_ism_dtx_enc.c +++ b/lib_enc/ivas_ism_dtx_enc.c @@ -36,6 +36,9 @@ #include "ivas_cnst.h" #include "prot.h" #include "ivas_prot.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" diff --git a/lib_enc/ivas_ism_enc.c b/lib_enc/ivas_ism_enc.c index 5f34a92a9..db689cc9f 100644 --- a/lib_enc/ivas_ism_enc.c +++ b/lib_enc/ivas_ism_enc.c @@ -36,6 +36,9 @@ #include "prot.h" #include "ivas_prot.h" #include "ivas_stat_enc.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" @@ -144,6 +147,10 @@ ivas_error ivas_ism_enc( st->input_bwidth = st->last_input_bwidth; /* updated in BWD */ st->bwidth = st->last_bwidth; /* updated in BWD */ st->rate_switching_reset = 0; +#ifdef DEBUGGING + st->force = st_ivas->hEncoderConfig->force; + st->id_element = sce_id; +#endif /*---------------------------------------------------------------* * Time Domain Transient Detector @@ -202,6 +209,13 @@ ivas_error ivas_ism_enc( ivas_ism_coh_estim_dtx_enc( st_ivas->hISMDTX, st_ivas->hSCE, st_ivas->nchan_transport, input_frame ); } +#ifdef DEBUG_MODE_PARAM_ISM + if ( st_ivas->hParamIsmDec != NULL ) + dbgwrite( &( st_ivas->hParamIsmDec->hParamIsm->flag_noisy_speech ), sizeof( int16_t ), 1, 1, "./res/ParamISM_noisy_speech_flag_enc.dat" ); + dbgwrite( &( st_ivas->hISMDTX->dtx_flag ), sizeof( int16_t ), 1, 1, "./res/ParamISM_DTX_CNG_flag_enc.dat" ); + dbgwrite( &( st_ivas->hISMDTX->sce_id_dtx ), sizeof( int16_t ), 1, input_frame, "./res/sce_id_dtx" ); + dbgwrite( &( dtx_flag ), sizeof( int16_t ), 1, input_frame, "./res/dtx_flag" ); +#endif } /*------------------------------------------------------------------* @@ -368,6 +382,40 @@ ivas_error ivas_ism_enc( } } +#ifdef DEBUG_MODE_INFO + if ( dtx_flag ) + { + float tmpF; + int16_t id, n; + + n = 0; + for ( sce_id = 0; sce_id < nchan_transport_ism; sce_id++ ) + { + if ( sce_id != st_ivas->hISMDTX->sce_id_dtx ) + { + st = st_ivas->hSCE[sce_id]->hCoreCoder[0]; + id = st->id_element; + + dbgwrite( &st->core, sizeof( int16_t ), 1, input_frame, fname( debug_dir, "core", n, id, ENC ) ); + dbgwrite( &st->extl, sizeof( int16_t ), 1, input_frame, fname( debug_dir, "extl", n, id, ENC ) ); + dbgwrite( &st->bwidth, sizeof( int16_t ), 1, input_frame, fname( debug_dir, "bwidth", n, id, ENC ) ); + tmpF = st->total_brate / 1000.0f; + dbgwrite( &tmpF, sizeof( float ), 1, input_frame, fname( debug_dir, "total_brate", n, id, ENC ) ); + tmpF = st->core_brate / 1000.0f; + dbgwrite( &tmpF, sizeof( float ), 1, input_frame, fname( debug_dir, "core_brate", n, id, ENC ) ); + tmpF = st->extl_brate / 1000.0f; + dbgwrite( &tmpF, sizeof( float ), 1, input_frame, fname( debug_dir, "extl_brate", n, id, ENC ) ); + + dbgwrite( &st->coder_type, sizeof( int16_t ), 1, input_frame, fname( debug_dir, "coder_type", n, id, ENC ) ); + dbgwrite( &st->coder_type_raw, sizeof( int16_t ), 1, input_frame, fname( debug_dir, "coder_type_raw", n, id, ENC ) ); + dbgwrite( &st->vad_flag, sizeof( int16_t ), 1, input_frame, fname( debug_dir, "vad_flag", n, id, ENC ) ); + dbgwrite( &st->localVAD, sizeof( int16_t ), 1, input_frame, fname( debug_dir, "localVAD", n, id, ENC ) ); + + dbgwrite( &st->lp_noise, sizeof( float ), 1, input_frame, fname( debug_dir, "lp_noise", n, id, ENC ) ); + } + } + } +#endif pop_wmops(); return error; diff --git a/lib_enc/ivas_ism_metadata_enc.c b/lib_enc/ivas_ism_metadata_enc.c index d272953a6..849b7957a 100644 --- a/lib_enc/ivas_ism_metadata_enc.c +++ b/lib_enc/ivas_ism_metadata_enc.c @@ -39,6 +39,9 @@ #include "ivas_rom_com.h" #include "prot.h" #include +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" diff --git a/lib_enc/ivas_ism_param_enc.c b/lib_enc/ivas_ism_param_enc.c index dd30d5828..6492c537a 100644 --- a/lib_enc/ivas_ism_param_enc.c +++ b/lib_enc/ivas_ism_param_enc.c @@ -142,6 +142,12 @@ static void ivas_param_ism_compute_obj_parameters( /* Power ratio range [0.5,1] is mapped to [0,1] first, rounding via truncation float->integer */ hParamIsm->power_ratios_idx[b][m] = (int16_t) ( ( ( power_ratios_m[b][m] - 0.5f ) * 2 ) * ( ( 1 << PARAM_ISM_POW_RATIO_NBITS ) - 1 ) + 0.5f ); assert( ( hParamIsm->power_ratios_idx[b][m] >= 0 ) && ( hParamIsm->power_ratios_idx[b][m] <= ( ( 1 << PARAM_ISM_POW_RATIO_NBITS ) - 1 ) ) ); +#ifdef DEBUG_MODE_PARAM_ISM + dbgwrite( ref_power_local, sizeof( float ), 3, 1, "res/ParamISM_refPowerLocal.dat" ); + dbgwrite( hParamIsm->obj_indices[b][m], sizeof( int16_t ), 2, 1, "res/ParamISM_objIndices.dat" ); + dbgwrite( &hParamIsm->power_ratios_idx[b][m], sizeof( int16_t ), 1, 1, "res/ParamISM_powerRatioIdx.dat" ); + dbgwrite( &power_ratios_m[b][m], sizeof( float ), 1, 1, "res/ParamISM_powerRatio.dat" ); +#endif } } diff --git a/lib_enc/ivas_lfe_enc.c b/lib_enc/ivas_lfe_enc.c index 0c7a1a21a..2ff49cb1f 100644 --- a/lib_enc/ivas_lfe_enc.c +++ b/lib_enc/ivas_lfe_enc.c @@ -37,6 +37,9 @@ #include "ivas_prot.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" diff --git a/lib_enc/ivas_masa_enc.c b/lib_enc/ivas_masa_enc.c index bc6993bc0..6019ee03c 100644 --- a/lib_enc/ivas_masa_enc.c +++ b/lib_enc/ivas_masa_enc.c @@ -3103,6 +3103,9 @@ static int16_t encode_ratio_ism_subframe( int16_t bits_index; int16_t nbits00, nbits11; int16_t idx_sep_obj_local; +#ifdef DEBUGGING + int16_t bits_pos0; +#endif idx_sep_obj_local = idx_separated_obj; if ( idx_separated_obj > -1 ) @@ -3116,6 +3119,9 @@ static int16_t encode_ratio_ism_subframe( nbits0 = 0; nbits1 = 0; +#ifdef DEBUGGING + bits_pos0 = hMetaData->nb_bits_tot; +#endif differential_subframe = 1; /* the differences are taken with respect to previous subframe */ /* first subframe */ @@ -3151,6 +3157,9 @@ static int16_t encode_ratio_ism_subframe( } } +#ifdef DEBUGGING + assert( nbits == ( hMetaData->nb_bits_tot - bits_pos0 ) ); +#endif } else { @@ -3319,6 +3328,9 @@ static int16_t encode_ratio_ism_subframe( } } +#ifdef DEBUGGING + assert( nbits == ( hMetaData->nb_bits_tot - bits_pos0 ) ); +#endif } } diff --git a/lib_enc/ivas_mc_param_enc.c b/lib_enc/ivas_mc_param_enc.c index 5a90fc89a..fba297566 100644 --- a/lib_enc/ivas_mc_param_enc.c +++ b/lib_enc/ivas_mc_param_enc.c @@ -41,6 +41,12 @@ #include "ivas_prot.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" +#ifdef DEBUGGING +#include "debug.h" +#endif +#ifdef DEBUG_PLOT +#include "deb_out.h" +#endif #include "wmc_auto.h" @@ -124,6 +130,10 @@ ivas_error ivas_param_mc_enc_open( st_ivas->nSCE = 0; st_ivas->hEncoderConfig->element_mode_init = IVAS_CPE_MDCT; break; +#ifdef DEBUGGING + default: + assert( 0 && "Number of transport channels not supported by ParamMC!\n" ); +#endif } /* get dmx factors */ @@ -261,6 +271,10 @@ ivas_error ivas_param_mc_enc_reconfig( st_ivas->nSCE = 0; st_ivas->hEncoderConfig->element_mode_init = IVAS_CPE_MDCT; break; +#ifdef DEBUGGING + default: + assert( 0 && "Number of transport channels not supported by ParamMC!\n" ); +#endif } /* get dmx factors */ @@ -269,6 +283,9 @@ ivas_error ivas_param_mc_enc_reconfig( /* deallocate the full icc map, gets newly allocated in the metadata open function */ for ( i = 0; i < 2; i++ ) { +#ifdef DEBUGGING + assert( hParamMC->hMetadataPMC.icc_map_full[i] != NULL ); +#endif if ( hParamMC->hMetadataPMC.icc_map_full[i] != NULL ) { free( hParamMC->hMetadataPMC.icc_map_full[i] ); @@ -474,6 +491,10 @@ void ivas_param_mc_enc( } } break; +#ifdef DEBUGGING + default: + assert( !"Number of transport channels not valid for ParamMC!" ); +#endif } /* Encoding */ @@ -1713,6 +1734,9 @@ static void ivas_param_mc_encode_parameter( } } +#ifdef DEBUG_MODE_PARAM_MC + dbgwrite( seq, sizeof( int16_t ), sz_seq, 1, "./res/param_mc_quant_param_idx_enc.dat" ); +#endif bit_cnt_uni = sz_seq * hParameterCodingInfo->uni_bits - 1; /* -1 for the additional diff/direct signaling bit for the range encoder*/ diff --git a/lib_enc/ivas_mc_paramupmix_enc.c b/lib_enc/ivas_mc_paramupmix_enc.c index 54f1eba84..2d1e6d37f 100644 --- a/lib_enc/ivas_mc_paramupmix_enc.c +++ b/lib_enc/ivas_mc_paramupmix_enc.c @@ -41,6 +41,12 @@ #include "ivas_cnst.h" #include "ivas_rom_com.h" #include "ivas_rom_enc.h" +#ifdef DEBUGGING +#include "debug.h" +#endif +#ifdef DEBUG_PLOT +#include "deb_out.h" +#endif #include "wmc_auto.h" /*------------------------------------------------------------------------- @@ -50,18 +56,35 @@ static void ivas_mc_paramupmix_dmx( MC_PARAMUPMIX_ENC_HANDLE hMCParamUpmix, float *data_f[], const int16_t input_frame ); static void ivas_mc_paramupmix_param_est_enc( MC_PARAMUPMIX_ENC_HANDLE hMCParamUpmix, float *input_frame_t[], const int16_t input_frame, float alphas[MC_PARAMUPMIX_COMBINATIONS][IVAS_MAX_NUM_BANDS], float betas[MC_PARAMUPMIX_COMBINATIONS][IVAS_MAX_NUM_BANDS] ); +#ifdef FIX_891_PARAMUPMIX_CLEANUP static void get_huff_table( const PAR_TYPE par_type, HUFF_TAB *df0, HUFF_TAB *df ); +#else +static void get_huff_table( const PAR_TYPE par_type, const QUANT_TYPE quant_type, HUFF_TAB *df0, HUFF_TAB *df, HUFF_TAB *dt ); +#endif static void write_huff_bits( const int32_t value, const uint16_t length, uint16_t bit_buffer[MC_PARAMUPMIX_MAX_BITS], int16_t *bit_pos ); +#ifdef FIX_891_PARAMUPMIX_CLEANUP static void huffman_encode( const int32_t *vqPrev, const int32_t *vq, const PAR_TYPE parType, const int16_t nq, uint16_t bit_buffer[MC_PARAMUPMIX_MAX_BITS], int16_t *bit_pos ); +#else +static void huffman_encode( const int16_t bdfOnly, const int16_t bdtAllowed, const int16_t nv, const int16_t ivStart, const int32_t *vqPrev, const int32_t *vq, const PAR_TYPE parType, const QUANT_TYPE quant_type, const int16_t nq, uint16_t bit_buffer[MC_PARAMUPMIX_MAX_BITS], int16_t *bit_pos ); +#endif static void put_ec_data( MC_PARAMUPMIX_ENC_HANDLE hMCParamUpmix, const int16_t ch, const float pars[IVAS_MAX_NUM_BANDS], const float alphas[IVAS_MAX_NUM_BANDS], const PAR_TYPE parType, uint16_t bit_buffer[MC_PARAMUPMIX_MAX_BITS], int16_t *bit_pos ); +#ifdef FIX_891_PARAMUPMIX_CLEANUP static void quantize_alpha( const float *alpha, int16_t *pnq, int32_t aq[IVAS_MAX_NUM_BANDS], float *adeq ); static void quantize_pars( const float *v, const int16_t nq, const float *data, int32_t vq[IVAS_MAX_NUM_BANDS], float *vdeq ); +#else +static void quantize_alpha( const int16_t nv, const float *alpha, const QUANT_TYPE quant_type, int16_t *pnq, int32_t aq[IVAS_MAX_NUM_BANDS], float *adeq ); + +static void quantize_pars( const int16_t nv, const float *v, const int16_t nq, const float *data, int32_t vq[IVAS_MAX_NUM_BANDS], float *vdeq ); + +static void quantize_pars( const int16_t nv, const float *v, const int16_t nq, const float *data, int32_t vq[IVAS_MAX_NUM_BANDS], float *vdeq ); + +#endif /*------------------------------------------------------------------------- * ivas_mc_paramupmix_enc() @@ -159,6 +182,10 @@ ivas_error ivas_mc_paramupmix_enc_open( st_ivas->nSCE = 0; st_ivas->hEncoderConfig->element_mode_init = IVAS_CPE_MDCT; break; +#ifdef DEBUGGING + default: + assert( 0 && "Number of transport channels not supported by MC PARAM UPMIX MODE!\n" ); +#endif } /* Transient Detector handle */ @@ -347,11 +374,19 @@ void ivas_mc_paramupmix_enc_close( static void get_huff_table( const PAR_TYPE par_type, +#ifndef FIX_891_PARAMUPMIX_CLEANUP + const QUANT_TYPE quant_type, + HUFF_TAB *df0, + HUFF_TAB *df, + HUFF_TAB *dt ) +#else HUFF_TAB *df0, HUFF_TAB *df ) +#endif { switch ( par_type ) { +#ifdef FIX_891_PARAMUPMIX_CLEANUP case ALPHA: df0->value = huff_alpha_table.df0.value; df0->length = huff_alpha_table.df0.length; @@ -364,6 +399,24 @@ static void get_huff_table( df->value = huff_beta_table.df.value; df->length = huff_beta_table.df.length; break; +#else + case ALPHA: + df0->value = huff_alpha_table[quant_type].df0.value; + df0->length = huff_alpha_table[quant_type].df0.length; + df->value = huff_alpha_table[quant_type].df.value; + df->length = huff_alpha_table[quant_type].df.length; + dt->value = huff_alpha_table[quant_type].dt.value; + dt->length = huff_alpha_table[quant_type].dt.length; + break; + case BETA: + df0->value = huff_beta_table[quant_type].df0.value; + df0->length = huff_beta_table[quant_type].df0.length; + df->value = huff_beta_table[quant_type].df.value; + df->length = huff_beta_table[quant_type].df.length; + dt->value = huff_beta_table[quant_type].dt.value; + dt->length = huff_beta_table[quant_type].dt.length; + break; +#endif } return; @@ -388,37 +441,88 @@ static void write_huff_bits( static void huffman_encode( +#ifndef FIX_891_PARAMUPMIX_CLEANUP + const int16_t bdfOnly, + const int16_t bdtAllowed, + const int16_t nv, + const int16_t ivStart, +#endif const int32_t *vqPrev, const int32_t *vq, const PAR_TYPE parType, +#ifndef FIX_891_PARAMUPMIX_CLEANUP + const QUANT_TYPE quant_type, +#endif const int16_t nq, uint16_t bit_buffer[MC_PARAMUPMIX_MAX_BITS], int16_t *bit_pos ) { +#ifdef FIX_891_PARAMUPMIX_CLEANUP int16_t iv; +#else + int16_t iv, ndf, ndt; +#endif int32_t icode; int16_t offset; +#ifdef FIX_891_PARAMUPMIX_CLEANUP HUFF_TAB df0, df; +#else + HUFF_TAB df0, df, dt; +#endif +#ifdef FIX_891_PARAMUPMIX_CLEANUP get_huff_table( parType, &df0, &df ); +#else + get_huff_table( parType, quant_type, &df0, &df, &dt ); +#endif offset = nq - 1; /* range [-(nquant - 1), nquant - 1] */ +#ifndef FIX_891_PARAMUPMIX_CLEANUP + /* Get code length for time and freq diff coding */ + ndf = 0; + ndt = 0; +#endif +#ifdef FIX_891_PARAMUPMIX_CLEANUP for ( iv = 0; iv < IVAS_MAX_NUM_BANDS; iv++ ) +#else + for ( iv = ivStart; iv < nv; iv++ ) +#endif { +#ifdef FIX_891_PARAMUPMIX_CLEANUP if ( iv == 0 ) +#else + if ( iv == ivStart ) +#endif { icode = vq[iv]; +#ifndef FIX_891_PARAMUPMIX_CLEANUP + ndf += df0.length[icode]; +#endif } else { icode = vq[iv] - vq[iv - 1] + offset; +#ifndef FIX_891_PARAMUPMIX_CLEANUP + ndf += df.length[icode]; +#endif } icode = vq[iv] - vqPrev[iv] + offset; +#ifndef FIX_891_PARAMUPMIX_CLEANUP + ndt += dt.length[icode]; +#endif + } + +#ifndef FIX_891_PARAMUPMIX_CLEANUP + if ( !bdtAllowed ) /* Time diff not allowed due to conformance or other reason even if bdfOnly = 0 */ + { + ndt = ndf + 1; } +#endif /* Write the bitstream */ +#ifdef FIX_891_PARAMUPMIX_CLEANUP bit_buffer[( *bit_pos )++] = (uint16_t) 0 & 1; for ( iv = 0; iv < IVAS_MAX_NUM_BANDS; iv++ ) { @@ -433,12 +537,49 @@ static void huffman_encode( write_huff_bits( df.value[icode], df.length[icode], bit_buffer, bit_pos ); } } +#else + if ( bdfOnly || ndf < ndt ) + { + bit_buffer[( *bit_pos )++] = (uint16_t) 0 & 1; + for ( iv = ivStart; iv < nv; iv++ ) + { + if ( iv == ivStart ) + { + icode = vq[iv]; + write_huff_bits( df0.value[icode], df0.length[icode], bit_buffer, bit_pos ); + } + else + { + icode = vq[iv] - vq[iv - 1] + offset; + write_huff_bits( df.value[icode], df.length[icode], bit_buffer, bit_pos ); + } + } + } + else + { + bit_buffer[( *bit_pos )++] = (uint16_t) 1 & 1; + for ( iv = ivStart; iv < nv; iv++ ) + { + icode = vq[iv] - vqPrev[iv] + offset; +#ifdef DEBUGGING + if ( icode < 0 || icode >= 2 * nq - 1 ) + { + assert( 0 ); + } +#endif + write_huff_bits( dt.value[icode], dt.length[icode], bit_buffer, bit_pos ); + } + } +#endif return; } static void quantize_pars( +#ifndef FIX_891_PARAMUPMIX_CLEANUP + const int16_t nv, +#endif const float *v, const int16_t nq, const float *data, @@ -447,7 +588,11 @@ static void quantize_pars( { int16_t iv, iq, iq0, iq1; +#ifdef FIX_891_PARAMUPMIX_CLEANUP for ( iv = 0; iv < IVAS_MAX_NUM_BANDS; iv++ ) +#else + for ( iv = 0; iv < nv; iv++ ) +#endif { iq0 = 0; iq1 = nq - 1; @@ -482,7 +627,13 @@ static void quantize_pars( static void quantize_alpha( +#ifndef FIX_891_PARAMUPMIX_CLEANUP + const int16_t nv, +#endif const float *alpha, +#ifndef FIX_891_PARAMUPMIX_CLEANUP + const QUANT_TYPE quant_type, +#endif int16_t *pnq, int32_t aq[IVAS_MAX_NUM_BANDS], float *adeq ) @@ -490,10 +641,17 @@ static void quantize_alpha( int16_t nq; const float *data; +#ifdef FIX_891_PARAMUPMIX_CLEANUP nq = ivas_mc_paramupmix_alpha_quant_table.nquant; data = ivas_mc_paramupmix_alpha_quant_table.data; quantize_pars( alpha, nq, data, aq, adeq ); +#else + nq = ivas_mc_paramupmix_alpha_quant_table[quant_type].nquant; + data = ivas_mc_paramupmix_alpha_quant_table[quant_type].data; + + quantize_pars( nv, alpha, nq, data, aq, adeq ); +#endif *pnq = nq; return; @@ -501,19 +659,37 @@ static void quantize_alpha( static void quantize_beta( +#ifndef FIX_891_PARAMUPMIX_CLEANUP + const int16_t nv, +#endif const float *beta, const int32_t aq[IVAS_MAX_NUM_BANDS], +#ifndef FIX_891_PARAMUPMIX_CLEANUP + const QUANT_TYPE quant_type, +#endif int16_t *pnq, int32_t bq[IVAS_MAX_NUM_BANDS], float *bdeq ) { int16_t iv, iq, iq0, iq1; +#ifdef FIX_891_PARAMUPMIX_CLEANUP const ACPL_QUANT_TABLE *tables = ivas_mc_paramupmix_beta_quant_table; +#else + const ACPL_QUANT_TABLE *tables = ivas_mc_paramupmix_beta_quant_table[quant_type]; +#endif ACPL_QUANT_TABLE quant_table; +#ifdef FIX_891_PARAMUPMIX_CLEANUP for ( iv = 0; iv < IVAS_MAX_NUM_BANDS; iv++ ) +#else + for ( iv = 0; iv < nv; iv++ ) +#endif { +#ifdef FIX_891_PARAMUPMIX_CLEANUP quant_table = tables[ivas_param_upmx_mx_qmap[aq[iv]]]; +#else + quant_table = tables[ivas_param_upmx_mx_qmap[quant_type][aq[iv]]]; +#endif iq0 = 0; iq1 = quant_table.nquant - 1; @@ -543,7 +719,11 @@ static void quantize_beta( } } +#ifdef FIX_891_PARAMUPMIX_CLEANUP *pnq = ivas_mc_paramupmix_beta_quant_table[0].nquant; +#else + *pnq = ivas_mc_paramupmix_beta_quant_table[quant_type][0].nquant; +#endif return; } @@ -558,7 +738,14 @@ static void put_ec_data( uint16_t bit_buffer[MC_PARAMUPMIX_MAX_BITS], int16_t *bit_pos ) { +#ifndef FIX_891_PARAMUPMIX_CLEANUP + int16_t npar = IVAS_MAX_NUM_BANDS; + int16_t onlyFreq = 1; +#endif int16_t nq; +#ifndef FIX_891_PARAMUPMIX_CLEANUP + QUANT_TYPE quant_type = FINE; +#endif int32_t alphaQuant[IVAS_MAX_NUM_BANDS]; int32_t betaQuant[IVAS_MAX_NUM_BANDS]; float alphaDequant[IVAS_MAX_NUM_BANDS]; @@ -566,12 +753,21 @@ static void put_ec_data( if ( parType == ALPHA ) { +#ifdef FIX_891_PARAMUPMIX_CLEANUP quantize_alpha( pars, &nq, alphaQuant, alphaDequant ); +#else + quantize_alpha( npar, pars, quant_type, &nq, alphaQuant, alphaDequant ); +#endif } else { +#ifdef FIX_891_PARAMUPMIX_CLEANUP quantize_alpha( alphas, &nq, alphaQuant, alphaDequant ); quantize_beta( pars, alphaQuant, &nq, betaQuant, betaDequant ); +#else + quantize_alpha( npar, alphas, quant_type, &nq, alphaQuant, alphaDequant ); + quantize_beta( npar, pars, alphaQuant, quant_type, &nq, betaQuant, betaDequant ); +#endif } if ( hMCParamUpmix->first_frame ) @@ -590,11 +786,19 @@ static void put_ec_data( /* Always one parameter set per frame for transient frames. Original PS framing is used internally. */ if ( parType == ALPHA ) { +#ifdef FIX_891_PARAMUPMIX_CLEANUP huffman_encode( hMCParamUpmix->alpha_quant_prev[ch], alphaQuant, ALPHA, nq, bit_buffer, bit_pos ); +#else + huffman_encode( onlyFreq, 1, npar, 0, hMCParamUpmix->alpha_quant_prev[ch], alphaQuant, ALPHA, quant_type, nq, bit_buffer, bit_pos ); +#endif } else { +#ifdef FIX_891_PARAMUPMIX_CLEANUP huffman_encode( hMCParamUpmix->beta_quant_prev[ch], betaQuant, BETA, nq, bit_buffer, bit_pos ); +#else + huffman_encode( onlyFreq, 1, npar, 0, hMCParamUpmix->beta_quant_prev[ch], betaQuant, BETA, quant_type, nq, bit_buffer, bit_pos ); +#endif } if ( parType == ALPHA ) diff --git a/lib_enc/ivas_mcmasa_enc.c b/lib_enc/ivas_mcmasa_enc.c index 7bb8092d7..32833d37b 100644 --- a/lib_enc/ivas_mcmasa_enc.c +++ b/lib_enc/ivas_mcmasa_enc.c @@ -40,6 +40,9 @@ #include "prot.h" #include "ivas_rom_com.h" #include "ivas_rom_enc.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" diff --git a/lib_enc/ivas_mct_core_enc.c b/lib_enc/ivas_mct_core_enc.c index 84aef1d46..c20d09e33 100644 --- a/lib_enc/ivas_mct_core_enc.c +++ b/lib_enc/ivas_mct_core_enc.c @@ -37,6 +37,9 @@ #include "prot.h" #include "ivas_prot.h" #include "rom_com.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" @@ -85,6 +88,13 @@ static void FindChannelRatio( } } +#ifdef DEBUG_MODE_MDCT + for ( i = 0; i < nChannels; i++ ) + { + dbgwrite( &chBitRatios[i], sizeof( int16_t ), 1, 1, "./res/chBitRatio" ); + /* dbgwrite(&chRatio[i], sizeof(float),1,1,"./res/chRatio");*/ + } +#endif return; } @@ -201,7 +211,16 @@ void ivas_mct_core_enc( int16_t sp_aud_decision0[MCT_MAX_CHANNELS]; BSTR_ENC_HANDLE hBstr; float mdst; +#ifdef DEBUGGING + int32_t total_brate = 0; + int16_t sba_meta = 0; + int16_t format_bits = 0; + int16_t mct_bits = 0; +#endif +#if defined( DEBUG_MODE_MDCT ) && defined( DEBUG_PLOT_BITS ) + static FILE *f_bit_split = 0; +#endif push_wmops( "mct_encoding" ); @@ -502,6 +521,9 @@ void ivas_mct_core_enc( } nAvailBits -= total_side_bits + hMCT->nchan_out_woLFE; /* if MC 1 extra bit that was initially send to signal LFE_off */ +#ifdef DEBUG_MODE_MDCT + dbgwrite( &nAvailBits, sizeof( int16_t ), 1, 1, "./res/availBits" ); +#endif if ( hMCT->hbr_mct ) { @@ -517,6 +539,9 @@ void ivas_mct_core_enc( } push_next_indice( hBstr, chBitRatios[ch], NBBITS_MCT_RATIO ); +#ifdef DEBUGGING + mct_bits += NBBITS_MCT_RATIO; +#endif } /*distribute bits amongst channels*/ @@ -533,9 +558,24 @@ void ivas_mct_core_enc( } st->total_brate = ( st->bits_frame_channel + st->side_bits_frame_channel ) * FRAMES_PER_SEC; +#ifdef DEBUGGING + total_brate += st->total_brate; +#endif + } +#ifdef DEBUGGING + if ( hCPE[cpe_id]->hMetaData != NULL ) + { + sba_meta += hCPE[cpe_id]->hMetaData->nb_bits_tot; } +#endif } +#ifdef DEBUGGING + format_bits = ( ivas_format == MC_FORMAT ? IVAS_FORMAT_SIGNALING_NBITS + MC_LS_SETUP_BITS : IVAS_FORMAT_SIGNALING_NBITS_EXTENDED + SBA_ORDER_BITS + SBA_PLANAR_BITS ); + format_bits += ( ivas_format == SBA_ISM_FORMAT && nChannels > FOA_CHANNELS ); + mct_bits += hMCT->nBitsMCT + hMCT->nchan_out_woLFE; + assert( ( total_brate + ( NBITS_BWIDTH + format_bits + mct_bits + sba_meta + lfe_bits ) * FRAMES_PER_SEC ) == ivas_total_brate ); +#endif pop_wmops(); diff --git a/lib_enc/ivas_mct_enc.c b/lib_enc/ivas_mct_enc.c index 9f1b4a416..59bec00e2 100644 --- a/lib_enc/ivas_mct_enc.c +++ b/lib_enc/ivas_mct_enc.c @@ -38,6 +38,9 @@ #include "ivas_cnst.h" #include "prot.h" #include "ivas_prot.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" @@ -186,6 +189,12 @@ ivas_error ivas_mct_enc( max_bwidth = st_ivas->hEncoderConfig->max_bwidth; ivas_total_brate = st_ivas->hEncoderConfig->ivas_total_brate; +#ifdef DEBUG_FORCE_MCT_CP + if ( ivas_format == MC_FORMAT ) + { + assert( !"Debugging switch works only with SBA modes" ); + } +#endif for ( cpe_id = 0; cpe_id < st_ivas->nCPE; cpe_id++ ) { @@ -325,6 +334,12 @@ ivas_error create_mct_enc( { hMCT->nchan_out_woLFE = MC_PARAMUPMIX_MAX_TRANSPORT_CHANS - 1; } +#ifdef DEBUGGING + else + { + assert( !"IVAS format currently not supported for MCT" ); + } +#endif cp_bitrate = ivas_total_brate / hMCT->nchan_out_woLFE * CPE_CHANNELS; if ( st_ivas->ism_mode == ISM_SBA_MODE_DISC ) @@ -372,6 +387,9 @@ ivas_error create_mct_enc( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for MDCT Stereo \n" ) ); } +#ifdef DEBUGGING + hMCT->hBlockData[n]->hStereoMdct->mdct_stereo_mode_cmdl = SMDCT_MS_DECISION; +#endif initMdctStereoEncData( hMCT->hBlockData[n]->hStereoMdct, ivas_format, IVAS_CPE_MDCT, cp_bitrate, st_ivas->hEncoderConfig->max_bwidth, st_ivas->hCPE[0]->hCoreCoder[0]->igf, st_ivas->hCPE[0]->hCoreCoder[0]->igf ? st_ivas->hCPE[0]->hCoreCoder[0]->hIGFEnc->igfData.igfInfo.grid : NULL, 1 ); } @@ -443,6 +461,12 @@ ivas_error mct_enc_reconfigure( hMCT->nchan_out_woLFE += st_ivas->hEncoderConfig->nchan_ism; } } +#ifdef DEBUGGING + else + { + assert( !"IVAS format currently not supported for MCT" ); + } +#endif } cp_bitrate = ivas_total_brate / hMCT->nchan_out_woLFE * CPE_CHANNELS; @@ -526,6 +550,9 @@ ivas_error mct_enc_reconfigure( } } +#ifdef DEBUGGING + hMCT->hBlockData[n]->hStereoMdct->mdct_stereo_mode_cmdl = SMDCT_MS_DECISION; +#endif initMdctStereoEncData( hMCT->hBlockData[n]->hStereoMdct, ivas_format, IVAS_CPE_MDCT, cp_bitrate, st_ivas->hEncoderConfig->max_bwidth, st_ivas->hCPE[0]->hCoreCoder[0]->igf, st_ivas->hCPE[0]->hCoreCoder[0]->igf ? st_ivas->hCPE[0]->hCoreCoder[0]->hIGFEnc->igfData.igfInfo.grid : NULL, mem_init ); } @@ -723,6 +750,12 @@ static ivas_error ivas_mc_enc_reconfig( return error; } } +#ifdef DEBUGGING + else + { + assert( 0 ); + } +#endif /*De-allocate handles for other MC modes*/ ivas_param_mc_enc_close( &st_ivas->hParamMC, st_ivas->hEncoderConfig->input_Fs ); diff --git a/lib_enc/ivas_mct_enc_mct.c b/lib_enc/ivas_mct_enc_mct.c index ee2690507..c5df49bf0 100644 --- a/lib_enc/ivas_mct_enc_mct.c +++ b/lib_enc/ivas_mct_enc_mct.c @@ -200,6 +200,9 @@ static void getCorrelationMatrix( xCorrMatrix[ch1][ch2] = 0.f; } +#ifdef DEBUG_MODE_MDCT + dbgwrite( &xCorrMatrix[ch1][ch2], sizeof( float ), 1, 1, "./res/xCorrMatrix" ); +#endif } } @@ -430,6 +433,11 @@ static void getGlobalILD( } } +#ifdef DEBUG_MODE_MDCT + /*check if energy levels are comparable*/ + getChannelEnergies( sts, nrg, nchan ); + dbgwrite( nrg, sizeof( float ), 6, 1, "./res/nrgGlobalILD" ); +#endif return; } @@ -486,6 +494,7 @@ void apply_MCT_enc( { /*Normalize energies with global ILD*/ getGlobalILD( sts, hMCT, mdst_spectrum, nchan ); +#ifndef DEBUG_FORCE_MCT_CP getCorrelationMatrix( sts, hMCT, xCorrMatrix ); /*check if previous tree should be kept*/ @@ -536,6 +545,9 @@ void apply_MCT_enc( } } +#ifdef DEBUG_MODE_MDCT + dbgwrite( &forceKeepTree, sizeof( int16_t ), 1, 1, "./res/keepTree" ); +#endif currBlockDataCnt = 0; while ( currBlockDataCnt < hMCT->nchan_out_woLFE ) @@ -614,6 +626,58 @@ void apply_MCT_enc( /*save number of blocks for next frame*/ hMCT->currBlockDataCnt = currBlockDataCnt; +#else + forceKeepTree = 1; + if ( nchan == 3 ) /*3 TCs*/ + { +#ifdef DEBUG_SINGLE_CODE_OMNI + ch1 = 1; + ch2 = 2; + cpEle[0] = 0; +#else + /* one stereo pair for first and second channel (W,Y)*/ + ch1 = 0; + ch2 = 1; + cpEle[2] = 0; +#endif + hMCT->currBlockDataCnt = 1; + hMCT->hBlockData[0]->ch1 = ch1; + hMCT->hBlockData[0]->ch2 = ch2; + + getBlockValues( sts, ch1, ch2, hMCT->hBlockData[0], mdst_spectrum, inv_spectrum, inv_mdst_spectrum ); + + if ( hMCT->hBlockData[0]->isActive ) + { + cpEle[ch1] = 1; + cpEle[ch2] = 1; + } + else + { + hMCT->currBlockDataCnt = 0; + } + } + else + { + assert( nchan == 4 ); /*4 TCs*/ + /* 2 Stereo Pairs W-Y and X-Z */ + hMCT->currBlockDataCnt = nchan * 0.5; + for ( currBlockDataCnt = 0; currBlockDataCnt < hMCT->currBlockDataCnt; currBlockDataCnt++ ) + { + hMCT->hBlockData[currBlockDataCnt]->ch1 = currBlockDataCnt * CPE_CHANNELS; + hMCT->hBlockData[currBlockDataCnt]->ch2 = currBlockDataCnt * CPE_CHANNELS + 1; + getBlockValues( sts, hMCT->hBlockData[currBlockDataCnt]->ch1, hMCT->hBlockData[currBlockDataCnt]->ch2, hMCT->hBlockData[currBlockDataCnt], mdst_spectrum, inv_spectrum, inv_mdst_spectrum ); + if ( hMCT->hBlockData[0]->isActive ) + { + cpEle[hMCT->hBlockData[currBlockDataCnt]->ch1] = 1; + cpEle[hMCT->hBlockData[currBlockDataCnt]->ch2] = 1; + } + else + { + hMCT->currBlockDataCnt -= 1; + } + } + } +#endif for ( ch = 0; ch < nchan; ch++ ) { @@ -652,6 +716,24 @@ void apply_MCT_enc( hMCT->mc_global_ild[ch] = 0; } } +#ifdef DEBUG_MODE_MDCT + dbgwrite( &hMCT->currBlockDataCnt, sizeof( int16_t ), 1, 1, "./res/blockCnt" ); + + { + int16_t pair, k; + for ( pair = 0; pair < (int16_t) ( hMCT->nchan_out_woLFE * 0.5 ); pair++ ) + { + dbgwrite( &hMCT->hBlockData[pair]->ch1, sizeof( int16_t ), 1, 1, "./res/CP_in_blocks" ); + dbgwrite( &hMCT->hBlockData[pair]->ch2, sizeof( int16_t ), 1, 1, "./res/CP_in_blocks" ); + for ( k = 0; k < 2; k++ ) + { + dbgwrite( &hMCT->hBlockData[pair]->hStereoMdct->global_ild[k], sizeof( int16_t ), 1, 1, "./res/ILD_p_block" ); + dbgwrite( &hMCT->hBlockData[pair]->hStereoMdct->mdct_stereo_mode[k], sizeof( int16_t ), 1, 1, "./res/stereo_mode_p_block" ); + dbgwrite( &hMCT->hBlockData[pair]->mask[k], sizeof( int16_t ), MAX_SFB, 1, "./res/ms_mask_p_block" ); + } + } + } +#endif pop_wmops(); diff --git a/lib_enc/ivas_mdct_core_enc.c b/lib_enc/ivas_mdct_core_enc.c index 368b76e94..f37eeb435 100644 --- a/lib_enc/ivas_mdct_core_enc.c +++ b/lib_enc/ivas_mdct_core_enc.c @@ -40,6 +40,9 @@ #include "ivas_prot.h" #include "rom_com.h" #include "ivas_rom_com.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" /*--------------------------------------------------------------* @@ -67,6 +70,9 @@ static void enc_prm_pre_mdct( ) { int16_t nbits_start; +#ifdef DEBUG_PLOT_BITS + int16_t tmp; +#endif nbits_start = hBstr->nb_bits_tot; @@ -92,6 +98,11 @@ static void enc_prm_pre_mdct( } st->glr_reset = 0; +#ifdef DEBUG_PLOT_BITS + tmp = hBstr->nb_bits_tot - nbits_start; + dbgwrite( &tmp, sizeof( int16_t ), 1, 1, "./res/bits_TCX" ); + tmp = hBstr->nb_bits_tot; +#endif /*--------------------------------------------------------------------------------* * TCX20/TCX10 parameters @@ -101,6 +112,9 @@ static void enc_prm_pre_mdct( st->side_bits_frame_channel = hBstr->nb_bits_tot - nbits_start; +#ifdef DEBUG_PLOT_BITS + dbgwrite( &st->side_bits_frame_channel, sizeof( int16_t ), 1, 1, "./res/side_bits_pre" ); +#endif return; } @@ -902,6 +916,14 @@ void ivas_mdct_core_whitening_enc( } else { +#ifdef DEBUG_MODE_MDCT + { + float ener_side = 0; + float ener_mid = 0; + dbgwrite( &ener_side, sizeof( float ), 1, 1, "./res/ener_side" ); + dbgwrite( &ener_mid, sizeof( float ), 1, 1, "./res/ener_mid" ); + } +#endif for ( ch = 0; ch < CPE_CHANNELS; ch++ ) { param_lpc[ch][0] = ch; @@ -1248,6 +1270,16 @@ void ivas_mdct_quant_coder( ivas_mdct_tcx10_bit_distribution( target_bitsTCX10[ch], bitsAvailable, nTnsBitsTCX10Tmp ); } +#ifdef DEBUG_PLOT_BITS + if ( st->hTcxEnc->tcxMode == TCX_20 ) + { + set_s( &target_bitsTCX10[ch][0], 0, NB_DIV ); + } + for ( n = 0; n < NB_DIV; n++ ) + { + dbgwrite( &target_bitsTCX10[ch][n], sizeof( int16_t ), 1, 1, "./res/bits_tarrget_TCX10" ); + } +#endif for ( n = 0; n < nSubframes; n++ ) { diff --git a/lib_enc/ivas_omasa_enc.c b/lib_enc/ivas_omasa_enc.c index 404c1537d..8f0cf1348 100644 --- a/lib_enc/ivas_omasa_enc.c +++ b/lib_enc/ivas_omasa_enc.c @@ -39,6 +39,9 @@ #include "prot.h" #include "ivas_rom_com.h" #include "ivas_rom_enc.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" @@ -666,6 +669,10 @@ void ivas_set_ism_importance_interformat( void ivas_set_surplus_brate_enc( Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ +#ifdef DEBUG_MODE_INFO + , + const int16_t *nb_bits_metadata /* i : number of metadata bits */ +#endif ) { if ( st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ ) @@ -682,6 +689,31 @@ void ivas_set_surplus_brate_enc( st_ivas->hCPE[0]->brate_surplus = 0; } +#ifdef DEBUG_MODE_INFO + if ( st_ivas->hSCE[0] != NULL ) + { + int16_t input_frame = (int16_t) ( st_ivas->hEncoderConfig->input_Fs / FRAMES_PER_SEC ); + float tmpF = 0; + + if ( st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ ) + { + tmpF += st_ivas->hSCE[0]->hCoreCoder[0]->total_brate + (float) ( nb_bits_metadata[1] * 50 ); + } + else + { + for ( int16_t i = 0; i < st_ivas->hEncoderConfig->nchan_ism; i++ ) + { + tmpF += st_ivas->hSCE[i]->hCoreCoder[0]->total_brate + (float) ( nb_bits_metadata[i + 1] * 50 ); + } + } + tmpF /= 1000.f; + dbgwrite( &tmpF, 4, 1, input_frame, "res/brate_ISM" ); /* == ism_total_brate incl. ISM MD */ + tmpF = st_ivas->hEncoderConfig->ivas_total_brate / 1000.0f - tmpF; + dbgwrite( &tmpF, 4, 1, input_frame, "res/brate_MASA" ); /* == masa_total_brate incl. MASA MD */ + tmpF = nb_bits_metadata[0] * FRAMES_PER_SEC / 1000.0f; + dbgwrite( &tmpF, 4, 1, input_frame, "res/brate_MASA_MD" ); /* == MASA MD bitrate */ + } +#endif return; } diff --git a/lib_enc/ivas_osba_enc.c b/lib_enc/ivas_osba_enc.c index 38c435ad1..675b89c6d 100644 --- a/lib_enc/ivas_osba_enc.c +++ b/lib_enc/ivas_osba_enc.c @@ -39,6 +39,9 @@ #include "prot.h" #include "ivas_rom_com.h" #include "ivas_rom_enc.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" diff --git a/lib_enc/ivas_pca_enc.c b/lib_enc/ivas_pca_enc.c index c3cdd6b2d..f8b4c8e9a 100644 --- a/lib_enc/ivas_pca_enc.c +++ b/lib_enc/ivas_pca_enc.c @@ -32,6 +32,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "prot.h" #include "ivas_prot.h" #include "ivas_cnst.h" @@ -329,6 +332,9 @@ void ivas_pca_enc( return; } +#ifdef DEBUGGING + assert( ivas_total_brate == PCA_BRATE ); /* the remaining code is defined at 256k where there are 4 dmx channel */ +#endif /*-----------------------------------------------------------------* * Covariance *-----------------------------------------------------------------*/ diff --git a/lib_enc/ivas_qmetadata_enc.c b/lib_enc/ivas_qmetadata_enc.c index adf728547..0be2dc62d 100644 --- a/lib_enc/ivas_qmetadata_enc.c +++ b/lib_enc/ivas_qmetadata_enc.c @@ -47,6 +47,10 @@ * Local function prototypes *-----------------------------------------------------------------------*/ +#ifdef DEBUG_MODE_QMETADATA +static float direction_distance( float elevation[DIRAC_MAX_NBANDS][MAX_PARAM_SPATIAL_SUBFRAMES], float azimuth[DIRAC_MAX_NBANDS][MAX_PARAM_SPATIAL_SUBFRAMES], IVAS_QDIRECTION *q_direction, const int16_t dim1, const int16_t dim2, float mat_dist[DIRAC_MAX_NBANDS][MAX_PARAM_SPATIAL_SUBFRAMES] ); + +#endif static void ivas_qmetadata_quantize_diffuseness_nrg_ratios( IVAS_QMETADATA_HANDLE hQMetaData, int16_t *needed_bits, int16_t *nbits_diff, int16_t *dfRatioBits, const int16_t hodirac_flag ); static int16_t ivas_qmetadata_entropy_encode_diffuseness( BSTR_ENC_HANDLE hMetaData, IVAS_QDIRECTION *q_direction, uint16_t *diffuseness_index_max_ec_frame ); @@ -164,6 +168,33 @@ ivas_error ivas_qmetadata_enc_encode( error = IVAS_ERR_OK; +#ifdef DEBUG_MODE_QMETADATA + int16_t ec_flag = 0; + int16_t tmp; + + static FILE *pF = NULL; + static FILE *pF_azi = NULL; + static FILE *pF_ele = NULL; + static FILE *pF_ratio = NULL; + static FILE *pF_spcoh = NULL; + static FILE *pF_spcoh_orig = NULL; + static FILE *pF_surcoh = NULL; + + if ( pF == NULL ) + pF = fopen( "./res/qmetadata_enc.txt", "w" ); + if ( pF_azi == NULL ) + pF_azi = fopen( "./res/qmetadata_azi_enc.txt", "w" ); + if ( pF_ele == NULL ) + pF_ele = fopen( "./res/qmetadata_ele_enc.txt", "w" ); + if ( pF_ratio == NULL ) + pF_ratio = fopen( "./res/qmetadata_ratio_enc.txt", "w" ); + if ( pF_spcoh == NULL ) + pF_spcoh = fopen( "./res/qmetadata_spcoh_enc.txt", "w" ); + if ( pF_spcoh_orig == NULL ) + pF_spcoh_orig = fopen( "./res/qmetadata_spcoh_orig.txt", "w" ); + if ( pF_surcoh == NULL ) + pF_surcoh = fopen( "./res/qmetadata_surcoh_enc.txt", "w" ); +#endif /* Save initial position in bitstream */ @@ -187,6 +218,9 @@ ivas_error ivas_qmetadata_enc_encode( if ( ndirections > 1 ) { +#ifdef DEBUGGING + assert( ndirections == 2 ); +#endif /* Reorder 2dir bands for more efficient encoding. */ if ( !hodirac_flag ) { @@ -217,6 +251,9 @@ ivas_error ivas_qmetadata_enc_encode( { set_f( hQMetaData->q_direction[1].band_data[i].energy_ratio, 0.0f, hQMetaData->q_direction[1].cfg.nblocks ); } +#ifdef DEBUGGING + assert( d == hQMetaData->numTwoDirBands ); +#endif hQMetaData->q_direction[1].cfg.nbands = hQMetaData->numTwoDirBands; } @@ -333,6 +370,25 @@ ivas_error ivas_qmetadata_enc_encode( bits_diff[d] = 0; } +#ifdef DEBUG_MODE_QMETADATA + { + int16_t j, k; + k = 0; + fprintf( pF_spcoh_orig, "%d %d ", frame, k ); + + for ( i = start_band; i < nbands; i++ ) + { + for ( j = 0; j < nblocks; j++ ) + { + if ( q_direction->coherence_band_data != NULL ) + { + fprintf( pF_spcoh_orig, " %d ", q_direction->coherence_band_data[i].spread_coherence[j] ); + } + } + } + fprintf( pF_spcoh_orig, "\n" ); + } +#endif bits_signaling[d] = 0; @@ -384,9 +440,21 @@ ivas_error ivas_qmetadata_enc_encode( { hMetaData->ind_list[next_ind_raw_flag].value = 1; /*rewrite flag*/ bits_ec = ivas_qmetadata_raw_encode_dir( hMetaData, q_direction, q_direction->cfg.nbands, q_direction->cfg.start_band ); +#ifdef DEBUGGING + assert( bits_dir_bands[0] == bits_ec ); +#endif } bits_dir[d] = bits_ec + 1; +#ifdef DEBUG_MODE_QMETADATA + tmp = bits_dir[d] - ( total_bits_1dir - ( bits_diff[d] + bits_coherence[d] + bits_signaling[d] ) ); +#endif extra_bits = hQMetaData->metadata_max_bits - ( hMetaData->nb_bits_tot - bit_pos_0 ); +#ifdef DEBUGGING + assert( bit_pos_start + bits_signaling[d] - 1 + bits_dir[d] == hMetaData->nb_bits_tot ); +#endif +#ifdef DEBUG_MODE_QMETADATA + ec_flag = 0; +#endif /* Encode quantized directions with EC band-wise */ if ( ( total_bits_1dir + bits_surround_coh <= hQMetaData->qmetadata_max_bit_req ) && ( bits_dir[d] + bits_diff[d] + bits_coherence[d] + bits_signaling[d] > total_bits_1dir ) && q_direction->cfg.nblocks > 1 ) @@ -437,13 +505,28 @@ ivas_error ivas_qmetadata_enc_encode( /* Write ec bits */ bits_ec = ivas_qmetadata_raw_encode_dir( hMetaData, q_direction, i + 1, i ); +#ifdef DEBUGGING + assert( bits_dir_bands[i] == bits_ec ); +#endif } bits_dir[d] += bits_dir_bands[i] + 1; } extra_bits = hQMetaData->metadata_max_bits - ( hMetaData->nb_bits_tot - bit_pos_0 ); +#ifdef DEBUGGING + if ( ( diff_bits <= 0 ) && ( bits_dir[d] + bits_diff[d] + bits_coherence[d] + bits_signaling[d] > total_bits_1dir ) ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "not possible!!" ); + } +#endif +#ifdef DEBUGGING + assert( bit_pos_start + bits_signaling[d] - 1 + bits_dir[d] == hMetaData->nb_bits_tot ); +#endif +#ifdef DEBUG_MODE_QMETADATA + ec_flag = 1; +#endif } /* Requantized directions */ @@ -486,6 +569,9 @@ ivas_error ivas_qmetadata_enc_encode( bits_dir[d] = hMetaData->nb_bits_tot; requantize_direction_EC_3( &extra_bits, q_direction, nbands, hMetaData, elevation_orig, azimuth_orig, ind_order ); bits_dir[d] = hMetaData->nb_bits_tot - bits_dir[d]; +#ifdef DEBUG_MODE_QMETADATA + ec_flag = 2; +#endif } /* finalize writing coherence */ @@ -501,6 +587,67 @@ ivas_error ivas_qmetadata_enc_encode( { total_bits_1dir = hQMetaData->metadata_max_bits - ( hMetaData->nb_bits_tot - bit_pos_0 ); } +#ifdef DEBUG_MODE_QMETADATA + { + int16_t j; + float tmp_f, mat_dist[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES]; + + fprintf( pF, "frame %d: diff %d coh %d surcoh %d ", frame, bits_diff[d], bits_coherence[d], bits_surround_coh ); + fprintf( pF, "dir %d %d,%d,%d %d %5.3f\n", ec_flag, hMetaData->nb_bits_tot - bit_pos_0, total_bits_1dir, bits_dir_raw, tmp, direction_distance( elevation_orig, azimuth_orig, q_direction, nbands, nblocks, mat_dist ) ); + fprintf( pF_azi, "frame %d/dir/ec %d/%d: ", frame, d, ec_flag ); + fprintf( pF_ele, "frame %d/dir/ec %d/%d: ", frame, d, ec_flag ); + fprintf( pF_ratio, "frame %d/dir %d: ", frame, d ); + /*fprintf( pF_spcoh, "frame %d/dir %d: ", frame, d ); */ + fprintf( pF_spcoh, " %d %d ", frame, d ); + if ( d == 0 ) + { + fprintf( pF_surcoh, "frame %d/dir %d: ", frame, d ); + } + + /* direction_distance( elevation_orig, azimuth_orig, q_direction, nbands, nblocks, mat_dist );*/ + for ( i = start_band; i < nbands; i++ ) + { + for ( j = 0; j < nblocks; j++ ) + { + fprintf( pF_azi, " %+5.2f ", (int16_t) ( 100.f * q_direction->band_data[i].azimuth[j] ) / 100.f ); + fprintf( pF_ele, " %+5.2f ", (int16_t) ( 100.f * q_direction->band_data[i].elevation[j] ) / 100.f ); + fprintf( pF_ratio, " %1.3f ", q_direction->band_data[i].energy_ratio[j] ); + if ( q_direction->coherence_band_data != NULL ) + { + fprintf( pF_spcoh, " %d ", q_direction->coherence_band_data[i].spread_coherence[j] ); + } + if ( d == 0 && hQMetaData->surcoh_band_data != NULL ) + { + fprintf( pF_surcoh, " %d ", hQMetaData->surcoh_band_data[i].surround_coherence[0] ); + } + } + } + fprintf( pF_azi, "\n" ); + fprintf( pF_ele, "\n" ); + fprintf( pF_ratio, "\n" ); + fprintf( pF_spcoh, "\n" ); + if ( d == 0 ) + { + fprintf( pF_surcoh, "\n" ); + } + + for ( i = 0; i < nblocks; i++ ) + { + for ( j = 0; j < nbands; j++ ) + { + dbgwrite( &( q_direction->band_data[j].azimuth[i] ), sizeof( float ), 1, 1, "./res/IVAS_QMETADATA_azi.bin" ); + dbgwrite( &( q_direction->band_data[j].elevation[i] ), sizeof( float ), 1, 1, "./res/IVAS_QMETADATA_ele.bin" ); + dbgwrite( &( mat_dist[j][i] ), sizeof( float ), 1, 1, "./res/IVAS_QMETADATA_dist.bin" ); + dbgwrite( &( q_direction->band_data[j].energy_ratio_index[i] ), sizeof( uint16_t ), 1, 1, "./res/IVAS_QMETADATA_diffuseness_index.bin" ); + tmp_f = 1.f - q_direction->band_data[j].energy_ratio[i]; + dbgwrite( &tmp_f, sizeof( float ), 1, 1, "./res/IVAS_QMETADATA_diffuseness.bin" ); + } + } + + j = (int16_t) ( hMetaData->nb_bits_tot ); + dbgwrite( &j, sizeof( int16_t ), 1, 1, "./res/IVAS_QMETADATA_bits.bin" ); + } +#endif /* Save quantized DOAs */ for ( i = start_band; i < nbands; i++ ) @@ -539,17 +686,48 @@ ivas_error ivas_qmetadata_enc_encode_hr_384_512( int16_t nbands, nblocks, start_band; int16_t ndirections, d; int16_t all_coherence_zero; +#ifdef DEBUG_MODE_QMETADATA + int16_t bits_no_dirs_coh; +#endif int16_t bits_ec; float azimuth_orig[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES], elevation_orig[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES]; ivas_error error; error = IVAS_ERR_OK; +#ifdef DEBUG_MODE_QMETADATA + + static FILE *pF = NULL; + static FILE *pF_azi = NULL; + static FILE *pF_ele = NULL; + static FILE *pF_ratio = NULL; + static FILE *pF_spcoh = NULL; + static FILE *pF_spcoh_orig = NULL; + static FILE *pF_surcoh = NULL; + + if ( pF == NULL ) + pF = fopen( "./res/qmetadata_enc.txt", "w" ); + if ( pF_azi == NULL ) + pF_azi = fopen( "./res/qmetadata_azi_enc.txt", "w" ); + if ( pF_ele == NULL ) + pF_ele = fopen( "./res/qmetadata_ele_enc.txt", "w" ); + if ( pF_ratio == NULL ) + pF_ratio = fopen( "./res/qmetadata_ratio_enc.txt", "w" ); + if ( pF_spcoh == NULL ) + pF_spcoh = fopen( "./res/qmetadata_spcoh_enc.txt", "w" ); + if ( pF_spcoh_orig == NULL ) + pF_spcoh_orig = fopen( "./res/qmetadata_spcoh_orig.txt", "w" ); + if ( pF_surcoh == NULL ) + pF_surcoh = fopen( "./res/qmetadata_surcoh_enc.txt", "w" ); +#endif ndirections = hQMetaData->no_directions; /* Check if coherence should be encoded */ all_coherence_zero = 1; +#ifdef DEBUG_MODE_QMETADATA + bits_no_dirs_coh = 0; +#endif if ( hQMetaData->q_direction->cfg.inactiveBands > 0 ) { push_next_indice( hMetaData, 1, 1 ); @@ -565,11 +743,17 @@ ivas_error ivas_qmetadata_enc_encode_hr_384_512( { all_coherence_zero = hQMetaData->all_coherence_zero; push_next_indice( hMetaData, all_coherence_zero, 1 ); /* signal coherence */ +#ifdef DEBUG_MODE_QMETADATA + bits_no_dirs_coh += 1; +#endif } /* encode 2 direction subbands position */ if ( ndirections == 2 && bits_sph_idx == 11 ) { +#ifdef DEBUG_MODE_QMETADATA + bits_no_dirs_coh += +#endif write_2dir_info( hMetaData, hQMetaData->twoDirBands, hQMetaData->q_direction[0].cfg.nbands, hQMetaData->numTwoDirBands ); d = 0; for ( i = hQMetaData->q_direction[1].cfg.start_band; i < hQMetaData->q_direction[1].cfg.nbands; i++ ) @@ -623,6 +807,25 @@ ivas_error ivas_qmetadata_enc_encode_hr_384_512( nblocks = q_direction->cfg.nblocks; start_band = q_direction->cfg.start_band; +#ifdef DEBUG_MODE_QMETADATA + { + int16_t k; + k = 0; + fprintf( pF_spcoh_orig, "%d %d ", frame, k ); + + for ( i = start_band; i < nbands; i++ ) + { + for ( j = 0; j < nblocks; j++ ) + { + if ( q_direction->coherence_band_data != NULL ) + { + fprintf( pF_spcoh_orig, " %d ", q_direction->coherence_band_data[i].spread_coherence[j] ); + } + } + } + fprintf( pF_spcoh_orig, "\n" ); + } +#endif q_direction->not_in_2D = 0; @@ -649,6 +852,65 @@ ivas_error ivas_qmetadata_enc_encode_hr_384_512( } bits_ec = hMetaData->nb_bits_tot - bits_ec; +#ifdef DEBUG_MODE_QMETADATA + { + float tmp_f; + fprintf( pF, "frame %d: diff %d ", frame, bits_diff[d] ); + fprintf( pF_azi, "frame %d/dir/ec %d: ", frame, d ); + fprintf( pF_ele, "frame %d/dir/ec %d: ", frame, d ); + fprintf( pF_ratio, "frame %d/dir %d: ", frame, d ); + /*fprintf( pF_spcoh, "frame %d/dir %d: ", frame, d ); */ + fprintf( pF_spcoh, " %d %d ", frame, d ); + + if ( d == 0 ) + { + fprintf( pF_surcoh, "frame %d/dir %d: ", frame, d ); + } + + /* direction_distance( elevation_orig, azimuth_orig, q_direction, nbands, nblocks, mat_dist );*/ + for ( i = start_band; i < nbands; i++ ) + { + for ( j = 0; j < nblocks; j++ ) + { + fprintf( pF_azi, " %+5.2f ", (int16_t) ( 100.f * q_direction->band_data[i].azimuth[j] ) / 100.f ); + fprintf( pF_ele, " %+5.2f ", (int16_t) ( 100.f * q_direction->band_data[i].elevation[j] ) / 100.f ); + fprintf( pF_ratio, " %1.3f ", q_direction->band_data[i].energy_ratio[j] ); + if ( q_direction->coherence_band_data != NULL ) + { + fprintf( pF_spcoh, " %d ", q_direction->coherence_band_data[i].spread_coherence[j] ); + } + if ( d == 0 && hQMetaData->surcoh_band_data != NULL ) + { + fprintf( pF_surcoh, " %d ", hQMetaData->surcoh_band_data[i].surround_coherence[j] ); + } + } + } + fprintf( pF, "\n" ); + fprintf( pF_azi, "\n" ); + fprintf( pF_ele, "\n" ); + fprintf( pF_ratio, "\n" ); + fprintf( pF_spcoh, "\n" ); + if ( d == 0 ) + { + fprintf( pF_surcoh, "\n" ); + } + + for ( i = 0; i < nblocks; i++ ) + { + for ( j = 0; j < nbands; j++ ) + { + dbgwrite( &( q_direction->band_data[j].azimuth[i] ), sizeof( float ), 1, 1, "./res/IVAS_QMETADATA_azi.bin" ); + dbgwrite( &( q_direction->band_data[j].elevation[i] ), sizeof( float ), 1, 1, "./res/IVAS_QMETADATA_ele.bin" ); + dbgwrite( &( q_direction->band_data[j].energy_ratio_index[i] ), sizeof( uint16_t ), 1, 1, "./res/IVAS_QMETADATA_diffuseness_index.bin" ); + tmp_f = 1.f - q_direction->band_data[j].energy_ratio[i]; + dbgwrite( &tmp_f, sizeof( float ), 1, 1, "./res/IVAS_QMETADATA_diffuseness.bin" ); + } + } + + j = (int16_t) ( hMetaData->nb_bits_tot ); + dbgwrite( &j, sizeof( int16_t ), 1, 1, "./res/IVAS_QMETADATA_bits.bin" ); + } +#endif /* Save quantized DOAs */ if ( bits_sph_idx == 11 ) @@ -716,6 +978,19 @@ void ivas_qmetadata_enc_sid_encode( metadata_sid_bits = ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS; } +#ifdef DEBUG_MODE_QMETADATA + static FILE *pF_azi = NULL; + static FILE *pF_ele = NULL; + static FILE *pF_ratio = NULL; + + if ( pF_azi == NULL ) + pF_azi = fopen( "./res/qmetadata_sid_azi_enc.txt", "w" ); + if ( pF_ele == NULL ) + pF_ele = fopen( "./res/qmetadata_sid_ele_enc.txt", "w" ); + if ( pF_ratio == NULL ) + pF_ratio = fopen( "./res/qmetadata_sid_ratio_enc.txt", "w" ); + +#endif /* Save initial position in bitstream */ bit_pos_start = hMetaData->nb_bits_tot; @@ -914,6 +1189,26 @@ void ivas_qmetadata_enc_sid_encode( } } +#ifdef DEBUG_MODE_QMETADATA + { + fprintf( pF_azi, "frame %d: ", frame ); + fprintf( pF_ele, "frame %d: ", frame ); + fprintf( pF_ratio, "frame %d: ", frame ); + + + /* Data is not used currently. Fix function when needed. */ + /*direction_distance( elevation_orig, azimuth_orig, q_direction->elevation, q_direction->azimuth, nbands, nblocks, mat_dist );*/ + for ( b = start_band; b < nbands; b++ ) + { + fprintf( pF_azi, " %+5.2f ", (int16_t) ( 100.f * avg_azimuth[b] ) / 100.f ); + fprintf( pF_ele, " %+5.2f ", (int16_t) ( 100.f * avg_elevation[b] ) / 100.f ); + fprintf( pF_ratio, " %1.3f ", q_direction->band_data[b].energy_ratio[0] ); + } + fprintf( pF_azi, "\n" ); + fprintf( pF_ele, "\n" ); + fprintf( pF_ratio, "\n" ); + } +#endif /* fill bits*/ assert( ( hMetaData->nb_bits_tot - bit_pos_start ) <= metadata_sid_bits && "Too many written bits!" ); @@ -951,6 +1246,9 @@ void reset_metadata_spatial( { if ( ivas_format == SBA_FORMAT ) { +#ifdef DEBUGGING + assert( hMetaData->ind_list[0].nb_bits == 1 ); +#endif hMetaData->ind_list[0].value = 1; metadata_sid_bits = (int16_t) ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS; @@ -986,6 +1284,9 @@ void reset_metadata_spatial( } hMetaData->nb_ind_tot = j; +#ifdef DEBUGGING + assert( ( hMetaData->nb_bits_tot == ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS ) && "Problem of SID metadata in SCE" ); +#endif } } else @@ -1005,6 +1306,9 @@ void reset_metadata_spatial( hMetaData->nb_bits_tot -= hMetaData->ind_list[hMetaData->nb_ind_tot].nb_bits; hMetaData->ind_list[hMetaData->nb_ind_tot].nb_bits = -1; } +#ifdef DEBUGGING + assert( hMetaData->nb_bits_tot == nb_bits_metadata && "Problem in metadata for SCE" ); +#endif } return; @@ -1499,6 +1803,9 @@ static int16_t ivas_qmetadata_entropy_encode_diffuseness( { ivas_diffuseness_huff_ec_encode( hMetaData, avr_idx[b] ); } +#ifdef DEBUGGING + assert( ( hMetaData->nb_bits_tot - start_bit_pos ) == diffuseness_bits_huff + 1 ); +#endif } else { @@ -1518,6 +1825,9 @@ static int16_t ivas_qmetadata_entropy_encode_diffuseness( *diffuseness_index_max_ec_frame = DIRAC_DIFFUSE_LEVELS - 1; } +#ifdef DEBUGGING + assert( ( hMetaData->nb_bits_tot - start_bit_pos ) <= 1 + diffuseness_bits_raw ); +#endif return ( hMetaData->nb_bits_tot - start_bit_pos ); } @@ -1671,6 +1981,10 @@ static void ivas_qmetadata_encode_quasi_uniform( { int16_t bits; uint16_t tresh; +#ifdef DEBUGGING + assert( ( alphabet_size >= 1 ) ); + assert( value < alphabet_size ); +#endif bits = 30 - norm_l( alphabet_size ); /* bits = floor(log2(alphabet_size)) */ tresh = ( 1U << ( bits + 1 ) ) - alphabet_size; @@ -1906,6 +2220,10 @@ static int16_t ivas_qmetadata_encode_quasi_uniform_length( { int16_t bits; uint16_t tresh; +#ifdef DEBUGGING + assert( ( alphabet_size >= 1 ) ); + assert( value < alphabet_size ); +#endif bits = 30 - norm_l( alphabet_size ); /* bits = floor(log2(alphabet_size)) */ tresh = ( 1U << ( bits + 1 ) ) - alphabet_size; @@ -2124,6 +2442,9 @@ static int16_t ivas_qmetadata_entropy_encode_dir( { avg_elevation_index_projected = ivas_dirac_project_elevation_index( avg_elevation_index, avg_elevation_alphabet, q_direction->band_data[i].elevation_m_alphabet[j] ); } +#ifdef DEBUGGING + assert( ( 0 <= avg_elevation_index_projected ) && ( avg_elevation_index_projected < q_direction->band_data[i].elevation_m_alphabet[j] ) ); +#endif if ( q_direction->cfg.mc_ls_setup != MC_LS_SETUP_INVALID ) { @@ -2171,6 +2492,9 @@ static int16_t ivas_qmetadata_entropy_encode_dir( { egr_size_elevation += ivas_qmetadata_encode_extended_gr_length( dist_elevation_indexes[i], dist_elevation_alphabets[i], gr_param_elevation ); } +#ifdef DEBUGGING + assert( egr_size_elevation <= gr_size_elevation ); +#endif } elevation_bits_ec += ivas_qmetadata_encode_quasi_uniform_length( gr_param_elevation, 4 + 1 ) + egr_size_elevation; @@ -2234,6 +2558,9 @@ static int16_t ivas_qmetadata_entropy_encode_dir( /* project the quantized average azimuth angle to the same grid as the current sample */ avg_azimuth_index_projected = ivas_dirac_project_azimuth_index( avg_azimuth_index, avg_azimuth_alphabet, q_direction->band_data[i].azimuth_m_alphabet[j] ); } +#ifdef DEBUGGING + assert( ( 0 <= avg_azimuth_index_projected ) && ( avg_azimuth_index_projected < q_direction->band_data[i].azimuth_m_alphabet[j] ) ); +#endif dist_azimuth_indexes[idx] = ivas_qmetadata_reorder_azimuth_index( ivas_qmetadata_dereorder_generic( q_direction->band_data[i].azimuth_index[j] ) + ( q_direction->band_data[i].azimuth_m_alphabet[j] >> 1 ), avg_azimuth_index_projected, q_direction->band_data[i].azimuth_m_alphabet[j] ); dist_azimuth_alphabets[idx] = q_direction->band_data[i].azimuth_m_alphabet[j]; @@ -2274,6 +2601,9 @@ static int16_t ivas_qmetadata_entropy_encode_dir( { egr_size_azimuth += ivas_qmetadata_encode_extended_gr_length( dist_azimuth_indexes[i], dist_azimuth_alphabets[i], gr_param_azimuth ); } +#ifdef DEBUGGING + assert( egr_size_azimuth <= gr_size_azimuth ); +#endif } azimuth_bits_ec += ivas_qmetadata_encode_quasi_uniform_length( gr_param_azimuth, 5 + 1 ) + egr_size_azimuth; @@ -2556,6 +2886,11 @@ ivas_qmetadata_encode_extended_gr_length( int16_t bits; uint16_t msb, lsb; +#ifdef DEBUGGING + assert( alphabet_size >= 1 ); + assert( value < alphabet_size ); + assert( ( gr_param >= 0 ) && ( gr_param <= 15 ) ); +#endif msb_alphabet_size = ( alphabet_size + ( 1U << gr_param ) - 1 ) >> gr_param; @@ -2597,6 +2932,9 @@ static int16_t ivas_qmetadata_reorder_elevation_index( { int16_t elevation_alphabet_half; int16_t elevation_index_reordered; +#ifdef DEBUGGING + assert( ( elevation_alphabet & 0x01 ) == 1 ); /* elevation_alphabet has the form 2 * n_points + 1 */ +#endif elevation_alphabet_half = elevation_alphabet >> 1; elevation_index_reordered = elevation_index - avg_elevation_index; @@ -2613,6 +2951,9 @@ static int16_t ivas_qmetadata_reorder_elevation_index( /* fold reduced signed distance value for converting to unsigned */ elevation_index_reordered = ivas_qmetadata_reorder_generic( elevation_index_reordered ); +#ifdef DEBUGGING + assert( ( 0 <= elevation_index_reordered ) && ( elevation_index_reordered < elevation_alphabet ) ); +#endif return elevation_index_reordered; } @@ -2652,12 +2993,21 @@ static int16_t ivas_qmetadata_reorder_azimuth_index( } /* fold reduced signed distance value for converting to unsigned */ azimuth_index_reordered = ivas_qmetadata_reorder_generic( azimuth_index_reordered ); +#ifdef DEBUGGING + assert( ( 0 <= azimuth_index_reordered ) && ( azimuth_index_reordered < azimuth_alphabet ) ); +#endif } else { /* for North and South poles, a single azimuth direction exists */ +#ifdef DEBUGGING + assert( ( azimuth_index == 0 ) || ( azimuth_index == MASA_NO_INDEX ) ); +#endif azimuth_index_reordered = 0; +#ifdef DEBUGGING + assert( avg_azimuth_index == 0 ); +#endif } return azimuth_index_reordered; @@ -2679,6 +3029,11 @@ void ivas_qmetadata_encode_extended_gr( uint16_t msb_alphabet_size; uint16_t msb, lsb, cnt; +#ifdef DEBUGGING + assert( alphabet_size >= 1 ); + assert( value < alphabet_size ); + assert( ( gr_param >= 0 ) && ( gr_param <= 31 ) ); +#endif msb_alphabet_size = ( alphabet_size + ( 1U << gr_param ) - 1 ) >> gr_param; @@ -2764,6 +3119,9 @@ static int16_t truncGR0( for ( i = 0; i < len; i++ ) { +#ifdef DEBUGGING + assert( data_idx[i] < MASA_NO_INDEX ); +#endif data_idx[i] = quantize_phi( data[i] + 180, 0, &data_hat[i], 8 ); data_hat[i] -= 180; data_idx[i] = remap3b[data_idx[i]]; @@ -2827,6 +3185,13 @@ static int16_t truncGR0( if ( bits > bits_allowed ) { +#ifdef DEBUGGING + assert( bits_allowed > len ); + for ( i = 0; i < len; i++ ) + { + assert( data_idx[i] <= 1 ); + } +#endif sort_desc_ind( diff, len, indx ); for ( i = len - 1; i >= 0; i-- ) @@ -2896,6 +3261,9 @@ static int16_t truncGR0_chan( for ( i = 0; i < len; i++ ) { +#ifdef DEBUGGING + assert( data_idx[i] < MASA_NO_INDEX ); +#endif data_idx[i] = quantize_phi_chan_lbr( data[i], &data_hat[i], 9 ); bits += ivas_qmetadata_encode_extended_gr_length( data_idx[i], 9, 0 ); @@ -3200,6 +3568,9 @@ static int16_t encode_directions_subband( bits_dir0[max_nb_idx] -= 1; allowed_bits -= 1; } +#ifdef DEBUGGING + assert( bits_dir0[max_nb_idx] > 0 ); +#endif } if ( no_subframes > 1 ) { @@ -3498,6 +3869,12 @@ static ivas_error requantize_direction_EC_3( } } } +#ifdef DEBUGGING + if ( diff > 0 ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Not enough bits in requantize_direction_EC_3(); %d bits written \n", nbits ); + } +#endif *extra_bits = -diff; @@ -3871,6 +4248,12 @@ static ivas_error write_ec_direction( } } +#ifdef DEBUGGING + if ( min_val == MASA_NO_INDEX ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "No azimuth data to be coded in write_ec_direction()" ); + } +#endif /* write min*/ bits_crt = hMetaData->nb_bits_tot; @@ -3889,6 +4272,15 @@ static ivas_error write_ec_direction( } } } +#ifdef DEBUGGING + else + { + if ( use_context != -3 ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Wrong use_context value in write_ec_direction()" ); + } + } +#endif } else { @@ -4481,6 +4873,15 @@ static int16_t encode_surround_coherence( } } } +#ifdef DEBUGGING + for ( i = 0; i < coding_subbands; i++ ) + { + for ( j = 1; j < q_direction->cfg.nblocks; j++ ) + { + hQMetaData->surcoh_band_data[i].surround_coherence[j] = hQMetaData->surcoh_band_data[i].surround_coherence[0]; + } + } +#endif return nbits; } @@ -5048,6 +5449,9 @@ static int16_t ivas_qmetadata_quantize_coherence( { /* make two indxes */ no_cb = 1; +#ifdef DEBUGGING + assert( coding_subbands % 2 == 0 ); +#endif for ( j = 0; j < coding_subbands / 2; j++ ) { @@ -5217,6 +5621,9 @@ static int16_t write_2dir_info( dif_p[i] = p[i] - p[i - 1] - 1; } +#ifdef DEBUGGING + assert( k == j ); +#endif j = hMetaData->nb_bits_tot; for ( i = 0; i < k; i++ ) { @@ -5264,6 +5671,9 @@ static void transform_azimuth_dir2( { hQMetaData->q_direction[1].band_data[i].azimuth[b] += 360; } +#ifdef DEBUGGING + assert( hQMetaData->q_direction[1].band_data[i].azimuth[b] < 180 && hQMetaData->q_direction[1].band_data[i].azimuth[b] >= -180 ); +#endif } } } @@ -5271,6 +5681,38 @@ static void transform_azimuth_dir2( return; } +#ifdef DEBUG_MODE_QMETADATA +/*------------------------------------------------------------------------- + * DEBUG function direction_distance() + * + *------------------------------------------------------------------------*/ + +static float direction_distance( + float elevation[DIRAC_MAX_NBANDS][MAX_PARAM_SPATIAL_SUBFRAMES], + float azimuth[DIRAC_MAX_NBANDS][MAX_PARAM_SPATIAL_SUBFRAMES], + IVAS_QDIRECTION *q_direction, + const int16_t dim1, + const int16_t dim2, + float mat_dist[DIRAC_MAX_NBANDS][MAX_PARAM_SPATIAL_SUBFRAMES] ) +{ + float d; + int16_t i, j; + + d = 0; + for ( i = 0; i < dim1; i++ ) + { + for ( j = 0; j < dim2; j++ ) + { + mat_dist[i][j] = sinf( elevation[i][j] * PI_OVER_180 ) * sinf( q_direction->band_data[i].elevation[j] * PI_OVER_180 ) + + cosf( elevation[i][j] * PI_OVER_180 ) * cosf( q_direction->band_data[i].elevation[j] * PI_OVER_180 ) * cosf( ( azimuth[i][j] - q_direction->band_data[i].azimuth[j] ) * PI_OVER_180 ); + + d += fabsf( mat_dist[i][j] ); + } + } + + return d / (float) ( dim1 * dim2 ); +} +#endif static int16_t divide_GR_orders( @@ -5571,6 +6013,16 @@ void ivas_omasa_encode_masa_to_total( int16_t bits_pos, nb_bits; int16_t n_streams, len_stream; +#ifdef DEBUG_MODE_QMETADATA + static FILE *pF = NULL; + static FILE *pF_ratio = NULL; + + if ( pF == NULL ) + pF = fopen( "./res/qmetadata_ism_qidx__enc.txt", "w" ); + if ( pF_ratio == NULL ) + pF_ratio = fopen( "./res/qmetadata_masa2tot_enc.txt", "w" ); + +#endif bits_pos = hMetaData->nb_bits_tot; k = 0; @@ -5726,6 +6178,29 @@ void ivas_omasa_encode_masa_to_total( } assert( nb_bits == ( hMetaData->nb_bits_tot - bits_pos ) ); +#ifdef DEBUG_MODE_QMETADATA + { + + fprintf( pF, "frame %d: ", frame ); + fprintf( pF_ratio, "frame %d: ", frame ); + + + /* direction_distance( elevation_orig, azimuth_orig, q_direction, nbands, nblocks, mat_dist );*/ + for ( i = 0; i < nbands; i++ ) + { + for ( j = 0; j < 4; j++ ) + { + fprintf( pF_ratio, " %5.2f ", hQMetaData->masa_to_total_energy_ratio[j][i] ); + } + } + for ( i = 0; i < 20; i++ ) + { + fprintf( pF, " %4d ", q_idx[i] ); + } + fprintf( pF, "\n" ); + fprintf( pF_ratio, "\n" ); + } +#endif return; } diff --git a/lib_enc/ivas_range_uni_enc.c b/lib_enc/ivas_range_uni_enc.c index 6781c750a..82f6813c2 100644 --- a/lib_enc/ivas_range_uni_enc.c +++ b/lib_enc/ivas_range_uni_enc.c @@ -40,6 +40,9 @@ #include "options.h" #include "prot.h" #include "wmc_auto.h" +#ifdef DEBUGGING +#include "debug.h" +#endif /* @@ -94,6 +97,9 @@ void rc_uni_enc_encode_fast( ) { uint32_t r, tmp; +#ifdef DEBUGGING + assert( tot_shift <= 16 ); +#endif r = rc_st_enc->rc_range >> tot_shift; tmp = r * cum_freq; @@ -156,6 +162,10 @@ int16_t rc_uni_enc_finish( int16_t total_bit_count; uint32_t val, mask; int16_t bits; +#ifdef DEBUGGING + assert( rc_st_enc->rc_range >= 0x01000000 ); /* rc_range is normalized */ + assert( rc_st_enc->last_byte_bit_count == -1 ); /* make sure finalization was not done already */ +#endif /* floor(log2(x)) = floor(log2(x >> 24)) + 24, for any x >= 2 ^ 24 */ /* 32 - floor(log2(y)) = norm_ul(y) + 1 = norm_l(y >> 24) - 22 */ @@ -164,6 +174,9 @@ int16_t rc_uni_enc_finish( bits++; /* conservative number of bits, because the decoder only has rc_range available */ +#ifdef DEBUGGING + assert( ( bits >= 2 ) && ( bits <= 9 ) ); /* depends on rc_range, which is normalized */ +#endif mask = 0xFFFFFFFFu >> bits; val = ( rc_st_enc->rc_low + mask ) & ~mask; @@ -188,29 +201,51 @@ int16_t rc_uni_enc_finish( /* rc_carry_count > 0, therefore the last call to rc_uni_enc_shift incremented rc_carry_count */ if ( rc_st_enc->rc_cache >= 0 ) /* may actually be always true, but it is difficult to prove formally */ { +#ifdef DEBUGGING + assert( rc_st_enc->byte_count < RANGE_UNI_BUFFER_BYTES_MAX ); +#endif rc_st_enc->byte_buffer[rc_st_enc->byte_count++] = (uint8_t) ( rc_st_enc->rc_cache + rc_st_enc->rc_carry ); } while ( rc_st_enc->rc_carry_count > 1 ) { +#ifdef DEBUGGING + assert( rc_st_enc->byte_count < RANGE_UNI_BUFFER_BYTES_MAX ); +#endif rc_st_enc->byte_buffer[rc_st_enc->byte_count++] = (uint8_t) ( rc_st_enc->rc_carry + 0xFF ); rc_st_enc->rc_carry_count--; } /* pack the last 1 to 8 bits into the MSB of the last byte, with zero padding into the LSB */ +#ifdef DEBUGGING + assert( rc_st_enc->byte_count < RANGE_UNI_BUFFER_BYTES_MAX ); +#endif rc_st_enc->byte_buffer[rc_st_enc->byte_count++] = (uint8_t) ( ( rc_st_enc->rc_carry + 0xFF ) & ( 0xFFu << ( 8 - bits ) ) ); rc_st_enc->last_byte_bit_count = bits; } else { /* rc_carry_count == 0, therefore the last call to rc_uni_enc_shift wrote into rc_cache */ +#ifdef DEBUGGING + assert( rc_st_enc->rc_cache >= 0 ); +#endif /* pack the last 1 to 8 bits into the MSB of the last byte, with zero padding into the LSB */ +#ifdef DEBUGGING + assert( rc_st_enc->byte_count < RANGE_UNI_BUFFER_BYTES_MAX ); +#endif rc_st_enc->byte_buffer[rc_st_enc->byte_count++] = (uint8_t) ( ( rc_st_enc->rc_cache + rc_st_enc->rc_carry ) & ( 0xFFu << ( 8 - bits ) ) ); rc_st_enc->last_byte_bit_count = bits; } +#ifdef DEBUGGING + assert( ( rc_st_enc->last_byte_bit_count >= 1 ) && ( rc_st_enc->last_byte_bit_count <= 8 ) ); + assert( rc_st_enc->byte_count >= 1 ); +#endif total_bit_count = ( ( rc_st_enc->byte_count - 1 ) << 3 ) + rc_st_enc->last_byte_bit_count; +#ifdef DEBUGGING + assert( total_bit_count >= 2 ); +#endif return total_bit_count; } @@ -226,6 +261,11 @@ int16_t rc_uni_enc_virtual_finish( RangeUniEncState *rc_st_enc /* i : RC state handle */ ) { +#ifdef DEBUGGING + assert( rc_st_enc->rc_range >= 0x01000000 ); /* rc_range is normalized */ + assert( rc_st_enc->last_byte_bit_count == -1 ); /* make sure finalization was not done already */ + assert( sizeof( rc_st_enc->rc_cache ) == 2 ); /* ensure the sign bit computation is correct */ +#endif /* byte_count bytes have already been written to the byte_buffer array @@ -254,11 +294,17 @@ static void rc_uni_enc_shift( { if ( rc_st_enc->rc_cache >= 0 ) { +#ifdef DEBUGGING + assert( rc_st_enc->byte_count < RANGE_UNI_BUFFER_BYTES_MAX ); +#endif rc_st_enc->byte_buffer[rc_st_enc->byte_count++] = (uint8_t) ( rc_st_enc->rc_cache + rc_st_enc->rc_carry ); } while ( rc_st_enc->rc_carry_count > 0 ) { +#ifdef DEBUGGING + assert( rc_st_enc->byte_count < RANGE_UNI_BUFFER_BYTES_MAX ); +#endif rc_st_enc->byte_buffer[rc_st_enc->byte_count++] = (uint8_t) ( rc_st_enc->rc_carry + 0xFF ); rc_st_enc->rc_carry_count--; } @@ -290,6 +336,9 @@ void rc_uni_enc_encode_bits( ) { uint32_t tmp; +#ifdef DEBUGGING + assert( bits <= 16 ); +#endif rc_st_enc->rc_range >>= bits; tmp = rc_st_enc->rc_range * value; diff --git a/lib_enc/ivas_rom_enc.c b/lib_enc/ivas_rom_enc.c index ebbffc089..2bb4efdd8 100644 --- a/lib_enc/ivas_rom_enc.c +++ b/lib_enc/ivas_rom_enc.c @@ -32,6 +32,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "ivas_cnst.h" #include @@ -720,6 +723,7 @@ const float Stereo_dmx_wnd_coef_48k[L_FRAME48k] = { }; +#ifdef FIX_891_PARAMUPMIX_CLEANUP /*----------------------------------------------------------------------------------* * ParamUpmix ROM tables *----------------------------------------------------------------------------------*/ @@ -767,6 +771,119 @@ const HUFF_TABLE huff_beta_table = 4, 7, 8, 9, 9, 11, 13 } } }; +#else +const HUFF_TABLE huff_alpha_table[2] = +{ + { /* Alfa Fine */ + { /* df0 */ + { 0x0002ce, 0x000b5e, 0x0004fe, 0x0005ae, 0x00027e, 0x0002de, 0x00016a, 0x0000b2, 0x00004a, 0x00004b, + 0x0000b6, 0x00004e, 0x000024, 0x00002e, 0x00000a, 0x000006, 0x000000, 0x000007, 0x000008, 0x00002f, + 0x000026, 0x000058, 0x0000b4, 0x00009e, 0x00016e, 0x000166, 0x0002df, 0x0002cf, 0x00027c, 0x00027d, + 0x0004ff, 0x000b5f, 0x0002d6 }, + { 10, 12, 11, 11, 10, 10, 9, 8, 7, 7, + 8, 7, 6, 6, 4, 3, 1, 3, 4, 6, + 6, 7, 8, 8, 9, 9, 10, 10, 10, 10, + 11, 12, 10 } + }, + { /* df */ + { 0x0011de, 0x011ffe, 0x013dea, 0x013df6, 0x008eea, 0x013df7, 0x013dee, 0x013deb, 0x013dec, 0x008eee, + 0x008ffe, 0x009efe, 0x0047fe, 0x004f7c, 0x0023fe, 0x0011fe, 0x0013fe, 0x0008f6, 0x0009ee, 0x000476, + 0x00047a, 0x0004f6, 0x00023a, 0x00027a, 0x00027e, 0x00013e, 0x00009a, 0x00004c, 0x00004e, 0x000012, + 0x00000a, 0x000006, 0x000000, 0x000007, 0x00000b, 0x000010, 0x000022, 0x000046, 0x00009b, 0x00013c, + 0x00011c, 0x00023e, 0x00023c, 0x0004fe, 0x00047e, 0x0009fe, 0x0008fe, 0x0008f7, 0x0013ff, 0x0011df, + 0x0027bc, 0x004f7e, 0x004776, 0x009efa, 0x009ef4, 0x013dfe, 0x008eeb, 0x008ee8, 0x013dff, 0x008ee9, + 0x008eef, 0x011fff, 0x013ded, 0x013def, 0x0011dc }, + { 13, 17, 17, 17, 16, 17, 17, 17, 17, 16, + 16, 16, 15, 15, 14, 13, 13, 12, 12, 11, + 11, 11, 10, 10, 10, 9, 8, 7, 7, 5, + 4, 3, 1, 3, 4, 5, 6, 7, 8, 9, + 9, 10, 10, 11, 11, 12, 12, 12, 13, 13, + 14, 15, 15, 16, 16, 17, 16, 16, 17, 16, + 16, 17, 17, 17, 13 } + }, + { /* dt */ + { 0x00eeee, 0x03b3ee, 0x03b3f6, 0x03b3fc, 0x01d9bc, 0x01d9bd, 0x01d9b2, 0x03b3fe, 0x01d9be, 0x01d9f6, + 0x01d9fc, 0x00ecda, 0x00ecfa, 0x00eeef, 0x00766e, 0x007776, 0x003b3a, 0x003bba, 0x001d9a, 0x001ddc, + 0x001dde, 0x000eec, 0x000764, 0x000772, 0x0003b0, 0x0003b8, 0x0001da, 0x0001de, 0x000072, 0x000038, + 0x00001e, 0x000006, 0x000000, 0x000002, 0x00001f, 0x00003a, 0x000073, 0x0001df, 0x0001db, 0x0003ba, + 0x0003b1, 0x000773, 0x000765, 0x000eed, 0x000ecc, 0x001d9e, 0x001d9c, 0x003bbe, 0x003b3b, 0x00777e, + 0x00767c, 0x00eefe, 0x00ecfc, 0x00ecd8, 0x01d9fd, 0x01d9fa, 0x01d9bf, 0x01d9b6, 0x01d9b3, 0x03b3fd, + 0x01d9b7, 0x03b3ff, 0x03b3ef, 0x03b3f7, 0x00eeff }, + { 16, 18, 18, 18, 17, 17, 17, 18, 17, 17, + 17, 16, 16, 16, 15, 15, 14, 14, 13, 13, + 13, 12, 11, 11, 10, 10, 9, 9, 7, 6, + 5, 3, 1, 2, 5, 6, 7, 9, 9, 10, + 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, + 15, 16, 16, 16, 17, 17, 17, 17, 17, 18, + 17, 18, 18, 18, 16 } + } + }, /* End Alfa Fine */ + { /* Alfa Coarse */ + { /* df0 */ + { 0x0003be, 0x0003fe, 0x0001fe, 0x0000fe, 0x00003e, 0x00003a, 0x00001e, 0x000002, 0x000000, 0x000006, + 0x00001c, 0x00007e, 0x000076, 0x0000ee, 0x0001de, 0x0003ff, 0x0003bf }, + { 10, 10, 9, 8, 6, 6, 5, 2, 1, 3, + 5, 7, 7, 8, 9, 10, 10 } + }, + { /* df */ + { 0x007c76, 0x03e3fe, 0x01f1f6, 0x01f1f7, 0x00f8ea, 0x007c74, 0x007c7c, 0x001f1c, 0x000f9e, 0x0007ce, + 0x0003e2, 0x0001f0, 0x0000fa, 0x00007e, 0x00000e, 0x000006, 0x000000, 0x000002, 0x00001e, 0x00007f, + 0x0000fb, 0x0001f2, 0x0003e6, 0x0007c6, 0x000f9f, 0x001f1e, 0x007c7e, 0x00f8fe, 0x00f8fa, 0x01f1fe, + 0x00f8eb, 0x03e3ff, 0x007c77 }, + { 15, 18, 17, 17, 16, 15, 15, 13, 12, 11, + 10, 9, 8, 7, 4, 3, 1, 2, 5, 7, + 8, 9, 10, 11, 12, 13, 15, 16, 16, 17, + 16, 18, 15 } + }, + { /* dt */ + { 0x003efc, 0x00fbfa, 0x007ddc, 0x00fbfe, 0x007dde, 0x007dfc, 0x003ef6, 0x001f76, 0x000fba, 0x000fbe, + 0x0003ec, 0x0001f2, 0x0000f8, 0x00007e, 0x00001e, 0x000006, 0x000000, 0x000002, 0x00000e, 0x00007f, + 0x0000fa, 0x0001f3, 0x0003ed, 0x0007dc, 0x000fbc, 0x001f7a, 0x003ef7, 0x007dfe, 0x007ddf, 0x00fbff, + 0x007ddd, 0x00fbfb, 0x003efd }, + { 14, 16, 15, 16, 15, 15, 14, 13, 12, 12, + 10, 9, 8, 7, 5, 3, 1, 2, 4, 7, + 8, 9, 10, 11, 12, 13, 14, 15, 15, 16, + 15, 16, 14 } + } + } /* End Alfa Coarse */ +}; + +const HUFF_TABLE huff_beta_table[2] = +{ + { /* Beta Fine */ + { /* df0 */ + { 0x000000, 0x000002, 0x000006, 0x00000e, 0x00001e, 0x00003e, 0x00007e, 0x0000fe, 0x0000ff }, + { 1, 2, 3, 4, 5, 6, 7, 8, 8 } + }, + { /* df */ + { 0x001f1e, 0x000f8e, 0x0003e2, 0x0001f2, 0x0000fa, 0x00007e, 0x00001e, 0x000006, 0x000000, 0x000002, + 0x00000e, 0x00007f, 0x0000fb, 0x0001f3, 0x0001f0, 0x0007c6, 0x001f1f }, + { 13, 12, 10, 9, 8, 7, 5, 3, 1, 2, + 4, 7, 8, 9, 9, 11, 13 } + }, + { /* dt */ + { 0x007dfe, 0x003efe, 0x000fbe, 0x0003ee, 0x0000fa, 0x00007e, 0x00001e, 0x000006, 0x000000, 0x000002, + 0x00000e, 0x00007f, 0x00007c, 0x0001f6, 0x0007de, 0x001f7e, 0x007dff }, + { 15, 14, 12, 10, 8, 7, 5, 3, 1, 2, + 4, 7, 7, 9, 11, 13, 15 } + } + }, /* End Beta Fine */ + { /* Beta Coarse */ + { /* df0 */ + { 0x000000, 0x000002, 0x000006, 0x00000e, 0x00000f }, + { 1, 2, 3, 4, 4 } + }, + { /* df */ + { 0x0000fe, 0x00003e, 0x00000e, 0x000006, 0x000000, 0x000002, 0x00001e, 0x00007e, 0x0000ff }, + { 8, 6, 4, 3, 1, 2, 5, 7, 8 } + }, + { /* dt */ + { 0x0000fe, 0x00007e, 0x00001e, 0x000006, 0x000000, 0x000002, 0x00000e, 0x00003e, 0x0000ff }, + { 8, 7, 5, 3, 1, 2, 4, 6, 8 } + } + } /* End Beta Coarse */ +}; +#endif const int16_t mc_paramupmix_fb_remix_order[4] = {0, 1, 2, 3}; diff --git a/lib_enc/ivas_rom_enc.h b/lib_enc/ivas_rom_enc.h index c15d1a27b..9e6363fb0 100644 --- a/lib_enc/ivas_rom_enc.h +++ b/lib_enc/ivas_rom_enc.h @@ -35,6 +35,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "ivas_cnst.h" @@ -123,6 +126,7 @@ extern const float Stereo_dmx_s_wnd_coef_48k[L_FRAME48k >> 4]; extern const float Stereo_dmx_wnd_coef_32k[L_FRAME32k]; extern const float Stereo_dmx_wnd_coef_48k[L_FRAME48k]; +#ifdef FIX_891_PARAMUPMIX_CLEANUP /*----------------------------------------------------------------------------------* * ParamUpmix ROM tables *----------------------------------------------------------------------------------*/ @@ -131,6 +135,12 @@ extern const HUFF_TABLE huff_alpha_table; extern const HUFF_TABLE huff_beta_table; extern const int16_t mc_paramupmix_fb_remix_order[4]; +#else +extern const HUFF_TABLE huff_alpha_table[2]; +extern const HUFF_TABLE huff_beta_table[2]; +extern const int16_t mc_paramupmix_fb_remix_order[4]; + +#endif /*----------------------------------------------------------------------------------* * ParamMC ROM tables *----------------------------------------------------------------------------------*/ diff --git a/lib_enc/ivas_sba_enc.c b/lib_enc/ivas_sba_enc.c index d81b73c6f..1b62335b9 100644 --- a/lib_enc/ivas_sba_enc.c +++ b/lib_enc/ivas_sba_enc.c @@ -40,6 +40,9 @@ #include "prot.h" #include "ivas_prot.h" #include "ivas_rom_com.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" @@ -75,6 +78,20 @@ void ivas_sba_getTCs( } } +#ifdef DEBUG_MODE_DIRAC + for ( int16_t n = 0; n < st_ivas->nchan_transport; n++ ) + { + int16_t tmp[L_FRAME48k]; + char file_name[50] = { 0 }; + + sprintf( file_name, "./res/ivas_dirac_enc_%d.%d.pcm", n, (int16_t) ( input_frame * 0.05 ) ); + for ( int16_t i = 0; i < input_frame; i++ ) + { + tmp[i] = (int16_t) ( sba_data[n][i] + 0.5f ); + } + dbgwrite( tmp, sizeof( int16_t ), input_frame, 1, file_name ); + } +#endif return; } diff --git a/lib_enc/ivas_sce_enc.c b/lib_enc/ivas_sce_enc.c index c72feda1d..ae6496657 100644 --- a/lib_enc/ivas_sce_enc.c +++ b/lib_enc/ivas_sce_enc.c @@ -38,6 +38,9 @@ #include "prot.h" #include "ivas_prot.h" #include "ivas_rom_com.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" @@ -114,6 +117,10 @@ ivas_error ivas_sce_enc( st->input_bwidth = st->last_input_bwidth; /* updated in BWD */ st->bwidth = st->last_bwidth; /* updated in BWD */ st->rate_switching_reset = 0; +#ifdef DEBUGGING + st->force = st_ivas->hEncoderConfig->force; + st->id_element = sce_id; +#endif /*---------------------------------------------------------------* * Time Domain Transient Detector @@ -164,6 +171,10 @@ ivas_error ivas_sce_enc( flag_16k_smc = 1; } +#ifdef DEBUG_MODE_INFO + dbgwrite( st->input - NS2SA( st->input_Fs, ACELP_LOOK_NS ), sizeof( float ), input_frame, 1, "res/input_DMX" ); + dbgwrite( &st->element_mode, sizeof( int16_t ), 1, input_frame, fname( debug_dir, "element_mode", 0, st->id_element, ENC ) ); +#endif /*----------------------------------------------------------------* * Front Pre-processing @@ -268,6 +279,12 @@ ivas_error ivas_sce_enc( /* Store previous attack detection flag */ st->hTranDet->transientDetector.prev_bIsAttackPresent = st->hTranDet->transientDetector.bIsAttackPresent; +#ifdef DEBUG_MODE_INFO + { + float tmpF = hSCE->element_brate / 1000.0f; + dbgwrite( &tmpF, sizeof( float ), 1, input_frame, fname( debug_dir, "element_brate", 0, sce_id, ENC ) ); + } +#endif pop_wmops(); diff --git a/lib_enc/ivas_sns_enc.c b/lib_enc/ivas_sns_enc.c index 5b455060a..5648aa794 100644 --- a/lib_enc/ivas_sns_enc.c +++ b/lib_enc/ivas_sns_enc.c @@ -40,6 +40,9 @@ #include "rom_com.h" #include "ivas_rom_com.h" #include "ivas_cnst.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" @@ -312,6 +315,19 @@ void sns_avq_cod_stereo( side[i] = snsl[i] - snsr[i]; ener_side += side[i] * side[i]; } +#ifdef DEBUG_MODE_MDCT + { + float ener_mid = 0; + /* Compute mid */ + for ( i = 0; i < M; i++ ) + { + mid[i] = ( snsl[i] + snsr[i] ) * 0.5f; + ener_mid += mid[i] * mid[i]; + } + dbgwrite( &ener_side, sizeof( float ), 1, 1, "./res/ener_side" ); + dbgwrite( &ener_mid, sizeof( float ), 1, 1, "./res/ener_mid" ); + } +#endif if ( ener_side < 12.f ) { diff --git a/lib_enc/ivas_spar_encoder.c b/lib_enc/ivas_spar_encoder.c index 3e4dce43c..ec31fe9c6 100644 --- a/lib_enc/ivas_spar_encoder.c +++ b/lib_enc/ivas_spar_encoder.c @@ -32,6 +32,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "ivas_prot.h" #include "ivas_rom_com.h" #include "ivas_stat_com.h" @@ -149,7 +152,11 @@ ivas_error ivas_spar_enc_open( hSpar->hMdEnc->table_idx = -1; /* AGC handle */ +#ifdef DEBUG_AGC_ENCODER_CMD_OPTION + hSpar->AGC_Enable = ivas_agc_enc_get_flag( hEncoderConfig->Opt_AGC_ON, nchan_transport ); +#else hSpar->AGC_Enable = ivas_agc_enc_get_flag( nchan_transport ); +#endif hSpar->hAgcEnc = NULL; if ( hSpar->AGC_Enable ) @@ -708,12 +715,102 @@ static ivas_error ivas_spar_enc_process( return error; } +#ifdef DEBUG_LBR_SBA + /* Dumping SPAR Coefficients */ + char f_name[100]; + int16_t nbands = 6; + int16_t num_subframes = 1; + int16_t num_elements = 6; + int16_t num_block_group = 1; + int16_t byte_size = sizeof( float ); + + sprintf( f_name, "SBA_MD_values.bin" ); + ( frame == 0 ) ? dbgwrite( &nbands, sizeof( nbands ), 1, 1, f_name ) : false; + ( frame == 0 ) ? dbgwrite( &num_elements, sizeof( num_elements ), 1, 1, f_name ) : false; + ( frame == 0 ) ? dbgwrite( &num_subframes, sizeof( num_subframes ), 1, 1, f_name ) : false; + ( frame == 0 ) ? dbgwrite( &num_block_group, sizeof( num_block_group ), 1, 1, f_name ) : false; + ( frame == 0 ) ? dbgwrite( &byte_size, sizeof( byte_size ), 1, 1, f_name ) : false; + + for ( b = 0; b < nbands; b++ ) + { + for ( int16_t sf = 0; sf < num_subframes; sf++ ) + { + for ( int16_t bl = 0; bl < num_block_group; bl++ ) + { + dbgwrite( &hSpar->hMdEnc->spar_md.band_coeffs[b].pred_re[0], byte_size, 1, 1, f_name ); + dbgwrite( &hSpar->hMdEnc->spar_md.band_coeffs[b].pred_re[1], byte_size, 1, 1, f_name ); + dbgwrite( &hSpar->hMdEnc->spar_md.band_coeffs[b].pred_re[2], byte_size, 1, 1, f_name ); + dbgwrite( &hSpar->hMdEnc->spar_md.band_coeffs[b].P_re[0], byte_size, 1, 1, f_name ); + dbgwrite( &hSpar->hMdEnc->spar_md.band_coeffs[b].P_re[1], byte_size, 1, 1, f_name ); + dbgwrite( &hSpar->hMdEnc->spar_md.band_coeffs[b].P_re[2], byte_size, 1, 1, f_name ); + // fprintf(stdout, "%f\t%f\t%f\t%d\t%d\n", dirac_md_kbps, spar_md_kbps, sba_md_kbps, qsi, code_strat ); + } + } + } +#endif +#ifdef DEBUG_LBR_SBA + /* Dumping SPAR Coefficients */ + nbands = 6; + num_subframes = 1; + num_elements = 6; + num_block_group = 1; + byte_size = sizeof( float ); + + sprintf( f_name, "SBA_MD_values_quant.bin" ); + ( frame == 0 ) ? dbgwrite( &nbands, sizeof( nbands ), 1, 1, f_name ) : false; + ( frame == 0 ) ? dbgwrite( &num_elements, sizeof( num_elements ), 1, 1, f_name ) : false; + ( frame == 0 ) ? dbgwrite( &num_subframes, sizeof( num_subframes ), 1, 1, f_name ) : false; + ( frame == 0 ) ? dbgwrite( &num_block_group, sizeof( num_block_group ), 1, 1, f_name ) : false; + ( frame == 0 ) ? dbgwrite( &byte_size, sizeof( byte_size ), 1, 1, f_name ) : false; + + for ( b = 0; b < nbands; b++ ) + { + for ( int16_t sf = 0; sf < num_subframes; sf++ ) + { + for ( int16_t bl = 0; bl < num_block_group; bl++ ) + { + dbgwrite( &hSpar->hMdEnc->spar_md.band_coeffs[b].pred_quant_re[0], byte_size, 1, 1, f_name ); + dbgwrite( &hSpar->hMdEnc->spar_md.band_coeffs[b].pred_quant_re[1], byte_size, 1, 1, f_name ); + dbgwrite( &hSpar->hMdEnc->spar_md.band_coeffs[b].pred_quant_re[2], byte_size, 1, 1, f_name ); + dbgwrite( &hSpar->hMdEnc->spar_md.band_coeffs[b].P_quant_re[0], byte_size, 1, 1, f_name ); + dbgwrite( &hSpar->hMdEnc->spar_md.band_coeffs[b].P_quant_re[1], byte_size, 1, 1, f_name ); + dbgwrite( &hSpar->hMdEnc->spar_md.band_coeffs[b].P_quant_re[2], byte_size, 1, 1, f_name ); + // fprintf(stdout, "%f\t%f\t%f\t%d\t%d\n", dirac_md_kbps, spar_md_kbps, sba_md_kbps, qsi, code_strat ); + } + } + } +#endif /*-----------------------------------------------------------------------------------------* * FB mixer *-----------------------------------------------------------------------------------------*/ ivas_fb_mixer_get_in_out_mapping( hSpar->hFbMixer->fb_cfg, in_out_mixer_map ); +#ifdef DEBUG_SBA_MD_DUMP + { + int16_t k; + static FILE *f_mat = 0; + + if ( f_mat == 0 ) + f_mat = fopen( "mixer_mat_enc", "w" ); + + for ( i = 0; i < hSpar->hFbMixer->fb_cfg->num_out_chans; i++ ) + { + for ( j = 0; j < hSpar->hFbMixer->fb_cfg->num_in_chans; j++ ) + { + for ( k = 0; k < hSpar->hFbMixer->pFb->filterbank_num_bands; k++ ) + { + fprintf( f_mat, "%f\n", hSpar->hMdEnc->mixer_mat[i][j][k] ); + + if ( ( in_out_mixer_map[i][j] == 0 ) && ( fabs( hSpar->hMdEnc->mixer_mat[i][j][k] ) > 1e-20 ) ) + { + assert( 0 && "Non zero value in unexpected mixer map!!!" ); + } + } + } + } + } +#endif #ifdef DEBUG_SPAR_DIRAC_WRITE_OUT_PRED_PARS { static FILE *fid = 0; @@ -728,6 +825,9 @@ static ivas_error ivas_spar_enc_process( ivas_fb_mixer_process( hSpar->hFbMixer, hSpar->hMdEnc->mixer_mat, p_pcm_tmp, input_frame, in_out_mixer_map ); +#ifdef DEBUG_SBA_AUDIO_DUMP + ivas_spar_dump_signal_wav( input_frame, p_pcm_tmp, NULL, nchan_transport, spar_foa_enc_wav[1], "ivas_fb_mixer_process()" ); +#endif if ( hSpar->hFbMixer->fb_cfg->active_w_mixing == 0 ) { @@ -794,6 +894,19 @@ static ivas_error ivas_spar_enc_process( } } +#ifdef DEBUG_LBR_SBA + for ( int16_t t = 0; t < 960; t++ ) + { + for ( int16_t c = 0; c < hSpar->hFbMixer->fb_cfg->num_out_chans; c++ ) + { + float val = p_pcm_tmp[c][t]; // / MAX16B_FLT; + dbgwrite( &val, sizeof( float ), 1, 1, "int_enc_dmx.raw" ); + } + } +#endif +#ifdef DEBUG_SBA_AUDIO_DUMP + ivas_spar_dump_signal_wav( input_frame, p_pcm_tmp, NULL, nchan_transport, spar_foa_enc_wav[0], "ivas_pca_enc()" ); +#endif /*-----------------------------------------------------------------------------------------* * AGC @@ -806,7 +919,46 @@ static ivas_error ivas_spar_enc_process( ivas_agc_enc_process( hSpar->hAgcEnc, hMetaData, p_pcm_tmp, p_pcm_tmp, hSpar->hFbMixer->fb_cfg->num_out_chans, hEncoderConfig ); } } +#ifdef DEBUG_SBA_AUDIO_DUMP + /* Dump audio signal after ivas_agc_enc_process */ + ivas_spar_dump_signal_wav( input_frame, p_pcm_tmp, NULL, nchan_transport, spar_foa_enc_wav[2], "ivas_agc_enc_process()" ); +#endif +#ifdef DEBUG_SPAR_BYPASS_EVS_CODEC + { + static FILE *fid_enc = 0; + static float delay_buf[576 * 4] = { 0 }; + int16_t smp, ch, buf_idx, framelen = input_frame, delay = 576; + if ( !fid_enc ) + { + fid_enc = fopen( "evs_input_float.raw", "wb" ); + } + + /* write out buffer */ + for ( smp = 0; smp < delay * nchan_transport; smp++ ) + { + fwrite( &delay_buf[smp], sizeof( float ), 1, fid_enc ); + } + + for ( smp = 0; smp < framelen - delay; smp++ ) + { + for ( ch = 0; ch < nchan_transport; ch++ ) + { + fwrite( &p_pcm_tmp[ch][smp], sizeof( float ), 1, fid_enc ); + } + } + + /* update delay buffer*/ + buf_idx = 0; + for ( ; smp < framelen; smp++ ) + { + for ( ch = 0; ch < nchan_transport; ch++ ) + { + delay_buf[buf_idx++] = p_pcm_tmp[ch][smp]; + } + } + } +#endif /*-----------------------------------------------------------------------------------------* * Re-order the dmx back to ACN/SN3D format diff --git a/lib_enc/ivas_spar_md_enc.c b/lib_enc/ivas_spar_md_enc.c index 422cc4b05..5a6ef2289 100644 --- a/lib_enc/ivas_spar_md_enc.c +++ b/lib_enc/ivas_spar_md_enc.c @@ -34,6 +34,9 @@ #include "options.h" #include "prot.h" #include "ivas_prot.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "math.h" #include "ivas_rom_com.h" #include @@ -251,8 +254,13 @@ ivas_error ivas_spar_md_enc_init( hMdEnc->spar_md.prior_dyn_active_w_flag = 0; +#ifndef DEBUG_AGC_ENCODER_CMD_OPTION ivas_spar_set_bitrate_config( &hMdEnc->spar_md_cfg, table_idx, ( hMdEnc->spar_hoa_md_flag ) ? IVAS_MAX_NUM_BANDS : SPAR_DIRAC_SPLIT_START_BAND, hMdEnc->spar_hoa_dirac2spar_md_flag, 1, hEncoderConfig->Opt_PCA_ON, ivas_agc_enc_get_flag( ivas_spar_br_table_consts[table_idx].nchan_transport ) ); +#else + ivas_spar_set_bitrate_config( &hMdEnc->spar_md_cfg, table_idx, ( hMdEnc->spar_hoa_md_flag ) ? IVAS_MAX_NUM_BANDS : SPAR_DIRAC_SPLIT_START_BAND, + hMdEnc->spar_hoa_dirac2spar_md_flag, 1, hEncoderConfig->Opt_PCA_ON, ivas_agc_enc_get_flag( hEncoderConfig->Opt_AGC_ON, ivas_spar_br_table_consts[table_idx].nchan_transport ) ); +#endif /* get FB coefficients */ for ( i = 0; i < IVAS_MAX_NUM_BANDS; i++ ) @@ -624,9 +632,22 @@ ivas_error ivas_spar_md_enc_process( } } } +#ifdef DEBUG_LBR_SBA + float dirac_md_kbps = (float) ( hMetaData->nb_bits_tot ) * 50 / 1000; +#endif code_strat = 0; +#ifdef DEBUG_SBA_MD_DUMP + ndec = -1; +#endif +#ifdef DEBUG_SPAR_MD_TARGET_TUNING + for ( qsi = 0; qsi < 1; qsi++ ) +#else for ( qsi = 0; qsi < num_quant_strats; qsi++ ) +#endif { +#ifdef SPAR_HOA_DBG + fprintf( stdout, "qsi = %d\n", qsi ); +#endif for ( b = 0; b < num_bands; b++ ) { ndm = hMdEnc->spar_md_cfg.num_dmx_chans_per_band[b * bands_bw]; @@ -742,6 +763,19 @@ ivas_error ivas_spar_md_enc_process( } } } +#ifdef SPAR_HOA_DBG + /*fprintf(stderr, "\n\n C coefficients: band %d\n", b); + + for (i = 0; i < num_ch - ndm; i++) + { + for (j = 0; j < ndm - 1; j++) + { + fprintf(stderr, "%f, ", hMdEnc->spar_md.band_coeffs[b].C_re[i][j]); + } + fprintf(stderr, "\n"); + } + fprintf(stderr, "\n\n"); */ +#endif ivas_quant_c_per_band( &hMdEnc->spar_md.band_coeffs[b], &hMdEnc->spar_md.band_coeffs_idx[b], &hMdEnc->spar_md_cfg.quant_strat[qsi], ndec, ndm ); @@ -808,6 +842,16 @@ ivas_error ivas_spar_md_enc_process( } } +#ifdef DEBUGGING + if ( dtx_vad == 1 ) + { + assert( packed_ok == 1 ); + } + if ( hEncoderConfig->ivas_total_brate >= IVAS_256k ) + { + assert( qsi == 0 ); + } +#endif /* Reuse mixer matrix values for unsent bands */ if ( ( hEncoderConfig->ivas_total_brate < IVAS_24k4 ) && ( code_strat > 3 ) ) @@ -828,6 +872,211 @@ ivas_error ivas_spar_md_enc_process( } } } +#ifdef DEBUG_LBR_SBA + char f_name[100]; + int16_t nbands = 1; + int16_t num_subframes = 1; + int16_t num_elements = 6; + int16_t num_block_group = 1; + int16_t byte_size = sizeof( float ); + + float sba_md_kbps = (float) hMetaData->nb_bits_tot * 50 / 1000; + float spar_md_kbps = sba_md_kbps - dirac_md_kbps; + float corebr_kbps = (float) hEncoderConfig->ivas_total_brate / 1000 - sba_md_kbps; + + sprintf( f_name, "SBA_MD_bitrate.bin" ); + ( frame == 0 ) ? dbgwrite( &nbands, sizeof( nbands ), 1, 1, f_name ) : false; + ( frame == 0 ) ? dbgwrite( &num_elements, sizeof( num_elements ), 1, 1, f_name ) : false; + ( frame == 0 ) ? dbgwrite( &num_subframes, sizeof( num_subframes ), 1, 1, f_name ) : false; + ( frame == 0 ) ? dbgwrite( &num_block_group, sizeof( num_block_group ), 1, 1, f_name ) : false; + ( frame == 0 ) ? dbgwrite( &byte_size, sizeof( byte_size ), 1, 1, f_name ) : false; + + for ( b = 0; b < nbands; b++ ) + { + for ( int16_t sf = 0; sf < num_subframes; sf++ ) + { + for ( int16_t bl = 0; bl < num_block_group; bl++ ) + { + float fqsi = (float) qsi; + float fcode = (float) code_strat; + + dbgwrite( &dirac_md_kbps, byte_size, 1, 1, f_name ); + dbgwrite( &spar_md_kbps, byte_size, 1, 1, f_name ); + dbgwrite( &sba_md_kbps, byte_size, 1, 1, f_name ); + dbgwrite( &fqsi, byte_size, 1, 1, f_name ); + dbgwrite( &fcode, byte_size, 1, 1, f_name ); + dbgwrite( &corebr_kbps, byte_size, 1, 1, f_name ); + // fprintf(stdout, "%f\t%f\t%f\t%d\t%d\n", dirac_md_kbps, spar_md_kbps, sba_md_kbps, qsi, code_strat ); + } + } + } +#endif +#ifdef SPAR_HOA_DBG + /*if ( strat >= 4 ) + { + for ( b = 0; b < nB; b++ ) + { + b = 0; + fprintf( stdout, "\n\nMETADATA PR: band %d, qsi %d\n\n", b, qsi ); + for ( i = 0; i < num_ch - 1; i++ ) + { + fprintf( stdout, "i: %d -- %f\t %d\t %d\n", i, //hMdEnc->spar_md.band_coeffs[b].pred_re[i], + hMdEnc->spar_md.band_coeffs[b].pred_quant_re[i], + hMdEnc->spar_md_prior.band_coeffs_idx[b].pred_index_re[i], + hMdEnc->spar_md.band_coeffs_idx[b].pred_index_re[i] ); + } + fprintf( stdout, "\n\n METADATA C: band %d\n\n", b ); + int16_t k = 0; + for ( i = 0; i < ndec; i++ ) + { + for ( j = 0; j < ( ndm - 1 ); j++ ) + { + fprintf( stdout, "i: %d -- %f\t %d\t %d\n", i, // hMdEnc->spar_md.band_coeffs[b].C_re[i][j], + hMdEnc->spar_md.band_coeffs[b].C_quant_re[i][j], + hMdEnc->spar_md_prior.band_coeffs_idx[b].drct_index_re[k], + hMdEnc->spar_md.band_coeffs_idx[b].drct_index_re[k] ); + k++; + } + } + fprintf( stdout, "\n\n METADATA Pd: band %d\n\n", b ); + for ( i = 0; i < num_ch - ndm; i++ ) + { + fprintf( stdout, "i: %d -- %f\t %d\t %d\n", i, //hMdEnc->spar_md.band_coeffs[b].P_re[i][i], + hMdEnc->spar_md.band_coeffs[b].P_quant_re[i][i], + hMdEnc->spar_md_prior.band_coeffs_idx[b].decd_index_re[i], + hMdEnc->spar_md.band_coeffs_idx[b].decd_index_re[i] ); + } + fprintf( stdout, "\n\n" ); + } + }*/ + b = 0; + ndm = hMdEnc->spar_md_cfg.num_dmx_chans_per_band[b * bands_bw]; + + fprintf( stdout, "\n\n Metadata PR (15x1), C(15x15), P(15x15): band %d\n", b ); + for ( i = 0; i < num_ch - 1; i++ ) + { + fprintf( stdout, "i: %d -- %.2f\t|\t", i, hMdEnc->spar_md.band_coeffs[b].pred_quant_re[i] ); + if ( i < num_ch - ndm ) + { + for ( j = 0; j < ndm - 1; j++ ) + { + fprintf( stdout, "%.2f\t", hMdEnc->spar_md.band_coeffs[b].C_quant_re[i][j] ); + } + fprintf( stdout, "|\t" ); + for ( j = 0; j < num_ch - ndm; j++ ) + { + fprintf( stdout, "%.2f\t", hMdEnc->spar_md.band_coeffs[b].P_quant_re[j] ); + } + } + fprintf( stdout, "\n" ); + } + fprintf( stdout, "\n" ); +#endif +#ifdef DEBUG_SBA_MD_DUMP + { + char f_name[100]; + int16_t n_bands = 1, num_subframes = 1, num_block_groups = 1, num_elements = 1, byte_size = sizeof( int16_t ); + sprintf( f_name, "spar_qsi.bin" ); + ( frame == 0 ) ? dbgwrite( &n_bands, sizeof( nB ), 1, 1, f_name ) : false; + ( frame == 0 ) ? dbgwrite( &num_elements, sizeof( num_elements ), 1, 1, f_name ) : false; + ( frame == 0 ) ? dbgwrite( &num_subframes, sizeof( num_subframes ), 1, 1, f_name ) : false; + ( frame == 0 ) ? dbgwrite( &num_block_groups, sizeof( num_block_groups ), 1, 1, f_name ) : false; + ( frame == 0 ) ? dbgwrite( &byte_size, sizeof( byte_size ), 1, 1, f_name ) : false; + dbgwrite( &qsi, sizeof( int16_t ), 1, 1, f_name ); + sprintf( f_name, "spar_strat.bin" ); + ( frame == 0 ) ? dbgwrite( &n_bands, sizeof( nB ), 1, 1, f_name ) : false; + ( frame == 0 ) ? dbgwrite( &num_elements, sizeof( num_elements ), 1, 1, f_name ) : false; + ( frame == 0 ) ? dbgwrite( &num_subframes, sizeof( num_subframes ), 1, 1, f_name ) : false; + ( frame == 0 ) ? dbgwrite( &num_block_groups, sizeof( num_block_groups ), 1, 1, f_name ) : false; + ( frame == 0 ) ? dbgwrite( &byte_size, sizeof( byte_size ), 1, 1, f_name ) : false; + dbgwrite( &strat, sizeof( int16_t ), 1, 1, f_name ); + byte_size = sizeof( float ); + for ( b = 0; b < nB; b++ ) + { + ndm = hMdEnc->spar_md_cfg.num_dmx_chans_per_band[b * bands_bw]; + + sprintf( f_name, "spar_band_pred_coeffs.bin" ); + ( b == 0 && frame == 0 ) ? dbgwrite( &nB, sizeof( nB ), 1, 1, f_name ) : false; + num_elements = num_ch - 1; + ( b == 0 && frame == 0 ) ? dbgwrite( &num_elements, sizeof( num_elements ), 1, 1, f_name ) : false; + ( b == 0 && frame == 0 ) ? dbgwrite( &num_subframes, sizeof( num_subframes ), 1, 1, f_name ) : false; + ( b == 0 && frame == 0 ) ? dbgwrite( &num_block_groups, sizeof( num_block_groups ), 1, 1, f_name ) : false; + ( b == 0 && frame == 0 ) ? dbgwrite( &byte_size, sizeof( byte_size ), 1, 1, f_name ) : false; + for ( i = 0; i < num_ch - 1; i++ ) + { + dbgwrite( &hMdEnc->spar_md.band_coeffs[b].pred_re[i], sizeof( float ), 1, 1, f_name ); + } + sprintf( f_name, "spar_band_C_coeffs.bin" ); + ( b == 0 && frame == 0 ) ? dbgwrite( &nB, sizeof( nB ), 1, 1, f_name ) : false; + num_elements = ndec * ( ndm - 1 ); + ( b == 0 && frame == 0 ) ? dbgwrite( &num_elements, sizeof( num_elements ), 1, 1, f_name ) : false; + ( b == 0 && frame == 0 ) ? dbgwrite( &num_subframes, sizeof( num_subframes ), 1, 1, f_name ) : false; + ( b == 0 && frame == 0 ) ? dbgwrite( &num_block_groups, sizeof( num_block_groups ), 1, 1, f_name ) : false; + ( b == 0 && frame == 0 ) ? dbgwrite( &byte_size, sizeof( byte_size ), 1, 1, f_name ) : false; + for ( i = 0; i < ndec; i++ ) + { + for ( j = 0; j < ( ndm - 1 ); j++ ) + { + dbgwrite( &hMdEnc->spar_md.band_coeffs[b].C_re[i][j], sizeof( float ), 1, 1, f_name ); + } + } + sprintf( f_name, "spar_band_P_coeffs.bin" ); + ( b == 0 && frame == 0 ) ? dbgwrite( &nB, sizeof( nB ), 1, 1, f_name ) : false; + num_elements = num_ch - ndm; + ( b == 0 && frame == 0 ) ? dbgwrite( &num_elements, sizeof( num_elements ), 1, 1, f_name ) : false; + ( b == 0 && frame == 0 ) ? dbgwrite( &num_subframes, sizeof( num_subframes ), 1, 1, f_name ) : false; + ( b == 0 && frame == 0 ) ? dbgwrite( &num_block_groups, sizeof( num_block_groups ), 1, 1, f_name ) : false; + ( b == 0 && frame == 0 ) ? dbgwrite( &byte_size, sizeof( byte_size ), 1, 1, f_name ) : false; + for ( i = 0; i < num_ch - ndm; i++ ) + { + dbgwrite( &hMdEnc->spar_md.band_coeffs[b].P_re[i], sizeof( float ), 1, 1, f_name ); + } + sprintf( f_name, "spar_band_pred_coeffs_quant.bin" ); + ( b == 0 && frame == 0 ) ? dbgwrite( &nB, sizeof( nB ), 1, 1, f_name ) : false; + num_elements = num_ch - 1; + ( b == 0 && frame == 0 ) ? dbgwrite( &num_elements, sizeof( num_elements ), 1, 1, f_name ) : false; + ( b == 0 && frame == 0 ) ? dbgwrite( &num_subframes, sizeof( num_subframes ), 1, 1, f_name ) : false; + ( b == 0 && frame == 0 ) ? dbgwrite( &num_block_groups, sizeof( num_block_groups ), 1, 1, f_name ) : false; + ( b == 0 && frame == 0 ) ? dbgwrite( &byte_size, sizeof( byte_size ), 1, 1, f_name ) : false; + for ( i = 0; i < num_ch - 1; i++ ) + { + dbgwrite( &hMdEnc->spar_md.band_coeffs[b].pred_quant_re[i], sizeof( float ), 1, 1, f_name ); + } + sprintf( f_name, "spar_band_C_coeffs_quant.bin" ); + ( b == 0 && frame == 0 ) ? dbgwrite( &nB, sizeof( nB ), 1, 1, f_name ) : false; + num_elements = ndec * ( ndm - 1 ); + ( b == 0 && frame == 0 ) ? dbgwrite( &num_elements, sizeof( num_elements ), 1, 1, f_name ) : false; + ( b == 0 && frame == 0 ) ? dbgwrite( &num_subframes, sizeof( num_subframes ), 1, 1, f_name ) : false; + ( b == 0 && frame == 0 ) ? dbgwrite( &num_block_groups, sizeof( num_block_groups ), 1, 1, f_name ) : false; + ( b == 0 && frame == 0 ) ? dbgwrite( &byte_size, sizeof( byte_size ), 1, 1, f_name ) : false; + for ( i = 0; i < ndec; i++ ) + { + for ( j = 0; j < ( ndm - 1 ); j++ ) + { + dbgwrite( &hMdEnc->spar_md.band_coeffs[b].C_quant_re[i][j], sizeof( float ), 1, 1, f_name ); + } + } + sprintf( f_name, "spar_band_P_coeffs_quant.bin" ); + ( b == 0 && frame == 0 ) ? dbgwrite( &nB, sizeof( nB ), 1, 1, f_name ) : false; + num_elements = num_ch - ndm; + ( b == 0 && frame == 0 ) ? dbgwrite( &num_elements, sizeof( num_elements ), 1, 1, f_name ) : false; + ( b == 0 && frame == 0 ) ? dbgwrite( &num_subframes, sizeof( num_subframes ), 1, 1, f_name ) : false; + ( b == 0 && frame == 0 ) ? dbgwrite( &num_block_groups, sizeof( num_block_groups ), 1, 1, f_name ) : false; + ( b == 0 && frame == 0 ) ? dbgwrite( &byte_size, sizeof( byte_size ), 1, 1, f_name ) : false; + for ( i = 0; i < num_ch - ndm; i++ ) + { + dbgwrite( &hMdEnc->spar_md.band_coeffs[b].P_quant_re[i], sizeof( float ), 1, 1, f_name ); + } + } + } +#endif +#ifdef DEBUG_SPAR_MD_TARGET_TUNING + int16_t md_bits = hMetaData->nb_bits_tot - bit_pos_start + ( ( ( hEncoderConfig->ivas_total_brate == IVAS_256k ) && ( sba_order == SBA_FOA_ORDER ) ) ? 1 : 0 ); + FILE *fp = fopen( "spar_md_bitrate.txt", "a" ); + + fprintf( fp, "%d\t %d \t %d\n", md_bits, qsi, code_strat ); + fclose( fp ); +#endif ivas_store_prior_coeffs( hMdEnc, num_bands, code_strat, dtx_vad, qsi ); @@ -1001,6 +1250,12 @@ static void ivas_write_spar_md_bitstream( } } +#ifdef SPAR_HOA_DBG + if ( strat < 2 ) + fprintf( stdout, "\n\n no_ec = %d, strat = %d\n", no_ec, strat - 1 ); + else + fprintf( stdout, "\n\n no_ec = %d, strat = %d\n", no_ec, strat ); +#endif if ( no_ec == 1 ) { entropy_coding_result = diff --git a/lib_enc/ivas_stat_enc.h b/lib_enc/ivas_stat_enc.h index eae9c41dd..6725d778b 100644 --- a/lib_enc/ivas_stat_enc.h +++ b/lib_enc/ivas_stat_enc.h @@ -271,6 +271,10 @@ typedef struct stereo_dft_enc_data_struct float icbweRefEner; float lbEner; int16_t flip_sign; +#ifdef DEBUG_MODE_DFT + int16_t verbose; + int16_t res_cod_bits; +#endif } STEREO_DFT_ENC_DATA, *STEREO_DFT_ENC_DATA_HANDLE; @@ -288,6 +292,11 @@ typedef struct stereo_mdct_enc_data_structure /* only intraframe */ int16_t mdct_stereo_mode[2]; /* mdct stereo mode: LR, MS, band-wise MS */ +#ifdef DEBUGGING + int16_t mdct_stereo_mode_cmdl; /* MDCT stereo mode from command-line */ + int16_t fDualMono; /* force dual mono in MDCT stereo mode */ + int16_t fMSstereo; /* force full-band MS in MDCT stereo mode */ +#endif int16_t global_ild[2]; /* Quantized ILD for the whole spectrum */ int16_t split_ratio; /* Ratio of bitrate (1 to 7), split_ratio = 8 * 1st chn bitrate / (1st + 2nd chn bitrate) */ @@ -996,6 +1005,9 @@ typedef struct cpe_enc_data_structure float *input_mem[CPE_CHANNELS]; /* input channels buffers memory; needed to be up-to-date for TD->DFT stereo switching */ int32_t brate_surplus; /* bitrate surplus for bitrate adaptation in combined format coding */ +#ifdef DEBUGGING + int16_t stereo_mode_cmdl; /* stereo mode forced from the commaand-line */ +#endif } CPE_ENC_DATA, *CPE_ENC_HANDLE; @@ -1166,6 +1178,15 @@ typedef struct encoder_config_structure /* temp. development parameters */ int16_t Opt_PCA_ON; /* flag indicating PCA operation in SBA */ +#ifdef DEBUGGING + /* debugging options */ + int16_t stereo_mode_cmdl; /* stereo mode forced from the command-line */ + int16_t force; /* parameter to force specific "core" of the Core-Coder*/ + int16_t mdct_stereo_mode_cmdl; /* mdct stereo mode forced from command-line, employed only when DEBUG_FORCE_MDCT_STEREO_MODE is activated */ +#ifdef DEBUG_AGC_ENCODER_CMD_OPTION + int16_t Opt_AGC_ON; /* flag indicating AGC operation in SBA */ +#endif +#endif } ENCODER_CONFIG, *ENCODER_CONFIG_HANDLE; diff --git a/lib_enc/ivas_stereo_adapt_GR_enc.c b/lib_enc/ivas_stereo_adapt_GR_enc.c index c8816da9c..087ecda8e 100644 --- a/lib_enc/ivas_stereo_adapt_GR_enc.c +++ b/lib_enc/ivas_stereo_adapt_GR_enc.c @@ -38,6 +38,9 @@ #include "stat_enc.h" #include "wmc_auto.h" #include "ivas_rom_com.h" +#ifdef DEBUGGING +#include "debug.h" +#endif /*---------------------------------------------------------------------* diff --git a/lib_enc/ivas_stereo_classifier.c b/lib_enc/ivas_stereo_classifier.c index 68be77ad1..427b55fe6 100644 --- a/lib_enc/ivas_stereo_classifier.c +++ b/lib_enc/ivas_stereo_classifier.c @@ -40,6 +40,9 @@ #include "ivas_rom_com.h" #include "ivas_rom_enc.h" #include "ivas_cnst.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" @@ -109,6 +112,9 @@ int16_t select_stereo_mode( stereo_switching_flag = 1; if ( hCPE->element_brate >= MIN_BRATE_MDCT_STEREO || ( ( ivas_format == MASA_FORMAT || ivas_format == MASA_ISM_FORMAT ) && hCPE->element_brate < MASA_STEREO_MIN_BITRATE ) +#ifdef DEBUGGING + || ( hCPE->stereo_mode_cmdl == IVAS_CPE_DFT || hCPE->stereo_mode_cmdl == IVAS_CPE_TD ) +#endif ) { stereo_switching_flag = 0; @@ -145,6 +151,12 @@ int16_t select_stereo_mode( { element_mode = IVAS_CPE_DFT; } +#ifdef DEBUGGING + if ( hCPE->stereo_mode_cmdl > 1 ) + { + element_mode = hCPE->stereo_mode_cmdl; + } +#endif } else if ( element_mode == IVAS_CPE_TD ) { @@ -199,6 +211,12 @@ int16_t select_stereo_mode( set_f( hStereoClassif->xtalk_fv, -1.0f, SSC_MAX_NFEA ); } } +#ifdef DEBUG_MODE_TD + dbgwrite( &hStereoClassif->unclr_decision, sizeof( int16_t ), 1, L_FRAME16k, "res/unclr_decision.enc" ); + dbgwrite( &hStereoClassif->xtalk_decision, sizeof( int16_t ), 1, L_FRAME16k, "res/xtalk_decision.enc" ); + dbgwrite( &hCPE->hCoreCoder[0]->sp_aud_decision0, sizeof( int16_t ), 1, L_FRAME16k, "res/sp_aud_class.enc" ); + dbgwrite( &hCPE->hCoreCoder[0]->last_core, sizeof( int16_t ), 1, L_FRAME16k, "res/last_core.enc" ); +#endif if ( element_mode == IVAS_CPE_TD && hCPE->hCoreCoder[0]->Opt_DTX_ON ) { @@ -535,6 +553,9 @@ void unclr_classifier_td( int16_t i, ind; float relE_ST, edge, edge_0_1; float score, fvn[SSC_MAX_NFEA]; +#ifdef DEBUG_MODE_TD + int16_t dec; +#endif STEREO_CLASSIF_HANDLE hStereoClassif = hCPE->hStereoClassif; set_f( fvn, -1.0f, SSC_MAX_NFEA ); @@ -552,6 +573,10 @@ void unclr_classifier_td( score += fvn[i] * unclr_coef_td[i]; } +#ifdef DEBUG_MODE_TD + /* raw decision */ + dec = score > 0; +#endif /* normalize score to -1:+1 */ if ( score > UNCLR_SCORE_THR ) @@ -591,6 +616,11 @@ void unclr_classifier_td( hStereoClassif->unclr_decision = !hStereoClassif->unclr_decision; } +#ifdef DEBUG_MODE_TD + dbgwrite( &dec, sizeof( int16_t ), 1, 1, "res/unclr_dec.x" ); + dbgwrite( &hStereoClassif->unclr_wscore, sizeof( float ), 1, 1, "res/unclr_wscore.x" ); + dbgwrite( &hStereoClassif->unclr_decision, sizeof( int16_t ), 1, 1, "res/unclr_dec_hyst.x" ); +#endif return; } @@ -609,6 +639,9 @@ void unclr_classifier_dft( int16_t i, ind; float edge, relE_ST, edge_0_1; float score, fvn[SSC_MAX_NFEA]; +#ifdef DEBUG_MODE_TD + int16_t dec; +#endif STEREO_CLASSIF_HANDLE hStereoClassif = hCPE->hStereoClassif; @@ -625,6 +658,10 @@ void unclr_classifier_dft( score += fvn[i] * unclr_coef_dft[i]; } +#ifdef DEBUG_MODE_TD + /* raw decision */ + dec = score > 0; +#endif /* normalize score to -1:+1 */ if ( score > UNCLR_SCORE_THR ) @@ -669,6 +706,11 @@ void unclr_classifier_dft( hStereoClassif->unclr_decision = !hStereoClassif->unclr_decision; } +#ifdef DEBUG_MODE_TD + dbgwrite( &dec, sizeof( int16_t ), 1, 1, "res/unclr_dec.x" ); + dbgwrite( &hStereoClassif->unclr_wscore, sizeof( float ), 1, 1, "res/unclr_wscore.x" ); + dbgwrite( &hStereoClassif->unclr_decision, sizeof( int16_t ), 1, 1, "res/unclr_dec_hyst.x" ); +#endif return; } @@ -688,6 +730,9 @@ void xtalk_classifier_td( float score, fvn[SSC_MAX_NFEA]; float edge, edge_0_1, wedge, scr_min, scr_max, wrelE; +#ifdef DEBUG_MODE_TD + int16_t dec; +#endif STEREO_CLASSIF_HANDLE hStereoClassif = hCPE->hStereoClassif; @@ -740,6 +785,10 @@ void xtalk_classifier_td( score = 0; } +#ifdef DEBUG_MODE_TD + /* raw decision */ + dec = score > 0; +#endif /* weight raw score with relative energy */ wrelE = lin_interp( hStereoClassif->relE_0_1, 0.5f, 0.95f, 0.9f, 0.0f, 1 ); @@ -791,6 +840,11 @@ void xtalk_classifier_td( hStereoClassif->xtalk_decision = !hStereoClassif->xtalk_decision; } +#ifdef DEBUG_MODE_TD + dbgwrite( &hStereoClassif->xtalk_wscore, sizeof( float ), 1, 1, "res/xtalk_wscore.x" ); + dbgwrite( &dec, sizeof( int16_t ), 1, 1, "res/xtalk_dec.x" ); + dbgwrite( &hStereoClassif->xtalk_decision, sizeof( int16_t ), 1, 1, "res/xtalk_dec_hyst.x" ); +#endif return; } @@ -815,6 +869,9 @@ void xtalk_classifier_dft( float fvn[SSC_MAX_NFEA], edge, edge_0_1, wedge; float ratio_m1_m2, m2_m2, d_itd2, itd1_flip; float scr_min, scr_max; +#ifdef DEBUG_MODE_TD + int16_t dec; +#endif hStereoClassif = hCPE->hStereoClassif; hItd = ( hCPE->hStereoDft != NULL ) ? hCPE->hStereoDft->hItd : hCPE->hStereoMdct->hItd; @@ -904,6 +961,10 @@ void xtalk_classifier_dft( score = 0; } +#ifdef DEBUG_MODE_TD + /* raw decision */ + dec = score > 0; +#endif /* rising edge detector on raw score -> yields 1 if strong rising edge is detected in the given buffer */ @@ -936,12 +997,20 @@ void xtalk_classifier_dft( hCPE->hCoreCoder[0]->vad_flag == 1 && hCPE->hCoreCoder[0]->flag_noisy_speech_snr == 0 && hCPE->hCoreCoder[0]->hNoiseEst->aEn_inac_cnt > 15 ) { hStereoClassif->xtalk_decision = 1; +#ifdef DEBUG_MODE_TD + printf( "\nSwitch DFT-stereo -> TD-LR on frame %d\n", frame ); +#endif } else if ( hCPE->element_brate >= IVAS_16k4 && hStereoClassif->xtalk_decision == 0 && abs( itd ) > STEREO_DFT_ITD_MAX && ( hCPE->hCoreCoder[0]->lp_speech - hCPE->hCoreCoder[0]->lp_noise ) > 25.0f ) { hStereoClassif->xtalk_decision = 1; } +#ifdef DEBUG_MODE_TD + dbgwrite( &hStereoClassif->xtalk_wscore, sizeof( float ), 1, 1, "res/xtalk_wscore.x" ); + dbgwrite( &dec, sizeof( int16_t ), 1, 1, "res/xtalk_dec.x" ); + dbgwrite( &hStereoClassif->xtalk_decision, sizeof( int16_t ), 1, 1, "res/xtalk_dec_hyst.x" ); +#endif /* updates */ hItd->prev_m1 = m1; diff --git a/lib_enc/ivas_stereo_cng_enc.c b/lib_enc/ivas_stereo_cng_enc.c index 10a87659a..76f56532d 100644 --- a/lib_enc/ivas_stereo_cng_enc.c +++ b/lib_enc/ivas_stereo_cng_enc.c @@ -40,6 +40,9 @@ #include "ivas_prot.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" diff --git a/lib_enc/ivas_stereo_dft_enc.c b/lib_enc/ivas_stereo_dft_enc.c index 3463af2da..109def1fd 100644 --- a/lib_enc/ivas_stereo_dft_enc.c +++ b/lib_enc/ivas_stereo_dft_enc.c @@ -42,7 +42,16 @@ #include "ivas_cnst.h" #include "ivas_rom_com.h" #include "ivas_rom_enc.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" +#ifdef DEBUG_PLOT +#include "deb_out.h" +#endif +#ifdef DEBUG_MODE_DFT +static FILE *pF = NULL; +#endif /*-------------------------------------------------------------------* @@ -70,7 +79,11 @@ static float stereo_dft_calc_mean_ipd_change( float *pIpd, float *ipd_smooth, in static void stereo_dft_gipd_stabilization( float *pgIpd, float prev_gipd, float ipd_mean_change ); +#ifdef DEBUG_MODE_DFT +static void stereo_dft_enc_get_nipd_flag( STEREO_DFT_ENC_DATA_HANDLE hStereoDft, float *pgIpd, const int16_t sp_aud_decision0, const float gainIPD ); +#else static void stereo_dft_enc_get_nipd_flag( STEREO_DFT_ENC_DATA_HANDLE hStereoDft, const int16_t sp_aud_decision0, const float gainIPD ); +#endif static void stereo_dft_enc_get_reverb_flag( STEREO_DFT_ENC_DATA_HANDLE hStereoDft, float *pPredGain, float *sub_nrg_DMX, const float *sub_nrg_L, const float *sub_nrg_R, const int16_t k_offset, const float *bin_nrgL, const float *bin_nrgR ); @@ -126,6 +139,11 @@ void stereo_dft_quantize_res_gains( sign = 1; } +#ifdef DEBUGGING + /* the following assertions should be satisfied by the input data: */ + assert( 1 - gg * gg + EPSILON >= rr * rr / 2 ); + assert( gg <= 1 ); +#endif gg = min( gg, 1 - EPSILON ); rr = min( rr, sqrtf( 1 - gg * gg ) - EPSILON ); @@ -492,6 +510,9 @@ void stereo_dft_enc_reset( hStereoDft->first_frm_flag = 1; +#ifdef DEBUG_MODE_DFT + hStereoDft->verbose = 1; +#endif stereo_enc_itd_init( hStereoDft->hItd ); @@ -616,6 +637,56 @@ void stereo_dft_enc_update( hStereoDft->res_cod_line_max = 8 * ( hStereoDft->res_cod_line_max / 8 ); hStereoDft->res_pred_band_min = max( STEREO_DFT_RES_PRED_BAND_MIN, hStereoDft->res_cod_band_max ); +#ifdef DEBUG_MODE_DFT + /*Compute the expected bitrate*/ + if ( hStereoDft->verbose ) + { + int16_t tmp, nbits, N_div_param, bits_itd; + int16_t input_frame = hStereoDft->N; + int32_t input_Fs; + input_Fs = input_frame * FRAMES_PER_SEC; + + hStereoDft->verbose = 0; + + /*init*/ + N_div_param = 1; + + nbits = 0; /*header: 0 bits*/ + + fprintf( stderr, "Stereo DFT\n" ); + + /*ITD*/ + tmp = 1 + STEREO_DFT_ITD_NBITS; + nbits += 1; + bits_itd = STEREO_DFT_ITD_NBITS; + fprintf( stderr, "\t ITD: %.2f kbps\n", tmp * input_Fs / ( 1000.f * input_frame ) ); + + /*SIDE_GAIN*/ + tmp = hStereoDft->nbands * 5 * N_div_param; + nbits += tmp; + fprintf( stderr, "\t SIDE_GAIN: %.2f kbps\n", tmp * input_Fs / ( 1000.f * input_frame ) ); + + + /*residual coding prediction*/ + tmp = 0; + if ( hStereoDft->hConfig->res_pred_mode ) + { + tmp = ( hStereoDft->nbands - hStereoDft->res_pred_band_min ) * 3 * N_div_param; + fprintf( stderr, "\t Res pred.: %.2f kbps\n", tmp * input_Fs / ( 1000.f * input_frame ) ); + } + nbits += max( tmp, bits_itd ); + + /*residual coding*/ + if ( hStereoDft->hConfig->res_cod_mode ) + { + tmp = hStereoDft->res_cod_bits; + nbits += tmp; + fprintf( stderr, "\t Res cod.: %.2f kbps\n", tmp * input_Fs / ( 1000.f * input_frame ) ); + } + + fprintf( stderr, "\t Total: %.2f kbps\n", nbits * input_Fs / ( 1000.f * input_frame ) ); + } +#endif /*DEBUGGING*/ return; } @@ -689,6 +760,23 @@ void stereo_dft_enc_analyze( mem[n] = input_mem[n]; } +#ifdef DEBUG_MODE_DFT + { + int16_t tmp[1024]; + + /* stereo side info is only simulated */ + for ( i = 0; i < input_frame; i++ ) + { + tmp[i] = (int16_t) ( input[0][i] + 0.5f ); + } + dbgwrite( tmp, sizeof( int16_t ), input_frame, 1, "./res/stereo_dft_ch0_input.pcm" ); + for ( i = 0; i < input_frame; i++ ) + { + tmp[i] = (int16_t) ( input[1][i] + 0.5f ); + } + dbgwrite( tmp, sizeof( int16_t ), input_frame, 1, "./res/stereo_dft_ch1_input.pcm" ); + } +#endif /*-----------------------------------------------------------------* * DFT Analysis @@ -765,7 +853,11 @@ void stereo_dft_enc_analyze( mem[n] = &input[n][N - dft_ovl]; } +#ifdef DEBUG_MODE_DFT + if ( hStereoDft != NULL && hStereoDft->hConfig->hybrid_itd_flag && hStereoDft->hConfig->itd_mode && hStereoDft->hItd->td_itd[STEREO_DFT_OFFSET] ) +#else if ( hStereoDft != NULL && hStereoDft->hConfig->hybrid_itd_flag && hStereoDft->hItd->td_itd[STEREO_DFT_OFFSET] ) +#endif { for ( n = 0; n < n_channels; n++ ) { @@ -1068,6 +1160,66 @@ float stereo_dft_enc_synthesize( output[offset + N + i] = ( tmp[zp + N + i] - ifft_deviation ) / win_ana[ovl - 1 - i] + ifft_deviation; } +#ifdef DEBUG_MODE_DFT + { + int16_t tmp_dbg[L_FRAME48k]; +#ifdef DEBUG_STEREO_DFT_NOCORE + static float mem_win[2][STEREO_DFT_OVL_MAX] = { { 0 }, { 0 } }; +#endif + char file_name[50] = { 0 }; + int16_t input_frame = N; + int16_t b = 0; + offset = -ovl; + b = L_frame; + +#ifdef DEBUG_STEREO_DFT_NOCORE + /*Simulate the un-windowing process which breaks partly TDAC of MDCT*/ + if ( ( ( chan == 1 ) || ( output_sampling_rate == input_Fs ) ) && ( L_frame <= 0 ) ) + { + float tmp_f[L_FRAME48k + STEREO_DFT_OVL_MAX]; + float MDCT[L_FRAME48k]; + + /*window signal*/ + for ( i = 0; i < ovl; i++ ) + { + tmp_f[i] = output[offset + i] * sqrt( win_ana[i] * win[i] ); + tmp_f[input_frame + i] = output[offset + input_frame + i] * sqrt( win_ana[ovl - 1 - i] * win[ovl - 1 - i] ); + } + /*Middle->Copy*/ + for ( ; i < input_frame; i++ ) + { + tmp_f[i] = output[offset + i]; + } + + /*MDCT -IMDCT (inject Time domain aliasing)*/ + TCX_MDCT( tmp_f, MDCT, ovl, input_frame - ovl, ovl, IVAS_CPE_DFT ); + TCX_MDCT_Inverse( MDCT, tmp_f, ovl, input_frame - ovl, ovl, IVAS_CPE_DFT ); + + /*OLA*/ + /*overlapping parts*/ + for ( i = 0; i < ovl; i++ ) + { + tmp_f[i] = mem_win[chan][i] + tmp_f[i] * sqrt( win_ana[i] * win[i] ); + mem_win[chan][i] = tmp_f[input_frame + i] * sqrt( win_ana[ovl - 1 - i] * win[ovl - 1 - i] ); + } + for ( i = 0; i < input_frame; i++ ) + { + tmp_dbg[i] = (int16_t) ( tmp_f[i] + 0.5f ); + } + } + else +#endif + { + for ( i = 0; i < input_frame; i++ ) + { + tmp_dbg[i] = (int16_t) ( output[offset + i] + 0.5f ); + } + } + + sprintf( file_name, "./res/stereo_dft_enc_M_S_%d_c%d_b%d.pcm", output_sampling_rate, chan, b ); + dbgwrite( tmp_dbg, sizeof( int16_t ), input_frame, 1, file_name ); + } +#endif pop_wmops(); return ( nrg ); @@ -1135,6 +1287,9 @@ void stereo_dft_enc_process( hStereoDft->res_pred_band_min = max( STEREO_DFT_RES_PRED_BAND_MIN, hStereoDft->res_cod_band_max ); +#ifdef DEBUG_MODE_DFT + dbgwrite( &( hStereoDft->nbands ), sizeof( int16_t ), 1, 1, "./res/stereo_dft_nbands.dat" ); +#endif hStereoDft->voicing_lt = 0.75f * hStereoDft->voicing_lt + 0.25f * hCPE->hCoreCoder[0]->voicing[0]; hStereoDft->voicing_lt = 0.75f * hStereoDft->voicing_lt + 0.25f * hCPE->hCoreCoder[0]->voicing[1]; @@ -1149,6 +1304,9 @@ void stereo_dft_enc_process( pDFT_L = hStereoDft->DFT[0]; pDFT_R = hStereoDft->DFT[1]; +#ifdef DEBUG_MODE_DFT + if ( hStereoDft->hConfig->itd_mode ) +#endif { stereo_dft_enc_compute_itd( hCPE, pDFT_L, pDFT_R, k_offset, input_frame, vad_flag_dtx, vad_hover_flag, bin_nrgL, bin_nrgR ); if ( hCPE->element_mode == IVAS_CPE_MDCT ) @@ -1207,6 +1365,18 @@ void stereo_dft_enc_process( bin_nrgR[i] = pDFT_R[2 * i] * pDFT_R[2 * i] + pDFT_R[2 * i + 1] * pDFT_R[2 * i + 1]; } } +#ifdef DEBUG_MODE_DFT + else + { + /* no ITD computation, get binwise energies here */ + + for ( i = 0; i < hStereoDft->NFFT / 2; i++ ) + { + bin_nrgL[i] = pDFT_L[2 * i] * pDFT_L[2 * i] + pDFT_L[2 * i + 1] * pDFT_L[2 * i + 1]; + bin_nrgR[i] = pDFT_R[2 * i] * pDFT_R[2 * i] + pDFT_R[2 * i + 1] * pDFT_R[2 * i + 1]; + } + } +#endif /* DFT stereo parameters */ stereo_dft_enc_compute_prm( hStereoDft, pDFT_L, pDFT_R, k_offset, 1, hCPE->hCoreCoder[0]->sp_aud_decision0, hCPE->hCoreCoder[0]->vad_flag, bin_nrgL, bin_nrgR, dot_prod_nrg_ratio ); @@ -1235,6 +1405,12 @@ void stereo_dft_enc_process( /*------------------------------------------------------------------* * Channel mapping: computation of DMX and RES *-----------------------------------------------------------------*/ +#ifdef DEBUG_MODE_DFT + { + int16_t tmp_dbg = (int16_t) ( 100 * fac_att ); + dbgwrite( &tmp_dbg, sizeof( int16_t ), 1, 1, "./res/stereo_dft_enc_facAtt.pcm" ); + } +#endif res_nrg_all_curr = EPSILON; dmx_nrg_all_curr = EPSILON; @@ -1278,6 +1454,13 @@ void stereo_dft_enc_process( if ( b < hStereoDft->res_cod_band_max && vad_flag_dtx[0] ) { +#ifdef DEBUGGING + assert( hStereoDft->nbands == hStereoDft->nbands_dmx && "Don't use coarser stereo parameter resolution for residual coding bitrates!" ); +#endif +#ifdef DEBUG_MODE_DFT + dbgwrite( &g, sizeof( float ), 1, 1, "./res/stereo_dft_enc_g.pcm" ); + dbgwrite( &alpha, sizeof( float ), 1, 1, "./res/stereo_dft_enc_alpha.pcm" ); +#endif /*Get the previous frame energy*/ if ( hStereoDft->hConfig->ada_wb_res_cod_mode ) @@ -1429,6 +1612,7 @@ void stereo_dft_enc_process( } else { +#ifndef DEBUG_STEREO_DFT_NOSTEREO /*passive DMX*/ assert( hStereoDft->nbands == hStereoDft->nbands_dmx && "Don't use coarser stereo parameter resolution for residual coding bitrates!" ); for ( i = 0; i < hStereoDft->band_limits[hStereoDft->res_cod_band_max]; i++ ) @@ -1440,6 +1624,22 @@ void stereo_dft_enc_process( { pDFT_DMX[i] = ( pDFT_L[i] + pDFT_R[i] ) * 0.5f; } +#else + /*Copy Left channel to DMX and reset residual coding*/ + mvr2r( pDFT_L, DFT_DMX, hStereoDft->NFFT ); + set_zero( pDFT_RES, hStereoDft->NFFT ); + + /*for( b=0; bnbands; b++ ) + { + if( hStereoDft->res_pred_mode[k+k_offset] && b>= hStereoDft->res_pred_band_min ) + { + if( (k % hStereoDft->prm_res_enc[k+k_offset]) == (hStereoDft->prm_res_enc[k+k_offset]-1) ) + { + stereo_dft_quantize_res_pred_gain( pPredGain+b, pPredGain+b, 1, hStereoDft->Ind+(k_offset+k)*STEREO_DFT_PRM_MAX, hStereoDft->nInd+k+k_offset ); + } + } + }*/ +#endif } /*------------------------------------------------------------------* @@ -1660,6 +1860,17 @@ static void stereo_dft_enc_get_res_cod_mode_flag( set_zero( hStereoDft->output_mem_res_8k, STEREO_DFT_OVL_8k ); } +#ifdef DEBUG_MODE_DFT + /* look at res_nrg_all value */ + { + static FILE *ResNrgAll_FILE = NULL; + + if ( ResNrgAll_FILE == NULL ) + ResNrgAll_FILE = fopen( "./res/stereo_dft_res_nrg.txt", "w" ); + fprintf( ResNrgAll_FILE, "%f\t\t%d\n", hStereoDft->res_dmx_ratio_lt, hStereoDft->res_cod_mode[STEREO_DFT_OFFSET] ); + dbgwrite( &hStereoDft->res_cod_mode[STEREO_DFT_OFFSET], sizeof( int16_t ), 1, 320, "./res/stereo_dft_res_cod_mode_flag.pcm" ); + } +#endif return; } @@ -1688,6 +1899,9 @@ void stereo_dft_enc_res( float panning_gain, panning_gain_min; float res_cod_gain[10]; float in_phase_ratio; +#ifdef DEBUG_MODE_DFT + float MDCT_RES_dec[L_FRAME8k] = { 0 }; +#endif assert( hStereoDft->res_cod_line_max <= L_FRAME8k ); if ( hStereoDft->res_cod_mode[STEREO_DFT_OFFSET] ) @@ -1729,6 +1943,9 @@ void stereo_dft_enc_res( } /*Smooth max_snr because of several perturbations in computation*/ +#ifdef DEBUG_MODE_DFT + dbgwrite( &max_snr, sizeof( float ), 1, 1, "./res/stereo_dft_res_cod_target_snr0.dat" ); +#endif hStereoDft->old_snr = 0.2f * max_snr + 0.8f * hStereoDft->old_snr; max_snr = hStereoDft->old_snr; @@ -1736,6 +1953,9 @@ void stereo_dft_enc_res( { max_snr = STEREO_DFT_RES_COD_SNR_MIN; } +#ifdef DEBUG_MODE_DFT + dbgwrite( &max_snr, sizeof( float ), 1, 1, "./res/stereo_dft_res_cod_target_snr.dat" ); +#endif push_wmops( "residual_encode" ); /* residual encoding */ @@ -1746,7 +1966,11 @@ void stereo_dft_enc_res( ecsq_inst.config_index = 2 * hStereoDft->res_cod_mode[STEREO_DFT_OFFSET] - 1; /* 7 bits (STEREO_DFT_RES_GLOBAL_GAIN_BITS) for global_gain_index, 2 bits for closing of the arithmetic coder, 8 safety bits to account for the size estimation accuracy */ +#ifndef DEBUG_MODE_DFT ECSQ_encode_target_SNR( &ecsq_inst, MDCT_RES, hStereoDft->res_cod_line_max, max_snr, max_bits - ( *nb_bits ) - STEREO_DFT_RES_GLOBAL_GAIN_BITS - 2 - 8, NULL, &global_gain_index ); +#else + total_bit_count = (int16_t) ECSQ_encode_target_SNR( &ecsq_inst, MDCT_RES, hStereoDft->res_cod_line_max, max_snr, max_bits - ( *nb_bits ) - STEREO_DFT_RES_GLOBAL_GAIN_BITS - 2 - 8, MDCT_RES_dec, &global_gain_index ); +#endif if ( global_gain_index != ECSQ_GLOBAL_GAIN_INDEX_ALL_ZERO ) { total_bit_count = rc_uni_enc_finish( &range_uni_enc_state ); @@ -1759,6 +1983,9 @@ void stereo_dft_enc_res( /* Global gain */ push_indice( hBstr, IND_STEREO_DFT_RESIDUAL_GLOBAL_GAIN, global_gain_index, STEREO_DFT_RES_GLOBAL_GAIN_BITS ); ( *nb_bits ) += STEREO_DFT_RES_GLOBAL_GAIN_BITS; +#ifdef DEBUG_MODE_DFT + fprintf( pF, "Gain: %d ", global_gain_index ); +#endif /* Push arithmetic coded bits */ byte_buffer = range_uni_enc_state.byte_buffer; @@ -1772,6 +1999,9 @@ void stereo_dft_enc_res( push_indice( hBstr, IND_STEREO_DFT_RESIDUAL_COD, byte_buffer[idx] >> ( 8 - ( total_bit_count & 7 ) ), total_bit_count & 7 ); } ( *nb_bits ) += total_bit_count; +#ifdef DEBUG_MODE_DFT + fprintf( pF, "%d (max: %d)\n", STEREO_DFT_RES_GLOBAL_GAIN_BITS + total_bit_count, max_bits ); +#endif } else { @@ -1779,6 +2009,10 @@ void stereo_dft_enc_res( global_gain_index = ECSQ_GLOBAL_GAIN_INDEX_ALL_ZERO; push_indice( hBstr, IND_STEREO_DFT_RESIDUAL_GLOBAL_GAIN, global_gain_index, STEREO_DFT_RES_GLOBAL_GAIN_BITS ); ( *nb_bits ) += STEREO_DFT_RES_GLOBAL_GAIN_BITS; +#ifdef DEBUG_MODE_DFT + fprintf( pF, "Gain: %d ", global_gain_index ); + fprintf( pF, "%d (max: %d)\n", STEREO_DFT_RES_GLOBAL_GAIN_BITS, max_bits ); +#endif } } else @@ -1786,11 +2020,95 @@ void stereo_dft_enc_res( /* Global gain -> 127*/ push_indice( hBstr, IND_STEREO_DFT_RESIDUAL_GLOBAL_GAIN, global_gain_index, STEREO_DFT_RES_GLOBAL_GAIN_BITS ); ( *nb_bits ) += STEREO_DFT_RES_GLOBAL_GAIN_BITS; +#ifdef DEBUG_MODE_DFT + fprintf( pF, "Gain: %d ", global_gain_index ); + fprintf( pF, "%d (max: %d)\n", STEREO_DFT_RES_GLOBAL_GAIN_BITS, max_bits ); +#endif } +#ifdef DEBUG_MODE_DFT + { + static FILE *resCodingSNR = NULL; + if ( resCodingSNR == NULL ) + resCodingSNR = fopen( "./res/resCodingSNR.txt", "w" ); + fprintf( resCodingSNR, "%d\t%d\t%f\n", STEREO_DFT_RES_GLOBAL_GAIN_BITS + total_bit_count, max_bits, max_snr ); + } +#endif pop_wmops(); +#ifdef DEBUG_MODE_DFT + { + int16_t tmp[1024]; + static float mem_win[STEREO_DFT_OVL_8k]; + float global_gain; + int16_t input_frame = L_FRAME8k; + float res_cod_error, res_cod_nrg, res_cod_snr; + + for ( i = 0; i < input_frame; i++ ) + { + tmp[i] = (int16_t) ( input_8k[i] + 0.5f ); + } + dbgwrite( &tmp, sizeof( int16_t ), input_frame, 1, "./res/stereo_dft_enc_res_original.pcm" ); + + if ( global_gain_index != ECSQ_GLOBAL_GAIN_INDEX_ALL_ZERO ) + { + global_gain = ECSQ_dequantize_gain( global_gain_index ); + } + else + { + global_gain = 0.f; + } + dbgwrite( &global_gain, sizeof( float ), 1, 1, "./res/stereo_dft_res_cod_gain.dat" ); + + tmp[0] = total_bit_count; + dbgwrite( &tmp, sizeof( int16_t ), 1, 1, "./res/stereo_dft_res_cod_bits.dat" ); + + dbgwrite( &( hStereoDft->res_cod_line_max ), sizeof( int16_t ), 1, 1, "./res/stereo_dft_res_cod_line.dat" ); + dbgwrite( &( hStereoDft->res_cod_band_max ), sizeof( int16_t ), 1, 1, "./res/stereo_dft_res_cod_band_max.dat" ); + dbgwrite( &( hStereoDft->res_cod_NRG_M ), sizeof( float ), hStereoDft->nbands, 1, "./res/stereo_dft_dmx_nrg.dat" ); + dbgwrite( &( hStereoDft->res_cod_NRG_S ), sizeof( float ), hStereoDft->nbands, 1, "./res/stereo_dft_res_nrg.dat" ); + + /*Compute coding SNR*/ + res_cod_nrg = EPSILON; + res_cod_error = EPSILON; + for ( i = 0; i < hStereoDft->res_cod_line_max; i++ ) + { + res_cod_nrg += MDCT_RES[i] * MDCT_RES[i]; + res_cod_error += ( MDCT_RES[i] - MDCT_RES_dec[i] ) * ( MDCT_RES[i] - MDCT_RES_dec[i] ); + } + + res_cod_snr = 10.f * log10f( res_cod_nrg / res_cod_error ); + dbgwrite( &( res_cod_snr ), sizeof( float ), 1, 1, "./res/stereo_dft_res_cod_snr.dat" ); + + /*IMDCT*/ + TCX_MDCT_Inverse( MDCT_RES_dec, win, STEREO_DFT_OVL_8k, L_FRAME8k - STEREO_DFT_OVL_8k, STEREO_DFT_OVL_8k, IVAS_CPE_DFT ); + + /*OLA*/ + /*overlapping parts*/ + for ( i = 0; i < STEREO_DFT_OVL_8k; i++ ) + { + win[i] = mem_win[i] + win[i] * hStereoDft->win_mdct_8k[i]; + mem_win[i] = win[input_frame + i] * hStereoDft->win_mdct_8k[STEREO_DFT_OVL_8k - 1 - i]; + } + for ( i = 0; i < input_frame; i++ ) + { + tmp[i] = (int16_t) ( win[i] + 0.5f ); + } + dbgwrite( tmp, sizeof( int16_t ), input_frame, 1, "./res/stereo_dft_enc_res_decoded.pcm" ); + } +#endif } +#ifdef DEBUG_MODE_DFT + { + int16_t input_frame = L_FRAME8k; + static FILE *bits_consumed = NULL; + if ( bits_consumed == NULL ) + bits_consumed = fopen( "./res/stereo_dft_bits_consumed.txt", "w" ); + + fprintf( bits_consumed, " %d \n", *nb_bits ); + dbgwrite( nb_bits, sizeof( int16_t ), 1, input_frame, "./res/stereo_dft_bits_consumed.dat" ); + } +#endif return; } @@ -1817,6 +2135,21 @@ void stereo_dft_enc_write_BS( BSTR_ENC_HANDLE hBstr; STEREO_DFT_ENC_DATA_HANDLE hStereoDft; int32_t core_brate; +#ifdef DEBUG_MODE_DFT + static FILE *ITD_values = NULL, *side_gain_values = NULL, *RPG_values = NULL; + static FILE *cum_freq_enc = NULL; + + if ( pF == NULL ) + pF = fopen( "./res/stereo_dft_enc_ind.txt", "w" ); + if ( ITD_values == NULL ) + ITD_values = fopen( "./res/itd_indicies_enc.txt", "w" ); + if ( side_gain_values == NULL ) + side_gain_values = fopen( "./res/side_gain_indicies_enc.txt", "w" ); + if ( RPG_values == NULL ) + RPG_values = fopen( "./res/rpg_indicies_enc.txt", "w" ); + if ( cum_freq_enc == NULL ) + cum_freq_enc = fopen( "./res/cum_freq_enc.txt", "w" ); +#endif /*------------------------------------------------------------------* * Initialization @@ -1874,8 +2207,19 @@ void stereo_dft_enc_write_BS( ( *nb_bits )++; hStereoDft->res_cod_band_max = dft_band_res_cod[hStereoDft->hConfig->band_res][hStereoDft->res_cod_mode[k_offset]]; hStereoDft->res_pred_band_min = max( STEREO_DFT_RES_PRED_BAND_MIN, hStereoDft->res_cod_band_max ); +#ifdef DEBUG_MODE_DFT + fprintf( pF, "res_cod_mode: %d\n", hStereoDft->res_cod_mode[k_offset] ); +#endif } +#ifdef DEBUG_MODE_DFT + fprintf( pF, "stereo Data: %d %d %d %d %d\n", hStereoDft->band_res[k_offset], 1, hStereoDft->res_pred_mode[k_offset], hStereoDft->res_cod_mode[k_offset], hStereoDft->res_cod_band_max ); + fprintf( pF, "stereo Bands: %d\n", hStereoDft->nbands ); + + dbgwrite( &( hStereoDft->nbands ), sizeof( int16_t ), 1, 1, "./res/stereo_dft_encBS_nbands.dat" ); + dbgwrite( &( hCPE->hCoreCoder[0]->bwidth ), sizeof( int16_t ), 1, 1, "./res/stereo_dft_encBS_bwidth.dat" ); + +#endif if ( nbands_full < hStereoDft->nbands ) { @@ -1901,6 +2245,9 @@ void stereo_dft_enc_write_BS( ( *nb_bits ) += STEREO_DFT_ITD_MODE_NBITS; /*ITD mode flag: 1bit*/ } +#ifdef DEBUG_MODE_DFT + fprintf( pF, "ITD: %d ", hStereoDft->hConfig->itd_mode && ( hStereoDft->hItd->itd[k_offset] != 0 ) ); +#endif if ( core_brate != SID_2k40 ) { if ( hStereoDft->hItd->itd[k_offset] ) @@ -1941,6 +2288,10 @@ void stereo_dft_enc_write_BS( ( *nb_bits ) += STEREO_DFT_ITD_NBITS + 1; } } +#ifdef DEBUG_MODE_DFT + fprintf( pF, "ITD: %d ", hStereoDft->hItd->itd_index[k_offset] ); + fprintf( ITD_values, "%d %d ", frame, hStereoDft->hItd->itd_index[k_offset] ); +#endif } } @@ -1967,6 +2318,13 @@ void stereo_dft_enc_write_BS( no_GR_ord = 3; +#ifdef DEBUG_MODE_DFT + for ( b = 0; b < hStereoDft->nbands; b++ ) + { + fprintf( pF, "Side gain: %d ", hStereoDft->side_gain_index_EC[b] ); + fprintf( side_gain_values, " %d ", hStereoDft->side_gain_index_EC[b] ); + } +#endif if ( hStereoDft->side_gain_flag_1 == 0 ) { nb += write_bitstream_adapt_GR( hBstr, IND_STEREO_DFT_SIDEGAINS, encoded_ind_GR, hStereoDft->nbands, hStereoDft->side_gain_flag_2, no_GR_ord ); @@ -2052,6 +2410,10 @@ void stereo_dft_enc_write_BS( ( *nb_bits ) += STEREO_DFT_SID_ITD_NBITS + 1; } +#ifdef DEBUG_MODE_DFT + fprintf( pF, "ITD: %d ", hStereoDft->hItd->itd_index[k_offset] ); + fprintf( ITD_values, "%d %d ", frame, hStereoDft->hItd->itd_index[k_offset] ); +#endif } } } @@ -2108,6 +2470,9 @@ void stereo_dft_enc_write_BS( /*read flag*/ push_indice( hBstr, IND_STEREO_DFT_REVERB_MODE, hStereoDft->reverb_flag, STEREO_DFT_REVERB_MODE_NBITS ); nb += STEREO_DFT_REVERB_MODE_NBITS; +#ifdef DEBUG_MODE_DFT + fprintf( RPG_values, " reverb_flag %d ", hStereoDft->reverb_flag ); +#endif if ( hStereoDft->reverb_flag ) { nbands -= STEREO_DFT_RES_PRED_BAND_MIN_CONST; @@ -2129,6 +2494,9 @@ void stereo_dft_enc_write_BS( no_GR_ord = 2; if ( hStereoDft->res_pred_flag_1 == 0 ) { +#ifdef DEBUG_MODE_DFT + fprintf( RPG_values, "flag: 0" ); +#endif if ( encoded_ind_pred_GR[0] == dft_maps_rpg[8 * NO_SYMB_GR_PRED_G] ) { nb += write_GR1( hBstr, IND_STEREO_DFT_PRED_GAIN_COD, encoded_ind_pred_GR, 1 ); @@ -2142,10 +2510,16 @@ void stereo_dft_enc_write_BS( { if ( hStereoDft->res_pred_flag_1 == 2 ) { +#ifdef DEBUG_MODE_DFT + fprintf( RPG_values, "flag: 2" ); +#endif nb += write_bitstream_GR( hBstr, IND_STEREO_DFT_PRED_GAIN_COD, &hStereoDft->res_pred_index_ECDiff[hStereoDft->res_pred_band_min], nbands - hStereoDft->res_pred_band_min, hStereoDft->res_pred_flag_2 - no_GR_ord ); } else { +#ifdef DEBUG_MODE_DFT + fprintf( RPG_values, "flag: 1" ); +#endif for ( b = hStereoDft->res_pred_band_min; b < nbands; b++ ) { push_indice( hBstr, IND_STEREO_DFT_PRED_GAIN_COD, hStereoDft->res_pred_index_EC[b], STEREO_DFT_RES_GAINS_BITS ); @@ -2154,6 +2528,20 @@ void stereo_dft_enc_write_BS( } } +#ifdef DEBUG_MODE_DFT + for ( b = hStereoDft->res_pred_band_min; b < nbands; b++ ) + { + fprintf( pF, "Res pred values: %d ", hStereoDft->res_pred_index_EC[b] ); + if ( hStereoDft->res_pred_flag_1 == 2 ) + { + fprintf( RPG_values, " %d(%d) ", hStereoDft->res_pred_index_EC[b], hStereoDft->res_pred_index_EC[b] + ( ( hStereoDft->res_pred_index_ECDiff[b] % 2 ) ? -( hStereoDft->res_pred_index_ECDiff[b] + 1 ) / 2 : ( hStereoDft->res_pred_index_ECDiff[b] ) / 2 ) ); + } + else + { + fprintf( RPG_values, " %d ", hStereoDft->res_pred_index_EC[b] ); + } + } +#endif } else { @@ -2172,6 +2560,13 @@ void stereo_dft_enc_write_BS( stereo_dft_enc_sid_coh( hBstr, hCPE->hStereoCng->mem_cohBand, hStereoDft->nbands, nb_bits, cohBand ); } +#ifdef DEBUG_MODE_DFT + /*fprintf(pF, "Total bits: %d", (*nb_bits));*/ + fprintf( pF, "\n" ); + fprintf( ITD_values, "\n" ); + fprintf( side_gain_values, "\n" ); + fprintf( RPG_values, "\n" ); +#endif return; } @@ -2250,6 +2645,10 @@ static void stereo_dft_enc_compute_prm( sum_dot_prod_real = EPSILON; sum_dot_prod_img = EPSILON; sub_nrg_DMX2 = 0.f; +#ifdef DEBUG_MODE_DFT + sum_nrg_L = EPSILON; + sum_nrg_R = EPSILON; +#endif /*------------------------------------------------------------------* * Band-wise processing @@ -2471,13 +2870,40 @@ static void stereo_dft_enc_compute_prm( hStereoDft->nrg_past_pos = ( pos + 1 ) % STEREO_DFT_NRG_PAST_LEN; +#ifdef DEBUG_MODE_DFT + { + float tmp_f; + dbgwrite( pPredGain, sizeof( float ), hStereoDft->nbands, 1, "./res/stereo_dft_gainPred.pcm" ); + dbgwrite( pSideGain, sizeof( float ), hStereoDft->nbands, 1, "./res/stereo_dft_gainSide.pcm" ); + + for ( i = 0; i < hStereoDft->nbands; i++ ) + { + float regularization; + + regularization = ( hStereoDft->band_limits[i + 1] - hStereoDft->band_limits[i] ) * sqrtf( hStereoDft->NFFT ); + tmp_f = sub_nrg_DMX[i] / ( regularization * regularization ); + dbgwrite( &tmp_f, sizeof( float ), 1, 1, "./res/stereo_dft_nrgDMX.pcm" ); + + g = sqrtf( sum_nrg_L / sum_nrg_R ); + tmp_f = ( g - 1 ) / ( g + 1 ); + dbgwrite( &tmp_f, sizeof( float ), 1, 1, "./res/stereo_dft_gainILD.pcm" ); + } + } +#endif /*------------------------------------------------------------------* * Compute IPDs *-----------------------------------------------------------------*/ +#ifdef DEBUG_MODE_DFT + stereo_dft_enc_get_nipd_flag( hStereoDft, pgIpd, sp_aud_decision0, gain_IPD ); +#else stereo_dft_enc_get_nipd_flag( hStereoDft, sp_aud_decision0, gain_IPD ); +#endif +#ifdef DEBUG_MODE_DFT + hStereoDft->no_ipd_flag = ( hStereoDft->hConfig->gipd_mode == 0 ) ? 1 : hStereoDft->no_ipd_flag; +#endif if ( flag_quant ) { @@ -2602,7 +3028,16 @@ static void stereo_dft_enc_compute_prm( hStereoDft->res_pred_index_EC[b - STEREO_DFT_RES_PRED_BAND_MIN_CONST] = hStereoDft->res_pred_index_EC[b]; } } +#ifdef DEBUG_MODE_DFT + if ( hStereoDft->reverb_flag ) + { + dbgwrite( &ipred, sizeof( ipred ), 1, 1, "./res/stereo_dft_enc_ipred" ); + } +#endif } +#ifdef DEBUG_MODE_DFT + dbgwrite( &( hStereoDft->reverb_flag ), sizeof( int16_t ), 1, 640, "./res/stereo_dft_reverb_flag2.pcm" ); +#endif assert( hStereoDft->nbands <= 13 ); /* always use band_limits_erb4 and not band_limits_erb2 */ @@ -2824,6 +3259,10 @@ static float stereo_dft_calc_mean_bipd( } ipd_buf[STEREO_DFT_IPD_BUF_LEN - 1] = *pIpd; +#ifdef DEBUG_MODE_DFT + dbgwrite( pIpd, sizeof( float ), 1, 1, "res/stereo_dft_bipd.pcm" ); + dbgwrite( &ipd_smooth, sizeof( float ), 1, 1, "res/stereo_dft_bipd_smooth.pcm" ); +#endif return ipd_smooth; } @@ -2857,6 +3296,10 @@ static float stereo_dft_calc_mean_ipd_change( } ipd_mean_change /= gipd_band_max; +#ifdef DEBUG_MODE_DFT + dbgwrite( ipd_change, sizeof( float ), hStereoDft->gipd_band_max, 1, "res/stereo_dft_ipd_change.pcm" ); + dbgwrite( &ipd_mean_change, sizeof( float ), 1, 1, "res/stereo_dft_ipd_mean_change.pcm" ); +#endif return ipd_mean_change; } @@ -2933,6 +3376,9 @@ static void stereo_dft_gipd_stabilization( static void stereo_dft_enc_get_nipd_flag( STEREO_DFT_ENC_DATA_HANDLE hStereoDft, +#ifdef DEBUG_MODE_DFT + float *pgIpd, +#endif const int16_t sp_aud_decision0, const float gainIPD ) { @@ -2945,6 +3391,15 @@ static void stereo_dft_enc_get_nipd_flag( hStereoDft->no_ipd_flag = 1; /* Set the flag */ } +#ifdef DEBUG_MODE_DFT + { + int16_t tmp; + dbgwrite( &( hStereoDft->no_ipd_flag ), sizeof( int16_t ), 1, 640, "./res/stereo_dft_nipd_first.pcm" ); + tmp = (int16_t) ( hStereoDft->gainIPD_sm * 100.f ); + dbgwrite( &tmp, sizeof( int16_t ), 1, 640, "./res/stereo_dft_gipd_gain_IPD.pcm" ); + dbgwrite( pgIpd, sizeof( float ), 1, 1, "./res/stereo_dft_gipd_IPD.pcm" ); + } +#endif /* hangover between the group IPD and subband IPD */ if ( hStereoDft->prev_no_ipd_flag != hStereoDft->no_ipd_flag && hStereoDft->no_ipd_cnt < 5 ) @@ -2959,6 +3414,10 @@ static void stereo_dft_enc_get_nipd_flag( hStereoDft->prev_no_ipd_flag = hStereoDft->no_ipd_flag; /* Save the no IPD flag for the next frame */ +#ifdef DEBUG_MODE_DFT + /*fprintf(pF2, "%d\n",hStereoDft->no_ipd_flag);*/ + dbgwrite( &( hStereoDft->no_ipd_flag ), sizeof( int16_t ), 1, 640, "./res/stereo_dft_nipd_final.pcm" ); +#endif return; } @@ -3118,6 +3577,9 @@ static void stereo_dft_enc_get_reverb_flag( } } +#ifdef DEBUG_MODE_DFT + dbgwrite( &( hStereoDft->reverb_flag ), sizeof( int16_t ), 1, 640, "./res/stereo_dft_reverb_flag.pcm" ); +#endif return; } diff --git a/lib_enc/ivas_stereo_dft_enc_itd.c b/lib_enc/ivas_stereo_dft_enc_itd.c index 2d43e3d30..d3336f4eb 100644 --- a/lib_enc/ivas_stereo_dft_enc_itd.c +++ b/lib_enc/ivas_stereo_dft_enc_itd.c @@ -42,6 +42,9 @@ #include "ivas_cnst.h" #include "ivas_rom_com.h" #include "ivas_rom_enc.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" @@ -1060,6 +1063,12 @@ void stereo_dft_enc_compute_itd( hStereoClassif->unclr_fv[E_sum_xcorr] = sum_xcorr; hStereoClassif->xtalk_fv[E_sum_xcorr] = sum_xcorr; +#if defined( DEBUG_MODE_DFT ) || defined( DEBUG_MODE_TD ) + dbgwrite( &hStereoClassif->unclr_fv[E_cohSNR], sizeof( float ), 1, 1, "res/stereo_clf_cohSNR.x" ); + dbgwrite( &hStereoClassif->unclr_fv[E_es_em], sizeof( float ), 1, 1, "res/stereo_clf_es_em.x" ); + dbgwrite( &hStereoClassif->unclr_fv[E_d_prodL_prodR], sizeof( float ), 1, 1, "res/stereo_clf_d_prodL_prodR.x" ); + dbgwrite( &hStereoClassif->unclr_fv[E_sum_xcorr], sizeof( float ), 1, 1, "res/stereo_clf_sum_xcorr.x" ); +#endif } /* reset estimates when silence is detected*/ @@ -1092,6 +1101,9 @@ void stereo_dft_enc_compute_itd( mvr2r( &xcorr_itd[STEREO_DFT_N_32k_ENC / 2 - XTALK_PHAT_LEN], gcc_phat, 2 * XTALK_PHAT_LEN + 1 ); +#ifdef DEBUG_MODE_DFT + dbgwrite( gcc_phat, sizeof( float ), 2 * XTALK_PHAT_LEN + 1, 1, "res/gcc_phat" ); +#endif thres = peak_detect( xcorr_itd, &tmpf1, &index, &zero_itd, cohSNR, hCPE->hCoreCoder[0]->vad_flag, &second_max, &second_max_lag, hItd->prev_itd, flag_noisy_speech_snr, hItd->detected_itd_flag, &hItd->prev_max, &hItd->prev_index, &hItd->prev_avg_max, &total_max ); @@ -1105,13 +1117,38 @@ void stereo_dft_enc_compute_itd( hStereoClassif->unclr_fv[E_xcorr_itd_value] = total_max; hStereoClassif->xtalk_fv[E_xcorr_itd_value] = total_max; +#if defined( DEBUG_MODE_DFT ) || defined( DEBUG_MODE_TD ) + { + int16_t stmp = index - STEREO_DFT_ITD_MAX_ANA; + dbgwrite( &stmp, sizeof( int16_t ), 1, 1, "res/raw_itd.x" ); + } + dbgwrite( &hStereoClassif->unclr_fv[E_xcorr_itd_value], sizeof( float ), 1, 1, "res/stereo_clf_raw_itd.x" ); +#endif + +#ifdef DEBUG_MODE_DFT + { + int16_t tmp; + tmp = (int16_t) ( tmpf1 * 100.f / thres ); + dbgwrite( &tmp, sizeof( int16_t ), 1, input_frame, "./res/stereo_dft_itd_thres0.pcm" ); + } +#endif /*for tonal music items increase thresholing by a factor up to 2.*/ if ( hCPE->hCoreCoder[0]->sp_aud_decision0 && ( index - STEREO_DFT_ITD_MAX_ANA ) != hItd->prev_itd && !flag_noisy_speech_snr && hCPE->hCoreCoder[0]->vad_flag && tmpf1 < 0.3 ) { thres *= 1.0f + 1.f * min( 1.f, max( 0.f, ( -1.0f * sfm_L + 0.5f ) / ( 0.5f - 0.2f ) ) ); } +#ifdef DEBUG_MODE_DFT + { + int16_t tmp; + + tmp = (int16_t) ( sfm_L * 100.f ); + dbgwrite( &tmp, sizeof( int16_t ), 1, input_frame, "./res/stereo_dft_itd_sfm.pcm" ); + tmp = (int16_t) ( tmpf1 * 100.f / thres ); + dbgwrite( &tmp, sizeof( int16_t ), 1, input_frame, "./res/stereo_dft_itd_thres.pcm" ); + } +#endif itd_cal_flag = 0; /*smooth threshold value depending on sfm for music items*/ @@ -1310,6 +1347,9 @@ void stereo_dft_enc_compute_itd( /* collect UNCLR classifier parameters */ hStereoClassif->unclr_fv[E_ITD] = hItd->itd[k_offset]; +#if defined( DEBUG_MODE_DFT ) || defined( DEBUG_MODE_TD ) + dbgwrite( &hItd->itd[k_offset], sizeof( float ), 1, 1, "res/stereo_clf_ITD.x" ); +#endif /* limit ITD range for MDCT stereo even more */ if ( hCPE->element_mode == IVAS_CPE_MDCT && fabsf( hItd->itd[k_offset] ) > ITD_MAX_MDCT ) @@ -1338,6 +1378,20 @@ void stereo_dft_enc_compute_itd( hItd->hybrid_itd_max = -1; } +#ifdef DEBUG_MODE_DFT + { + int16_t tmp; + static FILE *log_fid = NULL; + + tmp = (int16_t) hItd->itd[k_offset]; + dbgwrite( &tmp, sizeof( int16_t ), 1, input_frame, "./res/stereo_dft_itd_combined_fc.pcm" ); + dbgwrite( &tmp, sizeof( int16_t ), 1, input_frame, "./res/stereo_dft_itd_combined_fc.txt" ); + + if ( log_fid == NULL ) + log_fid = fopen( "./res/itd_log_td_itd.txt", "w" ); + fprintf( log_fid, "frame: %d\t itd: %f\t td_itd: %d\t delta_itd: %f\n", frame, hItd->itd[1], (int16_t) hItd->td_itd[1], hItd->deltaItd[1] ); + } +#endif return; } diff --git a/lib_enc/ivas_stereo_dft_td_itd.c b/lib_enc/ivas_stereo_dft_td_itd.c index ce5553518..ee37e924d 100644 --- a/lib_enc/ivas_stereo_dft_td_itd.c +++ b/lib_enc/ivas_stereo_dft_td_itd.c @@ -41,6 +41,12 @@ #include "ivas_rom_com.h" #include "ivas_stat_enc.h" #include "ivas_cnst.h" +#ifdef DEBUGGING +#include "debug.h" +#endif +#ifdef DEBUG_PLOT +#include "deb_out.h" +#endif #include "wmc_auto.h" @@ -229,6 +235,9 @@ void stereo_td_itd( ITD_DATA *hITD, /* i/o: ITD data structure */ float input_mem_itd[CPE_CHANNELS][STEREO_DFT_OVL_MAX], /* o : ITD memory (only used in DFT Stereo) */ const int16_t hybrid_itd_flag, /* i : flag for hybrid TD/FD ITD processing */ +#ifdef DEBUG_MODE_DFT + const int16_t itd_mode, /* i : main ITD processing flag */ +#endif const int16_t dft_ovl, /* i : size of DFT overlap */ Encoder_State **sts, /* i/o: Encoder state structure */ const int16_t input_frame, /* i : input frame length */ @@ -275,6 +284,9 @@ void stereo_td_itd( stereo_td_get_td_itd( &( hITD->td_itd[k_offset] ), &( hITD->td_itd_32k[k_offset] ), hITD->itd[k_offset], sts[0]->input_Fs ); /* initializations*/ +#ifdef DEBUG_MODE_DFT + if ( itd_mode ) +#endif { size_ovl = dft_ovl; @@ -346,6 +358,25 @@ void stereo_td_itd( } } +#ifdef DEBUG_MODE_DFT + { + int16_t tmp[L_FRAME48k]; + + for ( i = 0; i < input_frame; i++ ) + { + tmp[i] = (int16_t) ( sts[0]->input[i] + 0.5f ); + } + + dbgwrite( tmp, sizeof( int16_t ), input_frame, 1, "./res/td_shifted_signal_ch0.pcm" ); + + for ( i = 0; i < input_frame; i++ ) + { + tmp[i] = (int16_t) ( sts[1]->input[i] + 0.5f ); + } + + dbgwrite( tmp, sizeof( int16_t ), input_frame, 1, "./res/td_shifted_signal_ch1.pcm" ); + } +#endif return; } @@ -390,7 +421,11 @@ void stereo_td_itd_mdct_stereo( stereo_dft_enc_compute_itd( hCPE, DFT[0], DFT[1], STEREO_DFT_OFFSET, input_frame, vad_flag_dtx, vad_hover_flag, bin_nrgL, bin_nrgR ); /* Time Domain ITD compensation using extrapolation */ +#ifdef DEBUG_MODE_DFT + stereo_td_itd( hStereoMdct->hItd, NULL, 1, 1, hStereoMdct->hDft_ana->dft_ovl, hCPE->hCoreCoder, input_frame, hCPE->input_mem ); +#else stereo_td_itd( hStereoMdct->hItd, NULL, 1, hStereoMdct->hDft_ana->dft_ovl, hCPE->hCoreCoder, input_frame, hCPE->input_mem ); +#endif } return; diff --git a/lib_enc/ivas_stereo_dmx_evs.c b/lib_enc/ivas_stereo_dmx_evs.c index 5ac6fe180..2ffc13d75 100644 --- a/lib_enc/ivas_stereo_dmx_evs.c +++ b/lib_enc/ivas_stereo_dmx_evs.c @@ -40,6 +40,9 @@ #include "ivas_prot.h" #include "ivas_rom_com.h" #include "ivas_rom_enc.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" diff --git a/lib_enc/ivas_stereo_eclvq_enc.c b/lib_enc/ivas_stereo_eclvq_enc.c index 663101ca4..f71beece8 100644 --- a/lib_enc/ivas_stereo_eclvq_enc.c +++ b/lib_enc/ivas_stereo_eclvq_enc.c @@ -82,6 +82,10 @@ void ECSQ_quantize_vector( { int16_t i; float inv_global_gain; +#ifdef DEBUGGING + assert( N > 0 ); + assert( global_gain > 0.0f ); +#endif inv_global_gain = 1.0f / global_gain; for ( i = 0; i < N; ++i ) @@ -108,6 +112,9 @@ float ECSQ_compute_optimal_gain( float sum_sq_output; float sum_input_output; float optimal_global_gain; +#ifdef DEBUGGING + assert( N > 0 ); +#endif sum_sq_output = 0.0f; sum_input_output = 0.0f; @@ -137,6 +144,9 @@ static int16_t ECSQ_quantize_gain( { int16_t index; +#ifdef DEBUGGING + assert( global_gain > 0.0f ); +#endif global_gain = max( global_gain, 1.0f ); /* because always index >= 0 anyway */ @@ -167,6 +177,10 @@ static void arith_encode_bit( RangeUniEncState *rc_st_enc; rc_st_enc = (RangeUniEncState *) ecsq_inst->ac_handle; +#ifdef DEBUGGING + assert( bit >= 0 ); + assert( bit < 2 ); +#endif ecsq_inst->bit_count_estimate += 1024; /* 1024 eq 1 << 10, 22Q10 fixed-point representation */ @@ -193,6 +207,9 @@ static void arith_encode_bits( RangeUniEncState *rc_st_enc; rc_st_enc = (RangeUniEncState *) ecsq_inst->ac_handle; +#ifdef DEBUGGING + assert( n < ( 1 << size ) ); +#endif ecsq_inst->bit_count_estimate += size << 10; /* 22Q10 fixed-point representation */ @@ -218,6 +235,10 @@ static int16_t code_length_from_count( /* with c in {1, ..., 2 ^ 14}, representing a probability count in 14-bit AC implementations */ int16_t c_norm; int16_t res; +#ifdef DEBUGGING + assert( c >= 1 ); + assert( c <= ( 1 << 14 ) ); +#endif #define WMC_TOOL_SKIP c_norm = norm_s( (int16_t) c ); /* equivalent with 14 - floor(log_base2(c)) */ @@ -227,6 +248,10 @@ static int16_t code_length_from_count( /* normalize to {16384, ..., 32767}, subtract MSB bit, and convert to Q6 for indexing log2_1px_table */ res = ( c_norm << 10 ) - log2_1px_table[( ( c << c_norm ) - ( 1 << 14 ) + ( 1 << 7 ) ) >> 8]; +#ifdef DEBUGGING + assert( res >= 0 ); /* for c == 1 */ + assert( res <= 14 * ( 1 << 10 ) ); /* for c == 16384 */ +#endif /* |(14 - log2(c)) - res / (1 << 10)| < 0.0113, for c in {1, ..., 2 ^ 14} */ /* complexity: 1 norm_s, 2 adds, 3 shifts, 1 table lookup */ @@ -248,6 +273,12 @@ static void arith_encode_bit_prob( RangeUniEncState *rc_st_enc; rc_st_enc = (RangeUniEncState *) ecsq_inst->ac_handle; +#ifdef DEBUGGING + assert( bit >= 0 ); + assert( bit < 2 ); + assert( count0 >= 1 ); + assert( count0 <= ECSQ_PROB_TOTAL - 1 ); +#endif count = ECSQ_PROB_TOTAL - count0; @@ -284,9 +315,18 @@ static void arith_encode_prob( rc_st_enc = (RangeUniEncState *) ecsq_inst->ac_handle; +#ifdef DEBUGGING + assert( symbol < table_size ); + assert( table[symbol] <= ( 1 << 14 ) ); +#else count = table_size; /* just to avoid warning when DEBUGGING is deactivated */ +#endif count = table[symbol] - table[symbol + 1]; +#ifdef DEBUGGING + assert( count >= 1 ); + assert( count <= ( 1 << 14 ) ); +#endif ecsq_inst->bit_count_estimate += code_length_from_count( count ); /* 22Q10 fixed-point representation */ @@ -310,6 +350,10 @@ static void arith_encode_elias_mod( const int16_t n ) { int16_t i; +#ifdef DEBUGGING + assert( n >= 0 ); + /* n is already limited by the data type int16_t, so n_bits = floor(log_2(n)) <= 14 */ +#endif if ( n <= 1 ) { @@ -389,10 +433,16 @@ static int16_t get_best_param( sum_abs = 0; count = stop_offset - start_offset + 1; count0 = 0; +#ifdef DEBUGGING + assert( count > 0 ); +#endif /* compute sum(abs(x[v])) and sum(x[v] == 0) */ for ( v = start_offset; v <= stop_offset; ++v ) { +#ifdef DEBUGGING + assert( abs( x[v] ) <= MAX16B ); +#endif val = x[v]; sum_abs += abs( val ); @@ -402,6 +452,9 @@ static int16_t get_best_param( } } +#ifdef DEBUGGING + assert( sum_abs <= count * MAX16B ); +#endif /* the vector has at most ECSQ_NONZERO_MAX values of +-1 and the rest are zeros */ if ( ( count - count0 <= ECSQ_NONZERO_MAX ) && ( sum_abs == count - count0 ) ) @@ -455,6 +508,9 @@ static float get_est_size( index = param - ECSQ_log2TB_FIRST_PARAM; index = min( index, ECSQ_log2TB_SIZE - 2 ); +#ifdef DEBUGGING + assert( index >= 0 ); +#endif /* the estimated size in bits is N * log2(2 * 2 ^ param) + */ /* + N * log2(e) * (avg_abs_sum / 2 ^ param) - (N - N0) * log2(T(2 ^ param)) - */ @@ -525,6 +581,14 @@ static int32_t ECSQ_encode_raw( bit_count_estimate_initial = ecsq_inst->bit_count_estimate; +#ifdef DEBUGGING + assert( N > 0 ); + assert( ECSQ_ALL_ZERO_PARAM == -1 ); /* other values need code and table adjustments */ + assert( ( ecsq_inst->config_index >= 1 ) && ( ecsq_inst->config_index < ECSQ_CONFIG_COUNT ) ); + + /* ensure we are using target SNR configurations, disable target bits configurations for the moment */ + assert( ( ecsq_inst->config_index == 1 ) || ( ecsq_inst->config_index == 3 ) || ( ecsq_inst->config_index == 5 ) ); +#endif total_size = 0.0f; segment_count = ( N + ECSQ_SEGMENT_SIZE - 1 ) / ECSQ_SEGMENT_SIZE; @@ -639,6 +703,10 @@ static int32_t ECSQ_encode_raw( { nonzero = seg_length - saved_seg_count0[segment]; +#ifdef DEBUGGING + assert( ECSQ_NONZERO_MAX == 3 ); + assert( nonzero <= ECSQ_NONZERO_MAX ); +#endif arith_encode_bits( ecsq_inst, nonzero, 2 ); /* log_base2(ECSQ_NONZERO_MAX + 1) == 2 */ @@ -650,12 +718,21 @@ static int32_t ECSQ_encode_raw( val = input[i]; sym = (int16_t) abs( val ); +#ifdef DEBUGGING + assert( sym <= 1 ); +#endif if ( left1 == 0 ) { +#ifdef DEBUGGING + assert( sym == 0 ); +#endif } else if ( left0 == 0 ) { +#ifdef DEBUGGING + assert( sym == 1 ); +#endif } else { @@ -676,6 +753,18 @@ static int32_t ECSQ_encode_raw( } } +#ifdef DEBUGGING + DEBUG_LINE( 1 ) + { + static FILE *tolf = NULL; + if ( tolf == NULL ) + { + tolf = fopen( "tolerance.txt", "wt" ); + } + fprintf( tolf, "%8.3f %8.3f\n", ( ecsq_inst->bit_count_estimate - bit_count_estimate_initial ) / 1024.0, ( ecsq_inst->bit_count_estimate - bit_count_estimate_initial ) / 1024.0 - total_size ); + fflush( tolf ); + } +#endif return ecsq_inst->bit_count_estimate - bit_count_estimate_initial; } @@ -713,6 +802,10 @@ int32_t ECSQ_encode_target_SNR( int32_t max_bits_fixpt; float sum_squared, target_ratio, target_sum_squared_error; const float global_gain_step = powf( 10.0f, ECLVQ_INV_GLOBAL_GAIN_FACTOR ); +#ifdef DEBUGGING + int16_t j; + assert( N > 0 ); +#endif max_bits_fixpt = max_bits * 1024; /* max_bits_fixpt is in 22Q10 fixed-point representation */ @@ -769,6 +862,10 @@ int32_t ECSQ_encode_target_SNR( ECSQ_quantize_vector( input, global_gain, N, quantized_input ); test_size = ECSQ_encode_raw( ecsq_inst, quantized_input, N ); +#ifdef DEBUGGING + DEBUG_LINE( 1 ) + printf( "global_gain_index[0] %3d global_gain %9.3f test_size %9d max_bits %9d\n", global_gain_index, global_gain, test_size, max_bits_fixpt ); +#endif ++iteration; while ( ( test_size > max_bits_fixpt ) && ( iteration < ECSQ_MAX_BITS_ITERATIONS ) ) @@ -783,12 +880,20 @@ int32_t ECSQ_encode_target_SNR( ECSQ_quantize_vector( input, global_gain, N, quantized_input ); test_size = ECSQ_encode_raw( ecsq_inst, quantized_input, N ); +#ifdef DEBUGGING + DEBUG_LINE( 1 ) + printf( "global_gain_index[%d] %3d global_gain %9.3f test_size %9d max_bits %9d\n", iteration, global_gain_index, global_gain, test_size, max_bits_fixpt ); +#endif ++iteration; } if ( test_size > max_bits_fixpt ) { +#ifdef DEBUGGING + DEBUG_LINE( 1 ) + printf( "test_size %9d still larger than max_bits %9d, incrementing global_gain_index\n", test_size, max_bits_fixpt ); +#endif /* further increase the quantization step with the smallest increment for global_gain_index */ global_gain_index = (int16_t) min( global_gain_index + 1, 126 ); } @@ -821,6 +926,26 @@ int32_t ECSQ_encode_target_SNR( global_gain_index = ECSQ_quantize_gain( global_gain ); *global_gain_index_output = global_gain_index; +#ifdef DEBUGGING + DEBUG_LINE( 1 ) + { + float actual_sum_squared_error; + float delta_global_gain_index; + actual_sum_squared_error = 0.0f; + + /* compute the actual sum squared quantization error */ + global_gain = ECSQ_dequantize_gain( global_gain_index ); + for ( j = 0; j < N; ++j ) + { + float error; + error = input[j] - (float) quantized_input[j] * global_gain; + + actual_sum_squared_error += error * error; + } + delta_global_gain_index = (float) ( log( target_sum_squared_error / actual_sum_squared_error ) / ( 2.0f * log( global_gain_step ) ) ); + printf( "global_gain_index %3d global_gain %9.3f target_SSE %13.6e actual_SSE %13.6e delta_global_gain_index %9.3f\n", global_gain_index, global_gain, target_sum_squared_error, actual_sum_squared_error, delta_global_gain_index ); + } +#endif if ( output != NULL ) { diff --git a/lib_enc/ivas_stereo_ica_enc.c b/lib_enc/ivas_stereo_ica_enc.c index 4d698dfde..4cdd1c2fc 100644 --- a/lib_enc/ivas_stereo_ica_enc.c +++ b/lib_enc/ivas_stereo_ica_enc.c @@ -38,6 +38,9 @@ #include "ivas_cnst.h" #include "prot.h" #include "ivas_prot.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" #include "rom_com.h" #include "ivas_rom_com.h" @@ -928,6 +931,9 @@ void stereo_tca_enc( hStereoTCA->corrStatsSmoothFac = 0.7f; estDownmixGain( hStereoTCA, ptrChanL, ptrChanR, 0, input_frame, hCPE->element_mode, NULL, 0 ); hStereoTCA->prevTargetGain = hStereoTCA->targetGain; +#ifdef DEBUG_MODE_INFO + hStereoTCA->indx_ica_NCShift = 0; +#endif /* back up the L/R missing target */ mvr2r( bufChanL + input_frame, hStereoTCA->memChanL, lMemRecalc + lMemRecalc_SCh ); @@ -1121,6 +1127,13 @@ void stereo_tca_enc( tempS = ( currentNCShift >> 1 ); if ( abs( currentNCShift - prevNCShift ) <= min( N_MAX_SHIFT_CHANGE, N_MAX_SHIFT_CHANGE * input_Fs / 32000.0f ) ) { +#ifdef DEBUGGING + /* Max sample looked in INTERP1 should lie within the bounds of input_frame and memory populated */ + assert( ( ( abs( currentNCShift - prevNCShift ) + 1 ) + SINC_ORDER1 / INTERP_FACTOR1 ) + L_shift_adapt - tempS < input_frame ); + assert( ( ( abs( currentNCShift - prevNCShift ) + 1 ) + SINC_ORDER1 / INTERP_FACTOR1 + tempS ) < L_NCSHIFTMAX ); + assert( tempS + currentNCShift <= lMemRecalc ); + assert( input_frame - ( min( N_MAX_SHIFT_CHANGE, ( N_MAX_SHIFT_CHANGE * input_Fs ) / 32000 ) + 1 + SINC_ORDER1 / INTERP_FACTOR1 ) - ( prevNCShift >> 1 ) >= L_shift_adapt - tempS ); +#endif adjustTargetSignal( ( target - tempS ), prevNCShift, currentNCShift, L_shift_adapt, 0 ); } else diff --git a/lib_enc/ivas_stereo_icbwe_enc.c b/lib_enc/ivas_stereo_icbwe_enc.c index d4d70a344..e7b40e3ba 100644 --- a/lib_enc/ivas_stereo_icbwe_enc.c +++ b/lib_enc/ivas_stereo_icbwe_enc.c @@ -40,6 +40,9 @@ #include "wmc_auto.h" #include "rom_com.h" #include "ivas_rom_com.h" +#ifdef DEBUGGING +#include "debug.h" +#endif /*-------------------------------------------------------------------* * ic_bwe_enc_reset() diff --git a/lib_enc/ivas_stereo_mdct_core_enc.c b/lib_enc/ivas_stereo_mdct_core_enc.c index 579438a3f..d74f21d8e 100644 --- a/lib_enc/ivas_stereo_mdct_core_enc.c +++ b/lib_enc/ivas_stereo_mdct_core_enc.c @@ -38,6 +38,9 @@ #include "prot.h" #include "ivas_prot.h" #include "rom_com.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" /*-------------------------------------------------------------------* @@ -186,7 +189,14 @@ void stereo_mdct_core_enc( if ( hCPE->hCoreCoder[0]->igf ) { +#ifdef DEBUGGING + int16_t orig_mdct_stereo_mode_cmdl = hCPE->hStereoMdct->mdct_stereo_mode_cmdl; + hCPE->hStereoMdct->mdct_stereo_mode_cmdl = SMDCT_MS_DECISION; +#endif initMdctStereoEncData( hCPE->hStereoMdct, STEREO_FORMAT, IVAS_CPE_MDCT, hCPE->element_brate, hCPE->hCoreCoder[0]->bwidth, hCPE->hCoreCoder[0]->igf, hCPE->hCoreCoder[0]->hIGFEnc->igfData.igfInfo.grid, 0 ); +#ifdef DEBUGGING + hCPE->hStereoMdct->mdct_stereo_mode_cmdl = orig_mdct_stereo_mode_cmdl; +#endif stereo_mdct_init_igf_start_band( &( hCPE->hStereoMdct->stbParamsTCX20 ), 1.0f, hCPE->hCoreCoder[0]->bwidth, hCPE->element_brate ); stereo_mdct_init_igf_start_band( &( hCPE->hStereoMdct->stbParamsTCX10 ), 0.5f, hCPE->hCoreCoder[0]->bwidth, hCPE->element_brate ); @@ -305,6 +315,10 @@ void stereo_mdct_core_enc( st = sts[ch]; nSubframes = ( st->hTcxEnc->tcxMode == TCX_20 ) ? 1 : NB_DIV; L_subframeTCX = st->hTcxEnc->L_frameTCX / nSubframes; +#ifdef DEBUG_MODE_MDCT + dbgwrite( powerSpec[ch], sizeof( float ), 640, 1, "./res/powerSpec" ); + +#endif if ( st->last_core == ACELP_CORE ) { L_subframeTCX += L_subframeTCX / 4; @@ -384,8 +398,15 @@ void stereo_mdct_core_enc( /*write IGF data to bitstream*/ for ( ch = 0; ch < CPE_CHANNELS; ch++ ) { +#ifdef DEBUG_PLOT_BITS + int16_t tmp = hBstr->nb_bits_tot; +#endif st = sts[ch]; enc_prm_igf_mdct( st, hBstr ); +#ifdef DEBUG_PLOT_BITS + tmp = hBstr->nb_bits_tot - tmp; + dbgwrite( &tmp, sizeof( int16_t ), 1, 1, "./res/bits_IGF" ); +#endif } } @@ -416,6 +437,9 @@ void stereo_mdct_core_enc( nAvailBits -= SMDCT_NBBITS_SPLIT_RATIO; splitAvailableBits( nAvailBits, hStereoMdct->split_ratio, hStereoMdct->isSBAStereoMode, &sts[0]->bits_frame_channel, &sts[1]->bits_frame_channel ); +#ifdef DEBUG_MODE_MDCT + dbgwrite( &nAvailBits, sizeof( int16_t ), 1, 1, "./res/nAvailBits" ); +#endif sts[0]->bits_frame_channel += sts[0]->core * SMDCT_MINIMUM_ARITH_BITS; sts[1]->bits_frame_channel += sts[1]->core * SMDCT_MINIMUM_ARITH_BITS; @@ -430,6 +454,13 @@ void stereo_mdct_core_enc( push_next_indice( hBstr, hStereoMdct->split_ratio, SMDCT_NBBITS_SPLIT_RATIO ); +#ifdef DEBUG_MODE_MDCT + dbgwrite( &hStereoMdct->split_ratio, sizeof( int16_t ), 1, 1, "./res/split_ratio" ); + for ( ch = 0; ch < CPE_CHANNELS; ch++ ) + { + dbgwrite( &sts[ch]->bits_frame_channel, sizeof( int16_t ), 1, 1, "./res/bit_frame_channel" ); + } +#endif ivas_mdct_quant_coder( hCPE, tnsBits, tnsSize, p_param, 0 ); diff --git a/lib_enc/ivas_stereo_mdct_stereo_enc.c b/lib_enc/ivas_stereo_mdct_stereo_enc.c index 78d950c74..38e537713 100644 --- a/lib_enc/ivas_stereo_mdct_stereo_enc.c +++ b/lib_enc/ivas_stereo_mdct_stereo_enc.c @@ -41,6 +41,9 @@ #include "ivas_rom_enc.h" #include "wmc_auto.h" #include "stat_enc.h" +#ifdef DEBUG_PLOT +#include "deb_out.h" +#endif /*-------------------------------------------------------------------* @@ -210,6 +213,20 @@ void stereo_coder_tcx( nonQNrgRatio[k] = max( 0.5f / SMDCT_ILD_RANGE, min( ( SMDCT_ILD_RANGE - 0.5f ) / SMDCT_ILD_RANGE, nonQNrgRatio[k] ) ); nonQNrgRatio[k] = 1.0f / nonQNrgRatio[k] - 1.0f; } +#ifdef DEBUG_MODE_MDCT + { + float tmp; + for ( k = 0; k < 2; k++ ) + { + tmp = GetChannelEnergyRatio( sts, k, k, 1 ); + if ( nSubframes == 1 && k == 1 ) + { + tmp = 0; + } + dbgwrite( &tmp, sizeof( float ), 1, 1, "./res/ild" ); + } + } +#endif } else { @@ -219,6 +236,20 @@ void stereo_coder_tcx( nrgRatio[0] = nrgRatio[1] = (float) SMDCT_ILD_RANGE / hStereoMdct->global_ild[0] - 1; /* nrgRatio = nrg[1]/nrg[0] */ nonQNrgRatio[0] = nonQNrgRatio[1] = max( 0.5f / SMDCT_ILD_RANGE, min( ( SMDCT_ILD_RANGE - 0.5f ) / SMDCT_ILD_RANGE, nonQNrgRatio[0] ) ); nonQNrgRatio[0] = nonQNrgRatio[1] = 1.0f / nonQNrgRatio[0] - 1.0f; +#ifdef DEBUG_MODE_MDCT + { + float tmp; + for ( k = 0; k < 2; k++ ) + { + tmp = GetChannelEnergyRatio( sts, 0, nSubframes - 1, 1 ); + if ( nSubframes == 1 && k == 1 ) + { + tmp = 0; + } + dbgwrite( &tmp, sizeof( float ), 1, 1, "./res/ild" ); + } + } +#endif } for ( k = 0; k < nSubframes; k++ ) @@ -243,22 +274,78 @@ void stereo_coder_tcx( } if ( +#ifdef DEBUG_FORCE_MDCT_STEREO_MODE + hStereoMdct->fDualMono || +#endif ( sts[0]->hTcxEnc->transform_type[0] != sts[1]->hTcxEnc->transform_type[0] ) || ( sts[0]->hTcxEnc->transform_type[1] != sts[1]->hTcxEnc->transform_type[1] ) || ( sts[0]->last_core != sts[1]->last_core && ( sts[0]->last_core == ACELP_CORE || sts[1]->last_core == ACELP_CORE ) ) || sts[0]->last_core == ACELP_CORE || sts[1]->last_core == ACELP_CORE ) { hStereoMdct->mdct_stereo_mode[0] = SMDCT_DUAL_MONO; hStereoMdct->mdct_stereo_mode[1] = SMDCT_DUAL_MONO; +#ifdef DEBUG_MODE_MDCT + for ( k = 0; k < 2; k++ ) + { + nAvailBitsMS[k] = -1; + dbgwrite( &nAvailBitsMS[k], sizeof( int16_t ), 1, 1, "./res/nAvailBitsMS" ); + } +#endif if ( sts[0]->igf ) { hStereoMdct->IGFStereoMode[0] = SMDCT_DUAL_MONO; hStereoMdct->IGFStereoMode[1] = SMDCT_DUAL_MONO; } +#ifdef DEBUG_MODE_MDCT + /* MDCT stereo data */ + { + float Em[2]; + int16_t ch; + getChannelEnergies( sts, Em, 2 ); + dbgwrite( Em, sizeof( float ), 2, 1, "./res/Ech" ); + for ( k = 0; k < 2; k++ ) + { + dbgwrite( &hStereoMdct->global_ild[k], sizeof( int16_t ), 1, 1, "./res/ild_q" ); + dbgwrite( &hStereoMdct->mdct_stereo_mode[k], sizeof( int16_t ), 1, 1, "./res/stereo_mode" ); + dbgwrite( &hStereoMdct->IGFStereoMode[k], sizeof( int16_t ), 1, 1, "./res/stereo_mode_ifg" ); + dbgwrite( ms_mask[k], sizeof( int16_t ), 70, 1, "./res/ms_mask" ); + } + for ( ch = 0; ch < CPE_CHANNELS; ch++ ) + { + for ( k = 0; k < 2; k++ ) + { + dbgwrite( sts[ch]->hTcxEnc->spectrum[k], sizeof( float ), 640, 1, "./res/MDCT_spec_after_stereo" ); + dbgwrite( mdst_spectrum[ch][k], sizeof( float ), 640, 1, "./res/MDST_spec_after_stereo" ); + } + } + } +#endif hStereoMdct->sw_uncorr = 1; pop_wmops(); return; } +#ifdef DEBUG_FORCE_MDCT_STEREO_MODE + else if ( hStereoMdct->fMSstereo ) + { + hStereoMdct->mdct_stereo_mode[0] = SMDCT_MS_FULL; + hStereoMdct->mdct_stereo_mode[1] = SMDCT_MS_FULL; + if ( sts[0]->igf ) + { + hStereoMdct->IGFStereoMode[0] = SMDCT_MS_FULL; + hStereoMdct->IGFStereoMode[1] = SMDCT_MS_FULL; + } + for ( k = 0; k < nSubframes; k++ ) + { + convertToMS( L_frameTCX, sts[0]->hTcxEnc->spectrum[k], sts[1]->hTcxEnc->spectrum[k], SQRT2_OVER_2 ); + + /* Make sure that the MDST is processed in the correct way also */ + set_s( &ms_mask[k][0], 1, MAX_SFB ); + } + + pop_wmops(); + return; + } +#endif else /* decide based on signal */ { for ( k = 0; k < nSubframes; k++ ) @@ -351,6 +438,12 @@ void stereo_coder_tcx( } } /* for k */ +#ifdef DEBUG_MODE_MDCT + for ( k = 0; k < 2; k++ ) + { + dbgwrite( &nAvailBitsMS[k], sizeof( int16_t ), 1, 1, "./res/nAvailBitsMS" ); + } +#endif } /* for bitrate switching determine correlation depending on m/s decision */ { @@ -375,6 +468,30 @@ void stereo_coder_tcx( pop_wmops(); +#ifdef DEBUG_MODE_MDCT + /* MDCT stereo data */ + { + float Em[2]; + int16_t ch; + getChannelEnergies( sts, Em, 2 ); + dbgwrite( Em, sizeof( float ), 2, 1, "./res/Ech" ); + for ( k = 0; k < 2; k++ ) + { + dbgwrite( &hStereoMdct->global_ild[k], sizeof( int16_t ), 1, 1, "./res/ild_q" ); + dbgwrite( &hStereoMdct->mdct_stereo_mode[k], sizeof( int16_t ), 1, 1, "./res/stereo_mode" ); + dbgwrite( &hStereoMdct->IGFStereoMode[k], sizeof( int16_t ), 1, 1, "./res/stereo_mode_ifg" ); + dbgwrite( ms_mask[k], sizeof( int16_t ), 70, 1, "./res/ms_mask" ); + } + for ( ch = 0; ch < CPE_CHANNELS; ch++ ) + { + for ( k = 0; k < 2; k++ ) + { + dbgwrite( sts[ch]->hTcxEnc->spectrum[k], sizeof( float ), 640, 1, "./res/MDCT_spec_after_stereo" ); + dbgwrite( mdst_spectrum[ch][k], sizeof( float ), 640, 1, "./res/MDST_spec_after_stereo" ); + } + } + } +#endif return; } @@ -954,6 +1071,12 @@ static void MsStereoDecision( context_update( ctxR, ctxS, endline ); bitsBW += bitsL + bitsR; } +#ifdef DEBUG_MODE_MDCT + dbgwrite( &bitsL, sizeof( int16_t ), 1, 1, "./res/bitsL" ); + dbgwrite( &bitsR, sizeof( int16_t ), 1, 1, "./res/bitsR" ); + dbgwrite( &bitsM, sizeof( int16_t ), 1, 1, "./res/bitsM" ); + dbgwrite( &bitsS, sizeof( int16_t ), 1, 1, "./res/bitsS" ); +#endif } bitsBW += sfbParam->nBandsStereoCore; /* Signaling bits */ @@ -1022,6 +1145,20 @@ void initMdctStereoEncData( set_s( hStereoMdct->IGFStereoMode, -1, 2 ); +#ifdef DEBUG_FORCE_MDCT_STEREO_MODE + /*set all other members to defined states */ + hStereoMdct->fDualMono = 0; + hStereoMdct->fMSstereo = 0; + + if ( hStereoMdct->mdct_stereo_mode_cmdl == SMDCT_FORCE_LR ) + { + hStereoMdct->fDualMono = 1; + } + else if ( hStereoMdct->mdct_stereo_mode_cmdl == SMDCT_FORCE_MS ) + { + hStereoMdct->fMSstereo = 1; + } +#endif hStereoMdct->split_ratio = SMDCT_EQUAL_RATIO_RANGE; set_s( hStereoMdct->global_ild, SMDCT_ILD_RANGE >> 1, 2 ); diff --git a/lib_enc/ivas_stereo_switching_enc.c b/lib_enc/ivas_stereo_switching_enc.c index 5b173936c..fca3c7785 100644 --- a/lib_enc/ivas_stereo_switching_enc.c +++ b/lib_enc/ivas_stereo_switching_enc.c @@ -39,6 +39,9 @@ #include "ivas_rom_com.h" #include "assert.h" #include "wmc_auto.h" +#ifdef DEBUGGING +#include "debug.h" +#endif /*-------------------------------------------------------------------* * Function allocate_CoreCoder_enc() @@ -531,6 +534,9 @@ ivas_error stereo_memory_enc( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for MDCT Stereo \n" ) ); } +#ifdef DEBUGGING + hCPE->hStereoMdct->mdct_stereo_mode_cmdl = SMDCT_MS_DECISION; +#endif initMdctStereoEncData( hCPE->hStereoMdct, ivas_format, hCPE->element_mode, hCPE->element_brate, hCPE->hCoreCoder[0]->max_bwidth, 0, NULL, 1 ); hCPE->hStereoMdct->isSBAStereoMode = ( ivas_format == SBA_FORMAT && nchan_transport == 2 ); diff --git a/lib_enc/ivas_stereo_td_analysis.c b/lib_enc/ivas_stereo_td_analysis.c index 01f8a992c..fc318ce6b 100644 --- a/lib_enc/ivas_stereo_td_analysis.c +++ b/lib_enc/ivas_stereo_td_analysis.c @@ -40,6 +40,9 @@ #include "ivas_rom_com.h" #include "ivas_cnst.h" #include "rom_enc.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" @@ -532,6 +535,11 @@ int16_t stereo_tdm_ener_analysis( hCPE->hStereoClassif->ratio_L = ratio_L; +#ifdef DEBUG_MODE_TD + dbgwrite( &ratio_L, 4, 1, 320, "res/ratio_L" ); + dbgwrite( &hStereoTD->prev_fr_LRTD_TD_dec, 2, 1, 320, "res/prev_fr_LRTD_TD_dec" ); + dbgwrite( &hStereoTD->tdm_inst_ratio_idx, 2, 1, 320, "res/inst_ratio_L" ); +#endif return ( idx ); } diff --git a/lib_enc/ivas_stereo_td_enc.c b/lib_enc/ivas_stereo_td_enc.c index 7a72d612e..64446f3e5 100644 --- a/lib_enc/ivas_stereo_td_enc.c +++ b/lib_enc/ivas_stereo_td_enc.c @@ -32,6 +32,10 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#include "assert.h" +#endif #include "cnst.h" #include "rom_com.h" #include "prot.h" @@ -172,6 +176,9 @@ ivas_error stereo_set_tdm( hCPE->hStereoTD->tdm_LRTD_flag = hCPE->hStereoTD->prev_fr_LRTD_TD_dec; } +#ifdef DEBUG_MODE_INFO + dbgwrite( &hCPE->hStereoTD->tdm_LRTD_flag, 2, 1, (int16_t) ( hCPE->hCoreCoder[0]->input_Fs / FRAMES_PER_SEC ), "res/tdm_LRTD_flag" ); +#endif /* normal TD / LRTD switching */ if ( hCPE->hStereoTD->tdm_LRTD_flag == 0 ) @@ -269,6 +276,24 @@ ivas_error stereo_set_tdm( } else { +#ifdef DEBUG_MODE_INFO + { + int16_t tmp = -2; + dbgwrite( &tmp, 2, 1, (int16_t) ( hCPE->hCoreCoder[0]->input_Fs / FRAMES_PER_SEC ), "res/tdm_LRTD_flag" ); + } +#endif +#ifdef DEBUG_MODE_TD + { + float ftmp = -0.0; + int16_t tmp = -2; + dbgwrite( &tmp, 2, 1, 320, "res/prev_fr_LRTD_TD_dec" ); + dbgwrite( &tmp, 2, 1, 320, "res/inst_ratio_L" ); + dbgwrite( &ftmp, 4, 1, 320, "res/ratio_L" ); + dbgwrite( &tmp, 2, 1, 320, "res/tdm_low_rate_mode" ); + // dbgwrite( &tmp, 2, 1, 320, "res/tdm_lp_reuse_flag" ); + // dbgwrite( &tmp, 2, 1, 320, "res/mod_ct.enx" ); + } +#endif hCPE->hCoreCoder[0]->tdm_LRTD_flag = 0; hCPE->hCoreCoder[1]->tdm_LRTD_flag = 0; } @@ -521,6 +546,11 @@ void tdm_configure_enc( push_indice( &hStereoTD->tdm_hBstr_tmp, IND_STEREO_GD, hCPE->hStereoTCA->indx_ica_gD, STEREO_BITS_TCA_GD ); } +#ifdef DEBUG_MODE_TD + dbgwrite( &hStereoTD->tdm_low_rate_mode, 2, 1, 320, "res/tdm_low_rate_mode_c" ); + dbgwrite( &hStereoTD->tdm_lp_reuse_flag, 2, 1, 320, "res/tdm_lp_reuse_flag_c" ); + dbgwrite( &mod_ct, 2, 1, 320, "res/mod_ct.enc" ); +#endif /*----------------------------------------------------------------* * Updates @@ -574,6 +604,12 @@ ivas_error signaling_enc_secondary( { ind -= 2; } +#ifdef DEBUGGING + else if ( st->coder_type == TRANSITION || st->coder_type == VOICED ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Coder type not supported in secondary channel\n" ); + } +#endif ind <<= 1; ind += tdm_SM_or_LRTD_Pri; /* addition of the channel combination scheme flag value or the LRTD primary channel*/ @@ -798,6 +834,9 @@ void stereo_tdm_prep_dwnmx( sw_pos = 22 * i; enr_len = 6 * i; +#ifdef DEBUG_MODE_TD + assert( sw_pos > 15 ); +#endif if ( hCPE->element_mode == IVAS_CPE_TD ) { if ( hCPE->hStereoTD->flag_skip_DMX == 1 ) /* hStereoTD is defined only if element mode == TD */ diff --git a/lib_enc/ivas_tcx_core_enc.c b/lib_enc/ivas_tcx_core_enc.c index ef239607e..7d8394f5a 100644 --- a/lib_enc/ivas_tcx_core_enc.c +++ b/lib_enc/ivas_tcx_core_enc.c @@ -33,6 +33,9 @@ #include #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "prot.h" @@ -174,6 +177,11 @@ void stereo_tcx_core_enc( /* bitstream */ BSTR_ENC_HANDLE hBstr = st->hBstr; +#ifdef DEBUG_MODE_TCX + static FILE *pF = NULL; + if ( pF == NULL ) + pF = fopen( "./res/stereo_tcx_enc_ind.txt", "w" ); +#endif push_wmops( "stereo_tcx_core_enc" ); @@ -261,6 +269,10 @@ void stereo_tcx_core_enc( n_subframes = 1; } +#ifdef DEBUG_MODE_TCX + fprintf( pF, "== stereo Chan %d - Nominal Bits %d - Allocated Bits %d ==\n", st->idchan, st->bits_frame_nominal, (int16_t) ( st->total_brate / FRAMES_PER_SEC ) ); + fprintf( pF, "stereo Common Header: %d bits\n", hBstr->nb_bits_tot ); +#endif nbits_start = hBstr->nb_bits_tot; /*--------------------------------------------------------------------------------* @@ -281,6 +293,9 @@ void stereo_tcx_core_enc( } assert( nbits_header == ( hBstr->nb_bits_tot - nbits_start ) ); +#ifdef DEBUG_MODE_TCX + fprintf( pF, "\t TCX Header: %d bits: %d %d %d %d\n", hBstr->nb_bits_tot - nbits_start, st->tcxonly, st->core, st->tcxonly ? st->clas : st->hTcxCfg->coder_type, st->hTcxCfg->tcx_curr_overlap_mode ); +#endif /*--------------------------------------------------------------* * Core Signal Analysis: MDCT, TNS, LPC analysis @@ -388,6 +403,9 @@ void stereo_tcx_core_enc( writeLPCparam( st, hBstr, param_lpc, bits_param_lpc, no_param_lpc, &total_nbbits ); assert( total_nbbits == ( nbits_lpc[0] + nbits_lpc[1] ) ); +#ifdef DEBUG_MODE_TCX + fprintf( pF, "\t TCX LPC: %d bits\n", total_nbbits ); +#endif /*--------------------------------------------------------------* * Run TCX10/20 Core @@ -486,6 +504,29 @@ void stereo_tcx_core_enc( } } +#ifdef DEBUG_MODE_TCX + { + int16_t tmp[L_FRAME48k]; + + for ( i = 0; i < st->L_frame; i++ ) + { + tmp[i] = (int16_t) ( st->synth[i] + 0.5f ); + } + dbgwrite( tmp, sizeof( int16_t ), st->L_frame, 1, "./res/stereo_tcx_enc_synth.pcm" ); + + for ( i = 0; i < st->L_frame; i++ ) + { + tmp[i] = (int16_t) ( st->speech_enc[i] + 0.5f ); + } + dbgwrite( tmp, sizeof( int16_t ), st->L_frame, 1, "./res/stereo_tcx_enc_inLB.pcm" ); + + for ( i = 0; i < hTcxEnc->L_frameTCX; i++ ) + { + tmp[i] = (int16_t) ( st->hTcxEnc->speech_TCX[i] + 0.5f ); + } + dbgwrite( tmp, sizeof( int16_t ), hTcxEnc->L_frameTCX, 1, "./res/stereo_tcx_enc_inFB.pcm" ); + } +#endif /*--------------------------------------------------------------------------------* * Encode TCX20/10 parameters @@ -495,6 +536,16 @@ void stereo_tcx_core_enc( total_nbbits = hBstr->nb_bits_tot - nbits_start; +#ifdef DEBUG_MODE_TCX + { + static FILE *sP = NULL; + + if ( sP == NULL ) + sP = fopen( "./res/stereo_tcx_core_enc_swicthes.txt", "w" ); + + fprintf( sP, "frame:%d\t mdct_sw=%d\t rf_mode=%d tcxonly=%d\t tcxMode=%d\t core=%d\t, enableTcxLpc=%d\t igf=%d\t envWeighted=%d\t lpcQuantization=%d\t enablePlcWaveadjust=%d\t tcxltp=%d\t fIsTNSAllowed=%d\t tcx_lpc_shaped_ari=%d\t ctx_hm=%d\t \n", frame, st->mdct_sw, st->rf_mode, st->tcxonly, hTcxEnc->tcxMode, st->core, st->enableTcxLpc, st->igf, st->envWeighted, st->lpcQuantization, st->enablePlcWaveadjust, hTcxEnc->tcxltp, st->hTcxCfg->fIsTNSAllowed, hTcxEnc->tcx_lpc_shaped_ari, st->hTcxCfg->ctx_hm ); + } +#endif if ( param_core[1 + NOISE_FILL_RANGES] != 0 ) { @@ -823,6 +874,18 @@ int16_t ivas_acelp_tcx20_switching( smc_dec_ol = 2; } +#ifdef DEBUGGING + if ( st->force == FORCE_SPEECH ) + { + /* enforce ACELP */ + smc_dec_ol = 0; + } + else if ( st->force == FORCE_MUSIC ) + { + /* enforce TCX */ + smc_dec_ol = 2; + } +#endif st->prevTempFlatness = currFlatness; diff --git a/lib_enc/ivas_td_low_rate_enc.c b/lib_enc/ivas_td_low_rate_enc.c index 40d10e485..de75faf2f 100644 --- a/lib_enc/ivas_td_low_rate_enc.c +++ b/lib_enc/ivas_td_low_rate_enc.c @@ -32,6 +32,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "stat_enc.h" #include "rom_com.h" diff --git a/lib_enc/lead_indexing.c b/lib_enc/lead_indexing.c index 31116dfd1..6208d66eb 100644 --- a/lib_enc/lead_indexing.c +++ b/lib_enc/lead_indexing.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "rom_com.h" #include "prot.h" #include "wmc_auto.h" diff --git a/lib_enc/lib_enc.c b/lib_enc/lib_enc.c index 238de3ab1..62ea6dceb 100644 --- a/lib_enc/lib_enc.c +++ b/lib_enc/lib_enc.c @@ -37,6 +37,9 @@ #include #include #include +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" #include "options.h" @@ -49,6 +52,9 @@ struct IVAS_ENC Encoder_Struct *st_ivas; ENC_CORE_HANDLE hCoreCoder; bool isConfigured; +#ifdef DEBUGGING + bool cmd_stereo; +#endif bool switchingActive; /* flag for configuration changes during encoding - currently only used with mono */ int16_t Opt_RF_ON_loc; int16_t rf_fec_offset_loc; @@ -74,7 +80,13 @@ static ivas_error sanitizeBitrateISM( const ENCODER_CONFIG_HANDLE hEncoderConfig static void init_encoder_config( ENCODER_CONFIG_HANDLE hEncoderConfig ); static void resetIsmMetadataProvidedFlags( IVAS_ENC_HANDLE hIvasEnc ); static ivas_error bandwidthApiToInternal( const IVAS_ENC_BANDWIDTH maxBandwidth, int16_t *internalMaxBandwidth ); +#ifdef DEBUG_AGC_ENCODER_CMD_OPTION +static ivas_error agcAPIToInternal( const IVAS_ENC_AGC agcOption, int16_t *internalAGCOption ); +#endif static ivas_error fecIndicatorApiToInternal( const IVAS_ENC_FEC_INDICATOR fecIndicator, int16_t *fecIndicatorInternal ); +#ifdef DEBUGGING +static ivas_error forcedModeApiToInternal( IVAS_ENC_FORCED_MODE forcedMode, int16_t *forcedModeInternal ); +#endif /*---------------------------------------------------------------------* @@ -105,6 +117,9 @@ ivas_error IVAS_ENC_Open( ( *phIvasEnc )->hCoreCoder = NULL; ( *phIvasEnc )->isConfigured = false; +#ifdef DEBUGGING + ( *phIvasEnc )->cmd_stereo = false; +#endif ( *phIvasEnc )->switchingActive = false; ( *phIvasEnc )->maxBandwidthUser = false; resetIsmMetadataProvidedFlags( *phIvasEnc ); @@ -244,6 +259,10 @@ ivas_error IVAS_ENC_ConfigureForStereo( const IVAS_ENC_BANDWIDTH maxBandwidth, /* i : bandwidth limitation */ const IVAS_ENC_DTX_CONFIG dtxConfig, /* i : configuration of DTX, can by set to default by using IVAS_ENC_GetDefaultDtxConfig() */ const bool is_binaural /* i : flag indicating if input is binaural audio */ +#ifdef DEBUGGING + , + const IVAS_ENC_STEREO_MODE stereoMode /* i : forces a specific stereo coding mode */ +#endif ) { Encoder_Struct *st_ivas; @@ -262,6 +281,41 @@ ivas_error IVAS_ENC_ConfigureForStereo( hEncoderConfig->ivas_format = STEREO_FORMAT; hEncoderConfig->is_binaural = (int16_t) is_binaural; +#ifdef DEBUGGING + switch ( stereoMode ) + { + case IVAS_ENC_STEREO_MODE_UNIFIED: + hEncoderConfig->stereo_mode_cmdl = 1; /* set unified stereo by default */ + hEncoderConfig->element_mode_init = IVAS_CPE_DFT; + hIvasEnc->cmd_stereo = true; + break; + case IVAS_ENC_STEREO_MODE_DFT: + hEncoderConfig->element_mode_init = IVAS_CPE_DFT; + hEncoderConfig->stereo_mode_cmdl = IVAS_CPE_DFT; + break; + case IVAS_ENC_STEREO_MODE_TD: + hEncoderConfig->stereo_mode_cmdl = IVAS_CPE_TD; + hEncoderConfig->element_mode_init = IVAS_CPE_TD; + break; + case IVAS_ENC_STEREO_MODE_MDCT_DECISION: + hEncoderConfig->element_mode_init = IVAS_CPE_MDCT; + hEncoderConfig->mdct_stereo_mode_cmdl = SMDCT_MS_DECISION; + break; +#ifdef DEBUG_FORCE_MDCT_STEREO_MODE + case IVAS_ENC_STEREO_MODE_MDCT_FORCE_LR: + hEncoderConfig->element_mode_init = IVAS_CPE_MDCT; + hEncoderConfig->mdct_stereo_mode_cmdl = SMDCT_FORCE_LR; + break; + case IVAS_ENC_STEREO_MODE_MDCT_FORCE_MS: + hEncoderConfig->element_mode_init = IVAS_CPE_MDCT; + hEncoderConfig->mdct_stereo_mode_cmdl = SMDCT_FORCE_MS; + break; +#endif + default: + return IVAS_ERR_INVALID_STEREO_MODE; + break; + } +#endif /* DEBUGGING */ hIvasEnc->maxBandwidthUser = max_bwidth_user; @@ -430,7 +484,14 @@ ivas_error IVAS_ENC_ConfigureForAmbisonics( const IVAS_ENC_DTX_CONFIG dtxConfig, /* i : configuration of DTX, can by set to default by using IVAS_ENC_GetDefaultDtxConfig() */ const IVAS_ENC_SBA_ORDER order, /* i : order of the Ambisonics input */ const bool isPlanar, /* i : if true, input is treated as planar Ambisonics */ +#ifdef DEBUG_AGC_ENCODER_CMD_OPTION + const IVAS_ENC_AGC Opt_AGC_ON, /* i : AGC on/off/undefined flag */ +#endif const bool Opt_PCA_ON /* i : PCA option flag */ +#ifdef DEBUG_SBA_AUDIO_DUMP + , + int16_t *numTransportChannels +#endif ) { ENCODER_CONFIG_HANDLE hEncoderConfig; @@ -451,6 +512,12 @@ ivas_error IVAS_ENC_ConfigureForAmbisonics( /* Input in ACN/SN3D in all cases (3D and planar): get number of channels */ hEncoderConfig->nchan_inp = ivas_sba_get_nchan( hEncoderConfig->sba_order, 0 ); /*planar input arg. deliberately set to zero since input always in ACN/SN3D*/ +#ifdef DEBUG_AGC_ENCODER_CMD_OPTION + if ( ( error = agcAPIToInternal( Opt_AGC_ON, &( hEncoderConfig->Opt_AGC_ON ) ) ) != IVAS_ERR_OK ) + { + return error; + } +#endif hEncoderConfig->Opt_PCA_ON = (int16_t) Opt_PCA_ON; @@ -458,6 +525,9 @@ ivas_error IVAS_ENC_ConfigureForAmbisonics( error = configureEncoder( hIvasEnc, inputFs, bitrate, maxBandwidth, dtxConfig, IVAS_ENC_GetDefaultChannelAwareConfig() ); +#ifdef DEBUG_SBA_AUDIO_DUMP + *numTransportChannels = hIvasEnc->st_ivas->nchan_transport; +#endif return error; } @@ -549,6 +619,9 @@ ivas_error IVAS_ENC_ConfigureForMasa( break; case IVAS_ENC_MASA_2CH: hEncoderConfig->nchan_inp = 2; +#ifdef DEBUGGING + hEncoderConfig->stereo_mode_cmdl = 1; /* set unified stereo by default */ +#endif hEncoderConfig->element_mode_init = IVAS_CPE_DFT; /* initialization only, might be changed later based on element_brate */ break; default: @@ -753,11 +826,20 @@ static ivas_error configureEncoder( if ( hEncoderConfig->ivas_format == STEREO_FORMAT ) { +#ifdef DEBUGGING + if ( hIvasEnc->cmd_stereo ) +#endif { hEncoderConfig->element_mode_init = IVAS_CPE_DFT; +#ifdef DEBUGGING + hEncoderConfig->stereo_mode_cmdl = 1; +#endif if ( hEncoderConfig->ivas_total_brate >= MIN_BRATE_MDCT_STEREO ) { hEncoderConfig->element_mode_init = IVAS_CPE_MDCT; +#ifdef DEBUGGING + hEncoderConfig->stereo_mode_cmdl = 0; +#endif } } @@ -901,6 +983,12 @@ static ivas_error configureEncoder( return IVAS_ERROR( IVAS_ERR_DTX_NOT_SUPPORTED, "DTX is not supported in this IVAS format and element mode." ); } +#ifdef DEBUG_AGC_ENCODER_CMD_OPTION + if ( hEncoderConfig->Opt_AGC_ON == SBA_AGC_FORCE_ENABLE && !( hEncoderConfig->ivas_format == SBA_FORMAT ) ) + { + return IVAS_ERROR( IVAS_ERR_NOT_SUPPORTED_OPTION, "AGC supported in SBA format at bitrates >= 24.4 kbps only." ); + } +#endif if ( hEncoderConfig->Opt_PCA_ON && !( hEncoderConfig->ivas_format == SBA_FORMAT && hEncoderConfig->ivas_total_brate == PCA_BRATE && hEncoderConfig->sba_order == SBA_FOA_ORDER ) ) { @@ -969,7 +1057,11 @@ ivas_error IVAS_ENC_GetDelay( return IVAS_ERR_UNEXPECTED_NULL_POINTER; } +#ifdef SPLIT_REND_WITH_HEAD_ROT + *delay = NS2SA( hEncoderConfig->input_Fs, get_delay( ENC, hEncoderConfig->input_Fs, hEncoderConfig->ivas_format, NULL, IVAS_AUDIO_CONFIG_INVALID ) ); +#else *delay = NS2SA( hEncoderConfig->input_Fs, get_delay( ENC, hEncoderConfig->input_Fs, hEncoderConfig->ivas_format, NULL ) ); +#endif *delay *= hEncoderConfig->nchan_inp; @@ -1220,6 +1312,9 @@ ivas_error IVAS_ENC_EncodeFrameToSerial( if ( hEncoderConfig->ivas_format == MONO_FORMAT ) /* EVS mono */ { hCoreCoder->total_brate = hEncoderConfig->ivas_total_brate; /* needed in case of bitrate switching */ +#ifdef DEBUGGING + hCoreCoder->id_element = 0; +#endif if ( hEncoderConfig->stereo_dmx_evs == 1 ) { @@ -1358,6 +1453,41 @@ ivas_error IVAS_ENC_SetChannelAwareConfig( } +#ifdef DEBUGGING +/*---------------------------------------------------------------------* + * IVAS_ENC_SetForcedMode() + * + * + *---------------------------------------------------------------------*/ + +ivas_error IVAS_ENC_SetForcedMode( + IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ + const IVAS_ENC_FORCED_MODE forcedMode /* i : forced coding mode */ +) +{ + int16_t newForced; + ivas_error error; + + /* Do additional checks for user-facing function */ + if ( ( error = doCommonSetterChecks( hIvasEnc ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( ( error = forcedModeApiToInternal( forcedMode, &newForced ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( hIvasEnc->st_ivas->hEncoderConfig->force != newForced ) + { + hIvasEnc->st_ivas->hEncoderConfig->force = newForced; + hIvasEnc->switchingActive = true; + } + + return IVAS_ERR_OK; +} +#endif /* DEBUGGING */ /*---------------------------------------------------------------------* @@ -1479,6 +1609,24 @@ static ivas_error printConfigInfo_enc( } else if ( hEncoderConfig->ivas_format == STEREO_FORMAT ) { +#ifdef DEBUGGING + if ( hEncoderConfig->stereo_mode_cmdl == 1 ) + { + fprintf( stdout, "IVAS format: stereo - Unified stereo\n" ); + } + else if ( hEncoderConfig->element_mode_init == IVAS_CPE_DFT ) + { + fprintf( stdout, "IVAS format: stereo - DFT stereo\n" ); + } + else if ( hEncoderConfig->element_mode_init == IVAS_CPE_TD ) + { + fprintf( stdout, "IVAS format: stereo - TD stereo\n" ); + } + else if ( hEncoderConfig->element_mode_init == IVAS_CPE_MDCT ) + { + fprintf( stdout, "IVAS format: stereo - MDCT stereo\n" ); + } +#else if ( hEncoderConfig->element_mode_init != IVAS_CPE_MDCT ) { fprintf( stdout, "IVAS format: stereo - Unified stereo\n" ); @@ -1487,6 +1635,7 @@ static ivas_error printConfigInfo_enc( { fprintf( stdout, "IVAS format: stereo - MDCT stereo\n" ); } +#endif } else if ( hEncoderConfig->ivas_format == ISM_FORMAT ) { @@ -1507,6 +1656,23 @@ static ivas_error printConfigInfo_enc( fprintf( stdout, "- PCA configured with signal adaptive decision " ); } +#ifdef DEBUG_AGC_ENCODER_CMD_OPTION + switch ( hEncoderConfig->Opt_AGC_ON ) + { + case SBA_AGC_FORCE_ENABLE: + fprintf( stdout, "- AGC FORCED ON " ); + break; + case SBA_AGC_FORCE_DISABLE: + fprintf( stdout, "- AGC FORCED OFF " ); + break; + case SBA_AGC_DEFAULT: + fprintf( stdout, "- AGC default mode " ); + break; + default: + fprintf( stdout, "- AGC unknown " ); + break; + } +#endif fprintf( stdout, "\n" ); } else if ( hEncoderConfig->ivas_format == MASA_FORMAT ) @@ -2080,6 +2246,36 @@ static ivas_error bandwidthApiToInternal( return IVAS_ERR_OK; } +#ifdef DEBUG_AGC_ENCODER_CMD_OPTION +/*---------------------------------------------------------------------* + * agcAPIToInternal() + * + * + *---------------------------------------------------------------------*/ + +static ivas_error agcAPIToInternal( + const IVAS_ENC_AGC agcOption, + int16_t *internalAGCOption ) +{ + switch ( agcOption ) + { + case IVAS_ENC_AGC_ENABLED: + *internalAGCOption = SBA_AGC_FORCE_ENABLE; + break; + case IVAS_ENC_AGC_DISABLED: + *internalAGCOption = SBA_AGC_FORCE_DISABLE; + break; + case IVAS_ENC_AGC_UNDEFINED: + *internalAGCOption = SBA_AGC_DEFAULT; + break; + default: + return IVAS_ERR_INVALID_AGC; + break; + } + + return IVAS_ERR_OK; +} +#endif /*---------------------------------------------------------------------* @@ -2108,6 +2304,48 @@ static ivas_error fecIndicatorApiToInternal( return IVAS_ERR_OK; } +#ifdef DEBUGGING +/*---------------------------------------------------------------------* + * forcedModeApiToInternal() + * + * + *---------------------------------------------------------------------*/ + +static ivas_error forcedModeApiToInternal( + IVAS_ENC_FORCED_MODE forcedMode, + int16_t *forcedModeInternal ) +{ + switch ( forcedMode ) + { + case IVAS_ENC_FORCE_SPEECH: + *forcedModeInternal = FORCE_SPEECH; + break; + case IVAS_ENC_FORCE_MUSIC: + *forcedModeInternal = FORCE_MUSIC; + break; + case IVAS_ENC_FORCE_ACELP: + *forcedModeInternal = FORCE_ACELP; + break; + case IVAS_ENC_FORCE_GSC: + *forcedModeInternal = FORCE_GSC; + break; + case IVAS_ENC_FORCE_TCX: + *forcedModeInternal = FORCE_TCX; + break; + case IVAS_ENC_FORCE_HQ: + *forcedModeInternal = FORCE_HQ; + break; + case IVAS_ENC_FORCE_UNFORCED: + *forcedModeInternal = -1; + break; + default: + return IVAS_ERR_INVALID_FORCE_MODE; + break; + } + + return IVAS_ERR_OK; +} +#endif /*---------------------------------------------------------------------* @@ -2171,6 +2409,14 @@ static void init_encoder_config( hEncoderConfig->sba_order = 0; hEncoderConfig->sba_planar = 0; hEncoderConfig->ism_extended_metadata_flag = 0; +#ifdef DEBUGGING + hEncoderConfig->stereo_mode_cmdl = 0; + hEncoderConfig->force = -1; + hEncoderConfig->mdct_stereo_mode_cmdl = SMDCT_MS_DECISION; +#ifdef DEBUG_AGC_ENCODER_CMD_OPTION + hEncoderConfig->Opt_AGC_ON = SBA_AGC_DEFAULT; +#endif +#endif hEncoderConfig->Opt_PCA_ON = 0; return; diff --git a/lib_enc/lib_enc.h b/lib_enc/lib_enc.h index b57a1375a..13399ba0c 100644 --- a/lib_enc/lib_enc.h +++ b/lib_enc/lib_enc.h @@ -109,6 +109,39 @@ typedef enum _IVAS_ENC_COMBINED_FORMAT IVAS_ENC_COMBINED_UNDEFINED = 0xffff } IVAS_ENC_COMBINED_FORMAT; +#ifdef DEBUGGING +typedef enum _IVAS_ENC_STEREO_MODE +{ + IVAS_ENC_STEREO_MODE_UNIFIED, + IVAS_ENC_STEREO_MODE_DFT, + IVAS_ENC_STEREO_MODE_TD, + IVAS_ENC_STEREO_MODE_MDCT_DECISION, + IVAS_ENC_STEREO_MODE_MDCT_FORCE_LR, + IVAS_ENC_STEREO_MODE_MDCT_FORCE_MS, + IVAS_ENC_STEREO_MODE_UNDEFINED = 0xffff +} IVAS_ENC_STEREO_MODE; + +typedef enum _IVAS_ENC_FORCED_MODE +{ + IVAS_ENC_FORCE_SPEECH, + IVAS_ENC_FORCE_MUSIC, + IVAS_ENC_FORCE_ACELP, + IVAS_ENC_FORCE_GSC, + IVAS_ENC_FORCE_TCX, + IVAS_ENC_FORCE_HQ, + IVAS_ENC_FORCE_UNFORCED, + IVAS_ENC_FORCE_UNDEFINED = 0xffff +} IVAS_ENC_FORCED_MODE; + +#ifdef DEBUG_AGC_ENCODER_CMD_OPTION +typedef enum _IVAS_ENC_AGC +{ + IVAS_ENC_AGC_DISABLED = 0, + IVAS_ENC_AGC_ENABLED, + IVAS_ENC_AGC_UNDEFINED = 0xffff +} IVAS_ENC_AGC; +#endif +#endif /*---------------------------------------------------------------------* * Encoder structures @@ -150,6 +183,10 @@ ivas_error IVAS_ENC_ConfigureForStereo( const IVAS_ENC_BANDWIDTH maxBandwidth, /* i : bandwidth limitation */ const IVAS_ENC_DTX_CONFIG dtxConfig, /* i : configuration of DTX, can by set to default by using IVAS_ENC_GetDefaultDtxConfig() */ const bool is_binaural /* i : flag indicating if input is binaural audio */ +#ifdef DEBUGGING + , + const IVAS_ENC_STEREO_MODE stereoMode /* i : forces a specific stereo coding mode */ +#endif ); /*! r: error code */ @@ -198,7 +235,14 @@ ivas_error IVAS_ENC_ConfigureForAmbisonics( const IVAS_ENC_DTX_CONFIG dtxConfig, /* i : configuration of DTX, can by set to default by using IVAS_ENC_GetDefaultDtxConfig() */ const IVAS_ENC_SBA_ORDER order, /* i : order of the Ambisonics input */ const bool isPlanar, /* i : if true, input is treated as planar Ambisonics */ +#ifdef DEBUG_AGC_ENCODER_CMD_OPTION + const IVAS_ENC_AGC Opt_AGC_ON, /* i : AGC on/off/undefined flag */ +#endif const bool Opt_PCA_ON /* i : PCA option flag */ +#ifdef DEBUG_SBA_AUDIO_DUMP + , + int16_t *numTransportChannels +#endif ); /*! r: error code */ @@ -280,6 +324,13 @@ ivas_error IVAS_ENC_SetChannelAwareConfig( const IVAS_ENC_CHANNEL_AWARE_CONFIG rfConfig /* i : configuration of channel-aware mode */ ); +#ifdef DEBUGGING +/*! r: error code */ +ivas_error IVAS_ENC_SetForcedMode( + IVAS_ENC_HANDLE hIvasEnc, /* i/o: IVAS encoder handle */ + const IVAS_ENC_FORCED_MODE forcedMode /* i : forced coding mode */ +); +#endif /* Getter functions - retrieve information from an encoder through a handle */ diff --git a/lib_enc/long_enr.c b/lib_enc/long_enr.c index 6277129f8..488012b6b 100644 --- a/lib_enc/long_enr.c +++ b/lib_enc/long_enr.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "prot.h" #include "wmc_auto.h" diff --git a/lib_enc/lp_exc_e.c b/lib_enc/lp_exc_e.c index 07b1954f5..4fb81a9b7 100644 --- a/lib_enc/lp_exc_e.c +++ b/lib_enc/lp_exc_e.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "prot.h" diff --git a/lib_enc/lsf_enc.c b/lib_enc/lsf_enc.c index c32757972..61a81ffec 100644 --- a/lib_enc/lsf_enc.c +++ b/lib_enc/lsf_enc.c @@ -36,6 +36,10 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#include +#endif #include "cnst.h" #include "rom_enc.h" #include "rom_com.h" @@ -1142,6 +1146,9 @@ static float vq_lvq_lsf_enc( if ( pred_flag == 0 ) /* safety net*/ { cb = &Quantizers[CB_lsf[mode]]; +#ifdef DEBUGGING + assert( levels[stagesVQ] >= min_lat_bits_SN[mode] ); +#endif if ( mode < 6 ) /* for NB */ { mode_glb = offset_lvq_modes_SN[mode] + offset_in_lvq_mode_SN[mode][levels[stagesVQ] - min_lat_bits_SN[mode]]; @@ -1154,6 +1161,9 @@ static float vq_lvq_lsf_enc( else /* pred */ { cb = &Quantizers_p[CB_p_lsf[mode]]; +#ifdef DEBUGGING + assert( levels[stagesVQ] >= min_lat_bits_pred[mode] ); +#endif if ( ( mode < 6 ) || ( mode == 12 ) ) /* for NB or I 16k */ { mode_glb = offset_lvq_modes_pred[mode] + offset_in_lvq_mode_pred[mode][levels[stagesVQ] - min_lat_bits_pred[mode]]; diff --git a/lib_enc/lsf_msvq_ma_enc.c b/lib_enc/lsf_msvq_ma_enc.c index b825109dd..d75d57021 100644 --- a/lib_enc/lsf_msvq_ma_enc.c +++ b/lib_enc/lsf_msvq_ma_enc.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "ivas_prot.h" #include "prot.h" diff --git a/lib_enc/mdct_classifier.c b/lib_enc/mdct_classifier.c index 976c642a2..f26b12773 100644 --- a/lib_enc/mdct_classifier.c +++ b/lib_enc/mdct_classifier.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "prot.h" #include "wmc_auto.h" diff --git a/lib_enc/mdct_selector.c b/lib_enc/mdct_selector.c index ebe268fc7..45f3d3174 100644 --- a/lib_enc/mdct_selector.c +++ b/lib_enc/mdct_selector.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "rom_enc.h" diff --git a/lib_enc/multi_harm.c b/lib_enc/multi_harm.c index 18c354a97..c53371e28 100644 --- a/lib_enc/multi_harm.c +++ b/lib_enc/multi_harm.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "prot.h" diff --git a/lib_enc/nelp_enc.c b/lib_enc/nelp_enc.c index 1c065a517..a1ae3c20d 100644 --- a/lib_enc/nelp_enc.c +++ b/lib_enc/nelp_enc.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "prot.h" diff --git a/lib_enc/noise_adjust.c b/lib_enc/noise_adjust.c index 7b059f5c5..0ba9bd453 100644 --- a/lib_enc/noise_adjust.c +++ b/lib_enc/noise_adjust.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "rom_com.h" diff --git a/lib_enc/normalizecoefs.c b/lib_enc/normalizecoefs.c index 90b7c4a54..bd24f2cd2 100644 --- a/lib_enc/normalizecoefs.c +++ b/lib_enc/normalizecoefs.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "rom_com.h" #include "prot.h" #include "wmc_auto.h" diff --git a/lib_enc/peak_vq_enc.c b/lib_enc/peak_vq_enc.c index 27943ed61..efdd0b14a 100644 --- a/lib_enc/peak_vq_enc.c +++ b/lib_enc/peak_vq_enc.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "prot.h" @@ -63,6 +66,9 @@ static int16_t sparse_code_pos( const int16_t *inp, const int16_t length, int16_ int16_t peak_vq_enc( BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ const int16_t bwidth, /* i : audio bandwidth */ +#ifdef DEBUGGING + const int16_t idchan, /* i : channel ID */ +#endif const float *coefs, /* i : Input coefficient vector */ float *coefs_out, /* o : Quantized output vector */ const int32_t core_brate, /* i : Core bitrate */ @@ -306,6 +312,30 @@ int16_t peak_vq_enc( k_sort[i] = i; } +#ifdef DEBUGGING + /* SNR measurement */ + for ( i = 0; i < pvq_bands; i++ ) + { + float diff[120]; + + if ( npulses[i] > 0 ) + { + for ( j = 0; j < hvq_band_width[i]; j++ ) + { + diff[j] = pvq_vector[hvq_band_start[i] + j] - gopt[i] * coefs_pvq[hvq_band_start[i] + j]; + } + + if ( idchan == 0 ) + { + snr( &pvq_vector[hvq_band_start[i]], diff, hvq_band_width[i], "HVQ_PVQ_output" ); + } + else + { + snr( &pvq_vector[hvq_band_start[i]], diff, hvq_band_width[i], "HVQ_PVQ_output_chan2" ); + } + } + } +#endif fine_gain_pred( hvq_band_start, hvq_band_end, hvq_band_width, k_sort, npulses, NULL, NULL, pvq_bands, coefs_pvq, pvq_inp_vector, fg_pred, HQ_CORE ); diff --git a/lib_enc/pitch_ol2.c b/lib_enc/pitch_ol2.c index b7864e758..bc414158e 100644 --- a/lib_enc/pitch_ol2.c +++ b/lib_enc/pitch_ol2.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "rom_enc.h" #include "prot.h" diff --git a/lib_enc/pre_proc.c b/lib_enc/pre_proc.c index cb85ea29b..c035ef5ac 100644 --- a/lib_enc/pre_proc.c +++ b/lib_enc/pre_proc.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "rom_enc.h" #include "rom_com.h" @@ -57,7 +60,9 @@ void pre_proc( float **inp, /* o : ptr. to inp. signal in the current frame*/ float fr_bands[2 * NB_BANDS], /* i : energy in frequency bands */ float *ener, /* o : residual energy from Levinson-Durbin */ +#ifndef FIX_I4_OL_PITCH int16_t pitch_orig[3], /* o : open-loop pitch values for quantization */ +#endif float A[NB_SUBFR16k * ( M + 1 )], /* i/o: A(z) unquantized for the 4 subframes */ float Aw[NB_SUBFR16k * ( M + 1 )], /* i/o: weighted A(z) unquantized for subframes */ float epsP[M + 1], /* i/o: LP prediction errors */ @@ -844,7 +849,9 @@ void pre_proc( * ACELP/TCX20 Switching Decision *-----------------------------------------------------------------*/ +#ifndef FIX_I4_OL_PITCH mvs2s( st->pitch, pitch_orig, 3 ); +#endif if ( st->codec_mode == MODE2 ) { diff --git a/lib_enc/pvq_core_enc.c b/lib_enc/pvq_core_enc.c index 0a8b7954d..5876c8b44 100644 --- a/lib_enc/pvq_core_enc.c +++ b/lib_enc/pvq_core_enc.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "rom_com.h" #include "prot.h" diff --git a/lib_enc/pvq_encode.c b/lib_enc/pvq_encode.c index 17ed334b1..eb066e8ed 100644 --- a/lib_enc/pvq_encode.c +++ b/lib_enc/pvq_encode.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "prot.h" #include "rom_com.h" diff --git a/lib_enc/q_gain2p.c b/lib_enc/q_gain2p.c index c03f5c430..9c89b44c8 100644 --- a/lib_enc/q_gain2p.c +++ b/lib_enc/q_gain2p.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "prot.h" #include "cnst.h" diff --git a/lib_enc/qlpc_stoch.c b/lib_enc/qlpc_stoch.c index 05e7d8ec0..31021aee7 100644 --- a/lib_enc/qlpc_stoch.c +++ b/lib_enc/qlpc_stoch.c @@ -37,6 +37,9 @@ #include #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "prot.h" diff --git a/lib_enc/range_enc.c b/lib_enc/range_enc.c index 9074c9a9a..8ea8c888d 100644 --- a/lib_enc/range_enc.c +++ b/lib_enc/range_enc.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "rom_com.h" #include "prot.h" diff --git a/lib_enc/re8_cod.c b/lib_enc/re8_cod.c index 72b6c50bb..5facffd8f 100644 --- a/lib_enc/re8_cod.c +++ b/lib_enc/re8_cod.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "prot.h" #include "wmc_auto.h" diff --git a/lib_enc/reordernorm.c b/lib_enc/reordernorm.c index 96c7c0f52..831adeee5 100644 --- a/lib_enc/reordernorm.c +++ b/lib_enc/reordernorm.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "prot.h" #include "cnst.h" #include "rom_com.h" diff --git a/lib_enc/rom_enc.c b/lib_enc/rom_enc.c index ea1d5b469..ae96fdfc3 100644 --- a/lib_enc/rom_enc.c +++ b/lib_enc/rom_enc.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "wmc_auto.h" diff --git a/lib_enc/rom_enc.h b/lib_enc/rom_enc.h index 6e39642b4..7e7659ceb 100644 --- a/lib_enc/rom_enc.h +++ b/lib_enc/rom_enc.h @@ -39,6 +39,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "stat_enc.h" #include "cnst.h" diff --git a/lib_enc/rst_enc.c b/lib_enc/rst_enc.c index 023f1998c..3a2041875 100644 --- a/lib_enc/rst_enc.c +++ b/lib_enc/rst_enc.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "rom_com.h" #include "prot.h" diff --git a/lib_enc/setmodeindex.c b/lib_enc/setmodeindex.c index a1b8f9144..b2187b899 100644 --- a/lib_enc/setmodeindex.c +++ b/lib_enc/setmodeindex.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "prot.h" #include "cnst.h" #include "ivas_cnst.h" diff --git a/lib_enc/sig_clas.c b/lib_enc/sig_clas.c index 3e282c4bc..18ee55df6 100644 --- a/lib_enc/sig_clas.c +++ b/lib_enc/sig_clas.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "prot.h" diff --git a/lib_enc/speech_music_classif.c b/lib_enc/speech_music_classif.c index 5b50391c0..fac0f01e4 100644 --- a/lib_enc/speech_music_classif.c +++ b/lib_enc/speech_music_classif.c @@ -37,6 +37,9 @@ #include #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "prot.h" @@ -334,7 +337,11 @@ void speech_music_classif( } /* Select AUDIO frames */ +#ifdef DEBUGGING + if ( st->codec_mode == MODE1 && ( st->force == 1 || ( st->force == -1 && ( st->sp_aud_decision2 || st->GSC_noisy_speech ) ) ) ) +#else if ( st->codec_mode == MODE1 && ( st->sp_aud_decision2 || st->GSC_noisy_speech ) ) +#endif { st->coder_type = AUDIO; st->hGSCEnc->noise_lev = NOISE_LEVEL_SP0; @@ -1788,6 +1795,9 @@ int16_t ivas_smc_gmm( mvs2s( &hSpMusClas->past_dec[0], &hSpMusClas->past_dec[1], HANG_LEN - 2 ); hSpMusClas->past_dec[0] = dec; +#ifdef DEBUG_MODE_INFO + dbgwrite( &st->hSpMusClas->wdlp_0_95_sp, sizeof( float ), 1, 1, "res/wdlp_0_95_sp.x" ); +#endif return dec; } @@ -1956,6 +1966,38 @@ void ivas_smc_mode_selection( *attack_flag = attack + 1; } +#ifdef DEBUGGING + if ( st->idchan == 0 && st->coder_type != INACTIVE ) + { + if ( st->force == FORCE_GSC && element_brate < IVAS_24k4 ) + { + /* enforce GSC */ + st->sp_aud_decision1 = 1; + st->sp_aud_decision2 = 0; + } + else if ( st->force == FORCE_SPEECH && ( st->sp_aud_decision1 == 1 || st->sp_aud_decision2 == 1 ) ) + { + if ( element_brate < IVAS_24k4 ) + { + /* convert TCX to GSC */ + st->sp_aud_decision1 = 1; + st->sp_aud_decision2 = 0; + } + else + { + /* convert TCX to ACELP */ + st->sp_aud_decision1 = 0; + st->sp_aud_decision2 = 0; + } + } + else if ( st->force == FORCE_MUSIC ) + { + /* enforce TCX */ + st->sp_aud_decision1 = 1; + st->sp_aud_decision2 = 1; + } + } +#endif /* set GSC noisy speech flag on unvoiced SWB segments */ st->GSC_noisy_speech = 0; diff --git a/lib_enc/stat_enc.h b/lib_enc/stat_enc.h index 3e6fc9a48..b5fc7fdd7 100644 --- a/lib_enc/stat_enc.h +++ b/lib_enc/stat_enc.h @@ -39,6 +39,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "stat_com.h" #include "cnst.h" #include "ivas_cnst.h" @@ -1121,6 +1124,9 @@ typedef struct enc_core_structure int16_t idchan; /* channel ID (audio channel number) */ int16_t element_mode; /* element mode */ +#ifdef DEBUGGING + int16_t id_element; /* element ID */ +#endif int32_t element_brate; /* element bitrate */ int16_t codec_mode; /* Mode1 or Mode2 */ int16_t last_codec_mode; /* previous frame Mode 1 or 2 */ @@ -1162,6 +1168,9 @@ typedef struct enc_core_structure int16_t last_Opt_SC_VBR; /* flag indicating prev frame's SC-VBR mode */ int16_t low_rate_mode; /* low-rate mode flag */ int16_t inactive_coder_type_flag; /* inactive coder type flag (0 = AVQ / 1 = GSC) */ +#ifdef DEBUGGING + int16_t force; /* flag indicating specific signal type (0 = speech, 1 = music, -1 = N/A) */ +#endif int16_t ini_frame; /* initialization frames counter */ diff --git a/lib_enc/stat_noise_uv_enc.c b/lib_enc/stat_noise_uv_enc.c index 10894b02f..a1adfb052 100644 --- a/lib_enc/stat_noise_uv_enc.c +++ b/lib_enc/stat_noise_uv_enc.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "prot.h" #include "rom_com.h" #include "wmc_auto.h" diff --git a/lib_enc/swb_bwe_enc.c b/lib_enc/swb_bwe_enc.c index 3ff74624a..e2c8812ec 100644 --- a/lib_enc/swb_bwe_enc.c +++ b/lib_enc/swb_bwe_enc.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "prot.h" diff --git a/lib_enc/swb_bwe_enc_hr.c b/lib_enc/swb_bwe_enc_hr.c index ba13ad306..7b2f3687a 100644 --- a/lib_enc/swb_bwe_enc_hr.c +++ b/lib_enc/swb_bwe_enc_hr.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "prot.h" #include "rom_com.h" diff --git a/lib_enc/swb_bwe_enc_lr.c b/lib_enc/swb_bwe_enc_lr.c index 07cd4b7a4..63c432ea1 100644 --- a/lib_enc/swb_bwe_enc_lr.c +++ b/lib_enc/swb_bwe_enc_lr.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "prot.h" diff --git a/lib_enc/swb_pre_proc.c b/lib_enc/swb_pre_proc.c index 87d28c0b0..3ec175958 100644 --- a/lib_enc/swb_pre_proc.c +++ b/lib_enc/swb_pre_proc.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "prot.h" diff --git a/lib_enc/swb_tbe_enc.c b/lib_enc/swb_tbe_enc.c index e8573d96b..135e856a9 100644 --- a/lib_enc/swb_tbe_enc.c +++ b/lib_enc/swb_tbe_enc.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "prot.h" diff --git a/lib_enc/tcq_core_enc.c b/lib_enc/tcq_core_enc.c index 03164a323..aad3e54e7 100644 --- a/lib_enc/tcq_core_enc.c +++ b/lib_enc/tcq_core_enc.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "rom_com.h" #include "prot.h" #include "cnst.h" @@ -51,6 +54,9 @@ ivas_error tcq_core_LR_enc( BSTR_ENC_HANDLE hBstr, /* i/o: encoder bitstream handle */ +#ifdef DEBUGGING + const int16_t idchan, +#endif int32_t inp_vector[], const float coefs_norm[], float coefs_quant[], @@ -465,6 +471,35 @@ ivas_error tcq_core_LR_enc( } } +#ifdef DEBUGGING + if ( parenc->num_bits > bit_budget + 1 ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "nTCQ too much bits used! \n" ); + } + + for ( i = 0; i < BANDS; i++ ) + { + float diff[TCQ_MAX_BAND_SIZE]; + + if ( npulses[i] > 0 ) + { + /* SNR measurement */ + for ( j = 0; j < sfmsize[i]; j++ ) + { + diff[j] = coefs_norm[sfm_start[i] + j] - coefs_quant[sfm_start[i] + j]; + } + + if ( idchan == 0 ) + { + snr( &coefs_norm[sfm_start[i]], diff, sfmsize[i], "TCQ_output" ); + } + else + { + snr( &coefs_norm[sfm_start[i]], diff, sfmsize[i], "TCQ_output_chan2" ); + } + } + } +#endif return error; } diff --git a/lib_enc/tcx_ltp_enc.c b/lib_enc/tcx_ltp_enc.c index b8bc7dcd0..0ea2e0424 100644 --- a/lib_enc/tcx_ltp_enc.c +++ b/lib_enc/tcx_ltp_enc.c @@ -36,11 +36,17 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "prot.h" #include "rom_enc.h" #include "rom_com.h" #include "wmc_auto.h" +#ifdef DEBUG_PLOT +#include "deb_out.h" +#endif /*---------------------------------------------------------------------* diff --git a/lib_enc/tcx_utils_enc.c b/lib_enc/tcx_utils_enc.c index 31473d404..deaab8d69 100644 --- a/lib_enc/tcx_utils_enc.c +++ b/lib_enc/tcx_utils_enc.c @@ -37,6 +37,9 @@ #include #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "prot.h" #include "rom_com.h" diff --git a/lib_enc/transient_detection.c b/lib_enc/transient_detection.c index 43689d333..04cf8ea24 100644 --- a/lib_enc/transient_detection.c +++ b/lib_enc/transient_detection.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "stat_enc.h" #include "cnst.h" #include "prot.h" diff --git a/lib_enc/transition_enc.c b/lib_enc/transition_enc.c index f879066b1..925a6f1c3 100644 --- a/lib_enc/transition_enc.c +++ b/lib_enc/transition_enc.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "rom_com.h" diff --git a/lib_enc/updt_enc.c b/lib_enc/updt_enc.c index a92e7ef47..5cc66667f 100644 --- a/lib_enc/updt_enc.c +++ b/lib_enc/updt_enc.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "rom_com.h" #include "prot.h" diff --git a/lib_enc/updt_tar.c b/lib_enc/updt_tar.c index 52eb709cc..4c3ff4843 100644 --- a/lib_enc/updt_tar.c +++ b/lib_enc/updt_tar.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "prot.h" #include "wmc_auto.h" diff --git a/lib_enc/vad.c b/lib_enc/vad.c index 2486aa843..62c7ccb91 100644 --- a/lib_enc/vad.c +++ b/lib_enc/vad.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "prot.h" diff --git a/lib_enc/vad_param_updt.c b/lib_enc/vad_param_updt.c index f9b315ec9..b7adac46e 100644 --- a/lib_enc/vad_param_updt.c +++ b/lib_enc/vad_param_updt.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "cnst.h" #include "prot.h" diff --git a/lib_enc/vbr_average_rate.c b/lib_enc/vbr_average_rate.c index 3ee355c55..8e7330c8b 100644 --- a/lib_enc/vbr_average_rate.c +++ b/lib_enc/vbr_average_rate.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "prot.h" #include "rom_com.h" diff --git a/lib_enc/vlpc_1st_cod.c b/lib_enc/vlpc_1st_cod.c index 84afcd816..553cf7e26 100644 --- a/lib_enc/vlpc_1st_cod.c +++ b/lib_enc/vlpc_1st_cod.c @@ -36,6 +36,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include +#endif #include "cnst.h" #include "prot.h" #include "rom_com.h" @@ -58,6 +61,10 @@ static void lsf_weight( float scale = ( (float) sr_core ) / INT_FS_12k8; float freq_max = sr_core / 2.f; +#ifdef DEBUGGING + /* Verify, that M is pair, otherwise adapt exit of loop below */ + assert( ( M & 1 ) == 0 ); +#endif /* weighting function */ inv_di0 = scale / lsfq[0]; @@ -97,6 +104,9 @@ int16_t vlpc_1st_cod( float w[M], x[M]; float dist_min, dist, temp; const float *p_dico; +#ifdef DEBUGGING + int16_t hit = 0; +#endif float scale = ( (float) sr_core ) / INT_FS_12k8; float scaleinv = 1.f / scale; @@ -130,6 +140,9 @@ int16_t vlpc_1st_cod( { dist_min = dist; index = i; +#ifdef DEBUGGING + hit++; /*just for testing*/ +#endif } } @@ -141,6 +154,10 @@ int16_t vlpc_1st_cod( lsfq[j] += scale * *p_dico++; /* += cause it's differential */ } +#ifdef DEBUGGING + assert( index < 256 ); + assert( hit > 0 ); +#endif return index; } diff --git a/lib_lc3plus/.clang-format b/lib_lc3plus/.clang-format new file mode 100644 index 000000000..47a38a93f --- /dev/null +++ b/lib_lc3plus/.clang-format @@ -0,0 +1,2 @@ +DisableFormat: true +SortIncludes: Never diff --git a/lib_lc3plus/adjust_global_gain.c b/lib_lc3plus/adjust_global_gain.c new file mode 100644 index 000000000..e7674dd71 --- /dev/null +++ b/lib_lc3plus/adjust_global_gain.c @@ -0,0 +1,86 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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 "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 = 0; + LC3_INT delta2 = 0; + LC3_INT gg_idx_inc; + LC3_INT factor; + + + if (frame_dms == 25) + { + if (target < 520) + { + factor = 3; + } else { + factor = 4; + } + } else if (frame_dms == 50) + { + factor = 2; + } 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/al_fec_fl.c b/lib_lc3plus/al_fec_fl.c new file mode 100644 index 000000000..0cae36dad --- /dev/null +++ b/lib_lc3plus/al_fec_fl.c @@ -0,0 +1,2329 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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 "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 new file mode 100644 index 000000000..c67432e2c --- /dev/null +++ b/lib_lc3plus/apply_global_gain.c @@ -0,0 +1,21 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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 "functions.h" + +void processApplyGlobalGain_fl(LC3_FLOAT x[], LC3_INT xLen, LC3_INT global_gain_idx, LC3_INT global_gain_off) +{ + LC3_FLOAT gg = 0; + + gg = LC3_POW(10, (LC3_FLOAT)(global_gain_idx + global_gain_off) / 28); + + mult_const(x, gg, xLen); +} diff --git a/lib_lc3plus/ari_codec.c b/lib_lc3plus/ari_codec.c new file mode 100644 index 000000000..80c75fcf0 --- /dev/null +++ b/lib_lc3plus/ari_codec.c @@ -0,0 +1,1122 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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 "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 tns_order_freq_enc(LC3_INT enable_lpc_weighting, LC3_INT order, LC3_INT* symfreq, LC3_INT* cumfreq); +static void tns_coef_freq_enc(LC3_INT k, LC3_INT idx, LC3_INT* symfreq, LC3_INT* cumfreq); +static void ac_freq_fl(LC3_INT pki, LC3_INT s, LC3_INT* symfreq, LC3_INT* cumfreq); +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); +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); +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); +static void tns_order_freq(LC3_INT enable_lpc_weighting, 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 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); +static void ac_freq(LC3_INT pki, LC3_INT* symfreq, LC3_INT* cumfreq, LC3_INT* numsym); +static void findNonZero(LC3_INT* in, LC3_INT* out, LC3_INT len, LC3_INT* outLen); +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); +static void calculate_nfseed(LC3_INT *x, LC3_INT L_spec, LC3_INT *nf_seed); + +void calculate_nfseed(LC3_INT *x, LC3_INT L_spec, LC3_INT *nf_seed) +{ + LC3_INT k = 0; + + *nf_seed = 0; + + for (k = 0; k < L_spec; k++) { + *nf_seed = *nf_seed + (abs(x[k]) & 32767) * k; + } + *nf_seed = *nf_seed & 65535; + + if (*nf_seed >= 32768) { + *nf_seed = *nf_seed - 65536; + } +} + +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) + { + if (!from_left && mask_side != 1) + { + return; + } + + 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; + } + + 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) + { + offset = offset + st_fl->pc_bytes; + } + + if ((bp_side_local + offset - bp_local) == st_fl->pc_bytes) + { + st_fl->pc_b_left = bp_local + 1; + st_fl->pc_b_right = bp_side_local - 1; + + if (st_fl->pc_enc) + { + st_fl->pc_return = 1; + return; + } + } + } + + 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) + { + *bp_side = st_fl->pc_bytes - 1; + st_fl->pc_c_bp_side = 1; + } + + if (st_fl->pc_bfi == 2) + { + + 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)) + { + 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))) + { + st_fl->pc_bbi = 1; + } + } + } + } + + return; +} + + +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) + { + *bp = *bp + st_fl->pc_bytes; + } + + st_fl->ac_low_fl = 0; + + 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; + } + + st_fl->BER_detect = 0; +} + +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; + + j = 0; + for (i = 1; i < 9; i++) { + symfreq[j] = ari_tns_order_cf[enable_lpc_weighting][i]; + j++; + } + + for (i = 0; i < *numsym; i++) { + symfreq[i] -= ari_tns_order_cf[enable_lpc_weighting][i]; + } + + for (i = 0; i < *numsym; i++) { + cumfreq[i] = ari_tns_order_cf[enable_lpc_weighting][i]; + } +} + +/* Returns val */ +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; + + + tmp = st->ac_range_fl >> 10; + + if (st->ac_low_fl >= (LC3_UINT32)(tmp << 10)) { + st->BER_detect = 1; + } + + val = num_sym - 1; + + while (st->ac_low_fl < (LC3_UINT32)(tmp * cum_freq[val])) { + val--; + } + + st->ac_low_fl = st->ac_low_fl - tmp * cum_freq[val]; + st->ac_range_fl = tmp * sym_freq[val]; + + 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; + } + + return val; +} + +void tns_coef_freq(LC3_INT k, LC3_INT* symfreq, LC3_INT* cumfreq, LC3_INT* numsym) +{ + LC3_INT i = 0, j = 0; + + *numsym = 18 - 1; + + j = 0; + for (i = 1; i <= *numsym; i++) { + symfreq[j] = ari_tns_freq_cf[k][i]; + j++; + } + + for (i = 0; i < *numsym; i++) { + symfreq[i] -= ari_tns_freq_cf[k][i]; + } + + for (i = 0; i < *numsym; i++) { + cumfreq[i] = ari_tns_freq_cf[k][i]; + } +} + +void ac_freq(LC3_INT pki, LC3_INT* symfreq, LC3_INT* cumfreq, LC3_INT* numsym) +{ + LC3_INT i = 0, j = 0; + + *numsym = 18 - 1; + + j = 0; + for (i = 1; i <= *numsym; i++) { + symfreq[j] = ari_spec_cumfreq_fl[pki][i]; + j++; + } + + for (i = 0; i < *numsym; i++) { + symfreq[i] -= ari_spec_cumfreq_fl[pki][i]; + } + + for (i = 0; i < *numsym; i++) { + cumfreq[i] = ari_spec_cumfreq_fl[pki][i]; + } +} + +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) +{ + *bit = 0; + + UNUSED(bp); + UNUSED(st_fl); + UNUSED(from_left); + + 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; + } +} + +void findNonZero(LC3_INT* in, LC3_INT* out, LC3_INT len, LC3_INT* outLen) +{ + LC3_INT i = 0, j = 0; + + for (i = 0; i < len; i++) { + if (in[i] != 0) { + out[j] = i; + j++; + } + } + + *outLen = j; +} + +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 +) +{ + 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, idx[MAX_LEN] = {0}, rateFlag = 0; + + total_bits = 8 * numbytes; + + 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); + + /* Rate flag */ + if (fs_idx != 5) + { + if (total_bits > (160 + fs_idx * 160)) { + rateFlag = 512; + } + } + + /* 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) + { + tmp /= 2; + } + if (frame_dms == 50) + { + 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; + } + + /* 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); + } + + 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) { + 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) + { + *b_left = st.pc_b_left; + return; + } + + if (st.pc_bbi == 2) + { + *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]; + } + } + + /* Context */ + lev1 = MIN(lev, 3); + if (lev1 <= 1) { + t = 1 + (a + b) * (lev1 + 1); + } else { + t = 12 + lev1; + } + + c = (c & 15) * 16 + t; + + 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; + } + + *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; + } + } + + /* 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) + { + 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, idx, L_spec, &idx_len); + if (hrmode) + { + 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++) { + 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; + } + + 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) + { + *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; + } + + 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) + { + *bfi = 0; + memset(resBits, 0, sizeof(LC3_INT32) * (*nbits_residual)); + calculate_nfseed(x, k, nf_seed); + return; + } + + *nbits_residual = *nbits_residual - 1; + + if (bit == 0) { + x[k] = 1; + } else { + x[k] = -1; + } + } + } + + if (*nbits_residual == 0) { + break; + } + + 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) + { + *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; + } + + 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) + { + *bfi = 0; + memset(resBits, 0, sizeof(LC3_INT32) * (*nbits_residual)); + calculate_nfseed(x, k, nf_seed); + return; + } + + *nbits_residual = *nbits_residual - 1; + + if (bit == 0) { + x[k + 1] = 1; + } else { + x[k + 1] = -1; + } + } + } + } + } + } + + /* 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) { + *zero_frame = 1; + } else { + *zero_frame = 0; + } + + if (enc) + { + if (st.pc_bytes > 0) + { + if (st.pc_b_left > numbytes) + { + *b_left = bp_side - st.pc_bytes; + } + } + } + + if ((*bfi == 2) && (*spec_inv_idx == (L_spec + 1))) + { + *bfi = 0; + } + + *spec_inv_idx = *spec_inv_idx - 1; +} + +void ac_encode_fl(Encoder_State_fl* st, LC3_INT sym_freq, LC3_INT cum_freq) +{ + LC3_INT r = 0; + + r = st->range >> 10; + st->low = st->low + r * cum_freq; + + if ((st->low >> 24) == 1) { + st->carry = 1; + } + + st->low = (st->low) & ((LC3_INT)pow(2, 24) - 1); + st->range = r * sym_freq; + + while (st->range < (LC3_INT)pow(2, 16)) { + st->range = st->range << 8; + ac_shift_fl(st); + } +} + +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; + } + + st->low = st->low << 8; + st->low = (st->low) & ((LC3_INT)pow(2, 24) - 1); +} + +void tns_order_freq_enc(LC3_INT enable_lpc_weighting, LC3_INT order, LC3_INT* symfreq, LC3_INT* cumfreq) +{ + *symfreq = tns_freq_cf[enable_lpc_weighting][order] - tns_freq_cf[enable_lpc_weighting][order - 1]; + *cumfreq = tns_freq_cf[enable_lpc_weighting][order - 1]; +} + +void tns_coef_freq_enc(LC3_INT k, LC3_INT idx, LC3_INT* symfreq, LC3_INT* cumfreq) +{ + *symfreq = tns_cf[k][idx + 1] - tns_cf[k][idx]; + *cumfreq = tns_cf[k][idx]; +} + +void ac_freq_fl(LC3_INT pki, LC3_INT s, LC3_INT* symfreq, LC3_INT* cumfreq) +{ + *symfreq = ari_spec_cumfreq_fl[pki][s + 1] - ari_spec_cumfreq_fl[pki][s]; + *cumfreq = ari_spec_cumfreq_fl[pki][s]; +} + +void ac_finalize_fl(Encoder_State_fl* st) +{ + LC3_INT bits = 0, mask = 0, val = 0, over1 = 0, high = 0, over2 = 0, c = 0, b = 0; + + bits = 24 - floor(LC3_LOGTWO(st->range)); + mask = ((LC3_INT)pow(2, 24) - 1) >> bits; + val = st->low + mask; + over1 = val >> 24; + + val = (val) & ((LC3_INT)pow(2, 24) - 1); + high = st->low + st->range; + over2 = high >> 24; + high = high & ((LC3_INT)pow(2, 24) - 1); + val = val & (((LC3_INT)pow(2, 24) - 1) - mask); + + if (over1 == over2) { + if (val + mask >= high) { + bits = bits + 1; + mask = mask >> 1; + val = ((st->low + mask) & ((LC3_INT)pow(2, 24) - 1)) & (((LC3_INT)pow(2, 24) - 1) - mask); + } + + if (val < st->low) { + st->carry = 1; + } + } + + st->low = val; + + b = bits; + + if (bits > 8) { + for (; b >= 1; b = b - 8) { + ac_shift_fl(st); + } + } else { + ac_shift_fl(st); + } + + bits = b; + if (bits < 0) { + bits += 8; + } + + if (st->carry_count > 0) { + st->ptr[st->bp] = st->cache; + st->bp = st->bp + 1; + + for (c = st->carry_count; c >= 2; c--) { + st->ptr[st->bp] = 255; + st->bp = st->bp + 1; + } + + write_uint_forward_fl(st, 255 << (bits - 8), bits); + } else { + write_uint_forward_fl(st, st->cache, bits); + } +} + +void write_uint_forward_fl(Encoder_State_fl* st, LC3_INT val, LC3_INT numbits) +{ + LC3_INT k = 0, bit = 0, mask = 128; + + for (k = 0; k < numbits; k++) { + bit = val & mask; + + if (bit == 0) { + st->ptr[st->bp] = st->ptr[st->bp] & (255 - mask); + } else { + st->ptr[st->bp] = st->ptr[st->bp] | mask; + } + + mask = mask >> 1; + } +} + +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 = (LC3_INT)pow(2, 24) - 1; + st->cache = -1; + st->carry = 0; + st->carry_count = 0; +} + +LC3_INT sign(LC3_INT x) +{ + if (x > 0) + return 1; + + if (x < 0) + return -1; + + return 0; +} + +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) +{ + LC3_INT total_bits = 0, cumfreq = 0, symfreq = 0, k = 0, i = 0, j = 0, lev = 0, lev1 = 0; + LC3_INT bit1 = 0, bit2 = 0, lsb1 = 0, lsb2 = 0, a = 0, b = 0, bit = 0, pki = 0, nbits_side = 0; + LC3_INT nbits_residual_enc = 0, nbits_ari = 0, lsbs[MAX_LEN] = {0}, lsbsLen = 0; + Encoder_State_fl st; + + ari_enc_init(&st, bytes, &bp_side, &mask_side); + + total_bits = nbbits; + + /* TNS data */ + for (i = 0; i < tns_numfilters; i++) { + if (tns_order[i] > 0) { + tns_order_freq_enc(enable_lpc_weighting, tns_order[i], &symfreq, &cumfreq); + ac_encode_fl(&st, symfreq, cumfreq); + + for (j = 0; j < tns_order[i]; j++) { + tns_coef_freq_enc(j, tns_idx[i * 8 + j], &symfreq, &cumfreq); + ac_encode_fl(&st, symfreq, cumfreq); + } + } + } + + /* Spectral data */ + for (k = 0; k < lastnz; k = k + 2) { + for (lev = 0; lev < codingdata[1]; lev++) { + lev1 = MIN(lev, 3); + pki = ari_spec_lookup_fl[codingdata[0] + lev1 * 1024]; + ac_freq_fl(pki, 16, &symfreq, &cumfreq); + + ac_encode_fl(&st, symfreq, cumfreq); + bit1 = (abs(x[k]) >> lev) & 1; + bit2 = (abs(x[k + 1]) >> lev) & 1; + + 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); + } + } + + lev1 = MIN(MAX(codingdata[1], 0), 3); + pki = ari_spec_lookup_fl[codingdata[0] + lev1 * 1024]; + + ac_freq_fl(pki, codingdata[2], &symfreq, &cumfreq); + ac_encode_fl(&st, symfreq, cumfreq); + + a = abs(x[k]); + b = abs(x[k + 1]); + + if (lsbMode == 1 && codingdata[1] > 0) { + a = a >> 1; + lsbs[lsbsLen] = lsb1; + lsbsLen++; + + if (a == 0 && x[k] != 0) { + bit = MAX(0, -sign(x[k])); + lsbs[lsbsLen] = bit; + lsbsLen++; + } + + b = b >> 1; + lsbs[lsbsLen] = lsb2; + lsbsLen++; + + if (b == 0 && x[k + 1] != 0) { + bit = MAX(0, -sign(x[k + 1])); + lsbs[lsbsLen] = bit; + lsbsLen++; + } + } + + if (a != 0) { + bit = MAX(0, -sign(x[k])); + write_bit_backward_fl(st.ptr, st.bp_side, st.mask_side, bit); + } + + if (b != 0) { + bit = MAX(0, -sign(x[k + 1])); + write_bit_backward_fl(st.ptr, st.bp_side, st.mask_side, bit); + } + + codingdata += 3; + } + + /* Residual bits */ + nbits_side = total_bits - (8 * (*(st.bp_side) + 1) + 8 - LC3_LOGTWO(*(st.mask_side))); + nbits_ari = (st.bp + 1) * 8 + 25 - floor(LC3_LOGTWO(st.range)); + + if (st.cache >= 0) { + nbits_ari = nbits_ari + 8; + } + + if (st.carry_count > 0) { + nbits_ari = nbits_ari + st.carry_count * 8; + } + + 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 (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))) + { + write_bit_backward_fl(st.ptr, st.bp_side, st.mask_side, 1); + } + else + { + write_bit_backward_fl(st.ptr, st.bp_side, st.mask_side, 0); + } + } + } 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]); + } + } + + ac_finalize_fl(&st); +} + diff --git a/lib_lc3plus/attack_detector.c b/lib_lc3plus/attack_detector.c new file mode 100644 index 000000000..c9f7c0a94 --- /dev/null +++ b/lib_lc3plus/attack_detector.c @@ -0,0 +1,105 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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 "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] = {0}, block_nrg[4] = {0}, sum = 0, tmpEne = 0, *ptr = NULL, tmp[162] = {0}; + LC3_INT i = 0, j = 0, attackPosition = 0; + LC3_FLOAT mval = 0; + LC3_INT frame_size_16k = attdec_nblocks * 40; + + + ptr = &tmp[2]; + + + + if (attackHandlingOn) { + /* Decimate 96, 48 and 32 kHz signals to 16 kHz */ + if (fs == 96000) { + for (i = 0; i < frame_size;) { + ptr[j] = in[i] + in[i + 1] + in[i + 2] + in[i + 3] + in[i + 4] + in[i + 5]; + i = i + 6; + j++; + } + mval = 1e-5; + } else 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++; + } + } else if (fs == 24000) { + j = 0; + for (i = 0; i < frame_size;) { + ptr[j] = (in[i] + (in[i + 1] + in[i + 2]) / 2.0); + i = i + 3; + 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/clib.h b/lib_lc3plus/clib.h new file mode 100644 index 000000000..bd7092780 --- /dev/null +++ b/lib_lc3plus/clib.h @@ -0,0 +1,27 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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 +#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 new file mode 100644 index 000000000..8189761a0 --- /dev/null +++ b/lib_lc3plus/constants.c @@ -0,0 +1,3803 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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 "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 +}; + +const LC3_INT ari_tns_order_cf[2][9] = {{0, 3, 12, 35, 89, 200, 390, 658, 1024}, + {0, 14, 56, 156, 313, 494, 672, 839, 1024}}; + +const LC3_INT 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}}; + +const LC3_INT ari_spec_lookup_fl[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, + 0x24, 0x24, 0x26, 0x00, 0x3B, 0x17, 0x16, 0x2E, 0x2E, 0x2D, 0x2F, 0x30, 0x32, 0x32, 0x12, 0x36, 0x36, 0x36, 0x26, + 0x3B, 0x3B, 0x3B, 0x16, 0x00, 0x3E, 0x3F, 0x03, 0x21, 0x02, 0x02, 0x3D, 0x14, 0x14, 0x14, 0x15, 0x3B, 0x3B, 0x27, + 0x1C, 0x1C, 0x3F, 0x3F, 0x03, 0x21, 0x02, 0x02, 0x3D, 0x26, 0x26, 0x26, 0x15, 0x3B, 0x3B, 0x27, 0x1C, 0x1C, 0x06, + 0x06, 0x06, 0x02, 0x12, 0x3D, 0x14, 0x15, 0x15, 0x15, 0x3B, 0x27, 0x27, 0x07, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x33, 0x33, 0x33, 0x35, 0x36, 0x14, 0x26, + 0x26, 0x39, 0x27, 0x27, 0x27, 0x07, 0x18, 0x22, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, + 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x38, 0x26, 0x39, 0x39, 0x3B, 0x07, 0x07, 0x07, 0x2A, + 0x2A, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x05, 0x04, 0x04, 0x05, 0x15, 0x15, 0x3B, 0x07, 0x07, 0x07, 0x07, 0x19, 0x19, 0x19, 0x22, 0x04, 0x04, 0x04, 0x04, + 0x05, 0x17, 0x17, 0x27, 0x07, 0x07, 0x07, 0x2A, 0x19, 0x19, 0x16, 0x1F, 0x1F, 0x27, 0x27, 0x27, 0x27, 0x07, 0x07, + 0x2A, 0x00, 0x19, 0x16, 0x16, 0x16, 0x1C, 0x22, 0x1F, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, + 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x28, 0x08, 0x09, 0x31, 0x31, 0x34, 0x11, 0x11, 0x11, 0x04, 0x00, + 0x14, 0x11, 0x3C, 0x28, 0x28, 0x08, 0x2B, 0x1B, 0x31, 0x31, 0x0E, 0x11, 0x11, 0x11, 0x24, 0x2A, 0x2A, 0x11, 0x39, + 0x39, 0x28, 0x08, 0x1A, 0x1B, 0x31, 0x0C, 0x0E, 0x11, 0x11, 0x11, 0x24, 0x00, 0x26, 0x24, 0x01, 0x08, 0x08, 0x2B, + 0x09, 0x0B, 0x31, 0x0C, 0x0E, 0x0E, 0x21, 0x32, 0x32, 0x32, 0x3D, 0x24, 0x27, 0x08, 0x08, 0x2B, 0x2E, 0x31, 0x34, + 0x1E, 0x0E, 0x0E, 0x21, 0x32, 0x32, 0x32, 0x32, 0x12, 0x19, 0x08, 0x08, 0x2B, 0x2E, 0x31, 0x34, 0x1E, 0x0E, 0x0E, + 0x12, 0x05, 0x05, 0x05, 0x3D, 0x12, 0x17, 0x2B, 0x2B, 0x2B, 0x09, 0x31, 0x34, 0x03, 0x0E, 0x0E, 0x32, 0x32, 0x32, + 0x32, 0x3D, 0x11, 0x18, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, 0x2B, + 0x2B, 0x2B, 0x2B, 0x2B, 0x09, 0x0B, 0x34, 0x34, 0x0E, 0x0E, 0x11, 0x3D, 0x3D, 0x3D, 0x36, 0x11, 0x27, 0x2D, 0x2D, + 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2D, 0x2C, 0x1B, 0x1D, + 0x34, 0x30, 0x34, 0x34, 0x11, 0x11, 0x11, 0x11, 0x02, 0x11, 0x07, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, + 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x1B, 0x09, 0x1B, 0x1B, 0x0C, 0x34, 0x0E, 0x0E, 0x3A, 0x29, + 0x29, 0x29, 0x06, 0x11, 0x25, 0x09, 0x09, 0x09, 0x1B, 0x0B, 0x31, 0x0C, 0x34, 0x0E, 0x0E, 0x0E, 0x32, 0x00, 0x35, + 0x11, 0x1C, 0x34, 0x34, 0x31, 0x34, 0x0C, 0x34, 0x1E, 0x0E, 0x0E, 0x11, 0x02, 0x02, 0x02, 0x26, 0x26, 0x22, 0x1F, + 0x22, 0x22, 0x1F, 0x1F, 0x1F, 0x1F, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x13, 0x1F, 0x13, 0x2C, 0x2C, 0x3E, 0x1E, + 0x20, 0x3A, 0x23, 0x24, 0x24, 0x26, 0x00, 0x3B, 0x07, 0x07, 0x27, 0x22, 0x22, 0x2D, 0x2F, 0x30, 0x21, 0x23, 0x23, + 0x24, 0x26, 0x26, 0x26, 0x3B, 0x07, 0x07, 0x27, 0x22, 0x22, 0x3E, 0x1E, 0x0F, 0x32, 0x35, 0x35, 0x36, 0x15, 0x15, + 0x15, 0x3B, 0x07, 0x07, 0x07, 0x22, 0x1E, 0x1E, 0x30, 0x21, 0x3A, 0x12, 0x12, 0x38, 0x17, 0x17, 0x17, 0x3B, 0x07, + 0x07, 0x18, 0x22, 0x22, 0x06, 0x06, 0x3A, 0x35, 0x36, 0x36, 0x15, 0x3B, 0x3B, 0x3B, 0x27, 0x07, 0x07, 0x2A, 0x22, + 0x06, 0x06, 0x21, 0x3A, 0x35, 0x36, 0x3D, 0x15, 0x3B, 0x3B, 0x3B, 0x27, 0x07, 0x07, 0x2A, 0x22, 0x22, 0x33, 0x33, + 0x35, 0x36, 0x38, 0x38, 0x39, 0x27, 0x27, 0x27, 0x07, 0x2A, 0x2A, 0x19, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, + 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x04, 0x04, 0x04, 0x05, 0x17, 0x17, 0x27, 0x07, + 0x07, 0x07, 0x2A, 0x19, 0x19, 0x16, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, + 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x05, 0x05, 0x05, 0x05, 0x39, 0x39, 0x27, 0x18, 0x18, 0x18, 0x2A, 0x16, 0x16, 0x1C, + 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x29, + 0x29, 0x29, 0x29, 0x27, 0x27, 0x07, 0x2A, 0x2A, 0x2A, 0x19, 0x1C, 0x1C, 0x1C, 0x1F, 0x1F, 0x29, 0x29, 0x29, 0x29, + 0x27, 0x27, 0x18, 0x19, 0x19, 0x19, 0x16, 0x1C, 0x1C, 0x22, 0x1F, 0x1F, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x1C, + 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x1F, 0x13, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, + 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x09, 0x0B, 0x2F, 0x20, 0x32, 0x12, 0x12, 0x14, 0x15, 0x15, 0x15, 0x27, + 0x3B, 0x22, 0x1A, 0x1A, 0x1B, 0x1D, 0x1E, 0x21, 0x32, 0x12, 0x12, 0x14, 0x39, 0x39, 0x39, 0x3B, 0x3B, 0x22, 0x1B, + 0x1B, 0x0B, 0x0C, 0x30, 0x32, 0x3A, 0x3D, 0x3D, 0x38, 0x39, 0x39, 0x39, 0x3B, 0x27, 0x22, 0x2D, 0x2D, 0x0C, 0x1E, + 0x20, 0x02, 0x02, 0x3D, 0x26, 0x26, 0x26, 0x39, 0x00, 0x3B, 0x27, 0x22, 0x3F, 0x3F, 0x03, 0x20, 0x3A, 0x12, 0x12, + 0x14, 0x15, 0x15, 0x15, 0x3B, 0x27, 0x27, 0x07, 0x1F, 0x1F, 0x03, 0x03, 0x21, 0x3A, 0x12, 0x12, 0x14, 0x15, 0x15, + 0x15, 0x3B, 0x07, 0x07, 0x07, 0x1F, 0x06, 0x06, 0x33, 0x33, 0x35, 0x36, 0x36, 0x26, 0x39, 0x39, 0x39, 0x27, 0x07, + 0x07, 0x2A, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, + 0x1F, 0x33, 0x35, 0x35, 0x36, 0x38, 0x38, 0x39, 0x3B, 0x3B, 0x3B, 0x07, 0x18, 0x18, 0x19, 0x1F, 0x1F, 0x1F, 0x1F, + 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x04, 0x04, 0x04, 0x36, 0x15, + 0x15, 0x39, 0x27, 0x27, 0x27, 0x07, 0x2A, 0x2A, 0x16, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, + 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x05, 0x05, 0x05, 0x05, 0x17, 0x17, 0x3B, 0x07, 0x07, 0x07, 0x2A, + 0x16, 0x16, 0x1C, 0x1F, 0x1F, 0x04, 0x04, 0x04, 0x05, 0x17, 0x17, 0x27, 0x18, 0x18, 0x18, 0x19, 0x1C, 0x1C, 0x22, + 0x1F, 0x1F, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x1C, 0x22, 0x22, 0x22, 0x1F, 0x1F, 0x1F, 0x1F, 0x13, 0x0D, 0x0D, + 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x3C, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0D, 0x0D, 0x0D, 0x3C, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, + 0x0D, 0x3C, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x3C, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x3C, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, + 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, + 0x3C, 0x3C, 0x3C, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, + 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, + 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, + 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x10, 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, 0x0D, 0x0D, 0x0D, 0x00, + 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x00, 0x3C, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x3C, 0x3C, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x3C, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x3C, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x00, + 0x0D, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, + 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 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, 0x3C, 0x00, 0x00, 0x10, 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, 0x10, 0x10, 0x10, + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, + 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, + 0x0D, 0x0D, 0x0D, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, + 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x10, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, + 0x0D, 0x0D, 0x0D, 0x3C, 0x10, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, + 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x3C, 0x10, 0x0D, + 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, + 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x3C, 0x10, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, + 0x0D, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x10, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, + 0x10, 0x10, 0x10, 0x10, 0x10, 0x25, 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, 0x0D, 0x0D, 0x0D, 0x10, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x10, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, + 0x0D, 0x0D, 0x0D, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, + 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x0D, + 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x3C, + 0x3C, 0x10, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x10, 0x10, 0x10, + 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x25, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 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, 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, 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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, + 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0D, 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, 0x00, 0x0D, 0x0D, 0x0D, + 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, + 0x0D, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0D, 0x0D, 0x0D, 0x00, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, + 0x0D, 0x0D, 0x0D, 0x00, 0x0D, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, + 0x00, 0x0D, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x00, 0x0D, 0x0D, + 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x00, 0x13, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, + 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x13, 0x0D, 0x0D, 0x0D, 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, 0x00, 0x00, + 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, + 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x0D, 0x0D, 0x0D, 0x0D, + 0x0D, 0x0D, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, + 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x3C, 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, 0x0D, 0x3C, 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, 0x0D, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x3C, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, + 0x3C, 0x3C, 0x3C, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, + 0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x0D, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x0D, 0x3C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x3C, 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, 0x0D, 0x3C, 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, 0x0D, 0x0D, 0x0D, 0x3C, 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, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x3C, 0x0D, 0x0D, 0x0D, + 0x0D, 0x0D, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 0x3C, 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, 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, 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, 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, + 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, 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, 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, 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, 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, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 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, 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, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x00, + 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 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, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 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, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, + 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, 0x0D, + 0x0D, 0x0D, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x3C, 0x3C, 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, 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, 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, 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, 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, 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, + 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, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x0D, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x0D, 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, 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, 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, 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, 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, + 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, 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, 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, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; + +const LC3_INT 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] = { + {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}, + {7886, 7120, 8982, 10970, 7496, 6815, 8334, 10150, 9437, 8535, 9656, 11216, 11348, 10431, 11348, 12479, 4051}, + {5485, 6099, 9168, 11940, 6311, 6262, 8640, 11090, 9233, 8640, 10334, 12479, 11781, 11090, 12479, 13988, 6009}, + {7886, 7804, 10150, 11940, 7886, 7685, 9368, 10854, 10061, 9300, 10431, 11629, 11629, 10742, 11485, 12479, 2763}, + {9042, 8383, 10240, 11781, 8483, 8013, 9437, 10742, 10334, 9437, 10431, 11485, 11781, 10742, 11485, 12288, 2346}, + {5922, 6619, 9368, 11940, 6566, 6539, 8750, 10970, 9168, 8640, 10240, 12109, 11485, 10742, 11940, 13396, 5009}, + {12288, 11090, 11348, 12109, 11090, 9892, 10334, 10970, 11629, 10431, 10970, 11629, 12479, 11348, 11781, 12288, + 1289}, + {1685, 5676, 13138, 18432, 5598, 7804, 13677, 18432, 12683, 13396, 17234, 20480, 17234, 17234, 20480, 20480, 15725}, + {2793, 5072, 10970, 15725, 5204, 6487, 11216, 15186, 10970, 11216, 14336, 17234, 15186, 15186, 17234, 18432, 12109}, + {12902, 11485, 11940, 13396, 11629, 10531, 11348, 12479, 12683, 11629, 12288, 13138, 13677, 12683, 13138, 13677, + 854}, + {3821, 5088, 9812, 13988, 5289, 5901, 9812, 13677, 9976, 9892, 12479, 15186, 13988, 13677, 15186, 17234, 9812}, + {4856, 5412, 9168, 12902, 5598, 5736, 8863, 12288, 9368, 8982, 11090, 13677, 12902, 12288, 13677, 15725, 8147}, + {20480, 20480, 7088, 9300, 20480, 20480, 7844, 9733, 7320, 7928, 9368, 10970, 9581, 9892, 10970, 12288, 2550}, + {6031, 5859, 8192, 10635, 6410, 6286, 8433, 10742, 9656, 9042, 10531, 12479, 12479, 11629, 12902, 14336, 5756}, + {6144, 6215, 8982, 11940, 6262, 6009, 8433, 11216, 8982, 8433, 10240, 12479, 11781, 11090, 12479, 13988, 5817}, + {20480, 20480, 11216, 12109, 20480, 20480, 11216, 11940, 11629, 11485, 11940, 12479, 12479, 12109, 12683, 13138, + 704}, + {7928, 6994, 8239, 9733, 7218, 6539, 8147, 9892, 9812, 9105, 10240, 11629, 12109, 11216, 12109, 13138, 4167}, + {8640, 7724, 9233, 10970, 8013, 7185, 8483, 10150, 9656, 8694, 9656, 10970, 11348, 10334, 11090, 12288, 3391}, + {20480, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, 18432, + 91}, + {10061, 8863, 9733, 11090, 8982, 7970, 8806, 9976, 10061, 9105, 9812, 10742, 11485, 10334, 10970, 11781, 2557}, + {10431, 9368, 10240, 11348, 9368, 8433, 9233, 10334, 10431, 9437, 10061, 10970, 11781, 10635, 11216, 11940, 2119}, + {13988, 12479, 12683, 12902, 12683, 11348, 11485, 11940, 12902, 11629, 11940, 12288, 13396, 12109, 12479, 12683, + 828}, + {10431, 9300, 10334, 11629, 9508, 8483, 9437, 10635, 10635, 9656, 10431, 11348, 11940, 10854, 11485, 12288, 1946}, + {12479, 11216, 11629, 12479, 11348, 10150, 10635, 11348, 11940, 10854, 11216, 11940, 12902, 11629, 11940, 12479, + 1146}, + {13396, 12109, 12288, 12902, 12109, 10854, 11216, 11781, 12479, 11348, 11629, 12109, 13138, 11940, 12288, 12683, + 928}, + {2443, 5289, 11629, 16384, 5170, 6730, 11940, 16384, 11216, 11629, 14731, 18432, 15725, 15725, 18432, 20480, 13396}, + {3328, 5009, 10531, 15186, 5040, 6031, 10531, 14731, 10431, 10431, 13396, 16384, 15186, 14731, 16384, 18432, 11629}, + {14336, 12902, 12902, 13396, 12902, 11629, 11940, 12288, 13138, 12109, 12288, 12902, 13677, 12683, 12902, 13138, + 711}, + {4300, 5204, 9437, 13396, 5430, 5776, 9300, 12902, 9656, 9437, 11781, 14731, 13396, 12902, 14731, 16384, 8982}, + {5394, 5776, 8982, 12288, 5922, 5901, 8640, 11629, 9105, 8694, 10635, 13138, 12288, 11629, 13138, 14731, 6844}, + {17234, 15725, 15725, 15725, 15725, 14731, 14731, 14731, 16384, 14731, 14731, 15186, 16384, 15186, 15186, 15186, + 272}, + {6461, 6286, 8806, 11348, 6566, 6215, 8334, 10742, 9233, 8535, 10061, 12109, 11781, 10970, 12109, 13677, 5394}, + {6674, 6487, 8863, 11485, 6702, 6286, 8334, 10635, 9168, 8483, 9976, 11940, 11629, 10854, 11940, 13396, 5105}, + {15186, 13677, 13677, 13988, 13677, 12479, 12479, 12683, 13988, 12683, 12902, 13138, 14336, 13138, 13396, 13677, + 565}, + {7844, 7252, 8922, 10854, 7389, 6815, 8383, 10240, 9508, 8750, 9892, 11485, 11629, 10742, 11629, 12902, 3842}, + {9233, 8239, 9233, 10431, 8334, 7424, 8483, 9892, 10061, 9105, 10061, 11216, 11781, 10742, 11485, 12479, 2906}, + {20480, 20480, 14731, 14731, 20480, 20480, 14336, 14336, 15186, 14336, 14731, 14731, 15186, 14731, 14731, 15186, + 266}, + {10531, 9300, 9976, 11090, 9437, 8286, 9042, 10061, 10431, 9368, 9976, 10854, 11781, 10531, 11090, 11781, 2233}, + {11629, 10334, 10970, 12109, 10431, 9368, 10061, 10970, 11348, 10240, 10854, 11485, 12288, 11216, 11629, 12288, + 1469}, + {952, 6787, 15725, 20480, 6646, 9733, 16384, 20480, 14731, 15725, 18432, 20480, 18432, 20480, 20480, 20480, 18432}, + {9437, 8806, 10742, 12288, 8982, 8483, 9892, 11216, 10742, 9892, 10854, 11940, 12109, 11090, 11781, 12683, 1891}, + {12902, 11629, 11940, 12479, 11781, 10531, 10854, 11485, 12109, 10970, 11348, 11940, 12902, 11781, 12109, 12479, + 1054}, + {2113, 5323, 11781, 16384, 5579, 7252, 12288, 16384, 11781, 12288, 15186, 18432, 15725, 16384, 18432, 20480, 12902}, + {2463, 5965, 11348, 15186, 5522, 6934, 11216, 14731, 10334, 10635, 13677, 16384, 13988, 13988, 15725, 18432, 10334}, + {3779, 5541, 9812, 13677, 5467, 6122, 9656, 13138, 9581, 9437, 11940, 14731, 13138, 12683, 14336, 16384, 8982}, + {3181, 5154, 10150, 14336, 5448, 6311, 10334, 13988, 10334, 10431, 13138, 15725, 14336, 13988, 15725, 18432, 10431}, + {4841, 5560, 9105, 12479, 5756, 5944, 8922, 12109, 9300, 8982, 11090, 13677, 12479, 12109, 13677, 15186, 7460}, + {5859, 6009, 8922, 11940, 6144, 5987, 8483, 11348, 9042, 8535, 10334, 12683, 11940, 11216, 12683, 14336, 6215}, + {4250, 4916, 8587, 12109, 5901, 6191, 9233, 12288, 10150, 9892, 11940, 14336, 13677, 13138, 14731, 16384, 8383}, + {7153, 6702, 8863, 11216, 6904, 6410, 8239, 10431, 9233, 8433, 9812, 11629, 11629, 10742, 11781, 13138, 4753}, + {6674, 7057, 9508, 11629, 7120, 6964, 8806, 10635, 9437, 8750, 10061, 11629, 11485, 10531, 11485, 12683, 4062}, + {5341, 5289, 8013, 10970, 6311, 6262, 8640, 11090, 10061, 9508, 11090, 13138, 12902, 12288, 13396, 15186, 6539}, + {8057, 7533, 9300, 11216, 7685, 7057, 8535, 10334, 9508, 8694, 9812, 11216, 11485, 10431, 11348, 12479, 3541}, + {9168, 8239, 9656, 11216, 8483, 7608, 8806, 10240, 9892, 8982, 9812, 11090, 11485, 10431, 11090, 12109, 2815}, + {558, 7928, 18432, 20480, 7724, 12288, 20480, 20480, 18432, 20480, 20480, 20480, 20480, 20480, 20480, 20480, 20480}, + {9892, 8806, 9976, 11348, 9042, 8057, 9042, 10240, 10240, 9233, 9976, 11090, 11629, 10531, 11216, 12109, 2371}, + {11090, 9812, 10531, 11629, 9976, 8863, 9508, 10531, 10854, 9733, 10334, 11090, 11940, 10742, 11216, 11940, 1821}, + {7354, 6964, 9042, 11216, 7153, 6592, 8334, 10431, 9233, 8483, 9812, 11485, 11485, 10531, 11629, 12902, 4349}, + {11348, 10150, 10742, 11629, 10150, 9042, 9656, 10431, 10854, 9812, 10431, 11216, 12109, 10970, 11485, 12109, 1700}, + {20480, 20480, 8694, 10150, 20480, 20480, 8982, 10240, 8982, 9105, 9976, 10970, 10431, 10431, 11090, 11940, 1610}, + {9233, 8192, 9368, 10970, 8286, 7496, 8587, 9976, 9812, 8863, 9733, 10854, 11348, 10334, 11090, 11940, 3040}, + {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] = { + {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}, + {20480, 20480, 20480, 20480, 18432, 13396, 8982, 4767, 3779, 3658, 6335, 9656, 13988, 20480, 20480, 20480, 20480}, + {20480, 20480, 20480, 20480, 20480, 14731, 9437, 4275, 3249, 3493, 8483, 13988, 17234, 20480, 20480, 20480, 20480}, + {20480, 20480, 20480, 20480, 20480, 20480, 12902, 4753, 3040, 2953, 9105, 15725, 20480, 20480, 20480, 20480, 20480}, + {20480, 20480, 20480, 20480, 20480, 20480, 12902, 3821, 3346, 3000, 12109, 20480, 20480, 20480, 20480, 20480, + 20480}, + {20480, 20480, 20480, 20480, 20480, 20480, 15725, 3658, 20480, 1201, 10854, 18432, 20480, 20480, 20480, 20480, + 20480}}; + +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_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} +}; + +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}; + +/* 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}}; + +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}}; + +/* MDCT Windows */ + + +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}; + + +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}; + +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}; + +const LC3_INT MDCT_WINDOWS_LENGTHS_10ms[6] = {160, 320, 480, 640, 960, 1920}; /* Last 960 dummy */ + +const LC3_INT MDCT_WINDOWS_LENGTHS_2_5ms[6] = {40, 80, 120, 160, 240, 480}; + + +const LC3_INT MDCT_WINDOWS_LENGTHS_5ms[6] = {80, 160, 240, 320, 480, 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}; + +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}; + +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}; + +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}; + +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}; + +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}; + +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}; + +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}; + +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}; + +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}; + +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}; + + +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}; + + +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}; + +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}; + +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}; + +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}; + +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}; + + +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}; + +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}; + +/* Near Nyquist detector */ +const LC3_INT NN_thresh = 30; + + +const LC3_INT32 xavg_N_grp[5] = { 4, 5, 6, 7, 8 }; + + +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}; + + +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 +}; +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 +}; + + +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 }; + diff --git a/lib_lc3plus/constants.h b/lib_lc3plus/constants.h new file mode 100644 index 000000000..c0c9e286e --- /dev/null +++ b/lib_lc3plus/constants.h @@ -0,0 +1,203 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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 "defines.h" +#include "structs.h" + +/* DCT */ +extern const Complex dct2_16[16]; + +/* Ari coder */ +extern const LC3_INT ari_tns_order_cf[2][9]; +extern const LC3_INT ari_tns_freq_cf[8][18]; +extern const LC3_INT ari_spec_lookup_fl[4096]; +extern const LC3_INT ari_spec_cumfreq_fl[64][18]; +extern const LC3_INT ari_spec_bits_fl[64][17]; + +/* SNS */ +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]; + +/* 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]; + +extern const LC3_INT MDCT_WINDOWS_LENGTHS_10ms[6]; + +extern const LC3_INT MDCT_WINDOWS_LENGTHS_2_5ms[6]; + + +extern const LC3_INT MDCT_WINDOWS_LENGTHS_5ms[6]; + +/* Per band energy */ +extern const LC3_INT* ACC_COEFF_PER_BAND[6]; +extern const LC3_INT* ACC_COEFF_PER_BAND_HR[6]; + +extern const LC3_INT* ACC_COEFF_PER_BAND_2_5ms_HR[6]; +extern const LC3_INT* ACC_COEFF_PER_BAND_2_5ms[5]; + + +extern const LC3_INT* ACC_COEFF_PER_BAND_5ms_HR[6]; +extern const LC3_INT* ACC_COEFF_PER_BAND_5ms[5]; + +/* Near Nyquist detector */ +extern const LC3_INT NN_thresh; + + +extern const LC3_INT32 xavg_N_grp[5]; +extern const LC3_FLOAT *hannOla_wins[5]; +extern const LC3_INT32 gwlpr[MAX_LGW+1]; +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]; + +#endif diff --git a/lib_lc3plus/cutoff_bandwidth.c b/lib_lc3plus/cutoff_bandwidth.c new file mode 100644 index 000000000..642b2afda --- /dev/null +++ b/lib_lc3plus/cutoff_bandwidth.c @@ -0,0 +1,27 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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 "functions.h" + +void process_cutoff_bandwidth(LC3_FLOAT *d_fl, LC3_INT len, LC3_INT bw_bin) +{ + LC3_INT i = 0; + + if (len > bw_bin){ + for (i = -1; i < 3; i++) { + d_fl[bw_bin + i] = d_fl[bw_bin + i] * LC3_POW(2, -(i + 2)); + } + + for (i = bw_bin + 3; i < len; i++) { + d_fl[i] = 0; + } + } +} diff --git a/lib_lc3plus/dct4.c b/lib_lc3plus/dct4.c new file mode 100644 index 000000000..8fd5784b2 --- /dev/null +++ b/lib_lc3plus/dct4.c @@ -0,0 +1,95 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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 "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 = 0; + const int len = dct->length; + assert(input != output); + + for (i = 0; i < len / 2; i++) { + tmp1[i] = cmplx(input[i * 2], 0); + tmp1[len - i - 1] = cmplx(input[i * 2 + 1], 0); + } + + fft_apply(&dct->fft, tmp1, tmp2); + + for (i = 0; i < len; 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 = 0; + 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 / 2; 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 / 2; 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/dec_entropy.c b/lib_lc3plus/dec_entropy.c new file mode 100644 index 000000000..d8512a106 --- /dev/null +++ b/lib_lc3plus/dec_entropy.c @@ -0,0 +1,277 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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 "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); + +void read_bit_fl(LC3_UINT8* ptr, LC3_INT* mask_side, LC3_INT* bp_side, LC3_INT* bit) +{ + 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; + } +} + +void read_uint_fl(LC3_INT nbits, LC3_UINT8* ptr, LC3_INT* mask_side, LC3_INT* bp_side, LC3_INT* val) +{ + LC3_INT bit = 0, i = 0; + + read_bit_fl(ptr, mask_side, bp_side, val); + + for (i = 1; i < nbits; i++) { + read_bit_fl(ptr, mask_side, bp_side, &bit); + *val = *val + (bit << i); + } +} + +#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) +{ + 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) + { + return 1; + } + + *np_zero = 0; + + *total_padding = 0; + + bp_side = (nbbits - 1) >> 3; + mask_side = 1 << (8 - (nbbits - (bp_side << 3))); + + if (bp_side < 19 || bp_side >= LC3PLUS_MAX_BYTES) { + return 1; + } + + ptr = bytes; + + if (bw_cutoff_bits > 0) { + read_uint_fl(bw_cutoff_bits, ptr, &mask_side, &bp_side, &bw_cutoff_idx); + } + + read_uint_fl(nbits, ptr, &mask_side, &bp_side, &lastnz); + + lastnz_threshold = (1 << nbits) - 1 - 1; + + while (lastnz == lastnz_threshold) { + padding_len_bits = 16 - nbits - bw_cutoff_bits - 4; + + /*Read padding length*/ + read_uint_fl(padding_len_bits, ptr, &mask_side, &bp_side, &padding_len); + + /* Read 4 reserved bits */ + read_uint_fl(4, ptr, &mask_side, &bp_side, &val); + + if (ep_enabled == 0) + { + /* Discard padding length bytes */ + bp_side = bp_side - padding_len; + *total_padding = *total_padding + padding_len + 2; + } + else + { + *total_padding = *total_padding + 2; + *np_zero = *np_zero + padding_len; + } + + /* check if minimum payload size is reached */ + if ((nbbytes - (*total_padding + *np_zero)) < 20) { + return 1; + } + + /* Read bandwidth bits */ + if (bw_cutoff_bits > 0) { + read_uint_fl(bw_cutoff_bits, ptr, &mask_side, &bp_side, &bw_cutoff_idx); + } + + read_uint_fl(nbits, ptr, &mask_side, &bp_side, &lastnz); + } + + if (ep_enabled != 0) + { + *total_padding = *total_padding + *np_zero; + } + + 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) +{ + + LC3_INT plc_trigger_bw = 0, plc_trigger_last_nz = 0, plc_trigger_SNS1 = 0, plc_trigger_SNS2 = 0, tmp = 0, bit = 0, + submodeMSB = 0, i = 0, ltpf_tmp[3] = {0}, ind = 0, submodeLSB = 0, bp_side_local = 0, mask_side_local = 0; + 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); + + 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; + } + + /* Last non-zero tuple */ + read_uint_fl(ceil(LC3_LOGTWO(N / 2)), ptr, &mask_side_local, &bp_side_local, lastnz); + *lastnz = (*lastnz + 1) * 2; + + if (*lastnz > N) { + *bfi = plc_trigger_last_nz; + if (*bfi) { + return; + } + } + + /* LSB mode bit */ + read_bit_fl(ptr, &mask_side_local, &bp_side_local, lsbMode); + + /* Global gain */ + read_uint_fl(8, ptr, &mask_side_local, &bp_side_local, gg_idx); + + /* 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; + } + + /* 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; + } + } + + ind = floor(tmp / 2390004); + scf_idx[5] = tmp - ind * 2390004; + + 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; + } + + } else { + read_uint_fl(24, ptr, &mask_side_local, &bp_side_local, &tmp); + + if (tmp >= 16708096) { + *bfi = plc_trigger_SNS2; + if (*bfi) { + return; + } + } + + 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; + } + } + + scf_idx[2] = scf_idx[2] + submodeLSB; + + /* 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; + } + + for (i = 0; i < 3; i++) { + ltpf_idx[i] = ltpf_tmp[i]; + } + + /* 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; +} diff --git a/lib_lc3plus/dec_lc3_fl.c b/lib_lc3plus/dec_lc3_fl.c new file mode 100644 index 000000000..88c528b0f --- /dev/null +++ b/lib_lc3plus/dec_lc3_fl.c @@ -0,0 +1,365 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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 "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) + { +# ifdef ENABLE_025_DMS_MODE + case 25: + max_bw_stopband = max_bw_stopband >> 2; + break; +# endif +# ifdef ENABLE_050_DMS_MODE + case 50: + max_bw_stopband = max_bw_stopband >> 1; + break; +# endif +# ifdef ENABLE_075_DMS_MODE + 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); + + /* 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 + ); + + { + /* 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 new file mode 100644 index 000000000..d978fa4e1 --- /dev/null +++ b/lib_lc3plus/defines.h @@ -0,0 +1,238 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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 "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_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 + +#ifndef NO_POST_REL_CHANGES +/* Post-release non-bitexact changes */ + +#endif /* NO_POST_REL_CHANGES */ + +/* 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)) + +# 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 */ + +typedef int32_t LC3_INT32; + +# if defined(__xtensa__) +# define ALIGNMENT_BALLOC 4 +# define ALIGNMENT_BALLOC_RED 3 +# else +# define ALIGNMENT_BALLOC 8 +# define ALIGNMENT_BALLOC_RED 7 +# endif + +# define PLC2_FADEOUT_IN_MS 30 +# 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 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) */ + +# 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*/ +# 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 FEC_SLOT_BYTES_MIN 40 +# define FEC_SLOT_BYTES_MAX 400 + + +# 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 + +# define LC3_CONST_POW_2_100 1.267650600228229e+30 + +/* G192 bitstream writing/reading */ +#define G192_REDUNDANCY_FRAME 0x6B22 +#define G192_GOOD_FRAME 0x6B21 +#define G192_BAD_FRAME 0x6B20 +#define G192_ZERO 0x007F +#define G192_ONE 0x0081 +#define READ_G192FER /* Allow C executable to also read G192 formatted FER files */ + +# define LC3_EPS (1.1e-7f) + +#define M_PI 3.14159265358979323846 + +/* FUNCTION MACROS */ +#define CEILING(x, y) (((x) + (y)-1) / (y)) +#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 \ + */ +#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__) + +/* 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)) + +/* OPTIONS */ + +#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 MAX_CHANNELS 2 +#define MIN_NBYTES 20 /* 100dms: 16 kbps at !=44.1kHz, 14.7kbps at 44.1kHz + 50dms: 32 kbps at !=44.1kHz, 29.4kbps at 44.1kHz + 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_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) +#define MAX_BW_BIN 400 +#if MAX_BW_BIN > MAX_LEN +# define MAX_BW MAX_LEN +#else +# define MAX_BW MAX_BW_BIN +#endif + +# ifdef ENABLE_HR_MODE_FL +# define MAX_BW_HR 960 +# endif + +/* SCF */ +#define M 16 +#define MAX_BANDS_NUMBER 64 +#define MAX_BANDS_NUMBER_PLC 80 +#define PVQ_MAX_VEC_SIZE M + +/* PVQ VQ setup */ +#define SCF_MAX_PARAM \ + 7 /* (L+H) + submode_MSB +gain+(Ia_leads+Ia_mpvq)+(Ib_joint_mpvq), \ + submode-LSB */ + +/* RESIDUAL CODING */ +#define NPRM_RESQ 5 * MAX_LEN + +/* MDCT */ +#define MDCT_MEM_LEN_MAX (MAX_LEN - ((180 * MAX_LEN) / 480)) + +/* TNS */ +#define TNS_NUMFILTERS_MAX 2 +#define MAXLAG 8 + +/* OLPA/LTPF */ +#define LEN_12K8 128 +#define LEN_6K4 64 +#define MIN_PITCH_6K4 17 +#define MAX_PITCH_6K4 114 +#define RANGE_PITCH_6K4 98 +#define MIN_PITCH_12K8 32 +#define MAX_PITCH_12K8 228 +#define RES2_PITCH_12K8 157 +#define RES4_PITCH_12K8 127 +#define LTPF_MEMIN_LEN (MAX_PITCH_12K8 + 4) + +/* Advanced PLC */ + + + +/* some configurations leave empty translation units. */ +extern int fix_empty_translation_unit_warning; + +#endif diff --git a/lib_lc3plus/detect_cutoff_warped.c b/lib_lc3plus/detect_cutoff_warped.c new file mode 100644 index 000000000..939286720 --- /dev/null +++ b/lib_lc3plus/detect_cutoff_warped.c @@ -0,0 +1,84 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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 "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 = NULL, *warp_idx_stop = NULL; + LC3_INT counter = 0, brickwall = 0, i = 0, stop = 0, dist = 0; + LC3_FLOAT d2_mean = 0, d2_sum = 0, e_diff = 0, thr = 0; + const LC3_INT *bw_dist = NULL; + + 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; + 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/enc_entropy.c b/lib_lc3plus/enc_entropy.c new file mode 100644 index 000000000..a7ff8cd70 --- /dev/null +++ b/lib_lc3plus/enc_entropy.c @@ -0,0 +1,126 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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 "functions.h" + +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 + ) +{ + LC3_UINT8* ptr; + LC3_INT i = 0, submodeMSB = 0, submodeLSB = 0, tmp = 0, gainMSB = 0, gainLSB = 0; + LC3_INT gainMSBbits[4] = {1, 1, 2, 2}, gainLSBbits[4] = {0, 1, 0, 1}; + + LC3_INT16 lastnzTrigger[5] = {63, 127, 127, 255, 255}; + + *bp_side = numbytes - 1; + *mask_side = 1; + ptr = bytes; + + /* Bandwidth */ + if (bw_cutoff_bits > 0) { + write_uint_backward_fl(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))); + } + else + { + write_uint_backward_fl(ptr, bp_side, mask_side, lastnz / 2 - 1, ceil(LC3_LOGTWO(N / 2))); + } + + /* LSB mode bit */ + write_bit_backward_fl(ptr, bp_side, mask_side, lsbMode); + + /* Global gain */ + write_uint_backward_fl(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])); + } + + /* 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; + } + + 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; + } + + write_uint_backward_fl(ptr, bp_side, mask_side, tmp, 24); + } + + /* 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); + } + + /* Noise factor */ + write_uint_backward_fl(ptr, bp_side, mask_side, fac_ns_idx, 3); +} + +void write_uint_backward_fl(LC3_UINT8* ptr, LC3_INT* bp_side, LC3_INT* mask_side, LC3_INT val, LC3_INT numbits) +{ + LC3_INT k = 0, bit = 0; + + for (k = 0; k < numbits; k++) { + bit = val & 1; + write_bit_backward_fl(ptr, bp_side, mask_side, bit); + val = val / 2; + } +} + +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] & (255 - *mask_side); + } else { + 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 * 2; + } +} diff --git a/lib_lc3plus/enc_lc3_fl.c b/lib_lc3plus/enc_lc3_fl.c new file mode 100644 index 000000000..c89f7244c --- /dev/null +++ b/lib_lc3plus/enc_lc3_fl.c @@ -0,0 +1,270 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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 "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, &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); + + /* 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); + + /* 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->tilt, encoder->bands_number, h_EncSetup->scf, + h_EncSetup->attdec_detected, encoder->sns_damping, encoder->attdec_damping); + + /* 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 new file mode 100644 index 000000000..df9b1f5f2 --- /dev/null +++ b/lib_lc3plus/estimate_global_gain.c @@ -0,0 +1,128 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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 "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 = 0, N = 0, offset = 0, j = 0, iszero = 0; + LC3_FLOAT g_min = 0, x_max = 0, tmp = 0, ind = 0, ind_min = 0, target = 0, fac = 0, ener = 0; + LC3_FLOAT en[MAX_LEN / 4] = {0}; + 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_LOGTEN 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 * 0.5; + 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/fft/cfft.c b/lib_lc3plus/fft/cfft.c new file mode 100644 index 000000000..4bd8d29ad --- /dev/null +++ b/lib_lc3plus/fft/cfft.c @@ -0,0 +1,421 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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 "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 new file mode 100644 index 000000000..3902b4c39 --- /dev/null +++ b/lib_lc3plus/fft/cfft.h @@ -0,0 +1,42 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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" + +#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 new file mode 100644 index 000000000..83ca77353 --- /dev/null +++ b/lib_lc3plus/fft/fft_15_16.h @@ -0,0 +1,401 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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 new file mode 100644 index 000000000..c1d96c87b --- /dev/null +++ b/lib_lc3plus/fft/fft_240_480.h @@ -0,0 +1,185 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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 new file mode 100644 index 000000000..54f4f839d --- /dev/null +++ b/lib_lc3plus/fft/fft_2_9.h @@ -0,0 +1,278 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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 new file mode 100644 index 000000000..48b891108 --- /dev/null +++ b/lib_lc3plus/fft/fft_32.h @@ -0,0 +1,467 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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 new file mode 100644 index 000000000..47f42e90d --- /dev/null +++ b/lib_lc3plus/fft/fft_384_768.h @@ -0,0 +1,103 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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 new file mode 100644 index 000000000..75f1aaef4 --- /dev/null +++ b/lib_lc3plus/fft/fft_60_128.h @@ -0,0 +1,161 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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 new file mode 100644 index 000000000..e517ffb25 --- /dev/null +++ b/lib_lc3plus/fft/fft_generic.h @@ -0,0 +1,699 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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 new file mode 100644 index 000000000..b1f8ab5ab --- /dev/null +++ b/lib_lc3plus/fft/iis_fft.c @@ -0,0 +1,164 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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 +#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 new file mode 100644 index 000000000..b658930fa --- /dev/null +++ b/lib_lc3plus/fft/iis_fft.h @@ -0,0 +1,142 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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 "../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 new file mode 100644 index 000000000..227d2b603 --- /dev/null +++ b/lib_lc3plus/fft/iisfft.c @@ -0,0 +1,166 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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 +#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 new file mode 100644 index 000000000..7b448e2bb --- /dev/null +++ b/lib_lc3plus/fft/iisfft.h @@ -0,0 +1,86 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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 "../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/functions.h b/lib_lc3plus/functions.h new file mode 100644 index 000000000..7a529a25d --- /dev/null +++ b/lib_lc3plus/functions.h @@ -0,0 +1,304 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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 "clib.h" +#include "defines.h" +#include "float.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); + +#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 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 processMdctShaping_fl(LC3_FLOAT x[], LC3_FLOAT gains[], const LC3_INT bands_offset[], LC3_INT fdns_npts); + +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 processResidualDecoding_fl(LC3_INT* bitsRead, LC3_FLOAT x[], LC3_INT L_spec, uint8_t prm[], LC3_INT resQBits + , LC3_INT hrmode +); + +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 processApplyGlobalGain_fl(LC3_FLOAT x[], LC3_INT xLen, LC3_INT global_gain_idx, LC3_INT global_gain_off); + +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 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 processOlpa_fl(LC3_FLOAT* s_12k8, LC3_FLOAT* mem_s12k8, LC3_FLOAT* mem_s6k4, LC3_INT* mem_old_T0, 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); + +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); + +void processSnsComputeScf_fl(LC3_FLOAT* x, LC3_INT tilt, LC3_INT xLen, LC3_FLOAT* gains, LC3_INT smooth, LC3_FLOAT sns_damping, LC3_FLOAT attdec_damping_factor); + +void processSnsInterpolateScf_fl(LC3_FLOAT* gains, LC3_INT encoder_side, LC3_INT bands_number, LC3_FLOAT* gains_LC3_INT); + +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); + +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); + +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); + +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); + +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 +); + +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 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 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 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_snsQuantizesScf_Enc(LC3_FLOAT* env, LC3_INT* index, LC3_FLOAT* envq, Dct2 dct2structSNS); + +void process_snsQuantizesScf_Dec(LC3_INT* scf_idx, LC3_FLOAT* scf_q); + +void processMdct_fl(LC3_FLOAT* in, LC3_FLOAT* out, Mdct* mdctStruct); + +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); + +LC3PLUS_Error FillEncSetup(LC3PLUS_Enc* encoder, int samplerate, int channels, int hrmode, int32_t lfe_channel_array[]); + +/* 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); + +LC3PLUS_Error FillDecSetup(LC3PLUS_Dec* decoder, int samplerate, int channels, LC3PLUS_PlcMode plc_mode, int hrmode); + +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* balloc(void* base, size_t* base_size, size_t size); + +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 processPlcUpdateSpec_fl(LC3_FLOAT *q_d_prev, LC3_FLOAT *q_d_fl_c, LC3_INT yLen); + +void processNoiseSubstitution_fl(LC3_FLOAT* spec, LC3_FLOAT* spec_prev, LC3_INT32 yLen); + +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); + +/* 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 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 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, 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); +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 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 +); + +void processTdcPreemphasis_fl(LC3_FLOAT *in, LC3_FLOAT *pre_emph_factor, LC3_INT32 n_bands); + +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 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); +void* balloc(void* base, size_t* base_size, size_t size); + + + +#endif diff --git a/lib_lc3plus/imdct.c b/lib_lc3plus/imdct.c new file mode 100644 index 000000000..5d38aa6cc --- /dev/null +++ b/lib_lc3plus/imdct.c @@ -0,0 +1,102 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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 "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] = {0}, x_ov[2 * MAX_LEN] = {0}; + LC3_INT i = 0, j = 0; + + /* 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] = {0}; + 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/lc3.c b/lib_lc3plus/lc3.c new file mode 100644 index 000000000..17d2ccb71 --- /dev/null +++ b/lib_lc3plus/lc3.c @@ -0,0 +1,431 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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 "lc3.h" +#include "defines.h" +#include "functions.h" +#include + +#include "setup_dec_lc3.h" +#include "setup_enc_lc3.h" + +#define RETURN_IF(cond, error) \ + if (cond) \ + return (error) + +/* 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); + +/* misc functions ************************************************************/ + +int lc3plus_version(void) +{ + return LC3PLUS_VERSION; +} + +int lc3plus_channels_supported(int channels) +{ + return channels >= 1 && channels <= MAX_CHANNELS; +} + +int lc3plus_samplerate_supported(int samplerate) +{ + switch (samplerate) + { + case 8000: return 1; + case 16000: return 1; + case 24000: return 1; + case 32000: return 1; + case 44100: return 1; + case 48000: return 1; + case 96000: return 1; + default: break; + } + return 0; +} + +static int lc3plus_plc_mode_supported(LC3PLUS_PlcMode plc_mode) +{ + switch ((int)plc_mode) + { + case LC3PLUS_PLC_ADVANCED: /* fallthru */ + return 1; + default: break; + } + return 0; +} + +static int lc3plus_frame_size_supported(float frame_ms) +{ + switch ((int)(ceil(frame_ms * 10))) + { + case 25: /* fallthru */ + case 50: /* fallthru */ + case 100: return 1; + default: break; + } + return 0; +} + +static int null_in_list(void **list, int n) +{ + while (--n >= 0) + RETURN_IF(list[n] == NULL, 1); + return 0; +} + +/* return pointer to aligned base + base_size, *base_size += size + 4 bytes align */ +void *balloc(void *base, size_t *base_size, size_t size) +{ + uintptr_t ptr = ((uintptr_t)base + *base_size + 3) & ~3; + assert((uintptr_t)base % 4 == 0); /* base must be 4-byte aligned */ + *base_size = (*base_size + size + 3) & ~3; + return (void *)ptr; +} + +int32_t lc3_enc_supported_lfe(void) +{ + return 1; +} + +/* encoder functions *********************************************************/ +LC3PLUS_Error lc3plus_enc_init(LC3PLUS_Enc *encoder, int samplerate, int channels, int hrmode, 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); + RETURN_IF(samplerate==96000 && hrmode == 0, LC3PLUS_HRMODE_ERROR); + + 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 */ +} + +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); +} + +/* Dummy function for API alignment */ +int lc3plus_enc_get_scratch_size(const LC3PLUS_Enc *encoder) +{ + UNUSED(encoder); + return 0; +} + +int lc3plus_enc_get_input_samples(const LC3PLUS_Enc *encoder) +{ + RETURN_IF(encoder == NULL, 0); + return encoder->frame_length; +} + +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); +} + +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); + + for (ch = 0; ch < encoder->channels; ch++) + { + totalBytes += encoder->channel_setup[ch]->targetBytes; + } + + bitrate = (totalBytes * 80000.0 + encoder->frame_dms - 1) / encoder->frame_dms; + + if (encoder->fs_in == 44100) + { + int rem = bitrate % 480; + bitrate = ((bitrate - rem) / 480) * 441 + (rem * 441) / 480; + } + + 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); +} + +int lc3plus_enc_get_delay(const LC3PLUS_Enc *encoder) +{ + RETURN_IF(encoder == NULL, 0); + return encoder->frame_length - 2 * encoder->la_zeroes; +} + +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(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; + if (encoder->bandwidth != bandwidth) { + if (encoder->fs_in > 40000) { + effective_fs = 40000; + } + if ((bandwidth * 2) > effective_fs) { + return LC3PLUS_BW_WARNING; + } + else { + encoder->bandwidth = bandwidth; + encoder->bandwidth_preset = bandwidth; + encoder->bw_ctrl_active = 1; + update_enc_bitrate(encoder, encoder->bitrate); + } + } + return LC3PLUS_OK; +} + + +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, 16, output_bytes, num_bytes); +} + +LC3PLUS_Error lc3plus_enc24(LC3PLUS_Enc* encoder, int32_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); +} + + +LC3PLUS_Error lc3plus_enc_fl(LC3PLUS_Enc* encoder, void** input_samples, int bitdepth, void* output_bytes, int* num_bytes) +{ + 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; +} + +/* decoder functions *********************************************************/ + +LC3PLUS_Error lc3plus_dec_init(LC3PLUS_Dec* decoder, int samplerate, int channels, LC3PLUS_PlcMode plc_mode, int hrmode) +{ + 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); + RETURN_IF(samplerate==96000 && hrmode == 0, LC3PLUS_HRMODE_ERROR); + return FillDecSetup(decoder, samplerate, channels, plc_mode, hrmode); +} + +int lc3plus_dec_get_size(int samplerate, int channels) +{ + RETURN_IF(!lc3plus_samplerate_supported(samplerate), 0); + RETURN_IF(!lc3plus_channels_supported(channels), 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; +} + +LC3PLUS_Error lc3plus_dec_set_frame_dms(LC3PLUS_Dec *decoder, int frame_dms) +{ + 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); + return LC3PLUS_OK; +} + +int lc3plus_dec_get_output_samples(const LC3PLUS_Dec* decoder) +{ + RETURN_IF(decoder == NULL, 0); + return decoder->frame_length; +} + +int lc3plus_dec_get_delay(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; +} + +LC3PLUS_Error lc3plus_free_encoder_structs(LC3PLUS_Enc* encoder) +{ + 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; +} + +LC3PLUS_Error lc3plus_free_decoder_structs(LC3PLUS_Dec* decoder) +{ + 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 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) +{ + RETURN_IF(decoder == NULL, 0); + return decoder->error_report == 2047 ? -1 : decoder->error_report & 0x07FF; +} + +LC3PLUS_Error lc3plus_enc_set_ep_mode(LC3PLUS_Enc *encoder, LC3PLUS_EpMode epmode) +{ + 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; +} + +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_EPMODE_ERROR); + encoder->epmr = epmr; + return LC3PLUS_OK; +} + +LC3PLUS_Error lc3plus_dec_set_ep_enabled(LC3PLUS_Dec *decoder, int32_t ep_enabled) +{ + RETURN_IF(decoder == NULL, LC3PLUS_NULL_ERROR); + decoder->ep_enabled = ep_enabled != 0; + decoder->epmr = LC3PLUS_EPMR_ZERO; + return LC3PLUS_OK; +} + +int lc3plus_dec_get_epok_flags(const LC3PLUS_Dec *decoder) +{ + RETURN_IF(decoder == NULL, 0); + return decoder->error_report >> 11; +} + +#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 new file mode 100644 index 000000000..3e45438fe --- /dev/null +++ b/lib_lc3plus/lc3.h @@ -0,0 +1,517 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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. + * + * 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. + * + * Depending on the build configuration some functions might not be available. + */ + +#ifndef LC3PLUS_H +#define LC3PLUS_H + +#ifndef _MSC_VER +#include +#else +typedef unsigned char uint8_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, 6, 9) + +/*! 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. + */ +#define LC3PLUS_MAX_SAMPLES 960 + +/*! Maximum number of bytes of one LC3plus frame. */ +#define LC3PLUS_MAX_BYTES 1250 + +/*! Maximum size needed to store encoder state. */ +#define LC3PLUS_ENC_MAX_SIZE 20392 + +/*! Maximum size needed to store decoder state. */ +#define LC3PLUS_DEC_MAX_SIZE 87528 + +/*! Error codes returned by functions. */ +typedef enum +{ + LC3PLUS_PLC_ADVANCED = 1 /*!< Enhanced concealment method */ +} LC3PLUS_PlcMode; + +/*! Error protection mode. LC3PLUS_EP_ZERO differs to LC3PLUS_EP_OFF in that + * errors can be detected but not corrected. */ +typedef enum +{ + LC3PLUS_EP_OFF = 0, /*!< Error protection is disabled */ + LC3PLUS_EP_ZERO = 1, /*!< Error protection with 0 bit correction */ + LC3PLUS_EP_LOW = 2, /*!< Error protection correcting one symbol per codeword */ + LC3PLUS_EP_MEDIUM = 3, /*!< Error protection correcting two symbols per codeword */ + LC3PLUS_EP_HIGH = 4 /*!< Error protection correcting three symbols per codeword */ +} LC3PLUS_EpMode; + +/*! Error protection mode request. On the encoder sidem, LC3PLUS_EPMR_ZERO to LC3PLUS_EPMR_HIGH + * can be set. The decoder returns mode requests with different confidences. */ +typedef enum +{ + LC3PLUS_EPMR_ZERO = 0, /*!< Request no error correction. High confidence if returned by decoder. */ + LC3PLUS_EPMR_LOW = 1, /*!< Request low error correction. High confidence if returned by decoder. */ + LC3PLUS_EPMR_MEDIUM = 2, /*!< Request medium error correction. High confidence if returned by decoder. */ + LC3PLUS_EPMR_HIGH = 3, /*!< Request high error correction. High confidence if returned by decoder. */ + LC3PLUS_EPMR_ZERO_MC = 4, /*!< No error correction requested, medium confidence. */ + LC3PLUS_EPMR_LOW_MC = 5, /*!< Low error correction requested, medium confidence. */ + LC3PLUS_EPMR_MEDIUM_MC = 6, /*!< Medium error correction requested, medium confidence. */ + LC3PLUS_EPMR_HIGH_MC = 7, /*!< High error correction requested, medium confidence. */ + LC3PLUS_EPMR_ZERO_NC = 8, /*!< No error correction requested, unvalidated. */ + LC3PLUS_EPMR_LOW_NC = 9, /*!< Low error correction requested, unvalidated. */ + LC3PLUS_EPMR_MEDIUM_NC = 10, /*!< Medium error correction requested, unvalidated. */ + LC3PLUS_EPMR_HIGH_NC = 11 /*!< High error correction requested, unvalidated. */ +} LC3PLUS_EpModeRequest; + +/*! Error codes returned by functions. */ +typedef enum +{ + LC3PLUS_OK = 0, /*!< No error occurred */ + LC3PLUS_ERROR = 1, /*!< Function call failed */ + LC3PLUS_DECODE_ERROR = 2, /*!< Frame failed to decode and was concealed */ + LC3PLUS_NULL_ERROR = 3, /*!< Pointer argument is null */ + LC3PLUS_SAMPLERATE_ERROR = 4, /*!< Invalid samplerate value */ + LC3PLUS_CHANNELS_ERROR = 5, /*!< Invalid channels value */ + LC3PLUS_BITRATE_ERROR = 6, /*!< Invalid bitrate value */ + LC3PLUS_NUMBYTES_ERROR = 7, /*!< Invalid num_bytes value */ + LC3PLUS_EPMODE_ERROR = 8, /*!< Invalid plc_method value */ + LC3PLUS_FRAMEMS_ERROR = 9, /*!< Invalid epmode value */ + LC3PLUS_ALIGN_ERROR = 10, /*!< Invalid frame_ms value */ + LC3PLUS_HRMODE_ERROR = 11, /*!< Unaligned pointer */ + LC3PLUS_BITRATE_UNSET_ERROR = 12, /*!< Invalid epmr value */ + LC3PLUS_BITRATE_SET_ERROR = 13, /*!< Invalid usage of hrmode, sampling rate and frame size */ + LC3PLUS_HRMODE_BW_ERROR = 14, /*!< Function called before bitrate has been set */ + LC3PLUS_PLCMODE_ERROR = 15, /*!< Function called after bitrate has been set */ + LC3PLUS_EPMR_ERROR = 16, /*!< Invalid external bad frame index */ + LC3PLUS_PADDING_ERROR = 17, /*!< Incorrect padding value */ + FRAMESIZE_ERROR = 18, /*!< Incorrect frame size during decoding */ + LC3PLUS_LFE_MODE_NOT_SUPPORTED = 19, /*!< LFE support not available */ + + /* START WARNING */ + LC3PLUS_WARNING = 20, + LC3PLUS_BW_WARNING = 21 /*!< Invalid bandwidth cutoff frequency */ + +} LC3PLUS_Error; + +typedef struct LC3PLUS_Enc LC3PLUS_Enc; /*!< Opaque encoder struct. */ +typedef struct LC3PLUS_Dec LC3PLUS_Dec; /*!< Opaque decoder struct. */ + +/*! \addtogroup Misc + * \{ */ + +/*! Test LFE mode support. + * + * Tests the support of the LFE mode. + * + * \return 1 for true, 0 for false. + */ +int32_t lc3_enc_supported_lfe(void); + +/*! Return library version number. It should match LC3PLUS_VERSION. */ +int lc3plus_version(void); + +/*! Tests if the library supports number of channels. + * + * \param[in] channels Number of channels. + * \return 1 for true, 0 for false. + */ +int lc3plus_channels_supported(int channels); + +/*! Tests if the library supports a sampling rate. + * + * \param[in] samplerate Sampling rate + * \return 1 for true, 0 for false + */ +int lc3plus_samplerate_supported(int samplerate); + +/*! \} + * \addtogroup Encoder + * \{ */ + +/*! + * Initialize LC3plus encoder. + * + * This function is used to fill a user-allocated encoder struct. This is typically + * called once for a samplerate / channel configuration. After init and before encoding + * the first frame you must call lc3plus_enc_set_bitrate(). + * + * \param[out] encoder Pointer to allocated encoder memory. It must have a size provided + * by lc3plus_enc_get_size() for matching samplerate / channels + * configuration or LC3PLUS_ENC_MAX_SIZE. + * \param[in] channels Number of channels. + * \param[in] samplerate Input sampling rate. Allowed sampling rates are: + * 8000, 16000, 24000, 32000, 44100, 48000 + * \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[]); + +/*! + * 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], + * the right channel in input_samples[1]. The input is not changed + * by the encoder. + * \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. + * \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 +); + +/*! 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); + +/*! 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. + * \return Size in bytes or 0 on error. + */ +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. + * + * \param[in] encoder Encoder handle. + * \return Size in bytes or 0 on error. + */ +int lc3plus_enc_get_scratch_size(const LC3PLUS_Enc *encoder); + +/*! Get number of samples per channel expected by lc3plus_enc16() or lc3plus_enc24(). + * + * \param[in] encoder Encoder handle. + * \return Number of samples or 0 on error. + */ +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. + * + * \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); + +/*! 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(). + * + * \param[in] encoder Encoder handle. + * \return Size in bytes or 0 on error. + */ +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(). + * + * Recommended bitrates for input sampling rates with 10 ms framing: + * kHz | kbps + * --------|----- + * 8 | 24 + * 16 | 32 + * 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); + +/*! 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 + * + * \param[in] encoder Encoder handle. + * \param[in] lfe LFE mode flag + * \return LC3PLUS_OK on success or appropriate error code. + */ +LC3PLUS_Error lc3plus_enc_set_lfe(LC3PLUS_Enc* encoder, int lfe); + +/*! Free memory allocated within LC3plus encoder struct. + * + * \param[in] encoder Encoder handle. + * \return LC3PLUS_OK on success or appropriate error code. + */ +LC3PLUS_Error lc3plus_enc_free_memory(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. + * + * \param[in] encoder Encoder handle. + * \param[in] bandwidth Cutoff Frequency in Hz + * \return LC3PLUS_OK on success or appropriate error code. + */ +LC3PLUS_Error lc3plus_enc_set_bandwidth(LC3PLUS_Enc *encoder, int bandwidth); + +/*! Internal function called by lc3plus_enc_free_memory. + * + * \param[in] encoder Encoder handle. + * \return LC3PLUS_OK on success or appropriate error code. + */ +LC3PLUS_Error lc3plus_free_encoder_structs(LC3PLUS_Enc* encoder); + +/*! Sets error protection mode request transmitted in each channel encoded frame. + * The channel coder includes an error protection mode request (EPMR) in every frame. + * The EPMR takes value 0, 1, 2, and 3 which request ep modes 1, 2, 3, and 4 from the + * decoding device. The EPMR can be retrieved from the channel decoder via the interface + * routine lc3plus_dec_get_ep_mode_request(). + * + * \param[in] encoder Encoder handle. + * \param[in] epmr Error Protection Mode Request + * \return LC3PLUS_OK on success or appropriate error code. + */ +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. + * + * \param[in] encoder Encoder handle. + * \param[in] epmode Error protection mode. + * \return LC3PLUS_OK on success or appropriate error code. + */ +LC3PLUS_Error lc3plus_enc_set_ep_mode(LC3PLUS_Enc *encoder, LC3PLUS_EpMode epmode); + +/*! \} + * \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. + * + * 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. + * + * \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); + + + +/*! + * Decode compressed LC3plus frame to 16 bit PCM output. + * + * Each call decodes a fixed number of samples. Use lc3plus_dec_get_output_samples() to obtain this + * number. When the input is corrupted and can not be decoded, LC3PLUS_DECODE_ERROR is returned and + * packet loss concealment is applied, so the output is still usable. + * If error protection is enabled and the errors can be corrected the frame is corrected and + * normally decoded. Use lc3plus_dec_get_error_report() to check if errors were corrected. + * + * \param[in] decoder Decoder initialized by lc3plus_dec_init(). + * \param[in] input_bytes Input bytes. If error protection is enabled the input bytes can be + * altered when error correction is applied. This is why this buffer + * must be writable. + * \param[in] num_bytes Number of valid bytes in input_bytes. To signal a lost frame and + * generate concealment output this value must be set to 0. + * \param[out] output_samples Array of pointers to output channel buffers. Each channel buffer + * 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 + * \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); + +/*! 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); + +/* 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. + * + * \param[in] channels Number of channels. + * \param[in] samplerate Sampling rate. + * \return Size in bytes or 0 on error. + */ +int lc3plus_dec_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. + * + * \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. + * + * \param[in] decoder Decoder handle. + * \return Number of samples or 0 on error. + */ +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); + +/*! 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] 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. + * + * \param[in] decoder Decoder handle. + * \param[in] ep_enabled 1 (or any nonzero) for true, 0 for false. + * \return LC3PLUS_OK on success or appropriate error code. + */ +LC3PLUS_Error lc3plus_dec_set_ep_enabled(LC3PLUS_Dec *decoder, int ep_enabled); + +/*! Retrieves the error protection mode reqeust from channel decoder. + * + * The return value encodes both the error protection mode request (EPMR) + * and the confidence of the method by which it was retrieved. + * + * The requested error protection mode is (epmr % 4) + 1, where epmr is the + * function's return value. The confidence is specified as follows. + * + * Confidence | Range + * -----------|------------- + * high | 0 <= epmr < 4 + * medium | 4 <= epmr < 8 + * no | 8 <= epmr < 12 + * + * When receiving stereo content of separately channel encoded audio frames the + * return value is the minimum of two values retrieved from the individual channels. + * + * \param[in] decoder Decoder handle. + * \return Error protection mode reqeust. + */ +LC3PLUS_EpModeRequest lc3plus_dec_get_ep_mode_request(const LC3PLUS_Dec *decoder); + +/*! Get the number of corrected bit errors in the last decoded frame. This only works if + * error protection is active. If the number of errors is greater than the current error + * protection mode can correct, -1 is returned. If the last frame had no errors or the + * decoder handle is NULL, 0 is returned, + * + * \param[in] decoder Decoder handle. + * \return Number of corrected bits or -1. See description for details. + */ +int lc3plus_dec_get_error_report(const LC3PLUS_Dec *decoder); +/*! This function returns an set of flags indicating whether the last frame + * would have been channel decodable in epmode m, m ranging from 1 to 4. Note that + * this information is not available in case the last frame was not channel + * decodable in which case the return value is 0. If the last frame would have + * been decodable in epmode m, m-1th of the return value will be 1. + * Otherwise, if the frame would not have been decodable or if this information + * cannot be retrieved, the m-1th bit of the return value will be 0. + */ +int lc3plus_dec_get_epok_flags(const LC3PLUS_Dec *decoder); + +/*! \} */ +#endif /* LC3plus */ diff --git a/lib_lc3plus/lc3plus_fft.c b/lib_lc3plus/lc3plus_fft.c new file mode 100644 index 000000000..14f443f86 --- /dev/null +++ b/lib_lc3plus/lc3plus_fft.c @@ -0,0 +1,99 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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 "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/license.h b/lib_lc3plus/license.h new file mode 100644 index 000000000..d9d6c8967 --- /dev/null +++ b/lib_lc3plus/license.h @@ -0,0 +1,22 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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" + +static const char *const LICENSE = + "*******************************************************************************\n" + "* ETSI TS 103 634 V1.4.1 *\n" + "* Low Complexity Communication Codec Plus (LC3plus) *\n" + "* Floating 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" + "*******************************************************************************\n" + "\n"; diff --git a/lib_lc3plus/ltpf_coder.c b/lib_lc3plus/ltpf_coder.c new file mode 100644 index 000000000..fac8c481c --- /dev/null +++ b/lib_lc3plus/ltpf_coder.c @@ -0,0 +1,264 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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 "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 = 0; + 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) +{ + LC3_FLOAT buffer[LTPF_MEMIN_LEN + LEN_12K8 + 1 + (LEN_12K8 >> 2)] = {0}, sum = 0, buf_tmp[MAX_LEN] = {0}, cor_up[MAX_LEN] = {0}, *x; + LC3_INT i = 0, j = 0, k = 0, n = 0, step = 0, N = 0, ltpf_active = 0, pitch_search_delta = 0, + 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 norm_corr = 0, cor[MAX_LEN] = {0}, cor_int[MAX_LEN] = {0}, currFrame[MAX_LEN] = {0}, predFrame[MAX_LEN] = {0}, sum1 = 0, sum2 = 0, sum3 = 0; + LC3_FLOAT pitch = 0; + + /* 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; + + if (pitch_ol_norm_corr > 0.6) { + /* 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]; + } + + /* Compute Cross-Correlation */ + for (i = t_min; i <= t_max; i++) { + sum = 0; + for (j = 0; j < acflen; j++) { + sum += x[j] * x[j - i]; + } + + if (i > t_min) { + sum2 = sum2 + x[-i]*x[-i] + - x[acflen - 1 - ( i - 1 )]*x[acflen - 1 - ( i - 1 )]; + } + sum3 = LC3_SQRT(sum1 * sum2) + LC3_POW(10, -5); + norm_corr = sum / sum3; + + norm_corr = MAX(0, norm_corr); + cor[i - t_min] = norm_corr; + + } + + /* Find Integer Pitch-Lag */ + j = 0; + for (i = pitch_search_L_interpol1; i <= t_max - t_min - pitch_search_L_interpol1; i++) { + buf_tmp[j] = cor[i]; + j++; + } + + temp2 = searchMaxIndice(buf_tmp, j); + + 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 = 0; + + k = 0; + for (j = i; j < i + 32; j++) { + sum += cor_up[j] * inter4_1[k]; + k++; + } + + 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) { + buf_tmp[j] = cor_int[i]; + j++; + } + + temp2 = searchMaxIndice(buf_tmp, ((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; + + + for (n = 0; n < acflen; n++) + { + currFrame[n] = x[n + 1] * enc_inter_filter[0][0] + + x[n] * enc_inter_filter[0][1] + + x[n - 1] * enc_inter_filter[0][2]; + + predFrame[n] = 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]; + } + + /* Normalized Correlation */ + sum1 = sum2 = sum3 = 0; + + for (i = 0; i < acflen; i++) { + sum1 += currFrame[i] * predFrame[i]; + } + + for (i = 0; i < acflen; i++) { + sum2 += currFrame[i] * currFrame[i]; + } + + for (i = 0; i < acflen; i++) { + sum3 += predFrame[i] * predFrame[i]; + } + + sum2 = LC3_SQRT(sum2 * sum3) + LC3_POW(10, -5); + 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_decoder.c b/lib_lc3plus/ltpf_decoder.c new file mode 100644 index 000000000..a40c85213 --- /dev/null +++ b/lib_lc3plus/ltpf_decoder.c @@ -0,0 +1,356 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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 "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 +) +{ + LC3_INT i = 0, j = 0, n = 0, N = 0, L_past_x = 0, N4 = 0, N34 = 0, + pitch_int = 0, pitch_fr = 0, p1 = 0, p2 = 0, L_past_y = 0, inter_len = 0, tilt_len = 0, + tilt_len_r = 0, inter_len_r = 0, old_x_len = 0, old_y_len = 0; + + LC3_FLOAT conf_alpha = 0, gain = 0, a1[MAX_LEN] = {0}, a2[MAX_LEN] = {0}, b1[MAX_LEN] = {0}, b2[MAX_LEN] = {0}, + buf_x[4 * MAX_LEN] = {0}, buf_y[4 * MAX_LEN] = {0}, buf_z[4 * MAX_LEN] = {0}, pitch = 0, sum1 = 0, sum2 = 0; + + const LC3_FLOAT *inter_filter[4], *tilt_filter[4]; + + + 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 */ + 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++; + } + + 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; + } + + } 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++; + } + + 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; + } + } 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 { + 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) * 4 * MAX_LEN); + + 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; + } + } + + /* 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; + } + } + + /* 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; +} diff --git a/lib_lc3plus/mdct.c b/lib_lc3plus/mdct.c new file mode 100644 index 000000000..11618b946 --- /dev/null +++ b/lib_lc3plus/mdct.c @@ -0,0 +1,128 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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 "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; + } + } + 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]; + } + 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] = {0}; + LC3_INT i = 0; + 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_shaping.c b/lib_lc3plus/mdct_shaping.c new file mode 100644 index 000000000..187619250 --- /dev/null +++ b/lib_lc3plus/mdct_shaping.c @@ -0,0 +1,23 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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 "functions.h" + +void processMdctShaping_fl(LC3_FLOAT x[], LC3_FLOAT scf[], const LC3_INT bands_offset[], LC3_INT fdns_npts) +{ + LC3_INT i = 0, j = 0; + + for (i = 0; i < fdns_npts; i++) { + for (; j < bands_offset[i + 1]; j++) { + x[j] = x[j] * scf[i]; + } + } +} diff --git a/lib_lc3plus/near_nyquist_detector.c b/lib_lc3plus/near_nyquist_detector.c new file mode 100644 index 000000000..ce9435130 --- /dev/null +++ b/lib_lc3plus/near_nyquist_detector.c @@ -0,0 +1,38 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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 "options.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) +{ + *near_nyquist_flag = 0; + + 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; + } + } +} diff --git a/lib_lc3plus/noise_factor.c b/lib_lc3plus/noise_factor.c new file mode 100644 index 000000000..c5aa582e4 --- /dev/null +++ b/lib_lc3plus/noise_factor.c @@ -0,0 +1,112 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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 "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, end = 0, start = 0, i = 0, j = 0, k = 0, + allZeros = 0, m = 0; + LC3_FLOAT fac_ns_unq = 0, mean = 0, idx = 0, nsf1 = 0, nsf2 = 0; + LC3_INT zeroLines[MAX_LEN] = {0}, zL1[MAX_LEN] = {0}, zL2[MAX_LEN] = {0}; + + switch (frame_dms) + { + case 25: + nTransWidth = 4; + startOffset = 6; + break; + case 50: + nTransWidth = 4; + startOffset = 12; + break; + case 100: + nTransWidth = 8; + startOffset = 24; + break; + } + + for (k = startOffset; k < BW_cutoff_idx; k++) { + allZeros = 1; + + start = k - (nTransWidth - 2) / 2; + end = MIN(BW_cutoff_idx - 1, k + (nTransWidth - 2) / 2); + + for (i = start; i <= end; i++) { + if (xq[i] != 0) { + allZeros = 0; + } + } + + if (allZeros == 1) { + zeroLines[j] = k + 1; + kZeroLines++; + j++; + } + } + + for (i = 0; i < kZeroLines; i++) { + sumZeroLines += zeroLines[i]; + } + + if (sumZeroLines > 0) { + for (j = 0; j < kZeroLines; j++) { + mean += LC3_FABS(x[zeroLines[j] - 1]); + } + + fac_ns_unq = mean / (gg * kZeroLines); + } else { + fac_ns_unq = 0; + } + + if (kZeroLines > 0) + { + if (target_bytes <= 20 && frame_dms == 100) { + j = 0, k = 0; + m = floor(sumZeroLines / kZeroLines); + + for (i = 0; i < kZeroLines; i++) { + if (zeroLines[i] <= m) { + zL1[j] = zeroLines[i]; + j++; + } + + if (zeroLines[i] > m) { + zL2[k] = zeroLines[i]; + k++; + } + } + + mean = 0; + for (i = 0; i < j; i++) { + mean += LC3_FABS(x[zL1[i] - 1]) / gg; + } + + nsf1 = mean / j; + + mean = 0; + for (i = 0; i < k; i++) { + mean += LC3_FABS(x[zL2[i] - 1]) / gg; + } + + nsf2 = mean / 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_filling.c b/lib_lc3plus/noise_filling.c new file mode 100644 index 000000000..7fac5e0f7 --- /dev/null +++ b/lib_lc3plus/noise_filling.c @@ -0,0 +1,81 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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 "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] = {0}; + LC3_INT nTransWidth = 0, startOffset = 0, i = 0, j = 0, k = 0, start = 0, end = 0, allZeros = 0, kZeroLines = 0; + LC3_FLOAT fac_ns = 0; + + switch (frame_dms) + { + case 25: + nTransWidth = 1; + startOffset = 6; + break; + case 50: + nTransWidth = 1; + startOffset = 12; + break; + case 100: + nTransWidth = 3; + startOffset = 24; + break; + } + + fac_ns = (8.0 - fac_ns_idx) / 16.0; + + j = 0; + + for (k = startOffset; k < bw_stopband; k++) { + allZeros = 1; + + start = k - nTransWidth; + end = MIN(bw_stopband - 1, k + nTransWidth); + + for (i = start; i <= end; i++) { + if (xq[i] != 0) { + allZeros = 0; + } + } + + if (allZeros == 1) { + 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/olpa.c b/lib_lc3plus/olpa.c new file mode 100644 index 000000000..6bec50952 --- /dev/null +++ b/lib_lc3plus/olpa.c @@ -0,0 +1,144 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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 "functions.h" + +static void filter_olpa(LC3_FLOAT* in, LC3_FLOAT* out, const LC3_FLOAT* buf, LC3_FLOAT len_buf, LC3_INT len_input); +static LC3_INT searchMaxIndice(LC3_FLOAT* in, LC3_INT len); + +void filter_olpa(LC3_FLOAT* in, LC3_FLOAT* out, const LC3_FLOAT* buf, LC3_FLOAT len_buf, LC3_INT len_input) +{ + LC3_INT i = 0, j = 0; + LC3_FLOAT sum = 0; + /* a = 1, so denominator == 1, nothing to do here */ + + for (i = 0; i < len_input; i++) { + j = 0; + sum = 0; + for (j = 0; (j < len_buf) && (j <= i); j++) { + sum += buf[j] * in[i - j]; + } + + out[i] = sum; + } +} + +LC3_INT searchMaxIndice(LC3_FLOAT* in, LC3_INT len) +{ + LC3_INT max_i = 0, i = 0; + 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, 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] = {0}, filt_out[LEN_12K8 + 3] = {0}, d_wsp[LEN_6K4] = {0}, R0[RANGE_PITCH_6K4] = {0}, R[RANGE_PITCH_6K4] = {0}; /* constant length */ + LC3_INT i = 0, j = 0, len2 = 0, T0 = 0, T02 = 0, min_pitch = 0, max_pitch = 0, L = 0, mem_in_len = 0, acflen = 0; + + + mem_in_len = MAX_PITCH_6K4; + len2 = len / 2; + acflen = len2; + if (frame_dms == 25) + { + mem_in_len += 16; + acflen += 16; + } + + /* Downsampling */ + move_float(buf, mem_s12k8, 3); + move_float(&buf[3], s_12k8, len); + move_float(mem_s12k8, &buf[len], 3); + filter_olpa(buf, filt_out, olpa_down2, 5, len + 3); + for (i = 4, j = 0; i < len + 3; i = i + 2) { + d_wsp[j] = filt_out[i]; + j++; + } + + /* Compute autocorrelation */ + s6k4 = &buf[mem_in_len]; + move_float(buf, mem_s6k4, mem_in_len); + move_float(s6k4, d_wsp, len2); + move_float(mem_s6k4, &buf[len2], mem_in_len); + if (frame_dms == 25) + { + s6k4 = s6k4 - 16; + } + for (i = MIN_PITCH_6K4; i <= MAX_PITCH_6K4; i++) { + sum = 0; + for (j = 0; j < acflen; j++) { + sum += s6k4[j] * s6k4[j - i]; + } + R0[i - MIN_PITCH_6K4] = sum; + } + + /* Weight autocorrelation and find maximum */ + move_float(R, R0, RANGE_PITCH_6K4); + 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) + LC3_POW(10.0, -5.0); + norm_corr = sum0 / sum1; + norm_corr = MAX(0, norm_corr); + + /* 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(&R[min_pitch - MIN_PITCH_6K4], max_pitch - min_pitch + 1 ); + T02 = L + min_pitch; + + 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) + LC3_POW(10.0, -5.0); + norm_corr2 = sum0 / sum1; + norm_corr2 = MAX(0, norm_corr2); + + if (norm_corr2 > (norm_corr * 0.85)) { + T0 = T02; + norm_corr = norm_corr2; + } + } + + *mem_old_T0 = T0; + *T0_out = T0 * 2.0; + *normcorr_out = norm_corr; +} diff --git a/lib_lc3plus/pc_apply.c b/lib_lc3plus/pc_apply.c new file mode 100644 index 000000000..1d1bc4000 --- /dev/null +++ b/lib_lc3plus/pc_apply.c @@ -0,0 +1,73 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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 "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_classify.c b/lib_lc3plus/pc_classify.c new file mode 100644 index 000000000..71196edb8 --- /dev/null +++ b/lib_lc3plus/pc_classify.c @@ -0,0 +1,170 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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 "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_main.c b/lib_lc3plus/pc_main.c new file mode 100644 index 000000000..268ee94d2 --- /dev/null +++ b/lib_lc3plus/pc_main.c @@ -0,0 +1,43 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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 "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_update.c b/lib_lc3plus/pc_update.c new file mode 100644 index 000000000..57539b507 --- /dev/null +++ b/lib_lc3plus/pc_update.c @@ -0,0 +1,37 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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 "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/per_band_energy.c b/lib_lc3plus/per_band_energy.c new file mode 100644 index 000000000..db1b5b2d0 --- /dev/null +++ b/lib_lc3plus/per_band_energy.c @@ -0,0 +1,59 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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 "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 = 0, j = 0, start = 0, stop = 0, maxBwBin = 0; + LC3_FLOAT sum = 0; + +# 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 + } + + 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/plc_classify.c b/lib_lc3plus/plc_classify.c new file mode 100644 index 000000000..619a1f741 --- /dev/null +++ b/lib_lc3plus/plc_classify.c @@ -0,0 +1,199 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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 "functions.h" + + +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; + + if (plcAd) + { + *xcorr = 0; + } + + if (bfi == 1) + { + *nbLostCmpt = *nbLostCmpt + 1; + + /* Use pitch correlation at ltpf integer lag if available */ + if (*nbLostCmpt == 1) + { + *concealMethod = plcMeth; // this is a dangerous mapping! + + /* 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 */ + } + else + { + *concealMethod = 4; /* Noise Substitution */ + } + } + } + else + { + *concealMethod = 4; /* Noise Substitution */ + } + } + } +} + +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_compute_stab_fac.c b/lib_lc3plus/plc_compute_stab_fac.c new file mode 100644 index 000000000..4a1111a2c --- /dev/null +++ b/lib_lc3plus/plc_compute_stab_fac.c @@ -0,0 +1,64 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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 "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 new file mode 100644 index 000000000..ecea32be5 --- /dev/null +++ b/lib_lc3plus/plc_damping_scrambling.c @@ -0,0 +1,206 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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 "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) +{ + + LC3_INT32 processDampScramb; + + processDampScramb = 0; + + + if ( bfi != 0 ) + { + if (concealMethod == 4 || bfi == 2) + { + processDampScramb = 1; + } + 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); + } + 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); + 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) +{ + 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; + + /* Main process */ + if (nbLostCmpt == 1) + { + *cum_fading_slow = 1; + *cum_fading_fast = 1; + *cum_fflcAtten = 1; + } + + 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; + } + + *cum_fading_slow = *cum_fading_slow * slow; + *cum_fading_fast = *cum_fading_fast * fast; + + if (processDampScramb == 1) + { + 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; + 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; + + for (i = spec_inv_idx; i < yLen; i++) + { + *seed = 16831 + *seed * 12821; + + *seed = (LC3_INT16)(*seed); + if (*seed == 32768) + { + *seed -= 32768; + } + + if (*seed < 0) + { + if (pitch_present == 0 || *seed < randThreshold) + { + spec[i] = -spec[i]; + } + } + } + + 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; + + for (i = spec_inv_idx; i < yLen; i++) + { + if (LC3_FABS(spec[i]) < energThreshold) + { + 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_main.c b/lib_lc3plus/plc_main.c new file mode 100644 index 000000000..df3fd184d --- /dev/null +++ b/lib_lc3plus/plc_main.c @@ -0,0 +1,209 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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 "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]; + + 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) + { + 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) + ); + + + 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); + + 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_noise_substitution.c b/lib_lc3plus/plc_noise_substitution.c new file mode 100644 index 000000000..4913ee53e --- /dev/null +++ b/lib_lc3plus/plc_noise_substitution.c @@ -0,0 +1,22 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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 "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/plc_phecu_f0_refine_first.c b/lib_lc3plus/plc_phecu_f0_refine_first.c new file mode 100644 index 000000000..11ebf276b --- /dev/null +++ b/lib_lc3plus/plc_phecu_f0_refine_first.c @@ -0,0 +1,75 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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 "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_fec_hq.c b/lib_lc3plus/plc_phecu_fec_hq.c new file mode 100644 index 000000000..c25466c3e --- /dev/null +++ b/lib_lc3plus/plc_phecu_fec_hq.c @@ -0,0 +1,159 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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 "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_hq_ecu.c b/lib_lc3plus/plc_phecu_hq_ecu.c new file mode 100644 index 000000000..5b1978bca --- /dev/null +++ b/lib_lc3plus/plc_phecu_hq_ecu.c @@ -0,0 +1,116 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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 "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) +{ + 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; + } + } + + + *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); + + 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); + + } + + 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, + 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 new file mode 100644 index 000000000..0bcc98d7a --- /dev/null +++ b/lib_lc3plus/plc_phecu_lf_peak_analysis.c @@ -0,0 +1,112 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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 "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_rec_frame.c b/lib_lc3plus/plc_phecu_rec_frame.c new file mode 100644 index 000000000..0e6570743 --- /dev/null +++ b/lib_lc3plus/plc_phecu_rec_frame.c @@ -0,0 +1,147 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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 "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); + fs_idx = FRAME2FS_IDX(L); + 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.c b/lib_lc3plus/plc_phecu_setf0hz.c new file mode 100644 index 000000000..b14327e2b --- /dev/null +++ b/lib_lc3plus/plc_phecu_setf0hz.c @@ -0,0 +1,28 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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 "defines.h" +#include "functions.h" + + +LC3_FLOAT plc_phEcuSetF0Hz(LC3_INT32 fs, LC3_FLOAT * old_pitchPtr) +{ + LC3_FLOAT result; + + result = 0; + if (*old_pitchPtr != 0) + { + result = LC3_ROUND(fs/(*old_pitchPtr)/PHECU_FRES * 128.0) / 128.0; + } + + return result; +} + diff --git a/lib_lc3plus/plc_phecu_spec_ana.c b/lib_lc3plus/plc_phecu_spec_ana.c new file mode 100644 index 000000000..b49690030 --- /dev/null +++ b/lib_lc3plus/plc_phecu_spec_ana.c @@ -0,0 +1,599 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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 "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 new file mode 100644 index 000000000..43f806339 --- /dev/null +++ b/lib_lc3plus/plc_phecu_subst_spec.c @@ -0,0 +1,247 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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 "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); + +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, 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, subInd; + + 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 ----------------- + binCounter = 1; + subInd = 0; + + one_peak_flag_mask = -1; + if (n_plocs < 3 && n_plocs > 0) { + one_peak_flag_mask = 0; + } + + 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); + } + + + 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; +} + diff --git a/lib_lc3plus/plc_phecu_tba_per_band_gain.c b/lib_lc3plus/plc_phecu_tba_per_band_gain.c new file mode 100644 index 000000000..9f585f28d --- /dev/null +++ b/lib_lc3plus/plc_phecu_tba_per_band_gain.c @@ -0,0 +1,44 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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 "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 new file mode 100644 index 000000000..600b9714e --- /dev/null +++ b/lib_lc3plus/plc_phecu_tba_spect_Xavg.c @@ -0,0 +1,45 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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 "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 new file mode 100644 index 000000000..e5f0d3caa --- /dev/null +++ b/lib_lc3plus/plc_phecu_tba_trans_dect_gains.c @@ -0,0 +1,320 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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 "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 +/* default setting only requieres 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*/, +}; +#else +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 }; + + +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 + +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) +{ + + 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; + + LC3_INT32 FADEOUT_IN_MS, PLC_P800_SPEECH_FADEOUT_IN_FRAMES, + PLC2_FADEOUT_IN_FRAMES, BURST_ATT_THRESH_PRE; + const LC3_INT32 *TABLEQ15; + 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 */ + + UNUSED(attDegreeFrames_dbg); + + /* constants setup */ + att_always = 0; + + XavgFadeinFactor = -1.0; + + if (PLC2_FADEOUT_IN_MS != 0) + { + if (PLC2_FADEOUT_IN_MS < 0) + { + FADEOUT_IN_MS = PLC_FADEOUT_IN_MS; /* % use TDC - SETTING as input */ + } + else + { + FADEOUT_IN_MS = PLC2_FADEOUT_IN_MS; /* % use a PLC2 individual settinsg */ + } + + PLC_P800_SPEECH_FADEOUT_IN_FRAMES = (LC3_INT32) LC3_FLOOR((LC3_FLOAT)FADEOUT_IN_MS / (LC3_FLOAT)10.0); /* % nominal svaleu 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 fot assumed music */ + + 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; + + + /* 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); + + + /* envelope setting */ + burst_att_thresh = BURST_ATT_THRESH + 1; + att_per_frame_idx = ATT_PER_FRAME - 1; + + + 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; + + if (PLC_FADEOUT_IN_MS > 0) + { + assert(att_per_frame_idx >= 1 && att_per_frame_idx <= 10); + 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]; + } + 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); + } + } + + + 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 */ + } + + + + if(burst_len > BETA_MUTE_THR) + { + *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_trans_burst_ana_sub.c b/lib_lc3plus/plc_phecu_trans_burst_ana_sub.c new file mode 100644 index 000000000..c860cd6ce --- /dev/null +++ b/lib_lc3plus/plc_phecu_trans_burst_ana_sub.c @@ -0,0 +1,48 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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 "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) +{ + 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); + + return; +} + diff --git a/lib_lc3plus/plc_tdc.c b/lib_lc3plus/plc_tdc.c new file mode 100644 index 000000000..1a1a408f4 --- /dev/null +++ b/lib_lc3plus/plc_tdc.c @@ -0,0 +1,763 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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" +/***************************************************************************\ + * contents/description: Main function for Time domain concealment +\***************************************************************************/ + +#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 + ) +{ + 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; + + 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]; + + if (nbLostCmpt_loc > PLC_FADEOUT_IN_MS/10) + { + 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; + } + + 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; + case 50: *alpha *= PLC34_ATTEN_FAC_050; break; + case 100: *alpha *= PLC34_ATTEN_FAC_100; break; + } + } + + if (nbLostCmpt_loc > 5) + { + gain_p = *alpha; + } + + /*---------------------------------------------------------------* + * 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) + { + if (nbLostCmpt_loc == PLC_FADEOUT_IN_MS/10) + { + 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_tdac.c b/lib_lc3plus/plc_tdc_tdac.c new file mode 100644 index 000000000..329361b14 --- /dev/null +++ b/lib_lc3plus/plc_tdc_tdac.c @@ -0,0 +1,80 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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 "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 new file mode 100644 index 000000000..a151420eb --- /dev/null +++ b/lib_lc3plus/plc_update.c @@ -0,0 +1,125 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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 "options.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/quantize_spec.c b/lib_lc3plus/quantize_spec.c new file mode 100644 index 000000000..7886b4586 --- /dev/null +++ b/lib_lc3plus/quantize_spec.c @@ -0,0 +1,196 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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 "functions.h" + +static LC3_INT sign(LC3_FLOAT x); + +LC3_INT sign(LC3_FLOAT x) +{ + if (x > 0) + return 1; + + if (x < 0) + return -1; + + return 0; +} + +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 = 0, i = 0, lastnz2 = 0, m = 0, maxlev = 0, k = 0; + LC3_INT nbits_lsb = 0; + LC3_INT c = 0; + LC3_INT a = 0, b = 0, lev1 = 0, sym = 0, t = 0, pki = 0; + LC3_INT a1_msb = 0, b1_msb = 0; + LC3_INT lastnz = 1; + LC3_FLOAT offset = 0.375; + + if (hrmode) + { + offset = 0.5; + } + + + /* Quantization */ + for (i = 0; i < nt; i++) { + xq[i] = trunc(x[i] / gain + offset * sign(x[i])); + if (hrmode == 0) { + assert(xq[i] <= 32767 && xq[i] >= -32768); + } + } + + /* Rate flag */ + + if ((fs < 48000 && totalBits > 320 + (fs / 8000 - 2) * 160) || (fs == 48000 && totalBits > 800)) { + rateFlag = 512; + } + + /* Init */ + if (mode == 0 && ((fs < 48000 && totalBits >= 640 + (fs / 8000 - 2) * 160) || (fs == 48000 && totalBits >= 1120))) { + 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; + } + + *nbits = 0; + *nbits2 = 0; + + /* Calculate number of estimated bits */ + + for (k = 0; k < lastnz; k = k + 2) { + t = c + rateFlag; + if (k > nt / 2) { + 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) { + *nbits = *nbits + MIN(a, 1) * 2048; + *nbits = *nbits + MIN(b, 1) * 2048; + } + + lev1 = 0; + + while (MAX(a, b) >= 4) { + pki = ari_spec_lookup_fl[t + lev1 * 1024]; + *nbits = *nbits + ari_spec_bits_fl[pki][16]; + + if (lev1 == 0 && mode > 0) { + nbits_lsb += 2; + } else { + *nbits = *nbits + 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; + *nbits = *nbits + 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++; + } + } + + *nbits = *nbits + MIN(a1_msb, 1) * 2048; + *nbits = *nbits + MIN(b1_msb, 1) * 2048; + } + + if (mode >= 0 && (abs(xq[k]) != 0 || abs(xq[k + 1]) != 0) && *nbits <= target * 2048) { + lastnz2 = k + 2; + *nbits2 = *nbits; + } + + lev1 = lev1 - 1; + if (lev1 <= 0) { + t = 1 + (a + b) * (lev1 + 2); + } else { + t = 13 + lev1; + } + + c = (c & 15) * 16 + t; + } + + /* Number of bits */ + *nbits = ceil((LC3_FLOAT)*nbits / 2048.0); + + if (mode >= 0) { + *nbits2 = 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/reorder_bitstream.c b/lib_lc3plus/reorder_bitstream.c new file mode 100644 index 000000000..77b50d7a1 --- /dev/null +++ b/lib_lc3plus/reorder_bitstream.c @@ -0,0 +1,41 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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 "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/resamp12k8.c b/lib_lc3plus/resamp12k8.c new file mode 100644 index 000000000..0cab5daae --- /dev/null +++ b/lib_lc3plus/resamp12k8.c @@ -0,0 +1,107 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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 "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 = 0, N12k8 = 0, i = 0, k = 0; + LC3_FLOAT mac = 0, buf_out[120 + MAX_LEN] = {0}, bufdown[128] = {0}, buf[120 + MAX_LEN] = {0}; + 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; + 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_out, mem_out, mem_out_len * sizeof(LC3_FLOAT)); + + memmove(&buf_out[mem_out_len], bufdown, len_12k8 * sizeof(LC3_FLOAT)); + + memmove(y, buf_out, (*y_len + 1) * sizeof(LC3_FLOAT)); + + memmove(mem_out, &buf_out[N12k8], mem_out_len * sizeof(LC3_FLOAT)); +} diff --git a/lib_lc3plus/residual_coding.c b/lib_lc3plus/residual_coding.c new file mode 100644 index 000000000..42094d275 --- /dev/null +++ b/lib_lc3plus/residual_coding.c @@ -0,0 +1,76 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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 "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] = {0}; + 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_decoding.c b/lib_lc3plus/residual_decoding.c new file mode 100644 index 000000000..97fd94afc --- /dev/null +++ b/lib_lc3plus/residual_decoding.c @@ -0,0 +1,97 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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 "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] = {0}; + 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 /= 2; + 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/setup_com_lc3.c b/lib_lc3plus/setup_com_lc3.c new file mode 100644 index 000000000..17054d1ff --- /dev/null +++ b/lib_lc3plus/setup_com_lc3.c @@ -0,0 +1,30 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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 "options.h" + +LC3_FLOAT array_max_abs(LC3_FLOAT *in, LC3_INT32 len) +{ + LC3_FLOAT max; + LC3_INT32 i; + + max = LC3_FABS(in[0]); + + for (i = 0; i < len; i++) + { + if (LC3_FABS(in[i]) > LC3_FABS(max)) + { + max = LC3_FABS(in[i]); + } + } + + return max; +} + diff --git a/lib_lc3plus/setup_dec_lc3.c b/lib_lc3plus/setup_dec_lc3.c new file mode 100644 index 000000000..c14309720 --- /dev/null +++ b/lib_lc3plus/setup_dec_lc3.c @@ -0,0 +1,444 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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 "setup_dec_lc3.h" +#include "functions.h" +#include +#include + +/* if decoder is null only size is reported */ +# include "fft/iis_fft.h" + +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; + + 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)); + + q_old_res = balloc(decoder, &size, sizeof(LC3_FLOAT) * frame_len); + + if (decoder) { + decoder->channel_setup[ch] = setup; + + 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->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 +) +{ + memset(decoder, 0, lc3plus_dec_get_size(samplerate, channels)); + alloc_decoder(decoder, samplerate, channels); + + decoder->fs = CODEC_FS(samplerate); + decoder->fs_out = samplerate; + decoder->fs_idx = FS2FS_IDX(decoder->fs); + decoder->plcMeth = plc_mode; + + decoder->hrmode = hrmode != 0; + + if (decoder->fs_idx > 4) { + decoder->fs_idx = 5; + } + 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; + } + + set_dec_frame_params(decoder); + + lc3plus_dec_set_ep_enabled(decoder, 0); + + return LC3PLUS_OK; +} + +/* set frame config params */ +void set_dec_frame_params(LC3PLUS_Dec* decoder) +{ + int ch = 0; + + 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->yLen = MIN(MAX_BW, decoder->frame_length); + } + + decoder->bands_number = 64; + if (decoder->frame_ms == 2.5) + { + decoder->frame_length = decoder->frame_length >> 2; + decoder->yLen /= 4; + 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]; + } + } + if (decoder->frame_ms == 5) + { + decoder->frame_length = decoder->frame_length >> 1; + decoder->yLen /= 2; + decoder->bands_number = bands_number_5ms[decoder->fs_idx]; + } + + 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]; + } + else + { + decoder->bands_offset = ACC_COEFF_PER_BAND[decoder->fs_idx]; + } + decoder->cutoffBins = BW_cutoff_bin_all; + } + else if (decoder->frame_ms == 2.5) + { + if (decoder->hrmode) + { + decoder->bands_offset = ACC_COEFF_PER_BAND_2_5ms_HR[decoder->fs_idx]; + } + else + { + decoder->bands_offset = ACC_COEFF_PER_BAND_2_5ms[decoder->fs_idx]; + } + decoder->cutoffBins = BW_cutoff_bin_all_2_5ms; + } + else if (decoder->frame_ms == 5) + { + if (decoder->hrmode) + { + decoder->bands_offset = ACC_COEFF_PER_BAND_5ms_HR[decoder->fs_idx]; + } + else + { + decoder->bands_offset = ACC_COEFF_PER_BAND_5ms[decoder->fs_idx]; + } + decoder->cutoffBins = BW_cutoff_bin_all_5ms; + } + + 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; + } + } + 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; + } + } + 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]; + } + + 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; + + 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; + + 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; + } + } + } +} + +LC3PLUS_Error update_dec_bitrate(LC3PLUS_Dec* decoder, int ch, int nBytes) +{ + int totalBits = 0, bitsTmp = 0, channel_bytes = 0, maxBytes = 0, minBytes = 0; + DecSetup* setup; + + if (decoder->hrmode) + { + switch (decoder->frame_dms) + { + case 25: + maxBytes = 210; + minBytes = MIN_NBYTES; + break; + case 50: + maxBytes = 375; + minBytes = MIN_NBYTES; + break; + case 100: + maxBytes = 625; + minBytes = MIN_NBYTES; + break; + default: + return LC3PLUS_HRMODE_ERROR; + } + } + else + { + minBytes = MIN_NBYTES; + maxBytes = MAX_NBYTES_100; // for backward compatibility, MAX_NBYTES_100 is used for all frame lengths + } + + channel_bytes = nBytes; + + setup = decoder->channel_setup[ch]; + + if (channel_bytes < minBytes || channel_bytes > maxBytes) + { + return LC3PLUS_NUMBYTES_ERROR; + } + + 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)); + + 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; + } + + 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; + } + + 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; + } + + return LC3PLUS_OK; +} diff --git a/lib_lc3plus/setup_dec_lc3.h b/lib_lc3plus/setup_dec_lc3.h new file mode 100644 index 000000000..6ed0f438e --- /dev/null +++ b/lib_lc3plus/setup_dec_lc3.h @@ -0,0 +1,112 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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 + +#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]; + + 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; + + 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 */ + + LC3_INT imdct_memLen; + LC3_INT imdct_winLen; + LC3_INT imdct_laZeros; + const LC3_FLOAT* imdct_win; + + 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; +}; + +#endif diff --git a/lib_lc3plus/setup_enc_lc3.c b/lib_lc3plus/setup_enc_lc3.c new file mode 100644 index 000000000..986b43d60 --- /dev/null +++ b/lib_lc3plus/setup_enc_lc3.c @@ -0,0 +1,546 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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 "setup_enc_lc3.h" +#include "functions.h" +#include + +/* if encoder is null only size is reported */ +int alloc_encoder(LC3PLUS_Enc* encoder, int channels) +{ + int ch = 0; + size_t size = sizeof(LC3PLUS_Enc); + + for (ch = 0; ch < channels; ch++) { + EncSetup* setup = balloc(encoder, &size, sizeof(EncSetup)); + if (encoder) { + encoder->channel_setup[ch] = setup; + } + } + + return (int)size; +} + +LC3PLUS_Error FillEncSetup(LC3PLUS_Enc* encoder, int samplerate, int channels + , int hrmode + , int32_t lfe_channel_array[] +) +{ + int ch = 0; + memset(encoder, 0, lc3plus_enc_get_size(samplerate, channels)); + alloc_encoder(encoder, channels); + + encoder->fs = CODEC_FS(samplerate); + encoder->fs_in = samplerate; + encoder->fs_idx = FS2FS_IDX(encoder->fs); + encoder->frame_dms = 100; + if (encoder->fs_idx > 4) { + encoder->fs_idx = 5; + } + + 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; + encoder->r12k8_mem_out_len = 24; + + 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; + } + + set_enc_frame_params(encoder); + return LC3PLUS_OK; +} + +/* set frame config params */ +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; + } + 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; + + if (encoder->fs_idx == 5) + { + encoder->hrmode = 1; + } + + if (encoder->hrmode) + { + encoder->BW_cutoff_bits = 0; + } + else + { + 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]; + if (encoder->hrmode) + { + encoder->bands_offset = ACC_COEFF_PER_BAND_HR[encoder->fs_idx]; + } + else + { + encoder->bands_offset = ACC_COEFF_PER_BAND[encoder->fs_idx]; + } + encoder->cutoffBins = BW_cutoff_bin_all; + + encoder->attdec_nblocks = 4; + encoder->attdec_damping = 0.5; + encoder->attdec_hangover_thresh = 2; + } + 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; + } + else if (encoder->frame_ms == 5) { + 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; + } + + if (encoder->frame_ms == 2.5) { + encoder->frame_length = encoder->frame_length >> 2; + encoder->yLen /= 4; + encoder->stEnc_mdct_mem_len = encoder->frame_length - encoder->la_zeroes; + if (encoder->hrmode) + { + encoder->bands_number = bands_number_2_5ms_HR[encoder->fs_idx]; + } + else + { + 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); + } + + + 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; + } + + for (ch = 0; ch < encoder->channels; ch++) { + setup = encoder->channel_setup[ch]; + + setup->olpa_mem_pitch = 17; + + 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); + } + } +} + +/* change encoder 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; + + if (encoder->hrmode) + { +#ifdef ENABLE_HR_MODE_FL + 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;} + 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;} + break; + 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;} + break; + default: + return LC3PLUS_HRMODE_ERROR; + } +#endif + } + else + { + 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) + { + case 8000: maxBR = MAX_BR_050DMS_NB; break; + default: break; + } + break; + case 100: + /* have additional limitations for 10ms */ + minBR = MIN_BR_100DMS; + maxBR = MAX_BR; + 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; + } + break; + default: return LC3PLUS_FRAMEMS_ERROR; + } + maxBR *= (encoder->fs_in == 44100 ? 441. / 480 : 1); + } + minBR *= encoder->channels; + maxBR *= encoder->channels; + + encoder->combined_channel_coding = 0; + + if (encoder->channels > 1 && encoder->epmode) + { + if (encoder->bitrate * encoder->frame_length / (8 * encoder->fs_in) <= 160) + { + encoder->combined_channel_coding = 1; + } + } + + 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; + } + } + + if (encoder->combined_channel_coding) + { + totalBytes = fec_get_data_size(encoder->epmode, encoder->combined_channel_coding, + bitrate * 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, + 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)); + } + else + { + totalBytes = bitrate * encoder->frame_length / (8 * encoder->fs_in); + } + + if (encoder->frame_dms <= 50) + { + encoder->tnsMaxOrder = 4; + } else { + encoder->tnsMaxOrder = 8; + } + + 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)); + channel_bytes = totalBytes / encoder->channels + (ch < (totalBytes % encoder->channels)); + + if (encoder->combined_channel_coding) + { + setup->targetBytes = channel_bytes; + } + 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); + } + // 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))) + { + encoder->bandwidth = MIN(12000, encoder->bandwidth_preset); + } + else + { + /* channel with highest index has lowest 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; + } + if (setup->total_bits > 2560) { + setup->targetBitsInit = setup->targetBitsInit - 1; + } + + if (encoder->hrmode) + { + setup->targetBitsInit -= 1; + } + + setup->targetBitsAri = setup->total_bits; + setup->enable_lpc_weighting = setup->total_bits < 480; + + 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; + } + + setup->quantizedGainOff = + -(MIN(115, setup->total_bits / (10 * (encoder->fs_idx + 1))) + 105 + 5 * (encoder->fs_idx + 1)); + + if (encoder->hrmode && encoder->fs_idx == 5) + { + 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) + { + setup->attack_handling = 1; + } + else + { + /* reset 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; + } + + 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; + } + if (encoder->hrmode) { + setup->ltpf_enable = 0; + } + + /* 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) + { + if (setup->total_bits > 4400) { + encoder->sns_damping = 6881.0/32768.0; + } + } + if (encoder->frame_ms == 5) + { + if (setup->total_bits > 4600/2) { + encoder->sns_damping = 4915.0/32768.0; + } + } + if (encoder->frame_ms == 2.5) + { + if (setup->total_bits > 4600/4) { + encoder->sns_damping = 4915.0/32768.0; + } + } + } + } + + if (encoder->hrmode && encoder->fs_idx >= 4) + { + int real_rate = setup->targetBytes * 8000 / encoder->frame_ms; + setup->regBits = real_rate / 12500; + + if (encoder->fs_idx == 5) + { + if (encoder->frame_ms == 10) + { + setup->regBits +=2; + } + if (encoder->frame_ms == 2.5) + { + setup->regBits -= 6; + } + } + else + { + if (encoder->frame_ms == 2.5) + { + setup->regBits -= 6; + } + else if (encoder->frame_ms == 5) + { + setup->regBits += 0; + } + if (encoder->frame_ms == 10) + { + setup->regBits += 5; + } + } + if (setup->regBits < 6) + { + setup->regBits = 6; + } + if (setup->regBits > 23) + { + setup->regBits = 23; + } + } + else + { + setup->regBits = -1; + } + } + + encoder->bitrate = 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); + if (index > 4) { + index = 5; + } + encoder->bw_ctrl_cutoff_bin = encoder->cutoffBins[index]; + } +} diff --git a/lib_lc3plus/setup_enc_lc3.h b/lib_lc3plus/setup_enc_lc3.h new file mode 100644 index 000000000..31f0cbeb5 --- /dev/null +++ b/lib_lc3plus/setup_enc_lc3.h @@ -0,0 +1,119 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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 + +#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]; + LC3_FLOAT r12k8_mem_out[24]; + 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; + 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; + + LC3_INT 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; + + 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; +}; + +#endif diff --git a/lib_lc3plus/sns_compute_scf.c b/lib_lc3plus/sns_compute_scf.c new file mode 100644 index 000000000..5cb041925 --- /dev/null +++ b/lib_lc3plus/sns_compute_scf.c @@ -0,0 +1,177 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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 "functions.h" + +void processSnsComputeScf_fl(LC3_FLOAT* x, LC3_INT tilt, LC3_INT xLen, LC3_FLOAT* gains, LC3_INT smooth, LC3_FLOAT sns_damping, LC3_FLOAT attdec_damping_factor) +{ + LC3_INT bands_number = 0, d = 0, i = 0, j = 0, n = 0, n2 = 0, n4 = 0, mapping[64] = {0}; + LC3_FLOAT tmp[64] = {0}, x_tmp1[MAX_LEN] = {0}, x_tmp2[MAX_LEN] = {0}, sum = 0, mean = 0, xl4[16] = {0}, nf = 0, xl[64] = {0}, gains_smooth[M] = {0}, ratio = 0; + LC3_FLOAT W[6] = {1.0 / 12.0, 2.0 / 12.0, 3.0 / 12.0, 3.0 / 12.0, 2.0 / 12.0, 1.0 / 12.0}; + + 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) { + tmp[i] = x[j]; + tmp[i + 1] = x[j]; + j++; + } + + move_float(&tmp[2 * d], &x[d], 64 - 2 * d); + } else if (ceil(64.0 / (LC3_FLOAT) xLen) == 4) + { + 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++) + { + tmp[i] = x[mapping[i] - 1]; + } + } else { + assert(0 && "Unsupported number of bands!"); + } + + move_float(x, tmp, 64); + + bands_number = 64; + xLen = bands_number; + } + + + /* Smoothing */ + + x_tmp1[0] = x[0]; + + move_float(&x_tmp1[1], &x[0], xLen - 1); + + move_float(&x_tmp2[0], &x[1], xLen - 1); + + x_tmp2[xLen - 1] = x[xLen - 1]; + + for (i = 0; i < xLen; i++) { + x[i] = 0.5 * x[i] + 0.25 * (x_tmp1[i] + x_tmp2[i]); + } + + /* Pre-emphasis */ + for (i = 0; i < xLen; i++) { + x[i] = x[i] * LC3_POW(10.0, (LC3_FLOAT)i * (LC3_FLOAT)tilt / ((LC3_FLOAT)bands_number - 1.0) / 10.0); + } + + /* Noise floor at -40dB */ + for (i = 0; i < 64; i++) { + sum += x[i]; + } + + mean = sum / (LC3_FLOAT)xLen; + + nf = mean * LC3_POW(10.0, -40.0 / 10.0); + nf = MAX(nf, LC3_POW(2.0, -32.0)); + + for (i = 0; i < 64; i++) { + if (x[i] < nf) { + x[i] = nf; + } + } + + /* Log-domain */ + for (i = 0; i < 64; i++) { + xl[i] = LC3_LOGTWO(x[i]) / 2.0; + } + + /* Downsampling */ + for (n = 0; n < bands_number / 4; n++) { + if (n == 0) { + tmp[0] = xl[0]; + + move_float(&tmp[1], &xl[0], 5); + + } else if (n == (bands_number / 4 - 1)) { + move_float(tmp, &xl[59], 5); + + tmp[5] = xl[63]; + + } else { + move_float(tmp, &xl[n * 4 - 1], ((n * 4 + 5 - 1) - (n * 4 - 1) + 1)); + } + + sum = 0; + for (i = 0; i < 6; i++) { + sum += tmp[i] * W[i]; + } + + xl4[n] = sum; + } + + + /* Remove mean and scaling */ + + sum = 0; + for (i = 0; i < bands_number / 4; i++) { + sum += xl4[i]; + } + + mean = sum / ((LC3_FLOAT)bands_number / 4.0); + + for (i = 0; i < bands_number / 4; i++) { + gains[i] = sns_damping * (xl4[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_interpolate_scf.c b/lib_lc3plus/sns_interpolate_scf.c new file mode 100644 index 000000000..441939789 --- /dev/null +++ b/lib_lc3plus/sns_interpolate_scf.c @@ -0,0 +1,90 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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 "functions.h" + +void processSnsInterpolateScf_fl(LC3_FLOAT* gains, LC3_INT encoder_side, LC3_INT bands_number, LC3_FLOAT* gains_int) +{ + LC3_INT i = 0, n = 0, d = 0, n4 = 0; + LC3_FLOAT tmp[MAX_BANDS_NUMBER_PLC] = {0}, ratio = 0; + + /* 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]) / 8.0; + gains_int[n * 4 + 3] = gains[n] + 3.0 * (gains[n + 1] - gains[n]) / 8.0; + gains_int[n * 4 + 4] = gains[n] + 5.0 * (gains[n + 1] - gains[n]) / 8.0; + gains_int[n * 4 + 5] = gains[n] + 7.0 * (gains[n + 1] - gains[n]) / 8.0; + } + + gains_int[62] = gains[15] + (gains[15] - gains[14]) / 8.0; + gains_int[63] = gains[15] + 3.0 * (gains[15] - gains[14]) / 8.0; + + /* 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 (ceil(64.0 / (LC3_FLOAT) bands_number) == 4) + { + 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_quantize_scf.c b/lib_lc3plus/sns_quantize_scf.c new file mode 100644 index 000000000..704127cce --- /dev/null +++ b/lib_lc3plus/sns_quantize_scf.c @@ -0,0 +1,517 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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 "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 = 0, idx = 0, k_delta = 0, pos = 0; + + 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 = 0, submode = 0; + LC3_INT pulses2[6] = {0}, pulses[M] = {0}; + LC3_FLOAT st2_vector[M] = {0}, st2_vector_idct[M] = {0}, 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 */ + for (i = 0; i < M; i++) { + st2_vector_idct[i] = st2_vector_idct[i] * sns_dec_gains[submode][scf_idx[3]]; + } + + /* Add stage 1 and stage 2 */ + + for (i = 0; i < M; i++) { + scf_q[i] = scf_q[i] + st2_vector_idct[i]; + } +} diff --git a/lib_lc3plus/structs.h b/lib_lc3plus/structs.h new file mode 100644 index 000000000..fea377da4 --- /dev/null +++ b/lib_lc3plus/structs.h @@ -0,0 +1,186 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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 "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; +} 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; + +} 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; +} PlcAdvSetup; + + +#endif diff --git a/lib_lc3plus/tns_coder.c b/lib_lc3plus/tns_coder.c new file mode 100644 index 000000000..ff3883d2b --- /dev/null +++ b/lib_lc3plus/tns_coder.c @@ -0,0 +1,374 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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 "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); +static LC3_INT findRC_idx(const LC3_FLOAT* in1, const LC3_FLOAT* in2, LC3_FLOAT checkValue); + +void xcorr(LC3_FLOAT* in, LC3_FLOAT* out, LC3_INT lag, LC3_INT inLen) +{ + LC3_INT i = 0, m = 0; + LC3_FLOAT sum = 0, tmp_buf[MAX_LEN] = {0}; + + for (m = -lag; m <= lag; m++) { + /* Append zeros and input vector */ + + zero_float(tmp_buf, abs(m)); + + move_float(&tmp_buf[abs(m)], in, inLen - abs(m)); + + /* Calculate sum */ + sum = 0; + + for (i = 0; i < inLen; i++) { + sum += in[i] * tmp_buf[i]; + } + + out[m + lag] = sum; + } +} + +void levinsonDurbin(LC3_FLOAT* r, LC3_FLOAT* out_lev, LC3_FLOAT* rc_unq, LC3_FLOAT* error, LC3_INT len) +{ + LC3_INT t = 0, i = 0, j = 0; + LC3_FLOAT g = 0, v = 0, sum = 0, buf_tmp[MAX_LEN] = {0}; + + 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++) { + zero_float(buf_tmp, len + 1); + + 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_INT i = 0, j = 0; + LC3_FLOAT tmp_buf[8] = {0}, tmp_buf1[8] = {0}, tmp_buf2[8] = {0}, knxt = 0; + + /* Initial length = 9 */ + + /* Drop the leading 1 */ + + move_float(&tmp_buf[0], &anxt[1], (*len - 1)); + + *len = *len - 1; /* Lenght = 8 */ + + /* Last coefficient */ + knxt = tmp_buf[*len - 1]; /* At [7] */ + + *len = *len - 1; /* Lenght = 7 */ + + move_float(tmp_buf1, tmp_buf, *len); + + j = 0; + for (i = *len - 1; i >= 0; i--) { + tmp_buf2[j] = knxt * tmp_buf[i]; + j++; + } + + out_a[0] = 1; + for (i = 0; i < *len; i++) { + out_a[i + 1] = (tmp_buf1[i] - tmp_buf2[i]) / (1.0 - (LC3_FABS(knxt)) * (LC3_FABS(knxt))); + } + + *len = *len + 1; /* Length = 8 */ +} + +void poly2rc(LC3_FLOAT* a, LC3_FLOAT* out, LC3_INT len) +{ + LC3_INT k = 0, i = 0, len_old = 0; + LC3_FLOAT buf[9] = {0}; + + 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]; + } +} + +LC3_INT findRC_idx(const LC3_FLOAT* in1, const LC3_FLOAT* in2, LC3_FLOAT checkValue) +{ + LC3_INT i = 0, ret = 0; + + for (i = 0; i < 17; i++) { + if (checkValue <= in1[i] && checkValue > in2[i]) { + ret = i; + } + } + + return ret; +} + +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 = 0, stopfreq[2] = {0}, startfreq[2] = {0}, f = 0, numfilters = 0, maxOrder = 0, bits = 0, sub = 0, + subdiv_startfreq = 0, subdiv_stopfreq = 0, j = 0, rc_idx_tmp[8] = {0}, order_tmp[8] = {0}, tmp = 0, tns = 0; + LC3_FLOAT minPGfac = 0, minPredictionGain = 0, maxPG = 0, xcorr_out[MAX_LEN] = {0}, buf_tmp[MAX_LEN] = {0}, sum = 0, + subdiv_len = 0, nSubdivisions = 0, r[9] = {0}, out_lev[9] = {0}, rc_unq[9] = {0}, error_lev = 0, predGain = 0, + alpha = 0, rc[8] = {0}, st[9] = {0}, s = 0, tmpSave = 0, tmp_fl = 0; + const LC3_INT* order; + + /* Init */ + + if (fs >= 32000 && frame_dms >= 50) { + numfilters = 2; + } else { + numfilters = 1; + } + + if (N > 40 * ((LC3_FLOAT) (frame_dms) / 10.0)) { + N = 40 * ((LC3_FLOAT) (frame_dms) / 10.0); + 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; + case 100: + maxOrder = 8; + nSubdivisions = 3.0; + break; + } + + minPGfac = 0.85; + maxPG = 2; + minPredictionGain = 1.5; + + if ((frame_dms >= 50 && nBits >= 48 * ((LC3_FLOAT) frame_dms / 10.0)) || frame_dms == 25) { + maxPG = minPredictionGain; + } + + if ((frame_dms >= 50 && nBits >= 48 * ((LC3_FLOAT) frame_dms / 10.0)) || frame_dms == 25) { + 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, 9); + + 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; + + sum = 0; + for (i = subdiv_startfreq; i < subdiv_stopfreq; i++) { + sum += x[i] * x[i]; + } + + if (sum < LC3_EPS) + { + zero_float(r, 9); + r[0] = 1; + break; + } + + move_float(buf_tmp, &x[subdiv_startfreq], subdiv_stopfreq - subdiv_startfreq); + + xcorr(buf_tmp, xcorr_out, maxOrder, subdiv_stopfreq - subdiv_startfreq); + + j = 0; + for (i = maxOrder; i >= 0; i--) { + r[j] = r[j] + xcorr_out[i] / sum; + j++; + } + } + + for (i = 0; i <= maxOrder; i++) { + r[i] = r[i] * lagw_tns[i]; + } + + levinsonDurbin(r, out_lev, 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) { + /* LPC weighting */ + if (predGain < maxPG) { + alpha = (maxPG - predGain) * (minPGfac - 1.0) / (maxPG - minPredictionGain) + 1.0; + + for (i = 0; i <= maxOrder; i++) { + out_lev[i] = out_lev[i] * LC3_POW(alpha, i); + } + + poly2rc(out_lev, rc_unq, maxOrder + 1); + } + + /* PARCOR Quantization */ + for (i = 0; i < maxOrder; i++) { + rc_idx_tmp[i] = findRC_idx(&quants_thr_tns[1], &quants_thr_tns[0], rc_unq[i]); + } + + /* Filter Order */ + j = 0; + for (i = 0; i < maxOrder; i++) { + rc[i] = quants_pts_tns[rc_idx_tmp[i]]; + + if (rc[i] != 0) { + order_tmp[j] = i + 1; + j++; + } + } + + order_out[f] = order_tmp[j - 1]; + // 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++; + } + } + + /* 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_disabled: + + *tns_numfilters = numfilters; + *bits_out = bits; +} diff --git a/lib_lc3plus/tns_decoder.c b/lib_lc3plus/tns_decoder.c new file mode 100644 index 000000000..d3aeefc3a --- /dev/null +++ b/lib_lc3plus/tns_decoder.c @@ -0,0 +1,52 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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 "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] = {0}, stopfreq[2] = {0}, f = 0, i = 0, j = 0, m = 0, l = 0, rc_idx_f[9] = {0}; + LC3_FLOAT rc[9] = {0}, s = 0, st[9] = {0}; + + 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++) { + if (order[f] > 0) { + j = 0; + + for (i = f * 8; i < f * 8 + 8; i++) { + rc_idx_f[j] = rc_idx[i]; + rc[j] = quants_pts_tns[rc_idx_f[j]]; + j++; + } + + for (m = startfreq[f]; m <= stopfreq[f]; m++) { + s = x[m - 1] - rc[order[f] - 1] * st[order[f] - 1]; + + for (l = order[f] - 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/util.h b/lib_lc3plus/util.h new file mode 100644 index 000000000..7ef6dedef --- /dev/null +++ b/lib_lc3plus/util.h @@ -0,0 +1,222 @@ +/****************************************************************************** +* ETSI TS 103 634 V1.4.1 * +* 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 "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) { + memmove(dst, src, len * sizeof(LC3_FLOAT)); +} +static inline void move_int(LC3_INT *dst, const LC3_INT *src, LC3_INT len) { + memmove(dst, src, len * sizeof(LC3_INT)); +} + +/* convenience wrappers around memset */ +static inline void zero_float(LC3_FLOAT *x, LC3_INT len) { + memset(x, 0, len * sizeof(LC3_FLOAT)); +} +static inline void zero_int(LC3_INT *x, LC3_INT len) { + memset(x, 0, len * sizeof(LC3_INT)); +} + +/* 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_MSPred.c b/lib_rend/ivas_MSPred.c new file mode 100644 index 000000000..4dcdbbb1c --- /dev/null +++ b/lib_rend/ivas_MSPred.c @@ -0,0 +1,564 @@ +/****************************************************************************************************** + + (C) 2022-2023 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. + +*******************************************************************************************************/ + +#include "options.h" +#include +#ifdef SPLIT_REND_WITH_HEAD_ROT +#include "ivas_lcld_rom_tables.h" +#include "ivas_lcld_prot.h" +#include "ivas_prot_rend.h" +#include "wmc_auto.h" + + +/*-------------------------------------------------------------------* + * Function _round() + * + * + *-------------------------------------------------------------------*/ + +static int32_t _round( + float val ) +{ + return ( val > 0.0f ? (int32_t) ( val + 0.5f ) : (int32_t) ( val - 0.5f ) ); +} + + +/*-------------------------------------------------------------------* + * Function quantPhase() + * + * + *-------------------------------------------------------------------*/ + +int32_t quantPhase( + float phase ) +{ +#ifdef SIMPLE_PHASE + int32_t phaseQ; + if ( phase < 0.0f ) + { + phase += 2.0f * _PI_; + } + phaseQ = _round( phase * SIMPLE_PHASE_QUANT_FACTOR ); + phaseQ = ( phaseQ > SIMPLE_PHASE_MAX_VAL ? SIMPLE_PHASE_MIN_VAL : phaseQ ); +#else + int32_t phaseQ; + + phaseQ = _round( phase * PHASE_QUANT_FACTOR ); + if ( phaseQ == PHASE_MAX_VAL ) + { + phaseQ = PHASE_MIN_VAL; + } +#endif + return phaseQ; +} + +#ifdef SIMPLE_PHASE +/*-------------------------------------------------------------------* + * Function rot_pm_pi() + * + * + *-------------------------------------------------------------------*/ + +void rot_pm_pi( + float *pr, + float *pi ) +{ + /* (-1 + j0) */ + *pr = -( *pr ); + *pi = -( *pi ); + + return; +} + + +/*-------------------------------------------------------------------* + * Function ApplyInversePredictros() + * + * + *-------------------------------------------------------------------*/ + +void rot_p_pi_2( + float *pr, + float *pi ) +{ + /* (0 + j) */ + float r = *pr; + + *pr = -( *pi ); + *pi = r; + + return; +} + +/*-------------------------------------------------------------------* + * Function rot_zero() + * + * + *-------------------------------------------------------------------*/ + +void rot_zero( + float *pr, + float *pi ) +{ + *pr = *pr; + *pi = *pi; + + return; +} + +/*-------------------------------------------------------------------* + * Function rot_m_pi_2() + * + * + *-------------------------------------------------------------------*/ + +void rot_m_pi_2( + float *pr, + float *pi ) +{ + /* (0 - j) */ + float r = *pr; + + *pr = *pi; + *pi = -r; + + return; +} +#endif + +/*-------------------------------------------------------------------* + * Function cplxmult() + * + * + *-------------------------------------------------------------------*/ + +void cplxmult( + float *pr1, + float *pi1, + float r2, + float i2 ) +{ + float r1 = *pr1, i1 = *pi1; + + *pr1 = r1 * r2 - i1 * i2; + *pi1 = r1 * i2 + i1 * r2; + + return; +} + + +/*-------------------------------------------------------------------* + * Function requantPhase() + * + * + *-------------------------------------------------------------------*/ + +int32_t requantPhase( + int32_t phaseQ ) +{ + + if ( phaseQ >= PHASE_MAX_VAL ) + { + phaseQ += PHASE_MAX_VAL; + phaseQ %= ( 2 * PHASE_MAX_VAL ); + phaseQ -= PHASE_MAX_VAL; + } + else if ( phaseQ < PHASE_MIN_VAL ) + { + phaseQ -= PHASE_MAX_VAL; + phaseQ %= ( 2 * PHASE_MAX_VAL ); + phaseQ += PHASE_MAX_VAL; + if ( phaseQ == PHASE_MAX_VAL ) + { + phaseQ = PHASE_MIN_VAL; + } + } + + return phaseQ; +} + + +/*-------------------------------------------------------------------* + * Function quantPred() + * + * + *-------------------------------------------------------------------*/ + +int32_t quantPred( + const float pred ) +{ + int32_t predQ = _round( pred * PRED_QUANT_FACTOR ); + predQ = predQ > PRED_MAX_VAL ? PRED_MAX_VAL : predQ; + predQ = predQ < PRED_MIN_VAL ? PRED_MIN_VAL : predQ; + + return predQ; +} + + +/*-------------------------------------------------------------------* + * Function dequantPhase() + * + * + *-------------------------------------------------------------------*/ + +float dequantPhase( + const int32_t phaseQ ) +{ +#ifdef SIMPLE_PHASE + return (float) phaseQ / SIMPLE_PHASE_QUANT_FACTOR; +#else + return (float) phaseQ / PHASE_QUANT_FACTOR; +#endif +} + + +/*-------------------------------------------------------------------* + * Function dequantPred() + * + * + *-------------------------------------------------------------------*/ + +float dequantPred( int32_t predQ ) +{ + return (float) predQ / PRED_QUANT_FACTOR; +} + + +/*-------------------------------------------------------------------* + * Function PrepEncode() + * + * + *-------------------------------------------------------------------*/ + +int32_t PrepEncode( + int32_t *piQuant, + const int32_t *piMSFlags, + const int32_t numBands ) +{ + int32_t b, numMSBands = 0; + + for ( b = 0; b < numBands; b++ ) + { + if ( piMSFlags[b] ) + { + piQuant[numMSBands++] = piQuant[b]; + } + } + + for ( b = numMSBands; b < numBands; b++ ) + { + piQuant[b] = 0; + } + + return numMSBands; +} + + +/*-------------------------------------------------------------------* + * Function EncodePhase() + * + * + *-------------------------------------------------------------------*/ + +void EncodePhase( + int32_t *phaseQuant, + const int32_t numMSBands, + const int32_t diffDim ) +{ + int32_t b; + + if ( diffDim > 0 ) + { + int32_t tmp1, tmp2; + tmp1 = phaseQuant[0]; + for ( b = 1; b < numMSBands; b++ ) + { + tmp2 = phaseQuant[b]; + phaseQuant[b] -= tmp1; + tmp1 = tmp2; + } + } + + if ( diffDim > 1 ) + { + int32_t tmp1, tmp2; + tmp1 = phaseQuant[1]; + for ( b = 2; b < numMSBands; b++ ) + { + tmp2 = phaseQuant[b]; + phaseQuant[b] -= tmp1; + tmp1 = tmp2; + } + } + for ( b = 1; b < numMSBands; b++ ) + { + phaseQuant[b] = requantPhase( phaseQuant[b] ); + } + + return; +} + + +/*-------------------------------------------------------------------* + * Function DecodePhase() + * + * + *-------------------------------------------------------------------*/ + +void DecodePhase( + int32_t *phaseQuant, + const int32_t numMSBands, + const int32_t diffDim ) +{ + int32_t b; + + if ( diffDim > 1 ) + { + for ( b = 2; b < numMSBands; b++ ) + { + phaseQuant[b] += phaseQuant[b - 1]; + } + } + + if ( diffDim > 0 ) + { + for ( b = 1; b < numMSBands; b++ ) + { + phaseQuant[b] += phaseQuant[b - 1]; + } + } + + for ( b = 1; b < numMSBands; b++ ) + { + phaseQuant[b] = requantPhase( phaseQuant[b] ); + } + + return; +} + + +/*-------------------------------------------------------------------* + * Function EncodePredCoef() + * + * + *-------------------------------------------------------------------*/ + +int32_t EncodePredCoef( + int32_t *predQuant, + const int32_t numMSBands ) +{ + int32_t b, tmp1, tmp2; + + tmp1 = predQuant[0]; + for ( b = 1; b < numMSBands; b++ ) + { + tmp2 = predQuant[b]; + predQuant[b] -= tmp1; + tmp1 = tmp2; + } + + return numMSBands; +} + + +/*-------------------------------------------------------------------* + * Function DecodePredCoef() + * + * + *-------------------------------------------------------------------*/ + +void DecodePredCoef( + int32_t *phaseQuant, + const int32_t numMSBands ) +{ + int32_t b; + + for ( b = 1; b < numMSBands; b++ ) + { + phaseQuant[b] += phaseQuant[b - 1]; + } + + return; +} + + +/*-------------------------------------------------------------------* + * Function CountMSBits() + * + * + *-------------------------------------------------------------------*/ + +int32_t CountMSBits( + int32_t iNumBands, + const int32_t iMSMode, + const int32_t *piMSFlags, + const int32_t *piLRPhaseDiff, + const int32_t *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++ ) + { + piPhaseCopy[b] = 0; + piPredCopy[b] = 0; + } + + iBitsWritten += 2; /* iMSMode */ + for ( b = 0; b < iNumBands; b++ ) + { + iNumMSBands += ( piMSFlags[b] != 0 ); + } + + if ( iNumMSBands == 0 ) + { + return iBitsWritten; + } + + if ( iNumMSBands < iNumBands ) + { + iBitsWritten += iNumBands; /* piMSFlags */ + } + + if ( iMSMode < 3 ) + { + return iBitsWritten; + } + + /* prepare arrays for coding evaluation */ + for ( b = 0; b < iNumBands; b++ ) + { + piPhaseCopy[b] = piLRPhaseDiff[b]; + piPredCopy[b] = piMSPredCoef[b]; + } + + /* Differential Coding of Phase Data*/ + PrepEncode( piPhaseCopy, piMSFlags, iNumBands ); + PrepEncode( piPredCopy, piMSFlags, iNumBands ); +#ifndef SIMPLE_PHASE + EncodePhase( piPhaseCopy, iNumMSBands, PHASE_DIFF_DIM ); +#endif + EncodePredCoef( piPredCopy, iNumMSBands ); + + iBitsWritten += 1; /* iMSPredAll */ + anyNonZero = 0; /* phase */ + for ( b = 0; b < iNumMSBands; b++ ) + { + if ( piPhaseCopy[b] != 0 ) + { + anyNonZero = 1; + break; + } + } + iBitsWritten++; /*anyNonZero Phase*/ + if ( anyNonZero ) + { +#ifdef SIMPLE_PHASE + iBitsWritten += iNumMSBands * SIMPLE_PHASE_BITS; +#else + iBitsWritten += PHASE_BAND0_BITS; + for ( b = 1; b < iNumMSBands; b++ ) + { + int32_t tabIdx = piPhaseCopy[b] - ENV_DELTA_MIN; + iBitsWritten += c_aaiRMSEnvHuffEnc[tabIdx][0]; + } +#endif + } + anyNonZero = 0; /* prediction */ + for ( b = 0; b < iNumMSBands; b++ ) + { + if ( piPredCopy[b] != 0 ) + { + anyNonZero = 1; + break; + } + } + + iBitsWritten++; /* any nonZero Pred */ + if ( anyNonZero ) + { + iBitsWritten += PRED_BAND0_BITS; + for ( b = 1; b < iNumMSBands; b++ ) + { + int32_t tabIdx = piPredCopy[b] - ENV_DELTA_MIN; + iBitsWritten += c_aaiRMSEnvHuffEnc[tabIdx][0]; + } + } + + return iBitsWritten; +} + + +#ifdef DEBUG_WRITE_MS_PRED +void writeMSPred( + int32_t *phaseQuant, + int32_t *predQuant, + int32_t MSMode, + int32_t numMSBands, + int32_t numBands, + void *fid, + int32_t *piMsFlags ) +{ + int32_t b; + + fid = (FILE *) fid; + fprintf( fid, "%d %d", MSMode, numMSBands ); + for ( b = 0; b < numMSBands; b++ ) + { + fprintf( fid, " %d", phaseQuant[b] ); + } + for ( b = numMSBands; b < numBands; b++ ) + { + fprintf( fid, " %d", 0 ); + } + for ( b = 0; b < numMSBands; b++ ) + { + fprintf( fid, " %d", predQuant[b] ); + } + for ( b = numMSBands; b < numBands; b++ ) + { + fprintf( fid, " %d", 0 ); + } + for ( b = 0; b < numBands; b++ ) + { + fprintf( fid, " %d", piMsFlags[b] ); + } + fprintf( fid, "\n" ); + + return; +} +#endif +#endif diff --git a/lib_rend/ivas_NoiseGen.c b/lib_rend/ivas_NoiseGen.c new file mode 100644 index 000000000..e4a24fabd --- /dev/null +++ b/lib_rend/ivas_NoiseGen.c @@ -0,0 +1,100 @@ +/****************************************************************************************************** + + (C) 2022-2023 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. + +*******************************************************************************************************/ + +#include +#include "options.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT +#include +#include "prot.h" +#include "ivas_lcld_prot.h" +#include "ivas_prot_rend.h" +#include "wmc_auto.h" + + +/*------------------------------------------------------------------------------------------* + * Function CreateNoiseGen() + * + * + *------------------------------------------------------------------------------------------*/ +// todo: not used!! +NoiseGen *CreateNoiseGen( void ) +{ + int32_t n; + + NoiseGen *psNoiseGen = NULL; + + psNoiseGen = (NoiseGen *) malloc( sizeof( NoiseGen ) ); + psNoiseGen->iNoiseBufferLength = 2048; + psNoiseGen->iNoiseBufferMask = 2047; + psNoiseGen->iNoiseBufferIndex = 0; + + psNoiseGen->pfNoiseBuffer = (float *) malloc( psNoiseGen->iNoiseBufferLength * sizeof( float ) ); + + /* Generate Laplacian distributed noise */ + for ( n = 0; n < psNoiseGen->iNoiseBufferLength; n++ ) + { + float fNoise = 0.0f; + float fScale = 0.707f; + fNoise = (float) ( ( rand() & ( RAND_MAX - 1 ) ) - ( RAND_MAX >> 1 ) ) / (float) RAND_MAX; + + if ( fNoise < 0.0 ) + { + fNoise = fScale * (float) logf( 1.0f + 1.9999999f * fNoise ); + } + else + { + fNoise = -fScale * (float) logf( 1.0f - 1.9999999f * fNoise ); + } + + psNoiseGen->pfNoiseBuffer[n] = fNoise; + } + + return psNoiseGen; +} + + +/*------------------------------------------------------------------------------------------* + * Function DeleteNoiseGen() + * + * + *------------------------------------------------------------------------------------------*/ + +void DeleteNoiseGen( NoiseGen *psNoiseGen ) +{ + free( psNoiseGen->pfNoiseBuffer ); + free( psNoiseGen ); + + return; +} + +extern float GetNoise( NoiseGen *psNoiseGen ); +#endif diff --git a/lib_rend/ivas_PerceptualModel.c b/lib_rend/ivas_PerceptualModel.c new file mode 100644 index 000000000..4250a4fe8 --- /dev/null +++ b/lib_rend/ivas_PerceptualModel.c @@ -0,0 +1,257 @@ +/****************************************************************************************************** + + (C) 2022-2023 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. + +*******************************************************************************************************/ + +#include +#include "options.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT +#include "ivas_lcld_prot.h" +#include "prot.h" +#include "ivas_prot_rend.h" +#include "ivas_lcld_rom_tables.h" +#include +#include "wmc_auto.h" + + +/*------------------------------------------------------------------------------------------* + * Local constants + *------------------------------------------------------------------------------------------*/ + +#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 int32_t LogAdd( + const int32_t iVal1, + const int32_t iVal2 ) +{ + int32_t iRetVal; + + if ( iVal1 > iVal2 ) + { + iRetVal = iVal1 - iVal2; + iRetVal = ( iRetVal < ( LOG_ADD_TABLE_LENGTH - 1 ) ) ? iRetVal : ( LOG_ADD_TABLE_LENGTH - 1 ); + iRetVal = iVal1 + c_aiLogAddTable[iRetVal]; + } + else + { + iRetVal = iVal2 - iVal1; + iRetVal = ( iRetVal < ( LOG_ADD_TABLE_LENGTH - 1 ) ) ? iRetVal : ( LOG_ADD_TABLE_LENGTH - 1 ); + iRetVal = iVal2 + c_aiLogAddTable[iRetVal]; + } + + return iRetVal; +} + + +/*------------------------------------------------------------------------------------------* + * Function PerceptualModel() + * + * + *------------------------------------------------------------------------------------------*/ + +void PerceptualModel( + const int32_t iMaxQuantBands, + const int32_t *piRMSEnvelope, + int32_t *piExcitation, + int32_t *piSMR ) +{ + int32_t n; + + for ( n = 0; n < iMaxQuantBands; n++ ) + { + int32_t iSLOffset; + + piExcitation[n] = PERCEPTUAL_MODEL_SCALE * piRMSEnvelope[n] + c_aiBandwidthAdjust48[n]; + + /* 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; + + /* Convert to loudness domain (x^0.3) */ + piExcitation[n] = PERCEPTUAL_MODEL_ALPHA_SCALE * piExcitation[n] >> PERCEPTUAL_MODEL_ALPHA_SHIFT; + } + + /* Spread excitation function */ + for ( n = 0; n < iMaxQuantBands; n++ ) + { + int32_t k; + const int32_t *piSpread; + + piSpread = &c_aaiSpreadFunction48[n * MAX_BANDS_48]; + piSMR[n] = piExcitation[n] + piSpread[n]; + for ( k = 0; k < iMaxQuantBands; k++ ) + { + if ( k != n ) + { + piSMR[n] = LogAdd( piSMR[n], piExcitation[k] + piSpread[k] ); + } + } + } + + for ( n = 0; n < iMaxQuantBands; n++ ) + { + piSMR[n] = PERCEPTUAL_MODEL_ALPHA_INV_SCALE * piSMR[n] >> PERCEPTUAL_MODEL_ALPHA_SHIFT; + piSMR[n] = PERCEPTUAL_MODEL_SCALE * piRMSEnvelope[n] + c_aiBandwidthAdjust48[n] - piSMR[n]; + } + + return; +} + + +/*------------------------------------------------------------------------------------------* + * Function PerceptualModelStereo() + * + * + *------------------------------------------------------------------------------------------*/ + +void PerceptualModelStereo( + const int32_t iMaxQuantBands, + const int32_t *piMSFlags, + const int32_t *piRMSEnvelope0, + const int32_t *piRMSEnvelope1, + int32_t *piExcitation0, + int32_t *piExcitation1, + int32_t *piSMR0, + int32_t *piSMR1 ) +{ + int32_t n; + + for ( n = 0; n < iMaxQuantBands; n++ ) + { + int32_t iMaxRMSEnv; + int32_t iSLOffset; + + iMaxRMSEnv = piRMSEnvelope0[n]; + + piExcitation0[n] = PERCEPTUAL_MODEL_SCALE * iMaxRMSEnv + c_aiBandwidthAdjust48[n]; /* piRMSEnvelope0[n] */ + + /* 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; + + /* Convert to loudness domain (x^0.3) */ + piExcitation0[n] = PERCEPTUAL_MODEL_ALPHA_SCALE * piExcitation0[n] >> PERCEPTUAL_MODEL_ALPHA_SHIFT; + } + + /* Spread excitation function */ + for ( n = 0; n < iMaxQuantBands; n++ ) + { + int32_t k; + const int32_t *piSpread; + + piSpread = &c_aaiSpreadFunction48[n * MAX_BANDS_48]; + piSMR0[n] = piExcitation0[n] + piSpread[n]; + for ( k = 0; k < iMaxQuantBands; k++ ) + { + if ( k != n ) + { + piSMR0[n] = LogAdd( piSMR0[n], piExcitation0[k] + piSpread[k] ); + } + } + } + + for ( n = 0; n < iMaxQuantBands; n++ ) + { + int32_t iMaxRMSEnv; + int32_t iSLOffset; + + iMaxRMSEnv = piRMSEnvelope1[n]; + + piExcitation1[n] = PERCEPTUAL_MODEL_SCALE * iMaxRMSEnv + c_aiBandwidthAdjust48[n]; /* piRMSEnvelope1[n] */ + + /* 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; + + /* Convert to loudness domain (x^0.3) */ + piExcitation1[n] = PERCEPTUAL_MODEL_ALPHA_SCALE * piExcitation1[n] >> PERCEPTUAL_MODEL_ALPHA_SHIFT; + } + + /* Spread excitation function */ + for ( n = 0; n < iMaxQuantBands; n++ ) + { + int32_t k; + const int32_t *piSpread; + + piSpread = &c_aaiSpreadFunction48[n * MAX_BANDS_48]; + piSMR1[n] = piExcitation1[n] + piSpread[n]; + for ( k = 0; k < iMaxQuantBands; k++ ) + { + if ( k != n ) + { + piSMR1[n] = LogAdd( piSMR1[n], piExcitation1[k] + piSpread[k] ); + } + } + } + + for ( n = 0; n < iMaxQuantBands; n++ ) + { + if ( piMSFlags[n] == 1 ) + { + piSMR0[n] = ( piSMR0[n] > piSMR1[n] ) ? piSMR0[n] : piSMR1[n]; + piSMR1[n] = piSMR0[n]; + } + } + + for ( n = 0; n < iMaxQuantBands; n++ ) + { + piSMR0[n] = PERCEPTUAL_MODEL_ALPHA_INV_SCALE * piSMR0[n] >> PERCEPTUAL_MODEL_ALPHA_SHIFT; + piSMR0[n] = PERCEPTUAL_MODEL_SCALE * piRMSEnvelope0[n] + c_aiBandwidthAdjust48[n] - piSMR0[n]; + } + + for ( n = 0; n < iMaxQuantBands; n++ ) + { + piSMR1[n] = PERCEPTUAL_MODEL_ALPHA_INV_SCALE * piSMR1[n] >> PERCEPTUAL_MODEL_ALPHA_SHIFT; + piSMR1[n] = PERCEPTUAL_MODEL_SCALE * piRMSEnvelope1[n] + c_aiBandwidthAdjust48[n] - piSMR1[n]; + } + + return; +} +#endif diff --git a/lib_rend/ivas_PredDecoder.c b/lib_rend/ivas_PredDecoder.c new file mode 100644 index 000000000..914435e2f --- /dev/null +++ b/lib_rend/ivas_PredDecoder.c @@ -0,0 +1,335 @@ +/****************************************************************************************************** + + (C) 2022-2023 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. + +*******************************************************************************************************/ + +#include +#include "options.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT +#include +#include "prot.h" +#include "ivas_prot_rend.h" +#include "ivas_lcld_prot.h" +#include "ivas_lcld_rom_tables.h" +#include "wmc_auto.h" + + +/*-------------------------------------------------------------------* + * Function CreatePredictionDecoder() + * + * + *-------------------------------------------------------------------*/ + +ivas_error CreatePredictionDecoder( + PredictionDecoder **psPredictionDecoder_out, + const int32_t iChannels, + const int32_t iNumBlocks ) +{ + int16_t n; + PredictionDecoder *psPredictionDecoder = 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; + psPredictionDecoder->iNumBlocks = iNumBlocks; + + if ( ( psPredictionDecoder->piPredChanEnable = (int32_t *) malloc( sizeof( int32_t ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + if ( ( psPredictionDecoder->piNumPredBands = (int32_t *) malloc( sizeof( int32_t ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + + if ( ( psPredictionDecoder->ppfEstPredGain = (float **) malloc( sizeof( float * ) * 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 ) + { + 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 ) + { + 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 ) + { + 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 ) + { + 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 ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + + for ( n = 0; n < psPredictionDecoder->iChannels; n++ ) + { + if ( ( psPredictionDecoder->ppfEstPredGain[n] = (float *) malloc( sizeof( float ) * LCLD_BANDS ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + if ( ( psPredictionDecoder->ppiPredBandEnable[n] = (int32_t *) malloc( sizeof( int32_t ) * LCLD_BANDS ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + if ( ( psPredictionDecoder->ppfA1Real[n] = (float *) malloc( sizeof( float ) * 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 ) + { + 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 ) + { + 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 ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + } + + /* pre-define these tables? */ + 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 ); + } + + 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_out = psPredictionDecoder; + + return IVAS_ERR_OK; +} + + +/*-------------------------------------------------------------------* + * Function DeletePredictionDecoder() + * + * + *-------------------------------------------------------------------*/ + +void DeletePredictionDecoder( + PredictionDecoder *psPredictionDecoder ) +{ + int32_t n; + + for ( n = 0; n < psPredictionDecoder->iChannels; n++ ) + { + free( psPredictionDecoder->ppfEstPredGain[n] ); + free( psPredictionDecoder->ppiPredBandEnable[n] ); + free( psPredictionDecoder->ppfA1Real[n] ); + free( psPredictionDecoder->ppfA1Imag[n] ); + free( psPredictionDecoder->ppiA1Mag[n] ); + free( psPredictionDecoder->ppiA1Phase[n] ); + } + free( psPredictionDecoder->piPredChanEnable ); + free( psPredictionDecoder->piNumPredBands ); + free( psPredictionDecoder->ppfEstPredGain ); + free( psPredictionDecoder->ppiPredBandEnable ); + free( psPredictionDecoder->ppfA1Real ); + free( psPredictionDecoder->ppfA1Imag ); + free( psPredictionDecoder->ppiA1Mag ); + free( psPredictionDecoder->ppiA1Phase ); + + free( psPredictionDecoder ); + psPredictionDecoder = NULL; + + return; +} + + +#define USE_TABLE_LOOKUP +/*-------------------------------------------------------------------* + * Function ReadPredictors() + * + * + *-------------------------------------------------------------------*/ + +int32_t ReadPredictors( + PredictionDecoder *psPredictionDecoder, + IVAS_SPLIT_REND_BITS_HANDLE pBits ) +{ + int16_t iBitsRead = 0; + int32_t c; + + for ( c = 0; c < psPredictionDecoder->iChannels; c++ ) + { + psPredictionDecoder->piPredChanEnable[c] = ivas_split_rend_bitstream_read_int32( pBits, 1 ); + iBitsRead += 1; + + if ( psPredictionDecoder->piPredChanEnable[c] ) + { + int32_t b; + + for ( b = 0; b < LCLD_BANDS; b++ ) + { + psPredictionDecoder->ppiPredBandEnable[c][b] = 0; + } + psPredictionDecoder->piNumPredBands[c] = ivas_split_rend_bitstream_read_int32( pBits, 6 ); + iBitsRead += 6; + + for ( b = 0; b < psPredictionDecoder->piNumPredBands[c]; b++ ) + { + psPredictionDecoder->ppiPredBandEnable[c][b] = ivas_split_rend_bitstream_read_int32( pBits, 1 ); + iBitsRead += 1; + + if ( psPredictionDecoder->ppiPredBandEnable[c][b] == 1 ) + { +#ifdef USE_TABLE_LOOKUP + int32_t iA1Mag; + int32_t iA1Phase; + float fA1Real; + float fA1Imag; + iA1Mag = ivas_split_rend_bitstream_read_int32( pBits, PRED_QUNAT_FILTER_MAG_BITS ); + iBitsRead += PRED_QUNAT_FILTER_MAG_BITS; + iA1Phase = ivas_split_rend_bitstream_read_int32( pBits, PRED_QUANT_FILTER_PHASE_BITS ); + iBitsRead += PRED_QUANT_FILTER_PHASE_BITS; + + psPredictionDecoder->ppiA1Mag[c][b] = iA1Mag; + psPredictionDecoder->ppiA1Phase[c][b] = iA1Phase + PRED_QUANT_FILTER_PHASE_MIN; + + fA1Real = psPredictionDecoder->pfMagLUT[iA1Mag] * psPredictionDecoder->pfP2RRealLUT[iA1Phase]; + fA1Imag = psPredictionDecoder->pfMagLUT[iA1Mag] * psPredictionDecoder->pfP2RImagLUT[iA1Phase]; + + psPredictionDecoder->ppfA1Real[c][b] = fA1Real; + psPredictionDecoder->ppfA1Imag[c][b] = fA1Imag; +#else + const float fInvMagScale = M_PI / ( 2.0 * (float) ( 1 << ( PRED_QUNAT_FILTER_MAG_BITS ) ) + 1.0 ); + const float fInvPhaseScale = M_PI / (float) ( 1 << ( PRED_QUANT_FILTER_PHASE_BITS - 1 ) ); + int32_t iA1Mag; + int32_t iA1Phase; + float fA1Mag; + float fA1Phase; + float fA1Real; + float fA1Imag; + + iA1Mag = ivas_split_rend_bitstream_read_int32( pBits, PRED_QUNAT_FILTER_MAG_BITS ); + iBitsRead += PRED_QUNAT_FILTER_MAG_BITS; + + iA1Phase = ivas_split_rend_bitstream_read_int32( pBits, PRED_QUANT_FILTER_PHASE_BITS ); + iBitsRead += PRED_QUANT_FILTER_PHASE_BITS; + iA1Phase += PRED_QUANT_FILTER_PHASE_MIN; + + psPredictionDecoder->ppiA1Mag[c][b] = iA1Mag; + psPredictionDecoder->ppiA1Phase[c][b] = iA1Phase; + + fA1Mag = sinf( fInvMagScale * (float) iA1Mag ); + fA1Phase = fInvPhaseScale * (float) iA1Phase; + + fA1Real = fA1Mag * cosf( fA1Phase ); + fA1Imag = fA1Mag * sinf( fA1Phase ); + + psPredictionDecoder->ppfA1Real[c][b] = fA1Real; + psPredictionDecoder->ppfA1Imag[c][b] = fA1Imag; + + /* printf("Dec %f\t%f\t%f\n",fA1Real,fA1Imag,fA1Real * fA1Real + fA1Imag * fA1Imag); */ +#endif + } + } + } + else + { + int16_t b; + for ( b = 0; b < LCLD_BANDS; b++ ) + { + psPredictionDecoder->ppiPredBandEnable[c][b] = 0; + } + } + } + + return iBitsRead; +} + + +/*-------------------------------------------------------------------* + * Function ApplyInversePredictros() + * + * + *-------------------------------------------------------------------*/ + +void ApplyInversePredictros( + PredictionDecoder *psPredictionDecoder, + float ***pppfReal, + float ***pppfImag ) +{ + int32_t c; + for ( c = 0; c < psPredictionDecoder->iChannels; c++ ) + { + if ( psPredictionDecoder->piPredChanEnable[c] == 1 ) + { + int32_t b; + for ( b = 0; b < psPredictionDecoder->piNumPredBands[c]; b++ ) + { + if ( psPredictionDecoder->ppiPredBandEnable[c][b] == 1 ) + { + int32_t n; + float fA1Real; + float fA1Imag; + + fA1Real = psPredictionDecoder->ppfA1Real[c][b]; + fA1Imag = psPredictionDecoder->ppfA1Imag[c][b]; + for ( n = 1; n < psPredictionDecoder->iNumBlocks; n++ ) + { + float fReal; + float fImag; + + fReal = pppfReal[c][n][b] - fA1Real * pppfReal[c][n - 1][b] + fA1Imag * pppfImag[c][n - 1][b]; + fImag = pppfImag[c][n][b] - fA1Real * pppfImag[c][n - 1][b] - fA1Imag * pppfReal[c][n - 1][b]; + + pppfReal[c][n][b] = fReal; + pppfImag[c][n][b] = fImag; + } + } + } + } + } + + return; +} +#endif diff --git a/lib_rend/ivas_PredEncoder.c b/lib_rend/ivas_PredEncoder.c new file mode 100644 index 000000000..804a00a6a --- /dev/null +++ b/lib_rend/ivas_PredEncoder.c @@ -0,0 +1,531 @@ +/****************************************************************************************************** + + (C) 2022-2023 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. + +*******************************************************************************************************/ + +#include +#include "options.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT +#include +#include "ivas_lcld_prot.h" +#include "ivas_lcld_rom_tables.h" +#include "prot.h" +#include "ivas_prot_rend.h" +#include "wmc_auto.h" + + +/*-------------------------------------------------------------------* + * Function CreatePredictionEncoder() + * + * + *-------------------------------------------------------------------*/ + +ivas_error CreatePredictionEncoder( + PredictionEncoder **psPredictionEncoder_out, + const int32_t iChannels, + const int32_t iNumBlocks ) +{ + int32_t 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; + psPredictionEncoder->iNumBlocks = iNumBlocks; + + if ( ( psPredictionEncoder->pfWindow = (float *) malloc( sizeof( float ) * iNumBlocks ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + for ( n = 0; n < iNumBlocks; n++ ) + { + psPredictionEncoder->pfWindow[n] = 0.54f - 0.46f * cosf( 2.0f * M_PI * ( (float) n + 0.5f ) / (float) iNumBlocks ); + } + + if ( ( psPredictionEncoder->piPredChanEnable = (int32_t *) malloc( sizeof( int32_t ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + + if ( ( psPredictionEncoder->piNumPredBands = (int32_t *) malloc( sizeof( int32_t ) * 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; + psPredictionEncoder->piNumPredBands[n] = 40; // Will need to be set correctly + } + + if ( ( psPredictionEncoder->ppfEstPredGain = (float **) malloc( sizeof( float * ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + if ( ( psPredictionEncoder->ppfEstPredBitGain = (float **) malloc( sizeof( float * ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + if ( ( psPredictionEncoder->ppiPredBandEnable = (int32_t **) malloc( sizeof( int32_t * ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + if ( ( psPredictionEncoder->ppfA1Real = (float **) malloc( sizeof( float * ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + if ( ( psPredictionEncoder->ppfA1Imag = (float **) malloc( sizeof( float * ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + if ( ( psPredictionEncoder->ppiA1Mag = (int32_t **) malloc( sizeof( int32_t * ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + if ( ( psPredictionEncoder->ppiA1Phase = (int32_t **) malloc( sizeof( int32_t * ) * 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->ppfEstPredGain[n] = (float *) malloc( sizeof( float ) * LCLD_BANDS ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + if ( ( psPredictionEncoder->ppfEstPredBitGain[n] = (float *) malloc( sizeof( float ) * LCLD_BANDS ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + if ( ( psPredictionEncoder->ppiPredBandEnable[n] = (int32_t *) malloc( sizeof( int32_t ) * LCLD_BANDS ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + if ( ( psPredictionEncoder->ppfA1Real[n] = (float *) malloc( sizeof( float ) * LCLD_BANDS ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + if ( ( psPredictionEncoder->ppfA1Imag[n] = (float *) malloc( sizeof( float ) * LCLD_BANDS ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + if ( ( psPredictionEncoder->ppiA1Mag[n] = (int32_t *) malloc( sizeof( int32_t ) * LCLD_BANDS ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + if ( ( psPredictionEncoder->ppiA1Phase[n] = (int32_t *) malloc( sizeof( int32_t ) * LCLD_BANDS ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + for ( k = 0; k < LCLD_BANDS; k++ ) + { + psPredictionEncoder->ppiPredBandEnable[n][k] = 0; + psPredictionEncoder->ppfA1Real[n][k] = 0.0; + psPredictionEncoder->ppfA1Imag[n][k] = 0.0; + } + } + + *psPredictionEncoder_out = psPredictionEncoder; + + return IVAS_ERR_OK; +} + + +/*-------------------------------------------------------------------* + * Function DeletePredictionEncoder() + * + * + *-------------------------------------------------------------------*/ + +void DeletePredictionEncoder( + PredictionEncoder *psPredictionEncoder ) +{ + int32_t n; + + free( psPredictionEncoder->pfWindow ); + + for ( n = 0; n < psPredictionEncoder->iChannels; n++ ) + { + free( psPredictionEncoder->ppfEstPredGain[n] ); + free( psPredictionEncoder->ppfEstPredBitGain[n] ); + free( psPredictionEncoder->ppiPredBandEnable[n] ); + free( psPredictionEncoder->ppfA1Real[n] ); + free( psPredictionEncoder->ppfA1Imag[n] ); + free( psPredictionEncoder->ppiA1Mag[n] ); + free( psPredictionEncoder->ppiA1Phase[n] ); + } + free( psPredictionEncoder->piPredChanEnable ); + free( psPredictionEncoder->piNumPredBands ); + free( psPredictionEncoder->ppfEstPredGain ); + free( psPredictionEncoder->ppfEstPredBitGain ); + free( psPredictionEncoder->ppiPredBandEnable ); + free( psPredictionEncoder->ppfA1Real ); + free( psPredictionEncoder->ppfA1Imag ); + free( psPredictionEncoder->ppiA1Mag ); + free( psPredictionEncoder->ppiA1Phase ); + + free( psPredictionEncoder ); + + return; +} + + +//#define USE_RXX_WINDOW + +/*-------------------------------------------------------------------* + * Function ComputePredictors() + * + * + *-------------------------------------------------------------------*/ + +int32_t ComputePredictors( + PredictionEncoder *psPredictionEncoder, + float ***pppfReal, + float ***pppfImag ) +{ + int32_t c; + int32_t iPredictionBits = 0; + + for ( c = 0; c < psPredictionEncoder->iChannels; c++ ) + { + int32_t b; + psPredictionEncoder->piNumPredBands[c] = 50; + for ( b = 0; b < psPredictionEncoder->piNumPredBands[c]; b++ ) + { + int32_t n; + int32_t iNumBlocks; + float fGain = 0.0; + float fBitGain = 0.0; + float *pfRxxReal; + float *pfRxxImag; + float fA1Real; + float fA1Imag; + int32_t iA1Mag; + int32_t iA1Phase; + + iNumBlocks = psPredictionEncoder->iNumBlocks; + + pfRxxReal = psPredictionEncoder->pfRxxReal; + pfRxxImag = psPredictionEncoder->pfRxxImag; + + pfRxxReal[0] = 0.0; + pfRxxImag[0] = 0.0; + for ( n = 0; n < iNumBlocks; n++ ) + { +#ifdef USE_RXX_WINDOW + float fReal; + float fImag; + fReal = psPredictionEncoder->pfWindow[n] * pppfReal[c][n][b]; + fImag = psPredictionEncoder->pfWindow[n] * pppfImag[c][n][b]; + pfRxxReal[0] += ( fReal * fReal + fImag * fImag ); +#else + pfRxxReal[0] += ( pppfReal[c][n][b] * pppfReal[c][n][b] + pppfImag[c][n][b] * pppfImag[c][n][b] ); +#endif + } + + pfRxxReal[1] = 0.0; + pfRxxImag[1] = 0.0; + for ( n = 1; n < iNumBlocks; n++ ) + { +#ifdef USE_RXX_WINDOW + float fReal1; + float fImag1; + float fReal2; + float fImag2; + fReal1 = psPredictionEncoder->pfWindow[n] * pppfReal[c][n][b]; + fImag1 = psPredictionEncoder->pfWindow[n] * pppfImag[c][n][b]; + fReal2 = psPredictionEncoder->pfWindow[n - 1] * pppfReal[c][n - 1][b]; + fImag2 = psPredictionEncoder->pfWindow[n - 1] * pppfImag[c][n - 1][b]; + pfRxxReal[1] += ( fReal1 * fReal2 + fImag1 * fImag2 ); + pfRxxImag[1] += ( fImag1 * fReal2 - fReal1 * fImag2 ); +#else + pfRxxReal[1] += ( pppfReal[c][n][b] * pppfReal[c][n - 1][b] + pppfImag[c][n][b] * pppfImag[c][n - 1][b] ); + pfRxxImag[1] += ( pppfImag[c][n][b] * pppfReal[c][n - 1][b] - pppfReal[c][n][b] * pppfImag[c][n - 1][b] ); +#endif + } + + if ( pfRxxReal[0] > 1e-12f ) + { + float fA1Mag; + float fA1Phase; + float fGain2; + float fBitGain2; + + const float fMagScale = ( 2.0f * (float) ( 1 << ( PRED_QUNAT_FILTER_MAG_BITS ) ) + 1.0f ) / M_PI; + const float fInvMagScale = M_PI / ( 2.0f * (float) ( 1 << ( PRED_QUNAT_FILTER_MAG_BITS ) ) + 1.0f ); + const float fPhaseScale = (float) ( 1 << ( PRED_QUANT_FILTER_PHASE_BITS - 1 ) ) / M_PI; + const float fInvPhaseScale = M_PI / (float) ( 1 << ( PRED_QUANT_FILTER_PHASE_BITS - 1 ) ); + + /* Compute filter coefficeints */ + fA1Real = -pfRxxReal[1] / pfRxxReal[0]; + fA1Imag = -pfRxxImag[1] / pfRxxReal[0]; + + /* compute these before quant */ + /* Compute est coding gain based on quantized filter coefficients */ + fGain = 1.0f / ( 1.0f - fA1Real * fA1Real - fA1Imag * fA1Imag ); + fBitGain = 0.6f * log2f( fGain ) * (float) ( iNumBlocks ) - (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 ); + 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 ); + + fA1Phase = atan2f( fA1Imag, fA1Real ); + 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; // 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.6f * log2f( fGain ) * (float) ( iNumBlocks ) - (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; + } + else + { + psPredictionEncoder->ppfEstPredGain[c][b] = 0.0f; + fA1Real = 0.0f; + fA1Imag = 0.0f; + // iA1Real = 0; + // iA1Imag = 0; + iA1Mag = 0; + iA1Phase = 0; + fGain = -10.0f; // Fix this + } + + psPredictionEncoder->ppfEstPredGain[c][b] = fGain; + psPredictionEncoder->ppfEstPredBitGain[c][b] = fBitGain; + psPredictionEncoder->ppiPredBandEnable[c][b] = ( fBitGain > 0 ) ? 1 : 0; // Initial prediction enable + psPredictionEncoder->ppfA1Real[c][b] = fA1Real; + psPredictionEncoder->ppfA1Imag[c][b] = fA1Imag; + psPredictionEncoder->ppiA1Mag[c][b] = iA1Mag; + psPredictionEncoder->ppiA1Phase[c][b] = iA1Phase; + } + + { + /*int32_t iDone; + int32_t iPredBands; + + iDone = 0; + iPredBands = 30; + while(iPredBands > 0 && iDone == 0){ + int32_t b; + float fBitGain; + + fBitGain = -7.0; + for(b = 0; b < iPredBands; b ++){ + fBitGain -= 1.0; + if(psPredictionEncoder->ppiPredBandEnable[c][b] == 1){ + fBitGain += psPredictionEncoder->ppfEstPredBitGain[c][b]; + } + } + if(fBitGain > 0.0){ //thresh + iDone ++; + } + else{ + iPredBands --; + } + }*/ + // int32_t b; + float fBestCost; + int32_t iPredBands; + float fBitGain; + + fBestCost = 0.0; + iPredBands = 0; + fBitGain = -7.0; + for ( b = 0; b < 30; b++ ) + { // still getting this decision wrong! + fBitGain -= 1.0; + if ( psPredictionEncoder->ppiPredBandEnable[c][b] == 1 ) + { + fBitGain += psPredictionEncoder->ppfEstPredBitGain[c][b]; + } + if ( fBitGain > fBestCost ) + { + fBestCost = fBitGain; + iPredBands = b; + } + } + + // printf("%d\t%f\n",iPredBands,fBestCost); + /*if(fBestCost < 300.0){ + iPredBands = 0; + }*/ + + if ( iPredBands > 0 ) + { + // int32_t b; + iPredictionBits += 1; + iPredictionBits += 6; + for ( b = 0; b < iPredBands; b++ ) + { + iPredictionBits += 1; + if ( psPredictionEncoder->ppiPredBandEnable[c][b] == 1 ) + { + iPredictionBits += ( PRED_QUNAT_FILTER_MAG_BITS + PRED_QUANT_FILTER_PHASE_BITS ); + } + } + for ( b = iPredBands; b < LCLD_BANDS; b++ ) + { + psPredictionEncoder->ppiPredBandEnable[c][b] = 0; + } + psPredictionEncoder->piPredChanEnable[c] = 1; + psPredictionEncoder->piNumPredBands[c] = iPredBands; + } + else + { + // int32_t b; + iPredictionBits += 1; + for ( b = 0; b < LCLD_BANDS; b++ ) + { + psPredictionEncoder->ppiPredBandEnable[c][b] = 0; + } + psPredictionEncoder->piPredChanEnable[c] = 0; + psPredictionEncoder->piNumPredBands[c] = 0; + } + } + } + + return iPredictionBits; +} + + +/*-------------------------------------------------------------------* + * Function ApplyForwardPredictors() + * + * + *-------------------------------------------------------------------*/ + +void ApplyForwardPredictors( + PredictionEncoder *psPredictionEncoder, + float ***pppfReal, + float ***pppfImag ) +{ + int32_t c; + for ( c = 0; c < psPredictionEncoder->iChannels; c++ ) + { + int32_t b; + if ( psPredictionEncoder->piPredChanEnable[c] == 1 ) + { + for ( b = 0; b < psPredictionEncoder->piNumPredBands[c]; b++ ) + { + if ( psPredictionEncoder->ppiPredBandEnable[c][b] == 1 ) + { + int32_t n; + float fOldReal; + float fOldImag; + float fA1Real; + float fA1Imag; + + fOldReal = pppfReal[c][0][b]; + fOldImag = pppfImag[c][0][b]; + fA1Real = psPredictionEncoder->ppfA1Real[c][b]; + fA1Imag = psPredictionEncoder->ppfA1Imag[c][b]; + for ( n = 1; n < psPredictionEncoder->iNumBlocks; n++ ) + { + float fReal; + float fImag; + + fReal = pppfReal[c][n][b] + fA1Real * fOldReal - fA1Imag * fOldImag; + fImag = pppfImag[c][n][b] + fA1Real * fOldImag + fA1Imag * fOldReal; + + fOldReal = pppfReal[c][n][b]; + fOldImag = pppfImag[c][n][b]; + + pppfReal[c][n][b] = fReal; + pppfImag[c][n][b] = fImag; + } + } + } + } + } + + return; +} + + +/*-------------------------------------------------------------------* + * Function WritePredictors() + * + * + *-------------------------------------------------------------------*/ + +int32_t WritePredictors( + PredictionEncoder *psPredictionEncoder, + IVAS_SPLIT_REND_BITS_HANDLE pBits ) +{ + int32_t iBitsWritten = 0; + int32_t c; + + for ( c = 0; c < psPredictionEncoder->iChannels; c++ ) + { + int32_t b; + ivas_split_rend_bitstream_write_int32( pBits, psPredictionEncoder->piPredChanEnable[c], 1 ); + iBitsWritten += 1; + + if ( psPredictionEncoder->piPredChanEnable[c] == 1 ) + { + ivas_split_rend_bitstream_write_int32( pBits, psPredictionEncoder->piNumPredBands[c], 6 ); + iBitsWritten += 6; + + for ( b = 0; b < psPredictionEncoder->piNumPredBands[c]; b++ ) + { + ivas_split_rend_bitstream_write_int32( pBits, psPredictionEncoder->ppiPredBandEnable[c][b], 1 ); + iBitsWritten += 1; + + if ( psPredictionEncoder->ppiPredBandEnable[c][b] == 1 ) + { + int32_t iA1Mag; + int32_t iA1Phase; + + iA1Mag = psPredictionEncoder->ppiA1Mag[c][b]; + iA1Phase = psPredictionEncoder->ppiA1Phase[c][b] - PRED_QUANT_FILTER_PHASE_MIN; + ivas_split_rend_bitstream_write_int32( pBits, iA1Mag, PRED_QUNAT_FILTER_MAG_BITS ); + iBitsWritten += PRED_QUNAT_FILTER_MAG_BITS; + ivas_split_rend_bitstream_write_int32( pBits, iA1Phase, PRED_QUANT_FILTER_PHASE_BITS ); + iBitsWritten += PRED_QUANT_FILTER_PHASE_BITS; + } + } + } + } + + return iBitsWritten; +} +#endif diff --git a/lib_rend/ivas_RMSEnvGrouping.c b/lib_rend/ivas_RMSEnvGrouping.c new file mode 100644 index 000000000..770165ba6 --- /dev/null +++ b/lib_rend/ivas_RMSEnvGrouping.c @@ -0,0 +1,951 @@ +/****************************************************************************************************** + + (C) 2022-2023 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. + +*******************************************************************************************************/ + +/* Double check cost function calculation */ + +#include +#include "options.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT +#include +#include "prot.h" +#include "ivas_prot_rend.h" +#include "ivas_lcld_prot.h" +#include "ivas_lcld_rom_tables.h" +#include "wmc_auto.h" + + +/*-------------------------------------------------------------------* + * 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 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, +}; + +typedef struct GMNODE +{ + int32_t iGroupStart; + int32_t iGroupLength; + float *pfMergedEnergydB; + int32_t *piQRMSEnvelope; + + int32_t iGroupRMSEnvelopeCost; + float fGroupSNRPenalty; + + struct GMNODE *psNext; +} GMNode; + +struct RMS_ENVELOPE_GROUPING +{ + int32_t iNumBlocks; + int32_t iMaxGroups; + float **ppfBandEnergy; + float **ppfBandEnergydB; + float **ppfWeight; + GMNode *psGMNodes; +}; + + +/*-------------------------------------------------------------------* + * Function CreateRMSEnvelopeGrouping() + * + * + *-------------------------------------------------------------------*/ + +RMSEnvelopeGrouping *CreateRMSEnvelopeGrouping( + const int32_t iNumBlocks ) +{ + int32_t n; + + RMSEnvelopeGrouping *psRMSEnvelopeGrouping; + + psRMSEnvelopeGrouping = (RMSEnvelopeGrouping *) malloc( sizeof( RMSEnvelopeGrouping ) ); + psRMSEnvelopeGrouping->iNumBlocks = iNumBlocks; + + psRMSEnvelopeGrouping->iMaxGroups = iNumBlocks >> 1; + + 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->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].iGroupRMSEnvelopeCost = -1; + psRMSEnvelopeGrouping->psGMNodes[n].fGroupSNRPenalty = -1.0; + } + + return psRMSEnvelopeGrouping; +} + + +/*-------------------------------------------------------------------* + * Function DeleteRMSEnvelopeGrouping() + * + * + *-------------------------------------------------------------------*/ + +void DeleteRMSEnvelopeGrouping( + RMSEnvelopeGrouping *psRMSEnvelopeGrouping ) +{ + int32_t n; + + for ( n = 0; n < psRMSEnvelopeGrouping->iNumBlocks; n++ ) + { + free( psRMSEnvelopeGrouping->ppfBandEnergy[n] ); + free( psRMSEnvelopeGrouping->ppfBandEnergydB[n] ); + free( psRMSEnvelopeGrouping->ppfWeight[n] ); + } + free( psRMSEnvelopeGrouping->ppfBandEnergy ); + free( psRMSEnvelopeGrouping->ppfBandEnergydB ); + free( psRMSEnvelopeGrouping->ppfWeight ); + + for ( n = 0; n < psRMSEnvelopeGrouping->iNumBlocks; n++ ) + { + free( psRMSEnvelopeGrouping->psGMNodes[n].pfMergedEnergydB ); + free( psRMSEnvelopeGrouping->psGMNodes[n].piQRMSEnvelope ); + } + free( psRMSEnvelopeGrouping->psGMNodes ); + + free( psRMSEnvelopeGrouping ); + + return; +} + + +/*-------------------------------------------------------------------* + * Function ComputeBandEnergy() + * + * + *-------------------------------------------------------------------*/ + +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 ) +{ + int32_t n; + + for ( n = 0; n < iChannels; n++ ) + { + int32_t k; + int32_t iChanOffset; + + iChanOffset = n * iNumBands; + for ( k = 0; k < iNumBlocks; k++ ) + { + int32_t b; + int32_t iFBOffset; + float fMaxWeight; + + iFBOffset = 0; + fMaxWeight = 0.0f; + for ( b = 0; b < iNumBands; b++ ) + { + int32_t m; + float fEnergy = 1e-12f; + float fWeight; + + for ( m = 0; m < piBandwidths[b]; m++ ) + { + fEnergy += ( pppfReal[n][k][iFBOffset] * pppfReal[n][k][iFBOffset] + pppfImag[n][k][iFBOffset] * pppfImag[n][k][iFBOffset] ); + 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; + +#ifdef APPLY_TEMPORAL_SMOOTHING + if ( k > 0 ) + { + float fSmoothEnergy; + fSmoothEnergy = 0.7f * ppfBandEnergy[k - 1][iChanOffset + b] + 0.3f * fEnergy; + + fEnergy = ( fEnergy > fSmoothEnergy ) ? fEnergy : fSmoothEnergy; + } +#endif + fEnergy = 10.0f * log10f( fEnergy ); + ppfBandEnergydB[k][iChanOffset + b] = fEnergy; + } + for ( b = 0; b < iNumBands; b++ ) + { + ppfWeight[k][iChanOffset + b] /= fMaxWeight; + } + } + } + + return; +} + + +/*-------------------------------------------------------------------* + * Function TryMerge() + * + * + *-------------------------------------------------------------------*/ + +/* THis is temporary cost function */ +static float TryMerge( + const int32_t iNumBands, + const int32_t iStartBlock, + const int32_t iGroupLength, + const float fMaxAllowedDiffdB, + float **ppfBandEnergy, + float **ppfBandEnergydB, +#ifdef APPLY_WEIGHT + float **ppfWeight, +#endif + float *pfMegredEnergydB ) +{ + int32_t b; + int32_t n; + float fMeanCost; + float fMaxCost; + float fMinDiffCost; + float fMaxDiffCost; + float fInvGroupSize = 1.0f / (float) iGroupLength; + float fInvNumBands = 1.0f / (float) iNumBands; + + for ( b = 0; b < iNumBands; b++ ) + { + float fGroupEnergy; + + + fGroupEnergy = 0.0; + for ( n = iStartBlock; n < ( iStartBlock + iGroupLength ); n++ ) + { + fGroupEnergy += ppfBandEnergy[n][b]; + } + fGroupEnergy *= fInvGroupSize; + fGroupEnergy = 10.0f * log10f( fGroupEnergy ); // Note epsolon was added when computing BandEnergy; + + pfMegredEnergydB[b] = fGroupEnergy; + } + + fMeanCost = 0.0; + fMaxCost = 0.0; + fMinDiffCost = 0.0; + fMaxDiffCost = 0.0; + for ( n = iStartBlock; n < ( iStartBlock + iGroupLength ); n++ ) + { + float fMeanAbsDiff; + float fMaxAbsDiff; + float fMaxDiff; + float fMinDiff; + + fMeanAbsDiff = 0.0; + fMaxAbsDiff = 0.0; + fMaxDiff = 0.0; + fMinDiff = 0.0; + for ( b = 0; b < iNumBands; b++ ) + { + float fDiff; + float fAbsDiff; + + fDiff = pfMegredEnergydB[b] - ppfBandEnergydB[n][b]; // Changed the order of this + fAbsDiff = fabsf( fDiff ); +#ifdef APPLY_WEIGHT + fAbsDiff *= ppfWeight[n][b]; +#endif + + fMeanAbsDiff += fAbsDiff; + fMaxAbsDiff = ( fMaxAbsDiff > fAbsDiff ) ? fMaxAbsDiff : fAbsDiff; + + + fMaxDiff = ( fMaxDiff > fDiff ) ? fMaxDiff : fDiff; + fMinDiff = ( fMinDiff < fDiff ) ? fMinDiff : fDiff; + } + fMeanAbsDiff *= fInvNumBands; + + fMeanCost = ( fMeanCost > fMeanAbsDiff ) ? fMeanCost : fMeanAbsDiff; + fMaxCost = ( fMaxCost > fMaxAbsDiff ) ? fMaxCost : fMaxAbsDiff; + + fMaxDiffCost = ( fMaxDiffCost > fMaxDiff ) ? fMaxDiffCost : fMaxDiff; + fMinDiffCost = ( fMinDiffCost < fMinDiff ) ? fMinDiffCost : fMinDiff; + } + + // printf("%f\t%f\t%f\t%f\n",fMeanCost,fMaxCost,fMaxDiffCost,fMinDiffCost); + + /*if(fMinDiffCost < -9.0){ // This prevents cliping + fMeanCost = 1e12; //Some large value + }*/ + + if ( fMaxCost > fMaxAllowedDiffdB ) + { + fMeanCost = 1e12f; // Some large value + } + + return fMeanCost; +} + + +/*-------------------------------------------------------------------* + * Function ComputeMergeRMS() + * + * + *-------------------------------------------------------------------*/ + +static void ComputeMergeRMS( + const int32_t iNumBands, + const int32_t iStartBlock, + const int32_t iGroupLength, + float **ppfBandEnergy, + float *pfMergedEnergydB, + int32_t *piQRMSEnvelope ) +{ + int32_t b; + float fInvGroupSize = 1.0f / (float) iGroupLength; + + 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++ ) + { + fGroupEnergy += ppfBandEnergy[n][b]; + } + 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 epsolon was added when computing BandEnergy; + + pfMergedEnergydB[b] = fGroupEnergy; + piQRMSEnvelope[b] = iQRMSEnvelope; + } + + return; +} + + +/*-------------------------------------------------------------------* + * Function ComputeRMSEnvelopeBits() + * + * + *-------------------------------------------------------------------*/ + +static int32_t ComputeRMSEnvelopeBits( + const int32_t iChannels, + const int32_t iNumBands, + const int32_t *piQRMSEnevelope ) +{ + int32_t n; + int32_t iRMSEnvelopeBits = 0; + int32_t iChanOffset = 0; + + for ( n = 0; n < iChannels; n++ ) + { + int32_t b; + int32_t iLastRMSVal; + + iRMSEnvelopeBits += ENV0_BITS; + iLastRMSVal = piQRMSEnevelope[iChanOffset]; + for ( b = 1; b < iNumBands; b++ ) + { + int32_t iDelta; + + iDelta = 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]; + + iLastRMSVal = piQRMSEnevelope[iChanOffset + b]; + } + + 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 ) +{ + int32_t n; + int32_t iChanOffset; + float fSNRPenalty = 0.0; + + iChanOffset = 0; + for ( n = 0; n < iChannels; n++ ) + { + int32_t 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++ ) + { + float fDeltadB; + + fDeltadB = fRMSVal - ppfBandEnergydB[k][iChanOffset + b]; + if ( fDeltadB < -9.0309f ) + { + fSNRPenalty += 1e10f; // Some large number to prevent clipping + } + else /*if(fDeltadB < 0.0)*/ + { + fSNRPenalty += fabsf( c_fiDefaultTheta48[b] * fDeltadB - fDeltadB ) * 2.0f * (float) piBandwidths[b] / 6.0f; + } + } + } + + iChanOffset += iNumBands; + } + + return fSNRPenalty; +} + + +/*-------------------------------------------------------------------* + * Function TryMerge2() + * + * + *-------------------------------------------------------------------*/ + +static float TryMerge2( + const int32_t iChannels, + const int32_t iNumBands, + const int32_t *piBandwidths, + float **ppfBandEnergy, + float **ppfBandEnergydB, + GMNode *psGMNode1, + GMNode *psGMNode2 ) +{ + int32_t iRMSEnvBits1; + int32_t iRMSEnvBits2; + int32_t iRMSEnvBitsMerged; + float fSNRPenalty1; + float fSNRPenalty2; + float fSNRPenaltyMerged; + float fMergedCost = 0.0; + + /* First compute current RMS Envelope for each group */ + if ( psGMNode1->iGroupRMSEnvelopeCost == -1 || psGMNode1->fGroupSNRPenalty == -1.0 ) + { + ComputeMergeRMS( iNumBands * iChannels, psGMNode1->iGroupStart, psGMNode1->iGroupLength, ppfBandEnergy, psGMNode1->pfMergedEnergydB, psGMNode1->piQRMSEnvelope ); + + iRMSEnvBits1 = ComputeRMSEnvelopeBits( iChannels, iNumBands, psGMNode1->piQRMSEnvelope ); + + fSNRPenalty1 = ComputeSNRPenalty( iChannels, iNumBands, piBandwidths, psGMNode1->iGroupStart, psGMNode1->iGroupLength, ppfBandEnergydB, psGMNode1->piQRMSEnvelope ); + + psGMNode1->iGroupRMSEnvelopeCost = iRMSEnvBits1; + psGMNode1->fGroupSNRPenalty = fSNRPenalty1; + } + else + { + iRMSEnvBits1 = psGMNode1->iGroupRMSEnvelopeCost; + fSNRPenalty1 = psGMNode1->fGroupSNRPenalty; + } + + if ( psGMNode2->iGroupRMSEnvelopeCost == -1 || psGMNode2->fGroupSNRPenalty == -1.0 ) + { + ComputeMergeRMS( iNumBands * iChannels, psGMNode2->iGroupStart, psGMNode2->iGroupLength, ppfBandEnergy, psGMNode2->pfMergedEnergydB, psGMNode2->piQRMSEnvelope ); + + iRMSEnvBits2 = ComputeRMSEnvelopeBits( iChannels, iNumBands, psGMNode2->piQRMSEnvelope ); + + fSNRPenalty2 = ComputeSNRPenalty( iChannels, iNumBands, piBandwidths, psGMNode2->iGroupStart, psGMNode2->iGroupLength, ppfBandEnergydB, psGMNode2->piQRMSEnvelope ); + + psGMNode2->iGroupRMSEnvelopeCost = iRMSEnvBits2; + psGMNode2->fGroupSNRPenalty = fSNRPenalty2; + } + else + { + iRMSEnvBits2 = psGMNode2->iGroupRMSEnvelopeCost; + fSNRPenalty2 = psGMNode2->fGroupSNRPenalty; + } + + /* Compute the merged group */ + ComputeMergeRMS( iNumBands * iChannels, psGMNode1->iGroupStart, psGMNode1->iGroupLength + psGMNode2->iGroupLength, ppfBandEnergy, psGMNode1->pfMergedEnergydB, psGMNode1->piQRMSEnvelope ); + + /* Compute the RMS Envelope cost for merged group */ + iRMSEnvBitsMerged = ComputeRMSEnvelopeBits( iChannels, iNumBands, psGMNode1->piQRMSEnvelope ); + + /* 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; +} + + +/*-------------------------------------------------------------------* + * Function ComputeGreedyGroups() + * + * + *-------------------------------------------------------------------*/ + +static void ComputeGreedyGroups( + RMSEnvelopeGrouping *psRMSEnvelopeGrouping, + const int32_t iChannels, + const int32_t iNumBands, + const float fMeanAllowedDiffdB, + const float fMaxAllowedDiffdB ) +{ + float fBestMeanCost; + + fBestMeanCost = 0.0; + while ( fBestMeanCost < fMeanAllowedDiffdB ) + { + GMNode *psGMNode; + GMNode *psBestGMNode; + + fBestMeanCost = fMeanAllowedDiffdB; + psGMNode = &psRMSEnvelopeGrouping->psGMNodes[0]; + psBestGMNode = NULL; + while ( psGMNode->psNext != NULL ) + { + float fMeanCost; + int32_t iGroupLength; + + iGroupLength = psGMNode->iGroupLength + psGMNode->psNext->iGroupLength; + + fMeanCost = TryMerge( iNumBands * iChannels, + psGMNode->iGroupStart, + iGroupLength, // psGMNode->iGroupLength, //Fix this bug + fMaxAllowedDiffdB, + psRMSEnvelopeGrouping->ppfBandEnergy, + psRMSEnvelopeGrouping->ppfBandEnergydB, +#ifdef APPLY_WEIGHT + psRMSEnvelopeGrouping->ppfWeight, +#endif + psGMNode->pfMergedEnergydB ); + + + if ( fMeanCost < fBestMeanCost ) + { + fBestMeanCost = fMeanCost; + psBestGMNode = psGMNode; + } + + psGMNode = psGMNode->psNext; + } + + if ( fBestMeanCost < fMeanAllowedDiffdB && psBestGMNode != NULL && psBestGMNode->psNext != NULL ) + { + psBestGMNode->iGroupLength += psBestGMNode->psNext->iGroupLength; + psBestGMNode->psNext = psBestGMNode->psNext->psNext; + } + } + + return; +} + + +/*-------------------------------------------------------------------* + * Function ComputeGreedyGroups2() + * + * + *-------------------------------------------------------------------*/ + +static void ComputeGreedyGroups2( + RMSEnvelopeGrouping *psRMSEnvelopeGrouping, + const int32_t iChannels, + const int32_t iNumBands, + const int32_t *piBandwidths ) +{ + float fBestMergeCost; + // int32_t iDone = 0; + fBestMergeCost = -1.0; + + while ( fBestMergeCost < 0.0 ) + { + GMNode *psGMNode; + GMNode *psBestGMNode; + + fBestMergeCost = 0.0; + psGMNode = &psRMSEnvelopeGrouping->psGMNodes[0]; + psBestGMNode = NULL; + while ( psGMNode->psNext != NULL ) + { + float fMergeCost; + + fMergeCost = TryMerge2( iChannels, iNumBands, piBandwidths, psRMSEnvelopeGrouping->ppfBandEnergy, psRMSEnvelopeGrouping->ppfBandEnergydB, psGMNode, psGMNode->psNext ); + + if ( fMergeCost < fBestMergeCost ) + { + fBestMergeCost = fMergeCost; + psBestGMNode = psGMNode; + } + + psGMNode = psGMNode->psNext; + } + + if ( fBestMergeCost < 0.0 && psBestGMNode != NULL && psBestGMNode->psNext != NULL ) + { + psBestGMNode->iGroupLength += psBestGMNode->psNext->iGroupLength; + psBestGMNode->iGroupRMSEnvelopeCost = -1; + psBestGMNode->fGroupSNRPenalty = -1.0; + psBestGMNode->psNext = psBestGMNode->psNext->psNext; + } + } + + return; +} + + +/*-------------------------------------------------------------------* + * Function ComputeGreedyGroups3() + * + * + *-------------------------------------------------------------------*/ + +static void ComputeGreedyGroups3( + RMSEnvelopeGrouping *psRMSEnvelopeGrouping, + const int32_t iChannels, + const int32_t iNumBands, + const int32_t *piBandwidths, + const int32_t iMaxGroups ) +{ + + int32_t iDone = 0; + int32_t iNumGroups = psRMSEnvelopeGrouping->iMaxGroups; + + while ( iDone == 0 ) + { + GMNode *psGMNode; + GMNode *psBestGMNode; + float fBestMergeCost; + + fBestMergeCost = 1e20f; + psGMNode = &psRMSEnvelopeGrouping->psGMNodes[0]; + psBestGMNode = NULL; + while ( psGMNode->psNext != NULL ) + { + float fMergeCost; + + fMergeCost = TryMerge2( iChannels, iNumBands, piBandwidths, psRMSEnvelopeGrouping->ppfBandEnergy, psRMSEnvelopeGrouping->ppfBandEnergydB, psGMNode, psGMNode->psNext ); + + if ( fMergeCost < fBestMergeCost ) + { + fBestMergeCost = fMergeCost; + psBestGMNode = psGMNode; + } + + psGMNode = psGMNode->psNext; + } + + if ( fBestMergeCost > 0.0 && iNumGroups <= iMaxGroups ) + { + iDone++; + } + else if ( psBestGMNode != NULL && psBestGMNode->psNext != NULL ) + { + psBestGMNode->iGroupLength += psBestGMNode->psNext->iGroupLength; + psBestGMNode->iGroupRMSEnvelopeCost = -1; + psBestGMNode->fGroupSNRPenalty = -1.0; + psBestGMNode->psNext = psBestGMNode->psNext->psNext; + iNumGroups--; + } + else + { + 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 ) +{ + int32_t n; + + for ( n = 0; n < iChannels; n++ ) + { + int32_t b; + int32_t iChanOffset; + + iChanOffset = n * iNumBands; + for ( b = 0; b < iNumBands; b++ ) + { + int32_t k; + int32_t iBlockOffset; + + iBlockOffset = 0; + for ( k = 0; k < iNumGroups; k++ ) + { + int32_t m; + float fGroupEnergy; + fGroupEnergy = 0.0; + for ( m = 0; m < piGroupLengths[k]; m++ ) + { + fGroupEnergy += ppfBandEnergy[iBlockOffset][b + iChanOffset]; + 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 ); // Bug fix + 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; + } + } + } + + return; +} + + +/*-------------------------------------------------------------------* + * Function LimitRMSEnvelope() + * + * + *-------------------------------------------------------------------*/ + +static void LimitRMSEnvelope( + const int32_t iBandCount, + const int32_t iRMSDeltaMax, + const int32_t iRMSDeltaMin, + int32_t *piRMSEnvelope ) +{ + int32_t iBand; + int32_t iLastSCF; + + /* Increase low envelope values to ensure that the scale factors traces the large values correctly (checking for max deltas) */ + iLastSCF = piRMSEnvelope[iBandCount - 1]; + for ( iBand = iBandCount - 2; iBand > -1; iBand-- ) + { + int32_t iDelta; + + iDelta = iLastSCF - piRMSEnvelope[iBand]; + + if ( iDelta > iRMSDeltaMax ) + { +#ifdef DEBUG_VERBOSE + printf( "WARNING RMS envelope delta limited\n" ); +#endif + piRMSEnvelope[iBand] += ( iDelta - iRMSDeltaMax ); + } + + iLastSCF = piRMSEnvelope[iBand]; + } + + /* 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++ ) + { + int32_t iDelta; + + iDelta = piRMSEnvelope[iBand] - iLastSCF; + + if ( iDelta < iRMSDeltaMin ) + { +#ifdef DEBUG_VERBOSE + printf( "WARNING RMS envelope delta limited\n" ); +#endif + piRMSEnvelope[iBand] += ( iRMSDeltaMin - iDelta ); + } + + iLastSCF = piRMSEnvelope[iBand]; + } + + return; +} + + +/*-------------------------------------------------------------------* + * Function ComputeEnvelopeGrouping() + * + * + *-------------------------------------------------------------------*/ + +void ComputeEnvelopeGrouping( + RMSEnvelopeGrouping *psRMSEnvelopeGrouping, + const int32_t iChannels, + const int32_t iNumBands, + const int32_t *piBandwidths, // pass in absolute thresh + float ***pppfReal, + float ***pppfImag, + int32_t *piNumGroups, + int32_t *piGroupLengths, + int32_t ***pppiRMSEnvelope ) +{ + int32_t n; + GMNode *psGMNode; + + /* Compute Band Energies */ + ComputeBandEnergy( iChannels, psRMSEnvelopeGrouping->iNumBlocks, iNumBands, piBandwidths, pppfReal, pppfImag, psRMSEnvelopeGrouping->ppfBandEnergy, psRMSEnvelopeGrouping->ppfBandEnergydB, psRMSEnvelopeGrouping->ppfWeight ); + + /* Init GMNodes */ + psRMSEnvelopeGrouping->psGMNodes[0].iGroupStart = 0; + psRMSEnvelopeGrouping->psGMNodes[0].iGroupLength = 2; + psRMSEnvelopeGrouping->psGMNodes[0].psNext = NULL; + psRMSEnvelopeGrouping->psGMNodes[0].iGroupRMSEnvelopeCost = -1; + psRMSEnvelopeGrouping->psGMNodes[0].fGroupSNRPenalty = -1.0f; + + for ( n = 1; n < psRMSEnvelopeGrouping->iMaxGroups; n++ ) + { + psRMSEnvelopeGrouping->psGMNodes[n - 1].psNext = &psRMSEnvelopeGrouping->psGMNodes[n]; + psRMSEnvelopeGrouping->psGMNodes[n].iGroupStart = n * 2; + psRMSEnvelopeGrouping->psGMNodes[n].iGroupLength = 2; + psRMSEnvelopeGrouping->psGMNodes[n].iGroupRMSEnvelopeCost = -1; + psRMSEnvelopeGrouping->psGMNodes[n].fGroupSNRPenalty = -1.0; + psRMSEnvelopeGrouping->psGMNodes[n].psNext = NULL; + } + + /* Perform grouping via Greedy Merge */ + + /* ComputeGreedyGroups2( psRMSEnvelopeGrouping, iChannels, iNumBands, piBandwidths );*/ + + /* Allows control over max groups can call using 16 if want same as previous call */ + ComputeGreedyGroups3( psRMSEnvelopeGrouping, iChannels, iNumBands, piBandwidths, LCLD_BLOCKS_PER_FRAME ); + + /* Calc Groups from Merge Results */ + *piNumGroups = 0; + psGMNode = &psRMSEnvelopeGrouping->psGMNodes[0]; + while ( psGMNode != NULL ) + { + piGroupLengths[*piNumGroups] = psGMNode->iGroupLength; + *piNumGroups += 1; + psGMNode = psGMNode->psNext; + } + + /* Compute RMS Envelope given group lengths */ + ComputeRMSEnvelope( iChannels, iNumBands, *piNumGroups, piGroupLengths, psRMSEnvelopeGrouping->ppfBandEnergy, pppiRMSEnvelope ); + + /* Envelope Tenting */ + for ( n = 0; n < iChannels; n++ ) + { + int32_t k; + for ( k = 0; k < *piNumGroups; k++ ) + { + LimitRMSEnvelope( iNumBands, ENV_DELTA_MAX, ENV_DELTA_MIN, pppiRMSEnvelope[n][k] ); + } + } + + return; +} +#endif diff --git a/lib_rend/ivas_allrad_dec.c b/lib_rend/ivas_allrad_dec.c index abc98d70a..a7d915cf0 100644 --- a/lib_rend/ivas_allrad_dec.c +++ b/lib_rend/ivas_allrad_dec.c @@ -38,9 +38,43 @@ #include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_rom_rend.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" +#ifdef DEBUG_MODE_INFO_ALLRAD +/*-------------------------------------------------------------------------* + * debugMatrix_ivas() + * + * Write a column-major (IVAS-style) flattened matrix to + * a 2D array in a CSV file + *-------------------------------------------------------------------------*/ +static void debugMatrix_ivas( float *mtx, int16_t rows, int16_t cols, char *filename ) +{ + FILE *fid; + int16_t i, j; + + fid = fopen( filename, "w" ); + + if ( fid == NULL ) + { + IVAS_ERROR( IVAS_ERR_FAILED_FILE_WRITE, "Error writing file %s\n", filename ); + return; + } + + for ( i = 0; i < rows; i++ ) + { + for ( j = 0; j < cols - 1; j++ ) + { + fprintf( fid, "%.16f, ", mtx[i * cols + j] ); + } + fprintf( fid, "%.16f\n", mtx[i * cols + j] ); + } + fclose( fid ); +} +#endif /*-----------------------------------------------------------------------* * Global function definitions @@ -158,6 +192,13 @@ ivas_error ivas_sba_get_hoa_dec_matrix( assert( 0 && "ALLRAD: output not supported!!!" ); } +#ifdef DEBUG_MODE_INFO_ALLRAD + { + char filename[50]; + sprintf( filename, "./res/mtx_hoa%d_decoder_allradC.csv", ambisonics_order ); + debugMatrix_ivas( *hoa_dec_mtx, num_spk, SBA_NHARM_HOA3, filename ); + } +#endif return error; } diff --git a/lib_rend/ivas_crend.c b/lib_rend/ivas_crend.c index 71ad9fec4..1d7bebf5b 100644 --- a/lib_rend/ivas_crend.c +++ b/lib_rend/ivas_crend.c @@ -41,6 +41,9 @@ #include "ivas_rom_binaural_crend_head.h" #include "ivas_stat_rend.h" #include "lib_rend.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" @@ -177,6 +180,9 @@ static ivas_error ivas_rend_initCrend( } if ( outConfig != IVAS_AUDIO_CONFIG_BINAURAL && outConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR && outConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB +#ifdef SPLIT_REND_WITH_HEAD_ROT + && outConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED && outConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM +#endif ) { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Encountered unsupported output type in Crend" ); @@ -1119,11 +1125,19 @@ static ivas_error ivas_er_init_handle( *------------------------------------------------------------------------*/ ivas_error ivas_rend_initCrendWrapper( +#ifdef SPLIT_REND_WITH_HEAD_ROT + CREND_WRAPPER_HANDLE *pCrend, + const int16_t num_poses +#else CREND_WRAPPER_HANDLE *pCrend +#endif ) { int16_t i; CREND_HANDLE hCrend; +#ifdef SPLIT_REND_WITH_HEAD_ROT + int16_t pos_idx; +#endif if ( pCrend == NULL ) { @@ -1138,6 +1152,9 @@ ivas_error ivas_rend_initCrendWrapper( ( *pCrend )->binaural_latency_ns = 0; ( *pCrend )->hHrtfCrend = NULL; +#ifdef SPLIT_REND_WITH_HEAD_ROT + for ( pos_idx = 0; pos_idx < num_poses; pos_idx++ ) +#endif { hCrend = NULL; if ( ( hCrend = (CREND_HANDLE) malloc( sizeof( CREND_DATA ) ) ) == NULL ) @@ -1169,13 +1186,45 @@ ivas_error ivas_rend_initCrendWrapper( hCrend->m_fPitch = 0; hCrend->m_fRoll = 0; +#ifdef SPLIT_REND_WITH_HEAD_ROT + ( *pCrend )->hCrend[pos_idx] = hCrend; +#else ( *pCrend )->hCrend = hCrend; +#endif } return IVAS_ERR_OK; } +#ifdef SPLIT_REND_WITH_HEAD_ROT +/*------------------------------------------------------------------------- + * ivas_rend_openMultiBinCrend() + * + * Allocate and initialize crend renderer handle + *------------------------------------------------------------------------*/ + +ivas_error ivas_rend_openMultiBinCrend( + CREND_WRAPPER_HANDLE *pCrend, + const AUDIO_CONFIG inConfig, + const AUDIO_CONFIG outConfig, + const MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + const int32_t output_Fs ) +{ + ivas_error error; + +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( error = ivas_rend_openCrend( pCrend, inConfig, outConfig, NULL /*hRendCfg*/, NULL, output_Fs, pMultiBinPoseData->num_poses ) ) != IVAS_ERR_OK ) +#else + if ( ( error = ivas_rend_openCrend( pCrend, inConfig, outConfig, NULL /*hRendCfg*/, NULL, output_Fs ) ) != IVAS_ERR_OK ) +#endif + { + return error; + } + + return error; +} +#endif /*------------------------------------------------------------------------- @@ -1190,7 +1239,12 @@ ivas_error ivas_rend_openCrend( const AUDIO_CONFIG outConfig, RENDER_CONFIG_DATA *hRendCfg, HRTFS_CREND_HANDLE hSetOfHRTF, +#ifdef SPLIT_REND_WITH_HEAD_ROT + const int32_t output_Fs, + const int16_t num_poses +#else const int32_t output_Fs +#endif ) { int16_t i, subframe_length; @@ -1198,10 +1252,17 @@ ivas_error ivas_rend_openCrend( HRTFS_HANDLE hHrtf; CREND_HANDLE hCrend; ivas_error error; +#ifdef SPLIT_REND_WITH_HEAD_ROT + int16_t pos_idx; +#endif error = IVAS_ERR_OK; +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( error = ivas_rend_initCrendWrapper( pCrend, num_poses ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_rend_initCrendWrapper( pCrend ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -1216,8 +1277,15 @@ ivas_error ivas_rend_openCrend( } } +#ifdef SPLIT_REND_WITH_HEAD_ROT + for ( pos_idx = 0; pos_idx < num_poses; pos_idx++ ) +#endif { +#ifdef SPLIT_REND_WITH_HEAD_ROT + hCrend = ( *pCrend )->hCrend[pos_idx]; +#else hCrend = ( *pCrend )->hCrend; +#endif hHrtf = ( *pCrend )->hHrtfCrend; if ( hHrtf != NULL ) @@ -1334,7 +1402,11 @@ ivas_error ivas_rend_openCrend( ( *pCrend )->binaural_latency_ns = (int32_t) ( ( *pCrend )->hHrtfCrend->latency_s * 1000000000.f ); } +#ifdef SPLIT_REND_WITH_HEAD_ROT + ( *pCrend )->hCrend[pos_idx] = hCrend; +#else ( *pCrend )->hCrend = hCrend; +#endif } return IVAS_ERR_OK; @@ -1348,10 +1420,18 @@ ivas_error ivas_rend_openCrend( *------------------------------------------------------------------------*/ void ivas_rend_closeCrend( +#ifdef SPLIT_REND_WITH_HEAD_ROT + CREND_WRAPPER_HANDLE *pCrend, + const int16_t num_poses +#else CREND_WRAPPER_HANDLE *pCrend +#endif ) { int16_t i; +#ifdef SPLIT_REND_WITH_HEAD_ROT + int16_t pos_idx; +#endif CREND_HANDLE hCrend; if ( pCrend == NULL || *pCrend == NULL ) @@ -1364,8 +1444,15 @@ void ivas_rend_closeCrend( ivas_hrtf_close( &( *pCrend )->hHrtfCrend ); } +#ifdef SPLIT_REND_WITH_HEAD_ROT + for ( pos_idx = 0; pos_idx < num_poses; pos_idx++ ) +#endif { +#ifdef SPLIT_REND_WITH_HEAD_ROT + hCrend = ( *pCrend )->hCrend[pos_idx]; +#else hCrend = ( *pCrend )->hCrend; +#endif if ( hCrend != NULL ) { for ( i = 0; i < MAX_INTERN_CHANNELS; i++ ) @@ -1437,7 +1524,11 @@ void ivas_rend_closeCrend( free( hCrend ); hCrend = NULL; +#ifdef SPLIT_REND_WITH_HEAD_ROT + ( *pCrend )->hCrend[pos_idx] = hCrend; +#else ( *pCrend )->hCrend = hCrend; +#endif } } @@ -1448,6 +1539,29 @@ void ivas_rend_closeCrend( } +#ifdef SPLIT_REND_WITH_HEAD_ROT +/*------------------------------------------------------------------------- + * ivas_rend_openCldfbRend() + * + * Close CLDFB based fastconv binaural renderer memories + *------------------------------------------------------------------------*/ + +void ivas_rend_closeCldfbRend( + CLDFB_REND_WRAPPER *pCldfbRend ) +{ + if ( pCldfbRend->hCldfbRend->hInputSetup != NULL ) + { + free( pCldfbRend->hCldfbRend->hInputSetup ); + pCldfbRend->hCldfbRend->hInputSetup = NULL; + } + + ivas_binRenderer_close( &pCldfbRend->hCldfbRend ); + + ivas_HRTF_fastconv_binary_close( &pCldfbRend->hHrtfFastConv ); + + return; +} +#endif /*-----------------------------------------------------------------------------------------* @@ -1463,7 +1577,12 @@ static ivas_error ivas_rend_crendConvolver( float *pcm_in[], float *pcm_out[], const int32_t output_Fs, +#ifdef SPLIT_REND_WITH_HEAD_ROT + const int16_t i_ts, + const int16_t pos_idx +#else const int16_t i_ts +#endif ) { int16_t i, j, k, m; @@ -1479,7 +1598,11 @@ static ivas_error ivas_rend_crendConvolver( CREND_HANDLE hCrend; ivas_error error; +#ifdef SPLIT_REND_WITH_HEAD_ROT + hCrend = pCrend->hCrend[pos_idx]; +#else hCrend = pCrend->hCrend; +#endif if ( ( error = getAudioConfigNumChannels( inConfig, &nchan_in ) ) != IVAS_ERR_OK ) { @@ -1632,7 +1755,12 @@ ivas_error ivas_rend_crendProcess( EFAP_HANDLE hEFAPdata, float *output[], /* i/o: input/output audio channels */ const int32_t output_Fs, +#ifdef SPLIT_REND_WITH_HEAD_ROT + const int16_t num_subframes /* i : number of subframes to render */, + const int16_t pos_idx +#else const int16_t num_subframes /* i : number of subframes to render */ +#endif ) { int16_t i, subframe_idx, subframe_len; @@ -1644,7 +1772,11 @@ ivas_error ivas_rend_crendProcess( ivas_error error; CREND_HANDLE hCrend; +#ifdef SPLIT_REND_WITH_HEAD_ROT + hCrend = pCrend->hCrend[pos_idx]; +#else hCrend = pCrend->hCrend; +#endif combinedOrientationEnabled = 0; if ( hCombinedOrientationData != NULL ) @@ -1709,21 +1841,31 @@ ivas_error ivas_rend_crendProcess( if ( inConfigType == IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED || inConfigType == IVAS_REND_AUDIO_CONFIG_TYPE_AMBISONICS ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( error = ivas_rend_crendConvolver( pCrend, inConfig, outConfig, output, p_pcm_tmp, output_Fs, subframe_idx, pos_idx ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_rend_crendConvolver( pCrend, inConfig, outConfig, output, p_pcm_tmp, output_Fs, subframe_idx ) ) != IVAS_ERR_OK ) +#endif { return error; } if ( hCrend->hReverb != NULL ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( error = ivas_reverb_process( pCrend->hCrend[pos_idx]->hReverb, inConfig, 1, output, p_pcm_tmp, subframe_idx ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_reverb_process( pCrend->hCrend->hReverb, inConfig, 1, output, p_pcm_tmp, subframe_idx ) ) != IVAS_ERR_OK ) +#endif { return error; } } +#ifdef NONBE_UNIFIED_DECODING_PATHS /* update combined orientation access index */ ivas_combined_orientation_update_index( hCombinedOrientationData, subframe_len ); +#endif } else { @@ -1761,6 +1903,12 @@ ivas_error ivas_rend_crendProcessSubframe( float *output[], /* i/o: input/output audio channels */ const int16_t n_samples_to_render, /* i : output frame length per channel */ const int32_t output_Fs /* i : output sampling rate */ +#ifdef NONBE_UNIFIED_DECODING_PATHS +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + const int16_t pos_idx +#endif +#endif ) { int16_t subframe_idx, subframe_len; @@ -1773,7 +1921,15 @@ ivas_error ivas_rend_crendProcessSubframe( int8_t combinedOrientationEnabled; CREND_HANDLE hCrend; +#ifdef SPLIT_REND_WITH_HEAD_ROT +#ifdef NONBE_UNIFIED_DECODING_PATHS + hCrend = pCrend->hCrend[pos_idx]; +#else + hCrend = pCrend->hCrend[0]; +#endif +#else hCrend = pCrend->hCrend; +#endif combinedOrientationEnabled = 0; if ( hCombinedOrientationData != NULL ) @@ -1855,12 +2011,33 @@ ivas_error ivas_rend_crendProcessSubframe( if ( ( inConfigType == IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED ) || ( inConfigType == IVAS_REND_AUDIO_CONFIG_TYPE_AMBISONICS ) ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT +#ifdef NONBE_UNIFIED_DECODING_PATHS + if ( ( error = ivas_rend_crendConvolver( pCrend, inConfig, outConfig, tc_local, p_pcm_tmp, output_Fs, 0, pos_idx ) ) != IVAS_ERR_OK ) +#else + if ( ( error = ivas_rend_crendConvolver( pCrend, inConfig, outConfig, tc_local, p_pcm_tmp, output_Fs, 0, 0 ) ) != IVAS_ERR_OK ) +#endif +#else if ( ( error = ivas_rend_crendConvolver( pCrend, inConfig, outConfig, tc_local, p_pcm_tmp, output_Fs, 0 ) ) != IVAS_ERR_OK ) +#endif { return error; } +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( pCrend->hCrend[0]->hReverb != NULL ) + { +#ifdef NONBE_UNIFIED_DECODING_PATHS + if ( ( error = ivas_reverb_process( pCrend->hCrend[pos_idx]->hReverb, inConfig, 1, tc_local, p_pcm_tmp, 0 ) ) != IVAS_ERR_OK ) +#else + if ( ( error = ivas_reverb_process( pCrend->hCrend[0]->hReverb, inConfig, 1, tc_local, p_pcm_tmp, 0 ) ) != IVAS_ERR_OK ) +#endif + { + return error; + } + } +#else if ( pCrend->hCrend->hReverb != NULL ) { if ( ( error = ivas_reverb_process( pCrend->hCrend->hReverb, inConfig, 1, tc_local, p_pcm_tmp, 0 ) ) != IVAS_ERR_OK ) @@ -1868,6 +2045,7 @@ ivas_error ivas_rend_crendProcessSubframe( return error; } } +#endif for ( ch = 0; ch < nchan_in; ch++ ) { @@ -1884,8 +2062,10 @@ ivas_error ivas_rend_crendProcessSubframe( return IVAS_ERR_INVALID_INPUT_FORMAT; } +#ifdef NONBE_UNIFIED_DECODING_PATHS /* update combined orientation access index */ ivas_combined_orientation_update_index( hCombinedOrientationData, subframe_len ); +#endif } /* move to output */ @@ -1901,4 +2081,312 @@ ivas_error ivas_rend_crendProcessSubframe( } +#ifdef SPLIT_REND_WITH_HEAD_ROT +/*-----------------------------------------------------------------------------------------* + * Function ivas_rend_crend_ProcessSplitBin() + * + * Process call for IVAS Crend renderer + *-----------------------------------------------------------------------------------------*/ + +ivas_error ivas_rend_crendProcessSplitBin( + const CREND_WRAPPER *pCrend, + const AUDIO_CONFIG inConfig, + const AUDIO_CONFIG outConfig, + const MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + DECODER_CONFIG_HANDLE hDecoderConfig, + COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, + const IVAS_OUTPUT_SETUP_HANDLE hIntSetup, + EFAP_HANDLE hEFAPdata, + float *output[], + const int32_t output_Fs ) +{ + int16_t i, j; + int16_t sf; + int16_t pos_idx, output_frame; + ivas_error error; + float gain_lfe; + float tmpLfeBuffer[L_FRAME48k]; + float tmpInputBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; + float *p_tmpInputBuffer[MAX_OUTPUT_CHANNELS]; + float tmpSplitBinBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; + COMBINED_ORIENTATION_DATA combinedOrientationDataLocal; + COMBINED_ORIENTATION_HANDLE pCombinedOrientationDataLocal; + + output_frame = (int16_t) ( output_Fs / FRAMES_PER_SEC ); + + /* copy input */ + for ( i = 0; i < hIntSetup->nchan_out_woLFE; ++i ) + { + mvr2r( output[i], tmpInputBuffer[i], output_frame ); + } + + for ( i = 0; i < MAX_OUTPUT_CHANNELS; ++i ) + { + p_tmpInputBuffer[i] = tmpInputBuffer[i]; + } + + /* save current head positions */ + pCombinedOrientationDataLocal = hCombinedOrientationData; + combinedOrientationDataLocal = *pCombinedOrientationDataLocal; + if ( pMultiBinPoseData->poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) + { + for ( sf = 1; sf < hCombinedOrientationData->num_subframes; ++sf ) + { + combinedOrientationDataLocal.Quaternions[sf] = combinedOrientationDataLocal.Quaternions[0]; + for ( i = 0; i < 3; i++ ) + { + for ( j = 0; j < 3; j++ ) + { + combinedOrientationDataLocal.Rmat[sf][i][j] = combinedOrientationDataLocal.Rmat[0][i][j]; + } + } + } + } + + /* copy LFE to tmpLfeBuffer and apply gain only once */ + if ( hIntSetup->num_lfe > 0 && hIntSetup->index_lfe[0] != -1 ) + { + mvr2r( output[hIntSetup->index_lfe[0]], tmpLfeBuffer, output_frame ); + gain_lfe = ( ( pCrend != NULL ) && ( pCrend->hHrtfCrend != NULL ) ) ? pCrend->hHrtfCrend->gain_lfe : GAIN_LFE; + v_multc( tmpLfeBuffer, gain_lfe, tmpLfeBuffer, output_frame ); + } + else + { + set_zero( tmpLfeBuffer, output_frame ); + } + + for ( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses; ++pos_idx ) + { + /* Update head positions */ + + IVAS_QUATERNION Quaternions_orig[MAX_PARAM_SPATIAL_SUBFRAMES], Quaternions_abs; + for ( i = 0; i < hCombinedOrientationData->num_subframes; i++ ) + { + Quaternions_orig[i] = combinedOrientationDataLocal.Quaternions[i]; + Quaternions_abs.w = -3.0f; + Quat2EulerDegree( combinedOrientationDataLocal.Quaternions[i], &Quaternions_abs.z, &Quaternions_abs.y, &Quaternions_abs.x ); /*order in Quat2Euler seems to be reversed ?*/ + + Quaternions_abs.x += pMultiBinPoseData->relative_head_poses[pos_idx][0]; + Quaternions_abs.y += pMultiBinPoseData->relative_head_poses[pos_idx][1]; + Quaternions_abs.z += pMultiBinPoseData->relative_head_poses[pos_idx][2]; + combinedOrientationDataLocal.Quaternions[i] = Quaternions_abs; + QuatToRotMat( combinedOrientationDataLocal.Quaternions[i], combinedOrientationDataLocal.Rmat[i] ); + } + + + /* render inplace to first two channels of tmpInputBuffer */ + pCombinedOrientationDataLocal = &combinedOrientationDataLocal; + + for ( i = 0; i < 3; i++ ) + { + mvr2r( hCombinedOrientationData->Rmat_prev[pos_idx][i], pCombinedOrientationDataLocal->Rmat_prev[0][i], 3 ); + } + if ( ( error = ivas_rend_crendProcess( pCrend, inConfig, outConfig, hDecoderConfig, pCombinedOrientationDataLocal, hIntSetup, hEFAPdata, p_tmpInputBuffer, output_Fs, hCombinedOrientationData->num_subframes, pos_idx ) ) != IVAS_ERR_OK ) + { + return error; + } + + for ( i = 0; i < 3; i++ ) + { + mvr2r( pCombinedOrientationDataLocal->Rmat_prev[0][i], hCombinedOrientationData->Rmat_prev[pos_idx][i], 3 ); + } + + for ( i = 0; i < BINAURAL_CHANNELS; ++i ) + { + /* accumulate LFE to output */ + v_add( tmpInputBuffer[i], tmpLfeBuffer, tmpInputBuffer[i], output_frame ); + + /* move to split bin output buffer */ + mvr2r( tmpInputBuffer[i], tmpSplitBinBuffer[pos_idx * BINAURAL_CHANNELS + i], output_frame ); + } + + /* overwrite rendered channels with input again for next iteration */ + for ( i = 0; i < hIntSetup->nchan_out_woLFE; ++i ) + { + mvr2r( output[i], tmpInputBuffer[i], output_frame ); + } + + /* restore original headrotation data */ + for ( i = 0; i < hCombinedOrientationData->num_subframes; i++ ) + { + combinedOrientationDataLocal.Quaternions[i] = Quaternions_orig[i]; + } + } + + /* copy split binaural rendered signals to final output */ + for ( i = 0; i < BINAURAL_CHANNELS * pMultiBinPoseData->num_poses; ++i ) + { + mvr2r( tmpSplitBinBuffer[i], output[i], output_frame ); + } + + return IVAS_ERR_OK; +} +#endif + +#ifdef NONBE_UNIFIED_DECODING_PATHS +#ifdef SPLIT_REND_WITH_HEAD_ROT +/*-----------------------------------------------------------------------------------------* + * Function ivas_rend_crend_ProcessSubframesSplitBin() + * + * Process call for IVAS Crend renderer + *-----------------------------------------------------------------------------------------*/ + +ivas_error ivas_rend_crendProcessSubframesSplitBin( + const CREND_WRAPPER *pCrend, /* i/o: Crend wrapper handle */ + const AUDIO_CONFIG inConfig, /* i : input audio configuration */ + const AUDIO_CONFIG outConfig, /* i : output audio configuration */ + const MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + const DECODER_CONFIG_HANDLE hDecoderConfig, /* i : decoder config. structure */ + const COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i : combined orientation handle */ + const IVAS_OUTPUT_SETUP_HANDLE hIntSetup, /* i : internal setup handle */ + const EFAP_HANDLE hEFAPdata, /* i : EFAP handle */ + DECODER_TC_BUFFER_HANDLE hTcBuffer, /* i/o: JBM handle */ + float *input_f[], /* i : transport channels */ + float *output[], /* i/o: input/output audio channels */ + const int16_t n_samples_to_render, /* i : output frame length per channel */ + const int32_t output_Fs /* i : output sampling rate */ +) +{ + int16_t i, j; + int16_t sf; + int16_t pos_idx; + ivas_error error; + float gain_lfe; + float tmpLfeBuffer[L_FRAME48k]; + float *p_bin_output[BINAURAL_CHANNELS]; + int16_t original_subframes_rendered, original_slots_rendered; + float tmpInputBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; + float *p_tmpInputBuffer[MAX_OUTPUT_CHANNELS]; + float tmpSplitBinBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; + + COMBINED_ORIENTATION_DATA combinedOrientationDataLocal; + COMBINED_ORIENTATION_HANDLE pCombinedOrientationDataLocal; + + /* save current head positions */ + pCombinedOrientationDataLocal = hCombinedOrientationData; + combinedOrientationDataLocal = *pCombinedOrientationDataLocal; + original_subframes_rendered = hTcBuffer->subframes_rendered; + original_slots_rendered = hTcBuffer->slots_rendered; + + /* copy input */ + for ( i = 0; i < hIntSetup->nchan_out_woLFE; ++i ) + { + mvr2r( input_f[i], tmpInputBuffer[i], n_samples_to_render ); + } + + for ( i = 0; i < MAX_OUTPUT_CHANNELS; ++i ) + { + p_tmpInputBuffer[i] = tmpInputBuffer[i]; + } + /* save current head positions */ + pCombinedOrientationDataLocal = hCombinedOrientationData; + combinedOrientationDataLocal = *pCombinedOrientationDataLocal; + if ( pMultiBinPoseData->poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) + { + for ( sf = 1; sf < hCombinedOrientationData->num_subframes; ++sf ) + { + combinedOrientationDataLocal.Quaternions[sf] = combinedOrientationDataLocal.Quaternions[0]; + for ( i = 0; i < 3; i++ ) + { + for ( j = 0; j < 3; j++ ) + { + combinedOrientationDataLocal.Rmat[sf][i][j] = combinedOrientationDataLocal.Rmat[0][i][j]; + } + } + } + } + + /* copy LFE to tmpLfeBuffer and apply gain only once */ + if ( hIntSetup->num_lfe > 0 && hIntSetup->index_lfe[0] != -1 ) + { + mvr2r( output[hIntSetup->index_lfe[0]], tmpLfeBuffer, n_samples_to_render ); + gain_lfe = ( ( pCrend != NULL ) && ( pCrend->hHrtfCrend != NULL ) ) ? pCrend->hHrtfCrend->gain_lfe : GAIN_LFE; + v_multc( tmpLfeBuffer, gain_lfe, tmpLfeBuffer, n_samples_to_render ); + } + else + { + set_zero( tmpLfeBuffer, n_samples_to_render ); + } + + for ( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses; ++pos_idx ) + { + /* Update head positions */ + IVAS_QUATERNION Quaternions_orig[MAX_PARAM_SPATIAL_SUBFRAMES], Quaternions_abs; + for ( i = 0; i < hCombinedOrientationData->num_subframes; i++ ) + { + Quaternions_orig[i] = combinedOrientationDataLocal.Quaternions[i]; + Quaternions_abs.w = -3.0f; + Quat2EulerDegree( combinedOrientationDataLocal.Quaternions[i], &Quaternions_abs.z, &Quaternions_abs.y, &Quaternions_abs.x ); /*order in Quat2Euler seems to be reversed ?*/ + + Quaternions_abs.x += pMultiBinPoseData->relative_head_poses[pos_idx][0]; + Quaternions_abs.y += pMultiBinPoseData->relative_head_poses[pos_idx][1]; + Quaternions_abs.z += pMultiBinPoseData->relative_head_poses[pos_idx][2]; + combinedOrientationDataLocal.Quaternions[i] = Quaternions_abs; + QuatToRotMat( combinedOrientationDataLocal.Quaternions[i], combinedOrientationDataLocal.Rmat[i] ); + } + + pCombinedOrientationDataLocal = &combinedOrientationDataLocal; + + /* set output channels */ + for ( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + p_bin_output[i] = output[pos_idx * BINAURAL_CHANNELS + i]; + } + hTcBuffer->subframes_rendered = original_subframes_rendered; + hTcBuffer->slots_rendered = original_slots_rendered; + + /* update combined orientation access index */ + ivas_combined_orientation_set_to_start_index( pCombinedOrientationDataLocal ); + + for ( i = 0; i < 3; i++ ) + { + mvr2r( hCombinedOrientationData->Rmat_prev[pos_idx][i], pCombinedOrientationDataLocal->Rmat_prev[0][i], 3 ); + } + + if ( ( error = ivas_rend_crendProcessSubframe( pCrend, inConfig, outConfig, hDecoderConfig, pCombinedOrientationDataLocal, + hIntSetup, hEFAPdata, hTcBuffer, p_tmpInputBuffer, p_tmpInputBuffer, n_samples_to_render, output_Fs, pos_idx ) ) != IVAS_ERR_OK ) + { + return error; + } + + for ( i = 0; i < 3; i++ ) + { + mvr2r( pCombinedOrientationDataLocal->Rmat_prev[0][i], hCombinedOrientationData->Rmat_prev[pos_idx][i], 3 ); + } + + for ( i = 0; i < BINAURAL_CHANNELS; ++i ) + { + /* accumulate LFE to output */ + v_add( tmpInputBuffer[i], tmpLfeBuffer, tmpInputBuffer[i], n_samples_to_render ); + + /* move to split bin output buffer */ + mvr2r( tmpInputBuffer[i], tmpSplitBinBuffer[pos_idx * BINAURAL_CHANNELS + i], n_samples_to_render ); + } + + /* overwrite rendered channels with input again for next iteration */ + for ( i = 0; i < hIntSetup->nchan_out_woLFE; ++i ) + { + mvr2r( input_f[i], tmpInputBuffer[i], n_samples_to_render ); + } + + /* restore original headrotation data */ + for ( i = 0; i < hCombinedOrientationData->num_subframes; i++ ) + { + combinedOrientationDataLocal.Quaternions[i] = Quaternions_orig[i]; + } + } + + /* copy split binaural rendered signals to final output */ + for ( i = 0; i < BINAURAL_CHANNELS * pMultiBinPoseData->num_poses; ++i ) + { + mvr2r( tmpSplitBinBuffer[i], output[i], n_samples_to_render ); + } + + /* update main combined orientation access index */ + ivas_combined_orientation_update_index( hCombinedOrientationData, n_samples_to_render ); + + return IVAS_ERR_OK; +} +#endif +#endif diff --git a/lib_rend/ivas_dirac_ana.c b/lib_rend/ivas_dirac_ana.c index f848b59ce..2391d7cfa 100644 --- a/lib_rend/ivas_dirac_ana.c +++ b/lib_rend/ivas_dirac_ana.c @@ -38,6 +38,9 @@ #include "prot.h" #include "ivas_stat_rend.h" #include "ivas_rom_com.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" diff --git a/lib_rend/ivas_dirac_dec_binaural_functions.c b/lib_rend/ivas_dirac_dec_binaural_functions.c index 28b16eb64..52f771806 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions.c @@ -42,6 +42,9 @@ #include "ivas_rom_rend.h" #include "ivas_rom_com.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" @@ -95,11 +98,20 @@ static void ivas_dirac_dec_binaural_internal( Decoder_Struct *st_ivas, COMBINED_ static void ivas_dirac_dec_decorrelate_slot( DIRAC_DEC_BIN_HANDLE hDiracDecBin, const int16_t num_freq_bands, const int16_t slot, float inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float decRe[][CLDFB_NO_CHANNELS_MAX], float decIm[][CLDFB_NO_CHANNELS_MAX] ); +#ifdef SPLIT_REND_WITH_HEAD_ROT +static void ivas_dirac_dec_binaural_formulate_input_covariance_matrices( DIRAC_DEC_BIN_HANDLE hDiracDecBin, SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, PARAMBIN_REND_CONFIG_HANDLE hConfig, float inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], const int16_t subframe, float *subFrameTotalEne, float *IIReneLimiter ); +static void ivas_dirac_dec_binaural_formulate_target_covariance_matrices( DIRAC_DEC_BIN_HANDLE hDiracDecBin, SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, PARAMBIN_REND_CONFIG_HANDLE hConfig, float Rmat[3][3], const int16_t subframe, const int16_t isHeadtracked, const float *subFrameTotalEne, const float *IIReneLimiter, const MASA_ISM_DATA_HANDLE hMasaIsmData ); +#else static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matrices( DIRAC_DEC_BIN_HANDLE hDiracDecBin, SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, PARAMBIN_REND_CONFIG_HANDLE hConfig, float inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float Rmat[3][3], const int16_t subframe, const int16_t isHeadtracked, const MASA_ISM_DATA_HANDLE hMasaIsmData ); +#endif static void ivas_dirac_dec_binaural_determine_processing_matrices( DIRAC_DEC_BIN_HANDLE hDiracDecBin, SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, PARAMBIN_REND_CONFIG_HANDLE hConfig, const int16_t max_band_decorr, float Rmat[3][3], const int16_t subframe, const int16_t isHeadtracked, const int16_t nchanSeparateChannels, const MASA_ISM_DATA_HANDLE hMasaIsmData ); +#ifdef SPLIT_REND_WITH_HEAD_ROT +static void ivas_dirac_dec_binaural_process_output( DIRAC_DEC_BIN_HANDLE hDiracDecBin, SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, HANDLE_CLDFB_FILTER_BANK cldfbSynDec[MAX_OUTPUT_CHANNELS], float *output_f[], float inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], const int16_t max_band_decorr, const int16_t numInChannels, const int16_t processReverb, const int16_t subframe, float outRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float outIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float reverbRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float reverbIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float decorrRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float decorrIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], const uint8_t recompute ); +#else static void ivas_dirac_dec_binaural_process_output( DIRAC_DEC_BIN_HANDLE hDiracDecBin, SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, HANDLE_CLDFB_FILTER_BANK cldfbSynDec[MAX_OUTPUT_CHANNELS], float *output_f[], float inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], const int16_t max_band_decorr, const int16_t numInChannels, const int16_t processReverb, const int16_t subframe ); +#endif static void adaptTransportSignalsHeadtracked( COMBINED_ORIENTATION_HANDLE hHeadTrackData, float inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], const int16_t nBins, const int16_t nSlots, float Rmat[3][3] ); @@ -115,7 +127,11 @@ static void matrixMul( float Are[BINAURAL_CHANNELS][BINAURAL_CHANNELS], float Ai static void matrixTransp2Mul( float Are[BINAURAL_CHANNELS][BINAURAL_CHANNELS], float Aim[BINAURAL_CHANNELS][BINAURAL_CHANNELS], float Bre[BINAURAL_CHANNELS][BINAURAL_CHANNELS], float Bim[BINAURAL_CHANNELS][BINAURAL_CHANNELS], float outRe[BINAURAL_CHANNELS][BINAURAL_CHANNELS], float outIm[BINAURAL_CHANNELS][BINAURAL_CHANNELS] ); +#ifdef SPLIT_REND_WITH_HEAD_ROT +static void ivas_masa_ext_rend_parambin_internal( MASA_EXT_REND_HANDLE hMasaExtRend, COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, float *output_f[], const int16_t subframe, const SPLIT_REND_WRAPPER *hSplitRendWrapper, float Cldfb_Out_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], float Cldfb_Out_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX] ); +#else static void ivas_masa_ext_rend_parambin_internal( MASA_EXT_REND_HANDLE hMasaExtRend, COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, float *output_f[], const int16_t subframe ); +#endif /*------------------------------------------------------------------------- * ivas_dirac_dec_init_binaural_data() @@ -136,7 +152,15 @@ ivas_error ivas_dirac_dec_init_binaural_data( float binCenterFreq, tmpFloat; ivas_error error; float frequency_axis[CLDFB_NO_CHANNELS_MAX]; +#ifdef SPLIT_REND_WITH_HEAD_ROT + int16_t pos_idx; + + for ( pos_idx = 0; pos_idx < st_ivas->hSplitBinRend.splitrend.multiBinPoseData.num_poses; pos_idx++ ) + { + hDiracDecBin = st_ivas->hDiracDecBin[pos_idx]; +#else hDiracDecBin = st_ivas->hDiracDecBin; +#endif if ( hDiracDecBin == NULL ) { @@ -209,7 +233,11 @@ ivas_error ivas_dirac_dec_init_binaural_data( ivas_binaural_reverb_close( &( hDiracDecBin->hReverb ) ); } +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( hDiracDecBin->hReverb == NULL && pos_idx == 0 ) /* open reverb only for the main direction */ +#else if ( hDiracDecBin->hReverb == NULL ) +#endif { /* Todo Philips: Room acoustics should be passed here once the underlying part works. Probably enough to pick it from st_ivas but you know best. */ if ( ( error = ivas_binaural_reverb_open_parambin( &hDiracDecBin->hReverb, nBins, CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, NULL, output_Fs, st_ivas->hHrtfParambin ) ) != IVAS_ERR_OK ) @@ -241,6 +269,10 @@ ivas_error ivas_dirac_dec_init_binaural_data( ivas_dirac_dec_decorr_close( &hDiracDecBin->h_freq_domain_decorr_ap_params, &hDiracDecBin->h_freq_domain_decorr_ap_state ); } +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( pos_idx == 0 ) /* open decorrelator only for the main direction */ + { +#endif if ( ( error = ivas_td_decorr_reconfig_dec( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->nchan_transport, st_ivas->hDecoderConfig->output_Fs, &( hDiracDecBin->hTdDecorr ), &( hDiracDecBin->useTdDecorr ) ) ) != IVAS_ERR_OK ) { return error; @@ -262,13 +294,29 @@ ivas_error ivas_dirac_dec_init_binaural_data( return error; } } +#ifdef SPLIT_REND_WITH_HEAD_ROT + } + else + { + hDiracDecBin->useTdDecorr = st_ivas->hDiracDecBin[0]->useTdDecorr; /* copy the flag, but the implementation re-uses the decorrelated signal */ + } +#endif hDiracDecBin->reqularizationFactor = configure_reqularization_factor( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + st_ivas->hDiracDecBin[pos_idx] = hDiracDecBin; + } +#else st_ivas->hDiracDecBin = hDiracDecBin; +#endif /* allocate transport channels */ +#ifndef NONBE_UNIFIED_DECODING_PATHS + if ( st_ivas->hDecoderConfig->Opt_5ms && st_ivas->hTcBuffer == NULL ) +#else if ( st_ivas->hTcBuffer == NULL ) +#endif { int16_t nchan_to_allocate; int16_t n_samples_granularity; @@ -304,12 +352,37 @@ void ivas_dirac_dec_close_binaural_data( DIRAC_DEC_BIN_HANDLE *hBinaural /* i/o: decoder DirAC binaural data handle */ ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + int16_t pos_idx; +#endif if ( hBinaural == NULL || *hBinaural == NULL ) { return; } +#ifdef SPLIT_REND_WITH_HEAD_ROT + for ( pos_idx = 0; pos_idx < MAX_HEAD_ROT_POSES; pos_idx++ ) + { + if ( hBinaural[pos_idx] != NULL ) + { + if ( hBinaural[pos_idx]->hReverb != NULL ) + { + ivas_binaural_reverb_close( &( hBinaural[pos_idx]->hReverb ) ); + } + + ivas_td_decorr_dec_close( &( hBinaural[pos_idx]->hTdDecorr ) ); + + if ( hBinaural[pos_idx]->h_freq_domain_decorr_ap_params != NULL ) + { + ivas_dirac_dec_decorr_close( &( hBinaural[pos_idx]->h_freq_domain_decorr_ap_params ), &( hBinaural[pos_idx]->h_freq_domain_decorr_ap_state ) ); + } + + free( hBinaural[pos_idx] ); + hBinaural[pos_idx] = NULL; + } + } +#else if ( ( *hBinaural )->hReverb != NULL ) { ivas_binaural_reverb_close( &( ( *hBinaural )->hReverb ) ); @@ -323,6 +396,7 @@ void ivas_dirac_dec_close_binaural_data( free( *hBinaural ); *hBinaural = NULL; +#endif return; } @@ -394,14 +468,23 @@ void ivas_dirac_dec_binaural_render( uint16_t nchan_out; SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom; float *output_f_local[MAX_OUTPUT_CHANNELS]; +#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX float output_f_local_buff[MAX_OUTPUT_CHANNELS][L_FRAME48k]; int16_t output_length; +#endif hSpatParamRendCom = st_ivas->hSpatParamRendCom; nchan_out = BINAURAL_CHANNELS; +#ifdef DEBUGGING + assert( hSpatParamRendCom ); +#endif for ( ch = 0; ch < nchan_out; ch++ ) { +#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX output_f_local[ch] = output_f_local_buff[ch]; +#else + output_f_local[ch] = output_f[ch]; +#endif } slot_size = NS2SA( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ); @@ -417,7 +500,12 @@ void ivas_dirac_dec_binaural_render( last_sf++; } +#ifdef DEBUGGING + assert( slots_to_render == 0 ); +#endif +#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX output_length = 0; +#endif for ( subframe_idx = first_sf; subframe_idx < last_sf; subframe_idx++ ) { int16_t n_samples_sf = slot_size * hSpatParamRendCom->subframe_nbslots[subframe_idx]; @@ -428,17 +516,23 @@ void ivas_dirac_dec_binaural_render( output_f_local[ch] += n_samples_sf; } +#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX output_length += n_samples_sf; +#endif +#ifdef NONBE_UNIFIED_DECODING_PATHS /* update combined orientation access index */ ivas_combined_orientation_update_index( st_ivas->hCombinedOrientationData, n_samples_sf ); +#endif } +#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX for ( ch = 0; ch < nchan_out; ch++ ) { mvr2r( output_f_local_buff[ch], output_f[ch], output_length ); } +#endif if ( hSpatParamRendCom->slots_rendered == hSpatParamRendCom->num_slots ) { hSpatParamRendCom->dirac_read_idx = ( hSpatParamRendCom->dirac_read_idx + DEFAULT_JBM_SUBFRAMES_5MS ) % hSpatParamRendCom->dirac_md_buffer_length; @@ -482,6 +576,113 @@ void ivas_dirac_dec_binaural_sba_gain( return; } +#ifndef NONBE_UNIFIED_DECODING_PATHS +/*------------------------------------------------------------------------- + * ivas_dirac_dec_binaural() + * + * Parametric binaural renderer main function + *------------------------------------------------------------------------*/ + +void ivas_dirac_dec_binaural( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i : combined orientation handle */ + float *output_f[], /* i/o: synthesized core-coder transport channels/DirAC output */ + const int16_t nchan_transport, /* i : number of transport channels */ + const int16_t num_subframes /* i : number of subframes to render */ +) +{ + int16_t subframe; + SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom; + float cng_td_buffer[L_FRAME16k]; + float *p_output[MAX_OUTPUT_CHANNELS]; + int16_t ch; + int16_t slot_size; + int16_t numInChannels; + float *decorr_signal[BINAURAL_CHANNELS], decorr_signal_buff[BINAURAL_CHANNELS][L_FRAME48k]; + + hSpatParamRendCom = st_ivas->hSpatParamRendCom; + + slot_size = NS2SA( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ); + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + p_output[ch] = output_f[ch]; + p_output[ch + BINAURAL_CHANNELS] = decorr_signal_buff[ch]; + } + numInChannels = nchan_transport; + if ( st_ivas->hOutSetup.separateChannelEnabled || ( st_ivas->ivas_format == MASA_ISM_FORMAT && ( st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ ) ) ) + { + numInChannels++; + } + else if ( st_ivas->ivas_format == MASA_ISM_FORMAT && st_ivas->ism_mode == ISM_MASA_MODE_DISC && ( st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) ) + { + numInChannels += (uint8_t) st_ivas->nchan_ism; + } + + for ( ch = 0; ch < numInChannels; ch++ ) + { + st_ivas->hTcBuffer->tc[ch] = &output_f[ch][0]; + } + + ivas_dirac_dec_set_md_map( st_ivas, DEFAULT_JBM_CLDFB_TIMESLOTS ); + if ( st_ivas->ivas_format == SBA_FORMAT || st_ivas->ivas_format == SBA_ISM_FORMAT ) + { + ivas_spar_dec_set_render_map( st_ivas, DEFAULT_JBM_CLDFB_TIMESLOTS ); + } +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( st_ivas->hDiracDecBin[0]->useTdDecorr ) +#else + if ( st_ivas->hDiracDecBin->useTdDecorr ) +#endif + { + int16_t output_frame; + + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + decorr_signal[ch] = decorr_signal_buff[ch]; + st_ivas->hTcBuffer->tc[ch + BINAURAL_CHANNELS] = decorr_signal[ch]; + } + output_frame = (int16_t) ( st_ivas->hDecoderConfig->output_Fs / FRAMES_PER_SEC ); + +#ifdef SPLIT_REND_WITH_HEAD_ROT + ivas_td_decorr_process( st_ivas->hDiracDecBin[0]->hTdDecorr, p_output, decorr_signal, output_frame ); +#else + ivas_td_decorr_process( st_ivas->hDiracDecBin->hTdDecorr, p_output, decorr_signal, output_frame ); +#endif + } + + if ( nchan_transport == 1 && st_ivas->nchan_transport != 2 && st_ivas->hSCE[0]->hCoreCoder[0] != NULL && st_ivas->hSCE[0]->hCoreCoder[0]->cng_sba_flag ) + { + Decoder_State *st = st_ivas->hSCE[0]->hCoreCoder[0]; + st_ivas->hTcBuffer->tc[nchan_transport] = &cng_td_buffer[0]; + generate_masking_noise_lb_dirac( st->hFdCngDec->hFdCngCom, st_ivas->hTcBuffer->tc[nchan_transport], DEFAULT_JBM_CLDFB_TIMESLOTS, st->cna_dirac_flag && st->flag_cna ); + } + + for ( subframe = 0; subframe < num_subframes; subframe++ ) + { + int16_t n_samples_sf = slot_size * hSpatParamRendCom->subframe_nbslots[subframe]; + + ivas_dirac_dec_binaural_internal( st_ivas, hCombinedOrientationData, p_output, nchan_transport, subframe ); + + for ( ch = 0; ch < 2 * BINAURAL_CHANNELS; ch++ ) + { + p_output[ch] += n_samples_sf; + } + +#ifdef NONBE_UNIFIED_DECODING_PATHS + ivas_combined_orientation_update_index( hCombinedOrientationData, n_samples_sf ); +#endif + + hSpatParamRendCom->dirac_read_idx = ( hSpatParamRendCom->dirac_read_idx + 1 ) % hSpatParamRendCom->dirac_md_buffer_length; + } + + for ( ch = 0; ch < 2 * BINAURAL_CHANNELS; ch++ ) + { + st_ivas->hTcBuffer->tc[ch] = NULL; + } + + return; +} +#endif /*------------------------------------------------------------------------- * Local functions @@ -506,7 +707,23 @@ static void ivas_dirac_dec_binaural_internal( DIFFUSE_DISTRIBUTION_DATA diffuseDistData; int16_t nBins, offsetSamples; int16_t i, j; +#ifdef SPLIT_REND_WITH_HEAD_ROT + int16_t pos_idx; + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData; + float tmp_Cldfb_out_re[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; + float tmp_Cldfb_out_im[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; + /* these allow re-using the reverb and freq-domain decorrelator signals from ivas_dirac_dec_binaural_process_output() in split rendering for the side renderings */ + float reverbRe[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; + float reverbIm[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; + float decorrRe[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; + float decorrIm[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; + float subFrameTotalEne[CLDFB_NO_CHANNELS_MAX]; + float IIReneLimiter[CLDFB_NO_CHANNELS_MAX]; + + hDiracDecBin = st_ivas->hDiracDecBin[0]; +#else hDiracDecBin = st_ivas->hDiracDecBin; +#endif assert( hDiracDecBin ); hSpatParamRendCom = st_ivas->hSpatParamRendCom; nBins = hSpatParamRendCom->num_freq_bands; @@ -644,141 +861,779 @@ static void ivas_dirac_dec_binaural_internal( if ( config_data.nchan_transport == 1 && ( config_data.ivas_format == SBA_FORMAT || config_data.ivas_format == SBA_ISM_FORMAT ) ) { - v_multc( Cldfb_RealBuffer_in[ch][slot], INV_SQRT_2, Cldfb_RealBuffer_in[ch][slot], nBins ); - v_multc( Cldfb_ImagBuffer_in[ch][slot], INV_SQRT_2, Cldfb_ImagBuffer_in[ch][slot], nBins ); + v_multc( Cldfb_RealBuffer_in[ch][slot], INV_SQRT_2, Cldfb_RealBuffer_in[ch][slot], nBins ); + v_multc( Cldfb_ImagBuffer_in[ch][slot], INV_SQRT_2, Cldfb_ImagBuffer_in[ch][slot], nBins ); + } + } + } + } + + if ( config_data.ivas_format == SBA_FORMAT || config_data.ivas_format == SBA_ISM_FORMAT ) + { + hDiracDecBin->hDiffuseDist = &diffuseDistData; + + ivas_spar_param_to_masa_param_mapping( st_ivas, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in, subframe ); + ivas_sba_prototype_renderer( st_ivas, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in, subframe ); + } + + if ( st_ivas->ivas_format == MASA_ISM_FORMAT && nchan_transport == 2 && st_ivas->ism_mode != ISM_MASA_MODE_DISC && st_ivas->ism_mode != ISM_MASA_MODE_MASA_ONE_OBJ ) + { + ivas_omasa_preProcessStereoTransportsForMovedObjects( st_ivas, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in, nBins, subframe ); + } + + if ( hCombinedOrientationData ) + { + for ( i = 0; i < 3; i++ ) + { + for ( j = 0; j < 3; j++ ) + { +#ifdef NONBE_UNIFIED_DECODING_PATHS + Rmat[i][j] = hCombinedOrientationData->Rmat[hCombinedOrientationData->subframe_idx][i][j]; +#else + Rmat[i][j] = hCombinedOrientationData->Rmat[subframe][i][j]; +#endif + } + } + + if ( nchan_transport == 2 ) + { +#ifdef SPLIT_REND_WITH_HEAD_ROT + /* in case of split rendering, determine the prototype rotation based on the main direction and use the same prototypes for the offset directions */ +#endif + adaptTransportSignalsHeadtracked( hCombinedOrientationData, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in, nBins, hSpatParamRendCom->subframe_nbslots[subframe], Rmat ); + + ivas_dirac_dec_binaural_check_and_switch_transports_headtracked( hCombinedOrientationData, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in, nBins, hSpatParamRendCom->subframe_nbslots[subframe], Rmat ); + } + } + +#ifndef SPLIT_REND_WITH_HEAD_ROT +#ifdef NONBE_UNIFIED_DECODING_PATHS + ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matrices( hDiracDecBin, hSpatParamRendCom, &config_data, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in, Rmat, subframe, + hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[hCombinedOrientationData->subframe_idx] > 0, st_ivas->hMasaIsmData ); +#else + ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matrices( hDiracDecBin, hSpatParamRendCom, &config_data, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in, Rmat, subframe, + hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[subframe] > 0, st_ivas->hMasaIsmData ); +#endif +#endif + + if ( config_data.ivas_format == ISM_FORMAT ) + { + max_band_decorr = 0; + } + else if ( hDiracDecBin->useTdDecorr ) + { + max_band_decorr = CLDFB_NO_CHANNELS_MAX; + } + else + { + max_band_decorr = hDiracDecBin->h_freq_domain_decorr_ap_params->max_band_decorr; + } + + +#ifdef SPLIT_REND_WITH_HEAD_ROT + ivas_dirac_dec_binaural_formulate_input_covariance_matrices( hDiracDecBin, hSpatParamRendCom, &config_data, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in, subframe, + subFrameTotalEne, IIReneLimiter ); + + ivas_dirac_dec_binaural_formulate_target_covariance_matrices( hDiracDecBin, hSpatParamRendCom, &config_data, Rmat, subframe, + hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[subframe] > 0, subFrameTotalEne, IIReneLimiter, st_ivas->hMasaIsmData ); +#endif + + nchanSeparateChannels = 0; + if ( config_data.separateCenterChannelRendering || ( st_ivas->ivas_format == MASA_ISM_FORMAT && ( st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ ) ) ) + { + nchanSeparateChannels = 1; + } + else if ( st_ivas->ivas_format == MASA_ISM_FORMAT && st_ivas->ism_mode == ISM_MASA_MODE_DISC && ( st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) ) + { + nchanSeparateChannels = (uint8_t) st_ivas->nchan_ism; + } + +#ifdef NONBE_UNIFIED_DECODING_PATHS + ivas_dirac_dec_binaural_determine_processing_matrices( hDiracDecBin, hSpatParamRendCom, &config_data, max_band_decorr, Rmat, subframe, + hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[hCombinedOrientationData->subframe_idx] > 0, nchanSeparateChannels, st_ivas->hMasaIsmData ); +#else + ivas_dirac_dec_binaural_determine_processing_matrices( hDiracDecBin, hSpatParamRendCom, &config_data, max_band_decorr, Rmat, subframe, + hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[subframe] > 0, nchanSeparateChannels, st_ivas->hMasaIsmData ); +#endif + +#ifdef SPLIT_REND_WITH_HEAD_ROT + pMultiBinPoseData = &st_ivas->hSplitBinRend.splitrend.multiBinPoseData; + +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) +#else + if ( pMultiBinPoseData != NULL && pMultiBinPoseData->num_poses > 1 ) +#endif + { + ivas_dirac_dec_binaural_process_output( hDiracDecBin, hSpatParamRendCom, st_ivas->cldfbSynDec, output_f, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in, + max_band_decorr, numInChannels, config_data.processReverb, subframe, tmp_Cldfb_out_re, tmp_Cldfb_out_im, + reverbRe, reverbIm, decorrRe, decorrIm, 1 ); + + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + for ( i = 0; i < CLDFB_SLOTS_PER_SUBFRAME; i++ ) + { + mvr2r( tmp_Cldfb_out_re[ch][i], st_ivas->hSplitBinRend.hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[ch][subframe * CLDFB_SLOTS_PER_SUBFRAME + i], CLDFB_NO_CHANNELS_MAX ); + mvr2r( tmp_Cldfb_out_im[ch][i], st_ivas->hSplitBinRend.hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[ch][subframe * CLDFB_SLOTS_PER_SUBFRAME + i], CLDFB_NO_CHANNELS_MAX ); + } + } + } + else + { + ivas_dirac_dec_binaural_process_output( hDiracDecBin, hSpatParamRendCom, st_ivas->cldfbSynDec, output_f, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in, + max_band_decorr, numInChannels, config_data.processReverb, subframe, NULL, NULL, + reverbRe, reverbIm, decorrRe, decorrIm, 1 ); + } +#else + ivas_dirac_dec_binaural_process_output( hDiracDecBin, hSpatParamRendCom, st_ivas->cldfbSynDec, output_f, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in, max_band_decorr, numInChannels, config_data.processReverb, subframe ); +#endif + + hDiracDecBin->hDiffuseDist = NULL; + +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( pMultiBinPoseData != NULL && pMultiBinPoseData->num_poses > 1 ) + { + /* quaternion-based rotation from ivas_binRenderer_internal.c:ivas_binRenderer(), but using absolute rotation instead of delta rotations */ + IVAS_QUATERNION Quaternions_rot, Quaternions_abs, *Quaternions_ref; + float Rmat_local[3][3]; + + if ( hCombinedOrientationData ) + { + Quaternions_ref = &hCombinedOrientationData->Quaternions[0]; + Quaternions_rot.w = -3.0f; /* signal to use Euler */ + Quaternions_abs.w = -3.0f; /* signal to use Euler */ + Quat2EulerDegree( *Quaternions_ref, &Quaternions_abs.z, &Quaternions_abs.y, &Quaternions_abs.x ); /*order in Quat2Euler seems to be reversed ?*/ + + for ( pos_idx = 1; pos_idx < pMultiBinPoseData->num_poses; pos_idx++ ) + { + Quaternions_rot.x = Quaternions_abs.x + pMultiBinPoseData->relative_head_poses[pos_idx][0]; + Quaternions_rot.y = Quaternions_abs.y + pMultiBinPoseData->relative_head_poses[pos_idx][1]; + Quaternions_rot.z = Quaternions_abs.z + pMultiBinPoseData->relative_head_poses[pos_idx][2]; + + QuatToRotMat( Quaternions_rot, Rmat_local ); + + hDiracDecBin = st_ivas->hDiracDecBin[pos_idx]; + assert( hDiracDecBin != NULL && "No DiracDecBin handle for this position" ); + if ( config_data.ivas_format == SBA_FORMAT || config_data.ivas_format == SBA_ISM_FORMAT ) + { + hDiracDecBin->hDiffuseDist = &diffuseDistData; + } + + /* re-use input covariance for the side renderings */ + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + mvr2r( st_ivas->hDiracDecBin[0]->ChEne[ch], hDiracDecBin->ChEne[ch], hSpatParamRendCom->num_freq_bands ); + } + mvr2r( st_ivas->hDiracDecBin[0]->ChCrossRe, hDiracDecBin->ChCrossRe, hSpatParamRendCom->num_freq_bands ); + mvr2r( st_ivas->hDiracDecBin[0]->ChCrossIm, hDiracDecBin->ChCrossIm, hSpatParamRendCom->num_freq_bands ); + + ivas_dirac_dec_binaural_formulate_target_covariance_matrices( hDiracDecBin, hSpatParamRendCom, &config_data, Rmat_local, subframe, + hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[subframe] > 0, + subFrameTotalEne, IIReneLimiter, st_ivas->hMasaIsmData ); + + ivas_dirac_dec_binaural_determine_processing_matrices( hDiracDecBin, hSpatParamRendCom, &config_data, max_band_decorr, Rmat_local, subframe, + hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[subframe] > 0, + nchanSeparateChannels, st_ivas->hMasaIsmData ); + + + /* re-use reverb and decorr from main direction for the sides */ + ivas_dirac_dec_binaural_process_output( hDiracDecBin, hSpatParamRendCom, st_ivas->cldfbSynDec, output_f, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in, + max_band_decorr, numInChannels, config_data.processReverb, subframe, tmp_Cldfb_out_re, tmp_Cldfb_out_im, + reverbRe, reverbIm, decorrRe, decorrIm, 0 ); + + /* copy from temporary buffer to the main split rendering buffer */ + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + for ( i = 0; i < CLDFB_SLOTS_PER_SUBFRAME; i++ ) + { + mvr2r( tmp_Cldfb_out_re[ch][i], st_ivas->hSplitBinRend.hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[pos_idx * BINAURAL_CHANNELS + ch][subframe * CLDFB_SLOTS_PER_SUBFRAME + i], CLDFB_NO_CHANNELS_MAX ); + mvr2r( tmp_Cldfb_out_im[ch][i], st_ivas->hSplitBinRend.hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[pos_idx * BINAURAL_CHANNELS + ch][subframe * CLDFB_SLOTS_PER_SUBFRAME + i], CLDFB_NO_CHANNELS_MAX ); + } + } + + hDiracDecBin->hDiffuseDist = NULL; + } + } + } + + /* update this counter only after the last rendering of split directions */ +#endif + hSpatParamRendCom->slots_rendered += hSpatParamRendCom->subframe_nbslots[subframe]; + hSpatParamRendCom->subframes_rendered++; + + return; +} + + +static void ivas_dirac_dec_decorrelate_slot( + DIRAC_DEC_BIN_HANDLE hDiracDecBin, + const int16_t num_freq_bands, + const int16_t slot, + float inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], + float inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], + float decRe[][CLDFB_NO_CHANNELS_MAX], + float decIm[][CLDFB_NO_CHANNELS_MAX] ) +{ + int16_t offset, ch, bin; + float onset_filter[BINAURAL_CHANNELS * CLDFB_NO_CHANNELS_MAX]; /* 2 ch, 60 bins */ + float decorrelatedFrameInterleaved[2 * BINAURAL_CHANNELS * CLDFB_NO_CHANNELS_MAX]; /* 2 ch, real + imag, 60 bins */ + float protoFrameF[2 * BINAURAL_CHANNELS * CLDFB_NO_CHANNELS_MAX]; /* 2 ch, real + imag, 60 bins */ + const int16_t protoIndexDir[BINAURAL_CHANNELS] = { 0, 1 }; + + /* Decorrelation needs interleaved data. Copy left and right signals to proto_frame_f */ + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + offset = num_freq_bands * BINAURAL_CHANNELS * ch; + for ( bin = 0; bin < num_freq_bands; bin++ ) + { + protoFrameF[( bin * BINAURAL_CHANNELS ) + offset] = inRe[ch][slot][bin]; + protoFrameF[( bin * BINAURAL_CHANNELS ) + offset + 1] = inIm[ch][slot][bin]; + } + } + + /* Decorrelate proto signal to decorrelatedFrameInterleaved */ + ivas_dirac_dec_decorr_process( num_freq_bands, + BINAURAL_CHANNELS, + BINAURAL_CHANNELS, + DIRAC_SYNTHESIS_PSD_LS, + BINAURAL_CHANNELS, + protoFrameF, + BINAURAL_CHANNELS, + protoIndexDir, + decorrelatedFrameInterleaved, + onset_filter, + hDiracDecBin->h_freq_domain_decorr_ap_params, + hDiracDecBin->h_freq_domain_decorr_ap_state ); + + /* De-interleave decorrelated signals*/ + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + offset = num_freq_bands * BINAURAL_CHANNELS * ch; + for ( bin = 0; bin < num_freq_bands; bin++ ) + { + decRe[ch][bin] = decorrelatedFrameInterleaved[( bin * BINAURAL_CHANNELS ) + offset]; + decIm[ch][bin] = decorrelatedFrameInterleaved[( bin * BINAURAL_CHANNELS ) + offset + 1]; + } + } + + return; +} + + +#ifdef SPLIT_REND_WITH_HEAD_ROT +static void ivas_dirac_dec_binaural_formulate_input_covariance_matrices( + DIRAC_DEC_BIN_HANDLE hDiracDecBin, + SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, + PARAMBIN_REND_CONFIG_HANDLE hConfig, + float inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], + float inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], + const int16_t subframe, + float *subFrameTotalEne, + float *IIReneLimiter ) +{ + int16_t ch, slot, bin; + int16_t nBins; + float IIReneLimiterFactor; + float qualityBasedSmFactor; + float lowBitRateEQ[CLDFB_NO_CHANNELS_MAX]; + uint8_t applyLowBitRateEQ; + IVAS_FORMAT ivas_format; + int32_t ivas_total_brate; + int16_t nchan_transport; + + ivas_format = hConfig->ivas_format; + ivas_total_brate = hConfig->ivas_total_brate; + nchan_transport = hConfig->nchan_transport; + qualityBasedSmFactor = hConfig->qualityBasedSmFactor; + qualityBasedSmFactor *= qualityBasedSmFactor; + nBins = hSpatParamRendCom->num_freq_bands; /* Actually bins */ + + set_zero( hDiracDecBin->ChCrossRe, nBins ); + set_zero( hDiracDecBin->ChCrossIm, nBins ); + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + set_zero( hDiracDecBin->ChEne[ch], nBins ); + } + + /* Determine EQ for low bit rates (13.2 and 16.4 kbps) */ + applyLowBitRateEQ = 0; + if ( ( ivas_format == MASA_FORMAT || ivas_format == MC_FORMAT ) && ivas_total_brate < MASA_STEREO_MIN_BITRATE ) + { + applyLowBitRateEQ = 1; + if ( ivas_total_brate == IVAS_16k4 ) + { + for ( bin = 0; bin < LOW_BIT_RATE_BINAURAL_EQ_BINS; bin++ ) + { + lowBitRateEQ[bin + LOW_BIT_RATE_BINAURAL_EQ_OFFSET] = lowBitRateBinauralEQ[bin] * 0.5f + 0.5f; + } + } + else + { + for ( bin = 0; bin < LOW_BIT_RATE_BINAURAL_EQ_BINS; bin++ ) + { + lowBitRateEQ[bin + LOW_BIT_RATE_BINAURAL_EQ_OFFSET] = lowBitRateBinauralEQ[bin]; + } + } + } + + /* Formulate input and target covariance matrices for this subframe */ + set_zero( subFrameTotalEne, CLDFB_NO_CHANNELS_MAX ); + + /* Calculate input covariance matrix */ + for ( slot = 0; slot < hSpatParamRendCom->subframe_nbslots[subframe]; slot++ ) + { + for ( bin = 0; bin < nBins; bin++ ) + { + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + float instEne; + + instEne = ( inRe[ch][slot][bin] * inRe[ch][slot][bin] ); + instEne += ( inIm[ch][slot][bin] * inIm[ch][slot][bin] ); + hDiracDecBin->ChEne[ch][bin] += instEne; + subFrameTotalEne[bin] += instEne; + } + hDiracDecBin->ChCrossRe[bin] += inRe[0][slot][bin] * inRe[1][slot][bin]; + hDiracDecBin->ChCrossRe[bin] += inIm[0][slot][bin] * inIm[1][slot][bin]; + hDiracDecBin->ChCrossIm[bin] += inRe[0][slot][bin] * inIm[1][slot][bin]; + hDiracDecBin->ChCrossIm[bin] -= inIm[0][slot][bin] * inRe[1][slot][bin]; + } + } + + /* Apply EQ at low bit rates */ + if ( applyLowBitRateEQ ) + { + int16_t lastEqBin = LOW_BIT_RATE_BINAURAL_EQ_OFFSET + LOW_BIT_RATE_BINAURAL_EQ_BINS - 1; + + for ( bin = LOW_BIT_RATE_BINAURAL_EQ_OFFSET; bin < lastEqBin; bin++ ) + { + subFrameTotalEne[bin] *= lowBitRateEQ[bin]; + } + for ( ; bin < nBins; bin++ ) + { + subFrameTotalEne[bin] *= lowBitRateEQ[lastEqBin]; + } + } + + if ( ( ivas_format == SBA_FORMAT || ivas_format == SBA_ISM_FORMAT ) && nchan_transport == 2 ) + { + float tempRe, tempIm; + float subFrameSumEne[CLDFB_NO_CHANNELS_MAX]; + + v_multc( subFrameTotalEne, SBA_CARDI_TARGET_ENERGY_GAIN, subFrameTotalEne, nBins ); + + set_zero( subFrameSumEne, CLDFB_NO_CHANNELS_MAX ); + for ( slot = 0; slot < hSpatParamRendCom->subframe_nbslots[subframe]; slot++ ) + { + for ( bin = 0; bin < nBins; bin++ ) + { + tempRe = inRe[0][slot][bin] + inRe[1][slot][bin]; + tempIm = inIm[0][slot][bin] + inIm[1][slot][bin]; + subFrameSumEne[bin] += tempRe * tempRe + tempIm * tempIm; + } + } + + for ( bin = 0; bin < nBins; bin++ ) + { + subFrameTotalEne[bin] = max( subFrameTotalEne[bin], subFrameSumEne[bin] ); + } + } + + /* Temporal IIR-type smoothing of covariance matrices. Also apply encoding quality based smoothing factor. */ + if ( ivas_format == MASA_FORMAT && ivas_total_brate < MASA_STEREO_MIN_BITRATE ) + { + IIReneLimiterFactor = 16.0f + ( 1.0f - qualityBasedSmFactor ); + } + else + { + IIReneLimiterFactor = 8.0f + ( 1.0f - qualityBasedSmFactor ); + } + for ( bin = 0; bin < nBins; bin++ ) + { + float eneRatio; + + /* Temporally smooth cov mtx estimates for resulting mixing matrix stability. The design principle is that + * the energy history (IIR) must not be more than double of the current frame energy. This provides more + * robust performance at energy offsets when compared to typical IIR averaging. */ + eneRatio = ( hDiracDecBin->ChEne[0][bin] + hDiracDecBin->ChEne[1][bin] ) / fmaxf( 1e-12f, ( hDiracDecBin->ChEnePrev[0][bin] + hDiracDecBin->ChEnePrev[1][bin] ) ); + IIReneLimiter[bin] = fminf( 1.0f, eneRatio * IIReneLimiterFactor ); + + hDiracDecBin->ChCrossRe[bin] *= qualityBasedSmFactor; + hDiracDecBin->ChCrossIm[bin] *= qualityBasedSmFactor; + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + hDiracDecBin->ChEne[ch][bin] *= qualityBasedSmFactor; + } + + hDiracDecBin->ChCrossRe[bin] += IIReneLimiter[bin] * hDiracDecBin->ChCrossRePrev[bin]; + hDiracDecBin->ChCrossIm[bin] += IIReneLimiter[bin] * hDiracDecBin->ChCrossImPrev[bin]; + + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + hDiracDecBin->ChEne[ch][bin] += IIReneLimiter[bin] * hDiracDecBin->ChEnePrev[ch][bin]; + } + + /* Store energy values and coefficients for next round */ + hDiracDecBin->ChCrossRePrev[bin] = hDiracDecBin->ChCrossRe[bin]; + hDiracDecBin->ChCrossImPrev[bin] = hDiracDecBin->ChCrossIm[bin]; + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + hDiracDecBin->ChEnePrev[ch][bin] = hDiracDecBin->ChEne[ch][bin]; + } + } + + return; +} + +static void ivas_dirac_dec_binaural_formulate_target_covariance_matrices( + DIRAC_DEC_BIN_HANDLE hDiracDecBin, + SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, + PARAMBIN_REND_CONFIG_HANDLE hConfig, + float Rmat[3][3], + const int16_t subframe, + const int16_t isHeadtracked, + const float *subFrameTotalEne, + const float *IIReneLimiter, + const MASA_ISM_DATA_HANDLE hMasaIsmData ) +{ + int16_t ch, bin; + int16_t separateCenterChannelRendering; + int16_t nBins, idx; + float frameMeanDiffusenessEneWeight[CLDFB_NO_CHANNELS_MAX]; + float qualityBasedSmFactor; + int16_t dirac_read_idx; + PARAMBIN_HRTF_GAIN_CACHE gainCache[MAX_GAIN_CACHE_SIZE]; + IVAS_FORMAT ivas_format; + MC_MODE mc_mode; + int16_t gainCacheBaseIndex; + + separateCenterChannelRendering = hConfig->separateCenterChannelRendering; + ivas_format = hConfig->ivas_format; + mc_mode = hConfig->mc_mode; + qualityBasedSmFactor = hConfig->qualityBasedSmFactor; + qualityBasedSmFactor *= qualityBasedSmFactor; + nBins = hSpatParamRendCom->num_freq_bands; /* Actually bins */ + + set_zero( hDiracDecBin->ChCrossReOut, nBins ); + set_zero( hDiracDecBin->ChCrossImOut, nBins ); + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + set_zero( hDiracDecBin->ChEneOut[ch], nBins ); + } + set_zero( hDiracDecBin->frameMeanDiffuseness, nBins ); + + set_zero( frameMeanDiffusenessEneWeight, CLDFB_NO_CHANNELS_MAX ); + + for ( idx = 0; idx < MAX_GAIN_CACHE_SIZE; idx++ ) + { + gainCache[idx].azi = -1000; /* Use -1000 as value for uninitialized cache. */ + } + + dirac_read_idx = hSpatParamRendCom->render_to_md_map[subframe]; + + /* Determine target covariance matrix containing target binaural properties */ + for ( bin = 0; bin < nBins; bin++ ) + { + float diffuseness = 1.0f; /* ratio1 and ratio2 are subtracted from diffuseness further below */ + float diffusenessValForDecorrelationReduction = 1.0f; + float diffEneValForDecorrelationReduction; + float surCoh = 0.0f, spreadCoh = 0.0f; /* Default values if spreadSurroundCoherenceApplied == false */ + float diffEne, dirEne, meanEnePerCh; + int16_t dirIndex; + + /* When BINAURAL_ROOM is not indicated, hBinaural->earlyPartEneCorrection[bin] values are all 1.0f. + * When BINAURAL_ROOM is indicated, the binaural audio output is based on combined use of the + * HRTF data set and a BRIR-based data set. The HRTF data set is spectrally corrected to match + * the early spectrum of the BRIR data, using the spectral correction data in + * hBinaural->earlyPartEneCorrection[bin], based on the BRIR set. */ + meanEnePerCh = hDiracDecBin->earlyPartEneCorrection[bin] * subFrameTotalEne[bin] / 2.0f; + + /* Determine direct part target covariance matrix (for 1 or 2 directions) */ + for ( dirIndex = 0; dirIndex < hSpatParamRendCom->numSimultaneousDirections; dirIndex++ ) + { + int16_t aziDeg, eleDeg; + float lRealp, lImagp, rRealp, rImagp; + float lRealpTmp, lImagpTmp, rRealpTmp, rImagpTmp; + float hrtfEne[BINAURAL_CHANNELS], hrtfCrossRe, hrtfCrossIm, ratio; + uint8_t isIsmDirection = 0; + + if ( dirIndex == 0 ) /* For first of the two simultaneous directions */ + { + aziDeg = hSpatParamRendCom->azimuth[dirac_read_idx][bin]; + eleDeg = hSpatParamRendCom->elevation[dirac_read_idx][bin]; + ratio = hSpatParamRendCom->energy_ratio1[dirac_read_idx][bin]; + spreadCoh = hSpatParamRendCom->spreadCoherence[dirac_read_idx][bin]; + gainCacheBaseIndex = 0; + } + else if ( ivas_format != MASA_ISM_FORMAT || ( ivas_format == MASA_ISM_FORMAT && dirIndex < hSpatParamRendCom->numParametricDirections ) ) /* For second of the two simultaneous directions */ + { + if ( ( ratio = hSpatParamRendCom->energy_ratio2[dirac_read_idx][bin] ) < 0.001 ) + { + /* This touches only MASA path where second direction always has smaller ratio and + * for non-2dir it is zero. As the whole direction contribution is multiplied with + * the ratio, a very small ratio does not contribute any energy to output. Thus, + * it is better to save complexity. */ + continue; + } + aziDeg = hSpatParamRendCom->azimuth2[dirac_read_idx][bin]; + eleDeg = hSpatParamRendCom->elevation2[dirac_read_idx][bin]; + spreadCoh = hSpatParamRendCom->spreadCoherence2[dirac_read_idx][bin]; + gainCacheBaseIndex = 3; + } + else /* For object directions of MASA_ISM_FORMAT */ + { + isIsmDirection = 1; + uint16_t ismDirIndex; + ismDirIndex = dirIndex - hSpatParamRendCom->numParametricDirections; + assert( hMasaIsmData != NULL && "hMasaIsmData should not be NULL if we use it" ); + if ( hMasaIsmData->ism_is_edited[ismDirIndex] ) + { + aziDeg = hMasaIsmData->azimuth_ism_edited[ismDirIndex]; + eleDeg = hMasaIsmData->elevation_ism_edited[ismDirIndex]; + } + else + { + aziDeg = hMasaIsmData->azimuth_ism[ismDirIndex][dirac_read_idx]; + eleDeg = hMasaIsmData->elevation_ism[ismDirIndex][dirac_read_idx]; + } + ratio = hMasaIsmData->energy_ratio_ism[ismDirIndex][dirac_read_idx][bin]; + spreadCoh = 0.0f; + gainCacheBaseIndex = 6 + ismDirIndex; + } + + diffuseness -= ratio; /* diffuseness = 1 - ratio1 - ratio2 */ + + if ( diffuseness < 0.0f ) + { + diffuseness = 0.0f; + } + if ( isIsmDirection ) + { + /* Objects cause lesser decorrelation reduction, to avoid removing all decorrelation when only objects are present */ + diffusenessValForDecorrelationReduction -= ratio * 0.5f; + } + else + { + diffusenessValForDecorrelationReduction -= ratio; + } + + if ( separateCenterChannelRendering ) + { + /* In masa + mono rendering mode, the center directions originate from phantom sources, so the + * spread coherence is increased */ + float aziRad, eleRad, doaVectorX, spatialAngleDeg, altSpreadCoh; + + aziRad = (float) aziDeg * PI_OVER_180; + eleRad = (float) eleDeg * PI_OVER_180; + doaVectorX = cosf( aziRad ) * cosf( eleRad ); + spatialAngleDeg = acosf( doaVectorX ) * _180_OVER_PI; + altSpreadCoh = 1.0f - ( spatialAngleDeg / 30.0f ); + spreadCoh = max( spreadCoh, altSpreadCoh ); + } + + getDirectPartGains( bin, aziDeg, eleDeg, &lRealp, &lImagp, &rRealp, &rImagp, hDiracDecBin->renderStereoOutputInsteadOfBinaural, Rmat, &gainCache[gainCacheBaseIndex], isHeadtracked ); + + if ( hDiracDecBin->renderStereoOutputInsteadOfBinaural ) + { + /* Synthesizing spread coherence is not needed for stereo loudspeaker output, + * as directional sound is reproduced with two loudspeakers in any case */ + spreadCoh = 0.0f; + } + + if ( spreadCoh > 0.0f ) + { + float centerMul, sidesMul; + float hrtfEneCenter, hrtfEneSides, hrtfEneRealized, eneCorrectionFactor; + float w1, w2, w3, eq; + + hrtfEneCenter = ( lRealp * lRealp ) + ( lImagp * lImagp ) + ( rRealp * rRealp ) + ( rImagp * rImagp ); + + /* Spread coherence is synthesized as coherent sources at 30 degree horizontal spacing. + * The following formulas determine the gains for these sources. + * spreadCoh = 0: Only panning + * spreadCoh = 0.5: Three sources coherent panning (e.g. 30 0 -30 deg azi) + * spreadCoh = 1.0: Two sources coherent panning with gap (as above, but center is silent) */ + if ( spreadCoh < 0.5f ) + { + /* 0.0f < spreadCoh < 0.5f */ + sidesMul = 0.5774f * spreadCoh * 2.0f; /* sqrt(1/3) = 0.5774f */ + centerMul = 1.0f - ( spreadCoh * 2.0f ) + sidesMul; + } + else + { + /* 0.5f <= spreadCoh < 1.0f */ + centerMul = 2.0f - ( 2.0f * spreadCoh ); + sidesMul = inv_sqrt( centerMul + 2.0f ); + centerMul *= sidesMul; + } + + /* Apply the gain for the center source of the three coherent sources */ + lRealp *= centerMul; + lImagp *= centerMul; + rRealp *= centerMul; + rImagp *= centerMul; + + /* Apply the gain for the left source of the three coherent sources */ + getDirectPartGains( bin, aziDeg + 30, eleDeg, &lRealpTmp, &lImagpTmp, &rRealpTmp, &rImagpTmp, hDiracDecBin->renderStereoOutputInsteadOfBinaural, Rmat, &gainCache[gainCacheBaseIndex + 1], isHeadtracked ); + + hrtfEneSides = ( lRealpTmp * lRealpTmp ) + ( lImagpTmp * lImagpTmp ) + ( rRealpTmp * rRealpTmp ) + ( rImagpTmp * rImagpTmp ); + lRealp += sidesMul * lRealpTmp; + lImagp += sidesMul * lImagpTmp; + rRealp += sidesMul * rRealpTmp; + rImagp += sidesMul * rImagpTmp; + + /* Apply the gain for the right source of the three coherent sources. + * -30 degrees to 330 wrapping due to internal functions. */ + getDirectPartGains( bin, aziDeg + 330, eleDeg, &lRealpTmp, &lImagpTmp, &rRealpTmp, &rImagpTmp, hDiracDecBin->renderStereoOutputInsteadOfBinaural, Rmat, &gainCache[gainCacheBaseIndex + 2], isHeadtracked ); + hrtfEneSides += ( lRealpTmp * lRealpTmp ) + ( lImagpTmp * lImagpTmp ) + ( rRealpTmp * rRealpTmp ) + ( rImagpTmp * rImagpTmp ); + lRealp += sidesMul * lRealpTmp; + lImagp += sidesMul * lImagpTmp; + rRealp += sidesMul * rRealpTmp; + rImagp += sidesMul * rImagpTmp; + + /* Formulate an eneCorrectionFactor that compensates for the coherent summation of the HRTFs */ + hrtfEneRealized = ( lRealp * lRealp ) + ( lImagp * lImagp ) + ( rRealp * rRealp ) + ( rImagp * rImagp ); + eneCorrectionFactor = ( ( hrtfEneSides * sidesMul * sidesMul ) + + ( hrtfEneCenter * centerMul * centerMul ) ) / + max( 1e-12f, hrtfEneRealized ); + + /* Weighting factors to determine appropriate target spectrum for spread coherent sound */ + if ( spreadCoh < 0.5 ) + { + w1 = 1.0f - 2.0f * spreadCoh; + w2 = 2.0f * spreadCoh; + w3 = 0.0f; + } + else + { + w1 = 0.0f; + w2 = 2.0f - 2.0f * spreadCoh; + w3 = 2.0f * spreadCoh - 1.0f; + } + + if ( ( ivas_format == MC_FORMAT && mc_mode == MC_MODE_MCMASA ) ) + { + idx = min( bin, MASA_NUM_DEFINED_SUR_SPR_COH_ENE_BINS - 1 ); + + /* Apply the target spectrum to the eneCorrectionFactor */ + if ( separateCenterChannelRendering ) /* spreadCoh mostly originates from phantom sources in separate channel rendering mode */ + { + eneCorrectionFactor *= w1 * 1.0f + ( w2 + w3 ) * spreadCohEne1[idx]; + } + else + { + eneCorrectionFactor *= w1 * 1.0f + w2 * spreadCohEne05[idx] + w3 * spreadCohEne1[idx]; + } } + + /* Equalize the spread coherent combined HRTFs */ + eq = min( 4.0f, sqrtf( eneCorrectionFactor ) ); + lRealp *= eq; + lImagp *= eq; + rRealp *= eq; + rImagp *= eq; } - } - } - if ( config_data.ivas_format == SBA_FORMAT || config_data.ivas_format == SBA_ISM_FORMAT ) - { - hDiracDecBin->hDiffuseDist = &diffuseDistData; + hrtfEne[0] = ( lRealp * lRealp ) + ( lImagp * lImagp ); + hrtfEne[1] = ( rRealp * rRealp ) + ( rImagp * rImagp ); + hrtfCrossRe = ( lRealp * rRealp ) + ( lImagp * rImagp ); + hrtfCrossIm = ( -lImagp * rRealp ) + ( lRealp * rImagp ); - ivas_spar_param_to_masa_param_mapping( st_ivas, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in, subframe ); - ivas_sba_prototype_renderer( st_ivas, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in, subframe ); - } + /* Add direct part (1 or 2) covariance matrix */ + dirEne = ratio * meanEnePerCh; + hDiracDecBin->ChEneOut[0][bin] += dirEne * hrtfEne[0]; /* Dir ene part*/ + hDiracDecBin->ChEneOut[1][bin] += dirEne * hrtfEne[1]; + hDiracDecBin->ChCrossReOut[bin] += dirEne * hrtfCrossRe; /* Dir cross re */ + hDiracDecBin->ChCrossImOut[bin] += dirEne * hrtfCrossIm; /* Dir cross im */ + } - if ( st_ivas->ivas_format == MASA_ISM_FORMAT && nchan_transport == 2 && st_ivas->ism_mode != ISM_MASA_MODE_DISC && st_ivas->ism_mode != ISM_MASA_MODE_MASA_ONE_OBJ ) - { - ivas_omasa_preProcessStereoTransportsForMovedObjects( st_ivas, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in, nBins, subframe ); - } + /* Add diffuse / ambient part covariance matrix */ + diffuseness = max( 0.0f, diffuseness ); + diffEne = diffuseness * meanEnePerCh; + surCoh = hSpatParamRendCom->surroundingCoherence[dirac_read_idx][bin]; - if ( hCombinedOrientationData ) - { - for ( i = 0; i < 3; i++ ) + diffusenessValForDecorrelationReduction = max( 0.0f, diffusenessValForDecorrelationReduction ); + diffEneValForDecorrelationReduction = diffusenessValForDecorrelationReduction * meanEnePerCh; + + if ( ( ivas_format == MC_FORMAT && mc_mode == MC_MODE_MCMASA ) ) { - for ( j = 0; j < 3; j++ ) + if ( !hDiracDecBin->renderStereoOutputInsteadOfBinaural ) { - Rmat[i][j] = hCombinedOrientationData->Rmat[hCombinedOrientationData->subframe_idx][i][j]; + float spectrumModVal; + + idx = min( bin, MASA_NUM_DEFINED_SUR_SPR_COH_ENE_BINS - 1 ); + /* Apply target spectrum that emphasizes low frequencies when the sound is surround coherent */ + spectrumModVal = ( 1.0f - surCoh ) + surCoh * surCohEne[idx]; + diffEne *= spectrumModVal; + + /* Modify also the value for decorrelation reduction */ + diffEneValForDecorrelationReduction *= spectrumModVal; } } + hDiracDecBin->ChEneOut[0][bin] += diffEne; /* Diff ene part*/ + hDiracDecBin->ChEneOut[1][bin] += diffEne; - if ( nchan_transport == 2 ) + if ( hDiracDecBin->renderStereoOutputInsteadOfBinaural ) { - adaptTransportSignalsHeadtracked( hCombinedOrientationData, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in, nBins, hSpatParamRendCom->subframe_nbslots[subframe], Rmat ); - - ivas_dirac_dec_binaural_check_and_switch_transports_headtracked( hCombinedOrientationData, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in, nBins, hSpatParamRendCom->subframe_nbslots[subframe], Rmat ); + /* When rendering stereo, ambience (except for surround coherent sound) has zero ICC. */ + hDiracDecBin->ChCrossReOut[bin] += surCoh * diffEne; + } + else /* When rendering binaural, ambience has frequency dependent ICC. */ + { + if ( ( ivas_format == SBA_FORMAT || ivas_format == SBA_ISM_FORMAT ) && bin < BINAURAL_COHERENCE_DIFFERENCE_BINS ) + { + float diffuseFieldCoherence; + diffuseFieldCoherence = hDiracDecBin->hDiffuseDist->diffuseRatioX[bin] * hDiracDecBin->diffuseFieldCoherenceX[bin] + hDiracDecBin->hDiffuseDist->diffuseRatioY[bin] * hDiracDecBin->diffuseFieldCoherenceY[bin] + hDiracDecBin->hDiffuseDist->diffuseRatioZ[bin] * hDiracDecBin->diffuseFieldCoherenceZ[bin]; + hDiracDecBin->ChCrossReOut[bin] += ( ( 1.0f - surCoh ) * diffuseFieldCoherence + surCoh ) * diffEne; + } + else + { + hDiracDecBin->ChCrossReOut[bin] += ( ( 1.0f - surCoh ) * hDiracDecBin->diffuseFieldCoherence[bin] + surCoh ) * diffEne; + } } - } - - ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matrices( hDiracDecBin, hSpatParamRendCom, &config_data, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in, Rmat, subframe, - hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[hCombinedOrientationData->subframe_idx] > 0, st_ivas->hMasaIsmData ); - if ( config_data.ivas_format == ISM_FORMAT ) - { - max_band_decorr = 0; - } - else if ( hDiracDecBin->useTdDecorr ) - { - max_band_decorr = CLDFB_NO_CHANNELS_MAX; - } - else - { - max_band_decorr = hDiracDecBin->h_freq_domain_decorr_ap_params->max_band_decorr; + /* Store parameters for formulating average diffuseness over frame */ + hDiracDecBin->frameMeanDiffuseness[bin] += diffEneValForDecorrelationReduction; + frameMeanDiffusenessEneWeight[bin] += meanEnePerCh; } - - - nchanSeparateChannels = 0; - if ( config_data.separateCenterChannelRendering || ( st_ivas->ivas_format == MASA_ISM_FORMAT && ( st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ ) ) ) - { - nchanSeparateChannels = 1; - } - else if ( st_ivas->ivas_format == MASA_ISM_FORMAT && st_ivas->ism_mode == ISM_MASA_MODE_DISC && ( st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) ) + /* Formulate average diffuseness over frame */ + for ( bin = 0; bin < nBins; bin++ ) { - nchanSeparateChannels = (uint8_t) st_ivas->nchan_ism; + hDiracDecBin->frameMeanDiffuseness[bin] /= fmaxf( 1e-12f, frameMeanDiffusenessEneWeight[bin] ); } - ivas_dirac_dec_binaural_determine_processing_matrices( hDiracDecBin, hSpatParamRendCom, &config_data, max_band_decorr, Rmat, subframe, - hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[hCombinedOrientationData->subframe_idx] > 0, nchanSeparateChannels, st_ivas->hMasaIsmData ); - - ivas_dirac_dec_binaural_process_output( hDiracDecBin, hSpatParamRendCom, st_ivas->cldfbSynDec, output_f, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in, max_band_decorr, numInChannels, config_data.processReverb, subframe ); - - hDiracDecBin->hDiffuseDist = NULL; - - hSpatParamRendCom->slots_rendered += hSpatParamRendCom->subframe_nbslots[subframe]; - hSpatParamRendCom->subframes_rendered++; - - return; -} + for ( bin = 0; bin < nBins; bin++ ) + { + hDiracDecBin->ChCrossReOut[bin] *= qualityBasedSmFactor; + hDiracDecBin->ChCrossImOut[bin] *= qualityBasedSmFactor; + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + hDiracDecBin->ChEneOut[ch][bin] *= qualityBasedSmFactor; + } -static void ivas_dirac_dec_decorrelate_slot( - DIRAC_DEC_BIN_HANDLE hDiracDecBin, - const int16_t num_freq_bands, - const int16_t slot, - float inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], - float inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], - float decRe[][CLDFB_NO_CHANNELS_MAX], - float decIm[][CLDFB_NO_CHANNELS_MAX] ) -{ - int16_t offset, ch, bin; - float onset_filter[BINAURAL_CHANNELS * CLDFB_NO_CHANNELS_MAX]; /* 2 ch, 60 bins */ - float decorrelatedFrameInterleaved[2 * BINAURAL_CHANNELS * CLDFB_NO_CHANNELS_MAX]; /* 2 ch, real + imag, 60 bins */ - float protoFrameF[2 * BINAURAL_CHANNELS * CLDFB_NO_CHANNELS_MAX]; /* 2 ch, real + imag, 60 bins */ - const int16_t protoIndexDir[BINAURAL_CHANNELS] = { 0, 1 }; + hDiracDecBin->ChCrossReOut[bin] += IIReneLimiter[bin] * hDiracDecBin->ChCrossReOutPrev[bin]; + hDiracDecBin->ChCrossImOut[bin] += IIReneLimiter[bin] * hDiracDecBin->ChCrossImOutPrev[bin]; - /* Decorrelation needs interleaved data. Copy left and right signals to proto_frame_f */ - for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) - { - offset = num_freq_bands * BINAURAL_CHANNELS * ch; - for ( bin = 0; bin < num_freq_bands; bin++ ) + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) { - protoFrameF[( bin * BINAURAL_CHANNELS ) + offset] = inRe[ch][slot][bin]; - protoFrameF[( bin * BINAURAL_CHANNELS ) + offset + 1] = inIm[ch][slot][bin]; + hDiracDecBin->ChEneOut[ch][bin] += IIReneLimiter[bin] * hDiracDecBin->ChEneOutPrev[ch][bin]; } - } - /* Decorrelate proto signal to decorrelatedFrameInterleaved */ - ivas_dirac_dec_decorr_process( num_freq_bands, - BINAURAL_CHANNELS, - BINAURAL_CHANNELS, - DIRAC_SYNTHESIS_PSD_LS, - BINAURAL_CHANNELS, - protoFrameF, - BINAURAL_CHANNELS, - protoIndexDir, - decorrelatedFrameInterleaved, - onset_filter, - hDiracDecBin->h_freq_domain_decorr_ap_params, - hDiracDecBin->h_freq_domain_decorr_ap_state ); + /* Store energy values and coefficients for next round */ + hDiracDecBin->ChCrossReOutPrev[bin] = hDiracDecBin->ChCrossReOut[bin]; + hDiracDecBin->ChCrossImOutPrev[bin] = hDiracDecBin->ChCrossImOut[bin]; - /* De-interleave decorrelated signals*/ - for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) - { - offset = num_freq_bands * BINAURAL_CHANNELS * ch; - for ( bin = 0; bin < num_freq_bands; bin++ ) + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) { - decRe[ch][bin] = decorrelatedFrameInterleaved[( bin * BINAURAL_CHANNELS ) + offset]; - decIm[ch][bin] = decorrelatedFrameInterleaved[( bin * BINAURAL_CHANNELS ) + offset + 1]; + hDiracDecBin->ChEneOutPrev[ch][bin] = hDiracDecBin->ChEneOut[ch][bin]; } } return; } - - +#else static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matrices( DIRAC_DEC_BIN_HANDLE hDiracDecBin, SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, @@ -1246,6 +2101,7 @@ static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matric return; } +#endif static void ivas_dirac_dec_binaural_determine_processing_matrices( DIRAC_DEC_BIN_HANDLE hDiracDecBin, @@ -1488,14 +2344,26 @@ static void ivas_dirac_dec_binaural_process_output( const int16_t numInChannels, const int16_t processReverb, const int16_t subframe +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + float outRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], + float outIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], + float reverbRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], + float reverbIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], + float decorrRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], + float decorrIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], + const uint8_t recompute +#endif ) { int16_t slot, bin, chA, chB; int16_t nBins; float outSlotRe[CLDFB_NO_CHANNELS_MAX], outSlotIm[CLDFB_NO_CHANNELS_MAX]; float decSlotRe[BINAURAL_CHANNELS][CLDFB_NO_CHANNELS_MAX], decSlotIm[BINAURAL_CHANNELS][CLDFB_NO_CHANNELS_MAX]; +#ifndef SPLIT_REND_WITH_HEAD_ROT float reverbRe[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; float reverbIm[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; +#endif float interpVal; float *decSlotRePointer; float *decSlotImPointer; @@ -1509,7 +2377,14 @@ static void ivas_dirac_dec_binaural_process_output( if ( processReverb ) { /* Process second / room effect part of binaural output when needed */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( recompute == 1 ) + { +#endif ivas_binaural_reverb_processSubframe( hDiracDecBin->hReverb, numInChannels, nSlots, inRe, inIm, reverbRe, reverbIm ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + } +#endif } interpVal = 0.0f; @@ -1518,7 +2393,27 @@ static void ivas_dirac_dec_binaural_process_output( interpVal += 1.0f / (float) nSlots; if ( !hDiracDecBin->useTdDecorr && max_band_decorr > 0 ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( recompute == 1 ) + { +#endif ivas_dirac_dec_decorrelate_slot( hDiracDecBin, nBins, slot, inRe, inIm, decSlotRe, decSlotIm ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + for ( chA = 0; chA < BINAURAL_CHANNELS; chA++ ) + { + mvr2r( decSlotRe[chA], decorrRe[chA][slot], CLDFB_NO_CHANNELS_MAX ); + mvr2r( decSlotIm[chA], decorrIm[chA][slot], CLDFB_NO_CHANNELS_MAX ); + } + } + else + { + for ( chA = 0; chA < BINAURAL_CHANNELS; chA++ ) + { + mvr2r( decorrRe[chA][slot], decSlotRe[chA], CLDFB_NO_CHANNELS_MAX ); + mvr2r( decorrIm[chA][slot], decSlotIm[chA], CLDFB_NO_CHANNELS_MAX ); + } + } +#endif } for ( chA = 0; chA < BINAURAL_CHANNELS; chA++ ) @@ -1596,8 +2491,22 @@ static void ivas_dirac_dec_binaural_process_output( outSlotRePr = &( outSlotRe[0] ); outSlotImPr = &( outSlotIm[0] ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( outRe != NULL && outIm != NULL ) + { + /* provide the data outside in CLDFB domain => mainly for split rendering */ + mvr2r( outSlotRePr, outRe[chA][slot], CLDFB_NO_CHANNELS_MAX ); + mvr2r( outSlotImPr, outIm[chA][slot], CLDFB_NO_CHANNELS_MAX ); + } + if ( recompute == 1 ) + { + /* Inverse filter bank */ + cldfbSynthesis( &outSlotRePr, &outSlotImPr, &( output_f[chA][nBins * slot + offsetSamples] ), nBins, cldfbSynDec[chA] ); + } +#else /* Inverse filter bank */ cldfbSynthesis( &outSlotRePr, &outSlotImPr, &( output_f[chA][nBins * slot + offsetSamples] ), nBins, cldfbSynDec[chA] ); +#endif } } @@ -2593,7 +3502,14 @@ static void ivas_masa_ext_rend_parambin_internal( MASA_EXT_REND_HANDLE hMasaExtRend, COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, float *output_f[], +#ifdef SPLIT_REND_WITH_HEAD_ROT + const int16_t subframe, + const SPLIT_REND_WRAPPER *hSplitRendWrapper, + float Cldfb_Out_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + float Cldfb_Out_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX] ) +#else const int16_t subframe ) +#endif { DIRAC_DEC_BIN_HANDLE hDiracDecBin; SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom; @@ -2607,7 +3523,24 @@ static void ivas_masa_ext_rend_parambin_internal( int16_t i, j; int16_t nchan_transport; +#ifdef SPLIT_REND_WITH_HEAD_ROT + int16_t pos_idx; + const MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData; + float tmp_Cldfb_out_re[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; + float tmp_Cldfb_out_im[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; + + /* these allow re-using the reverb and freq-domain decorrelator signals from ivas_dirac_dec_binaural_process_output() in split rendering for the side renderings */ + float reverbRe[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; + float reverbIm[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; + float decorrRe[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; + float decorrIm[BINAURAL_CHANNELS][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; + float subFrameTotalEne[CLDFB_NO_CHANNELS_MAX]; + float IIReneLimiter[CLDFB_NO_CHANNELS_MAX]; + + hDiracDecBin = hMasaExtRend->hDiracDecBin[0]; +#else hDiracDecBin = hMasaExtRend->hDiracDecBin; +#endif assert( hDiracDecBin ); hSpatParamRendCom = hMasaExtRend->hSpatParamRendCom; nBins = hSpatParamRendCom->num_freq_bands; @@ -2672,12 +3605,19 @@ static void ivas_masa_ext_rend_parambin_internal( { for ( j = 0; j < 3; j++ ) { +#ifdef NONBE_UNIFIED_DECODING_PATHS Rmat[i][j] = hCombinedOrientationData->Rmat[hCombinedOrientationData->subframe_idx][i][j]; +#else + Rmat[i][j] = hCombinedOrientationData->Rmat[subframe][i][j]; +#endif } } if ( nchan_transport == 2 ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + /* in case of split rendering, determine the prototype rotation based on the main direction and use the same prototypes for the offset directions */ +#endif adaptTransportSignalsHeadtracked( hCombinedOrientationData, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in, nBins, hSpatParamRendCom->subframe_nbslots[subframe], Rmat ); ivas_dirac_dec_binaural_check_and_switch_transports_headtracked( hCombinedOrientationData, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in, nBins, hSpatParamRendCom->subframe_nbslots[subframe], Rmat ); @@ -2685,22 +3625,133 @@ static void ivas_masa_ext_rend_parambin_internal( } +#ifndef SPLIT_REND_WITH_HEAD_ROT +#ifdef NONBE_UNIFIED_DECODING_PATHS ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matrices( hDiracDecBin, hSpatParamRendCom, &config_data, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in, Rmat, subframe, hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[hCombinedOrientationData->subframe_idx] > 0, NULL ); +#else + ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matrices( hDiracDecBin, hSpatParamRendCom, &config_data, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in, Rmat, subframe, + hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[subframe] > 0, NULL ); +#endif +#endif /* Always using CLDFB decorrelation in MASA EXT renderer */ max_band_decorr = hDiracDecBin->h_freq_domain_decorr_ap_params->max_band_decorr; +#ifdef SPLIT_REND_WITH_HEAD_ROT + ivas_dirac_dec_binaural_formulate_input_covariance_matrices( hDiracDecBin, hSpatParamRendCom, &config_data, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in, subframe, + subFrameTotalEne, IIReneLimiter ); + ivas_dirac_dec_binaural_formulate_target_covariance_matrices( hDiracDecBin, hSpatParamRendCom, &config_data, Rmat, subframe, + hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[subframe] > 0, + subFrameTotalEne, IIReneLimiter, NULL ); +#endif +#ifdef NONBE_UNIFIED_DECODING_PATHS ivas_dirac_dec_binaural_determine_processing_matrices( hDiracDecBin, hSpatParamRendCom, &config_data, max_band_decorr, Rmat, subframe, hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[hCombinedOrientationData->subframe_idx] > 0, 0, NULL ); +#else + ivas_dirac_dec_binaural_determine_processing_matrices( hDiracDecBin, hSpatParamRendCom, &config_data, max_band_decorr, Rmat, subframe, + hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[subframe] > 0, + 0, NULL ); +#endif + +#ifdef SPLIT_REND_WITH_HEAD_ROT + pMultiBinPoseData = NULL; + if ( hSplitRendWrapper != NULL ) + { + pMultiBinPoseData = &( hSplitRendWrapper->multiBinPoseData ); + ivas_dirac_dec_binaural_process_output( hDiracDecBin, hSpatParamRendCom, hMasaExtRend->cldfbSynRend, output_f, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in, + max_band_decorr, numInChannels, config_data.processReverb, subframe, tmp_Cldfb_out_re, tmp_Cldfb_out_im, + reverbRe, reverbIm, decorrRe, decorrIm, 1 ); + + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + for ( i = 0; i < CLDFB_SLOTS_PER_SUBFRAME; i++ ) + { + mvr2r( tmp_Cldfb_out_re[ch][i], Cldfb_Out_Real[ch][subframe * CLDFB_SLOTS_PER_SUBFRAME + i], CLDFB_NO_CHANNELS_MAX ); + mvr2r( tmp_Cldfb_out_im[ch][i], Cldfb_Out_Imag[ch][subframe * CLDFB_SLOTS_PER_SUBFRAME + i], CLDFB_NO_CHANNELS_MAX ); + } + } + } + else + { + ivas_dirac_dec_binaural_process_output( hDiracDecBin, hSpatParamRendCom, hMasaExtRend->cldfbSynRend, output_f, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in, + max_band_decorr, numInChannels, config_data.processReverb, subframe, NULL, NULL, + reverbRe, reverbIm, decorrRe, decorrIm, 1 ); + } +#else ivas_dirac_dec_binaural_process_output( hDiracDecBin, hSpatParamRendCom, hMasaExtRend->cldfbSynRend, output_f, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in, max_band_decorr, numInChannels, config_data.processReverb, subframe ); +#endif hDiracDecBin->hDiffuseDist = NULL; +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( pMultiBinPoseData != NULL && pMultiBinPoseData->num_poses > 1 ) + { + /* quaternion-based rotation from ivas_binRenderer_internal.c:ivas_binRenderer(), but using absolute rotation instead of delta rotations */ + IVAS_QUATERNION Quaternions_rot, Quaternions_abs, *Quaternions_ref; + float Rmat_local[3][3]; + + if ( hCombinedOrientationData ) + { + Quaternions_ref = &hCombinedOrientationData->Quaternions[0]; + Quaternions_rot.w = -3.0f; /* signal to use Euler */ + Quaternions_abs.w = -3.0f; /* signal to use Euler */ + Quat2EulerDegree( *Quaternions_ref, &Quaternions_abs.z, &Quaternions_abs.y, &Quaternions_abs.x ); /*order in Quat2Euler seems to be reversed ?*/ + + for ( pos_idx = 1; pos_idx < pMultiBinPoseData->num_poses; pos_idx++ ) + { + Quaternions_rot.x = Quaternions_abs.x + pMultiBinPoseData->relative_head_poses[pos_idx][0]; + Quaternions_rot.y = Quaternions_abs.y + pMultiBinPoseData->relative_head_poses[pos_idx][1]; + Quaternions_rot.z = Quaternions_abs.z + pMultiBinPoseData->relative_head_poses[pos_idx][2]; + + QuatToRotMat( Quaternions_rot, Rmat_local ); + + hDiracDecBin = hMasaExtRend->hDiracDecBin[pos_idx]; + assert( hDiracDecBin != NULL && "No DiracDecBin handle for this position" ); + + /* re-use input covariance for the side renderings */ + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + mvr2r( hMasaExtRend->hDiracDecBin[0]->ChEne[ch], hDiracDecBin->ChEne[ch], hSpatParamRendCom->num_freq_bands ); + } + mvr2r( hMasaExtRend->hDiracDecBin[0]->ChCrossRe, hDiracDecBin->ChCrossRe, hSpatParamRendCom->num_freq_bands ); + mvr2r( hMasaExtRend->hDiracDecBin[0]->ChCrossIm, hDiracDecBin->ChCrossIm, hSpatParamRendCom->num_freq_bands ); + + ivas_dirac_dec_binaural_formulate_target_covariance_matrices( hDiracDecBin, hSpatParamRendCom, &config_data, Rmat_local, subframe, + hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[subframe] > 0, + subFrameTotalEne, IIReneLimiter, NULL ); + + ivas_dirac_dec_binaural_determine_processing_matrices( hDiracDecBin, hSpatParamRendCom, &config_data, max_band_decorr, Rmat_local, subframe, + hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[subframe] > 0, + 0, NULL ); + + + /* re-use reverb and decorr from main direction for the sides */ + ivas_dirac_dec_binaural_process_output( hDiracDecBin, hSpatParamRendCom, hMasaExtRend->cldfbSynRend, output_f, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in, + max_band_decorr, numInChannels, config_data.processReverb, subframe, tmp_Cldfb_out_re, tmp_Cldfb_out_im, + reverbRe, reverbIm, decorrRe, decorrIm, 0 ); + + /* copy from temporary buffer to the main split rendering buffer */ + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + for ( i = 0; i < CLDFB_SLOTS_PER_SUBFRAME; i++ ) + { + mvr2r( tmp_Cldfb_out_re[ch][i], Cldfb_Out_Real[pos_idx * BINAURAL_CHANNELS + ch][subframe * CLDFB_SLOTS_PER_SUBFRAME + i], CLDFB_NO_CHANNELS_MAX ); + mvr2r( tmp_Cldfb_out_im[ch][i], Cldfb_Out_Imag[pos_idx * BINAURAL_CHANNELS + ch][subframe * CLDFB_SLOTS_PER_SUBFRAME + i], CLDFB_NO_CHANNELS_MAX ); + } + } + + hDiracDecBin->hDiffuseDist = NULL; + } + } + } + + /* update this counter only after the last rendering of split directions */ +#endif hSpatParamRendCom->slots_rendered += hSpatParamRendCom->subframe_nbslots[subframe]; hSpatParamRendCom->subframes_rendered++; @@ -2712,7 +3763,14 @@ void ivas_masa_ext_rend_parambin_render( MASA_EXT_REND_HANDLE hMasaExtRend, /* i/o: MASA ext rend structure */ COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i : combined orientation handle */ float *output_f[], /* i/o: synthesized core-coder transport channels/DirAC output */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + const int16_t num_subframes, /* i : number of subframes to render */ + const SPLIT_REND_WRAPPER *hSplitRendWrapper, /* i : split rendering orientation data */ + float Cldfb_Out_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* o : rendered orientations for split rend. real part of cldfb */ + float Cldfb_Out_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX] ) /* o : rendered orientations for split rend. imag part of cldfb */ +#else const int16_t num_subframes ) /* i : number of subframes to render */ +#endif { int16_t subframe; SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom; @@ -2733,14 +3791,20 @@ void ivas_masa_ext_rend_parambin_render( int16_t n_samples_sf = hSpatParamRendCom->slot_size * CLDFB_SLOTS_PER_SUBFRAME; hSpatParamRendCom->slots_rendered = 0; +#ifdef SPLIT_REND_WITH_HEAD_ROT + ivas_masa_ext_rend_parambin_internal( hMasaExtRend, hCombinedOrientationData, p_output, hSpatParamRendCom->dirac_read_idx, hSplitRendWrapper, Cldfb_Out_Real, Cldfb_Out_Imag ); +#else ivas_masa_ext_rend_parambin_internal( hMasaExtRend, hCombinedOrientationData, p_output, hSpatParamRendCom->dirac_read_idx ); +#endif for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) { p_output[ch] += n_samples_sf; } +#ifdef NONBE_UNIFIED_DECODING_PATHS ivas_combined_orientation_update_index( hCombinedOrientationData, n_samples_sf ); +#endif hSpatParamRendCom->dirac_read_idx = ( hSpatParamRendCom->dirac_read_idx + 1 ) % hSpatParamRendCom->dirac_md_buffer_length; } diff --git a/lib_rend/ivas_dirac_decorr_dec.c b/lib_rend/ivas_dirac_decorr_dec.c index 0240eb7ea..89c2c4a08 100644 --- a/lib_rend/ivas_dirac_decorr_dec.c +++ b/lib_rend/ivas_dirac_decorr_dec.c @@ -40,6 +40,9 @@ #include "ivas_prot_rend.h" #include "ivas_cnst.h" #include "ivas_rom_rend.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" @@ -354,18 +357,27 @@ void ivas_dirac_dec_decorr_process( /* check handles */ if ( h_freq_domain_decorr_ap_params == NULL || h_freq_domain_decorr_ap_state == NULL ) { +#ifdef DEBUGGING + assert( !"Error: NULL pointer.\n" ); +#endif return; } /* check input data */ if ( input_frame_f == NULL ) { +#ifdef DEBUGGING + assert( !"Error: NULL pointer.\n" ); +#endif return; } /* check result arrays */ if ( frame_dec_f == NULL ) { +#ifdef DEBUGGING + assert( !"Error: NULL pointer.\n" ); +#endif return; } @@ -620,11 +632,17 @@ void ivas_dirac_dec_decorr_close( if ( ph_freq_domain_decorr_ap_params == NULL || ph_freq_domain_decorr_ap_state == NULL ) { +#ifdef DEBUGGING + assert( 0 && "Error: Closing decorrelation synthesis failed." ); +#endif return; } if ( *ph_freq_domain_decorr_ap_params == NULL || *ph_freq_domain_decorr_ap_state == NULL ) { +#ifdef DEBUGGING + assert( 0 && "Error: Closing decorrelation synthesis failed." ); +#endif return; } diff --git a/lib_rend/ivas_dirac_onsets_dec.c b/lib_rend/ivas_dirac_onsets_dec.c index 5d24f40ad..8a03dc2c5 100644 --- a/lib_rend/ivas_dirac_onsets_dec.c +++ b/lib_rend/ivas_dirac_onsets_dec.c @@ -40,6 +40,9 @@ #include "ivas_cnst.h" #include "ivas_rom_com.h" #include "ivas_rom_dec.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" diff --git a/lib_rend/ivas_dirac_output_synthesis_dec.c b/lib_rend/ivas_dirac_output_synthesis_dec.c index a85ea96d0..8ee3b1e4f 100644 --- a/lib_rend/ivas_dirac_output_synthesis_dec.c +++ b/lib_rend/ivas_dirac_output_synthesis_dec.c @@ -42,6 +42,9 @@ #include "ivas_cnst.h" #include "ivas_rom_com.h" #include "ivas_rom_dec.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" /*------------------------------------------------------------------------- @@ -2422,6 +2425,9 @@ static void computeAlphaSynthesis( /* check input pointer */ if ( alpha_synthesis == NULL ) { +#ifdef DEBUGGING + assert( !"Error: NULL pointer.\n" ); +#endif return; } diff --git a/lib_rend/ivas_dirac_rend.c b/lib_rend/ivas_dirac_rend.c index b998b9636..9fa1ddd8e 100644 --- a/lib_rend/ivas_dirac_rend.c +++ b/lib_rend/ivas_dirac_rend.c @@ -40,6 +40,9 @@ #include "ivas_prot_rend.h" #include "ivas_cnst.h" #include "ivas_rom_rend.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" diff --git a/lib_rend/ivas_efap.c b/lib_rend/ivas_efap.c index 4c202a481..40f5e7312 100644 --- a/lib_rend/ivas_efap.c +++ b/lib_rend/ivas_efap.c @@ -39,6 +39,9 @@ #include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_stat_dec.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" /*-----------------------------------------------------------------------* @@ -80,6 +83,9 @@ static void get_poly_gains( const float azi, const float ele, const float aziPol static float get_tri_gain( const float A[2], const float B[2], const float C[2], const float P_minus_A[2] ); +#ifdef DEBUG_EFAP_POLY_TOFILE +static void get_poly_select( EFAP_POLYSET_DATA *polyData ); +#endif /*-----------------------------------------------------------------------* @@ -455,9 +461,49 @@ static ivas_error poly_init( efap->polyData.numPoly = finalLength; +#ifdef DEBUG_EFAP_POLY_TOFILE + get_poly_select( &efap->polyData ); +#endif return error; } +#ifdef DEBUG_EFAP_POLY_TOFILE +static void get_poly_select( + EFAP_POLYSET_DATA *polyData /* o : Polygon data structure */ +) +{ + int16_t azi_index, ele_index; + float P[2]; + +#ifdef DEBUG_EFAP_POLY_TOFILE + /* Write polygon selection table to .csv file, modify filename according to selected loudspeaker layout! */ + static FILE *pF = NULL; + if ( pF == NULL ) + pF = fopen( "./res/efap_poly_select_cicpX.csv", "w" ); +#endif + + for ( azi_index = 0; azi_index <= ( 360 / PANNING_AZI_RESOLUTION ); azi_index++ ) + { + P[0] = (float) ( ( azi_index * PANNING_AZI_RESOLUTION ) - 180 ); + for ( ele_index = 0; ele_index <= ( 180 / PANNING_ELE_RESOLUTION ); ele_index++ ) + { + P[1] = (float) ( ( ele_index * PANNING_ELE_RESOLUTION ) - 90 ); + +#ifdef DEBUG_EFAP_POLY_TOFILE + if ( pF != NULL ) + fprintf( pF, "%d,", get_poly_num( P, polyData ) ); +#endif + } + } + +#ifdef DEBUG_EFAP_POLY_TOFILE + if ( pF != NULL ) + fclose( pF ); +#endif + + return; +} +#endif /*-------------------------------------------------------------------------* * sphere_triangulation() @@ -2106,6 +2152,9 @@ static int16_t in_poly( if ( numVertices < 3 ) { +#ifdef DEBUGGING + IVAS_ERROR( IVAS_ERR_INTERNAL, "Less than 3 channels in the polygon" ); +#endif return 0; } diff --git a/lib_rend/ivas_lc3plus_common.c b/lib_rend/ivas_lc3plus_common.c new file mode 100644 index 000000000..db33f9861 --- /dev/null +++ b/lib_rend/ivas_lc3plus_common.c @@ -0,0 +1,60 @@ +/****************************************************************************************************** + + (C) 2022-2023 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. + +*******************************************************************************************************/ + +#include "options.h" +#include "ivas_lc3plus_common.h" +#include "ivas_error.h" +#include "lc3.h" + +#ifdef SPLIT_REND_WITH_HEAD_ROT +/*-----------------------------------------------------------------------------------------* + * Function IVAS_LC3PLUS_LC3plusErrToIvasErr() + * + * + *-----------------------------------------------------------------------------------------*/ + +ivas_error IVAS_LC3PLUS_LC3plusErrToIvasErr( + const LC3PLUS_Error lc3PlusError ) +{ + switch ( lc3PlusError ) + { + case LC3PLUS_OK: + return IVAS_ERR_OK; + case LC3PLUS_BITRATE_ERROR: + return IVAS_ERR_LC3PLUS_INVALID_BITRATE; + default: + break; + } + + return IVAS_ERR_INTERNAL; +} +#endif diff --git a/lib_rend/ivas_lc3plus_common.h b/lib_rend/ivas_lc3plus_common.h new file mode 100644 index 000000000..93a37488c --- /dev/null +++ b/lib_rend/ivas_lc3plus_common.h @@ -0,0 +1,57 @@ +/****************************************************************************************************** + + (C) 2022-2023 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 IVAS_LC3PLUS_COM_H +#define IVAS_LC3PLUS_COM_H + + +#include +#include "ivas_error.h" +#include "lc3.h" + +/*! common configuration parameters between encoder and decoder */ +typedef struct LC3PLUS_CONFIG +{ + /*! frame duration in microseconds [10000, 5000, 2500] */ + uint32_t lc3plus_frame_duration_us; + /*! ivas frame duration in microseconds [20000, 5000] */ + uint32_t ivas_frame_duration_us; + /*! sampling rate*/ + uint32_t samplerate; + /*! number of channels */ + uint16_t channels; +} LC3PLUS_CONFIG; + +/*! utility function to convert LC3PLUS_Errors to the suitable ivas_error */ +ivas_error IVAS_LC3PLUS_LC3plusErrToIvasErr( const LC3PLUS_Error lc3PlusError ); + +#endif /* IVAS_LC3PLUS_COM_H */ diff --git a/lib_rend/ivas_lc3plus_dec.c b/lib_rend/ivas_lc3plus_dec.c new file mode 100644 index 000000000..5dfdb9cec --- /dev/null +++ b/lib_rend/ivas_lc3plus_dec.c @@ -0,0 +1,703 @@ +/****************************************************************************************************** + + (C) 2022-2023 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. + +*******************************************************************************************************/ + +#include +#include "options.h" +#include "prot.h" +#include "ivas_prot.h" +#include "ivas_lc3plus_dec.h" +#include "ivas_lc3plus_common.h" +#include "lc3.h" +#include "ivas_error_utils.h" +#include "wmc_auto.h" + +#ifdef SPLIT_REND_WITH_HEAD_ROT + +/*------------------------------------------------------------------------- + * IVAS_LC3PLUS_DEC_Open() + * + * + *------------------------------------------------------------------------*/ + +ivas_error IVAS_LC3PLUS_DEC_Open( + const LC3PLUS_CONFIG config, /* i : LC3plus decoder configuration */ + IVAS_LC3PLUS_DEC_HANDLE *handle /* o : decoder handle */ +) +{ + LC3PLUS_Error err; + int32_t decoder_size; + int16_t lc3plusFrameIdx; + int16_t numLC3plusFramesPerIvasFrame; + int16_t i; + + if ( ( *handle = malloc( sizeof( struct IVAS_LC3PLUS_DEC_HANDLE ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus wrapper handle\n" ); + } + + if ( 0 == config.lc3plus_frame_duration_us ) + { + return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Invalid lc3plus_frame_duration_us (0)\n" ); + } + numLC3plusFramesPerIvasFrame = (int16_t) ( config.ivas_frame_duration_us / config.lc3plus_frame_duration_us ); + + + ( *handle )->num_decs = 0; + ( *handle )->pcm_conversion_buffer = NULL; + ( *handle )->handles = NULL; + ( *handle )->selective_decoding_states = NULL; + ( *handle )->bitstream_caches = NULL; + + if ( ( ( *handle )->handles = malloc( config.channels * sizeof( IVAS_LC3PLUS_DEC_HANDLE ) ) ) == NULL ) + { + IVAS_LC3PLUS_DEC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus wrapper handle\n" ); + } + + if ( ( ( *handle )->selective_decoding_states = malloc( config.channels * sizeof( IVAS_LC3PLUS_DEC_SELECTIVE_DECODING_STATE * ) ) ) == NULL ) + { + IVAS_LC3PLUS_DEC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus wrapper handle\n" ); + } + + for ( i = 0; i < config.channels; ++i ) + { + ( *handle )->handles[i] = NULL; + ( *handle )->selective_decoding_states[i] = NULL; + } + + if ( ( ( *handle )->bitstream_caches = malloc( config.channels * sizeof( IVAS_LC3PLUS_DEC_BITSTREAM_CACHE * ) ) ) == NULL ) + { + IVAS_LC3PLUS_DEC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus wrapper handle\n" ); + } + for ( i = 0; i < config.channels; ++i ) + { + ( *handle )->bitstream_caches[i] = NULL; + } + + ( *handle )->num_decs = config.channels; + for ( int32_t iCh = 0; iCh < config.channels; iCh++ ) + { + ( *handle )->selective_decoding_states[iCh] = NULL; + if ( NULL != ( *handle )->bitstream_caches ) + { + ( *handle )->bitstream_caches[iCh] = NULL; + } + /* allocate and configure LC3plus decoder */ + decoder_size = lc3plus_dec_get_size( config.samplerate, 1 ); + if ( 0 == decoder_size ) + { + IVAS_LC3PLUS_DEC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_INTERNAL, "lc3plus_dec_get_size failed\n" ); + } + + if ( ( ( *handle )->handles[iCh] = malloc( decoder_size ) ) == NULL ) + { + IVAS_LC3PLUS_DEC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus decoder\n" ); + } + + err = lc3plus_dec_init( ( *handle )->handles[iCh], config.samplerate, 1, LC3PLUS_PLC_ADVANCED, 0 ); + if ( LC3PLUS_OK != err ) + { + IVAS_LC3PLUS_DEC_Close( handle ); + return IVAS_ERROR( IVAS_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_dec_init failed\n" ); + } + + err = lc3plus_dec_set_frame_dms( ( *handle )->handles[iCh], config.lc3plus_frame_duration_us / 100 ); + if ( LC3PLUS_OK != err ) + { + IVAS_LC3PLUS_DEC_Close( handle ); + return IVAS_ERROR( IVAS_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_dec_set_frame_dms failed\n" ); + } + + /* allocate and configure per LC3plus decoder skip state */ + if ( ( ( *handle )->selective_decoding_states[iCh] = malloc( sizeof( IVAS_LC3PLUS_DEC_SELECTIVE_DECODING_STATE ) ) ) == NULL ) + { + IVAS_LC3PLUS_DEC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus decoder\n" ); + } + + if ( ( ( *handle )->selective_decoding_states[iCh]->frame_actions = malloc( numLC3plusFramesPerIvasFrame * sizeof( SelectiveDecAction ) ) ) == NULL ) + { + IVAS_LC3PLUS_DEC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus decoder\n" ); + } + + ( *handle )->selective_decoding_states[iCh]->has_skipped_a_frame = 0; + ( *handle )->selective_decoding_states[iCh]->shall_decode_cached_frame = 0; + for ( lc3plusFrameIdx = 0; lc3plusFrameIdx < numLC3plusFramesPerIvasFrame; lc3plusFrameIdx++ ) + { + ( *handle )->selective_decoding_states[iCh]->frame_actions[lc3plusFrameIdx] = DEC_ACTION_DECODE_AND_USE; + } + + /* allocate and configure per LC3plus decoder bitstream cache */ + if ( ( ( *handle )->bitstream_caches[iCh] = malloc( sizeof( IVAS_LC3PLUS_DEC_BITSTREAM_CACHE ) ) ) == NULL ) + { + IVAS_LC3PLUS_DEC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus decoder\n" ); + } + ( *handle )->bitstream_caches[iCh]->bitstream_cache_capacity = 400 /*LC3plus max non-HR octet count*/ * numLC3plusFramesPerIvasFrame; + if ( ( ( *handle )->bitstream_caches[iCh]->bitstream_cache = malloc( ( *handle )->bitstream_caches[iCh]->bitstream_cache_capacity ) ) == NULL ) + { + IVAS_LC3PLUS_DEC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus decoder\n" ); + } + ( *handle )->bitstream_caches[iCh]->bitstream_cache_size = 0; + } + + ( *handle )->config = config; + if ( config.ivas_frame_duration_us < config.lc3plus_frame_duration_us || config.ivas_frame_duration_us % config.lc3plus_frame_duration_us != 0 ) + { + IVAS_LC3PLUS_DEC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "Current pcm_conversion_buffer sizing requires that lc3plus uses a shorter or equal frame duration than ivas\n" ); + } + + if ( ( ( *handle )->pcm_conversion_buffer = malloc( sizeof( int16_t ) * config.samplerate * config.lc3plus_frame_duration_us / 1000000 ) ) == NULL ) + { + IVAS_LC3PLUS_DEC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus decoder wrapper pcm_conversion_buffer\n" ); + } + + return IVAS_ERR_OK; +} + + +/*------------------------------------------------------------------------- + * IVAS_LC3PLUS_DEC_AllocateSubframeDecodingMatrix() + * + * + *------------------------------------------------------------------------*/ + +ivas_error IVAS_LC3PLUS_DEC_AllocateSubframeDecodingMatrix( + int16_t ***subframeChannelMatrix, + const uint32_t num_decs ) +{ + int16_t i; + + if ( ( *subframeChannelMatrix = malloc( MAX_PARAM_SPATIAL_SUBFRAMES * sizeof( int16_t * ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "subframeChannelMatrix allocation failed\n" ); + } + + for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) + { + ( *subframeChannelMatrix )[i] = NULL; + } + + for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) + { + if ( ( ( *subframeChannelMatrix )[i] = malloc( num_decs * sizeof( int16_t ) ) ) == NULL ) + { + IVAS_LC3PLUS_DEC_FreeSubframeDecodingMatrix( *subframeChannelMatrix ); + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "subframeChannelMatrix allocation failed\n" ); + } + } + + return IVAS_ERR_OK; +} + + +/*------------------------------------------------------------------------- + * IVAS_LC3PLUS_DEC_AllocateSubframeDecodingMatrix() + * + * + *------------------------------------------------------------------------*/ + +void IVAS_LC3PLUS_DEC_FreeSubframeDecodingMatrix( + int16_t **subframeChannelMatrix ) +{ + for ( int16_t i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) + { + free( subframeChannelMatrix[i] ); + } + + free( subframeChannelMatrix ); + + return; +} + + +/*------------------------------------------------------------------------- + * IVAS_LC3PLUS_DEC_SetSelectiveDecodingMatrix() + * + * + *------------------------------------------------------------------------*/ + +ivas_error IVAS_LC3PLUS_DEC_SetSelectiveDecodingMatrix( + IVAS_LC3PLUS_DEC_HANDLE handle, /* i : LC3plus decoder handle */ + int16_t *subframeChannelMatrix[MAX_PARAM_SPATIAL_SUBFRAMES] ) +{ + int16_t numIvasSubFramesPerLC3frame; + uint32_t decIdx; + int16_t ivasSubframeIdx; + int16_t effectiveIvasSubframeDuration; + int16_t actual_num_spatial_subframes; + + if ( NULL == handle ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "IVAS_LC3PLUS_DEC_HANDLE is NULL\n" ); + } + + if ( NULL == subframeChannelMatrix ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "subframeChannelMatrix is NULL\n" ); + } + + if ( handle->config.lc3plus_frame_duration_us == 0 || handle->config.ivas_frame_duration_us % handle->config.lc3plus_frame_duration_us != 0 ) + { + return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "invalid ivas_frame_duration_us/lc3plus_frame_duration_us values\n" ); + } + + effectiveIvasSubframeDuration = (int16_t) ( handle->config.ivas_frame_duration_us == 20000 ? handle->config.ivas_frame_duration_us / MAX_PARAM_SPATIAL_SUBFRAMES : handle->config.ivas_frame_duration_us ); + numIvasSubFramesPerLC3frame = (int16_t) handle->config.lc3plus_frame_duration_us / effectiveIvasSubframeDuration; + actual_num_spatial_subframes = (int16_t) handle->config.ivas_frame_duration_us / effectiveIvasSubframeDuration; + /* 0.5(0) = 10ms lc3plus, 5ms subframe */ + if ( numIvasSubFramesPerLC3frame != 1 ) + { + return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "Selective decoding is only implemented for aligned IVAS-Subframes & LC3plus \n" ); + } + + /* map subframeChannelMatrix to lc3plus skip states */ + /* 1st pass: Flag the required frames */ + for ( decIdx = 0; decIdx < handle->num_decs; decIdx++ ) + { + for ( ivasSubframeIdx = 0; ivasSubframeIdx < actual_num_spatial_subframes; ivasSubframeIdx++ ) + { + if ( 1 == subframeChannelMatrix[ivasSubframeIdx][decIdx] ) + { + /* subframe needed by the user, definitely decode */ + handle->selective_decoding_states[decIdx]->frame_actions[ivasSubframeIdx] = DEC_ACTION_DECODE_AND_USE; + } + else + { + + /* subframe not needed by the user, but might be required to re-initialize a decoder after inactivity */ + if ( + ( ivasSubframeIdx != actual_num_spatial_subframes - 1 ) && 1 == subframeChannelMatrix[ivasSubframeIdx + 1][decIdx] ) + { + /* ... but if the following subframe is required, it needs to be decoded and dropped */ + handle->selective_decoding_states[decIdx]->frame_actions[ivasSubframeIdx] = DEC_ACTION_DECODE_AND_DROP; + } + else + { + handle->selective_decoding_states[decIdx]->frame_actions[ivasSubframeIdx] = DEC_ACTION_SKIP; + } + } + } + } + + /* if a decoder was paused before, it needs to either: + * - Decode the cached frame (if available) and the first required frame OR + * - Decode the previous LC3plus subframe, even if it isn't needed by the user */ + for ( decIdx = 0; decIdx < handle->num_decs; decIdx++ ) + { + if ( handle->selective_decoding_states[decIdx]->has_skipped_a_frame ) + { + /* find the first frame required by the user */ + for ( ivasSubframeIdx = 0; ivasSubframeIdx < actual_num_spatial_subframes; ivasSubframeIdx++ ) + { + if ( DEC_ACTION_DECODE_AND_USE == handle->selective_decoding_states[decIdx]->frame_actions[ivasSubframeIdx] ) + { + /* The first required frame is the first subframe. To flush the decoder, the cached frame must be decoded and dropped */ + if ( 0 == ivasSubframeIdx ) + { + handle->selective_decoding_states[decIdx]->shall_decode_cached_frame = 1; + break; + } + /* The first required frame is not the first frame, so the cache is useless. Instead we decode & drop the previous frame*/ + else + { + handle->selective_decoding_states[decIdx]->frame_actions[ivasSubframeIdx - 1] = DEC_ACTION_DECODE_AND_DROP; + break; + } + } + } + } + } + + /* if a dec gets paused & caching is activated we need to flag the last useful LC3plus frame for caching */ + for ( decIdx = 0; decIdx < handle->num_decs; decIdx++ ) + { + for ( ivasSubframeIdx = 0; ivasSubframeIdx < actual_num_spatial_subframes; ivasSubframeIdx++ ) + { + if ( handle->selective_decoding_states[decIdx]->frame_actions[ivasSubframeIdx] == DEC_ACTION_SKIP && handle->selective_decoding_states[decIdx]->frame_actions[actual_num_spatial_subframes - 1] != DEC_ACTION_DECODE_AND_USE ) + { + handle->selective_decoding_states[decIdx]->frame_actions[actual_num_spatial_subframes - 1] = DEC_ACTION_CACHE; + } + } + } + + return IVAS_ERR_OK; +} + + +/*------------------------------------------------------------------------- + * IVAS_LC3PLUS_DEC_GetDelay() + * + * + *------------------------------------------------------------------------*/ + +ivas_error IVAS_LC3PLUS_DEC_GetDelay( + IVAS_LC3PLUS_DEC_HANDLE handle, /* i : LC3plus decoder handle */ + int32_t *delayInSamples /* o : decoder delay in number of samples per channel */ +) +{ + int32_t tmpDelayInSamples; + + if ( NULL == handle ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "IVAS_LC3PLUS_DEC_HANDLE is NULL\n" ); + } + if ( NULL == delayInSamples ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "delayInSamples is NULL\n" ); + } + + *delayInSamples = 0; + /* sanity check whether all encoders are actually configured identically */ + for ( uint32_t iDec = 0; iDec < handle->num_decs; iDec++ ) + { + if ( NULL == handle->handles[iDec] ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "LC3plus decoder handle is NULL\n" ); + } + + tmpDelayInSamples = lc3plus_dec_get_delay( handle->handles[iDec] ); + if ( 0 != *delayInSamples && tmpDelayInSamples != *delayInSamples ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "Not all mono LC3plus decoders are configured identically\n" ); + } + + *delayInSamples = tmpDelayInSamples; + } + + return IVAS_ERR_OK; +} + + +/*------------------------------------------------------------------------- + * IVAS_LC3PLUS_DEC_Close() + * + * + *------------------------------------------------------------------------*/ + +void IVAS_LC3PLUS_DEC_Close( + IVAS_LC3PLUS_DEC_HANDLE *handle /* i/o: Pointer to LC3plus decoder handle */ +) +{ + if ( NULL == handle || NULL == *handle ) + { + return; + } + for ( uint32_t iDec = 0; iDec < ( *handle )->num_decs; iDec++ ) + { + if ( NULL != ( *handle )->handles && NULL != ( *handle )->handles[iDec] ) + { + lc3plus_free_decoder_structs( ( *handle )->handles[iDec] ); + free( ( *handle )->handles[iDec] ); + } + + if ( NULL != ( *handle )->selective_decoding_states && NULL != ( *handle )->selective_decoding_states[iDec] ) + { + free( ( *handle )->selective_decoding_states[iDec]->frame_actions ); + free( ( *handle )->selective_decoding_states[iDec] ); + } + + if ( NULL != ( *handle )->bitstream_caches && NULL != ( *handle )->bitstream_caches[iDec] ) + { + free( ( *handle )->bitstream_caches[iDec]->bitstream_cache ); + free( ( *handle )->bitstream_caches[iDec] ); + } + } + + if ( NULL != ( *handle )->pcm_conversion_buffer ) + { + free( ( *handle )->pcm_conversion_buffer ); + } + free( ( *handle )->handles ); + + if ( NULL != ( *handle )->bitstream_caches ) + { + free( ( *handle )->bitstream_caches ); + } + free( ( *handle )->selective_decoding_states ); + + free( *handle ); + *handle = NULL; + + return; +} + + +/*------------------------------------------------------------------------- + * decode_or_conceal_one_lc3plus_frame() + * + * + *------------------------------------------------------------------------*/ + +static ivas_error decode_or_conceal_one_lc3plus_frame( + LC3PLUS_Dec *dec, + uint8_t *bitstream_in, + const int32_t bitstream_in_length, + int16_t **pcm_out_buffer, + const int32_t badFrameIndicator ) +{ + LC3PLUS_Error err; + + push_wmops( "lc3plus_dec16" ); + err = lc3plus_dec16( dec, bitstream_in, bitstream_in_length, pcm_out_buffer, NULL, badFrameIndicator ); + pop_wmops(); + + if ( err == LC3PLUS_DECODE_ERROR && 1 == badFrameIndicator ) + { + /* LC3PLUS_DECODE_ERROR && badFrameIndicator means that the decoder has successfully concealed, which is actually OK. */ + err = LC3PLUS_OK; + } + + if ( err != LC3PLUS_OK ) + { + return IVAS_ERROR( IVAS_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_dec16 failed\n" ); + } + + return IVAS_ERR_OK; +} + + +/*------------------------------------------------------------------------- + * IVAS_LC3PLUS_DEC_Decode_or_Conceal_internal() + * + * + *------------------------------------------------------------------------*/ + +static ivas_error IVAS_LC3PLUS_DEC_Decode_or_Conceal_internal( + IVAS_LC3PLUS_DEC_HANDLE handle, /* i : LC3plus decoder configuration */ + 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 */ +) +{ + uint32_t iDec; + int32_t iLc3plusFrame; + int32_t lc3framesPerIvasFrame; + int32_t ivasSampleIndex; + int16_t numSamplesPerLC3plusChannel; + int32_t bitstreamOffsetPerCoder; + ivas_error err; + uint8_t *bitstream_in_iter = bitstream_in; + + if ( NULL == handle ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "LC3PLUS_Dec_Wrap_Handle is NULL\n" ); + } + if ( NULL == bitstream_in ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "bitstream_in is NULL\n" ); + } + if ( NULL == pcm_out ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "pcm_out is NULL\n" ); + } + if ( badFrameIndicator != 0 && badFrameIndicator != 1 ) + { + return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "badFrameIndicator must be 1 or 0\n" ); + } + if ( badFrameIndicator == 0 && bitstream_in_size <= 0 ) + { + return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "bitstream_in_size must be positive\n" ); + } + + if ( handle->config.ivas_frame_duration_us % handle->config.lc3plus_frame_duration_us != 0 ) + { + return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "ivas_frame_duration_us must be equal or multiple of lc3plus_frame_duration_us \n" ); + } + + lc3framesPerIvasFrame = handle->config.ivas_frame_duration_us / handle->config.lc3plus_frame_duration_us; + + numSamplesPerLC3plusChannel = (int16_t) ( handle->config.samplerate / ( 1000000 / handle->config.ivas_frame_duration_us ) / lc3framesPerIvasFrame ); + bitstreamOffsetPerCoder = bitstream_in_size / handle->num_decs / lc3framesPerIvasFrame; + for ( iDec = 0; iDec < handle->num_decs; iDec++ ) + { + for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) + { + if ( handle->selective_decoding_states[iDec]->shall_decode_cached_frame ) + { + if ( 0 == handle->bitstream_caches[iDec]->bitstream_cache_size ) + { + 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 ); + if ( err != IVAS_ERR_OK ) + { + return IVAS_ERROR( err, "lc3plus decoding failed\n" ); + } + handle->selective_decoding_states[iDec]->shall_decode_cached_frame = 0; + handle->selective_decoding_states[iDec]->has_skipped_a_frame = 0; + } + + /* reset cache if caching is enabled - it has either been decoded or is not needed */ + if ( NULL != handle->bitstream_caches ) + { + handle->bitstream_caches[iDec]->bitstream_cache_size = 0; + } + switch ( handle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] ) + { + 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 ); + if ( err != IVAS_ERR_OK ) + { + return IVAS_ERROR( err, "lc3plus decoding failed\n" ); + } + handle->selective_decoding_states[iDec]->has_skipped_a_frame = 0; + break; + } + case DEC_ACTION_DECODE_AND_USE: + { + err = decode_or_conceal_one_lc3plus_frame( handle->handles[iDec], bitstream_in_iter, bitstreamOffsetPerCoder, &handle->pcm_conversion_buffer, badFrameIndicator ); + if ( err != IVAS_ERR_OK ) + { + return IVAS_ERROR( err, "lc3plus decoding failed\n" ); + } + + for ( int32_t iSampleInt16 = 0; iSampleInt16 < numSamplesPerLC3plusChannel; iSampleInt16++ ) + { + ivasSampleIndex = iSampleInt16 + iLc3plusFrame * numSamplesPerLC3plusChannel; + pcm_out[iDec][ivasSampleIndex] = (float) handle->pcm_conversion_buffer[iSampleInt16]; + } + handle->selective_decoding_states[iDec]->has_skipped_a_frame = 0; + break; + } + case DEC_ACTION_SKIP: + { + /* log that this instance has skipped a frame and must decode twice once reactivated */ + handle->selective_decoding_states[iDec]->has_skipped_a_frame = 1; + break; + } + case DEC_ACTION_CACHE: + { + if ( handle->bitstream_caches[iDec]->bitstream_cache_capacity < bitstreamOffsetPerCoder ) + { + return IVAS_ERROR( IVAS_ERR_INVALID_BUFFER_SIZE, "bitstream_cache_capacity is too low for LC3plus frame size\n" ); + } + /* store bit rate of cached frame */ + mvc2c( bitstream_in_iter, handle->bitstream_caches[iDec]->bitstream_cache, (int16_t) bitstreamOffsetPerCoder ); + handle->bitstream_caches[iDec]->bitstream_cache_size = bitstreamOffsetPerCoder; + /* log that this instance has skipped a frame and must decode twice once reactivated */ + handle->selective_decoding_states[iDec]->has_skipped_a_frame = 1; + break; + } + case DEC_ACTION_NUM_ENUMS: + default: + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "invalid LC3plus decoder state\n" ); + } + + bitstream_in_iter += bitstreamOffsetPerCoder; + } + + /* reset skipping state, must be set by the user before each decode call*/ + for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) + { + handle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] = DEC_ACTION_DECODE_AND_USE; + } + } + + return IVAS_ERR_OK; +} + + +/*------------------------------------------------------------------------- + * IVAS_LC3PLUS_DEC_Decode() + * + * + *------------------------------------------------------------------------*/ + +ivas_error IVAS_LC3PLUS_DEC_Decode( + IVAS_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 */ +) +{ + int16_t badFrameIndicator; + + if ( NULL == handle ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "LC3PLUS_Dec_Wrap_Handle is NULL\n" ); + } + if ( NULL == bitstream_in ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "bitstream_in is NULL\n" ); + } + if ( NULL == pcm_out ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "pcm_out is NULL\n" ); + } + badFrameIndicator = 0; + + return IVAS_LC3PLUS_DEC_Decode_or_Conceal_internal( handle, bitstream_in, bitstream_in_size, badFrameIndicator, pcm_out ); +} + + +/*------------------------------------------------------------------------- + * IVAS_LC3PLUS_DEC_Conceal() + * + * + *------------------------------------------------------------------------*/ + +ivas_error IVAS_LC3PLUS_DEC_Conceal( + IVAS_LC3PLUS_DEC_HANDLE handle, /* i : LC3plus decoder handle */ + float **pcm_out /* o : concealed samples */ +) +{ + uint8_t bitstream_in[LC3PLUS_MAX_BYTES]; + int16_t badFrameIndicator; + + if ( NULL == handle ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "LC3PLUS_Dec_Wrap_Handle is NULL\n" ); + } + + if ( NULL == pcm_out ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "pcm_out is NULL\n" ); + } + + /* LC3plus API requires a non-NULL bitstream pointer, even when triggering concealment */ + badFrameIndicator = 1; + + return IVAS_LC3PLUS_DEC_Decode_or_Conceal_internal( handle, bitstream_in, 0, badFrameIndicator, pcm_out ); +} +#endif /* SPLIT_REND_WITH_HEAD_ROT */ diff --git a/lib_rend/ivas_lc3plus_dec.h b/lib_rend/ivas_lc3plus_dec.h new file mode 100644 index 000000000..6e6f13f62 --- /dev/null +++ b/lib_rend/ivas_lc3plus_dec.h @@ -0,0 +1,119 @@ +/****************************************************************************************************** + + (C) 2022-2023 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 IVAS_LC3PLUS_DEC_H +#define IVAS_LC3PLUS_DEC_H + +#include +#include "options.h" +#include "lc3.h" +#include "ivas_error.h" +#include "ivas_lc3plus_common.h" +#include "ivas_cnst.h" + +typedef enum +{ + DEC_ACTION_DECODE_AND_DROP = 0, + DEC_ACTION_DECODE_AND_USE, + DEC_ACTION_SKIP, + DEC_ACTION_CACHE, + DEC_ACTION_NUM_ENUMS +} SelectiveDecAction; + + +typedef struct IVAS_LC3PLUS_DEC_SELECTIVE_DECODING_STATE +{ + /*! indicates that the decoder has skipped one or more frames. This means it must decode two frames to flush algorithmic delay when re-activated */ + int16_t has_skipped_a_frame; + /*! if set to 1, decoder will skip decoding for the next frame */ + SelectiveDecAction *frame_actions; + /*! if set to 1, decoder will decode the cache before decoding any of current frames */ + int16_t shall_decode_cached_frame; +} IVAS_LC3PLUS_DEC_SELECTIVE_DECODING_STATE; + +typedef struct IVAS_LC3PLUS_DEC_BITSTREAM_CACHE +{ + uint8_t *bitstream_cache; + int32_t bitstream_cache_capacity; + int32_t bitstream_cache_size; +} IVAS_LC3PLUS_DEC_BITSTREAM_CACHE; + +/* decoder wrapper */ +typedef struct IVAS_LC3PLUS_DEC_HANDLE +{ + LC3PLUS_Dec **handles; + IVAS_LC3PLUS_DEC_SELECTIVE_DECODING_STATE **selective_decoding_states; + IVAS_LC3PLUS_DEC_BITSTREAM_CACHE **bitstream_caches; + uint32_t num_decs; + int16_t *pcm_conversion_buffer; + LC3PLUS_CONFIG config; +} * IVAS_LC3PLUS_DEC_HANDLE; + +ivas_error IVAS_LC3PLUS_DEC_Open( + const LC3PLUS_CONFIG config, /* i : decoder configuration */ + IVAS_LC3PLUS_DEC_HANDLE *handle /* o : decoder handle */ +); + +ivas_error IVAS_LC3PLUS_DEC_GetDelay( + IVAS_LC3PLUS_DEC_HANDLE handle, /* i : decoder handle */ + int32_t *delayInSamples /* o : algorithmic delay of encoding and decoding in number of samples per channel */ +); + +void IVAS_LC3PLUS_DEC_Close( + IVAS_LC3PLUS_DEC_HANDLE *handle /* i/o: pointer to decoder handle */ +); + +/*! Sets a matrix[MAX_PARAM_SPATIAL_SUBFRAMES][numLC3plusDecoders] where all require subframes must be flagged with 1, frames that are not required with 0 */ +ivas_error IVAS_LC3PLUS_DEC_SetSelectiveDecodingMatrix( + IVAS_LC3PLUS_DEC_HANDLE handle, /* i : decoder handle */ + int16_t *subframeChannelMatrix[MAX_PARAM_SPATIAL_SUBFRAMES] /* i : */ +); + +ivas_error IVAS_LC3PLUS_DEC_Decode( + IVAS_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 */ +); + +ivas_error IVAS_LC3PLUS_DEC_Conceal( + IVAS_LC3PLUS_DEC_HANDLE handle, /* i : decoder handle */ + float **pcm_out /* o : concealed samples */ +); + +ivas_error IVAS_LC3PLUS_DEC_AllocateSubframeDecodingMatrix( + int16_t ***subframeChannelMatrix, + const uint32_t num_decs ); + +void IVAS_LC3PLUS_DEC_FreeSubframeDecodingMatrix( int16_t **subframeChannelMatrix ); + +#endif /* IVAS_LC3PLUS_DEC_H */ diff --git a/lib_rend/ivas_lc3plus_enc.c b/lib_rend/ivas_lc3plus_enc.c new file mode 100644 index 000000000..8751d3dac --- /dev/null +++ b/lib_rend/ivas_lc3plus_enc.c @@ -0,0 +1,334 @@ +/****************************************************************************************************** + + (C) 2022-2023 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. + +*******************************************************************************************************/ + +#include "ivas_lc3plus_enc.h" +#include "ivas_lc3plus_common.h" +#include "lc3.h" +#include "ivas_error_utils.h" +#include "prot.h" +#include "wmc_auto.h" + +#ifdef SPLIT_REND_WITH_HEAD_ROT +/*-------------------------------------------------------------------* + * Function IVAS_LC3PLUS_ENC_Open() + * + * + *-------------------------------------------------------------------*/ + +ivas_error IVAS_LC3PLUS_ENC_Open( + const LC3PLUS_CONFIG config, /* i : LC3plus encoder configuration */ + const uint32_t bitsPerSecond, /* i : bit rate */ + IVAS_LC3PLUS_ENC_HANDLE *handle /* o : encoder handle */ +) +{ + int32_t bitsPerSecondPerChannel; + int32_t encoder_size; + LC3PLUS_Error err; + int32_t lfeChans[1]; + int16_t i; + + lfeChans[0] = 0; + + if ( 0U == config.channels ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "Invalid number of channels\n" ); + } + bitsPerSecondPerChannel = bitsPerSecond / config.channels; + + encoder_size = lc3plus_enc_get_size( config.samplerate, 1 ); + if ( 0 == encoder_size ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "lc3plus_enc_get_size failed\n" ); + } + + if ( ( *handle = malloc( sizeof( struct IVAS_LC3PLUS_ENC_HANDLE ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus wrapper handle\n" ); + } + + ( *handle )->pcm_conversion_buffer = NULL; + ( *handle )->num_encs = 0; + if ( ( ( *handle )->handles = malloc( config.channels * sizeof( IVAS_LC3PLUS_ENC_HANDLE ) ) ) == NULL ) + { + IVAS_LC3PLUS_ENC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus wrapper handle\n" ); + } + + for ( i = 0; i < config.channels; ++i ) + { + ( *handle )->handles[i] = NULL; + } + ( *handle )->num_encs = config.channels; + + for ( int32_t iCh = 0; iCh < config.channels; iCh++ ) + { + if ( ( ( *handle )->handles[iCh] = malloc( encoder_size ) ) == NULL ) + { + IVAS_LC3PLUS_ENC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus encoder\n" ); + } + + err = lc3plus_enc_init( ( *handle )->handles[iCh], config.samplerate, 1, 0, lfeChans ); + if ( err != LC3PLUS_OK ) + { + IVAS_LC3PLUS_ENC_Close( handle ); + return IVAS_ERROR( IVAS_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_enc_init failed\n" ); + } + + err = lc3plus_enc_set_frame_dms( ( *handle )->handles[iCh], config.lc3plus_frame_duration_us / 100 ); + if ( err != LC3PLUS_OK ) + { + IVAS_LC3PLUS_ENC_Close( handle ); + return IVAS_ERROR( IVAS_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_enc_set_frame_dms failed\n" ); + } + + err = lc3plus_enc_set_bitrate( ( *handle )->handles[iCh], bitsPerSecondPerChannel ); + if ( err != LC3PLUS_OK ) + { + IVAS_LC3PLUS_ENC_Close( handle ); + return IVAS_ERROR( IVAS_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_enc_set_bitrate failed\n" ); + } + } + + if ( config.ivas_frame_duration_us < config.lc3plus_frame_duration_us || config.ivas_frame_duration_us % config.lc3plus_frame_duration_us != 0 ) + { + IVAS_LC3PLUS_ENC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "Current pcm_conversion_buffer sizing requires that lc3plus uses a shorter or equal frame duration than ivas\n" ); + } + + ( *handle )->config = config; + ( *handle )->pcm_conversion_buffer = malloc( sizeof( int16_t ) * config.samplerate * config.lc3plus_frame_duration_us / 1000000 ); + if ( NULL == ( *handle )->pcm_conversion_buffer ) + { + IVAS_LC3PLUS_ENC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus encoder wrapper pcm_conversion_buffer\n" ); + } + + return IVAS_ERR_OK; +} + + +/*-------------------------------------------------------------------* + * Function IVAS_LC3PLUS_ENC_GetDelay() + * + * + *-------------------------------------------------------------------*/ + +ivas_error IVAS_LC3PLUS_ENC_GetDelay( + IVAS_LC3PLUS_ENC_HANDLE handle, /* i : LC3plus encoder handle */ + int32_t *delayInSamples /* o : encoder delay in number of samples per channel */ +) +{ + int32_t tmpDelayInSamples; + + if ( NULL == handle ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "LC3PLUS_Enc_Wrap_Handle is NULL\n" ); + } + if ( NULL == delayInSamples ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "delayInSamples is NULL\n" ); + } + + *delayInSamples = 0; + /* sanity check whether all encoders are actually configured identically */ + for ( uint32_t iEnc = 0; iEnc < handle->num_encs; iEnc++ ) + { + if ( NULL == handle->handles[iEnc] ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "LC3plus encoder handle is NULL\n" ); + } + + tmpDelayInSamples = lc3plus_enc_get_delay( handle->handles[iEnc] ); + if ( 0 != *delayInSamples && tmpDelayInSamples != *delayInSamples ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "Not all mono LC3plus encoders are configured identically\n" ); + } + *delayInSamples = tmpDelayInSamples; + } + + return IVAS_ERR_OK; +} + + +/*-------------------------------------------------------------------* + * Function IVAS_LC3PLUS_ENC_GetOutputBitstreamSize() + * + * + *-------------------------------------------------------------------*/ + +ivas_error IVAS_LC3PLUS_ENC_GetOutputBitstreamSize( + IVAS_LC3PLUS_ENC_HANDLE handle, /* i : LC3plus encoder handle */ + int32_t *bsSize /* o : size of each bitstream frame in bytes */ +) +{ + int32_t bitstreamSizeMultiplier; + if ( NULL == handle ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "LC3PLUS_Enc_Wrap_Handle is NULL\n" ); + } + if ( NULL == bsSize ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "bsSize is NULL\n" ); + } + + *bsSize = 0; + for ( uint32_t iEnc = 0; iEnc < handle->num_encs; iEnc++ ) + { + if ( NULL == handle->handles[iEnc] ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "LC3plus encoder handle is NULL\n" ); + } + *bsSize += lc3plus_enc_get_num_bytes( handle->handles[iEnc] ); + } + + if ( handle->config.ivas_frame_duration_us % handle->config.lc3plus_frame_duration_us != 0 ) + { + return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "ivas_frame_duration_us must be equal or multiple of lc3plus_frame_duration_us \n" ); + } + bitstreamSizeMultiplier = handle->config.ivas_frame_duration_us / handle->config.lc3plus_frame_duration_us; + + *bsSize *= bitstreamSizeMultiplier; + + return IVAS_ERR_OK; +} + + +/*-------------------------------------------------------------------* + * Function IVAS_LC3PLUS_ENC_Close() + * + * + *-------------------------------------------------------------------*/ + +void IVAS_LC3PLUS_ENC_Close( + IVAS_LC3PLUS_ENC_HANDLE *handle /* i/o: pointer to LC3plus encoder handle */ +) +{ + if ( NULL == handle || NULL == *handle ) + { + return; + } + for ( uint32_t iEnc = 0; iEnc < ( *handle )->num_encs; iEnc++ ) + { + if ( NULL != ( *handle )->handles[iEnc] ) + { + lc3plus_free_encoder_structs( ( *handle )->handles[iEnc] ); + free( ( *handle )->handles[iEnc] ); + } + } + if ( NULL != ( *handle )->pcm_conversion_buffer ) + { + free( ( *handle )->pcm_conversion_buffer ); + } + + free( ( *handle )->handles ); + free( *handle ); + + *handle = NULL; + + return; +} + + +/*-------------------------------------------------------------------* + * Function IVAS_LC3PLUS_ENC_Encode() + * + * + *-------------------------------------------------------------------*/ + +ivas_error IVAS_LC3PLUS_ENC_Encode( + IVAS_LC3PLUS_ENC_HANDLE handle, /* i : LC3plus encoder handle */ + float **pcm_in, /* i : pointer input samples */ + void *bitstream_out /* o : pointer to bitstream frame */ +) +{ + uint32_t numSamplesPerLC3plusChannel; + uint32_t lc3framesPerIvasFrame; + int32_t ivasSampleIndex; + uint8_t *bitstream_out_iter = bitstream_out; + int32_t num_bytes = 0; + LC3PLUS_Error err; + + push_wmops( "IVAS_LC3PLUS_ENC_Encode" ); + + if ( NULL == handle ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "LC3PLUS_Enc_Wrap_Handle is NULL\n" ); + } + if ( NULL == pcm_in ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "pcm_in is NULL\n" ); + } + if ( NULL == bitstream_out ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "bitstream_out is NULL\n" ); + } + + if ( handle->config.ivas_frame_duration_us % handle->config.lc3plus_frame_duration_us != 0 ) + { + return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "ivas_frame_duration_us must be equal or multiple of lc3plus_frame_duration_us \n" ); + } + lc3framesPerIvasFrame = handle->config.ivas_frame_duration_us / handle->config.lc3plus_frame_duration_us; + + numSamplesPerLC3plusChannel = handle->config.samplerate / ( 1000000 / handle->config.ivas_frame_duration_us ) / lc3framesPerIvasFrame; + for ( uint32_t iEnc = 0; iEnc < handle->num_encs; iEnc++ ) + { + for ( uint32_t iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) + { + for ( uint32_t iSampleInt16 = 0; iSampleInt16 < numSamplesPerLC3plusChannel; iSampleInt16++ ) + { + ivasSampleIndex = iSampleInt16 + iLc3plusFrame * numSamplesPerLC3plusChannel; + handle->pcm_conversion_buffer[iSampleInt16] = (int16_t) max( INT16_MIN, min( pcm_in[iEnc][ivasSampleIndex], INT16_MAX ) ); + } + + num_bytes = 0; + push_wmops( "lc3plus_enc16" ); + err = lc3plus_enc16( handle->handles[iEnc], &handle->pcm_conversion_buffer, bitstream_out_iter, &num_bytes, NULL ); + pop_wmops(); + if ( err != LC3PLUS_OK ) + { + return IVAS_ERROR( IVAS_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_enc16 failed\n" ); + } + if ( 0 == num_bytes ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "lc3plus_enc16 did not produce output\n" ); + } + + bitstream_out_iter += num_bytes; + } + } + + pop_wmops(); + + return IVAS_ERR_OK; +} +#endif /* SPLIT_REND_WITH_HEAD_ROT */ diff --git a/lib_rend/ivas_lc3plus_enc.h b/lib_rend/ivas_lc3plus_enc.h new file mode 100644 index 000000000..d58ecf1b6 --- /dev/null +++ b/lib_rend/ivas_lc3plus_enc.h @@ -0,0 +1,76 @@ +/****************************************************************************************************** + + (C) 2022-2023 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 IVAS_LC3PLUS_ENC_H +#define IVAS_LC3PLUS_ENC_H + +#include +#include "lc3.h" +#include "ivas_error.h" +#include "ivas_lc3plus_common.h" + +/* encoder wrapper */ +typedef struct IVAS_LC3PLUS_ENC_HANDLE +{ + LC3PLUS_CONFIG config; + LC3PLUS_Enc **handles; + uint32_t num_encs; + int16_t *pcm_conversion_buffer; +} * IVAS_LC3PLUS_ENC_HANDLE; + +ivas_error IVAS_LC3PLUS_ENC_Open( + const LC3PLUS_CONFIG config, /* i : encoder configuration */ + const uint32_t bitsPerSecond, /* i : bit rate */ + IVAS_LC3PLUS_ENC_HANDLE *handle /* o : LC3plus encoder handle */ +); + +ivas_error IVAS_LC3PLUS_ENC_GetDelay( + IVAS_LC3PLUS_ENC_HANDLE handle, /* i : LC3plus encoder handle */ + int32_t *delayInSamples /* o : algorithmic delay of encoding and decoding in number of samples per channel */ +); + +ivas_error IVAS_LC3PLUS_ENC_GetOutputBitstreamSize( + IVAS_LC3PLUS_ENC_HANDLE handle, /* i : LC3plus encoder handle */ + int32_t *bsSize /* o : size of each bitstream frame in bytes */ +); + +void IVAS_LC3PLUS_ENC_Close( + IVAS_LC3PLUS_ENC_HANDLE *handle /* i/o: pointer to LC3plus encoder handle */ +); + +ivas_error IVAS_LC3PLUS_ENC_Encode( + IVAS_LC3PLUS_ENC_HANDLE handle, /* i : LC3plus encoder handle */ + float **pcm_in, /* i : pointer input samples */ + void *bitstream_out /* o : pointer to bitstream frame */ +); + +#endif /* IVAS_LC3PLUS_ENC_H */ diff --git a/lib_rend/ivas_lcld_decoder.c b/lib_rend/ivas_lcld_decoder.c new file mode 100644 index 000000000..8aafcb1fa --- /dev/null +++ b/lib_rend/ivas_lcld_decoder.c @@ -0,0 +1,1668 @@ +/****************************************************************************************************** + + (C) 2022-2023 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. + +*******************************************************************************************************/ + +#include +#include "options.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT +#include "ivas_lcld_prot.h" +#include "ivas_lcld_rom_tables.h" +#include "prot.h" +#include +#include "ivas_prot_rend.h" +#include "wmc_auto.h" + + +/*------------------------------------------------------------------------------------------* + * Local constants + *------------------------------------------------------------------------------------------*/ + +#define HUFF_READ_SIZE ( 4 ) + +/*------------------------------------------------------------------------------------------* + * Local structures + *------------------------------------------------------------------------------------------*/ + +typedef struct TableNode +{ + struct TableNode **ppoNextTable; + struct TableNode *poOrderedNext; + + int32_t *piCodeIndex; + int32_t *piDifference; + int32_t *piLength; +} TableNode; +typedef struct TableList +{ + TableNode *poOrderedTop; + TableNode *poOrderedBottom; + +} TableList; + +struct LCLD_DECODER +{ + int32_t iSampleRate; + int32_t iChannels; + int32_t iNumBlocks; + + int32_t iNumBands; + const int32_t *piBandwidths; + + int32_t iMSMode; + int32_t *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]; +#ifdef ENABLE_PMOD_ADJUST + int32_t **ppiHiSMRFlags; +#endif + 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 ***pppiLCLDSignReal; + int32_t ***pppiLCLDSignImag; + int32_t ***pppiQLCLDReal; + int32_t ***pppiQLCLDImag; + + PredictionDecoder *psPredictionDecoder; + + + NoiseGen *psNoiseGen; +}; + +static void CreateDecodeTable( LCLDDecoder *psLCLDDecoder, int32_t num, const uint16_t ( *ppuiEncTable )[2], int32_t iSize, int32_t iReadLength, uint32_t *iTables ); +static TableNode *CreateTableList( int32_t iReadLength ); +static void DeleteTableList( TableList *ptable_list, int32_t iTables ); +static TableNode *GetNextTable( int32_t iIndex, TableList *table_list, TableNode *poParent, int32_t iReadLength, uint32_t *iTablesCreated ); +static void AddcodeTableList( TableList *ptable_list, int32_t iLength, int32_t iCode, int32_t iCodeIndex, int32_t iReadLength, uint32_t *iTables ); +static void CompleteTables( LCLDDecoder *psLCLDDecoder, int32_t n, TableList *ptable_list, int32_t iReadLength, int32_t iTablesCreated ); + +static TableNode *CreateTableList( int32_t iReadLength ) +{ + int32_t n; + int32_t iMaxTables; + TableNode *ptable_top; + iMaxTables = 1 << 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->ppoNextTable[n] = NULL; + ptable_top->piCodeIndex[n] = 0xffff; + ptable_top->piDifference[n] = 0; + ptable_top->piLength[n] = 0; + } + + return ptable_top; +} +static void DeleteTableList( TableList *ptable_list, int32_t iTables ) +{ + + TableNode *node; + node = ptable_list->poOrderedTop; + + while ( ( iTables ) ) + { + + TableNode *node1 = node; + node = node1->poOrderedNext; + if ( node1->piCodeIndex != NULL ) + { + free( node1->piCodeIndex ); + } + if ( node1->piLength != NULL ) + { + free( node1->piLength ); + } + if ( node1->piDifference != NULL ) + { + free( node1->piDifference ); + } + if ( node1->ppoNextTable != NULL ) + { + free( node1->ppoNextTable ); + } + if ( node1 != NULL ) + { + free( node1 ); + } + iTables--; + } + if ( ptable_list != NULL ) + { + free( ptable_list ); + } +} +static TableNode *GetNextTable( int32_t iIndex, TableList *table_list, TableNode *poParent, int32_t iReadLength, uint32_t *iTablesCreated ) +{ + TableNode *poNextNode; + + 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 */ + table_list->poOrderedBottom->poOrderedNext = poNextNode; + table_list->poOrderedBottom = poNextNode; + + ( *iTablesCreated )++; + } + else + { + poNextNode = poParent->ppoNextTable[iIndex]; + } + + return poNextNode; +} +static void CompleteTables( LCLDDecoder *psLCLDDecoder, int32_t n, TableList *ptable_list, int32_t iReadLength, int32_t iTablesCreated ) +{ + + int32_t iMaxTables; + int32_t j; + TableNode *poNode; + + iMaxTables = 1 << iReadLength; + psLCLDDecoder->c_apauiHuffDecTable_RAM[n] = + malloc( iTablesCreated * iMaxTables * sizeof( uint32_t * ) ); + + poNode = ptable_list->poOrderedTop; + for ( j = 0; j < iTablesCreated; j++ ) + { + int32_t k; + if ( poNode != NULL ) + { + for ( k = 0; k < iMaxTables; k++ ) + { + uint32_t uiCode; + uiCode = poNode->piDifference[k]; + uiCode <<= 16; + uiCode |= poNode->piCodeIndex[k]; + psLCLDDecoder->c_apauiHuffDecTable_RAM[n][j][k] = uiCode; + } + } + poNode = poNode->poOrderedNext; + } +} +static void AddcodeTableList( TableList *ptable_list, int32_t iLength, int32_t iCode, int32_t iCodeIndex, int32_t iReadLength, uint32_t *iTables ) +{ + int32_t iDifference; + int32_t iMask; + int32_t iCurrentLength; + int32_t iIndex; + int32_t iCodeLow; + int32_t iCodeHigh; + + TableNode *poNode; + poNode = ptable_list->poOrderedTop; + iMask = ( 1 << iReadLength ) - 1; + iCurrentLength = iLength; + while ( iCurrentLength > iReadLength ) + { + iDifference = iCurrentLength - iReadLength; + iIndex = iCode >> iDifference; + iIndex &= iMask; + poNode = GetNextTable( iIndex, ptable_list, poNode, iReadLength, iTables ); + 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++ ) + { + poNode->piCodeIndex[iIndex] = iCodeIndex; + poNode->piDifference[iIndex] = iDifference; + poNode->piLength[iIndex] = iLength; + } +} + +static void CreateDecodeTable( LCLDDecoder *psLCLDDecoder, int32_t num, const uint16_t ( *ppuiEncTable )[2], int32_t iSize, int32_t iReadLength, uint32_t *iTables ) +{ + int32_t n; + uint32_t **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[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; + } + + for ( n = 0; n < iSize; n++ ) + { + uint32_t iMin; + int32_t iMinIndex; + int32_t k; + + iMin = ppsort_enc_table[n][0]; + iMinIndex = n; + for ( k = n; k < iSize; k++ ) + { + if ( ppsort_enc_table[k][0] < iMin ) + { + iMin = ppsort_enc_table[k][0]; + iMinIndex = k; + } + } + + if ( iMinIndex != n ) + { + uint32_t uiLength; + uint32_t uiCode; + uint32_t uiCodeIndex; + + uiLength = ppsort_enc_table[n][0]; + uiCode = ppsort_enc_table[n][1]; + uiCodeIndex = ppsort_enc_table[n][2]; + + ppsort_enc_table[n][0] = ppsort_enc_table[iMinIndex][0]; + ppsort_enc_table[n][1] = ppsort_enc_table[iMinIndex][1]; + ppsort_enc_table[n][2] = ppsort_enc_table[iMinIndex][2]; + + ppsort_enc_table[iMinIndex][0] = uiLength; + ppsort_enc_table[iMinIndex][1] = uiCode; + ppsort_enc_table[iMinIndex][2] = uiCodeIndex; + } + } + ptable_list->poOrderedTop = CreateTableList( iReadLength ); + ptable_list->poOrderedBottom = ptable_list->poOrderedTop; + for ( n = 0; n < iSize; n++ ) + { + int32_t iLength; + int32_t iCode; + int32_t iCodeIndex; + + iLength = ppsort_enc_table[n][0]; + iCode = ppsort_enc_table[n][1]; + iCodeIndex = ppsort_enc_table[n][2]; + 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++ ) + { + free( ppsort_enc_table[n] ); + } + free( ppsort_enc_table ); +} + + +/*------------------------------------------------------------------------------------------* + * Function CreateLCLDDecoder() + * + * + *------------------------------------------------------------------------------------------*/ + +ivas_error CreateLCLDDecoder( + LCLDDecoder **psLCLDDecoder_out, + const int32_t iSampleRate, + const int32_t iChannels ) +{ + int32_t n; + int32_t read_length; + ivas_error error; + LCLDDecoder *psLCLDDecoder = NULL; + + assert( iSampleRate == 48000 ); // Fix + + 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; + psLCLDDecoder->iChannels = iChannels; + psLCLDDecoder->iNumBlocks = LCLD_BLOCKS_PER_FRAME; + psLCLDDecoder->iAllocOffset = 0; + + psLCLDDecoder->iNumBands = MAX_BANDS_48; // Fix + psLCLDDecoder->piBandwidths = c_aiBandwidths48; // Fix + + psLCLDDecoder->iMSMode = 0; + if ( ( psLCLDDecoder->piMSFlags = (int32_t *) malloc( MAX_BANDS * sizeof( int32_t ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + for ( n = 0; n < MAX_BANDS; n++ ) + { + psLCLDDecoder->piLRPhaseDiffs[n] = 0; + psLCLDDecoder->piMSPredCoefs[n] = 0; + } +#ifdef ENABLE_PMOD_ADJUST + psLCLDDecoder->ppiHiSMRFlags = + (int32_t **) malloc( psLCLDDecoder->iChannels * sizeof( int32_t * ) ); +#endif + + psLCLDDecoder->iCommonGrouping = 1; /* Common grouping always on only impacts stereo */ + if ( ( psLCLDDecoder->piNumGroups = (int32_t *) malloc( psLCLDDecoder->iChannels * sizeof( int32_t ) ) ) == 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 ) + { + 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 ) + { + 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 ) + { + 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 ) + { + 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 ) + { + 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 ) + { + 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 ) + { + 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 ) + { + 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 ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + + for ( n = 0; n < iChannels; n++ ) + { + int16_t k; +#ifdef ENABLE_PMOD_ADJUST + psLCLDDecoder->ppiHiSMRFlags[n] = + (int32_t *) malloc( MAX_BANDS * sizeof( int32_t ) ); + ; +#endif + if ( ( psLCLDDecoder->ppiGroupLengths[n] = (int32_t *) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( int32_t ) ) ) == 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 ) + { + 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 ) + { + 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 ) + { + 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 ) + { + 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 ) + { + 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 ) + { + 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 ) + { + 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 ) + { + 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++ ) + { + if ( ( psLCLDDecoder->pppiRMSEnvelope[n][k] = (int32_t *) malloc( MAX_BANDS * sizeof( int32_t ) ) ) == 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 ) + { + 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 ) + { + 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 ) + { + 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 ) + { + 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 ) + { + 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 ) + { + 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 ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + } + } + + read_length = READ_LENGTH; + for ( n = 0; n < ALLOC_TABLE_SIZE * 2; n++ ) + { + psLCLDDecoder->num_decode_table[n] = 1; + if ( c_apauiHuffEncTabels[n] != NULL ) + { + + CreateDecodeTable( psLCLDDecoder, n, c_apauiHuffEncTabels[n], num_row_aauiLCLDHuff[n], read_length, &psLCLDDecoder->num_decode_table[n] ); + } + else + { + psLCLDDecoder->c_apauiHuffDecTable_RAM[n] = NULL; + } + } + + if ( ( error = CreatePredictionDecoder( &psLCLDDecoder->psPredictionDecoder, iChannels, psLCLDDecoder->iNumBlocks ) ) != IVAS_ERR_OK ) + { + return error; + } + psLCLDDecoder->psNoiseGen = NULL; // CreateNoiseGen(); // No noise fill for now + *psLCLDDecoder_out = psLCLDDecoder; + + return IVAS_ERR_OK; +} + + +/*------------------------------------------------------------------------------------------* + * Function CreateLCLDDecoder() + * + * + *------------------------------------------------------------------------------------------*/ + +void DeleteLCLDDecoder( LCLDDecoder *psLCLDDecoder ) +{ + int32_t k, n; + + if ( psLCLDDecoder != NULL ) + { + if ( psLCLDDecoder->piMSFlags != NULL ) + { + free( psLCLDDecoder->piMSFlags ); + } + + if ( psLCLDDecoder->piNumGroups != NULL ) + { + free( psLCLDDecoder->piNumGroups ); + } + + if ( psLCLDDecoder->ppiGroupLengths != NULL ) + { + for ( n = 0; n < psLCLDDecoder->iChannels; n++ ) + { + free( psLCLDDecoder->ppiGroupLengths[n] ); + } + free( psLCLDDecoder->ppiGroupLengths ); + } + + if ( psLCLDDecoder->pppiRMSEnvelope != NULL ) + { + for ( n = 0; n < psLCLDDecoder->iChannels; n++ ) + { + for ( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) + { + free( psLCLDDecoder->pppiRMSEnvelope[n][k] ); + } + free( psLCLDDecoder->pppiRMSEnvelope[n] ); + } + free( psLCLDDecoder->pppiRMSEnvelope ); + } + + if ( psLCLDDecoder->pppiSMR != NULL ) + { + for ( n = 0; n < psLCLDDecoder->iChannels; n++ ) + { + for ( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) + { + free( psLCLDDecoder->pppiSMR[n][k] ); + } + free( psLCLDDecoder->pppiSMR[n] ); + } + free( psLCLDDecoder->pppiSMR ); + } + + if ( psLCLDDecoder->pppiExcitation != NULL ) + { + for ( n = 0; n < psLCLDDecoder->iChannels; n++ ) + { + for ( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) + { + free( psLCLDDecoder->pppiExcitation[n][k] ); + } + free( psLCLDDecoder->pppiExcitation[n] ); + } + free( psLCLDDecoder->pppiExcitation ); + } + +#ifdef ENABLE_PMOD_ADJUST + if ( psLCLDDecoder->ppiHiSMRFlags != NULL ) + { + for ( n = 0; n < psLCLDDecoder->iChannels; n++ ) + { + free( psLCLDDecoder->ppiHiSMRFlags[n] ); + } + free( psLCLDDecoder->ppiHiSMRFlags ); + } +#endif + + if ( psLCLDDecoder->pppiAlloc != NULL ) + { + for ( n = 0; n < psLCLDDecoder->iChannels; n++ ) + { + for ( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) + { + free( psLCLDDecoder->pppiAlloc[n][k] ); + } + free( psLCLDDecoder->pppiAlloc[n] ); + } + free( psLCLDDecoder->pppiAlloc ); + } + + if ( psLCLDDecoder->pppiLCLDSignReal != NULL ) + { + for ( n = 0; n < psLCLDDecoder->iChannels; n++ ) + { + for ( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) + { + free( psLCLDDecoder->pppiLCLDSignReal[n][k] ); + } + free( psLCLDDecoder->pppiLCLDSignReal[n] ); + } + free( psLCLDDecoder->pppiLCLDSignReal ); + } + + if ( psLCLDDecoder->pppiLCLDSignImag != NULL ) + { + for ( n = 0; n < psLCLDDecoder->iChannels; n++ ) + { + for ( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) + { + free( psLCLDDecoder->pppiLCLDSignImag[n][k] ); + } + free( psLCLDDecoder->pppiLCLDSignImag[n] ); + } + free( psLCLDDecoder->pppiLCLDSignImag ); + } + + if ( psLCLDDecoder->pppiQLCLDReal != NULL ) + { + for ( n = 0; n < psLCLDDecoder->iChannels; n++ ) + { + for ( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) + { + free( psLCLDDecoder->pppiQLCLDReal[n][k] ); + } + free( psLCLDDecoder->pppiQLCLDReal[n] ); + } + free( psLCLDDecoder->pppiQLCLDReal ); + } + + if ( psLCLDDecoder->pppiQLCLDImag != NULL ) + { + for ( n = 0; n < psLCLDDecoder->iChannels; n++ ) + { + for ( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) + { + free( psLCLDDecoder->pppiQLCLDImag[n][k] ); + } + free( psLCLDDecoder->pppiQLCLDImag[n] ); + } + free( psLCLDDecoder->pppiQLCLDImag ); + } + + for ( n = 0; n < ALLOC_TABLE_SIZE * 2; n++ ) + { + if ( psLCLDDecoder->num_decode_table[n] > 1 ) + { + + if ( psLCLDDecoder->c_apauiHuffDecTable_RAM[n] != NULL ) + { + free( psLCLDDecoder->c_apauiHuffDecTable_RAM[n] ); + } + } + } + + if ( psLCLDDecoder->psPredictionDecoder != NULL ) + { + DeletePredictionDecoder( psLCLDDecoder->psPredictionDecoder ); + psLCLDDecoder->psPredictionDecoder = NULL; + } + + if ( psLCLDDecoder->psNoiseGen != NULL ) + { + DeleteNoiseGen( psLCLDDecoder->psNoiseGen ); + } + + free( psLCLDDecoder ); + } +} + +/*------------------------------------------------------------------------------------------* + * Local function declarations + * + * + *------------------------------------------------------------------------------------------*/ + +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 ReplaceSign( const int32_t iNumBlocks, const int32_t iNumLCLDBands, int32_t **ppiSignReal, int32_t **ppiSignImag, float **ppfReal, float **ppfImag ); + +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 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 int32_t ReadHeaderInformation( int32_t *piNumBands, IVAS_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, IVAS_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, IVAS_SPLIT_REND_BITS_HANDLE pBits ); + +static int32_t ReadHuff( const uint32_t ( *pauiHuffDecTable )[HUFF_DEC_TABLE_SIZE], int32_t *piSymbol, IVAS_SPLIT_REND_BITS_HANDLE pBits ); + +static int32_t ReadRMSEnvelope( const int32_t iChannels, const int32_t *piNumGroups, const int32_t iNumBands, int32_t ***pppiRMSEnvelope, IVAS_SPLIT_REND_BITS_HANDLE pBits ); + +static int32_t ReadAllocInformation( int32_t *piAllocOffset, IVAS_SPLIT_REND_BITS_HANDLE pBits ); + +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, IVAS_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 ); + + +/*------------------------------------------------------------------------------------------* + * Function DecodeLCLDFrame() + * + * + *------------------------------------------------------------------------------------------*/ + +int32_t DecodeLCLDFrame( + LCLDDecoder *psLCLDDecoder, + IVAS_SPLIT_REND_BITS_HANDLE pBits, + float ***pppfLCLDReal, + float ***pppfLCLDImag ) +{ + int32_t k, n; + + ReadHeaderInformation( &psLCLDDecoder->iNumBands, pBits ); + + if ( psLCLDDecoder->iChannels == 2 ) + { + ReadMSInformation( psLCLDDecoder->iNumBands, &psLCLDDecoder->iMSMode, psLCLDDecoder->piMSFlags, psLCLDDecoder->piLRPhaseDiffs, psLCLDDecoder->piMSPredCoefs, pBits ); + } + + ReadPredictors( psLCLDDecoder->psPredictionDecoder, pBits ); + + 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 ); + +#ifdef ENABLE_PMOD_ADJUST + ReadPmodInformation( psLCLDDecoder->ppiHiSMRFlags, pBits, psLCLDDecoder->iChannels, psLCLDDecoder->iNumBands ); +#endif + + ReadAllocInformation( &psLCLDDecoder->iAllocOffset, pBits ); + + if ( psLCLDDecoder->iChannels == 2 && psLCLDDecoder->iCommonGrouping == 1 ) + { /* MS Mode? */ + 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] ); + } + } + else + { + for ( n = 0; n < psLCLDDecoder->iChannels; n++ ) + { // This will be updated to support multiple sample rates + for ( k = 0; k < psLCLDDecoder->piNumGroups[n]; k++ ) + { + PerceptualModel( 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 ); + + for ( n = 0; n < psLCLDDecoder->iChannels; n++ ) + { + ReadLCLDData( + psLCLDDecoder->piNumGroups[n], + (const int32_t *) psLCLDDecoder->ppiGroupLengths[n], + psLCLDDecoder->iNumBands, psLCLDDecoder->piBandwidths, + (const int32_t *) + psLCLDDecoder->psPredictionDecoder->ppiPredBandEnable[n], + psLCLDDecoder->pppiAlloc[n], + psLCLDDecoder->pppiLCLDSignReal[n], psLCLDDecoder->pppiLCLDSignImag[n], + psLCLDDecoder->pppiQLCLDReal[n], psLCLDDecoder->pppiQLCLDImag[n], + pBits, + psLCLDDecoder->c_apauiHuffDecTable_RAM ); + } + + 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, LCLD_BANDS, + psLCLDDecoder->pppiLCLDSignReal[n], + psLCLDDecoder->pppiLCLDSignImag[n], + pppfLCLDReal[n], pppfLCLDImag[n] ); + } + + ApplyInversePredictros( psLCLDDecoder->psPredictionDecoder, pppfLCLDReal, pppfLCLDImag ); + + for ( n = 0; n < psLCLDDecoder->iChannels; n++ ) + { + ApplyRMSEnvelope( psLCLDDecoder->iNumBands, psLCLDDecoder->piBandwidths, + psLCLDDecoder->piNumGroups[n], + (const int32_t *) psLCLDDecoder->ppiGroupLengths[n], + psLCLDDecoder->pppiRMSEnvelope[n], + pppfLCLDReal[n], pppfLCLDImag[n] ); + } + + if ( psLCLDDecoder->iChannels == 2 && psLCLDDecoder->iMSMode > 0 ) + { + 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 ); + } + + return 0; +} + + +/*------------------------------------------------------------------------------------------* + * 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 ) +{ + int32_t b, k, n; + int32_t iBlockOffset, iFBOffset; + + iBlockOffset = 0; + for ( n = 0; n < iNumGroups; n++ ) + { + for ( k = 0; k < piGroupLengths[n]; k++ ) + { + iFBOffset = 0; + for ( b = 0; b < iNumBands; b++ ) + { + int32_t m; + int32_t iRMSEnv; + float fGain; + + iRMSEnv = ppiRMSEnvelope[n][b]; + fGain = + c_afRMSEnvReconstructTable[ENV_RECONSTRUCT_TABLE_CENTER + iRMSEnv]; + for ( m = 0; m < piBandwidths[b]; m++ ) + { + ppfReal[iBlockOffset][iFBOffset] *= fGain; + ppfImag[iBlockOffset][iFBOffset] *= fGain; + iFBOffset++; + } + } + iBlockOffset++; + } + } + + return; +} + + +static void ReplaceSign( + const int32_t iNumBlocks, + const int32_t iNumLCLDBands, + int32_t **ppiSignReal, + int32_t **ppiSignImag, + float **ppfReal, + float **ppfImag ) +{ + int32_t b, n; + + for ( n = 0; n < iNumBlocks; n++ ) + { + for ( b = 0; b < iNumLCLDBands; b++ ) + { + if ( ppiSignReal[n][b] == 1 ) + { + ppfReal[n][b] = -ppfReal[n][b]; + } + + if ( ppiSignImag[n][b] == 1 ) + { + ppfImag[n][b] = -ppfImag[n][b]; + } + } + } + + 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, + NoiseGen *psNoiseGen /* Pass in NULL to switch off noise gen */ +) +{ + int32_t b, k, n; + int32_t iBlockOffest, iFBOffset; + + iBlockOffest = 0; + for ( n = 0; n < iNumGroups; n++ ) + { + for ( k = 0; k < piGroupLengths[n]; k++ ) + { + iFBOffset = 0; + for ( b = 0; b < iNumBands; b++ ) + { + int32_t m; + int32_t iAlloc; + float fInvSCFGain; + + iAlloc = ppiAlloc[n][b]; + fInvSCFGain = c_afInvScaleFactor[iAlloc]; + + if ( iAlloc > 0 ) + { + 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; + + iFBOffset++; + } + } + else if ( psNoiseGen != NULL ) + { + for ( m = 0; m < piBandwidths[b]; m++ ) + { + ppfReal[iBlockOffest][iFBOffset] = 0.7f * GetNoise( psNoiseGen ); + ppfImag[iBlockOffest][iFBOffset] = 0.7f * GetNoise( psNoiseGen ); + + iFBOffset++; + } + } + else + { + iFBOffset += piBandwidths[b]; + } + } + + iBlockOffest++; + } + } + + 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 ) +{ + if ( iMSMode > 0 ) + { + int32_t b; + int32_t iFBOffset; + int32_t bms = 0; +#if defined SIMPLE_PHASE + void( *pFuncPhaseRotateOptions[4] ) = { &rot_zero, &rot_m_pi_2, &rot_pm_pi, &rot_p_pi_2 }; +#endif + + iFBOffset = 0; + for ( b = 0; b < iNumBands; b++ ) + { + if ( piMSFlags[b] == 1 ) + { + int32_t n; +#if defined SIMPLE_PHASE + void ( *pFuncPhaseRotate )( float *, float * ) = + pFuncPhaseRotateOptions[piLRPhaseDiffs[bms]]; +#endif + for ( n = 0; n < piBandwidths[b]; n++ ) + { + int32_t k; + for ( k = 0; k < iNumBlocks; k++ ) + { + float fLeftReal; + float fLeftImag; + float fRightReal; + float fRightImag; + + if ( iMSMode == 3 ) + { + float fPred; + fPred = dequantPred( piMSPredCoefs[bms] ); + pppfReal[1][k][iFBOffset] += fPred * pppfReal[0][k][iFBOffset]; + pppfImag[1][k][iFBOffset] += fPred * pppfImag[0][k][iFBOffset]; + } + + 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] ); + + if ( iMSMode == 3 ) + { +#ifdef SIMPLE_PHASE + ( *pFuncPhaseRotate )( &fRightReal, &fRightImag ); +#else + int32_t phaseIdx; + phaseIdx = piLRPhaseDiffs[bms] - PHASE_MIN_VAL; + cplxmult( &fRightReal, &fRightImag, c_afRotRealImag[phaseIdx][0], -c_afRotRealImag[phaseIdx][1] ); +#endif + } + + pppfReal[0][k][iFBOffset] = fLeftReal; + pppfReal[1][k][iFBOffset] = fRightReal; + pppfImag[0][k][iFBOffset] = fLeftImag; + pppfImag[1][k][iFBOffset] = fRightImag; + } + iFBOffset++; + } + + bms++; + } + else + { + iFBOffset += piBandwidths[b]; + } + } + } + + return; +} + + +/* Currently only the number of bands in frame */ +static int32_t ReadHeaderInformation( + int32_t *piNumBands, + IVAS_SPLIT_REND_BITS_HANDLE pBits ) +{ + int32_t iBitsRead; + + iBitsRead = 0; + *piNumBands = ivas_split_rend_bitstream_read_int32( pBits, 5 ); + iBitsRead += 5; + + return iBitsRead; +} + + +static int32_t ReadMSInformation( + const int32_t iNumBands, + int32_t *piMSMode, + int32_t *piMSFlags, + int32_t *piLRPhaseDiffs, + int32_t *piMSPredCoefs, + IVAS_SPLIT_REND_BITS_HANDLE pBits ) +{ + int32_t iBitsRead; + + iBitsRead = 0; + *piMSMode = ivas_split_rend_bitstream_read_int32( pBits, 2 ); + iBitsRead += 2; + + if ( *piMSMode == 0 ) + { + int32_t n; + for ( n = 0; n < iNumBands; n++ ) + { + piMSFlags[n] = 0; + } + } + else if ( *piMSMode == 1 ) + { + int32_t n; + for ( n = 0; n < iNumBands; n++ ) + { + piMSFlags[n] = 1; + } + } + else if ( *piMSMode == 2 ) + { + int32_t n; + for ( n = 0; n < iNumBands; n++ ) + { + piMSFlags[n] = ivas_split_rend_bitstream_read_int32( pBits, 1 ); + iBitsRead += 1; + } + } + else if ( *piMSMode == 3 ) + { + int32_t n; + int32_t iMSPredAll; + int32_t iNumMSPredBands = 0; + int32_t anyNonZero; + iMSPredAll = ivas_split_rend_bitstream_read_int32( pBits, 1 ); + iBitsRead += 1; + if ( iMSPredAll ) + { + iNumMSPredBands = iNumBands; + for ( n = 0; n < iNumBands; n++ ) + { + piMSFlags[n] = 1; + } + } + else + { + for ( n = 0; n < iNumBands; n++ ) + { + piMSFlags[n] = ivas_split_rend_bitstream_read_int32( pBits, 1 ); + iBitsRead += 1; + if ( piMSFlags[n] ) + { + iNumMSPredBands++; + } + } + } + anyNonZero = ivas_split_rend_bitstream_read_int32( pBits, 1 ); + if ( anyNonZero ) + { +#ifdef SIMPLE_PHASE + for ( n = 0; n < iNumMSPredBands; n++ ) + { + piLRPhaseDiffs[n] = ivas_split_rend_bitstream_read_int32( pBits, SIMPLE_PHASE_BITS ); + iBitsRead += SIMPLE_PHASE_BITS; + } +#else + piLRPhaseDiffs[0] = ivas_split_rend_bitstream_read_int32( pBits, PHASE_BAND0_BITS ); + piLRPhaseDiffs[0] += PHASE_MIN_VAL; + 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; + } + DecodePhase( piLRPhaseDiffs, iNumMSPredBands, PHASE_DIFF_DIM ); +#endif + } + else + { + for ( n = 0; n < iNumMSPredBands; n++ ) + { + piLRPhaseDiffs[n] = 0; + } + } + anyNonZero = ivas_split_rend_bitstream_read_int32( pBits, 1 ); + if ( anyNonZero ) + { + piMSPredCoefs[0] = ivas_split_rend_bitstream_read_int32( pBits, PRED_BAND0_BITS ); + piMSPredCoefs[0] += PRED_MIN_VAL; + 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; + } + DecodePredCoef( piMSPredCoefs, iNumMSPredBands ); + } + else + { + for ( n = 0; n < iNumMSPredBands; n++ ) + { + piMSPredCoefs[n] = 0; + } + } +#ifdef DEBUG_WRITE_MS_PRED + { + static FILE *fid = 0; + if ( !fid ) + { + fid = fopen( "ms_mode_dec.txt", "wt" ); + } + writeMSPred( piLRPhaseDiffs, piMSPredCoefs, *piMSMode, iNumMSPredBands, iNumBands, fid, piMSFlags ); + } +#endif + } + else + { + printf( "ERROR UNSUPPORTED MS MODE\n" ); + } + + return iBitsRead; +} + + +static int32_t ReadGroupInformation( + const int32_t iChannels, + const int32_t iNumBlocks, + int32_t *piCommonGrouping, + int32_t *piNumGroups, + int32_t **ppiGroupLengths, + IVAS_SPLIT_REND_BITS_HANDLE pBits ) +{ + int32_t c, k, iBitsRead; + + iBitsRead = 0; + if ( iChannels == 2 ) + { + *piCommonGrouping = ivas_split_rend_bitstream_read_int32( pBits, 1 ); + iBitsRead += 1; + + if ( *piCommonGrouping == 1 ) + { + piNumGroups[0] = 0; + ppiGroupLengths[0][piNumGroups[0]] = 1; + for ( k = 0; k < ( iNumBlocks - 1 ); k++ ) + { + int32_t iGroupStart; + + iGroupStart = ivas_split_rend_bitstream_read_int32( pBits, 1 ); + iBitsRead += 1; + + if ( iGroupStart == 1 ) + { + piNumGroups[0]++; + ppiGroupLengths[0][piNumGroups[0]] = 1; + } + else + { + ppiGroupLengths[0][piNumGroups[0]]++; + } + } + piNumGroups[0]++; + + piNumGroups[1] = piNumGroups[0]; + for ( k = 0; k < piNumGroups[1]; k++ ) + { + ppiGroupLengths[1][k] = ppiGroupLengths[0][k]; + } + } + else + { + for ( c = 0; c < iChannels; c++ ) + { + piNumGroups[c] = 0; + ppiGroupLengths[c][piNumGroups[c]] = 1; + for ( k = 0; k < ( iNumBlocks - 1 ); k++ ) + { + int32_t iGroupStart; + + iGroupStart = ivas_split_rend_bitstream_read_int32( pBits, 1 ); + iBitsRead += 1; + + if ( iGroupStart == 1 ) + { + piNumGroups[c]++; + ppiGroupLengths[c][piNumGroups[c]] = 1; + } + else + { + ppiGroupLengths[c][piNumGroups[c]]++; + } + } + piNumGroups[c]++; + } + } + } + else + { + for ( c = 0; c < iChannels; c++ ) + { + piNumGroups[c] = 0; + ppiGroupLengths[c][piNumGroups[c]] = 1; + for ( k = 0; k < ( iNumBlocks - 1 ); k++ ) + { + int32_t iGroupStart; + + iGroupStart = ivas_split_rend_bitstream_read_int32( pBits, 1 ); + iBitsRead += 1; + + if ( iGroupStart == 1 ) + { + piNumGroups[c]++; + ppiGroupLengths[c][piNumGroups[c]] = 1; + } + else + { + ppiGroupLengths[c][piNumGroups[c]]++; + } + } + piNumGroups[c]++; + } + } + + return iBitsRead; +} + + +static int32_t BSForceBack( + IVAS_SPLIT_REND_BITS_HANDLE pBits, + int32_t iValue, + int32_t iBitCount ) +{ + pBits->bits_read -= iBitCount; + + return ( iValue >> iBitCount ); +} + + +static int32_t ReadHuff( + const uint32_t ( *pauiHuffDecTable )[HUFF_DEC_TABLE_SIZE], + int32_t *piSymbol, + IVAS_SPLIT_REND_BITS_HANDLE pBits ) +{ + int32_t iBitsRead; + int32_t iSymbol; + int32_t iIndex; + int32_t iVal; + + iVal = 0; + iIndex = 0; + iSymbol = 0xFFFF; + iBitsRead = 0; + while ( iSymbol == 0xFFFF ) + { + iIndex = ivas_split_rend_bitstream_read_int32( pBits, HUFF_READ_SIZE ); + iBitsRead += HUFF_READ_SIZE; + + iIndex = pauiHuffDecTable[iVal][iIndex]; + iSymbol = ( iIndex & 0xFFFF ); + + iVal = ( iIndex >> 16 ); + } + + if ( iVal ) + { + BSForceBack( pBits, iIndex, iVal ); + iBitsRead -= iVal; + } + + *piSymbol = iSymbol; + + return iBitsRead; +} + + +static int32_t ReadRMSEnvelope( + const int32_t iChannels, + const int32_t *piNumGroups, + const int32_t iNumBands, + int32_t ***pppiRMSEnvelope, + IVAS_SPLIT_REND_BITS_HANDLE pBits ) +{ + int32_t b, k, n; + int32_t iBitsRead, iLastRMSVal; + + iBitsRead = 0; + for ( n = 0; n < iChannels; n++ ) + { + for ( k = 0; k < piNumGroups[n]; k++ ) + { + iLastRMSVal = ivas_split_rend_bitstream_read_int32( pBits, ENV0_BITS ); + iBitsRead += ENV0_BITS; + + iLastRMSVal += ENV_MIN; + pppiRMSEnvelope[n][k][0] = iLastRMSVal; + for ( b = 1; b < iNumBands; b++ ) + { + int32_t iDelta; + + iBitsRead += ReadHuff( c_aaiRMSEnvHuffDec, &iDelta, pBits ); + + iDelta += ENV_DELTA_MIN; + iLastRMSVal += iDelta; + pppiRMSEnvelope[n][k][b] = iLastRMSVal; + } + } + } + + return iBitsRead; +} + + +#ifdef ENABLE_PMOD_ADJUST +static int32_t ReadPmodInformation( + int32_t **ppiHiSMRFlags, + IVAS_SPLIT_REND_BITS_HANDLE pBits, + int32_t iChannels, + int32_t iNumBands ) +{ + int32_t iBitsRead; + int32_t c; + iBitsRead = 0; + for ( c = 0; c < iChannels; c++ ) + { + int32_t b; + int32_t iFlags = ivas_split_rend_bitstream_read_int32( pBits, 1 ); + iBitsRead += 1; + if ( iFlags ) + { + for ( b = 0; b < iNumBands; b++ ) + { + ppiHiSMRFlags[c][b] = ivas_split_rend_bitstream_read_int32( pBits, 1 ); + iBitsRead += 1; + } + } + else + { + for ( b = 0; b < iNumBands; b++ ) + { + ppiHiSMRFlags[c][b] = 0; + } + } + } +#ifdef WRITE_HISMR_FLAGS + { + static FILE *fid = 0; + if ( !fid ) + { + fid = fopen( "hismr_dec.txt", "wt" ); + } + for ( c = 0; c < iChannels; c++ ) + { + int32_t b; + for ( b = 0; b < iNumBands; b++ ) + { + if ( c == iChannels - 1 && b == iNumBands - 1 ) + { + fprintf( fid, "%d\n", ppiHiSMRFlags[c][b] ); + } + else + { + fprintf( fid, "%d ", ppiHiSMRFlags[c][b] ); + } + } + } + } +#endif + return iBitsRead; +} +#endif + + +static int32_t ReadAllocInformation( + int32_t *piAllocOffset, + IVAS_SPLIT_REND_BITS_HANDLE pBits ) +{ + int32_t iBitsRead; + + iBitsRead = 0; + *piAllocOffset = ivas_split_rend_bitstream_read_int32( pBits, ALLOC_OFFSET_BITS ); + *piAllocOffset += MIN_ALLOC_OFFSET; + iBitsRead += ALLOC_OFFSET_BITS; + + return iBitsRead; +} + +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, + IVAS_SPLIT_REND_BITS_HANDLE pBits, + uint32_t ( *c_apauiHuffDecTables[2 * ALLOC_TABLE_SIZE] )[HUFF_DEC_TABLE_SIZE] ) +{ + int32_t b, k, m, n; + int32_t iBitsRead, iBlockOffest, iFBOffset; + int32_t iAlloc, iHuffDim, iHuffMod; + + iBitsRead = 0; + iBlockOffest = 0; + for ( n = 0; n < iNumGroups; n++ ) + { + for ( k = 0; k < piGroupLengths[n]; k++ ) + { + iFBOffset = 0; + for ( b = 0; b < iNumBands; b++ ) + { + iAlloc = ppiAlloc[n][b]; + + iHuffDim = c_aiHuffmanDim[iAlloc]; + iHuffMod = c_aiHuffmanMod[iAlloc]; + + if ( iAlloc > 0 ) + { + const uint32_t( *pauiHuffmanTable )[HUFF_DEC_TABLE_SIZE] = NULL; + const uint32_t( *pauiHuffmanTableDPCM )[HUFF_DEC_TABLE_SIZE] = NULL; +#ifdef USE_DEMOD_TABLES + const int32_t( *paiDemodTable )[2] = NULL; +#endif + 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]; +#ifdef USE_DEMOD_TABLES + paiDemodTable = c_apaiDemodTables[iAlloc]; +#endif + for ( m = 0; m < piBandwidths[b]; m++ ) + { + int32_t iQuantValue1 = 0; + int32_t iQuantValue2 = 0; + + if ( piPredEnable[iFBOffset] == 1 ) + { + if ( iHuffDim == 2 ) + { + int32_t iSymbol; + iBitsRead += ReadHuff( pauiHuffmanTableDPCM, &iSymbol, pBits ); +#ifdef USE_DEMOD_TABLES + iQuantValue1 = paiDemodTable[iSymbol][0]; + iQuantValue2 = paiDemodTable[iSymbol][1]; +#else + iQuantValue1 = iSymbol / iHuffMod; + iQuantValue2 = iSymbol % iHuffMod; +#endif + } + else + { + iBitsRead += ReadHuff( pauiHuffmanTableDPCM, &iQuantValue1, pBits ); + iBitsRead += ReadHuff( pauiHuffmanTableDPCM, &iQuantValue2, pBits ); + } + } + else + { + if ( iHuffDim == 2 ) + { + int32_t iSymbol; + + iBitsRead += ReadHuff( pauiHuffmanTable, &iSymbol, pBits ); +#ifdef USE_DEMOD_TABLES + iQuantValue1 = paiDemodTable[iSymbol][0]; + iQuantValue2 = paiDemodTable[iSymbol][1]; +#else + iQuantValue1 = iSymbol / iHuffMod; + iQuantValue2 = iSymbol % iHuffMod; +#endif + } + else + { + iBitsRead += ReadHuff( pauiHuffmanTable, &iQuantValue1, pBits ); + iBitsRead += ReadHuff( pauiHuffmanTable, &iQuantValue2, pBits ); + } + } + + ppiQReal[iBlockOffest][iFBOffset] = iQuantValue1; + ppiQImag[iBlockOffest][iFBOffset] = iQuantValue2; + + if ( iQuantValue1 > 0 ) + { + ppiSignReal[iBlockOffest][iFBOffset] = ivas_split_rend_bitstream_read_int32( pBits, 1 ); + iBitsRead += 1; + } + else + { + ppiSignReal[iBlockOffest][iFBOffset] = 0; + } + if ( iQuantValue2 > 0 ) + { + ppiSignImag[iBlockOffest][iFBOffset] = ivas_split_rend_bitstream_read_int32( pBits, 1 ); + iBitsRead += 1; + } + else + { + ppiSignImag[iBlockOffest][iFBOffset] = 0; + } + + iFBOffset++; + } + } + else + { + for ( m = 0; m < piBandwidths[b]; m++ ) + { + ppiSignReal[iBlockOffest][iFBOffset] = 0; + ppiSignImag[iBlockOffest][iFBOffset] = 0; + iFBOffset++; + } + } + } + + iBlockOffest++; + } + } + + return iBitsRead; +} + + +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 ) +{ + int32_t b, k, n, iAlloc; + + for ( n = 0; n < iChannels; n++ ) + { + for ( k = 0; k < piNumGroups[n]; k++ ) + { + for ( b = 0; b < iNumBands; b++ ) + { + iAlloc = ( ( pppiSMR[n][k][b] + iAllocOffset * ALLOC_OFFSET_SCALE ) >> 5 ); + iAlloc = ( iAlloc > MIN_ALLOC ) ? iAlloc : MIN_ALLOC; + iAlloc = ( iAlloc < MAX_ALLOC ) ? iAlloc : MAX_ALLOC; + pppiAlloc[n][k][b] = iAlloc; + } + } + } + + return; +} +#endif diff --git a/lib_rend/ivas_lcld_encoder.c b/lib_rend/ivas_lcld_encoder.c new file mode 100644 index 000000000..127aaea5c --- /dev/null +++ b/lib_rend/ivas_lcld_encoder.c @@ -0,0 +1,2011 @@ +/****************************************************************************************************** + + (C) 2022-2023 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. + +*******************************************************************************************************/ + +#include +#include "options.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT +#include +#include +#include "ivas_lcld_prot.h" +#include "ivas_lcld_rom_tables.h" +#include "prot.h" +#include "ivas_prot_rend.h" +#ifdef ENABLE_PMOD_ADJUST +#include "ton_corr.h" +#endif +#include "wmc_auto.h" + +/*------------------------------------------------------------------------------------------* + * Local structures + *------------------------------------------------------------------------------------------*/ + +struct LCLD_ENCODER +{ + int32_t iSampleRate; + int32_t iChannels; + int32_t iNumBlocks; + + int32_t iTargetBitRate; + int32_t iTargetBitsPerFrame; + + int32_t iNumBands; + const int32_t *piBandwidths; + + int32_t iMSMode; + int32_t *piMSFlags; + int32_t piMSPredCoefs[MAX_BANDS]; + int32_t piLRPhaseDiffs[MAX_BANDS]; + int32_t iAllowSidePred; + +#ifdef ENABLE_PMOD_ADJUST + int32_t **ppiHiSMRFlags; +#endif + + RMSEnvelopeGrouping *psRMSEnvelopeGrouping; + + 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 ***pppiLCLDSignReal; + int32_t ***pppiLCLDSignImag; + int32_t ***pppiQLCLDReal; + int32_t ***pppiQLCLDImag; + + + PredictionEncoder *psPredictionEncoder; +}; + + +/*------------------------------------------------------------------------------------------* + * Function CreateLCLDEncoder() + * + * + *------------------------------------------------------------------------------------------*/ + +ivas_error CreateLCLDEncoder( + LCLDEncoder **psLCLDEncoder_out, + const int32_t iSampleRate, + const int32_t iChannels, + const int32_t iTargetBitRate, + const int32_t iAllowSidePred ) +{ + int32_t n; + LCLDEncoder *psLCLDEncoder; + ivas_error error; + + assert( iSampleRate == 48000 ); // Fix + + 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; + psLCLDEncoder->iChannels = iChannels; + psLCLDEncoder->iNumBlocks = LCLD_BLOCKS_PER_FRAME; + psLCLDEncoder->iAllocOffset = 0; + + psLCLDEncoder->iTargetBitRate = iTargetBitRate; + psLCLDEncoder->iTargetBitsPerFrame = iTargetBitRate * LCLD_BLOCKS_PER_FRAME * LCLD_BANDS / iSampleRate; + + psLCLDEncoder->iNumBands = MAX_BANDS_48; // Fix + psLCLDEncoder->piBandwidths = c_aiBandwidths48; // Fix + + psLCLDEncoder->iMSMode = 0; + if ( ( psLCLDEncoder->piMSFlags = (int32_t *) malloc( MAX_BANDS * sizeof( int32_t ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + + for ( n = 0; n < MAX_BANDS; n++ ) + { + psLCLDEncoder->piLRPhaseDiffs[n] = 0; + psLCLDEncoder->piMSPredCoefs[n] = 0; + } + psLCLDEncoder->iAllowSidePred = iAllowSidePred; + + 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 ) + { + 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 ) + { + 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 ) + { + 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 ) + { + 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 ) + { + 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 ) + { + 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 ) + { + 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 ) + { + 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 ) + { + 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 ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } +#ifdef ENABLE_PMOD_ADJUST + if ( ( psLCLDEncoder->ppiHiSMRFlags = (int32_t **) malloc( psLCLDEncoder->iChannels * sizeof( int32_t * ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } +#endif + + + for ( n = 0; n < iChannels; n++ ) + { + int32_t k; +#ifdef ENABLE_PMOD_ADJUST + if ( ( psLCLDEncoder->ppiHiSMRFlags[n] = (int32_t *) malloc( MAX_BANDS * sizeof( int32_t ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } +#endif + if ( ( psLCLDEncoder->ppiGroupLengths[n] = (int32_t *) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( int32_t ) ) ) == 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 ) + { + 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 ) + { + 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 ) + { + 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 ) + { + 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 ) + { + 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 ) + { + 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 ) + { + 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 ) + { + 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++ ) + { + if ( ( psLCLDEncoder->pppiRMSEnvelope[n][k] = (int32_t *) malloc( MAX_BANDS * sizeof( int32_t ) ) ) == 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 ) + { + 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 ) + { + 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 ) + { + 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 ) + { + 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 ) + { + 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 ) + { + 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 ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + } + } + + if ( ( error = CreatePredictionEncoder( &( psLCLDEncoder->psPredictionEncoder ), iChannels, psLCLDEncoder->iNumBlocks ) ) != IVAS_ERR_OK ) + { + return error; + } + + *psLCLDEncoder_out = psLCLDEncoder; + + return IVAS_ERR_OK; +} + + +/*------------------------------------------------------------------------------------------* + * Function DeleteLCLDEncoder() + * + * + *------------------------------------------------------------------------------------------*/ + +void DeleteLCLDEncoder( + LCLDEncoder *psLCLDEncoder ) +{ + int32_t k, n; + + if ( psLCLDEncoder != NULL ) + { + + if ( psLCLDEncoder->piMSFlags != NULL ) + { + free( psLCLDEncoder->piMSFlags ); + } + + if ( psLCLDEncoder->piNumGroups != NULL ) + { + free( psLCLDEncoder->piNumGroups ); + } + + if ( psLCLDEncoder->psRMSEnvelopeGrouping != NULL ) + { + DeleteRMSEnvelopeGrouping( psLCLDEncoder->psRMSEnvelopeGrouping ); + } + + if ( psLCLDEncoder->ppiGroupLengths != NULL ) + { + for ( n = 0; n < psLCLDEncoder->iChannels; n++ ) + { + free( psLCLDEncoder->ppiGroupLengths[n] ); + } + free( psLCLDEncoder->ppiGroupLengths ); + } +#ifdef ENABLE_PMOD_ADJUST + if ( psLCLDEncoder->ppiHiSMRFlags != NULL ) + { + for ( n = 0; n < psLCLDEncoder->iChannels; n++ ) + { + free( psLCLDEncoder->ppiHiSMRFlags[n] ); + } + free( psLCLDEncoder->ppiHiSMRFlags ); + } +#endif + if ( psLCLDEncoder->pppiRMSEnvelope != NULL ) + { + for ( n = 0; n < psLCLDEncoder->iChannels; n++ ) + { + for ( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) + { + free( psLCLDEncoder->pppiRMSEnvelope[n][k] ); + } + free( psLCLDEncoder->pppiRMSEnvelope[n] ); + } + free( psLCLDEncoder->pppiRMSEnvelope ); + } + + if ( psLCLDEncoder->pppiSMR != NULL ) + { + for ( n = 0; n < psLCLDEncoder->iChannels; n++ ) + { + for ( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) + { + free( psLCLDEncoder->pppiSMR[n][k] ); + } + free( psLCLDEncoder->pppiSMR[n] ); + } + free( psLCLDEncoder->pppiSMR ); + } + + if ( psLCLDEncoder->pppiExcitation != NULL ) + { + for ( n = 0; n < psLCLDEncoder->iChannels; n++ ) + { + for ( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) + { + free( psLCLDEncoder->pppiExcitation[n][k] ); + } + free( psLCLDEncoder->pppiExcitation[n] ); + } + free( psLCLDEncoder->pppiExcitation ); + } + + if ( psLCLDEncoder->pppiAlloc != NULL ) + { + for ( n = 0; n < psLCLDEncoder->iChannels; n++ ) + { + for ( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) + { + free( psLCLDEncoder->pppiAlloc[n][k] ); + } + free( psLCLDEncoder->pppiAlloc[n] ); + } + free( psLCLDEncoder->pppiAlloc ); + } + + if ( psLCLDEncoder->pppiLCLDSignReal != NULL ) + { + for ( n = 0; n < psLCLDEncoder->iChannels; n++ ) + { + for ( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) + { + free( psLCLDEncoder->pppiLCLDSignReal[n][k] ); + } + free( psLCLDEncoder->pppiLCLDSignReal[n] ); + } + free( psLCLDEncoder->pppiLCLDSignReal ); + } + + if ( psLCLDEncoder->pppiLCLDSignImag != NULL ) + { + for ( n = 0; n < psLCLDEncoder->iChannels; n++ ) + { + for ( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) + { + free( psLCLDEncoder->pppiLCLDSignImag[n][k] ); + } + free( psLCLDEncoder->pppiLCLDSignImag[n] ); + } + free( psLCLDEncoder->pppiLCLDSignImag ); + } + + if ( psLCLDEncoder->pppiQLCLDReal != NULL ) + { + for ( n = 0; n < psLCLDEncoder->iChannels; n++ ) + { + for ( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) + { + free( psLCLDEncoder->pppiQLCLDReal[n][k] ); + } + free( psLCLDEncoder->pppiQLCLDReal[n] ); + } + free( psLCLDEncoder->pppiQLCLDReal ); + } + + if ( psLCLDEncoder->pppiQLCLDImag != NULL ) + { + for ( n = 0; n < psLCLDEncoder->iChannels; n++ ) + { + for ( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) + { + free( psLCLDEncoder->pppiQLCLDImag[n][k] ); + } + free( psLCLDEncoder->pppiQLCLDImag[n] ); + } + free( psLCLDEncoder->pppiQLCLDImag ); + } + + DeletePredictionEncoder( psLCLDEncoder->psPredictionEncoder ); + free( psLCLDEncoder ); + } + + return; +} + +/*------------------------------------------------------------------------------------------* + * 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, int32_t *piMSFlags ); + +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 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 int32_t WriteHeaderInformation( const int32_t iNumBands, IVAS_SPLIT_REND_BITS_HANDLE pBits ); + +static int32_t WritePmodInformation( const int32_t **ppiHiSMRFlags, IVAS_SPLIT_REND_BITS_HANDLE pBits, int32_t iChannels, int32_t iNumBands ); + +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, IVAS_SPLIT_REND_BITS_HANDLE pBits ); + +static int32_t WriteGroupInformation( const int32_t iChannels, const int32_t iCommonGrouping, const int32_t *piNumGroups, int32_t **ppiGroupLengths, IVAS_SPLIT_REND_BITS_HANDLE pBits ); + +static int32_t WriteRMSEnvelope( const int32_t iChannels, const int32_t *piNumGroups, const int32_t iNumBands, int32_t ***pppiRMSEnvelope, IVAS_SPLIT_REND_BITS_HANDLE pBits ); + +static int32_t WriteAllocInformation( const int32_t iAllocOffset, IVAS_SPLIT_REND_BITS_HANDLE pBits ); + +static int32_t WriteLCLDData( 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, IVAS_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, int32_t **ppiPredEnable, float **ppfA1Real, float **ppfA1Imag ); + + +/*------------------------------------------------------------------------------------------* + * Function EncodeLCLDFrame() + * + * + *------------------------------------------------------------------------------------------*/ + +int32_t EncodeLCLDFrame( + LCLDEncoder *psLCLDEncoder, + float ***pppfLCLDReal, + float ***pppfLCLDImag, + int32_t *piBitsWritten, + const int32_t available_bits, + IVAS_SPLIT_REND_BITS_HANDLE pBits ) +{ + int32_t n; + int32_t iAvailableBits, iBitsWritten; + int32_t iNumMSBands = 0; + iAvailableBits = available_bits; // HCBR for now + iBitsWritten = 0; + + /* Do MS calc here */ + if ( psLCLDEncoder->iChannels == 2 ) + { + iNumMSBands = MSModeCalculation( psLCLDEncoder->iNumBlocks, + psLCLDEncoder->iNumBands, + psLCLDEncoder->piBandwidths, + pppfLCLDReal, + pppfLCLDImag, + &psLCLDEncoder->iMSMode, + psLCLDEncoder->piLRPhaseDiffs, + psLCLDEncoder->piMSPredCoefs, + psLCLDEncoder->iAllowSidePred, + psLCLDEncoder->piMSFlags ); + + if ( psLCLDEncoder->iMSMode > 0 ) + { + psLCLDEncoder->iCommonGrouping = 1; // Make sure common grouping is enabled when MS is in use + } + } + +#ifdef ENABLE_PMOD_ADJUST + CalcTonQuotas( psLCLDEncoder->iChannels, psLCLDEncoder->iNumBands, psLCLDEncoder->piBandwidths, pppfLCLDReal, pppfLCLDImag, psLCLDEncoder->ppiHiSMRFlags ); +#endif + + /* Compute Grouping and RMS Envelopes */ + if ( psLCLDEncoder->iChannels == 2 && psLCLDEncoder->iCommonGrouping == 1 ) + { + ComputeEnvelopeGrouping( psLCLDEncoder->psRMSEnvelopeGrouping, + psLCLDEncoder->iChannels, + psLCLDEncoder->iNumBands, + psLCLDEncoder->piBandwidths, + pppfLCLDReal, + pppfLCLDImag, + &psLCLDEncoder->piNumGroups[0], + psLCLDEncoder->ppiGroupLengths[0], + psLCLDEncoder->pppiRMSEnvelope ); + + psLCLDEncoder->piNumGroups[1] = psLCLDEncoder->piNumGroups[0]; + for ( n = 0; n < psLCLDEncoder->piNumGroups[0]; n++ ) + { + psLCLDEncoder->ppiGroupLengths[1][n] = psLCLDEncoder->ppiGroupLengths[0][n]; + } + } + else + { + for ( n = 0; n < psLCLDEncoder->iChannels; n++ ) + { + ComputeEnvelopeGrouping( psLCLDEncoder->psRMSEnvelopeGrouping, + psLCLDEncoder->iChannels, + psLCLDEncoder->iNumBands, + psLCLDEncoder->piBandwidths, + &pppfLCLDReal[n], + &pppfLCLDImag[n], + &psLCLDEncoder->piNumGroups[n], + psLCLDEncoder->ppiGroupLengths[n], + &psLCLDEncoder->pppiRMSEnvelope[n] ); + } + } + + for ( n = 0; n < psLCLDEncoder->iChannels; n++ ) + { + RemoveRMSEnvelope( psLCLDEncoder->iNumBands, + psLCLDEncoder->piBandwidths, + psLCLDEncoder->piNumGroups[n], + (const int32_t *) psLCLDEncoder->ppiGroupLengths[n], + psLCLDEncoder->pppiRMSEnvelope[n], + pppfLCLDReal[n], + pppfLCLDImag[n] ); + } + + ComputePredictors( psLCLDEncoder->psPredictionEncoder, pppfLCLDReal, pppfLCLDImag ); + + iBitsWritten += WriteHeaderInformation( psLCLDEncoder->iNumBands, pBits ); + + if ( 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 += WritePredictors( psLCLDEncoder->psPredictionEncoder, pBits ); + + iBitsWritten += WriteGroupInformation( psLCLDEncoder->iChannels, psLCLDEncoder->iCommonGrouping, (const int32_t *) psLCLDEncoder->piNumGroups, psLCLDEncoder->ppiGroupLengths, pBits ); + + iBitsWritten += WriteRMSEnvelope( psLCLDEncoder->iChannels, (const int32_t *) psLCLDEncoder->piNumGroups, psLCLDEncoder->iNumBands, psLCLDEncoder->pppiRMSEnvelope, pBits ); + +#ifdef ENABLE_PMOD_ADJUST + iBitsWritten += WritePmodInformation( psLCLDEncoder->ppiHiSMRFlags, + pBits, + psLCLDEncoder->iChannels, + psLCLDEncoder->iNumBands ); +#endif + + if ( psLCLDEncoder->iChannels == 2 && psLCLDEncoder->iCommonGrouping == 1 ) + { + int32_t 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] ); + } + } + else + { + for ( n = 0; n < psLCLDEncoder->iChannels; n++ ) + { + int32_t k; + for ( k = 0; k < psLCLDEncoder->piNumGroups[n]; k++ ) + { + PerceptualModel( psLCLDEncoder->iNumBands, + psLCLDEncoder->pppiRMSEnvelope[n][k], + psLCLDEncoder->pppiExcitation[n][k], + psLCLDEncoder->pppiSMR[n][k] ); + } + } + } + + iAvailableBits -= iBitsWritten; + ComputeAllocation( psLCLDEncoder->iChannels, + (const int32_t *) psLCLDEncoder->piNumGroups, + psLCLDEncoder->ppiGroupLengths, + psLCLDEncoder->iNumBands, + psLCLDEncoder->piBandwidths, + pppfLCLDReal, + pppfLCLDImag, + psLCLDEncoder->pppiSMR, + iAvailableBits, + &psLCLDEncoder->iAllocOffset, + psLCLDEncoder->pppiAlloc, + psLCLDEncoder->pppiQLCLDReal, + psLCLDEncoder->pppiQLCLDImag, + psLCLDEncoder->pppiLCLDSignReal, + psLCLDEncoder->pppiLCLDSignImag, + psLCLDEncoder->psPredictionEncoder->ppiPredBandEnable, + psLCLDEncoder->psPredictionEncoder->ppfA1Real, + psLCLDEncoder->psPredictionEncoder->ppfA1Imag ); + + iBitsWritten += WriteAllocInformation( psLCLDEncoder->iAllocOffset, + pBits ); + + for ( n = 0; n < psLCLDEncoder->iChannels; n++ ) + { + iBitsWritten += WriteLCLDData( psLCLDEncoder->piNumGroups[n], + (const int32_t *) psLCLDEncoder->ppiGroupLengths[n], + psLCLDEncoder->iNumBands, + psLCLDEncoder->piBandwidths, + (const int32_t *) psLCLDEncoder->psPredictionEncoder->ppiPredBandEnable[n], + psLCLDEncoder->pppiAlloc[n], + psLCLDEncoder->pppiLCLDSignReal[n], + psLCLDEncoder->pppiLCLDSignImag[n], + psLCLDEncoder->pppiQLCLDReal[n], + psLCLDEncoder->pppiQLCLDImag[n], + pBits ); + } + *piBitsWritten = iBitsWritten; + + return 0; +} + + +/*------------------------------------------------------------------------------------------* + * Function GetNumGroups() + * + * + *------------------------------------------------------------------------------------------*/ + +int32_t GetNumGroups( LCLDEncoder *psLCLDEncoder ) +{ + return psLCLDEncoder->piNumGroups[0]; +} + + +/*------------------------------------------------------------------------------------------* + * Local functions + * + * + *------------------------------------------------------------------------------------------*/ + +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, + int32_t *piMSFlags ) +{ + int32_t b; + int32_t iFBOffset; + int32_t iNumMSBands; + int32_t piMSPredFlags[MAX_BANDS]; + int32_t iNumMSPredBands = 0; + float msBitsReduction = 0.0f; + float msPredBitsReduction = 0.0f; + int32_t msBits; + int32_t msPredBits; + float fPred; +#if defined SIMPLE_PHASE + void( *pFuncPhaseRotateOptions[4] ) = { &rot_zero, &rot_p_pi_2, &rot_pm_pi, &rot_m_pi_2 }; +#endif + const float one_by_log10_2 = 3.32192809488736f; + + set_l( piMSPredFlags, 0, MAX_BANDS ); + *piMSMode = 0; + iFBOffset = 0; + iNumMSBands = 0; + for ( b = 0; b < iNumBands; b++ ) + { + int32_t n; + float fLeftEnergy; + float fRightEnergy; + float fMidEnergy; + float fSideEnergy; + float fLRRatio; + float fMSRatio; + float fMSPredRatio; + float fMidEnergyPred; + float fSideEnergyPred; + float fLRCovReal = 0.0f; + float fLRCovImag = 0.0f; + int32_t iPhase; + int32_t iPred; + int32_t tabIdx = 0; + + fLeftEnergy = 0.0f; + fRightEnergy = 0.0f; + fMidEnergy = 0.0; + fSideEnergy = 0.0; + + for ( n = 0; n < piBandwidths[b]; n++ ) + { + int32_t k; + for ( k = 0; k < iNumBlocks; k++ ) + { + 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] ); + } + + iFBOffset++; + } + + /* compute L/R phase difference if high coherence */ + if ( fLRCovReal * fLRCovReal + fLRCovImag * fLRCovImag > 0.5f * fLeftEnergy * fRightEnergy ) + { + float fPhase = (float) atan2( fLRCovImag, fLRCovReal ); // ToDo: replace by atan2f() + iPhase = quantPhase( fPhase ); + } + else + { + iPhase = 0; + } + piLRPhaseDiffs[b] = iPhase; + + /* adjust covariance based on phase rotation */ +#ifdef SIMPLE_PHASE + cplxmult( &fLRCovReal, &fLRCovImag, c_afRotRealImagSimple[iPhase][0], -c_afRotRealImagSimple[iPhase][1] ); +#else + tabIdx = iPhase - PHASE_MIN_VAL; + cplxmult( &fLRCovReal, &fLRCovImag, c_afRotRealImag[tabIdx][0], -c_afRotRealImag[tabIdx][1] ); +#endif + /* compute MS prediction coefficient based on LR covariance*/ + fMidEnergyPred = 0.25f * ( fLeftEnergy + fRightEnergy + 2.0f * fLRCovReal ); + fSideEnergyPred = 0.25f * ( fLeftEnergy + fRightEnergy - 2.0f * fLRCovReal ); + + /* M/S prediction */ + fPred = fMidEnergyPred == 0.0f ? 0.0f : 0.25f * ( fLeftEnergy - fRightEnergy ) / fMidEnergyPred; + iPred = quantPred( fPred ); + fPred = dequantPred( iPred ); + piMSPredCoefs[b] = iPred; + + /* evaluation */ + fSideEnergyPred += ( fPred * fPred * fMidEnergyPred - 2.0f * fPred * 0.25f * ( fLeftEnergy - fRightEnergy ) ); + /* -= fPred * fPred * fMidEnergyPred doesn't work because fPred is quantized and does not match MS/MM exactly */ + fMSPredRatio = log10f( ( fMidEnergyPred + 1e-12f ) / ( fSideEnergyPred + 1e-12f ) ); + + fLeftEnergy = log10f( fLeftEnergy + 1e-12f ); + fRightEnergy = log10f( fRightEnergy + 1e-12f ); + fMidEnergy = log10f( fMidEnergy + 1e-12f ); + fSideEnergy = log10f( fSideEnergy + 1e-12f ); + + if ( fLeftEnergy > fRightEnergy ) + { + fLRRatio = fLeftEnergy - fRightEnergy; + } + else + { + fLRRatio = fRightEnergy - fLeftEnergy; + } + + if ( fMidEnergy > fSideEnergy ) + { + fMSRatio = fMidEnergy - fSideEnergy; + } + else + { + fMSRatio = fSideEnergy - fMidEnergy; + } + + if ( fMSRatio > fLRRatio ) + { + iNumMSBands++; + piMSFlags[b] = 1; + } + else + { + piMSFlags[b] = 0; + } + + if ( fMSRatio > fLRRatio ) + { + float maskThresShift_dB_by_10 = ( fMSRatio - fLRRatio ) * (float) c_aiDefaultTheta48[b] / 16.0f; + msBitsReduction += (float) ( piBandwidths[b] * iNumBlocks * 2 ) * one_by_log10_2 * maskThresShift_dB_by_10; /* * 2 for real/imag */ + } + + if ( fMSPredRatio > fLRRatio ) + { + float maskThresShift_dB_by_10 = ( fMSPredRatio - fLRRatio ) * (float) c_aiDefaultTheta48[b] / 16.0f; + msPredBitsReduction += (float) ( piBandwidths[b] * iNumBlocks * 2 ) * one_by_log10_2 * maskThresShift_dB_by_10; + iNumMSPredBands++; + piMSPredFlags[b] = 1; + } + else + { + piMSPredFlags[b] = 0; + } + } + + msPredBits = CountMSBits( iNumBands, 3, piMSPredFlags, piLRPhaseDiffs, piMSPredCoefs ); + msPredBitsReduction = max( msPredBitsReduction - (float) msPredBits, 0.0f ); + msBits = CountMSBits( iNumBands, 2, piMSFlags, NULL, NULL ); + msBitsReduction = max( msBitsReduction - (float) msBits, 0.0f ); +#ifdef DEBUG_WRITE_MS_PRED + { + static FILE *fid = 0; + if ( !fid ) + { + fid = fopen( "bit_red.txt", "wt" ); + } + fprintf( fid, "%.1f %.1f %d %d\n", msBitsReduction, msPredBitsReduction, msBits, msPredBits ); + } +#endif + + if ( iAllowSidePred && msPredBitsReduction > 1.1f * msBitsReduction ) + { + *piMSMode = 3; + for ( b = 0; b < iNumBands; b++ ) + { + piMSFlags[b] = piMSPredFlags[b]; + } + iNumMSBands = iNumMSPredBands; + } + else if ( iNumMSBands == iNumBands ) + { + *piMSMode = 1; + } + else if ( iNumMSBands > 0 ) + { + *piMSMode = 2; + } + else + { + *piMSMode = 0; + } + + if ( *piMSMode > 0 ) + { + iFBOffset = 0; + for ( b = 0; b < iNumBands; b++ ) + { +#if defined SIMPLE_PHASE + void ( *pFuncPhaseRotate )( float *, float * ) = pFuncPhaseRotateOptions[piLRPhaseDiffs[b]]; +#endif + if ( piMSFlags[b] == 1 ) + { + int32_t n; + for ( n = 0; n < piBandwidths[b]; n++ ) + { + int32_t k; + for ( k = 0; k < iNumBlocks; k++ ) + { + float fMidReal; + float fMidImag; + float fSideReal; + float fSideImag; + + if ( *piMSMode == 3 ) + { +#ifdef SIMPLE_PHASE + ( *pFuncPhaseRotate )( &pppfReal[1][k][iFBOffset], &pppfImag[1][k][iFBOffset] ); +#else + int32_t phaseIdx; + + phaseIdx = piLRPhaseDiffs[b] - PHASE_MIN_VAL; + cplxmult( &pppfReal[1][k][iFBOffset], &pppfImag[1][k][iFBOffset], c_afRotRealImag[phaseIdx][0], c_afRotRealImag[phaseIdx][1] ); +#endif + } + + 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] ); + + if ( *piMSMode == 3 ) + { + fPred = dequantPred( piMSPredCoefs[b] ); + fSideReal -= fPred * fMidReal; + fSideImag -= fPred * fMidImag; + } + + pppfReal[0][k][iFBOffset] = fMidReal; + pppfReal[1][k][iFBOffset] = fSideReal; + pppfImag[0][k][iFBOffset] = fMidImag; + pppfImag[1][k][iFBOffset] = fSideImag; + } + iFBOffset++; + } + } + else + { + iFBOffset += piBandwidths[b]; + } + } + } + +#ifdef DEBUG_WRITE_MS_PRED + { + static FILE *fid = 0; + if ( !fid ) + { + fid = fopen( "ms_mode_enc_raw.txt", "wt" ); + } + writeMSPred( piLRPhaseDiffs, piMSPredCoefs, *piMSMode, iNumBands, iNumBands, fid, piMSFlags ); + } +#endif + if ( *piMSMode == 3 ) + { + /* Differential Coding of Phase Data*/ + PrepEncode( piLRPhaseDiffs, piMSFlags, iNumBands ); + PrepEncode( piMSPredCoefs, piMSFlags, iNumBands ); +#ifdef DEBUG_WRITE_MS_PRED + { + static FILE *fid = 0; + if ( !fid ) + { + fid = fopen( "ms_mode_enc.txt", "wt" ); + } + writeMSPred( piLRPhaseDiffs, piMSPredCoefs, *piMSMode, iNumMSBands, iNumBands, fid, piMSFlags ); + } +#endif + /* Differential Coding*/ +#ifndef SIMPLE_PHASE + EncodePhase( piLRPhaseDiffs, iNumMSBands, PHASE_DIFF_DIM ); +#endif + EncodePredCoef( piMSPredCoefs, iNumMSBands ); +#ifdef DEBUG_WRITE_MS_PRED + { + static FILE *fid = 0; + if ( !fid ) + { + fid = fopen( "ms_mode_enc_diff.txt", "wt" ); + } + writeMSPred( piLRPhaseDiffs, piMSPredCoefs, *piMSMode, iNumMSBands, iNumBands, fid, piMSFlags ); + } +#endif + } + + 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 ) +{ + int32_t k, n, b, iFBOffset, m, iRMSEnv; + int32_t iBlockOffset; + float fGain; + + iBlockOffset = 0; + for ( n = 0; n < iNumGroups; n++ ) + { + for ( k = 0; k < piGroupLengths[n]; k++ ) + { + iFBOffset = 0; + 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++ ) + { + ppfReal[iBlockOffset][iFBOffset] *= fGain; + ppfImag[iBlockOffset][iFBOffset] *= fGain; + iFBOffset++; + } + } + iBlockOffset++; + } + } + + 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, + int32_t *piPredEnable, + float *pfA1Real, + float *pfA1Imag ) /* Pass in 2 previous value buffers NULLABLE */ +{ + int32_t b, m, n, iBlockOffset; + float fVal, fPrevReal, fPrevImag, fPredReal, fPredImag; + int32_t iFBOffset; + int32_t k, iAlloc, iQuantValue, iMaxQuantVal; + float fSCFGain, fInvSCFGain; + + iFBOffset = 0; + for ( b = 0; b < iNumBands; b++ ) + { + for ( m = 0; m < piBandwidths[b]; m++ ) + { + iBlockOffset = 0; + fPrevReal = 0.0; + fPrevImag = 0.0; + for ( n = 0; n < iNumGroups; n++ ) + { + iAlloc = ppiAlloc[n][b]; + iMaxQuantVal = c_aiQuantMaxValues[iAlloc]; + fSCFGain = c_afScaleFactor[iAlloc]; + fInvSCFGain = c_afInvScaleFactor[iAlloc]; + + if ( piPredEnable[iFBOffset] == 1 ) + { + for ( k = 0; k < piGroupLengths[n]; k++ ) + { + fPredReal = 0.0; + fPredImag = 0.0; + + fPredReal = pfA1Real[iFBOffset] * fPrevReal - pfA1Imag[iFBOffset] * fPrevImag; + fPredImag = pfA1Real[iFBOffset] * fPrevImag + pfA1Imag[iFBOffset] * fPrevReal; + + fVal = ppfReal[iBlockOffset][iFBOffset] + fPredReal; + if ( fVal > 0.0 ) + { + iQuantValue = (int32_t) ( fSCFGain * fVal + 0.5 ); + ppiSignReal[iBlockOffset][iFBOffset] = 0; + } + else + { + iQuantValue = (int32_t) ( -fSCFGain * fVal + 0.5 ); + ppiSignReal[iBlockOffset][iFBOffset] = 1; + } + iQuantValue = ( iQuantValue < iMaxQuantVal ) ? iQuantValue : iMaxQuantVal; + + ppiQReal[iBlockOffset][iFBOffset] = iQuantValue; + + fVal = ppfImag[iBlockOffset][iFBOffset] + fPredImag; + if ( fVal > 0.0 ) + { + iQuantValue = (int32_t) ( fSCFGain * fVal + 0.5 ); + ppiSignImag[iBlockOffset][iFBOffset] = 0; + } + else + { + iQuantValue = (int32_t) ( -fSCFGain * fVal + 0.5 ); + ppiSignImag[iBlockOffset][iFBOffset] = 1; + } + + iQuantValue = ( iQuantValue < iMaxQuantVal ) ? iQuantValue : iMaxQuantVal; + ppiQImag[iBlockOffset][iFBOffset] = iQuantValue; + + + if ( ppiSignReal[iBlockOffset][iFBOffset] == 0 ) + { + fPrevReal = fInvSCFGain * (float) ppiQReal[iBlockOffset][iFBOffset] - fPredReal; + } + else + { + fPrevReal = -fInvSCFGain * (float) ppiQReal[iBlockOffset][iFBOffset] - fPredReal; + } + if ( ppiSignImag[iBlockOffset][iFBOffset] == 0 ) + { + fPrevImag = fInvSCFGain * (float) ppiQImag[iBlockOffset][iFBOffset] - fPredImag; + } + else + { + fPrevImag = -fInvSCFGain * (float) ppiQImag[iBlockOffset][iFBOffset] - fPredImag; + } + + iBlockOffset++; + } + } + else + { + for ( k = 0; k < piGroupLengths[n]; k++ ) + { + fVal = ppfReal[iBlockOffset][iFBOffset]; + if ( fVal > 0.0 ) + { + iQuantValue = (int32_t) ( fSCFGain * fVal + 0.5 ); + ppiSignReal[iBlockOffset][iFBOffset] = 0; + } + else + { + iQuantValue = (int32_t) ( -fSCFGain * fVal + 0.5 ); + ppiSignReal[iBlockOffset][iFBOffset] = 1; + } + iQuantValue = ( iQuantValue < iMaxQuantVal ) ? iQuantValue : iMaxQuantVal; + + ppiQReal[iBlockOffset][iFBOffset] = iQuantValue; + + fVal = ppfImag[iBlockOffset][iFBOffset]; + if ( fVal > 0.0 ) + { + iQuantValue = (int32_t) ( fSCFGain * fVal + 0.5 ); + ppiSignImag[iBlockOffset][iFBOffset] = 0; + } + else + { + iQuantValue = (int32_t) ( -fSCFGain * fVal + 0.5 ); + ppiSignImag[iBlockOffset][iFBOffset] = 1; + } + iQuantValue = ( iQuantValue < iMaxQuantVal ) ? iQuantValue : iMaxQuantVal; + ppiQImag[iBlockOffset][iFBOffset] = iQuantValue; + iBlockOffset++; + } + } + } + + iFBOffset++; + } + } + + return; +} + + +static void QuantizeSpectrumDPCM( + 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, + int32_t *piPredEnable, + float *pfA1Real, + float *pfA1Imag ) /* Pass in 2 previous value buffers NULLABLE */ +{ + int32_t b, m, n, iBlockOffset; + float fVal, fPrevReal, fPrevImag, fPredReal, fPredImag; + int32_t iFBOffset; + int32_t k, iAlloc, iQuantValue, iMaxQuantVal; + float fSCFGain, fInvSCFGain; + + iFBOffset = 0; + for ( b = 0; b < iNumBands; b++ ) + { + for ( m = 0; m < piBandwidths[b]; m++ ) + { + iBlockOffset = 0; + fPrevReal = 0.0; + fPrevImag = 0.0; + 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++ ) + { + fPredReal = 0.0; + fPredImag = 0.0; + + if ( piPredEnable[iFBOffset] == 1 ) + { + fPredReal = pfA1Real[iFBOffset] * fPrevReal - pfA1Imag[iFBOffset] * fPrevImag; + fPredImag = pfA1Real[iFBOffset] * fPrevImag + pfA1Imag[iFBOffset] * fPrevReal; + } + else + { // don't need + fPredReal = 0.0; + fPredImag = 0.0; + } + + fVal = ppfReal[iBlockOffset][iFBOffset] + fPredReal; + if ( fVal > 0.0 ) + { + iQuantValue = (int32_t) ( fSCFGain * fVal + 0.5 ); + ppiSignReal[iBlockOffset][iFBOffset] = 0; + } + else + { + iQuantValue = (int32_t) ( -fSCFGain * fVal + 0.5 ); + ppiSignReal[iBlockOffset][iFBOffset] = 1; + } +#ifdef _DEBUG_VERBOSE + if ( iQuantValue > iMaxQuantVal ) + { + printf( "Value out of range %d\t%d\t%d\t%d\n", b, iAlloc, iQuantValue, iMaxQuantVal ); + iQuantValue = iMaxQuantVal; + } +#else + iQuantValue = ( iQuantValue < iMaxQuantVal ) ? iQuantValue : iMaxQuantVal; +#endif + + ppiQReal[iBlockOffset][iFBOffset] = iQuantValue; + + fVal = ppfImag[iBlockOffset][iFBOffset] + fPredImag; + if ( fVal > 0.0 ) + { + iQuantValue = (int32_t) ( fSCFGain * fVal + 0.5 ); + ppiSignImag[iBlockOffset][iFBOffset] = 0; + } + else + { + iQuantValue = (int32_t) ( -fSCFGain * fVal + 0.5 ); + ppiSignImag[iBlockOffset][iFBOffset] = 1; + } + +#ifdef _DEBUG_VERBOSE + if ( iQuantValue > iMaxQuantVal ) + { + printf( "Value out of range %d\t%d\t%d\t%d\n", b, iAlloc, iQuantValue, iMaxQuantVal ); + iQuantValue = iMaxQuantVal; + } +#else + iQuantValue = ( iQuantValue < iMaxQuantVal ) ? iQuantValue : iMaxQuantVal; +#endif + ppiQImag[iBlockOffset][iFBOffset] = iQuantValue; + + if ( piPredEnable[iFBOffset] == 1 ) + { + if ( ppiSignReal[iBlockOffset][iFBOffset] == 0 ) + { + fPrevReal = fInvSCFGain * (float) ppiQReal[iBlockOffset][iFBOffset] - fPredReal; + } + else + { + fPrevReal = -fInvSCFGain * (float) ppiQReal[iBlockOffset][iFBOffset] - fPredReal; + } + if ( ppiSignImag[iBlockOffset][iFBOffset] == 0 ) + { + fPrevImag = fInvSCFGain * (float) ppiQImag[iBlockOffset][iFBOffset] - fPredImag; + } + else + { + fPrevImag = -fInvSCFGain * (float) ppiQImag[iBlockOffset][iFBOffset] - fPredImag; + } + } + else + { + fPrevReal = 0.0; + fPrevImag = 0.0; + } + + iBlockOffset++; + } + } + + iFBOffset++; + } + } + + return; +} + + +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 ) +{ + int32_t k, n, b, iFBOffset; + int32_t iBits, iBlockOffest; + int32_t m, iAlloc, iHuffDim, iHuffMod; + + iBits = 0; + iBlockOffest = 0; + for ( n = 0; n < iNumGroups; n++ ) + { + for ( k = 0; k < piGroupLengths[n]; k++ ) + { + iFBOffset = 0; + for ( b = 0; b < iNumBands; b++ ) + { + iAlloc = ppiAlloc[n][b]; + + iHuffDim = c_aiHuffmanDim[iAlloc]; + iHuffMod = c_aiHuffmanMod[iAlloc]; + + if ( iAlloc > 0 ) + { + const uint16_t( *pauiHuffmanTable )[2] = NULL; + const uint16_t( *pauiHuffmanTableDPCM )[2] = NULL; + pauiHuffmanTable = c_apauiHuffEncTabels[iAlloc]; + pauiHuffmanTableDPCM = c_apauiHuffEncTabels[ALLOC_TABLE_SIZE + iAlloc]; + for ( m = 0; m < piBandwidths[b]; m++ ) + { + int32_t iQuantValue1; + int32_t iQuantValue2; + + iQuantValue1 = ppiQReal[iBlockOffest][iFBOffset]; + iQuantValue2 = ppiQImag[iBlockOffest][iFBOffset]; + + iBits += ( iQuantValue1 > 0 ) ? 1 : 0; /* Sign bit for vals > 0 */ + iBits += ( iQuantValue2 > 0 ) ? 1 : 0; /* Sign bit for vals > 0 */ + + if ( piPredEnable[iFBOffset] == 1 ) + { + if ( iHuffDim == 2 ) + { + iQuantValue1 *= iHuffMod; + iQuantValue1 += iQuantValue2; + iBits += pauiHuffmanTableDPCM[iQuantValue1][0]; + } + else + { + iBits += pauiHuffmanTableDPCM[iQuantValue1][0]; + iBits += pauiHuffmanTableDPCM[iQuantValue2][0]; + } + } + else + { + if ( iHuffDim == 2 ) + { + iQuantValue1 *= iHuffMod; + iQuantValue1 += iQuantValue2; + iBits += pauiHuffmanTable[iQuantValue1][0]; + } + else + { + iBits += pauiHuffmanTable[iQuantValue1][0]; + iBits += pauiHuffmanTable[iQuantValue2][0]; + } + } + + iFBOffset++; + } + } + else + { + iFBOffset += piBandwidths[b]; + } + } + + iBlockOffest++; + } + } + + return iBits; +} + + +/* Currently only the number of bands in frame */ +static int32_t WriteHeaderInformation( + const int32_t iNumBands, + IVAS_SPLIT_REND_BITS_HANDLE pBits ) +{ + int32_t iBitsWritten; + + iBitsWritten = 0; + ivas_split_rend_bitstream_write_int32( pBits, iNumBands, 5 ); + 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, + IVAS_SPLIT_REND_BITS_HANDLE pBits ) +{ + int32_t iBitsWritten; + int32_t iMSPredAll = ( iNumMSPredBands == iNumBands ); +#ifdef DEBUG_WRITE_MS_PRED + int32_t iBitsWrittenTmp = 0; +#endif + iBitsWritten = 0; + ivas_split_rend_bitstream_write_int32( pBits, iMSMode, 2 ); + iBitsWritten += 2; + + if ( iMSMode == 3 ) + { + ivas_split_rend_bitstream_write_int32( pBits, iMSPredAll, 1 ); + iBitsWritten += 1; + } + + if ( iMSMode == 2 || ( iMSMode == 3 && !iMSPredAll ) ) + { + int32_t n; + for ( n = 0; n < iNumBands; n++ ) + { + ivas_split_rend_bitstream_write_int32( pBits, piMSFlags[n], 1 ); + iBitsWritten += 1; + } + } + +#ifdef DEBUG_WRITE_MS_PRED + iBitsWrittenTmp = iBitsWritten; +#endif + if ( iMSMode == 3 ) + { + int32_t b; + int32_t anyNonZero; + anyNonZero = 0; + for ( b = 0; b < iNumMSPredBands; b++ ) + { + if ( piLRPhaseDiff[b] != 0 ) + { + anyNonZero = 1; + break; + } + } + ivas_split_rend_bitstream_write_int32( pBits, anyNonZero, 1 ); + iBitsWritten++; + + if ( anyNonZero ) + { +#ifdef SIMPLE_PHASE + for ( b = 0; b < iNumMSPredBands; b++ ) + { + ivas_split_rend_bitstream_write_int32( pBits, piLRPhaseDiff[b], SIMPLE_PHASE_BITS ); + iBitsWritten += SIMPLE_PHASE_BITS; + } +#else + ivas_split_rend_bitstream_write_int32( pBits, piLRPhaseDiff[0] - PHASE_MIN_VAL, PHASE_BAND0_BITS ); + iBitsWritten += PHASE_BAND0_BITS; + for ( b = 1; b < iNumMSPredBands; b++ ) + { + int32_t tabIdx = piLRPhaseDiff[b] - ENV_DELTA_MIN; + ivas_split_rend_bitstream_write_int32( pBits, c_aaiRMSEnvHuffEnc[tabIdx][1], c_aaiRMSEnvHuffEnc[tabIdx][0] ); + iBitsWritten += c_aaiRMSEnvHuffEnc[tabIdx][0]; + } +#endif + } + + anyNonZero = 0; + for ( b = 0; b < iNumMSPredBands; b++ ) + { + if ( piMSPredCoef[b] != 0 ) + { + anyNonZero = 1; + break; + } + } + + ivas_split_rend_bitstream_write_int32( pBits, anyNonZero, 1 ); + iBitsWritten++; + + if ( anyNonZero ) + { + ivas_split_rend_bitstream_write_int32( pBits, piMSPredCoef[0] - PRED_MIN_VAL, PRED_BAND0_BITS ); + iBitsWritten += PRED_BAND0_BITS; + for ( b = 1; b < iNumMSPredBands; b++ ) + { + int32_t tabIdx = piMSPredCoef[b] - ENV_DELTA_MIN; + ivas_split_rend_bitstream_write_int32( pBits, c_aaiRMSEnvHuffEnc[tabIdx][1], c_aaiRMSEnvHuffEnc[tabIdx][0] ); + iBitsWritten += c_aaiRMSEnvHuffEnc[tabIdx][0]; + } + } + } +#ifdef DEBUG_WRITE_MS_PRED + { + static FILE *fid = 0; + if ( !fid ) + { + fid = fopen( "ms_pred_bitrate.txt", "wt" ); + } + fprintf( fid, "%f\n", (float) ( ( iBitsWritten - iBitsWrittenTmp ) * ( iMSMode == 3 ) * 50 ) / 1000.0f ); /*kb/s*/ + } +#endif + + return iBitsWritten; +} + + +static int32_t WriteGroupInformation( + const int32_t iChannels, + const int32_t iCommonGrouping, + const int32_t *piNumGroups, + int32_t **ppiGroupLengths, + IVAS_SPLIT_REND_BITS_HANDLE pBits ) +{ + int32_t c, k, n, iBitsWritten; + + iBitsWritten = 0; + if ( iChannels == 2 && iCommonGrouping == 1 ) + { + ivas_split_rend_bitstream_write_int32( pBits, iCommonGrouping, 1 ); + iBitsWritten += 1; + + for ( n = 0; n < piNumGroups[0]; n++ ) + { + for ( k = 1; k < ppiGroupLengths[0][n]; k++ ) + { + ivas_split_rend_bitstream_write_int32( pBits, 0, 1 ); + iBitsWritten += 1; + } + if ( n < ( piNumGroups[0] - 1 ) ) + { + ivas_split_rend_bitstream_write_int32( pBits, 1, 1 ); + iBitsWritten += 1; + } + } + } + else if ( iChannels == 2 ) + { + ivas_split_rend_bitstream_write_int32( pBits, iCommonGrouping, 1 ); + iBitsWritten += 1; + + for ( c = 0; c < iChannels; c++ ) + { + for ( n = 0; n < piNumGroups[c]; n++ ) + { + for ( k = 1; k < ppiGroupLengths[c][n]; k++ ) + { + ivas_split_rend_bitstream_write_int32( pBits, 0, 1 ); + iBitsWritten += 1; + } + if ( n < ( piNumGroups[c] - 1 ) ) + { + ivas_split_rend_bitstream_write_int32( pBits, 1, 1 ); + iBitsWritten += 1; + } + } + } + } + else + { + for ( c = 0; c < iChannels; c++ ) + { + for ( n = 0; n < piNumGroups[c]; n++ ) + { + for ( k = 1; k < ppiGroupLengths[c][n]; k++ ) + { + ivas_split_rend_bitstream_write_int32( pBits, 0, 1 ); + iBitsWritten += 1; + } + + if ( n < ( piNumGroups[c] - 1 ) ) + { + ivas_split_rend_bitstream_write_int32( pBits, 1, 1 ); + iBitsWritten += 1; + } + } + } + } + + return iBitsWritten; +} + + +static int32_t WriteRMSEnvelope( + const int32_t iChannels, + const int32_t *piNumGroups, + const int32_t iNumBands, + int32_t ***pppiRMSEnvelope, + IVAS_SPLIT_REND_BITS_HANDLE pBits ) +{ + int32_t k, n; + int32_t iBitsWritten; + + iBitsWritten = 0; + for ( n = 0; n < iChannels; n++ ) + { + for ( k = 0; k < piNumGroups[n]; k++ ) + { + int32_t b; + int32_t iLastRMSVal; + + iLastRMSVal = pppiRMSEnvelope[n][k][0]; + iLastRMSVal = ( iLastRMSVal > ENV_MIN ) ? iLastRMSVal : ENV_MIN; + iLastRMSVal = ( iLastRMSVal < ENV_MAX ) ? iLastRMSVal : ENV_MAX; + ivas_split_rend_bitstream_write_int32( pBits, ( iLastRMSVal - ENV_MIN ), ENV0_BITS ); + 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; + ivas_split_rend_bitstream_write_int32( pBits, c_aaiRMSEnvHuffEnc[iDelta][1], c_aaiRMSEnvHuffEnc[iDelta][0] ); + iBitsWritten += c_aaiRMSEnvHuffEnc[iDelta][0]; + + iLastRMSVal = pppiRMSEnvelope[n][k][b]; + } + } + } + + return iBitsWritten; +} + + +#ifdef ENABLE_PMOD_ADJUST +static int32_t WritePmodInformation( + const int32_t **ppiHiSMRFlags, + IVAS_SPLIT_REND_BITS_HANDLE pBits, + int32_t iChannels, + int32_t iNumBands ) +{ + int32_t iBitsWritten, c, b; + + iBitsWritten = 0; + + for ( c = 0; c < iChannels; c++ ) + { + int32_t anyNonZero = 0; + const int32_t *flags = ppiHiSMRFlags[c]; + for ( b = 0; b < iNumBands; b++ ) + { + if ( flags[b] ) + { + anyNonZero = 1; + break; + } + } + ivas_split_rend_bitstream_write_int32( pBits, anyNonZero, 1 ); + iBitsWritten += 1; + if ( anyNonZero ) + { + for ( b = 0; b < iNumBands; b++ ) + { + ivas_split_rend_bitstream_write_int32( pBits, flags[b], 1 ); + iBitsWritten += 1; + } + } + } +#ifdef WRITE_HISMR_FLAGS + { + static FILE *fid = 0; + if ( !fid ) + { + fid = fopen( "hismr_enc.txt", "wt" ); + } + for ( c = 0; c < iChannels; c++ ) + { + int32_t b; + for ( b = 0; b < iNumBands; b++ ) + { + if ( c == iChannels - 1 && b == iNumBands - 1 ) + { + fprintf( fid, "%d\n", ppiHiSMRFlags[c][b] ); + } + else + { + fprintf( fid, "%d ", ppiHiSMRFlags[c][b] ); + } + } + } + } +#endif + + return iBitsWritten; +} +#endif + + +static int32_t WriteAllocInformation( + const int32_t iAllocOffset, + IVAS_SPLIT_REND_BITS_HANDLE pBits ) +{ + int32_t iBitsWritten; + + iBitsWritten = 0; + + if ( iAllocOffset < MIN_ALLOC_OFFSET || iAllocOffset > MAX_ALLOC_OFFSET ) + { + printf( "Serious error\n" ); + } + + ivas_split_rend_bitstream_write_int32( pBits, ( iAllocOffset - MIN_ALLOC_OFFSET ), ALLOC_OFFSET_BITS ); + iBitsWritten += ALLOC_OFFSET_BITS; + + return iBitsWritten; +} + + +static int32_t WriteLCLDData( + 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, + IVAS_SPLIT_REND_BITS_HANDLE pBits ) +{ + int32_t n; + int32_t iBitsWritten; + int32_t iBlockOffest; + + iBitsWritten = 0; + iBlockOffest = 0; + + for ( n = 0; n < iNumGroups; n++ ) + { + int32_t k; + for ( k = 0; k < piGroupLengths[n]; k++ ) + { + int32_t b; + int32_t iFBOffset; + + iFBOffset = 0; + for ( b = 0; b < iNumBands; b++ ) + { + int32_t m; + int32_t iAlloc; + int32_t iHuffDim; + int32_t iHuffMod; + + iAlloc = ppiAlloc[n][b]; + + iHuffDim = c_aiHuffmanDim[iAlloc]; + iHuffMod = c_aiHuffmanMod[iAlloc]; + + if ( iAlloc > 0 ) + { + const uint16_t( *pauiHuffmanTable )[2] = NULL; + const uint16_t( *pauiHuffmanTableDPCM )[2] = NULL; + pauiHuffmanTable = c_apauiHuffEncTabels[iAlloc]; + pauiHuffmanTableDPCM = c_apauiHuffEncTabels[ALLOC_TABLE_SIZE + iAlloc]; + for ( m = 0; m < piBandwidths[b]; m++ ) + { + int32_t iQuantValue1; + int32_t iQuantValue2; + + iQuantValue1 = ppiQReal[iBlockOffest][iFBOffset]; + iQuantValue2 = ppiQImag[iBlockOffest][iFBOffset]; + + if ( piPredEnable[iFBOffset] == 1 ) + { + if ( iHuffDim == 2 ) + { + int32_t iSymbol; + iSymbol = iQuantValue1; + iSymbol *= iHuffMod; + iSymbol += iQuantValue2; + ivas_split_rend_bitstream_write_int32( pBits, pauiHuffmanTableDPCM[iSymbol][1], pauiHuffmanTableDPCM[iSymbol][0] ); + iBitsWritten += pauiHuffmanTableDPCM[iSymbol][0]; + } + else + { + ivas_split_rend_bitstream_write_int32( pBits, pauiHuffmanTableDPCM[iQuantValue1][1], pauiHuffmanTableDPCM[iQuantValue1][0] ); + iBitsWritten += pauiHuffmanTableDPCM[iQuantValue1][0]; + + ivas_split_rend_bitstream_write_int32( pBits, pauiHuffmanTableDPCM[iQuantValue2][1], pauiHuffmanTableDPCM[iQuantValue2][0] ); + iBitsWritten += pauiHuffmanTableDPCM[iQuantValue2][0]; + } + } + else + { + if ( iHuffDim == 2 ) + { + int32_t iSymbol; + iSymbol = iQuantValue1; + iSymbol *= iHuffMod; + iSymbol += iQuantValue2; + ivas_split_rend_bitstream_write_int32( pBits, pauiHuffmanTable[iSymbol][1], pauiHuffmanTable[iSymbol][0] ); + iBitsWritten += pauiHuffmanTable[iSymbol][0]; + } + else + { + ivas_split_rend_bitstream_write_int32( pBits, pauiHuffmanTable[iQuantValue1][1], pauiHuffmanTable[iQuantValue1][0] ); + iBitsWritten += pauiHuffmanTable[iQuantValue1][0]; + + ivas_split_rend_bitstream_write_int32( pBits, pauiHuffmanTable[iQuantValue2][1], pauiHuffmanTable[iQuantValue2][0] ); + iBitsWritten += pauiHuffmanTable[iQuantValue2][0]; + } + } + + if ( iQuantValue1 > 0 ) + { + ivas_split_rend_bitstream_write_int32( pBits, ppiSignReal[iBlockOffest][iFBOffset], 1 ); + iBitsWritten += 1; + } + if ( iQuantValue2 > 0 ) + { + ivas_split_rend_bitstream_write_int32( pBits, ppiSignImag[iBlockOffest][iFBOffset], 1 ); + iBitsWritten += 1; + } + + iFBOffset++; + } + } + else + { + iFBOffset += piBandwidths[b]; + } + } + + iBlockOffest++; + } + } + + 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, + int32_t **ppiPredEnable, + float **ppfA1Real, + float **ppfA1Imag ) +{ + int32_t iBitsUsed, iDone, iDelta; + int32_t b, k, n; + int32_t iLimitAllocOffset; + + iBitsUsed = ALLOC_OFFSET_BITS; /* Bits used for Alloc Offset */ + + iDone = 0; + iDelta = -MIN_ALLOC_OFFSET; + *piAllocOffset = 0; + + while ( iDone == 0 ) + { + iBitsUsed = ALLOC_OFFSET_BITS; + + iLimitAllocOffset = *piAllocOffset; + iLimitAllocOffset = ( iLimitAllocOffset > MIN_ALLOC_OFFSET ) ? iLimitAllocOffset : MIN_ALLOC_OFFSET; + iLimitAllocOffset = ( iLimitAllocOffset < MAX_ALLOC_OFFSET ) ? iLimitAllocOffset : MAX_ALLOC_OFFSET; + + for ( n = 0; n < iChannels; n++ ) + { + for ( k = 0; k < piNumGroups[n]; k++ ) + { + 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; + pppiAlloc[n][k][b] = iAlloc; + } + } + + QuantizeSpectrumDPCM_Opt( piNumGroups[n], + (const int32_t *) ppiGroupLengths[n], + iNumBands, + piBandwidths, + pppiAlloc[n], + pppfReal[n], + pppfImag[n], + pppiQReal[n], + pppiQImag[n], + pppiSignReal[n], + pppiSignImag[n], + ppiPredEnable[n], + ppfA1Real[n], + ppfA1Imag[n] ); + + iBitsUsed += CountLCLDBits( piNumGroups[n], + (const int32_t *) ppiGroupLengths[n], + iNumBands, + piBandwidths, + (const int32_t *) ppiPredEnable[n], + pppiAlloc[n], + pppiQReal[n], + pppiQImag[n] ); + } + + if ( *piAllocOffset <= MIN_ALLOC_OFFSET && iBitsUsed > iAvailableBits ) + { +#ifdef DEBUG_VERBOSE + printf( "Frame can not be coded with the number of bits available\n" ); +#endif + // iLastError = ENC_ERROR_STREAM_FAILURE; + return -1; + } + else if ( *piAllocOffset >= MAX_ALLOC_OFFSET && iBitsUsed < iAvailableBits ) + { + *piAllocOffset = MAX_ALLOC_OFFSET; + iDone++; + } + else + { + if ( iDelta == 0 && iBitsUsed > iAvailableBits ) + { + iDelta = 1; + } + else if ( iDelta == 0 && iBitsUsed < iAvailableBits ) + { + iDone++; + } + else if ( iBitsUsed == iAvailableBits ) + { + iDone++; + } + + if ( iBitsUsed > iAvailableBits ) + { + *piAllocOffset -= iDelta; + iDelta >>= 1; + } + else if ( iBitsUsed < iAvailableBits ) + { + *piAllocOffset += iDelta; + iDelta >>= 1; + } + } + } + + // 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_rend/ivas_lcld_prot.h b/lib_rend/ivas_lcld_prot.h new file mode 100644 index 000000000..ad35e50f0 --- /dev/null +++ b/lib_rend/ivas_lcld_prot.h @@ -0,0 +1,370 @@ +/****************************************************************************************************** + + (C) 2022-2023 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 _IVAS_LCLD_ENCODER_H_ +#define _IVAS_LCLD_ENCODER_H_ + +#include "options.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT +#include "lib_rend.h" +#include "ivas_lcld_rom_tables.h" + +/* clang-format off */ + +typedef struct LCLD_ENCODER LCLDEncoder; + +ivas_error CreateLCLDEncoder( + LCLDEncoder **psLCLDEncoder, + const int32_t iSampleRate, + const int32_t iChannels, + const int32_t iTargetBitRate, + const int32_t iAllowSidePred ); + +void DeleteLCLDEncoder( + LCLDEncoder *psLCLDEncoder +); + +int32_t EncodeLCLDFrame( + LCLDEncoder *psLCLDEncoder, + float ***pppfLCLDReal, + float ***pppfLCLDImag, + int32_t *piNumiBites, + const int32_t available_bits, + IVAS_SPLIT_REND_BITS_HANDLE pBits ); + +int32_t GetNumGroups( + LCLDEncoder *psLCLDEncoder +); + + +typedef struct LCLD_DECODER LCLDDecoder; + +ivas_error CreateLCLDDecoder( + LCLDDecoder **psLCLDDecoder_out, + const int32_t iSampleRate, + const int32_t iChannels ); + +void DeleteLCLDDecoder( + LCLDDecoder *psLCLDDecoder +); + +int32_t DecodeLCLDFrame( + LCLDDecoder *psLCLDDecoder, + IVAS_SPLIT_REND_BITS_HANDLE pBits, + float ***pppfLCLDReal, + float ***pppfLCLDImag +); + + +/*----------------------------------------------------------------------------------* + * MSPred prototypes + *----------------------------------------------------------------------------------*/ + +int32_t quantPhase( + float phase +); + +void cplxmult( + float *pr1, + float *pi1, + float r2, + float i2 +); + +#ifdef SIMPLE_PHASE +void rot_pm_pi( + float *pr, + float *pi ); + +void rot_p_pi_2( + float *pr, + float *pi +); + +void rot_m_pi_2( + float *pr, + float *pi ); + +void rot_zero( + float *pr, + float *pi +); +#endif + +int32_t requantPhase( + int32_t phaseQ +); + +int32_t quantPred( + const float pred +); + +float dequantPhase( + const int32_t phaseQ +); + +float dequantPred( + int32_t predQ +); + +int32_t PrepEncode( + int32_t *piQuant, + const int32_t *piMSFlags, + const int32_t numBands +); + +void EncodePhase( + int32_t *phaseQuant, + const int32_t numMSBands, + const int32_t diffDim +); + +void DecodePhase( + int32_t *phaseQuant, + const int32_t numMSBands, + const int32_t diffDim +); + +int32_t EncodePredCoef( + int32_t *predQuant, + const int32_t numMSBands +); + +void DecodePredCoef( + int32_t *phaseQuant, + const int32_t numMSBands +); + +void writeMSPred( + int32_t *phaseQuant, + int32_t *predQuant, + const int32_t MSMode, + const int32_t numMSBands, + int32_t numBands, + void *fid, + 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 +); + + +/*----------------------------------------------------------------------------------* + * NoiseGen prototypes + *----------------------------------------------------------------------------------*/ + +typedef struct NOISE_GEN +{ + int32_t iNoiseBufferLength; + int32_t iNoiseBufferMask; + int32_t iNoiseBufferIndex; + float *pfNoiseBuffer; +} NoiseGen; + +NoiseGen *CreateNoiseGen( + void +); + +void DeleteNoiseGen( + NoiseGen *psNoiseGen +); + +inline float GetNoise( NoiseGen *psNoiseGen ) +{ + float fNoiseSample; + + fNoiseSample = psNoiseGen->pfNoiseBuffer[psNoiseGen->iNoiseBufferIndex]; + psNoiseGen->iNoiseBufferIndex++; + psNoiseGen->iNoiseBufferIndex &= psNoiseGen->iNoiseBufferMask; + + return fNoiseSample; +} + + +/*----------------------------------------------------------------------------------* + * PereptualModel prototypes + *----------------------------------------------------------------------------------*/ + +extern void PerceptualModel( + const int32_t iMaxQuantBands, + const int32_t *piRMSEnvelope, + int32_t *piExcitation, + int32_t *piSMR +); + +extern void PerceptualModelStereo( + const int32_t iMaxQuantBands, + const int32_t *piMSFlags, + const int32_t *piRMSEnvelope0, + const int32_t *piRMSEnvelope1, + int32_t *piExcitation0, + int32_t *piExcitation1, + int32_t *piSMR0, + int32_t *piSMR1 +); + + +/*----------------------------------------------------------------------------------* + * PredEncoder/PredDecoder prototypes + *----------------------------------------------------------------------------------*/ + +typedef struct PREDICTION_ENCODER +{ + int32_t iChannels; + int32_t iNumBlocks; + + float *pfWindow; + float pfRxxReal[2]; + float pfRxxImag[2]; + + int32_t *piPredChanEnable; + int32_t *piNumPredBands; + + float **ppfEstPredGain; + float **ppfEstPredBitGain; + int32_t **ppiPredBandEnable; + + float **ppfA1Real; + float **ppfA1Imag; + + int32_t **ppiA1Mag; + int32_t **ppiA1Phase; +} PredictionEncoder; + +ivas_error CreatePredictionEncoder( + PredictionEncoder **psPredictionEncoder_out, + const int32_t iChannels, + const int32_t iNumBlocks +); + +void DeletePredictionEncoder( + PredictionEncoder *psPredictionEncoder +); + +int32_t ComputePredictors( + PredictionEncoder *psPredictionEncoder, + float ***pppfReal, + float ***pppfImag +); + +void ApplyForwardPredictors( + PredictionEncoder *psPredictionEncoder, + float ***pppfReal, + float ***pppfImag +); + +int32_t WritePredictors( + PredictionEncoder *psPredictionEncoder, + IVAS_SPLIT_REND_BITS_HANDLE pBits +); + +typedef struct PREDICTION_DECODER +{ + int32_t iChannels; + int32_t iNumBlocks; + + int32_t *piPredChanEnable; + int32_t *piNumPredBands; + + float **ppfEstPredGain; + int32_t **ppiPredBandEnable; + + float **ppfA1Real; + float **ppfA1Imag; + + 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]; + +} PredictionDecoder; + +ivas_error CreatePredictionDecoder( + PredictionDecoder **psPredictionDecoder_out, + const int32_t iChannels, + const int32_t iNumBlocks +); + +void DeletePredictionDecoder( + PredictionDecoder *psPredictionDecoder +); + +int32_t ReadPredictors( + PredictionDecoder *psPredictionDecoder, + IVAS_SPLIT_REND_BITS_HANDLE pBits +); + +void ApplyInversePredictros( + PredictionDecoder *psPredictionDecoder, + float ***pppfReal, + float ***pppfImag +); + + +/*----------------------------------------------------------------------------------* + * RMSEnvGrouping prototypes + *----------------------------------------------------------------------------------*/ + +typedef struct RMS_ENVELOPE_GROUPING RMSEnvelopeGrouping; + +RMSEnvelopeGrouping *CreateRMSEnvelopeGrouping( + const int32_t iNumBlocks +); + +void DeleteRMSEnvelopeGrouping( + RMSEnvelopeGrouping *psRMSEnvelopeGrouping +); + +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 +); + + +#endif +/* clang-format on */ + +#endif /* _LCLD_ENCODER_H_ */ diff --git a/lib_rend/ivas_lcld_rom_tables.c b/lib_rend/ivas_lcld_rom_tables.c new file mode 100644 index 000000000..144c44718 --- /dev/null +++ b/lib_rend/ivas_lcld_rom_tables.c @@ -0,0 +1,19854 @@ +/****************************************************************************************************** + + (C) 2022-2023 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. + +*******************************************************************************************************/ + +#include "ivas_lcld_rom_tables.h" +#include "options.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT +#include "wmc_auto.h" +#include "prot.h" +#include "ivas_lcld_prot.h" + +/* clang-format off */ + +const float c_afRotRealImagSimple[SIMPLE_PHASE_MAX_VAL + 1][2] = { + { 1.0f, 0.0f }, /* zero */ + { 0.0f, 1.0f }, /* pi/2 */ + { -1.0f, 0.0f }, /* pi */ + { 0.0f, -1.0f }, /* 3*pi/2 */ +}; + +/* 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] = +{ + { -1.00000000f, -0.00000000f }, + { -0.96592583f, -0.25881905f }, + { -0.86602540f, -0.50000000f }, + { -0.70710678f, -0.70710678f }, + { -0.50000000f, -0.86602540f }, + { -0.25881905f, -0.96592583f }, + { 0.00000000f, -1.00000000f }, + { 0.25881905f, -0.96592583f }, + { 0.50000000f, -0.86602540f }, + { 0.70710678f, -0.70710678f }, + { 0.86602540f, -0.50000000f }, + { 0.96592583f, -0.25881905f }, + { 1.00000000f, 0.00000000f }, + { 0.96592583f, 0.25881905f }, + { 0.86602540f, 0.50000000f }, + { 0.70710678f, 0.70710678f }, + { 0.50000000f, 0.86602540f }, + { 0.25881905f, 0.96592583f }, + { 0.00000000f, 1.00000000f }, + { -0.25881905f, 0.96592583f }, + { -0.50000000f, 0.86602540f }, + { -0.70710678f, 0.70710678f }, + { -0.86602540f, 0.50000000f }, + { -0.96592583f, 0.25881905f }, + { -1.00000000f, 0.00000000f } +}; + +/* Move this to perceptual model ? */ +const int32_t c_aiBandwidths48[MAX_BANDS_48] = +{ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 2, + 2, + 2, + 2, + 2, + 3, + 3, + 4, + 6, + 6, + 7, + 10, +}; + + +const float c_afScaleFactor[ALLOC_TABLE_SIZE] = { + 0.0f, + 0.353553390593f, + 0.420448207627f, + 0.500000000000f, + 0.594603557501f, + 0.707106781187f, + 0.840896415254f, + 1.000000000000f, + 1.189207115003f, + 1.414213562373f, + 1.681792830507f, + 2.000000000000f, + 2.378414230005f, + 2.828427124746f, + 3.363585661015f, + 4.0f, + 4.756828460011f, + 5.656854249492f, + 6.727171322030f, + 8.0f, + 9.513656920022f, + 11.31370849898f, + 13.45434264406f, + 16.00000000000f, + 19.02731384004f, + 22.62741699797f, + 26.90868528812f, + 32.000000000000000f, + 38.054627680087073f, + 45.254833995939038f, + 53.817370576237735f, + 64.000000000000000f, +}; + +const float c_afInvScaleFactor[ALLOC_TABLE_SIZE] = { + 0.0f, + 2.367513562373095f, + 2.046407115002721f, + 1.775900000000000f, + 1.536446415253715f, + 1.323056781186548f, + 1.132903557501360f, + 0.965800000000000f, + 0.821348207626857f, + 0.695103390593274f, + 0.587801778750680f, + 0.495800000000000f, + 0.418124103813429f, + 0.352176695296637f, + 0.296200889375340f, + 0.249400000000000f, + 0.209812051906714f, + 0.176538347648318f, + 0.148525444687670f, + 0.124900000000000f, + 0.105056025953357f, + 0.088388347648318f, + 0.074325444687670f, + 0.062500000000000f, + 0.052556025953357f, + 0.044194173824159f, + 0.037162722343835f, + 0.031250000000000f, + 0.026278012976679f, + 0.022097086912080f, + 0.018581361171918f, + 0.015625000000000f, +}; + +const float c_afRMSEnvReconstructTable[ENV_RECONSTRUCT_TABLE_SIZE] = { + 2.32830644e-10f, + 3.29272254e-10f, + 4.65661287e-10f, + 6.58544508e-10f, + 9.31322575e-10f, + 1.31708902e-09f, + 1.86264515e-09f, + 2.63417803e-09f, + 3.72529030e-09f, + 5.26835606e-09f, + 7.45058060e-09f, + 1.05367121e-08f, + 1.49011612e-08f, + 2.10734243e-08f, + 2.98023224e-08f, + 4.21468485e-08f, + 5.96046448e-08f, + 8.42936970e-08f, + 1.19209290e-07f, + 1.68587394e-07f, + 2.38418579e-07f, + 3.37174788e-07f, + 4.76837158e-07f, + 6.74349576e-07f, + 9.53674316e-07f, + 1.34869915e-06f, + 1.90734863e-06f, + 2.69739830e-06f, + 3.81469727e-06f, + 5.39479661e-06f, + 7.62939453e-06f, + 1.07895932e-05f, + 1.52587891e-05f, + 2.15791864e-05f, + 3.05175781e-05f, + 4.31583729e-05f, + 6.10351562e-05f, + 8.63167458e-05f, + 1.22070312e-04f, + 1.72633492e-04f, + 2.44140625e-04f, + 3.45266983e-04f, + 4.88281250e-04f, + 6.90533966e-04f, + 9.76562500e-04f, + 1.38106793e-03f, + 1.95312500e-03f, + 2.76213586e-03f, + 3.90625000e-03f, + 5.52427173e-03f, + 7.81250000e-03f, + 1.10485435e-02f, + 1.56250000e-02f, + 2.20970869e-02f, + 3.12500000e-02f, + 4.41941738e-02f, + 6.25000000e-02f, + 8.83883476e-02f, + 1.25000000e-01f, + 1.76776695e-01f, + 2.50000000e-01f, + 3.53553391e-01f, + 5.00000000e-01f, + 7.07106781e-01f, + 1.00000000e+00f, + 1.41421356e+00f, + 2.00000000e+00f, + 2.82842712e+00f, + 4.00000000e+00f, + 5.65685425e+00f, + 8.00000000e+00f, + 1.13137085e+01f, + 1.60000000e+01f, + 2.26274170e+01f, + 3.20000000e+01f, + 4.52548340e+01f, + 6.40000000e+01f, + 9.05096680e+01f, + 1.28000000e+02f, + 1.81019336e+02f, + 2.56000000e+02f, + 3.62038672e+02f, + 5.12000000e+02f, + 7.24077344e+02f, + 1.02400000e+03f, + 1.44815469e+03f, + 2.04800000e+03f, + 2.89630938e+03f, + 4.09600000e+03f, + 5.79261875e+03f, + 8.19200000e+03f, + 1.15852375e+04f, + 1.63840000e+04f, + 2.31704750e+04f, + 3.27680000e+04f, + 4.63409500e+04f, + 6.55360000e+04f, + 9.26819000e+04f, + 1.31072000e+05f, + 1.85363800e+05f, + 2.62144000e+05f, + 3.70727600e+05f, + 5.24288000e+05f, + 7.41455200e+05f, + 1.04857600e+06f, + 1.48291040e+06f, + 2.09715200e+06f, + 2.96582080e+06f, + 4.19430400e+06f, + 5.93164160e+06f, + 8.38860800e+06f, + 1.18632832e+07f, + 1.67772160e+07f, + 2.37265664e+07f, + 3.35544320e+07f, + 4.74531328e+07f, + 6.71088640e+07f, + 9.49062656e+07f, + 1.34217728e+08f, + 1.89812531e+08f, + 2.68435456e+08f, + 3.79625062e+08f, + 5.36870912e+08f, + 7.59250125e+08f, + 1.07374182e+09f, + 1.51850025e+09f, + 2.14748365e+09f, + 3.03700050e+09f, + 4.29496730e+09f, +}; + +const int32_t c_aiQuantMaxValues[ALLOC_TABLE_SIZE] = { + 0, + 3, + 3, + 4, + 5, + 5, + 6, + 7, + 8, + 9, + 12, + 13, + 16, + 17, + 19, + 23, + 26, + 26, + 27, + 28, + 31, + 36, + 38, + 45, + 54, + 64, + 76, + 90, + 108, + 128, + 152, + 180, +}; + +const int32_t c_aiHuffmanDim[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 int32_t c_aiHuffmanMod[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_aiHuffmanSize[ALLOC_TABLE_SIZE] = { + 1, + 16, + 16, + 25, + 36, + 36, + 49, + 64, + 81, + 100, + 169, + 196, + 289, + 324, + 400, + 576, + 729, + 729, + 28, + 29, + 32, + 37, + 39, + 46, + 55, + 65, + 77, + 91, + 109, + 129, + 153, + 181, +}; + +const uint32_t c_aaiRMSEnvHuffEnc[64][2] = { + { 0x0014, 0x0000 }, + { 0x0014, 0x0001 }, + { 0x0014, 0x0002 }, + { 0x0014, 0x0003 }, + { 0x0014, 0x0004 }, + { 0x0014, 0x0005 }, + { 0x0013, 0x0003 }, + { 0x0013, 0x0004 }, + { 0x0013, 0x0005 }, + { 0x0013, 0x0006 }, + { 0x0013, 0x0007 }, + { 0x0012, 0x000b }, + { 0x000d, 0x0002 }, + { 0x000e, 0x0001 }, + { 0x000e, 0x0002 }, + { 0x000d, 0x0003 }, + { 0x000b, 0x0002 }, + { 0x000a, 0x0003 }, + { 0x000a, 0x0004 }, + { 0x000a, 0x0005 }, + { 0x0009, 0x0004 }, + { 0x0009, 0x0005 }, + { 0x0009, 0x0006 }, + { 0x0008, 0x0005 }, + { 0x0008, 0x0006 }, + { 0x0007, 0x0004 }, + { 0x0006, 0x0003 }, + { 0x0006, 0x0004 }, + { 0x0005, 0x0003 }, + { 0x0004, 0x0002 }, + { 0x0003, 0x0002 }, + { 0x0002, 0x0002 }, + { 0x0002, 0x0003 }, + { 0x0003, 0x0003 }, + { 0x0004, 0x0003 }, + { 0x0006, 0x0005 }, + { 0x0007, 0x0005 }, + { 0x0008, 0x0007 }, + { 0x0009, 0x0007 }, + { 0x0009, 0x0008 }, + { 0x0009, 0x0009 }, + { 0x000a, 0x0006 }, + { 0x000a, 0x0007 }, + { 0x000b, 0x0003 }, + { 0x000c, 0x0002 }, + { 0x000c, 0x0003 }, + { 0x000b, 0x0004 }, + { 0x000b, 0x0005 }, + { 0x000e, 0x0003 }, + { 0x0010, 0x0003 }, + { 0x0013, 0x0008 }, + { 0x0013, 0x0009 }, + { 0x0013, 0x000a }, + { 0x0013, 0x000b }, + { 0x0013, 0x000c }, + { 0x0013, 0x000d }, + { 0x0013, 0x000e }, + { 0x0013, 0x000f }, + { 0x0013, 0x0010 }, + { 0x0013, 0x0011 }, + { 0x0013, 0x0012 }, + { 0x0013, 0x0013 }, + { 0x0013, 0x0014 }, + { 0x0013, 0x0015 }, +}; + +const uint32_t c_aaiRMSEnvHuffDec[13][HUFF_DEC_TABLE_SIZE] = { + { + 0x0002ffff, + 0x0001ffff, + 0x0000001d, + 0x00000022, + 0x0001001e, + 0x0001001e, + 0x00010021, + 0x00010021, + 0x0002001f, + 0x0002001f, + 0x0002001f, + 0x0002001f, + 0x00020020, + 0x00020020, + 0x00020020, + 0x00020020, + }, + { + 0x0002001b, + 0x0002001b, + 0x0002001b, + 0x0002001b, + 0x00020023, + 0x00020023, + 0x00020023, + 0x00020023, + 0x0003001c, + 0x0003001c, + 0x0003001c, + 0x0003001c, + 0x0003001c, + 0x0003001c, + 0x0003001c, + 0x0003001c, + }, + { + 0x0006ffff, + 0x0007ffff, + 0x0003ffff, + 0x0004ffff, + 0x0005ffff, + 0x00000017, + 0x00000018, + 0x00000025, + 0x00010019, + 0x00010019, + 0x00010024, + 0x00010024, + 0x0002001a, + 0x0002001a, + 0x0002001a, + 0x0002001a, + }, + { + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030015, + 0x00030015, + 0x00030015, + 0x00030015, + 0x00030015, + 0x00030015, + 0x00030015, + 0x00030015, + }, + { + 0x00030016, + 0x00030016, + 0x00030016, + 0x00030016, + 0x00030016, + 0x00030016, + 0x00030016, + 0x00030016, + 0x00030026, + 0x00030026, + 0x00030026, + 0x00030026, + 0x00030026, + 0x00030026, + 0x00030026, + 0x00030026, + }, + { + 0x00030027, + 0x00030027, + 0x00030027, + 0x00030027, + 0x00030027, + 0x00030027, + 0x00030027, + 0x00030027, + 0x00030028, + 0x00030028, + 0x00030028, + 0x00030028, + 0x00030028, + 0x00030028, + 0x00030028, + 0x00030028, + }, + { + 0x0009ffff, + 0x0008ffff, + 0x0000002c, + 0x0000002d, + 0x00010010, + 0x00010010, + 0x0001002b, + 0x0001002b, + 0x0001002e, + 0x0001002e, + 0x0001002f, + 0x0001002f, + 0x00020011, + 0x00020011, + 0x00020011, + 0x00020011, + }, + { + 0x00020012, + 0x00020012, + 0x00020012, + 0x00020012, + 0x00020013, + 0x00020013, + 0x00020013, + 0x00020013, + 0x00020029, + 0x00020029, + 0x00020029, + 0x00020029, + 0x0002002a, + 0x0002002a, + 0x0002002a, + 0x0002002a, + }, + { + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + }, + { + 0x000bffff, + 0x000cffff, + 0x000affff, + 0x00000031, + 0x0002000d, + 0x0002000d, + 0x0002000d, + 0x0002000d, + 0x0002000e, + 0x0002000e, + 0x0002000e, + 0x0002000e, + 0x00020030, + 0x00020030, + 0x00020030, + 0x00020030, + }, + { + 0x0001003a, + 0x0001003a, + 0x0001003b, + 0x0001003b, + 0x0001003c, + 0x0001003c, + 0x0001003d, + 0x0001003d, + 0x0001003e, + 0x0001003e, + 0x0001003f, + 0x0001003f, + 0x0002000b, + 0x0002000b, + 0x0002000b, + 0x0002000b, + }, + { + 0x00000000, + 0x00000001, + 0x00000002, + 0x00000003, + 0x00000004, + 0x00000005, + 0x00010006, + 0x00010006, + 0x00010007, + 0x00010007, + 0x00010008, + 0x00010008, + 0x00010009, + 0x00010009, + 0x0001000a, + 0x0001000a, + }, + { + 0x00010032, + 0x00010032, + 0x00010033, + 0x00010033, + 0x00010034, + 0x00010034, + 0x00010035, + 0x00010035, + 0x00010036, + 0x00010036, + 0x00010037, + 0x00010037, + 0x00010038, + 0x00010038, + 0x00010039, + 0x00010039, + }, +}; + +const uint16_t c_aauiLCLDHuffEnc1[16][2] = + { + { 0x0001, 0x0001 }, + { 0x0003, 0x0001 }, + { 0x0005, 0x0001 }, + { 0x000b, 0x0000 }, + { 0x0002, 0x0001 }, + { 0x0004, 0x0001 }, + { 0x0007, 0x0001 }, + { 0x000b, 0x0001 }, + { 0x0006, 0x0001 }, + { 0x0008, 0x0001 }, + { 0x000b, 0x0002 }, + { 0x000b, 0x0003 }, + { 0x000b, 0x0004 }, + { 0x000b, 0x0005 }, + { 0x000b, 0x0006 }, + { 0x000b, 0x0007 }, + }; + +const uint16_t c_aauiLCLDHuffEnc2[16][2] = + { + { 0x0001, 0x0001 }, + { 0x0003, 0x0001 }, + { 0x0005, 0x0001 }, + { 0x000c, 0x0000 }, + { 0x0002, 0x0001 }, + { 0x0004, 0x0001 }, + { 0x0007, 0x0001 }, + { 0x000c, 0x0001 }, + { 0x0006, 0x0001 }, + { 0x0008, 0x0001 }, + { 0x0009, 0x0001 }, + { 0x000c, 0x0002 }, + { 0x000c, 0x0003 }, + { 0x000c, 0x0004 }, + { 0x000c, 0x0005 }, + { 0x000b, 0x0003 }, + }; + +const uint16_t c_aauiLCLDHuffEnc3[25][2] = + { + { 0x0001, 0x0001 }, + { 0x0003, 0x0001 }, + { 0x0006, 0x0001 }, + { 0x000d, 0x0000 }, + { 0x000d, 0x0001 }, + { 0x0002, 0x0001 }, + { 0x0004, 0x0001 }, + { 0x0007, 0x0001 }, + { 0x000d, 0x0002 }, + { 0x000d, 0x0003 }, + { 0x0006, 0x0002 }, + { 0x0006, 0x0003 }, + { 0x0008, 0x0001 }, + { 0x000d, 0x0004 }, + { 0x000d, 0x0005 }, + { 0x0009, 0x0001 }, + { 0x000c, 0x0007 }, + { 0x000d, 0x0006 }, + { 0x000d, 0x0007 }, + { 0x000d, 0x0008 }, + { 0x000d, 0x0009 }, + { 0x000d, 0x000a }, + { 0x000d, 0x000b }, + { 0x000d, 0x000c }, + { 0x000d, 0x000d }, + + }; + +const uint16_t c_aauiLCLDHuffEnc4[36][2] = + { + { 0x0001, 0x0001 }, + { 0x0003, 0x0001 }, + { 0x0006, 0x0001 }, + { 0x000b, 0x0001 }, + { 0x0010, 0x0000 }, + { 0x0010, 0x0001 }, + { 0x0002, 0x0001 }, + { 0x0004, 0x0001 }, + { 0x0007, 0x0001 }, + { 0x000a, 0x0001 }, + { 0x0010, 0x0002 }, + { 0x0010, 0x0003 }, + { 0x0006, 0x0002 }, + { 0x0006, 0x0003 }, + { 0x0008, 0x0001 }, + { 0x000e, 0x0006 }, + { 0x0010, 0x0004 }, + { 0x0010, 0x0005 }, + { 0x000a, 0x0002 }, + { 0x000a, 0x0003 }, + { 0x000e, 0x0007 }, + { 0x0010, 0x0006 }, + { 0x0010, 0x0007 }, + { 0x0010, 0x0008 }, + { 0x0010, 0x0009 }, + { 0x0010, 0x000a }, + { 0x0010, 0x000b }, + { 0x0010, 0x000c }, + { 0x0010, 0x000d }, + { 0x0010, 0x000e }, + { 0x0010, 0x000f }, + { 0x0010, 0x0010 }, + { 0x0010, 0x0011 }, + { 0x000f, 0x0009 }, + { 0x000f, 0x000a }, + { 0x000f, 0x000b }, + + }; + +const uint16_t c_aauiLCLDHuffEnc5[36][2] = + { + { 0x0001, 0x0001 }, + { 0x0003, 0x0001 }, + { 0x0006, 0x0001 }, + { 0x000a, 0x0001 }, + { 0x000f, 0x0003 }, + { 0x0012, 0x0000 }, + { 0x0002, 0x0001 }, + { 0x0004, 0x0001 }, + { 0x0007, 0x0001 }, + { 0x000b, 0x0001 }, + { 0x0011, 0x0008 }, + { 0x0012, 0x0001 }, + { 0x0006, 0x0002 }, + { 0x0006, 0x0003 }, + { 0x0008, 0x0001 }, + { 0x000c, 0x0001 }, + { 0x0012, 0x0002 }, + { 0x0012, 0x0003 }, + { 0x000a, 0x0002 }, + { 0x000a, 0x0003 }, + { 0x000d, 0x0001 }, + { 0x0012, 0x0004 }, + { 0x0012, 0x0005 }, + { 0x0012, 0x0006 }, + { 0x0011, 0x0009 }, + { 0x0011, 0x000a }, + { 0x0012, 0x0007 }, + { 0x0012, 0x0008 }, + { 0x0012, 0x0009 }, + { 0x0012, 0x000a }, + { 0x0012, 0x000b }, + { 0x0012, 0x000c }, + { 0x0012, 0x000d }, + { 0x0012, 0x000e }, + { 0x0012, 0x000f }, + { 0x0011, 0x000b }, + + }; + +const uint16_t c_aauiLCLDHuffEnc6[49][2] = + { + { 0x0001, 0x0001 }, + { 0x0003, 0x0001 }, + { 0x0006, 0x0001 }, + { 0x000a, 0x0001 }, + { 0x0010, 0x0003 }, + { 0x0014, 0x0000 }, + { 0x0014, 0x0001 }, + { 0x0002, 0x0001 }, + { 0x0004, 0x0001 }, + { 0x0007, 0x0001 }, + { 0x000a, 0x0002 }, + { 0x0010, 0x0004 }, + { 0x0014, 0x0002 }, + { 0x0014, 0x0003 }, + { 0x0006, 0x0002 }, + { 0x0006, 0x0003 }, + { 0x0008, 0x0001 }, + { 0x000d, 0x0001 }, + { 0x0012, 0x0007 }, + { 0x0014, 0x0004 }, + { 0x0014, 0x0005 }, + { 0x000a, 0x0003 }, + { 0x000b, 0x0001 }, + { 0x000c, 0x0001 }, + { 0x0011, 0x0004 }, + { 0x0014, 0x0006 }, + { 0x0014, 0x0007 }, + { 0x0014, 0x0008 }, + { 0x0010, 0x0005 }, + { 0x000f, 0x0003 }, + { 0x0011, 0x0005 }, + { 0x0014, 0x0009 }, + { 0x0014, 0x000a }, + { 0x0014, 0x000b }, + { 0x0014, 0x000c }, + { 0x0014, 0x000d }, + { 0x0013, 0x000d }, + { 0x0014, 0x000e }, + { 0x0014, 0x000f }, + { 0x0014, 0x0010 }, + { 0x0014, 0x0011 }, + { 0x0014, 0x0012 }, + { 0x0014, 0x0013 }, + { 0x0014, 0x0014 }, + { 0x0014, 0x0015 }, + { 0x0014, 0x0016 }, + { 0x0014, 0x0017 }, + { 0x0014, 0x0018 }, + { 0x0014, 0x0019 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc7[64][2] = + { + { 0x0002, 0x0001 }, + { 0x0002, 0x0002 }, + { 0x0005, 0x0001 }, + { 0x0009, 0x0001 }, + { 0x000f, 0x0002 }, + { 0x0015, 0x0000 }, + { 0x0015, 0x0001 }, + { 0x0015, 0x0002 }, + { 0x0002, 0x0003 }, + { 0x0003, 0x0001 }, + { 0x0006, 0x0001 }, + { 0x0009, 0x0002 }, + { 0x000f, 0x0003 }, + { 0x0014, 0x0011 }, + { 0x0015, 0x0003 }, + { 0x0015, 0x0004 }, + { 0x0005, 0x0002 }, + { 0x0005, 0x0003 }, + { 0x0007, 0x0001 }, + { 0x000b, 0x0001 }, + { 0x0010, 0x0002 }, + { 0x0015, 0x0005 }, + { 0x0015, 0x0006 }, + { 0x0015, 0x0007 }, + { 0x000a, 0x0001 }, + { 0x0009, 0x0003 }, + { 0x000c, 0x0001 }, + { 0x000f, 0x0004 }, + { 0x0012, 0x0006 }, + { 0x0015, 0x0008 }, + { 0x0015, 0x0009 }, + { 0x0015, 0x000a }, + { 0x000f, 0x0005 }, + { 0x000e, 0x0003 }, + { 0x0010, 0x0003 }, + { 0x0012, 0x0007 }, + { 0x0014, 0x0012 }, + { 0x0015, 0x000b }, + { 0x0015, 0x000c }, + { 0x0015, 0x000d }, + { 0x0014, 0x0013 }, + { 0x0014, 0x0014 }, + { 0x0013, 0x000b }, + { 0x0014, 0x0015 }, + { 0x0015, 0x000e }, + { 0x0015, 0x000f }, + { 0x0015, 0x0010 }, + { 0x0015, 0x0011 }, + { 0x0015, 0x0012 }, + { 0x0015, 0x0013 }, + { 0x0015, 0x0014 }, + { 0x0015, 0x0015 }, + { 0x0015, 0x0016 }, + { 0x0015, 0x0017 }, + { 0x0015, 0x0018 }, + { 0x0015, 0x0019 }, + { 0x0015, 0x001a }, + { 0x0015, 0x001b }, + { 0x0015, 0x001c }, + { 0x0015, 0x001d }, + { 0x0015, 0x001e }, + { 0x0015, 0x001f }, + { 0x0015, 0x0020 }, + { 0x0015, 0x0021 }, + }; + +const uint16_t c_aauiLCLDHuffEnc8[81][2] = + { + { 0x0001, 0x0001 }, + { 0x0003, 0x0001 }, + { 0x0006, 0x0001 }, + { 0x000a, 0x0001 }, + { 0x000f, 0x0002 }, + { 0x0014, 0x0008 }, + { 0x0017, 0x0000 }, + { 0x0017, 0x0001 }, + { 0x0017, 0x0002 }, + { 0x0003, 0x0002 }, + { 0x0003, 0x0003 }, + { 0x0005, 0x0001 }, + { 0x0009, 0x0001 }, + { 0x000f, 0x0003 }, + { 0x0012, 0x0004 }, + { 0x0015, 0x000d }, + { 0x0017, 0x0003 }, + { 0x0017, 0x0004 }, + { 0x0005, 0x0002 }, + { 0x0005, 0x0003 }, + { 0x0007, 0x0001 }, + { 0x000c, 0x0001 }, + { 0x0010, 0x0002 }, + { 0x0013, 0x0005 }, + { 0x0017, 0x0005 }, + { 0x0017, 0x0006 }, + { 0x0017, 0x0007 }, + { 0x0009, 0x0002 }, + { 0x0009, 0x0003 }, + { 0x000b, 0x0001 }, + { 0x000f, 0x0004 }, + { 0x0012, 0x0005 }, + { 0x0016, 0x0015 }, + { 0x0017, 0x0008 }, + { 0x0017, 0x0009 }, + { 0x0017, 0x000a }, + { 0x000f, 0x0005 }, + { 0x000e, 0x0003 }, + { 0x0010, 0x0003 }, + { 0x0012, 0x0006 }, + { 0x0014, 0x0009 }, + { 0x0017, 0x000b }, + { 0x0017, 0x000c }, + { 0x0017, 0x000d }, + { 0x0017, 0x000e }, + { 0x0013, 0x0006 }, + { 0x0012, 0x0007 }, + { 0x0013, 0x0007 }, + { 0x0015, 0x000e }, + { 0x0017, 0x000f }, + { 0x0017, 0x0010 }, + { 0x0017, 0x0011 }, + { 0x0017, 0x0012 }, + { 0x0017, 0x0013 }, + { 0x0016, 0x0016 }, + { 0x0016, 0x0017 }, + { 0x0015, 0x000f }, + { 0x0016, 0x0018 }, + { 0x0017, 0x0014 }, + { 0x0017, 0x0015 }, + { 0x0017, 0x0016 }, + { 0x0017, 0x0017 }, + { 0x0017, 0x0018 }, + { 0x0017, 0x0019 }, + { 0x0017, 0x001a }, + { 0x0017, 0x001b }, + { 0x0017, 0x001c }, + { 0x0017, 0x001d }, + { 0x0017, 0x001e }, + { 0x0017, 0x001f }, + { 0x0017, 0x0020 }, + { 0x0017, 0x0021 }, + { 0x0017, 0x0022 }, + { 0x0017, 0x0023 }, + { 0x0017, 0x0024 }, + { 0x0017, 0x0025 }, + { 0x0017, 0x0026 }, + { 0x0017, 0x0027 }, + { 0x0017, 0x0028 }, + { 0x0017, 0x0029 }, + { 0x0016, 0x0019 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc9[100][2] = + { + { 0x0001, 0x0001 }, + { 0x0003, 0x0001 }, + { 0x0006, 0x0001 }, + { 0x0009, 0x0001 }, + { 0x000d, 0x0002 }, + { 0x0011, 0x0004 }, + { 0x0014, 0x000a }, + { 0x0017, 0x0000 }, + { 0x0017, 0x0001 }, + { 0x0017, 0x0002 }, + { 0x0003, 0x0002 }, + { 0x0003, 0x0003 }, + { 0x0005, 0x0001 }, + { 0x0009, 0x0002 }, + { 0x000d, 0x0003 }, + { 0x0010, 0x0004 }, + { 0x0013, 0x0007 }, + { 0x0016, 0x0018 }, + { 0x0017, 0x0003 }, + { 0x0017, 0x0004 }, + { 0x0005, 0x0002 }, + { 0x0005, 0x0003 }, + { 0x0008, 0x0002 }, + { 0x000b, 0x0002 }, + { 0x000e, 0x0002 }, + { 0x0011, 0x0005 }, + { 0x0014, 0x000b }, + { 0x0016, 0x0019 }, + { 0x0017, 0x0005 }, + { 0x0017, 0x0006 }, + { 0x0009, 0x0003 }, + { 0x0008, 0x0003 }, + { 0x000b, 0x0003 }, + { 0x000d, 0x0004 }, + { 0x0010, 0x0005 }, + { 0x0012, 0x0006 }, + { 0x0015, 0x000f }, + { 0x0017, 0x0007 }, + { 0x0017, 0x0008 }, + { 0x0017, 0x0009 }, + { 0x000d, 0x0005 }, + { 0x000c, 0x0003 }, + { 0x000e, 0x0003 }, + { 0x0010, 0x0006 }, + { 0x0012, 0x0007 }, + { 0x0014, 0x000c }, + { 0x0017, 0x000a }, + { 0x0016, 0x001a }, + { 0x0017, 0x000b }, + { 0x0017, 0x000c }, + { 0x0011, 0x0006 }, + { 0x0010, 0x0007 }, + { 0x0011, 0x0007 }, + { 0x0013, 0x0008 }, + { 0x0013, 0x0009 }, + { 0x0015, 0x0010 }, + { 0x0017, 0x000d }, + { 0x0017, 0x000e }, + { 0x0017, 0x000f }, + { 0x0017, 0x0010 }, + { 0x0013, 0x000a }, + { 0x0013, 0x000b }, + { 0x0014, 0x000d }, + { 0x0015, 0x0011 }, + { 0x0017, 0x0011 }, + { 0x0016, 0x001b }, + { 0x0017, 0x0012 }, + { 0x0017, 0x0013 }, + { 0x0017, 0x0014 }, + { 0x0017, 0x0015 }, + { 0x0017, 0x0016 }, + { 0x0015, 0x0012 }, + { 0x0015, 0x0013 }, + { 0x0017, 0x0017 }, + { 0x0016, 0x001c }, + { 0x0017, 0x0018 }, + { 0x0017, 0x0019 }, + { 0x0017, 0x001a }, + { 0x0017, 0x001b }, + { 0x0017, 0x001c }, + { 0x0017, 0x001d }, + { 0x0017, 0x001e }, + { 0x0017, 0x001f }, + { 0x0017, 0x0020 }, + { 0x0017, 0x0021 }, + { 0x0017, 0x0022 }, + { 0x0017, 0x0023 }, + { 0x0017, 0x0024 }, + { 0x0017, 0x0025 }, + { 0x0017, 0x0026 }, + { 0x0017, 0x0027 }, + { 0x0017, 0x0028 }, + { 0x0017, 0x0029 }, + { 0x0017, 0x002a }, + { 0x0017, 0x002b }, + { 0x0017, 0x002c }, + { 0x0017, 0x002d }, + { 0x0017, 0x002e }, + { 0x0017, 0x002f }, + { 0x0016, 0x001d }, + + }; + +const uint16_t c_aauiLCLDHuffEnc10[169][2] = + { + { 0x0001, 0x0001 }, + { 0x0004, 0x0002 }, + { 0x0005, 0x0002 }, + { 0x0007, 0x0002 }, + { 0x000a, 0x0002 }, + { 0x000e, 0x0004 }, + { 0x0011, 0x0007 }, + { 0x0013, 0x0012 }, + { 0x0016, 0x0000 }, + { 0x0016, 0x0001 }, + { 0x0016, 0x0002 }, + { 0x0016, 0x0003 }, + { 0x0016, 0x0004 }, + { 0x0004, 0x0003 }, + { 0x0003, 0x0003 }, + { 0x0004, 0x0004 }, + { 0x0007, 0x0003 }, + { 0x000a, 0x0003 }, + { 0x000d, 0x0004 }, + { 0x0010, 0x0007 }, + { 0x0013, 0x0013 }, + { 0x0015, 0x0035 }, + { 0x0016, 0x0005 }, + { 0x0016, 0x0006 }, + { 0x0016, 0x0007 }, + { 0x0016, 0x0008 }, + { 0x0005, 0x0003 }, + { 0x0004, 0x0005 }, + { 0x0006, 0x0003 }, + { 0x0008, 0x0002 }, + { 0x000b, 0x0002 }, + { 0x000e, 0x0005 }, + { 0x0010, 0x0008 }, + { 0x0013, 0x0014 }, + { 0x0014, 0x001d }, + { 0x0016, 0x0009 }, + { 0x0016, 0x000a }, + { 0x0016, 0x000b }, + { 0x0016, 0x000c }, + { 0x0007, 0x0004 }, + { 0x0007, 0x0005 }, + { 0x0008, 0x0003 }, + { 0x000a, 0x0004 }, + { 0x000d, 0x0005 }, + { 0x000f, 0x0005 }, + { 0x0011, 0x0008 }, + { 0x0014, 0x001e }, + { 0x0014, 0x001f }, + { 0x0016, 0x000d }, + { 0x0016, 0x000e }, + { 0x0016, 0x000f }, + { 0x0016, 0x0010 }, + { 0x000a, 0x0005 }, + { 0x0009, 0x0003 }, + { 0x000b, 0x0003 }, + { 0x000d, 0x0006 }, + { 0x000f, 0x0006 }, + { 0x0011, 0x0009 }, + { 0x0013, 0x0015 }, + { 0x0014, 0x0020 }, + { 0x0016, 0x0011 }, + { 0x0016, 0x0012 }, + { 0x0016, 0x0013 }, + { 0x0016, 0x0014 }, + { 0x0016, 0x0015 }, + { 0x000e, 0x0006 }, + { 0x000d, 0x0007 }, + { 0x000e, 0x0007 }, + { 0x000f, 0x0007 }, + { 0x0011, 0x000a }, + { 0x0012, 0x000c }, + { 0x0016, 0x0016 }, + { 0x0016, 0x0017 }, + { 0x0016, 0x0018 }, + { 0x0016, 0x0019 }, + { 0x0016, 0x001a }, + { 0x0016, 0x001b }, + { 0x0016, 0x001c }, + { 0x0011, 0x000b }, + { 0x0010, 0x0009 }, + { 0x0011, 0x000c }, + { 0x0011, 0x000d }, + { 0x0013, 0x0016 }, + { 0x0016, 0x001d }, + { 0x0016, 0x001e }, + { 0x0016, 0x001f }, + { 0x0016, 0x0020 }, + { 0x0016, 0x0021 }, + { 0x0016, 0x0022 }, + { 0x0016, 0x0023 }, + { 0x0016, 0x0024 }, + { 0x0014, 0x0021 }, + { 0x0014, 0x0022 }, + { 0x0012, 0x000d }, + { 0x0013, 0x0017 }, + { 0x0016, 0x0025 }, + { 0x0016, 0x0026 }, + { 0x0016, 0x0027 }, + { 0x0016, 0x0028 }, + { 0x0016, 0x0029 }, + { 0x0016, 0x002a }, + { 0x0016, 0x002b }, + { 0x0016, 0x002c }, + { 0x0016, 0x002d }, + { 0x0015, 0x0036 }, + { 0x0015, 0x0037 }, + { 0x0014, 0x0023 }, + { 0x0015, 0x0038 }, + { 0x0016, 0x002e }, + { 0x0016, 0x002f }, + { 0x0016, 0x0030 }, + { 0x0016, 0x0031 }, + { 0x0016, 0x0032 }, + { 0x0016, 0x0033 }, + { 0x0016, 0x0034 }, + { 0x0016, 0x0035 }, + { 0x0016, 0x0036 }, + { 0x0016, 0x0037 }, + { 0x0016, 0x0038 }, + { 0x0016, 0x0039 }, + { 0x0016, 0x003a }, + { 0x0016, 0x003b }, + { 0x0016, 0x003c }, + { 0x0016, 0x003d }, + { 0x0016, 0x003e }, + { 0x0016, 0x003f }, + { 0x0016, 0x0040 }, + { 0x0016, 0x0041 }, + { 0x0016, 0x0042 }, + { 0x0016, 0x0043 }, + { 0x0016, 0x0044 }, + { 0x0016, 0x0045 }, + { 0x0016, 0x0046 }, + { 0x0016, 0x0047 }, + { 0x0016, 0x0048 }, + { 0x0016, 0x0049 }, + { 0x0016, 0x004a }, + { 0x0016, 0x004b }, + { 0x0016, 0x004c }, + { 0x0016, 0x004d }, + { 0x0016, 0x004e }, + { 0x0016, 0x004f }, + { 0x0016, 0x0050 }, + { 0x0016, 0x0051 }, + { 0x0016, 0x0052 }, + { 0x0016, 0x0053 }, + { 0x0016, 0x0054 }, + { 0x0016, 0x0055 }, + { 0x0016, 0x0056 }, + { 0x0016, 0x0057 }, + { 0x0016, 0x0058 }, + { 0x0016, 0x0059 }, + { 0x0016, 0x005a }, + { 0x0016, 0x005b }, + { 0x0016, 0x005c }, + { 0x0016, 0x005d }, + { 0x0016, 0x005e }, + { 0x0016, 0x005f }, + { 0x0016, 0x0060 }, + { 0x0016, 0x0061 }, + { 0x0016, 0x0062 }, + { 0x0016, 0x0063 }, + { 0x0016, 0x0064 }, + { 0x0016, 0x0065 }, + { 0x0016, 0x0066 }, + { 0x0016, 0x0067 }, + { 0x0016, 0x0068 }, + { 0x0016, 0x0069 }, + { 0x0015, 0x0039 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc11[196][2] = + { + { 0x0001, 0x0001 }, + { 0x0004, 0x0003 }, + { 0x0005, 0x0003 }, + { 0x0007, 0x0002 }, + { 0x0009, 0x0003 }, + { 0x000c, 0x0004 }, + { 0x000f, 0x0005 }, + { 0x0012, 0x000d }, + { 0x0014, 0x001f }, + { 0x0016, 0x0000 }, + { 0x0016, 0x0001 }, + { 0x0016, 0x0002 }, + { 0x0016, 0x0003 }, + { 0x0016, 0x0004 }, + { 0x0004, 0x0004 }, + { 0x0003, 0x0003 }, + { 0x0005, 0x0004 }, + { 0x0006, 0x0003 }, + { 0x0009, 0x0004 }, + { 0x000b, 0x0004 }, + { 0x000e, 0x0005 }, + { 0x0010, 0x0007 }, + { 0x0012, 0x000e }, + { 0x0014, 0x0020 }, + { 0x0016, 0x0005 }, + { 0x0016, 0x0006 }, + { 0x0016, 0x0007 }, + { 0x0016, 0x0008 }, + { 0x0005, 0x0005 }, + { 0x0004, 0x0005 }, + { 0x0006, 0x0004 }, + { 0x0007, 0x0003 }, + { 0x000a, 0x0004 }, + { 0x000c, 0x0005 }, + { 0x000e, 0x0006 }, + { 0x0011, 0x000a }, + { 0x0012, 0x000f }, + { 0x0015, 0x003b }, + { 0x0016, 0x0009 }, + { 0x0016, 0x000a }, + { 0x0016, 0x000b }, + { 0x0016, 0x000c }, + { 0x0007, 0x0004 }, + { 0x0006, 0x0005 }, + { 0x0007, 0x0005 }, + { 0x0009, 0x0005 }, + { 0x000b, 0x0005 }, + { 0x000d, 0x0005 }, + { 0x000f, 0x0006 }, + { 0x0012, 0x0010 }, + { 0x0014, 0x0021 }, + { 0x0016, 0x000d }, + { 0x0016, 0x000e }, + { 0x0016, 0x000f }, + { 0x0016, 0x0010 }, + { 0x0016, 0x0011 }, + { 0x0009, 0x0006 }, + { 0x0009, 0x0007 }, + { 0x000a, 0x0005 }, + { 0x000b, 0x0006 }, + { 0x000d, 0x0006 }, + { 0x000f, 0x0007 }, + { 0x0011, 0x000b }, + { 0x0013, 0x0017 }, + { 0x0014, 0x0022 }, + { 0x0016, 0x0012 }, + { 0x0016, 0x0013 }, + { 0x0016, 0x0014 }, + { 0x0016, 0x0015 }, + { 0x0016, 0x0016 }, + { 0x000c, 0x0006 }, + { 0x000b, 0x0007 }, + { 0x000c, 0x0007 }, + { 0x000d, 0x0007 }, + { 0x000e, 0x0007 }, + { 0x0010, 0x0008 }, + { 0x0012, 0x0011 }, + { 0x0014, 0x0023 }, + { 0x0015, 0x003c }, + { 0x0016, 0x0017 }, + { 0x0016, 0x0018 }, + { 0x0016, 0x0019 }, + { 0x0016, 0x001a }, + { 0x0016, 0x001b }, + { 0x000f, 0x0008 }, + { 0x000e, 0x0008 }, + { 0x000e, 0x0009 }, + { 0x000f, 0x0009 }, + { 0x0011, 0x000c }, + { 0x0013, 0x0018 }, + { 0x0014, 0x0024 }, + { 0x0016, 0x001c }, + { 0x0016, 0x001d }, + { 0x0016, 0x001e }, + { 0x0016, 0x001f }, + { 0x0016, 0x0020 }, + { 0x0016, 0x0021 }, + { 0x0016, 0x0022 }, + { 0x0011, 0x000d }, + { 0x0010, 0x0009 }, + { 0x0012, 0x0012 }, + { 0x0012, 0x0013 }, + { 0x0014, 0x0025 }, + { 0x0015, 0x003d }, + { 0x0014, 0x0026 }, + { 0x0016, 0x0023 }, + { 0x0016, 0x0024 }, + { 0x0016, 0x0025 }, + { 0x0016, 0x0026 }, + { 0x0016, 0x0027 }, + { 0x0016, 0x0028 }, + { 0x0016, 0x0029 }, + { 0x0014, 0x0027 }, + { 0x0013, 0x0019 }, + { 0x0014, 0x0028 }, + { 0x0014, 0x0029 }, + { 0x0014, 0x002a }, + { 0x0016, 0x002a }, + { 0x0016, 0x002b }, + { 0x0016, 0x002c }, + { 0x0016, 0x002d }, + { 0x0016, 0x002e }, + { 0x0016, 0x002f }, + { 0x0016, 0x0030 }, + { 0x0016, 0x0031 }, + { 0x0016, 0x0032 }, + { 0x0014, 0x002b }, + { 0x0014, 0x002c }, + { 0x0014, 0x002d }, + { 0x0016, 0x0033 }, + { 0x0016, 0x0034 }, + { 0x0016, 0x0035 }, + { 0x0016, 0x0036 }, + { 0x0016, 0x0037 }, + { 0x0016, 0x0038 }, + { 0x0016, 0x0039 }, + { 0x0016, 0x003a }, + { 0x0016, 0x003b }, + { 0x0016, 0x003c }, + { 0x0016, 0x003d }, + { 0x0016, 0x003e }, + { 0x0016, 0x003f }, + { 0x0016, 0x0040 }, + { 0x0016, 0x0041 }, + { 0x0016, 0x0042 }, + { 0x0016, 0x0043 }, + { 0x0016, 0x0044 }, + { 0x0016, 0x0045 }, + { 0x0016, 0x0046 }, + { 0x0016, 0x0047 }, + { 0x0016, 0x0048 }, + { 0x0016, 0x0049 }, + { 0x0016, 0x004a }, + { 0x0016, 0x004b }, + { 0x0016, 0x004c }, + { 0x0016, 0x004d }, + { 0x0016, 0x004e }, + { 0x0016, 0x004f }, + { 0x0016, 0x0050 }, + { 0x0016, 0x0051 }, + { 0x0016, 0x0052 }, + { 0x0016, 0x0053 }, + { 0x0016, 0x0054 }, + { 0x0016, 0x0055 }, + { 0x0016, 0x0056 }, + { 0x0016, 0x0057 }, + { 0x0016, 0x0058 }, + { 0x0016, 0x0059 }, + { 0x0016, 0x005a }, + { 0x0016, 0x005b }, + { 0x0016, 0x005c }, + { 0x0016, 0x005d }, + { 0x0016, 0x005e }, + { 0x0016, 0x005f }, + { 0x0016, 0x0060 }, + { 0x0016, 0x0061 }, + { 0x0016, 0x0062 }, + { 0x0016, 0x0063 }, + { 0x0016, 0x0064 }, + { 0x0016, 0x0065 }, + { 0x0016, 0x0066 }, + { 0x0016, 0x0067 }, + { 0x0016, 0x0068 }, + { 0x0016, 0x0069 }, + { 0x0016, 0x006a }, + { 0x0016, 0x006b }, + { 0x0016, 0x006c }, + { 0x0016, 0x006d }, + { 0x0016, 0x006e }, + { 0x0016, 0x006f }, + { 0x0016, 0x0070 }, + { 0x0016, 0x0071 }, + { 0x0016, 0x0072 }, + { 0x0016, 0x0073 }, + { 0x0016, 0x0074 }, + { 0x0016, 0x0075 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc12[289][2] = + { + { 0x0001, 0x0001 }, + { 0x0004, 0x0004 }, + { 0x0005, 0x0004 }, + { 0x0007, 0x0004 }, + { 0x0008, 0x0002 }, + { 0x000b, 0x0004 }, + { 0x000e, 0x0006 }, + { 0x0010, 0x0009 }, + { 0x0012, 0x0014 }, + { 0x0013, 0x001f }, + { 0x0016, 0x0000 }, + { 0x0016, 0x0001 }, + { 0x0016, 0x0002 }, + { 0x0016, 0x0003 }, + { 0x0016, 0x0004 }, + { 0x0016, 0x0005 }, + { 0x0016, 0x0006 }, + { 0x0004, 0x0005 }, + { 0x0004, 0x0006 }, + { 0x0005, 0x0005 }, + { 0x0006, 0x0003 }, + { 0x0008, 0x0003 }, + { 0x000a, 0x0004 }, + { 0x000d, 0x0006 }, + { 0x000f, 0x0008 }, + { 0x0011, 0x000c }, + { 0x0013, 0x0020 }, + { 0x0016, 0x0007 }, + { 0x0015, 0x0063 }, + { 0x0016, 0x0008 }, + { 0x0016, 0x0009 }, + { 0x0016, 0x000a }, + { 0x0016, 0x000b }, + { 0x0016, 0x000c }, + { 0x0005, 0x0006 }, + { 0x0004, 0x0007 }, + { 0x0005, 0x0007 }, + { 0x0006, 0x0004 }, + { 0x0008, 0x0004 }, + { 0x000b, 0x0005 }, + { 0x000d, 0x0007 }, + { 0x0010, 0x000a }, + { 0x0012, 0x0015 }, + { 0x0015, 0x0064 }, + { 0x0016, 0x000d }, + { 0x0016, 0x000e }, + { 0x0016, 0x000f }, + { 0x0016, 0x0010 }, + { 0x0016, 0x0011 }, + { 0x0016, 0x0012 }, + { 0x0016, 0x0013 }, + { 0x0006, 0x0005 }, + { 0x0006, 0x0006 }, + { 0x0006, 0x0007 }, + { 0x0008, 0x0005 }, + { 0x000a, 0x0005 }, + { 0x000c, 0x0005 }, + { 0x000e, 0x0007 }, + { 0x0010, 0x000b }, + { 0x0012, 0x0016 }, + { 0x0014, 0x0037 }, + { 0x0015, 0x0065 }, + { 0x0016, 0x0014 }, + { 0x0016, 0x0015 }, + { 0x0016, 0x0016 }, + { 0x0016, 0x0017 }, + { 0x0016, 0x0018 }, + { 0x0016, 0x0019 }, + { 0x0008, 0x0006 }, + { 0x0007, 0x0005 }, + { 0x0008, 0x0007 }, + { 0x000a, 0x0006 }, + { 0x000c, 0x0006 }, + { 0x000e, 0x0008 }, + { 0x0010, 0x000c }, + { 0x0011, 0x000d }, + { 0x0013, 0x0021 }, + { 0x0015, 0x0066 }, + { 0x0016, 0x001a }, + { 0x0016, 0x001b }, + { 0x0016, 0x001c }, + { 0x0016, 0x001d }, + { 0x0016, 0x001e }, + { 0x0016, 0x001f }, + { 0x0016, 0x0020 }, + { 0x000b, 0x0006 }, + { 0x000a, 0x0007 }, + { 0x000b, 0x0007 }, + { 0x000c, 0x0007 }, + { 0x000e, 0x0009 }, + { 0x000f, 0x0009 }, + { 0x0011, 0x000e }, + { 0x0013, 0x0022 }, + { 0x0015, 0x0067 }, + { 0x0015, 0x0068 }, + { 0x0016, 0x0021 }, + { 0x0016, 0x0022 }, + { 0x0016, 0x0023 }, + { 0x0016, 0x0024 }, + { 0x0016, 0x0025 }, + { 0x0016, 0x0026 }, + { 0x0016, 0x0027 }, + { 0x000e, 0x000a }, + { 0x000d, 0x0008 }, + { 0x000d, 0x0009 }, + { 0x000e, 0x000b }, + { 0x000f, 0x000a }, + { 0x0011, 0x000f }, + { 0x0013, 0x0023 }, + { 0x0014, 0x0038 }, + { 0x0016, 0x0028 }, + { 0x0016, 0x0029 }, + { 0x0016, 0x002a }, + { 0x0016, 0x002b }, + { 0x0016, 0x002c }, + { 0x0016, 0x002d }, + { 0x0016, 0x002e }, + { 0x0016, 0x002f }, + { 0x0016, 0x0030 }, + { 0x0010, 0x000d }, + { 0x000f, 0x000b }, + { 0x0010, 0x000e }, + { 0x0010, 0x000f }, + { 0x0012, 0x0017 }, + { 0x0013, 0x0024 }, + { 0x0014, 0x0039 }, + { 0x0016, 0x0031 }, + { 0x0016, 0x0032 }, + { 0x0016, 0x0033 }, + { 0x0016, 0x0034 }, + { 0x0016, 0x0035 }, + { 0x0016, 0x0036 }, + { 0x0016, 0x0037 }, + { 0x0016, 0x0038 }, + { 0x0016, 0x0039 }, + { 0x0016, 0x003a }, + { 0x0013, 0x0025 }, + { 0x0011, 0x0010 }, + { 0x0011, 0x0011 }, + { 0x0013, 0x0026 }, + { 0x0013, 0x0027 }, + { 0x0014, 0x003a }, + { 0x0014, 0x003b }, + { 0x0016, 0x003b }, + { 0x0016, 0x003c }, + { 0x0016, 0x003d }, + { 0x0016, 0x003e }, + { 0x0016, 0x003f }, + { 0x0016, 0x0040 }, + { 0x0016, 0x0041 }, + { 0x0016, 0x0042 }, + { 0x0016, 0x0043 }, + { 0x0016, 0x0044 }, + { 0x0015, 0x0069 }, + { 0x0014, 0x003c }, + { 0x0014, 0x003d }, + { 0x0015, 0x006a }, + { 0x0015, 0x006b }, + { 0x0015, 0x006c }, + { 0x0016, 0x0045 }, + { 0x0016, 0x0046 }, + { 0x0016, 0x0047 }, + { 0x0016, 0x0048 }, + { 0x0016, 0x0049 }, + { 0x0016, 0x004a }, + { 0x0016, 0x004b }, + { 0x0016, 0x004c }, + { 0x0016, 0x004d }, + { 0x0016, 0x004e }, + { 0x0016, 0x004f }, + { 0x0016, 0x0050 }, + { 0x0016, 0x0051 }, + { 0x0015, 0x006d }, + { 0x0016, 0x0052 }, + { 0x0016, 0x0053 }, + { 0x0016, 0x0054 }, + { 0x0016, 0x0055 }, + { 0x0016, 0x0056 }, + { 0x0016, 0x0057 }, + { 0x0016, 0x0058 }, + { 0x0016, 0x0059 }, + { 0x0016, 0x005a }, + { 0x0016, 0x005b }, + { 0x0016, 0x005c }, + { 0x0016, 0x005d }, + { 0x0016, 0x005e }, + { 0x0016, 0x005f }, + { 0x0016, 0x0060 }, + { 0x0016, 0x0061 }, + { 0x0016, 0x0062 }, + { 0x0016, 0x0063 }, + { 0x0016, 0x0064 }, + { 0x0016, 0x0065 }, + { 0x0016, 0x0066 }, + { 0x0016, 0x0067 }, + { 0x0016, 0x0068 }, + { 0x0016, 0x0069 }, + { 0x0016, 0x006a }, + { 0x0016, 0x006b }, + { 0x0016, 0x006c }, + { 0x0016, 0x006d }, + { 0x0016, 0x006e }, + { 0x0016, 0x006f }, + { 0x0016, 0x0070 }, + { 0x0016, 0x0071 }, + { 0x0016, 0x0072 }, + { 0x0016, 0x0073 }, + { 0x0016, 0x0074 }, + { 0x0016, 0x0075 }, + { 0x0016, 0x0076 }, + { 0x0016, 0x0077 }, + { 0x0016, 0x0078 }, + { 0x0016, 0x0079 }, + { 0x0016, 0x007a }, + { 0x0016, 0x007b }, + { 0x0016, 0x007c }, + { 0x0016, 0x007d }, + { 0x0016, 0x007e }, + { 0x0016, 0x007f }, + { 0x0016, 0x0080 }, + { 0x0016, 0x0081 }, + { 0x0016, 0x0082 }, + { 0x0016, 0x0083 }, + { 0x0016, 0x0084 }, + { 0x0016, 0x0085 }, + { 0x0016, 0x0086 }, + { 0x0016, 0x0087 }, + { 0x0016, 0x0088 }, + { 0x0016, 0x0089 }, + { 0x0016, 0x008a }, + { 0x0016, 0x008b }, + { 0x0016, 0x008c }, + { 0x0016, 0x008d }, + { 0x0016, 0x008e }, + { 0x0016, 0x008f }, + { 0x0016, 0x0090 }, + { 0x0016, 0x0091 }, + { 0x0016, 0x0092 }, + { 0x0016, 0x0093 }, + { 0x0016, 0x0094 }, + { 0x0016, 0x0095 }, + { 0x0016, 0x0096 }, + { 0x0016, 0x0097 }, + { 0x0016, 0x0098 }, + { 0x0016, 0x0099 }, + { 0x0016, 0x009a }, + { 0x0016, 0x009b }, + { 0x0016, 0x009c }, + { 0x0016, 0x009d }, + { 0x0016, 0x009e }, + { 0x0016, 0x009f }, + { 0x0016, 0x00a0 }, + { 0x0016, 0x00a1 }, + { 0x0016, 0x00a2 }, + { 0x0016, 0x00a3 }, + { 0x0016, 0x00a4 }, + { 0x0016, 0x00a5 }, + { 0x0016, 0x00a6 }, + { 0x0016, 0x00a7 }, + { 0x0016, 0x00a8 }, + { 0x0016, 0x00a9 }, + { 0x0016, 0x00aa }, + { 0x0016, 0x00ab }, + { 0x0016, 0x00ac }, + { 0x0016, 0x00ad }, + { 0x0016, 0x00ae }, + { 0x0016, 0x00af }, + { 0x0016, 0x00b0 }, + { 0x0016, 0x00b1 }, + { 0x0016, 0x00b2 }, + { 0x0016, 0x00b3 }, + { 0x0016, 0x00b4 }, + { 0x0016, 0x00b5 }, + { 0x0016, 0x00b6 }, + { 0x0016, 0x00b7 }, + { 0x0016, 0x00b8 }, + { 0x0016, 0x00b9 }, + { 0x0016, 0x00ba }, + { 0x0016, 0x00bb }, + { 0x0016, 0x00bc }, + { 0x0016, 0x00bd }, + { 0x0016, 0x00be }, + { 0x0016, 0x00bf }, + { 0x0016, 0x00c0 }, + { 0x0016, 0x00c1 }, + { 0x0016, 0x00c2 }, + { 0x0016, 0x00c3 }, + { 0x0016, 0x00c4 }, + { 0x0016, 0x00c5 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc13[324][2] = + { + { 0x0004, 0x0006 }, + { 0x0004, 0x0007 }, + { 0x0005, 0x0005 }, + { 0x0005, 0x0006 }, + { 0x0006, 0x0004 }, + { 0x0008, 0x0005 }, + { 0x000a, 0x0005 }, + { 0x000c, 0x0007 }, + { 0x000e, 0x000b }, + { 0x0010, 0x0011 }, + { 0x0012, 0x002d }, + { 0x0015, 0x0000 }, + { 0x0014, 0x0035 }, + { 0x0015, 0x0001 }, + { 0x0015, 0x0002 }, + { 0x0015, 0x0003 }, + { 0x0015, 0x0004 }, + { 0x0015, 0x0005 }, + { 0x0004, 0x0008 }, + { 0x0003, 0x0007 }, + { 0x0004, 0x0009 }, + { 0x0004, 0x000a }, + { 0x0006, 0x0005 }, + { 0x0008, 0x0006 }, + { 0x0009, 0x0006 }, + { 0x000c, 0x0008 }, + { 0x000d, 0x0009 }, + { 0x0010, 0x0012 }, + { 0x0011, 0x001a }, + { 0x0015, 0x0006 }, + { 0x0015, 0x0007 }, + { 0x0015, 0x0008 }, + { 0x0015, 0x0009 }, + { 0x0015, 0x000a }, + { 0x0015, 0x000b }, + { 0x0015, 0x000c }, + { 0x0005, 0x0007 }, + { 0x0004, 0x000b }, + { 0x0004, 0x000c }, + { 0x0005, 0x0008 }, + { 0x0006, 0x0006 }, + { 0x0008, 0x0007 }, + { 0x000a, 0x0006 }, + { 0x000c, 0x0009 }, + { 0x000e, 0x000c }, + { 0x0010, 0x0013 }, + { 0x0012, 0x002e }, + { 0x0015, 0x000d }, + { 0x0015, 0x000e }, + { 0x0015, 0x000f }, + { 0x0015, 0x0010 }, + { 0x0015, 0x0011 }, + { 0x0015, 0x0012 }, + { 0x0015, 0x0013 }, + { 0x0005, 0x0009 }, + { 0x0004, 0x000d }, + { 0x0005, 0x000a }, + { 0x0006, 0x0007 }, + { 0x0007, 0x0005 }, + { 0x0009, 0x0007 }, + { 0x000b, 0x0008 }, + { 0x000d, 0x000a }, + { 0x000f, 0x000e }, + { 0x0010, 0x0014 }, + { 0x0011, 0x001b }, + { 0x0014, 0x0036 }, + { 0x0015, 0x0014 }, + { 0x0015, 0x0015 }, + { 0x0015, 0x0016 }, + { 0x0015, 0x0017 }, + { 0x0015, 0x0018 }, + { 0x0015, 0x0019 }, + { 0x0006, 0x0008 }, + { 0x0005, 0x000b }, + { 0x0006, 0x0009 }, + { 0x0007, 0x0006 }, + { 0x0009, 0x0008 }, + { 0x000a, 0x0007 }, + { 0x000c, 0x000a }, + { 0x000e, 0x000d }, + { 0x0010, 0x0015 }, + { 0x0011, 0x001c }, + { 0x0013, 0x0053 }, + { 0x0015, 0x001a }, + { 0x0015, 0x001b }, + { 0x0015, 0x001c }, + { 0x0015, 0x001d }, + { 0x0015, 0x001e }, + { 0x0015, 0x001f }, + { 0x0015, 0x0020 }, + { 0x0008, 0x0008 }, + { 0x0007, 0x0007 }, + { 0x0008, 0x0009 }, + { 0x0009, 0x0009 }, + { 0x000a, 0x0008 }, + { 0x000c, 0x000b }, + { 0x000d, 0x000b }, + { 0x000f, 0x000f }, + { 0x0010, 0x0016 }, + { 0x0011, 0x001d }, + { 0x0014, 0x0037 }, + { 0x0015, 0x0021 }, + { 0x0015, 0x0022 }, + { 0x0015, 0x0023 }, + { 0x0015, 0x0024 }, + { 0x0015, 0x0025 }, + { 0x0015, 0x0026 }, + { 0x0015, 0x0027 }, + { 0x000a, 0x0009 }, + { 0x000a, 0x000a }, + { 0x000a, 0x000b }, + { 0x000b, 0x0009 }, + { 0x000c, 0x000c }, + { 0x000d, 0x000c }, + { 0x000f, 0x0010 }, + { 0x0010, 0x0017 }, + { 0x0012, 0x002f }, + { 0x0015, 0x0028 }, + { 0x0015, 0x0029 }, + { 0x0015, 0x002a }, + { 0x0015, 0x002b }, + { 0x0015, 0x002c }, + { 0x0015, 0x002d }, + { 0x0015, 0x002e }, + { 0x0015, 0x002f }, + { 0x0015, 0x0030 }, + { 0x000c, 0x000d }, + { 0x000c, 0x000e }, + { 0x000c, 0x000f }, + { 0x000d, 0x000d }, + { 0x000e, 0x000e }, + { 0x000f, 0x0011 }, + { 0x0010, 0x0018 }, + { 0x0011, 0x001e }, + { 0x0014, 0x0038 }, + { 0x0015, 0x0031 }, + { 0x0015, 0x0032 }, + { 0x0015, 0x0033 }, + { 0x0015, 0x0034 }, + { 0x0015, 0x0035 }, + { 0x0015, 0x0036 }, + { 0x0015, 0x0037 }, + { 0x0015, 0x0038 }, + { 0x0015, 0x0039 }, + { 0x000f, 0x0012 }, + { 0x000e, 0x000f }, + { 0x000e, 0x0010 }, + { 0x000e, 0x0011 }, + { 0x000f, 0x0013 }, + { 0x0010, 0x0019 }, + { 0x0011, 0x001f }, + { 0x0013, 0x0054 }, + { 0x0015, 0x003a }, + { 0x0014, 0x0039 }, + { 0x0015, 0x003b }, + { 0x0015, 0x003c }, + { 0x0015, 0x003d }, + { 0x0015, 0x003e }, + { 0x0015, 0x003f }, + { 0x0015, 0x0040 }, + { 0x0015, 0x0041 }, + { 0x0015, 0x0042 }, + { 0x0010, 0x001a }, + { 0x000f, 0x0014 }, + { 0x000f, 0x0015 }, + { 0x0010, 0x001b }, + { 0x0011, 0x0020 }, + { 0x0012, 0x0030 }, + { 0x0013, 0x0055 }, + { 0x0015, 0x0043 }, + { 0x0015, 0x0044 }, + { 0x0014, 0x003a }, + { 0x0015, 0x0045 }, + { 0x0015, 0x0046 }, + { 0x0015, 0x0047 }, + { 0x0015, 0x0048 }, + { 0x0015, 0x0049 }, + { 0x0015, 0x004a }, + { 0x0015, 0x004b }, + { 0x0015, 0x004c }, + { 0x0012, 0x0031 }, + { 0x0011, 0x0021 }, + { 0x0013, 0x0056 }, + { 0x0013, 0x0057 }, + { 0x0012, 0x0032 }, + { 0x0015, 0x004d }, + { 0x0015, 0x004e }, + { 0x0015, 0x004f }, + { 0x0015, 0x0050 }, + { 0x0015, 0x0051 }, + { 0x0015, 0x0052 }, + { 0x0015, 0x0053 }, + { 0x0015, 0x0054 }, + { 0x0015, 0x0055 }, + { 0x0015, 0x0056 }, + { 0x0015, 0x0057 }, + { 0x0015, 0x0058 }, + { 0x0015, 0x0059 }, + { 0x0015, 0x005a }, + { 0x0014, 0x003b }, + { 0x0012, 0x0033 }, + { 0x0013, 0x0058 }, + { 0x0013, 0x0059 }, + { 0x0015, 0x005b }, + { 0x0015, 0x005c }, + { 0x0015, 0x005d }, + { 0x0015, 0x005e }, + { 0x0015, 0x005f }, + { 0x0015, 0x0060 }, + { 0x0015, 0x0061 }, + { 0x0015, 0x0062 }, + { 0x0015, 0x0063 }, + { 0x0015, 0x0064 }, + { 0x0015, 0x0065 }, + { 0x0015, 0x0066 }, + { 0x0015, 0x0067 }, + { 0x0015, 0x0068 }, + { 0x0015, 0x0069 }, + { 0x0014, 0x003c }, + { 0x0014, 0x003d }, + { 0x0014, 0x003e }, + { 0x0014, 0x003f }, + { 0x0014, 0x0040 }, + { 0x0014, 0x0041 }, + { 0x0014, 0x0042 }, + { 0x0014, 0x0043 }, + { 0x0014, 0x0044 }, + { 0x0014, 0x0045 }, + { 0x0014, 0x0046 }, + { 0x0014, 0x0047 }, + { 0x0014, 0x0048 }, + { 0x0014, 0x0049 }, + { 0x0014, 0x004a }, + { 0x0014, 0x004b }, + { 0x0014, 0x004c }, + { 0x0014, 0x004d }, + { 0x0014, 0x004e }, + { 0x0014, 0x004f }, + { 0x0014, 0x0050 }, + { 0x0014, 0x0051 }, + { 0x0014, 0x0052 }, + { 0x0014, 0x0053 }, + { 0x0014, 0x0054 }, + { 0x0014, 0x0055 }, + { 0x0014, 0x0056 }, + { 0x0014, 0x0057 }, + { 0x0014, 0x0058 }, + { 0x0014, 0x0059 }, + { 0x0014, 0x005a }, + { 0x0014, 0x005b }, + { 0x0014, 0x005c }, + { 0x0014, 0x005d }, + { 0x0014, 0x005e }, + { 0x0014, 0x005f }, + { 0x0014, 0x0060 }, + { 0x0014, 0x0061 }, + { 0x0014, 0x0062 }, + { 0x0014, 0x0063 }, + { 0x0014, 0x0064 }, + { 0x0014, 0x0065 }, + { 0x0014, 0x0066 }, + { 0x0014, 0x0067 }, + { 0x0014, 0x0068 }, + { 0x0014, 0x0069 }, + { 0x0014, 0x006a }, + { 0x0014, 0x006b }, + { 0x0014, 0x006c }, + { 0x0014, 0x006d }, + { 0x0014, 0x006e }, + { 0x0014, 0x006f }, + { 0x0014, 0x0070 }, + { 0x0014, 0x0071 }, + { 0x0014, 0x0072 }, + { 0x0014, 0x0073 }, + { 0x0014, 0x0074 }, + { 0x0014, 0x0075 }, + { 0x0014, 0x0076 }, + { 0x0014, 0x0077 }, + { 0x0014, 0x0078 }, + { 0x0014, 0x0079 }, + { 0x0014, 0x007a }, + { 0x0014, 0x007b }, + { 0x0014, 0x007c }, + { 0x0014, 0x007d }, + { 0x0014, 0x007e }, + { 0x0014, 0x007f }, + { 0x0014, 0x0080 }, + { 0x0014, 0x0081 }, + { 0x0014, 0x0082 }, + { 0x0014, 0x0083 }, + { 0x0014, 0x0084 }, + { 0x0014, 0x0085 }, + { 0x0014, 0x0086 }, + { 0x0014, 0x0087 }, + { 0x0014, 0x0088 }, + { 0x0014, 0x0089 }, + { 0x0014, 0x008a }, + { 0x0014, 0x008b }, + { 0x0014, 0x008c }, + { 0x0014, 0x008d }, + { 0x0014, 0x008e }, + { 0x0014, 0x008f }, + { 0x0014, 0x0090 }, + { 0x0014, 0x0091 }, + { 0x0014, 0x0092 }, + { 0x0014, 0x0093 }, + { 0x0014, 0x0094 }, + { 0x0014, 0x0095 }, + { 0x0014, 0x0096 }, + { 0x0014, 0x0097 }, + { 0x0014, 0x0098 }, + { 0x0014, 0x0099 }, + { 0x0014, 0x009a }, + { 0x0014, 0x009b }, + { 0x0014, 0x009c }, + { 0x0014, 0x009d }, + { 0x0014, 0x009e }, + { 0x0014, 0x009f }, + { 0x0014, 0x00a0 }, + { 0x0014, 0x00a1 }, + { 0x0014, 0x00a2 }, + { 0x0014, 0x00a3 }, + { 0x0014, 0x00a4 }, + { 0x0014, 0x00a5 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc14[400][2] = + { + { 0x0005, 0x0007 }, + { 0x0004, 0x0009 }, + { 0x0005, 0x0008 }, + { 0x0005, 0x0009 }, + { 0x0006, 0x0006 }, + { 0x0007, 0x0006 }, + { 0x0009, 0x0007 }, + { 0x000b, 0x0008 }, + { 0x000d, 0x000c }, + { 0x000f, 0x0013 }, + { 0x0010, 0x001b }, + { 0x0013, 0x0082 }, + { 0x0013, 0x0083 }, + { 0x0014, 0x0000 }, + { 0x0014, 0x0001 }, + { 0x0014, 0x0002 }, + { 0x0014, 0x0003 }, + { 0x0014, 0x0004 }, + { 0x0014, 0x0005 }, + { 0x0014, 0x0006 }, + { 0x0004, 0x000a }, + { 0x0004, 0x000b }, + { 0x0004, 0x000c }, + { 0x0005, 0x000a }, + { 0x0005, 0x000b }, + { 0x0006, 0x0007 }, + { 0x0008, 0x0006 }, + { 0x000a, 0x0007 }, + { 0x000c, 0x000a }, + { 0x000e, 0x000e }, + { 0x000f, 0x0014 }, + { 0x0011, 0x002a }, + { 0x0012, 0x004a }, + { 0x0013, 0x0084 }, + { 0x0014, 0x0007 }, + { 0x0014, 0x0008 }, + { 0x0014, 0x0009 }, + { 0x0014, 0x000a }, + { 0x0014, 0x000b }, + { 0x0014, 0x000c }, + { 0x0005, 0x000c }, + { 0x0004, 0x000d }, + { 0x0004, 0x000e }, + { 0x0005, 0x000d }, + { 0x0006, 0x0008 }, + { 0x0007, 0x0007 }, + { 0x0008, 0x0007 }, + { 0x000a, 0x0008 }, + { 0x000c, 0x000b }, + { 0x000e, 0x000f }, + { 0x000f, 0x0015 }, + { 0x0012, 0x004b }, + { 0x0013, 0x0085 }, + { 0x0014, 0x000d }, + { 0x0014, 0x000e }, + { 0x0014, 0x000f }, + { 0x0014, 0x0010 }, + { 0x0014, 0x0011 }, + { 0x0014, 0x0012 }, + { 0x0014, 0x0013 }, + { 0x0005, 0x000e }, + { 0x0004, 0x000f }, + { 0x0005, 0x000f }, + { 0x0005, 0x0010 }, + { 0x0006, 0x0009 }, + { 0x0008, 0x0008 }, + { 0x0009, 0x0008 }, + { 0x000b, 0x0009 }, + { 0x000d, 0x000d }, + { 0x000e, 0x0010 }, + { 0x0010, 0x001c }, + { 0x0011, 0x002b }, + { 0x0014, 0x0014 }, + { 0x0014, 0x0015 }, + { 0x0014, 0x0016 }, + { 0x0014, 0x0017 }, + { 0x0014, 0x0018 }, + { 0x0014, 0x0019 }, + { 0x0014, 0x001a }, + { 0x0014, 0x001b }, + { 0x0006, 0x000a }, + { 0x0005, 0x0011 }, + { 0x0006, 0x000b }, + { 0x0006, 0x000c }, + { 0x0007, 0x0008 }, + { 0x0008, 0x0009 }, + { 0x000a, 0x0009 }, + { 0x000c, 0x000c }, + { 0x000e, 0x0011 }, + { 0x000f, 0x0016 }, + { 0x0010, 0x001d }, + { 0x0012, 0x004c }, + { 0x0014, 0x001c }, + { 0x0014, 0x001d }, + { 0x0014, 0x001e }, + { 0x0014, 0x001f }, + { 0x0014, 0x0020 }, + { 0x0014, 0x0021 }, + { 0x0014, 0x0022 }, + { 0x0014, 0x0023 }, + { 0x0007, 0x0009 }, + { 0x0006, 0x000d }, + { 0x0007, 0x000a }, + { 0x0007, 0x000b }, + { 0x0009, 0x0009 }, + { 0x000a, 0x000a }, + { 0x000b, 0x000a }, + { 0x000d, 0x000e }, + { 0x000f, 0x0017 }, + { 0x0011, 0x002c }, + { 0x0010, 0x001e }, + { 0x0014, 0x0024 }, + { 0x0014, 0x0025 }, + { 0x0014, 0x0026 }, + { 0x0014, 0x0027 }, + { 0x0014, 0x0028 }, + { 0x0014, 0x0029 }, + { 0x0014, 0x002a }, + { 0x0014, 0x002b }, + { 0x0014, 0x002c }, + { 0x0009, 0x000a }, + { 0x0008, 0x000a }, + { 0x0008, 0x000b }, + { 0x0009, 0x000b }, + { 0x000a, 0x000b }, + { 0x000b, 0x000b }, + { 0x000d, 0x000f }, + { 0x000e, 0x0012 }, + { 0x000f, 0x0018 }, + { 0x0011, 0x002d }, + { 0x0011, 0x002e }, + { 0x0013, 0x0086 }, + { 0x0014, 0x002d }, + { 0x0014, 0x002e }, + { 0x0014, 0x002f }, + { 0x0014, 0x0030 }, + { 0x0014, 0x0031 }, + { 0x0014, 0x0032 }, + { 0x0014, 0x0033 }, + { 0x0014, 0x0034 }, + { 0x000b, 0x000c }, + { 0x000a, 0x000c }, + { 0x000a, 0x000d }, + { 0x000b, 0x000d }, + { 0x000c, 0x000d }, + { 0x000d, 0x0010 }, + { 0x000e, 0x0013 }, + { 0x000f, 0x0019 }, + { 0x0010, 0x001f }, + { 0x0013, 0x0087 }, + { 0x0014, 0x0035 }, + { 0x0014, 0x0036 }, + { 0x0013, 0x0088 }, + { 0x0014, 0x0037 }, + { 0x0014, 0x0038 }, + { 0x0014, 0x0039 }, + { 0x0014, 0x003a }, + { 0x0014, 0x003b }, + { 0x0014, 0x003c }, + { 0x0014, 0x003d }, + { 0x000d, 0x0011 }, + { 0x000c, 0x000e }, + { 0x000c, 0x000f }, + { 0x000d, 0x0012 }, + { 0x000d, 0x0013 }, + { 0x000e, 0x0014 }, + { 0x0010, 0x0020 }, + { 0x0010, 0x0021 }, + { 0x0012, 0x004d }, + { 0x0011, 0x002f }, + { 0x0014, 0x003e }, + { 0x0014, 0x003f }, + { 0x0014, 0x0040 }, + { 0x0014, 0x0041 }, + { 0x0014, 0x0042 }, + { 0x0014, 0x0043 }, + { 0x0014, 0x0044 }, + { 0x0014, 0x0045 }, + { 0x0014, 0x0046 }, + { 0x0014, 0x0047 }, + { 0x000f, 0x001a }, + { 0x000e, 0x0015 }, + { 0x000e, 0x0016 }, + { 0x000e, 0x0017 }, + { 0x000f, 0x001b }, + { 0x0011, 0x0030 }, + { 0x0011, 0x0031 }, + { 0x0013, 0x0089 }, + { 0x0013, 0x008a }, + { 0x0013, 0x008b }, + { 0x0014, 0x0048 }, + { 0x0014, 0x0049 }, + { 0x0014, 0x004a }, + { 0x0014, 0x004b }, + { 0x0014, 0x004c }, + { 0x0014, 0x004d }, + { 0x0014, 0x004e }, + { 0x0014, 0x004f }, + { 0x0014, 0x0050 }, + { 0x0014, 0x0051 }, + { 0x0010, 0x0022 }, + { 0x0010, 0x0023 }, + { 0x0010, 0x0024 }, + { 0x0010, 0x0025 }, + { 0x0011, 0x0032 }, + { 0x0011, 0x0033 }, + { 0x0012, 0x004e }, + { 0x0012, 0x004f }, + { 0x0014, 0x0052 }, + { 0x0013, 0x008c }, + { 0x0013, 0x008d }, + { 0x0014, 0x0053 }, + { 0x0014, 0x0054 }, + { 0x0014, 0x0055 }, + { 0x0014, 0x0056 }, + { 0x0014, 0x0057 }, + { 0x0014, 0x0058 }, + { 0x0014, 0x0059 }, + { 0x0014, 0x005a }, + { 0x0014, 0x005b }, + { 0x0011, 0x0034 }, + { 0x0011, 0x0035 }, + { 0x0012, 0x0050 }, + { 0x0012, 0x0051 }, + { 0x0013, 0x008e }, + { 0x0014, 0x005c }, + { 0x0014, 0x005d }, + { 0x0014, 0x005e }, + { 0x0014, 0x005f }, + { 0x0014, 0x0060 }, + { 0x0014, 0x0061 }, + { 0x0014, 0x0062 }, + { 0x0014, 0x0063 }, + { 0x0014, 0x0064 }, + { 0x0014, 0x0065 }, + { 0x0014, 0x0066 }, + { 0x0014, 0x0067 }, + { 0x0014, 0x0068 }, + { 0x0014, 0x0069 }, + { 0x0014, 0x006a }, + { 0x0012, 0x0052 }, + { 0x0013, 0x008f }, + { 0x0013, 0x0090 }, + { 0x0014, 0x006b }, + { 0x0013, 0x0091 }, + { 0x0014, 0x006c }, + { 0x0014, 0x006d }, + { 0x0014, 0x006e }, + { 0x0014, 0x006f }, + { 0x0014, 0x0070 }, + { 0x0014, 0x0071 }, + { 0x0014, 0x0072 }, + { 0x0014, 0x0073 }, + { 0x0014, 0x0074 }, + { 0x0014, 0x0075 }, + { 0x0014, 0x0076 }, + { 0x0014, 0x0077 }, + { 0x0014, 0x0078 }, + { 0x0014, 0x0079 }, + { 0x0014, 0x007a }, + { 0x0014, 0x007b }, + { 0x0014, 0x007c }, + { 0x0013, 0x0092 }, + { 0x0012, 0x0053 }, + { 0x0014, 0x007d }, + { 0x0014, 0x007e }, + { 0x0014, 0x007f }, + { 0x0014, 0x0080 }, + { 0x0014, 0x0081 }, + { 0x0014, 0x0082 }, + { 0x0014, 0x0083 }, + { 0x0014, 0x0084 }, + { 0x0014, 0x0085 }, + { 0x0014, 0x0086 }, + { 0x0014, 0x0087 }, + { 0x0014, 0x0088 }, + { 0x0014, 0x0089 }, + { 0x0014, 0x008a }, + { 0x0014, 0x008b }, + { 0x0014, 0x008c }, + { 0x0014, 0x008d }, + { 0x0014, 0x008e }, + { 0x0013, 0x0093 }, + { 0x0014, 0x008f }, + { 0x0014, 0x0090 }, + { 0x0014, 0x0091 }, + { 0x0014, 0x0092 }, + { 0x0014, 0x0093 }, + { 0x0014, 0x0094 }, + { 0x0014, 0x0095 }, + { 0x0014, 0x0096 }, + { 0x0014, 0x0097 }, + { 0x0014, 0x0098 }, + { 0x0014, 0x0099 }, + { 0x0014, 0x009a }, + { 0x0014, 0x009b }, + { 0x0014, 0x009c }, + { 0x0014, 0x009d }, + { 0x0014, 0x009e }, + { 0x0014, 0x009f }, + { 0x0014, 0x00a0 }, + { 0x0014, 0x00a1 }, + { 0x0014, 0x00a2 }, + { 0x0014, 0x00a3 }, + { 0x0014, 0x00a4 }, + { 0x0014, 0x00a5 }, + { 0x0014, 0x00a6 }, + { 0x0014, 0x00a7 }, + { 0x0014, 0x00a8 }, + { 0x0014, 0x00a9 }, + { 0x0014, 0x00aa }, + { 0x0014, 0x00ab }, + { 0x0014, 0x00ac }, + { 0x0014, 0x00ad }, + { 0x0014, 0x00ae }, + { 0x0014, 0x00af }, + { 0x0014, 0x00b0 }, + { 0x0014, 0x00b1 }, + { 0x0014, 0x00b2 }, + { 0x0014, 0x00b3 }, + { 0x0014, 0x00b4 }, + { 0x0014, 0x00b5 }, + { 0x0014, 0x00b6 }, + { 0x0014, 0x00b7 }, + { 0x0014, 0x00b8 }, + { 0x0014, 0x00b9 }, + { 0x0014, 0x00ba }, + { 0x0014, 0x00bb }, + { 0x0014, 0x00bc }, + { 0x0014, 0x00bd }, + { 0x0014, 0x00be }, + { 0x0014, 0x00bf }, + { 0x0014, 0x00c0 }, + { 0x0014, 0x00c1 }, + { 0x0014, 0x00c2 }, + { 0x0014, 0x00c3 }, + { 0x0014, 0x00c4 }, + { 0x0014, 0x00c5 }, + { 0x0014, 0x00c6 }, + { 0x0014, 0x00c7 }, + { 0x0014, 0x00c8 }, + { 0x0014, 0x00c9 }, + { 0x0014, 0x00ca }, + { 0x0014, 0x00cb }, + { 0x0014, 0x00cc }, + { 0x0014, 0x00cd }, + { 0x0014, 0x00ce }, + { 0x0014, 0x00cf }, + { 0x0014, 0x00d0 }, + { 0x0014, 0x00d1 }, + { 0x0014, 0x00d2 }, + { 0x0014, 0x00d3 }, + { 0x0014, 0x00d4 }, + { 0x0014, 0x00d5 }, + { 0x0014, 0x00d6 }, + { 0x0014, 0x00d7 }, + { 0x0014, 0x00d8 }, + { 0x0014, 0x00d9 }, + { 0x0014, 0x00da }, + { 0x0014, 0x00db }, + { 0x0014, 0x00dc }, + { 0x0014, 0x00dd }, + { 0x0014, 0x00de }, + { 0x0014, 0x00df }, + { 0x0014, 0x00e0 }, + { 0x0014, 0x00e1 }, + { 0x0014, 0x00e2 }, + { 0x0014, 0x00e3 }, + { 0x0014, 0x00e4 }, + { 0x0014, 0x00e5 }, + { 0x0014, 0x00e6 }, + { 0x0014, 0x00e7 }, + { 0x0014, 0x00e8 }, + { 0x0014, 0x00e9 }, + { 0x0014, 0x00ea }, + { 0x0014, 0x00eb }, + { 0x0014, 0x00ec }, + { 0x0014, 0x00ed }, + { 0x0014, 0x00ee }, + { 0x0014, 0x00ef }, + { 0x0014, 0x00f0 }, + { 0x0014, 0x00f1 }, + { 0x0014, 0x00f2 }, + { 0x0014, 0x00f3 }, + { 0x0014, 0x00f4 }, + { 0x0014, 0x00f5 }, + { 0x0014, 0x00f6 }, + { 0x0014, 0x00f7 }, + { 0x0014, 0x00f8 }, + { 0x0014, 0x00f9 }, + { 0x0014, 0x00fa }, + { 0x0014, 0x00fb }, + { 0x0014, 0x00fc }, + { 0x0014, 0x00fd }, + { 0x0014, 0x00fe }, + { 0x0014, 0x00ff }, + { 0x0014, 0x0100 }, + { 0x0014, 0x0101 }, + { 0x0014, 0x0102 }, + { 0x0014, 0x0103 }, + }; + +const uint16_t c_aauiLCLDHuffEnc15[576][2] = + { + { 0x0005, 0x000a }, + { 0x0005, 0x000b }, + { 0x0005, 0x000c }, + { 0x0006, 0x0009 }, + { 0x0006, 0x000a }, + { 0x0007, 0x0008 }, + { 0x0008, 0x0009 }, + { 0x0009, 0x0008 }, + { 0x000b, 0x000b }, + { 0x000d, 0x000e }, + { 0x000e, 0x0011 }, + { 0x000f, 0x001a }, + { 0x0012, 0x006e }, + { 0x0014, 0x0000 }, + { 0x0013, 0x00cc }, + { 0x0014, 0x0001 }, + { 0x0014, 0x0002 }, + { 0x0014, 0x0003 }, + { 0x0014, 0x0004 }, + { 0x0014, 0x0005 }, + { 0x0014, 0x0006 }, + { 0x0014, 0x0007 }, + { 0x0014, 0x0008 }, + { 0x0014, 0x0009 }, + { 0x0005, 0x000d }, + { 0x0004, 0x000c }, + { 0x0004, 0x000d }, + { 0x0005, 0x000e }, + { 0x0005, 0x000f }, + { 0x0006, 0x000b }, + { 0x0007, 0x0009 }, + { 0x0008, 0x000a }, + { 0x000a, 0x000a }, + { 0x000c, 0x000c }, + { 0x000d, 0x000f }, + { 0x000f, 0x001b }, + { 0x0011, 0x003d }, + { 0x0011, 0x003e }, + { 0x0013, 0x00cd }, + { 0x0014, 0x000a }, + { 0x0014, 0x000b }, + { 0x0014, 0x000c }, + { 0x0014, 0x000d }, + { 0x0014, 0x000e }, + { 0x0014, 0x000f }, + { 0x0014, 0x0010 }, + { 0x0014, 0x0011 }, + { 0x0014, 0x0012 }, + { 0x0005, 0x0010 }, + { 0x0004, 0x000e }, + { 0x0004, 0x000f }, + { 0x0005, 0x0011 }, + { 0x0005, 0x0012 }, + { 0x0006, 0x000c }, + { 0x0007, 0x000a }, + { 0x0009, 0x0009 }, + { 0x000a, 0x000b }, + { 0x000c, 0x000d }, + { 0x000e, 0x0012 }, + { 0x0010, 0x0027 }, + { 0x0011, 0x003f }, + { 0x0012, 0x006f }, + { 0x0014, 0x0013 }, + { 0x0014, 0x0014 }, + { 0x0014, 0x0015 }, + { 0x0014, 0x0016 }, + { 0x0014, 0x0017 }, + { 0x0014, 0x0018 }, + { 0x0014, 0x0019 }, + { 0x0014, 0x001a }, + { 0x0014, 0x001b }, + { 0x0014, 0x001c }, + { 0x0006, 0x000d }, + { 0x0005, 0x0013 }, + { 0x0005, 0x0014 }, + { 0x0005, 0x0015 }, + { 0x0006, 0x000e }, + { 0x0007, 0x000b }, + { 0x0008, 0x000b }, + { 0x0009, 0x000a }, + { 0x000b, 0x000c }, + { 0x000c, 0x000e }, + { 0x000e, 0x0013 }, + { 0x000f, 0x001c }, + { 0x0011, 0x0040 }, + { 0x0012, 0x0070 }, + { 0x0014, 0x001d }, + { 0x0014, 0x001e }, + { 0x0014, 0x001f }, + { 0x0014, 0x0020 }, + { 0x0014, 0x0021 }, + { 0x0014, 0x0022 }, + { 0x0014, 0x0023 }, + { 0x0014, 0x0024 }, + { 0x0014, 0x0025 }, + { 0x0014, 0x0026 }, + { 0x0006, 0x000f }, + { 0x0005, 0x0016 }, + { 0x0005, 0x0017 }, + { 0x0006, 0x0010 }, + { 0x0006, 0x0011 }, + { 0x0007, 0x000c }, + { 0x0009, 0x000b }, + { 0x000a, 0x000c }, + { 0x000b, 0x000d }, + { 0x000d, 0x0010 }, + { 0x000e, 0x0014 }, + { 0x0010, 0x0028 }, + { 0x0011, 0x0041 }, + { 0x0013, 0x00ce }, + { 0x0014, 0x0027 }, + { 0x0014, 0x0028 }, + { 0x0014, 0x0029 }, + { 0x0014, 0x002a }, + { 0x0014, 0x002b }, + { 0x0014, 0x002c }, + { 0x0014, 0x002d }, + { 0x0014, 0x002e }, + { 0x0014, 0x002f }, + { 0x0014, 0x0030 }, + { 0x0007, 0x000d }, + { 0x0006, 0x0012 }, + { 0x0006, 0x0013 }, + { 0x0007, 0x000e }, + { 0x0007, 0x000f }, + { 0x0008, 0x000c }, + { 0x0009, 0x000c }, + { 0x000b, 0x000e }, + { 0x000c, 0x000f }, + { 0x000e, 0x0015 }, + { 0x0010, 0x0029 }, + { 0x0011, 0x0042 }, + { 0x0014, 0x0031 }, + { 0x0014, 0x0032 }, + { 0x0014, 0x0033 }, + { 0x0014, 0x0034 }, + { 0x0014, 0x0035 }, + { 0x0014, 0x0036 }, + { 0x0014, 0x0037 }, + { 0x0014, 0x0038 }, + { 0x0014, 0x0039 }, + { 0x0014, 0x003a }, + { 0x0014, 0x003b }, + { 0x0014, 0x003c }, + { 0x0008, 0x000d }, + { 0x0007, 0x0010 }, + { 0x0007, 0x0011 }, + { 0x0008, 0x000e }, + { 0x0009, 0x000d }, + { 0x0009, 0x000e }, + { 0x000b, 0x000f }, + { 0x000c, 0x0010 }, + { 0x000d, 0x0011 }, + { 0x000f, 0x001d }, + { 0x0010, 0x002a }, + { 0x0011, 0x0043 }, + { 0x0014, 0x003d }, + { 0x0013, 0x00cf }, + { 0x0014, 0x003e }, + { 0x0014, 0x003f }, + { 0x0014, 0x0040 }, + { 0x0014, 0x0041 }, + { 0x0014, 0x0042 }, + { 0x0014, 0x0043 }, + { 0x0014, 0x0044 }, + { 0x0014, 0x0045 }, + { 0x0014, 0x0046 }, + { 0x0014, 0x0047 }, + { 0x0009, 0x000f }, + { 0x0008, 0x000f }, + { 0x0009, 0x0010 }, + { 0x0009, 0x0011 }, + { 0x000a, 0x000d }, + { 0x000b, 0x0010 }, + { 0x000c, 0x0011 }, + { 0x000d, 0x0012 }, + { 0x000e, 0x0016 }, + { 0x0010, 0x002b }, + { 0x0011, 0x0044 }, + { 0x0012, 0x0071 }, + { 0x0014, 0x0048 }, + { 0x0014, 0x0049 }, + { 0x0014, 0x004a }, + { 0x0014, 0x004b }, + { 0x0014, 0x004c }, + { 0x0014, 0x004d }, + { 0x0014, 0x004e }, + { 0x0014, 0x004f }, + { 0x0014, 0x0050 }, + { 0x0014, 0x0051 }, + { 0x0014, 0x0052 }, + { 0x0014, 0x0053 }, + { 0x000b, 0x0011 }, + { 0x000a, 0x000e }, + { 0x000a, 0x000f }, + { 0x000b, 0x0012 }, + { 0x000b, 0x0013 }, + { 0x000c, 0x0012 }, + { 0x000d, 0x0013 }, + { 0x000e, 0x0017 }, + { 0x0010, 0x002c }, + { 0x0012, 0x0072 }, + { 0x0011, 0x0045 }, + { 0x0013, 0x00d0 }, + { 0x0013, 0x00d1 }, + { 0x0014, 0x0054 }, + { 0x0014, 0x0055 }, + { 0x0014, 0x0056 }, + { 0x0014, 0x0057 }, + { 0x0014, 0x0058 }, + { 0x0014, 0x0059 }, + { 0x0014, 0x005a }, + { 0x0014, 0x005b }, + { 0x0014, 0x005c }, + { 0x0014, 0x005d }, + { 0x0014, 0x005e }, + { 0x000c, 0x0013 }, + { 0x000c, 0x0014 }, + { 0x000c, 0x0015 }, + { 0x000d, 0x0014 }, + { 0x000d, 0x0015 }, + { 0x000e, 0x0018 }, + { 0x000f, 0x001e }, + { 0x0010, 0x002d }, + { 0x0011, 0x0046 }, + { 0x0011, 0x0047 }, + { 0x0011, 0x0048 }, + { 0x0014, 0x005f }, + { 0x0014, 0x0060 }, + { 0x0014, 0x0061 }, + { 0x0014, 0x0062 }, + { 0x0014, 0x0063 }, + { 0x0014, 0x0064 }, + { 0x0014, 0x0065 }, + { 0x0014, 0x0066 }, + { 0x0014, 0x0067 }, + { 0x0014, 0x0068 }, + { 0x0014, 0x0069 }, + { 0x0014, 0x006a }, + { 0x0014, 0x006b }, + { 0x000e, 0x0019 }, + { 0x000d, 0x0016 }, + { 0x000d, 0x0017 }, + { 0x000e, 0x001a }, + { 0x000e, 0x001b }, + { 0x000f, 0x001f }, + { 0x0010, 0x002e }, + { 0x0011, 0x0049 }, + { 0x0012, 0x0073 }, + { 0x0014, 0x006c }, + { 0x0014, 0x006d }, + { 0x0014, 0x006e }, + { 0x0014, 0x006f }, + { 0x0014, 0x0070 }, + { 0x0014, 0x0071 }, + { 0x0014, 0x0072 }, + { 0x0014, 0x0073 }, + { 0x0014, 0x0074 }, + { 0x0014, 0x0075 }, + { 0x0014, 0x0076 }, + { 0x0014, 0x0077 }, + { 0x0014, 0x0078 }, + { 0x0014, 0x0079 }, + { 0x0014, 0x007a }, + { 0x0010, 0x002f }, + { 0x000f, 0x0020 }, + { 0x0010, 0x0030 }, + { 0x000f, 0x0021 }, + { 0x0010, 0x0031 }, + { 0x0011, 0x004a }, + { 0x0011, 0x004b }, + { 0x0012, 0x0074 }, + { 0x0014, 0x007b }, + { 0x0014, 0x007c }, + { 0x0013, 0x00d2 }, + { 0x0014, 0x007d }, + { 0x0014, 0x007e }, + { 0x0014, 0x007f }, + { 0x0014, 0x0080 }, + { 0x0014, 0x0081 }, + { 0x0014, 0x0082 }, + { 0x0014, 0x0083 }, + { 0x0014, 0x0084 }, + { 0x0014, 0x0085 }, + { 0x0014, 0x0086 }, + { 0x0014, 0x0087 }, + { 0x0014, 0x0088 }, + { 0x0014, 0x0089 }, + { 0x0012, 0x0075 }, + { 0x0010, 0x0032 }, + { 0x0010, 0x0033 }, + { 0x0011, 0x004c }, + { 0x0011, 0x004d }, + { 0x0013, 0x00d3 }, + { 0x0013, 0x00d4 }, + { 0x0012, 0x0076 }, + { 0x0013, 0x00d5 }, + { 0x0014, 0x008a }, + { 0x0014, 0x008b }, + { 0x0014, 0x008c }, + { 0x0014, 0x008d }, + { 0x0014, 0x008e }, + { 0x0014, 0x008f }, + { 0x0014, 0x0090 }, + { 0x0014, 0x0091 }, + { 0x0014, 0x0092 }, + { 0x0014, 0x0093 }, + { 0x0014, 0x0094 }, + { 0x0014, 0x0095 }, + { 0x0014, 0x0096 }, + { 0x0014, 0x0097 }, + { 0x0014, 0x0098 }, + { 0x0013, 0x00d6 }, + { 0x0013, 0x00d7 }, + { 0x0012, 0x0077 }, + { 0x0012, 0x0078 }, + { 0x0014, 0x0099 }, + { 0x0014, 0x009a }, + { 0x0013, 0x00d8 }, + { 0x0014, 0x009b }, + { 0x0014, 0x009c }, + { 0x0014, 0x009d }, + { 0x0014, 0x009e }, + { 0x0014, 0x009f }, + { 0x0014, 0x00a0 }, + { 0x0014, 0x00a1 }, + { 0x0014, 0x00a2 }, + { 0x0014, 0x00a3 }, + { 0x0014, 0x00a4 }, + { 0x0014, 0x00a5 }, + { 0x0014, 0x00a6 }, + { 0x0014, 0x00a7 }, + { 0x0014, 0x00a8 }, + { 0x0014, 0x00a9 }, + { 0x0014, 0x00aa }, + { 0x0014, 0x00ab }, + { 0x0014, 0x00ac }, + { 0x0014, 0x00ad }, + { 0x0014, 0x00ae }, + { 0x0014, 0x00af }, + { 0x0012, 0x0079 }, + { 0x0014, 0x00b0 }, + { 0x0014, 0x00b1 }, + { 0x0014, 0x00b2 }, + { 0x0014, 0x00b3 }, + { 0x0014, 0x00b4 }, + { 0x0014, 0x00b5 }, + { 0x0014, 0x00b6 }, + { 0x0014, 0x00b7 }, + { 0x0014, 0x00b8 }, + { 0x0014, 0x00b9 }, + { 0x0014, 0x00ba }, + { 0x0014, 0x00bb }, + { 0x0014, 0x00bc }, + { 0x0014, 0x00bd }, + { 0x0014, 0x00be }, + { 0x0014, 0x00bf }, + { 0x0014, 0x00c0 }, + { 0x0014, 0x00c1 }, + { 0x0014, 0x00c2 }, + { 0x0014, 0x00c3 }, + { 0x0014, 0x00c4 }, + { 0x0014, 0x00c5 }, + { 0x0014, 0x00c6 }, + { 0x0013, 0x00d9 }, + { 0x0013, 0x00da }, + { 0x0014, 0x00c7 }, + { 0x0014, 0x00c8 }, + { 0x0014, 0x00c9 }, + { 0x0014, 0x00ca }, + { 0x0014, 0x00cb }, + { 0x0014, 0x00cc }, + { 0x0014, 0x00cd }, + { 0x0014, 0x00ce }, + { 0x0014, 0x00cf }, + { 0x0014, 0x00d0 }, + { 0x0014, 0x00d1 }, + { 0x0014, 0x00d2 }, + { 0x0014, 0x00d3 }, + { 0x0014, 0x00d4 }, + { 0x0014, 0x00d5 }, + { 0x0014, 0x00d6 }, + { 0x0014, 0x00d7 }, + { 0x0014, 0x00d8 }, + { 0x0014, 0x00d9 }, + { 0x0014, 0x00da }, + { 0x0014, 0x00db }, + { 0x0014, 0x00dc }, + { 0x0014, 0x00dd }, + { 0x0014, 0x00de }, + { 0x0014, 0x00df }, + { 0x0014, 0x00e0 }, + { 0x0014, 0x00e1 }, + { 0x0014, 0x00e2 }, + { 0x0014, 0x00e3 }, + { 0x0014, 0x00e4 }, + { 0x0014, 0x00e5 }, + { 0x0014, 0x00e6 }, + { 0x0014, 0x00e7 }, + { 0x0014, 0x00e8 }, + { 0x0014, 0x00e9 }, + { 0x0014, 0x00ea }, + { 0x0014, 0x00eb }, + { 0x0014, 0x00ec }, + { 0x0014, 0x00ed }, + { 0x0014, 0x00ee }, + { 0x0014, 0x00ef }, + { 0x0014, 0x00f0 }, + { 0x0014, 0x00f1 }, + { 0x0014, 0x00f2 }, + { 0x0014, 0x00f3 }, + { 0x0014, 0x00f4 }, + { 0x0014, 0x00f5 }, + { 0x0014, 0x00f6 }, + { 0x0014, 0x00f7 }, + { 0x0014, 0x00f8 }, + { 0x0014, 0x00f9 }, + { 0x0014, 0x00fa }, + { 0x0014, 0x00fb }, + { 0x0014, 0x00fc }, + { 0x0014, 0x00fd }, + { 0x0014, 0x00fe }, + { 0x0014, 0x00ff }, + { 0x0014, 0x0100 }, + { 0x0014, 0x0101 }, + { 0x0014, 0x0102 }, + { 0x0014, 0x0103 }, + { 0x0014, 0x0104 }, + { 0x0014, 0x0105 }, + { 0x0014, 0x0106 }, + { 0x0014, 0x0107 }, + { 0x0014, 0x0108 }, + { 0x0014, 0x0109 }, + { 0x0014, 0x010a }, + { 0x0014, 0x010b }, + { 0x0014, 0x010c }, + { 0x0014, 0x010d }, + { 0x0014, 0x010e }, + { 0x0014, 0x010f }, + { 0x0014, 0x0110 }, + { 0x0014, 0x0111 }, + { 0x0014, 0x0112 }, + { 0x0014, 0x0113 }, + { 0x0014, 0x0114 }, + { 0x0014, 0x0115 }, + { 0x0014, 0x0116 }, + { 0x0014, 0x0117 }, + { 0x0014, 0x0118 }, + { 0x0014, 0x0119 }, + { 0x0014, 0x011a }, + { 0x0014, 0x011b }, + { 0x0014, 0x011c }, + { 0x0014, 0x011d }, + { 0x0014, 0x011e }, + { 0x0014, 0x011f }, + { 0x0014, 0x0120 }, + { 0x0014, 0x0121 }, + { 0x0014, 0x0122 }, + { 0x0014, 0x0123 }, + { 0x0014, 0x0124 }, + { 0x0014, 0x0125 }, + { 0x0014, 0x0126 }, + { 0x0014, 0x0127 }, + { 0x0014, 0x0128 }, + { 0x0014, 0x0129 }, + { 0x0014, 0x012a }, + { 0x0014, 0x012b }, + { 0x0014, 0x012c }, + { 0x0014, 0x012d }, + { 0x0014, 0x012e }, + { 0x0014, 0x012f }, + { 0x0014, 0x0130 }, + { 0x0014, 0x0131 }, + { 0x0014, 0x0132 }, + { 0x0014, 0x0133 }, + { 0x0014, 0x0134 }, + { 0x0014, 0x0135 }, + { 0x0014, 0x0136 }, + { 0x0014, 0x0137 }, + { 0x0014, 0x0138 }, + { 0x0014, 0x0139 }, + { 0x0014, 0x013a }, + { 0x0014, 0x013b }, + { 0x0014, 0x013c }, + { 0x0014, 0x013d }, + { 0x0014, 0x013e }, + { 0x0014, 0x013f }, + { 0x0014, 0x0140 }, + { 0x0014, 0x0141 }, + { 0x0014, 0x0142 }, + { 0x0014, 0x0143 }, + { 0x0014, 0x0144 }, + { 0x0014, 0x0145 }, + { 0x0014, 0x0146 }, + { 0x0014, 0x0147 }, + { 0x0014, 0x0148 }, + { 0x0014, 0x0149 }, + { 0x0014, 0x014a }, + { 0x0014, 0x014b }, + { 0x0014, 0x014c }, + { 0x0014, 0x014d }, + { 0x0014, 0x014e }, + { 0x0014, 0x014f }, + { 0x0014, 0x0150 }, + { 0x0014, 0x0151 }, + { 0x0014, 0x0152 }, + { 0x0014, 0x0153 }, + { 0x0014, 0x0154 }, + { 0x0014, 0x0155 }, + { 0x0014, 0x0156 }, + { 0x0014, 0x0157 }, + { 0x0014, 0x0158 }, + { 0x0014, 0x0159 }, + { 0x0014, 0x015a }, + { 0x0014, 0x015b }, + { 0x0014, 0x015c }, + { 0x0014, 0x015d }, + { 0x0014, 0x015e }, + { 0x0014, 0x015f }, + { 0x0014, 0x0160 }, + { 0x0014, 0x0161 }, + { 0x0014, 0x0162 }, + { 0x0014, 0x0163 }, + { 0x0014, 0x0164 }, + { 0x0014, 0x0165 }, + { 0x0014, 0x0166 }, + { 0x0014, 0x0167 }, + { 0x0014, 0x0168 }, + { 0x0014, 0x0169 }, + { 0x0014, 0x016a }, + { 0x0014, 0x016b }, + { 0x0014, 0x016c }, + { 0x0014, 0x016d }, + { 0x0014, 0x016e }, + { 0x0014, 0x016f }, + { 0x0014, 0x0170 }, + { 0x0014, 0x0171 }, + { 0x0014, 0x0172 }, + { 0x0014, 0x0173 }, + { 0x0014, 0x0174 }, + { 0x0014, 0x0175 }, + { 0x0014, 0x0176 }, + { 0x0014, 0x0177 }, + { 0x0014, 0x0178 }, + { 0x0014, 0x0179 }, + { 0x0014, 0x017a }, + { 0x0014, 0x017b }, + { 0x0014, 0x017c }, + { 0x0014, 0x017d }, + { 0x0014, 0x017e }, + { 0x0014, 0x017f }, + { 0x0014, 0x0180 }, + { 0x0014, 0x0181 }, + { 0x0014, 0x0182 }, + { 0x0014, 0x0183 }, + { 0x0014, 0x0184 }, + { 0x0014, 0x0185 }, + { 0x0014, 0x0186 }, + { 0x0014, 0x0187 }, + { 0x0014, 0x0188 }, + { 0x0014, 0x0189 }, + { 0x0014, 0x018a }, + { 0x0014, 0x018b }, + { 0x0014, 0x018c }, + { 0x0014, 0x018d }, + { 0x0014, 0x018e }, + { 0x0014, 0x018f }, + { 0x0014, 0x0190 }, + { 0x0014, 0x0191 }, + { 0x0014, 0x0192 }, + { 0x0014, 0x0193 }, + { 0x0014, 0x0194 }, + { 0x0014, 0x0195 }, + { 0x0014, 0x0196 }, + { 0x0014, 0x0197 }, + { 0x0013, 0x00db }, + }; + +const uint16_t c_aauiLCLDHuffEnc16[729][2] = + { + { 0x0006, 0x000d }, + { 0x0005, 0x0010 }, + { 0x0006, 0x000e }, + { 0x0006, 0x000f }, + { 0x0006, 0x0010 }, + { 0x0007, 0x000a }, + { 0x0007, 0x000b }, + { 0x0008, 0x000a }, + { 0x0009, 0x000b }, + { 0x000b, 0x000d }, + { 0x000c, 0x000e }, + { 0x000e, 0x0016 }, + { 0x0010, 0x002d }, + { 0x0011, 0x0051 }, + { 0x0012, 0x008c }, + { 0x0014, 0x0000 }, + { 0x0014, 0x0001 }, + { 0x0014, 0x0002 }, + { 0x0014, 0x0003 }, + { 0x0014, 0x0004 }, + { 0x0014, 0x0005 }, + { 0x0014, 0x0006 }, + { 0x0014, 0x0007 }, + { 0x0014, 0x0008 }, + { 0x0014, 0x0009 }, + { 0x0014, 0x000a }, + { 0x0014, 0x000b }, + { 0x0005, 0x0011 }, + { 0x0004, 0x000f }, + { 0x0005, 0x0012 }, + { 0x0005, 0x0013 }, + { 0x0005, 0x0014 }, + { 0x0006, 0x0011 }, + { 0x0006, 0x0012 }, + { 0x0007, 0x000c }, + { 0x0008, 0x000b }, + { 0x000a, 0x000c }, + { 0x000b, 0x000e }, + { 0x000d, 0x0010 }, + { 0x000e, 0x0017 }, + { 0x000f, 0x001c }, + { 0x0013, 0x010b }, + { 0x0013, 0x010c }, + { 0x0014, 0x000c }, + { 0x0014, 0x000d }, + { 0x0014, 0x000e }, + { 0x0014, 0x000f }, + { 0x0014, 0x0010 }, + { 0x0014, 0x0011 }, + { 0x0014, 0x0012 }, + { 0x0014, 0x0013 }, + { 0x0014, 0x0014 }, + { 0x0014, 0x0015 }, + { 0x0014, 0x0016 }, + { 0x0006, 0x0013 }, + { 0x0005, 0x0015 }, + { 0x0005, 0x0016 }, + { 0x0005, 0x0017 }, + { 0x0005, 0x0018 }, + { 0x0006, 0x0014 }, + { 0x0007, 0x000d }, + { 0x0007, 0x000e }, + { 0x0009, 0x000c }, + { 0x000a, 0x000d }, + { 0x000c, 0x000f }, + { 0x000d, 0x0011 }, + { 0x000f, 0x001d }, + { 0x0011, 0x0052 }, + { 0x0012, 0x008d }, + { 0x0012, 0x008e }, + { 0x0014, 0x0017 }, + { 0x0014, 0x0018 }, + { 0x0014, 0x0019 }, + { 0x0014, 0x001a }, + { 0x0014, 0x001b }, + { 0x0014, 0x001c }, + { 0x0014, 0x001d }, + { 0x0014, 0x001e }, + { 0x0014, 0x001f }, + { 0x0014, 0x0020 }, + { 0x0014, 0x0021 }, + { 0x0006, 0x0015 }, + { 0x0005, 0x0019 }, + { 0x0005, 0x001a }, + { 0x0005, 0x001b }, + { 0x0006, 0x0016 }, + { 0x0006, 0x0017 }, + { 0x0007, 0x000f }, + { 0x0008, 0x000c }, + { 0x0009, 0x000d }, + { 0x000b, 0x000f }, + { 0x000c, 0x0010 }, + { 0x000d, 0x0012 }, + { 0x000f, 0x001e }, + { 0x0012, 0x008f }, + { 0x0014, 0x0022 }, + { 0x0014, 0x0023 }, + { 0x0014, 0x0024 }, + { 0x0014, 0x0025 }, + { 0x0014, 0x0026 }, + { 0x0014, 0x0027 }, + { 0x0014, 0x0028 }, + { 0x0014, 0x0029 }, + { 0x0014, 0x002a }, + { 0x0014, 0x002b }, + { 0x0014, 0x002c }, + { 0x0014, 0x002d }, + { 0x0014, 0x002e }, + { 0x0006, 0x0018 }, + { 0x0005, 0x001c }, + { 0x0005, 0x001d }, + { 0x0006, 0x0019 }, + { 0x0006, 0x001a }, + { 0x0007, 0x0010 }, + { 0x0007, 0x0011 }, + { 0x0008, 0x000d }, + { 0x000a, 0x000e }, + { 0x000b, 0x0010 }, + { 0x000c, 0x0011 }, + { 0x000e, 0x0018 }, + { 0x0010, 0x002e }, + { 0x0012, 0x0090 }, + { 0x0013, 0x010d }, + { 0x0013, 0x010e }, + { 0x0014, 0x002f }, + { 0x0014, 0x0030 }, + { 0x0014, 0x0031 }, + { 0x0014, 0x0032 }, + { 0x0014, 0x0033 }, + { 0x0014, 0x0034 }, + { 0x0014, 0x0035 }, + { 0x0014, 0x0036 }, + { 0x0014, 0x0037 }, + { 0x0014, 0x0038 }, + { 0x0014, 0x0039 }, + { 0x0007, 0x0012 }, + { 0x0006, 0x001b }, + { 0x0006, 0x001c }, + { 0x0006, 0x001d }, + { 0x0007, 0x0013 }, + { 0x0007, 0x0014 }, + { 0x0008, 0x000e }, + { 0x0009, 0x000e }, + { 0x000b, 0x0011 }, + { 0x000c, 0x0012 }, + { 0x000d, 0x0013 }, + { 0x000e, 0x0019 }, + { 0x0010, 0x002f }, + { 0x0012, 0x0091 }, + { 0x0014, 0x003a }, + { 0x0014, 0x003b }, + { 0x0014, 0x003c }, + { 0x0014, 0x003d }, + { 0x0014, 0x003e }, + { 0x0014, 0x003f }, + { 0x0014, 0x0040 }, + { 0x0014, 0x0041 }, + { 0x0014, 0x0042 }, + { 0x0014, 0x0043 }, + { 0x0014, 0x0044 }, + { 0x0014, 0x0045 }, + { 0x0014, 0x0046 }, + { 0x0007, 0x0015 }, + { 0x0006, 0x001e }, + { 0x0006, 0x001f }, + { 0x0007, 0x0016 }, + { 0x0007, 0x0017 }, + { 0x0008, 0x000f }, + { 0x0009, 0x000f }, + { 0x000a, 0x000f }, + { 0x000b, 0x0012 }, + { 0x000d, 0x0014 }, + { 0x000e, 0x001a }, + { 0x000f, 0x001f }, + { 0x0013, 0x010f }, + { 0x0011, 0x0053 }, + { 0x0014, 0x0047 }, + { 0x0014, 0x0048 }, + { 0x0014, 0x0049 }, + { 0x0014, 0x004a }, + { 0x0014, 0x004b }, + { 0x0014, 0x004c }, + { 0x0014, 0x004d }, + { 0x0014, 0x004e }, + { 0x0014, 0x004f }, + { 0x0014, 0x0050 }, + { 0x0014, 0x0051 }, + { 0x0014, 0x0052 }, + { 0x0014, 0x0053 }, + { 0x0008, 0x0010 }, + { 0x0007, 0x0018 }, + { 0x0007, 0x0019 }, + { 0x0008, 0x0011 }, + { 0x0008, 0x0012 }, + { 0x0009, 0x0010 }, + { 0x000a, 0x0010 }, + { 0x000b, 0x0013 }, + { 0x000c, 0x0013 }, + { 0x000e, 0x001b }, + { 0x000f, 0x0020 }, + { 0x0010, 0x0030 }, + { 0x0012, 0x0092 }, + { 0x0014, 0x0054 }, + { 0x0014, 0x0055 }, + { 0x0014, 0x0056 }, + { 0x0014, 0x0057 }, + { 0x0014, 0x0058 }, + { 0x0014, 0x0059 }, + { 0x0014, 0x005a }, + { 0x0014, 0x005b }, + { 0x0014, 0x005c }, + { 0x0014, 0x005d }, + { 0x0014, 0x005e }, + { 0x0014, 0x005f }, + { 0x0014, 0x0060 }, + { 0x0014, 0x0061 }, + { 0x0009, 0x0011 }, + { 0x0008, 0x0013 }, + { 0x0009, 0x0012 }, + { 0x0009, 0x0013 }, + { 0x000a, 0x0011 }, + { 0x000a, 0x0012 }, + { 0x000b, 0x0014 }, + { 0x000c, 0x0014 }, + { 0x000d, 0x0015 }, + { 0x000e, 0x001c }, + { 0x000f, 0x0021 }, + { 0x0013, 0x0110 }, + { 0x0012, 0x0093 }, + { 0x0012, 0x0094 }, + { 0x0014, 0x0062 }, + { 0x0014, 0x0063 }, + { 0x0014, 0x0064 }, + { 0x0014, 0x0065 }, + { 0x0014, 0x0066 }, + { 0x0014, 0x0067 }, + { 0x0014, 0x0068 }, + { 0x0014, 0x0069 }, + { 0x0014, 0x006a }, + { 0x0014, 0x006b }, + { 0x0014, 0x006c }, + { 0x0014, 0x006d }, + { 0x0014, 0x006e }, + { 0x000b, 0x0015 }, + { 0x000a, 0x0013 }, + { 0x000a, 0x0014 }, + { 0x000a, 0x0015 }, + { 0x000b, 0x0016 }, + { 0x000c, 0x0015 }, + { 0x000d, 0x0016 }, + { 0x000d, 0x0017 }, + { 0x000f, 0x0022 }, + { 0x0010, 0x0031 }, + { 0x0012, 0x0095 }, + { 0x0012, 0x0096 }, + { 0x0014, 0x006f }, + { 0x0013, 0x0111 }, + { 0x0014, 0x0070 }, + { 0x0014, 0x0071 }, + { 0x0014, 0x0072 }, + { 0x0014, 0x0073 }, + { 0x0014, 0x0074 }, + { 0x0014, 0x0075 }, + { 0x0014, 0x0076 }, + { 0x0014, 0x0077 }, + { 0x0014, 0x0078 }, + { 0x0014, 0x0079 }, + { 0x0014, 0x007a }, + { 0x0014, 0x007b }, + { 0x0014, 0x007c }, + { 0x000c, 0x0016 }, + { 0x000b, 0x0017 }, + { 0x000c, 0x0017 }, + { 0x000c, 0x0018 }, + { 0x000c, 0x0019 }, + { 0x000d, 0x0018 }, + { 0x000e, 0x001d }, + { 0x000f, 0x0023 }, + { 0x000f, 0x0024 }, + { 0x0011, 0x0054 }, + { 0x0012, 0x0097 }, + { 0x0014, 0x007d }, + { 0x0014, 0x007e }, + { 0x0014, 0x007f }, + { 0x0014, 0x0080 }, + { 0x0014, 0x0081 }, + { 0x0014, 0x0082 }, + { 0x0014, 0x0083 }, + { 0x0014, 0x0084 }, + { 0x0014, 0x0085 }, + { 0x0014, 0x0086 }, + { 0x0014, 0x0087 }, + { 0x0014, 0x0088 }, + { 0x0014, 0x0089 }, + { 0x0014, 0x008a }, + { 0x0014, 0x008b }, + { 0x0014, 0x008c }, + { 0x000e, 0x001e }, + { 0x000d, 0x0019 }, + { 0x000d, 0x001a }, + { 0x000d, 0x001b }, + { 0x000e, 0x001f }, + { 0x000f, 0x0025 }, + { 0x000f, 0x0026 }, + { 0x0010, 0x0032 }, + { 0x0010, 0x0033 }, + { 0x0012, 0x0098 }, + { 0x0013, 0x0112 }, + { 0x0014, 0x008d }, + { 0x0014, 0x008e }, + { 0x0014, 0x008f }, + { 0x0014, 0x0090 }, + { 0x0014, 0x0091 }, + { 0x0014, 0x0092 }, + { 0x0014, 0x0093 }, + { 0x0014, 0x0094 }, + { 0x0014, 0x0095 }, + { 0x0014, 0x0096 }, + { 0x0014, 0x0097 }, + { 0x0014, 0x0098 }, + { 0x0014, 0x0099 }, + { 0x0014, 0x009a }, + { 0x0014, 0x009b }, + { 0x0014, 0x009c }, + { 0x000f, 0x0027 }, + { 0x000f, 0x0028 }, + { 0x000f, 0x0029 }, + { 0x000f, 0x002a }, + { 0x0010, 0x0034 }, + { 0x000f, 0x002b }, + { 0x0011, 0x0055 }, + { 0x0012, 0x0099 }, + { 0x0012, 0x009a }, + { 0x0012, 0x009b }, + { 0x0014, 0x009d }, + { 0x0013, 0x0113 }, + { 0x0014, 0x009e }, + { 0x0014, 0x009f }, + { 0x0014, 0x00a0 }, + { 0x0014, 0x00a1 }, + { 0x0014, 0x00a2 }, + { 0x0014, 0x00a3 }, + { 0x0014, 0x00a4 }, + { 0x0014, 0x00a5 }, + { 0x0014, 0x00a6 }, + { 0x0014, 0x00a7 }, + { 0x0014, 0x00a8 }, + { 0x0014, 0x00a9 }, + { 0x0014, 0x00aa }, + { 0x0014, 0x00ab }, + { 0x0014, 0x00ac }, + { 0x0011, 0x0056 }, + { 0x0010, 0x0035 }, + { 0x0010, 0x0036 }, + { 0x0010, 0x0037 }, + { 0x0011, 0x0057 }, + { 0x0012, 0x009c }, + { 0x0012, 0x009d }, + { 0x0012, 0x009e }, + { 0x0014, 0x00ad }, + { 0x0014, 0x00ae }, + { 0x0014, 0x00af }, + { 0x0014, 0x00b0 }, + { 0x0014, 0x00b1 }, + { 0x0014, 0x00b2 }, + { 0x0014, 0x00b3 }, + { 0x0014, 0x00b4 }, + { 0x0014, 0x00b5 }, + { 0x0014, 0x00b6 }, + { 0x0014, 0x00b7 }, + { 0x0014, 0x00b8 }, + { 0x0014, 0x00b9 }, + { 0x0014, 0x00ba }, + { 0x0014, 0x00bb }, + { 0x0014, 0x00bc }, + { 0x0014, 0x00bd }, + { 0x0014, 0x00be }, + { 0x0014, 0x00bf }, + { 0x0012, 0x009f }, + { 0x0011, 0x0058 }, + { 0x0012, 0x00a0 }, + { 0x0014, 0x00c0 }, + { 0x0011, 0x0059 }, + { 0x0013, 0x0114 }, + { 0x0012, 0x00a1 }, + { 0x0014, 0x00c1 }, + { 0x0013, 0x0115 }, + { 0x0014, 0x00c2 }, + { 0x0014, 0x00c3 }, + { 0x0014, 0x00c4 }, + { 0x0014, 0x00c5 }, + { 0x0014, 0x00c6 }, + { 0x0014, 0x00c7 }, + { 0x0014, 0x00c8 }, + { 0x0014, 0x00c9 }, + { 0x0014, 0x00ca }, + { 0x0014, 0x00cb }, + { 0x0014, 0x00cc }, + { 0x0014, 0x00cd }, + { 0x0014, 0x00ce }, + { 0x0014, 0x00cf }, + { 0x0014, 0x00d0 }, + { 0x0014, 0x00d1 }, + { 0x0014, 0x00d2 }, + { 0x0014, 0x00d3 }, + { 0x0014, 0x00d4 }, + { 0x0014, 0x00d5 }, + { 0x0014, 0x00d6 }, + { 0x0014, 0x00d7 }, + { 0x0014, 0x00d8 }, + { 0x0014, 0x00d9 }, + { 0x0014, 0x00da }, + { 0x0014, 0x00db }, + { 0x0014, 0x00dc }, + { 0x0014, 0x00dd }, + { 0x0014, 0x00de }, + { 0x0014, 0x00df }, + { 0x0014, 0x00e0 }, + { 0x0014, 0x00e1 }, + { 0x0014, 0x00e2 }, + { 0x0014, 0x00e3 }, + { 0x0014, 0x00e4 }, + { 0x0014, 0x00e5 }, + { 0x0014, 0x00e6 }, + { 0x0014, 0x00e7 }, + { 0x0014, 0x00e8 }, + { 0x0014, 0x00e9 }, + { 0x0014, 0x00ea }, + { 0x0014, 0x00eb }, + { 0x0014, 0x00ec }, + { 0x0014, 0x00ed }, + { 0x0014, 0x00ee }, + { 0x0014, 0x00ef }, + { 0x0014, 0x00f0 }, + { 0x0014, 0x00f1 }, + { 0x0014, 0x00f2 }, + { 0x0014, 0x00f3 }, + { 0x0014, 0x00f4 }, + { 0x0014, 0x00f5 }, + { 0x0014, 0x00f6 }, + { 0x0014, 0x00f7 }, + { 0x0014, 0x00f8 }, + { 0x0014, 0x00f9 }, + { 0x0014, 0x00fa }, + { 0x0014, 0x00fb }, + { 0x0014, 0x00fc }, + { 0x0014, 0x00fd }, + { 0x0014, 0x00fe }, + { 0x0014, 0x00ff }, + { 0x0014, 0x0100 }, + { 0x0014, 0x0101 }, + { 0x0014, 0x0102 }, + { 0x0014, 0x0103 }, + { 0x0014, 0x0104 }, + { 0x0014, 0x0105 }, + { 0x0014, 0x0106 }, + { 0x0014, 0x0107 }, + { 0x0014, 0x0108 }, + { 0x0014, 0x0109 }, + { 0x0014, 0x010a }, + { 0x0014, 0x010b }, + { 0x0014, 0x010c }, + { 0x0014, 0x010d }, + { 0x0014, 0x010e }, + { 0x0014, 0x010f }, + { 0x0014, 0x0110 }, + { 0x0014, 0x0111 }, + { 0x0014, 0x0112 }, + { 0x0014, 0x0113 }, + { 0x0014, 0x0114 }, + { 0x0014, 0x0115 }, + { 0x0014, 0x0116 }, + { 0x0014, 0x0117 }, + { 0x0014, 0x0118 }, + { 0x0014, 0x0119 }, + { 0x0014, 0x011a }, + { 0x0014, 0x011b }, + { 0x0014, 0x011c }, + { 0x0014, 0x011d }, + { 0x0014, 0x011e }, + { 0x0014, 0x011f }, + { 0x0014, 0x0120 }, + { 0x0014, 0x0121 }, + { 0x0014, 0x0122 }, + { 0x0014, 0x0123 }, + { 0x0014, 0x0124 }, + { 0x0014, 0x0125 }, + { 0x0013, 0x0116 }, + { 0x0014, 0x0126 }, + { 0x0014, 0x0127 }, + { 0x0014, 0x0128 }, + { 0x0014, 0x0129 }, + { 0x0014, 0x012a }, + { 0x0014, 0x012b }, + { 0x0014, 0x012c }, + { 0x0014, 0x012d }, + { 0x0014, 0x012e }, + { 0x0014, 0x012f }, + { 0x0014, 0x0130 }, + { 0x0014, 0x0131 }, + { 0x0014, 0x0132 }, + { 0x0014, 0x0133 }, + { 0x0014, 0x0134 }, + { 0x0014, 0x0135 }, + { 0x0014, 0x0136 }, + { 0x0014, 0x0137 }, + { 0x0014, 0x0138 }, + { 0x0014, 0x0139 }, + { 0x0014, 0x013a }, + { 0x0014, 0x013b }, + { 0x0014, 0x013c }, + { 0x0014, 0x013d }, + { 0x0014, 0x013e }, + { 0x0014, 0x013f }, + { 0x0014, 0x0140 }, + { 0x0014, 0x0141 }, + { 0x0014, 0x0142 }, + { 0x0014, 0x0143 }, + { 0x0014, 0x0144 }, + { 0x0014, 0x0145 }, + { 0x0014, 0x0146 }, + { 0x0014, 0x0147 }, + { 0x0014, 0x0148 }, + { 0x0014, 0x0149 }, + { 0x0014, 0x014a }, + { 0x0014, 0x014b }, + { 0x0014, 0x014c }, + { 0x0014, 0x014d }, + { 0x0014, 0x014e }, + { 0x0014, 0x014f }, + { 0x0014, 0x0150 }, + { 0x0014, 0x0151 }, + { 0x0014, 0x0152 }, + { 0x0014, 0x0153 }, + { 0x0014, 0x0154 }, + { 0x0014, 0x0155 }, + { 0x0014, 0x0156 }, + { 0x0014, 0x0157 }, + { 0x0014, 0x0158 }, + { 0x0014, 0x0159 }, + { 0x0014, 0x015a }, + { 0x0014, 0x015b }, + { 0x0014, 0x015c }, + { 0x0014, 0x015d }, + { 0x0014, 0x015e }, + { 0x0014, 0x015f }, + { 0x0014, 0x0160 }, + { 0x0014, 0x0161 }, + { 0x0014, 0x0162 }, + { 0x0014, 0x0163 }, + { 0x0014, 0x0164 }, + { 0x0014, 0x0165 }, + { 0x0014, 0x0166 }, + { 0x0014, 0x0167 }, + { 0x0014, 0x0168 }, + { 0x0014, 0x0169 }, + { 0x0014, 0x016a }, + { 0x0014, 0x016b }, + { 0x0014, 0x016c }, + { 0x0014, 0x016d }, + { 0x0014, 0x016e }, + { 0x0014, 0x016f }, + { 0x0014, 0x0170 }, + { 0x0014, 0x0171 }, + { 0x0014, 0x0172 }, + { 0x0014, 0x0173 }, + { 0x0014, 0x0174 }, + { 0x0014, 0x0175 }, + { 0x0014, 0x0176 }, + { 0x0014, 0x0177 }, + { 0x0014, 0x0178 }, + { 0x0014, 0x0179 }, + { 0x0014, 0x017a }, + { 0x0014, 0x017b }, + { 0x0014, 0x017c }, + { 0x0014, 0x017d }, + { 0x0014, 0x017e }, + { 0x0014, 0x017f }, + { 0x0014, 0x0180 }, + { 0x0014, 0x0181 }, + { 0x0014, 0x0182 }, + { 0x0014, 0x0183 }, + { 0x0014, 0x0184 }, + { 0x0014, 0x0185 }, + { 0x0014, 0x0186 }, + { 0x0014, 0x0187 }, + { 0x0014, 0x0188 }, + { 0x0014, 0x0189 }, + { 0x0014, 0x018a }, + { 0x0014, 0x018b }, + { 0x0014, 0x018c }, + { 0x0014, 0x018d }, + { 0x0014, 0x018e }, + { 0x0014, 0x018f }, + { 0x0014, 0x0190 }, + { 0x0014, 0x0191 }, + { 0x0014, 0x0192 }, + { 0x0014, 0x0193 }, + { 0x0014, 0x0194 }, + { 0x0014, 0x0195 }, + { 0x0014, 0x0196 }, + { 0x0014, 0x0197 }, + { 0x0014, 0x0198 }, + { 0x0014, 0x0199 }, + { 0x0014, 0x019a }, + { 0x0014, 0x019b }, + { 0x0014, 0x019c }, + { 0x0014, 0x019d }, + { 0x0014, 0x019e }, + { 0x0014, 0x019f }, + { 0x0014, 0x01a0 }, + { 0x0014, 0x01a1 }, + { 0x0014, 0x01a2 }, + { 0x0014, 0x01a3 }, + { 0x0014, 0x01a4 }, + { 0x0014, 0x01a5 }, + { 0x0014, 0x01a6 }, + { 0x0014, 0x01a7 }, + { 0x0014, 0x01a8 }, + { 0x0014, 0x01a9 }, + { 0x0014, 0x01aa }, + { 0x0014, 0x01ab }, + { 0x0014, 0x01ac }, + { 0x0014, 0x01ad }, + { 0x0014, 0x01ae }, + { 0x0014, 0x01af }, + { 0x0014, 0x01b0 }, + { 0x0014, 0x01b1 }, + { 0x0014, 0x01b2 }, + { 0x0014, 0x01b3 }, + { 0x0014, 0x01b4 }, + { 0x0014, 0x01b5 }, + { 0x0014, 0x01b6 }, + { 0x0014, 0x01b7 }, + { 0x0014, 0x01b8 }, + { 0x0014, 0x01b9 }, + { 0x0014, 0x01ba }, + { 0x0014, 0x01bb }, + { 0x0014, 0x01bc }, + { 0x0014, 0x01bd }, + { 0x0014, 0x01be }, + { 0x0014, 0x01bf }, + { 0x0014, 0x01c0 }, + { 0x0014, 0x01c1 }, + { 0x0014, 0x01c2 }, + { 0x0014, 0x01c3 }, + { 0x0014, 0x01c4 }, + { 0x0014, 0x01c5 }, + { 0x0014, 0x01c6 }, + { 0x0014, 0x01c7 }, + { 0x0014, 0x01c8 }, + { 0x0014, 0x01c9 }, + { 0x0014, 0x01ca }, + { 0x0014, 0x01cb }, + { 0x0014, 0x01cc }, + { 0x0014, 0x01cd }, + { 0x0014, 0x01ce }, + { 0x0014, 0x01cf }, + { 0x0014, 0x01d0 }, + { 0x0014, 0x01d1 }, + { 0x0014, 0x01d2 }, + { 0x0014, 0x01d3 }, + { 0x0014, 0x01d4 }, + { 0x0014, 0x01d5 }, + { 0x0014, 0x01d6 }, + { 0x0014, 0x01d7 }, + { 0x0014, 0x01d8 }, + { 0x0014, 0x01d9 }, + { 0x0014, 0x01da }, + { 0x0014, 0x01db }, + { 0x0014, 0x01dc }, + { 0x0014, 0x01dd }, + { 0x0014, 0x01de }, + { 0x0014, 0x01df }, + { 0x0014, 0x01e0 }, + { 0x0014, 0x01e1 }, + { 0x0014, 0x01e2 }, + { 0x0014, 0x01e3 }, + { 0x0014, 0x01e4 }, + { 0x0014, 0x01e5 }, + { 0x0014, 0x01e6 }, + { 0x0014, 0x01e7 }, + { 0x0014, 0x01e8 }, + { 0x0014, 0x01e9 }, + { 0x0014, 0x01ea }, + { 0x0014, 0x01eb }, + { 0x0014, 0x01ec }, + { 0x0014, 0x01ed }, + { 0x0014, 0x01ee }, + { 0x0014, 0x01ef }, + { 0x0014, 0x01f0 }, + { 0x0014, 0x01f1 }, + { 0x0014, 0x01f2 }, + { 0x0014, 0x01f3 }, + { 0x0014, 0x01f4 }, + { 0x0014, 0x01f5 }, + { 0x0014, 0x01f6 }, + { 0x0014, 0x01f7 }, + { 0x0014, 0x01f8 }, + { 0x0014, 0x01f9 }, + { 0x0014, 0x01fa }, + { 0x0014, 0x01fb }, + { 0x0014, 0x01fc }, + { 0x0014, 0x01fd }, + { 0x0014, 0x01fe }, + { 0x0014, 0x01ff }, + { 0x0014, 0x0200 }, + { 0x0014, 0x0201 }, + { 0x0014, 0x0202 }, + { 0x0014, 0x0203 }, + { 0x0014, 0x0204 }, + { 0x0014, 0x0205 }, + { 0x0014, 0x0206 }, + { 0x0014, 0x0207 }, + { 0x0014, 0x0208 }, + { 0x0014, 0x0209 }, + { 0x0014, 0x020a }, + { 0x0014, 0x020b }, + { 0x0014, 0x020c }, + { 0x0014, 0x020d }, + { 0x0014, 0x020e }, + { 0x0014, 0x020f }, + { 0x0014, 0x0210 }, + { 0x0014, 0x0211 }, + { 0x0014, 0x0212 }, + { 0x0014, 0x0213 }, + { 0x0014, 0x0214 }, + { 0x0014, 0x0215 }, + { 0x0013, 0x0117 }, + + }; + + +const uint16_t c_aauiLCLDHuffEnc17[729][2] = + { + { 0x0006, 0x0012 }, + { 0x0006, 0x0013 }, + { 0x0006, 0x0014 }, + { 0x0006, 0x0015 }, + { 0x0007, 0x000f }, + { 0x0007, 0x0010 }, + { 0x0007, 0x0011 }, + { 0x0008, 0x000e }, + { 0x0008, 0x000f }, + { 0x0009, 0x000f }, + { 0x000a, 0x000f }, + { 0x000c, 0x0011 }, + { 0x000d, 0x0014 }, + { 0x000e, 0x0017 }, + { 0x0010, 0x002d }, + { 0x0011, 0x004c }, + { 0x0012, 0x008a }, + { 0x0014, 0x0000 }, + { 0x0014, 0x0001 }, + { 0x0014, 0x0002 }, + { 0x0014, 0x0003 }, + { 0x0014, 0x0004 }, + { 0x0014, 0x0005 }, + { 0x0014, 0x0006 }, + { 0x0014, 0x0007 }, + { 0x0014, 0x0008 }, + { 0x0014, 0x0009 }, + { 0x0006, 0x0016 }, + { 0x0005, 0x0018 }, + { 0x0005, 0x0019 }, + { 0x0005, 0x001a }, + { 0x0006, 0x0017 }, + { 0x0006, 0x0018 }, + { 0x0006, 0x0019 }, + { 0x0007, 0x0012 }, + { 0x0007, 0x0013 }, + { 0x0008, 0x0010 }, + { 0x000a, 0x0010 }, + { 0x000b, 0x0011 }, + { 0x000c, 0x0012 }, + { 0x000e, 0x0018 }, + { 0x000f, 0x0020 }, + { 0x0011, 0x004d }, + { 0x0013, 0x00e4 }, + { 0x0014, 0x000a }, + { 0x0014, 0x000b }, + { 0x0014, 0x000c }, + { 0x0014, 0x000d }, + { 0x0014, 0x000e }, + { 0x0014, 0x000f }, + { 0x0014, 0x0010 }, + { 0x0014, 0x0011 }, + { 0x0014, 0x0012 }, + { 0x0014, 0x0013 }, + { 0x0006, 0x001a }, + { 0x0005, 0x001b }, + { 0x0005, 0x001c }, + { 0x0005, 0x001d }, + { 0x0006, 0x001b }, + { 0x0006, 0x001c }, + { 0x0006, 0x001d }, + { 0x0007, 0x0014 }, + { 0x0008, 0x0011 }, + { 0x0009, 0x0010 }, + { 0x000a, 0x0011 }, + { 0x000b, 0x0012 }, + { 0x000c, 0x0013 }, + { 0x000e, 0x0019 }, + { 0x000f, 0x0021 }, + { 0x0010, 0x002e }, + { 0x0013, 0x00e5 }, + { 0x0013, 0x00e6 }, + { 0x0014, 0x0014 }, + { 0x0014, 0x0015 }, + { 0x0014, 0x0016 }, + { 0x0014, 0x0017 }, + { 0x0014, 0x0018 }, + { 0x0014, 0x0019 }, + { 0x0014, 0x001a }, + { 0x0014, 0x001b }, + { 0x0014, 0x001c }, + { 0x0006, 0x001e }, + { 0x0005, 0x001e }, + { 0x0005, 0x001f }, + { 0x0006, 0x001f }, + { 0x0006, 0x0020 }, + { 0x0006, 0x0021 }, + { 0x0006, 0x0022 }, + { 0x0007, 0x0015 }, + { 0x0008, 0x0012 }, + { 0x0009, 0x0011 }, + { 0x000a, 0x0012 }, + { 0x000b, 0x0013 }, + { 0x000c, 0x0014 }, + { 0x000e, 0x001a }, + { 0x000f, 0x0022 }, + { 0x0010, 0x002f }, + { 0x0013, 0x00e7 }, + { 0x0013, 0x00e8 }, + { 0x0014, 0x001d }, + { 0x0014, 0x001e }, + { 0x0014, 0x001f }, + { 0x0014, 0x0020 }, + { 0x0014, 0x0021 }, + { 0x0014, 0x0022 }, + { 0x0014, 0x0023 }, + { 0x0014, 0x0024 }, + { 0x0014, 0x0025 }, + { 0x0006, 0x0023 }, + { 0x0006, 0x0024 }, + { 0x0006, 0x0025 }, + { 0x0006, 0x0026 }, + { 0x0006, 0x0027 }, + { 0x0006, 0x0028 }, + { 0x0007, 0x0016 }, + { 0x0007, 0x0017 }, + { 0x0008, 0x0013 }, + { 0x0009, 0x0012 }, + { 0x000a, 0x0013 }, + { 0x000c, 0x0015 }, + { 0x000d, 0x0015 }, + { 0x000f, 0x0023 }, + { 0x0010, 0x0030 }, + { 0x0011, 0x004e }, + { 0x0014, 0x0026 }, + { 0x0014, 0x0027 }, + { 0x0014, 0x0028 }, + { 0x0014, 0x0029 }, + { 0x0014, 0x002a }, + { 0x0014, 0x002b }, + { 0x0014, 0x002c }, + { 0x0014, 0x002d }, + { 0x0014, 0x002e }, + { 0x0014, 0x002f }, + { 0x0014, 0x0030 }, + { 0x0007, 0x0018 }, + { 0x0006, 0x0029 }, + { 0x0006, 0x002a }, + { 0x0006, 0x002b }, + { 0x0006, 0x002c }, + { 0x0007, 0x0019 }, + { 0x0007, 0x001a }, + { 0x0008, 0x0014 }, + { 0x0009, 0x0013 }, + { 0x000a, 0x0014 }, + { 0x000b, 0x0014 }, + { 0x000c, 0x0016 }, + { 0x000d, 0x0016 }, + { 0x000f, 0x0024 }, + { 0x0010, 0x0031 }, + { 0x0011, 0x004f }, + { 0x0014, 0x0031 }, + { 0x0014, 0x0032 }, + { 0x0014, 0x0033 }, + { 0x0014, 0x0034 }, + { 0x0014, 0x0035 }, + { 0x0014, 0x0036 }, + { 0x0014, 0x0037 }, + { 0x0014, 0x0038 }, + { 0x0014, 0x0039 }, + { 0x0014, 0x003a }, + { 0x0014, 0x003b }, + { 0x0007, 0x001b }, + { 0x0006, 0x002d }, + { 0x0006, 0x002e }, + { 0x0006, 0x002f }, + { 0x0007, 0x001c }, + { 0x0007, 0x001d }, + { 0x0008, 0x0015 }, + { 0x0009, 0x0014 }, + { 0x000a, 0x0015 }, + { 0x000a, 0x0016 }, + { 0x000c, 0x0017 }, + { 0x000d, 0x0017 }, + { 0x000e, 0x001b }, + { 0x000f, 0x0025 }, + { 0x0011, 0x0050 }, + { 0x0011, 0x0051 }, + { 0x0014, 0x003c }, + { 0x0014, 0x003d }, + { 0x0014, 0x003e }, + { 0x0014, 0x003f }, + { 0x0014, 0x0040 }, + { 0x0014, 0x0041 }, + { 0x0014, 0x0042 }, + { 0x0014, 0x0043 }, + { 0x0014, 0x0044 }, + { 0x0014, 0x0045 }, + { 0x0014, 0x0046 }, + { 0x0008, 0x0016 }, + { 0x0007, 0x001e }, + { 0x0007, 0x001f }, + { 0x0007, 0x0020 }, + { 0x0007, 0x0021 }, + { 0x0008, 0x0017 }, + { 0x0008, 0x0018 }, + { 0x0009, 0x0015 }, + { 0x000a, 0x0017 }, + { 0x000b, 0x0015 }, + { 0x000c, 0x0018 }, + { 0x000e, 0x001c }, + { 0x000e, 0x001d }, + { 0x0010, 0x0032 }, + { 0x0012, 0x008b }, + { 0x0012, 0x008c }, + { 0x0014, 0x0047 }, + { 0x0014, 0x0048 }, + { 0x0014, 0x0049 }, + { 0x0014, 0x004a }, + { 0x0014, 0x004b }, + { 0x0014, 0x004c }, + { 0x0014, 0x004d }, + { 0x0014, 0x004e }, + { 0x0014, 0x004f }, + { 0x0014, 0x0050 }, + { 0x0014, 0x0051 }, + { 0x0008, 0x0019 }, + { 0x0007, 0x0022 }, + { 0x0007, 0x0023 }, + { 0x0008, 0x001a }, + { 0x0008, 0x001b }, + { 0x0009, 0x0016 }, + { 0x0009, 0x0017 }, + { 0x000a, 0x0018 }, + { 0x000b, 0x0016 }, + { 0x000c, 0x0019 }, + { 0x000d, 0x0018 }, + { 0x000e, 0x001e }, + { 0x0010, 0x0033 }, + { 0x0011, 0x0052 }, + { 0x0014, 0x0052 }, + { 0x0013, 0x00e9 }, + { 0x0014, 0x0053 }, + { 0x0014, 0x0054 }, + { 0x0014, 0x0055 }, + { 0x0014, 0x0056 }, + { 0x0014, 0x0057 }, + { 0x0014, 0x0058 }, + { 0x0014, 0x0059 }, + { 0x0014, 0x005a }, + { 0x0014, 0x005b }, + { 0x0014, 0x005c }, + { 0x0014, 0x005d }, + { 0x0009, 0x0018 }, + { 0x0008, 0x001c }, + { 0x0008, 0x001d }, + { 0x0009, 0x0019 }, + { 0x0009, 0x001a }, + { 0x000a, 0x0019 }, + { 0x000a, 0x001a }, + { 0x000b, 0x0017 }, + { 0x000c, 0x001a }, + { 0x000d, 0x0019 }, + { 0x000e, 0x001f }, + { 0x000f, 0x0026 }, + { 0x0010, 0x0034 }, + { 0x0012, 0x008d }, + { 0x0013, 0x00ea }, + { 0x0014, 0x005e }, + { 0x0014, 0x005f }, + { 0x0014, 0x0060 }, + { 0x0014, 0x0061 }, + { 0x0014, 0x0062 }, + { 0x0014, 0x0063 }, + { 0x0014, 0x0064 }, + { 0x0014, 0x0065 }, + { 0x0014, 0x0066 }, + { 0x0014, 0x0067 }, + { 0x0014, 0x0068 }, + { 0x0014, 0x0069 }, + { 0x000b, 0x0018 }, + { 0x0009, 0x001b }, + { 0x000a, 0x001b }, + { 0x000a, 0x001c }, + { 0x000a, 0x001d }, + { 0x000b, 0x0019 }, + { 0x000b, 0x001a }, + { 0x000c, 0x001b }, + { 0x000d, 0x001a }, + { 0x000e, 0x0020 }, + { 0x000f, 0x0027 }, + { 0x0012, 0x008e }, + { 0x0011, 0x0053 }, + { 0x0013, 0x00eb }, + { 0x0014, 0x006a }, + { 0x0014, 0x006b }, + { 0x0014, 0x006c }, + { 0x0014, 0x006d }, + { 0x0014, 0x006e }, + { 0x0014, 0x006f }, + { 0x0014, 0x0070 }, + { 0x0014, 0x0071 }, + { 0x0014, 0x0072 }, + { 0x0014, 0x0073 }, + { 0x0014, 0x0074 }, + { 0x0014, 0x0075 }, + { 0x0014, 0x0076 }, + { 0x000c, 0x001c }, + { 0x000b, 0x001b }, + { 0x000b, 0x001c }, + { 0x000b, 0x001d }, + { 0x000c, 0x001d }, + { 0x000c, 0x001e }, + { 0x000d, 0x001b }, + { 0x000d, 0x001c }, + { 0x000e, 0x0021 }, + { 0x0010, 0x0035 }, + { 0x0010, 0x0036 }, + { 0x0011, 0x0054 }, + { 0x0013, 0x00ec }, + { 0x0014, 0x0077 }, + { 0x0014, 0x0078 }, + { 0x0014, 0x0079 }, + { 0x0014, 0x007a }, + { 0x0014, 0x007b }, + { 0x0014, 0x007c }, + { 0x0014, 0x007d }, + { 0x0014, 0x007e }, + { 0x0014, 0x007f }, + { 0x0014, 0x0080 }, + { 0x0014, 0x0081 }, + { 0x0014, 0x0082 }, + { 0x0014, 0x0083 }, + { 0x0014, 0x0084 }, + { 0x000d, 0x001d }, + { 0x000c, 0x001f }, + { 0x000c, 0x0020 }, + { 0x000c, 0x0021 }, + { 0x000d, 0x001e }, + { 0x000d, 0x001f }, + { 0x000e, 0x0022 }, + { 0x000f, 0x0028 }, + { 0x0010, 0x0037 }, + { 0x0010, 0x0038 }, + { 0x0010, 0x0039 }, + { 0x0012, 0x008f }, + { 0x0013, 0x00ed }, + { 0x0014, 0x0085 }, + { 0x0014, 0x0086 }, + { 0x0014, 0x0087 }, + { 0x0014, 0x0088 }, + { 0x0014, 0x0089 }, + { 0x0014, 0x008a }, + { 0x0014, 0x008b }, + { 0x0014, 0x008c }, + { 0x0014, 0x008d }, + { 0x0014, 0x008e }, + { 0x0014, 0x008f }, + { 0x0014, 0x0090 }, + { 0x0014, 0x0091 }, + { 0x0014, 0x0092 }, + { 0x000e, 0x0023 }, + { 0x000d, 0x0020 }, + { 0x000d, 0x0021 }, + { 0x000e, 0x0024 }, + { 0x000e, 0x0025 }, + { 0x000e, 0x0026 }, + { 0x000f, 0x0029 }, + { 0x0010, 0x003a }, + { 0x0010, 0x003b }, + { 0x0012, 0x0090 }, + { 0x0014, 0x0093 }, + { 0x0014, 0x0094 }, + { 0x0014, 0x0095 }, + { 0x0014, 0x0096 }, + { 0x0014, 0x0097 }, + { 0x0014, 0x0098 }, + { 0x0014, 0x0099 }, + { 0x0014, 0x009a }, + { 0x0014, 0x009b }, + { 0x0014, 0x009c }, + { 0x0014, 0x009d }, + { 0x0014, 0x009e }, + { 0x0014, 0x009f }, + { 0x0014, 0x00a0 }, + { 0x0014, 0x00a1 }, + { 0x0014, 0x00a2 }, + { 0x0014, 0x00a3 }, + { 0x000f, 0x002a }, + { 0x000e, 0x0027 }, + { 0x000f, 0x002b }, + { 0x000f, 0x002c }, + { 0x000f, 0x002d }, + { 0x0010, 0x003c }, + { 0x0010, 0x003d }, + { 0x0011, 0x0055 }, + { 0x0011, 0x0056 }, + { 0x0014, 0x00a4 }, + { 0x0014, 0x00a5 }, + { 0x0014, 0x00a6 }, + { 0x0014, 0x00a7 }, + { 0x0014, 0x00a8 }, + { 0x0014, 0x00a9 }, + { 0x0014, 0x00aa }, + { 0x0014, 0x00ab }, + { 0x0014, 0x00ac }, + { 0x0014, 0x00ad }, + { 0x0014, 0x00ae }, + { 0x0014, 0x00af }, + { 0x0014, 0x00b0 }, + { 0x0014, 0x00b1 }, + { 0x0014, 0x00b2 }, + { 0x0014, 0x00b3 }, + { 0x0014, 0x00b4 }, + { 0x0014, 0x00b5 }, + { 0x0012, 0x0091 }, + { 0x0010, 0x003e }, + { 0x0010, 0x003f }, + { 0x0011, 0x0057 }, + { 0x0011, 0x0058 }, + { 0x0011, 0x0059 }, + { 0x0012, 0x0092 }, + { 0x0013, 0x00ee }, + { 0x0013, 0x00ef }, + { 0x0012, 0x0093 }, + { 0x0014, 0x00b6 }, + { 0x0014, 0x00b7 }, + { 0x0014, 0x00b8 }, + { 0x0014, 0x00b9 }, + { 0x0014, 0x00ba }, + { 0x0014, 0x00bb }, + { 0x0014, 0x00bc }, + { 0x0014, 0x00bd }, + { 0x0014, 0x00be }, + { 0x0014, 0x00bf }, + { 0x0014, 0x00c0 }, + { 0x0014, 0x00c1 }, + { 0x0014, 0x00c2 }, + { 0x0014, 0x00c3 }, + { 0x0014, 0x00c4 }, + { 0x0014, 0x00c5 }, + { 0x0014, 0x00c6 }, + { 0x0013, 0x00f0 }, + { 0x0012, 0x0094 }, + { 0x0012, 0x0095 }, + { 0x0012, 0x0096 }, + { 0x0014, 0x00c7 }, + { 0x0014, 0x00c8 }, + { 0x0014, 0x00c9 }, + { 0x0014, 0x00ca }, + { 0x0014, 0x00cb }, + { 0x0014, 0x00cc }, + { 0x0014, 0x00cd }, + { 0x0014, 0x00ce }, + { 0x0014, 0x00cf }, + { 0x0014, 0x00d0 }, + { 0x0014, 0x00d1 }, + { 0x0014, 0x00d2 }, + { 0x0014, 0x00d3 }, + { 0x0014, 0x00d4 }, + { 0x0014, 0x00d5 }, + { 0x0014, 0x00d6 }, + { 0x0014, 0x00d7 }, + { 0x0014, 0x00d8 }, + { 0x0014, 0x00d9 }, + { 0x0014, 0x00da }, + { 0x0014, 0x00db }, + { 0x0014, 0x00dc }, + { 0x0014, 0x00dd }, + { 0x0014, 0x00de }, + { 0x0012, 0x0097 }, + { 0x0014, 0x00df }, + { 0x0014, 0x00e0 }, + { 0x0014, 0x00e1 }, + { 0x0014, 0x00e2 }, + { 0x0014, 0x00e3 }, + { 0x0014, 0x00e4 }, + { 0x0014, 0x00e5 }, + { 0x0014, 0x00e6 }, + { 0x0014, 0x00e7 }, + { 0x0014, 0x00e8 }, + { 0x0014, 0x00e9 }, + { 0x0014, 0x00ea }, + { 0x0014, 0x00eb }, + { 0x0014, 0x00ec }, + { 0x0014, 0x00ed }, + { 0x0014, 0x00ee }, + { 0x0014, 0x00ef }, + { 0x0014, 0x00f0 }, + { 0x0014, 0x00f1 }, + { 0x0014, 0x00f2 }, + { 0x0014, 0x00f3 }, + { 0x0014, 0x00f4 }, + { 0x0014, 0x00f5 }, + { 0x0014, 0x00f6 }, + { 0x0014, 0x00f7 }, + { 0x0014, 0x00f8 }, + { 0x0014, 0x00f9 }, + { 0x0014, 0x00fa }, + { 0x0014, 0x00fb }, + { 0x0014, 0x00fc }, + { 0x0014, 0x00fd }, + { 0x0014, 0x00fe }, + { 0x0014, 0x00ff }, + { 0x0014, 0x0100 }, + { 0x0014, 0x0101 }, + { 0x0014, 0x0102 }, + { 0x0014, 0x0103 }, + { 0x0014, 0x0104 }, + { 0x0014, 0x0105 }, + { 0x0014, 0x0106 }, + { 0x0014, 0x0107 }, + { 0x0014, 0x0108 }, + { 0x0014, 0x0109 }, + { 0x0014, 0x010a }, + { 0x0014, 0x010b }, + { 0x0014, 0x010c }, + { 0x0014, 0x010d }, + { 0x0014, 0x010e }, + { 0x0014, 0x010f }, + { 0x0014, 0x0110 }, + { 0x0014, 0x0111 }, + { 0x0014, 0x0112 }, + { 0x0014, 0x0113 }, + { 0x0014, 0x0114 }, + { 0x0014, 0x0115 }, + { 0x0014, 0x0116 }, + { 0x0014, 0x0117 }, + { 0x0014, 0x0118 }, + { 0x0014, 0x0119 }, + { 0x0014, 0x011a }, + { 0x0014, 0x011b }, + { 0x0014, 0x011c }, + { 0x0014, 0x011d }, + { 0x0014, 0x011e }, + { 0x0014, 0x011f }, + { 0x0014, 0x0120 }, + { 0x0014, 0x0121 }, + { 0x0014, 0x0122 }, + { 0x0014, 0x0123 }, + { 0x0014, 0x0124 }, + { 0x0014, 0x0125 }, + { 0x0014, 0x0126 }, + { 0x0014, 0x0127 }, + { 0x0014, 0x0128 }, + { 0x0014, 0x0129 }, + { 0x0014, 0x012a }, + { 0x0014, 0x012b }, + { 0x0014, 0x012c }, + { 0x0014, 0x012d }, + { 0x0014, 0x012e }, + { 0x0014, 0x012f }, + { 0x0014, 0x0130 }, + { 0x0014, 0x0131 }, + { 0x0014, 0x0132 }, + { 0x0014, 0x0133 }, + { 0x0014, 0x0134 }, + { 0x0014, 0x0135 }, + { 0x0014, 0x0136 }, + { 0x0014, 0x0137 }, + { 0x0014, 0x0138 }, + { 0x0014, 0x0139 }, + { 0x0014, 0x013a }, + { 0x0014, 0x013b }, + { 0x0014, 0x013c }, + { 0x0014, 0x013d }, + { 0x0014, 0x013e }, + { 0x0014, 0x013f }, + { 0x0014, 0x0140 }, + { 0x0014, 0x0141 }, + { 0x0014, 0x0142 }, + { 0x0014, 0x0143 }, + { 0x0014, 0x0144 }, + { 0x0014, 0x0145 }, + { 0x0014, 0x0146 }, + { 0x0014, 0x0147 }, + { 0x0014, 0x0148 }, + { 0x0014, 0x0149 }, + { 0x0014, 0x014a }, + { 0x0014, 0x014b }, + { 0x0014, 0x014c }, + { 0x0014, 0x014d }, + { 0x0014, 0x014e }, + { 0x0014, 0x014f }, + { 0x0014, 0x0150 }, + { 0x0014, 0x0151 }, + { 0x0014, 0x0152 }, + { 0x0014, 0x0153 }, + { 0x0014, 0x0154 }, + { 0x0014, 0x0155 }, + { 0x0014, 0x0156 }, + { 0x0014, 0x0157 }, + { 0x0014, 0x0158 }, + { 0x0014, 0x0159 }, + { 0x0014, 0x015a }, + { 0x0014, 0x015b }, + { 0x0014, 0x015c }, + { 0x0014, 0x015d }, + { 0x0014, 0x015e }, + { 0x0014, 0x015f }, + { 0x0014, 0x0160 }, + { 0x0014, 0x0161 }, + { 0x0014, 0x0162 }, + { 0x0014, 0x0163 }, + { 0x0014, 0x0164 }, + { 0x0014, 0x0165 }, + { 0x0014, 0x0166 }, + { 0x0014, 0x0167 }, + { 0x0014, 0x0168 }, + { 0x0014, 0x0169 }, + { 0x0014, 0x016a }, + { 0x0014, 0x016b }, + { 0x0014, 0x016c }, + { 0x0014, 0x016d }, + { 0x0014, 0x016e }, + { 0x0014, 0x016f }, + { 0x0014, 0x0170 }, + { 0x0014, 0x0171 }, + { 0x0014, 0x0172 }, + { 0x0014, 0x0173 }, + { 0x0014, 0x0174 }, + { 0x0014, 0x0175 }, + { 0x0014, 0x0176 }, + { 0x0014, 0x0177 }, + { 0x0014, 0x0178 }, + { 0x0014, 0x0179 }, + { 0x0014, 0x017a }, + { 0x0014, 0x017b }, + { 0x0014, 0x017c }, + { 0x0014, 0x017d }, + { 0x0014, 0x017e }, + { 0x0014, 0x017f }, + { 0x0014, 0x0180 }, + { 0x0014, 0x0181 }, + { 0x0014, 0x0182 }, + { 0x0014, 0x0183 }, + { 0x0014, 0x0184 }, + { 0x0014, 0x0185 }, + { 0x0014, 0x0186 }, + { 0x0014, 0x0187 }, + { 0x0014, 0x0188 }, + { 0x0014, 0x0189 }, + { 0x0014, 0x018a }, + { 0x0014, 0x018b }, + { 0x0014, 0x018c }, + { 0x0014, 0x018d }, + { 0x0014, 0x018e }, + { 0x0014, 0x018f }, + { 0x0014, 0x0190 }, + { 0x0014, 0x0191 }, + { 0x0014, 0x0192 }, + { 0x0014, 0x0193 }, + { 0x0014, 0x0194 }, + { 0x0014, 0x0195 }, + { 0x0014, 0x0196 }, + { 0x0014, 0x0197 }, + { 0x0014, 0x0198 }, + { 0x0014, 0x0199 }, + { 0x0014, 0x019a }, + { 0x0014, 0x019b }, + { 0x0014, 0x019c }, + { 0x0014, 0x019d }, + { 0x0014, 0x019e }, + { 0x0014, 0x019f }, + { 0x0014, 0x01a0 }, + { 0x0014, 0x01a1 }, + { 0x0014, 0x01a2 }, + { 0x0014, 0x01a3 }, + { 0x0014, 0x01a4 }, + { 0x0014, 0x01a5 }, + { 0x0014, 0x01a6 }, + { 0x0014, 0x01a7 }, + { 0x0014, 0x01a8 }, + { 0x0014, 0x01a9 }, + { 0x0014, 0x01aa }, + { 0x0014, 0x01ab }, + { 0x0014, 0x01ac }, + { 0x0014, 0x01ad }, + { 0x0014, 0x01ae }, + { 0x0014, 0x01af }, + { 0x0014, 0x01b0 }, + { 0x0014, 0x01b1 }, + { 0x0014, 0x01b2 }, + { 0x0014, 0x01b3 }, + { 0x0014, 0x01b4 }, + { 0x0014, 0x01b5 }, + { 0x0014, 0x01b6 }, + { 0x0014, 0x01b7 }, + { 0x0014, 0x01b8 }, + { 0x0014, 0x01b9 }, + { 0x0014, 0x01ba }, + { 0x0014, 0x01bb }, + { 0x0014, 0x01bc }, + { 0x0014, 0x01bd }, + { 0x0014, 0x01be }, + { 0x0014, 0x01bf }, + { 0x0014, 0x01c0 }, + { 0x0014, 0x01c1 }, + { 0x0014, 0x01c2 }, + { 0x0014, 0x01c3 }, + { 0x0014, 0x01c4 }, + { 0x0014, 0x01c5 }, + { 0x0014, 0x01c6 }, + { 0x0014, 0x01c7 }, + { 0x0013, 0x00f1 }, + { 0x0013, 0x00f2 }, + { 0x0013, 0x00f3 }, + { 0x0013, 0x00f4 }, + { 0x0013, 0x00f5 }, + { 0x0013, 0x00f6 }, + { 0x0013, 0x00f7 }, + { 0x0013, 0x00f8 }, + { 0x0013, 0x00f9 }, + { 0x0013, 0x00fa }, + { 0x0013, 0x00fb }, + { 0x0013, 0x00fc }, + { 0x0013, 0x00fd }, + { 0x0013, 0x00fe }, + { 0x0013, 0x00ff }, + { 0x0013, 0x0100 }, + { 0x0013, 0x0101 }, + { 0x0013, 0x0102 }, + { 0x0013, 0x0103 }, + { 0x0013, 0x0104 }, + { 0x0013, 0x0105 }, + { 0x0013, 0x0106 }, + { 0x0013, 0x0107 }, + { 0x0013, 0x0108 }, + { 0x0013, 0x0109 }, + { 0x0013, 0x010a }, + { 0x0013, 0x010b }, + { 0x0013, 0x010c }, + { 0x0013, 0x010d }, + { 0x0013, 0x010e }, + { 0x0013, 0x010f }, + { 0x0013, 0x0110 }, + { 0x0013, 0x0111 }, + { 0x0013, 0x0112 }, + { 0x0013, 0x0113 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc18[28][2] = + { + { 0x0004, 0x0001 }, + { 0x0003, 0x0002 }, + { 0x0003, 0x0003 }, + { 0x0003, 0x0004 }, + { 0x0003, 0x0005 }, + { 0x0003, 0x0006 }, + { 0x0003, 0x0007 }, + { 0x0004, 0x0002 }, + { 0x0004, 0x0003 }, + { 0x0005, 0x0001 }, + { 0x0006, 0x0001 }, + { 0x0007, 0x0001 }, + { 0x0008, 0x0001 }, + { 0x0009, 0x0001 }, + { 0x000a, 0x0001 }, + { 0x000b, 0x0001 }, + { 0x000c, 0x0001 }, + { 0x000d, 0x0001 }, + { 0x000e, 0x0001 }, + { 0x000f, 0x0001 }, + { 0x0011, 0x0003 }, + { 0x0012, 0x0001 }, + { 0x0012, 0x0002 }, + { 0x0012, 0x0003 }, + { 0x0013, 0x0000 }, + { 0x0013, 0x0001 }, + { 0x0012, 0x0004 }, + { 0x0012, 0x0005 }, + + }; + + +const uint16_t c_aauiLCLDHuffEnc19[29][2] = + { + { 0x0004, 0x0002 }, + { 0x0003, 0x0003 }, + { 0x0003, 0x0004 }, + { 0x0003, 0x0005 }, + { 0x0003, 0x0006 }, + { 0x0003, 0x0007 }, + { 0x0004, 0x0003 }, + { 0x0004, 0x0004 }, + { 0x0004, 0x0005 }, + { 0x0005, 0x0001 }, + { 0x0005, 0x0002 }, + { 0x0005, 0x0003 }, + { 0x0006, 0x0001 }, + { 0x0007, 0x0001 }, + { 0x0008, 0x0001 }, + { 0x0009, 0x0001 }, + { 0x000a, 0x0001 }, + { 0x000b, 0x0001 }, + { 0x000c, 0x0001 }, + { 0x000d, 0x0001 }, + { 0x000e, 0x0001 }, + { 0x000f, 0x0001 }, + { 0x0010, 0x0001 }, + { 0x0012, 0x0002 }, + { 0x0013, 0x0000 }, + { 0x0013, 0x0001 }, + { 0x0013, 0x0002 }, + { 0x0013, 0x0003 }, + { 0x0012, 0x0003 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc20[32][2] = + { + { 0x0004, 0x0002 }, + { 0x0003, 0x0005 }, + { 0x0003, 0x0006 }, + { 0x0003, 0x0007 }, + { 0x0004, 0x0003 }, + { 0x0004, 0x0004 }, + { 0x0004, 0x0005 }, + { 0x0004, 0x0006 }, + { 0x0004, 0x0007 }, + { 0x0004, 0x0008 }, + { 0x0004, 0x0009 }, + { 0x0005, 0x0002 }, + { 0x0005, 0x0003 }, + { 0x0006, 0x0001 }, + { 0x0006, 0x0002 }, + { 0x0006, 0x0003 }, + { 0x0007, 0x0001 }, + { 0x0008, 0x0001 }, + { 0x0009, 0x0001 }, + { 0x000a, 0x0001 }, + { 0x000b, 0x0001 }, + { 0x000c, 0x0001 }, + { 0x000d, 0x0001 }, + { 0x000e, 0x0001 }, + { 0x000f, 0x0001 }, + { 0x0010, 0x0001 }, + { 0x0011, 0x0001 }, + { 0x0014, 0x0000 }, + { 0x0014, 0x0001 }, + { 0x0013, 0x0001 }, + { 0x0013, 0x0002 }, + { 0x0013, 0x0003 }, + }; + +const uint16_t c_aauiLCLDHuffEnc21[37][2] = + { + { 0x0005, 0x0002 }, + { 0x0003, 0x0006 }, + { 0x0003, 0x0007 }, + { 0x0004, 0x0003 }, + { 0x0004, 0x0004 }, + { 0x0004, 0x0005 }, + { 0x0004, 0x0006 }, + { 0x0004, 0x0007 }, + { 0x0004, 0x0008 }, + { 0x0004, 0x0009 }, + { 0x0004, 0x000a }, + { 0x0004, 0x000b }, + { 0x0005, 0x0003 }, + { 0x0005, 0x0004 }, + { 0x0005, 0x0005 }, + { 0x0006, 0x0002 }, + { 0x0006, 0x0003 }, + { 0x0007, 0x0002 }, + { 0x0007, 0x0003 }, + { 0x0008, 0x0001 }, + { 0x0008, 0x0002 }, + { 0x0008, 0x0003 }, + { 0x0009, 0x0001 }, + { 0x000b, 0x0001 }, + { 0x000b, 0x0002 }, + { 0x000b, 0x0003 }, + { 0x000c, 0x0001 }, + { 0x000d, 0x0001 }, + { 0x000e, 0x0001 }, + { 0x000f, 0x0001 }, + { 0x0010, 0x0001 }, + { 0x0011, 0x0001 }, + { 0x0014, 0x0000 }, + { 0x0014, 0x0001 }, + { 0x0013, 0x0001 }, + { 0x0013, 0x0002 }, + { 0x0013, 0x0003 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc22[39][2] = + { + { 0x0005, 0x0002 }, + { 0x0004, 0x0004 }, + { 0x0004, 0x0005 }, + { 0x0004, 0x0006 }, + { 0x0004, 0x0007 }, + { 0x0004, 0x0008 }, + { 0x0004, 0x0009 }, + { 0x0004, 0x000a }, + { 0x0004, 0x000b }, + { 0x0004, 0x000c }, + { 0x0004, 0x000d }, + { 0x0004, 0x000e }, + { 0x0004, 0x000f }, + { 0x0005, 0x0003 }, + { 0x0005, 0x0004 }, + { 0x0005, 0x0005 }, + { 0x0005, 0x0006 }, + { 0x0005, 0x0007 }, + { 0x0006, 0x0002 }, + { 0x0006, 0x0003 }, + { 0x0007, 0x0002 }, + { 0x0007, 0x0003 }, + { 0x0008, 0x0002 }, + { 0x0008, 0x0003 }, + { 0x0009, 0x0002 }, + { 0x0009, 0x0003 }, + { 0x000a, 0x0001 }, + { 0x000a, 0x0002 }, + { 0x000a, 0x0003 }, + { 0x000c, 0x0001 }, + { 0x000c, 0x0002 }, + { 0x000c, 0x0003 }, + { 0x000e, 0x0001 }, + { 0x000e, 0x0002 }, + { 0x000f, 0x0001 }, + { 0x000e, 0x0003 }, + { 0x0011, 0x0000 }, + { 0x0010, 0x0001 }, + { 0x0011, 0x0001 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc23[46][2] = + { + { 0x0005, 0x0003 }, + { 0x0004, 0x0006 }, + { 0x0004, 0x0007 }, + { 0x0004, 0x0008 }, + { 0x0004, 0x0009 }, + { 0x0004, 0x000a }, + { 0x0004, 0x000b }, + { 0x0004, 0x000c }, + { 0x0004, 0x000d }, + { 0x0004, 0x000e }, + { 0x0004, 0x000f }, + { 0x0005, 0x0004 }, + { 0x0005, 0x0005 }, + { 0x0005, 0x0006 }, + { 0x0005, 0x0007 }, + { 0x0005, 0x0008 }, + { 0x0005, 0x0009 }, + { 0x0005, 0x000a }, + { 0x0005, 0x000b }, + { 0x0006, 0x0003 }, + { 0x0006, 0x0004 }, + { 0x0006, 0x0005 }, + { 0x0007, 0x0002 }, + { 0x0007, 0x0003 }, + { 0x0007, 0x0004 }, + { 0x0007, 0x0005 }, + { 0x0008, 0x0002 }, + { 0x0008, 0x0003 }, + { 0x0009, 0x0002 }, + { 0x0009, 0x0003 }, + { 0x000a, 0x0002 }, + { 0x000a, 0x0003 }, + { 0x000b, 0x0002 }, + { 0x000b, 0x0003 }, + { 0x000c, 0x0002 }, + { 0x000c, 0x0003 }, + { 0x000d, 0x0002 }, + { 0x000d, 0x0003 }, + { 0x000e, 0x0001 }, + { 0x000e, 0x0002 }, + { 0x000e, 0x0003 }, + { 0x000f, 0x0001 }, + { 0x0010, 0x0001 }, + { 0x0012, 0x0000 }, + { 0x0012, 0x0001 }, + { 0x0011, 0x0001 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc24[55][2] = + { + { 0x0005, 0x0004 }, + { 0x0004, 0x0009 }, + { 0x0004, 0x000a }, + { 0x0004, 0x000b }, + { 0x0004, 0x000c }, + { 0x0004, 0x000d }, + { 0x0004, 0x000e }, + { 0x0004, 0x000f }, + { 0x0005, 0x0005 }, + { 0x0005, 0x0006 }, + { 0x0005, 0x0007 }, + { 0x0005, 0x0008 }, + { 0x0005, 0x0009 }, + { 0x0005, 0x000a }, + { 0x0005, 0x000b }, + { 0x0005, 0x000c }, + { 0x0005, 0x000d }, + { 0x0005, 0x000e }, + { 0x0005, 0x000f }, + { 0x0005, 0x0010 }, + { 0x0005, 0x0011 }, + { 0x0006, 0x0003 }, + { 0x0006, 0x0004 }, + { 0x0006, 0x0005 }, + { 0x0006, 0x0006 }, + { 0x0006, 0x0007 }, + { 0x0007, 0x0003 }, + { 0x0007, 0x0004 }, + { 0x0007, 0x0005 }, + { 0x0008, 0x0003 }, + { 0x0008, 0x0004 }, + { 0x0008, 0x0005 }, + { 0x0009, 0x0002 }, + { 0x0009, 0x0003 }, + { 0x0009, 0x0004 }, + { 0x0009, 0x0005 }, + { 0x000a, 0x0002 }, + { 0x000a, 0x0003 }, + { 0x000b, 0x0002 }, + { 0x000b, 0x0003 }, + { 0x000c, 0x0003 }, + { 0x000d, 0x0002 }, + { 0x000d, 0x0003 }, + { 0x000d, 0x0004 }, + { 0x000d, 0x0005 }, + { 0x000e, 0x0002 }, + { 0x000e, 0x0003 }, + { 0x000f, 0x0001 }, + { 0x000f, 0x0002 }, + { 0x000f, 0x0003 }, + { 0x0010, 0x0001 }, + { 0x0011, 0x0001 }, + { 0x0013, 0x0000 }, + { 0x0012, 0x0001 }, + { 0x0013, 0x0001 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc25[65][2] = + { + { 0x0005, 0x0005 }, + { 0x0004, 0x000c }, + { 0x0004, 0x000d }, + { 0x0004, 0x000e }, + { 0x0005, 0x0006 }, + { 0x0004, 0x000f }, + { 0x0005, 0x0007 }, + { 0x0005, 0x0008 }, + { 0x0005, 0x0009 }, + { 0x0005, 0x000a }, + { 0x0005, 0x000b }, + { 0x0005, 0x000c }, + { 0x0005, 0x000d }, + { 0x0005, 0x000e }, + { 0x0005, 0x000f }, + { 0x0005, 0x0010 }, + { 0x0005, 0x0011 }, + { 0x0005, 0x0012 }, + { 0x0005, 0x0013 }, + { 0x0005, 0x0014 }, + { 0x0005, 0x0015 }, + { 0x0005, 0x0016 }, + { 0x0005, 0x0017 }, + { 0x0006, 0x0004 }, + { 0x0006, 0x0005 }, + { 0x0006, 0x0006 }, + { 0x0006, 0x0007 }, + { 0x0006, 0x0008 }, + { 0x0006, 0x0009 }, + { 0x0007, 0x0003 }, + { 0x0007, 0x0004 }, + { 0x0007, 0x0005 }, + { 0x0007, 0x0006 }, + { 0x0007, 0x0007 }, + { 0x0008, 0x0003 }, + { 0x0008, 0x0004 }, + { 0x0008, 0x0005 }, + { 0x0009, 0x0003 }, + { 0x0009, 0x0004 }, + { 0x0009, 0x0005 }, + { 0x000a, 0x0003 }, + { 0x000a, 0x0004 }, + { 0x000a, 0x0005 }, + { 0x000b, 0x0003 }, + { 0x000b, 0x0004 }, + { 0x000b, 0x0005 }, + { 0x000c, 0x0002 }, + { 0x000c, 0x0003 }, + { 0x000c, 0x0004 }, + { 0x000c, 0x0005 }, + { 0x000d, 0x0003 }, + { 0x000e, 0x0003 }, + { 0x000e, 0x0004 }, + { 0x000f, 0x0003 }, + { 0x000e, 0x0005 }, + { 0x000f, 0x0004 }, + { 0x0010, 0x0001 }, + { 0x000f, 0x0005 }, + { 0x0010, 0x0002 }, + { 0x0010, 0x0003 }, + { 0x0010, 0x0004 }, + { 0x0010, 0x0005 }, + { 0x0011, 0x0001 }, + { 0x0012, 0x0000 }, + { 0x0012, 0x0001 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc26[77][2] = + { + { 0x0006, 0x0004 }, + { 0x0005, 0x0007 }, + { 0x0005, 0x0008 }, + { 0x0005, 0x0009 }, + { 0x0005, 0x000a }, + { 0x0005, 0x000b }, + { 0x0005, 0x000c }, + { 0x0005, 0x000d }, + { 0x0005, 0x000e }, + { 0x0005, 0x000f }, + { 0x0005, 0x0010 }, + { 0x0005, 0x0011 }, + { 0x0005, 0x0012 }, + { 0x0005, 0x0013 }, + { 0x0005, 0x0014 }, + { 0x0005, 0x0015 }, + { 0x0005, 0x0016 }, + { 0x0005, 0x0017 }, + { 0x0005, 0x0018 }, + { 0x0005, 0x0019 }, + { 0x0005, 0x001a }, + { 0x0005, 0x001b }, + { 0x0005, 0x001c }, + { 0x0005, 0x001d }, + { 0x0005, 0x001e }, + { 0x0005, 0x001f }, + { 0x0006, 0x0005 }, + { 0x0006, 0x0006 }, + { 0x0006, 0x0007 }, + { 0x0006, 0x0008 }, + { 0x0006, 0x0009 }, + { 0x0006, 0x000a }, + { 0x0006, 0x000b }, + { 0x0006, 0x000c }, + { 0x0006, 0x000d }, + { 0x0007, 0x0004 }, + { 0x0007, 0x0005 }, + { 0x0007, 0x0006 }, + { 0x0007, 0x0007 }, + { 0x0008, 0x0004 }, + { 0x0008, 0x0005 }, + { 0x0008, 0x0006 }, + { 0x0008, 0x0007 }, + { 0x0009, 0x0003 }, + { 0x0009, 0x0004 }, + { 0x0009, 0x0005 }, + { 0x0009, 0x0006 }, + { 0x0009, 0x0007 }, + { 0x000a, 0x0003 }, + { 0x000a, 0x0004 }, + { 0x000a, 0x0005 }, + { 0x000b, 0x0004 }, + { 0x000b, 0x0005 }, + { 0x000c, 0x0003 }, + { 0x000c, 0x0004 }, + { 0x000c, 0x0005 }, + { 0x000c, 0x0006 }, + { 0x000c, 0x0007 }, + { 0x000d, 0x0003 }, + { 0x000d, 0x0004 }, + { 0x000e, 0x0002 }, + { 0x000d, 0x0005 }, + { 0x000e, 0x0003 }, + { 0x000e, 0x0004 }, + { 0x000f, 0x0003 }, + { 0x000e, 0x0005 }, + { 0x0010, 0x0002 }, + { 0x0010, 0x0003 }, + { 0x0010, 0x0004 }, + { 0x0011, 0x0002 }, + { 0x0012, 0x0001 }, + { 0x0010, 0x0005 }, + { 0x0012, 0x0002 }, + { 0x0011, 0x0003 }, + { 0x0012, 0x0003 }, + { 0x0013, 0x0000 }, + { 0x0013, 0x0001 }, + + }; + + +const uint16_t c_aauiLCLDHuffEnc27[91][2] = + { + { 0x0006, 0x0006 }, + { 0x0005, 0x000b }, + { 0x0005, 0x000c }, + { 0x0005, 0x000d }, + { 0x0005, 0x000e }, + { 0x0005, 0x000f }, + { 0x0005, 0x0010 }, + { 0x0005, 0x0011 }, + { 0x0005, 0x0012 }, + { 0x0005, 0x0013 }, + { 0x0005, 0x0014 }, + { 0x0005, 0x0015 }, + { 0x0005, 0x0016 }, + { 0x0005, 0x0017 }, + { 0x0005, 0x0018 }, + { 0x0005, 0x0019 }, + { 0x0005, 0x001a }, + { 0x0005, 0x001b }, + { 0x0005, 0x001c }, + { 0x0005, 0x001d }, + { 0x0005, 0x001e }, + { 0x0005, 0x001f }, + { 0x0006, 0x0007 }, + { 0x0006, 0x0008 }, + { 0x0006, 0x0009 }, + { 0x0006, 0x000a }, + { 0x0006, 0x000b }, + { 0x0006, 0x000c }, + { 0x0006, 0x000d }, + { 0x0006, 0x000e }, + { 0x0006, 0x000f }, + { 0x0006, 0x0010 }, + { 0x0006, 0x0011 }, + { 0x0006, 0x0012 }, + { 0x0006, 0x0013 }, + { 0x0006, 0x0014 }, + { 0x0006, 0x0015 }, + { 0x0007, 0x0005 }, + { 0x0007, 0x0006 }, + { 0x0007, 0x0007 }, + { 0x0007, 0x0008 }, + { 0x0007, 0x0009 }, + { 0x0007, 0x000a }, + { 0x0007, 0x000b }, + { 0x0008, 0x0004 }, + { 0x0008, 0x0005 }, + { 0x0008, 0x0006 }, + { 0x0008, 0x0007 }, + { 0x0008, 0x0008 }, + { 0x0008, 0x0009 }, + { 0x0009, 0x0004 }, + { 0x0009, 0x0005 }, + { 0x0009, 0x0006 }, + { 0x0009, 0x0007 }, + { 0x000a, 0x0004 }, + { 0x000a, 0x0005 }, + { 0x000a, 0x0006 }, + { 0x000a, 0x0007 }, + { 0x000b, 0x0004 }, + { 0x000b, 0x0005 }, + { 0x000b, 0x0006 }, + { 0x000b, 0x0007 }, + { 0x000c, 0x0004 }, + { 0x000c, 0x0005 }, + { 0x000c, 0x0006 }, + { 0x000c, 0x0007 }, + { 0x000d, 0x0004 }, + { 0x000d, 0x0005 }, + { 0x000d, 0x0006 }, + { 0x000d, 0x0007 }, + { 0x000e, 0x0003 }, + { 0x000e, 0x0004 }, + { 0x000e, 0x0005 }, + { 0x000e, 0x0006 }, + { 0x000e, 0x0007 }, + { 0x000f, 0x0003 }, + { 0x000f, 0x0004 }, + { 0x0010, 0x0003 }, + { 0x000f, 0x0005 }, + { 0x0012, 0x0000 }, + { 0x0010, 0x0004 }, + { 0x0010, 0x0005 }, + { 0x0012, 0x0001 }, + { 0x0012, 0x0002 }, + { 0x0011, 0x0004 }, + { 0x0011, 0x0005 }, + { 0x0012, 0x0003 }, + { 0x0012, 0x0004 }, + { 0x0012, 0x0005 }, + { 0x0012, 0x0006 }, + { 0x0012, 0x0007 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc28[109][2] = + { + { 0x0006, 0x0008 }, + { 0x0005, 0x0010 }, + { 0x0005, 0x0011 }, + { 0x0005, 0x0012 }, + { 0x0005, 0x0013 }, + { 0x0005, 0x0014 }, + { 0x0005, 0x0015 }, + { 0x0005, 0x0016 }, + { 0x0005, 0x0017 }, + { 0x0005, 0x0018 }, + { 0x0005, 0x0019 }, + { 0x0005, 0x001a }, + { 0x0005, 0x001b }, + { 0x0005, 0x001c }, + { 0x0005, 0x001d }, + { 0x0005, 0x001e }, + { 0x0006, 0x0009 }, + { 0x0005, 0x001f }, + { 0x0006, 0x000a }, + { 0x0006, 0x000b }, + { 0x0006, 0x000c }, + { 0x0006, 0x000d }, + { 0x0006, 0x000e }, + { 0x0006, 0x000f }, + { 0x0006, 0x0010 }, + { 0x0006, 0x0011 }, + { 0x0006, 0x0012 }, + { 0x0006, 0x0013 }, + { 0x0006, 0x0014 }, + { 0x0006, 0x0015 }, + { 0x0006, 0x0016 }, + { 0x0006, 0x0017 }, + { 0x0006, 0x0018 }, + { 0x0006, 0x0019 }, + { 0x0006, 0x001a }, + { 0x0006, 0x001b }, + { 0x0006, 0x001c }, + { 0x0006, 0x001d }, + { 0x0006, 0x001e }, + { 0x0006, 0x001f }, + { 0x0007, 0x0006 }, + { 0x0007, 0x0007 }, + { 0x0007, 0x0008 }, + { 0x0007, 0x0009 }, + { 0x0007, 0x000a }, + { 0x0007, 0x000b }, + { 0x0007, 0x000c }, + { 0x0007, 0x000d }, + { 0x0007, 0x000e }, + { 0x0007, 0x000f }, + { 0x0008, 0x0005 }, + { 0x0008, 0x0006 }, + { 0x0008, 0x0007 }, + { 0x0008, 0x0008 }, + { 0x0008, 0x0009 }, + { 0x0008, 0x000a }, + { 0x0008, 0x000b }, + { 0x0009, 0x0004 }, + { 0x0009, 0x0005 }, + { 0x0009, 0x0006 }, + { 0x0009, 0x0007 }, + { 0x0009, 0x0008 }, + { 0x0009, 0x0009 }, + { 0x000a, 0x0005 }, + { 0x000a, 0x0006 }, + { 0x000a, 0x0007 }, + { 0x000b, 0x0005 }, + { 0x000b, 0x0006 }, + { 0x000b, 0x0007 }, + { 0x000b, 0x0008 }, + { 0x000b, 0x0009 }, + { 0x000c, 0x0004 }, + { 0x000c, 0x0005 }, + { 0x000c, 0x0006 }, + { 0x000c, 0x0007 }, + { 0x000c, 0x0008 }, + { 0x000c, 0x0009 }, + { 0x000d, 0x0004 }, + { 0x000d, 0x0005 }, + { 0x000d, 0x0006 }, + { 0x000d, 0x0007 }, + { 0x000e, 0x0004 }, + { 0x000e, 0x0005 }, + { 0x000e, 0x0006 }, + { 0x000e, 0x0007 }, + { 0x0010, 0x0004 }, + { 0x000f, 0x0005 }, + { 0x0010, 0x0005 }, + { 0x000f, 0x0006 }, + { 0x000f, 0x0007 }, + { 0x0010, 0x0006 }, + { 0x0011, 0x0006 }, + { 0x0010, 0x0007 }, + { 0x0013, 0x0000 }, + { 0x0010, 0x0008 }, + { 0x0010, 0x0009 }, + { 0x0013, 0x0001 }, + { 0x0011, 0x0007 }, + { 0x0012, 0x0001 }, + { 0x0012, 0x0002 }, + { 0x0012, 0x0003 }, + { 0x0012, 0x0004 }, + { 0x0012, 0x0005 }, + { 0x0012, 0x0006 }, + { 0x0012, 0x0007 }, + { 0x0012, 0x0008 }, + { 0x0012, 0x0009 }, + { 0x0012, 0x000a }, + { 0x0012, 0x000b }, + + }; + +const uint16_t c_aauiLCLDHuffEnc29[129][2] = + { + { 0x0006, 0x0009 }, + { 0x0005, 0x0019 }, + { 0x0006, 0x000a }, + { 0x0005, 0x001a }, + { 0x0005, 0x001b }, + { 0x0005, 0x001c }, + { 0x0006, 0x000b }, + { 0x0005, 0x001d }, + { 0x0005, 0x001e }, + { 0x0006, 0x000c }, + { 0x0006, 0x000d }, + { 0x0005, 0x001f }, + { 0x0006, 0x000e }, + { 0x0006, 0x000f }, + { 0x0006, 0x0010 }, + { 0x0006, 0x0011 }, + { 0x0006, 0x0012 }, + { 0x0006, 0x0013 }, + { 0x0006, 0x0014 }, + { 0x0006, 0x0015 }, + { 0x0006, 0x0016 }, + { 0x0006, 0x0017 }, + { 0x0006, 0x0018 }, + { 0x0006, 0x0019 }, + { 0x0006, 0x001a }, + { 0x0006, 0x001b }, + { 0x0006, 0x001c }, + { 0x0006, 0x001d }, + { 0x0006, 0x001e }, + { 0x0006, 0x001f }, + { 0x0006, 0x0020 }, + { 0x0006, 0x0021 }, + { 0x0006, 0x0022 }, + { 0x0006, 0x0023 }, + { 0x0006, 0x0024 }, + { 0x0006, 0x0025 }, + { 0x0006, 0x0026 }, + { 0x0006, 0x0027 }, + { 0x0006, 0x0028 }, + { 0x0006, 0x0029 }, + { 0x0006, 0x002a }, + { 0x0006, 0x002b }, + { 0x0006, 0x002c }, + { 0x0006, 0x002d }, + { 0x0006, 0x002e }, + { 0x0006, 0x002f }, + { 0x0006, 0x0030 }, + { 0x0006, 0x0031 }, + { 0x0007, 0x0007 }, + { 0x0007, 0x0008 }, + { 0x0007, 0x0009 }, + { 0x0007, 0x000a }, + { 0x0007, 0x000b }, + { 0x0007, 0x000c }, + { 0x0007, 0x000d }, + { 0x0007, 0x000e }, + { 0x0007, 0x000f }, + { 0x0007, 0x0010 }, + { 0x0007, 0x0011 }, + { 0x0008, 0x0006 }, + { 0x0008, 0x0007 }, + { 0x0008, 0x0008 }, + { 0x0008, 0x0009 }, + { 0x0008, 0x000a }, + { 0x0008, 0x000b }, + { 0x0008, 0x000c }, + { 0x0008, 0x000d }, + { 0x0009, 0x0006 }, + { 0x0009, 0x0007 }, + { 0x0009, 0x0008 }, + { 0x0009, 0x0009 }, + { 0x0009, 0x000a }, + { 0x0009, 0x000b }, + { 0x000a, 0x0005 }, + { 0x000a, 0x0006 }, + { 0x000a, 0x0007 }, + { 0x000a, 0x0008 }, + { 0x000a, 0x0009 }, + { 0x000a, 0x000a }, + { 0x000a, 0x000b }, + { 0x000b, 0x0006 }, + { 0x000b, 0x0007 }, + { 0x000b, 0x0008 }, + { 0x000b, 0x0009 }, + { 0x000c, 0x0006 }, + { 0x000c, 0x0007 }, + { 0x000c, 0x0008 }, + { 0x000c, 0x0009 }, + { 0x000c, 0x000a }, + { 0x000c, 0x000b }, + { 0x000d, 0x0005 }, + { 0x000d, 0x0006 }, + { 0x000d, 0x0007 }, + { 0x000d, 0x0008 }, + { 0x000d, 0x0009 }, + { 0x000d, 0x000a }, + { 0x000d, 0x000b }, + { 0x000e, 0x0006 }, + { 0x000e, 0x0007 }, + { 0x000e, 0x0008 }, + { 0x000e, 0x0009 }, + { 0x000f, 0x0004 }, + { 0x000f, 0x0005 }, + { 0x000f, 0x0006 }, + { 0x000f, 0x0007 }, + { 0x0011, 0x0007 }, + { 0x000f, 0x0008 }, + { 0x0012, 0x0000 }, + { 0x000f, 0x0009 }, + { 0x0010, 0x0005 }, + { 0x000f, 0x000a }, + { 0x000f, 0x000b }, + { 0x0012, 0x0001 }, + { 0x0010, 0x0006 }, + { 0x0010, 0x0007 }, + { 0x0012, 0x0002 }, + { 0x0012, 0x0003 }, + { 0x0012, 0x0004 }, + { 0x0012, 0x0005 }, + { 0x0012, 0x0006 }, + { 0x0012, 0x0007 }, + { 0x0012, 0x0008 }, + { 0x0011, 0x0008 }, + { 0x0012, 0x0009 }, + { 0x0012, 0x000a }, + { 0x0012, 0x000b }, + { 0x0012, 0x000c }, + { 0x0012, 0x000d }, + { 0x0011, 0x0009 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc30[153][2] = + { + { 0x0007, 0x0009 }, + { 0x0006, 0x000e }, + { 0x0006, 0x000f }, + { 0x0006, 0x0010 }, + { 0x0006, 0x0011 }, + { 0x0006, 0x0012 }, + { 0x0006, 0x0013 }, + { 0x0006, 0x0014 }, + { 0x0006, 0x0015 }, + { 0x0006, 0x0016 }, + { 0x0006, 0x0017 }, + { 0x0006, 0x0018 }, + { 0x0006, 0x0019 }, + { 0x0006, 0x001a }, + { 0x0006, 0x001b }, + { 0x0006, 0x001c }, + { 0x0006, 0x001d }, + { 0x0006, 0x001e }, + { 0x0006, 0x001f }, + { 0x0006, 0x0020 }, + { 0x0006, 0x0021 }, + { 0x0006, 0x0022 }, + { 0x0006, 0x0023 }, + { 0x0006, 0x0024 }, + { 0x0006, 0x0025 }, + { 0x0006, 0x0026 }, + { 0x0006, 0x0027 }, + { 0x0006, 0x0028 }, + { 0x0006, 0x0029 }, + { 0x0006, 0x002a }, + { 0x0006, 0x002b }, + { 0x0006, 0x002c }, + { 0x0006, 0x002d }, + { 0x0006, 0x002e }, + { 0x0006, 0x002f }, + { 0x0006, 0x0030 }, + { 0x0006, 0x0031 }, + { 0x0006, 0x0032 }, + { 0x0006, 0x0033 }, + { 0x0006, 0x0034 }, + { 0x0006, 0x0035 }, + { 0x0006, 0x0036 }, + { 0x0006, 0x0037 }, + { 0x0006, 0x0038 }, + { 0x0006, 0x0039 }, + { 0x0006, 0x003a }, + { 0x0006, 0x003b }, + { 0x0006, 0x003c }, + { 0x0006, 0x003d }, + { 0x0006, 0x003e }, + { 0x0006, 0x003f }, + { 0x0007, 0x000a }, + { 0x0007, 0x000b }, + { 0x0007, 0x000c }, + { 0x0007, 0x000d }, + { 0x0007, 0x000e }, + { 0x0007, 0x000f }, + { 0x0007, 0x0010 }, + { 0x0007, 0x0011 }, + { 0x0007, 0x0012 }, + { 0x0007, 0x0013 }, + { 0x0007, 0x0014 }, + { 0x0007, 0x0015 }, + { 0x0007, 0x0016 }, + { 0x0007, 0x0017 }, + { 0x0007, 0x0018 }, + { 0x0007, 0x0019 }, + { 0x0007, 0x001a }, + { 0x0007, 0x001b }, + { 0x0008, 0x0008 }, + { 0x0008, 0x0009 }, + { 0x0008, 0x000a }, + { 0x0008, 0x000b }, + { 0x0008, 0x000c }, + { 0x0008, 0x000d }, + { 0x0008, 0x000e }, + { 0x0008, 0x000f }, + { 0x0008, 0x0010 }, + { 0x0008, 0x0011 }, + { 0x0009, 0x0007 }, + { 0x0009, 0x0008 }, + { 0x0009, 0x0009 }, + { 0x0009, 0x000a }, + { 0x0009, 0x000b }, + { 0x0009, 0x000c }, + { 0x0009, 0x000d }, + { 0x0009, 0x000e }, + { 0x000a, 0x0008 }, + { 0x0009, 0x000f }, + { 0x000a, 0x0009 }, + { 0x000a, 0x000a }, + { 0x000a, 0x000b }, + { 0x000a, 0x000c }, + { 0x000a, 0x000d }, + { 0x000b, 0x0007 }, + { 0x000b, 0x0008 }, + { 0x000b, 0x0009 }, + { 0x000b, 0x000a }, + { 0x000b, 0x000b }, + { 0x000b, 0x000c }, + { 0x000b, 0x000d }, + { 0x000c, 0x0008 }, + { 0x000b, 0x000e }, + { 0x000b, 0x000f }, + { 0x000c, 0x0009 }, + { 0x000c, 0x000a }, + { 0x000d, 0x0008 }, + { 0x000c, 0x000b }, + { 0x000c, 0x000c }, + { 0x000d, 0x0009 }, + { 0x000c, 0x000d }, + { 0x000d, 0x000a }, + { 0x000d, 0x000b }, + { 0x000d, 0x000c }, + { 0x000d, 0x000d }, + { 0x000e, 0x0008 }, + { 0x000d, 0x000e }, + { 0x000d, 0x000f }, + { 0x000e, 0x0009 }, + { 0x000e, 0x000a }, + { 0x000e, 0x000b }, + { 0x000e, 0x000c }, + { 0x000f, 0x0006 }, + { 0x000f, 0x0007 }, + { 0x000f, 0x0008 }, + { 0x0010, 0x0006 }, + { 0x000e, 0x000d }, + { 0x000e, 0x000e }, + { 0x000e, 0x000f }, + { 0x0010, 0x0007 }, + { 0x000f, 0x0009 }, + { 0x0010, 0x0008 }, + { 0x000f, 0x000a }, + { 0x000f, 0x000b }, + { 0x000f, 0x000c }, + { 0x000f, 0x000d }, + { 0x0010, 0x0009 }, + { 0x0011, 0x0000 }, + { 0x0011, 0x0001 }, + { 0x0011, 0x0002 }, + { 0x000f, 0x000e }, + { 0x0010, 0x000a }, + { 0x0011, 0x0003 }, + { 0x0011, 0x0004 }, + { 0x0011, 0x0005 }, + { 0x000f, 0x000f }, + { 0x0011, 0x0006 }, + { 0x0011, 0x0007 }, + { 0x0011, 0x0008 }, + { 0x0011, 0x0009 }, + { 0x0011, 0x000a }, + { 0x0011, 0x000b }, + { 0x0010, 0x000b }, + + }; + +const uint16_t c_aauiLCLDHuffEnc31[181][2] = + { + { 0x0007, 0x000b }, + { 0x0006, 0x0015 }, + { 0x0006, 0x0016 }, + { 0x0006, 0x0017 }, + { 0x0006, 0x0018 }, + { 0x0006, 0x0019 }, + { 0x0006, 0x001a }, + { 0x0006, 0x001b }, + { 0x0006, 0x001c }, + { 0x0006, 0x001d }, + { 0x0006, 0x001e }, + { 0x0006, 0x001f }, + { 0x0006, 0x0020 }, + { 0x0006, 0x0021 }, + { 0x0006, 0x0022 }, + { 0x0006, 0x0023 }, + { 0x0006, 0x0024 }, + { 0x0006, 0x0025 }, + { 0x0006, 0x0026 }, + { 0x0006, 0x0027 }, + { 0x0006, 0x0028 }, + { 0x0006, 0x0029 }, + { 0x0006, 0x002a }, + { 0x0006, 0x002b }, + { 0x0006, 0x002c }, + { 0x0006, 0x002d }, + { 0x0006, 0x002e }, + { 0x0006, 0x002f }, + { 0x0006, 0x0030 }, + { 0x0006, 0x0031 }, + { 0x0006, 0x0032 }, + { 0x0006, 0x0033 }, + { 0x0006, 0x0034 }, + { 0x0006, 0x0035 }, + { 0x0006, 0x0036 }, + { 0x0006, 0x0037 }, + { 0x0006, 0x0038 }, + { 0x0006, 0x0039 }, + { 0x0006, 0x003a }, + { 0x0006, 0x003b }, + { 0x0006, 0x003c }, + { 0x0006, 0x003d }, + { 0x0006, 0x003e }, + { 0x0007, 0x000c }, + { 0x0006, 0x003f }, + { 0x0007, 0x000d }, + { 0x0007, 0x000e }, + { 0x0007, 0x000f }, + { 0x0007, 0x0010 }, + { 0x0007, 0x0011 }, + { 0x0007, 0x0012 }, + { 0x0007, 0x0013 }, + { 0x0007, 0x0014 }, + { 0x0007, 0x0015 }, + { 0x0007, 0x0016 }, + { 0x0007, 0x0017 }, + { 0x0007, 0x0018 }, + { 0x0007, 0x0019 }, + { 0x0007, 0x001a }, + { 0x0007, 0x001b }, + { 0x0007, 0x001c }, + { 0x0007, 0x001d }, + { 0x0007, 0x001e }, + { 0x0007, 0x001f }, + { 0x0007, 0x0020 }, + { 0x0007, 0x0021 }, + { 0x0007, 0x0022 }, + { 0x0007, 0x0023 }, + { 0x0007, 0x0024 }, + { 0x0007, 0x0025 }, + { 0x0007, 0x0026 }, + { 0x0007, 0x0027 }, + { 0x0007, 0x0028 }, + { 0x0007, 0x0029 }, + { 0x0008, 0x0009 }, + { 0x0008, 0x000a }, + { 0x0008, 0x000b }, + { 0x0008, 0x000c }, + { 0x0008, 0x000d }, + { 0x0008, 0x000e }, + { 0x0008, 0x000f }, + { 0x0008, 0x0010 }, + { 0x0008, 0x0011 }, + { 0x0008, 0x0012 }, + { 0x0008, 0x0013 }, + { 0x0008, 0x0014 }, + { 0x0008, 0x0015 }, + { 0x0009, 0x0008 }, + { 0x0009, 0x0009 }, + { 0x0009, 0x000a }, + { 0x0009, 0x000b }, + { 0x0009, 0x000c }, + { 0x0009, 0x000d }, + { 0x0009, 0x000e }, + { 0x0009, 0x000f }, + { 0x0009, 0x0010 }, + { 0x0009, 0x0011 }, + { 0x000a, 0x0008 }, + { 0x000a, 0x0009 }, + { 0x000a, 0x000a }, + { 0x000a, 0x000b }, + { 0x000a, 0x000c }, + { 0x000a, 0x000d }, + { 0x000a, 0x000e }, + { 0x000a, 0x000f }, + { 0x000b, 0x0008 }, + { 0x000b, 0x0009 }, + { 0x000b, 0x000a }, + { 0x000b, 0x000b }, + { 0x000b, 0x000c }, + { 0x000b, 0x000d }, + { 0x000b, 0x000e }, + { 0x000c, 0x0008 }, + { 0x000c, 0x0009 }, + { 0x000b, 0x000f }, + { 0x000c, 0x000a }, + { 0x000c, 0x000b }, + { 0x000c, 0x000c }, + { 0x000c, 0x000d }, + { 0x000d, 0x0008 }, + { 0x000c, 0x000e }, + { 0x000d, 0x0009 }, + { 0x000d, 0x000a }, + { 0x000c, 0x000f }, + { 0x000d, 0x000b }, + { 0x000d, 0x000c }, + { 0x000d, 0x000d }, + { 0x000d, 0x000e }, + { 0x000d, 0x000f }, + { 0x000e, 0x0008 }, + { 0x000e, 0x0009 }, + { 0x000e, 0x000a }, + { 0x000e, 0x000b }, + { 0x000e, 0x000c }, + { 0x000e, 0x000d }, + { 0x000e, 0x000e }, + { 0x000e, 0x000f }, + { 0x000f, 0x0009 }, + { 0x000f, 0x000a }, + { 0x000f, 0x000b }, + { 0x000f, 0x000c }, + { 0x0010, 0x0009 }, + { 0x000f, 0x000d }, + { 0x000f, 0x000e }, + { 0x0010, 0x000a }, + { 0x0010, 0x000b }, + { 0x0010, 0x000c }, + { 0x0010, 0x000d }, + { 0x0011, 0x000a }, + { 0x0010, 0x000e }, + { 0x000f, 0x000f }, + { 0x0010, 0x000f }, + { 0x0012, 0x0000 }, + { 0x0012, 0x0001 }, + { 0x0011, 0x000b }, + { 0x0011, 0x000c }, + { 0x0010, 0x0010 }, + { 0x0012, 0x0002 }, + { 0x0012, 0x0003 }, + { 0x0011, 0x000d }, + { 0x0011, 0x000e }, + { 0x0011, 0x000f }, + { 0x0011, 0x0010 }, + { 0x0011, 0x0011 }, + { 0x0010, 0x0011 }, + { 0x0012, 0x0004 }, + { 0x0012, 0x0005 }, + { 0x0012, 0x0006 }, + { 0x0012, 0x0007 }, + { 0x0012, 0x0008 }, + { 0x0012, 0x0009 }, + { 0x0012, 0x000a }, + { 0x0012, 0x000b }, + { 0x0012, 0x000c }, + { 0x0012, 0x000d }, + { 0x0012, 0x000e }, + { 0x0012, 0x000f }, + { 0x0012, 0x0010 }, + { 0x0012, 0x0011 }, + { 0x0012, 0x0012 }, + { 0x0012, 0x0013 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc33[16][2] = + { + { 0x0001, 0x0001 }, + { 0x0003, 0x0001 }, + { 0x0008, 0x0000 }, + { 0x0008, 0x0001 }, + { 0x0002, 0x0001 }, + { 0x0004, 0x0001 }, + { 0x0008, 0x0002 }, + { 0x0008, 0x0003 }, + { 0x0008, 0x0004 }, + { 0x0008, 0x0005 }, + { 0x0008, 0x0006 }, + { 0x0008, 0x0007 }, + { 0x0007, 0x0004 }, + { 0x0007, 0x0005 }, + { 0x0007, 0x0006 }, + { 0x0007, 0x0007 }, + }; + +const uint16_t c_aauiLCLDHuffEnc34[16][2] = + { + { 0x0001, 0x0001 }, + { 0x0003, 0x0001 }, + { 0x0008, 0x0000 }, + { 0x0008, 0x0001 }, + { 0x0002, 0x0001 }, + { 0x0004, 0x0001 }, + { 0x0008, 0x0002 }, + { 0x0008, 0x0003 }, + { 0x0008, 0x0004 }, + { 0x0008, 0x0005 }, + { 0x0008, 0x0006 }, + { 0x0008, 0x0007 }, + { 0x0007, 0x0004 }, + { 0x0007, 0x0005 }, + { 0x0007, 0x0006 }, + { 0x0007, 0x0007 }, + }; + +const uint16_t c_aauiLCLDHuffEnc35[25][2] = + { + { 0x0001, 0x0001 }, + { 0x0003, 0x0001 }, + { 0x0007, 0x0006 }, + { 0x0009, 0x0000 }, + { 0x0009, 0x0001 }, + { 0x0002, 0x0001 }, + { 0x0004, 0x0001 }, + { 0x0009, 0x0002 }, + { 0x0009, 0x0003 }, + { 0x0009, 0x0004 }, + { 0x0007, 0x0007 }, + { 0x0009, 0x0005 }, + { 0x0009, 0x0006 }, + { 0x0009, 0x0007 }, + { 0x0009, 0x0008 }, + { 0x0009, 0x0009 }, + { 0x0009, 0x000a }, + { 0x0009, 0x000b }, + { 0x0009, 0x000c }, + { 0x0009, 0x000d }, + { 0x0008, 0x0007 }, + { 0x0008, 0x0008 }, + { 0x0008, 0x0009 }, + { 0x0008, 0x000a }, + { 0x0008, 0x000b }, + + }; + +const uint16_t c_aauiLCLDHuffEnc36[36][2] = + { + { 0x0001, 0x0001 }, + { 0x0002, 0x0001 }, + { 0x0006, 0x0002 }, + { 0x000b, 0x0000 }, + { 0x000b, 0x0001 }, + { 0x000b, 0x0002 }, + { 0x0003, 0x0001 }, + { 0x0004, 0x0001 }, + { 0x0008, 0x0005 }, + { 0x000b, 0x0003 }, + { 0x000b, 0x0004 }, + { 0x000b, 0x0005 }, + { 0x0006, 0x0003 }, + { 0x0007, 0x0003 }, + { 0x000b, 0x0006 }, + { 0x000b, 0x0007 }, + { 0x000b, 0x0008 }, + { 0x000b, 0x0009 }, + { 0x000b, 0x000a }, + { 0x000b, 0x000b }, + { 0x000b, 0x000c }, + { 0x000b, 0x000d }, + { 0x000b, 0x000e }, + { 0x000b, 0x000f }, + { 0x000a, 0x0008 }, + { 0x000a, 0x0009 }, + { 0x000a, 0x000a }, + { 0x000a, 0x000b }, + { 0x000a, 0x000c }, + { 0x000a, 0x000d }, + { 0x000a, 0x000e }, + { 0x000a, 0x000f }, + { 0x000a, 0x0010 }, + { 0x000a, 0x0011 }, + { 0x000a, 0x0012 }, + { 0x000a, 0x0013 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc37[36][2] = + { + { 0x0001, 0x0001 }, + { 0x0002, 0x0001 }, + { 0x0006, 0x0001 }, + { 0x000c, 0x0000 }, + { 0x000c, 0x0001 }, + { 0x000c, 0x0002 }, + { 0x0003, 0x0001 }, + { 0x0004, 0x0001 }, + { 0x0006, 0x0002 }, + { 0x000c, 0x0003 }, + { 0x000c, 0x0004 }, + { 0x000c, 0x0005 }, + { 0x0006, 0x0003 }, + { 0x0007, 0x0001 }, + { 0x000a, 0x0007 }, + { 0x000c, 0x0006 }, + { 0x000c, 0x0007 }, + { 0x000c, 0x0008 }, + { 0x000c, 0x0009 }, + { 0x000c, 0x000a }, + { 0x000c, 0x000b }, + { 0x000c, 0x000c }, + { 0x000c, 0x000d }, + { 0x000c, 0x000e }, + { 0x000c, 0x000f }, + { 0x000c, 0x0010 }, + { 0x000c, 0x0011 }, + { 0x000c, 0x0012 }, + { 0x000c, 0x0013 }, + { 0x000c, 0x0014 }, + { 0x000c, 0x0015 }, + { 0x000c, 0x0016 }, + { 0x000c, 0x0017 }, + { 0x000c, 0x0018 }, + { 0x000c, 0x0019 }, + { 0x000b, 0x000d }, + + }; + +const uint16_t c_aauiLCLDHuffEnc38[49][2] = + { + { 0x0001, 0x0001 }, + { 0x0003, 0x0001 }, + { 0x0006, 0x0001 }, + { 0x000c, 0x0012 }, + { 0x000d, 0x0000 }, + { 0x000d, 0x0001 }, + { 0x000d, 0x0002 }, + { 0x0002, 0x0001 }, + { 0x0004, 0x0001 }, + { 0x0007, 0x0001 }, + { 0x000b, 0x000a }, + { 0x000d, 0x0003 }, + { 0x000d, 0x0004 }, + { 0x000d, 0x0005 }, + { 0x0006, 0x0002 }, + { 0x0006, 0x0003 }, + { 0x0009, 0x0003 }, + { 0x000d, 0x0006 }, + { 0x000d, 0x0007 }, + { 0x000d, 0x0008 }, + { 0x000d, 0x0009 }, + { 0x000c, 0x0013 }, + { 0x000b, 0x000b }, + { 0x000d, 0x000a }, + { 0x000d, 0x000b }, + { 0x000d, 0x000c }, + { 0x000d, 0x000d }, + { 0x000d, 0x000e }, + { 0x000d, 0x000f }, + { 0x000d, 0x0010 }, + { 0x000d, 0x0011 }, + { 0x000d, 0x0012 }, + { 0x000d, 0x0013 }, + { 0x000d, 0x0014 }, + { 0x000d, 0x0015 }, + { 0x000d, 0x0016 }, + { 0x000d, 0x0017 }, + { 0x000d, 0x0018 }, + { 0x000d, 0x0019 }, + { 0x000d, 0x001a }, + { 0x000d, 0x001b }, + { 0x000d, 0x001c }, + { 0x000d, 0x001d }, + { 0x000d, 0x001e }, + { 0x000d, 0x001f }, + { 0x000d, 0x0020 }, + { 0x000d, 0x0021 }, + { 0x000d, 0x0022 }, + { 0x000d, 0x0023 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc39[64][2] = + { + { 0x0001, 0x0001 }, + { 0x0002, 0x0001 }, + { 0x0006, 0x0001 }, + { 0x000a, 0x0002 }, + { 0x000f, 0x0000 }, + { 0x000f, 0x0001 }, + { 0x000f, 0x0002 }, + { 0x000f, 0x0003 }, + { 0x0003, 0x0001 }, + { 0x0004, 0x0001 }, + { 0x0007, 0x0001 }, + { 0x000a, 0x0003 }, + { 0x000f, 0x0004 }, + { 0x000f, 0x0005 }, + { 0x000f, 0x0006 }, + { 0x000f, 0x0007 }, + { 0x0006, 0x0002 }, + { 0x0006, 0x0003 }, + { 0x0009, 0x0003 }, + { 0x000d, 0x000e }, + { 0x000f, 0x0008 }, + { 0x000f, 0x0009 }, + { 0x000f, 0x000a }, + { 0x000f, 0x000b }, + { 0x000a, 0x0004 }, + { 0x000a, 0x0005 }, + { 0x000d, 0x000f }, + { 0x000f, 0x000c }, + { 0x000f, 0x000d }, + { 0x000f, 0x000e }, + { 0x000f, 0x000f }, + { 0x000f, 0x0010 }, + { 0x000f, 0x0011 }, + { 0x000f, 0x0012 }, + { 0x000f, 0x0013 }, + { 0x000f, 0x0014 }, + { 0x000f, 0x0015 }, + { 0x000f, 0x0016 }, + { 0x000f, 0x0017 }, + { 0x000f, 0x0018 }, + { 0x000f, 0x0019 }, + { 0x000f, 0x001a }, + { 0x000f, 0x001b }, + { 0x000f, 0x001c }, + { 0x000f, 0x001d }, + { 0x000f, 0x001e }, + { 0x000f, 0x001f }, + { 0x000f, 0x0020 }, + { 0x000f, 0x0021 }, + { 0x000f, 0x0022 }, + { 0x000f, 0x0023 }, + { 0x000f, 0x0024 }, + { 0x000f, 0x0025 }, + { 0x000f, 0x0026 }, + { 0x000f, 0x0027 }, + { 0x000f, 0x0028 }, + { 0x000f, 0x0029 }, + { 0x000e, 0x0015 }, + { 0x000e, 0x0016 }, + { 0x000e, 0x0017 }, + { 0x000e, 0x0018 }, + { 0x000e, 0x0019 }, + { 0x000e, 0x001a }, + { 0x000e, 0x001b }, + }; + +const uint16_t c_aauiLCLDHuffEnc40[81][2] = + { + { 0x0001, 0x0001 }, + { 0x0002, 0x0001 }, + { 0x0006, 0x0001 }, + { 0x000b, 0x0002 }, + { 0x000f, 0x0011 }, + { 0x0011, 0x0000 }, + { 0x0011, 0x0001 }, + { 0x0011, 0x0002 }, + { 0x0011, 0x0003 }, + { 0x0003, 0x0001 }, + { 0x0004, 0x0001 }, + { 0x0007, 0x0001 }, + { 0x000a, 0x0002 }, + { 0x000e, 0x0009 }, + { 0x0011, 0x0004 }, + { 0x0011, 0x0005 }, + { 0x0011, 0x0006 }, + { 0x0011, 0x0007 }, + { 0x0006, 0x0002 }, + { 0x0006, 0x0003 }, + { 0x0008, 0x0001 }, + { 0x000d, 0x0005 }, + { 0x0011, 0x0008 }, + { 0x0011, 0x0009 }, + { 0x0011, 0x000a }, + { 0x0011, 0x000b }, + { 0x0011, 0x000c }, + { 0x000b, 0x0003 }, + { 0x000a, 0x0003 }, + { 0x000c, 0x0003 }, + { 0x0011, 0x000d }, + { 0x0011, 0x000e }, + { 0x0011, 0x000f }, + { 0x0011, 0x0010 }, + { 0x0011, 0x0011 }, + { 0x0011, 0x0012 }, + { 0x0011, 0x0013 }, + { 0x0011, 0x0014 }, + { 0x0011, 0x0015 }, + { 0x0011, 0x0016 }, + { 0x0011, 0x0017 }, + { 0x0011, 0x0018 }, + { 0x0011, 0x0019 }, + { 0x0011, 0x001a }, + { 0x0011, 0x001b }, + { 0x0011, 0x001c }, + { 0x0011, 0x001d }, + { 0x0011, 0x001e }, + { 0x0011, 0x001f }, + { 0x0011, 0x0020 }, + { 0x0011, 0x0021 }, + { 0x0011, 0x0022 }, + { 0x0011, 0x0023 }, + { 0x0011, 0x0024 }, + { 0x0011, 0x0025 }, + { 0x0011, 0x0026 }, + { 0x0011, 0x0027 }, + { 0x0011, 0x0028 }, + { 0x0011, 0x0029 }, + { 0x0011, 0x002a }, + { 0x0011, 0x002b }, + { 0x0011, 0x002c }, + { 0x0011, 0x002d }, + { 0x0011, 0x002e }, + { 0x0011, 0x002f }, + { 0x0011, 0x0030 }, + { 0x0011, 0x0031 }, + { 0x0011, 0x0032 }, + { 0x0011, 0x0033 }, + { 0x0011, 0x0034 }, + { 0x0011, 0x0035 }, + { 0x0011, 0x0036 }, + { 0x0011, 0x0037 }, + { 0x0011, 0x0038 }, + { 0x0011, 0x0039 }, + { 0x0011, 0x003a }, + { 0x0011, 0x003b }, + { 0x0010, 0x001e }, + { 0x0010, 0x001f }, + { 0x0010, 0x0020 }, + { 0x0010, 0x0021 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc41[100][2] = + { + { 0x0001, 0x0001 }, + { 0x0003, 0x0001 }, + { 0x0006, 0x0001 }, + { 0x000b, 0x0001 }, + { 0x0011, 0x0014 }, + { 0x0013, 0x0000 }, + { 0x0013, 0x0001 }, + { 0x0013, 0x0002 }, + { 0x0013, 0x0003 }, + { 0x0013, 0x0004 }, + { 0x0002, 0x0001 }, + { 0x0004, 0x0001 }, + { 0x0007, 0x0001 }, + { 0x000a, 0x0001 }, + { 0x0010, 0x000b }, + { 0x0013, 0x0005 }, + { 0x0013, 0x0006 }, + { 0x0013, 0x0007 }, + { 0x0013, 0x0008 }, + { 0x0013, 0x0009 }, + { 0x0006, 0x0002 }, + { 0x0006, 0x0003 }, + { 0x0008, 0x0001 }, + { 0x000d, 0x0002 }, + { 0x0011, 0x0015 }, + { 0x0013, 0x000a }, + { 0x0013, 0x000b }, + { 0x0013, 0x000c }, + { 0x0013, 0x000d }, + { 0x0013, 0x000e }, + { 0x000a, 0x0002 }, + { 0x000a, 0x0003 }, + { 0x000d, 0x0003 }, + { 0x0010, 0x000c }, + { 0x0013, 0x000f }, + { 0x0013, 0x0010 }, + { 0x0013, 0x0011 }, + { 0x0013, 0x0012 }, + { 0x0013, 0x0013 }, + { 0x0013, 0x0014 }, + { 0x0010, 0x000d }, + { 0x000f, 0x0007 }, + { 0x0012, 0x0027 }, + { 0x0013, 0x0015 }, + { 0x0013, 0x0016 }, + { 0x0013, 0x0017 }, + { 0x0013, 0x0018 }, + { 0x0013, 0x0019 }, + { 0x0013, 0x001a }, + { 0x0013, 0x001b }, + { 0x0013, 0x001c }, + { 0x0013, 0x001d }, + { 0x0013, 0x001e }, + { 0x0013, 0x001f }, + { 0x0013, 0x0020 }, + { 0x0013, 0x0021 }, + { 0x0013, 0x0022 }, + { 0x0013, 0x0023 }, + { 0x0013, 0x0024 }, + { 0x0013, 0x0025 }, + { 0x0013, 0x0026 }, + { 0x0013, 0x0027 }, + { 0x0013, 0x0028 }, + { 0x0013, 0x0029 }, + { 0x0013, 0x002a }, + { 0x0013, 0x002b }, + { 0x0013, 0x002c }, + { 0x0013, 0x002d }, + { 0x0013, 0x002e }, + { 0x0013, 0x002f }, + { 0x0013, 0x0030 }, + { 0x0013, 0x0031 }, + { 0x0013, 0x0032 }, + { 0x0013, 0x0033 }, + { 0x0013, 0x0034 }, + { 0x0013, 0x0035 }, + { 0x0013, 0x0036 }, + { 0x0013, 0x0037 }, + { 0x0013, 0x0038 }, + { 0x0013, 0x0039 }, + { 0x0013, 0x003a }, + { 0x0013, 0x003b }, + { 0x0013, 0x003c }, + { 0x0013, 0x003d }, + { 0x0013, 0x003e }, + { 0x0013, 0x003f }, + { 0x0013, 0x0040 }, + { 0x0013, 0x0041 }, + { 0x0013, 0x0042 }, + { 0x0013, 0x0043 }, + { 0x0013, 0x0044 }, + { 0x0013, 0x0045 }, + { 0x0013, 0x0046 }, + { 0x0013, 0x0047 }, + { 0x0013, 0x0048 }, + { 0x0013, 0x0049 }, + { 0x0013, 0x004a }, + { 0x0013, 0x004b }, + { 0x0013, 0x004c }, + { 0x0013, 0x004d }, + + }; + +const uint16_t c_aauiLCLDHuffEnc42[169][2] = + { + { 0x0001, 0x0001 }, + { 0x0003, 0x0001 }, + { 0x0006, 0x0001 }, + { 0x0009, 0x0001 }, + { 0x000e, 0x0006 }, + { 0x0013, 0x0000 }, + { 0x0013, 0x0001 }, + { 0x0013, 0x0002 }, + { 0x0013, 0x0003 }, + { 0x0013, 0x0004 }, + { 0x0013, 0x0005 }, + { 0x0013, 0x0006 }, + { 0x0013, 0x0007 }, + { 0x0003, 0x0002 }, + { 0x0003, 0x0003 }, + { 0x0005, 0x0001 }, + { 0x0009, 0x0002 }, + { 0x000d, 0x0004 }, + { 0x0010, 0x0013 }, + { 0x0013, 0x0008 }, + { 0x0013, 0x0009 }, + { 0x0013, 0x000a }, + { 0x0013, 0x000b }, + { 0x0013, 0x000c }, + { 0x0013, 0x000d }, + { 0x0013, 0x000e }, + { 0x0005, 0x0002 }, + { 0x0005, 0x0003 }, + { 0x0008, 0x0002 }, + { 0x000b, 0x0002 }, + { 0x000f, 0x000b }, + { 0x0011, 0x0025 }, + { 0x0013, 0x000f }, + { 0x0013, 0x0010 }, + { 0x0013, 0x0011 }, + { 0x0013, 0x0012 }, + { 0x0013, 0x0013 }, + { 0x0013, 0x0014 }, + { 0x0013, 0x0015 }, + { 0x0009, 0x0003 }, + { 0x0008, 0x0003 }, + { 0x000b, 0x0003 }, + { 0x000d, 0x0005 }, + { 0x0010, 0x0014 }, + { 0x0013, 0x0016 }, + { 0x0013, 0x0017 }, + { 0x0013, 0x0018 }, + { 0x0013, 0x0019 }, + { 0x0013, 0x001a }, + { 0x0013, 0x001b }, + { 0x0013, 0x001c }, + { 0x0013, 0x001d }, + { 0x000d, 0x0006 }, + { 0x000d, 0x0007 }, + { 0x000e, 0x0007 }, + { 0x0010, 0x0015 }, + { 0x0013, 0x001e }, + { 0x0013, 0x001f }, + { 0x0013, 0x0020 }, + { 0x0013, 0x0021 }, + { 0x0013, 0x0022 }, + { 0x0013, 0x0023 }, + { 0x0013, 0x0024 }, + { 0x0013, 0x0025 }, + { 0x0013, 0x0026 }, + { 0x0012, 0x0045 }, + { 0x0013, 0x0027 }, + { 0x0013, 0x0028 }, + { 0x0013, 0x0029 }, + { 0x0013, 0x002a }, + { 0x0013, 0x002b }, + { 0x0013, 0x002c }, + { 0x0013, 0x002d }, + { 0x0013, 0x002e }, + { 0x0013, 0x002f }, + { 0x0013, 0x0030 }, + { 0x0013, 0x0031 }, + { 0x0013, 0x0032 }, + { 0x0013, 0x0033 }, + { 0x0013, 0x0034 }, + { 0x0013, 0x0035 }, + { 0x0013, 0x0036 }, + { 0x0013, 0x0037 }, + { 0x0013, 0x0038 }, + { 0x0013, 0x0039 }, + { 0x0013, 0x003a }, + { 0x0013, 0x003b }, + { 0x0013, 0x003c }, + { 0x0013, 0x003d }, + { 0x0013, 0x003e }, + { 0x0013, 0x003f }, + { 0x0013, 0x0040 }, + { 0x0013, 0x0041 }, + { 0x0013, 0x0042 }, + { 0x0013, 0x0043 }, + { 0x0013, 0x0044 }, + { 0x0013, 0x0045 }, + { 0x0013, 0x0046 }, + { 0x0013, 0x0047 }, + { 0x0013, 0x0048 }, + { 0x0013, 0x0049 }, + { 0x0013, 0x004a }, + { 0x0013, 0x004b }, + { 0x0013, 0x004c }, + { 0x0013, 0x004d }, + { 0x0013, 0x004e }, + { 0x0013, 0x004f }, + { 0x0013, 0x0050 }, + { 0x0013, 0x0051 }, + { 0x0013, 0x0052 }, + { 0x0013, 0x0053 }, + { 0x0013, 0x0054 }, + { 0x0013, 0x0055 }, + { 0x0013, 0x0056 }, + { 0x0013, 0x0057 }, + { 0x0013, 0x0058 }, + { 0x0013, 0x0059 }, + { 0x0013, 0x005a }, + { 0x0013, 0x005b }, + { 0x0013, 0x005c }, + { 0x0013, 0x005d }, + { 0x0013, 0x005e }, + { 0x0013, 0x005f }, + { 0x0013, 0x0060 }, + { 0x0013, 0x0061 }, + { 0x0013, 0x0062 }, + { 0x0013, 0x0063 }, + { 0x0013, 0x0064 }, + { 0x0013, 0x0065 }, + { 0x0013, 0x0066 }, + { 0x0013, 0x0067 }, + { 0x0013, 0x0068 }, + { 0x0013, 0x0069 }, + { 0x0013, 0x006a }, + { 0x0013, 0x006b }, + { 0x0013, 0x006c }, + { 0x0013, 0x006d }, + { 0x0013, 0x006e }, + { 0x0013, 0x006f }, + { 0x0013, 0x0070 }, + { 0x0013, 0x0071 }, + { 0x0013, 0x0072 }, + { 0x0013, 0x0073 }, + { 0x0013, 0x0074 }, + { 0x0013, 0x0075 }, + { 0x0013, 0x0076 }, + { 0x0013, 0x0077 }, + { 0x0013, 0x0078 }, + { 0x0013, 0x0079 }, + { 0x0013, 0x007a }, + { 0x0013, 0x007b }, + { 0x0013, 0x007c }, + { 0x0013, 0x007d }, + { 0x0013, 0x007e }, + { 0x0013, 0x007f }, + { 0x0013, 0x0080 }, + { 0x0013, 0x0081 }, + { 0x0013, 0x0082 }, + { 0x0013, 0x0083 }, + { 0x0013, 0x0084 }, + { 0x0013, 0x0085 }, + { 0x0013, 0x0086 }, + { 0x0013, 0x0087 }, + { 0x0013, 0x0088 }, + { 0x0013, 0x0089 }, + { 0x0012, 0x0046 }, + { 0x0012, 0x0047 }, + { 0x0012, 0x0048 }, + { 0x0012, 0x0049 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc43[196][2] = + { + { 0x0001, 0x0001 }, + { 0x0003, 0x0001 }, + { 0x0006, 0x0001 }, + { 0x0009, 0x0002 }, + { 0x000c, 0x0003 }, + { 0x0010, 0x0017 }, + { 0x0013, 0x0000 }, + { 0x0013, 0x0001 }, + { 0x0013, 0x0002 }, + { 0x0013, 0x0003 }, + { 0x0013, 0x0004 }, + { 0x0013, 0x0005 }, + { 0x0013, 0x0006 }, + { 0x0013, 0x0007 }, + { 0x0003, 0x0002 }, + { 0x0003, 0x0003 }, + { 0x0005, 0x0001 }, + { 0x0009, 0x0003 }, + { 0x000c, 0x0004 }, + { 0x0010, 0x0018 }, + { 0x0012, 0x0050 }, + { 0x0013, 0x0008 }, + { 0x0013, 0x0009 }, + { 0x0013, 0x000a }, + { 0x0013, 0x000b }, + { 0x0013, 0x000c }, + { 0x0013, 0x000d }, + { 0x0013, 0x000e }, + { 0x0005, 0x0002 }, + { 0x0005, 0x0003 }, + { 0x0008, 0x0003 }, + { 0x000a, 0x0002 }, + { 0x000d, 0x0004 }, + { 0x0011, 0x002a }, + { 0x0013, 0x000f }, + { 0x0013, 0x0010 }, + { 0x0013, 0x0011 }, + { 0x0013, 0x0012 }, + { 0x0013, 0x0013 }, + { 0x0013, 0x0014 }, + { 0x0013, 0x0015 }, + { 0x0013, 0x0016 }, + { 0x0009, 0x0004 }, + { 0x0009, 0x0005 }, + { 0x000a, 0x0003 }, + { 0x000c, 0x0005 }, + { 0x000f, 0x000d }, + { 0x0012, 0x0051 }, + { 0x0013, 0x0017 }, + { 0x0013, 0x0018 }, + { 0x0013, 0x0019 }, + { 0x0013, 0x001a }, + { 0x0013, 0x001b }, + { 0x0013, 0x001c }, + { 0x0013, 0x001d }, + { 0x0013, 0x001e }, + { 0x000c, 0x0006 }, + { 0x000c, 0x0007 }, + { 0x000d, 0x0005 }, + { 0x000f, 0x000e }, + { 0x0011, 0x002b }, + { 0x0013, 0x001f }, + { 0x0013, 0x0020 }, + { 0x0013, 0x0021 }, + { 0x0013, 0x0022 }, + { 0x0013, 0x0023 }, + { 0x0013, 0x0024 }, + { 0x0013, 0x0025 }, + { 0x0013, 0x0026 }, + { 0x0013, 0x0027 }, + { 0x0011, 0x002c }, + { 0x000f, 0x000f }, + { 0x0010, 0x0019 }, + { 0x0012, 0x0052 }, + { 0x0012, 0x0053 }, + { 0x0013, 0x0028 }, + { 0x0013, 0x0029 }, + { 0x0013, 0x002a }, + { 0x0013, 0x002b }, + { 0x0013, 0x002c }, + { 0x0013, 0x002d }, + { 0x0013, 0x002e }, + { 0x0013, 0x002f }, + { 0x0013, 0x0030 }, + { 0x0013, 0x0031 }, + { 0x0011, 0x002d }, + { 0x0013, 0x0032 }, + { 0x0013, 0x0033 }, + { 0x0013, 0x0034 }, + { 0x0013, 0x0035 }, + { 0x0013, 0x0036 }, + { 0x0013, 0x0037 }, + { 0x0013, 0x0038 }, + { 0x0013, 0x0039 }, + { 0x0013, 0x003a }, + { 0x0013, 0x003b }, + { 0x0013, 0x003c }, + { 0x0013, 0x003d }, + { 0x0013, 0x003e }, + { 0x0013, 0x003f }, + { 0x0013, 0x0040 }, + { 0x0013, 0x0041 }, + { 0x0013, 0x0042 }, + { 0x0013, 0x0043 }, + { 0x0013, 0x0044 }, + { 0x0013, 0x0045 }, + { 0x0013, 0x0046 }, + { 0x0013, 0x0047 }, + { 0x0013, 0x0048 }, + { 0x0013, 0x0049 }, + { 0x0013, 0x004a }, + { 0x0013, 0x004b }, + { 0x0013, 0x004c }, + { 0x0013, 0x004d }, + { 0x0013, 0x004e }, + { 0x0013, 0x004f }, + { 0x0013, 0x0050 }, + { 0x0013, 0x0051 }, + { 0x0013, 0x0052 }, + { 0x0013, 0x0053 }, + { 0x0013, 0x0054 }, + { 0x0013, 0x0055 }, + { 0x0013, 0x0056 }, + { 0x0013, 0x0057 }, + { 0x0013, 0x0058 }, + { 0x0013, 0x0059 }, + { 0x0013, 0x005a }, + { 0x0013, 0x005b }, + { 0x0013, 0x005c }, + { 0x0013, 0x005d }, + { 0x0013, 0x005e }, + { 0x0013, 0x005f }, + { 0x0013, 0x0060 }, + { 0x0013, 0x0061 }, + { 0x0013, 0x0062 }, + { 0x0013, 0x0063 }, + { 0x0013, 0x0064 }, + { 0x0013, 0x0065 }, + { 0x0013, 0x0066 }, + { 0x0013, 0x0067 }, + { 0x0013, 0x0068 }, + { 0x0013, 0x0069 }, + { 0x0013, 0x006a }, + { 0x0013, 0x006b }, + { 0x0013, 0x006c }, + { 0x0013, 0x006d }, + { 0x0013, 0x006e }, + { 0x0013, 0x006f }, + { 0x0013, 0x0070 }, + { 0x0013, 0x0071 }, + { 0x0013, 0x0072 }, + { 0x0013, 0x0073 }, + { 0x0013, 0x0074 }, + { 0x0013, 0x0075 }, + { 0x0013, 0x0076 }, + { 0x0013, 0x0077 }, + { 0x0013, 0x0078 }, + { 0x0013, 0x0079 }, + { 0x0013, 0x007a }, + { 0x0013, 0x007b }, + { 0x0013, 0x007c }, + { 0x0013, 0x007d }, + { 0x0013, 0x007e }, + { 0x0013, 0x007f }, + { 0x0013, 0x0080 }, + { 0x0013, 0x0081 }, + { 0x0013, 0x0082 }, + { 0x0013, 0x0083 }, + { 0x0013, 0x0084 }, + { 0x0013, 0x0085 }, + { 0x0013, 0x0086 }, + { 0x0013, 0x0087 }, + { 0x0013, 0x0088 }, + { 0x0013, 0x0089 }, + { 0x0013, 0x008a }, + { 0x0013, 0x008b }, + { 0x0013, 0x008c }, + { 0x0013, 0x008d }, + { 0x0013, 0x008e }, + { 0x0013, 0x008f }, + { 0x0013, 0x0090 }, + { 0x0013, 0x0091 }, + { 0x0013, 0x0092 }, + { 0x0013, 0x0093 }, + { 0x0013, 0x0094 }, + { 0x0013, 0x0095 }, + { 0x0013, 0x0096 }, + { 0x0013, 0x0097 }, + { 0x0013, 0x0098 }, + { 0x0013, 0x0099 }, + { 0x0013, 0x009a }, + { 0x0013, 0x009b }, + { 0x0013, 0x009c }, + { 0x0013, 0x009d }, + { 0x0013, 0x009e }, + { 0x0013, 0x009f }, + + }; + +const uint16_t c_aauiLCLDHuffEnc44[289][2] = + { + { 0x0001, 0x0001 }, + { 0x0003, 0x0001 }, + { 0x0006, 0x0002 }, + { 0x0008, 0x0002 }, + { 0x000b, 0x0002 }, + { 0x000f, 0x000a }, + { 0x0011, 0x0022 }, + { 0x0014, 0x0000 }, + { 0x0014, 0x0001 }, + { 0x0014, 0x0002 }, + { 0x0014, 0x0003 }, + { 0x0014, 0x0004 }, + { 0x0014, 0x0005 }, + { 0x0014, 0x0006 }, + { 0x0014, 0x0007 }, + { 0x0014, 0x0008 }, + { 0x0014, 0x0009 }, + { 0x0003, 0x0002 }, + { 0x0003, 0x0003 }, + { 0x0005, 0x0002 }, + { 0x0008, 0x0003 }, + { 0x000b, 0x0003 }, + { 0x000e, 0x0007 }, + { 0x0012, 0x003f }, + { 0x0014, 0x000a }, + { 0x0014, 0x000b }, + { 0x0014, 0x000c }, + { 0x0014, 0x000d }, + { 0x0014, 0x000e }, + { 0x0014, 0x000f }, + { 0x0014, 0x0010 }, + { 0x0014, 0x0011 }, + { 0x0014, 0x0012 }, + { 0x0014, 0x0013 }, + { 0x0006, 0x0003 }, + { 0x0005, 0x0003 }, + { 0x0007, 0x0003 }, + { 0x0009, 0x0002 }, + { 0x000c, 0x0003 }, + { 0x000f, 0x000b }, + { 0x0012, 0x0040 }, + { 0x0014, 0x0014 }, + { 0x0014, 0x0015 }, + { 0x0014, 0x0016 }, + { 0x0014, 0x0017 }, + { 0x0014, 0x0018 }, + { 0x0014, 0x0019 }, + { 0x0014, 0x001a }, + { 0x0014, 0x001b }, + { 0x0014, 0x001c }, + { 0x0014, 0x001d }, + { 0x0008, 0x0004 }, + { 0x0008, 0x0005 }, + { 0x0009, 0x0003 }, + { 0x000b, 0x0004 }, + { 0x000d, 0x0005 }, + { 0x0010, 0x0013 }, + { 0x0014, 0x001e }, + { 0x0014, 0x001f }, + { 0x0014, 0x0020 }, + { 0x0014, 0x0021 }, + { 0x0014, 0x0022 }, + { 0x0014, 0x0023 }, + { 0x0014, 0x0024 }, + { 0x0014, 0x0025 }, + { 0x0014, 0x0026 }, + { 0x0014, 0x0027 }, + { 0x0014, 0x0028 }, + { 0x000b, 0x0005 }, + { 0x000b, 0x0006 }, + { 0x000b, 0x0007 }, + { 0x000e, 0x0008 }, + { 0x0011, 0x0023 }, + { 0x0012, 0x0041 }, + { 0x0014, 0x0029 }, + { 0x0014, 0x002a }, + { 0x0013, 0x007b }, + { 0x0014, 0x002b }, + { 0x0014, 0x002c }, + { 0x0014, 0x002d }, + { 0x0014, 0x002e }, + { 0x0014, 0x002f }, + { 0x0014, 0x0030 }, + { 0x0014, 0x0031 }, + { 0x0014, 0x0032 }, + { 0x000f, 0x000c }, + { 0x000e, 0x0009 }, + { 0x000f, 0x000d }, + { 0x0011, 0x0024 }, + { 0x0012, 0x0042 }, + { 0x0014, 0x0033 }, + { 0x0014, 0x0034 }, + { 0x0014, 0x0035 }, + { 0x0014, 0x0036 }, + { 0x0014, 0x0037 }, + { 0x0014, 0x0038 }, + { 0x0014, 0x0039 }, + { 0x0014, 0x003a }, + { 0x0014, 0x003b }, + { 0x0014, 0x003c }, + { 0x0014, 0x003d }, + { 0x0014, 0x003e }, + { 0x0013, 0x007c }, + { 0x0011, 0x0025 }, + { 0x0012, 0x0043 }, + { 0x0014, 0x003f }, + { 0x0014, 0x0040 }, + { 0x0014, 0x0041 }, + { 0x0014, 0x0042 }, + { 0x0014, 0x0043 }, + { 0x0014, 0x0044 }, + { 0x0014, 0x0045 }, + { 0x0014, 0x0046 }, + { 0x0014, 0x0047 }, + { 0x0014, 0x0048 }, + { 0x0014, 0x0049 }, + { 0x0014, 0x004a }, + { 0x0014, 0x004b }, + { 0x0014, 0x004c }, + { 0x0014, 0x004d }, + { 0x0014, 0x004e }, + { 0x0014, 0x004f }, + { 0x0014, 0x0050 }, + { 0x0014, 0x0051 }, + { 0x0014, 0x0052 }, + { 0x0014, 0x0053 }, + { 0x0014, 0x0054 }, + { 0x0014, 0x0055 }, + { 0x0014, 0x0056 }, + { 0x0014, 0x0057 }, + { 0x0014, 0x0058 }, + { 0x0014, 0x0059 }, + { 0x0014, 0x005a }, + { 0x0014, 0x005b }, + { 0x0014, 0x005c }, + { 0x0014, 0x005d }, + { 0x0014, 0x005e }, + { 0x0014, 0x005f }, + { 0x0014, 0x0060 }, + { 0x0014, 0x0061 }, + { 0x0014, 0x0062 }, + { 0x0014, 0x0063 }, + { 0x0014, 0x0064 }, + { 0x0014, 0x0065 }, + { 0x0014, 0x0066 }, + { 0x0014, 0x0067 }, + { 0x0014, 0x0068 }, + { 0x0014, 0x0069 }, + { 0x0014, 0x006a }, + { 0x0014, 0x006b }, + { 0x0014, 0x006c }, + { 0x0014, 0x006d }, + { 0x0014, 0x006e }, + { 0x0014, 0x006f }, + { 0x0014, 0x0070 }, + { 0x0014, 0x0071 }, + { 0x0014, 0x0072 }, + { 0x0014, 0x0073 }, + { 0x0014, 0x0074 }, + { 0x0014, 0x0075 }, + { 0x0014, 0x0076 }, + { 0x0014, 0x0077 }, + { 0x0014, 0x0078 }, + { 0x0014, 0x0079 }, + { 0x0014, 0x007a }, + { 0x0014, 0x007b }, + { 0x0014, 0x007c }, + { 0x0014, 0x007d }, + { 0x0014, 0x007e }, + { 0x0014, 0x007f }, + { 0x0014, 0x0080 }, + { 0x0014, 0x0081 }, + { 0x0014, 0x0082 }, + { 0x0014, 0x0083 }, + { 0x0014, 0x0084 }, + { 0x0014, 0x0085 }, + { 0x0014, 0x0086 }, + { 0x0014, 0x0087 }, + { 0x0014, 0x0088 }, + { 0x0014, 0x0089 }, + { 0x0014, 0x008a }, + { 0x0014, 0x008b }, + { 0x0014, 0x008c }, + { 0x0014, 0x008d }, + { 0x0014, 0x008e }, + { 0x0014, 0x008f }, + { 0x0014, 0x0090 }, + { 0x0014, 0x0091 }, + { 0x0014, 0x0092 }, + { 0x0014, 0x0093 }, + { 0x0014, 0x0094 }, + { 0x0014, 0x0095 }, + { 0x0014, 0x0096 }, + { 0x0014, 0x0097 }, + { 0x0014, 0x0098 }, + { 0x0014, 0x0099 }, + { 0x0014, 0x009a }, + { 0x0014, 0x009b }, + { 0x0014, 0x009c }, + { 0x0014, 0x009d }, + { 0x0014, 0x009e }, + { 0x0014, 0x009f }, + { 0x0014, 0x00a0 }, + { 0x0014, 0x00a1 }, + { 0x0014, 0x00a2 }, + { 0x0014, 0x00a3 }, + { 0x0014, 0x00a4 }, + { 0x0014, 0x00a5 }, + { 0x0014, 0x00a6 }, + { 0x0014, 0x00a7 }, + { 0x0014, 0x00a8 }, + { 0x0014, 0x00a9 }, + { 0x0014, 0x00aa }, + { 0x0014, 0x00ab }, + { 0x0014, 0x00ac }, + { 0x0014, 0x00ad }, + { 0x0014, 0x00ae }, + { 0x0014, 0x00af }, + { 0x0014, 0x00b0 }, + { 0x0014, 0x00b1 }, + { 0x0014, 0x00b2 }, + { 0x0014, 0x00b3 }, + { 0x0014, 0x00b4 }, + { 0x0014, 0x00b5 }, + { 0x0014, 0x00b6 }, + { 0x0014, 0x00b7 }, + { 0x0014, 0x00b8 }, + { 0x0014, 0x00b9 }, + { 0x0014, 0x00ba }, + { 0x0014, 0x00bb }, + { 0x0014, 0x00bc }, + { 0x0014, 0x00bd }, + { 0x0014, 0x00be }, + { 0x0014, 0x00bf }, + { 0x0014, 0x00c0 }, + { 0x0014, 0x00c1 }, + { 0x0014, 0x00c2 }, + { 0x0014, 0x00c3 }, + { 0x0014, 0x00c4 }, + { 0x0014, 0x00c5 }, + { 0x0014, 0x00c6 }, + { 0x0014, 0x00c7 }, + { 0x0014, 0x00c8 }, + { 0x0014, 0x00c9 }, + { 0x0014, 0x00ca }, + { 0x0014, 0x00cb }, + { 0x0014, 0x00cc }, + { 0x0014, 0x00cd }, + { 0x0014, 0x00ce }, + { 0x0014, 0x00cf }, + { 0x0014, 0x00d0 }, + { 0x0014, 0x00d1 }, + { 0x0014, 0x00d2 }, + { 0x0014, 0x00d3 }, + { 0x0014, 0x00d4 }, + { 0x0014, 0x00d5 }, + { 0x0014, 0x00d6 }, + { 0x0014, 0x00d7 }, + { 0x0014, 0x00d8 }, + { 0x0014, 0x00d9 }, + { 0x0014, 0x00da }, + { 0x0014, 0x00db }, + { 0x0014, 0x00dc }, + { 0x0014, 0x00dd }, + { 0x0014, 0x00de }, + { 0x0014, 0x00df }, + { 0x0014, 0x00e0 }, + { 0x0014, 0x00e1 }, + { 0x0014, 0x00e2 }, + { 0x0014, 0x00e3 }, + { 0x0014, 0x00e4 }, + { 0x0014, 0x00e5 }, + { 0x0014, 0x00e6 }, + { 0x0014, 0x00e7 }, + { 0x0014, 0x00e8 }, + { 0x0014, 0x00e9 }, + { 0x0014, 0x00ea }, + { 0x0014, 0x00eb }, + { 0x0014, 0x00ec }, + { 0x0014, 0x00ed }, + { 0x0014, 0x00ee }, + { 0x0014, 0x00ef }, + { 0x0014, 0x00f0 }, + { 0x0014, 0x00f1 }, + { 0x0014, 0x00f2 }, + { 0x0014, 0x00f3 }, + { 0x0014, 0x00f4 }, + { 0x0014, 0x00f5 }, + { 0x0013, 0x007d }, + + }; + + +const uint16_t c_aauiLCLDHuffEnc45[324][2] = + { + { 0x0002, 0x0002 }, + { 0x0003, 0x0002 }, + { 0x0005, 0x0003 }, + { 0x0007, 0x0002 }, + { 0x0009, 0x0003 }, + { 0x000c, 0x0005 }, + { 0x0010, 0x0025 }, + { 0x0012, 0x0088 }, + { 0x0013, 0x0000 }, + { 0x0013, 0x0001 }, + { 0x0013, 0x0002 }, + { 0x0013, 0x0003 }, + { 0x0013, 0x0004 }, + { 0x0013, 0x0005 }, + { 0x0013, 0x0006 }, + { 0x0013, 0x0007 }, + { 0x0013, 0x0008 }, + { 0x0013, 0x0009 }, + { 0x0002, 0x0003 }, + { 0x0003, 0x0003 }, + { 0x0005, 0x0004 }, + { 0x0006, 0x0003 }, + { 0x0009, 0x0004 }, + { 0x000b, 0x0004 }, + { 0x000f, 0x0014 }, + { 0x0011, 0x0048 }, + { 0x0013, 0x000a }, + { 0x0013, 0x000b }, + { 0x0013, 0x000c }, + { 0x0013, 0x000d }, + { 0x0013, 0x000e }, + { 0x0013, 0x000f }, + { 0x0013, 0x0010 }, + { 0x0013, 0x0011 }, + { 0x0013, 0x0012 }, + { 0x0013, 0x0013 }, + { 0x0005, 0x0005 }, + { 0x0004, 0x0003 }, + { 0x0006, 0x0004 }, + { 0x0007, 0x0003 }, + { 0x000a, 0x0004 }, + { 0x000d, 0x0007 }, + { 0x000f, 0x0015 }, + { 0x0013, 0x0014 }, + { 0x0013, 0x0015 }, + { 0x0013, 0x0016 }, + { 0x0013, 0x0017 }, + { 0x0013, 0x0018 }, + { 0x0013, 0x0019 }, + { 0x0013, 0x001a }, + { 0x0013, 0x001b }, + { 0x0013, 0x001c }, + { 0x0013, 0x001d }, + { 0x0013, 0x001e }, + { 0x0007, 0x0004 }, + { 0x0006, 0x0005 }, + { 0x0007, 0x0005 }, + { 0x0009, 0x0005 }, + { 0x000b, 0x0005 }, + { 0x000d, 0x0008 }, + { 0x0010, 0x0026 }, + { 0x0012, 0x0089 }, + { 0x0012, 0x008a }, + { 0x0013, 0x001f }, + { 0x0013, 0x0020 }, + { 0x0013, 0x0021 }, + { 0x0013, 0x0022 }, + { 0x0013, 0x0023 }, + { 0x0013, 0x0024 }, + { 0x0013, 0x0025 }, + { 0x0013, 0x0026 }, + { 0x0013, 0x0027 }, + { 0x0009, 0x0006 }, + { 0x0009, 0x0007 }, + { 0x000a, 0x0005 }, + { 0x000b, 0x0006 }, + { 0x000d, 0x0009 }, + { 0x000f, 0x0016 }, + { 0x0011, 0x0049 }, + { 0x0013, 0x0028 }, + { 0x0013, 0x0029 }, + { 0x0013, 0x002a }, + { 0x0013, 0x002b }, + { 0x0013, 0x002c }, + { 0x0013, 0x002d }, + { 0x0013, 0x002e }, + { 0x0013, 0x002f }, + { 0x0013, 0x0030 }, + { 0x0013, 0x0031 }, + { 0x0013, 0x0032 }, + { 0x000c, 0x0006 }, + { 0x000b, 0x0007 }, + { 0x000c, 0x0007 }, + { 0x000e, 0x000d }, + { 0x0010, 0x0027 }, + { 0x0012, 0x008b }, + { 0x0012, 0x008c }, + { 0x0013, 0x0033 }, + { 0x0013, 0x0034 }, + { 0x0013, 0x0035 }, + { 0x0013, 0x0036 }, + { 0x0013, 0x0037 }, + { 0x0013, 0x0038 }, + { 0x0013, 0x0039 }, + { 0x0013, 0x003a }, + { 0x0013, 0x003b }, + { 0x0013, 0x003c }, + { 0x0013, 0x003d }, + { 0x000f, 0x0017 }, + { 0x000f, 0x0018 }, + { 0x000f, 0x0019 }, + { 0x0012, 0x008d }, + { 0x0013, 0x003e }, + { 0x0013, 0x003f }, + { 0x0013, 0x0040 }, + { 0x0013, 0x0041 }, + { 0x0013, 0x0042 }, + { 0x0013, 0x0043 }, + { 0x0013, 0x0044 }, + { 0x0013, 0x0045 }, + { 0x0013, 0x0046 }, + { 0x0013, 0x0047 }, + { 0x0013, 0x0048 }, + { 0x0013, 0x0049 }, + { 0x0013, 0x004a }, + { 0x0013, 0x004b }, + { 0x0013, 0x004c }, + { 0x0012, 0x008e }, + { 0x0012, 0x008f }, + { 0x0013, 0x004d }, + { 0x0013, 0x004e }, + { 0x0013, 0x004f }, + { 0x0013, 0x0050 }, + { 0x0013, 0x0051 }, + { 0x0013, 0x0052 }, + { 0x0013, 0x0053 }, + { 0x0013, 0x0054 }, + { 0x0013, 0x0055 }, + { 0x0013, 0x0056 }, + { 0x0013, 0x0057 }, + { 0x0013, 0x0058 }, + { 0x0013, 0x0059 }, + { 0x0013, 0x005a }, + { 0x0013, 0x005b }, + { 0x0013, 0x005c }, + { 0x0013, 0x005d }, + { 0x0013, 0x005e }, + { 0x0013, 0x005f }, + { 0x0013, 0x0060 }, + { 0x0013, 0x0061 }, + { 0x0013, 0x0062 }, + { 0x0013, 0x0063 }, + { 0x0013, 0x0064 }, + { 0x0013, 0x0065 }, + { 0x0013, 0x0066 }, + { 0x0013, 0x0067 }, + { 0x0013, 0x0068 }, + { 0x0013, 0x0069 }, + { 0x0013, 0x006a }, + { 0x0013, 0x006b }, + { 0x0013, 0x006c }, + { 0x0013, 0x006d }, + { 0x0013, 0x006e }, + { 0x0013, 0x006f }, + { 0x0013, 0x0070 }, + { 0x0013, 0x0071 }, + { 0x0013, 0x0072 }, + { 0x0013, 0x0073 }, + { 0x0013, 0x0074 }, + { 0x0013, 0x0075 }, + { 0x0013, 0x0076 }, + { 0x0013, 0x0077 }, + { 0x0013, 0x0078 }, + { 0x0013, 0x0079 }, + { 0x0013, 0x007a }, + { 0x0013, 0x007b }, + { 0x0013, 0x007c }, + { 0x0013, 0x007d }, + { 0x0013, 0x007e }, + { 0x0013, 0x007f }, + { 0x0013, 0x0080 }, + { 0x0013, 0x0081 }, + { 0x0013, 0x0082 }, + { 0x0013, 0x0083 }, + { 0x0013, 0x0084 }, + { 0x0013, 0x0085 }, + { 0x0013, 0x0086 }, + { 0x0013, 0x0087 }, + { 0x0013, 0x0088 }, + { 0x0013, 0x0089 }, + { 0x0013, 0x008a }, + { 0x0013, 0x008b }, + { 0x0013, 0x008c }, + { 0x0013, 0x008d }, + { 0x0013, 0x008e }, + { 0x0013, 0x008f }, + { 0x0013, 0x0090 }, + { 0x0013, 0x0091 }, + { 0x0013, 0x0092 }, + { 0x0013, 0x0093 }, + { 0x0013, 0x0094 }, + { 0x0013, 0x0095 }, + { 0x0013, 0x0096 }, + { 0x0013, 0x0097 }, + { 0x0013, 0x0098 }, + { 0x0013, 0x0099 }, + { 0x0013, 0x009a }, + { 0x0013, 0x009b }, + { 0x0013, 0x009c }, + { 0x0013, 0x009d }, + { 0x0013, 0x009e }, + { 0x0013, 0x009f }, + { 0x0013, 0x00a0 }, + { 0x0013, 0x00a1 }, + { 0x0013, 0x00a2 }, + { 0x0013, 0x00a3 }, + { 0x0013, 0x00a4 }, + { 0x0013, 0x00a5 }, + { 0x0013, 0x00a6 }, + { 0x0013, 0x00a7 }, + { 0x0013, 0x00a8 }, + { 0x0013, 0x00a9 }, + { 0x0013, 0x00aa }, + { 0x0013, 0x00ab }, + { 0x0013, 0x00ac }, + { 0x0013, 0x00ad }, + { 0x0013, 0x00ae }, + { 0x0013, 0x00af }, + { 0x0013, 0x00b0 }, + { 0x0013, 0x00b1 }, + { 0x0013, 0x00b2 }, + { 0x0013, 0x00b3 }, + { 0x0013, 0x00b4 }, + { 0x0013, 0x00b5 }, + { 0x0013, 0x00b6 }, + { 0x0013, 0x00b7 }, + { 0x0013, 0x00b8 }, + { 0x0013, 0x00b9 }, + { 0x0013, 0x00ba }, + { 0x0013, 0x00bb }, + { 0x0013, 0x00bc }, + { 0x0013, 0x00bd }, + { 0x0013, 0x00be }, + { 0x0013, 0x00bf }, + { 0x0013, 0x00c0 }, + { 0x0013, 0x00c1 }, + { 0x0013, 0x00c2 }, + { 0x0013, 0x00c3 }, + { 0x0013, 0x00c4 }, + { 0x0013, 0x00c5 }, + { 0x0013, 0x00c6 }, + { 0x0013, 0x00c7 }, + { 0x0013, 0x00c8 }, + { 0x0013, 0x00c9 }, + { 0x0013, 0x00ca }, + { 0x0013, 0x00cb }, + { 0x0013, 0x00cc }, + { 0x0013, 0x00cd }, + { 0x0013, 0x00ce }, + { 0x0013, 0x00cf }, + { 0x0013, 0x00d0 }, + { 0x0013, 0x00d1 }, + { 0x0013, 0x00d2 }, + { 0x0013, 0x00d3 }, + { 0x0013, 0x00d4 }, + { 0x0013, 0x00d5 }, + { 0x0013, 0x00d6 }, + { 0x0013, 0x00d7 }, + { 0x0013, 0x00d8 }, + { 0x0013, 0x00d9 }, + { 0x0013, 0x00da }, + { 0x0013, 0x00db }, + { 0x0013, 0x00dc }, + { 0x0013, 0x00dd }, + { 0x0013, 0x00de }, + { 0x0013, 0x00df }, + { 0x0013, 0x00e0 }, + { 0x0013, 0x00e1 }, + { 0x0013, 0x00e2 }, + { 0x0013, 0x00e3 }, + { 0x0013, 0x00e4 }, + { 0x0013, 0x00e5 }, + { 0x0013, 0x00e6 }, + { 0x0013, 0x00e7 }, + { 0x0013, 0x00e8 }, + { 0x0013, 0x00e9 }, + { 0x0013, 0x00ea }, + { 0x0013, 0x00eb }, + { 0x0013, 0x00ec }, + { 0x0013, 0x00ed }, + { 0x0013, 0x00ee }, + { 0x0013, 0x00ef }, + { 0x0013, 0x00f0 }, + { 0x0013, 0x00f1 }, + { 0x0013, 0x00f2 }, + { 0x0013, 0x00f3 }, + { 0x0013, 0x00f4 }, + { 0x0013, 0x00f5 }, + { 0x0013, 0x00f6 }, + { 0x0013, 0x00f7 }, + { 0x0013, 0x00f8 }, + { 0x0013, 0x00f9 }, + { 0x0013, 0x00fa }, + { 0x0013, 0x00fb }, + { 0x0013, 0x00fc }, + { 0x0013, 0x00fd }, + { 0x0013, 0x00fe }, + { 0x0013, 0x00ff }, + { 0x0013, 0x0100 }, + { 0x0013, 0x0101 }, + { 0x0013, 0x0102 }, + { 0x0013, 0x0103 }, + { 0x0013, 0x0104 }, + { 0x0013, 0x0105 }, + { 0x0013, 0x0106 }, + { 0x0013, 0x0107 }, + { 0x0013, 0x0108 }, + { 0x0013, 0x0109 }, + { 0x0013, 0x010a }, + { 0x0013, 0x010b }, + { 0x0013, 0x010c }, + { 0x0013, 0x010d }, + { 0x0013, 0x010e }, + { 0x0013, 0x010f }, + + }; + +const uint16_t c_aauiLCLDHuffEnc46[400][2] = + { + { 0x0002, 0x0002 }, + { 0x0003, 0x0002 }, + { 0x0005, 0x0003 }, + { 0x0007, 0x0004 }, + { 0x0009, 0x0005 }, + { 0x000b, 0x0006 }, + { 0x000d, 0x000a }, + { 0x000f, 0x0018 }, + { 0x0012, 0x00a6 }, + { 0x0013, 0x0000 }, + { 0x0013, 0x0001 }, + { 0x0013, 0x0002 }, + { 0x0013, 0x0003 }, + { 0x0013, 0x0004 }, + { 0x0013, 0x0005 }, + { 0x0013, 0x0006 }, + { 0x0013, 0x0007 }, + { 0x0013, 0x0008 }, + { 0x0013, 0x0009 }, + { 0x0013, 0x000a }, + { 0x0002, 0x0003 }, + { 0x0003, 0x0003 }, + { 0x0005, 0x0004 }, + { 0x0006, 0x0004 }, + { 0x0008, 0x0004 }, + { 0x000a, 0x0006 }, + { 0x000c, 0x0008 }, + { 0x000e, 0x0011 }, + { 0x0012, 0x00a7 }, + { 0x0013, 0x000b }, + { 0x0013, 0x000c }, + { 0x0013, 0x000d }, + { 0x0013, 0x000e }, + { 0x0013, 0x000f }, + { 0x0013, 0x0010 }, + { 0x0013, 0x0011 }, + { 0x0013, 0x0012 }, + { 0x0013, 0x0013 }, + { 0x0013, 0x0014 }, + { 0x0013, 0x0015 }, + { 0x0005, 0x0005 }, + { 0x0005, 0x0006 }, + { 0x0005, 0x0007 }, + { 0x0007, 0x0005 }, + { 0x0009, 0x0006 }, + { 0x000b, 0x0007 }, + { 0x000d, 0x000b }, + { 0x000f, 0x0019 }, + { 0x0013, 0x0016 }, + { 0x0013, 0x0017 }, + { 0x0013, 0x0018 }, + { 0x0013, 0x0019 }, + { 0x0013, 0x001a }, + { 0x0013, 0x001b }, + { 0x0013, 0x001c }, + { 0x0013, 0x001d }, + { 0x0013, 0x001e }, + { 0x0013, 0x001f }, + { 0x0013, 0x0020 }, + { 0x0013, 0x0021 }, + { 0x0007, 0x0006 }, + { 0x0006, 0x0005 }, + { 0x0007, 0x0007 }, + { 0x0008, 0x0005 }, + { 0x000a, 0x0007 }, + { 0x000c, 0x0009 }, + { 0x000e, 0x0012 }, + { 0x000f, 0x001a }, + { 0x0012, 0x00a8 }, + { 0x0013, 0x0022 }, + { 0x0013, 0x0023 }, + { 0x0013, 0x0024 }, + { 0x0013, 0x0025 }, + { 0x0013, 0x0026 }, + { 0x0013, 0x0027 }, + { 0x0013, 0x0028 }, + { 0x0013, 0x0029 }, + { 0x0013, 0x002a }, + { 0x0013, 0x002b }, + { 0x0013, 0x002c }, + { 0x0009, 0x0007 }, + { 0x0008, 0x0006 }, + { 0x0008, 0x0007 }, + { 0x000a, 0x0008 }, + { 0x000b, 0x0008 }, + { 0x000d, 0x000c }, + { 0x000e, 0x0013 }, + { 0x0010, 0x002c }, + { 0x0013, 0x002d }, + { 0x0013, 0x002e }, + { 0x0013, 0x002f }, + { 0x0013, 0x0030 }, + { 0x0013, 0x0031 }, + { 0x0013, 0x0032 }, + { 0x0013, 0x0033 }, + { 0x0013, 0x0034 }, + { 0x0013, 0x0035 }, + { 0x0013, 0x0036 }, + { 0x0013, 0x0037 }, + { 0x0013, 0x0038 }, + { 0x000b, 0x0009 }, + { 0x000a, 0x0009 }, + { 0x000b, 0x000a }, + { 0x000b, 0x000b }, + { 0x000d, 0x000d }, + { 0x000f, 0x001b }, + { 0x0010, 0x002d }, + { 0x0013, 0x0039 }, + { 0x0013, 0x003a }, + { 0x0013, 0x003b }, + { 0x0013, 0x003c }, + { 0x0013, 0x003d }, + { 0x0013, 0x003e }, + { 0x0013, 0x003f }, + { 0x0013, 0x0040 }, + { 0x0013, 0x0041 }, + { 0x0013, 0x0042 }, + { 0x0013, 0x0043 }, + { 0x0013, 0x0044 }, + { 0x0013, 0x0045 }, + { 0x000d, 0x000e }, + { 0x000c, 0x000a }, + { 0x000c, 0x000b }, + { 0x000d, 0x000f }, + { 0x000f, 0x001c }, + { 0x000f, 0x001d }, + { 0x0013, 0x0046 }, + { 0x0013, 0x0047 }, + { 0x0013, 0x0048 }, + { 0x0013, 0x0049 }, + { 0x0013, 0x004a }, + { 0x0013, 0x004b }, + { 0x0013, 0x004c }, + { 0x0013, 0x004d }, + { 0x0013, 0x004e }, + { 0x0013, 0x004f }, + { 0x0013, 0x0050 }, + { 0x0013, 0x0051 }, + { 0x0013, 0x0052 }, + { 0x0013, 0x0053 }, + { 0x000f, 0x001e }, + { 0x000f, 0x001f }, + { 0x000f, 0x0020 }, + { 0x000f, 0x0021 }, + { 0x0010, 0x002e }, + { 0x0012, 0x00a9 }, + { 0x0013, 0x0054 }, + { 0x0013, 0x0055 }, + { 0x0012, 0x00aa }, + { 0x0013, 0x0056 }, + { 0x0013, 0x0057 }, + { 0x0013, 0x0058 }, + { 0x0013, 0x0059 }, + { 0x0013, 0x005a }, + { 0x0013, 0x005b }, + { 0x0013, 0x005c }, + { 0x0013, 0x005d }, + { 0x0013, 0x005e }, + { 0x0013, 0x005f }, + { 0x0013, 0x0060 }, + { 0x0013, 0x0061 }, + { 0x0010, 0x002f }, + { 0x0013, 0x0062 }, + { 0x0011, 0x0057 }, + { 0x0013, 0x0063 }, + { 0x0013, 0x0064 }, + { 0x0013, 0x0065 }, + { 0x0013, 0x0066 }, + { 0x0013, 0x0067 }, + { 0x0013, 0x0068 }, + { 0x0013, 0x0069 }, + { 0x0013, 0x006a }, + { 0x0013, 0x006b }, + { 0x0013, 0x006c }, + { 0x0013, 0x006d }, + { 0x0013, 0x006e }, + { 0x0013, 0x006f }, + { 0x0013, 0x0070 }, + { 0x0013, 0x0071 }, + { 0x0013, 0x0072 }, + { 0x0013, 0x0073 }, + { 0x0013, 0x0074 }, + { 0x0013, 0x0075 }, + { 0x0013, 0x0076 }, + { 0x0013, 0x0077 }, + { 0x0013, 0x0078 }, + { 0x0013, 0x0079 }, + { 0x0013, 0x007a }, + { 0x0013, 0x007b }, + { 0x0013, 0x007c }, + { 0x0013, 0x007d }, + { 0x0013, 0x007e }, + { 0x0013, 0x007f }, + { 0x0013, 0x0080 }, + { 0x0013, 0x0081 }, + { 0x0013, 0x0082 }, + { 0x0013, 0x0083 }, + { 0x0013, 0x0084 }, + { 0x0013, 0x0085 }, + { 0x0013, 0x0086 }, + { 0x0013, 0x0087 }, + { 0x0013, 0x0088 }, + { 0x0013, 0x0089 }, + { 0x0013, 0x008a }, + { 0x0013, 0x008b }, + { 0x0013, 0x008c }, + { 0x0013, 0x008d }, + { 0x0013, 0x008e }, + { 0x0013, 0x008f }, + { 0x0013, 0x0090 }, + { 0x0013, 0x0091 }, + { 0x0013, 0x0092 }, + { 0x0013, 0x0093 }, + { 0x0013, 0x0094 }, + { 0x0013, 0x0095 }, + { 0x0013, 0x0096 }, + { 0x0013, 0x0097 }, + { 0x0013, 0x0098 }, + { 0x0013, 0x0099 }, + { 0x0013, 0x009a }, + { 0x0013, 0x009b }, + { 0x0013, 0x009c }, + { 0x0013, 0x009d }, + { 0x0013, 0x009e }, + { 0x0013, 0x009f }, + { 0x0013, 0x00a0 }, + { 0x0013, 0x00a1 }, + { 0x0013, 0x00a2 }, + { 0x0013, 0x00a3 }, + { 0x0013, 0x00a4 }, + { 0x0013, 0x00a5 }, + { 0x0013, 0x00a6 }, + { 0x0013, 0x00a7 }, + { 0x0013, 0x00a8 }, + { 0x0013, 0x00a9 }, + { 0x0013, 0x00aa }, + { 0x0013, 0x00ab }, + { 0x0013, 0x00ac }, + { 0x0013, 0x00ad }, + { 0x0013, 0x00ae }, + { 0x0013, 0x00af }, + { 0x0013, 0x00b0 }, + { 0x0013, 0x00b1 }, + { 0x0013, 0x00b2 }, + { 0x0013, 0x00b3 }, + { 0x0013, 0x00b4 }, + { 0x0013, 0x00b5 }, + { 0x0013, 0x00b6 }, + { 0x0013, 0x00b7 }, + { 0x0013, 0x00b8 }, + { 0x0013, 0x00b9 }, + { 0x0013, 0x00ba }, + { 0x0013, 0x00bb }, + { 0x0013, 0x00bc }, + { 0x0013, 0x00bd }, + { 0x0013, 0x00be }, + { 0x0013, 0x00bf }, + { 0x0013, 0x00c0 }, + { 0x0013, 0x00c1 }, + { 0x0013, 0x00c2 }, + { 0x0013, 0x00c3 }, + { 0x0013, 0x00c4 }, + { 0x0013, 0x00c5 }, + { 0x0013, 0x00c6 }, + { 0x0013, 0x00c7 }, + { 0x0013, 0x00c8 }, + { 0x0013, 0x00c9 }, + { 0x0013, 0x00ca }, + { 0x0013, 0x00cb }, + { 0x0013, 0x00cc }, + { 0x0013, 0x00cd }, + { 0x0013, 0x00ce }, + { 0x0013, 0x00cf }, + { 0x0013, 0x00d0 }, + { 0x0013, 0x00d1 }, + { 0x0013, 0x00d2 }, + { 0x0013, 0x00d3 }, + { 0x0013, 0x00d4 }, + { 0x0013, 0x00d5 }, + { 0x0013, 0x00d6 }, + { 0x0013, 0x00d7 }, + { 0x0013, 0x00d8 }, + { 0x0013, 0x00d9 }, + { 0x0013, 0x00da }, + { 0x0013, 0x00db }, + { 0x0013, 0x00dc }, + { 0x0013, 0x00dd }, + { 0x0013, 0x00de }, + { 0x0013, 0x00df }, + { 0x0013, 0x00e0 }, + { 0x0013, 0x00e1 }, + { 0x0013, 0x00e2 }, + { 0x0013, 0x00e3 }, + { 0x0013, 0x00e4 }, + { 0x0013, 0x00e5 }, + { 0x0013, 0x00e6 }, + { 0x0013, 0x00e7 }, + { 0x0013, 0x00e8 }, + { 0x0013, 0x00e9 }, + { 0x0013, 0x00ea }, + { 0x0013, 0x00eb }, + { 0x0013, 0x00ec }, + { 0x0013, 0x00ed }, + { 0x0013, 0x00ee }, + { 0x0013, 0x00ef }, + { 0x0013, 0x00f0 }, + { 0x0013, 0x00f1 }, + { 0x0013, 0x00f2 }, + { 0x0013, 0x00f3 }, + { 0x0013, 0x00f4 }, + { 0x0013, 0x00f5 }, + { 0x0013, 0x00f6 }, + { 0x0013, 0x00f7 }, + { 0x0013, 0x00f8 }, + { 0x0013, 0x00f9 }, + { 0x0013, 0x00fa }, + { 0x0013, 0x00fb }, + { 0x0013, 0x00fc }, + { 0x0013, 0x00fd }, + { 0x0013, 0x00fe }, + { 0x0013, 0x00ff }, + { 0x0013, 0x0100 }, + { 0x0013, 0x0101 }, + { 0x0013, 0x0102 }, + { 0x0013, 0x0103 }, + { 0x0013, 0x0104 }, + { 0x0013, 0x0105 }, + { 0x0013, 0x0106 }, + { 0x0013, 0x0107 }, + { 0x0013, 0x0108 }, + { 0x0013, 0x0109 }, + { 0x0013, 0x010a }, + { 0x0013, 0x010b }, + { 0x0013, 0x010c }, + { 0x0013, 0x010d }, + { 0x0013, 0x010e }, + { 0x0013, 0x010f }, + { 0x0013, 0x0110 }, + { 0x0013, 0x0111 }, + { 0x0013, 0x0112 }, + { 0x0013, 0x0113 }, + { 0x0013, 0x0114 }, + { 0x0013, 0x0115 }, + { 0x0013, 0x0116 }, + { 0x0013, 0x0117 }, + { 0x0013, 0x0118 }, + { 0x0013, 0x0119 }, + { 0x0013, 0x011a }, + { 0x0013, 0x011b }, + { 0x0013, 0x011c }, + { 0x0013, 0x011d }, + { 0x0013, 0x011e }, + { 0x0013, 0x011f }, + { 0x0013, 0x0120 }, + { 0x0013, 0x0121 }, + { 0x0013, 0x0122 }, + { 0x0013, 0x0123 }, + { 0x0013, 0x0124 }, + { 0x0013, 0x0125 }, + { 0x0013, 0x0126 }, + { 0x0013, 0x0127 }, + { 0x0013, 0x0128 }, + { 0x0013, 0x0129 }, + { 0x0013, 0x012a }, + { 0x0013, 0x012b }, + { 0x0013, 0x012c }, + { 0x0013, 0x012d }, + { 0x0013, 0x012e }, + { 0x0013, 0x012f }, + { 0x0013, 0x0130 }, + { 0x0013, 0x0131 }, + { 0x0013, 0x0132 }, + { 0x0013, 0x0133 }, + { 0x0013, 0x0134 }, + { 0x0013, 0x0135 }, + { 0x0013, 0x0136 }, + { 0x0013, 0x0137 }, + { 0x0013, 0x0138 }, + { 0x0013, 0x0139 }, + { 0x0013, 0x013a }, + { 0x0013, 0x013b }, + { 0x0013, 0x013c }, + { 0x0013, 0x013d }, + { 0x0013, 0x013e }, + { 0x0013, 0x013f }, + { 0x0013, 0x0140 }, + { 0x0013, 0x0141 }, + { 0x0013, 0x0142 }, + { 0x0013, 0x0143 }, + { 0x0013, 0x0144 }, + { 0x0013, 0x0145 }, + { 0x0013, 0x0146 }, + { 0x0013, 0x0147 }, + { 0x0013, 0x0148 }, + { 0x0013, 0x0149 }, + { 0x0013, 0x014a }, + { 0x0013, 0x014b }, + { 0x0012, 0x00ab }, + { 0x0012, 0x00ac }, + { 0x0012, 0x00ad }, + }; + +const uint16_t c_aauiLCLDHuffEnc47[576][2] = + { + { 0x0002, 0x0003 }, + { 0x0003, 0x0003 }, + { 0x0005, 0x0005 }, + { 0x0006, 0x0004 }, + { 0x0008, 0x0006 }, + { 0x000a, 0x0007 }, + { 0x000c, 0x000b }, + { 0x000d, 0x000d }, + { 0x0010, 0x0041 }, + { 0x0013, 0x0000 }, + { 0x0013, 0x0001 }, + { 0x0013, 0x0002 }, + { 0x0013, 0x0003 }, + { 0x0013, 0x0004 }, + { 0x0013, 0x0005 }, + { 0x0013, 0x0006 }, + { 0x0013, 0x0007 }, + { 0x0013, 0x0008 }, + { 0x0013, 0x0009 }, + { 0x0013, 0x000a }, + { 0x0013, 0x000b }, + { 0x0013, 0x000c }, + { 0x0013, 0x000d }, + { 0x0013, 0x000e }, + { 0x0003, 0x0004 }, + { 0x0003, 0x0005 }, + { 0x0004, 0x0004 }, + { 0x0006, 0x0005 }, + { 0x0007, 0x0005 }, + { 0x0009, 0x0006 }, + { 0x000b, 0x0007 }, + { 0x000d, 0x000e }, + { 0x000f, 0x0025 }, + { 0x000f, 0x0026 }, + { 0x0012, 0x00f6 }, + { 0x0013, 0x000f }, + { 0x0013, 0x0010 }, + { 0x0013, 0x0011 }, + { 0x0013, 0x0012 }, + { 0x0013, 0x0013 }, + { 0x0013, 0x0014 }, + { 0x0013, 0x0015 }, + { 0x0013, 0x0016 }, + { 0x0013, 0x0017 }, + { 0x0013, 0x0018 }, + { 0x0013, 0x0019 }, + { 0x0013, 0x001a }, + { 0x0013, 0x001b }, + { 0x0005, 0x0006 }, + { 0x0004, 0x0005 }, + { 0x0005, 0x0007 }, + { 0x0006, 0x0006 }, + { 0x0008, 0x0007 }, + { 0x0009, 0x0007 }, + { 0x000b, 0x0008 }, + { 0x000d, 0x000f }, + { 0x000f, 0x0027 }, + { 0x0012, 0x00f7 }, + { 0x0013, 0x001c }, + { 0x0013, 0x001d }, + { 0x0013, 0x001e }, + { 0x0013, 0x001f }, + { 0x0013, 0x0020 }, + { 0x0013, 0x0021 }, + { 0x0013, 0x0022 }, + { 0x0013, 0x0023 }, + { 0x0013, 0x0024 }, + { 0x0013, 0x0025 }, + { 0x0013, 0x0026 }, + { 0x0013, 0x0027 }, + { 0x0013, 0x0028 }, + { 0x0013, 0x0029 }, + { 0x0006, 0x0007 }, + { 0x0006, 0x0008 }, + { 0x0006, 0x0009 }, + { 0x0007, 0x0006 }, + { 0x0009, 0x0008 }, + { 0x000a, 0x0008 }, + { 0x000c, 0x000c }, + { 0x000e, 0x0017 }, + { 0x0010, 0x0042 }, + { 0x0012, 0x00f8 }, + { 0x0013, 0x002a }, + { 0x0013, 0x002b }, + { 0x0013, 0x002c }, + { 0x0013, 0x002d }, + { 0x0013, 0x002e }, + { 0x0013, 0x002f }, + { 0x0013, 0x0030 }, + { 0x0013, 0x0031 }, + { 0x0013, 0x0032 }, + { 0x0013, 0x0033 }, + { 0x0013, 0x0034 }, + { 0x0013, 0x0035 }, + { 0x0013, 0x0036 }, + { 0x0013, 0x0037 }, + { 0x0008, 0x0008 }, + { 0x0007, 0x0007 }, + { 0x0008, 0x0009 }, + { 0x0009, 0x0009 }, + { 0x000a, 0x0009 }, + { 0x000b, 0x0009 }, + { 0x000d, 0x0010 }, + { 0x000f, 0x0028 }, + { 0x000f, 0x0029 }, + { 0x0011, 0x007f }, + { 0x0013, 0x0038 }, + { 0x0013, 0x0039 }, + { 0x0013, 0x003a }, + { 0x0013, 0x003b }, + { 0x0013, 0x003c }, + { 0x0013, 0x003d }, + { 0x0013, 0x003e }, + { 0x0013, 0x003f }, + { 0x0013, 0x0040 }, + { 0x0013, 0x0041 }, + { 0x0013, 0x0042 }, + { 0x0013, 0x0043 }, + { 0x0013, 0x0044 }, + { 0x0013, 0x0045 }, + { 0x000a, 0x000a }, + { 0x0009, 0x000a }, + { 0x0009, 0x000b }, + { 0x000a, 0x000b }, + { 0x000b, 0x000a }, + { 0x000d, 0x0011 }, + { 0x000f, 0x002a }, + { 0x0010, 0x0043 }, + { 0x0012, 0x00f9 }, + { 0x0013, 0x0046 }, + { 0x0013, 0x0047 }, + { 0x0013, 0x0048 }, + { 0x0013, 0x0049 }, + { 0x0013, 0x004a }, + { 0x0013, 0x004b }, + { 0x0013, 0x004c }, + { 0x0013, 0x004d }, + { 0x0013, 0x004e }, + { 0x0013, 0x004f }, + { 0x0013, 0x0050 }, + { 0x0013, 0x0051 }, + { 0x0013, 0x0052 }, + { 0x0013, 0x0053 }, + { 0x0013, 0x0054 }, + { 0x000b, 0x000b }, + { 0x000b, 0x000c }, + { 0x000b, 0x000d }, + { 0x000c, 0x000d }, + { 0x000d, 0x0012 }, + { 0x000e, 0x0018 }, + { 0x0010, 0x0044 }, + { 0x0013, 0x0055 }, + { 0x0013, 0x0056 }, + { 0x0013, 0x0057 }, + { 0x0013, 0x0058 }, + { 0x0013, 0x0059 }, + { 0x0013, 0x005a }, + { 0x0013, 0x005b }, + { 0x0013, 0x005c }, + { 0x0013, 0x005d }, + { 0x0013, 0x005e }, + { 0x0013, 0x005f }, + { 0x0013, 0x0060 }, + { 0x0013, 0x0061 }, + { 0x0013, 0x0062 }, + { 0x0013, 0x0063 }, + { 0x0013, 0x0064 }, + { 0x0013, 0x0065 }, + { 0x000e, 0x0019 }, + { 0x000d, 0x0013 }, + { 0x000d, 0x0014 }, + { 0x000d, 0x0015 }, + { 0x000f, 0x002b }, + { 0x0010, 0x0045 }, + { 0x0013, 0x0066 }, + { 0x0012, 0x00fa }, + { 0x0013, 0x0067 }, + { 0x0013, 0x0068 }, + { 0x0013, 0x0069 }, + { 0x0013, 0x006a }, + { 0x0013, 0x006b }, + { 0x0013, 0x006c }, + { 0x0013, 0x006d }, + { 0x0013, 0x006e }, + { 0x0013, 0x006f }, + { 0x0013, 0x0070 }, + { 0x0013, 0x0071 }, + { 0x0013, 0x0072 }, + { 0x0013, 0x0073 }, + { 0x0013, 0x0074 }, + { 0x0013, 0x0075 }, + { 0x0013, 0x0076 }, + { 0x0010, 0x0046 }, + { 0x000f, 0x002c }, + { 0x000f, 0x002d }, + { 0x0010, 0x0047 }, + { 0x0011, 0x0080 }, + { 0x0013, 0x0077 }, + { 0x0013, 0x0078 }, + { 0x0013, 0x0079 }, + { 0x0013, 0x007a }, + { 0x0013, 0x007b }, + { 0x0013, 0x007c }, + { 0x0013, 0x007d }, + { 0x0013, 0x007e }, + { 0x0013, 0x007f }, + { 0x0013, 0x0080 }, + { 0x0013, 0x0081 }, + { 0x0013, 0x0082 }, + { 0x0013, 0x0083 }, + { 0x0013, 0x0084 }, + { 0x0013, 0x0085 }, + { 0x0013, 0x0086 }, + { 0x0013, 0x0087 }, + { 0x0013, 0x0088 }, + { 0x0013, 0x0089 }, + { 0x0013, 0x008a }, + { 0x0010, 0x0048 }, + { 0x0010, 0x0049 }, + { 0x0011, 0x0081 }, + { 0x0013, 0x008b }, + { 0x0012, 0x00fb }, + { 0x0013, 0x008c }, + { 0x0013, 0x008d }, + { 0x0013, 0x008e }, + { 0x0013, 0x008f }, + { 0x0013, 0x0090 }, + { 0x0013, 0x0091 }, + { 0x0013, 0x0092 }, + { 0x0013, 0x0093 }, + { 0x0013, 0x0094 }, + { 0x0013, 0x0095 }, + { 0x0013, 0x0096 }, + { 0x0013, 0x0097 }, + { 0x0013, 0x0098 }, + { 0x0013, 0x0099 }, + { 0x0013, 0x009a }, + { 0x0013, 0x009b }, + { 0x0013, 0x009c }, + { 0x0013, 0x009d }, + { 0x0013, 0x009e }, + { 0x0013, 0x009f }, + { 0x0013, 0x00a0 }, + { 0x0012, 0x00fc }, + { 0x0013, 0x00a1 }, + { 0x0013, 0x00a2 }, + { 0x0013, 0x00a3 }, + { 0x0013, 0x00a4 }, + { 0x0013, 0x00a5 }, + { 0x0013, 0x00a6 }, + { 0x0013, 0x00a7 }, + { 0x0013, 0x00a8 }, + { 0x0013, 0x00a9 }, + { 0x0013, 0x00aa }, + { 0x0013, 0x00ab }, + { 0x0013, 0x00ac }, + { 0x0013, 0x00ad }, + { 0x0013, 0x00ae }, + { 0x0013, 0x00af }, + { 0x0013, 0x00b0 }, + { 0x0013, 0x00b1 }, + { 0x0013, 0x00b2 }, + { 0x0013, 0x00b3 }, + { 0x0013, 0x00b4 }, + { 0x0013, 0x00b5 }, + { 0x0013, 0x00b6 }, + { 0x0013, 0x00b7 }, + { 0x0013, 0x00b8 }, + { 0x0013, 0x00b9 }, + { 0x0013, 0x00ba }, + { 0x0013, 0x00bb }, + { 0x0013, 0x00bc }, + { 0x0013, 0x00bd }, + { 0x0013, 0x00be }, + { 0x0013, 0x00bf }, + { 0x0013, 0x00c0 }, + { 0x0013, 0x00c1 }, + { 0x0013, 0x00c2 }, + { 0x0013, 0x00c3 }, + { 0x0013, 0x00c4 }, + { 0x0013, 0x00c5 }, + { 0x0013, 0x00c6 }, + { 0x0013, 0x00c7 }, + { 0x0013, 0x00c8 }, + { 0x0013, 0x00c9 }, + { 0x0013, 0x00ca }, + { 0x0013, 0x00cb }, + { 0x0013, 0x00cc }, + { 0x0013, 0x00cd }, + { 0x0013, 0x00ce }, + { 0x0013, 0x00cf }, + { 0x0013, 0x00d0 }, + { 0x0013, 0x00d1 }, + { 0x0013, 0x00d2 }, + { 0x0013, 0x00d3 }, + { 0x0013, 0x00d4 }, + { 0x0013, 0x00d5 }, + { 0x0013, 0x00d6 }, + { 0x0013, 0x00d7 }, + { 0x0013, 0x00d8 }, + { 0x0013, 0x00d9 }, + { 0x0013, 0x00da }, + { 0x0013, 0x00db }, + { 0x0013, 0x00dc }, + { 0x0013, 0x00dd }, + { 0x0013, 0x00de }, + { 0x0013, 0x00df }, + { 0x0013, 0x00e0 }, + { 0x0013, 0x00e1 }, + { 0x0013, 0x00e2 }, + { 0x0013, 0x00e3 }, + { 0x0013, 0x00e4 }, + { 0x0013, 0x00e5 }, + { 0x0013, 0x00e6 }, + { 0x0013, 0x00e7 }, + { 0x0013, 0x00e8 }, + { 0x0013, 0x00e9 }, + { 0x0013, 0x00ea }, + { 0x0013, 0x00eb }, + { 0x0013, 0x00ec }, + { 0x0013, 0x00ed }, + { 0x0013, 0x00ee }, + { 0x0013, 0x00ef }, + { 0x0013, 0x00f0 }, + { 0x0013, 0x00f1 }, + { 0x0013, 0x00f2 }, + { 0x0013, 0x00f3 }, + { 0x0013, 0x00f4 }, + { 0x0013, 0x00f5 }, + { 0x0013, 0x00f6 }, + { 0x0013, 0x00f7 }, + { 0x0013, 0x00f8 }, + { 0x0013, 0x00f9 }, + { 0x0013, 0x00fa }, + { 0x0013, 0x00fb }, + { 0x0013, 0x00fc }, + { 0x0013, 0x00fd }, + { 0x0013, 0x00fe }, + { 0x0013, 0x00ff }, + { 0x0013, 0x0100 }, + { 0x0013, 0x0101 }, + { 0x0013, 0x0102 }, + { 0x0013, 0x0103 }, + { 0x0013, 0x0104 }, + { 0x0013, 0x0105 }, + { 0x0013, 0x0106 }, + { 0x0013, 0x0107 }, + { 0x0013, 0x0108 }, + { 0x0013, 0x0109 }, + { 0x0013, 0x010a }, + { 0x0013, 0x010b }, + { 0x0013, 0x010c }, + { 0x0013, 0x010d }, + { 0x0013, 0x010e }, + { 0x0013, 0x010f }, + { 0x0013, 0x0110 }, + { 0x0013, 0x0111 }, + { 0x0013, 0x0112 }, + { 0x0013, 0x0113 }, + { 0x0013, 0x0114 }, + { 0x0013, 0x0115 }, + { 0x0013, 0x0116 }, + { 0x0013, 0x0117 }, + { 0x0013, 0x0118 }, + { 0x0013, 0x0119 }, + { 0x0013, 0x011a }, + { 0x0013, 0x011b }, + { 0x0013, 0x011c }, + { 0x0013, 0x011d }, + { 0x0013, 0x011e }, + { 0x0013, 0x011f }, + { 0x0013, 0x0120 }, + { 0x0013, 0x0121 }, + { 0x0013, 0x0122 }, + { 0x0013, 0x0123 }, + { 0x0013, 0x0124 }, + { 0x0013, 0x0125 }, + { 0x0013, 0x0126 }, + { 0x0013, 0x0127 }, + { 0x0013, 0x0128 }, + { 0x0013, 0x0129 }, + { 0x0013, 0x012a }, + { 0x0013, 0x012b }, + { 0x0013, 0x012c }, + { 0x0013, 0x012d }, + { 0x0013, 0x012e }, + { 0x0013, 0x012f }, + { 0x0013, 0x0130 }, + { 0x0013, 0x0131 }, + { 0x0013, 0x0132 }, + { 0x0013, 0x0133 }, + { 0x0013, 0x0134 }, + { 0x0013, 0x0135 }, + { 0x0013, 0x0136 }, + { 0x0013, 0x0137 }, + { 0x0013, 0x0138 }, + { 0x0013, 0x0139 }, + { 0x0013, 0x013a }, + { 0x0013, 0x013b }, + { 0x0013, 0x013c }, + { 0x0013, 0x013d }, + { 0x0013, 0x013e }, + { 0x0013, 0x013f }, + { 0x0013, 0x0140 }, + { 0x0013, 0x0141 }, + { 0x0013, 0x0142 }, + { 0x0013, 0x0143 }, + { 0x0013, 0x0144 }, + { 0x0013, 0x0145 }, + { 0x0013, 0x0146 }, + { 0x0013, 0x0147 }, + { 0x0013, 0x0148 }, + { 0x0013, 0x0149 }, + { 0x0013, 0x014a }, + { 0x0013, 0x014b }, + { 0x0013, 0x014c }, + { 0x0013, 0x014d }, + { 0x0013, 0x014e }, + { 0x0013, 0x014f }, + { 0x0013, 0x0150 }, + { 0x0013, 0x0151 }, + { 0x0013, 0x0152 }, + { 0x0013, 0x0153 }, + { 0x0013, 0x0154 }, + { 0x0013, 0x0155 }, + { 0x0013, 0x0156 }, + { 0x0013, 0x0157 }, + { 0x0013, 0x0158 }, + { 0x0013, 0x0159 }, + { 0x0013, 0x015a }, + { 0x0013, 0x015b }, + { 0x0013, 0x015c }, + { 0x0013, 0x015d }, + { 0x0013, 0x015e }, + { 0x0013, 0x015f }, + { 0x0013, 0x0160 }, + { 0x0013, 0x0161 }, + { 0x0013, 0x0162 }, + { 0x0013, 0x0163 }, + { 0x0013, 0x0164 }, + { 0x0013, 0x0165 }, + { 0x0013, 0x0166 }, + { 0x0013, 0x0167 }, + { 0x0013, 0x0168 }, + { 0x0013, 0x0169 }, + { 0x0013, 0x016a }, + { 0x0013, 0x016b }, + { 0x0013, 0x016c }, + { 0x0013, 0x016d }, + { 0x0013, 0x016e }, + { 0x0013, 0x016f }, + { 0x0013, 0x0170 }, + { 0x0013, 0x0171 }, + { 0x0013, 0x0172 }, + { 0x0013, 0x0173 }, + { 0x0013, 0x0174 }, + { 0x0013, 0x0175 }, + { 0x0013, 0x0176 }, + { 0x0013, 0x0177 }, + { 0x0013, 0x0178 }, + { 0x0013, 0x0179 }, + { 0x0013, 0x017a }, + { 0x0013, 0x017b }, + { 0x0013, 0x017c }, + { 0x0013, 0x017d }, + { 0x0013, 0x017e }, + { 0x0013, 0x017f }, + { 0x0013, 0x0180 }, + { 0x0013, 0x0181 }, + { 0x0013, 0x0182 }, + { 0x0013, 0x0183 }, + { 0x0013, 0x0184 }, + { 0x0013, 0x0185 }, + { 0x0013, 0x0186 }, + { 0x0013, 0x0187 }, + { 0x0013, 0x0188 }, + { 0x0013, 0x0189 }, + { 0x0013, 0x018a }, + { 0x0013, 0x018b }, + { 0x0013, 0x018c }, + { 0x0013, 0x018d }, + { 0x0013, 0x018e }, + { 0x0013, 0x018f }, + { 0x0013, 0x0190 }, + { 0x0013, 0x0191 }, + { 0x0013, 0x0192 }, + { 0x0013, 0x0193 }, + { 0x0013, 0x0194 }, + { 0x0013, 0x0195 }, + { 0x0013, 0x0196 }, + { 0x0013, 0x0197 }, + { 0x0013, 0x0198 }, + { 0x0013, 0x0199 }, + { 0x0013, 0x019a }, + { 0x0013, 0x019b }, + { 0x0013, 0x019c }, + { 0x0013, 0x019d }, + { 0x0013, 0x019e }, + { 0x0013, 0x019f }, + { 0x0013, 0x01a0 }, + { 0x0013, 0x01a1 }, + { 0x0013, 0x01a2 }, + { 0x0013, 0x01a3 }, + { 0x0013, 0x01a4 }, + { 0x0013, 0x01a5 }, + { 0x0013, 0x01a6 }, + { 0x0013, 0x01a7 }, + { 0x0013, 0x01a8 }, + { 0x0013, 0x01a9 }, + { 0x0013, 0x01aa }, + { 0x0013, 0x01ab }, + { 0x0013, 0x01ac }, + { 0x0013, 0x01ad }, + { 0x0013, 0x01ae }, + { 0x0013, 0x01af }, + { 0x0013, 0x01b0 }, + { 0x0013, 0x01b1 }, + { 0x0013, 0x01b2 }, + { 0x0013, 0x01b3 }, + { 0x0013, 0x01b4 }, + { 0x0013, 0x01b5 }, + { 0x0013, 0x01b6 }, + { 0x0013, 0x01b7 }, + { 0x0013, 0x01b8 }, + { 0x0013, 0x01b9 }, + { 0x0013, 0x01ba }, + { 0x0013, 0x01bb }, + { 0x0013, 0x01bc }, + { 0x0013, 0x01bd }, + { 0x0013, 0x01be }, + { 0x0013, 0x01bf }, + { 0x0013, 0x01c0 }, + { 0x0013, 0x01c1 }, + { 0x0013, 0x01c2 }, + { 0x0013, 0x01c3 }, + { 0x0013, 0x01c4 }, + { 0x0013, 0x01c5 }, + { 0x0013, 0x01c6 }, + { 0x0013, 0x01c7 }, + { 0x0013, 0x01c8 }, + { 0x0013, 0x01c9 }, + { 0x0013, 0x01ca }, + { 0x0013, 0x01cb }, + { 0x0013, 0x01cc }, + { 0x0013, 0x01cd }, + { 0x0013, 0x01ce }, + { 0x0013, 0x01cf }, + { 0x0013, 0x01d0 }, + { 0x0013, 0x01d1 }, + { 0x0013, 0x01d2 }, + { 0x0013, 0x01d3 }, + { 0x0013, 0x01d4 }, + { 0x0013, 0x01d5 }, + { 0x0013, 0x01d6 }, + { 0x0013, 0x01d7 }, + { 0x0013, 0x01d8 }, + { 0x0013, 0x01d9 }, + { 0x0013, 0x01da }, + { 0x0013, 0x01db }, + { 0x0013, 0x01dc }, + { 0x0013, 0x01dd }, + { 0x0013, 0x01de }, + { 0x0013, 0x01df }, + { 0x0013, 0x01e0 }, + { 0x0013, 0x01e1 }, + { 0x0013, 0x01e2 }, + { 0x0013, 0x01e3 }, + { 0x0013, 0x01e4 }, + { 0x0013, 0x01e5 }, + { 0x0013, 0x01e6 }, + { 0x0013, 0x01e7 }, + { 0x0013, 0x01e8 }, + { 0x0013, 0x01e9 }, + { 0x0013, 0x01ea }, + { 0x0013, 0x01eb }, + { 0x0012, 0x00fd }, + }; + +const uint16_t c_aauiLCLDHuffEnc48[729][2] = + { + { 0x0002, 0x0003 }, + { 0x0003, 0x0003 }, + { 0x0005, 0x0006 }, + { 0x0006, 0x0006 }, + { 0x0008, 0x0006 }, + { 0x0009, 0x0007 }, + { 0x000b, 0x000b }, + { 0x000c, 0x000d }, + { 0x000f, 0x0030 }, + { 0x0010, 0x0055 }, + { 0x0012, 0x0136 }, + { 0x0013, 0x0000 }, + { 0x0013, 0x0001 }, + { 0x0013, 0x0002 }, + { 0x0013, 0x0003 }, + { 0x0013, 0x0004 }, + { 0x0013, 0x0005 }, + { 0x0013, 0x0006 }, + { 0x0013, 0x0007 }, + { 0x0013, 0x0008 }, + { 0x0013, 0x0009 }, + { 0x0013, 0x000a }, + { 0x0013, 0x000b }, + { 0x0013, 0x000c }, + { 0x0013, 0x000d }, + { 0x0013, 0x000e }, + { 0x0013, 0x000f }, + { 0x0003, 0x0004 }, + { 0x0003, 0x0005 }, + { 0x0005, 0x0007 }, + { 0x0006, 0x0007 }, + { 0x0007, 0x0007 }, + { 0x0008, 0x0007 }, + { 0x000a, 0x0008 }, + { 0x000c, 0x000e }, + { 0x000d, 0x0012 }, + { 0x000f, 0x0031 }, + { 0x0011, 0x00a0 }, + { 0x0013, 0x0010 }, + { 0x0013, 0x0011 }, + { 0x0013, 0x0012 }, + { 0x0013, 0x0013 }, + { 0x0013, 0x0014 }, + { 0x0013, 0x0015 }, + { 0x0013, 0x0016 }, + { 0x0013, 0x0017 }, + { 0x0013, 0x0018 }, + { 0x0013, 0x0019 }, + { 0x0013, 0x001a }, + { 0x0013, 0x001b }, + { 0x0013, 0x001c }, + { 0x0013, 0x001d }, + { 0x0013, 0x001e }, + { 0x0013, 0x001f }, + { 0x0005, 0x0008 }, + { 0x0004, 0x0005 }, + { 0x0005, 0x0009 }, + { 0x0006, 0x0008 }, + { 0x0007, 0x0008 }, + { 0x0008, 0x0008 }, + { 0x000a, 0x0009 }, + { 0x000c, 0x000f }, + { 0x000d, 0x0013 }, + { 0x000f, 0x0032 }, + { 0x0011, 0x00a1 }, + { 0x0013, 0x0020 }, + { 0x0013, 0x0021 }, + { 0x0013, 0x0022 }, + { 0x0013, 0x0023 }, + { 0x0013, 0x0024 }, + { 0x0013, 0x0025 }, + { 0x0013, 0x0026 }, + { 0x0013, 0x0027 }, + { 0x0013, 0x0028 }, + { 0x0013, 0x0029 }, + { 0x0013, 0x002a }, + { 0x0013, 0x002b }, + { 0x0013, 0x002c }, + { 0x0013, 0x002d }, + { 0x0013, 0x002e }, + { 0x0013, 0x002f }, + { 0x0006, 0x0009 }, + { 0x0006, 0x000a }, + { 0x0006, 0x000b }, + { 0x0007, 0x0009 }, + { 0x0008, 0x0009 }, + { 0x0009, 0x0008 }, + { 0x000b, 0x000c }, + { 0x000d, 0x0014 }, + { 0x000e, 0x001d }, + { 0x000f, 0x0033 }, + { 0x0012, 0x0137 }, + { 0x0013, 0x0030 }, + { 0x0013, 0x0031 }, + { 0x0013, 0x0032 }, + { 0x0013, 0x0033 }, + { 0x0013, 0x0034 }, + { 0x0013, 0x0035 }, + { 0x0013, 0x0036 }, + { 0x0013, 0x0037 }, + { 0x0013, 0x0038 }, + { 0x0013, 0x0039 }, + { 0x0013, 0x003a }, + { 0x0013, 0x003b }, + { 0x0013, 0x003c }, + { 0x0013, 0x003d }, + { 0x0013, 0x003e }, + { 0x0013, 0x003f }, + { 0x0008, 0x000a }, + { 0x0007, 0x000a }, + { 0x0007, 0x000b }, + { 0x0008, 0x000b }, + { 0x0009, 0x0009 }, + { 0x000a, 0x000a }, + { 0x000c, 0x0010 }, + { 0x000d, 0x0015 }, + { 0x000f, 0x0034 }, + { 0x0010, 0x0056 }, + { 0x0012, 0x0138 }, + { 0x0013, 0x0040 }, + { 0x0013, 0x0041 }, + { 0x0013, 0x0042 }, + { 0x0013, 0x0043 }, + { 0x0013, 0x0044 }, + { 0x0013, 0x0045 }, + { 0x0013, 0x0046 }, + { 0x0013, 0x0047 }, + { 0x0013, 0x0048 }, + { 0x0013, 0x0049 }, + { 0x0013, 0x004a }, + { 0x0013, 0x004b }, + { 0x0013, 0x004c }, + { 0x0013, 0x004d }, + { 0x0013, 0x004e }, + { 0x0013, 0x004f }, + { 0x0009, 0x000a }, + { 0x0008, 0x000c }, + { 0x0008, 0x000d }, + { 0x0009, 0x000b }, + { 0x000a, 0x000b }, + { 0x000c, 0x0011 }, + { 0x000d, 0x0016 }, + { 0x000e, 0x001e }, + { 0x0010, 0x0057 }, + { 0x0011, 0x00a2 }, + { 0x0011, 0x00a3 }, + { 0x0013, 0x0050 }, + { 0x0013, 0x0051 }, + { 0x0013, 0x0052 }, + { 0x0013, 0x0053 }, + { 0x0013, 0x0054 }, + { 0x0013, 0x0055 }, + { 0x0013, 0x0056 }, + { 0x0013, 0x0057 }, + { 0x0013, 0x0058 }, + { 0x0013, 0x0059 }, + { 0x0013, 0x005a }, + { 0x0013, 0x005b }, + { 0x0013, 0x005c }, + { 0x0013, 0x005d }, + { 0x0013, 0x005e }, + { 0x0013, 0x005f }, + { 0x000b, 0x000d }, + { 0x000a, 0x000c }, + { 0x000a, 0x000d }, + { 0x000b, 0x000e }, + { 0x000c, 0x0012 }, + { 0x000d, 0x0017 }, + { 0x000e, 0x001f }, + { 0x0010, 0x0058 }, + { 0x0012, 0x0139 }, + { 0x0011, 0x00a4 }, + { 0x0012, 0x013a }, + { 0x0013, 0x0060 }, + { 0x0013, 0x0061 }, + { 0x0013, 0x0062 }, + { 0x0013, 0x0063 }, + { 0x0013, 0x0064 }, + { 0x0013, 0x0065 }, + { 0x0013, 0x0066 }, + { 0x0013, 0x0067 }, + { 0x0013, 0x0068 }, + { 0x0013, 0x0069 }, + { 0x0013, 0x006a }, + { 0x0013, 0x006b }, + { 0x0013, 0x006c }, + { 0x0013, 0x006d }, + { 0x0013, 0x006e }, + { 0x0013, 0x006f }, + { 0x000c, 0x0013 }, + { 0x000b, 0x000f }, + { 0x000c, 0x0014 }, + { 0x000c, 0x0015 }, + { 0x000d, 0x0018 }, + { 0x000e, 0x0020 }, + { 0x000f, 0x0035 }, + { 0x0012, 0x013b }, + { 0x0013, 0x0070 }, + { 0x0013, 0x0071 }, + { 0x0013, 0x0072 }, + { 0x0013, 0x0073 }, + { 0x0013, 0x0074 }, + { 0x0013, 0x0075 }, + { 0x0013, 0x0076 }, + { 0x0013, 0x0077 }, + { 0x0013, 0x0078 }, + { 0x0013, 0x0079 }, + { 0x0013, 0x007a }, + { 0x0013, 0x007b }, + { 0x0013, 0x007c }, + { 0x0013, 0x007d }, + { 0x0013, 0x007e }, + { 0x0013, 0x007f }, + { 0x0013, 0x0080 }, + { 0x0013, 0x0081 }, + { 0x0013, 0x0082 }, + { 0x000e, 0x0021 }, + { 0x000d, 0x0019 }, + { 0x000e, 0x0022 }, + { 0x000e, 0x0023 }, + { 0x000f, 0x0036 }, + { 0x0010, 0x0059 }, + { 0x0011, 0x00a5 }, + { 0x0013, 0x0083 }, + { 0x0011, 0x00a6 }, + { 0x0012, 0x013c }, + { 0x0013, 0x0084 }, + { 0x0013, 0x0085 }, + { 0x0013, 0x0086 }, + { 0x0013, 0x0087 }, + { 0x0013, 0x0088 }, + { 0x0013, 0x0089 }, + { 0x0013, 0x008a }, + { 0x0013, 0x008b }, + { 0x0013, 0x008c }, + { 0x0013, 0x008d }, + { 0x0013, 0x008e }, + { 0x0013, 0x008f }, + { 0x0013, 0x0090 }, + { 0x0013, 0x0091 }, + { 0x0013, 0x0092 }, + { 0x0013, 0x0093 }, + { 0x0013, 0x0094 }, + { 0x0010, 0x005a }, + { 0x000f, 0x0037 }, + { 0x000f, 0x0038 }, + { 0x000f, 0x0039 }, + { 0x0010, 0x005b }, + { 0x0010, 0x005c }, + { 0x0013, 0x0095 }, + { 0x0011, 0x00a7 }, + { 0x0013, 0x0096 }, + { 0x0013, 0x0097 }, + { 0x0013, 0x0098 }, + { 0x0013, 0x0099 }, + { 0x0013, 0x009a }, + { 0x0013, 0x009b }, + { 0x0013, 0x009c }, + { 0x0013, 0x009d }, + { 0x0013, 0x009e }, + { 0x0013, 0x009f }, + { 0x0013, 0x00a0 }, + { 0x0013, 0x00a1 }, + { 0x0013, 0x00a2 }, + { 0x0013, 0x00a3 }, + { 0x0013, 0x00a4 }, + { 0x0013, 0x00a5 }, + { 0x0013, 0x00a6 }, + { 0x0013, 0x00a7 }, + { 0x0013, 0x00a8 }, + { 0x0010, 0x005d }, + { 0x0010, 0x005e }, + { 0x0013, 0x00a9 }, + { 0x0010, 0x005f }, + { 0x0013, 0x00aa }, + { 0x0012, 0x013d }, + { 0x0013, 0x00ab }, + { 0x0013, 0x00ac }, + { 0x0013, 0x00ad }, + { 0x0013, 0x00ae }, + { 0x0013, 0x00af }, + { 0x0013, 0x00b0 }, + { 0x0013, 0x00b1 }, + { 0x0013, 0x00b2 }, + { 0x0013, 0x00b3 }, + { 0x0013, 0x00b4 }, + { 0x0013, 0x00b5 }, + { 0x0013, 0x00b6 }, + { 0x0013, 0x00b7 }, + { 0x0013, 0x00b8 }, + { 0x0013, 0x00b9 }, + { 0x0013, 0x00ba }, + { 0x0013, 0x00bb }, + { 0x0013, 0x00bc }, + { 0x0013, 0x00bd }, + { 0x0013, 0x00be }, + { 0x0013, 0x00bf }, + { 0x0013, 0x00c0 }, + { 0x0011, 0x00a8 }, + { 0x0013, 0x00c1 }, + { 0x0011, 0x00a9 }, + { 0x0013, 0x00c2 }, + { 0x0013, 0x00c3 }, + { 0x0013, 0x00c4 }, + { 0x0013, 0x00c5 }, + { 0x0013, 0x00c6 }, + { 0x0013, 0x00c7 }, + { 0x0013, 0x00c8 }, + { 0x0013, 0x00c9 }, + { 0x0013, 0x00ca }, + { 0x0013, 0x00cb }, + { 0x0013, 0x00cc }, + { 0x0013, 0x00cd }, + { 0x0013, 0x00ce }, + { 0x0013, 0x00cf }, + { 0x0013, 0x00d0 }, + { 0x0013, 0x00d1 }, + { 0x0013, 0x00d2 }, + { 0x0013, 0x00d3 }, + { 0x0013, 0x00d4 }, + { 0x0013, 0x00d5 }, + { 0x0013, 0x00d6 }, + { 0x0013, 0x00d7 }, + { 0x0013, 0x00d8 }, + { 0x0013, 0x00d9 }, + { 0x0013, 0x00da }, + { 0x0012, 0x013e }, + { 0x0013, 0x00db }, + { 0x0013, 0x00dc }, + { 0x0013, 0x00dd }, + { 0x0013, 0x00de }, + { 0x0013, 0x00df }, + { 0x0013, 0x00e0 }, + { 0x0013, 0x00e1 }, + { 0x0013, 0x00e2 }, + { 0x0013, 0x00e3 }, + { 0x0013, 0x00e4 }, + { 0x0013, 0x00e5 }, + { 0x0013, 0x00e6 }, + { 0x0013, 0x00e7 }, + { 0x0013, 0x00e8 }, + { 0x0013, 0x00e9 }, + { 0x0013, 0x00ea }, + { 0x0013, 0x00eb }, + { 0x0013, 0x00ec }, + { 0x0013, 0x00ed }, + { 0x0013, 0x00ee }, + { 0x0013, 0x00ef }, + { 0x0013, 0x00f0 }, + { 0x0013, 0x00f1 }, + { 0x0013, 0x00f2 }, + { 0x0013, 0x00f3 }, + { 0x0013, 0x00f4 }, + { 0x0013, 0x00f5 }, + { 0x0013, 0x00f6 }, + { 0x0013, 0x00f7 }, + { 0x0013, 0x00f8 }, + { 0x0013, 0x00f9 }, + { 0x0013, 0x00fa }, + { 0x0013, 0x00fb }, + { 0x0013, 0x00fc }, + { 0x0013, 0x00fd }, + { 0x0013, 0x00fe }, + { 0x0013, 0x00ff }, + { 0x0013, 0x0100 }, + { 0x0013, 0x0101 }, + { 0x0013, 0x0102 }, + { 0x0013, 0x0103 }, + { 0x0013, 0x0104 }, + { 0x0013, 0x0105 }, + { 0x0013, 0x0106 }, + { 0x0013, 0x0107 }, + { 0x0013, 0x0108 }, + { 0x0013, 0x0109 }, + { 0x0013, 0x010a }, + { 0x0013, 0x010b }, + { 0x0013, 0x010c }, + { 0x0013, 0x010d }, + { 0x0013, 0x010e }, + { 0x0013, 0x010f }, + { 0x0013, 0x0110 }, + { 0x0013, 0x0111 }, + { 0x0013, 0x0112 }, + { 0x0013, 0x0113 }, + { 0x0013, 0x0114 }, + { 0x0013, 0x0115 }, + { 0x0013, 0x0116 }, + { 0x0013, 0x0117 }, + { 0x0013, 0x0118 }, + { 0x0013, 0x0119 }, + { 0x0013, 0x011a }, + { 0x0013, 0x011b }, + { 0x0013, 0x011c }, + { 0x0013, 0x011d }, + { 0x0013, 0x011e }, + { 0x0013, 0x011f }, + { 0x0013, 0x0120 }, + { 0x0013, 0x0121 }, + { 0x0013, 0x0122 }, + { 0x0013, 0x0123 }, + { 0x0013, 0x0124 }, + { 0x0013, 0x0125 }, + { 0x0013, 0x0126 }, + { 0x0013, 0x0127 }, + { 0x0013, 0x0128 }, + { 0x0013, 0x0129 }, + { 0x0013, 0x012a }, + { 0x0013, 0x012b }, + { 0x0013, 0x012c }, + { 0x0013, 0x012d }, + { 0x0013, 0x012e }, + { 0x0013, 0x012f }, + { 0x0013, 0x0130 }, + { 0x0013, 0x0131 }, + { 0x0013, 0x0132 }, + { 0x0013, 0x0133 }, + { 0x0013, 0x0134 }, + { 0x0013, 0x0135 }, + { 0x0013, 0x0136 }, + { 0x0013, 0x0137 }, + { 0x0013, 0x0138 }, + { 0x0013, 0x0139 }, + { 0x0013, 0x013a }, + { 0x0013, 0x013b }, + { 0x0013, 0x013c }, + { 0x0013, 0x013d }, + { 0x0013, 0x013e }, + { 0x0013, 0x013f }, + { 0x0013, 0x0140 }, + { 0x0013, 0x0141 }, + { 0x0013, 0x0142 }, + { 0x0013, 0x0143 }, + { 0x0013, 0x0144 }, + { 0x0013, 0x0145 }, + { 0x0013, 0x0146 }, + { 0x0013, 0x0147 }, + { 0x0013, 0x0148 }, + { 0x0013, 0x0149 }, + { 0x0013, 0x014a }, + { 0x0013, 0x014b }, + { 0x0013, 0x014c }, + { 0x0013, 0x014d }, + { 0x0013, 0x014e }, + { 0x0013, 0x014f }, + { 0x0013, 0x0150 }, + { 0x0013, 0x0151 }, + { 0x0013, 0x0152 }, + { 0x0013, 0x0153 }, + { 0x0013, 0x0154 }, + { 0x0013, 0x0155 }, + { 0x0013, 0x0156 }, + { 0x0013, 0x0157 }, + { 0x0013, 0x0158 }, + { 0x0013, 0x0159 }, + { 0x0013, 0x015a }, + { 0x0013, 0x015b }, + { 0x0013, 0x015c }, + { 0x0013, 0x015d }, + { 0x0013, 0x015e }, + { 0x0013, 0x015f }, + { 0x0013, 0x0160 }, + { 0x0013, 0x0161 }, + { 0x0013, 0x0162 }, + { 0x0013, 0x0163 }, + { 0x0013, 0x0164 }, + { 0x0013, 0x0165 }, + { 0x0013, 0x0166 }, + { 0x0013, 0x0167 }, + { 0x0013, 0x0168 }, + { 0x0013, 0x0169 }, + { 0x0013, 0x016a }, + { 0x0013, 0x016b }, + { 0x0013, 0x016c }, + { 0x0013, 0x016d }, + { 0x0013, 0x016e }, + { 0x0013, 0x016f }, + { 0x0013, 0x0170 }, + { 0x0013, 0x0171 }, + { 0x0013, 0x0172 }, + { 0x0013, 0x0173 }, + { 0x0013, 0x0174 }, + { 0x0013, 0x0175 }, + { 0x0013, 0x0176 }, + { 0x0013, 0x0177 }, + { 0x0013, 0x0178 }, + { 0x0013, 0x0179 }, + { 0x0013, 0x017a }, + { 0x0013, 0x017b }, + { 0x0013, 0x017c }, + { 0x0013, 0x017d }, + { 0x0013, 0x017e }, + { 0x0013, 0x017f }, + { 0x0013, 0x0180 }, + { 0x0013, 0x0181 }, + { 0x0013, 0x0182 }, + { 0x0013, 0x0183 }, + { 0x0013, 0x0184 }, + { 0x0013, 0x0185 }, + { 0x0013, 0x0186 }, + { 0x0013, 0x0187 }, + { 0x0013, 0x0188 }, + { 0x0013, 0x0189 }, + { 0x0013, 0x018a }, + { 0x0013, 0x018b }, + { 0x0013, 0x018c }, + { 0x0013, 0x018d }, + { 0x0013, 0x018e }, + { 0x0013, 0x018f }, + { 0x0013, 0x0190 }, + { 0x0013, 0x0191 }, + { 0x0013, 0x0192 }, + { 0x0013, 0x0193 }, + { 0x0013, 0x0194 }, + { 0x0013, 0x0195 }, + { 0x0013, 0x0196 }, + { 0x0013, 0x0197 }, + { 0x0013, 0x0198 }, + { 0x0013, 0x0199 }, + { 0x0013, 0x019a }, + { 0x0013, 0x019b }, + { 0x0013, 0x019c }, + { 0x0013, 0x019d }, + { 0x0013, 0x019e }, + { 0x0013, 0x019f }, + { 0x0013, 0x01a0 }, + { 0x0013, 0x01a1 }, + { 0x0013, 0x01a2 }, + { 0x0013, 0x01a3 }, + { 0x0013, 0x01a4 }, + { 0x0013, 0x01a5 }, + { 0x0013, 0x01a6 }, + { 0x0013, 0x01a7 }, + { 0x0013, 0x01a8 }, + { 0x0013, 0x01a9 }, + { 0x0013, 0x01aa }, + { 0x0013, 0x01ab }, + { 0x0013, 0x01ac }, + { 0x0013, 0x01ad }, + { 0x0013, 0x01ae }, + { 0x0013, 0x01af }, + { 0x0013, 0x01b0 }, + { 0x0013, 0x01b1 }, + { 0x0013, 0x01b2 }, + { 0x0013, 0x01b3 }, + { 0x0013, 0x01b4 }, + { 0x0013, 0x01b5 }, + { 0x0013, 0x01b6 }, + { 0x0013, 0x01b7 }, + { 0x0013, 0x01b8 }, + { 0x0013, 0x01b9 }, + { 0x0013, 0x01ba }, + { 0x0013, 0x01bb }, + { 0x0013, 0x01bc }, + { 0x0013, 0x01bd }, + { 0x0013, 0x01be }, + { 0x0013, 0x01bf }, + { 0x0013, 0x01c0 }, + { 0x0013, 0x01c1 }, + { 0x0013, 0x01c2 }, + { 0x0013, 0x01c3 }, + { 0x0013, 0x01c4 }, + { 0x0013, 0x01c5 }, + { 0x0013, 0x01c6 }, + { 0x0013, 0x01c7 }, + { 0x0013, 0x01c8 }, + { 0x0013, 0x01c9 }, + { 0x0013, 0x01ca }, + { 0x0013, 0x01cb }, + { 0x0013, 0x01cc }, + { 0x0013, 0x01cd }, + { 0x0013, 0x01ce }, + { 0x0013, 0x01cf }, + { 0x0013, 0x01d0 }, + { 0x0013, 0x01d1 }, + { 0x0013, 0x01d2 }, + { 0x0013, 0x01d3 }, + { 0x0013, 0x01d4 }, + { 0x0013, 0x01d5 }, + { 0x0013, 0x01d6 }, + { 0x0013, 0x01d7 }, + { 0x0013, 0x01d8 }, + { 0x0013, 0x01d9 }, + { 0x0013, 0x01da }, + { 0x0013, 0x01db }, + { 0x0013, 0x01dc }, + { 0x0013, 0x01dd }, + { 0x0013, 0x01de }, + { 0x0013, 0x01df }, + { 0x0013, 0x01e0 }, + { 0x0013, 0x01e1 }, + { 0x0013, 0x01e2 }, + { 0x0013, 0x01e3 }, + { 0x0013, 0x01e4 }, + { 0x0013, 0x01e5 }, + { 0x0013, 0x01e6 }, + { 0x0013, 0x01e7 }, + { 0x0013, 0x01e8 }, + { 0x0013, 0x01e9 }, + { 0x0013, 0x01ea }, + { 0x0013, 0x01eb }, + { 0x0013, 0x01ec }, + { 0x0013, 0x01ed }, + { 0x0013, 0x01ee }, + { 0x0013, 0x01ef }, + { 0x0013, 0x01f0 }, + { 0x0013, 0x01f1 }, + { 0x0013, 0x01f2 }, + { 0x0013, 0x01f3 }, + { 0x0013, 0x01f4 }, + { 0x0013, 0x01f5 }, + { 0x0013, 0x01f6 }, + { 0x0013, 0x01f7 }, + { 0x0013, 0x01f8 }, + { 0x0013, 0x01f9 }, + { 0x0013, 0x01fa }, + { 0x0013, 0x01fb }, + { 0x0013, 0x01fc }, + { 0x0013, 0x01fd }, + { 0x0013, 0x01fe }, + { 0x0013, 0x01ff }, + { 0x0013, 0x0200 }, + { 0x0013, 0x0201 }, + { 0x0013, 0x0202 }, + { 0x0013, 0x0203 }, + { 0x0013, 0x0204 }, + { 0x0013, 0x0205 }, + { 0x0013, 0x0206 }, + { 0x0013, 0x0207 }, + { 0x0013, 0x0208 }, + { 0x0013, 0x0209 }, + { 0x0013, 0x020a }, + { 0x0013, 0x020b }, + { 0x0013, 0x020c }, + { 0x0013, 0x020d }, + { 0x0013, 0x020e }, + { 0x0013, 0x020f }, + { 0x0013, 0x0210 }, + { 0x0013, 0x0211 }, + { 0x0013, 0x0212 }, + { 0x0013, 0x0213 }, + { 0x0013, 0x0214 }, + { 0x0013, 0x0215 }, + { 0x0013, 0x0216 }, + { 0x0013, 0x0217 }, + { 0x0013, 0x0218 }, + { 0x0013, 0x0219 }, + { 0x0013, 0x021a }, + { 0x0013, 0x021b }, + { 0x0013, 0x021c }, + { 0x0013, 0x021d }, + { 0x0013, 0x021e }, + { 0x0013, 0x021f }, + { 0x0013, 0x0220 }, + { 0x0013, 0x0221 }, + { 0x0013, 0x0222 }, + { 0x0013, 0x0223 }, + { 0x0013, 0x0224 }, + { 0x0013, 0x0225 }, + { 0x0013, 0x0226 }, + { 0x0013, 0x0227 }, + { 0x0013, 0x0228 }, + { 0x0013, 0x0229 }, + { 0x0013, 0x022a }, + { 0x0013, 0x022b }, + { 0x0013, 0x022c }, + { 0x0013, 0x022d }, + { 0x0013, 0x022e }, + { 0x0013, 0x022f }, + { 0x0013, 0x0230 }, + { 0x0013, 0x0231 }, + { 0x0013, 0x0232 }, + { 0x0013, 0x0233 }, + { 0x0013, 0x0234 }, + { 0x0013, 0x0235 }, + { 0x0013, 0x0236 }, + { 0x0013, 0x0237 }, + { 0x0013, 0x0238 }, + { 0x0013, 0x0239 }, + { 0x0013, 0x023a }, + { 0x0013, 0x023b }, + { 0x0013, 0x023c }, + { 0x0013, 0x023d }, + { 0x0013, 0x023e }, + { 0x0013, 0x023f }, + { 0x0013, 0x0240 }, + { 0x0013, 0x0241 }, + { 0x0013, 0x0242 }, + { 0x0013, 0x0243 }, + { 0x0013, 0x0244 }, + { 0x0013, 0x0245 }, + { 0x0013, 0x0246 }, + { 0x0013, 0x0247 }, + { 0x0013, 0x0248 }, + { 0x0013, 0x0249 }, + { 0x0013, 0x024a }, + { 0x0013, 0x024b }, + { 0x0013, 0x024c }, + { 0x0013, 0x024d }, + { 0x0013, 0x024e }, + { 0x0013, 0x024f }, + { 0x0013, 0x0250 }, + { 0x0013, 0x0251 }, + { 0x0013, 0x0252 }, + { 0x0013, 0x0253 }, + { 0x0013, 0x0254 }, + { 0x0013, 0x0255 }, + { 0x0013, 0x0256 }, + { 0x0013, 0x0257 }, + { 0x0013, 0x0258 }, + { 0x0013, 0x0259 }, + { 0x0013, 0x025a }, + { 0x0013, 0x025b }, + { 0x0013, 0x025c }, + { 0x0013, 0x025d }, + { 0x0013, 0x025e }, + { 0x0013, 0x025f }, + { 0x0013, 0x0260 }, + { 0x0013, 0x0261 }, + { 0x0013, 0x0262 }, + { 0x0013, 0x0263 }, + { 0x0013, 0x0264 }, + { 0x0013, 0x0265 }, + { 0x0013, 0x0266 }, + { 0x0013, 0x0267 }, + { 0x0013, 0x0268 }, + { 0x0013, 0x0269 }, + { 0x0013, 0x026a }, + { 0x0013, 0x026b }, + { 0x0012, 0x013f }, + + }; + +const uint16_t c_aauiLCLDHuffEnc49[729][2] = + { + { 0x0002, 0x0003 }, + { 0x0003, 0x0003 }, + { 0x0005, 0x0007 }, + { 0x0007, 0x000a }, + { 0x0008, 0x0009 }, + { 0x0008, 0x000a }, + { 0x0009, 0x0009 }, + { 0x000b, 0x000d }, + { 0x000d, 0x0014 }, + { 0x000d, 0x0015 }, + { 0x0010, 0x0052 }, + { 0x0011, 0x0098 }, + { 0x0013, 0x0000 }, + { 0x0013, 0x0001 }, + { 0x0013, 0x0002 }, + { 0x0013, 0x0003 }, + { 0x0013, 0x0004 }, + { 0x0013, 0x0005 }, + { 0x0013, 0x0006 }, + { 0x0013, 0x0007 }, + { 0x0013, 0x0008 }, + { 0x0013, 0x0009 }, + { 0x0013, 0x000a }, + { 0x0013, 0x000b }, + { 0x0013, 0x000c }, + { 0x0013, 0x000d }, + { 0x0013, 0x000e }, + { 0x0003, 0x0004 }, + { 0x0003, 0x0005 }, + { 0x0005, 0x0008 }, + { 0x0006, 0x000a }, + { 0x0007, 0x000b }, + { 0x0008, 0x000b }, + { 0x0008, 0x000c }, + { 0x000a, 0x000a }, + { 0x000b, 0x000e }, + { 0x000d, 0x0016 }, + { 0x000f, 0x0031 }, + { 0x0010, 0x0053 }, + { 0x0012, 0x012a }, + { 0x0013, 0x000f }, + { 0x0013, 0x0010 }, + { 0x0013, 0x0011 }, + { 0x0013, 0x0012 }, + { 0x0013, 0x0013 }, + { 0x0013, 0x0014 }, + { 0x0013, 0x0015 }, + { 0x0013, 0x0016 }, + { 0x0013, 0x0017 }, + { 0x0013, 0x0018 }, + { 0x0013, 0x0019 }, + { 0x0013, 0x001a }, + { 0x0013, 0x001b }, + { 0x0013, 0x001c }, + { 0x0005, 0x0009 }, + { 0x0005, 0x000a }, + { 0x0005, 0x000b }, + { 0x0006, 0x000b }, + { 0x0007, 0x000c }, + { 0x0008, 0x000d }, + { 0x0009, 0x000a }, + { 0x000a, 0x000b }, + { 0x000c, 0x000f }, + { 0x000d, 0x0017 }, + { 0x000f, 0x0032 }, + { 0x0010, 0x0054 }, + { 0x0013, 0x001d }, + { 0x0013, 0x001e }, + { 0x0013, 0x001f }, + { 0x0013, 0x0020 }, + { 0x0013, 0x0021 }, + { 0x0013, 0x0022 }, + { 0x0013, 0x0023 }, + { 0x0013, 0x0024 }, + { 0x0013, 0x0025 }, + { 0x0013, 0x0026 }, + { 0x0013, 0x0027 }, + { 0x0013, 0x0028 }, + { 0x0013, 0x0029 }, + { 0x0013, 0x002a }, + { 0x0013, 0x002b }, + { 0x0007, 0x000d }, + { 0x0006, 0x000c }, + { 0x0006, 0x000d }, + { 0x0007, 0x000e }, + { 0x0007, 0x000f }, + { 0x0008, 0x000e }, + { 0x0009, 0x000b }, + { 0x000b, 0x000f }, + { 0x000c, 0x0010 }, + { 0x000e, 0x001d }, + { 0x000f, 0x0033 }, + { 0x0011, 0x0099 }, + { 0x0013, 0x002c }, + { 0x0013, 0x002d }, + { 0x0013, 0x002e }, + { 0x0013, 0x002f }, + { 0x0013, 0x0030 }, + { 0x0013, 0x0031 }, + { 0x0013, 0x0032 }, + { 0x0013, 0x0033 }, + { 0x0013, 0x0034 }, + { 0x0013, 0x0035 }, + { 0x0013, 0x0036 }, + { 0x0013, 0x0037 }, + { 0x0013, 0x0038 }, + { 0x0013, 0x0039 }, + { 0x0013, 0x003a }, + { 0x0008, 0x000f }, + { 0x0007, 0x0010 }, + { 0x0007, 0x0011 }, + { 0x0007, 0x0012 }, + { 0x0008, 0x0010 }, + { 0x0009, 0x000c }, + { 0x000a, 0x000c }, + { 0x000c, 0x0011 }, + { 0x000d, 0x0018 }, + { 0x000e, 0x001e }, + { 0x0011, 0x009a }, + { 0x0011, 0x009b }, + { 0x0013, 0x003b }, + { 0x0013, 0x003c }, + { 0x0013, 0x003d }, + { 0x0013, 0x003e }, + { 0x0013, 0x003f }, + { 0x0013, 0x0040 }, + { 0x0013, 0x0041 }, + { 0x0013, 0x0042 }, + { 0x0013, 0x0043 }, + { 0x0013, 0x0044 }, + { 0x0013, 0x0045 }, + { 0x0013, 0x0046 }, + { 0x0013, 0x0047 }, + { 0x0013, 0x0048 }, + { 0x0013, 0x0049 }, + { 0x0008, 0x0011 }, + { 0x0007, 0x0013 }, + { 0x0008, 0x0012 }, + { 0x0008, 0x0013 }, + { 0x0009, 0x000d }, + { 0x000a, 0x000d }, + { 0x000b, 0x0010 }, + { 0x000c, 0x0012 }, + { 0x000e, 0x001f }, + { 0x000e, 0x0020 }, + { 0x0010, 0x0055 }, + { 0x0011, 0x009c }, + { 0x0013, 0x004a }, + { 0x0013, 0x004b }, + { 0x0013, 0x004c }, + { 0x0013, 0x004d }, + { 0x0013, 0x004e }, + { 0x0013, 0x004f }, + { 0x0013, 0x0050 }, + { 0x0013, 0x0051 }, + { 0x0013, 0x0052 }, + { 0x0013, 0x0053 }, + { 0x0013, 0x0054 }, + { 0x0013, 0x0055 }, + { 0x0013, 0x0056 }, + { 0x0013, 0x0057 }, + { 0x0013, 0x0058 }, + { 0x0009, 0x000e }, + { 0x0009, 0x000f }, + { 0x0009, 0x0010 }, + { 0x0009, 0x0011 }, + { 0x000a, 0x000e }, + { 0x000b, 0x0011 }, + { 0x000c, 0x0013 }, + { 0x000d, 0x0019 }, + { 0x000e, 0x0021 }, + { 0x0010, 0x0056 }, + { 0x0010, 0x0057 }, + { 0x0013, 0x0059 }, + { 0x0013, 0x005a }, + { 0x0013, 0x005b }, + { 0x0013, 0x005c }, + { 0x0013, 0x005d }, + { 0x0013, 0x005e }, + { 0x0013, 0x005f }, + { 0x0013, 0x0060 }, + { 0x0013, 0x0061 }, + { 0x0013, 0x0062 }, + { 0x0013, 0x0063 }, + { 0x0013, 0x0064 }, + { 0x0013, 0x0065 }, + { 0x0013, 0x0066 }, + { 0x0013, 0x0067 }, + { 0x0013, 0x0068 }, + { 0x000b, 0x0012 }, + { 0x000a, 0x000f }, + { 0x000a, 0x0010 }, + { 0x000a, 0x0011 }, + { 0x000c, 0x0014 }, + { 0x000c, 0x0015 }, + { 0x000d, 0x001a }, + { 0x000e, 0x0022 }, + { 0x0010, 0x0058 }, + { 0x0010, 0x0059 }, + { 0x0013, 0x0069 }, + { 0x0013, 0x006a }, + { 0x0013, 0x006b }, + { 0x0013, 0x006c }, + { 0x0013, 0x006d }, + { 0x0013, 0x006e }, + { 0x0013, 0x006f }, + { 0x0013, 0x0070 }, + { 0x0013, 0x0071 }, + { 0x0013, 0x0072 }, + { 0x0013, 0x0073 }, + { 0x0013, 0x0074 }, + { 0x0013, 0x0075 }, + { 0x0013, 0x0076 }, + { 0x0013, 0x0077 }, + { 0x0013, 0x0078 }, + { 0x0013, 0x0079 }, + { 0x000c, 0x0016 }, + { 0x000b, 0x0013 }, + { 0x000c, 0x0017 }, + { 0x000c, 0x0018 }, + { 0x000c, 0x0019 }, + { 0x000e, 0x0023 }, + { 0x000e, 0x0024 }, + { 0x000f, 0x0034 }, + { 0x0010, 0x005a }, + { 0x0011, 0x009d }, + { 0x0013, 0x007a }, + { 0x0013, 0x007b }, + { 0x0013, 0x007c }, + { 0x0013, 0x007d }, + { 0x0013, 0x007e }, + { 0x0013, 0x007f }, + { 0x0013, 0x0080 }, + { 0x0013, 0x0081 }, + { 0x0013, 0x0082 }, + { 0x0013, 0x0083 }, + { 0x0013, 0x0084 }, + { 0x0013, 0x0085 }, + { 0x0013, 0x0086 }, + { 0x0013, 0x0087 }, + { 0x0013, 0x0088 }, + { 0x0013, 0x0089 }, + { 0x0013, 0x008a }, + { 0x000e, 0x0025 }, + { 0x000d, 0x001b }, + { 0x000d, 0x001c }, + { 0x000d, 0x001d }, + { 0x000e, 0x0026 }, + { 0x000f, 0x0035 }, + { 0x0010, 0x005b }, + { 0x0011, 0x009e }, + { 0x0011, 0x009f }, + { 0x0012, 0x012b }, + { 0x0013, 0x008b }, + { 0x0013, 0x008c }, + { 0x0013, 0x008d }, + { 0x0013, 0x008e }, + { 0x0013, 0x008f }, + { 0x0013, 0x0090 }, + { 0x0013, 0x0091 }, + { 0x0013, 0x0092 }, + { 0x0013, 0x0093 }, + { 0x0013, 0x0094 }, + { 0x0013, 0x0095 }, + { 0x0013, 0x0096 }, + { 0x0013, 0x0097 }, + { 0x0013, 0x0098 }, + { 0x0013, 0x0099 }, + { 0x0013, 0x009a }, + { 0x0013, 0x009b }, + { 0x0010, 0x005c }, + { 0x000f, 0x0036 }, + { 0x000e, 0x0027 }, + { 0x000f, 0x0037 }, + { 0x000f, 0x0038 }, + { 0x0010, 0x005d }, + { 0x0011, 0x00a0 }, + { 0x0013, 0x009c }, + { 0x0012, 0x012c }, + { 0x0013, 0x009d }, + { 0x0013, 0x009e }, + { 0x0013, 0x009f }, + { 0x0013, 0x00a0 }, + { 0x0013, 0x00a1 }, + { 0x0013, 0x00a2 }, + { 0x0013, 0x00a3 }, + { 0x0013, 0x00a4 }, + { 0x0013, 0x00a5 }, + { 0x0013, 0x00a6 }, + { 0x0013, 0x00a7 }, + { 0x0013, 0x00a8 }, + { 0x0013, 0x00a9 }, + { 0x0013, 0x00aa }, + { 0x0013, 0x00ab }, + { 0x0013, 0x00ac }, + { 0x0013, 0x00ad }, + { 0x0013, 0x00ae }, + { 0x0010, 0x005e }, + { 0x000f, 0x0039 }, + { 0x0010, 0x005f }, + { 0x0010, 0x0060 }, + { 0x0011, 0x00a1 }, + { 0x0010, 0x0061 }, + { 0x0013, 0x00af }, + { 0x0013, 0x00b0 }, + { 0x0012, 0x012d }, + { 0x0013, 0x00b1 }, + { 0x0013, 0x00b2 }, + { 0x0013, 0x00b3 }, + { 0x0013, 0x00b4 }, + { 0x0013, 0x00b5 }, + { 0x0013, 0x00b6 }, + { 0x0013, 0x00b7 }, + { 0x0013, 0x00b8 }, + { 0x0013, 0x00b9 }, + { 0x0013, 0x00ba }, + { 0x0013, 0x00bb }, + { 0x0013, 0x00bc }, + { 0x0013, 0x00bd }, + { 0x0013, 0x00be }, + { 0x0013, 0x00bf }, + { 0x0013, 0x00c0 }, + { 0x0013, 0x00c1 }, + { 0x0013, 0x00c2 }, + { 0x0012, 0x012e }, + { 0x0011, 0x00a2 }, + { 0x0011, 0x00a3 }, + { 0x0013, 0x00c3 }, + { 0x0013, 0x00c4 }, + { 0x0013, 0x00c5 }, + { 0x0013, 0x00c6 }, + { 0x0013, 0x00c7 }, + { 0x0013, 0x00c8 }, + { 0x0013, 0x00c9 }, + { 0x0013, 0x00ca }, + { 0x0013, 0x00cb }, + { 0x0013, 0x00cc }, + { 0x0013, 0x00cd }, + { 0x0013, 0x00ce }, + { 0x0013, 0x00cf }, + { 0x0013, 0x00d0 }, + { 0x0013, 0x00d1 }, + { 0x0013, 0x00d2 }, + { 0x0013, 0x00d3 }, + { 0x0013, 0x00d4 }, + { 0x0013, 0x00d5 }, + { 0x0013, 0x00d6 }, + { 0x0013, 0x00d7 }, + { 0x0013, 0x00d8 }, + { 0x0013, 0x00d9 }, + { 0x0013, 0x00da }, + { 0x0013, 0x00db }, + { 0x0013, 0x00dc }, + { 0x0013, 0x00dd }, + { 0x0013, 0x00de }, + { 0x0013, 0x00df }, + { 0x0012, 0x012f }, + { 0x0013, 0x00e0 }, + { 0x0013, 0x00e1 }, + { 0x0013, 0x00e2 }, + { 0x0013, 0x00e3 }, + { 0x0013, 0x00e4 }, + { 0x0013, 0x00e5 }, + { 0x0013, 0x00e6 }, + { 0x0013, 0x00e7 }, + { 0x0013, 0x00e8 }, + { 0x0013, 0x00e9 }, + { 0x0013, 0x00ea }, + { 0x0013, 0x00eb }, + { 0x0013, 0x00ec }, + { 0x0013, 0x00ed }, + { 0x0013, 0x00ee }, + { 0x0013, 0x00ef }, + { 0x0013, 0x00f0 }, + { 0x0013, 0x00f1 }, + { 0x0013, 0x00f2 }, + { 0x0013, 0x00f3 }, + { 0x0013, 0x00f4 }, + { 0x0013, 0x00f5 }, + { 0x0013, 0x00f6 }, + { 0x0013, 0x00f7 }, + { 0x0013, 0x00f8 }, + { 0x0013, 0x00f9 }, + { 0x0013, 0x00fa }, + { 0x0013, 0x00fb }, + { 0x0013, 0x00fc }, + { 0x0013, 0x00fd }, + { 0x0013, 0x00fe }, + { 0x0013, 0x00ff }, + { 0x0013, 0x0100 }, + { 0x0013, 0x0101 }, + { 0x0013, 0x0102 }, + { 0x0013, 0x0103 }, + { 0x0013, 0x0104 }, + { 0x0013, 0x0105 }, + { 0x0013, 0x0106 }, + { 0x0013, 0x0107 }, + { 0x0013, 0x0108 }, + { 0x0013, 0x0109 }, + { 0x0013, 0x010a }, + { 0x0013, 0x010b }, + { 0x0013, 0x010c }, + { 0x0013, 0x010d }, + { 0x0013, 0x010e }, + { 0x0013, 0x010f }, + { 0x0013, 0x0110 }, + { 0x0013, 0x0111 }, + { 0x0013, 0x0112 }, + { 0x0013, 0x0113 }, + { 0x0013, 0x0114 }, + { 0x0013, 0x0115 }, + { 0x0013, 0x0116 }, + { 0x0013, 0x0117 }, + { 0x0013, 0x0118 }, + { 0x0013, 0x0119 }, + { 0x0013, 0x011a }, + { 0x0013, 0x011b }, + { 0x0013, 0x011c }, + { 0x0013, 0x011d }, + { 0x0013, 0x011e }, + { 0x0013, 0x011f }, + { 0x0013, 0x0120 }, + { 0x0013, 0x0121 }, + { 0x0013, 0x0122 }, + { 0x0013, 0x0123 }, + { 0x0013, 0x0124 }, + { 0x0013, 0x0125 }, + { 0x0013, 0x0126 }, + { 0x0013, 0x0127 }, + { 0x0013, 0x0128 }, + { 0x0013, 0x0129 }, + { 0x0013, 0x012a }, + { 0x0013, 0x012b }, + { 0x0013, 0x012c }, + { 0x0013, 0x012d }, + { 0x0013, 0x012e }, + { 0x0013, 0x012f }, + { 0x0013, 0x0130 }, + { 0x0013, 0x0131 }, + { 0x0013, 0x0132 }, + { 0x0013, 0x0133 }, + { 0x0013, 0x0134 }, + { 0x0013, 0x0135 }, + { 0x0013, 0x0136 }, + { 0x0013, 0x0137 }, + { 0x0013, 0x0138 }, + { 0x0013, 0x0139 }, + { 0x0013, 0x013a }, + { 0x0013, 0x013b }, + { 0x0013, 0x013c }, + { 0x0013, 0x013d }, + { 0x0013, 0x013e }, + { 0x0013, 0x013f }, + { 0x0013, 0x0140 }, + { 0x0013, 0x0141 }, + { 0x0013, 0x0142 }, + { 0x0013, 0x0143 }, + { 0x0013, 0x0144 }, + { 0x0013, 0x0145 }, + { 0x0013, 0x0146 }, + { 0x0013, 0x0147 }, + { 0x0013, 0x0148 }, + { 0x0013, 0x0149 }, + { 0x0013, 0x014a }, + { 0x0013, 0x014b }, + { 0x0013, 0x014c }, + { 0x0013, 0x014d }, + { 0x0013, 0x014e }, + { 0x0013, 0x014f }, + { 0x0013, 0x0150 }, + { 0x0013, 0x0151 }, + { 0x0013, 0x0152 }, + { 0x0013, 0x0153 }, + { 0x0013, 0x0154 }, + { 0x0013, 0x0155 }, + { 0x0013, 0x0156 }, + { 0x0013, 0x0157 }, + { 0x0013, 0x0158 }, + { 0x0013, 0x0159 }, + { 0x0013, 0x015a }, + { 0x0013, 0x015b }, + { 0x0013, 0x015c }, + { 0x0013, 0x015d }, + { 0x0013, 0x015e }, + { 0x0013, 0x015f }, + { 0x0013, 0x0160 }, + { 0x0013, 0x0161 }, + { 0x0013, 0x0162 }, + { 0x0013, 0x0163 }, + { 0x0013, 0x0164 }, + { 0x0013, 0x0165 }, + { 0x0013, 0x0166 }, + { 0x0013, 0x0167 }, + { 0x0013, 0x0168 }, + { 0x0013, 0x0169 }, + { 0x0013, 0x016a }, + { 0x0013, 0x016b }, + { 0x0013, 0x016c }, + { 0x0013, 0x016d }, + { 0x0013, 0x016e }, + { 0x0013, 0x016f }, + { 0x0013, 0x0170 }, + { 0x0013, 0x0171 }, + { 0x0013, 0x0172 }, + { 0x0013, 0x0173 }, + { 0x0013, 0x0174 }, + { 0x0013, 0x0175 }, + { 0x0013, 0x0176 }, + { 0x0013, 0x0177 }, + { 0x0013, 0x0178 }, + { 0x0013, 0x0179 }, + { 0x0013, 0x017a }, + { 0x0013, 0x017b }, + { 0x0013, 0x017c }, + { 0x0013, 0x017d }, + { 0x0013, 0x017e }, + { 0x0013, 0x017f }, + { 0x0013, 0x0180 }, + { 0x0013, 0x0181 }, + { 0x0013, 0x0182 }, + { 0x0013, 0x0183 }, + { 0x0013, 0x0184 }, + { 0x0013, 0x0185 }, + { 0x0013, 0x0186 }, + { 0x0013, 0x0187 }, + { 0x0013, 0x0188 }, + { 0x0013, 0x0189 }, + { 0x0013, 0x018a }, + { 0x0013, 0x018b }, + { 0x0013, 0x018c }, + { 0x0013, 0x018d }, + { 0x0013, 0x018e }, + { 0x0013, 0x018f }, + { 0x0013, 0x0190 }, + { 0x0013, 0x0191 }, + { 0x0013, 0x0192 }, + { 0x0013, 0x0193 }, + { 0x0013, 0x0194 }, + { 0x0013, 0x0195 }, + { 0x0013, 0x0196 }, + { 0x0013, 0x0197 }, + { 0x0013, 0x0198 }, + { 0x0013, 0x0199 }, + { 0x0013, 0x019a }, + { 0x0013, 0x019b }, + { 0x0013, 0x019c }, + { 0x0013, 0x019d }, + { 0x0013, 0x019e }, + { 0x0013, 0x019f }, + { 0x0013, 0x01a0 }, + { 0x0013, 0x01a1 }, + { 0x0013, 0x01a2 }, + { 0x0013, 0x01a3 }, + { 0x0013, 0x01a4 }, + { 0x0013, 0x01a5 }, + { 0x0013, 0x01a6 }, + { 0x0013, 0x01a7 }, + { 0x0013, 0x01a8 }, + { 0x0013, 0x01a9 }, + { 0x0013, 0x01aa }, + { 0x0013, 0x01ab }, + { 0x0013, 0x01ac }, + { 0x0013, 0x01ad }, + { 0x0013, 0x01ae }, + { 0x0013, 0x01af }, + { 0x0013, 0x01b0 }, + { 0x0013, 0x01b1 }, + { 0x0013, 0x01b2 }, + { 0x0013, 0x01b3 }, + { 0x0013, 0x01b4 }, + { 0x0013, 0x01b5 }, + { 0x0013, 0x01b6 }, + { 0x0013, 0x01b7 }, + { 0x0013, 0x01b8 }, + { 0x0013, 0x01b9 }, + { 0x0013, 0x01ba }, + { 0x0013, 0x01bb }, + { 0x0013, 0x01bc }, + { 0x0013, 0x01bd }, + { 0x0013, 0x01be }, + { 0x0013, 0x01bf }, + { 0x0013, 0x01c0 }, + { 0x0013, 0x01c1 }, + { 0x0013, 0x01c2 }, + { 0x0013, 0x01c3 }, + { 0x0013, 0x01c4 }, + { 0x0013, 0x01c5 }, + { 0x0013, 0x01c6 }, + { 0x0013, 0x01c7 }, + { 0x0013, 0x01c8 }, + { 0x0013, 0x01c9 }, + { 0x0013, 0x01ca }, + { 0x0013, 0x01cb }, + { 0x0013, 0x01cc }, + { 0x0013, 0x01cd }, + { 0x0013, 0x01ce }, + { 0x0013, 0x01cf }, + { 0x0013, 0x01d0 }, + { 0x0013, 0x01d1 }, + { 0x0013, 0x01d2 }, + { 0x0013, 0x01d3 }, + { 0x0013, 0x01d4 }, + { 0x0013, 0x01d5 }, + { 0x0013, 0x01d6 }, + { 0x0013, 0x01d7 }, + { 0x0013, 0x01d8 }, + { 0x0013, 0x01d9 }, + { 0x0013, 0x01da }, + { 0x0013, 0x01db }, + { 0x0013, 0x01dc }, + { 0x0013, 0x01dd }, + { 0x0013, 0x01de }, + { 0x0013, 0x01df }, + { 0x0013, 0x01e0 }, + { 0x0013, 0x01e1 }, + { 0x0013, 0x01e2 }, + { 0x0013, 0x01e3 }, + { 0x0013, 0x01e4 }, + { 0x0013, 0x01e5 }, + { 0x0013, 0x01e6 }, + { 0x0013, 0x01e7 }, + { 0x0013, 0x01e8 }, + { 0x0013, 0x01e9 }, + { 0x0013, 0x01ea }, + { 0x0013, 0x01eb }, + { 0x0013, 0x01ec }, + { 0x0013, 0x01ed }, + { 0x0013, 0x01ee }, + { 0x0013, 0x01ef }, + { 0x0013, 0x01f0 }, + { 0x0013, 0x01f1 }, + { 0x0013, 0x01f2 }, + { 0x0013, 0x01f3 }, + { 0x0013, 0x01f4 }, + { 0x0013, 0x01f5 }, + { 0x0013, 0x01f6 }, + { 0x0013, 0x01f7 }, + { 0x0013, 0x01f8 }, + { 0x0013, 0x01f9 }, + { 0x0013, 0x01fa }, + { 0x0013, 0x01fb }, + { 0x0013, 0x01fc }, + { 0x0013, 0x01fd }, + { 0x0013, 0x01fe }, + { 0x0013, 0x01ff }, + { 0x0013, 0x0200 }, + { 0x0013, 0x0201 }, + { 0x0013, 0x0202 }, + { 0x0013, 0x0203 }, + { 0x0013, 0x0204 }, + { 0x0013, 0x0205 }, + { 0x0013, 0x0206 }, + { 0x0013, 0x0207 }, + { 0x0013, 0x0208 }, + { 0x0013, 0x0209 }, + { 0x0013, 0x020a }, + { 0x0013, 0x020b }, + { 0x0013, 0x020c }, + { 0x0013, 0x020d }, + { 0x0013, 0x020e }, + { 0x0013, 0x020f }, + { 0x0013, 0x0210 }, + { 0x0013, 0x0211 }, + { 0x0013, 0x0212 }, + { 0x0013, 0x0213 }, + { 0x0013, 0x0214 }, + { 0x0013, 0x0215 }, + { 0x0013, 0x0216 }, + { 0x0013, 0x0217 }, + { 0x0013, 0x0218 }, + { 0x0013, 0x0219 }, + { 0x0013, 0x021a }, + { 0x0013, 0x021b }, + { 0x0013, 0x021c }, + { 0x0013, 0x021d }, + { 0x0013, 0x021e }, + { 0x0013, 0x021f }, + { 0x0013, 0x0220 }, + { 0x0013, 0x0221 }, + { 0x0013, 0x0222 }, + { 0x0013, 0x0223 }, + { 0x0013, 0x0224 }, + { 0x0013, 0x0225 }, + { 0x0013, 0x0226 }, + { 0x0013, 0x0227 }, + { 0x0013, 0x0228 }, + { 0x0013, 0x0229 }, + { 0x0013, 0x022a }, + { 0x0013, 0x022b }, + { 0x0013, 0x022c }, + { 0x0013, 0x022d }, + { 0x0013, 0x022e }, + { 0x0013, 0x022f }, + { 0x0013, 0x0230 }, + { 0x0013, 0x0231 }, + { 0x0013, 0x0232 }, + { 0x0013, 0x0233 }, + { 0x0013, 0x0234 }, + { 0x0013, 0x0235 }, + { 0x0013, 0x0236 }, + { 0x0013, 0x0237 }, + { 0x0013, 0x0238 }, + { 0x0013, 0x0239 }, + { 0x0013, 0x023a }, + { 0x0013, 0x023b }, + { 0x0013, 0x023c }, + { 0x0013, 0x023d }, + { 0x0013, 0x023e }, + { 0x0013, 0x023f }, + { 0x0013, 0x0240 }, + { 0x0013, 0x0241 }, + { 0x0013, 0x0242 }, + { 0x0013, 0x0243 }, + { 0x0013, 0x0244 }, + { 0x0013, 0x0245 }, + { 0x0013, 0x0246 }, + { 0x0013, 0x0247 }, + { 0x0013, 0x0248 }, + { 0x0013, 0x0249 }, + { 0x0013, 0x024a }, + { 0x0013, 0x024b }, + { 0x0013, 0x024c }, + { 0x0013, 0x024d }, + { 0x0013, 0x024e }, + { 0x0013, 0x024f }, + { 0x0013, 0x0250 }, + { 0x0013, 0x0251 }, + { 0x0013, 0x0252 }, + { 0x0013, 0x0253 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc50[28][2] = + { + { 0x0002, 0x0001 }, + { 0x0002, 0x0002 }, + { 0x0002, 0x0003 }, + { 0x0003, 0x0001 }, + { 0x0004, 0x0001 }, + { 0x0005, 0x0001 }, + { 0x0006, 0x0001 }, + { 0x0007, 0x0001 }, + { 0x0008, 0x0001 }, + { 0x0009, 0x0001 }, + { 0x000a, 0x0001 }, + { 0x000b, 0x0001 }, + { 0x000c, 0x0001 }, + { 0x000d, 0x0001 }, + { 0x000e, 0x0001 }, + { 0x000f, 0x0001 }, + { 0x0011, 0x0003 }, + { 0x0012, 0x0005 }, + { 0x0013, 0x0000 }, + { 0x0013, 0x0001 }, + { 0x0013, 0x0002 }, + { 0x0013, 0x0003 }, + { 0x0013, 0x0004 }, + { 0x0013, 0x0005 }, + { 0x0013, 0x0006 }, + { 0x0013, 0x0007 }, + { 0x0013, 0x0008 }, + { 0x0013, 0x0009 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc51[29][2] = + { + { 0x0002, 0x0002 }, + { 0x0002, 0x0003 }, + { 0x0003, 0x0002 }, + { 0x0003, 0x0003 }, + { 0x0004, 0x0001 }, + { 0x0004, 0x0002 }, + { 0x0004, 0x0003 }, + { 0x0005, 0x0001 }, + { 0x0006, 0x0001 }, + { 0x0007, 0x0001 }, + { 0x0008, 0x0001 }, + { 0x0009, 0x0001 }, + { 0x000a, 0x0001 }, + { 0x000b, 0x0001 }, + { 0x000c, 0x0001 }, + { 0x000d, 0x0001 }, + { 0x000e, 0x0001 }, + { 0x0010, 0x0002 }, + { 0x0010, 0x0003 }, + { 0x0012, 0x0002 }, + { 0x0012, 0x0003 }, + { 0x0013, 0x0000 }, + { 0x0013, 0x0001 }, + { 0x0013, 0x0002 }, + { 0x0013, 0x0003 }, + { 0x0012, 0x0004 }, + { 0x0012, 0x0005 }, + { 0x0012, 0x0006 }, + { 0x0012, 0x0007 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc52[32][2] = + { + { 0x0002, 0x0002 }, + { 0x0002, 0x0003 }, + { 0x0003, 0x0002 }, + { 0x0003, 0x0003 }, + { 0x0004, 0x0002 }, + { 0x0004, 0x0003 }, + { 0x0005, 0x0001 }, + { 0x0005, 0x0002 }, + { 0x0005, 0x0003 }, + { 0x0006, 0x0001 }, + { 0x0007, 0x0001 }, + { 0x0008, 0x0001 }, + { 0x0009, 0x0001 }, + { 0x000a, 0x0001 }, + { 0x000b, 0x0001 }, + { 0x000c, 0x0001 }, + { 0x000e, 0x0001 }, + { 0x000e, 0x0002 }, + { 0x000e, 0x0003 }, + { 0x000f, 0x0001 }, + { 0x0011, 0x0002 }, + { 0x0011, 0x0003 }, + { 0x0012, 0x0003 }, + { 0x0014, 0x0000 }, + { 0x0013, 0x0003 }, + { 0x0014, 0x0001 }, + { 0x0014, 0x0002 }, + { 0x0014, 0x0003 }, + { 0x0014, 0x0004 }, + { 0x0014, 0x0005 }, + { 0x0013, 0x0004 }, + { 0x0013, 0x0005 }, + }; + +const uint16_t c_aauiLCLDHuffEnc53[37][2] = + { + { 0x0002, 0x0002 }, + { 0x0002, 0x0003 }, + { 0x0003, 0x0002 }, + { 0x0003, 0x0003 }, + { 0x0004, 0x0002 }, + { 0x0004, 0x0003 }, + { 0x0005, 0x0002 }, + { 0x0005, 0x0003 }, + { 0x0006, 0x0002 }, + { 0x0006, 0x0003 }, + { 0x0007, 0x0001 }, + { 0x0007, 0x0002 }, + { 0x0007, 0x0003 }, + { 0x0008, 0x0001 }, + { 0x0009, 0x0001 }, + { 0x000b, 0x0002 }, + { 0x000b, 0x0003 }, + { 0x000c, 0x0002 }, + { 0x000c, 0x0003 }, + { 0x000d, 0x0002 }, + { 0x000d, 0x0003 }, + { 0x000e, 0x0002 }, + { 0x000e, 0x0003 }, + { 0x000f, 0x0002 }, + { 0x000f, 0x0003 }, + { 0x0011, 0x0004 }, + { 0x0010, 0x0003 }, + { 0x0011, 0x0005 }, + { 0x0013, 0x0000 }, + { 0x0013, 0x0001 }, + { 0x0012, 0x0001 }, + { 0x0012, 0x0002 }, + { 0x0012, 0x0003 }, + { 0x0012, 0x0004 }, + { 0x0012, 0x0005 }, + { 0x0012, 0x0006 }, + { 0x0012, 0x0007 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc54[39][2] = + { + { 0x0002, 0x0002 }, + { 0x0002, 0x0003 }, + { 0x0003, 0x0002 }, + { 0x0003, 0x0003 }, + { 0x0004, 0x0003 }, + { 0x0005, 0x0003 }, + { 0x0005, 0x0004 }, + { 0x0005, 0x0005 }, + { 0x0006, 0x0002 }, + { 0x0006, 0x0003 }, + { 0x0006, 0x0004 }, + { 0x0006, 0x0005 }, + { 0x0007, 0x0002 }, + { 0x0007, 0x0003 }, + { 0x0008, 0x0001 }, + { 0x0008, 0x0002 }, + { 0x0008, 0x0003 }, + { 0x000a, 0x0002 }, + { 0x000a, 0x0003 }, + { 0x000b, 0x0002 }, + { 0x000b, 0x0003 }, + { 0x000c, 0x0002 }, + { 0x000c, 0x0003 }, + { 0x000d, 0x0002 }, + { 0x000d, 0x0003 }, + { 0x000e, 0x0002 }, + { 0x000e, 0x0003 }, + { 0x000f, 0x0002 }, + { 0x000f, 0x0003 }, + { 0x0011, 0x0002 }, + { 0x0010, 0x0002 }, + { 0x0010, 0x0003 }, + { 0x0011, 0x0003 }, + { 0x0012, 0x0002 }, + { 0x0012, 0x0003 }, + { 0x0013, 0x0000 }, + { 0x0013, 0x0001 }, + { 0x0013, 0x0002 }, + { 0x0013, 0x0003 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc55[46][2] = + { + { 0x0003, 0x0003 }, + { 0x0002, 0x0003 }, + { 0x0003, 0x0004 }, + { 0x0003, 0x0005 }, + { 0x0004, 0x0003 }, + { 0x0004, 0x0004 }, + { 0x0004, 0x0005 }, + { 0x0005, 0x0003 }, + { 0x0005, 0x0004 }, + { 0x0005, 0x0005 }, + { 0x0006, 0x0003 }, + { 0x0006, 0x0004 }, + { 0x0006, 0x0005 }, + { 0x0007, 0x0002 }, + { 0x0007, 0x0003 }, + { 0x0007, 0x0004 }, + { 0x0007, 0x0005 }, + { 0x0008, 0x0002 }, + { 0x0008, 0x0003 }, + { 0x0009, 0x0002 }, + { 0x0009, 0x0003 }, + { 0x000a, 0x0002 }, + { 0x000a, 0x0003 }, + { 0x000b, 0x0002 }, + { 0x000b, 0x0003 }, + { 0x000c, 0x0002 }, + { 0x000c, 0x0003 }, + { 0x000d, 0x0002 }, + { 0x000d, 0x0003 }, + { 0x000e, 0x0002 }, + { 0x000e, 0x0003 }, + { 0x000f, 0x0003 }, + { 0x0010, 0x0002 }, + { 0x0010, 0x0003 }, + { 0x0010, 0x0004 }, + { 0x0010, 0x0005 }, + { 0x0011, 0x0003 }, + { 0x0012, 0x0003 }, + { 0x0012, 0x0004 }, + { 0x0012, 0x0005 }, + { 0x0013, 0x0000 }, + { 0x0013, 0x0001 }, + { 0x0013, 0x0002 }, + { 0x0013, 0x0003 }, + { 0x0013, 0x0004 }, + { 0x0013, 0x0005 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc56[55][2] = + { + { 0x0003, 0x0003 }, + { 0x0002, 0x0003 }, + { 0x0003, 0x0004 }, + { 0x0003, 0x0005 }, + { 0x0004, 0x0004 }, + { 0x0004, 0x0005 }, + { 0x0005, 0x0003 }, + { 0x0005, 0x0004 }, + { 0x0005, 0x0005 }, + { 0x0005, 0x0006 }, + { 0x0005, 0x0007 }, + { 0x0006, 0x0003 }, + { 0x0006, 0x0004 }, + { 0x0006, 0x0005 }, + { 0x0007, 0x0003 }, + { 0x0007, 0x0004 }, + { 0x0007, 0x0005 }, + { 0x0008, 0x0002 }, + { 0x0008, 0x0003 }, + { 0x0008, 0x0004 }, + { 0x0008, 0x0005 }, + { 0x0009, 0x0002 }, + { 0x0009, 0x0003 }, + { 0x000a, 0x0002 }, + { 0x000a, 0x0003 }, + { 0x000b, 0x0003 }, + { 0x000c, 0x0003 }, + { 0x000c, 0x0004 }, + { 0x000c, 0x0005 }, + { 0x000d, 0x0003 }, + { 0x000d, 0x0004 }, + { 0x000d, 0x0005 }, + { 0x000e, 0x0003 }, + { 0x000e, 0x0004 }, + { 0x000e, 0x0005 }, + { 0x000f, 0x0004 }, + { 0x000f, 0x0005 }, + { 0x0010, 0x0002 }, + { 0x0010, 0x0003 }, + { 0x0010, 0x0004 }, + { 0x0010, 0x0005 }, + { 0x0010, 0x0006 }, + { 0x0010, 0x0007 }, + { 0x0013, 0x0000 }, + { 0x0011, 0x0003 }, + { 0x0012, 0x0005 }, + { 0x0013, 0x0001 }, + { 0x0013, 0x0002 }, + { 0x0013, 0x0003 }, + { 0x0013, 0x0004 }, + { 0x0013, 0x0005 }, + { 0x0013, 0x0006 }, + { 0x0013, 0x0007 }, + { 0x0013, 0x0008 }, + { 0x0013, 0x0009 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc57[65][2] = + { + { 0x0003, 0x0004 }, + { 0x0002, 0x0003 }, + { 0x0003, 0x0005 }, + { 0x0004, 0x0004 }, + { 0x0004, 0x0005 }, + { 0x0004, 0x0006 }, + { 0x0004, 0x0007 }, + { 0x0005, 0x0004 }, + { 0x0005, 0x0005 }, + { 0x0005, 0x0006 }, + { 0x0005, 0x0007 }, + { 0x0006, 0x0004 }, + { 0x0006, 0x0005 }, + { 0x0006, 0x0006 }, + { 0x0006, 0x0007 }, + { 0x0007, 0x0003 }, + { 0x0007, 0x0004 }, + { 0x0007, 0x0005 }, + { 0x0007, 0x0006 }, + { 0x0007, 0x0007 }, + { 0x0008, 0x0003 }, + { 0x0008, 0x0004 }, + { 0x0008, 0x0005 }, + { 0x0009, 0x0003 }, + { 0x0009, 0x0004 }, + { 0x0009, 0x0005 }, + { 0x000a, 0x0003 }, + { 0x000a, 0x0004 }, + { 0x000a, 0x0005 }, + { 0x000b, 0x0003 }, + { 0x000b, 0x0004 }, + { 0x000b, 0x0005 }, + { 0x000c, 0x0003 }, + { 0x000c, 0x0004 }, + { 0x000d, 0x0003 }, + { 0x000c, 0x0005 }, + { 0x000d, 0x0004 }, + { 0x000d, 0x0005 }, + { 0x000e, 0x0003 }, + { 0x000e, 0x0004 }, + { 0x000e, 0x0005 }, + { 0x000f, 0x0003 }, + { 0x0010, 0x0003 }, + { 0x000f, 0x0004 }, + { 0x000f, 0x0005 }, + { 0x0010, 0x0004 }, + { 0x0010, 0x0005 }, + { 0x0013, 0x0000 }, + { 0x0011, 0x0005 }, + { 0x0013, 0x0001 }, + { 0x0013, 0x0002 }, + { 0x0012, 0x0007 }, + { 0x0013, 0x0003 }, + { 0x0013, 0x0004 }, + { 0x0012, 0x0008 }, + { 0x0012, 0x0009 }, + { 0x0013, 0x0005 }, + { 0x0013, 0x0006 }, + { 0x0013, 0x0007 }, + { 0x0013, 0x0008 }, + { 0x0013, 0x0009 }, + { 0x0013, 0x000a }, + { 0x0013, 0x000b }, + { 0x0013, 0x000c }, + { 0x0013, 0x000d }, + + }; + +const uint16_t c_aauiLCLDHuffEnc58[77][2] = + { + { 0x0004, 0x0005 }, + { 0x0003, 0x0005 }, + { 0x0003, 0x0006 }, + { 0x0003, 0x0007 }, + { 0x0004, 0x0006 }, + { 0x0004, 0x0007 }, + { 0x0004, 0x0008 }, + { 0x0004, 0x0009 }, + { 0x0005, 0x0005 }, + { 0x0005, 0x0006 }, + { 0x0005, 0x0007 }, + { 0x0005, 0x0008 }, + { 0x0005, 0x0009 }, + { 0x0006, 0x0004 }, + { 0x0006, 0x0005 }, + { 0x0006, 0x0006 }, + { 0x0006, 0x0007 }, + { 0x0006, 0x0008 }, + { 0x0006, 0x0009 }, + { 0x0007, 0x0004 }, + { 0x0007, 0x0005 }, + { 0x0007, 0x0006 }, + { 0x0007, 0x0007 }, + { 0x0008, 0x0003 }, + { 0x0008, 0x0004 }, + { 0x0008, 0x0005 }, + { 0x0008, 0x0006 }, + { 0x0008, 0x0007 }, + { 0x0009, 0x0003 }, + { 0x0009, 0x0004 }, + { 0x0009, 0x0005 }, + { 0x000a, 0x0003 }, + { 0x000a, 0x0004 }, + { 0x000a, 0x0005 }, + { 0x000b, 0x0004 }, + { 0x000b, 0x0005 }, + { 0x000c, 0x0004 }, + { 0x000c, 0x0005 }, + { 0x000c, 0x0006 }, + { 0x000c, 0x0007 }, + { 0x000d, 0x0004 }, + { 0x000d, 0x0005 }, + { 0x000d, 0x0006 }, + { 0x000d, 0x0007 }, + { 0x000e, 0x0004 }, + { 0x000e, 0x0005 }, + { 0x000e, 0x0006 }, + { 0x000e, 0x0007 }, + { 0x000f, 0x0004 }, + { 0x000f, 0x0005 }, + { 0x000f, 0x0006 }, + { 0x0010, 0x0004 }, + { 0x000f, 0x0007 }, + { 0x0010, 0x0005 }, + { 0x0010, 0x0006 }, + { 0x0010, 0x0007 }, + { 0x0013, 0x0000 }, + { 0x0013, 0x0001 }, + { 0x0012, 0x0006 }, + { 0x0011, 0x0007 }, + { 0x0013, 0x0002 }, + { 0x0013, 0x0003 }, + { 0x0013, 0x0004 }, + { 0x0013, 0x0005 }, + { 0x0012, 0x0007 }, + { 0x0013, 0x0006 }, + { 0x0013, 0x0007 }, + { 0x0013, 0x0008 }, + { 0x0013, 0x0009 }, + { 0x0013, 0x000a }, + { 0x0013, 0x000b }, + { 0x0012, 0x0008 }, + { 0x0012, 0x0009 }, + { 0x0012, 0x000a }, + { 0x0012, 0x000b }, + { 0x0012, 0x000c }, + { 0x0012, 0x000d }, + + }; + +const uint16_t c_aauiLCLDHuffEnc59[91][2] = + { + { 0x0003, 0x0005 }, + { 0x0003, 0x0006 }, + { 0x0003, 0x0007 }, + { 0x0004, 0x0006 }, + { 0x0004, 0x0007 }, + { 0x0004, 0x0008 }, + { 0x0004, 0x0009 }, + { 0x0005, 0x0006 }, + { 0x0005, 0x0007 }, + { 0x0005, 0x0008 }, + { 0x0005, 0x0009 }, + { 0x0005, 0x000a }, + { 0x0005, 0x000b }, + { 0x0006, 0x0006 }, + { 0x0006, 0x0007 }, + { 0x0006, 0x0008 }, + { 0x0006, 0x0009 }, + { 0x0006, 0x000a }, + { 0x0006, 0x000b }, + { 0x0007, 0x0005 }, + { 0x0007, 0x0006 }, + { 0x0007, 0x0007 }, + { 0x0007, 0x0008 }, + { 0x0007, 0x0009 }, + { 0x0007, 0x000a }, + { 0x0007, 0x000b }, + { 0x0008, 0x0003 }, + { 0x0008, 0x0004 }, + { 0x0008, 0x0005 }, + { 0x0008, 0x0006 }, + { 0x0008, 0x0007 }, + { 0x0008, 0x0008 }, + { 0x0008, 0x0009 }, + { 0x0009, 0x0004 }, + { 0x0009, 0x0005 }, + { 0x000a, 0x0004 }, + { 0x000a, 0x0005 }, + { 0x000a, 0x0006 }, + { 0x000a, 0x0007 }, + { 0x000b, 0x0004 }, + { 0x000b, 0x0005 }, + { 0x000b, 0x0006 }, + { 0x000b, 0x0007 }, + { 0x000c, 0x0004 }, + { 0x000c, 0x0005 }, + { 0x000c, 0x0006 }, + { 0x000c, 0x0007 }, + { 0x000d, 0x0003 }, + { 0x000d, 0x0004 }, + { 0x000d, 0x0005 }, + { 0x000d, 0x0006 }, + { 0x000d, 0x0007 }, + { 0x000e, 0x0003 }, + { 0x000e, 0x0004 }, + { 0x000e, 0x0005 }, + { 0x000f, 0x0003 }, + { 0x000f, 0x0004 }, + { 0x000f, 0x0005 }, + { 0x0011, 0x0008 }, + { 0x0011, 0x0009 }, + { 0x0013, 0x0000 }, + { 0x0011, 0x000a }, + { 0x0013, 0x0001 }, + { 0x0013, 0x0002 }, + { 0x0012, 0x000d }, + { 0x0012, 0x000e }, + { 0x0013, 0x0003 }, + { 0x0013, 0x0004 }, + { 0x0013, 0x0005 }, + { 0x0011, 0x000b }, + { 0x0013, 0x0006 }, + { 0x0013, 0x0007 }, + { 0x0013, 0x0008 }, + { 0x0013, 0x0009 }, + { 0x0013, 0x000a }, + { 0x0013, 0x000b }, + { 0x0013, 0x000c }, + { 0x0013, 0x000d }, + { 0x0013, 0x000e }, + { 0x0013, 0x000f }, + { 0x0013, 0x0010 }, + { 0x0013, 0x0011 }, + { 0x0013, 0x0012 }, + { 0x0013, 0x0013 }, + { 0x0013, 0x0014 }, + { 0x0013, 0x0015 }, + { 0x0013, 0x0016 }, + { 0x0013, 0x0017 }, + { 0x0013, 0x0018 }, + { 0x0013, 0x0019 }, + { 0x0012, 0x000f }, + + }; + +const uint16_t c_aauiLCLDHuffEnc60[109][2] = + { + { 0x0004, 0x0007 }, + { 0x0002, 0x0003 }, + { 0x0003, 0x0005 }, + { 0x0004, 0x0008 }, + { 0x0004, 0x0009 }, + { 0x0005, 0x0007 }, + { 0x0005, 0x0008 }, + { 0x0005, 0x0009 }, + { 0x0005, 0x000a }, + { 0x0005, 0x000b }, + { 0x0005, 0x000c }, + { 0x0005, 0x000d }, + { 0x0006, 0x0007 }, + { 0x0006, 0x0008 }, + { 0x0006, 0x0009 }, + { 0x0006, 0x000a }, + { 0x0006, 0x000b }, + { 0x0006, 0x000c }, + { 0x0006, 0x000d }, + { 0x0007, 0x0006 }, + { 0x0007, 0x0007 }, + { 0x0007, 0x0008 }, + { 0x0007, 0x0009 }, + { 0x0007, 0x000a }, + { 0x0007, 0x000b }, + { 0x0007, 0x000c }, + { 0x0007, 0x000d }, + { 0x0008, 0x0006 }, + { 0x0008, 0x0007 }, + { 0x0008, 0x0008 }, + { 0x0008, 0x0009 }, + { 0x0008, 0x000a }, + { 0x0008, 0x000b }, + { 0x0009, 0x0004 }, + { 0x0009, 0x0005 }, + { 0x0009, 0x0006 }, + { 0x0009, 0x0007 }, + { 0x0009, 0x0008 }, + { 0x0009, 0x0009 }, + { 0x0009, 0x000a }, + { 0x0009, 0x000b }, + { 0x000a, 0x0004 }, + { 0x000a, 0x0005 }, + { 0x000a, 0x0006 }, + { 0x000a, 0x0007 }, + { 0x000b, 0x0004 }, + { 0x000b, 0x0005 }, + { 0x000b, 0x0006 }, + { 0x000b, 0x0007 }, + { 0x000c, 0x0004 }, + { 0x000c, 0x0005 }, + { 0x000c, 0x0006 }, + { 0x000d, 0x0005 }, + { 0x000d, 0x0006 }, + { 0x000d, 0x0007 }, + { 0x000c, 0x0007 }, + { 0x000e, 0x0005 }, + { 0x000e, 0x0006 }, + { 0x000e, 0x0007 }, + { 0x000e, 0x0008 }, + { 0x000f, 0x0005 }, + { 0x000e, 0x0009 }, + { 0x000f, 0x0006 }, + { 0x0010, 0x0006 }, + { 0x000f, 0x0007 }, + { 0x000f, 0x0008 }, + { 0x000f, 0x0009 }, + { 0x0010, 0x0007 }, + { 0x0010, 0x0008 }, + { 0x0010, 0x0009 }, + { 0x0011, 0x000a }, + { 0x0013, 0x0000 }, + { 0x0011, 0x000b }, + { 0x0013, 0x0001 }, + { 0x0013, 0x0002 }, + { 0x0012, 0x0011 }, + { 0x0012, 0x0012 }, + { 0x0013, 0x0003 }, + { 0x0013, 0x0004 }, + { 0x0013, 0x0005 }, + { 0x0013, 0x0006 }, + { 0x0013, 0x0007 }, + { 0x0013, 0x0008 }, + { 0x0013, 0x0009 }, + { 0x0013, 0x000a }, + { 0x0013, 0x000b }, + { 0x0013, 0x000c }, + { 0x0013, 0x000d }, + { 0x0013, 0x000e }, + { 0x0013, 0x000f }, + { 0x0013, 0x0010 }, + { 0x0013, 0x0011 }, + { 0x0013, 0x0012 }, + { 0x0013, 0x0013 }, + { 0x0013, 0x0014 }, + { 0x0013, 0x0015 }, + { 0x0013, 0x0016 }, + { 0x0013, 0x0017 }, + { 0x0013, 0x0018 }, + { 0x0013, 0x0019 }, + { 0x0013, 0x001a }, + { 0x0013, 0x001b }, + { 0x0013, 0x001c }, + { 0x0013, 0x001d }, + { 0x0013, 0x001e }, + { 0x0013, 0x001f }, + { 0x0013, 0x0020 }, + { 0x0013, 0x0021 }, + { 0x0012, 0x0013 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc61[129][2] = + { + { 0x0004, 0x0008 }, + { 0x0003, 0x0006 }, + { 0x0003, 0x0007 }, + { 0x0004, 0x0009 }, + { 0x0004, 0x000a }, + { 0x0004, 0x000b }, + { 0x0005, 0x0008 }, + { 0x0005, 0x0009 }, + { 0x0005, 0x000a }, + { 0x0005, 0x000b }, + { 0x0005, 0x000c }, + { 0x0005, 0x000d }, + { 0x0005, 0x000e }, + { 0x0005, 0x000f }, + { 0x0006, 0x0008 }, + { 0x0006, 0x0009 }, + { 0x0006, 0x000a }, + { 0x0006, 0x000b }, + { 0x0006, 0x000c }, + { 0x0006, 0x000d }, + { 0x0006, 0x000e }, + { 0x0006, 0x000f }, + { 0x0007, 0x0008 }, + { 0x0007, 0x0009 }, + { 0x0007, 0x000a }, + { 0x0007, 0x000b }, + { 0x0007, 0x000c }, + { 0x0007, 0x000d }, + { 0x0007, 0x000e }, + { 0x0007, 0x000f }, + { 0x0008, 0x0006 }, + { 0x0008, 0x0007 }, + { 0x0008, 0x0008 }, + { 0x0008, 0x0009 }, + { 0x0008, 0x000a }, + { 0x0008, 0x000b }, + { 0x0008, 0x000c }, + { 0x0008, 0x000d }, + { 0x0008, 0x000e }, + { 0x0008, 0x000f }, + { 0x0009, 0x0006 }, + { 0x0009, 0x0007 }, + { 0x0009, 0x0008 }, + { 0x0009, 0x0009 }, + { 0x0009, 0x000a }, + { 0x0009, 0x000b }, + { 0x000a, 0x0005 }, + { 0x000a, 0x0006 }, + { 0x000a, 0x0007 }, + { 0x000a, 0x0008 }, + { 0x000a, 0x0009 }, + { 0x000a, 0x000a }, + { 0x000a, 0x000b }, + { 0x000b, 0x0005 }, + { 0x000b, 0x0006 }, + { 0x000b, 0x0007 }, + { 0x000b, 0x0008 }, + { 0x000b, 0x0009 }, + { 0x000c, 0x0006 }, + { 0x000c, 0x0007 }, + { 0x000c, 0x0008 }, + { 0x000c, 0x0009 }, + { 0x000d, 0x0005 }, + { 0x000d, 0x0006 }, + { 0x000d, 0x0007 }, + { 0x000d, 0x0008 }, + { 0x000d, 0x0009 }, + { 0x000d, 0x000a }, + { 0x000e, 0x0008 }, + { 0x000d, 0x000b }, + { 0x000e, 0x0009 }, + { 0x000f, 0x0009 }, + { 0x000f, 0x000a }, + { 0x000f, 0x000b }, + { 0x000f, 0x000c }, + { 0x000f, 0x000d }, + { 0x000f, 0x000e }, + { 0x0010, 0x000c }, + { 0x0011, 0x0015 }, + { 0x0010, 0x000d }, + { 0x000f, 0x000f }, + { 0x0010, 0x000e }, + { 0x0010, 0x000f }, + { 0x0012, 0x0000 }, + { 0x0011, 0x0016 }, + { 0x0010, 0x0010 }, + { 0x0010, 0x0011 }, + { 0x0011, 0x0017 }, + { 0x0012, 0x0001 }, + { 0x0012, 0x0002 }, + { 0x0012, 0x0003 }, + { 0x0012, 0x0004 }, + { 0x0012, 0x0005 }, + { 0x0012, 0x0006 }, + { 0x0012, 0x0007 }, + { 0x0012, 0x0008 }, + { 0x0012, 0x0009 }, + { 0x0012, 0x000a }, + { 0x0012, 0x000b }, + { 0x0012, 0x000c }, + { 0x0012, 0x000d }, + { 0x0012, 0x000e }, + { 0x0012, 0x000f }, + { 0x0012, 0x0010 }, + { 0x0012, 0x0011 }, + { 0x0012, 0x0012 }, + { 0x0012, 0x0013 }, + { 0x0012, 0x0014 }, + { 0x0012, 0x0015 }, + { 0x0012, 0x0016 }, + { 0x0012, 0x0017 }, + { 0x0012, 0x0018 }, + { 0x0012, 0x0019 }, + { 0x0012, 0x001a }, + { 0x0012, 0x001b }, + { 0x0012, 0x001c }, + { 0x0012, 0x001d }, + { 0x0012, 0x001e }, + { 0x0012, 0x001f }, + { 0x0012, 0x0020 }, + { 0x0012, 0x0021 }, + { 0x0012, 0x0022 }, + { 0x0012, 0x0023 }, + { 0x0012, 0x0024 }, + { 0x0012, 0x0025 }, + { 0x0012, 0x0026 }, + { 0x0012, 0x0027 }, + { 0x0012, 0x0028 }, + { 0x0012, 0x0029 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc62[153][2] = + { + { 0x0004, 0x0009 }, + { 0x0003, 0x0006 }, + { 0x0003, 0x0007 }, + { 0x0004, 0x000a }, + { 0x0004, 0x000b }, + { 0x0005, 0x000a }, + { 0x0005, 0x000b }, + { 0x0005, 0x000c }, + { 0x0005, 0x000d }, + { 0x0005, 0x000e }, + { 0x0005, 0x000f }, + { 0x0005, 0x0010 }, + { 0x0005, 0x0011 }, + { 0x0006, 0x000a }, + { 0x0006, 0x000b }, + { 0x0006, 0x000c }, + { 0x0006, 0x000d }, + { 0x0006, 0x000e }, + { 0x0006, 0x000f }, + { 0x0006, 0x0010 }, + { 0x0006, 0x0011 }, + { 0x0006, 0x0012 }, + { 0x0006, 0x0013 }, + { 0x0007, 0x0009 }, + { 0x0007, 0x000a }, + { 0x0007, 0x000b }, + { 0x0007, 0x000c }, + { 0x0007, 0x000d }, + { 0x0007, 0x000e }, + { 0x0007, 0x000f }, + { 0x0007, 0x0010 }, + { 0x0007, 0x0011 }, + { 0x0007, 0x0012 }, + { 0x0007, 0x0013 }, + { 0x0008, 0x0009 }, + { 0x0008, 0x000a }, + { 0x0008, 0x000b }, + { 0x0008, 0x000c }, + { 0x0008, 0x000d }, + { 0x0008, 0x000e }, + { 0x0008, 0x000f }, + { 0x0008, 0x0010 }, + { 0x0008, 0x0011 }, + { 0x0009, 0x0007 }, + { 0x0009, 0x0008 }, + { 0x0009, 0x0009 }, + { 0x0009, 0x000a }, + { 0x0009, 0x000b }, + { 0x0009, 0x000c }, + { 0x0009, 0x000d }, + { 0x0009, 0x000e }, + { 0x0009, 0x000f }, + { 0x0009, 0x0010 }, + { 0x0009, 0x0011 }, + { 0x000a, 0x0004 }, + { 0x000a, 0x0005 }, + { 0x000a, 0x0006 }, + { 0x000a, 0x0007 }, + { 0x000a, 0x0008 }, + { 0x000a, 0x0009 }, + { 0x000a, 0x000a }, + { 0x000a, 0x000b }, + { 0x000a, 0x000c }, + { 0x000a, 0x000d }, + { 0x000b, 0x0007 }, + { 0x000c, 0x0007 }, + { 0x000c, 0x0008 }, + { 0x000c, 0x0009 }, + { 0x000c, 0x000a }, + { 0x000c, 0x000b }, + { 0x000c, 0x000c }, + { 0x000d, 0x0007 }, + { 0x000c, 0x000d }, + { 0x000d, 0x0008 }, + { 0x000d, 0x0009 }, + { 0x000d, 0x000a }, + { 0x000d, 0x000b }, + { 0x000e, 0x0008 }, + { 0x000d, 0x000c }, + { 0x000d, 0x000d }, + { 0x000e, 0x0009 }, + { 0x000e, 0x000a }, + { 0x000e, 0x000b }, + { 0x000e, 0x000c }, + { 0x000f, 0x000c }, + { 0x000e, 0x000d }, + { 0x000f, 0x000d }, + { 0x000f, 0x000e }, + { 0x000f, 0x000f }, + { 0x0010, 0x000f }, + { 0x0010, 0x0010 }, + { 0x0011, 0x0019 }, + { 0x0010, 0x0011 }, + { 0x0010, 0x0012 }, + { 0x0010, 0x0013 }, + { 0x0010, 0x0014 }, + { 0x0010, 0x0015 }, + { 0x0012, 0x0000 }, + { 0x0010, 0x0016 }, + { 0x0011, 0x001a }, + { 0x0010, 0x0017 }, + { 0x0012, 0x0001 }, + { 0x0012, 0x0002 }, + { 0x0012, 0x0003 }, + { 0x0011, 0x001b }, + { 0x0012, 0x0004 }, + { 0x0012, 0x0005 }, + { 0x0012, 0x0006 }, + { 0x0012, 0x0007 }, + { 0x0012, 0x0008 }, + { 0x0012, 0x0009 }, + { 0x0012, 0x000a }, + { 0x0012, 0x000b }, + { 0x0012, 0x000c }, + { 0x0012, 0x000d }, + { 0x0012, 0x000e }, + { 0x0012, 0x000f }, + { 0x0012, 0x0010 }, + { 0x0012, 0x0011 }, + { 0x0012, 0x0012 }, + { 0x0012, 0x0013 }, + { 0x0012, 0x0014 }, + { 0x0012, 0x0015 }, + { 0x0012, 0x0016 }, + { 0x0012, 0x0017 }, + { 0x0012, 0x0018 }, + { 0x0011, 0x001c }, + { 0x0012, 0x0019 }, + { 0x0012, 0x001a }, + { 0x0012, 0x001b }, + { 0x0012, 0x001c }, + { 0x0012, 0x001d }, + { 0x0012, 0x001e }, + { 0x0012, 0x001f }, + { 0x0012, 0x0020 }, + { 0x0012, 0x0021 }, + { 0x0012, 0x0022 }, + { 0x0012, 0x0023 }, + { 0x0012, 0x0024 }, + { 0x0012, 0x0025 }, + { 0x0012, 0x0026 }, + { 0x0012, 0x0027 }, + { 0x0012, 0x0028 }, + { 0x0012, 0x0029 }, + { 0x0012, 0x002a }, + { 0x0012, 0x002b }, + { 0x0012, 0x002c }, + { 0x0012, 0x002d }, + { 0x0012, 0x002e }, + { 0x0012, 0x002f }, + { 0x0012, 0x0030 }, + { 0x0012, 0x0031 }, + { 0x0011, 0x001d }, + + }; + +const uint16_t c_aauiLCLDHuffEnc63[181][2] = + { + { 0x0004, 0x0008 }, + { 0x0003, 0x0005 }, + { 0x0002, 0x0003 }, + { 0x0004, 0x0009 }, + { 0x0005, 0x000c }, + { 0x0005, 0x000d }, + { 0x0005, 0x000e }, + { 0x0005, 0x000f }, + { 0x0006, 0x000c }, + { 0x0006, 0x000d }, + { 0x0006, 0x000e }, + { 0x0006, 0x000f }, + { 0x0006, 0x0010 }, + { 0x0006, 0x0011 }, + { 0x0006, 0x0012 }, + { 0x0006, 0x0013 }, + { 0x0006, 0x0014 }, + { 0x0006, 0x0015 }, + { 0x0006, 0x0016 }, + { 0x0006, 0x0017 }, + { 0x0007, 0x000b }, + { 0x0007, 0x000c }, + { 0x0007, 0x000d }, + { 0x0007, 0x000e }, + { 0x0007, 0x000f }, + { 0x0007, 0x0010 }, + { 0x0007, 0x0011 }, + { 0x0007, 0x0012 }, + { 0x0007, 0x0013 }, + { 0x0007, 0x0014 }, + { 0x0007, 0x0015 }, + { 0x0007, 0x0016 }, + { 0x0007, 0x0017 }, + { 0x0008, 0x000c }, + { 0x0008, 0x000d }, + { 0x0008, 0x000e }, + { 0x0008, 0x000f }, + { 0x0008, 0x0010 }, + { 0x0008, 0x0011 }, + { 0x0008, 0x0012 }, + { 0x0008, 0x0013 }, + { 0x0008, 0x0014 }, + { 0x0008, 0x0015 }, + { 0x0009, 0x0008 }, + { 0x0009, 0x0009 }, + { 0x0009, 0x000a }, + { 0x0009, 0x000b }, + { 0x0009, 0x000c }, + { 0x0009, 0x000d }, + { 0x0009, 0x000e }, + { 0x0009, 0x000f }, + { 0x0009, 0x0010 }, + { 0x0009, 0x0011 }, + { 0x0009, 0x0012 }, + { 0x0009, 0x0013 }, + { 0x0009, 0x0014 }, + { 0x0009, 0x0015 }, + { 0x000a, 0x0007 }, + { 0x0009, 0x0016 }, + { 0x0009, 0x0017 }, + { 0x000a, 0x0008 }, + { 0x000a, 0x0009 }, + { 0x000a, 0x000a }, + { 0x000a, 0x000b }, + { 0x000a, 0x000c }, + { 0x000a, 0x000d }, + { 0x000a, 0x000e }, + { 0x000b, 0x0008 }, + { 0x000b, 0x0009 }, + { 0x000b, 0x000a }, + { 0x000a, 0x000f }, + { 0x000b, 0x000b }, + { 0x000b, 0x000c }, + { 0x000b, 0x000d }, + { 0x000c, 0x0009 }, + { 0x000c, 0x000a }, + { 0x000c, 0x000b }, + { 0x000c, 0x000c }, + { 0x000c, 0x000d }, + { 0x000c, 0x000e }, + { 0x000c, 0x000f }, + { 0x000d, 0x0008 }, + { 0x000d, 0x0009 }, + { 0x000d, 0x000a }, + { 0x000d, 0x000b }, + { 0x000d, 0x000c }, + { 0x000d, 0x000d }, + { 0x000d, 0x000e }, + { 0x000d, 0x000f }, + { 0x000d, 0x0010 }, + { 0x000d, 0x0011 }, + { 0x000e, 0x0007 }, + { 0x000e, 0x0008 }, + { 0x000e, 0x0009 }, + { 0x000e, 0x000a }, + { 0x000e, 0x000b }, + { 0x000e, 0x000c }, + { 0x000e, 0x000d }, + { 0x000e, 0x000e }, + { 0x000e, 0x000f }, + { 0x000f, 0x0008 }, + { 0x000f, 0x0009 }, + { 0x000f, 0x000a }, + { 0x000f, 0x000b }, + { 0x000f, 0x000c }, + { 0x0010, 0x0009 }, + { 0x0010, 0x000a }, + { 0x000f, 0x000d }, + { 0x0010, 0x000b }, + { 0x0010, 0x000c }, + { 0x0010, 0x000d }, + { 0x0011, 0x000e }, + { 0x0011, 0x000f }, + { 0x0010, 0x000e }, + { 0x0011, 0x0010 }, + { 0x0011, 0x0011 }, + { 0x0012, 0x0014 }, + { 0x0014, 0x0000 }, + { 0x0010, 0x000f }, + { 0x0012, 0x0015 }, + { 0x0012, 0x0016 }, + { 0x0014, 0x0001 }, + { 0x0012, 0x0017 }, + { 0x0012, 0x0018 }, + { 0x0012, 0x0019 }, + { 0x0013, 0x0010 }, + { 0x0012, 0x001a }, + { 0x0014, 0x0002 }, + { 0x0012, 0x001b }, + { 0x0014, 0x0003 }, + { 0x0014, 0x0004 }, + { 0x0014, 0x0005 }, + { 0x0013, 0x0011 }, + { 0x0014, 0x0006 }, + { 0x0013, 0x0012 }, + { 0x0014, 0x0007 }, + { 0x0014, 0x0008 }, + { 0x0014, 0x0009 }, + { 0x0014, 0x000a }, + { 0x0014, 0x000b }, + { 0x0014, 0x000c }, + { 0x0014, 0x000d }, + { 0x0014, 0x000e }, + { 0x0013, 0x0013 }, + { 0x0014, 0x000f }, + { 0x0014, 0x0010 }, + { 0x0014, 0x0011 }, + { 0x0014, 0x0012 }, + { 0x0014, 0x0013 }, + { 0x0014, 0x0014 }, + { 0x0014, 0x0015 }, + { 0x0014, 0x0016 }, + { 0x0014, 0x0017 }, + { 0x0014, 0x0018 }, + { 0x0014, 0x0019 }, + { 0x0014, 0x001a }, + { 0x0014, 0x001b }, + { 0x0014, 0x001c }, + { 0x0014, 0x001d }, + { 0x0014, 0x001e }, + { 0x0014, 0x001f }, + { 0x0013, 0x0014 }, + { 0x0013, 0x0015 }, + { 0x0013, 0x0016 }, + { 0x0013, 0x0017 }, + { 0x0013, 0x0018 }, + { 0x0013, 0x0019 }, + { 0x0013, 0x001a }, + { 0x0013, 0x001b }, + { 0x0013, 0x001c }, + { 0x0013, 0x001d }, + { 0x0013, 0x001e }, + { 0x0013, 0x001f }, + { 0x0013, 0x0020 }, + { 0x0013, 0x0021 }, + { 0x0013, 0x0022 }, + { 0x0013, 0x0023 }, + { 0x0013, 0x0024 }, + { 0x0013, 0x0025 }, + { 0x0013, 0x0026 }, + { 0x0013, 0x0027 }, + + }; + +const uint16_t ( *c_apauiHuffEncTabels[2 * ALLOC_TABLE_SIZE] )[2] = + { + NULL, + c_aauiLCLDHuffEnc1, + c_aauiLCLDHuffEnc2, + c_aauiLCLDHuffEnc3, + c_aauiLCLDHuffEnc4, + c_aauiLCLDHuffEnc5, + c_aauiLCLDHuffEnc6, + c_aauiLCLDHuffEnc7, + c_aauiLCLDHuffEnc8, + c_aauiLCLDHuffEnc9, + c_aauiLCLDHuffEnc10, + c_aauiLCLDHuffEnc11, + c_aauiLCLDHuffEnc12, + c_aauiLCLDHuffEnc13, + c_aauiLCLDHuffEnc14, + c_aauiLCLDHuffEnc15, + c_aauiLCLDHuffEnc16, + c_aauiLCLDHuffEnc17, + c_aauiLCLDHuffEnc18, + c_aauiLCLDHuffEnc19, + c_aauiLCLDHuffEnc20, + c_aauiLCLDHuffEnc21, + c_aauiLCLDHuffEnc22, + c_aauiLCLDHuffEnc23, + c_aauiLCLDHuffEnc24, + c_aauiLCLDHuffEnc25, + c_aauiLCLDHuffEnc26, + c_aauiLCLDHuffEnc27, + c_aauiLCLDHuffEnc28, + c_aauiLCLDHuffEnc29, + c_aauiLCLDHuffEnc30, + c_aauiLCLDHuffEnc31, + NULL, + c_aauiLCLDHuffEnc33, + c_aauiLCLDHuffEnc34, + c_aauiLCLDHuffEnc35, + c_aauiLCLDHuffEnc36, + c_aauiLCLDHuffEnc37, + c_aauiLCLDHuffEnc38, + c_aauiLCLDHuffEnc39, + c_aauiLCLDHuffEnc40, + c_aauiLCLDHuffEnc41, + c_aauiLCLDHuffEnc42, + c_aauiLCLDHuffEnc43, + c_aauiLCLDHuffEnc44, + c_aauiLCLDHuffEnc45, + c_aauiLCLDHuffEnc46, + c_aauiLCLDHuffEnc47, + c_aauiLCLDHuffEnc48, + c_aauiLCLDHuffEnc49, + c_aauiLCLDHuffEnc50, + c_aauiLCLDHuffEnc51, + c_aauiLCLDHuffEnc52, + c_aauiLCLDHuffEnc53, + c_aauiLCLDHuffEnc54, + c_aauiLCLDHuffEnc55, + c_aauiLCLDHuffEnc56, + c_aauiLCLDHuffEnc57, + c_aauiLCLDHuffEnc58, + c_aauiLCLDHuffEnc59, + c_aauiLCLDHuffEnc60, + c_aauiLCLDHuffEnc61, + c_aauiLCLDHuffEnc62, + c_aauiLCLDHuffEnc63, + }; + +const uint32_t num_row_aauiLCLDHuff[2 * ALLOC_TABLE_SIZE] = { 0, 16, 16, 25, 36, 36, 49, 64, 81, 100, + 169, 196, 289, 324, 400, 576, 729, 729, 28, 29, + 32, 37, 39, 46, 55, 65, 77, 91, 109, 129, + 153, 181, 0, 16, 16, 25, 36, 36, 49, 64, 81, + 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_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 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, + 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_aiBandwidthAdjust48[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_aiAbsoluteThresh48[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, +}; + + +#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 + +const int32_t c_aaiSpreadFunction48[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, +}; +#endif diff --git a/lib_rend/ivas_lcld_rom_tables.h b/lib_rend/ivas_lcld_rom_tables.h new file mode 100644 index 000000000..132f52add --- /dev/null +++ b/lib_rend/ivas_lcld_rom_tables.h @@ -0,0 +1,225 @@ +/****************************************************************************************************** + + (C) 2022-2023 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 _IVAS_TABLES_H_ +#define _IVAS_TABLES_H_ + +#include +#include "options.h" + +#ifndef M_PI + +#define M_PI 3.14159265358979323846264338327950288f // todo: replace by EVS_PI + +#endif + +#define LCLD_BLOCKS_PER_FRAME ( 16 ) +#define LCLD_MAX_BLOCKS_PER_FRAME ( 16 ) +#define LCLD_BANDS ( 60 ) + +#define MAX_BANDS ( 23 ) +#define MAX_BANDS_48 ( 23 ) + +#define ENV_MIN ( -64 ) +#define ENV_MAX ( 64 ) + +#define ENV0_BITS ( 7 ) + +#define ENV_DELTA_MIN ( -32 ) +#define ENV_DELTA_MAX ( 31 ) + +#define ENV_RECONSTRUCT_TABLE_SIZE ( 129 ) + +#define ENV_RECONSTRUCT_TABLE_CENTER ( 64 ) + +#define MIN_ALLOC ( 0 ) +#define MAX_ALLOC ( 31 ) + +#define ALLOC_OFFSET_SCALE ( 8 ) + +#define ALLOC_OFFSET_BITS ( 8 ) + +#define MIN_ALLOC_OFFSET ( -128 ) +#define MAX_ALLOC_OFFSET ( 127 ) +#define READ_LENGTH ( 4 ) + +#define ALLOC_TABLE_SIZE ( 32 ) + +#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 SIMPLE_PHASE_MAX_VAL ( 3 ) +#define SIMPLE_PHASE_MIN_VAL ( 0 ) +#define SIMPLE_PHASE_BITS ( 2 ) +#define SIMPLE_PHASE_QUANT_FACTOR ( 2.0f / _PI_ ) + +#define TON_QUOTA_ABS_THRESHOLD ( 8.0f ) +#define TON_QUOTA_INC_THRESHOLD ( 4.0f ) + +#define PERCEPTUAL_MODEL_SLGAIN_SHIFT ( 8 ) + +//#define USE_DEMOD_TABLES + +#define HUFF_DEC_TABLE_SIZE ( 16 ) + +extern const float c_afRotRealImag[PRED_MAX_VAL - PRED_MIN_VAL + 1][2]; +extern const float c_afRotRealImagSimple[SIMPLE_PHASE_MAX_VAL + 1][2]; +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 float c_afRMSEnvReconstructTable[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 int32_t c_aiHuffmanSize[ALLOC_TABLE_SIZE]; + + +#define LOG_ADD_TABLE_LENGTH ( 512 ) + +extern const int32_t c_aiBandwidths48[MAX_BANDS_48]; +extern const int32_t c_aiLogAddTable[LOG_ADD_TABLE_LENGTH]; +extern const int32_t c_aiBandwidthAdjust48[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]; + + +#define PRED_QUNAT_FILTER_MAG_BITS ( 3 ) +#define PRED_QUANT_FILTER_PHASE_BITS ( 5 ) +#define PRED_QUANT_FILTER_MAG_MIN ( 0 ) +#define PRED_QUANT_FILTER_MAG_MAX ( 7 ) +#define PRED_QUANT_FILTER_PHASE_MIN ( -16 ) +#define PRED_QUANT_FILTER_PHASE_MAX ( 15 ) + +extern const uint16_t c_aauiLCLDHuffEnc1[16][2]; +extern const uint16_t c_aauiLCLDHuffEnc2[16][2]; +extern const uint16_t c_aauiLCLDHuffEnc3[25][2]; +extern const uint16_t c_aauiLCLDHuffEnc4[36][2]; +extern const uint16_t c_aauiLCLDHuffEnc5[36][2]; +extern const uint16_t c_aauiLCLDHuffEnc6[49][2]; +extern const uint16_t c_aauiLCLDHuffEnc7[64][2]; +extern const uint16_t c_aauiLCLDHuffEnc8[81][2]; +extern const uint16_t c_aauiLCLDHuffEnc9[100][2]; +extern const uint16_t c_aauiLCLDHuffEnc10[169][2]; +extern const uint16_t c_aauiLCLDHuffEnc11[196][2]; +extern const uint16_t c_aauiLCLDHuffEnc12[289][2]; +extern const uint16_t c_aauiLCLDHuffEnc13[324][2]; +extern const uint16_t c_aauiLCLDHuffEnc14[400][2]; +extern const uint16_t c_aauiLCLDHuffEnc15[576][2]; +extern const uint16_t c_aauiLCLDHuffEnc16[729][2]; +extern const uint16_t c_aauiLCLDHuffEnc17[729][2]; +extern const uint16_t c_aauiLCLDHuffEnc18[28][2]; +extern const uint16_t c_aauiLCLDHuffEnc19[29][2]; +extern const uint16_t c_aauiLCLDHuffEnc20[32][2]; +extern const uint16_t c_aauiLCLDHuffEnc21[37][2]; +extern const uint16_t c_aauiLCLDHuffEnc22[39][2]; +extern const uint16_t c_aauiLCLDHuffEnc23[46][2]; +extern const uint16_t c_aauiLCLDHuffEnc24[55][2]; +extern const uint16_t c_aauiLCLDHuffEnc25[65][2]; +extern const uint16_t c_aauiLCLDHuffEnc26[77][2]; +extern const uint16_t c_aauiLCLDHuffEnc27[91][2]; +extern const uint16_t c_aauiLCLDHuffEnc28[109][2]; +extern const uint16_t c_aauiLCLDHuffEnc29[129][2]; +extern const uint16_t c_aauiLCLDHuffEnc30[153][2]; +extern const uint16_t c_aauiLCLDHuffEnc31[181][2]; +extern const uint16_t c_aauiLCLDHuffEnc33[16][2]; +extern const uint16_t c_aauiLCLDHuffEnc34[16][2]; +extern const uint16_t c_aauiLCLDHuffEnc35[25][2]; +extern const uint16_t c_aauiLCLDHuffEnc36[36][2]; +extern const uint16_t c_aauiLCLDHuffEnc37[36][2]; +extern const uint16_t c_aauiLCLDHuffEnc38[49][2]; +extern const uint16_t c_aauiLCLDHuffEnc39[64][2]; +extern const uint16_t c_aauiLCLDHuffEnc40[81][2]; +extern const uint16_t c_aauiLCLDHuffEnc41[100][2]; +extern const uint16_t c_aauiLCLDHuffEnc42[169][2]; +extern const uint16_t c_aauiLCLDHuffEnc43[196][2]; +extern const uint16_t c_aauiLCLDHuffEnc44[289][2]; +extern const uint16_t c_aauiLCLDHuffEnc45[324][2]; +extern const uint16_t c_aauiLCLDHuffEnc46[400][2]; +extern const uint16_t c_aauiLCLDHuffEnc47[576][2]; +extern const uint16_t c_aauiLCLDHuffEnc48[729][2]; +extern const uint16_t c_aauiLCLDHuffEnc49[729][2]; +extern const uint16_t c_aauiLCLDHuffEnc50[28][2]; +extern const uint16_t c_aauiLCLDHuffEnc51[29][2]; +extern const uint16_t c_aauiLCLDHuffEnc52[32][2]; +extern const uint16_t c_aauiLCLDHuffEnc53[37][2]; +extern const uint16_t c_aauiLCLDHuffEnc54[39][2]; +extern const uint16_t c_aauiLCLDHuffEnc55[46][2]; +extern const uint16_t c_aauiLCLDHuffEnc56[55][2]; +extern const uint16_t c_aauiLCLDHuffEnc57[65][2]; +extern const uint16_t c_aauiLCLDHuffEnc58[77][2]; +extern const uint16_t c_aauiLCLDHuffEnc59[91][2]; +extern const uint16_t c_aauiLCLDHuffEnc60[109][2]; +extern const uint16_t c_aauiLCLDHuffEnc61[129][2]; +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 /* _TABLES_H_ */ diff --git a/lib_rend/ivas_limiter.c b/lib_rend/ivas_limiter.c index ae7e3afb8..0953e8a82 100644 --- a/lib_rend/ivas_limiter.c +++ b/lib_rend/ivas_limiter.c @@ -132,6 +132,9 @@ ivas_error ivas_limiter_open( hLimiter->release_heuristic = 0.f; hLimiter->attack_constant = powf( 0.01f, 1.0f / ( IVAS_LIMITER_ATTACK_SECONDS * sampling_rate ) ); hLimiter->strong_saturation_count = 0; +#ifdef DEBUGGING + hLimiter->cnt_frames_limited = 0; +#endif for ( i = 0; i < max_num_channels; ++i ) { @@ -291,6 +294,12 @@ void limiter_process( * ^ * React faster when release time should be increased */ +#ifdef DEBUGGING + if ( max_val > threshold ) + { + hLimiter->cnt_frames_limited++; + } +#endif } else { diff --git a/lib_rend/ivas_mcmasa_ana.c b/lib_rend/ivas_mcmasa_ana.c index d0dd9787d..7ed4aeb0d 100644 --- a/lib_rend/ivas_mcmasa_ana.c +++ b/lib_rend/ivas_mcmasa_ana.c @@ -40,6 +40,9 @@ #include "prot.h" #include "ivas_stat_rend.h" #include "ivas_rom_com.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" diff --git a/lib_rend/ivas_objectRenderer.c b/lib_rend/ivas_objectRenderer.c index 984f35ed3..a1e686020 100644 --- a/lib_rend/ivas_objectRenderer.c +++ b/lib_rend/ivas_objectRenderer.c @@ -36,8 +36,14 @@ #include "prot.h" #include "ivas_prot.h" #include "ivas_prot_rend.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT +#include "ivas_prot.h" +#endif #include #include "ivas_rom_com.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" @@ -281,7 +287,13 @@ ivas_error ivas_td_binaural_renderer_unwrap( const int16_t lfe_idx, /* i : LFE channel index */ const IVAS_FORMAT ivas_format, /* i : IVAS format */ ISM_METADATA_HANDLE *hIsmMetaData, /* i : ISM metadata handle */ +#ifdef NONBE_UNIFIED_DECODING_PATHS COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i/o: combined orientaton data handle */ +#else + const int16_t *enableCombinedOrientation, /* i : Combined orientation flag */ + const IVAS_QUATERNION *Quaternions, /* i : Head tracking data per subframe */ + const IVAS_VECTOR3 *Pos, /* i : Listener position data per subframe */ +#endif const int16_t ism_md_subframe_update, /* i : Number of subframes to delay ism metadata to sync with audio */ float *output[], /* i/o: SCE channels / Binaural synthesis */ const int16_t output_frame, /* i : output frame length */ @@ -295,10 +307,13 @@ ivas_error ivas_td_binaural_renderer_unwrap( int16_t c_indx, nS; float *p_reverb_signal[BINAURAL_CHANNELS]; int16_t ch; +#ifdef NONBE_UNIFIED_DECODING_PATHS int16_t *enableCombinedOrientation; /* i : Combined orientation flag */ IVAS_QUATERNION *Quaternions; /* i : Head tracking data per subframe */ IVAS_VECTOR3 *Pos; /* i : Listener position data per subframe */ +#endif +#ifdef NONBE_UNIFIED_DECODING_PATHS enableCombinedOrientation = NULL; Quaternions = NULL; Pos = NULL; @@ -308,6 +323,7 @@ ivas_error ivas_td_binaural_renderer_unwrap( Quaternions = hCombinedOrientationData->Quaternions; Pos = hCombinedOrientationData->listenerPos; } +#endif for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) { @@ -339,7 +355,11 @@ ivas_error ivas_td_binaural_renderer_unwrap( } /* Update the listener's location/orientation */ +#ifdef NONBE_UNIFIED_DECODING_PATHS if ( ( error = TDREND_Update_listener_orientation( hBinRendererTd, ( enableCombinedOrientation != NULL ) ? enableCombinedOrientation[hCombinedOrientationData->subframe_idx] : 0, ( Quaternions != NULL ) ? &Quaternions[hCombinedOrientationData->subframe_idx] : NULL, ( Pos != NULL ) ? &Pos[hCombinedOrientationData->subframe_idx] : NULL ) ) != IVAS_ERR_OK ) +#else + if ( ( error = TDREND_Update_listener_orientation( hBinRendererTd, ( enableCombinedOrientation != NULL ) ? enableCombinedOrientation[subframe_idx] : 0, ( Quaternions != NULL ) ? &Quaternions[subframe_idx] : NULL, ( Pos != NULL ) ? &Pos[subframe_idx] : NULL ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -369,8 +389,10 @@ ivas_error ivas_td_binaural_renderer_unwrap( } } +#ifdef NONBE_UNIFIED_DECODING_PATHS /* update combined orientation access index */ ivas_combined_orientation_update_index( hCombinedOrientationData, subframe_length ); +#endif } if ( hReverb != NULL ) @@ -744,7 +766,15 @@ ivas_error ivas_td_binaural_renderer_ext( hIsmMetaData[0]->non_diegetic_flag = currentPos->non_diegetic_flag; } +#ifdef NONBE_UNIFIED_DECODING_PATHS if ( ( error = ivas_td_binaural_renderer_unwrap( hReverb, transport_config, pTDRend->hBinRendererTd, num_src, lfe_idx, ivas_format, hIsmMetaData, *hCombinedOrientationData, +#else + if ( ( error = ivas_td_binaural_renderer_unwrap( hReverb, transport_config, pTDRend->hBinRendererTd, num_src, lfe_idx, ivas_format, hIsmMetaData, + + ( hCombinedOrientationData != NULL ) ? ( *hCombinedOrientationData )->enableCombinedOrientation : NULL, + ( hCombinedOrientationData != NULL ) ? ( *hCombinedOrientationData )->Quaternions : NULL, + ( hCombinedOrientationData != NULL ) ? ( *hCombinedOrientationData )->listenerPos : NULL, +#endif ism_md_subframe_update_ext, p_output, output_frame, (int16_t) ( ( output_frame * FRAMES_PER_SEC * MAX_PARAM_SPATIAL_SUBFRAMES ) / output_Fs ) ) ) != IVAS_ERR_OK ) { return error; @@ -756,6 +786,151 @@ ivas_error ivas_td_binaural_renderer_ext( } +#ifdef SPLIT_REND_WITH_HEAD_ROT +/*---------------------------------------------------------------------* + * ObjRenderIvasFrame_splitBinaural() + * + * Render to multiple binaural pairs based on relative head positions for split rendering. + *---------------------------------------------------------------------*/ + +ivas_error ObjRenderIvasFrame_splitBinaural( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + float *output[], /* i/o: SCE channels / Binaural synthesis */ + const int16_t output_frame /* i : output frame length */ +) +{ + int16_t i; + float tmpProcessing[MAX_OUTPUT_CHANNELS][L_FRAME48k]; + float tmpBinaural[MAX_HEAD_ROT_POSES * 2][L_FRAME48k]; + float *p_tmpProcessing[MAX_OUTPUT_CHANNELS]; + int16_t pos_idx; + IVAS_QUATERNION originalHeadRot[MAX_PARAM_SPATIAL_SUBFRAMES]; + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData; + BINAURAL_TD_OBJECT_RENDERER_HANDLE tmpTdRendHandle; + ivas_error error; + + push_wmops( "ObjRenderIvasFrame_splitBinaural" ); + pMultiBinPoseData = &st_ivas->hSplitBinRend.splitrend.multiBinPoseData; + + /* If not yet allocated, open additional instances of TD renderer */ + for ( i = 0; i < pMultiBinPoseData->num_poses - 1; ++i ) + { + if ( st_ivas->hSplitBinRend.splitrend.hTdRendHandles[i] != NULL ) + { + continue; + } + + if ( ( error = ivas_td_binaural_open_unwrap( &st_ivas->hHrtfTD, + st_ivas->hDecoderConfig->output_Fs, + st_ivas->nchan_transport, + st_ivas->ivas_format, + st_ivas->transport_config, + st_ivas->hRenderConfig->directivity, + st_ivas->hTransSetup, + &st_ivas->hSplitBinRend.splitrend.hTdRendHandles[i], + &st_ivas->binaural_latency_ns ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + /* Save current head positions */ + for ( i = 0; i < st_ivas->hCombinedOrientationData->num_subframes; ++i ) + { + originalHeadRot[i] = st_ivas->hCombinedOrientationData->Quaternions[i]; + } + + /* Copy input audio to a processing buffer. Cannot render in-place because binaurally rendered + * audio would overwrite original material, which is still needed for rendering next head pose. */ + for ( i = 0; i < st_ivas->nchan_transport; ++i ) + { + mvr2r( output[i], tmpProcessing[i], output_frame ); + } + + for ( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses; pos_idx++ ) + { + /* Update head positions */ + if ( pos_idx != 0 ) + { + for ( i = 0; i < st_ivas->hCombinedOrientationData->num_subframes; ++i ) + { + if ( originalHeadRot[i].w == -3.0f ) + { + st_ivas->hCombinedOrientationData->Quaternions[i].w = -3.0f; + st_ivas->hCombinedOrientationData->Quaternions[i].x = originalHeadRot[i].x + pMultiBinPoseData->relative_head_poses[pos_idx][0]; + st_ivas->hCombinedOrientationData->Quaternions[i].y = originalHeadRot[i].y + pMultiBinPoseData->relative_head_poses[pos_idx][1]; + st_ivas->hCombinedOrientationData->Quaternions[i].z = originalHeadRot[i].z + pMultiBinPoseData->relative_head_poses[pos_idx][2]; + } + else + { + st_ivas->hCombinedOrientationData->Quaternions[i].w = -3.0f; + + Quat2EulerDegree( originalHeadRot[i], /* TODO tmu : fix bug with ordering*/ + &st_ivas->hCombinedOrientationData->Quaternions[i].z, + &st_ivas->hCombinedOrientationData->Quaternions[i].y, + &st_ivas->hCombinedOrientationData->Quaternions[i].x ); + + st_ivas->hCombinedOrientationData->Quaternions[i].x += pMultiBinPoseData->relative_head_poses[pos_idx][0]; + st_ivas->hCombinedOrientationData->Quaternions[i].y += pMultiBinPoseData->relative_head_poses[pos_idx][1]; + st_ivas->hCombinedOrientationData->Quaternions[i].z += pMultiBinPoseData->relative_head_poses[pos_idx][2]; + } + } + } + + /* Handle the 1 ISM case where there is only one channel in the input buffer */ + for ( i = 0; i < max( st_ivas->nchan_transport, BINAURAL_CHANNELS ); ++i ) + { + p_tmpProcessing[i] = tmpProcessing[i]; + } + + /* Render */ + if ( pos_idx == 0 ) + { + if ( ( error = ivas_td_binaural_renderer( st_ivas, p_tmpProcessing, output_frame ) ) != IVAS_ERR_OK ) + { + return error; + } + } + else + { + /* Tmp swap renderer handles for rendering call */ + tmpTdRendHandle = st_ivas->hBinRendererTd; + st_ivas->hBinRendererTd = st_ivas->hSplitBinRend.splitrend.hTdRendHandles[pos_idx - 1]; + + if ( ( error = ivas_td_binaural_renderer( st_ivas, p_tmpProcessing, output_frame ) ) != IVAS_ERR_OK ) + { + return error; + } + + st_ivas->hBinRendererTd = tmpTdRendHandle; + } + + /* Copy rendered audio to tmp storage buffer. Copying directly to output would + * overwrite original audio, which is still needed for rendering next head pose. */ + mvr2r( tmpProcessing[0], tmpBinaural[2 * pos_idx], output_frame ); + mvr2r( tmpProcessing[1], tmpBinaural[2 * pos_idx + 1], output_frame ); + + /* Overwrite first 2 channels with original input audio again */ + mvr2r( output[0], tmpProcessing[0], output_frame ); + mvr2r( output[1], tmpProcessing[1], output_frame ); + } + + /* Copy from storage buffer to output */ + for ( i = 0; i < pMultiBinPoseData->num_poses * BINAURAL_CHANNELS; ++i ) + { + mvr2r( tmpBinaural[i], output[i], output_frame ); + } + + /* Restore original head rotation */ + for ( i = 0; i < st_ivas->hCombinedOrientationData->num_subframes; ++i ) + { + st_ivas->hCombinedOrientationData->Quaternions[i] = originalHeadRot[i]; + } + + pop_wmops(); + return IVAS_ERR_OK; +} +#endif /*---------------------------------------------------------------------* diff --git a/lib_rend/ivas_objectRenderer_mix.c b/lib_rend/ivas_objectRenderer_mix.c index cf1dba8b2..f65f6a452 100644 --- a/lib_rend/ivas_objectRenderer_mix.c +++ b/lib_rend/ivas_objectRenderer_mix.c @@ -38,6 +38,9 @@ #include "ivas_error.h" #include "wmc_auto.h" #include "ivas_rom_rend.h" +#ifdef DEBUGGING +#include "debug.h" +#endif /*-------------------------------------------------------------------* diff --git a/lib_rend/ivas_objectRenderer_sources.c b/lib_rend/ivas_objectRenderer_sources.c index 5d948cab8..2706a9c5c 100644 --- a/lib_rend/ivas_objectRenderer_sources.c +++ b/lib_rend/ivas_objectRenderer_sources.c @@ -36,6 +36,9 @@ #include "prot.h" #include "ivas_prot_rend.h" #include "wmc_auto.h" +#ifdef DEBUGGING +#include "debug.h" +#endif /*---------------------------------------------------------------------* diff --git a/lib_rend/ivas_objectRenderer_vec.c b/lib_rend/ivas_objectRenderer_vec.c index 0abde0389..061b790e1 100644 --- a/lib_rend/ivas_objectRenderer_vec.c +++ b/lib_rend/ivas_objectRenderer_vec.c @@ -36,6 +36,9 @@ #include "prot.h" #include "ivas_prot_rend.h" #include "wmc_auto.h" +#ifdef DEBUGGING +#include "debug.h" +#endif /*-------------------------------------------------------------------* diff --git a/lib_rend/ivas_omasa_ana.c b/lib_rend/ivas_omasa_ana.c index dd29384c6..16f0e0b5d 100644 --- a/lib_rend/ivas_omasa_ana.c +++ b/lib_rend/ivas_omasa_ana.c @@ -39,6 +39,9 @@ #include "prot.h" #include "ivas_stat_rend.h" #include "ivas_rom_com.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" diff --git a/lib_rend/ivas_orient_trk.c b/lib_rend/ivas_orient_trk.c index c540c9911..ff24510c5 100644 --- a/lib_rend/ivas_orient_trk.c +++ b/lib_rend/ivas_orient_trk.c @@ -36,6 +36,9 @@ #include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_cnst.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include #include "wmc_auto.h" diff --git a/lib_rend/ivas_output_init.c b/lib_rend/ivas_output_init.c index ae9312cff..795779800 100644 --- a/lib_rend/ivas_output_init.c +++ b/lib_rend/ivas_output_init.c @@ -37,6 +37,10 @@ #include "ivas_prot_rend.h" #include "ivas_rom_com.h" #include "ivas_prot.h" +#ifdef DEBUGGING +#include "debug.h" +#include +#endif #include "wmc_auto.h" /*-------------------------------------------------------------------------* @@ -88,6 +92,10 @@ int16_t audioCfg2channels( nchan_out = 8; break; case IVAS_AUDIO_CONFIG_BINAURAL: +#ifdef SPLIT_REND_WITH_HEAD_ROT + case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED: + case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM: +#endif case IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR: case IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB: nchan_out = 2; @@ -215,6 +223,10 @@ void ivas_output_init( hOutSetup->is_planar_setup = 0; break; case IVAS_AUDIO_CONFIG_BINAURAL: +#ifdef SPLIT_REND_WITH_HEAD_ROT + case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED: + case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM: +#endif case IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR: case IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB: case IVAS_AUDIO_CONFIG_ISM1: @@ -226,6 +238,10 @@ void ivas_output_init( /* Default values are used */ break; default: +#ifdef DEBUGGING + /* error */ + assert( !"Error: Unknown output setup!\n" ); +#endif return; } } @@ -262,7 +278,11 @@ int16_t ivas_get_nchan_buffers_dec( if ( st_ivas->ivas_format == MONO_FORMAT ) { +#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX nchan_out_buff = st_ivas->hDecoderConfig->nchan_out; +#else + nchan_out_buff = 0; +#endif } else if ( st_ivas->ivas_format == STEREO_FORMAT ) { @@ -307,10 +327,16 @@ int16_t ivas_get_nchan_buffers_dec( { nchan_out_buff = max( nchan_out_buff, st_ivas->hOutSetup.nchan_out_woLFE + st_ivas->hOutSetup.num_lfe ); } +#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX +#ifdef SPLIT_REND_WITH_HEAD_ROT + else if ( output_config == IVAS_AUDIO_CONFIG_STEREO || output_config == IVAS_AUDIO_CONFIG_BINAURAL || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) +#else else if ( output_config == IVAS_AUDIO_CONFIG_STEREO || output_config == IVAS_AUDIO_CONFIG_BINAURAL || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) +#endif { nchan_out_buff = 2 * CPE_CHANNELS; } +#endif else if ( output_config != IVAS_AUDIO_CONFIG_EXTERNAL ) { nchan_out_buff = max( nchan_out_buff, audioCfg2channels( st_ivas->intern_config ) ); @@ -386,6 +412,12 @@ int16_t ivas_get_nchan_buffers_dec( } } +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { + nchan_out_buff = max( nchan_out_buff, st_ivas->hSplitBinRend.splitrend.multiBinPoseData.num_poses * BINAURAL_CHANNELS ); + } +#endif return nchan_out_buff; } diff --git a/lib_rend/ivas_prot_rend.h b/lib_rend/ivas_prot_rend.h index ef1e6f7f3..0bd5a09f5 100644 --- a/lib_rend/ivas_prot_rend.h +++ b/lib_rend/ivas_prot_rend.h @@ -221,6 +221,15 @@ void ivas_dirac_dec_binaural_sba_gain( const int16_t output_frame /* i : output frame length */ ); +#ifndef NONBE_UNIFIED_DECODING_PATHS +void ivas_dirac_dec_binaural( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i : combined orientation handle */ + float *output_f[], /* i/o: synthesized core-coder transport channels/DirAC output */ + const int16_t nchan_transport, /* i : number of transport channels */ + const int16_t num_subframes /* i : number of subframes to render */ +); +#endif void ivas_dirac_dec_binaural_render( Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ const uint16_t nSamplesAsked, /* i : number of CLDFB slots requested */ @@ -234,7 +243,14 @@ void ivas_masa_ext_rend_parambin_render( MASA_EXT_REND_HANDLE hMasaExtRend, /* i/o: MASA ext rend structure */ COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i : combined orientation handle */ float *output_f[], /* i/o: synthesized core-coder transport channels/DirAC output */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + const int16_t num_subframes, /* i : number of subframes to render */ + const SPLIT_REND_WRAPPER *hSplitRendWrapper, /* i : split rendering orientation data */ + float Cldfb_Out_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* o : rendered orientations for split rend. real part of cldfb */ + float Cldfb_Out_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX] /* o : rendered orientations for split rend. imag part of cldfb */ +#else const int16_t num_subframes /* i : number of subframes to render */ +#endif ); ivas_error ivas_dirac_dec_init_binaural_data( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ @@ -622,7 +638,13 @@ ivas_error ivas_td_binaural_renderer_unwrap( const int16_t lfe_idx, /* i : LFE channel index */ const IVAS_FORMAT ivas_format, /* i : IVAS format */ ISM_METADATA_HANDLE *hIsmMetaData, /* i : ISM metadata handle */ +#ifdef NONBE_UNIFIED_DECODING_PATHS COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i/o: combined orientaton data handle */ +#else + const int16_t *enableCombinedOrientation, /* i : Combined orientation flag */ + const IVAS_QUATERNION *Quaternions, /* i : Head tracking data per subframe */ + const IVAS_VECTOR3 *Pos, /* i : Listener position data per subframe */ +#endif const int16_t ism_md_subframe_update, float *output[], /* i/o: SCE channels / Binaural synthesis */ const int16_t output_frame, /* i : output frame length */ @@ -881,11 +903,21 @@ ivas_error ivas_rend_openCrend( const AUDIO_CONFIG outConfig, RENDER_CONFIG_DATA *hRendCfg, HRTFS_CREND_HANDLE hSetOfHRTF, +#ifdef SPLIT_REND_WITH_HEAD_ROT + const int32_t output_Fs, + const int16_t num_poses +#else const int32_t output_Fs +#endif ); void ivas_rend_closeCrend( +#ifdef SPLIT_REND_WITH_HEAD_ROT + CREND_WRAPPER_HANDLE *pCrend , + const int16_t num_poses +#else CREND_WRAPPER_HANDLE *pCrend +#endif ); ivas_error ivas_hrtf_init( @@ -893,7 +925,12 @@ ivas_error ivas_hrtf_init( ); ivas_error ivas_rend_initCrendWrapper( +#ifdef SPLIT_REND_WITH_HEAD_ROT + CREND_WRAPPER_HANDLE *pCrend, + const int16_t num_poses +#else CREND_WRAPPER_HANDLE *pCrend +#endif ); ivas_error ivas_rend_crendProcess( @@ -906,7 +943,12 @@ ivas_error ivas_rend_crendProcess( EFAP_HANDLE hEFAPdata, float *output[], /* i/o: input/output audio channels */ const int32_t output_Fs, +#ifdef SPLIT_REND_WITH_HEAD_ROT + const int16_t num_subframes, /* i : number of subframes to render */ + const int16_t pos_idx /* i : pose index */ +#else const int16_t num_subframes /* i : number of subframes to render */ +#endif ); ivas_error ivas_rend_crendProcessSubframe( @@ -922,6 +964,12 @@ ivas_error ivas_rend_crendProcessSubframe( float *output[], /* i/o: input/output audio channels */ const int16_t n_samples_to_render, /* i : output frame length per channel */ const int32_t output_Fs /* i : output sampling rate */ +#ifdef NONBE_UNIFIED_DECODING_PATHS +#ifdef SPLIT_REND_WITH_HEAD_ROT + , + const int16_t pos_idx +#endif +#endif ); @@ -1244,6 +1292,14 @@ void QuatToRotMat( float Rmat[3][3] /* o : real-space rotation matrix for this rotation */ ); +#ifdef SPLIT_REND_WITH_HEAD_ROT +void Quat2EulerDegree( + const IVAS_QUATERNION quat, /* i : quaternion describing the rotation */ + float *yaw, /* o : yaw */ + float *pitch, /* o : pitch */ + float *roll /* o : roll */ +); +#endif void rotateAziEle( float azi_in, /* i : output elevation */ @@ -1277,6 +1333,7 @@ void rotateFrame_sd( const int16_t subframe_idx /* i : subframe index */ ); +#ifdef NONBE_UNIFIED_DECODING_PATHS void ivas_combined_orientation_update_index( COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i/o: combined orientation handle */ const int16_t samples_rendered /* i : samples rendered since the last call */ @@ -1290,6 +1347,7 @@ void ivas_combined_orientation_update_start_index( void ivas_combined_orientation_set_to_start_index( COMBINED_ORIENTATION_HANDLE hCombinedOrientationData /* i/o: combined orientation handle */ ); +#endif void rotateFrame_shd_cldfb( float Cldfb_RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i/o: unrotated HOA3 signal buffer in cldfb domain real part */ @@ -1321,7 +1379,9 @@ void ivas_external_orientation_close( ivas_error ivas_combined_orientation_open( COMBINED_ORIENTATION_HANDLE *hCombinedOrientationData, /* o : combined orientation handle */ +#ifdef NONBE_UNIFIED_DECODING_PATHS const int32_t fs, /* i : sampling rate */ +#endif const int16_t num_subframes /* i : number of subframes */ ); @@ -1422,6 +1482,232 @@ ivas_error ivas_orient_trk_Process( IVAS_QUATERNION *pTrkRot /* o : tracked rotation */ ); +#ifdef SPLIT_REND_WITH_HEAD_ROT +void ivas_set_split_rend_ht_setup( + IVAS_DEC_SPLIT_REND_WRAPPER *hSplitBinRend, + COMBINED_ORIENTATION_HANDLE hCombinedOrientationData +); + +/*----------------------------------------------------------------------------------* + * Split binaural renderer prototypes + *----------------------------------------------------------------------------------*/ + +void ivas_set_split_rend_ht_setup( + IVAS_DEC_SPLIT_REND_WRAPPER *hSplitBinRend, + COMBINED_ORIENTATION_HANDLE hCombinedOrientationData +); + +ivas_error ivas_set_split_rend_setup( + IVAS_DEC_SPLIT_REND_WRAPPER *hSplitBinRend, + IVAS_SPLIT_REND_CONFIG_DATA *hSplitBinConfig, + COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i/o: combined orientation handle */ + uint8_t *splitRendBitsBuf +); + +void ivas_init_split_rend_handles( + SPLIT_REND_WRAPPER *hSplitRendWrapper +); + +void ivas_init_split_post_rend_handles( + SPLIT_POST_REND_WRAPPER *hSplitRendWrapper +); + +ivas_error ivas_split_renderer_open( + SPLIT_REND_WRAPPER *hSplitBinRend, + const IVAS_SPLIT_REND_CONFIG_DATA *pSplitRendConfig, + const int32_t output_Fs, + const int16_t cldfb_in_flag, + const int16_t pcm_out_flag, + const int16_t is_5ms_frame +); + +void ivas_split_renderer_close( + SPLIT_REND_WRAPPER *hSplitBinRend +); + +ivas_error ivas_splitBinLCLDEncOpen( + BIN_HR_SPLIT_LCLD_ENC_HANDLE *hSplitBinLCLDEnc, + const int32_t iSampleRate, + const int16_t iChannels, + const int32_t iDataRate +); + +void ivas_splitBinLCLDEncClose( + BIN_HR_SPLIT_LCLD_ENC_HANDLE *hSplitBinLCLDEnc +); + +void ivas_splitBinLCLDEncProcess( + 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, + IVAS_SPLIT_REND_BITS_HANDLE pBits +); + +ivas_error ivas_splitBinLCLDDecOpen( + BIN_HR_SPLIT_LCLD_DEC_HANDLE *hSplitBinLCLDDec, + const int32_t iSampleRate, + const int16_t iChannels +); + +void ivas_splitBinLCLDDecClose( + BIN_HR_SPLIT_LCLD_DEC_HANDLE *hSplitBinLCLDDec +); + +void ivas_splitBinLCLDDecProcess( + BIN_HR_SPLIT_LCLD_DEC_HANDLE hSplitBinLCLDDec, + IVAS_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 +); + +ivas_error ivas_splitBinPreRendOpen( + 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 +); + +ivas_error ivas_splitBinPostRendOpen( + BIN_HR_SPLIT_POST_REND_HANDLE *hBinHrSplitPostRend, + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + const int32_t output_Fs +); + +void ivas_init_multi_bin_pose_data( + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData +); + +void ivas_renderSplitGetMultiBinPoseData( + const IVAS_SPLIT_REND_CONFIG_DATA *pSplit_rend_config, + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + const IVAS_SPLIT_REND_ROT_AXIS rot_axis +); + +void ivas_renderSplitUpdateNoCorrectionPoseData( + const IVAS_SPLIT_REND_CONFIG_DATA *pSplit_rend_config, + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData +); + +ivas_error ivas_renderMultiBinToSplitBinaural( + SPLIT_REND_WRAPPER *hSplitBin, + const IVAS_QUATERNION headPosition, + const int32_t SplitRendBitRate, + IVAS_SPLIT_REND_CODEC splitCodec, + int16_t codec_frame_size_ms, + IVAS_SPLIT_REND_BITS_HANDLE pBits, + float Cldfb_In_BinReal[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + float Cldfb_In_BinImag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + const int16_t max_bands, + float *output[], + const int16_t low_res_pre_rend_rot, + const int16_t cldfb_in_flag, + const int16_t pcm_out_flag +); + +void ivas_rend_CldfbSplitPreRendProcess( + const 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], + IVAS_SPLIT_REND_BITS_HANDLE pBits, + const int32_t target_md_bits, + const int16_t low_res_pre_rend_rot +); + +void ivas_rend_CldfbSplitPostRendProcess( + 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 +); + +void ivas_splitBinPreRendClose( + BIN_HR_SPLIT_PRE_REND_HANDLE *hBinHrSplitPreRend +); + +void ivas_splitBinPostRendClose( + BIN_HR_SPLIT_POST_REND_HANDLE *hBinHrSplitPostRend ); + +void ivas_splitBinPostRendMdDec( + IVAS_SPLIT_REND_BITS_HANDLE pBits, + BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend, +#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 +); + +ivas_error ivas_splitBinRendPLCOpen( + SPLIT_REND_PLC_HANDLE* phSplitRendPLC +); + +void ivas_splitBinRendPLCClose( + SPLIT_REND_PLC_HANDLE* phSplitRendPLC +); + +void ivas_splitBinRendPLCsaveState( + 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 +); + +void ivas_splitBinRendPLC_xf( + 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 +); + +void ivas_splitBinRendPLC( + 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 +); + +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG +void ivas_log_cldfb2wav_data( + float Cldfb_In_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + float Cldfb_In_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + HANDLE_CLDFB_FILTER_BANK *cldfbSyn, + const int16_t num_chs, + const int16_t num_freq_bands, + const int32_t output_Fs, + const int16_t start_slot_idx, + const int16_t md_band_idx, + const char *filename +); +#endif + +void ivas_SplitRenderer_GetRotMd( + 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 +); + +void ivas_SplitRenderer_PostRenderer( + 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 +); + +#endif /*----------------------------------------------------------------------------------* * Rendering & merging to MASA format @@ -1532,6 +1818,204 @@ void masaPrerendClose( ); +#ifdef SPLIT_REND_WITH_HEAD_ROT +/*----------------------------------------------------------------------------------* + * Split rendering + *----------------------------------------------------------------------------------*/ + +/* TODO(sgi): Rework interface */ +ivas_error ObjRenderIvasFrame_splitBinaural( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + float *output[], /* i/o: SCE channels / Binaural synthesis */ + const int16_t output_frame /* i : output frame length */ +); + +#ifdef NONBE_UNIFIED_DECODING_PATHS +ivas_error ivas_td_binaural_renderer_sf_splitBinaural( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + float *output[], /* i/o: SCE channels / Binaural synthesis */ + int16_t nSamplesRendered /* i : number of samples to render */ +); + +ivas_error ivas_rend_crendProcessSubframesSplitBin( + const CREND_WRAPPER *pCrend, /* i/o: Crend wrapper handle */ + const AUDIO_CONFIG inConfig, /* i : input audio configuration */ + const AUDIO_CONFIG outConfig, /* i : output audio configuration */ + const MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + const DECODER_CONFIG_HANDLE hDecoderConfig, /* i : decoder config. structure */ + const COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i : combined orientation handle */ + const IVAS_OUTPUT_SETUP_HANDLE hIntSetup, /* i : internal setup handle */ + const EFAP_HANDLE hEFAPdata, /* i : EFAP handle */ + DECODER_TC_BUFFER_HANDLE hTcBuffer, /* i/o: JBM handle */ + float *input_f[], /* i : transport channels */ + float *output[], /* i/o: input/output audio channels */ + const int16_t n_samples_to_render, /* i : output frame length per channel */ + const int32_t output_Fs /* i : output sampling rate */ +); +#endif + +ivas_error ivas_rend_crendProcessSplitBin( + const CREND_WRAPPER *pCrend, + const AUDIO_CONFIG inConfig, + const AUDIO_CONFIG outConfig, + const MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + DECODER_CONFIG_HANDLE hDecoderConfig, + COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, + const IVAS_OUTPUT_SETUP_HANDLE hIntSetup, + EFAP_HANDLE hEFAPdata, + float *output[], + const int32_t output_Fs +); + +ivas_error ivas_rend_openMultiBinCrend( + CREND_WRAPPER_HANDLE *pCrend, + const AUDIO_CONFIG inConfig, + const AUDIO_CONFIG outConfig, + const MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + const int32_t output_Fs +); + +void ivas_rend_CldfbMultiBinRendProcess( + const BINAURAL_RENDERER_HANDLE hCldfbRend, + const COMBINED_ORIENTATION_HANDLE *pCombinedOrientationData, + const MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + float Cldfb_In_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + float Cldfb_In_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + float Cldfb_Out_Real[MAX_HEAD_ROT_POSES*BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* o : Binaural signals */ + float Cldfb_Out_Imag[MAX_HEAD_ROT_POSES*BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + const int16_t low_res_pre_rend_rot, + const int16_t num_subframes +); + +ivas_error ivas_rend_openCldfb( + HANDLE_CLDFB_FILTER_BANK cldfbAna[MAX_INPUT_CHANNELS], + const AUDIO_CONFIG inConfig, + const int32_t output_Fs +); + +ivas_error ivas_rend_openCldfbRend( + CLDFB_REND_WRAPPER *pCldfbRend, + const AUDIO_CONFIG inConfig, + const AUDIO_CONFIG outConfig, + const MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + const int32_t output_Fs +); + +void ivas_mat_mult_2by2_complex( + float in_re1[2][2], + float in_im1[2][2], + float in_re2[2][2], + float in_im2[2][2], + float out_re2[2][2], + float out_im2[2][2] +); + +void ivas_split_rend_bitstream_init( + IVAS_SPLIT_REND_BITS_HANDLE pBits, + const int32_t buf_len_bytes, uint8_t *pbuf +); + +void ivas_split_rend_huffman_dec_init_min_max_len( + ivas_split_rend_huffman_cfg_t *p_huff_cfg +); + +void ivas_split_rend_init_huff_cfg( + BIN_HR_SPLIT_REND_HUFF_HANDLE pHuff_cfg ); + +void set_fix_rotation_mat( + float fix_pos_rot_mat[][BINAURAL_CHANNELS][BINAURAL_CHANNELS], + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData +); + +void set_pose_types( + IVAS_SPLIT_REND_POSE_TYPE pose_type[MAX_HEAD_ROT_POSES - 1], + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData +); + +int16_t wrap_a( + int16_t val, + const int16_t min_val, + const int16_t max_val +); + +void ivas_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 +); + +void ivas_split_rend_bitstream_write_int32( + IVAS_SPLIT_REND_BITS_HANDLE pBits, + const int32_t val, + const int32_t bits +); + +int32_t ivas_split_rend_bitstream_read_int32( + IVAS_SPLIT_REND_BITS_HANDLE pBits, + const int32_t bits +); + + +void ivas_rend_closeCldfbRend( + CLDFB_REND_WRAPPER *pCldfbRend +); + +int32_t ivas_get_lcld_bitrate( + const int32_t SplitRendBitRate, + const IVAS_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode +); + +int32_t ivas_get_split_rend_md_target_brate( + const int32_t SplitRendBitRate, + const int16_t pcm_out_flag +); + +int32_t ivas_get_lc3plus_bitrate( + const int32_t SplitRendBitRate, + const IVAS_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode, + const int16_t split_prerender_frame_size_ms +); + +int8_t ivas_get_lc3plus_bitrate_id( + const int32_t SplitRendBitRate +); + +int32_t ivas_get_lc3plus_size_from_id( + const int8_t SplitRendBitRateId, + const IVAS_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode, + const int16_t split_prerender_frame_size_ms +); + +ivas_error ivas_split_rend_validate_config( + const IVAS_SPLIT_REND_CONFIG_DATA *pSplitRendConfig, + const int16_t pcm_out_flag +); + +void ivas_split_rend_get_quant_params( + const int16_t num_md_bands, + int16_t pred_real_bands_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], + int16_t pred_imag_bands_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], + int16_t pred_quant_pnts_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], + float pred_quantstep_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], + float pred_1byquantstep_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], + int16_t d_bands_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], + int16_t bands_pitch[IVAS_SPLIT_REND_NUM_QUANT_STRATS], + int16_t pred_real_bands_roll[IVAS_SPLIT_REND_NUM_QUANT_STRATS], + int16_t pred_imag_bands_roll[IVAS_SPLIT_REND_NUM_QUANT_STRATS], + int16_t *num_quant_strats, + int16_t *num_complex_bands +); + +ivas_error ivas_split_rend_choose_default_codec( + IVAS_SPLIT_REND_CODEC *pCodec, /* i/o: pointer to codec setting */ + 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 CLDFB */ + const int16_t pcm_out_flag /* i : flag to indicate PCM output */ +); + +#endif /* clang-format on */ diff --git a/lib_rend/ivas_reflections.c b/lib_rend/ivas_reflections.c index d5742624c..47143e20c 100644 --- a/lib_rend/ivas_reflections.c +++ b/lib_rend/ivas_reflections.c @@ -42,6 +42,9 @@ #include "ivas_prot.h" #include "ivas_rom_com.h" #include "wmc_auto.h" +#ifdef DEBUGGING +#include "debug.h" +#endif /*-----------------------------------------------------------------------------------------* diff --git a/lib_rend/ivas_render_config.c b/lib_rend/ivas_render_config.c index 7eeaaa54c..c7a1abacf 100644 --- a/lib_rend/ivas_render_config.c +++ b/lib_rend/ivas_render_config.c @@ -36,6 +36,9 @@ #include "ivas_prot_rend.h" #include "ivas_rom_rend.h" #include "ivas_rom_TdBinauralRenderer.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" @@ -106,6 +109,9 @@ ivas_error ivas_render_config_init_from_rom( { return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "Unexpected null pointer while attempting to fill renderer configuration from ROM" ); } +#ifdef DEBUGGING + ( *hRenderConfig )->renderer_type_override = IVAS_RENDER_TYPE_OVERRIDE_NONE; +#endif ( *hRenderConfig )->roomAcoustics.override = FALSE; ( *hRenderConfig )->roomAcoustics.nBands = IVAS_REVERB_DEFAULT_N_BANDS; ( *hRenderConfig )->roomAcoustics.acousticPreDelay = IVAS_REVERB_DEFAULT_PRE_DELAY; @@ -125,6 +131,16 @@ ivas_error ivas_render_config_init_from_rom( ( *hRenderConfig )->directivity[i * 3 + 1] = 360.0f; /* Back cone */ ( *hRenderConfig )->directivity[i * 3 + 2] = 1.0f; /* Back attenuation */ } +#ifdef SPLIT_REND_WITH_HEAD_ROT + ( *hRenderConfig )->split_rend_config.splitRendBitRate = SPLIT_REND_768k; + ( *hRenderConfig )->split_rend_config.dof = 3; + ( *hRenderConfig )->split_rend_config.hq_mode = 0; + ( *hRenderConfig )->split_rend_config.codec_delay_ms = 0; + ( *hRenderConfig )->split_rend_config.codec_frame_size_ms = 0; /* 0 means "use default for selected codec" */ + ( *hRenderConfig )->split_rend_config.codec = IVAS_SPLIT_REND_CODEC_DEFAULT; + ( *hRenderConfig )->split_rend_config.poseCorrectionMode = IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB; + ( *hRenderConfig )->split_rend_config.rendererSelection = IVAS_SPLIT_REND_RENDERER_SELECTION_DEFAULT; +#endif return IVAS_ERR_OK; } diff --git a/lib_rend/ivas_reverb.c b/lib_rend/ivas_reverb.c index cf61669c9..537ecde2c 100644 --- a/lib_rend/ivas_reverb.c +++ b/lib_rend/ivas_reverb.c @@ -35,6 +35,9 @@ #include "prot.h" #include "ivas_prot_rend.h" #include "ivas_cnst.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "math.h" #include "ivas_rom_rend.h" #include @@ -1167,6 +1170,9 @@ ivas_error ivas_reverb_open( set_reverb_acoustic_data( ¶ms, input_audio_config, hHrtf, &hRenderConfig->roomAcoustics, subframe_len, nr_fc_input, nr_fc_fft_filter ); /* set reverb acoustic configuration based on renderer config */ +#ifdef DEBUGGING + pState->pConfig.renderer_type_override = hRenderConfig->renderer_type_override; +#endif pState->pConfig.roomAcoustics.override = hRenderConfig->roomAcoustics.override; pState->pConfig.roomAcoustics.nBands = hRenderConfig->roomAcoustics.nBands; diff --git a/lib_rend/ivas_reverb_delay_line.c b/lib_rend/ivas_reverb_delay_line.c index 64271ae15..a91551f71 100644 --- a/lib_rend/ivas_reverb_delay_line.c +++ b/lib_rend/ivas_reverb_delay_line.c @@ -35,6 +35,9 @@ #include "ivas_prot.h" #include "ivas_prot_rend.h" #include "prot.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" diff --git a/lib_rend/ivas_reverb_fft_filter.c b/lib_rend/ivas_reverb_fft_filter.c index b1ae53ae7..8b14d2d41 100644 --- a/lib_rend/ivas_reverb_fft_filter.c +++ b/lib_rend/ivas_reverb_fft_filter.c @@ -34,6 +34,9 @@ #include "options.h" #include "prot.h" #include "ivas_prot_rend.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include "wmc_auto.h" diff --git a/lib_rend/ivas_reverb_filter_design.c b/lib_rend/ivas_reverb_filter_design.c index 3bd53cdb4..2c4dc7530 100644 --- a/lib_rend/ivas_reverb_filter_design.c +++ b/lib_rend/ivas_reverb_filter_design.c @@ -34,6 +34,9 @@ #include "options.h" #include "prot.h" #include "ivas_prot_rend.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include #include #include diff --git a/lib_rend/ivas_reverb_iir_filter.c b/lib_rend/ivas_reverb_iir_filter.c index bf326e09b..ce73c9d86 100644 --- a/lib_rend/ivas_reverb_iir_filter.c +++ b/lib_rend/ivas_reverb_iir_filter.c @@ -34,6 +34,9 @@ #include "options.h" #include "prot.h" #include "ivas_prot_rend.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" diff --git a/lib_rend/ivas_reverb_utils.c b/lib_rend/ivas_reverb_utils.c index 3bdc9b2af..23d7592ce 100644 --- a/lib_rend/ivas_reverb_utils.c +++ b/lib_rend/ivas_reverb_utils.c @@ -36,6 +36,9 @@ #include "ivas_prot_rend.h" #include "ivas_rom_rend.h" #include +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" diff --git a/lib_rend/ivas_rom_TdBinauralRenderer.c b/lib_rend/ivas_rom_TdBinauralRenderer.c index a84f26198..c3c8ae118 100644 --- a/lib_rend/ivas_rom_TdBinauralRenderer.c +++ b/lib_rend/ivas_rom_TdBinauralRenderer.c @@ -34,6 +34,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "ivas_cnst.h" #include "wmc_auto.h" diff --git a/lib_rend/ivas_rom_TdBinauralRenderer.h b/lib_rend/ivas_rom_TdBinauralRenderer.h index 8e113b040..e60a72783 100644 --- a/lib_rend/ivas_rom_TdBinauralRenderer.h +++ b/lib_rend/ivas_rom_TdBinauralRenderer.h @@ -32,6 +32,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "ivas_cnst.h" diff --git a/lib_rend/ivas_rom_binauralRenderer.c b/lib_rend/ivas_rom_binauralRenderer.c index cc77cc46c..5708cc7e6 100644 --- a/lib_rend/ivas_rom_binauralRenderer.c +++ b/lib_rend/ivas_rom_binauralRenderer.c @@ -32,6 +32,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "ivas_cnst.h" #include "wmc_auto.h" diff --git a/lib_rend/ivas_rom_binauralRenderer.h b/lib_rend/ivas_rom_binauralRenderer.h index 656bc44b8..97ec8f390 100644 --- a/lib_rend/ivas_rom_binauralRenderer.h +++ b/lib_rend/ivas_rom_binauralRenderer.h @@ -32,6 +32,9 @@ #include #include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "cnst.h" #include "ivas_cnst.h" diff --git a/lib_rend/ivas_rom_rend.c b/lib_rend/ivas_rom_rend.c index 4a5bb177f..99ffe4428 100644 --- a/lib_rend/ivas_rom_rend.c +++ b/lib_rend/ivas_rom_rend.c @@ -32,6 +32,9 @@ #include "options.h" #include +#ifdef DEBUGGING +#include "debug.h" +#endif #include "ivas_rom_rend.h" /* clang-format off */ diff --git a/lib_rend/ivas_rom_rend.h b/lib_rend/ivas_rom_rend.h index 9e7d0b889..165f4791c 100644 --- a/lib_rend/ivas_rom_rend.h +++ b/lib_rend/ivas_rom_rend.h @@ -35,6 +35,9 @@ #include "options.h" #include +#ifdef DEBUGGING +#include "debug.h" +#endif #include "ivas_cnst.h" #include "ivas_stat_rend.h" @@ -145,5 +148,12 @@ extern const float ls_conversion_cicpX_stereo[12][2]; extern const LS_CONVERSION_MAPPING ls_conversion_mapping[]; +#ifdef SPLIT_REND_WITH_HEAD_ROT +/*----------------------------------------------------------------------------------* + * Split binaural rendering ROM tables + *----------------------------------------------------------------------------------*/ + +extern const int32_t split_rend_brate_tbl[]; +#endif #endif /* IVAS_ROM_REND_H */ diff --git a/lib_rend/ivas_rotation.c b/lib_rend/ivas_rotation.c index bda768ca4..7c4bdd94b 100644 --- a/lib_rend/ivas_rotation.c +++ b/lib_rend/ivas_rotation.c @@ -38,6 +38,9 @@ #include "cnst.h" #include "prot.h" #include "ivas_prot_rend.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" @@ -48,6 +51,9 @@ static ivas_error combine_external_and_head_orientations( IVAS_QUATERNION *headRotQuaternions, IVAS_VECTOR3 *listenerPos, +#ifdef SPLIT_REND_WITH_HEAD_ROT + IVAS_SPLIT_REND_ROT_AXIS sr_pose_pred_axis, /* i : split rend pose prediction axis*/ +#endif EXTERNAL_ORIENTATION_HANDLE hExtOrientationData, COMBINED_ORIENTATION_HANDLE hCombinedOrientationData ); @@ -99,6 +105,9 @@ ivas_error ivas_headTrack_open( ( *hHeadTrackData )->Rmat_prev[i][i] = 1.0f; } +#ifdef SPLIT_REND_WITH_HEAD_ROT + ( *hHeadTrackData )->sr_pose_pred_axis = DEFAULT_AXIS; +#endif set_zero( ( *hHeadTrackData )->chEneIIR[0], MASA_FREQUENCY_BANDS ); set_zero( ( *hHeadTrackData )->chEneIIR[1], MASA_FREQUENCY_BANDS ); @@ -148,6 +157,16 @@ void QuatToRotMat( float Rmat[3][3] /* o : real-space rotation matrix for this rotation */ ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( quat.w == -3.0 ) + { + IVAS_QUATERNION quat_local; + Euler2Quat( deg2rad( quat.x ), deg2rad( quat.y ), deg2rad( quat.z ), &quat_local ); + QuatToRotMat( quat_local, Rmat ); + } + else + { +#endif Rmat[0][0] = quat.w * quat.w + quat.x * quat.x - quat.y * quat.y - quat.z * quat.z; Rmat[0][1] = 2.0f * ( quat.x * quat.y - quat.w * quat.z ); Rmat[0][2] = 2.0f * ( quat.x * quat.z + quat.w * quat.y ); @@ -159,6 +178,9 @@ void QuatToRotMat( Rmat[2][0] = 2.0f * ( quat.x * quat.z - quat.w * quat.y ); Rmat[2][1] = 2.0f * ( quat.y * quat.z + quat.w * quat.x ); Rmat[2][2] = quat.w * quat.w - quat.x * quat.x - quat.y * quat.y + quat.z * quat.z; +#ifdef SPLIT_REND_WITH_HEAD_ROT + } +#endif return; } @@ -192,6 +214,48 @@ void Euler2Quat( } +#ifdef SPLIT_REND_WITH_HEAD_ROT +/*------------------------------------------------------------------------- + * Quat2EulerDegree() + * + * Quaternion handling: calculate corresponding Euler angles in degrees + *------------------------------------------------------------------------*/ + +void Quat2EulerDegree( + const IVAS_QUATERNION quat, /* i : quaternion describing the rotation */ + float *yaw, /* o : yaw */ + float *pitch, /* o : pitch */ + float *roll /* o : roll */ +) +{ + 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; + } + 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 = quat.z; + *pitch = quat.y; + *roll = quat.x; + } + + return; +} +#endif /*------------------------------------------------------------------------- @@ -324,9 +388,17 @@ void rotateFrame_shd( } /* calculate ambisonics rotation matrices for the previous and current frames */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + SHrotmatgen( SHrotmat_prev, hCombinedOrientationData->Rmat_prev[0], shd_rot_max_order ); +#else SHrotmatgen( SHrotmat_prev, hCombinedOrientationData->Rmat_prev, shd_rot_max_order ); +#endif +#ifdef NONBE_UNIFIED_DECODING_PATHS SHrotmatgen( SHrotmat, hCombinedOrientationData->Rmat[hCombinedOrientationData->subframe_idx], shd_rot_max_order ); +#else + SHrotmatgen( SHrotmat, hCombinedOrientationData->Rmat[subframe_idx], shd_rot_max_order ); +#endif for ( i = 0; i < subframe_len; i++ ) { @@ -380,8 +452,16 @@ void rotateFrame_shd( for ( i = 0; i < 3; i++ ) { mvr2r( +#ifdef NONBE_UNIFIED_DECODING_PATHS hCombinedOrientationData->Rmat[hCombinedOrientationData->subframe_idx][i], +#else + hCombinedOrientationData->Rmat[subframe_idx][i], +#endif +#ifdef SPLIT_REND_WITH_HEAD_ROT + hCombinedOrientationData->Rmat_prev[0][i], +#else hCombinedOrientationData->Rmat_prev[i], +#endif 3 ); } @@ -447,7 +527,11 @@ void rotateFrame_sd( ch_in_woLFE = ( ch_in >= index_lfe ) ? ch_in - 1 : ch_in; /* gains for previous subframe rotation */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + rotateAziEle( hTransSetup.ls_azimuth[ch_in_woLFE], hTransSetup.ls_elevation[ch_in_woLFE], &azimuth, &elevation, hCombinedOrientationData->Rmat_prev[0], hTransSetup.is_planar_setup ); +#else rotateAziEle( hTransSetup.ls_azimuth[ch_in_woLFE], hTransSetup.ls_elevation[ch_in_woLFE], &azimuth, &elevation, hCombinedOrientationData->Rmat_prev, hTransSetup.is_planar_setup ); +#endif if ( hEFAPdata != NULL && ( hTransSetup.ls_azimuth[ch_in_woLFE] != azimuth || hTransSetup.ls_elevation[ch_in_woLFE] != elevation ) ) { @@ -468,7 +552,11 @@ void rotateFrame_sd( } /* gains for current subframe rotation */ +#ifdef NONBE_UNIFIED_DECODING_PATHS rotateAziEle( hTransSetup.ls_azimuth[ch_in_woLFE], hTransSetup.ls_elevation[ch_in_woLFE], &azimuth, &elevation, hCombinedOrientationData->Rmat[hCombinedOrientationData->subframe_idx], hTransSetup.is_planar_setup ); +#else + rotateAziEle( hTransSetup.ls_azimuth[ch_in_woLFE], hTransSetup.ls_elevation[ch_in_woLFE], &azimuth, &elevation, hCombinedOrientationData->Rmat[subframe_idx], hTransSetup.is_planar_setup ); +#endif if ( hEFAPdata != NULL && ( hTransSetup.ls_azimuth[ch_in_woLFE] != azimuth || hTransSetup.ls_elevation[ch_in_woLFE] != elevation ) ) { @@ -507,8 +595,16 @@ void rotateFrame_sd( for ( i = 0; i < 3; i++ ) { mvr2r( +#ifdef NONBE_UNIFIED_DECODING_PATHS hCombinedOrientationData->Rmat[hCombinedOrientationData->subframe_idx][i], +#else + hCombinedOrientationData->Rmat[subframe_idx][i], +#endif +#ifdef SPLIT_REND_WITH_HEAD_ROT + hCombinedOrientationData->Rmat_prev[0][i], +#else hCombinedOrientationData->Rmat_prev[i], +#endif 3 ); } @@ -792,7 +888,9 @@ void ivas_external_orientation_close( ivas_error ivas_combined_orientation_open( COMBINED_ORIENTATION_HANDLE *hCombinedOrientationData, /* o : combined orientation handle */ +#ifdef NONBE_UNIFIED_DECODING_PATHS const int32_t fs, /* i : sampling rate */ +#endif const int16_t num_subframes /* i : number of subframes */ ) { @@ -800,6 +898,9 @@ ivas_error ivas_combined_orientation_open( int16_t j; IVAS_QUATERNION identity; IVAS_VECTOR3 origo; +#ifdef SPLIT_REND_WITH_HEAD_ROT + int16_t pos_idx; +#endif identity.w = 1.0f; identity.x = identity.y = identity.z = 0.0f; @@ -844,11 +945,26 @@ ivas_error ivas_combined_orientation_open( } } +#ifdef SPLIT_REND_WITH_HEAD_ROT + for ( pos_idx = 0; pos_idx < MAX_HEAD_ROT_POSES; pos_idx++ ) + { + for ( j = 0; j < 3; j++ ) + { + set_zero( ( *hCombinedOrientationData )->Rmat_prev[pos_idx][j], 3 ); + ( *hCombinedOrientationData )->Rmat_prev[pos_idx][j][j] = 1.0f; + } + } + ( *hCombinedOrientationData )->sr_pose_pred_axis = DEFAULT_AXIS; +#ifdef NONBE_UNIFIED_DECODING_PATHS + ( *hCombinedOrientationData )->sr_low_res_flag = 0; +#endif +#else for ( j = 0; j < 3; j++ ) { set_zero( ( *hCombinedOrientationData )->Rmat_prev[j], 3 ); ( *hCombinedOrientationData )->Rmat_prev[j][j] = 1.0f; } +#endif ( *hCombinedOrientationData )->Quaternion_prev_extOrientation = identity; ( *hCombinedOrientationData )->Quaternion_frozen_ext = identity; @@ -863,9 +979,11 @@ ivas_error ivas_combined_orientation_open( ( *hCombinedOrientationData )->isExtOrientationFrozen = 0; ( *hCombinedOrientationData )->isHeadRotationFrozen = 0; +#ifdef NONBE_UNIFIED_DECODING_PATHS ( *hCombinedOrientationData )->subframe_idx = 0; ( *hCombinedOrientationData )->subframe_size = (int16_t) ( fs / ( FRAMES_PER_SEC * MAX_PARAM_SPATIAL_SUBFRAMES ) ); ( *hCombinedOrientationData )->cur_subframe_samples_rendered = 0; +#endif return IVAS_ERR_OK; } @@ -905,6 +1023,9 @@ ivas_error combine_external_and_head_orientations_dec( COMBINED_ORIENTATION_HANDLE hCombinedOrientationData /* i/o: combined orientation handle */ ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + IVAS_SPLIT_REND_ROT_AXIS sr_pose_pred_axis; +#endif IVAS_QUATERNION *pHeadRotQuaternion = NULL; IVAS_VECTOR3 *listenerPos = NULL; @@ -912,9 +1033,21 @@ ivas_error combine_external_and_head_orientations_dec( { pHeadRotQuaternion = hHeadTrackData->Quaternions; listenerPos = hHeadTrackData->Pos; +#ifdef SPLIT_REND_WITH_HEAD_ROT + sr_pose_pred_axis = hHeadTrackData->sr_pose_pred_axis; +#endif + } +#ifdef SPLIT_REND_WITH_HEAD_ROT + else + { + sr_pose_pred_axis = DEFAULT_AXIS; } +#endif return combine_external_and_head_orientations( pHeadRotQuaternion, listenerPos, +#ifdef SPLIT_REND_WITH_HEAD_ROT + sr_pose_pred_axis, +#endif hExtOrientationData, hCombinedOrientationData ); } @@ -931,10 +1064,16 @@ ivas_error combine_external_and_head_orientations_rend( COMBINED_ORIENTATION_HANDLE hCombinedOrientationData /* i/o: combined orientation handle */ ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + IVAS_SPLIT_REND_ROT_AXIS sr_pose_pred_axis; +#endif IVAS_QUATERNION *headRotQuaternions = NULL; IVAS_VECTOR3 *listenerPos = NULL; int16_t i; +#ifdef SPLIT_REND_WITH_HEAD_ROT + sr_pose_pred_axis = DEFAULT_AXIS; +#endif if ( hHeadTrackData != NULL ) { if ( hHeadTrackData->headRotEnabled ) @@ -942,6 +1081,9 @@ ivas_error combine_external_and_head_orientations_rend( headRotQuaternions = hHeadTrackData->headPositions; listenerPos = hHeadTrackData->Pos; } +#ifdef SPLIT_REND_WITH_HEAD_ROT + sr_pose_pred_axis = hHeadTrackData->sr_pose_pred_axis; +#endif } else if ( hExtOrientationData != NULL ) { @@ -956,6 +1098,9 @@ ivas_error combine_external_and_head_orientations_rend( } return combine_external_and_head_orientations( headRotQuaternions, listenerPos, +#ifdef SPLIT_REND_WITH_HEAD_ROT + sr_pose_pred_axis, +#endif hExtOrientationData, hCombinedOrientationData ); } @@ -970,6 +1115,9 @@ ivas_error combine_external_and_head_orientations_rend( ivas_error combine_external_and_head_orientations( IVAS_QUATERNION *headRotQuaternions, /* i : quaternions for head rotation */ IVAS_VECTOR3 *listenerPos, /* i : listener position */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + IVAS_SPLIT_REND_ROT_AXIS sr_pose_pred_axis, /* i : split rend pose prediction axis */ +#endif EXTERNAL_ORIENTATION_HANDLE hExtOrientationData, /* i : external orientation handle */ COMBINED_ORIENTATION_HANDLE hCombinedOrientationData /* i/o: combined orientation handle */ ) @@ -1205,10 +1353,15 @@ ivas_error combine_external_and_head_orientations( } } +#ifdef SPLIT_REND_WITH_HEAD_ROT + hCombinedOrientationData->sr_pose_pred_axis = sr_pose_pred_axis; +#endif +#ifdef NONBE_UNIFIED_DECODING_PATHS hCombinedOrientationData->subframe_idx = 0; hCombinedOrientationData->cur_subframe_samples_rendered = 0; hCombinedOrientationData->subframe_idx_start = 0; hCombinedOrientationData->cur_subframe_samples_rendered_start = 0; +#endif return IVAS_ERR_OK; } @@ -1425,7 +1578,11 @@ static float SHrot_w( if ( m == 0 ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + assert( 0 && "ERROR should not be called\n" ); +#else printf( "ERROR should not be called\n" ); +#endif return 0.0f; } else @@ -1559,6 +1716,7 @@ void SHrotmatgen( } +#ifdef NONBE_UNIFIED_DECODING_PATHS /*------------------------------------------------------------------------- * ivas_combined_orientation_update_index() * @@ -1573,6 +1731,9 @@ void ivas_combined_orientation_update_index( if ( hCombinedOrientationData != NULL ) { if ( hCombinedOrientationData->num_subframes == 1 +#ifdef SPLIT_REND_WITH_HEAD_ROT + || hCombinedOrientationData->sr_low_res_flag +#endif ) { /* only one orientation available anyway or split rendering with low resolution*/ @@ -1624,7 +1785,11 @@ void ivas_combined_orientation_update_start_index( { if ( hCombinedOrientationData != NULL ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( hCombinedOrientationData->num_subframes == 1 || hCombinedOrientationData->sr_low_res_flag ) +#else if ( hCombinedOrientationData->num_subframes == 1 ) +#endif { /* only one orientation available anyway or split rendering with low resolution*/ hCombinedOrientationData->subframe_idx = 0; @@ -1641,3 +1806,4 @@ void ivas_combined_orientation_update_start_index( return; } +#endif diff --git a/lib_rend/ivas_sba_rendering.c b/lib_rend/ivas_sba_rendering.c index 55671330b..6fc30a477 100644 --- a/lib_rend/ivas_sba_rendering.c +++ b/lib_rend/ivas_sba_rendering.c @@ -38,6 +38,9 @@ #include "ivas_stat_dec.h" #include "ivas_cnst.h" #include +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" diff --git a/lib_rend/ivas_splitRend_lcld_dec.c b/lib_rend/ivas_splitRend_lcld_dec.c new file mode 100644 index 000000000..1d81dfebc --- /dev/null +++ b/lib_rend/ivas_splitRend_lcld_dec.c @@ -0,0 +1,239 @@ +/****************************************************************************************************** + + (C) 2022-2023 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. + +*******************************************************************************************************/ + +#include +#include "options.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT +#include "ivas_prot_rend.h" +#include "ivas_prot.h" +#include "prot.h" +#ifdef DEBUGGING +#include "debug.h" +#endif +#include "wmc_auto.h" + + +/*------------------------------------------------------------------------- + * Function ivas_splitBinLCLDDecOpen() + * + * + *------------------------------------------------------------------------*/ + +ivas_error ivas_splitBinLCLDDecOpen( + BIN_HR_SPLIT_LCLD_DEC_HANDLE *hSplitBinLCLDDec, + const int32_t iSampleRate, + const int16_t iChannels ) +{ + int16_t n; + BIN_HR_SPLIT_LCLD_DEC_HANDLE splitBinLCLDDec; + ivas_error error; + + if ( ( splitBinLCLDDec = (BIN_HR_SPLIT_LCLD_DEC_HANDLE) malloc( sizeof( BIN_HR_SPLIT_LCLD_DEC ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD decoder Module \n" ) ); + } + + splitBinLCLDDec->pLcld_dec = NULL; /* place holder for CLDFB decoder handle */ + + splitBinLCLDDec->iChannels = iChannels; + if ( ( error = CreateLCLDDecoder( &splitBinLCLDDec->psLCLDDecoder, iSampleRate, iChannels ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( ( splitBinLCLDDec->pppfDecLCLDReal = (float ***) malloc( iChannels * sizeof( float ** ) ) ) == 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 ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD decoder Module \n" ) ); + } + + for ( n = 0; n < splitBinLCLDDec->iChannels; n++ ) + { + if ( ( splitBinLCLDDec->pppfDecLCLDReal[n] = (float **) malloc( CLDFB_NO_COL_MAX * sizeof( float * ) ) ) == 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 ) + { + 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"; + if ( ( splitBinLCLDDec->cldfbOut = fopen( cldfbFilename, "wb" ) ) == NULL ) + { + fprintf( stderr, "Error: CLDFB bitstream file %s could not be opened\n\n", cldfbFilename ); + exit( -1 ); + } + int16_t num_bands = CLDFB_NO_CHANNELS_MAX; + fwrite( &iChannels, sizeof( int16_t ), 1, splitBinLCLDDec->cldfbOut ); + fwrite( &num_bands, sizeof( int16_t ), 1, splitBinLCLDDec->cldfbOut ); +#endif + + if ( ( error = ivas_splitBinRendPLCOpen( &splitBinLCLDDec->hSplitRendPLC ) ) != IVAS_ERR_OK ) + { + return error; + } + + *hSplitBinLCLDDec = splitBinLCLDDec; + + return IVAS_ERR_OK; +} + + +/*------------------------------------------------------------------------- + * Function ivas_splitBinLCLDDecClose() + * + * + *------------------------------------------------------------------------*/ + +void ivas_splitBinLCLDDecClose( + BIN_HR_SPLIT_LCLD_DEC_HANDLE *hSplitBinLCLDDec ) +{ + int16_t n; + + if ( ( *hSplitBinLCLDDec ) != NULL ) + { + if ( ( *hSplitBinLCLDDec )->psLCLDDecoder != NULL ) + { + DeleteLCLDDecoder( ( *hSplitBinLCLDDec )->psLCLDDecoder ); + } + + for ( n = 0; n < ( *hSplitBinLCLDDec )->iChannels; n++ ) + { + free( ( *hSplitBinLCLDDec )->pppfDecLCLDReal[n] ); + free( ( *hSplitBinLCLDDec )->pppfDecLCLDImag[n] ); + } + free( ( *hSplitBinLCLDDec )->pppfDecLCLDReal ); + free( ( *hSplitBinLCLDDec )->pppfDecLCLDImag ); + +#ifdef CLDFB_DEBUG + if ( ( *hSplitBinLCLDDec )->cldfbOut != NULL ) + { + fclose( ( *hSplitBinLCLDDec )->cldfbOut ); + } +#endif + ivas_splitBinRendPLCClose( &( *hSplitBinLCLDDec )->hSplitRendPLC ); + + free( *hSplitBinLCLDDec ); + *hSplitBinLCLDDec = NULL; + } + + return; +} + + +/*------------------------------------------------------------------------- + * Function ivas_splitBinLCLDDecProcess() + * + * + *------------------------------------------------------------------------*/ + +void ivas_splitBinLCLDDecProcess( + BIN_HR_SPLIT_LCLD_DEC_HANDLE hSplitBinLCLDDec, + IVAS_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 ) +{ + int16_t k, n; + + push_wmops( "ivas_splitBinLCLDDecProcess" ); + + assert( hSplitBinLCLDDec != NULL ); + assert( Cldfb_Out_Real != NULL ); + assert( Cldfb_Out_Imag != NULL ); + assert( pBits != NULL ); + +#ifdef CLDFB_DEBUG + printf( "Bytes read = %d\n", iBytesWritten ); +#endif + if ( !bfi ) + { + /* Initialized with zeros....... */ + for ( n = 0; n < hSplitBinLCLDDec->iChannels; n++ ) + { + for ( k = 0; k < CLDFB_NO_COL_MAX; k++ ) + { + hSplitBinLCLDDec->pppfDecLCLDReal[n][k] = Cldfb_Out_Real[n][k]; + hSplitBinLCLDDec->pppfDecLCLDImag[n][k] = Cldfb_Out_Imag[n][k]; + set_f( hSplitBinLCLDDec->pppfDecLCLDReal[n][k], 0, CLDFB_NO_CHANNELS_MAX ); + set_f( hSplitBinLCLDDec->pppfDecLCLDImag[n][k], 0, CLDFB_NO_CHANNELS_MAX ); + } + } + + DecodeLCLDFrame( hSplitBinLCLDDec->psLCLDDecoder, pBits, hSplitBinLCLDDec->pppfDecLCLDReal, hSplitBinLCLDDec->pppfDecLCLDImag ); + +#ifdef CLDFB_DEBUG + printf( "Frame Decoded = %d\n", ++hSplitBinLCLDDec->numFrame ); + int16_t writeByte = 0; + for ( k = 0; k < CLDFB_NO_COL_MAX; k++ ) + { + for ( int16_t b = 0; b < CLDFB_NO_CHANNELS_MAX; b++ ) + { + for ( n = 0; n < hSplitBinLCLDDec->iChannels; n++ ) + { + writeByte = fwrite( &hSplitBinLCLDDec->pppfDecLCLDReal[n][k][b], sizeof( float ), 1, hSplitBinLCLDDec->cldfbOut ); + if ( writeByte != 1 ) + exit( -1 ); + writeByte = fwrite( &hSplitBinLCLDDec->pppfDecLCLDImag[n][k][b], sizeof( float ), 1, hSplitBinLCLDDec->cldfbOut ); + if ( writeByte != 1 ) + exit( -1 ); + } + } + } +#endif + if ( hSplitBinLCLDDec->hSplitRendPLC->prev_bfi != 0 ) + { + /* cross-fade recovered frame into good frame */ + ivas_splitBinRendPLC_xf( hSplitBinLCLDDec->hSplitRendPLC, Cldfb_Out_Real, Cldfb_Out_Imag, (int16_t) hSplitBinLCLDDec->iChannels ); + } + } + else + { + /* do PLC for lost split renderer frame */ + ivas_splitBinRendPLC( hSplitBinLCLDDec->hSplitRendPLC, Cldfb_Out_Real, Cldfb_Out_Imag, (int16_t) hSplitBinLCLDDec->iChannels ); + } + + /* save PLC state */ + ivas_splitBinRendPLCsaveState( hSplitBinLCLDDec->hSplitRendPLC, Cldfb_Out_Real, Cldfb_Out_Imag, (int16_t) hSplitBinLCLDDec->iChannels ); + + pop_wmops(); + + return; +} +#endif diff --git a/lib_rend/ivas_splitRend_lcld_enc.c b/lib_rend/ivas_splitRend_lcld_enc.c new file mode 100644 index 000000000..a0789d63a --- /dev/null +++ b/lib_rend/ivas_splitRend_lcld_enc.c @@ -0,0 +1,232 @@ +/****************************************************************************************************** + + (C) 2022-2023 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. + +*******************************************************************************************************/ + +#include +#include "options.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT +#include "ivas_prot_rend.h" +#include "ivas_prot.h" +#ifdef DEBUGGING +#include "debug.h" +#endif +#include "wmc_auto.h" + + +/*------------------------------------------------------------------------- + * Function ivas_splitBinLCLDEncOpen() + * + * + *------------------------------------------------------------------------*/ + +ivas_error ivas_splitBinLCLDEncOpen( + BIN_HR_SPLIT_LCLD_ENC_HANDLE *hSplitBinLCLDEnc, + const int32_t iSampleRate, + const int16_t iChannels, + const int32_t iDataRate ) +{ + BIN_HR_SPLIT_LCLD_ENC_HANDLE splitBinLCLDEnc; + ivas_error error; + + if ( ( splitBinLCLDEnc = (BIN_HR_SPLIT_LCLD_ENC_HANDLE) malloc( sizeof( BIN_HR_SPLIT_LCLD_ENC ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + + splitBinLCLDEnc->pLcld_enc = NULL; // place holder for CLDFB encoder handle + + splitBinLCLDEnc->iChannels = iChannels; + if ( ( error = CreateLCLDEncoder( &( splitBinLCLDEnc->psLCLDEncoder ), iSampleRate, iChannels, iDataRate, 1 ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( ( splitBinLCLDEnc->pppfLCLDReal = (float ***) malloc( iChannels * sizeof( float ** ) ) ) == 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 ) + { + 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++ ) + { + if ( ( splitBinLCLDEnc->pppfLCLDReal[n] = (float **) malloc( CLDFB_NO_COL_MAX * sizeof( float * ) ) ) == 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 ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + } + +#ifdef CLDFB_DEBUG + splitBinLCLDEnc->numFrame = 0; + char cldfbFilename[50] = "cldfb_in_ref.qmf"; + if ( ( splitBinLCLDEnc->cldfbIn = fopen( cldfbFilename, "rb" ) ) == NULL ) + { + fprintf( stderr, "Error: CLDFB bitstream file %s could not be opened\n\n", cldfbFilename ); + exit( -1 ); + } + int16_t chan, band; + fread( &chan, sizeof( int16_t ), 1, splitBinLCLDEnc->cldfbIn ); + fread( &band, sizeof( int16_t ), 1, splitBinLCLDEnc->cldfbIn ); +#endif + + *hSplitBinLCLDEnc = splitBinLCLDEnc; + + return IVAS_ERR_OK; +} + + +/*------------------------------------------------------------------------- + * Function ivas_splitBinLCLDEncClose() + * + * + *------------------------------------------------------------------------*/ + +void ivas_splitBinLCLDEncClose( + BIN_HR_SPLIT_LCLD_ENC_HANDLE *hSplitBinLCLDEnc ) +{ + if ( ( *hSplitBinLCLDEnc ) != NULL ) + { + DeleteLCLDEncoder( ( *hSplitBinLCLDEnc )->psLCLDEncoder ); + + for ( int16_t n = 0; n < ( *hSplitBinLCLDEnc )->iChannels; n++ ) + { + free( ( *hSplitBinLCLDEnc )->pppfLCLDReal[n] ); + free( ( *hSplitBinLCLDEnc )->pppfLCLDImag[n] ); + } + free( ( *hSplitBinLCLDEnc )->pppfLCLDReal ); + free( ( *hSplitBinLCLDEnc )->pppfLCLDImag ); + +#ifdef CLDFB_DEBUG + if ( ( *hSplitBinLCLDEnc )->cldfbIn != NULL ) + { + fclose( ( *hSplitBinLCLDEnc )->cldfbIn ); + } +#endif + + free( *hSplitBinLCLDEnc ); + *hSplitBinLCLDEnc = NULL; + } + + return; +} + + +/*------------------------------------------------------------------------- + * Function ivas_splitBinLCLDEncProcess() + * + * + *------------------------------------------------------------------------*/ + +void ivas_splitBinLCLDEncProcess( + 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, + IVAS_SPLIT_REND_BITS_HANDLE pBits ) +{ + int32_t iBitsWritten; + + push_wmops( "ivas_splitBinLCLDEncProcess" ); + + assert( hSplitBinLCLDEnc != NULL ); + assert( Cldfb_In_Real != NULL ); + assert( Cldfb_In_Imag != NULL ); + assert( pBits != NULL ); + + /* A conversion is needed for the 3d pointer interface here ........ */ + for ( int32_t n = 0; n < hSplitBinLCLDEnc->iChannels; n++ ) + { + for ( int32_t k = 0; k < CLDFB_NO_COL_MAX; k++ ) + { + hSplitBinLCLDEnc->pppfLCLDReal[n][k] = Cldfb_In_Real[n][k]; + hSplitBinLCLDEnc->pppfLCLDImag[n][k] = Cldfb_In_Imag[n][k]; + } + } + +#ifdef CLDFB_DEBUG + int16_t readByte = 0; + for ( int16_t k = 0; k < CLDFB_NO_COL_MAX; k++ ) + { + for ( int16_t b = 0; b < CLDFB_NO_CHANNELS_MAX; b++ ) + { + for ( int16_t n = 0; n < hSplitBinLCLDEnc->iChannels; n++ ) + { + readByte = fread( &Cldfb_In_Real[n][k][b], sizeof( float ), 1, hSplitBinLCLDEnc->cldfbIn ); + if ( readByte != 1 ) + break; + readByte = fread( &Cldfb_In_Imag[n][k][b], sizeof( float ), 1, hSplitBinLCLDEnc->cldfbIn ); + } + } + } + + if ( readByte == 1 ) + { + printf( "Frame Read = %d\n", ++hSplitBinLCLDEnc->numFrame ); + } + else + { + printf( "Writing zeroes...\n" ); + for ( int16_T k = 0; k < CLDFB_NO_COL_MAX; k++ ) + { + for ( int16_t b = 0; b < CLDFB_NO_CHANNELS_MAX; b++ ) + { + for ( int16_t n = 0; n < hSplitBinLCLDEnc->iChannels; n++ ) + { + hSplitBinLCLDEnc->pppfLCLDReal[n][k][b] = 0.f; + hSplitBinLCLDEnc->pppfLCLDImag[n][k][b] = 0.f; + } + } + } + } +#endif + + EncodeLCLDFrame( hSplitBinLCLDEnc->psLCLDEncoder, hSplitBinLCLDEnc->pppfLCLDReal, hSplitBinLCLDEnc->pppfLCLDImag, &iBitsWritten, available_bits, pBits ); + +#ifdef DEBUGGING + if ( iBitsWritten > available_bits ) + assert( iBitsWritten <= available_bits ); +#endif + +#ifdef CLDFB_DEBUG + printf( "Bits written = %d\n", iBitsWritten ); +#endif + + pop_wmops(); + + return; +} +#endif diff --git a/lib_rend/ivas_splitRendererPLC.c b/lib_rend/ivas_splitRendererPLC.c new file mode 100644 index 000000000..0c75b55eb --- /dev/null +++ b/lib_rend/ivas_splitRendererPLC.c @@ -0,0 +1,552 @@ +/****************************************************************************************************** + + (C) 2022-2023 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. + +*******************************************************************************************************/ + +#include +#include "options.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT +#include +#include "ivas_prot.h" +#include "prot.h" +#include "ivas_cnst.h" +#include "ivas_prot_rend.h" +#ifdef DEBUGGING +#include "debug.h" +#endif +#include "wmc_auto.h" + + +/*------------------------------------------------------------------------- + * Local constants + *------------------------------------------------------------------------*/ + +#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 STH_THRESH ( 2.f / 3.f * PI2 / 12 ) + + +/*------------------------------------------------------------------------- + * Function adaptive_polar_ext_plc() + * + * + *------------------------------------------------------------------------*/ + +static void adaptive_polar_ext_plc( + const float *prev_real, + const float *prev_imag, + float *rec_real, + float *rec_imag +#if CLDFB_PLC_XF > 0 + , + float xf_alp[CLDFB_PLC_XF], + float xf_bet[CLDFB_PLC_XF] +#endif +) +{ + 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; + + /* reset of accumulators */ + ph_adj = 0.0f; + drho = 0.0f; + srho = 0.0f; + dth = 0.0f; + sth = 0.0f; + + /* calculate per-sample phase and magnitude evolution in preceding frame */ + for ( k = 0; k < CLDFB_NO_COL_MAX; k++ ) + { + urh[k] = sqrtf( prev_imag[k] * prev_imag[k] + prev_real[k] * prev_real[k] ); + if ( urh[k] < EPSILON ) + { + /* zero encountered */ + break; + } + uth[k] = atan2f( prev_imag[k], prev_real[k] ); + + /* phase unwrap */ + if ( k == 0 ) + { + uthu[0] = uth[0]; + } + else + { + /* phase unwrap */ + ph_diff = uth[k] - uth[k - 1]; + uthu[k] = uth[k]; + if ( fabsf( ph_diff ) >= PI2 / 2 ) + { + ph_adj_t = ph_diff / PI2; + if ( fabsf( ph_adj_t - truncf( ph_adj_t ) ) == 0.5f ) + { + ph_adj_t = truncf( ph_adj_t ); + } + ph_adj = -PI2 * roundf( ph_adj_t ) + ph_adj; + } + uthu[k] += ph_adj; + /* unwrapped phase in uthu */ + + /* mean and stdev of per-sample magnitude ratios */ + quot = urh[k] / urh[k - 1]; + drho += quot; + srho += SQR( quot ); + /* 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 == CLDFB_NO_COL_MAX ) + { + /* mean and stdev of per-sample magnitude ratios */ + drho *= 1.0f / ( CLDFB_NO_COL_MAX - 1 ); + temp = srho - ( CLDFB_NO_COL_MAX - 1 ) * SQR( drho ); + if ( temp > 0 ) + { + srho = sqrtf( temp * ( 1.0f / ( CLDFB_NO_COL_MAX - 2 ) ) ); + } + else + { + srho = 0.0f; + } + + /* mean and stdev of per-sample phase differences */ + dth *= 1.0f / ( CLDFB_NO_COL_MAX - 1 ); + temp = sth - ( CLDFB_NO_COL_MAX - 1 ) * SQR( dth ); + if ( temp > 0 ) + { + sth = sqrtf( temp * ( 1.0f / ( CLDFB_NO_COL_MAX - 2 ) ) ); + } + else + { + sth = 0.0f; + } + + /* do phase extension only if the std deviations are small */ + if ( ( srho < SRHO_THRESH ) || ( sth < STH_THRESH ) ) + { + /* 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; + +#if START_VAL_AVG_LEN > 1 + /* Calculate start value for evolution from last samples of previous frame */ + fac_powj_real = fac_real; + fac_powj_imag = fac_imag; + start_real = prev_real[CLDFB_NO_COL_MAX - 1]; + start_imag = prev_imag[CLDFB_NO_COL_MAX - 1]; + for ( j = 1; j < START_VAL_AVG_LEN; j++ ) + { + start_real += fac_powj_real * prev_real[CLDFB_NO_COL_MAX - j - 1] - fac_powj_imag * prev_imag[CLDFB_NO_COL_MAX - j - 1]; + start_imag += fac_powj_imag * prev_real[CLDFB_NO_COL_MAX - j - 1] + fac_powj_real * prev_imag[CLDFB_NO_COL_MAX - 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; + } + start_real *= 1.0f / START_VAL_AVG_LEN; + start_imag *= 1.0f / START_VAL_AVG_LEN; +#else + /* take last sample of previous frame as start value */ + start_real = prev_real[CLDFB_NO_COL_MAX - 1]; + start_imag = prev_imag[CLDFB_NO_COL_MAX - 1]; +#endif + +#if DO_PERTURB != 0 + /* 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] ); +#if PH_PERT_ONLY != 0 + /* 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; +#else + /* phase and magnitude perturbation */ + abs2inv = 1 / ( max( 1, drho ) * ( SQR( prev_real[0] ) + SQR( prev_imag[0] ) ) ); + rat_real *= abs2inv; + rat_imag *= abs2inv; +#endif + + /* 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 < CLDFB_NO_COL_MAX; j++ ) + { + /* 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] ); +#if PH_PERT_ONLY != 0 + /* only phase perturbation */ + 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; + /* 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]; + } + + /* 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 PH_PERT_ONLY != 0 + abs_temp = sqrtf( SQR( rat_real ) + SQR( rat_imag ) ); + abs2inv = min( 1, drho ) / max( EPSILON, abs_temp ); +#else + 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 + CLDFB_NO_COL_MAX - 2] = rat_real * rec_real[j + CLDFB_NO_COL_MAX - 3] - rat_imag * rec_imag[j + CLDFB_NO_COL_MAX - 3]; + rec_imag[j + CLDFB_NO_COL_MAX - 2] = rat_imag * rec_real[j + CLDFB_NO_COL_MAX - 3] + rat_real * rec_imag[j + CLDFB_NO_COL_MAX - 3]; + } +#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 < CLDFB_NO_COL_MAX + 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++ ) + { + rec_real[CLDFB_NO_COL_MAX + j] *= xf_alp[j]; + rec_imag[CLDFB_NO_COL_MAX + j] *= xf_alp[j]; + xf_bet[j] = 1 - xf_alp[j]; + } +#endif + } + else + { + /* 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 < CLDFB_NO_COL_MAX; 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]; + } + if ( Ruu_real[0] > EPSILON ) + { + /* prediction coefficient */ + fac_real = Ruu_real[1] / Ruu_real[0]; + fac_imag = Ruu_imag[1] / Ruu_real[0]; + } + else + { + fac_real = 0; + fac_imag = 0; + } + + /* 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 < CLDFB_NO_COL_MAX; j++ ) + { + comp_fac = 1 - abs_fac_powj; + rec_real[j] = prev_real[CLDFB_NO_COL_MAX - 1] * fac_powj_real - prev_imag[CLDFB_NO_COL_MAX - 1] * fac_powj_imag + + prev_real[j] * comp_fac; + rec_imag[j] = prev_real[CLDFB_NO_COL_MAX - 1] * fac_powj_imag + prev_imag[CLDFB_NO_COL_MAX - 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; + } + + /* prepare XF to next frame using prediction */ + fac_powj_real = fac_real; + fac_powj_imag = fac_imag; + abs_fac_powj = abs_fac; +#if CLDFB_PLC_XF > 0 + for ( j = 0; j < CLDFB_PLC_XF; j++ ) + { + xf_bet[j] = 1 - abs_fac_powj; + rec_real[j + CLDFB_NO_COL_MAX] = rec_real[CLDFB_NO_COL_MAX - 1] * fac_powj_real - rec_imag[CLDFB_NO_COL_MAX - 1] * fac_powj_imag; + rec_imag[j + CLDFB_NO_COL_MAX] = rec_real[CLDFB_NO_COL_MAX - 1] * fac_powj_imag + rec_imag[CLDFB_NO_COL_MAX - 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; + } +#endif + } + } + else + { + for ( j = 0; j < CLDFB_NO_COL_MAX; j++ ) + { + rec_real[j] = prev_real[j]; + rec_imag[j] = prev_imag[j]; + } +#if CLDFB_PLC_XF > 0 + for ( j = 0; j < CLDFB_PLC_XF; j++ ) + { + xf_bet[j] = 1; + rec_real[j + CLDFB_NO_COL_MAX] = 0; + rec_imag[j + CLDFB_NO_COL_MAX] = 0; + } +#endif + } + + return; +} + + +/*------------------------------------------------------------------------- + * Function ivas_splitBinRendPLCOpen() + * + * + *------------------------------------------------------------------------*/ + +ivas_error ivas_splitBinRendPLCOpen( + SPLIT_REND_PLC_HANDLE *phSplitRendPLC ) +{ + ivas_error error; + SPLIT_REND_PLC_HANDLE hSplitRendPLC; + + error = IVAS_ERR_OK; + if ( ( hSplitRendPLC = (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" ) ); + } + + hSplitRendPLC->prev_bfi = 0; + hSplitRendPLC->bf_count = 0; + 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 ); + *phSplitRendPLC = hSplitRendPLC; + + return error; +} + + +/*------------------------------------------------------------------------- + * Function ivas_splitBinRendPLCClose() + * + * + *------------------------------------------------------------------------*/ + +void ivas_splitBinRendPLCClose( + SPLIT_REND_PLC_HANDLE *phSplitRendPLC ) +{ + if ( ( *phSplitRendPLC ) != NULL ) + { + free( ( *phSplitRendPLC ) ); + ( *phSplitRendPLC ) = NULL; + } + + return; +} + + +/*------------------------------------------------------------------------- + * Function ivas_splitBinRendPLCsaveState() + * + * + *------------------------------------------------------------------------*/ + +void ivas_splitBinRendPLCsaveState( + 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 ) +{ + int16_t k, n; + + /* Save Cldfb frame */ + for ( k = 0; k < CLDFB_NO_COL_MAX; k++ ) + { + 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 ); + } + } + + return; +} + + +/*------------------------------------------------------------------------- + * Function ivas_splitBinRendPLC_xf() + * + * Cross-fade of preceding bad frame into good frame + *------------------------------------------------------------------------*/ + +void ivas_splitBinRendPLC_xf( + 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 ) +{ + int16_t n, i, k; + + /* Indicate that next transition will be from a good frame */ + hSplitRendPLC->prev_bfi = 0; + + /* Reset bf conter */ + hSplitRendPLC->bf_count = 0; + + + /* Do the cross fade */ + for ( n = 0; n < num_chs; n++ ) + { + for ( i = 0; i < CLDFB_NO_CHANNELS_MAX; i++ ) + { +#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 + CLDFB_NO_COL_MAX][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 + CLDFB_NO_COL_MAX][i]; + } +#endif + } + } + + return; +} + + +/*------------------------------------------------------------------------- + * Function ivas_splitBinRendPLC() + * + * Conceal bad frame + *------------------------------------------------------------------------*/ + +void ivas_splitBinRendPLC( + 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 ) +{ + 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]; +#if CLDFB_PLC_XF > 0 + float xf_alp[CLDFB_PLC_XF]; +#endif + + /* Indicate that next transition will be from a bad frame */ + hSplitRendPLC->prev_bfi = 1; + + +#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 ); + } +#endif + + for ( n = 0; n < num_chs; n++ ) + { + for ( i = 0; i < CLDFB_NO_CHANNELS_MAX; i++ ) + { + for ( k = 0; k < CLDFB_NO_COL_MAX; 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]; + } + + adaptive_polar_ext_plc( prev_real, prev_imag, rec_real, rec_imag +#if CLDFB_PLC_XF > 0 + , + xf_alp, hSplitRendPLC->CldfbPLC_state.xf_bet[n][i] +#endif + ); + + for ( k = 0; k < CLDFB_NO_COL_MAX; k++ ) + { + Cldfb_RealBuffer_Binaural[n][k][i] = rec_real[k]; + hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinReal[n][k][i] = rec_real[k]; + Cldfb_ImagBuffer_Binaural[n][k][i] = rec_imag[k]; + hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinImag[n][k][i] = rec_imag[k]; + } + +#if CLDFB_PLC_XF > 0 + for ( k = CLDFB_NO_COL_MAX; k < CLDFB_NO_COL_MAX + 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]; + } +#endif + } + } + + + /* Check bf counter */ + if ( hSplitRendPLC->bf_count++ >= SR_PLC_FADE_START ) + { + if ( hSplitRendPLC->bf_count < SR_PLC_MUTE ) + { + fade_fac = powf( 10, ( hSplitRendPLC->bf_count - SR_PLC_FADE_START ) * SR_PLC_FADE_DEGREE / 20.0f ); + v_multc( &Cldfb_RealBuffer_Binaural[0][0][0], fade_fac, &Cldfb_RealBuffer_Binaural[0][0][0], (int16_t) ( (CLDFB_NO_COL_MAX) *num_chs * CLDFB_NO_CHANNELS_MAX ) ); + v_multc( &Cldfb_ImagBuffer_Binaural[0][0][0], fade_fac, &Cldfb_ImagBuffer_Binaural[0][0][0], (int16_t) ( (CLDFB_NO_COL_MAX) *num_chs * CLDFB_NO_CHANNELS_MAX ) ); + } + else + { + set_zero( &Cldfb_RealBuffer_Binaural[0][0][0], (int16_t) ( (CLDFB_NO_COL_MAX) *num_chs * CLDFB_NO_CHANNELS_MAX ) ); + set_zero( &Cldfb_ImagBuffer_Binaural[0][0][0], (int16_t) ( (CLDFB_NO_COL_MAX) *num_chs * CLDFB_NO_CHANNELS_MAX ) ); + hSplitRendPLC->bf_count = SR_PLC_MUTE; + } + } + + return; +} + +#endif diff --git a/lib_rend/ivas_splitRendererPost.c b/lib_rend/ivas_splitRendererPost.c new file mode 100644 index 000000000..8eb542892 --- /dev/null +++ b/lib_rend/ivas_splitRendererPost.c @@ -0,0 +1,1799 @@ +/****************************************************************************************************** + + (C) 2022-2023 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. + +*******************************************************************************************************/ + +#include +#include "options.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT +#include +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG +#include +#endif +#include "ivas_prot.h" +#include "prot.h" +#include "ivas_rom_dec.h" +#include "ivas_prot_rend.h" +#ifdef DEBUGGING +#include "debug.h" +#endif +#include "wmc_auto.h" + + +/*------------------------------------------------------------------------- + * ivas_splitBinPostRendOpen() + * + * + *------------------------------------------------------------------------*/ + +ivas_error ivas_splitBinPostRendOpen( + BIN_HR_SPLIT_POST_REND_HANDLE *hBinHrSplitPostRend, + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + const int32_t output_Fs ) +{ + BIN_HR_SPLIT_POST_REND_HANDLE hBinRend; + ivas_error error; + int16_t ch; + + if ( ( hBinRend = (BIN_HR_SPLIT_POST_REND_HANDLE) malloc( sizeof( 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++ ) + { + hBinRend->cldfbSyn[ch] = NULL; + hBinRend->cldfbAna[ch] = NULL; + } +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + for ( int16_t i = 0; i < MAX_HEAD_ROT_POSES; i++ ) + { + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + hBinRend->cldfbSynReconsBinDec[i][ch] = NULL; + } + } +#endif + + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + if ( ( error = openCldfb( &( 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 ) + { + return error; + } + } + +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + for ( int16_t i = 0; i < MAX_HEAD_ROT_POSES; i++ ) + { + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + if ( ( error = openCldfb( &( hBinRend->cldfbSynReconsBinDec[i][ch] ), CLDFB_SYNTHESIS, output_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) + { + return error; + } + } + } +#endif + hBinRend->cf_flag = 0; + set_fix_rotation_mat( hBinRend->fix_pos_rot_mat, pMultiBinPoseData ); + set_pose_types( hBinRend->pose_type, pMultiBinPoseData ); + ivas_split_rend_init_huff_cfg( &hBinRend->huff_cfg ); + *hBinHrSplitPostRend = hBinRend; + + return IVAS_ERR_OK; +} + + +/*------------------------------------------------------------------------- + * ivas_splitBinPostRendClose() + * + * + *------------------------------------------------------------------------*/ + +void ivas_splitBinPostRendClose( + BIN_HR_SPLIT_POST_REND_HANDLE *hBinHrSplitPostRend ) +{ + int16_t ch; + + if ( ( *hBinHrSplitPostRend ) != NULL ) + { + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + if ( ( *hBinHrSplitPostRend )->cldfbSyn[ch] != NULL ) + { + deleteCldfb( &( ( *hBinHrSplitPostRend )->cldfbSyn[ch] ) ); + ( *hBinHrSplitPostRend )->cldfbSyn[ch] = NULL; + } + if ( ( *hBinHrSplitPostRend )->cldfbAna[ch] != NULL ) + { + deleteCldfb( &( ( *hBinHrSplitPostRend )->cldfbAna[ch] ) ); + ( *hBinHrSplitPostRend )->cldfbAna[ch] = NULL; + } + } +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + for ( int16_t i = 0; i < MAX_HEAD_ROT_POSES; i++ ) + { + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + if ( ( *hBinHrSplitPostRend )->cldfbSynReconsBinDec[i][ch] != NULL ) + { + deleteCldfb( &( ( *hBinHrSplitPostRend )->cldfbSynReconsBinDec[i][ch] ) ); + ( *hBinHrSplitPostRend )->cldfbSynReconsBinDec[i][ch] = NULL; + } + } + } +#endif + + free( ( *hBinHrSplitPostRend ) ); + ( *hBinHrSplitPostRend ) = NULL; + } + + return; +} + + +/*-----------------------------------------------------------------------------------------* + * Function ivas_huffman_code_bits_present() + * + * Huffman code bits present + *-----------------------------------------------------------------------------------------*/ + +static int32_t ivas_split_rend_huffman_code_bits_present( + const int32_t *codebook, + const int32_t code, + const int32_t bits, + const int16_t len ) +{ + int16_t index = len + 1; + int16_t i = 0; + int32_t code_t, ind_t, bits_t; + + while ( i < len ) + { + ind_t = codebook[0]; + bits_t = codebook[1]; + code_t = codebook[2]; + if ( ( code == code_t ) && ( bits == bits_t ) ) + { + return ind_t; + } + codebook = codebook + 3; + i++; + } + + return index; +} + + +/*-----------------------------------------------------------------------------------------* + * Function ivas_split_rend_huffman_decode_opt() + * + * + *-----------------------------------------------------------------------------------------*/ + +static int16_t ivas_split_rend_huffman_decode_opt( + ivas_split_rend_huffman_cfg_t *huff_cfg, + IVAS_SPLIT_REND_BITS_HANDLE pBits, + const int16_t *idx_trav_list ) +{ + int32_t i, ind, code, num_bits, code_b, num_bits_read; + const int32_t *codebook; + + codebook = huff_cfg->codebook; + num_bits_read = 0; + ind = huff_cfg->codebook[0] - 1; + code = 0; + for ( i = 0; i < huff_cfg->sym_len; i++ ) + { + codebook = codebook + idx_trav_list[i] * 3; + num_bits = codebook[1]; + code_b = codebook[2]; + num_bits_read = num_bits - num_bits_read; + code = code << num_bits_read; + if ( num_bits_read > 0 ) + { + code |= ivas_split_rend_bitstream_read_int32( pBits, num_bits_read ); + } + + if ( code == code_b ) + { + ind = codebook[0]; + break; + } + + num_bits_read = num_bits; + codebook = huff_cfg->codebook; + } + +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + assert( ind >= huff_cfg->codebook[0] ); +#endif + return (int16_t) ind; +} + +/*-----------------------------------------------------------------------------------------* + * Function ivas_split_rend_unquant_md() + * + * + *-----------------------------------------------------------------------------------------*/ + +static void ivas_split_rend_unquant_md( + BIN_HR_SPLIT_REND_MD_HANDLE hMd, + IVAS_SPLIT_REND_POSE_TYPE pose_type, + int16_t real_only, + float fix_pos_rot_mat[][BINAURAL_CHANNELS], + const float pred_quant_step ) +{ + int16_t ch1, ch2; + int16_t gd_idx_min; + + if ( pose_type == PRED_ONLY || pose_type == PRED_ROLL_ONLY ) + { + float quantstep; + + quantstep = pred_quant_step; + + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + 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]; + } + } + if ( real_only ) + { + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + hMd->pred_mat_im[ch1][ch2] = 0.0f; + } + } + } + else + { + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + hMd->pred_mat_im[ch1][ch2] = hMd->pred_mat_im_idx[ch1][ch2] * quantstep; + } + } + } + } + else if ( pose_type == COM_GAIN_ONLY ) + { + gd_idx_min = (int16_t) roundf( IVAS_SPLIT_REND_D_1BYQ_STEP * IVAS_SPLIT_REND_D_MIN_VAL ); + hMd->gd_idx += gd_idx_min; + hMd->gd = hMd->gd_idx * IVAS_SPLIT_REND_D_Q_STEP; + } + else if ( pose_type == LR_GAIN_ONLY ) + { + gd_idx_min = (int16_t) roundf( IVAS_SPLIT_REND_PITCH_G_1BYQ_STEP * IVAS_SPLIT_REND_PITCH_G_MIN_VAL ); + hMd->gd_idx += gd_idx_min; + hMd->gd = hMd->gd_idx * IVAS_SPLIT_REND_PITCH_G_Q_STEP; + + hMd->gd2_idx += gd_idx_min; + hMd->gd2 = hMd->gd2_idx * IVAS_SPLIT_REND_PITCH_G_Q_STEP; + } + else + { + hMd->gd = 0.0f; + } + + return; +} + + +/*-----------------------------------------------------------------------------------------* + * Function ivas_splitBinPostRendMdBase2Dec() + * + * + *-----------------------------------------------------------------------------------------*/ + +static void ivas_splitBinPostRendMdBase2Dec( + IVAS_SPLIT_REND_BITS_HANDLE pBits, + 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 ) +{ + 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; + BIN_HR_SPLIT_REND_MD_HANDLE hMd; + BIN_HR_SPLIT_REND_HUFF_HANDLE pHuff_cfg; + + pHuff_cfg = &hBinHrSplitPostRend->huff_cfg; + + if ( pred_quant_pnts_yaw == IVAS_SPLIT_REND_PRED_63QUANT_PNTS ) + { + pred_cb_idx = 1; + } + else + { + pred_cb_idx = 0; + } + 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]; + pred_code_len = pHuff_cfg->pred_base2_code_len[pred_cb_idx]; + pred_roll_code_len = pHuff_cfg->pred_roll_base2_code_len; + gd_code_len = pHuff_cfg->gd_base2_code_len; + p_gd_code_len = pHuff_cfg->p_gd_base2_code_len; + + for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) + { + for ( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses - 1; pos_idx++ ) + { + if ( hBinHrSplitPostRend->pose_type[pos_idx] == ANY_YAW ) + { + 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 ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + code = (int16_t) ivas_split_rend_bitstream_read_int32( pBits, pred_code_len ); + hMd->pred_mat_re_idx[ch1][ch2] = code + min_pred_idx; + } + } + } + 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 ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + code = (int16_t) ivas_split_rend_bitstream_read_int32( pBits, pred_code_len ); + hMd->pred_mat_im_idx[ch1][ch2] = code + min_pred_idx; + } + } + } + for ( b = 0; b < d_bands_yaw; b++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + code = (int16_t) ivas_split_rend_bitstream_read_int32( pBits, gd_code_len ); + hMd->gd_idx = code + min_gd_idx; + } + } + else if ( hBinHrSplitPostRend->pose_type[pos_idx] == PITCH_ONLY ) + { + for ( b = 0; b < bands_pitch; b++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + code = (int16_t) ivas_split_rend_bitstream_read_int32( pBits, p_gd_code_len ); + hMd->gd_idx = code + min_p_gd_idx; + code = (int16_t) ivas_split_rend_bitstream_read_int32( pBits, p_gd_code_len ); + hMd->gd2_idx = code + min_p_gd_idx; + } + } + else + { + 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 ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + code = (int16_t) ivas_split_rend_bitstream_read_int32( pBits, pred_roll_code_len ); + hMd->pred_mat_re_idx[ch1][ch2] = code + min_pred_roll_idx; + } + } + } + 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 ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + code = (int16_t) ivas_split_rend_bitstream_read_int32( pBits, pred_roll_code_len ); + hMd->pred_mat_im_idx[ch1][ch2] = code + min_pred_roll_idx; + } + } + } + } + } + } + + return; +} + + +/*-----------------------------------------------------------------------------------------* + * Function ivas_splitBinPostRendMdHuffDec() + * + * + *-----------------------------------------------------------------------------------------*/ + +static void ivas_splitBinPostRendMdHuffDec( + IVAS_SPLIT_REND_BITS_HANDLE pBits, + 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 ) +{ + 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; + BIN_HR_SPLIT_REND_MD_HANDLE hMd; + BIN_HR_SPLIT_REND_HUFF_HANDLE pHuff_cfg; + + pHuff_cfg = &hBinHrSplitPostRend->huff_cfg; + + if ( pred_quant_pnts_yaw == IVAS_SPLIT_REND_PRED_63QUANT_PNTS ) + { + pred_cb_idx = 1; + } + else + { + pred_cb_idx = 0; + } + 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[( IVAS_SPLIT_REND_ROLL_PRED_QUANT_PNTS - 1 ) * 3]; + + for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) + { + for ( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses - 1; pos_idx++ ) + { + if ( hBinHrSplitPostRend->pose_type[pos_idx] == ANY_YAW ) + { + 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 ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + 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] ); + // sym_adj_idx[ch1][ch2] = ivas_split_rend_huffman_decode( &pHuff_cfg->pred, pBits ); + } + } + ivas_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++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + 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] ); + // sym_adj_idx[ch1][ch2] = ivas_split_rend_huffman_decode( &pHuff_cfg->pred, pBits ); + } + } + ivas_SplitRenderer_getdiagdiff( sym_adj_idx, hMd->pred_mat_im_idx, -1, min_pred_idx, max_pred_idx ); + } + for ( b = 0; b < d_bands_yaw; b++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + 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 ) + { + for ( b = 0; b < bands_pitch; b++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + 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 = ivas_split_rend_huffman_decode_opt( &pHuff_cfg->p_gd, pBits, pHuff_cfg->p_gd_idx_trav ); + } + } + else + { + 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 ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + sym_adj_idx[ch1][ch2] = ivas_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( &pHuff_cfg->pred_roll, pBits ); + } + } + ivas_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++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + sym_adj_idx[ch1][ch2] = ivas_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( &pHuff_cfg->pred_roll, pBits ); + } + } + ivas_SplitRenderer_getdiagdiff( sym_adj_idx, hMd->pred_mat_im_idx, -1, min_pred_roll_idx, max_pred_roll_idx ); + } + } + } + } + + return; +} + + +/*-----------------------------------------------------------------------------------------* + * Function ivas_splitBinPostRendMdDec() + * + * + *-----------------------------------------------------------------------------------------*/ + +void ivas_splitBinPostRendMdDec( + IVAS_SPLIT_REND_BITS_HANDLE pBits, + BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend, + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + , + BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend +#endif +) +{ + int16_t pos_idx, b, sf_idx, num_subframes, ch1; + int16_t pred_real_bands_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], pred_real_bands_roll[IVAS_SPLIT_REND_NUM_QUANT_STRATS]; + int16_t pred_imag_bands_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], pred_imag_bands_roll[IVAS_SPLIT_REND_NUM_QUANT_STRATS]; + int16_t d_bands_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], bands_pitch[IVAS_SPLIT_REND_NUM_QUANT_STRATS]; + int16_t num_complex_bands, num_quant_strats; + int32_t quant_strat_bits, is_huff_coding, quant_strat; + int16_t pred_quant_pnts_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS]; + float pred_1byquantstep_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS]; + float pred_quantstep_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS]; +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + int16_t ch1, ch2; +#endif + BIN_HR_SPLIT_REND_MD_HANDLE hMd; + IVAS_SPLIT_REND_CONFIG_DATA split_rend_config; + IVAS_SPLIT_REND_ROT_AXIS rot_axis; + + hBinHrSplitPostRend->low_Res = 1; + + split_rend_config.dof = (int16_t) ivas_split_rend_bitstream_read_int32( pBits, IVAS_SPLIT_REND_DOF_BITS ); + split_rend_config.hq_mode = (int16_t) ivas_split_rend_bitstream_read_int32( pBits, IVAS_SPLIT_REND_HQ_MODE_BITS ); + rot_axis = (IVAS_SPLIT_REND_ROT_AXIS) ivas_split_rend_bitstream_read_int32( pBits, IVAS_SPLIT_REND_ROT_AXIS_BITS ); + + ivas_renderSplitGetMultiBinPoseData( &split_rend_config, pMultiBinPoseData, rot_axis ); + + set_fix_rotation_mat( hBinHrSplitPostRend->fix_pos_rot_mat, pMultiBinPoseData ); + set_pose_types( 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++ ) + { + int16_t angle; + + hBinHrSplitPostRend->QuaternionsPre[sf_idx].w = -3.0f; + + angle = (int16_t) ivas_split_rend_bitstream_read_int32( pBits, IVAS_SPLIT_REND_HEAD_POSE_BITS ); + angle -= 180; + hBinHrSplitPostRend->QuaternionsPre[sf_idx].x = (float) angle; + + angle = (int16_t) ivas_split_rend_bitstream_read_int32( pBits, IVAS_SPLIT_REND_HEAD_POSE_BITS ); + angle -= 180; + hBinHrSplitPostRend->QuaternionsPre[sf_idx].y = (float) angle; + + angle = (int16_t) ivas_split_rend_bitstream_read_int32( pBits, IVAS_SPLIT_REND_HEAD_POSE_BITS ); + angle -= 180; + hBinHrSplitPostRend->QuaternionsPre[sf_idx].z = (float) angle; + } + + ivas_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 ); + + quant_strat_bits = (int32_t) ceilf( log2f( num_quant_strats ) ); + is_huff_coding = ivas_split_rend_bitstream_read_int32( pBits, 1 ); + quant_strat = ivas_split_rend_bitstream_read_int32( pBits, quant_strat_bits ); + + if ( is_huff_coding == 0 ) + { + ivas_splitBinPostRendMdBase2Dec( + pBits, hBinHrSplitPostRend, + pMultiBinPoseData, + num_subframes, + pred_real_bands_yaw[quant_strat], + pred_imag_bands_yaw[quant_strat], + pred_quant_pnts_yaw[quant_strat], + d_bands_yaw[quant_strat], + bands_pitch[quant_strat], + pred_real_bands_roll[quant_strat], + pred_imag_bands_roll[quant_strat] ); + } + else + { + ivas_splitBinPostRendMdHuffDec( + pBits, hBinHrSplitPostRend, + pMultiBinPoseData, + num_subframes, + pred_real_bands_yaw[quant_strat], + pred_imag_bands_yaw[quant_strat], + pred_quant_pnts_yaw[quant_strat], + d_bands_yaw[quant_strat], + bands_pitch[quant_strat], + pred_real_bands_roll[quant_strat], + pred_imag_bands_roll[quant_strat] ); + } +#ifdef SPLIT_MD_CODING_DEBUG + for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) + { + int16_t val, ch2, val_ref; + char filename[200] = "split_md_debug_indices.bin"; + for ( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses - 1; pos_idx++ ) + { + if ( hBinHrSplitPostRend->pose_type[pos_idx] == ANY_YAW ) + { + for ( b = 0; b < pred_real_bands_yaw[quant_strat]; b++ ) + { + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + val = hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b].pred_mat_re_idx[ch1][ch2]; + dbgread( &val_ref, sizeof( int16_t ), 1, filename ); + if ( abs( val_ref - val ) > 0 ) + { + assert( 0 ); + } + } + } + } + for ( b = 0; b < pred_imag_bands_yaw[quant_strat]; b++ ) + { + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + val = hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b].pred_mat_im_idx[ch1][ch2]; + dbgread( &val_ref, sizeof( int16_t ), 1, filename ); + if ( abs( val_ref - val ) > 0 ) + { + assert( 0 ); + } + } + } + } + for ( b = 0; b < d_bands_yaw[quant_strat]; b++ ) + { + val = hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b].gd_idx; + dbgread( &val_ref, sizeof( int16_t ), 1, filename ); + if ( abs( val_ref - val ) > 0 ) + { + assert( 0 ); + } + } + } + else if ( hBinHrSplitPostRend->pose_type[pos_idx] == PITCH_ONLY ) + { + for ( b = 0; b < bands_pitch[quant_strat]; b++ ) + { + val = hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b].gd_idx; + dbgread( &val_ref, sizeof( int16_t ), 1, filename ); + if ( abs( val_ref - val ) > 0 ) + { + assert( 0 ); + } + val = hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b].gd2_idx; + dbgread( &val_ref, sizeof( int16_t ), 1, filename ); + if ( abs( val_ref - val ) > 0 ) + { + assert( 0 ); + } + } + } + else + { + for ( b = 0; b < pred_real_bands_roll[quant_strat]; b++ ) + { + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + val = hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b].pred_mat_re_idx[ch1][ch2]; + dbgread( &val_ref, sizeof( int16_t ), 1, filename ); + if ( abs( val_ref - val ) > 0 ) + { + assert( 0 ); + } + } + } + } + for ( b = 0; b < pred_imag_bands_roll[quant_strat]; b++ ) + { + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + val = hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b].pred_mat_im_idx[ch1][ch2]; + dbgread( &val_ref, sizeof( int16_t ), 1, filename ); + if ( abs( val_ref - val ) > 0 ) + { + assert( 0 ); + } + } + } + } + } + } + } +#endif + + for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) + { + for ( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses - 1; pos_idx++ ) + { + if ( hBinHrSplitPostRend->pose_type[pos_idx] == ANY_YAW ) + { + for ( b = 0; b < pred_imag_bands_yaw[quant_strat]; b++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + ivas_split_rend_unquant_md( hMd, PRED_ONLY, 0, hBinHrSplitPostRend->fix_pos_rot_mat[pos_idx], pred_quantstep_yaw[quant_strat] ); + } + for ( ; b < pred_real_bands_yaw[quant_strat]; b++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + ivas_split_rend_unquant_md( hMd, PRED_ONLY, 1, hBinHrSplitPostRend->fix_pos_rot_mat[pos_idx], pred_quantstep_yaw[quant_strat] ); + } + for ( ; b < MAX_SPLIT_REND_MD_BANDS; b++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + 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; + } + } + for ( b = 0; b < d_bands_yaw[quant_strat]; b++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + ivas_split_rend_unquant_md( hMd, COM_GAIN_ONLY, 1, hBinHrSplitPostRend->fix_pos_rot_mat[pos_idx], 0 ); + } + for ( ; b < MAX_SPLIT_REND_MD_BANDS; b++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + hMd->gd = 0.0f; + } + } + else if ( hBinHrSplitPostRend->pose_type[pos_idx] == PITCH_ONLY ) + { + for ( b = 0; b < bands_pitch[quant_strat]; b++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + ivas_split_rend_unquant_md( hMd, LR_GAIN_ONLY, 1, hBinHrSplitPostRend->fix_pos_rot_mat[pos_idx], 0 ); + } + 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; + } + } + else + { + for ( b = 0; b < pred_imag_bands_roll[quant_strat]; b++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + ivas_split_rend_unquant_md( hMd, PRED_ROLL_ONLY, 0, hBinHrSplitPostRend->fix_pos_rot_mat[pos_idx], IVAS_SPLIT_REND_PRED_ROLL_Q_STEP ); + } + for ( ; b < pred_real_bands_roll[quant_strat]; b++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + ivas_split_rend_unquant_md( hMd, PRED_ROLL_ONLY, 1, hBinHrSplitPostRend->fix_pos_rot_mat[pos_idx], IVAS_SPLIT_REND_PRED_ROLL_Q_STEP ); + } + for ( ; b < MAX_SPLIT_REND_MD_BANDS; b++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + 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; + } + } + } + } + } + +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) + { + float val; + for ( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses - 1; pos_idx++ ) + { + if ( hBinHrSplitPostRend->pose_type[pos_idx] == ANY_YAW ) + { + for ( b = 0; b < pred_real_bands_yaw[quant_strat]; b++ ) + { + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_re_idx[ch1][ch2]; + if ( fabsf( hMd->pred_mat_re_idx[ch1][ch2] - val ) > 1e-20 ) + { + assert( 0 ); + } + } + } + } + for ( b = 0; b < pred_imag_bands_yaw[quant_strat]; b++ ) + { + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_im_idx[ch1][ch2]; + if ( fabsf( hMd->pred_mat_im_idx[ch1][ch2] - val ) > 1e-20 ) + { + assert( 0 ); + } + } + } + } + for ( b = 0; b < d_bands_yaw[quant_strat]; b++ ) + { + val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd_idx; + if ( fabsf( hMd->gd_idx - val ) > 1e-20 ) + { + assert( 0 ); + } + } + } + else if ( hBinHrSplitPostRend->pose_type[pos_idx] == PITCH_ONLY ) + { + for ( b = 0; b < bands_pitch[quant_strat]; b++ ) + { + val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd_idx; + if ( fabsf( hMd->gd_idx - val ) > 1e-20 ) + { + assert( 0 ); + } + val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd2_idx; + if ( fabsf( hMd->gd2_idx - val ) > 1e-20 ) + { + assert( 0 ); + } + } + } + else + { + for ( b = 0; b < pred_real_bands_roll[quant_strat]; b++ ) + { + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_re_idx[ch1][ch2]; + if ( fabsf( hMd->pred_mat_re_idx[ch1][ch2] - val ) > 1e-20 ) + { + assert( 0 ); + } + } + } + } + for ( b = 0; b < pred_imag_bands_roll[quant_strat]; b++ ) + { + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_im_idx[ch1][ch2]; + if ( fabsf( hMd->pred_mat_im_idx[ch1][ch2] - val ) > 1e-20 ) + { + assert( 0 ); + } + } + } + } + } + } + } +#endif + + return; +} + + +/*-----------------------------------------------------------------------------------------* + * Function wrap_around_angle() + * + * + *-----------------------------------------------------------------------------------------*/ + +static void wrap_around_angle( + float *a ) +{ + if ( ( *a ) > 180.0f ) + { + ( *a ) = ( *a ) - 360; + } + else if ( ( *a ) < -180.0f ) + { + ( *a ) = ( *a ) + 360; + } + return; +} + + +/*-----------------------------------------------------------------------------------------* + * Function wrap_around_angle() + * + * + *-----------------------------------------------------------------------------------------*/ + +static void wrap_around_ypr( + IVAS_QUATERNION *Quaternions ) +{ + /*only if quat is actually yaw, pitch , roll angles*/ + if ( Quaternions->w == -3.0f ) + { + wrap_around_angle( &Quaternions->x ); + wrap_around_angle( &Quaternions->y ); + wrap_around_angle( &Quaternions->z ); + } + 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] ) +{ + float n, d, interp_fact; + + if ( 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 ) + { + 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; + } + } + else + { + interp_fact = 0.0f; + } + + return interp_fact; +} + + +/*-----------------------------------------------------------------------------------------* + * 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 ) +{ + float min_diff, diff; + int16_t pos_idx; + + ind[0] = 0; + ind[1] = 0; + min_diff = 360.0f; + + /*find the closest pose from assumed poses*/ + for ( pos_idx = 0; pos_idx < num_poses; pos_idx++ ) + { + diff = fabsf( p_t - p[pos_idx] ); + if ( diff < min_diff ) + { + ind[0] = pos_idx; + min_diff = (float) diff; + } + } + + min_diff = 360.0; + 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 ) ) + { + ind[1] = pos_idx; + min_diff = (float) diff; + } + } + + return; +} + + +/*-----------------------------------------------------------------------------------------* + * Function get_interpolation_vars() + * + * + *-----------------------------------------------------------------------------------------*/ + +static void get_interpolation_vars( + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + const IVAS_QUATERNION *Quaternions_ref, + const IVAS_QUATERNION *Quaternions_act, + 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 ) +{ + 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]; + int16_t pos_idx, num_poses; + + quaternions_diff.x = 0.0f; + quaternions_diff.y = 0.0f; + quaternions_diff.z = 0.0f; + + num_poses = pMultiBinPoseData->num_poses; + 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; + } + + /*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 ); + + interp_yaw_pose_idx[0] = 0; + interp_yaw_pose_idx[1] = 0; + if ( fabs( quaternions_diff.x ) > EPSILON ) + { + get_nearest_pose_ind( y, quaternions_diff.x, interp_yaw_pose_idx, num_poses ); + } + *interp_yaw_fact = get_interp_fact( y, quaternions_diff.x, interp_yaw_pose_idx ); + + interp_pitch_pose_idx[0] = 0; + interp_pitch_pose_idx[1] = 0; + if ( fabs( quaternions_diff.y ) > EPSILON ) + { + get_nearest_pose_ind( p, quaternions_diff.y, interp_pitch_pose_idx, num_poses ); + } + *interp_pitch_fact = get_interp_fact( p, quaternions_diff.y, interp_pitch_pose_idx ); + + interp_roll_pose_idx[0] = 0; + interp_roll_pose_idx[1] = 0; + if ( fabs( quaternions_diff.z ) > EPSILON ) + { + get_nearest_pose_ind( r, quaternions_diff.z, interp_roll_pose_idx, num_poses ); + } + *interp_roll_fact = get_interp_fact( r, quaternions_diff.z, interp_roll_pose_idx ); + + return; +} + + +/*-----------------------------------------------------------------------------------------* + * Function interpolate_gain_matrix() + * + * + *-----------------------------------------------------------------------------------------*/ + +static void interpolate_gain_matrix( + 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 gain[BINAURAL_CHANNELS] ) +{ + float gd1, gd2, gd3, gd4, diff; + + gd1 = 1.0f; + gd2 = 1.0f; + gd3 = 1.0f; + gd4 = 1.0f; + if ( ind[0] != 0 ) + { + gd1 = rot_md[ind[0] - 1][sf_idx][band_idx].gd; + gd3 = rot_md[ind[0] - 1][sf_idx][band_idx].gd2; + } + if ( ind[1] != 0 ) + { + gd2 = rot_md[ind[1] - 1][sf_idx][band_idx].gd; + gd4 = rot_md[ind[1] - 1][sf_idx][band_idx].gd2; + } +#if 0 + diff = gd1 / gd2; + pitch_gain_l = gd2 * powf( diff, 1.0f - interp_pitch_fact ); + pitch_gain_l = max( 0.0f, pitch_gain_l ); + + diff = gd3 / gd4; + pitch_gain_r = gd4 * powf( diff, 1.0f - interp_pitch_fact ); + pitch_gain_r = max( 0.0f, pitch_gain_r ); +#else + diff = gd1 - gd2; + gain[0] = gd1 - ( diff * interp_fact ); + gain[0] = max( 0.0f, gain[0] ); + + diff = gd3 - gd4; + gain[1] = gd3 - ( diff * interp_fact ); + gain[1] = max( 0.0f, gain[1] ); +#endif + + return; +} + + +/*-----------------------------------------------------------------------------------------* + * Function interpolate_pred_matrix() + * + * + *-----------------------------------------------------------------------------------------*/ + +static void interpolate_pred_matrix( + 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] ) +{ + int16_t ch_idx1, ch_idx2; + float diff; + 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++ ) + { + 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; + + 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; + } + + 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_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]; + } + } + } + + 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_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]; + } + } + } + + for ( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) + { + 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 ); + + 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 ); + } + } + + return; +} + + +/*-----------------------------------------------------------------------------------------* + * Function interpolate_rend_md() + * + * + *-----------------------------------------------------------------------------------------*/ + +static void interpolate_rend_md( + 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 ) +{ + 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; + + gd1 = 0.0f; + gd2 = 0.0f; + + idx1 = interp_yaw_pose_idx[0]; + idx2 = interp_yaw_pose_idx[1]; + if ( ( idx1 != 0 ) || ( idx2 != 0 ) ) + { + interpolate_pred_matrix( rot_md, sf_idx, band_idx, interp_yaw_pose_idx, interp_yaw_fact, mix_mat_re, mix_mat_im ); + + if ( idx1 != 0 ) + { + gd1 = rot_md[idx1 - 1][sf_idx][band_idx].gd; + } + + if ( idx2 != 0 ) + { + gd2 = rot_md[idx2 - 1][sf_idx][band_idx].gd; + } + + diff = gd1 - gd2; + *gd_int = gd1 - ( diff * interp_yaw_fact ); + } + else + { + /*P = P'*/ + 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; + } + *gd_int = 0.0f; + } + + idx1 = interp_pitch_pose_idx[0]; + idx2 = interp_pitch_pose_idx[1]; + if ( ( idx1 != 0 ) || ( idx2 != 0 ) ) + { + gd1 = 1.0f; + gd2 = 1.0f; + + gd3 = 1.0f; + gd4 = 1.0f; + + if ( idx1 != 0 ) + { + gd1 = rot_md[idx1 - 1][sf_idx][band_idx].gd; + gd3 = rot_md[idx1 - 1][sf_idx][band_idx].gd2; + } + if ( idx2 != 0 ) + { + gd2 = rot_md[idx2 - 1][sf_idx][band_idx].gd; + gd4 = rot_md[idx2 - 1][sf_idx][band_idx].gd2; + } +#if 0 + diff = gd1 / gd2; + pitch_gain_l = gd2 * powf( diff, 1.0f - interp_pitch_fact ); + pitch_gain_l = max( 0.0f, pitch_gain_l ); + + diff = gd3 / gd4; + pitch_gain_r = gd4 * powf( diff, 1.0f - interp_pitch_fact ); + pitch_gain_r = max( 0.0f, pitch_gain_r ); +#else + 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 ); +#endif + + for ( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) + { + 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; + } + } + else + { + pitch_gain_l = 1.0f; + pitch_gain_r = 1.0f; + } + + idx1 = interp_roll_pose_idx[0]; + idx2 = interp_roll_pose_idx[1]; + if ( ( idx1 != 0 ) || ( idx2 != 0 ) ) + { + interpolate_pred_matrix( rot_md, sf_idx, band_idx, interp_roll_pose_idx, interp_roll_fact, mix_mat_re3, mix_mat_im3 ); + + ivas_mat_mult_2by2_complex( mix_mat_re, mix_mat_im, mix_mat_re3, mix_mat_im3, mix_mat_re1, mix_mat_im1 ); + + for ( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) + { + 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]; + } + } + } + + return; +} + + +/*-----------------------------------------------------------------------------------------* + * Function ivas_SplitRenderer_PostRenderer() + * + * + *-----------------------------------------------------------------------------------------*/ + +void ivas_SplitRenderer_PostRenderer( + 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 */ + const IVAS_QUATERNION Quaternion_act ) +{ + int16_t pos_idx, b, brange[2], ch_idx1; + int16_t num_md_bands, slot_idx, b2, index_slot, num_slots, sf_idx_md; + float pred_out_re[BINAURAL_CHANNELS], pred_out_im[BINAURAL_CHANNELS], tmp_re, tmp_im, gd_int; +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + BIN_HR_SPLIT_REND_MD rot_md_act[MAX_HEAD_ROT_POSES][MAX_SPLIT_REND_MD_BANDS]; +#else + 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]; +#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]; + const int16_t *pBand_grouping = ivas_split_rend_band_grouping; + + num_md_bands = MAX_SPLIT_REND_MD_BANDS; + + push_wmops( "ivas_SplitRenderer_PostRenderer" ); + + num_slots = MAX_PARAM_SPATIAL_SUBFRAMES; +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + pos_idx = MAX_HEAD_ROT_POSES - 1; +#else + pos_idx = 0; +#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++ ) + { + 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; + } + 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++ ) + { + /*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; + } + } + + +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + for ( pos_idx = 0; pos_idx < MAX_HEAD_ROT_POSES - 1; pos_idx++ ) + { + for ( b = 0; b < num_md_bands; b++ ) + { + if ( hBinPostRenderer->pose_type[pos_idx] == PITCH_ONLY ) + { + + for ( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) + { + set_zero( hBinPostRenderer->rot_md[pos_idx][sf_idx][b].pred_mat_re[ch_idx1], BINAURAL_CHANNELS ); + set_zero( hBinPostRenderer->rot_md[pos_idx][sf_idx][b].pred_mat_im[ch_idx1], BINAURAL_CHANNELS ); + hBinPostRenderer->rot_md[pos_idx][sf_idx][b].pred_mat_re[ch_idx1][ch_idx1] = 1.0f; + } + hBinPostRenderer->rot_md[pos_idx][sf_idx][b].pred_mat_re[0][0] *= hBinPostRenderer->rot_md[pos_idx][sf_idx][b].gd; + hBinPostRenderer->rot_md[pos_idx][sf_idx][b].pred_mat_re[1][1] *= hBinPostRenderer->rot_md[pos_idx][sf_idx][b].gd2; + hBinPostRenderer->rot_md[pos_idx][sf_idx][b].gd = 0.0f; + } + else if ( hBinPostRenderer->pose_type[pos_idx] == ANY_ROLL ) + { + hBinPostRenderer->rot_md[pos_idx][sf_idx][b].gd = 0.0f; + } + + 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] = hBinPostRenderer->rot_md[pos_idx][sf_idx][b].pred_mat_re[ch_idx1][0]; + rot_md_act[pos_idx][b].pred_mat_re[ch_idx1][1] = hBinPostRenderer->rot_md[pos_idx][sf_idx][b].pred_mat_re[ch_idx1][1]; + rot_md_act[pos_idx][b].pred_mat_im[ch_idx1][0] = hBinPostRenderer->rot_md[pos_idx][sf_idx][b].pred_mat_im[ch_idx1][0]; + rot_md_act[pos_idx][b].pred_mat_im[ch_idx1][1] = hBinPostRenderer->rot_md[pos_idx][sf_idx][b].pred_mat_im[ch_idx1][1]; + rot_md_act[pos_idx][b].gd = hBinPostRenderer->rot_md[pos_idx][sf_idx][b].gd; + } + } + } + +#endif + +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + for ( pos_idx = 0; pos_idx < MAX_HEAD_ROT_POSES; pos_idx++ ) +#else + pos_idx = 0; +#endif + { + for ( slot_idx = 0; slot_idx < num_slots; slot_idx++ ) + { + index_slot = slot_idx; /* TODO: can be cleaned up */ + fade = ( (float) slot_idx + 1.0f ) / MAX_PARAM_SPATIAL_SUBFRAMES; + fade = min( fade, 1.0f ); + for ( b = 0; b < num_md_bands; b++ ) + { + for ( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) + { + 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]; + } + 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]; + } + } + + brange[0] = pBand_grouping[b]; + brange[1] = pBand_grouping[b + 1]; + for ( b2 = brange[0]; b2 < brange[1]; b2++ ) + { + for ( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) + { + /* Apply prediction matrix */ + IVAS_CMULT_FLOAT( Cldfb_RealBuffer_Ref_Binaural[0][index_slot][b2], + Cldfb_ImagBuffer_Ref_Binaural[0][index_slot][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][index_slot][b2], + Cldfb_ImagBuffer_Ref_Binaural[1][index_slot][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; + } + + + 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][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][index_slot][b2] = pred_out_re[ch_idx1]; + Cldfb_ImagBuffer_Ref_Binaural[ch_idx1][index_slot][b2] = pred_out_im[ch_idx1]; +#endif + } + } + } + } + } + +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + for ( pos_idx = 0; pos_idx < MAX_HEAD_ROT_POSES; pos_idx++ ) +#else + pos_idx = 0; +#endif + { + for ( b = 0; b < num_md_bands; b++ ) + { + 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->gd_mem[pos_idx][b] = rot_md_act[pos_idx][b].gd; + } + } + hBinPostRenderer->cf_flag = 1; + +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + { + int16_t num_cldfb_bands; + num_cldfb_bands = CLDFB_NO_CHANNELS_MAX; + for ( slot_idx = 0; slot_idx < num_slots; slot_idx++ ) + { + index_slot = sf_idx * num_slots + slot_idx; + for ( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) + { + mvr2r( Cldfb_RealBuffer_Recons_Binaural[MAX_HEAD_ROT_POSES - 1][ch_idx1][index_slot], Cldfb_RealBuffer_Ref_Binaural[ch_idx1][index_slot], num_cldfb_bands ); + mvr2r( Cldfb_ImagBuffer_Recons_Binaural[MAX_HEAD_ROT_POSES - 1][ch_idx1][index_slot], Cldfb_ImagBuffer_Ref_Binaural[ch_idx1][index_slot], num_cldfb_bands ); + } + } + + for ( pos_idx = 0; pos_idx < MAX_HEAD_ROT_POSES; pos_idx++ ) + { + char fname[200] = "recons_out_pos"; + char tag[2]; + tag[0] = (char) ( '0' + pos_idx ); + tag[1] = '\0'; + strcat( fname, tag ); + strcat( fname, ".wav" ); + ivas_log_cldfb2wav_data( + Cldfb_RealBuffer_Recons_Binaural[pos_idx], + Cldfb_ImagBuffer_Recons_Binaural[pos_idx], + hBinPostRenderer->cldfbSynReconsBinDec[pos_idx], + BINAURAL_CHANNELS, + num_cldfb_bands, + 48000, + num_slots, + sf_idx * num_slots, + fname ); + } + } +#endif + + pop_wmops(); + return; +} + + +/*-----------------------------------------------------------------------------------------* + * Function ivas_rend_CldfbSplitPostRendProcessTdIn() + * + * + *-----------------------------------------------------------------------------------------*/ + +static void ivas_rend_CldfbSplitPostRendProcessTdIn( + BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend, + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + const IVAS_QUATERNION QuaternionPost, + float output[][L_FRAME48k] ) +{ + 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]; + num_cldfb_bands = hBinHrSplitPostRend->cldfbSyn[0]->no_channels; + + /* Implement CLDFB analysis */ + 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++ ) + { + 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] ); + } + } + + ivas_SplitRenderer_PostRenderer( hBinHrSplitPostRend, pMultiBinPoseData, Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, QuaternionPost ); + + /* Implement CLDFB synthesis */ + 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]; + + 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]; + } + + cldfbSynthesis( RealBuffer, ImagBuffer, &( output[ch_idx][0] ), num_cldfb_bands * CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, hBinHrSplitPostRend->cldfbSyn[ch_idx] ); + } + + return; +} + + +/*-----------------------------------------------------------------------------------------* + * Function ivas_rend_CldfbSplitPostRendProcess() + * + * + *-----------------------------------------------------------------------------------------*/ + +void ivas_rend_CldfbSplitPostRendProcess( + 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 ) +{ + int16_t ch_idx, slot_idx, num_cldfb_bands; + + push_wmops( "ivas_rend_CldfbSplitPostRendProcess" ); + + num_cldfb_bands = hBinHrSplitPostRend->cldfbSyn[0]->no_channels; + + if ( cldfb_in_flag == 0 ) + { + ivas_rend_CldfbSplitPostRendProcessTdIn( hBinHrSplitPostRend, pMultiBinPoseData, QuaternionPost, output ); + pop_wmops(); + return; + } + + ivas_SplitRenderer_PostRenderer( hBinHrSplitPostRend, pMultiBinPoseData, Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, QuaternionPost ); + + /* Implement CLDFB synthesis */ + 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]; + + 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]; + } + + cldfbSynthesis( RealBuffer, ImagBuffer, &( output[ch_idx][0] ), num_cldfb_bands * CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, hBinHrSplitPostRend->cldfbSyn[ch_idx] ); + } + + pop_wmops(); + return; +} + + +/*-----------------------------------------------------------------------------------------* + * Function ivas_init_split_post_rend_handles() + * + * + *-----------------------------------------------------------------------------------------*/ + +void ivas_init_split_post_rend_handles( + SPLIT_POST_REND_WRAPPER *hSplitRendWrapper ) +{ + hSplitRendWrapper->hBinHrSplitPostRend = NULL; + hSplitRendWrapper->hSplitBinLCLDDec = NULL; + hSplitRendWrapper->hLc3plusDec = NULL; + ivas_init_multi_bin_pose_data( &hSplitRendWrapper->multiBinPoseData ); + hSplitRendWrapper->first_good_frame_received = 0; + + return; +} +#endif diff --git a/lib_rend/ivas_splitRendererPre.c b/lib_rend/ivas_splitRendererPre.c new file mode 100644 index 000000000..700117931 --- /dev/null +++ b/lib_rend/ivas_splitRendererPre.c @@ -0,0 +1,2474 @@ +/****************************************************************************************************** + + (C) 2022-2023 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. + +*******************************************************************************************************/ + +#include +#include "options.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT +#include +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG +#include +#endif +#include "ivas_prot.h" +#include "prot.h" +#include "ivas_cnst.h" +#include "ivas_rom_dec.h" +#include "ivas_prot_rend.h" +#ifdef DEBUGGING +#include "debug.h" +#endif +#include "wmc_auto.h" +#ifdef DBG_WAV_WRITER +#include "string.h" +#endif + + +/*------------------------------------------------------------------------- + * Local functions + * + * + *------------------------------------------------------------------------*/ + +static void ivas_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 ) +{ + float re1, im1, re2, im2; + + 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; + + return; +} + + +static int16_t ivas_is_mat_inv_2by2_complex( + float in_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS], + float in_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS] ) +{ + int16_t is_det_zero = 1; + float det, det_re, det_im; + + ivas_calc_mat_det_2by2_complex( in_re, in_im, &det_re, &det_im ); + + det = ( ( det_re * det_re ) + ( det_im * det_im ) ); + + if ( det < EPSILON ) + { + is_det_zero = 0; + } + + return is_det_zero; +} + + +static void ivas_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] ) +{ + float det_re, det_im; + float re, im, det; + + ivas_calc_mat_det_2by2_complex( in_re, in_im, &det_re, &det_im ); + + det = ( det_re * det_re ) + ( det_im * det_im ); + +#ifdef DEBUGGING + /* assert to catch cases when input is singular matrix */ + assert( det > 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; + + 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; + + 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; + + 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], + int16_t num_chs, + int16_t 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; + + trace_cov = 0.0f; + for ( i = 0; i < num_chs; i++ ) + { + trace_cov += cov_ii_re[i][i]; + } + + trace_cov = max( 0.0f, trace_cov ); + + if ( trace_cov < EPSILON ) + { + 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 ); + } + return; + } + + for ( i = 0; i < num_chs; i++ ) + { + mvr2r( cov_ii_re[i], cov_ii_local_re[i], num_chs ); + } + + for ( i = 0; i < num_chs; i++ ) + { + cov_ii_local_re[i][i] = cov_ii_re[i][i] + ( trace_cov * 0.0001f ); + } + + if ( ivas_is_mat_inv_2by2_complex( cov_ii_local_re, cov_ii_im ) ) + { + ivas_calc_mat_inv_2by2_complex( cov_ii_local_re, cov_ii_im, cov_ii_inv_re, cov_ii_inv_im ); + ivas_mat_mult_2by2_complex( cov_ii_inv_re, cov_ii_inv_im, cov_io_re, cov_io_im, pred_mat_re, pred_mat_im ); + } + else + { + int16_t max_var_idx; + for ( i = 0; i < num_chs; i++ ) + { + set_zero( pred_mat_re[i], BINAURAL_CHANNELS ); + set_zero( pred_mat_im[i], BINAURAL_CHANNELS ); + } + + max_var_idx = 0; + if ( cov_ii_local_re[1][1] > cov_ii_local_re[0][0] ) + { + max_var_idx = 1; + } + + if ( cov_ii_local_re[max_var_idx][max_var_idx] > EPSILON ) + { + 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]; + } + } + } + + if ( real_only ) + { + for ( i = 0; i < num_chs; i++ ) + { + set_zero( pred_mat_im[i], 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], + float postpred_cov_im[][BINAURAL_CHANNELS], + int16_t 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]; + + assert( num_chs == BINAURAL_CHANNELS ); + for ( i = 0; i < num_chs; i++ ) + { + 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]; + } + set_zero( postpred_cov_re[i], BINAURAL_CHANNELS ); + set_zero( postpred_cov_im[i], BINAURAL_CHANNELS ); + } + + /* 2x2 mult */ + ivas_mat_mult_2by2_complex( dmx_mat_conj_re, dmx_mat_conj_im, cov_ii_re, cov_ii_im, temp_mat_re, temp_mat_im ); + ivas_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 ( j = 0; j < i; j++ ) + { + postpred_cov_re[i][j] = postpred_cov_re[j][i]; + postpred_cov_im[i][j] = -postpred_cov_im[j][i]; + } + postpred_cov_im[i][i] = 0; + } + + 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 ) +{ + int16_t sf, cldfb_band_idx, ch_idx1, ch_idx2; + int16_t brange[2]; + + 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 ); + } + + brange[0] = pBand_grouping[md_band_idx]; + brange[1] = pBand_grouping[md_band_idx + 1]; + + for ( ch_idx1 = 0; ch_idx1 < num_chs; ch_idx1++ ) + { + for ( ch_idx2 = 0; ch_idx2 < num_chs; ch_idx2++ ) + { + if ( real_only == 0 ) + { + for ( sf = start_slot_idx; sf < start_slot_idx + num_slots; sf++ ) + { + 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]; + } + } + } + else + { + for ( sf = start_slot_idx; sf < start_slot_idx + num_slots; sf++ ) + { + 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; + } + } + } + } + } + + 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 ) +{ + int16_t sf, cldfb_band_idx, ch_idx1, ch_idx2; + int16_t brange[2]; + + 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 ); + } + + brange[0] = pBand_grouping[md_band_idx]; + brange[1] = pBand_grouping[md_band_idx + 1]; + + for ( ch_idx1 = 0; ch_idx1 < num_chs; ch_idx1++ ) + { + for ( ch_idx2 = 0; ch_idx2 <= ch_idx1; ch_idx2++ ) + { + if ( ( ch_idx2 != ch_idx1 ) && ( real_only == 0 ) ) + { + for ( sf = start_slot_idx; sf < start_slot_idx + num_slots; sf++ ) + { + 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]; + } + } + } + else + { + for ( sf = start_slot_idx; sf < start_slot_idx + num_slots; sf++ ) + { + 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] = 0.0f; + } + } + } + } + } + + for ( ch_idx1 = 0; ch_idx1 < num_chs; ch_idx1++ ) + { + for ( ch_idx2 = ch_idx1 + 1; ch_idx2 < num_chs; ch_idx2++ ) + { + 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]; + } + } + + return; +} + + +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] ) +{ + int16_t i, j; + float norm_fact, abs_val; + + norm_fact = 0.0f; + for ( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + 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_RABS( cov_oo_re[i][j], abs_val ); + norm_fact = max( norm_fact, abs_val ); + } + } + + norm_fact = ( norm_fact > EPSILON ) ? norm_fact : 1.0f; + + norm_fact = PCM16_TO_FLT_FAC / norm_fact; + + return norm_fact; +} + + +static void ivas_split_rend_huffman_encode( + ivas_split_rend_huffman_cfg_t *huff_cfg, + int16_t in, + int32_t *hcode, + int32_t *hlen ) +{ + int32_t min_sym_val; + const int32_t *codebook; + + min_sym_val = huff_cfg->codebook[0]; + + codebook = &huff_cfg->codebook[3 * ( in - min_sym_val )]; + *hlen = codebook[1]; + *hcode = codebook[2]; + + return; +} + + +static void ivas_split_rend_quant_md( + BIN_HR_SPLIT_REND_MD_HANDLE hMd, + IVAS_SPLIT_REND_POSE_TYPE pose_type, + int16_t real_only, + float fix_pos_rot_mat[][BINAURAL_CHANNELS], + const float pred_1byquantstep ) +{ + int16_t ch1, ch2; + int16_t gd_idx_min; + float sign, quant_val; + + if ( pose_type == PRED_ONLY || pose_type == PRED_ROLL_ONLY ) + { + float onebyquantstep; + + onebyquantstep = pred_1byquantstep; + if ( real_only == 1 ) + { + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + 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; + } + } + } + + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + quant_val = hMd->pred_mat_re[ch1][ch2] - fix_pos_rot_mat[ch1][ch2]; + quant_val = min( IVAS_SPLIT_REND_PRED_MAX_VAL, max( quant_val, IVAS_SPLIT_REND_PRED_MIN_VAL ) ); + hMd->pred_mat_re_idx[ch1][ch2] = (int16_t) roundf( onebyquantstep * quant_val ); + } + } + + if ( real_only == 0 ) + { + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + quant_val = min( IVAS_SPLIT_REND_PRED_MAX_VAL, max( hMd->pred_mat_im[ch1][ch2], IVAS_SPLIT_REND_PRED_MIN_VAL ) ); + hMd->pred_mat_im_idx[ch1][ch2] = (int16_t) roundf( onebyquantstep * quant_val ); + // hMd->pred_mat_im[ch1][ch2] = hMd->pred_mat_im_idx[ch1][ch2] * IVAS_SPLIT_REND_PRED_Q_STEP; + } + } + } + } + else if ( pose_type == COM_GAIN_ONLY ) + { + quant_val = min( IVAS_SPLIT_REND_D_MAX_VAL, max( hMd->gd, IVAS_SPLIT_REND_D_MIN_VAL ) ); + gd_idx_min = (int16_t) roundf( IVAS_SPLIT_REND_D_1BYQ_STEP * IVAS_SPLIT_REND_D_MIN_VAL ); + hMd->gd_idx = (int16_t) roundf( IVAS_SPLIT_REND_D_1BYQ_STEP * quant_val ); + hMd->gd = hMd->gd_idx * IVAS_SPLIT_REND_D_Q_STEP; + hMd->gd_idx = hMd->gd_idx - gd_idx_min; + } + else if ( pose_type == LR_GAIN_ONLY ) + { + quant_val = min( IVAS_SPLIT_REND_PITCH_G_MAX_VAL, max( hMd->gd, IVAS_SPLIT_REND_PITCH_G_MIN_VAL ) ); + gd_idx_min = (int16_t) roundf( IVAS_SPLIT_REND_PITCH_G_1BYQ_STEP * IVAS_SPLIT_REND_PITCH_G_MIN_VAL ); + hMd->gd_idx = (int16_t) roundf( IVAS_SPLIT_REND_PITCH_G_1BYQ_STEP * quant_val ); + hMd->gd_idx = hMd->gd_idx - gd_idx_min; + + quant_val = min( IVAS_SPLIT_REND_PITCH_G_MAX_VAL, max( hMd->gd2, IVAS_SPLIT_REND_PITCH_G_MIN_VAL ) ); + hMd->gd2_idx = (int16_t) roundf( IVAS_SPLIT_REND_PITCH_G_1BYQ_STEP * quant_val ); + hMd->gd2_idx = hMd->gd2_idx - gd_idx_min; + } + + return; +} + + +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], + BIN_HR_SPLIT_REND_MD_HANDLE hMd, + const IVAS_SPLIT_REND_POSE_TYPE pose_type, + const int16_t real_only ) +{ + float postpred_cov_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + float postpred_cov_im[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]; + + for ( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + gd_tmp[i] = cov_ii_re[i][i]; + if ( gd_tmp[i] < EPSILON ) + { + gd_tmp[i] = 1.0f; + } + else + { + gd_tmp[i] = ( cov_oo_re[i][i] ) / gd_tmp[i]; + gd_tmp[i] = sqrtf( gd_tmp[i] ); + } + } + hMd->gd = gd_tmp[0]; + hMd->gd2 = gd_tmp[1]; + } + else + { + cov_norm_fact = GetNormFact( cov_ii_re, cov_ii_im, cov_io_re, cov_io_im, cov_oo_re ); + + /* normalize the covariance */ + for ( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + 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; + } + } + + 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 ); + + /*TODO : change this function to real only as thats what is needed*/ + ComputePostPredCov( cov_ii_norm_re, cov_ii_norm_im, hMd->pred_mat_re, hMd->pred_mat_im, postpred_cov_re, postpred_cov_im, BINAURAL_CHANNELS ); + + /* normalize everything to +-1 range */ + gd = 1.0f / ( PCM16_TO_FLT_FAC ); + for ( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + 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; + } + } + +#if 0 + if ( 1 ) + { +#endif + gd2 = 0.0f; + sigma_d = 0.0f; + hMd->gd = 0.0f; +#if 0 + } + else + { + + sigma_d = cov_ii_norm_re[0][0] + cov_ii_norm_re[1][1] + cov_ii_norm_re[0][1] + cov_ii_norm_re[1][0] + EPSILON; + + rho_hat = max( EPSILON, sqrtf( postpred_cov_re[0][0] * postpred_cov_re[1][1] ) ); + rho_hat = postpred_cov_re[0][1] / rho_hat; + rho = max( EPSILON, sqrtf( cov_oo_norm_re[0][0] * cov_oo_norm_re[1][1] ) ); + rho = cov_oo_norm_re[0][1] / rho; + rho_hat = min( max( rho_hat, -0.9999f ), 0.9999f ); + rho = min( max( rho, -0.9999f ), 0.9999f ); + + // Compute decorrelator gain : gd2 = 0; + gd = 0; + gd2 = 0; + + aa = ( sigma_d * sigma_d ) * ( ( rho_hat * rho_hat ) - 1 ) + EPSILON; + bb = -( rho_hat * rho_hat ) * sigma_d * ( cov_oo_norm_re[0][0] + cov_oo_norm_re[1][1] ); + cc = ( rho_hat * rho_hat ) * cov_oo_norm_re[0][0] * cov_oo_norm_re[1][1]; + cc -= cov_oo_norm_re[0][1] * cov_oo_norm_re[0][1]; + + sign = +1.0f; + if ( rho < ( rho_hat - 0.0001 ) ) + { + bb -= 2 * sigma_d * cov_oo_norm_re[0][1]; + sign = -1.0f; + } + else if ( rho > ( rho_hat + 0.0001 ) ) + { + bb += 2 * sigma_d * cov_oo_norm_re[0][1]; + } + dd = bb * bb - ( 4 * aa * cc ); + if ( dd >= 0 ) + { + float gd2_1, gd2_2; + gd2_1 = ( -bb + sqrtf( dd ) ) / ( 2 * aa ); + gd2_2 = ( -bb - sqrtf( dd ) ) / ( 2 * aa ); + if ( ( gd2_1 >= 0 ) && ( gd2_2 >= 0 ) ) + { + gd2 = min( gd2_1, gd2_2 ); + } + else + { + gd2 = max( 0, max( gd2_1, gd2_2 ) ); + } + gd = sign * sqrtf( gd2 ); + } + + gd = min( IVAS_SPLIT_REND_D_MAX_VAL, max( gd, IVAS_SPLIT_REND_D_MIN_VAL ) ); + hMd->gd = SPLIT_REND_DECOR_ALPHA * gd + ( 1 - SPLIT_REND_DECOR_ALPHA ) * hMd->gd; + gd2 = min( gd2, cov_oo_norm_re[0][0] / sigma_d ); + gd2 = min( gd2, cov_oo_norm_re[1][1] / sigma_d ); + } +#endif /* 0 */ + + if ( postpred_cov_re[0][0] > EPSILON ) + { + 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 ); + } + else + { + gl2 = 1.0f; + } + + if ( postpred_cov_re[1][1] > EPSILON ) + { + 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 ); + } + else + { + gr2 = 1.0f; + } + + for ( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + hMd->pred_mat_re[i][0] *= gl2; + hMd->pred_mat_re[i][1] *= gr2; + } + + if ( real_only == 0 ) + { + for ( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + hMd->pred_mat_im[i][0] *= gl2; + hMd->pred_mat_im[i][1] *= gr2; + } + } + } + + return; +} + + +static void get_base2_bits( + const 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[IVAS_SPLIT_REND_NUM_QUANT_STRATS], + const int16_t pred_imag_bands_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], + int16_t pred_quant_pnts_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], + const int16_t d_bands_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], + const int16_t bands_pitch[IVAS_SPLIT_REND_NUM_QUANT_STRATS], + const int16_t pred_real_bands_roll[IVAS_SPLIT_REND_NUM_QUANT_STRATS], + const int16_t pred_imag_bands_roll[IVAS_SPLIT_REND_NUM_QUANT_STRATS], + int32_t base2bits[IVAS_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[IVAS_SPLIT_REND_NUM_QUANT_STRATS]; + + IVAS_SPLIT_REND_POSE_TYPE pose_type; + + for ( q = 0; q < num_quant_strats; q++ ) + { + pred_yaw_bits[q] = (int16_t) ceilf( log2f( pred_quant_pnts_yaw[q] ) ); + } + pred_roll_bits = (int16_t) ceilf( log2f( IVAS_SPLIT_REND_ROLL_PRED_QUANT_PNTS ) ); + + d_gain_bits = (int16_t) ceilf( log2f( IVAS_SPLIT_REND_D_QUANT_PNTS ) ); + pitch_gain_bits = d_gain_bits; + + for ( q = 0; q < num_quant_strats; q++ ) + { + base2bits[q] = 0; + } + + for ( q = 0; q < num_quant_strats; q++ ) + { + for ( pose_idx = 0; pose_idx < pMultiBinPoseData->num_poses - 1; pose_idx++ ) + { + pose_type = hBinHrSplitPreRend->pose_type[pose_idx]; + if ( pose_type == ANY_YAW ) + { + 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] += d_gain_bits * d_bands_yaw[q] * num_subframes; + } + else if ( pose_type == PITCH_ONLY ) + { + base2bits[q] += pitch_gain_bits * bands_pitch[q] * num_subframes; + base2bits[q] += pitch_gain_bits * bands_pitch[q] * num_subframes; + } + else + { + 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; + } + } + } + + return; +} + + +static void ivas_SplitRenderer_code_md_base2( + const 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, + IVAS_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; + BIN_HR_SPLIT_REND_MD_HANDLE hMd; + BIN_HR_SPLIT_REND_HUFF_HANDLE pHuff_cfg; + + pHuff_cfg = &hBinHrSplitPreRend->huff_cfg; + if ( pred_quant_pnts_yaw == IVAS_SPLIT_REND_PRED_63QUANT_PNTS ) + { + pred_cb_idx = 1; + } + else + { + pred_cb_idx = 0; + } + 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]; + + pred_code_len = pHuff_cfg->pred_base2_code_len[pred_cb_idx]; + pred_roll_code_len = pHuff_cfg->pred_roll_base2_code_len; + gd_code_len = pHuff_cfg->gd_base2_code_len; + p_gd_code_len = pHuff_cfg->p_gd_base2_code_len; + + num_poses = pMultiBinPoseData->num_poses; + + for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) + { + for ( pos_idx = 0; pos_idx < num_poses - 1; pos_idx++ ) + { + if ( hBinHrSplitPreRend->pose_type[pos_idx] == ANY_YAW ) + { + 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 ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + code = hMd->pred_mat_re_idx[ch1][ch2] - min_pred_idx; + ivas_split_rend_bitstream_write_int32( pBits, code, pred_code_len ); + } + } + } + + 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 ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + code = hMd->pred_mat_im_idx[ch1][ch2] - min_pred_idx; + ivas_split_rend_bitstream_write_int32( pBits, code, pred_code_len ); + } + } + } + for ( b = 0; b < d_bands_yaw; b++ ) + { + hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; + code = hMd->gd_idx - min_gd_idx; + ivas_split_rend_bitstream_write_int32( pBits, code, gd_code_len ); + } + } + else if ( hBinHrSplitPreRend->pose_type[pos_idx] == PITCH_ONLY ) + { + for ( b = 0; b < bands_pitch; b++ ) + { + hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; + code = hMd->gd_idx - min_p_gd_idx; + ivas_split_rend_bitstream_write_int32( pBits, code, p_gd_code_len ); + + code = hMd->gd2_idx - min_p_gd_idx; + ivas_split_rend_bitstream_write_int32( pBits, code, p_gd_code_len ); + } + } + else + { + 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 ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + code = hMd->pred_mat_re_idx[ch1][ch2] - min_pred_roll_idx; + ivas_split_rend_bitstream_write_int32( pBits, code, pred_roll_code_len ); + } + } + } + + 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 ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + code = hMd->pred_mat_im_idx[ch1][ch2] - min_pred_roll_idx; + ivas_split_rend_bitstream_write_int32( pBits, code, pred_roll_code_len ); + } + } + } + } + } + } + +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + { + static int16_t num_bits = 0; + static int16_t cntr = 0; + float fnum_bits; + + cntr++; + + num_bits += pBits->bits_written; + /* collect bits for every second */ + if ( cntr == 50 ) + { + cntr = 0; + fnum_bits = (float) num_bits / 1000.0f; + dbgwrite_txt( &fnum_bits, 1, "split_rend_MD_bitrate.txt", "MD bitrate (kbps)" ); + num_bits = 0; + } + } +#endif + return; +} + + +static void ivas_SplitRenderer_code_md_huff( + const 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, + IVAS_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; + BIN_HR_SPLIT_REND_MD_HANDLE hMd; + BIN_HR_SPLIT_REND_HUFF_HANDLE pHuff_cfg; + + pHuff_cfg = &hBinHrSplitPreRend->huff_cfg; + + if ( pred_quant_pnts_yaw == IVAS_SPLIT_REND_PRED_63QUANT_PNTS ) + { + pred_cb_idx = 1; + } + else + { + pred_cb_idx = 0; + } + + 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[( IVAS_SPLIT_REND_ROLL_PRED_QUANT_PNTS - 1 ) * 3]; + + num_poses = pMultiBinPoseData->num_poses; + + for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) + { + for ( pos_idx = 0; pos_idx < num_poses - 1; pos_idx++ ) + { + if ( hBinHrSplitPreRend->pose_type[pos_idx] == ANY_YAW ) + { + for ( b = 0; b < pred_real_bands_yaw; b++ ) + { + hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; + ivas_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 ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + ivas_split_rend_huffman_encode( &pHuff_cfg->pred[pred_cb_idx], sym_adj_idx[ch1][ch2], &code, &len ); + ivas_split_rend_bitstream_write_int32( pBits, code, len ); + } + } + } + for ( b = 0; b < pred_imag_bands_yaw; b++ ) + { + hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; + ivas_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 ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + + ivas_split_rend_huffman_encode( &pHuff_cfg->pred[pred_cb_idx], sym_adj_idx[ch1][ch2], &code, &len ); + + ivas_split_rend_bitstream_write_int32( pBits, code, len ); + } + } + } + for ( b = 0; b < d_bands_yaw; b++ ) + { + hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; + ivas_split_rend_huffman_encode( &pHuff_cfg->gd, hMd->gd_idx, &code, &len ); + ivas_split_rend_bitstream_write_int32( pBits, code, len ); + } + } + else if ( hBinHrSplitPreRend->pose_type[pos_idx] == PITCH_ONLY ) + { + for ( b = 0; b < bands_pitch; b++ ) + { + hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; + ivas_split_rend_huffman_encode( &pHuff_cfg->p_gd, hMd->gd_idx, &code, &len ); + ivas_split_rend_bitstream_write_int32( pBits, code, len ); + + ivas_split_rend_huffman_encode( &pHuff_cfg->p_gd, hMd->gd2_idx, &code, &len ); + ivas_split_rend_bitstream_write_int32( pBits, code, len ); + } + } + else + { + for ( b = 0; b < pred_real_bands_roll; b++ ) + { + hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; + ivas_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 ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + ivas_split_rend_huffman_encode( &pHuff_cfg->pred_roll, sym_adj_idx[ch1][ch2], &code, &len ); + ivas_split_rend_bitstream_write_int32( pBits, code, len ); + } + } + } + for ( b = 0; b < pred_imag_bands_roll; b++ ) + { + hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; + ivas_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 ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + ivas_split_rend_huffman_encode( &pHuff_cfg->pred_roll, sym_adj_idx[ch1][ch2], &code, &len ); + ivas_split_rend_bitstream_write_int32( pBits, code, len ); + } + } + } + } + } + } + +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + { + static int16_t num_bits = 0; + static int16_t cntr = 0; + float fnum_bits; + + cntr++; + num_bits += pBits->bits_written; + /* collect bits for every second */ + if ( cntr == 50 ) + { + cntr = 0; + fnum_bits = (float) num_bits / 1000.0f; + dbgwrite_txt( &fnum_bits, 1, "split_rend_MD_bitrate.txt", "MD bitrate (kbps)" ); + num_bits = 0; + } + } +#endif + return; +} + + +static void ivas_SplitRenderer_quant_code( + const BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, + const IVAS_QUATERNION headPosition, + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + IVAS_SPLIT_REND_BITS_HANDLE pBits, + const int16_t low_res_pre_rend_rot, + const int32_t target_md_bits ) +{ + int16_t num_complex_bands, q, num_subframes, sf_idx, pos_idx, b, num_quant_strats; + int32_t overhead_bits, quant_strat_bits, huff_bits, start_bit; + int16_t pred_real_bands_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], pred_real_bands_roll[IVAS_SPLIT_REND_NUM_QUANT_STRATS]; + int16_t pred_imag_bands_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], pred_imag_bands_roll[IVAS_SPLIT_REND_NUM_QUANT_STRATS]; + int16_t d_bands_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], bands_pitch[IVAS_SPLIT_REND_NUM_QUANT_STRATS]; + int32_t base2bits[IVAS_SPLIT_REND_NUM_QUANT_STRATS]; + int16_t pred_quant_pnts_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS]; + float pred_1byquantstep_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS]; + float pred_quantstep_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS]; + BIN_HR_SPLIT_REND_MD_HANDLE hMd; + + if ( low_res_pre_rend_rot ) + { + num_subframes = 1; + } + else + { + num_subframes = MAX_PARAM_SPATIAL_SUBFRAMES; + } + + overhead_bits = pBits->bits_written; + + ivas_split_rend_bitstream_write_int32( pBits, pMultiBinPoseData->dof, IVAS_SPLIT_REND_DOF_BITS ); + ivas_split_rend_bitstream_write_int32( pBits, pMultiBinPoseData->hq_mode, IVAS_SPLIT_REND_HQ_MODE_BITS ); + ivas_split_rend_bitstream_write_int32( pBits, (int32_t) pMultiBinPoseData->rot_axis, IVAS_SPLIT_REND_ROT_AXIS_BITS ); + + /* code ref pose*/ + for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) + { + int16_t 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; + ivas_split_rend_bitstream_write_int32( pBits, angle, IVAS_SPLIT_REND_HEAD_POSE_BITS ); + + angle = (int16_t) roundf( head_pos_euler.y ); + angle += 180; + ivas_split_rend_bitstream_write_int32( pBits, angle, IVAS_SPLIT_REND_HEAD_POSE_BITS ); + + angle = (int16_t) roundf( head_pos_euler.z ); + angle += 180; + + ivas_split_rend_bitstream_write_int32( pBits, angle, IVAS_SPLIT_REND_HEAD_POSE_BITS ); + } + + ivas_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 ); + + 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 */ + + 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 ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) + { + for ( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses - 1; pos_idx++ ) + { + if ( hBinHrSplitPreRend->pose_type[pos_idx] == ANY_YAW ) + { + for ( b = 0; b < pred_imag_bands_yaw[q]; b++ ) + { + hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; + + ivas_split_rend_quant_md( hMd, PRED_ONLY, 0, hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx], pred_1byquantstep_yaw[q] ); + } + for ( ; b < pred_real_bands_yaw[q]; b++ ) + { + hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; + + ivas_split_rend_quant_md( hMd, PRED_ONLY, 1, hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx], pred_1byquantstep_yaw[q] ); + } + + for ( b = 0; b < d_bands_yaw[q]; b++ ) + { + hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; + + ivas_split_rend_quant_md( hMd, COM_GAIN_ONLY, 1, hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx], 0 ); + } + } + else if ( hBinHrSplitPreRend->pose_type[pos_idx] == PITCH_ONLY ) + { + for ( b = 0; b < bands_pitch[q]; b++ ) + { + hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; + ivas_split_rend_quant_md( hMd, LR_GAIN_ONLY, 1, hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx], 0 ); + } + } + else + { + for ( b = 0; b < pred_imag_bands_roll[q]; b++ ) + { + hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; + ivas_split_rend_quant_md( hMd, PRED_ROLL_ONLY, 0, hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx], IVAS_SPLIT_REND_PRED_ROLL_1BYQ_STEP ); + } + for ( ; b < pred_real_bands_roll[q]; b++ ) + { + hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; + ivas_split_rend_quant_md( hMd, PRED_ROLL_ONLY, 1, hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx], IVAS_SPLIT_REND_PRED_ROLL_1BYQ_STEP ); + } + } + } + } + + /*get base2 bits and check if its within target. if yes then code with base2 to save complexity on post renderer*/ + start_bit = pBits->bits_written; + + ivas_split_rend_bitstream_write_int32( pBits, 1, 1 ); + ivas_split_rend_bitstream_write_int32( pBits, q, quant_strat_bits ); + + huff_bits = pBits->bits_written; + ivas_SplitRenderer_code_md_huff( + hBinHrSplitPreRend, + pMultiBinPoseData, + num_subframes, + pred_real_bands_yaw[q], + pred_imag_bands_yaw[q], + pred_quant_pnts_yaw[q], + d_bands_yaw[q], + bands_pitch[q], + pred_real_bands_roll[q], + 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 ) ) ) + { + if ( huff_bits > base2bits[q] ) + { + pBits->bits_written = start_bit; + + ivas_split_rend_bitstream_write_int32( pBits, 0, 1 ); + ivas_split_rend_bitstream_write_int32( pBits, q, quant_strat_bits ); + + ivas_SplitRenderer_code_md_base2( hBinHrSplitPreRend, pMultiBinPoseData, num_subframes, pred_real_bands_yaw[q], pred_imag_bands_yaw[q], + pred_quant_pnts_yaw[q], + d_bands_yaw[q], bands_pitch[q], pred_real_bands_roll[q], pred_imag_bands_roll[q], pBits ); + } + break; + } + + pBits->bits_written = start_bit; + } + +#ifdef SPLIT_MD_CODING_DEBUG + for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) + { + int16_t val, quant_strat, ch1, ch2; + char filename[200] = "split_md_debug_indices.bin"; + quant_strat = q; + for ( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses - 1; pos_idx++ ) + { + if ( hBinHrSplitPreRend->pose_type[pos_idx] == ANY_YAW ) + { + for ( b = 0; b < pred_real_bands_yaw[quant_strat]; b++ ) + { + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_re_idx[ch1][ch2]; + dbgwrite( &val, sizeof( int16_t ), 1, 1, filename ); + } + } + } + for ( b = 0; b < pred_imag_bands_yaw[quant_strat]; b++ ) + { + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_im_idx[ch1][ch2]; + dbgwrite( &val, sizeof( int16_t ), 1, 1, filename ); + } + } + } + for ( b = 0; b < d_bands_yaw[quant_strat]; b++ ) + { + val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd_idx; + dbgwrite( &val, sizeof( int16_t ), 1, 1, filename ); + } + } + else if ( hBinHrSplitPreRend->pose_type[pos_idx] == PITCH_ONLY ) + { + for ( b = 0; b < bands_pitch[quant_strat]; b++ ) + { + val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd_idx; + dbgwrite( &val, sizeof( int16_t ), 1, 1, filename ); + val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd2_idx; + dbgwrite( &val, sizeof( int16_t ), 1, 1, filename ); + } + } + else + { + for ( b = 0; b < pred_real_bands_roll[quant_strat]; b++ ) + { + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_re_idx[ch1][ch2]; + dbgwrite( &val, sizeof( int16_t ), 1, 1, filename ); + } + } + } + for ( b = 0; b < pred_imag_bands_roll[quant_strat]; b++ ) + { + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_im_idx[ch1][ch2]; + dbgwrite( &val, sizeof( int16_t ), 1, 1, filename ); + } + } + } + } + } + } +#endif + + return; +} + + +/*------------------------------------------------------------------------- + * Function ivas_SplitRenderer_GetRotMd() + * + * + *------------------------------------------------------------------------*/ + +void ivas_SplitRenderer_GetRotMd( + 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 ) +{ + 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 = ivas_split_rend_band_grouping; + + push_wmops( "ivas_SplitRenderer_GetRotMd" ); + + num_md_bands = MAX_SPLIT_REND_MD_BANDS; + num_poses = pMultiBinPoseData->num_poses; + + if ( low_res ) + { + num_slots = CLDFB_NO_COL_MAX; + num_subframes = 1; + } + else + { + num_slots = MAX_PARAM_SPATIAL_SUBFRAMES; + num_subframes = MAX_PARAM_SPATIAL_SUBFRAMES; + } + + /* compute reference signal covariance */ + 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++ ) + { + if ( b < COMPLEX_MD_BAND_THRESH ) + { + real_only = 0; + } + else + { + real_only = 1; + } + + 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 ); + + /* compute rotated signal covariance */ + for ( pos_idx = 0; pos_idx < num_poses - 1; pos_idx++ ) + { + 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 ); + + 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 ); + + 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 ); + } + } + } + + pop_wmops(); + return; +} + + +/*------------------------------------------------------------------------- + * Function ivas_rend_CldfbSplitPreRendProcess() + * + * + *------------------------------------------------------------------------*/ + +void ivas_rend_CldfbSplitPreRendProcess( + const 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], + IVAS_SPLIT_REND_BITS_HANDLE pBits, + const int32_t target_md_bits, + const int16_t low_res_pre_rend_rot ) +{ + push_wmops( "ivas_rend_CldfbSplitPreRendProcess" ); + + ivas_SplitRenderer_GetRotMd( hBinHrSplitPreRend, pMultiBinPoseData, Cldfb_In_BinReal, Cldfb_In_BinImag, low_res_pre_rend_rot ); + + ivas_SplitRenderer_quant_code( hBinHrSplitPreRend, headPosition, pMultiBinPoseData, pBits, low_res_pre_rend_rot, target_md_bits ); + +#ifdef SPLIT_POSE_CORRECTION_DEBUG + float tmpCrendBuffer[2][L_FRAME48k], quant_val, step, minv, maxv; + IVAS_QUATERNION QuaternionsPost[MAX_PARAM_SPATIAL_SUBFRAMES]; + int16_t sf_idx, pos_idx, b, ch1, ch2; + int32_t read_off, write_off; + for ( sf_idx = 0; sf_idx < MAX_PARAM_SPATIAL_SUBFRAMES; sf_idx++ ) + { + QuaternionsPost[sf_idx].w = -3.0f; + QuaternionsPost[sf_idx].x = 0.0f; + QuaternionsPost[sf_idx].y = 0.0f; + QuaternionsPost[sf_idx].z = 0.0f; + } + +#if 0 + read_off = pBits->bits_read; + write_off = pBits->bits_written; + ivas_splitBinPostRendMdDec( + pBits, + hBinHrSplitPreRend->hBinHrSplitPostRend, + pMultiBinPoseData ); + pMultiBinPoseData->poseCorrectionMode = IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB; + pBits->bits_read = read_off; + pBits->bits_written = write_off; +#else + hBinHrSplitPreRend->hBinHrSplitPostRend->low_Res = 1; + set_fix_rotation_mat( hBinHrSplitPreRend->hBinHrSplitPostRend->fix_pos_rot_mat, pMultiBinPoseData ); + set_pose_types( hBinHrSplitPreRend->hBinHrSplitPostRend->pose_type, pMultiBinPoseData ); + for ( sf_idx = 0; sf_idx < MAX_PARAM_SPATIAL_SUBFRAMES; sf_idx++ ) + { + hBinHrSplitPreRend->hBinHrSplitPostRend->QuaternionsPre[sf_idx] = headPositions[sf_idx]; + } + for ( sf_idx = 0; sf_idx < 1; sf_idx++ ) + { + for ( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses - 1; pos_idx++ ) + { + for ( b = 0; b < MAX_SPLIT_REND_MD_BANDS; b++ ) + { + hBinHrSplitPreRend->hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b] = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; +#if 0 + BIN_HR_SPLIT_REND_MD_HANDLE hMd; + hMd = &hBinHrSplitPreRend->hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + minv = -1.4f; + maxv = 1.4f; + step = ( maxv - minv ) / 30.0f; + if ( b >= 20 ) + { + float sign; + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + 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; + } + } + } + + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + quant_val = hMd->pred_mat_re[ch1][ch2] - hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx][ch1][ch2]; + quant_val = min( maxv, max( quant_val, minv ) ); + quant_val = (int16_t) roundf( quant_val / step ); + hMd->pred_mat_re[ch1][ch2] = quant_val * step; + hMd->pred_mat_re[ch1][ch2] += hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx][ch1][ch2]; + + quant_val = hMd->pred_mat_im[ch1][ch2]; + quant_val = min( maxv, max( quant_val, minv ) ); + quant_val = (int16_t) roundf( quant_val / step ); + hMd->pred_mat_im[ch1][ch2] = quant_val * step; + } + } +#endif + } + } + } + +#endif + ivas_rend_CldfbSplitPostRendProcess( hBinHrSplitPreRend->hBinHrSplitPostRend, pMultiBinPoseData, QuaternionsPost, Cldfb_In_BinReal[0], Cldfb_In_BinImag[0], tmpCrendBuffer, 1 ); + + { + float *pOut[2]; + char fname[200] = "ref_act_pos.wav"; + pOut[0] = tmpCrendBuffer[0]; + pOut[1] = tmpCrendBuffer[1]; + dbgwrite_wav( pOut, CLDFB_NO_COL_MAX * hBinHrSplitPreRend->hBinHrSplitPostRend->cldfbSyn[0]->no_channels, fname, 48000, 2 ); + } +#endif + + pop_wmops(); + return; +} + + +/*------------------------------------------------------------------------- + * Function ivas_splitBinPreRendOpen() + * + * + *------------------------------------------------------------------------*/ + +ivas_error ivas_splitBinPreRendOpen( + 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 +) +{ + BIN_HR_SPLIT_PRE_REND_HANDLE hBinRend; +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + ivas_error error; + int16_t ch; +#endif + int16_t pos_idx, sf_idx, bandIdx; + + if ( ( hBinRend = (BIN_HR_SPLIT_PRE_REND_HANDLE) malloc( sizeof( BIN_HR_SPLIT_PRE_REND ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for bin split pre renderer Module \n" ) ); + } + +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + for ( int16_t i = 0; i < MAX_HEAD_ROT_POSES + 1; i++ ) + { + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + hBinRend->cldfbSynRotBinDec[i][ch] = NULL; + } + } + + for ( int16_t i = 0; i < MAX_HEAD_ROT_POSES + 1; i++ ) + { + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + if ( ( error = openCldfb( &( hBinRend->cldfbSynRotBinDec[i][ch] ), CLDFB_SYNTHESIS, output_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) + { + return error; + } + } + } +#endif + + 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 ( bandIdx = 0; bandIdx < MAX_SPLIT_REND_MD_BANDS; bandIdx++ ) + { + hBinRend->rot_md[pos_idx][sf_idx][bandIdx].gd = 0.0f; + } + } + } + + set_fix_rotation_mat( hBinRend->fix_pos_rot_mat, pMultiBinPoseData ); + + set_pose_types( hBinRend->pose_type, pMultiBinPoseData ); + + ivas_split_rend_init_huff_cfg( &hBinRend->huff_cfg ); + +#ifdef SPLIT_POSE_CORRECTION_DEBUG + if ( ( error = ivas_splitBinPostRendOpen( &hBinRend->hBinHrSplitPostRend, pMultiBinPoseData, 48000 ) ) != IVAS_ERR_OK ) + { + return error; + } +#endif + + *hBinHrSplitPreRend = hBinRend; + + return IVAS_ERR_OK; +} + + +/*------------------------------------------------------------------------- + * Function ivas_splitBinPreRendClose() + * + * + *------------------------------------------------------------------------*/ + +void ivas_splitBinPreRendClose( + BIN_HR_SPLIT_PRE_REND_HANDLE *hBinHrSplitPreRend ) +{ + if ( ( *hBinHrSplitPreRend ) != NULL ) + { +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + { + int16_t i, n; + for ( i = 0; i < MAX_HEAD_ROT_POSES + 1; i++ ) + { + for ( n = 0; n < BINAURAL_CHANNELS; n++ ) + { + if ( ( *hBinHrSplitPreRend )->cldfbSynRotBinDec[i][n] != NULL ) + { + deleteCldfb( &( ( *hBinHrSplitPreRend )->cldfbSynRotBinDec[i][n] ) ); + ( *hBinHrSplitPreRend )->cldfbSynRotBinDec[i][n] = NULL; + } + } + } + } +#endif +#ifdef SPLIT_POSE_CORRECTION_DEBUG + ivas_splitBinPostRendClose( &( *hBinHrSplitPreRend )->hBinHrSplitPostRend ); +#endif + + free( ( *hBinHrSplitPreRend ) ); + ( *hBinHrSplitPreRend ) = NULL; + } + + return; +} + + +/*-------------------------------------------------------------------------* + * ivas_set_split_rend_ht_setup() + * + * + *-------------------------------------------------------------------------*/ + +void ivas_set_split_rend_ht_setup( + IVAS_DEC_SPLIT_REND_WRAPPER *hSplitBinRend, + COMBINED_ORIENTATION_HANDLE hCombinedOrientationData ) +{ + int16_t sf, i, j; + if ( hCombinedOrientationData != NULL && hSplitBinRend->splitrend.multiBinPoseData.poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) + { + for ( sf = 1; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ ) + { + hCombinedOrientationData->Quaternions[sf] = hCombinedOrientationData->Quaternions[0]; + + for ( i = 0; i < 3; i++ ) + { + for ( j = 0; j < 3; j++ ) + { + hCombinedOrientationData->Rmat[sf][i][j] = hCombinedOrientationData->Rmat[0][i][j]; + } + } + } + } + + return; +} + + +/*-------------------------------------------------------------------------* + * ivas_set_split_rend_setup() + * + * Setup IVAS split rendering + *-------------------------------------------------------------------------*/ + +ivas_error ivas_set_split_rend_setup( + IVAS_DEC_SPLIT_REND_WRAPPER *hSplitBinRend, + IVAS_SPLIT_REND_CONFIG_DATA *hSplitBinConfig, + COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, + uint8_t *splitRendBitsBuf ) +{ + int16_t sf, i, j; + + if ( ( hSplitBinRend->hSplitRendBits = (IVAS_SPLIT_REND_BITS_HANDLE) malloc( sizeof( IVAS_SPLIT_REND_BITS_DATA ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for split renderer Bits buffer\n" ) ); + } + + hSplitBinRend->hSplitRendBits->bits_buf = splitRendBitsBuf; + hSplitBinRend->hSplitRendBits->bits_read = 0; + hSplitBinRend->hSplitRendBits->bits_written = 0; + hSplitBinRend->hSplitRendBits->buf_len = IVAS_MAX_SPLIT_REND_BITS_BUFFER_SIZE_IN_BYTES; + hSplitBinRend->hSplitRendBits->codec = IVAS_SPLIT_REND_CODEC_DEFAULT; + hSplitBinRend->hSplitRendBits->pose_correction = IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE; + hSplitBinRend->hSplitRendBits->codec_frame_size_ms = 0; + + + if ( ( hSplitBinRend->hMultiBinCldfbData = (IVAS_DEC_SPLIT_REND_MULTI_BIN_CLDFB_DATA_HANDLE) malloc( sizeof( IVAS_DEC_SPLIT_REND_MULTI_BIN_CLDFB_DATA ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for split rendering structure" ); + } + + ivas_renderSplitGetMultiBinPoseData( hSplitBinConfig, &hSplitBinRend->splitrend.multiBinPoseData, hCombinedOrientationData->sr_pose_pred_axis ); + + if ( hCombinedOrientationData != NULL && hSplitBinRend->splitrend.multiBinPoseData.poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) + { + for ( sf = 1; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ ) + { + hCombinedOrientationData->Quaternions[sf] = hCombinedOrientationData->Quaternions[0]; + + for ( i = 0; i < 3; i++ ) + { + for ( j = 0; j < 3; j++ ) + { + hCombinedOrientationData->Rmat[sf][i][j] = hCombinedOrientationData->Rmat[0][i][j]; + } + } + } + } + + return IVAS_ERR_OK; +} + + +/*------------------------------------------------------------------------- + * Function ivas_init_split_rend_handles() + * + * + *------------------------------------------------------------------------*/ + +void ivas_init_split_rend_handles( + SPLIT_REND_WRAPPER *hSplitRendWrapper ) +{ + int16_t i; + + hSplitRendWrapper->hBinHrSplitPreRend = NULL; + hSplitRendWrapper->hCldfbHandles = NULL; + hSplitRendWrapper->hSplitBinLCLDEnc = NULL; + hSplitRendWrapper->hLc3plusEnc = NULL; + + for ( i = 0; i < MAX_HEAD_ROT_POSES - 1; ++i ) + { + hSplitRendWrapper->hTdRendHandles[i] = NULL; + } + + for ( i = 0; i < MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS; ++i ) + { + hSplitRendWrapper->lc3plusDelayBuffers[i] = NULL; + } + hSplitRendWrapper->lc3plusDelaySamples = 0; + + ivas_init_multi_bin_pose_data( &hSplitRendWrapper->multiBinPoseData ); + + return; +} + + +/*------------------------------------------------------------------------- + * Function split_renderer_open_lc3plus() + * + * + *------------------------------------------------------------------------*/ + +static ivas_error split_renderer_open_lc3plus( + SPLIT_REND_WRAPPER *hSplitRendWrapper, + const IVAS_SPLIT_REND_CONFIG_DATA *pSplitRendConfig, + const int32_t OutSampleRate, + const int16_t is_5ms_frame ) +{ + ivas_error error; + int16_t i, delayBufferLength; + LC3PLUS_CONFIG config; + + if ( is_5ms_frame ) + { + config.lc3plus_frame_duration_us = pSplitRendConfig->codec_frame_size_ms * 1000; + config.ivas_frame_duration_us = ( pSplitRendConfig->dof == 0 ) ? config.lc3plus_frame_duration_us : 20000; + } + else + { + config.lc3plus_frame_duration_us = 5000; + config.ivas_frame_duration_us = 20000; + } + config.samplerate = OutSampleRate; + + config.channels = BINAURAL_CHANNELS; + + if ( ( error = IVAS_LC3PLUS_ENC_Open( config, ivas_get_lc3plus_bitrate( pSplitRendConfig->splitRendBitRate, pSplitRendConfig->poseCorrectionMode, (int16_t) ( config.ivas_frame_duration_us / 1000 ) ), &hSplitRendWrapper->hLc3plusEnc ) ) != IVAS_ERR_OK ) + { + return error; + } + + /* This returns delay of entire LC3plus chain (enc + dec) */ + if ( ( error = IVAS_LC3PLUS_ENC_GetDelay( hSplitRendWrapper->hLc3plusEnc, &hSplitRendWrapper->lc3plusDelaySamples ) ) != IVAS_ERR_OK ) + { + return error; + } + + /* Alocate buffers for delay compensation */ + if ( pSplitRendConfig->codec == IVAS_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 ) + { + 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 ); + } + } + 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 ) + { + 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 ); + } + } + + return IVAS_ERR_OK; +} + + +/*------------------------------------------------------------------------- + * Function ivas_split_renderer_open() + * + * + *------------------------------------------------------------------------*/ + +ivas_error ivas_split_renderer_open( + SPLIT_REND_WRAPPER *hSplitRendWrapper, + const IVAS_SPLIT_REND_CONFIG_DATA *pSplitRendConfig, + const int32_t OutSampleRate, + const int16_t cldfb_in_flag, + const int16_t pcm_out_flag, + const int16_t is_5ms_frame ) +{ + ivas_error error, ch, num_ch; +#ifndef SPLIT_REND_WITH_HEAD_ROT + CLDFB_TYPE cldfbMode; +#endif + uint8_t isCldfbNeeded = 0; +#ifndef SPLIT_REND_WITH_HEAD_ROT + cldfbMode = CLDFB_ANALYSIS; +#endif + + if ( ( error = ivas_split_rend_validate_config( pSplitRendConfig, pcm_out_flag ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( cldfb_in_flag == 0 ) + { + isCldfbNeeded = 1; +#ifndef SPLIT_REND_WITH_HEAD_ROT + cldfbMode = CLDFB_ANALYSIS; +#endif + } + else if ( pSplitRendConfig->codec == IVAS_SPLIT_REND_CODEC_LC3PLUS && cldfb_in_flag ) + { +#ifdef SPLIT_REND_WITH_HEAD_ROT + isCldfbNeeded = 1; +#else + isCldfbNeeded = 1; + cldfbMode = CLDFB_SYNTHESIS; +#endif + } + else if ( pcm_out_flag && cldfb_in_flag ) + { +#ifdef SPLIT_REND_WITH_HEAD_ROT + isCldfbNeeded = 1; +#else + isCldfbNeeded = 1; + cldfbMode = CLDFB_SYNTHESIS; +#endif + } + + hSplitRendWrapper->hCldfbHandles = NULL; + + if ( isCldfbNeeded ) + { + 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++ ) + { + hSplitRendWrapper->hCldfbHandles->cldfbAna[ch] = NULL; + } + +#ifdef SPLIT_REND_WITH_HEAD_ROT + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + hSplitRendWrapper->hCldfbHandles->cldfbSyn[ch] = NULL; + } +#endif + + num_ch = hSplitRendWrapper->multiBinPoseData.num_poses * BINAURAL_CHANNELS; + + for ( ch = 0; ch < num_ch; ch++ ) + { + if ( ( error = openCldfb( &( hSplitRendWrapper->hCldfbHandles->cldfbAna[ch] ), +#ifndef SPLIT_REND_WITH_HEAD_ROT + cldfbMode, +#else + CLDFB_ANALYSIS, +#endif + OutSampleRate, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) + { + return error; + } + } + +#ifdef SPLIT_REND_WITH_HEAD_ROT + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + if ( ( error = openCldfb( &( hSplitRendWrapper->hCldfbHandles->cldfbSyn[ch] ), CLDFB_SYNTHESIS, OutSampleRate, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) + { + return error; + } + } +#endif + } + + if ( pSplitRendConfig->poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) + { + if ( ( error = ivas_splitBinPreRendOpen( &hSplitRendWrapper->hBinHrSplitPreRend, &hSplitRendWrapper->multiBinPoseData +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + , + OutSampleRate +#endif + ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + if ( pcm_out_flag == 0 ) + { + if ( pSplitRendConfig->codec == IVAS_SPLIT_REND_CODEC_LC3PLUS ) + { + if ( ( error = split_renderer_open_lc3plus( hSplitRendWrapper, pSplitRendConfig, OutSampleRate, is_5ms_frame ) ) != IVAS_ERR_OK ) + { + return error; + } + } + else + { + if ( ( error = ivas_splitBinLCLDEncOpen( &hSplitRendWrapper->hSplitBinLCLDEnc, OutSampleRate, BINAURAL_CHANNELS, ivas_get_lcld_bitrate( pSplitRendConfig->splitRendBitRate, hSplitRendWrapper->multiBinPoseData.poseCorrectionMode ) ) ) != IVAS_ERR_OK ) + { + return error; + } + } + } + + return IVAS_ERR_OK; +} + + +/*------------------------------------------------------------------------- + * Function ivas_split_renderer_close() + * + * + *------------------------------------------------------------------------*/ + +void ivas_split_renderer_close( + SPLIT_REND_WRAPPER *hSplitBinRend ) +{ + int16_t i; + + if ( hSplitBinRend->hBinHrSplitPreRend != NULL ) + { + ivas_splitBinPreRendClose( &hSplitBinRend->hBinHrSplitPreRend ); + } + + if ( hSplitBinRend->hSplitBinLCLDEnc != NULL ) + { + ivas_splitBinLCLDEncClose( &hSplitBinRend->hSplitBinLCLDEnc ); + } + + if ( hSplitBinRend->hCldfbHandles != NULL ) + { + int16_t num_ch, ch; + num_ch = MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS; + for ( ch = 0; ch < num_ch; ch++ ) + { + if ( hSplitBinRend->hCldfbHandles->cldfbAna[ch] != NULL ) + { + deleteCldfb( &hSplitBinRend->hCldfbHandles->cldfbAna[ch] ); + hSplitBinRend->hCldfbHandles->cldfbAna[ch] = NULL; + } + } + +#ifdef SPLIT_REND_WITH_HEAD_ROT + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + 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 ) + { + IVAS_LC3PLUS_ENC_Close( &hSplitBinRend->hLc3plusEnc ); + } + + for ( i = 0; i < MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS; ++i ) + { + if ( hSplitBinRend->lc3plusDelayBuffers[i] != NULL ) + { + free( hSplitBinRend->lc3plusDelayBuffers[i] ); + hSplitBinRend->lc3plusDelayBuffers[i] = NULL; + } + } + + for ( i = 0; i < MAX_HEAD_ROT_POSES - 1; ++i ) + { + if ( hSplitBinRend->hTdRendHandles[i] != NULL ) + { + hSplitBinRend->hTdRendHandles[i]->HrFiltSet_p = NULL; + ivas_td_binaural_close( &hSplitBinRend->hTdRendHandles[i] ); + } + } + + return; +} + + +/*------------------------------------------------------------------------- + * Function splitRendLc3plusEncodeAndWrite() + * + * + *------------------------------------------------------------------------*/ + +static ivas_error splitRendLc3plusEncodeAndWrite( + SPLIT_REND_WRAPPER *hSplitBin, + IVAS_SPLIT_REND_BITS_HANDLE pBits, + const int32_t SplitRendBitRate, + float *in[] ) +{ + ivas_error error; + int16_t i; + int32_t lc3plusBitstreamSize; + float *channel_ptrs[MAX_HEAD_ROT_POSES * 2]; + assert( hSplitBin->hLc3plusEnc != NULL ); + + /* Find next byte boundary and zero-pad to it */ + while ( pBits->bits_written % 8 != 0 ) + { + ivas_split_rend_bitstream_write_int32( pBits, 0L, 1 ); + } + + for ( i = 0; i < BINAURAL_CHANNELS * hSplitBin->multiBinPoseData.num_poses; ++i ) + { + channel_ptrs[i] = in[i]; + } + + if ( ( error = IVAS_LC3PLUS_ENC_GetOutputBitstreamSize( hSplitBin->hLc3plusEnc, &lc3plusBitstreamSize ) ) != IVAS_ERR_OK ) + { + return error; + } + + ivas_split_rend_bitstream_write_int32( pBits, ivas_get_lc3plus_bitrate_id( SplitRendBitRate ), 8 ); + + /* Write bitstream */ + if ( ( error = IVAS_LC3PLUS_ENC_Encode( hSplitBin->hLc3plusEnc, channel_ptrs, &pBits->bits_buf[pBits->bits_written / 8] ) ) != IVAS_ERR_OK ) + { + return error; + } + + pBits->bits_written += 8 * lc3plusBitstreamSize; + pBits->codec = IVAS_SPLIT_REND_CODEC_LC3PLUS; + pBits->pose_correction = hSplitBin->multiBinPoseData.poseCorrectionMode; + pBits->codec_frame_size_ms = (int16_t) ( hSplitBin->hLc3plusEnc->config.lc3plus_frame_duration_us / 1000 ); + return IVAS_ERR_OK; +} + + +/*------------------------------------------------------------------------- + * Function ivas_renderMultiTDBinToSplitBinaural() + * + * + *------------------------------------------------------------------------*/ + +static ivas_error ivas_renderMultiTDBinToSplitBinaural( + SPLIT_REND_WRAPPER *hSplitBin, + const IVAS_QUATERNION headPosition, + const int32_t SplitRendBitRate, + const int16_t codec_frame_size_ms, + IVAS_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 ) +{ + ivas_error error; + int32_t bit_len, available_bits, target_md_bits, actual_md_bits; + 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; + + push_wmops( "ivas_renderMultiTDBinToSplitBinaural" ); + + error = IVAS_ERR_OK; + num_poses = hSplitBin->multiBinPoseData.num_poses; + + useLc3plus = hSplitBin->hLc3plusEnc != NULL; + + 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 ) + { + /* 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 ); + } + } + else + { + for ( i = 0; i < num_poses * BINAURAL_CHANNELS; ++i ) + { + in_delayed[i] = in[i]; + } + } + + actual_md_bits = pBits->bits_written; + if ( ( hSplitBin->multiBinPoseData.poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) || ( !useLc3plus && !pcm_out_flag ) ) + { + if ( !useLc3plus && codec_frame_size_ms != 20 && !pcm_out_flag ) + { + return IVAS_ERROR( IVAS_ERR_INVALID_INPUT_BUFFER_SIZE, "Unsupported framing for LCLD codec!" ); + } + num_cldfb_bands = hSplitBin->hCldfbHandles->cldfbAna[0]->no_channels; + + /* CLDFB Analysis*/ + for ( pos_idx = 0; pos_idx < num_poses; pos_idx++ ) + { +#ifdef SPLIT_POSE_CORRECTION_DEBUG + { + float *pOut[2]; + char fname[200] = "ref_out_pos"; + char tag[2]; + tag[0] = (char) ( '0' + pos_idx ); + tag[1] = '\0'; + strcat( fname, tag ); + strcat( fname, ".wav" ); + + pOut[0] = in_delayed[2 * pos_idx]; + pOut[1] = in_delayed[2 * pos_idx + 1]; + dbgwrite_wav( pOut, CLDFB_NO_COL_MAX * max_bands, fname, 48000, 2 ); + } + +#endif + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + for ( slot_idx = 0; slot_idx < CLDFB_NO_COL_MAX; 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] ); + } + } + } + } + + if ( hSplitBin->multiBinPoseData.poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) + { + target_md_bits = ivas_get_split_rend_md_target_brate( SplitRendBitRate, pcm_out_flag ) * L_FRAME48k / 48000; + + actual_md_bits = pBits->bits_written; + + ivas_rend_CldfbSplitPreRendProcess( hSplitBin->hBinHrSplitPreRend, headPosition, &hSplitBin->multiBinPoseData, Cldfb_In_BinReal, Cldfb_In_BinImag, pBits, target_md_bits, low_res_pre_rend_rot ); + } + + if ( pcm_out_flag == 0 ) + { + pBits->pose_correction = hSplitBin->multiBinPoseData.poseCorrectionMode; + pBits->codec = useLc3plus ? IVAS_SPLIT_REND_CODEC_LC3PLUS : IVAS_SPLIT_REND_CODEC_LCLD; + + if ( !useLc3plus ) + { + available_bits = SplitRendBitRate * L_FRAME48k / 48000; + actual_md_bits = pBits->bits_written - actual_md_bits; + available_bits -= actual_md_bits; + pBits->codec_frame_size_ms = 20; + + ivas_splitBinLCLDEncProcess( hSplitBin->hSplitBinLCLDEnc, Cldfb_In_BinReal, Cldfb_In_BinImag, available_bits, pBits ); + } + else + { + if ( ( error = splitRendLc3plusEncodeAndWrite( hSplitBin, pBits, SplitRendBitRate, in ) ) != IVAS_ERR_OK ) + { + return error; + } + } + } + else + { + pBits->pose_correction = hSplitBin->multiBinPoseData.poseCorrectionMode; + pBits->codec = IVAS_SPLIT_REND_CODEC_NONE; + } + + /*zero pad*/ + if ( pcm_out_flag ) + { + bit_len = SplitRendBitRate / FRAMES_PER_SEC; + } + else + { + if ( !useLc3plus ) + { + bit_len = SplitRendBitRate / FRAMES_PER_SEC; + } + else + { + bit_len = hSplitBin->hLc3plusEnc->config.ivas_frame_duration_us / 1000; + bit_len = SplitRendBitRate * bit_len / 1000; + } + } + + while ( pBits->bits_written < bit_len ) + { + ivas_split_rend_bitstream_write_int32( pBits, 0L, 1 ); + } + + pop_wmops(); + + return error; +} + + +/*------------------------------------------------------------------------- + * Function lc3plusTimeAlignCldfbPoseCorr() + * + * + *------------------------------------------------------------------------*/ + +static 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] ) +{ + 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; + + for ( pose = 0; pose < hSplitBin->multiBinPoseData.num_poses; ++pose ) + { + for ( ch = 0; ch < BINAURAL_CHANNELS; ++ch ) + { + bufRead = hSplitBin->lc3plusDelayBuffers[pose * BINAURAL_CHANNELS + ch]; + bufWrite = bufRead; + + /* Save last 2 columns for next frame */ + 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 ); + } + + /* Delay existing columns by 2 slots */ + /*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 ); + } + + /* Fill 2 first columns from buffer */ + 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; + } + + /* Copy last 2 columns to buffer */ + 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; + } + } + } + + return; +} + + +/*------------------------------------------------------------------------- + * Function ivas_renderMultiBinToSplitBinaural() + * + * + *------------------------------------------------------------------------*/ + +ivas_error ivas_renderMultiBinToSplitBinaural( + SPLIT_REND_WRAPPER *hSplitBin, + const IVAS_QUATERNION headPosition, + const int32_t SplitRendBitRate, + IVAS_SPLIT_REND_CODEC splitCodec, + int16_t codec_frame_size_ms, + IVAS_SPLIT_REND_BITS_HANDLE pBits, + float Cldfb_In_BinReal[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + float Cldfb_In_BinImag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + const int16_t max_bands, + float *output[], + const int16_t low_res_pre_rend_rot, + const int16_t cldfb_in_flag, + const int16_t pcm_out_flag ) +{ + ivas_error error; + int32_t bit_len, target_md_bits, actual_md_bits, available_bits; + + error = IVAS_ERR_OK; + push_wmops( "ivas_renderMultiBinToSplitBinaural" ); + + if ( hSplitBin->multiBinPoseData.poseCorrectionMode == IVAS_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 ); + } + + /* Needs to be done at runtime. If this was in another API function, + * there would be no guarantee that the user did not change + * the split rendering config before calling the main rendering function */ + if ( ( error = ivas_split_rend_choose_default_codec( &splitCodec, &codec_frame_size_ms, cldfb_in_flag, pcm_out_flag ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( 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 = ivas_renderMultiTDBinToSplitBinaural( hSplitBin, headPosition, SplitRendBitRate, codec_frame_size_ms, pBits, max_bands, output, low_res_pre_rend_rot, pcm_out_flag ); + + pop_wmops(); + return error; + } + + if ( splitCodec == IVAS_SPLIT_REND_CODEC_LC3PLUS && hSplitBin->multiBinPoseData.poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) + { + /* Time-align pose correction to delay of LC3plus */ + lc3plusTimeAlignCldfbPoseCorr( hSplitBin, Cldfb_In_BinReal, Cldfb_In_BinImag ); + } + + actual_md_bits = pBits->bits_written; + if ( hSplitBin->multiBinPoseData.poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) + { + target_md_bits = ivas_get_split_rend_md_target_brate( SplitRendBitRate, pcm_out_flag ) * L_FRAME48k / 48000; + + actual_md_bits = pBits->bits_written; + ivas_rend_CldfbSplitPreRendProcess( hSplitBin->hBinHrSplitPreRend, headPosition, &hSplitBin->multiBinPoseData, Cldfb_In_BinReal, Cldfb_In_BinImag, pBits, target_md_bits, low_res_pre_rend_rot ); + } + + if ( pcm_out_flag == 0 ) + { + pBits->codec = splitCodec; + pBits->pose_correction = hSplitBin->multiBinPoseData.poseCorrectionMode; + + if ( splitCodec == IVAS_SPLIT_REND_CODEC_LCLD ) + { + available_bits = SplitRendBitRate * L_FRAME48k / 48000; + actual_md_bits = pBits->bits_written - actual_md_bits; + available_bits -= actual_md_bits; + + ivas_splitBinLCLDEncProcess( hSplitBin->hSplitBinLCLDEnc, Cldfb_In_BinReal, Cldfb_In_BinImag, available_bits, pBits ); + } + else + { + int16_t ch, slot_idx; + + /* CLDFB synthesis of main pose */ + 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]; + + 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]; + } +#ifndef SPLIT_REND_WITH_HEAD_ROT + cldfbSynthesis( Cldfb_In_BinReal_p, Cldfb_In_BinImag_p, output[ch], hSplitBin->hCldfbHandles->cldfbAna[0]->no_channels * CLDFB_NO_COL_MAX, hSplitBin->hCldfbHandles->cldfbAna[ch] ); +#else + 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] ); +#endif + } + + if ( ( error = splitRendLc3plusEncodeAndWrite( hSplitBin, pBits, SplitRendBitRate, output ) ) != IVAS_ERR_OK ) + { + return error; + } + } + } + else + { + int16_t ch, slot_idx; + /* CLDFB synthesis of main pose */ + 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]; + + 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]; + } + +#ifndef SPLIT_REND_WITH_HEAD_ROT + cldfbSynthesis( Cldfb_In_BinReal_p, Cldfb_In_BinImag_p, output[ch], hSplitBin->hCldfbHandles->cldfbAna[0]->no_channels * CLDFB_NO_COL_MAX, hSplitBin->hCldfbHandles->cldfbAna[ch] ); +#else + 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] ); +#endif + } + + pBits->pose_correction = hSplitBin->multiBinPoseData.poseCorrectionMode; + pBits->codec = IVAS_SPLIT_REND_CODEC_NONE; + } + + /*zero pad*/ + /*TODO: do this inside the LCLD ENC codec */ + if ( pcm_out_flag ) + { + bit_len = SplitRendBitRate / FRAMES_PER_SEC; + } + else + { + if ( splitCodec == IVAS_SPLIT_REND_CODEC_LCLD ) + { + bit_len = SplitRendBitRate / FRAMES_PER_SEC; + } + else + { + bit_len = hSplitBin->hLc3plusEnc->config.ivas_frame_duration_us / 1000; + bit_len = SplitRendBitRate * bit_len / 1000; + } + } + + while ( pBits->bits_written < bit_len ) + { + ivas_split_rend_bitstream_write_int32( pBits, 0L, 1 ); + } + + pop_wmops(); + + return error; +} +#endif diff --git a/lib_rend/ivas_splitRenderer_utils.c b/lib_rend/ivas_splitRenderer_utils.c new file mode 100644 index 000000000..daf6eb6f2 --- /dev/null +++ b/lib_rend/ivas_splitRenderer_utils.c @@ -0,0 +1,1089 @@ +/****************************************************************************************************** + + (C) 2022-2023 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. + +*******************************************************************************************************/ + +#include +#include "options.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT +#include +#include "ivas_prot.h" +#include "prot.h" +#include "cnst.h" +#include "ivas_cnst.h" +#include "ivas_rom_rend.h" +#include "ivas_rom_com.h" +#include "ivas_rom_dec.h" +#include "ivas_rom_binauralRenderer.h" +#include "lib_rend.h" +#include "ivas_prot_rend.h" +#ifdef DEBUGGING +#include "debug.h" +#endif +#include "wmc_auto.h" + + +/*------------------------------------------------------------------------- + * Function ivas_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], + float in_im2[2][2], + float out_re2[2][2], + float out_im2[2][2] ) +{ + int16_t i, j; + float tmp_re, tmp_im; + + for ( i = 0; i < 2; i++ ) + { + for ( j = 0; j < 2; j++ ) + { + IVAS_CMULT_FLOAT( in_re1[i][0], in_im1[i][0], in_re2[0][j], in_im2[0][j], tmp_re, tmp_im ); + out_re2[i][j] = tmp_re; + out_im2[i][j] = tmp_im; + + IVAS_CMULT_FLOAT( in_re1[i][1], in_im1[i][1], in_re2[1][j], in_im2[1][j], tmp_re, tmp_im ); + out_re2[i][j] += tmp_re; + out_im2[i][j] += tmp_im; + } + } + + return; +} + + +/*------------------------------------------------------------------------- + * Function ivas_split_rend_bitstream_init() + * + * + *------------------------------------------------------------------------*/ + +void ivas_split_rend_bitstream_init( + IVAS_SPLIT_REND_BITS_HANDLE pBits, + const int32_t buf_len_bytes, + uint8_t *pbuf ) +{ + pBits->bits_buf = pbuf; + pBits->buf_len = buf_len_bytes; + pBits->bits_read = 0; + pBits->bits_written = 0; + + return; +} + + +/*------------------------------------------------------------------------- + * Function ivas_split_rend_huffman_dec_init_min_max_len() + * + * + *------------------------------------------------------------------------*/ + +void ivas_split_rend_huffman_dec_init_min_max_len( + ivas_split_rend_huffman_cfg_t *p_huff_cfg ) +{ + int16_t i, code_len; + const int32_t *codebook; + + codebook = p_huff_cfg->codebook; + + p_huff_cfg->min_len = p_huff_cfg->sym_len; + p_huff_cfg->max_len = 0; + + for ( i = 0; i < p_huff_cfg->sym_len; i++ ) + { + code_len = (int16_t) codebook[1]; + if ( p_huff_cfg->min_len > code_len ) + { + p_huff_cfg->min_len = code_len; + } + if ( p_huff_cfg->max_len < code_len ) + { + p_huff_cfg->max_len = code_len; + } + codebook = codebook + 3; + } + + return; +} + + +/*------------------------------------------------------------------------- + * Function is_idx_present() + * + * + *------------------------------------------------------------------------*/ + +static int16_t is_idx_present( + int16_t *idx_list, + const int16_t idx, + const int16_t len ) +{ + int16_t i; + + for ( i = 0; i < len; i++ ) + { + if ( idx_list[i] == idx ) + { + return 1; + } + } + + return 0; +} + + +/*------------------------------------------------------------------------- + * Function ivas_split_huff_get_idx_trav_list() + * + * + *------------------------------------------------------------------------*/ + +static void ivas_split_huff_get_idx_trav_list( + int16_t *idx_list, + ivas_split_rend_huffman_cfg_t *p_huff_cfg ) +{ + int16_t i, j, min_idx; + int32_t min_bits; + const int32_t *codebook; + + for ( i = 0; i < p_huff_cfg->sym_len; i++ ) + { + idx_list[i] = -1; + } + + for ( i = 0; i < p_huff_cfg->sym_len; i++ ) + { + codebook = p_huff_cfg->codebook; + min_bits = p_huff_cfg->max_len; + min_idx = -1; + for ( j = 0; j < p_huff_cfg->sym_len; j++ ) + { + if ( ( min_bits >= codebook[1] ) && ( is_idx_present( idx_list, j, i + 1 ) == 0 ) ) + { + min_bits = codebook[1]; + min_idx = j; + } + codebook += 3; + } + idx_list[i] = min_idx; + } + + return; +} + + +/*------------------------------------------------------------------------- + * Function ivas_split_rend_init_huff_cfg() + * + * + *------------------------------------------------------------------------*/ + +void ivas_split_rend_init_huff_cfg( + BIN_HR_SPLIT_REND_HUFF_HANDLE pHuff_cfg ) +{ + pHuff_cfg->pred[0].codebook = &ivas_split_rend_huff_pred31_consts[0][0]; + pHuff_cfg->pred[0].sym_len = IVAS_SPLIT_REND_PRED_31QUANT_PNTS; + ivas_split_rend_huffman_dec_init_min_max_len( &pHuff_cfg->pred[0] ); + ivas_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 ) ); + + pHuff_cfg->pred[1].codebook = &ivas_split_rend_huff_pred63_consts[0][0]; + pHuff_cfg->pred[1].sym_len = IVAS_SPLIT_REND_PRED_63QUANT_PNTS; + ivas_split_rend_huffman_dec_init_min_max_len( &pHuff_cfg->pred[1] ); + ivas_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 ) ); + + + pHuff_cfg->pred_roll.codebook = &ivas_split_rend_huff_roll_pred_consts[0][0]; + pHuff_cfg->pred_roll.sym_len = IVAS_SPLIT_REND_ROLL_PRED_QUANT_PNTS; + ivas_split_rend_huffman_dec_init_min_max_len( &pHuff_cfg->pred_roll ); + ivas_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 ) ); + + pHuff_cfg->gd.codebook = &ivas_split_rend_huff_d_consts[0][0]; + pHuff_cfg->gd.sym_len = IVAS_SPLIT_REND_D_QUANT_PNTS; + ivas_split_rend_huffman_dec_init_min_max_len( &pHuff_cfg->gd ); + ivas_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 ) ); + + pHuff_cfg->p_gd.codebook = &ivas_split_rend_huff_p_d_consts[0][0]; + pHuff_cfg->p_gd.sym_len = IVAS_SPLIT_REND_D_QUANT_PNTS; + ivas_split_rend_huffman_dec_init_min_max_len( &pHuff_cfg->p_gd ); + ivas_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 ) ); + + pHuff_cfg->p_gd_diff.codebook = &ivas_split_rend_huff_p_d_diff_consts[0][0]; + pHuff_cfg->p_gd_diff.sym_len = IVAS_SPLIT_REND_D_QUANT_PNTS; + ivas_split_rend_huffman_dec_init_min_max_len( &pHuff_cfg->p_gd_diff ); + 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 = (int16_t) ceilf( log2f( pHuff_cfg->p_gd_diff.sym_len ) ); + + return; +} + + +/*------------------------------------------------------------------------- + * Function set_fix_rotation_mat() + * + * + *------------------------------------------------------------------------*/ + +void set_fix_rotation_mat( + float fix_pos_rot_mat[][BINAURAL_CHANNELS][BINAURAL_CHANNELS], + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData ) +{ + float yaw_a, cos_yaw, sin_yaw; + int16_t pos_idx; + yaw_a = 0.0f; + + for ( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses - 1; pos_idx++ ) + { + yaw_a = pMultiBinPoseData->relative_head_poses[pos_idx + 1][0]; + cos_yaw = cosf( EVS_PI * yaw_a / 180.0f ); + sin_yaw = sinf( EVS_PI * yaw_a / 180.0f ); + sin_yaw = 0.0f; + fix_pos_rot_mat[pos_idx][0][0] = cos_yaw; + fix_pos_rot_mat[pos_idx][1][1] = cos_yaw; + fix_pos_rot_mat[pos_idx][0][1] = sin_yaw; + fix_pos_rot_mat[pos_idx][1][0] = -1.0f * sin_yaw; + } + + return; +} + + +/*------------------------------------------------------------------------- + * Function set_pose_types() + * + * + *------------------------------------------------------------------------*/ + +void set_pose_types( + IVAS_SPLIT_REND_POSE_TYPE pose_type[MAX_HEAD_ROT_POSES - 1], + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData ) +{ + int16_t pos_idx; + + for ( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses - 1; pos_idx++ ) + { + if ( fabs( pMultiBinPoseData->relative_head_poses[pos_idx + 1][0] ) > EPSILON ) + { + pose_type[pos_idx] = ANY_YAW; + } + else if ( fabs( pMultiBinPoseData->relative_head_poses[pos_idx + 1][2] ) > EPSILON ) + { + pose_type[pos_idx] = ANY_ROLL; + } + else + { + pose_type[pos_idx] = PITCH_ONLY; + } + } + + return; +} + + +/*------------------------------------------------------------------------- + * Function wrap_a() + * + * + *------------------------------------------------------------------------*/ + +int16_t wrap_a( + int16_t val, + const int16_t min_val, + const int16_t max_val ) +{ + if ( val < min_val ) + { + val = max_val - min_val + val + 1; + } + + if ( val > max_val ) + { + val = min_val + val - max_val - 1; + } + + return val; +} + + +/*------------------------------------------------------------------------- + * Function ivas_SplitRenderer_getdiagdiff() + * + * + *------------------------------------------------------------------------*/ + +void ivas_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 ) +{ + out_idx[0][0] = in_idx[0][0]; + out_idx[0][1] = in_idx[0][1]; + out_idx[1][1] = in_idx[1][1] + sign * out_idx[0][0]; + 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]; + out_idx[1][0] = wrap_a( out_idx[1][0], min_val, max_val ); + + return; +} + + +/*------------------------------------------------------------------------- + * Function ivas_split_rend_bitstream_read_int32() + * + * + *------------------------------------------------------------------------*/ + +int32_t ivas_split_rend_bitstream_read_int32( + IVAS_SPLIT_REND_BITS_HANDLE pBits, + const int32_t bits ) +{ + int32_t val, k, bit_val; + +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + assert( ( pBits->bits_written - pBits->bits_read ) >= bits ); + assert( bits <= 32 ); +#endif + + /* write bit by bit */ + val = 0; + for ( k = 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++; + } + + return val; +} + + +/*------------------------------------------------------------------------- + * Function ivas_split_rend_bitstream_write_int32() + * + * + *------------------------------------------------------------------------*/ + +void ivas_split_rend_bitstream_write_int32( + IVAS_SPLIT_REND_BITS_HANDLE pBits, + const int32_t val, + const int32_t bits ) +{ + int32_t mask, k; + +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + /*protection check*/ + if ( ( pBits->buf_len << 3 ) < ( pBits->bits_written + bits ) ) + { + assert( 0 ); + } +#endif + + mask = 1 << ( bits - 1 ); + /* write bit by bit */ + for ( k = 0; k < bits; k++ ) + { + if ( val & mask ) + { + pBits->bits_buf[pBits->bits_written >> 3] |= ( 1 << ( pBits->bits_written & 7 ) ); + } + else + { + pBits->bits_buf[pBits->bits_written >> 3] &= ~( 1 << ( pBits->bits_written & 7 ) ); + } + pBits->bits_written++; + mask >>= 1; + } + + return; +} + + +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG +/*------------------------------------------------------------------------- + * ivas_mat_mult_2by2_complex() + * + * + *------------------------------------------------------------------------*/ + +void ivas_log_cldfb2wav_data( + float Cldfb_In_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + float Cldfb_In_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + HANDLE_CLDFB_FILTER_BANK *cldfbSyn, + const int16_t num_chs, + const int16_t num_freq_bands, + const int32_t output_Fs, + const int16_t num_slots, + const int16_t start_slot_idx, + const char *filename ) +{ + float *RealBuffer[CLDFB_NO_COL_MAX]; + float *ImagBuffer[CLDFB_NO_COL_MAX]; + float pcm_out[BINAURAL_CHANNELS][L_FRAME48k]; + float *pPcm[BINAURAL_CHANNELS]; + float Cldfb_local_Real[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + float Cldfb_local_Imag[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + int16_t sf, ch; + + assert( num_chs <= BINAURAL_CHANNELS ); + for ( ch = 0; ch < num_chs; ch++ ) + { + for ( sf = start_slot_idx; sf < start_slot_idx + num_slots; sf++ ) + { + mvr2r( Cldfb_In_Real[ch][sf], Cldfb_local_Real[ch][sf], num_freq_bands ); + mvr2r( Cldfb_In_Imag[ch][sf], Cldfb_local_Imag[ch][sf], num_freq_bands ); + RealBuffer[sf - start_slot_idx] = Cldfb_local_Real[ch][sf]; + ImagBuffer[sf - start_slot_idx] = Cldfb_local_Imag[ch][sf]; + } + cldfbSynthesis( RealBuffer, ImagBuffer, &( pcm_out[ch][0] ), num_freq_bands * num_slots, cldfbSyn[ch] ); + pPcm[ch] = pcm_out[ch]; + } + dbgwrite_wav( pPcm, num_freq_bands * num_slots, filename, output_Fs, num_chs ); + + return; +} +#endif + + +/*------------------------------------------------------------------------- + * Function ivas_get_split_rend_md_target_brate() + * + * + *------------------------------------------------------------------------*/ + +int32_t ivas_get_split_rend_md_target_brate( + const int32_t SplitRendBitRate, + const int16_t pcm_out_flag ) +{ + int32_t md_bitrate; + + if ( pcm_out_flag == 1 ) + { + md_bitrate = SplitRendBitRate; + } + else + { + switch ( SplitRendBitRate ) + { + case SPLIT_REND_768k: + { + md_bitrate = 256000; + break; + } + case SPLIT_REND_512k: + { + md_bitrate = 128000; + break; + } + case SPLIT_REND_384k: + { + md_bitrate = 128000; + break; + } + default: + { + return -1; + } + } + } + + return md_bitrate; +} + + +/*------------------------------------------------------------------------- + * Function ivas_get_lcld_bitrate() + * + * + *------------------------------------------------------------------------*/ + +int32_t ivas_get_lcld_bitrate( + const int32_t SplitRendBitRate, + const IVAS_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode ) +{ + if ( poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) + { + switch ( SplitRendBitRate ) + { + case SPLIT_REND_768k: + { + return IVAS_512k; + } + case SPLIT_REND_512k: + { + return IVAS_384k; + } + case SPLIT_REND_384k: + { + return IVAS_256k; + } + default: + { + assert( 0 ); + } + } + } + else + { + return SplitRendBitRate; + } + + return -1; +} + + +/*------------------------------------------------------------------------- + * Function ivas_get_lc3plus_bitrate() + * + * + *------------------------------------------------------------------------*/ + +int32_t ivas_get_lc3plus_bitrate( + const int32_t SplitRendBitRate, + IVAS_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode, + const int16_t split_prerender_frame_size_ms ) +{ + if ( poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) + { + int32_t inBandMdBps = (int32_t) ( 8 * 1000 / split_prerender_frame_size_ms ); + return ivas_get_lcld_bitrate( SplitRendBitRate, poseCorrectionMode ) - inBandMdBps; + } + + if ( poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) + { + return SplitRendBitRate; + } + + /* Should not be reached */ + assert( 0 ); + return -1; +} + + +/*------------------------------------------------------------------------- + * Function ivas_get_lc3plus_bitrate_id() + * + * + *------------------------------------------------------------------------*/ + +int8_t ivas_get_lc3plus_bitrate_id( + const int32_t SplitRendBitRate ) +{ + switch ( SplitRendBitRate ) + { + case SPLIT_REND_768k: + { + return 4; + } + case SPLIT_REND_512k: + { + return 3; + } + case SPLIT_REND_384k: + { + return 2; + } + case SPLIT_REND_320k: + { + return 1; + } + case SPLIT_REND_256k: + { + return 0; + } + default: + { + break; + } + } + + return -1; +} + + +/*------------------------------------------------------------------------- + * Function ivas_mat_mult_2by2_complex() + * + * + *------------------------------------------------------------------------*/ + +int32_t ivas_get_lc3plus_size_from_id( + const int8_t SplitRendBitRateId, + const IVAS_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode, + const int16_t split_prerender_frame_size_ms ) +{ + int32_t bitrate; + + switch ( SplitRendBitRateId ) + { + case 4: + { + bitrate = SPLIT_REND_768k; + break; + } + case 3: + { + bitrate = SPLIT_REND_512k; + break; + } + case 2: + { + bitrate = SPLIT_REND_384k; + break; + } + case 1: + { + bitrate = SPLIT_REND_320k; + break; + } + case 0: + { + bitrate = SPLIT_REND_256k; + break; + } + default: + { + bitrate = -1; + break; + } + } + + bitrate = ivas_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 ); +} + + +/*------------------------------------------------------------------------- + * Function ivas_split_rend_validate_config() + * + * + *------------------------------------------------------------------------*/ + +ivas_error ivas_split_rend_validate_config( + const IVAS_SPLIT_REND_CONFIG_DATA *pSplitRendConfig, + const int16_t is_pcm_out ) +{ + /* Valid DOF range is 0-3 */ + if ( pSplitRendConfig->dof < 0 || 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 != IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB && 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 == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE && pSplitRendConfig->dof != 0 ) || + ( pSplitRendConfig->poseCorrectionMode != IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE && 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 ( pSplitRendConfig->codec == IVAS_SPLIT_REND_CODEC_LCLD && pSplitRendConfig->codec_frame_size_ms != 20 ) + { + return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "Invalid framing for LCLD codec" ); + } + + if ( pSplitRendConfig->codec == IVAS_SPLIT_REND_CODEC_LC3PLUS && ( pSplitRendConfig->codec_frame_size_ms != 5 && 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 ) + { + switch ( pSplitRendConfig->splitRendBitRate ) + { + case SPLIT_REND_256k: + if ( 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; + case SPLIT_REND_320k: + /* Only valid with 0 DOF */ + if ( 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; + case SPLIT_REND_384k: + case SPLIT_REND_512k: + /* Always valid */ + break; + case SPLIT_REND_768k: + if ( pSplitRendConfig->dof == 0 && pSplitRendConfig->codec == IVAS_SPLIT_REND_CODEC_LC3PLUS ) + { + return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "Bitrate is too high for LC3plus with 0 DOF" ); + } + break; + default: + return IVAS_ERR_LC3PLUS_INVALID_BITRATE; + } + } + else + { + if ( pSplitRendConfig->dof == 1 ) + { + if ( pSplitRendConfig->splitRendBitRate < 50000 ) + { + return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "1DOF metadata needs atleast 50 kbps" ); + } + } + else if ( pSplitRendConfig->dof == 2 ) + { + if ( pSplitRendConfig->splitRendBitRate < 66000 ) + { + return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "2DOF metadata needs atleast 66 kbps" ); + } + } + else if ( pSplitRendConfig->dof == 3 ) + { + if ( pSplitRendConfig->splitRendBitRate < 128000 ) + { + return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "3DOF metadata needs atleast 128 kbps" ); + } + } + } + + return IVAS_ERR_OK; +} + + +/*------------------------------------------------------------------------- + * Function ivas_split_rend_get_quant_params() + * + * + *------------------------------------------------------------------------*/ + +void ivas_split_rend_get_quant_params( + const int16_t num_md_bands, + int16_t pred_real_bands_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], + int16_t pred_imag_bands_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], + int16_t pred_quant_pnts_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], + float pred_quantstep_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], + float pred_1byquantstep_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], + int16_t d_bands_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], + int16_t bands_pitch[IVAS_SPLIT_REND_NUM_QUANT_STRATS], + int16_t pred_real_bands_roll[IVAS_SPLIT_REND_NUM_QUANT_STRATS], + int16_t pred_imag_bands_roll[IVAS_SPLIT_REND_NUM_QUANT_STRATS], + int16_t *num_quant_strats, + int16_t *num_complex_bands ) +{ + int16_t q; + + *num_quant_strats = IVAS_SPLIT_REND_NUM_QUANT_STRATS; + *num_complex_bands = COMPLEX_MD_BAND_THRESH_LOW; + assert( *num_complex_bands <= num_md_bands ); + + pred_quant_pnts_yaw[0] = IVAS_SPLIT_REND_PRED_63QUANT_PNTS; + pred_quantstep_yaw[0] = IVAS_SPLIT_REND_PRED63_Q_STEP; + pred_1byquantstep_yaw[0] = IVAS_SPLIT_REND_PRED63_1BYQ_STEP; + for ( q = 1; q < *num_quant_strats; q++ ) + { + pred_quant_pnts_yaw[q] = IVAS_SPLIT_REND_PRED_31QUANT_PNTS; + pred_quantstep_yaw[q] = IVAS_SPLIT_REND_PRED31_Q_STEP; + pred_1byquantstep_yaw[q] = IVAS_SPLIT_REND_PRED31_1BYQ_STEP; + } + + for ( q = 0; q < *num_quant_strats; q++ ) + { + pred_real_bands_yaw[q] = num_md_bands; + pred_real_bands_roll[q] = num_md_bands; + } + pred_imag_bands_yaw[0] = num_md_bands; + pred_imag_bands_roll[0] = num_md_bands; + pred_imag_bands_yaw[1] = num_md_bands; + pred_imag_bands_roll[1] = num_md_bands; + + 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_roll[q] = *num_complex_bands; + } + + for ( q = 0; q < *num_quant_strats; q++ ) + { + d_bands_yaw[q] = 0; + bands_pitch[q] = num_md_bands; + } + + return; +} + + +/*------------------------------------------------------------------------- + * Function ivas_renderSplitGetMultiBinPoseData() + * + * + *------------------------------------------------------------------------*/ + +void ivas_renderSplitGetMultiBinPoseData( + const IVAS_SPLIT_REND_CONFIG_DATA *pSplit_rend_config, + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + const IVAS_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; + + 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; + } + + /* 0 DOF defaults */ + num_yaw_poses = 0; + num_pitch_poses = 0; + num_roll_poses = 0; + + /* defaults for all DOF except 3DOF HQ */ + relative_yaw_angles = ivas_split_rend_relative_yaw_pos_angles_hq; + relative_pitch_angles = ivas_split_rend_relative_pitch_pos_angles_hq; + relative_roll_angles = ivas_split_rend_relative_roll_pos_angles_hq; + + if ( pSplit_rend_config->dof == 1 ) + { + switch ( rot_axis ) + { + case DEFAULT_AXIS: + case YAW: + { + num_yaw_poses = SPLIT_REND_MAX_YAW_ONLY_POSES; + break; + } + case PITCH: + { + num_pitch_poses = SPLIT_REND_MAX_PITCH_ONLY_POSES; + break; + } + case ROLL: + { + num_roll_poses = SPLIT_REND_MAX_ROLL_ONLY_POSES; + break; + } + default: + { + assert( 0 && "unsupported rotation axis value" ); + } + } + } + else if ( pSplit_rend_config->dof == 2 ) + { + switch ( rot_axis ) + { + case DEFAULT_AXIS: + case YAW: + case PITCH: + case YAW_PITCH: + { + num_yaw_poses = SPLIT_REND_MAX_YAW_ONLY_POSES; + num_pitch_poses = SPLIT_REND_MAX_PITCH_ONLY_POSES; + break; + } + case ROLL: + case YAW_ROLL: + { + num_yaw_poses = SPLIT_REND_MAX_YAW_ONLY_POSES; + num_roll_poses = SPLIT_REND_MAX_ROLL_ONLY_POSES; + break; + } + case PITCH_ROLL: + { + num_pitch_poses = SPLIT_REND_MAX_PITCH_ONLY_POSES; + num_roll_poses = SPLIT_REND_MAX_ROLL_ONLY_POSES; + break; + } + default: + { + assert( 0 && "unsupported rotation axis value" ); + } + } + } + else if ( pSplit_rend_config->dof == 3 ) + { + if ( pSplit_rend_config->hq_mode == 1 ) + { + relative_yaw_angles = ivas_split_rend_relative_yaw_pos_angles_hq; + relative_pitch_angles = ivas_split_rend_relative_pitch_pos_angles_hq; + relative_roll_angles = ivas_split_rend_relative_roll_pos_angles_hq; + num_yaw_poses = SPLIT_REND_MAX_YAW_ONLY_POSES; + num_pitch_poses = SPLIT_REND_MAX_PITCH_ONLY_POSES; + num_roll_poses = SPLIT_REND_MAX_ROLL_ONLY_POSES; + } + else + { + relative_yaw_angles = ivas_split_rend_relative_yaw_pos_angles; + relative_pitch_angles = ivas_split_rend_relative_pitch_pos_angles; + relative_roll_angles = ivas_split_rend_relative_roll_pos_angles; + num_yaw_poses = SPLIT_REND_MAX_YAW_ONLY_POSES; + num_pitch_poses = 1; + num_roll_poses = 1; + } + } + + pMultiBinPoseData->num_poses = num_yaw_poses + num_pitch_poses + num_roll_poses + 1; + assert( pMultiBinPoseData->num_poses <= MAX_HEAD_ROT_POSES ); + + for ( pos_idx = 0; pos_idx < num_yaw_poses; pos_idx++ ) + { + pMultiBinPoseData->relative_head_poses[pos_idx + 1][0] = relative_yaw_angles[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]; + } + + 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->dof = pSplit_rend_config->dof; + pMultiBinPoseData->hq_mode = pSplit_rend_config->hq_mode; + pMultiBinPoseData->rot_axis = rot_axis; + pMultiBinPoseData->poseCorrectionMode = pSplit_rend_config->poseCorrectionMode; + + return; +} + + +/*------------------------------------------------------------------------- + * Function ivas_renderSplitUpdateNoCorrectionPoseData() + * + * + *------------------------------------------------------------------------*/ + +void ivas_renderSplitUpdateNoCorrectionPoseData( + const IVAS_SPLIT_REND_CONFIG_DATA *pSplit_rend_config, + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData ) +{ + pMultiBinPoseData->num_poses = 1; + assert( pSplit_rend_config->dof == 0 ); + pMultiBinPoseData->dof = pSplit_rend_config->dof; + assert( pSplit_rend_config->poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE ); + pMultiBinPoseData->poseCorrectionMode = pSplit_rend_config->poseCorrectionMode; + + return; +} + + +/*------------------------------------------------------------------------- + * Function ivas_init_multi_bin_pose_data() + * + * + *------------------------------------------------------------------------*/ + +void ivas_init_multi_bin_pose_data( + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData ) +{ + int16_t 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->num_poses = 1; + pMultiBinPoseData->dof = 3; + pMultiBinPoseData->hq_mode = 0; + pMultiBinPoseData->rot_axis = DEFAULT_AXIS; + + return; +} + + +/*------------------------------------------------------------------------- + * Function ivas_split_rend_choose_default_codec() + * + * + *------------------------------------------------------------------------*/ + +ivas_error ivas_split_rend_choose_default_codec( + IVAS_SPLIT_REND_CODEC *pCodec, /* i/o: pointer to codec setting */ + 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 */ +) +{ + if ( pcm_out_flag == 0 ) + { + if ( *pCodec == IVAS_SPLIT_REND_CODEC_DEFAULT ) + { + *pCodec = cldfb_in_flag ? IVAS_SPLIT_REND_CODEC_LCLD : IVAS_SPLIT_REND_CODEC_LC3PLUS; + } + } + else + { + *pCodec = IVAS_SPLIT_REND_CODEC_NONE; + } + + if ( *pCodec_frame_size_ms == 0 ) /* codec frame size hasn't been set yet - use default for current configuration */ + { + switch ( *pCodec ) + { + case IVAS_SPLIT_REND_CODEC_LCLD: + *pCodec_frame_size_ms = 20; + break; + case IVAS_SPLIT_REND_CODEC_LC3PLUS: + case IVAS_SPLIT_REND_CODEC_NONE: + *pCodec_frame_size_ms = 5; + break; + default: + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Unknown split codec value" ); + } + } + + return IVAS_ERR_OK; +} +#endif diff --git a/lib_rend/ivas_stat_rend.h b/lib_rend/ivas_stat_rend.h index 12175766d..21c8c3a9c 100644 --- a/lib_rend/ivas_stat_rend.h +++ b/lib_rend/ivas_stat_rend.h @@ -39,6 +39,12 @@ #include "ivas_stat_com.h" // note: needed for DIRAC_DEC_BIN_HANDLE until #156 is solved #include "stat_com.h" /* Note: Currently needed for CLDFB. */ #include "common_api_types.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT +#include "stat_com.h" +#include "ivas_lcld_prot.h" +#include "ivas_lc3plus_enc.h" +#include "ivas_lc3plus_dec.h" +#endif /*----------------------------------------------------------------------------------* @@ -544,8 +550,13 @@ typedef struct ivas_binaural_rendering_conv_module_struct float ***filterTapsRightReal; float ***filterTapsRightImag; +#ifdef SPLIT_REND_WITH_HEAD_ROT + float ****filterStatesLeftReal; + float ****filterStatesLeftImag; +#else float ***filterStatesLeftReal; float ***filterStatesLeftImag; +#endif int16_t numTapsArray[BINAURAL_CONVBANDS]; int16_t numTaps; @@ -643,6 +654,9 @@ typedef struct IVAS_QUATERNION headPositions[MAX_PARAM_SPATIAL_SUBFRAMES]; IVAS_VECTOR3 Pos[MAX_PARAM_SPATIAL_SUBFRAMES]; float crossfade[L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES]; +#ifdef SPLIT_REND_WITH_HEAD_ROT + IVAS_SPLIT_REND_ROT_AXIS sr_pose_pred_axis; +#endif ivas_orient_trk_state_t *hOrientationTracker; } IVAS_REND_HeadRotData; @@ -664,6 +678,9 @@ typedef struct ivas_binaural_head_track_struct int16_t shd_rot_max_order; ivas_orient_trk_state_t *OrientationTracker; +#ifdef SPLIT_REND_WITH_HEAD_ROT + IVAS_SPLIT_REND_ROT_AXIS sr_pose_pred_axis; +#endif } HEAD_TRACK_DATA, *HEAD_TRACK_DATA_HANDLE; @@ -701,21 +718,33 @@ 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]; +#ifdef SPLIT_REND_WITH_HEAD_ROT + float Rmat_prev[MAX_HEAD_ROT_POSES][3][3]; +#else float Rmat_prev[3][3]; +#endif float chEneIIR[2][MASA_FREQUENCY_BANDS]; /* independent of the format. MASA bands are suitable for the task and readily available in ROM. */ float procChEneIIR[2][MASA_FREQUENCY_BANDS]; int16_t shd_rot_max_order; IVAS_VECTOR3 listenerPos[MAX_PARAM_SPATIAL_SUBFRAMES]; +#ifdef SPLIT_REND_WITH_HEAD_ROT + IVAS_SPLIT_REND_ROT_AXIS sr_pose_pred_axis; +#ifdef NONBE_UNIFIED_DECODING_PATHS + int16_t sr_low_res_flag; +#endif +#endif IVAS_QUATERNION Quaternion_frozen_ext; IVAS_QUATERNION Quaternion_frozen_head; int8_t isExtOrientationFrozen; int8_t isHeadRotationFrozen; int16_t num_subframes; +#ifdef NONBE_UNIFIED_DECODING_PATHS int16_t subframe_idx; int16_t subframe_size; int16_t cur_subframe_samples_rendered; int16_t subframe_idx_start; int16_t cur_subframe_samples_rendered_start; +#endif } COMBINED_ORIENTATION_DATA, *COMBINED_ORIENTATION_HANDLE; @@ -1196,12 +1225,43 @@ typedef struct ivas_crend_state_t typedef struct ivas_binaural_crend_wrapper_struct { int32_t binaural_latency_ns; +#ifdef SPLIT_REND_WITH_HEAD_ROT + CREND_HANDLE hCrend[MAX_HEAD_ROT_POSES]; +#else CREND_HANDLE hCrend; +#endif HRTFS_HANDLE hHrtfCrend; } CREND_WRAPPER, *CREND_WRAPPER_HANDLE; +#ifdef SPLIT_REND_WITH_HEAD_ROT +/* Fastconv binaural data structure */ +typedef struct ivas_binaural_rendering_struct +{ + /* Common variables for all modules */ + IVAS_OUTPUT_SETUP_HANDLE hInputSetup; /* pointer to input spatial format for binaural renderer*/ + EFAP_HANDLE hEFAPdata; /* EFAP structure*/ + float *hoa_dec_mtx; /* pointer to HOA decoder mtx */ + int8_t rotInCldfb; /* Flag to enable rotation within bin Renderer in CLDFB*/ + int16_t max_band; /* band upto which rendering is performed */ + int16_t conv_band; /* band upto which convolution in cldfb domain is performed */ + int16_t timeSlots; /* number of time slots of binaural renderer */ + int16_t nInChannels; /* number input channels */ + int8_t render_lfe; /* Flag to render LFE in binaural rendering*/ + IVAS_FORMAT ivas_format; /* format; corresponds to st_ivas->ivas_format, unless the signal gets transormed to a different domain for rendering */ + + /* Convolution module structure */ + BINRENDERER_CONV_MODULE_HANDLE hBinRenConvModule; + + /* Variables related to reverberator module */ + float earlyPartEneCorrection[CLDFB_NO_CHANNELS_MAX]; + REVERB_STRUCT_HANDLE hReverb; + + int16_t numPoses; + +} BINAURAL_RENDERER, *BINAURAL_RENDERER_HANDLE; +#endif /*------------------------------------------------------------------------------------------* * HRTF structures - hrtfs from binary files @@ -1269,6 +1329,189 @@ typedef struct ivas_hrtfs_parambin_struct } HRTFS_PARAMBIN, *HRTFS_PARAMBIN_HANDLE; +#ifdef SPLIT_REND_WITH_HEAD_ROT +/*----------------------------------------------------------------------------------* + * Binaural split rendering structures + *----------------------------------------------------------------------------------*/ + +/* binaural split rendering head rotation data structure */ +typedef struct ivas_binaural_head_rot_split_rendering_md_struct +{ + float pred_mat_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + float pred_mat_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + float gd; + float 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; + +} BIN_HR_SPLIT_REND_MD, *BIN_HR_SPLIT_REND_MD_HANDLE; + +typedef struct ivas_split_rend_huffman_cfg_t +{ + const int32_t *codebook; + int16_t min_len; + int16_t max_len; + int16_t sym_len; + +} ivas_split_rend_huffman_cfg_t; + +typedef struct ivas_binaural_head_rot_split_rendering_huff_struct +{ + ivas_split_rend_huffman_cfg_t pred[2]; + int16_t pred_idx_trav[2][IVAS_SPLIT_REND_PRED_63QUANT_PNTS]; + int16_t pred_base2_code_len[2]; + ivas_split_rend_huffman_cfg_t pred_roll; + int16_t pred_roll_idx_trav[IVAS_SPLIT_REND_ROLL_PRED_QUANT_PNTS]; + int16_t pred_roll_base2_code_len; + ivas_split_rend_huffman_cfg_t gd; + int16_t gd_base2_code_len; + int16_t gd_idx_trav[IVAS_SPLIT_REND_D_QUANT_PNTS]; + ivas_split_rend_huffman_cfg_t p_gd; + int16_t p_gd_base2_code_len; + int16_t p_gd_idx_trav[IVAS_SPLIT_REND_D_QUANT_PNTS]; + ivas_split_rend_huffman_cfg_t p_gd_diff; + int16_t p_gd_diff_base2_code_len; + int16_t p_gd_diff_idx_trav[IVAS_SPLIT_REND_D_QUANT_PNTS]; + +} BIN_HR_SPLIT_REND_HUFF, *BIN_HR_SPLIT_REND_HUFF_HANDLE; + +typedef struct ivas_binaural_head_rot_split_pre_rendering_struct +{ + BIN_HR_SPLIT_REND_MD rot_md[MAX_HEAD_ROT_POSES - 1][MAX_SPLIT_MD_SUBFRAMES][MAX_SPLIT_REND_MD_BANDS]; + float fix_pos_rot_mat[MAX_HEAD_ROT_POSES - 1][BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + IVAS_SPLIT_REND_POSE_TYPE pose_type[MAX_HEAD_ROT_POSES - 1]; + BIN_HR_SPLIT_REND_HUFF huff_cfg; +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + HANDLE_CLDFB_FILTER_BANK cldfbSynRotBinDec[MAX_HEAD_ROT_POSES + 1][BINAURAL_CHANNELS]; +#endif + +#ifdef SPLIT_POSE_CORRECTION_DEBUG + BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend; +#endif + +} BIN_HR_SPLIT_PRE_REND, *BIN_HR_SPLIT_PRE_REND_HANDLE; + +typedef struct ivas_binaural_head_rot_split_post_rendering_struct +{ + BIN_HR_SPLIT_REND_MD rot_md[MAX_HEAD_ROT_POSES][MAX_SPLIT_MD_SUBFRAMES][MAX_SPLIT_REND_MD_BANDS]; + IVAS_QUATERNION QuaternionsPre[MAX_PARAM_SPATIAL_SUBFRAMES]; + int16_t low_Res; + + float fix_pos_rot_mat[MAX_HEAD_ROT_POSES - 1][BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + IVAS_SPLIT_REND_POSE_TYPE pose_type[MAX_HEAD_ROT_POSES - 1]; + 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]; +#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]; +#endif + int16_t cf_flag; + HANDLE_CLDFB_FILTER_BANK cldfbAna[BINAURAL_CHANNELS]; + HANDLE_CLDFB_FILTER_BANK cldfbSyn[BINAURAL_CHANNELS]; +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + HANDLE_CLDFB_FILTER_BANK cldfbSynReconsBinDec[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS]; +#endif + +} BIN_HR_SPLIT_POST_REND, *BIN_HR_SPLIT_POST_REND_HANDLE; + +typedef struct ivas_binaural_head_rot_split_rendering_lcld_enc_struct +{ + void *pLcld_enc; + int16_t iChannels; + LCLDEncoder *psLCLDEncoder; + float ***pppfLCLDReal; + float ***pppfLCLDImag; +#ifdef CLDFB_DEBUG + FILE *cldfbIn; + int16_t numFrame; +#endif + +} BIN_HR_SPLIT_LCLD_ENC, *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]; +#if CLDFB_PLC_XF > 0 + float xf_bet[2][CLDFB_NO_CHANNELS_MAX][CLDFB_PLC_XF]; +#endif + +} CLDFB_PLC, *CLDFB_PLC_HANDLE; + +typedef struct +{ + CLDFB_PLC CldfbPLC_state; + int16_t prev_bfi; + int16_t bf_count; + +} SPLIT_REND_PLC_STRUCT, *SPLIT_REND_PLC_HANDLE; + +typedef struct ivas_binaural_head_rot_split_rendering_lcld_dec_struct +{ + void *pLcld_dec; + int32_t iChannels; + LCLDDecoder *psLCLDDecoder; + float ***pppfDecLCLDReal; + float ***pppfDecLCLDImag; +#ifdef CLDFB_DEBUG + FILE *cldfbOut; + int16_t numFrame; +#endif + SPLIT_REND_PLC_HANDLE hSplitRendPLC; + +} BIN_HR_SPLIT_LCLD_DEC, *BIN_HR_SPLIT_LCLD_DEC_HANDLE; + +typedef struct +{ +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + HANDLE_CLDFB_FILTER_BANK cldfbAna[( 1 + MAX_HEAD_ROT_POSES ) * BINAURAL_CHANNELS]; +#else + HANDLE_CLDFB_FILTER_BANK cldfbAna[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS]; +#endif + HANDLE_CLDFB_FILTER_BANK cldfbSyn[BINAURAL_CHANNELS]; + +} CLDFB_HANDLES_WRAPPER, *CLDFB_HANDLES_WRAPPER_HANDLE; + +typedef struct +{ + int16_t num_poses; + float relative_head_poses[MAX_HEAD_ROT_POSES][3]; + int16_t dof; + int16_t hq_mode; + IVAS_SPLIT_REND_ROT_AXIS rot_axis; + IVAS_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode; + +} MULTI_BIN_REND_POSE_DATA; + +typedef struct +{ + MULTI_BIN_REND_POSE_DATA multiBinPoseData; + BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend; + BIN_HR_SPLIT_LCLD_ENC_HANDLE hSplitBinLCLDEnc; + CLDFB_HANDLES_WRAPPER_HANDLE hCldfbHandles; + IVAS_LC3PLUS_ENC_HANDLE hLc3plusEnc; + BINAURAL_TD_OBJECT_RENDERER_HANDLE hTdRendHandles[MAX_HEAD_ROT_POSES - 1]; + float *lc3plusDelayBuffers[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS]; /* Used to time-align head pose correction metadata with LC3plus-coded reference audio */ + int32_t lc3plusDelaySamples; + +} SPLIT_REND_WRAPPER; + +typedef struct +{ + MULTI_BIN_REND_POSE_DATA multiBinPoseData; + BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend; + BIN_HR_SPLIT_LCLD_DEC_HANDLE hSplitBinLCLDDec; + int16_t first_good_frame_received; + IVAS_LC3PLUS_DEC_HANDLE hLc3plusDec; + +} SPLIT_POST_REND_WRAPPER; +#endif /*----------------------------------------------------------------------------------* @@ -1285,6 +1528,9 @@ typedef struct float release_heuristic; float attack_constant; int16_t strong_saturation_count; +#ifdef DEBUGGING + int32_t cnt_frames_limited; /* counter of frames in which the limiter is applied */ +#endif } IVAS_LIMITER, *IVAS_LIMITER_HANDLE; @@ -1341,6 +1587,21 @@ typedef struct ivas_LS_setup_custom } LSSETUP_CUSTOM_STRUCT, *LSSETUP_CUSTOM_HANDLE; +#ifdef SPLIT_REND_WITH_HEAD_ROT + +/*----------------------------------------------------------------------------------* + * CLDFB renderer wrapper + *----------------------------------------------------------------------------------*/ + +typedef struct +{ + int32_t binaural_latency_ns; + BINAURAL_RENDERER_HANDLE hCldfbRend; + HRTFS_FASTCONV_HANDLE hHrtfFastConv; + +} CLDFB_REND_WRAPPER; + +#endif /* Channel types in a channel-based config */ typedef enum @@ -1362,7 +1623,11 @@ typedef struct ivas_masa_external_rendering_struct RENDERER_TYPE renderer_type; DIRAC_REND_HANDLE hDirACRend; SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom; +#ifdef SPLIT_REND_WITH_HEAD_ROT + DIRAC_DEC_BIN_HANDLE hDiracDecBin[MAX_HEAD_ROT_POSES]; +#else DIRAC_DEC_BIN_HANDLE hDiracDecBin; +#endif REVERB_STRUCT_HANDLE hReverb; HRTFS_PARAMBIN_HANDLE hHrtfParambin; diff --git a/lib_rend/ivas_td_decorr.c b/lib_rend/ivas_td_decorr.c index 8deab7b15..beff2ae36 100644 --- a/lib_rend/ivas_td_decorr.c +++ b/lib_rend/ivas_td_decorr.c @@ -35,6 +35,9 @@ #include "prot.h" #include "ivas_prot.h" #include "ivas_prot_rend.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "math.h" #include #include "wmc_auto.h" diff --git a/lib_rend/ivas_vbap.c b/lib_rend/ivas_vbap.c index 38a7a86c0..602d64df6 100644 --- a/lib_rend/ivas_vbap.c +++ b/lib_rend/ivas_vbap.c @@ -38,6 +38,9 @@ #include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_stat_dec.h" +#ifdef DEBUGGING +#include "debug.h" +#endif #include "wmc_auto.h" /*-----------------------------------------------------------------------* @@ -492,6 +495,10 @@ void vbap_determine_gains( float *top_virtual_speaker_node_division_gains; float *back_virtual_speaker_node_division_gains; +#ifdef DEBUGGING + assert( hVBAPdata != NULL && "VBAP gain determination requires initialized structure." ); + assert( gains != NULL && "VBAP gain determination requires reserved memory for gain output." ); +#endif push_wmops( "vbap_gains" ); num_speaker_nodes = hVBAPdata->num_speaker_nodes; diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index 4ffc2cc07..852454253 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -51,10 +51,20 @@ /* Maximum buffer length (per channel) in samples. * Keep this separate from L_FRAME48k in case we want to support different size later */ #define MAX_BUFFER_LENGTH_PER_CHANNEL ( L_FRAME48k ) +#ifdef SPLIT_REND_WITH_HEAD_ROT +#define MAX_CLDFB_BUFFER_LENGTH_PER_CHANNEL ( MAX_BUFFER_LENGTH_PER_CHANNEL * 2 ) +#endif /* Maximum buffer length (total) in samples. */ /* Maximum buffer length (total) in samples. */ +#ifdef SPLIT_REND_WITH_HEAD_ROT +#define MAX_BUFFER_LENGTH ( MAX_BUFFER_LENGTH_PER_CHANNEL * MAX_INPUT_CHANNELS ) +#define MAX_CLDFB_BUFFER_LENGTH ( MAX_CLDFB_BUFFER_LENGTH_PER_CHANNEL * MAX_INPUT_CHANNELS ) +#define MAX_BIN_BUFFER_LENGTH ( MAX_BUFFER_LENGTH_PER_CHANNEL * BINAURAL_CHANNELS ) +#define MAX_CLDFB_BIN_BUFFER_LENGTH ( MAX_CLDFB_BUFFER_LENGTH_PER_CHANNEL * BINAURAL_CHANNELS ) +#else #define MAX_BUFFER_LENGTH ( MAX_BUFFER_LENGTH_PER_CHANNEL * MAX_INPUT_CHANNELS ) +#endif #define MAX_BIN_DELAY_SAMPLES 50 /* Maximum supported rendering latency for binaural IRs */ @@ -93,6 +103,11 @@ typedef struct const LSSETUP_CUSTOM_STRUCT *pCustomLsOut; const EFAP_WRAPPER *pEfapOutWrapper; const IVAS_REND_HeadRotData *pHeadRotData; +#ifdef SPLIT_REND_WITH_HEAD_ROT + const RENDER_CONFIG_HANDLE *hhRendererConfig; + const int16_t *pSplitRendBFI; + const SPLIT_REND_WRAPPER *pSplitRendWrapper; +#endif const COMBINED_ORIENTATION_HANDLE *pCombinedOrientationData; } rendering_context; @@ -118,6 +133,9 @@ typedef struct rotation_matrix rot_mat_prev; pan_vector prev_pan_gains; int8_t firstFrameRendered; +#ifdef SPLIT_REND_WITH_HEAD_ROT + TDREND_WRAPPER splitTdRendWrappers[MAX_HEAD_ROT_POSES - 1]; /* Additional TD Rend instances used for split rendering */ +#endif float *bufferData; int16_t nonDiegeticPan; float nonDiegeticPanGain; @@ -148,8 +166,15 @@ typedef struct EFAP_WRAPPER efapInWrapper; TDREND_WRAPPER tdRendWrapper; CREND_WRAPPER_HANDLE crendWrapper; +#ifdef SPLIT_REND_WITH_HEAD_ROT + TDREND_WRAPPER splitTdRendWrappers[MAX_HEAD_ROT_POSES - 1]; /* Additional TD Rend instances used for split rendering */ +#endif REVERB_HANDLE hReverb; +#ifdef SPLIT_REND_WITH_HEAD_ROT + rotation_gains rot_gains_prev[MAX_HEAD_ROT_POSES]; +#else rotation_gains rot_gains_prev; +#endif int16_t nonDiegeticPan; float nonDiegeticPanGain; lfe_routing lfeRouting; @@ -163,12 +188,29 @@ typedef struct { input_base base; pan_matrix hoaDecMtx; +#ifdef SPLIT_REND_WITH_HEAD_ROT + CLDFB_REND_WRAPPER cldfbRendWrapper; +#endif CREND_WRAPPER_HANDLE crendWrapper; +#ifdef SPLIT_REND_WITH_HEAD_ROT + rotation_gains rot_gains_prev[MAX_HEAD_ROT_POSES]; +#else rotation_gains rot_gains_prev; +#endif float *bufferData; DIRAC_ANA_HANDLE hDirAC; } input_sba; +#ifdef SPLIT_REND_WITH_HEAD_ROT +typedef struct +{ + input_base base; + SPLIT_POST_REND_WRAPPER splitPostRendWrapper; + float *bufferData; + int16_t numCachedSamples; /* Number of decoded samples in bufferData that have not yet been played out */ + IVAS_REND_BitstreamBuffer *hBits; +} input_split_post_rend; +#endif typedef struct @@ -186,18 +228,31 @@ struct IVAS_REND int32_t sampleRateOut; IVAS_LIMITER_HANDLE hLimiter; +#ifdef DEBUGGING + int32_t numClipping; /* Counter of clipped output samples */ +#endif input_ism inputsIsm[RENDERER_MAX_ISM_INPUTS]; input_mc inputsMc[RENDERER_MAX_MC_INPUTS]; input_sba inputsSba[RENDERER_MAX_SBA_INPUTS]; input_masa inputsMasa[RENDERER_MAX_MASA_INPUTS]; +#ifdef SPLIT_REND_WITH_HEAD_ROT + input_split_post_rend inputsSplitPost[RENDERER_MAX_BIN_INPUTS]; +#endif AUDIO_CONFIG inputConfig; AUDIO_CONFIG outputConfig; EFAP_WRAPPER efapOutWrapper; IVAS_LSSETUP_CUSTOM_STRUCT customLsOut; +#ifdef SPLIT_REND_WITH_HEAD_ROT + SPLIT_REND_WRAPPER splitRendWrapper; + IVAS_REND_AudioBuffer splitRendEncBuffer; +#endif IVAS_REND_HeadRotData headRotData; +#ifdef SPLIT_REND_WITH_HEAD_ROT + int16_t splitRendBFI; +#endif EXTERNAL_ORIENTATION_HANDLE hExternalOrientationData; COMBINED_ORIENTATION_HANDLE hCombinedOrientationData; @@ -287,6 +342,101 @@ static float *getSmplPtr( return buffer.data + chnlIdx * buffer.config.numSamplesPerChannel + smplIdx; } +#ifdef SPLIT_REND_WITH_HEAD_ROT +static void convertBitsBufferToInternalBitsBuff( + const IVAS_REND_BitstreamBuffer outBits, + IVAS_SPLIT_REND_BITS_HANDLE hBits ) +{ + hBits->bits_buf = outBits.bits; + hBits->bits_read = outBits.config.bitsRead; + hBits->bits_written = outBits.config.bitsWritten; + hBits->buf_len = outBits.config.bufLenInBytes; + hBits->codec = outBits.config.codec; + hBits->pose_correction = outBits.config.poseCorrection; + hBits->codec_frame_size_ms = outBits.config.codec_frame_size_ms; + + return; +} + +static void convertInternalBitsBuffToBitsBuffer( + IVAS_REND_BitstreamBuffer *hOutBits, + const IVAS_SPLIT_REND_BITS_DATA bits ) +{ + hOutBits->bits = bits.bits_buf; + hOutBits->config.bitsRead = bits.bits_read; + hOutBits->config.bitsWritten = bits.bits_written; + hOutBits->config.bufLenInBytes = bits.buf_len; + hOutBits->config.codec = bits.codec; + hOutBits->config.poseCorrection = bits.pose_correction; + hOutBits->config.codec_frame_size_ms = bits.codec_frame_size_ms; + + return; +} + +static void copyBufferToCLDFBarray( + const IVAS_REND_AudioBuffer buffer, + float re[MAX_OUTPUT_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + float im[MAX_OUTPUT_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX] ) +{ + uint32_t smplIdx, slotIdx; + uint32_t numCldfbSamples, num_bands; + uint32_t chnlIdx; + const float *readPtr; + + assert( ( buffer.config.is_cldfb == 1 ) && "for time domain input call copyBufferTo2dArray()" ); + readPtr = buffer.data; + numCldfbSamples = ( (uint32_t) buffer.config.numSamplesPerChannel ) >> 1; + num_bands = numCldfbSamples / CLDFB_NO_COL_MAX; + for ( chnlIdx = 0; chnlIdx < (uint32_t) buffer.config.numChannels; ++chnlIdx ) + { + for ( slotIdx = 0; slotIdx < CLDFB_NO_COL_MAX; ++slotIdx ) + { + for ( smplIdx = 0; smplIdx < num_bands; ++smplIdx ) + { + re[chnlIdx][slotIdx][smplIdx] = *readPtr++; + } + for ( smplIdx = 0; smplIdx < num_bands; ++smplIdx ) + { + im[chnlIdx][slotIdx][smplIdx] = *readPtr++; + } + } + } + + return; +} + +static void accumulateCLDFBArrayToBuffer( + float re[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + float im[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + IVAS_REND_AudioBuffer *buffer ) +{ + uint32_t smplIdx, slotIdx; + uint32_t numCldfbSamples, num_bands; + uint32_t chnlIdx; + float *writePtr; + + assert( ( buffer->config.is_cldfb == 1 ) && "for time domain input call copyBufferTo2dArray()" ); + writePtr = buffer->data; + numCldfbSamples = ( (uint32_t) buffer->config.numSamplesPerChannel ) >> 1; + num_bands = numCldfbSamples / CLDFB_NO_COL_MAX; + for ( chnlIdx = 0; chnlIdx < (uint32_t) buffer->config.numChannels; ++chnlIdx ) + { + for ( slotIdx = 0; slotIdx < CLDFB_NO_COL_MAX; ++slotIdx ) + { + for ( smplIdx = 0; smplIdx < num_bands; ++smplIdx ) + { + *writePtr++ += re[chnlIdx][slotIdx][smplIdx]; + } + for ( smplIdx = 0; smplIdx < num_bands; ++smplIdx ) + { + *writePtr++ += im[chnlIdx][slotIdx][smplIdx]; + } + } + } + + return; +} +#endif static void copyBufferTo2dArray( const IVAS_REND_AudioBuffer buffer, @@ -296,6 +446,9 @@ static void copyBufferTo2dArray( uint32_t chnlIdx; const float *readPtr; +#ifdef SPLIT_REND_WITH_HEAD_ROT + assert( ( buffer.config.is_cldfb == 0 ) && "for CLDFB input call copyBufferToCLDFBarray()" ); +#endif readPtr = buffer.data; for ( chnlIdx = 0; chnlIdx < (uint32_t) buffer.config.numChannels; ++chnlIdx ) @@ -311,6 +464,9 @@ static void copyBufferTo2dArray( static void accumulate2dArrayToBuffer( float array[][L_FRAME48k], +#ifdef SPLIT_REND_WITH_HEAD_ROT + const +#endif IVAS_REND_AudioBuffer *buffer ) { int16_t smplIdx, chnlIdx; @@ -366,6 +522,12 @@ static int32_t limitRendererOutput( /* Apply clipping to buffer in case the limiter let through some samples > 1.0f */ 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 ); } @@ -397,6 +559,10 @@ static ivas_error validateOutputAudioConfig( case IVAS_AUDIO_CONFIG_HOA2: case IVAS_AUDIO_CONFIG_HOA3: case IVAS_AUDIO_CONFIG_BINAURAL: +#ifdef SPLIT_REND_WITH_HEAD_ROT + case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED: + case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM: +#endif case IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR: case IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB: case IVAS_AUDIO_CONFIG_MASA1: @@ -476,6 +642,14 @@ static ivas_error validateOutputSampleRate( /* If no binaural rendering, any sampling rate is supported */ return IVAS_ERR_OK; } +#ifdef SPLIT_REND_WITH_HEAD_ROT + else if ( ( outConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || outConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) && sampleRate != 48000 ) + { + return IVAS_ERROR( IVAS_ERR_INVALID_SAMPLING_RATE, "Error: Only 48kHz output sampling rate is supported for split rendering." ); + } + else + { +#endif /* Otherwise rendering to binaural, support the same set as IVAS decoder */ switch ( sampleRate ) @@ -488,6 +662,9 @@ static ivas_error validateOutputSampleRate( } return IVAS_ERR_INVALID_SAMPLING_RATE; +#ifdef SPLIT_REND_WITH_HEAD_ROT + } +#endif } @@ -510,6 +687,10 @@ ivas_error getAudioConfigNumChannels( break; case IVAS_AUDIO_CONFIG_STEREO: case IVAS_AUDIO_CONFIG_BINAURAL: +#ifdef SPLIT_REND_WITH_HEAD_ROT + case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED: + case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM: +#endif case IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR: case IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB: case IVAS_AUDIO_CONFIG_MASA2: @@ -963,6 +1144,9 @@ static ivas_error initHeadRotation( hIvasRend->headRotData.headPositions[i] = quaternionInit(); } +#ifdef SPLIT_REND_WITH_HEAD_ROT + hIvasRend->headRotData.sr_pose_pred_axis = DEFAULT_AXIS; +#endif if ( ( hIvasRend->headRotData.hOrientationTracker = (ivas_orient_trk_state_t *) malloc( sizeof( ivas_orient_trk_state_t ) ) ) == NULL ) { @@ -1087,6 +1271,11 @@ static rendering_context getRendCtx( ctx.pCustomLsOut = &hIvasRend->customLsOut; ctx.pEfapOutWrapper = &hIvasRend->efapOutWrapper; ctx.pHeadRotData = &hIvasRend->headRotData; +#ifdef SPLIT_REND_WITH_HEAD_ROT + ctx.hhRendererConfig = &hIvasRend->hRendererConfig; + ctx.pSplitRendBFI = &hIvasRend->splitRendBFI; + ctx.pSplitRendWrapper = &hIvasRend->splitRendWrapper; +#endif ctx.pCombinedOrientationData = &hIvasRend->hCombinedOrientationData; return ctx; @@ -1133,7 +1322,11 @@ static ivas_error initIsmMasaRendering( inputIsm->tdRendWrapper.hHrtfTD = NULL; } +#ifdef SPLIT_REND_WITH_HEAD_ROT + ivas_rend_closeCrend( &inputIsm->crendWrapper, inputIsm->base.ctx.pSplitRendWrapper->multiBinPoseData.num_poses ); +#else ivas_rend_closeCrend( &inputIsm->crendWrapper ); +#endif ivas_reverb_close( &inputIsm->hReverb ); @@ -1156,6 +1349,9 @@ static ivas_error setRendInputActiveIsm( rendering_context rendCtx; AUDIO_CONFIG outConfig; input_ism *inputIsm; +#ifdef SPLIT_REND_WITH_HEAD_ROT + int16_t i; +#endif inputIsm = (input_ism *) input; rendCtx = inputIsm->base.ctx; @@ -1182,17 +1378,46 @@ static ivas_error setRendInputActiveIsm( initRotMatrix( inputIsm->rot_mat_prev ); set_zero( inputIsm->prev_pan_gains, MAX_OUTPUT_CHANNELS ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + for ( i = 0; i < (int16_t) ( sizeof( inputIsm->splitTdRendWrappers ) / sizeof( *inputIsm->splitTdRendWrappers ) ); ++i ) + { + inputIsm->splitTdRendWrappers[i] = defaultTdRendWrapper(); + } +#endif inputIsm->hOMasa = NULL; error = IVAS_ERR_OK; +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( outConfig == IVAS_AUDIO_CONFIG_BINAURAL || outConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || outConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) +#else if ( outConfig == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) +#endif { +#ifndef SPLIT_REND_WITH_HEAD_ROT if ( ( error = ivas_rend_openCrend( &inputIsm->crendWrapper, IVAS_AUDIO_CONFIG_7_1_4, outConfig, hRendCfg, NULL, *rendCtx.pOutSampleRate ) ) != IVAS_ERR_OK ) { return error; } +#else + if ( ( error = ivas_td_binaural_open_ext( &inputIsm->tdRendWrapper, inConfig, hRendCfg, NULL, *rendCtx.pOutSampleRate ) ) != IVAS_ERR_OK ) + { + return error; + } + + /* Open TD renderer wrappers */ + for ( i = 0; i < MAX_HEAD_ROT_POSES - 1; ++i ) + { + if ( ( error = ivas_td_binaural_open_ext( &inputIsm->splitTdRendWrappers[i], inConfig, hRendCfg, NULL, *inputIsm->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) + { + return error; + } + + /* Assert same delay as main TD renderer */ + assert( inputIsm->splitTdRendWrappers[i].binaural_latency_ns == inputIsm->tdRendWrapper.binaural_latency_ns ); + } +#endif } else if ( outConfig == IVAS_AUDIO_CONFIG_MASA1 || outConfig == IVAS_AUDIO_CONFIG_MASA2 ) { @@ -1203,6 +1428,20 @@ static ivas_error setRendInputActiveIsm( } else { +#ifndef SPLIT_REND_WITH_HEAD_ROT + if ( ( error = ivas_td_binaural_open_ext( &inputIsm->tdRendWrapper, inConfig, hRendCfg, NULL, *rendCtx.pOutSampleRate ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( outConfig == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) + { + if ( ( error = ivas_reverb_open( &( inputIsm->hReverb ), outConfig, NULL, inputIsm->tdRendWrapper.hBinRendererTd->HrFiltSet_p->lr_energy_and_iac, hRendCfg, *rendCtx.pOutSampleRate ) ) != IVAS_ERR_OK ) + { + return error; + } + } +#else if ( ( error = ivas_td_binaural_open_ext( &inputIsm->tdRendWrapper, inConfig, hRendCfg, NULL, *rendCtx.pOutSampleRate ) ) != IVAS_ERR_OK ) { return error; @@ -1215,6 +1454,14 @@ static ivas_error setRendInputActiveIsm( return error; } } + else if ( outConfig == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) + { + if ( ( error = ivas_rend_openCrend( &inputIsm->crendWrapper, IVAS_AUDIO_CONFIG_7_1_4, outConfig, hRendCfg, NULL, *rendCtx.pOutSampleRate, rendCtx.pSplitRendWrapper->multiBinPoseData.num_poses ) ) != IVAS_ERR_OK ) + { + return error; + } + } +#endif } return IVAS_ERR_OK; @@ -1225,6 +1472,9 @@ static void clearInputIsm( input_ism *inputIsm ) { rendering_context rendCtx; +#ifdef SPLIT_REND_WITH_HEAD_ROT + int16_t i; +#endif rendCtx = inputIsm->base.ctx; @@ -1232,7 +1482,11 @@ static void clearInputIsm( initRendInputBase( &inputIsm->base, IVAS_AUDIO_CONFIG_INVALID, 0, rendCtx, NULL, 0 ); /* Free input's internal handles */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + ivas_rend_closeCrend( &inputIsm->crendWrapper, inputIsm->base.ctx.pSplitRendWrapper->multiBinPoseData.num_poses ); +#else ivas_rend_closeCrend( &inputIsm->crendWrapper ); +#endif ivas_reverb_close( &inputIsm->hReverb ); @@ -1242,6 +1496,13 @@ static void clearInputIsm( inputIsm->tdRendWrapper.hHrtfTD = NULL; } +#ifdef SPLIT_REND_WITH_HEAD_ROT + for ( i = 0; i < (int16_t) ( sizeof( inputIsm->splitTdRendWrappers ) / sizeof( *inputIsm->splitTdRendWrappers ) ); ++i ) + { + ivas_td_binaural_close( &inputIsm->splitTdRendWrappers[i].hBinRendererTd ); + inputIsm->splitTdRendWrappers[i].hHrtfTD = NULL; + } +#endif ivas_omasa_ana_close( &( inputIsm->hOMasa ) ); @@ -1835,6 +2096,10 @@ static ivas_error updateMcPanGains( switch ( outConfig ) { case IVAS_AUDIO_CONFIG_BINAURAL: +#ifdef SPLIT_REND_WITH_HEAD_ROT + case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED: + case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM: +#endif break; /* Do nothing */ case IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR: case IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB: @@ -1882,6 +2147,9 @@ static ivas_error initMcBinauralRendering( uint8_t reconfigureFlag ) { ivas_error error; +#ifdef SPLIT_REND_WITH_HEAD_ROT + int16_t i; +#endif int32_t binauralDelayNs; int32_t outSampleRate; int8_t useTDRend; @@ -1909,11 +2177,28 @@ static ivas_error initMcBinauralRendering( inputMc->tdRendWrapper.hHrtfTD = NULL; } +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( !reconfigureFlag || !useTDRend ) + { + for ( i = 0; i < MAX_HEAD_ROT_POSES - 1; ++i ) + { + if ( inputMc->splitTdRendWrappers[i].hBinRendererTd != NULL ) + { + ivas_td_binaural_close( &inputMc->splitTdRendWrappers[i].hBinRendererTd ); + inputMc->splitTdRendWrappers[i].hHrtfTD = NULL; + } + } + } +#endif /* if we need to use TD renderer and CREND was open, close it */ if ( useTDRend ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + ivas_rend_closeCrend( &inputMc->crendWrapper, inputMc->base.ctx.pSplitRendWrapper->multiBinPoseData.num_poses ); +#else ivas_rend_closeCrend( &inputMc->crendWrapper ); +#endif } if ( !reconfigureFlag || ( !useTDRend && outConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB && inputMc->hReverb != NULL ) ) @@ -1938,6 +2223,23 @@ static ivas_error initMcBinauralRendering( return error; } +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( outConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || outConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { + /* Open TD renderer wrappers */ + for ( i = 0; i < MAX_HEAD_ROT_POSES - 1; ++i ) + { + if ( ( error = ivas_td_binaural_open_ext( &inputMc->splitTdRendWrappers[i], inConfig, hRendCfg, &inputMc->customLsInput, outSampleRate ) ) != IVAS_ERR_OK ) + { + return error; + } + + /* Assert same delay as main TD renderer */ + assert( inputMc->splitTdRendWrappers[i].binaural_latency_ns == inputMc->tdRendWrapper.binaural_latency_ns ); + } + } + +#endif if ( outConfig == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB && inputMc->hReverb == NULL ) { if ( ( error = ivas_reverb_open( &( inputMc->hReverb ), outConfig, NULL, inputMc->tdRendWrapper.hBinRendererTd->HrFiltSet_p->lr_energy_and_iac, hRendCfg, outSampleRate ) ) != IVAS_ERR_OK ) @@ -1949,7 +2251,11 @@ static ivas_error initMcBinauralRendering( else if ( !useTDRend && inputMc->crendWrapper == NULL ) { /* open CREND */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( error = ivas_rend_openCrend( &inputMc->crendWrapper, ( inConfig == IVAS_AUDIO_CONFIG_LS_CUSTOM ) ? IVAS_AUDIO_CONFIG_7_1_4 : inConfig, outConfig, hRendCfg, NULL, outSampleRate, ( ( outConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) || ( outConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) ) ? inputMc->base.ctx.pSplitRendWrapper->multiBinPoseData.num_poses : 1 ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_rend_openCrend( &inputMc->crendWrapper, ( inConfig == IVAS_AUDIO_CONFIG_LS_CUSTOM ) ? IVAS_AUDIO_CONFIG_7_1_4 : inConfig, outConfig, hRendCfg, NULL, outSampleRate ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -1990,7 +2296,11 @@ static ivas_error initMcMasaRendering( inputMc->tdRendWrapper.hHrtfTD = NULL; } +#ifdef SPLIT_REND_WITH_HEAD_ROT + ivas_rend_closeCrend( &inputMc->crendWrapper, inputMc->base.ctx.pSplitRendWrapper->multiBinPoseData.num_poses ); +#else ivas_rend_closeCrend( &inputMc->crendWrapper ); +#endif ivas_reverb_close( &inputMc->hReverb ); @@ -2073,10 +2383,16 @@ static ivas_error setRendInputActiveMc( const IVAS_REND_InputId id, RENDER_CONFIG_DATA *hRendCfg ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + int16_t i; +#endif ivas_error error; rendering_context rendCtx; AUDIO_CONFIG outConfig; input_mc *inputMc; +#ifdef SPLIT_REND_WITH_HEAD_ROT + int16_t pos_idx; +#endif inputMc = (input_mc *) input; rendCtx = inputMc->base.ctx; @@ -2105,12 +2421,28 @@ static ivas_error setRendInputActiveMc( inputMc->hReverb = NULL; inputMc->hMcMasa = NULL; +#ifdef SPLIT_REND_WITH_HEAD_ROT + for ( pos_idx = 0; pos_idx < MAX_HEAD_ROT_POSES; pos_idx++ ) + { + initRotGains( inputMc->rot_gains_prev[pos_idx] ); + } +#else initRotGains( inputMc->rot_gains_prev ); +#endif inputMc->lfeRouting = defaultLfeRouting( inConfig, inputMc->customLsInput, outConfig, *inputMc->base.ctx.pCustomLsOut ); set_zero( inputMc->lfeDelayBuffer, MAX_BIN_DELAY_SAMPLES ); inputMc->binauralDelaySmp = 0; +#ifdef SPLIT_REND_WITH_HEAD_ROT + for ( i = 0; i < (int16_t) ( sizeof( inputMc->splitTdRendWrappers ) / sizeof( *inputMc->splitTdRendWrappers ) ); ++i ) + { + inputMc->splitTdRendWrappers[i] = defaultTdRendWrapper(); + } + + if ( getAudioConfigType( outConfig ) == IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL ) +#else if ( outConfig == IVAS_AUDIO_CONFIG_BINAURAL || outConfig == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR || outConfig == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) +#endif { if ( ( error = initMcBinauralRendering( inputMc, inConfig, outConfig, hRendCfg, FALSE ) ) != IVAS_ERR_OK ) { @@ -2138,6 +2470,9 @@ static ivas_error setRendInputActiveMc( static void clearInputMc( input_mc *inputMc ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + int16_t i; +#endif rendering_context rendCtx; rendCtx = inputMc->base.ctx; @@ -2152,7 +2487,11 @@ static void clearInputMc( efap_free_data( &inputMc->efapInWrapper.hEfap ); } +#ifdef SPLIT_REND_WITH_HEAD_ROT + ivas_rend_closeCrend( &inputMc->crendWrapper, inputMc->base.ctx.pSplitRendWrapper->multiBinPoseData.num_poses ); +#else ivas_rend_closeCrend( &inputMc->crendWrapper ); +#endif ivas_reverb_close( &inputMc->hReverb ); @@ -2162,6 +2501,16 @@ static void clearInputMc( inputMc->tdRendWrapper.hHrtfTD = NULL; } +#ifdef SPLIT_REND_WITH_HEAD_ROT + for ( i = 0; i < (int16_t) ( sizeof( inputMc->splitTdRendWrappers ) / sizeof( *inputMc->splitTdRendWrappers ) ); ++i ) + { + if ( inputMc->splitTdRendWrappers[i].hBinRendererTd != NULL ) + { + ivas_td_binaural_close( &inputMc->splitTdRendWrappers[i].hBinRendererTd ); + inputMc->splitTdRendWrappers[i].hHrtfTD = NULL; + } + } +#endif ivas_mcmasa_ana_close( &( inputMc->hMcMasa ) ); @@ -2259,6 +2608,33 @@ static ivas_error initSbaPanGainsForSbaOut( } +#ifdef SPLIT_REND_WITH_HEAD_ROT +static ivas_error updateSplitPostRendPanGains( + input_split_post_rend *inputSplitPostRend, + const AUDIO_CONFIG outConfig, + RENDER_CONFIG_DATA *hRendCfg ) +{ + ivas_error error; + rendering_context rendCtx; + int16_t numOutChannels; + + if ( ( error = getAudioConfigNumChannels( outConfig, &numOutChannels ) ) != IVAS_ERR_OK ) + { + + return error; + } + + rendCtx = inputSplitPostRend->base.ctx; + ivas_renderSplitGetMultiBinPoseData( &hRendCfg->split_rend_config, &inputSplitPostRend->splitPostRendWrapper.multiBinPoseData, rendCtx.pHeadRotData->sr_pose_pred_axis ); + + if ( ( error = ivas_splitBinPostRendOpen( &inputSplitPostRend->splitPostRendWrapper.hBinHrSplitPostRend, &inputSplitPostRend->splitPostRendWrapper.multiBinPoseData, *rendCtx.pOutSampleRate ) ) != IVAS_ERR_OK ) + { + return error; + } + + return IVAS_ERR_OK; +} +#endif static ivas_error updateSbaPanGains( @@ -2287,9 +2663,47 @@ static ivas_error updateSbaPanGains( case IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL: switch ( outConfig ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED: + case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM: + { + if ( hRendCfg->split_rend_config.rendererSelection == IVAS_SPLIT_REND_RENDERER_SELECTION_FASTCONV ) + + { + assert( inConfig == IVAS_AUDIO_CONFIG_HOA3 && ( *rendCtx.pOutSampleRate == 48000 ) && "split binaural fast conv mode is currently supported with HOA3 input and 48k sampling rate only" ); + if ( ( error = ivas_rend_openCldfbRend( &inputSba->cldfbRendWrapper, inConfig, outConfig, &rendCtx.pSplitRendWrapper->multiBinPoseData, *rendCtx.pOutSampleRate ) ) != IVAS_ERR_OK ) + { + return error; + } + } + else + { + assert( ( *rendCtx.pOutSampleRate == 48000 ) && "split binaural crend mode is currently supported with 48k sampling rate only" ); + if ( ( error = ivas_rend_openMultiBinCrend( &inputSba->crendWrapper, inConfig, outConfig, &rendCtx.pSplitRendWrapper->multiBinPoseData, *rendCtx.pOutSampleRate ) ) != IVAS_ERR_OK ) + { + return error; + } + } + break; + } +#endif case IVAS_AUDIO_CONFIG_BINAURAL: +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( hRendCfg->split_rend_config.rendererSelection == IVAS_SPLIT_REND_RENDERER_SELECTION_FASTCONV ) + { + if ( ( error = ivas_rend_openCldfbRend( &inputSba->cldfbRendWrapper, inConfig, outConfig, &rendCtx.pSplitRendWrapper->multiBinPoseData, *rendCtx.pOutSampleRate ) ) != IVAS_ERR_OK ) + { + return error; + } + } + else +#endif { +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( error = ivas_rend_openCrend( &inputSba->crendWrapper, inConfig, outConfig, hRendCfg, NULL, *rendCtx.pOutSampleRate, rendCtx.pSplitRendWrapper->multiBinPoseData.num_poses ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_rend_openCrend( &inputSba->crendWrapper, inConfig, outConfig, hRendCfg, NULL, *rendCtx.pOutSampleRate ) ) != IVAS_ERR_OK ) +#endif { return error; @@ -2303,7 +2717,11 @@ static ivas_error updateSbaPanGains( return error; } +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( error = ivas_rend_openCrend( &inputSba->crendWrapper, IVAS_AUDIO_CONFIG_7_1_4, outConfig, hRendCfg, NULL, *rendCtx.pOutSampleRate, rendCtx.pSplitRendWrapper->multiBinPoseData.num_poses ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_rend_openCrend( &inputSba->crendWrapper, IVAS_AUDIO_CONFIG_7_1_4, outConfig, hRendCfg, NULL, *rendCtx.pOutSampleRate ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -2329,6 +2747,38 @@ static ivas_error updateSbaPanGains( } +#ifdef SPLIT_REND_WITH_HEAD_ROT +static ivas_error setRendInputActiveSplitPostRend( + void *input, + const AUDIO_CONFIG inConfig, + const IVAS_REND_InputId id, + RENDER_CONFIG_DATA *hRendCfg ) +{ + ivas_error error; + rendering_context rendCtx; + AUDIO_CONFIG outConfig; + input_split_post_rend *inputSplitPostRend; + + inputSplitPostRend = (input_split_post_rend *) input; + rendCtx = inputSplitPostRend->base.ctx; + outConfig = *rendCtx.pOutConfig; + + if ( ( error = allocateInputBaseBufferData( &inputSplitPostRend->bufferData, MAX_CLDFB_BIN_BUFFER_LENGTH ) ) != IVAS_ERR_OK ) + { + return error; + } + + initRendInputBase( &inputSplitPostRend->base, inConfig, id, rendCtx, inputSplitPostRend->bufferData, MAX_CLDFB_BIN_BUFFER_LENGTH ); + inputSplitPostRend->numCachedSamples = 0; + + if ( ( error = updateSplitPostRendPanGains( inputSplitPostRend, outConfig, hRendCfg ) ) != IVAS_ERR_OK ) + { + return error; + } + + return IVAS_ERR_OK; +} +#endif static ivas_error initSbaMasaRendering( @@ -2337,7 +2787,11 @@ static ivas_error initSbaMasaRendering( { ivas_error error; +#ifdef SPLIT_REND_WITH_HEAD_ROT + ivas_rend_closeCrend( &inputSba->crendWrapper, inputSba->base.ctx.pSplitRendWrapper->multiBinPoseData.num_poses ); +#else ivas_rend_closeCrend( &inputSba->crendWrapper ); +#endif if ( ( error = ivas_dirac_ana_open( &inputSba->hDirAC, inSampleRate ) ) != IVAS_ERR_OK ) { @@ -2358,6 +2812,9 @@ static ivas_error setRendInputActiveSba( rendering_context rendCtx; AUDIO_CONFIG outConfig; input_sba *inputSba; +#ifdef SPLIT_REND_WITH_HEAD_ROT + int16_t pos_idx; +#endif inputSba = (input_sba *) input; rendCtx = inputSba->base.ctx; @@ -2368,18 +2825,34 @@ static ivas_error setRendInputActiveSba( return IVAS_ERR_IO_CONFIG_PAIR_NOT_SUPPORTED; } +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( error = allocateInputBaseBufferData( &inputSba->bufferData, MAX_CLDFB_BUFFER_LENGTH ) ) != IVAS_ERR_OK ) +#else if ( ( error = allocateInputBaseBufferData( &inputSba->bufferData, MAX_BUFFER_LENGTH ) ) != IVAS_ERR_OK ) +#endif { return error; } +#ifdef SPLIT_REND_WITH_HEAD_ROT + initRendInputBase( &inputSba->base, inConfig, id, rendCtx, inputSba->bufferData, MAX_CLDFB_BUFFER_LENGTH ); +#else initRendInputBase( &inputSba->base, inConfig, id, rendCtx, inputSba->bufferData, MAX_BUFFER_LENGTH ); +#endif setZeroPanMatrix( inputSba->hoaDecMtx ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + inputSba->crendWrapper = NULL; + for ( pos_idx = 0; pos_idx < MAX_HEAD_ROT_POSES; pos_idx++ ) + { + initRotGains( inputSba->rot_gains_prev[pos_idx] ); + } +#else inputSba->crendWrapper = NULL; inputSba->hDirAC = NULL; initRotGains( inputSba->rot_gains_prev ); +#endif if ( outConfig == IVAS_AUDIO_CONFIG_MASA1 || outConfig == IVAS_AUDIO_CONFIG_MASA2 ) { @@ -2398,21 +2871,60 @@ static ivas_error setRendInputActiveSba( } - - -static void clearInputSba( - input_sba *inputSba ) +#ifdef SPLIT_REND_WITH_HEAD_ROT +static void clearInputSplitRend( + input_split_post_rend *inputSplitRend ) { rendering_context rendCtx; - rendCtx = inputSba->base.ctx; + rendCtx = inputSplitRend->base.ctx; - freeInputBaseBufferData( &inputSba->bufferData ); + freeInputBaseBufferData( &inputSplitRend->bufferData ); - initRendInputBase( &inputSba->base, IVAS_AUDIO_CONFIG_INVALID, 0, rendCtx, NULL, 0 ); + initRendInputBase( &inputSplitRend->base, IVAS_AUDIO_CONFIG_INVALID, 0, rendCtx, NULL, 0 ); - /* Free input's internal handles */ - ivas_rend_closeCrend( &inputSba->crendWrapper ); + if ( inputSplitRend->splitPostRendWrapper.hBinHrSplitPostRend != NULL ) + { + ivas_splitBinPostRendClose( &inputSplitRend->splitPostRendWrapper.hBinHrSplitPostRend ); + } + + if ( inputSplitRend->splitPostRendWrapper.hSplitBinLCLDDec != NULL ) + { + ivas_splitBinLCLDDecClose( &inputSplitRend->splitPostRendWrapper.hSplitBinLCLDDec ); + } + + if ( inputSplitRend->splitPostRendWrapper.hLc3plusDec != NULL ) + { + IVAS_LC3PLUS_DEC_Close( &inputSplitRend->splitPostRendWrapper.hLc3plusDec ); + } + + return; +} +#endif /* SPLIT_REND_WITH_HEAD_ROT */ + + +static void clearInputSba( + input_sba *inputSba ) +{ + rendering_context rendCtx; + + rendCtx = inputSba->base.ctx; + + freeInputBaseBufferData( &inputSba->bufferData ); + + initRendInputBase( &inputSba->base, IVAS_AUDIO_CONFIG_INVALID, 0, rendCtx, NULL, 0 ); + + /* Free input's internal handles */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + ivas_rend_closeCrend( &inputSba->crendWrapper, rendCtx.pSplitRendWrapper->multiBinPoseData.num_poses ); + + if ( inputSba->cldfbRendWrapper.hCldfbRend != NULL ) + { + ivas_rend_closeCldfbRend( &inputSba->cldfbRendWrapper ); + } +#else + ivas_rend_closeCrend( &inputSba->crendWrapper ); +#endif ivas_dirac_ana_close( &( inputSba->hDirAC ) ); @@ -2493,6 +3005,61 @@ static void clearInputMasa( } +#ifdef SPLIT_REND_WITH_HEAD_ROT +static ivas_error initSplitRend( + SPLIT_REND_WRAPPER *pSplitRendWrapper, + IVAS_REND_AudioBuffer *pSplitRendEncBuffer, + const IVAS_SPLIT_REND_CONFIG_DATA *pSplit_rend_config, + IVAS_REND_HeadRotData headRotData, + const int32_t outputSampleRate, + const AUDIO_CONFIG outConfig, + const int16_t cldfb_in_flag, + const int16_t is_5ms_frame ) +{ + ivas_error error; + IVAS_REND_AudioBufferConfig bufConfig; + + if ( outConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || outConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { + if ( pSplit_rend_config->poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) + { + ivas_renderSplitGetMultiBinPoseData( pSplit_rend_config, &pSplitRendWrapper->multiBinPoseData, headRotData.sr_pose_pred_axis ); + } + else if ( pSplit_rend_config->poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) + { + ivas_renderSplitUpdateNoCorrectionPoseData( pSplit_rend_config, &pSplitRendWrapper->multiBinPoseData ); + } + + if ( ( error = ivas_split_renderer_open( pSplitRendWrapper, pSplit_rend_config, outputSampleRate, cldfb_in_flag, outConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM, is_5ms_frame ) ) != IVAS_ERR_OK ) + { + return error; + } + + /*allocate for CLDFB in and change to TD during process if needed*/ + bufConfig.numSamplesPerChannel = MAX_CLDFB_BUFFER_LENGTH_PER_CHANNEL; + bufConfig.numChannels = BINAURAL_CHANNELS * pSplitRendWrapper->multiBinPoseData.num_poses; + bufConfig.is_cldfb = 1; + pSplitRendEncBuffer->config = bufConfig; + + if ( ( pSplitRendEncBuffer->data = malloc( bufConfig.numChannels * bufConfig.numSamplesPerChannel * sizeof( float ) ) ) == NULL ) + { + return IVAS_ERR_FAILED_ALLOC; + } + } + else + { + IVAS_REND_AudioBufferConfig bufConfig2; + + bufConfig2.numSamplesPerChannel = 0; + bufConfig2.numChannels = 0; + bufConfig2.is_cldfb = 0; + pSplitRendEncBuffer->config = bufConfig2; + pSplitRendEncBuffer->data = NULL; + } + + return IVAS_ERR_OK; +} +#endif /*------------------------------------------------------------------------- @@ -2510,6 +3077,9 @@ ivas_error IVAS_REND_Open( const int16_t num_subframes ) { int16_t i; +#ifdef SPLIT_REND_WITH_HEAD_ROT + int16_t j; +#endif IVAS_REND_HANDLE hIvasRend; ivas_error error; int16_t numOutChannels; @@ -2543,6 +3113,9 @@ ivas_error IVAS_REND_Open( hIvasRend->hLimiter = NULL; hIvasRend->efapOutWrapper.hEfap = NULL; hIvasRend->efapOutWrapper.pCustomLsSetup = NULL; +#ifdef DEBUGGING + hIvasRend->numClipping = 0; +#endif hIvasRend->num_subframes = num_subframes; /* Initialize limiter */ @@ -2569,7 +3142,11 @@ ivas_error IVAS_REND_Open( } /* Initilize combined orientation data */ +#ifdef NONBE_UNIFIED_DECODING_PATHS if ( ( error = ivas_combined_orientation_open( &( hIvasRend->hCombinedOrientationData ), outputSampleRate, num_subframes ) ) != IVAS_ERR_OK ) +#else + if ( ( error = ivas_combined_orientation_open( &( hIvasRend->hCombinedOrientationData ), num_subframes ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -2581,6 +3158,10 @@ ivas_error IVAS_REND_Open( } /* Initialize inputs */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + ivas_init_split_rend_handles( &hIvasRend->splitRendWrapper ); + hIvasRend->splitRendEncBuffer.data = NULL; +#endif for ( i = 0; i < RENDERER_MAX_ISM_INPUTS; ++i ) { @@ -2589,6 +3170,13 @@ ivas_error IVAS_REND_Open( hIvasRend->inputsIsm[i].crendWrapper = NULL; hIvasRend->inputsIsm[i].hReverb = NULL; hIvasRend->inputsIsm[i].tdRendWrapper.hBinRendererTd = NULL; +#ifdef SPLIT_REND_WITH_HEAD_ROT + for ( j = 0; j < (int16_t) ( sizeof( hIvasRend->inputsIsm[i].splitTdRendWrappers ) / sizeof( *hIvasRend->inputsIsm[i].splitTdRendWrappers ) ); ++j ) + { + hIvasRend->inputsIsm[i].splitTdRendWrappers[j].hBinRendererTd = NULL; + hIvasRend->inputsIsm[i].splitTdRendWrappers[j].hHrtfTD = NULL; + } +#endif hIvasRend->inputsIsm[i].bufferData = NULL; hIvasRend->inputsIsm[i].nonDiegeticPan = nonDiegeticPan; hIvasRend->inputsIsm[i].nonDiegeticPanGain = nonDiegeticPanGain; @@ -2608,6 +3196,13 @@ ivas_error IVAS_REND_Open( hIvasRend->inputsMc[i].nonDiegeticPan = nonDiegeticPan; hIvasRend->inputsMc[i].nonDiegeticPanGain = nonDiegeticPanGain; hIvasRend->inputsMc[i].hMcMasa = NULL; +#ifdef SPLIT_REND_WITH_HEAD_ROT + for ( j = 0; j < (int16_t) ( sizeof( hIvasRend->inputsMc[i].splitTdRendWrappers ) / sizeof( *hIvasRend->inputsMc[i].splitTdRendWrappers ) ); ++j ) + { + hIvasRend->inputsMc[i].splitTdRendWrappers[j].hBinRendererTd = NULL; + hIvasRend->inputsMc[i].splitTdRendWrappers[j].hHrtfTD = NULL; + } +#endif } for ( i = 0; i < RENDERER_MAX_SBA_INPUTS; ++i ) @@ -2615,6 +3210,10 @@ ivas_error IVAS_REND_Open( initRendInputBase( &hIvasRend->inputsSba[i].base, IVAS_AUDIO_CONFIG_INVALID, 0, getRendCtx( hIvasRend ), NULL, 0 ); hIvasRend->inputsSba[i].crendWrapper = NULL; +#ifdef SPLIT_REND_WITH_HEAD_ROT + hIvasRend->inputsSba[i].cldfbRendWrapper.hCldfbRend = NULL; + hIvasRend->inputsSba[i].cldfbRendWrapper.hHrtfFastConv = NULL; +#endif hIvasRend->inputsSba[i].bufferData = NULL; hIvasRend->inputsSba[i].hDirAC = NULL; } @@ -2629,6 +3228,19 @@ ivas_error IVAS_REND_Open( hIvasRend->inputsMasa[i].hMasaExtRend = NULL; } +#ifdef SPLIT_REND_WITH_HEAD_ROT + for ( i = 0; i < RENDERER_MAX_BIN_INPUTS; ++i ) + { + initRendInputBase( &hIvasRend->inputsSplitPost[i].base, IVAS_AUDIO_CONFIG_INVALID, 0, getRendCtx( hIvasRend ), NULL, 0 ); + + ivas_init_split_post_rend_handles( &hIvasRend->inputsSplitPost[i].splitPostRendWrapper ); + +#ifdef SPLIT_REND_WITH_HEAD_ROT + hIvasRend->splitRendBFI = 0; +#endif + hIvasRend->inputsSplitPost[i].bufferData = NULL; + } +#endif return IVAS_ERR_OK; } @@ -2879,6 +3491,15 @@ static ivas_error getInputById( } pInputBase = &hIvasRend->inputsMasa[inputIndex].base; break; +#ifdef SPLIT_REND_WITH_HEAD_ROT + case IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL: + if ( inputIndex > RENDERER_MAX_BIN_INPUTS ) + { + return IVAS_ERR_INVALID_INPUT_ID; + } + pInputBase = &hIvasRend->inputsSplitPost[inputIndex].base; + break; +#endif default: return IVAS_ERR_INVALID_INPUT_ID; } @@ -2944,6 +3565,15 @@ static ivas_error getConstInputById( } pInputBase = &hIvasRend->inputsMasa[inputIndex].base; break; +#ifdef SPLIT_REND_WITH_HEAD_ROT + case IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL: + if ( inputIndex > RENDERER_MAX_BIN_INPUTS ) + { + return IVAS_ERR_INVALID_INPUT_ID; + } + pInputBase = &hIvasRend->inputsSplitPost[inputIndex].base; + break; +#endif default: return IVAS_ERR_INVALID_INPUT_ID; } @@ -3003,6 +3633,67 @@ static ivas_error findFreeInputSlot( } +#ifdef SPLIT_REND_WITH_HEAD_ROT +static int16_t getCldfbRendFlag( + IVAS_REND_HANDLE hIvasRend, /* i : Renderer handle */ + const IVAS_REND_AudioConfigType new_configType ) +{ + int16_t i; + int16_t numMasaInputs = 0, numSbaInputs = 0, numIsmInputs = 0, numMcInputs = 0; + int16_t isCldfbRend; + + isCldfbRend = 0; + if ( hIvasRend->hRendererConfig != NULL ) + { + for ( i = 0; i < RENDERER_MAX_MASA_INPUTS; ++i ) + { + numMasaInputs += ( hIvasRend->inputsMasa[i].base.inConfig == IVAS_AUDIO_CONFIG_INVALID && new_configType != IVAS_REND_AUDIO_CONFIG_TYPE_MASA ) ? 0 : 1; + } + for ( i = 0; i < RENDERER_MAX_SBA_INPUTS; ++i ) + { + numSbaInputs += ( hIvasRend->inputsSba[i].base.inConfig == IVAS_AUDIO_CONFIG_INVALID && new_configType != IVAS_REND_AUDIO_CONFIG_TYPE_AMBISONICS ) ? 0 : 1; + } + for ( i = 0; i < RENDERER_MAX_ISM_INPUTS; ++i ) + { + numIsmInputs += ( hIvasRend->inputsIsm[i].base.inConfig == IVAS_AUDIO_CONFIG_INVALID && new_configType != IVAS_REND_AUDIO_CONFIG_TYPE_OBJECT_BASED ) ? 0 : 1; + } + for ( i = 0; i < RENDERER_MAX_MC_INPUTS; ++i ) + { + numMcInputs += ( hIvasRend->inputsMc[i].base.inConfig == IVAS_AUDIO_CONFIG_INVALID && new_configType != IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED ) ? 0 : 1; + } + + if ( numIsmInputs > 0 || numMcInputs > 0 ) + { + isCldfbRend = 0; + } + else if ( ( numMasaInputs > 0 ) || ( numSbaInputs > 0 && hIvasRend->hRendererConfig->split_rend_config.rendererSelection == IVAS_SPLIT_REND_RENDERER_SELECTION_FASTCONV ) ) + { + isCldfbRend = 1; + } + } + + return isCldfbRend; +} + + +static void closeSplitRend( + SPLIT_REND_WRAPPER *pSplitRendWrapper, + IVAS_REND_AudioBuffer *pSplitRendEncBuffer ) +{ + ivas_split_renderer_close( pSplitRendWrapper ); + + if ( pSplitRendEncBuffer->data != NULL ) + { + free( pSplitRendEncBuffer->data ); + pSplitRendEncBuffer->data = NULL; + } + + pSplitRendEncBuffer->config.numChannels = 0; + pSplitRendEncBuffer->config.numSamplesPerChannel = 0; + + return; +} +#endif /*-------------------------------------------------------------------* @@ -3030,6 +3721,23 @@ ivas_error IVAS_REND_AddInput( return IVAS_ERR_UNEXPECTED_NULL_POINTER; } +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( hIvasRend->outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || hIvasRend->outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) && hIvasRend->splitRendEncBuffer.data == NULL && hIvasRend->hRendererConfig != NULL ) + { + int16_t cldfb_in_flag; + cldfb_in_flag = getCldfbRendFlag( hIvasRend, getAudioConfigType( inConfig ) ); + + if ( ( error = ivas_split_rend_choose_default_codec( &hIvasRend->hRendererConfig->split_rend_config.codec, &hIvasRend->hRendererConfig->split_rend_config.codec_frame_size_ms, cldfb_in_flag, hIvasRend->outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( ( error = initSplitRend( &hIvasRend->splitRendWrapper, &hIvasRend->splitRendEncBuffer, &hIvasRend->hRendererConfig->split_rend_config, hIvasRend->headRotData, hIvasRend->sampleRateOut, hIvasRend->outputConfig, cldfb_in_flag, ( hIvasRend->num_subframes == 1 ) ? 1 : 0 ) ) != IVAS_ERR_OK ) + { + return error; + } + } +#endif switch ( getAudioConfigType( inConfig ) ) { @@ -3057,6 +3765,14 @@ ivas_error IVAS_REND_AddInput( inputStructSize = sizeof( *hIvasRend->inputsMasa ); activateInput = setRendInputActiveMasa; break; +#ifdef SPLIT_REND_WITH_HEAD_ROT + case IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL: + maxNumInputsOfType = RENDERER_MAX_BIN_INPUTS; + inputsArray = hIvasRend->inputsSplitPost; + inputStructSize = sizeof( *hIvasRend->inputsSplitPost ); + activateInput = setRendInputActiveSplitPostRend; + break; +#endif default: return IVAS_ERR_INVALID_INPUT_FORMAT; } @@ -3128,7 +3844,11 @@ ivas_error IVAS_REND_ConfigureCustomInputLoudspeakerLayout( return error; } +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( getAudioConfigType( hIvasRend->outputConfig ) == IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL ) +#else if ( hIvasRend->outputConfig == IVAS_AUDIO_CONFIG_BINAURAL || hIvasRend->outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR || hIvasRend->outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) +#endif { if ( ( error = initMcBinauralRendering( inputMc, inputMc->base.inConfig, hIvasRend->outputConfig, hIvasRend->hRendererConfig, FALSE ) ) != IVAS_ERR_OK ) { @@ -3316,6 +4036,11 @@ ivas_error IVAS_REND_RemoveInput( case IVAS_REND_AUDIO_CONFIG_TYPE_MASA: clearInputMasa( (input_masa *) inputBase ); break; +#ifdef SPLIT_REND_WITH_HEAD_ROT + case IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL: + clearInputSplitRend( (input_split_post_rend *) inputBase ); + break; +#endif default: return IVAS_ERR_INVALID_INPUT_FORMAT; } @@ -3438,6 +4163,27 @@ ivas_error IVAS_REND_GetDelay( { if ( hIvasRend->inputsSba[i].base.inConfig != IVAS_AUDIO_CONFIG_INVALID ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( hIvasRend->splitRendWrapper.hBinHrSplitPreRend != NULL ) + { + if ( hIvasRend->hRendererConfig->split_rend_config.rendererSelection == IVAS_SPLIT_REND_RENDERER_SELECTION_FASTCONV ) + { + latency_ns = hIvasRend->inputsSba[i].cldfbRendWrapper.binaural_latency_ns; + } + else + { + latency_ns = ( hIvasRend->inputsSba[i].crendWrapper != NULL ) ? hIvasRend->inputsSba[i].crendWrapper->binaural_latency_ns : 0; + } + max_latency_ns = max( max_latency_ns, latency_ns ); + } + else if ( hIvasRend->inputsSba[i].cldfbRendWrapper.hCldfbRend != NULL ) + { + latency_ns = hIvasRend->inputsSba[i].cldfbRendWrapper.binaural_latency_ns; + latency_ns += IVAS_FB_DEC_DELAY_NS; + max_latency_ns = max( max_latency_ns, latency_ns ); + } + else +#endif { latency_ns = ( hIvasRend->inputsSba[i].crendWrapper != NULL ) ? hIvasRend->inputsSba[i].crendWrapper->binaural_latency_ns : 0; max_latency_ns = max( max_latency_ns, latency_ns ); @@ -3445,6 +4191,26 @@ ivas_error IVAS_REND_GetDelay( } } +#ifdef SPLIT_REND_WITH_HEAD_ROT + 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; + IVAS_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 == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) + { + latency_ns += IVAS_FB_DEC_DELAY_NS; + } + max_latency_ns = max( max_latency_ns, latency_ns ); + } + } +#endif for ( i = 0; i < RENDERER_MAX_MASA_INPUTS; i++ ) { @@ -3476,6 +4242,9 @@ ivas_error IVAS_REND_FeedInputAudio( ivas_error error; input_base *inputBase; int16_t numInputChannels; +#ifdef SPLIT_REND_WITH_HEAD_ROT + int16_t cldfb2tdSampleFact; +#endif /* Validate function arguments */ if ( hIvasRend == NULL || inputAudio.data == NULL ) @@ -3483,7 +4252,14 @@ ivas_error IVAS_REND_FeedInputAudio( return IVAS_ERR_UNEXPECTED_NULL_POINTER; } +#ifdef SPLIT_REND_WITH_HEAD_ROT + 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 ) ) +#else if ( inputAudio.config.numSamplesPerChannel <= 0 || MAX_BUFFER_LENGTH_PER_CHANNEL < inputAudio.config.numSamplesPerChannel ) +#endif { return IVAS_ERROR( IVAS_ERR_INVALID_BUFFER_SIZE, "Buffer size outside of supported range" ); } @@ -3493,8 +4269,15 @@ ivas_error IVAS_REND_FeedInputAudio( return IVAS_ERR_WRONG_NUM_CHANNELS; } +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( getAudioConfigType( hIvasRend->outputConfig ) == IVAS_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 ) +#else if ( getAudioConfigType( hIvasRend->outputConfig ) == IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL && inputAudio.config.numSamplesPerChannel * 1000 != ( BINAURAL_RENDERING_FRAME_SIZE_MS * hIvasRend->num_subframes ) * hIvasRend->sampleRateOut ) +#endif { return IVAS_ERROR( IVAS_ERR_INVALID_BUFFER_SIZE, "Binaural rendering requires specific frame size" ); } @@ -3523,7 +4306,11 @@ ivas_error IVAS_REND_FeedInputAudio( mvr2r( inputAudio.data, inputBase->inputBuffer.data, inputAudio.config.numSamplesPerChannel * inputAudio.config.numChannels ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + inputBase->numNewSamplesPerChannel = inputAudio.config.numSamplesPerChannel / cldfb2tdSampleFact; +#else inputBase->numNewSamplesPerChannel = inputAudio.config.numSamplesPerChannel; +#endif return IVAS_ERR_OK; } @@ -3701,6 +4488,20 @@ int16_t IVAS_REND_GetRenderConfig( } hRCin = hIvasRend->hRendererConfig; +#ifdef DEBUGGING + switch ( hRCin->renderer_type_override ) + { + case IVAS_RENDER_TYPE_OVERRIDE_CREND: + hRCout->renderer_type_override = IVAS_RENDER_TYPE_OVERRIDE_CREND; + break; + case IVAS_RENDER_TYPE_OVERRIDE_FASTCONV: + hRCout->renderer_type_override = IVAS_RENDER_TYPE_OVERRIDE_FASTCONV; + break; + default: + hRCout->renderer_type_override = IVAS_RENDER_TYPE_OVERRIDE_NONE; + break; + } +#endif hRCout->roomAcoustics.override = hRCin->roomAcoustics.override; hRCout->roomAcoustics.nBands = hRCin->roomAcoustics.nBands; hRCout->roomAcoustics.acousticPreDelay = hRCin->roomAcoustics.acousticPreDelay; @@ -3711,6 +4512,16 @@ int16_t IVAS_REND_GetRenderConfig( mvr2r( hRCin->roomAcoustics.pAcoustic_rt60, hRCout->roomAcoustics.pAcoustic_rt60, CLDFB_NO_CHANNELS_MAX ); mvr2r( hRCin->roomAcoustics.pAcoustic_dsr, hRCout->roomAcoustics.pAcoustic_dsr, CLDFB_NO_CHANNELS_MAX ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + hRCout->split_rend_config.splitRendBitRate = SPLIT_REND_768k; + hRCout->split_rend_config.dof = 3; + hRCout->split_rend_config.hq_mode = 0; + hRCout->split_rend_config.codec_delay_ms = 0; + hRCout->split_rend_config.codec_frame_size_ms = 0; /* 0 means "use default for selected codec" */ + hRCout->split_rend_config.codec = IVAS_SPLIT_REND_CODEC_DEFAULT; + hRCout->split_rend_config.poseCorrectionMode = IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB; + hRCout->split_rend_config.rendererSelection = hRCin->split_rend_config.rendererSelection; +#endif hRCout->roomAcoustics.use_er = hRCin->roomAcoustics.use_er; hRCout->roomAcoustics.lowComplexity = hRCin->roomAcoustics.lowComplexity; @@ -3731,12 +4542,18 @@ int16_t IVAS_REND_FeedRenderConfig( ) { RENDER_CONFIG_HANDLE hRenderConfig; +#ifdef SPLIT_REND_WITH_HEAD_ROT + ivas_error error; +#endif if ( hIvasRend == NULL || hIvasRend->hRendererConfig == NULL ) { return IVAS_ERR_UNEXPECTED_NULL_POINTER; } hRenderConfig = hIvasRend->hRendererConfig; +#ifdef DEBUGGING + hRenderConfig->renderer_type_override = renderConfig.renderer_type_override; +#endif hRenderConfig->roomAcoustics.override = renderConfig.roomAcoustics.override; hRenderConfig->roomAcoustics.nBands = renderConfig.roomAcoustics.nBands; @@ -3758,11 +4575,79 @@ int16_t IVAS_REND_FeedRenderConfig( mvr2r( renderConfig.roomAcoustics.AbsCoeff, hRenderConfig->roomAcoustics.AbsCoeff, IVAS_ROOM_ABS_COEFF ); } +#ifdef SPLIT_REND_WITH_HEAD_ROT + hRenderConfig->split_rend_config = renderConfig.split_rend_config; + /* Overwrite any pose correction settings if 0 DOF (no pose correction) was selected */ + if ( hRenderConfig->split_rend_config.dof == 0 ) + { + hRenderConfig->split_rend_config.poseCorrectionMode = IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE; + } + + hRenderConfig->split_rend_config.codec = renderConfig.split_rend_config.codec; + + if ( ( error = ivas_split_rend_validate_config( &hRenderConfig->split_rend_config, ( hIvasRend->outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0 ) ) != IVAS_ERR_OK ) + { + return error; + } + + /* Must re-initialize split rendering config in case renderer config is updated after adding renderer inputs */ + /* if its not initialized yet then no need to re-initialize, initialization will happen while adding inputs*/ + if ( hIvasRend->splitRendEncBuffer.data != NULL && hIvasRend->hRendererConfig != NULL ) + { + int16_t cldfb_in_flag; + cldfb_in_flag = getCldfbRendFlag( hIvasRend, IVAS_REND_AUDIO_CONFIG_TYPE_UNKNOWN ); + closeSplitRend( &hIvasRend->splitRendWrapper, &hIvasRend->splitRendEncBuffer ); + + if ( ( error = ivas_split_rend_choose_default_codec( &hIvasRend->hRendererConfig->split_rend_config.codec, &hIvasRend->hRendererConfig->split_rend_config.codec_frame_size_ms, cldfb_in_flag, hIvasRend->outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( ( error = initSplitRend( &hIvasRend->splitRendWrapper, &hIvasRend->splitRendEncBuffer, &hIvasRend->hRendererConfig->split_rend_config, hIvasRend->headRotData, hIvasRend->sampleRateOut, hIvasRend->outputConfig, cldfb_in_flag, ( hIvasRend->num_subframes == 1 ) ? 1 : 0 ) ) != IVAS_ERR_OK ) + { + return error; + } + } +#endif return IVAS_ERR_OK; } +#ifdef SPLIT_REND_WITH_HEAD_ROT +/*-------------------------------------------------------------------* + * IVAS_REND_FeedSplitBinauralBitstream() + * + * + *-------------------------------------------------------------------*/ + +ivas_error IVAS_REND_FeedSplitBinauralBitstream( + IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + const IVAS_REND_InputId inputId, /* i : ID of the input */ + IVAS_REND_BitstreamBuffer *hBits /* i : buffer for input bitstream */ +) +{ + ivas_error error; + input_base *inputBase; + input_split_post_rend *inputSplitPostRend; + + /* Validate function arguments */ + if ( hIvasRend == NULL || hBits == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + if ( ( error = getInputById( hIvasRend, inputId, (void **) &inputBase ) ) != IVAS_ERR_OK ) + { + return error; + } + + inputSplitPostRend = (input_split_post_rend *) inputBase; + inputSplitPostRend->hBits = hBits; + + return IVAS_ERR_OK; +} +#endif /*-------------------------------------------------------------------* @@ -3775,6 +4660,9 @@ ivas_error IVAS_REND_SetHeadRotation( IVAS_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 */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + const IVAS_SPLIT_REND_ROT_AXIS rot_axis, /* i : external control for rotation axis for split rendering */ +#endif const int16_t sf_idx /* i : subframe index */ ) { @@ -3825,6 +4713,9 @@ ivas_error IVAS_REND_SetHeadRotation( hIvasRend->headRotData.Pos[sf_idx] = Pos; +#ifdef SPLIT_REND_WITH_HEAD_ROT + hIvasRend->headRotData.sr_pose_pred_axis = rot_axis; +#endif return IVAS_ERR_OK; } @@ -3871,6 +4762,22 @@ ivas_error IVAS_REND_DisableHeadRotation( } +#ifdef SPLIT_REND_WITH_HEAD_ROT +/*-------------------------------------------------------------------* + * IVAS_REND_SetSplitRendBFI() + * + * + *-------------------------------------------------------------------*/ + +ivas_error IVAS_REND_SetSplitRendBFI( + IVAS_REND_HANDLE hIvasRend, + const int16_t bfi ) +{ + hIvasRend->splitRendBFI = bfi; + + return IVAS_ERR_OK; +} +#endif /*-------------------------------------------------------------------* @@ -4472,9 +5379,25 @@ static int16_t getNumSubframesInBuffer( const IVAS_REND_AudioBuffer *buffer, const int32_t sampleRate ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + int16_t cldfb2tdSampleFact; + + cldfb2tdSampleFact = buffer->config.is_cldfb ? 2 : 1; +#endif +#ifdef DEBUGGING +#ifdef SPLIT_REND_WITH_HEAD_ROT + assert( buffer->config.numSamplesPerChannel % ( sampleRate / FRAMES_PER_SEC / MAX_PARAM_SPATIAL_SUBFRAMES * cldfb2tdSampleFact ) == 0 ); +#else + assert( buffer->config.numSamplesPerChannel % ( sampleRate / FRAMES_PER_SEC / MAX_PARAM_SPATIAL_SUBFRAMES ) == 0 ); +#endif +#endif +#ifdef SPLIT_REND_WITH_HEAD_ROT + return (int16_t) ( buffer->config.numSamplesPerChannel / ( sampleRate / FRAMES_PER_SEC / MAX_PARAM_SPATIAL_SUBFRAMES * cldfb2tdSampleFact ) ); +#else return (int16_t) ( buffer->config.numSamplesPerChannel / ( sampleRate / FRAMES_PER_SEC / MAX_PARAM_SPATIAL_SUBFRAMES ) ); +#endif } @@ -4624,10 +5547,16 @@ static ivas_error renderIsmToBinauralRoom( /* render 7_1_4 with BRIRs */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( error = ivas_rend_crendProcess( ismInput->crendWrapper, IVAS_AUDIO_CONFIG_7_1_4, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR, + NULL, NULL, NULL, NULL, p_tmpRendBuffer, *ismInput->base.ctx.pOutSampleRate, + getNumSubframesInBuffer( &outAudio, *ismInput->base.ctx.pOutSampleRate ), 0 ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_rend_crendProcess( ismInput->crendWrapper, IVAS_AUDIO_CONFIG_7_1_4, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR, NULL, NULL, NULL, NULL, p_tmpRendBuffer, *ismInput->base.ctx.pOutSampleRate, getNumSubframesInBuffer( &outAudio, *ismInput->base.ctx.pOutSampleRate ) ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -4808,19 +5737,120 @@ static ivas_error renderIsmToSba( } - - -static void renderIsmToMasa( +#ifdef SPLIT_REND_WITH_HEAD_ROT +static ivas_error renderIsmToSplitBinaural( input_ism *ismInput, - IVAS_REND_AudioBuffer outAudio ) + const IVAS_REND_AudioBuffer outAudio ) { - float tmpRendBuffer[MAX_NUM_OBJECTS][L_FRAME48k]; + ivas_error error; + float tmpProcessing[MAX_NUM_OBJECTS][L_FRAME48k]; + int16_t pos_idx; + const MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData; + const SPLIT_REND_WRAPPER *pSplitRendWrapper; + IVAS_QUATERNION originalHeadRot[MAX_PARAM_SPATIAL_SUBFRAMES]; + int16_t i; + float tmpBinaural[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][L_FRAME48k]; + int16_t output_frame = ismInput->base.inputBuffer.config.numSamplesPerChannel; + COMBINED_ORIENTATION_HANDLE pCombinedOrientationData; + int16_t ism_md_subframe_update_ext; - push_wmops( "renderIsmToMasa" ); + push_wmops( "renderIsmToSplitBinaural" ); - copyBufferTo2dArray( ismInput->base.inputBuffer, tmpRendBuffer ); + pSplitRendWrapper = ismInput->base.ctx.pSplitRendWrapper; + pMultiBinPoseData = &pSplitRendWrapper->multiBinPoseData; - ivas_omasa_ana( ismInput->hOMasa, tmpRendBuffer, ismInput->base.inputBuffer.config.numSamplesPerChannel, outAudio.config.numChannels, ismInput->base.inputBuffer.config.numChannels ); + /* Metadata Delay to sync with audio delay converted from ms to 5ms (1000/50/4) subframe index */ + ism_md_subframe_update_ext = (int16_t) roundf( ismInput->ism_metadata_delay_ms / ( 1000 / FRAMES_PER_SEC / MAX_PARAM_SPATIAL_SUBFRAMES ) ); + + pCombinedOrientationData = *ismInput->base.ctx.pCombinedOrientationData; + + if ( pMultiBinPoseData->poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) + { + for ( i = 1; i < pCombinedOrientationData->num_subframes; ++i ) + { + pCombinedOrientationData->Quaternions[i] = pCombinedOrientationData->Quaternions[0]; + } + } + + /* Save current head positions */ + for ( i = 0; i < pCombinedOrientationData->num_subframes; ++i ) + { + originalHeadRot[i] = pCombinedOrientationData->Quaternions[i]; + } + + /* Copy input audio to a processing buffer. */ + copyBufferTo2dArray( ismInput->base.inputBuffer, tmpProcessing ); + + for ( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses; pos_idx++ ) + { + /* Update head positions */ + if ( pos_idx != 0 ) + { + for ( i = 0; i < pCombinedOrientationData->num_subframes; ++i ) + { + if ( originalHeadRot[i].w == -3.0f ) + { + pCombinedOrientationData->Quaternions[i].w = -3.0f; + pCombinedOrientationData->Quaternions[i].x = originalHeadRot[i].x + pMultiBinPoseData->relative_head_poses[pos_idx][0]; + pCombinedOrientationData->Quaternions[i].y = originalHeadRot[i].y + pMultiBinPoseData->relative_head_poses[pos_idx][1]; + pCombinedOrientationData->Quaternions[i].z = originalHeadRot[i].z + pMultiBinPoseData->relative_head_poses[pos_idx][2]; + } + else + { + pCombinedOrientationData->Quaternions[i].w = -3.0f; + Quat2EulerDegree( originalHeadRot[i], + &pCombinedOrientationData->Quaternions[i].z, + &pCombinedOrientationData->Quaternions[i].y, + &pCombinedOrientationData->Quaternions[i].x ); + pCombinedOrientationData->Quaternions[i].x += pMultiBinPoseData->relative_head_poses[pos_idx][0]; + pCombinedOrientationData->Quaternions[i].y += pMultiBinPoseData->relative_head_poses[pos_idx][1]; + pCombinedOrientationData->Quaternions[i].z += pMultiBinPoseData->relative_head_poses[pos_idx][2]; + } + } + } + + /* Render */ + if ( ( error = ivas_td_binaural_renderer_ext( ( pos_idx == 0 ) ? &ismInput->tdRendWrapper : &ismInput->splitTdRendWrappers[pos_idx - 1], ismInput->base.inConfig, NULL, ismInput->base.ctx.pCombinedOrientationData, &ismInput->currentPos, + NULL, ism_md_subframe_update_ext, *ismInput->base.ctx.pOutSampleRate, output_frame, tmpProcessing ) ) != IVAS_ERR_OK ) + { + return error; + } + + /* Copy rendered audio to tmp storage buffer. Copying directly to output would + * overwrite original audio, which is still needed for rendering next head pose. */ + mvr2r( tmpProcessing[0], tmpBinaural[2 * pos_idx], output_frame ); + mvr2r( tmpProcessing[1], tmpBinaural[2 * pos_idx + 1], output_frame ); + + /* Overwrite processing buffer with original input audio again */ + copyBufferTo2dArray( ismInput->base.inputBuffer, tmpProcessing ); + } + + /* Restore original head rotation */ + for ( i = 0; i < pCombinedOrientationData->num_subframes; ++i ) + { + pCombinedOrientationData->Quaternions[i] = originalHeadRot[i]; + } + + accumulate2dArrayToBuffer( tmpBinaural, &outAudio ); + pop_wmops(); + + /* Encoding to split rendering bitstream done at a higher level */ + return IVAS_ERR_OK; +} +#endif + + +static void renderIsmToMasa( + input_ism *ismInput, + IVAS_REND_AudioBuffer outAudio ) +{ + float tmpRendBuffer[MAX_NUM_OBJECTS][L_FRAME48k]; + + push_wmops( "renderIsmToMasa" ); + + copyBufferTo2dArray( ismInput->base.inputBuffer, tmpRendBuffer ); + + ivas_omasa_ana( ismInput->hOMasa, tmpRendBuffer, ismInput->base.inputBuffer.config.numSamplesPerChannel, outAudio.config.numChannels, ismInput->base.inputBuffer.config.numChannels ); accumulate2dArrayToBuffer( tmpRendBuffer, &outAudio ); @@ -4850,8 +5880,10 @@ static ivas_error renderInputIsm( /* Apply input gain to new audio */ v_multc( inAudio.data, ismInput->base.gain, inAudio.data, inAudio.config.numSamplesPerChannel * inAudio.config.numChannels ); +#ifdef NONBE_UNIFIED_DECODING_PATHS /* set combined orientation subframe info to start info */ ivas_combined_orientation_set_to_start_index( *ismInput->base.ctx.pCombinedOrientationData ); +#endif switch ( getAudioConfigType( outConfig ) ) { @@ -4870,6 +5902,12 @@ static ivas_error renderInputIsm( case IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR: error = renderIsmToBinauralRoom( ismInput, outAudio ); break; +#ifdef SPLIT_REND_WITH_HEAD_ROT + case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED: + case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM: + error = renderIsmToSplitBinaural( ismInput, outAudio ); + break; +#endif case IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB: error = renderIsmToBinauralReverb( ismInput, outAudio ); break; @@ -4924,9 +5962,15 @@ static ivas_error renderActiveInputsIsm( static ivas_error renderLfeToBinaural( const input_mc *mcInput, +#ifdef SPLIT_REND_WITH_HEAD_ROT + const AUDIO_CONFIG outConfig, +#endif IVAS_REND_AudioBuffer outAudio ) { int16_t lfe_idx; +#ifdef SPLIT_REND_WITH_HEAD_ROT + int16_t pose_idx, num_poses; +#endif float gain; int16_t ear_idx; float tmpLfeBuffer[MAX_BUFFER_LENGTH_PER_CHANNEL]; @@ -4934,7 +5978,11 @@ static ivas_error renderLfeToBinaural( const float *lfeInput; float *writePtr; +#ifdef SPLIT_REND_WITH_HEAD_ROT + assert( ( getAudioConfigType( outConfig ) == IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL ) && "Must be binaural output" ); +#else assert( ( outAudio.config.numChannels == 2 ) && "Must be binaural output" ); +#endif push_wmops( "renderLfeToBinaural" ); @@ -4972,12 +6020,33 @@ static ivas_error renderLfeToBinaural( /* Save remaining LFE samples of current frame for next frame */ mvr2r( lfeInput + num_cpy_smpl_cur_frame, mcInput->lfeDelayBuffer, num_cpy_smpl_prev_frame ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + /* Copy LFE to left and right binaural channels for all poses */ + if ( mcInput->base.ctx.pSplitRendWrapper != NULL ) + { + num_poses = mcInput->base.ctx.pSplitRendWrapper->multiBinPoseData.num_poses; + } + else + { + num_poses = 1; + } + + for ( pose_idx = 0; pose_idx < num_poses; ++pose_idx ) + { + for ( ear_idx = 0; ear_idx < BINAURAL_CHANNELS; ++ear_idx ) + { + writePtr = getSmplPtr( outAudio, pose_idx * BINAURAL_CHANNELS + ear_idx, 0 ); + v_add( writePtr, tmpLfeBuffer, writePtr, frame_size ); + } + } +#else /* SPLIT_REND_WITH_HEAD_ROT */ /* Copy LFE to left and right ears */ for ( ear_idx = 0; ear_idx < BINAURAL_CHANNELS; ++ear_idx ) { writePtr = getSmplPtr( outAudio, ear_idx, 0 ); v_add( writePtr, tmpLfeBuffer, writePtr, frame_size ); } +#endif /* SPLIT_REND_WITH_HEAD_ROT */ pop_wmops(); @@ -5041,7 +6110,11 @@ static ivas_error renderMcToBinaural( tmpRotBuffer.data = malloc( tmpRotBuffer.config.numSamplesPerChannel * tmpRotBuffer.config.numChannels * sizeof( float ) ); set_zero( tmpRotBuffer.data, tmpRotBuffer.config.numSamplesPerChannel * tmpRotBuffer.config.numChannels ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( error = rotateFrameMc( mcInput->base.inputBuffer, mcInput->base.inConfig, &mcInput->customLsInput, mcInput->base.ctx.pHeadRotData, mcInput->base.ctx.pCombinedOrientationData, mcInput->rot_gains_prev[0], mcInput->efapInWrapper.hEfap, tmpRotBuffer ) ) != IVAS_ERR_OK ) +#else if ( ( error = rotateFrameMc( mcInput->base.inputBuffer, mcInput->base.inConfig, &mcInput->customLsInput, mcInput->base.ctx.pHeadRotData, mcInput->base.ctx.pCombinedOrientationData, mcInput->rot_gains_prev, mcInput->efapInWrapper.hEfap, tmpRotBuffer ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -5055,8 +6128,13 @@ static ivas_error renderMcToBinaural( } /* call CREND */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( error = ivas_rend_crendProcess( mcInput->crendWrapper, mcInput->base.inConfig, outConfig, NULL, NULL, NULL, NULL, p_tmpRendBuffer, *mcInput->base.ctx.pOutSampleRate, + getNumSubframesInBuffer( &outAudio, *mcInput->base.ctx.pOutSampleRate ), 0 ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_rend_crendProcess( mcInput->crendWrapper, mcInput->base.inConfig, outConfig, NULL, NULL, NULL, NULL, p_tmpRendBuffer, *mcInput->base.ctx.pOutSampleRate, getNumSubframesInBuffer( &outAudio, *mcInput->base.ctx.pOutSampleRate ) ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -5064,7 +6142,11 @@ static ivas_error renderMcToBinaural( accumulate2dArrayToBuffer( tmpRendBuffer, &outAudio ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( error = renderLfeToBinaural( mcInput, outConfig, outAudio ) ) != IVAS_ERR_OK ) +#else if ( ( error = renderLfeToBinaural( mcInput, outAudio ) ) != IVAS_ERR_OK ) +#endif { return error; @@ -5132,7 +6214,11 @@ static ivas_error renderMcToBinauralRoom( set_zero( tmpRotBuffer.data, tmpRotBuffer.config.numSamplesPerChannel * tmpRotBuffer.config.numChannels ); if ( ( error = rotateFrameMc( mcInput->base.inputBuffer, mcInput->base.inConfig, &mcInput->customLsInput, mcInput->base.ctx.pHeadRotData, mcInput->base.ctx.pCombinedOrientationData, +#ifdef SPLIT_REND_WITH_HEAD_ROT + mcInput->rot_gains_prev[0], +#else mcInput->rot_gains_prev, +#endif mcInput->efapInWrapper.hEfap, tmpRotBuffer ) ) != IVAS_ERR_OK ) { return error; @@ -5147,8 +6233,13 @@ static ivas_error renderMcToBinauralRoom( } /* call CREND */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( error = ivas_rend_crendProcess( mcInput->crendWrapper, mcInput->base.inConfig, outConfig, NULL, NULL, NULL, NULL, p_tmpRendBuffer, *mcInput->base.ctx.pOutSampleRate, + getNumSubframesInBuffer( &outAudio, *mcInput->base.ctx.pOutSampleRate ), 0 ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_rend_crendProcess( mcInput->crendWrapper, mcInput->base.inConfig, outConfig, NULL, NULL, NULL, NULL, p_tmpRendBuffer, *mcInput->base.ctx.pOutSampleRate, getNumSubframesInBuffer( &outAudio, *mcInput->base.ctx.pOutSampleRate ) ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -5156,7 +6247,11 @@ static ivas_error renderMcToBinauralRoom( accumulate2dArrayToBuffer( tmpRendBuffer, &outAudio ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( error = renderLfeToBinaural( mcInput, outConfig, outAudio ) ) != IVAS_ERR_OK ) +#else if ( ( error = renderLfeToBinaural( mcInput, outAudio ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -5213,7 +6308,11 @@ static ivas_error renderMcCustomLsToBinauralRoom( set_zero( tmpRotBuffer.data, tmpRotBuffer.config.numSamplesPerChannel * tmpRotBuffer.config.numChannels ); if ( ( error = rotateFrameMc( mcInput->base.inputBuffer, mcInput->base.inConfig, &mcInput->customLsInput, mcInput->base.ctx.pHeadRotData, mcInput->base.ctx.pCombinedOrientationData, +#ifdef SPLIT_REND_WITH_HEAD_ROT + mcInput->rot_gains_prev[0], +#else mcInput->rot_gains_prev, +#endif mcInput->efapInWrapper.hEfap, tmpRotBuffer ) ) != IVAS_ERR_OK ) { return error; @@ -5240,15 +6339,24 @@ static ivas_error renderMcCustomLsToBinauralRoom( copyBufferTo2dArray( tmpMcBuffer, tmpCrendBuffer ); /* call CREND */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( error = ivas_rend_crendProcess( mcInput->crendWrapper, IVAS_AUDIO_CONFIG_7_1_4, outConfig, NULL, NULL, NULL, NULL, + p_tmpCrendBuffer, *mcInput->base.ctx.pOutSampleRate, getNumSubframesInBuffer( &outAudio, *mcInput->base.ctx.pOutSampleRate ), 0 ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_rend_crendProcess( mcInput->crendWrapper, IVAS_AUDIO_CONFIG_7_1_4, outConfig, NULL, NULL, NULL, NULL, p_tmpCrendBuffer, *mcInput->base.ctx.pOutSampleRate, getNumSubframesInBuffer( &outAudio, *mcInput->base.ctx.pOutSampleRate ) ) ) != IVAS_ERR_OK ) +#endif { return error; } accumulate2dArrayToBuffer( tmpCrendBuffer, &outAudio ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( error = renderLfeToBinaural( mcInput, outConfig, outAudio ) ) != IVAS_ERR_OK ) +#else if ( ( error = renderLfeToBinaural( mcInput, outAudio ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -5322,6 +6430,164 @@ static void renderMcToMasa( } +#ifdef SPLIT_REND_WITH_HEAD_ROT +static ivas_error renderMcToSplitBinaural( + input_mc *mcInput, + const AUDIO_CONFIG outConfig, + IVAS_REND_AudioBuffer outAudio ) +{ + int16_t i, j, pos_idx; + int16_t sf; + int16_t output_frame; + ivas_error error; + const MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData; + const SPLIT_REND_WRAPPER *pSplitRendWrapper; + float tmpRendBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; + float *p_tmpRendBuffer[MAX_OUTPUT_CHANNELS]; + float tmpSplitBinauralBuffer[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][L_FRAME48k]; + AUDIO_CONFIG inConfig; + IVAS_REND_AudioBuffer tmpRotBuffer; + COMBINED_ORIENTATION_DATA combinedOrientationDataLocal; + COMBINED_ORIENTATION_HANDLE pCombinedOrientationDataLocal; + + push_wmops( "renderMcToSplitBinaural" ); + inConfig = mcInput->base.inConfig; + output_frame = mcInput->base.inputBuffer.config.numSamplesPerChannel; + + pSplitRendWrapper = mcInput->base.ctx.pSplitRendWrapper; + pMultiBinPoseData = &pSplitRendWrapper->multiBinPoseData; + + for ( i = 0; i < MAX_OUTPUT_CHANNELS; ++i ) + { + p_tmpRendBuffer[i] = tmpRendBuffer[i]; + } + + /* save current head positions */ + pCombinedOrientationDataLocal = *mcInput->base.ctx.pCombinedOrientationData; + combinedOrientationDataLocal = *pCombinedOrientationDataLocal; + if ( pMultiBinPoseData->poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) + { + for ( sf = 1; sf < combinedOrientationDataLocal.num_subframes; ++sf ) + { + combinedOrientationDataLocal.Quaternions[sf] = combinedOrientationDataLocal.Quaternions[0]; + for ( i = 0; i < 3; i++ ) + { + for ( j = 0; j < 3; j++ ) + { + combinedOrientationDataLocal.Rmat[sf][i][j] = combinedOrientationDataLocal.Rmat[0][i][j]; + } + } + } + } + + /* temporary buffer for rotation in source format for CREND */ + tmpRotBuffer = mcInput->base.inputBuffer; + if ( inConfig != IVAS_AUDIO_CONFIG_LS_CUSTOM && inConfig != IVAS_AUDIO_CONFIG_5_1 && inConfig != IVAS_AUDIO_CONFIG_7_1 ) + { + tmpRotBuffer.data = malloc( tmpRotBuffer.config.numSamplesPerChannel * tmpRotBuffer.config.numChannels * sizeof( float ) ); + } + + for ( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses; pos_idx++ ) + { + /* Update head positions */ + IVAS_QUATERNION Quaternions_orig[MAX_PARAM_SPATIAL_SUBFRAMES], Quaternions_abs; + for ( i = 0; i < combinedOrientationDataLocal.num_subframes; i++ ) + { + Quaternions_orig[i] = combinedOrientationDataLocal.Quaternions[i]; + Quaternions_abs.w = -3.0f; + Quat2EulerDegree( combinedOrientationDataLocal.Quaternions[i], &Quaternions_abs.z, &Quaternions_abs.y, &Quaternions_abs.x ); /*order in Quat2Euler seems to be reversed ?*/ + + Quaternions_abs.x += pMultiBinPoseData->relative_head_poses[pos_idx][0]; + Quaternions_abs.y += pMultiBinPoseData->relative_head_poses[pos_idx][1]; + Quaternions_abs.z += pMultiBinPoseData->relative_head_poses[pos_idx][2]; + combinedOrientationDataLocal.Quaternions[i] = Quaternions_abs; + QuatToRotMat( combinedOrientationDataLocal.Quaternions[i], combinedOrientationDataLocal.Rmat[i] ); + } + + if ( inConfig == IVAS_AUDIO_CONFIG_LS_CUSTOM || inConfig == IVAS_AUDIO_CONFIG_5_1 || inConfig == IVAS_AUDIO_CONFIG_7_1 ) + { + /* tdrend processing overview: + * 1. copy from inputBuffer to tmpRendBuffer + * 2. td_binaural_renderer_ext: inplace processing in tmpRendBuffer + * 3. copy from tmpRendBuffer to tmpSplitBinBuffer + * 4. LFE mixing + * 5. tmpSplitBinBuffer accumulated to outBuffer */ + + /* copy input to tdrend input/output buffer */ + copyBufferTo2dArray( mcInput->base.inputBuffer, tmpRendBuffer ); + + /* perform rotation in source format to tmpRotBuffer */ + pCombinedOrientationDataLocal = &combinedOrientationDataLocal; + + /* Render */ + if ( ( error = ivas_td_binaural_renderer_ext( ( pos_idx == 0 ) ? &mcInput->tdRendWrapper : &mcInput->splitTdRendWrappers[pos_idx - 1], mcInput->base.inConfig, &mcInput->customLsInput, &pCombinedOrientationDataLocal, NULL, mcInput->hReverb, 0, /* Ism Audio Metadata Delay Sync in ms for External Renderer */ *mcInput->base.ctx.pOutSampleRate, mcInput->base.inputBuffer.config.numSamplesPerChannel, tmpRendBuffer ) ) != IVAS_ERR_OK ) + { + return error; + } + + /* Copy rendered audio to tmp storage buffer. Copying directly to output would + * overwrite original audio, which is still needed for rendering next head pose. */ + mvr2r( tmpRendBuffer[0], tmpSplitBinauralBuffer[2 * pos_idx], output_frame ); + mvr2r( tmpRendBuffer[1], tmpSplitBinauralBuffer[2 * pos_idx + 1], output_frame ); + } + else + { + /* crend processing overview: + * 1. rotateFrameMc: inputBuffer to tmpRotBuffer + * 2. crend_process: tmpRotBuffer to tmpRendBuffer + * 3. copy from tmpRendBuffer to tmpSplitBinBuffer + * 4. LFE mixing + * 5. tmpSplitBinBuffer accumulated to outBuffer */ + + + /* copy input for in-place rotation */ + mvr2r( mcInput->base.inputBuffer.data, tmpRotBuffer.data, tmpRotBuffer.config.numChannels * tmpRotBuffer.config.numSamplesPerChannel ); + + /* perform rotation in source format to tmpRotBuffer */ + pCombinedOrientationDataLocal = &combinedOrientationDataLocal; + if ( ( error = rotateFrameMc( mcInput->base.inputBuffer, mcInput->base.inConfig, &mcInput->customLsInput, mcInput->base.ctx.pHeadRotData, &pCombinedOrientationDataLocal, mcInput->rot_gains_prev[pos_idx], mcInput->efapInWrapper.hEfap, tmpRotBuffer ) ) != IVAS_ERR_OK ) + { + return error; + } + + copyBufferTo2dArray( tmpRotBuffer, tmpRendBuffer ); + + /* call CREND (rotation already performed) */ + if ( ( error = ivas_rend_crendProcess( mcInput->crendWrapper, mcInput->base.inConfig, outConfig, NULL, NULL, NULL, NULL, p_tmpRendBuffer, *mcInput->base.ctx.pOutSampleRate, getNumSubframesInBuffer( &mcInput->base.inputBuffer, *mcInput->base.ctx.pOutSampleRate ), pos_idx ) ) != IVAS_ERR_OK ) + { + return error; + } + + /* Copy rendererd audio to tmp storage buffer, Copying directly to output would + * overwrite original audio, which is still needed for rendering next head pose. */ + mvr2r( tmpRendBuffer[0], tmpSplitBinauralBuffer[2 * pos_idx], output_frame ); + mvr2r( tmpRendBuffer[1], tmpSplitBinauralBuffer[2 * pos_idx + 1], output_frame ); + } + + /* restore original headrotation data */ + for ( i = 0; i < combinedOrientationDataLocal.num_subframes; i++ ) + { + combinedOrientationDataLocal.Quaternions[i] = Quaternions_orig[i]; + } + } + + if ( inConfig != IVAS_AUDIO_CONFIG_LS_CUSTOM && inConfig != IVAS_AUDIO_CONFIG_5_1 && inConfig != IVAS_AUDIO_CONFIG_7_1 ) + { + /* free temporary buffer for rotation in source format for CREND */ + free( tmpRotBuffer.data ); + } + + if ( ( error = renderLfeToBinaural( mcInput, outConfig, outAudio ) ) != IVAS_ERR_OK ) + { + return error; + } + + accumulate2dArrayToBuffer( tmpSplitBinauralBuffer, &outAudio ); + + pop_wmops(); + return IVAS_ERR_OK; +} +#endif static ivas_error renderInputMc( @@ -5345,8 +6611,10 @@ static ivas_error renderInputMc( /* Apply input gain to new audio */ v_multc( inAudio.data, mcInput->base.gain, inAudio.data, inAudio.config.numSamplesPerChannel * inAudio.config.numChannels ); +#ifdef NONBE_UNIFIED_DECODING_PATHS /* set combined orientation subframe info to start info */ ivas_combined_orientation_set_to_start_index( *( mcInput->base.ctx.pCombinedOrientationData ) ); +#endif switch ( getAudioConfigType( outConfig ) ) { @@ -5373,6 +6641,12 @@ static ivas_error renderInputMc( error = renderMcToBinauralRoom( mcInput, outConfig, outAudio ); } break; +#ifdef SPLIT_REND_WITH_HEAD_ROT + case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED: + case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM: + error = renderMcToSplitBinaural( mcInput, outConfig, outAudio ); + break; +#endif default: return IVAS_ERR_INVALID_OUTPUT_FORMAT; } @@ -5453,6 +6727,462 @@ static void renderSbaToSba( return; } +#ifdef SPLIT_REND_WITH_HEAD_ROT +static ivas_error splitBinLc3plusDecode( + SPLIT_POST_REND_WRAPPER *hSplitBin, + IVAS_SPLIT_REND_BITS_HANDLE bits, + float outputBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k], + IVAS_SPLIT_REND_POSE_CORRECTION_MODE pose_correction ) +{ + ivas_error error; + float *channel_ptrs[MAX_HEAD_ROT_POSES * 2]; + int32_t lc3plusBitrateId, lc3plusBitstreamSize; + + push_wmops( "splitBinLc3plusDecode" ); + assert( hSplitBin->hLc3plusDec != NULL ); + + /* Find next byte boundary */ + while ( bits->bits_read % 8 != 0 ) + { + ++bits->bits_read; + } + /* Read LC3plus bitstream size info */ + lc3plusBitrateId = ivas_split_rend_bitstream_read_int32( bits, 8 ); + lc3plusBitstreamSize = ivas_get_lc3plus_size_from_id( (int8_t) lc3plusBitrateId, pose_correction, (int16_t) ( hSplitBin->hLc3plusDec->config.ivas_frame_duration_us / 1000 ) ); + + for ( int16_t i = 0; i < BINAURAL_CHANNELS * hSplitBin->multiBinPoseData.num_poses; ++i ) + { + channel_ptrs[i] = outputBuffer[i]; + } + + if ( ( error = IVAS_LC3PLUS_DEC_Decode( hSplitBin->hLc3plusDec, &bits->bits_buf[bits->bits_read / 8], lc3plusBitstreamSize, channel_ptrs ) ) != IVAS_ERR_OK ) + { + return error; + } + + pop_wmops(); + return IVAS_ERR_OK; +} + + +static ivas_error renderSplitBinauralWithPostRot( + input_split_post_rend *splitBinInput, + IVAS_REND_AudioBuffer outAudio, + const int16_t SplitRendBFI ) +{ + 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]; + 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]; + IVAS_QUATERNION QuaternionsPost[MAX_PARAM_SPATIAL_SUBFRAMES]; + int16_t sf_idx, ch_idx; + IVAS_SPLIT_REND_BITS_DATA bits; + float tmpCrendBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; + float tmpCrendBuffer_sf[BINAURAL_CHANNELS][L_FRAME48k]; + COMBINED_ORIENTATION_HANDLE pCombinedOrientationData; + 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; + + isPostRendInputCldfb = 0; + push_wmops( "renderSplitBinauralWithPostRot" ); + error = IVAS_ERR_OK; + + pCombinedOrientationData = *splitBinInput->base.ctx.pCombinedOrientationData; + hSplitBin = &splitBinInput->splitPostRendWrapper; + convertBitsBufferToInternalBitsBuff( *splitBinInput->hBits, &bits ); + + if ( bits.codec == IVAS_SPLIT_REND_CODEC_LCLD && splitBinInput->splitPostRendWrapper.hSplitBinLCLDDec == NULL ) + { + if ( ( error = ivas_splitBinLCLDDecOpen( &splitBinInput->splitPostRendWrapper.hSplitBinLCLDDec, *splitBinInput->base.ctx.pOutSampleRate, BINAURAL_CHANNELS ) ) != IVAS_ERR_OK ) + { + return error; + } + } + else if ( bits.codec == IVAS_SPLIT_REND_CODEC_LC3PLUS && splitBinInput->splitPostRendWrapper.hLc3plusDec == NULL ) + { + LC3PLUS_CONFIG config; + + if ( outAudio.config.numSamplesPerChannel == 240 ) + { + config.lc3plus_frame_duration_us = bits.codec_frame_size_ms * 1000; + config.ivas_frame_duration_us = ( bits.pose_correction == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) ? config.lc3plus_frame_duration_us : 20000; + } + else + { + config.lc3plus_frame_duration_us = 5000; + config.ivas_frame_duration_us = 20000; + } + config.channels = BINAURAL_CHANNELS; + config.samplerate = *splitBinInput->base.ctx.pOutSampleRate; + + if ( ( error = IVAS_LC3PLUS_DEC_Open( config, + &splitBinInput->splitPostRendWrapper.hLc3plusDec ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + outBufNumSamplesPerChannel = outAudio.config.numSamplesPerChannel / pCombinedOrientationData->num_subframes; + for ( sf_idx = 0; sf_idx < pCombinedOrientationData->num_subframes; sf_idx++ ) + { + QuaternionsPost[sf_idx] = pCombinedOrientationData->Quaternions[sf_idx]; + } + + + if ( !SplitRendBFI ) + { + hSplitBin->first_good_frame_received = 1; + } + + if ( hSplitBin->first_good_frame_received == 1 ) + { + if ( bits.pose_correction == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) + { + if ( !SplitRendBFI ) + { +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + ivas_splitBinPostRendMdDec( &bits, hSplitBin->hBinHrSplitPostRend, &hSplitBin->multiBinPoseData, hSplitBin->hBinHrSplitPreRend ); +#else + ivas_splitBinPostRendMdDec( &bits, hSplitBin->hBinHrSplitPostRend, &hSplitBin->multiBinPoseData ); +#endif + } + } + + /*copy pose correction after MD is parsed*/ + hSplitBin->multiBinPoseData.poseCorrectionMode = bits.pose_correction; + + /* decode audio */ + if ( splitBinInput->base.inConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) + { + if ( bits.codec == IVAS_SPLIT_REND_CODEC_LCLD ) + { + isPostRendInputCldfb = 1; + } + + preRendFrameSize_ms = bits.codec == IVAS_SPLIT_REND_CODEC_LC3PLUS ? (int16_t) ( hSplitBin->hLc3plusDec->config.ivas_frame_duration_us ) / 1000 : 20; + + numSamplesPerChannelCacheSize = (int16_t) ( *splitBinInput->base.ctx.pOutSampleRate * ( preRendFrameSize_ms - bits.codec_frame_size_ms ) / 1000 ); + + outBufNumColPerChannel = MAX_PARAM_SPATIAL_SUBFRAMES; + numColPerChannelCacheSize = CLDFB_NO_COL_MAX - outBufNumColPerChannel; + + for ( sf_idx = 0; sf_idx < pCombinedOrientationData->num_subframes; sf_idx++ ) + { + if ( splitBinInput->numCachedSamples == 0 ) + { + if ( bits.codec == IVAS_SPLIT_REND_CODEC_LCLD ) + { + ivas_splitBinLCLDDecProcess( hSplitBin->hSplitBinLCLDDec, &bits, Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, SplitRendBFI ); + + /* copy data over to 5ms buffer */ + for ( chnlIdx = 0; chnlIdx < BINAURAL_CHANNELS; ++chnlIdx ) + { + for ( slotIdx = 0; slotIdx < 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 ); + } + } + + /* cache the remaining 15ms */ + splitBinInput->numCachedSamples = numColPerChannelCacheSize; + writePtr = splitBinInput->bufferData; + for ( slotIdx = CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES; slotIdx < CLDFB_NO_COL_MAX; ++slotIdx ) + { + for ( chnlIdx = 0; chnlIdx < BINAURAL_CHANNELS; ++chnlIdx ) + { + for ( smplIdx = 0; smplIdx < CLDFB_NO_CHANNELS_MAX; ++smplIdx ) + { + *writePtr++ = Cldfb_RealBuffer_Binaural[chnlIdx][slotIdx][smplIdx]; + } + for ( smplIdx = 0; smplIdx < CLDFB_NO_CHANNELS_MAX; ++smplIdx ) + { + *writePtr++ = Cldfb_ImagBuffer_Binaural[chnlIdx][slotIdx][smplIdx]; + } + } + } + } + else + { + if ( ( error = splitBinLc3plusDecode( hSplitBin, &bits, tmpCrendBuffer, bits.pose_correction ) ) != IVAS_ERR_OK ) + { + return error; + } + + /* cache the remaining 15ms */ + splitBinInput->numCachedSamples = numSamplesPerChannelCacheSize; + mvr2r( &tmpCrendBuffer[0][outBufNumSamplesPerChannel], splitBinInput->bufferData, numSamplesPerChannelCacheSize ); + mvr2r( &tmpCrendBuffer[1][outBufNumSamplesPerChannel], splitBinInput->bufferData + numSamplesPerChannelCacheSize, numSamplesPerChannelCacheSize ); + } + } + else + { + /* copy from cache */ + if ( bits.codec == IVAS_SPLIT_REND_CODEC_LCLD ) + { + int16_t readOffset = ( numColPerChannelCacheSize - splitBinInput->numCachedSamples ); + readPtr = splitBinInput->bufferData; + isPostRendInputCldfb = 1; + + readPtr += 2 * readOffset * CLDFB_NO_CHANNELS_MAX * BINAURAL_CHANNELS; + for ( slotIdx = 0; slotIdx < CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES; ++slotIdx ) + { + for ( chnlIdx = 0; chnlIdx < BINAURAL_CHANNELS; ++chnlIdx ) + { + for ( smplIdx = 0; smplIdx < CLDFB_NO_CHANNELS_MAX; ++smplIdx ) + { + Cldfb_RealBuffer_Binaural_5ms[sf_idx][chnlIdx][slotIdx][smplIdx] = *readPtr++; + } + for ( smplIdx = 0; smplIdx < CLDFB_NO_CHANNELS_MAX; ++smplIdx ) + { + Cldfb_ImagBuffer_Binaural_5ms[sf_idx][chnlIdx][slotIdx][smplIdx] = *readPtr++; + } + } + } + + splitBinInput->numCachedSamples -= outBufNumColPerChannel; + } + 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 ); + splitBinInput->numCachedSamples -= outBufNumSamplesPerChannel; + } + } + } + } + else + { + copyBufferTo2dArray( splitBinInput->base.inputBuffer, tmpCrendBuffer ); + } + + /* apply pose correction if enabled */ + for ( sf_idx = 0; sf_idx < pCombinedOrientationData->num_subframes; sf_idx++ ) + { + if ( bits.pose_correction == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE && isPostRendInputCldfb ) + { + /* 0DOF with LCLD codec requires CLDFB synthesis */ + int16_t slot_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]; + + 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]; + } + + 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] ); + } + } + else if ( bits.pose_correction == IVAS_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 ); + + ivas_rend_CldfbSplitPostRendProcess( hSplitBin->hBinHrSplitPostRend, &hSplitBin->multiBinPoseData, QuaternionsPost[sf_idx], Cldfb_RealBuffer_Binaural_5ms[sf_idx], Cldfb_ImagBuffer_Binaural_5ms[sf_idx], tmpCrendBuffer_sf, isPostRendInputCldfb ); + + mvr2r( tmpCrendBuffer_sf[0], &tmpCrendBuffer[0][sf_idx * outBufNumSamplesPerChannel], outBufNumSamplesPerChannel ); + mvr2r( tmpCrendBuffer_sf[1], &tmpCrendBuffer[1][sf_idx * outBufNumSamplesPerChannel], outBufNumSamplesPerChannel ); + } + } + } + else + { + if ( splitBinInput->base.inConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) + { + for ( ch_idx = 0; ch_idx < BINAURAL_CHANNELS; ch_idx++ ) + { + set_zero( tmpCrendBuffer[ch_idx], outAudio.config.numSamplesPerChannel ); + } + } + else + { + copyBufferTo2dArray( splitBinInput->base.inputBuffer, tmpCrendBuffer ); + } + } + + convertInternalBitsBuffToBitsBuffer( splitBinInput->hBits, bits ); + accumulate2dArrayToBuffer( tmpCrendBuffer, &outAudio ); + + pop_wmops(); + return error; +} + + +static ivas_error renderSbaToMultiBinaural( + input_sba *sbaInput, + const AUDIO_CONFIG outConfig, + float out[][L_FRAME48k] ) +{ + float tmpCrendBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; + float *p_tmpCrendBuffer[MAX_OUTPUT_CHANNELS]; + int16_t sf; + int16_t i, j, pos_idx; + COMBINED_ORIENTATION_DATA combinedOrientationDataLocal; + COMBINED_ORIENTATION_HANDLE pCombinedOrientationDataLocal; + ivas_error error; + IVAS_REND_AudioBuffer tmpRotBuffer; + const MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData; + + for ( i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) + { + p_tmpCrendBuffer[i] = tmpCrendBuffer[i]; + } + push_wmops( "renderSbaToMultiBinaural" ); + pMultiBinPoseData = &sbaInput->base.ctx.pSplitRendWrapper->multiBinPoseData; + + pCombinedOrientationDataLocal = *sbaInput->base.ctx.pCombinedOrientationData; + combinedOrientationDataLocal = *pCombinedOrientationDataLocal; + if ( pMultiBinPoseData->poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) + { + for ( sf = 1; sf < combinedOrientationDataLocal.num_subframes; sf++ ) + { + combinedOrientationDataLocal.Quaternions[sf] = combinedOrientationDataLocal.Quaternions[0]; + for ( i = 0; i < 3; i++ ) + { + for ( j = 0; j < 3; j++ ) + { + combinedOrientationDataLocal.Rmat[sf][i][j] = combinedOrientationDataLocal.Rmat[0][i][j]; + } + } + } + } + + tmpRotBuffer = sbaInput->base.inputBuffer; + tmpRotBuffer.data = malloc( tmpRotBuffer.config.numSamplesPerChannel * tmpRotBuffer.config.numChannels * sizeof( float ) ); + + for ( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses; pos_idx++ ) + { + IVAS_QUATERNION Quaternions_orig[MAX_PARAM_SPATIAL_SUBFRAMES], Quaternions_abs; + for ( i = 0; i < combinedOrientationDataLocal.num_subframes; i++ ) + { + Quaternions_orig[i] = combinedOrientationDataLocal.Quaternions[i]; + Quaternions_abs.w = -3.0f; + Quat2EulerDegree( combinedOrientationDataLocal.Quaternions[i], &Quaternions_abs.z, &Quaternions_abs.y, &Quaternions_abs.x ); /*order in Quat2Euler seems to be reversed ?*/ + + Quaternions_abs.x += pMultiBinPoseData->relative_head_poses[pos_idx][0]; + Quaternions_abs.y += pMultiBinPoseData->relative_head_poses[pos_idx][1]; + Quaternions_abs.z += pMultiBinPoseData->relative_head_poses[pos_idx][2]; + combinedOrientationDataLocal.Quaternions[i] = Quaternions_abs; + QuatToRotMat( combinedOrientationDataLocal.Quaternions[i], combinedOrientationDataLocal.Rmat[i] ); + } + + + /* copy input for in-place rotation */ + mvr2r( sbaInput->base.inputBuffer.data, tmpRotBuffer.data, tmpRotBuffer.config.numChannels * tmpRotBuffer.config.numSamplesPerChannel ); + + pCombinedOrientationDataLocal = &combinedOrientationDataLocal; + + if ( ( error = rotateFrameSba( sbaInput->base.inputBuffer, sbaInput->base.inConfig, sbaInput->base.ctx.pHeadRotData, &pCombinedOrientationDataLocal, sbaInput->rot_gains_prev[pos_idx], tmpRotBuffer ) ) != IVAS_ERR_OK ) + { + return error; + } + + copyBufferTo2dArray( tmpRotBuffer, tmpCrendBuffer ); + + assert( sbaInput->crendWrapper->hCrend[0]->hReverb == NULL ); + + /* call CREND */ + if ( ( error = ivas_rend_crendProcess( sbaInput->crendWrapper, sbaInput->base.inConfig, outConfig, NULL, NULL, NULL, NULL, p_tmpCrendBuffer, *sbaInput->base.ctx.pOutSampleRate, + getNumSubframesInBuffer( &sbaInput->base.inputBuffer, *sbaInput->base.ctx.pOutSampleRate ), pos_idx ) ) != IVAS_ERR_OK ) + { + return error; + } + + for ( i = 0; i < combinedOrientationDataLocal.num_subframes; i++ ) + { + combinedOrientationDataLocal.Quaternions[i] = Quaternions_orig[i]; + } + + + /* move to output */ + for ( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + mvr2r( tmpCrendBuffer[i], out[pos_idx * BINAURAL_CHANNELS + i], tmpRotBuffer.config.numSamplesPerChannel ); + } + } + + free( tmpRotBuffer.data ); + + pop_wmops(); + return IVAS_ERR_OK; +} + + +static ivas_error renderSbaToMultiBinauralCldfb( + input_sba *sbaInput, + 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 low_res_pre_rend_rot, + const int16_t num_subframes ) +{ + float Cldfb_RealBuffer[MAX_OUTPUT_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + float Cldfb_ImagBuffer[MAX_OUTPUT_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + + copyBufferToCLDFBarray( sbaInput->base.inputBuffer, Cldfb_RealBuffer, Cldfb_ImagBuffer ); + + ivas_rend_CldfbMultiBinRendProcess( sbaInput->cldfbRendWrapper.hCldfbRend, sbaInput->base.ctx.pCombinedOrientationData, &sbaInput->base.ctx.pSplitRendWrapper->multiBinPoseData, + Cldfb_RealBuffer, Cldfb_ImagBuffer, Cldfb_Out_Real, Cldfb_Out_Imag, low_res_pre_rend_rot, num_subframes ); + + return IVAS_ERR_OK; +} + + +static ivas_error renderSbaToSplitBinaural( + input_sba *sbaInput, + const AUDIO_CONFIG outConfig, + IVAS_REND_AudioBuffer outAudio ) +{ + float tmpCrendBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; + ivas_error error; + 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]; + int16_t low_res_pre_rend_rot; + + low_res_pre_rend_rot = 1; + + push_wmops( "renderSbaToSplitBinaural" ); + error = IVAS_ERR_OK; + + if ( sbaInput->base.ctx.hhRendererConfig[0]->split_rend_config.rendererSelection == IVAS_SPLIT_REND_RENDERER_SELECTION_FASTCONV ) + { + if ( ( renderSbaToMultiBinauralCldfb( sbaInput, Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, low_res_pre_rend_rot, + getNumSubframesInBuffer( &outAudio, *sbaInput->base.ctx.pOutSampleRate ) ) ) != IVAS_ERR_OK ) + { + return error; + } + + accumulateCLDFBArrayToBuffer( Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, &outAudio ); + } + else + { + if ( ( renderSbaToMultiBinaural( sbaInput, outConfig, tmpCrendBuffer ) ) != IVAS_ERR_OK ) + { + return error; + } + + accumulate2dArrayToBuffer( tmpCrendBuffer, &outAudio ); + } + + pop_wmops(); + return error; +} +#endif static ivas_error renderSbaToBinaural( @@ -5470,6 +7200,22 @@ static ivas_error renderSbaToBinaural( int16_t subframe_idx; push_wmops( "renderSbaToBinaural" ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( sbaInput->base.ctx.hhRendererConfig[0]->split_rend_config.rendererSelection == IVAS_SPLIT_REND_RENDERER_SELECTION_FASTCONV ) + { + 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]; + + if ( ( error = renderSbaToMultiBinauralCldfb( sbaInput, Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, 0, + getNumSubframesInBuffer( &outAudio, *sbaInput->base.ctx.pOutSampleRate ) ) ) != IVAS_ERR_OK ) + { + return error; + } + + accumulateCLDFBArrayToBuffer( Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, &outAudio ); + } + else +#endif { for ( i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) { @@ -5499,8 +7245,13 @@ static ivas_error renderSbaToBinaural( /* copy input for in-place rotation */ mvr2r( sbaInput->base.inputBuffer.data, tmpRotBuffer.data, tmpRotBuffer.config.numChannels * tmpRotBuffer.config.numSamplesPerChannel ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( error = rotateFrameSba( sbaInput->base.inputBuffer, sbaInput->base.inConfig, sbaInput->base.ctx.pHeadRotData, + sbaInput->base.ctx.pCombinedOrientationData, sbaInput->rot_gains_prev[0], tmpRotBuffer ) ) != IVAS_ERR_OK ) +#else if ( ( error = rotateFrameSba( sbaInput->base.inputBuffer, sbaInput->base.inConfig, sbaInput->base.ctx.pHeadRotData, sbaInput->base.ctx.pCombinedOrientationData, sbaInput->rot_gains_prev, tmpRotBuffer ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -5514,8 +7265,13 @@ static ivas_error renderSbaToBinaural( } /* call CREND */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( error = ivas_rend_crendProcess( sbaInput->crendWrapper, sbaInput->base.inConfig, outConfig, NULL, NULL, NULL, NULL, p_tmpCrendBuffer, *sbaInput->base.ctx.pOutSampleRate, + getNumSubframesInBuffer( &outAudio, *sbaInput->base.ctx.pOutSampleRate ), 0 ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_rend_crendProcess( sbaInput->crendWrapper, sbaInput->base.inConfig, outConfig, NULL, NULL, NULL, NULL, p_tmpCrendBuffer, *sbaInput->base.ctx.pOutSampleRate, getNumSubframesInBuffer( &outAudio, *sbaInput->base.ctx.pOutSampleRate ) ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -5578,7 +7334,11 @@ static ivas_error renderSbaToBinauralRoom( if ( ( error = rotateFrameSba( sbaInput->base.inputBuffer, sbaInput->base.inConfig, sbaInput->base.ctx.pHeadRotData, sbaInput->base.ctx.pCombinedOrientationData, +#ifdef SPLIT_REND_WITH_HEAD_ROT + sbaInput->rot_gains_prev[0], +#else sbaInput->rot_gains_prev, +#endif tmpRotBuffer ) ) != IVAS_ERR_OK ) { return error; @@ -5608,24 +7368,59 @@ static ivas_error renderSbaToBinauralRoom( /* call CREND */ if ( ( error = ivas_rend_crendProcess( sbaInput->crendWrapper, IVAS_AUDIO_CONFIG_7_1_4, outConfig, NULL, NULL, NULL, NULL, p_tmpCrendBuffer, *sbaInput->base.ctx.pOutSampleRate, +#ifdef SPLIT_REND_WITH_HEAD_ROT + getNumSubframesInBuffer( &outAudio, *sbaInput->base.ctx.pOutSampleRate ), 0 ) ) != IVAS_ERR_OK ) +#else getNumSubframesInBuffer( &outAudio, *sbaInput->base.ctx.pOutSampleRate ) ) ) != IVAS_ERR_OK ) +#endif { return error; } - accumulate2dArrayToBuffer( tmpCrendBuffer, &outAudio ); + accumulate2dArrayToBuffer( tmpCrendBuffer, &outAudio ); + + if ( combinedOrientationEnabled ) + { + free( tmpRotBuffer.data ); + } + free( tmpMcBuffer.data ); + + pop_wmops(); + return IVAS_ERR_OK; +} + + +#ifdef SPLIT_REND_WITH_HEAD_ROT +static ivas_error renderInputSplitBin( + input_split_post_rend *splitBinInput, + const AUDIO_CONFIG outConfig, + IVAS_REND_AudioBuffer outAudio, + const int16_t SplitRendBFI ) +{ + ivas_error error; + IVAS_REND_AudioBuffer inAudio; + + inAudio = splitBinInput->base.inputBuffer; + + splitBinInput->base.numNewSamplesPerChannel = 0; - if ( combinedOrientationEnabled ) + /* Apply input gain to new audio */ + v_multc( inAudio.data, + splitBinInput->base.gain, + inAudio.data, + inAudio.config.numSamplesPerChannel * inAudio.config.numChannels ); /* TODO: the output buffer is empty at this point, should be moved to a point after decoding the split bitstream */ + switch ( outConfig ) { - free( tmpRotBuffer.data ); + case IVAS_AUDIO_CONFIG_BINAURAL: + error = renderSplitBinauralWithPostRot( splitBinInput, outAudio, SplitRendBFI ); + break; + default: + return IVAS_ERR_INVALID_OUTPUT_FORMAT; } - free( tmpMcBuffer.data ); - pop_wmops(); - return IVAS_ERR_OK; + return error; } - - +#endif static void renderSbaToMasa( @@ -5651,11 +7446,20 @@ static ivas_error renderInputSba( { ivas_error error; IVAS_REND_AudioBuffer inAudio; +#ifdef SPLIT_REND_WITH_HEAD_ROT + int16_t cldfb2tdSampleFact; +#endif error = IVAS_ERR_OK; inAudio = sbaInput->base.inputBuffer; +#ifdef SPLIT_REND_WITH_HEAD_ROT + cldfb2tdSampleFact = outAudio.config.is_cldfb ? 2 : 1; + if ( ( sbaInput->base.numNewSamplesPerChannel * cldfb2tdSampleFact != outAudio.config.numSamplesPerChannel ) && + ( outConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) && ( outConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) +#else if ( sbaInput->base.numNewSamplesPerChannel != outAudio.config.numSamplesPerChannel ) +#endif { return IVAS_ERROR( IVAS_ERR_INVALID_BUFFER_SIZE, "Mismatch between the number of input samples vs number of requested output samples - currently not allowed" ); } @@ -5664,8 +7468,10 @@ static ivas_error renderInputSba( /* Apply input gain to new audio */ v_multc( inAudio.data, sbaInput->base.gain, inAudio.data, inAudio.config.numSamplesPerChannel * inAudio.config.numChannels ); +#ifdef NONBE_UNIFIED_DECODING_PATHS /* set combined orientation subframe info to start info */ ivas_combined_orientation_set_to_start_index( *( sbaInput->base.ctx.pCombinedOrientationData ) ); +#endif switch ( getAudioConfigType( outConfig ) ) { @@ -5678,6 +7484,12 @@ static ivas_error renderInputSba( case IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL: switch ( outConfig ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED: + case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM: + error = renderSbaToSplitBinaural( sbaInput, outConfig, outAudio ); + break; +#endif case IVAS_AUDIO_CONFIG_BINAURAL: error = renderSbaToBinaural( sbaInput, outConfig, outAudio ); break; @@ -5700,6 +7512,32 @@ static ivas_error renderInputSba( } +#ifdef SPLIT_REND_WITH_HEAD_ROT +static ivas_error renderActiveInputsSplitBin( + IVAS_REND_HANDLE hIvasRend, + IVAS_REND_AudioBuffer outAudio ) +{ + int16_t i; + input_split_post_rend *pCurrentInput; + ivas_error error; + + for ( i = 0, pCurrentInput = hIvasRend->inputsSplitPost; i < RENDERER_MAX_BIN_INPUTS; ++i, ++pCurrentInput ) + { + if ( pCurrentInput->base.inConfig == IVAS_AUDIO_CONFIG_INVALID ) + { + /* Skip inactive inputs */ + continue; + } + + if ( ( error = renderInputSplitBin( pCurrentInput, hIvasRend->outputConfig, outAudio, hIvasRend->splitRendBFI ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + return IVAS_ERR_OK; +} +#endif static ivas_error renderActiveInputsSba( @@ -5909,6 +7747,11 @@ static ivas_error renderInputMasa( int16_t maxBin; float *tmpBuffer[MAX_OUTPUT_CHANNELS]; float tmpBuffer_buff[MAX_OUTPUT_CHANNELS][L_FRAME48k]; +#ifdef SPLIT_REND_WITH_HEAD_ROT + int16_t cldfb2tdSampleFact; + 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]; +#endif if ( !masaInput->metadataHasBeenFed ) { @@ -5916,7 +7759,13 @@ static ivas_error renderInputMasa( } inAudio = masaInput->base.inputBuffer; +#ifdef SPLIT_REND_WITH_HEAD_ROT + cldfb2tdSampleFact = outAudio.config.is_cldfb ? 2 : 1; + if ( ( masaInput->base.numNewSamplesPerChannel * cldfb2tdSampleFact != outAudio.config.numSamplesPerChannel ) && + ( outConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) && ( outConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) +#else if ( masaInput->base.numNewSamplesPerChannel != outAudio.config.numSamplesPerChannel ) +#endif { return IVAS_ERROR( IVAS_ERR_INVALID_BUFFER_SIZE, "Mismatch between the number of input samples vs number of requested output samples - currently not allowed" ); } @@ -5927,8 +7776,10 @@ static ivas_error renderInputMasa( maxBin = (int16_t) ( *masaInput->base.ctx.pOutSampleRate * INV_CLDFB_BANDWIDTH ); +#ifdef NONBE_UNIFIED_DECODING_PATHS /* set combined orientation subframe info to start info */ ivas_combined_orientation_set_to_start_index( *( masaInput->base.ctx.pCombinedOrientationData ) ); +#endif if ( getAudioConfigType( outConfig ) == IVAS_REND_AUDIO_CONFIG_TYPE_MASA ) { @@ -5948,6 +7799,35 @@ static ivas_error renderInputMasa( num_subframes = (int16_t) ( masaInput->base.inputBuffer.config.numSamplesPerChannel / ( *masaInput->base.ctx.pOutSampleRate / ( IVAS_NUM_FRAMES_PER_SEC * MAX_PARAM_SPATIAL_SUBFRAMES ) ) ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( outConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM || outConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) + { + /* split rendering. use the combined of the first subframe in all subframes */ + int16_t sf, i, j; + COMBINED_ORIENTATION_HANDLE pCombinedOrientationData; + pCombinedOrientationData = *masaInput->base.ctx.pCombinedOrientationData; + for ( sf = 1; sf < pCombinedOrientationData->num_subframes; sf++ ) + { + pCombinedOrientationData->Quaternions[sf] = pCombinedOrientationData->Quaternions[0]; + for ( i = 0; i < 3; i++ ) + { + for ( j = 0; j < 3; j++ ) + { + pCombinedOrientationData->Rmat[sf][i][j] = pCombinedOrientationData->Rmat[0][i][j]; + } + } + } + + copyMasaMetadataToDiracRenderer( &masaInput->masaMetadata, masaInput->hMasaExtRend->hSpatParamRendCom, maxBin ); + + ivas_masa_ext_rend_parambin_render( masaInput->hMasaExtRend, *masaInput->base.ctx.pCombinedOrientationData, tmpBuffer, num_subframes, masaInput->base.ctx.pSplitRendWrapper, Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural ); + + accumulateCLDFBArrayToBuffer( Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, &outAudio ); + } + else + { + /* non-split path */ +#endif switch ( masaInput->hMasaExtRend->renderer_type ) { case RENDERER_DIRAC: @@ -5958,7 +7838,11 @@ static ivas_error renderInputMasa( case RENDERER_BINAURAL_PARAMETRIC: case RENDERER_BINAURAL_PARAMETRIC_ROOM: copyMasaMetadataToDiracRenderer( &masaInput->masaMetadata, masaInput->hMasaExtRend->hSpatParamRendCom, maxBin ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + ivas_masa_ext_rend_parambin_render( masaInput->hMasaExtRend, *masaInput->base.ctx.pCombinedOrientationData, tmpBuffer, num_subframes, NULL, NULL, NULL ); +#else ivas_masa_ext_rend_parambin_render( masaInput->hMasaExtRend, *masaInput->base.ctx.pCombinedOrientationData, tmpBuffer, num_subframes ); +#endif break; case RENDERER_DISABLE: break; /* This happens for 1TC MASA to MONO where we just copy input transport to output */ @@ -5967,6 +7851,9 @@ static ivas_error renderInputMasa( } accumulate2dArrayToBuffer( tmpBuffer_buff, &outAudio ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + } +#endif } return IVAS_ERR_OK; @@ -6177,11 +8064,20 @@ ivas_error IVAS_REND_SetIsmMetadataDelay( static ivas_error getSamplesInternal( IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + IVAS_REND_AudioBuffer outAudio /* i/o: buffer for output audio */, + IVAS_REND_BitstreamBuffer *hBits /*i/o: buffer for input/output bitstream. Needed in split rendering mode*/ +#else IVAS_REND_AudioBuffer outAudio /* i/o: buffer for output audio */ +#endif ) { ivas_error error; int16_t numOutChannels; +#ifdef SPLIT_REND_WITH_HEAD_ROT + int16_t cldfb2tdSampleFact; + IVAS_REND_AudioBuffer outAudioOrig; +#endif /* Validate function arguments */ if ( hIvasRend == NULL || outAudio.data == NULL ) @@ -6189,7 +8085,14 @@ static ivas_error getSamplesInternal( return IVAS_ERR_UNEXPECTED_NULL_POINTER; } +#ifdef SPLIT_REND_WITH_HEAD_ROT + 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 ) ) +#else if ( outAudio.config.numSamplesPerChannel <= 0 || MAX_BUFFER_LENGTH_PER_CHANNEL < outAudio.config.numSamplesPerChannel ) +#endif { return IVAS_ERR_INVALID_BUFFER_SIZE; } @@ -6199,8 +8102,15 @@ static ivas_error getSamplesInternal( return IVAS_ERR_WRONG_NUM_CHANNELS; } +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( getAudioConfigType( hIvasRend->outputConfig ) == IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL && + hIvasRend->outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED && + hIvasRend->outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM && + ( outAudio.config.numSamplesPerChannel * 1000 / cldfb2tdSampleFact ) != ( hIvasRend->num_subframes * BINAURAL_RENDERING_FRAME_SIZE_MS ) * hIvasRend->sampleRateOut ) +#else if ( getAudioConfigType( hIvasRend->outputConfig ) == IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL && outAudio.config.numSamplesPerChannel * 1000 != ( hIvasRend->num_subframes * BINAURAL_RENDERING_FRAME_SIZE_MS ) * hIvasRend->sampleRateOut ) +#endif { return IVAS_ERROR( IVAS_ERR_INVALID_BUFFER_SIZE, "Binaural rendering requires specific frame size" ); } @@ -6241,7 +8151,11 @@ static ivas_error getSamplesInternal( return error; } +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( numOutChannels != outAudio.config.numChannels && hIvasRend->outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED && hIvasRend->outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) +#else if ( numOutChannels != outAudio.config.numChannels ) +#endif { return IVAS_ERR_WRONG_NUM_CHANNELS; } @@ -6249,6 +8163,22 @@ static ivas_error getSamplesInternal( /* Clear original output buffer */ set_zero( outAudio.data, outAudio.config.numChannels * outAudio.config.numSamplesPerChannel ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + outAudioOrig = outAudio; + /* Use internal buffer if outputting split rendering bitstream */ + if ( ( hIvasRend->outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) || + ( hIvasRend->outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) + { + int16_t num_poses_orig; + num_poses_orig = hIvasRend->splitRendWrapper.multiBinPoseData.num_poses; + outAudio = hIvasRend->splitRendEncBuffer; + ivas_renderSplitGetMultiBinPoseData( &hIvasRend->hRendererConfig->split_rend_config, &hIvasRend->splitRendWrapper.multiBinPoseData, hIvasRend->headRotData.sr_pose_pred_axis ); + assert( num_poses_orig == hIvasRend->splitRendWrapper.multiBinPoseData.num_poses && "number of poses should not change dynamically" ); + + /* Clear output buffer for split rendering bitstream */ + set_zero( outAudio.data, outAudio.config.numChannels * outAudio.config.numSamplesPerChannel ); + } +#endif if ( ( error = renderActiveInputsIsm( hIvasRend, outAudio ) ) != IVAS_ERR_OK ) { @@ -6270,14 +8200,82 @@ static ivas_error getSamplesInternal( return error; } +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( error = renderActiveInputsSplitBin( hIvasRend, outAudio ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( outAudio.config.is_cldfb == 0 ) + { +#ifndef DISABLE_LIMITER +#ifdef DEBUGGING + hIvasRend->numClipping += +#endif + limitRendererOutput( hIvasRend->hLimiter, outAudio.data, outAudio.config.numSamplesPerChannel, IVAS_LIMITER_THRESHOLD ); +#endif + } +#else #ifndef DISABLE_LIMITER +#ifdef DEBUGGING + hIvasRend->numClipping += +#endif limitRendererOutput( hIvasRend->hLimiter, outAudio.data, outAudio.config.numSamplesPerChannel, IVAS_LIMITER_THRESHOLD ); #endif +#endif + +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( hIvasRend->outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || hIvasRend->outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { + IVAS_SPLIT_REND_BITS_DATA bits; + 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]; + int16_t ch; + float *tmpBinaural[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS], tmpBinaural_buff[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][L_FRAME48k]; + + for ( ch = 0; ch < MAX_OUTPUT_CHANNELS; ch++ ) + { + tmpBinaural[ch] = tmpBinaural_buff[ch]; + } + + if ( outAudio.config.is_cldfb == 1 ) + { + cldfb_in_flag = 1; + copyBufferToCLDFBarray( outAudio, Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural ); + } + else + { + cldfb_in_flag = 0; + copyBufferTo2dArray( outAudio, tmpBinaural_buff ); + } + + /* Encode split rendering bitstream */ + convertBitsBufferToInternalBitsBuff( *hBits, &bits ); + + if ( ( error = ivas_renderMultiBinToSplitBinaural( &hIvasRend->splitRendWrapper, hIvasRend->headRotData.headPositions[0], hIvasRend->hRendererConfig->split_rend_config.splitRendBitRate, hIvasRend->hRendererConfig->split_rend_config.codec, 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 ) ) != IVAS_ERR_OK ) + { + return error; + } + + convertInternalBitsBuffToBitsBuffer( hBits, bits ); + + /* reset to outAudioOrig in case of PCM output */ + outAudio = outAudioOrig; + if ( hIvasRend->outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { + accumulate2dArrayToBuffer( tmpBinaural_buff, &outAudio ); + } + } +#endif +#ifdef NONBE_UNIFIED_DECODING_PATHS /* update global cominbed orientation start index */ ivas_combined_orientation_update_start_index( hIvasRend->hCombinedOrientationData, outAudio.config.numSamplesPerChannel ); +#endif return IVAS_ERR_OK; } @@ -6295,10 +8293,71 @@ ivas_error IVAS_REND_GetSamples( ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + return getSamplesInternal( hIvasRend, outAudio, NULL ); +#else return getSamplesInternal( hIvasRend, outAudio ); +#endif +} + + +#ifdef SPLIT_REND_WITH_HEAD_ROT +/*-------------------------------------------------------------------* + * IVAS_REND_GetSplitBinauralBitstream() + * + * + *-------------------------------------------------------------------*/ + +ivas_error IVAS_REND_GetSplitBinauralBitstream( + IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + IVAS_REND_AudioBuffer outAudio, /* i/o: buffer for output audio */ + IVAS_REND_BitstreamBuffer *hBits /* o : buffer for output bitstream */ +) +{ + int16_t cldfb_in_flag; + + cldfb_in_flag = getCldfbRendFlag( hIvasRend, IVAS_REND_AUDIO_CONFIG_TYPE_UNKNOWN ); + hIvasRend->splitRendEncBuffer.config.is_cldfb = cldfb_in_flag; + + if ( hIvasRend->hRendererConfig->split_rend_config.codec == IVAS_SPLIT_REND_CODEC_LC3PLUS && + ( hIvasRend->hRendererConfig->split_rend_config.dof == 0 || hIvasRend->hRendererConfig->split_rend_config.poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) ) + { + hIvasRend->splitRendEncBuffer.config.numSamplesPerChannel = hIvasRend->hRendererConfig->split_rend_config.codec_frame_size_ms * hIvasRend->num_subframes * (int16_t) ( hIvasRend->sampleRateOut / 1000 ); + } + else + { + hIvasRend->splitRendEncBuffer.config.numSamplesPerChannel = (int16_t) ( hIvasRend->sampleRateOut / FRAMES_PER_SEC ); + } + hIvasRend->splitRendEncBuffer.config.numSamplesPerChannel *= cldfb_in_flag ? 2 : 1; + + /* hIvasRend->splitRendEncBuffer used for BINAURAL_SPLIT_CODED output + outAudio used for BINAURAL_SPLIT_PCM output */ + return getSamplesInternal( hIvasRend, outAudio, hBits ); } +/*-------------------------------------------------------------------* + * IVAS_REND_GetSplitBinauralSamples() + * + * + *-------------------------------------------------------------------*/ + +ivas_error IVAS_REND_GetSplitBinauralSamples( + IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + IVAS_REND_AudioBuffer outAudio, /* i/o: buffer for output audio */ + bool *needNewFrame ) +{ + ivas_error error; + + if ( ( error = getSamplesInternal( hIvasRend, outAudio, NULL ) ) != IVAS_ERR_OK ) + { + return error; + } + *needNewFrame = hIvasRend->inputsSplitPost[0].numCachedSamples == 0; + + return IVAS_ERR_OK; +} +#endif /*-------------------------------------------------------------------* @@ -6343,12 +8402,22 @@ void IVAS_REND_Close( { clearInputMasa( &hIvasRend->inputsMasa[i] ); } +#ifdef SPLIT_REND_WITH_HEAD_ROT + for ( i = 0; i < RENDERER_MAX_BIN_INPUTS; ++i ) + { + clearInputSplitRend( &hIvasRend->inputsSplitPost[i] ); + } +#endif /* clear Config. Renderer */ ivas_render_config_close( &( hIvasRend->hRendererConfig ) ); ivas_limiter_close( &hIvasRend->hLimiter ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + /* Split binaural rendering */ + closeSplitRend( &hIvasRend->splitRendWrapper, &hIvasRend->splitRendEncBuffer ); +#endif closeHeadRotation( hIvasRend ); @@ -6362,8 +8431,150 @@ void IVAS_REND_Close( } +#ifdef SPLIT_REND_WITH_HEAD_ROT +/*-------------------------------------------------------------------* + * IVAS_REND_openCldfb() + * + * + *-------------------------------------------------------------------*/ + +ivas_error IVAS_REND_openCldfb( + IVAS_CLDFB_FILTER_BANK_HANDLE cldfbAna[IVAS_MAX_INPUT_CHANNELS], + IVAS_CLDFB_FILTER_BANK_HANDLE cldfbSyn[IVAS_MAX_OUTPUT_CHANNELS], + const int16_t num_in_chs, + const int16_t num_out_chs, + const int32_t output_Fs ) +{ + int16_t n; + ivas_error error; + + for ( n = 0; n < num_in_chs; n++ ) + { + if ( ( error = openCldfb( &( cldfbAna[n] ), CLDFB_ANALYSIS, output_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) + { + return error; + } + } + for ( ; n < IVAS_MAX_INPUT_CHANNELS; n++ ) + { + cldfbAna[n] = NULL; + } + + for ( n = 0; n < num_out_chs; n++ ) + { + if ( ( error = openCldfb( &( cldfbSyn[n] ), CLDFB_SYNTHESIS, output_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) + { + return error; + } + } + for ( ; n < IVAS_MAX_OUTPUT_CHANNELS; n++ ) + { + cldfbSyn[n] = NULL; + } + + return IVAS_ERR_OK; +} + + +/*-------------------------------------------------------------------* + * IVAS_REND_closeCldfb() + * + * + *-------------------------------------------------------------------*/ + +void IVAS_REND_closeCldfb( + IVAS_CLDFB_FILTER_BANK_HANDLE cldfbAna[IVAS_MAX_INPUT_CHANNELS], + IVAS_CLDFB_FILTER_BANK_HANDLE cldfbSyn[IVAS_MAX_OUTPUT_CHANNELS] ) +{ + int16_t n; + + for ( n = 0; n < IVAS_MAX_INPUT_CHANNELS; n++ ) + { + if ( cldfbAna[n] != NULL ) + { + deleteCldfb( &( cldfbAna[n] ) ); + cldfbAna[n] = NULL; + } + } + + for ( n = 0; n < IVAS_MAX_OUTPUT_CHANNELS; n++ ) + { + if ( cldfbSyn[n] != NULL ) + { + deleteCldfb( &( cldfbSyn[n] ) ); + cldfbSyn[n] = NULL; + } + } + + return; +} + + +/*-------------------------------------------------------------------* + * IVAS_REND_cldfbSynthesis_wrapper() + * + * + *-------------------------------------------------------------------*/ + +void IVAS_REND_cldfbAnalysis_ts_wrapper( + const float *timeIn, /* i : time buffer */ + float realBuffer[IVAS_CLDFB_NO_CHANNELS_MAX], /* o : real value buffer */ + float imagBuffer[IVAS_CLDFB_NO_CHANNELS_MAX], /* o : imag value buffer */ + const int16_t samplesToProcess, /* i : samples to process */ + IVAS_CLDFB_FILTER_BANK_HANDLE h_cldfb /* i : filterbank state */ +) +{ + cldfbAnalysis_ts( timeIn, realBuffer, imagBuffer, samplesToProcess, h_cldfb ); + + return; +} + + +/*-------------------------------------------------------------------* + * IVAS_REND_cldfbSynthesis_wrapper() + * + * + *-------------------------------------------------------------------*/ + +void IVAS_REND_cldfbSynthesis_wrapper( + float **realBuffer, /* i : real values */ + float **imagBuffer, /* i : imag values */ + float *timeOut, /* o : output time domain samples */ + const int16_t samplesToProcess, /* i : number of processed samples */ + IVAS_CLDFB_FILTER_BANK_HANDLE h_cldfb /* i : filter bank state */ +) +{ + cldfbSynthesis( realBuffer, imagBuffer, timeOut, samplesToProcess, h_cldfb ); + + return; +} +#endif + + +#ifdef DEBUGGING +/*-------------------------------------------------------------------* + * IVAS_REND_GetNoCLipping() + * + * + *-------------------------------------------------------------------*/ + +int32_t IVAS_REND_GetNoCLipping( + IVAS_REND_CONST_HANDLE hIvasRend ) +{ + return hIvasRend->numClipping; +} +int32_t IVAS_REND_GetCntFramesLimited( + IVAS_REND_CONST_HANDLE hIvasRend ) +{ + if ( hIvasRend->hLimiter == NULL ) + { + return 0; + } + return hIvasRend->hLimiter->cnt_frames_limited; +} +#endif static ivas_error ivas_masa_ext_rend_dirac_rend_init( input_masa *inputMasa ) @@ -6738,6 +8949,9 @@ static ivas_error ivas_masa_ext_rend_parambin_init( float binCenterFreq, tmpFloat; ivas_error error; float frequency_axis[CLDFB_NO_CHANNELS_MAX]; +#ifdef SPLIT_REND_WITH_HEAD_ROT + int16_t pos_idx; +#endif error = IVAS_ERR_OK; @@ -6748,7 +8962,13 @@ static ivas_error ivas_masa_ext_rend_parambin_init( nBins = inputMasa->hMasaExtRend->hSpatParamRendCom->num_freq_bands; renderer_type = inputMasa->hMasaExtRend->renderer_type; +#ifdef SPLIT_REND_WITH_HEAD_ROT + for ( pos_idx = 0; pos_idx < inputMasa->base.ctx.pSplitRendWrapper->multiBinPoseData.num_poses; pos_idx++ ) + { + hDiracDecBin = inputMasa->hMasaExtRend->hDiracDecBin[pos_idx]; +#else hDiracDecBin = inputMasa->hMasaExtRend->hDiracDecBin; +#endif /* Init assumes that no reconfiguration is required in external renderer. Instead, free and rebuild whole rendering. */ if ( ( hDiracDecBin = (DIRAC_DEC_BIN_HANDLE) malloc( sizeof( DIRAC_DEC_BIN_DATA ) ) ) == NULL ) @@ -6807,7 +9027,11 @@ static ivas_error ivas_masa_ext_rend_parambin_init( { mvr2r( hHrtfParambin->parametricEarlyPartEneCorrection, hDiracDecBin->earlyPartEneCorrection, nBins ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( hDiracDecBin->hReverb == NULL && pos_idx == 0 ) /* open reverb only for the main direction */ +#else if ( hDiracDecBin->hReverb == NULL ) +#endif { /* Todo Philips: Room acoustics should be passed here once the underlying part works. In this case, it probably should come from render context or somewhere else suitable. */ if ( ( error = ivas_binaural_reverb_open_parambin( &hDiracDecBin->hReverb, nBins, CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, NULL, output_Fs, hHrtfParambin ) ) != IVAS_ERR_OK ) @@ -6827,6 +9051,10 @@ static ivas_error ivas_masa_ext_rend_parambin_init( assert( false ); } +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( pos_idx == 0 ) /* open decorrelator only for the main direction */ + { +#endif /* Always open frequency domain decorrelator */ ivas_dirac_dec_get_frequency_axis( frequency_axis, output_Fs, nBins ); if ( ( error = ivas_dirac_dec_decorr_open( &( hDiracDecBin->h_freq_domain_decorr_ap_params ), @@ -6841,10 +9069,18 @@ static ivas_error ivas_masa_ext_rend_parambin_init( { return error; } +#ifdef SPLIT_REND_WITH_HEAD_ROT + } +#endif /* External renderer uses constant regularization factor */ hDiracDecBin->reqularizationFactor = 0.4f; +#ifdef SPLIT_REND_WITH_HEAD_ROT + inputMasa->hMasaExtRend->hDiracDecBin[pos_idx] = hDiracDecBin; + } +#else inputMasa->hMasaExtRend->hDiracDecBin = hDiracDecBin; +#endif return error; } @@ -6870,7 +9106,14 @@ static ivas_error initMasaExtRenderer( hMasaExtRend->renderer_type = RENDERER_DISABLE; hMasaExtRend->hDirACRend = NULL; hMasaExtRend->hSpatParamRendCom = NULL; +#ifdef SPLIT_REND_WITH_HEAD_ROT + for ( i = 0; i < MAX_HEAD_ROT_POSES; i++ ) + { + hMasaExtRend->hDiracDecBin[i] = NULL; + } +#else hMasaExtRend->hDiracDecBin = NULL; +#endif hMasaExtRend->hReverb = NULL; hMasaExtRend->hHrtfParambin = NULL; hMasaExtRend->hVBAPdata = NULL; @@ -6917,6 +9160,10 @@ static ivas_error initMasaExtRenderer( break; case IVAS_AUDIO_CONFIG_BINAURAL: +#ifdef SPLIT_REND_WITH_HEAD_ROT + case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM: + case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED: +#endif hMasaExtRend->renderer_type = RENDERER_BINAURAL_PARAMETRIC; break; @@ -7030,10 +9277,21 @@ static void freeMasaExtRenderer( ivas_spat_hSpatParamRendCom_close( &hMasaExtRend->hSpatParamRendCom ); } +#ifdef SPLIT_REND_WITH_HEAD_ROT + for ( i = 0; i < MAX_HEAD_ROT_POSES; i++ ) + { + if ( hMasaExtRend->hDiracDecBin[i] != NULL ) + { + ivas_dirac_dec_close_binaural_data( &hMasaExtRend->hDiracDecBin[i] ); + } + } + +#else if ( hMasaExtRend->hDiracDecBin != NULL ) { ivas_dirac_dec_close_binaural_data( &hMasaExtRend->hDiracDecBin ); } +#endif if ( hMasaExtRend->hReverb != NULL ) { diff --git a/lib_rend/lib_rend.h b/lib_rend/lib_rend.h index b8bc3a8a8..6df2ff3f4 100644 --- a/lib_rend/lib_rend.h +++ b/lib_rend/lib_rend.h @@ -45,6 +45,9 @@ #define RENDERER_MAX_SBA_INPUTS 1 #define RENDERER_MAX_MASA_INPUTS 1 #define RENDERER_MAX_INPUT_LFE_CHANNELS 4 +#ifdef SPLIT_REND_WITH_HEAD_ROT +#define RENDERER_MAX_BIN_INPUTS 1 +#endif /*---------------------------------------------------------------------* @@ -57,6 +60,9 @@ typedef struct { int16_t numSamplesPerChannel; int16_t numChannels; +#ifdef SPLIT_REND_WITH_HEAD_ROT + int16_t is_cldfb; +#endif } IVAS_REND_AudioBufferConfig; typedef struct @@ -65,6 +71,22 @@ typedef struct float *data; } IVAS_REND_AudioBuffer; +#ifdef SPLIT_REND_WITH_HEAD_ROT +typedef struct +{ + int32_t bufLenInBytes; + int32_t bitsWritten; + int32_t bitsRead; + IVAS_SPLIT_REND_CODEC codec; + IVAS_SPLIT_REND_POSE_CORRECTION_MODE poseCorrection; + int16_t codec_frame_size_ms; +} IVAS_REND_BitstreamBufferConfig; +typedef struct +{ + IVAS_REND_BitstreamBufferConfig config; + uint8_t *bits; +} IVAS_REND_BitstreamBuffer; +#endif typedef struct { @@ -216,11 +238,33 @@ int16_t IVAS_REND_FeedRenderConfig( const IVAS_RENDER_CONFIG_DATA renderConfig /* i : Render configuration struct */ ); +#ifdef SPLIT_REND_WITH_HEAD_ROT +ivas_error IVAS_REND_FeedSplitBinauralBitstream( + IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + const IVAS_REND_InputId inputId, /* i : ID of the input */ + IVAS_REND_BitstreamBuffer *hBits /* i : buffer for input bitstream */ +); + +ivas_error IVAS_REND_GetSplitBinauralSamples( + IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + IVAS_REND_AudioBuffer outAudio, /* i/o: buffer for output audio */ + bool* needNewFrame +); + +ivas_error IVAS_REND_GetSplitBinauralBitstream( + IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + IVAS_REND_AudioBuffer outAudio, /* i/o: buffer for output audio */ + IVAS_REND_BitstreamBuffer *hBits /* o : buffer for output bitstream */ +); +#endif ivas_error IVAS_REND_SetHeadRotation( IVAS_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 */ +#ifdef SPLIT_REND_WITH_HEAD_ROT + const IVAS_SPLIT_REND_ROT_AXIS rot_axis, /* i : external control for rotation axis for split rendering*/ +#endif const int16_t sf_idx /* i : subframe index */ ); @@ -255,6 +299,11 @@ ivas_error IVAS_REND_SetReferenceVector( const IVAS_VECTOR3 refPos /* i : Reference position */ ); +#ifdef SPLIT_REND_WITH_HEAD_ROT +ivas_error IVAS_REND_SetSplitRendBFI( + IVAS_REND_HANDLE hIvasRend, + const int16_t bfi); +#endif ivas_error IVAS_REND_SetExternalOrientation( IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ @@ -315,7 +364,48 @@ void IVAS_REND_Close( ); +#ifdef SPLIT_REND_WITH_HEAD_ROT +/* Split binaural rendering functions */ + +ivas_error IVAS_REND_openCldfb( + IVAS_CLDFB_FILTER_BANK_HANDLE cldfbAna[IVAS_MAX_INPUT_CHANNELS], + IVAS_CLDFB_FILTER_BANK_HANDLE cldfbSyn[IVAS_MAX_OUTPUT_CHANNELS], + const int16_t num_in_chs, + const int16_t num_out_chs, + const int32_t output_Fs +); + +void IVAS_REND_closeCldfb( + IVAS_CLDFB_FILTER_BANK_HANDLE cldfbAna[IVAS_MAX_INPUT_CHANNELS], + IVAS_CLDFB_FILTER_BANK_HANDLE cldfbSyn[IVAS_MAX_OUTPUT_CHANNELS] +); + +void IVAS_REND_cldfbAnalysis_ts_wrapper( + const float *timeIn, /* i : time buffer */ + float realBuffer[IVAS_CLDFB_NO_CHANNELS_MAX], /* o : real value buffer */ + float imagBuffer[IVAS_CLDFB_NO_CHANNELS_MAX], /* o : imag value buffer */ + const int16_t samplesToProcess, /* i : samples to process */ + IVAS_CLDFB_FILTER_BANK_HANDLE h_cldfb /* i : filterbank state */ +); + +void IVAS_REND_cldfbSynthesis_wrapper( + float **realBuffer, /* i : real values */ + float **imagBuffer, /* i : imag values */ + float *timeOut, /* o : output time domain samples */ + const int16_t samplesToProcess, /* i : number of processed samples */ + IVAS_CLDFB_FILTER_BANK_HANDLE h_cldfb /* i : filter bank state */ +); +#endif + +#ifdef DEBUGGING +int32_t IVAS_REND_GetNoCLipping( + IVAS_REND_CONST_HANDLE hIvasRend /* i : Renderer handle */ +); +int32_t IVAS_REND_GetCntFramesLimited( + IVAS_REND_CONST_HANDLE hIvasRend /* i : Renderer handle */ +); +#endif /* clang-format on */ diff --git a/lib_util/bitstream_reader.c b/lib_util/bitstream_reader.c index d103e7e79..2e88746c0 100644 --- a/lib_util/bitstream_reader.c +++ b/lib_util/bitstream_reader.c @@ -263,6 +263,22 @@ cleanup: return error; } +#ifdef DEBUGGING +ivas_error BS_Reader_Rewind( BS_READER_HANDLE hBsReader ) +{ + if ( hBsReader == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + if ( hBsReader->rewind == NULL ) + { + return IVAS_ERR_NOT_IMPLEMENTED; + } + + return hBsReader->rewind( hBsReader->hFormatReader ); +} +#endif ivas_error BS_Reader_ReadFrame_short( BS_READER_HANDLE hBsReader, uint16_t *serial, int16_t *num_bits, int16_t *bfi ) { diff --git a/lib_util/bitstream_reader.h b/lib_util/bitstream_reader.h index 937e8f167..374c19d43 100644 --- a/lib_util/bitstream_reader.h +++ b/lib_util/bitstream_reader.h @@ -58,6 +58,9 @@ typedef struct BS_Reader *BS_READER_HANDLE; ivas_error BS_Reader_Open_filename( BS_READER_HANDLE *phBsReader, const char *filename, BS_READER_FORMAT format ); +#ifdef DEBUGGING +ivas_error BS_Reader_Rewind( BS_READER_HANDLE hBsReader ); +#endif ivas_error BS_Reader_ReadFrame_short( BS_READER_HANDLE hBsReader, uint16_t *serial, int16_t *num_bits, int16_t *bfi ); diff --git a/lib_util/masa_file_reader.c b/lib_util/masa_file_reader.c index 00f3d69a9..5fda0fcc3 100644 --- a/lib_util/masa_file_reader.c +++ b/lib_util/masa_file_reader.c @@ -132,6 +132,9 @@ ivas_error MasaFileReader_readNextFrame( { if ( hMeta->descriptive_meta.formatDescriptor[i] != ivasmasaFormatDescriptor[i] ) { +#ifdef DEBUGGING + fprintf( stderr, "Input format is not IVASMASA\n" ); +#endif return IVAS_ERR_INVALID_MASA_FORMAT_METADATA_FILE; } } diff --git a/lib_util/render_config_reader.c b/lib_util/render_config_reader.c index 9661dcdf2..a1d778980 100644 --- a/lib_util/render_config_reader.c +++ b/lib_util/render_config_reader.c @@ -1064,7 +1064,11 @@ static void strip_spaces( while ( pStr[read_idx] ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( !isspace( (int32_t) pStr[read_idx] ) && !iscntrl( (int32_t) pStr[read_idx] ) ) +#else if ( !isspace( pStr[read_idx] ) && !iscntrl( pStr[read_idx] ) ) +#endif { pStr[write_idx++] = pStr[read_idx]; } @@ -1180,6 +1184,25 @@ ivas_error RenderConfigReader_checkValues( return IVAS_ERR_WRONG_PARAMS; } +#ifdef DEBUGGING + /* Specific limits for Jot reverb */ + if ( hRenderConfig->renderer_type_override == IVAS_RENDER_TYPE_OVERRIDE_CREND ) + { + if ( ( pRoom_acoustics->acousticPreDelay > ACOUSTICPREDELAY_JOTREV_MAX ) || ( pRoom_acoustics->acousticPreDelay < ACOUSTICPREDELAY_JOTREV_MIN ) ) + { + return IVAS_ERR_WRONG_PARAMS; + } + } + + /* Specific limits for frequency-domain reverb */ + if ( hRenderConfig->renderer_type_override == IVAS_RENDER_TYPE_OVERRIDE_FASTCONV ) + { + if ( ( pRoom_acoustics->acousticPreDelay > ACOUSTICPREDELAY_FDREV_MAX ) || ( pRoom_acoustics->acousticPreDelay < ACOUSTICPREDELAY_FDREV_MIN ) ) + { + return IVAS_ERR_WRONG_PARAMS; + } + } +#endif /* DEBUGGING */ if ( pRoom_acoustics->use_er == 1 ) @@ -1822,6 +1845,10 @@ ivas_error RenderConfigReader_read( uint32_t fgHasMethod, fgHasNBands, fgHasFreqs, fgHasDefaultGrid, fgHasStartFreq, fgHasFreqHop; uint32_t aeHasFgIdx, aeHasPredelay, aeHasRt60, aeHasDsr; uint32_t aeHasERsize, aeHasERabs; +#ifdef SPLIT_REND_WITH_HEAD_ROT + bool dofProvided = false; + bool poseCorrProvided = false; +#endif uint32_t nDP; uint32_t accDPIdx; @@ -1879,6 +1906,9 @@ ivas_error RenderConfigReader_read( while ( sscanf( pParams + params_idx, "%64[^=]=%[^;];", item, pValue ) == 2 ) { params_idx += (int32_t) ( strlen( item ) + strlen( pValue ) + 2 ); +#ifdef DEBUGGING + fprintf( stderr, " PARAM: %s -> %s\n", item, pValue ); +#endif if ( strcmp( item, "FREQUENCYGRIDCOUNT" ) == 0 ) { /* Read the number of frequency grids */ @@ -1950,7 +1980,23 @@ ivas_error RenderConfigReader_read( acIdx = 0; roomAcHasAcEnvCount = TRUE; } +#ifdef DEBUGGING + else + { + fprintf( stderr, "Rendering configuration: unsupported property %s\n", item ); + } +#endif + } +#ifdef DEBUGGING + if ( roomAcHasFgCount == FALSE ) + { + fprintf( stderr, "Renderer configuration: frequencyGridCount missing from 'roomAcoustics' chapter.\n\n" ); + } + if ( roomAcHasAcEnvCount == FALSE ) + { + fprintf( stderr, "Renderer configuration: acousticEnvironmentCount missing from 'roomAcoustics' chapter.\n\n" ); } +#endif if ( roomAcHasFgCount == FALSE || roomAcHasAcEnvCount == FALSE ) { return IVAS_ERR_INVALID_RENDER_CONFIG; @@ -1967,6 +2013,9 @@ ivas_error RenderConfigReader_read( idx = strtol( strtok( NULL, ":" ), NULL, 0 ); if ( idx >= pRenderConfigReader->nFG ) { +#ifdef DEBUGGING + fprintf( stderr, "Rendering configuration: frequency grid with index %d does not fit into the frequency grid array of %d elements.\n", idx, pRenderConfigReader->nFG ); +#endif return IVAS_ERR_INVALID_RENDER_CONFIG; } @@ -1977,6 +2026,9 @@ ivas_error RenderConfigReader_read( while ( sscanf( pParams + params_idx, "%64[^=]=%[^;];", item, pValue ) == 2 ) { params_idx += (int32_t) ( strlen( item ) + strlen( pValue ) + 2 ); +#ifdef DEBUGGING + fprintf( stderr, " PARAM: %s -> %s\n", item, pValue ); +#endif if ( strcmp( item, "METHOD" ) == 0 ) { if ( strcmp( pValue, "INDIVIDUALFREQUENCIES" ) == 0 ) @@ -2133,6 +2185,9 @@ ivas_error RenderConfigReader_read( } else { +#ifdef DEBUGGING + fprintf( stderr, "Rendering configuration: unsupported property %s\n", item ); +#endif break; } params_idx += (int32_t) ( strlen( item ) + strlen( pValue ) + 2 ); @@ -2140,6 +2195,9 @@ ivas_error RenderConfigReader_read( if ( defGridOffset + defGridNrBands > defGridLen ) { +#ifdef DEBUGGING + fprintf( stderr, "Rendering configuration: invalid default banding selection.\n\n" ); +#endif return IVAS_ERR_INVALID_RENDER_CONFIG; } pRenderConfigReader->pFG[idx].nrBands = defGridNrBands; @@ -2156,12 +2214,21 @@ ivas_error RenderConfigReader_read( pRenderConfigReader->pFG[idx].pFc[i] = pDefGrid[defGridOffset + i]; } } +#ifdef DEBUGGING + else + { + fprintf( stderr, "Rendering configuration: unsupported configuration property %s\n", item ); + } +#endif } if ( fgHasMethod == FALSE || ( fgMode == FREQ_GRID_MODE_INDIVIDUAL_FREQUENCIES && ( fgHasFreqs == FALSE || fgHasNBands == FALSE ) ) || ( fgMode == FREQ_GRID_MODE_DEFAULT_BANDING && fgHasDefaultGrid == FALSE ) || ( fgMode == FREQ_GRID_MODE_START_HOP_AMOUNT && ( fgHasStartFreq == FALSE || fgHasFreqHop == FALSE || fgHasNBands == FALSE ) ) ) { +#ifdef DEBUGGING + fprintf( stderr, "Rendering configuration: inconsistent default frequency band configuration.\n\n" ); +#endif return IVAS_ERR_INVALID_RENDER_CONFIG; } free( pValue ); @@ -2183,6 +2250,9 @@ ivas_error RenderConfigReader_read( while ( sscanf( pParams + params_idx, "%64[^=]=%[^;];", item, pValue ) == 2 ) { params_idx += (int32_t) ( strlen( item ) + strlen( pValue ) + 2 ); +#ifdef DEBUGGING + fprintf( stderr, " PARAM: %s -> %s\n", item, pValue ); +#endif /* Frequency grid index */ if ( strcmp( item, "FREQUENCYGRIDINDEX" ) == 0 ) { @@ -2276,6 +2346,9 @@ ivas_error RenderConfigReader_read( { if ( pRenderConfigReader->pAE[acIdx].pEarlyReflections == NULL ) { +#ifdef DEBUGGING + fprintf( stderr, "Rendering configuration: early reflections absorption coefficients specified without room size preceding.\n\n" ); +#endif return IVAS_ERR_INVALID_RENDER_CONFIG; } if ( read_txt_vector( pValue, N_ABS_COEFFS, erTemp ) ) @@ -2293,6 +2366,9 @@ ivas_error RenderConfigReader_read( { if ( pRenderConfigReader->pAE[acIdx].pEarlyReflections == NULL ) { +#ifdef DEBUGGING + fprintf( stderr, "Rendering configuration: early reflections listener origin specified without room size preceding.\n\n" ); +#endif return IVAS_ERR_INVALID_RENDER_CONFIG; } if ( read_txt_vector( pValue, 3, erTemp ) ) @@ -2312,6 +2388,9 @@ ivas_error RenderConfigReader_read( { if ( pRenderConfigReader->pAE[acIdx].pEarlyReflections == NULL ) { +#ifdef DEBUGGING + fprintf( stderr, "Rendering configuration: early reflections low complexity flag specified without room size preceding.\n\n" ); +#endif return IVAS_ERR_INVALID_RENDER_CONFIG; } if ( read_txt_bool( pValue, &pRenderConfigReader->pAE[acIdx].pEarlyReflections->lowComplexity ) ) @@ -2320,7 +2399,35 @@ ivas_error RenderConfigReader_read( return IVAS_ERR_INVALID_RENDER_CONFIG; } } +#ifdef DEBUGGING + else + { + fprintf( stderr, "Rendering configuration: unsupported configuration property %s\n", item ); + } +#endif + } +#ifdef DEBUGGING + if ( aeHasFgIdx == FALSE ) + { + fprintf( stderr, "Renderer configuration: frequencyGridIndex missing from 'acousticEnvironment' %d.\n\n", acIdx ); + } + if ( aeHasPredelay == FALSE ) + { + fprintf( stderr, "Renderer configuration: predelay missing from 'acousticEnvironment' %d.\n\n", acIdx ); + } + if ( aeHasRt60 == FALSE ) + { + fprintf( stderr, "Renderer configuration: RT60 missing from 'acousticEnvironment' %d.\n\n", acIdx ); + } + if ( aeHasDsr == FALSE ) + { + fprintf( stderr, "Renderer configuration: DSR missing from 'acousticEnvironment' %d.\n\n", acIdx ); } + if ( aeHasERsize == TRUE && aeHasERabs == FALSE ) + { + fprintf( stderr, "Renderer configuration: early reflections absorption coefficients missing from 'acousticEnvironment' %d.\n\n", acIdx ); + } +#endif if ( aeHasFgIdx == FALSE || aeHasPredelay == FALSE || aeHasRt60 == FALSE || aeHasDsr == FALSE ) { return IVAS_ERR_INVALID_RENDER_CONFIG; @@ -2337,6 +2444,131 @@ ivas_error RenderConfigReader_read( free( pValue ); acIdx++; } +#ifdef SPLIT_REND_WITH_HEAD_ROT + else if ( strcmp( chapter, "SPLITREND" ) == 0 && strlen( pParams ) != 0 ) + { + params_idx = 0; + pValue = (char *) calloc( strlen( pParams ), sizeof( char ) ); + while ( sscanf( pParams + params_idx, "%64[^=]=%[^;];", item, pValue ) == 2 ) + { + params_idx += (int32_t) ( strlen( item ) + strlen( pValue ) + 2 ); + fprintf( stderr, " PARAM: %s -> %s\n", item, pValue ); + if ( strcmp( item, "CODECDELAY" ) == 0 ) + { + if ( !sscanf( pValue, "%hd", &hRenderConfig->split_rend_config.codec_delay_ms ) ) + { + errorHandler( item, ERROR_VALUE_INVALID ); + } + } + else if ( strcmp( item, "HQMODE" ) == 0 ) + { + if ( !sscanf( pValue, "%hd", &hRenderConfig->split_rend_config.hq_mode ) ) + { + errorHandler( item, ERROR_VALUE_INVALID ); + } + } + else if ( strcmp( item, "BITRATE" ) == 0 ) + { + if ( !sscanf( pValue, "%d", &hRenderConfig->split_rend_config.splitRendBitRate ) ) + { + errorHandler( item, ERROR_VALUE_INVALID ); + } + } + else if ( strcmp( item, "DOF" ) == 0 ) + { + dofProvided = true; + if ( !sscanf( pValue, "%hd", &hRenderConfig->split_rend_config.dof ) ) + { + errorHandler( item, ERROR_VALUE_INVALID ); + } + /* 0 DOF implies no pose correction */ + if ( hRenderConfig->split_rend_config.dof == 0 && !poseCorrProvided ) + { + hRenderConfig->split_rend_config.poseCorrectionMode = IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE; + } + } + else if ( strcmp( item, "CODEC" ) == 0 ) + { + if ( strcmp( pValue, "LCLD" ) == 0 ) + { + hRenderConfig->split_rend_config.codec = IVAS_SPLIT_REND_CODEC_LCLD; + } + else if ( strcmp( pValue, "LC3PLUS" ) == 0 ) + { + hRenderConfig->split_rend_config.codec = IVAS_SPLIT_REND_CODEC_LC3PLUS; + } + else + { + errorHandler( pValue, ERROR_VALUE_INVALID ); + } + } + else if ( strcmp( item, "FRAMESIZE" ) == 0 ) + { + if ( !sscanf( pValue, "%hd", &hRenderConfig->split_rend_config.codec_frame_size_ms ) ) + { + errorHandler( item, ERROR_VALUE_INVALID ); + } + if ( hRenderConfig->split_rend_config.codec_frame_size_ms != 5 && + hRenderConfig->split_rend_config.codec_frame_size_ms != 10 && + hRenderConfig->split_rend_config.codec_frame_size_ms != 20 ) + { + errorHandler( item, ERROR_VALUE_INVALID ); + } + } + else if ( strcmp( item, "POSECORRECTION" ) == 0 ) + { + poseCorrProvided = true; + if ( strcmp( pValue, "CLDFB" ) == 0 ) + { + hRenderConfig->split_rend_config.poseCorrectionMode = IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB; + } + else if ( strcmp( pValue, "NONE" ) == 0 ) + { + hRenderConfig->split_rend_config.poseCorrectionMode = IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE; + /* no pose correction implies 0 DOF */ + if ( !dofProvided ) + { + hRenderConfig->split_rend_config.dof = 0; + } + } + else + { + errorHandler( pValue, ERROR_VALUE_INVALID ); + } + } + else if ( strcmp( item, "RENDERER" ) == 0 ) + { + if ( strcmp( pValue, "CREND" ) == 0 ) + { + hRenderConfig->split_rend_config.rendererSelection = IVAS_SPLIT_REND_RENDERER_SELECTION_CREND; + } + else if ( strcmp( pValue, "FASTCONV" ) == 0 ) + { + hRenderConfig->split_rend_config.rendererSelection = IVAS_SPLIT_REND_RENDERER_SELECTION_FASTCONV; + } + else if ( strcmp( pValue, "PARAMBIN" ) == 0 ) + { + hRenderConfig->split_rend_config.rendererSelection = IVAS_SPLIT_REND_RENDERER_SELECTION_PARAMBIN; + } + else if ( strcmp( pValue, "TDREND" ) == 0 ) + { + hRenderConfig->split_rend_config.rendererSelection = IVAS_SPLIT_REND_RENDERER_SELECTION_TDREND; + } + else + { + errorHandler( pValue, ERROR_VALUE_INVALID ); + } + } +#ifdef DEBUGGING + else + { + fprintf( stderr, "Unsupported configuration property %s\n", item ); + } +#endif + } + free( pValue ); + } +#endif else if ( strcmp( chapter, "DIRECTIVITYSETTING" ) == 0 && strlen( pParams ) != 0 ) { @@ -2346,6 +2578,9 @@ ivas_error RenderConfigReader_read( while ( sscanf( pParams + params_idx, "%64[^=]=%[^;];", item, pValue ) == 2 ) { params_idx += (int32_t) ( strlen( item ) + strlen( pValue ) + 2 ); +#ifdef DEBUGGING + fprintf( stderr, " PARAM: %s -> %s\n", item, pValue ); +#endif if ( strcmp( item, "DIRECTIVITYCOUNT" ) == 0 ) { /* Read the number of directivity chapters */ @@ -2393,6 +2628,9 @@ ivas_error RenderConfigReader_read( while ( sscanf( pParams + params_idx, "%64[^=]=%[^;];", item, pValue ) == 2 ) { params_idx += (int32_t) ( strlen( item ) + strlen( pValue ) + 2 ); +#ifdef DEBUGGING + fprintf( stderr, " PARAM: %s -> %s, DIRECTIVITYPATTERN -> %u\n", item, pValue, idx ); +#endif /* Allocate memory for directivity arrays*/ if ( ( pRenderConfigReader->pDP[accDPIdx].pDirectivity = (float *) malloc( 3 * sizeof( float ) ) ) == NULL ) { @@ -2420,6 +2658,9 @@ ivas_error RenderConfigReader_read( while ( sscanf( pParams + params_idx, "%64[^=]=%[^;];", item, pValue ) == 2 ) { params_length = (int32_t) ( strlen( item ) + strlen( pValue ) + 2 ); +#ifdef DEBUGGING + fprintf( stderr, " PARAM: %s -> %s\n", item, pValue ); +#endif if ( strcmp( item, "BINARYCONFIG" ) == 0 ) { /* get correct case reverb configuration file path */ @@ -2451,6 +2692,25 @@ ivas_error RenderConfigReader_read( free( pCombinedName ); } else +#ifdef DEBUGGING + if ( strcmp( item, "RENDERER" ) == 0 ) + { + if ( strcmp( pValue, "CREND" ) == 0 ) + { + hRenderConfig->renderer_type_override = IVAS_RENDER_TYPE_OVERRIDE_CREND; + } + else if ( strcmp( pValue, "FASTCONV" ) == 0 ) + { + hRenderConfig->renderer_type_override = IVAS_RENDER_TYPE_OVERRIDE_FASTCONV; + } + else + { + errorHandler( pValue, ERROR_VALUE_INVALID ); + return IVAS_ERR_INVALID_RENDER_CONFIG; + } + } + else +#endif if ( strcmp( item, "DIRECTIVITY" ) == 0 ) { if ( read_txt_vector( pValue, 3, hRenderConfig->directivity ) ) @@ -2458,6 +2718,12 @@ ivas_error RenderConfigReader_read( errorHandler( item, ERROR_VALUE_INVALID ); } } +#ifdef DEBUGGING + else + { + fprintf( stderr, "Unsupported configuration property %s\n", item ); + } +#endif params_idx += params_length; } free( pValue ); @@ -2471,6 +2737,12 @@ ivas_error RenderConfigReader_read( { /* comment lines are to be ignored */ } +#ifdef DEBUGGING + else + { + fprintf( stderr, "Unsupported configuration property %s\n", item ); + } +#endif } free( pConfig_str ); diff --git a/lib_util/split_rend_bfi_file_reader.c b/lib_util/split_rend_bfi_file_reader.c new file mode 100644 index 000000000..66f0a17ec --- /dev/null +++ b/lib_util/split_rend_bfi_file_reader.c @@ -0,0 +1,164 @@ +/****************************************************************************************************** + + (C) 2022-2023 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. + +*******************************************************************************************************/ + +#include +#include "options.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT +#include "split_rend_bfi_file_reader.h" +#include +#include +#include +#include "prot.h" + +struct SplitRendBFIFileReader +{ + FILE *bfiFile; + int32_t frameCounter; + char *file_path; + bool fileRewind; + bool txtfile; +}; + + +/*-----------------------------------------------------------------------* + * SplitRendBFIFileReader_open() + * + * Allocate and initialize Split Renderer Frameloss file reader + *-----------------------------------------------------------------------*/ + +ivas_error SplitRendBFIFileReader_open( + char *bfiFilePath, /* i : frame loss file name */ + SplitRendBFIFileReader **SplitRendBFIReader /* o : SplitRendBFIFileReader handle */ +) +{ + SplitRendBFIFileReader *self; + FILE *bfiFile; + bool txtfile; + + /* Open bfi file */ + if ( strlen( bfiFilePath ) < 1 ) + { + return IVAS_ERR_FAILED_FILE_OPEN; + } + + bfiFile = fopen( bfiFilePath, "r" ); + + if ( !bfiFile ) + { + return IVAS_ERR_FAILED_FILE_OPEN; + } + + txtfile = ( strcmp( bfiFilePath + strlen( bfiFilePath ) - 4, ".txt" ) ? false : true ); + + self = calloc( sizeof( SplitRendBFIFileReader ), 1 ); + self->bfiFile = bfiFile; + self->frameCounter = 0; + self->file_path = calloc( sizeof( char ), strlen( bfiFilePath ) + 1 ); + strcpy( self->file_path, bfiFilePath ); + self->fileRewind = false; + self->txtfile = txtfile; + + *SplitRendBFIReader = self; + + return IVAS_ERR_OK; +} + + +/*-----------------------------------------------------------------------* + * SplitRendBFIFileReading() + * + * Read values from the bfi file + *-----------------------------------------------------------------------*/ + +ivas_error SplitRendBFIFileReading( + SplitRendBFIFileReader *SplitRendBFIReader, /* i/o: SplitRendBFIFileReader handle */ + int16_t *bfi ) +{ + if ( SplitRendBFIReader->txtfile ? 1 != fscanf( SplitRendBFIReader->bfiFile, "%hd", bfi ) : 1 != fread( bfi, sizeof( *bfi ), 1, SplitRendBFIReader->bfiFile ) ) + { + if ( feof( SplitRendBFIReader->bfiFile ) ) + { + rewind( SplitRendBFIReader->bfiFile ); + SplitRendBFIReader->fileRewind = true; + return SplitRendBFIFileReading( SplitRendBFIReader, bfi ); + } + return IVAS_ERR_FAILED_FILE_PARSE; + } + + ( SplitRendBFIReader->frameCounter )++; + + return IVAS_ERR_OK; +} + + +/*-----------------------------------------------------------------------* + * SplitRendBFIationFileReader_close() + * + * Deallocates memory for the Head-Tracking reader + *-----------------------------------------------------------------------*/ + +void SplitRendBFIFileReader_close( + SplitRendBFIFileReader **SplitRendBFIReader /* i/o: SplitRendBFIFileReader handle */ +) +{ + if ( SplitRendBFIReader == NULL || *SplitRendBFIReader == NULL ) + { + return; + } + + fclose( ( *SplitRendBFIReader )->bfiFile ); + free( ( *SplitRendBFIReader )->file_path ); + free( *SplitRendBFIReader ); + *SplitRendBFIReader = NULL; + + return; +} + + +/*-----------------------------------------------------------------------* + * SplitRendBFIFileReader_getFilePath() + * + * + *-----------------------------------------------------------------------*/ + +const char *SplitRendBFIFileReader_getFilePath( + SplitRendBFIFileReader *SplitRendBFIReader /* i/o: SplitRendBFIFileReader handle */ +) +{ + if ( SplitRendBFIReader == NULL ) + { + return NULL; + } + + return SplitRendBFIReader->file_path; +} +#endif /* SPLIT_REND_WITH_HEAD_ROT */ diff --git a/lib_util/split_rend_bfi_file_reader.h b/lib_util/split_rend_bfi_file_reader.h new file mode 100644 index 000000000..341ef3ed6 --- /dev/null +++ b/lib_util/split_rend_bfi_file_reader.h @@ -0,0 +1,60 @@ +/****************************************************************************************************** + + (C) 2022-2023 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 IVAS_SR_BFI_FILE_READER_H +#define IVAS_SR_BFI_FILE_READER_H + +#include "common_api_types.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT + +typedef struct SplitRendBFIFileReader SplitRendBFIFileReader; + +ivas_error SplitRendBFIFileReader_open( + char *trajFilePath, /* i : head rotation trajectory file name */ + SplitRendBFIFileReader **SplitRendBFIReader /* o : SplitRendBFIFileReader handle */ +); + +ivas_error SplitRendBFIFileReading( + SplitRendBFIFileReader *SplitRendBFIReader, /* i/o: SplitRendBFIFileReader handle */ + int16_t *bfi ); + +void SplitRendBFIFileReader_close( + SplitRendBFIFileReader **SplitRendBFIReader /* i/o: SplitRendBFIFileReader handle */ +); + +const char *SplitRendBFIFileReader_getFilePath( + SplitRendBFIFileReader *SplitRendBFIReader /* i/o: SplitRendBFIFileReader handle */ +); + + +#endif /* SPLIT_REND_WITH_HEAD_ROT */ +#endif /* IVAS_SR_BFI_FILE_READER_H */ diff --git a/lib_util/split_render_file_read_write.c b/lib_util/split_render_file_read_write.c new file mode 100644 index 000000000..1a08a6929 --- /dev/null +++ b/lib_util/split_render_file_read_write.c @@ -0,0 +1,388 @@ +/****************************************************************************************************** + + (C) 2022-2023 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. + +*******************************************************************************************************/ + +#include +#include "options.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT +#include "split_render_file_read_write.h" +#include +#include +#include +#include +#include "cmdl_tools.h" +#include "prot.h" +#include "ivas_cnst.h" + + +/*------------------------------------------------------------------------------------------* + * PreProc Macros + *------------------------------------------------------------------------------------------*/ + +#define SPLIT_RENDERER_FRAME_HEADER_LEN ( 12 ) + +/*------------------------------------------------------------------------------------------* + * Type definitions + *------------------------------------------------------------------------------------------*/ + +struct SplitFileReadWrite +{ + FILE *file; + uint32_t delay_ns; +}; + + +/*-----------------------------------------------------------------------------------------* + * Function split_rend_reader_open() + * + * open in read mode + *-----------------------------------------------------------------------------------------*/ + +ivas_error split_rend_reader_open( + SplitFileReadWrite **hhSplitRendFileReadWrite, + char *filename ) +{ + SplitFileReadWrite *hSplitRendFileReadWrite; + size_t header_len, h; + char header[SPLIT_RENDERER_FRAME_HEADER_LEN] = "MAIN_SPLITH"; + char header_read[SPLIT_RENDERER_FRAME_HEADER_LEN]; + + if ( ( hSplitRendFileReadWrite = (SplitFileReadWrite *) malloc( sizeof( SplitFileReadWrite ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for split rendering writer\n" ) ); + } + + hSplitRendFileReadWrite->file = fopen( filename, "rb" ); + if ( hSplitRendFileReadWrite->file == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_FILE_READ, "\nCould not open split rend metadata file %s\n", filename ) ); + } + + header_len = strlen( header ); + + /*read frame header*/ + for ( h = 0; h < header_len; h++ ) + { + if ( fread( &header_read[h], sizeof( char ), 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_FAILED_FILE_READ; + } + } + + if ( strncmp( header_read, header, header_len ) ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_FILE_READ, "\nError split rend bitstream main header mismatch\n" ) ); + } + + fread( &hSplitRendFileReadWrite->delay_ns, sizeof( uint32_t ), 1, hSplitRendFileReadWrite->file ); + + *hhSplitRendFileReadWrite = hSplitRendFileReadWrite; + + return IVAS_ERR_OK; +} + + +/*-----------------------------------------------------------------------------------------* + * Function split_rend_writer_open() + * + * open in write mode + *-----------------------------------------------------------------------------------------*/ + +ivas_error split_rend_writer_open( + SplitFileReadWrite **hhSplitRendFileReadWrite, + char *filename, + const int16_t delayNumSamples, + const int32_t delayTimeScale ) +{ + SplitFileReadWrite *hSplitRendFileReadWrite; + size_t header_len, h; + char header[SPLIT_RENDERER_FRAME_HEADER_LEN] = "MAIN_SPLITH"; + + if ( filename == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + if ( ( hSplitRendFileReadWrite = (SplitFileReadWrite *) malloc( sizeof( SplitFileReadWrite ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for split rendering writer\n" ) ); + } + + hSplitRendFileReadWrite->file = fopen( filename, "wb" ); + if ( hSplitRendFileReadWrite->file == NULL ) + { + return IVAS_ERR_FAILED_FILE_OPEN; + } + + header_len = strlen( header ); + + /* write frame header */ + for ( h = 0; h < header_len; h++ ) + { + if ( fwrite( &header[h], sizeof( char ), 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_END_OF_FILE; + } + } + hSplitRendFileReadWrite->delay_ns = (int32_t) ( (float) delayNumSamples * 1000000000.0f / (float) delayTimeScale ); + fwrite( &hSplitRendFileReadWrite->delay_ns, sizeof( int32_t ), 1, hSplitRendFileReadWrite->file ); + + *hhSplitRendFileReadWrite = hSplitRendFileReadWrite; + + return IVAS_ERR_OK; +} + + +/*-----------------------------------------------------------------------------------------* + * Function split_rend_reader_writer_close() + * + * + *-----------------------------------------------------------------------------------------*/ + +ivas_error split_rend_reader_writer_close( + SplitFileReadWrite **hhSplitRendFileReadWrite ) +{ + if ( ( *hhSplitRendFileReadWrite ) != NULL ) + { + if ( ( *hhSplitRendFileReadWrite )->file != NULL ) + { + fclose( ( *hhSplitRendFileReadWrite )->file ); + ( *hhSplitRendFileReadWrite )->file = NULL; + } + + free( *hhSplitRendFileReadWrite ); + *hhSplitRendFileReadWrite = NULL; + } + + return IVAS_ERR_OK; +} + + +/*-----------------------------------------------------------------------------------------* + * Function split_rend_write_bitstream_to_file() + * + * + *-----------------------------------------------------------------------------------------*/ + +ivas_error split_rend_write_bitstream_to_file( + SplitFileReadWrite *hSplitRendFileReadWrite, + uint8_t *bits, + int32_t *bits_read, + int32_t *bits_written, + IVAS_SPLIT_REND_CODEC codec, + IVAS_SPLIT_REND_POSE_CORRECTION_MODE poseCorrection, + int16_t codec_frame_size_ms ) +{ + char header[SPLIT_RENDERER_FRAME_HEADER_LEN] = "SPLIT_FRAME"; + size_t header_len, i, num_bytes; + uint8_t version = 0; + + if ( hSplitRendFileReadWrite == NULL ) + { + return IVAS_ERR_FAILED_FILE_READ; + } + + if ( hSplitRendFileReadWrite->file == NULL ) + { + return IVAS_ERR_FAILED_FILE_WRITE; + } + + header_len = strlen( header ); + + /* write frame header */ + for ( i = 0; i < header_len; i++ ) + { + if ( fwrite( &header[i], sizeof( char ), 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_FAILED_FILE_WRITE; + } + } + + /* Write versioning signalling */ + if ( fwrite( &version, 1, 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_FAILED_FILE_WRITE; + } + + /* Write codec signalling */ + if ( fwrite( &codec, sizeof( codec ), 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_FAILED_FILE_WRITE; + } + + /* Write pose correction signalling */ + if ( fwrite( &poseCorrection, sizeof( poseCorrection ), 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_FAILED_FILE_WRITE; + } + /* Write frame size signalling */ + if ( fwrite( &codec_frame_size_ms, sizeof( codec_frame_size_ms ), 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_FAILED_FILE_WRITE; + } + + /* write num bytes */ + if ( fwrite( bits_written, sizeof( int32_t ), 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_FAILED_FILE_WRITE; + } + + num_bytes = ( *bits_written + 7 ) >> 3; + if ( fwrite( bits, sizeof( uint8_t ), num_bytes, hSplitRendFileReadWrite->file ) != num_bytes ) + { + return IVAS_ERR_FAILED_FILE_WRITE; + } + + *bits_read = 0; + *bits_written = 0; + + return IVAS_ERR_OK; +} + + +/*-----------------------------------------------------------------------------------------* + * Function split_rend_read_bits_from_file() + * + * + *-----------------------------------------------------------------------------------------*/ + +ivas_error split_rend_read_bits_from_file( + SplitFileReadWrite *hSplitRendFileReadWrite, + uint8_t *bits, + int32_t *bits_read, + int32_t *bits_written, + IVAS_SPLIT_REND_CODEC *codec, + IVAS_SPLIT_REND_POSE_CORRECTION_MODE *poseCorrection, + int16_t *codec_frame_size_ms ) +{ + char header[SPLIT_RENDERER_FRAME_HEADER_LEN] = "SPLIT_FRAME"; + char header_read[SPLIT_RENDERER_FRAME_HEADER_LEN]; + int32_t header_len, i, num_bytes, bit_len = 0; + uint8_t version; + + if ( hSplitRendFileReadWrite == NULL ) + { + return IVAS_ERR_FAILED_FILE_READ; + } + + if ( hSplitRendFileReadWrite->file == NULL ) + { + return IVAS_ERR_FAILED_FILE_READ; + } + + header_len = strlen( header ); + + /* read frame header */ + for ( i = 0; i < header_len; i++ ) + { + if ( fread( &header_read[i], sizeof( char ), 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_END_OF_FILE; + } + } + + if ( strncmp( header_read, header, header_len ) ) + { + fprintf( stderr, "Error bitstream frame header mismatch\n" ); + return IVAS_ERR_FAILED_FILE_READ; + } + + /* read versioning signalling */ + if ( fread( &version, 1, 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_FAILED_FILE_WRITE; + } + if ( version != 0 ) + { + fprintf( stderr, "Error bitstream version mismatch\n" ); + return IVAS_ERR_FAILED_FILE_READ; + } + + /* read codec signalling */ + if ( fread( codec, sizeof( *codec ), 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_FAILED_FILE_READ; + } + + /* read pose correction signalling */ + if ( fread( poseCorrection, sizeof( *poseCorrection ), 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_FAILED_FILE_READ; + } + /* read frame size signalling */ + if ( fread( codec_frame_size_ms, sizeof( *codec_frame_size_ms ), 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_FAILED_FILE_READ; + } + + /* write num bytes */ + if ( fread( &bit_len, sizeof( int32_t ), 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_FAILED_FILE_READ; + } + num_bytes = ( bit_len + 7 ) >> 3; + + if ( fread( bits, sizeof( uint8_t ), num_bytes, hSplitRendFileReadWrite->file ) != (uint32_t) num_bytes ) + { + return IVAS_ERR_FAILED_FILE_READ; + } + for ( i = 0; i < IVAS_SPLIT_REND_ADDITIONAL_BYTES_TO_READ; i++ ) + { + bits[num_bytes + i] = 0; + } + + *bits_read = 0; + *bits_written = bit_len; + + return IVAS_ERR_OK; +} + + +/*-----------------------------------------------------------------------------------------* + * Function split_rend_read_pre_rend_delay_ns() + * + * + *-----------------------------------------------------------------------------------------*/ + +ivas_error split_rend_read_pre_rend_delay_ns( + SplitFileReadWrite *hSplitRendFileReadWrite, + uint32_t *delay_ns ) +{ + if ( hSplitRendFileReadWrite == NULL ) + { + return IVAS_ERR_FAILED_FILE_READ; + } + + *delay_ns = hSplitRendFileReadWrite->delay_ns; + + return IVAS_ERR_OK; +} +#endif /* SPLIT_REND_WITH_HEAD_ROT */ diff --git a/lib_util/split_render_file_read_write.h b/lib_util/split_render_file_read_write.h new file mode 100644 index 000000000..40028c2ad --- /dev/null +++ b/lib_util/split_render_file_read_write.h @@ -0,0 +1,84 @@ +/****************************************************************************************************** + + (C) 2022-2023 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 SPLIT_RENDER_FILE_READ_WRITE_H +#define SPLIT_RENDER_FILE_READ_WRITE_H + +#include "common_api_types.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT + +typedef struct SplitFileReadWrite SplitFileReadWrite; + +/* Allocates and initializes a a split renderer reader instance */ +ivas_error split_rend_reader_open( + SplitFileReadWrite **hhSplitRendFileReadWrite, + char *filename ); + + +/* Allocates and initializes a a split renderer writer instance */ +ivas_error split_rend_writer_open( + SplitFileReadWrite **hhSplitRendFileReadWrite, + char *filename, + const int16_t delayNumSamples, + const int32_t delayTimeScale ); + +/* Closes the split renderer reader/writer and deallocates memory */ +ivas_error split_rend_reader_writer_close( + SplitFileReadWrite **hhSplitRendFileReadWrite ); + +/*write split rend coded bitstream to file */ +ivas_error split_rend_write_bitstream_to_file( + SplitFileReadWrite *hSplitRendFileReadWrite, + uint8_t *bits, + int32_t *bits_read, + int32_t *bits_written, + IVAS_SPLIT_REND_CODEC codec, + IVAS_SPLIT_REND_POSE_CORRECTION_MODE poseCorrection, + int16_t codec_frame_size_ms ); + +/* read split rend coded bits from file */ +ivas_error split_rend_read_bits_from_file( + SplitFileReadWrite *hSplitRendFileReadWrite, + uint8_t *bits, + int32_t *bits_read, + int32_t *bits_written, + IVAS_SPLIT_REND_CODEC *codec, + IVAS_SPLIT_REND_POSE_CORRECTION_MODE *poseCorrection, + int16_t *codec_frame_size_ms ); + +/* read split pre rend delay */ +ivas_error split_rend_read_pre_rend_delay_ns( + SplitFileReadWrite *hSplitRendFileReadWrite, + uint32_t *delay_ns ); + +#endif /* SPLIT_REND_WITH_HEAD_ROT */ +#endif /* SPLIT_RENDER_FILE_READ_WRITE_H */ diff --git a/lib_util/tsm_scale_file_reader.c b/lib_util/tsm_scale_file_reader.c new file mode 100644 index 000000000..fbd1824d9 --- /dev/null +++ b/lib_util/tsm_scale_file_reader.c @@ -0,0 +1,148 @@ +/****************************************************************************************************** + + (C) 2022-2023 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. + +*******************************************************************************************************/ + +#include "tsm_scale_file_reader.h" +#include "cmdl_tools.h" +#include +#include +#include + +struct TsmScaleFileReader +{ + FILE *file; + char *file_path; + bool fileRewind; +}; + + +/*---------------------------------------------------------------------* + * TsmScaleFileReader_open() + * + * Allocates memory for an TsmScaleFileReader and opens the file at given path for reading. + *---------------------------------------------------------------------*/ + +/*! r: JbmFileReader handle */ +TsmScaleFileReader *TsmScaleFileReader_open( + const char *filePath /* i : path to CA config file */ +) +{ + TsmScaleFileReader *self; + FILE *file; + + if ( !filePath ) + { + return NULL; + } + + file = fopen( filePath, "rb" ); + + if ( !file ) + { + return NULL; + } + + self = calloc( sizeof( TsmScaleFileReader ), 1 ); + self->file = file; + self->file_path = calloc( sizeof( char ), strlen( filePath ) + 1 ); + strcpy( self->file_path, filePath ); + + return self; +} + + +/*---------------------------------------------------------------------* + * TsmScaleFileReader_readScale() + * + * Read TSM scale entry + *---------------------------------------------------------------------*/ + +ivas_error TsmScaleFileReader_readScale( + TsmScaleFileReader *self, /* i/o: TsmScaleFileReader handle */ + int16_t *scale /* o : scale */ +) +{ + int tmp; + if ( 1 != fscanf( self->file, "%d", &tmp ) ) + { + if ( feof( self->file ) ) + { + rewind( self->file ); + self->fileRewind = true; + return TsmScaleFileReader_readScale( self, scale ); + } + return IVAS_ERR_FAILED_FILE_PARSE; + } + *scale = (int16_t) tmp; + return IVAS_ERR_OK; +} + + +/*---------------------------------------------------------------------* + * JbmFileReader_close() + * + * De-allocates all underlying memory of an JbmFileReader. + *---------------------------------------------------------------------*/ + +void TsmScaleFileReader_close( + TsmScaleFileReader **selfPtr /* i/o: pointer to JbmFileReader handle */ +) +{ + if ( selfPtr == NULL || *selfPtr == NULL ) + { + return; + } + + fclose( ( *selfPtr )->file ); + free( ( *selfPtr )->file_path ); + free( *selfPtr ); + *selfPtr = NULL; + + return; +} + + +/*---------------------------------------------------------------------* + * JbmFileReader_getFilePath() + * + *---------------------------------------------------------------------*/ + +const char *TsmScaleFileReader_getFilePath( + TsmScaleFileReader *self /* i/o: JbmFileReader handle */ +) +{ + if ( self == NULL ) + { + return NULL; + } + + return self->file_path; +} diff --git a/lib_util/tsm_scale_file_reader.h b/lib_util/tsm_scale_file_reader.h new file mode 100644 index 000000000..55ee20f8c --- /dev/null +++ b/lib_util/tsm_scale_file_reader.h @@ -0,0 +1,64 @@ +/****************************************************************************************************** + + (C) 2022-2023 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 IVAS_TSM_SCALE_FILE_READER_H +#define IVAS_TSM_SCALE_FILE_READER_H + +#include "common_api_types.h" + +/* clang-format off */ + +typedef struct TsmScaleFileReader TsmScaleFileReader; + + +/*! r: TsmScaleFileReader handle */ +TsmScaleFileReader *TsmScaleFileReader_open( + const char *filePath /* i : path to TSM scale file */ +); + +ivas_error TsmScaleFileReader_readScale( + TsmScaleFileReader* self, /* i/o: TsmScaleFileReader handle */ + int16_t *scale /* o : next scale */ +); + +void TsmScaleFileReader_close( + TsmScaleFileReader **selfPtr /* i/o: pointer to TsmScaleFileReader handle */ +); + +/*! r: path to the currently opened file or NULL if `self` is NULL */ +const char *TsmScaleFileReader_getFilePath( + TsmScaleFileReader* self /* i/o: TsmScaleFileReader handle */ +); + +/* clang-format on */ + +#endif /* IVAS_TSM_SCALE_FILE_READER_H */ -- GitLab From bbd9744b32517c2b6fde7934ae5958ba165fe47e Mon Sep 17 00:00:00 2001 From: Erik Norvell Date: Fri, 20 Dec 2024 15:08:03 +0100 Subject: [PATCH 02/33] Merge with float-pc --- apps/decoder.c | 267 +++++- apps/renderer.c | 176 ++-- lib_com/common_api_types.h | 2 - lib_com/ivas_cnst.h | 23 - lib_com/ivas_dirac_com.c | 10 - lib_com/ivas_prot.h | 126 --- lib_com/ivas_rom_com.c | 112 --- lib_com/ivas_rom_com.h | 11 - lib_com/tcx_ltp.c | 9 - lib_dec/bass_psfilter.c | 4 - lib_dec/fd_cng_dec.c | 11 - lib_dec/ivas_core_dec.c | 4 - lib_dec/ivas_corecoder_dec_reconfig.c | 8 - lib_dec/ivas_cpe_dec.c | 4 - lib_dec/ivas_dec.c | 1119 ------------------------ lib_dec/ivas_dirac_dec.c | 147 ---- lib_dec/ivas_init_dec.c | 77 -- lib_dec/ivas_ism_dec.c | 9 - lib_dec/ivas_ism_dtx_dec.c | 60 -- lib_dec/ivas_ism_param_dec.c | 20 - lib_dec/ivas_ism_renderer.c | 242 ----- lib_dec/ivas_masa_dec.c | 1 - lib_dec/ivas_mc_param_dec.c | 15 - lib_dec/ivas_mc_paramupmix_dec.c | 596 ------------- lib_dec/ivas_mct_dec.c | 17 - lib_dec/ivas_mdct_core_dec.c | 4 - lib_dec/ivas_objectRenderer_internal.c | 26 - lib_dec/ivas_omasa_dec.c | 109 --- lib_dec/ivas_osba_dec.c | 211 ----- lib_dec/ivas_rom_dec.c | 143 --- lib_dec/ivas_sba_dec.c | 44 - lib_dec/ivas_sba_dirac_stereo_dec.c | 2 - lib_dec/ivas_sba_rendering_internal.c | 128 --- lib_dec/ivas_spar_decoder.c | 32 - lib_dec/ivas_stat_dec.h | 10 - lib_dec/ivas_stereo_dft_dec.c | 8 - lib_dec/ivas_stereo_mdct_stereo_dec.c | 5 - lib_dec/lib_dec.c | 255 ------ lib_dec/lib_dec.h | 16 - lib_enc/cod_tcx.c | 9 - lib_enc/ivas_mc_paramupmix_enc.c | 194 ---- lib_enc/ivas_rom_enc.c | 114 --- lib_enc/ivas_rom_enc.h | 7 - lib_rend/ivas_crend.c | 20 - lib_rend/ivas_objectRenderer.c | 24 - lib_rend/ivas_output_init.c | 6 - lib_rend/ivas_prot_rend.h | 23 - lib_rend/ivas_rotation.c | 26 - lib_rend/ivas_stat_rend.h | 4 - 49 files changed, 334 insertions(+), 4156 deletions(-) diff --git a/apps/decoder.c b/apps/decoder.c index 7b3a5410d..4d42bcbf3 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -43,6 +43,7 @@ #include "masa_file_writer.h" #include "render_config_reader.h" #include "rotation_file_reader.h" +#include "split_render_file_read_write.h" #ifdef VARIABLE_SPEED_DECODING #include "tsm_scale_file_reader.h" #include @@ -121,6 +122,7 @@ typedef struct float non_diegetic_pan_gain; bool renderConfigEnabled; char *renderConfigFilename; + char *outputMdFilename; IVAS_DEC_COMPLEXITY_LEVEL complexityLevel; bool tsmEnabled; IVAS_RENDER_FRAMESIZE renderFramesize; @@ -148,7 +150,7 @@ typedef struct static bool parseCmdlIVAS_dec( int16_t argc, char **argv, DecArguments *arg ); static void usage_dec( void ); -static ivas_error decodeG192( DecArguments arg, BS_READER_HANDLE hBsReader, RotFileReader *headRotReader, RotFileReader *externalOrientationFileReader, RotFileReader *refRotReader, Vector3PairFileReader *referenceVectorReader, IVAS_DEC_HANDLE hIvasDec, int16_t *pcmBuf ); +static ivas_error decodeG192( DecArguments arg, BS_READER_HANDLE hBsReader, RotFileReader *headRotReader, RotFileReader *externalOrientationFileReader, RotFileReader *refRotReader, Vector3PairFileReader *referenceVectorReader, uint8_t *splitRendBitsBuf, IVAS_DEC_HANDLE hIvasDec, int16_t *pcmBuf ); static ivas_error decodeVoIP( DecArguments arg, BS_READER_HANDLE hBsReader, RotFileReader *headRotReader, RotFileReader *externalOrientationFileReader, RotFileReader *refRotReader, Vector3PairFileReader *referenceVectorReader, IVAS_DEC_HANDLE hIvasDec ); #ifdef DEBUGGING @@ -170,6 +172,7 @@ int main( bool mainFailed = true; /* Assume main failed until cleanup is reached without errors */ DecArguments arg; ivas_error error = IVAS_ERR_UNKNOWN; + uint8_t splitRendBitsBuf[IVAS_MAX_SPLIT_REND_BITS_BUFFER_SIZE_IN_BYTES]; /* Any handles that require cleanup must be declared here and initialized to NULL */ IVAS_DEC_HANDLE hIvasDec = NULL; @@ -245,6 +248,16 @@ int main( } } + if ( arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) + { + fprintf( stdout, "Output metadata file: %s\n", arg.outputWavFilename ); + } + else if ( arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { + fprintf( stdout, "Output synthesis file: %s\n", arg.outputWavFilename ); + fprintf( stdout, "Output metadata file: %s\n", arg.outputMdFilename ); + } + else { fprintf( stdout, "Output synthesis file: %s\n", arg.outputWavFilename ); } @@ -279,6 +292,7 @@ int main( { /* sanity check */ if ( arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB + && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) { fprintf( stderr, "\nError: Head-rotation file file cannot be used in this output configuration.\n\n" ); @@ -380,6 +394,7 @@ int main( { /* sanity check */ if ( arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB + && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) { fprintf( stderr, "\nError: Renderer configuration file cannot be used in this output configuration.\n\n" ); @@ -420,6 +435,28 @@ int main( * Configure Split rendering *------------------------------------------------------------------------------------------*/ + if ( arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { + asked_frame_size = arg.renderFramesize; + if ( ( error = IVAS_DEC_EnableSplitRendering( hIvasDec ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nConfigure failed: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + + if ( ( error = IVAS_DEC_GetRenderFramesize( hIvasDec, &arg.renderFramesize ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nConfigure failed: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + + if ( arg.renderFramesize != asked_frame_size ) + { + fprintf( stderr, "\nChanged render framesize, only 20ms are allowed for split rendering!\n" ); + } + + arg.enableHeadRotation = true; + } /*------------------------------------------------------------------------------------------* * Configure VoIP mode @@ -548,9 +585,10 @@ int main( IVAS_RENDER_CONFIG_DATA renderConfig; /* sanity check */ - if ( arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) + if ( arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB && + arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) { - fprintf( stderr, "\nExternal Renderer Config is supported only for binaural output configurations. Exiting. \n\n" ); + fprintf( stderr, "\nExternal Renderer Config is supported only when binaural output configurations is used as output OR when Split rendering mode is enabled. Exiting. \n" ); goto cleanup; } @@ -560,6 +598,22 @@ int main( goto cleanup; } + if ( arg.renderFramesize == IVAS_RENDER_FRAMESIZE_5MS && ( renderConfig.split_rend_config.poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE || + renderConfig.split_rend_config.dof == 0 ) ) + { +/*TODO : needs to be refined as this wont work with LCLD codec*/ + arg.renderFramesize = IVAS_RENDER_FRAMESIZE_5MS; + } + else + { + arg.renderFramesize = IVAS_RENDER_FRAMESIZE_20MS; + } + + if ( ( error = IVAS_DEC_SetRenderFramesize( hIvasDec, arg.renderFramesize ) ) != IVAS_ERR_OK ) + { + return error; + } + if ( RenderConfigReader_read( renderConfigReader, arg.renderConfigFilename, &renderConfig ) != IVAS_ERR_OK ) { @@ -703,7 +757,7 @@ int main( } else { - error = decodeG192( arg, hBsReader, headRotReader, externalOrientationFileReader, refRotReader, referenceVectorReader, hIvasDec, pcmBuf ); + error = decodeG192( arg, hBsReader, headRotReader, externalOrientationFileReader, refRotReader, referenceVectorReader, splitRendBitsBuf, hIvasDec, pcmBuf ); } if ( error == IVAS_ERR_OK || error == IVAS_ERR_END_OF_FILE ) @@ -856,6 +910,14 @@ static IVAS_AUDIO_CONFIG cmdline2config( { output_config = IVAS_AUDIO_CONFIG_BINAURAL; } + else if ( strcmp( argv_to_upper, "BINAURAL_SPLIT_CODED" ) == 0 ) + { + output_config = IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED; + } + else if ( strcmp( argv_to_upper, "BINAURAL_SPLIT_PCM" ) == 0 ) + { + output_config = IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM; + } else if ( strcmp( argv_to_upper, "BINAURAL_ROOM_IR" ) == 0 ) { output_config = IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR; @@ -931,6 +993,7 @@ static bool parseCmdlIVAS_dec( arg->renderConfigFilename = NULL; arg->Opt_dpid_on = 0; + arg->outputMdFilename = NULL; arg->inputFormat = IVAS_DEC_INPUT_FORMAT_G192; arg->Opt_non_diegetic_pan = 0; @@ -1254,6 +1317,17 @@ static bool parseCmdlIVAS_dec( } i += 2; } + else if ( strcmp( argv_to_upper, "-OM" ) == 0 ) + { + arg->outputMdFilename = argv[i + 1]; + if ( arg->outputMdFilename[0] == '\0' ) + { + fprintf( stderr, "Error: output metadata file path not specified\n\n" ); + usage_dec(); + return false; + } + i += 2; + } else if ( strcmp( argv_to_upper, "-NON_DIEGETIC_PAN" ) == 0 ) { i++; @@ -1472,7 +1546,7 @@ static void usage_dec( void ) fprintf( stdout, "Mandatory parameters:\n" ); fprintf( stdout, "---------------------\n" ); fprintf( stdout, "OutputConf : Output configuration: MONO, STEREO, 5_1, 7_1, 5_1_2, 5_1_4, 7_1_4, FOA,\n" ); - fprintf( stdout, " HOA2, HOA3, BINAURAL, BINAURAL_ROOM_IR, BINAURAL_ROOM_REVERB, EXT\n" ); + fprintf( stdout, " HOA2, HOA3, BINAURAL, BINAURAL_ROOM_IR, BINAURAL_ROOM_REVERB, BINAURAL_SPLIT_CODED, BINAURAL_SPLIT_PCM, EXT\n" ); fprintf( stdout, " By default, channel order and loudspeaker positions are equal to the\n" ); fprintf( stdout, " encoder. For loudspeaker outputs, OutputConf can be a custom loudspeaker\n" ); fprintf( stdout, " layout file. See readme.txt for details.\n" ); @@ -1518,6 +1592,7 @@ static void usage_dec( void ) fprintf( stdout, "-rvf File : Reference vector specified by external trajectory File\n" ); fprintf( stdout, " works only in combination with '-otr ref_vec' and 'ref_vec_lev' modes\n" ); fprintf( stdout, "-render_config File : Renderer configuration File\n" ); + fprintf( stdout, "-om File : Metadata output File for BINAURAL_SPLIT_PCM OutputConf (only for Fs = 48 kHz)\n" ); fprintf( stdout, "-non_diegetic_pan P : panning mono non-diegetic sound to stereo with paning P, -90<= P <=90,\n" ); fprintf( stdout, " left or l or 90->left, right or r or -90->right, center or c or 0->middle\n" ); #ifdef DEBUGGING @@ -1575,7 +1650,8 @@ static ivas_error initOnFirstGoodFrame( IVAS_DEC_HANDLE hIvasDec, /* i/o: */ const DecArguments arg, /* i : */ const int16_t numInitialBadFrames, /* i : */ - const uint16_t numOutSamples, /* i : */ + int16_t *numOutSamples, /* i/o: */ + int16_t *vec_pos_len, /* i/o: */ int16_t *pFullDelayNumSamples, /* o : */ int16_t *pRemainingDelayNumSamples, /* o : */ int32_t *delayTimeScale, /* o : */ @@ -1584,7 +1660,8 @@ static ivas_error initOnFirstGoodFrame( MasaFileWriter **ppMasaWriter, /* o : */ IsmFileWriter *ismWriters[IVAS_MAX_NUM_OBJECTS], /* o : */ int16_t *pNumOutChannels, /* o : */ - uint16_t *pNumObj /* o : */ + uint16_t *pNumObj, /* o : */ + SplitFileReadWrite **splitRendWriter ) { ivas_error error = IVAS_ERR_UNKNOWN; @@ -1596,6 +1673,10 @@ static ivas_error initOnFirstGoodFrame( return error; } + if ( arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { + pFullDelayNumSamples[0] = 0; + } if ( !arg.delayCompensationEnabled ) { @@ -1617,22 +1698,74 @@ static ivas_error initOnFirstGoodFrame( return error; } + if ( arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { + /* Open split rendering metadata writer */ + int16_t delayNumSamples_temp[3]; + int32_t delayTimeScale_temp; + + if ( ( error = IVAS_DEC_GetDelay( hIvasDec, delayNumSamples_temp, &delayTimeScale_temp ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nUnable to get delay of decoder: %s\n", ivas_error_to_string( error ) ); + return error; + } + + if ( arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) + { + if ( ( error = split_rend_writer_open( splitRendWriter, arg.outputWavFilename, delayNumSamples_temp[0], delayTimeScale_temp ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nUnable to open output split rendering metadata file %s\n", arg.outputWavFilename ); + return error; + } + } + else + { + if ( ( error = split_rend_writer_open( splitRendWriter, arg.outputMdFilename, delayNumSamples_temp[0], delayTimeScale_temp ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nUnable to open output split rendering metadata file %s\n", arg.outputWavFilename ); + return error; + } + } + } + + if ( arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) + { /* Open audio writer and write all previously skipped bad frames now that frame size is known */ if ( ( error = AudioFileWriter_open( ppAfWriter, arg.outputWavFilename, arg.output_Fs, *pNumOutChannels ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nUnable to open output file %s\n", arg.outputWavFilename ); return error; } + } int16_t *zeroBuf = malloc( pcmFrameSize * sizeof( int16_t ) ); memset( zeroBuf, 0, pcmFrameSize * sizeof( int16_t ) ); for ( int16_t i = 0; i < numInitialBadFrames; ++i ) { + if ( *splitRendWriter != NULL ) + { + IVAS_SPLIT_REND_BITS_DATA splitRendBitsZero; + splitRendBitsZero.bits_buf = NULL; + splitRendBitsZero.bits_read = 0; + splitRendBitsZero.bits_written = 0; + splitRendBitsZero.buf_len = 0; + splitRendBitsZero.codec = IVAS_SPLIT_REND_CODEC_DEFAULT; + splitRendBitsZero.pose_correction = IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE; + splitRendBitsZero.codec_frame_size_ms = 20; + + if ( split_rend_write_bitstream_to_file( *splitRendWriter, splitRendBitsZero.bits_buf, &splitRendBitsZero.bits_read, &splitRendBitsZero.bits_written, -1, IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE, splitRendBitsZero.codec_frame_size_ms ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nUnable to write to bitstream file!\n" ); + return error; + } + } + else + { - if ( *pRemainingDelayNumSamples < numOutSamples ) + if ( *pRemainingDelayNumSamples < *numOutSamples ) { - if ( ( error = AudioFileWriter_write( *ppAfWriter, zeroBuf, numOutSamples * *pNumOutChannels - ( *pRemainingDelayNumSamples * *pNumOutChannels ) ) ) != IVAS_ERR_OK ) + if ( ( error = AudioFileWriter_write( *ppAfWriter, zeroBuf, *numOutSamples * *pNumOutChannels - ( *pRemainingDelayNumSamples * *pNumOutChannels ) ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nOutput audio file writer error\n" ); return error; @@ -1641,8 +1774,9 @@ static ivas_error initOnFirstGoodFrame( } else { - *pRemainingDelayNumSamples -= numOutSamples; + *pRemainingDelayNumSamples -= *numOutSamples; } + } } free( zeroBuf ); @@ -1727,6 +1861,25 @@ static ivas_error initOnFirstGoodFrame( } } + if ( *splitRendWriter != NULL ) + { + if ( numOutSamples == NULL || vec_pos_len == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + /* real setting of the 5ms mode for split rendering is only known after the decoded first good frame, reset the variables needed in the main decoding loop accordingly here*/ + if ( ( error = IVAS_DEC_GetRenderFramesizeSamples( hIvasDec, numOutSamples ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError getting render frame size in samples\n" ); + return error; + } + if ( ( error = IVAS_DEC_GetReferencesUpdateFrequency( hIvasDec, vec_pos_len ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError getting render frame size in samples\n" ); + return error; + } + } return IVAS_ERR_OK; } @@ -1745,6 +1898,7 @@ static ivas_error decodeG192( RotFileReader *externalOrientationFileReader, RotFileReader *refRotReader, Vector3PairFileReader *referenceVectorReader, + uint8_t *splitRendBitsBuf, IVAS_DEC_HANDLE hIvasDec, int16_t *pcmBuf ) @@ -1780,6 +1934,7 @@ static ivas_error decodeG192( 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 } }; int16_t vec_pos_update, vec_pos_len; + SplitFileReadWrite *splitRendWriter = NULL; for ( i = 0; i < IVAS_MAX_NUM_OBJECTS; ++i ) { @@ -1914,6 +2069,21 @@ static ivas_error decodeG192( { IVAS_QUATERNION Quaternions[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES]; + if ( headRotReader == NULL ) + { + for ( i = 0; i < num_subframes; i++ ) + { + Quaternions[i].w = -3.0f; + Quaternions[i].x = 0.0f; + Quaternions[i].y = 0.0f; + Quaternions[i].z = 0.0f; + Pos[i].x = 0.0f; + Pos[i].y = 0.0f; + Pos[i].z = 0.0f; + } + } + else + { for ( i = 0; i < num_subframes; i++ ) { if ( ( error = HeadRotationFileReading( headRotReader, &Quaternions[i], &Pos[i] ) ) != IVAS_ERR_OK ) @@ -1922,10 +2092,11 @@ static ivas_error decodeG192( goto cleanup; } } + } for ( i = 0; i < num_subframes; i++ ) { - if ( ( error = IVAS_DEC_FeedHeadTrackData( hIvasDec, Quaternions[i], Pos[i], i ) ) != IVAS_ERR_OK ) + if ( ( error = IVAS_DEC_FeedHeadTrackData( hIvasDec, Quaternions[i], Pos[i], i, DEFAULT_AXIS ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nIVAS_DEC_FeedHeadTrackData failed: %s\n", IVAS_DEC_GetErrorMessage( error ) ); goto cleanup; @@ -2019,7 +2190,20 @@ static ivas_error decodeG192( } } - if ( ( error = IVAS_DEC_GetSamples( hIvasDec, nSamplesToRender, ( pcmBuf + nOutChannels * nSamplesRendered ), &nSamplesRendered_loop, &needNewFrame ) ) != IVAS_ERR_OK ) + if ( arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { + if ( ( error = IVAS_DEC_GetSplitBinauralBitstream( hIvasDec, (void *) ( pcmBuf + nOutChannels * nSamplesRendered ), splitRendBitsBuf, &nSamplesRendered_loop, &needNewFrame ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError in IVAS_DEC_GetSplitBinauralBitstream: %s\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + + nSamplesRendered += nSamplesRendered_loop; + nSamplesToRender -= nSamplesRendered_loop; + } + else + { + if ( ( error = IVAS_DEC_GetSamples( hIvasDec, nSamplesToRender, IVAS_DEC_PCM_INT16, (void *) ( pcmBuf + nOutChannels * nSamplesRendered ), &nSamplesRendered_loop, &needNewFrame ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nError in IVAS_DEC_GetSamples: %s\n", IVAS_DEC_GetErrorMessage( error ) ); @@ -2027,6 +2211,7 @@ static ivas_error decodeG192( } nSamplesRendered += nSamplesRendered_loop; nSamplesToRender -= nSamplesRendered_loop; + } if ( needNewFrame ) { frame++; @@ -2061,7 +2246,7 @@ static ivas_error decodeG192( /* Once good frame decoded, catch up */ if ( decodedGoodFrame ) { - if ( ( error = initOnFirstGoodFrame( hIvasDec, arg, numInitialBadFrames, nOutSamples, delayNumSamples_orig, &delayNumSamples, &delayTimeScale, &bsFormat, &afWriter, &masaWriter, ismWriters, &nOutChannels, &numObj ) ) != IVAS_ERR_OK ) + if ( ( error = initOnFirstGoodFrame( hIvasDec, arg, numInitialBadFrames, &nOutSamples, &vec_pos_len, delayNumSamples_orig, &delayNumSamples, &delayTimeScale, &bsFormat, &afWriter, &masaWriter, ismWriters, &nOutChannels, &numObj, &splitRendWriter ) ) != IVAS_ERR_OK ) { goto cleanup; } @@ -2075,6 +2260,25 @@ static ivas_error decodeG192( /* Write current frame */ if ( decodedGoodFrame ) { + if ( arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { + IVAS_SPLIT_REND_BITS_DATA splitRendBits; + + if ( ( error = IVAS_DEC_GetSplitRendBits( hIvasDec, &splitRendBits ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError in IVAS_DEC_SplitRendBits: %s\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; + } + + if ( split_rend_write_bitstream_to_file( splitRendWriter, splitRendBits.bits_buf, &splitRendBits.bits_read, &splitRendBits.bits_written, splitRendBits.codec, splitRendBits.pose_correction, splitRendBits.codec_frame_size_ms ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nUnable to write to bitstream file!\n" ); + goto cleanup; + } + } + + if ( arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) + { if ( delayNumSamples < nOutSamples ) { if ( ( error = AudioFileWriter_write( afWriter, &pcmBuf[delayNumSamples * nOutChannels], nOutSamples * nOutChannels - ( delayNumSamples * nOutChannels ) ) ) != IVAS_ERR_OK ) @@ -2088,6 +2292,7 @@ static ivas_error decodeG192( { delayNumSamples -= nOutSamples; } + } } /* Write ISm metadata to external file(s) */ @@ -2202,7 +2407,7 @@ static ivas_error decodeG192( goto cleanup; } - if ( ( error = IVAS_DEC_FeedHeadTrackData( hIvasDec, Quaternion, Pos[0], 0 ) ) != IVAS_ERR_OK ) + if ( ( error = IVAS_DEC_FeedHeadTrackData( hIvasDec, Quaternion, Pos[0], 0, DEFAULT_AXIS ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nIVAS_DEC_FeedHeadTrackData failed: %s\n", IVAS_DEC_GetErrorMessage( error ) ); goto cleanup; @@ -2210,7 +2415,7 @@ static ivas_error decodeG192( } /* decode and get samples */ - if ( ( error = IVAS_DEC_Flush( hIvasDec, nOutSamples, pcmBuf, &nSamplesFlushed ) ) != IVAS_ERR_OK ) + if ( ( error = IVAS_DEC_Flush( hIvasDec, nOutSamples, IVAS_DEC_PCM_INT16, (void *) pcmBuf, &nSamplesFlushed ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nError in IVAS_DEC_VoIP_Flush: %s\n", IVAS_DEC_GetErrorMessage( error ) ); goto cleanup; @@ -2320,11 +2525,14 @@ static ivas_error decodeG192( *------------------------------------------------------------------------------------------*/ memset( pcmBuf, 0, delayNumSamples_orig[0] * nOutChannels * sizeof( int16_t ) ); + if ( afWriter != NULL ) + { if ( ( error = AudioFileWriter_write( afWriter, pcmBuf, delayNumSamples_orig[0] * nOutChannels ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nError writing output file: %s\n", ivas_error_to_string( error ) ); goto cleanup; } + } /*------------------------------------------------------------------------------------------* * Close files and deallocate resources @@ -2334,6 +2542,7 @@ static ivas_error decodeG192( cleanup: + split_rend_reader_writer_close( &splitRendWriter ); AudioFileWriter_close( &afWriter ); MasaFileWriter_close( &masaWriter ); #ifdef DEBUGGING @@ -2685,6 +2894,21 @@ static ivas_error decodeVoIP( { IVAS_QUATERNION Quaternions[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES]; + if ( headRotReader == NULL ) + { + for ( i = 0; i < num_subframes; i++ ) + { + Quaternions[i].w = -3.0f; + Quaternions[i].x = 0.0f; + Quaternions[i].y = 0.0f; + Quaternions[i].z = 0.0f; + Pos[i].x = 0.0f; + Pos[i].y = 0.0f; + Pos[i].z = 0.0f; + } + } + else + { for ( i = 0; i < num_subframes; i++ ) { if ( ( error = HeadRotationFileReading( headRotReader, &Quaternions[i], &Pos[i] ) ) != IVAS_ERR_OK ) @@ -2694,10 +2918,13 @@ static ivas_error decodeVoIP( goto cleanup; } } + } for ( i = 0; i < num_subframes; i++ ) { if ( ( error = IVAS_DEC_FeedHeadTrackData( hIvasDec, Quaternions[i], Pos[i], i + , + DEFAULT_AXIS ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nIVAS_DEC_FeedHeadTrackData failed: %s\n", IVAS_DEC_GetErrorMessage( error ) ); @@ -2787,9 +3014,9 @@ static ivas_error decodeVoIP( /* decode and get samples */ #ifdef SUPPORT_JBM_TRACEFILE - if ( ( error = IVAS_DEC_VoIP_GetSamples( hIvasDec, nOutSamples, pcmBuf, systemTime_ms, writeJbmTraceFileFrameWrapper, jbmTraceWriter ) ) != IVAS_ERR_OK ) + if ( ( error = IVAS_DEC_VoIP_GetSamples( hIvasDec, nOutSamples, IVAS_DEC_PCM_INT16, (void *) pcmBuf, systemTime_ms, writeJbmTraceFileFrameWrapper, jbmTraceWriter ) ) != IVAS_ERR_OK ) #else - if ( ( error = IVAS_DEC_VoIP_GetSamples( hIvasDec, nOutSamples, pcmBuf, systemTime_ms ) ) != IVAS_ERR_OK ) + if ( ( error = IVAS_DEC_VoIP_GetSamples( hIvasDec, nOutSamples, IVAS_DEC_PCM_INT16, (void *) pcmBuf, systemTime_ms ) ) != IVAS_ERR_OK ) #endif { fprintf( stderr, "\nError in IVAS_DEC_VoIP_GetSamples: %s\n", IVAS_DEC_GetErrorMessage( error ) ); @@ -2826,8 +3053,10 @@ static ivas_error decodeVoIP( /* Once good frame decoded, catch up */ if ( decodedGoodFrame ) { - if ( ( error = initOnFirstGoodFrame( hIvasDec, arg, numInitialBadFrames, nOutSamples, delayNumSamples_orig, &delayNumSamples, &delayTimeScale, - &bsFormat, &afWriter, &masaWriter, ismWriters, &nOutChannels, &numObj ) ) != IVAS_ERR_OK ) + SplitFileReadWrite *splitRendWriter = NULL; + + if ( ( error = initOnFirstGoodFrame( hIvasDec, arg, numInitialBadFrames, &nOutSamples, NULL, delayNumSamples_orig, &delayNumSamples, &delayTimeScale, + &bsFormat, &afWriter, &masaWriter, ismWriters, &nOutChannels, &numObj, &splitRendWriter ) ) != IVAS_ERR_OK ) { goto cleanup; } diff --git a/apps/renderer.c b/apps/renderer.c index 24967f2cd..d289e85d8 100644 --- a/apps/renderer.c +++ b/apps/renderer.c @@ -433,8 +433,7 @@ static int16_t getTotalNumInChannels( IVAS_REND_InputId mcIds[RENDERER_MAX_MC_INPUTS], IVAS_REND_InputId ismIds[RENDERER_MAX_ISM_INPUTS], IVAS_REND_InputId sbaIds[RENDERER_MAX_SBA_INPUTS], - IVAS_REND_InputId masaIds[RENDERER_MAX_MASA_INPUTS] -) + IVAS_REND_InputId masaIds[RENDERER_MAX_MASA_INPUTS] ) { int16_t totalNumInChannels = 0; int16_t i, numInputChannels; @@ -520,8 +519,7 @@ static void setupWithSingleFormatInput( CmdlnArgs args, char *audioFilePath, IsmPositionProvider *positionProvider, - MasaFileReader **masaReaders -) + MasaFileReader **masaReaders ) { /* With single-format input, inputFilePath is the path to input audio file. */ strncpy( audioFilePath, args.inputFilePath, FILENAME_MAX - 1 ); @@ -580,8 +578,6 @@ static float dBToLin( } - - /*------------------------------------------------------------------------------------------* * main() * @@ -749,14 +745,14 @@ int main( } } - if ( AudioFileReader_open( &audioReader, audioFilePath ) != IVAS_ERR_OK ) - { - fprintf( stderr, "Error opening file: %s\n", audioFilePath ); - exit( -1 ); - } + if ( AudioFileReader_open( &audioReader, audioFilePath ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error opening file: %s\n", audioFilePath ); + exit( -1 ); + } int32_t inFileSampleRate = 0; - error = AudioFileReader_getSamplingRate( audioReader, &inFileSampleRate ); + error = AudioFileReader_getSamplingRate( audioReader, &inFileSampleRate ); switch ( error ) { @@ -786,12 +782,12 @@ int main( } int16_t inFileNumChannels = 0; - error = AudioFileReader_getNumChannels( audioReader, &inFileNumChannels ); - if ( error != IVAS_ERR_OK && error != IVAS_ERR_NUM_CHANNELS_UNKNOWN ) - { - fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); - exit( -1 ); - } + error = AudioFileReader_getNumChannels( audioReader, &inFileNumChannels ); + if ( error != IVAS_ERR_OK && error != IVAS_ERR_NUM_CHANNELS_UNKNOWN ) + { + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } const int16_t frameSize_smpls = (int16_t) ( ( args.render_framesize ) * args.sampleRate * 5 / ( 1000 ) ); if ( ( error = IVAS_REND_Open( &hIvasRend, args.sampleRate, args.outConfig.audioConfig, args.nonDiegeticPan, args.nonDiegeticPanGain, (int16_t) args.render_framesize ) ) != IVAS_ERR_OK ) @@ -855,7 +851,6 @@ int main( fprintf( stderr, "\nIVAS_DEC_FeedRenderConfig failed\n" ); exit( -1 ); } - } if ( ( error = IVAS_REND_SetOrientationTrackingMode( hIvasRend, args.orientation_tracking ) ) != IVAS_ERR_OK ) @@ -1091,11 +1086,11 @@ int main( } - if ( AudioFileWriter_open( &audioWriter, args.outputFilePath, args.sampleRate, numOutChannels ) != IVAS_ERR_OK ) - { - fprintf( stderr, "Failed to open file: %s\n", args.outputFilePath ); - exit( -1 ); - } + if ( AudioFileWriter_open( &audioWriter, args.outputFilePath, args.sampleRate, numOutChannels ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Failed to open file: %s\n", args.outputFilePath ); + exit( -1 ); + } inBufferSize = frameSize_smpls * totalNumInChannels; outBufferSize = frameSize_smpls * numOutChannels; @@ -1136,12 +1131,12 @@ int main( num_in_channels = inBuffer.config.numChannels; const bool isCurrentFrameMultipleOf20ms = frame % ( 4 / args.render_framesize ) == 0; - /* Read the input data */ - if ( ( error = AudioFileReader_read( audioReader, inpInt16Buffer, (int16_t) inBufferSize, &numSamplesRead ) ) != IVAS_ERR_OK ) - { - fprintf( stderr, "\nError reading from file %s\n", audioFilePath ); - exit( -1 ); - } + /* Read the input data */ + if ( ( error = AudioFileReader_read( audioReader, inpInt16Buffer, (int16_t) inBufferSize, &numSamplesRead ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError reading from file %s\n", audioFilePath ); + exit( -1 ); + } if ( numSamplesRead == 0 && splitBinNeedsNewFrame ) { @@ -1208,7 +1203,11 @@ int main( exit( -1 ); } +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( error = IVAS_REND_SetHeadRotation( hIvasRend, headRot, Pos, DEFAULT_AXIS, sf_idx ) ) != IVAS_ERR_OK ) +#else if ( ( error = IVAS_REND_SetHeadRotation( hIvasRend, headRot, Pos, sf_idx ) ) != IVAS_ERR_OK ) +#endif { fprintf( stderr, "Error setting Head Rotation: %s\n", ivas_error_to_string( error ) ); exit( -1 ); @@ -1366,12 +1365,11 @@ int main( } - - if ( ( error = IVAS_REND_GetSamples( hIvasRend, outBuffer ) ) != IVAS_ERR_OK ) - { + if ( ( error = IVAS_REND_GetSamples( hIvasRend, outBuffer ) ) != IVAS_ERR_OK ) + { fprintf( stderr, "Error in getting samples\n" ); - exit( -1 ); - } + exit( -1 ); + } int16_t num_out_channels; num_out_channels = outBuffer.config.numChannels; @@ -1400,19 +1398,19 @@ int main( zeroPad = delayNumSamples; } - if ( delayNumSamples * num_out_channels < outBufferSize ) - { - if ( AudioFileWriter_write( audioWriter, &outInt16Buffer[delayNumSamples * num_out_channels], outBufferSize - ( delayNumSamples * num_out_channels ) ) != IVAS_ERR_OK ) - { - fprintf( stderr, "Error writing audio file %s\n", args.outputFilePath ); - exit( -1 ); - } - delayNumSamples = 0; - } - else + if ( delayNumSamples * num_out_channels < outBufferSize ) + { + if ( AudioFileWriter_write( audioWriter, &outInt16Buffer[delayNumSamples * num_out_channels], outBufferSize - ( delayNumSamples * num_out_channels ) ) != IVAS_ERR_OK ) { - delayNumSamples -= (int16_t) ( outBufferSize / num_out_channels ); + fprintf( stderr, "Error writing audio file %s\n", args.outputFilePath ); + exit( -1 ); } + delayNumSamples = 0; + } + else + { + delayNumSamples -= (int16_t) ( outBufferSize / num_out_channels ); + } /* Write MASA metadata for MASA outputs */ if ( args.outConfig.audioConfig == IVAS_AUDIO_CONFIG_MASA1 || args.outConfig.audioConfig == IVAS_AUDIO_CONFIG_MASA2 ) @@ -1517,23 +1515,23 @@ int main( } /* add zeros at the end to have equal length of synthesized signals */ - for ( zeroPadToWrite = zeroPad; zeroPadToWrite > frameSize_smpls; zeroPadToWrite -= frameSize_smpls ) - { - memset( outInt16Buffer, 0, outBufferSize * sizeof( int16_t ) ); - if ( ( error = AudioFileWriter_write( audioWriter, outInt16Buffer, outBufferSize ) ) != IVAS_ERR_OK ) - { - fprintf( stderr, "\nOutput audio file writer error\n" ); - exit( -1 ); - } - } - - memset( outInt16Buffer, 0, zeroPadToWrite * outBuffer.config.numChannels * sizeof( int16_t ) ); - if ( ( error = AudioFileWriter_write( audioWriter, outInt16Buffer, zeroPadToWrite * outBuffer.config.numChannels ) ) != IVAS_ERR_OK ) + for ( zeroPadToWrite = zeroPad; zeroPadToWrite > frameSize_smpls; zeroPadToWrite -= frameSize_smpls ) + { + memset( outInt16Buffer, 0, outBufferSize * sizeof( int16_t ) ); + if ( ( error = AudioFileWriter_write( audioWriter, outInt16Buffer, outBufferSize ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nOutput audio file writer error\n" ); exit( -1 ); } - zeroPadToWrite = 0; + } + + memset( outInt16Buffer, 0, zeroPadToWrite * outBuffer.config.numChannels * sizeof( int16_t ) ); + if ( ( error = AudioFileWriter_write( audioWriter, outInt16Buffer, zeroPadToWrite * outBuffer.config.numChannels ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nOutput audio file writer error\n" ); + exit( -1 ); + } + zeroPadToWrite = 0; if ( args.inConfig.numAudioObjects != 0 && ( args.outConfig.audioConfig == IVAS_AUDIO_CONFIG_BINAURAL || args.outConfig.audioConfig == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ) @@ -3270,29 +3268,28 @@ static void convertInputBuffer( const int16_t numIntSamplesPerChannel, const int16_t numFloatSamplesPerChannel, const int16_t numChannels, - float *floatBuffer -) + float *floatBuffer ) { 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]; - } - else - { - floatBuffer[chnl * numFloatSamplesPerChannel + smpl] = 0.f; - } - - ++i; + floatBuffer[chnl * numFloatSamplesPerChannel + smpl] = (float) intBuffer[i]; } + else + { + floatBuffer[chnl * numFloatSamplesPerChannel + smpl] = 0.f; + } + + ++i; } + } return; } @@ -3308,33 +3305,32 @@ static void convertOutputBuffer( const float *floatBuffer, const int16_t numSamplesPerChannel, const int16_t numChannels, - int16_t *intBuffer -) + int16_t *intBuffer ) { int16_t chnl, smpl, i; float temp; i = 0; - for ( smpl = 0; smpl < numSamplesPerChannel; ++smpl ) + for ( smpl = 0; smpl < numSamplesPerChannel; ++smpl ) + { + for ( chnl = 0; chnl < numChannels; ++chnl ) { - for ( chnl = 0; chnl < numChannels; ++chnl ) + temp = floatBuffer[chnl * numSamplesPerChannel + smpl]; + temp = (float) floor( temp + 0.5f ); + if ( temp > IVAS_MAX16B_FLT ) { - temp = floatBuffer[chnl * numSamplesPerChannel + smpl]; - temp = (float) floor( temp + 0.5f ); - if ( temp > IVAS_MAX16B_FLT ) - { - temp = IVAS_MAX16B_FLT; - } - else if ( temp < IVAS_MIN16B_FLT ) - { - temp = IVAS_MIN16B_FLT; - } - intBuffer[i] = (int16_t) temp; - - ++i; + temp = IVAS_MAX16B_FLT; + } + else if ( temp < IVAS_MIN16B_FLT ) + { + temp = IVAS_MIN16B_FLT; } + intBuffer[i] = (int16_t) temp; + + ++i; } + } return; } diff --git a/lib_com/common_api_types.h b/lib_com/common_api_types.h index 4f1a452c6..132e829ed 100644 --- a/lib_com/common_api_types.h +++ b/lib_com/common_api_types.h @@ -147,7 +147,6 @@ typedef enum } IVAS_HEAD_ORIENT_TRK_T; -#ifdef NONBE_UNIFIED_DECODING_PATHS typedef enum { IVAS_RENDER_FRAMESIZE_UNKNOWN = 0, @@ -156,7 +155,6 @@ typedef enum IVAS_RENDER_FRAMESIZE_20MS = 4 } IVAS_RENDER_FRAMESIZE; -#endif typedef struct ivas_masa_metadata_frame_struct *IVAS_MASA_METADATA_HANDLE; typedef struct ivas_masa_decoder_ext_out_meta_struct *IVAS_MASA_DECODER_EXT_OUT_META_HANDLE; diff --git a/lib_com/ivas_cnst.h b/lib_com/ivas_cnst.h index d42cc57d9..1da90b5ac 100644 --- a/lib_com/ivas_cnst.h +++ b/lib_com/ivas_cnst.h @@ -1345,49 +1345,26 @@ typedef struct { unsigned short length[81]; } HUFF_ELEMENTS; -#ifdef FIX_891_PARAMUPMIX_CLEANUP typedef struct { HUFF_ELEMENTS df0; HUFF_ELEMENTS df; } HUFF_TABLE; -#else -typedef struct { - HUFF_ELEMENTS df0; - HUFF_ELEMENTS df; - HUFF_ELEMENTS dt; -} HUFF_TABLE; -#endif typedef enum { ALPHA, BETA } PAR_TYPE; -#ifndef FIX_891_PARAMUPMIX_CLEANUP -typedef enum { - FINE, - COARSE -} QUANT_TYPE; - -#endif typedef struct { int16_t nquant; int16_t offset; float data[35]; } ACPL_QUANT_TABLE; -#ifdef FIX_891_PARAMUPMIX_CLEANUP typedef struct { const int16_t (*alpha)[2]; const int16_t (*beta)[2]; } HUFF_NODE_TABLE; -#else -typedef struct -{ - const int16_t (*alpha[2])[2]; - const int16_t (*beta[2])[2]; -} HUFF_NODE_TABLE; -#endif /*----------------------------------------------------------------------------------* * Parametric MC Constants diff --git a/lib_com/ivas_dirac_com.c b/lib_com/ivas_dirac_com.c index bcf502033..a490858c8 100644 --- a/lib_com/ivas_dirac_com.c +++ b/lib_com/ivas_dirac_com.c @@ -163,10 +163,8 @@ ivas_error ivas_dirac_config( if ( ivas_format == SBA_FORMAT || ivas_format == SBA_ISM_FORMAT ) /* skip for MASA decoder */ { if ( ( error = ivas_dirac_sba_config( hQMetaData, element_mode, ivas_total_brate, sba_order, hConfig->nbands - spar_dirac_split_band -#ifdef NONBE_FIX_871_ACELP_CRASH_IN_OSBA , ivas_format -#endif ) ) != IVAS_ERR_OK ) { return error; @@ -325,10 +323,8 @@ void ivas_get_dirac_sba_max_md_bits( int16_t *metadata_max_bits, int16_t *qmetadata_max_bit_req, const int16_t nbands -#ifdef NONBE_FIX_871_ACELP_CRASH_IN_OSBA , IVAS_FORMAT ivas_format -#endif ) { if ( sba_total_brate <= IVAS_13k2 ) @@ -345,13 +341,11 @@ void ivas_get_dirac_sba_max_md_bits( { *bits_frame_nominal = ACELP_16k40 / FRAMES_PER_SEC; *metadata_max_bits = 103; -#ifdef NONBE_FIX_871_ACELP_CRASH_IN_OSBA /* OSBA needs an additional 2-bits safety margin to avoid acelp crashes */ if ( ivas_format == SBA_ISM_FORMAT ) { ( *metadata_max_bits ) -= 3; } -#endif } else if ( sba_total_brate <= IVAS_32k ) { @@ -407,10 +401,8 @@ ivas_error ivas_dirac_sba_config( int32_t sba_total_brate, /* i : SBA total bitrate */ const int16_t sba_order, /* i : Ambisonic (SBA) order */ const int16_t nbands /* i : number of frequency bands */ -#ifdef NONBE_FIX_871_ACELP_CRASH_IN_OSBA , IVAS_FORMAT ivas_format -#endif ) { int16_t nbands_coded; @@ -474,10 +466,8 @@ ivas_error ivas_dirac_sba_config( } ivas_get_dirac_sba_max_md_bits( sba_total_brate, &hQMetaData->bits_frame_nominal, &hQMetaData->metadata_max_bits, &hQMetaData->qmetadata_max_bit_req, hQMetaData->q_direction[0].cfg.nbands -#ifdef NONBE_FIX_871_ACELP_CRASH_IN_OSBA , ivas_format -#endif ); return error; diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index 473b716a7..815b3aff4 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -315,12 +315,7 @@ void stereo_dmx_evs_close_encoder( ivas_error ivas_dec( Decoder_Struct *st_ivas, /* i : IVAS decoder structure */ -#if( defined SPLIT_REND_WITH_HEAD_ROT && !defined NONBE_UNIFIED_DECODING_PATHS_FIX ) - const PCM_RESOLUTION pcm_resolution, /* i : type for the decoded PCM resolution */ - void *data /* o : output synthesis signal */ -#else int16_t *data /* o : output synthesis signal */ -#endif ); ivas_error ivas_dec_setup( @@ -1158,11 +1153,7 @@ int16_t ivas_ism_dtx_enc( int16_t *sid_flag /* o : indication of SID frame */ ); -#ifdef NONBE_FIX_898_ISM_BRATE_CRASH void ivas_ism_dtx_dec( -#else -ivas_error ivas_ism_dtx_dec( -#endif Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ int16_t *nb_bits_metadata /* o : number of metadata bits */ ); @@ -1458,11 +1449,7 @@ int16_t stereo_dft_sg_recovery( void stereo_dft_dec_res( CPE_DEC_HANDLE hCPE, /* i/o: decoder CPE handle */ -#ifdef FIX_887_ARRAY_SIZE_DFT_MDCT_STEREO float res_buf[STEREO_DFT_N_8k], /* i : residual buffer */ -#else - float res_buf[STEREO_DFT_BUF_MAX], /* i : residual buffer */ -#endif float *output /* o : output frame */ ); @@ -1470,11 +1457,7 @@ void stereo_dft_dec_res( int16_t res_bpf_adapt( STEREO_DFT_DEC_DATA_HANDLE hStereoDft, /* i/o: DFT stereo decoder handle */ const float *bpf_error_signal_8k, /* i : BPF modification signal */ -#ifdef FIX_887_ARRAY_SIZE_DFT_MDCT_STEREO float res_buf[STEREO_DFT_N_8k] /* i : residual buffer */ -#else - float res_buf[STEREO_DFT_BUF_MAX] /* i : residual buffer */ -#endif ); void bpf_pitch_coherence( @@ -1490,11 +1473,7 @@ void stereo_dft_dec_read_BS( STEREO_DFT_DEC_DATA_HANDLE hStereoDft, /* i/o: decoder DFT stereo handle */ const int16_t bwidth, /* i : bandwidth */ const int16_t output_frame, /* i : output frame length */ -#ifdef FIX_887_ARRAY_SIZE_DFT_MDCT_STEREO float res_buf[STEREO_DFT_N_8k], /* o : residual buffer */ -#else - float res_buf[STEREO_DFT_BUF_MAX], /* o : residual buffer */ -#endif int16_t *nb_bits, /* o : number of bits read */ float *coh, /* i/o: Coherence */ const int16_t ivas_format /* i : ivas format */ @@ -2266,19 +2245,10 @@ void EstimateStereoTCXNoiseLevel( void TNSAnalysisStereo( Encoder_State **sts, /* i : state handle */ -#ifdef FIX_887_ARRAY_SIZE_DFT_MDCT_STEREO float *mdst_spectrum[CPE_CHANNELS][NB_DIV], /* o : MDST spectrum */ -#else - float *mdst_spectrum[MCT_MAX_CHANNELS][NB_DIV], /* o : MDST spectrum */ -#endif const int16_t bWhitenedDomain, /* i : whitened domain flag */ -#ifdef FIX_887_ARRAY_SIZE_DFT_MDCT_STEREO int16_t tnsSize[CPE_CHANNELS][NB_DIV], /* i : number of tns parameters put into prm */ int16_t tnsBits[CPE_CHANNELS][NB_DIV], /* i : number of tns bits in the frame */ -#else - int16_t tnsSize[MCT_MAX_CHANNELS][NB_DIV], /* i : number of tns parameters put into prm */ - int16_t tnsBits[MCT_MAX_CHANNELS][NB_DIV], /* i : number of tns bits in the frame */ -#endif int16_t param_core[][NB_DIV * NPRM_DIV], /* o : quantized noise filling level */ const int16_t mct_on /* i : flag mct block (1) or stereo (0) */ ); @@ -2561,13 +2531,8 @@ void stereo_decoder_tcx( STEREO_MDCT_DEC_DATA *hStereoMdct, /* i/o: MDCT stereo decoder structure */ int16_t ms_mask[NB_DIV][MAX_SFB], /* i : bandwise MS mask */ float *spec_r_0[NB_DIV], /* i/o: spectrum right channel */ -#ifdef FIX_887_ARRAY_SIZE_DFT_MDCT_STEREO float *spec_l[], /* i/o: spectrum left channel [NB_DIV][N] */ float *spec_r[], /* i/o: spectrum right channel [NB_DIV][N] */ -#else - float *spec_l[NB_DIV], /* i/o: spectrum left channel */ - float *spec_r[NB_DIV], /* i/o: spectrum right channel */ -#endif const int16_t mdct_stereo_mode[], /* i : stereo mode (FB/band wise MS, dual mono */ const int16_t core_l, /* i : core for left channel (TCX20/TCX10) */ const int16_t core_r, /* i : core for right channel (TCX20/TCX10) */ @@ -3099,11 +3064,7 @@ void mctStereoIGF_enc( void ivas_mdct_dec_side_bits_frame_channel( CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ -#ifdef FIX_887_ARRAY_SIZE_DFT_MDCT_STEREO int16_t param_lpc[CPE_CHANNELS][NPRM_LPC_NEW], /* o : lpc_parameters */ -#else - int16_t param_lpc[MCT_MAX_CHANNELS][NPRM_LPC_NEW], /* o : lpc_parameters */ -#endif int16_t p_param[CPE_CHANNELS][NB_DIV], /* o : pointer to param buffer */ Decoder_State *st0, /* i : pointer to bitstream handle */ int16_t nTnsBitsTCX10[CPE_CHANNELS][NB_DIV], /* o : number of bits for TNS */ @@ -3682,10 +3643,8 @@ void ivas_get_dirac_sba_max_md_bits( int16_t *metadata_max_bits, int16_t *qmetadata_max_bit_req, const int16_t nbands -#ifdef NONBE_FIX_871_ACELP_CRASH_IN_OSBA , IVAS_FORMAT ivas_format -#endif ); ivas_error ivas_dirac_sba_config( @@ -3694,10 +3653,8 @@ ivas_error ivas_dirac_sba_config( int32_t sba_total_brate, /* i : SBA total bitrate */ const int16_t sba_order, /* i : Ambisonic (SBA) order */ const int16_t nbands /* i : number of frequency bands */ -#ifdef NONBE_FIX_871_ACELP_CRASH_IN_OSBA , IVAS_FORMAT ivas_format -#endif ); ivas_error ivas_dirac_dec_config( @@ -3733,14 +3690,6 @@ void ivas_dirac_dec_set_md_map( const int16_t nCldfbTs /* i : number of CLDFB time slots */ ); -#ifndef NONBE_UNIFIED_DECODING_PATHS_FIX -void ivas_dirac_dec( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - float *output_f[], /* i/o: synthesized core-coder transport channels/DirAC output */ - const int16_t nchan_transport, /* i : number of transport channels */ - const int16_t num_subframes /* i : number of subframes to render */ -); -#endif void ivas_dirac_dec_render( Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ const int16_t nchan_transport, /* i : number of transport channels */ @@ -3822,12 +3771,6 @@ void ivas_mc_paramupmix_enc_close( const int32_t input_Fs /* i : input sampling rate */ ); -#ifndef NONBE_UNIFIED_DECODING_PATHS_FIX -void ivas_mc_paramupmix_dec( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ - float *output_f[] /* i/o: synthesized core-coder transport channels/DirAC output */ -); -#endif ivas_error ivas_mc_paramupmix_dec_open( Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ ); @@ -4197,13 +4140,6 @@ void ivas_spar_config( const int16_t sid_format /* i : IVAS format indicator from SID frame */ ); -#ifndef NONBE_UNIFIED_DECODING_PATHS_FIX -ivas_error ivas_sba_upmixer_renderer( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder struct */ - float *output[], /* i/o: transport/output audio channels */ - const int16_t output_frame /* i : output frame length */ -); -#endif ivas_error ivas_sba_linear_renderer( float *output_f[], /* i/o: synthesized core-coder transport channels/DirAC output */ const int16_t output_frame, /* i : output frame length per channel */ @@ -5278,9 +5214,6 @@ void ivas_binRenderer( const MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, #endif COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i : combined head and external orientation handle */ -#ifndef NONBE_UNIFIED_DECODING_PATHS - int16_t subframe_idx, /* i : subframe index */ -#endif const int16_t numTimeSlots, /* i : number of time slots to process */ #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG HEAD_TRACK_DATA_HANDLE hPostRendHeadTrackData, @@ -5316,13 +5249,6 @@ void ivas_ism_renderer_close( ISM_RENDERER_HANDLE *hIsmRendererData /* i/o: ISM renderer handle */ ); -#ifndef NONBE_UNIFIED_DECODING_PATHS -void ivas_ism_render( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - float *output_f[], /* i/o: core-coder transport channels/object output */ - const int16_t output_frame /* i : output frame length per channel */ -); -#endif void ivas_ism_render_sf( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ float *output_f[], /* i/o: core-coder transport channels/object output */ @@ -5355,17 +5281,6 @@ void ivas_param_mc_mc2sba_cldfb( const float gain_lfe /* i : gain applied to LFE */ ); -#ifndef NONBE_UNIFIED_DECODING_PATHS_FIX -void ivas_ism2sba( - float *buffer_td[], /* i/o: TD signal buffers */ - ISM_RENDERER_HANDLE hIsmRendererData, /* i/o: renderer data */ - const ISM_METADATA_HANDLE hIsmMetaData[], /* i : object metadata */ - const int16_t nchan_ism, /* i : number of objects */ - const int16_t output_frame, /* i : output frame length per channel */ - const int16_t sba_order /* i : SBA order */ -); - -#endif void ivas_ism2sba_sf( float *buffer_in[], /* i : TC buffer */ float *buffer_out[], /* o : TD signal buffers */ @@ -5718,13 +5633,6 @@ ivas_error ivas_osba_dirac_td_binaural_jbm( float *output_f[] /* o : rendered time signal */ ); -#ifndef NONBE_UNIFIED_DECODING_PATHS_FIX -ivas_error ivas_osba_dirac_td_binaural( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - float *output[], /* o : output synthesis signal */ - const int16_t output_frame /* i : output frame length per channel */ -); -#endif ivas_error ivas_osba_ism_metadata_dec( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ @@ -5733,7 +5641,6 @@ ivas_error ivas_osba_ism_metadata_dec( int16_t nb_bits_metadata[] /* o : number of ISM metadata bits */ ); -#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX ivas_error ivas_osba_render_sf( Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ const uint16_t nSamplesAsked, /* i : number of CLDFB slots requested */ @@ -5741,13 +5648,6 @@ ivas_error ivas_osba_render_sf( uint16_t *nSamplesAvailableNext, /* o : number of CLDFB slots still to render */ float *output_f[] /* o : rendered time signal */ ); -#else -ivas_error ivas_osba_render( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - float *output_f[], /* i/o: core-coder transport channels/object output */ - const int16_t output_frame /* i : output frame length per channel */ -); -#endif void ivas_osba_data_close( SBA_ISM_DATA_HANDLE *hSbaIsmData /* i/o: OSBA rendering handle */ @@ -5886,13 +5786,6 @@ ivas_error ivas_omasa_ism_metadata_dec( int16_t nb_bits_metadata[] /* o : number of ISM metadata bits */ ); -#ifndef NONBE_UNIFIED_DECODING_PATHS -ivas_error ivas_omasa_dirac_td_binaural( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - float *output[], /* o : output synthesis signal */ - const int16_t output_frame /* i : output frame length per channel */ -); -#endif ivas_error ivas_omasa_dirac_td_binaural_jbm( Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ const uint16_t nSamplesAsked, /* i : number of samples requested */ @@ -5902,14 +5795,6 @@ ivas_error ivas_omasa_dirac_td_binaural_jbm( float *output_f[] /* o : rendered time signal */ ); -#ifndef NONBE_UNIFIED_DECODING_PATHS_FIX -void ivas_omasa_dirac_rend( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - float *output[], /* o : output synthesis signal */ - const int16_t output_frame /* i : output frame length per channel */ -); - -#endif void ivas_omasa_rearrange_channels( float *output[], /* o : output synthesis signal */ const int16_t nchan_transport_ism, /* i : number of ISM TCs */ @@ -5941,21 +5826,10 @@ void ivas_omasa_separate_object_renderer_close( Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ ); -#ifndef NONBE_UNIFIED_DECODING_PATHS_FIX -void ivas_omasa_separate_object_render( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - float input_f[][L_FRAME48k], /* i : separated object signal */ - float *output_f[], /* i/o: output signals */ - const int16_t output_frame /* i : output frame length per channel */ -); - -#endif void ivas_omasa_separate_object_render_jbm( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ const uint16_t nSamplesRendered, /* i : number of samples rendered */ -#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX float input_f[][L_FRAME48k], /* i : separated object signal */ -#endif float *output_f[], /* o : rendered time signal */ const int16_t subframes_rendered, /* i : number of subframes rendered */ const int16_t slots_rendered /* i : number of CLDFB slots rendered */ diff --git a/lib_com/ivas_rom_com.c b/lib_com/ivas_rom_com.c index 1ea974267..58dc6dc97 100644 --- a/lib_com/ivas_rom_com.c +++ b/lib_com/ivas_rom_com.c @@ -2518,17 +2518,6 @@ const uint16_t ivas_param_mc_sym_freq_ild_delta_combined_48_16bits[2 * PARAM_MC_ 1, 1, 1, 2, 24, 69, 122, 194, 285, 487, 690, 1173, 2255, 4709, 10599, 24635, 10862, 4709, 2204, 1059, 566, 330, 221, 150, 95, 59, 28, 2, 1, 1, 1 }; -#ifndef FIX_891_PARAMUPMIX_CLEANUP -/*----------------------------------------------------------------------------------* - * Parametric Upmix MC ROM tables - *----------------------------------------------------------------------------------*/ - -const int16_t ivas_param_upmx_mx_qmap[2][33] = -{ - { 0, 1, 2, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 3, 2, 1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 3, 2, 1, 0 }, - { 0, 1, 2, 3, 4, 3, 2, 1, 0, 1, 2, 3, 4, 3, 2, 1, 0 } -}; -#endif /*----------------------------------------------------------------------------------* * MASA ROM tables @@ -6459,7 +6448,6 @@ const int16_t sns_1st_means_32k[2][16] = * MC ParamUpmix ROM tables *-----------------------------------------------------------------------*/ -#ifdef FIX_891_PARAMUPMIX_CLEANUP const int16_t ivas_param_upmx_mx_qmap[33] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 3, 2, 1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 7, 6, 5, 4, 3, 2, 1, 0 @@ -6523,105 +6511,5 @@ const ACPL_QUANT_TABLE ivas_mc_paramupmix_beta_quant_table[9] = { +0.000000e+000f, +5.937500e-002f, +1.375000e-001f, +2.343750e-001f, +3.500000e-001f, +4.843750e-001f, +6.375000e-001f, +8.093750e-001f, +1.000000e+000f } /* data */ } }; -#else -const ACPL_QUANT_TABLE ivas_mc_paramupmix_alpha_quant_table[] = -{ - /* Alfa Fine */ - { - 33, /* nquant */ - 16, /* offset */ - { -2.000000e+000f, -1.809375e+000f, -1.637500e+000f, -1.484375e+000f, -1.350000e+000f, -1.234375e+000f, -1.137500e+000f, -1.059375e+000f, -1.000000e+000f, -9.406250e-001f, - -8.625000e-001f, -7.656250e-001f, -6.500000e-001f, -5.156250e-001f, -3.625000e-001f, -1.906250e-001f, +0.000000e+000f, +1.906250e-001f, +3.625000e-001f, +5.156250e-001f, - +6.500000e-001f, +7.656250e-001f, +8.625000e-001f, +9.406250e-001f, +1.000000e+000f, +1.059375e+000f, +1.137500e+000f, +1.234375e+000f, +1.350000e+000f, +1.484375e+000f, - +1.637500e+000f, +1.809375e+000f, +2.000000e+000f } /* data */ - }, - { /* Alfa Coarse */ - 17, /* nquant */ - 8, /* offset */ - { -2.000000e+000f, -1.637500e+000f, -1.350000e+000f, -1.137500e+000f, -1.000000e+000f, -8.625000e-001f, -6.500000e-001f, -3.625000e-001f, +0.000000e+000f, +3.625000e-001f, - +6.500000e-001f, +8.625000e-001f, +1.000000e+000f, +1.137500e+000f, +1.350000e+000f, +1.637500e+000f, +2.000000e+000f } /* data */ - } -}; - -const ACPL_QUANT_TABLE ivas_mc_paramupmix_beta_quant_table[2][9] = -{ - { - /* Beta Fine #1 */ - { - 9, /* nquant */ - 0, /* offset */ - { +0.000000e+000f, +2.375000e-001f, +5.500000e-001f, +9.375000e-001f, +1.400000e+000f, +1.937500e+000f, +2.550000e+000f, +3.237500e+000f, +4.000000e+000f } /* data */ - }, - { /* Beta Fine #2 */ - 9, /* nquant */ - 0, /* offset */ - { +0.000000e+000f, +2.035449e-001f, +4.713672e-001f, +8.034668e-001f, +1.199844e+000f, +1.660498e+000f, +2.185430e+000f, +2.774639e+000f, +3.428125e+000f } /* data */ - }, - { /* Beta Fine #3 */ - 9, /* nquant */ - 0, /* offset */ - { +0.000000e+000f, +1.729297e-001f, +4.004688e-001f, +6.826172e-001f, +1.019375e+000f, +1.410742e+000f, +1.856719e+000f, +2.357305e+000f, +2.912500e+000f } /* data */ - }, - { /* Beta Fine #4 */ - 9, /* nquant */ - 0, /* offset */ - { +0.000000e+000f, +1.456543e-001f, +3.373047e-001f, +5.749512e-001f, +8.585938e-001f, +1.188232e+000f, +1.563867e+000f, +1.985498e+000f, +2.453125e+000f } /* data */ - }, - { /* Beta Fine #5 */ - 9, /* nquant */ - 0, /* offset */ - { +0.000000e+000f, +1.217188e-001f, +2.818750e-001f, +4.804688e-001f, +7.175000e-001f, +9.929688e-001f, +1.306875e+000f, +1.659219e+000f, +2.050000e+000f } /* data */ - }, - { /* Beta Fine #6 */ - 9, /* nquant */ - 0, /* offset */ - { +0.000000e+000f, +1.011230e-001f, +2.341797e-001f, +3.991699e-001f, +5.960938e-001f, +8.249512e-001f, +1.085742e+000f, +1.378467e+000f, +1.703125e+000f } /* data */ - }, - { /* Beta Fine #7 */ - 9, /* nquant */ - 0, /* offset */ - { +0.000000e+000f, +8.386719e-002f, +1.942188e-001f, +3.310547e-001f, +4.943750e-001f, +6.841797e-001f, +9.004688e-001f, +1.143242e+000f, +1.412500e+000f } /* data */ - }, - { /* Beta Fine #8 */ - 9, /* nquant */ - 0, /* offset */ - { +0.000000e+000f, +6.995117e-002f, +1.619922e-001f, +2.761230e-001f, +4.123438e-001f, +5.706543e-001f, +7.510547e-001f, +9.535449e-001f, +1.178125e+000f } /* data */ - }, - { /* Beta Fine #9 */ - 9, /* nquant */ - 0, /* offset */ - { +0.000000e+000f, +5.937500e-002f, +1.375000e-001f, +2.343750e-001f, +3.500000e-001f, +4.843750e-001f, +6.375000e-001f, +8.093750e-001f, +1.000000e+000f } /* data */ - } - }, - { - /* Beta Coarse #1 */ - { - 5, /* nquant */ - 0, /* offset */ - { +0.000000e+000f, +5.500000e-001f, +1.400000e+000f, +2.550000e+000f, +4.000000e+000f } /* data */ - }, - { /* Beta Coarse #2 */ - 5, /* nquant */ - 0, /* offset */ - { +0.000000e+000f, +4.004688e-001f, +1.019375e+000f, +1.856719e+000f, +2.912500e+000f } /* data */ - }, - { /* Beta Coarse #3 */ - 5, /* nquant */ - 0, /* offset */ - { +0.000000e+000f, +2.818750e-001f, +7.175000e-001f, +1.306875e+000f, +2.050000e+000f } /* data */ - }, - { /* Beta Coarse #4 */ - 5, /* nquant */ - 0, /* offset */ - { +0.000000e+000f, +1.942188e-001f, +4.943750e-001f, +9.004688e-001f, +1.412500e+000f } /* data */ - }, - { /* Beta Coarse #5 */ - 5, /* nquant */ - 0, /* offset */ - { +0.000000e+000f, +1.375000e-001f, +3.500000e-001f, +6.375000e-001f, +1.000000e+000f } /* data */ - } - } -}; -#endif /* clang-format on */ diff --git a/lib_com/ivas_rom_com.h b/lib_com/ivas_rom_com.h index effc3f03e..f597fe8b9 100644 --- a/lib_com/ivas_rom_com.h +++ b/lib_com/ivas_rom_com.h @@ -259,12 +259,6 @@ extern const uint16_t ivas_param_mc_sym_freq_icc_combined_48_16bits[PARAM_MC_SZ_ extern const uint16_t ivas_param_mc_cum_freq_icc_delta_combined_48_16bits[2 * PARAM_MC_SZ_ICC_QUANTIZER]; extern const uint16_t ivas_param_mc_sym_freq_icc_delta_combined_48_16bits[2 * PARAM_MC_SZ_ICC_QUANTIZER - 1]; -#ifndef FIX_891_PARAMUPMIX_CLEANUP -/*----------------------------------------------------------------------------------* - * Parametric Upmix MC ROM tables - *----------------------------------------------------------------------------------*/ -extern const int16_t ivas_param_upmx_mx_qmap[2][33]; -#endif /*----------------------------------------------------------------------------------* * MASA ROM tables @@ -457,15 +451,10 @@ extern const int16_t sns_1st_means_32k[2][16]; /*----------------------------------------------------------------------* * MC ParamUpmix ROM tables *-----------------------------------------------------------------------*/ -#ifdef FIX_891_PARAMUPMIX_CLEANUP extern const int16_t ivas_param_upmx_mx_qmap[33]; extern const ACPL_QUANT_TABLE ivas_mc_paramupmix_alpha_quant_table; extern const ACPL_QUANT_TABLE ivas_mc_paramupmix_beta_quant_table[9]; -#else -extern const ACPL_QUANT_TABLE ivas_mc_paramupmix_alpha_quant_table[]; -extern const ACPL_QUANT_TABLE ivas_mc_paramupmix_beta_quant_table[2][9]; -#endif /* IVAS_ROM_COM_H */ #endif diff --git a/lib_com/tcx_ltp.c b/lib_com/tcx_ltp.c index 502328348..1711ad24b 100644 --- a/lib_com/tcx_ltp.c +++ b/lib_com/tcx_ltp.c @@ -740,11 +740,7 @@ static void tcx_ltp_synth_filter_11_unequal_pitch( gain = prev_gain; gain_step = -prev_gain / length; -#ifdef NONBE_FIX_856_TCX_LTP_SYNTH_FILTER for ( j = 0; j < length; j++ ) -#else - for ( j = 0; j < length + L; j++ ) -#endif { s = 0; s2 = 0; @@ -765,14 +761,9 @@ static void tcx_ltp_synth_filter_11_unequal_pitch( gain += gain_step; } -#ifdef NONBE_FIX_856_TCX_LTP_SYNTH_FILTER mvr2r( out - L, temp_buf, length + L ); mvr2r( in + length, temp_buf + length + L, L ); temp_ptr = &temp_buf[0] + L; -#else - mvr2r( out - MAX_TCX_LTP_FILTER_LEN, temp_buf, MAX_TRANSITION_LEN + 2 * MAX_TCX_LTP_FILTER_LEN ); - temp_ptr = &temp_buf[0] + MAX_TCX_LTP_FILTER_LEN; -#endif m0 = temp_ptr; m1 = temp_ptr - 1; diff --git a/lib_dec/bass_psfilter.c b/lib_dec/bass_psfilter.c index d1fc86e0e..09daa4ae9 100644 --- a/lib_dec/bass_psfilter.c +++ b/lib_dec/bass_psfilter.c @@ -522,11 +522,7 @@ void addBassPostFilter( int16_t res_bpf_adapt( STEREO_DFT_DEC_DATA_HANDLE hStereoDft, /* i/o: DFT stereo decoder handle */ const float *bpf_error_signal_8k, /* i : BPF modification signal */ -#ifdef FIX_887_ARRAY_SIZE_DFT_MDCT_STEREO float res_buf[STEREO_DFT_N_8k] /* i : residual buffer */ -#else - float res_buf[STEREO_DFT_BUF_MAX] /* i : residual buffer */ -#endif ) { float error_nrg; diff --git a/lib_dec/fd_cng_dec.c b/lib_dec/fd_cng_dec.c index 348cfd122..69d007825 100644 --- a/lib_dec/fd_cng_dec.c +++ b/lib_dec/fd_cng_dec.c @@ -1104,17 +1104,10 @@ void generate_comfort_noise_dec( c2 = (float) sqrt( 1 - hFdCngCom->coherence ); seed2 = &( hFdCngCom->seed2 ); -#ifdef NONBE_FIX_DISCRETE_ISM_NOISE_SEED_HANDLING if ( st->element_mode == IVAS_CPE_MDCT && st->idchan == 1 ) { seed2 = &( hFdCngCom->seed3 ); } -#else - if ( ( st->element_mode == IVAS_CPE_MDCT && st->idchan == 1 ) || ( st->element_mode == IVAS_SCE && st->cng_ism_flag ) ) - { - seed2 = &( hFdCngCom->seed3 ); - } -#endif /* Generate Gaussian random noise in real and imaginary parts of the FFT bins Amplitudes are adjusted to the estimated noise level cngNoiseLevel in each bin */ @@ -1366,11 +1359,7 @@ void generate_comfort_noise_dec_hf( if ( cng_coh_flag ) { -#ifdef NONBE_FIX_DISCRETE_ISM_NOISE_SEED_HANDLING seed2 = &( hFdCngCom->seed2 ); -#else - seed2 = &( hFdCngCom->seed3 ); -#endif c1 = (float) sqrt( hFdCngCom->coherence ); c2 = (float) sqrt( 1 - hFdCngCom->coherence ); diff --git a/lib_dec/ivas_core_dec.c b/lib_dec/ivas_core_dec.c index 8b802b127..639a7b636 100644 --- a/lib_dec/ivas_core_dec.c +++ b/lib_dec/ivas_core_dec.c @@ -112,11 +112,7 @@ ivas_error ivas_core_dec( sts = hSCE->hCoreCoder; hStereoICBWE = NULL; element_brate = hSCE->element_brate; -#ifdef FIX_902_HACK_IN_CORECODER last_element_brate = hSCE->last_element_brate; /* note: this parameter is unused */ -#else - last_element_brate = hSCE->element_brate; /* hack - the past parameter is not really needed */ -#endif last_element_mode = IVAS_SCE; hStereoTD = NULL; p_output_mem = NULL; diff --git a/lib_dec/ivas_corecoder_dec_reconfig.c b/lib_dec/ivas_corecoder_dec_reconfig.c index 14d7ce1dd..aaff963d5 100644 --- a/lib_dec/ivas_corecoder_dec_reconfig.c +++ b/lib_dec/ivas_corecoder_dec_reconfig.c @@ -64,10 +64,8 @@ ivas_error ivas_corecoder_dec_reconfig( MC_MODE last_mc_mode; DECODER_CONFIG_HANDLE hDecoderConfig; ivas_error error; -#ifdef NONBE_FIX_862_UBSAN_SPAR_DEC_BR_SW_PLC int16_t prev_bfi; Decoder_State *st0; -#endif /*-----------------------------------------------------------------* * Initialization @@ -145,10 +143,8 @@ ivas_error ivas_corecoder_dec_reconfig( } else { -#ifdef NONBE_FIX_862_UBSAN_SPAR_DEC_BR_SW_PLC st0 = ( nSCE_old > 0 ) ? st_ivas->hSCE[0]->hCoreCoder[0] : st_ivas->hCPE[0]->hCoreCoder[0]; prev_bfi = st0->prev_bfi; -#endif nSCE_existing = min( nSCE_old, st_ivas->nSCE ); nCPE_existing = min( nCPE_old, st_ivas->nCPE ); @@ -221,9 +217,7 @@ ivas_error ivas_corecoder_dec_reconfig( { return error; } -#ifdef NONBE_FIX_862_UBSAN_SPAR_DEC_BR_SW_PLC st_ivas->hSCE[sce_id]->hCoreCoder[0]->prev_bfi = prev_bfi; -#endif } if ( st_ivas->sba_dirac_stereo_flag && sba_dirac_stereo_flag_old && st_ivas->nchan_transport == 1 && nSCE_old == 0 ) { @@ -252,10 +246,8 @@ ivas_error ivas_corecoder_dec_reconfig( { return error; } -#ifdef NONBE_FIX_862_UBSAN_SPAR_DEC_BR_SW_PLC st_ivas->hCPE[cpe_id]->hCoreCoder[0]->prev_bfi = prev_bfi; st_ivas->hCPE[cpe_id]->hCoreCoder[1]->prev_bfi = prev_bfi; -#endif } if ( st_ivas->nCPE > 1 && nCPE_old <= 1 ) diff --git a/lib_dec/ivas_cpe_dec.c b/lib_dec/ivas_cpe_dec.c index 140b33622..1972c3262 100644 --- a/lib_dec/ivas_cpe_dec.c +++ b/lib_dec/ivas_cpe_dec.c @@ -248,10 +248,8 @@ ivas_error ivas_cpe_dec( { nb_bits -= SID_FORMAT_NBITS; sts[1]->bit_stream -= SID_FORMAT_NBITS; -#ifdef NONBE_FIX_878_RS_FEC_STEREO_CNG /* set total bitrate of Stereo CNG parameters for BER detection */ sts[1]->total_brate = IVAS_SID_5k2 - SID_2k40; -#endif } if ( ( ( st_ivas->ivas_format == MASA_FORMAT && ivas_total_brate < MASA_STEREO_MIN_BITRATE ) || ( st_ivas->ivas_format == MASA_ISM_FORMAT && cpe_brate < MASA_STEREO_MIN_BITRATE ) ) && ivas_total_brate > IVAS_SID_5k2 ) @@ -260,7 +258,6 @@ ivas_error ivas_cpe_dec( } else { -#ifdef NONBE_FIX_913_OMASA_BITBUDGET_VIOLATION if ( st_ivas->ivas_format == MASA_FORMAT || st_ivas->ivas_format == MASA_ISM_FORMAT ) { nb_bits -= nb_bits_metadata; @@ -270,7 +267,6 @@ ivas_error ivas_cpe_dec( } } -#endif stereo_dft_dec_read_BS( ivas_total_brate, hCPE->element_brate, &sts[0]->total_brate, sts[1], hCPE->hStereoDft, sts[0]->bwidth, output_frame, res_buf, &nb_bits, hCPE->hStereoCng->coh, st_ivas->ivas_format ); } diff --git a/lib_dec/ivas_dec.c b/lib_dec/ivas_dec.c index 7ed71d5d6..aeb2b1d06 100644 --- a/lib_dec/ivas_dec.c +++ b/lib_dec/ivas_dec.c @@ -51,7 +51,6 @@ * Principal IVAS decoder routine *--------------------------------------------------------------------------*/ -#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX ivas_error ivas_dec( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ int16_t *data /* o : output synthesis signal */ @@ -63,1121 +62,3 @@ ivas_error ivas_dec( return IVAS_ERR_OK; } -#else -ivas_error ivas_dec( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ -#ifdef SPLIT_REND_WITH_HEAD_ROT - const PCM_RESOLUTION pcm_resolution, /* i : type for the decoded PCM resolution */ - void *data /* o : output synthesis signal */ -#else - int16_t *data /* o : output synthesis signal */ -#endif -) -{ - int16_t n, output_frame, nchan_out; - Decoder_State *st; /* used for bitstream handling */ - float *p_output[MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS]; /* 'float' buffer for output synthesis */ - int16_t nchan_remapped; - int16_t nb_bits_metadata[MAX_SCE + 1]; - int32_t output_Fs, ivas_total_brate; - AUDIO_CONFIG output_config; - ivas_error error; - int16_t num_md_sub_frames; - int32_t ism_total_brate; -#ifdef SPLIT_REND_WITH_HEAD_ROT - int16_t nchan_out_syn_output; -#endif - - push_wmops( "ivas_dec" ); - - /*----------------------------------------------------------------* - * Initialization of local vars after struct has been set - *----------------------------------------------------------------*/ - - output_Fs = st_ivas->hDecoderConfig->output_Fs; - nchan_out = st_ivas->hDecoderConfig->nchan_out; - output_config = st_ivas->hDecoderConfig->output_config; - ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate; - - output_frame = (int16_t) ( output_Fs / FRAMES_PER_SEC ); - - for ( n = 0; n < MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS; n++ ) - { - p_output[n] = st_ivas->p_output_f[n]; - } - - /*----------------------------------------------------------------* - * Update combined orientation access index - *----------------------------------------------------------------*/ - -#ifndef NONBE_UNIFIED_DECODING_PATHS - if ( ( error = combine_external_and_head_orientations_dec( st_ivas->hHeadTrackData, st_ivas->hExtOrientationData, st_ivas->hCombinedOrientationData ) ) != IVAS_ERR_OK ) - { - return error; - } -#else - ivas_combined_orientation_set_to_start_index( st_ivas->hCombinedOrientationData ); -#endif - -#ifdef SPLIT_REND_WITH_HEAD_ROT - /*----------------------------------------------------------------* - * Binaural split rendering setup - *----------------------------------------------------------------*/ - - if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) - { - ivas_set_split_rend_ht_setup( &st_ivas->hSplitBinRend, st_ivas->hCombinedOrientationData ); - } - -#endif - /*----------------------------------------------------------------* - * Decoding + Rendering - *----------------------------------------------------------------*/ - - if ( st_ivas->bfi && st_ivas->ini_frame == 0 ) - { - for ( n = 0; n < nchan_out; n++ ) - { - /* note: these are intra-frame heap memories */ - if ( ( st_ivas->p_output_f[n] = (float *) malloc( ( 48000 / FRAMES_PER_SEC ) * sizeof( float ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for floating-point output audio buffer!\n" ) ); - } - p_output[n] = st_ivas->p_output_f[n]; - } - - /* zero output when first frame(s) is lost */ - for ( n = 0; n < nchan_out; n++ ) - { - set_f( p_output[n], 0.0f, output_frame ); - } - -#ifdef DEBUG_MODE_INFO - create_sce_dec( st_ivas, 0, ivas_total_brate ); - output_debug_mode_info_dec( st_ivas->hSCE[0]->hCoreCoder, 1, output_frame, NULL ); - destroy_sce_dec( st_ivas->hSCE[0] ); - st_ivas->hSCE[0] = NULL; -#endif - } - else if ( st_ivas->ivas_format == STEREO_FORMAT ) - { - st_ivas->hCPE[0]->element_brate = ivas_total_brate; - - if ( ( error = ivas_cpe_dec( st_ivas, 0, p_output, output_frame, 0 ) ) != IVAS_ERR_OK ) - { - return error; - } - - /* HP filtering */ - for ( n = 0; n < min( nchan_out, st_ivas->nchan_transport ); n++ ) - { - hp20( p_output[n], output_frame, st_ivas->mem_hp20_out[n], output_Fs ); - } - - /* Rendering */ - if ( st_ivas->renderer_type == RENDERER_MC ) - { - ivas_ls_setup_conversion( st_ivas, st_ivas->nchan_transport, output_frame, p_output, p_output ); - } - } - else if ( st_ivas->ivas_format == ISM_FORMAT ) - { - /* Metadata decoding and configuration */ - if ( ivas_total_brate == IVAS_SID_5k2 || ivas_total_brate == FRAME_NO_DATA ) - { -#ifdef NONBE_FIX_898_ISM_BRATE_CRASH - ivas_ism_dtx_dec( st_ivas, nb_bits_metadata ); -#else - if ( ( error = ivas_ism_dtx_dec( st_ivas, nb_bits_metadata ) ) != IVAS_ERR_OK ) - { - return error; - } -#endif - - /* decode dominant object first so the noise energy of the other objects can be limited */ - if ( ( error = ivas_sce_dec( st_ivas, st_ivas->hISMDTX.sce_id_dtx, &p_output[st_ivas->hISMDTX.sce_id_dtx], output_frame, nb_bits_metadata[st_ivas->hISMDTX.sce_id_dtx] ) ) != IVAS_ERR_OK ) - { - return error; - } - - ivas_ism_dtx_limit_noise_energy_for_near_silence( st_ivas->hSCE, st_ivas->hISMDTX.sce_id_dtx, st_ivas->nchan_transport ); - } - else if ( st_ivas->ism_mode == ISM_MODE_PARAM ) - { - if ( ( error = ivas_ism_metadata_dec( ivas_total_brate, st_ivas->nchan_ism, &( st_ivas->nchan_transport ), st_ivas->hIsmMetaData, st_ivas->hSCE, st_ivas->bfi, nb_bits_metadata, st_ivas->ism_mode, st_ivas->hISMDTX, st_ivas->hParamIsmDec->hParamIsm, &st_ivas->ism_extmeta_active, &st_ivas->ism_extmeta_cnt, st_ivas->hSCE[0]->hCoreCoder[0] ) ) != IVAS_ERR_OK ) - { - return error; - } - } - else /* ISM_MODE_DISC */ - { - if ( ( error = ivas_ism_metadata_dec( ivas_total_brate, st_ivas->nchan_ism, &( st_ivas->nchan_transport ), st_ivas->hIsmMetaData, st_ivas->hSCE, st_ivas->bfi, nb_bits_metadata, st_ivas->ism_mode, st_ivas->hISMDTX, NULL, &st_ivas->ism_extmeta_active, &st_ivas->ism_extmeta_cnt, st_ivas->hSCE[0]->hCoreCoder[0] ) ) != IVAS_ERR_OK ) - { - return error; - } - } - - for ( n = 0; n < st_ivas->nchan_transport; n++ ) - { - /* for DTX frames, dominant object has already been decoded before */ - if ( !( ( ivas_total_brate == IVAS_SID_5k2 || ivas_total_brate == FRAME_NO_DATA ) && n == st_ivas->hISMDTX.sce_id_dtx ) ) - { - if ( ( error = ivas_sce_dec( st_ivas, n, &p_output[n], output_frame, nb_bits_metadata[n] ) ) != IVAS_ERR_OK ) - { - return error; - } - } - - /* HP filtering */ - hp20( p_output[n], output_frame, st_ivas->mem_hp20_out[n], output_Fs ); - } - - /* Rendering */ - if ( st_ivas->ism_mode == ISM_MODE_PARAM ) - { - if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM || st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC ) - { - /* loudness correction */ - ivas_dirac_dec_binaural_sba_gain( p_output, st_ivas->nchan_transport, output_frame ); - - ivas_param_ism_params_to_masa_param_mapping( st_ivas ); - - ivas_dirac_dec_binaural( st_ivas, st_ivas->hCombinedOrientationData, p_output, st_ivas->nchan_transport, MAX_PARAM_SPATIAL_SUBFRAMES ); - } - else if ( st_ivas->renderer_type == RENDERER_MONO_DOWNMIX ) - { - ivas_mono_downmix_render_passive( st_ivas, p_output, output_frame ); - } - else if ( st_ivas->renderer_type == RENDERER_NON_DIEGETIC_DOWNMIX ) - { - ivas_apply_non_diegetic_panning( p_output, st_ivas->hDecoderConfig->non_diegetic_pan_gain, output_frame ); - } - else if ( st_ivas->renderer_type == RENDERER_PARAM_ISM || st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC ) - { - ivas_param_ism_dec( st_ivas, p_output ); - - if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC ) - { - /* Convert CICP19 -> Ambisonics */ - ivas_mc2sba( st_ivas->hIntSetup, p_output, p_output, output_frame, st_ivas->hOutSetup.ambisonics_order, 0.f ); - } - } - } - else /* ISM_MODE_DISC */ - { - /* Loudspeaker or Ambisonics rendering */ - if ( st_ivas->renderer_type == RENDERER_MONO_DOWNMIX ) - { - ivas_mono_downmix_render_passive( st_ivas, p_output, output_frame ); - } - else if ( st_ivas->renderer_type == RENDERER_NON_DIEGETIC_DOWNMIX ) - { - ivas_apply_non_diegetic_panning( p_output, st_ivas->hDecoderConfig->non_diegetic_pan_gain, output_frame ); - } - else if ( st_ivas->renderer_type == RENDERER_TD_PANNING || st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV_ROOM ) - { - /* Convert to CICPxx; used also for ISM->CICP19->binaural_room rendering */ - ivas_ism_render( st_ivas, p_output, output_frame ); - } -#ifdef DEBUGGING - else if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV ) -#else - else if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC ) -#endif - { - /* Convert to Ambisonics; used also for ISM->HOA3->binaural rendering */ - ivas_ism2sba( p_output, st_ivas->hIsmRendererData, st_ivas->hIsmMetaData, st_ivas->nchan_ism, output_frame, st_ivas->hIntSetup.ambisonics_order ); - } - - /* Binaural rendering */ - if ( st_ivas->renderer_type == RENDERER_BINAURAL_OBJECTS_TD ) - { -#ifdef SPLIT_REND_WITH_HEAD_ROT - if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) - { - if ( ( error = ObjRenderIvasFrame_splitBinaural( st_ivas, p_output, output_frame ) ) != IVAS_ERR_OK ) - { - return error; - } - } - else - { -#endif - if ( ( error = ivas_td_binaural_renderer( st_ivas, p_output, output_frame ) ) != IVAS_ERR_OK ) - { - return error; - } -#ifdef SPLIT_REND_WITH_HEAD_ROT - } -#endif - } - else if ( st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV_ROOM ) - { -#ifdef SPLIT_REND_WITH_HEAD_ROT - if ( ( error = ivas_rend_crendProcess( st_ivas->hCrendWrapper, IVAS_AUDIO_CONFIG_7_1_4, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR, NULL, NULL, NULL, NULL, p_output, output_Fs, MAX_PARAM_SPATIAL_SUBFRAMES, 0 ) ) != IVAS_ERR_OK ) -#else - if ( ( error = ivas_rend_crendProcess( st_ivas->hCrendWrapper, IVAS_AUDIO_CONFIG_7_1_4, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR, NULL, NULL, NULL, NULL, p_output, output_Fs, MAX_PARAM_SPATIAL_SUBFRAMES ) ) != IVAS_ERR_OK ) -#endif - { - return error; - } -#ifndef FIX_881_REMOVE_LFE_ADDITION_IN_ISM - ivas_binaural_add_LFE( st_ivas, output_frame, p_output, p_output ); -#endif - } -#ifdef DEBUGGING - else if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) - { - ivas_binaural_cldfb( st_ivas, p_output ); - } -#endif - } - } - else if ( st_ivas->ivas_format == SBA_FORMAT || st_ivas->ivas_format == MASA_FORMAT ) - { - set_s( nb_bits_metadata, 0, MAX_SCE ); - - /* read parameters from the bitstream */ - if ( st_ivas->ivas_format == MASA_FORMAT && st_ivas->hQMetaData != NULL ) - { - st = ( st_ivas->nSCE > 0 ) ? st_ivas->hSCE[0]->hCoreCoder[0] : st_ivas->hCPE[0]->hCoreCoder[0]; - - if ( ( error = ivas_masa_decode( st_ivas, st, &nb_bits_metadata[0] ) ) != IVAS_ERR_OK ) - { - return error; - } - } - else if ( st_ivas->ivas_format == SBA_FORMAT ) - { - if ( ( error = ivas_spar_dec( st_ivas, nb_bits_metadata ) ) != IVAS_ERR_OK ) - { - return error; - } - } - - if ( st_ivas->nchan_transport == CPE_CHANNELS && st_ivas->nCPE >= 1 ) - { - st_ivas->hCPE[0]->element_brate = ivas_total_brate; - } - - /* core-decoding of transport channels */ - if ( st_ivas->nSCE == 1 ) - { - if ( ( error = ivas_sce_dec( st_ivas, 0, &p_output[0], output_frame, nb_bits_metadata[0] ) ) != IVAS_ERR_OK ) - { - return error; - } - } - else if ( st_ivas->nCPE == 1 ) - { - if ( ( error = ivas_cpe_dec( st_ivas, 0, p_output, output_frame, nb_bits_metadata[0] ) ) != IVAS_ERR_OK ) - { - return error; - } - } - else if ( st_ivas->nCPE > 1 ) - { - if ( ( error = ivas_mct_dec( st_ivas, p_output, output_frame, nb_bits_metadata[0] ) ) != IVAS_ERR_OK ) - { - return error; - } - } -#ifdef DEBUG_LBR_SBA - /* SCE Decoder Output */ - for ( int16_t t = 0; t < 960; t++ ) - { - for ( int16_t c = 0; c < st_ivas->nchan_transport; c++ ) - { - float val = output[c][t] / MAX16B_FLT; - dbgwrite( &val, sizeof( float ), 1, 1, "int_dec_core_out.raw" ); - } - } -#endif -#ifdef DEBUG_SBA_AUDIO_DUMP - /* Dump audio signal after core-decoding */ - ivas_spar_dump_signal_wav( output_frame, NULL, output, st_ivas->nchan_transport, spar_foa_dec_wav[0], "core-decoding" ); -#endif - - /* TCs remapping */ - nchan_remapped = st_ivas->nchan_transport; - if ( st_ivas->sba_dirac_stereo_flag ) - { - nchan_remapped = nchan_out; - - if ( st_ivas->ivas_format == SBA_FORMAT ) - { - ivas_agc_dec_process( st_ivas->hSpar->hAgcDec, p_output, p_output, st_ivas->hSpar->hMdDec->spar_md_cfg.nchan_transport, output_frame ); - - if ( st_ivas->hSpar->hPCA != NULL ) - { - ivas_pca_dec( st_ivas->hSpar->hPCA, output_frame, st_ivas->hSpar->hMdDec->spar_md_cfg.nchan_transport, ivas_total_brate, st_ivas->hDecoderConfig->last_ivas_total_brate, st_ivas->bfi, p_output ); - } - - ivas_spar_dec_gen_umx_mat( st_ivas->hSpar->hMdDec, st_ivas->nchan_transport, IVAS_MAX_NUM_BANDS, st_ivas->bfi, ivas_get_spar_dec_md_num_subframes( st_ivas->sba_order, ivas_total_brate, st_ivas->last_active_ivas_total_brate ) ); - } - - ivas_sba_dirac_stereo_dec( st_ivas, p_output, output_frame, st_ivas->ivas_format == MC_FORMAT ); - } - else if ( st_ivas->ivas_format == MASA_FORMAT && ivas_total_brate < MASA_STEREO_MIN_BITRATE && ( ivas_total_brate > IVAS_SID_5k2 || ( ivas_total_brate <= IVAS_SID_5k2 && st_ivas->nCPE > 0 && st_ivas->hCPE[0]->nchan_out == 1 ) ) ) - { - nchan_remapped = 1; /* Only one channel transported */ - } - - /* HP filtering */ -#ifndef DEBUG_SPAR_BYPASS_EVS_CODEC - for ( n = 0; n < nchan_remapped; n++ ) - { - hp20( p_output[n], output_frame, st_ivas->mem_hp20_out[n], output_Fs ); - } -#endif - if ( st_ivas->ivas_format == SBA_FORMAT ) - { - nchan_remapped = ivas_sba_remapTCs( p_output, st_ivas, output_frame ); - - if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) - { - num_md_sub_frames = ivas_get_spar_dec_md_num_subframes( st_ivas->sba_analysis_order, ivas_total_brate, st_ivas->last_active_ivas_total_brate ); - ivas_sba_mix_matrix_determiner( st_ivas->hSpar, p_output, st_ivas->bfi, nchan_remapped, output_frame, num_md_sub_frames ); - } - else if ( st_ivas->renderer_type != RENDERER_DISABLE ) - { - ivas_spar_dec_agc_pca( st_ivas, p_output, output_frame ); - } - } - - if ( st_ivas->ivas_format == MASA_FORMAT ) - { - ivas_masa_prerender( st_ivas, p_output, output_frame, nchan_remapped ); - } - else if ( st_ivas->ivas_format == SBA_FORMAT && ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) ) - { - /* loudness correction */ - ivas_dirac_dec_binaural_sba_gain( p_output, nchan_remapped, output_frame ); - } - - /* Loudspeakers, Ambisonics or Binaural rendering */ - if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM || st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC ) - { - ivas_dirac_dec_binaural( st_ivas, st_ivas->hCombinedOrientationData, p_output, nchan_remapped, MAX_PARAM_SPATIAL_SUBFRAMES ); - } - else if ( st_ivas->ivas_format == MASA_FORMAT ) - { - if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_DEC ) - { - if ( ( error = ivas_sba_linear_renderer( p_output, output_frame, nchan_remapped, 0, output_config, st_ivas->hOutSetup ) ) != IVAS_ERR_OK ) - { - return error; - } - } - else if ( st_ivas->renderer_type == RENDERER_DIRAC ) - { - ivas_dirac_dec( st_ivas, p_output, nchan_remapped, MAX_PARAM_SPATIAL_SUBFRAMES ); - } - } - else if ( !st_ivas->sba_dirac_stereo_flag && nchan_out != 1 ) - { - if ( ( error = ivas_sba_upmixer_renderer( st_ivas, p_output, output_frame ) ) != IVAS_ERR_OK ) /* Note: ivas_sba_linear_renderer() or ivas_dirac_dec() are called internally */ - { - return error; - } - } - } - else if ( st_ivas->ivas_format == MASA_ISM_FORMAT ) - { - int16_t nchan_ism, nchan_transport_ism; - int16_t dirac_bs_md_write_idx; - - set_s( nb_bits_metadata, 0, MAX_SCE + 1 ); - - /* Set the number of objects for the parametric rendering */ - dirac_bs_md_write_idx = 0; - if ( st_ivas->hSpatParamRendCom != NULL ) - { - st_ivas->hSpatParamRendCom->numIsmDirections = 0; - if ( st_ivas->ism_mode != ISM_MASA_MODE_DISC && st_ivas->ism_mode != ISM_MASA_MODE_MASA_ONE_OBJ ) - { - st_ivas->hSpatParamRendCom->numIsmDirections = st_ivas->nchan_ism; - } - - dirac_bs_md_write_idx = st_ivas->hSpatParamRendCom->dirac_bs_md_write_idx; /* Store the write-index for this frame */ - } - - /* MASA metadata decoding */ - if ( ( error = ivas_masa_decode( st_ivas, st_ivas->hCPE[0]->hCoreCoder[0], &nb_bits_metadata[0] ) ) != IVAS_ERR_OK ) - { - return error; - } - - /* Configuration of combined-format bit-budget distribution */ - ivas_set_surplus_brate_dec( st_ivas, &ism_total_brate ); - - st_ivas->hCPE[0]->hCoreCoder[0]->bit_stream = &( st_ivas->bit_stream[( ism_total_brate / FRAMES_PER_SEC )] ); - - /* set ISM parameters and decode ISM metadata in OMASA format */ - if ( ( error = ivas_omasa_ism_metadata_dec( st_ivas, ism_total_brate, &nchan_ism, &nchan_transport_ism, dirac_bs_md_write_idx, &nb_bits_metadata[1] ) ) != IVAS_ERR_OK ) - { - return error; - } - - /* decode ISM channels */ - for ( n = 0; n < nchan_transport_ism; n++ ) - { - if ( ( error = ivas_sce_dec( st_ivas, n, &p_output[st_ivas->nchan_transport + n], output_frame, nb_bits_metadata[1] ) ) != IVAS_ERR_OK ) - { - return error; - } - } - - /* decode MASA channels */ - if ( ( error = ivas_cpe_dec( st_ivas, 0, p_output, output_frame, nb_bits_metadata[0] ) ) != IVAS_ERR_OK ) - { - return error; - } - - if ( st_ivas->hCPE[0]->nchan_out == 1 ) - { - mvr2r( p_output[0], p_output[1], output_frame ); /* Copy mono signal to stereo output channels */ - } - - /* HP filtering */ - for ( n = 0; n < getNumChanSynthesis( st_ivas ); n++ ) - { - hp20( p_output[n], output_frame, st_ivas->mem_hp20_out[n], output_Fs ); - } - - /* Rendering */ - if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM || st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC ) - { - if ( st_ivas->ism_mode == ISM_MASA_MODE_DISC && st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC ) - { - if ( ( error = ivas_omasa_dirac_td_binaural( st_ivas, p_output, output_frame ) ) != IVAS_ERR_OK ) - { - return error; - } - } - else - { - ivas_dirac_dec_binaural( st_ivas, st_ivas->hCombinedOrientationData, p_output, st_ivas->nchan_transport, MAX_PARAM_SPATIAL_SUBFRAMES ); - } - } - else if ( st_ivas->renderer_type == RENDERER_MONO_DOWNMIX ) - { - ivas_mono_downmix_render_passive( st_ivas, p_output, output_frame ); - } - else if ( st_ivas->renderer_type == RENDERER_DIRAC ) - { - ivas_omasa_dirac_rend( st_ivas, p_output, output_frame ); - } - - /* external output */ - if ( output_config == IVAS_AUDIO_CONFIG_EXTERNAL ) - { - /* sanity check in case of bitrate switching */ - if ( st_ivas->ism_mode != ISM_MASA_MODE_DISC ) - { - return IVAS_ERROR( IVAS_ERR_INVALID_OUTPUT_FORMAT, "Incorrect output configuration specified for combined MASA and ISM format" ); - } - - ivas_omasa_rearrange_channels( p_output, nchan_transport_ism, output_frame ); - } - } - else if ( st_ivas->ivas_format == SBA_ISM_FORMAT ) - { - int16_t nchan_ism, sba_ch_idx; - - set_s( nb_bits_metadata, 0, MAX_SCE + 1 ); - nchan_ism = st_ivas->nchan_ism; - if ( st_ivas->ism_mode == ISM_SBA_MODE_DISC ) - { - /* set ISM parameters and decode ISM metadata in OSBA format */ - if ( ( error = ivas_osba_ism_metadata_dec( st_ivas, ivas_total_brate, &nchan_ism, &nb_bits_metadata[1] ) ) != IVAS_ERR_OK ) - { - return error; - } - sba_ch_idx = st_ivas->nchan_ism; - } - else - { - nb_bits_metadata[1] += NO_BITS_MASA_ISM_NO_OBJ; - sba_ch_idx = 0; - } - - /* SBA metadata decoding */ - if ( ( error = ivas_spar_dec( st_ivas, nb_bits_metadata ) ) != IVAS_ERR_OK ) - { - return error; - } - - if ( st_ivas->nchan_transport == CPE_CHANNELS && st_ivas->nCPE >= 1 ) - { - st_ivas->hCPE[0]->element_brate = ivas_total_brate; - } - - /* core-decoding of transport channels */ - if ( st_ivas->nSCE == 1 ) - { - if ( ( error = ivas_sce_dec( st_ivas, 0, &p_output[0], output_frame, nb_bits_metadata[0] + nb_bits_metadata[1] ) ) != IVAS_ERR_OK ) - { - return error; - } - } - else if ( st_ivas->nCPE == 1 ) - { - if ( ( error = ivas_cpe_dec( st_ivas, 0, p_output, output_frame, nb_bits_metadata[0] + nb_bits_metadata[1] ) ) != IVAS_ERR_OK ) - { - return error; - } - } - else if ( st_ivas->nCPE > 1 ) - { - if ( ( error = ivas_mct_dec( st_ivas, p_output, output_frame, nb_bits_metadata[0] + nb_bits_metadata[1] ) ) != IVAS_ERR_OK ) - { - return error; - } - } - - if ( st_ivas->sba_dirac_stereo_flag ) - { - ivas_agc_dec_process( st_ivas->hSpar->hAgcDec, &p_output[sba_ch_idx], &p_output[sba_ch_idx], st_ivas->hSpar->hMdDec->spar_md_cfg.nchan_transport, output_frame ); - - if ( st_ivas->hSpar->hPCA != NULL ) - { - ivas_pca_dec( st_ivas->hSpar->hPCA, output_frame, st_ivas->hSpar->hMdDec->spar_md_cfg.nchan_transport, ivas_total_brate, st_ivas->hDecoderConfig->last_ivas_total_brate, st_ivas->bfi, &p_output[sba_ch_idx] ); - } - - ivas_spar_dec_gen_umx_mat( st_ivas->hSpar->hMdDec, st_ivas->nchan_transport, IVAS_MAX_NUM_BANDS, st_ivas->bfi, ivas_get_spar_dec_md_num_subframes( st_ivas->sba_order, ivas_total_brate, st_ivas->last_active_ivas_total_brate ) ); - - ivas_sba_dirac_stereo_dec( st_ivas, &p_output[sba_ch_idx], output_frame, 0 ); - } - - /* HP filtering */ - for ( n = 0; n < getNumChanSynthesis( st_ivas ); n++ ) - { - hp20( p_output[n], output_frame, st_ivas->mem_hp20_out[n], output_Fs ); - } - - nchan_remapped = ivas_sba_remapTCs( &p_output[sba_ch_idx], st_ivas, output_frame ); - -#ifdef DEBUG_OSBA - if ( st_ivas->ism_mode == ISM_SBA_MODE_DISC ) - { - int16_t nchan = st_ivas->nchan_transport + st_ivas->nchan_ism; - for ( int16_t t = 0; t < output_frame; t++ ) - { - for ( int16_t c = 0; c < nchan; c++ ) - { - int16_t val = (int16_t) ( output[c][t] + 0.5f ); - dbgwrite( &val, sizeof( int16_t ), 1, 1, "./res/TC_dec_core_out.raw" ); - } - } - } -#endif - if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) - { - num_md_sub_frames = ivas_get_spar_dec_md_num_subframes( st_ivas->sba_analysis_order, ivas_total_brate, st_ivas->last_active_ivas_total_brate ); - ivas_sba_mix_matrix_determiner( st_ivas->hSpar, &p_output[sba_ch_idx], st_ivas->bfi, nchan_remapped, output_frame, num_md_sub_frames ); - } - else if ( st_ivas->renderer_type != RENDERER_DISABLE ) - { - ivas_spar_dec_agc_pca( st_ivas, &p_output[sba_ch_idx], output_frame ); - } - - if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) - { - /* loudness correction */ - ivas_dirac_dec_binaural_sba_gain( &p_output[sba_ch_idx], nchan_remapped, output_frame ); - } - - /* Loudspeakers, Ambisonics or Binaural rendering */ - if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || - st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM || - st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC ) - { - ivas_dirac_dec_binaural( st_ivas, st_ivas->hCombinedOrientationData, &p_output[sba_ch_idx], nchan_remapped, MAX_PARAM_SPATIAL_SUBFRAMES ); - } - else if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV ) - { - if ( st_ivas->ism_mode == ISM_SBA_MODE_DISC ) - { - if ( ( error = ivas_osba_dirac_td_binaural( st_ivas, p_output, output_frame ) ) != IVAS_ERR_OK ) - { - return error; - } - } - else - { - ivas_sba_upmixer_renderer( st_ivas, &p_output[sba_ch_idx], output_frame ); - } - } - else if ( st_ivas->ism_mode == ISM_SBA_MODE_DISC && ( st_ivas->renderer_type == RENDERER_OSBA_STEREO || st_ivas->renderer_type == RENDERER_MONO_DOWNMIX ) ) - { - if ( st_ivas->renderer_type == RENDERER_MONO_DOWNMIX ) - { - ivas_mono_downmix_render_passive( st_ivas, p_output, output_frame ); - } - else /* stereo output */ - { - /* shift SBA channels to avoid overwrite by ISM upmix in 1 object case */ - if ( nchan_ism == 1 ) - { - mvr2r( p_output[2], p_output[3], output_frame ); - mvr2r( p_output[1], p_output[2], output_frame ); - } - - ivas_ism_render( st_ivas, p_output, output_frame ); - } - - for ( n = 0; n < nchan_out; n++ ) - { - v_add( p_output[n], p_output[n + max( nchan_out, nchan_ism )], p_output[n], output_frame ); - } - } - else if ( st_ivas->renderer_type == RENDERER_OSBA_AMBI || st_ivas->renderer_type == RENDERER_OSBA_LS ) - { - if ( ( error = ivas_osba_render( st_ivas, p_output, output_frame ) ) != IVAS_ERR_OK ) - { - return error; - } - } - else if ( output_config != IVAS_AUDIO_CONFIG_EXTERNAL && !st_ivas->sba_dirac_stereo_flag && nchan_out != 1 ) - { - if ( ( error = ivas_sba_upmixer_renderer( st_ivas, p_output, output_frame ) ) != IVAS_ERR_OK ) - { - return error; - } - } - else if ( output_config == IVAS_AUDIO_CONFIG_EXTERNAL ) /*EXT output = individual objects + HOA3*/ - { - if ( st_ivas->ism_mode == ISM_SBA_MODE_DISC ) - { - for ( n = 0; n < nchan_ism; n++ ) - { - delay_signal( p_output[n], output_frame, st_ivas->hSbaIsmData->delayBuffer[n], st_ivas->hSbaIsmData->delayBuffer_size ); - } - } - - if ( ( error = ivas_sba_upmixer_renderer( st_ivas, p_output, output_frame ) ) != IVAS_ERR_OK ) - { - return error; - } - - if ( st_ivas->ism_mode == ISM_MODE_NONE ) - { - for ( n = st_ivas->hIntSetup.nchan_out_woLFE - 1; n >= 0; n-- ) - { - mvr2r( p_output[n], p_output[n + nchan_ism], output_frame ); - } - - for ( n = 0; n < nchan_ism; n++ ) - { - set_zero( p_output[n], output_frame ); - } - } - } - } - else if ( st_ivas->ivas_format == MC_FORMAT ) - { - st = ( st_ivas->nSCE > 0 ) ? st_ivas->hSCE[0]->hCoreCoder[0] : st_ivas->hCPE[0]->hCoreCoder[0]; - - if ( st_ivas->mc_mode == MC_MODE_MCT ) - { - /* LFE channel decoder */ - ivas_lfe_dec( st_ivas->hLFE, st, output_frame, st_ivas->bfi, p_output[LFE_CHANNEL] ); - - if ( ( error = ivas_mct_dec( st_ivas, p_output, output_frame, 0 ) ) != IVAS_ERR_OK ) - { - return error; - } - - /* HP filtering */ - for ( n = 0; n < st_ivas->nchan_transport; n++ ) - { - if ( n != LFE_CHANNEL ) - { - hp20( p_output[n], output_frame, st_ivas->mem_hp20_out[n], output_Fs ); - } - } - - if ( st_ivas->transport_config != st_ivas->intern_config && ( st_ivas->intern_config == IVAS_AUDIO_CONFIG_FOA || st_ivas->intern_config == IVAS_AUDIO_CONFIG_HOA2 || st_ivas->intern_config == IVAS_AUDIO_CONFIG_HOA3 ) ) - { - ivas_mc2sba( st_ivas->hTransSetup, p_output, p_output, output_frame, st_ivas->hIntSetup.ambisonics_order, GAIN_LFE ); - } - - /* Rendering */ - if ( st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV || st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV_ROOM ) - { -#ifdef SPLIT_REND_WITH_HEAD_ROT - if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) - { - if ( ( error = ivas_rend_crendProcessSplitBin( st_ivas->hCrendWrapper, st_ivas->intern_config, st_ivas->hOutSetup.output_config, &st_ivas->hSplitBinRend.splitrend.multiBinPoseData, st_ivas->hDecoderConfig, - st_ivas->hCombinedOrientationData, &st_ivas->hIntSetup, st_ivas->hEFAPdata, p_output, output_Fs ) ) != IVAS_ERR_OK ) - { - return error; - } - } - else - { - if ( ( error = ivas_rend_crendProcess( st_ivas->hCrendWrapper, st_ivas->intern_config, st_ivas->hOutSetup.output_config, st_ivas->hDecoderConfig, - st_ivas->hCombinedOrientationData, &st_ivas->hIntSetup, st_ivas->hEFAPdata, p_output, output_Fs, MAX_PARAM_SPATIAL_SUBFRAMES, 0 ) ) != IVAS_ERR_OK ) -#else - if ( ( error = ivas_rend_crendProcess( st_ivas->hCrendWrapper, st_ivas->intern_config, st_ivas->hOutSetup.output_config, st_ivas->hDecoderConfig, - st_ivas->hCombinedOrientationData, &st_ivas->hIntSetup, st_ivas->hEFAPdata, p_output, output_Fs, MAX_PARAM_SPATIAL_SUBFRAMES ) ) != IVAS_ERR_OK ) -#endif - { - return error; - } - - ivas_binaural_add_LFE( st_ivas, output_frame, p_output, p_output ); -#ifdef SPLIT_REND_WITH_HEAD_ROT - } -#endif - } - else if ( st_ivas->renderer_type == RENDERER_MC ) - { - ivas_ls_setup_conversion( st_ivas, st_ivas->nchan_transport, output_frame, p_output, p_output ); - } - else if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC ) - { - ivas_mc2sba( st_ivas->hIntSetup, p_output, p_output, output_frame, st_ivas->hOutSetup.ambisonics_order, 0.f ); - } - else if ( st_ivas->renderer_type == RENDERER_BINAURAL_OBJECTS_TD ) - { -#ifdef SPLIT_REND_WITH_HEAD_ROT - if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) - { - if ( ( error = ObjRenderIvasFrame_splitBinaural( st_ivas, p_output, output_frame ) ) != IVAS_ERR_OK ) - { - return error; - } - } - else - { -#endif - if ( ( ivas_td_binaural_renderer( st_ivas, p_output, output_frame ) ) != IVAS_ERR_OK ) - { - return error; - } - - ivas_binaural_add_LFE( st_ivas, output_frame, p_output, p_output ); -#ifdef SPLIT_REND_WITH_HEAD_ROT - } -#endif - } - } - else if ( st_ivas->mc_mode == MC_MODE_PARAMUPMIX ) - { - ivas_lfe_dec( st_ivas->hLFE, st, output_frame, st_ivas->bfi, p_output[LFE_CHANNEL] ); - - ivas_mc_paramupmix_dec_read_BS( st_ivas, st, st_ivas->hMCParamUpmix, &nb_bits_metadata[0] ); - - if ( ( error = ivas_mct_dec( st_ivas, p_output, output_frame, nb_bits_metadata[0] ) ) != IVAS_ERR_OK ) - { - return error; - } - - /* HP filtering */ - for ( n = 0; n < st_ivas->nchan_transport; n++ ) - { - if ( n != LFE_CHANNEL ) - { - hp20( p_output[n], output_frame, st_ivas->mem_hp20_out[n], output_Fs ); - } - } - - ivas_mc_paramupmix_dec( st_ivas, p_output ); - - if ( st_ivas->transport_config != st_ivas->intern_config && - ( st_ivas->intern_config == IVAS_AUDIO_CONFIG_FOA || st_ivas->intern_config == IVAS_AUDIO_CONFIG_HOA2 || st_ivas->intern_config == IVAS_AUDIO_CONFIG_HOA3 ) && - ( output_config == IVAS_AUDIO_CONFIG_FOA || output_config == IVAS_AUDIO_CONFIG_HOA2 || output_config == IVAS_AUDIO_CONFIG_HOA3 ) ) - { - ivas_mc2sba( st_ivas->hTransSetup, p_output, p_output, output_frame, st_ivas->hIntSetup.ambisonics_order, GAIN_LFE ); - } - - /* Rendering */ - if ( ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) && !st_ivas->hDecoderConfig->Opt_Headrotation ) - { -#ifdef SPLIT_REND_WITH_HEAD_ROT - if ( output_config != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED && output_config != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) -#endif - { - ivas_binaural_add_LFE( st_ivas, output_frame, p_output, p_output ); - } - } - else if ( st_ivas->renderer_type == RENDERER_MC ) - { - if ( output_config == IVAS_AUDIO_CONFIG_MONO || output_config == IVAS_AUDIO_CONFIG_STEREO ) - { - ivas_ls_setup_conversion( st_ivas, audioCfg2channels( IVAS_AUDIO_CONFIG_5_1_2 ), output_frame, p_output, p_output ); - } - else - { - ivas_ls_setup_conversion( st_ivas, MC_PARAMUPMIX_MAX_INPUT_CHANS, output_frame, p_output, p_output ); - } - } - else if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC ) - { - ivas_mc2sba( st_ivas->hIntSetup, p_output, p_output, output_frame, st_ivas->hOutSetup.ambisonics_order, 0.f ); - } - else if ( st_ivas->renderer_type == RENDERER_BINAURAL_OBJECTS_TD ) - { -#ifdef SPLIT_REND_WITH_HEAD_ROT - if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) - { - if ( ( error = ObjRenderIvasFrame_splitBinaural( st_ivas, p_output, output_frame ) ) != IVAS_ERR_OK ) - { - return error; - } - } - else - { -#endif - if ( ( error = ivas_td_binaural_renderer( st_ivas, p_output, output_frame ) ) != IVAS_ERR_OK ) - { - return error; - } - - ivas_binaural_add_LFE( st_ivas, output_frame, p_output, p_output ); -#ifdef SPLIT_REND_WITH_HEAD_ROT - } -#endif - } - } - else if ( st_ivas->mc_mode == MC_MODE_PARAMMC ) - { - /* read Parametric MC parameters from the bitstream */ - ivas_param_mc_dec_read_BS( ivas_total_brate, st, st_ivas->hParamMC, &nb_bits_metadata[0] ); - - if ( st_ivas->nCPE == 1 ) - { - if ( ( error = ivas_cpe_dec( st_ivas, 0, p_output, output_frame, nb_bits_metadata[0] ) ) != IVAS_ERR_OK ) - { - return error; - } - } - else if ( st_ivas->nCPE > 1 ) - { - if ( ( error = ivas_mct_dec( st_ivas, p_output, output_frame, nb_bits_metadata[0] ) ) != IVAS_ERR_OK ) - { - return error; - } - } - - /* HP filtering */ - for ( n = 0; n < st_ivas->nchan_transport; n++ ) - { - hp20( p_output[n], output_frame, st_ivas->mem_hp20_out[n], output_Fs ); - } - - /* Rendering */ - if ( output_config == IVAS_AUDIO_CONFIG_MONO || output_config == IVAS_AUDIO_CONFIG_STEREO ) - { - ivas_ls_setup_conversion( st_ivas, st_ivas->nchan_transport, output_frame, p_output, p_output ); - } - else - { - ivas_param_mc_dec( st_ivas, p_output ); - } - } - else if ( st_ivas->mc_mode == MC_MODE_MCMASA ) - { - if ( st_ivas->hOutSetup.separateChannelEnabled ) - { - st = st_ivas->hCPE[0]->hCoreCoder[0]; /* Metadata is always with CPE in the case of separated channel */ - } - - /* read McMASA parameters from the bitstream */ - if ( ( error = ivas_masa_decode( st_ivas, st, &nb_bits_metadata[0] ) ) != IVAS_ERR_OK ) - { - return error; - } - - if ( st_ivas->hOutSetup.separateChannelEnabled ) - { - /* Decode the transport audio signals */ - if ( ( error = ivas_cpe_dec( st_ivas, 0, p_output, output_frame, nb_bits_metadata[0] ) ) != IVAS_ERR_OK ) - { - return error; - } - - /* Identify the index of the separated channel */ - n = st_ivas->hOutSetup.separateChannelIndex; - - /* Decode the separated channel to output[n] to be combined with the synthesized channels */ - if ( ( error = ivas_sce_dec( st_ivas, 0, &p_output[n], output_frame, 0 ) ) != IVAS_ERR_OK ) - { - return error; - } - - /* Delay the separated channel to sync with CLDFB delay of the DirAC synthesis, and synthesize the LFE signal. */ - if ( output_config == IVAS_AUDIO_CONFIG_5_1 || output_config == IVAS_AUDIO_CONFIG_7_1 || - output_config == IVAS_AUDIO_CONFIG_5_1_4 || output_config == IVAS_AUDIO_CONFIG_7_1_4 || - output_config == IVAS_AUDIO_CONFIG_5_1_2 || ( output_config == IVAS_AUDIO_CONFIG_LS_CUSTOM && st_ivas->hOutSetup.num_lfe > 0 ) ) - { - ivas_lfe_synth_with_filters( st_ivas->hMasa->hMasaLfeSynth, p_output, output_frame, n, LFE_CHANNEL ); - } - else if ( output_config == IVAS_AUDIO_CONFIG_LS_CUSTOM && st_ivas->hOutSetup.num_lfe == 0 ) - { - /* Delay the separated channel to sync with the DirAC rendering */ - delay_signal( p_output[n], output_frame, st_ivas->hMasa->hMasaLfeSynth->delayBuffer_syncDirAC, st_ivas->hMasa->hMasaLfeSynth->delayBuffer_syncDirAC_size ); - } - } - else - { - if ( st_ivas->nSCE == 1 ) - { - if ( ( error = ivas_sce_dec( st_ivas, 0, p_output, output_frame, nb_bits_metadata[0] ) ) != IVAS_ERR_OK ) - { - return error; - } - } - else if ( st_ivas->nCPE == 1 ) - { - if ( ( error = ivas_cpe_dec( st_ivas, 0, p_output, output_frame, nb_bits_metadata[0] ) ) != IVAS_ERR_OK ) - { - return error; - } - } - } - - if ( st_ivas->sba_dirac_stereo_flag ) /* use the flag to trigger the DFT upmix */ - { - ivas_sba_dirac_stereo_dec( st_ivas, p_output, output_frame, 1 ); - } - - /* HP filtering */ - for ( n = 0; n < getNumChanSynthesis( st_ivas ); n++ ) - { - hp20( p_output[n], output_frame, st_ivas->mem_hp20_out[n], output_Fs ); - } - - /* Rendering */ - if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM || st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC ) - { - ivas_dirac_dec_binaural( st_ivas, st_ivas->hCombinedOrientationData, p_output, st_ivas->nchan_transport, MAX_PARAM_SPATIAL_SUBFRAMES ); - } - else if ( st_ivas->renderer_type == RENDERER_DIRAC || st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC ) /* rendering to CICPxx and Ambisonics */ - { - ivas_dirac_dec( st_ivas, p_output, st_ivas->nchan_transport, MAX_PARAM_SPATIAL_SUBFRAMES ); - - if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC ) - { - ivas_mc2sba( st_ivas->hIntSetup, p_output, p_output, output_frame, st_ivas->hOutSetup.ambisonics_order, 0.f ); - } - else if ( st_ivas->intern_config == IVAS_AUDIO_CONFIG_5_1 && ( output_config == IVAS_AUDIO_CONFIG_5_1_2 || output_config == IVAS_AUDIO_CONFIG_5_1_4 || output_config == IVAS_AUDIO_CONFIG_7_1 ) ) - { - for ( n = st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe; n < st_ivas->hOutSetup.nchan_out_woLFE + st_ivas->hOutSetup.num_lfe; n++ ) - { - set_zero( p_output[n], output_frame ); - } - } - } - else if ( st_ivas->renderer_type == RENDERER_MCMASA_MONO_STEREO ) - { - ivas_mono_stereo_downmix_mcmasa( st_ivas, p_output, output_frame ); - } - } - } - - /*----------------------------------------------------------------* - * Write IVAS output channels - * - compensation for saturation - * - float to integer conversion - *----------------------------------------------------------------*/ - -#ifdef SPLIT_REND_WITH_HEAD_ROT - if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) - { - nchan_out_syn_output = BINAURAL_CHANNELS * st_ivas->hSplitBinRend.splitrend.multiBinPoseData.num_poses; - } - else - { - nchan_out_syn_output = nchan_out; - } - - if ( st_ivas->hDecoderConfig->Opt_Limiter ) -#endif - { -#ifndef DISABLE_LIMITER -#ifdef SPLIT_REND_WITH_HEAD_ROT - ivas_limiter_dec( st_ivas->hLimiter, p_output, nchan_out_syn_output, output_frame, st_ivas->BER_detect ); -#else - ivas_limiter_dec( st_ivas->hLimiter, p_output, nchan_out, output_frame, st_ivas->BER_detect ); -#endif -#endif - } - -#ifdef SPLIT_REND_WITH_HEAD_ROT - switch ( pcm_resolution ) - { - case PCM_INT16: -#endif -#ifdef DEBUGGING - st_ivas->noClipping += -#endif -#ifdef SPLIT_REND_WITH_HEAD_ROT - ivas_syn_output( p_output, output_frame, nchan_out_syn_output, (int16_t *) data ); -#else - ivas_syn_output( p_output, output_frame, nchan_out, data ); -#endif - -#ifdef SPLIT_REND_WITH_HEAD_ROT - break; - case PCM_FLOAT32: - ivas_syn_output_f( p_output, output_frame, nchan_out_syn_output, (float *) data ); - break; - default: - error = IVAS_ERR_UNKNOWN; - break; - } -#endif - - /*----------------------------------------------------------------* - * Common updates - *----------------------------------------------------------------*/ - - if ( !st_ivas->bfi ) /* do not update if first frame(s) are lost or NO_DATA */ - { - st_ivas->hDecoderConfig->last_ivas_total_brate = ivas_total_brate; - st_ivas->last_active_ivas_total_brate = ( ivas_total_brate <= IVAS_SID_5k2 ) ? st_ivas->last_active_ivas_total_brate : ivas_total_brate; - } - - if ( st_ivas->ini_frame < MAX_FRAME_COUNTER && !( st_ivas->bfi && st_ivas->ini_frame == 0 ) ) /* keep "st_ivas->ini_frame = 0" until first good received frame */ - { - st_ivas->ini_frame++; - } - - if ( st_ivas->ini_active_frame < MAX_FRAME_COUNTER && !( st_ivas->bfi && st_ivas->ini_frame == 0 ) && ivas_total_brate > IVAS_SID_5k2 ) /* needed in MASA decoder in case the first active frame is BFI, and there were SID-frames decoded before */ - { - st_ivas->ini_active_frame++; - } - - st_ivas->last_ivas_format = st_ivas->ivas_format; - -#ifdef NONBE_UNIFIED_DECODING_PATHS - /* update global combined orientation start index */ - ivas_combined_orientation_update_start_index( st_ivas->hCombinedOrientationData, output_frame ); -#endif - - /* in case first frame(s) was/were lost, deallocate output buffers */ - if ( st_ivas->bfi && st_ivas->ini_frame == 0 ) - { - for ( n = 0; n < nchan_out; n++ ) - { - free( st_ivas->p_output_f[n] ); - st_ivas->p_output_f[n] = NULL; - } - } - -#ifdef DEBUG_MODE_INFO - dbgwrite( &st_ivas->bfi, sizeof( int16_t ), 1, output_frame, "res/bfi" ); - dbgwrite( &st_ivas->BER_detect, sizeof( int16_t ), 1, output_frame, "res/BER_detect" ); - { - float tmpF = ivas_total_brate / 1000.0f; - dbgwrite( &tmpF, sizeof( float ), 1, output_frame, "res/ivas_total_brate.dec" ); - } -#endif - - pop_wmops(); - return IVAS_ERR_OK; -} -#endif diff --git a/lib_dec/ivas_dirac_dec.c b/lib_dec/ivas_dirac_dec.c index 25fc8d99f..bdc5e1827 100644 --- a/lib_dec/ivas_dirac_dec.c +++ b/lib_dec/ivas_dirac_dec.c @@ -949,40 +949,6 @@ ivas_error ivas_dirac_dec_config( } } -#ifndef NONBE_UNIFIED_DECODING_PATHS - /* Allocate transport channel buffers for SBA format when in JBM */ - if ( dec_config_flag == DIRAC_OPEN ) - { -#ifndef NONBE_UNIFIED_DECODING_PATHS - if ( st_ivas->hDecoderConfig->Opt_5ms && st_ivas->hTcBuffer == NULL ) -#else - if ( st_ivas->hTcBuffer == NULL ) -#endif - { - if ( st_ivas->ivas_format == SBA_FORMAT ) - { - int16_t nchan_to_allocate; - int16_t nchan_transport; - - nchan_transport = st_ivas->nchan_transport; - - nchan_to_allocate = nchan_transport; - if ( st_ivas->nchan_transport == 1 && ( ( st_ivas->renderer_type == RENDERER_DIRAC && st_ivas->hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD ) || ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) ) ) - { - nchan_to_allocate++; /* we need a channel for the CNG in this case*/ - } - if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) - { - nchan_to_allocate = 2 * BINAURAL_CHANNELS; - } - if ( ( error = ivas_jbm_dec_tc_buffer_open( st_ivas, TC_BUFFER_MODE_RENDERER, nchan_transport, nchan_to_allocate, nchan_to_allocate, st_ivas->hSpatParamRendCom->slot_size ) ) != IVAS_ERR_OK ) - { - return error; - } - } - } - } -#endif return error; } @@ -1590,86 +1556,6 @@ void ivas_dirac_dec_set_md_map( return; } -#ifndef NONBE_UNIFIED_DECODING_PATHS_FIX -/*------------------------------------------------------------------------- - * ivas_dirac_dec() - * - * DirAC decoding process - *------------------------------------------------------------------------*/ - -void ivas_dirac_dec( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - float *output_f[], /* i/o: synthesized core-coder transport channels/DirAC output */ - const int16_t nchan_transport, /* i : number of transport channels */ - const int16_t num_subframes /* i : number of subframes to render */ -) -{ - int16_t subframe_idx; - float *output_f_local[MAX_OUTPUT_CHANNELS]; - float cng_td_buffer[L_FRAME16k]; - int16_t nchan_out, n, n_samples_sf; - SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom; - - hSpatParamRendCom = st_ivas->hSpatParamRendCom; - nchan_out = st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe; - - n_samples_sf = JBM_CLDFB_SLOTS_IN_SUBFRAME * hSpatParamRendCom->slot_size; - - for ( n = 0; n < nchan_out; n++ ) - { - output_f_local[n] = output_f[n]; - } - - for ( n = 0; n < nchan_transport; n++ ) - { - st_ivas->hTcBuffer->tc[n] = output_f[n]; - } - - if ( st_ivas->nchan_transport == 1 && st_ivas->hSCE[0]->hCoreCoder[0] != NULL && st_ivas->hSCE[0]->hCoreCoder[0]->cna_dirac_flag && st_ivas->ivas_format != SBA_FORMAT ) - { - Decoder_State *st = st_ivas->hSCE[0]->hCoreCoder[0]; - st_ivas->hTcBuffer->tc[nchan_transport] = &cng_td_buffer[0]; - generate_masking_noise_lb_dirac( st->hFdCngDec->hFdCngCom, st_ivas->hTcBuffer->tc[1], DEFAULT_JBM_CLDFB_TIMESLOTS, st->cna_dirac_flag && st->flag_cna ); - } - - ivas_dirac_dec_set_md_map( st_ivas, DEFAULT_JBM_CLDFB_TIMESLOTS ); - - for ( subframe_idx = 0; subframe_idx < num_subframes; subframe_idx++ ) - { - ivas_dirac_dec_render_sf( st_ivas, output_f_local, nchan_transport, NULL, NULL ); - for ( n = 0; n < nchan_out; n++ ) - { - output_f_local[n] += n_samples_sf; - } - -#ifdef NONBE_UNIFIED_DECODING_PATHS - /* update combined orientation access index */ - ivas_combined_orientation_update_index( st_ivas->hCombinedOrientationData, n_samples_sf ); -#endif - } - - if ( st_ivas->hDirAC->hConfig->dec_param_estim == 1 ) - { - hSpatParamRendCom->dirac_read_idx = ( hSpatParamRendCom->dirac_read_idx + DEFAULT_JBM_CLDFB_TIMESLOTS ) % hSpatParamRendCom->dirac_md_buffer_length; - } - else - { - hSpatParamRendCom->dirac_read_idx = ( hSpatParamRendCom->dirac_read_idx + DEFAULT_JBM_SUBFRAMES_5MS ) % hSpatParamRendCom->dirac_md_buffer_length; - } - - for ( n = 0; n < nchan_transport; n++ ) - { - st_ivas->hTcBuffer->tc[n] = NULL; - } - - if ( st_ivas->nchan_transport == 1 && st_ivas->hSCE[0]->hCoreCoder[0] != NULL && st_ivas->hSCE[0]->hCoreCoder[0]->cna_dirac_flag && st_ivas->ivas_format != SBA_FORMAT ) - { - st_ivas->hTcBuffer->tc[nchan_transport] = NULL; - } - - return; -} -#endif /*------------------------------------------------------------------------- * ivas_dirac_dec_render() @@ -1690,9 +1576,7 @@ void ivas_dirac_dec_render( uint16_t slot_size, n_samples_sf, ch, nchan_intern; SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom; float *output_f_local[MAX_OUTPUT_CHANNELS]; -#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX float output_f_local_buff[MAX_OUTPUT_CHANNELS][L_FRAME48k]; // VE2SB: TBV -#endif hSpatParamRendCom = st_ivas->hSpatParamRendCom; @@ -1702,12 +1586,8 @@ void ivas_dirac_dec_render( #endif for ( ch = 0; ch < nchan_intern; ch++ ) { -#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX output_f_local[ch] = output_f_local_buff[ch]; set_zero( output_f_local_buff[ch], nSamplesAsked ); -#else - output_f_local[ch] = output_f[ch]; -#endif } slot_size = NS2SA( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ); @@ -1735,13 +1615,10 @@ void ivas_dirac_dec_render( output_f_local[ch] += n_samples_sf; } -#ifdef NONBE_UNIFIED_DECODING_PATHS /* update combined orientation access index */ ivas_combined_orientation_update_index( st_ivas->hCombinedOrientationData, n_samples_sf ); -#endif } -#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX for ( ch = 0; ch < nchan_intern; ch++ ) { if ( !( ( st_ivas->hDirACRend->hOutSetup.separateChannelEnabled ) && ( st_ivas->hDirACRend->hOutSetup.separateChannelIndex == ch || st_ivas->hDirACRend->hOutSetup.separateChannelIndex + 1 == ch ) ) ) @@ -1750,7 +1627,6 @@ void ivas_dirac_dec_render( } } -#endif if ( hSpatParamRendCom->slots_rendered == hSpatParamRendCom->num_slots ) { if ( st_ivas->hDirAC->hConfig->dec_param_estim == 1 ) @@ -1896,17 +1772,9 @@ void ivas_dirac_dec_render_sf( set_zero( onset_filter_subframe, hSpatParamRendCom->num_freq_bands ); } -#ifdef NONBE_UNIFIED_DECODING_PATHS if ( st_ivas->hCombinedOrientationData && st_ivas->hCombinedOrientationData->enableCombinedOrientation[st_ivas->hCombinedOrientationData->subframe_idx] ) -#else - if ( st_ivas->hCombinedOrientationData && st_ivas->hCombinedOrientationData->enableCombinedOrientation[subframe_idx] ) -#endif { -#ifdef NONBE_UNIFIED_DECODING_PATHS p_Rmat = &st_ivas->hCombinedOrientationData->Rmat[st_ivas->hCombinedOrientationData->subframe_idx][0][0]; -#else - p_Rmat = &st_ivas->hCombinedOrientationData->Rmat[subframe_idx][0][0]; -#endif if ( st_ivas->hCombinedOrientationData->shd_rot_max_order == 0 ) { num_freq_bands = hDirAC->band_grouping[hDirAC->hConfig->enc_param_start_band]; @@ -1970,11 +1838,7 @@ void ivas_dirac_dec_render_sf( } } -#ifdef NONBE_UNIFIED_DECODING_PATHS if ( st_ivas->hCombinedOrientationData && st_ivas->hCombinedOrientationData->enableCombinedOrientation[st_ivas->hCombinedOrientationData->subframe_idx] && st_ivas->hCombinedOrientationData->shd_rot_max_order == 1 ) -#else - if ( st_ivas->hCombinedOrientationData && st_ivas->hCombinedOrientationData->enableCombinedOrientation[subframe_idx] && st_ivas->hCombinedOrientationData->shd_rot_max_order == 1 ) -#endif { ivas_dirac_dec_compute_directional_responses( hSpatParamRendCom, hDirACRend, @@ -2101,11 +1965,7 @@ void ivas_dirac_dec_render_sf( if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD ) { -#ifdef NONBE_UNIFIED_DECODING_PATHS if ( st_ivas->hCombinedOrientationData && st_ivas->hCombinedOrientationData->enableCombinedOrientation[st_ivas->hCombinedOrientationData->subframe_idx] && st_ivas->hCombinedOrientationData->shd_rot_max_order == 0 ) -#else - if ( st_ivas->hCombinedOrientationData && st_ivas->hCombinedOrientationData->enableCombinedOrientation[subframe_idx] && st_ivas->hCombinedOrientationData->shd_rot_max_order == 0 ) -#endif { protoSignalComputation_shd( Cldfb_RealBuffer, Cldfb_ImagBuffer, hDirACRend->h_output_synthesis_psd_state.proto_direct_buffer_f, @@ -2337,11 +2197,7 @@ void ivas_dirac_dec_render_sf( } /*Compute PSDs*/ -#ifdef NONBE_UNIFIED_DECODING_PATHS if ( st_ivas->hCombinedOrientationData && st_ivas->hCombinedOrientationData->enableCombinedOrientation[st_ivas->hCombinedOrientationData->subframe_idx] && st_ivas->hCombinedOrientationData->shd_rot_max_order > 0 ) -#else - if ( st_ivas->hCombinedOrientationData && st_ivas->hCombinedOrientationData->enableCombinedOrientation[subframe_idx] && st_ivas->hCombinedOrientationData->shd_rot_max_order > 0 ) -#endif { ivas_dirac_dec_output_synthesis_process_slot( reference_power, p_onset_filter, @@ -2544,9 +2400,6 @@ void ivas_dirac_dec_render_sf( #endif st_ivas->hCombinedOrientationData, -#ifndef NONBE_UNIFIED_DECODING_PATHS - subframe_idx, -#endif hSpatParamRendCom->subframe_nbslots[subframe_idx], #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG NULL, diff --git a/lib_dec/ivas_init_dec.c b/lib_dec/ivas_init_dec.c index a2e53ceb0..dcf35207d 100644 --- a/lib_dec/ivas_init_dec.c +++ b/lib_dec/ivas_init_dec.c @@ -259,11 +259,7 @@ static ivas_error ivas_dec_init_split_rend( } #endif -#ifdef NONBE_UNIFIED_DECODING_PATHS error = ivas_split_renderer_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 == IVAS_RENDER_FRAMESIZE_5MS ); -#else - error = ivas_split_renderer_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->Opt_5ms ); -#endif return error; } @@ -357,11 +353,6 @@ ivas_error ivas_dec_setup( st_ivas->sba_order = st_ivas->bit_stream[num_bits_read + 1]; st_ivas->sba_order += 2 * st_ivas->bit_stream[num_bits_read]; -#ifndef NONBE_UNIFIED_DECODING_PATHS - /* set Ambisonic (SBA) order used for analysis and coding */ - st_ivas->sba_analysis_order = ivas_sba_get_analysis_order( ivas_total_brate, st_ivas->sba_order ); - -#endif num_bits_read += SBA_ORDER_BITS; if ( st_ivas->ini_frame > 0 && ivas_total_brate != st_ivas->last_active_ivas_total_brate && ivas_total_brate > IVAS_SID_5k2 ) { @@ -376,10 +367,8 @@ ivas_error ivas_dec_setup( } else { -#ifdef NONBE_UNIFIED_DECODING_PATHS /* set Ambisonic (SBA) order used for analysis and coding */ st_ivas->sba_analysis_order = ivas_sba_get_analysis_order( ivas_total_brate, st_ivas->sba_order ); -#endif ivas_sba_config( ivas_total_brate, st_ivas->sba_analysis_order, -1, &( st_ivas->nchan_transport ), st_ivas->sba_planar, &st_ivas->nSCE, &st_ivas->nCPE, &st_ivas->element_mode_init ); } @@ -636,15 +625,9 @@ ivas_error ivas_dec_setup( } } -#ifdef NONBE_FIX_898_ISM_BRATE_CRASH if ( st_ivas->ivas_format == ISM_FORMAT ) -#else - if ( st_ivas->ini_frame == 0 && st_ivas->ivas_format == ISM_FORMAT ) -#endif { -#ifdef NONBE_FIX_898_ISM_BRATE_CRASH ISM_MODE last_ism_mode = st_ivas->ism_mode; -#endif /* read the number of objects */ st_ivas->nchan_transport = 1; @@ -657,12 +640,10 @@ ivas_error ivas_dec_setup( } k--; -#ifdef NONBE_FIX_898_ISM_BRATE_CRASH if ( st_ivas->ini_frame > 0 && nchan_ism != st_ivas->nchan_ism ) { return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "wrong number of objects signalled!" ); } -#endif st_ivas->nchan_ism = nchan_ism; @@ -675,25 +656,15 @@ ivas_error ivas_dec_setup( st_ivas->ism_mode = (ISM_MODE) ( idx + 1 ); } -#ifdef NONBE_FIX_898_ISM_BRATE_CRASH if ( st_ivas->ini_frame == 0 ) { last_ism_mode = st_ivas->ism_mode; } -#endif #ifdef SPLIT_REND_WITH_HEAD_ROT -#ifdef NONBE_FIX_898_ISM_BRATE_CRASH if ( ( error = ivas_ism_dec_config( st_ivas, last_ism_mode, nSamplesRendered, pcm_resolution, data ) ) != IVAS_ERR_OK ) #else - if ( ( error = ivas_ism_dec_config( st_ivas, st_ivas->ism_mode, nSamplesRendered, pcm_resolution, data ) ) != IVAS_ERR_OK ) -#endif -#else -#ifdef NONBE_FIX_898_ISM_BRATE_CRASH if ( ( error = ivas_ism_dec_config( st_ivas, last_ism_mode, nSamplesRendered, data ) ) != IVAS_ERR_OK ) -#else - if ( ( error = ivas_ism_dec_config( st_ivas, st_ivas->ism_mode, nSamplesRendered, data ) ) != IVAS_ERR_OK ) -#endif #endif { return error; @@ -1053,11 +1024,7 @@ ivas_error ivas_init_decoder_front( if ( st_ivas->hDecoderConfig->Opt_ExternalOrientation ) { -#ifdef NONBE_UNIFIED_DECODING_PATHS if ( ( error = ivas_external_orientation_open( &( st_ivas->hExtOrientationData ), st_ivas->hDecoderConfig->render_framesize ) ) != IVAS_ERR_OK ) -#else - if ( ( error = ivas_external_orientation_open( &( st_ivas->hExtOrientationData ), ( st_ivas->hDecoderConfig->Opt_5ms ) ? 1 : MAX_PARAM_SPATIAL_SUBFRAMES ) ) != IVAS_ERR_OK ) -#endif { return error; } @@ -1069,11 +1036,7 @@ ivas_error ivas_init_decoder_front( if ( st_ivas->hDecoderConfig->Opt_Headrotation || st_ivas->hDecoderConfig->Opt_ExternalOrientation ) { -#ifdef NONBE_UNIFIED_DECODING_PATHS if ( ( error = ivas_combined_orientation_open( &( st_ivas->hCombinedOrientationData ), st_ivas->hDecoderConfig->output_Fs, st_ivas->hDecoderConfig->render_framesize ) ) != IVAS_ERR_OK ) -#else - if ( ( error = ivas_combined_orientation_open( &( st_ivas->hCombinedOrientationData ), ( st_ivas->hDecoderConfig->Opt_5ms ) ? 1 : MAX_PARAM_SPATIAL_SUBFRAMES ) ) != IVAS_ERR_OK ) -#endif { return error; } @@ -1361,7 +1324,6 @@ ivas_error ivas_init_decoder( st_ivas->hISMDTX.sce_id_dtx = 0; -#ifdef NONBE_FIX_DISCRETE_ISM_NOISE_SEED_HANDLING if ( st_ivas->ism_mode == ISM_MODE_PARAM ) { st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->seed2 = st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->seed3; @@ -1373,12 +1335,6 @@ ivas_error ivas_init_decoder( st_ivas->hSCE[sce_id]->hCoreCoder[0]->hFdCngDec->hFdCngCom->seed2 = 2 + sce_id; } } -#else - if ( st_ivas->ism_mode == ISM_MODE_PARAM ) - { - st_ivas->hSCE[1]->hCoreCoder[0]->hFdCngDec->hFdCngCom->seed3 = st_ivas->hSCE[0]->hCoreCoder[0]->hFdCngDec->hFdCngCom->seed2; - } -#endif } else if ( st_ivas->ivas_format == SBA_FORMAT ) { @@ -1401,10 +1357,8 @@ ivas_error ivas_init_decoder( } if ( ( error = ivas_dirac_sba_config( st_ivas->hQMetaData, &st_ivas->element_mode_init, ivas_total_brate, st_ivas->sba_analysis_order, ivas_get_hodirac_flag( ivas_total_brate, st_ivas->sba_analysis_order ) ? IVAS_MAX_NUM_BANDS : ( IVAS_MAX_NUM_BANDS - SPAR_DIRAC_SPLIT_START_BAND ) -#ifdef NONBE_FIX_871_ACELP_CRASH_IN_OSBA , st_ivas->ivas_format -#endif ) ) != IVAS_ERR_OK ) { return error; @@ -1559,10 +1513,8 @@ ivas_error ivas_init_decoder( } if ( ( error = ivas_dirac_sba_config( st_ivas->hQMetaData, &st_ivas->element_mode_init, ivas_total_brate, st_ivas->sba_analysis_order, ivas_get_hodirac_flag( ivas_total_brate, st_ivas->sba_analysis_order ) ? IVAS_MAX_NUM_BANDS : ( IVAS_MAX_NUM_BANDS - SPAR_DIRAC_SPLIT_START_BAND ) -#ifdef NONBE_FIX_871_ACELP_CRASH_IN_OSBA , st_ivas->ivas_format -#endif ) ) != IVAS_ERR_OK ) { return error; @@ -2028,10 +1980,6 @@ ivas_error ivas_init_decoder( } } -#ifndef NONBE_UNIFIED_DECODING_PATHS - if ( st_ivas->hDecoderConfig->Opt_5ms ) - { -#endif granularity = NS2SA( st_ivas->hDecoderConfig->output_Fs, FRAME_SIZE_NS / MAX_PARAM_SPATIAL_SUBFRAMES ); n_channels_transport_jbm = ivas_jbm_dec_get_num_tc_channels( st_ivas ); @@ -2039,9 +1987,6 @@ ivas_error ivas_init_decoder( { return error; } -#ifndef NONBE_UNIFIED_DECODING_PATHS - } -#endif } else if ( st_ivas->renderer_type == RENDERER_MC ) { @@ -2080,10 +2025,6 @@ ivas_error ivas_init_decoder( st_ivas->binaural_latency_ns = st_ivas->hCrendWrapper->binaural_latency_ns; -#ifndef NONBE_UNIFIED_DECODING_PATHS - if ( st_ivas->hDecoderConfig->Opt_5ms ) - { -#endif if ( ( st_ivas->ivas_format == MC_FORMAT ) && ( st_ivas->mc_mode == MC_MODE_PARAMUPMIX ) ) { granularity = NS2SA( output_Fs, CLDFB_SLOT_NS ); @@ -2106,9 +2047,6 @@ ivas_error ivas_init_decoder( return error; } } -#ifndef NONBE_UNIFIED_DECODING_PATHS - } -#endif } if ( st_ivas->ivas_format == MASA_ISM_FORMAT ) @@ -2251,11 +2189,7 @@ ivas_error ivas_init_decoder( * Allocate and initialize JBM struct + buffer *-----------------------------------------------------------------*/ -#ifndef NONBE_UNIFIED_DECODING_PATHS - if ( st_ivas->hDecoderConfig->Opt_5ms && st_ivas->hTcBuffer == NULL ) -#else if ( st_ivas->hTcBuffer == NULL ) -#endif { /* no module has yet open the TC buffer, open a default one */ @@ -2291,10 +2225,6 @@ ivas_error ivas_init_decoder( * Allocate floating-point output audio buffers *-----------------------------------------------------------------*/ -#ifndef NONBE_UNIFIED_DECODING_PATHS - if ( !st_ivas->hDecoderConfig->Opt_5ms ) - { -#endif for ( n = 0; n < ivas_get_nchan_buffers_dec( st_ivas, st_ivas->sba_analysis_order, st_ivas->hDecoderConfig->ivas_total_brate ); n++ ) { /* note: these are intra-frame heap memories */ @@ -2303,13 +2233,6 @@ ivas_error ivas_init_decoder( return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for floating-point output audio buffer!\n" ) ); } } -#ifndef NONBE_UNIFIED_DECODING_PATHS - } - else - { - n = 0; - } -#endif for ( ; n < MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS; n++ ) { diff --git a/lib_dec/ivas_ism_dec.c b/lib_dec/ivas_ism_dec.c index 7d22eb50b..52349b9e6 100644 --- a/lib_dec/ivas_ism_dec.c +++ b/lib_dec/ivas_ism_dec.c @@ -128,9 +128,6 @@ static ivas_error ivas_ism_bitrate_switching_dec( ivas_output_init( &( st_ivas->hIntSetup ), st_ivas->hDecoderConfig->output_config ); } -#ifndef NONBE_UNIFIED_DECODING_PATHS - if ( st_ivas->hDecoderConfig->Opt_5ms ) -#endif { /* transfer subframe info from DirAC or ParamMC to central tc buffer */ if ( last_ism_mode == ISM_MODE_PARAM && st_ivas->hSpatParamRendCom != NULL && ( st_ivas->renderer_type != RENDERER_MONO_DOWNMIX && st_ivas->renderer_type != RENDERER_DISABLE ) ) @@ -324,9 +321,6 @@ static ivas_error ivas_ism_bitrate_switching_dec( * floating-point output audio buffers *-----------------------------------------------------------------*/ -#ifndef NONBE_UNIFIED_DECODING_PATHS - if ( !st_ivas->hDecoderConfig->Opt_5ms ) -#endif { nchan_out_buff = ivas_get_nchan_buffers_dec( st_ivas, -1, -1 ); @@ -339,9 +333,6 @@ static ivas_error ivas_ism_bitrate_switching_dec( /*-----------------------------------------------------------------* * JBM TC buffers *-----------------------------------------------------------------*/ -#ifndef NONBE_UNIFIED_DECODING_PATHS - if ( st_ivas->hDecoderConfig->Opt_5ms ) -#endif { int16_t tc_nchan_full_new; DECODER_TC_BUFFER_HANDLE hTcBuffer; diff --git a/lib_dec/ivas_ism_dtx_dec.c b/lib_dec/ivas_ism_dtx_dec.c index 1c53749d7..523002e74 100644 --- a/lib_dec/ivas_ism_dtx_dec.c +++ b/lib_dec/ivas_ism_dtx_dec.c @@ -47,29 +47,15 @@ * ISM DTX Metadata decoding routine *-------------------------------------------------------------------*/ -#ifdef NONBE_FIX_898_ISM_BRATE_CRASH void ivas_ism_dtx_dec( -#else -ivas_error ivas_ism_dtx_dec( -#endif Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ int16_t *nb_bits_metadata /* o : number of metadata bits */ ) { -#ifdef NONBE_FIX_898_ISM_BRATE_CRASH int16_t ch, nchan_ism, nchan_ism_prev; -#else - int16_t ch, pos, nchan_ism, nchan_ism_prev; -#endif int32_t ivas_total_brate; int16_t md_diff_flag[MAX_NUM_OBJECTS]; -#ifdef NONBE_FIX_898_ISM_BRATE_CRASH int16_t flag_noisy_speech, sce_id_dtx; -#else - int16_t idx, flag_noisy_speech, sce_id_dtx; - ISM_MODE last_ism_mode, ism_mode_bstr; - ivas_error error; -#endif Decoder_State *st; ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate; @@ -79,50 +65,10 @@ ivas_error ivas_ism_dtx_dec( if ( !st_ivas->bfi && ivas_total_brate == IVAS_SID_5k2 ) { -#ifdef NONBE_FIX_898_ISM_BRATE_CRASH /* 'nchan_ism' was read in ivas_dec_setup() */ nchan_ism = st_ivas->nchan_ism; /* ism_mode was read in ivas_dec_setup() as well as reconfiguration ivas_ism_dec_config() */ -#else - /* read number of objects */ - nchan_ism = 1; - pos = (int16_t) ( ( ivas_total_brate / FRAMES_PER_SEC ) - 1 - SID_FORMAT_NBITS ); - - while ( get_indice( st_ivas->hSCE[0]->hCoreCoder[0], pos, 1 ) == 1 && nchan_ism < MAX_NUM_OBJECTS ) - { - ( nchan_ism )++; - pos--; - } - st_ivas->nchan_ism = nchan_ism; - pos--; - - if ( nchan_ism != nchan_ism_prev ) - { - return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "wrong number of objects signalled!" ); - } - - last_ism_mode = st_ivas->ism_mode; - - /* read ism_mode */ - if ( nchan_ism > 2 ) - { - pos -= nchan_ism; /* SID metadata flags */ - - idx = get_indice( st_ivas->hSCE[0]->hCoreCoder[0], pos, 1 ); - ism_mode_bstr = (ISM_MODE) ( idx + 1 ); - st_ivas->ism_mode = ism_mode_bstr; - } - -#ifdef SPLIT_REND_WITH_HEAD_ROT - if ( ( error = ivas_ism_dec_config( st_ivas, last_ism_mode, NULL, PCM_NOT_KNOW, NULL ) ) != IVAS_ERR_OK ) -#else - if ( ( error = ivas_ism_dec_config( st_ivas, last_ism_mode, NULL, NULL ) ) != IVAS_ERR_OK ) -#endif - { - return error; - } -#endif } else { @@ -154,7 +100,6 @@ ivas_error ivas_ism_dtx_dec( } } -#ifdef NONBE_FIX_DISCRETE_ISM_NOISE_SEED_HANDLING /* synch common seed between SCEs */ if ( st_ivas->ism_mode == ISM_MODE_DISC ) { @@ -163,7 +108,6 @@ ivas_error ivas_ism_dtx_dec( st_ivas->hSCE[ch]->hCoreCoder[0]->hFdCngDec->hFdCngCom->seed = st_ivas->hSCE[st_ivas->hISMDTX.sce_id_dtx]->hCoreCoder[0]->hFdCngDec->hFdCngCom->seed; } } -#endif update_last_metadata( nchan_ism, st_ivas->hIsmMetaData, md_diff_flag ); @@ -189,11 +133,7 @@ ivas_error ivas_ism_dtx_dec( } } -#ifdef NONBE_FIX_898_ISM_BRATE_CRASH return; -#else - return IVAS_ERR_OK; -#endif } diff --git a/lib_dec/ivas_ism_param_dec.c b/lib_dec/ivas_ism_param_dec.c index d355798f6..3158389d1 100644 --- a/lib_dec/ivas_ism_param_dec.c +++ b/lib_dec/ivas_ism_param_dec.c @@ -591,10 +591,6 @@ ivas_error ivas_param_ism_dec_open( st_ivas->hSpatParamRendCom = hSpatParamRendCom; -#ifndef NONBE_UNIFIED_DECODING_PATHS - if ( st_ivas->hDecoderConfig->Opt_5ms ) - { -#endif if ( st_ivas->renderer_type != RENDERER_MONO_DOWNMIX && st_ivas->renderer_type != RENDERER_DISABLE ) { int16_t nchan_transport = st_ivas->nchan_transport; @@ -652,14 +648,6 @@ ivas_error ivas_param_ism_dec_open( } } } -#ifndef NONBE_UNIFIED_DECODING_PATHS - } - else - { - hParamIsmDec->hParamIsmRendering->Cldfb_RealBuffer_tc = NULL; - hParamIsmDec->hParamIsmRendering->Cldfb_ImagBuffer_tc = NULL; - } -#endif pop_wmops(); return error; @@ -1211,11 +1199,7 @@ void ivas_param_ism_dec_digest_tc( } } -#ifndef NONBE_UNIFIED_DECODING_PATHS - if ( st_ivas->hDecoderConfig->Opt_tsm || !st_ivas->hDecoderConfig->Opt_5ms ) -#else if ( st_ivas->hDecoderConfig->Opt_tsm ) -#endif { /*TODO : FhG to check*/ ivas_ism_param_dec_tc_gain_ajust( st_ivas, output_frame, fade_len, transport_channels_f ); @@ -1226,11 +1210,7 @@ void ivas_param_ism_dec_digest_tc( /* CLDFB Analysis */ for ( slot_idx = 0; slot_idx < nCldfbSlots; slot_idx++ ) { -#ifndef NONBE_UNIFIED_DECODING_PATHS - if ( st_ivas->hDecoderConfig->Opt_tsm || !st_ivas->hDecoderConfig->Opt_5ms ) -#else if ( st_ivas->hDecoderConfig->Opt_tsm ) -#endif { float RealBuffer[CLDFB_NO_CHANNELS_MAX]; diff --git a/lib_dec/ivas_ism_renderer.c b/lib_dec/ivas_ism_renderer.c index 63c8f47d2..ab922db4c 100644 --- a/lib_dec/ivas_ism_renderer.c +++ b/lib_dec/ivas_ism_renderer.c @@ -132,108 +132,6 @@ void ivas_ism_renderer_close( return; } -#ifndef NONBE_UNIFIED_DECODING_PATHS -/*-------------------------------------------------------------------------* - * ivas_ism_render() - * - * Object rendering process. - *-------------------------------------------------------------------------*/ - -void ivas_ism_render( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - float *output_f[], /* i/o: core-coder transport channels/object output */ - const int16_t output_frame /* i : output frame length per channel */ -) -{ - int16_t i, j, k, j2; - float input_f[MAX_NUM_OBJECTS][L_FRAME48k]; - float tmp_output_f[MAX_OUTPUT_CHANNELS][L_FRAME48k]; - float gains[MAX_NUM_OBJECTS][MAX_OUTPUT_CHANNELS]; - float g1, g2; - int16_t nchan_ism, nchan_out_woLFE, lfe_index; - int16_t azimuth, elevation; - - nchan_ism = st_ivas->nchan_ism; - nchan_out_woLFE = st_ivas->hIntSetup.nchan_out_woLFE; - - lfe_index = 0; - - for ( j = 0; j < nchan_out_woLFE; j++ ) - { - set_f( tmp_output_f[j], 0.0f, output_frame ); - } - - for ( i = 0; i < nchan_ism; i++ ) - { - mvr2r( output_f[i], input_f[i], output_frame ); - } - - for ( i = 0; i < nchan_out_woLFE + st_ivas->hIntSetup.num_lfe; i++ ) - { - set_f( output_f[i], 0.0f, output_frame ); - } - - for ( i = 0; i < nchan_ism; i++ ) - { - if ( st_ivas->intern_config == IVAS_AUDIO_CONFIG_STEREO ) - { - ivas_ism_get_stereo_gains( st_ivas->hIsmMetaData[i]->azimuth, st_ivas->hIsmMetaData[i]->elevation, &gains[i][0], &gains[i][1] ); - } - else - { - /* Combined rotation: rotate the object positions depending the head and external orientations */ - if ( st_ivas->hCombinedOrientationData != NULL && st_ivas->hCombinedOrientationData->enableCombinedOrientation[0] == 1 ) - { - rotateAziEle( st_ivas->hIsmMetaData[i]->azimuth, st_ivas->hIsmMetaData[i]->elevation, &azimuth, &elevation, st_ivas->hCombinedOrientationData->Rmat[0], st_ivas->hIntSetup.is_planar_setup ); - } - else - { - // TODO tmu review when #215 is resolved - azimuth = (int16_t) floorf( st_ivas->hIsmMetaData[i]->azimuth + 0.5f ); - elevation = (int16_t) floorf( st_ivas->hIsmMetaData[i]->elevation + 0.5f ); - - if ( st_ivas->hIntSetup.is_planar_setup ) - { - /* If no elevation support in output format, then rendering should be done with zero elevation */ - elevation = 0; - } - } - - if ( st_ivas->hEFAPdata != NULL ) - { - efap_determine_gains( st_ivas->hEFAPdata, gains[i], azimuth, elevation, EFAP_MODE_EFAP ); - } - } - - for ( j = 0; j < nchan_out_woLFE; j++ ) - { - if ( fabsf( gains[i][j] ) > 0.0f || fabsf( st_ivas->hIsmRendererData->prev_gains[i][j] ) > 0.0f ) - { - for ( k = 0; k < output_frame; k++ ) - { - g1 = st_ivas->hIsmRendererData->interpolator[k]; - g2 = 1.0f - g1; - tmp_output_f[j][k] += ( g1 * gains[i][j] + g2 * st_ivas->hIsmRendererData->prev_gains[i][j] ) * input_f[i][k]; - } - } - - st_ivas->hIsmRendererData->prev_gains[i][j] = gains[i][j]; - } - } - - /* Move to output skipping LFE */ - for ( j = 0, j2 = 0; j < nchan_out_woLFE; j++, j2++ ) - { - if ( ( st_ivas->hIntSetup.num_lfe > 0 ) && ( st_ivas->hIntSetup.index_lfe[lfe_index] == j ) ) - { - ( lfe_index < ( st_ivas->hIntSetup.num_lfe - 1 ) ) ? ( lfe_index++, j2++ ) : j2++; - } - mvr2r( tmp_output_f[j], output_f[j2], output_frame ); - } - - return; -} -#endif /*-------------------------------------------------------------------------* * ivas_ism_render_sf() @@ -254,10 +152,8 @@ void ivas_ism_render_sf( int16_t tc_offset; int16_t interp_offset; float gain, prev_gain; -#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX float tc_local[MAX_NUM_OBJECTS][L_FRAME48k]; float *p_tc[MAX_NUM_OBJECTS]; -#endif num_objects = st_ivas->nchan_transport; if ( st_ivas->ivas_format == SBA_ISM_FORMAT ) @@ -270,7 +166,6 @@ void ivas_ism_render_sf( tc_offset = st_ivas->hTcBuffer->n_samples_rendered; interp_offset = st_ivas->hTcBuffer->n_samples_rendered; -#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX if ( st_ivas->hDecoderConfig->Opt_tsm ) { for ( i = 0; i < num_objects; i++ ) @@ -286,18 +181,13 @@ void ivas_ism_render_sf( p_tc[i] = tc_local[i]; } } -#endif for ( i = 0; i < nchan_out_woLFE + st_ivas->hIntSetup.num_lfe; i++ ) { set_f( output_f[i], 0.0f, n_samples_to_render ); } -#ifdef NONBE_UNIFIED_DECODING_PATHS if ( st_ivas->hCombinedOrientationData && st_ivas->hCombinedOrientationData->enableCombinedOrientation[st_ivas->hCombinedOrientationData->subframe_idx] == 1 ) -#else - if ( st_ivas->hCombinedOrientationData && st_ivas->hCombinedOrientationData->enableCombinedOrientation[0] ) -#endif { ivas_jbm_dec_get_adapted_linear_interpolator( n_samples_to_render, n_samples_to_render, st_ivas->hIsmRendererData->interpolator ); interp_offset = 0; @@ -306,11 +196,7 @@ void ivas_ism_render_sf( for ( i = 0; i < num_objects; i++ ) { /* Combined rotation: rotate the object positions depending the head and external orientations */ -#ifdef NONBE_UNIFIED_DECODING_PATHS if ( st_ivas->hCombinedOrientationData != NULL && st_ivas->hCombinedOrientationData->enableCombinedOrientation[st_ivas->hCombinedOrientationData->subframe_idx] == 1 ) -#else - if ( st_ivas->hCombinedOrientationData != NULL && st_ivas->hCombinedOrientationData->enableCombinedOrientation[0] == 1 ) -#endif { rotateAziEle( st_ivas->hIsmMetaData[i]->azimuth, st_ivas->hIsmMetaData[i]->elevation, &azimuth, &elevation, st_ivas->hCombinedOrientationData->Rmat[0], st_ivas->hIntSetup.is_planar_setup ); @@ -333,11 +219,7 @@ void ivas_ism_render_sf( if ( fabsf( gain ) > 0.0f || fabsf( prev_gain ) > 0.0f ) { g1 = &st_ivas->hIsmRendererData->interpolator[interp_offset]; -#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX tc = p_tc[i]; -#else - tc = &st_ivas->hTcBuffer->tc[i][tc_offset]; -#endif for ( k = 0; k < n_samples_to_render; k++ ) { g2 = 1.0f - *g1; @@ -346,21 +228,15 @@ void ivas_ism_render_sf( } /* update here only in case of head rotation */ -#ifdef NONBE_UNIFIED_DECODING_PATHS if ( st_ivas->hCombinedOrientationData != NULL && st_ivas->hCombinedOrientationData->enableCombinedOrientation[st_ivas->hCombinedOrientationData->subframe_idx] == 1 ) -#else - if ( st_ivas->hCombinedOrientationData != NULL && st_ivas->hCombinedOrientationData->enableCombinedOrientation[0] == 1 ) -#endif { st_ivas->hIsmRendererData->prev_gains[i][j] = gain; } } } -#ifdef NONBE_UNIFIED_DECODING_PATHS /* update combined orientation access index */ ivas_combined_orientation_update_index( st_ivas->hCombinedOrientationData, n_samples_to_render ); -#endif return; } @@ -512,118 +388,6 @@ void ivas_omasa_separate_object_renderer_close( return; } -#ifndef NONBE_UNIFIED_DECODING_PATHS_FIX -/*-------------------------------------------------------------------------* - * ivas_omasa_separate_object_render() - * - * Rendering separated objects and mixing them to the parametrically rendered signals - *-------------------------------------------------------------------------*/ - -void ivas_omasa_separate_object_render( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - float input_f[][L_FRAME48k], /* i : separated object signal */ - float *output_f[], /* i/o: output signals */ - const int16_t output_frame /* i : output frame length per channel */ -) -{ - VBAP_HANDLE hVBAPdata; - int16_t nchan_out_woLFE; - ISM_RENDERER_HANDLE hRendererData; - int16_t j, k, j2; - int16_t obj; - float gains[MAX_OUTPUT_CHANNELS]; - float g1, g2; - int16_t lfe_index; - int16_t azimuth, elevation; - int16_t num_objects; - uint8_t single_separated; - int16_t block; - int16_t subframe_len; - int16_t idx_offset; - int16_t dirac_read_idx; - - hVBAPdata = st_ivas->hVBAPdata; - nchan_out_woLFE = st_ivas->hIntSetup.nchan_out_woLFE; - hRendererData = st_ivas->hIsmRendererData; - lfe_index = st_ivas->hDirACRend->hOutSetup.index_lfe[0]; - subframe_len = output_frame / MAX_PARAM_SPATIAL_SUBFRAMES; - - if ( st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ ) - { - single_separated = 1; - num_objects = 1; - } - else - { - single_separated = 0; - num_objects = st_ivas->nchan_ism; - } - - for ( obj = 0; obj < num_objects; obj++ ) - { - delay_signal( input_f[obj], output_frame, st_ivas->hMasaIsmData->delayBuffer[obj], st_ivas->hMasaIsmData->delayBuffer_size ); /* Delay the signal to match CLDFB delay */ - - for ( block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; block++ ) - { - idx_offset = block * subframe_len; - dirac_read_idx = ( st_ivas->hSpatParamRendCom->dirac_read_idx + block ) % st_ivas->hSpatParamRendCom->dirac_md_buffer_length; - - if ( single_separated ) - { - azimuth = st_ivas->hMasaIsmData->azimuth_separated_ism[dirac_read_idx]; - elevation = st_ivas->hMasaIsmData->elevation_separated_ism[dirac_read_idx]; - } - else - { - azimuth = st_ivas->hMasaIsmData->azimuth_ism[obj][dirac_read_idx]; - elevation = st_ivas->hMasaIsmData->elevation_ism[obj][dirac_read_idx]; - } - - if ( st_ivas->hOutSetup.is_planar_setup ) - { - /* If no elevation support in output format, then rendering should be done with zero elevation */ - elevation = 0; - } - - if ( hVBAPdata != NULL ) - { - vbap_determine_gains( hVBAPdata, gains, azimuth, elevation, 1 ); - } - else - { - ivas_dirac_dec_get_response( azimuth, elevation, gains, st_ivas->hDirACRend->hOutSetup.ambisonics_order ); - } - - for ( j = 0; j < nchan_out_woLFE; j++ ) - { - if ( st_ivas->hDirACRend->hOutSetup.num_lfe > 0 ) - { - j2 = j + ( j >= lfe_index ); - } - else - { - j2 = j; - } - - if ( fabsf( gains[j] ) > 0.0f || fabsf( hRendererData->prev_gains[obj][j] ) > 0.0f ) - { - for ( k = 0; k < subframe_len; k++ ) - { - g1 = hRendererData->interpolator[k]; - g2 = 1.0f - g1; - output_f[j2][k + idx_offset] += ( g1 * gains[j] + g2 * hRendererData->prev_gains[obj][j] ) * input_f[obj][k + idx_offset]; - } - } - hRendererData->prev_gains[obj][j] = gains[j]; - } - } - } - - st_ivas->hSpatParamRendCom->dirac_read_idx = ( st_ivas->hSpatParamRendCom->dirac_read_idx + MAX_PARAM_SPATIAL_SUBFRAMES ) % st_ivas->hSpatParamRendCom->dirac_md_buffer_length; - - return; -} -#endif /*-------------------------------------------------------------------------* * ivas_omasa_separate_object_render_jbm() @@ -634,9 +398,7 @@ void ivas_omasa_separate_object_render( void ivas_omasa_separate_object_render_jbm( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ const uint16_t nSamplesRendered, /* i : number of samples rendered */ -#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX float input_f_in[][L_FRAME48k], /* i : separated object signal */ -#endif float *output_f[], /* o : rendered time signal */ const int16_t subframes_rendered, /* i : number of subframes rendered */ const int16_t slots_rendered /* i : number of CLDFB slots rendered */ @@ -687,15 +449,12 @@ void ivas_omasa_separate_object_render_jbm( output_f_local[j] = output_f[j]; } -#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX if ( st_ivas->hDecoderConfig->Opt_tsm ) { -#endif for ( obj = 0; obj < num_objects; obj++ ) { input_f[obj] = &st_ivas->hTcBuffer->tc[obj + 2][offsetSamples]; } -#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX } else { @@ -704,7 +463,6 @@ void ivas_omasa_separate_object_render_jbm( input_f[obj] = input_f_in[obj]; } } -#endif slots_to_render = nSamplesRendered / hSpatParamRendCom->slot_size; first_sf = subframes_rendered; diff --git a/lib_dec/ivas_masa_dec.c b/lib_dec/ivas_masa_dec.c index 2b922314f..0e2202107 100644 --- a/lib_dec/ivas_masa_dec.c +++ b/lib_dec/ivas_masa_dec.c @@ -1239,7 +1239,6 @@ ivas_error ivas_masa_dec_reconfigure( #else int16_t *data /* o : output synthesis signal */ #endif - int16_t *data /* o : output synthesis signal */ ) { int16_t n, tmp, num_bits; diff --git a/lib_dec/ivas_mc_param_dec.c b/lib_dec/ivas_mc_param_dec.c index 0ded6b37f..6f2970ada 100644 --- a/lib_dec/ivas_mc_param_dec.c +++ b/lib_dec/ivas_mc_param_dec.c @@ -447,11 +447,7 @@ ivas_error ivas_param_mc_dec_open( ivas_param_mc_dec_init( hParamMC, nchan_transport, nchan_out_cov ); -#ifndef NONBE_UNIFIED_DECODING_PATHS - if ( st_ivas->hDecoderConfig->Opt_5ms && hParamMC->synthesis_conf != PARAM_MC_SYNTH_MONO_STEREO ) -#else if ( hParamMC->synthesis_conf != PARAM_MC_SYNTH_MONO_STEREO ) -#endif { int16_t n_cldfb_slots; @@ -983,7 +979,6 @@ ivas_error ivas_param_mc_dec_reconfig( } -#ifdef NONBE_UNIFIED_DECODING_PATHS if ( nchan_transport_old != nchan_transport ) { if ( hParamMC->synthesis_conf != PARAM_MC_SYNTH_MONO_STEREO ) @@ -1032,7 +1027,6 @@ ivas_error ivas_param_mc_dec_reconfig( } } } -#endif return error; } @@ -1634,11 +1628,7 @@ void ivas_param_mc_dec_digest_tc( /* slot loop for gathering the input data */ for ( slot_idx = 0; slot_idx < nCldfbSlots; slot_idx++ ) { -#ifndef NONBE_UNIFIED_DECODING_PATHS - if ( st_ivas->hDecoderConfig->Opt_tsm || !st_ivas->hDecoderConfig->Opt_5ms ) -#else if ( st_ivas->hDecoderConfig->Opt_tsm ) -#endif { float RealBuffer[CLDFB_NO_CHANNELS_MAX]; float ImagBuffer[CLDFB_NO_CHANNELS_MAX]; @@ -1977,9 +1967,6 @@ void ivas_param_mc_dec_render( #endif #endif st_ivas->hCombinedOrientationData, -#ifndef NONBE_UNIFIED_DECODING_PATHS - subframe_idx, -#endif hParamMC->subframe_nbslots[subframe_idx], Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, Cldfb_RealBuffer, Cldfb_ImagBuffer ); @@ -2001,10 +1988,8 @@ void ivas_param_mc_dec_render( } #endif -#ifdef NONBE_UNIFIED_DECODING_PATHS /* update combined orientation access index */ ivas_combined_orientation_update_index( st_ivas->hCombinedOrientationData, hParamMC->num_freq_bands * hParamMC->subframe_nbslots[subframe_idx] ); -#endif } else if ( hParamMC->synthesis_conf == PARAM_MC_SYNTH_LS_CONV_CLDFB ) { diff --git a/lib_dec/ivas_mc_paramupmix_dec.c b/lib_dec/ivas_mc_paramupmix_dec.c index 57065ed32..a9be77ec8 100644 --- a/lib_dec/ivas_mc_paramupmix_dec.c +++ b/lib_dec/ivas_mc_paramupmix_dec.c @@ -64,9 +64,6 @@ const int16_t MC_PARAMUPMIX_CHIDX2[MC_PARAMUPMIX_COMBINATIONS] = { 2, 3, 6, 7 }; * Local function prototypes *-----------------------------------------------------------------------*/ -#ifndef NONBE_UNIFIED_DECODING_PATHS_FIX -static void ps_pred_process( MC_PARAMUPMIX_DEC_HANDLE hMCParamUpmix, float qmf_mod_re[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], float qmf_mod_im[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], float qmf_side_re[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], float qmf_side_im[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], const int16_t ch ); -#endif static void ps_pred_process_sf( MC_PARAMUPMIX_DEC_HANDLE hMCParamUpmix, DECODER_TC_BUFFER_HANDLE hTcBuffer, float qmf_mod_re[JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float qmf_mod_im[JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float qmf_side_re[JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float qmf_side_im[JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float *param_interpol, const int16_t ch, const int16_t slots_rendered ); #ifdef SPLIT_REND_WITH_HEAD_ROT @@ -77,12 +74,8 @@ static void ivas_mc_paramupmix_dec_sf( Decoder_Struct *st_ivas, float *output_f[ static void ivas_param_upmix_dec_decorr_subframes( Decoder_Struct *st_ivas, const int16_t nSamplesForRendering ); -#ifndef NONBE_UNIFIED_DECODING_PATHS_FIX -static void paramupmix_td_decorr_process( ivas_td_decorr_state_t *hTdDecorr[], float *pcm_in[], float **pp_out_pcm, const int16_t output_frame ); -#endif static int16_t huff_read( Decoder_State *st, const int16_t ( *ht )[2] ); -#ifdef FIX_891_PARAMUPMIX_CLEANUP static void huffman_decode( Decoder_State *st, const PAR_TYPE parType, int32_t *vq ); static void dequant_alpha( int32_t *vq, float *v ); @@ -90,15 +83,6 @@ static void dequant_alpha( int32_t *vq, float *v ); static void dequant_beta( int32_t *aq, int32_t *bq, float *beta ); static void get_ec_data( Decoder_State *st, const PAR_TYPE parType, int32_t *parQ, int32_t *alphaQEnv, float ab[IVAS_MAX_NUM_BANDS] ); -#else -static void huffman_decode( Decoder_State *st, const int16_t nv, const int16_t ivStart, PAR_TYPE parType, QUANT_TYPE quant_type, const int16_t bNoDt, int32_t *vq ); - -static void dequant_alpha( const int16_t nv, const int16_t ivStart, const QUANT_TYPE quant_type, int32_t *vq, float *v ); - -static void dequant_beta( const int16_t nv, const int16_t ivStart, const QUANT_TYPE quant_type, int32_t *aq, int32_t *bq, float *beta ); - -static void get_ec_data( Decoder_State *st, const PAR_TYPE parType, const QUANT_TYPE quant_type, const int16_t nParBand, const int16_t parBandStart, int32_t *parQ, int32_t *alphaQEnv, float ab[IVAS_MAX_NUM_BANDS] ); -#endif /*------------------------------------------------------------------------- @@ -153,17 +137,9 @@ void ivas_mc_paramupmix_dec_read_BS( for ( i = 0; i < MC_PARAMUPMIX_COMBINATIONS; i++ ) { -#ifdef FIX_891_PARAMUPMIX_CLEANUP get_ec_data( st0, ALPHA, hMCParamUpmix->alpha_quant[i], alpha_quant, hMCParamUpmix->alphas[i] ); get_ec_data( st0, BETA, hMCParamUpmix->beta_quant[i], alpha_quant, hMCParamUpmix->betas[i] ); -#else - get_ec_data( st0, ALPHA, FINE /*quant_type*/, IVAS_MAX_NUM_BANDS /*nParBand*/, - 0 /*parBandStart*/, hMCParamUpmix->alpha_quant[i], alpha_quant, hMCParamUpmix->alphas[i] ); - - get_ec_data( st0, BETA, FINE /*quant_type*/, IVAS_MAX_NUM_BANDS /*nParBand*/, - 0 /*parBandStart*/, hMCParamUpmix->beta_quant[i], alpha_quant, hMCParamUpmix->betas[i] ); -#endif } *nb_bits += st0->next_bit_pos; st0->bit_stream = bit_stream_orig; @@ -184,299 +160,6 @@ void ivas_mc_paramupmix_dec_read_BS( return; } -#ifndef NONBE_UNIFIED_DECODING_PATHS_FIX -/*------------------------------------------------------------------------- - * ivas_mc_paramupmix_dec() - * - * MC ParamUpmix decoding process - *------------------------------------------------------------------------*/ - -void ivas_mc_paramupmix_dec( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ - float *output_f[] /* i/o: synthesized core-coder transport channels */ -) -{ - MC_PARAMUPMIX_DEC_HANDLE hMCParamUpmix; - int16_t i, k, ch; - int16_t slot_idx; - int16_t first_empty_channel; - int16_t nchan_out_transport; - /*CLDFB*/ - float Cldfb_RealBuffer[MC_PARAMUPMIX_MAX_TRANSPORT_CHANS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; - float Cldfb_ImagBuffer[MC_PARAMUPMIX_MAX_TRANSPORT_CHANS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; - int16_t channel_active[MAX_OUTPUT_CHANNELS]; - int32_t output_Fs; - int16_t output_frame; - float Pcm_decorr[MC_PARAMUPMIX_COMBINATIONS][L_FRAME48k]; /* decorrelated channels */ - float *pPcm_temp[MC_PARAMUPMIX_COMBINATIONS * 2]; /* decorrelated and undecorrelated*/ - int16_t noparamupmix_delay; - AUDIO_CONFIG output_config; - int16_t subframeIdx, idx_in, index_slot, maxBand; - float Cldfb_RealBuffer_subfr[MAX_INTERN_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; - float Cldfb_ImagBuffer_subfr[MAX_INTERN_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; -#ifdef SPLIT_REND_WITH_HEAD_ROT - float Cldfb_RealBuffer_Binaural[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; - float Cldfb_ImagBuffer_Binaural[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; -#else - float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; - float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; -#endif - - hMCParamUpmix = st_ivas->hMCParamUpmix; - assert( hMCParamUpmix ); - push_wmops( "mc_paramupmix_dec" ); - - set_s( channel_active, 0, MAX_CICP_CHANNELS ); - nchan_out_transport = st_ivas->hTransSetup.nchan_out_woLFE + st_ivas->hTransSetup.num_lfe; - set_s( channel_active, 1, nchan_out_transport ); /* change to nchan_out_transport */ - output_Fs = st_ivas->hDecoderConfig->output_Fs; - output_config = st_ivas->hDecoderConfig->output_config; - output_frame = (int16_t) ( output_Fs / FRAMES_PER_SEC ); - - if ( ( output_config == IVAS_AUDIO_CONFIG_STEREO ) || ( output_config == IVAS_AUDIO_CONFIG_MONO ) ) - { - first_empty_channel = 8; /* Don't upmix */ - - /* Compensate loudness for not doing full upmix */ - for ( i = 4; i < 8; i++ ) - { - v_multc( output_f[i], 2.0f, output_f[i], L_FRAME48k ); - } - } - else - { - first_empty_channel = 12; - - for ( i = 0; i < MC_PARAMUPMIX_COMBINATIONS; i++ ) - { - pPcm_temp[i] = Pcm_decorr[i]; /* decorrelated */ - } - - paramupmix_td_decorr_process( hMCParamUpmix->hTdDecorr, &( output_f[4] ), pPcm_temp, output_frame ); - - for ( i = 0; i < MC_PARAMUPMIX_COMBINATIONS; i++ ) - { - pPcm_temp[2 * i] = output_f[i + 4]; /* un-decorrelated */ - pPcm_temp[2 * i + 1] = Pcm_decorr[i]; /* decorrelated */ - } - - /* CLDFB Analysis*/ - for ( ch = 0; ch < MC_PARAMUPMIX_COMBINATIONS * 2; ch++ ) - { - /* slot loop for gathering the input data */ - for ( slot_idx = 0; slot_idx < CLDFB_NO_COL_MAX; slot_idx++ ) - { - cldfbAnalysis_ts( &( pPcm_temp[ch][hMCParamUpmix->num_freq_bands * slot_idx] ), Cldfb_RealBuffer[ch][slot_idx], Cldfb_ImagBuffer[ch][slot_idx], hMCParamUpmix->num_freq_bands, st_ivas->cldfbAnaDec[ch] ); - } - } - for ( ch = 0; ch < MC_PARAMUPMIX_COMBINATIONS; ch++ ) - { - ps_pred_process( hMCParamUpmix, - Cldfb_RealBuffer[2 * ch], /* in/out */ - Cldfb_ImagBuffer[2 * ch], - Cldfb_RealBuffer[2 * ch + 1], /* in/out decorr */ - Cldfb_ImagBuffer[2 * ch + 1], - ch ); - - /*-- m, s -> l, r ----------------------------*/ - for ( i = 0; i < CLDFB_NO_COL_MAX; i++ ) - { - for ( k = 0; k < CLDFB_NO_CHANNELS_MAX; k++ ) - { - float qlre = Cldfb_RealBuffer[2 * ch][i][k]; - float qlim = Cldfb_ImagBuffer[2 * ch][i][k]; - float qrre = Cldfb_RealBuffer[2 * ch + 1][i][k]; - float qrim = Cldfb_ImagBuffer[2 * ch + 1][i][k]; - - Cldfb_RealBuffer[2 * ch][i][k] = qlre + qrre; - Cldfb_ImagBuffer[2 * ch][i][k] = qlim + qrim; - Cldfb_RealBuffer[2 * ch + 1][i][k] = qlre - qrre; - Cldfb_ImagBuffer[2 * ch + 1][i][k] = qlim - qrim; - } - } - - mvr2r( hMCParamUpmix->alphas[ch], hMCParamUpmix->alpha_prev[ch], IVAS_MAX_NUM_BANDS ); - mvr2r( hMCParamUpmix->betas[ch], hMCParamUpmix->beta_prev[ch], IVAS_MAX_NUM_BANDS ); - } - - if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) - { - maxBand = (int16_t) ( ( CLDFB_NO_CHANNELS_MAX * st_ivas->hDecoderConfig->output_Fs ) / 48000 ); - /* fastconv binaural rendering and CLDFB synthesis */ - for ( subframeIdx = 0; subframeIdx < ( CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES ); subframeIdx++ ) - { - index_slot = subframeIdx * MAX_PARAM_SPATIAL_SUBFRAMES; - /* cldfb analysis of non-coupled, non-LFE channels */ - idx_in = 0; - for ( ch = 0; ch < first_empty_channel - 2 * MC_PARAMUPMIX_COMBINATIONS; ch++ ) - { - if ( st_ivas->hIntSetup.index_lfe[0] != ch ) - { - pPcm_temp[ch] = output_f[ch]; - /* slot loop for gathering the input data */ - for ( slot_idx = 0; slot_idx < MAX_PARAM_SPATIAL_SUBFRAMES; slot_idx++ ) - { - cldfbAnalysis_ts( &( pPcm_temp[ch][hMCParamUpmix->num_freq_bands * ( index_slot + slot_idx )] ), - Cldfb_RealBuffer_subfr[idx_in][slot_idx], - Cldfb_ImagBuffer_subfr[idx_in][slot_idx], - maxBand, st_ivas->cldfbAnaDec[2 * MC_PARAMUPMIX_COMBINATIONS + idx_in] ); - } - idx_in++; - } - } - - /* copy and reorder cldfb analysis of coupled channels */ - for ( ch = 0; ch < MAX_PARAM_SPATIAL_SUBFRAMES; ch++ ) - { - for ( slot_idx = 0; slot_idx < MAX_PARAM_SPATIAL_SUBFRAMES; slot_idx++ ) - { - mvr2r( Cldfb_RealBuffer[MC_PARAMUPMIX_CHIDX1[ch]][index_slot + slot_idx], Cldfb_RealBuffer_subfr[idx_in][slot_idx], CLDFB_NO_CHANNELS_MAX ); - mvr2r( Cldfb_ImagBuffer[MC_PARAMUPMIX_CHIDX1[ch]][index_slot + slot_idx], Cldfb_ImagBuffer_subfr[idx_in][slot_idx], CLDFB_NO_CHANNELS_MAX ); - mvr2r( Cldfb_RealBuffer[MC_PARAMUPMIX_CHIDX2[ch]][index_slot + slot_idx], Cldfb_RealBuffer_subfr[idx_in + 1][slot_idx], CLDFB_NO_CHANNELS_MAX ); - mvr2r( Cldfb_ImagBuffer[MC_PARAMUPMIX_CHIDX2[ch]][index_slot + slot_idx], Cldfb_ImagBuffer_subfr[idx_in + 1][slot_idx], CLDFB_NO_CHANNELS_MAX ); - } - idx_in += 2; - } - - if ( st_ivas->hCombinedOrientationData && st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV ) - { - for ( slot_idx = 0; slot_idx < MAX_PARAM_SPATIAL_SUBFRAMES; slot_idx++ ) - { - ivas_param_mc_mc2sba_cldfb( st_ivas->hTransSetup, hMCParamUpmix->hoa_encoder, slot_idx, Cldfb_RealBuffer_subfr, Cldfb_ImagBuffer_subfr, maxBand, GAIN_LFE ); - } - } - -#ifdef SPLIT_REND_WITH_HEAD_ROT - /*LFE handling for split rendering cases*/ - if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) - { - -#ifdef SPLIT_REND_WITH_HEAD_ROT - if ( st_ivas->hSplitBinRend.hCldfbDataOut != NULL ) - { - for ( slot_idx = 0; slot_idx < MAX_PARAM_SPATIAL_SUBFRAMES; slot_idx++ ) - { - for ( ch = 0; ch < ( st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe ); ch++ ) - { - mvr2r( Cldfb_RealBuffer_subfr[ch][slot_idx], st_ivas->hSplitBinRend.hCldfbDataOut->Cldfb_RealBuffer[ch][( subframeIdx * JBM_CLDFB_SLOTS_IN_SUBFRAME ) + slot_idx], maxBand ); - mvr2r( Cldfb_ImagBuffer_subfr[ch][slot_idx], st_ivas->hSplitBinRend.hCldfbDataOut->Cldfb_ImagBuffer[ch][( subframeIdx * JBM_CLDFB_SLOTS_IN_SUBFRAME ) + slot_idx], maxBand ); - } - } - st_ivas->hSplitBinRend.hCldfbDataOut->config = st_ivas->hIntSetup.output_config; - } -#endif - } -#endif - - /* Implement binaural rendering */ - ivas_binRenderer( st_ivas->hBinRenderer, -#ifdef SPLIT_REND_WITH_HEAD_ROT - &st_ivas->hSplitBinRend.splitrend.multiBinPoseData, -#endif - st_ivas->hCombinedOrientationData, -#ifndef NONBE_UNIFIED_DECODING_PATHS - subframeIdx, -#endif - JBM_CLDFB_SLOTS_IN_SUBFRAME, -#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG - NULL, -#endif - Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, - Cldfb_RealBuffer_subfr, - Cldfb_ImagBuffer_subfr ); - -#ifdef SPLIT_REND_WITH_HEAD_ROT - if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) - { - int16_t pos_idx; - - for ( pos_idx = 0; pos_idx < st_ivas->hBinRenderer->numPoses; pos_idx++ ) - { - for ( slot_idx = 0; slot_idx < JBM_CLDFB_SLOTS_IN_SUBFRAME; slot_idx++ ) - { - for ( ch = 0; ch < st_ivas->hDecoderConfig->nchan_out; ch++ ) - { - mvr2r( Cldfb_RealBuffer_Binaural[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend.hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[( pos_idx * BINAURAL_CHANNELS ) + ch][( subframeIdx * JBM_CLDFB_SLOTS_IN_SUBFRAME ) + slot_idx], maxBand ); - mvr2r( Cldfb_ImagBuffer_Binaural[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend.hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[( pos_idx * BINAURAL_CHANNELS ) + ch][( subframeIdx * JBM_CLDFB_SLOTS_IN_SUBFRAME ) + slot_idx], maxBand ); - } - } - } - } -#endif - -#ifdef NONBE_UNIFIED_DECODING_PATHS - /* update combined orientation access index */ - ivas_combined_orientation_update_index( st_ivas->hCombinedOrientationData, maxBand * MAX_PARAM_SPATIAL_SUBFRAMES ); -#endif - - /* Implement CLDFB synthesis */ - for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) - { - float *RealBuffer[MAX_PARAM_SPATIAL_SUBFRAMES]; - float *ImagBuffer[MAX_PARAM_SPATIAL_SUBFRAMES]; - - for ( slot_idx = 0; slot_idx < MAX_PARAM_SPATIAL_SUBFRAMES; slot_idx++ ) - { -#ifdef SPLIT_REND_WITH_HEAD_ROT - RealBuffer[slot_idx] = Cldfb_RealBuffer_Binaural[0][ch][slot_idx]; - ImagBuffer[slot_idx] = Cldfb_ImagBuffer_Binaural[0][ch][slot_idx]; -#else - RealBuffer[slot_idx] = Cldfb_RealBuffer_Binaural[ch][slot_idx]; - ImagBuffer[slot_idx] = Cldfb_ImagBuffer_Binaural[ch][slot_idx]; -#endif - } - - cldfbSynthesis( RealBuffer, ImagBuffer, &( output_f[ch][index_slot * maxBand] ), maxBand * MAX_PARAM_SPATIAL_SUBFRAMES, st_ivas->cldfbSynDec[ch] ); - } - } - } - else - { - pPcm_temp[0] = output_f[4]; - pPcm_temp[1] = output_f[6]; - pPcm_temp[2] = output_f[5]; - pPcm_temp[3] = output_f[7]; - pPcm_temp[4] = output_f[8]; - pPcm_temp[5] = output_f[10]; - pPcm_temp[6] = output_f[9]; - pPcm_temp[7] = output_f[11]; - - /* CLDFB synthesis */ - for ( ch = 0; ch < MC_PARAMUPMIX_COMBINATIONS * 2; ch++ ) - { - for ( slot_idx = 0; slot_idx < CLDFB_NO_COL_MAX; slot_idx++ ) - { - float *ptr_im[1], *ptr_re[1]; - ptr_re[0] = Cldfb_RealBuffer[ch][slot_idx]; - ptr_im[0] = Cldfb_ImagBuffer[ch][slot_idx]; - - cldfbSynthesis( ptr_re, ptr_im, &( pPcm_temp[ch][hMCParamUpmix->num_freq_bands * slot_idx] ), - hMCParamUpmix->num_freq_bands, st_ivas->cldfbSynDec[ch] ); - } - } - - /* adjust delay of other channels */ - noparamupmix_delay = NS2SA( output_Fs, IVAS_FB_DEC_DELAY_NS ); - for ( ch = 0; ch < MC_PARAMUPMIX_COMBINATIONS; ch++ ) - { - float tmp_buf[L_SUBFRAME5MS_48k]; - mvr2r( &output_f[ch][output_frame - noparamupmix_delay], tmp_buf, noparamupmix_delay ); - mvr2r( output_f[ch], &output_f[ch][noparamupmix_delay], output_frame - noparamupmix_delay ); - mvr2r( hMCParamUpmix->pcm_delay[ch], output_f[ch], noparamupmix_delay ); - mvr2r( tmp_buf, hMCParamUpmix->pcm_delay[ch], noparamupmix_delay ); - } - } - } - - for ( ch = first_empty_channel; ch < ivas_get_nchan_buffers_dec( st_ivas, -1, -1 ); ch++ ) - { - set_f( output_f[ch], 0.0f, output_frame ); - } - - pop_wmops(); - return; -} -#endif /*------------------------------------------------------------------------- * ivas_mc_paramupmix_dec_digest_tc() @@ -584,19 +267,13 @@ void ivas_mc_paramupmix_dec_render( ivas_mc_paramupmix_dec_sf( st_ivas, output_f_local ); #endif -#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX for ( ch = 0; ch < min( MAX_OUTPUT_CHANNELS, ivas_get_nchan_buffers_dec( st_ivas, -1, -1 ) ); ch++ ) -#else - for ( ch = 0; ch < MAX_OUTPUT_CHANNELS; ch++ ) -#endif { output_f_local[ch] += n_samples_sf; } -#ifdef NONBE_UNIFIED_DECODING_PATHS /* update combined orientation access index */ ivas_combined_orientation_update_index( st_ivas->hCombinedOrientationData, n_samples_sf ); -#endif } for ( ch = 0; ch < MC_PARAMUPMIX_COMBINATIONS; ch++ ) @@ -693,10 +370,6 @@ ivas_error ivas_mc_paramupmix_dec_open( hMCParamUpmix->free_param_interpolator = 0; hMCParamUpmix->param_interpolator = NULL; -#ifndef NONBE_UNIFIED_DECODING_PATHS - if ( st_ivas->hDecoderConfig->Opt_5ms == 1 ) - { -#endif if ( ( hMCParamUpmix->param_interpolator = (float *) malloc( MAX_JBM_CLDFB_TIMESLOTS * sizeof( float ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for interpolator\n" ) ); @@ -704,15 +377,8 @@ ivas_error ivas_mc_paramupmix_dec_open( hMCParamUpmix->free_param_interpolator = 1; ivas_jbm_dec_get_adapted_linear_interpolator( DEFAULT_JBM_CLDFB_TIMESLOTS, DEFAULT_JBM_CLDFB_TIMESLOTS, hMCParamUpmix->param_interpolator ); -#ifndef NONBE_UNIFIED_DECODING_PATHS - } -#endif -#ifndef NONBE_UNIFIED_DECODING_PATHS - if ( st_ivas->hDecoderConfig->Opt_5ms == 1 && st_ivas->hTcBuffer == NULL ) -#else if ( st_ivas->hTcBuffer == NULL ) -#endif { int16_t nchan_to_allocate; int16_t nchan_tc; @@ -898,70 +564,6 @@ static void ivas_param_upmix_dec_decorr_subframes( /*****************************************************************************************/ /* local functions */ /*****************************************************************************************/ -#ifndef NONBE_UNIFIED_DECODING_PATHS_FIX -static void ps_pred_process( - MC_PARAMUPMIX_DEC_HANDLE hMCParamUpmix, - float qmf_mod_re[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* in/out */ - float qmf_mod_im[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - float qmf_side_re[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* in/out */ - float qmf_side_im[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - const int16_t ch ) -{ - float vmre, vmim, vsre, vsim; - int16_t iqmf, ipar, ismp, iismp; - float alpha_smp, dalpha, beta_smp, dbeta; - float *alpha1, *alpha2; - float *beta1, *beta2; - float *alpha_prev = hMCParamUpmix->alpha_prev[ch]; - float *beta_prev = hMCParamUpmix->beta_prev[ch]; - - const int16_t qmf_to_par_band[] = { - 0, 1, 2, 3, 4, 5, 5, 6, 6, 7, - 7, 7, 8, 8, 8, 8, 9, 9, 9, 9, - 9, 9, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11 - }; - - for ( iqmf = 0; iqmf < CLDFB_NO_CHANNELS_MAX; iqmf++ ) - { - /* For changing no of parameter bands (ipar1 != ipar2), TIGGER_FRAMING assumed */ - ipar = qmf_to_par_band[iqmf]; - alpha1 = alpha_prev; - beta1 = beta_prev; - - ismp = 0; - alpha2 = hMCParamUpmix->alphas[ch]; - beta2 = hMCParamUpmix->betas[ch]; - alpha_smp = alpha1[ipar]; - beta_smp = beta1[ipar]; - dalpha = ( alpha2[ipar] - alpha1[ipar] ) / CLDFB_NO_COL_MAX; - dbeta = ( beta2[ipar] - beta1[ipar] ) / CLDFB_NO_COL_MAX; - - for ( iismp = 0; iismp < CLDFB_NO_COL_MAX; iismp++ ) - { - alpha_smp += dalpha; - beta_smp += dbeta; - - vmre = qmf_mod_re[ismp][iqmf]; - vmim = qmf_mod_im[ismp][iqmf]; - vsre = qmf_side_re[ismp][iqmf]; - vsim = qmf_side_im[ismp][iqmf]; - - qmf_side_re[ismp][iqmf] = alpha_smp * vmre + beta_smp * vsre; - qmf_side_im[ismp][iqmf] = alpha_smp * vmim + beta_smp * vsim; - - ismp++; - } - - alpha1 = alpha2; - beta1 = beta2; - } - - return; -} -#endif static void ps_pred_process_sf( MC_PARAMUPMIX_DEC_HANDLE hMCParamUpmix, @@ -1191,9 +793,6 @@ static void ivas_mc_paramupmix_dec_sf( &st_ivas->hSplitBinRend.splitrend.multiBinPoseData, #endif st_ivas->hCombinedOrientationData, -#ifndef NONBE_UNIFIED_DECODING_PATHS - subframeIdx, -#endif st_ivas->hTcBuffer->subframe_nbslots[subframeIdx], Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, Cldfb_RealBuffer_subfr, @@ -1296,53 +895,6 @@ static void ivas_mc_paramupmix_dec_sf( return; } -#ifndef NONBE_UNIFIED_DECODING_PATHS_FIX -static void paramupmix_td_decorr_process( - ivas_td_decorr_state_t *hTdDecorr[], /* i/o: SPAR Covar. decoder handle */ - float *pcm_in[], /* i : input audio channels */ - float **pp_out_pcm, /* o : output audio channels */ - const int16_t output_frame /* i : output frame length */ -) -{ - int16_t j, k; - int16_t offset; - float in_duck_gain[L_FRAME48k], out_duck_gain[L_FRAME48k]; - - offset = (int16_t) ( output_frame * FRAMES_PER_SEC * IVAS_DECORR_PARM_LOOKAHEAD_TAU ); - - /* Look-ahead delay */ - for ( k = 0; k < MC_PARAMUPMIX_COMBINATIONS; k++ ) - { - mvr2r( pcm_in[k], pp_out_pcm[k], output_frame ); - delay_signal( pp_out_pcm[k], output_frame, hTdDecorr[k]->look_ahead_buf, offset ); - - /* In ducking gains */ - if ( hTdDecorr[k]->ducking_flag ) - { - ivas_td_decorr_get_ducking_gains( hTdDecorr[k]->pTrans_det, pcm_in[k], in_duck_gain, out_duck_gain, output_frame, 0 ); - - for ( j = 0; j < output_frame; j++ ) - { - pp_out_pcm[k][j] = pp_out_pcm[k][j] * in_duck_gain[j]; - } - } - - /* All pass delay section */ - ivas_td_decorr_APD_iir_filter( &hTdDecorr[k]->APD_filt_state[0], pp_out_pcm[k], hTdDecorr[k]->num_apd_sections, output_frame ); - - /* Out ducking gains */ - if ( hTdDecorr[k]->ducking_flag ) - { - for ( j = 0; j < output_frame; j++ ) - { - pp_out_pcm[k][j] = pp_out_pcm[k][j] * out_duck_gain[j]; - } - } - } - - return; -} -#endif static int16_t huff_read( Decoder_State *st, @@ -1364,19 +916,10 @@ static int16_t huff_read( static void huffman_decode( Decoder_State *st, -#ifndef FIX_891_PARAMUPMIX_CLEANUP - const int16_t nv, - const int16_t ivStart, - const PAR_TYPE parType, - const QUANT_TYPE quant_type, - const int16_t bNoDt, -#else const PAR_TYPE parType, -#endif int32_t *vq ) { const int16_t( *huff_node_table )[2]; -#ifdef FIX_891_PARAMUPMIX_CLEANUP int16_t iv, nquant, offset; nquant = 0; @@ -1393,38 +936,8 @@ static void huffman_decode( } offset = nquant - 1; /* range of df [-(nquant - 1), nquant - 1] */ -#else - int16_t iv, bdt, nquant, offset; - nquant = 0; - switch ( parType ) - { - case ALPHA: - nquant = ivas_mc_paramupmix_alpha_quant_table[quant_type].nquant; - break; - case BETA: - nquant = ivas_mc_paramupmix_beta_quant_table[quant_type][0].nquant; - break; - default: - assert( 0 ); - } - offset = nquant - 1; /* range of df/dt [-(nquant - 1), nquant - 1] */ -#endif - -#ifdef FIX_891_PARAMUPMIX_CLEANUP st->next_bit_pos++; -#else - if ( bNoDt ) - { - bdt = 0; - } - else - { - bdt = st->bit_stream[st->next_bit_pos]; - st->next_bit_pos++; - } -#endif -#ifdef FIX_891_PARAMUPMIX_CLEANUP switch ( parType ) { case ALPHA: @@ -1455,76 +968,16 @@ static void huffman_decode( { vq[iv] = huff_read( st, huff_node_table ) + vq[iv - 1] - offset; } -#else - if ( bdt ) - { /* Get dt */ - switch ( parType ) - { - case ALPHA: - huff_node_table = ivas_mc_paramupmix_huff_nodes_dt.alpha[quant_type]; - break; - case BETA: - huff_node_table = ivas_mc_paramupmix_huff_nodes_dt.beta[quant_type]; - break; - default: - huff_node_table = NULL; - assert( 0 ); - } - for ( iv = ivStart; iv < nv; iv++ ) - { - vq[iv] = huff_read( st, huff_node_table ) + vq[iv] - offset; - } - } - else /* Get f0, df */ - { - switch ( parType ) - { - case ALPHA: - huff_node_table = ivas_mc_paramupmix_huff_nodes_df0.alpha[quant_type]; - break; - case BETA: - huff_node_table = ivas_mc_paramupmix_huff_nodes_df0.beta[quant_type]; - break; - default: - huff_node_table = NULL; - assert( 0 ); - } - vq[ivStart] = huff_read( st, huff_node_table ); - - switch ( parType ) - { - case ALPHA: - huff_node_table = ivas_mc_paramupmix_huff_nodes_df.alpha[quant_type]; - break; - case BETA: - huff_node_table = ivas_mc_paramupmix_huff_nodes_df.beta[quant_type]; - break; - default: - assert( 0 ); - } - - for ( iv = ivStart + 1; iv < nv; iv++ ) - { - vq[iv] = huff_read( st, huff_node_table ) + vq[iv - 1] - offset; - } - } -#endif return; } static void dequant_alpha( -#ifndef FIX_891_PARAMUPMIX_CLEANUP - const int16_t nv, - const int16_t ivStart, - const QUANT_TYPE quant_type, -#endif int32_t *vq, float *v ) { int16_t iv; -#ifdef FIX_891_PARAMUPMIX_CLEANUP const ACPL_QUANT_TABLE *quant_table = &ivas_mc_paramupmix_alpha_quant_table; for ( iv = 0; iv < IVAS_MAX_NUM_BANDS; iv++ ) @@ -1532,29 +985,11 @@ static void dequant_alpha( v[iv] = quant_table->data[vq[iv]]; } -#else - const ACPL_QUANT_TABLE *quant_table = &ivas_mc_paramupmix_alpha_quant_table[quant_type]; - - for ( iv = 0; iv < ivStart; iv++ ) - { - v[iv] = 0; - } - - for ( iv = ivStart; iv < nv; iv++ ) - { - v[iv] = quant_table->data[vq[iv]]; - } -#endif return; } static void dequant_beta( -#ifndef FIX_891_PARAMUPMIX_CLEANUP - const int16_t nv, - const int16_t ivStart, - const QUANT_TYPE quant_type, -#endif int32_t *aq, int32_t *bq, float *beta ) @@ -1562,25 +997,12 @@ static void dequant_beta( int16_t iv; const ACPL_QUANT_TABLE *quant_table; -#ifdef FIX_891_PARAMUPMIX_CLEANUP for ( iv = 0; iv < IVAS_MAX_NUM_BANDS; iv++ ) { quant_table = &ivas_mc_paramupmix_beta_quant_table[ivas_param_upmx_mx_qmap[aq[iv]]]; beta[iv] = quant_table->data[bq[iv]]; } -#else - for ( iv = 0; iv < ivStart; iv++ ) - { - beta[iv] = 0; - } - - for ( iv = ivStart; iv < nv; iv++ ) - { - quant_table = &ivas_mc_paramupmix_beta_quant_table[quant_type][ivas_param_upmx_mx_qmap[quant_type][aq[iv]]]; - beta[iv] = quant_table->data[bq[iv]]; - } -#endif return; } @@ -1588,38 +1010,20 @@ static void dequant_beta( static void get_ec_data( Decoder_State *st, const PAR_TYPE parType, -#ifndef FIX_891_PARAMUPMIX_CLEANUP - const QUANT_TYPE quant_type, - const int16_t nParBand, - const int16_t parBandStart, -#endif int32_t *parQ, int32_t *alphaQEnv, float ab[IVAS_MAX_NUM_BANDS] ) { -#ifdef FIX_891_PARAMUPMIX_CLEANUP huffman_decode( st, parType, parQ ); -#else - huffman_decode( st, nParBand, parBandStart, parType, quant_type, 0, parQ ); -#endif if ( parType == ALPHA ) { -#ifdef FIX_891_PARAMUPMIX_CLEANUP dequant_alpha( parQ, ab ); mvl2l( parQ, alphaQEnv, (int16_t) IVAS_MAX_NUM_BANDS ); -#else - dequant_alpha( nParBand, parBandStart, quant_type, parQ, ab ); - mvl2l( parQ, alphaQEnv, (int16_t) nParBand ); -#endif } else { -#ifdef FIX_891_PARAMUPMIX_CLEANUP dequant_beta( alphaQEnv, parQ, ab ); -#else - dequant_beta( nParBand, parBandStart, quant_type, alphaQEnv, parQ, ab ); -#endif } return; diff --git a/lib_dec/ivas_mct_dec.c b/lib_dec/ivas_mct_dec.c index 6d7f80dd9..4e6397b26 100644 --- a/lib_dec/ivas_mct_dec.c +++ b/lib_dec/ivas_mct_dec.c @@ -773,10 +773,6 @@ static ivas_error ivas_mc_dec_reconfig( /* side effect of the renderer selection can be a changed internal config */ ivas_output_init( &( st_ivas->hIntSetup ), st_ivas->intern_config ); -#ifndef NONBE_UNIFIED_DECODING_PATHS - if ( st_ivas->hDecoderConfig->Opt_5ms ) - { -#endif /* transfer subframe info from DirAC or ParamMC to central tc buffer */ if ( last_mc_mode == MC_MODE_PARAMMC ) { @@ -817,9 +813,6 @@ static ivas_error ivas_mc_dec_reconfig( return error; } } -#ifndef NONBE_UNIFIED_DECODING_PATHS - } -#endif if ( st_ivas->mc_mode == MC_MODE_MCT ) { @@ -1332,9 +1325,6 @@ static ivas_error ivas_mc_dec_reconfig( * JBM TC buffers *-----------------------------------------------------------------*/ -#ifndef NONBE_UNIFIED_DECODING_PATHS - if ( st_ivas->hDecoderConfig->Opt_5ms == 1 ) -#endif { int16_t tc_nchan_full_new; DECODER_TC_BUFFER_HANDLE hTcBuffer; @@ -1402,19 +1392,12 @@ static ivas_error ivas_mc_dec_reconfig( * floating-point output audio buffers *-----------------------------------------------------------------*/ -#ifndef NONBE_UNIFIED_DECODING_PATHS - if ( !st_ivas->hDecoderConfig->Opt_5ms ) - { -#endif nchan_out_buff = ivas_get_nchan_buffers_dec( st_ivas, -1, -1 ); if ( ( error = ivas_output_buff_dec( st_ivas->p_output_f, nchan_out_buff_old, nchan_out_buff ) ) != IVAS_ERR_OK ) { return error; } -#ifndef NONBE_UNIFIED_DECODING_PATHS - } -#endif return error; } diff --git a/lib_dec/ivas_mdct_core_dec.c b/lib_dec/ivas_mdct_core_dec.c index afa3faebb..0b13c274d 100644 --- a/lib_dec/ivas_mdct_core_dec.c +++ b/lib_dec/ivas_mdct_core_dec.c @@ -286,11 +286,7 @@ static void dec_prm_tcx_spec( void ivas_mdct_dec_side_bits_frame_channel( CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */ -#ifdef FIX_887_ARRAY_SIZE_DFT_MDCT_STEREO int16_t param_lpc[CPE_CHANNELS][NPRM_LPC_NEW], /* o : lpc_parameters */ -#else - int16_t param_lpc[MCT_MAX_CHANNELS][NPRM_LPC_NEW], /* o : lpc_parameters */ -#endif int16_t p_param[CPE_CHANNELS][NB_DIV], /* o : pointer to param buffer */ Decoder_State *st0, /* i : pointer to bitstream handle */ int16_t nTnsBitsTCX10[CPE_CHANNELS][NB_DIV], /* o : number of bits for TNS */ diff --git a/lib_dec/ivas_objectRenderer_internal.c b/lib_dec/ivas_objectRenderer_internal.c index a0f522711..9991ed32a 100644 --- a/lib_dec/ivas_objectRenderer_internal.c +++ b/lib_dec/ivas_objectRenderer_internal.c @@ -98,16 +98,8 @@ ivas_error ivas_td_binaural_renderer( ism_md_subframe_update = 2; } -#ifdef NONBE_UNIFIED_DECODING_PATHS return ivas_td_binaural_renderer_unwrap( st_ivas->hReverb, st_ivas->transport_config, st_ivas->hBinRendererTd, nchan_transport, LFE_CHANNEL, st_ivas->ivas_format, st_ivas->hIsmMetaData, st_ivas->hCombinedOrientationData, ism_md_subframe_update, output, output_frame, MAX_PARAM_SPATIAL_SUBFRAMES ); -#else - return ivas_td_binaural_renderer_unwrap( st_ivas->hReverb, st_ivas->transport_config, st_ivas->hBinRendererTd, nchan_transport, LFE_CHANNEL, st_ivas->ivas_format, st_ivas->hIsmMetaData, - ( st_ivas->hCombinedOrientationData != NULL ) ? st_ivas->hCombinedOrientationData->enableCombinedOrientation : NULL, - ( st_ivas->hCombinedOrientationData != NULL ) ? st_ivas->hCombinedOrientationData->Quaternions : NULL, - ( st_ivas->hCombinedOrientationData != NULL ) ? st_ivas->hCombinedOrientationData->listenerPos : NULL, - ism_md_subframe_update, output, output_frame, MAX_PARAM_SPATIAL_SUBFRAMES ); -#endif } @@ -226,15 +218,9 @@ ivas_error ivas_td_binaural_renderer_sf( /* Update the listener's location/orientation */ if ( ( error = TDREND_Update_listener_orientation( st_ivas->hBinRendererTd, -#ifdef NONBE_UNIFIED_DECODING_PATHS ( st_ivas->hCombinedOrientationData != NULL ) ? st_ivas->hCombinedOrientationData->enableCombinedOrientation[st_ivas->hCombinedOrientationData->subframe_idx] : 0, ( st_ivas->hCombinedOrientationData != NULL ) ? &st_ivas->hCombinedOrientationData->Quaternions[st_ivas->hCombinedOrientationData->subframe_idx] : NULL, ( st_ivas->hCombinedOrientationData != NULL ) ? &st_ivas->hCombinedOrientationData->listenerPos[st_ivas->hCombinedOrientationData->subframe_idx] : NULL -#else - ( st_ivas->hCombinedOrientationData != NULL ) ? st_ivas->hCombinedOrientationData->enableCombinedOrientation[subframe_idx] : 0, - ( st_ivas->hCombinedOrientationData != NULL ) ? st_ivas->hCombinedOrientationData->Quaternions : NULL, - ( st_ivas->hCombinedOrientationData != NULL ) ? st_ivas->hCombinedOrientationData->listenerPos : NULL -#endif ) ) != IVAS_ERR_OK ) { return error; @@ -274,10 +260,8 @@ ivas_error ivas_td_binaural_renderer_sf( output_f_local[ch] += output_frame; } -#ifdef NONBE_UNIFIED_DECODING_PATHS /* update combined orientation access index */ ivas_combined_orientation_update_index( st_ivas->hCombinedOrientationData, output_frame ); -#endif } st_ivas->hTcBuffer->subframes_rendered = last_sf; @@ -286,7 +270,6 @@ ivas_error ivas_td_binaural_renderer_sf( } -#ifdef NONBE_UNIFIED_DECODING_PATHS #ifdef SPLIT_REND_WITH_HEAD_ROT /*---------------------------------------------------------------------* * ivas_td_binaural_renderer_sf_splitBinaural() @@ -309,9 +292,7 @@ ivas_error ivas_td_binaural_renderer_sf_splitBinaural( int16_t original_subframes_rendered; int16_t original_slots_rendered; float *p_bin_output[BINAURAL_CHANNELS]; -#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX float output_local[MAX_OUTPUT_CHANNELS][L_FRAME48k]; // VE2SB: TBV -#endif push_wmops( "ivas_td_binaural_renderer_sf_splitBinaural" ); pMultiBinPoseData = &st_ivas->hSplitBinRend.splitrend.multiBinPoseData; @@ -381,11 +362,7 @@ ivas_error ivas_td_binaural_renderer_sf_splitBinaural( /* set output channels */ for ( i = 0; i < BINAURAL_CHANNELS; i++ ) { -#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX p_bin_output[i] = output_local[pos_idx * BINAURAL_CHANNELS + i]; -#else - p_bin_output[i] = output[pos_idx * BINAURAL_CHANNELS + i]; -#endif } st_ivas->hTcBuffer->subframes_rendered = original_subframes_rendered; st_ivas->hTcBuffer->slots_rendered = original_slots_rendered; @@ -405,12 +382,10 @@ ivas_error ivas_td_binaural_renderer_sf_splitBinaural( } } -#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX for ( i = 0; i < pMultiBinPoseData->num_poses * BINAURAL_CHANNELS; i++ ) { mvr2r( output_local[i], output[i], nSamplesRendered ); } -#endif /* Restore original head rotation */ for ( i = 0; i < st_ivas->hCombinedOrientationData->num_subframes; ++i ) @@ -425,4 +400,3 @@ ivas_error ivas_td_binaural_renderer_sf_splitBinaural( return IVAS_ERR_OK; } #endif -#endif diff --git a/lib_dec/ivas_omasa_dec.c b/lib_dec/ivas_omasa_dec.c index 50f9b06be..9c0c891d8 100644 --- a/lib_dec/ivas_omasa_dec.c +++ b/lib_dec/ivas_omasa_dec.c @@ -415,18 +415,11 @@ ivas_error ivas_omasa_dec_config( * floating-point output audio buffers *-----------------------------------------------------------------*/ -#ifndef NONBE_UNIFIED_DECODING_PATHS - if ( !st_ivas->hDecoderConfig->Opt_5ms ) - { -#endif nchan_out_buff = ivas_get_nchan_buffers_dec( st_ivas, -1, -1 ); if ( ( error = ivas_output_buff_dec( st_ivas->p_output_f, nchan_out_buff_old, nchan_out_buff ) ) != IVAS_ERR_OK ) { return error; } -#ifndef NONBE_UNIFIED_DECODING_PATHS - } -#endif } @@ -594,45 +587,6 @@ ivas_error ivas_omasa_ism_metadata_dec( return IVAS_ERR_OK; } -#ifndef NONBE_UNIFIED_DECODING_PATHS_FIX -/*--------------------------------------------------------------------------* - * ivas_omasa_dirac_rend() - * - * Rendering in OMASA format - *--------------------------------------------------------------------------*/ - -void ivas_omasa_dirac_rend( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - float *output[], /* o : output synthesis signal */ - const int16_t output_frame /* i : output frame length per channel */ -) -{ - int16_t n, dirac_read_idx; - float data_separated_objects[MAX_NUM_OBJECTS][L_FRAME48k]; - - if ( st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ ) - { - mvr2r( output[2], data_separated_objects[0], output_frame ); - } - else - { - for ( n = 0; n < st_ivas->nchan_ism; n++ ) - { - mvr2r( output[n + 2], data_separated_objects[n], output_frame ); - } - } - - dirac_read_idx = st_ivas->hSpatParamRendCom->dirac_read_idx; - - ivas_dirac_dec( st_ivas, output, st_ivas->nchan_transport, MAX_PARAM_SPATIAL_SUBFRAMES ); - - st_ivas->hSpatParamRendCom->dirac_read_idx = dirac_read_idx; /* Original read index is needed for the next function which will update it again */ - - ivas_omasa_separate_object_render( st_ivas, data_separated_objects, output, output_frame ); - - return; -} -#endif /*--------------------------------------------------------------------------* * ivas_omasa_dirac_rend_jbm() @@ -651,7 +605,6 @@ void ivas_omasa_dirac_rend_jbm( { int16_t subframes_rendered; int16_t slots_rendered; -#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX int16_t n; float data_separated_objects[MAX_NUM_OBJECTS][L_FRAME48k]; @@ -666,77 +619,17 @@ void ivas_omasa_dirac_rend_jbm( mvr2r( output_f[n + CPE_CHANNELS], data_separated_objects[n], nSamplesAsked ); } } -#endif subframes_rendered = st_ivas->hSpatParamRendCom->subframes_rendered; slots_rendered = st_ivas->hSpatParamRendCom->slots_rendered; ivas_dirac_dec_render( st_ivas, nchan_transport, nSamplesAsked, nSamplesRendered, nSamplesAvailable, output_f ); -#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX ivas_omasa_separate_object_render_jbm( st_ivas, *nSamplesRendered, data_separated_objects, output_f, subframes_rendered, slots_rendered ); -#else - ivas_omasa_separate_object_render_jbm( st_ivas, *nSamplesRendered, output_f, subframes_rendered, slots_rendered ); -#endif return; } -#ifndef NONBE_UNIFIED_DECODING_PATHS -/*--------------------------------------------------------------------------* - * ivas_omasa_dirac_td_binaural() - * - * Binaural rendering in OMASA format - *--------------------------------------------------------------------------*/ - -ivas_error ivas_omasa_dirac_td_binaural( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - float *output[], /* o : output synthesis signal */ - const int16_t output_frame /* i : output frame length per channel */ -) -{ - int16_t n; - float data_separated_objects[MAX_NUM_OBJECTS][L_FRAME48k]; - float gain = OMASA_TDREND_MATCHING_GAIN; - ivas_error error; - float *p_sepobj[MAX_NUM_OBJECTS]; - - for ( n = 0; n < MAX_NUM_OBJECTS; n++ ) - { - p_sepobj[n] = &data_separated_objects[n][0]; - } - - for ( n = 0; n < st_ivas->nchan_ism; n++ ) - { - mvr2r( output[2 + n], data_separated_objects[n], output_frame ); - v_multc( data_separated_objects[n], gain, data_separated_objects[n], output_frame ); - } - - for ( n = 0; n < st_ivas->nchan_ism; n++ ) - { - delay_signal( data_separated_objects[n], output_frame, st_ivas->hMasaIsmData->delayBuffer[n], st_ivas->hMasaIsmData->delayBuffer_size ); - } - - ivas_dirac_dec_binaural( st_ivas, st_ivas->hCombinedOrientationData, output, st_ivas->nchan_transport, MAX_PARAM_SPATIAL_SUBFRAMES ); - -#ifdef NONBE_UNIFIED_DECODING_PATHS - /* reset combined orientation access index before calling the td renderer */ - ivas_combined_orientation_set_to_start_index( st_ivas->hCombinedOrientationData ); -#endif - - if ( ( error = ivas_td_binaural_renderer( st_ivas, p_sepobj, output_frame ) ) != IVAS_ERR_OK ) - { - return error; - } - - for ( n = 0; n < BINAURAL_CHANNELS; n++ ) - { - v_add( output[n], p_sepobj[n], output[n], output_frame ); - } - - return IVAS_ERR_OK; -} -#endif /*--------------------------------------------------------------------------* * ivas_omasa_dirac_td_binaural_render() @@ -782,10 +675,8 @@ ivas_error ivas_omasa_dirac_td_binaural_jbm( ivas_dirac_dec_binaural_render( st_ivas, nSamplesAsked, nSamplesRendered, nSamplesAvailable, nchan_transport, output_f ); -#ifdef NONBE_UNIFIED_DECODING_PATHS /* reset combined orientation access index before calling the td renderer */ ivas_combined_orientation_set_to_start_index( st_ivas->hCombinedOrientationData ); -#endif if ( ( error = ivas_td_binaural_renderer_sf( st_ivas, p_sepobj, *nSamplesRendered ) ) != IVAS_ERR_OK ) { diff --git a/lib_dec/ivas_osba_dec.c b/lib_dec/ivas_osba_dec.c index a30ddfb55..32c8b0fef 100644 --- a/lib_dec/ivas_osba_dec.c +++ b/lib_dec/ivas_osba_dec.c @@ -134,7 +134,6 @@ ivas_error ivas_osba_dirac_td_binaural_jbm( { int16_t n; ivas_error error; -#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX float output_separated_objects[BINAURAL_CHANNELS][L_FRAME48k]; // VE2SB: TBV float *p_sepobj[BINAURAL_CHANNELS]; int16_t channel_offset; @@ -145,13 +144,8 @@ ivas_error ivas_osba_dirac_td_binaural_jbm( } channel_offset = st_ivas->nchan_ism; -#endif -#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX if ( ( error = ivas_sba_dec_render( st_ivas, nSamplesAsked, nSamplesRendered, nSamplesAvailable, &output_f[channel_offset] ) ) != IVAS_ERR_OK ) -#else - if ( ( error = ivas_sba_dec_render( st_ivas, nSamplesAsked, nSamplesRendered, nSamplesAvailable, &output_f[2] ) ) != IVAS_ERR_OK ) -#endif { return error; } @@ -199,11 +193,7 @@ ivas_error ivas_osba_dirac_td_binaural_jbm( { #endif -#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX if ( ( error = ivas_td_binaural_renderer_sf( st_ivas, p_sepobj, *nSamplesRendered ) ) != IVAS_ERR_OK ) -#else - if ( ( error = ivas_td_binaural_renderer_sf( st_ivas, output_f, *nSamplesRendered ) ) != IVAS_ERR_OK ) -#endif { return error; } @@ -213,11 +203,7 @@ ivas_error ivas_osba_dirac_td_binaural_jbm( int16_t i; for ( i = 0; i < nSamplesAsked; i++ ) { -#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX output_f[n][i] = 0.5f * output_f[channel_offset + n][i] + 0.5f * p_sepobj[n][i]; -#else - output_f[n][i] = 0.5f * output_f[2 + n][i] + 0.5f * output_f[n][i]; -#endif } } #ifdef SPLIT_REND_WITH_HEAD_ROT @@ -226,141 +212,6 @@ ivas_error ivas_osba_dirac_td_binaural_jbm( return IVAS_ERR_OK; } -#ifndef NONBE_UNIFIED_DECODING_PATHS_FIX -/*--------------------------------------------------------------------------* - * ivas_osba_dirac_td_binaural() - * - * Binaural rendering in OSBA format - *--------------------------------------------------------------------------*/ - -ivas_error ivas_osba_dirac_td_binaural( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - float *output[], /* o : output synthesis signal */ - const int16_t output_frame /* i : output frame length per channel */ -) -{ - int16_t n; - float data_separated_objects[MAX_NUM_OBJECTS][L_FRAME48k]; - ivas_error error; - float *p_sepobj[MAX_NUM_OBJECTS]; - int16_t channel_offset; - - for ( n = 0; n < MAX_NUM_OBJECTS; n++ ) - { - p_sepobj[n] = &data_separated_objects[n][0]; - } - - channel_offset = st_ivas->nchan_ism; - - for ( n = 0; n < st_ivas->nchan_ism; n++ ) - { - mvr2r( output[n], data_separated_objects[n], output_frame ); - } - -#ifdef SPLIT_REND_WITH_HEAD_ROT - if ( st_ivas->hDecoderConfig->output_config != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED && st_ivas->hDecoderConfig->output_config != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) -#endif - { - for ( n = 0; n < st_ivas->nchan_ism; n++ ) - { - delay_signal( data_separated_objects[n], output_frame, st_ivas->hSbaIsmData->delayBuffer[n], st_ivas->hSbaIsmData->delayBuffer_size ); - } - } - - if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV ) - { - if ( ( error = ivas_sba_upmixer_renderer( st_ivas, output, output_frame ) ) != IVAS_ERR_OK ) - { - return error; - } - } - else - { - ivas_dirac_dec_binaural( st_ivas, st_ivas->hCombinedOrientationData, &output[channel_offset], st_ivas->nchan_transport, MAX_PARAM_SPATIAL_SUBFRAMES ); - } - -#ifdef DEBUG_OSBA - { - for ( int16_t t = 0; t < output_frame; t++ ) - { - for ( int16_t c = 0; c < BINAURAL_CHANNELS; c++ ) - { - int16_t val = (int16_t) ( output[channel_offset + c][t] + 0.5f ); - dbgwrite( &val, sizeof( int16_t ), 1, 1, "./res/sba_fast_conv_out.raw" ); - } - } - } -#endif -#ifdef SPLIT_REND_WITH_HEAD_ROT - if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) - { - int16_t slot_idx, num_cldfb_bands, b, nchan_transport_orig; - float Cldfb_RealBuffer[CLDFB_NO_CHANNELS_MAX]; - float Cldfb_ImagBuffer[CLDFB_NO_CHANNELS_MAX]; - - num_cldfb_bands = st_ivas->hSplitBinRend.splitrend.hCldfbHandles->cldfbAna[0]->no_channels; - nchan_transport_orig = st_ivas->nchan_transport; - st_ivas->nchan_transport = st_ivas->nchan_ism; - - if ( ( error = ObjRenderIvasFrame_splitBinaural( st_ivas, output, output_frame ) ) != IVAS_ERR_OK ) - { - return error; - } - - st_ivas->nchan_transport = nchan_transport_orig; - - for ( n = 0; n < st_ivas->hSplitBinRend.splitrend.multiBinPoseData.num_poses * BINAURAL_CHANNELS; ++n ) - { - for ( slot_idx = 0; slot_idx < CLDFB_NO_COL_MAX; slot_idx++ ) - { - cldfbAnalysis_ts( &( output[n][num_cldfb_bands * slot_idx] ), Cldfb_RealBuffer, Cldfb_ImagBuffer, num_cldfb_bands, st_ivas->hSplitBinRend.splitrend.hCldfbHandles->cldfbAna[n] ); - - for ( b = 0; b < num_cldfb_bands; b++ ) - { - st_ivas->hSplitBinRend.hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[n][slot_idx][b] = - ( 0.5f * st_ivas->hSplitBinRend.hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[n][slot_idx][b] ) + - ( 0.5f * Cldfb_RealBuffer[b] ); - - st_ivas->hSplitBinRend.hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[n][slot_idx][b] = - ( 0.5f * st_ivas->hSplitBinRend.hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[n][slot_idx][b] ) + - ( 0.5f * Cldfb_ImagBuffer[b] ); - } - } - } - } - else - { -#endif - if ( ( error = ivas_td_binaural_renderer( st_ivas, p_sepobj, output_frame ) ) != IVAS_ERR_OK ) - { - return error; - } - -#ifdef DEBUG_OSBA - for ( int16_t t = 0; t < output_frame; t++ ) - { - for ( int16_t c = 0; c < BINAURAL_CHANNELS; c++ ) - { - int16_t val = (int16_t) ( p_sepobj[c][t] + 0.5f ); - dbgwrite( &val, sizeof( int16_t ), 1, 1, "./res/ism_td_bin_out.raw" ); - } - } -#endif - for ( n = 0; n < BINAURAL_CHANNELS; n++ ) - { - int16_t i; - for ( i = 0; i < output_frame; i++ ) - { - output[n][i] = 0.5f * output[channel_offset + n][i] + 0.5f * p_sepobj[n][i]; - } - } -#ifdef SPLIT_REND_WITH_HEAD_ROT - } -#endif - - return IVAS_ERR_OK; -} -#endif /*-------------------------------------------------------------------------* * ivas_osba_ism_metadata_dec() @@ -392,7 +243,6 @@ ivas_error ivas_osba_ism_metadata_dec( return IVAS_ERR_OK; } -#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX /*-------------------------------------------------------------------------* * ivas_osba_render_sf() * @@ -444,64 +294,3 @@ ivas_error ivas_osba_render_sf( return IVAS_ERR_OK; } -#else -/*-------------------------------------------------------------------------* - * ivas_osba_render() - * - * Object + SBA rendering process. - *-------------------------------------------------------------------------*/ - -ivas_error ivas_osba_render( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - float *output_f[], /* i/o: core-coder transport channels/object output */ - const int16_t output_frame /* i : output frame length per channel */ -) -{ - float tmp_ism_out[MAX_OUTPUT_CHANNELS][L_FRAME48k]; - float *p_tmp_ism_out[MAX_OUTPUT_CHANNELS]; - int16_t n, nchan_out, nchan_ism; - ivas_error error; - - nchan_out = st_ivas->hDecoderConfig->nchan_out; - nchan_ism = st_ivas->nchan_ism; - - for ( n = 0; n < max( nchan_out, nchan_ism ); n++ ) - { - p_tmp_ism_out[n] = &tmp_ism_out[n][0]; - } - - if ( st_ivas->ism_mode == ISM_SBA_MODE_DISC ) - { - for ( n = 0; n < nchan_ism; n++ ) - { - mvr2r( output_f[n], tmp_ism_out[n], output_frame ); - delay_signal( tmp_ism_out[n], output_frame, st_ivas->hSbaIsmData->delayBuffer[n], st_ivas->hSbaIsmData->delayBuffer_size ); - } - - if ( st_ivas->renderer_type == RENDERER_OSBA_AMBI ) - { - ivas_ism2sba( p_tmp_ism_out, st_ivas->hIsmRendererData, st_ivas->hIsmMetaData, st_ivas->nchan_ism, output_frame, st_ivas->hIntSetup.ambisonics_order ); - } - else - { - ivas_ism_render( st_ivas, p_tmp_ism_out, output_frame ); - } - } - - if ( ( error = ivas_sba_upmixer_renderer( st_ivas, output_f, output_frame ) ) != IVAS_ERR_OK ) - { - return error; - } - - if ( st_ivas->ism_mode == ISM_SBA_MODE_DISC ) - { - for ( n = 0; n < nchan_out; n++ ) - { - v_add( output_f[n + nchan_ism], tmp_ism_out[n], output_f[n], output_frame ); - v_multc( output_f[n], 0.5f, output_f[n], output_frame ); - } - } - - return IVAS_ERR_OK; -} -#endif diff --git a/lib_dec/ivas_rom_dec.c b/lib_dec/ivas_rom_dec.c index d05bf16fe..cfe91dfab 100644 --- a/lib_dec/ivas_rom_dec.c +++ b/lib_dec/ivas_rom_dec.c @@ -580,29 +580,6 @@ static const int16_t huff_nodes_first_band_alpha[32][2] = { -2, -32 } }; -#ifndef FIX_891_PARAMUPMIX_CLEANUP -/* Alpha Coarse Huffman table df0 */ -static const int16_t huff_nodes_first_band_alpha_coarse[16][2] = -{ - { -9, 1 }, - { -8, 2 }, - { -10, 3 }, - { 5, 4 }, - { -7, 6 }, - { -11, 7 }, - { -5, 8 }, - { -6, 9 }, - { -12, 10 }, - { -13, 11 }, - { -4, 12 }, - { -14, 13 }, - { -3, 14 }, - { -15, 15 }, - { -2, -16 }, - { -1, -17 } -}; - -#endif /* Alpha Fine Huffman table df */ static const int16_t huff_nodes_alpha_1D_DF[64][2] = { @@ -672,45 +649,6 @@ static const int16_t huff_nodes_alpha_1D_DF[64][2] = { -2, -62 } }; -#ifndef FIX_891_PARAMUPMIX_CLEANUP -/* Alpha Coarse Huffman table df */ -static const int16_t huff_nodes_alpha_1D_DF_coarse[32][2] = -{ - { -17, 1 }, - { -18, 2 }, - { -16, 3 }, - { -15, 4 }, - { -19, 5 }, - { 7, 6 }, - { -14, -20 }, - { 9, 8 }, - { -13, -21 }, - { 11, 10 }, - { -22, 12 }, - { -12, 13 }, - { -23, 14 }, - { -11, 15 }, - { -10, 16 }, - { -24, 17 }, - { -9, -25 }, - { 19, 18 }, - { -26, 20 }, - { -8, 21 }, - { 23, 22 }, - { 25, 24 }, - { -27, 26 }, - { -7, 27 }, - { -1, -33 }, - { -6, 28 }, - { -28, 29 }, - { -29, 30 }, - { -5, -31 }, - { -30, 31 }, - { -3, -4 }, - { -2, -32 } -}; - -#endif /* Alpha Fine Huffman table dt */ static const int16_t huff_nodes_alpha_1D_DT[64][2] = { @@ -780,88 +718,25 @@ static const int16_t huff_nodes_alpha_1D_DT[64][2] = { -2, -63 } }; -#ifndef FIX_891_PARAMUPMIX_CLEANUP -/* Alpha Coarse Huffman table dt */ -static const int16_t huff_nodes_alpha_1D_DT_coarse[32][2] = -{ - { -17, 1 }, - { -18, 2 }, - { -16, 3 }, - { -19, 4 }, - { -15, 5 }, - { 7, 6 }, - { -14, -20 }, - { 9, 8 }, - { -21, 10 }, - { -13, 11 }, - { 13, 12 }, - { -12, -22 }, - { 15, 14 }, - { -11, -23 }, - { 17, 16 }, - { -24, 18 }, - { -10, 19 }, - { -25, 20 }, - { -9, 21 }, - { 23, 22 }, - { -26, 24 }, - { -8, 25 }, - { 27, 26 }, - { -1, -33 }, - { -7, -27 }, - { 29, 28 }, - { -28, 30 }, - { -6, 31 }, - { -5, -29 }, - { -3, -31 }, - { -4, -30 }, - { -2, -32 } -}; - -#endif /* Beta Fine Huffman table df0 */ static const int16_t huff_nodes_first_band_beta[8][2] = { { -1, 1 }, { -2, 2 }, { -3, 3 }, { -4, 4 }, { -5, 5 }, { -6, 6 }, { -7, 7 }, { -8, -9 } }; -#ifndef FIX_891_PARAMUPMIX_CLEANUP -/* Beta Coarse Huffman table df0 */ -static const int16_t huff_nodes_first_band_beta_coarse[4][2] = -{ - { -1, 1 }, { -2, 2 }, { -3, 3 }, { -4, -5 } -}; - -#endif /* Beta Fine Huffman table df */ static const int16_t huff_nodes_beta_1D_DF[16][2] = { { -9, 1 }, { -10, 2 }, { -8, 3 }, { -11, 4 }, { -7, 5 }, { 7, 6 }, { -6, -12 }, { 9, 8 }, { -5, -13 }, { 11, 10 }, { -4, -14 }, { -15, 12 }, { -3, 13 }, { -16, 14 }, { -2, 15 }, { -1, -17 } }; -#ifndef FIX_891_PARAMUPMIX_CLEANUP -/* Beta Coarse Huffman table df */ -static const int16_t huff_nodes_beta_1D_DF_coarse[8][2] = -{ - { -5, 1 }, { -6, 2 }, { -4, 3 }, { -3, 4 }, { -7, 5 }, { -2, 6 }, { -8, 7 }, { -1, -9 } -}; - -#endif /* Beta Fine Huffman table dt */ static const int16_t huff_nodes_beta_1D_DT[16][2] = { { -9, 1 }, { -10, 2 }, { -8, 3 }, { -11, 4 }, { -7, 5 }, { 7, 6 }, { -6, -12 }, { -13, 8 }, { -5, 9 }, { -14, 10 }, { -4, 11 }, { -15, 12 }, { -3, 13 }, { -16, 14 }, { -2, 15 }, { -1, -17 } }; -#ifndef FIX_891_PARAMUPMIX_CLEANUP -/* Beta Coarse Huffman table dt */ -static const int16_t huff_nodes_beta_1D_DT_coarse[8][2] = -{ - { -5, 1 }, { -6, 2 }, { -4, 3 }, { -7, 4 }, { -3, 5 }, { -8, 6 }, { -2, 7 }, { -1, -9 } -}; -#endif -#ifdef FIX_891_PARAMUPMIX_CLEANUP const HUFF_NODE_TABLE ivas_mc_paramupmix_huff_nodes_df0 = { huff_nodes_first_band_alpha, @@ -879,24 +754,6 @@ const HUFF_NODE_TABLE ivas_mc_paramupmix_huff_nodes_dt = huff_nodes_alpha_1D_DT, huff_nodes_beta_1D_DT }; -#else -const HUFF_NODE_TABLE ivas_mc_paramupmix_huff_nodes_df0 = -{ - { huff_nodes_first_band_alpha, huff_nodes_first_band_alpha_coarse }, - { huff_nodes_first_band_beta, huff_nodes_first_band_beta_coarse } -}; -const HUFF_NODE_TABLE ivas_mc_paramupmix_huff_nodes_df = -{ - { huff_nodes_alpha_1D_DF, huff_nodes_alpha_1D_DF_coarse }, - { huff_nodes_beta_1D_DF, huff_nodes_beta_1D_DF_coarse } -}; - -const HUFF_NODE_TABLE ivas_mc_paramupmix_huff_nodes_dt = -{ - { huff_nodes_alpha_1D_DT, huff_nodes_alpha_1D_DT_coarse }, - { huff_nodes_beta_1D_DT, huff_nodes_beta_1D_DT_coarse } -}; -#endif /* clang-format on */ diff --git a/lib_dec/ivas_sba_dec.c b/lib_dec/ivas_sba_dec.c index d5b5d8ff1..d16237557 100644 --- a/lib_dec/ivas_sba_dec.c +++ b/lib_dec/ivas_sba_dec.c @@ -119,9 +119,6 @@ ivas_error ivas_sba_dec_reconfigure( int32_t last_ivas_total_brate; int16_t num_channels, num_md_sub_frames; int16_t nchan_out_buff, nchan_out_buff_old; -#ifndef NONBE_UNIFIED_DECODING_PATHS - int16_t sba_analysis_order_old; -#endif int16_t sba_analysis_order_old_flush; DECODER_CONFIG_HANDLE hDecoderConfig; ivas_error error; @@ -133,20 +130,13 @@ ivas_error ivas_sba_dec_reconfigure( ivas_total_brate = hDecoderConfig->ivas_total_brate; last_ivas_total_brate = st_ivas->last_active_ivas_total_brate; sba_analysis_order_old_flush = st_ivas->sba_analysis_order; -#ifndef NONBE_UNIFIED_DECODING_PATHS - sba_analysis_order_old = ivas_sba_get_analysis_order( last_ivas_total_brate, st_ivas->sba_order ); -#endif /*-----------------------------------------------------------------* * Set SBA high-level parameters * Save old SBA high-level parameters *-----------------------------------------------------------------*/ -#ifdef NONBE_UNIFIED_DECODING_PATHS nchan_out_buff_old = ivas_get_nchan_buffers_dec( st_ivas, sba_analysis_order_old_flush, last_ivas_total_brate ); -#else - nchan_out_buff_old = ivas_get_nchan_buffers_dec( st_ivas, sba_analysis_order_old, last_ivas_total_brate ); -#endif ivas_init_dec_get_num_cldfb_instances( st_ivas, &numCldfbAnalyses_old, &numCldfbSyntheses_old ); nchan_hp20_old = getNumChanSynthesis( st_ivas ); @@ -253,7 +243,6 @@ ivas_error ivas_sba_dec_reconfigure( { return error; } -#ifdef NONBE_FIX_904_JBM_SBA_RS_FOA /* make sure the changed number of slots in the last subframe is not lost in the following steps */ if ( st_ivas->hSpatParamRendCom != NULL ) @@ -261,7 +250,6 @@ ivas_error ivas_sba_dec_reconfigure( st_ivas->hSpatParamRendCom->subframe_nbslots[st_ivas->hSpatParamRendCom->nb_subframes - 1] = st_ivas->hTcBuffer->subframe_nbslots[st_ivas->hTcBuffer->nb_subframes - 1]; } st_ivas->hSpar->subframe_nbslots[st_ivas->hSpar->nb_subframes - 1] = st_ivas->hTcBuffer->subframe_nbslots[st_ivas->hTcBuffer->nb_subframes - 1]; -#endif } } @@ -402,10 +390,8 @@ ivas_error ivas_sba_dec_reconfigure( } if ( ( error = ivas_dirac_sba_config( st_ivas->hQMetaData, &st_ivas->element_mode_init, ivas_total_brate, st_ivas->sba_analysis_order, ivas_get_hodirac_flag( ivas_total_brate, st_ivas->sba_analysis_order ) ? IVAS_MAX_NUM_BANDS : ( IVAS_MAX_NUM_BANDS - SPAR_DIRAC_SPLIT_START_BAND ) -#ifdef NONBE_FIX_871_ACELP_CRASH_IN_OSBA , st_ivas->ivas_format -#endif ) ) != IVAS_ERR_OK ) { return error; @@ -604,9 +590,6 @@ ivas_error ivas_sba_dec_reconfigure( * JBM TC buffers *-----------------------------------------------------------------*/ -#ifndef NONBE_UNIFIED_DECODING_PATHS - if ( st_ivas->hDecoderConfig->Opt_5ms == 1 || st_ivas->ivas_format == SBA_ISM_FORMAT ) -#endif { int16_t tc_nchan_to_allocate; int16_t tc_nchan_tc; @@ -660,7 +643,6 @@ ivas_error ivas_sba_dec_reconfigure( } /* resync SPAR and DirAC JBM info from TC Buffer */ -#ifdef NONBE_FIX_904_JBM_SBA_RS_FOA if ( st_ivas->hSpatParamRendCom != NULL && st_ivas->hSpatParamRendCom->slot_size == st_ivas->hTcBuffer->n_samples_granularity ) { mvs2s( st_ivas->hTcBuffer->subframe_nbslots, st_ivas->hSpatParamRendCom->subframe_nbslots, MAX_JBM_SUBFRAMES_5MS ); @@ -670,21 +652,6 @@ ivas_error ivas_sba_dec_reconfigure( mvs2s( st_ivas->hTcBuffer->subframe_nbslots, st_ivas->hSpar->subframe_nbslots, MAX_JBM_SUBFRAMES_5MS ); st_ivas->hSpar->nb_subframes = st_ivas->hTcBuffer->nb_subframes; st_ivas->hSpar->subframes_rendered = st_ivas->hTcBuffer->subframes_rendered; -#else - if ( st_ivas->hSpatParamRendCom != NULL ) - { - if ( st_ivas->hSpatParamRendCom->slot_size == st_ivas->hTcBuffer->n_samples_granularity ) - { - mvs2s( st_ivas->hTcBuffer->subframe_nbslots, st_ivas->hSpatParamRendCom->subframe_nbslots, MAX_JBM_SUBFRAMES_5MS ); - st_ivas->hSpatParamRendCom->nb_subframes = st_ivas->hTcBuffer->nb_subframes; - st_ivas->hSpatParamRendCom->subframes_rendered = st_ivas->hTcBuffer->subframes_rendered; - - mvs2s( st_ivas->hTcBuffer->subframe_nbslots, st_ivas->hSpar->subframe_nbslots, MAX_JBM_SUBFRAMES_5MS ); - st_ivas->hSpar->nb_subframes = st_ivas->hTcBuffer->nb_subframes; - st_ivas->hSpar->subframes_rendered = st_ivas->hTcBuffer->subframes_rendered; - } - } -#endif if ( st_ivas->ivas_format == SBA_ISM_FORMAT && st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV && st_ivas->ism_mode == ISM_SBA_MODE_DISC ) { @@ -693,9 +660,7 @@ ivas_error ivas_sba_dec_reconfigure( for ( n = 0; n < MAX_JBM_SUBFRAMES_5MS; n++ ) { st_ivas->hSpatParamRendCom->subframe_nbslots[n] = st_ivas->hTcBuffer->subframe_nbslots[n] * granularityMultiplier; -#ifdef NONBE_FIX_904_JBM_SBA_RS_FOA st_ivas->hSpar->subframe_nbslots[n] = st_ivas->hSpatParamRendCom->subframe_nbslots[n]; -#endif } } @@ -703,19 +668,12 @@ ivas_error ivas_sba_dec_reconfigure( * floating-point output audio buffers *-----------------------------------------------------------------*/ -#ifndef NONBE_UNIFIED_DECODING_PATHS - if ( !st_ivas->hDecoderConfig->Opt_5ms ) - { -#endif nchan_out_buff = ivas_get_nchan_buffers_dec( st_ivas, st_ivas->sba_analysis_order, st_ivas->hDecoderConfig->ivas_total_brate ); if ( ( error = ivas_output_buff_dec( st_ivas->p_output_f, nchan_out_buff_old, nchan_out_buff ) ) != IVAS_ERR_OK ) { return error; } -#ifndef NONBE_UNIFIED_DECODING_PATHS - } -#endif return error; } @@ -871,10 +829,8 @@ ivas_error ivas_sba_dec_render( output_f_local[ch] += n_samples_sf; } -#ifdef NONBE_UNIFIED_DECODING_PATHS /* update combined orientation access index */ ivas_combined_orientation_update_index( st_ivas->hCombinedOrientationData, n_samples_sf ); -#endif } if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_DEC ) diff --git a/lib_dec/ivas_sba_dirac_stereo_dec.c b/lib_dec/ivas_sba_dirac_stereo_dec.c index d611eadfd..ae1a2df0c 100644 --- a/lib_dec/ivas_sba_dirac_stereo_dec.c +++ b/lib_dec/ivas_sba_dirac_stereo_dec.c @@ -947,13 +947,11 @@ void ivas_sba_dirac_stereo_dec( } } -#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX /* reset the other channels to 0 (they are not used since here) */ for ( int16_t ch = CPE_CHANNELS; ch < st_ivas->nchan_transport; ch++ ) { set_zero( output[ch], output_frame ); } -#endif return; } diff --git a/lib_dec/ivas_sba_rendering_internal.c b/lib_dec/ivas_sba_rendering_internal.c index a87cdaca3..3d06dac2f 100644 --- a/lib_dec/ivas_sba_rendering_internal.c +++ b/lib_dec/ivas_sba_rendering_internal.c @@ -339,70 +339,6 @@ int16_t ivas_sba_remapTCs( return ( nchan_remapped ); } -#ifndef NONBE_UNIFIED_DECODING_PATHS_FIX -/*-------------------------------------------------------------------------* - * ivas_ism2sba() - * - * ISM transformed into SBA in TD domain. - *-------------------------------------------------------------------------*/ - -void ivas_ism2sba( - float *buffer_td[], /* i/o: TD signal buffers */ - ISM_RENDERER_HANDLE hIsmRendererData, /* i/o: renderer data */ - const ISM_METADATA_HANDLE hIsmMetaData[], /* i : object metadata */ - const int16_t nchan_ism, /* i : number of objects */ - const int16_t output_frame, /* i : output frame length per channel */ - const int16_t sba_order /* i : Ambisonic (SBA) order */ -) -{ - int16_t i, j, k; - float buffer_tmp[16][L_FRAME48k]; - float gains[16]; - float g1, g2; - int16_t azimuth, elevation; - int16_t sba_num_chans; - - assert( ( sba_order <= 3 ) && "Only order up to 3 is supported!" ); - assert( hIsmRendererData != NULL && "hIsmRendererData not allocated!" ); - - /* Init*/ - sba_num_chans = ( sba_order + 1 ) * ( sba_order + 1 ); - for ( j = 0; j < sba_num_chans; j++ ) - { - set_zero( buffer_tmp[j], output_frame ); - } - - for ( i = 0; i < nchan_ism; i++ ) - { - // TODO tmu review when #215 is resolved - azimuth = (int16_t) floorf( hIsmMetaData[i]->azimuth + 0.5f ); - elevation = (int16_t) floorf( hIsmMetaData[i]->elevation + 0.5f ); - - /*get HOA gets for direction (ACN/SN3D)*/ - ivas_dirac_dec_get_response( azimuth, elevation, gains, sba_order ); - - for ( j = 0; j < sba_num_chans; j++ ) - { - g1 = 1.f; - g2 = 0.f; - for ( k = 0; k < output_frame; k++ ) - { - buffer_tmp[j][k] += ( g2 * gains[j] + g1 * hIsmRendererData->prev_gains[i][j] ) * buffer_td[i][k]; - g2 += 1.f / ( output_frame - 1 ); - g1 = 1.0f - g2; - } - hIsmRendererData->prev_gains[i][j] = gains[j]; - } - } - - for ( j = 0; j < sba_num_chans; j++ ) - { - mvr2r( buffer_tmp[j], buffer_td[j], output_frame ); - } - - return; -} -#endif /*-------------------------------------------------------------------------* @@ -423,9 +359,7 @@ void ivas_ism2sba_sf( { int16_t i, j, k; float g1, *g2, *tc, *out, gain, prev_gain; -#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX float buffer_tmp[HOA3_CHANNELS][L_FRAME48k]; // VE2SB: TBV -#endif int16_t sba_num_chans; assert( ( sba_order <= 3 ) && "Only order up to 3 is supported!" ); @@ -435,11 +369,7 @@ void ivas_ism2sba_sf( sba_num_chans = ( sba_order + 1 ) * ( sba_order + 1 ); for ( j = 0; j < sba_num_chans; j++ ) { -#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX set_zero( buffer_tmp[j], n_samples_to_render ); -#else - set_zero( buffer_out[j], n_samples_to_render ); -#endif } for ( i = 0; i < num_objects; i++ ) @@ -448,11 +378,7 @@ void ivas_ism2sba_sf( { g2 = hIsmRendererData->interpolator + offset; tc = buffer_in[i] + offset; -#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX out = buffer_tmp[j]; -#else - out = buffer_out[j]; -#endif gain = hIsmRendererData->gains[i][j]; prev_gain = hIsmRendererData->prev_gains[i][j]; for ( k = 0; k < n_samples_to_render; k++ ) @@ -463,68 +389,14 @@ void ivas_ism2sba_sf( } } -#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX for ( j = 0; j < sba_num_chans; j++ ) { mvr2r( buffer_tmp[j], buffer_out[j], n_samples_to_render ); } -#endif return; } -#ifndef NONBE_UNIFIED_DECODING_PATHS_FIX -/*-------------------------------------------------------------------* - * ivas_sba_upmixer_renderer() - * - * SBA upmix & rendering - *-------------------------------------------------------------------*/ - -ivas_error ivas_sba_upmixer_renderer( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder struct */ - float *output[], /* i/o: transport/output audio channels */ - const int16_t output_frame /* i : output frame length */ -) -{ - int16_t nchan_internal; - int16_t sba_ch_idx; - ivas_error error; - - push_wmops( "ivas_sba_upmixer_renderer" ); - nchan_internal = ivas_sba_get_nchan_metadata( st_ivas->sba_analysis_order, st_ivas->hDecoderConfig->ivas_total_brate ); - - /* Upmixer + Renderer */ - ivas_spar_dec_upmixer( st_ivas, output, nchan_internal, output_frame ); - - if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_DEC ) - { - float *output_f[MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS]; - int16_t ch; - AUDIO_CONFIG output_config; - - output_config = ( st_ivas->ivas_format == SBA_ISM_FORMAT ? st_ivas->hOutSetup.output_config : st_ivas->hDecoderConfig->output_config ); - - sba_ch_idx = 0; - if ( st_ivas->ivas_format == SBA_ISM_FORMAT && st_ivas->ism_mode == ISM_SBA_MODE_DISC ) - { - sba_ch_idx = st_ivas->nchan_ism; - } - - for ( ch = 0; ch < ivas_get_nchan_buffers_dec( st_ivas, st_ivas->sba_analysis_order, st_ivas->hDecoderConfig->ivas_total_brate ) - sba_ch_idx; ch++ ) - { - output_f[ch] = output[ch]; - } - - if ( ( error = ivas_sba_linear_renderer( output_f, output_frame, st_ivas->hIntSetup.nchan_out_woLFE, st_ivas->nchan_ism, output_config, st_ivas->hOutSetup ) ) != IVAS_ERR_OK ) - { - return error; - } - } - pop_wmops(); - - return IVAS_ERR_OK; -} -#endif /*-------------------------------------------------------------------* * ivas_sba_linear_renderer() diff --git a/lib_dec/ivas_spar_decoder.c b/lib_dec/ivas_spar_decoder.c index 76e5c6f1f..a7e105b36 100644 --- a/lib_dec/ivas_spar_decoder.c +++ b/lib_dec/ivas_spar_decoder.c @@ -212,11 +212,7 @@ ivas_error ivas_spar_dec_open( } /* allocate transport channels*/ -#ifndef NONBE_UNIFIED_DECODING_PATHS - if ( st_ivas->hDecoderConfig->Opt_5ms && st_ivas->hTcBuffer == NULL || st_ivas->ivas_format == SBA_ISM_FORMAT ) -#else if ( st_ivas->hTcBuffer == NULL ) -#endif { int16_t nchan_to_allocate; int16_t nchan_tc; @@ -259,14 +255,6 @@ ivas_error ivas_spar_dec_open( granularity = (int16_t) ( st_ivas->hDecoderConfig->output_Fs / ( FRAMES_PER_SEC * MAX_PARAM_SPATIAL_SUBFRAMES ) ); } -#ifndef NONBE_UNIFIED_DECODING_PATHS - /* make sure we have a TC buffer with the correct granularity for rate switching in OSBA */ - if ( !st_ivas->hDecoderConfig->Opt_5ms ) - { - nchan_tc = 0; - nchan_to_allocate = 0; - } -#endif if ( ( error = ivas_jbm_dec_tc_buffer_open( st_ivas, buffer_mode, nchan_tc, nchan_to_allocate, nchan_to_allocate, granularity ) ) != IVAS_ERR_OK ) { return error; @@ -1062,10 +1050,8 @@ static void ivas_spar_calc_smooth_facs( float *cldfb_in_ts_re[CLDFB_NO_COL_MAX], float *cldfb_in_ts_im[CLDFB_NO_COL_MAX], int16_t nbands_spar, -#ifdef NONBE_FIX_906_SBA_LBR_SMOOTHING const int16_t nSlots, const int16_t isFirstSubframe, -#endif ivas_fb_bin_to_band_data_t *bin2band, float *smooth_fac, float smooth_buf[IVAS_MAX_NUM_BANDS][2 * SBA_DIRAC_NRG_SMOOTH_LONG + 1] ) @@ -1087,18 +1073,13 @@ static void ivas_spar_calc_smooth_facs( subframe_band_nrg[b] = 0.f; while ( bin < CLDFB_NO_CHANNELS_MAX && b == bin2band->p_cldfb_map_to_spar_band[bin] ) { -#ifdef NONBE_FIX_906_SBA_LBR_SMOOTHING for ( ts = 0; ts < nSlots; ts++ ) -#else - for ( ts = 0; ts < MAX_PARAM_SPATIAL_SUBFRAMES; ts++ ) -#endif { subframe_band_nrg[b] += cldfb_in_ts_re[ts][bin] * cldfb_in_ts_re[ts][bin] + cldfb_in_ts_im[ts][bin] * cldfb_in_ts_im[ts][bin]; } bin++; } subframe_band_nrg[b] = sqrtf( subframe_band_nrg[b] ); -#ifdef NONBE_FIX_906_SBA_LBR_SMOOTHING if ( isFirstSubframe && nSlots < MAX_PARAM_SPATIAL_SUBFRAMES ) { /* fill up to full 5ms subframe */ @@ -1106,11 +1087,8 @@ static void ivas_spar_calc_smooth_facs( } else { -#endif smooth_buf[b][0] = subframe_band_nrg[b]; -#ifdef NONBE_FIX_906_SBA_LBR_SMOOTHING } -#endif /* calculate short and long energy averages */ smooth_short_avg[b] = EPSILON; for ( i = 0; i < 2 * SBA_DIRAC_NRG_SMOOTH_SHORT; i++ ) @@ -1147,11 +1125,9 @@ static void ivas_spar_calc_smooth_facs( smooth_fac[b] = max( min_smooth_gains1[b], min( max_smooth_gains2[b], smooth_fac[b] ) ); } -#ifdef NONBE_FIX_906_SBA_LBR_SMOOTHING /* only update if we collected a full 5ms worth of energies for the buffer */ if ( isFirstSubframe || nSlots == MAX_PARAM_SPATIAL_SUBFRAMES ) { -#endif for ( b = 0; b < nbands_spar; b++ ) { for ( i = 2 * SBA_DIRAC_NRG_SMOOTH_LONG; i > 0; i-- ) @@ -1159,9 +1135,7 @@ static void ivas_spar_calc_smooth_facs( smooth_buf[b][i] = smooth_buf[b][i - 1]; } } -#ifdef NONBE_FIX_906_SBA_LBR_SMOOTHING } -#endif return; } @@ -1487,10 +1461,8 @@ void ivas_spar_dec_upmixer( output_f_local[n] += n_samples_sf; } -#ifdef NONBE_UNIFIED_DECODING_PATHS /* update combined orientation access index */ ivas_combined_orientation_update_index( st_ivas->hCombinedOrientationData, n_samples_sf ); -#endif } for ( n = 0; n < nchan_internal_total; n++ ) @@ -1711,11 +1683,7 @@ void ivas_spar_dec_upmixer_sf( if ( ( hDecoderConfig->ivas_total_brate < IVAS_24k4 ) && ( ( hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_HOA2 ) || ( hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_HOA3 ) ) ) { -#ifdef NONBE_FIX_906_SBA_LBR_SMOOTHING ivas_spar_calc_smooth_facs( cldfb_in_ts_re[0], cldfb_in_ts_im[0], num_spar_bands, hSpar->subframe_nbslots[hSpar->subframes_rendered], hSpar->subframes_rendered == 0, &hSpar->hFbMixer->pFb->fb_bin_to_band, hSpar->hMdDec->smooth_fac, hSpar->hMdDec->smooth_buf ); -#else - ivas_spar_calc_smooth_facs( cldfb_in_ts_re[0], cldfb_in_ts_im[0], num_spar_bands, &hSpar->hFbMixer->pFb->fb_bin_to_band, hSpar->hMdDec->smooth_fac, hSpar->hMdDec->smooth_buf ); -#endif } for ( ts = 0; ts < hSpar->subframe_nbslots[hSpar->subframes_rendered]; ts++ ) diff --git a/lib_dec/ivas_stat_dec.h b/lib_dec/ivas_stat_dec.h index c2c31152f..684d4b3e3 100644 --- a/lib_dec/ivas_stat_dec.h +++ b/lib_dec/ivas_stat_dec.h @@ -603,11 +603,9 @@ typedef struct ivas_spar_md_dec_state_t float smooth_buf[IVAS_MAX_NUM_BANDS][2 * SBA_DIRAC_NRG_SMOOTH_LONG + 1]; float smooth_fac[IVAS_MAX_NUM_BANDS]; float mixer_mat_prev2[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH][IVAS_MAX_NUM_BANDS]; -#ifdef NONBE_FIX_862_UBSAN_SPAR_DEC_BR_SW_PLC int16_t first_valid_frame; ivas_band_coeffs_t *band_coeffs_prev; int16_t base_band_coeffs_age[IVAS_MAX_NUM_BANDS]; -#endif } ivas_spar_md_dec_state_t; @@ -915,11 +913,7 @@ typedef struct ivas_masa_ism_data_structure typedef struct decoder_tc_buffer_structure { float *tc_buffer; /* the buffer itself */ -#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX float *tc[MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS]; /* pointers into the buffer to the beginning of each tc */ // VE2SB: TBV -#else - float *tc[MAX_TRANSPORT_CHANNELS + MAX_NUM_OBJECTS]; /* pointers into the buffer to the beginning of each tc */ -#endif TC_BUFFER_MODE tc_buffer_mode; /* mode of the buffer (no buffering, render buffering, out buffering) */ int16_t nchan_transport_jbm; /* number of TCs after TC decoding */ int16_t nchan_transport_internal; /* total number of TC buffer channels, can include e.g. TD decorr data */ @@ -1022,11 +1016,7 @@ typedef struct decoder_config_structure #ifdef SPLIT_REND_WITH_HEAD_ROT int16_t Opt_Limiter; #endif -#ifdef NONBE_UNIFIED_DECODING_PATHS IVAS_RENDER_FRAMESIZE render_framesize; -#else - int16_t Opt_5ms; -#endif int16_t Opt_delay_comp; /* flag indicating delay compensation active */ } DECODER_CONFIG, *DECODER_CONFIG_HANDLE; diff --git a/lib_dec/ivas_stereo_dft_dec.c b/lib_dec/ivas_stereo_dft_dec.c index f22978e7c..558ef6e31 100644 --- a/lib_dec/ivas_stereo_dft_dec.c +++ b/lib_dec/ivas_stereo_dft_dec.c @@ -1734,11 +1734,7 @@ void stereo_dft_dec( void stereo_dft_dec_res( CPE_DEC_HANDLE hCPE, /* i/o: decoder CPE handle */ -#ifdef FIX_887_ARRAY_SIZE_DFT_MDCT_STEREO float res_buf[STEREO_DFT_N_8k], /* i : residual buffer */ -#else - float res_buf[STEREO_DFT_BUF_MAX], /* i : residual buffer */ -#endif float *output /* o : output */ ) { @@ -1877,11 +1873,7 @@ void stereo_dft_dec_read_BS( STEREO_DFT_DEC_DATA_HANDLE hStereoDft, /* i/o: decoder stereo handle */ const int16_t bwidth, /* i : bandwidth */ const int16_t output_frame, /* i : output frame length */ -#ifdef FIX_887_ARRAY_SIZE_DFT_MDCT_STEREO float res_buf[STEREO_DFT_N_8k], /* o : residual buffer */ -#else - float res_buf[STEREO_DFT_BUF_MAX], /* o : residual buffer */ -#endif int16_t *nb_bits, /* o : number of bits read */ float *coh, /* i/o: Coherence */ const int16_t ivas_format /* i : ivas format */ diff --git a/lib_dec/ivas_stereo_mdct_stereo_dec.c b/lib_dec/ivas_stereo_mdct_stereo_dec.c index 95d7ba6d6..bd0fa38e0 100644 --- a/lib_dec/ivas_stereo_mdct_stereo_dec.c +++ b/lib_dec/ivas_stereo_mdct_stereo_dec.c @@ -209,13 +209,8 @@ void stereo_decoder_tcx( STEREO_MDCT_DEC_DATA *hStereoMdct, /* i/o: MDCT stereo decoder structure */ int16_t ms_mask[NB_DIV][MAX_SFB], /* i : bandwise MS mask */ float *spec_r_0[NB_DIV], /* i/o: spectrum right channel */ -#ifdef FIX_887_ARRAY_SIZE_DFT_MDCT_STEREO float *spec_l[], /* i/o: spectrum left channel [NB_DIV][N] */ float *spec_r[], /* i/o: spectrum right channel [NB_DIV][N] */ -#else - float *spec_l[NB_DIV], /* i/o: spectrum left channel */ - float *spec_r[NB_DIV], /* i/o: spectrum right channel */ -#endif const int16_t mdct_stereo_mode[], /* i : stereo mode (FB/band wise MS, dual mono */ const int16_t core_l, /* i : core for left channel (TCX20/TCX10) */ const int16_t core_r, /* i : core for right channel (TCX20/TCX10) */ diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index b1ac64db2..65babe812 100644 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -83,9 +83,7 @@ struct IVAS_DEC PCMDSP_APA_HANDLE hTimeScaler; bool needNewFrame; bool hasBeenFedFrame; -#ifdef NONBE_UNIFIED_DECODING_PATHS bool updateOrientation; -#endif uint16_t nSamplesAvailableNext; int16_t nSamplesRendered; int16_t nTransportChannelsOld; @@ -126,9 +124,7 @@ static PCM_RESOLUTION pcm_type_API_to_internal( const IVAS_DEC_PCM_TYPE pcmType static void *pcm_buffer_offset( void *buffer, const IVAS_DEC_PCM_TYPE pcmType, const int32_t offset ); static ivas_error set_pcm_buffer_to_zero( void *buffer, const IVAS_DEC_PCM_TYPE pcmType, const int16_t nZeroSamples ); #endif -#ifdef NONBE_UNIFIED_DECODING_PATHS static int16_t get_render_frame_size_ms( IVAS_RENDER_FRAMESIZE render_framesize ); -#endif /*---------------------------------------------------------------------* @@ -175,9 +171,7 @@ ivas_error IVAS_DEC_Open( hIvasDec->hasBeenFedFirstGoodFrame = false; hIvasDec->hasDecodedFirstGoodFrame = false; hIvasDec->isInitialized = false; -#ifdef NONBE_UNIFIED_DECODING_PATHS hIvasDec->updateOrientation = false; -#endif hIvasDec->mode = mode; @@ -274,9 +268,6 @@ static void init_decoder_config( hDecoderConfig->Opt_tsm = 0; #ifdef SPLIT_REND_WITH_HEAD_ROT hDecoderConfig->Opt_Limiter = 1; -#endif -#ifndef NONBE_UNIFIED_DECODING_PATHS - hDecoderConfig->Opt_5ms = 0; #endif hDecoderConfig->Opt_delay_comp = 0; hDecoderConfig->Opt_ExternalOrientation = 0; @@ -376,11 +367,7 @@ ivas_error IVAS_DEC_Configure( const uint32_t sampleRate, /* i : output sampling frequency */ const AUDIO_CONFIG outputConfig, /* i : output configuration */ const int16_t tsmEnabled, /* i : enable time scale modification */ -#ifndef NONBE_UNIFIED_DECODING_PATHS - const int16_t enable5ms, /* i : enable 5ms rendering path */ -#else const IVAS_RENDER_FRAMESIZE renderFramesize, /* i : rendering frame size */ -#endif const int16_t customLsOutputEnabled, /* i : enable custom loudspeaker setup handle */ const int16_t hrtfReaderEnabled, /* i : enable HRTF binary file input */ const int16_t enableHeadRotation, /* i : enable head rotation for binaural output */ @@ -439,9 +426,6 @@ ivas_error IVAS_DEC_Configure( } hDecoderConfig->Opt_tsm = tsmEnabled; -#ifndef NONBE_UNIFIED_DECODING_PATHS - hDecoderConfig->Opt_5ms = enable5ms; -#endif hDecoderConfig->Opt_LsCustom = customLsOutputEnabled; hDecoderConfig->Opt_Headrotation = enableHeadRotation; hDecoderConfig->orientation_tracking = orientation_tracking; @@ -454,7 +438,6 @@ ivas_error IVAS_DEC_Configure( hDecoderConfig->Opt_dpid_on = Opt_dpid_on; hDecoderConfig->Opt_aeid_on = acousticEnvironmentId != 65535 ? TRUE : FALSE; -#ifdef NONBE_UNIFIED_DECODING_PATHS if ( renderFramesize == IVAS_RENDER_FRAMESIZE_UNKNOWN ) { return IVAS_ERR_WRONG_PARAMS; @@ -467,7 +450,6 @@ ivas_error IVAS_DEC_Configure( { hDecoderConfig->render_framesize = renderFramesize; } -#endif #ifdef SPLIT_REND_WITH_HEAD_ROT if ( hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) @@ -523,11 +505,7 @@ ivas_error IVAS_DEC_EnableSplitRendering( hDecoderConfig = hIvasDec->st_ivas->hDecoderConfig; hDecoderConfig->Opt_Headrotation = 1; -#ifndef NONBE_UNIFIED_DECODING_PATHS - hDecoderConfig->Opt_5ms = false; -#else hDecoderConfig->render_framesize = IVAS_RENDER_FRAMESIZE_20MS; -#endif hDecoderConfig->Opt_Limiter = 0; @@ -535,50 +513,6 @@ ivas_error IVAS_DEC_EnableSplitRendering( } #endif -#ifndef NONBE_UNIFIED_DECODING_PATHS -/*---------------------------------------------------------------------* - * IVAS_DEC_Set5msFlag( ) - * - * Get the 5ms flag - *---------------------------------------------------------------------*/ - -ivas_error IVAS_DEC_Set5msFlag( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - const int16_t enable5ms /* i : 5ms flag */ -) -{ - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || hIvasDec->st_ivas->hDecoderConfig == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } - - hIvasDec->st_ivas->hDecoderConfig->Opt_5ms = enable5ms; - - return IVAS_ERR_OK; -} - - -/*---------------------------------------------------------------------* - * IVAS_DEC_Get5msFlag( ) - * - * Get the 5ms flag - *---------------------------------------------------------------------*/ - -ivas_error IVAS_DEC_Get5msFlag( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - int16_t *enable5ms /* o : 5ms flag */ -) -{ - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || enable5ms == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } - - *enable5ms = (int16_t) hIvasDec->st_ivas->hDecoderConfig->Opt_5ms; - - return IVAS_ERR_OK; -} -#else /*---------------------------------------------------------------------* * get_render_framesize_ms( ) * @@ -717,7 +651,6 @@ ivas_error IVAS_DEC_GetNumOrientationSubframes( return IVAS_ERR_OK; } -#endif /*---------------------------------------------------------------------* @@ -749,9 +682,6 @@ ivas_error IVAS_DEC_EnableVoIP( hIvasDec->Opt_VOIP = 1; hDecoderConfig->Opt_tsm = 1; -#ifndef NONBE_UNIFIED_DECODING_PATHS - hDecoderConfig->Opt_5ms = 1; -#endif if ( hDecoderConfig->output_config != IVAS_AUDIO_CONFIG_EXTERNAL ) { hDecoderConfig->nchan_out = audioCfg2channels( hDecoderConfig->output_config ); @@ -900,68 +830,6 @@ ivas_error IVAS_DEC_FeedFrame_Serial( * Main function to decode to PCM data *---------------------------------------------------------------------*/ -#ifndef NONBE_UNIFIED_DECODING_PATHS -static ivas_error _GetSamples( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ -#ifdef SPLIT_REND_WITH_HEAD_ROT - const PCM_RESOLUTION pcm_resolution, - void *pcmBuf, /* i/o: buffer for decoded PCM output. The memory must already be allocated and be able to hold the expected number of output samples, based on frame size and number of output channels */ -#else - int16_t *pcmBuf, /* i/o: buffer for decoded PCM output. The memory must already be allocated and be able to hold the expected number of output samples, based on frame size and number of output channels */ -#endif - int16_t *nOutSamples /* o : number of samples per channel written to output buffer */ -) -{ - Decoder_Struct *st_ivas; - ivas_error error; - - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } - - st_ivas = hIvasDec->st_ivas; - - *nOutSamples = (int16_t) ( st_ivas->hDecoderConfig->output_Fs / FRAMES_PER_SEC ); - - if ( hIvasDec->mode == IVAS_DEC_MODE_EVS ) - { -#if defined DEBUGGING && defined SPLIT_REND_WITH_HEAD_ROT - assert( pcm_resolution == PCM_INT16 ); -#endif -#ifdef SPLIT_REND_WITH_HEAD_ROT - if ( ( error = evs_dec_main( st_ivas, *nOutSamples, NULL, (int16_t *) pcmBuf ) ) != IVAS_ERR_OK ) -#else - if ( ( error = evs_dec_main( st_ivas, *nOutSamples, NULL, pcmBuf ) ) != IVAS_ERR_OK ) -#endif - { - return error; - } - } - else if ( hIvasDec->mode == IVAS_DEC_MODE_IVAS ) - { - /* run the main IVAS decoding routine */ - -#ifdef SPLIT_REND_WITH_HEAD_ROT - if ( ( error = ivas_dec( st_ivas, pcm_resolution, pcmBuf ) ) != IVAS_ERR_OK ) -#else - if ( ( error = ivas_dec( st_ivas, pcmBuf ) ) != IVAS_ERR_OK ) -#endif - { - return error; - } - - hIvasDec->isInitialized = true; /* Initialization done in ivas_dec() */ - } - - if ( hIvasDec->hasBeenFedFirstGoodFrame ) - { - hIvasDec->hasDecodedFirstGoodFrame = true; - } - - return IVAS_ERR_OK; -} -#endif ivas_error IVAS_DEC_GetSamples( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ @@ -977,11 +845,7 @@ ivas_error IVAS_DEC_GetSamples( ) { ivas_error error; -#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX int16_t nOutSamplesElse, nSamplesToRender; -#else - int16_t nOutSamplesElse, result, nSamplesToRender; -#endif uint16_t nSamplesRendered, nSamplesRendered_loop, l_ts, nTimeScalerOutSamples; uint8_t nTransportChannels, nOutChannels; @@ -996,7 +860,6 @@ ivas_error IVAS_DEC_GetSamples( return IVAS_ERR_UNEXPECTED_NULL_POINTER; } -#ifdef NONBE_UNIFIED_DECODING_PATHS if ( hIvasDec->updateOrientation ) { /*----------------------------------------------------------------* @@ -1021,7 +884,6 @@ ivas_error IVAS_DEC_GetSamples( hIvasDec->updateOrientation = false; } -#endif if ( !hIvasDec->hasBeenFedFrame && hIvasDec->nSamplesAvailableNext == 0 ) { @@ -1066,29 +928,6 @@ ivas_error IVAS_DEC_GetSamples( /* :TODO: change nSamplesAsked also if we are in 5ms 0dof split rendering... */ #endif } -#ifndef NONBE_UNIFIED_DECODING_PATHS - if ( !hIvasDec->st_ivas->hDecoderConfig->Opt_5ms ) - { -#ifdef SPLIT_REND_WITH_HEAD_ROT - if ( ( error = _GetSamples( hIvasDec, pcm_type_API_to_internal( pcmType ), pcmBuf, nOutSamples ) ) != IVAS_ERR_OK ) -#else - if ( ( error = _GetSamples( hIvasDec, pcmBuf, nOutSamples ) ) != IVAS_ERR_OK ) -#endif - { - return error; - } -#ifdef DEBUGGING - assert( *nOutSamples == nSamplesAsked ); -#endif - hIvasDec->nSamplesAvailableNext = 0; - hIvasDec->nSamplesRendered = *nOutSamples; - nSamplesRendered = *nOutSamples; - hIvasDec->needNewFrame = true; - hIvasDec->hasBeenFedFrame = false; - *needNewFrame = true; - } - else -#endif { /* check if we need to run the setup function, tc decoding and feeding the renderer */ if ( !hIvasDec->isInitialized || hIvasDec->hasBeenFedFrame ) @@ -1096,11 +935,7 @@ ivas_error IVAS_DEC_GetSamples( int16_t nResidualSamples, nSamplesTcsScaled; nSamplesRendered += nSamplesRendered_loop; -#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX if ( hIvasDec->st_ivas->hDecoderConfig->Opt_tsm && nTransportChannels != hIvasDec->nTransportChannelsOld ) -#else - if ( nTransportChannels != hIvasDec->nTransportChannelsOld ) -#endif { if ( ( error = IVAS_DEC_VoIP_reconfigure( hIvasDec, nTransportChannels, l_ts ) ) != IVAS_ERR_OK ) { @@ -1122,7 +957,6 @@ ivas_error IVAS_DEC_GetSamples( return IVAS_ERR_UNKNOWN; } -#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX if ( apa_exec( hIvasDec->hTimeScaler, hIvasDec->apaExecBuffer, hIvasDec->nSamplesFrame * nTransportChannels, (uint16_t) hIvasDec->tsm_max_scaling, hIvasDec->apaExecBuffer, &nTimeScalerOutSamples ) != 0 ) { return IVAS_ERR_UNKNOWN; @@ -1130,26 +964,11 @@ ivas_error IVAS_DEC_GetSamples( assert( nTimeScalerOutSamples <= APA_BUF ); nSamplesTcsScaled = nTimeScalerOutSamples / nTransportChannels; -#else - result = apa_exec( hIvasDec->hTimeScaler, hIvasDec->apaExecBuffer, hIvasDec->nSamplesFrame * nTransportChannels, (uint16_t) hIvasDec->tsm_max_scaling, hIvasDec->apaExecBuffer, &nTimeScalerOutSamples ); - if ( result != 0 ) - { - return IVAS_ERR_UNKNOWN; - } - assert( nTimeScalerOutSamples <= APA_BUF ); -#endif } else { -#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX nSamplesTcsScaled = hIvasDec->nSamplesFrame; -#else - nTimeScalerOutSamples = hIvasDec->nSamplesFrame * nTransportChannels; -#endif } -#ifndef NONBE_UNIFIED_DECODING_PATHS_FIX - nSamplesTcsScaled = nTimeScalerOutSamples / nTransportChannels; -#endif /* Feed decoded transport channels samples to the renderer */ if ( ( error = IVAS_DEC_RendererFeedTcSamples( hIvasDec, nSamplesTcsScaled, &nResidualSamples, hIvasDec->apaExecBuffer ) ) != IVAS_ERR_OK ) @@ -1249,15 +1068,9 @@ ivas_error IVAS_DEC_GetSplitBinauralBitstream( numPoses = hSplitBinRend->splitrend.multiBinPoseData.num_poses; -#ifdef NONBE_UNIFIED_DECODING_PATHS if ( st_ivas->hDecoderConfig->render_framesize == IVAS_RENDER_FRAMESIZE_5MS && hIvasDec->st_ivas->hRenderConfig->split_rend_config.codec == IVAS_SPLIT_REND_CODEC_LC3PLUS && ( hIvasDec->st_ivas->hRenderConfig->split_rend_config.poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE || hIvasDec->st_ivas->hRenderConfig->split_rend_config.dof == 0 ) ) -#else - if ( st_ivas->hDecoderConfig->Opt_5ms && hIvasDec->st_ivas->hRenderConfig->split_rend_config.codec == IVAS_SPLIT_REND_CODEC_LC3PLUS && - ( hIvasDec->st_ivas->hRenderConfig->split_rend_config.poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE || - hIvasDec->st_ivas->hRenderConfig->split_rend_config.dof == 0 ) ) -#endif { numSamplesPerChannelToSplitEncode = (int16_t) ( output_Fs / FRAMES_PER_SEC / MAX_PARAM_SPATIAL_SUBFRAMES ); numSamplesPerChannelCacheSize = numSamplesPerChannelToDecode - numSamplesPerChannelToSplitEncode; @@ -1356,11 +1169,7 @@ ivas_error IVAS_DEC_GetSplitBinauralBitstream( /* convert to int16 with limiting for BINAURAL_SPLIT_PCM */ if ( pcm_out_flag ) { -#ifdef NONBE_UNIFIED_DECODING_PATHS if ( st_ivas->hDecoderConfig->render_framesize == IVAS_RENDER_FRAMESIZE_5MS ) -#else - if ( st_ivas->hDecoderConfig->Opt_5ms ) -#endif { #ifndef DISABLE_LIMITER ivas_limiter_dec( st_ivas->hLimiter, pOutput, st_ivas->hDecoderConfig->nchan_out, numSamplesPerChannelToSplitEncode, st_ivas->BER_detect ); @@ -1890,9 +1699,7 @@ ivas_error IVAS_DEC_FeedHeadTrackData( #ifdef SPLIT_REND_WITH_HEAD_ROT hHeadTrackData->sr_pose_pred_axis = rot_axis; #endif -#ifdef NONBE_UNIFIED_DECODING_PATHS hIvasDec->updateOrientation = true; -#endif return IVAS_ERR_OK; } @@ -1923,9 +1730,7 @@ ivas_error IVAS_DEC_FeedRefRotData( pOtr->refRot.z = rotation.z; pOtr->refRot.y = rotation.y; -#ifdef NONBE_UNIFIED_DECODING_PATHS hIvasDec->updateOrientation = true; -#endif return IVAS_ERR_OK; } @@ -1954,9 +1759,7 @@ ivas_error IVAS_DEC_FeedRefVectorData( pOtr = hIvasDec->st_ivas->hHeadTrackData->OrientationTracker; -#ifdef NONBE_UNIFIED_DECODING_PATHS hIvasDec->updateOrientation = true; -#endif return ivas_orient_trk_SetReferenceVector( pOtr, listenerPos, refPos ); } @@ -2000,9 +1803,7 @@ ivas_error IVAS_DEC_FeedExternalOrientationData( hExternalOrientationData->enableRotationInterpolation[subframe_idx] = enableRotationInterpolation; hExternalOrientationData->numFramesToTargetOrientation[subframe_idx] = numFramesToTargetOrientation; -#ifdef NONBE_UNIFIED_DECODING_PATHS hIvasDec->updateOrientation = true; -#endif return IVAS_ERR_OK; } @@ -3087,9 +2888,7 @@ static ivas_error printConfigInfo_dec( { ivas_error error; char config_str[50]; -#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX AUDIO_CONFIG output_config; -#endif /*-----------------------------------------------------------------* * Print info on screen @@ -3189,26 +2988,18 @@ static ivas_error printConfigInfo_dec( } } -#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX output_config = st_ivas->hDecoderConfig->output_config; get_channel_config( output_config, &config_str[0] ); -#else - get_channel_config( st_ivas->hDecoderConfig->output_config, &config_str[0] ); -#endif fprintf( stdout, "Output configuration: %s\n", config_str ); -#ifdef NONBE_UNIFIED_DECODING_PATHS -#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX #ifdef SPLIT_REND_WITH_HEAD_ROT if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) #else if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) -#endif #endif { fprintf( stdout, "Render framesize: %dms\n", get_render_frame_size_ms( st_ivas->hDecoderConfig->render_framesize ) ); } -#endif if ( st_ivas->hDecoderConfig->Opt_HRTF_binary ) { fprintf( stdout, "HRIR/BRIR file: ON\n" ); @@ -3274,16 +3065,6 @@ static ivas_error printConfigInfo_dec( { fprintf( stdout, "TSM mode: ON\n" ); } -#ifndef NONBE_UNIFIED_DECODING_PATHS - /*-----------------------------------------------------------------* - * Print 5ms API mode info - *-----------------------------------------------------------------*/ - - if ( st_ivas->hDecoderConfig->Opt_5ms ) - { - fprintf( stdout, "API 5ms mode: ON\n" ); - } -#endif return IVAS_ERR_OK; } @@ -3388,9 +3169,6 @@ static ivas_error evs_dec_main( int16_t *pcmBuf ) { DEC_CORE_HANDLE *hCoreCoder; -#ifndef NONBE_UNIFIED_DECODING_PATHS_FIX - float output[MAX_OUTPUT_CHANNELS_IN_DIEGETIC_PAN][L_FRAME48k]; -#endif float mixer_left, mixer_rigth; float *p_output[MAX_OUTPUT_CHANNELS_IN_DIEGETIC_PAN]; int16_t ch; @@ -3403,11 +3181,7 @@ static ivas_error evs_dec_main( for ( ch = 0; ch < MAX_OUTPUT_CHANNELS_IN_DIEGETIC_PAN; ch++ ) { -#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX p_output[ch] = st_ivas->p_output_f[ch]; -#else - p_output[ch] = output[ch]; -#endif } /* run the main EVS decoding routine */ @@ -3415,22 +3189,14 @@ static ivas_error evs_dec_main( { if ( hCoreCoder[0]->Opt_AMR_WB ) { -#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX if ( ( error = amr_wb_dec( hCoreCoder[0], st_ivas->mem_hp20_out[0], p_output[0] ) ) != IVAS_ERR_OK ) -#else - if ( ( error = amr_wb_dec( hCoreCoder[0], st_ivas->mem_hp20_out[0], output[0] ) ) != IVAS_ERR_OK ) -#endif { return error; } } else { -#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX if ( ( error = evs_dec( hCoreCoder[0], st_ivas->mem_hp20_out[0], p_output[0], FRAMEMODE_NORMAL ) ) != IVAS_ERR_OK ) -#else - if ( ( error = evs_dec( hCoreCoder[0], st_ivas->mem_hp20_out[0], output[0], FRAMEMODE_NORMAL ) ) != IVAS_ERR_OK ) -#endif { return error; } @@ -3440,33 +3206,21 @@ static ivas_error evs_dec_main( { if ( hCoreCoder[0]->bfi == 0 ) { -#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX if ( ( error = evs_dec( hCoreCoder[0], st_ivas->mem_hp20_out[0], p_output[0], FRAMEMODE_NORMAL ) ) != IVAS_ERR_OK ) -#else - if ( ( error = evs_dec( hCoreCoder[0], st_ivas->mem_hp20_out[0], output[0], FRAMEMODE_NORMAL ) ) != IVAS_ERR_OK ) -#endif { return error; } } else if ( hCoreCoder[0]->bfi == 2 ) { -#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX if ( ( error = evs_dec( hCoreCoder[0], st_ivas->mem_hp20_out[0], p_output[0], FRAMEMODE_FUTURE ) ) != IVAS_ERR_OK ) -#else - if ( ( error = evs_dec( hCoreCoder[0], st_ivas->mem_hp20_out[0], output[0], FRAMEMODE_FUTURE ) ) != IVAS_ERR_OK ) -#endif { return error; } } else { -#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX if ( ( error = evs_dec( hCoreCoder[0], st_ivas->mem_hp20_out[0], p_output[0], FRAMEMODE_MISSING ) ) != IVAS_ERR_OK ) -#else - if ( ( error = evs_dec( hCoreCoder[0], st_ivas->mem_hp20_out[0], output[0], FRAMEMODE_MISSING ) ) != IVAS_ERR_OK ) -#endif { return error; } @@ -3479,20 +3233,11 @@ static ivas_error evs_dec_main( { mixer_left = ( st_ivas->hDecoderConfig->non_diegetic_pan_gain + 1.f ) * 0.5f; mixer_rigth = 1.f - mixer_left; -#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX v_multc( p_output[0], mixer_rigth, p_output[1], nOutSamples ); v_multc( p_output[0], mixer_left, p_output[0], nOutSamples ); -#else - v_multc( output[0], mixer_rigth, output[1], nOutSamples ); - v_multc( output[0], mixer_left, output[0], nOutSamples ); -#endif } -#ifndef NONBE_UNIFIED_DECODING_PATHS - if ( !st_ivas->hDecoderConfig->Opt_tsm && st_ivas->hDecoderConfig->Opt_5ms ) -#else if ( !st_ivas->hDecoderConfig->Opt_tsm ) -#endif { ivas_jbm_dec_copy_tc_no_tsm( st_ivas, p_output, nOutSamples ); } diff --git a/lib_dec/lib_dec.h b/lib_dec/lib_dec.h index bccc190f9..5ed4da72d 100644 --- a/lib_dec/lib_dec.h +++ b/lib_dec/lib_dec.h @@ -125,11 +125,7 @@ ivas_error IVAS_DEC_Configure( const uint32_t sampleRate, /* i : output sampling frequency */ const IVAS_AUDIO_CONFIG outputConfig, /* i : audio configuration */ const int16_t tsmEnabled, /* i : enable TSM */ -#ifndef NONBE_UNIFIED_DECODING_PATHS - const int16_t enable5ms, /* i : enable 5ms rendering path */ -#else const IVAS_RENDER_FRAMESIZE renderFramesize, /* i : rendering frame size */ -#endif const int16_t customLsOutputEnabled, /* i : enable custom loudspeaker setup handle */ const int16_t hrtfReaderEnabled, /* i : enable HRTF binary file input */ const int16_t enableHeadRotation, /* i : enable head rotation for binaural output */ @@ -316,17 +312,6 @@ ivas_error IVAS_DEC_EnableSplitRendering( ); #endif -#ifndef NONBE_UNIFIED_DECODING_PATHS -ivas_error IVAS_DEC_Set5msFlag( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - const int16_t enable5ms /* i : 5ms flag */ -); - -ivas_error IVAS_DEC_Get5msFlag( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - int16_t *enable5ms /* o : 5ms flag */ -); -#else ivas_error IVAS_DEC_SetRenderFramesize( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ const IVAS_RENDER_FRAMESIZE render_framesize /* i : render framesize */ @@ -356,7 +341,6 @@ ivas_error IVAS_DEC_GetRenderFramesizeMs( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ uint32_t *render_framesize /* o : render framesize in samples */ ); -#endif #ifdef DEBUGGING bool IVAS_DEC_GetBerDetectFlag( diff --git a/lib_enc/cod_tcx.c b/lib_enc/cod_tcx.c index 9e4b601a5..e2efb2c26 100644 --- a/lib_enc/cod_tcx.c +++ b/lib_enc/cod_tcx.c @@ -110,19 +110,10 @@ void HBAutocorrelation( void TNSAnalysisStereo( Encoder_State **sts, /* i : encoder state handle */ -#ifdef FIX_887_ARRAY_SIZE_DFT_MDCT_STEREO float *mdst_spectrum[CPE_CHANNELS][NB_DIV], /* o : MDST spectrum */ -#else - float *mdst_spectrum[MCT_MAX_CHANNELS][NB_DIV], /* o : MDST spectrum */ -#endif const int16_t bWhitenedDomain, /* i : whitened domain flag */ -#ifdef FIX_887_ARRAY_SIZE_DFT_MDCT_STEREO int16_t tnsSize[CPE_CHANNELS][NB_DIV], /* i : number of tns parameters put into prm */ int16_t tnsBits[CPE_CHANNELS][NB_DIV], /* i : number of tns bits in the frame */ -#else - int16_t tnsSize[MCT_MAX_CHANNELS][NB_DIV], /* i : number of tns parameters put into prm */ - int16_t tnsBits[MCT_MAX_CHANNELS][NB_DIV], /* i : number of tns bits in the frame */ -#endif int16_t param_core[][NB_DIV * NPRM_DIV], /* o : TNS parameters */ const int16_t mct_on /* i : flag mct block (1) or stereo (0) */ ) diff --git a/lib_enc/ivas_mc_paramupmix_enc.c b/lib_enc/ivas_mc_paramupmix_enc.c index 2d1e6d37f..bcb519f07 100644 --- a/lib_enc/ivas_mc_paramupmix_enc.c +++ b/lib_enc/ivas_mc_paramupmix_enc.c @@ -56,35 +56,18 @@ static void ivas_mc_paramupmix_dmx( MC_PARAMUPMIX_ENC_HANDLE hMCParamUpmix, float *data_f[], const int16_t input_frame ); static void ivas_mc_paramupmix_param_est_enc( MC_PARAMUPMIX_ENC_HANDLE hMCParamUpmix, float *input_frame_t[], const int16_t input_frame, float alphas[MC_PARAMUPMIX_COMBINATIONS][IVAS_MAX_NUM_BANDS], float betas[MC_PARAMUPMIX_COMBINATIONS][IVAS_MAX_NUM_BANDS] ); -#ifdef FIX_891_PARAMUPMIX_CLEANUP static void get_huff_table( const PAR_TYPE par_type, HUFF_TAB *df0, HUFF_TAB *df ); -#else -static void get_huff_table( const PAR_TYPE par_type, const QUANT_TYPE quant_type, HUFF_TAB *df0, HUFF_TAB *df, HUFF_TAB *dt ); -#endif static void write_huff_bits( const int32_t value, const uint16_t length, uint16_t bit_buffer[MC_PARAMUPMIX_MAX_BITS], int16_t *bit_pos ); -#ifdef FIX_891_PARAMUPMIX_CLEANUP static void huffman_encode( const int32_t *vqPrev, const int32_t *vq, const PAR_TYPE parType, const int16_t nq, uint16_t bit_buffer[MC_PARAMUPMIX_MAX_BITS], int16_t *bit_pos ); -#else -static void huffman_encode( const int16_t bdfOnly, const int16_t bdtAllowed, const int16_t nv, const int16_t ivStart, const int32_t *vqPrev, const int32_t *vq, const PAR_TYPE parType, const QUANT_TYPE quant_type, const int16_t nq, uint16_t bit_buffer[MC_PARAMUPMIX_MAX_BITS], int16_t *bit_pos ); -#endif static void put_ec_data( MC_PARAMUPMIX_ENC_HANDLE hMCParamUpmix, const int16_t ch, const float pars[IVAS_MAX_NUM_BANDS], const float alphas[IVAS_MAX_NUM_BANDS], const PAR_TYPE parType, uint16_t bit_buffer[MC_PARAMUPMIX_MAX_BITS], int16_t *bit_pos ); -#ifdef FIX_891_PARAMUPMIX_CLEANUP static void quantize_alpha( const float *alpha, int16_t *pnq, int32_t aq[IVAS_MAX_NUM_BANDS], float *adeq ); static void quantize_pars( const float *v, const int16_t nq, const float *data, int32_t vq[IVAS_MAX_NUM_BANDS], float *vdeq ); -#else -static void quantize_alpha( const int16_t nv, const float *alpha, const QUANT_TYPE quant_type, int16_t *pnq, int32_t aq[IVAS_MAX_NUM_BANDS], float *adeq ); - -static void quantize_pars( const int16_t nv, const float *v, const int16_t nq, const float *data, int32_t vq[IVAS_MAX_NUM_BANDS], float *vdeq ); - -static void quantize_pars( const int16_t nv, const float *v, const int16_t nq, const float *data, int32_t vq[IVAS_MAX_NUM_BANDS], float *vdeq ); - -#endif /*------------------------------------------------------------------------- * ivas_mc_paramupmix_enc() @@ -374,19 +357,11 @@ void ivas_mc_paramupmix_enc_close( static void get_huff_table( const PAR_TYPE par_type, -#ifndef FIX_891_PARAMUPMIX_CLEANUP - const QUANT_TYPE quant_type, - HUFF_TAB *df0, - HUFF_TAB *df, - HUFF_TAB *dt ) -#else HUFF_TAB *df0, HUFF_TAB *df ) -#endif { switch ( par_type ) { -#ifdef FIX_891_PARAMUPMIX_CLEANUP case ALPHA: df0->value = huff_alpha_table.df0.value; df0->length = huff_alpha_table.df0.length; @@ -399,24 +374,6 @@ static void get_huff_table( df->value = huff_beta_table.df.value; df->length = huff_beta_table.df.length; break; -#else - case ALPHA: - df0->value = huff_alpha_table[quant_type].df0.value; - df0->length = huff_alpha_table[quant_type].df0.length; - df->value = huff_alpha_table[quant_type].df.value; - df->length = huff_alpha_table[quant_type].df.length; - dt->value = huff_alpha_table[quant_type].dt.value; - dt->length = huff_alpha_table[quant_type].dt.length; - break; - case BETA: - df0->value = huff_beta_table[quant_type].df0.value; - df0->length = huff_beta_table[quant_type].df0.length; - df->value = huff_beta_table[quant_type].df.value; - df->length = huff_beta_table[quant_type].df.length; - dt->value = huff_beta_table[quant_type].dt.value; - dt->length = huff_beta_table[quant_type].dt.length; - break; -#endif } return; @@ -441,88 +398,37 @@ static void write_huff_bits( static void huffman_encode( -#ifndef FIX_891_PARAMUPMIX_CLEANUP - const int16_t bdfOnly, - const int16_t bdtAllowed, - const int16_t nv, - const int16_t ivStart, -#endif const int32_t *vqPrev, const int32_t *vq, const PAR_TYPE parType, -#ifndef FIX_891_PARAMUPMIX_CLEANUP - const QUANT_TYPE quant_type, -#endif const int16_t nq, uint16_t bit_buffer[MC_PARAMUPMIX_MAX_BITS], int16_t *bit_pos ) { -#ifdef FIX_891_PARAMUPMIX_CLEANUP int16_t iv; -#else - int16_t iv, ndf, ndt; -#endif int32_t icode; int16_t offset; -#ifdef FIX_891_PARAMUPMIX_CLEANUP HUFF_TAB df0, df; -#else - HUFF_TAB df0, df, dt; -#endif -#ifdef FIX_891_PARAMUPMIX_CLEANUP get_huff_table( parType, &df0, &df ); -#else - get_huff_table( parType, quant_type, &df0, &df, &dt ); -#endif offset = nq - 1; /* range [-(nquant - 1), nquant - 1] */ -#ifndef FIX_891_PARAMUPMIX_CLEANUP - /* Get code length for time and freq diff coding */ - ndf = 0; - ndt = 0; -#endif -#ifdef FIX_891_PARAMUPMIX_CLEANUP for ( iv = 0; iv < IVAS_MAX_NUM_BANDS; iv++ ) -#else - for ( iv = ivStart; iv < nv; iv++ ) -#endif { -#ifdef FIX_891_PARAMUPMIX_CLEANUP if ( iv == 0 ) -#else - if ( iv == ivStart ) -#endif { icode = vq[iv]; -#ifndef FIX_891_PARAMUPMIX_CLEANUP - ndf += df0.length[icode]; -#endif } else { icode = vq[iv] - vq[iv - 1] + offset; -#ifndef FIX_891_PARAMUPMIX_CLEANUP - ndf += df.length[icode]; -#endif } icode = vq[iv] - vqPrev[iv] + offset; -#ifndef FIX_891_PARAMUPMIX_CLEANUP - ndt += dt.length[icode]; -#endif - } - -#ifndef FIX_891_PARAMUPMIX_CLEANUP - if ( !bdtAllowed ) /* Time diff not allowed due to conformance or other reason even if bdfOnly = 0 */ - { - ndt = ndf + 1; } -#endif /* Write the bitstream */ -#ifdef FIX_891_PARAMUPMIX_CLEANUP bit_buffer[( *bit_pos )++] = (uint16_t) 0 & 1; for ( iv = 0; iv < IVAS_MAX_NUM_BANDS; iv++ ) { @@ -537,49 +443,12 @@ static void huffman_encode( write_huff_bits( df.value[icode], df.length[icode], bit_buffer, bit_pos ); } } -#else - if ( bdfOnly || ndf < ndt ) - { - bit_buffer[( *bit_pos )++] = (uint16_t) 0 & 1; - for ( iv = ivStart; iv < nv; iv++ ) - { - if ( iv == ivStart ) - { - icode = vq[iv]; - write_huff_bits( df0.value[icode], df0.length[icode], bit_buffer, bit_pos ); - } - else - { - icode = vq[iv] - vq[iv - 1] + offset; - write_huff_bits( df.value[icode], df.length[icode], bit_buffer, bit_pos ); - } - } - } - else - { - bit_buffer[( *bit_pos )++] = (uint16_t) 1 & 1; - for ( iv = ivStart; iv < nv; iv++ ) - { - icode = vq[iv] - vqPrev[iv] + offset; -#ifdef DEBUGGING - if ( icode < 0 || icode >= 2 * nq - 1 ) - { - assert( 0 ); - } -#endif - write_huff_bits( dt.value[icode], dt.length[icode], bit_buffer, bit_pos ); - } - } -#endif return; } static void quantize_pars( -#ifndef FIX_891_PARAMUPMIX_CLEANUP - const int16_t nv, -#endif const float *v, const int16_t nq, const float *data, @@ -588,11 +457,7 @@ static void quantize_pars( { int16_t iv, iq, iq0, iq1; -#ifdef FIX_891_PARAMUPMIX_CLEANUP for ( iv = 0; iv < IVAS_MAX_NUM_BANDS; iv++ ) -#else - for ( iv = 0; iv < nv; iv++ ) -#endif { iq0 = 0; iq1 = nq - 1; @@ -627,13 +492,7 @@ static void quantize_pars( static void quantize_alpha( -#ifndef FIX_891_PARAMUPMIX_CLEANUP - const int16_t nv, -#endif const float *alpha, -#ifndef FIX_891_PARAMUPMIX_CLEANUP - const QUANT_TYPE quant_type, -#endif int16_t *pnq, int32_t aq[IVAS_MAX_NUM_BANDS], float *adeq ) @@ -641,17 +500,10 @@ static void quantize_alpha( int16_t nq; const float *data; -#ifdef FIX_891_PARAMUPMIX_CLEANUP nq = ivas_mc_paramupmix_alpha_quant_table.nquant; data = ivas_mc_paramupmix_alpha_quant_table.data; quantize_pars( alpha, nq, data, aq, adeq ); -#else - nq = ivas_mc_paramupmix_alpha_quant_table[quant_type].nquant; - data = ivas_mc_paramupmix_alpha_quant_table[quant_type].data; - - quantize_pars( nv, alpha, nq, data, aq, adeq ); -#endif *pnq = nq; return; @@ -659,37 +511,19 @@ static void quantize_alpha( static void quantize_beta( -#ifndef FIX_891_PARAMUPMIX_CLEANUP - const int16_t nv, -#endif const float *beta, const int32_t aq[IVAS_MAX_NUM_BANDS], -#ifndef FIX_891_PARAMUPMIX_CLEANUP - const QUANT_TYPE quant_type, -#endif int16_t *pnq, int32_t bq[IVAS_MAX_NUM_BANDS], float *bdeq ) { int16_t iv, iq, iq0, iq1; -#ifdef FIX_891_PARAMUPMIX_CLEANUP const ACPL_QUANT_TABLE *tables = ivas_mc_paramupmix_beta_quant_table; -#else - const ACPL_QUANT_TABLE *tables = ivas_mc_paramupmix_beta_quant_table[quant_type]; -#endif ACPL_QUANT_TABLE quant_table; -#ifdef FIX_891_PARAMUPMIX_CLEANUP for ( iv = 0; iv < IVAS_MAX_NUM_BANDS; iv++ ) -#else - for ( iv = 0; iv < nv; iv++ ) -#endif { -#ifdef FIX_891_PARAMUPMIX_CLEANUP quant_table = tables[ivas_param_upmx_mx_qmap[aq[iv]]]; -#else - quant_table = tables[ivas_param_upmx_mx_qmap[quant_type][aq[iv]]]; -#endif iq0 = 0; iq1 = quant_table.nquant - 1; @@ -719,11 +553,7 @@ static void quantize_beta( } } -#ifdef FIX_891_PARAMUPMIX_CLEANUP *pnq = ivas_mc_paramupmix_beta_quant_table[0].nquant; -#else - *pnq = ivas_mc_paramupmix_beta_quant_table[quant_type][0].nquant; -#endif return; } @@ -738,14 +568,7 @@ static void put_ec_data( uint16_t bit_buffer[MC_PARAMUPMIX_MAX_BITS], int16_t *bit_pos ) { -#ifndef FIX_891_PARAMUPMIX_CLEANUP - int16_t npar = IVAS_MAX_NUM_BANDS; - int16_t onlyFreq = 1; -#endif int16_t nq; -#ifndef FIX_891_PARAMUPMIX_CLEANUP - QUANT_TYPE quant_type = FINE; -#endif int32_t alphaQuant[IVAS_MAX_NUM_BANDS]; int32_t betaQuant[IVAS_MAX_NUM_BANDS]; float alphaDequant[IVAS_MAX_NUM_BANDS]; @@ -753,21 +576,12 @@ static void put_ec_data( if ( parType == ALPHA ) { -#ifdef FIX_891_PARAMUPMIX_CLEANUP quantize_alpha( pars, &nq, alphaQuant, alphaDequant ); -#else - quantize_alpha( npar, pars, quant_type, &nq, alphaQuant, alphaDequant ); -#endif } else { -#ifdef FIX_891_PARAMUPMIX_CLEANUP quantize_alpha( alphas, &nq, alphaQuant, alphaDequant ); quantize_beta( pars, alphaQuant, &nq, betaQuant, betaDequant ); -#else - quantize_alpha( npar, alphas, quant_type, &nq, alphaQuant, alphaDequant ); - quantize_beta( npar, pars, alphaQuant, quant_type, &nq, betaQuant, betaDequant ); -#endif } if ( hMCParamUpmix->first_frame ) @@ -786,19 +600,11 @@ static void put_ec_data( /* Always one parameter set per frame for transient frames. Original PS framing is used internally. */ if ( parType == ALPHA ) { -#ifdef FIX_891_PARAMUPMIX_CLEANUP huffman_encode( hMCParamUpmix->alpha_quant_prev[ch], alphaQuant, ALPHA, nq, bit_buffer, bit_pos ); -#else - huffman_encode( onlyFreq, 1, npar, 0, hMCParamUpmix->alpha_quant_prev[ch], alphaQuant, ALPHA, quant_type, nq, bit_buffer, bit_pos ); -#endif } else { -#ifdef FIX_891_PARAMUPMIX_CLEANUP huffman_encode( hMCParamUpmix->beta_quant_prev[ch], betaQuant, BETA, nq, bit_buffer, bit_pos ); -#else - huffman_encode( onlyFreq, 1, npar, 0, hMCParamUpmix->beta_quant_prev[ch], betaQuant, BETA, quant_type, nq, bit_buffer, bit_pos ); -#endif } if ( parType == ALPHA ) diff --git a/lib_enc/ivas_rom_enc.c b/lib_enc/ivas_rom_enc.c index 2bb4efdd8..9d04a2068 100644 --- a/lib_enc/ivas_rom_enc.c +++ b/lib_enc/ivas_rom_enc.c @@ -723,7 +723,6 @@ const float Stereo_dmx_wnd_coef_48k[L_FRAME48k] = { }; -#ifdef FIX_891_PARAMUPMIX_CLEANUP /*----------------------------------------------------------------------------------* * ParamUpmix ROM tables *----------------------------------------------------------------------------------*/ @@ -771,119 +770,6 @@ const HUFF_TABLE huff_beta_table = 4, 7, 8, 9, 9, 11, 13 } } }; -#else -const HUFF_TABLE huff_alpha_table[2] = -{ - { /* Alfa Fine */ - { /* df0 */ - { 0x0002ce, 0x000b5e, 0x0004fe, 0x0005ae, 0x00027e, 0x0002de, 0x00016a, 0x0000b2, 0x00004a, 0x00004b, - 0x0000b6, 0x00004e, 0x000024, 0x00002e, 0x00000a, 0x000006, 0x000000, 0x000007, 0x000008, 0x00002f, - 0x000026, 0x000058, 0x0000b4, 0x00009e, 0x00016e, 0x000166, 0x0002df, 0x0002cf, 0x00027c, 0x00027d, - 0x0004ff, 0x000b5f, 0x0002d6 }, - { 10, 12, 11, 11, 10, 10, 9, 8, 7, 7, - 8, 7, 6, 6, 4, 3, 1, 3, 4, 6, - 6, 7, 8, 8, 9, 9, 10, 10, 10, 10, - 11, 12, 10 } - }, - { /* df */ - { 0x0011de, 0x011ffe, 0x013dea, 0x013df6, 0x008eea, 0x013df7, 0x013dee, 0x013deb, 0x013dec, 0x008eee, - 0x008ffe, 0x009efe, 0x0047fe, 0x004f7c, 0x0023fe, 0x0011fe, 0x0013fe, 0x0008f6, 0x0009ee, 0x000476, - 0x00047a, 0x0004f6, 0x00023a, 0x00027a, 0x00027e, 0x00013e, 0x00009a, 0x00004c, 0x00004e, 0x000012, - 0x00000a, 0x000006, 0x000000, 0x000007, 0x00000b, 0x000010, 0x000022, 0x000046, 0x00009b, 0x00013c, - 0x00011c, 0x00023e, 0x00023c, 0x0004fe, 0x00047e, 0x0009fe, 0x0008fe, 0x0008f7, 0x0013ff, 0x0011df, - 0x0027bc, 0x004f7e, 0x004776, 0x009efa, 0x009ef4, 0x013dfe, 0x008eeb, 0x008ee8, 0x013dff, 0x008ee9, - 0x008eef, 0x011fff, 0x013ded, 0x013def, 0x0011dc }, - { 13, 17, 17, 17, 16, 17, 17, 17, 17, 16, - 16, 16, 15, 15, 14, 13, 13, 12, 12, 11, - 11, 11, 10, 10, 10, 9, 8, 7, 7, 5, - 4, 3, 1, 3, 4, 5, 6, 7, 8, 9, - 9, 10, 10, 11, 11, 12, 12, 12, 13, 13, - 14, 15, 15, 16, 16, 17, 16, 16, 17, 16, - 16, 17, 17, 17, 13 } - }, - { /* dt */ - { 0x00eeee, 0x03b3ee, 0x03b3f6, 0x03b3fc, 0x01d9bc, 0x01d9bd, 0x01d9b2, 0x03b3fe, 0x01d9be, 0x01d9f6, - 0x01d9fc, 0x00ecda, 0x00ecfa, 0x00eeef, 0x00766e, 0x007776, 0x003b3a, 0x003bba, 0x001d9a, 0x001ddc, - 0x001dde, 0x000eec, 0x000764, 0x000772, 0x0003b0, 0x0003b8, 0x0001da, 0x0001de, 0x000072, 0x000038, - 0x00001e, 0x000006, 0x000000, 0x000002, 0x00001f, 0x00003a, 0x000073, 0x0001df, 0x0001db, 0x0003ba, - 0x0003b1, 0x000773, 0x000765, 0x000eed, 0x000ecc, 0x001d9e, 0x001d9c, 0x003bbe, 0x003b3b, 0x00777e, - 0x00767c, 0x00eefe, 0x00ecfc, 0x00ecd8, 0x01d9fd, 0x01d9fa, 0x01d9bf, 0x01d9b6, 0x01d9b3, 0x03b3fd, - 0x01d9b7, 0x03b3ff, 0x03b3ef, 0x03b3f7, 0x00eeff }, - { 16, 18, 18, 18, 17, 17, 17, 18, 17, 17, - 17, 16, 16, 16, 15, 15, 14, 14, 13, 13, - 13, 12, 11, 11, 10, 10, 9, 9, 7, 6, - 5, 3, 1, 2, 5, 6, 7, 9, 9, 10, - 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, - 15, 16, 16, 16, 17, 17, 17, 17, 17, 18, - 17, 18, 18, 18, 16 } - } - }, /* End Alfa Fine */ - { /* Alfa Coarse */ - { /* df0 */ - { 0x0003be, 0x0003fe, 0x0001fe, 0x0000fe, 0x00003e, 0x00003a, 0x00001e, 0x000002, 0x000000, 0x000006, - 0x00001c, 0x00007e, 0x000076, 0x0000ee, 0x0001de, 0x0003ff, 0x0003bf }, - { 10, 10, 9, 8, 6, 6, 5, 2, 1, 3, - 5, 7, 7, 8, 9, 10, 10 } - }, - { /* df */ - { 0x007c76, 0x03e3fe, 0x01f1f6, 0x01f1f7, 0x00f8ea, 0x007c74, 0x007c7c, 0x001f1c, 0x000f9e, 0x0007ce, - 0x0003e2, 0x0001f0, 0x0000fa, 0x00007e, 0x00000e, 0x000006, 0x000000, 0x000002, 0x00001e, 0x00007f, - 0x0000fb, 0x0001f2, 0x0003e6, 0x0007c6, 0x000f9f, 0x001f1e, 0x007c7e, 0x00f8fe, 0x00f8fa, 0x01f1fe, - 0x00f8eb, 0x03e3ff, 0x007c77 }, - { 15, 18, 17, 17, 16, 15, 15, 13, 12, 11, - 10, 9, 8, 7, 4, 3, 1, 2, 5, 7, - 8, 9, 10, 11, 12, 13, 15, 16, 16, 17, - 16, 18, 15 } - }, - { /* dt */ - { 0x003efc, 0x00fbfa, 0x007ddc, 0x00fbfe, 0x007dde, 0x007dfc, 0x003ef6, 0x001f76, 0x000fba, 0x000fbe, - 0x0003ec, 0x0001f2, 0x0000f8, 0x00007e, 0x00001e, 0x000006, 0x000000, 0x000002, 0x00000e, 0x00007f, - 0x0000fa, 0x0001f3, 0x0003ed, 0x0007dc, 0x000fbc, 0x001f7a, 0x003ef7, 0x007dfe, 0x007ddf, 0x00fbff, - 0x007ddd, 0x00fbfb, 0x003efd }, - { 14, 16, 15, 16, 15, 15, 14, 13, 12, 12, - 10, 9, 8, 7, 5, 3, 1, 2, 4, 7, - 8, 9, 10, 11, 12, 13, 14, 15, 15, 16, - 15, 16, 14 } - } - } /* End Alfa Coarse */ -}; - -const HUFF_TABLE huff_beta_table[2] = -{ - { /* Beta Fine */ - { /* df0 */ - { 0x000000, 0x000002, 0x000006, 0x00000e, 0x00001e, 0x00003e, 0x00007e, 0x0000fe, 0x0000ff }, - { 1, 2, 3, 4, 5, 6, 7, 8, 8 } - }, - { /* df */ - { 0x001f1e, 0x000f8e, 0x0003e2, 0x0001f2, 0x0000fa, 0x00007e, 0x00001e, 0x000006, 0x000000, 0x000002, - 0x00000e, 0x00007f, 0x0000fb, 0x0001f3, 0x0001f0, 0x0007c6, 0x001f1f }, - { 13, 12, 10, 9, 8, 7, 5, 3, 1, 2, - 4, 7, 8, 9, 9, 11, 13 } - }, - { /* dt */ - { 0x007dfe, 0x003efe, 0x000fbe, 0x0003ee, 0x0000fa, 0x00007e, 0x00001e, 0x000006, 0x000000, 0x000002, - 0x00000e, 0x00007f, 0x00007c, 0x0001f6, 0x0007de, 0x001f7e, 0x007dff }, - { 15, 14, 12, 10, 8, 7, 5, 3, 1, 2, - 4, 7, 7, 9, 11, 13, 15 } - } - }, /* End Beta Fine */ - { /* Beta Coarse */ - { /* df0 */ - { 0x000000, 0x000002, 0x000006, 0x00000e, 0x00000f }, - { 1, 2, 3, 4, 4 } - }, - { /* df */ - { 0x0000fe, 0x00003e, 0x00000e, 0x000006, 0x000000, 0x000002, 0x00001e, 0x00007e, 0x0000ff }, - { 8, 6, 4, 3, 1, 2, 5, 7, 8 } - }, - { /* dt */ - { 0x0000fe, 0x00007e, 0x00001e, 0x000006, 0x000000, 0x000002, 0x00000e, 0x00003e, 0x0000ff }, - { 8, 7, 5, 3, 1, 2, 4, 6, 8 } - } - } /* End Beta Coarse */ -}; -#endif const int16_t mc_paramupmix_fb_remix_order[4] = {0, 1, 2, 3}; diff --git a/lib_enc/ivas_rom_enc.h b/lib_enc/ivas_rom_enc.h index 9e6363fb0..60d4ddcf7 100644 --- a/lib_enc/ivas_rom_enc.h +++ b/lib_enc/ivas_rom_enc.h @@ -126,7 +126,6 @@ extern const float Stereo_dmx_s_wnd_coef_48k[L_FRAME48k >> 4]; extern const float Stereo_dmx_wnd_coef_32k[L_FRAME32k]; extern const float Stereo_dmx_wnd_coef_48k[L_FRAME48k]; -#ifdef FIX_891_PARAMUPMIX_CLEANUP /*----------------------------------------------------------------------------------* * ParamUpmix ROM tables *----------------------------------------------------------------------------------*/ @@ -135,12 +134,6 @@ extern const HUFF_TABLE huff_alpha_table; extern const HUFF_TABLE huff_beta_table; extern const int16_t mc_paramupmix_fb_remix_order[4]; -#else -extern const HUFF_TABLE huff_alpha_table[2]; -extern const HUFF_TABLE huff_beta_table[2]; -extern const int16_t mc_paramupmix_fb_remix_order[4]; - -#endif /*----------------------------------------------------------------------------------* * ParamMC ROM tables *----------------------------------------------------------------------------------*/ diff --git a/lib_rend/ivas_crend.c b/lib_rend/ivas_crend.c index 1d7bebf5b..2044a095b 100644 --- a/lib_rend/ivas_crend.c +++ b/lib_rend/ivas_crend.c @@ -1862,10 +1862,8 @@ ivas_error ivas_rend_crendProcess( } } -#ifdef NONBE_UNIFIED_DECODING_PATHS /* update combined orientation access index */ ivas_combined_orientation_update_index( hCombinedOrientationData, subframe_len ); -#endif } else { @@ -1903,12 +1901,10 @@ ivas_error ivas_rend_crendProcessSubframe( float *output[], /* i/o: input/output audio channels */ const int16_t n_samples_to_render, /* i : output frame length per channel */ const int32_t output_Fs /* i : output sampling rate */ -#ifdef NONBE_UNIFIED_DECODING_PATHS #ifdef SPLIT_REND_WITH_HEAD_ROT , const int16_t pos_idx #endif -#endif ) { int16_t subframe_idx, subframe_len; @@ -1922,11 +1918,7 @@ ivas_error ivas_rend_crendProcessSubframe( CREND_HANDLE hCrend; #ifdef SPLIT_REND_WITH_HEAD_ROT -#ifdef NONBE_UNIFIED_DECODING_PATHS hCrend = pCrend->hCrend[pos_idx]; -#else - hCrend = pCrend->hCrend[0]; -#endif #else hCrend = pCrend->hCrend; #endif @@ -2012,11 +2004,7 @@ ivas_error ivas_rend_crendProcessSubframe( if ( ( inConfigType == IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED ) || ( inConfigType == IVAS_REND_AUDIO_CONFIG_TYPE_AMBISONICS ) ) { #ifdef SPLIT_REND_WITH_HEAD_ROT -#ifdef NONBE_UNIFIED_DECODING_PATHS if ( ( error = ivas_rend_crendConvolver( pCrend, inConfig, outConfig, tc_local, p_pcm_tmp, output_Fs, 0, pos_idx ) ) != IVAS_ERR_OK ) -#else - if ( ( error = ivas_rend_crendConvolver( pCrend, inConfig, outConfig, tc_local, p_pcm_tmp, output_Fs, 0, 0 ) ) != IVAS_ERR_OK ) -#endif #else if ( ( error = ivas_rend_crendConvolver( pCrend, inConfig, outConfig, tc_local, p_pcm_tmp, output_Fs, 0 ) ) != IVAS_ERR_OK ) @@ -2028,11 +2016,7 @@ ivas_error ivas_rend_crendProcessSubframe( #ifdef SPLIT_REND_WITH_HEAD_ROT if ( pCrend->hCrend[0]->hReverb != NULL ) { -#ifdef NONBE_UNIFIED_DECODING_PATHS if ( ( error = ivas_reverb_process( pCrend->hCrend[pos_idx]->hReverb, inConfig, 1, tc_local, p_pcm_tmp, 0 ) ) != IVAS_ERR_OK ) -#else - if ( ( error = ivas_reverb_process( pCrend->hCrend[0]->hReverb, inConfig, 1, tc_local, p_pcm_tmp, 0 ) ) != IVAS_ERR_OK ) -#endif { return error; } @@ -2062,10 +2046,8 @@ ivas_error ivas_rend_crendProcessSubframe( return IVAS_ERR_INVALID_INPUT_FORMAT; } -#ifdef NONBE_UNIFIED_DECODING_PATHS /* update combined orientation access index */ ivas_combined_orientation_update_index( hCombinedOrientationData, subframe_len ); -#endif } /* move to output */ @@ -2223,7 +2205,6 @@ ivas_error ivas_rend_crendProcessSplitBin( } #endif -#ifdef NONBE_UNIFIED_DECODING_PATHS #ifdef SPLIT_REND_WITH_HEAD_ROT /*-----------------------------------------------------------------------------------------* * Function ivas_rend_crend_ProcessSubframesSplitBin() @@ -2389,4 +2370,3 @@ ivas_error ivas_rend_crendProcessSubframesSplitBin( return IVAS_ERR_OK; } #endif -#endif diff --git a/lib_rend/ivas_objectRenderer.c b/lib_rend/ivas_objectRenderer.c index a1e686020..8fc8935ec 100644 --- a/lib_rend/ivas_objectRenderer.c +++ b/lib_rend/ivas_objectRenderer.c @@ -287,13 +287,7 @@ ivas_error ivas_td_binaural_renderer_unwrap( const int16_t lfe_idx, /* i : LFE channel index */ const IVAS_FORMAT ivas_format, /* i : IVAS format */ ISM_METADATA_HANDLE *hIsmMetaData, /* i : ISM metadata handle */ -#ifdef NONBE_UNIFIED_DECODING_PATHS COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i/o: combined orientaton data handle */ -#else - const int16_t *enableCombinedOrientation, /* i : Combined orientation flag */ - const IVAS_QUATERNION *Quaternions, /* i : Head tracking data per subframe */ - const IVAS_VECTOR3 *Pos, /* i : Listener position data per subframe */ -#endif const int16_t ism_md_subframe_update, /* i : Number of subframes to delay ism metadata to sync with audio */ float *output[], /* i/o: SCE channels / Binaural synthesis */ const int16_t output_frame, /* i : output frame length */ @@ -307,13 +301,10 @@ ivas_error ivas_td_binaural_renderer_unwrap( int16_t c_indx, nS; float *p_reverb_signal[BINAURAL_CHANNELS]; int16_t ch; -#ifdef NONBE_UNIFIED_DECODING_PATHS int16_t *enableCombinedOrientation; /* i : Combined orientation flag */ IVAS_QUATERNION *Quaternions; /* i : Head tracking data per subframe */ IVAS_VECTOR3 *Pos; /* i : Listener position data per subframe */ -#endif -#ifdef NONBE_UNIFIED_DECODING_PATHS enableCombinedOrientation = NULL; Quaternions = NULL; Pos = NULL; @@ -323,7 +314,6 @@ ivas_error ivas_td_binaural_renderer_unwrap( Quaternions = hCombinedOrientationData->Quaternions; Pos = hCombinedOrientationData->listenerPos; } -#endif for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) { @@ -355,11 +345,7 @@ ivas_error ivas_td_binaural_renderer_unwrap( } /* Update the listener's location/orientation */ -#ifdef NONBE_UNIFIED_DECODING_PATHS if ( ( error = TDREND_Update_listener_orientation( hBinRendererTd, ( enableCombinedOrientation != NULL ) ? enableCombinedOrientation[hCombinedOrientationData->subframe_idx] : 0, ( Quaternions != NULL ) ? &Quaternions[hCombinedOrientationData->subframe_idx] : NULL, ( Pos != NULL ) ? &Pos[hCombinedOrientationData->subframe_idx] : NULL ) ) != IVAS_ERR_OK ) -#else - if ( ( error = TDREND_Update_listener_orientation( hBinRendererTd, ( enableCombinedOrientation != NULL ) ? enableCombinedOrientation[subframe_idx] : 0, ( Quaternions != NULL ) ? &Quaternions[subframe_idx] : NULL, ( Pos != NULL ) ? &Pos[subframe_idx] : NULL ) ) != IVAS_ERR_OK ) -#endif { return error; } @@ -389,10 +375,8 @@ ivas_error ivas_td_binaural_renderer_unwrap( } } -#ifdef NONBE_UNIFIED_DECODING_PATHS /* update combined orientation access index */ ivas_combined_orientation_update_index( hCombinedOrientationData, subframe_length ); -#endif } if ( hReverb != NULL ) @@ -766,15 +750,7 @@ ivas_error ivas_td_binaural_renderer_ext( hIsmMetaData[0]->non_diegetic_flag = currentPos->non_diegetic_flag; } -#ifdef NONBE_UNIFIED_DECODING_PATHS if ( ( error = ivas_td_binaural_renderer_unwrap( hReverb, transport_config, pTDRend->hBinRendererTd, num_src, lfe_idx, ivas_format, hIsmMetaData, *hCombinedOrientationData, -#else - if ( ( error = ivas_td_binaural_renderer_unwrap( hReverb, transport_config, pTDRend->hBinRendererTd, num_src, lfe_idx, ivas_format, hIsmMetaData, - - ( hCombinedOrientationData != NULL ) ? ( *hCombinedOrientationData )->enableCombinedOrientation : NULL, - ( hCombinedOrientationData != NULL ) ? ( *hCombinedOrientationData )->Quaternions : NULL, - ( hCombinedOrientationData != NULL ) ? ( *hCombinedOrientationData )->listenerPos : NULL, -#endif ism_md_subframe_update_ext, p_output, output_frame, (int16_t) ( ( output_frame * FRAMES_PER_SEC * MAX_PARAM_SPATIAL_SUBFRAMES ) / output_Fs ) ) ) != IVAS_ERR_OK ) { return error; diff --git a/lib_rend/ivas_output_init.c b/lib_rend/ivas_output_init.c index 795779800..78db534f7 100644 --- a/lib_rend/ivas_output_init.c +++ b/lib_rend/ivas_output_init.c @@ -278,11 +278,7 @@ int16_t ivas_get_nchan_buffers_dec( if ( st_ivas->ivas_format == MONO_FORMAT ) { -#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX nchan_out_buff = st_ivas->hDecoderConfig->nchan_out; -#else - nchan_out_buff = 0; -#endif } else if ( st_ivas->ivas_format == STEREO_FORMAT ) { @@ -327,7 +323,6 @@ int16_t ivas_get_nchan_buffers_dec( { nchan_out_buff = max( nchan_out_buff, st_ivas->hOutSetup.nchan_out_woLFE + st_ivas->hOutSetup.num_lfe ); } -#ifdef NONBE_UNIFIED_DECODING_PATHS_FIX #ifdef SPLIT_REND_WITH_HEAD_ROT else if ( output_config == IVAS_AUDIO_CONFIG_STEREO || output_config == IVAS_AUDIO_CONFIG_BINAURAL || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR || output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) #else @@ -336,7 +331,6 @@ int16_t ivas_get_nchan_buffers_dec( { nchan_out_buff = 2 * CPE_CHANNELS; } -#endif else if ( output_config != IVAS_AUDIO_CONFIG_EXTERNAL ) { nchan_out_buff = max( nchan_out_buff, audioCfg2channels( st_ivas->intern_config ) ); diff --git a/lib_rend/ivas_prot_rend.h b/lib_rend/ivas_prot_rend.h index 0bd5a09f5..de3830bea 100644 --- a/lib_rend/ivas_prot_rend.h +++ b/lib_rend/ivas_prot_rend.h @@ -221,15 +221,6 @@ void ivas_dirac_dec_binaural_sba_gain( const int16_t output_frame /* i : output frame length */ ); -#ifndef NONBE_UNIFIED_DECODING_PATHS -void ivas_dirac_dec_binaural( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i : combined orientation handle */ - float *output_f[], /* i/o: synthesized core-coder transport channels/DirAC output */ - const int16_t nchan_transport, /* i : number of transport channels */ - const int16_t num_subframes /* i : number of subframes to render */ -); -#endif void ivas_dirac_dec_binaural_render( Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ const uint16_t nSamplesAsked, /* i : number of CLDFB slots requested */ @@ -638,13 +629,7 @@ ivas_error ivas_td_binaural_renderer_unwrap( const int16_t lfe_idx, /* i : LFE channel index */ const IVAS_FORMAT ivas_format, /* i : IVAS format */ ISM_METADATA_HANDLE *hIsmMetaData, /* i : ISM metadata handle */ -#ifdef NONBE_UNIFIED_DECODING_PATHS COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i/o: combined orientaton data handle */ -#else - const int16_t *enableCombinedOrientation, /* i : Combined orientation flag */ - const IVAS_QUATERNION *Quaternions, /* i : Head tracking data per subframe */ - const IVAS_VECTOR3 *Pos, /* i : Listener position data per subframe */ -#endif const int16_t ism_md_subframe_update, float *output[], /* i/o: SCE channels / Binaural synthesis */ const int16_t output_frame, /* i : output frame length */ @@ -964,12 +949,10 @@ ivas_error ivas_rend_crendProcessSubframe( float *output[], /* i/o: input/output audio channels */ const int16_t n_samples_to_render, /* i : output frame length per channel */ const int32_t output_Fs /* i : output sampling rate */ -#ifdef NONBE_UNIFIED_DECODING_PATHS #ifdef SPLIT_REND_WITH_HEAD_ROT , const int16_t pos_idx #endif -#endif ); @@ -1333,7 +1316,6 @@ void rotateFrame_sd( const int16_t subframe_idx /* i : subframe index */ ); -#ifdef NONBE_UNIFIED_DECODING_PATHS void ivas_combined_orientation_update_index( COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i/o: combined orientation handle */ const int16_t samples_rendered /* i : samples rendered since the last call */ @@ -1347,7 +1329,6 @@ void ivas_combined_orientation_update_start_index( void ivas_combined_orientation_set_to_start_index( COMBINED_ORIENTATION_HANDLE hCombinedOrientationData /* i/o: combined orientation handle */ ); -#endif void rotateFrame_shd_cldfb( float Cldfb_RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i/o: unrotated HOA3 signal buffer in cldfb domain real part */ @@ -1379,9 +1360,7 @@ void ivas_external_orientation_close( ivas_error ivas_combined_orientation_open( COMBINED_ORIENTATION_HANDLE *hCombinedOrientationData, /* o : combined orientation handle */ -#ifdef NONBE_UNIFIED_DECODING_PATHS const int32_t fs, /* i : sampling rate */ -#endif const int16_t num_subframes /* i : number of subframes */ ); @@ -1830,7 +1809,6 @@ ivas_error ObjRenderIvasFrame_splitBinaural( const int16_t output_frame /* i : output frame length */ ); -#ifdef NONBE_UNIFIED_DECODING_PATHS ivas_error ivas_td_binaural_renderer_sf_splitBinaural( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ float *output[], /* i/o: SCE channels / Binaural synthesis */ @@ -1852,7 +1830,6 @@ ivas_error ivas_rend_crendProcessSubframesSplitBin( const int16_t n_samples_to_render, /* i : output frame length per channel */ const int32_t output_Fs /* i : output sampling rate */ ); -#endif ivas_error ivas_rend_crendProcessSplitBin( const CREND_WRAPPER *pCrend, diff --git a/lib_rend/ivas_rotation.c b/lib_rend/ivas_rotation.c index 7c4bdd94b..28d5b805b 100644 --- a/lib_rend/ivas_rotation.c +++ b/lib_rend/ivas_rotation.c @@ -394,11 +394,7 @@ void rotateFrame_shd( SHrotmatgen( SHrotmat_prev, hCombinedOrientationData->Rmat_prev, shd_rot_max_order ); #endif -#ifdef NONBE_UNIFIED_DECODING_PATHS SHrotmatgen( SHrotmat, hCombinedOrientationData->Rmat[hCombinedOrientationData->subframe_idx], shd_rot_max_order ); -#else - SHrotmatgen( SHrotmat, hCombinedOrientationData->Rmat[subframe_idx], shd_rot_max_order ); -#endif for ( i = 0; i < subframe_len; i++ ) { @@ -452,11 +448,7 @@ void rotateFrame_shd( for ( i = 0; i < 3; i++ ) { mvr2r( -#ifdef NONBE_UNIFIED_DECODING_PATHS hCombinedOrientationData->Rmat[hCombinedOrientationData->subframe_idx][i], -#else - hCombinedOrientationData->Rmat[subframe_idx][i], -#endif #ifdef SPLIT_REND_WITH_HEAD_ROT hCombinedOrientationData->Rmat_prev[0][i], #else @@ -552,11 +544,7 @@ void rotateFrame_sd( } /* gains for current subframe rotation */ -#ifdef NONBE_UNIFIED_DECODING_PATHS rotateAziEle( hTransSetup.ls_azimuth[ch_in_woLFE], hTransSetup.ls_elevation[ch_in_woLFE], &azimuth, &elevation, hCombinedOrientationData->Rmat[hCombinedOrientationData->subframe_idx], hTransSetup.is_planar_setup ); -#else - rotateAziEle( hTransSetup.ls_azimuth[ch_in_woLFE], hTransSetup.ls_elevation[ch_in_woLFE], &azimuth, &elevation, hCombinedOrientationData->Rmat[subframe_idx], hTransSetup.is_planar_setup ); -#endif if ( hEFAPdata != NULL && ( hTransSetup.ls_azimuth[ch_in_woLFE] != azimuth || hTransSetup.ls_elevation[ch_in_woLFE] != elevation ) ) { @@ -595,11 +583,7 @@ void rotateFrame_sd( for ( i = 0; i < 3; i++ ) { mvr2r( -#ifdef NONBE_UNIFIED_DECODING_PATHS hCombinedOrientationData->Rmat[hCombinedOrientationData->subframe_idx][i], -#else - hCombinedOrientationData->Rmat[subframe_idx][i], -#endif #ifdef SPLIT_REND_WITH_HEAD_ROT hCombinedOrientationData->Rmat_prev[0][i], #else @@ -888,9 +872,7 @@ void ivas_external_orientation_close( ivas_error ivas_combined_orientation_open( COMBINED_ORIENTATION_HANDLE *hCombinedOrientationData, /* o : combined orientation handle */ -#ifdef NONBE_UNIFIED_DECODING_PATHS const int32_t fs, /* i : sampling rate */ -#endif const int16_t num_subframes /* i : number of subframes */ ) { @@ -955,9 +937,7 @@ ivas_error ivas_combined_orientation_open( } } ( *hCombinedOrientationData )->sr_pose_pred_axis = DEFAULT_AXIS; -#ifdef NONBE_UNIFIED_DECODING_PATHS ( *hCombinedOrientationData )->sr_low_res_flag = 0; -#endif #else for ( j = 0; j < 3; j++ ) { @@ -979,11 +959,9 @@ ivas_error ivas_combined_orientation_open( ( *hCombinedOrientationData )->isExtOrientationFrozen = 0; ( *hCombinedOrientationData )->isHeadRotationFrozen = 0; -#ifdef NONBE_UNIFIED_DECODING_PATHS ( *hCombinedOrientationData )->subframe_idx = 0; ( *hCombinedOrientationData )->subframe_size = (int16_t) ( fs / ( FRAMES_PER_SEC * MAX_PARAM_SPATIAL_SUBFRAMES ) ); ( *hCombinedOrientationData )->cur_subframe_samples_rendered = 0; -#endif return IVAS_ERR_OK; } @@ -1356,12 +1334,10 @@ ivas_error combine_external_and_head_orientations( #ifdef SPLIT_REND_WITH_HEAD_ROT hCombinedOrientationData->sr_pose_pred_axis = sr_pose_pred_axis; #endif -#ifdef NONBE_UNIFIED_DECODING_PATHS hCombinedOrientationData->subframe_idx = 0; hCombinedOrientationData->cur_subframe_samples_rendered = 0; hCombinedOrientationData->subframe_idx_start = 0; hCombinedOrientationData->cur_subframe_samples_rendered_start = 0; -#endif return IVAS_ERR_OK; } @@ -1716,7 +1692,6 @@ void SHrotmatgen( } -#ifdef NONBE_UNIFIED_DECODING_PATHS /*------------------------------------------------------------------------- * ivas_combined_orientation_update_index() * @@ -1806,4 +1781,3 @@ void ivas_combined_orientation_update_start_index( return; } -#endif diff --git a/lib_rend/ivas_stat_rend.h b/lib_rend/ivas_stat_rend.h index 21c8c3a9c..ccd6641b5 100644 --- a/lib_rend/ivas_stat_rend.h +++ b/lib_rend/ivas_stat_rend.h @@ -729,22 +729,18 @@ typedef struct ivas_combined_orientation_struct IVAS_VECTOR3 listenerPos[MAX_PARAM_SPATIAL_SUBFRAMES]; #ifdef SPLIT_REND_WITH_HEAD_ROT IVAS_SPLIT_REND_ROT_AXIS sr_pose_pred_axis; -#ifdef NONBE_UNIFIED_DECODING_PATHS int16_t sr_low_res_flag; -#endif #endif IVAS_QUATERNION Quaternion_frozen_ext; IVAS_QUATERNION Quaternion_frozen_head; int8_t isExtOrientationFrozen; int8_t isHeadRotationFrozen; int16_t num_subframes; -#ifdef NONBE_UNIFIED_DECODING_PATHS int16_t subframe_idx; int16_t subframe_size; int16_t cur_subframe_samples_rendered; int16_t subframe_idx_start; int16_t cur_subframe_samples_rendered_start; -#endif } COMBINED_ORIENTATION_DATA, *COMBINED_ORIENTATION_HANDLE; -- GitLab From 0bee48ef2ba4a86fe37f530ceaf675f304034d64 Mon Sep 17 00:00:00 2001 From: Erik Norvell Date: Fri, 20 Dec 2024 15:24:07 +0100 Subject: [PATCH 03/33] Revert line ending characters for VS workspace files --- Workspace_msvc/decoder.vcxproj | 340 +++--- Workspace_msvc/encoder.vcxproj | 354 +++---- Workspace_msvc/lib_com.vcxproj | 616 +++++------ Workspace_msvc/lib_com.vcxproj.filters | 1100 ++++++++++---------- Workspace_msvc/lib_dec.vcxproj | 698 ++++++------- Workspace_msvc/lib_dec.vcxproj.filters | 1142 ++++++++++----------- Workspace_msvc/lib_enc.vcxproj | 730 ++++++------- Workspace_msvc/lib_enc.vcxproj.filters | 1256 +++++++++++------------ Workspace_msvc/lib_lc3plus.vcxproj | 364 +++---- Workspace_msvc/lib_rend.vcxproj | 466 ++++----- Workspace_msvc/lib_rend.vcxproj.filters | 440 ++++---- Workspace_msvc/lib_util.vcxproj | 322 +++--- Workspace_msvc/renderer.vcxproj | 358 +++---- 13 files changed, 4093 insertions(+), 4093 deletions(-) diff --git a/Workspace_msvc/decoder.vcxproj b/Workspace_msvc/decoder.vcxproj index 1ea98099d..e59992847 100644 --- a/Workspace_msvc/decoder.vcxproj +++ b/Workspace_msvc/decoder.vcxproj @@ -1,171 +1,171 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - decoder - {E3DCBC31-7FC9-D127-E000-529F8460D5FD} - decoder - 10.0.17763.0 - - - - Application - v141 - false - MultiByte - - - Application - v141 - false - MultiByte - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - ..\ - .\Debug_$(ProjectName)\ - false - false - IVAS_dec - - - ..\ - .\Release_$(ProjectName)\ - false - false - IVAS_dec - - - - - - - $(IntDir)$(ProjectName).tlb - - - - Disabled - ..\lib_dec;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;WIN32;$(Macros);%(PreprocessorDefinitions) - - EnableFastChecks - MultiThreadedDebug - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - OldStyle - Default - %(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - - $(OutDir)$(TargetName).exe - true - - true - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - - - $(IntDir)$(ProjectName).tlb - - - - MaxSpeed - AnySuitable - false - Neither - false - false - ..\lib_dec;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - Precise - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - - Default - %(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - $(OutDir)$(TargetName).exe - true - - false - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX86 - libcmtd.lib - - - - - - - - {e822ddaf-0f5f-4cd0-a694-38ae69de74d3} - false - - - {2fa8f384-0775-f3b7-f8c3-85209222fc70} - false - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + decoder + {E3DCBC31-7FC9-D127-E000-529F8460D5FD} + decoder + 10.0.17763.0 + + + + Application + v141 + false + MultiByte + + + Application + v141 + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + ..\ + .\Debug_$(ProjectName)\ + false + false + IVAS_dec + + + ..\ + .\Release_$(ProjectName)\ + false + false + IVAS_dec + + + + + + + $(IntDir)$(ProjectName).tlb + + + + Disabled + ..\lib_dec;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;WIN32;$(Macros);%(PreprocessorDefinitions) + + EnableFastChecks + MultiThreadedDebug + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + OldStyle + Default + %(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + + $(OutDir)$(TargetName).exe + true + + true + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + + + $(IntDir)$(ProjectName).tlb + + + + MaxSpeed + AnySuitable + false + Neither + false + false + ..\lib_dec;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + Precise + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + + Default + %(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + $(OutDir)$(TargetName).exe + true + + false + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX86 + libcmtd.lib + + + + + + + + {e822ddaf-0f5f-4cd0-a694-38ae69de74d3} + false + + + {2fa8f384-0775-f3b7-f8c3-85209222fc70} + false + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/encoder.vcxproj b/Workspace_msvc/encoder.vcxproj index 5ec7a2c01..9578e488d 100644 --- a/Workspace_msvc/encoder.vcxproj +++ b/Workspace_msvc/encoder.vcxproj @@ -1,178 +1,178 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - encoder - {B3FC9DFC-7268-8660-7C0D-B60BAF02C554} - encoder - 10.0.17763.0 - - - - Application - v141 - false - MultiByte - - - Application - v141 - false - MultiByte - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - ..\ - .\Debug_$(ProjectName)\ - false - false - IVAS_cod - - - ..\ - .\Release_$(ProjectName)\ - false - false - IVAS_cod - - - - - - - $(IntDir)$(ProjectName).tlb - - - - Disabled - ..\lib_enc;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;WIN32;$(Macros);%(PreprocessorDefinitions) - - EnableFastChecks - MultiThreadedDebug - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - OldStyle - Default - %(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - - $(OutDir)$(TargetName).exe - true - - false - true - $(IntDir)$(ProjectName).pdb - Console - - false - - MachineX86 - - - - - - - - - - - $(IntDir)$(ProjectName).tlb - - - - MaxSpeed - AnySuitable - false - Neither - false - false - ..\lib_enc;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - Precise - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - - Default - %(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - $(OutDir)$(TargetName).exe - true - - false - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - - - - - - {824da4cf-06f0-45c9-929a-8792f0e19c3e} - false - - - {2fa8f384-0775-f3b7-f8c3-85209222fc70} - false - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + encoder + {B3FC9DFC-7268-8660-7C0D-B60BAF02C554} + encoder + 10.0.17763.0 + + + + Application + v141 + false + MultiByte + + + Application + v141 + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + ..\ + .\Debug_$(ProjectName)\ + false + false + IVAS_cod + + + ..\ + .\Release_$(ProjectName)\ + false + false + IVAS_cod + + + + + + + $(IntDir)$(ProjectName).tlb + + + + Disabled + ..\lib_enc;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;WIN32;$(Macros);%(PreprocessorDefinitions) + + EnableFastChecks + MultiThreadedDebug + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + OldStyle + Default + %(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + + $(OutDir)$(TargetName).exe + true + + false + true + $(IntDir)$(ProjectName).pdb + Console + + false + + MachineX86 + + + + + + + + + + + $(IntDir)$(ProjectName).tlb + + + + MaxSpeed + AnySuitable + false + Neither + false + false + ..\lib_enc;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + Precise + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + + Default + %(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + $(OutDir)$(TargetName).exe + true + + false + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + + + + + + {824da4cf-06f0-45c9-929a-8792f0e19c3e} + false + + + {2fa8f384-0775-f3b7-f8c3-85209222fc70} + false + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/lib_com.vcxproj b/Workspace_msvc/lib_com.vcxproj index 494131992..cdf577df2 100644 --- a/Workspace_msvc/lib_com.vcxproj +++ b/Workspace_msvc/lib_com.vcxproj @@ -1,309 +1,309 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - {39EC200D-7795-4FF8-B214-B24EDA5526AE} - common - 10.0.17763.0 - - - - StaticLibrary - v141 - false - MultiByte - - - StaticLibrary - v141 - false - MultiByte - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - .\Debug_$(ProjectName)\ - .\Debug_$(ProjectName)\ - libivascom - - - .\Release_$(ProjectName)\ - .\Release_$(ProjectName)\ - libivascom - - - - - - - Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_lc3plus;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) - - EnableFastChecks - MultiThreadedDebug - - - $(IntDir)$(ProjectName).pdb - Level4 - true - OldStyle - Default - %(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - WS2_32.lib; %(AdditionalDependencies) - $(OutDir)$(TargetName).lib - true - - - - - - - - MaxSpeed - AnySuitable - false - Neither - false - false - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_lc3plus;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - - - $(IntDir)$(ProjectName).pdb - Level4 - true - - Default - %(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - WS2_32.lib; %(AdditionalDependencies) - $(OutDir)$(TargetName).lib - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + {39EC200D-7795-4FF8-B214-B24EDA5526AE} + common + 10.0.17763.0 + + + + StaticLibrary + v141 + false + MultiByte + + + StaticLibrary + v141 + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + .\Debug_$(ProjectName)\ + .\Debug_$(ProjectName)\ + libivascom + + + .\Release_$(ProjectName)\ + .\Release_$(ProjectName)\ + libivascom + + + + + + + Disabled + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_lc3plus;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) + + EnableFastChecks + MultiThreadedDebug + + + $(IntDir)$(ProjectName).pdb + Level4 + true + OldStyle + Default + %(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + + + + MaxSpeed + AnySuitable + false + Neither + false + false + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_lc3plus;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + + + $(IntDir)$(ProjectName).pdb + Level4 + true + + Default + %(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/lib_com.vcxproj.filters b/Workspace_msvc/lib_com.vcxproj.filters index 66edeac26..85fd7e8d6 100644 --- a/Workspace_msvc/lib_com.vcxproj.filters +++ b/Workspace_msvc/lib_com.vcxproj.filters @@ -1,551 +1,551 @@ - - - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_evs_c - - - common_evs_c - - - common_evs_c - - - common_evs_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_all_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_evs_c - - - common_evs_c - - - common_evs_c - - - common_evs_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - common_ivas_c - - - - - common_h - - - common_h - - - common_h - - - common_h - - - common_h - - - common_h - - - common_h - - - common_h - - - common_h - - - common_h - - - common_h - - - common_h - - - common_h - - - common_h - - - common_h - - - common_h - - - common_h - - - common_h - - - common_h - - - - common_h - - - - - - {890c2f45-9385-4fce-859b-6a65469e8dc0} - - - {201ea764-9626-4dca-9cc4-5b4106f8b8b2} - - - {fbb860e2-79d0-45b1-ada1-c3a0a369ce2c} - - - {b95b7bed-a666-4a00-9332-2b528638503e} - - + + + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_evs_c + + + common_evs_c + + + common_evs_c + + + common_evs_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_all_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_evs_c + + + common_evs_c + + + common_evs_c + + + common_evs_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + common_ivas_c + + + + + common_h + + + common_h + + + common_h + + + common_h + + + common_h + + + common_h + + + common_h + + + common_h + + + common_h + + + common_h + + + common_h + + + common_h + + + common_h + + + common_h + + + common_h + + + common_h + + + common_h + + + common_h + + + common_h + + + + common_h + + + + + + {890c2f45-9385-4fce-859b-6a65469e8dc0} + + + {201ea764-9626-4dca-9cc4-5b4106f8b8b2} + + + {fbb860e2-79d0-45b1-ada1-c3a0a369ce2c} + + + {b95b7bed-a666-4a00-9332-2b528638503e} + + \ No newline at end of file diff --git a/Workspace_msvc/lib_dec.vcxproj b/Workspace_msvc/lib_dec.vcxproj index 228f821f1..662502a1a 100644 --- a/Workspace_msvc/lib_dec.vcxproj +++ b/Workspace_msvc/lib_dec.vcxproj @@ -1,349 +1,349 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - lib_dec - {E822DDAF-0F5F-4CD0-A694-38AE69DE74D3} - evs_dec - 10.0.17763.0 - - - StaticLibrary - v141 - false - MultiByte - - - - StaticLibrary - v141 - false - MultiByte - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - .\Debug_$(ProjectName)\ - .\Debug_$(ProjectName)\ - false - false - libivasdec - - - .\Release_$(ProjectName)\ - .\Release_$(ProjectName)\ - false - false - libivasdec - - - - - - - .\Debug\$(ProjectName).tlb - - - - Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_lc3plus;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) - - EnableFastChecks - MultiThreadedDebug - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - OldStyle - Default - %(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - WS2_32.lib; %(AdditionalDependencies) - $(OutDir)$(TargetName).lib - true - - - - - - - - $(IntDir)$(ProjectName).tlb - - - - MaxSpeed - AnySuitable - false - Neither - false - false - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_lc3plus;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - - Default - %(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - WS2_32.lib; %(AdditionalDependencies) - $(OutDir)$(TargetName).lib - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {39ec200d-7795-4ff8-b214-b24eda5526ae} - false - - - {54509728-928b-44d9-a118-a6f92f08b34f} - false - - - {718DE063-A18B-BB72-9150-62B892E6FFA6} - false - - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + lib_dec + {E822DDAF-0F5F-4CD0-A694-38AE69DE74D3} + evs_dec + 10.0.17763.0 + + + StaticLibrary + v141 + false + MultiByte + + + + StaticLibrary + v141 + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + .\Debug_$(ProjectName)\ + .\Debug_$(ProjectName)\ + false + false + libivasdec + + + .\Release_$(ProjectName)\ + .\Release_$(ProjectName)\ + false + false + libivasdec + + + + + + + .\Debug\$(ProjectName).tlb + + + + Disabled + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_lc3plus;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) + + EnableFastChecks + MultiThreadedDebug + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + OldStyle + Default + %(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + + + + $(IntDir)$(ProjectName).tlb + + + + MaxSpeed + AnySuitable + false + Neither + false + false + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_lc3plus;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + + Default + %(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {39ec200d-7795-4ff8-b214-b24eda5526ae} + false + + + {54509728-928b-44d9-a118-a6f92f08b34f} + false + + + {718DE063-A18B-BB72-9150-62B892E6FFA6} + false + + + + + + + + + + + diff --git a/Workspace_msvc/lib_dec.vcxproj.filters b/Workspace_msvc/lib_dec.vcxproj.filters index 80340b480..24d58eb97 100644 --- a/Workspace_msvc/lib_dec.vcxproj.filters +++ b/Workspace_msvc/lib_dec.vcxproj.filters @@ -1,572 +1,572 @@ - - - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_ivas_c - - - decoder_evs_c - - - decoder_evs_c - - - decoder_evs_c - - - decoder_evs_c - - - decoder_evs_c - - - decoder_evs_c - - - decoder_evs_c - - - decoder_evs_c - - - decoder_evs_c - - - decoder_evs_c - - - decoder_evs_c - - - decoder_evs_c - - - decoder_evs_c - - - decoder_evs_c - - - decoder_evs_c - - - decoder_evs_c - - - decoder_evs_c - - - decoder_evs_c - - - decoder_evs_c - - - decoder_evs_c - - - decoder_evs_c - - - decoder_evs_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - decoder_all_c - - - - - - decoder_h - - - decoder_h - - - decoder_h - - - decoder_h - - - decoder_h - - - decoder_h - - - decoder_h - - - decoder_h - - - decoder_h - - - decoder_h - - - decoder_h - - - decoder_h - - - - - - {f63b6db2-97ec-4d8d-be9c-e798ac8bb645} - - - {0853864e-7de7-411d-975b-5045652f22c3} - - - {e29aae34-aeeb-45dd-a986-61b39890c5bb} - - - {c33b80b3-67ce-466b-91c0-4adfc9efcb5c} - - + + + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_ivas_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_evs_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + decoder_all_c + + + + + + decoder_h + + + decoder_h + + + decoder_h + + + decoder_h + + + decoder_h + + + decoder_h + + + decoder_h + + + decoder_h + + + decoder_h + + + decoder_h + + + decoder_h + + + decoder_h + + + + + + {f63b6db2-97ec-4d8d-be9c-e798ac8bb645} + + + {0853864e-7de7-411d-975b-5045652f22c3} + + + {e29aae34-aeeb-45dd-a986-61b39890c5bb} + + + {c33b80b3-67ce-466b-91c0-4adfc9efcb5c} + + \ No newline at end of file diff --git a/Workspace_msvc/lib_enc.vcxproj b/Workspace_msvc/lib_enc.vcxproj index dae54445c..6ef1fcabe 100644 --- a/Workspace_msvc/lib_enc.vcxproj +++ b/Workspace_msvc/lib_enc.vcxproj @@ -1,365 +1,365 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - lib_enc - {824DA4CF-06F0-45C9-929A-8792F0E19C3E} - evs_enc - 10.0.17763.0 - - - - StaticLibrary - v141 - false - MultiByte - - - StaticLibrary - v141 - false - MultiByte - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - .\Debug_$(ProjectName)\ - .\Debug_$(ProjectName)\ - false - false - libivasenc - - - .\Release_$(ProjectName)\ - .\Release_$(ProjectName)\ - false - false - libivasenc - - - - - - - $(IntDir)$(ProjectName).tlb - - - - Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_lc3plus;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) - - EnableFastChecks - MultiThreadedDebug - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - OldStyle - Default - %(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - WS2_32.lib; %(AdditionalDependencies) - $(OutDir)$(TargetName).lib - true - - - - - - - - - - - $(IntDir)$(ProjectName).tlb - - - - MaxSpeed - AnySuitable - false - Neither - false - false - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_lc3plus;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - Precise - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - - Default - %(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - WS2_32.lib; %(AdditionalDependencies) - $(OutDir)$(TargetName).lib - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {39ec200d-7795-4ff8-b214-b24eda5526ae} - false - - - {54509728-928b-44d9-a118-a6f92f08b34f} - false - - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + lib_enc + {824DA4CF-06F0-45C9-929A-8792F0E19C3E} + evs_enc + 10.0.17763.0 + + + + StaticLibrary + v141 + false + MultiByte + + + StaticLibrary + v141 + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + .\Debug_$(ProjectName)\ + .\Debug_$(ProjectName)\ + false + false + libivasenc + + + .\Release_$(ProjectName)\ + .\Release_$(ProjectName)\ + false + false + libivasenc + + + + + + + $(IntDir)$(ProjectName).tlb + + + + Disabled + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_lc3plus;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) + + EnableFastChecks + MultiThreadedDebug + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + OldStyle + Default + %(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + + + + + + + $(IntDir)$(ProjectName).tlb + + + + MaxSpeed + AnySuitable + false + Neither + false + false + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_lc3plus;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + Precise + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + + Default + %(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {39ec200d-7795-4ff8-b214-b24eda5526ae} + false + + + {54509728-928b-44d9-a118-a6f92f08b34f} + false + + + + + + + + + + + diff --git a/Workspace_msvc/lib_enc.vcxproj.filters b/Workspace_msvc/lib_enc.vcxproj.filters index 4995de5c9..250aecf0b 100644 --- a/Workspace_msvc/lib_enc.vcxproj.filters +++ b/Workspace_msvc/lib_enc.vcxproj.filters @@ -1,629 +1,629 @@ - - - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_evs_c - - - enc_evs_c - - - enc_evs_c - - - enc_evs_c - - - enc_evs_c - - - enc_evs_c - - - enc_evs_c - - - enc_evs_c - - - enc_evs_c - - - enc_evs_c - - - enc_evs_c - - - enc_evs_c - - - enc_evs_c - - - enc_evs_c - - - enc_evs_c - - - enc_evs_c - - - enc_evs_c - - - enc_evs_c - - - enc_evs_c - - - enc_evs_c - - - enc_evs_c - - - enc_evs_c - - - enc_evs_c - - - enc_evs_c - - - enc_evs_c - - - enc_evs_c - - - enc_evs_c - - - enc_evs_c - - - enc_evs_c - - - enc_evs_c - - - enc_evs_c - - - enc_evs_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_all_c - - - enc_evs_c - - - enc_evs_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_all_c - - - enc_evs_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - enc_ivas_c - - - - - enc_h - - - enc_h - - - enc_h - - - enc_h - - - - - - {b7ee0526-8b79-4554-a3ec-04e51d38475f} - - - {dabed049-70a2-48f2-9da6-3b81a3664033} - - - {5717f1cb-c593-400b-b23a-45c422fd95c8} - - - {6cccabbe-510f-43d3-90e1-8ed5ea3837d7} - - + + + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_evs_c + + + enc_evs_c + + + enc_evs_c + + + enc_evs_c + + + enc_evs_c + + + enc_evs_c + + + enc_evs_c + + + enc_evs_c + + + enc_evs_c + + + enc_evs_c + + + enc_evs_c + + + enc_evs_c + + + enc_evs_c + + + enc_evs_c + + + enc_evs_c + + + enc_evs_c + + + enc_evs_c + + + enc_evs_c + + + enc_evs_c + + + enc_evs_c + + + enc_evs_c + + + enc_evs_c + + + enc_evs_c + + + enc_evs_c + + + enc_evs_c + + + enc_evs_c + + + enc_evs_c + + + enc_evs_c + + + enc_evs_c + + + enc_evs_c + + + enc_evs_c + + + enc_evs_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_all_c + + + enc_evs_c + + + enc_evs_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_all_c + + + enc_evs_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + enc_ivas_c + + + + + enc_h + + + enc_h + + + enc_h + + + enc_h + + + + + + {b7ee0526-8b79-4554-a3ec-04e51d38475f} + + + {dabed049-70a2-48f2-9da6-3b81a3664033} + + + {5717f1cb-c593-400b-b23a-45c422fd95c8} + + + {6cccabbe-510f-43d3-90e1-8ed5ea3837d7} + + \ No newline at end of file diff --git a/Workspace_msvc/lib_lc3plus.vcxproj b/Workspace_msvc/lib_lc3plus.vcxproj index c61e00bf3..207b6903c 100644 --- a/Workspace_msvc/lib_lc3plus.vcxproj +++ b/Workspace_msvc/lib_lc3plus.vcxproj @@ -1,183 +1,183 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Release - Win32 - - - Release - x64 - - - - {95030B82-70CD-4C6B-84D4-61096035BEA2} - Win32Proj - LC3_FL - 10.0.17763.0 - - - - StaticLibrary - true - v141 - Unicode - - - StaticLibrary - false - v141 - true - Unicode - - - - - - - - - - - - - - - liblc3plus - .\Debug_$(ProjectName)\ - .\Debug_$(ProjectName)\ - - - LC3plus - $(Platform)\$(Configuration)\ - $(Platform)\$(Configuration)\Obj\ - - - - - - Level3 - ..\lib_com;%(AdditionalIncludeDirectories) - Disabled - MultiThreadedDebug - WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) - 4305;4244;4996 - OldStyle - false - - - Console - true - - - - - Level3 - - - ..\lib_com;%(AdditionalIncludeDirectories) - MaxSpeed - MultiThreaded - true - true - WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) - 4244;4305;4996 - - - Console - true - true - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {95030B82-70CD-4C6B-84D4-61096035BEA2} + Win32Proj + LC3_FL + 10.0.17763.0 + + + + StaticLibrary + true + v141 + Unicode + + + StaticLibrary + false + v141 + true + Unicode + + + + + + + + + + + + + + + liblc3plus + .\Debug_$(ProjectName)\ + .\Debug_$(ProjectName)\ + + + LC3plus + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\Obj\ + + + + + + Level3 + ..\lib_com;%(AdditionalIncludeDirectories) + Disabled + MultiThreadedDebug + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + 4305;4244;4996 + OldStyle + false + + + Console + true + + + + + Level3 + + + ..\lib_com;%(AdditionalIncludeDirectories) + MaxSpeed + MultiThreaded + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + 4244;4305;4996 + + + Console + true + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/lib_rend.vcxproj b/Workspace_msvc/lib_rend.vcxproj index fdc709e44..f248ab541 100644 --- a/Workspace_msvc/lib_rend.vcxproj +++ b/Workspace_msvc/lib_rend.vcxproj @@ -1,234 +1,234 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - lib_rend - {718DE063-A18B-BB72-9150-62B892E6FFA6} - evs_dec - 10.0.17763.0 - - - StaticLibrary - v141 - false - MultiByte - - - - StaticLibrary - v141 - false - MultiByte - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - .\Debug_$(ProjectName)\ - .\Debug_$(ProjectName)\ - false - false - libivasrend - - - .\Release_$(ProjectName)\ - .\Release_$(ProjectName)\ - false - false - libivasrend - - - - - - - .\Debug\$(ProjectName).tlb - - - - Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_lc3plus;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) - - EnableFastChecks - MultiThreadedDebug - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - OldStyle - Default - %(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - WS2_32.lib; %(AdditionalDependencies) - $(OutDir)$(TargetName).lib - true - - - - - - - - $(IntDir)$(ProjectName).tlb - - - - MaxSpeed - AnySuitable - false - Neither - false - false - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_lc3plus;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - - Default - %(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - WS2_32.lib; %(AdditionalDependencies) - $(OutDir)$(TargetName).lib - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {39ec200d-7795-4ff8-b214-b24eda5526ae} - false - - - {54509728-928b-44d9-a118-a6f92f08b34f} - false - - - {95030B82-70CD-4C6B-84D4-61096035BEA2} - false - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + lib_rend + {718DE063-A18B-BB72-9150-62B892E6FFA6} + evs_dec + 10.0.17763.0 + + + StaticLibrary + v141 + false + MultiByte + + + + StaticLibrary + v141 + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + .\Debug_$(ProjectName)\ + .\Debug_$(ProjectName)\ + false + false + libivasrend + + + .\Release_$(ProjectName)\ + .\Release_$(ProjectName)\ + false + false + libivasrend + + + + + + + .\Debug\$(ProjectName).tlb + + + + Disabled + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_lc3plus;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) + + EnableFastChecks + MultiThreadedDebug + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + OldStyle + Default + %(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + + + + $(IntDir)$(ProjectName).tlb + + + + MaxSpeed + AnySuitable + false + Neither + false + false + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_lc3plus;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + + Default + %(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {39ec200d-7795-4ff8-b214-b24eda5526ae} + false + + + {54509728-928b-44d9-a118-a6f92f08b34f} + false + + + {95030B82-70CD-4C6B-84D4-61096035BEA2} + false + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/lib_rend.vcxproj.filters b/Workspace_msvc/lib_rend.vcxproj.filters index e5e6c9401..4707a48b2 100644 --- a/Workspace_msvc/lib_rend.vcxproj.filters +++ b/Workspace_msvc/lib_rend.vcxproj.filters @@ -1,221 +1,221 @@ - - - - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - rend_c - - - - - - rend_h - - - rend_h - - - rend_h - - - rend_h - - - rend_h - - - rend_h - - - rend_h - - - rend_h - - - rend_h - - - rend_h - - - rend_h - - - - - {54449ece-ef29-44b5-9512-ed8f555851a8} - - - {672b0eb6-cce8-425c-8bf2-aba4b45639bb} - - + + + + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + rend_c + + + + + + rend_h + + + rend_h + + + rend_h + + + rend_h + + + rend_h + + + rend_h + + + rend_h + + + rend_h + + + rend_h + + + rend_h + + + rend_h + + + + + {54449ece-ef29-44b5-9512-ed8f555851a8} + + + {672b0eb6-cce8-425c-8bf2-aba4b45639bb} + + \ No newline at end of file diff --git a/Workspace_msvc/lib_util.vcxproj b/Workspace_msvc/lib_util.vcxproj index 76f69d8be..4b787f1d0 100644 --- a/Workspace_msvc/lib_util.vcxproj +++ b/Workspace_msvc/lib_util.vcxproj @@ -1,162 +1,162 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - {2FA8F384-0775-F3B7-F8C3-85209222FC70} - utility - 10.0.17763.0 - - - - StaticLibrary - v141 - MultiByte - - - StaticLibrary - v141 - MultiByte - true - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - true - .\Debug_$(ProjectName)\ - .\Debug_$(ProjectName)\ - libivasutil - - - false - .\Release_$(ProjectName)\ - .\Release_$(ProjectName)\ - libivasutil - - - - Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_util;..\lib_lc3plus;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);ZLIB_WINAPI;%(PreprocessorDefinitions) - false - - EnableFastChecks - MultiThreadedDebug - false - $(IntDir)$(ProjectName).pdb - Level4 - OldStyle - Default - %(DisableSpecificWarnings) - - - $(OutDir)$(TargetName).lib - - - - - MaxSpeed - AnySuitable - false - false - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_util;..\lib_lc3plus;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);ZLIB_WINAPI;%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - $(IntDir)$(ProjectName).pdb - Level4 - - Default - %(DisableSpecificWarnings) - - - $(OutDir)$(TargetName).lib - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + {2FA8F384-0775-F3B7-F8C3-85209222FC70} + utility + 10.0.17763.0 + + + + StaticLibrary + v141 + MultiByte + + + StaticLibrary + v141 + MultiByte + true + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + true + .\Debug_$(ProjectName)\ + .\Debug_$(ProjectName)\ + libivasutil + + + false + .\Release_$(ProjectName)\ + .\Release_$(ProjectName)\ + libivasutil + + + + Disabled + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_util;..\lib_lc3plus;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);ZLIB_WINAPI;%(PreprocessorDefinitions) + false + + EnableFastChecks + MultiThreadedDebug + false + $(IntDir)$(ProjectName).pdb + Level4 + OldStyle + Default + %(DisableSpecificWarnings) + + + $(OutDir)$(TargetName).lib + + + + + MaxSpeed + AnySuitable + false + false + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_util;..\lib_lc3plus;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);ZLIB_WINAPI;%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + $(IntDir)$(ProjectName).pdb + Level4 + + Default + %(DisableSpecificWarnings) + + + $(OutDir)$(TargetName).lib + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/renderer.vcxproj b/Workspace_msvc/renderer.vcxproj index 6047c5b39..bf4a162d1 100644 --- a/Workspace_msvc/renderer.vcxproj +++ b/Workspace_msvc/renderer.vcxproj @@ -1,180 +1,180 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - renderer - {12B4C8A5-1E06-4E30-B443-D1F916F52B47} - renderer - 10.0.17763.0 - - - - Application - v141 - false - MultiByte - - - Application - v141 - false - MultiByte - - - - - - - - - - - - - - - <_ProjectFileVersion>15.0.27428.2015 - - - ..\ - .\Debug_$(ProjectName)\ - false - false - IVAS_rend - - - ..\ - .\Release_$(ProjectName)\ - false - false - IVAS_rend - - - - $(IntDir)$(ProjectName).tlb - - - - Disabled - ..\lib_com;..\lib_debug;..\lib_util;..\lib_rend;..\lib_lc3plus;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;WIN32;$(Macros);%(PreprocessorDefinitions) - - EnableFastChecks - MultiThreadedDebug - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - OldStyle - Default - %(DisableSpecificWarnings) - - - _DEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - - $(OutDir)$(TargetName).exe - true - - true - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX86 - - - - - $(IntDir)$(ProjectName).tlb - - - - MaxSpeed - AnySuitable - false - Neither - false - false - ..\lib_com;..\lib_debug;..\lib_util;..\lib_rend;..\lib_lc3plus;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) - true - - Default - MultiThreaded - true - Precise - false - - - $(IntDir)$(ProjectName).pdb - Level4 - true - - Default - %(DisableSpecificWarnings) - - - NDEBUG;%(PreprocessorDefinitions) - 0x0c0c - - - $(OutDir)$(TargetName).exe - true - - false - $(IntDir)$(ProjectName).pdb - Console - false - - MachineX86 - libcmtd.lib - - - - - - - - {54509728-928B-44D9-A118-A6F92F08B34F} - false - - - {E822DDAF-0F5F-4CD0-A694-38AE69DE74D3} - false - - - {2FA8F384-0775-F3B7-F8C3-85209222FC70} - false - - - {39ec200d-7795-4ff8-b214-b24eda5526ae} - false - - - {718DE063-A18B-BB72-9150-62B892E6FFA6} - false - - - - - - - - - - + + + + + Debug + Win32 + + + Release + Win32 + + + + renderer + {12B4C8A5-1E06-4E30-B443-D1F916F52B47} + renderer + 10.0.17763.0 + + + + Application + v141 + false + MultiByte + + + Application + v141 + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + ..\ + .\Debug_$(ProjectName)\ + false + false + IVAS_rend + + + ..\ + .\Release_$(ProjectName)\ + false + false + IVAS_rend + + + + $(IntDir)$(ProjectName).tlb + + + + Disabled + ..\lib_com;..\lib_debug;..\lib_util;..\lib_rend;..\lib_lc3plus;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;WIN32;$(Macros);%(PreprocessorDefinitions) + + EnableFastChecks + MultiThreadedDebug + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + OldStyle + Default + %(DisableSpecificWarnings) + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + + $(OutDir)$(TargetName).exe + true + + true + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + + + $(IntDir)$(ProjectName).tlb + + + + MaxSpeed + AnySuitable + false + Neither + false + false + ..\lib_com;..\lib_debug;..\lib_util;..\lib_rend;..\lib_lc3plus;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + Precise + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + + Default + %(DisableSpecificWarnings) + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + $(OutDir)$(TargetName).exe + true + + false + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX86 + libcmtd.lib + + + + + + + + {54509728-928B-44D9-A118-A6F92F08B34F} + false + + + {E822DDAF-0F5F-4CD0-A694-38AE69DE74D3} + false + + + {2FA8F384-0775-F3B7-F8C3-85209222FC70} + false + + + {39ec200d-7795-4ff8-b214-b24eda5526ae} + false + + + {718DE063-A18B-BB72-9150-62B892E6FFA6} + false + + + + + + + + + + \ No newline at end of file -- GitLab From a60351ad1283cea7674309d1f014797c56d44d33 Mon Sep 17 00:00:00 2001 From: Erik Norvell Date: Fri, 20 Dec 2024 15:25:35 +0100 Subject: [PATCH 04/33] Revert line ending characters for VS workspace files - 2 --- Workspace_msvc/Workspace_msvc.sln | 210 +++++++++++++++--------------- 1 file changed, 105 insertions(+), 105 deletions(-) diff --git a/Workspace_msvc/Workspace_msvc.sln b/Workspace_msvc/Workspace_msvc.sln index 56eb9f45e..f7a8d6f9e 100644 --- a/Workspace_msvc/Workspace_msvc.sln +++ b/Workspace_msvc/Workspace_msvc.sln @@ -1,105 +1,105 @@ -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.28307.902 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lib_dec", "lib_dec.vcxproj", "{E822DDAF-0F5F-4CD0-A694-38AE69DE74D3}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lib_enc", "lib_enc.vcxproj", "{824DA4CF-06F0-45C9-929A-8792F0E19C3E}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lib_com", "lib_com.vcxproj", "{39EC200D-7795-4FF8-B214-B24EDA5526AE}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lib_rend", "lib_rend.vcxproj", "{718DE063-A18B-BB72-9150-62B892E6FFA6}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lib_util", "lib_util.vcxproj", "{2FA8F384-0775-F3B7-F8C3-85209222FC70}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lib_debug", "lib_debug.vcxproj", "{54509728-928B-44D9-A118-A6F92F08B34F}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "decoder", "decoder.vcxproj", "{E3DCBC31-7FC9-D127-E000-529F8460D5FD}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "encoder", "encoder.vcxproj", "{B3FC9DFC-7268-8660-7C0D-B60BAF02C554}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "renderer", "renderer.vcxproj", "{12B4C8A5-1E06-4E30-B443-D1F916F52B47}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LC3plus", "lib_lc3plus.vcxproj", "{95030B82-70CD-4C6B-84D4-61096035BEA2}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{51160D4C-55C9-4C16-A792-D94507225746}" - ProjectSection(SolutionItems) = preProject - ..\.clang-format = ..\.clang-format - EndProjectSection -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Debug|x64 = Debug|x64 - Release|Win32 = Release|Win32 - Release|x64 = Release|x64 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {E822DDAF-0F5F-4CD0-A694-38AE69DE74D3}.Debug|Win32.ActiveCfg = Debug|Win32 - {E822DDAF-0F5F-4CD0-A694-38AE69DE74D3}.Debug|Win32.Build.0 = Debug|Win32 - {E822DDAF-0F5F-4CD0-A694-38AE69DE74D3}.Debug|x64.ActiveCfg = Debug|Win32 - {E822DDAF-0F5F-4CD0-A694-38AE69DE74D3}.Release|Win32.ActiveCfg = Release|Win32 - {E822DDAF-0F5F-4CD0-A694-38AE69DE74D3}.Release|Win32.Build.0 = Release|Win32 - {E822DDAF-0F5F-4CD0-A694-38AE69DE74D3}.Release|x64.ActiveCfg = Release|Win32 - {824DA4CF-06F0-45C9-929A-8792F0E19C3E}.Debug|Win32.ActiveCfg = Debug|Win32 - {824DA4CF-06F0-45C9-929A-8792F0E19C3E}.Debug|Win32.Build.0 = Debug|Win32 - {824DA4CF-06F0-45C9-929A-8792F0E19C3E}.Debug|x64.ActiveCfg = Debug|Win32 - {824DA4CF-06F0-45C9-929A-8792F0E19C3E}.Release|Win32.ActiveCfg = Release|Win32 - {824DA4CF-06F0-45C9-929A-8792F0E19C3E}.Release|Win32.Build.0 = Release|Win32 - {824DA4CF-06F0-45C9-929A-8792F0E19C3E}.Release|x64.ActiveCfg = Release|Win32 - {39EC200D-7795-4FF8-B214-B24EDA5526AE}.Debug|Win32.ActiveCfg = Debug|Win32 - {39EC200D-7795-4FF8-B214-B24EDA5526AE}.Debug|Win32.Build.0 = Debug|Win32 - {39EC200D-7795-4FF8-B214-B24EDA5526AE}.Debug|x64.ActiveCfg = Debug|Win32 - {39EC200D-7795-4FF8-B214-B24EDA5526AE}.Release|Win32.ActiveCfg = Release|Win32 - {39EC200D-7795-4FF8-B214-B24EDA5526AE}.Release|Win32.Build.0 = Release|Win32 - {39EC200D-7795-4FF8-B214-B24EDA5526AE}.Release|x64.ActiveCfg = Release|Win32 - {718DE063-A18B-BB72-9150-62B892E6FFA6}.Debug|Win32.ActiveCfg = Debug|Win32 - {718DE063-A18B-BB72-9150-62B892E6FFA6}.Debug|Win32.Build.0 = Debug|Win32 - {718DE063-A18B-BB72-9150-62B892E6FFA6}.Debug|x64.ActiveCfg = Debug|Win32 - {718DE063-A18B-BB72-9150-62B892E6FFA6}.Release|Win32.ActiveCfg = Release|Win32 - {718DE063-A18B-BB72-9150-62B892E6FFA6}.Release|Win32.Build.0 = Release|Win32 - {718DE063-A18B-BB72-9150-62B892E6FFA6}.Release|x64.ActiveCfg = Release|Win32 - {2FA8F384-0775-F3B7-F8C3-85209222FC70}.Debug|Win32.ActiveCfg = Debug|Win32 - {2FA8F384-0775-F3B7-F8C3-85209222FC70}.Debug|Win32.Build.0 = Debug|Win32 - {2FA8F384-0775-F3B7-F8C3-85209222FC70}.Debug|x64.ActiveCfg = Debug|Win32 - {2FA8F384-0775-F3B7-F8C3-85209222FC70}.Release|Win32.ActiveCfg = Release|Win32 - {2FA8F384-0775-F3B7-F8C3-85209222FC70}.Release|Win32.Build.0 = Release|Win32 - {2FA8F384-0775-F3B7-F8C3-85209222FC70}.Release|x64.ActiveCfg = Release|Win32 - {54509728-928B-44D9-A118-A6F92F08B34F}.Debug|Win32.ActiveCfg = Debug|Win32 - {54509728-928B-44D9-A118-A6F92F08B34F}.Debug|Win32.Build.0 = Debug|Win32 - {54509728-928B-44D9-A118-A6F92F08B34F}.Debug|x64.ActiveCfg = Debug|Win32 - {54509728-928B-44D9-A118-A6F92F08B34F}.Release|Win32.ActiveCfg = Release|Win32 - {54509728-928B-44D9-A118-A6F92F08B34F}.Release|Win32.Build.0 = Release|Win32 - {54509728-928B-44D9-A118-A6F92F08B34F}.Release|x64.ActiveCfg = Release|Win32 - {E3DCBC31-7FC9-D127-E000-529F8460D5FD}.Debug|Win32.ActiveCfg = Debug|Win32 - {E3DCBC31-7FC9-D127-E000-529F8460D5FD}.Debug|Win32.Build.0 = Debug|Win32 - {E3DCBC31-7FC9-D127-E000-529F8460D5FD}.Debug|x64.ActiveCfg = Debug|Win32 - {E3DCBC31-7FC9-D127-E000-529F8460D5FD}.Release|Win32.ActiveCfg = Release|Win32 - {E3DCBC31-7FC9-D127-E000-529F8460D5FD}.Release|Win32.Build.0 = Release|Win32 - {E3DCBC31-7FC9-D127-E000-529F8460D5FD}.Release|x64.ActiveCfg = Release|Win32 - {B3FC9DFC-7268-8660-7C0D-B60BAF02C554}.Debug|Win32.ActiveCfg = Debug|Win32 - {B3FC9DFC-7268-8660-7C0D-B60BAF02C554}.Debug|Win32.Build.0 = Debug|Win32 - {B3FC9DFC-7268-8660-7C0D-B60BAF02C554}.Debug|x64.ActiveCfg = Debug|Win32 - {B3FC9DFC-7268-8660-7C0D-B60BAF02C554}.Release|Win32.ActiveCfg = Release|Win32 - {B3FC9DFC-7268-8660-7C0D-B60BAF02C554}.Release|Win32.Build.0 = Release|Win32 - {B3FC9DFC-7268-8660-7C0D-B60BAF02C554}.Release|x64.ActiveCfg = Release|Win32 - {12B4C8A5-1E06-4E30-B443-D1F916F52B47}.Debug|Win32.ActiveCfg = Debug|Win32 - {12B4C8A5-1E06-4E30-B443-D1F916F52B47}.Debug|Win32.Build.0 = Debug|Win32 - {12B4C8A5-1E06-4E30-B443-D1F916F52B47}.Debug|x64.ActiveCfg = Debug|Win32 - {12B4C8A5-1E06-4E30-B443-D1F916F52B47}.Release|Win32.ActiveCfg = Release|Win32 - {12B4C8A5-1E06-4E30-B443-D1F916F52B47}.Release|Win32.Build.0 = Release|Win32 - {12B4C8A5-1E06-4E30-B443-D1F916F52B47}.Release|x64.ActiveCfg = Release|Win32 - {95030B82-70CD-4C6B-84D4-61096035BEA2}.Debug|Win32.ActiveCfg = Debug|Win32 - {95030B82-70CD-4C6B-84D4-61096035BEA2}.Debug|Win32.Build.0 = Debug|Win32 - {95030B82-70CD-4C6B-84D4-61096035BEA2}.Debug|x64.ActiveCfg = Debug|Win32 - {95030B82-70CD-4C6B-84D4-61096035BEA2}.Release|Win32.ActiveCfg = Release|Win32 - {95030B82-70CD-4C6B-84D4-61096035BEA2}.Release|Win32.Build.0 = Release|Win32 - {95030B82-70CD-4C6B-84D4-61096035BEA2}.Release|x64.ActiveCfg = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {74E3E3B8-3E51-4003-816B-8ED3057AAC21} - EndGlobalSection -EndGlobal +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.28307.902 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lib_dec", "lib_dec.vcxproj", "{E822DDAF-0F5F-4CD0-A694-38AE69DE74D3}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lib_enc", "lib_enc.vcxproj", "{824DA4CF-06F0-45C9-929A-8792F0E19C3E}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lib_com", "lib_com.vcxproj", "{39EC200D-7795-4FF8-B214-B24EDA5526AE}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lib_rend", "lib_rend.vcxproj", "{718DE063-A18B-BB72-9150-62B892E6FFA6}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lib_util", "lib_util.vcxproj", "{2FA8F384-0775-F3B7-F8C3-85209222FC70}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lib_debug", "lib_debug.vcxproj", "{54509728-928B-44D9-A118-A6F92F08B34F}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "decoder", "decoder.vcxproj", "{E3DCBC31-7FC9-D127-E000-529F8460D5FD}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "encoder", "encoder.vcxproj", "{B3FC9DFC-7268-8660-7C0D-B60BAF02C554}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "renderer", "renderer.vcxproj", "{12B4C8A5-1E06-4E30-B443-D1F916F52B47}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LC3plus", "lib_lc3plus.vcxproj", "{95030B82-70CD-4C6B-84D4-61096035BEA2}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{51160D4C-55C9-4C16-A792-D94507225746}" + ProjectSection(SolutionItems) = preProject + ..\.clang-format = ..\.clang-format + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {E822DDAF-0F5F-4CD0-A694-38AE69DE74D3}.Debug|Win32.ActiveCfg = Debug|Win32 + {E822DDAF-0F5F-4CD0-A694-38AE69DE74D3}.Debug|Win32.Build.0 = Debug|Win32 + {E822DDAF-0F5F-4CD0-A694-38AE69DE74D3}.Debug|x64.ActiveCfg = Debug|Win32 + {E822DDAF-0F5F-4CD0-A694-38AE69DE74D3}.Release|Win32.ActiveCfg = Release|Win32 + {E822DDAF-0F5F-4CD0-A694-38AE69DE74D3}.Release|Win32.Build.0 = Release|Win32 + {E822DDAF-0F5F-4CD0-A694-38AE69DE74D3}.Release|x64.ActiveCfg = Release|Win32 + {824DA4CF-06F0-45C9-929A-8792F0E19C3E}.Debug|Win32.ActiveCfg = Debug|Win32 + {824DA4CF-06F0-45C9-929A-8792F0E19C3E}.Debug|Win32.Build.0 = Debug|Win32 + {824DA4CF-06F0-45C9-929A-8792F0E19C3E}.Debug|x64.ActiveCfg = Debug|Win32 + {824DA4CF-06F0-45C9-929A-8792F0E19C3E}.Release|Win32.ActiveCfg = Release|Win32 + {824DA4CF-06F0-45C9-929A-8792F0E19C3E}.Release|Win32.Build.0 = Release|Win32 + {824DA4CF-06F0-45C9-929A-8792F0E19C3E}.Release|x64.ActiveCfg = Release|Win32 + {39EC200D-7795-4FF8-B214-B24EDA5526AE}.Debug|Win32.ActiveCfg = Debug|Win32 + {39EC200D-7795-4FF8-B214-B24EDA5526AE}.Debug|Win32.Build.0 = Debug|Win32 + {39EC200D-7795-4FF8-B214-B24EDA5526AE}.Debug|x64.ActiveCfg = Debug|Win32 + {39EC200D-7795-4FF8-B214-B24EDA5526AE}.Release|Win32.ActiveCfg = Release|Win32 + {39EC200D-7795-4FF8-B214-B24EDA5526AE}.Release|Win32.Build.0 = Release|Win32 + {39EC200D-7795-4FF8-B214-B24EDA5526AE}.Release|x64.ActiveCfg = Release|Win32 + {718DE063-A18B-BB72-9150-62B892E6FFA6}.Debug|Win32.ActiveCfg = Debug|Win32 + {718DE063-A18B-BB72-9150-62B892E6FFA6}.Debug|Win32.Build.0 = Debug|Win32 + {718DE063-A18B-BB72-9150-62B892E6FFA6}.Debug|x64.ActiveCfg = Debug|Win32 + {718DE063-A18B-BB72-9150-62B892E6FFA6}.Release|Win32.ActiveCfg = Release|Win32 + {718DE063-A18B-BB72-9150-62B892E6FFA6}.Release|Win32.Build.0 = Release|Win32 + {718DE063-A18B-BB72-9150-62B892E6FFA6}.Release|x64.ActiveCfg = Release|Win32 + {2FA8F384-0775-F3B7-F8C3-85209222FC70}.Debug|Win32.ActiveCfg = Debug|Win32 + {2FA8F384-0775-F3B7-F8C3-85209222FC70}.Debug|Win32.Build.0 = Debug|Win32 + {2FA8F384-0775-F3B7-F8C3-85209222FC70}.Debug|x64.ActiveCfg = Debug|Win32 + {2FA8F384-0775-F3B7-F8C3-85209222FC70}.Release|Win32.ActiveCfg = Release|Win32 + {2FA8F384-0775-F3B7-F8C3-85209222FC70}.Release|Win32.Build.0 = Release|Win32 + {2FA8F384-0775-F3B7-F8C3-85209222FC70}.Release|x64.ActiveCfg = Release|Win32 + {54509728-928B-44D9-A118-A6F92F08B34F}.Debug|Win32.ActiveCfg = Debug|Win32 + {54509728-928B-44D9-A118-A6F92F08B34F}.Debug|Win32.Build.0 = Debug|Win32 + {54509728-928B-44D9-A118-A6F92F08B34F}.Debug|x64.ActiveCfg = Debug|Win32 + {54509728-928B-44D9-A118-A6F92F08B34F}.Release|Win32.ActiveCfg = Release|Win32 + {54509728-928B-44D9-A118-A6F92F08B34F}.Release|Win32.Build.0 = Release|Win32 + {54509728-928B-44D9-A118-A6F92F08B34F}.Release|x64.ActiveCfg = Release|Win32 + {E3DCBC31-7FC9-D127-E000-529F8460D5FD}.Debug|Win32.ActiveCfg = Debug|Win32 + {E3DCBC31-7FC9-D127-E000-529F8460D5FD}.Debug|Win32.Build.0 = Debug|Win32 + {E3DCBC31-7FC9-D127-E000-529F8460D5FD}.Debug|x64.ActiveCfg = Debug|Win32 + {E3DCBC31-7FC9-D127-E000-529F8460D5FD}.Release|Win32.ActiveCfg = Release|Win32 + {E3DCBC31-7FC9-D127-E000-529F8460D5FD}.Release|Win32.Build.0 = Release|Win32 + {E3DCBC31-7FC9-D127-E000-529F8460D5FD}.Release|x64.ActiveCfg = Release|Win32 + {B3FC9DFC-7268-8660-7C0D-B60BAF02C554}.Debug|Win32.ActiveCfg = Debug|Win32 + {B3FC9DFC-7268-8660-7C0D-B60BAF02C554}.Debug|Win32.Build.0 = Debug|Win32 + {B3FC9DFC-7268-8660-7C0D-B60BAF02C554}.Debug|x64.ActiveCfg = Debug|Win32 + {B3FC9DFC-7268-8660-7C0D-B60BAF02C554}.Release|Win32.ActiveCfg = Release|Win32 + {B3FC9DFC-7268-8660-7C0D-B60BAF02C554}.Release|Win32.Build.0 = Release|Win32 + {B3FC9DFC-7268-8660-7C0D-B60BAF02C554}.Release|x64.ActiveCfg = Release|Win32 + {12B4C8A5-1E06-4E30-B443-D1F916F52B47}.Debug|Win32.ActiveCfg = Debug|Win32 + {12B4C8A5-1E06-4E30-B443-D1F916F52B47}.Debug|Win32.Build.0 = Debug|Win32 + {12B4C8A5-1E06-4E30-B443-D1F916F52B47}.Debug|x64.ActiveCfg = Debug|Win32 + {12B4C8A5-1E06-4E30-B443-D1F916F52B47}.Release|Win32.ActiveCfg = Release|Win32 + {12B4C8A5-1E06-4E30-B443-D1F916F52B47}.Release|Win32.Build.0 = Release|Win32 + {12B4C8A5-1E06-4E30-B443-D1F916F52B47}.Release|x64.ActiveCfg = Release|Win32 + {95030B82-70CD-4C6B-84D4-61096035BEA2}.Debug|Win32.ActiveCfg = Debug|Win32 + {95030B82-70CD-4C6B-84D4-61096035BEA2}.Debug|Win32.Build.0 = Debug|Win32 + {95030B82-70CD-4C6B-84D4-61096035BEA2}.Debug|x64.ActiveCfg = Debug|Win32 + {95030B82-70CD-4C6B-84D4-61096035BEA2}.Release|Win32.ActiveCfg = Release|Win32 + {95030B82-70CD-4C6B-84D4-61096035BEA2}.Release|Win32.Build.0 = Release|Win32 + {95030B82-70CD-4C6B-84D4-61096035BEA2}.Release|x64.ActiveCfg = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {74E3E3B8-3E51-4003-816B-8ED3057AAC21} + EndGlobalSection +EndGlobal -- GitLab From 1f535caead73622ad1390257021ee6e8e5c27d70 Mon Sep 17 00:00:00 2001 From: Erik Norvell Date: Fri, 20 Dec 2024 15:39:41 +0100 Subject: [PATCH 05/33] Add missing updates for Makefile --- Makefile | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/Makefile b/Makefile index f72577249..9ebcb7aa9 100644 --- a/Makefile +++ b/Makefile @@ -134,12 +134,7 @@ SRCS_LIBDEC = $(foreach DIR,$(SRC_LIBDEC),$(patsubst $(DIR)/%,%,$(wildcard $(D SRCS_LIBENC = $(foreach DIR,$(SRC_LIBENC),$(patsubst $(DIR)/%,%,$(wildcard $(DIR)/*.c))) SRCS_LIBREND = $(foreach DIR,$(SRC_LIBREND),$(patsubst $(DIR)/%,%,$(wildcard $(DIR)/*.c))) SRCS_LIBUTIL = $(foreach DIR,$(SRC_LIBUTIL),$(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)) @@ -180,11 +175,7 @@ $(LIB_LIBREND): $(OBJS_LIBREND) $(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 $@ $^ @@ -193,18 +184,10 @@ $(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) -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) -ifeq "$(INCLUDE_SPLIT)" "1" $(QUIET_LINK)$(CC) $(LDFLAGS) $(OBJS_CLI_APPREND) -L. -livasrend -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 libs: $(LIB_LIBENC) $(LIB_LIBDEBUG) $(LIB_LIBCOM) $(LIB_LIBDEC) $(LIB_LIBREND) $(LIB_LC3PLUS) $(LIB_LIBUTIL) -- GitLab From e86f14b5df507b977a3155c0484db963f6b9ce13 Mon Sep 17 00:00:00 2001 From: Erik Norvell Date: Fri, 20 Dec 2024 17:16:01 +0100 Subject: [PATCH 06/33] Add missing updates to apps/renderer.c --- apps/renderer.c | 651 ++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 573 insertions(+), 78 deletions(-) diff --git a/apps/renderer.c b/apps/renderer.c index d289e85d8..bfcd10f8a 100644 --- a/apps/renderer.c +++ b/apps/renderer.c @@ -45,6 +45,8 @@ #include "masa_file_writer.h" #include "render_config_reader.h" #include "rotation_file_reader.h" +#include "split_render_file_read_write.h" +#include "split_rend_bfi_file_reader.h" #include "vector3_pair_file_reader.h" #ifdef DEBUGGING #include "debug.h" @@ -62,6 +64,7 @@ #define RENDERER_MAX_METADATA_LENGTH 8192 #define RENDERER_MAX_METADATA_LINE_LENGTH 1024 +#define SPLIT_REND_BITS_BUFF_SIZE ( ( ( ( (int32_t) IVAS_MAX_SPLIT_REND_BITRATE / IVAS_NUM_FRAMES_PER_SEC ) + 7 ) >> 3 ) + IVAS_SPLIT_REND_ADDITIONAL_BYTES_TO_READ ) #define IVAS_MAX16B_FLT 32767.0f #define IVAS_MIN16B_FLT ( -32768.0f ) @@ -131,6 +134,8 @@ typedef struct IVAS_CUSTOM_LS_DATA inSetupCustom; RendererInput masaBuses[RENDERER_MAX_MASA_INPUTS]; uint16_t numMasaBuses; + RendererInput binBuses[RENDERER_MAX_BIN_INPUTS]; + uint16_t numBinBuses; } InputConfig; typedef struct @@ -149,7 +154,9 @@ typedef struct OutputConfig outConfig; char inMetadataFilePaths[RENDERER_MAX_ISM_INPUTS][RENDERER_MAX_CLI_ARG_LENGTH]; int16_t numInMetadataFiles; + char outMetadataFilePath[RENDERER_MAX_CLI_ARG_LENGTH]; char headRotationFilePath[RENDERER_MAX_CLI_ARG_LENGTH]; + char splitRendBFIFilePath[RENDERER_MAX_CLI_ARG_LENGTH]; char referenceVectorFilePath[RENDERER_MAX_CLI_ARG_LENGTH]; char referenceRotationFilePath[RENDERER_MAX_CLI_ARG_LENGTH]; char externalOrientationFilePath[RENDERER_MAX_CLI_ARG_LENGTH]; @@ -196,6 +203,8 @@ typedef enum CmdLnOptionId_inputMetadata, CmdLnOptionId_listFormats, CmdLnOptionId_inputGain, + CmdLnOptionId_outputMetadata, + CmdLnOptionId_SplitRendBFIFile, CmdLnOptionId_referenceVectorFile, CmdLnOptionId_exteriorOrientationFile, CmdLnOptionId_framing, @@ -221,7 +230,7 @@ static const CmdLnParser_Option cliOptions[] = { .id = CmdLnOptionId_inputMetadata, .match = "input_metadata", .matchShort = "im", - .description = "Space-separated list of path to metadata files for ISM or MASA inputs", + .description = "Space-separated list of path to metadata files for ISM or MASA inputs or BINAURAL_SPLIT_PCM input mode", }, { .id = CmdLnOptionId_outputFile, @@ -247,6 +256,18 @@ static const CmdLnParser_Option cliOptions[] = { .matchShort = "T", .description = "Head rotation trajectory file for simulation of head tracking (only for binaural outputs)", }, + { + .id = CmdLnOptionId_outputMetadata, + .match = "output_metadata", + .matchShort = "om", + .description = "coded metadata file for BINAURAL_SPLIT_PCM output mode", + }, + { + .id = CmdLnOptionId_SplitRendBFIFile, + .match = "post_rend_bfi_file", + .matchShort = "prbfi", + .description = "Split rendering option: bfi file", + }, { .id = CmdLnOptionId_refRotFile, .match = "reference_rotation_file", @@ -404,9 +425,9 @@ static void printSupportedAudioConfigs( void ); static IVAS_AUDIO_CONFIG parseAudioConfig( const char *configString ); -static void convertInputBuffer( const int16_t *intBuffer, const int16_t numIntSamplesPerChannel, const int16_t numFloatSamplesPerChannel, const int16_t numChannels, float *floatBuffer ); +static void convertInputBuffer( const int16_t *intBuffer, const int16_t numIntSamplesPerChannel, const int16_t numFloatSamplesPerChannel, const int16_t numChannels, float *floatBuffer, const int16_t cldfb_in, IVAS_CLDFB_FILTER_BANK_HANDLE *cldfbAna ); -static void convertOutputBuffer( const float *floatBuffer, const int16_t numSamplesPerChannel, const int16_t numChannels, int16_t *intBuffer ); +static void convertOutputBuffer( const float *floatBuffer, const int16_t numSamplesPerChannel, const int16_t numChannels, int16_t *intBuffer, const int16_t cldfb_in, IVAS_CLDFB_FILTER_BANK_HANDLE *cldfbSyn ); /*------------------------------------------------------------------------------------------* @@ -433,7 +454,9 @@ static int16_t getTotalNumInChannels( IVAS_REND_InputId mcIds[RENDERER_MAX_MC_INPUTS], IVAS_REND_InputId ismIds[RENDERER_MAX_ISM_INPUTS], IVAS_REND_InputId sbaIds[RENDERER_MAX_SBA_INPUTS], - IVAS_REND_InputId masaIds[RENDERER_MAX_MASA_INPUTS] ) + IVAS_REND_InputId masaIds[RENDERER_MAX_MASA_INPUTS], + IVAS_REND_InputId splitBinIds[RENDERER_MAX_BIN_INPUTS] +) { int16_t totalNumInChannels = 0; int16_t i, numInputChannels; @@ -510,6 +533,21 @@ static int16_t getTotalNumInChannels( totalNumInChannels += numInputChannels; } + for ( i = 0; i < RENDERER_MAX_BIN_INPUTS; ++i ) + { + if ( splitBinIds[i] == 0 ) + { + /* Skip inactive inputs */ + continue; + } + + if ( ( error = IVAS_REND_GetInputNumChannels( hIvasRend, splitBinIds[i], &numInputChannels ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + totalNumInChannels += numInputChannels; + } return totalNumInChannels; } @@ -519,7 +557,9 @@ static void setupWithSingleFormatInput( CmdlnArgs args, char *audioFilePath, IsmPositionProvider *positionProvider, - MasaFileReader **masaReaders ) + MasaFileReader **masaReaders, + SplitFileReadWrite **hhSplitRendFileReadWrite +) { /* With single-format input, inputFilePath is the path to input audio file. */ strncpy( audioFilePath, args.inputFilePath, FILENAME_MAX - 1 ); @@ -566,6 +606,20 @@ static void setupWithSingleFormatInput( } } } + else if ( args.inConfig.numBinBuses != 0 ) + { + *hhSplitRendFileReadWrite = NULL; + if ( args.inConfig.binBuses[0].audioConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { + ivas_error error; + error = split_rend_reader_open( hhSplitRendFileReadWrite, args.inMetadataFilePaths[0] ); + if ( error != IVAS_ERR_OK ) + { + fprintf( stderr, "Could not open split rend metadata file %s\n", args.inMetadataFilePaths[0] ); + exit( -1 ); + } + } + } return; } @@ -578,6 +632,57 @@ static float dBToLin( } +static int16_t get_cldfb_in_flag( + const IVAS_AUDIO_CONFIG audioConfig, + IVAS_RENDER_CONFIG_DATA *renderConfig ) +{ + int16_t cldfb_in_flag; + + cldfb_in_flag = 0; + if ( renderConfig->split_rend_config.rendererSelection == IVAS_SPLIT_REND_RENDERER_SELECTION_FASTCONV ) + { +#ifdef DEBUGGING + cldfb_in_flag = 1; +#endif + if ( audioConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) + { + cldfb_in_flag = 1; + } + } + + return cldfb_in_flag; +} + + +static int16_t is_split_post_rend_mode( + CmdlnArgs *args ) +{ + int16_t flag; + + flag = 0; + if ( args->inConfig.numBinBuses > 0 && ( args->inConfig.binBuses[0].audioConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || args->inConfig.binBuses[0].audioConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) + { + flag = 1; + } + + return flag; +} + +static int16_t is_split_pre_rend_mode( + CmdlnArgs *args ) +{ + int16_t flag; + + flag = 0; + if ( args->outConfig.audioConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || args->outConfig.audioConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { + flag = 1; + } + + return flag; +} + + /*------------------------------------------------------------------------------------------* * main() * @@ -592,6 +697,10 @@ int main( RotFileReader *headRotReader = NULL; RotFileReader *externalOrientationFileReader = NULL; RotFileReader *referenceRotReader = NULL; + IVAS_CLDFB_FILTER_BANK_HANDLE cldfbAna[IVAS_MAX_INPUT_CHANNELS]; + IVAS_CLDFB_FILTER_BANK_HANDLE cldfbSyn[IVAS_MAX_INPUT_CHANNELS]; + int16_t cldfb_in_flag, CLDFBframeSize_smpls; + SplitRendBFIFileReader *splitRendBFIReader = NULL; Vector3PairFileReader *referenceVectorReader = NULL; hrtfFileReader *hrtfFileReader = NULL; IsmPositionProvider *positionProvider; @@ -605,12 +714,18 @@ int main( AudioFileWriter *audioWriter; int32_t inBufferSize; int32_t outBufferSize; + int32_t bitsBufferSize; int16_t *inpInt16Buffer; float *inFloatBuffer; int16_t *outInt16Buffer; float *outFloatBuffer; + uint8_t *bitsBufferData; IVAS_REND_AudioBuffer inBuffer; IVAS_REND_AudioBuffer outBuffer; + IVAS_REND_BitstreamBuffer bitsBuffer; + SplitFileReadWrite *hSplitRendFileReadWrite; + int16_t delayNumSamples_temp; + int32_t delayTimeScale_temp; int16_t numSamplesRead; int16_t delayNumSamples = -1; int16_t delayNumSamples_orig = 0; @@ -632,6 +747,7 @@ int main( hMasaMetadata[i] = NULL; } + hSplitRendFileReadWrite = NULL; for ( i = 0; i < RENDERER_MAX_MC_INPUTS; ++i ) { lfeRoutingConfigs[i] = NULL; @@ -688,6 +804,11 @@ int main( } } + if ( !isEmptyString( args.splitRendBFIFilePath ) ) + { + convert_backslash( args.splitRendBFIFilePath ); + SplitRendBFIFileReader_open( args.splitRendBFIFilePath, &splitRendBFIReader ); + } if ( !isEmptyString( args.externalOrientationFilePath ) ) { if ( RotationFileReader_open( args.externalOrientationFilePath, &externalOrientationFileReader ) != IVAS_ERR_OK ) @@ -724,7 +845,7 @@ int main( else { /* With single-format input, all information is given on command line. */ - setupWithSingleFormatInput( args, audioFilePath, positionProvider, masaReaders ); + setupWithSingleFormatInput( args, audioFilePath, positionProvider, masaReaders, &hSplitRendFileReadWrite ); } /* Check that there is allowed configuration for MASA format output */ @@ -745,14 +866,35 @@ int main( } } - if ( AudioFileReader_open( &audioReader, audioFilePath ) != IVAS_ERR_OK ) + /*if split renderer is running in post renderer mode*/ + if ( ( args.inConfig.numBinBuses > 0 ) && ( args.inConfig.binBuses[0].audioConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) ) { - fprintf( stderr, "Error opening file: %s\n", audioFilePath ); - exit( -1 ); + error = split_rend_reader_open( &hSplitRendFileReadWrite, args.inputFilePath ); + if ( error != IVAS_ERR_OK ) + { + fprintf( stderr, "Could not open split rend metadata file %s\n", args.inputFilePath ); + exit( -1 ); + } + audioReader = NULL; + } + else + { + if ( AudioFileReader_open( &audioReader, audioFilePath ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error opening file: %s\n", audioFilePath ); + exit( -1 ); + } } int32_t inFileSampleRate = 0; - error = AudioFileReader_getSamplingRate( audioReader, &inFileSampleRate ); + if ( audioReader != NULL ) + { + error = AudioFileReader_getSamplingRate( audioReader, &inFileSampleRate ); + } + else + { + inFileSampleRate = args.sampleRate; + } switch ( error ) { @@ -782,11 +924,14 @@ int main( } int16_t inFileNumChannels = 0; - error = AudioFileReader_getNumChannels( audioReader, &inFileNumChannels ); - if ( error != IVAS_ERR_OK && error != IVAS_ERR_NUM_CHANNELS_UNKNOWN ) + if ( audioReader != NULL ) { - fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); - exit( -1 ); + error = AudioFileReader_getNumChannels( audioReader, &inFileNumChannels ); + if ( error != IVAS_ERR_OK && error != IVAS_ERR_NUM_CHANNELS_UNKNOWN ) + { + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } } const int16_t frameSize_smpls = (int16_t) ( ( args.render_framesize ) * args.sampleRate * 5 / ( 1000 ) ); @@ -803,22 +948,24 @@ int main( exit( -1 ); } + CLDFBframeSize_smpls = 0; + cldfb_in_flag = 0; if ( args.renderConfigFilePath[0] != '\0' ) { IVAS_RENDER_CONFIG_DATA renderConfig; /* sanity check */ - if ( ( args.outConfig.audioConfig != IVAS_AUDIO_CONFIG_BINAURAL ) && ( args.outConfig.audioConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) && ( args.outConfig.audioConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ) + if ( ( args.outConfig.audioConfig != IVAS_AUDIO_CONFIG_BINAURAL ) && ( args.outConfig.audioConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) && ( args.outConfig.audioConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) && !is_split_pre_rend_mode( &args ) ) { - fprintf( stderr, "\nExternal Renderer Config is only supported for binaural output configurations. Exiting. \n" ); + fprintf( stderr, "\nExternal Renderer Config is supported only when binaural output configurations is used as output OR when Split pre-rendering mode is enabled. Exiting. \n" ); exit( -1 ); } if ( ( error = IVAS_REND_GetRenderConfig( hIvasRend, &renderConfig ) ) != IVAS_ERR_OK ) { - fprintf( stderr, "\nIVAS_DEC_GetRenderConfig failed\n" ); + fprintf( stderr, "\nIVAS_DEC_GetRenderConfig failed: %s\n", ivas_error_to_string( error ) ); exit( -1 ); } @@ -848,9 +995,15 @@ int main( if ( ( error = IVAS_REND_FeedRenderConfig( hIvasRend, renderConfig ) ) != IVAS_ERR_OK ) { - fprintf( stderr, "\nIVAS_DEC_FeedRenderConfig failed\n" ); + fprintf( stderr, "\nIVAS_REND_FeedRenderConfig failed: %s\n", ivas_error_to_string( error ) ); exit( -1 ); } + + if ( !is_split_post_rend_mode( &args ) ) + { + CLDFBframeSize_smpls = frameSize_smpls * 2; + cldfb_in_flag = get_cldfb_in_flag( args.outConfig.audioConfig, &renderConfig ); + } } if ( ( error = IVAS_REND_SetOrientationTrackingMode( hIvasRend, args.orientation_tracking ) ) != IVAS_ERR_OK ) @@ -912,6 +1065,7 @@ int main( IVAS_REND_InputId ismIds[RENDERER_MAX_ISM_INPUTS]; IVAS_REND_InputId sbaIds[RENDERER_MAX_SBA_INPUTS]; IVAS_REND_InputId masaIds[RENDERER_MAX_MASA_INPUTS]; + IVAS_REND_InputId splitBinIds[RENDERER_MAX_BIN_INPUTS]; for ( i = 0; i < RENDERER_MAX_MC_INPUTS; i++ ) { @@ -929,6 +1083,10 @@ int main( { masaIds[i] = 0u; } + for ( i = 0; i < RENDERER_MAX_BIN_INPUTS; i++ ) + { + splitBinIds[i] = 0u; + } for ( i = 0; i < args.inConfig.numMultiChannelBuses; ++i ) { @@ -1046,6 +1204,20 @@ int main( } } + for ( i = 0; i < args.inConfig.numBinBuses; ++i ) + { + if ( ( error = IVAS_REND_AddInput( hIvasRend, args.inConfig.binBuses[i].audioConfig, &splitBinIds[i] ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + + if ( ( error = IVAS_REND_SetInputGain( hIvasRend, splitBinIds[i], args.inputGainGlobal * dBToLin( args.inConfig.binBuses[i].gain_dB ) ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + } for ( i = 0; i < args.inConfig.numMasaBuses; ++i ) { @@ -1062,7 +1234,7 @@ int main( } } - const int16_t totalNumInChannels = getTotalNumInChannels( hIvasRend, mcIds, ismIds, sbaIds, masaIds ); + const int16_t totalNumInChannels = getTotalNumInChannels( hIvasRend, mcIds, ismIds, sbaIds, masaIds, splitBinIds ); if ( inFileNumChannels != 0 /* inFileNumChannels is 0 with raw PCM input */ && totalNumInChannels != inFileNumChannels ) { @@ -1085,29 +1257,110 @@ int main( exit( -1 ); } + if ( cldfb_in_flag ) + { + if ( ( error = IVAS_REND_openCldfb( cldfbAna, cldfbSyn, totalNumInChannels, numOutChannels, args.sampleRate ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error in IVAS_REND_openCldfb(): %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + } + + if ( args.outConfig.audioConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) + { + if ( IVAS_REND_GetDelay( hIvasRend, &delayNumSamples_temp, &delayTimeScale_temp ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nUnable to get delay of renderer!\n" ); + exit( -1 ); + } - if ( AudioFileWriter_open( &audioWriter, args.outputFilePath, args.sampleRate, numOutChannels ) != IVAS_ERR_OK ) + if ( ( error = split_rend_writer_open( &hSplitRendFileReadWrite, args.outputFilePath, delayNumSamples_temp, delayTimeScale_temp ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Could not open split rend metadata file %s\n", args.outputFilePath ); + exit( -1 ); + } + audioWriter = NULL; + } + else { - fprintf( stderr, "Failed to open file: %s\n", args.outputFilePath ); - exit( -1 ); + if ( args.outConfig.audioConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { + if ( IVAS_REND_GetDelay( hIvasRend, &delayNumSamples_temp, &delayTimeScale_temp ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nUnable to get delay of renderer!\n" ); + exit( -1 ); + } + + if ( ( error = split_rend_writer_open( &hSplitRendFileReadWrite, args.outMetadataFilePath, delayNumSamples_temp, delayTimeScale_temp ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Could not open split rend metadata file %s\n", args.outMetadataFilePath ); + exit( -1 ); + } + } + + if ( AudioFileWriter_open( &audioWriter, args.outputFilePath, args.sampleRate, numOutChannels ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Failed to open file: %s\n", args.outputFilePath ); + exit( -1 ); + } } inBufferSize = frameSize_smpls * totalNumInChannels; outBufferSize = frameSize_smpls * numOutChannels; inpInt16Buffer = malloc( inBufferSize * sizeof( int16_t ) ); - inFloatBuffer = malloc( inBufferSize * sizeof( float ) ); + if ( cldfb_in_flag == 0 ) + { + inFloatBuffer = malloc( inBufferSize * sizeof( float ) ); + inBuffer.config.numSamplesPerChannel = (int16_t) frameSize_smpls; + outFloatBuffer = malloc( outBufferSize * sizeof( float ) ); + outBuffer.config.numSamplesPerChannel = (int16_t) frameSize_smpls; + } + else + { + inFloatBuffer = malloc( CLDFBframeSize_smpls * totalNumInChannels * sizeof( float ) ); + inBuffer.config.numSamplesPerChannel = (int16_t) CLDFBframeSize_smpls; + outFloatBuffer = malloc( CLDFBframeSize_smpls * totalNumInChannels * sizeof( float ) ); + outBuffer.config.numSamplesPerChannel = (int16_t) CLDFBframeSize_smpls; + } outInt16Buffer = malloc( outBufferSize * sizeof( int16_t ) ); - outFloatBuffer = malloc( outBufferSize * sizeof( float ) ); - inBuffer.config.numSamplesPerChannel = (int16_t) frameSize_smpls; + inBuffer.config.is_cldfb = cldfb_in_flag; inBuffer.config.numChannels = (int16_t) totalNumInChannels; inBuffer.data = inFloatBuffer; - outBuffer.config.numSamplesPerChannel = (int16_t) frameSize_smpls; + outBuffer.config.is_cldfb = cldfb_in_flag; outBuffer.config.numChannels = (int16_t) numOutChannels; outBuffer.data = outFloatBuffer; + memset( outBuffer.data, 0, outBuffer.config.numSamplesPerChannel * outBuffer.config.numChannels * sizeof( float ) ); + + if ( is_split_pre_rend_mode( &args ) || is_split_post_rend_mode( &args ) ) + { + bitsBufferSize = SPLIT_REND_BITS_BUFF_SIZE; + } + else + { + bitsBufferSize = 0; + } + + if ( bitsBufferSize > 0 ) + { + bitsBufferData = malloc( bitsBufferSize * sizeof( uint8_t ) ); + } + else + { + bitsBufferData = NULL; + } + + bitsBuffer.bits = bitsBufferData; + bitsBuffer.config.bitsRead = 0; + bitsBuffer.config.bitsWritten = 0; + bitsBuffer.config.bufLenInBytes = bitsBufferSize; + bitsBuffer.config.codec = IVAS_SPLIT_REND_CODEC_DEFAULT; + bitsBuffer.config.poseCorrection = IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE; + bitsBuffer.config.codec_frame_size_ms = 20; + #ifdef WMOPS reset_stack(); reset_wmops(); @@ -1131,11 +1384,36 @@ int main( num_in_channels = inBuffer.config.numChannels; const bool isCurrentFrameMultipleOf20ms = frame % ( 4 / args.render_framesize ) == 0; - /* Read the input data */ - if ( ( error = AudioFileReader_read( audioReader, inpInt16Buffer, (int16_t) inBufferSize, &numSamplesRead ) ) != IVAS_ERR_OK ) + numSamplesRead = 0; + if ( ( hSplitRendFileReadWrite != NULL ) && is_split_post_rend_mode( &args ) && splitBinNeedsNewFrame ) { - fprintf( stderr, "\nError reading from file %s\n", audioFilePath ); - exit( -1 ); + ivas_error error_tmp; + numSamplesRead = (int16_t) inBufferSize; + error_tmp = split_rend_read_bits_from_file( hSplitRendFileReadWrite, bitsBuffer.bits, &bitsBuffer.config.bitsRead, &bitsBuffer.config.bitsWritten, + &bitsBuffer.config.codec, &bitsBuffer.config.poseCorrection, + &bitsBuffer.config.codec_frame_size_ms ); + if ( error_tmp != IVAS_ERR_OK ) + { + if ( error_tmp == IVAS_ERR_END_OF_FILE ) + { + numSamplesRead = 0; + } + else + { + fprintf( stderr, "\nUnable to read from bitstream file!\n" ); + exit( -1 ); + } + } + } + + if ( audioReader != NULL ) + { + /* Read the input data */ + if ( ( error = AudioFileReader_read( audioReader, inpInt16Buffer, (int16_t) inBufferSize, &numSamplesRead ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError reading from file %s\n", audioFilePath ); + exit( -1 ); + } } if ( numSamplesRead == 0 && splitBinNeedsNewFrame ) @@ -1145,7 +1423,7 @@ 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, inBuffer.config.is_cldfb, cldfbAna ); int16_t num_subframes, sf_idx; num_subframes = (int16_t) args.render_framesize; @@ -1203,11 +1481,7 @@ int main( exit( -1 ); } -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( ( error = IVAS_REND_SetHeadRotation( hIvasRend, headRot, Pos, DEFAULT_AXIS, sf_idx ) ) != IVAS_ERR_OK ) -#else - if ( ( error = IVAS_REND_SetHeadRotation( hIvasRend, headRot, Pos, sf_idx ) ) != IVAS_ERR_OK ) -#endif { fprintf( stderr, "Error setting Head Rotation: %s\n", ivas_error_to_string( error ) ); exit( -1 ); @@ -1223,6 +1497,22 @@ int main( } } + /* Read from split renderer bfi file if specified */ + if ( splitRendBFIReader != NULL && splitBinNeedsNewFrame ) + { + int16_t bfi; + if ( ( error = SplitRendBFIFileReading( splitRendBFIReader, &bfi ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error in SplitRendBFIFileReading(): %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + + if ( ( error = IVAS_REND_SetSplitRendBFI( hIvasRend, bfi ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error in IVAS_REND_SetSplitRendBFI(): %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + } /* Read from external orientation file if specified */ if ( externalOrientationFileReader != NULL ) @@ -1365,10 +1655,54 @@ int main( } - if ( ( error = IVAS_REND_GetSamples( hIvasRend, outBuffer ) ) != IVAS_ERR_OK ) + for ( i = 0; i < args.inConfig.numBinBuses; ++i ) { - fprintf( stderr, "Error in getting samples\n" ); - exit( -1 ); + if ( splitBinNeedsNewFrame ) + { + if ( ( error = IVAS_REND_GetInputNumChannels( hIvasRend, splitBinIds[i], &numChannels ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + IVAS_REND_ReadOnlyAudioBuffer tmpBuffer = getReadOnlySubBuffer( inBuffer, (int16_t) args.inConfig.binBuses[i].inputChannelIndex, numChannels ); + + if ( ( error = IVAS_REND_FeedInputAudio( hIvasRend, splitBinIds[i], tmpBuffer ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + + if ( ( error = IVAS_REND_FeedSplitBinauralBitstream( hIvasRend, splitBinIds[i], &bitsBuffer ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + } + } + + if ( args.inConfig.numBinBuses != 0 ) + { + if ( ( error = IVAS_REND_GetSplitBinauralSamples( hIvasRend, outBuffer, &splitBinNeedsNewFrame ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + } + else if ( args.outConfig.audioConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || args.outConfig.audioConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { + if ( ( error = IVAS_REND_GetSplitBinauralBitstream( hIvasRend, outBuffer, &bitsBuffer ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + } + else + { + if ( ( error = IVAS_REND_GetSamples( hIvasRend, outBuffer ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } } int16_t num_out_channels; @@ -1376,11 +1710,11 @@ 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, outBuffer.config.numSamplesPerChannel, num_out_channels, outInt16Buffer, cldfb_in_flag, cldfbSyn ); if ( delayNumSamples == -1 ) { - if ( args.delayCompensationEnabled ) + if ( args.delayCompensationEnabled && !is_split_pre_rend_mode( &args ) ) { if ( IVAS_REND_GetDelay( hIvasRend, &delayNumSamples, &delayTimeScale ) != IVAS_ERR_OK ) { @@ -1388,6 +1722,12 @@ int main( exit( -1 ); } + if ( is_split_post_rend_mode( &args ) && ( hSplitRendFileReadWrite != NULL ) ) + { + 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_orig = delayNumSamples; } @@ -1398,20 +1738,37 @@ int main( zeroPad = delayNumSamples; } - if ( delayNumSamples * num_out_channels < outBufferSize ) + if ( is_split_pre_rend_mode( &args ) ) { - if ( AudioFileWriter_write( audioWriter, &outInt16Buffer[delayNumSamples * num_out_channels], outBufferSize - ( delayNumSamples * num_out_channels ) ) != IVAS_ERR_OK ) + if ( split_rend_write_bitstream_to_file( hSplitRendFileReadWrite, bitsBuffer.bits, &bitsBuffer.config.bitsRead, &bitsBuffer.config.bitsWritten, + bitsBuffer.config.codec, bitsBuffer.config.poseCorrection, + bitsBuffer.config.codec_frame_size_ms ) != IVAS_ERR_OK ) { - fprintf( stderr, "Error writing audio file %s\n", args.outputFilePath ); + fprintf( stderr, "\nUnable to write to bitstream file!\n" ); exit( -1 ); } - delayNumSamples = 0; } - else + + if ( audioWriter != NULL ) { - delayNumSamples -= (int16_t) ( outBufferSize / num_out_channels ); + if ( delayNumSamples * num_out_channels < outBufferSize ) + { + if ( AudioFileWriter_write( audioWriter, &outInt16Buffer[delayNumSamples * num_out_channels], outBufferSize - ( delayNumSamples * num_out_channels ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error writing audio file %s\n", args.outputFilePath ); + exit( -1 ); + } + delayNumSamples = 0; + } + else + { + delayNumSamples -= (int16_t) ( outBufferSize / num_out_channels ); + } } + bitsBuffer.config.bitsRead = 0; + bitsBuffer.config.bitsWritten = 0; + /* Write MASA metadata for MASA outputs */ if ( args.outConfig.audioConfig == IVAS_AUDIO_CONFIG_MASA1 || args.outConfig.audioConfig == IVAS_AUDIO_CONFIG_MASA2 ) { @@ -1515,24 +1872,27 @@ int main( } /* add zeros at the end to have equal length of synthesized signals */ - for ( zeroPadToWrite = zeroPad; zeroPadToWrite > frameSize_smpls; zeroPadToWrite -= frameSize_smpls ) + if ( audioWriter != NULL ) { - memset( outInt16Buffer, 0, outBufferSize * sizeof( int16_t ) ); - if ( ( error = AudioFileWriter_write( audioWriter, outInt16Buffer, outBufferSize ) ) != IVAS_ERR_OK ) + for ( zeroPadToWrite = zeroPad; zeroPadToWrite > frameSize_smpls; zeroPadToWrite -= frameSize_smpls ) + { + memset( outInt16Buffer, 0, outBufferSize * sizeof( int16_t ) ); + if ( ( error = AudioFileWriter_write( audioWriter, outInt16Buffer, outBufferSize ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nOutput audio file writer error\n" ); + exit( -1 ); + } + } + + memset( outInt16Buffer, 0, zeroPadToWrite * outBuffer.config.numChannels * sizeof( int16_t ) ); + if ( ( error = AudioFileWriter_write( audioWriter, outInt16Buffer, zeroPadToWrite * outBuffer.config.numChannels ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nOutput audio file writer error\n" ); exit( -1 ); } + zeroPadToWrite = 0; } - memset( outInt16Buffer, 0, zeroPadToWrite * outBuffer.config.numChannels * sizeof( int16_t ) ); - if ( ( error = AudioFileWriter_write( audioWriter, outInt16Buffer, zeroPadToWrite * outBuffer.config.numChannels ) ) != IVAS_ERR_OK ) - { - fprintf( stderr, "\nOutput audio file writer error\n" ); - exit( -1 ); - } - zeroPadToWrite = 0; - if ( args.inConfig.numAudioObjects != 0 && ( args.outConfig.audioConfig == IVAS_AUDIO_CONFIG_BINAURAL || args.outConfig.audioConfig == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ) { @@ -1563,11 +1923,21 @@ int main( free( inFloatBuffer ); free( outInt16Buffer ); free( outFloatBuffer ); + if ( bitsBufferData != NULL ) + { + free( bitsBufferData ); + } for ( i = 0; i < RENDERER_MAX_MASA_INPUTS; ++i ) { MasaFileReader_close( &masaReaders[i] ); } + if ( cldfb_in_flag ) + { + IVAS_REND_closeCldfb( cldfbAna, cldfbSyn ); + } + + split_rend_reader_writer_close( &hSplitRendFileReadWrite ); for ( i = 0; i < RENDERER_MAX_MC_INPUTS; ++i ) { @@ -1643,6 +2013,7 @@ static bool parseInConfig( inConfig->numAmbisonicsBuses = 0; inConfig->numMultiChannelBuses = 0; inConfig->numMasaBuses = 0; + inConfig->numBinBuses = 0; /* First check if input is being set to scene description file - this is not covered by parseAudioConfig(). */ strncpy( charBuf, inFormatStr, sizeof( charBuf ) - 1 ); @@ -1680,6 +2051,13 @@ static bool parseInConfig( inConfig->ambisonicsBuses[0].inputChannelIndex = 0; inConfig->ambisonicsBuses[0].gain_dB = 0.0f; break; + case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED: + case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM: + inConfig->numBinBuses = 1; + inConfig->binBuses[0].audioConfig = audioConfig; + inConfig->binBuses[0].inputChannelIndex = 0; + inConfig->binBuses[0].gain_dB = 0.0f; + break; case IVAS_AUDIO_CONFIG_MASA1: case IVAS_AUDIO_CONFIG_MASA2: inConfig->numMasaBuses = 1; @@ -1870,8 +2248,8 @@ static bool parseOrientationTracking( static IVAS_AUDIO_CONFIG parseAudioConfig( const char *configString ) { - char charBuf[21]; - charBuf[20] = '\0'; + char charBuf[25]; + charBuf[24] = '\0'; strncpy( charBuf, configString, sizeof( charBuf ) - 1 ); charBuf[sizeof( charBuf ) - 1] = '\0'; @@ -1946,6 +2324,14 @@ static IVAS_AUDIO_CONFIG parseAudioConfig( { return IVAS_AUDIO_CONFIG_BINAURAL; } + if ( strcmp( charBuf, "BINAURAL_SPLIT_PCM" ) == 0 ) + { + return IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM; + } + if ( strcmp( charBuf, "BINAURAL_SPLIT_CODED" ) == 0 ) + { + return IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED; + } if ( strcmp( charBuf, "BINAURAL_ROOM_IR" ) == 0 ) { return IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR; @@ -2021,7 +2407,8 @@ static bool checkRequiredArgs( const bool singleInputSpecified = args.inConfig.numAudioObjects != 0 || args.inConfig.numAmbisonicsBuses != 0 || args.inConfig.numMultiChannelBuses != 0 || - args.inConfig.numMasaBuses != 0; + args.inConfig.numMasaBuses != 0 || + args.inConfig.numBinBuses != 0; if ( !args.sceneDescriptionInput && !singleInputSpecified ) { @@ -2078,6 +2465,8 @@ static CmdlnArgs defaultArgs( args.numInMetadataFiles = 0; clearString( args.headRotationFilePath ); + clearString( args.outMetadataFilePath ); + clearString( args.splitRendBFIFilePath ); clearString( args.referenceVectorFilePath ); clearString( args.referenceRotationFilePath ); clearString( args.customHrtfFilePath ); @@ -2170,6 +2559,14 @@ static void parseOption( assert( numOptionValues == 1 ); strncpy( args->headRotationFilePath, optionValues[0], RENDERER_MAX_CLI_ARG_LENGTH - 1 ); break; + case CmdLnOptionId_outputMetadata: + assert( numOptionValues == 1 ); + strncpy( args->outMetadataFilePath, optionValues[0], RENDERER_MAX_CLI_ARG_LENGTH - 1 ); + break; + case CmdLnOptionId_SplitRendBFIFile: + assert( numOptionValues == 1 ); + strncpy( args->splitRendBFIFilePath, optionValues[0], RENDERER_MAX_CLI_ARG_LENGTH - 1 ); + break; case CmdLnOptionId_referenceVectorFile: assert( numOptionValues == 1 ); strncpy( args->referenceVectorFilePath, optionValues[0], RENDERER_MAX_CLI_ARG_LENGTH - 1 ); @@ -3172,6 +3569,8 @@ static void printSupportedAudioConfigs( void ) "ISMx (input only)", "MASAx", "BINAURAL (output only)", + "BINAURAL_SPLIT_PCM", + "BINAURAL_SPLIT_CODED", "BINAURAL_ROOM_IR (output only)", "BINAURAL_ROOM_REVERB (output only)", }; @@ -3268,26 +3667,70 @@ static void convertInputBuffer( const int16_t numIntSamplesPerChannel, const int16_t numFloatSamplesPerChannel, const int16_t numChannels, - float *floatBuffer ) + float *floatBuffer, + const int16_t cldfb_in_flag, + IVAS_CLDFB_FILTER_BANK_HANDLE *cldfbAna +) { int16_t chnl, smpl, i; i = 0; - for ( smpl = 0; smpl < numFloatSamplesPerChannel; ++smpl ) + if ( cldfb_in_flag ) { - for ( chnl = 0; chnl < numChannels; ++chnl ) + int16_t slotIdx, numCldfbBands, numFloatPcmSamples; + float fIn[IVAS_MAX_OUTPUT_CHANNELS][IVAS_MAX_FRAME_SIZE]; + + numFloatPcmSamples = numFloatSamplesPerChannel >> 1; + numCldfbBands = numFloatPcmSamples / IVAS_CLDFB_NO_COL_MAX; + + /* CLDFB Analysis*/ + assert( numIntSamplesPerChannel <= IVAS_MAX_OUTPUT_CHANNELS * IVAS_MAX_FRAME_SIZE ); + for ( smpl = 0; smpl < numFloatPcmSamples; ++smpl ) { - if ( i < numIntSamplesPerChannel ) + for ( chnl = 0; chnl < numChannels; ++chnl ) { - floatBuffer[chnl * numFloatSamplesPerChannel + smpl] = (float) intBuffer[i]; + if ( i < numIntSamplesPerChannel ) + { + fIn[chnl][smpl] = (float) intBuffer[i]; + } + else + { + fIn[chnl][smpl] = 0.f; + } + + ++i; } - else + } + + for ( chnl = 0; chnl < numChannels; ++chnl ) + { + for ( slotIdx = 0; slotIdx < IVAS_CLDFB_NO_COL_MAX; slotIdx++ ) { - floatBuffer[chnl * numFloatSamplesPerChannel + smpl] = 0.f; + IVAS_REND_cldfbAnalysis_ts_wrapper( &fIn[chnl][numCldfbBands * slotIdx], + &floatBuffer[( chnl * numFloatSamplesPerChannel ) + ( 2 * slotIdx * numCldfbBands )], + &floatBuffer[numCldfbBands + ( chnl * numFloatSamplesPerChannel ) + ( 2 * slotIdx * numCldfbBands )], + numCldfbBands, cldfbAna[chnl] ); } + } + } + else + { + for ( smpl = 0; smpl < numFloatSamplesPerChannel; ++smpl ) + { + for ( chnl = 0; chnl < numChannels; ++chnl ) + { + if ( i < numIntSamplesPerChannel ) + { + floatBuffer[chnl * numFloatSamplesPerChannel + smpl] = (float) intBuffer[i]; + } + else + { + floatBuffer[chnl * numFloatSamplesPerChannel + smpl] = 0.f; + } - ++i; + ++i; + } } } @@ -3305,30 +3748,82 @@ static void convertOutputBuffer( const float *floatBuffer, const int16_t numSamplesPerChannel, const int16_t numChannels, - int16_t *intBuffer ) + int16_t *intBuffer, + const int16_t cldfb_in_flag, + IVAS_CLDFB_FILTER_BANK_HANDLE *cldfbSyn +) { int16_t chnl, smpl, i; float temp; i = 0; - for ( smpl = 0; smpl < numSamplesPerChannel; ++smpl ) + if ( cldfb_in_flag ) { + int16_t slotIdx, numCldfbBands, numPcmSamples, b; + float fIn[IVAS_MAX_OUTPUT_CHANNELS][IVAS_MAX_FRAME_SIZE]; + float re[IVAS_MAX_OUTPUT_CHANNELS][IVAS_CLDFB_NO_COL_MAX][IVAS_CLDFB_NO_CHANNELS_MAX]; + float im[IVAS_MAX_OUTPUT_CHANNELS][IVAS_CLDFB_NO_COL_MAX][IVAS_CLDFB_NO_CHANNELS_MAX]; + + numPcmSamples = numSamplesPerChannel >> 1; + numCldfbBands = numPcmSamples / IVAS_CLDFB_NO_COL_MAX; + + /* CLDFB Synthesis*/ + for ( chnl = 0; chnl < numChannels; ++chnl ) + { + for ( slotIdx = 0; slotIdx < IVAS_CLDFB_NO_COL_MAX; slotIdx++ ) + { + for ( b = 0; b < numCldfbBands; b++ ) + { + re[chnl][slotIdx][b] = floatBuffer[( chnl * numSamplesPerChannel ) + ( 2 * slotIdx * numCldfbBands ) + b]; + im[chnl][slotIdx][b] = floatBuffer[numCldfbBands + ( chnl * numSamplesPerChannel ) + ( 2 * slotIdx * numCldfbBands ) + b]; + } + } + } + + /* Implement CLDFB synthesis */ for ( chnl = 0; chnl < numChannels; ++chnl ) { - temp = floatBuffer[chnl * numSamplesPerChannel + smpl]; - temp = (float) floor( temp + 0.5f ); - if ( temp > IVAS_MAX16B_FLT ) + float *RealBuffer[IVAS_CLDFB_NO_COL_MAX]; + float *ImagBuffer[IVAS_CLDFB_NO_COL_MAX]; + + for ( slotIdx = 0; slotIdx < IVAS_CLDFB_NO_COL_MAX; slotIdx++ ) { - temp = IVAS_MAX16B_FLT; + RealBuffer[slotIdx] = re[chnl][slotIdx]; + ImagBuffer[slotIdx] = im[chnl][slotIdx]; } - else if ( temp < IVAS_MIN16B_FLT ) + + IVAS_REND_cldfbSynthesis_wrapper( RealBuffer, ImagBuffer, &( fIn[chnl][0] ), numCldfbBands * IVAS_CLDFB_NO_COL_MAX, cldfbSyn[chnl] ); + } + for ( smpl = 0; smpl < numPcmSamples; ++smpl ) + { + for ( chnl = 0; chnl < numChannels; ++chnl ) { - temp = IVAS_MIN16B_FLT; + intBuffer[i] = (int16_t) roundf( fIn[chnl][smpl] ); + ++i; } - intBuffer[i] = (int16_t) temp; + } + } + else + { + for ( smpl = 0; smpl < numSamplesPerChannel; ++smpl ) + { + for ( chnl = 0; chnl < numChannels; ++chnl ) + { + temp = floatBuffer[chnl * numSamplesPerChannel + smpl]; + temp = (float) floor( temp + 0.5f ); + if ( temp > IVAS_MAX16B_FLT ) + { + temp = IVAS_MAX16B_FLT; + } + else if ( temp < IVAS_MIN16B_FLT ) + { + temp = IVAS_MIN16B_FLT; + } + intBuffer[i] = (int16_t) temp; - ++i; + ++i; + } } } -- GitLab From 95082ba7a4773da8755d1ff99bc3ecebe158a9d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20M=C3=BCller?= Date: Mon, 13 Jan 2025 12:14:40 +0100 Subject: [PATCH 07/33] Port CI jobs relevant for split rendering --- .gitlab-ci.yml | 112 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 4843bd3bf..16cb1deae 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -117,6 +117,24 @@ stages: echo "Commit time was $CI_COMMIT_TIMESTAMP" date | xargs echo "System time is" +.mr-fetch-target-branch: &mr-fetch-target-branch + # first delete local target branch to avoid conflicts when branch is cached and there are merge conflicts during fetching + # depending on chaching, the branch may not be there, so prevent failure of this command -> should maybe be done smarter later + - git branch -D $CI_MERGE_REQUEST_TARGET_BRANCH_NAME || true + # needed when depth is lower than the number of commits in the branch + - git fetch origin $CI_MERGE_REQUEST_TARGET_BRANCH_NAME:$CI_MERGE_REQUEST_TARGET_BRANCH_NAME + +.mr-get-target-commit: &mr-get-target-commit # compare to last target branch commit before pipeline was created + - target_commit=$(git log $CI_MERGE_REQUEST_TARGET_BRANCH_NAME -1 --oneline --before=${CI_PIPELINE_CREATED_AT} --format=%H) + +.get-commits-behind-count: &get-commits-behind-count + - echo $CI_COMMIT_SHA + - echo $CI_MERGE_REQUEST_TARGET_BRANCH_NAME + - commits_behind_count=$(git rev-list --count $CI_COMMIT_SHA..origin/$CI_MERGE_REQUEST_TARGET_BRANCH_NAME) + +.check-commits-behind-count-in-compare-jobs: &check-commits-behind-count-in-compare-jobs + - if [ $commits_behind_count -ne 0 ]; then echo "Your branch is not up-to-date with main -> Compare tests will not run as they can contain false negatives this way.\nMain might have changed during your pipeline run. Run 'git merge origin/main' to update."; exit 1; fi + .build-reference-binaries: &build-reference-binaries - current_commit_sha=$(git rev-parse HEAD) ### build reference binaries @@ -167,6 +185,13 @@ stages: - echo "Applying level scaling in scripts/testv using scale=$LEVEL_SCALING" - tests/scale_pcm.py ./scripts/testv/ $LEVEL_SCALING +.merge-request-comparison-check: &merge-request-comparison-check + - echo "--------------- Running merge-request-comparison-check anchor ---------------" + - if [ $zero_errors != 1 ]; then echo "Run errors encountered!"; exit $EXIT_CODE_FAIL; fi + - if [ $exit_code -eq 1 ] && [ $non_be_flag == 0 ]; then echo "Non-bitexact cases without non-BE tag encountered!"; exit $EXIT_CODE_FAIL; fi + - if [ $exit_code -eq 1 ] && [ $non_be_flag != 0 ]; then echo "Non-bitexact cases with non-BE tag encountered"; exit $EXIT_CODE_NON_BE; fi + - exit 0 + .update-ltv-repo: &update-ltv-repo - cd $LTV_DIR - git pull @@ -683,6 +708,93 @@ build-codec-linux-instrumented-make: - bash scripts/prepare_instrumentation.sh -m MEM_ONLY -p BASOP - make -j -C $INSTR_DIR +# --------------------------------------------------------------- +# Test jobs for merge requests +# --------------------------------------------------------------- + +lc3-wrapper-unit-test: + extends: + - .test-job-linux + - .rules-merge-request + needs: ["build-codec-linux-cmake"] + stage: test + script: + - cmake -B cmake-build -G "Unix Makefiles" -DCOPY_EXECUTABLES_FROM_BUILD_DIR=true + - cmake --build cmake-build -- -j + - scripts/split_rendering/lc3plus/ivas_lc3plus_unit_test + +# compare split-rendering bitexactness between target and source branch +split-rendering-pytest-on-merge-request: + extends: + - .test-job-linux-needs-testv-dir + - .rules-merge-request + needs: ["build-codec-linux-make"] + # TODO: set reasonable timeout, will most likely take less + timeout: "30 minutes" + stage: compare + script: + - *print-common-info + - *get-commits-behind-count + - *check-commits-behind-count-in-compare-jobs + + # some helper variables - "|| true" to prevent failures from grep not finding anything + # write to temporary file as workaround for failures observed with piping echo + - echo $CI_MERGE_REQUEST_TITLE > tmp.txt + - non_be_flag=$(grep -c --ignore-case "\[split*[ -]*non[ -]*be\]" tmp.txt) || true + - ref_using_main=$(grep -c --ignore-case "\[ref[ -]*using[ -]*main\]" tmp.txt) || true + + # store the current commit hash + - source_branch_commit_sha=$(git rev-parse HEAD) + + - *mr-fetch-target-branch + - *mr-get-target-commit + - git checkout $target_commit + - echo "Building reference codec at commit $target_commit" + + # build reference binaries + - make -j + - mv IVAS_cod IVAS_cod_ref + - mv IVAS_dec IVAS_dec_ref + - mv IVAS_rend IVAS_rend_ref + + ### If ref_using_main is not set, checkout the source branch to use scripts and input from there + - if [ $ref_using_main == 0 ]; then git restore lib_com/options.h; fi # Revert changes back before checking out another branch to avoid conflicts + - if [ $ref_using_main == 0 ]; then git checkout $source_branch_commit_sha; fi + - exit_code=0 + - testcase_timeout=60 + - python3 -m pytest -q --log-level ERROR -n auto -rA --html=report.html --self-contained-html --junit-xml=report-junit.xml tests/split_rendering/test_split_rendering.py --create_ref --testcase_timeout=$testcase_timeout || exit_code=$? + + # back to source branch + - git restore lib_com/options.h # Revert changes back before checking out another branch to avoid conflicts + - git checkout $source_branch_commit_sha + - make clean + - make -j + + ### Run test using scripts and input from main + - if [ $ref_using_main == 1 ]; then git restore lib_com/options.h; fi # Revert changes back before checking out another branch to avoid conflicts + - if [ $ref_using_main == 1 ]; then git checkout $source_branch_commit_sha; fi + + # run test + - python3 -m pytest -q --log-level ERROR -n auto -rA --html=report.html --self-contained-html --junit-xml=report-junit.xml tests/split_rendering/test_split_rendering.py --create_cut --testcase_timeout=$testcase_timeout || exit_code=$? + - zero_errors=$(cat report-junit.xml | grep -c 'errors="0"') || true + + - *merge-request-comparison-check + + allow_failure: + exit_codes: + - 123 + artifacts: + name: "mr-$CI_MERGE_REQUEST_IID--sha-$CI_COMMIT_SHORT_SHA--job-$CI_JOB_NAME--results" + expire_in: 2 week + when: always + paths: + - report-junit.xml + - report.html + expose_as: "pytest split rendering results" + reports: + junit: + - report-junit.xml + # --------------------------------------------------------------- # Short test jobs that run in merge request pipelines # --------------------------------------------------------------- -- GitLab From bbc56d70040be5cc538d21a851527590b2cec5fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20M=C3=BCller?= Date: Mon, 13 Jan 2025 12:17:10 +0100 Subject: [PATCH 08/33] fixup! Port CI jobs relevant for split rendering --- .gitlab-ci.yml | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 16cb1deae..434f1103e 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -205,6 +205,45 @@ stages: .activate-Werror-linux: &activate-Werror-linux - sed -i.bak "s/^# \(CFLAGS += -Werror\)/\1/" Makefile + +# --------------------------------------------------------------- +# Job templates +# --------------------------------------------------------------- + +# When designing templates, try not to use too much inheritance and +# if multiple templates and extended on, remember that on conflict, +# latest overwrites the parameter. + +# templates for rules +.rules-basis: + rules: + - if: $MIRROR_ACCESS_TOKEN # Don't run in the mirror update pipeline (only then MIRROR_ACCESS_TOKEN is defined) + when: never + - if: $CI_PIPELINE_SOURCE == 'schedule' # Don't run in any scheduled pipelines by default (use schedule templates below to enable again for certain conditions) + when: never + - if: $CI_PIPELINE_SOURCE == 'trigger' # Don't run triggered pipeline by default + when: never + - if: $MANUAL_PIPELINE_TYPE == 'test-be-release' # Skip all the normal jobs when testing manually against release codec + when: never + - if: $MANUAL_PIPELINE_TYPE == 'test-long-self-test' # Skip all the normal jobs when testing manually against release codec + when: never + - if: $MANUAL_PIPELINE_TYPE == 'ivas-conformance' + when: never + - if: $MANUAL_PIPELINE_TYPE == 'ivas-conformance-linux' + when: never + - if: $MANUAL_PIPELINE_TYPE == 'check-clipping' + when: never + - if: $MANUAL_PIPELINE_TYPE == 'test-branch-vs-input-passthrough' + when: never + - when: on_success + +.rules-merge-request: + extends: .rules-basis + rules: + - if: $CI_PIPELINE_SOURCE == 'merge_request_event' + - if: $CI_PIPELINE_SOURCE == 'push' + when: never + .rules-pytest-to-ref-short: rules: - if: $CI_PIPELINE_SOURCE == 'web' && $MANUAL_PIPELINE_TYPE == "pytest-compare" -- GitLab From 01a3d857abff163d197ade0d6976d63297816a9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20M=C3=BCller?= Date: Mon, 13 Jan 2025 12:18:40 +0100 Subject: [PATCH 09/33] fixup! fixup! Port CI jobs relevant for split rendering --- .gitlab-ci.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 434f1103e..1536b03e4 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -755,11 +755,10 @@ lc3-wrapper-unit-test: extends: - .test-job-linux - .rules-merge-request - needs: ["build-codec-linux-cmake"] + needs: ["build-codec-linux-make"] stage: test script: - - cmake -B cmake-build -G "Unix Makefiles" -DCOPY_EXECUTABLES_FROM_BUILD_DIR=true - - cmake --build cmake-build -- -j + - make -j - scripts/split_rendering/lc3plus/ivas_lc3plus_unit_test # compare split-rendering bitexactness between target and source branch -- GitLab From 2d7d9a50d2f79917e56cb5fbd6011ff4946d026b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20M=C3=BCller?= Date: Mon, 13 Jan 2025 12:19:21 +0100 Subject: [PATCH 10/33] fixup! fixup! fixup! Port CI jobs relevant for split rendering --- .gitlab-ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 1536b03e4..a3881a16c 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -101,6 +101,7 @@ stages: - prevalidate - build - test + - compare - deploy # --------------------------------------------------------------- -- GitLab From 8b4bd143b24396957fb76f1d099743ff10ce0571 Mon Sep 17 00:00:00 2001 From: rtyag Date: Wed, 15 Jan 2025 22:42:17 +1100 Subject: [PATCH 11/33] addition of lib isar, not compiling yet --- apps/isar_post_rend.c | 1253 ++ lib_com/common_api_types.h | 112 +- lib_isar/isar_MSPred.c | 470 + lib_isar/isar_NoiseGen.c | 57 + lib_isar/isar_PerceptualModel.c | 252 + lib_isar/isar_PredDecoder.c | 462 + lib_isar/isar_PredEncoder.c | 577 + lib_isar/isar_RMSEnvGrouping.c | 727 + lib_isar/isar_cnst.h | 135 + lib_isar/isar_lc3plus_common.c | 89 + lib_isar/isar_lc3plus_common.h | 72 + lib_isar/isar_lc3plus_dec.c | 844 ++ lib_isar/isar_lc3plus_dec.h | 135 + lib_isar/isar_lc3plus_enc.c | 686 + lib_isar/isar_lc3plus_enc.h | 102 + lib_isar/isar_lc3plus_payload.c | 823 ++ lib_isar/isar_lc3plus_payload.h | 216 + lib_isar/isar_lcld_decoder.c | 1711 +++ lib_isar/isar_lcld_encoder.c | 1893 +++ lib_isar/isar_lcld_prot.h | 393 + lib_isar/isar_prot.h | 393 + lib_isar/isar_rom_lcld_tables.c | 12097 +++++++++++++++++ lib_isar/isar_rom_lcld_tables.h | 197 + lib_isar/isar_rom_post_rend.c | 182 + lib_isar/isar_rom_post_rend.h | 69 + lib_isar/isar_splitRend_lcld_dec.c | 258 + lib_isar/isar_splitRend_lcld_enc.c | 242 + lib_isar/isar_splitRendererPLC.c | 543 + lib_isar/isar_splitRendererPost.c | 1910 +++ lib_isar/isar_splitRendererPre.c | 2340 ++++ lib_isar/isar_splitRenderer_utils.c | 1289 ++ lib_isar/isar_stat.h | 259 + lib_isar/lib_isar_post_rend.c | 1911 +++ lib_isar/lib_isar_post_rend.h | 231 + lib_isar/lib_isar_pre_rend.c | 497 + lib_isar/lib_isar_pre_rend.h | 91 + lib_lc3plus/adjust_global_gain.c | 23 +- lib_lc3plus/al_fec_fl.c | 3 +- lib_lc3plus/apply_global_gain.c | 5 +- lib_lc3plus/ari_codec.c | 962 +- lib_lc3plus/attack_detector.c | 39 +- lib_lc3plus/clib.h | 4 +- lib_lc3plus/constants.c | 2545 +++- lib_lc3plus/constants.h | 55 +- lib_lc3plus/cutoff_bandwidth.c | 5 +- lib_lc3plus/dct4.c | 18 +- lib_lc3plus/dec_entropy.c | 11 +- lib_lc3plus/dec_lc3_fl.c | 26 +- lib_lc3plus/defines.h | 298 +- lib_lc3plus/detect_cutoff_warped.c | 18 +- lib_lc3plus/enc_entropy.c | 24 +- lib_lc3plus/enc_lc3_fl.c | 27 +- lib_lc3plus/estimate_global_gain.c | 16 +- lib_lc3plus/fft/cfft.c | 10 +- lib_lc3plus/fft/cfft.h | 4 +- lib_lc3plus/fft/fft_15_16.h | 2 +- lib_lc3plus/fft/fft_240_480.h | 2 +- lib_lc3plus/fft/fft_2_9.h | 2 +- lib_lc3plus/fft/fft_32.h | 2 +- lib_lc3plus/fft/fft_384_768.h | 2 +- lib_lc3plus/fft/fft_60_128.h | 2 +- lib_lc3plus/fft/fft_generic.h | 2 +- lib_lc3plus/fft/iis_fft.c | 20 +- lib_lc3plus/fft/iis_fft.h | 4 +- lib_lc3plus/fft/iisfft.c | 13 +- lib_lc3plus/fft/iisfft.h | 4 +- lib_lc3plus/functions.h | 73 +- lib_lc3plus/imdct.c | 9 +- lib_lc3plus/lc3.c | 11 +- lib_lc3plus/lc3.h | 6 +- lib_lc3plus/lc3plus_fft.c | 22 +- lib_lc3plus/license.h | 6 +- lib_lc3plus/ltpf_coder.c | 106 +- lib_lc3plus/ltpf_decoder.c | 164 +- lib_lc3plus/mdct.c | 41 +- lib_lc3plus/mdct_shaping.c | 11 +- lib_lc3plus/near_nyquist_detector.c | 79 +- lib_lc3plus/noise_factor.c | 120 +- lib_lc3plus/noise_filling.c | 60 +- lib_lc3plus/olpa.c | 135 +- lib_lc3plus/pc_apply.c | 3 +- lib_lc3plus/pc_classify.c | 3 +- lib_lc3plus/pc_main.c | 3 +- lib_lc3plus/pc_update.c | 3 +- lib_lc3plus/per_band_energy.c | 26 +- lib_lc3plus/plc_classify.c | 146 +- lib_lc3plus/plc_compute_stab_fac.c | 3 +- lib_lc3plus/plc_damping_scrambling.c | 228 +- lib_lc3plus/plc_main.c | 130 +- lib_lc3plus/plc_noise_substitution.c | 3 +- lib_lc3plus/plc_phecu_f0_refine_first.c | 3 +- lib_lc3plus/plc_phecu_fec_hq.c | 3 +- lib_lc3plus/plc_phecu_hq_ecu.c | 35 +- lib_lc3plus/plc_phecu_lf_peak_analysis.c | 3 +- lib_lc3plus/plc_phecu_rec_frame.c | 10 +- lib_lc3plus/plc_phecu_setf0hz.c | 3 +- lib_lc3plus/plc_phecu_spec_ana.c | 3 +- lib_lc3plus/plc_phecu_subst_spec.c | 245 +- lib_lc3plus/plc_phecu_tba_per_band_gain.c | 10 +- lib_lc3plus/plc_phecu_tba_spect_Xavg.c | 3 +- lib_lc3plus/plc_phecu_tba_trans_dect_gains.c | 123 +- lib_lc3plus/plc_phecu_trans_burst_ana_sub.c | 26 +- lib_lc3plus/plc_tdc.c | 48 +- lib_lc3plus/plc_tdc_tdac.c | 3 +- lib_lc3plus/plc_update.c | 5 +- lib_lc3plus/quantize_spec.c | 207 +- lib_lc3plus/reorder_bitstream.c | 3 +- lib_lc3plus/resamp12k8.c | 24 +- lib_lc3plus/residual_coding.c | 5 +- lib_lc3plus/residual_decoding.c | 7 +- lib_lc3plus/setup_com_lc3.c | 5 +- lib_lc3plus/setup_dec_lc3.c | 106 +- lib_lc3plus/setup_dec_lc3.h | 7 +- lib_lc3plus/setup_enc_lc3.c | 129 +- lib_lc3plus/setup_enc_lc3.h | 11 +- lib_lc3plus/sns_compute_scf.c | 86 +- lib_lc3plus/sns_interpolate_scf.c | 24 +- lib_lc3plus/sns_quantize_scf.c | 18 +- lib_lc3plus/structs.h | 28 +- lib_lc3plus/tns_coder.c | 177 +- lib_lc3plus/tns_decoder.c | 21 +- lib_lc3plus/util.h | 36 +- 122 files changed, 39402 insertions(+), 1072 deletions(-) create mode 100644 apps/isar_post_rend.c create mode 100644 lib_isar/isar_MSPred.c create mode 100644 lib_isar/isar_NoiseGen.c create mode 100644 lib_isar/isar_PerceptualModel.c create mode 100644 lib_isar/isar_PredDecoder.c create mode 100644 lib_isar/isar_PredEncoder.c create mode 100644 lib_isar/isar_RMSEnvGrouping.c create mode 100644 lib_isar/isar_cnst.h create mode 100644 lib_isar/isar_lc3plus_common.c create mode 100644 lib_isar/isar_lc3plus_common.h create mode 100644 lib_isar/isar_lc3plus_dec.c create mode 100644 lib_isar/isar_lc3plus_dec.h create mode 100644 lib_isar/isar_lc3plus_enc.c create mode 100644 lib_isar/isar_lc3plus_enc.h create mode 100644 lib_isar/isar_lc3plus_payload.c create mode 100644 lib_isar/isar_lc3plus_payload.h create mode 100644 lib_isar/isar_lcld_decoder.c create mode 100644 lib_isar/isar_lcld_encoder.c create mode 100644 lib_isar/isar_lcld_prot.h create mode 100644 lib_isar/isar_prot.h create mode 100644 lib_isar/isar_rom_lcld_tables.c create mode 100644 lib_isar/isar_rom_lcld_tables.h create mode 100644 lib_isar/isar_rom_post_rend.c create mode 100644 lib_isar/isar_rom_post_rend.h create mode 100644 lib_isar/isar_splitRend_lcld_dec.c create mode 100644 lib_isar/isar_splitRend_lcld_enc.c create mode 100644 lib_isar/isar_splitRendererPLC.c create mode 100644 lib_isar/isar_splitRendererPost.c create mode 100644 lib_isar/isar_splitRendererPre.c create mode 100644 lib_isar/isar_splitRenderer_utils.c create mode 100644 lib_isar/isar_stat.h create mode 100644 lib_isar/lib_isar_post_rend.c create mode 100644 lib_isar/lib_isar_post_rend.h create mode 100644 lib_isar/lib_isar_pre_rend.c create mode 100644 lib_isar/lib_isar_pre_rend.h diff --git a/apps/isar_post_rend.c b/apps/isar_post_rend.c new file mode 100644 index 000000000..7f5af86ff --- /dev/null +++ b/apps/isar_post_rend.c @@ -0,0 +1,1253 @@ +/****************************************************************************************************** + + (C) 2022-2023 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. + +*******************************************************************************************************/ + +#include "lib_isar_post_rend.h" + +#ifndef SPLIT_REND_WITH_HEAD_ROT + +int main( int argc, char **argv ) +{ + (void) argc; + (void) argv; + ISAR_POST_REND_void_func(); + return 0; +} + +#else + +#include +#include +#include +#include "audio_file_reader.h" +#include "audio_file_writer.h" +#include "cmdl_tools.h" +#include "cmdln_parser.h" +#include "render_config_reader.h" +#include "rotation_file_reader.h" +#include "split_render_file_read_write.h" +#include "split_rend_bfi_file_reader.h" +#ifdef DEBUGGING +#include "debug.h" +#endif +#include "wmc_auto.h" + + +#define WMC_TOOL_SKIP + +/*------------------------------------------------------------------------------------------* + * Local constants + *------------------------------------------------------------------------------------------*/ + +#define POST_REND_MAX_CLI_ARG_LENGTH ( FILENAME_MAX ) + +#define ISAR_MAX16B_FLT 32767.0f +#define ISAR_MIN16B_FLT ( -32768.0f ) + +#if !defined( DEBUGGING ) && !defined( WMOPS ) +static +#endif + int32_t frame = 0; + +#ifdef _WIN32 +#define SEP_FOLDER '\\' +#else +#define SEP_FOLDER '/' +#endif + +/*------------------------------------------------------------------------------------------* + * Local structures + *------------------------------------------------------------------------------------------*/ + +typedef struct +{ + IVAS_AUDIO_CONFIG audioConfig; + int32_t inputChannelIndex; + float gain_dB; +} RendererInput; + +typedef struct +{ + RendererInput binBuses[RENDERER_MAX_BIN_INPUTS]; + uint16_t numBinBuses; +} InputConfig; + +typedef struct +{ + IVAS_AUDIO_CONFIG audioConfig; +} OutputConfig; + +typedef struct +{ + char executableName[POST_REND_MAX_CLI_ARG_LENGTH]; + char inputFilePath[POST_REND_MAX_CLI_ARG_LENGTH]; + char outputFilePath[POST_REND_MAX_CLI_ARG_LENGTH]; + int32_t sampleRate; + InputConfig inConfig; + OutputConfig outConfig; + char inMetadataFilePaths[RENDERER_MAX_ISAR_MD_INPUTS][POST_REND_MAX_CLI_ARG_LENGTH]; + int16_t numInMetadataFiles; + char headRotationFilePath[POST_REND_MAX_CLI_ARG_LENGTH]; + char splitRendBFIFilePath[POST_REND_MAX_CLI_ARG_LENGTH]; + ISAR_POST_REND_COMPLEXITY_LEVEL complexityLevel; + bool delayCompensationEnabled; + bool quietModeEnabled; + bool sceneDescriptionInput; + IVAS_RENDER_FRAMESIZE render_framesize; +} CmdlnArgs; + +typedef enum +{ + CmdLnOptionId_inputFile = 1, + CmdLnOptionId_inputFormat, + CmdLnOptionId_outputFile, + CmdLnOptionId_sampleRate, + CmdLnOptionId_trajFile, + CmdLnOptionId_orientationTracking, + CmdLnOptionId_complexityLevel, + CmdLnOptionId_noDelayCmp, + CmdLnOptionId_quietModeEnabled, + CmdLnOptionId_inputMetadata, + CmdLnOptionId_listFormats, + CmdLnOptionId_SplitRendBFIFile, + CmdLnOptionId_framing, +} CmdLnOptionId; + +static const CmdLnParser_Option cliOptions[] = { + { + .id = CmdLnOptionId_inputFile, + .match = "input_file", + .matchShort = "i", + .description = "Path to the input file (WAV, raw PCM or scene description file)", + }, + { + .id = CmdLnOptionId_inputFormat, + .match = "input_format", + .matchShort = "if", + .description = "Audio format of input file (e.g. BINAURAL_SPLIT_PCM, use -l for a list)", + }, + { + .id = CmdLnOptionId_inputMetadata, + .match = "input_metadata", + .matchShort = "im", + .description = "Space-separated list of path to metadata files for BINAURAL_SPLIT_PCM input mode", + }, + { + .id = CmdLnOptionId_outputFile, + .match = "output_file", + .matchShort = "o", + .description = "Path to the output file", + }, + { + .id = CmdLnOptionId_sampleRate, + .match = "sample_rate", + .matchShort = "fs", + .description = "Input sampling rate in kHz (16, 32, 48) - required only with raw PCM inputs", + }, + { + .id = CmdLnOptionId_trajFile, + .match = "trajectory_file", + .matchShort = "T", + .description = "Head rotation trajectory file for simulation of head tracking", + }, + { + .id = CmdLnOptionId_SplitRendBFIFile, + .match = "post_rend_bfi_file", + .matchShort = "prbfi", + .description = "Split rendering option: bfi file", + }, + { + .id = CmdLnOptionId_noDelayCmp, + .match = "no_delay_compensation", + .matchShort = "no_delay_cmp", + .description = "[flag] Turn off delay compensation", + }, + { + .id = CmdLnOptionId_complexityLevel, + .match = "complexity_level", + .matchShort = "level", + .description = "Complexity level, level = (1, 2, 3), will be defined after characterisation.", + }, + { + .id = CmdLnOptionId_quietModeEnabled, + .match = "quiet", + .matchShort = "q", + .description = "[flag] Limit printouts to terminal", + }, + { + .id = CmdLnOptionId_listFormats, + .match = "list", + .matchShort = "l", + .description = "List supported audio formats", + }, + { + .id = CmdLnOptionId_framing, + .match = "framing", + .matchShort = "fr", + .description = "Set Render audio framing.", + }, +}; + + +/*------------------------------------------------------------------------------------------* + * Local function prototypes + *------------------------------------------------------------------------------------------*/ + +static const int32_t numCliOptions = sizeof( cliOptions ) / sizeof( CmdLnParser_Option ); + +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 ); + +/*------------------------------------------------------------------------------------------* + * Local functions + *------------------------------------------------------------------------------------------*/ + +static ISAR_POST_REND_ReadOnlyAudioBuffer getReadOnlySubBuffer( + IVAS_REND_AudioBuffer buffer, + const int16_t chBeginIdx, + const int16_t numChannels ) +{ + ISAR_POST_REND_ReadOnlyAudioBuffer subBuffer; + + subBuffer.config = buffer.config; + subBuffer.config.numChannels = numChannels; + subBuffer.data = buffer.data + subBuffer.config.numSamplesPerChannel * chBeginIdx; + + return subBuffer; +} + + +static int16_t getTotalNumInChannels( + ISAR_POST_REND_HANDLE hIsarPostRend, + ISAR_POST_REND_InputId splitBinIds[RENDERER_MAX_BIN_INPUTS] ) +{ + int16_t totalNumInChannels = 0; + int16_t i, numInputChannels; + ivas_error error; + + for ( i = 0; i < RENDERER_MAX_BIN_INPUTS; ++i ) + { + if ( splitBinIds[i] == 0 ) + { + /* Skip inactive inputs */ + continue; + } + + if ( ( error = ISAR_POST_REND_GetInputNumChannels( hIsarPostRend, splitBinIds[i], &numInputChannels ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + totalNumInChannels += numInputChannels; + } + + return totalNumInChannels; +} + +/*------------------------------------------------------------------------------------------* + * Local functions + *------------------------------------------------------------------------------------------*/ + +static const CmdLnParser_Option *findOptionById( + const int32_t id ) +{ + for ( int32_t i = 0; i < numCliOptions; ++i ) + { + if ( cliOptions[i].id == id ) + { + return &cliOptions[i]; + } + } + + return NULL; +} + +static bool parseInConfig( + const char *inFormatStr, + InputConfig *inConfig, + bool *sceneDescriptionInput ) +{ + char charBuf[FILENAME_MAX]; + + /* Initialize input config struct */ + inConfig->numBinBuses = 0; + + /* First check if input is being set to scene description file - this is not covered by parseAudioConfig(). */ + strncpy( charBuf, inFormatStr, sizeof( charBuf ) - 1 ); + charBuf[sizeof( charBuf ) - 1] = '\0'; + to_upper( charBuf ); + if ( strcmp( charBuf, "META" ) == 0 ) + { + *sceneDescriptionInput = true; + /* Parsing the file will be done later. At this point the actual file path + * may not be known as command line parameters are still being parsed. */ + return true; + } + + /* Check for single-format inputs. The given string should map to a member of AUDIO_CONFIG enum. */ + IVAS_AUDIO_CONFIG audioConfig = parseAudioConfig( inFormatStr ); + switch ( audioConfig ) + { + case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED: + case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM: + inConfig->numBinBuses = 1; + inConfig->binBuses[0].audioConfig = audioConfig; + inConfig->binBuses[0].inputChannelIndex = 0; + inConfig->binBuses[0].gain_dB = 0.0f; + break; + default: + { + /* Default case covers formats that are defined in the AUDIO_CONFIG enum, + * but cannot be used at input, e.g. BINAURAL */ + const CmdLnParser_Option *listOption = findOptionById( CmdLnOptionId_listFormats ); + fprintf( stderr, "Unsupported input format: %s. To list valid formats, use option --%s.\n", inFormatStr, listOption->match ); + return false; + } + } + + return true; +} + + +static bool parseRenderFramesize( + char *value, + IVAS_RENDER_FRAMESIZE *render_framesize ) +{ + int32_t tmp; + + *render_framesize = IVAS_RENDER_FRAMESIZE_UNKNOWN; + if ( !is_digits_only( value ) ) + { + return false; + } + tmp = (int32_t) strtol( value, NULL, 0 ); + switch ( (int16_t) tmp ) + { + case 5: + *render_framesize = IVAS_RENDER_FRAMESIZE_5MS; + break; + case 10: + *render_framesize = IVAS_RENDER_FRAMESIZE_10MS; + break; + case 20: + *render_framesize = IVAS_RENDER_FRAMESIZE_20MS; + break; + default: + return false; + } + + return true; +} + + +static IVAS_AUDIO_CONFIG parseAudioConfig( + const char *configString ) +{ + char charBuf[25]; + charBuf[24] = '\0'; + + strncpy( charBuf, configString, sizeof( charBuf ) - 1 ); + charBuf[sizeof( charBuf ) - 1] = '\0'; + to_upper( charBuf ); + + if ( strcmp( charBuf, "BINAURAL" ) == 0 ) + { + return IVAS_AUDIO_CONFIG_BINAURAL; + } + if ( strcmp( charBuf, "BINAURAL_SPLIT_PCM" ) == 0 ) + { + return IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM; + } + if ( strcmp( charBuf, "BINAURAL_SPLIT_CODED" ) == 0 ) + { + return IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED; + } + return IVAS_AUDIO_CONFIG_INVALID; +} + + +static bool checkRequiredArgs( + CmdlnArgs args ) +{ + const CmdLnParser_Option *tmpOption; + + /* Check required arguments */ + bool missingRequiredArg = false; + if ( isEmptyString( args.inputFilePath ) ) + { + tmpOption = findOptionById( CmdLnOptionId_inputFile ); + fprintf( stderr, "Missing required argument: %s (%s)\n", tmpOption->match, tmpOption->matchShort ); + missingRequiredArg = true; + } + + const bool singleInputSpecified = ( args.inConfig.numBinBuses != 0 ); + + if ( !args.sceneDescriptionInput && !singleInputSpecified ) + { + /* Neither scene description input nor single-type input was specified on command line */ + tmpOption = findOptionById( CmdLnOptionId_inputFormat ); + fprintf( stderr, "Missing required argument: %s (%s)\n", tmpOption->match, tmpOption->matchShort ); + missingRequiredArg = true; + } + if ( isEmptyString( args.outputFilePath ) ) + { + tmpOption = findOptionById( CmdLnOptionId_outputFile ); + fprintf( stderr, "Missing required argument: %s (%s)\n", tmpOption->match, tmpOption->matchShort ); + missingRequiredArg = true; + } + if ( args.sampleRate == 0 ) + { + tmpOption = findOptionById( CmdLnOptionId_sampleRate ); + fprintf( stderr, "Missing required argument: %s (%s)\n", tmpOption->match, tmpOption->matchShort ); + missingRequiredArg = true; + } + if ( missingRequiredArg ) + { + CmdLnParser_printUsage( args.executableName, cliOptions, numCliOptions ); + } + + return !missingRequiredArg; +} + +static CmdlnArgs defaultArgs( + const char *executableName ) +{ + CmdlnArgs args; + + strncpy( args.executableName, executableName, POST_REND_MAX_CLI_ARG_LENGTH ); + clearString( args.inputFilePath ); + clearString( args.outputFilePath ); + args.sampleRate = 0; + + args.outConfig.audioConfig = IVAS_AUDIO_CONFIG_INVALID; + + for ( int32_t i = 0; i < RENDERER_MAX_ISAR_MD_INPUTS; ++i ) + { + clearString( args.inMetadataFilePaths[i] ); + } + args.numInMetadataFiles = 0; + + clearString( args.headRotationFilePath ); + clearString( args.splitRendBFIFilePath ); + + args.delayCompensationEnabled = true; + args.quietModeEnabled = false; + args.sceneDescriptionInput = false; + + args.render_framesize = IVAS_RENDER_FRAMESIZE_20MS; + + return args; +} + +static void parseOption( + const int32_t optionId, + char **optionValues, + const int16_t numOptionValues, + void *pOutputStruct ) +{ + CmdlnArgs *args = pOutputStruct; + + switch ( optionId ) + { + case CmdLnOptionId_listFormats: + assert( numOptionValues == 0 ); + printSupportedAudioConfigs(); + exit( 0 ); + case CmdLnOptionId_inputFile: + assert( numOptionValues == 1 ); + strncpy( args->inputFilePath, optionValues[0], POST_REND_MAX_CLI_ARG_LENGTH - 1 ); + break; + case CmdLnOptionId_inputFormat: + assert( numOptionValues == 1 ); + if ( !parseInConfig( optionValues[0], &args->inConfig, &args->sceneDescriptionInput ) ) + { + exit( -1 ); /* Error printout handled by failing function */ + } + break; + case CmdLnOptionId_inputMetadata: + assert( numOptionValues <= RENDERER_MAX_ISAR_MD_INPUTS ); + for ( int16_t i = 0; i < numOptionValues; ++i ) + { + strncpy( args->inMetadataFilePaths[i], optionValues[i], POST_REND_MAX_CLI_ARG_LENGTH - 1 ); + } + args->numInMetadataFiles = numOptionValues; + break; + case CmdLnOptionId_outputFile: + assert( numOptionValues == 1 ); + strncpy( args->outputFilePath, optionValues[0], POST_REND_MAX_CLI_ARG_LENGTH - 1 ); + break; + case CmdLnOptionId_sampleRate: + assert( numOptionValues == 1 ); + args->sampleRate = (int32_t) ( strtol( optionValues[0], NULL, 10 ) * 1000 ); + if ( args->sampleRate == 0 ) + { + fprintf( stderr, "Invalid sampling rate specified\n" ); + exit( -1 ); + } + break; + case CmdLnOptionId_trajFile: + assert( numOptionValues == 1 ); + strncpy( args->headRotationFilePath, optionValues[0], POST_REND_MAX_CLI_ARG_LENGTH - 1 ); + break; + case CmdLnOptionId_SplitRendBFIFile: + assert( numOptionValues == 1 ); + strncpy( args->splitRendBFIFilePath, optionValues[0], POST_REND_MAX_CLI_ARG_LENGTH - 1 ); + break; + case CmdLnOptionId_complexityLevel: + assert( numOptionValues == 1 ); + args->complexityLevel = (int32_t) ( strtol( optionValues[0], NULL, 10 ) ); + if ( args->complexityLevel < ISAR_POST_REND_COMPLEXITY_LEVEL_ONE || args->complexityLevel > ISAR_POST_REND_COMPLEXITY_LEVEL_THREE ) + { + fprintf( stdout, "Invalid complexity level specified.\n" ); + exit( -1 ); + } + else if ( args->complexityLevel == ISAR_POST_REND_COMPLEXITY_LEVEL_ONE || args->complexityLevel == ISAR_POST_REND_COMPLEXITY_LEVEL_TWO ) + { + fprintf( stdout, "Complexity levels 1 and 2 will be defined after characterisation - default to level 3 (full functionality).\n" ); + } + break; + case CmdLnOptionId_noDelayCmp: + assert( numOptionValues == 0 ); + args->delayCompensationEnabled = false; + break; + case CmdLnOptionId_quietModeEnabled: + assert( numOptionValues == 0 ); + args->quietModeEnabled = true; + break; + case CmdLnOptionId_framing: + assert( numOptionValues == 1 ); + if ( !parseRenderFramesize( optionValues[0], &args->render_framesize ) ) + { + fprintf( stderr, "Unknown or invalid option for frame size: %s\n", optionValues[0] ); + exit( -1 ); + } + + break; + default: + assert( 0 && "This should be unreachable - all command line options should be explicitly handled." ); + break; + } + + return; +} + +static CmdlnArgs parseCmdlnArgs( + const int argc, + char **argv ) +{ + CmdlnArgs args = defaultArgs( argv[0] ); + + if ( CmdLnParser_parseArgs( argc, argv, cliOptions, numCliOptions, &args, parseOption ) != 0 ) + { + exit( -1 ); /* Error printout handled by failing function */ + } + + if ( !checkRequiredArgs( args ) ) + { + exit( -1 ); /* Error printout handled by failing function */ + } + + return args; +} + + +static void printSupportedAudioConfigs( void ) +{ + uint16_t i; + const char *supportedFormats[] = { + "BINAURAL (output only)", + "BINAURAL_SPLIT_PCM", + "BINAURAL_SPLIT_CODED", + }; + + fprintf( stdout, "Supported audio formats:\n" ); + for ( i = 0; i < sizeof( supportedFormats ) / sizeof( *supportedFormats ); i++ ) + { + fprintf( stdout, "%s\n", supportedFormats[i] ); + } + + return; +} + +/*--------------------------------------------------------------------------* + * convertInputBuffer() + * + * Convert input buffer from WAV/PCM file (int16_t, interleaved) to a format + * accepted by the renderer (float, packed) + *--------------------------------------------------------------------------*/ + +static void convertInputBuffer( + const int16_t *intBuffer, + const int16_t numIntSamplesPerChannel, + const int16_t numFloatSamplesPerChannel, + const int16_t numChannels, + float *floatBuffer ) +{ + int16_t chnl, smpl, i; + + i = 0; + + for ( smpl = 0; smpl < numFloatSamplesPerChannel; ++smpl ) + { + for ( chnl = 0; chnl < numChannels; ++chnl ) + { + if ( i < numIntSamplesPerChannel ) + { + floatBuffer[chnl * numFloatSamplesPerChannel + smpl] = (float) intBuffer[i]; + } + else + { + floatBuffer[chnl * numFloatSamplesPerChannel + smpl] = 0.f; + } + + ++i; + } + } + + return; +} + +/*--------------------------------------------------------------------------* + * convertOutputBuffer() + * + * Convert output buffer from the renderer (float, packed) to a format ready + * for writing to a WAV/PCM file (int16_t, interleaved) + *--------------------------------------------------------------------------*/ + +static void convertOutputBuffer( + const float *floatBuffer, + const int16_t numSamplesPerChannel, + const int16_t numChannels, + int16_t *intBuffer ) +{ + int16_t chnl, smpl, i; + float temp; + + i = 0; + + for ( smpl = 0; smpl < numSamplesPerChannel; ++smpl ) + { + for ( chnl = 0; chnl < numChannels; ++chnl ) + { + temp = floatBuffer[chnl * numSamplesPerChannel + smpl]; + temp = (float) floor( temp + 0.5f ); + if ( temp > ISAR_MAX16B_FLT ) + { + temp = ISAR_MAX16B_FLT; + } + else if ( temp < ISAR_MIN16B_FLT ) + { + temp = ISAR_MIN16B_FLT; + } + intBuffer[i] = (int16_t) temp; + + ++i; + } + } + + return; +} + +/*------------------------------------------------------------------------------------------* + * main() + * + * Main ISAR post renderer function for command-line interface + *------------------------------------------------------------------------------------------*/ + +int main( + int argc, + char **argv ) +{ + ISAR_POST_REND_HANDLE hIsarPostRend; + RotFileReader *headRotReader = NULL; + RotFileReader *externalOrientationFileReader = NULL; + SplitRendBFIFileReader *splitRendBFIReader = NULL; + AudioFileReader *audioReader = NULL; + AudioFileWriter *audioWriter; + int32_t inBufferSize; + int32_t outBufferSize; + int32_t bitsBufferSize; + int16_t *inpInt16Buffer; + float *inFloatBuffer; + int16_t *outInt16Buffer; + float *outFloatBuffer; + uint8_t *bitsBufferData = NULL; + IVAS_REND_AudioBuffer inBuffer; + IVAS_REND_AudioBuffer outBuffer; + ISAR_POST_REND_BitstreamBuffer bitsBuffer; + SplitFileReadWrite *hSplitRendFileReadWrite; + char audioFilePath[FILENAME_MAX]; + int16_t numSamplesRead; + int16_t delayNumSamples = -1; + int16_t delayNumSamples_orig = 0; + int16_t zeroPad = 0; + int16_t zeroPadToWrite = 0; + int32_t delayTimeScale = 0; + int16_t i, numChannels; + ivas_error error = IVAS_ERR_OK; + bool splitBinNeedsNewFrame = true; + +#ifdef WMOPS + reset_wmops(); + reset_mem( USE_BYTES ); +#endif + + hSplitRendFileReadWrite = NULL; + bitsBuffer.bits = NULL; + bitsBuffer.config.bitsRead = 0; + bitsBuffer.config.bitsWritten = 0; + bitsBuffer.config.bufLenInBytes = 0; + bitsBuffer.config.codec = ISAR_SPLIT_REND_CODEC_DEFAULT; + bitsBuffer.config.poseCorrection = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + bitsBuffer.config.codec_frame_size_ms = 5; + bitsBuffer.config.isar_frame_size_ms = 20; + bitsBuffer.config.lc3plusHighRes = 0; +#else + bitsBuffer.config.codec_frame_size_ms = 20; +#endif + + + CmdlnArgs args = parseCmdlnArgs( argc, argv ); + + convert_backslash( args.inputFilePath ); + convert_backslash( args.outputFilePath ); + convert_backslash( args.headRotationFilePath ); + + if ( !isEmptyString( args.headRotationFilePath ) ) + { + if ( RotationFileReader_open( args.headRotationFilePath, &headRotReader ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error opening file: %s\n", args.headRotationFilePath ); + exit( -1 ); + } + } + + if ( !isEmptyString( args.splitRendBFIFilePath ) ) + { + convert_backslash( args.splitRendBFIFilePath ); + SplitRendBFIFileReader_open( args.splitRendBFIFilePath, &splitRendBFIReader ); + } + +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + int32_t inFileSampleRate = 0; +#endif + strncpy( audioFilePath, args.inputFilePath, FILENAME_MAX - 1 ); + hSplitRendFileReadWrite = NULL; + if ( ( args.inConfig.numBinBuses > 0 ) && ( args.inConfig.binBuses[0].audioConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) + { + error = split_rend_reader_open( &hSplitRendFileReadWrite, + args.inMetadataFilePaths[0], + &bitsBuffer.config.codec, + &bitsBuffer.config.poseCorrection, + &bitsBuffer.config.codec_frame_size_ms +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + , + &bitsBuffer.config.isar_frame_size_ms, + &inFileSampleRate, + &bitsBuffer.config.lc3plusHighRes +#endif + ); + if ( error != IVAS_ERR_OK ) + { + fprintf( stderr, "Could not open split rend metadata file %s\n", args.inMetadataFilePaths[0] ); + exit( -1 ); + } + + if ( AudioFileReader_open( &audioReader, audioFilePath ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error opening file: %s\n", audioFilePath ); + exit( -1 ); + } + } + + /*if split renderer is running in post renderer mode*/ + if ( ( args.inConfig.numBinBuses > 0 ) && ( args.inConfig.binBuses[0].audioConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) ) + { + error = split_rend_reader_open( &hSplitRendFileReadWrite, + args.inputFilePath, + &bitsBuffer.config.codec, + &bitsBuffer.config.poseCorrection, + &bitsBuffer.config.codec_frame_size_ms +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + , + &bitsBuffer.config.isar_frame_size_ms, + &inFileSampleRate, + &bitsBuffer.config.lc3plusHighRes +#endif + ); + if ( error != IVAS_ERR_OK ) + { + fprintf( stderr, "Could not open split rend metadata file %s\n", args.inputFilePath ); + exit( -1 ); + } + audioReader = NULL; + } + +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS + int32_t inFileSampleRate = 0; +#endif + if ( audioReader != NULL ) + { + error = AudioFileReader_getSamplingRate( audioReader, &inFileSampleRate ); + } + else +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + if ( hSplitRendFileReadWrite == NULL ) +#endif + { + inFileSampleRate = args.sampleRate; + } + + switch ( error ) + { + case IVAS_ERR_OK: + /* If sampling rate not given on command line, use the one from SR file */ + if ( args.sampleRate == 0 ) + { + args.sampleRate = inFileSampleRate; + } + /* else if sampling rate given on command line, compare with wav file */ + else if ( inFileSampleRate != args.sampleRate ) + { + fprintf( stderr, "Sampling rate mismatch: %d Hz requested, but %d Hz found in file %s\n", args.sampleRate, inFileSampleRate, args.inputFilePath ); + exit( -1 ); + } + break; + case IVAS_ERR_SAMPLING_RATE_UNKNOWN: /* Returned when input is raw PCM */ + if ( args.sampleRate == 0 ) + { + fprintf( stderr, "Sampling rate must be specified on command line when using raw PCM input\n" ); + exit( -1 ); + } + break; + default: + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + + int16_t inFileNumChannels = 0; + if ( audioReader != NULL ) + { + error = AudioFileReader_getNumChannels( audioReader, &inFileNumChannels ); + if ( error != IVAS_ERR_OK && error != IVAS_ERR_NUM_CHANNELS_UNKNOWN ) + { + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + } + 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 ) + { + fprintf( stderr, "Error opening renderer handle: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + + /* === Configure === */ + if ( ( error = ISAR_POST_REND_InitConfig( hIsarPostRend, args.outConfig.audioConfig ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error in Renderer Config Init: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + + if ( args.inConfig.numBinBuses > 0 ) + { + if ( ( error = ISAR_REND_SetSplitRendBitstreamHeader( hIsarPostRend, + bitsBuffer.config.codec, + bitsBuffer.config.poseCorrection, + bitsBuffer.config.codec_frame_size_ms +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + , + bitsBuffer.config.isar_frame_size_ms, + bitsBuffer.config.lc3plusHighRes +#endif + ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error in getting split renderer bitstream header: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + } + + + ISAR_POST_REND_InputId splitBinIds[RENDERER_MAX_BIN_INPUTS]; + + for ( i = 0; i < RENDERER_MAX_BIN_INPUTS; i++ ) + { + splitBinIds[i] = 0u; + } + + for ( i = 0; i < args.inConfig.numBinBuses; ++i ) + { + if ( ( error = ISAR_POST_REND_AddInput( hIsarPostRend, args.inConfig.binBuses[i].audioConfig, &splitBinIds[i] ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + } + + const int16_t totalNumInChannels = getTotalNumInChannels( hIsarPostRend, splitBinIds ); + + if ( inFileNumChannels != 0 /* inFileNumChannels is 0 with raw PCM input */ && totalNumInChannels != inFileNumChannels ) + { + fprintf( stderr, "Number of channels in input file does not match selected configuration\n" ); + exit( -1 ); + } + + int16_t numOutChannels = 2; + + if ( AudioFileWriter_open( &audioWriter, args.outputFilePath, args.sampleRate, numOutChannels ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Failed to open file: %s\n", args.outputFilePath ); + exit( -1 ); + } + + inBufferSize = frameSize_smpls * totalNumInChannels; + outBufferSize = frameSize_smpls * numOutChannels; + inpInt16Buffer = malloc( inBufferSize * sizeof( int16_t ) ); + + inFloatBuffer = malloc( inBufferSize * sizeof( float ) ); + inBuffer.config.numSamplesPerChannel = (int16_t) frameSize_smpls; + outFloatBuffer = malloc( outBufferSize * sizeof( float ) ); + 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; + + outBuffer.config.is_cldfb = 0; + outBuffer.config.numChannels = (int16_t) numOutChannels; + outBuffer.data = outFloatBuffer; + + memset( outBuffer.data, 0, outBuffer.config.numSamplesPerChannel * outBuffer.config.numChannels * sizeof( float ) ); + + bitsBufferSize = SPLIT_REND_BITS_BUFF_SIZE; + + if ( bitsBufferSize > 0 ) + { + bitsBufferData = malloc( bitsBufferSize * sizeof( uint8_t ) ); + } + else + { + bitsBufferData = NULL; + } + + bitsBuffer.bits = bitsBufferData; + bitsBuffer.config.bitsRead = 0; + bitsBuffer.config.bitsWritten = 0; + bitsBuffer.config.bufLenInBytes = bitsBufferSize; + +#ifdef WMOPS + reset_stack(); + reset_wmops(); +#endif + + if ( !args.quietModeEnabled ) + { + fprintf( stdout, "\n------ Running the ISAR post renderer ------\n\n" ); + fprintf( stdout, "Frames processed: " ); + } + else + { + fprintf( stdout, "\n\n-- Start the ISAR post renderer (quiet mode) --\n\n" ); + } + + while ( 1 ) + { + int16_t num_in_channels; + num_in_channels = inBuffer.config.numChannels; + + numSamplesRead = 0; + if ( ( hSplitRendFileReadWrite != NULL ) && splitBinNeedsNewFrame ) + { + ivas_error error_tmp; + numSamplesRead = (int16_t) inBufferSize; + error_tmp = split_rend_read_bits_from_file( hSplitRendFileReadWrite, bitsBuffer.bits, &bitsBuffer.config.bitsRead, &bitsBuffer.config.bitsWritten ); + if ( error_tmp != IVAS_ERR_OK ) + { + if ( error_tmp == IVAS_ERR_END_OF_FILE ) + { + numSamplesRead = 0; + } + else + { + fprintf( stderr, "\nUnable to read from bitstream file!\n" ); + exit( -1 ); + } + } + } + + if ( audioReader != NULL ) + { + /* Read the input data */ + if ( ( error = AudioFileReader_read( audioReader, inpInt16Buffer, (int16_t) inBufferSize, &numSamplesRead ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError reading from file %s\n", audioFilePath ); + exit( -1 ); + } + } + + if ( numSamplesRead == 0 && splitBinNeedsNewFrame ) + { + /* end of input data */ + break; + } + + /* Convert from int to float and from interleaved to packed */ + convertInputBuffer( inpInt16Buffer, numSamplesRead, inBuffer.config.numSamplesPerChannel, num_in_channels, inFloatBuffer ); + + int16_t num_subframes, sf_idx; + num_subframes = (int16_t) args.render_framesize; + + /* Read from head rotation trajectory file if specified */ + if ( headRotReader != NULL ) + { + for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) + { + IVAS_QUATERNION headRot; + IVAS_VECTOR3 Pos; + + if ( ( error = HeadRotationFileReading( headRotReader, &headRot, &Pos ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error in Head Rotation File Reading: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + + if ( ( error = ISAR_POST_REND_SetHeadRotation( hIsarPostRend, headRot, Pos, DEFAULT_AXIS, sf_idx ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error setting Head Rotation: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + } + } + else + { + fprintf( stderr, "Head Rotation should be enabled in post renderer\n" ); + exit( -1 ); + } + + /* Read from split renderer bfi file if specified */ + if ( splitRendBFIReader != NULL && splitBinNeedsNewFrame ) + { + int16_t bfi; + if ( ( error = SplitRendBFIFileReading( splitRendBFIReader, &bfi ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error in SplitRendBFIFileReading(): %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + + if ( ( error = ISAR_POST_REND_SetSplitRendBFI( hIsarPostRend, bfi ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error in ISAR_POST_REND_SetSplitRendBFI(): %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + } + + for ( i = 0; i < args.inConfig.numBinBuses; ++i ) + { + if ( numSamplesRead > 0 ) + { + if ( ( error = ISAR_POST_REND_GetInputNumChannels( hIsarPostRend, splitBinIds[i], &numChannels ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + ISAR_POST_REND_ReadOnlyAudioBuffer tmpBuffer = getReadOnlySubBuffer( inBuffer, (int16_t) args.inConfig.binBuses[i].inputChannelIndex, numChannels ); + + if ( ( error = ISAR_POST_REND_FeedInputAudio( hIsarPostRend, splitBinIds[i], tmpBuffer ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + } + if ( splitBinNeedsNewFrame ) + { + if ( ( error = ISAR_POST_REND_FeedSplitBinauralBitstream( hIsarPostRend, splitBinIds[i], &bitsBuffer ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + } + } + + if ( ( error = ISAR_POST_REND_GetSplitBinauralSamples( hIsarPostRend, outBuffer, &splitBinNeedsNewFrame ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + + int16_t num_out_channels; + num_out_channels = outBuffer.config.numChannels; + + /* 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 ); + + if ( delayNumSamples == -1 ) + { + if ( args.delayCompensationEnabled ) + { + if ( ISAR_POST_REND_GetDelay( hIsarPostRend, &delayNumSamples, &delayTimeScale ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nUnable to get delay of renderer!\n" ); + exit( -1 ); + } + + if ( hSplitRendFileReadWrite != NULL ) + { + 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_orig = delayNumSamples; + } + else + { + delayNumSamples = 0; + } + zeroPad = delayNumSamples; + } + + if ( audioWriter != NULL ) + { + if ( delayNumSamples * num_out_channels < outBufferSize ) + { + if ( AudioFileWriter_write( audioWriter, &outInt16Buffer[delayNumSamples * num_out_channels], outBufferSize - ( delayNumSamples * num_out_channels ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error writing audio file %s\n", args.outputFilePath ); + exit( -1 ); + } + delayNumSamples = 0; + } + else + { + delayNumSamples -= (int16_t) ( outBufferSize / num_out_channels ); + } + } + + bitsBuffer.config.bitsRead = 0; + bitsBuffer.config.bitsWritten = 0; + + frame++; + if ( !args.quietModeEnabled ) + { + fprintf( stdout, "%-8d\b\b\b\b\b\b\b\b", frame ); + } + +#ifdef WMOPS + update_mem(); + update_wmops(); +#endif + } + + /* add zeros at the end to have equal length of synthesized signals */ + if ( audioWriter != NULL ) + { + for ( zeroPadToWrite = zeroPad; zeroPadToWrite > frameSize_smpls; zeroPadToWrite -= frameSize_smpls ) + { + memset( outInt16Buffer, 0, outBufferSize * sizeof( int16_t ) ); + if ( ( error = AudioFileWriter_write( audioWriter, outInt16Buffer, outBufferSize ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nOutput audio file writer error\n" ); + exit( -1 ); + } + } + + memset( outInt16Buffer, 0, zeroPadToWrite * outBuffer.config.numChannels * sizeof( int16_t ) ); + if ( ( error = AudioFileWriter_write( audioWriter, outInt16Buffer, zeroPadToWrite * outBuffer.config.numChannels ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nOutput audio file writer error\n" ); + exit( -1 ); + } + zeroPadToWrite = 0; + } + + if ( !args.quietModeEnabled && args.delayCompensationEnabled ) + { + fprintf( stdout, "\nRenderer delay: %-5u [samples] - Timescale: %5u\n", delayNumSamples_orig, delayTimeScale ); + } + + fprintf( stdout, "\n\nRendering of %d frames finished\n\n", frame ); + +#ifdef DEBUGGING + int32_t cnt_frames_limited, noClipping; + if ( ( cnt_frames_limited = ISAR_POST_REND_GetCntFramesLimited( hIsarPostRend ) ) > 0 ) + { + fprintf( stdout, "Limiter applied in %d frames.\n\n", cnt_frames_limited ); + } + if ( ( noClipping = ISAR_POST_REND_GetNoCLipping( hIsarPostRend ) ) > 0 ) + { + fprintf( stdout, "Clipping (saturation) detected: %d samples clipped!!!\n\n", noClipping ); + } +#endif + + /* === Close === */ + free( inpInt16Buffer ); + free( inFloatBuffer ); + free( outInt16Buffer ); + free( outFloatBuffer ); + + if ( bitsBufferData != NULL ) + { + free( bitsBufferData ); + } + + split_rend_reader_writer_close( &hSplitRendFileReadWrite ); + SplitRendBFIFileReader_close( &splitRendBFIReader ); + + AudioFileReader_close( &audioReader ); + AudioFileWriter_close( &audioWriter ); + RotationFileReader_close( &headRotReader ); + RotationFileReader_close( &externalOrientationFileReader ); + + ISAR_POST_REND_Close( &hIsarPostRend ); + +#ifdef DEBUGGING + dbgclose(); +#endif +#ifdef WMOPS + print_wmops(); + print_mem( NULL ); +#endif + + return 0; +} + + +#undef WMC_TOOL_SKIP + +#endif /* SPLIT_REND_WITH_HEAD_ROT */ diff --git a/lib_com/common_api_types.h b/lib_com/common_api_types.h index 132e829ed..55de10146 100644 --- a/lib_com/common_api_types.h +++ b/lib_com/common_api_types.h @@ -57,6 +57,12 @@ #define IVAS_MAX_PARAM_SPATIAL_SUBFRAMES 4 #define IVAS_ROOM_ABS_COEFF 6 +/* Maximum buffer length (per channel) in samples */ +#define MAX_BUFFER_LENGTH_PER_CHANNEL ( L_FRAME48k ) + +/* Frame size required when rendering to binaural */ +#define BINAURAL_RENDERING_FRAME_SIZE_MS 5 + /*----------------------------------------------------------------------------------* * Common API enum for output audio configurations *----------------------------------------------------------------------------------*/ @@ -200,9 +206,10 @@ typedef struct _IVAS_JBM_TRACE_DATA * Split rendering API constants, structures, and enums *----------------------------------------------------------------------------------*/ -#define IVAS_MAX_SPLIT_REND_BITRATE 768000 -#define IVAS_MAX_SPLIT_REND_BITS_BUFFER_SIZE_IN_BYTES ( ( ( (int32_t) IVAS_MAX_SPLIT_REND_BITRATE / IVAS_NUM_FRAMES_PER_SEC ) + 7 ) >> 3 ) -#define IVAS_SPLIT_REND_ADDITIONAL_BYTES_TO_READ 1 +#define ISAR_MAX_SPLIT_REND_BITRATE 768000 +#define ISAR_MAX_SPLIT_REND_BITS_BUFFER_SIZE_IN_BYTES ( ( ( (int32_t) ISAR_MAX_SPLIT_REND_BITRATE / IVAS_NUM_FRAMES_PER_SEC ) + 7 ) >> 3 ) +#define ISAR_SPLIT_REND_ADDITIONAL_BYTES_TO_READ 1 +#define SPLIT_REND_BITS_BUFF_SIZE ( ISAR_MAX_SPLIT_REND_BITS_BUFFER_SIZE_IN_BYTES + ISAR_SPLIT_REND_ADDITIONAL_BYTES_TO_READ ) typedef enum { @@ -214,64 +221,74 @@ typedef enum YAW_ROLL, PITCH_ROLL -} IVAS_SPLIT_REND_ROT_AXIS; +} ISAR_SPLIT_REND_ROT_AXIS; typedef enum { - IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE, - IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB, + ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE, + ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB, -} IVAS_SPLIT_REND_POSE_CORRECTION_MODE; +} ISAR_SPLIT_REND_POSE_CORRECTION_MODE; typedef enum { - IVAS_SPLIT_REND_CODEC_LCLD, - IVAS_SPLIT_REND_CODEC_LC3PLUS, - IVAS_SPLIT_REND_CODEC_DEFAULT, /* Will use LCLD for CLDFB rendering paths and LC3plus for TD rendering paths */ - IVAS_SPLIT_REND_CODEC_NONE + ISAR_SPLIT_REND_CODEC_LCLD, + ISAR_SPLIT_REND_CODEC_LC3PLUS, + ISAR_SPLIT_REND_CODEC_DEFAULT, /* Will use LCLD for CLDFB rendering paths and LC3plus for TD rendering paths */ + ISAR_SPLIT_REND_CODEC_NONE -} IVAS_SPLIT_REND_CODEC; +} ISAR_SPLIT_REND_CODEC; typedef enum { - IVAS_SPLIT_REND_RENDERER_SELECTION_CREND, - IVAS_SPLIT_REND_RENDERER_SELECTION_FASTCONV, - IVAS_SPLIT_REND_RENDERER_SELECTION_PARAMBIN, - IVAS_SPLIT_REND_RENDERER_SELECTION_TDREND, - IVAS_SPLIT_REND_RENDERER_SELECTION_DEFAULT, + ISAR_SPLIT_REND_RENDERER_SELECTION_CREND, + ISAR_SPLIT_REND_RENDERER_SELECTION_FASTCONV, + ISAR_SPLIT_REND_RENDERER_SELECTION_PARAMBIN, + ISAR_SPLIT_REND_RENDERER_SELECTION_TDREND, + ISAR_SPLIT_REND_RENDERER_SELECTION_DEFAULT, -} IVAS_SPLIT_REND_RENDERER_SELECTION; +} ISAR_SPLIT_REND_RENDERER_SELECTION; -typedef struct _IVAS_SPLIT_REND_BITS_DATA +typedef struct _ISAR_SPLIT_REND_BITS_DATA { uint8_t *bits_buf; int32_t buf_len; /*size of bits_buf in bytes. This field should be set by allocator of bits_buf*/ int32_t bits_written; int32_t bits_read; int16_t codec_frame_size_ms; - IVAS_SPLIT_REND_CODEC codec; - IVAS_SPLIT_REND_POSE_CORRECTION_MODE pose_correction; + ISAR_SPLIT_REND_CODEC codec; + ISAR_SPLIT_REND_POSE_CORRECTION_MODE pose_correction; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + int16_t isar_frame_size_ms; + int16_t lc3plus_highres; +#endif -} IVAS_SPLIT_REND_BITS_DATA, *IVAS_SPLIT_REND_BITS_HANDLE; +} ISAR_SPLIT_REND_BITS_DATA, *ISAR_SPLIT_REND_BITS_HANDLE; -typedef struct _IVAS_SPLIT_REND_CONFIG +typedef struct _ISAR_SPLIT_REND_CONFIG { - int32_t splitRendBitRate; /*Bit rate for split rendering mode, if "pcm_out" is set then "splitRendBitRate" is used as a limit for MD bitrate */ - int16_t hq_mode; /*High quality 3DOF mode with additional side information. Requires more pre-renditions. */ - int16_t dof; /*flag to specify if pose correction is needed for 1, 2 or 3 degree of freedoms*/ - /*The axis can be set dynamically per frame based on a file input */ - /*possible values: - 1 - (1dof correction. By default YAW correction) - 2 - (2dof correction. By default YAW and PITCH correction) - 3 - (3dof correction. By default YAW, PITCH and ROLL correction) - */ - int16_t codec_delay_ms; /*PLACEHOLDER (currently being ignored) : look ahead delay of the codec that is used to code BIN signal output of pre-renderer*/ - int16_t codec_frame_size_ms; /*Codec frame size in milliseconds, only relevant with LC3plus */ - IVAS_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode; - IVAS_SPLIT_REND_CODEC codec; - IVAS_SPLIT_REND_RENDERER_SELECTION rendererSelection; - -} IVAS_SPLIT_REND_CONFIG_DATA; + int32_t splitRendBitRate; /*Bit rate for split rendering mode, if "pcm_out" is set then "splitRendBitRate" is used as a limit for MD bitrate */ + int16_t hq_mode; /*High quality 3DOF mode with additional side information. Requires more pre-renditions. */ + int16_t dof; /*flag to specify if pose correction is needed for 1, 2 or 3 degree of freedoms*/ + /*The axis can be set dynamically per frame based on a file input */ + /*possible values: + 1 - (1dof correction. By default YAW correction) + 2 - (2dof correction. By default YAW and PITCH correction) + 3 - (3dof correction. By default YAW, PITCH and ROLL correction) + */ + int16_t codec_delay_ms; /*PLACEHOLDER (currently being ignored) : look ahead delay of the codec that is used to code BIN signal output of pre-renderer*/ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + int16_t isar_frame_size_ms; /* ISAR bit stream frame size in milliseconds */ +#endif + int16_t codec_frame_size_ms; /* Codec frame size in milliseconds, only relevant with LC3plus */ + ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode; + ISAR_SPLIT_REND_CODEC codec; + ISAR_SPLIT_REND_RENDERER_SELECTION rendererSelection; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + int16_t lc3plus_highres; +#endif + +} ISAR_SPLIT_REND_CONFIG_DATA, *ISAR_SPLIT_REND_CONFIG_HANDLE; #endif /*----------------------------------------------------------------------------------* @@ -314,10 +331,25 @@ typedef struct _IVAS_RENDER_CONFIG #endif IVAS_ROOM_ACOUSTICS_CONFIG_DATA roomAcoustics; #ifdef SPLIT_REND_WITH_HEAD_ROT - IVAS_SPLIT_REND_CONFIG_DATA split_rend_config; + ISAR_SPLIT_REND_CONFIG_DATA split_rend_config; #endif float directivity[IVAS_MAX_NUM_OBJECTS * 3]; } IVAS_RENDER_CONFIG_DATA, *IVAS_RENDER_CONFIG_HANDLE; +typedef struct +{ + int16_t numSamplesPerChannel; + int16_t numChannels; +#ifdef SPLIT_REND_WITH_HEAD_ROT + int16_t is_cldfb; +#endif +} IVAS_REND_AudioBufferConfig; + +typedef struct +{ + IVAS_REND_AudioBufferConfig config; + float *data; +} IVAS_REND_AudioBuffer; + #endif /* COMMON_API_TYPES_H */ diff --git a/lib_isar/isar_MSPred.c b/lib_isar/isar_MSPred.c new file mode 100644 index 000000000..76debae57 --- /dev/null +++ b/lib_isar/isar_MSPred.c @@ -0,0 +1,470 @@ +/****************************************************************************************************** + + (C) 2022-2023 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. + +*******************************************************************************************************/ + +#include "options.h" +#include +#ifdef SPLIT_REND_WITH_HEAD_ROT +#include "isar_lcld_prot.h" +#include "isar_prot.h" +#include "wmc_auto.h" + + +/*-------------------------------------------------------------------* + * Function _round() + * + * + *-------------------------------------------------------------------*/ + +static int32_t _round( + float val ) +{ + return ( val > 0.0f ? (int32_t) ( val + 0.5f ) : (int32_t) ( val - 0.5f ) ); +} + + +/*-------------------------------------------------------------------* + * Function quantPhase() + * + * + *-------------------------------------------------------------------*/ + +int32_t quantPhase( + float phase ) +{ + int32_t phaseQ; + + phaseQ = _round( phase * PHASE_QUANT_FACTOR ); + if ( phaseQ == PHASE_MAX_VAL ) + { + phaseQ = PHASE_MIN_VAL; + } + return phaseQ; +} + + +/*-------------------------------------------------------------------* + * Function cplxmult_lcld() + * + * + *-------------------------------------------------------------------*/ + +void cplxmult_lcld( + float *pr1, + float *pi1, + const float r2, + const float i2 ) +{ + float r1 = *pr1, i1 = *pi1; + + *pr1 = r1 * r2 - i1 * i2; + *pi1 = r1 * i2 + i1 * r2; + + return; +} + + +/*-------------------------------------------------------------------* + * Function requantPhase() + * + * + *-------------------------------------------------------------------*/ + +int32_t requantPhase( + int32_t phaseQ ) +{ + + if ( phaseQ >= PHASE_MAX_VAL ) + { + phaseQ += PHASE_MAX_VAL; + phaseQ %= ( 2 * PHASE_MAX_VAL ); + phaseQ -= PHASE_MAX_VAL; + } + else if ( phaseQ < PHASE_MIN_VAL ) + { + phaseQ -= PHASE_MAX_VAL; + phaseQ %= ( 2 * PHASE_MAX_VAL ); + phaseQ += PHASE_MAX_VAL; + if ( phaseQ == PHASE_MAX_VAL ) + { + phaseQ = PHASE_MIN_VAL; + } + } + + return phaseQ; +} + + +/*-------------------------------------------------------------------* + * Function quantPred() + * + * + *-------------------------------------------------------------------*/ + +int32_t quantPred( + const float pred ) +{ + int32_t predQ = _round( pred * PRED_QUANT_FACTOR ); + predQ = predQ > PRED_MAX_VAL ? PRED_MAX_VAL : predQ; + predQ = predQ < PRED_MIN_VAL ? PRED_MIN_VAL : predQ; + + return predQ; +} + + +/*-------------------------------------------------------------------* + * Function dequantPhase() + * + * + *-------------------------------------------------------------------*/ + +float dequantPhase( + const int32_t phaseQ ) +{ + return (float) phaseQ / PHASE_QUANT_FACTOR; +} + + +/*-------------------------------------------------------------------* + * Function dequantPred() + * + * + *-------------------------------------------------------------------*/ + +float dequantPred( int32_t predQ ) +{ + return (float) predQ / PRED_QUANT_FACTOR; +} + + +/*-------------------------------------------------------------------* + * Function PrepEncode() + * + * + *-------------------------------------------------------------------*/ + +int32_t PrepEncode( + int32_t *piQuant, + const int32_t *piMSFlags, + const int32_t numBands ) +{ + int32_t b, numMSBands = 0; + + for ( b = 0; b < numBands; b++ ) + { + if ( piMSFlags[b] ) + { + piQuant[numMSBands++] = piQuant[b]; + } + } + + for ( b = numMSBands; b < numBands; b++ ) + { + piQuant[b] = 0; + } + + return numMSBands; +} + + +/*-------------------------------------------------------------------* + * Function EncodePhase() + * + * + *-------------------------------------------------------------------*/ + +void EncodePhase( + int32_t *phaseQuant, + const int32_t numMSBands, + const int32_t diffDim ) +{ + int32_t b; + + if ( diffDim > 0 ) + { + int32_t tmp1, tmp2; + tmp1 = phaseQuant[0]; + for ( b = 1; b < numMSBands; b++ ) + { + tmp2 = phaseQuant[b]; + phaseQuant[b] -= tmp1; + tmp1 = tmp2; + } + } + + if ( diffDim > 1 ) + { + int32_t tmp1, tmp2; + tmp1 = phaseQuant[1]; + for ( b = 2; b < numMSBands; b++ ) + { + tmp2 = phaseQuant[b]; + phaseQuant[b] -= tmp1; + tmp1 = tmp2; + } + } + for ( b = 1; b < numMSBands; b++ ) + { + phaseQuant[b] = requantPhase( phaseQuant[b] ); + } + + return; +} + + +/*-------------------------------------------------------------------* + * Function DecodePhase() + * + * + *-------------------------------------------------------------------*/ + +void DecodePhase( + int32_t *phaseQuant, + const int32_t numMSBands, + const int32_t diffDim ) +{ + int32_t b; + + if ( diffDim > 1 ) + { + for ( b = 2; b < numMSBands; b++ ) + { + phaseQuant[b] += phaseQuant[b - 1]; + } + } + + if ( diffDim > 0 ) + { + for ( b = 1; b < numMSBands; b++ ) + { + phaseQuant[b] += phaseQuant[b - 1]; + } + } + + for ( b = 1; b < numMSBands; b++ ) + { + phaseQuant[b] = requantPhase( phaseQuant[b] ); + } + + return; +} + + +/*-------------------------------------------------------------------* + * Function EncodePredCoef() + * + * + *-------------------------------------------------------------------*/ + +int32_t EncodePredCoef( + int32_t *predQuant, + const int32_t numMSBands ) +{ + int32_t b, tmp1, tmp2; + + tmp1 = predQuant[0]; + for ( b = 1; b < numMSBands; b++ ) + { + tmp2 = predQuant[b]; + predQuant[b] -= tmp1; + tmp1 = tmp2; + } + + return numMSBands; +} + + +/*-------------------------------------------------------------------* + * Function DecodePredCoef() + * + * + *-------------------------------------------------------------------*/ + +void DecodePredCoef( + int32_t *phaseQuant, + const int32_t numMSBands ) +{ + int32_t b; + + for ( b = 1; b < numMSBands; b++ ) + { + phaseQuant[b] += phaseQuant[b - 1]; + } + + return; +} + + +/*-------------------------------------------------------------------* + * Function CountMSBits() + * + * + *-------------------------------------------------------------------*/ + +int32_t CountMSBits( + int32_t iNumBands, + const int32_t iMSMode, + const int32_t *piMSFlags, + const int32_t *piLRPhaseDiff, + const int32_t *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++ ) + { + piPhaseCopy[b] = 0; + piPredCopy[b] = 0; + } + + iBitsWritten += 2; /* iMSMode */ + for ( b = 0; b < iNumBands; b++ ) + { + iNumMSBands += ( piMSFlags[b] != 0 ); + } + + if ( iNumMSBands == 0 ) + { + return iBitsWritten; + } + + if ( iNumMSBands < iNumBands ) + { + iBitsWritten += iNumBands; /* piMSFlags */ + } + + if ( iMSMode < 3 ) + { + return iBitsWritten; + } + + /* prepare arrays for coding evaluation */ + for ( b = 0; b < iNumBands; b++ ) + { + piPhaseCopy[b] = piLRPhaseDiff[b]; + piPredCopy[b] = piMSPredCoef[b]; + } + + /* Differential Coding of Phase Data*/ + PrepEncode( piPhaseCopy, piMSFlags, iNumBands ); + PrepEncode( piPredCopy, piMSFlags, iNumBands ); + EncodePhase( piPhaseCopy, iNumMSBands, PHASE_DIFF_DIM ); + EncodePredCoef( piPredCopy, iNumMSBands ); + + iBitsWritten += 1; /* iMSPredAll */ + anyNonZero = 0; /* phase */ + for ( b = 0; b < iNumMSBands; b++ ) + { + if ( piPhaseCopy[b] != 0 ) + { + anyNonZero = 1; + break; + } + } + iBitsWritten++; /*anyNonZero Phase*/ + if ( anyNonZero ) + { + iBitsWritten += PHASE_BAND0_BITS; + for ( b = 1; b < iNumMSBands; b++ ) + { + int32_t tabIdx = piPhaseCopy[b] - ENV_DELTA_MIN; + iBitsWritten += c_aaiRMSEnvHuffEnc[tabIdx][0]; + } + } + anyNonZero = 0; /* prediction */ + for ( b = 0; b < iNumMSBands; b++ ) + { + if ( piPredCopy[b] != 0 ) + { + anyNonZero = 1; + break; + } + } + + iBitsWritten++; /* any nonZero Pred */ + if ( anyNonZero ) + { + iBitsWritten += PRED_BAND0_BITS; + for ( b = 1; b < iNumMSBands; b++ ) + { + int32_t tabIdx = piPredCopy[b] - ENV_DELTA_MIN; + iBitsWritten += c_aaiRMSEnvHuffEnc[tabIdx][0]; + } + } + + return iBitsWritten; +} + + +#ifdef DEBUG_WRITE_MS_PRED +void writeMSPred( + int32_t *phaseQuant, + int32_t *predQuant, + int32_t MSMode, + int32_t numMSBands, + int32_t numBands, + void *fid, + int32_t *piMsFlags ) +{ + int32_t b; + + fid = (FILE *) fid; + fprintf( fid, "%d %d", MSMode, numMSBands ); + for ( b = 0; b < numMSBands; b++ ) + { + fprintf( fid, " %d", phaseQuant[b] ); + } + for ( b = numMSBands; b < numBands; b++ ) + { + fprintf( fid, " %d", 0 ); + } + for ( b = 0; b < numMSBands; b++ ) + { + fprintf( fid, " %d", predQuant[b] ); + } + for ( b = numMSBands; b < numBands; b++ ) + { + fprintf( fid, " %d", 0 ); + } + for ( b = 0; b < numBands; b++ ) + { + fprintf( fid, " %d", piMsFlags[b] ); + } + fprintf( fid, "\n" ); + + return; +} +#endif +#endif diff --git a/lib_isar/isar_NoiseGen.c b/lib_isar/isar_NoiseGen.c new file mode 100644 index 000000000..f7dd512b6 --- /dev/null +++ b/lib_isar/isar_NoiseGen.c @@ -0,0 +1,57 @@ +/****************************************************************************************************** + + (C) 2022-2023 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. + +*******************************************************************************************************/ + +#include +#include "options.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT +#include +#include "prot.h" +#include "isar_lcld_prot.h" +#include "wmc_auto.h" + + +/*------------------------------------------------------------------------------------------* + * Function DeleteNoiseGen() + * + * + *------------------------------------------------------------------------------------------*/ + +void DeleteNoiseGen( NoiseGen *psNoiseGen ) +{ + free( psNoiseGen->pfNoiseBuffer ); + free( psNoiseGen ); + + return; +} + +extern float GetNoise( NoiseGen *psNoiseGen ); +#endif diff --git a/lib_isar/isar_PerceptualModel.c b/lib_isar/isar_PerceptualModel.c new file mode 100644 index 000000000..1a88a2943 --- /dev/null +++ b/lib_isar/isar_PerceptualModel.c @@ -0,0 +1,252 @@ +/****************************************************************************************************** + + (C) 2022-2023 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. + +*******************************************************************************************************/ + +#include +#include "options.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT +#include "isar_lcld_prot.h" +#include "prot.h" +#include "isar_rom_lcld_tables.h" +#include +#include "wmc_auto.h" + + +/*------------------------------------------------------------------------------------------* + * Local constants + *------------------------------------------------------------------------------------------*/ + +#define PERCEPTUAL_MODEL_SCALE ( 64 ) +#define PERCEPTUAL_MODEL_ALPHA_SCALE ( 614 ) +#define PERCEPTUAL_MODEL_ALPHA_INV_SCALE ( 6827 ) +#define PERCEPTUAL_MODEL_ALPHA_SHIFT ( 11 ) + + +/*------------------------------------------------------------------------------------------* + * Function LogAdd() + * + * + *------------------------------------------------------------------------------------------*/ + +static inline int32_t LogAdd( + const int32_t iVal1, + const int32_t iVal2 ) +{ + int32_t iRetVal; + + if ( iVal1 > iVal2 ) + { + iRetVal = iVal1 - iVal2; + iRetVal = ( iRetVal < ( LOG_ADD_TABLE_LENGTH - 1 ) ) ? iRetVal : ( LOG_ADD_TABLE_LENGTH - 1 ); + iRetVal = iVal1 + c_aiLogAddTable[iRetVal]; + } + else + { + iRetVal = iVal2 - iVal1; + iRetVal = ( iRetVal < ( LOG_ADD_TABLE_LENGTH - 1 ) ) ? iRetVal : ( LOG_ADD_TABLE_LENGTH - 1 ); + iRetVal = iVal2 + c_aiLogAddTable[iRetVal]; + } + + return iRetVal; +} + + +/*------------------------------------------------------------------------------------------* + * Function PerceptualModel() + * + * + *------------------------------------------------------------------------------------------*/ + +void PerceptualModel( + const int32_t iMaxQuantBands, + const int32_t *piRMSEnvelope, + int32_t *piExcitation, + int32_t *piSMR ) +{ + int32_t n; + + for ( n = 0; n < iMaxQuantBands; n++ ) + { + int32_t iSLOffset; + + piExcitation[n] = PERCEPTUAL_MODEL_SCALE * piRMSEnvelope[n] + c_aiBandwidthAdjust48[n]; + + /* Calculate sensation level offset */ + iSLOffset = c_aiDefaultTheta48[n] * ( piExcitation[n] - c_aiAbsoluteThresh48[n] ) >> PERCEPTUAL_MODEL_SLGAIN_SHIFT; + + /* Offset envelope by sensation level offset */ + piExcitation[n] -= iSLOffset; + + /* Convert to loudness domain (x^0.3) */ + piExcitation[n] = PERCEPTUAL_MODEL_ALPHA_SCALE * piExcitation[n] >> PERCEPTUAL_MODEL_ALPHA_SHIFT; + } + + /* Spread excitation function */ + for ( n = 0; n < iMaxQuantBands; n++ ) + { + int32_t k; + const int32_t *piSpread; + + piSpread = &c_aaiSpreadFunction48[n * MAX_BANDS_48]; + piSMR[n] = piExcitation[n] + piSpread[n]; + for ( k = 0; k < iMaxQuantBands; k++ ) + { + if ( k != n ) + { + piSMR[n] = LogAdd( piSMR[n], piExcitation[k] + piSpread[k] ); + } + } + } + + for ( n = 0; n < iMaxQuantBands; n++ ) + { + piSMR[n] = PERCEPTUAL_MODEL_ALPHA_INV_SCALE * piSMR[n] >> PERCEPTUAL_MODEL_ALPHA_SHIFT; + piSMR[n] = PERCEPTUAL_MODEL_SCALE * piRMSEnvelope[n] + c_aiBandwidthAdjust48[n] - piSMR[n]; + } + + return; +} + + +/*------------------------------------------------------------------------------------------* + * Function PerceptualModelStereo() + * + * + *------------------------------------------------------------------------------------------*/ + +void PerceptualModelStereo( + const int32_t iMaxQuantBands, + const int32_t *piMSFlags, + const int32_t *piRMSEnvelope0, + const int32_t *piRMSEnvelope1, + int32_t *piExcitation0, + int32_t *piExcitation1, + int32_t *piSMR0, + int32_t *piSMR1 ) +{ + int32_t n; + + for ( n = 0; n < iMaxQuantBands; n++ ) + { + int32_t iMaxRMSEnv; + int32_t iSLOffset; + + iMaxRMSEnv = piRMSEnvelope0[n]; + + piExcitation0[n] = PERCEPTUAL_MODEL_SCALE * iMaxRMSEnv + c_aiBandwidthAdjust48[n]; /* piRMSEnvelope0[n] */ + + /* Calculate sensation level offset */ + iSLOffset = c_aiDefaultTheta48[n] * ( piExcitation0[n] - c_aiAbsoluteThresh48[n] ) >> PERCEPTUAL_MODEL_SLGAIN_SHIFT; + + /* Offset envelope by sensation level offset */ + piExcitation0[n] -= iSLOffset; + + /* Convert to loudness domain (x^0.3) */ + piExcitation0[n] = PERCEPTUAL_MODEL_ALPHA_SCALE * piExcitation0[n] >> PERCEPTUAL_MODEL_ALPHA_SHIFT; + } + + /* Spread excitation function */ + for ( n = 0; n < iMaxQuantBands; n++ ) + { + int32_t k; + const int32_t *piSpread; + + piSpread = &c_aaiSpreadFunction48[n * MAX_BANDS_48]; + piSMR0[n] = piExcitation0[n] + piSpread[n]; + for ( k = 0; k < iMaxQuantBands; k++ ) + { + if ( k != n ) + { + piSMR0[n] = LogAdd( piSMR0[n], piExcitation0[k] + piSpread[k] ); + } + } + } + + for ( n = 0; n < iMaxQuantBands; n++ ) + { + int32_t iMaxRMSEnv; + int32_t iSLOffset; + + iMaxRMSEnv = piRMSEnvelope1[n]; + + piExcitation1[n] = PERCEPTUAL_MODEL_SCALE * iMaxRMSEnv + c_aiBandwidthAdjust48[n]; /* piRMSEnvelope1[n] */ + + /* Calculate sensation level offset */ + iSLOffset = c_aiDefaultTheta48[n] * ( piExcitation1[n] - c_aiAbsoluteThresh48[n] ) >> PERCEPTUAL_MODEL_SLGAIN_SHIFT; + + /* Offset envelope by sensation level offset */ + piExcitation1[n] -= iSLOffset; + + /* Convert to loudness domain (x^0.3) */ + piExcitation1[n] = PERCEPTUAL_MODEL_ALPHA_SCALE * piExcitation1[n] >> PERCEPTUAL_MODEL_ALPHA_SHIFT; + } + + /* Spread excitation function */ + for ( n = 0; n < iMaxQuantBands; n++ ) + { + int32_t k; + const int32_t *piSpread; + + piSpread = &c_aaiSpreadFunction48[n * MAX_BANDS_48]; + piSMR1[n] = piExcitation1[n] + piSpread[n]; + for ( k = 0; k < iMaxQuantBands; k++ ) + { + if ( k != n ) + { + piSMR1[n] = LogAdd( piSMR1[n], piExcitation1[k] + piSpread[k] ); + } + } + } + + for ( n = 0; n < iMaxQuantBands; n++ ) + { + if ( piMSFlags[n] == 1 ) + { + piSMR0[n] = ( piSMR0[n] > piSMR1[n] ) ? piSMR0[n] : piSMR1[n]; + piSMR1[n] = piSMR0[n]; + } + } + + for ( n = 0; n < iMaxQuantBands; n++ ) + { + piSMR0[n] = PERCEPTUAL_MODEL_ALPHA_INV_SCALE * piSMR0[n] >> PERCEPTUAL_MODEL_ALPHA_SHIFT; + piSMR0[n] = PERCEPTUAL_MODEL_SCALE * piRMSEnvelope0[n] + c_aiBandwidthAdjust48[n] - piSMR0[n]; + } + + for ( n = 0; n < iMaxQuantBands; n++ ) + { + piSMR1[n] = PERCEPTUAL_MODEL_ALPHA_INV_SCALE * piSMR1[n] >> PERCEPTUAL_MODEL_ALPHA_SHIFT; + piSMR1[n] = PERCEPTUAL_MODEL_SCALE * piRMSEnvelope1[n] + c_aiBandwidthAdjust48[n] - piSMR1[n]; + } + + return; +} +#endif diff --git a/lib_isar/isar_PredDecoder.c b/lib_isar/isar_PredDecoder.c new file mode 100644 index 000000000..423f45c07 --- /dev/null +++ b/lib_isar/isar_PredDecoder.c @@ -0,0 +1,462 @@ +/****************************************************************************************************** + + (C) 2022-2023 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. + +*******************************************************************************************************/ + +#include +#include "options.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT +#include +#include "prot.h" +#include "isar_prot.h" +#include "isar_lcld_prot.h" +#include "isar_rom_lcld_tables.h" +#include "wmc_auto.h" + +/*-------------------------------------------------------------------* + * Function CreatePredictionDecoder() + * + * + *-------------------------------------------------------------------*/ + +ivas_error CreatePredictionDecoder( + PredictionDecoder **psPredictionDecoder_out, + const int32_t iChannels, + const int32_t iNumBlocks ) +{ + int16_t n; + int16_t m; + PredictionDecoder *psPredictionDecoder = 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; + psPredictionDecoder->iNumBlocks = iNumBlocks; + psPredictionDecoder->iNumSubSets = LCLD_BLOCKS_PER_FRAME / psPredictionDecoder->iNumBlocks; + psPredictionDecoder->iSubSetId = 0; + /* PLC_IMPROVEMENT */ + if ( ( psPredictionDecoder->ppiDecodingFailedPrev = (int32_t **) malloc( sizeof( int32_t * ) * 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 ) + { + 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 ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD decoder Module \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 ) + { + 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 ) + { + 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 ) + { + 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++ ) + { + psPredictionDecoder->ppiDecodingUnresolved[n][k] = 0; + psPredictionDecoder->ppiDecodingFailed[n][k] = 0; + psPredictionDecoder->ppiDecodingFailedPrev[n][k] = 0; + } + } + if ( ( psPredictionDecoder->piPredChanEnable = (int32_t *) malloc( sizeof( int32_t ) * 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 ) + { + 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 ) + { + 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 ) + { + 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 ) + { + 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 ) + { + 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 ) + { + 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 ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD decoder Module \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 ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + for ( m = 0; m < LCLD_BANDS; m++ ) + { + psPredictionDecoder->ppiPredBandEnable[n][m] = 0; + } + if ( ( psPredictionDecoder->ppfA1Real[n] = (float *) malloc( sizeof( float ) * 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 ) + { + 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 ) + { + 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 ) + { + 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 ) + { + 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 ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionDecoder Module \n" ) ); + } + for ( m = 0; m < LCLD_BANDS; m++ ) + { + psPredictionDecoder->ppfPredStateReal[n][m] = 0; + psPredictionDecoder->ppfPredStateImag[n][m] = 0; + } + } + + /* pre-define these tables? */ + 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 ); + } + + 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_out = psPredictionDecoder; + + return IVAS_ERR_OK; +} + + +/*-------------------------------------------------------------------* + * Function DeletePredictionDecoder() + * + * + *-------------------------------------------------------------------*/ + +void DeletePredictionDecoder( + PredictionDecoder *psPredictionDecoder ) +{ + int32_t n; + + for ( n = 0; n < psPredictionDecoder->iChannels; n++ ) + { + free( psPredictionDecoder->ppiPredBandEnable[n] ); + free( psPredictionDecoder->ppfA1Real[n] ); + free( psPredictionDecoder->ppfA1Imag[n] ); + free( psPredictionDecoder->ppiA1Mag[n] ); + free( psPredictionDecoder->ppiA1Phase[n] ); + free( psPredictionDecoder->ppfPredStateReal[n] ); + free( psPredictionDecoder->ppfPredStateImag[n] ); + /* PLC_IMPROVEMENT */ + 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->ppiA1Mag ); + free( psPredictionDecoder->ppiA1Phase ); + free( psPredictionDecoder->ppfPredStateReal ); + free( psPredictionDecoder->ppfPredStateImag ); + /* PLC_IMPROVEMENT */ + free( psPredictionDecoder->ppiDecodingUnresolved ); + free( psPredictionDecoder->ppiDecodingFailed ); + free( psPredictionDecoder->ppiDecodingFailedPrev ); + + free( psPredictionDecoder ); + psPredictionDecoder = NULL; + + return; +} + +/*-------------------------------------------------------------------* + * Function ReadPredictors() + * + * + *-------------------------------------------------------------------*/ + +int32_t ReadPredictors( + 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 ) + { + psPredictionDecoder->iSubSetId = ISAR_SPLIT_REND_BITStream_read_int32( pBits, iSubSetBits ); + iBitsRead += iSubSetBits; + iNumPredBandBits = ( psPredictionDecoder->iNumSubSets >= 4 ? 4 : 5 ); + } + else + { + psPredictionDecoder->iSubSetId = 0; + } + for ( c = 0; c < psPredictionDecoder->iChannels; c++ ) + { + psPredictionDecoder->piPredChanEnable[c] = ISAR_SPLIT_REND_BITStream_read_int32( pBits, psPredictionDecoder->iNumSubSets ); + iBitsRead += (int16_t) psPredictionDecoder->iNumSubSets; + + if ( get_bit( psPredictionDecoder->piPredChanEnable[c], psPredictionDecoder->iSubSetId ) ) + { + int32_t b0 = psPredictionDecoder->iSubSetId; + int32_t bstep = psPredictionDecoder->iNumSubSets; + int32_t iNumPredBands; + + for ( b = b0; b < LCLD_BANDS; b += bstep ) + { + psPredictionDecoder->ppiPredBandEnable[c][b] = 0; + } + iNumPredBands = ISAR_SPLIT_REND_BITStream_read_int32( pBits, iNumPredBandBits ); + iBitsRead += iNumPredBandBits; + iNumPredBands = iNumPredBands * psPredictionDecoder->iNumSubSets + b0; + + for ( b = b0; b < iNumPredBands; b += bstep ) + { + psPredictionDecoder->ppiPredBandEnable[c][b] = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 1 ); + iBitsRead += 1; + + if ( psPredictionDecoder->ppiPredBandEnable[c][b] == 1 ) + { + int32_t iA1Mag; + int32_t iA1Phase; + float fA1Real; + float fA1Imag; + iA1Mag = ISAR_SPLIT_REND_BITStream_read_int32( pBits, PRED_QUNAT_FILTER_MAG_BITS ); + 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; + + psPredictionDecoder->ppiA1Mag[c][b] = iA1Mag; + psPredictionDecoder->ppiA1Phase[c][b] = iA1Phase + PRED_QUANT_FILTER_PHASE_MIN; + + fA1Real = psPredictionDecoder->pfMagLUT[iA1Mag] * psPredictionDecoder->pfP2RRealLUT[iA1Phase]; + fA1Imag = psPredictionDecoder->pfMagLUT[iA1Mag] * psPredictionDecoder->pfP2RImagLUT[iA1Phase]; + + psPredictionDecoder->ppfA1Real[c][b] = fA1Real; + psPredictionDecoder->ppfA1Imag[c][b] = fA1Imag; + } + } + } + } + + /* disable any inactive prediction bands */ + for ( c = 0; c < psPredictionDecoder->iChannels; c++ ) + { + int32_t set; + for ( set = 0; set < psPredictionDecoder->iNumSubSets; set++ ) + { + if ( !get_bit( psPredictionDecoder->piPredChanEnable[c], set ) ) + { + for ( b = set; b < LCLD_BANDS; b += psPredictionDecoder->iNumSubSets ) + { + psPredictionDecoder->ppiPredBandEnable[c][b] = 0; + } + } + } + } + + return iBitsRead; +} + +/* PLC_IMPROVEMENT */ +void SetDecodingPassed( PredictionDecoder *psPredictionDecoder ) +{ + int32_t n, ch; + for ( ch = 0; ch < psPredictionDecoder->iChannels; ch++ ) + { + for ( n = 0; n < psPredictionDecoder->iNumSubSets; n++ ) + { + psPredictionDecoder->ppiDecodingFailed[ch][n] = 0; + } + } +} +int32_t AnyDecodingUnresolved( PredictionDecoder *psPredictionDecoder ) +{ + int32_t n, ch; + for ( ch = 0; ch < psPredictionDecoder->iChannels; ch++ ) + { + for ( n = 0; n < psPredictionDecoder->iNumSubSets; n++ ) + { + if ( psPredictionDecoder->ppiDecodingUnresolved[ch][n] == 1 ) + { + return 1; + } + } + } + return 0; +} + +void UpdateDecodingFailedStatus( PredictionDecoder *psPredictionDecoder ) +{ + int32_t n, ch; + for ( ch = 0; ch < psPredictionDecoder->iChannels; ch++ ) + { + for ( n = 0; n < psPredictionDecoder->iNumSubSets; n++ ) + { + psPredictionDecoder->ppiDecodingFailedPrev[ch][n] = psPredictionDecoder->ppiDecodingFailed[ch][n]; + } + } +} + +void UpdateDecodingUnresolved( PredictionDecoder *psPredictionDecoder ) +{ + int32_t n, ch; + + int32_t iCurrentSubSet = psPredictionDecoder->iSubSetId; + + for ( ch = 0; ch < psPredictionDecoder->iChannels; ch++ ) + { + /* Prediction data always available for current subset */ + psPredictionDecoder->ppiDecodingUnresolved[ch][iCurrentSubSet] = 0; + + for ( n = 0; n < psPredictionDecoder->iNumSubSets; n++ ) + { + int32_t iSubSetActive = get_bit( psPredictionDecoder->piPredChanEnable[ch], n ); + if ( iSubSetActive == 0 ) + { + /* Prediction information available inactive subsets (e.g. no Prediction) */ + psPredictionDecoder->ppiDecodingUnresolved[ch][n] = 0; + } + } + } +} + +/*-------------------------------------------------------------------* + * Function ApplyInversePredictors() + * + * + *-------------------------------------------------------------------*/ + +void ApplyInversePredictors( + PredictionDecoder *psPredictionDecoder, + float ***pppfReal, + float ***pppfImag ) +{ + int32_t c; + for ( c = 0; c < psPredictionDecoder->iChannels; c++ ) + { + if ( psPredictionDecoder->piPredChanEnable[c] > 0 ) + { + int32_t b; + for ( b = 0; b < LCLD_BANDS; b++ ) + { + if ( 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 ) + { + fPrevReal = psPredictionDecoder->ppfPredStateReal[c][b]; + fPrevImag = psPredictionDecoder->ppfPredStateImag[c][b]; + } + + fA1Real = psPredictionDecoder->ppfA1Real[c][b]; + fA1Imag = psPredictionDecoder->ppfA1Imag[c][b]; + for ( n = 0; n < psPredictionDecoder->iNumBlocks; n++ ) + { + float fReal; + float fImag; + + fReal = pppfReal[c][n][b] - fA1Real * fPrevReal + fA1Imag * fPrevImag; + fImag = pppfImag[c][n][b] - fA1Real * fPrevImag - fA1Imag * fPrevReal; + + pppfReal[c][n][b] = fReal; + pppfImag[c][n][b] = fImag; + + fPrevReal = fReal; + fPrevImag = fImag; + } + psPredictionDecoder->ppfPredStateReal[c][b] = fPrevReal; + psPredictionDecoder->ppfPredStateImag[c][b] = fPrevImag; + } + } + } + } + + return; +} +#endif diff --git a/lib_isar/isar_PredEncoder.c b/lib_isar/isar_PredEncoder.c new file mode 100644 index 000000000..0433ff30e --- /dev/null +++ b/lib_isar/isar_PredEncoder.c @@ -0,0 +1,577 @@ +/****************************************************************************************************** + + (C) 2022-2023 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. + +*******************************************************************************************************/ + +#include +#include "options.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT +#include +#include "isar_lcld_prot.h" +#include "isar_rom_lcld_tables.h" +#include "prot.h" +#include "isar_prot.h" +#include "wmc_auto.h" + + +/*-------------------------------------------------------------------* + * Function activate_bit() + * + * + *-------------------------------------------------------------------*/ +static void activate_bit( + int32_t *state, + const int32_t bit_id ) +{ + ( *state ) |= ( 1 << bit_id ); +} + +/*-------------------------------------------------------------------* + * Function deactivate_bit() + * + * + *-------------------------------------------------------------------*/ + +static void deactivate_bit( + int32_t *state, + const int32_t bit_id ) +{ + ( *state ) &= ( ~( 1 << bit_id ) ); +} + +void UpdatePredictionSubSetId( PredictionEncoder *psPredictionEncoder ) +{ + if ( ++psPredictionEncoder->iSubSetId == psPredictionEncoder->iNumSubSets ) + { + psPredictionEncoder->iSubSetId = 0; + } +} + +/*-------------------------------------------------------------------* + * Function CreatePredictionEncoder() + * + * + *-------------------------------------------------------------------*/ + +ivas_error CreatePredictionEncoder( + PredictionEncoder **psPredictionEncoder_out, + const int32_t iChannels, + const int32_t iNumBlocks, + const int32_t iNumSubSets, + const int32_t iMaxNumPredBands ) +{ + int32_t 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; + psPredictionEncoder->iNumBlocks = iNumBlocks; + psPredictionEncoder->iSubSetId = 0; + psPredictionEncoder->iMaxNumPredBands = iMaxNumPredBands; + psPredictionEncoder->iNumSubSets = iNumSubSets; + + if ( ( psPredictionEncoder->piPredChanEnable = (int32_t *) malloc( sizeof( int32_t ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + + if ( ( psPredictionEncoder->piNumPredBands = (int32_t *) malloc( sizeof( int32_t ) * 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; + psPredictionEncoder->piNumPredBands[n] = 40; + } + + if ( ( psPredictionEncoder->ppiPredBandEnable = (int32_t **) malloc( sizeof( int32_t * ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + if ( ( psPredictionEncoder->ppfA1Real = (float **) malloc( sizeof( float * ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + if ( ( psPredictionEncoder->ppfA1Imag = (float **) malloc( sizeof( float * ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + if ( ( psPredictionEncoder->ppiA1Mag = (int32_t **) malloc( sizeof( int32_t * ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + if ( ( psPredictionEncoder->ppiA1Phase = (int32_t **) malloc( sizeof( int32_t * ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + if ( ( psPredictionEncoder->pppfInpBufReal = (float ***) malloc( sizeof( float ** ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + if ( ( psPredictionEncoder->pppfInpBufImag = (float ***) malloc( sizeof( float ** ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + if ( ( psPredictionEncoder->ppfInpPrevReal = (float **) malloc( sizeof( float * ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + if ( ( psPredictionEncoder->ppfInpPrevImag = (float **) malloc( sizeof( float * ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + if ( ( psPredictionEncoder->ppfPredStateReal = (float **) malloc( sizeof( float * ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + if ( ( psPredictionEncoder->ppfPredStateImag = (float **) malloc( sizeof( float * ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + if ( ( psPredictionEncoder->ppfPredStateRealTmp = (float **) malloc( sizeof( float * ) * iChannels ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + if ( ( psPredictionEncoder->ppfPredStateImagTmp = (float **) malloc( sizeof( float * ) * 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] = (int32_t *) malloc( sizeof( int32_t ) * LCLD_BANDS ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + if ( ( psPredictionEncoder->ppfA1Real[n] = (float *) malloc( sizeof( float ) * LCLD_BANDS ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + if ( ( psPredictionEncoder->ppfA1Imag[n] = (float *) malloc( sizeof( float ) * LCLD_BANDS ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + if ( ( psPredictionEncoder->ppiA1Mag[n] = (int32_t *) malloc( sizeof( int32_t ) * LCLD_BANDS ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + if ( ( psPredictionEncoder->ppiA1Phase[n] = (int32_t *) malloc( sizeof( int32_t ) * LCLD_BANDS ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + if ( ( psPredictionEncoder->pppfInpBufReal[n] = (float **) malloc( sizeof( float * ) * LCLD_PRED_WIN_LEN ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + if ( ( psPredictionEncoder->pppfInpBufImag[n] = (float **) malloc( sizeof( float * ) * 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[n][k] = (float *) malloc( LCLD_BANDS * sizeof( float ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + if ( ( psPredictionEncoder->pppfInpBufImag[n][k] = (float *) malloc( LCLD_BANDS * sizeof( float ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + set_zero( psPredictionEncoder->pppfInpBufReal[n][k], LCLD_BANDS ); + set_zero( psPredictionEncoder->pppfInpBufImag[n][k], LCLD_BANDS ); + } + if ( ( psPredictionEncoder->ppfPredStateReal[n] = (float *) malloc( LCLD_BANDS * sizeof( float ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + if ( ( psPredictionEncoder->ppfPredStateImag[n] = (float *) malloc( LCLD_BANDS * sizeof( float ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + set_zero( psPredictionEncoder->ppfPredStateReal[n], LCLD_BANDS ); + set_zero( psPredictionEncoder->ppfPredStateImag[n], LCLD_BANDS ); + + if ( ( psPredictionEncoder->ppfInpPrevReal[n] = (float *) malloc( LCLD_BANDS * sizeof( float ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + if ( ( psPredictionEncoder->ppfInpPrevImag[n] = (float *) malloc( LCLD_BANDS * sizeof( float ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + + set_zero( psPredictionEncoder->ppfInpPrevReal[n], LCLD_BANDS ); + set_zero( psPredictionEncoder->ppfInpPrevImag[n], LCLD_BANDS ); + + if ( ( psPredictionEncoder->ppfPredStateRealTmp[n] = (float *) malloc( LCLD_BANDS * sizeof( float ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + if ( ( psPredictionEncoder->ppfPredStateImagTmp[n] = (float *) malloc( LCLD_BANDS * sizeof( float ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); + } + set_zero( psPredictionEncoder->ppfPredStateRealTmp[n], LCLD_BANDS ); + set_zero( psPredictionEncoder->ppfPredStateImagTmp[n], LCLD_BANDS ); + for ( k = 0; k < LCLD_BANDS; k++ ) + { + psPredictionEncoder->ppiPredBandEnable[n][k] = 0; + psPredictionEncoder->ppfA1Real[n][k] = 0.0f; + psPredictionEncoder->ppfA1Imag[n][k] = 0.0f; + } + } + + *psPredictionEncoder_out = psPredictionEncoder; + + return IVAS_ERR_OK; +} + + +/*-------------------------------------------------------------------* + * Function DeletePredictionEncoder() + * + * + *-------------------------------------------------------------------*/ + +void DeletePredictionEncoder( + PredictionEncoder *psPredictionEncoder ) +{ + int32_t n; + for ( n = 0; n < psPredictionEncoder->iChannels; n++ ) + { + int32_t k; + free( psPredictionEncoder->ppiPredBandEnable[n] ); + free( psPredictionEncoder->ppfA1Real[n] ); + free( psPredictionEncoder->ppfA1Imag[n] ); + free( psPredictionEncoder->ppiA1Mag[n] ); + free( psPredictionEncoder->ppiA1Phase[n] ); + for ( k = 0; k < LCLD_PRED_WIN_LEN; k++ ) + { + free( psPredictionEncoder->pppfInpBufReal[n][k] ); + free( psPredictionEncoder->pppfInpBufImag[n][k] ); + } + free( psPredictionEncoder->pppfInpBufReal[n] ); + free( psPredictionEncoder->pppfInpBufImag[n] ); + free( psPredictionEncoder->ppfInpPrevReal[n] ); + free( psPredictionEncoder->ppfInpPrevImag[n] ); + free( psPredictionEncoder->ppfPredStateReal[n] ); + free( psPredictionEncoder->ppfPredStateImag[n] ); + free( psPredictionEncoder->ppfPredStateRealTmp[n] ); + free( psPredictionEncoder->ppfPredStateImagTmp[n] ); + } + free( psPredictionEncoder->piPredChanEnable ); + free( psPredictionEncoder->piNumPredBands ); + free( psPredictionEncoder->ppiPredBandEnable ); + free( psPredictionEncoder->ppfA1Real ); + free( psPredictionEncoder->ppfA1Imag ); + free( psPredictionEncoder->ppiA1Mag ); + free( psPredictionEncoder->ppiA1Phase ); + free( psPredictionEncoder->pppfInpBufReal ); + free( psPredictionEncoder->pppfInpBufImag ); + free( psPredictionEncoder->ppfInpPrevReal ); + free( psPredictionEncoder->ppfInpPrevImag ); + free( psPredictionEncoder->ppfPredStateReal ); + free( psPredictionEncoder->ppfPredStateImag ); + free( psPredictionEncoder->ppfPredStateRealTmp ); + free( psPredictionEncoder->ppfPredStateImagTmp ); + + + free( psPredictionEncoder ); + + return; +} + + +/*-------------------------------------------------------------------* + * Function ComputePredictors() + * + * + *-------------------------------------------------------------------*/ + +void ComputePredictors( + PredictionEncoder *psPredictionEncoder, + float ***pppfReal, + float ***pppfImag ) +{ + int32_t c; + + int32_t b0 = psPredictionEncoder->iSubSetId; + int32_t bstep = psPredictionEncoder->iNumSubSets; + int32_t iNumBlocks = psPredictionEncoder->iNumBlocks; + float ***pppfRealBuf; + float ***pppfImagBuf; + float pfEstPredBitGain[LCLD_BANDS] = { 0 }; + + if ( iNumBlocks < LCLD_PRED_WIN_LEN ) + { + pppfRealBuf = psPredictionEncoder->pppfInpBufReal; + pppfImagBuf = psPredictionEncoder->pppfInpBufImag; + for ( c = 0; c < psPredictionEncoder->iChannels; c++ ) + { + int32_t n; + for ( n = 0; n < 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 ); + } + 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 ); + } + } + } + else + { + pppfRealBuf = pppfReal; + pppfImagBuf = pppfImag; + } + + for ( c = 0; c < psPredictionEncoder->iChannels; c++ ) + { + int32_t b; + for ( b = b0; b < psPredictionEncoder->iMaxNumPredBands; b += bstep ) + { + int32_t n; + float fGain = 0.0; + float fBitGain = 0.0; + float *pfRxxReal; + float *pfRxxImag; + float fA1Real; + float fA1Imag; + int32_t iA1Mag; + int32_t iA1Phase; + + pfRxxReal = psPredictionEncoder->pfRxxReal; + pfRxxImag = psPredictionEncoder->pfRxxImag; + + pfRxxReal[0] = 0.0; + pfRxxImag[0] = 0.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] ); + } + + pfRxxReal[1] = 0.0; + pfRxxImag[1] = 0.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] ); + } + + if ( pfRxxReal[0] > 1e-12f ) + { + float fA1Mag; + float fA1Phase; + float fGain2; + float fBitGain2; + int32_t iNumBlocksPerPredCoef = min( iNumBlocks * psPredictionEncoder->iNumSubSets, LCLD_PRED_WIN_LEN ); + + const float fMagScale = ( 2.0f * (float) ( 1 << ( PRED_QUNAT_FILTER_MAG_BITS ) ) + 1.0f ) / M_PI; + const float fInvMagScale = M_PI / ( 2.0f * (float) ( 1 << ( PRED_QUNAT_FILTER_MAG_BITS ) ) + 1.0f ); + const float fPhaseScale = (float) ( 1 << ( PRED_QUANT_FILTER_PHASE_BITS - 1 ) ) / M_PI; + const float fInvPhaseScale = M_PI / (float) ( 1 << ( PRED_QUANT_FILTER_PHASE_BITS - 1 ) ); + + /* Compute filter coefficeints */ + fA1Real = -pfRxxReal[1] / pfRxxReal[0]; + fA1Imag = -pfRxxImag[1] / pfRxxReal[0]; + + /* 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 ); + fA1Mag = sqrtf( fA1Real * fA1Real + fA1Imag * fA1Imag ); + fA1Mag = fMagScale * asinf( fA1Mag ); + iA1Mag = (int32_t) ( fA1Mag + 0.5f ); + 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 ); + + fA1Phase = atan2f( fA1Imag, fA1Real ); + 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; + 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 ); + fGain = ( fGain < fGain2 ) ? fGain : fGain2; + fBitGain = ( fBitGain < fBitGain2 ) ? fBitGain : fBitGain2; + } + else + { + fA1Real = 0.0f; + fA1Imag = 0.0f; + iA1Mag = 0; + iA1Phase = 0; + fGain = -10.0f; + } + + pfEstPredBitGain[b] = fBitGain; + psPredictionEncoder->ppiPredBandEnable[c][b] = ( fBitGain > 0.0f ); + psPredictionEncoder->ppfA1Real[c][b] = fA1Real; + psPredictionEncoder->ppfA1Imag[c][b] = fA1Imag; + psPredictionEncoder->ppiA1Mag[c][b] = iA1Mag; + psPredictionEncoder->ppiA1Phase[c][b] = iA1Phase; + } + + { + float fBestCost; + int32_t iPredBands; + float fBitGain; + int32_t iPredChanEnable = 0; + + fBestCost = 0.0; + iPredBands = 0; + fBitGain = -7.0; + for ( b = b0; b < psPredictionEncoder->iMaxNumPredBands; b += bstep ) + { + fBitGain -= 1.0; + if ( psPredictionEncoder->ppiPredBandEnable[c][b] == 1 ) + { + fBitGain += pfEstPredBitGain[b]; + } + if ( fBitGain > fBestCost ) + { + fBestCost = fBitGain; + iPredBands = b; + iPredChanEnable = 1; + } + } + + if ( 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; + } + } + } +} + + +/*-------------------------------------------------------------------* + * Function ApplyForwardPredictors() + * + * + *-------------------------------------------------------------------*/ + +/*-------------------------------------------------------------------* + * Function WritePredictors() + * + * + *-------------------------------------------------------------------*/ + +int32_t 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 ); + + /* number of subsets */ + ISAR_SPLIT_REND_BITStream_write_int32( pBits, iNumSubSets - 1, iSubSetBits ); /* otherwise use default */ + iBitsWritten += iSubSetBits; + + if ( iNumSubSets > 1 ) + { + /* write current subset */ + ISAR_SPLIT_REND_BITStream_write_int32( pBits, iSubSetId, iSubSetBits ); + iBitsWritten += iSubSetBits; + iNumPredBandBits = ( iNumSubSets >= 4 ? 4 : 5 ); + } + + for ( c = 0; c < psPredictionEncoder->iChannels; c++ ) + { + int32_t b; + int32_t b0 = iSubSetId; + + ISAR_SPLIT_REND_BITStream_write_int32( pBits, psPredictionEncoder->piPredChanEnable[c], iNumSubSets ); + iBitsWritten += iNumSubSets; + + if ( get_bit( psPredictionEncoder->piPredChanEnable[c], iSubSetId ) ) + { + int32_t iNumPredBands = ( psPredictionEncoder->piNumPredBands[c] - b0 ) / iNumSubSets; + + ISAR_SPLIT_REND_BITStream_write_int32( pBits, iNumPredBands, iNumPredBandBits ); + iBitsWritten += iNumPredBandBits; + + for ( b = b0; b < psPredictionEncoder->piNumPredBands[c]; b += iNumSubSets ) + { + ISAR_SPLIT_REND_BITStream_write_int32( pBits, psPredictionEncoder->ppiPredBandEnable[c][b], 1 ); + iBitsWritten += 1; + + if ( psPredictionEncoder->ppiPredBandEnable[c][b] == 1 ) + { + int32_t iA1Mag; + int32_t iA1Phase; + + iA1Mag = psPredictionEncoder->ppiA1Mag[c][b]; + iA1Phase = 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; + + ISAR_SPLIT_REND_BITStream_write_int32( pBits, iA1Phase, PRED_QUANT_FILTER_PHASE_BITS ); + iBitsWritten += PRED_QUANT_FILTER_PHASE_BITS; + } + } + } + } + + return iBitsWritten; +} +#endif diff --git a/lib_isar/isar_RMSEnvGrouping.c b/lib_isar/isar_RMSEnvGrouping.c new file mode 100644 index 000000000..1a0b3aa11 --- /dev/null +++ b/lib_isar/isar_RMSEnvGrouping.c @@ -0,0 +1,727 @@ +/****************************************************************************************************** + + (C) 2022-2023 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. + +*******************************************************************************************************/ + +#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 "wmc_auto.h" + + +/*-------------------------------------------------------------------* + * 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 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, +}; + +typedef struct GMNODE +{ + int32_t iGroupStart; + int32_t iGroupLength; + float *pfMergedEnergydB; + int32_t *piQRMSEnvelope; + + int32_t iGroupRMSEnvelopeCost; + float fGroupSNRPenalty; + + struct GMNODE *psNext; +} GMNode; + +struct RMS_ENVELOPE_GROUPING +{ + int32_t iNumBlocks; + int32_t iMaxGroups; + float **ppfBandEnergy; + float **ppfBandEnergydB; + float **ppfWeight; + GMNode *psGMNodes; +}; + + +/*-------------------------------------------------------------------* + * Function CreateRMSEnvelopeGrouping() + * + * + *-------------------------------------------------------------------*/ + +RMSEnvelopeGrouping *CreateRMSEnvelopeGrouping( + const int32_t iNumBlocks ) +{ + int32_t n; + + RMSEnvelopeGrouping *psRMSEnvelopeGrouping; + + psRMSEnvelopeGrouping = (RMSEnvelopeGrouping *) malloc( sizeof( RMSEnvelopeGrouping ) ); + psRMSEnvelopeGrouping->iNumBlocks = iNumBlocks; + + psRMSEnvelopeGrouping->iMaxGroups = iNumBlocks >> 1; + + 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->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].iGroupRMSEnvelopeCost = -1; + psRMSEnvelopeGrouping->psGMNodes[n].fGroupSNRPenalty = -1.0; + } + + return psRMSEnvelopeGrouping; +} + + +/*-------------------------------------------------------------------* + * Function DeleteRMSEnvelopeGrouping() + * + * + *-------------------------------------------------------------------*/ + +void DeleteRMSEnvelopeGrouping( + RMSEnvelopeGrouping *psRMSEnvelopeGrouping ) +{ + int32_t n; + + for ( n = 0; n < psRMSEnvelopeGrouping->iNumBlocks; n++ ) + { + free( psRMSEnvelopeGrouping->ppfBandEnergy[n] ); + free( psRMSEnvelopeGrouping->ppfBandEnergydB[n] ); + free( psRMSEnvelopeGrouping->ppfWeight[n] ); + } + free( psRMSEnvelopeGrouping->ppfBandEnergy ); + free( psRMSEnvelopeGrouping->ppfBandEnergydB ); + free( psRMSEnvelopeGrouping->ppfWeight ); + + for ( n = 0; n < psRMSEnvelopeGrouping->iNumBlocks; n++ ) + { + free( psRMSEnvelopeGrouping->psGMNodes[n].pfMergedEnergydB ); + free( psRMSEnvelopeGrouping->psGMNodes[n].piQRMSEnvelope ); + } + free( psRMSEnvelopeGrouping->psGMNodes ); + + free( psRMSEnvelopeGrouping ); + + return; +} + + +/*-------------------------------------------------------------------* + * Function ComputeBandEnergy() + * + * + *-------------------------------------------------------------------*/ + +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 ) +{ + int32_t n; + + for ( n = 0; n < iChannels; n++ ) + { + int32_t k; + int32_t iChanOffset; + + iChanOffset = n * iNumBands; + for ( k = 0; k < iNumBlocks; k++ ) + { + int32_t b; + int32_t iFBOffset; + float fMaxWeight; + + iFBOffset = 0; + fMaxWeight = 0.0f; + for ( b = 0; b < iNumBands; b++ ) + { + int32_t m; + float fEnergy = 1e-12f; + float fWeight; + + for ( m = 0; m < piBandwidths[b]; m++ ) + { + fEnergy += ( pppfReal[n][k][iFBOffset] * pppfReal[n][k][iFBOffset] + pppfImag[n][k][iFBOffset] * pppfImag[n][k][iFBOffset] ); + 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; + +#ifdef APPLY_TEMPORAL_SMOOTHING + if ( k > 0 ) + { + float fSmoothEnergy; + fSmoothEnergy = 0.7f * ppfBandEnergy[k - 1][iChanOffset + b] + 0.3f * fEnergy; + + fEnergy = ( fEnergy > fSmoothEnergy ) ? fEnergy : fSmoothEnergy; + } +#endif + fEnergy = 10.0f * log10f( fEnergy ); + ppfBandEnergydB[k][iChanOffset + b] = fEnergy; + } + for ( b = 0; b < iNumBands; b++ ) + { + ppfWeight[k][iChanOffset + b] /= fMaxWeight; + } + } + } + + 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 ) +{ + int32_t b; + float fInvGroupSize = 1.0f / (float) iGroupLength; + + 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++ ) + { + fGroupEnergy += ppfBandEnergy[n][b]; + } + 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;*/ + + pfMergedEnergydB[b] = fGroupEnergy; + piQRMSEnvelope[b] = iQRMSEnvelope; + } + + return; +} + + +/*-------------------------------------------------------------------* + * Function ComputeRMSEnvelopeBits() + * + * + *-------------------------------------------------------------------*/ + +static int32_t ComputeRMSEnvelopeBits( + const int32_t iChannels, + const int32_t iNumBands, + const int32_t *piQRMSEnevelope ) +{ + int32_t n; + int32_t iRMSEnvelopeBits = 0; + int32_t iChanOffset = 0; + + for ( n = 0; n < iChannels; n++ ) + { + int32_t b; + int32_t iLastRMSVal; + + iRMSEnvelopeBits += ENV0_BITS; + iLastRMSVal = piQRMSEnevelope[iChanOffset]; + for ( b = 1; b < iNumBands; b++ ) + { + int32_t iDelta; + + iDelta = 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]; + + iLastRMSVal = piQRMSEnevelope[iChanOffset + b]; + } + + 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 ) +{ + int32_t n; + int32_t iChanOffset; + float fSNRPenalty = 0.0; + + iChanOffset = 0; + for ( n = 0; n < iChannels; n++ ) + { + int32_t 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++ ) + { + float fDeltadB; + + fDeltadB = fRMSVal - ppfBandEnergydB[k][iChanOffset + b]; + if ( fDeltadB < -9.0309f ) + { + fSNRPenalty += 1e10f; /* Some large number to prevent clipping*/ + } + else /*if(fDeltadB < 0.0)*/ + { + fSNRPenalty += fabsf( c_fiDefaultTheta48[b] * fDeltadB - fDeltadB ) * 2.0f * (float) piBandwidths[b] / 6.0f; + } + } + } + + iChanOffset += iNumBands; + } + + return fSNRPenalty; +} + + +/*-------------------------------------------------------------------* + * Function TryMerge2() + * + * + *-------------------------------------------------------------------*/ + +static float TryMerge2( + const int32_t iChannels, + const int32_t iNumBands, + const int32_t *piBandwidths, + float **ppfBandEnergy, + float **ppfBandEnergydB, + GMNode *psGMNode1, + GMNode *psGMNode2 ) +{ + int32_t iRMSEnvBits1; + int32_t iRMSEnvBits2; + int32_t iRMSEnvBitsMerged; + float fSNRPenalty1; + float fSNRPenalty2; + float fSNRPenaltyMerged; + float fMergedCost = 0.0; + + /* First compute current RMS Envelope for each group */ + if ( psGMNode1->iGroupRMSEnvelopeCost == -1 || psGMNode1->fGroupSNRPenalty == -1.0 ) + { + ComputeMergeRMS( iNumBands * iChannels, psGMNode1->iGroupStart, psGMNode1->iGroupLength, ppfBandEnergy, psGMNode1->pfMergedEnergydB, psGMNode1->piQRMSEnvelope ); + + iRMSEnvBits1 = ComputeRMSEnvelopeBits( iChannels, iNumBands, psGMNode1->piQRMSEnvelope ); + + fSNRPenalty1 = ComputeSNRPenalty( iChannels, iNumBands, piBandwidths, psGMNode1->iGroupStart, psGMNode1->iGroupLength, ppfBandEnergydB, psGMNode1->piQRMSEnvelope ); + + psGMNode1->iGroupRMSEnvelopeCost = iRMSEnvBits1; + psGMNode1->fGroupSNRPenalty = fSNRPenalty1; + } + else + { + iRMSEnvBits1 = psGMNode1->iGroupRMSEnvelopeCost; + fSNRPenalty1 = psGMNode1->fGroupSNRPenalty; + } + + if ( psGMNode2->iGroupRMSEnvelopeCost == -1 || psGMNode2->fGroupSNRPenalty == -1.0 ) + { + ComputeMergeRMS( iNumBands * iChannels, psGMNode2->iGroupStart, psGMNode2->iGroupLength, ppfBandEnergy, psGMNode2->pfMergedEnergydB, psGMNode2->piQRMSEnvelope ); + + iRMSEnvBits2 = ComputeRMSEnvelopeBits( iChannels, iNumBands, psGMNode2->piQRMSEnvelope ); + + fSNRPenalty2 = ComputeSNRPenalty( iChannels, iNumBands, piBandwidths, psGMNode2->iGroupStart, psGMNode2->iGroupLength, ppfBandEnergydB, psGMNode2->piQRMSEnvelope ); + + psGMNode2->iGroupRMSEnvelopeCost = iRMSEnvBits2; + psGMNode2->fGroupSNRPenalty = fSNRPenalty2; + } + else + { + iRMSEnvBits2 = psGMNode2->iGroupRMSEnvelopeCost; + fSNRPenalty2 = psGMNode2->fGroupSNRPenalty; + } + + /* Compute the merged group */ + ComputeMergeRMS( iNumBands * iChannels, psGMNode1->iGroupStart, psGMNode1->iGroupLength + psGMNode2->iGroupLength, ppfBandEnergy, psGMNode1->pfMergedEnergydB, psGMNode1->piQRMSEnvelope ); + + /* Compute the RMS Envelope cost for merged group */ + iRMSEnvBitsMerged = ComputeRMSEnvelopeBits( iChannels, iNumBands, psGMNode1->piQRMSEnvelope ); + + /* 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; +} + +/*-------------------------------------------------------------------* + * Function ComputeGreedyGroups3() + * + * + *-------------------------------------------------------------------*/ + +static void ComputeGreedyGroups3( + RMSEnvelopeGrouping *psRMSEnvelopeGrouping, + const int32_t iChannels, + const int32_t iNumBands, + const int32_t *piBandwidths, + const int32_t iMaxGroups ) +{ + + int32_t iDone = 0; + int32_t iNumGroups = psRMSEnvelopeGrouping->iMaxGroups; + + while ( iDone == 0 ) + { + GMNode *psGMNode; + GMNode *psBestGMNode; + float fBestMergeCost; + + fBestMergeCost = 1e20f; + psGMNode = &psRMSEnvelopeGrouping->psGMNodes[0]; + psBestGMNode = NULL; + while ( psGMNode->psNext != NULL ) + { + float fMergeCost; + + fMergeCost = TryMerge2( iChannels, iNumBands, piBandwidths, psRMSEnvelopeGrouping->ppfBandEnergy, psRMSEnvelopeGrouping->ppfBandEnergydB, psGMNode, psGMNode->psNext ); + + if ( fMergeCost < fBestMergeCost ) + { + fBestMergeCost = fMergeCost; + psBestGMNode = psGMNode; + } + + psGMNode = psGMNode->psNext; + } + + if ( fBestMergeCost > 0.0 && iNumGroups <= iMaxGroups ) + { + iDone++; + } + else if ( psBestGMNode != NULL && psBestGMNode->psNext != NULL ) + { + psBestGMNode->iGroupLength += psBestGMNode->psNext->iGroupLength; + psBestGMNode->iGroupRMSEnvelopeCost = -1; + psBestGMNode->fGroupSNRPenalty = -1.0; + psBestGMNode->psNext = psBestGMNode->psNext->psNext; + iNumGroups--; + } + else + { + 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 ) +{ + int32_t n; + + for ( n = 0; n < iChannels; n++ ) + { + int32_t b; + int32_t iChanOffset; + + iChanOffset = n * iNumBands; + for ( b = 0; b < iNumBands; b++ ) + { + int32_t k; + int32_t iBlockOffset; + + iBlockOffset = 0; + for ( k = 0; k < iNumGroups; k++ ) + { + int32_t m; + float fGroupEnergy; + fGroupEnergy = 0.0; + for ( m = 0; m < piGroupLengths[k]; m++ ) + { + fGroupEnergy += ppfBandEnergy[iBlockOffset][b + iChanOffset]; + 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; + } + } + } + + return; +} + + +/*-------------------------------------------------------------------* + * Function LimitRMSEnvelope() + * + * + *-------------------------------------------------------------------*/ + +static void LimitRMSEnvelope( + const int32_t iBandCount, + const int32_t iRMSDeltaMax, + const int32_t iRMSDeltaMin, + int32_t *piRMSEnvelope ) +{ + int32_t iBand; + int32_t iLastSCF; + + /* Increase low envelope values to ensure that the scale factors traces the large values correctly (checking for max deltas) */ + iLastSCF = piRMSEnvelope[iBandCount - 1]; + for ( iBand = iBandCount - 2; iBand > -1; iBand-- ) + { + int32_t iDelta; + + iDelta = iLastSCF - piRMSEnvelope[iBand]; + + if ( iDelta > iRMSDeltaMax ) + { +#ifdef DEBUG_VERBOSE + printf( "WARNING RMS envelope delta limited\n" ); +#endif + piRMSEnvelope[iBand] += ( iDelta - iRMSDeltaMax ); + } + + iLastSCF = piRMSEnvelope[iBand]; + } + + /* 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++ ) + { + int32_t iDelta; + + iDelta = piRMSEnvelope[iBand] - iLastSCF; + + if ( iDelta < iRMSDeltaMin ) + { +#ifdef DEBUG_VERBOSE + printf( "WARNING RMS envelope delta limited\n" ); +#endif + piRMSEnvelope[iBand] += ( iRMSDeltaMin - iDelta ); + } + + iLastSCF = piRMSEnvelope[iBand]; + } + + 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 ) +{ + int32_t n; + GMNode *psGMNode; + + /* Compute Band Energies */ + ComputeBandEnergy( iChannels, psRMSEnvelopeGrouping->iNumBlocks, iNumBands, piBandwidths, pppfReal, pppfImag, psRMSEnvelopeGrouping->ppfBandEnergy, psRMSEnvelopeGrouping->ppfBandEnergydB, psRMSEnvelopeGrouping->ppfWeight ); + + /* Init GMNodes */ + psRMSEnvelopeGrouping->psGMNodes[0].iGroupStart = 0; + psRMSEnvelopeGrouping->psGMNodes[0].iGroupLength = 2; + psRMSEnvelopeGrouping->psGMNodes[0].psNext = NULL; + psRMSEnvelopeGrouping->psGMNodes[0].iGroupRMSEnvelopeCost = -1; + psRMSEnvelopeGrouping->psGMNodes[0].fGroupSNRPenalty = -1.0f; + + for ( n = 1; n < psRMSEnvelopeGrouping->iMaxGroups; n++ ) + { + psRMSEnvelopeGrouping->psGMNodes[n - 1].psNext = &psRMSEnvelopeGrouping->psGMNodes[n]; + psRMSEnvelopeGrouping->psGMNodes[n].iGroupStart = n * 2; + psRMSEnvelopeGrouping->psGMNodes[n].iGroupLength = 2; + psRMSEnvelopeGrouping->psGMNodes[n].iGroupRMSEnvelopeCost = -1; + psRMSEnvelopeGrouping->psGMNodes[n].fGroupSNRPenalty = -1.0; + 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; + psGMNode = &psRMSEnvelopeGrouping->psGMNodes[0]; + while ( psGMNode != NULL ) + { + piGroupLengths[*piNumGroups] = psGMNode->iGroupLength; + *piNumGroups += 1; + psGMNode = psGMNode->psNext; + } + + /* Compute RMS Envelope given group lengths */ + ComputeRMSEnvelope( iChannels, iNumBands, *piNumGroups, piGroupLengths, psRMSEnvelopeGrouping->ppfBandEnergy, pppiRMSEnvelope ); + + /* Envelope Tenting */ + for ( n = 0; n < iChannels; n++ ) + { + int32_t k; + for ( k = 0; k < *piNumGroups; k++ ) + { + LimitRMSEnvelope( iNumBands, ENV_DELTA_MAX, ENV_DELTA_MIN, pppiRMSEnvelope[n][k] ); + } + } + + return; +} +#endif diff --git a/lib_isar/isar_cnst.h b/lib_isar/isar_cnst.h new file mode 100644 index 000000000..e54fcd0ea --- /dev/null +++ b/lib_isar/isar_cnst.h @@ -0,0 +1,135 @@ +/****************************************************************************************************** + + (C) 2022-2023 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 ISAR_CNST_H +#define ISAR_CNST_H + +#include +#include "options.h" + +/* clang-format off */ + +#ifdef SPLIT_REND_WITH_HEAD_ROT + +/*----------------------------------------------------------------------------------* + * Split Binaural Rendering Constants + *----------------------------------------------------------------------------------*/ + +typedef enum +{ + PCM_INT16, + PCM_FLOAT32, + PCM_NOT_KNOW = 0xffff +} PCM_RESOLUTION; + +typedef enum +{ + ANY_YAW, + PITCH_ONLY, + ANY_ROLL, + PRED_ONLY, + PRED_ROLL_ONLY, + COM_GAIN_ONLY, + LR_GAIN_ONLY +} ISAR_SPLIT_REND_POSE_TYPE; + + +#define CLDFB_PLC_XF 2 /* Length of cross-fade into first good frame after frame loss in CLDFB cols. */ + +#define SPLIT_REND_MAX_YAW_ONLY_POSES 2 +#define SPLIT_REND_MAX_PITCH_ONLY_POSES 2 +#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_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 +#define MAX_SPLIT_MD_SUBFRAMES 1 +#define COMPLEX_MD_BAND_THRESH MAX_SPLIT_REND_MD_BANDS +#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS +#define COMPLEX_MD_BAND_THRESH_LOW 4 +#define COMPLEX_MD_BAND_THRESH_HIGH 10 +#else +#define COMPLEX_MD_BAND_THRESH_LOW 5 +#endif +#define SPLIT_REND_RO_MD_BAND_THRESH 4 + +#define ISAR_SPLIT_REND_NUM_QUANT_STRATS 4 +#define ISAR_SPLIT_REND_PRED_63QUANT_PNTS 63 +#define ISAR_SPLIT_REND_PRED_31QUANT_PNTS 31 +#define ISAR_SPLIT_REND_ROLL_PRED_QUANT_PNTS 31 +#define ISAR_SPLIT_REND_D_QUANT_PNTS 15 +#define ISAR_SPLIT_REND_PRED_MIN_VAL -1.4f +#define ISAR_SPLIT_REND_PRED_MAX_VAL 1.4f + +#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_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_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_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_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_HEAD_POSE_BITS 9 +#define ISAR_SPLIT_REND_DOF_BITS 2 +#define ISAR_SPLIT_REND_HQ_MODE_BITS 1 +#define ISAR_SPLIT_REND_ROT_AXIS_BITS 3 +#define ISAR_SPLIT_REND_RO_FLAG_BITS 1 + +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS +#define IVAS_LC3PLUS_MAX_NUM_DECODERS 2 +#endif + +/*----------------------------------------------------------------------------------* + * Split rendering bitrate constants + *----------------------------------------------------------------------------------*/ + +#define SPLIT_REND_256k 256000 +#define SPLIT_REND_320k 320000 +#define SPLIT_REND_384k 384000 +#define SPLIT_REND_512k 512000 +#define SPLIT_REND_768k 768000 + +#endif /*SPLIT_REND_WITH_HEAD_ROT */ + +#endif /*ISAR_CNST_H */ +/* clang-format on */ diff --git a/lib_isar/isar_lc3plus_common.c b/lib_isar/isar_lc3plus_common.c new file mode 100644 index 000000000..32e30e97c --- /dev/null +++ b/lib_isar/isar_lc3plus_common.c @@ -0,0 +1,89 @@ +/****************************************************************************************************** + + (C) 2022-2023 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. + +*******************************************************************************************************/ + +#include "options.h" +#include "isar_lc3plus_common.h" +#include "ivas_error.h" +#include "lc3.h" + +#ifdef SPLIT_REND_WITH_HEAD_ROT +/*-----------------------------------------------------------------------------------------* + * Function ISAR_LC3PLUS_LC3plusErrToIvasErr() + * + * + *-----------------------------------------------------------------------------------------*/ + +ivas_error ISAR_LC3PLUS_LC3plusErrToIvasErr( + const LC3PLUS_Error lc3PlusError ) +{ + switch ( lc3PlusError ) + { + case LC3PLUS_OK: + return IVAS_ERR_OK; + case LC3PLUS_BITRATE_ERROR: + return IVAS_ERR_LC3PLUS_INVALID_BITRATE; + default: + break; + } + + return IVAS_ERR_INTERNAL; +} +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS +ivas_error IVAS_LC3PLUS_LC3plusRtpErrToIvasErr( const LC3PLUS_RTP_ERR lc3PlusRtpError ) +{ + switch ( lc3PlusRtpError ) + { + case LC3PLUS_RTP_ERR_NO_ERROR: + return IVAS_ERR_OK; + case LC3PLUS_RTP_ERR_NULL_PTR: + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + case LC3PLUS_RTP_ERR_INVALID_PARAMETERS: + return IVAS_ERR_WRONG_PARAMS; + case LC3PLUS_RTP_ERR_NOT_IMPLEMENTED: + return IVAS_ERR_NOT_IMPLEMENTED; + case LC3PLUS_RTP_ERR_UNSUPPORTED_CONFIGURATION: + return IVAS_ERR_INTERNAL; + case LC3PLUS_RTP_ERR_INVALID_BITSTREAM: + return IVAS_ERR_UNEXPECTED_LC3PLUS_BITSTREAM; + case LC3PLUS_RTP_ERR_INVALID_BITSTREAM_SIZE: + return IVAS_ERR_INVALID_BUFFER_SIZE; + case LC3PLUS_RTP_ERR_NOT_ENOUGH_FTDS_ALLOCATED: + return IVAS_ERR_INTERNAL; + case LC3PLUS_RTP_ERR_GENERIC_ERROR: + default: + break; + } + + return IVAS_ERR_UNKNOWN; +} +#endif +#endif diff --git a/lib_isar/isar_lc3plus_common.h b/lib_isar/isar_lc3plus_common.h new file mode 100644 index 000000000..08ffff60a --- /dev/null +++ b/lib_isar/isar_lc3plus_common.h @@ -0,0 +1,72 @@ +/****************************************************************************************************** + + (C) 2022-2023 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 ISAR_LC3PLUS_COM_H +#define ISAR_LC3PLUS_COM_H + + +#include +#include "options.h" +#include "ivas_error.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT +#include "lc3.h" +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS +#include "isar_lc3plus_payload.h" +#endif + +/*! common configuration parameters between encoder and decoder */ +typedef struct LC3PLUS_CONFIG +{ + /*! frame duration in microseconds [10000, 5000, 2500] */ + int16_t lc3plus_frame_duration_us; + /*! isar frame duration in microseconds [20000, 10000, 5000] */ + int16_t isar_frame_duration_us; + /*! sampling rate*/ + int32_t samplerate; + /*! number of channels */ + int16_t channels; +#if defined ISAR_BITSTREAM_UPDATE_LC3PLUS || defined ISAR_BITSTREAM_UPDATE_LC3PLUS + /*! high resolution mode enabled (1) or disabled (0)*/ + int16_t high_res_mode_enabled; +#endif +} LC3PLUS_CONFIG; + +/*! utility function to convert LC3PLUS_Errors to the suitable ivas_error */ +ivas_error ISAR_LC3PLUS_LC3plusErrToIvasErr( const LC3PLUS_Error lc3PlusError ); + +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS +/*! utility function to convert LC3PLUS_Errors to the suitable ivas_error */ +ivas_error IVAS_LC3PLUS_LC3plusRtpErrToIvasErr( const LC3PLUS_RTP_ERR lc3PlusRtpError ); +#endif + +#endif /* SPLIT_REND_WITH_HEAD_ROT */ +#endif /* ISAR_LC3PLUS_COM_H */ diff --git a/lib_isar/isar_lc3plus_dec.c b/lib_isar/isar_lc3plus_dec.c new file mode 100644 index 000000000..77cd4da21 --- /dev/null +++ b/lib_isar/isar_lc3plus_dec.c @@ -0,0 +1,844 @@ +/****************************************************************************************************** + + (C) 2022-2023 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. + +*******************************************************************************************************/ + +#include +#include "options.h" +#include "prot.h" +#include "ivas_prot.h" +#include "isar_lc3plus_dec.h" +#include "isar_lc3plus_common.h" +#include "lc3.h" +#include "ivas_error_utils.h" +#include "wmc_auto.h" + +#ifdef SPLIT_REND_WITH_HEAD_ROT + +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS +/*------------------------------------------------------------------------- + * isar_LC3PLUS_AllocateSubframeDecodingMatrix() + * + * + *------------------------------------------------------------------------*/ + +static void isar_LC3PLUS_DEC_FreeSubframeDecodingMatrix( + int16_t **subframeChannelMatrix ) +{ + for ( int16_t i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) + { + free( subframeChannelMatrix[i] ); + } + + free( subframeChannelMatrix ); + + return; +} +#endif + + +/*------------------------------------------------------------------------- + * ISAR_LC3PLUS_DEC_Open() + * + * + *------------------------------------------------------------------------*/ + +ivas_error ISAR_LC3PLUS_DEC_Open( + const LC3PLUS_CONFIG config, /* i : LC3plus decoder configuration */ + ISAR_LC3PLUS_DEC_HANDLE *handle /* o : decoder handle */ +) +{ + LC3PLUS_Error err; + int32_t decoder_size; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + int16_t i; + + if ( 0 == config.lc3plus_frame_duration_us ) + { + return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Invalid lc3plus_frame_duration_us (0)\n" ); + } +#else + int16_t lc3plusFrameIdx; + int16_t numLC3plusFramesPerIvasFrame; + int16_t i; +#endif + + if ( ( *handle = malloc( sizeof( struct ISAR_LC3PLUS_DEC_HANDLE ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus wrapper handle\n" ); + } + +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + if ( config.channels > IVAS_LC3PLUS_MAX_NUM_DECODERS ) + { + return IVAS_ERROR( IVAS_ERR_INIT_ERROR, "Maximum number of channels exceeds IVAS_LC3PLUS_MAX_NUM_DECODERS\n" ); + } +#else + + if ( 0 == config.lc3plus_frame_duration_us ) + { + return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Invalid lc3plus_frame_duration_us (0)\n" ); + } + numLC3plusFramesPerIvasFrame = (int16_t) ( config.isar_frame_duration_us / config.lc3plus_frame_duration_us ); +#endif + + + ( *handle )->num_decs = 0; + ( *handle )->pcm_conversion_buffer = NULL; + ( *handle )->handles = NULL; + ( *handle )->selective_decoding_states = NULL; + ( *handle )->bitstream_caches = NULL; + + if ( ( ( *handle )->handles = malloc( config.channels * sizeof( ISAR_LC3PLUS_DEC_HANDLE ) ) ) == NULL ) + { + ISAR_LC3PLUS_DEC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus wrapper handle\n" ); + } + + if ( ( ( *handle )->selective_decoding_states = malloc( config.channels * sizeof( ISAR_LC3PLUS_DEC_SELECTIVE_DECODING_STATE * ) ) ) == NULL ) + { + ISAR_LC3PLUS_DEC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus wrapper handle\n" ); + } + + for ( i = 0; i < config.channels; ++i ) + { + ( *handle )->handles[i] = NULL; + ( *handle )->selective_decoding_states[i] = NULL; + } + + if ( ( ( *handle )->bitstream_caches = malloc( config.channels * sizeof( ISAR_LC3PLUS_DEC_BITSTREAM_CACHE * ) ) ) == NULL ) + { + ISAR_LC3PLUS_DEC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus wrapper handle\n" ); + } + for ( i = 0; i < config.channels; ++i ) + { + ( *handle )->bitstream_caches[i] = NULL; + } + + ( *handle )->num_decs = config.channels; + for ( int32_t iCh = 0; iCh < config.channels; iCh++ ) + { + ( *handle )->selective_decoding_states[iCh] = NULL; + if ( NULL != ( *handle )->bitstream_caches ) + { + ( *handle )->bitstream_caches[iCh] = NULL; + } + /* allocate and configure LC3plus decoder */ + decoder_size = lc3plus_dec_get_size( config.samplerate, 1 ); + if ( 0 == decoder_size ) + { + ISAR_LC3PLUS_DEC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_INTERNAL, "lc3plus_dec_get_size failed\n" ); + } + + if ( ( ( *handle )->handles[iCh] = malloc( decoder_size ) ) == NULL ) + { + ISAR_LC3PLUS_DEC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus decoder\n" ); + } + +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + err = lc3plus_dec_init( ( *handle )->handles[iCh], config.samplerate, 1, LC3PLUS_PLC_ADVANCED, config.high_res_mode_enabled ); +#else + err = lc3plus_dec_init( ( *handle )->handles[iCh], config.samplerate, 1, LC3PLUS_PLC_ADVANCED, 0 ); +#endif + if ( LC3PLUS_OK != err ) + { + ISAR_LC3PLUS_DEC_Close( handle ); + return IVAS_ERROR( ISAR_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_dec_init failed\n" ); + } + + err = lc3plus_dec_set_frame_dms( ( *handle )->handles[iCh], config.lc3plus_frame_duration_us / 100 ); + if ( LC3PLUS_OK != err ) + { + ISAR_LC3PLUS_DEC_Close( handle ); + return IVAS_ERROR( ISAR_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_dec_set_frame_dms failed\n" ); + } + + /* allocate and configure per LC3plus decoder skip state */ + if ( ( ( *handle )->selective_decoding_states[iCh] = malloc( sizeof( ISAR_LC3PLUS_DEC_SELECTIVE_DECODING_STATE ) ) ) == NULL ) + { + ISAR_LC3PLUS_DEC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus decoder\n" ); + } + +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS + if ( ( ( *handle )->selective_decoding_states[iCh]->frame_actions = malloc( numLC3plusFramesPerIvasFrame * sizeof( SelectiveDecAction ) ) ) == NULL ) + { + ISAR_LC3PLUS_DEC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus decoder\n" ); + } +#endif + + ( *handle )->selective_decoding_states[iCh]->has_skipped_a_frame = 0; + ( *handle )->selective_decoding_states[iCh]->shall_decode_cached_frame = 0; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + ( *handle )->selective_decoding_states[iCh]->frame_action = DEC_ACTION_DECODE_AND_USE; +#else + for ( lc3plusFrameIdx = 0; lc3plusFrameIdx < numLC3plusFramesPerIvasFrame; lc3plusFrameIdx++ ) + { + ( *handle )->selective_decoding_states[iCh]->frame_actions[lc3plusFrameIdx] = DEC_ACTION_DECODE_AND_USE; + } +#endif + + /* allocate and configure per LC3plus decoder bitstream cache */ + if ( ( ( *handle )->bitstream_caches[iCh] = malloc( sizeof( ISAR_LC3PLUS_DEC_BITSTREAM_CACHE ) ) ) == NULL ) + { + ISAR_LC3PLUS_DEC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus decoder\n" ); + } +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + ( *handle )->bitstream_caches[iCh]->bitstream_cache_capacity = 400 /*LC3plus max non-HR octet count*/; +#else + ( *handle )->bitstream_caches[iCh]->bitstream_cache_capacity = 400 /*LC3plus max non-HR octet count*/ * numLC3plusFramesPerIvasFrame; +#endif + if ( ( ( *handle )->bitstream_caches[iCh]->bitstream_cache = malloc( ( *handle )->bitstream_caches[iCh]->bitstream_cache_capacity ) ) == NULL ) + { + ISAR_LC3PLUS_DEC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus decoder\n" ); + } + ( *handle )->bitstream_caches[iCh]->bitstream_cache_size = 0; + } + + ( *handle )->config = config; + if ( config.isar_frame_duration_us < config.lc3plus_frame_duration_us || config.isar_frame_duration_us % config.lc3plus_frame_duration_us != 0 ) + { + ISAR_LC3PLUS_DEC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "Current pcm_conversion_buffer sizing requires that lc3plus uses a shorter or equal frame duration than ivas\n" ); + } + + if ( ( ( *handle )->pcm_conversion_buffer = malloc( sizeof( int16_t ) * config.samplerate * config.lc3plus_frame_duration_us / 1000000 ) ) == NULL ) + { + ISAR_LC3PLUS_DEC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus decoder wrapper pcm_conversion_buffer\n" ); + } + + return IVAS_ERR_OK; +} + +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS +/*------------------------------------------------------------------------- + * ISAR_LC3PLUS_DEC_AllocateSubframeDecodingMatrix() + * + * + *------------------------------------------------------------------------*/ + +ivas_error ISAR_LC3PLUS_DEC_AllocateSubframeDecodingMatrix( + int16_t ***subframeChannelMatrix, + const uint32_t num_decs ) +{ + int16_t i; + + if ( ( *subframeChannelMatrix = malloc( MAX_PARAM_SPATIAL_SUBFRAMES * sizeof( int16_t * ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "subframeChannelMatrix allocation failed\n" ); + } + + for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) + { + ( *subframeChannelMatrix )[i] = NULL; + } + + for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) + { + if ( ( ( *subframeChannelMatrix )[i] = malloc( num_decs * sizeof( int16_t ) ) ) == NULL ) + { + isar_LC3PLUS_DEC_FreeSubframeDecodingMatrix( *subframeChannelMatrix ); + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "subframeChannelMatrix allocation failed\n" ); + } + } + + return IVAS_ERR_OK; +} + + +/*------------------------------------------------------------------------- + * ISAR_LC3PLUS_DEC_SetSelectiveDecodingMatrix() + * + * + *------------------------------------------------------------------------*/ + +ivas_error ISAR_LC3PLUS_DEC_SetSelectiveDecodingMatrix( + ISAR_LC3PLUS_DEC_HANDLE handle, /* i : LC3plus decoder handle */ + int16_t *subframeChannelMatrix[MAX_PARAM_SPATIAL_SUBFRAMES] ) +{ + int16_t numIvasSubFramesPerLC3frame; + uint32_t decIdx; + int16_t ivasSubframeIdx; + int16_t effectiveIsarSubframeDuration; + int16_t actual_num_spatial_subframes; + + if ( NULL == handle ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "ISAR_LC3PLUS_DEC_HANDLE is NULL\n" ); + } + + if ( NULL == subframeChannelMatrix ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "subframeChannelMatrix is NULL\n" ); + } + + if ( handle->config.lc3plus_frame_duration_us == 0 || handle->config.isar_frame_duration_us % handle->config.lc3plus_frame_duration_us != 0 ) + { + return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "invalid isar_frame_duration_us/lc3plus_frame_duration_us values\n" ); + } + + effectiveIsarSubframeDuration = (int16_t) ( handle->config.isar_frame_duration_us == 20000 ? handle->config.isar_frame_duration_us / MAX_PARAM_SPATIAL_SUBFRAMES : handle->config.isar_frame_duration_us ); + numIvasSubFramesPerLC3frame = (int16_t) handle->config.lc3plus_frame_duration_us / effectiveIsarSubframeDuration; + actual_num_spatial_subframes = (int16_t) handle->config.isar_frame_duration_us / effectiveIsarSubframeDuration; + /* 0.5(0) = 10ms lc3plus, 5ms subframe */ + if ( numIvasSubFramesPerLC3frame != 1 ) + { + return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "Selective decoding is only implemented for aligned IVAS-Subframes & LC3plus \n" ); + } + + /* map subframeChannelMatrix to lc3plus skip states */ + /* 1st pass: Flag the required frames */ + for ( decIdx = 0; decIdx < handle->num_decs; decIdx++ ) + { + for ( ivasSubframeIdx = 0; ivasSubframeIdx < actual_num_spatial_subframes; ivasSubframeIdx++ ) + { + if ( 1 == subframeChannelMatrix[ivasSubframeIdx][decIdx] ) + { + /* subframe needed by the user, definitely decode */ + handle->selective_decoding_states[decIdx]->frame_actions[ivasSubframeIdx] = DEC_ACTION_DECODE_AND_USE; + } + else + { + + /* subframe not needed by the user, but might be required to re-initialize a decoder after inactivity */ + if ( + ( ivasSubframeIdx != actual_num_spatial_subframes - 1 ) && 1 == subframeChannelMatrix[ivasSubframeIdx + 1][decIdx] ) + { + /* ... but if the following subframe is required, it needs to be decoded and dropped */ + handle->selective_decoding_states[decIdx]->frame_actions[ivasSubframeIdx] = DEC_ACTION_DECODE_AND_DROP; + } + else + { + handle->selective_decoding_states[decIdx]->frame_actions[ivasSubframeIdx] = DEC_ACTION_SKIP; + } + } + } + } + + /* if a decoder was paused before, it needs to either: + * - Decode the cached frame (if available) and the first required frame OR + * - Decode the previous LC3plus subframe, even if it isn't needed by the user */ + for ( decIdx = 0; decIdx < handle->num_decs; decIdx++ ) + { + if ( handle->selective_decoding_states[decIdx]->has_skipped_a_frame ) + { + /* find the first frame required by the user */ + for ( ivasSubframeIdx = 0; ivasSubframeIdx < actual_num_spatial_subframes; ivasSubframeIdx++ ) + { + if ( DEC_ACTION_DECODE_AND_USE == handle->selective_decoding_states[decIdx]->frame_actions[ivasSubframeIdx] ) + { + /* The first required frame is the first subframe. To flush the decoder, the cached frame must be decoded and dropped */ + if ( 0 == ivasSubframeIdx ) + { + handle->selective_decoding_states[decIdx]->shall_decode_cached_frame = 1; + break; + } + /* The first required frame is not the first frame, so the cache is useless. Instead we decode & drop the previous frame*/ + else + { + handle->selective_decoding_states[decIdx]->frame_actions[ivasSubframeIdx - 1] = DEC_ACTION_DECODE_AND_DROP; + break; + } + } + } + } + } + + /* if a dec gets paused & caching is activated we need to flag the last useful LC3plus frame for caching */ + for ( decIdx = 0; decIdx < handle->num_decs; decIdx++ ) + { + for ( ivasSubframeIdx = 0; ivasSubframeIdx < actual_num_spatial_subframes; ivasSubframeIdx++ ) + { + if ( handle->selective_decoding_states[decIdx]->frame_actions[ivasSubframeIdx] == DEC_ACTION_SKIP && handle->selective_decoding_states[decIdx]->frame_actions[actual_num_spatial_subframes - 1] != DEC_ACTION_DECODE_AND_USE ) + { + handle->selective_decoding_states[decIdx]->frame_actions[actual_num_spatial_subframes - 1] = DEC_ACTION_CACHE; + } + } + } + + return IVAS_ERR_OK; +} +#endif + + +/*------------------------------------------------------------------------- + * ISAR_LC3PLUS_DEC_GetDelay() + * + * + *------------------------------------------------------------------------*/ + +ivas_error ISAR_LC3PLUS_DEC_GetDelay( + ISAR_LC3PLUS_DEC_HANDLE handle, /* i : LC3plus decoder handle */ + int32_t *delayInSamples /* o : decoder delay in number of samples per channel */ +) +{ + int32_t tmpDelayInSamples; + + if ( NULL == handle ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "ISAR_LC3PLUS_DEC_HANDLE is NULL\n" ); + } + if ( NULL == delayInSamples ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "delayInSamples is NULL\n" ); + } + + *delayInSamples = 0; + /* sanity check whether all encoders are actually configured identically */ + for ( uint32_t iDec = 0; iDec < handle->num_decs; iDec++ ) + { + if ( NULL == handle->handles[iDec] ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "LC3plus decoder handle is NULL\n" ); + } + + tmpDelayInSamples = lc3plus_dec_get_delay( handle->handles[iDec] ); + if ( 0 != *delayInSamples && tmpDelayInSamples != *delayInSamples ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "Not all mono LC3plus decoders are configured identically\n" ); + } + + *delayInSamples = tmpDelayInSamples; + } + + return IVAS_ERR_OK; +} + + +/*------------------------------------------------------------------------- + * ISAR_LC3PLUS_DEC_Close() + * + * + *------------------------------------------------------------------------*/ + +void ISAR_LC3PLUS_DEC_Close( + ISAR_LC3PLUS_DEC_HANDLE *handle /* i/o: Pointer to LC3plus decoder handle */ +) +{ + if ( NULL == handle || NULL == *handle ) + { + return; + } + for ( uint32_t iDec = 0; iDec < ( *handle )->num_decs; iDec++ ) + { + if ( NULL != ( *handle )->handles && NULL != ( *handle )->handles[iDec] ) + { + lc3plus_free_decoder_structs( ( *handle )->handles[iDec] ); + free( ( *handle )->handles[iDec] ); + } + + if ( NULL != ( *handle )->selective_decoding_states && NULL != ( *handle )->selective_decoding_states[iDec] ) + { +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS + free( ( *handle )->selective_decoding_states[iDec]->frame_actions ); +#endif + free( ( *handle )->selective_decoding_states[iDec] ); + } + + if ( NULL != ( *handle )->bitstream_caches && NULL != ( *handle )->bitstream_caches[iDec] ) + { + free( ( *handle )->bitstream_caches[iDec]->bitstream_cache ); + free( ( *handle )->bitstream_caches[iDec] ); + } + } + + if ( NULL != ( *handle )->pcm_conversion_buffer ) + { + free( ( *handle )->pcm_conversion_buffer ); + } + free( ( *handle )->handles ); + + if ( NULL != ( *handle )->bitstream_caches ) + { + free( ( *handle )->bitstream_caches ); + } + free( ( *handle )->selective_decoding_states ); + + free( *handle ); + *handle = NULL; + + return; +} + + +/*------------------------------------------------------------------------- + * decode_or_conceal_one_lc3plus_frame() + * + * + *------------------------------------------------------------------------*/ + +static ivas_error decode_or_conceal_one_lc3plus_frame( + LC3PLUS_Dec *dec, + uint8_t *bitstream_in, + const int32_t bitstream_in_length, + int16_t **pcm_out_buffer, + const int32_t badFrameIndicator ) +{ + LC3PLUS_Error err; + + push_wmops( "lc3plus_dec16" ); + err = lc3plus_dec16( dec, bitstream_in, bitstream_in_length, pcm_out_buffer, NULL, badFrameIndicator ); + pop_wmops(); + + if ( err == LC3PLUS_DECODE_ERROR && 1 == badFrameIndicator ) + { + /* LC3PLUS_DECODE_ERROR && badFrameIndicator means that the decoder has successfully concealed, which is actually OK. */ + err = LC3PLUS_OK; + } + + if ( err != LC3PLUS_OK ) + { + return IVAS_ERROR( ISAR_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_dec16 failed\n" ); + } + + return IVAS_ERR_OK; +} + + +/*------------------------------------------------------------------------- + * isar_LC3PLUS_DEC_Decode_or_Conceal_internal() + * + * + *------------------------------------------------------------------------*/ + +static ivas_error isar_LC3PLUS_DEC_Decode_or_Conceal_internal( + ISAR_LC3PLUS_DEC_HANDLE handle, /* i : LC3plus decoder configuration */ + 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 */ +) +{ + uint32_t iDec; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + int32_t config_num_media_times; + int32_t iMediaTime; + int32_t iFtd; + LC3PLUS_RTP_PAYLOAD payload; +#else + int32_t iLc3plusFrame; + int32_t lc3framesPerIvasFrame; + int32_t bitstreamOffsetPerCoder; + uint8_t *bitstream_in_iter = bitstream_in; +#endif + int32_t ivasSampleIndex; + int16_t numSamplesPerLC3plusChannel; + ivas_error err; + + if ( NULL == handle ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "LC3PLUS_Dec_Wrap_Handle is NULL\n" ); + } + if ( NULL == bitstream_in ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "bitstream_in is NULL\n" ); + } + if ( NULL == pcm_out ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "pcm_out is NULL\n" ); + } + if ( badFrameIndicator != 0 && badFrameIndicator != 1 ) + { + return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "badFrameIndicator must be 1 or 0\n" ); + } + if ( badFrameIndicator == 0 && bitstream_in_size <= 0 ) + { + return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "bitstream_in_size must be positive\n" ); + } + + if ( handle->config.isar_frame_duration_us % handle->config.lc3plus_frame_duration_us != 0 ) + { + return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "isar_frame_duration_us must be equal or multiple of lc3plus_frame_duration_us \n" ); + } + +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + config_num_media_times = handle->config.isar_frame_duration_us / handle->config.lc3plus_frame_duration_us; + if ( !badFrameIndicator ) + { + if ( LC3PLUS_RTP_payload_deserialize( &payload, bitstream_in, bitstream_in_size ) != LC3PLUS_RTP_ERR_NO_ERROR ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "LC3PLUS_RTP_payload_deserialize failed\n" ); + } + if ( payload.sampling_rate_hz != handle->config.samplerate ) + { + return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "LC3plus config change (samplerate) in bitstream is not supported\n" ); + } + if ( payload.num_channels != handle->config.channels ) + { + return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "LC3plus config change (number of channels) in bitstream is not supported\n" ); + } + if ( payload.frame_duration_us != handle->config.lc3plus_frame_duration_us ) + { + return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "LC3plus config change (frame duration) in bitstream is not supported\n" ); + } + if ( payload.high_resolution_enabled != handle->config.high_res_mode_enabled ) + { + return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "LC3plus config change (high resolution mode) in bitstream is not supported\n" ); + } + if ( payload.num_media_times != config_num_media_times ) + { + return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "LC3plus config change (number of media times per frame data block) in bitstream is not supported\n" ); + } + } +#endif + +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + numSamplesPerLC3plusChannel = (int16_t) ( handle->config.samplerate / ( 1000000 / handle->config.isar_frame_duration_us ) / config_num_media_times ); + for ( iDec = 0; iDec < handle->num_decs; iDec++ ) + { + for ( iMediaTime = 0; iMediaTime < config_num_media_times; iMediaTime++ ) + { + iFtd = iDec + iMediaTime * handle->num_decs; +#else + lc3framesPerIvasFrame = handle->config.isar_frame_duration_us / handle->config.lc3plus_frame_duration_us; + + numSamplesPerLC3plusChannel = (int16_t) ( handle->config.samplerate / ( 1000000 / handle->config.isar_frame_duration_us ) / lc3framesPerIvasFrame ); + bitstreamOffsetPerCoder = bitstream_in_size / handle->num_decs / lc3framesPerIvasFrame; + for ( iDec = 0; iDec < handle->num_decs; iDec++ ) + { + for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) + { +#endif + if ( handle->selective_decoding_states[iDec]->shall_decode_cached_frame ) + { + if ( 0 == handle->bitstream_caches[iDec]->bitstream_cache_size ) + { + 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 ); + if ( err != IVAS_ERR_OK ) + { + return IVAS_ERROR( err, "lc3plus decoding failed\n" ); + } + handle->selective_decoding_states[iDec]->shall_decode_cached_frame = 0; + handle->selective_decoding_states[iDec]->has_skipped_a_frame = 0; + } + + /* reset cache if caching is enabled - it has either been decoded or is not needed */ + if ( NULL != handle->bitstream_caches ) + { + handle->bitstream_caches[iDec]->bitstream_cache_size = 0; + } + +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + switch ( handle->selective_decoding_states[iDec]->frame_action ) +#else + switch ( handle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] ) +#endif + { +#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 ); + if ( err != IVAS_ERR_OK ) + { + return IVAS_ERROR( err, "lc3plus decoding failed\n" ); + } + handle->selective_decoding_states[iDec]->has_skipped_a_frame = 0; + break; + } +#endif + case DEC_ACTION_DECODE_AND_USE: + { +#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 ); + } + else if ( payload.ftds[iFtd].frame_data_length == LC3PLUS_RTP_FDL_SPEECH_BAD ) + { + return IVAS_ERR_NOT_IMPLEMENTED; + /* Untested therefore disabled. Would probably only need to call concealment, + * but the LC3plus API requires a non-NULL ptr for this which is not available here */ + } + 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 ); + } + if ( err != IVAS_ERR_OK ) + { + return IVAS_ERROR( err, "lc3plus decoding failed\n" ); + } + + for ( int16_t iSampleInt16 = 0; iSampleInt16 < numSamplesPerLC3plusChannel; iSampleInt16++ ) + { + ivasSampleIndex = iSampleInt16 + iMediaTime * numSamplesPerLC3plusChannel; + pcm_out[iDec][ivasSampleIndex] = (float) handle->pcm_conversion_buffer[iSampleInt16]; + } + handle->selective_decoding_states[iDec]->has_skipped_a_frame = 0; + break; +#else + err = decode_or_conceal_one_lc3plus_frame( handle->handles[iDec], bitstream_in_iter, bitstreamOffsetPerCoder, &handle->pcm_conversion_buffer, badFrameIndicator ); + if ( err != IVAS_ERR_OK ) + { + return IVAS_ERROR( err, "lc3plus decoding failed\n" ); + } + + for ( int32_t iSampleInt16 = 0; iSampleInt16 < numSamplesPerLC3plusChannel; iSampleInt16++ ) + { + ivasSampleIndex = iSampleInt16 + iLc3plusFrame * numSamplesPerLC3plusChannel; + pcm_out[iDec][ivasSampleIndex] = (float) handle->pcm_conversion_buffer[iSampleInt16]; + } + handle->selective_decoding_states[iDec]->has_skipped_a_frame = 0; + break; +#endif + } +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS + case DEC_ACTION_SKIP: + { + /* log that this instance has skipped a frame and must decode twice once reactivated */ + handle->selective_decoding_states[iDec]->has_skipped_a_frame = 1; + break; + } +#endif + case DEC_ACTION_CACHE: + { +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + if ( handle->bitstream_caches[iDec]->bitstream_cache_capacity < (int32_t) payload.ftds[iFtd].frame_data_length ) + { + return IVAS_ERROR( IVAS_ERR_INVALID_BUFFER_SIZE, "bitstream_cache_capacity is too low for LC3plus frame size\n" ); + } + /* store bit rate of cached frame */ + mvc2c( payload.ftds[iFtd].frame_data, handle->bitstream_caches[iDec]->bitstream_cache, (int16_t) payload.ftds[iFtd].frame_data_length ); + handle->bitstream_caches[iDec]->bitstream_cache_size = payload.ftds[iFtd].frame_data_length; + /* log that this instance has skipped a frame and must decode twice once reactivated */ + handle->selective_decoding_states[iDec]->has_skipped_a_frame = 1; + break; +#else + if ( handle->bitstream_caches[iDec]->bitstream_cache_capacity < bitstreamOffsetPerCoder ) + { + return IVAS_ERROR( IVAS_ERR_INVALID_BUFFER_SIZE, "bitstream_cache_capacity is too low for LC3plus frame size\n" ); + } + /* store bit rate of cached frame */ + mvc2c( bitstream_in_iter, handle->bitstream_caches[iDec]->bitstream_cache, (int16_t) bitstreamOffsetPerCoder ); + handle->bitstream_caches[iDec]->bitstream_cache_size = bitstreamOffsetPerCoder; + /* log that this instance has skipped a frame and must decode twice once reactivated */ + handle->selective_decoding_states[iDec]->has_skipped_a_frame = 1; + break; +#endif + } + case DEC_ACTION_NUM_ENUMS: + default: + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "invalid LC3plus decoder state\n" ); + } +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + } /* for each media time */ + /* reset skipping state, must be set by the user before each decode call*/ + handle->selective_decoding_states[iDec]->frame_action = DEC_ACTION_DECODE_AND_USE; + } /* for each dec/channel */ +#else + + bitstream_in_iter += bitstreamOffsetPerCoder; + } + + /* reset skipping state, must be set by the user before each decode call*/ + for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) + { + handle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] = DEC_ACTION_DECODE_AND_USE; + } + } + +#endif + return IVAS_ERR_OK; +} + + +/*------------------------------------------------------------------------- + * ISAR_LC3PLUS_DEC_Decode() + * + * + *------------------------------------------------------------------------*/ + +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 */ +) +{ + int16_t badFrameIndicator; + + if ( NULL == handle ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "LC3PLUS_Dec_Wrap_Handle is NULL\n" ); + } + if ( NULL == bitstream_in ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "bitstream_in is NULL\n" ); + } + if ( NULL == pcm_out ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "pcm_out is NULL\n" ); + } + badFrameIndicator = 0; + + return isar_LC3PLUS_DEC_Decode_or_Conceal_internal( handle, bitstream_in, bitstream_in_size, badFrameIndicator, pcm_out ); +} + + +/*------------------------------------------------------------------------- + * ISAR_LC3PLUS_DEC_Conceal() + * + * + *------------------------------------------------------------------------*/ + +ivas_error ISAR_LC3PLUS_DEC_Conceal( + ISAR_LC3PLUS_DEC_HANDLE handle, /* i : LC3plus decoder handle */ + float **pcm_out /* o : concealed samples */ +) +{ + uint8_t bitstream_in[LC3PLUS_MAX_BYTES]; + int16_t badFrameIndicator; + + if ( NULL == handle ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "LC3PLUS_Dec_Wrap_Handle is NULL\n" ); + } + + if ( NULL == pcm_out ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "pcm_out is NULL\n" ); + } + + /* LC3plus API requires a non-NULL bitstream pointer, even when triggering concealment */ + badFrameIndicator = 1; + + return isar_LC3PLUS_DEC_Decode_or_Conceal_internal( handle, bitstream_in, 0, badFrameIndicator, pcm_out ); +} +#endif /* SPLIT_REND_WITH_HEAD_ROT */ diff --git a/lib_isar/isar_lc3plus_dec.h b/lib_isar/isar_lc3plus_dec.h new file mode 100644 index 000000000..2be6649b9 --- /dev/null +++ b/lib_isar/isar_lc3plus_dec.h @@ -0,0 +1,135 @@ +/****************************************************************************************************** + + (C) 2022-2023 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 ISAR_LC3PLUS_DEC_H +#define ISAR_LC3PLUS_DEC_H + +#include +#include "options.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT +#include "lc3.h" +#include "ivas_error.h" +#include "ivas_cnst.h" +#include "isar_lc3plus_common.h" + + +typedef enum +{ +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS + DEC_ACTION_DECODE_AND_DROP = 0, +#endif + DEC_ACTION_DECODE_AND_USE, +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS + DEC_ACTION_SKIP, +#endif + DEC_ACTION_CACHE, + DEC_ACTION_NUM_ENUMS +} SelectiveDecAction; + + +typedef struct ISAR_LC3PLUS_DEC_SELECTIVE_DECODING_STATE +{ + /*! indicates that the decoder has skipped one or more frames. This means it must decode two frames to flush algorithmic delay when re-activated */ + int16_t has_skipped_a_frame; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + /*! action to execute for the next frame */ + SelectiveDecAction frame_action; +#else + /*! if set to 1, decoder will skip decoding for the next frame */ + SelectiveDecAction *frame_actions; +#endif + /*! if set to 1, decoder will decode the cache before decoding any of current frames */ + int16_t shall_decode_cached_frame; +} ISAR_LC3PLUS_DEC_SELECTIVE_DECODING_STATE; + +typedef struct ISAR_LC3PLUS_DEC_BITSTREAM_CACHE +{ + uint8_t *bitstream_cache; + int32_t bitstream_cache_capacity; + int32_t bitstream_cache_size; +} ISAR_LC3PLUS_DEC_BITSTREAM_CACHE; + +/* decoder wrapper */ +typedef struct ISAR_LC3PLUS_DEC_HANDLE +{ + LC3PLUS_Dec **handles; + ISAR_LC3PLUS_DEC_SELECTIVE_DECODING_STATE **selective_decoding_states; + ISAR_LC3PLUS_DEC_BITSTREAM_CACHE **bitstream_caches; + uint32_t num_decs; + int16_t *pcm_conversion_buffer; + LC3PLUS_CONFIG config; +} * ISAR_LC3PLUS_DEC_HANDLE; + +ivas_error ISAR_LC3PLUS_DEC_Open( + const LC3PLUS_CONFIG config, /* i : decoder configuration */ + ISAR_LC3PLUS_DEC_HANDLE *handle /* o : decoder handle */ +); + +ivas_error ISAR_LC3PLUS_DEC_GetDelay( + ISAR_LC3PLUS_DEC_HANDLE handle, /* i : decoder handle */ + int32_t *delayInSamples /* o : algorithmic delay of encoding and decoding in number of samples per channel */ +); + +void ISAR_LC3PLUS_DEC_Close( + ISAR_LC3PLUS_DEC_HANDLE *handle /* i/o: pointer to decoder handle */ +); + +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS +/*! Sets a matrix[MAX_PARAM_SPATIAL_SUBFRAMES][numLC3plusDecoders] where all require subframes must be flagged with 1, frames that are not required with 0 */ +ivas_error ISAR_LC3PLUS_DEC_SetSelectiveDecodingMatrix( + ISAR_LC3PLUS_DEC_HANDLE handle, /* i : decoder handle */ + int16_t *subframeChannelMatrix[MAX_PARAM_SPATIAL_SUBFRAMES] /* i : */ +); +#endif + +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 */ +); + +ivas_error ISAR_LC3PLUS_DEC_Conceal( + ISAR_LC3PLUS_DEC_HANDLE handle, /* i : decoder handle */ + float **pcm_out /* o : concealed samples */ +); + +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS +ivas_error ISAR_LC3PLUS_DEC_AllocateSubframeDecodingMatrix( + int16_t ***subframeChannelMatrix, + const uint32_t num_decs ); + +void ISAR_LC3PLUS_DEC_FreeSubframeDecodingMatrix( int16_t **subframeChannelMatrix ); +#endif + +#endif /* SPLIT_REND_WITH_HEAD_ROT */ +#endif /* ISAR_LC3PLUS_DEC_H */ diff --git a/lib_isar/isar_lc3plus_enc.c b/lib_isar/isar_lc3plus_enc.c new file mode 100644 index 000000000..002741040 --- /dev/null +++ b/lib_isar/isar_lc3plus_enc.c @@ -0,0 +1,686 @@ +/****************************************************************************************************** + + (C) 2022-2023 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. + +*******************************************************************************************************/ + +#include "isar_lc3plus_enc.h" +#include "isar_lc3plus_common.h" +#include "lc3.h" +#include "ivas_error_utils.h" +#include "prot.h" +#include "wmc_auto.h" +#include "options.h" + +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS +static const LC3PLUS_RTP_FDL s_fdl_request = LC3PLUS_RTP_FDL_NO_REQ_OR_NO_DATA; +#endif + +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS +static int32_t limit_per_channel_bitrate( LC3PLUS_CONFIG config, + int32_t per_channel_bitrate ) +{ + if ( config.high_res_mode_enabled ) + { + switch ( config.lc3plus_frame_duration_us ) + { + case 10000: + return min( per_channel_bitrate, 500000 ); + case 5000: + return min( per_channel_bitrate, 600000 ); + case 2500: + return min( per_channel_bitrate, 672000 ); + default: + assert( false && "unreachable" ); + } + } + + switch ( config.samplerate ) + { + case 48000: + case 32000: + return min( per_channel_bitrate, 320000 ); + case 24000: + return min( per_channel_bitrate, 314400 ); + case 16000: + return min( per_channel_bitrate, 221600 ); + case 8000: + return min( per_channel_bitrate, 114400 ); + default: + assert( false && "unreachable" ); + } + + assert( false && "unreachable" ); + return -1; +} +#endif + +#ifdef SPLIT_REND_WITH_HEAD_ROT +/*-------------------------------------------------------------------* + * Function ISAR_LC3PLUS_ENC_Open() + * + * + *-------------------------------------------------------------------*/ + +ivas_error ISAR_LC3PLUS_ENC_Open( + const LC3PLUS_CONFIG config, /* i : LC3plus encoder configuration */ + const uint32_t bitsPerSecond, /* i : bit rate */ + ISAR_LC3PLUS_ENC_HANDLE *handle /* o : encoder handle */ +) +{ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + int32_t num_lc3plus_media_times_per_ivas_frame; +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS + int32_t lc3plus_num_bytes_per_frame; +#endif + bool is_last_media_time, is_last_channel; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + ivas_error ivas_err; +#endif +#endif +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS + int32_t bitsPerSecondPerChannel; +#endif + int32_t encoder_size; + LC3PLUS_Error err; + int32_t lfeChans[1]; + int16_t i; + + lfeChans[0] = 0; + + if ( 0U == config.channels ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "Invalid number of channels\n" ); + } +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS + bitsPerSecondPerChannel = bitsPerSecond / config.channels; +#endif +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + if ( config.lc3plus_frame_duration_us != 2500 && config.lc3plus_frame_duration_us != 5000 && config.lc3plus_frame_duration_us != 10000 ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "Invalid lc3plus_frame_duration_us\n" ); + } + if ( config.isar_frame_duration_us != 20000 && config.isar_frame_duration_us != 10000 && config.isar_frame_duration_us != 5000 ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "Invalid isar_frame_duration_us\n" ); + } +#endif + encoder_size = lc3plus_enc_get_size( config.samplerate, 1 ); + if ( 0 == encoder_size ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "lc3plus_enc_get_size failed\n" ); + } + + if ( ( *handle = malloc( sizeof( struct ISAR_LC3PLUS_ENC_HANDLE ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus wrapper handle\n" ); + } +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + ( *handle )->config = config; + ( *handle )->frame_type_descriptors = NULL; +#endif + + ( *handle )->pcm_conversion_buffer = NULL; + ( *handle )->num_encs = 0; + if ( ( ( *handle )->handles = malloc( config.channels * sizeof( ISAR_LC3PLUS_ENC_HANDLE ) ) ) == NULL ) + { + ISAR_LC3PLUS_ENC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus wrapper handle\n" ); + } + + for ( i = 0; i < config.channels; ++i ) + { + ( *handle )->handles[i] = NULL; + } + ( *handle )->num_encs = config.channels; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + num_lc3plus_media_times_per_ivas_frame = config.isar_frame_duration_us / config.lc3plus_frame_duration_us; + ( *handle )->fdl_request = s_fdl_request; + ( *handle )->num_ftds = config.channels * num_lc3plus_media_times_per_ivas_frame; + ( *handle )->frame_type_descriptors = malloc( ( *handle )->num_ftds * sizeof( LC3PLUS_RTP_FTD ) ); + if ( NULL == ( *handle )->frame_type_descriptors ) + { + ISAR_LC3PLUS_ENC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus frame_type_descriptors\n" ); + } +#endif + + for ( int32_t iCh = 0; iCh < config.channels; iCh++ ) + { + if ( ( ( *handle )->handles[iCh] = malloc( encoder_size ) ) == NULL ) + { + ISAR_LC3PLUS_ENC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus encoder\n" ); + } + +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + err = lc3plus_enc_init( ( *handle )->handles[iCh], config.samplerate, 1, config.high_res_mode_enabled, lfeChans ); +#else + err = lc3plus_enc_init( ( *handle )->handles[iCh], config.samplerate, 1, 0, lfeChans ); +#endif + if ( err != LC3PLUS_OK ) + { + ISAR_LC3PLUS_ENC_Close( handle ); + return IVAS_ERROR( ISAR_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_enc_init failed\n" ); + } + + err = lc3plus_enc_set_frame_dms( ( *handle )->handles[iCh], config.lc3plus_frame_duration_us / 100 ); + if ( err != LC3PLUS_OK ) + { + ISAR_LC3PLUS_ENC_Close( handle ); + return IVAS_ERROR( ISAR_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_enc_set_frame_dms failed\n" ); + } +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS + err = lc3plus_enc_set_bitrate( ( *handle )->handles[iCh], bitsPerSecondPerChannel ); + if ( err != LC3PLUS_OK ) + { + ISAR_LC3PLUS_ENC_Close( handle ); + return IVAS_ERROR( ISAR_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_enc_set_bitrate failed\n" ); + } +#endif + } + + if ( config.isar_frame_duration_us < config.lc3plus_frame_duration_us || config.isar_frame_duration_us % config.lc3plus_frame_duration_us != 0 ) + { + ISAR_LC3PLUS_ENC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "Current pcm_conversion_buffer sizing requires that lc3plus uses a shorter or equal frame duration than ivas\n" ); + } + +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS + ( *handle )->config = config; +#endif + ( *handle )->pcm_conversion_buffer = malloc( sizeof( int16_t ) * config.samplerate * config.lc3plus_frame_duration_us / 1000000 ); + if ( NULL == ( *handle )->pcm_conversion_buffer ) + { + ISAR_LC3PLUS_ENC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus encoder wrapper pcm_conversion_buffer\n" ); + } + +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + /* update FDI fields */ + for ( int32_t iMediaTime = 0; iMediaTime < num_lc3plus_media_times_per_ivas_frame; ++iMediaTime ) + { + for ( uint32_t iEnc = 0; iEnc < ( *handle )->num_encs; ++iEnc ) + { + int32_t ftd_index = iEnc + iMediaTime * ( *handle )->num_encs; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + ( *handle )->frame_type_descriptors[ftd_index].frame_data_length = 0; /* will be set to the correct value in IVAS_LC3PLUS_ENC_SetBitrate */ +#else + lc3plus_num_bytes_per_frame = lc3plus_enc_get_num_bytes( ( *handle )->handles[iEnc] ); + if ( lc3plus_num_bytes_per_frame <= 0 ) + { + ISAR_LC3PLUS_ENC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_INTERNAL, "lc3plus_enc_get_num_bytes reported invalid result failed\n" ); + } + ( *handle )->frame_type_descriptors[ftd_index].frame_data_length = lc3plus_num_bytes_per_frame; +#endif + if ( 0 != LC3PLUS_RTP_ftd_bwr_from_samplerate( &( *handle )->frame_type_descriptors[ftd_index].bwr, config.samplerate, config.high_res_mode_enabled ) ) + { + ISAR_LC3PLUS_ENC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_INTERNAL, "LC3PLUS_RTP_ftd_bwr_from_samplerate failed\n" ); + } + if ( 0 != LC3PLUS_RTP_ftd_fdi_from_frame_duration_us( &( *handle )->frame_type_descriptors[ftd_index].fdi, config.lc3plus_frame_duration_us ) ) + { + ISAR_LC3PLUS_ENC_Close( handle ); + return IVAS_ERROR( IVAS_ERR_INTERNAL, "LC3PLUS_RTP_ftd_fdi_from_frame_duration_us failed\n" ); + } + ( *handle )->frame_type_descriptors[ftd_index].h = LC3PLUS_RTP_FTD_H_PRIMARY; + ( *handle )->frame_type_descriptors[ftd_index].frame_data = NULL; + + /* The FTDs in the ToC are included in the following order: + * 1) First the FTD for the first channel of the first FDB (oldest frame) + * 2) Then the FTDs for the remaining channels for the first FDB in increasing CC order + * 3) Then the FTD for the first channel of the second FDB + * 4) Then the FTDs for the remaining channels for the second FDB + * 5) Etc. to the last FDB */ + is_last_media_time = num_lc3plus_media_times_per_ivas_frame - 1 == iMediaTime; + is_last_channel = ( *handle )->num_encs - 1 == iEnc; + if ( is_last_media_time && is_last_channel ) + { + ( *handle )->frame_type_descriptors[ftd_index].fc = LC3PLUS_RTP_FTD_FC_LAST_OVERALL; + } + else if ( !is_last_media_time && is_last_channel ) + { + ( *handle )->frame_type_descriptors[ftd_index].fc = LC3PLUS_RTP_FTD_FC_LAST_IN_MEDIATIME; + } + else + { + ( *handle )->frame_type_descriptors[ftd_index].fc = LC3PLUS_RTP_FTD_FC_SUBSEQUENT_CHANNEL; + } + } + } + +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + ivas_err = IVAS_LC3PLUS_ENC_SetBitrate( *handle, bitsPerSecond ); + if ( ivas_err != IVAS_ERR_OK ) + { + ISAR_LC3PLUS_ENC_Close( handle ); + return ivas_err; + } +#endif +#endif + return IVAS_ERR_OK; +} + +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS +/*-------------------------------------------------------------------* + * Function IVAS_LC3PLUS_ENC_SetBitrate() + * + * + *-------------------------------------------------------------------*/ + +ivas_error IVAS_LC3PLUS_ENC_SetBitrate( + ISAR_LC3PLUS_ENC_HANDLE handle, /* o : LC3plus encoder handle */ + const uint32_t bitsPerSecond /* i : new target bit rate */ +) +{ + int32_t numLc3plusMediaTimesPerIvasFrame; + int32_t lc3plus_num_bytes_per_frame; + int32_t availableOctetsPerIsarFrame; + int32_t actualOctetsPerFrame; + LC3PLUS_Error err; + int32_t iFtd; + int32_t fdrLength; + int32_t lc3plusPacketRate; + int32_t numSubframes; + int32_t minPayloadOverhead; + int32_t targetLc3PlusBitratePerChannel; + int32_t targetLc3PlusOctetCount; + int32_t lc3plusFdlLength; + + if ( NULL == handle ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "LC3PLUS_Enc_Wrap_Handle is NULL\n" ); + } + + availableOctetsPerIsarFrame = bitsPerSecond / ( 1000000 / handle->config.isar_frame_duration_us ) / 8; + lc3plusPacketRate = 1000 * 1000 / handle->config.lc3plus_frame_duration_us; + numLc3plusMediaTimesPerIvasFrame = handle->config.isar_frame_duration_us / handle->config.lc3plus_frame_duration_us; + numSubframes = numLc3plusMediaTimesPerIvasFrame * handle->config.channels; + + /* subtract minimum required payload bytes & calculate a first per-channel target bit rate */ + if ( LC3PLUS_RTP_frame_data_length_get_size( &fdrLength, s_fdl_request ) != LC3PLUS_RTP_ERR_NO_ERROR ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "LC3PLUS_RTP_frame_data_length_get_size failed\n" ); + } + minPayloadOverhead = fdrLength + ( numSubframes * LC3PLUS_RTP_FTD_MIN_SIZE ); + targetLc3PlusBitratePerChannel = ( availableOctetsPerIsarFrame - minPayloadOverhead ) / handle->config.channels * 8 * lc3plusPacketRate / numLc3plusMediaTimesPerIvasFrame; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + if ( targetLc3PlusBitratePerChannel <= 0 ) + { + return IVAS_ERROR( IVAS_ERR_LC3PLUS_INVALID_BITRATE, "available LC3plus bitrate <= 0\n" ); + } +#endif + targetLc3PlusBitratePerChannel = limit_per_channel_bitrate( handle->config, targetLc3PlusBitratePerChannel ); + targetLc3PlusOctetCount = targetLc3PlusBitratePerChannel / 8 / lc3plusPacketRate; + /* check resulting octet count. If it requires larger than 1-byte length fields, decrease the bitrate by enough to make room for the additional length field */ + if ( LC3PLUS_RTP_frame_data_length_get_size( &lc3plusFdlLength, targetLc3PlusOctetCount ) != LC3PLUS_RTP_ERR_NO_ERROR ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "LC3PLUS_RTP_frame_data_length_get_size failed\n" ); + } + if ( lc3plusFdlLength != LC3PLUS_RTP_FDL_MIN_LENGTH ) + { + /* reduce bitrate to allow for the required fdl field */ + targetLc3PlusBitratePerChannel = ( targetLc3PlusOctetCount - ( lc3plusFdlLength - LC3PLUS_RTP_FDL_MIN_LENGTH ) ) / handle->config.channels * 8 * lc3plusPacketRate; + } + + for ( int32_t iCh = 0; iCh < handle->config.channels; iCh++ ) + { + err = lc3plus_enc_set_bitrate( handle->handles[iCh], targetLc3PlusBitratePerChannel ); + if ( err != LC3PLUS_OK ) + { + return IVAS_ERROR( ISAR_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_enc_set_bitrate failed\n" ); + } + } + + // update FTD settings after bitrate change + for ( int32_t iMediaTime = 0; iMediaTime < numLc3plusMediaTimesPerIvasFrame; ++iMediaTime ) + { + for ( uint32_t iEnc = 0; iEnc < handle->num_encs; ++iEnc ) + { + iFtd = iEnc + iMediaTime * handle->num_encs; + lc3plus_num_bytes_per_frame = lc3plus_enc_get_num_bytes( handle->handles[iEnc] ); + if ( lc3plus_num_bytes_per_frame <= 0 ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "lc3plus_enc_get_num_bytes reported invalid result failed\n" ); + } + handle->frame_type_descriptors[iFtd].frame_data_length = lc3plus_num_bytes_per_frame; + } + } + + // TODO: remove sanity checks? + if ( ISAR_LC3PLUS_ENC_GetOutputBitstreamSize( handle, &actualOctetsPerFrame ) != IVAS_ERR_OK ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "ISAR_LC3PLUS_ENC_GetOutputBitstreamSize failed\n" ); + } + if ( actualOctetsPerFrame > availableOctetsPerIsarFrame ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "Bitrate reduction logic failed\n" ); + } + return IVAS_ERR_OK; +} +#endif + + +/*-------------------------------------------------------------------* + * Function ISAR_LC3PLUS_ENC_GetDelay() + * + * + *-------------------------------------------------------------------*/ + +ivas_error ISAR_LC3PLUS_ENC_GetDelay( + ISAR_LC3PLUS_ENC_HANDLE handle, /* i : LC3plus encoder handle */ + int32_t *delayInSamples /* o : encoder delay in number of samples per channel */ +) +{ + int32_t tmpDelayInSamples; + + if ( NULL == handle ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "LC3PLUS_Enc_Wrap_Handle is NULL\n" ); + } + if ( NULL == delayInSamples ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "delayInSamples is NULL\n" ); + } + + *delayInSamples = 0; + /* sanity check whether all encoders are actually configured identically */ + for ( uint32_t iEnc = 0; iEnc < handle->num_encs; iEnc++ ) + { + if ( NULL == handle->handles[iEnc] ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "LC3plus encoder handle is NULL\n" ); + } + + tmpDelayInSamples = lc3plus_enc_get_delay( handle->handles[iEnc] ); + if ( 0 != *delayInSamples && tmpDelayInSamples != *delayInSamples ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "Not all mono LC3plus encoders are configured identically\n" ); + } + *delayInSamples = tmpDelayInSamples; + } + + return IVAS_ERR_OK; +} + + +/*-------------------------------------------------------------------* + * Function ISAR_LC3PLUS_ENC_GetOutputBitstreamSize() + * + * + *-------------------------------------------------------------------*/ + +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 */ +) +{ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + LC3PLUS_RTP_ERR rtp_err; + int32_t num_lc3plus_media_times_per_ivas_frame; + int32_t iMediaTime; + int32_t ftd_frame_data_length_size, lc3plus_frame_data_length; + int32_t ftd_index; +#else + int32_t bitstreamSizeMultiplier; +#endif + if ( NULL == handle ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "LC3PLUS_Enc_Wrap_Handle is NULL\n" ); + } + if ( NULL == bsSize ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "bsSize is NULL\n" ); + } + +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + if ( 0 == handle->config.lc3plus_frame_duration_us ) + { + return IVAS_ERROR( IVAS_ERR_INIT_ERROR, "lc3plus_frame_duration_us is 0\n" ); + } + if ( handle->config.isar_frame_duration_us % handle->config.lc3plus_frame_duration_us != 0 ) + { + return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "isar_frame_duration_us must be equal or multiple of lc3plus_frame_duration_us \n" ); + } + + num_lc3plus_media_times_per_ivas_frame = handle->config.isar_frame_duration_us / handle->config.lc3plus_frame_duration_us; +#endif + *bsSize = 0; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + int32_t fdl_request_length; + rtp_err = LC3PLUS_RTP_frame_data_length_get_size( &fdl_request_length, handle->fdl_request ); + if ( rtp_err != LC3PLUS_RTP_ERR_NO_ERROR ) + { + return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Invalid LC3plus frame_data_length request\n" ); + } + *bsSize += fdl_request_length; +#endif + for ( uint32_t iEnc = 0; iEnc < handle->num_encs; iEnc++ ) + { + if ( NULL == handle->handles[iEnc] ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "LC3plus encoder handle is NULL\n" ); + } +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + lc3plus_frame_data_length = lc3plus_enc_get_num_bytes( handle->handles[iEnc] ); + for ( iMediaTime = 0; iMediaTime < num_lc3plus_media_times_per_ivas_frame; ++iMediaTime ) + { + ftd_index = iEnc + iMediaTime * handle->num_encs; + if ( lc3plus_frame_data_length != (int32_t) handle->frame_type_descriptors[ftd_index].frame_data_length ) + { + return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "LC3plus FTD data not synchronised with encoder bitrate\n" ); + } + rtp_err = LC3PLUS_RTP_frame_data_length_get_size( &ftd_frame_data_length_size, handle->frame_type_descriptors[ftd_index].frame_data_length ); + if ( rtp_err != LC3PLUS_RTP_ERR_NO_ERROR ) + { + return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Invalid LC3plus frame_data_length\n" ); + } + *bsSize += LC3PLUS_RTP_FTD_LENGTH_EXCLUDING_FDL; + *bsSize += handle->frame_type_descriptors[ftd_index].frame_data_length; + *bsSize += ftd_frame_data_length_size; + } + } +#else + *bsSize += lc3plus_enc_get_num_bytes( handle->handles[iEnc] ); + } + + if ( handle->config.isar_frame_duration_us % handle->config.lc3plus_frame_duration_us != 0 ) + { + return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "isar_frame_duration_us must be equal or multiple of lc3plus_frame_duration_us \n" ); + } + bitstreamSizeMultiplier = handle->config.isar_frame_duration_us / handle->config.lc3plus_frame_duration_us; + + *bsSize *= bitstreamSizeMultiplier; +#endif + + return IVAS_ERR_OK; +} + + +/*-------------------------------------------------------------------* + * Function ISAR_LC3PLUS_ENC_Close() + * + * + *-------------------------------------------------------------------*/ + +void ISAR_LC3PLUS_ENC_Close( + ISAR_LC3PLUS_ENC_HANDLE *handle /* i/o: pointer to LC3plus encoder handle */ +) +{ + if ( NULL == handle || NULL == *handle ) + { + return; + } +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + if ( NULL != ( *handle )->frame_type_descriptors ) + { + free( ( *handle )->frame_type_descriptors ); + } +#endif + for ( uint32_t iEnc = 0; iEnc < ( *handle )->num_encs; iEnc++ ) + { + if ( NULL != ( *handle )->handles[iEnc] ) + { + lc3plus_free_encoder_structs( ( *handle )->handles[iEnc] ); + free( ( *handle )->handles[iEnc] ); + } + } + if ( NULL != ( *handle )->pcm_conversion_buffer ) + { + free( ( *handle )->pcm_conversion_buffer ); + } + + free( ( *handle )->handles ); + free( *handle ); + + *handle = NULL; + + return; +} + + +/*-------------------------------------------------------------------* + * Function ISAR_LC3PLUS_ENC_Encode() + * + * + *-------------------------------------------------------------------*/ + +ivas_error ISAR_LC3PLUS_ENC_Encode( + ISAR_LC3PLUS_ENC_HANDLE handle, /* i : LC3plus encoder handle */ + float **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. */ +#else + void *bitstream_out /* o : pointer to bitstream frame */ +#endif +) +{ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + int32_t ftdIndex; + LC3PLUS_RTP_ERR rtpErr; + uint32_t num_media_times; +#else + uint32_t lc3framesPerIvasFrame; + uint8_t *bitstream_out_iter = bitstream_out; +#endif + uint32_t numSamplesPerLC3plusChannel; + int32_t ivasSampleIndex; + int32_t num_bytes = 0; + LC3PLUS_Error err; + + push_wmops( "ISAR_LC3PLUS_ENC_Encode" ); + + if ( NULL == handle ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "LC3PLUS_Enc_Wrap_Handle is NULL\n" ); + } + if ( NULL == pcm_in ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "pcm_in is NULL\n" ); + } + if ( NULL == bitstream_out ) + { + return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "bitstream_out is NULL\n" ); + } + + if ( handle->config.isar_frame_duration_us % handle->config.lc3plus_frame_duration_us != 0 ) + { + return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "isar_frame_duration_us must be equal or multiple of lc3plus_frame_duration_us \n" ); + } +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + num_media_times = handle->config.isar_frame_duration_us / handle->config.lc3plus_frame_duration_us; + numSamplesPerLC3plusChannel = handle->config.samplerate / ( 1000000 / handle->config.isar_frame_duration_us ) / num_media_times; + + size_t actual_size; + rtpErr = LC3PLUS_RTP_payload_serialize( bitstream_out, bitstream_out_size, &actual_size, s_fdl_request, handle->frame_type_descriptors, handle->num_ftds ); + if ( rtpErr != LC3PLUS_RTP_ERR_NO_ERROR ) + { + return IVAS_ERROR( IVAS_LC3PLUS_LC3plusRtpErrToIvasErr( rtpErr ), "LC3PLUS_RTP_payload_serialize failed\n" ); + } +#else + lc3framesPerIvasFrame = handle->config.isar_frame_duration_us / handle->config.lc3plus_frame_duration_us; + + numSamplesPerLC3plusChannel = handle->config.samplerate / ( 1000000 / handle->config.isar_frame_duration_us ) / lc3framesPerIvasFrame; +#endif + for ( uint32_t iEnc = 0; iEnc < handle->num_encs; iEnc++ ) + { +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + for ( uint32_t iMediaTime = 0; iMediaTime < num_media_times; iMediaTime++ ) +#else + for ( uint32_t iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) +#endif + { + for ( uint32_t iSampleInt16 = 0; iSampleInt16 < numSamplesPerLC3plusChannel; iSampleInt16++ ) + { +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + ivasSampleIndex = iSampleInt16 + iMediaTime * numSamplesPerLC3plusChannel; +#else + ivasSampleIndex = iSampleInt16 + iLc3plusFrame * numSamplesPerLC3plusChannel; +#endif + handle->pcm_conversion_buffer[iSampleInt16] = (int16_t) max( INT16_MIN, min( pcm_in[iEnc][ivasSampleIndex], INT16_MAX ) ); + } + +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + ftdIndex = iMediaTime * handle->num_encs + iEnc; +#endif + 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 ); +#else + err = lc3plus_enc16( handle->handles[iEnc], &handle->pcm_conversion_buffer, bitstream_out_iter, &num_bytes, NULL ); +#endif + pop_wmops(); + if ( err != LC3PLUS_OK ) + { + return IVAS_ERROR( ISAR_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_enc16 failed\n" ); + } + if ( 0 == num_bytes ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "lc3plus_enc16 did not produce output\n" ); + } +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + if ( num_bytes != (int32_t) handle->frame_type_descriptors[ftdIndex].frame_data_length ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "payload format and lc3plus enc bitrate are not aligned\n" ); + } +#else + + bitstream_out_iter += num_bytes; +#endif + } + } + + pop_wmops(); + + return IVAS_ERR_OK; +} +#endif /* SPLIT_REND_WITH_HEAD_ROT */ diff --git a/lib_isar/isar_lc3plus_enc.h b/lib_isar/isar_lc3plus_enc.h new file mode 100644 index 000000000..6fda1cb21 --- /dev/null +++ b/lib_isar/isar_lc3plus_enc.h @@ -0,0 +1,102 @@ +/****************************************************************************************************** + + (C) 2022-2023 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 ISAR_LC3PLUS_ENC_H +#define ISAR_LC3PLUS_ENC_H + +#include +#include "ivas_error.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT +#include "lc3.h" +#include "isar_lc3plus_common.h" +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS +#include "isar_lc3plus_payload.h" +#endif + +/* encoder wrapper */ +typedef struct ISAR_LC3PLUS_ENC_HANDLE +{ + LC3PLUS_CONFIG config; + LC3PLUS_Enc **handles; + uint32_t num_encs; + int16_t *pcm_conversion_buffer; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + LC3PLUS_RTP_FTD *frame_type_descriptors; + int32_t num_ftds; + LC3PLUS_RTP_FDL fdl_request; +#endif +} * ISAR_LC3PLUS_ENC_HANDLE; + +ivas_error ISAR_LC3PLUS_ENC_Open( + const LC3PLUS_CONFIG config, /* i : encoder configuration */ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + const uint32_t initialBitsPerSecond, /* i : initial target bit rate */ +#else + const uint32_t bitsPerSecond, /* i : bit rate */ +#endif + ISAR_LC3PLUS_ENC_HANDLE *handle /* o : LC3plus encoder handle */ +); + +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS +ivas_error IVAS_LC3PLUS_ENC_SetBitrate( + ISAR_LC3PLUS_ENC_HANDLE handle, /* o : LC3plus encoder handle */ + const uint32_t bitsPerSecond /* i : new target bit rate */ +); +#endif + +ivas_error ISAR_LC3PLUS_ENC_GetDelay( + ISAR_LC3PLUS_ENC_HANDLE handle, /* i : LC3plus encoder handle */ + int32_t *delayInSamples /* o : algorithmic delay of encoding and decoding in number of samples per channel */ +); + +ivas_error ISAR_LC3PLUS_ENC_GetOutputBitstreamSize( + ISAR_LC3PLUS_ENC_HANDLE handle, /* i : LC3plus encoder handle */ + int32_t *bsSize /* o : size of next bitstream frame in bytes */ +); + +void ISAR_LC3PLUS_ENC_Close( + ISAR_LC3PLUS_ENC_HANDLE *handle /* i/o: pointer to LC3plus encoder handle */ +); + +ivas_error ISAR_LC3PLUS_ENC_Encode( + ISAR_LC3PLUS_ENC_HANDLE handle, /* i : LC3plus encoder handle */ + float **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. */ +#else + void *bitstream_out /* o : pointer to bitstream frame */ +#endif +); +#endif + +#endif /* ISAR_LC3PLUS_ENC_H */ diff --git a/lib_isar/isar_lc3plus_payload.c b/lib_isar/isar_lc3plus_payload.c new file mode 100644 index 000000000..fa47189ca --- /dev/null +++ b/lib_isar/isar_lc3plus_payload.c @@ -0,0 +1,823 @@ +/****************************************************************************************************** + + (C) 2022-2023 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. + +*******************************************************************************************************/ + +#include +#include +#include +#include "isar_lc3plus_payload.h" +#include "options.h" + +#ifdef SPLIT_REND_WITH_HEAD_ROT +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS +static LC3PLUS_RTP_ERR s_frame_duration_ms_from_fdi( int32_t *frame_duration_us, const LC3PLUS_RTP_FTD_FDI fdi ) +{ + if ( NULL == frame_duration_us ) + { + return LC3PLUS_RTP_ERR_NULL_PTR; + } + switch ( fdi ) + { + case LC3PLUS_RTP_FTD_FDI_2500_US: + *frame_duration_us = 2500; + break; + case LC3PLUS_RTP_FTD_FDI_5000_US: + *frame_duration_us = 5000; + break; + case LC3PLUS_RTP_FTD_FDI_10000_US: + *frame_duration_us = 10000; + break; + case LC3PLUS_RTP_FTD_FDI_RESERVED: + default: + return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; + } + return LC3PLUS_RTP_ERR_NO_ERROR; +} + +static LC3PLUS_RTP_ERR s_sampling_rate_hz_from_bwr( int32_t *sample_rate_hz, const LC3PLUS_RTP_FTD_BWR bwr ) +{ + if ( NULL == sample_rate_hz ) + { + return LC3PLUS_RTP_ERR_NULL_PTR; + } + switch ( bwr ) + { + case LC3PLUS_RTP_FTD_BWR_NB: + *sample_rate_hz = 8000; + break; + case LC3PLUS_RTP_FTD_BWR_WB: + *sample_rate_hz = 16000; + break; + case LC3PLUS_RTP_FTD_BWR_SSWB: + *sample_rate_hz = 24000; + break; + case LC3PLUS_RTP_FTD_BWR_SWB: + *sample_rate_hz = 32000; + break; + case LC3PLUS_RTP_FTD_BWR_FBCD: + *sample_rate_hz = 44100; + break; + case LC3PLUS_RTP_FTD_BWR_FB: + *sample_rate_hz = 48000; + break; + case LC3PLUS_RTP_FTD_BWR_FBHR: + *sample_rate_hz = 48000; + break; + case LC3PLUS_RTP_FTD_BWR_UBHR: + *sample_rate_hz = 96000; + break; + default: + return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; + } + return LC3PLUS_RTP_ERR_NO_ERROR; +} + +static LC3PLUS_RTP_ERR s_high_resolution_flag_from_bwr( int16_t *high_resolution_flag, const LC3PLUS_RTP_FTD_BWR bwr ) +{ + if ( NULL == high_resolution_flag ) + { + return LC3PLUS_RTP_ERR_NULL_PTR; + } + switch ( bwr ) + { + case LC3PLUS_RTP_FTD_BWR_NB: + *high_resolution_flag = 0; + break; + case LC3PLUS_RTP_FTD_BWR_WB: + *high_resolution_flag = 0; + break; + case LC3PLUS_RTP_FTD_BWR_SSWB: + *high_resolution_flag = 0; + break; + case LC3PLUS_RTP_FTD_BWR_SWB: + *high_resolution_flag = 0; + break; + case LC3PLUS_RTP_FTD_BWR_FBCD: + *high_resolution_flag = 0; + break; + case LC3PLUS_RTP_FTD_BWR_FB: + *high_resolution_flag = 0; + break; + case LC3PLUS_RTP_FTD_BWR_FBHR: + *high_resolution_flag = 1; + break; + case LC3PLUS_RTP_FTD_BWR_UBHR: + *high_resolution_flag = 1; + break; + default: + return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; + } + return LC3PLUS_RTP_ERR_NO_ERROR; +} + +LC3PLUS_RTP_ERR LC3PLUS_RTP_frame_data_length_get_size( int32_t *length, const LC3PLUS_RTP_FDL frameDataLengthValue ) +{ + if ( frameDataLengthValue == LC3PLUS_RTP_FDL_NO_REQ_OR_NO_DATA || frameDataLengthValue == LC3PLUS_RTP_FDL_SPEECH_BAD || frameDataLengthValue == LC3PLUS_RTP_FDL_SPEECH_SID ) + { + *length = 1; + } + else if ( frameDataLengthValue >= LC3PLUS_RTP_FDL_LENGTH_1_MIN && frameDataLengthValue <= LC3PLUS_RTP_FDL_LENGTH_1_MAX ) + { + *length = 1; + } + else if ( frameDataLengthValue >= LC3PLUS_RTP_FDL_LENGTH_2_MIN && frameDataLengthValue <= LC3PLUS_RTP_FDL_LENGTH_2_MAX ) + { + *length = 2; + } + else if ( frameDataLengthValue >= LC3PLUS_RTP_FDL_LENGTH_3_MIN && frameDataLengthValue <= LC3PLUS_RTP_FDL_LENGTH_3_MAX ) + { + *length = 3; + } + else + { + return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; + } + return LC3PLUS_RTP_ERR_NO_ERROR; +} + +static LC3PLUS_RTP_ERR s_frame_data_length_pack( const LC3PLUS_RTP_FDL frameDataLengthValue, uint8_t *dst ) +{ + int32_t frame_data_length_size; + LC3PLUS_RTP_ERR err; + + if ( NULL == dst ) + { + return LC3PLUS_RTP_ERR_NULL_PTR; + } + + err = LC3PLUS_RTP_frame_data_length_get_size( &frame_data_length_size, frameDataLengthValue ); + if ( err != LC3PLUS_RTP_ERR_NO_ERROR ) + { + return err; + } + if ( 1 == frame_data_length_size ) + { + *dst++ = frameDataLengthValue >> 0 & LC3PLUS_RTP_FDL_EXTENSION_VALUE; + } + else if ( 2 == frame_data_length_size ) + { + const int32_t frameDataLengthValueToWrite = frameDataLengthValue - LC3PLUS_RTP_FDL_EXTENSION_VALUE; + *dst++ = LC3PLUS_RTP_FDL_EXTENSION_VALUE; + *dst = frameDataLengthValueToWrite >> 0 & LC3PLUS_RTP_FDL_EXTENSION_VALUE; + } + else if ( 3 == frame_data_length_size ) + { + const int32_t frameDataLengthValueToWrite = frameDataLengthValue - ( 2 * LC3PLUS_RTP_FDL_EXTENSION_VALUE ); + *dst++ = LC3PLUS_RTP_FDL_EXTENSION_VALUE; + *dst++ = LC3PLUS_RTP_FDL_EXTENSION_VALUE; + *dst = frameDataLengthValueToWrite >> 0 & LC3PLUS_RTP_FDL_EXTENSION_VALUE; + } + return LC3PLUS_RTP_ERR_NO_ERROR; +} + +static int32_t s_get_size_from_fdl( const LC3PLUS_RTP_FDL fdl ) +{ + if ( fdl >= LC3PLUS_RTP_FDL_LENGTH_1_MIN && fdl <= LC3PLUS_RTP_FDL_LENGTH_3_MAX ) + { + return fdl; + } + return 0; +} + +static bool s_fdl_is_magic_value( const LC3PLUS_RTP_FDL fdl ) +{ + if ( fdl == LC3PLUS_RTP_FDL_NO_REQ_OR_NO_DATA || fdl == LC3PLUS_RTP_FDL_SPEECH_SID || fdl == LC3PLUS_RTP_FDL_SPEECH_BAD ) + { + return true; + } + return false; +} + +static bool s_fdl_value_is_valid_request( const LC3PLUS_RTP_FDL fdl_request ) +{ + /* LC3PLUS_RTP_FDL_SPEECH_SID && LC3PLUS_RTP_FDL_SPEECH_SID are not valid values for the FDL request */ + if ( fdl_request == LC3PLUS_RTP_FDL_NO_REQ_OR_NO_DATA || ( fdl_request >= LC3PLUS_RTP_FDL_LENGTH_1_MIN && fdl_request <= LC3PLUS_RTP_FDL_LENGTH_3_MAX ) ) + { + return true; + } + return false; +} + +static LC3PLUS_RTP_ERR s_frame_data_length_parse( LC3PLUS_RTP_FDL *frame_data_length_value, const uint8_t *src, const size_t remaining_capacity ) +{ + int32_t frame_data_length_size; + LC3PLUS_RTP_ERR err; + if ( NULL == src || NULL == frame_data_length_value || remaining_capacity < 1 ) + { + return LC3PLUS_RTP_ERR_NULL_PTR; + } + + if ( remaining_capacity > 2 && LC3PLUS_RTP_FDL_EXTENSION_VALUE == *src && LC3PLUS_RTP_FDL_EXTENSION_VALUE == *( src + 1 ) ) + { + *frame_data_length_value = *( src + 2 ) + 2 * LC3PLUS_RTP_FDL_EXTENSION_VALUE; + } + else if ( remaining_capacity > 1 && LC3PLUS_RTP_FDL_EXTENSION_VALUE == *src ) + { + *frame_data_length_value = *( src + 1 ) + 1 * LC3PLUS_RTP_FDL_EXTENSION_VALUE; + } + else if ( remaining_capacity > 0 ) + { + *frame_data_length_value = *src << 0; + } + else + { + return LC3PLUS_RTP_ERR_INVALID_BITSTREAM_SIZE; + } + + /* sanity check */ + err = LC3PLUS_RTP_frame_data_length_get_size( &frame_data_length_size, *frame_data_length_value ); + if ( err != LC3PLUS_RTP_ERR_NO_ERROR ) + { + return err; + } + return LC3PLUS_RTP_ERR_NO_ERROR; +} + +static LC3PLUS_RTP_ERR s_parse_ftd( const uint8_t *p_read, LC3PLUS_RTP_FTD *receiver_ftd, int32_t *num_bytes_read, const size_t remaining_capacity ) +{ + int32_t frame_data_block_size; + LC3PLUS_RTP_FDL fdl; + LC3PLUS_RTP_ERR err; + if ( NULL == p_read || NULL == receiver_ftd || NULL == num_bytes_read || remaining_capacity < LC3PLUS_RTP_FTD_MIN_SIZE ) + { + return LC3PLUS_RTP_ERR_NULL_PTR; + } + + *num_bytes_read = 0; + receiver_ftd->fc = 0; + receiver_ftd->fdi = 0; + receiver_ftd->bwr = 0; + receiver_ftd->h = 0; + receiver_ftd->fc |= *p_read & LC3PLUS_RTP_FTD_FC_MASK; + receiver_ftd->fdi |= ( *p_read & LC3PLUS_RTP_FTD_FDI_MASK ); + receiver_ftd->bwr |= ( *p_read & LC3PLUS_RTP_FTD_BWR_MASK ); + receiver_ftd->h |= ( *p_read & LC3PLUS_RTP_FTD_H_MASK ); + p_read++; + *num_bytes_read = 1; + + err = s_frame_data_length_parse( &fdl, p_read, remaining_capacity - *num_bytes_read ); + if ( LC3PLUS_RTP_ERR_NO_ERROR != err ) + { + return err; + } + frame_data_block_size = s_get_size_from_fdl( fdl ); + + receiver_ftd->frame_data_length = frame_data_block_size; + int32_t length_field_size; + err = LC3PLUS_RTP_frame_data_length_get_size( &length_field_size, receiver_ftd->frame_data_length ); + if ( LC3PLUS_RTP_ERR_NO_ERROR != err ) + { + return err; + } + *num_bytes_read += length_field_size; + return LC3PLUS_RTP_ERR_NO_ERROR; +} + +LC3PLUS_RTP_ERR LC3PLUS_RTP_payload_serialize( + uint8_t *serialized_buffer, + const size_t serialized_buffer_capacity, + size_t *packed_buffer_actual_size, + const LC3PLUS_RTP_FDL fdl_request, + LC3PLUS_RTP_FTD *sender_ftds, + const size_t sender_ftds_num ) +{ + LC3PLUS_RTP_ERR err; + uint8_t *p_write = serialized_buffer; + uint32_t i; + int32_t bytes_written = 0; + int32_t lc3plus_frame_size_sum; + uint8_t *p_frame_data; + int32_t fdl_request_length; + + if ( NULL == serialized_buffer || NULL == packed_buffer_actual_size || NULL == sender_ftds ) + { + return LC3PLUS_RTP_ERR_NULL_PTR; + } + + *packed_buffer_actual_size = 0; + err = LC3PLUS_RTP_frame_data_length_get_size( &fdl_request_length, fdl_request ); + if ( LC3PLUS_RTP_ERR_NO_ERROR != err ) + { + return err; + } + if ( !s_fdl_value_is_valid_request( fdl_request ) ) + { + return LC3PLUS_RTP_ERR_INVALID_FDL_REQUEST; + } + if ( (int32_t) serialized_buffer_capacity < bytes_written + fdl_request_length ) + { + return LC3PLUS_RTP_ERR_INVALID_BITSTREAM_SIZE; + } + err = s_frame_data_length_pack( fdl_request, p_write ); + if ( LC3PLUS_RTP_ERR_NO_ERROR != err ) + { + return err; + } + bytes_written += fdl_request_length; + p_write += bytes_written; + + for ( i = 0; i < sender_ftds_num; ++i ) + { + /* only the last ftd may have the LC3PLUS_RTP_FTD_FC_LAST_OVERALL value */ + if ( sender_ftds[i].fc == LC3PLUS_RTP_FTD_FC_LAST_OVERALL && i != ( sender_ftds_num - 1 ) ) + { + return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; + } + /* the last ftd must have the LC3PLUS_RTP_FTD_FC_LAST_OVERALL value */ + if ( sender_ftds[i].fc != LC3PLUS_RTP_FTD_FC_LAST_OVERALL && i == ( sender_ftds_num - 1 ) ) + { + return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; + } + if ( (int32_t) serialized_buffer_capacity < bytes_written + LC3PLUS_RTP_FTD_LENGTH_EXCLUDING_FDL ) + { + return LC3PLUS_RTP_ERR_INVALID_BITSTREAM_SIZE; + } + *p_write = 0x00; + *p_write |= LC3PLUS_RTP_FTD_FC_MASK & (uint8_t) sender_ftds[i].fc; + *p_write |= LC3PLUS_RTP_FTD_FDI_MASK & (uint8_t) sender_ftds[i].fdi; + *p_write |= LC3PLUS_RTP_FTD_BWR_MASK & (uint8_t) sender_ftds[i].bwr; + *p_write |= LC3PLUS_RTP_FTD_H_MASK & (uint8_t) sender_ftds[i].h; + p_write++; + bytes_written += LC3PLUS_RTP_FTD_LENGTH_EXCLUDING_FDL; + + int32_t fdl_length; + err = LC3PLUS_RTP_frame_data_length_get_size( &fdl_length, sender_ftds[i].frame_data_length ); + if ( LC3PLUS_RTP_ERR_NO_ERROR != err ) + { + return err; + } + if ( (int32_t) serialized_buffer_capacity < bytes_written + fdl_length ) + { + return LC3PLUS_RTP_ERR_INVALID_BITSTREAM_SIZE; + } + err = s_frame_data_length_pack( sender_ftds[i].frame_data_length, p_write ); + if ( LC3PLUS_RTP_ERR_NO_ERROR != err ) + { + return err; + } + p_write += fdl_length; + bytes_written += fdl_length; + } + + lc3plus_frame_size_sum = 0; + p_frame_data = serialized_buffer + bytes_written; + for ( i = 0; i < sender_ftds_num; ++i ) + { + sender_ftds[i].frame_data = p_frame_data; + p_frame_data += sender_ftds[i].frame_data_length; + lc3plus_frame_size_sum += sender_ftds[i].frame_data_length; + } + *packed_buffer_actual_size = bytes_written + lc3plus_frame_size_sum; + assert( *packed_buffer_actual_size <= serialized_buffer_capacity ); + return LC3PLUS_RTP_ERR_NO_ERROR; +} + +static LC3PLUS_RTP_ERR s_ftds_parse( + LC3PLUS_RTP_FTD *receiver_ftds, + const int32_t receiver_ftds_num_max, + int16_t *receiver_ftds_num, + uint8_t *serialized_buffer, + const size_t serialized_buffer_size ) +{ + int32_t diff; + uint8_t *p_read; + uint32_t ftds_offset_sum = 0; + int16_t i; + LC3PLUS_RTP_ERR error; + int32_t frame_offset_counter; + int32_t size; + + p_read = serialized_buffer; + if ( NULL == receiver_ftds || NULL == receiver_ftds_num || NULL == serialized_buffer ) + { + return LC3PLUS_RTP_ERR_NULL_PTR; + } + if ( 0 == serialized_buffer_size ) + { + return LC3PLUS_RTP_ERR_EMPTY_TOC; + } + if ( receiver_ftds_num_max <= 0 ) + { + return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; + } + { + int32_t num_bytes_read_sum = 0; + const int32_t min_num_bytes_per_ftd = 2; + int16_t receiver_ftds_index = 0; + bool another_ftd = true; + int32_t num_bytes_read_per_ftd; + + while ( another_ftd ) + { + if ( (int32_t) serialized_buffer_size < min_num_bytes_per_ftd ) + { + return LC3PLUS_RTP_ERR_INVALID_BITSTREAM_SIZE; + } + if ( num_bytes_read_sum >= (int32_t) serialized_buffer_size - min_num_bytes_per_ftd ) + { + return LC3PLUS_RTP_ERR_INVALID_BITSTREAM_SIZE; + } + num_bytes_read_per_ftd = 0; + error = s_parse_ftd( p_read, &receiver_ftds[receiver_ftds_index], &num_bytes_read_per_ftd, serialized_buffer_size - num_bytes_read_sum ); + if ( LC3PLUS_RTP_ERR_NO_ERROR != error ) + { + return error; + } + p_read += num_bytes_read_per_ftd; + num_bytes_read_sum += num_bytes_read_per_ftd; + + if ( receiver_ftds[receiver_ftds_index].fc == LC3PLUS_RTP_FTD_FC_RESERVED ) + { + return LC3PLUS_RTP_ERR_INVALID_BITSTREAM; + } + else if ( receiver_ftds[receiver_ftds_index].fc == LC3PLUS_RTP_FTD_FC_LAST_OVERALL ) + { + another_ftd = false; + } + + if ( another_ftd ) + { + if ( receiver_ftds_index >= receiver_ftds_num_max ) + { + return LC3PLUS_RTP_ERR_NOT_ENOUGH_FTDS_ALLOCATED; + } + ( receiver_ftds_index )++; + } + } + *receiver_ftds_num = receiver_ftds_index + 1; + } + + /* set frame-data pointers into serialized_buffer */ + for ( i = 0; i < *receiver_ftds_num; ++i ) + { + error = LC3PLUS_RTP_frame_data_length_get_size( &size, receiver_ftds[i].frame_data_length ); + if ( error != LC3PLUS_RTP_ERR_NO_ERROR ) + { + return error; + } + ftds_offset_sum += LC3PLUS_RTP_FTD_LENGTH_EXCLUDING_FDL + size; + } + + frame_offset_counter = 0; + for ( i = 0; i < *receiver_ftds_num; ++i ) + { + if ( s_fdl_is_magic_value( receiver_ftds[i].frame_data_length ) ) + { + receiver_ftds[i].frame_data = NULL; + } + else + { + receiver_ftds[i].frame_data = serialized_buffer + ftds_offset_sum + frame_offset_counter; + frame_offset_counter += receiver_ftds[i].frame_data_length; + } + } + + if ( ftds_offset_sum + frame_offset_counter != serialized_buffer_size ) + { + /* parsed content & size n bytes of input buffer do not line up */ + /* if the buffer capacity is larger and the remaining bytes are zero, we don't treat this as an error since it's due to the IVAS-Split rendering zero padding */ + diff = serialized_buffer_size - ( ftds_offset_sum + frame_offset_counter ); + if ( diff < 0 ) + { + return LC3PLUS_RTP_ERR_INVALID_BITSTREAM_SIZE; + } + /* verify that all bytes are zero */ + p_read += frame_offset_counter; + for ( i = 0; i < diff; ++i ) + { + if ( *p_read != 0 ) + { + /* non-zero byte in padding region */ + return LC3PLUS_RTP_ERR_NONZERO_PADDING_BYTES; + } + p_read++; + } + } + return LC3PLUS_RTP_ERR_NO_ERROR; +} + +LC3PLUS_RTP_ERR LC3PLUS_RTP_payload_deserialize( + LC3PLUS_RTP_PAYLOAD *payload, + uint8_t *serialized_buffer, + const size_t serialized_buffer_size ) +{ + int32_t new_frame_duration_us; + int32_t new_sampling_rate_hz; + int16_t new_high_resolution_flag; + int16_t i = 0; + int16_t channel_id = 0; + int16_t media_time_id = 0; + const int16_t invalid_value = -1; + int16_t media_times_per_channel[LC3PLUS_RTP_PAYLOAD_MAX_NUM_CHANNELS]; + int16_t channels_per_media_time[LC3PLUS_RTP_PAYLOAD_MAX_NUM_MEDIA_TIMES]; + LC3PLUS_RTP_ERR err; + + if ( NULL == payload || NULL == serialized_buffer ) + { + return LC3PLUS_RTP_ERR_NULL_PTR; + } + if ( 0 == serialized_buffer_size ) + { + return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; + } + + for ( media_time_id = 0; media_time_id < LC3PLUS_RTP_PAYLOAD_MAX_NUM_MEDIA_TIMES; ++media_time_id ) + { + channels_per_media_time[media_time_id] = invalid_value; + } + media_time_id = 0; + for ( channel_id = 0; channel_id < LC3PLUS_RTP_PAYLOAD_MAX_NUM_CHANNELS; ++channel_id ) + { + media_times_per_channel[channel_id] = invalid_value; + } + channel_id = 0; + + err = s_frame_data_length_parse( &payload->fdl_request, serialized_buffer, serialized_buffer_size ); + if ( LC3PLUS_RTP_ERR_NO_ERROR != err ) + { + return err; + } + int32_t fdl_request_length; + err = LC3PLUS_RTP_frame_data_length_get_size( &fdl_request_length, payload->fdl_request ); + if ( LC3PLUS_RTP_ERR_NO_ERROR != err ) + { + return err; + } + if ( !s_fdl_value_is_valid_request( payload->fdl_request ) ) + { + return LC3PLUS_RTP_ERR_INVALID_FDL_REQUEST; + } + + err = s_ftds_parse( payload->ftds, sizeof( payload->ftds ) / sizeof( LC3PLUS_RTP_FTD ), &payload->num_ftds, serialized_buffer + fdl_request_length, serialized_buffer_size - fdl_request_length ); + if ( LC3PLUS_RTP_ERR_NO_ERROR != err ) + { + return err; + } + if ( 0 == payload->num_ftds ) + { + return LC3PLUS_RTP_ERR_GENERIC_ERROR; + } + /* verify shared setting between all FTDs [samplerate, frame_duration, channel count] */ + + /* initialize on the first FTD, use this as reference */ + err = s_frame_duration_ms_from_fdi( &payload->frame_duration_us, payload->ftds[0].fdi ); + if ( LC3PLUS_RTP_ERR_NO_ERROR != err ) + { + return err; + } + err = s_sampling_rate_hz_from_bwr( &payload->sampling_rate_hz, payload->ftds[0].bwr ); + if ( LC3PLUS_RTP_ERR_NO_ERROR != err ) + { + return err; + } + err = s_high_resolution_flag_from_bwr( &payload->high_resolution_enabled, payload->ftds[0].bwr ); + if ( LC3PLUS_RTP_ERR_NO_ERROR != err ) + { + return err; + } + payload->num_channels = 0; + payload->num_media_times = 0; + for ( i = 0; i < payload->num_ftds; ++i ) + { + if ( payload->ftds[i].h != LC3PLUS_RTP_FTD_H_PRIMARY ) + { + /* not implemented */ + return LC3PLUS_RTP_ERR_NOT_IMPLEMENTED; + } + + err = s_frame_duration_ms_from_fdi( &new_frame_duration_us, payload->ftds[i].fdi ); + if ( LC3PLUS_RTP_ERR_NO_ERROR != err ) + { + return err; + } + if ( payload->frame_duration_us != new_frame_duration_us ) + { + /* mixed frame durations not supported */ + return LC3PLUS_RTP_ERR_UNSUPPORTED_CONFIGURATION; + } + + err = s_sampling_rate_hz_from_bwr( &new_sampling_rate_hz, payload->ftds[i].bwr ); + if ( LC3PLUS_RTP_ERR_NO_ERROR != err ) + { + return err; + } + if ( payload->sampling_rate_hz != new_sampling_rate_hz ) + { + /* mixed sampling frequencies not supported */ + return LC3PLUS_RTP_ERR_UNSUPPORTED_CONFIGURATION; + } + + + err = s_high_resolution_flag_from_bwr( &new_high_resolution_flag, payload->ftds[i].bwr ); + if ( LC3PLUS_RTP_ERR_NO_ERROR != err ) + { + return err; + } + if ( payload->high_resolution_enabled != new_high_resolution_flag ) + { + /* mixed high resolution mode not supported */ + return LC3PLUS_RTP_ERR_UNSUPPORTED_CONFIGURATION; + } + + switch ( payload->ftds[i].fc ) + { + case LC3PLUS_RTP_FTD_FC_LAST_OVERALL: + channels_per_media_time[media_time_id]++; + media_times_per_channel[channel_id]++; + channel_id = 0; + media_time_id = 0; + break; + case LC3PLUS_RTP_FTD_FC_SUBSEQUENT_CHANNEL: + media_times_per_channel[channel_id]++; + channels_per_media_time[media_time_id]++; + channel_id++; + break; + case LC3PLUS_RTP_FTD_FC_LAST_IN_MEDIATIME: + media_times_per_channel[channel_id]++; + channels_per_media_time[media_time_id]++; + channel_id = 0; + media_time_id++; + break; + case LC3PLUS_RTP_FTD_FC_RESERVED: + default: + return LC3PLUS_RTP_ERR_INVALID_BITSTREAM; + } + } + + { + int32_t valid_num_media_times_per_channel; + int32_t iCh; + /* check whether all channels exist for each media time */ + if ( media_times_per_channel[0] == invalid_value ) + { + return LC3PLUS_RTP_ERR_NOT_IMPLEMENTED; + } + valid_num_media_times_per_channel = media_times_per_channel[0]; + for ( iCh = 0; iCh < LC3PLUS_RTP_PAYLOAD_MAX_NUM_CHANNELS; ++iCh ) + { + if ( media_times_per_channel[iCh] == invalid_value ) + { + break; + } + if ( valid_num_media_times_per_channel != media_times_per_channel[iCh] ) + { + return LC3PLUS_RTP_ERR_NOT_IMPLEMENTED; + } + } + } + { + /* whether all media times exist for each channel */ + int32_t iMediaTime; + int32_t valid_num_channels_per_media_time; + if ( channels_per_media_time[0] == invalid_value ) + { + return LC3PLUS_RTP_ERR_NOT_IMPLEMENTED; + } + valid_num_channels_per_media_time = channels_per_media_time[0]; + for ( iMediaTime = 0; iMediaTime < LC3PLUS_RTP_PAYLOAD_MAX_NUM_MEDIA_TIMES; ++iMediaTime ) + { + if ( channels_per_media_time[iMediaTime] == invalid_value ) + { + break; + } + if ( valid_num_channels_per_media_time != channels_per_media_time[iMediaTime] ) + { + return LC3PLUS_RTP_ERR_NOT_IMPLEMENTED; + } + } + } + + /* convert zero-index to count */ + payload->num_channels = channels_per_media_time[0] + 1; + payload->num_media_times = media_times_per_channel[0] + 1; + + /* verify that all media times have the same number of channels, partial packets are not supported */ + if ( payload->num_ftds != payload->num_channels * payload->num_media_times ) + { + return LC3PLUS_RTP_ERR_GENERIC_ERROR; + } + return LC3PLUS_RTP_ERR_NO_ERROR; +} + +LC3PLUS_RTP_ERR LC3PLUS_RTP_ftd_bwr_from_samplerate( LC3PLUS_RTP_FTD_BWR *bwr, const int32_t sampling_rate, const int32_t high_res_enabled ) +{ + if ( NULL == bwr ) + { + return LC3PLUS_RTP_ERR_NULL_PTR; + } + switch ( sampling_rate ) + { + case 8000: + if ( high_res_enabled ) + { + return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; + } + *bwr = LC3PLUS_RTP_FTD_BWR_NB; + return LC3PLUS_RTP_ERR_NO_ERROR; + case 16000: + if ( high_res_enabled ) + { + return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; + } + *bwr = LC3PLUS_RTP_FTD_BWR_WB; + return LC3PLUS_RTP_ERR_NO_ERROR; + case 24000: + if ( high_res_enabled ) + { + return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; + } + *bwr = LC3PLUS_RTP_FTD_BWR_SSWB; + return LC3PLUS_RTP_ERR_NO_ERROR; + case 32000: + if ( high_res_enabled ) + { + return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; + } + *bwr = LC3PLUS_RTP_FTD_BWR_SWB; + return LC3PLUS_RTP_ERR_NO_ERROR; + case 44100: + if ( high_res_enabled ) + { + return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; + } + *bwr = LC3PLUS_RTP_FTD_BWR_FBCD; + return LC3PLUS_RTP_ERR_NO_ERROR; + case 48000: + if ( 0 == high_res_enabled ) + { + *bwr = LC3PLUS_RTP_FTD_BWR_FB; + return LC3PLUS_RTP_ERR_NO_ERROR; + } + else + { + *bwr = LC3PLUS_RTP_FTD_BWR_FBHR; + return LC3PLUS_RTP_ERR_NO_ERROR; + } + case 96000: + if ( 0 == high_res_enabled ) + { + return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; + } + *bwr = LC3PLUS_RTP_FTD_BWR_UBHR; + return LC3PLUS_RTP_ERR_NO_ERROR; + default: + break; + } + + return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; +} + +LC3PLUS_RTP_ERR LC3PLUS_RTP_ftd_fdi_from_frame_duration_us( LC3PLUS_RTP_FTD_FDI *fdi, const int32_t frame_duration_us ) +{ + if ( NULL == fdi ) + { + return LC3PLUS_RTP_ERR_NULL_PTR; + } + switch ( frame_duration_us ) + { + case 2500: + *fdi = LC3PLUS_RTP_FTD_FDI_2500_US; + return LC3PLUS_RTP_ERR_NO_ERROR; + case 5000: + *fdi = LC3PLUS_RTP_FTD_FDI_5000_US; + return LC3PLUS_RTP_ERR_NO_ERROR; + case 10000: + *fdi = LC3PLUS_RTP_FTD_FDI_10000_US; + return LC3PLUS_RTP_ERR_NO_ERROR; + default: + break; + } + + return LC3PLUS_RTP_ERR_INVALID_PARAMETERS; +} + +#endif /* ISAR_BITSTREAM_UPDATE_LC3PLUS */ +#endif /* SPLIT_REND_WITH_HEAD_ROT */ diff --git a/lib_isar/isar_lc3plus_payload.h b/lib_isar/isar_lc3plus_payload.h new file mode 100644 index 000000000..3af6757fa --- /dev/null +++ b/lib_isar/isar_lc3plus_payload.h @@ -0,0 +1,216 @@ +/****************************************************************************************************** + + (C) 2022-2023 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 ISAR_LC3PLUS_PAYLOAD_H +#define ISAR_LC3PLUS_PAYLOAD_H + +#include +#include +#include "lc3.h" +#include "options.h" + +#ifdef SPLIT_REND_WITH_HEAD_ROT +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + +/* Implementation of the "B.2.6 Table of contents" part of the RTP payload format + * for LC3plus as specified in ETSI TS 103 634. */ + +typedef enum LC3PLUS_RTP_ERR +{ + LC3PLUS_RTP_ERR_NO_ERROR, + LC3PLUS_RTP_ERR_NULL_PTR, + LC3PLUS_RTP_ERR_INVALID_PARAMETERS, + LC3PLUS_RTP_ERR_EMPTY_TOC, + LC3PLUS_RTP_ERR_NOT_IMPLEMENTED, + LC3PLUS_RTP_ERR_UNSUPPORTED_CONFIGURATION, + LC3PLUS_RTP_ERR_INVALID_BITSTREAM, + LC3PLUS_RTP_ERR_INVALID_BITSTREAM_SIZE, + LC3PLUS_RTP_ERR_NOT_ENOUGH_FTDS_ALLOCATED, + LC3PLUS_RTP_ERR_INVALID_FDL_REQUEST, + LC3PLUS_RTP_ERR_NONZERO_PADDING_BYTES, + LC3PLUS_RTP_ERR_GENERIC_ERROR +} LC3PLUS_RTP_ERR; + +/* + * The content of the FTD is shown in Figure B.6. + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |FC |FDI| BWR |H| FDL1 | (FDL2) | (FDL3) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + +/* FC (2 bits): + * Frame and Channel (FC) indicator for subsequent frame data (if available). The meaning of the FC + * indicator is shown in Table B.2. The FC value defines the media time stamp (in integer increments + * of TSI) and the channel counter (CC, starting from 1 for the first channel) for the subsequent + * FTD (if available). */ +typedef enum LC3PLUS_RTP_FTD_FC +{ + LC3PLUS_RTP_FTD_FC_LAST_OVERALL = 0x00, /* Last FDL in ToC, no FDL follows the current FDL */ + LC3PLUS_RTP_FTD_FC_SUBSEQUENT_CHANNEL = 0x01, /* The next FDL is for the next channel for the same media time */ + LC3PLUS_RTP_FTD_FC_LAST_IN_MEDIATIME = 0x02, /* The next FDL is for first channel for next media time, channel counter is reset */ + LC3PLUS_RTP_FTD_FC_RESERVED = 0x03, /* Reserved */ +} LC3PLUS_RTP_FTD_FC; +#define LC3PLUS_RTP_FTD_FC_MASK 0x03 + +/* FDI (2 bits): + * Frame Duration Index, with encoding as shown in Table B.3. The FDI shall be static for a given + * payload type during the session. The FDI also dictates the TSI, needed for deriving the media + * time in case of more than one frame in the payload. */ +typedef enum LC3PLUS_RTP_FTD_FDI +{ + LC3PLUS_RTP_FTD_FDI_2500_US = 0x00, + LC3PLUS_RTP_FTD_FDI_5000_US = 0x04, + LC3PLUS_RTP_FTD_FDI_10000_US = 0x08, + LC3PLUS_RTP_FTD_FDI_RESERVED = 0x0C, +} LC3PLUS_RTP_FTD_FDI; +#define LC3PLUS_RTP_FTD_FDI_MASK 0x0C +LC3PLUS_RTP_ERR LC3PLUS_RTP_ftd_fdi_from_frame_duration_us( LC3PLUS_RTP_FTD_FDI *fdi, const int32_t frame_duration_us ); + +/* BWR (3 bits): + * Bandwidth and resolution combination used by the codec is jointly encoded into a bandwidth and + * resolution (BWR) index. The BWR index is encoded as shown in Table B.4. The BWR encoding is + * defined in Table B.4. The BWR index shall be static for a given payload type during the session. */ +typedef enum LC3PLUS_RTP_FTD_BWR +{ + LC3PLUS_RTP_FTD_BWR_NB = 0x00, + LC3PLUS_RTP_FTD_BWR_WB = 0x10, + LC3PLUS_RTP_FTD_BWR_SSWB = 0x20, + LC3PLUS_RTP_FTD_BWR_SWB = 0x30, + LC3PLUS_RTP_FTD_BWR_FBCD = 0x40, + LC3PLUS_RTP_FTD_BWR_FB = 0x50, + LC3PLUS_RTP_FTD_BWR_FBHR = 0x60, + LC3PLUS_RTP_FTD_BWR_UBHR = 0x70, +} LC3PLUS_RTP_FTD_BWR; +#define LC3PLUS_RTP_FTD_BWR_MASK 0x70 +LC3PLUS_RTP_ERR LC3PLUS_RTP_ftd_bwr_from_samplerate( LC3PLUS_RTP_FTD_BWR *bwr, const int32_t sampling_rate, const int32_t high_res_enabled ); + +/* H (1 bit): + * Indicates whether the corresponding frame is a normal frame (primary encoding) or a helper frame + * (secondary encoding). 0 indicates a primary frame, 1 indicates secondary (redundant) frame */ +typedef enum LC3PLUS_RTP_FTD_H +{ + LC3PLUS_RTP_FTD_H_PRIMARY = 0x00, + LC3PLUS_RTP_FTD_H_SECONDARY = 0x80, +} LC3PLUS_RTP_FTD_H; +#define LC3PLUS_RTP_FTD_H_MASK 0x80 + +typedef enum LC3PLUS_RTP_FDL +{ + LC3PLUS_RTP_FDL_NO_REQ_OR_NO_DATA = 0, + LC3PLUS_RTP_FDL_SPEECH_BAD = 1, + LC3PLUS_RTP_FDL_SPEECH_SID = 2, + LC3PLUS_RTP_FDL_RESERVED_MIN = 3, + LC3PLUS_RTP_FDL_RESERVED_MAX = 19, + LC3PLUS_RTP_FDL_LENGTH_1_MIN = 20, + LC3PLUS_RTP_FDL_LENGTH_1_MAX = 254, + LC3PLUS_RTP_FDL_LENGTH_2_MIN = 255, + LC3PLUS_RTP_FDL_LENGTH_2_MAX = 509, + LC3PLUS_RTP_FDL_LENGTH_3_MIN = 510, + LC3PLUS_RTP_FDL_LENGTH_3_MAX = 765 +} LC3PLUS_RTP_FDL; +/* value used to indicate that the Frame Data Length (FDL) extends to the next byte */ +#define LC3PLUS_RTP_FDL_EXTENSION_VALUE 0xFF + +typedef struct LC3PLUS_RTP_FTD +{ + LC3PLUS_RTP_FTD_FC fc; + LC3PLUS_RTP_FTD_FDI fdi; + LC3PLUS_RTP_FTD_BWR bwr; + LC3PLUS_RTP_FTD_H h; + uint8_t *frame_data; + LC3PLUS_RTP_FDL frame_data_length; +} LC3PLUS_RTP_FTD; +#define LC3PLUS_RTP_FTD_LENGTH_EXCLUDING_FDL 1 +#define LC3PLUS_RTP_FDL_MIN_LENGTH 1 +#define LC3PLUS_RTP_FTD_MIN_SIZE ( LC3PLUS_RTP_FTD_LENGTH_EXCLUDING_FDL + LC3PLUS_RTP_FDL_MIN_LENGTH ) + +/*! Serialize the sender_ftds structs and fdl_request into a linear compact buffer + * @param[out] serialized_buffer pointer to the start of the memory location where the serialized buffer will be written to + * @param[in] serialized_buffer_capacity capacity of the serialized_buffer in bytes + * @param[out] packed_buffer_actual_size actually used size of in bytes of the packed_buffer (<=serialized_buffer_capacity) + * @param[in] fdl_request frame data length request + * @param[in,out] sender_ftds the function will overwrite the frame_data pointer with the correct memory location in + * the packed_buffer (so it can subsequently be used as input for the LC3plus encode call) + * @param[in] sender_ftds_num number of sender_ftds + * @return LC3PLUS_RTP_ERR_NO_ERROR in case of success */ +LC3PLUS_RTP_ERR LC3PLUS_RTP_payload_serialize( + uint8_t *serialized_buffer, + const size_t serialized_buffer_capacity, + size_t *packed_buffer_actual_size, + const LC3PLUS_RTP_FDL fdl_request, + LC3PLUS_RTP_FTD *sender_ftds, + const size_t sender_ftds_num ); + +/*! Get size of the frame data length field for a certain frame data length value in bytes. + * @param[out] length size of the frame data length field in bytes [1,2,3] + * @param[in] frameDataLengthValue frame data length value + * @return LC3PLUS_RTP_ERR_NO_ERROR in case of success */ +LC3PLUS_RTP_ERR LC3PLUS_RTP_frame_data_length_get_size( int32_t *length, const LC3PLUS_RTP_FDL frameDataLengthValue ); + +#define LC3PLUS_RTP_PAYLOAD_MAX_NUM_CHANNELS 16 +#define LC3PLUS_RTP_PAYLOAD_MAX_NUM_MEDIA_TIMES 8 /* max ivas frame duration/min lc3plus frame duration: 20000/2500 */ +#define LC3PLUS_RTP_PAYLOAD_MAX_NUM_FTDS LC3PLUS_RTP_PAYLOAD_MAX_NUM_CHANNELS *LC3PLUS_RTP_PAYLOAD_MAX_NUM_MEDIA_TIMES + +typedef struct LC3PLUS_RTP_PAYLOAD_CONFIG +{ + /* frame duration in us shared among all FTDs */ + int32_t frame_duration_us; + /* high resolution flag shared among all FTDs */ + int16_t high_resolution_enabled; + /* sampling frequency shared among all FTDs */ + int32_t sampling_rate_hz; + /* number of individual channels in the payload */ + int16_t num_channels; + /* number of individual media times in the payload */ + int16_t num_media_times; + /* frame data length request */ + LC3PLUS_RTP_FDL fdl_request; + /* FTD data with pointer to raw frame data */ + LC3PLUS_RTP_FTD ftds[LC3PLUS_RTP_PAYLOAD_MAX_NUM_FTDS]; + /* actual number of ftds */ + int16_t num_ftds; +} LC3PLUS_RTP_PAYLOAD; + +/*! Deserialized a serialized buffer into a LC3PLUS_RTP_PAYLOAD struct + * @param payload pointer to target LC3PLUS_RTP_PAYLOAD object. Note: frame_data pointers in the struct will point to the respective memory locations in the serialized_buffer. + * @param serialized_buffer pointer to the start of the serialized input buffer + * @param serialized_buffer_size size of the serialized input buffer in bytes + * @return LC3PLUS_RTP_ERR_NO_ERROR in case of success */ +LC3PLUS_RTP_ERR LC3PLUS_RTP_payload_deserialize( + LC3PLUS_RTP_PAYLOAD *payload, + uint8_t *serialized_buffer, + const size_t serialized_buffer_size ); + +#endif /* ISAR_BITSTREAM_UPDATE_LC3PLUS */ +#endif /* #ifdef SPLIT_REND_WITH_HEAD_ROT */ +#endif /* ISAR_LC3PLUS_PAYLOAD_H */ diff --git a/lib_isar/isar_lcld_decoder.c b/lib_isar/isar_lcld_decoder.c new file mode 100644 index 000000000..47045ba59 --- /dev/null +++ b/lib_isar/isar_lcld_decoder.c @@ -0,0 +1,1711 @@ +/****************************************************************************************************** + + (C) 2022-2023 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. + +*******************************************************************************************************/ + +#include +#include "options.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT +#include "isar_lcld_prot.h" +#include "isar_rom_lcld_tables.h" +#include "prot.h" +#include +#include "isar_prot.h" +#include "wmc_auto.h" + + +/*------------------------------------------------------------------------------------------* + * Local constants + *------------------------------------------------------------------------------------------*/ + +#define HUFF_READ_SIZE ( 4 ) + +/*------------------------------------------------------------------------------------------* + * Local structures + *------------------------------------------------------------------------------------------*/ + +typedef struct TableNode +{ + struct TableNode **ppoNextTable; + struct TableNode *poOrderedNext; + + int32_t *piCodeIndex; + int32_t *piDifference; + int32_t *piLength; +} TableNode; +typedef struct TableList +{ + TableNode *poOrderedTop; + TableNode *poOrderedBottom; + +} TableList; + +struct LCLD_DECODER +{ + int32_t iSampleRate; + int32_t iChannels; + int32_t iNumBlocks; + + int32_t iNumBands; + const int32_t *piBandwidths; + + int32_t iMSMode; + int32_t *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; + + PredictionDecoder *psPredictionDecoder; + + + 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 TableNode *CreateTableList( const int32_t iReadLength ) +{ + int32_t n; + int32_t iMaxTables; + TableNode *ptable_top; + iMaxTables = 1 << 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->ppoNextTable[n] = NULL; + ptable_top->piCodeIndex[n] = 0xffff; + ptable_top->piDifference[n] = 0; + ptable_top->piLength[n] = 0; + } + + return ptable_top; +} +static void DeleteTableList( TableList *ptable_list, int32_t iTables ) +{ + + TableNode *node; + node = ptable_list->poOrderedTop; + + while ( ( iTables ) ) + { + + TableNode *node1 = node; + node = node1->poOrderedNext; + if ( node1->piCodeIndex != NULL ) + { + free( node1->piCodeIndex ); + } + if ( node1->piLength != NULL ) + { + free( node1->piLength ); + } + if ( node1->piDifference != NULL ) + { + free( node1->piDifference ); + } + if ( node1->ppoNextTable != NULL ) + { + free( node1->ppoNextTable ); + } + if ( node1 != NULL ) + { + free( node1 ); + } + iTables--; + } + 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 ) +{ + TableNode *poNextNode; + + 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 */ + table_list->poOrderedBottom->poOrderedNext = poNextNode; + table_list->poOrderedBottom = poNextNode; + + ( *iTablesCreated )++; + } + 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 ) +{ + + int32_t iMaxTables; + int32_t j; + TableNode *poNode; + + iMaxTables = 1 << iReadLength; + psLCLDDecoder->c_apauiHuffDecTable_RAM[n] = + malloc( iTablesCreated * iMaxTables * sizeof( uint32_t ) ); + + poNode = ptable_list->poOrderedTop; + for ( j = 0; j < iTablesCreated; j++ ) + { + int32_t k; + if ( poNode != NULL ) + { + for ( k = 0; k < iMaxTables; k++ ) + { + uint32_t uiCode; + uiCode = poNode->piDifference[k]; + uiCode <<= 16; + uiCode |= poNode->piCodeIndex[k]; + psLCLDDecoder->c_apauiHuffDecTable_RAM[n][j][k] = uiCode; + } + } + 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 ) +{ + int32_t iDifference; + int32_t iMask; + int32_t iCurrentLength; + int32_t iIndex; + int32_t iCodeLow; + int32_t iCodeHigh; + + TableNode *poNode; + poNode = ptable_list->poOrderedTop; + iMask = ( 1 << iReadLength ) - 1; + iCurrentLength = iLength; + while ( iCurrentLength > iReadLength ) + { + iDifference = iCurrentLength - iReadLength; + iIndex = iCode >> iDifference; + iIndex &= iMask; + poNode = GetNextTable( iIndex, ptable_list, poNode, iReadLength, iTables ); + 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++ ) + { + poNode->piCodeIndex[iIndex] = iCodeIndex; + poNode->piDifference[iIndex] = iDifference; + poNode->piLength[iIndex] = iLength; + } +} + +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 ) +{ + int32_t n; + uint32_t **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[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; + } + + for ( n = 0; n < iSize; n++ ) + { + uint32_t iMin; + int32_t iMinIndex; + int32_t k; + + iMin = ppsort_enc_table[n][0]; + iMinIndex = n; + for ( k = n; k < iSize; k++ ) + { + if ( ppsort_enc_table[k][0] < iMin ) + { + iMin = ppsort_enc_table[k][0]; + iMinIndex = k; + } + } + + if ( iMinIndex != n ) + { + uint32_t uiLength; + uint32_t uiCode; + uint32_t uiCodeIndex; + + uiLength = ppsort_enc_table[n][0]; + uiCode = ppsort_enc_table[n][1]; + uiCodeIndex = ppsort_enc_table[n][2]; + + ppsort_enc_table[n][0] = ppsort_enc_table[iMinIndex][0]; + ppsort_enc_table[n][1] = ppsort_enc_table[iMinIndex][1]; + ppsort_enc_table[n][2] = ppsort_enc_table[iMinIndex][2]; + + ppsort_enc_table[iMinIndex][0] = uiLength; + ppsort_enc_table[iMinIndex][1] = uiCode; + ppsort_enc_table[iMinIndex][2] = uiCodeIndex; + } + } + ptable_list->poOrderedTop = CreateTableList( iReadLength ); + ptable_list->poOrderedBottom = ptable_list->poOrderedTop; + for ( n = 0; n < iSize; n++ ) + { + int32_t iLength; + int32_t iCode; + int32_t iCodeIndex; + + iLength = ppsort_enc_table[n][0]; + iCode = ppsort_enc_table[n][1]; + iCodeIndex = ppsort_enc_table[n][2]; + 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++ ) + { + free( ppsort_enc_table[n] ); + } + free( ppsort_enc_table ); +} + + +/*------------------------------------------------------------------------------------------* + * Function CreateLCLDDecoder() + * + * + *------------------------------------------------------------------------------------------*/ + +ivas_error CreateLCLDDecoder( + LCLDDecoder **psLCLDDecoder_out, + const int32_t iSampleRate, + const int32_t iChannels, + const int32_t iNumBlocks, + const int32_t iRealOnlyOut ) +{ + int32_t n; + int32_t 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 ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + psLCLDDecoder->iSampleRate = iSampleRate; + psLCLDDecoder->iChannels = iChannels; + psLCLDDecoder->iAllocOffset = 0; + psLCLDDecoder->iRealOnlyOut = iRealOnlyOut; + if ( iRealOnlyOut == 1 ) + { + psLCLDDecoder->iNumBlocks = iNumBlocks / 2; + } + else + { + psLCLDDecoder->iNumBlocks = iNumBlocks; + } + psLCLDDecoder->iNumBands = 0; /* read from bitstream*/ + psLCLDDecoder->piBandwidths = c_aiBandwidths48; + + psLCLDDecoder->iMSMode = 0; + if ( ( psLCLDDecoder->piMSFlags = (int32_t *) malloc( MAX_BANDS * sizeof( int32_t ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + for ( n = 0; n < MAX_BANDS; n++ ) + { + psLCLDDecoder->piLRPhaseDiffs[n] = 0; + psLCLDDecoder->piMSPredCoefs[n] = 0; + } + + psLCLDDecoder->iCommonGrouping = 1; /* Common grouping always on only impacts stereo */ + if ( ( psLCLDDecoder->piNumGroups = (int32_t *) malloc( psLCLDDecoder->iChannels * sizeof( int32_t ) ) ) == 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 ) + { + 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 ) + { + 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 ) + { + 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 ) + { + 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 ) + { + 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 ) + { + 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 ) + { + 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 ) + { + 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 ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \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 ) + { + 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 ) + { + 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 ) + { + 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 ) + { + 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 ) + { + 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 ) + { + 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 ) + { + 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 ) + { + 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 ) + { + 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++ ) + { + if ( ( psLCLDDecoder->pppiRMSEnvelope[n][k] = (int32_t *) malloc( MAX_BANDS * sizeof( int32_t ) ) ) == 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 ) + { + 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 ) + { + 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 ) + { + 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 ) + { + 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 ) + { + 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 ) + { + 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 ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + } + } + + read_length = READ_LENGTH; + for ( n = 0; n < ALLOC_TABLE_SIZE * 2; n++ ) + { + psLCLDDecoder->num_decode_table[n] = 1; + if ( c_apauiHuffEncTabels[n] != NULL ) + { + + CreateDecodeTable( psLCLDDecoder, n, c_apauiHuffEncTabels[n], num_row_aauiLCLDHuff[n], read_length, &psLCLDDecoder->num_decode_table[n] ); + } + else + { + psLCLDDecoder->c_apauiHuffDecTable_RAM[n] = NULL; + } + } + + if ( ( error = CreatePredictionDecoder( &psLCLDDecoder->psPredictionDecoder, iChannels, psLCLDDecoder->iNumBlocks ) ) != IVAS_ERR_OK ) + { + return error; + } + psLCLDDecoder->psNoiseGen = NULL; /* CreateNoiseGen(); No noise fill for now*/ + *psLCLDDecoder_out = psLCLDDecoder; + + return IVAS_ERR_OK; +} + + +/*------------------------------------------------------------------------------------------* + * Function CreateLCLDDecoder() + * + * + *------------------------------------------------------------------------------------------*/ + +void DeleteLCLDDecoder( LCLDDecoder *psLCLDDecoder ) +{ + int32_t k, n; + + if ( psLCLDDecoder != NULL ) + { + if ( psLCLDDecoder->piMSFlags != NULL ) + { + free( psLCLDDecoder->piMSFlags ); + } + + if ( psLCLDDecoder->piNumGroups != NULL ) + { + free( psLCLDDecoder->piNumGroups ); + } + + if ( psLCLDDecoder->ppiGroupLengths != NULL ) + { + for ( n = 0; n < psLCLDDecoder->iChannels; n++ ) + { + free( psLCLDDecoder->ppiGroupLengths[n] ); + } + free( psLCLDDecoder->ppiGroupLengths ); + } + + if ( psLCLDDecoder->pppiRMSEnvelope != NULL ) + { + for ( n = 0; n < psLCLDDecoder->iChannels; n++ ) + { + for ( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) + { + free( psLCLDDecoder->pppiRMSEnvelope[n][k] ); + } + free( psLCLDDecoder->pppiRMSEnvelope[n] ); + } + free( psLCLDDecoder->pppiRMSEnvelope ); + } + + if ( psLCLDDecoder->pppiSMR != NULL ) + { + for ( n = 0; n < psLCLDDecoder->iChannels; n++ ) + { + for ( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) + { + free( psLCLDDecoder->pppiSMR[n][k] ); + } + free( psLCLDDecoder->pppiSMR[n] ); + } + free( psLCLDDecoder->pppiSMR ); + } + + if ( psLCLDDecoder->pppiExcitation != NULL ) + { + for ( n = 0; n < psLCLDDecoder->iChannels; n++ ) + { + for ( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) + { + free( psLCLDDecoder->pppiExcitation[n][k] ); + } + free( psLCLDDecoder->pppiExcitation[n] ); + } + free( psLCLDDecoder->pppiExcitation ); + } + + + if ( psLCLDDecoder->pppiAlloc != NULL ) + { + for ( n = 0; n < psLCLDDecoder->iChannels; n++ ) + { + for ( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) + { + free( psLCLDDecoder->pppiAlloc[n][k] ); + } + free( psLCLDDecoder->pppiAlloc[n] ); + } + free( psLCLDDecoder->pppiAlloc ); + } + + if ( psLCLDDecoder->pppiLCLDSignReal != NULL ) + { + for ( n = 0; n < psLCLDDecoder->iChannels; n++ ) + { + for ( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) + { + free( psLCLDDecoder->pppiLCLDSignReal[n][k] ); + } + free( psLCLDDecoder->pppiLCLDSignReal[n] ); + } + free( psLCLDDecoder->pppiLCLDSignReal ); + } + + if ( psLCLDDecoder->pppiLCLDSignImag != NULL ) + { + for ( n = 0; n < psLCLDDecoder->iChannels; n++ ) + { + for ( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) + { + free( psLCLDDecoder->pppiLCLDSignImag[n][k] ); + } + free( psLCLDDecoder->pppiLCLDSignImag[n] ); + } + free( psLCLDDecoder->pppiLCLDSignImag ); + } + + if ( psLCLDDecoder->pppiQLCLDReal != NULL ) + { + for ( n = 0; n < psLCLDDecoder->iChannels; n++ ) + { + for ( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) + { + free( psLCLDDecoder->pppiQLCLDReal[n][k] ); + } + free( psLCLDDecoder->pppiQLCLDReal[n] ); + } + free( psLCLDDecoder->pppiQLCLDReal ); + } + + if ( psLCLDDecoder->pppiQLCLDImag != NULL ) + { + for ( n = 0; n < psLCLDDecoder->iChannels; n++ ) + { + for ( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) + { + free( psLCLDDecoder->pppiQLCLDImag[n][k] ); + } + free( psLCLDDecoder->pppiQLCLDImag[n] ); + } + free( psLCLDDecoder->pppiQLCLDImag ); + } + + for ( n = 0; n < ALLOC_TABLE_SIZE * 2; n++ ) + { + if ( psLCLDDecoder->num_decode_table[n] > 1 ) + { + + if ( psLCLDDecoder->c_apauiHuffDecTable_RAM[n] != NULL ) + { + free( psLCLDDecoder->c_apauiHuffDecTable_RAM[n] ); + } + } + } + + if ( psLCLDDecoder->psPredictionDecoder != NULL ) + { + DeletePredictionDecoder( psLCLDDecoder->psPredictionDecoder ); + psLCLDDecoder->psPredictionDecoder = NULL; + } + + if ( psLCLDDecoder->psNoiseGen != NULL ) + { + DeleteNoiseGen( psLCLDDecoder->psNoiseGen ); + } + + free( psLCLDDecoder ); + } +} + +/*------------------------------------------------------------------------------------------* + * Local function declarations + * + * + *------------------------------------------------------------------------------------------*/ + +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 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( 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 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 int32_t ReadHeaderInformation( int32_t *piNumBands, 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 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 int32_t ReadHuff( const uint32_t ( *pauiHuffDecTable )[HUFF_DEC_TABLE_SIZE], int32_t *piSymbol, 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 ); + +void SetDecodingUnresolved( LCLDDecoder *psLCLDDecoder ) +{ + int32_t n, ch; + PredictionDecoder *psPredictionDecoder = psLCLDDecoder->psPredictionDecoder; + for ( ch = 0; ch < psPredictionDecoder->iChannels; ch++ ) + { + for ( n = 0; n < psPredictionDecoder->iNumSubSets; n++ ) + { + psPredictionDecoder->ppiDecodingUnresolved[ch][n] = 1; + psPredictionDecoder->ppiDecodingFailed[ch][n] = 1; + psPredictionDecoder->ppiDecodingFailedPrev[ch][n] = 1; + } + } +} + +int32_t AnyDecodingFailedPrev( LCLDDecoder *psLCLDDecoder ) +{ + int32_t n, ch; + PredictionDecoder *psPredictionDecoder = psLCLDDecoder->psPredictionDecoder; + for ( ch = 0; ch < psPredictionDecoder->iChannels; ch++ ) + { + for ( n = 0; n < psPredictionDecoder->iNumSubSets; n++ ) + { + if ( psPredictionDecoder->ppiDecodingFailedPrev[ch][n] == 1 ) + { + return 1; + } + } + } + return 0; +} + +int32_t AnyDecodingFailed( LCLDDecoder *psLCLDDecoder ) +{ + int32_t n, ch; + PredictionDecoder *psPredictionDecoder = psLCLDDecoder->psPredictionDecoder; + for ( ch = 0; ch < psPredictionDecoder->iChannels; ch++ ) + { + for ( n = 0; n < psPredictionDecoder->iNumSubSets; n++ ) + { + if ( psPredictionDecoder->ppiDecodingFailed[ch][n] == 1 ) + { + return 1; + } + } + } + return 0; +} + +int32_t **GetDecodingFailedStatus( LCLDDecoder *psLCLDDecoder ) +{ + return psLCLDDecoder->psPredictionDecoder->ppiDecodingFailed; +} + +int16_t GetNumSubSets( LCLDDecoder *psLCLDDecoder ) +{ + return (int16_t) psLCLDDecoder->psPredictionDecoder->iNumSubSets; +} + +int32_t **GetDecodingFailedPrevStatus( LCLDDecoder *psLCLDDecoder ) +{ + return psLCLDDecoder->psPredictionDecoder->ppiDecodingFailedPrev; +} + +static void UnpackReal( + const int32_t iChannels, + const int32_t iNumBlocks, + float ***pppfReal, + float ***pppfImag ) +{ + int32_t ch, b, n; + for ( ch = 0; ch < iChannels; ch++ ) + { + for ( b = 0; b < LCLD_BANDS; b++ ) + { + int32_t 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; + iRealBlock -= 2; + } + } + } +} + +/*------------------------------------------------------------------------------------------* + * Function DecodeLCLDFrame() + * + * + *------------------------------------------------------------------------------------------*/ + +int32_t DecodeLCLDFrame( + LCLDDecoder *psLCLDDecoder, + ISAR_SPLIT_REND_BITS_HANDLE pBits, + float ***pppfLCLDReal, + float ***pppfLCLDImag ) +{ + int32_t k, n; + + ReadHeaderInformation( &psLCLDDecoder->iNumBands, pBits ); + + if ( psLCLDDecoder->iChannels == 2 ) + { + ReadMSInformation( psLCLDDecoder->iNumBands, &psLCLDDecoder->iMSMode, psLCLDDecoder->piMSFlags, psLCLDDecoder->piLRPhaseDiffs, psLCLDDecoder->piMSPredCoefs, pBits ); + } + + ReadPredictors( 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 ); + + + ReadAllocInformation( &psLCLDDecoder->iAllocOffset, pBits ); + + if ( psLCLDDecoder->iChannels == 2 && psLCLDDecoder->iCommonGrouping == 1 ) + { /* MS Mode? */ + 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] ); + } + } + else + { + for ( n = 0; n < psLCLDDecoder->iChannels; n++ ) + { /* This will be updated to support multiple sample rates*/ + for ( k = 0; k < psLCLDDecoder->piNumGroups[n]; k++ ) + { + PerceptualModel( 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 ); + + ReadLCLDData( + psLCLDDecoder->piNumGroups, + psLCLDDecoder->ppiGroupLengths, + psLCLDDecoder->iNumBands, + psLCLDDecoder->iChannels, + psLCLDDecoder->psPredictionDecoder->ppiDecodingUnresolved, + psLCLDDecoder->psPredictionDecoder->ppiPredBandEnable, + psLCLDDecoder->psPredictionDecoder->iNumSubSets, + psLCLDDecoder->psPredictionDecoder->iSubSetId, + psLCLDDecoder->pppiAlloc, + psLCLDDecoder->pppiLCLDSignReal, + psLCLDDecoder->pppiLCLDSignImag, + psLCLDDecoder->pppiQLCLDReal, + psLCLDDecoder->pppiQLCLDImag, + psLCLDDecoder->psPredictionDecoder->ppiDecodingFailed, + pBits, + psLCLDDecoder->c_apauiHuffDecTable_RAM ); + + 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 ); + } +#ifdef DEBUG_WRITE_PREDICTORS + { + static FILE *fid; + if ( !fid ) + fid = fopen( "pred_dec.txt", "wt" ); + for ( n = 0; n < psLCLDDecoder->iChannels; n++ ) + { + int16_t b; + for ( b = 0; b < 60; b++ ) + fprintf( fid, "%.5f ", (float) psLCLDDecoder->psPredictionDecoder->ppiPredBandEnable[n][b] * psLCLDDecoder->psPredictionDecoder->ppfA1Imag[n][b] ); + } + fprintf( fid, "%d %d\n", psLCLDDecoder->psPredictionDecoder->iSubSetId, psLCLDDecoder->psPredictionDecoder->piPredChanEnable[n] ); + } +#endif + + ApplyInversePredictors( psLCLDDecoder->psPredictionDecoder, pppfLCLDReal, pppfLCLDImag ); + + for ( n = 0; n < psLCLDDecoder->iChannels; n++ ) + { + ApplyRMSEnvelope( psLCLDDecoder->iNumBands, psLCLDDecoder->piBandwidths, + psLCLDDecoder->piNumGroups[n], + (const int32_t *) psLCLDDecoder->ppiGroupLengths[n], + psLCLDDecoder->pppiRMSEnvelope[n], + pppfLCLDReal[n], pppfLCLDImag[n] ); + } + + if ( psLCLDDecoder->iChannels == 2 && psLCLDDecoder->iMSMode > 0 ) + { + 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 ); + } + + if ( psLCLDDecoder->iRealOnlyOut == 1 ) + { + UnpackReal( psLCLDDecoder->iChannels, + psLCLDDecoder->iNumBlocks * 2, + pppfLCLDReal, + pppfLCLDImag ); + } + + 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 ) +{ + int32_t b, k, n; + int32_t iBlockOffset, iFBOffset; + + iBlockOffset = 0; + for ( n = 0; n < iNumGroups; n++ ) + { + for ( k = 0; k < piGroupLengths[n]; k++ ) + { + iFBOffset = 0; + for ( b = 0; b < iNumBands; b++ ) + { + int32_t m; + int32_t iRMSEnv; + float fGain; + + iRMSEnv = ppiRMSEnvelope[n][b]; + fGain = + c_afRMSEnvReconstructTable[ENV_RECONSTRUCT_TABLE_CENTER + iRMSEnv]; + for ( m = 0; m < piBandwidths[b]; m++ ) + { + ppfReal[iBlockOffset][iFBOffset] *= fGain; + ppfImag[iBlockOffset][iFBOffset] *= fGain; + iFBOffset++; + } + } + iBlockOffset++; + } + } + + 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 ) +{ + int32_t b, n; + int32_t m, idx; + + for ( n = 0; n < iNumBlocks; n++ ) + { + idx = 0; + for ( b = 0; b < iNumLCLDBands; b++ ) + { + for ( m = 0; m < piBandwidths[b]; m++ ) + { + if ( ppiSignReal[n][idx] == 1 ) + { + ppfReal[n][idx] = -ppfReal[n][idx]; + } + + if ( ppiSignImag[n][idx] == 1 ) + { + ppfImag[n][idx] = -ppfImag[n][idx]; + } + 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, + NoiseGen *psNoiseGen /* Pass in NULL to switch off noise gen */ +) +{ + int32_t b, k, n; + int32_t iBlockOffest, iFBOffset; + + iBlockOffest = 0; + for ( n = 0; n < iNumGroups; n++ ) + { + for ( k = 0; k < piGroupLengths[n]; k++ ) + { + iFBOffset = 0; + for ( b = 0; b < iNumBands; b++ ) + { + int32_t m; + int32_t iAlloc; + float fInvSCFGain; + + iAlloc = ppiAlloc[n][b]; + fInvSCFGain = c_afInvScaleFactor[iAlloc]; + + if ( iAlloc > 0 ) + { + 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; + + iFBOffset++; + } + } + else if ( psNoiseGen != NULL ) + { + for ( m = 0; m < piBandwidths[b]; m++ ) + { + ppfReal[iBlockOffest][iFBOffset] = 0.7f * GetNoise( psNoiseGen ); + ppfImag[iBlockOffest][iFBOffset] = 0.7f * GetNoise( psNoiseGen ); + + iFBOffset++; + } + } + else + { + iFBOffset += piBandwidths[b]; + } + } + + iBlockOffest++; + } + } + + 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 ) +{ + if ( iMSMode > 0 ) + { + int32_t b; + int32_t iFBOffset; + int32_t bMSPred = 0; + + iFBOffset = 0; + for ( b = 0; b < iNumBands; b++ ) + { + if ( piMSFlags[b] == 1 ) + { + int32_t n; + int32_t phaseIdx; + float fPred; + phaseIdx = piLRPhaseDiffs[bMSPred] - PHASE_MIN_VAL; + fPred = dequantPred( piMSPredCoefs[bMSPred] ); + for ( n = 0; n < piBandwidths[b]; n++ ) + { + int32_t k; + for ( k = 0; k < iNumBlocks; k++ ) + { + float fLeftReal; + float fLeftImag; + float fRightReal; + float fRightImag; + + if ( iMSMode == 3 ) + { + pppfReal[1][k][iFBOffset] += fPred * pppfReal[0][k][iFBOffset]; + pppfImag[1][k][iFBOffset] += fPred * pppfImag[0][k][iFBOffset]; + } + + 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] ); + + if ( iMSMode == 3 ) + { + cplxmult_lcld( &fRightReal, &fRightImag, c_afRotRealImag[phaseIdx][0], -c_afRotRealImag[phaseIdx][1] ); + } + + pppfReal[0][k][iFBOffset] = fLeftReal; + pppfReal[1][k][iFBOffset] = fRightReal; + pppfImag[0][k][iFBOffset] = fLeftImag; + pppfImag[1][k][iFBOffset] = fRightImag; + } + iFBOffset++; + } + bMSPred++; + } + else + { + iFBOffset += piBandwidths[b]; + } + } + } + + return; +} + + +/* Currently only the number of bands in frame */ +static int32_t ReadHeaderInformation( + int32_t *piNumBands, + ISAR_SPLIT_REND_BITS_HANDLE pBits ) +{ + int32_t iBitsRead; + + iBitsRead = 0; + *piNumBands = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 5 ); + iBitsRead += 5; + + return iBitsRead; +} + + +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 ) +{ + int32_t iBitsRead; + + iBitsRead = 0; + *piMSMode = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 2 ); + iBitsRead += 2; + + if ( *piMSMode == 0 ) + { + int32_t n; + for ( n = 0; n < iNumBands; n++ ) + { + piMSFlags[n] = 0; + } + } + else if ( *piMSMode == 1 ) + { + int32_t n; + for ( n = 0; n < iNumBands; n++ ) + { + piMSFlags[n] = 1; + } + } + else if ( *piMSMode == 2 ) + { + int32_t n; + for ( n = 0; n < iNumBands; n++ ) + { + piMSFlags[n] = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 1 ); + iBitsRead += 1; + } + } + else if ( *piMSMode == 3 ) + { + int32_t n; + int32_t iMSPredAll; + int32_t iNumMSPredBands = 0; + int32_t anyNonZero; + iMSPredAll = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 1 ); + iBitsRead += 1; + if ( iMSPredAll ) + { + iNumMSPredBands = iNumBands; + for ( n = 0; n < iNumBands; n++ ) + { + piMSFlags[n] = 1; + } + } + else + { + for ( n = 0; n < iNumBands; n++ ) + { + piMSFlags[n] = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 1 ); + iBitsRead += 1; + if ( piMSFlags[n] ) + { + iNumMSPredBands++; + } + } + } + anyNonZero = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 1 ); + 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++ ) + { + int32_t tabIdx; + iBitsRead += ReadHuff( c_aaiRMSEnvHuffDec, &tabIdx, pBits ); + piLRPhaseDiffs[n] = tabIdx + ENV_DELTA_MIN; + } + DecodePhase( piLRPhaseDiffs, iNumMSPredBands, PHASE_DIFF_DIM ); + } + else + { + for ( n = 0; n < iNumMSPredBands; n++ ) + { + piLRPhaseDiffs[n] = 0; + } + } + anyNonZero = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 1 ); + 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++ ) + { + int32_t tabIdx; + iBitsRead += ReadHuff( c_aaiRMSEnvHuffDec, &tabIdx, pBits ); + piMSPredCoefs[n] = tabIdx + ENV_DELTA_MIN; + } + DecodePredCoef( piMSPredCoefs, iNumMSPredBands ); + } + else + { + for ( n = 0; n < iNumMSPredBands; n++ ) + { + piMSPredCoefs[n] = 0; + } + } +#ifdef DEBUG_WRITE_MS_PRED + { + static FILE *fid; + if ( !fid ) + fid = fopen( "ms_pred_dec.txt", "wt" ); + writeMSPred( piLRPhaseDiffs, piMSPredCoefs, *piMSMode, iNumMSPredBands, iNumBands, fid, piMSFlags ); + } +#endif + } + else + { + printf( "ERROR UNSUPPORTED MS MODE\n" ); + } + + return iBitsRead; +} + +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 ) +{ + int32_t c, k, iBitsRead; + + iBitsRead = 0; + if ( iChannels == 2 ) + { + *piCommonGrouping = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 1 ); + iBitsRead += 1; + + if ( *piCommonGrouping == 1 ) + { + piNumGroups[0] = 0; + ppiGroupLengths[0][piNumGroups[0]] = 1; + for ( k = 0; k < ( iNumBlocks - 1 ); k++ ) + { + int32_t iGroupStart; + + iGroupStart = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 1 ); + iBitsRead += 1; + + if ( iGroupStart == 1 ) + { + piNumGroups[0]++; + ppiGroupLengths[0][piNumGroups[0]] = 1; + } + else + { + ppiGroupLengths[0][piNumGroups[0]]++; + } + } + piNumGroups[0]++; + + piNumGroups[1] = piNumGroups[0]; + for ( k = 0; k < piNumGroups[1]; k++ ) + { + ppiGroupLengths[1][k] = ppiGroupLengths[0][k]; + } + } + else + { + for ( c = 0; c < iChannels; c++ ) + { + piNumGroups[c] = 0; + ppiGroupLengths[c][piNumGroups[c]] = 1; + for ( k = 0; k < ( iNumBlocks - 1 ); k++ ) + { + int32_t iGroupStart; + + iGroupStart = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 1 ); + iBitsRead += 1; + + if ( iGroupStart == 1 ) + { + piNumGroups[c]++; + ppiGroupLengths[c][piNumGroups[c]] = 1; + } + else + { + ppiGroupLengths[c][piNumGroups[c]]++; + } + } + piNumGroups[c]++; + } + } + } + else + { + for ( c = 0; c < iChannels; c++ ) + { + piNumGroups[c] = 0; + ppiGroupLengths[c][piNumGroups[c]] = 1; + for ( k = 0; k < ( iNumBlocks - 1 ); k++ ) + { + int32_t iGroupStart; + + iGroupStart = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 1 ); + iBitsRead += 1; + + if ( iGroupStart == 1 ) + { + piNumGroups[c]++; + ppiGroupLengths[c][piNumGroups[c]] = 1; + } + else + { + ppiGroupLengths[c][piNumGroups[c]]++; + } + } + piNumGroups[c]++; + } + } + + return iBitsRead; +} + + +static int32_t BSForceBack( + ISAR_SPLIT_REND_BITS_HANDLE pBits, + int32_t iValue, + int32_t iBitCount ) +{ + pBits->bits_read -= iBitCount; + + return ( iValue >> iBitCount ); +} + + +static int32_t ReadHuff( + const uint32_t ( *pauiHuffDecTable )[HUFF_DEC_TABLE_SIZE], + int32_t *piSymbol, + ISAR_SPLIT_REND_BITS_HANDLE pBits ) +{ + int32_t iBitsRead; + int32_t iSymbol; + int32_t iIndex; + int32_t iVal; + + iVal = 0; + iIndex = 0; + iSymbol = 0xFFFF; + iBitsRead = 0; + while ( iSymbol == 0xFFFF ) + { + iIndex = ISAR_SPLIT_REND_BITStream_read_int32( pBits, HUFF_READ_SIZE ); + iBitsRead += HUFF_READ_SIZE; + + iIndex = pauiHuffDecTable[iVal][iIndex]; + iSymbol = ( iIndex & 0xFFFF ); + + iVal = ( iIndex >> 16 ); + } + + if ( iVal ) + { + BSForceBack( pBits, iIndex, iVal ); + iBitsRead -= iVal; + } + + *piSymbol = iSymbol; + + return iBitsRead; +} + + +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 ) +{ + int32_t b, k, n; + int32_t iBitsRead, iLastRMSVal; + + iBitsRead = 0; + for ( n = 0; n < iChannels; n++ ) + { + for ( k = 0; k < piNumGroups[n]; k++ ) + { + iLastRMSVal = ISAR_SPLIT_REND_BITStream_read_int32( pBits, ENV0_BITS ); + iBitsRead += ENV0_BITS; + + iLastRMSVal += ENV_MIN; + pppiRMSEnvelope[n][k][0] = iLastRMSVal; + for ( b = 1; b < iNumBands; b++ ) + { + int32_t iDelta; + + iBitsRead += ReadHuff( c_aaiRMSEnvHuffDec, &iDelta, pBits ); + + iDelta += ENV_DELTA_MIN; + iLastRMSVal += iDelta; + pppiRMSEnvelope[n][k][b] = iLastRMSVal; + } + } + } + + return iBitsRead; +} + + +static int32_t ReadAllocInformation( + int32_t *piAllocOffset, + ISAR_SPLIT_REND_BITS_HANDLE pBits ) +{ + int32_t iBitsRead; + + iBitsRead = 0; + *piAllocOffset = ISAR_SPLIT_REND_BITStream_read_int32( pBits, ALLOC_OFFSET_BITS ); + *piAllocOffset += MIN_ALLOC_OFFSET; + 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, + ISAR_SPLIT_REND_BITS_HANDLE pBits, + uint32_t ( *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; + + iBitsRead = 0; + for ( s = 0; s < iNumSubSets; s++, iSet-- ) + { + int32_t ch; + + if ( iSet < 0 ) + { + iSet = iNumSubSets - 1; + } + + for ( ch = 0; ch < iNumChannels; ch++ ) + { + int32_t n; + int32_t iBlockOffest; + + if ( 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 + { + ppiDecodingFailed[ch][iSet] = 0; /* mark as correctly decoded */ + } + iBlockOffest = 0; + for ( n = 0; n < piNumGroups[ch]; n++ ) + { + int32_t k; + for ( k = 0; k < ppiGroupLengths[ch][n]; k++ ) + { + int32_t iFBOffset; + + for ( iFBOffset = iSet; iFBOffset < iNumLcldBands; iFBOffset += iNumSubSets ) + { + int32_t b; + int32_t iAlloc; + int32_t iHuffDim; + int32_t iHuffMod; + + b = c_aiBandIdPerLcldBand[iFBOffset]; + + iAlloc = pppiAlloc[ch][n][b]; + + iHuffDim = c_aiHuffmanDim[iAlloc]; + iHuffMod = c_aiHuffmanMod[iAlloc]; + + if ( 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 ) + { + 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]; +#ifdef LCLD_HANDLE_PRED_START_SAMPLE + if ( ppiPredEnable[ch][iFBOffset] == 1 && ( iBlockOffest > 0 || iSet != iSubSetId ) ) +#else + if ( ppiPredEnable[ch][iFBOffset] == 1 ) +#endif + { + if ( iHuffDim == 2 ) + { + int32_t iSymbol; + iBitsRead += ReadHuff( pauiHuffmanTableDPCM, &iSymbol, pBits ); + iQuantValue1 = iSymbol / iHuffMod; + iQuantValue2 = iSymbol % iHuffMod; + } + else + { + iBitsRead += ReadHuff( pauiHuffmanTableDPCM, &iQuantValue1, pBits ); + iBitsRead += ReadHuff( pauiHuffmanTableDPCM, &iQuantValue2, pBits ); + } + } + else + { + if ( iHuffDim == 2 ) + { + int32_t iSymbol; + + iBitsRead += ReadHuff( pauiHuffmanTable, &iSymbol, pBits ); + iQuantValue1 = iSymbol / iHuffMod; + iQuantValue2 = iSymbol % iHuffMod; + } + else + { + iBitsRead += ReadHuff( pauiHuffmanTable, &iQuantValue1, pBits ); + iBitsRead += ReadHuff( pauiHuffmanTable, &iQuantValue2, pBits ); + } + } + + pppiQReal[ch][iBlockOffest][iFBOffset] = iQuantValue1; + pppiQImag[ch][iBlockOffest][iFBOffset] = iQuantValue2; + + if ( iQuantValue1 > 0 ) + { + pppiSignReal[ch][iBlockOffest][iFBOffset] = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 1 ); + iBitsRead += 1; + } + else + { + pppiSignReal[ch][iBlockOffest][iFBOffset] = 0; + } + if ( iQuantValue2 > 0 ) + { + pppiSignImag[ch][iBlockOffest][iFBOffset] = ISAR_SPLIT_REND_BITStream_read_int32( pBits, 1 ); + iBitsRead += 1; + } + else + { + pppiSignImag[ch][iBlockOffest][iFBOffset] = 0; + } + } + else + { + pppiSignReal[ch][iBlockOffest][iFBOffset] = 0; + pppiSignImag[ch][iBlockOffest][iFBOffset] = 0; + } + } + iBlockOffest++; + } + } + } + } + + return iBitsRead; +} + +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 ) +{ + int32_t b, k, n, iAlloc; + + for ( n = 0; n < iChannels; n++ ) + { + for ( k = 0; k < piNumGroups[n]; k++ ) + { + for ( b = 0; b < iNumBands; b++ ) + { + iAlloc = ( ( pppiSMR[n][k][b] + iAllocOffset * ALLOC_OFFSET_SCALE ) >> 5 ); + iAlloc = ( iAlloc > MIN_ALLOC ) ? iAlloc : MIN_ALLOC; + iAlloc = ( iAlloc < MAX_ALLOC ) ? iAlloc : MAX_ALLOC; + pppiAlloc[n][k][b] = iAlloc; + } + } + } + + return; +} +#endif diff --git a/lib_isar/isar_lcld_encoder.c b/lib_isar/isar_lcld_encoder.c new file mode 100644 index 000000000..b71ed9854 --- /dev/null +++ b/lib_isar/isar_lcld_encoder.c @@ -0,0 +1,1893 @@ +/****************************************************************************************************** + + (C) 2022-2023 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. + +*******************************************************************************************************/ + +#include +#include "options.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT +#include +#include +#include "prot.h" +#include "isar_prot.h" +#include "wmc_auto.h" + +/*------------------------------------------------------------------------------------------* + * Local structures + *------------------------------------------------------------------------------------------*/ + +struct LCLD_ENCODER +{ + int32_t iSampleRate; + int32_t iChannels; + int32_t iNumBlocks; + + int32_t iTargetBitRate; + + int32_t iNumBands; + const int32_t *piBandwidths; + + int32_t iMSMode; + int32_t *piMSFlags; + int32_t piMSPredCoefs[MAX_BANDS]; + int32_t piLRPhaseDiffs[MAX_BANDS]; + int32_t iAllowSidePred; + + int32_t iRealOnlyOut; + + RMSEnvelopeGrouping *psRMSEnvelopeGrouping; + + 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 ***pppiLCLDSignReal; + int32_t ***pppiLCLDSignImag; + int32_t ***pppiQLCLDReal; + int32_t ***pppiQLCLDImag; + + + PredictionEncoder *psPredictionEncoder; +}; + +/*------------------------------------------------------------------------------------------* + * Function Quantize() + * + * + *------------------------------------------------------------------------------------------*/ + +static int32_t Quantize( + const float fVal, + const float fScale, + int32_t *iSign, + const int32_t iMaxVal ) +{ + int32_t iVal; + if ( fVal > 0.0f ) + { + iVal = (int32_t) ( fScale * fVal + 0.5f ); + *iSign = 0; + } + else + { + iVal = (int32_t) ( -fScale * fVal + 0.5f ); + *iSign = 1; + } + iVal = ( iVal < iMaxVal ) ? iVal : iMaxVal; + + return iVal; +} + +/*------------------------------------------------------------------------------------------* + * Function UnQuantize() + * + * + *------------------------------------------------------------------------------------------*/ + +static float UnQuantize( + const int32_t iVal, + const float fScale, + const int32_t iSign ) +{ + float fVal; + if ( iSign == 0 ) + { + fVal = fScale * (float) iVal; + } + else + { + fVal = -fScale * (float) iVal; + } + return fVal; +} + +static void PackReal( + const int32_t iChannels, + const int32_t iNumBlocks, + float ***pppfReal, + float ***pppfImag ) +{ + int32_t ch, b, n; + for ( ch = 0; ch < iChannels; ch++ ) + { + for ( b = 0; b < LCLD_BANDS; b++ ) + { + int32_t iRealBlock = 0; + for ( n = 0; n < iNumBlocks; n += 2 ) + { + pppfImag[ch][iRealBlock][b] = pppfReal[ch][n + 1][b]; + pppfReal[ch][iRealBlock][b] = pppfReal[ch][n][b]; + iRealBlock++; + } + } + } +} + +/*------------------------------------------------------------------------------------------* + * Function CreateLCLDEncoder() + * + * + *------------------------------------------------------------------------------------------*/ + +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 ) +{ + int32_t n; + LCLDEncoder *psLCLDEncoder; + ivas_error error; + int32_t iMaxNumPredBands = 0; + + assert( iSampleRate == 48000 ); + assert( iNumBlocks == 16 || iNumBlocks == 8 || iNumBlocks == 4 ); + assert( iNumSubSets > 0 && iNumSubSets <= LCLD_MAX_NUM_PRED_SUBSETS ); + + 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; + psLCLDEncoder->iChannels = iChannels; + psLCLDEncoder->iRealOnlyOut = iRealOnlyOut; + psLCLDEncoder->iAllocOffset = 0; + + psLCLDEncoder->iTargetBitRate = iTargetBitRate; + + 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 ) + { + iMaxNumPredBands = 0; + assert( iNumSubSets == 1 ); + psLCLDEncoder->iNumBlocks = iNumBlocks / 2; + } + else + { + psLCLDEncoder->iNumBlocks = iNumBlocks; + } + psLCLDEncoder->iMSMode = 0; + if ( ( psLCLDEncoder->piMSFlags = (int32_t *) malloc( MAX_BANDS * sizeof( int32_t ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + + for ( n = 0; n < MAX_BANDS; n++ ) + { + psLCLDEncoder->piLRPhaseDiffs[n] = 0; + psLCLDEncoder->piMSPredCoefs[n] = 0; + } + psLCLDEncoder->iAllowSidePred = iAllowSidePred; + 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 ) + { + 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 ) + { + 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 ) + { + 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 ) + { + 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 ) + { + 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 ) + { + 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 ) + { + 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 ) + { + 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 ) + { + 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 ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \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 ) + { + 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 ) + { + 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 ) + { + 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 ) + { + 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 ) + { + 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 ) + { + 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 ) + { + 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 ) + { + 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 ) + { + 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++ ) + { + if ( ( psLCLDEncoder->pppiRMSEnvelope[n][k] = (int32_t *) malloc( MAX_BANDS * sizeof( int32_t ) ) ) == 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 ) + { + 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 ) + { + 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 ) + { + 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 ) + { + 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 ) + { + 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 ) + { + 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 ) + { + 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 ) + { + return error; + } + + *psLCLDEncoder_out = psLCLDEncoder; + + return IVAS_ERR_OK; +} + + +/*------------------------------------------------------------------------------------------* + * Function DeleteLCLDEncoder() + * + * + *------------------------------------------------------------------------------------------*/ + +void DeleteLCLDEncoder( + LCLDEncoder *psLCLDEncoder ) +{ + int32_t k, n; + + if ( psLCLDEncoder != NULL ) + { + + if ( psLCLDEncoder->piMSFlags != NULL ) + { + free( psLCLDEncoder->piMSFlags ); + } + + if ( psLCLDEncoder->piNumGroups != NULL ) + { + free( psLCLDEncoder->piNumGroups ); + } + + if ( psLCLDEncoder->psRMSEnvelopeGrouping != NULL ) + { + DeleteRMSEnvelopeGrouping( psLCLDEncoder->psRMSEnvelopeGrouping ); + } + + if ( psLCLDEncoder->ppiGroupLengths != NULL ) + { + for ( n = 0; n < psLCLDEncoder->iChannels; n++ ) + { + free( psLCLDEncoder->ppiGroupLengths[n] ); + } + free( psLCLDEncoder->ppiGroupLengths ); + } + if ( psLCLDEncoder->pppiRMSEnvelope != NULL ) + { + for ( n = 0; n < psLCLDEncoder->iChannels; n++ ) + { + for ( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) + { + free( psLCLDEncoder->pppiRMSEnvelope[n][k] ); + } + free( psLCLDEncoder->pppiRMSEnvelope[n] ); + } + free( psLCLDEncoder->pppiRMSEnvelope ); + } + + if ( psLCLDEncoder->pppiSMR != NULL ) + { + for ( n = 0; n < psLCLDEncoder->iChannels; n++ ) + { + for ( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) + { + free( psLCLDEncoder->pppiSMR[n][k] ); + } + free( psLCLDEncoder->pppiSMR[n] ); + } + free( psLCLDEncoder->pppiSMR ); + } + + if ( psLCLDEncoder->pppiExcitation != NULL ) + { + for ( n = 0; n < psLCLDEncoder->iChannels; n++ ) + { + for ( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) + { + free( psLCLDEncoder->pppiExcitation[n][k] ); + } + free( psLCLDEncoder->pppiExcitation[n] ); + } + free( psLCLDEncoder->pppiExcitation ); + } + + if ( psLCLDEncoder->pppiAlloc != NULL ) + { + for ( n = 0; n < psLCLDEncoder->iChannels; n++ ) + { + for ( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) + { + free( psLCLDEncoder->pppiAlloc[n][k] ); + } + free( psLCLDEncoder->pppiAlloc[n] ); + } + free( psLCLDEncoder->pppiAlloc ); + } + + if ( psLCLDEncoder->pppiLCLDSignReal != NULL ) + { + for ( n = 0; n < psLCLDEncoder->iChannels; n++ ) + { + for ( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) + { + free( psLCLDEncoder->pppiLCLDSignReal[n][k] ); + } + free( psLCLDEncoder->pppiLCLDSignReal[n] ); + } + free( psLCLDEncoder->pppiLCLDSignReal ); + } + + if ( psLCLDEncoder->pppiLCLDSignImag != NULL ) + { + for ( n = 0; n < psLCLDEncoder->iChannels; n++ ) + { + for ( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) + { + free( psLCLDEncoder->pppiLCLDSignImag[n][k] ); + } + free( psLCLDEncoder->pppiLCLDSignImag[n] ); + } + free( psLCLDEncoder->pppiLCLDSignImag ); + } + + if ( psLCLDEncoder->pppiQLCLDReal != NULL ) + { + for ( n = 0; n < psLCLDEncoder->iChannels; n++ ) + { + for ( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) + { + free( psLCLDEncoder->pppiQLCLDReal[n][k] ); + } + free( psLCLDEncoder->pppiQLCLDReal[n] ); + } + free( psLCLDEncoder->pppiQLCLDReal ); + } + + if ( psLCLDEncoder->pppiQLCLDImag != NULL ) + { + for ( n = 0; n < psLCLDEncoder->iChannels; n++ ) + { + for ( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) + { + free( psLCLDEncoder->pppiQLCLDImag[n][k] ); + } + free( psLCLDEncoder->pppiQLCLDImag[n] ); + } + free( psLCLDEncoder->pppiQLCLDImag ); + } + + DeletePredictionEncoder( psLCLDEncoder->psPredictionEncoder ); + free( psLCLDEncoder ); + } + + return; +} + +/*------------------------------------------------------------------------------------------* + * 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 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 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 int32_t WriteHeaderInformation( const int32_t iNumBands, 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 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 ); + +/*------------------------------------------------------------------------------------------* + * Function EncodeLCLDFrame() + * + * + *------------------------------------------------------------------------------------------*/ + +int32_t EncodeLCLDFrame( + LCLDEncoder *psLCLDEncoder, + float ***pppfLCLDReal, + float ***pppfLCLDImag, + int32_t *piBitsWritten, + const int32_t available_bits, + ISAR_SPLIT_REND_BITS_HANDLE pBits ) +{ + int32_t n; + int32_t iAvailableBits, iBitsWritten; + int32_t iNumMSBands = 0; + int32_t iAudioBitsWritten; + + iAvailableBits = available_bits; /* HCBR for now*/ + iBitsWritten = 0; + assert( available_bits <= pBits->buf_len * 8 ); + + if ( psLCLDEncoder->iRealOnlyOut == 1 ) + { + PackReal( psLCLDEncoder->iChannels, psLCLDEncoder->iNumBlocks * 2, pppfLCLDReal, pppfLCLDImag ); + } + + /* Do MS calc here */ + if ( 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 ) + { + 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 ) + { + ComputeEnvelopeGrouping( psLCLDEncoder->psRMSEnvelopeGrouping, + psLCLDEncoder->iChannels, + psLCLDEncoder->iNumBands, + psLCLDEncoder->piBandwidths, + pppfLCLDReal, + pppfLCLDImag, + &psLCLDEncoder->piNumGroups[0], + psLCLDEncoder->ppiGroupLengths[0], + psLCLDEncoder->pppiRMSEnvelope ); + + psLCLDEncoder->piNumGroups[1] = psLCLDEncoder->piNumGroups[0]; + for ( n = 0; n < psLCLDEncoder->piNumGroups[0]; n++ ) + { + psLCLDEncoder->ppiGroupLengths[1][n] = psLCLDEncoder->ppiGroupLengths[0][n]; + } + } + else + { + for ( n = 0; n < psLCLDEncoder->iChannels; n++ ) + { + ComputeEnvelopeGrouping( psLCLDEncoder->psRMSEnvelopeGrouping, + psLCLDEncoder->iChannels, + psLCLDEncoder->iNumBands, + psLCLDEncoder->piBandwidths, + &pppfLCLDReal[n], + &pppfLCLDImag[n], + &psLCLDEncoder->piNumGroups[n], + psLCLDEncoder->ppiGroupLengths[n], + &psLCLDEncoder->pppiRMSEnvelope[n] ); + } + } + + for ( n = 0; n < psLCLDEncoder->iChannels; n++ ) + { + RemoveRMSEnvelope( psLCLDEncoder->iNumBands, + psLCLDEncoder->piBandwidths, + psLCLDEncoder->piNumGroups[n], + (const int32_t *) psLCLDEncoder->ppiGroupLengths[n], + psLCLDEncoder->pppiRMSEnvelope[n], + pppfLCLDReal[n], + pppfLCLDImag[n] ); + } + + ComputePredictors( psLCLDEncoder->psPredictionEncoder, pppfLCLDReal, pppfLCLDImag ); + + iBitsWritten += WriteHeaderInformation( psLCLDEncoder->iNumBands, pBits ); + + if ( 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 += WritePredictors( psLCLDEncoder->psPredictionEncoder, pBits ); + + iBitsWritten += WriteGroupInformation( psLCLDEncoder->iChannels, psLCLDEncoder->iCommonGrouping, (const int32_t *) psLCLDEncoder->piNumGroups, psLCLDEncoder->ppiGroupLengths, pBits ); + + iBitsWritten += WriteRMSEnvelope( psLCLDEncoder->iChannels, (const int32_t *) psLCLDEncoder->piNumGroups, psLCLDEncoder->iNumBands, psLCLDEncoder->pppiRMSEnvelope, pBits ); + + + if ( psLCLDEncoder->iChannels == 2 && psLCLDEncoder->iCommonGrouping == 1 ) + { + int32_t 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] ); + } + } + else + { + for ( n = 0; n < psLCLDEncoder->iChannels; n++ ) + { + int32_t k; + for ( k = 0; k < psLCLDEncoder->piNumGroups[n]; k++ ) + { + PerceptualModel( psLCLDEncoder->iNumBands, + psLCLDEncoder->pppiRMSEnvelope[n][k], + psLCLDEncoder->pppiExcitation[n][k], + psLCLDEncoder->pppiSMR[n][k] ); + } + } + } +#ifdef DEBUG_WRITE_PREDICTORS + { + static FILE *fid; + if ( !fid ) + fid = fopen( "pred_enc.txt", "wt" ); + for ( n = 0; n < psLCLDEncoder->iChannels; n++ ) + { + int16_t b; + for ( b = 0; b < 60; b++ ) + fprintf( fid, "%.5f ", (float) psLCLDEncoder->psPredictionEncoder->ppiPredBandEnable[n][b] * psLCLDEncoder->psPredictionEncoder->ppfA1Imag[n][b] ); + } + fprintf( fid, "%d %d\n", psLCLDEncoder->psPredictionEncoder->iSubSetId, psLCLDEncoder->psPredictionEncoder->piPredChanEnable[n] ); + } +#endif + iAvailableBits -= iBitsWritten; + ComputeAllocation( psLCLDEncoder->iChannels, + (const int32_t *) psLCLDEncoder->piNumGroups, + psLCLDEncoder->ppiGroupLengths, + psLCLDEncoder->iNumBands, + psLCLDEncoder->piBandwidths, + pppfLCLDReal, + pppfLCLDImag, + psLCLDEncoder->pppiSMR, + iAvailableBits, + &psLCLDEncoder->iAllocOffset, + psLCLDEncoder->pppiAlloc, + psLCLDEncoder->pppiQLCLDReal, + psLCLDEncoder->pppiQLCLDImag, + psLCLDEncoder->pppiLCLDSignReal, + psLCLDEncoder->pppiLCLDSignImag, + psLCLDEncoder->psPredictionEncoder ); + + 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 ); + *piBitsWritten = iBitsWritten; + iAudioBitsWritten = iBitsWritten - iAudioBitsWritten; + + UpdatePredictionSubSetId( psLCLDEncoder->psPredictionEncoder ); + + return 0; +} + + +/*------------------------------------------------------------------------------------------* + * Local functions + * + * + *------------------------------------------------------------------------------------------*/ + +enum MSPred_Types +{ + MS_PHASE_AND_PRED = 0, /* LR phase alignment + real-valued M/S prediction */ + MS_PRED_ONLY = 1, /* real-valued M/S prediction */ + MS_PHASE_ONLY = 2 /* LR phase alignment + M/S */ +}; + +enum MS_BS_TYPES +{ + MS_OFF = 0, + MS_ALL = 1, + 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 ) +{ + 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 ) + { + 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 */ + } + + ppiMSPredFlags[0] = piMSPredFlags0; + ppiMSPredFlags[1] = piMSPredFlags1; + ppiMSPredFlags[2] = piMSPredFlags2; + + ppiMSPredCoefs[0] = piMSPredCoefs0; + ppiMSPredCoefs[1] = piMSPredCoefs1; + ppiMSPredCoefs[2] = piMSPredCoefs2; + + ppiMSPredPhase[0] = piMSPredPhase0; + ppiMSPredPhase[1] = piMSPredPhase1; + ppiMSPredPhase[2] = piMSPredPhase2; + + *piMSMode = MS_OFF; + iFBOffset = 0; + iNumMSBands = 0; + for ( b = 0; b < iNumBands; b++ ) + { + int32_t n; + float fLeftEnergy; + float fRightEnergy; + float fMidEnergy; + float fSideEnergy; + float fLRRatio; + float fMSRatio; + float pfMSPredRatio[3] = { 0.0f }; + 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++ ) + { + int32_t k; + for ( k = 0; k < iNumBlocks; k++ ) + { + 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] ); + } + + iFBOffset++; + } + + /* 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 ) ); + + ppiMSPredCoefs[MS_PRED_ONLY][b] = iPred; + ppiMSPredPhase[MS_PRED_ONLY][b] = 0; + pfMSPredRatio[MS_PRED_ONLY] = log10f( ( fMidEnergy + feps ) / ( fSideEnergyPred + feps ) ); + + /* Phase alignment*/ + iPhase = 0; + if ( fLRCovReal * fLRCovReal + fLRCovImag * fLRCovImag > 0.5f * fLeftEnergy * fRightEnergy ) + { + float fPhase = atan2f( fLRCovImag, fLRCovReal ); + iPhase = quantPhase( fPhase ); + } + + /* adjust covariance */ + tabIdx = iPhase - PHASE_MIN_VAL; + cplxmult_lcld( &fLRCovReal, &fLRCovImag, c_afRotRealImag[tabIdx][0], -c_afRotRealImag[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 ); + + /* M/S with LR phase alignment but without prediction */ + ppiMSPredCoefs[MS_PHASE_ONLY][b] = 0; + ppiMSPredPhase[MS_PHASE_ONLY][b] = iPhase; + pfMSPredRatio[MS_PHASE_ONLY] = log10f( ( fMidEnergyPred + feps ) / ( fSideEnergyPred + feps ) ); + + /* 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 * fPred * fMidEnergyPred doesn't work because fPred is quantized and does not match MS/MM exactly */ + ppiMSPredCoefs[MS_PHASE_AND_PRED][b] = iPred; + ppiMSPredPhase[MS_PHASE_AND_PRED][b] = iPhase; + pfMSPredRatio[MS_PHASE_AND_PRED] = log10f( ( fMidEnergyPred + feps ) / ( fSideEnergyPred + feps ) ); + + /* 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 ) + { + iNumMSBands++; + piMSFlags[b] = 1; + fMSBitGain += fNumLines * ( fMSRatio - fLRRatio ) * fLevelToSMRdBFactor * fBitsFactor; + } + else + { + piMSFlags[b] = 0; + } + piLRPhaseDiffs[b] = 0; + piMSPredCoefs[b] = 0; + + /* 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++ ) + { + if ( pfMSPredRatio[iMSPredType] > fLRRatio ) + { + ppiMSPredFlags[iMSPredType][b] = 1; + pfMSPredBitGain[iMSPredType] += fNumLines * ( pfMSPredRatio[iMSPredType] - fLRRatio ) * fLevelToSMRdBFactor * fBitsFactor; + } + } + } + + /* remove signalling cost from bit gains */ + 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 ); + } + + /* find the best M/S Pred type */ + if ( iRealOnlyOut == 1 ) + { + iMSPredType = MS_PRED_ONLY; + } + 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 ); + } + + /* plain M/S */ + iMsInfoBits = CountMSBits( iNumBands, MS_SOME, piMSFlags, NULL, NULL ); + fMSBitGain = max( fMSBitGain - iMsInfoBits, 0.0f ); + if ( iAllowSidePred && pfMSPredBitGain[iMSPredType] > 1.1f * fMSBitGain ) + { + *piMSMode = MS_PRED; + iNumMSBands = 0; + for ( b = 0; b < iNumBands; b++ ) + { + piMSFlags[b] = ppiMSPredFlags[iMSPredType][b]; + if ( piMSFlags[b] == 1 ) + { + piMSPredCoefs[b] = ppiMSPredCoefs[iMSPredType][b]; + piLRPhaseDiffs[b] = ppiMSPredPhase[iMSPredType][b]; + iNumMSBands++; + } + else + { + piMSPredCoefs[b] = 0; + piLRPhaseDiffs[b] = 0; + } + } + } + else if ( iNumMSBands == iNumBands ) + { + *piMSMode = MS_ALL; + } + else if ( iNumMSBands > 0 ) + { + *piMSMode = MS_SOME; + } + else + { + *piMSMode = MS_OFF; + } +#ifdef DEBUG_WRITE_MS_PRED + { + static FILE *fid; + int32_t iActualInfoBits = CountMSBits( iNumBands, *piMSMode, piMSFlags, piLRPhaseDiffs, piMSPredCoefs ); + if ( !fid ) + fid = fopen( "ms_info_bits.txt", "wt" ); + 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 ) + { + iFBOffset = 0; + for ( b = 0; b < iNumBands; b++ ) + { + if ( 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++ ) + { + int32_t k; + for ( k = 0; k < iNumBlocks; k++ ) + { + float fMidReal; + float fMidImag; + float fSideReal; + float fSideImag; + + if ( *piMSMode == MS_PRED ) + { + cplxmult_lcld( &pppfReal[1][k][iFBOffset], &pppfImag[1][k][iFBOffset], c_afRotRealImag[phaseIdx][0], c_afRotRealImag[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] ); + + if ( *piMSMode == MS_PRED ) + { + fSideReal -= fPred * fMidReal; + fSideImag -= fPred * fMidImag; + } + + pppfReal[0][k][iFBOffset] = fMidReal; + pppfReal[1][k][iFBOffset] = fSideReal; + pppfImag[0][k][iFBOffset] = fMidImag; + pppfImag[1][k][iFBOffset] = fSideImag; + } + iFBOffset++; + } + } + else + { + iFBOffset += piBandwidths[b]; + } + } + } +#ifdef DEBUG_WRITE_MS_PRED + { + static FILE *fid; + if ( !fid ) + fid = fopen( "ms_enc.txt", "wt" ); + writeMSPred( piLRPhaseDiffs, piMSPredCoefs, *piMSMode, iNumMSBands, iNumBands, fid, piMSFlags ); + } +#endif + if ( *piMSMode == MS_PRED ) + { + /* Differential Coding of Phase Data*/ + PrepEncode( piLRPhaseDiffs, piMSFlags, iNumBands ); + PrepEncode( piMSPredCoefs, piMSFlags, iNumBands ); +#ifdef DEBUG_WRITE_MS_PRED + { + static FILE *fid; + if ( !fid ) + fid = fopen( "ms_pred_enc.txt", "wt" ); + writeMSPred( piLRPhaseDiffs, piMSPredCoefs, *piMSMode, iNumMSBands, iNumBands, fid, piMSFlags ); + } +#endif + /* Differential Coding*/ + EncodePhase( piLRPhaseDiffs, iNumMSBands, PHASE_DIFF_DIM ); + EncodePredCoef( piMSPredCoefs, iNumMSBands ); + } + + 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 ) +{ + int32_t k, n, b, iFBOffset, m, iRMSEnv; + int32_t iBlockOffset; + float fGain; + + iBlockOffset = 0; + for ( n = 0; n < iNumGroups; n++ ) + { + for ( k = 0; k < piGroupLengths[n]; k++ ) + { + iFBOffset = 0; + 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++ ) + { + ppfReal[iBlockOffset][iFBOffset] *= fGain; + ppfImag[iBlockOffset][iFBOffset] *= fGain; + iFBOffset++; + } + } + iBlockOffset++; + } + } + + 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 ) +{ + int32_t b, n; + int32_t iFBOffset; + int32_t k, iAlloc, iMaxQuantVal; + float fSCFGain, fInvSCFGain; + + iFBOffset = 0; + for ( b = 0; b < iNumBands; b++ ) + { + int32_t m; + for ( m = 0; m < piBandwidths[b]; m++ ) + { + int32_t iBlockOffset = 0; + if ( piPredEnable[iFBOffset] == 1 ) + { + float fReal; + float fImag; + int32_t iSubset = iFBOffset % iNumSubSets; + float fPrevReal = 0.0f; + float fPrevImag = 0.0f; + if ( iSubset != iSubSetId ) + { + /* run predictors across sub-frames */ + fPrevReal = pfPredStateReal[iFBOffset]; + fPrevImag = pfPredStateImag[iFBOffset]; + } + 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++ ) + { + /* 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; + + iBlockOffset++; + } /* group length */ + } /* groups */ + pfPredStateReal[iFBOffset] = fPrevReal; + pfPredStateImag[iFBOffset] = fPrevImag; + } /* predEnable */ + else + { /* no prediction */ + 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++ ) + { + ppiQReal[iBlockOffset][iFBOffset] = Quantize( ppfReal[iBlockOffset][iFBOffset], + fSCFGain, + &ppiSignReal[iBlockOffset][iFBOffset], + iMaxQuantVal ); + + ppiQImag[iBlockOffset][iFBOffset] = Quantize( ppfImag[iBlockOffset][iFBOffset], + fSCFGain, + &ppiSignImag[iBlockOffset][iFBOffset], + iMaxQuantVal ); + + iBlockOffset++; + } /* group length */ + } /* groups */ + } /* 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 ) +{ + int32_t k, n, b, iFBOffset; + int32_t iBits, iBlockOffest; + int32_t m, iAlloc, iHuffDim, iHuffMod; + + iBits = 0; + iBlockOffest = 0; + for ( n = 0; n < iNumGroups; n++ ) + { + for ( k = 0; k < piGroupLengths[n]; k++ ) + { + iFBOffset = 0; + for ( b = 0; b < iNumBands; b++ ) + { + iAlloc = ppiAlloc[n][b]; + + iHuffDim = c_aiHuffmanDim[iAlloc]; + iHuffMod = c_aiHuffmanMod[iAlloc]; + + if ( iAlloc > 0 ) + { + const uint16_t( *pauiHuffmanTable )[2] = NULL; + const uint16_t( *pauiHuffmanTableDPCM )[2] = NULL; + pauiHuffmanTable = c_apauiHuffEncTabels[iAlloc]; + pauiHuffmanTableDPCM = c_apauiHuffEncTabels[ALLOC_TABLE_SIZE + iAlloc]; + for ( m = 0; m < piBandwidths[b]; m++ ) + { + int32_t iQuantValue1; + int32_t iQuantValue2; + + iQuantValue1 = ppiQReal[iBlockOffest][iFBOffset]; + iQuantValue2 = ppiQImag[iBlockOffest][iFBOffset]; + + iBits += ( iQuantValue1 > 0 ) ? 1 : 0; /* Sign bit for vals > 0 */ + iBits += ( iQuantValue2 > 0 ) ? 1 : 0; /* Sign bit for vals > 0 */ + + if ( piPredEnable[iFBOffset] == 1 ) + { + if ( iHuffDim == 2 ) + { + iQuantValue1 *= iHuffMod; + iQuantValue1 += iQuantValue2; + iBits += pauiHuffmanTableDPCM[iQuantValue1][0]; + } + else + { + iBits += pauiHuffmanTableDPCM[iQuantValue1][0]; + iBits += pauiHuffmanTableDPCM[iQuantValue2][0]; + } + } + else + { + if ( iHuffDim == 2 ) + { + iQuantValue1 *= iHuffMod; + iQuantValue1 += iQuantValue2; + iBits += pauiHuffmanTable[iQuantValue1][0]; + } + else + { + iBits += pauiHuffmanTable[iQuantValue1][0]; + iBits += pauiHuffmanTable[iQuantValue2][0]; + } + } + + iFBOffset++; + } + } + else + { + iFBOffset += piBandwidths[b]; + } + } + + iBlockOffest++; + } + } + + return iBits; +} + + +/* Currently only the number of bands in frame */ +static int32_t WriteHeaderInformation( + const int32_t iNumBands, + ISAR_SPLIT_REND_BITS_HANDLE pBits ) +{ + int32_t iBitsWritten; + + iBitsWritten = 0; + ISAR_SPLIT_REND_BITStream_write_int32( pBits, iNumBands, 5 ); + 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, + ISAR_SPLIT_REND_BITS_HANDLE pBits ) +{ + int32_t iBitsWritten; + int32_t iMSPredAll = ( iNumMSPredBands == iNumBands ); +#ifdef DEBUG_WRITE_MS_PRED + int32_t iBitsWrittenTmp = 0; +#endif + iBitsWritten = 0; + ISAR_SPLIT_REND_BITStream_write_int32( pBits, iMSMode, 2 ); + iBitsWritten += 2; + + if ( iMSMode == 3 ) + { + ISAR_SPLIT_REND_BITStream_write_int32( pBits, iMSPredAll, 1 ); + iBitsWritten += 1; + } + + if ( iMSMode == 2 || ( iMSMode == 3 && !iMSPredAll ) ) + { + int32_t n; + for ( n = 0; n < iNumBands; n++ ) + { + ISAR_SPLIT_REND_BITStream_write_int32( pBits, piMSFlags[n], 1 ); + iBitsWritten += 1; + } + } + +#ifdef DEBUG_WRITE_MS_PRED + iBitsWrittenTmp = iBitsWritten; +#endif + if ( iMSMode == 3 ) + { + int32_t b; + int32_t anyNonZero; + anyNonZero = 0; + for ( b = 0; b < iNumMSPredBands; b++ ) + { + if ( piLRPhaseDiff[b] != 0 ) + { + anyNonZero = 1; + break; + } + } + ISAR_SPLIT_REND_BITStream_write_int32( pBits, anyNonZero, 1 ); + iBitsWritten++; + + 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++ ) + { + int32_t tabIdx = 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]; + } + } + + anyNonZero = 0; + for ( b = 0; b < iNumMSPredBands; b++ ) + { + if ( piMSPredCoef[b] != 0 ) + { + anyNonZero = 1; + break; + } + } + + ISAR_SPLIT_REND_BITStream_write_int32( pBits, anyNonZero, 1 ); + iBitsWritten++; + + 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++ ) + { + int32_t tabIdx = 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]; + } + } + } +#ifdef DEBUG_WRITE_MS_PRED + { + static FILE *fid = 0; + if ( !fid ) + { + fid = fopen( "ms_pred_bitrate.txt", "wt" ); + } + fprintf( fid, "%f\n", (float) ( ( iBitsWritten - iBitsWrittenTmp ) * ( iMSMode == 3 ) * 50 ) / 1000.0f ); /*kb/s*/ + } +#endif + + return iBitsWritten; +} + + +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 ) +{ + int32_t c, k, n, iBitsWritten; + + iBitsWritten = 0; + if ( iChannels == 2 && iCommonGrouping == 1 ) + { + ISAR_SPLIT_REND_BITStream_write_int32( pBits, iCommonGrouping, 1 ); + iBitsWritten += 1; + + for ( n = 0; n < piNumGroups[0]; n++ ) + { + for ( k = 1; k < ppiGroupLengths[0][n]; k++ ) + { + ISAR_SPLIT_REND_BITStream_write_int32( pBits, 0, 1 ); + iBitsWritten += 1; + } + if ( n < ( piNumGroups[0] - 1 ) ) + { + ISAR_SPLIT_REND_BITStream_write_int32( pBits, 1, 1 ); + iBitsWritten += 1; + } + } + } + else if ( iChannels == 2 ) + { + ISAR_SPLIT_REND_BITStream_write_int32( pBits, iCommonGrouping, 1 ); + iBitsWritten += 1; + + for ( c = 0; c < iChannels; c++ ) + { + for ( n = 0; n < piNumGroups[c]; n++ ) + { + for ( k = 1; k < ppiGroupLengths[c][n]; k++ ) + { + ISAR_SPLIT_REND_BITStream_write_int32( pBits, 0, 1 ); + iBitsWritten += 1; + } + if ( n < ( piNumGroups[c] - 1 ) ) + { + ISAR_SPLIT_REND_BITStream_write_int32( pBits, 1, 1 ); + iBitsWritten += 1; + } + } + } + } + else + { + for ( c = 0; c < iChannels; c++ ) + { + for ( n = 0; n < piNumGroups[c]; n++ ) + { + for ( k = 1; k < ppiGroupLengths[c][n]; k++ ) + { + ISAR_SPLIT_REND_BITStream_write_int32( pBits, 0, 1 ); + iBitsWritten += 1; + } + + if ( n < ( piNumGroups[c] - 1 ) ) + { + ISAR_SPLIT_REND_BITStream_write_int32( pBits, 1, 1 ); + iBitsWritten += 1; + } + } + } + } + + return iBitsWritten; +} + + +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 ) +{ + int32_t k, n; + int32_t iBitsWritten; + + iBitsWritten = 0; + for ( n = 0; n < iChannels; n++ ) + { + for ( k = 0; k < piNumGroups[n]; k++ ) + { + int32_t b; + int32_t 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++ ) + { + 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; + ISAR_SPLIT_REND_BITStream_write_int32( pBits, c_aaiRMSEnvHuffEnc[iDelta][1], c_aaiRMSEnvHuffEnc[iDelta][0] ); + iBitsWritten += c_aaiRMSEnvHuffEnc[iDelta][0]; + + iLastRMSVal = pppiRMSEnvelope[n][k][b]; + } + } + } + + return iBitsWritten; +} + + +static int32_t WriteAllocInformation( + const int32_t iAllocOffset, + ISAR_SPLIT_REND_BITS_HANDLE pBits ) +{ + int32_t iBitsWritten; + + iBitsWritten = 0; + + if ( iAllocOffset < MIN_ALLOC_OFFSET || 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; + + 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, + ISAR_SPLIT_REND_BITS_HANDLE pBits ) +{ + int32_t iBitsWritten; + int32_t iNumLcldBands = c_aiNumLcldBandsPerBand[iNumBands - 1]; + int32_t s; + int32_t iSet = iSubSetId; + + iBitsWritten = 0; + for ( s = 0; s < iNumSubSets; s++, iSet-- ) + { + int32_t ch; + if ( iSet < 0 ) + { + iSet = iNumSubSets - 1; + } + + for ( ch = 0; ch < iNumChannels; ch++ ) + { + int32_t iBlockOffest = 0; + int32_t n; + for ( n = 0; n < piNumGroups[ch]; n++ ) + { + int32_t k; + for ( k = 0; k < ppiGroupLengths[ch][n]; k++ ) + { + int32_t iFBOffset; + for ( iFBOffset = iSet; iFBOffset < iNumLcldBands; iFBOffset += iNumSubSets ) + { + int32_t b; + int32_t iAlloc; + int32_t iHuffDim; + int32_t iHuffMod; + + b = c_aiBandIdPerLcldBand[iFBOffset]; + + iAlloc = pppiAlloc[ch][n][b]; + + iHuffDim = c_aiHuffmanDim[iAlloc]; + iHuffMod = c_aiHuffmanMod[iAlloc]; + + if ( iAlloc > 0 ) + { + const uint16_t( *pauiHuffmanTable )[2] = NULL; + const uint16_t( *pauiHuffmanTableDPCM )[2] = NULL; + int32_t iQuantValue1; + int32_t iQuantValue2; + pauiHuffmanTable = c_apauiHuffEncTabels[iAlloc]; + pauiHuffmanTableDPCM = c_apauiHuffEncTabels[ALLOC_TABLE_SIZE + iAlloc]; + + iQuantValue1 = pppiQReal[ch][iBlockOffest][iFBOffset]; + iQuantValue2 = pppiQImag[ch][iBlockOffest][iFBOffset]; +#ifdef LCLD_HANDLE_PRED_START_SAMPLE + if ( ppiPredEnable[ch][iFBOffset] == 1 && ( iBlockOffest > 0 || iSet != iSubSetId ) ) +#else + if ( ppiPredEnable[ch][iFBOffset] == 1 ) +#endif + { + if ( iHuffDim == 2 ) + { + int32_t iSymbol; + iSymbol = iQuantValue1; + iSymbol *= iHuffMod; + iSymbol += iQuantValue2; + ISAR_SPLIT_REND_BITStream_write_int32( pBits, pauiHuffmanTableDPCM[iSymbol][1], pauiHuffmanTableDPCM[iSymbol][0] ); + iBitsWritten += pauiHuffmanTableDPCM[iSymbol][0]; + } + else + { + ISAR_SPLIT_REND_BITStream_write_int32( pBits, pauiHuffmanTableDPCM[iQuantValue1][1], pauiHuffmanTableDPCM[iQuantValue1][0] ); + iBitsWritten += pauiHuffmanTableDPCM[iQuantValue1][0]; + + ISAR_SPLIT_REND_BITStream_write_int32( pBits, pauiHuffmanTableDPCM[iQuantValue2][1], pauiHuffmanTableDPCM[iQuantValue2][0] ); + iBitsWritten += pauiHuffmanTableDPCM[iQuantValue2][0]; + } + } + else + { + if ( iHuffDim == 2 ) + { + int32_t iSymbol; + iSymbol = iQuantValue1; + iSymbol *= iHuffMod; + iSymbol += iQuantValue2; + ISAR_SPLIT_REND_BITStream_write_int32( pBits, pauiHuffmanTable[iSymbol][1], pauiHuffmanTable[iSymbol][0] ); + iBitsWritten += pauiHuffmanTable[iSymbol][0]; + } + else + { + ISAR_SPLIT_REND_BITStream_write_int32( pBits, pauiHuffmanTable[iQuantValue1][1], pauiHuffmanTable[iQuantValue1][0] ); + iBitsWritten += pauiHuffmanTable[iQuantValue1][0]; + + ISAR_SPLIT_REND_BITStream_write_int32( pBits, pauiHuffmanTable[iQuantValue2][1], pauiHuffmanTable[iQuantValue2][0] ); + iBitsWritten += pauiHuffmanTable[iQuantValue2][0]; + } + } + + if ( iQuantValue1 > 0 ) + { + ISAR_SPLIT_REND_BITStream_write_int32( pBits, pppiSignReal[ch][iBlockOffest][iFBOffset], 1 ); + iBitsWritten += 1; + } + if ( iQuantValue2 > 0 ) + { + ISAR_SPLIT_REND_BITStream_write_int32( pBits, pppiSignImag[ch][iBlockOffest][iFBOffset], 1 ); + iBitsWritten += 1; + } + } + } + iBlockOffest++; + } + } + } + } + + 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, + PredictionEncoder *psPredictionEncoder ) +{ + int32_t iBitsUsed, iDone, iDelta; + int32_t b, k, n; + int32_t iLimitAllocOffset; + + iBitsUsed = ALLOC_OFFSET_BITS; /* Bits used for Alloc Offset */ + + iDone = 0; + iDelta = -MIN_ALLOC_OFFSET; + *piAllocOffset = 0; + + while ( iDone == 0 ) + { + iBitsUsed = ALLOC_OFFSET_BITS; + + iLimitAllocOffset = *piAllocOffset; + iLimitAllocOffset = ( iLimitAllocOffset > MIN_ALLOC_OFFSET ) ? iLimitAllocOffset : MIN_ALLOC_OFFSET; + iLimitAllocOffset = ( iLimitAllocOffset < MAX_ALLOC_OFFSET ) ? iLimitAllocOffset : MAX_ALLOC_OFFSET; + + for ( n = 0; n < iChannels; n++ ) + { + for ( k = 0; k < piNumGroups[n]; k++ ) + { + 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; + pppiAlloc[n][k][b] = iAlloc; + } + } + + if ( psPredictionEncoder->iNumSubSets > 1 ) + { + mvr2r( psPredictionEncoder->ppfPredStateReal[n], psPredictionEncoder->ppfPredStateRealTmp[n], LCLD_BANDS ); + mvr2r( psPredictionEncoder->ppfPredStateImag[n], psPredictionEncoder->ppfPredStateImagTmp[n], LCLD_BANDS ); + } + + QuantizeSpectrumDPCM_Opt( piNumGroups[n], + (const int32_t *) ppiGroupLengths[n], + iNumBands, + piBandwidths, + pppiAlloc[n], + pppfReal[n], + pppfImag[n], + pppiQReal[n], + pppiQImag[n], + pppiSignReal[n], + pppiSignImag[n], + 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] ); + } + + if ( *piAllocOffset <= MIN_ALLOC_OFFSET && iBitsUsed > iAvailableBits ) + { +#ifdef DEBUG_VERBOSE + printf( "Frame can not be coded with the number of bits available\n" ); +#endif + /* iLastError = ENC_ERROR_STREAM_FAILURE;*/ + return -1; + } + else if ( *piAllocOffset >= MAX_ALLOC_OFFSET && iBitsUsed < iAvailableBits ) + { + *piAllocOffset = MAX_ALLOC_OFFSET; + iDone++; + } + else + { + if ( iDelta == 0 && iBitsUsed > iAvailableBits ) + { + iDelta = 1; + } + else if ( iDelta == 0 && iBitsUsed < iAvailableBits ) + { + iDone++; + } + else if ( iBitsUsed == iAvailableBits ) + { + iDone++; + } + + if ( iBitsUsed > iAvailableBits ) + { + *piAllocOffset -= iDelta; + iDelta >>= 1; + } + else if ( iBitsUsed < iAvailableBits ) + { + *piAllocOffset += iDelta; + iDelta >>= 1; + } + } + } + + if ( psPredictionEncoder->iNumSubSets > 1 ) + { + for ( n = 0; n < iChannels; n++ ) + { + mvr2r( psPredictionEncoder->ppfPredStateRealTmp[n], psPredictionEncoder->ppfPredStateReal[n], LCLD_BANDS ); + mvr2r( psPredictionEncoder->ppfPredStateImagTmp[n], psPredictionEncoder->ppfPredStateImag[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 new file mode 100644 index 000000000..d3ce8cc96 --- /dev/null +++ b/lib_isar/isar_lcld_prot.h @@ -0,0 +1,393 @@ +/****************************************************************************************************** + + (C) 2022-2023 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 ISAR_LCLD_PROT_H +#define ISAR_LCLD_PROT_H + +#include "options.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT +#include "common_api_types.h" +#include "isar_rom_lcld_tables.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 + ); + +void DeleteLCLDEncoder( + LCLDEncoder *psLCLDEncoder +); + +int32_t EncodeLCLDFrame( + LCLDEncoder *psLCLDEncoder, + float ***pppfLCLDReal, + float ***pppfLCLDImag, + int32_t *piNumiBites, + const int32_t available_bits, + ISAR_SPLIT_REND_BITS_HANDLE pBits ); + + +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); + +void DeleteLCLDDecoder( + LCLDDecoder *psLCLDDecoder +); + +int32_t DecodeLCLDFrame( + LCLDDecoder *psLCLDDecoder, + ISAR_SPLIT_REND_BITS_HANDLE pBits, + float ***pppfLCLDReal, + float ***pppfLCLDImag +); + + +/*----------------------------------------------------------------------------------* + * MSPred prototypes + *----------------------------------------------------------------------------------*/ + +int32_t quantPhase( + float phase +); + +void cplxmult_lcld( + float *pr1, + float *pi1, + const float r2, + const float i2 +); + + +int32_t requantPhase( + int32_t phaseQ +); + +int32_t quantPred( + const float pred +); + +float dequantPhase( + const int32_t phaseQ +); + +float dequantPred( + int32_t predQ +); + +int32_t PrepEncode( + int32_t *piQuant, + const int32_t *piMSFlags, + const int32_t numBands +); + +void EncodePhase( + int32_t *phaseQuant, + const int32_t numMSBands, + const int32_t diffDim +); + +void DecodePhase( + int32_t *phaseQuant, + const int32_t numMSBands, + const int32_t diffDim +); + +int32_t EncodePredCoef( + int32_t *predQuant, + const int32_t numMSBands +); + +void DecodePredCoef( + int32_t *phaseQuant, + const int32_t numMSBands +); + +void writeMSPred( + int32_t *phaseQuant, + int32_t *predQuant, + const int32_t MSMode, + const int32_t numMSBands, + int32_t numBands, + void *fid, + 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 +); + + +/*----------------------------------------------------------------------------------* + * NoiseGen prototypes + *----------------------------------------------------------------------------------*/ + +typedef struct NOISE_GEN +{ + int32_t iNoiseBufferLength; + int32_t iNoiseBufferMask; + int32_t iNoiseBufferIndex; + float *pfNoiseBuffer; +} NoiseGen; + +void DeleteNoiseGen( + NoiseGen *psNoiseGen +); + +inline float GetNoise( NoiseGen *psNoiseGen ) +{ + float fNoiseSample; + + fNoiseSample = psNoiseGen->pfNoiseBuffer[psNoiseGen->iNoiseBufferIndex]; + psNoiseGen->iNoiseBufferIndex++; + psNoiseGen->iNoiseBufferIndex &= psNoiseGen->iNoiseBufferMask; + + return fNoiseSample; +} + + +/*----------------------------------------------------------------------------------* + * PereptualModel prototypes + *----------------------------------------------------------------------------------*/ + +extern void PerceptualModel( + const int32_t iMaxQuantBands, + const int32_t *piRMSEnvelope, + int32_t *piExcitation, + int32_t *piSMR +); + +extern void PerceptualModelStereo( + const int32_t iMaxQuantBands, + const int32_t *piMSFlags, + const int32_t *piRMSEnvelope0, + const int32_t *piRMSEnvelope1, + int32_t *piExcitation0, + int32_t *piExcitation1, + int32_t *piSMR0, + int32_t *piSMR1 +); + + +/*----------------------------------------------------------------------------------* + * PredEncoder/PredDecoder prototypes + *----------------------------------------------------------------------------------*/ + +typedef struct PREDICTION_ENCODER +{ + int32_t iChannels; + int32_t iNumBlocks; + + int32_t iSubSetId; + int32_t iNumSubSets; + int32_t iMaxNumPredBands; + float ***pppfInpBufReal; /* channels, LCLD_PRED_WIN_LEN, bands */ + float ***pppfInpBufImag; + float **ppfPredStateReal; /* channels, bands */ + float **ppfPredStateImag; + float **ppfPredStateRealTmp; + float **ppfPredStateImagTmp; + float **ppfInpPrevReal; /* channels, bands */ + float **ppfInpPrevImag; + float pfRxxReal[2]; + float pfRxxImag[2]; + + int32_t *piPredChanEnable; + int32_t *piNumPredBands; + int32_t **ppiPredBandEnable; + + float **ppfA1Real; + float **ppfA1Imag; + + int32_t **ppiA1Mag; + int32_t **ppiA1Phase; +} PredictionEncoder; + +ivas_error CreatePredictionEncoder( + PredictionEncoder **psPredictionEncoder_out, + const int32_t iChannels, + const int32_t iNumBlocks, + const int32_t iNumSubSets, + const int32_t iMaxNumPredBands +); + +void DeletePredictionEncoder( + PredictionEncoder *psPredictionEncoder +); + +void ComputePredictors( + PredictionEncoder *psPredictionEncoder, + float ***pppfReal, + float ***pppfImag +); + + +int32_t WritePredictors( + PredictionEncoder *psPredictionEncoder, + ISAR_SPLIT_REND_BITS_HANDLE pBits +); + +typedef struct PREDICTION_DECODER +{ + int32_t iChannels; + int32_t iNumBlocks; + int32_t iSubSetId; + int32_t iNumSubSets; + float **ppfPredStateReal; + float **ppfPredStateImag; + + int32_t *piPredChanEnable; + int32_t **ppiPredBandEnable; + + /* PLC_IMPROVEMENT */ + int32_t **ppiDecodingUnresolved; + int32_t **ppiDecodingFailed; + int32_t **ppiDecodingFailedPrev; + + float **ppfA1Real; + float **ppfA1Imag; + + 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]; + +} PredictionDecoder; + +ivas_error CreatePredictionDecoder( + PredictionDecoder **psPredictionDecoder_out, + const int32_t iChannels, + const int32_t iNumBlocks +); + +void DeletePredictionDecoder( + PredictionDecoder *psPredictionDecoder +); + +int32_t ReadPredictors( + PredictionDecoder *psPredictionDecoder, + ISAR_SPLIT_REND_BITS_HANDLE pBits +); + +/* PLC_IMPROVEMENT */ +void UpdatePredictionSubSetId( + PredictionEncoder *psPredictionEncoder); + +void SetDecodingUnresolved( + LCLDDecoder *psLCLDDecoder); + +int32_t AnyDecodingFailedPrev( + LCLDDecoder *psLCLDDecoder); + +int32_t AnyDecodingFailed( + LCLDDecoder *psLCLDDecoder); + +int32_t **GetDecodingFailedStatus( + LCLDDecoder *psLCLDDecoder); + +int16_t GetNumSubSets( + LCLDDecoder *psLCLDDecoder); + +int32_t **GetDecodingFailedPrevStatus( + LCLDDecoder *psLCLDDecoder); + +void SetDecodingPassed( + PredictionDecoder *psPredictionDecoder); + +void UpdateDecodingUnresolved( + PredictionDecoder *psPredictionDecoder); + +void UpdateDecodingFailedStatus( + PredictionDecoder *psPredictionDecoder); + +int32_t AnyDecodingUnresolved( + PredictionDecoder *psPredictionDecoder); + +void ApplyInversePredictors( + PredictionDecoder *psPredictionDecoder, + float ***pppfReal, + float ***pppfImag +); + + +/*----------------------------------------------------------------------------------* + * RMSEnvGrouping prototypes + *----------------------------------------------------------------------------------*/ + +typedef struct RMS_ENVELOPE_GROUPING RMSEnvelopeGrouping; + +RMSEnvelopeGrouping *CreateRMSEnvelopeGrouping( + const int32_t iNumBlocks +); + +void DeleteRMSEnvelopeGrouping( + RMSEnvelopeGrouping *psRMSEnvelopeGrouping +); + +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 +); + + +#endif +/* clang-format on */ + +#endif /* _LCLD_ENCODER_H_ */ diff --git a/lib_isar/isar_prot.h b/lib_isar/isar_prot.h new file mode 100644 index 000000000..43248926d --- /dev/null +++ b/lib_isar/isar_prot.h @@ -0,0 +1,393 @@ +/****************************************************************************************************** + + (C) 2022-2023 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 ISAR_PROT_H +#define ISAR_PROT_H + + +#include "isar_stat.h" + +#ifdef SPLIT_REND_WITH_HEAD_ROT + +#include +#include "options.h" +#include "ivas_error.h" +#include "lib_isar_post_rend.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( + ISAR_SPLIT_REND_BITS_HANDLE pBits, + const int32_t bits ); + +void ISAR_SPLIT_REND_BITStream_write_int32( + ISAR_SPLIT_REND_BITS_HANDLE pBits, + const int32_t val, + const int32_t bits ); + +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 ); + +ivas_error isar_splitBinRendPLCOpen( + ISAR_SPLIT_REND_PLC_HANDLE *phSplitRendPLC, + const 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 ); + +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], + const int16_t num_chs, + const int16_t iNumBlocks, + const int16_t iNumIterations ); + +void isar_splitBinRendPLC_xf( + 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 ); + +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 ); + +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG +void isar_log_cldfb2wav_data( + float Cldfb_In_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + float Cldfb_In_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + HANDLE_CLDFB_FILTER_BANK *cldfbSyn, + const int16_t num_chs, + const int16_t num_freq_bands, + const int32_t output_Fs, + const int16_t start_slot_idx, + const int16_t md_band_idx, + const char *filename ); +#endif + +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 ); + +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 ); + +void set_pose_types( + ISAR_SPLIT_REND_POSE_TYPE pose_type[MAX_HEAD_ROT_POSES - 1], + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData ); + +void isar_split_rend_init_huff_cfg( + ISAR_BIN_HR_SPLIT_REND_HUFF_HANDLE pHuff_cfg ); + +ivas_error isar_splitBinPostRendOpen( + ISAR_BIN_HR_SPLIT_POST_REND_HANDLE *hBinHrSplitPostRend, + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + const int32_t output_Fs ); + +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 ); + +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], +#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 +); + +void isar_splitBinPostRendMdDec( + ISAR_SPLIT_REND_BITS_HANDLE pBits, + ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend, +#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 +); + +void Quat2EulerDegree( + const IVAS_QUATERNION quat, /* i : quaternion describing the rotation */ + float *yaw, /* o : yaw */ + float *pitch, /* o : pitch */ + float *roll /* o : roll */ +); + +void isar_mat_mult_2by2_complex( + float in_re1[2][2], + float in_im1[2][2], + float in_re2[2][2], + float in_im2[2][2], + float out_re2[2][2], + float out_im2[2][2] ); + +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 ); + +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, + 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 ); + +#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS +int16_t isar_renderSplitGetRot_axisNumBits( + const int16_t dof ); + +ISAR_SPLIT_REND_ROT_AXIS isar_renderSplitGetRot_axisFromCode( + const int16_t dof, + const int16_t code ); + +int16_t isar_renderSplitGetCodeFromRot_axis( + const int16_t dof, + const ISAR_SPLIT_REND_ROT_AXIS rot_axis, + int16_t *num_bits ); +#endif + +void isar_init_split_post_rend_handles( + ISAR_SPLIT_POST_REND_WRAPPER *hSplitRendWrapper ); + +void isar_set_split_rend_ht_setup( + SPLIT_REND_WRAPPER *hSplitrend, + IVAS_QUATERNION Quaternions[MAX_PARAM_SPATIAL_SUBFRAMES], + float Rmat[MAX_PARAM_SPATIAL_SUBFRAMES][3][3] ); + +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS +int32_t isar_get_lc3plus_bitrate( + const int32_t SplitRendBitRate, + const ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode, + const int16_t 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 ); + +int32_t isar_get_lcld_bitrate( + const int32_t 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 ); +#endif + +int32_t isar_get_split_rend_md_target_brate( + const int32_t SplitRendBitRate, + const int16_t pcm_out_flag ); + +#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 */ +); +#endif + +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 */ +#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 */ +); + +void ISAR_SPLIT_REND_BITStream_init( + ISAR_SPLIT_REND_BITS_HANDLE pBits, + const int32_t buf_len_bytes, + uint8_t *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 ); + +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS +int32_t isar_get_lc3plus_size_from_id( + const int8_t SplitRendBitRateId, + const ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode, + const int16_t 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 ); + +ISAR_POST_REND_AudioConfigType isar_getAudioConfigType( + const IVAS_AUDIO_CONFIG config ); + +void isar_init_split_rend_handles( + SPLIT_REND_WRAPPER *hSplitRendWrapper ); + +#endif + +/* clang-format on */ + +#endif /* ISAR_PROT_H */ diff --git a/lib_isar/isar_rom_lcld_tables.c b/lib_isar/isar_rom_lcld_tables.c new file mode 100644 index 000000000..bd2487404 --- /dev/null +++ b/lib_isar/isar_rom_lcld_tables.c @@ -0,0 +1,12097 @@ +/****************************************************************************************************** + + (C) 2022-2023 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. + +*******************************************************************************************************/ + +#include "isar_rom_lcld_tables.h" +#include "options.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT +#include "wmc_auto.h" +#include "prot.h" +#include "isar_lcld_prot.h" + +/* clang-format off */ +const int32_t c_aiNumLcldBandsPerBand[MAX_BANDS_48] = { + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 21, 24, 27, 31, 37, 43, 50, 60 +}; + +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] = +{ + { -1.00000000f, -0.00000000f }, + { -0.96592583f, -0.25881905f }, + { -0.86602540f, -0.50000000f }, + { -0.70710678f, -0.70710678f }, + { -0.50000000f, -0.86602540f }, + { -0.25881905f, -0.96592583f }, + { 0.00000000f, -1.00000000f }, + { 0.25881905f, -0.96592583f }, + { 0.50000000f, -0.86602540f }, + { 0.70710678f, -0.70710678f }, + { 0.86602540f, -0.50000000f }, + { 0.96592583f, -0.25881905f }, + { 1.00000000f, 0.00000000f }, + { 0.96592583f, 0.25881905f }, + { 0.86602540f, 0.50000000f }, + { 0.70710678f, 0.70710678f }, + { 0.50000000f, 0.86602540f }, + { 0.25881905f, 0.96592583f }, + { 0.00000000f, 1.00000000f }, + { -0.25881905f, 0.96592583f }, + { -0.50000000f, 0.86602540f }, + { -0.70710678f, 0.70710678f }, + { -0.86602540f, 0.50000000f }, + { -0.96592583f, 0.25881905f }, + { -1.00000000f, 0.00000000f } +}; + +const int32_t c_aiBandwidths48[MAX_BANDS_48] = +{ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 2, + 2, + 2, + 2, + 2, + 3, + 3, + 4, + 6, + 6, + 7, + 10, +}; + + +const float c_afScaleFactor[ALLOC_TABLE_SIZE] = { + 0.0f, + 0.353553390593f, + 0.420448207627f, + 0.500000000000f, + 0.594603557501f, + 0.707106781187f, + 0.840896415254f, + 1.000000000000f, + 1.189207115003f, + 1.414213562373f, + 1.681792830507f, + 2.000000000000f, + 2.378414230005f, + 2.828427124746f, + 3.363585661015f, + 4.0f, + 4.756828460011f, + 5.656854249492f, + 6.727171322030f, + 8.0f, + 9.513656920022f, + 11.31370849898f, + 13.45434264406f, + 16.00000000000f, + 19.02731384004f, + 22.62741699797f, + 26.90868528812f, + 32.000000000000000f, + 38.054627680087073f, + 45.254833995939038f, + 53.817370576237735f, + 64.000000000000000f, +}; + +const float c_afInvScaleFactor[ALLOC_TABLE_SIZE] = { + 0.0f, + 2.367513562373095f, + 2.046407115002721f, + 1.775900000000000f, + 1.536446415253715f, + 1.323056781186548f, + 1.132903557501360f, + 0.965800000000000f, + 0.821348207626857f, + 0.695103390593274f, + 0.587801778750680f, + 0.495800000000000f, + 0.418124103813429f, + 0.352176695296637f, + 0.296200889375340f, + 0.249400000000000f, + 0.209812051906714f, + 0.176538347648318f, + 0.148525444687670f, + 0.124900000000000f, + 0.105056025953357f, + 0.088388347648318f, + 0.074325444687670f, + 0.062500000000000f, + 0.052556025953357f, + 0.044194173824159f, + 0.037162722343835f, + 0.031250000000000f, + 0.026278012976679f, + 0.022097086912080f, + 0.018581361171918f, + 0.015625000000000f, +}; + +const float c_afRMSEnvReconstructTable[ENV_RECONSTRUCT_TABLE_SIZE] = { + 2.32830644e-10f, + 3.29272254e-10f, + 4.65661287e-10f, + 6.58544508e-10f, + 9.31322575e-10f, + 1.31708902e-09f, + 1.86264515e-09f, + 2.63417803e-09f, + 3.72529030e-09f, + 5.26835606e-09f, + 7.45058060e-09f, + 1.05367121e-08f, + 1.49011612e-08f, + 2.10734243e-08f, + 2.98023224e-08f, + 4.21468485e-08f, + 5.96046448e-08f, + 8.42936970e-08f, + 1.19209290e-07f, + 1.68587394e-07f, + 2.38418579e-07f, + 3.37174788e-07f, + 4.76837158e-07f, + 6.74349576e-07f, + 9.53674316e-07f, + 1.34869915e-06f, + 1.90734863e-06f, + 2.69739830e-06f, + 3.81469727e-06f, + 5.39479661e-06f, + 7.62939453e-06f, + 1.07895932e-05f, + 1.52587891e-05f, + 2.15791864e-05f, + 3.05175781e-05f, + 4.31583729e-05f, + 6.10351562e-05f, + 8.63167458e-05f, + 1.22070312e-04f, + 1.72633492e-04f, + 2.44140625e-04f, + 3.45266983e-04f, + 4.88281250e-04f, + 6.90533966e-04f, + 9.76562500e-04f, + 1.38106793e-03f, + 1.95312500e-03f, + 2.76213586e-03f, + 3.90625000e-03f, + 5.52427173e-03f, + 7.81250000e-03f, + 1.10485435e-02f, + 1.56250000e-02f, + 2.20970869e-02f, + 3.12500000e-02f, + 4.41941738e-02f, + 6.25000000e-02f, + 8.83883476e-02f, + 1.25000000e-01f, + 1.76776695e-01f, + 2.50000000e-01f, + 3.53553391e-01f, + 5.00000000e-01f, + 7.07106781e-01f, + 1.00000000e+00f, + 1.41421356e+00f, + 2.00000000e+00f, + 2.82842712e+00f, + 4.00000000e+00f, + 5.65685425e+00f, + 8.00000000e+00f, + 1.13137085e+01f, + 1.60000000e+01f, + 2.26274170e+01f, + 3.20000000e+01f, + 4.52548340e+01f, + 6.40000000e+01f, + 9.05096680e+01f, + 1.28000000e+02f, + 1.81019336e+02f, + 2.56000000e+02f, + 3.62038672e+02f, + 5.12000000e+02f, + 7.24077344e+02f, + 1.02400000e+03f, + 1.44815469e+03f, + 2.04800000e+03f, + 2.89630938e+03f, + 4.09600000e+03f, + 5.79261875e+03f, + 8.19200000e+03f, + 1.15852375e+04f, + 1.63840000e+04f, + 2.31704750e+04f, + 3.27680000e+04f, + 4.63409500e+04f, + 6.55360000e+04f, + 9.26819000e+04f, + 1.31072000e+05f, + 1.85363800e+05f, + 2.62144000e+05f, + 3.70727600e+05f, + 5.24288000e+05f, + 7.41455200e+05f, + 1.04857600e+06f, + 1.48291040e+06f, + 2.09715200e+06f, + 2.96582080e+06f, + 4.19430400e+06f, + 5.93164160e+06f, + 8.38860800e+06f, + 1.18632832e+07f, + 1.67772160e+07f, + 2.37265664e+07f, + 3.35544320e+07f, + 4.74531328e+07f, + 6.71088640e+07f, + 9.49062656e+07f, + 1.34217728e+08f, + 1.89812531e+08f, + 2.68435456e+08f, + 3.79625062e+08f, + 5.36870912e+08f, + 7.59250125e+08f, + 1.07374182e+09f, + 1.51850025e+09f, + 2.14748365e+09f, + 3.03700050e+09f, + 4.29496730e+09f, +}; + +const int32_t c_aiQuantMaxValues[ALLOC_TABLE_SIZE] = { + 0, + 3, + 3, + 4, + 5, + 5, + 6, + 7, + 8, + 9, + 12, + 13, + 16, + 17, + 19, + 23, + 26, + 26, + 27, + 28, + 31, + 36, + 38, + 45, + 54, + 64, + 76, + 90, + 108, + 128, + 152, + 180, +}; + +const int32_t c_aiHuffmanDim[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 int32_t c_aiHuffmanMod[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_aiHuffmanSize[ALLOC_TABLE_SIZE] = { + 1, + 16, + 16, + 25, + 36, + 36, + 49, + 64, + 81, + 100, + 169, + 196, + 289, + 324, + 400, + 576, + 729, + 729, + 28, + 29, + 32, + 37, + 39, + 46, + 55, + 65, + 77, + 91, + 109, + 129, + 153, + 181, +}; + +const uint32_t c_aaiRMSEnvHuffEnc[64][2] = { + { 0x0014, 0x0000 }, + { 0x0014, 0x0001 }, + { 0x0014, 0x0002 }, + { 0x0014, 0x0003 }, + { 0x0014, 0x0004 }, + { 0x0014, 0x0005 }, + { 0x0013, 0x0003 }, + { 0x0013, 0x0004 }, + { 0x0013, 0x0005 }, + { 0x0013, 0x0006 }, + { 0x0013, 0x0007 }, + { 0x0012, 0x000b }, + { 0x000d, 0x0002 }, + { 0x000e, 0x0001 }, + { 0x000e, 0x0002 }, + { 0x000d, 0x0003 }, + { 0x000b, 0x0002 }, + { 0x000a, 0x0003 }, + { 0x000a, 0x0004 }, + { 0x000a, 0x0005 }, + { 0x0009, 0x0004 }, + { 0x0009, 0x0005 }, + { 0x0009, 0x0006 }, + { 0x0008, 0x0005 }, + { 0x0008, 0x0006 }, + { 0x0007, 0x0004 }, + { 0x0006, 0x0003 }, + { 0x0006, 0x0004 }, + { 0x0005, 0x0003 }, + { 0x0004, 0x0002 }, + { 0x0003, 0x0002 }, + { 0x0002, 0x0002 }, + { 0x0002, 0x0003 }, + { 0x0003, 0x0003 }, + { 0x0004, 0x0003 }, + { 0x0006, 0x0005 }, + { 0x0007, 0x0005 }, + { 0x0008, 0x0007 }, + { 0x0009, 0x0007 }, + { 0x0009, 0x0008 }, + { 0x0009, 0x0009 }, + { 0x000a, 0x0006 }, + { 0x000a, 0x0007 }, + { 0x000b, 0x0003 }, + { 0x000c, 0x0002 }, + { 0x000c, 0x0003 }, + { 0x000b, 0x0004 }, + { 0x000b, 0x0005 }, + { 0x000e, 0x0003 }, + { 0x0010, 0x0003 }, + { 0x0013, 0x0008 }, + { 0x0013, 0x0009 }, + { 0x0013, 0x000a }, + { 0x0013, 0x000b }, + { 0x0013, 0x000c }, + { 0x0013, 0x000d }, + { 0x0013, 0x000e }, + { 0x0013, 0x000f }, + { 0x0013, 0x0010 }, + { 0x0013, 0x0011 }, + { 0x0013, 0x0012 }, + { 0x0013, 0x0013 }, + { 0x0013, 0x0014 }, + { 0x0013, 0x0015 }, +}; + +const uint32_t c_aaiRMSEnvHuffDec[13][HUFF_DEC_TABLE_SIZE] = { + { + 0x0002ffff, + 0x0001ffff, + 0x0000001d, + 0x00000022, + 0x0001001e, + 0x0001001e, + 0x00010021, + 0x00010021, + 0x0002001f, + 0x0002001f, + 0x0002001f, + 0x0002001f, + 0x00020020, + 0x00020020, + 0x00020020, + 0x00020020, + }, + { + 0x0002001b, + 0x0002001b, + 0x0002001b, + 0x0002001b, + 0x00020023, + 0x00020023, + 0x00020023, + 0x00020023, + 0x0003001c, + 0x0003001c, + 0x0003001c, + 0x0003001c, + 0x0003001c, + 0x0003001c, + 0x0003001c, + 0x0003001c, + }, + { + 0x0006ffff, + 0x0007ffff, + 0x0003ffff, + 0x0004ffff, + 0x0005ffff, + 0x00000017, + 0x00000018, + 0x00000025, + 0x00010019, + 0x00010019, + 0x00010024, + 0x00010024, + 0x0002001a, + 0x0002001a, + 0x0002001a, + 0x0002001a, + }, + { + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030014, + 0x00030015, + 0x00030015, + 0x00030015, + 0x00030015, + 0x00030015, + 0x00030015, + 0x00030015, + 0x00030015, + }, + { + 0x00030016, + 0x00030016, + 0x00030016, + 0x00030016, + 0x00030016, + 0x00030016, + 0x00030016, + 0x00030016, + 0x00030026, + 0x00030026, + 0x00030026, + 0x00030026, + 0x00030026, + 0x00030026, + 0x00030026, + 0x00030026, + }, + { + 0x00030027, + 0x00030027, + 0x00030027, + 0x00030027, + 0x00030027, + 0x00030027, + 0x00030027, + 0x00030027, + 0x00030028, + 0x00030028, + 0x00030028, + 0x00030028, + 0x00030028, + 0x00030028, + 0x00030028, + 0x00030028, + }, + { + 0x0009ffff, + 0x0008ffff, + 0x0000002c, + 0x0000002d, + 0x00010010, + 0x00010010, + 0x0001002b, + 0x0001002b, + 0x0001002e, + 0x0001002e, + 0x0001002f, + 0x0001002f, + 0x00020011, + 0x00020011, + 0x00020011, + 0x00020011, + }, + { + 0x00020012, + 0x00020012, + 0x00020012, + 0x00020012, + 0x00020013, + 0x00020013, + 0x00020013, + 0x00020013, + 0x00020029, + 0x00020029, + 0x00020029, + 0x00020029, + 0x0002002a, + 0x0002002a, + 0x0002002a, + 0x0002002a, + }, + { + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000c, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + 0x0003000f, + }, + { + 0x000bffff, + 0x000cffff, + 0x000affff, + 0x00000031, + 0x0002000d, + 0x0002000d, + 0x0002000d, + 0x0002000d, + 0x0002000e, + 0x0002000e, + 0x0002000e, + 0x0002000e, + 0x00020030, + 0x00020030, + 0x00020030, + 0x00020030, + }, + { + 0x0001003a, + 0x0001003a, + 0x0001003b, + 0x0001003b, + 0x0001003c, + 0x0001003c, + 0x0001003d, + 0x0001003d, + 0x0001003e, + 0x0001003e, + 0x0001003f, + 0x0001003f, + 0x0002000b, + 0x0002000b, + 0x0002000b, + 0x0002000b, + }, + { + 0x00000000, + 0x00000001, + 0x00000002, + 0x00000003, + 0x00000004, + 0x00000005, + 0x00010006, + 0x00010006, + 0x00010007, + 0x00010007, + 0x00010008, + 0x00010008, + 0x00010009, + 0x00010009, + 0x0001000a, + 0x0001000a, + }, + { + 0x00010032, + 0x00010032, + 0x00010033, + 0x00010033, + 0x00010034, + 0x00010034, + 0x00010035, + 0x00010035, + 0x00010036, + 0x00010036, + 0x00010037, + 0x00010037, + 0x00010038, + 0x00010038, + 0x00010039, + 0x00010039, + }, +}; + +const uint16_t c_aauiLCLDHuffEnc1[16][2] = + { + { 0x0001, 0x0001 }, + { 0x0003, 0x0001 }, + { 0x0005, 0x0001 }, + { 0x000b, 0x0000 }, + { 0x0002, 0x0001 }, + { 0x0004, 0x0001 }, + { 0x0007, 0x0001 }, + { 0x000b, 0x0001 }, + { 0x0006, 0x0001 }, + { 0x0008, 0x0001 }, + { 0x000b, 0x0002 }, + { 0x000b, 0x0003 }, + { 0x000b, 0x0004 }, + { 0x000b, 0x0005 }, + { 0x000b, 0x0006 }, + { 0x000b, 0x0007 }, + }; + +const uint16_t c_aauiLCLDHuffEnc2[16][2] = + { + { 0x0001, 0x0001 }, + { 0x0003, 0x0001 }, + { 0x0005, 0x0001 }, + { 0x000c, 0x0000 }, + { 0x0002, 0x0001 }, + { 0x0004, 0x0001 }, + { 0x0007, 0x0001 }, + { 0x000c, 0x0001 }, + { 0x0006, 0x0001 }, + { 0x0008, 0x0001 }, + { 0x0009, 0x0001 }, + { 0x000c, 0x0002 }, + { 0x000c, 0x0003 }, + { 0x000c, 0x0004 }, + { 0x000c, 0x0005 }, + { 0x000b, 0x0003 }, + }; + +const uint16_t c_aauiLCLDHuffEnc3[25][2] = + { + { 0x0001, 0x0001 }, + { 0x0003, 0x0001 }, + { 0x0006, 0x0001 }, + { 0x000d, 0x0000 }, + { 0x000d, 0x0001 }, + { 0x0002, 0x0001 }, + { 0x0004, 0x0001 }, + { 0x0007, 0x0001 }, + { 0x000d, 0x0002 }, + { 0x000d, 0x0003 }, + { 0x0006, 0x0002 }, + { 0x0006, 0x0003 }, + { 0x0008, 0x0001 }, + { 0x000d, 0x0004 }, + { 0x000d, 0x0005 }, + { 0x0009, 0x0001 }, + { 0x000c, 0x0007 }, + { 0x000d, 0x0006 }, + { 0x000d, 0x0007 }, + { 0x000d, 0x0008 }, + { 0x000d, 0x0009 }, + { 0x000d, 0x000a }, + { 0x000d, 0x000b }, + { 0x000d, 0x000c }, + { 0x000d, 0x000d }, + + }; + +const uint16_t c_aauiLCLDHuffEnc4[36][2] = + { + { 0x0001, 0x0001 }, + { 0x0003, 0x0001 }, + { 0x0006, 0x0001 }, + { 0x000b, 0x0001 }, + { 0x0010, 0x0000 }, + { 0x0010, 0x0001 }, + { 0x0002, 0x0001 }, + { 0x0004, 0x0001 }, + { 0x0007, 0x0001 }, + { 0x000a, 0x0001 }, + { 0x0010, 0x0002 }, + { 0x0010, 0x0003 }, + { 0x0006, 0x0002 }, + { 0x0006, 0x0003 }, + { 0x0008, 0x0001 }, + { 0x000e, 0x0006 }, + { 0x0010, 0x0004 }, + { 0x0010, 0x0005 }, + { 0x000a, 0x0002 }, + { 0x000a, 0x0003 }, + { 0x000e, 0x0007 }, + { 0x0010, 0x0006 }, + { 0x0010, 0x0007 }, + { 0x0010, 0x0008 }, + { 0x0010, 0x0009 }, + { 0x0010, 0x000a }, + { 0x0010, 0x000b }, + { 0x0010, 0x000c }, + { 0x0010, 0x000d }, + { 0x0010, 0x000e }, + { 0x0010, 0x000f }, + { 0x0010, 0x0010 }, + { 0x0010, 0x0011 }, + { 0x000f, 0x0009 }, + { 0x000f, 0x000a }, + { 0x000f, 0x000b }, + + }; + +const uint16_t c_aauiLCLDHuffEnc5[36][2] = + { + { 0x0001, 0x0001 }, + { 0x0003, 0x0001 }, + { 0x0006, 0x0001 }, + { 0x000a, 0x0001 }, + { 0x000f, 0x0003 }, + { 0x0012, 0x0000 }, + { 0x0002, 0x0001 }, + { 0x0004, 0x0001 }, + { 0x0007, 0x0001 }, + { 0x000b, 0x0001 }, + { 0x0011, 0x0008 }, + { 0x0012, 0x0001 }, + { 0x0006, 0x0002 }, + { 0x0006, 0x0003 }, + { 0x0008, 0x0001 }, + { 0x000c, 0x0001 }, + { 0x0012, 0x0002 }, + { 0x0012, 0x0003 }, + { 0x000a, 0x0002 }, + { 0x000a, 0x0003 }, + { 0x000d, 0x0001 }, + { 0x0012, 0x0004 }, + { 0x0012, 0x0005 }, + { 0x0012, 0x0006 }, + { 0x0011, 0x0009 }, + { 0x0011, 0x000a }, + { 0x0012, 0x0007 }, + { 0x0012, 0x0008 }, + { 0x0012, 0x0009 }, + { 0x0012, 0x000a }, + { 0x0012, 0x000b }, + { 0x0012, 0x000c }, + { 0x0012, 0x000d }, + { 0x0012, 0x000e }, + { 0x0012, 0x000f }, + { 0x0011, 0x000b }, + + }; + +const uint16_t c_aauiLCLDHuffEnc6[49][2] = + { + { 0x0001, 0x0001 }, + { 0x0003, 0x0001 }, + { 0x0006, 0x0001 }, + { 0x000a, 0x0001 }, + { 0x0010, 0x0003 }, + { 0x0014, 0x0000 }, + { 0x0014, 0x0001 }, + { 0x0002, 0x0001 }, + { 0x0004, 0x0001 }, + { 0x0007, 0x0001 }, + { 0x000a, 0x0002 }, + { 0x0010, 0x0004 }, + { 0x0014, 0x0002 }, + { 0x0014, 0x0003 }, + { 0x0006, 0x0002 }, + { 0x0006, 0x0003 }, + { 0x0008, 0x0001 }, + { 0x000d, 0x0001 }, + { 0x0012, 0x0007 }, + { 0x0014, 0x0004 }, + { 0x0014, 0x0005 }, + { 0x000a, 0x0003 }, + { 0x000b, 0x0001 }, + { 0x000c, 0x0001 }, + { 0x0011, 0x0004 }, + { 0x0014, 0x0006 }, + { 0x0014, 0x0007 }, + { 0x0014, 0x0008 }, + { 0x0010, 0x0005 }, + { 0x000f, 0x0003 }, + { 0x0011, 0x0005 }, + { 0x0014, 0x0009 }, + { 0x0014, 0x000a }, + { 0x0014, 0x000b }, + { 0x0014, 0x000c }, + { 0x0014, 0x000d }, + { 0x0013, 0x000d }, + { 0x0014, 0x000e }, + { 0x0014, 0x000f }, + { 0x0014, 0x0010 }, + { 0x0014, 0x0011 }, + { 0x0014, 0x0012 }, + { 0x0014, 0x0013 }, + { 0x0014, 0x0014 }, + { 0x0014, 0x0015 }, + { 0x0014, 0x0016 }, + { 0x0014, 0x0017 }, + { 0x0014, 0x0018 }, + { 0x0014, 0x0019 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc7[64][2] = + { + { 0x0002, 0x0001 }, + { 0x0002, 0x0002 }, + { 0x0005, 0x0001 }, + { 0x0009, 0x0001 }, + { 0x000f, 0x0002 }, + { 0x0015, 0x0000 }, + { 0x0015, 0x0001 }, + { 0x0015, 0x0002 }, + { 0x0002, 0x0003 }, + { 0x0003, 0x0001 }, + { 0x0006, 0x0001 }, + { 0x0009, 0x0002 }, + { 0x000f, 0x0003 }, + { 0x0014, 0x0011 }, + { 0x0015, 0x0003 }, + { 0x0015, 0x0004 }, + { 0x0005, 0x0002 }, + { 0x0005, 0x0003 }, + { 0x0007, 0x0001 }, + { 0x000b, 0x0001 }, + { 0x0010, 0x0002 }, + { 0x0015, 0x0005 }, + { 0x0015, 0x0006 }, + { 0x0015, 0x0007 }, + { 0x000a, 0x0001 }, + { 0x0009, 0x0003 }, + { 0x000c, 0x0001 }, + { 0x000f, 0x0004 }, + { 0x0012, 0x0006 }, + { 0x0015, 0x0008 }, + { 0x0015, 0x0009 }, + { 0x0015, 0x000a }, + { 0x000f, 0x0005 }, + { 0x000e, 0x0003 }, + { 0x0010, 0x0003 }, + { 0x0012, 0x0007 }, + { 0x0014, 0x0012 }, + { 0x0015, 0x000b }, + { 0x0015, 0x000c }, + { 0x0015, 0x000d }, + { 0x0014, 0x0013 }, + { 0x0014, 0x0014 }, + { 0x0013, 0x000b }, + { 0x0014, 0x0015 }, + { 0x0015, 0x000e }, + { 0x0015, 0x000f }, + { 0x0015, 0x0010 }, + { 0x0015, 0x0011 }, + { 0x0015, 0x0012 }, + { 0x0015, 0x0013 }, + { 0x0015, 0x0014 }, + { 0x0015, 0x0015 }, + { 0x0015, 0x0016 }, + { 0x0015, 0x0017 }, + { 0x0015, 0x0018 }, + { 0x0015, 0x0019 }, + { 0x0015, 0x001a }, + { 0x0015, 0x001b }, + { 0x0015, 0x001c }, + { 0x0015, 0x001d }, + { 0x0015, 0x001e }, + { 0x0015, 0x001f }, + { 0x0015, 0x0020 }, + { 0x0015, 0x0021 }, + }; + +const uint16_t c_aauiLCLDHuffEnc8[81][2] = + { + { 0x0001, 0x0001 }, + { 0x0003, 0x0001 }, + { 0x0006, 0x0001 }, + { 0x000a, 0x0001 }, + { 0x000f, 0x0002 }, + { 0x0014, 0x0008 }, + { 0x0017, 0x0000 }, + { 0x0017, 0x0001 }, + { 0x0017, 0x0002 }, + { 0x0003, 0x0002 }, + { 0x0003, 0x0003 }, + { 0x0005, 0x0001 }, + { 0x0009, 0x0001 }, + { 0x000f, 0x0003 }, + { 0x0012, 0x0004 }, + { 0x0015, 0x000d }, + { 0x0017, 0x0003 }, + { 0x0017, 0x0004 }, + { 0x0005, 0x0002 }, + { 0x0005, 0x0003 }, + { 0x0007, 0x0001 }, + { 0x000c, 0x0001 }, + { 0x0010, 0x0002 }, + { 0x0013, 0x0005 }, + { 0x0017, 0x0005 }, + { 0x0017, 0x0006 }, + { 0x0017, 0x0007 }, + { 0x0009, 0x0002 }, + { 0x0009, 0x0003 }, + { 0x000b, 0x0001 }, + { 0x000f, 0x0004 }, + { 0x0012, 0x0005 }, + { 0x0016, 0x0015 }, + { 0x0017, 0x0008 }, + { 0x0017, 0x0009 }, + { 0x0017, 0x000a }, + { 0x000f, 0x0005 }, + { 0x000e, 0x0003 }, + { 0x0010, 0x0003 }, + { 0x0012, 0x0006 }, + { 0x0014, 0x0009 }, + { 0x0017, 0x000b }, + { 0x0017, 0x000c }, + { 0x0017, 0x000d }, + { 0x0017, 0x000e }, + { 0x0013, 0x0006 }, + { 0x0012, 0x0007 }, + { 0x0013, 0x0007 }, + { 0x0015, 0x000e }, + { 0x0017, 0x000f }, + { 0x0017, 0x0010 }, + { 0x0017, 0x0011 }, + { 0x0017, 0x0012 }, + { 0x0017, 0x0013 }, + { 0x0016, 0x0016 }, + { 0x0016, 0x0017 }, + { 0x0015, 0x000f }, + { 0x0016, 0x0018 }, + { 0x0017, 0x0014 }, + { 0x0017, 0x0015 }, + { 0x0017, 0x0016 }, + { 0x0017, 0x0017 }, + { 0x0017, 0x0018 }, + { 0x0017, 0x0019 }, + { 0x0017, 0x001a }, + { 0x0017, 0x001b }, + { 0x0017, 0x001c }, + { 0x0017, 0x001d }, + { 0x0017, 0x001e }, + { 0x0017, 0x001f }, + { 0x0017, 0x0020 }, + { 0x0017, 0x0021 }, + { 0x0017, 0x0022 }, + { 0x0017, 0x0023 }, + { 0x0017, 0x0024 }, + { 0x0017, 0x0025 }, + { 0x0017, 0x0026 }, + { 0x0017, 0x0027 }, + { 0x0017, 0x0028 }, + { 0x0017, 0x0029 }, + { 0x0016, 0x0019 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc9[100][2] = + { + { 0x0001, 0x0001 }, + { 0x0003, 0x0001 }, + { 0x0006, 0x0001 }, + { 0x0009, 0x0001 }, + { 0x000d, 0x0002 }, + { 0x0011, 0x0004 }, + { 0x0014, 0x000a }, + { 0x0017, 0x0000 }, + { 0x0017, 0x0001 }, + { 0x0017, 0x0002 }, + { 0x0003, 0x0002 }, + { 0x0003, 0x0003 }, + { 0x0005, 0x0001 }, + { 0x0009, 0x0002 }, + { 0x000d, 0x0003 }, + { 0x0010, 0x0004 }, + { 0x0013, 0x0007 }, + { 0x0016, 0x0018 }, + { 0x0017, 0x0003 }, + { 0x0017, 0x0004 }, + { 0x0005, 0x0002 }, + { 0x0005, 0x0003 }, + { 0x0008, 0x0002 }, + { 0x000b, 0x0002 }, + { 0x000e, 0x0002 }, + { 0x0011, 0x0005 }, + { 0x0014, 0x000b }, + { 0x0016, 0x0019 }, + { 0x0017, 0x0005 }, + { 0x0017, 0x0006 }, + { 0x0009, 0x0003 }, + { 0x0008, 0x0003 }, + { 0x000b, 0x0003 }, + { 0x000d, 0x0004 }, + { 0x0010, 0x0005 }, + { 0x0012, 0x0006 }, + { 0x0015, 0x000f }, + { 0x0017, 0x0007 }, + { 0x0017, 0x0008 }, + { 0x0017, 0x0009 }, + { 0x000d, 0x0005 }, + { 0x000c, 0x0003 }, + { 0x000e, 0x0003 }, + { 0x0010, 0x0006 }, + { 0x0012, 0x0007 }, + { 0x0014, 0x000c }, + { 0x0017, 0x000a }, + { 0x0016, 0x001a }, + { 0x0017, 0x000b }, + { 0x0017, 0x000c }, + { 0x0011, 0x0006 }, + { 0x0010, 0x0007 }, + { 0x0011, 0x0007 }, + { 0x0013, 0x0008 }, + { 0x0013, 0x0009 }, + { 0x0015, 0x0010 }, + { 0x0017, 0x000d }, + { 0x0017, 0x000e }, + { 0x0017, 0x000f }, + { 0x0017, 0x0010 }, + { 0x0013, 0x000a }, + { 0x0013, 0x000b }, + { 0x0014, 0x000d }, + { 0x0015, 0x0011 }, + { 0x0017, 0x0011 }, + { 0x0016, 0x001b }, + { 0x0017, 0x0012 }, + { 0x0017, 0x0013 }, + { 0x0017, 0x0014 }, + { 0x0017, 0x0015 }, + { 0x0017, 0x0016 }, + { 0x0015, 0x0012 }, + { 0x0015, 0x0013 }, + { 0x0017, 0x0017 }, + { 0x0016, 0x001c }, + { 0x0017, 0x0018 }, + { 0x0017, 0x0019 }, + { 0x0017, 0x001a }, + { 0x0017, 0x001b }, + { 0x0017, 0x001c }, + { 0x0017, 0x001d }, + { 0x0017, 0x001e }, + { 0x0017, 0x001f }, + { 0x0017, 0x0020 }, + { 0x0017, 0x0021 }, + { 0x0017, 0x0022 }, + { 0x0017, 0x0023 }, + { 0x0017, 0x0024 }, + { 0x0017, 0x0025 }, + { 0x0017, 0x0026 }, + { 0x0017, 0x0027 }, + { 0x0017, 0x0028 }, + { 0x0017, 0x0029 }, + { 0x0017, 0x002a }, + { 0x0017, 0x002b }, + { 0x0017, 0x002c }, + { 0x0017, 0x002d }, + { 0x0017, 0x002e }, + { 0x0017, 0x002f }, + { 0x0016, 0x001d }, + + }; + +const uint16_t c_aauiLCLDHuffEnc10[169][2] = + { + { 0x0001, 0x0001 }, + { 0x0004, 0x0002 }, + { 0x0005, 0x0002 }, + { 0x0007, 0x0002 }, + { 0x000a, 0x0002 }, + { 0x000e, 0x0004 }, + { 0x0011, 0x0007 }, + { 0x0013, 0x0012 }, + { 0x0016, 0x0000 }, + { 0x0016, 0x0001 }, + { 0x0016, 0x0002 }, + { 0x0016, 0x0003 }, + { 0x0016, 0x0004 }, + { 0x0004, 0x0003 }, + { 0x0003, 0x0003 }, + { 0x0004, 0x0004 }, + { 0x0007, 0x0003 }, + { 0x000a, 0x0003 }, + { 0x000d, 0x0004 }, + { 0x0010, 0x0007 }, + { 0x0013, 0x0013 }, + { 0x0015, 0x0035 }, + { 0x0016, 0x0005 }, + { 0x0016, 0x0006 }, + { 0x0016, 0x0007 }, + { 0x0016, 0x0008 }, + { 0x0005, 0x0003 }, + { 0x0004, 0x0005 }, + { 0x0006, 0x0003 }, + { 0x0008, 0x0002 }, + { 0x000b, 0x0002 }, + { 0x000e, 0x0005 }, + { 0x0010, 0x0008 }, + { 0x0013, 0x0014 }, + { 0x0014, 0x001d }, + { 0x0016, 0x0009 }, + { 0x0016, 0x000a }, + { 0x0016, 0x000b }, + { 0x0016, 0x000c }, + { 0x0007, 0x0004 }, + { 0x0007, 0x0005 }, + { 0x0008, 0x0003 }, + { 0x000a, 0x0004 }, + { 0x000d, 0x0005 }, + { 0x000f, 0x0005 }, + { 0x0011, 0x0008 }, + { 0x0014, 0x001e }, + { 0x0014, 0x001f }, + { 0x0016, 0x000d }, + { 0x0016, 0x000e }, + { 0x0016, 0x000f }, + { 0x0016, 0x0010 }, + { 0x000a, 0x0005 }, + { 0x0009, 0x0003 }, + { 0x000b, 0x0003 }, + { 0x000d, 0x0006 }, + { 0x000f, 0x0006 }, + { 0x0011, 0x0009 }, + { 0x0013, 0x0015 }, + { 0x0014, 0x0020 }, + { 0x0016, 0x0011 }, + { 0x0016, 0x0012 }, + { 0x0016, 0x0013 }, + { 0x0016, 0x0014 }, + { 0x0016, 0x0015 }, + { 0x000e, 0x0006 }, + { 0x000d, 0x0007 }, + { 0x000e, 0x0007 }, + { 0x000f, 0x0007 }, + { 0x0011, 0x000a }, + { 0x0012, 0x000c }, + { 0x0016, 0x0016 }, + { 0x0016, 0x0017 }, + { 0x0016, 0x0018 }, + { 0x0016, 0x0019 }, + { 0x0016, 0x001a }, + { 0x0016, 0x001b }, + { 0x0016, 0x001c }, + { 0x0011, 0x000b }, + { 0x0010, 0x0009 }, + { 0x0011, 0x000c }, + { 0x0011, 0x000d }, + { 0x0013, 0x0016 }, + { 0x0016, 0x001d }, + { 0x0016, 0x001e }, + { 0x0016, 0x001f }, + { 0x0016, 0x0020 }, + { 0x0016, 0x0021 }, + { 0x0016, 0x0022 }, + { 0x0016, 0x0023 }, + { 0x0016, 0x0024 }, + { 0x0014, 0x0021 }, + { 0x0014, 0x0022 }, + { 0x0012, 0x000d }, + { 0x0013, 0x0017 }, + { 0x0016, 0x0025 }, + { 0x0016, 0x0026 }, + { 0x0016, 0x0027 }, + { 0x0016, 0x0028 }, + { 0x0016, 0x0029 }, + { 0x0016, 0x002a }, + { 0x0016, 0x002b }, + { 0x0016, 0x002c }, + { 0x0016, 0x002d }, + { 0x0015, 0x0036 }, + { 0x0015, 0x0037 }, + { 0x0014, 0x0023 }, + { 0x0015, 0x0038 }, + { 0x0016, 0x002e }, + { 0x0016, 0x002f }, + { 0x0016, 0x0030 }, + { 0x0016, 0x0031 }, + { 0x0016, 0x0032 }, + { 0x0016, 0x0033 }, + { 0x0016, 0x0034 }, + { 0x0016, 0x0035 }, + { 0x0016, 0x0036 }, + { 0x0016, 0x0037 }, + { 0x0016, 0x0038 }, + { 0x0016, 0x0039 }, + { 0x0016, 0x003a }, + { 0x0016, 0x003b }, + { 0x0016, 0x003c }, + { 0x0016, 0x003d }, + { 0x0016, 0x003e }, + { 0x0016, 0x003f }, + { 0x0016, 0x0040 }, + { 0x0016, 0x0041 }, + { 0x0016, 0x0042 }, + { 0x0016, 0x0043 }, + { 0x0016, 0x0044 }, + { 0x0016, 0x0045 }, + { 0x0016, 0x0046 }, + { 0x0016, 0x0047 }, + { 0x0016, 0x0048 }, + { 0x0016, 0x0049 }, + { 0x0016, 0x004a }, + { 0x0016, 0x004b }, + { 0x0016, 0x004c }, + { 0x0016, 0x004d }, + { 0x0016, 0x004e }, + { 0x0016, 0x004f }, + { 0x0016, 0x0050 }, + { 0x0016, 0x0051 }, + { 0x0016, 0x0052 }, + { 0x0016, 0x0053 }, + { 0x0016, 0x0054 }, + { 0x0016, 0x0055 }, + { 0x0016, 0x0056 }, + { 0x0016, 0x0057 }, + { 0x0016, 0x0058 }, + { 0x0016, 0x0059 }, + { 0x0016, 0x005a }, + { 0x0016, 0x005b }, + { 0x0016, 0x005c }, + { 0x0016, 0x005d }, + { 0x0016, 0x005e }, + { 0x0016, 0x005f }, + { 0x0016, 0x0060 }, + { 0x0016, 0x0061 }, + { 0x0016, 0x0062 }, + { 0x0016, 0x0063 }, + { 0x0016, 0x0064 }, + { 0x0016, 0x0065 }, + { 0x0016, 0x0066 }, + { 0x0016, 0x0067 }, + { 0x0016, 0x0068 }, + { 0x0016, 0x0069 }, + { 0x0015, 0x0039 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc11[196][2] = + { + { 0x0001, 0x0001 }, + { 0x0004, 0x0003 }, + { 0x0005, 0x0003 }, + { 0x0007, 0x0002 }, + { 0x0009, 0x0003 }, + { 0x000c, 0x0004 }, + { 0x000f, 0x0005 }, + { 0x0012, 0x000d }, + { 0x0014, 0x001f }, + { 0x0016, 0x0000 }, + { 0x0016, 0x0001 }, + { 0x0016, 0x0002 }, + { 0x0016, 0x0003 }, + { 0x0016, 0x0004 }, + { 0x0004, 0x0004 }, + { 0x0003, 0x0003 }, + { 0x0005, 0x0004 }, + { 0x0006, 0x0003 }, + { 0x0009, 0x0004 }, + { 0x000b, 0x0004 }, + { 0x000e, 0x0005 }, + { 0x0010, 0x0007 }, + { 0x0012, 0x000e }, + { 0x0014, 0x0020 }, + { 0x0016, 0x0005 }, + { 0x0016, 0x0006 }, + { 0x0016, 0x0007 }, + { 0x0016, 0x0008 }, + { 0x0005, 0x0005 }, + { 0x0004, 0x0005 }, + { 0x0006, 0x0004 }, + { 0x0007, 0x0003 }, + { 0x000a, 0x0004 }, + { 0x000c, 0x0005 }, + { 0x000e, 0x0006 }, + { 0x0011, 0x000a }, + { 0x0012, 0x000f }, + { 0x0015, 0x003b }, + { 0x0016, 0x0009 }, + { 0x0016, 0x000a }, + { 0x0016, 0x000b }, + { 0x0016, 0x000c }, + { 0x0007, 0x0004 }, + { 0x0006, 0x0005 }, + { 0x0007, 0x0005 }, + { 0x0009, 0x0005 }, + { 0x000b, 0x0005 }, + { 0x000d, 0x0005 }, + { 0x000f, 0x0006 }, + { 0x0012, 0x0010 }, + { 0x0014, 0x0021 }, + { 0x0016, 0x000d }, + { 0x0016, 0x000e }, + { 0x0016, 0x000f }, + { 0x0016, 0x0010 }, + { 0x0016, 0x0011 }, + { 0x0009, 0x0006 }, + { 0x0009, 0x0007 }, + { 0x000a, 0x0005 }, + { 0x000b, 0x0006 }, + { 0x000d, 0x0006 }, + { 0x000f, 0x0007 }, + { 0x0011, 0x000b }, + { 0x0013, 0x0017 }, + { 0x0014, 0x0022 }, + { 0x0016, 0x0012 }, + { 0x0016, 0x0013 }, + { 0x0016, 0x0014 }, + { 0x0016, 0x0015 }, + { 0x0016, 0x0016 }, + { 0x000c, 0x0006 }, + { 0x000b, 0x0007 }, + { 0x000c, 0x0007 }, + { 0x000d, 0x0007 }, + { 0x000e, 0x0007 }, + { 0x0010, 0x0008 }, + { 0x0012, 0x0011 }, + { 0x0014, 0x0023 }, + { 0x0015, 0x003c }, + { 0x0016, 0x0017 }, + { 0x0016, 0x0018 }, + { 0x0016, 0x0019 }, + { 0x0016, 0x001a }, + { 0x0016, 0x001b }, + { 0x000f, 0x0008 }, + { 0x000e, 0x0008 }, + { 0x000e, 0x0009 }, + { 0x000f, 0x0009 }, + { 0x0011, 0x000c }, + { 0x0013, 0x0018 }, + { 0x0014, 0x0024 }, + { 0x0016, 0x001c }, + { 0x0016, 0x001d }, + { 0x0016, 0x001e }, + { 0x0016, 0x001f }, + { 0x0016, 0x0020 }, + { 0x0016, 0x0021 }, + { 0x0016, 0x0022 }, + { 0x0011, 0x000d }, + { 0x0010, 0x0009 }, + { 0x0012, 0x0012 }, + { 0x0012, 0x0013 }, + { 0x0014, 0x0025 }, + { 0x0015, 0x003d }, + { 0x0014, 0x0026 }, + { 0x0016, 0x0023 }, + { 0x0016, 0x0024 }, + { 0x0016, 0x0025 }, + { 0x0016, 0x0026 }, + { 0x0016, 0x0027 }, + { 0x0016, 0x0028 }, + { 0x0016, 0x0029 }, + { 0x0014, 0x0027 }, + { 0x0013, 0x0019 }, + { 0x0014, 0x0028 }, + { 0x0014, 0x0029 }, + { 0x0014, 0x002a }, + { 0x0016, 0x002a }, + { 0x0016, 0x002b }, + { 0x0016, 0x002c }, + { 0x0016, 0x002d }, + { 0x0016, 0x002e }, + { 0x0016, 0x002f }, + { 0x0016, 0x0030 }, + { 0x0016, 0x0031 }, + { 0x0016, 0x0032 }, + { 0x0014, 0x002b }, + { 0x0014, 0x002c }, + { 0x0014, 0x002d }, + { 0x0016, 0x0033 }, + { 0x0016, 0x0034 }, + { 0x0016, 0x0035 }, + { 0x0016, 0x0036 }, + { 0x0016, 0x0037 }, + { 0x0016, 0x0038 }, + { 0x0016, 0x0039 }, + { 0x0016, 0x003a }, + { 0x0016, 0x003b }, + { 0x0016, 0x003c }, + { 0x0016, 0x003d }, + { 0x0016, 0x003e }, + { 0x0016, 0x003f }, + { 0x0016, 0x0040 }, + { 0x0016, 0x0041 }, + { 0x0016, 0x0042 }, + { 0x0016, 0x0043 }, + { 0x0016, 0x0044 }, + { 0x0016, 0x0045 }, + { 0x0016, 0x0046 }, + { 0x0016, 0x0047 }, + { 0x0016, 0x0048 }, + { 0x0016, 0x0049 }, + { 0x0016, 0x004a }, + { 0x0016, 0x004b }, + { 0x0016, 0x004c }, + { 0x0016, 0x004d }, + { 0x0016, 0x004e }, + { 0x0016, 0x004f }, + { 0x0016, 0x0050 }, + { 0x0016, 0x0051 }, + { 0x0016, 0x0052 }, + { 0x0016, 0x0053 }, + { 0x0016, 0x0054 }, + { 0x0016, 0x0055 }, + { 0x0016, 0x0056 }, + { 0x0016, 0x0057 }, + { 0x0016, 0x0058 }, + { 0x0016, 0x0059 }, + { 0x0016, 0x005a }, + { 0x0016, 0x005b }, + { 0x0016, 0x005c }, + { 0x0016, 0x005d }, + { 0x0016, 0x005e }, + { 0x0016, 0x005f }, + { 0x0016, 0x0060 }, + { 0x0016, 0x0061 }, + { 0x0016, 0x0062 }, + { 0x0016, 0x0063 }, + { 0x0016, 0x0064 }, + { 0x0016, 0x0065 }, + { 0x0016, 0x0066 }, + { 0x0016, 0x0067 }, + { 0x0016, 0x0068 }, + { 0x0016, 0x0069 }, + { 0x0016, 0x006a }, + { 0x0016, 0x006b }, + { 0x0016, 0x006c }, + { 0x0016, 0x006d }, + { 0x0016, 0x006e }, + { 0x0016, 0x006f }, + { 0x0016, 0x0070 }, + { 0x0016, 0x0071 }, + { 0x0016, 0x0072 }, + { 0x0016, 0x0073 }, + { 0x0016, 0x0074 }, + { 0x0016, 0x0075 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc12[289][2] = + { + { 0x0001, 0x0001 }, + { 0x0004, 0x0004 }, + { 0x0005, 0x0004 }, + { 0x0007, 0x0004 }, + { 0x0008, 0x0002 }, + { 0x000b, 0x0004 }, + { 0x000e, 0x0006 }, + { 0x0010, 0x0009 }, + { 0x0012, 0x0014 }, + { 0x0013, 0x001f }, + { 0x0016, 0x0000 }, + { 0x0016, 0x0001 }, + { 0x0016, 0x0002 }, + { 0x0016, 0x0003 }, + { 0x0016, 0x0004 }, + { 0x0016, 0x0005 }, + { 0x0016, 0x0006 }, + { 0x0004, 0x0005 }, + { 0x0004, 0x0006 }, + { 0x0005, 0x0005 }, + { 0x0006, 0x0003 }, + { 0x0008, 0x0003 }, + { 0x000a, 0x0004 }, + { 0x000d, 0x0006 }, + { 0x000f, 0x0008 }, + { 0x0011, 0x000c }, + { 0x0013, 0x0020 }, + { 0x0016, 0x0007 }, + { 0x0015, 0x0063 }, + { 0x0016, 0x0008 }, + { 0x0016, 0x0009 }, + { 0x0016, 0x000a }, + { 0x0016, 0x000b }, + { 0x0016, 0x000c }, + { 0x0005, 0x0006 }, + { 0x0004, 0x0007 }, + { 0x0005, 0x0007 }, + { 0x0006, 0x0004 }, + { 0x0008, 0x0004 }, + { 0x000b, 0x0005 }, + { 0x000d, 0x0007 }, + { 0x0010, 0x000a }, + { 0x0012, 0x0015 }, + { 0x0015, 0x0064 }, + { 0x0016, 0x000d }, + { 0x0016, 0x000e }, + { 0x0016, 0x000f }, + { 0x0016, 0x0010 }, + { 0x0016, 0x0011 }, + { 0x0016, 0x0012 }, + { 0x0016, 0x0013 }, + { 0x0006, 0x0005 }, + { 0x0006, 0x0006 }, + { 0x0006, 0x0007 }, + { 0x0008, 0x0005 }, + { 0x000a, 0x0005 }, + { 0x000c, 0x0005 }, + { 0x000e, 0x0007 }, + { 0x0010, 0x000b }, + { 0x0012, 0x0016 }, + { 0x0014, 0x0037 }, + { 0x0015, 0x0065 }, + { 0x0016, 0x0014 }, + { 0x0016, 0x0015 }, + { 0x0016, 0x0016 }, + { 0x0016, 0x0017 }, + { 0x0016, 0x0018 }, + { 0x0016, 0x0019 }, + { 0x0008, 0x0006 }, + { 0x0007, 0x0005 }, + { 0x0008, 0x0007 }, + { 0x000a, 0x0006 }, + { 0x000c, 0x0006 }, + { 0x000e, 0x0008 }, + { 0x0010, 0x000c }, + { 0x0011, 0x000d }, + { 0x0013, 0x0021 }, + { 0x0015, 0x0066 }, + { 0x0016, 0x001a }, + { 0x0016, 0x001b }, + { 0x0016, 0x001c }, + { 0x0016, 0x001d }, + { 0x0016, 0x001e }, + { 0x0016, 0x001f }, + { 0x0016, 0x0020 }, + { 0x000b, 0x0006 }, + { 0x000a, 0x0007 }, + { 0x000b, 0x0007 }, + { 0x000c, 0x0007 }, + { 0x000e, 0x0009 }, + { 0x000f, 0x0009 }, + { 0x0011, 0x000e }, + { 0x0013, 0x0022 }, + { 0x0015, 0x0067 }, + { 0x0015, 0x0068 }, + { 0x0016, 0x0021 }, + { 0x0016, 0x0022 }, + { 0x0016, 0x0023 }, + { 0x0016, 0x0024 }, + { 0x0016, 0x0025 }, + { 0x0016, 0x0026 }, + { 0x0016, 0x0027 }, + { 0x000e, 0x000a }, + { 0x000d, 0x0008 }, + { 0x000d, 0x0009 }, + { 0x000e, 0x000b }, + { 0x000f, 0x000a }, + { 0x0011, 0x000f }, + { 0x0013, 0x0023 }, + { 0x0014, 0x0038 }, + { 0x0016, 0x0028 }, + { 0x0016, 0x0029 }, + { 0x0016, 0x002a }, + { 0x0016, 0x002b }, + { 0x0016, 0x002c }, + { 0x0016, 0x002d }, + { 0x0016, 0x002e }, + { 0x0016, 0x002f }, + { 0x0016, 0x0030 }, + { 0x0010, 0x000d }, + { 0x000f, 0x000b }, + { 0x0010, 0x000e }, + { 0x0010, 0x000f }, + { 0x0012, 0x0017 }, + { 0x0013, 0x0024 }, + { 0x0014, 0x0039 }, + { 0x0016, 0x0031 }, + { 0x0016, 0x0032 }, + { 0x0016, 0x0033 }, + { 0x0016, 0x0034 }, + { 0x0016, 0x0035 }, + { 0x0016, 0x0036 }, + { 0x0016, 0x0037 }, + { 0x0016, 0x0038 }, + { 0x0016, 0x0039 }, + { 0x0016, 0x003a }, + { 0x0013, 0x0025 }, + { 0x0011, 0x0010 }, + { 0x0011, 0x0011 }, + { 0x0013, 0x0026 }, + { 0x0013, 0x0027 }, + { 0x0014, 0x003a }, + { 0x0014, 0x003b }, + { 0x0016, 0x003b }, + { 0x0016, 0x003c }, + { 0x0016, 0x003d }, + { 0x0016, 0x003e }, + { 0x0016, 0x003f }, + { 0x0016, 0x0040 }, + { 0x0016, 0x0041 }, + { 0x0016, 0x0042 }, + { 0x0016, 0x0043 }, + { 0x0016, 0x0044 }, + { 0x0015, 0x0069 }, + { 0x0014, 0x003c }, + { 0x0014, 0x003d }, + { 0x0015, 0x006a }, + { 0x0015, 0x006b }, + { 0x0015, 0x006c }, + { 0x0016, 0x0045 }, + { 0x0016, 0x0046 }, + { 0x0016, 0x0047 }, + { 0x0016, 0x0048 }, + { 0x0016, 0x0049 }, + { 0x0016, 0x004a }, + { 0x0016, 0x004b }, + { 0x0016, 0x004c }, + { 0x0016, 0x004d }, + { 0x0016, 0x004e }, + { 0x0016, 0x004f }, + { 0x0016, 0x0050 }, + { 0x0016, 0x0051 }, + { 0x0015, 0x006d }, + { 0x0016, 0x0052 }, + { 0x0016, 0x0053 }, + { 0x0016, 0x0054 }, + { 0x0016, 0x0055 }, + { 0x0016, 0x0056 }, + { 0x0016, 0x0057 }, + { 0x0016, 0x0058 }, + { 0x0016, 0x0059 }, + { 0x0016, 0x005a }, + { 0x0016, 0x005b }, + { 0x0016, 0x005c }, + { 0x0016, 0x005d }, + { 0x0016, 0x005e }, + { 0x0016, 0x005f }, + { 0x0016, 0x0060 }, + { 0x0016, 0x0061 }, + { 0x0016, 0x0062 }, + { 0x0016, 0x0063 }, + { 0x0016, 0x0064 }, + { 0x0016, 0x0065 }, + { 0x0016, 0x0066 }, + { 0x0016, 0x0067 }, + { 0x0016, 0x0068 }, + { 0x0016, 0x0069 }, + { 0x0016, 0x006a }, + { 0x0016, 0x006b }, + { 0x0016, 0x006c }, + { 0x0016, 0x006d }, + { 0x0016, 0x006e }, + { 0x0016, 0x006f }, + { 0x0016, 0x0070 }, + { 0x0016, 0x0071 }, + { 0x0016, 0x0072 }, + { 0x0016, 0x0073 }, + { 0x0016, 0x0074 }, + { 0x0016, 0x0075 }, + { 0x0016, 0x0076 }, + { 0x0016, 0x0077 }, + { 0x0016, 0x0078 }, + { 0x0016, 0x0079 }, + { 0x0016, 0x007a }, + { 0x0016, 0x007b }, + { 0x0016, 0x007c }, + { 0x0016, 0x007d }, + { 0x0016, 0x007e }, + { 0x0016, 0x007f }, + { 0x0016, 0x0080 }, + { 0x0016, 0x0081 }, + { 0x0016, 0x0082 }, + { 0x0016, 0x0083 }, + { 0x0016, 0x0084 }, + { 0x0016, 0x0085 }, + { 0x0016, 0x0086 }, + { 0x0016, 0x0087 }, + { 0x0016, 0x0088 }, + { 0x0016, 0x0089 }, + { 0x0016, 0x008a }, + { 0x0016, 0x008b }, + { 0x0016, 0x008c }, + { 0x0016, 0x008d }, + { 0x0016, 0x008e }, + { 0x0016, 0x008f }, + { 0x0016, 0x0090 }, + { 0x0016, 0x0091 }, + { 0x0016, 0x0092 }, + { 0x0016, 0x0093 }, + { 0x0016, 0x0094 }, + { 0x0016, 0x0095 }, + { 0x0016, 0x0096 }, + { 0x0016, 0x0097 }, + { 0x0016, 0x0098 }, + { 0x0016, 0x0099 }, + { 0x0016, 0x009a }, + { 0x0016, 0x009b }, + { 0x0016, 0x009c }, + { 0x0016, 0x009d }, + { 0x0016, 0x009e }, + { 0x0016, 0x009f }, + { 0x0016, 0x00a0 }, + { 0x0016, 0x00a1 }, + { 0x0016, 0x00a2 }, + { 0x0016, 0x00a3 }, + { 0x0016, 0x00a4 }, + { 0x0016, 0x00a5 }, + { 0x0016, 0x00a6 }, + { 0x0016, 0x00a7 }, + { 0x0016, 0x00a8 }, + { 0x0016, 0x00a9 }, + { 0x0016, 0x00aa }, + { 0x0016, 0x00ab }, + { 0x0016, 0x00ac }, + { 0x0016, 0x00ad }, + { 0x0016, 0x00ae }, + { 0x0016, 0x00af }, + { 0x0016, 0x00b0 }, + { 0x0016, 0x00b1 }, + { 0x0016, 0x00b2 }, + { 0x0016, 0x00b3 }, + { 0x0016, 0x00b4 }, + { 0x0016, 0x00b5 }, + { 0x0016, 0x00b6 }, + { 0x0016, 0x00b7 }, + { 0x0016, 0x00b8 }, + { 0x0016, 0x00b9 }, + { 0x0016, 0x00ba }, + { 0x0016, 0x00bb }, + { 0x0016, 0x00bc }, + { 0x0016, 0x00bd }, + { 0x0016, 0x00be }, + { 0x0016, 0x00bf }, + { 0x0016, 0x00c0 }, + { 0x0016, 0x00c1 }, + { 0x0016, 0x00c2 }, + { 0x0016, 0x00c3 }, + { 0x0016, 0x00c4 }, + { 0x0016, 0x00c5 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc13[324][2] = + { + { 0x0004, 0x0006 }, + { 0x0004, 0x0007 }, + { 0x0005, 0x0005 }, + { 0x0005, 0x0006 }, + { 0x0006, 0x0004 }, + { 0x0008, 0x0005 }, + { 0x000a, 0x0005 }, + { 0x000c, 0x0007 }, + { 0x000e, 0x000b }, + { 0x0010, 0x0011 }, + { 0x0012, 0x002d }, + { 0x0015, 0x0000 }, + { 0x0014, 0x0035 }, + { 0x0015, 0x0001 }, + { 0x0015, 0x0002 }, + { 0x0015, 0x0003 }, + { 0x0015, 0x0004 }, + { 0x0015, 0x0005 }, + { 0x0004, 0x0008 }, + { 0x0003, 0x0007 }, + { 0x0004, 0x0009 }, + { 0x0004, 0x000a }, + { 0x0006, 0x0005 }, + { 0x0008, 0x0006 }, + { 0x0009, 0x0006 }, + { 0x000c, 0x0008 }, + { 0x000d, 0x0009 }, + { 0x0010, 0x0012 }, + { 0x0011, 0x001a }, + { 0x0015, 0x0006 }, + { 0x0015, 0x0007 }, + { 0x0015, 0x0008 }, + { 0x0015, 0x0009 }, + { 0x0015, 0x000a }, + { 0x0015, 0x000b }, + { 0x0015, 0x000c }, + { 0x0005, 0x0007 }, + { 0x0004, 0x000b }, + { 0x0004, 0x000c }, + { 0x0005, 0x0008 }, + { 0x0006, 0x0006 }, + { 0x0008, 0x0007 }, + { 0x000a, 0x0006 }, + { 0x000c, 0x0009 }, + { 0x000e, 0x000c }, + { 0x0010, 0x0013 }, + { 0x0012, 0x002e }, + { 0x0015, 0x000d }, + { 0x0015, 0x000e }, + { 0x0015, 0x000f }, + { 0x0015, 0x0010 }, + { 0x0015, 0x0011 }, + { 0x0015, 0x0012 }, + { 0x0015, 0x0013 }, + { 0x0005, 0x0009 }, + { 0x0004, 0x000d }, + { 0x0005, 0x000a }, + { 0x0006, 0x0007 }, + { 0x0007, 0x0005 }, + { 0x0009, 0x0007 }, + { 0x000b, 0x0008 }, + { 0x000d, 0x000a }, + { 0x000f, 0x000e }, + { 0x0010, 0x0014 }, + { 0x0011, 0x001b }, + { 0x0014, 0x0036 }, + { 0x0015, 0x0014 }, + { 0x0015, 0x0015 }, + { 0x0015, 0x0016 }, + { 0x0015, 0x0017 }, + { 0x0015, 0x0018 }, + { 0x0015, 0x0019 }, + { 0x0006, 0x0008 }, + { 0x0005, 0x000b }, + { 0x0006, 0x0009 }, + { 0x0007, 0x0006 }, + { 0x0009, 0x0008 }, + { 0x000a, 0x0007 }, + { 0x000c, 0x000a }, + { 0x000e, 0x000d }, + { 0x0010, 0x0015 }, + { 0x0011, 0x001c }, + { 0x0013, 0x0053 }, + { 0x0015, 0x001a }, + { 0x0015, 0x001b }, + { 0x0015, 0x001c }, + { 0x0015, 0x001d }, + { 0x0015, 0x001e }, + { 0x0015, 0x001f }, + { 0x0015, 0x0020 }, + { 0x0008, 0x0008 }, + { 0x0007, 0x0007 }, + { 0x0008, 0x0009 }, + { 0x0009, 0x0009 }, + { 0x000a, 0x0008 }, + { 0x000c, 0x000b }, + { 0x000d, 0x000b }, + { 0x000f, 0x000f }, + { 0x0010, 0x0016 }, + { 0x0011, 0x001d }, + { 0x0014, 0x0037 }, + { 0x0015, 0x0021 }, + { 0x0015, 0x0022 }, + { 0x0015, 0x0023 }, + { 0x0015, 0x0024 }, + { 0x0015, 0x0025 }, + { 0x0015, 0x0026 }, + { 0x0015, 0x0027 }, + { 0x000a, 0x0009 }, + { 0x000a, 0x000a }, + { 0x000a, 0x000b }, + { 0x000b, 0x0009 }, + { 0x000c, 0x000c }, + { 0x000d, 0x000c }, + { 0x000f, 0x0010 }, + { 0x0010, 0x0017 }, + { 0x0012, 0x002f }, + { 0x0015, 0x0028 }, + { 0x0015, 0x0029 }, + { 0x0015, 0x002a }, + { 0x0015, 0x002b }, + { 0x0015, 0x002c }, + { 0x0015, 0x002d }, + { 0x0015, 0x002e }, + { 0x0015, 0x002f }, + { 0x0015, 0x0030 }, + { 0x000c, 0x000d }, + { 0x000c, 0x000e }, + { 0x000c, 0x000f }, + { 0x000d, 0x000d }, + { 0x000e, 0x000e }, + { 0x000f, 0x0011 }, + { 0x0010, 0x0018 }, + { 0x0011, 0x001e }, + { 0x0014, 0x0038 }, + { 0x0015, 0x0031 }, + { 0x0015, 0x0032 }, + { 0x0015, 0x0033 }, + { 0x0015, 0x0034 }, + { 0x0015, 0x0035 }, + { 0x0015, 0x0036 }, + { 0x0015, 0x0037 }, + { 0x0015, 0x0038 }, + { 0x0015, 0x0039 }, + { 0x000f, 0x0012 }, + { 0x000e, 0x000f }, + { 0x000e, 0x0010 }, + { 0x000e, 0x0011 }, + { 0x000f, 0x0013 }, + { 0x0010, 0x0019 }, + { 0x0011, 0x001f }, + { 0x0013, 0x0054 }, + { 0x0015, 0x003a }, + { 0x0014, 0x0039 }, + { 0x0015, 0x003b }, + { 0x0015, 0x003c }, + { 0x0015, 0x003d }, + { 0x0015, 0x003e }, + { 0x0015, 0x003f }, + { 0x0015, 0x0040 }, + { 0x0015, 0x0041 }, + { 0x0015, 0x0042 }, + { 0x0010, 0x001a }, + { 0x000f, 0x0014 }, + { 0x000f, 0x0015 }, + { 0x0010, 0x001b }, + { 0x0011, 0x0020 }, + { 0x0012, 0x0030 }, + { 0x0013, 0x0055 }, + { 0x0015, 0x0043 }, + { 0x0015, 0x0044 }, + { 0x0014, 0x003a }, + { 0x0015, 0x0045 }, + { 0x0015, 0x0046 }, + { 0x0015, 0x0047 }, + { 0x0015, 0x0048 }, + { 0x0015, 0x0049 }, + { 0x0015, 0x004a }, + { 0x0015, 0x004b }, + { 0x0015, 0x004c }, + { 0x0012, 0x0031 }, + { 0x0011, 0x0021 }, + { 0x0013, 0x0056 }, + { 0x0013, 0x0057 }, + { 0x0012, 0x0032 }, + { 0x0015, 0x004d }, + { 0x0015, 0x004e }, + { 0x0015, 0x004f }, + { 0x0015, 0x0050 }, + { 0x0015, 0x0051 }, + { 0x0015, 0x0052 }, + { 0x0015, 0x0053 }, + { 0x0015, 0x0054 }, + { 0x0015, 0x0055 }, + { 0x0015, 0x0056 }, + { 0x0015, 0x0057 }, + { 0x0015, 0x0058 }, + { 0x0015, 0x0059 }, + { 0x0015, 0x005a }, + { 0x0014, 0x003b }, + { 0x0012, 0x0033 }, + { 0x0013, 0x0058 }, + { 0x0013, 0x0059 }, + { 0x0015, 0x005b }, + { 0x0015, 0x005c }, + { 0x0015, 0x005d }, + { 0x0015, 0x005e }, + { 0x0015, 0x005f }, + { 0x0015, 0x0060 }, + { 0x0015, 0x0061 }, + { 0x0015, 0x0062 }, + { 0x0015, 0x0063 }, + { 0x0015, 0x0064 }, + { 0x0015, 0x0065 }, + { 0x0015, 0x0066 }, + { 0x0015, 0x0067 }, + { 0x0015, 0x0068 }, + { 0x0015, 0x0069 }, + { 0x0014, 0x003c }, + { 0x0014, 0x003d }, + { 0x0014, 0x003e }, + { 0x0014, 0x003f }, + { 0x0014, 0x0040 }, + { 0x0014, 0x0041 }, + { 0x0014, 0x0042 }, + { 0x0014, 0x0043 }, + { 0x0014, 0x0044 }, + { 0x0014, 0x0045 }, + { 0x0014, 0x0046 }, + { 0x0014, 0x0047 }, + { 0x0014, 0x0048 }, + { 0x0014, 0x0049 }, + { 0x0014, 0x004a }, + { 0x0014, 0x004b }, + { 0x0014, 0x004c }, + { 0x0014, 0x004d }, + { 0x0014, 0x004e }, + { 0x0014, 0x004f }, + { 0x0014, 0x0050 }, + { 0x0014, 0x0051 }, + { 0x0014, 0x0052 }, + { 0x0014, 0x0053 }, + { 0x0014, 0x0054 }, + { 0x0014, 0x0055 }, + { 0x0014, 0x0056 }, + { 0x0014, 0x0057 }, + { 0x0014, 0x0058 }, + { 0x0014, 0x0059 }, + { 0x0014, 0x005a }, + { 0x0014, 0x005b }, + { 0x0014, 0x005c }, + { 0x0014, 0x005d }, + { 0x0014, 0x005e }, + { 0x0014, 0x005f }, + { 0x0014, 0x0060 }, + { 0x0014, 0x0061 }, + { 0x0014, 0x0062 }, + { 0x0014, 0x0063 }, + { 0x0014, 0x0064 }, + { 0x0014, 0x0065 }, + { 0x0014, 0x0066 }, + { 0x0014, 0x0067 }, + { 0x0014, 0x0068 }, + { 0x0014, 0x0069 }, + { 0x0014, 0x006a }, + { 0x0014, 0x006b }, + { 0x0014, 0x006c }, + { 0x0014, 0x006d }, + { 0x0014, 0x006e }, + { 0x0014, 0x006f }, + { 0x0014, 0x0070 }, + { 0x0014, 0x0071 }, + { 0x0014, 0x0072 }, + { 0x0014, 0x0073 }, + { 0x0014, 0x0074 }, + { 0x0014, 0x0075 }, + { 0x0014, 0x0076 }, + { 0x0014, 0x0077 }, + { 0x0014, 0x0078 }, + { 0x0014, 0x0079 }, + { 0x0014, 0x007a }, + { 0x0014, 0x007b }, + { 0x0014, 0x007c }, + { 0x0014, 0x007d }, + { 0x0014, 0x007e }, + { 0x0014, 0x007f }, + { 0x0014, 0x0080 }, + { 0x0014, 0x0081 }, + { 0x0014, 0x0082 }, + { 0x0014, 0x0083 }, + { 0x0014, 0x0084 }, + { 0x0014, 0x0085 }, + { 0x0014, 0x0086 }, + { 0x0014, 0x0087 }, + { 0x0014, 0x0088 }, + { 0x0014, 0x0089 }, + { 0x0014, 0x008a }, + { 0x0014, 0x008b }, + { 0x0014, 0x008c }, + { 0x0014, 0x008d }, + { 0x0014, 0x008e }, + { 0x0014, 0x008f }, + { 0x0014, 0x0090 }, + { 0x0014, 0x0091 }, + { 0x0014, 0x0092 }, + { 0x0014, 0x0093 }, + { 0x0014, 0x0094 }, + { 0x0014, 0x0095 }, + { 0x0014, 0x0096 }, + { 0x0014, 0x0097 }, + { 0x0014, 0x0098 }, + { 0x0014, 0x0099 }, + { 0x0014, 0x009a }, + { 0x0014, 0x009b }, + { 0x0014, 0x009c }, + { 0x0014, 0x009d }, + { 0x0014, 0x009e }, + { 0x0014, 0x009f }, + { 0x0014, 0x00a0 }, + { 0x0014, 0x00a1 }, + { 0x0014, 0x00a2 }, + { 0x0014, 0x00a3 }, + { 0x0014, 0x00a4 }, + { 0x0014, 0x00a5 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc14[400][2] = + { + { 0x0005, 0x0007 }, + { 0x0004, 0x0009 }, + { 0x0005, 0x0008 }, + { 0x0005, 0x0009 }, + { 0x0006, 0x0006 }, + { 0x0007, 0x0006 }, + { 0x0009, 0x0007 }, + { 0x000b, 0x0008 }, + { 0x000d, 0x000c }, + { 0x000f, 0x0013 }, + { 0x0010, 0x001b }, + { 0x0013, 0x0082 }, + { 0x0013, 0x0083 }, + { 0x0014, 0x0000 }, + { 0x0014, 0x0001 }, + { 0x0014, 0x0002 }, + { 0x0014, 0x0003 }, + { 0x0014, 0x0004 }, + { 0x0014, 0x0005 }, + { 0x0014, 0x0006 }, + { 0x0004, 0x000a }, + { 0x0004, 0x000b }, + { 0x0004, 0x000c }, + { 0x0005, 0x000a }, + { 0x0005, 0x000b }, + { 0x0006, 0x0007 }, + { 0x0008, 0x0006 }, + { 0x000a, 0x0007 }, + { 0x000c, 0x000a }, + { 0x000e, 0x000e }, + { 0x000f, 0x0014 }, + { 0x0011, 0x002a }, + { 0x0012, 0x004a }, + { 0x0013, 0x0084 }, + { 0x0014, 0x0007 }, + { 0x0014, 0x0008 }, + { 0x0014, 0x0009 }, + { 0x0014, 0x000a }, + { 0x0014, 0x000b }, + { 0x0014, 0x000c }, + { 0x0005, 0x000c }, + { 0x0004, 0x000d }, + { 0x0004, 0x000e }, + { 0x0005, 0x000d }, + { 0x0006, 0x0008 }, + { 0x0007, 0x0007 }, + { 0x0008, 0x0007 }, + { 0x000a, 0x0008 }, + { 0x000c, 0x000b }, + { 0x000e, 0x000f }, + { 0x000f, 0x0015 }, + { 0x0012, 0x004b }, + { 0x0013, 0x0085 }, + { 0x0014, 0x000d }, + { 0x0014, 0x000e }, + { 0x0014, 0x000f }, + { 0x0014, 0x0010 }, + { 0x0014, 0x0011 }, + { 0x0014, 0x0012 }, + { 0x0014, 0x0013 }, + { 0x0005, 0x000e }, + { 0x0004, 0x000f }, + { 0x0005, 0x000f }, + { 0x0005, 0x0010 }, + { 0x0006, 0x0009 }, + { 0x0008, 0x0008 }, + { 0x0009, 0x0008 }, + { 0x000b, 0x0009 }, + { 0x000d, 0x000d }, + { 0x000e, 0x0010 }, + { 0x0010, 0x001c }, + { 0x0011, 0x002b }, + { 0x0014, 0x0014 }, + { 0x0014, 0x0015 }, + { 0x0014, 0x0016 }, + { 0x0014, 0x0017 }, + { 0x0014, 0x0018 }, + { 0x0014, 0x0019 }, + { 0x0014, 0x001a }, + { 0x0014, 0x001b }, + { 0x0006, 0x000a }, + { 0x0005, 0x0011 }, + { 0x0006, 0x000b }, + { 0x0006, 0x000c }, + { 0x0007, 0x0008 }, + { 0x0008, 0x0009 }, + { 0x000a, 0x0009 }, + { 0x000c, 0x000c }, + { 0x000e, 0x0011 }, + { 0x000f, 0x0016 }, + { 0x0010, 0x001d }, + { 0x0012, 0x004c }, + { 0x0014, 0x001c }, + { 0x0014, 0x001d }, + { 0x0014, 0x001e }, + { 0x0014, 0x001f }, + { 0x0014, 0x0020 }, + { 0x0014, 0x0021 }, + { 0x0014, 0x0022 }, + { 0x0014, 0x0023 }, + { 0x0007, 0x0009 }, + { 0x0006, 0x000d }, + { 0x0007, 0x000a }, + { 0x0007, 0x000b }, + { 0x0009, 0x0009 }, + { 0x000a, 0x000a }, + { 0x000b, 0x000a }, + { 0x000d, 0x000e }, + { 0x000f, 0x0017 }, + { 0x0011, 0x002c }, + { 0x0010, 0x001e }, + { 0x0014, 0x0024 }, + { 0x0014, 0x0025 }, + { 0x0014, 0x0026 }, + { 0x0014, 0x0027 }, + { 0x0014, 0x0028 }, + { 0x0014, 0x0029 }, + { 0x0014, 0x002a }, + { 0x0014, 0x002b }, + { 0x0014, 0x002c }, + { 0x0009, 0x000a }, + { 0x0008, 0x000a }, + { 0x0008, 0x000b }, + { 0x0009, 0x000b }, + { 0x000a, 0x000b }, + { 0x000b, 0x000b }, + { 0x000d, 0x000f }, + { 0x000e, 0x0012 }, + { 0x000f, 0x0018 }, + { 0x0011, 0x002d }, + { 0x0011, 0x002e }, + { 0x0013, 0x0086 }, + { 0x0014, 0x002d }, + { 0x0014, 0x002e }, + { 0x0014, 0x002f }, + { 0x0014, 0x0030 }, + { 0x0014, 0x0031 }, + { 0x0014, 0x0032 }, + { 0x0014, 0x0033 }, + { 0x0014, 0x0034 }, + { 0x000b, 0x000c }, + { 0x000a, 0x000c }, + { 0x000a, 0x000d }, + { 0x000b, 0x000d }, + { 0x000c, 0x000d }, + { 0x000d, 0x0010 }, + { 0x000e, 0x0013 }, + { 0x000f, 0x0019 }, + { 0x0010, 0x001f }, + { 0x0013, 0x0087 }, + { 0x0014, 0x0035 }, + { 0x0014, 0x0036 }, + { 0x0013, 0x0088 }, + { 0x0014, 0x0037 }, + { 0x0014, 0x0038 }, + { 0x0014, 0x0039 }, + { 0x0014, 0x003a }, + { 0x0014, 0x003b }, + { 0x0014, 0x003c }, + { 0x0014, 0x003d }, + { 0x000d, 0x0011 }, + { 0x000c, 0x000e }, + { 0x000c, 0x000f }, + { 0x000d, 0x0012 }, + { 0x000d, 0x0013 }, + { 0x000e, 0x0014 }, + { 0x0010, 0x0020 }, + { 0x0010, 0x0021 }, + { 0x0012, 0x004d }, + { 0x0011, 0x002f }, + { 0x0014, 0x003e }, + { 0x0014, 0x003f }, + { 0x0014, 0x0040 }, + { 0x0014, 0x0041 }, + { 0x0014, 0x0042 }, + { 0x0014, 0x0043 }, + { 0x0014, 0x0044 }, + { 0x0014, 0x0045 }, + { 0x0014, 0x0046 }, + { 0x0014, 0x0047 }, + { 0x000f, 0x001a }, + { 0x000e, 0x0015 }, + { 0x000e, 0x0016 }, + { 0x000e, 0x0017 }, + { 0x000f, 0x001b }, + { 0x0011, 0x0030 }, + { 0x0011, 0x0031 }, + { 0x0013, 0x0089 }, + { 0x0013, 0x008a }, + { 0x0013, 0x008b }, + { 0x0014, 0x0048 }, + { 0x0014, 0x0049 }, + { 0x0014, 0x004a }, + { 0x0014, 0x004b }, + { 0x0014, 0x004c }, + { 0x0014, 0x004d }, + { 0x0014, 0x004e }, + { 0x0014, 0x004f }, + { 0x0014, 0x0050 }, + { 0x0014, 0x0051 }, + { 0x0010, 0x0022 }, + { 0x0010, 0x0023 }, + { 0x0010, 0x0024 }, + { 0x0010, 0x0025 }, + { 0x0011, 0x0032 }, + { 0x0011, 0x0033 }, + { 0x0012, 0x004e }, + { 0x0012, 0x004f }, + { 0x0014, 0x0052 }, + { 0x0013, 0x008c }, + { 0x0013, 0x008d }, + { 0x0014, 0x0053 }, + { 0x0014, 0x0054 }, + { 0x0014, 0x0055 }, + { 0x0014, 0x0056 }, + { 0x0014, 0x0057 }, + { 0x0014, 0x0058 }, + { 0x0014, 0x0059 }, + { 0x0014, 0x005a }, + { 0x0014, 0x005b }, + { 0x0011, 0x0034 }, + { 0x0011, 0x0035 }, + { 0x0012, 0x0050 }, + { 0x0012, 0x0051 }, + { 0x0013, 0x008e }, + { 0x0014, 0x005c }, + { 0x0014, 0x005d }, + { 0x0014, 0x005e }, + { 0x0014, 0x005f }, + { 0x0014, 0x0060 }, + { 0x0014, 0x0061 }, + { 0x0014, 0x0062 }, + { 0x0014, 0x0063 }, + { 0x0014, 0x0064 }, + { 0x0014, 0x0065 }, + { 0x0014, 0x0066 }, + { 0x0014, 0x0067 }, + { 0x0014, 0x0068 }, + { 0x0014, 0x0069 }, + { 0x0014, 0x006a }, + { 0x0012, 0x0052 }, + { 0x0013, 0x008f }, + { 0x0013, 0x0090 }, + { 0x0014, 0x006b }, + { 0x0013, 0x0091 }, + { 0x0014, 0x006c }, + { 0x0014, 0x006d }, + { 0x0014, 0x006e }, + { 0x0014, 0x006f }, + { 0x0014, 0x0070 }, + { 0x0014, 0x0071 }, + { 0x0014, 0x0072 }, + { 0x0014, 0x0073 }, + { 0x0014, 0x0074 }, + { 0x0014, 0x0075 }, + { 0x0014, 0x0076 }, + { 0x0014, 0x0077 }, + { 0x0014, 0x0078 }, + { 0x0014, 0x0079 }, + { 0x0014, 0x007a }, + { 0x0014, 0x007b }, + { 0x0014, 0x007c }, + { 0x0013, 0x0092 }, + { 0x0012, 0x0053 }, + { 0x0014, 0x007d }, + { 0x0014, 0x007e }, + { 0x0014, 0x007f }, + { 0x0014, 0x0080 }, + { 0x0014, 0x0081 }, + { 0x0014, 0x0082 }, + { 0x0014, 0x0083 }, + { 0x0014, 0x0084 }, + { 0x0014, 0x0085 }, + { 0x0014, 0x0086 }, + { 0x0014, 0x0087 }, + { 0x0014, 0x0088 }, + { 0x0014, 0x0089 }, + { 0x0014, 0x008a }, + { 0x0014, 0x008b }, + { 0x0014, 0x008c }, + { 0x0014, 0x008d }, + { 0x0014, 0x008e }, + { 0x0013, 0x0093 }, + { 0x0014, 0x008f }, + { 0x0014, 0x0090 }, + { 0x0014, 0x0091 }, + { 0x0014, 0x0092 }, + { 0x0014, 0x0093 }, + { 0x0014, 0x0094 }, + { 0x0014, 0x0095 }, + { 0x0014, 0x0096 }, + { 0x0014, 0x0097 }, + { 0x0014, 0x0098 }, + { 0x0014, 0x0099 }, + { 0x0014, 0x009a }, + { 0x0014, 0x009b }, + { 0x0014, 0x009c }, + { 0x0014, 0x009d }, + { 0x0014, 0x009e }, + { 0x0014, 0x009f }, + { 0x0014, 0x00a0 }, + { 0x0014, 0x00a1 }, + { 0x0014, 0x00a2 }, + { 0x0014, 0x00a3 }, + { 0x0014, 0x00a4 }, + { 0x0014, 0x00a5 }, + { 0x0014, 0x00a6 }, + { 0x0014, 0x00a7 }, + { 0x0014, 0x00a8 }, + { 0x0014, 0x00a9 }, + { 0x0014, 0x00aa }, + { 0x0014, 0x00ab }, + { 0x0014, 0x00ac }, + { 0x0014, 0x00ad }, + { 0x0014, 0x00ae }, + { 0x0014, 0x00af }, + { 0x0014, 0x00b0 }, + { 0x0014, 0x00b1 }, + { 0x0014, 0x00b2 }, + { 0x0014, 0x00b3 }, + { 0x0014, 0x00b4 }, + { 0x0014, 0x00b5 }, + { 0x0014, 0x00b6 }, + { 0x0014, 0x00b7 }, + { 0x0014, 0x00b8 }, + { 0x0014, 0x00b9 }, + { 0x0014, 0x00ba }, + { 0x0014, 0x00bb }, + { 0x0014, 0x00bc }, + { 0x0014, 0x00bd }, + { 0x0014, 0x00be }, + { 0x0014, 0x00bf }, + { 0x0014, 0x00c0 }, + { 0x0014, 0x00c1 }, + { 0x0014, 0x00c2 }, + { 0x0014, 0x00c3 }, + { 0x0014, 0x00c4 }, + { 0x0014, 0x00c5 }, + { 0x0014, 0x00c6 }, + { 0x0014, 0x00c7 }, + { 0x0014, 0x00c8 }, + { 0x0014, 0x00c9 }, + { 0x0014, 0x00ca }, + { 0x0014, 0x00cb }, + { 0x0014, 0x00cc }, + { 0x0014, 0x00cd }, + { 0x0014, 0x00ce }, + { 0x0014, 0x00cf }, + { 0x0014, 0x00d0 }, + { 0x0014, 0x00d1 }, + { 0x0014, 0x00d2 }, + { 0x0014, 0x00d3 }, + { 0x0014, 0x00d4 }, + { 0x0014, 0x00d5 }, + { 0x0014, 0x00d6 }, + { 0x0014, 0x00d7 }, + { 0x0014, 0x00d8 }, + { 0x0014, 0x00d9 }, + { 0x0014, 0x00da }, + { 0x0014, 0x00db }, + { 0x0014, 0x00dc }, + { 0x0014, 0x00dd }, + { 0x0014, 0x00de }, + { 0x0014, 0x00df }, + { 0x0014, 0x00e0 }, + { 0x0014, 0x00e1 }, + { 0x0014, 0x00e2 }, + { 0x0014, 0x00e3 }, + { 0x0014, 0x00e4 }, + { 0x0014, 0x00e5 }, + { 0x0014, 0x00e6 }, + { 0x0014, 0x00e7 }, + { 0x0014, 0x00e8 }, + { 0x0014, 0x00e9 }, + { 0x0014, 0x00ea }, + { 0x0014, 0x00eb }, + { 0x0014, 0x00ec }, + { 0x0014, 0x00ed }, + { 0x0014, 0x00ee }, + { 0x0014, 0x00ef }, + { 0x0014, 0x00f0 }, + { 0x0014, 0x00f1 }, + { 0x0014, 0x00f2 }, + { 0x0014, 0x00f3 }, + { 0x0014, 0x00f4 }, + { 0x0014, 0x00f5 }, + { 0x0014, 0x00f6 }, + { 0x0014, 0x00f7 }, + { 0x0014, 0x00f8 }, + { 0x0014, 0x00f9 }, + { 0x0014, 0x00fa }, + { 0x0014, 0x00fb }, + { 0x0014, 0x00fc }, + { 0x0014, 0x00fd }, + { 0x0014, 0x00fe }, + { 0x0014, 0x00ff }, + { 0x0014, 0x0100 }, + { 0x0014, 0x0101 }, + { 0x0014, 0x0102 }, + { 0x0014, 0x0103 }, + }; + +const uint16_t c_aauiLCLDHuffEnc15[576][2] = + { + { 0x0005, 0x000a }, + { 0x0005, 0x000b }, + { 0x0005, 0x000c }, + { 0x0006, 0x0009 }, + { 0x0006, 0x000a }, + { 0x0007, 0x0008 }, + { 0x0008, 0x0009 }, + { 0x0009, 0x0008 }, + { 0x000b, 0x000b }, + { 0x000d, 0x000e }, + { 0x000e, 0x0011 }, + { 0x000f, 0x001a }, + { 0x0012, 0x006e }, + { 0x0014, 0x0000 }, + { 0x0013, 0x00cc }, + { 0x0014, 0x0001 }, + { 0x0014, 0x0002 }, + { 0x0014, 0x0003 }, + { 0x0014, 0x0004 }, + { 0x0014, 0x0005 }, + { 0x0014, 0x0006 }, + { 0x0014, 0x0007 }, + { 0x0014, 0x0008 }, + { 0x0014, 0x0009 }, + { 0x0005, 0x000d }, + { 0x0004, 0x000c }, + { 0x0004, 0x000d }, + { 0x0005, 0x000e }, + { 0x0005, 0x000f }, + { 0x0006, 0x000b }, + { 0x0007, 0x0009 }, + { 0x0008, 0x000a }, + { 0x000a, 0x000a }, + { 0x000c, 0x000c }, + { 0x000d, 0x000f }, + { 0x000f, 0x001b }, + { 0x0011, 0x003d }, + { 0x0011, 0x003e }, + { 0x0013, 0x00cd }, + { 0x0014, 0x000a }, + { 0x0014, 0x000b }, + { 0x0014, 0x000c }, + { 0x0014, 0x000d }, + { 0x0014, 0x000e }, + { 0x0014, 0x000f }, + { 0x0014, 0x0010 }, + { 0x0014, 0x0011 }, + { 0x0014, 0x0012 }, + { 0x0005, 0x0010 }, + { 0x0004, 0x000e }, + { 0x0004, 0x000f }, + { 0x0005, 0x0011 }, + { 0x0005, 0x0012 }, + { 0x0006, 0x000c }, + { 0x0007, 0x000a }, + { 0x0009, 0x0009 }, + { 0x000a, 0x000b }, + { 0x000c, 0x000d }, + { 0x000e, 0x0012 }, + { 0x0010, 0x0027 }, + { 0x0011, 0x003f }, + { 0x0012, 0x006f }, + { 0x0014, 0x0013 }, + { 0x0014, 0x0014 }, + { 0x0014, 0x0015 }, + { 0x0014, 0x0016 }, + { 0x0014, 0x0017 }, + { 0x0014, 0x0018 }, + { 0x0014, 0x0019 }, + { 0x0014, 0x001a }, + { 0x0014, 0x001b }, + { 0x0014, 0x001c }, + { 0x0006, 0x000d }, + { 0x0005, 0x0013 }, + { 0x0005, 0x0014 }, + { 0x0005, 0x0015 }, + { 0x0006, 0x000e }, + { 0x0007, 0x000b }, + { 0x0008, 0x000b }, + { 0x0009, 0x000a }, + { 0x000b, 0x000c }, + { 0x000c, 0x000e }, + { 0x000e, 0x0013 }, + { 0x000f, 0x001c }, + { 0x0011, 0x0040 }, + { 0x0012, 0x0070 }, + { 0x0014, 0x001d }, + { 0x0014, 0x001e }, + { 0x0014, 0x001f }, + { 0x0014, 0x0020 }, + { 0x0014, 0x0021 }, + { 0x0014, 0x0022 }, + { 0x0014, 0x0023 }, + { 0x0014, 0x0024 }, + { 0x0014, 0x0025 }, + { 0x0014, 0x0026 }, + { 0x0006, 0x000f }, + { 0x0005, 0x0016 }, + { 0x0005, 0x0017 }, + { 0x0006, 0x0010 }, + { 0x0006, 0x0011 }, + { 0x0007, 0x000c }, + { 0x0009, 0x000b }, + { 0x000a, 0x000c }, + { 0x000b, 0x000d }, + { 0x000d, 0x0010 }, + { 0x000e, 0x0014 }, + { 0x0010, 0x0028 }, + { 0x0011, 0x0041 }, + { 0x0013, 0x00ce }, + { 0x0014, 0x0027 }, + { 0x0014, 0x0028 }, + { 0x0014, 0x0029 }, + { 0x0014, 0x002a }, + { 0x0014, 0x002b }, + { 0x0014, 0x002c }, + { 0x0014, 0x002d }, + { 0x0014, 0x002e }, + { 0x0014, 0x002f }, + { 0x0014, 0x0030 }, + { 0x0007, 0x000d }, + { 0x0006, 0x0012 }, + { 0x0006, 0x0013 }, + { 0x0007, 0x000e }, + { 0x0007, 0x000f }, + { 0x0008, 0x000c }, + { 0x0009, 0x000c }, + { 0x000b, 0x000e }, + { 0x000c, 0x000f }, + { 0x000e, 0x0015 }, + { 0x0010, 0x0029 }, + { 0x0011, 0x0042 }, + { 0x0014, 0x0031 }, + { 0x0014, 0x0032 }, + { 0x0014, 0x0033 }, + { 0x0014, 0x0034 }, + { 0x0014, 0x0035 }, + { 0x0014, 0x0036 }, + { 0x0014, 0x0037 }, + { 0x0014, 0x0038 }, + { 0x0014, 0x0039 }, + { 0x0014, 0x003a }, + { 0x0014, 0x003b }, + { 0x0014, 0x003c }, + { 0x0008, 0x000d }, + { 0x0007, 0x0010 }, + { 0x0007, 0x0011 }, + { 0x0008, 0x000e }, + { 0x0009, 0x000d }, + { 0x0009, 0x000e }, + { 0x000b, 0x000f }, + { 0x000c, 0x0010 }, + { 0x000d, 0x0011 }, + { 0x000f, 0x001d }, + { 0x0010, 0x002a }, + { 0x0011, 0x0043 }, + { 0x0014, 0x003d }, + { 0x0013, 0x00cf }, + { 0x0014, 0x003e }, + { 0x0014, 0x003f }, + { 0x0014, 0x0040 }, + { 0x0014, 0x0041 }, + { 0x0014, 0x0042 }, + { 0x0014, 0x0043 }, + { 0x0014, 0x0044 }, + { 0x0014, 0x0045 }, + { 0x0014, 0x0046 }, + { 0x0014, 0x0047 }, + { 0x0009, 0x000f }, + { 0x0008, 0x000f }, + { 0x0009, 0x0010 }, + { 0x0009, 0x0011 }, + { 0x000a, 0x000d }, + { 0x000b, 0x0010 }, + { 0x000c, 0x0011 }, + { 0x000d, 0x0012 }, + { 0x000e, 0x0016 }, + { 0x0010, 0x002b }, + { 0x0011, 0x0044 }, + { 0x0012, 0x0071 }, + { 0x0014, 0x0048 }, + { 0x0014, 0x0049 }, + { 0x0014, 0x004a }, + { 0x0014, 0x004b }, + { 0x0014, 0x004c }, + { 0x0014, 0x004d }, + { 0x0014, 0x004e }, + { 0x0014, 0x004f }, + { 0x0014, 0x0050 }, + { 0x0014, 0x0051 }, + { 0x0014, 0x0052 }, + { 0x0014, 0x0053 }, + { 0x000b, 0x0011 }, + { 0x000a, 0x000e }, + { 0x000a, 0x000f }, + { 0x000b, 0x0012 }, + { 0x000b, 0x0013 }, + { 0x000c, 0x0012 }, + { 0x000d, 0x0013 }, + { 0x000e, 0x0017 }, + { 0x0010, 0x002c }, + { 0x0012, 0x0072 }, + { 0x0011, 0x0045 }, + { 0x0013, 0x00d0 }, + { 0x0013, 0x00d1 }, + { 0x0014, 0x0054 }, + { 0x0014, 0x0055 }, + { 0x0014, 0x0056 }, + { 0x0014, 0x0057 }, + { 0x0014, 0x0058 }, + { 0x0014, 0x0059 }, + { 0x0014, 0x005a }, + { 0x0014, 0x005b }, + { 0x0014, 0x005c }, + { 0x0014, 0x005d }, + { 0x0014, 0x005e }, + { 0x000c, 0x0013 }, + { 0x000c, 0x0014 }, + { 0x000c, 0x0015 }, + { 0x000d, 0x0014 }, + { 0x000d, 0x0015 }, + { 0x000e, 0x0018 }, + { 0x000f, 0x001e }, + { 0x0010, 0x002d }, + { 0x0011, 0x0046 }, + { 0x0011, 0x0047 }, + { 0x0011, 0x0048 }, + { 0x0014, 0x005f }, + { 0x0014, 0x0060 }, + { 0x0014, 0x0061 }, + { 0x0014, 0x0062 }, + { 0x0014, 0x0063 }, + { 0x0014, 0x0064 }, + { 0x0014, 0x0065 }, + { 0x0014, 0x0066 }, + { 0x0014, 0x0067 }, + { 0x0014, 0x0068 }, + { 0x0014, 0x0069 }, + { 0x0014, 0x006a }, + { 0x0014, 0x006b }, + { 0x000e, 0x0019 }, + { 0x000d, 0x0016 }, + { 0x000d, 0x0017 }, + { 0x000e, 0x001a }, + { 0x000e, 0x001b }, + { 0x000f, 0x001f }, + { 0x0010, 0x002e }, + { 0x0011, 0x0049 }, + { 0x0012, 0x0073 }, + { 0x0014, 0x006c }, + { 0x0014, 0x006d }, + { 0x0014, 0x006e }, + { 0x0014, 0x006f }, + { 0x0014, 0x0070 }, + { 0x0014, 0x0071 }, + { 0x0014, 0x0072 }, + { 0x0014, 0x0073 }, + { 0x0014, 0x0074 }, + { 0x0014, 0x0075 }, + { 0x0014, 0x0076 }, + { 0x0014, 0x0077 }, + { 0x0014, 0x0078 }, + { 0x0014, 0x0079 }, + { 0x0014, 0x007a }, + { 0x0010, 0x002f }, + { 0x000f, 0x0020 }, + { 0x0010, 0x0030 }, + { 0x000f, 0x0021 }, + { 0x0010, 0x0031 }, + { 0x0011, 0x004a }, + { 0x0011, 0x004b }, + { 0x0012, 0x0074 }, + { 0x0014, 0x007b }, + { 0x0014, 0x007c }, + { 0x0013, 0x00d2 }, + { 0x0014, 0x007d }, + { 0x0014, 0x007e }, + { 0x0014, 0x007f }, + { 0x0014, 0x0080 }, + { 0x0014, 0x0081 }, + { 0x0014, 0x0082 }, + { 0x0014, 0x0083 }, + { 0x0014, 0x0084 }, + { 0x0014, 0x0085 }, + { 0x0014, 0x0086 }, + { 0x0014, 0x0087 }, + { 0x0014, 0x0088 }, + { 0x0014, 0x0089 }, + { 0x0012, 0x0075 }, + { 0x0010, 0x0032 }, + { 0x0010, 0x0033 }, + { 0x0011, 0x004c }, + { 0x0011, 0x004d }, + { 0x0013, 0x00d3 }, + { 0x0013, 0x00d4 }, + { 0x0012, 0x0076 }, + { 0x0013, 0x00d5 }, + { 0x0014, 0x008a }, + { 0x0014, 0x008b }, + { 0x0014, 0x008c }, + { 0x0014, 0x008d }, + { 0x0014, 0x008e }, + { 0x0014, 0x008f }, + { 0x0014, 0x0090 }, + { 0x0014, 0x0091 }, + { 0x0014, 0x0092 }, + { 0x0014, 0x0093 }, + { 0x0014, 0x0094 }, + { 0x0014, 0x0095 }, + { 0x0014, 0x0096 }, + { 0x0014, 0x0097 }, + { 0x0014, 0x0098 }, + { 0x0013, 0x00d6 }, + { 0x0013, 0x00d7 }, + { 0x0012, 0x0077 }, + { 0x0012, 0x0078 }, + { 0x0014, 0x0099 }, + { 0x0014, 0x009a }, + { 0x0013, 0x00d8 }, + { 0x0014, 0x009b }, + { 0x0014, 0x009c }, + { 0x0014, 0x009d }, + { 0x0014, 0x009e }, + { 0x0014, 0x009f }, + { 0x0014, 0x00a0 }, + { 0x0014, 0x00a1 }, + { 0x0014, 0x00a2 }, + { 0x0014, 0x00a3 }, + { 0x0014, 0x00a4 }, + { 0x0014, 0x00a5 }, + { 0x0014, 0x00a6 }, + { 0x0014, 0x00a7 }, + { 0x0014, 0x00a8 }, + { 0x0014, 0x00a9 }, + { 0x0014, 0x00aa }, + { 0x0014, 0x00ab }, + { 0x0014, 0x00ac }, + { 0x0014, 0x00ad }, + { 0x0014, 0x00ae }, + { 0x0014, 0x00af }, + { 0x0012, 0x0079 }, + { 0x0014, 0x00b0 }, + { 0x0014, 0x00b1 }, + { 0x0014, 0x00b2 }, + { 0x0014, 0x00b3 }, + { 0x0014, 0x00b4 }, + { 0x0014, 0x00b5 }, + { 0x0014, 0x00b6 }, + { 0x0014, 0x00b7 }, + { 0x0014, 0x00b8 }, + { 0x0014, 0x00b9 }, + { 0x0014, 0x00ba }, + { 0x0014, 0x00bb }, + { 0x0014, 0x00bc }, + { 0x0014, 0x00bd }, + { 0x0014, 0x00be }, + { 0x0014, 0x00bf }, + { 0x0014, 0x00c0 }, + { 0x0014, 0x00c1 }, + { 0x0014, 0x00c2 }, + { 0x0014, 0x00c3 }, + { 0x0014, 0x00c4 }, + { 0x0014, 0x00c5 }, + { 0x0014, 0x00c6 }, + { 0x0013, 0x00d9 }, + { 0x0013, 0x00da }, + { 0x0014, 0x00c7 }, + { 0x0014, 0x00c8 }, + { 0x0014, 0x00c9 }, + { 0x0014, 0x00ca }, + { 0x0014, 0x00cb }, + { 0x0014, 0x00cc }, + { 0x0014, 0x00cd }, + { 0x0014, 0x00ce }, + { 0x0014, 0x00cf }, + { 0x0014, 0x00d0 }, + { 0x0014, 0x00d1 }, + { 0x0014, 0x00d2 }, + { 0x0014, 0x00d3 }, + { 0x0014, 0x00d4 }, + { 0x0014, 0x00d5 }, + { 0x0014, 0x00d6 }, + { 0x0014, 0x00d7 }, + { 0x0014, 0x00d8 }, + { 0x0014, 0x00d9 }, + { 0x0014, 0x00da }, + { 0x0014, 0x00db }, + { 0x0014, 0x00dc }, + { 0x0014, 0x00dd }, + { 0x0014, 0x00de }, + { 0x0014, 0x00df }, + { 0x0014, 0x00e0 }, + { 0x0014, 0x00e1 }, + { 0x0014, 0x00e2 }, + { 0x0014, 0x00e3 }, + { 0x0014, 0x00e4 }, + { 0x0014, 0x00e5 }, + { 0x0014, 0x00e6 }, + { 0x0014, 0x00e7 }, + { 0x0014, 0x00e8 }, + { 0x0014, 0x00e9 }, + { 0x0014, 0x00ea }, + { 0x0014, 0x00eb }, + { 0x0014, 0x00ec }, + { 0x0014, 0x00ed }, + { 0x0014, 0x00ee }, + { 0x0014, 0x00ef }, + { 0x0014, 0x00f0 }, + { 0x0014, 0x00f1 }, + { 0x0014, 0x00f2 }, + { 0x0014, 0x00f3 }, + { 0x0014, 0x00f4 }, + { 0x0014, 0x00f5 }, + { 0x0014, 0x00f6 }, + { 0x0014, 0x00f7 }, + { 0x0014, 0x00f8 }, + { 0x0014, 0x00f9 }, + { 0x0014, 0x00fa }, + { 0x0014, 0x00fb }, + { 0x0014, 0x00fc }, + { 0x0014, 0x00fd }, + { 0x0014, 0x00fe }, + { 0x0014, 0x00ff }, + { 0x0014, 0x0100 }, + { 0x0014, 0x0101 }, + { 0x0014, 0x0102 }, + { 0x0014, 0x0103 }, + { 0x0014, 0x0104 }, + { 0x0014, 0x0105 }, + { 0x0014, 0x0106 }, + { 0x0014, 0x0107 }, + { 0x0014, 0x0108 }, + { 0x0014, 0x0109 }, + { 0x0014, 0x010a }, + { 0x0014, 0x010b }, + { 0x0014, 0x010c }, + { 0x0014, 0x010d }, + { 0x0014, 0x010e }, + { 0x0014, 0x010f }, + { 0x0014, 0x0110 }, + { 0x0014, 0x0111 }, + { 0x0014, 0x0112 }, + { 0x0014, 0x0113 }, + { 0x0014, 0x0114 }, + { 0x0014, 0x0115 }, + { 0x0014, 0x0116 }, + { 0x0014, 0x0117 }, + { 0x0014, 0x0118 }, + { 0x0014, 0x0119 }, + { 0x0014, 0x011a }, + { 0x0014, 0x011b }, + { 0x0014, 0x011c }, + { 0x0014, 0x011d }, + { 0x0014, 0x011e }, + { 0x0014, 0x011f }, + { 0x0014, 0x0120 }, + { 0x0014, 0x0121 }, + { 0x0014, 0x0122 }, + { 0x0014, 0x0123 }, + { 0x0014, 0x0124 }, + { 0x0014, 0x0125 }, + { 0x0014, 0x0126 }, + { 0x0014, 0x0127 }, + { 0x0014, 0x0128 }, + { 0x0014, 0x0129 }, + { 0x0014, 0x012a }, + { 0x0014, 0x012b }, + { 0x0014, 0x012c }, + { 0x0014, 0x012d }, + { 0x0014, 0x012e }, + { 0x0014, 0x012f }, + { 0x0014, 0x0130 }, + { 0x0014, 0x0131 }, + { 0x0014, 0x0132 }, + { 0x0014, 0x0133 }, + { 0x0014, 0x0134 }, + { 0x0014, 0x0135 }, + { 0x0014, 0x0136 }, + { 0x0014, 0x0137 }, + { 0x0014, 0x0138 }, + { 0x0014, 0x0139 }, + { 0x0014, 0x013a }, + { 0x0014, 0x013b }, + { 0x0014, 0x013c }, + { 0x0014, 0x013d }, + { 0x0014, 0x013e }, + { 0x0014, 0x013f }, + { 0x0014, 0x0140 }, + { 0x0014, 0x0141 }, + { 0x0014, 0x0142 }, + { 0x0014, 0x0143 }, + { 0x0014, 0x0144 }, + { 0x0014, 0x0145 }, + { 0x0014, 0x0146 }, + { 0x0014, 0x0147 }, + { 0x0014, 0x0148 }, + { 0x0014, 0x0149 }, + { 0x0014, 0x014a }, + { 0x0014, 0x014b }, + { 0x0014, 0x014c }, + { 0x0014, 0x014d }, + { 0x0014, 0x014e }, + { 0x0014, 0x014f }, + { 0x0014, 0x0150 }, + { 0x0014, 0x0151 }, + { 0x0014, 0x0152 }, + { 0x0014, 0x0153 }, + { 0x0014, 0x0154 }, + { 0x0014, 0x0155 }, + { 0x0014, 0x0156 }, + { 0x0014, 0x0157 }, + { 0x0014, 0x0158 }, + { 0x0014, 0x0159 }, + { 0x0014, 0x015a }, + { 0x0014, 0x015b }, + { 0x0014, 0x015c }, + { 0x0014, 0x015d }, + { 0x0014, 0x015e }, + { 0x0014, 0x015f }, + { 0x0014, 0x0160 }, + { 0x0014, 0x0161 }, + { 0x0014, 0x0162 }, + { 0x0014, 0x0163 }, + { 0x0014, 0x0164 }, + { 0x0014, 0x0165 }, + { 0x0014, 0x0166 }, + { 0x0014, 0x0167 }, + { 0x0014, 0x0168 }, + { 0x0014, 0x0169 }, + { 0x0014, 0x016a }, + { 0x0014, 0x016b }, + { 0x0014, 0x016c }, + { 0x0014, 0x016d }, + { 0x0014, 0x016e }, + { 0x0014, 0x016f }, + { 0x0014, 0x0170 }, + { 0x0014, 0x0171 }, + { 0x0014, 0x0172 }, + { 0x0014, 0x0173 }, + { 0x0014, 0x0174 }, + { 0x0014, 0x0175 }, + { 0x0014, 0x0176 }, + { 0x0014, 0x0177 }, + { 0x0014, 0x0178 }, + { 0x0014, 0x0179 }, + { 0x0014, 0x017a }, + { 0x0014, 0x017b }, + { 0x0014, 0x017c }, + { 0x0014, 0x017d }, + { 0x0014, 0x017e }, + { 0x0014, 0x017f }, + { 0x0014, 0x0180 }, + { 0x0014, 0x0181 }, + { 0x0014, 0x0182 }, + { 0x0014, 0x0183 }, + { 0x0014, 0x0184 }, + { 0x0014, 0x0185 }, + { 0x0014, 0x0186 }, + { 0x0014, 0x0187 }, + { 0x0014, 0x0188 }, + { 0x0014, 0x0189 }, + { 0x0014, 0x018a }, + { 0x0014, 0x018b }, + { 0x0014, 0x018c }, + { 0x0014, 0x018d }, + { 0x0014, 0x018e }, + { 0x0014, 0x018f }, + { 0x0014, 0x0190 }, + { 0x0014, 0x0191 }, + { 0x0014, 0x0192 }, + { 0x0014, 0x0193 }, + { 0x0014, 0x0194 }, + { 0x0014, 0x0195 }, + { 0x0014, 0x0196 }, + { 0x0014, 0x0197 }, + { 0x0013, 0x00db }, + }; + +const uint16_t c_aauiLCLDHuffEnc16[729][2] = + { + { 0x0006, 0x000d }, + { 0x0005, 0x0010 }, + { 0x0006, 0x000e }, + { 0x0006, 0x000f }, + { 0x0006, 0x0010 }, + { 0x0007, 0x000a }, + { 0x0007, 0x000b }, + { 0x0008, 0x000a }, + { 0x0009, 0x000b }, + { 0x000b, 0x000d }, + { 0x000c, 0x000e }, + { 0x000e, 0x0016 }, + { 0x0010, 0x002d }, + { 0x0011, 0x0051 }, + { 0x0012, 0x008c }, + { 0x0014, 0x0000 }, + { 0x0014, 0x0001 }, + { 0x0014, 0x0002 }, + { 0x0014, 0x0003 }, + { 0x0014, 0x0004 }, + { 0x0014, 0x0005 }, + { 0x0014, 0x0006 }, + { 0x0014, 0x0007 }, + { 0x0014, 0x0008 }, + { 0x0014, 0x0009 }, + { 0x0014, 0x000a }, + { 0x0014, 0x000b }, + { 0x0005, 0x0011 }, + { 0x0004, 0x000f }, + { 0x0005, 0x0012 }, + { 0x0005, 0x0013 }, + { 0x0005, 0x0014 }, + { 0x0006, 0x0011 }, + { 0x0006, 0x0012 }, + { 0x0007, 0x000c }, + { 0x0008, 0x000b }, + { 0x000a, 0x000c }, + { 0x000b, 0x000e }, + { 0x000d, 0x0010 }, + { 0x000e, 0x0017 }, + { 0x000f, 0x001c }, + { 0x0013, 0x010b }, + { 0x0013, 0x010c }, + { 0x0014, 0x000c }, + { 0x0014, 0x000d }, + { 0x0014, 0x000e }, + { 0x0014, 0x000f }, + { 0x0014, 0x0010 }, + { 0x0014, 0x0011 }, + { 0x0014, 0x0012 }, + { 0x0014, 0x0013 }, + { 0x0014, 0x0014 }, + { 0x0014, 0x0015 }, + { 0x0014, 0x0016 }, + { 0x0006, 0x0013 }, + { 0x0005, 0x0015 }, + { 0x0005, 0x0016 }, + { 0x0005, 0x0017 }, + { 0x0005, 0x0018 }, + { 0x0006, 0x0014 }, + { 0x0007, 0x000d }, + { 0x0007, 0x000e }, + { 0x0009, 0x000c }, + { 0x000a, 0x000d }, + { 0x000c, 0x000f }, + { 0x000d, 0x0011 }, + { 0x000f, 0x001d }, + { 0x0011, 0x0052 }, + { 0x0012, 0x008d }, + { 0x0012, 0x008e }, + { 0x0014, 0x0017 }, + { 0x0014, 0x0018 }, + { 0x0014, 0x0019 }, + { 0x0014, 0x001a }, + { 0x0014, 0x001b }, + { 0x0014, 0x001c }, + { 0x0014, 0x001d }, + { 0x0014, 0x001e }, + { 0x0014, 0x001f }, + { 0x0014, 0x0020 }, + { 0x0014, 0x0021 }, + { 0x0006, 0x0015 }, + { 0x0005, 0x0019 }, + { 0x0005, 0x001a }, + { 0x0005, 0x001b }, + { 0x0006, 0x0016 }, + { 0x0006, 0x0017 }, + { 0x0007, 0x000f }, + { 0x0008, 0x000c }, + { 0x0009, 0x000d }, + { 0x000b, 0x000f }, + { 0x000c, 0x0010 }, + { 0x000d, 0x0012 }, + { 0x000f, 0x001e }, + { 0x0012, 0x008f }, + { 0x0014, 0x0022 }, + { 0x0014, 0x0023 }, + { 0x0014, 0x0024 }, + { 0x0014, 0x0025 }, + { 0x0014, 0x0026 }, + { 0x0014, 0x0027 }, + { 0x0014, 0x0028 }, + { 0x0014, 0x0029 }, + { 0x0014, 0x002a }, + { 0x0014, 0x002b }, + { 0x0014, 0x002c }, + { 0x0014, 0x002d }, + { 0x0014, 0x002e }, + { 0x0006, 0x0018 }, + { 0x0005, 0x001c }, + { 0x0005, 0x001d }, + { 0x0006, 0x0019 }, + { 0x0006, 0x001a }, + { 0x0007, 0x0010 }, + { 0x0007, 0x0011 }, + { 0x0008, 0x000d }, + { 0x000a, 0x000e }, + { 0x000b, 0x0010 }, + { 0x000c, 0x0011 }, + { 0x000e, 0x0018 }, + { 0x0010, 0x002e }, + { 0x0012, 0x0090 }, + { 0x0013, 0x010d }, + { 0x0013, 0x010e }, + { 0x0014, 0x002f }, + { 0x0014, 0x0030 }, + { 0x0014, 0x0031 }, + { 0x0014, 0x0032 }, + { 0x0014, 0x0033 }, + { 0x0014, 0x0034 }, + { 0x0014, 0x0035 }, + { 0x0014, 0x0036 }, + { 0x0014, 0x0037 }, + { 0x0014, 0x0038 }, + { 0x0014, 0x0039 }, + { 0x0007, 0x0012 }, + { 0x0006, 0x001b }, + { 0x0006, 0x001c }, + { 0x0006, 0x001d }, + { 0x0007, 0x0013 }, + { 0x0007, 0x0014 }, + { 0x0008, 0x000e }, + { 0x0009, 0x000e }, + { 0x000b, 0x0011 }, + { 0x000c, 0x0012 }, + { 0x000d, 0x0013 }, + { 0x000e, 0x0019 }, + { 0x0010, 0x002f }, + { 0x0012, 0x0091 }, + { 0x0014, 0x003a }, + { 0x0014, 0x003b }, + { 0x0014, 0x003c }, + { 0x0014, 0x003d }, + { 0x0014, 0x003e }, + { 0x0014, 0x003f }, + { 0x0014, 0x0040 }, + { 0x0014, 0x0041 }, + { 0x0014, 0x0042 }, + { 0x0014, 0x0043 }, + { 0x0014, 0x0044 }, + { 0x0014, 0x0045 }, + { 0x0014, 0x0046 }, + { 0x0007, 0x0015 }, + { 0x0006, 0x001e }, + { 0x0006, 0x001f }, + { 0x0007, 0x0016 }, + { 0x0007, 0x0017 }, + { 0x0008, 0x000f }, + { 0x0009, 0x000f }, + { 0x000a, 0x000f }, + { 0x000b, 0x0012 }, + { 0x000d, 0x0014 }, + { 0x000e, 0x001a }, + { 0x000f, 0x001f }, + { 0x0013, 0x010f }, + { 0x0011, 0x0053 }, + { 0x0014, 0x0047 }, + { 0x0014, 0x0048 }, + { 0x0014, 0x0049 }, + { 0x0014, 0x004a }, + { 0x0014, 0x004b }, + { 0x0014, 0x004c }, + { 0x0014, 0x004d }, + { 0x0014, 0x004e }, + { 0x0014, 0x004f }, + { 0x0014, 0x0050 }, + { 0x0014, 0x0051 }, + { 0x0014, 0x0052 }, + { 0x0014, 0x0053 }, + { 0x0008, 0x0010 }, + { 0x0007, 0x0018 }, + { 0x0007, 0x0019 }, + { 0x0008, 0x0011 }, + { 0x0008, 0x0012 }, + { 0x0009, 0x0010 }, + { 0x000a, 0x0010 }, + { 0x000b, 0x0013 }, + { 0x000c, 0x0013 }, + { 0x000e, 0x001b }, + { 0x000f, 0x0020 }, + { 0x0010, 0x0030 }, + { 0x0012, 0x0092 }, + { 0x0014, 0x0054 }, + { 0x0014, 0x0055 }, + { 0x0014, 0x0056 }, + { 0x0014, 0x0057 }, + { 0x0014, 0x0058 }, + { 0x0014, 0x0059 }, + { 0x0014, 0x005a }, + { 0x0014, 0x005b }, + { 0x0014, 0x005c }, + { 0x0014, 0x005d }, + { 0x0014, 0x005e }, + { 0x0014, 0x005f }, + { 0x0014, 0x0060 }, + { 0x0014, 0x0061 }, + { 0x0009, 0x0011 }, + { 0x0008, 0x0013 }, + { 0x0009, 0x0012 }, + { 0x0009, 0x0013 }, + { 0x000a, 0x0011 }, + { 0x000a, 0x0012 }, + { 0x000b, 0x0014 }, + { 0x000c, 0x0014 }, + { 0x000d, 0x0015 }, + { 0x000e, 0x001c }, + { 0x000f, 0x0021 }, + { 0x0013, 0x0110 }, + { 0x0012, 0x0093 }, + { 0x0012, 0x0094 }, + { 0x0014, 0x0062 }, + { 0x0014, 0x0063 }, + { 0x0014, 0x0064 }, + { 0x0014, 0x0065 }, + { 0x0014, 0x0066 }, + { 0x0014, 0x0067 }, + { 0x0014, 0x0068 }, + { 0x0014, 0x0069 }, + { 0x0014, 0x006a }, + { 0x0014, 0x006b }, + { 0x0014, 0x006c }, + { 0x0014, 0x006d }, + { 0x0014, 0x006e }, + { 0x000b, 0x0015 }, + { 0x000a, 0x0013 }, + { 0x000a, 0x0014 }, + { 0x000a, 0x0015 }, + { 0x000b, 0x0016 }, + { 0x000c, 0x0015 }, + { 0x000d, 0x0016 }, + { 0x000d, 0x0017 }, + { 0x000f, 0x0022 }, + { 0x0010, 0x0031 }, + { 0x0012, 0x0095 }, + { 0x0012, 0x0096 }, + { 0x0014, 0x006f }, + { 0x0013, 0x0111 }, + { 0x0014, 0x0070 }, + { 0x0014, 0x0071 }, + { 0x0014, 0x0072 }, + { 0x0014, 0x0073 }, + { 0x0014, 0x0074 }, + { 0x0014, 0x0075 }, + { 0x0014, 0x0076 }, + { 0x0014, 0x0077 }, + { 0x0014, 0x0078 }, + { 0x0014, 0x0079 }, + { 0x0014, 0x007a }, + { 0x0014, 0x007b }, + { 0x0014, 0x007c }, + { 0x000c, 0x0016 }, + { 0x000b, 0x0017 }, + { 0x000c, 0x0017 }, + { 0x000c, 0x0018 }, + { 0x000c, 0x0019 }, + { 0x000d, 0x0018 }, + { 0x000e, 0x001d }, + { 0x000f, 0x0023 }, + { 0x000f, 0x0024 }, + { 0x0011, 0x0054 }, + { 0x0012, 0x0097 }, + { 0x0014, 0x007d }, + { 0x0014, 0x007e }, + { 0x0014, 0x007f }, + { 0x0014, 0x0080 }, + { 0x0014, 0x0081 }, + { 0x0014, 0x0082 }, + { 0x0014, 0x0083 }, + { 0x0014, 0x0084 }, + { 0x0014, 0x0085 }, + { 0x0014, 0x0086 }, + { 0x0014, 0x0087 }, + { 0x0014, 0x0088 }, + { 0x0014, 0x0089 }, + { 0x0014, 0x008a }, + { 0x0014, 0x008b }, + { 0x0014, 0x008c }, + { 0x000e, 0x001e }, + { 0x000d, 0x0019 }, + { 0x000d, 0x001a }, + { 0x000d, 0x001b }, + { 0x000e, 0x001f }, + { 0x000f, 0x0025 }, + { 0x000f, 0x0026 }, + { 0x0010, 0x0032 }, + { 0x0010, 0x0033 }, + { 0x0012, 0x0098 }, + { 0x0013, 0x0112 }, + { 0x0014, 0x008d }, + { 0x0014, 0x008e }, + { 0x0014, 0x008f }, + { 0x0014, 0x0090 }, + { 0x0014, 0x0091 }, + { 0x0014, 0x0092 }, + { 0x0014, 0x0093 }, + { 0x0014, 0x0094 }, + { 0x0014, 0x0095 }, + { 0x0014, 0x0096 }, + { 0x0014, 0x0097 }, + { 0x0014, 0x0098 }, + { 0x0014, 0x0099 }, + { 0x0014, 0x009a }, + { 0x0014, 0x009b }, + { 0x0014, 0x009c }, + { 0x000f, 0x0027 }, + { 0x000f, 0x0028 }, + { 0x000f, 0x0029 }, + { 0x000f, 0x002a }, + { 0x0010, 0x0034 }, + { 0x000f, 0x002b }, + { 0x0011, 0x0055 }, + { 0x0012, 0x0099 }, + { 0x0012, 0x009a }, + { 0x0012, 0x009b }, + { 0x0014, 0x009d }, + { 0x0013, 0x0113 }, + { 0x0014, 0x009e }, + { 0x0014, 0x009f }, + { 0x0014, 0x00a0 }, + { 0x0014, 0x00a1 }, + { 0x0014, 0x00a2 }, + { 0x0014, 0x00a3 }, + { 0x0014, 0x00a4 }, + { 0x0014, 0x00a5 }, + { 0x0014, 0x00a6 }, + { 0x0014, 0x00a7 }, + { 0x0014, 0x00a8 }, + { 0x0014, 0x00a9 }, + { 0x0014, 0x00aa }, + { 0x0014, 0x00ab }, + { 0x0014, 0x00ac }, + { 0x0011, 0x0056 }, + { 0x0010, 0x0035 }, + { 0x0010, 0x0036 }, + { 0x0010, 0x0037 }, + { 0x0011, 0x0057 }, + { 0x0012, 0x009c }, + { 0x0012, 0x009d }, + { 0x0012, 0x009e }, + { 0x0014, 0x00ad }, + { 0x0014, 0x00ae }, + { 0x0014, 0x00af }, + { 0x0014, 0x00b0 }, + { 0x0014, 0x00b1 }, + { 0x0014, 0x00b2 }, + { 0x0014, 0x00b3 }, + { 0x0014, 0x00b4 }, + { 0x0014, 0x00b5 }, + { 0x0014, 0x00b6 }, + { 0x0014, 0x00b7 }, + { 0x0014, 0x00b8 }, + { 0x0014, 0x00b9 }, + { 0x0014, 0x00ba }, + { 0x0014, 0x00bb }, + { 0x0014, 0x00bc }, + { 0x0014, 0x00bd }, + { 0x0014, 0x00be }, + { 0x0014, 0x00bf }, + { 0x0012, 0x009f }, + { 0x0011, 0x0058 }, + { 0x0012, 0x00a0 }, + { 0x0014, 0x00c0 }, + { 0x0011, 0x0059 }, + { 0x0013, 0x0114 }, + { 0x0012, 0x00a1 }, + { 0x0014, 0x00c1 }, + { 0x0013, 0x0115 }, + { 0x0014, 0x00c2 }, + { 0x0014, 0x00c3 }, + { 0x0014, 0x00c4 }, + { 0x0014, 0x00c5 }, + { 0x0014, 0x00c6 }, + { 0x0014, 0x00c7 }, + { 0x0014, 0x00c8 }, + { 0x0014, 0x00c9 }, + { 0x0014, 0x00ca }, + { 0x0014, 0x00cb }, + { 0x0014, 0x00cc }, + { 0x0014, 0x00cd }, + { 0x0014, 0x00ce }, + { 0x0014, 0x00cf }, + { 0x0014, 0x00d0 }, + { 0x0014, 0x00d1 }, + { 0x0014, 0x00d2 }, + { 0x0014, 0x00d3 }, + { 0x0014, 0x00d4 }, + { 0x0014, 0x00d5 }, + { 0x0014, 0x00d6 }, + { 0x0014, 0x00d7 }, + { 0x0014, 0x00d8 }, + { 0x0014, 0x00d9 }, + { 0x0014, 0x00da }, + { 0x0014, 0x00db }, + { 0x0014, 0x00dc }, + { 0x0014, 0x00dd }, + { 0x0014, 0x00de }, + { 0x0014, 0x00df }, + { 0x0014, 0x00e0 }, + { 0x0014, 0x00e1 }, + { 0x0014, 0x00e2 }, + { 0x0014, 0x00e3 }, + { 0x0014, 0x00e4 }, + { 0x0014, 0x00e5 }, + { 0x0014, 0x00e6 }, + { 0x0014, 0x00e7 }, + { 0x0014, 0x00e8 }, + { 0x0014, 0x00e9 }, + { 0x0014, 0x00ea }, + { 0x0014, 0x00eb }, + { 0x0014, 0x00ec }, + { 0x0014, 0x00ed }, + { 0x0014, 0x00ee }, + { 0x0014, 0x00ef }, + { 0x0014, 0x00f0 }, + { 0x0014, 0x00f1 }, + { 0x0014, 0x00f2 }, + { 0x0014, 0x00f3 }, + { 0x0014, 0x00f4 }, + { 0x0014, 0x00f5 }, + { 0x0014, 0x00f6 }, + { 0x0014, 0x00f7 }, + { 0x0014, 0x00f8 }, + { 0x0014, 0x00f9 }, + { 0x0014, 0x00fa }, + { 0x0014, 0x00fb }, + { 0x0014, 0x00fc }, + { 0x0014, 0x00fd }, + { 0x0014, 0x00fe }, + { 0x0014, 0x00ff }, + { 0x0014, 0x0100 }, + { 0x0014, 0x0101 }, + { 0x0014, 0x0102 }, + { 0x0014, 0x0103 }, + { 0x0014, 0x0104 }, + { 0x0014, 0x0105 }, + { 0x0014, 0x0106 }, + { 0x0014, 0x0107 }, + { 0x0014, 0x0108 }, + { 0x0014, 0x0109 }, + { 0x0014, 0x010a }, + { 0x0014, 0x010b }, + { 0x0014, 0x010c }, + { 0x0014, 0x010d }, + { 0x0014, 0x010e }, + { 0x0014, 0x010f }, + { 0x0014, 0x0110 }, + { 0x0014, 0x0111 }, + { 0x0014, 0x0112 }, + { 0x0014, 0x0113 }, + { 0x0014, 0x0114 }, + { 0x0014, 0x0115 }, + { 0x0014, 0x0116 }, + { 0x0014, 0x0117 }, + { 0x0014, 0x0118 }, + { 0x0014, 0x0119 }, + { 0x0014, 0x011a }, + { 0x0014, 0x011b }, + { 0x0014, 0x011c }, + { 0x0014, 0x011d }, + { 0x0014, 0x011e }, + { 0x0014, 0x011f }, + { 0x0014, 0x0120 }, + { 0x0014, 0x0121 }, + { 0x0014, 0x0122 }, + { 0x0014, 0x0123 }, + { 0x0014, 0x0124 }, + { 0x0014, 0x0125 }, + { 0x0013, 0x0116 }, + { 0x0014, 0x0126 }, + { 0x0014, 0x0127 }, + { 0x0014, 0x0128 }, + { 0x0014, 0x0129 }, + { 0x0014, 0x012a }, + { 0x0014, 0x012b }, + { 0x0014, 0x012c }, + { 0x0014, 0x012d }, + { 0x0014, 0x012e }, + { 0x0014, 0x012f }, + { 0x0014, 0x0130 }, + { 0x0014, 0x0131 }, + { 0x0014, 0x0132 }, + { 0x0014, 0x0133 }, + { 0x0014, 0x0134 }, + { 0x0014, 0x0135 }, + { 0x0014, 0x0136 }, + { 0x0014, 0x0137 }, + { 0x0014, 0x0138 }, + { 0x0014, 0x0139 }, + { 0x0014, 0x013a }, + { 0x0014, 0x013b }, + { 0x0014, 0x013c }, + { 0x0014, 0x013d }, + { 0x0014, 0x013e }, + { 0x0014, 0x013f }, + { 0x0014, 0x0140 }, + { 0x0014, 0x0141 }, + { 0x0014, 0x0142 }, + { 0x0014, 0x0143 }, + { 0x0014, 0x0144 }, + { 0x0014, 0x0145 }, + { 0x0014, 0x0146 }, + { 0x0014, 0x0147 }, + { 0x0014, 0x0148 }, + { 0x0014, 0x0149 }, + { 0x0014, 0x014a }, + { 0x0014, 0x014b }, + { 0x0014, 0x014c }, + { 0x0014, 0x014d }, + { 0x0014, 0x014e }, + { 0x0014, 0x014f }, + { 0x0014, 0x0150 }, + { 0x0014, 0x0151 }, + { 0x0014, 0x0152 }, + { 0x0014, 0x0153 }, + { 0x0014, 0x0154 }, + { 0x0014, 0x0155 }, + { 0x0014, 0x0156 }, + { 0x0014, 0x0157 }, + { 0x0014, 0x0158 }, + { 0x0014, 0x0159 }, + { 0x0014, 0x015a }, + { 0x0014, 0x015b }, + { 0x0014, 0x015c }, + { 0x0014, 0x015d }, + { 0x0014, 0x015e }, + { 0x0014, 0x015f }, + { 0x0014, 0x0160 }, + { 0x0014, 0x0161 }, + { 0x0014, 0x0162 }, + { 0x0014, 0x0163 }, + { 0x0014, 0x0164 }, + { 0x0014, 0x0165 }, + { 0x0014, 0x0166 }, + { 0x0014, 0x0167 }, + { 0x0014, 0x0168 }, + { 0x0014, 0x0169 }, + { 0x0014, 0x016a }, + { 0x0014, 0x016b }, + { 0x0014, 0x016c }, + { 0x0014, 0x016d }, + { 0x0014, 0x016e }, + { 0x0014, 0x016f }, + { 0x0014, 0x0170 }, + { 0x0014, 0x0171 }, + { 0x0014, 0x0172 }, + { 0x0014, 0x0173 }, + { 0x0014, 0x0174 }, + { 0x0014, 0x0175 }, + { 0x0014, 0x0176 }, + { 0x0014, 0x0177 }, + { 0x0014, 0x0178 }, + { 0x0014, 0x0179 }, + { 0x0014, 0x017a }, + { 0x0014, 0x017b }, + { 0x0014, 0x017c }, + { 0x0014, 0x017d }, + { 0x0014, 0x017e }, + { 0x0014, 0x017f }, + { 0x0014, 0x0180 }, + { 0x0014, 0x0181 }, + { 0x0014, 0x0182 }, + { 0x0014, 0x0183 }, + { 0x0014, 0x0184 }, + { 0x0014, 0x0185 }, + { 0x0014, 0x0186 }, + { 0x0014, 0x0187 }, + { 0x0014, 0x0188 }, + { 0x0014, 0x0189 }, + { 0x0014, 0x018a }, + { 0x0014, 0x018b }, + { 0x0014, 0x018c }, + { 0x0014, 0x018d }, + { 0x0014, 0x018e }, + { 0x0014, 0x018f }, + { 0x0014, 0x0190 }, + { 0x0014, 0x0191 }, + { 0x0014, 0x0192 }, + { 0x0014, 0x0193 }, + { 0x0014, 0x0194 }, + { 0x0014, 0x0195 }, + { 0x0014, 0x0196 }, + { 0x0014, 0x0197 }, + { 0x0014, 0x0198 }, + { 0x0014, 0x0199 }, + { 0x0014, 0x019a }, + { 0x0014, 0x019b }, + { 0x0014, 0x019c }, + { 0x0014, 0x019d }, + { 0x0014, 0x019e }, + { 0x0014, 0x019f }, + { 0x0014, 0x01a0 }, + { 0x0014, 0x01a1 }, + { 0x0014, 0x01a2 }, + { 0x0014, 0x01a3 }, + { 0x0014, 0x01a4 }, + { 0x0014, 0x01a5 }, + { 0x0014, 0x01a6 }, + { 0x0014, 0x01a7 }, + { 0x0014, 0x01a8 }, + { 0x0014, 0x01a9 }, + { 0x0014, 0x01aa }, + { 0x0014, 0x01ab }, + { 0x0014, 0x01ac }, + { 0x0014, 0x01ad }, + { 0x0014, 0x01ae }, + { 0x0014, 0x01af }, + { 0x0014, 0x01b0 }, + { 0x0014, 0x01b1 }, + { 0x0014, 0x01b2 }, + { 0x0014, 0x01b3 }, + { 0x0014, 0x01b4 }, + { 0x0014, 0x01b5 }, + { 0x0014, 0x01b6 }, + { 0x0014, 0x01b7 }, + { 0x0014, 0x01b8 }, + { 0x0014, 0x01b9 }, + { 0x0014, 0x01ba }, + { 0x0014, 0x01bb }, + { 0x0014, 0x01bc }, + { 0x0014, 0x01bd }, + { 0x0014, 0x01be }, + { 0x0014, 0x01bf }, + { 0x0014, 0x01c0 }, + { 0x0014, 0x01c1 }, + { 0x0014, 0x01c2 }, + { 0x0014, 0x01c3 }, + { 0x0014, 0x01c4 }, + { 0x0014, 0x01c5 }, + { 0x0014, 0x01c6 }, + { 0x0014, 0x01c7 }, + { 0x0014, 0x01c8 }, + { 0x0014, 0x01c9 }, + { 0x0014, 0x01ca }, + { 0x0014, 0x01cb }, + { 0x0014, 0x01cc }, + { 0x0014, 0x01cd }, + { 0x0014, 0x01ce }, + { 0x0014, 0x01cf }, + { 0x0014, 0x01d0 }, + { 0x0014, 0x01d1 }, + { 0x0014, 0x01d2 }, + { 0x0014, 0x01d3 }, + { 0x0014, 0x01d4 }, + { 0x0014, 0x01d5 }, + { 0x0014, 0x01d6 }, + { 0x0014, 0x01d7 }, + { 0x0014, 0x01d8 }, + { 0x0014, 0x01d9 }, + { 0x0014, 0x01da }, + { 0x0014, 0x01db }, + { 0x0014, 0x01dc }, + { 0x0014, 0x01dd }, + { 0x0014, 0x01de }, + { 0x0014, 0x01df }, + { 0x0014, 0x01e0 }, + { 0x0014, 0x01e1 }, + { 0x0014, 0x01e2 }, + { 0x0014, 0x01e3 }, + { 0x0014, 0x01e4 }, + { 0x0014, 0x01e5 }, + { 0x0014, 0x01e6 }, + { 0x0014, 0x01e7 }, + { 0x0014, 0x01e8 }, + { 0x0014, 0x01e9 }, + { 0x0014, 0x01ea }, + { 0x0014, 0x01eb }, + { 0x0014, 0x01ec }, + { 0x0014, 0x01ed }, + { 0x0014, 0x01ee }, + { 0x0014, 0x01ef }, + { 0x0014, 0x01f0 }, + { 0x0014, 0x01f1 }, + { 0x0014, 0x01f2 }, + { 0x0014, 0x01f3 }, + { 0x0014, 0x01f4 }, + { 0x0014, 0x01f5 }, + { 0x0014, 0x01f6 }, + { 0x0014, 0x01f7 }, + { 0x0014, 0x01f8 }, + { 0x0014, 0x01f9 }, + { 0x0014, 0x01fa }, + { 0x0014, 0x01fb }, + { 0x0014, 0x01fc }, + { 0x0014, 0x01fd }, + { 0x0014, 0x01fe }, + { 0x0014, 0x01ff }, + { 0x0014, 0x0200 }, + { 0x0014, 0x0201 }, + { 0x0014, 0x0202 }, + { 0x0014, 0x0203 }, + { 0x0014, 0x0204 }, + { 0x0014, 0x0205 }, + { 0x0014, 0x0206 }, + { 0x0014, 0x0207 }, + { 0x0014, 0x0208 }, + { 0x0014, 0x0209 }, + { 0x0014, 0x020a }, + { 0x0014, 0x020b }, + { 0x0014, 0x020c }, + { 0x0014, 0x020d }, + { 0x0014, 0x020e }, + { 0x0014, 0x020f }, + { 0x0014, 0x0210 }, + { 0x0014, 0x0211 }, + { 0x0014, 0x0212 }, + { 0x0014, 0x0213 }, + { 0x0014, 0x0214 }, + { 0x0014, 0x0215 }, + { 0x0013, 0x0117 }, + + }; + + +const uint16_t c_aauiLCLDHuffEnc17[729][2] = + { + { 0x0006, 0x0012 }, + { 0x0006, 0x0013 }, + { 0x0006, 0x0014 }, + { 0x0006, 0x0015 }, + { 0x0007, 0x000f }, + { 0x0007, 0x0010 }, + { 0x0007, 0x0011 }, + { 0x0008, 0x000e }, + { 0x0008, 0x000f }, + { 0x0009, 0x000f }, + { 0x000a, 0x000f }, + { 0x000c, 0x0011 }, + { 0x000d, 0x0014 }, + { 0x000e, 0x0017 }, + { 0x0010, 0x002d }, + { 0x0011, 0x004c }, + { 0x0012, 0x008a }, + { 0x0014, 0x0000 }, + { 0x0014, 0x0001 }, + { 0x0014, 0x0002 }, + { 0x0014, 0x0003 }, + { 0x0014, 0x0004 }, + { 0x0014, 0x0005 }, + { 0x0014, 0x0006 }, + { 0x0014, 0x0007 }, + { 0x0014, 0x0008 }, + { 0x0014, 0x0009 }, + { 0x0006, 0x0016 }, + { 0x0005, 0x0018 }, + { 0x0005, 0x0019 }, + { 0x0005, 0x001a }, + { 0x0006, 0x0017 }, + { 0x0006, 0x0018 }, + { 0x0006, 0x0019 }, + { 0x0007, 0x0012 }, + { 0x0007, 0x0013 }, + { 0x0008, 0x0010 }, + { 0x000a, 0x0010 }, + { 0x000b, 0x0011 }, + { 0x000c, 0x0012 }, + { 0x000e, 0x0018 }, + { 0x000f, 0x0020 }, + { 0x0011, 0x004d }, + { 0x0013, 0x00e4 }, + { 0x0014, 0x000a }, + { 0x0014, 0x000b }, + { 0x0014, 0x000c }, + { 0x0014, 0x000d }, + { 0x0014, 0x000e }, + { 0x0014, 0x000f }, + { 0x0014, 0x0010 }, + { 0x0014, 0x0011 }, + { 0x0014, 0x0012 }, + { 0x0014, 0x0013 }, + { 0x0006, 0x001a }, + { 0x0005, 0x001b }, + { 0x0005, 0x001c }, + { 0x0005, 0x001d }, + { 0x0006, 0x001b }, + { 0x0006, 0x001c }, + { 0x0006, 0x001d }, + { 0x0007, 0x0014 }, + { 0x0008, 0x0011 }, + { 0x0009, 0x0010 }, + { 0x000a, 0x0011 }, + { 0x000b, 0x0012 }, + { 0x000c, 0x0013 }, + { 0x000e, 0x0019 }, + { 0x000f, 0x0021 }, + { 0x0010, 0x002e }, + { 0x0013, 0x00e5 }, + { 0x0013, 0x00e6 }, + { 0x0014, 0x0014 }, + { 0x0014, 0x0015 }, + { 0x0014, 0x0016 }, + { 0x0014, 0x0017 }, + { 0x0014, 0x0018 }, + { 0x0014, 0x0019 }, + { 0x0014, 0x001a }, + { 0x0014, 0x001b }, + { 0x0014, 0x001c }, + { 0x0006, 0x001e }, + { 0x0005, 0x001e }, + { 0x0005, 0x001f }, + { 0x0006, 0x001f }, + { 0x0006, 0x0020 }, + { 0x0006, 0x0021 }, + { 0x0006, 0x0022 }, + { 0x0007, 0x0015 }, + { 0x0008, 0x0012 }, + { 0x0009, 0x0011 }, + { 0x000a, 0x0012 }, + { 0x000b, 0x0013 }, + { 0x000c, 0x0014 }, + { 0x000e, 0x001a }, + { 0x000f, 0x0022 }, + { 0x0010, 0x002f }, + { 0x0013, 0x00e7 }, + { 0x0013, 0x00e8 }, + { 0x0014, 0x001d }, + { 0x0014, 0x001e }, + { 0x0014, 0x001f }, + { 0x0014, 0x0020 }, + { 0x0014, 0x0021 }, + { 0x0014, 0x0022 }, + { 0x0014, 0x0023 }, + { 0x0014, 0x0024 }, + { 0x0014, 0x0025 }, + { 0x0006, 0x0023 }, + { 0x0006, 0x0024 }, + { 0x0006, 0x0025 }, + { 0x0006, 0x0026 }, + { 0x0006, 0x0027 }, + { 0x0006, 0x0028 }, + { 0x0007, 0x0016 }, + { 0x0007, 0x0017 }, + { 0x0008, 0x0013 }, + { 0x0009, 0x0012 }, + { 0x000a, 0x0013 }, + { 0x000c, 0x0015 }, + { 0x000d, 0x0015 }, + { 0x000f, 0x0023 }, + { 0x0010, 0x0030 }, + { 0x0011, 0x004e }, + { 0x0014, 0x0026 }, + { 0x0014, 0x0027 }, + { 0x0014, 0x0028 }, + { 0x0014, 0x0029 }, + { 0x0014, 0x002a }, + { 0x0014, 0x002b }, + { 0x0014, 0x002c }, + { 0x0014, 0x002d }, + { 0x0014, 0x002e }, + { 0x0014, 0x002f }, + { 0x0014, 0x0030 }, + { 0x0007, 0x0018 }, + { 0x0006, 0x0029 }, + { 0x0006, 0x002a }, + { 0x0006, 0x002b }, + { 0x0006, 0x002c }, + { 0x0007, 0x0019 }, + { 0x0007, 0x001a }, + { 0x0008, 0x0014 }, + { 0x0009, 0x0013 }, + { 0x000a, 0x0014 }, + { 0x000b, 0x0014 }, + { 0x000c, 0x0016 }, + { 0x000d, 0x0016 }, + { 0x000f, 0x0024 }, + { 0x0010, 0x0031 }, + { 0x0011, 0x004f }, + { 0x0014, 0x0031 }, + { 0x0014, 0x0032 }, + { 0x0014, 0x0033 }, + { 0x0014, 0x0034 }, + { 0x0014, 0x0035 }, + { 0x0014, 0x0036 }, + { 0x0014, 0x0037 }, + { 0x0014, 0x0038 }, + { 0x0014, 0x0039 }, + { 0x0014, 0x003a }, + { 0x0014, 0x003b }, + { 0x0007, 0x001b }, + { 0x0006, 0x002d }, + { 0x0006, 0x002e }, + { 0x0006, 0x002f }, + { 0x0007, 0x001c }, + { 0x0007, 0x001d }, + { 0x0008, 0x0015 }, + { 0x0009, 0x0014 }, + { 0x000a, 0x0015 }, + { 0x000a, 0x0016 }, + { 0x000c, 0x0017 }, + { 0x000d, 0x0017 }, + { 0x000e, 0x001b }, + { 0x000f, 0x0025 }, + { 0x0011, 0x0050 }, + { 0x0011, 0x0051 }, + { 0x0014, 0x003c }, + { 0x0014, 0x003d }, + { 0x0014, 0x003e }, + { 0x0014, 0x003f }, + { 0x0014, 0x0040 }, + { 0x0014, 0x0041 }, + { 0x0014, 0x0042 }, + { 0x0014, 0x0043 }, + { 0x0014, 0x0044 }, + { 0x0014, 0x0045 }, + { 0x0014, 0x0046 }, + { 0x0008, 0x0016 }, + { 0x0007, 0x001e }, + { 0x0007, 0x001f }, + { 0x0007, 0x0020 }, + { 0x0007, 0x0021 }, + { 0x0008, 0x0017 }, + { 0x0008, 0x0018 }, + { 0x0009, 0x0015 }, + { 0x000a, 0x0017 }, + { 0x000b, 0x0015 }, + { 0x000c, 0x0018 }, + { 0x000e, 0x001c }, + { 0x000e, 0x001d }, + { 0x0010, 0x0032 }, + { 0x0012, 0x008b }, + { 0x0012, 0x008c }, + { 0x0014, 0x0047 }, + { 0x0014, 0x0048 }, + { 0x0014, 0x0049 }, + { 0x0014, 0x004a }, + { 0x0014, 0x004b }, + { 0x0014, 0x004c }, + { 0x0014, 0x004d }, + { 0x0014, 0x004e }, + { 0x0014, 0x004f }, + { 0x0014, 0x0050 }, + { 0x0014, 0x0051 }, + { 0x0008, 0x0019 }, + { 0x0007, 0x0022 }, + { 0x0007, 0x0023 }, + { 0x0008, 0x001a }, + { 0x0008, 0x001b }, + { 0x0009, 0x0016 }, + { 0x0009, 0x0017 }, + { 0x000a, 0x0018 }, + { 0x000b, 0x0016 }, + { 0x000c, 0x0019 }, + { 0x000d, 0x0018 }, + { 0x000e, 0x001e }, + { 0x0010, 0x0033 }, + { 0x0011, 0x0052 }, + { 0x0014, 0x0052 }, + { 0x0013, 0x00e9 }, + { 0x0014, 0x0053 }, + { 0x0014, 0x0054 }, + { 0x0014, 0x0055 }, + { 0x0014, 0x0056 }, + { 0x0014, 0x0057 }, + { 0x0014, 0x0058 }, + { 0x0014, 0x0059 }, + { 0x0014, 0x005a }, + { 0x0014, 0x005b }, + { 0x0014, 0x005c }, + { 0x0014, 0x005d }, + { 0x0009, 0x0018 }, + { 0x0008, 0x001c }, + { 0x0008, 0x001d }, + { 0x0009, 0x0019 }, + { 0x0009, 0x001a }, + { 0x000a, 0x0019 }, + { 0x000a, 0x001a }, + { 0x000b, 0x0017 }, + { 0x000c, 0x001a }, + { 0x000d, 0x0019 }, + { 0x000e, 0x001f }, + { 0x000f, 0x0026 }, + { 0x0010, 0x0034 }, + { 0x0012, 0x008d }, + { 0x0013, 0x00ea }, + { 0x0014, 0x005e }, + { 0x0014, 0x005f }, + { 0x0014, 0x0060 }, + { 0x0014, 0x0061 }, + { 0x0014, 0x0062 }, + { 0x0014, 0x0063 }, + { 0x0014, 0x0064 }, + { 0x0014, 0x0065 }, + { 0x0014, 0x0066 }, + { 0x0014, 0x0067 }, + { 0x0014, 0x0068 }, + { 0x0014, 0x0069 }, + { 0x000b, 0x0018 }, + { 0x0009, 0x001b }, + { 0x000a, 0x001b }, + { 0x000a, 0x001c }, + { 0x000a, 0x001d }, + { 0x000b, 0x0019 }, + { 0x000b, 0x001a }, + { 0x000c, 0x001b }, + { 0x000d, 0x001a }, + { 0x000e, 0x0020 }, + { 0x000f, 0x0027 }, + { 0x0012, 0x008e }, + { 0x0011, 0x0053 }, + { 0x0013, 0x00eb }, + { 0x0014, 0x006a }, + { 0x0014, 0x006b }, + { 0x0014, 0x006c }, + { 0x0014, 0x006d }, + { 0x0014, 0x006e }, + { 0x0014, 0x006f }, + { 0x0014, 0x0070 }, + { 0x0014, 0x0071 }, + { 0x0014, 0x0072 }, + { 0x0014, 0x0073 }, + { 0x0014, 0x0074 }, + { 0x0014, 0x0075 }, + { 0x0014, 0x0076 }, + { 0x000c, 0x001c }, + { 0x000b, 0x001b }, + { 0x000b, 0x001c }, + { 0x000b, 0x001d }, + { 0x000c, 0x001d }, + { 0x000c, 0x001e }, + { 0x000d, 0x001b }, + { 0x000d, 0x001c }, + { 0x000e, 0x0021 }, + { 0x0010, 0x0035 }, + { 0x0010, 0x0036 }, + { 0x0011, 0x0054 }, + { 0x0013, 0x00ec }, + { 0x0014, 0x0077 }, + { 0x0014, 0x0078 }, + { 0x0014, 0x0079 }, + { 0x0014, 0x007a }, + { 0x0014, 0x007b }, + { 0x0014, 0x007c }, + { 0x0014, 0x007d }, + { 0x0014, 0x007e }, + { 0x0014, 0x007f }, + { 0x0014, 0x0080 }, + { 0x0014, 0x0081 }, + { 0x0014, 0x0082 }, + { 0x0014, 0x0083 }, + { 0x0014, 0x0084 }, + { 0x000d, 0x001d }, + { 0x000c, 0x001f }, + { 0x000c, 0x0020 }, + { 0x000c, 0x0021 }, + { 0x000d, 0x001e }, + { 0x000d, 0x001f }, + { 0x000e, 0x0022 }, + { 0x000f, 0x0028 }, + { 0x0010, 0x0037 }, + { 0x0010, 0x0038 }, + { 0x0010, 0x0039 }, + { 0x0012, 0x008f }, + { 0x0013, 0x00ed }, + { 0x0014, 0x0085 }, + { 0x0014, 0x0086 }, + { 0x0014, 0x0087 }, + { 0x0014, 0x0088 }, + { 0x0014, 0x0089 }, + { 0x0014, 0x008a }, + { 0x0014, 0x008b }, + { 0x0014, 0x008c }, + { 0x0014, 0x008d }, + { 0x0014, 0x008e }, + { 0x0014, 0x008f }, + { 0x0014, 0x0090 }, + { 0x0014, 0x0091 }, + { 0x0014, 0x0092 }, + { 0x000e, 0x0023 }, + { 0x000d, 0x0020 }, + { 0x000d, 0x0021 }, + { 0x000e, 0x0024 }, + { 0x000e, 0x0025 }, + { 0x000e, 0x0026 }, + { 0x000f, 0x0029 }, + { 0x0010, 0x003a }, + { 0x0010, 0x003b }, + { 0x0012, 0x0090 }, + { 0x0014, 0x0093 }, + { 0x0014, 0x0094 }, + { 0x0014, 0x0095 }, + { 0x0014, 0x0096 }, + { 0x0014, 0x0097 }, + { 0x0014, 0x0098 }, + { 0x0014, 0x0099 }, + { 0x0014, 0x009a }, + { 0x0014, 0x009b }, + { 0x0014, 0x009c }, + { 0x0014, 0x009d }, + { 0x0014, 0x009e }, + { 0x0014, 0x009f }, + { 0x0014, 0x00a0 }, + { 0x0014, 0x00a1 }, + { 0x0014, 0x00a2 }, + { 0x0014, 0x00a3 }, + { 0x000f, 0x002a }, + { 0x000e, 0x0027 }, + { 0x000f, 0x002b }, + { 0x000f, 0x002c }, + { 0x000f, 0x002d }, + { 0x0010, 0x003c }, + { 0x0010, 0x003d }, + { 0x0011, 0x0055 }, + { 0x0011, 0x0056 }, + { 0x0014, 0x00a4 }, + { 0x0014, 0x00a5 }, + { 0x0014, 0x00a6 }, + { 0x0014, 0x00a7 }, + { 0x0014, 0x00a8 }, + { 0x0014, 0x00a9 }, + { 0x0014, 0x00aa }, + { 0x0014, 0x00ab }, + { 0x0014, 0x00ac }, + { 0x0014, 0x00ad }, + { 0x0014, 0x00ae }, + { 0x0014, 0x00af }, + { 0x0014, 0x00b0 }, + { 0x0014, 0x00b1 }, + { 0x0014, 0x00b2 }, + { 0x0014, 0x00b3 }, + { 0x0014, 0x00b4 }, + { 0x0014, 0x00b5 }, + { 0x0012, 0x0091 }, + { 0x0010, 0x003e }, + { 0x0010, 0x003f }, + { 0x0011, 0x0057 }, + { 0x0011, 0x0058 }, + { 0x0011, 0x0059 }, + { 0x0012, 0x0092 }, + { 0x0013, 0x00ee }, + { 0x0013, 0x00ef }, + { 0x0012, 0x0093 }, + { 0x0014, 0x00b6 }, + { 0x0014, 0x00b7 }, + { 0x0014, 0x00b8 }, + { 0x0014, 0x00b9 }, + { 0x0014, 0x00ba }, + { 0x0014, 0x00bb }, + { 0x0014, 0x00bc }, + { 0x0014, 0x00bd }, + { 0x0014, 0x00be }, + { 0x0014, 0x00bf }, + { 0x0014, 0x00c0 }, + { 0x0014, 0x00c1 }, + { 0x0014, 0x00c2 }, + { 0x0014, 0x00c3 }, + { 0x0014, 0x00c4 }, + { 0x0014, 0x00c5 }, + { 0x0014, 0x00c6 }, + { 0x0013, 0x00f0 }, + { 0x0012, 0x0094 }, + { 0x0012, 0x0095 }, + { 0x0012, 0x0096 }, + { 0x0014, 0x00c7 }, + { 0x0014, 0x00c8 }, + { 0x0014, 0x00c9 }, + { 0x0014, 0x00ca }, + { 0x0014, 0x00cb }, + { 0x0014, 0x00cc }, + { 0x0014, 0x00cd }, + { 0x0014, 0x00ce }, + { 0x0014, 0x00cf }, + { 0x0014, 0x00d0 }, + { 0x0014, 0x00d1 }, + { 0x0014, 0x00d2 }, + { 0x0014, 0x00d3 }, + { 0x0014, 0x00d4 }, + { 0x0014, 0x00d5 }, + { 0x0014, 0x00d6 }, + { 0x0014, 0x00d7 }, + { 0x0014, 0x00d8 }, + { 0x0014, 0x00d9 }, + { 0x0014, 0x00da }, + { 0x0014, 0x00db }, + { 0x0014, 0x00dc }, + { 0x0014, 0x00dd }, + { 0x0014, 0x00de }, + { 0x0012, 0x0097 }, + { 0x0014, 0x00df }, + { 0x0014, 0x00e0 }, + { 0x0014, 0x00e1 }, + { 0x0014, 0x00e2 }, + { 0x0014, 0x00e3 }, + { 0x0014, 0x00e4 }, + { 0x0014, 0x00e5 }, + { 0x0014, 0x00e6 }, + { 0x0014, 0x00e7 }, + { 0x0014, 0x00e8 }, + { 0x0014, 0x00e9 }, + { 0x0014, 0x00ea }, + { 0x0014, 0x00eb }, + { 0x0014, 0x00ec }, + { 0x0014, 0x00ed }, + { 0x0014, 0x00ee }, + { 0x0014, 0x00ef }, + { 0x0014, 0x00f0 }, + { 0x0014, 0x00f1 }, + { 0x0014, 0x00f2 }, + { 0x0014, 0x00f3 }, + { 0x0014, 0x00f4 }, + { 0x0014, 0x00f5 }, + { 0x0014, 0x00f6 }, + { 0x0014, 0x00f7 }, + { 0x0014, 0x00f8 }, + { 0x0014, 0x00f9 }, + { 0x0014, 0x00fa }, + { 0x0014, 0x00fb }, + { 0x0014, 0x00fc }, + { 0x0014, 0x00fd }, + { 0x0014, 0x00fe }, + { 0x0014, 0x00ff }, + { 0x0014, 0x0100 }, + { 0x0014, 0x0101 }, + { 0x0014, 0x0102 }, + { 0x0014, 0x0103 }, + { 0x0014, 0x0104 }, + { 0x0014, 0x0105 }, + { 0x0014, 0x0106 }, + { 0x0014, 0x0107 }, + { 0x0014, 0x0108 }, + { 0x0014, 0x0109 }, + { 0x0014, 0x010a }, + { 0x0014, 0x010b }, + { 0x0014, 0x010c }, + { 0x0014, 0x010d }, + { 0x0014, 0x010e }, + { 0x0014, 0x010f }, + { 0x0014, 0x0110 }, + { 0x0014, 0x0111 }, + { 0x0014, 0x0112 }, + { 0x0014, 0x0113 }, + { 0x0014, 0x0114 }, + { 0x0014, 0x0115 }, + { 0x0014, 0x0116 }, + { 0x0014, 0x0117 }, + { 0x0014, 0x0118 }, + { 0x0014, 0x0119 }, + { 0x0014, 0x011a }, + { 0x0014, 0x011b }, + { 0x0014, 0x011c }, + { 0x0014, 0x011d }, + { 0x0014, 0x011e }, + { 0x0014, 0x011f }, + { 0x0014, 0x0120 }, + { 0x0014, 0x0121 }, + { 0x0014, 0x0122 }, + { 0x0014, 0x0123 }, + { 0x0014, 0x0124 }, + { 0x0014, 0x0125 }, + { 0x0014, 0x0126 }, + { 0x0014, 0x0127 }, + { 0x0014, 0x0128 }, + { 0x0014, 0x0129 }, + { 0x0014, 0x012a }, + { 0x0014, 0x012b }, + { 0x0014, 0x012c }, + { 0x0014, 0x012d }, + { 0x0014, 0x012e }, + { 0x0014, 0x012f }, + { 0x0014, 0x0130 }, + { 0x0014, 0x0131 }, + { 0x0014, 0x0132 }, + { 0x0014, 0x0133 }, + { 0x0014, 0x0134 }, + { 0x0014, 0x0135 }, + { 0x0014, 0x0136 }, + { 0x0014, 0x0137 }, + { 0x0014, 0x0138 }, + { 0x0014, 0x0139 }, + { 0x0014, 0x013a }, + { 0x0014, 0x013b }, + { 0x0014, 0x013c }, + { 0x0014, 0x013d }, + { 0x0014, 0x013e }, + { 0x0014, 0x013f }, + { 0x0014, 0x0140 }, + { 0x0014, 0x0141 }, + { 0x0014, 0x0142 }, + { 0x0014, 0x0143 }, + { 0x0014, 0x0144 }, + { 0x0014, 0x0145 }, + { 0x0014, 0x0146 }, + { 0x0014, 0x0147 }, + { 0x0014, 0x0148 }, + { 0x0014, 0x0149 }, + { 0x0014, 0x014a }, + { 0x0014, 0x014b }, + { 0x0014, 0x014c }, + { 0x0014, 0x014d }, + { 0x0014, 0x014e }, + { 0x0014, 0x014f }, + { 0x0014, 0x0150 }, + { 0x0014, 0x0151 }, + { 0x0014, 0x0152 }, + { 0x0014, 0x0153 }, + { 0x0014, 0x0154 }, + { 0x0014, 0x0155 }, + { 0x0014, 0x0156 }, + { 0x0014, 0x0157 }, + { 0x0014, 0x0158 }, + { 0x0014, 0x0159 }, + { 0x0014, 0x015a }, + { 0x0014, 0x015b }, + { 0x0014, 0x015c }, + { 0x0014, 0x015d }, + { 0x0014, 0x015e }, + { 0x0014, 0x015f }, + { 0x0014, 0x0160 }, + { 0x0014, 0x0161 }, + { 0x0014, 0x0162 }, + { 0x0014, 0x0163 }, + { 0x0014, 0x0164 }, + { 0x0014, 0x0165 }, + { 0x0014, 0x0166 }, + { 0x0014, 0x0167 }, + { 0x0014, 0x0168 }, + { 0x0014, 0x0169 }, + { 0x0014, 0x016a }, + { 0x0014, 0x016b }, + { 0x0014, 0x016c }, + { 0x0014, 0x016d }, + { 0x0014, 0x016e }, + { 0x0014, 0x016f }, + { 0x0014, 0x0170 }, + { 0x0014, 0x0171 }, + { 0x0014, 0x0172 }, + { 0x0014, 0x0173 }, + { 0x0014, 0x0174 }, + { 0x0014, 0x0175 }, + { 0x0014, 0x0176 }, + { 0x0014, 0x0177 }, + { 0x0014, 0x0178 }, + { 0x0014, 0x0179 }, + { 0x0014, 0x017a }, + { 0x0014, 0x017b }, + { 0x0014, 0x017c }, + { 0x0014, 0x017d }, + { 0x0014, 0x017e }, + { 0x0014, 0x017f }, + { 0x0014, 0x0180 }, + { 0x0014, 0x0181 }, + { 0x0014, 0x0182 }, + { 0x0014, 0x0183 }, + { 0x0014, 0x0184 }, + { 0x0014, 0x0185 }, + { 0x0014, 0x0186 }, + { 0x0014, 0x0187 }, + { 0x0014, 0x0188 }, + { 0x0014, 0x0189 }, + { 0x0014, 0x018a }, + { 0x0014, 0x018b }, + { 0x0014, 0x018c }, + { 0x0014, 0x018d }, + { 0x0014, 0x018e }, + { 0x0014, 0x018f }, + { 0x0014, 0x0190 }, + { 0x0014, 0x0191 }, + { 0x0014, 0x0192 }, + { 0x0014, 0x0193 }, + { 0x0014, 0x0194 }, + { 0x0014, 0x0195 }, + { 0x0014, 0x0196 }, + { 0x0014, 0x0197 }, + { 0x0014, 0x0198 }, + { 0x0014, 0x0199 }, + { 0x0014, 0x019a }, + { 0x0014, 0x019b }, + { 0x0014, 0x019c }, + { 0x0014, 0x019d }, + { 0x0014, 0x019e }, + { 0x0014, 0x019f }, + { 0x0014, 0x01a0 }, + { 0x0014, 0x01a1 }, + { 0x0014, 0x01a2 }, + { 0x0014, 0x01a3 }, + { 0x0014, 0x01a4 }, + { 0x0014, 0x01a5 }, + { 0x0014, 0x01a6 }, + { 0x0014, 0x01a7 }, + { 0x0014, 0x01a8 }, + { 0x0014, 0x01a9 }, + { 0x0014, 0x01aa }, + { 0x0014, 0x01ab }, + { 0x0014, 0x01ac }, + { 0x0014, 0x01ad }, + { 0x0014, 0x01ae }, + { 0x0014, 0x01af }, + { 0x0014, 0x01b0 }, + { 0x0014, 0x01b1 }, + { 0x0014, 0x01b2 }, + { 0x0014, 0x01b3 }, + { 0x0014, 0x01b4 }, + { 0x0014, 0x01b5 }, + { 0x0014, 0x01b6 }, + { 0x0014, 0x01b7 }, + { 0x0014, 0x01b8 }, + { 0x0014, 0x01b9 }, + { 0x0014, 0x01ba }, + { 0x0014, 0x01bb }, + { 0x0014, 0x01bc }, + { 0x0014, 0x01bd }, + { 0x0014, 0x01be }, + { 0x0014, 0x01bf }, + { 0x0014, 0x01c0 }, + { 0x0014, 0x01c1 }, + { 0x0014, 0x01c2 }, + { 0x0014, 0x01c3 }, + { 0x0014, 0x01c4 }, + { 0x0014, 0x01c5 }, + { 0x0014, 0x01c6 }, + { 0x0014, 0x01c7 }, + { 0x0013, 0x00f1 }, + { 0x0013, 0x00f2 }, + { 0x0013, 0x00f3 }, + { 0x0013, 0x00f4 }, + { 0x0013, 0x00f5 }, + { 0x0013, 0x00f6 }, + { 0x0013, 0x00f7 }, + { 0x0013, 0x00f8 }, + { 0x0013, 0x00f9 }, + { 0x0013, 0x00fa }, + { 0x0013, 0x00fb }, + { 0x0013, 0x00fc }, + { 0x0013, 0x00fd }, + { 0x0013, 0x00fe }, + { 0x0013, 0x00ff }, + { 0x0013, 0x0100 }, + { 0x0013, 0x0101 }, + { 0x0013, 0x0102 }, + { 0x0013, 0x0103 }, + { 0x0013, 0x0104 }, + { 0x0013, 0x0105 }, + { 0x0013, 0x0106 }, + { 0x0013, 0x0107 }, + { 0x0013, 0x0108 }, + { 0x0013, 0x0109 }, + { 0x0013, 0x010a }, + { 0x0013, 0x010b }, + { 0x0013, 0x010c }, + { 0x0013, 0x010d }, + { 0x0013, 0x010e }, + { 0x0013, 0x010f }, + { 0x0013, 0x0110 }, + { 0x0013, 0x0111 }, + { 0x0013, 0x0112 }, + { 0x0013, 0x0113 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc18[28][2] = + { + { 0x0004, 0x0001 }, + { 0x0003, 0x0002 }, + { 0x0003, 0x0003 }, + { 0x0003, 0x0004 }, + { 0x0003, 0x0005 }, + { 0x0003, 0x0006 }, + { 0x0003, 0x0007 }, + { 0x0004, 0x0002 }, + { 0x0004, 0x0003 }, + { 0x0005, 0x0001 }, + { 0x0006, 0x0001 }, + { 0x0007, 0x0001 }, + { 0x0008, 0x0001 }, + { 0x0009, 0x0001 }, + { 0x000a, 0x0001 }, + { 0x000b, 0x0001 }, + { 0x000c, 0x0001 }, + { 0x000d, 0x0001 }, + { 0x000e, 0x0001 }, + { 0x000f, 0x0001 }, + { 0x0011, 0x0003 }, + { 0x0012, 0x0001 }, + { 0x0012, 0x0002 }, + { 0x0012, 0x0003 }, + { 0x0013, 0x0000 }, + { 0x0013, 0x0001 }, + { 0x0012, 0x0004 }, + { 0x0012, 0x0005 }, + + }; + + +const uint16_t c_aauiLCLDHuffEnc19[29][2] = + { + { 0x0004, 0x0002 }, + { 0x0003, 0x0003 }, + { 0x0003, 0x0004 }, + { 0x0003, 0x0005 }, + { 0x0003, 0x0006 }, + { 0x0003, 0x0007 }, + { 0x0004, 0x0003 }, + { 0x0004, 0x0004 }, + { 0x0004, 0x0005 }, + { 0x0005, 0x0001 }, + { 0x0005, 0x0002 }, + { 0x0005, 0x0003 }, + { 0x0006, 0x0001 }, + { 0x0007, 0x0001 }, + { 0x0008, 0x0001 }, + { 0x0009, 0x0001 }, + { 0x000a, 0x0001 }, + { 0x000b, 0x0001 }, + { 0x000c, 0x0001 }, + { 0x000d, 0x0001 }, + { 0x000e, 0x0001 }, + { 0x000f, 0x0001 }, + { 0x0010, 0x0001 }, + { 0x0012, 0x0002 }, + { 0x0013, 0x0000 }, + { 0x0013, 0x0001 }, + { 0x0013, 0x0002 }, + { 0x0013, 0x0003 }, + { 0x0012, 0x0003 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc20[32][2] = + { + { 0x0004, 0x0002 }, + { 0x0003, 0x0005 }, + { 0x0003, 0x0006 }, + { 0x0003, 0x0007 }, + { 0x0004, 0x0003 }, + { 0x0004, 0x0004 }, + { 0x0004, 0x0005 }, + { 0x0004, 0x0006 }, + { 0x0004, 0x0007 }, + { 0x0004, 0x0008 }, + { 0x0004, 0x0009 }, + { 0x0005, 0x0002 }, + { 0x0005, 0x0003 }, + { 0x0006, 0x0001 }, + { 0x0006, 0x0002 }, + { 0x0006, 0x0003 }, + { 0x0007, 0x0001 }, + { 0x0008, 0x0001 }, + { 0x0009, 0x0001 }, + { 0x000a, 0x0001 }, + { 0x000b, 0x0001 }, + { 0x000c, 0x0001 }, + { 0x000d, 0x0001 }, + { 0x000e, 0x0001 }, + { 0x000f, 0x0001 }, + { 0x0010, 0x0001 }, + { 0x0011, 0x0001 }, + { 0x0014, 0x0000 }, + { 0x0014, 0x0001 }, + { 0x0013, 0x0001 }, + { 0x0013, 0x0002 }, + { 0x0013, 0x0003 }, + }; + +const uint16_t c_aauiLCLDHuffEnc21[37][2] = + { + { 0x0005, 0x0002 }, + { 0x0003, 0x0006 }, + { 0x0003, 0x0007 }, + { 0x0004, 0x0003 }, + { 0x0004, 0x0004 }, + { 0x0004, 0x0005 }, + { 0x0004, 0x0006 }, + { 0x0004, 0x0007 }, + { 0x0004, 0x0008 }, + { 0x0004, 0x0009 }, + { 0x0004, 0x000a }, + { 0x0004, 0x000b }, + { 0x0005, 0x0003 }, + { 0x0005, 0x0004 }, + { 0x0005, 0x0005 }, + { 0x0006, 0x0002 }, + { 0x0006, 0x0003 }, + { 0x0007, 0x0002 }, + { 0x0007, 0x0003 }, + { 0x0008, 0x0001 }, + { 0x0008, 0x0002 }, + { 0x0008, 0x0003 }, + { 0x0009, 0x0001 }, + { 0x000b, 0x0001 }, + { 0x000b, 0x0002 }, + { 0x000b, 0x0003 }, + { 0x000c, 0x0001 }, + { 0x000d, 0x0001 }, + { 0x000e, 0x0001 }, + { 0x000f, 0x0001 }, + { 0x0010, 0x0001 }, + { 0x0011, 0x0001 }, + { 0x0014, 0x0000 }, + { 0x0014, 0x0001 }, + { 0x0013, 0x0001 }, + { 0x0013, 0x0002 }, + { 0x0013, 0x0003 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc22[39][2] = + { + { 0x0005, 0x0002 }, + { 0x0004, 0x0004 }, + { 0x0004, 0x0005 }, + { 0x0004, 0x0006 }, + { 0x0004, 0x0007 }, + { 0x0004, 0x0008 }, + { 0x0004, 0x0009 }, + { 0x0004, 0x000a }, + { 0x0004, 0x000b }, + { 0x0004, 0x000c }, + { 0x0004, 0x000d }, + { 0x0004, 0x000e }, + { 0x0004, 0x000f }, + { 0x0005, 0x0003 }, + { 0x0005, 0x0004 }, + { 0x0005, 0x0005 }, + { 0x0005, 0x0006 }, + { 0x0005, 0x0007 }, + { 0x0006, 0x0002 }, + { 0x0006, 0x0003 }, + { 0x0007, 0x0002 }, + { 0x0007, 0x0003 }, + { 0x0008, 0x0002 }, + { 0x0008, 0x0003 }, + { 0x0009, 0x0002 }, + { 0x0009, 0x0003 }, + { 0x000a, 0x0001 }, + { 0x000a, 0x0002 }, + { 0x000a, 0x0003 }, + { 0x000c, 0x0001 }, + { 0x000c, 0x0002 }, + { 0x000c, 0x0003 }, + { 0x000e, 0x0001 }, + { 0x000e, 0x0002 }, + { 0x000f, 0x0001 }, + { 0x000e, 0x0003 }, + { 0x0011, 0x0000 }, + { 0x0010, 0x0001 }, + { 0x0011, 0x0001 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc23[46][2] = + { + { 0x0005, 0x0003 }, + { 0x0004, 0x0006 }, + { 0x0004, 0x0007 }, + { 0x0004, 0x0008 }, + { 0x0004, 0x0009 }, + { 0x0004, 0x000a }, + { 0x0004, 0x000b }, + { 0x0004, 0x000c }, + { 0x0004, 0x000d }, + { 0x0004, 0x000e }, + { 0x0004, 0x000f }, + { 0x0005, 0x0004 }, + { 0x0005, 0x0005 }, + { 0x0005, 0x0006 }, + { 0x0005, 0x0007 }, + { 0x0005, 0x0008 }, + { 0x0005, 0x0009 }, + { 0x0005, 0x000a }, + { 0x0005, 0x000b }, + { 0x0006, 0x0003 }, + { 0x0006, 0x0004 }, + { 0x0006, 0x0005 }, + { 0x0007, 0x0002 }, + { 0x0007, 0x0003 }, + { 0x0007, 0x0004 }, + { 0x0007, 0x0005 }, + { 0x0008, 0x0002 }, + { 0x0008, 0x0003 }, + { 0x0009, 0x0002 }, + { 0x0009, 0x0003 }, + { 0x000a, 0x0002 }, + { 0x000a, 0x0003 }, + { 0x000b, 0x0002 }, + { 0x000b, 0x0003 }, + { 0x000c, 0x0002 }, + { 0x000c, 0x0003 }, + { 0x000d, 0x0002 }, + { 0x000d, 0x0003 }, + { 0x000e, 0x0001 }, + { 0x000e, 0x0002 }, + { 0x000e, 0x0003 }, + { 0x000f, 0x0001 }, + { 0x0010, 0x0001 }, + { 0x0012, 0x0000 }, + { 0x0012, 0x0001 }, + { 0x0011, 0x0001 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc24[55][2] = + { + { 0x0005, 0x0004 }, + { 0x0004, 0x0009 }, + { 0x0004, 0x000a }, + { 0x0004, 0x000b }, + { 0x0004, 0x000c }, + { 0x0004, 0x000d }, + { 0x0004, 0x000e }, + { 0x0004, 0x000f }, + { 0x0005, 0x0005 }, + { 0x0005, 0x0006 }, + { 0x0005, 0x0007 }, + { 0x0005, 0x0008 }, + { 0x0005, 0x0009 }, + { 0x0005, 0x000a }, + { 0x0005, 0x000b }, + { 0x0005, 0x000c }, + { 0x0005, 0x000d }, + { 0x0005, 0x000e }, + { 0x0005, 0x000f }, + { 0x0005, 0x0010 }, + { 0x0005, 0x0011 }, + { 0x0006, 0x0003 }, + { 0x0006, 0x0004 }, + { 0x0006, 0x0005 }, + { 0x0006, 0x0006 }, + { 0x0006, 0x0007 }, + { 0x0007, 0x0003 }, + { 0x0007, 0x0004 }, + { 0x0007, 0x0005 }, + { 0x0008, 0x0003 }, + { 0x0008, 0x0004 }, + { 0x0008, 0x0005 }, + { 0x0009, 0x0002 }, + { 0x0009, 0x0003 }, + { 0x0009, 0x0004 }, + { 0x0009, 0x0005 }, + { 0x000a, 0x0002 }, + { 0x000a, 0x0003 }, + { 0x000b, 0x0002 }, + { 0x000b, 0x0003 }, + { 0x000c, 0x0003 }, + { 0x000d, 0x0002 }, + { 0x000d, 0x0003 }, + { 0x000d, 0x0004 }, + { 0x000d, 0x0005 }, + { 0x000e, 0x0002 }, + { 0x000e, 0x0003 }, + { 0x000f, 0x0001 }, + { 0x000f, 0x0002 }, + { 0x000f, 0x0003 }, + { 0x0010, 0x0001 }, + { 0x0011, 0x0001 }, + { 0x0013, 0x0000 }, + { 0x0012, 0x0001 }, + { 0x0013, 0x0001 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc25[65][2] = + { + { 0x0005, 0x0005 }, + { 0x0004, 0x000c }, + { 0x0004, 0x000d }, + { 0x0004, 0x000e }, + { 0x0005, 0x0006 }, + { 0x0004, 0x000f }, + { 0x0005, 0x0007 }, + { 0x0005, 0x0008 }, + { 0x0005, 0x0009 }, + { 0x0005, 0x000a }, + { 0x0005, 0x000b }, + { 0x0005, 0x000c }, + { 0x0005, 0x000d }, + { 0x0005, 0x000e }, + { 0x0005, 0x000f }, + { 0x0005, 0x0010 }, + { 0x0005, 0x0011 }, + { 0x0005, 0x0012 }, + { 0x0005, 0x0013 }, + { 0x0005, 0x0014 }, + { 0x0005, 0x0015 }, + { 0x0005, 0x0016 }, + { 0x0005, 0x0017 }, + { 0x0006, 0x0004 }, + { 0x0006, 0x0005 }, + { 0x0006, 0x0006 }, + { 0x0006, 0x0007 }, + { 0x0006, 0x0008 }, + { 0x0006, 0x0009 }, + { 0x0007, 0x0003 }, + { 0x0007, 0x0004 }, + { 0x0007, 0x0005 }, + { 0x0007, 0x0006 }, + { 0x0007, 0x0007 }, + { 0x0008, 0x0003 }, + { 0x0008, 0x0004 }, + { 0x0008, 0x0005 }, + { 0x0009, 0x0003 }, + { 0x0009, 0x0004 }, + { 0x0009, 0x0005 }, + { 0x000a, 0x0003 }, + { 0x000a, 0x0004 }, + { 0x000a, 0x0005 }, + { 0x000b, 0x0003 }, + { 0x000b, 0x0004 }, + { 0x000b, 0x0005 }, + { 0x000c, 0x0002 }, + { 0x000c, 0x0003 }, + { 0x000c, 0x0004 }, + { 0x000c, 0x0005 }, + { 0x000d, 0x0003 }, + { 0x000e, 0x0003 }, + { 0x000e, 0x0004 }, + { 0x000f, 0x0003 }, + { 0x000e, 0x0005 }, + { 0x000f, 0x0004 }, + { 0x0010, 0x0001 }, + { 0x000f, 0x0005 }, + { 0x0010, 0x0002 }, + { 0x0010, 0x0003 }, + { 0x0010, 0x0004 }, + { 0x0010, 0x0005 }, + { 0x0011, 0x0001 }, + { 0x0012, 0x0000 }, + { 0x0012, 0x0001 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc26[77][2] = + { + { 0x0006, 0x0004 }, + { 0x0005, 0x0007 }, + { 0x0005, 0x0008 }, + { 0x0005, 0x0009 }, + { 0x0005, 0x000a }, + { 0x0005, 0x000b }, + { 0x0005, 0x000c }, + { 0x0005, 0x000d }, + { 0x0005, 0x000e }, + { 0x0005, 0x000f }, + { 0x0005, 0x0010 }, + { 0x0005, 0x0011 }, + { 0x0005, 0x0012 }, + { 0x0005, 0x0013 }, + { 0x0005, 0x0014 }, + { 0x0005, 0x0015 }, + { 0x0005, 0x0016 }, + { 0x0005, 0x0017 }, + { 0x0005, 0x0018 }, + { 0x0005, 0x0019 }, + { 0x0005, 0x001a }, + { 0x0005, 0x001b }, + { 0x0005, 0x001c }, + { 0x0005, 0x001d }, + { 0x0005, 0x001e }, + { 0x0005, 0x001f }, + { 0x0006, 0x0005 }, + { 0x0006, 0x0006 }, + { 0x0006, 0x0007 }, + { 0x0006, 0x0008 }, + { 0x0006, 0x0009 }, + { 0x0006, 0x000a }, + { 0x0006, 0x000b }, + { 0x0006, 0x000c }, + { 0x0006, 0x000d }, + { 0x0007, 0x0004 }, + { 0x0007, 0x0005 }, + { 0x0007, 0x0006 }, + { 0x0007, 0x0007 }, + { 0x0008, 0x0004 }, + { 0x0008, 0x0005 }, + { 0x0008, 0x0006 }, + { 0x0008, 0x0007 }, + { 0x0009, 0x0003 }, + { 0x0009, 0x0004 }, + { 0x0009, 0x0005 }, + { 0x0009, 0x0006 }, + { 0x0009, 0x0007 }, + { 0x000a, 0x0003 }, + { 0x000a, 0x0004 }, + { 0x000a, 0x0005 }, + { 0x000b, 0x0004 }, + { 0x000b, 0x0005 }, + { 0x000c, 0x0003 }, + { 0x000c, 0x0004 }, + { 0x000c, 0x0005 }, + { 0x000c, 0x0006 }, + { 0x000c, 0x0007 }, + { 0x000d, 0x0003 }, + { 0x000d, 0x0004 }, + { 0x000e, 0x0002 }, + { 0x000d, 0x0005 }, + { 0x000e, 0x0003 }, + { 0x000e, 0x0004 }, + { 0x000f, 0x0003 }, + { 0x000e, 0x0005 }, + { 0x0010, 0x0002 }, + { 0x0010, 0x0003 }, + { 0x0010, 0x0004 }, + { 0x0011, 0x0002 }, + { 0x0012, 0x0001 }, + { 0x0010, 0x0005 }, + { 0x0012, 0x0002 }, + { 0x0011, 0x0003 }, + { 0x0012, 0x0003 }, + { 0x0013, 0x0000 }, + { 0x0013, 0x0001 }, + + }; + + +const uint16_t c_aauiLCLDHuffEnc27[91][2] = + { + { 0x0006, 0x0006 }, + { 0x0005, 0x000b }, + { 0x0005, 0x000c }, + { 0x0005, 0x000d }, + { 0x0005, 0x000e }, + { 0x0005, 0x000f }, + { 0x0005, 0x0010 }, + { 0x0005, 0x0011 }, + { 0x0005, 0x0012 }, + { 0x0005, 0x0013 }, + { 0x0005, 0x0014 }, + { 0x0005, 0x0015 }, + { 0x0005, 0x0016 }, + { 0x0005, 0x0017 }, + { 0x0005, 0x0018 }, + { 0x0005, 0x0019 }, + { 0x0005, 0x001a }, + { 0x0005, 0x001b }, + { 0x0005, 0x001c }, + { 0x0005, 0x001d }, + { 0x0005, 0x001e }, + { 0x0005, 0x001f }, + { 0x0006, 0x0007 }, + { 0x0006, 0x0008 }, + { 0x0006, 0x0009 }, + { 0x0006, 0x000a }, + { 0x0006, 0x000b }, + { 0x0006, 0x000c }, + { 0x0006, 0x000d }, + { 0x0006, 0x000e }, + { 0x0006, 0x000f }, + { 0x0006, 0x0010 }, + { 0x0006, 0x0011 }, + { 0x0006, 0x0012 }, + { 0x0006, 0x0013 }, + { 0x0006, 0x0014 }, + { 0x0006, 0x0015 }, + { 0x0007, 0x0005 }, + { 0x0007, 0x0006 }, + { 0x0007, 0x0007 }, + { 0x0007, 0x0008 }, + { 0x0007, 0x0009 }, + { 0x0007, 0x000a }, + { 0x0007, 0x000b }, + { 0x0008, 0x0004 }, + { 0x0008, 0x0005 }, + { 0x0008, 0x0006 }, + { 0x0008, 0x0007 }, + { 0x0008, 0x0008 }, + { 0x0008, 0x0009 }, + { 0x0009, 0x0004 }, + { 0x0009, 0x0005 }, + { 0x0009, 0x0006 }, + { 0x0009, 0x0007 }, + { 0x000a, 0x0004 }, + { 0x000a, 0x0005 }, + { 0x000a, 0x0006 }, + { 0x000a, 0x0007 }, + { 0x000b, 0x0004 }, + { 0x000b, 0x0005 }, + { 0x000b, 0x0006 }, + { 0x000b, 0x0007 }, + { 0x000c, 0x0004 }, + { 0x000c, 0x0005 }, + { 0x000c, 0x0006 }, + { 0x000c, 0x0007 }, + { 0x000d, 0x0004 }, + { 0x000d, 0x0005 }, + { 0x000d, 0x0006 }, + { 0x000d, 0x0007 }, + { 0x000e, 0x0003 }, + { 0x000e, 0x0004 }, + { 0x000e, 0x0005 }, + { 0x000e, 0x0006 }, + { 0x000e, 0x0007 }, + { 0x000f, 0x0003 }, + { 0x000f, 0x0004 }, + { 0x0010, 0x0003 }, + { 0x000f, 0x0005 }, + { 0x0012, 0x0000 }, + { 0x0010, 0x0004 }, + { 0x0010, 0x0005 }, + { 0x0012, 0x0001 }, + { 0x0012, 0x0002 }, + { 0x0011, 0x0004 }, + { 0x0011, 0x0005 }, + { 0x0012, 0x0003 }, + { 0x0012, 0x0004 }, + { 0x0012, 0x0005 }, + { 0x0012, 0x0006 }, + { 0x0012, 0x0007 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc28[109][2] = + { + { 0x0006, 0x0008 }, + { 0x0005, 0x0010 }, + { 0x0005, 0x0011 }, + { 0x0005, 0x0012 }, + { 0x0005, 0x0013 }, + { 0x0005, 0x0014 }, + { 0x0005, 0x0015 }, + { 0x0005, 0x0016 }, + { 0x0005, 0x0017 }, + { 0x0005, 0x0018 }, + { 0x0005, 0x0019 }, + { 0x0005, 0x001a }, + { 0x0005, 0x001b }, + { 0x0005, 0x001c }, + { 0x0005, 0x001d }, + { 0x0005, 0x001e }, + { 0x0006, 0x0009 }, + { 0x0005, 0x001f }, + { 0x0006, 0x000a }, + { 0x0006, 0x000b }, + { 0x0006, 0x000c }, + { 0x0006, 0x000d }, + { 0x0006, 0x000e }, + { 0x0006, 0x000f }, + { 0x0006, 0x0010 }, + { 0x0006, 0x0011 }, + { 0x0006, 0x0012 }, + { 0x0006, 0x0013 }, + { 0x0006, 0x0014 }, + { 0x0006, 0x0015 }, + { 0x0006, 0x0016 }, + { 0x0006, 0x0017 }, + { 0x0006, 0x0018 }, + { 0x0006, 0x0019 }, + { 0x0006, 0x001a }, + { 0x0006, 0x001b }, + { 0x0006, 0x001c }, + { 0x0006, 0x001d }, + { 0x0006, 0x001e }, + { 0x0006, 0x001f }, + { 0x0007, 0x0006 }, + { 0x0007, 0x0007 }, + { 0x0007, 0x0008 }, + { 0x0007, 0x0009 }, + { 0x0007, 0x000a }, + { 0x0007, 0x000b }, + { 0x0007, 0x000c }, + { 0x0007, 0x000d }, + { 0x0007, 0x000e }, + { 0x0007, 0x000f }, + { 0x0008, 0x0005 }, + { 0x0008, 0x0006 }, + { 0x0008, 0x0007 }, + { 0x0008, 0x0008 }, + { 0x0008, 0x0009 }, + { 0x0008, 0x000a }, + { 0x0008, 0x000b }, + { 0x0009, 0x0004 }, + { 0x0009, 0x0005 }, + { 0x0009, 0x0006 }, + { 0x0009, 0x0007 }, + { 0x0009, 0x0008 }, + { 0x0009, 0x0009 }, + { 0x000a, 0x0005 }, + { 0x000a, 0x0006 }, + { 0x000a, 0x0007 }, + { 0x000b, 0x0005 }, + { 0x000b, 0x0006 }, + { 0x000b, 0x0007 }, + { 0x000b, 0x0008 }, + { 0x000b, 0x0009 }, + { 0x000c, 0x0004 }, + { 0x000c, 0x0005 }, + { 0x000c, 0x0006 }, + { 0x000c, 0x0007 }, + { 0x000c, 0x0008 }, + { 0x000c, 0x0009 }, + { 0x000d, 0x0004 }, + { 0x000d, 0x0005 }, + { 0x000d, 0x0006 }, + { 0x000d, 0x0007 }, + { 0x000e, 0x0004 }, + { 0x000e, 0x0005 }, + { 0x000e, 0x0006 }, + { 0x000e, 0x0007 }, + { 0x0010, 0x0004 }, + { 0x000f, 0x0005 }, + { 0x0010, 0x0005 }, + { 0x000f, 0x0006 }, + { 0x000f, 0x0007 }, + { 0x0010, 0x0006 }, + { 0x0011, 0x0006 }, + { 0x0010, 0x0007 }, + { 0x0013, 0x0000 }, + { 0x0010, 0x0008 }, + { 0x0010, 0x0009 }, + { 0x0013, 0x0001 }, + { 0x0011, 0x0007 }, + { 0x0012, 0x0001 }, + { 0x0012, 0x0002 }, + { 0x0012, 0x0003 }, + { 0x0012, 0x0004 }, + { 0x0012, 0x0005 }, + { 0x0012, 0x0006 }, + { 0x0012, 0x0007 }, + { 0x0012, 0x0008 }, + { 0x0012, 0x0009 }, + { 0x0012, 0x000a }, + { 0x0012, 0x000b }, + + }; + +const uint16_t c_aauiLCLDHuffEnc29[129][2] = + { + { 0x0006, 0x0009 }, + { 0x0005, 0x0019 }, + { 0x0006, 0x000a }, + { 0x0005, 0x001a }, + { 0x0005, 0x001b }, + { 0x0005, 0x001c }, + { 0x0006, 0x000b }, + { 0x0005, 0x001d }, + { 0x0005, 0x001e }, + { 0x0006, 0x000c }, + { 0x0006, 0x000d }, + { 0x0005, 0x001f }, + { 0x0006, 0x000e }, + { 0x0006, 0x000f }, + { 0x0006, 0x0010 }, + { 0x0006, 0x0011 }, + { 0x0006, 0x0012 }, + { 0x0006, 0x0013 }, + { 0x0006, 0x0014 }, + { 0x0006, 0x0015 }, + { 0x0006, 0x0016 }, + { 0x0006, 0x0017 }, + { 0x0006, 0x0018 }, + { 0x0006, 0x0019 }, + { 0x0006, 0x001a }, + { 0x0006, 0x001b }, + { 0x0006, 0x001c }, + { 0x0006, 0x001d }, + { 0x0006, 0x001e }, + { 0x0006, 0x001f }, + { 0x0006, 0x0020 }, + { 0x0006, 0x0021 }, + { 0x0006, 0x0022 }, + { 0x0006, 0x0023 }, + { 0x0006, 0x0024 }, + { 0x0006, 0x0025 }, + { 0x0006, 0x0026 }, + { 0x0006, 0x0027 }, + { 0x0006, 0x0028 }, + { 0x0006, 0x0029 }, + { 0x0006, 0x002a }, + { 0x0006, 0x002b }, + { 0x0006, 0x002c }, + { 0x0006, 0x002d }, + { 0x0006, 0x002e }, + { 0x0006, 0x002f }, + { 0x0006, 0x0030 }, + { 0x0006, 0x0031 }, + { 0x0007, 0x0007 }, + { 0x0007, 0x0008 }, + { 0x0007, 0x0009 }, + { 0x0007, 0x000a }, + { 0x0007, 0x000b }, + { 0x0007, 0x000c }, + { 0x0007, 0x000d }, + { 0x0007, 0x000e }, + { 0x0007, 0x000f }, + { 0x0007, 0x0010 }, + { 0x0007, 0x0011 }, + { 0x0008, 0x0006 }, + { 0x0008, 0x0007 }, + { 0x0008, 0x0008 }, + { 0x0008, 0x0009 }, + { 0x0008, 0x000a }, + { 0x0008, 0x000b }, + { 0x0008, 0x000c }, + { 0x0008, 0x000d }, + { 0x0009, 0x0006 }, + { 0x0009, 0x0007 }, + { 0x0009, 0x0008 }, + { 0x0009, 0x0009 }, + { 0x0009, 0x000a }, + { 0x0009, 0x000b }, + { 0x000a, 0x0005 }, + { 0x000a, 0x0006 }, + { 0x000a, 0x0007 }, + { 0x000a, 0x0008 }, + { 0x000a, 0x0009 }, + { 0x000a, 0x000a }, + { 0x000a, 0x000b }, + { 0x000b, 0x0006 }, + { 0x000b, 0x0007 }, + { 0x000b, 0x0008 }, + { 0x000b, 0x0009 }, + { 0x000c, 0x0006 }, + { 0x000c, 0x0007 }, + { 0x000c, 0x0008 }, + { 0x000c, 0x0009 }, + { 0x000c, 0x000a }, + { 0x000c, 0x000b }, + { 0x000d, 0x0005 }, + { 0x000d, 0x0006 }, + { 0x000d, 0x0007 }, + { 0x000d, 0x0008 }, + { 0x000d, 0x0009 }, + { 0x000d, 0x000a }, + { 0x000d, 0x000b }, + { 0x000e, 0x0006 }, + { 0x000e, 0x0007 }, + { 0x000e, 0x0008 }, + { 0x000e, 0x0009 }, + { 0x000f, 0x0004 }, + { 0x000f, 0x0005 }, + { 0x000f, 0x0006 }, + { 0x000f, 0x0007 }, + { 0x0011, 0x0007 }, + { 0x000f, 0x0008 }, + { 0x0012, 0x0000 }, + { 0x000f, 0x0009 }, + { 0x0010, 0x0005 }, + { 0x000f, 0x000a }, + { 0x000f, 0x000b }, + { 0x0012, 0x0001 }, + { 0x0010, 0x0006 }, + { 0x0010, 0x0007 }, + { 0x0012, 0x0002 }, + { 0x0012, 0x0003 }, + { 0x0012, 0x0004 }, + { 0x0012, 0x0005 }, + { 0x0012, 0x0006 }, + { 0x0012, 0x0007 }, + { 0x0012, 0x0008 }, + { 0x0011, 0x0008 }, + { 0x0012, 0x0009 }, + { 0x0012, 0x000a }, + { 0x0012, 0x000b }, + { 0x0012, 0x000c }, + { 0x0012, 0x000d }, + { 0x0011, 0x0009 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc30[153][2] = + { + { 0x0007, 0x0009 }, + { 0x0006, 0x000e }, + { 0x0006, 0x000f }, + { 0x0006, 0x0010 }, + { 0x0006, 0x0011 }, + { 0x0006, 0x0012 }, + { 0x0006, 0x0013 }, + { 0x0006, 0x0014 }, + { 0x0006, 0x0015 }, + { 0x0006, 0x0016 }, + { 0x0006, 0x0017 }, + { 0x0006, 0x0018 }, + { 0x0006, 0x0019 }, + { 0x0006, 0x001a }, + { 0x0006, 0x001b }, + { 0x0006, 0x001c }, + { 0x0006, 0x001d }, + { 0x0006, 0x001e }, + { 0x0006, 0x001f }, + { 0x0006, 0x0020 }, + { 0x0006, 0x0021 }, + { 0x0006, 0x0022 }, + { 0x0006, 0x0023 }, + { 0x0006, 0x0024 }, + { 0x0006, 0x0025 }, + { 0x0006, 0x0026 }, + { 0x0006, 0x0027 }, + { 0x0006, 0x0028 }, + { 0x0006, 0x0029 }, + { 0x0006, 0x002a }, + { 0x0006, 0x002b }, + { 0x0006, 0x002c }, + { 0x0006, 0x002d }, + { 0x0006, 0x002e }, + { 0x0006, 0x002f }, + { 0x0006, 0x0030 }, + { 0x0006, 0x0031 }, + { 0x0006, 0x0032 }, + { 0x0006, 0x0033 }, + { 0x0006, 0x0034 }, + { 0x0006, 0x0035 }, + { 0x0006, 0x0036 }, + { 0x0006, 0x0037 }, + { 0x0006, 0x0038 }, + { 0x0006, 0x0039 }, + { 0x0006, 0x003a }, + { 0x0006, 0x003b }, + { 0x0006, 0x003c }, + { 0x0006, 0x003d }, + { 0x0006, 0x003e }, + { 0x0006, 0x003f }, + { 0x0007, 0x000a }, + { 0x0007, 0x000b }, + { 0x0007, 0x000c }, + { 0x0007, 0x000d }, + { 0x0007, 0x000e }, + { 0x0007, 0x000f }, + { 0x0007, 0x0010 }, + { 0x0007, 0x0011 }, + { 0x0007, 0x0012 }, + { 0x0007, 0x0013 }, + { 0x0007, 0x0014 }, + { 0x0007, 0x0015 }, + { 0x0007, 0x0016 }, + { 0x0007, 0x0017 }, + { 0x0007, 0x0018 }, + { 0x0007, 0x0019 }, + { 0x0007, 0x001a }, + { 0x0007, 0x001b }, + { 0x0008, 0x0008 }, + { 0x0008, 0x0009 }, + { 0x0008, 0x000a }, + { 0x0008, 0x000b }, + { 0x0008, 0x000c }, + { 0x0008, 0x000d }, + { 0x0008, 0x000e }, + { 0x0008, 0x000f }, + { 0x0008, 0x0010 }, + { 0x0008, 0x0011 }, + { 0x0009, 0x0007 }, + { 0x0009, 0x0008 }, + { 0x0009, 0x0009 }, + { 0x0009, 0x000a }, + { 0x0009, 0x000b }, + { 0x0009, 0x000c }, + { 0x0009, 0x000d }, + { 0x0009, 0x000e }, + { 0x000a, 0x0008 }, + { 0x0009, 0x000f }, + { 0x000a, 0x0009 }, + { 0x000a, 0x000a }, + { 0x000a, 0x000b }, + { 0x000a, 0x000c }, + { 0x000a, 0x000d }, + { 0x000b, 0x0007 }, + { 0x000b, 0x0008 }, + { 0x000b, 0x0009 }, + { 0x000b, 0x000a }, + { 0x000b, 0x000b }, + { 0x000b, 0x000c }, + { 0x000b, 0x000d }, + { 0x000c, 0x0008 }, + { 0x000b, 0x000e }, + { 0x000b, 0x000f }, + { 0x000c, 0x0009 }, + { 0x000c, 0x000a }, + { 0x000d, 0x0008 }, + { 0x000c, 0x000b }, + { 0x000c, 0x000c }, + { 0x000d, 0x0009 }, + { 0x000c, 0x000d }, + { 0x000d, 0x000a }, + { 0x000d, 0x000b }, + { 0x000d, 0x000c }, + { 0x000d, 0x000d }, + { 0x000e, 0x0008 }, + { 0x000d, 0x000e }, + { 0x000d, 0x000f }, + { 0x000e, 0x0009 }, + { 0x000e, 0x000a }, + { 0x000e, 0x000b }, + { 0x000e, 0x000c }, + { 0x000f, 0x0006 }, + { 0x000f, 0x0007 }, + { 0x000f, 0x0008 }, + { 0x0010, 0x0006 }, + { 0x000e, 0x000d }, + { 0x000e, 0x000e }, + { 0x000e, 0x000f }, + { 0x0010, 0x0007 }, + { 0x000f, 0x0009 }, + { 0x0010, 0x0008 }, + { 0x000f, 0x000a }, + { 0x000f, 0x000b }, + { 0x000f, 0x000c }, + { 0x000f, 0x000d }, + { 0x0010, 0x0009 }, + { 0x0011, 0x0000 }, + { 0x0011, 0x0001 }, + { 0x0011, 0x0002 }, + { 0x000f, 0x000e }, + { 0x0010, 0x000a }, + { 0x0011, 0x0003 }, + { 0x0011, 0x0004 }, + { 0x0011, 0x0005 }, + { 0x000f, 0x000f }, + { 0x0011, 0x0006 }, + { 0x0011, 0x0007 }, + { 0x0011, 0x0008 }, + { 0x0011, 0x0009 }, + { 0x0011, 0x000a }, + { 0x0011, 0x000b }, + { 0x0010, 0x000b }, + + }; + +const uint16_t c_aauiLCLDHuffEnc31[181][2] = + { + { 0x0007, 0x000b }, + { 0x0006, 0x0015 }, + { 0x0006, 0x0016 }, + { 0x0006, 0x0017 }, + { 0x0006, 0x0018 }, + { 0x0006, 0x0019 }, + { 0x0006, 0x001a }, + { 0x0006, 0x001b }, + { 0x0006, 0x001c }, + { 0x0006, 0x001d }, + { 0x0006, 0x001e }, + { 0x0006, 0x001f }, + { 0x0006, 0x0020 }, + { 0x0006, 0x0021 }, + { 0x0006, 0x0022 }, + { 0x0006, 0x0023 }, + { 0x0006, 0x0024 }, + { 0x0006, 0x0025 }, + { 0x0006, 0x0026 }, + { 0x0006, 0x0027 }, + { 0x0006, 0x0028 }, + { 0x0006, 0x0029 }, + { 0x0006, 0x002a }, + { 0x0006, 0x002b }, + { 0x0006, 0x002c }, + { 0x0006, 0x002d }, + { 0x0006, 0x002e }, + { 0x0006, 0x002f }, + { 0x0006, 0x0030 }, + { 0x0006, 0x0031 }, + { 0x0006, 0x0032 }, + { 0x0006, 0x0033 }, + { 0x0006, 0x0034 }, + { 0x0006, 0x0035 }, + { 0x0006, 0x0036 }, + { 0x0006, 0x0037 }, + { 0x0006, 0x0038 }, + { 0x0006, 0x0039 }, + { 0x0006, 0x003a }, + { 0x0006, 0x003b }, + { 0x0006, 0x003c }, + { 0x0006, 0x003d }, + { 0x0006, 0x003e }, + { 0x0007, 0x000c }, + { 0x0006, 0x003f }, + { 0x0007, 0x000d }, + { 0x0007, 0x000e }, + { 0x0007, 0x000f }, + { 0x0007, 0x0010 }, + { 0x0007, 0x0011 }, + { 0x0007, 0x0012 }, + { 0x0007, 0x0013 }, + { 0x0007, 0x0014 }, + { 0x0007, 0x0015 }, + { 0x0007, 0x0016 }, + { 0x0007, 0x0017 }, + { 0x0007, 0x0018 }, + { 0x0007, 0x0019 }, + { 0x0007, 0x001a }, + { 0x0007, 0x001b }, + { 0x0007, 0x001c }, + { 0x0007, 0x001d }, + { 0x0007, 0x001e }, + { 0x0007, 0x001f }, + { 0x0007, 0x0020 }, + { 0x0007, 0x0021 }, + { 0x0007, 0x0022 }, + { 0x0007, 0x0023 }, + { 0x0007, 0x0024 }, + { 0x0007, 0x0025 }, + { 0x0007, 0x0026 }, + { 0x0007, 0x0027 }, + { 0x0007, 0x0028 }, + { 0x0007, 0x0029 }, + { 0x0008, 0x0009 }, + { 0x0008, 0x000a }, + { 0x0008, 0x000b }, + { 0x0008, 0x000c }, + { 0x0008, 0x000d }, + { 0x0008, 0x000e }, + { 0x0008, 0x000f }, + { 0x0008, 0x0010 }, + { 0x0008, 0x0011 }, + { 0x0008, 0x0012 }, + { 0x0008, 0x0013 }, + { 0x0008, 0x0014 }, + { 0x0008, 0x0015 }, + { 0x0009, 0x0008 }, + { 0x0009, 0x0009 }, + { 0x0009, 0x000a }, + { 0x0009, 0x000b }, + { 0x0009, 0x000c }, + { 0x0009, 0x000d }, + { 0x0009, 0x000e }, + { 0x0009, 0x000f }, + { 0x0009, 0x0010 }, + { 0x0009, 0x0011 }, + { 0x000a, 0x0008 }, + { 0x000a, 0x0009 }, + { 0x000a, 0x000a }, + { 0x000a, 0x000b }, + { 0x000a, 0x000c }, + { 0x000a, 0x000d }, + { 0x000a, 0x000e }, + { 0x000a, 0x000f }, + { 0x000b, 0x0008 }, + { 0x000b, 0x0009 }, + { 0x000b, 0x000a }, + { 0x000b, 0x000b }, + { 0x000b, 0x000c }, + { 0x000b, 0x000d }, + { 0x000b, 0x000e }, + { 0x000c, 0x0008 }, + { 0x000c, 0x0009 }, + { 0x000b, 0x000f }, + { 0x000c, 0x000a }, + { 0x000c, 0x000b }, + { 0x000c, 0x000c }, + { 0x000c, 0x000d }, + { 0x000d, 0x0008 }, + { 0x000c, 0x000e }, + { 0x000d, 0x0009 }, + { 0x000d, 0x000a }, + { 0x000c, 0x000f }, + { 0x000d, 0x000b }, + { 0x000d, 0x000c }, + { 0x000d, 0x000d }, + { 0x000d, 0x000e }, + { 0x000d, 0x000f }, + { 0x000e, 0x0008 }, + { 0x000e, 0x0009 }, + { 0x000e, 0x000a }, + { 0x000e, 0x000b }, + { 0x000e, 0x000c }, + { 0x000e, 0x000d }, + { 0x000e, 0x000e }, + { 0x000e, 0x000f }, + { 0x000f, 0x0009 }, + { 0x000f, 0x000a }, + { 0x000f, 0x000b }, + { 0x000f, 0x000c }, + { 0x0010, 0x0009 }, + { 0x000f, 0x000d }, + { 0x000f, 0x000e }, + { 0x0010, 0x000a }, + { 0x0010, 0x000b }, + { 0x0010, 0x000c }, + { 0x0010, 0x000d }, + { 0x0011, 0x000a }, + { 0x0010, 0x000e }, + { 0x000f, 0x000f }, + { 0x0010, 0x000f }, + { 0x0012, 0x0000 }, + { 0x0012, 0x0001 }, + { 0x0011, 0x000b }, + { 0x0011, 0x000c }, + { 0x0010, 0x0010 }, + { 0x0012, 0x0002 }, + { 0x0012, 0x0003 }, + { 0x0011, 0x000d }, + { 0x0011, 0x000e }, + { 0x0011, 0x000f }, + { 0x0011, 0x0010 }, + { 0x0011, 0x0011 }, + { 0x0010, 0x0011 }, + { 0x0012, 0x0004 }, + { 0x0012, 0x0005 }, + { 0x0012, 0x0006 }, + { 0x0012, 0x0007 }, + { 0x0012, 0x0008 }, + { 0x0012, 0x0009 }, + { 0x0012, 0x000a }, + { 0x0012, 0x000b }, + { 0x0012, 0x000c }, + { 0x0012, 0x000d }, + { 0x0012, 0x000e }, + { 0x0012, 0x000f }, + { 0x0012, 0x0010 }, + { 0x0012, 0x0011 }, + { 0x0012, 0x0012 }, + { 0x0012, 0x0013 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc33[16][2] = + { + { 0x0001, 0x0001 }, + { 0x0003, 0x0001 }, + { 0x0008, 0x0000 }, + { 0x0008, 0x0001 }, + { 0x0002, 0x0001 }, + { 0x0004, 0x0001 }, + { 0x0008, 0x0002 }, + { 0x0008, 0x0003 }, + { 0x0008, 0x0004 }, + { 0x0008, 0x0005 }, + { 0x0008, 0x0006 }, + { 0x0008, 0x0007 }, + { 0x0007, 0x0004 }, + { 0x0007, 0x0005 }, + { 0x0007, 0x0006 }, + { 0x0007, 0x0007 }, + }; + +const uint16_t c_aauiLCLDHuffEnc34[16][2] = + { + { 0x0001, 0x0001 }, + { 0x0003, 0x0001 }, + { 0x0008, 0x0000 }, + { 0x0008, 0x0001 }, + { 0x0002, 0x0001 }, + { 0x0004, 0x0001 }, + { 0x0008, 0x0002 }, + { 0x0008, 0x0003 }, + { 0x0008, 0x0004 }, + { 0x0008, 0x0005 }, + { 0x0008, 0x0006 }, + { 0x0008, 0x0007 }, + { 0x0007, 0x0004 }, + { 0x0007, 0x0005 }, + { 0x0007, 0x0006 }, + { 0x0007, 0x0007 }, + }; + +const uint16_t c_aauiLCLDHuffEnc35[25][2] = + { + { 0x0001, 0x0001 }, + { 0x0003, 0x0001 }, + { 0x0007, 0x0006 }, + { 0x0009, 0x0000 }, + { 0x0009, 0x0001 }, + { 0x0002, 0x0001 }, + { 0x0004, 0x0001 }, + { 0x0009, 0x0002 }, + { 0x0009, 0x0003 }, + { 0x0009, 0x0004 }, + { 0x0007, 0x0007 }, + { 0x0009, 0x0005 }, + { 0x0009, 0x0006 }, + { 0x0009, 0x0007 }, + { 0x0009, 0x0008 }, + { 0x0009, 0x0009 }, + { 0x0009, 0x000a }, + { 0x0009, 0x000b }, + { 0x0009, 0x000c }, + { 0x0009, 0x000d }, + { 0x0008, 0x0007 }, + { 0x0008, 0x0008 }, + { 0x0008, 0x0009 }, + { 0x0008, 0x000a }, + { 0x0008, 0x000b }, + + }; + +const uint16_t c_aauiLCLDHuffEnc36[36][2] = + { + { 0x0001, 0x0001 }, + { 0x0002, 0x0001 }, + { 0x0006, 0x0002 }, + { 0x000b, 0x0000 }, + { 0x000b, 0x0001 }, + { 0x000b, 0x0002 }, + { 0x0003, 0x0001 }, + { 0x0004, 0x0001 }, + { 0x0008, 0x0005 }, + { 0x000b, 0x0003 }, + { 0x000b, 0x0004 }, + { 0x000b, 0x0005 }, + { 0x0006, 0x0003 }, + { 0x0007, 0x0003 }, + { 0x000b, 0x0006 }, + { 0x000b, 0x0007 }, + { 0x000b, 0x0008 }, + { 0x000b, 0x0009 }, + { 0x000b, 0x000a }, + { 0x000b, 0x000b }, + { 0x000b, 0x000c }, + { 0x000b, 0x000d }, + { 0x000b, 0x000e }, + { 0x000b, 0x000f }, + { 0x000a, 0x0008 }, + { 0x000a, 0x0009 }, + { 0x000a, 0x000a }, + { 0x000a, 0x000b }, + { 0x000a, 0x000c }, + { 0x000a, 0x000d }, + { 0x000a, 0x000e }, + { 0x000a, 0x000f }, + { 0x000a, 0x0010 }, + { 0x000a, 0x0011 }, + { 0x000a, 0x0012 }, + { 0x000a, 0x0013 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc37[36][2] = + { + { 0x0001, 0x0001 }, + { 0x0002, 0x0001 }, + { 0x0006, 0x0001 }, + { 0x000c, 0x0000 }, + { 0x000c, 0x0001 }, + { 0x000c, 0x0002 }, + { 0x0003, 0x0001 }, + { 0x0004, 0x0001 }, + { 0x0006, 0x0002 }, + { 0x000c, 0x0003 }, + { 0x000c, 0x0004 }, + { 0x000c, 0x0005 }, + { 0x0006, 0x0003 }, + { 0x0007, 0x0001 }, + { 0x000a, 0x0007 }, + { 0x000c, 0x0006 }, + { 0x000c, 0x0007 }, + { 0x000c, 0x0008 }, + { 0x000c, 0x0009 }, + { 0x000c, 0x000a }, + { 0x000c, 0x000b }, + { 0x000c, 0x000c }, + { 0x000c, 0x000d }, + { 0x000c, 0x000e }, + { 0x000c, 0x000f }, + { 0x000c, 0x0010 }, + { 0x000c, 0x0011 }, + { 0x000c, 0x0012 }, + { 0x000c, 0x0013 }, + { 0x000c, 0x0014 }, + { 0x000c, 0x0015 }, + { 0x000c, 0x0016 }, + { 0x000c, 0x0017 }, + { 0x000c, 0x0018 }, + { 0x000c, 0x0019 }, + { 0x000b, 0x000d }, + + }; + +const uint16_t c_aauiLCLDHuffEnc38[49][2] = + { + { 0x0001, 0x0001 }, + { 0x0003, 0x0001 }, + { 0x0006, 0x0001 }, + { 0x000c, 0x0012 }, + { 0x000d, 0x0000 }, + { 0x000d, 0x0001 }, + { 0x000d, 0x0002 }, + { 0x0002, 0x0001 }, + { 0x0004, 0x0001 }, + { 0x0007, 0x0001 }, + { 0x000b, 0x000a }, + { 0x000d, 0x0003 }, + { 0x000d, 0x0004 }, + { 0x000d, 0x0005 }, + { 0x0006, 0x0002 }, + { 0x0006, 0x0003 }, + { 0x0009, 0x0003 }, + { 0x000d, 0x0006 }, + { 0x000d, 0x0007 }, + { 0x000d, 0x0008 }, + { 0x000d, 0x0009 }, + { 0x000c, 0x0013 }, + { 0x000b, 0x000b }, + { 0x000d, 0x000a }, + { 0x000d, 0x000b }, + { 0x000d, 0x000c }, + { 0x000d, 0x000d }, + { 0x000d, 0x000e }, + { 0x000d, 0x000f }, + { 0x000d, 0x0010 }, + { 0x000d, 0x0011 }, + { 0x000d, 0x0012 }, + { 0x000d, 0x0013 }, + { 0x000d, 0x0014 }, + { 0x000d, 0x0015 }, + { 0x000d, 0x0016 }, + { 0x000d, 0x0017 }, + { 0x000d, 0x0018 }, + { 0x000d, 0x0019 }, + { 0x000d, 0x001a }, + { 0x000d, 0x001b }, + { 0x000d, 0x001c }, + { 0x000d, 0x001d }, + { 0x000d, 0x001e }, + { 0x000d, 0x001f }, + { 0x000d, 0x0020 }, + { 0x000d, 0x0021 }, + { 0x000d, 0x0022 }, + { 0x000d, 0x0023 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc39[64][2] = + { + { 0x0001, 0x0001 }, + { 0x0002, 0x0001 }, + { 0x0006, 0x0001 }, + { 0x000a, 0x0002 }, + { 0x000f, 0x0000 }, + { 0x000f, 0x0001 }, + { 0x000f, 0x0002 }, + { 0x000f, 0x0003 }, + { 0x0003, 0x0001 }, + { 0x0004, 0x0001 }, + { 0x0007, 0x0001 }, + { 0x000a, 0x0003 }, + { 0x000f, 0x0004 }, + { 0x000f, 0x0005 }, + { 0x000f, 0x0006 }, + { 0x000f, 0x0007 }, + { 0x0006, 0x0002 }, + { 0x0006, 0x0003 }, + { 0x0009, 0x0003 }, + { 0x000d, 0x000e }, + { 0x000f, 0x0008 }, + { 0x000f, 0x0009 }, + { 0x000f, 0x000a }, + { 0x000f, 0x000b }, + { 0x000a, 0x0004 }, + { 0x000a, 0x0005 }, + { 0x000d, 0x000f }, + { 0x000f, 0x000c }, + { 0x000f, 0x000d }, + { 0x000f, 0x000e }, + { 0x000f, 0x000f }, + { 0x000f, 0x0010 }, + { 0x000f, 0x0011 }, + { 0x000f, 0x0012 }, + { 0x000f, 0x0013 }, + { 0x000f, 0x0014 }, + { 0x000f, 0x0015 }, + { 0x000f, 0x0016 }, + { 0x000f, 0x0017 }, + { 0x000f, 0x0018 }, + { 0x000f, 0x0019 }, + { 0x000f, 0x001a }, + { 0x000f, 0x001b }, + { 0x000f, 0x001c }, + { 0x000f, 0x001d }, + { 0x000f, 0x001e }, + { 0x000f, 0x001f }, + { 0x000f, 0x0020 }, + { 0x000f, 0x0021 }, + { 0x000f, 0x0022 }, + { 0x000f, 0x0023 }, + { 0x000f, 0x0024 }, + { 0x000f, 0x0025 }, + { 0x000f, 0x0026 }, + { 0x000f, 0x0027 }, + { 0x000f, 0x0028 }, + { 0x000f, 0x0029 }, + { 0x000e, 0x0015 }, + { 0x000e, 0x0016 }, + { 0x000e, 0x0017 }, + { 0x000e, 0x0018 }, + { 0x000e, 0x0019 }, + { 0x000e, 0x001a }, + { 0x000e, 0x001b }, + }; + +const uint16_t c_aauiLCLDHuffEnc40[81][2] = + { + { 0x0001, 0x0001 }, + { 0x0002, 0x0001 }, + { 0x0006, 0x0001 }, + { 0x000b, 0x0002 }, + { 0x000f, 0x0011 }, + { 0x0011, 0x0000 }, + { 0x0011, 0x0001 }, + { 0x0011, 0x0002 }, + { 0x0011, 0x0003 }, + { 0x0003, 0x0001 }, + { 0x0004, 0x0001 }, + { 0x0007, 0x0001 }, + { 0x000a, 0x0002 }, + { 0x000e, 0x0009 }, + { 0x0011, 0x0004 }, + { 0x0011, 0x0005 }, + { 0x0011, 0x0006 }, + { 0x0011, 0x0007 }, + { 0x0006, 0x0002 }, + { 0x0006, 0x0003 }, + { 0x0008, 0x0001 }, + { 0x000d, 0x0005 }, + { 0x0011, 0x0008 }, + { 0x0011, 0x0009 }, + { 0x0011, 0x000a }, + { 0x0011, 0x000b }, + { 0x0011, 0x000c }, + { 0x000b, 0x0003 }, + { 0x000a, 0x0003 }, + { 0x000c, 0x0003 }, + { 0x0011, 0x000d }, + { 0x0011, 0x000e }, + { 0x0011, 0x000f }, + { 0x0011, 0x0010 }, + { 0x0011, 0x0011 }, + { 0x0011, 0x0012 }, + { 0x0011, 0x0013 }, + { 0x0011, 0x0014 }, + { 0x0011, 0x0015 }, + { 0x0011, 0x0016 }, + { 0x0011, 0x0017 }, + { 0x0011, 0x0018 }, + { 0x0011, 0x0019 }, + { 0x0011, 0x001a }, + { 0x0011, 0x001b }, + { 0x0011, 0x001c }, + { 0x0011, 0x001d }, + { 0x0011, 0x001e }, + { 0x0011, 0x001f }, + { 0x0011, 0x0020 }, + { 0x0011, 0x0021 }, + { 0x0011, 0x0022 }, + { 0x0011, 0x0023 }, + { 0x0011, 0x0024 }, + { 0x0011, 0x0025 }, + { 0x0011, 0x0026 }, + { 0x0011, 0x0027 }, + { 0x0011, 0x0028 }, + { 0x0011, 0x0029 }, + { 0x0011, 0x002a }, + { 0x0011, 0x002b }, + { 0x0011, 0x002c }, + { 0x0011, 0x002d }, + { 0x0011, 0x002e }, + { 0x0011, 0x002f }, + { 0x0011, 0x0030 }, + { 0x0011, 0x0031 }, + { 0x0011, 0x0032 }, + { 0x0011, 0x0033 }, + { 0x0011, 0x0034 }, + { 0x0011, 0x0035 }, + { 0x0011, 0x0036 }, + { 0x0011, 0x0037 }, + { 0x0011, 0x0038 }, + { 0x0011, 0x0039 }, + { 0x0011, 0x003a }, + { 0x0011, 0x003b }, + { 0x0010, 0x001e }, + { 0x0010, 0x001f }, + { 0x0010, 0x0020 }, + { 0x0010, 0x0021 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc41[100][2] = + { + { 0x0001, 0x0001 }, + { 0x0003, 0x0001 }, + { 0x0006, 0x0001 }, + { 0x000b, 0x0001 }, + { 0x0011, 0x0014 }, + { 0x0013, 0x0000 }, + { 0x0013, 0x0001 }, + { 0x0013, 0x0002 }, + { 0x0013, 0x0003 }, + { 0x0013, 0x0004 }, + { 0x0002, 0x0001 }, + { 0x0004, 0x0001 }, + { 0x0007, 0x0001 }, + { 0x000a, 0x0001 }, + { 0x0010, 0x000b }, + { 0x0013, 0x0005 }, + { 0x0013, 0x0006 }, + { 0x0013, 0x0007 }, + { 0x0013, 0x0008 }, + { 0x0013, 0x0009 }, + { 0x0006, 0x0002 }, + { 0x0006, 0x0003 }, + { 0x0008, 0x0001 }, + { 0x000d, 0x0002 }, + { 0x0011, 0x0015 }, + { 0x0013, 0x000a }, + { 0x0013, 0x000b }, + { 0x0013, 0x000c }, + { 0x0013, 0x000d }, + { 0x0013, 0x000e }, + { 0x000a, 0x0002 }, + { 0x000a, 0x0003 }, + { 0x000d, 0x0003 }, + { 0x0010, 0x000c }, + { 0x0013, 0x000f }, + { 0x0013, 0x0010 }, + { 0x0013, 0x0011 }, + { 0x0013, 0x0012 }, + { 0x0013, 0x0013 }, + { 0x0013, 0x0014 }, + { 0x0010, 0x000d }, + { 0x000f, 0x0007 }, + { 0x0012, 0x0027 }, + { 0x0013, 0x0015 }, + { 0x0013, 0x0016 }, + { 0x0013, 0x0017 }, + { 0x0013, 0x0018 }, + { 0x0013, 0x0019 }, + { 0x0013, 0x001a }, + { 0x0013, 0x001b }, + { 0x0013, 0x001c }, + { 0x0013, 0x001d }, + { 0x0013, 0x001e }, + { 0x0013, 0x001f }, + { 0x0013, 0x0020 }, + { 0x0013, 0x0021 }, + { 0x0013, 0x0022 }, + { 0x0013, 0x0023 }, + { 0x0013, 0x0024 }, + { 0x0013, 0x0025 }, + { 0x0013, 0x0026 }, + { 0x0013, 0x0027 }, + { 0x0013, 0x0028 }, + { 0x0013, 0x0029 }, + { 0x0013, 0x002a }, + { 0x0013, 0x002b }, + { 0x0013, 0x002c }, + { 0x0013, 0x002d }, + { 0x0013, 0x002e }, + { 0x0013, 0x002f }, + { 0x0013, 0x0030 }, + { 0x0013, 0x0031 }, + { 0x0013, 0x0032 }, + { 0x0013, 0x0033 }, + { 0x0013, 0x0034 }, + { 0x0013, 0x0035 }, + { 0x0013, 0x0036 }, + { 0x0013, 0x0037 }, + { 0x0013, 0x0038 }, + { 0x0013, 0x0039 }, + { 0x0013, 0x003a }, + { 0x0013, 0x003b }, + { 0x0013, 0x003c }, + { 0x0013, 0x003d }, + { 0x0013, 0x003e }, + { 0x0013, 0x003f }, + { 0x0013, 0x0040 }, + { 0x0013, 0x0041 }, + { 0x0013, 0x0042 }, + { 0x0013, 0x0043 }, + { 0x0013, 0x0044 }, + { 0x0013, 0x0045 }, + { 0x0013, 0x0046 }, + { 0x0013, 0x0047 }, + { 0x0013, 0x0048 }, + { 0x0013, 0x0049 }, + { 0x0013, 0x004a }, + { 0x0013, 0x004b }, + { 0x0013, 0x004c }, + { 0x0013, 0x004d }, + + }; + +const uint16_t c_aauiLCLDHuffEnc42[169][2] = + { + { 0x0001, 0x0001 }, + { 0x0003, 0x0001 }, + { 0x0006, 0x0001 }, + { 0x0009, 0x0001 }, + { 0x000e, 0x0006 }, + { 0x0013, 0x0000 }, + { 0x0013, 0x0001 }, + { 0x0013, 0x0002 }, + { 0x0013, 0x0003 }, + { 0x0013, 0x0004 }, + { 0x0013, 0x0005 }, + { 0x0013, 0x0006 }, + { 0x0013, 0x0007 }, + { 0x0003, 0x0002 }, + { 0x0003, 0x0003 }, + { 0x0005, 0x0001 }, + { 0x0009, 0x0002 }, + { 0x000d, 0x0004 }, + { 0x0010, 0x0013 }, + { 0x0013, 0x0008 }, + { 0x0013, 0x0009 }, + { 0x0013, 0x000a }, + { 0x0013, 0x000b }, + { 0x0013, 0x000c }, + { 0x0013, 0x000d }, + { 0x0013, 0x000e }, + { 0x0005, 0x0002 }, + { 0x0005, 0x0003 }, + { 0x0008, 0x0002 }, + { 0x000b, 0x0002 }, + { 0x000f, 0x000b }, + { 0x0011, 0x0025 }, + { 0x0013, 0x000f }, + { 0x0013, 0x0010 }, + { 0x0013, 0x0011 }, + { 0x0013, 0x0012 }, + { 0x0013, 0x0013 }, + { 0x0013, 0x0014 }, + { 0x0013, 0x0015 }, + { 0x0009, 0x0003 }, + { 0x0008, 0x0003 }, + { 0x000b, 0x0003 }, + { 0x000d, 0x0005 }, + { 0x0010, 0x0014 }, + { 0x0013, 0x0016 }, + { 0x0013, 0x0017 }, + { 0x0013, 0x0018 }, + { 0x0013, 0x0019 }, + { 0x0013, 0x001a }, + { 0x0013, 0x001b }, + { 0x0013, 0x001c }, + { 0x0013, 0x001d }, + { 0x000d, 0x0006 }, + { 0x000d, 0x0007 }, + { 0x000e, 0x0007 }, + { 0x0010, 0x0015 }, + { 0x0013, 0x001e }, + { 0x0013, 0x001f }, + { 0x0013, 0x0020 }, + { 0x0013, 0x0021 }, + { 0x0013, 0x0022 }, + { 0x0013, 0x0023 }, + { 0x0013, 0x0024 }, + { 0x0013, 0x0025 }, + { 0x0013, 0x0026 }, + { 0x0012, 0x0045 }, + { 0x0013, 0x0027 }, + { 0x0013, 0x0028 }, + { 0x0013, 0x0029 }, + { 0x0013, 0x002a }, + { 0x0013, 0x002b }, + { 0x0013, 0x002c }, + { 0x0013, 0x002d }, + { 0x0013, 0x002e }, + { 0x0013, 0x002f }, + { 0x0013, 0x0030 }, + { 0x0013, 0x0031 }, + { 0x0013, 0x0032 }, + { 0x0013, 0x0033 }, + { 0x0013, 0x0034 }, + { 0x0013, 0x0035 }, + { 0x0013, 0x0036 }, + { 0x0013, 0x0037 }, + { 0x0013, 0x0038 }, + { 0x0013, 0x0039 }, + { 0x0013, 0x003a }, + { 0x0013, 0x003b }, + { 0x0013, 0x003c }, + { 0x0013, 0x003d }, + { 0x0013, 0x003e }, + { 0x0013, 0x003f }, + { 0x0013, 0x0040 }, + { 0x0013, 0x0041 }, + { 0x0013, 0x0042 }, + { 0x0013, 0x0043 }, + { 0x0013, 0x0044 }, + { 0x0013, 0x0045 }, + { 0x0013, 0x0046 }, + { 0x0013, 0x0047 }, + { 0x0013, 0x0048 }, + { 0x0013, 0x0049 }, + { 0x0013, 0x004a }, + { 0x0013, 0x004b }, + { 0x0013, 0x004c }, + { 0x0013, 0x004d }, + { 0x0013, 0x004e }, + { 0x0013, 0x004f }, + { 0x0013, 0x0050 }, + { 0x0013, 0x0051 }, + { 0x0013, 0x0052 }, + { 0x0013, 0x0053 }, + { 0x0013, 0x0054 }, + { 0x0013, 0x0055 }, + { 0x0013, 0x0056 }, + { 0x0013, 0x0057 }, + { 0x0013, 0x0058 }, + { 0x0013, 0x0059 }, + { 0x0013, 0x005a }, + { 0x0013, 0x005b }, + { 0x0013, 0x005c }, + { 0x0013, 0x005d }, + { 0x0013, 0x005e }, + { 0x0013, 0x005f }, + { 0x0013, 0x0060 }, + { 0x0013, 0x0061 }, + { 0x0013, 0x0062 }, + { 0x0013, 0x0063 }, + { 0x0013, 0x0064 }, + { 0x0013, 0x0065 }, + { 0x0013, 0x0066 }, + { 0x0013, 0x0067 }, + { 0x0013, 0x0068 }, + { 0x0013, 0x0069 }, + { 0x0013, 0x006a }, + { 0x0013, 0x006b }, + { 0x0013, 0x006c }, + { 0x0013, 0x006d }, + { 0x0013, 0x006e }, + { 0x0013, 0x006f }, + { 0x0013, 0x0070 }, + { 0x0013, 0x0071 }, + { 0x0013, 0x0072 }, + { 0x0013, 0x0073 }, + { 0x0013, 0x0074 }, + { 0x0013, 0x0075 }, + { 0x0013, 0x0076 }, + { 0x0013, 0x0077 }, + { 0x0013, 0x0078 }, + { 0x0013, 0x0079 }, + { 0x0013, 0x007a }, + { 0x0013, 0x007b }, + { 0x0013, 0x007c }, + { 0x0013, 0x007d }, + { 0x0013, 0x007e }, + { 0x0013, 0x007f }, + { 0x0013, 0x0080 }, + { 0x0013, 0x0081 }, + { 0x0013, 0x0082 }, + { 0x0013, 0x0083 }, + { 0x0013, 0x0084 }, + { 0x0013, 0x0085 }, + { 0x0013, 0x0086 }, + { 0x0013, 0x0087 }, + { 0x0013, 0x0088 }, + { 0x0013, 0x0089 }, + { 0x0012, 0x0046 }, + { 0x0012, 0x0047 }, + { 0x0012, 0x0048 }, + { 0x0012, 0x0049 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc43[196][2] = + { + { 0x0001, 0x0001 }, + { 0x0003, 0x0001 }, + { 0x0006, 0x0001 }, + { 0x0009, 0x0002 }, + { 0x000c, 0x0003 }, + { 0x0010, 0x0017 }, + { 0x0013, 0x0000 }, + { 0x0013, 0x0001 }, + { 0x0013, 0x0002 }, + { 0x0013, 0x0003 }, + { 0x0013, 0x0004 }, + { 0x0013, 0x0005 }, + { 0x0013, 0x0006 }, + { 0x0013, 0x0007 }, + { 0x0003, 0x0002 }, + { 0x0003, 0x0003 }, + { 0x0005, 0x0001 }, + { 0x0009, 0x0003 }, + { 0x000c, 0x0004 }, + { 0x0010, 0x0018 }, + { 0x0012, 0x0050 }, + { 0x0013, 0x0008 }, + { 0x0013, 0x0009 }, + { 0x0013, 0x000a }, + { 0x0013, 0x000b }, + { 0x0013, 0x000c }, + { 0x0013, 0x000d }, + { 0x0013, 0x000e }, + { 0x0005, 0x0002 }, + { 0x0005, 0x0003 }, + { 0x0008, 0x0003 }, + { 0x000a, 0x0002 }, + { 0x000d, 0x0004 }, + { 0x0011, 0x002a }, + { 0x0013, 0x000f }, + { 0x0013, 0x0010 }, + { 0x0013, 0x0011 }, + { 0x0013, 0x0012 }, + { 0x0013, 0x0013 }, + { 0x0013, 0x0014 }, + { 0x0013, 0x0015 }, + { 0x0013, 0x0016 }, + { 0x0009, 0x0004 }, + { 0x0009, 0x0005 }, + { 0x000a, 0x0003 }, + { 0x000c, 0x0005 }, + { 0x000f, 0x000d }, + { 0x0012, 0x0051 }, + { 0x0013, 0x0017 }, + { 0x0013, 0x0018 }, + { 0x0013, 0x0019 }, + { 0x0013, 0x001a }, + { 0x0013, 0x001b }, + { 0x0013, 0x001c }, + { 0x0013, 0x001d }, + { 0x0013, 0x001e }, + { 0x000c, 0x0006 }, + { 0x000c, 0x0007 }, + { 0x000d, 0x0005 }, + { 0x000f, 0x000e }, + { 0x0011, 0x002b }, + { 0x0013, 0x001f }, + { 0x0013, 0x0020 }, + { 0x0013, 0x0021 }, + { 0x0013, 0x0022 }, + { 0x0013, 0x0023 }, + { 0x0013, 0x0024 }, + { 0x0013, 0x0025 }, + { 0x0013, 0x0026 }, + { 0x0013, 0x0027 }, + { 0x0011, 0x002c }, + { 0x000f, 0x000f }, + { 0x0010, 0x0019 }, + { 0x0012, 0x0052 }, + { 0x0012, 0x0053 }, + { 0x0013, 0x0028 }, + { 0x0013, 0x0029 }, + { 0x0013, 0x002a }, + { 0x0013, 0x002b }, + { 0x0013, 0x002c }, + { 0x0013, 0x002d }, + { 0x0013, 0x002e }, + { 0x0013, 0x002f }, + { 0x0013, 0x0030 }, + { 0x0013, 0x0031 }, + { 0x0011, 0x002d }, + { 0x0013, 0x0032 }, + { 0x0013, 0x0033 }, + { 0x0013, 0x0034 }, + { 0x0013, 0x0035 }, + { 0x0013, 0x0036 }, + { 0x0013, 0x0037 }, + { 0x0013, 0x0038 }, + { 0x0013, 0x0039 }, + { 0x0013, 0x003a }, + { 0x0013, 0x003b }, + { 0x0013, 0x003c }, + { 0x0013, 0x003d }, + { 0x0013, 0x003e }, + { 0x0013, 0x003f }, + { 0x0013, 0x0040 }, + { 0x0013, 0x0041 }, + { 0x0013, 0x0042 }, + { 0x0013, 0x0043 }, + { 0x0013, 0x0044 }, + { 0x0013, 0x0045 }, + { 0x0013, 0x0046 }, + { 0x0013, 0x0047 }, + { 0x0013, 0x0048 }, + { 0x0013, 0x0049 }, + { 0x0013, 0x004a }, + { 0x0013, 0x004b }, + { 0x0013, 0x004c }, + { 0x0013, 0x004d }, + { 0x0013, 0x004e }, + { 0x0013, 0x004f }, + { 0x0013, 0x0050 }, + { 0x0013, 0x0051 }, + { 0x0013, 0x0052 }, + { 0x0013, 0x0053 }, + { 0x0013, 0x0054 }, + { 0x0013, 0x0055 }, + { 0x0013, 0x0056 }, + { 0x0013, 0x0057 }, + { 0x0013, 0x0058 }, + { 0x0013, 0x0059 }, + { 0x0013, 0x005a }, + { 0x0013, 0x005b }, + { 0x0013, 0x005c }, + { 0x0013, 0x005d }, + { 0x0013, 0x005e }, + { 0x0013, 0x005f }, + { 0x0013, 0x0060 }, + { 0x0013, 0x0061 }, + { 0x0013, 0x0062 }, + { 0x0013, 0x0063 }, + { 0x0013, 0x0064 }, + { 0x0013, 0x0065 }, + { 0x0013, 0x0066 }, + { 0x0013, 0x0067 }, + { 0x0013, 0x0068 }, + { 0x0013, 0x0069 }, + { 0x0013, 0x006a }, + { 0x0013, 0x006b }, + { 0x0013, 0x006c }, + { 0x0013, 0x006d }, + { 0x0013, 0x006e }, + { 0x0013, 0x006f }, + { 0x0013, 0x0070 }, + { 0x0013, 0x0071 }, + { 0x0013, 0x0072 }, + { 0x0013, 0x0073 }, + { 0x0013, 0x0074 }, + { 0x0013, 0x0075 }, + { 0x0013, 0x0076 }, + { 0x0013, 0x0077 }, + { 0x0013, 0x0078 }, + { 0x0013, 0x0079 }, + { 0x0013, 0x007a }, + { 0x0013, 0x007b }, + { 0x0013, 0x007c }, + { 0x0013, 0x007d }, + { 0x0013, 0x007e }, + { 0x0013, 0x007f }, + { 0x0013, 0x0080 }, + { 0x0013, 0x0081 }, + { 0x0013, 0x0082 }, + { 0x0013, 0x0083 }, + { 0x0013, 0x0084 }, + { 0x0013, 0x0085 }, + { 0x0013, 0x0086 }, + { 0x0013, 0x0087 }, + { 0x0013, 0x0088 }, + { 0x0013, 0x0089 }, + { 0x0013, 0x008a }, + { 0x0013, 0x008b }, + { 0x0013, 0x008c }, + { 0x0013, 0x008d }, + { 0x0013, 0x008e }, + { 0x0013, 0x008f }, + { 0x0013, 0x0090 }, + { 0x0013, 0x0091 }, + { 0x0013, 0x0092 }, + { 0x0013, 0x0093 }, + { 0x0013, 0x0094 }, + { 0x0013, 0x0095 }, + { 0x0013, 0x0096 }, + { 0x0013, 0x0097 }, + { 0x0013, 0x0098 }, + { 0x0013, 0x0099 }, + { 0x0013, 0x009a }, + { 0x0013, 0x009b }, + { 0x0013, 0x009c }, + { 0x0013, 0x009d }, + { 0x0013, 0x009e }, + { 0x0013, 0x009f }, + + }; + +const uint16_t c_aauiLCLDHuffEnc44[289][2] = + { + { 0x0001, 0x0001 }, + { 0x0003, 0x0001 }, + { 0x0006, 0x0002 }, + { 0x0008, 0x0002 }, + { 0x000b, 0x0002 }, + { 0x000f, 0x000a }, + { 0x0011, 0x0022 }, + { 0x0014, 0x0000 }, + { 0x0014, 0x0001 }, + { 0x0014, 0x0002 }, + { 0x0014, 0x0003 }, + { 0x0014, 0x0004 }, + { 0x0014, 0x0005 }, + { 0x0014, 0x0006 }, + { 0x0014, 0x0007 }, + { 0x0014, 0x0008 }, + { 0x0014, 0x0009 }, + { 0x0003, 0x0002 }, + { 0x0003, 0x0003 }, + { 0x0005, 0x0002 }, + { 0x0008, 0x0003 }, + { 0x000b, 0x0003 }, + { 0x000e, 0x0007 }, + { 0x0012, 0x003f }, + { 0x0014, 0x000a }, + { 0x0014, 0x000b }, + { 0x0014, 0x000c }, + { 0x0014, 0x000d }, + { 0x0014, 0x000e }, + { 0x0014, 0x000f }, + { 0x0014, 0x0010 }, + { 0x0014, 0x0011 }, + { 0x0014, 0x0012 }, + { 0x0014, 0x0013 }, + { 0x0006, 0x0003 }, + { 0x0005, 0x0003 }, + { 0x0007, 0x0003 }, + { 0x0009, 0x0002 }, + { 0x000c, 0x0003 }, + { 0x000f, 0x000b }, + { 0x0012, 0x0040 }, + { 0x0014, 0x0014 }, + { 0x0014, 0x0015 }, + { 0x0014, 0x0016 }, + { 0x0014, 0x0017 }, + { 0x0014, 0x0018 }, + { 0x0014, 0x0019 }, + { 0x0014, 0x001a }, + { 0x0014, 0x001b }, + { 0x0014, 0x001c }, + { 0x0014, 0x001d }, + { 0x0008, 0x0004 }, + { 0x0008, 0x0005 }, + { 0x0009, 0x0003 }, + { 0x000b, 0x0004 }, + { 0x000d, 0x0005 }, + { 0x0010, 0x0013 }, + { 0x0014, 0x001e }, + { 0x0014, 0x001f }, + { 0x0014, 0x0020 }, + { 0x0014, 0x0021 }, + { 0x0014, 0x0022 }, + { 0x0014, 0x0023 }, + { 0x0014, 0x0024 }, + { 0x0014, 0x0025 }, + { 0x0014, 0x0026 }, + { 0x0014, 0x0027 }, + { 0x0014, 0x0028 }, + { 0x000b, 0x0005 }, + { 0x000b, 0x0006 }, + { 0x000b, 0x0007 }, + { 0x000e, 0x0008 }, + { 0x0011, 0x0023 }, + { 0x0012, 0x0041 }, + { 0x0014, 0x0029 }, + { 0x0014, 0x002a }, + { 0x0013, 0x007b }, + { 0x0014, 0x002b }, + { 0x0014, 0x002c }, + { 0x0014, 0x002d }, + { 0x0014, 0x002e }, + { 0x0014, 0x002f }, + { 0x0014, 0x0030 }, + { 0x0014, 0x0031 }, + { 0x0014, 0x0032 }, + { 0x000f, 0x000c }, + { 0x000e, 0x0009 }, + { 0x000f, 0x000d }, + { 0x0011, 0x0024 }, + { 0x0012, 0x0042 }, + { 0x0014, 0x0033 }, + { 0x0014, 0x0034 }, + { 0x0014, 0x0035 }, + { 0x0014, 0x0036 }, + { 0x0014, 0x0037 }, + { 0x0014, 0x0038 }, + { 0x0014, 0x0039 }, + { 0x0014, 0x003a }, + { 0x0014, 0x003b }, + { 0x0014, 0x003c }, + { 0x0014, 0x003d }, + { 0x0014, 0x003e }, + { 0x0013, 0x007c }, + { 0x0011, 0x0025 }, + { 0x0012, 0x0043 }, + { 0x0014, 0x003f }, + { 0x0014, 0x0040 }, + { 0x0014, 0x0041 }, + { 0x0014, 0x0042 }, + { 0x0014, 0x0043 }, + { 0x0014, 0x0044 }, + { 0x0014, 0x0045 }, + { 0x0014, 0x0046 }, + { 0x0014, 0x0047 }, + { 0x0014, 0x0048 }, + { 0x0014, 0x0049 }, + { 0x0014, 0x004a }, + { 0x0014, 0x004b }, + { 0x0014, 0x004c }, + { 0x0014, 0x004d }, + { 0x0014, 0x004e }, + { 0x0014, 0x004f }, + { 0x0014, 0x0050 }, + { 0x0014, 0x0051 }, + { 0x0014, 0x0052 }, + { 0x0014, 0x0053 }, + { 0x0014, 0x0054 }, + { 0x0014, 0x0055 }, + { 0x0014, 0x0056 }, + { 0x0014, 0x0057 }, + { 0x0014, 0x0058 }, + { 0x0014, 0x0059 }, + { 0x0014, 0x005a }, + { 0x0014, 0x005b }, + { 0x0014, 0x005c }, + { 0x0014, 0x005d }, + { 0x0014, 0x005e }, + { 0x0014, 0x005f }, + { 0x0014, 0x0060 }, + { 0x0014, 0x0061 }, + { 0x0014, 0x0062 }, + { 0x0014, 0x0063 }, + { 0x0014, 0x0064 }, + { 0x0014, 0x0065 }, + { 0x0014, 0x0066 }, + { 0x0014, 0x0067 }, + { 0x0014, 0x0068 }, + { 0x0014, 0x0069 }, + { 0x0014, 0x006a }, + { 0x0014, 0x006b }, + { 0x0014, 0x006c }, + { 0x0014, 0x006d }, + { 0x0014, 0x006e }, + { 0x0014, 0x006f }, + { 0x0014, 0x0070 }, + { 0x0014, 0x0071 }, + { 0x0014, 0x0072 }, + { 0x0014, 0x0073 }, + { 0x0014, 0x0074 }, + { 0x0014, 0x0075 }, + { 0x0014, 0x0076 }, + { 0x0014, 0x0077 }, + { 0x0014, 0x0078 }, + { 0x0014, 0x0079 }, + { 0x0014, 0x007a }, + { 0x0014, 0x007b }, + { 0x0014, 0x007c }, + { 0x0014, 0x007d }, + { 0x0014, 0x007e }, + { 0x0014, 0x007f }, + { 0x0014, 0x0080 }, + { 0x0014, 0x0081 }, + { 0x0014, 0x0082 }, + { 0x0014, 0x0083 }, + { 0x0014, 0x0084 }, + { 0x0014, 0x0085 }, + { 0x0014, 0x0086 }, + { 0x0014, 0x0087 }, + { 0x0014, 0x0088 }, + { 0x0014, 0x0089 }, + { 0x0014, 0x008a }, + { 0x0014, 0x008b }, + { 0x0014, 0x008c }, + { 0x0014, 0x008d }, + { 0x0014, 0x008e }, + { 0x0014, 0x008f }, + { 0x0014, 0x0090 }, + { 0x0014, 0x0091 }, + { 0x0014, 0x0092 }, + { 0x0014, 0x0093 }, + { 0x0014, 0x0094 }, + { 0x0014, 0x0095 }, + { 0x0014, 0x0096 }, + { 0x0014, 0x0097 }, + { 0x0014, 0x0098 }, + { 0x0014, 0x0099 }, + { 0x0014, 0x009a }, + { 0x0014, 0x009b }, + { 0x0014, 0x009c }, + { 0x0014, 0x009d }, + { 0x0014, 0x009e }, + { 0x0014, 0x009f }, + { 0x0014, 0x00a0 }, + { 0x0014, 0x00a1 }, + { 0x0014, 0x00a2 }, + { 0x0014, 0x00a3 }, + { 0x0014, 0x00a4 }, + { 0x0014, 0x00a5 }, + { 0x0014, 0x00a6 }, + { 0x0014, 0x00a7 }, + { 0x0014, 0x00a8 }, + { 0x0014, 0x00a9 }, + { 0x0014, 0x00aa }, + { 0x0014, 0x00ab }, + { 0x0014, 0x00ac }, + { 0x0014, 0x00ad }, + { 0x0014, 0x00ae }, + { 0x0014, 0x00af }, + { 0x0014, 0x00b0 }, + { 0x0014, 0x00b1 }, + { 0x0014, 0x00b2 }, + { 0x0014, 0x00b3 }, + { 0x0014, 0x00b4 }, + { 0x0014, 0x00b5 }, + { 0x0014, 0x00b6 }, + { 0x0014, 0x00b7 }, + { 0x0014, 0x00b8 }, + { 0x0014, 0x00b9 }, + { 0x0014, 0x00ba }, + { 0x0014, 0x00bb }, + { 0x0014, 0x00bc }, + { 0x0014, 0x00bd }, + { 0x0014, 0x00be }, + { 0x0014, 0x00bf }, + { 0x0014, 0x00c0 }, + { 0x0014, 0x00c1 }, + { 0x0014, 0x00c2 }, + { 0x0014, 0x00c3 }, + { 0x0014, 0x00c4 }, + { 0x0014, 0x00c5 }, + { 0x0014, 0x00c6 }, + { 0x0014, 0x00c7 }, + { 0x0014, 0x00c8 }, + { 0x0014, 0x00c9 }, + { 0x0014, 0x00ca }, + { 0x0014, 0x00cb }, + { 0x0014, 0x00cc }, + { 0x0014, 0x00cd }, + { 0x0014, 0x00ce }, + { 0x0014, 0x00cf }, + { 0x0014, 0x00d0 }, + { 0x0014, 0x00d1 }, + { 0x0014, 0x00d2 }, + { 0x0014, 0x00d3 }, + { 0x0014, 0x00d4 }, + { 0x0014, 0x00d5 }, + { 0x0014, 0x00d6 }, + { 0x0014, 0x00d7 }, + { 0x0014, 0x00d8 }, + { 0x0014, 0x00d9 }, + { 0x0014, 0x00da }, + { 0x0014, 0x00db }, + { 0x0014, 0x00dc }, + { 0x0014, 0x00dd }, + { 0x0014, 0x00de }, + { 0x0014, 0x00df }, + { 0x0014, 0x00e0 }, + { 0x0014, 0x00e1 }, + { 0x0014, 0x00e2 }, + { 0x0014, 0x00e3 }, + { 0x0014, 0x00e4 }, + { 0x0014, 0x00e5 }, + { 0x0014, 0x00e6 }, + { 0x0014, 0x00e7 }, + { 0x0014, 0x00e8 }, + { 0x0014, 0x00e9 }, + { 0x0014, 0x00ea }, + { 0x0014, 0x00eb }, + { 0x0014, 0x00ec }, + { 0x0014, 0x00ed }, + { 0x0014, 0x00ee }, + { 0x0014, 0x00ef }, + { 0x0014, 0x00f0 }, + { 0x0014, 0x00f1 }, + { 0x0014, 0x00f2 }, + { 0x0014, 0x00f3 }, + { 0x0014, 0x00f4 }, + { 0x0014, 0x00f5 }, + { 0x0013, 0x007d }, + + }; + + +const uint16_t c_aauiLCLDHuffEnc45[324][2] = + { + { 0x0002, 0x0002 }, + { 0x0003, 0x0002 }, + { 0x0005, 0x0003 }, + { 0x0007, 0x0002 }, + { 0x0009, 0x0003 }, + { 0x000c, 0x0005 }, + { 0x0010, 0x0025 }, + { 0x0012, 0x0088 }, + { 0x0013, 0x0000 }, + { 0x0013, 0x0001 }, + { 0x0013, 0x0002 }, + { 0x0013, 0x0003 }, + { 0x0013, 0x0004 }, + { 0x0013, 0x0005 }, + { 0x0013, 0x0006 }, + { 0x0013, 0x0007 }, + { 0x0013, 0x0008 }, + { 0x0013, 0x0009 }, + { 0x0002, 0x0003 }, + { 0x0003, 0x0003 }, + { 0x0005, 0x0004 }, + { 0x0006, 0x0003 }, + { 0x0009, 0x0004 }, + { 0x000b, 0x0004 }, + { 0x000f, 0x0014 }, + { 0x0011, 0x0048 }, + { 0x0013, 0x000a }, + { 0x0013, 0x000b }, + { 0x0013, 0x000c }, + { 0x0013, 0x000d }, + { 0x0013, 0x000e }, + { 0x0013, 0x000f }, + { 0x0013, 0x0010 }, + { 0x0013, 0x0011 }, + { 0x0013, 0x0012 }, + { 0x0013, 0x0013 }, + { 0x0005, 0x0005 }, + { 0x0004, 0x0003 }, + { 0x0006, 0x0004 }, + { 0x0007, 0x0003 }, + { 0x000a, 0x0004 }, + { 0x000d, 0x0007 }, + { 0x000f, 0x0015 }, + { 0x0013, 0x0014 }, + { 0x0013, 0x0015 }, + { 0x0013, 0x0016 }, + { 0x0013, 0x0017 }, + { 0x0013, 0x0018 }, + { 0x0013, 0x0019 }, + { 0x0013, 0x001a }, + { 0x0013, 0x001b }, + { 0x0013, 0x001c }, + { 0x0013, 0x001d }, + { 0x0013, 0x001e }, + { 0x0007, 0x0004 }, + { 0x0006, 0x0005 }, + { 0x0007, 0x0005 }, + { 0x0009, 0x0005 }, + { 0x000b, 0x0005 }, + { 0x000d, 0x0008 }, + { 0x0010, 0x0026 }, + { 0x0012, 0x0089 }, + { 0x0012, 0x008a }, + { 0x0013, 0x001f }, + { 0x0013, 0x0020 }, + { 0x0013, 0x0021 }, + { 0x0013, 0x0022 }, + { 0x0013, 0x0023 }, + { 0x0013, 0x0024 }, + { 0x0013, 0x0025 }, + { 0x0013, 0x0026 }, + { 0x0013, 0x0027 }, + { 0x0009, 0x0006 }, + { 0x0009, 0x0007 }, + { 0x000a, 0x0005 }, + { 0x000b, 0x0006 }, + { 0x000d, 0x0009 }, + { 0x000f, 0x0016 }, + { 0x0011, 0x0049 }, + { 0x0013, 0x0028 }, + { 0x0013, 0x0029 }, + { 0x0013, 0x002a }, + { 0x0013, 0x002b }, + { 0x0013, 0x002c }, + { 0x0013, 0x002d }, + { 0x0013, 0x002e }, + { 0x0013, 0x002f }, + { 0x0013, 0x0030 }, + { 0x0013, 0x0031 }, + { 0x0013, 0x0032 }, + { 0x000c, 0x0006 }, + { 0x000b, 0x0007 }, + { 0x000c, 0x0007 }, + { 0x000e, 0x000d }, + { 0x0010, 0x0027 }, + { 0x0012, 0x008b }, + { 0x0012, 0x008c }, + { 0x0013, 0x0033 }, + { 0x0013, 0x0034 }, + { 0x0013, 0x0035 }, + { 0x0013, 0x0036 }, + { 0x0013, 0x0037 }, + { 0x0013, 0x0038 }, + { 0x0013, 0x0039 }, + { 0x0013, 0x003a }, + { 0x0013, 0x003b }, + { 0x0013, 0x003c }, + { 0x0013, 0x003d }, + { 0x000f, 0x0017 }, + { 0x000f, 0x0018 }, + { 0x000f, 0x0019 }, + { 0x0012, 0x008d }, + { 0x0013, 0x003e }, + { 0x0013, 0x003f }, + { 0x0013, 0x0040 }, + { 0x0013, 0x0041 }, + { 0x0013, 0x0042 }, + { 0x0013, 0x0043 }, + { 0x0013, 0x0044 }, + { 0x0013, 0x0045 }, + { 0x0013, 0x0046 }, + { 0x0013, 0x0047 }, + { 0x0013, 0x0048 }, + { 0x0013, 0x0049 }, + { 0x0013, 0x004a }, + { 0x0013, 0x004b }, + { 0x0013, 0x004c }, + { 0x0012, 0x008e }, + { 0x0012, 0x008f }, + { 0x0013, 0x004d }, + { 0x0013, 0x004e }, + { 0x0013, 0x004f }, + { 0x0013, 0x0050 }, + { 0x0013, 0x0051 }, + { 0x0013, 0x0052 }, + { 0x0013, 0x0053 }, + { 0x0013, 0x0054 }, + { 0x0013, 0x0055 }, + { 0x0013, 0x0056 }, + { 0x0013, 0x0057 }, + { 0x0013, 0x0058 }, + { 0x0013, 0x0059 }, + { 0x0013, 0x005a }, + { 0x0013, 0x005b }, + { 0x0013, 0x005c }, + { 0x0013, 0x005d }, + { 0x0013, 0x005e }, + { 0x0013, 0x005f }, + { 0x0013, 0x0060 }, + { 0x0013, 0x0061 }, + { 0x0013, 0x0062 }, + { 0x0013, 0x0063 }, + { 0x0013, 0x0064 }, + { 0x0013, 0x0065 }, + { 0x0013, 0x0066 }, + { 0x0013, 0x0067 }, + { 0x0013, 0x0068 }, + { 0x0013, 0x0069 }, + { 0x0013, 0x006a }, + { 0x0013, 0x006b }, + { 0x0013, 0x006c }, + { 0x0013, 0x006d }, + { 0x0013, 0x006e }, + { 0x0013, 0x006f }, + { 0x0013, 0x0070 }, + { 0x0013, 0x0071 }, + { 0x0013, 0x0072 }, + { 0x0013, 0x0073 }, + { 0x0013, 0x0074 }, + { 0x0013, 0x0075 }, + { 0x0013, 0x0076 }, + { 0x0013, 0x0077 }, + { 0x0013, 0x0078 }, + { 0x0013, 0x0079 }, + { 0x0013, 0x007a }, + { 0x0013, 0x007b }, + { 0x0013, 0x007c }, + { 0x0013, 0x007d }, + { 0x0013, 0x007e }, + { 0x0013, 0x007f }, + { 0x0013, 0x0080 }, + { 0x0013, 0x0081 }, + { 0x0013, 0x0082 }, + { 0x0013, 0x0083 }, + { 0x0013, 0x0084 }, + { 0x0013, 0x0085 }, + { 0x0013, 0x0086 }, + { 0x0013, 0x0087 }, + { 0x0013, 0x0088 }, + { 0x0013, 0x0089 }, + { 0x0013, 0x008a }, + { 0x0013, 0x008b }, + { 0x0013, 0x008c }, + { 0x0013, 0x008d }, + { 0x0013, 0x008e }, + { 0x0013, 0x008f }, + { 0x0013, 0x0090 }, + { 0x0013, 0x0091 }, + { 0x0013, 0x0092 }, + { 0x0013, 0x0093 }, + { 0x0013, 0x0094 }, + { 0x0013, 0x0095 }, + { 0x0013, 0x0096 }, + { 0x0013, 0x0097 }, + { 0x0013, 0x0098 }, + { 0x0013, 0x0099 }, + { 0x0013, 0x009a }, + { 0x0013, 0x009b }, + { 0x0013, 0x009c }, + { 0x0013, 0x009d }, + { 0x0013, 0x009e }, + { 0x0013, 0x009f }, + { 0x0013, 0x00a0 }, + { 0x0013, 0x00a1 }, + { 0x0013, 0x00a2 }, + { 0x0013, 0x00a3 }, + { 0x0013, 0x00a4 }, + { 0x0013, 0x00a5 }, + { 0x0013, 0x00a6 }, + { 0x0013, 0x00a7 }, + { 0x0013, 0x00a8 }, + { 0x0013, 0x00a9 }, + { 0x0013, 0x00aa }, + { 0x0013, 0x00ab }, + { 0x0013, 0x00ac }, + { 0x0013, 0x00ad }, + { 0x0013, 0x00ae }, + { 0x0013, 0x00af }, + { 0x0013, 0x00b0 }, + { 0x0013, 0x00b1 }, + { 0x0013, 0x00b2 }, + { 0x0013, 0x00b3 }, + { 0x0013, 0x00b4 }, + { 0x0013, 0x00b5 }, + { 0x0013, 0x00b6 }, + { 0x0013, 0x00b7 }, + { 0x0013, 0x00b8 }, + { 0x0013, 0x00b9 }, + { 0x0013, 0x00ba }, + { 0x0013, 0x00bb }, + { 0x0013, 0x00bc }, + { 0x0013, 0x00bd }, + { 0x0013, 0x00be }, + { 0x0013, 0x00bf }, + { 0x0013, 0x00c0 }, + { 0x0013, 0x00c1 }, + { 0x0013, 0x00c2 }, + { 0x0013, 0x00c3 }, + { 0x0013, 0x00c4 }, + { 0x0013, 0x00c5 }, + { 0x0013, 0x00c6 }, + { 0x0013, 0x00c7 }, + { 0x0013, 0x00c8 }, + { 0x0013, 0x00c9 }, + { 0x0013, 0x00ca }, + { 0x0013, 0x00cb }, + { 0x0013, 0x00cc }, + { 0x0013, 0x00cd }, + { 0x0013, 0x00ce }, + { 0x0013, 0x00cf }, + { 0x0013, 0x00d0 }, + { 0x0013, 0x00d1 }, + { 0x0013, 0x00d2 }, + { 0x0013, 0x00d3 }, + { 0x0013, 0x00d4 }, + { 0x0013, 0x00d5 }, + { 0x0013, 0x00d6 }, + { 0x0013, 0x00d7 }, + { 0x0013, 0x00d8 }, + { 0x0013, 0x00d9 }, + { 0x0013, 0x00da }, + { 0x0013, 0x00db }, + { 0x0013, 0x00dc }, + { 0x0013, 0x00dd }, + { 0x0013, 0x00de }, + { 0x0013, 0x00df }, + { 0x0013, 0x00e0 }, + { 0x0013, 0x00e1 }, + { 0x0013, 0x00e2 }, + { 0x0013, 0x00e3 }, + { 0x0013, 0x00e4 }, + { 0x0013, 0x00e5 }, + { 0x0013, 0x00e6 }, + { 0x0013, 0x00e7 }, + { 0x0013, 0x00e8 }, + { 0x0013, 0x00e9 }, + { 0x0013, 0x00ea }, + { 0x0013, 0x00eb }, + { 0x0013, 0x00ec }, + { 0x0013, 0x00ed }, + { 0x0013, 0x00ee }, + { 0x0013, 0x00ef }, + { 0x0013, 0x00f0 }, + { 0x0013, 0x00f1 }, + { 0x0013, 0x00f2 }, + { 0x0013, 0x00f3 }, + { 0x0013, 0x00f4 }, + { 0x0013, 0x00f5 }, + { 0x0013, 0x00f6 }, + { 0x0013, 0x00f7 }, + { 0x0013, 0x00f8 }, + { 0x0013, 0x00f9 }, + { 0x0013, 0x00fa }, + { 0x0013, 0x00fb }, + { 0x0013, 0x00fc }, + { 0x0013, 0x00fd }, + { 0x0013, 0x00fe }, + { 0x0013, 0x00ff }, + { 0x0013, 0x0100 }, + { 0x0013, 0x0101 }, + { 0x0013, 0x0102 }, + { 0x0013, 0x0103 }, + { 0x0013, 0x0104 }, + { 0x0013, 0x0105 }, + { 0x0013, 0x0106 }, + { 0x0013, 0x0107 }, + { 0x0013, 0x0108 }, + { 0x0013, 0x0109 }, + { 0x0013, 0x010a }, + { 0x0013, 0x010b }, + { 0x0013, 0x010c }, + { 0x0013, 0x010d }, + { 0x0013, 0x010e }, + { 0x0013, 0x010f }, + + }; + +const uint16_t c_aauiLCLDHuffEnc46[400][2] = + { + { 0x0002, 0x0002 }, + { 0x0003, 0x0002 }, + { 0x0005, 0x0003 }, + { 0x0007, 0x0004 }, + { 0x0009, 0x0005 }, + { 0x000b, 0x0006 }, + { 0x000d, 0x000a }, + { 0x000f, 0x0018 }, + { 0x0012, 0x00a6 }, + { 0x0013, 0x0000 }, + { 0x0013, 0x0001 }, + { 0x0013, 0x0002 }, + { 0x0013, 0x0003 }, + { 0x0013, 0x0004 }, + { 0x0013, 0x0005 }, + { 0x0013, 0x0006 }, + { 0x0013, 0x0007 }, + { 0x0013, 0x0008 }, + { 0x0013, 0x0009 }, + { 0x0013, 0x000a }, + { 0x0002, 0x0003 }, + { 0x0003, 0x0003 }, + { 0x0005, 0x0004 }, + { 0x0006, 0x0004 }, + { 0x0008, 0x0004 }, + { 0x000a, 0x0006 }, + { 0x000c, 0x0008 }, + { 0x000e, 0x0011 }, + { 0x0012, 0x00a7 }, + { 0x0013, 0x000b }, + { 0x0013, 0x000c }, + { 0x0013, 0x000d }, + { 0x0013, 0x000e }, + { 0x0013, 0x000f }, + { 0x0013, 0x0010 }, + { 0x0013, 0x0011 }, + { 0x0013, 0x0012 }, + { 0x0013, 0x0013 }, + { 0x0013, 0x0014 }, + { 0x0013, 0x0015 }, + { 0x0005, 0x0005 }, + { 0x0005, 0x0006 }, + { 0x0005, 0x0007 }, + { 0x0007, 0x0005 }, + { 0x0009, 0x0006 }, + { 0x000b, 0x0007 }, + { 0x000d, 0x000b }, + { 0x000f, 0x0019 }, + { 0x0013, 0x0016 }, + { 0x0013, 0x0017 }, + { 0x0013, 0x0018 }, + { 0x0013, 0x0019 }, + { 0x0013, 0x001a }, + { 0x0013, 0x001b }, + { 0x0013, 0x001c }, + { 0x0013, 0x001d }, + { 0x0013, 0x001e }, + { 0x0013, 0x001f }, + { 0x0013, 0x0020 }, + { 0x0013, 0x0021 }, + { 0x0007, 0x0006 }, + { 0x0006, 0x0005 }, + { 0x0007, 0x0007 }, + { 0x0008, 0x0005 }, + { 0x000a, 0x0007 }, + { 0x000c, 0x0009 }, + { 0x000e, 0x0012 }, + { 0x000f, 0x001a }, + { 0x0012, 0x00a8 }, + { 0x0013, 0x0022 }, + { 0x0013, 0x0023 }, + { 0x0013, 0x0024 }, + { 0x0013, 0x0025 }, + { 0x0013, 0x0026 }, + { 0x0013, 0x0027 }, + { 0x0013, 0x0028 }, + { 0x0013, 0x0029 }, + { 0x0013, 0x002a }, + { 0x0013, 0x002b }, + { 0x0013, 0x002c }, + { 0x0009, 0x0007 }, + { 0x0008, 0x0006 }, + { 0x0008, 0x0007 }, + { 0x000a, 0x0008 }, + { 0x000b, 0x0008 }, + { 0x000d, 0x000c }, + { 0x000e, 0x0013 }, + { 0x0010, 0x002c }, + { 0x0013, 0x002d }, + { 0x0013, 0x002e }, + { 0x0013, 0x002f }, + { 0x0013, 0x0030 }, + { 0x0013, 0x0031 }, + { 0x0013, 0x0032 }, + { 0x0013, 0x0033 }, + { 0x0013, 0x0034 }, + { 0x0013, 0x0035 }, + { 0x0013, 0x0036 }, + { 0x0013, 0x0037 }, + { 0x0013, 0x0038 }, + { 0x000b, 0x0009 }, + { 0x000a, 0x0009 }, + { 0x000b, 0x000a }, + { 0x000b, 0x000b }, + { 0x000d, 0x000d }, + { 0x000f, 0x001b }, + { 0x0010, 0x002d }, + { 0x0013, 0x0039 }, + { 0x0013, 0x003a }, + { 0x0013, 0x003b }, + { 0x0013, 0x003c }, + { 0x0013, 0x003d }, + { 0x0013, 0x003e }, + { 0x0013, 0x003f }, + { 0x0013, 0x0040 }, + { 0x0013, 0x0041 }, + { 0x0013, 0x0042 }, + { 0x0013, 0x0043 }, + { 0x0013, 0x0044 }, + { 0x0013, 0x0045 }, + { 0x000d, 0x000e }, + { 0x000c, 0x000a }, + { 0x000c, 0x000b }, + { 0x000d, 0x000f }, + { 0x000f, 0x001c }, + { 0x000f, 0x001d }, + { 0x0013, 0x0046 }, + { 0x0013, 0x0047 }, + { 0x0013, 0x0048 }, + { 0x0013, 0x0049 }, + { 0x0013, 0x004a }, + { 0x0013, 0x004b }, + { 0x0013, 0x004c }, + { 0x0013, 0x004d }, + { 0x0013, 0x004e }, + { 0x0013, 0x004f }, + { 0x0013, 0x0050 }, + { 0x0013, 0x0051 }, + { 0x0013, 0x0052 }, + { 0x0013, 0x0053 }, + { 0x000f, 0x001e }, + { 0x000f, 0x001f }, + { 0x000f, 0x0020 }, + { 0x000f, 0x0021 }, + { 0x0010, 0x002e }, + { 0x0012, 0x00a9 }, + { 0x0013, 0x0054 }, + { 0x0013, 0x0055 }, + { 0x0012, 0x00aa }, + { 0x0013, 0x0056 }, + { 0x0013, 0x0057 }, + { 0x0013, 0x0058 }, + { 0x0013, 0x0059 }, + { 0x0013, 0x005a }, + { 0x0013, 0x005b }, + { 0x0013, 0x005c }, + { 0x0013, 0x005d }, + { 0x0013, 0x005e }, + { 0x0013, 0x005f }, + { 0x0013, 0x0060 }, + { 0x0013, 0x0061 }, + { 0x0010, 0x002f }, + { 0x0013, 0x0062 }, + { 0x0011, 0x0057 }, + { 0x0013, 0x0063 }, + { 0x0013, 0x0064 }, + { 0x0013, 0x0065 }, + { 0x0013, 0x0066 }, + { 0x0013, 0x0067 }, + { 0x0013, 0x0068 }, + { 0x0013, 0x0069 }, + { 0x0013, 0x006a }, + { 0x0013, 0x006b }, + { 0x0013, 0x006c }, + { 0x0013, 0x006d }, + { 0x0013, 0x006e }, + { 0x0013, 0x006f }, + { 0x0013, 0x0070 }, + { 0x0013, 0x0071 }, + { 0x0013, 0x0072 }, + { 0x0013, 0x0073 }, + { 0x0013, 0x0074 }, + { 0x0013, 0x0075 }, + { 0x0013, 0x0076 }, + { 0x0013, 0x0077 }, + { 0x0013, 0x0078 }, + { 0x0013, 0x0079 }, + { 0x0013, 0x007a }, + { 0x0013, 0x007b }, + { 0x0013, 0x007c }, + { 0x0013, 0x007d }, + { 0x0013, 0x007e }, + { 0x0013, 0x007f }, + { 0x0013, 0x0080 }, + { 0x0013, 0x0081 }, + { 0x0013, 0x0082 }, + { 0x0013, 0x0083 }, + { 0x0013, 0x0084 }, + { 0x0013, 0x0085 }, + { 0x0013, 0x0086 }, + { 0x0013, 0x0087 }, + { 0x0013, 0x0088 }, + { 0x0013, 0x0089 }, + { 0x0013, 0x008a }, + { 0x0013, 0x008b }, + { 0x0013, 0x008c }, + { 0x0013, 0x008d }, + { 0x0013, 0x008e }, + { 0x0013, 0x008f }, + { 0x0013, 0x0090 }, + { 0x0013, 0x0091 }, + { 0x0013, 0x0092 }, + { 0x0013, 0x0093 }, + { 0x0013, 0x0094 }, + { 0x0013, 0x0095 }, + { 0x0013, 0x0096 }, + { 0x0013, 0x0097 }, + { 0x0013, 0x0098 }, + { 0x0013, 0x0099 }, + { 0x0013, 0x009a }, + { 0x0013, 0x009b }, + { 0x0013, 0x009c }, + { 0x0013, 0x009d }, + { 0x0013, 0x009e }, + { 0x0013, 0x009f }, + { 0x0013, 0x00a0 }, + { 0x0013, 0x00a1 }, + { 0x0013, 0x00a2 }, + { 0x0013, 0x00a3 }, + { 0x0013, 0x00a4 }, + { 0x0013, 0x00a5 }, + { 0x0013, 0x00a6 }, + { 0x0013, 0x00a7 }, + { 0x0013, 0x00a8 }, + { 0x0013, 0x00a9 }, + { 0x0013, 0x00aa }, + { 0x0013, 0x00ab }, + { 0x0013, 0x00ac }, + { 0x0013, 0x00ad }, + { 0x0013, 0x00ae }, + { 0x0013, 0x00af }, + { 0x0013, 0x00b0 }, + { 0x0013, 0x00b1 }, + { 0x0013, 0x00b2 }, + { 0x0013, 0x00b3 }, + { 0x0013, 0x00b4 }, + { 0x0013, 0x00b5 }, + { 0x0013, 0x00b6 }, + { 0x0013, 0x00b7 }, + { 0x0013, 0x00b8 }, + { 0x0013, 0x00b9 }, + { 0x0013, 0x00ba }, + { 0x0013, 0x00bb }, + { 0x0013, 0x00bc }, + { 0x0013, 0x00bd }, + { 0x0013, 0x00be }, + { 0x0013, 0x00bf }, + { 0x0013, 0x00c0 }, + { 0x0013, 0x00c1 }, + { 0x0013, 0x00c2 }, + { 0x0013, 0x00c3 }, + { 0x0013, 0x00c4 }, + { 0x0013, 0x00c5 }, + { 0x0013, 0x00c6 }, + { 0x0013, 0x00c7 }, + { 0x0013, 0x00c8 }, + { 0x0013, 0x00c9 }, + { 0x0013, 0x00ca }, + { 0x0013, 0x00cb }, + { 0x0013, 0x00cc }, + { 0x0013, 0x00cd }, + { 0x0013, 0x00ce }, + { 0x0013, 0x00cf }, + { 0x0013, 0x00d0 }, + { 0x0013, 0x00d1 }, + { 0x0013, 0x00d2 }, + { 0x0013, 0x00d3 }, + { 0x0013, 0x00d4 }, + { 0x0013, 0x00d5 }, + { 0x0013, 0x00d6 }, + { 0x0013, 0x00d7 }, + { 0x0013, 0x00d8 }, + { 0x0013, 0x00d9 }, + { 0x0013, 0x00da }, + { 0x0013, 0x00db }, + { 0x0013, 0x00dc }, + { 0x0013, 0x00dd }, + { 0x0013, 0x00de }, + { 0x0013, 0x00df }, + { 0x0013, 0x00e0 }, + { 0x0013, 0x00e1 }, + { 0x0013, 0x00e2 }, + { 0x0013, 0x00e3 }, + { 0x0013, 0x00e4 }, + { 0x0013, 0x00e5 }, + { 0x0013, 0x00e6 }, + { 0x0013, 0x00e7 }, + { 0x0013, 0x00e8 }, + { 0x0013, 0x00e9 }, + { 0x0013, 0x00ea }, + { 0x0013, 0x00eb }, + { 0x0013, 0x00ec }, + { 0x0013, 0x00ed }, + { 0x0013, 0x00ee }, + { 0x0013, 0x00ef }, + { 0x0013, 0x00f0 }, + { 0x0013, 0x00f1 }, + { 0x0013, 0x00f2 }, + { 0x0013, 0x00f3 }, + { 0x0013, 0x00f4 }, + { 0x0013, 0x00f5 }, + { 0x0013, 0x00f6 }, + { 0x0013, 0x00f7 }, + { 0x0013, 0x00f8 }, + { 0x0013, 0x00f9 }, + { 0x0013, 0x00fa }, + { 0x0013, 0x00fb }, + { 0x0013, 0x00fc }, + { 0x0013, 0x00fd }, + { 0x0013, 0x00fe }, + { 0x0013, 0x00ff }, + { 0x0013, 0x0100 }, + { 0x0013, 0x0101 }, + { 0x0013, 0x0102 }, + { 0x0013, 0x0103 }, + { 0x0013, 0x0104 }, + { 0x0013, 0x0105 }, + { 0x0013, 0x0106 }, + { 0x0013, 0x0107 }, + { 0x0013, 0x0108 }, + { 0x0013, 0x0109 }, + { 0x0013, 0x010a }, + { 0x0013, 0x010b }, + { 0x0013, 0x010c }, + { 0x0013, 0x010d }, + { 0x0013, 0x010e }, + { 0x0013, 0x010f }, + { 0x0013, 0x0110 }, + { 0x0013, 0x0111 }, + { 0x0013, 0x0112 }, + { 0x0013, 0x0113 }, + { 0x0013, 0x0114 }, + { 0x0013, 0x0115 }, + { 0x0013, 0x0116 }, + { 0x0013, 0x0117 }, + { 0x0013, 0x0118 }, + { 0x0013, 0x0119 }, + { 0x0013, 0x011a }, + { 0x0013, 0x011b }, + { 0x0013, 0x011c }, + { 0x0013, 0x011d }, + { 0x0013, 0x011e }, + { 0x0013, 0x011f }, + { 0x0013, 0x0120 }, + { 0x0013, 0x0121 }, + { 0x0013, 0x0122 }, + { 0x0013, 0x0123 }, + { 0x0013, 0x0124 }, + { 0x0013, 0x0125 }, + { 0x0013, 0x0126 }, + { 0x0013, 0x0127 }, + { 0x0013, 0x0128 }, + { 0x0013, 0x0129 }, + { 0x0013, 0x012a }, + { 0x0013, 0x012b }, + { 0x0013, 0x012c }, + { 0x0013, 0x012d }, + { 0x0013, 0x012e }, + { 0x0013, 0x012f }, + { 0x0013, 0x0130 }, + { 0x0013, 0x0131 }, + { 0x0013, 0x0132 }, + { 0x0013, 0x0133 }, + { 0x0013, 0x0134 }, + { 0x0013, 0x0135 }, + { 0x0013, 0x0136 }, + { 0x0013, 0x0137 }, + { 0x0013, 0x0138 }, + { 0x0013, 0x0139 }, + { 0x0013, 0x013a }, + { 0x0013, 0x013b }, + { 0x0013, 0x013c }, + { 0x0013, 0x013d }, + { 0x0013, 0x013e }, + { 0x0013, 0x013f }, + { 0x0013, 0x0140 }, + { 0x0013, 0x0141 }, + { 0x0013, 0x0142 }, + { 0x0013, 0x0143 }, + { 0x0013, 0x0144 }, + { 0x0013, 0x0145 }, + { 0x0013, 0x0146 }, + { 0x0013, 0x0147 }, + { 0x0013, 0x0148 }, + { 0x0013, 0x0149 }, + { 0x0013, 0x014a }, + { 0x0013, 0x014b }, + { 0x0012, 0x00ab }, + { 0x0012, 0x00ac }, + { 0x0012, 0x00ad }, + }; + +const uint16_t c_aauiLCLDHuffEnc47[576][2] = + { + { 0x0002, 0x0003 }, + { 0x0003, 0x0003 }, + { 0x0005, 0x0005 }, + { 0x0006, 0x0004 }, + { 0x0008, 0x0006 }, + { 0x000a, 0x0007 }, + { 0x000c, 0x000b }, + { 0x000d, 0x000d }, + { 0x0010, 0x0041 }, + { 0x0013, 0x0000 }, + { 0x0013, 0x0001 }, + { 0x0013, 0x0002 }, + { 0x0013, 0x0003 }, + { 0x0013, 0x0004 }, + { 0x0013, 0x0005 }, + { 0x0013, 0x0006 }, + { 0x0013, 0x0007 }, + { 0x0013, 0x0008 }, + { 0x0013, 0x0009 }, + { 0x0013, 0x000a }, + { 0x0013, 0x000b }, + { 0x0013, 0x000c }, + { 0x0013, 0x000d }, + { 0x0013, 0x000e }, + { 0x0003, 0x0004 }, + { 0x0003, 0x0005 }, + { 0x0004, 0x0004 }, + { 0x0006, 0x0005 }, + { 0x0007, 0x0005 }, + { 0x0009, 0x0006 }, + { 0x000b, 0x0007 }, + { 0x000d, 0x000e }, + { 0x000f, 0x0025 }, + { 0x000f, 0x0026 }, + { 0x0012, 0x00f6 }, + { 0x0013, 0x000f }, + { 0x0013, 0x0010 }, + { 0x0013, 0x0011 }, + { 0x0013, 0x0012 }, + { 0x0013, 0x0013 }, + { 0x0013, 0x0014 }, + { 0x0013, 0x0015 }, + { 0x0013, 0x0016 }, + { 0x0013, 0x0017 }, + { 0x0013, 0x0018 }, + { 0x0013, 0x0019 }, + { 0x0013, 0x001a }, + { 0x0013, 0x001b }, + { 0x0005, 0x0006 }, + { 0x0004, 0x0005 }, + { 0x0005, 0x0007 }, + { 0x0006, 0x0006 }, + { 0x0008, 0x0007 }, + { 0x0009, 0x0007 }, + { 0x000b, 0x0008 }, + { 0x000d, 0x000f }, + { 0x000f, 0x0027 }, + { 0x0012, 0x00f7 }, + { 0x0013, 0x001c }, + { 0x0013, 0x001d }, + { 0x0013, 0x001e }, + { 0x0013, 0x001f }, + { 0x0013, 0x0020 }, + { 0x0013, 0x0021 }, + { 0x0013, 0x0022 }, + { 0x0013, 0x0023 }, + { 0x0013, 0x0024 }, + { 0x0013, 0x0025 }, + { 0x0013, 0x0026 }, + { 0x0013, 0x0027 }, + { 0x0013, 0x0028 }, + { 0x0013, 0x0029 }, + { 0x0006, 0x0007 }, + { 0x0006, 0x0008 }, + { 0x0006, 0x0009 }, + { 0x0007, 0x0006 }, + { 0x0009, 0x0008 }, + { 0x000a, 0x0008 }, + { 0x000c, 0x000c }, + { 0x000e, 0x0017 }, + { 0x0010, 0x0042 }, + { 0x0012, 0x00f8 }, + { 0x0013, 0x002a }, + { 0x0013, 0x002b }, + { 0x0013, 0x002c }, + { 0x0013, 0x002d }, + { 0x0013, 0x002e }, + { 0x0013, 0x002f }, + { 0x0013, 0x0030 }, + { 0x0013, 0x0031 }, + { 0x0013, 0x0032 }, + { 0x0013, 0x0033 }, + { 0x0013, 0x0034 }, + { 0x0013, 0x0035 }, + { 0x0013, 0x0036 }, + { 0x0013, 0x0037 }, + { 0x0008, 0x0008 }, + { 0x0007, 0x0007 }, + { 0x0008, 0x0009 }, + { 0x0009, 0x0009 }, + { 0x000a, 0x0009 }, + { 0x000b, 0x0009 }, + { 0x000d, 0x0010 }, + { 0x000f, 0x0028 }, + { 0x000f, 0x0029 }, + { 0x0011, 0x007f }, + { 0x0013, 0x0038 }, + { 0x0013, 0x0039 }, + { 0x0013, 0x003a }, + { 0x0013, 0x003b }, + { 0x0013, 0x003c }, + { 0x0013, 0x003d }, + { 0x0013, 0x003e }, + { 0x0013, 0x003f }, + { 0x0013, 0x0040 }, + { 0x0013, 0x0041 }, + { 0x0013, 0x0042 }, + { 0x0013, 0x0043 }, + { 0x0013, 0x0044 }, + { 0x0013, 0x0045 }, + { 0x000a, 0x000a }, + { 0x0009, 0x000a }, + { 0x0009, 0x000b }, + { 0x000a, 0x000b }, + { 0x000b, 0x000a }, + { 0x000d, 0x0011 }, + { 0x000f, 0x002a }, + { 0x0010, 0x0043 }, + { 0x0012, 0x00f9 }, + { 0x0013, 0x0046 }, + { 0x0013, 0x0047 }, + { 0x0013, 0x0048 }, + { 0x0013, 0x0049 }, + { 0x0013, 0x004a }, + { 0x0013, 0x004b }, + { 0x0013, 0x004c }, + { 0x0013, 0x004d }, + { 0x0013, 0x004e }, + { 0x0013, 0x004f }, + { 0x0013, 0x0050 }, + { 0x0013, 0x0051 }, + { 0x0013, 0x0052 }, + { 0x0013, 0x0053 }, + { 0x0013, 0x0054 }, + { 0x000b, 0x000b }, + { 0x000b, 0x000c }, + { 0x000b, 0x000d }, + { 0x000c, 0x000d }, + { 0x000d, 0x0012 }, + { 0x000e, 0x0018 }, + { 0x0010, 0x0044 }, + { 0x0013, 0x0055 }, + { 0x0013, 0x0056 }, + { 0x0013, 0x0057 }, + { 0x0013, 0x0058 }, + { 0x0013, 0x0059 }, + { 0x0013, 0x005a }, + { 0x0013, 0x005b }, + { 0x0013, 0x005c }, + { 0x0013, 0x005d }, + { 0x0013, 0x005e }, + { 0x0013, 0x005f }, + { 0x0013, 0x0060 }, + { 0x0013, 0x0061 }, + { 0x0013, 0x0062 }, + { 0x0013, 0x0063 }, + { 0x0013, 0x0064 }, + { 0x0013, 0x0065 }, + { 0x000e, 0x0019 }, + { 0x000d, 0x0013 }, + { 0x000d, 0x0014 }, + { 0x000d, 0x0015 }, + { 0x000f, 0x002b }, + { 0x0010, 0x0045 }, + { 0x0013, 0x0066 }, + { 0x0012, 0x00fa }, + { 0x0013, 0x0067 }, + { 0x0013, 0x0068 }, + { 0x0013, 0x0069 }, + { 0x0013, 0x006a }, + { 0x0013, 0x006b }, + { 0x0013, 0x006c }, + { 0x0013, 0x006d }, + { 0x0013, 0x006e }, + { 0x0013, 0x006f }, + { 0x0013, 0x0070 }, + { 0x0013, 0x0071 }, + { 0x0013, 0x0072 }, + { 0x0013, 0x0073 }, + { 0x0013, 0x0074 }, + { 0x0013, 0x0075 }, + { 0x0013, 0x0076 }, + { 0x0010, 0x0046 }, + { 0x000f, 0x002c }, + { 0x000f, 0x002d }, + { 0x0010, 0x0047 }, + { 0x0011, 0x0080 }, + { 0x0013, 0x0077 }, + { 0x0013, 0x0078 }, + { 0x0013, 0x0079 }, + { 0x0013, 0x007a }, + { 0x0013, 0x007b }, + { 0x0013, 0x007c }, + { 0x0013, 0x007d }, + { 0x0013, 0x007e }, + { 0x0013, 0x007f }, + { 0x0013, 0x0080 }, + { 0x0013, 0x0081 }, + { 0x0013, 0x0082 }, + { 0x0013, 0x0083 }, + { 0x0013, 0x0084 }, + { 0x0013, 0x0085 }, + { 0x0013, 0x0086 }, + { 0x0013, 0x0087 }, + { 0x0013, 0x0088 }, + { 0x0013, 0x0089 }, + { 0x0013, 0x008a }, + { 0x0010, 0x0048 }, + { 0x0010, 0x0049 }, + { 0x0011, 0x0081 }, + { 0x0013, 0x008b }, + { 0x0012, 0x00fb }, + { 0x0013, 0x008c }, + { 0x0013, 0x008d }, + { 0x0013, 0x008e }, + { 0x0013, 0x008f }, + { 0x0013, 0x0090 }, + { 0x0013, 0x0091 }, + { 0x0013, 0x0092 }, + { 0x0013, 0x0093 }, + { 0x0013, 0x0094 }, + { 0x0013, 0x0095 }, + { 0x0013, 0x0096 }, + { 0x0013, 0x0097 }, + { 0x0013, 0x0098 }, + { 0x0013, 0x0099 }, + { 0x0013, 0x009a }, + { 0x0013, 0x009b }, + { 0x0013, 0x009c }, + { 0x0013, 0x009d }, + { 0x0013, 0x009e }, + { 0x0013, 0x009f }, + { 0x0013, 0x00a0 }, + { 0x0012, 0x00fc }, + { 0x0013, 0x00a1 }, + { 0x0013, 0x00a2 }, + { 0x0013, 0x00a3 }, + { 0x0013, 0x00a4 }, + { 0x0013, 0x00a5 }, + { 0x0013, 0x00a6 }, + { 0x0013, 0x00a7 }, + { 0x0013, 0x00a8 }, + { 0x0013, 0x00a9 }, + { 0x0013, 0x00aa }, + { 0x0013, 0x00ab }, + { 0x0013, 0x00ac }, + { 0x0013, 0x00ad }, + { 0x0013, 0x00ae }, + { 0x0013, 0x00af }, + { 0x0013, 0x00b0 }, + { 0x0013, 0x00b1 }, + { 0x0013, 0x00b2 }, + { 0x0013, 0x00b3 }, + { 0x0013, 0x00b4 }, + { 0x0013, 0x00b5 }, + { 0x0013, 0x00b6 }, + { 0x0013, 0x00b7 }, + { 0x0013, 0x00b8 }, + { 0x0013, 0x00b9 }, + { 0x0013, 0x00ba }, + { 0x0013, 0x00bb }, + { 0x0013, 0x00bc }, + { 0x0013, 0x00bd }, + { 0x0013, 0x00be }, + { 0x0013, 0x00bf }, + { 0x0013, 0x00c0 }, + { 0x0013, 0x00c1 }, + { 0x0013, 0x00c2 }, + { 0x0013, 0x00c3 }, + { 0x0013, 0x00c4 }, + { 0x0013, 0x00c5 }, + { 0x0013, 0x00c6 }, + { 0x0013, 0x00c7 }, + { 0x0013, 0x00c8 }, + { 0x0013, 0x00c9 }, + { 0x0013, 0x00ca }, + { 0x0013, 0x00cb }, + { 0x0013, 0x00cc }, + { 0x0013, 0x00cd }, + { 0x0013, 0x00ce }, + { 0x0013, 0x00cf }, + { 0x0013, 0x00d0 }, + { 0x0013, 0x00d1 }, + { 0x0013, 0x00d2 }, + { 0x0013, 0x00d3 }, + { 0x0013, 0x00d4 }, + { 0x0013, 0x00d5 }, + { 0x0013, 0x00d6 }, + { 0x0013, 0x00d7 }, + { 0x0013, 0x00d8 }, + { 0x0013, 0x00d9 }, + { 0x0013, 0x00da }, + { 0x0013, 0x00db }, + { 0x0013, 0x00dc }, + { 0x0013, 0x00dd }, + { 0x0013, 0x00de }, + { 0x0013, 0x00df }, + { 0x0013, 0x00e0 }, + { 0x0013, 0x00e1 }, + { 0x0013, 0x00e2 }, + { 0x0013, 0x00e3 }, + { 0x0013, 0x00e4 }, + { 0x0013, 0x00e5 }, + { 0x0013, 0x00e6 }, + { 0x0013, 0x00e7 }, + { 0x0013, 0x00e8 }, + { 0x0013, 0x00e9 }, + { 0x0013, 0x00ea }, + { 0x0013, 0x00eb }, + { 0x0013, 0x00ec }, + { 0x0013, 0x00ed }, + { 0x0013, 0x00ee }, + { 0x0013, 0x00ef }, + { 0x0013, 0x00f0 }, + { 0x0013, 0x00f1 }, + { 0x0013, 0x00f2 }, + { 0x0013, 0x00f3 }, + { 0x0013, 0x00f4 }, + { 0x0013, 0x00f5 }, + { 0x0013, 0x00f6 }, + { 0x0013, 0x00f7 }, + { 0x0013, 0x00f8 }, + { 0x0013, 0x00f9 }, + { 0x0013, 0x00fa }, + { 0x0013, 0x00fb }, + { 0x0013, 0x00fc }, + { 0x0013, 0x00fd }, + { 0x0013, 0x00fe }, + { 0x0013, 0x00ff }, + { 0x0013, 0x0100 }, + { 0x0013, 0x0101 }, + { 0x0013, 0x0102 }, + { 0x0013, 0x0103 }, + { 0x0013, 0x0104 }, + { 0x0013, 0x0105 }, + { 0x0013, 0x0106 }, + { 0x0013, 0x0107 }, + { 0x0013, 0x0108 }, + { 0x0013, 0x0109 }, + { 0x0013, 0x010a }, + { 0x0013, 0x010b }, + { 0x0013, 0x010c }, + { 0x0013, 0x010d }, + { 0x0013, 0x010e }, + { 0x0013, 0x010f }, + { 0x0013, 0x0110 }, + { 0x0013, 0x0111 }, + { 0x0013, 0x0112 }, + { 0x0013, 0x0113 }, + { 0x0013, 0x0114 }, + { 0x0013, 0x0115 }, + { 0x0013, 0x0116 }, + { 0x0013, 0x0117 }, + { 0x0013, 0x0118 }, + { 0x0013, 0x0119 }, + { 0x0013, 0x011a }, + { 0x0013, 0x011b }, + { 0x0013, 0x011c }, + { 0x0013, 0x011d }, + { 0x0013, 0x011e }, + { 0x0013, 0x011f }, + { 0x0013, 0x0120 }, + { 0x0013, 0x0121 }, + { 0x0013, 0x0122 }, + { 0x0013, 0x0123 }, + { 0x0013, 0x0124 }, + { 0x0013, 0x0125 }, + { 0x0013, 0x0126 }, + { 0x0013, 0x0127 }, + { 0x0013, 0x0128 }, + { 0x0013, 0x0129 }, + { 0x0013, 0x012a }, + { 0x0013, 0x012b }, + { 0x0013, 0x012c }, + { 0x0013, 0x012d }, + { 0x0013, 0x012e }, + { 0x0013, 0x012f }, + { 0x0013, 0x0130 }, + { 0x0013, 0x0131 }, + { 0x0013, 0x0132 }, + { 0x0013, 0x0133 }, + { 0x0013, 0x0134 }, + { 0x0013, 0x0135 }, + { 0x0013, 0x0136 }, + { 0x0013, 0x0137 }, + { 0x0013, 0x0138 }, + { 0x0013, 0x0139 }, + { 0x0013, 0x013a }, + { 0x0013, 0x013b }, + { 0x0013, 0x013c }, + { 0x0013, 0x013d }, + { 0x0013, 0x013e }, + { 0x0013, 0x013f }, + { 0x0013, 0x0140 }, + { 0x0013, 0x0141 }, + { 0x0013, 0x0142 }, + { 0x0013, 0x0143 }, + { 0x0013, 0x0144 }, + { 0x0013, 0x0145 }, + { 0x0013, 0x0146 }, + { 0x0013, 0x0147 }, + { 0x0013, 0x0148 }, + { 0x0013, 0x0149 }, + { 0x0013, 0x014a }, + { 0x0013, 0x014b }, + { 0x0013, 0x014c }, + { 0x0013, 0x014d }, + { 0x0013, 0x014e }, + { 0x0013, 0x014f }, + { 0x0013, 0x0150 }, + { 0x0013, 0x0151 }, + { 0x0013, 0x0152 }, + { 0x0013, 0x0153 }, + { 0x0013, 0x0154 }, + { 0x0013, 0x0155 }, + { 0x0013, 0x0156 }, + { 0x0013, 0x0157 }, + { 0x0013, 0x0158 }, + { 0x0013, 0x0159 }, + { 0x0013, 0x015a }, + { 0x0013, 0x015b }, + { 0x0013, 0x015c }, + { 0x0013, 0x015d }, + { 0x0013, 0x015e }, + { 0x0013, 0x015f }, + { 0x0013, 0x0160 }, + { 0x0013, 0x0161 }, + { 0x0013, 0x0162 }, + { 0x0013, 0x0163 }, + { 0x0013, 0x0164 }, + { 0x0013, 0x0165 }, + { 0x0013, 0x0166 }, + { 0x0013, 0x0167 }, + { 0x0013, 0x0168 }, + { 0x0013, 0x0169 }, + { 0x0013, 0x016a }, + { 0x0013, 0x016b }, + { 0x0013, 0x016c }, + { 0x0013, 0x016d }, + { 0x0013, 0x016e }, + { 0x0013, 0x016f }, + { 0x0013, 0x0170 }, + { 0x0013, 0x0171 }, + { 0x0013, 0x0172 }, + { 0x0013, 0x0173 }, + { 0x0013, 0x0174 }, + { 0x0013, 0x0175 }, + { 0x0013, 0x0176 }, + { 0x0013, 0x0177 }, + { 0x0013, 0x0178 }, + { 0x0013, 0x0179 }, + { 0x0013, 0x017a }, + { 0x0013, 0x017b }, + { 0x0013, 0x017c }, + { 0x0013, 0x017d }, + { 0x0013, 0x017e }, + { 0x0013, 0x017f }, + { 0x0013, 0x0180 }, + { 0x0013, 0x0181 }, + { 0x0013, 0x0182 }, + { 0x0013, 0x0183 }, + { 0x0013, 0x0184 }, + { 0x0013, 0x0185 }, + { 0x0013, 0x0186 }, + { 0x0013, 0x0187 }, + { 0x0013, 0x0188 }, + { 0x0013, 0x0189 }, + { 0x0013, 0x018a }, + { 0x0013, 0x018b }, + { 0x0013, 0x018c }, + { 0x0013, 0x018d }, + { 0x0013, 0x018e }, + { 0x0013, 0x018f }, + { 0x0013, 0x0190 }, + { 0x0013, 0x0191 }, + { 0x0013, 0x0192 }, + { 0x0013, 0x0193 }, + { 0x0013, 0x0194 }, + { 0x0013, 0x0195 }, + { 0x0013, 0x0196 }, + { 0x0013, 0x0197 }, + { 0x0013, 0x0198 }, + { 0x0013, 0x0199 }, + { 0x0013, 0x019a }, + { 0x0013, 0x019b }, + { 0x0013, 0x019c }, + { 0x0013, 0x019d }, + { 0x0013, 0x019e }, + { 0x0013, 0x019f }, + { 0x0013, 0x01a0 }, + { 0x0013, 0x01a1 }, + { 0x0013, 0x01a2 }, + { 0x0013, 0x01a3 }, + { 0x0013, 0x01a4 }, + { 0x0013, 0x01a5 }, + { 0x0013, 0x01a6 }, + { 0x0013, 0x01a7 }, + { 0x0013, 0x01a8 }, + { 0x0013, 0x01a9 }, + { 0x0013, 0x01aa }, + { 0x0013, 0x01ab }, + { 0x0013, 0x01ac }, + { 0x0013, 0x01ad }, + { 0x0013, 0x01ae }, + { 0x0013, 0x01af }, + { 0x0013, 0x01b0 }, + { 0x0013, 0x01b1 }, + { 0x0013, 0x01b2 }, + { 0x0013, 0x01b3 }, + { 0x0013, 0x01b4 }, + { 0x0013, 0x01b5 }, + { 0x0013, 0x01b6 }, + { 0x0013, 0x01b7 }, + { 0x0013, 0x01b8 }, + { 0x0013, 0x01b9 }, + { 0x0013, 0x01ba }, + { 0x0013, 0x01bb }, + { 0x0013, 0x01bc }, + { 0x0013, 0x01bd }, + { 0x0013, 0x01be }, + { 0x0013, 0x01bf }, + { 0x0013, 0x01c0 }, + { 0x0013, 0x01c1 }, + { 0x0013, 0x01c2 }, + { 0x0013, 0x01c3 }, + { 0x0013, 0x01c4 }, + { 0x0013, 0x01c5 }, + { 0x0013, 0x01c6 }, + { 0x0013, 0x01c7 }, + { 0x0013, 0x01c8 }, + { 0x0013, 0x01c9 }, + { 0x0013, 0x01ca }, + { 0x0013, 0x01cb }, + { 0x0013, 0x01cc }, + { 0x0013, 0x01cd }, + { 0x0013, 0x01ce }, + { 0x0013, 0x01cf }, + { 0x0013, 0x01d0 }, + { 0x0013, 0x01d1 }, + { 0x0013, 0x01d2 }, + { 0x0013, 0x01d3 }, + { 0x0013, 0x01d4 }, + { 0x0013, 0x01d5 }, + { 0x0013, 0x01d6 }, + { 0x0013, 0x01d7 }, + { 0x0013, 0x01d8 }, + { 0x0013, 0x01d9 }, + { 0x0013, 0x01da }, + { 0x0013, 0x01db }, + { 0x0013, 0x01dc }, + { 0x0013, 0x01dd }, + { 0x0013, 0x01de }, + { 0x0013, 0x01df }, + { 0x0013, 0x01e0 }, + { 0x0013, 0x01e1 }, + { 0x0013, 0x01e2 }, + { 0x0013, 0x01e3 }, + { 0x0013, 0x01e4 }, + { 0x0013, 0x01e5 }, + { 0x0013, 0x01e6 }, + { 0x0013, 0x01e7 }, + { 0x0013, 0x01e8 }, + { 0x0013, 0x01e9 }, + { 0x0013, 0x01ea }, + { 0x0013, 0x01eb }, + { 0x0012, 0x00fd }, + }; + +const uint16_t c_aauiLCLDHuffEnc48[729][2] = + { + { 0x0002, 0x0003 }, + { 0x0003, 0x0003 }, + { 0x0005, 0x0006 }, + { 0x0006, 0x0006 }, + { 0x0008, 0x0006 }, + { 0x0009, 0x0007 }, + { 0x000b, 0x000b }, + { 0x000c, 0x000d }, + { 0x000f, 0x0030 }, + { 0x0010, 0x0055 }, + { 0x0012, 0x0136 }, + { 0x0013, 0x0000 }, + { 0x0013, 0x0001 }, + { 0x0013, 0x0002 }, + { 0x0013, 0x0003 }, + { 0x0013, 0x0004 }, + { 0x0013, 0x0005 }, + { 0x0013, 0x0006 }, + { 0x0013, 0x0007 }, + { 0x0013, 0x0008 }, + { 0x0013, 0x0009 }, + { 0x0013, 0x000a }, + { 0x0013, 0x000b }, + { 0x0013, 0x000c }, + { 0x0013, 0x000d }, + { 0x0013, 0x000e }, + { 0x0013, 0x000f }, + { 0x0003, 0x0004 }, + { 0x0003, 0x0005 }, + { 0x0005, 0x0007 }, + { 0x0006, 0x0007 }, + { 0x0007, 0x0007 }, + { 0x0008, 0x0007 }, + { 0x000a, 0x0008 }, + { 0x000c, 0x000e }, + { 0x000d, 0x0012 }, + { 0x000f, 0x0031 }, + { 0x0011, 0x00a0 }, + { 0x0013, 0x0010 }, + { 0x0013, 0x0011 }, + { 0x0013, 0x0012 }, + { 0x0013, 0x0013 }, + { 0x0013, 0x0014 }, + { 0x0013, 0x0015 }, + { 0x0013, 0x0016 }, + { 0x0013, 0x0017 }, + { 0x0013, 0x0018 }, + { 0x0013, 0x0019 }, + { 0x0013, 0x001a }, + { 0x0013, 0x001b }, + { 0x0013, 0x001c }, + { 0x0013, 0x001d }, + { 0x0013, 0x001e }, + { 0x0013, 0x001f }, + { 0x0005, 0x0008 }, + { 0x0004, 0x0005 }, + { 0x0005, 0x0009 }, + { 0x0006, 0x0008 }, + { 0x0007, 0x0008 }, + { 0x0008, 0x0008 }, + { 0x000a, 0x0009 }, + { 0x000c, 0x000f }, + { 0x000d, 0x0013 }, + { 0x000f, 0x0032 }, + { 0x0011, 0x00a1 }, + { 0x0013, 0x0020 }, + { 0x0013, 0x0021 }, + { 0x0013, 0x0022 }, + { 0x0013, 0x0023 }, + { 0x0013, 0x0024 }, + { 0x0013, 0x0025 }, + { 0x0013, 0x0026 }, + { 0x0013, 0x0027 }, + { 0x0013, 0x0028 }, + { 0x0013, 0x0029 }, + { 0x0013, 0x002a }, + { 0x0013, 0x002b }, + { 0x0013, 0x002c }, + { 0x0013, 0x002d }, + { 0x0013, 0x002e }, + { 0x0013, 0x002f }, + { 0x0006, 0x0009 }, + { 0x0006, 0x000a }, + { 0x0006, 0x000b }, + { 0x0007, 0x0009 }, + { 0x0008, 0x0009 }, + { 0x0009, 0x0008 }, + { 0x000b, 0x000c }, + { 0x000d, 0x0014 }, + { 0x000e, 0x001d }, + { 0x000f, 0x0033 }, + { 0x0012, 0x0137 }, + { 0x0013, 0x0030 }, + { 0x0013, 0x0031 }, + { 0x0013, 0x0032 }, + { 0x0013, 0x0033 }, + { 0x0013, 0x0034 }, + { 0x0013, 0x0035 }, + { 0x0013, 0x0036 }, + { 0x0013, 0x0037 }, + { 0x0013, 0x0038 }, + { 0x0013, 0x0039 }, + { 0x0013, 0x003a }, + { 0x0013, 0x003b }, + { 0x0013, 0x003c }, + { 0x0013, 0x003d }, + { 0x0013, 0x003e }, + { 0x0013, 0x003f }, + { 0x0008, 0x000a }, + { 0x0007, 0x000a }, + { 0x0007, 0x000b }, + { 0x0008, 0x000b }, + { 0x0009, 0x0009 }, + { 0x000a, 0x000a }, + { 0x000c, 0x0010 }, + { 0x000d, 0x0015 }, + { 0x000f, 0x0034 }, + { 0x0010, 0x0056 }, + { 0x0012, 0x0138 }, + { 0x0013, 0x0040 }, + { 0x0013, 0x0041 }, + { 0x0013, 0x0042 }, + { 0x0013, 0x0043 }, + { 0x0013, 0x0044 }, + { 0x0013, 0x0045 }, + { 0x0013, 0x0046 }, + { 0x0013, 0x0047 }, + { 0x0013, 0x0048 }, + { 0x0013, 0x0049 }, + { 0x0013, 0x004a }, + { 0x0013, 0x004b }, + { 0x0013, 0x004c }, + { 0x0013, 0x004d }, + { 0x0013, 0x004e }, + { 0x0013, 0x004f }, + { 0x0009, 0x000a }, + { 0x0008, 0x000c }, + { 0x0008, 0x000d }, + { 0x0009, 0x000b }, + { 0x000a, 0x000b }, + { 0x000c, 0x0011 }, + { 0x000d, 0x0016 }, + { 0x000e, 0x001e }, + { 0x0010, 0x0057 }, + { 0x0011, 0x00a2 }, + { 0x0011, 0x00a3 }, + { 0x0013, 0x0050 }, + { 0x0013, 0x0051 }, + { 0x0013, 0x0052 }, + { 0x0013, 0x0053 }, + { 0x0013, 0x0054 }, + { 0x0013, 0x0055 }, + { 0x0013, 0x0056 }, + { 0x0013, 0x0057 }, + { 0x0013, 0x0058 }, + { 0x0013, 0x0059 }, + { 0x0013, 0x005a }, + { 0x0013, 0x005b }, + { 0x0013, 0x005c }, + { 0x0013, 0x005d }, + { 0x0013, 0x005e }, + { 0x0013, 0x005f }, + { 0x000b, 0x000d }, + { 0x000a, 0x000c }, + { 0x000a, 0x000d }, + { 0x000b, 0x000e }, + { 0x000c, 0x0012 }, + { 0x000d, 0x0017 }, + { 0x000e, 0x001f }, + { 0x0010, 0x0058 }, + { 0x0012, 0x0139 }, + { 0x0011, 0x00a4 }, + { 0x0012, 0x013a }, + { 0x0013, 0x0060 }, + { 0x0013, 0x0061 }, + { 0x0013, 0x0062 }, + { 0x0013, 0x0063 }, + { 0x0013, 0x0064 }, + { 0x0013, 0x0065 }, + { 0x0013, 0x0066 }, + { 0x0013, 0x0067 }, + { 0x0013, 0x0068 }, + { 0x0013, 0x0069 }, + { 0x0013, 0x006a }, + { 0x0013, 0x006b }, + { 0x0013, 0x006c }, + { 0x0013, 0x006d }, + { 0x0013, 0x006e }, + { 0x0013, 0x006f }, + { 0x000c, 0x0013 }, + { 0x000b, 0x000f }, + { 0x000c, 0x0014 }, + { 0x000c, 0x0015 }, + { 0x000d, 0x0018 }, + { 0x000e, 0x0020 }, + { 0x000f, 0x0035 }, + { 0x0012, 0x013b }, + { 0x0013, 0x0070 }, + { 0x0013, 0x0071 }, + { 0x0013, 0x0072 }, + { 0x0013, 0x0073 }, + { 0x0013, 0x0074 }, + { 0x0013, 0x0075 }, + { 0x0013, 0x0076 }, + { 0x0013, 0x0077 }, + { 0x0013, 0x0078 }, + { 0x0013, 0x0079 }, + { 0x0013, 0x007a }, + { 0x0013, 0x007b }, + { 0x0013, 0x007c }, + { 0x0013, 0x007d }, + { 0x0013, 0x007e }, + { 0x0013, 0x007f }, + { 0x0013, 0x0080 }, + { 0x0013, 0x0081 }, + { 0x0013, 0x0082 }, + { 0x000e, 0x0021 }, + { 0x000d, 0x0019 }, + { 0x000e, 0x0022 }, + { 0x000e, 0x0023 }, + { 0x000f, 0x0036 }, + { 0x0010, 0x0059 }, + { 0x0011, 0x00a5 }, + { 0x0013, 0x0083 }, + { 0x0011, 0x00a6 }, + { 0x0012, 0x013c }, + { 0x0013, 0x0084 }, + { 0x0013, 0x0085 }, + { 0x0013, 0x0086 }, + { 0x0013, 0x0087 }, + { 0x0013, 0x0088 }, + { 0x0013, 0x0089 }, + { 0x0013, 0x008a }, + { 0x0013, 0x008b }, + { 0x0013, 0x008c }, + { 0x0013, 0x008d }, + { 0x0013, 0x008e }, + { 0x0013, 0x008f }, + { 0x0013, 0x0090 }, + { 0x0013, 0x0091 }, + { 0x0013, 0x0092 }, + { 0x0013, 0x0093 }, + { 0x0013, 0x0094 }, + { 0x0010, 0x005a }, + { 0x000f, 0x0037 }, + { 0x000f, 0x0038 }, + { 0x000f, 0x0039 }, + { 0x0010, 0x005b }, + { 0x0010, 0x005c }, + { 0x0013, 0x0095 }, + { 0x0011, 0x00a7 }, + { 0x0013, 0x0096 }, + { 0x0013, 0x0097 }, + { 0x0013, 0x0098 }, + { 0x0013, 0x0099 }, + { 0x0013, 0x009a }, + { 0x0013, 0x009b }, + { 0x0013, 0x009c }, + { 0x0013, 0x009d }, + { 0x0013, 0x009e }, + { 0x0013, 0x009f }, + { 0x0013, 0x00a0 }, + { 0x0013, 0x00a1 }, + { 0x0013, 0x00a2 }, + { 0x0013, 0x00a3 }, + { 0x0013, 0x00a4 }, + { 0x0013, 0x00a5 }, + { 0x0013, 0x00a6 }, + { 0x0013, 0x00a7 }, + { 0x0013, 0x00a8 }, + { 0x0010, 0x005d }, + { 0x0010, 0x005e }, + { 0x0013, 0x00a9 }, + { 0x0010, 0x005f }, + { 0x0013, 0x00aa }, + { 0x0012, 0x013d }, + { 0x0013, 0x00ab }, + { 0x0013, 0x00ac }, + { 0x0013, 0x00ad }, + { 0x0013, 0x00ae }, + { 0x0013, 0x00af }, + { 0x0013, 0x00b0 }, + { 0x0013, 0x00b1 }, + { 0x0013, 0x00b2 }, + { 0x0013, 0x00b3 }, + { 0x0013, 0x00b4 }, + { 0x0013, 0x00b5 }, + { 0x0013, 0x00b6 }, + { 0x0013, 0x00b7 }, + { 0x0013, 0x00b8 }, + { 0x0013, 0x00b9 }, + { 0x0013, 0x00ba }, + { 0x0013, 0x00bb }, + { 0x0013, 0x00bc }, + { 0x0013, 0x00bd }, + { 0x0013, 0x00be }, + { 0x0013, 0x00bf }, + { 0x0013, 0x00c0 }, + { 0x0011, 0x00a8 }, + { 0x0013, 0x00c1 }, + { 0x0011, 0x00a9 }, + { 0x0013, 0x00c2 }, + { 0x0013, 0x00c3 }, + { 0x0013, 0x00c4 }, + { 0x0013, 0x00c5 }, + { 0x0013, 0x00c6 }, + { 0x0013, 0x00c7 }, + { 0x0013, 0x00c8 }, + { 0x0013, 0x00c9 }, + { 0x0013, 0x00ca }, + { 0x0013, 0x00cb }, + { 0x0013, 0x00cc }, + { 0x0013, 0x00cd }, + { 0x0013, 0x00ce }, + { 0x0013, 0x00cf }, + { 0x0013, 0x00d0 }, + { 0x0013, 0x00d1 }, + { 0x0013, 0x00d2 }, + { 0x0013, 0x00d3 }, + { 0x0013, 0x00d4 }, + { 0x0013, 0x00d5 }, + { 0x0013, 0x00d6 }, + { 0x0013, 0x00d7 }, + { 0x0013, 0x00d8 }, + { 0x0013, 0x00d9 }, + { 0x0013, 0x00da }, + { 0x0012, 0x013e }, + { 0x0013, 0x00db }, + { 0x0013, 0x00dc }, + { 0x0013, 0x00dd }, + { 0x0013, 0x00de }, + { 0x0013, 0x00df }, + { 0x0013, 0x00e0 }, + { 0x0013, 0x00e1 }, + { 0x0013, 0x00e2 }, + { 0x0013, 0x00e3 }, + { 0x0013, 0x00e4 }, + { 0x0013, 0x00e5 }, + { 0x0013, 0x00e6 }, + { 0x0013, 0x00e7 }, + { 0x0013, 0x00e8 }, + { 0x0013, 0x00e9 }, + { 0x0013, 0x00ea }, + { 0x0013, 0x00eb }, + { 0x0013, 0x00ec }, + { 0x0013, 0x00ed }, + { 0x0013, 0x00ee }, + { 0x0013, 0x00ef }, + { 0x0013, 0x00f0 }, + { 0x0013, 0x00f1 }, + { 0x0013, 0x00f2 }, + { 0x0013, 0x00f3 }, + { 0x0013, 0x00f4 }, + { 0x0013, 0x00f5 }, + { 0x0013, 0x00f6 }, + { 0x0013, 0x00f7 }, + { 0x0013, 0x00f8 }, + { 0x0013, 0x00f9 }, + { 0x0013, 0x00fa }, + { 0x0013, 0x00fb }, + { 0x0013, 0x00fc }, + { 0x0013, 0x00fd }, + { 0x0013, 0x00fe }, + { 0x0013, 0x00ff }, + { 0x0013, 0x0100 }, + { 0x0013, 0x0101 }, + { 0x0013, 0x0102 }, + { 0x0013, 0x0103 }, + { 0x0013, 0x0104 }, + { 0x0013, 0x0105 }, + { 0x0013, 0x0106 }, + { 0x0013, 0x0107 }, + { 0x0013, 0x0108 }, + { 0x0013, 0x0109 }, + { 0x0013, 0x010a }, + { 0x0013, 0x010b }, + { 0x0013, 0x010c }, + { 0x0013, 0x010d }, + { 0x0013, 0x010e }, + { 0x0013, 0x010f }, + { 0x0013, 0x0110 }, + { 0x0013, 0x0111 }, + { 0x0013, 0x0112 }, + { 0x0013, 0x0113 }, + { 0x0013, 0x0114 }, + { 0x0013, 0x0115 }, + { 0x0013, 0x0116 }, + { 0x0013, 0x0117 }, + { 0x0013, 0x0118 }, + { 0x0013, 0x0119 }, + { 0x0013, 0x011a }, + { 0x0013, 0x011b }, + { 0x0013, 0x011c }, + { 0x0013, 0x011d }, + { 0x0013, 0x011e }, + { 0x0013, 0x011f }, + { 0x0013, 0x0120 }, + { 0x0013, 0x0121 }, + { 0x0013, 0x0122 }, + { 0x0013, 0x0123 }, + { 0x0013, 0x0124 }, + { 0x0013, 0x0125 }, + { 0x0013, 0x0126 }, + { 0x0013, 0x0127 }, + { 0x0013, 0x0128 }, + { 0x0013, 0x0129 }, + { 0x0013, 0x012a }, + { 0x0013, 0x012b }, + { 0x0013, 0x012c }, + { 0x0013, 0x012d }, + { 0x0013, 0x012e }, + { 0x0013, 0x012f }, + { 0x0013, 0x0130 }, + { 0x0013, 0x0131 }, + { 0x0013, 0x0132 }, + { 0x0013, 0x0133 }, + { 0x0013, 0x0134 }, + { 0x0013, 0x0135 }, + { 0x0013, 0x0136 }, + { 0x0013, 0x0137 }, + { 0x0013, 0x0138 }, + { 0x0013, 0x0139 }, + { 0x0013, 0x013a }, + { 0x0013, 0x013b }, + { 0x0013, 0x013c }, + { 0x0013, 0x013d }, + { 0x0013, 0x013e }, + { 0x0013, 0x013f }, + { 0x0013, 0x0140 }, + { 0x0013, 0x0141 }, + { 0x0013, 0x0142 }, + { 0x0013, 0x0143 }, + { 0x0013, 0x0144 }, + { 0x0013, 0x0145 }, + { 0x0013, 0x0146 }, + { 0x0013, 0x0147 }, + { 0x0013, 0x0148 }, + { 0x0013, 0x0149 }, + { 0x0013, 0x014a }, + { 0x0013, 0x014b }, + { 0x0013, 0x014c }, + { 0x0013, 0x014d }, + { 0x0013, 0x014e }, + { 0x0013, 0x014f }, + { 0x0013, 0x0150 }, + { 0x0013, 0x0151 }, + { 0x0013, 0x0152 }, + { 0x0013, 0x0153 }, + { 0x0013, 0x0154 }, + { 0x0013, 0x0155 }, + { 0x0013, 0x0156 }, + { 0x0013, 0x0157 }, + { 0x0013, 0x0158 }, + { 0x0013, 0x0159 }, + { 0x0013, 0x015a }, + { 0x0013, 0x015b }, + { 0x0013, 0x015c }, + { 0x0013, 0x015d }, + { 0x0013, 0x015e }, + { 0x0013, 0x015f }, + { 0x0013, 0x0160 }, + { 0x0013, 0x0161 }, + { 0x0013, 0x0162 }, + { 0x0013, 0x0163 }, + { 0x0013, 0x0164 }, + { 0x0013, 0x0165 }, + { 0x0013, 0x0166 }, + { 0x0013, 0x0167 }, + { 0x0013, 0x0168 }, + { 0x0013, 0x0169 }, + { 0x0013, 0x016a }, + { 0x0013, 0x016b }, + { 0x0013, 0x016c }, + { 0x0013, 0x016d }, + { 0x0013, 0x016e }, + { 0x0013, 0x016f }, + { 0x0013, 0x0170 }, + { 0x0013, 0x0171 }, + { 0x0013, 0x0172 }, + { 0x0013, 0x0173 }, + { 0x0013, 0x0174 }, + { 0x0013, 0x0175 }, + { 0x0013, 0x0176 }, + { 0x0013, 0x0177 }, + { 0x0013, 0x0178 }, + { 0x0013, 0x0179 }, + { 0x0013, 0x017a }, + { 0x0013, 0x017b }, + { 0x0013, 0x017c }, + { 0x0013, 0x017d }, + { 0x0013, 0x017e }, + { 0x0013, 0x017f }, + { 0x0013, 0x0180 }, + { 0x0013, 0x0181 }, + { 0x0013, 0x0182 }, + { 0x0013, 0x0183 }, + { 0x0013, 0x0184 }, + { 0x0013, 0x0185 }, + { 0x0013, 0x0186 }, + { 0x0013, 0x0187 }, + { 0x0013, 0x0188 }, + { 0x0013, 0x0189 }, + { 0x0013, 0x018a }, + { 0x0013, 0x018b }, + { 0x0013, 0x018c }, + { 0x0013, 0x018d }, + { 0x0013, 0x018e }, + { 0x0013, 0x018f }, + { 0x0013, 0x0190 }, + { 0x0013, 0x0191 }, + { 0x0013, 0x0192 }, + { 0x0013, 0x0193 }, + { 0x0013, 0x0194 }, + { 0x0013, 0x0195 }, + { 0x0013, 0x0196 }, + { 0x0013, 0x0197 }, + { 0x0013, 0x0198 }, + { 0x0013, 0x0199 }, + { 0x0013, 0x019a }, + { 0x0013, 0x019b }, + { 0x0013, 0x019c }, + { 0x0013, 0x019d }, + { 0x0013, 0x019e }, + { 0x0013, 0x019f }, + { 0x0013, 0x01a0 }, + { 0x0013, 0x01a1 }, + { 0x0013, 0x01a2 }, + { 0x0013, 0x01a3 }, + { 0x0013, 0x01a4 }, + { 0x0013, 0x01a5 }, + { 0x0013, 0x01a6 }, + { 0x0013, 0x01a7 }, + { 0x0013, 0x01a8 }, + { 0x0013, 0x01a9 }, + { 0x0013, 0x01aa }, + { 0x0013, 0x01ab }, + { 0x0013, 0x01ac }, + { 0x0013, 0x01ad }, + { 0x0013, 0x01ae }, + { 0x0013, 0x01af }, + { 0x0013, 0x01b0 }, + { 0x0013, 0x01b1 }, + { 0x0013, 0x01b2 }, + { 0x0013, 0x01b3 }, + { 0x0013, 0x01b4 }, + { 0x0013, 0x01b5 }, + { 0x0013, 0x01b6 }, + { 0x0013, 0x01b7 }, + { 0x0013, 0x01b8 }, + { 0x0013, 0x01b9 }, + { 0x0013, 0x01ba }, + { 0x0013, 0x01bb }, + { 0x0013, 0x01bc }, + { 0x0013, 0x01bd }, + { 0x0013, 0x01be }, + { 0x0013, 0x01bf }, + { 0x0013, 0x01c0 }, + { 0x0013, 0x01c1 }, + { 0x0013, 0x01c2 }, + { 0x0013, 0x01c3 }, + { 0x0013, 0x01c4 }, + { 0x0013, 0x01c5 }, + { 0x0013, 0x01c6 }, + { 0x0013, 0x01c7 }, + { 0x0013, 0x01c8 }, + { 0x0013, 0x01c9 }, + { 0x0013, 0x01ca }, + { 0x0013, 0x01cb }, + { 0x0013, 0x01cc }, + { 0x0013, 0x01cd }, + { 0x0013, 0x01ce }, + { 0x0013, 0x01cf }, + { 0x0013, 0x01d0 }, + { 0x0013, 0x01d1 }, + { 0x0013, 0x01d2 }, + { 0x0013, 0x01d3 }, + { 0x0013, 0x01d4 }, + { 0x0013, 0x01d5 }, + { 0x0013, 0x01d6 }, + { 0x0013, 0x01d7 }, + { 0x0013, 0x01d8 }, + { 0x0013, 0x01d9 }, + { 0x0013, 0x01da }, + { 0x0013, 0x01db }, + { 0x0013, 0x01dc }, + { 0x0013, 0x01dd }, + { 0x0013, 0x01de }, + { 0x0013, 0x01df }, + { 0x0013, 0x01e0 }, + { 0x0013, 0x01e1 }, + { 0x0013, 0x01e2 }, + { 0x0013, 0x01e3 }, + { 0x0013, 0x01e4 }, + { 0x0013, 0x01e5 }, + { 0x0013, 0x01e6 }, + { 0x0013, 0x01e7 }, + { 0x0013, 0x01e8 }, + { 0x0013, 0x01e9 }, + { 0x0013, 0x01ea }, + { 0x0013, 0x01eb }, + { 0x0013, 0x01ec }, + { 0x0013, 0x01ed }, + { 0x0013, 0x01ee }, + { 0x0013, 0x01ef }, + { 0x0013, 0x01f0 }, + { 0x0013, 0x01f1 }, + { 0x0013, 0x01f2 }, + { 0x0013, 0x01f3 }, + { 0x0013, 0x01f4 }, + { 0x0013, 0x01f5 }, + { 0x0013, 0x01f6 }, + { 0x0013, 0x01f7 }, + { 0x0013, 0x01f8 }, + { 0x0013, 0x01f9 }, + { 0x0013, 0x01fa }, + { 0x0013, 0x01fb }, + { 0x0013, 0x01fc }, + { 0x0013, 0x01fd }, + { 0x0013, 0x01fe }, + { 0x0013, 0x01ff }, + { 0x0013, 0x0200 }, + { 0x0013, 0x0201 }, + { 0x0013, 0x0202 }, + { 0x0013, 0x0203 }, + { 0x0013, 0x0204 }, + { 0x0013, 0x0205 }, + { 0x0013, 0x0206 }, + { 0x0013, 0x0207 }, + { 0x0013, 0x0208 }, + { 0x0013, 0x0209 }, + { 0x0013, 0x020a }, + { 0x0013, 0x020b }, + { 0x0013, 0x020c }, + { 0x0013, 0x020d }, + { 0x0013, 0x020e }, + { 0x0013, 0x020f }, + { 0x0013, 0x0210 }, + { 0x0013, 0x0211 }, + { 0x0013, 0x0212 }, + { 0x0013, 0x0213 }, + { 0x0013, 0x0214 }, + { 0x0013, 0x0215 }, + { 0x0013, 0x0216 }, + { 0x0013, 0x0217 }, + { 0x0013, 0x0218 }, + { 0x0013, 0x0219 }, + { 0x0013, 0x021a }, + { 0x0013, 0x021b }, + { 0x0013, 0x021c }, + { 0x0013, 0x021d }, + { 0x0013, 0x021e }, + { 0x0013, 0x021f }, + { 0x0013, 0x0220 }, + { 0x0013, 0x0221 }, + { 0x0013, 0x0222 }, + { 0x0013, 0x0223 }, + { 0x0013, 0x0224 }, + { 0x0013, 0x0225 }, + { 0x0013, 0x0226 }, + { 0x0013, 0x0227 }, + { 0x0013, 0x0228 }, + { 0x0013, 0x0229 }, + { 0x0013, 0x022a }, + { 0x0013, 0x022b }, + { 0x0013, 0x022c }, + { 0x0013, 0x022d }, + { 0x0013, 0x022e }, + { 0x0013, 0x022f }, + { 0x0013, 0x0230 }, + { 0x0013, 0x0231 }, + { 0x0013, 0x0232 }, + { 0x0013, 0x0233 }, + { 0x0013, 0x0234 }, + { 0x0013, 0x0235 }, + { 0x0013, 0x0236 }, + { 0x0013, 0x0237 }, + { 0x0013, 0x0238 }, + { 0x0013, 0x0239 }, + { 0x0013, 0x023a }, + { 0x0013, 0x023b }, + { 0x0013, 0x023c }, + { 0x0013, 0x023d }, + { 0x0013, 0x023e }, + { 0x0013, 0x023f }, + { 0x0013, 0x0240 }, + { 0x0013, 0x0241 }, + { 0x0013, 0x0242 }, + { 0x0013, 0x0243 }, + { 0x0013, 0x0244 }, + { 0x0013, 0x0245 }, + { 0x0013, 0x0246 }, + { 0x0013, 0x0247 }, + { 0x0013, 0x0248 }, + { 0x0013, 0x0249 }, + { 0x0013, 0x024a }, + { 0x0013, 0x024b }, + { 0x0013, 0x024c }, + { 0x0013, 0x024d }, + { 0x0013, 0x024e }, + { 0x0013, 0x024f }, + { 0x0013, 0x0250 }, + { 0x0013, 0x0251 }, + { 0x0013, 0x0252 }, + { 0x0013, 0x0253 }, + { 0x0013, 0x0254 }, + { 0x0013, 0x0255 }, + { 0x0013, 0x0256 }, + { 0x0013, 0x0257 }, + { 0x0013, 0x0258 }, + { 0x0013, 0x0259 }, + { 0x0013, 0x025a }, + { 0x0013, 0x025b }, + { 0x0013, 0x025c }, + { 0x0013, 0x025d }, + { 0x0013, 0x025e }, + { 0x0013, 0x025f }, + { 0x0013, 0x0260 }, + { 0x0013, 0x0261 }, + { 0x0013, 0x0262 }, + { 0x0013, 0x0263 }, + { 0x0013, 0x0264 }, + { 0x0013, 0x0265 }, + { 0x0013, 0x0266 }, + { 0x0013, 0x0267 }, + { 0x0013, 0x0268 }, + { 0x0013, 0x0269 }, + { 0x0013, 0x026a }, + { 0x0013, 0x026b }, + { 0x0012, 0x013f }, + + }; + +const uint16_t c_aauiLCLDHuffEnc49[729][2] = + { + { 0x0002, 0x0003 }, + { 0x0003, 0x0003 }, + { 0x0005, 0x0007 }, + { 0x0007, 0x000a }, + { 0x0008, 0x0009 }, + { 0x0008, 0x000a }, + { 0x0009, 0x0009 }, + { 0x000b, 0x000d }, + { 0x000d, 0x0014 }, + { 0x000d, 0x0015 }, + { 0x0010, 0x0052 }, + { 0x0011, 0x0098 }, + { 0x0013, 0x0000 }, + { 0x0013, 0x0001 }, + { 0x0013, 0x0002 }, + { 0x0013, 0x0003 }, + { 0x0013, 0x0004 }, + { 0x0013, 0x0005 }, + { 0x0013, 0x0006 }, + { 0x0013, 0x0007 }, + { 0x0013, 0x0008 }, + { 0x0013, 0x0009 }, + { 0x0013, 0x000a }, + { 0x0013, 0x000b }, + { 0x0013, 0x000c }, + { 0x0013, 0x000d }, + { 0x0013, 0x000e }, + { 0x0003, 0x0004 }, + { 0x0003, 0x0005 }, + { 0x0005, 0x0008 }, + { 0x0006, 0x000a }, + { 0x0007, 0x000b }, + { 0x0008, 0x000b }, + { 0x0008, 0x000c }, + { 0x000a, 0x000a }, + { 0x000b, 0x000e }, + { 0x000d, 0x0016 }, + { 0x000f, 0x0031 }, + { 0x0010, 0x0053 }, + { 0x0012, 0x012a }, + { 0x0013, 0x000f }, + { 0x0013, 0x0010 }, + { 0x0013, 0x0011 }, + { 0x0013, 0x0012 }, + { 0x0013, 0x0013 }, + { 0x0013, 0x0014 }, + { 0x0013, 0x0015 }, + { 0x0013, 0x0016 }, + { 0x0013, 0x0017 }, + { 0x0013, 0x0018 }, + { 0x0013, 0x0019 }, + { 0x0013, 0x001a }, + { 0x0013, 0x001b }, + { 0x0013, 0x001c }, + { 0x0005, 0x0009 }, + { 0x0005, 0x000a }, + { 0x0005, 0x000b }, + { 0x0006, 0x000b }, + { 0x0007, 0x000c }, + { 0x0008, 0x000d }, + { 0x0009, 0x000a }, + { 0x000a, 0x000b }, + { 0x000c, 0x000f }, + { 0x000d, 0x0017 }, + { 0x000f, 0x0032 }, + { 0x0010, 0x0054 }, + { 0x0013, 0x001d }, + { 0x0013, 0x001e }, + { 0x0013, 0x001f }, + { 0x0013, 0x0020 }, + { 0x0013, 0x0021 }, + { 0x0013, 0x0022 }, + { 0x0013, 0x0023 }, + { 0x0013, 0x0024 }, + { 0x0013, 0x0025 }, + { 0x0013, 0x0026 }, + { 0x0013, 0x0027 }, + { 0x0013, 0x0028 }, + { 0x0013, 0x0029 }, + { 0x0013, 0x002a }, + { 0x0013, 0x002b }, + { 0x0007, 0x000d }, + { 0x0006, 0x000c }, + { 0x0006, 0x000d }, + { 0x0007, 0x000e }, + { 0x0007, 0x000f }, + { 0x0008, 0x000e }, + { 0x0009, 0x000b }, + { 0x000b, 0x000f }, + { 0x000c, 0x0010 }, + { 0x000e, 0x001d }, + { 0x000f, 0x0033 }, + { 0x0011, 0x0099 }, + { 0x0013, 0x002c }, + { 0x0013, 0x002d }, + { 0x0013, 0x002e }, + { 0x0013, 0x002f }, + { 0x0013, 0x0030 }, + { 0x0013, 0x0031 }, + { 0x0013, 0x0032 }, + { 0x0013, 0x0033 }, + { 0x0013, 0x0034 }, + { 0x0013, 0x0035 }, + { 0x0013, 0x0036 }, + { 0x0013, 0x0037 }, + { 0x0013, 0x0038 }, + { 0x0013, 0x0039 }, + { 0x0013, 0x003a }, + { 0x0008, 0x000f }, + { 0x0007, 0x0010 }, + { 0x0007, 0x0011 }, + { 0x0007, 0x0012 }, + { 0x0008, 0x0010 }, + { 0x0009, 0x000c }, + { 0x000a, 0x000c }, + { 0x000c, 0x0011 }, + { 0x000d, 0x0018 }, + { 0x000e, 0x001e }, + { 0x0011, 0x009a }, + { 0x0011, 0x009b }, + { 0x0013, 0x003b }, + { 0x0013, 0x003c }, + { 0x0013, 0x003d }, + { 0x0013, 0x003e }, + { 0x0013, 0x003f }, + { 0x0013, 0x0040 }, + { 0x0013, 0x0041 }, + { 0x0013, 0x0042 }, + { 0x0013, 0x0043 }, + { 0x0013, 0x0044 }, + { 0x0013, 0x0045 }, + { 0x0013, 0x0046 }, + { 0x0013, 0x0047 }, + { 0x0013, 0x0048 }, + { 0x0013, 0x0049 }, + { 0x0008, 0x0011 }, + { 0x0007, 0x0013 }, + { 0x0008, 0x0012 }, + { 0x0008, 0x0013 }, + { 0x0009, 0x000d }, + { 0x000a, 0x000d }, + { 0x000b, 0x0010 }, + { 0x000c, 0x0012 }, + { 0x000e, 0x001f }, + { 0x000e, 0x0020 }, + { 0x0010, 0x0055 }, + { 0x0011, 0x009c }, + { 0x0013, 0x004a }, + { 0x0013, 0x004b }, + { 0x0013, 0x004c }, + { 0x0013, 0x004d }, + { 0x0013, 0x004e }, + { 0x0013, 0x004f }, + { 0x0013, 0x0050 }, + { 0x0013, 0x0051 }, + { 0x0013, 0x0052 }, + { 0x0013, 0x0053 }, + { 0x0013, 0x0054 }, + { 0x0013, 0x0055 }, + { 0x0013, 0x0056 }, + { 0x0013, 0x0057 }, + { 0x0013, 0x0058 }, + { 0x0009, 0x000e }, + { 0x0009, 0x000f }, + { 0x0009, 0x0010 }, + { 0x0009, 0x0011 }, + { 0x000a, 0x000e }, + { 0x000b, 0x0011 }, + { 0x000c, 0x0013 }, + { 0x000d, 0x0019 }, + { 0x000e, 0x0021 }, + { 0x0010, 0x0056 }, + { 0x0010, 0x0057 }, + { 0x0013, 0x0059 }, + { 0x0013, 0x005a }, + { 0x0013, 0x005b }, + { 0x0013, 0x005c }, + { 0x0013, 0x005d }, + { 0x0013, 0x005e }, + { 0x0013, 0x005f }, + { 0x0013, 0x0060 }, + { 0x0013, 0x0061 }, + { 0x0013, 0x0062 }, + { 0x0013, 0x0063 }, + { 0x0013, 0x0064 }, + { 0x0013, 0x0065 }, + { 0x0013, 0x0066 }, + { 0x0013, 0x0067 }, + { 0x0013, 0x0068 }, + { 0x000b, 0x0012 }, + { 0x000a, 0x000f }, + { 0x000a, 0x0010 }, + { 0x000a, 0x0011 }, + { 0x000c, 0x0014 }, + { 0x000c, 0x0015 }, + { 0x000d, 0x001a }, + { 0x000e, 0x0022 }, + { 0x0010, 0x0058 }, + { 0x0010, 0x0059 }, + { 0x0013, 0x0069 }, + { 0x0013, 0x006a }, + { 0x0013, 0x006b }, + { 0x0013, 0x006c }, + { 0x0013, 0x006d }, + { 0x0013, 0x006e }, + { 0x0013, 0x006f }, + { 0x0013, 0x0070 }, + { 0x0013, 0x0071 }, + { 0x0013, 0x0072 }, + { 0x0013, 0x0073 }, + { 0x0013, 0x0074 }, + { 0x0013, 0x0075 }, + { 0x0013, 0x0076 }, + { 0x0013, 0x0077 }, + { 0x0013, 0x0078 }, + { 0x0013, 0x0079 }, + { 0x000c, 0x0016 }, + { 0x000b, 0x0013 }, + { 0x000c, 0x0017 }, + { 0x000c, 0x0018 }, + { 0x000c, 0x0019 }, + { 0x000e, 0x0023 }, + { 0x000e, 0x0024 }, + { 0x000f, 0x0034 }, + { 0x0010, 0x005a }, + { 0x0011, 0x009d }, + { 0x0013, 0x007a }, + { 0x0013, 0x007b }, + { 0x0013, 0x007c }, + { 0x0013, 0x007d }, + { 0x0013, 0x007e }, + { 0x0013, 0x007f }, + { 0x0013, 0x0080 }, + { 0x0013, 0x0081 }, + { 0x0013, 0x0082 }, + { 0x0013, 0x0083 }, + { 0x0013, 0x0084 }, + { 0x0013, 0x0085 }, + { 0x0013, 0x0086 }, + { 0x0013, 0x0087 }, + { 0x0013, 0x0088 }, + { 0x0013, 0x0089 }, + { 0x0013, 0x008a }, + { 0x000e, 0x0025 }, + { 0x000d, 0x001b }, + { 0x000d, 0x001c }, + { 0x000d, 0x001d }, + { 0x000e, 0x0026 }, + { 0x000f, 0x0035 }, + { 0x0010, 0x005b }, + { 0x0011, 0x009e }, + { 0x0011, 0x009f }, + { 0x0012, 0x012b }, + { 0x0013, 0x008b }, + { 0x0013, 0x008c }, + { 0x0013, 0x008d }, + { 0x0013, 0x008e }, + { 0x0013, 0x008f }, + { 0x0013, 0x0090 }, + { 0x0013, 0x0091 }, + { 0x0013, 0x0092 }, + { 0x0013, 0x0093 }, + { 0x0013, 0x0094 }, + { 0x0013, 0x0095 }, + { 0x0013, 0x0096 }, + { 0x0013, 0x0097 }, + { 0x0013, 0x0098 }, + { 0x0013, 0x0099 }, + { 0x0013, 0x009a }, + { 0x0013, 0x009b }, + { 0x0010, 0x005c }, + { 0x000f, 0x0036 }, + { 0x000e, 0x0027 }, + { 0x000f, 0x0037 }, + { 0x000f, 0x0038 }, + { 0x0010, 0x005d }, + { 0x0011, 0x00a0 }, + { 0x0013, 0x009c }, + { 0x0012, 0x012c }, + { 0x0013, 0x009d }, + { 0x0013, 0x009e }, + { 0x0013, 0x009f }, + { 0x0013, 0x00a0 }, + { 0x0013, 0x00a1 }, + { 0x0013, 0x00a2 }, + { 0x0013, 0x00a3 }, + { 0x0013, 0x00a4 }, + { 0x0013, 0x00a5 }, + { 0x0013, 0x00a6 }, + { 0x0013, 0x00a7 }, + { 0x0013, 0x00a8 }, + { 0x0013, 0x00a9 }, + { 0x0013, 0x00aa }, + { 0x0013, 0x00ab }, + { 0x0013, 0x00ac }, + { 0x0013, 0x00ad }, + { 0x0013, 0x00ae }, + { 0x0010, 0x005e }, + { 0x000f, 0x0039 }, + { 0x0010, 0x005f }, + { 0x0010, 0x0060 }, + { 0x0011, 0x00a1 }, + { 0x0010, 0x0061 }, + { 0x0013, 0x00af }, + { 0x0013, 0x00b0 }, + { 0x0012, 0x012d }, + { 0x0013, 0x00b1 }, + { 0x0013, 0x00b2 }, + { 0x0013, 0x00b3 }, + { 0x0013, 0x00b4 }, + { 0x0013, 0x00b5 }, + { 0x0013, 0x00b6 }, + { 0x0013, 0x00b7 }, + { 0x0013, 0x00b8 }, + { 0x0013, 0x00b9 }, + { 0x0013, 0x00ba }, + { 0x0013, 0x00bb }, + { 0x0013, 0x00bc }, + { 0x0013, 0x00bd }, + { 0x0013, 0x00be }, + { 0x0013, 0x00bf }, + { 0x0013, 0x00c0 }, + { 0x0013, 0x00c1 }, + { 0x0013, 0x00c2 }, + { 0x0012, 0x012e }, + { 0x0011, 0x00a2 }, + { 0x0011, 0x00a3 }, + { 0x0013, 0x00c3 }, + { 0x0013, 0x00c4 }, + { 0x0013, 0x00c5 }, + { 0x0013, 0x00c6 }, + { 0x0013, 0x00c7 }, + { 0x0013, 0x00c8 }, + { 0x0013, 0x00c9 }, + { 0x0013, 0x00ca }, + { 0x0013, 0x00cb }, + { 0x0013, 0x00cc }, + { 0x0013, 0x00cd }, + { 0x0013, 0x00ce }, + { 0x0013, 0x00cf }, + { 0x0013, 0x00d0 }, + { 0x0013, 0x00d1 }, + { 0x0013, 0x00d2 }, + { 0x0013, 0x00d3 }, + { 0x0013, 0x00d4 }, + { 0x0013, 0x00d5 }, + { 0x0013, 0x00d6 }, + { 0x0013, 0x00d7 }, + { 0x0013, 0x00d8 }, + { 0x0013, 0x00d9 }, + { 0x0013, 0x00da }, + { 0x0013, 0x00db }, + { 0x0013, 0x00dc }, + { 0x0013, 0x00dd }, + { 0x0013, 0x00de }, + { 0x0013, 0x00df }, + { 0x0012, 0x012f }, + { 0x0013, 0x00e0 }, + { 0x0013, 0x00e1 }, + { 0x0013, 0x00e2 }, + { 0x0013, 0x00e3 }, + { 0x0013, 0x00e4 }, + { 0x0013, 0x00e5 }, + { 0x0013, 0x00e6 }, + { 0x0013, 0x00e7 }, + { 0x0013, 0x00e8 }, + { 0x0013, 0x00e9 }, + { 0x0013, 0x00ea }, + { 0x0013, 0x00eb }, + { 0x0013, 0x00ec }, + { 0x0013, 0x00ed }, + { 0x0013, 0x00ee }, + { 0x0013, 0x00ef }, + { 0x0013, 0x00f0 }, + { 0x0013, 0x00f1 }, + { 0x0013, 0x00f2 }, + { 0x0013, 0x00f3 }, + { 0x0013, 0x00f4 }, + { 0x0013, 0x00f5 }, + { 0x0013, 0x00f6 }, + { 0x0013, 0x00f7 }, + { 0x0013, 0x00f8 }, + { 0x0013, 0x00f9 }, + { 0x0013, 0x00fa }, + { 0x0013, 0x00fb }, + { 0x0013, 0x00fc }, + { 0x0013, 0x00fd }, + { 0x0013, 0x00fe }, + { 0x0013, 0x00ff }, + { 0x0013, 0x0100 }, + { 0x0013, 0x0101 }, + { 0x0013, 0x0102 }, + { 0x0013, 0x0103 }, + { 0x0013, 0x0104 }, + { 0x0013, 0x0105 }, + { 0x0013, 0x0106 }, + { 0x0013, 0x0107 }, + { 0x0013, 0x0108 }, + { 0x0013, 0x0109 }, + { 0x0013, 0x010a }, + { 0x0013, 0x010b }, + { 0x0013, 0x010c }, + { 0x0013, 0x010d }, + { 0x0013, 0x010e }, + { 0x0013, 0x010f }, + { 0x0013, 0x0110 }, + { 0x0013, 0x0111 }, + { 0x0013, 0x0112 }, + { 0x0013, 0x0113 }, + { 0x0013, 0x0114 }, + { 0x0013, 0x0115 }, + { 0x0013, 0x0116 }, + { 0x0013, 0x0117 }, + { 0x0013, 0x0118 }, + { 0x0013, 0x0119 }, + { 0x0013, 0x011a }, + { 0x0013, 0x011b }, + { 0x0013, 0x011c }, + { 0x0013, 0x011d }, + { 0x0013, 0x011e }, + { 0x0013, 0x011f }, + { 0x0013, 0x0120 }, + { 0x0013, 0x0121 }, + { 0x0013, 0x0122 }, + { 0x0013, 0x0123 }, + { 0x0013, 0x0124 }, + { 0x0013, 0x0125 }, + { 0x0013, 0x0126 }, + { 0x0013, 0x0127 }, + { 0x0013, 0x0128 }, + { 0x0013, 0x0129 }, + { 0x0013, 0x012a }, + { 0x0013, 0x012b }, + { 0x0013, 0x012c }, + { 0x0013, 0x012d }, + { 0x0013, 0x012e }, + { 0x0013, 0x012f }, + { 0x0013, 0x0130 }, + { 0x0013, 0x0131 }, + { 0x0013, 0x0132 }, + { 0x0013, 0x0133 }, + { 0x0013, 0x0134 }, + { 0x0013, 0x0135 }, + { 0x0013, 0x0136 }, + { 0x0013, 0x0137 }, + { 0x0013, 0x0138 }, + { 0x0013, 0x0139 }, + { 0x0013, 0x013a }, + { 0x0013, 0x013b }, + { 0x0013, 0x013c }, + { 0x0013, 0x013d }, + { 0x0013, 0x013e }, + { 0x0013, 0x013f }, + { 0x0013, 0x0140 }, + { 0x0013, 0x0141 }, + { 0x0013, 0x0142 }, + { 0x0013, 0x0143 }, + { 0x0013, 0x0144 }, + { 0x0013, 0x0145 }, + { 0x0013, 0x0146 }, + { 0x0013, 0x0147 }, + { 0x0013, 0x0148 }, + { 0x0013, 0x0149 }, + { 0x0013, 0x014a }, + { 0x0013, 0x014b }, + { 0x0013, 0x014c }, + { 0x0013, 0x014d }, + { 0x0013, 0x014e }, + { 0x0013, 0x014f }, + { 0x0013, 0x0150 }, + { 0x0013, 0x0151 }, + { 0x0013, 0x0152 }, + { 0x0013, 0x0153 }, + { 0x0013, 0x0154 }, + { 0x0013, 0x0155 }, + { 0x0013, 0x0156 }, + { 0x0013, 0x0157 }, + { 0x0013, 0x0158 }, + { 0x0013, 0x0159 }, + { 0x0013, 0x015a }, + { 0x0013, 0x015b }, + { 0x0013, 0x015c }, + { 0x0013, 0x015d }, + { 0x0013, 0x015e }, + { 0x0013, 0x015f }, + { 0x0013, 0x0160 }, + { 0x0013, 0x0161 }, + { 0x0013, 0x0162 }, + { 0x0013, 0x0163 }, + { 0x0013, 0x0164 }, + { 0x0013, 0x0165 }, + { 0x0013, 0x0166 }, + { 0x0013, 0x0167 }, + { 0x0013, 0x0168 }, + { 0x0013, 0x0169 }, + { 0x0013, 0x016a }, + { 0x0013, 0x016b }, + { 0x0013, 0x016c }, + { 0x0013, 0x016d }, + { 0x0013, 0x016e }, + { 0x0013, 0x016f }, + { 0x0013, 0x0170 }, + { 0x0013, 0x0171 }, + { 0x0013, 0x0172 }, + { 0x0013, 0x0173 }, + { 0x0013, 0x0174 }, + { 0x0013, 0x0175 }, + { 0x0013, 0x0176 }, + { 0x0013, 0x0177 }, + { 0x0013, 0x0178 }, + { 0x0013, 0x0179 }, + { 0x0013, 0x017a }, + { 0x0013, 0x017b }, + { 0x0013, 0x017c }, + { 0x0013, 0x017d }, + { 0x0013, 0x017e }, + { 0x0013, 0x017f }, + { 0x0013, 0x0180 }, + { 0x0013, 0x0181 }, + { 0x0013, 0x0182 }, + { 0x0013, 0x0183 }, + { 0x0013, 0x0184 }, + { 0x0013, 0x0185 }, + { 0x0013, 0x0186 }, + { 0x0013, 0x0187 }, + { 0x0013, 0x0188 }, + { 0x0013, 0x0189 }, + { 0x0013, 0x018a }, + { 0x0013, 0x018b }, + { 0x0013, 0x018c }, + { 0x0013, 0x018d }, + { 0x0013, 0x018e }, + { 0x0013, 0x018f }, + { 0x0013, 0x0190 }, + { 0x0013, 0x0191 }, + { 0x0013, 0x0192 }, + { 0x0013, 0x0193 }, + { 0x0013, 0x0194 }, + { 0x0013, 0x0195 }, + { 0x0013, 0x0196 }, + { 0x0013, 0x0197 }, + { 0x0013, 0x0198 }, + { 0x0013, 0x0199 }, + { 0x0013, 0x019a }, + { 0x0013, 0x019b }, + { 0x0013, 0x019c }, + { 0x0013, 0x019d }, + { 0x0013, 0x019e }, + { 0x0013, 0x019f }, + { 0x0013, 0x01a0 }, + { 0x0013, 0x01a1 }, + { 0x0013, 0x01a2 }, + { 0x0013, 0x01a3 }, + { 0x0013, 0x01a4 }, + { 0x0013, 0x01a5 }, + { 0x0013, 0x01a6 }, + { 0x0013, 0x01a7 }, + { 0x0013, 0x01a8 }, + { 0x0013, 0x01a9 }, + { 0x0013, 0x01aa }, + { 0x0013, 0x01ab }, + { 0x0013, 0x01ac }, + { 0x0013, 0x01ad }, + { 0x0013, 0x01ae }, + { 0x0013, 0x01af }, + { 0x0013, 0x01b0 }, + { 0x0013, 0x01b1 }, + { 0x0013, 0x01b2 }, + { 0x0013, 0x01b3 }, + { 0x0013, 0x01b4 }, + { 0x0013, 0x01b5 }, + { 0x0013, 0x01b6 }, + { 0x0013, 0x01b7 }, + { 0x0013, 0x01b8 }, + { 0x0013, 0x01b9 }, + { 0x0013, 0x01ba }, + { 0x0013, 0x01bb }, + { 0x0013, 0x01bc }, + { 0x0013, 0x01bd }, + { 0x0013, 0x01be }, + { 0x0013, 0x01bf }, + { 0x0013, 0x01c0 }, + { 0x0013, 0x01c1 }, + { 0x0013, 0x01c2 }, + { 0x0013, 0x01c3 }, + { 0x0013, 0x01c4 }, + { 0x0013, 0x01c5 }, + { 0x0013, 0x01c6 }, + { 0x0013, 0x01c7 }, + { 0x0013, 0x01c8 }, + { 0x0013, 0x01c9 }, + { 0x0013, 0x01ca }, + { 0x0013, 0x01cb }, + { 0x0013, 0x01cc }, + { 0x0013, 0x01cd }, + { 0x0013, 0x01ce }, + { 0x0013, 0x01cf }, + { 0x0013, 0x01d0 }, + { 0x0013, 0x01d1 }, + { 0x0013, 0x01d2 }, + { 0x0013, 0x01d3 }, + { 0x0013, 0x01d4 }, + { 0x0013, 0x01d5 }, + { 0x0013, 0x01d6 }, + { 0x0013, 0x01d7 }, + { 0x0013, 0x01d8 }, + { 0x0013, 0x01d9 }, + { 0x0013, 0x01da }, + { 0x0013, 0x01db }, + { 0x0013, 0x01dc }, + { 0x0013, 0x01dd }, + { 0x0013, 0x01de }, + { 0x0013, 0x01df }, + { 0x0013, 0x01e0 }, + { 0x0013, 0x01e1 }, + { 0x0013, 0x01e2 }, + { 0x0013, 0x01e3 }, + { 0x0013, 0x01e4 }, + { 0x0013, 0x01e5 }, + { 0x0013, 0x01e6 }, + { 0x0013, 0x01e7 }, + { 0x0013, 0x01e8 }, + { 0x0013, 0x01e9 }, + { 0x0013, 0x01ea }, + { 0x0013, 0x01eb }, + { 0x0013, 0x01ec }, + { 0x0013, 0x01ed }, + { 0x0013, 0x01ee }, + { 0x0013, 0x01ef }, + { 0x0013, 0x01f0 }, + { 0x0013, 0x01f1 }, + { 0x0013, 0x01f2 }, + { 0x0013, 0x01f3 }, + { 0x0013, 0x01f4 }, + { 0x0013, 0x01f5 }, + { 0x0013, 0x01f6 }, + { 0x0013, 0x01f7 }, + { 0x0013, 0x01f8 }, + { 0x0013, 0x01f9 }, + { 0x0013, 0x01fa }, + { 0x0013, 0x01fb }, + { 0x0013, 0x01fc }, + { 0x0013, 0x01fd }, + { 0x0013, 0x01fe }, + { 0x0013, 0x01ff }, + { 0x0013, 0x0200 }, + { 0x0013, 0x0201 }, + { 0x0013, 0x0202 }, + { 0x0013, 0x0203 }, + { 0x0013, 0x0204 }, + { 0x0013, 0x0205 }, + { 0x0013, 0x0206 }, + { 0x0013, 0x0207 }, + { 0x0013, 0x0208 }, + { 0x0013, 0x0209 }, + { 0x0013, 0x020a }, + { 0x0013, 0x020b }, + { 0x0013, 0x020c }, + { 0x0013, 0x020d }, + { 0x0013, 0x020e }, + { 0x0013, 0x020f }, + { 0x0013, 0x0210 }, + { 0x0013, 0x0211 }, + { 0x0013, 0x0212 }, + { 0x0013, 0x0213 }, + { 0x0013, 0x0214 }, + { 0x0013, 0x0215 }, + { 0x0013, 0x0216 }, + { 0x0013, 0x0217 }, + { 0x0013, 0x0218 }, + { 0x0013, 0x0219 }, + { 0x0013, 0x021a }, + { 0x0013, 0x021b }, + { 0x0013, 0x021c }, + { 0x0013, 0x021d }, + { 0x0013, 0x021e }, + { 0x0013, 0x021f }, + { 0x0013, 0x0220 }, + { 0x0013, 0x0221 }, + { 0x0013, 0x0222 }, + { 0x0013, 0x0223 }, + { 0x0013, 0x0224 }, + { 0x0013, 0x0225 }, + { 0x0013, 0x0226 }, + { 0x0013, 0x0227 }, + { 0x0013, 0x0228 }, + { 0x0013, 0x0229 }, + { 0x0013, 0x022a }, + { 0x0013, 0x022b }, + { 0x0013, 0x022c }, + { 0x0013, 0x022d }, + { 0x0013, 0x022e }, + { 0x0013, 0x022f }, + { 0x0013, 0x0230 }, + { 0x0013, 0x0231 }, + { 0x0013, 0x0232 }, + { 0x0013, 0x0233 }, + { 0x0013, 0x0234 }, + { 0x0013, 0x0235 }, + { 0x0013, 0x0236 }, + { 0x0013, 0x0237 }, + { 0x0013, 0x0238 }, + { 0x0013, 0x0239 }, + { 0x0013, 0x023a }, + { 0x0013, 0x023b }, + { 0x0013, 0x023c }, + { 0x0013, 0x023d }, + { 0x0013, 0x023e }, + { 0x0013, 0x023f }, + { 0x0013, 0x0240 }, + { 0x0013, 0x0241 }, + { 0x0013, 0x0242 }, + { 0x0013, 0x0243 }, + { 0x0013, 0x0244 }, + { 0x0013, 0x0245 }, + { 0x0013, 0x0246 }, + { 0x0013, 0x0247 }, + { 0x0013, 0x0248 }, + { 0x0013, 0x0249 }, + { 0x0013, 0x024a }, + { 0x0013, 0x024b }, + { 0x0013, 0x024c }, + { 0x0013, 0x024d }, + { 0x0013, 0x024e }, + { 0x0013, 0x024f }, + { 0x0013, 0x0250 }, + { 0x0013, 0x0251 }, + { 0x0013, 0x0252 }, + { 0x0013, 0x0253 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc50[28][2] = + { + { 0x0002, 0x0001 }, + { 0x0002, 0x0002 }, + { 0x0002, 0x0003 }, + { 0x0003, 0x0001 }, + { 0x0004, 0x0001 }, + { 0x0005, 0x0001 }, + { 0x0006, 0x0001 }, + { 0x0007, 0x0001 }, + { 0x0008, 0x0001 }, + { 0x0009, 0x0001 }, + { 0x000a, 0x0001 }, + { 0x000b, 0x0001 }, + { 0x000c, 0x0001 }, + { 0x000d, 0x0001 }, + { 0x000e, 0x0001 }, + { 0x000f, 0x0001 }, + { 0x0011, 0x0003 }, + { 0x0012, 0x0005 }, + { 0x0013, 0x0000 }, + { 0x0013, 0x0001 }, + { 0x0013, 0x0002 }, + { 0x0013, 0x0003 }, + { 0x0013, 0x0004 }, + { 0x0013, 0x0005 }, + { 0x0013, 0x0006 }, + { 0x0013, 0x0007 }, + { 0x0013, 0x0008 }, + { 0x0013, 0x0009 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc51[29][2] = + { + { 0x0002, 0x0002 }, + { 0x0002, 0x0003 }, + { 0x0003, 0x0002 }, + { 0x0003, 0x0003 }, + { 0x0004, 0x0001 }, + { 0x0004, 0x0002 }, + { 0x0004, 0x0003 }, + { 0x0005, 0x0001 }, + { 0x0006, 0x0001 }, + { 0x0007, 0x0001 }, + { 0x0008, 0x0001 }, + { 0x0009, 0x0001 }, + { 0x000a, 0x0001 }, + { 0x000b, 0x0001 }, + { 0x000c, 0x0001 }, + { 0x000d, 0x0001 }, + { 0x000e, 0x0001 }, + { 0x0010, 0x0002 }, + { 0x0010, 0x0003 }, + { 0x0012, 0x0002 }, + { 0x0012, 0x0003 }, + { 0x0013, 0x0000 }, + { 0x0013, 0x0001 }, + { 0x0013, 0x0002 }, + { 0x0013, 0x0003 }, + { 0x0012, 0x0004 }, + { 0x0012, 0x0005 }, + { 0x0012, 0x0006 }, + { 0x0012, 0x0007 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc52[32][2] = + { + { 0x0002, 0x0002 }, + { 0x0002, 0x0003 }, + { 0x0003, 0x0002 }, + { 0x0003, 0x0003 }, + { 0x0004, 0x0002 }, + { 0x0004, 0x0003 }, + { 0x0005, 0x0001 }, + { 0x0005, 0x0002 }, + { 0x0005, 0x0003 }, + { 0x0006, 0x0001 }, + { 0x0007, 0x0001 }, + { 0x0008, 0x0001 }, + { 0x0009, 0x0001 }, + { 0x000a, 0x0001 }, + { 0x000b, 0x0001 }, + { 0x000c, 0x0001 }, + { 0x000e, 0x0001 }, + { 0x000e, 0x0002 }, + { 0x000e, 0x0003 }, + { 0x000f, 0x0001 }, + { 0x0011, 0x0002 }, + { 0x0011, 0x0003 }, + { 0x0012, 0x0003 }, + { 0x0014, 0x0000 }, + { 0x0013, 0x0003 }, + { 0x0014, 0x0001 }, + { 0x0014, 0x0002 }, + { 0x0014, 0x0003 }, + { 0x0014, 0x0004 }, + { 0x0014, 0x0005 }, + { 0x0013, 0x0004 }, + { 0x0013, 0x0005 }, + }; + +const uint16_t c_aauiLCLDHuffEnc53[37][2] = + { + { 0x0002, 0x0002 }, + { 0x0002, 0x0003 }, + { 0x0003, 0x0002 }, + { 0x0003, 0x0003 }, + { 0x0004, 0x0002 }, + { 0x0004, 0x0003 }, + { 0x0005, 0x0002 }, + { 0x0005, 0x0003 }, + { 0x0006, 0x0002 }, + { 0x0006, 0x0003 }, + { 0x0007, 0x0001 }, + { 0x0007, 0x0002 }, + { 0x0007, 0x0003 }, + { 0x0008, 0x0001 }, + { 0x0009, 0x0001 }, + { 0x000b, 0x0002 }, + { 0x000b, 0x0003 }, + { 0x000c, 0x0002 }, + { 0x000c, 0x0003 }, + { 0x000d, 0x0002 }, + { 0x000d, 0x0003 }, + { 0x000e, 0x0002 }, + { 0x000e, 0x0003 }, + { 0x000f, 0x0002 }, + { 0x000f, 0x0003 }, + { 0x0011, 0x0004 }, + { 0x0010, 0x0003 }, + { 0x0011, 0x0005 }, + { 0x0013, 0x0000 }, + { 0x0013, 0x0001 }, + { 0x0012, 0x0001 }, + { 0x0012, 0x0002 }, + { 0x0012, 0x0003 }, + { 0x0012, 0x0004 }, + { 0x0012, 0x0005 }, + { 0x0012, 0x0006 }, + { 0x0012, 0x0007 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc54[39][2] = + { + { 0x0002, 0x0002 }, + { 0x0002, 0x0003 }, + { 0x0003, 0x0002 }, + { 0x0003, 0x0003 }, + { 0x0004, 0x0003 }, + { 0x0005, 0x0003 }, + { 0x0005, 0x0004 }, + { 0x0005, 0x0005 }, + { 0x0006, 0x0002 }, + { 0x0006, 0x0003 }, + { 0x0006, 0x0004 }, + { 0x0006, 0x0005 }, + { 0x0007, 0x0002 }, + { 0x0007, 0x0003 }, + { 0x0008, 0x0001 }, + { 0x0008, 0x0002 }, + { 0x0008, 0x0003 }, + { 0x000a, 0x0002 }, + { 0x000a, 0x0003 }, + { 0x000b, 0x0002 }, + { 0x000b, 0x0003 }, + { 0x000c, 0x0002 }, + { 0x000c, 0x0003 }, + { 0x000d, 0x0002 }, + { 0x000d, 0x0003 }, + { 0x000e, 0x0002 }, + { 0x000e, 0x0003 }, + { 0x000f, 0x0002 }, + { 0x000f, 0x0003 }, + { 0x0011, 0x0002 }, + { 0x0010, 0x0002 }, + { 0x0010, 0x0003 }, + { 0x0011, 0x0003 }, + { 0x0012, 0x0002 }, + { 0x0012, 0x0003 }, + { 0x0013, 0x0000 }, + { 0x0013, 0x0001 }, + { 0x0013, 0x0002 }, + { 0x0013, 0x0003 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc55[46][2] = + { + { 0x0003, 0x0003 }, + { 0x0002, 0x0003 }, + { 0x0003, 0x0004 }, + { 0x0003, 0x0005 }, + { 0x0004, 0x0003 }, + { 0x0004, 0x0004 }, + { 0x0004, 0x0005 }, + { 0x0005, 0x0003 }, + { 0x0005, 0x0004 }, + { 0x0005, 0x0005 }, + { 0x0006, 0x0003 }, + { 0x0006, 0x0004 }, + { 0x0006, 0x0005 }, + { 0x0007, 0x0002 }, + { 0x0007, 0x0003 }, + { 0x0007, 0x0004 }, + { 0x0007, 0x0005 }, + { 0x0008, 0x0002 }, + { 0x0008, 0x0003 }, + { 0x0009, 0x0002 }, + { 0x0009, 0x0003 }, + { 0x000a, 0x0002 }, + { 0x000a, 0x0003 }, + { 0x000b, 0x0002 }, + { 0x000b, 0x0003 }, + { 0x000c, 0x0002 }, + { 0x000c, 0x0003 }, + { 0x000d, 0x0002 }, + { 0x000d, 0x0003 }, + { 0x000e, 0x0002 }, + { 0x000e, 0x0003 }, + { 0x000f, 0x0003 }, + { 0x0010, 0x0002 }, + { 0x0010, 0x0003 }, + { 0x0010, 0x0004 }, + { 0x0010, 0x0005 }, + { 0x0011, 0x0003 }, + { 0x0012, 0x0003 }, + { 0x0012, 0x0004 }, + { 0x0012, 0x0005 }, + { 0x0013, 0x0000 }, + { 0x0013, 0x0001 }, + { 0x0013, 0x0002 }, + { 0x0013, 0x0003 }, + { 0x0013, 0x0004 }, + { 0x0013, 0x0005 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc56[55][2] = + { + { 0x0003, 0x0003 }, + { 0x0002, 0x0003 }, + { 0x0003, 0x0004 }, + { 0x0003, 0x0005 }, + { 0x0004, 0x0004 }, + { 0x0004, 0x0005 }, + { 0x0005, 0x0003 }, + { 0x0005, 0x0004 }, + { 0x0005, 0x0005 }, + { 0x0005, 0x0006 }, + { 0x0005, 0x0007 }, + { 0x0006, 0x0003 }, + { 0x0006, 0x0004 }, + { 0x0006, 0x0005 }, + { 0x0007, 0x0003 }, + { 0x0007, 0x0004 }, + { 0x0007, 0x0005 }, + { 0x0008, 0x0002 }, + { 0x0008, 0x0003 }, + { 0x0008, 0x0004 }, + { 0x0008, 0x0005 }, + { 0x0009, 0x0002 }, + { 0x0009, 0x0003 }, + { 0x000a, 0x0002 }, + { 0x000a, 0x0003 }, + { 0x000b, 0x0003 }, + { 0x000c, 0x0003 }, + { 0x000c, 0x0004 }, + { 0x000c, 0x0005 }, + { 0x000d, 0x0003 }, + { 0x000d, 0x0004 }, + { 0x000d, 0x0005 }, + { 0x000e, 0x0003 }, + { 0x000e, 0x0004 }, + { 0x000e, 0x0005 }, + { 0x000f, 0x0004 }, + { 0x000f, 0x0005 }, + { 0x0010, 0x0002 }, + { 0x0010, 0x0003 }, + { 0x0010, 0x0004 }, + { 0x0010, 0x0005 }, + { 0x0010, 0x0006 }, + { 0x0010, 0x0007 }, + { 0x0013, 0x0000 }, + { 0x0011, 0x0003 }, + { 0x0012, 0x0005 }, + { 0x0013, 0x0001 }, + { 0x0013, 0x0002 }, + { 0x0013, 0x0003 }, + { 0x0013, 0x0004 }, + { 0x0013, 0x0005 }, + { 0x0013, 0x0006 }, + { 0x0013, 0x0007 }, + { 0x0013, 0x0008 }, + { 0x0013, 0x0009 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc57[65][2] = + { + { 0x0003, 0x0004 }, + { 0x0002, 0x0003 }, + { 0x0003, 0x0005 }, + { 0x0004, 0x0004 }, + { 0x0004, 0x0005 }, + { 0x0004, 0x0006 }, + { 0x0004, 0x0007 }, + { 0x0005, 0x0004 }, + { 0x0005, 0x0005 }, + { 0x0005, 0x0006 }, + { 0x0005, 0x0007 }, + { 0x0006, 0x0004 }, + { 0x0006, 0x0005 }, + { 0x0006, 0x0006 }, + { 0x0006, 0x0007 }, + { 0x0007, 0x0003 }, + { 0x0007, 0x0004 }, + { 0x0007, 0x0005 }, + { 0x0007, 0x0006 }, + { 0x0007, 0x0007 }, + { 0x0008, 0x0003 }, + { 0x0008, 0x0004 }, + { 0x0008, 0x0005 }, + { 0x0009, 0x0003 }, + { 0x0009, 0x0004 }, + { 0x0009, 0x0005 }, + { 0x000a, 0x0003 }, + { 0x000a, 0x0004 }, + { 0x000a, 0x0005 }, + { 0x000b, 0x0003 }, + { 0x000b, 0x0004 }, + { 0x000b, 0x0005 }, + { 0x000c, 0x0003 }, + { 0x000c, 0x0004 }, + { 0x000d, 0x0003 }, + { 0x000c, 0x0005 }, + { 0x000d, 0x0004 }, + { 0x000d, 0x0005 }, + { 0x000e, 0x0003 }, + { 0x000e, 0x0004 }, + { 0x000e, 0x0005 }, + { 0x000f, 0x0003 }, + { 0x0010, 0x0003 }, + { 0x000f, 0x0004 }, + { 0x000f, 0x0005 }, + { 0x0010, 0x0004 }, + { 0x0010, 0x0005 }, + { 0x0013, 0x0000 }, + { 0x0011, 0x0005 }, + { 0x0013, 0x0001 }, + { 0x0013, 0x0002 }, + { 0x0012, 0x0007 }, + { 0x0013, 0x0003 }, + { 0x0013, 0x0004 }, + { 0x0012, 0x0008 }, + { 0x0012, 0x0009 }, + { 0x0013, 0x0005 }, + { 0x0013, 0x0006 }, + { 0x0013, 0x0007 }, + { 0x0013, 0x0008 }, + { 0x0013, 0x0009 }, + { 0x0013, 0x000a }, + { 0x0013, 0x000b }, + { 0x0013, 0x000c }, + { 0x0013, 0x000d }, + + }; + +const uint16_t c_aauiLCLDHuffEnc58[77][2] = + { + { 0x0004, 0x0005 }, + { 0x0003, 0x0005 }, + { 0x0003, 0x0006 }, + { 0x0003, 0x0007 }, + { 0x0004, 0x0006 }, + { 0x0004, 0x0007 }, + { 0x0004, 0x0008 }, + { 0x0004, 0x0009 }, + { 0x0005, 0x0005 }, + { 0x0005, 0x0006 }, + { 0x0005, 0x0007 }, + { 0x0005, 0x0008 }, + { 0x0005, 0x0009 }, + { 0x0006, 0x0004 }, + { 0x0006, 0x0005 }, + { 0x0006, 0x0006 }, + { 0x0006, 0x0007 }, + { 0x0006, 0x0008 }, + { 0x0006, 0x0009 }, + { 0x0007, 0x0004 }, + { 0x0007, 0x0005 }, + { 0x0007, 0x0006 }, + { 0x0007, 0x0007 }, + { 0x0008, 0x0003 }, + { 0x0008, 0x0004 }, + { 0x0008, 0x0005 }, + { 0x0008, 0x0006 }, + { 0x0008, 0x0007 }, + { 0x0009, 0x0003 }, + { 0x0009, 0x0004 }, + { 0x0009, 0x0005 }, + { 0x000a, 0x0003 }, + { 0x000a, 0x0004 }, + { 0x000a, 0x0005 }, + { 0x000b, 0x0004 }, + { 0x000b, 0x0005 }, + { 0x000c, 0x0004 }, + { 0x000c, 0x0005 }, + { 0x000c, 0x0006 }, + { 0x000c, 0x0007 }, + { 0x000d, 0x0004 }, + { 0x000d, 0x0005 }, + { 0x000d, 0x0006 }, + { 0x000d, 0x0007 }, + { 0x000e, 0x0004 }, + { 0x000e, 0x0005 }, + { 0x000e, 0x0006 }, + { 0x000e, 0x0007 }, + { 0x000f, 0x0004 }, + { 0x000f, 0x0005 }, + { 0x000f, 0x0006 }, + { 0x0010, 0x0004 }, + { 0x000f, 0x0007 }, + { 0x0010, 0x0005 }, + { 0x0010, 0x0006 }, + { 0x0010, 0x0007 }, + { 0x0013, 0x0000 }, + { 0x0013, 0x0001 }, + { 0x0012, 0x0006 }, + { 0x0011, 0x0007 }, + { 0x0013, 0x0002 }, + { 0x0013, 0x0003 }, + { 0x0013, 0x0004 }, + { 0x0013, 0x0005 }, + { 0x0012, 0x0007 }, + { 0x0013, 0x0006 }, + { 0x0013, 0x0007 }, + { 0x0013, 0x0008 }, + { 0x0013, 0x0009 }, + { 0x0013, 0x000a }, + { 0x0013, 0x000b }, + { 0x0012, 0x0008 }, + { 0x0012, 0x0009 }, + { 0x0012, 0x000a }, + { 0x0012, 0x000b }, + { 0x0012, 0x000c }, + { 0x0012, 0x000d }, + + }; + +const uint16_t c_aauiLCLDHuffEnc59[91][2] = + { + { 0x0003, 0x0005 }, + { 0x0003, 0x0006 }, + { 0x0003, 0x0007 }, + { 0x0004, 0x0006 }, + { 0x0004, 0x0007 }, + { 0x0004, 0x0008 }, + { 0x0004, 0x0009 }, + { 0x0005, 0x0006 }, + { 0x0005, 0x0007 }, + { 0x0005, 0x0008 }, + { 0x0005, 0x0009 }, + { 0x0005, 0x000a }, + { 0x0005, 0x000b }, + { 0x0006, 0x0006 }, + { 0x0006, 0x0007 }, + { 0x0006, 0x0008 }, + { 0x0006, 0x0009 }, + { 0x0006, 0x000a }, + { 0x0006, 0x000b }, + { 0x0007, 0x0005 }, + { 0x0007, 0x0006 }, + { 0x0007, 0x0007 }, + { 0x0007, 0x0008 }, + { 0x0007, 0x0009 }, + { 0x0007, 0x000a }, + { 0x0007, 0x000b }, + { 0x0008, 0x0003 }, + { 0x0008, 0x0004 }, + { 0x0008, 0x0005 }, + { 0x0008, 0x0006 }, + { 0x0008, 0x0007 }, + { 0x0008, 0x0008 }, + { 0x0008, 0x0009 }, + { 0x0009, 0x0004 }, + { 0x0009, 0x0005 }, + { 0x000a, 0x0004 }, + { 0x000a, 0x0005 }, + { 0x000a, 0x0006 }, + { 0x000a, 0x0007 }, + { 0x000b, 0x0004 }, + { 0x000b, 0x0005 }, + { 0x000b, 0x0006 }, + { 0x000b, 0x0007 }, + { 0x000c, 0x0004 }, + { 0x000c, 0x0005 }, + { 0x000c, 0x0006 }, + { 0x000c, 0x0007 }, + { 0x000d, 0x0003 }, + { 0x000d, 0x0004 }, + { 0x000d, 0x0005 }, + { 0x000d, 0x0006 }, + { 0x000d, 0x0007 }, + { 0x000e, 0x0003 }, + { 0x000e, 0x0004 }, + { 0x000e, 0x0005 }, + { 0x000f, 0x0003 }, + { 0x000f, 0x0004 }, + { 0x000f, 0x0005 }, + { 0x0011, 0x0008 }, + { 0x0011, 0x0009 }, + { 0x0013, 0x0000 }, + { 0x0011, 0x000a }, + { 0x0013, 0x0001 }, + { 0x0013, 0x0002 }, + { 0x0012, 0x000d }, + { 0x0012, 0x000e }, + { 0x0013, 0x0003 }, + { 0x0013, 0x0004 }, + { 0x0013, 0x0005 }, + { 0x0011, 0x000b }, + { 0x0013, 0x0006 }, + { 0x0013, 0x0007 }, + { 0x0013, 0x0008 }, + { 0x0013, 0x0009 }, + { 0x0013, 0x000a }, + { 0x0013, 0x000b }, + { 0x0013, 0x000c }, + { 0x0013, 0x000d }, + { 0x0013, 0x000e }, + { 0x0013, 0x000f }, + { 0x0013, 0x0010 }, + { 0x0013, 0x0011 }, + { 0x0013, 0x0012 }, + { 0x0013, 0x0013 }, + { 0x0013, 0x0014 }, + { 0x0013, 0x0015 }, + { 0x0013, 0x0016 }, + { 0x0013, 0x0017 }, + { 0x0013, 0x0018 }, + { 0x0013, 0x0019 }, + { 0x0012, 0x000f }, + + }; + +const uint16_t c_aauiLCLDHuffEnc60[109][2] = + { + { 0x0004, 0x0007 }, + { 0x0002, 0x0003 }, + { 0x0003, 0x0005 }, + { 0x0004, 0x0008 }, + { 0x0004, 0x0009 }, + { 0x0005, 0x0007 }, + { 0x0005, 0x0008 }, + { 0x0005, 0x0009 }, + { 0x0005, 0x000a }, + { 0x0005, 0x000b }, + { 0x0005, 0x000c }, + { 0x0005, 0x000d }, + { 0x0006, 0x0007 }, + { 0x0006, 0x0008 }, + { 0x0006, 0x0009 }, + { 0x0006, 0x000a }, + { 0x0006, 0x000b }, + { 0x0006, 0x000c }, + { 0x0006, 0x000d }, + { 0x0007, 0x0006 }, + { 0x0007, 0x0007 }, + { 0x0007, 0x0008 }, + { 0x0007, 0x0009 }, + { 0x0007, 0x000a }, + { 0x0007, 0x000b }, + { 0x0007, 0x000c }, + { 0x0007, 0x000d }, + { 0x0008, 0x0006 }, + { 0x0008, 0x0007 }, + { 0x0008, 0x0008 }, + { 0x0008, 0x0009 }, + { 0x0008, 0x000a }, + { 0x0008, 0x000b }, + { 0x0009, 0x0004 }, + { 0x0009, 0x0005 }, + { 0x0009, 0x0006 }, + { 0x0009, 0x0007 }, + { 0x0009, 0x0008 }, + { 0x0009, 0x0009 }, + { 0x0009, 0x000a }, + { 0x0009, 0x000b }, + { 0x000a, 0x0004 }, + { 0x000a, 0x0005 }, + { 0x000a, 0x0006 }, + { 0x000a, 0x0007 }, + { 0x000b, 0x0004 }, + { 0x000b, 0x0005 }, + { 0x000b, 0x0006 }, + { 0x000b, 0x0007 }, + { 0x000c, 0x0004 }, + { 0x000c, 0x0005 }, + { 0x000c, 0x0006 }, + { 0x000d, 0x0005 }, + { 0x000d, 0x0006 }, + { 0x000d, 0x0007 }, + { 0x000c, 0x0007 }, + { 0x000e, 0x0005 }, + { 0x000e, 0x0006 }, + { 0x000e, 0x0007 }, + { 0x000e, 0x0008 }, + { 0x000f, 0x0005 }, + { 0x000e, 0x0009 }, + { 0x000f, 0x0006 }, + { 0x0010, 0x0006 }, + { 0x000f, 0x0007 }, + { 0x000f, 0x0008 }, + { 0x000f, 0x0009 }, + { 0x0010, 0x0007 }, + { 0x0010, 0x0008 }, + { 0x0010, 0x0009 }, + { 0x0011, 0x000a }, + { 0x0013, 0x0000 }, + { 0x0011, 0x000b }, + { 0x0013, 0x0001 }, + { 0x0013, 0x0002 }, + { 0x0012, 0x0011 }, + { 0x0012, 0x0012 }, + { 0x0013, 0x0003 }, + { 0x0013, 0x0004 }, + { 0x0013, 0x0005 }, + { 0x0013, 0x0006 }, + { 0x0013, 0x0007 }, + { 0x0013, 0x0008 }, + { 0x0013, 0x0009 }, + { 0x0013, 0x000a }, + { 0x0013, 0x000b }, + { 0x0013, 0x000c }, + { 0x0013, 0x000d }, + { 0x0013, 0x000e }, + { 0x0013, 0x000f }, + { 0x0013, 0x0010 }, + { 0x0013, 0x0011 }, + { 0x0013, 0x0012 }, + { 0x0013, 0x0013 }, + { 0x0013, 0x0014 }, + { 0x0013, 0x0015 }, + { 0x0013, 0x0016 }, + { 0x0013, 0x0017 }, + { 0x0013, 0x0018 }, + { 0x0013, 0x0019 }, + { 0x0013, 0x001a }, + { 0x0013, 0x001b }, + { 0x0013, 0x001c }, + { 0x0013, 0x001d }, + { 0x0013, 0x001e }, + { 0x0013, 0x001f }, + { 0x0013, 0x0020 }, + { 0x0013, 0x0021 }, + { 0x0012, 0x0013 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc61[129][2] = + { + { 0x0004, 0x0008 }, + { 0x0003, 0x0006 }, + { 0x0003, 0x0007 }, + { 0x0004, 0x0009 }, + { 0x0004, 0x000a }, + { 0x0004, 0x000b }, + { 0x0005, 0x0008 }, + { 0x0005, 0x0009 }, + { 0x0005, 0x000a }, + { 0x0005, 0x000b }, + { 0x0005, 0x000c }, + { 0x0005, 0x000d }, + { 0x0005, 0x000e }, + { 0x0005, 0x000f }, + { 0x0006, 0x0008 }, + { 0x0006, 0x0009 }, + { 0x0006, 0x000a }, + { 0x0006, 0x000b }, + { 0x0006, 0x000c }, + { 0x0006, 0x000d }, + { 0x0006, 0x000e }, + { 0x0006, 0x000f }, + { 0x0007, 0x0008 }, + { 0x0007, 0x0009 }, + { 0x0007, 0x000a }, + { 0x0007, 0x000b }, + { 0x0007, 0x000c }, + { 0x0007, 0x000d }, + { 0x0007, 0x000e }, + { 0x0007, 0x000f }, + { 0x0008, 0x0006 }, + { 0x0008, 0x0007 }, + { 0x0008, 0x0008 }, + { 0x0008, 0x0009 }, + { 0x0008, 0x000a }, + { 0x0008, 0x000b }, + { 0x0008, 0x000c }, + { 0x0008, 0x000d }, + { 0x0008, 0x000e }, + { 0x0008, 0x000f }, + { 0x0009, 0x0006 }, + { 0x0009, 0x0007 }, + { 0x0009, 0x0008 }, + { 0x0009, 0x0009 }, + { 0x0009, 0x000a }, + { 0x0009, 0x000b }, + { 0x000a, 0x0005 }, + { 0x000a, 0x0006 }, + { 0x000a, 0x0007 }, + { 0x000a, 0x0008 }, + { 0x000a, 0x0009 }, + { 0x000a, 0x000a }, + { 0x000a, 0x000b }, + { 0x000b, 0x0005 }, + { 0x000b, 0x0006 }, + { 0x000b, 0x0007 }, + { 0x000b, 0x0008 }, + { 0x000b, 0x0009 }, + { 0x000c, 0x0006 }, + { 0x000c, 0x0007 }, + { 0x000c, 0x0008 }, + { 0x000c, 0x0009 }, + { 0x000d, 0x0005 }, + { 0x000d, 0x0006 }, + { 0x000d, 0x0007 }, + { 0x000d, 0x0008 }, + { 0x000d, 0x0009 }, + { 0x000d, 0x000a }, + { 0x000e, 0x0008 }, + { 0x000d, 0x000b }, + { 0x000e, 0x0009 }, + { 0x000f, 0x0009 }, + { 0x000f, 0x000a }, + { 0x000f, 0x000b }, + { 0x000f, 0x000c }, + { 0x000f, 0x000d }, + { 0x000f, 0x000e }, + { 0x0010, 0x000c }, + { 0x0011, 0x0015 }, + { 0x0010, 0x000d }, + { 0x000f, 0x000f }, + { 0x0010, 0x000e }, + { 0x0010, 0x000f }, + { 0x0012, 0x0000 }, + { 0x0011, 0x0016 }, + { 0x0010, 0x0010 }, + { 0x0010, 0x0011 }, + { 0x0011, 0x0017 }, + { 0x0012, 0x0001 }, + { 0x0012, 0x0002 }, + { 0x0012, 0x0003 }, + { 0x0012, 0x0004 }, + { 0x0012, 0x0005 }, + { 0x0012, 0x0006 }, + { 0x0012, 0x0007 }, + { 0x0012, 0x0008 }, + { 0x0012, 0x0009 }, + { 0x0012, 0x000a }, + { 0x0012, 0x000b }, + { 0x0012, 0x000c }, + { 0x0012, 0x000d }, + { 0x0012, 0x000e }, + { 0x0012, 0x000f }, + { 0x0012, 0x0010 }, + { 0x0012, 0x0011 }, + { 0x0012, 0x0012 }, + { 0x0012, 0x0013 }, + { 0x0012, 0x0014 }, + { 0x0012, 0x0015 }, + { 0x0012, 0x0016 }, + { 0x0012, 0x0017 }, + { 0x0012, 0x0018 }, + { 0x0012, 0x0019 }, + { 0x0012, 0x001a }, + { 0x0012, 0x001b }, + { 0x0012, 0x001c }, + { 0x0012, 0x001d }, + { 0x0012, 0x001e }, + { 0x0012, 0x001f }, + { 0x0012, 0x0020 }, + { 0x0012, 0x0021 }, + { 0x0012, 0x0022 }, + { 0x0012, 0x0023 }, + { 0x0012, 0x0024 }, + { 0x0012, 0x0025 }, + { 0x0012, 0x0026 }, + { 0x0012, 0x0027 }, + { 0x0012, 0x0028 }, + { 0x0012, 0x0029 }, + + }; + +const uint16_t c_aauiLCLDHuffEnc62[153][2] = + { + { 0x0004, 0x0009 }, + { 0x0003, 0x0006 }, + { 0x0003, 0x0007 }, + { 0x0004, 0x000a }, + { 0x0004, 0x000b }, + { 0x0005, 0x000a }, + { 0x0005, 0x000b }, + { 0x0005, 0x000c }, + { 0x0005, 0x000d }, + { 0x0005, 0x000e }, + { 0x0005, 0x000f }, + { 0x0005, 0x0010 }, + { 0x0005, 0x0011 }, + { 0x0006, 0x000a }, + { 0x0006, 0x000b }, + { 0x0006, 0x000c }, + { 0x0006, 0x000d }, + { 0x0006, 0x000e }, + { 0x0006, 0x000f }, + { 0x0006, 0x0010 }, + { 0x0006, 0x0011 }, + { 0x0006, 0x0012 }, + { 0x0006, 0x0013 }, + { 0x0007, 0x0009 }, + { 0x0007, 0x000a }, + { 0x0007, 0x000b }, + { 0x0007, 0x000c }, + { 0x0007, 0x000d }, + { 0x0007, 0x000e }, + { 0x0007, 0x000f }, + { 0x0007, 0x0010 }, + { 0x0007, 0x0011 }, + { 0x0007, 0x0012 }, + { 0x0007, 0x0013 }, + { 0x0008, 0x0009 }, + { 0x0008, 0x000a }, + { 0x0008, 0x000b }, + { 0x0008, 0x000c }, + { 0x0008, 0x000d }, + { 0x0008, 0x000e }, + { 0x0008, 0x000f }, + { 0x0008, 0x0010 }, + { 0x0008, 0x0011 }, + { 0x0009, 0x0007 }, + { 0x0009, 0x0008 }, + { 0x0009, 0x0009 }, + { 0x0009, 0x000a }, + { 0x0009, 0x000b }, + { 0x0009, 0x000c }, + { 0x0009, 0x000d }, + { 0x0009, 0x000e }, + { 0x0009, 0x000f }, + { 0x0009, 0x0010 }, + { 0x0009, 0x0011 }, + { 0x000a, 0x0004 }, + { 0x000a, 0x0005 }, + { 0x000a, 0x0006 }, + { 0x000a, 0x0007 }, + { 0x000a, 0x0008 }, + { 0x000a, 0x0009 }, + { 0x000a, 0x000a }, + { 0x000a, 0x000b }, + { 0x000a, 0x000c }, + { 0x000a, 0x000d }, + { 0x000b, 0x0007 }, + { 0x000c, 0x0007 }, + { 0x000c, 0x0008 }, + { 0x000c, 0x0009 }, + { 0x000c, 0x000a }, + { 0x000c, 0x000b }, + { 0x000c, 0x000c }, + { 0x000d, 0x0007 }, + { 0x000c, 0x000d }, + { 0x000d, 0x0008 }, + { 0x000d, 0x0009 }, + { 0x000d, 0x000a }, + { 0x000d, 0x000b }, + { 0x000e, 0x0008 }, + { 0x000d, 0x000c }, + { 0x000d, 0x000d }, + { 0x000e, 0x0009 }, + { 0x000e, 0x000a }, + { 0x000e, 0x000b }, + { 0x000e, 0x000c }, + { 0x000f, 0x000c }, + { 0x000e, 0x000d }, + { 0x000f, 0x000d }, + { 0x000f, 0x000e }, + { 0x000f, 0x000f }, + { 0x0010, 0x000f }, + { 0x0010, 0x0010 }, + { 0x0011, 0x0019 }, + { 0x0010, 0x0011 }, + { 0x0010, 0x0012 }, + { 0x0010, 0x0013 }, + { 0x0010, 0x0014 }, + { 0x0010, 0x0015 }, + { 0x0012, 0x0000 }, + { 0x0010, 0x0016 }, + { 0x0011, 0x001a }, + { 0x0010, 0x0017 }, + { 0x0012, 0x0001 }, + { 0x0012, 0x0002 }, + { 0x0012, 0x0003 }, + { 0x0011, 0x001b }, + { 0x0012, 0x0004 }, + { 0x0012, 0x0005 }, + { 0x0012, 0x0006 }, + { 0x0012, 0x0007 }, + { 0x0012, 0x0008 }, + { 0x0012, 0x0009 }, + { 0x0012, 0x000a }, + { 0x0012, 0x000b }, + { 0x0012, 0x000c }, + { 0x0012, 0x000d }, + { 0x0012, 0x000e }, + { 0x0012, 0x000f }, + { 0x0012, 0x0010 }, + { 0x0012, 0x0011 }, + { 0x0012, 0x0012 }, + { 0x0012, 0x0013 }, + { 0x0012, 0x0014 }, + { 0x0012, 0x0015 }, + { 0x0012, 0x0016 }, + { 0x0012, 0x0017 }, + { 0x0012, 0x0018 }, + { 0x0011, 0x001c }, + { 0x0012, 0x0019 }, + { 0x0012, 0x001a }, + { 0x0012, 0x001b }, + { 0x0012, 0x001c }, + { 0x0012, 0x001d }, + { 0x0012, 0x001e }, + { 0x0012, 0x001f }, + { 0x0012, 0x0020 }, + { 0x0012, 0x0021 }, + { 0x0012, 0x0022 }, + { 0x0012, 0x0023 }, + { 0x0012, 0x0024 }, + { 0x0012, 0x0025 }, + { 0x0012, 0x0026 }, + { 0x0012, 0x0027 }, + { 0x0012, 0x0028 }, + { 0x0012, 0x0029 }, + { 0x0012, 0x002a }, + { 0x0012, 0x002b }, + { 0x0012, 0x002c }, + { 0x0012, 0x002d }, + { 0x0012, 0x002e }, + { 0x0012, 0x002f }, + { 0x0012, 0x0030 }, + { 0x0012, 0x0031 }, + { 0x0011, 0x001d }, + + }; + +const uint16_t c_aauiLCLDHuffEnc63[181][2] = + { + { 0x0004, 0x0008 }, + { 0x0003, 0x0005 }, + { 0x0002, 0x0003 }, + { 0x0004, 0x0009 }, + { 0x0005, 0x000c }, + { 0x0005, 0x000d }, + { 0x0005, 0x000e }, + { 0x0005, 0x000f }, + { 0x0006, 0x000c }, + { 0x0006, 0x000d }, + { 0x0006, 0x000e }, + { 0x0006, 0x000f }, + { 0x0006, 0x0010 }, + { 0x0006, 0x0011 }, + { 0x0006, 0x0012 }, + { 0x0006, 0x0013 }, + { 0x0006, 0x0014 }, + { 0x0006, 0x0015 }, + { 0x0006, 0x0016 }, + { 0x0006, 0x0017 }, + { 0x0007, 0x000b }, + { 0x0007, 0x000c }, + { 0x0007, 0x000d }, + { 0x0007, 0x000e }, + { 0x0007, 0x000f }, + { 0x0007, 0x0010 }, + { 0x0007, 0x0011 }, + { 0x0007, 0x0012 }, + { 0x0007, 0x0013 }, + { 0x0007, 0x0014 }, + { 0x0007, 0x0015 }, + { 0x0007, 0x0016 }, + { 0x0007, 0x0017 }, + { 0x0008, 0x000c }, + { 0x0008, 0x000d }, + { 0x0008, 0x000e }, + { 0x0008, 0x000f }, + { 0x0008, 0x0010 }, + { 0x0008, 0x0011 }, + { 0x0008, 0x0012 }, + { 0x0008, 0x0013 }, + { 0x0008, 0x0014 }, + { 0x0008, 0x0015 }, + { 0x0009, 0x0008 }, + { 0x0009, 0x0009 }, + { 0x0009, 0x000a }, + { 0x0009, 0x000b }, + { 0x0009, 0x000c }, + { 0x0009, 0x000d }, + { 0x0009, 0x000e }, + { 0x0009, 0x000f }, + { 0x0009, 0x0010 }, + { 0x0009, 0x0011 }, + { 0x0009, 0x0012 }, + { 0x0009, 0x0013 }, + { 0x0009, 0x0014 }, + { 0x0009, 0x0015 }, + { 0x000a, 0x0007 }, + { 0x0009, 0x0016 }, + { 0x0009, 0x0017 }, + { 0x000a, 0x0008 }, + { 0x000a, 0x0009 }, + { 0x000a, 0x000a }, + { 0x000a, 0x000b }, + { 0x000a, 0x000c }, + { 0x000a, 0x000d }, + { 0x000a, 0x000e }, + { 0x000b, 0x0008 }, + { 0x000b, 0x0009 }, + { 0x000b, 0x000a }, + { 0x000a, 0x000f }, + { 0x000b, 0x000b }, + { 0x000b, 0x000c }, + { 0x000b, 0x000d }, + { 0x000c, 0x0009 }, + { 0x000c, 0x000a }, + { 0x000c, 0x000b }, + { 0x000c, 0x000c }, + { 0x000c, 0x000d }, + { 0x000c, 0x000e }, + { 0x000c, 0x000f }, + { 0x000d, 0x0008 }, + { 0x000d, 0x0009 }, + { 0x000d, 0x000a }, + { 0x000d, 0x000b }, + { 0x000d, 0x000c }, + { 0x000d, 0x000d }, + { 0x000d, 0x000e }, + { 0x000d, 0x000f }, + { 0x000d, 0x0010 }, + { 0x000d, 0x0011 }, + { 0x000e, 0x0007 }, + { 0x000e, 0x0008 }, + { 0x000e, 0x0009 }, + { 0x000e, 0x000a }, + { 0x000e, 0x000b }, + { 0x000e, 0x000c }, + { 0x000e, 0x000d }, + { 0x000e, 0x000e }, + { 0x000e, 0x000f }, + { 0x000f, 0x0008 }, + { 0x000f, 0x0009 }, + { 0x000f, 0x000a }, + { 0x000f, 0x000b }, + { 0x000f, 0x000c }, + { 0x0010, 0x0009 }, + { 0x0010, 0x000a }, + { 0x000f, 0x000d }, + { 0x0010, 0x000b }, + { 0x0010, 0x000c }, + { 0x0010, 0x000d }, + { 0x0011, 0x000e }, + { 0x0011, 0x000f }, + { 0x0010, 0x000e }, + { 0x0011, 0x0010 }, + { 0x0011, 0x0011 }, + { 0x0012, 0x0014 }, + { 0x0014, 0x0000 }, + { 0x0010, 0x000f }, + { 0x0012, 0x0015 }, + { 0x0012, 0x0016 }, + { 0x0014, 0x0001 }, + { 0x0012, 0x0017 }, + { 0x0012, 0x0018 }, + { 0x0012, 0x0019 }, + { 0x0013, 0x0010 }, + { 0x0012, 0x001a }, + { 0x0014, 0x0002 }, + { 0x0012, 0x001b }, + { 0x0014, 0x0003 }, + { 0x0014, 0x0004 }, + { 0x0014, 0x0005 }, + { 0x0013, 0x0011 }, + { 0x0014, 0x0006 }, + { 0x0013, 0x0012 }, + { 0x0014, 0x0007 }, + { 0x0014, 0x0008 }, + { 0x0014, 0x0009 }, + { 0x0014, 0x000a }, + { 0x0014, 0x000b }, + { 0x0014, 0x000c }, + { 0x0014, 0x000d }, + { 0x0014, 0x000e }, + { 0x0013, 0x0013 }, + { 0x0014, 0x000f }, + { 0x0014, 0x0010 }, + { 0x0014, 0x0011 }, + { 0x0014, 0x0012 }, + { 0x0014, 0x0013 }, + { 0x0014, 0x0014 }, + { 0x0014, 0x0015 }, + { 0x0014, 0x0016 }, + { 0x0014, 0x0017 }, + { 0x0014, 0x0018 }, + { 0x0014, 0x0019 }, + { 0x0014, 0x001a }, + { 0x0014, 0x001b }, + { 0x0014, 0x001c }, + { 0x0014, 0x001d }, + { 0x0014, 0x001e }, + { 0x0014, 0x001f }, + { 0x0013, 0x0014 }, + { 0x0013, 0x0015 }, + { 0x0013, 0x0016 }, + { 0x0013, 0x0017 }, + { 0x0013, 0x0018 }, + { 0x0013, 0x0019 }, + { 0x0013, 0x001a }, + { 0x0013, 0x001b }, + { 0x0013, 0x001c }, + { 0x0013, 0x001d }, + { 0x0013, 0x001e }, + { 0x0013, 0x001f }, + { 0x0013, 0x0020 }, + { 0x0013, 0x0021 }, + { 0x0013, 0x0022 }, + { 0x0013, 0x0023 }, + { 0x0013, 0x0024 }, + { 0x0013, 0x0025 }, + { 0x0013, 0x0026 }, + { 0x0013, 0x0027 }, + + }; + +const uint16_t ( *c_apauiHuffEncTabels[2 * ALLOC_TABLE_SIZE] )[2] = + { + NULL, + c_aauiLCLDHuffEnc1, + c_aauiLCLDHuffEnc2, + c_aauiLCLDHuffEnc3, + c_aauiLCLDHuffEnc4, + c_aauiLCLDHuffEnc5, + c_aauiLCLDHuffEnc6, + c_aauiLCLDHuffEnc7, + c_aauiLCLDHuffEnc8, + c_aauiLCLDHuffEnc9, + c_aauiLCLDHuffEnc10, + c_aauiLCLDHuffEnc11, + c_aauiLCLDHuffEnc12, + c_aauiLCLDHuffEnc13, + c_aauiLCLDHuffEnc14, + c_aauiLCLDHuffEnc15, + c_aauiLCLDHuffEnc16, + c_aauiLCLDHuffEnc17, + c_aauiLCLDHuffEnc18, + c_aauiLCLDHuffEnc19, + c_aauiLCLDHuffEnc20, + c_aauiLCLDHuffEnc21, + c_aauiLCLDHuffEnc22, + c_aauiLCLDHuffEnc23, + c_aauiLCLDHuffEnc24, + c_aauiLCLDHuffEnc25, + c_aauiLCLDHuffEnc26, + c_aauiLCLDHuffEnc27, + c_aauiLCLDHuffEnc28, + c_aauiLCLDHuffEnc29, + c_aauiLCLDHuffEnc30, + c_aauiLCLDHuffEnc31, + NULL, + c_aauiLCLDHuffEnc33, + c_aauiLCLDHuffEnc34, + c_aauiLCLDHuffEnc35, + c_aauiLCLDHuffEnc36, + c_aauiLCLDHuffEnc37, + c_aauiLCLDHuffEnc38, + c_aauiLCLDHuffEnc39, + c_aauiLCLDHuffEnc40, + c_aauiLCLDHuffEnc41, + c_aauiLCLDHuffEnc42, + c_aauiLCLDHuffEnc43, + c_aauiLCLDHuffEnc44, + c_aauiLCLDHuffEnc45, + c_aauiLCLDHuffEnc46, + c_aauiLCLDHuffEnc47, + c_aauiLCLDHuffEnc48, + c_aauiLCLDHuffEnc49, + c_aauiLCLDHuffEnc50, + c_aauiLCLDHuffEnc51, + c_aauiLCLDHuffEnc52, + c_aauiLCLDHuffEnc53, + c_aauiLCLDHuffEnc54, + c_aauiLCLDHuffEnc55, + c_aauiLCLDHuffEnc56, + c_aauiLCLDHuffEnc57, + c_aauiLCLDHuffEnc58, + c_aauiLCLDHuffEnc59, + c_aauiLCLDHuffEnc60, + c_aauiLCLDHuffEnc61, + c_aauiLCLDHuffEnc62, + c_aauiLCLDHuffEnc63, + }; + +const uint32_t num_row_aauiLCLDHuff[2 * ALLOC_TABLE_SIZE] = { 0, 16, 16, 25, 36, 36, 49, 64, 81, 100, + 169, 196, 289, 324, 400, 576, 729, 729, 28, 29, + 32, 37, 39, 46, 55, 65, 77, 91, 109, 129, + 153, 181, 0, 16, 16, 25, 36, 36, 49, 64, 81, + 100, 169, 196, 289, 324, 400, 576, 729, 729, 28, + 29, 32, 37, 39, 46, 55, 65, 77, 91, 109, + 129, 153, 181 }; + +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, + 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_aiBandwidthAdjust48[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_aiAbsoluteThresh48[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, +}; + + +#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 + +const int32_t c_aaiSpreadFunction48[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, +}; +#endif diff --git a/lib_isar/isar_rom_lcld_tables.h b/lib_isar/isar_rom_lcld_tables.h new file mode 100644 index 000000000..974e57af0 --- /dev/null +++ b/lib_isar/isar_rom_lcld_tables.h @@ -0,0 +1,197 @@ +/****************************************************************************************************** + + (C) 2022-2023 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 ISAR_ROM_LCLD_TABLES_H +#define ISAR_ROM_LCLD_TABLES_H + +#include +#include "options.h" + +#ifdef SPLIT_REND_WITH_HEAD_ROT +#ifndef M_PI + +#define M_PI 3.14159265358979323846264338327950288f + +#endif + +#define LCLD_BLOCKS_PER_FRAME ( 16 ) +#define LCLD_MAX_BLOCKS_PER_FRAME ( 16 ) +#define LCLD_BANDS ( 60 ) +#define LCLD_PRED_WIN_LEN ( 16 ) +#define LCLD_MAX_NUM_PRED_SUBSETS ( 8 ) +#define MAX_BANDS ( 23 ) +#define MAX_BANDS_48 ( 23 ) +#define DEF_BANDS_48 ( 22 ) + +#define ENV_MIN ( -64 ) +#define ENV_MAX ( 64 ) + +#define ENV0_BITS ( 7 ) + +#define ENV_DELTA_MIN ( -32 ) +#define ENV_DELTA_MAX ( 31 ) + +#define ENV_RECONSTRUCT_TABLE_SIZE ( 129 ) + +#define ENV_RECONSTRUCT_TABLE_CENTER ( 64 ) + +#define MIN_ALLOC ( 0 ) +#define MAX_ALLOC ( 31 ) + +#define ALLOC_OFFSET_SCALE ( 8 ) + +#define ALLOC_OFFSET_BITS ( 8 ) + +#define MIN_ALLOC_OFFSET ( -128 ) +#define MAX_ALLOC_OFFSET ( 127 ) +#define READ_LENGTH ( 4 ) + +#define ALLOC_TABLE_SIZE ( 32 ) + +#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 PERCEPTUAL_MODEL_SLGAIN_SHIFT ( 8 ) + +#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 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 float c_afRMSEnvReconstructTable[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 int32_t c_aiHuffmanSize[ALLOC_TABLE_SIZE]; + + +#define LOG_ADD_TABLE_LENGTH ( 512 ) + +extern const int32_t c_aiBandwidths48[MAX_BANDS_48]; +extern const int32_t c_aiLogAddTable[LOG_ADD_TABLE_LENGTH]; +extern const int32_t c_aiBandwidthAdjust48[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]; + + +#define PRED_QUNAT_FILTER_MAG_BITS ( 3 ) +#define PRED_QUANT_FILTER_PHASE_BITS ( 5 ) +#define PRED_QUANT_FILTER_MAG_MIN ( 0 ) +#define PRED_QUANT_FILTER_MAG_MAX ( 7 ) +#define PRED_QUANT_FILTER_PHASE_MIN ( -16 ) +#define PRED_QUANT_FILTER_PHASE_MAX ( 15 ) + +extern const uint16_t c_aauiLCLDHuffEnc1[16][2]; +extern const uint16_t c_aauiLCLDHuffEnc2[16][2]; +extern const uint16_t c_aauiLCLDHuffEnc3[25][2]; +extern const uint16_t c_aauiLCLDHuffEnc4[36][2]; +extern const uint16_t c_aauiLCLDHuffEnc5[36][2]; +extern const uint16_t c_aauiLCLDHuffEnc6[49][2]; +extern const uint16_t c_aauiLCLDHuffEnc7[64][2]; +extern const uint16_t c_aauiLCLDHuffEnc8[81][2]; +extern const uint16_t c_aauiLCLDHuffEnc9[100][2]; +extern const uint16_t c_aauiLCLDHuffEnc10[169][2]; +extern const uint16_t c_aauiLCLDHuffEnc11[196][2]; +extern const uint16_t c_aauiLCLDHuffEnc12[289][2]; +extern const uint16_t c_aauiLCLDHuffEnc13[324][2]; +extern const uint16_t c_aauiLCLDHuffEnc14[400][2]; +extern const uint16_t c_aauiLCLDHuffEnc15[576][2]; +extern const uint16_t c_aauiLCLDHuffEnc16[729][2]; +extern const uint16_t c_aauiLCLDHuffEnc17[729][2]; +extern const uint16_t c_aauiLCLDHuffEnc18[28][2]; +extern const uint16_t c_aauiLCLDHuffEnc19[29][2]; +extern const uint16_t c_aauiLCLDHuffEnc20[32][2]; +extern const uint16_t c_aauiLCLDHuffEnc21[37][2]; +extern const uint16_t c_aauiLCLDHuffEnc22[39][2]; +extern const uint16_t c_aauiLCLDHuffEnc23[46][2]; +extern const uint16_t c_aauiLCLDHuffEnc24[55][2]; +extern const uint16_t c_aauiLCLDHuffEnc25[65][2]; +extern const uint16_t c_aauiLCLDHuffEnc26[77][2]; +extern const uint16_t c_aauiLCLDHuffEnc27[91][2]; +extern const uint16_t c_aauiLCLDHuffEnc28[109][2]; +extern const uint16_t c_aauiLCLDHuffEnc29[129][2]; +extern const uint16_t c_aauiLCLDHuffEnc30[153][2]; +extern const uint16_t c_aauiLCLDHuffEnc31[181][2]; +extern const uint16_t c_aauiLCLDHuffEnc33[16][2]; +extern const uint16_t c_aauiLCLDHuffEnc34[16][2]; +extern const uint16_t c_aauiLCLDHuffEnc35[25][2]; +extern const uint16_t c_aauiLCLDHuffEnc36[36][2]; +extern const uint16_t c_aauiLCLDHuffEnc37[36][2]; +extern const uint16_t c_aauiLCLDHuffEnc38[49][2]; +extern const uint16_t c_aauiLCLDHuffEnc39[64][2]; +extern const uint16_t c_aauiLCLDHuffEnc40[81][2]; +extern const uint16_t c_aauiLCLDHuffEnc41[100][2]; +extern const uint16_t c_aauiLCLDHuffEnc42[169][2]; +extern const uint16_t c_aauiLCLDHuffEnc43[196][2]; +extern const uint16_t c_aauiLCLDHuffEnc44[289][2]; +extern const uint16_t c_aauiLCLDHuffEnc45[324][2]; +extern const uint16_t c_aauiLCLDHuffEnc46[400][2]; +extern const uint16_t c_aauiLCLDHuffEnc47[576][2]; +extern const uint16_t c_aauiLCLDHuffEnc48[729][2]; +extern const uint16_t c_aauiLCLDHuffEnc49[729][2]; +extern const uint16_t c_aauiLCLDHuffEnc50[28][2]; +extern const uint16_t c_aauiLCLDHuffEnc51[29][2]; +extern const uint16_t c_aauiLCLDHuffEnc52[32][2]; +extern const uint16_t c_aauiLCLDHuffEnc53[37][2]; +extern const uint16_t c_aauiLCLDHuffEnc54[39][2]; +extern const uint16_t c_aauiLCLDHuffEnc55[46][2]; +extern const uint16_t c_aauiLCLDHuffEnc56[55][2]; +extern const uint16_t c_aauiLCLDHuffEnc57[65][2]; +extern const uint16_t c_aauiLCLDHuffEnc58[77][2]; +extern const uint16_t c_aauiLCLDHuffEnc59[91][2]; +extern const uint16_t c_aauiLCLDHuffEnc60[109][2]; +extern const uint16_t c_aauiLCLDHuffEnc61[129][2]; +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]; +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_ */ diff --git a/lib_isar/isar_rom_post_rend.c b/lib_isar/isar_rom_post_rend.c new file mode 100644 index 000000000..31c8429d9 --- /dev/null +++ b/lib_isar/isar_rom_post_rend.c @@ -0,0 +1,182 @@ +/****************************************************************************************************** + + (C) 2022-2023 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. + +*******************************************************************************************************/ + +#include +#include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif +#include "isar_cnst.h" +#include "wmc_auto.h" + +/* clang-format off */ + + +#ifdef SPLIT_REND_WITH_HEAD_ROT +/*----------------------------------------------------------------------* + * Binuaral split rendering ROM tables + *-----------------------------------------------------------------------*/ + +/* 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 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] = +{ + {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] = +{ + { 0, 1, 0 },{ 1, 2, 2 },{ 2, 3, 6 },{ 3, 4, 14 }, + { 4, 5, 30 },{ 5, 6, 62 },{ 6, 7, 126 },{ 7, 8, 254 }, + { 8, 9, 510 },{ 9, 10, 1022 },{ 10, 11, 2046 },{ 11, 12, 4094 }, + { 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] = +{ + { 0, 1, 0 },{ 1, 2, 2 },{ 2, 3, 6 },{ 3, 4, 14 }, + { 4, 5, 30 },{ 5, 6, 62 },{ 6, 7, 126 },{ 7, 8, 254 }, + { 8, 9, 510 },{ 9, 10, 1022 },{ 10, 11, 2046 },{ 11, 12, 4094 }, + { 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] = +{ + {-31,11,2040}, + {-30,11,2041}, + {-29,11,2042}, + {-28,11,2043}, + {-27,10,1012}, + {-26,10,1013}, + {-25,10,1014}, + {-24,10,1015}, + {-23,9,498}, + {-22,9,499}, + {-21,9,500}, + {-20,9,501}, + {-19,8,242}, + {-18,8,243}, + {-17,8,244}, + {-16,8,245}, + {-15,7,112}, + {-14,7,113}, + {-13,7,114}, + {-12,7,115}, + {-11,6,48}, + {-10,6,49}, + {-9,6,50}, + {-8,6,51}, + {-7,5,16}, + {-6,5,17}, + {-5,5,18}, + {-4,5,19}, + {-3,4,2}, + {-2,4,3}, + {-1,4,4}, + {0,3,0}, + {1,4,5}, + {2,4,6}, + {3,4,7}, + {4,5,20}, + {5,5,21}, + {6,5,22}, + {7,5,23}, + {8,6,52}, + {9,6,53}, + {10,6,54}, + {11,6,55}, + {12,7,116}, + {13,7,117}, + {14,7,118}, + {15,7,119}, + {16,7,120}, + {17,8,246}, + {18,8,247}, + {19,8,248}, + {20,9,502}, + {21,9,503}, + {22,9,504}, + {23,9,505}, + {24,10,1016}, + {25,10,1017}, + {26,10,1018}, + {27,10,1019}, + {28,11,2044}, + {29,11,2045}, + {30,11,2046}, + {31,11,2047}, +}; + +const int32_t isar_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}, + {-7,6,56},{-6,6,57},{-5,5,24},{-4,5,25},{-3,4,8}, + {-2,4,9},{-1,3,2},{0,2,0},{1,3,3}, + {2,4,10},{3,4,11},{4,5,26},{5,5,27}, + {6,6,58},{7,6,59},{8,7,122},{9,7,123}, + {10,7,124},{11,8,252},{12,9,508},{13,9,509}, + {14,10,1022},{15,10,1023}, +}; + +const int32_t isar_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}, + {-7,6,56},{-6,6,57},{-5,5,24},{-4,5,25},{-3,4,8}, + {-2,4,9},{-1,3,2},{0,2,0},{1,3,3}, + {2,4,10},{3,4,11},{4,5,26},{5,5,27}, + {6,6,58},{7,6,59},{8,7,122},{9,7,123}, + {10,7,124},{11,8,252},{12,9,508},{13,9,509}, +{14,10,1022},{15,10,1023}, +}; + +#endif + + +/* clang-format on */ diff --git a/lib_isar/isar_rom_post_rend.h b/lib_isar/isar_rom_post_rend.h new file mode 100644 index 000000000..b046263b3 --- /dev/null +++ b/lib_isar/isar_rom_post_rend.h @@ -0,0 +1,69 @@ +/****************************************************************************************************** + + (C) 2022-2023 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 ISAR_ROM_POST_REND_H +#define ISAR_ROM_POST_REND_H + +#include +#include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif +#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 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]; + +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]; +#endif + +#endif diff --git a/lib_isar/isar_splitRend_lcld_dec.c b/lib_isar/isar_splitRend_lcld_dec.c new file mode 100644 index 000000000..d34cc8482 --- /dev/null +++ b/lib_isar/isar_splitRend_lcld_dec.c @@ -0,0 +1,258 @@ +/****************************************************************************************************** + + (C) 2022-2023 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. + +*******************************************************************************************************/ + +#include +#include "options.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT +#include "isar_prot.h" +#include "ivas_prot.h" +#include "prot.h" +#ifdef DEBUGGING +#include "debug.h" +#endif +#include "wmc_auto.h" + + +/*------------------------------------------------------------------------- + * Function isar_splitBinLCLDDecOpen() + * + * + *------------------------------------------------------------------------*/ + +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 ) +{ + 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 ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD decoder Module \n" ) ); + } + + splitBinLCLDDec->pLcld_dec = NULL; /* place holder for CLDFB decoder handle */ + + splitBinLCLDDec->iChannels = iChannels; + + if ( ( error = CreateLCLDDecoder( &splitBinLCLDDec->psLCLDDecoder, iSampleRate, iChannels, iNumBlocks, 0 ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( ( splitBinLCLDDec->pppfDecLCLDReal = (float ***) malloc( iChannels * sizeof( float ** ) ) ) == 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 ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD decoder Module \n" ) ); + } + + for ( n = 0; n < splitBinLCLDDec->iChannels; n++ ) + { + if ( ( splitBinLCLDDec->pppfDecLCLDReal[n] = (float **) malloc( CLDFB_NO_COL_MAX * sizeof( float * ) ) ) == 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 ) + { + 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"; + if ( ( splitBinLCLDDec->cldfbOut = fopen( cldfbFilename, "wb" ) ) == NULL ) + { + fprintf( stderr, "Error: CLDFB bitstream file %s could not be opened\n\n", cldfbFilename ); + exit( -1 ); + } + int16_t num_bands = CLDFB_NO_CHANNELS_MAX; + fwrite( &iChannels, sizeof( int16_t ), 1, splitBinLCLDDec->cldfbOut ); + fwrite( &num_bands, sizeof( int16_t ), 1, splitBinLCLDDec->cldfbOut ); +#endif + + if ( ( error = isar_splitBinRendPLCOpen( &splitBinLCLDDec->hSplitRendPLC, GetNumSubSets( splitBinLCLDDec->psLCLDDecoder ) ) ) != IVAS_ERR_OK ) + { + return error; + } + splitBinLCLDDec->iNumBlocks = iNumBlocks; + splitBinLCLDDec->iNumIterations = iNumIterations; + + *hSplitBinLCLDDec = splitBinLCLDDec; + + return IVAS_ERR_OK; +} + + +/*------------------------------------------------------------------------- + * Function isar_splitBinLCLDDecClose() + * + * + *------------------------------------------------------------------------*/ + +void isar_splitBinLCLDDecClose( + ISAR_BIN_HR_SPLIT_LCLD_DEC_HANDLE *hSplitBinLCLDDec ) +{ + int16_t n; + + if ( ( *hSplitBinLCLDDec ) != NULL ) + { + if ( ( *hSplitBinLCLDDec )->psLCLDDecoder != NULL ) + { + DeleteLCLDDecoder( ( *hSplitBinLCLDDec )->psLCLDDecoder ); + } + + for ( n = 0; n < ( *hSplitBinLCLDDec )->iChannels; n++ ) + { + free( ( *hSplitBinLCLDDec )->pppfDecLCLDReal[n] ); + free( ( *hSplitBinLCLDDec )->pppfDecLCLDImag[n] ); + } + free( ( *hSplitBinLCLDDec )->pppfDecLCLDReal ); + free( ( *hSplitBinLCLDDec )->pppfDecLCLDImag ); + +#ifdef CLDFB_DEBUG + if ( ( *hSplitBinLCLDDec )->cldfbOut != NULL ) + { + fclose( ( *hSplitBinLCLDDec )->cldfbOut ); + } +#endif + isar_splitBinRendPLCClose( &( *hSplitBinLCLDDec )->hSplitRendPLC ); + + free( *hSplitBinLCLDDec ); + *hSplitBinLCLDDec = NULL; + } + + 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 ) +{ + int16_t k, n; + int16_t itr; + push_wmops( "isar_splitBinLCLDDecProcess" ); + + assert( hSplitBinLCLDDec != NULL ); + assert( Cldfb_Out_Real != NULL ); + assert( Cldfb_Out_Imag != NULL ); + assert( pBits != NULL ); + +#ifdef CLDFB_DEBUG + printf( "Bytes read = %d\n", iBytesWritten ); +#endif + if ( !bfi ) + { + for ( itr = 0; itr < hSplitBinLCLDDec->iNumIterations; itr++ ) + { + /* Initialized with zeros....... */ + for ( n = 0; n < hSplitBinLCLDDec->iChannels; n++ ) + { + 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 ); + } + } + + DecodeLCLDFrame( hSplitBinLCLDDec->psLCLDDecoder, pBits, hSplitBinLCLDDec->pppfDecLCLDReal, hSplitBinLCLDDec->pppfDecLCLDImag ); + +#ifdef CLDFB_DEBUG + printf( "Frame Decoded = %d\n", ++hSplitBinLCLDDec->numFrame ); + int16_t writeByte = 0; + for ( k = 0; k < CLDFB_NO_COL_MAX; k++ ) + { + for ( int16_t b = 0; b < CLDFB_NO_CHANNELS_MAX; b++ ) + { + for ( n = 0; n < hSplitBinLCLDDec->iChannels; n++ ) + { + writeByte = fwrite( &hSplitBinLCLDDec->pppfDecLCLDReal[n][k][b], sizeof( float ), 1, hSplitBinLCLDDec->cldfbOut ); + if ( writeByte != 1 ) + exit( -1 ); + writeByte = fwrite( &hSplitBinLCLDDec->pppfDecLCLDImag[n][k][b], sizeof( float ), 1, hSplitBinLCLDDec->cldfbOut ); + if ( writeByte != 1 ) + exit( -1 ); + } + } + } +#endif + if ( AnyDecodingFailed( hSplitBinLCLDDec->psLCLDDecoder ) ) + { + /* continue concealing */ + isar_splitBinRendPLC( hSplitBinLCLDDec->hSplitRendPLC, Cldfb_Out_Real, Cldfb_Out_Imag, (int16_t) hSplitBinLCLDDec->iChannels, hSplitBinLCLDDec->iNumBlocks, + hSplitBinLCLDDec->iNumIterations, GetDecodingFailedStatus( hSplitBinLCLDDec->psLCLDDecoder ) ); + } + if ( AnyDecodingFailedPrev( hSplitBinLCLDDec->psLCLDDecoder ) ) + { + /* 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 ) ); + } + } + } + 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 ) ); + } + + /* save PLC state */ + isar_splitBinRendPLCsaveState( hSplitBinLCLDDec->hSplitRendPLC, Cldfb_Out_Real, Cldfb_Out_Imag, (int16_t) hSplitBinLCLDDec->iChannels, hSplitBinLCLDDec->iNumBlocks, hSplitBinLCLDDec->iNumIterations ); + + pop_wmops(); + + return; +} +#endif diff --git a/lib_isar/isar_splitRend_lcld_enc.c b/lib_isar/isar_splitRend_lcld_enc.c new file mode 100644 index 000000000..7dc10787b --- /dev/null +++ b/lib_isar/isar_splitRend_lcld_enc.c @@ -0,0 +1,242 @@ +/****************************************************************************************************** + + (C) 2022-2023 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. + +*******************************************************************************************************/ + +#include +#include "options.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT +#include "isar_prot.h" +#include "ivas_prot.h" +#ifdef DEBUGGING +#include "debug.h" +#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 ) +{ + 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 ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + + 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 ) + { + return error; + } + + if ( ( splitBinLCLDEnc->pppfLCLDReal = (float ***) malloc( iChannels * sizeof( float ** ) ) ) == 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 ) + { + 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++ ) + { + if ( ( splitBinLCLDEnc->pppfLCLDReal[n] = (float **) malloc( CLDFB_NO_COL_MAX * sizeof( float * ) ) ) == 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 ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); + } + } + + splitBinLCLDEnc->iNumIterations = iNumIterations; + splitBinLCLDEnc->iNumBlocks = iNumBlocks; + +#ifdef CLDFB_DEBUG + splitBinLCLDEnc->numFrame = 0; + char cldfbFilename[50] = "cldfb_in_ref.qmf"; + if ( ( splitBinLCLDEnc->cldfbIn = fopen( cldfbFilename, "rb" ) ) == NULL ) + { + fprintf( stderr, "Error: CLDFB bitstream file %s could not be opened\n\n", cldfbFilename ); + exit( -1 ); + } + int16_t chan, band; + fread( &chan, sizeof( int16_t ), 1, splitBinLCLDEnc->cldfbIn ); + fread( &band, sizeof( int16_t ), 1, splitBinLCLDEnc->cldfbIn ); +#endif + + *hSplitBinLCLDEnc = splitBinLCLDEnc; + + return IVAS_ERR_OK; +} + + +/*------------------------------------------------------------------------- + * Function isar_splitBinLCLDEncClose() + * + * + *------------------------------------------------------------------------*/ + +void isar_splitBinLCLDEncClose( + ISAR_BIN_HR_SPLIT_LCLD_ENC_HANDLE *hSplitBinLCLDEnc ) +{ + if ( ( *hSplitBinLCLDEnc ) != NULL ) + { + DeleteLCLDEncoder( ( *hSplitBinLCLDEnc )->psLCLDEncoder ); + + for ( int16_t n = 0; n < ( *hSplitBinLCLDEnc )->iChannels; n++ ) + { + free( ( *hSplitBinLCLDEnc )->pppfLCLDReal[n] ); + free( ( *hSplitBinLCLDEnc )->pppfLCLDImag[n] ); + } + free( ( *hSplitBinLCLDEnc )->pppfLCLDReal ); + free( ( *hSplitBinLCLDEnc )->pppfLCLDImag ); + +#ifdef CLDFB_DEBUG + if ( ( *hSplitBinLCLDEnc )->cldfbIn != NULL ) + { + fclose( ( *hSplitBinLCLDEnc )->cldfbIn ); + } +#endif + + free( *hSplitBinLCLDEnc ); + *hSplitBinLCLDEnc = NULL; + } + + 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 ) +{ + int32_t 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( pBits != NULL ); + + available_bits_local = available_bits; + /* A conversion is needed for the 3d pointer interface here ........ */ + 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++ ) + { + for ( int32_t 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]; + } + } + +#ifdef CLDFB_DEBUG + int16_t readByte = 0; + for ( int16_t k = 0; k < hSplitBinLCLDEnc->iNumBlocks; k++ ) + { + for ( int16_t b = 0; b < CLDFB_NO_CHANNELS_MAX; b++ ) + { + for ( int16_t n = 0; n < hSplitBinLCLDEnc->iChannels; n++ ) + { + readByte = fread( &hSplitBinLCLDEnc->pppfLCLDReal[n][k][b], sizeof( float ), 1, hSplitBinLCLDEnc->cldfbIn ); + if ( readByte != 1 ) + break; + readByte = fread( &hSplitBinLCLDEnc->pppfLCLDReal[n][k][b], sizeof( float ), 1, hSplitBinLCLDEnc->cldfbIn ); + } + } + } + + if ( readByte == 1 ) + { + printf( "Frame Read = %d\n", ++hSplitBinLCLDEnc->numFrame ); + } + else + { + printf( "Writing zeroes...\n" ); + for ( int16_T k = 0; k < hSplitBinLCLDEnc->iNumBlocks; k++ ) + { + for ( int16_t b = 0; b < CLDFB_NO_CHANNELS_MAX; b++ ) + { + for ( int16_t n = 0; n < hSplitBinLCLDEnc->iChannels; n++ ) + { + hSplitBinLCLDEnc->pppfLCLDReal[n][k][b] = 0.f; + hSplitBinLCLDEnc->pppfLCLDImag[n][k][b] = 0.f; + } + } + } + } +#endif + EncodeLCLDFrame( hSplitBinLCLDEnc->psLCLDEncoder, hSplitBinLCLDEnc->pppfLCLDReal, hSplitBinLCLDEnc->pppfLCLDImag, &iBitsWritten, available_bits_itr, pBits ); + + available_bits_local -= iBitsWritten; +#ifdef DEBUGGING + assert( available_bits_local >= 0 ); +#endif + +#ifdef CLDFB_DEBUG + printf( "Bits written = %d\n", iBitsWritten ); +#endif + } + pop_wmops(); + + return; +} +#endif diff --git a/lib_isar/isar_splitRendererPLC.c b/lib_isar/isar_splitRendererPLC.c new file mode 100644 index 000000000..515d67188 --- /dev/null +++ b/lib_isar/isar_splitRendererPLC.c @@ -0,0 +1,543 @@ +/****************************************************************************************************** + + (C) 2022-2023 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. + +*******************************************************************************************************/ + +#include +#include "options.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT +#include +#include "ivas_prot.h" +#include "prot.h" +#include "ivas_cnst.h" +#include "isar_prot.h" +#ifdef DEBUGGING +#include "debug.h" +#endif +#include "wmc_auto.h" + + +/*------------------------------------------------------------------------- + * Local constants + *------------------------------------------------------------------------*/ + +#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 STH_THRESH ( 2.f / 3.f * PI2 / 12 ) + + +/*------------------------------------------------------------------------- + * Function adaptive_polar_ext_plc() + * + * + *------------------------------------------------------------------------*/ + +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; + + /* reset of accumulators */ + ph_adj = 0.0f; + drho = 0.0f; + srho = 0.0f; + dth = 0.0f; + sth = 0.0f; + + /* calculate per-sample phase and magnitude evolution in preceding frame */ + 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 ) + { + /* zero encountered */ + break; + } + uth[k] = atan2f( prev_imag[k], prev_real[k] ); + + /* phase unwrap */ + if ( k == 0 ) + { + uthu[0] = uth[0]; + } + else + { + /* phase unwrap */ + ph_diff = uth[k] - uth[k - 1]; + uthu[k] = uth[k]; + if ( fabsf( ph_diff ) >= PI2 / 2 ) + { + ph_adj_t = ph_diff / PI2; + if ( fabsf( ph_adj_t - truncf( ph_adj_t ) ) == 0.5f ) + { + ph_adj_t = truncf( ph_adj_t ); + } + ph_adj = -PI2 * roundf( ph_adj_t ) + ph_adj; + } + uthu[k] += ph_adj; + /* unwrapped phase in uthu */ + + /* mean and stdev of per-sample magnitude ratios */ + quot = urh[k] / urh[k - 1]; + drho += quot; + srho += SQR( quot ); + /* 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 ) + { + /* mean and stdev of per-sample magnitude ratios */ + drho *= 1.0f / ( iNumCols - 1 ); + temp = srho - ( iNumCols - 1 ) * SQR( drho ); + if ( temp > 0 ) + { + srho = sqrtf( temp * ( 1.0f / ( iNumCols - 2 ) ) ); + } + else + { + srho = 0.0f; + } + + /* mean and stdev of per-sample phase differences */ + dth *= 1.0f / ( iNumCols - 1 ); + temp = sth - ( iNumCols - 1 ) * SQR( dth ); + if ( temp > 0 ) + { + sth = sqrtf( temp * ( 1.0f / ( iNumCols - 2 ) ) ); + } + else + { + sth = 0.0f; + } + + /* do phase extension only if the std deviations are small */ + if ( ( srho < SRHO_THRESH ) || ( sth < STH_THRESH ) ) + { + /* 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; + start_real = prev_real[iNumCols - 1]; + start_imag = prev_imag[iNumCols - 1]; + for ( j = 1; j < START_VAL_AVG_LEN; j++ ) + { + 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; + } + start_real *= 1.0f / START_VAL_AVG_LEN; + start_imag *= 1.0f / START_VAL_AVG_LEN; + + /* 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] ); + + /* 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 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++ ) + { + /* 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] ); + + /* 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]; + } + + /* 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] ); + + abs_temp = sqrtf( SQR( rat_real ) + SQR( rat_imag ) ); + abs2inv = min( 1, drho ) / max( EPSILON, abs_temp ); + + 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]; + } + + + /* apply crossfade */ + 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]; + } + } + else + { + /* 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[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]; + } + if ( Ruu_real[0] > EPSILON ) + { + /* prediction coefficient */ + fac_real = Ruu_real[1] / Ruu_real[0]; + fac_imag = Ruu_imag[1] / Ruu_real[0]; + } + else + { + fac_real = 0; + fac_imag = 0; + } + + /* 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++ ) + { + 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; + } + + /* 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++ ) + { + 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; + } + } + } + else + { + for ( j = 0; j < iNumCols; j++ ) + { + rec_real[j] = prev_real[j]; + rec_imag[j] = prev_imag[j]; + } + for ( j = 0; j < CLDFB_PLC_XF; j++ ) + { + xf_bet[j] = 1; + rec_real[j + iNumCols] = 0; + rec_imag[j + iNumCols] = 0; + } + } + + return; +} + + +/*------------------------------------------------------------------------- + * Function isar_splitBinRendPLCOpen() + * + * + *------------------------------------------------------------------------*/ + +ivas_error isar_splitBinRendPLCOpen( + ISAR_SPLIT_REND_PLC_HANDLE *phSplitRendPLC, + const int16_t 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 ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for bin split renderer PLC Module \n" ) ); + } + + 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 ); + *phSplitRendPLC = hSplitRendPLC; + + return error; +} + + +/*------------------------------------------------------------------------- + * Function isar_splitBinRendPLCClose() + * + * + *------------------------------------------------------------------------*/ + +void isar_splitBinRendPLCClose( + ISAR_SPLIT_REND_PLC_HANDLE *phSplitRendPLC ) +{ + if ( ( *phSplitRendPLC ) != NULL ) + { + free( ( *phSplitRendPLC ) ); + ( *phSplitRendPLC ) = NULL; + } + + return; +} + + +/*------------------------------------------------------------------------- + * Function isar_splitBinRendPLCsaveState() + * + * + *------------------------------------------------------------------------*/ + +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 ) +{ + int16_t k, n; + + /* Save Cldfb frame */ + for ( k = 0; k < ( iNumBlocks * iNumIterations ); k++ ) + { + 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 ); + } + } + + return; +} + + +/*------------------------------------------------------------------------- + * Function isar_splitBinRendPLC_xf() + * + * Cross-fade of preceding bad frame into good frame + *------------------------------------------------------------------------*/ + +void isar_splitBinRendPLC_xf( + 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 ) +{ + int16_t n, i, k; + + /* Indicate that next transition will be from a good frame */ + hSplitRendPLC->prev_bfi = 0; + + /* Reset bf conter */ + hSplitRendPLC->bf_count = 0; + + + /* Do the cross fade */ + for ( n = 0; n < num_chs; n++ ) + { + for ( i = 0; i < CLDFB_NO_CHANNELS_MAX; i++ ) + { + int16_t iSubSet = i % hSplitRendPLC->iNumSubSets; + if ( ppiDecodingFailedPrev[n][iSubSet] == 1 && ppiDecodingFailed[n][iSubSet] == 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]; + } + } + } + } + + return; +} + + +/*------------------------------------------------------------------------- + * Function isar_splitBinRendPLC() + * + * 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 ) +{ + 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; + + iNumCols = iNumBlocks * iNumIterations; + + /* Indicate that next transition will be from a bad frame */ + hSplitRendPLC->prev_bfi = 1; + + for ( i = 0; i < CLDFB_PLC_XF; i++ ) + { + xf_alp[i] = 1.0f - ( i + 1.0f ) / ( CLDFB_PLC_XF + 1.0f ); + } + + for ( n = 0; n < num_chs; n++ ) + { + for ( i = 0; i < CLDFB_NO_CHANNELS_MAX; i++ ) + { + int32_t 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]; + } + + adaptive_polar_ext_plc( prev_real, prev_imag, rec_real, rec_imag, + xf_alp, hSplitRendPLC->CldfbPLC_state.xf_bet[n][i], + iNumCols ); + + 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]; + + 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]; + } + } + + 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]; + } + } + } + + + /* 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; + + if ( hSplitRendPLC->bf_count++ >= fade_start_cntr ) + { + if ( 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 ); + + for ( n = 0; n < num_chs; n++ ) + { + 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 ); + } + } + } + else + { + for ( n = 0; n < num_chs; n++ ) + { + 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 ); + } + } + hSplitRendPLC->bf_count = mute_cntr; + } + } + + return; +} + +#endif diff --git a/lib_isar/isar_splitRendererPost.c b/lib_isar/isar_splitRendererPost.c new file mode 100644 index 000000000..c4d7a20d3 --- /dev/null +++ b/lib_isar/isar_splitRendererPost.c @@ -0,0 +1,1910 @@ +/****************************************************************************************************** + + (C) 2022-2023 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. + +*******************************************************************************************************/ + +#include +#include "options.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT +#include +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG +#include +#endif +#include "ivas_prot.h" +#include "prot.h" +#include "isar_rom_post_rend.h" +#include "isar_prot.h" +#ifdef DEBUGGING +#include "debug.h" +#endif +#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 ); + + +/*------------------------------------------------------------------------- + * isar_splitBinPostRendOpen() + * + * + *------------------------------------------------------------------------*/ + +ivas_error isar_splitBinPostRendOpen( + ISAR_BIN_HR_SPLIT_POST_REND_HANDLE *hBinHrSplitPostRend, + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + const int32_t output_Fs ) +{ + ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinRend; + ivas_error error; + int16_t ch; + + 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++ ) + { + hBinRend->cldfbSyn[ch] = NULL; + hBinRend->cldfbAna[ch] = NULL; + } +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + for ( int16_t i = 0; i < MAX_HEAD_ROT_POSES; i++ ) + { + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + hBinRend->cldfbSynReconsBinDec[i][ch] = NULL; + } + } +#endif + + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + if ( ( error = openCldfb( &( 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 ) + { + return error; + } + } + +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + for ( int16_t i = 0; i < MAX_HEAD_ROT_POSES; i++ ) + { + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + if ( ( error = openCldfb( &( hBinRend->cldfbSynReconsBinDec[i][ch] ), CLDFB_SYNTHESIS, output_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) + { + return error; + } + } + } +#endif + hBinRend->cf_flag = 0; + set_fix_rotation_mat( hBinRend->fix_pos_rot_mat, pMultiBinPoseData ); + set_pose_types( hBinRend->pose_type, pMultiBinPoseData ); + isar_split_rend_init_huff_cfg( &hBinRend->huff_cfg ); + *hBinHrSplitPostRend = hBinRend; + + return IVAS_ERR_OK; +} + + +/*------------------------------------------------------------------------- + * isar_splitBinPostRendClose() + * + * + *------------------------------------------------------------------------*/ + +void isar_splitBinPostRendClose( + ISAR_BIN_HR_SPLIT_POST_REND_HANDLE *hBinHrSplitPostRend ) +{ + int16_t ch; + + if ( ( *hBinHrSplitPostRend ) != NULL ) + { + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + if ( ( *hBinHrSplitPostRend )->cldfbSyn[ch] != NULL ) + { + deleteCldfb( &( ( *hBinHrSplitPostRend )->cldfbSyn[ch] ) ); + ( *hBinHrSplitPostRend )->cldfbSyn[ch] = NULL; + } + if ( ( *hBinHrSplitPostRend )->cldfbAna[ch] != NULL ) + { + deleteCldfb( &( ( *hBinHrSplitPostRend )->cldfbAna[ch] ) ); + ( *hBinHrSplitPostRend )->cldfbAna[ch] = NULL; + } + } +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + for ( int16_t i = 0; i < MAX_HEAD_ROT_POSES; i++ ) + { + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + if ( ( *hBinHrSplitPostRend )->cldfbSynReconsBinDec[i][ch] != NULL ) + { + deleteCldfb( &( ( *hBinHrSplitPostRend )->cldfbSynReconsBinDec[i][ch] ) ); + ( *hBinHrSplitPostRend )->cldfbSynReconsBinDec[i][ch] = NULL; + } + } + } +#endif + + free( ( *hBinHrSplitPostRend ) ); + ( *hBinHrSplitPostRend ) = NULL; + } + + return; +} + + +/*-----------------------------------------------------------------------------------------* + * Function isar_split_rend_huffman_decode_opt() + * + * + *-----------------------------------------------------------------------------------------*/ + +static int16_t isar_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 ) +{ + int32_t i, ind, code, num_bits, code_b, num_bits_read; + const int32_t *codebook; + + codebook = huff_cfg->codebook; + num_bits_read = 0; + ind = huff_cfg->codebook[0] - 1; + code = 0; + for ( i = 0; i < huff_cfg->sym_len; i++ ) + { + codebook = codebook + idx_trav_list[i] * 3; + num_bits = codebook[1]; + code_b = codebook[2]; + num_bits_read = num_bits - num_bits_read; + code = code << num_bits_read; + if ( num_bits_read > 0 ) + { + code |= ISAR_SPLIT_REND_BITStream_read_int32( pBits, num_bits_read ); + } + + if ( code == code_b ) + { + ind = codebook[0]; + break; + } + + num_bits_read = num_bits; + codebook = huff_cfg->codebook; + } + +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + assert( ind >= huff_cfg->codebook[0] ); +#endif + return (int16_t) ind; +} + +/*-----------------------------------------------------------------------------------------* + * Function isar_split_rend_unquant_md() + * + * + *-----------------------------------------------------------------------------------------*/ + +static void isar_split_rend_unquant_md( + 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 ) +{ + int16_t ch1, ch2; + int16_t gd_idx_min; + + if ( pose_type == PRED_ONLY || pose_type == PRED_ROLL_ONLY ) + { + float quantstep; + + quantstep = pred_quant_step; +#ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + 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]; + } + } +#endif + if ( real_only ) + { +#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + 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 ); + } + } +#endif + + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + hMd->pred_mat_im[ch1][ch2] = 0.0f; + } + } + } + else + { +#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + 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]; + } + } +#endif + + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + hMd->pred_mat_im[ch1][ch2] = hMd->pred_mat_im_idx[ch1][ch2] * quantstep; + } + } + } + } + else if ( 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; + } + else if ( 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; + + hMd->gd2_idx += gd_idx_min; + hMd->gd2 = hMd->gd2_idx * ISAR_SPLIT_REND_PITCH_G_Q_STEP; + } + else + { + hMd->gd = 0.0f; + } + + return; +} + + +/*-----------------------------------------------------------------------------------------* + * Function isar_splitBinPostRendMdBase2Dec() + * + * + *-----------------------------------------------------------------------------------------*/ + +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 ) +{ + 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; + 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 ) + { + pred_cb_idx = 1; + } + else + { + pred_cb_idx = 0; + } + 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]; + pred_code_len = pHuff_cfg->pred_base2_code_len[pred_cb_idx]; + pred_roll_code_len = pHuff_cfg->pred_roll_base2_code_len; + gd_code_len = pHuff_cfg->gd_base2_code_len; + p_gd_code_len = pHuff_cfg->p_gd_base2_code_len; + + for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) + { + for ( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses - 1; pos_idx++ ) + { + if ( hBinHrSplitPostRend->pose_type[pos_idx] == ANY_YAW ) + { +#ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + 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 ( 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; + } + } + } + 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 ( 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; + } + } + } +#else + 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 ( 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; + } + } + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + 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; + } + } + } + + for ( ; b < pred_real_bands_yaw; b++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + 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; + } + hMd->pred_mat_re_idx[0][1] = 0; + hMd->pred_mat_re_idx[1][0] = 0; + } +#endif + 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; + } + } + else if ( hBinHrSplitPostRend->pose_type[pos_idx] == PITCH_ONLY ) + { + 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; + } + } + else + { +#ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + 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 ( 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; + } + } + } + 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 ( 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; + } + } + } +#else + 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 ( 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; + } + } + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + 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; + } + } + } + + for ( ; b < pred_real_bands_roll; b++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + 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; + } + hMd->pred_mat_re_idx[0][1] = 0; + hMd->pred_mat_re_idx[1][0] = 0; + } +#endif + } + } + } + + return; +} + + +/*-----------------------------------------------------------------------------------------* + * Function isar_splitBinPostRendMdHuffDec() + * + * + *-----------------------------------------------------------------------------------------*/ + +static void isar_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 ) +{ + 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; + 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 ) + { + pred_cb_idx = 1; + } + else + { + pred_cb_idx = 0; + } + 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]; + + for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) + { + for ( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses - 1; pos_idx++ ) + { + if ( hBinHrSplitPostRend->pose_type[pos_idx] == ANY_YAW ) + { +#ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + 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 ( 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] ); + } + } + 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++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + 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] ); + } + } + 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++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + 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] ); + } + } + 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 ( 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] ); + } + } + 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++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + 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[1][0] = 0; + sym_adj_idx[0][1] = 0; + 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++ ) + { + 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 ); + } + } + else if ( hBinHrSplitPostRend->pose_type[pos_idx] == PITCH_ONLY ) + { + 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->gd2_idx = isar_split_rend_huffman_decode_opt( &pHuff_cfg->p_gd, pBits, pHuff_cfg->p_gd_idx_trav ); + } + } + else + { +#ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + 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 ( 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 ); + } + } + 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++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + 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 ); + } + } + 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++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + 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 ); + } + } + 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 ( 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 ); + } + } + 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++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + + 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[1][0] = 0; + sym_adj_idx[0][1] = 0; + isar_SplitRenderer_getdiagdiff( sym_adj_idx, hMd->pred_mat_re_idx, -1, min_pred_roll_idx, max_pred_roll_idx ); + } +#endif + } + } + } + + return; +} + + +/*-----------------------------------------------------------------------------------------* + * Function isar_splitBinPostRendMdDec() + * + * + *-----------------------------------------------------------------------------------------*/ + +void isar_splitBinPostRendMdDec( + 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 + , + BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend +#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]; +#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + int16_t num_quant_strats; +#else + int16_t 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]; +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + int16_t 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; +#endif + + hBinHrSplitPostRend->low_Res = 1; + + 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 ); + +#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + num_bits = isar_renderSplitGetRot_axisNumBits( split_rend_config.dof ); + if ( num_bits > 0 ) + { + axis_code = (int16_t) ISAR_SPLIT_REND_BITStream_read_int32( pBits, (int32_t) num_bits ); + } + else + { + axis_code = 0; + } + rot_axis = isar_renderSplitGetRot_axisFromCode( split_rend_config.dof, axis_code ); + ro_md_flag = (int16_t) ISAR_SPLIT_REND_BITStream_read_int32( pBits, ISAR_SPLIT_REND_RO_FLAG_BITS ); +#else + rot_axis = (ISAR_SPLIT_REND_ROT_AXIS) ISAR_SPLIT_REND_BITStream_read_int32( pBits, ISAR_SPLIT_REND_ROT_AXIS_BITS ); +#endif + + 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 ); + + num_subframes = ( hBinHrSplitPostRend->low_Res == 0 ) ? MAX_PARAM_SPATIAL_SUBFRAMES : 1; + for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) + { + int16_t angle; + + hBinHrSplitPostRend->QuaternionsPre[sf_idx].w = -3.0f; + + 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 = (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 = (int16_t) ISAR_SPLIT_REND_BITStream_read_int32( pBits, ISAR_SPLIT_REND_HEAD_POSE_BITS ); + angle -= 180; + hBinHrSplitPostRend->QuaternionsPre[sf_idx].z = (float) angle; + } + +#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 ); +#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 ); +#endif + + quant_strat_bits = (int32_t) ceilf( log2f( 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 ) + { + isar_splitBinPostRendMdBase2Dec( + pBits, hBinHrSplitPostRend, + pMultiBinPoseData, + num_subframes, + pred_real_bands_yaw[quant_strat], + pred_imag_bands_yaw[quant_strat], + pred_quant_pnts_yaw[quant_strat], + d_bands_yaw[quant_strat], + bands_pitch[quant_strat], + pred_real_bands_roll[quant_strat], + pred_imag_bands_roll[quant_strat] ); + } + else + { + isar_splitBinPostRendMdHuffDec( + pBits, hBinHrSplitPostRend, + pMultiBinPoseData, + num_subframes, + pred_real_bands_yaw[quant_strat], + pred_imag_bands_yaw[quant_strat], + pred_quant_pnts_yaw[quant_strat], + d_bands_yaw[quant_strat], + bands_pitch[quant_strat], + pred_real_bands_roll[quant_strat], + pred_imag_bands_roll[quant_strat] ); + } +#ifdef SPLIT_MD_CODING_DEBUG + for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) + { + int16_t val, ch2, val_ref; + char filename[200] = "split_md_debug_indices.bin"; + for ( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses - 1; pos_idx++ ) + { + if ( hBinHrSplitPostRend->pose_type[pos_idx] == ANY_YAW ) + { + for ( b = 0; b < pred_real_bands_yaw[quant_strat]; b++ ) + { + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + val = hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b].pred_mat_re_idx[ch1][ch2]; + dbgread( &val_ref, sizeof( int16_t ), 1, filename ); + if ( abs( val_ref - val ) > 0 ) + { + assert( 0 ); + } + } + } + } + for ( b = 0; b < pred_imag_bands_yaw[quant_strat]; b++ ) + { + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + val = hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b].pred_mat_im_idx[ch1][ch2]; + dbgread( &val_ref, sizeof( int16_t ), 1, filename ); + if ( abs( val_ref - val ) > 0 ) + { + assert( 0 ); + } + } + } + } + for ( b = 0; b < d_bands_yaw[quant_strat]; b++ ) + { + val = hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b].gd_idx; + dbgread( &val_ref, sizeof( int16_t ), 1, filename ); + if ( abs( val_ref - val ) > 0 ) + { + assert( 0 ); + } + } + } + else if ( hBinHrSplitPostRend->pose_type[pos_idx] == PITCH_ONLY ) + { + for ( b = 0; b < bands_pitch[quant_strat]; b++ ) + { + val = hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b].gd_idx; + dbgread( &val_ref, sizeof( int16_t ), 1, filename ); + if ( abs( val_ref - val ) > 0 ) + { + assert( 0 ); + } + val = hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b].gd2_idx; + dbgread( &val_ref, sizeof( int16_t ), 1, filename ); + if ( abs( val_ref - val ) > 0 ) + { + assert( 0 ); + } + } + } + else + { + for ( b = 0; b < pred_real_bands_roll[quant_strat]; b++ ) + { + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + val = hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b].pred_mat_re_idx[ch1][ch2]; + dbgread( &val_ref, sizeof( int16_t ), 1, filename ); + if ( abs( val_ref - val ) > 0 ) + { + assert( 0 ); + } + } + } + } + for ( b = 0; b < pred_imag_bands_roll[quant_strat]; b++ ) + { + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + val = hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b].pred_mat_im_idx[ch1][ch2]; + dbgread( &val_ref, sizeof( int16_t ), 1, filename ); + if ( abs( val_ref - val ) > 0 ) + { + assert( 0 ); + } + } + } + } + } + } + } +#endif + + for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) + { + for ( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses - 1; pos_idx++ ) + { + if ( hBinHrSplitPostRend->pose_type[pos_idx] == ANY_YAW ) + { + 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] ); + } + 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] ); + } + for ( ; b < MAX_SPLIT_REND_MD_BANDS; b++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + 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; + } + } + 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 ); + } + for ( ; b < MAX_SPLIT_REND_MD_BANDS; b++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + hMd->gd = 0.0f; + } + } + else if ( hBinHrSplitPostRend->pose_type[pos_idx] == PITCH_ONLY ) + { + 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 ); + } + 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; + } + } + else + { + 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 ); + } + 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 ); + } + for ( ; b < MAX_SPLIT_REND_MD_BANDS; b++ ) + { + hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + 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; + } + } + } + } + } + +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) + { + float val; + for ( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses - 1; pos_idx++ ) + { + if ( hBinHrSplitPostRend->pose_type[pos_idx] == ANY_YAW ) + { + for ( b = 0; b < pred_real_bands_yaw[quant_strat]; b++ ) + { + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_re_idx[ch1][ch2]; + if ( fabsf( hMd->pred_mat_re_idx[ch1][ch2] - val ) > 1e-20 ) + { + assert( 0 ); + } + } + } + } + for ( b = 0; b < pred_imag_bands_yaw[quant_strat]; b++ ) + { + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_im_idx[ch1][ch2]; + if ( fabsf( hMd->pred_mat_im_idx[ch1][ch2] - val ) > 1e-20 ) + { + assert( 0 ); + } + } + } + } + for ( b = 0; b < d_bands_yaw[quant_strat]; b++ ) + { + val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd_idx; + if ( fabsf( hMd->gd_idx - val ) > 1e-20 ) + { + assert( 0 ); + } + } + } + else if ( hBinHrSplitPostRend->pose_type[pos_idx] == PITCH_ONLY ) + { + for ( b = 0; b < bands_pitch[quant_strat]; b++ ) + { + val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd_idx; + if ( fabsf( hMd->gd_idx - val ) > 1e-20 ) + { + assert( 0 ); + } + val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd2_idx; + if ( fabsf( hMd->gd2_idx - val ) > 1e-20 ) + { + assert( 0 ); + } + } + } + else + { + for ( b = 0; b < pred_real_bands_roll[quant_strat]; b++ ) + { + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_re_idx[ch1][ch2]; + if ( fabsf( hMd->pred_mat_re_idx[ch1][ch2] - val ) > 1e-20 ) + { + assert( 0 ); + } + } + } + } + for ( b = 0; b < pred_imag_bands_roll[quant_strat]; b++ ) + { + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_im_idx[ch1][ch2]; + if ( fabsf( hMd->pred_mat_im_idx[ch1][ch2] - val ) > 1e-20 ) + { + assert( 0 ); + } + } + } + } + } + } + } +#endif + + return; +} + + +/*-----------------------------------------------------------------------------------------* + * Function wrap_around_angle() + * + * + *-----------------------------------------------------------------------------------------*/ + +static void wrap_around_angle( + float *a ) +{ + if ( ( *a ) > 180.0f ) + { + ( *a ) = ( *a ) - 360; + } + else if ( ( *a ) < -180.0f ) + { + ( *a ) = ( *a ) + 360; + } + return; +} + + +/*-----------------------------------------------------------------------------------------* + * Function wrap_around_angle() + * + * + *-----------------------------------------------------------------------------------------*/ + +static void wrap_around_ypr( + IVAS_QUATERNION *Quaternions ) +{ + /*only if quat is actually yaw, pitch , roll angles*/ + if ( Quaternions->w == -3.0f ) + { + wrap_around_angle( &Quaternions->x ); + wrap_around_angle( &Quaternions->y ); + wrap_around_angle( &Quaternions->z ); + } + 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] ) +{ + float n, d, interp_fact; + + if ( 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 ) + { + 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; + } + } + else + { + interp_fact = 0.0f; + } + + return interp_fact; +} + + +/*-----------------------------------------------------------------------------------------* + * 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 ) +{ + float min_diff, diff; + int16_t pos_idx; + + ind[0] = 0; + ind[1] = 0; + min_diff = 360.0f; + + /*find the closest pose from assumed poses*/ + for ( pos_idx = 0; pos_idx < num_poses; pos_idx++ ) + { + diff = fabsf( p_t - p[pos_idx] ); + if ( diff < min_diff ) + { + ind[0] = pos_idx; + min_diff = (float) diff; + } + } + + min_diff = 360.0; + 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 ) ) + { + ind[1] = pos_idx; + min_diff = (float) diff; + } + } + + return; +} + + +/*-----------------------------------------------------------------------------------------* + * Function get_interpolation_vars() + * + * + *-----------------------------------------------------------------------------------------*/ + +static void get_interpolation_vars( + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + const IVAS_QUATERNION *Quaternions_ref, + const IVAS_QUATERNION *Quaternions_act, + 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 ) +{ + 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]; + int16_t pos_idx, num_poses; + + quaternions_diff.x = 0.0f; + quaternions_diff.y = 0.0f; + quaternions_diff.z = 0.0f; + + num_poses = pMultiBinPoseData->num_poses; + 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; + } + + /*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 ); + + interp_yaw_pose_idx[0] = 0; + interp_yaw_pose_idx[1] = 0; + if ( fabs( quaternions_diff.x ) > EPSILON ) + { + get_nearest_pose_ind( y, quaternions_diff.x, interp_yaw_pose_idx, num_poses ); + } + *interp_yaw_fact = get_interp_fact( y, quaternions_diff.x, interp_yaw_pose_idx ); + + interp_pitch_pose_idx[0] = 0; + interp_pitch_pose_idx[1] = 0; + if ( fabs( quaternions_diff.y ) > EPSILON ) + { + get_nearest_pose_ind( p, quaternions_diff.y, interp_pitch_pose_idx, num_poses ); + } + *interp_pitch_fact = get_interp_fact( p, quaternions_diff.y, interp_pitch_pose_idx ); + + interp_roll_pose_idx[0] = 0; + interp_roll_pose_idx[1] = 0; + if ( fabs( quaternions_diff.z ) > EPSILON ) + { + get_nearest_pose_ind( r, quaternions_diff.z, interp_roll_pose_idx, num_poses ); + } + *interp_roll_fact = get_interp_fact( r, quaternions_diff.z, interp_roll_pose_idx ); + + return; +} + + +/*-----------------------------------------------------------------------------------------* + * Function interpolate_pred_matrix() + * + * + *-----------------------------------------------------------------------------------------*/ + +static void interpolate_pred_matrix( + 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] ) +{ + int16_t ch_idx1, ch_idx2; + float diff; + 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++ ) + { + 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; + + 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; + } + + 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_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]; + } + } + } + + 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_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]; + } + } + } + + for ( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) + { + 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 ); + + 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 ); + } + } + + return; +} + + +/*-----------------------------------------------------------------------------------------* + * Function interpolate_rend_md() + * + * + *-----------------------------------------------------------------------------------------*/ + +static void interpolate_rend_md( + 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 ) +{ + 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; + + gd1 = 0.0f; + gd2 = 0.0f; + + idx1 = interp_yaw_pose_idx[0]; + idx2 = interp_yaw_pose_idx[1]; + if ( ( idx1 != 0 ) || ( idx2 != 0 ) ) + { + interpolate_pred_matrix( rot_md, sf_idx, band_idx, interp_yaw_pose_idx, interp_yaw_fact, mix_mat_re, mix_mat_im ); + + if ( idx1 != 0 ) + { + gd1 = rot_md[idx1 - 1][sf_idx][band_idx].gd; + } + + if ( idx2 != 0 ) + { + gd2 = rot_md[idx2 - 1][sf_idx][band_idx].gd; + } + + diff = gd1 - gd2; + *gd_int = gd1 - ( diff * interp_yaw_fact ); + } + else + { + /*P = P'*/ + 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; + } + *gd_int = 0.0f; + } + + idx1 = interp_pitch_pose_idx[0]; + idx2 = interp_pitch_pose_idx[1]; + if ( ( idx1 != 0 ) || ( idx2 != 0 ) ) + { + gd1 = 1.0f; + gd2 = 1.0f; + + gd3 = 1.0f; + gd4 = 1.0f; + + if ( idx1 != 0 ) + { + gd1 = rot_md[idx1 - 1][sf_idx][band_idx].gd; + gd3 = rot_md[idx1 - 1][sf_idx][band_idx].gd2; + } + if ( idx2 != 0 ) + { + gd2 = rot_md[idx2 - 1][sf_idx][band_idx].gd; + gd4 = rot_md[idx2 - 1][sf_idx][band_idx].gd2; + } + 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 ); + + for ( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) + { + 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; + } + } + else + { + pitch_gain_l = 1.0f; + pitch_gain_r = 1.0f; + } + + idx1 = interp_roll_pose_idx[0]; + idx2 = interp_roll_pose_idx[1]; + if ( ( idx1 != 0 ) || ( idx2 != 0 ) ) + { + interpolate_pred_matrix( rot_md, sf_idx, band_idx, interp_roll_pose_idx, interp_roll_fact, mix_mat_re3, 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 ); + + for ( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) + { + 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]; + } + } + } + + return; +} + + +/*-----------------------------------------------------------------------------------------* + * Function isar_SplitRenderer_PostRenderer() + * + * + *-----------------------------------------------------------------------------------------*/ + +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[][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 */ + 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; +#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]; +#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]; + const int16_t *pBand_grouping = isar_split_rend_band_grouping; + + num_md_bands = MAX_SPLIT_REND_MD_BANDS; + + push_wmops( "isar_SplitRenderer_PostRenderer" ); + + num_slots = MAX_PARAM_SPATIAL_SUBFRAMES; +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + pos_idx = MAX_HEAD_ROT_POSES - 1; +#else + pos_idx = 0; +#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++ ) + { + 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; + } + 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++ ) + { + /*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; + } + } + + +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + for ( pos_idx = 0; pos_idx < MAX_HEAD_ROT_POSES - 1; pos_idx++ ) + { + for ( b = 0; b < num_md_bands; b++ ) + { + if ( hBinPostRenderer->pose_type[pos_idx] == PITCH_ONLY ) + { + + for ( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) + { + set_zero( hBinPostRenderer->rot_md[pos_idx][sf_idx][b].pred_mat_re[ch_idx1], BINAURAL_CHANNELS ); + set_zero( hBinPostRenderer->rot_md[pos_idx][sf_idx][b].pred_mat_im[ch_idx1], BINAURAL_CHANNELS ); + hBinPostRenderer->rot_md[pos_idx][sf_idx][b].pred_mat_re[ch_idx1][ch_idx1] = 1.0f; + } + hBinPostRenderer->rot_md[pos_idx][sf_idx][b].pred_mat_re[0][0] *= hBinPostRenderer->rot_md[pos_idx][sf_idx][b].gd; + hBinPostRenderer->rot_md[pos_idx][sf_idx][b].pred_mat_re[1][1] *= hBinPostRenderer->rot_md[pos_idx][sf_idx][b].gd2; + hBinPostRenderer->rot_md[pos_idx][sf_idx][b].gd = 0.0f; + } + else if ( hBinPostRenderer->pose_type[pos_idx] == ANY_ROLL ) + { + hBinPostRenderer->rot_md[pos_idx][sf_idx][b].gd = 0.0f; + } + + 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] = hBinPostRenderer->rot_md[pos_idx][sf_idx][b].pred_mat_re[ch_idx1][0]; + rot_md_act[pos_idx][b].pred_mat_re[ch_idx1][1] = hBinPostRenderer->rot_md[pos_idx][sf_idx][b].pred_mat_re[ch_idx1][1]; + rot_md_act[pos_idx][b].pred_mat_im[ch_idx1][0] = hBinPostRenderer->rot_md[pos_idx][sf_idx][b].pred_mat_im[ch_idx1][0]; + rot_md_act[pos_idx][b].pred_mat_im[ch_idx1][1] = hBinPostRenderer->rot_md[pos_idx][sf_idx][b].pred_mat_im[ch_idx1][1]; + rot_md_act[pos_idx][b].gd = hBinPostRenderer->rot_md[pos_idx][sf_idx][b].gd; + } + } + } + +#endif + +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + for ( pos_idx = 0; pos_idx < MAX_HEAD_ROT_POSES; pos_idx++ ) +#else + pos_idx = 0; +#endif + { + 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++ ) + { + for ( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) + { + 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]; + } + 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]; + } + } + + brange[0] = pBand_grouping[b]; + brange[1] = pBand_grouping[b + 1]; + for ( b2 = brange[0]; b2 < brange[1]; b2++ ) + { + 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; + } + + + 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]; +#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]; +#endif + } + } + } + } + } + +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + for ( pos_idx = 0; pos_idx < MAX_HEAD_ROT_POSES; pos_idx++ ) +#else + pos_idx = 0; +#endif + { + for ( b = 0; b < num_md_bands; b++ ) + { + 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->gd_mem[pos_idx][b] = rot_md_act[pos_idx][b].gd; + } + } + hBinPostRenderer->cf_flag = 1; + +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + { + int16_t num_cldfb_bands; + num_cldfb_bands = CLDFB_NO_CHANNELS_MAX; + for ( slot_idx = 0; slot_idx < num_slots; slot_idx++ ) + { + index_slot = sf_idx * num_slots + slot_idx; + for ( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) + { + mvr2r( Cldfb_RealBuffer_Recons_Binaural[MAX_HEAD_ROT_POSES - 1][ch_idx1][index_slot], Cldfb_RealBuffer_Ref_Binaural[ch_idx1][index_slot], num_cldfb_bands ); + mvr2r( Cldfb_ImagBuffer_Recons_Binaural[MAX_HEAD_ROT_POSES - 1][ch_idx1][index_slot], Cldfb_ImagBuffer_Ref_Binaural[ch_idx1][index_slot], num_cldfb_bands ); + } + } + + for ( pos_idx = 0; pos_idx < MAX_HEAD_ROT_POSES; pos_idx++ ) + { + char fname[200] = "recons_out_pos"; + char tag[2]; + tag[0] = (char) ( '0' + pos_idx ); + tag[1] = '\0'; + strcat( fname, tag ); + strcat( fname, ".wav" ); + isar_log_cldfb2wav_data( + Cldfb_RealBuffer_Recons_Binaural[pos_idx], + Cldfb_ImagBuffer_Recons_Binaural[pos_idx], + hBinPostRenderer->cldfbSynReconsBinDec[pos_idx], + BINAURAL_CHANNELS, + num_cldfb_bands, + 48000, + num_slots, + sf_idx * num_slots, + fname ); + } + } +#endif + + pop_wmops(); + 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] ) +{ + 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]; + num_cldfb_bands = hBinHrSplitPostRend->cldfbSyn[0]->no_channels; + + /* Implement CLDFB analysis */ + 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++ ) + { + 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] ); + } + } + + isar_SplitRenderer_PostRenderer( hBinHrSplitPostRend, pMultiBinPoseData, Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, QuaternionPost ); + + /* Implement CLDFB synthesis */ + 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]; + + 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]; + } + + cldfbSynthesis( RealBuffer, ImagBuffer, &( output[ch_idx][0] ), num_cldfb_bands * CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, hBinHrSplitPostRend->cldfbSyn[ch_idx] ); + } + + 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 ) +{ + int16_t ch_idx, slot_idx, num_cldfb_bands; + + push_wmops( "isar_rend_CldfbSplitPostRendProcess" ); + + num_cldfb_bands = hBinHrSplitPostRend->cldfbSyn[0]->no_channels; + + if ( cldfb_in_flag == 0 ) + { + isar_rend_CldfbSplitPostRendProcessTdIn( hBinHrSplitPostRend, pMultiBinPoseData, QuaternionPost, output ); + pop_wmops(); + return; + } + + isar_SplitRenderer_PostRenderer( hBinHrSplitPostRend, pMultiBinPoseData, Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, QuaternionPost ); + + /* Implement CLDFB synthesis */ + 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]; + + 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]; + } + + cldfbSynthesis( RealBuffer, ImagBuffer, &( output[ch_idx][0] ), num_cldfb_bands * CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, hBinHrSplitPostRend->cldfbSyn[ch_idx] ); + } + + pop_wmops(); + return; +} + + +/*-----------------------------------------------------------------------------------------* + * Function isar_init_split_post_rend_handles() + * + * + *-----------------------------------------------------------------------------------------*/ + +void isar_init_split_post_rend_handles( + ISAR_SPLIT_POST_REND_WRAPPER *hSplitRendWrapper ) +{ + hSplitRendWrapper->hBinHrSplitPostRend = NULL; + hSplitRendWrapper->hSplitBinLCLDDec = NULL; + hSplitRendWrapper->hLc3plusDec = NULL; + isar_init_multi_bin_pose_data( &hSplitRendWrapper->multiBinPoseData ); + hSplitRendWrapper->first_good_frame_received = 0; + + return; +} +#endif diff --git a/lib_isar/isar_splitRendererPre.c b/lib_isar/isar_splitRendererPre.c new file mode 100644 index 000000000..5a7c6ee70 --- /dev/null +++ b/lib_isar/isar_splitRendererPre.c @@ -0,0 +1,2340 @@ +/****************************************************************************************************** + + (C) 2022-2023 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. + +*******************************************************************************************************/ + +#include +#include "options.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT +#include +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG +#include +#endif +#include "ivas_prot.h" +#include "prot.h" +#include "isar_rom_post_rend.h" +#include "lib_isar_pre_rend.h" +#include "isar_prot.h" +#ifdef DEBUGGING +#include "debug.h" +#endif +#include "wmc_auto.h" +#ifdef DBG_WAV_WRITER +#include "string.h" +#endif + +/*---------------------------------------------------------------------* + * Local function declarations + *---------------------------------------------------------------------*/ + +static void isar_SplitRenderer_GetRotMd( + 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 ); + +/*------------------------------------------------------------------------- + * Local functions + * + * + *------------------------------------------------------------------------*/ + +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 ) +{ + float re1, im1, re2, im2; + + 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; + + return; +} + + +static int16_t isar_is_mat_inv_2by2_complex( + float in_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS], + float in_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS] ) +{ + int16_t is_det_zero = 1; + float det, det_re, det_im; + + isar_calc_mat_det_2by2_complex( in_re, in_im, &det_re, &det_im ); + + det = ( ( det_re * det_re ) + ( det_im * det_im ) ); + + if ( det < EPSILON ) + { + 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] ) +{ + float det_re, det_im; + float re, im, det; + + isar_calc_mat_det_2by2_complex( in_re, in_im, &det_re, &det_im ); + + det = ( det_re * det_re ) + ( det_im * det_im ); + +#ifdef DEBUGGING + /* assert to catch cases when input is singular matrix */ + assert( det > 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; + + 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; + + 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; + + 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 ) +{ + 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; + + trace_cov = 0.0f; + for ( i = 0; i < num_chs; i++ ) + { + trace_cov += cov_ii_re[i][i]; + } + + trace_cov = max( 0.0f, trace_cov ); + + if ( trace_cov < EPSILON ) + { + 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 ); + } + return; + } + + for ( i = 0; i < num_chs; i++ ) + { + mvr2r( cov_ii_re[i], cov_ii_local_re[i], num_chs ); + } + + for ( i = 0; i < num_chs; i++ ) + { + cov_ii_local_re[i][i] = cov_ii_re[i][i] + ( trace_cov * 0.0001f ); + } + + if ( isar_is_mat_inv_2by2_complex( cov_ii_local_re, cov_ii_im ) ) + { + 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 ); + } + else + { + int16_t max_var_idx; + for ( i = 0; i < num_chs; i++ ) + { + set_zero( pred_mat_re[i], BINAURAL_CHANNELS ); + set_zero( pred_mat_im[i], BINAURAL_CHANNELS ); + } + + max_var_idx = 0; + if ( cov_ii_local_re[1][1] > cov_ii_local_re[0][0] ) + { + max_var_idx = 1; + } + + if ( cov_ii_local_re[max_var_idx][max_var_idx] > EPSILON ) + { + 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]; + } + } + } + + if ( real_only ) + { + for ( i = 0; i < num_chs; i++ ) + { + set_zero( pred_mat_im[i], 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 ) +{ + 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]; + + assert( num_chs == BINAURAL_CHANNELS ); + for ( i = 0; i < num_chs; i++ ) + { + 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]; + } + set_zero( postpred_cov_re[i], BINAURAL_CHANNELS ); + } + + /* 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 ( j = 0; j < i; j++ ) + { + postpred_cov_re[i][j] = postpred_cov_re[j][i]; + } + } + + 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 ) +{ + int16_t sf, cldfb_band_idx, ch_idx1, ch_idx2; + int16_t brange[2]; + + 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 ); + } + + brange[0] = pBand_grouping[md_band_idx]; + brange[1] = pBand_grouping[md_band_idx + 1]; + + for ( ch_idx1 = 0; ch_idx1 < num_chs; ch_idx1++ ) + { + for ( ch_idx2 = 0; ch_idx2 < num_chs; ch_idx2++ ) + { + if ( real_only == 0 ) + { + for ( sf = start_slot_idx; sf < start_slot_idx + num_slots; sf++ ) + { + 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]; + } + } + } + else + { + for ( sf = start_slot_idx; sf < start_slot_idx + num_slots; sf++ ) + { + 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; + } + } + } + } + } + + 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 ) +{ + int16_t sf, cldfb_band_idx, ch_idx1, ch_idx2; + int16_t brange[2]; + + 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 ); + } + + brange[0] = pBand_grouping[md_band_idx]; + brange[1] = pBand_grouping[md_band_idx + 1]; + + for ( ch_idx1 = 0; ch_idx1 < num_chs; ch_idx1++ ) + { + for ( ch_idx2 = 0; ch_idx2 <= ch_idx1; ch_idx2++ ) + { + if ( ( ch_idx2 != ch_idx1 ) && ( real_only == 0 ) ) + { + for ( sf = start_slot_idx; sf < start_slot_idx + num_slots; sf++ ) + { + 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]; + } + } + } + else + { + for ( sf = start_slot_idx; sf < start_slot_idx + num_slots; sf++ ) + { + 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] = 0.0f; + } + } + } + } + } + + for ( ch_idx1 = 0; ch_idx1 < num_chs; ch_idx1++ ) + { + for ( ch_idx2 = ch_idx1 + 1; ch_idx2 < num_chs; ch_idx2++ ) + { + 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]; + } + } + + return; +} + + +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] ) +{ + int16_t i, j; + float norm_fact, abs_val; + + norm_fact = 0.0f; + for ( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + 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_RABS( cov_oo_re[i][j], abs_val ); + norm_fact = max( norm_fact, abs_val ); + } + } + + norm_fact = ( norm_fact > EPSILON ) ? norm_fact : 1.0f; + + norm_fact = PCM16_TO_FLT_FAC / norm_fact; + + return norm_fact; +} + + +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 ) +{ + int32_t min_sym_val; + const int32_t *codebook; + + min_sym_val = huff_cfg->codebook[0]; + + codebook = &huff_cfg->codebook[3 * ( in - min_sym_val )]; + *hlen = codebook[1]; + *hcode = codebook[2]; + + return; +} + + +static void isar_split_rend_quant_md( + 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 ) +{ + int16_t ch1, ch2; + int16_t gd_idx_min; +#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + float quant_val; +#else + float sign, quant_val; +#endif + + if ( pose_type == PRED_ONLY || pose_type == PRED_ROLL_ONLY ) + { + float onebyquantstep; + + onebyquantstep = pred_1byquantstep; + if ( real_only == 1 ) + { +#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + hMd->pred_mat_re[ch1][ch1] = hMd->pred_mat_re2[ch1]; + } + hMd->pred_mat_re[1][0] = 0.0f; + hMd->pred_mat_re[0][1] = 0.0f; + + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + 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 ); + } + } +#else + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + 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; + } + } +#endif + } +#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + else + { +#endif + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + 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 ); + } + } +#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + } +#endif + + if ( real_only == 0 ) + { + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + 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 ); + } + } + } + } + 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 ) ); + 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; + } + 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; + } + + 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] ) +{ + int16_t i; + for ( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + gains[i] = cov_in[i][i]; + if ( gains[i] < EPSILON ) + { + gains[i] = 1.0f; + } + else + { + gains[i] = ( cov_out[i][i] ) / gains[i]; + gains[i] = sqrtf( gains[i] ); + } + } + 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], + ISAR_BIN_HR_SPLIT_REND_MD_HANDLE hMd, + const ISAR_SPLIT_REND_POSE_TYPE pose_type, + const int16_t 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++ ) + { + gd_tmp[i] = cov_ii_re[i][i]; + if ( gd_tmp[i] < EPSILON ) + { + gd_tmp[i] = 1.0f; + } + else + { + gd_tmp[i] = ( cov_oo_re[i][i] ) / gd_tmp[i]; + gd_tmp[i] = sqrtf( gd_tmp[i] ); + } + } +#endif + hMd->gd = gd_tmp[0]; + hMd->gd2 = gd_tmp[1]; + } + 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 ); + 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 ); + } +#else + for ( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + gd_tmp[i] = cov_ii_re[i][i]; + if ( gd_tmp[i] < EPSILON ) + { + gd_tmp[i] = 1.0f; + } + else + { + gd_tmp[i] = ( cov_oo_re[i][i] ) / gd_tmp[i]; + gd_tmp[i] = sqrtf( gd_tmp[i] ); + } + hMd->pred_mat_re[i][i] = gd_tmp[i]; + set_zero( hMd->pred_mat_im[i], BINAURAL_CHANNELS ); + } +#endif + hMd->pred_mat_re[1][0] = 0.0f; + hMd->pred_mat_re[0][1] = 0.0f; + } + else + { +#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + get_lr_gains( cov_ii_re, cov_oo_re, hMd->pred_mat_re2 ); +#endif + cov_norm_fact = GetNormFact( cov_ii_re, cov_ii_im, cov_io_re, cov_io_im, cov_oo_re ); + + /* normalize the covariance */ + for ( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + 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; + } + } + + 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 ); + + ComputePostPredCov( cov_ii_norm_re, cov_ii_norm_im, hMd->pred_mat_re, hMd->pred_mat_im, postpred_cov_re, BINAURAL_CHANNELS ); + + /* normalize everything to +-1 range */ + gd = 1.0f / ( PCM16_TO_FLT_FAC ); + for ( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + 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; + } + } + + gd2 = 0.0f; + sigma_d = 0.0f; + hMd->gd = 0.0f; + + if ( postpred_cov_re[0][0] > EPSILON ) + { + 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 ); + } + else + { + gl2 = 1.0f; + } + + if ( postpred_cov_re[1][1] > EPSILON ) + { + 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 ); + } + else + { + gr2 = 1.0f; + } + + for ( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + hMd->pred_mat_re[i][0] *= gl2; + hMd->pred_mat_re[i][1] *= gr2; + } + + if ( real_only == 0 ) + { + for ( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + hMd->pred_mat_im[i][0] *= gl2; + hMd->pred_mat_im[i][1] *= gr2; + } + } + } + } + + 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] ) +{ + 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]; + + ISAR_SPLIT_REND_POSE_TYPE pose_type; + + for ( q = 0; q < num_quant_strats; q++ ) + { + pred_yaw_bits[q] = (int16_t) ceilf( log2f( pred_quant_pnts_yaw[q] ) ); + } + pred_roll_bits = (int16_t) ceilf( log2f( ISAR_SPLIT_REND_ROLL_PRED_QUANT_PNTS ) ); + + d_gain_bits = (int16_t) ceilf( log2f( ISAR_SPLIT_REND_D_QUANT_PNTS ) ); + pitch_gain_bits = d_gain_bits; + + for ( q = 0; q < num_quant_strats; q++ ) + { + base2bits[q] = 0; + } + + for ( q = 0; q < num_quant_strats; q++ ) + { + for ( pose_idx = 0; pose_idx < pMultiBinPoseData->num_poses - 1; pose_idx++ ) + { + pose_type = hBinHrSplitPreRend->pose_type[pose_idx]; + if ( 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; +#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; +#endif + base2bits[q] += d_gain_bits * d_bands_yaw[q] * num_subframes; + } + else if ( pose_type == PITCH_ONLY ) + { + base2bits[q] += pitch_gain_bits * bands_pitch[q] * num_subframes; + base2bits[q] += pitch_gain_bits * bands_pitch[q] * num_subframes; + } + 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; +#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; +#endif + } + } + } + + return; +} + + +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, + 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; + 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 ) + { + pred_cb_idx = 1; + } + else + { + pred_cb_idx = 0; + } + 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]; + + pred_code_len = pHuff_cfg->pred_base2_code_len[pred_cb_idx]; + pred_roll_code_len = pHuff_cfg->pred_roll_base2_code_len; + gd_code_len = pHuff_cfg->gd_base2_code_len; + p_gd_code_len = pHuff_cfg->p_gd_base2_code_len; + + num_poses = pMultiBinPoseData->num_poses; + + for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) + { + for ( pos_idx = 0; pos_idx < num_poses - 1; pos_idx++ ) + { + if ( hBinHrSplitPreRend->pose_type[pos_idx] == ANY_YAW ) + { +#ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + 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 ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + code = 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++ ) + { + hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + code = 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++ ) + { + hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + code = 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 ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + code = 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++ ) + { + hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + code = 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++ ) + { + hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; + code = 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 ) + { + for ( b = 0; b < bands_pitch; b++ ) + { + hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; + code = 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; + ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, p_gd_code_len ); + } + } + else + { +#ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + 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 ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + code = 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++ ) + { + hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + code = 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++ ) + { + hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + code = 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 ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + code = 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++ ) + { + hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + code = hMd->pred_mat_re_idx[ch1][ch1] - min_pred_roll_idx; + ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, pred_roll_code_len ); + } + } +#endif + } + } + } + +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + { + static int16_t num_bits = 0; + static int16_t cntr = 0; + float fnum_bits; + + cntr++; + + num_bits += pBits->bits_written; + /* collect bits for every second */ + if ( cntr == 50 ) + { + cntr = 0; + fnum_bits = (float) num_bits / 1000.0f; + dbgwrite_txt( &fnum_bits, 1, "split_rend_MD_bitrate.txt", "MD bitrate (kbps)" ); + num_bits = 0; + } + } +#endif + return; +} + + +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, + 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; + 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 ) + { + pred_cb_idx = 1; + } + else + { + pred_cb_idx = 0; + } + + 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]; + + num_poses = pMultiBinPoseData->num_poses; + + for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) + { + for ( pos_idx = 0; pos_idx < num_poses - 1; pos_idx++ ) + { + if ( hBinHrSplitPreRend->pose_type[pos_idx] == ANY_YAW ) + { +#ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + 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 ( 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++ ) + { + 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 ( 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 ); + } + } + } +#else + 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 ( 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 ); + } + } + + 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 ( 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++ ) + { + 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++ ) + { + 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++ ) + { + 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 ) + { + 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 ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len ); + + isar_split_rend_huffman_encode( &pHuff_cfg->p_gd, hMd->gd2_idx, &code, &len ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, code, len ); + } + } + else + { +#ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + 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 ( 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++ ) + { + 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 ( 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 ); + } + } + } +#else + 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 ( 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 ); + } + } + + 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 ( 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++ ) + { + 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++ ) + { + 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 ); + } + } +#endif + } + } + } + +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + { + static int16_t num_bits = 0; + static int16_t cntr = 0; + float fnum_bits; + + cntr++; + num_bits += pBits->bits_written; + /* collect bits for every second */ + if ( cntr == 50 ) + { + cntr = 0; + fnum_bits = (float) num_bits / 1000.0f; + dbgwrite_txt( &fnum_bits, 1, "split_rend_MD_bitrate.txt", "MD bitrate (kbps)" ); + num_bits = 0; + } + } +#endif + 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, +#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + const int16_t ro_md_flag, +#endif + const int32_t target_md_bits ) +{ +#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + int16_t 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]; + float pred_1byquantstep_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS]; + float pred_quantstep_yaw[ISAR_SPLIT_REND_NUM_QUANT_STRATS]; + ISAR_BIN_HR_SPLIT_REND_MD_HANDLE hMd; +#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + int16_t rot_axis_code, num_bits; +#endif + + if ( low_res_pre_rend_rot ) + { + num_subframes = 1; + } + else + { + num_subframes = MAX_PARAM_SPATIAL_SUBFRAMES; + } + + overhead_bits = pBits->bits_written; + + ISAR_SPLIT_REND_BITStream_write_int32( pBits, pMultiBinPoseData->dof, ISAR_SPLIT_REND_DOF_BITS ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, pMultiBinPoseData->hq_mode, ISAR_SPLIT_REND_HQ_MODE_BITS ); +#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + rot_axis_code = isar_renderSplitGetCodeFromRot_axis( pMultiBinPoseData->dof, pMultiBinPoseData->rot_axis, &num_bits ); + if ( num_bits > 0 ) + { + ISAR_SPLIT_REND_BITStream_write_int32( pBits, (int32_t) rot_axis_code, num_bits ); + } + ISAR_SPLIT_REND_BITStream_write_int32( pBits, (int32_t) ro_md_flag, ISAR_SPLIT_REND_RO_FLAG_BITS ); +#else + ISAR_SPLIT_REND_BITStream_write_int32( pBits, (int32_t) pMultiBinPoseData->rot_axis, ISAR_SPLIT_REND_ROT_AXIS_BITS ); +#endif + + /* code ref pose*/ + for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) + { + int16_t 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; + ISAR_SPLIT_REND_BITStream_write_int32( pBits, angle, ISAR_SPLIT_REND_HEAD_POSE_BITS ); + + angle = (int16_t) roundf( head_pos_euler.y ); + 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; + + 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 ); +#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 ); +#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 */ + + 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 ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) + { + for ( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses - 1; pos_idx++ ) + { + if ( hBinHrSplitPreRend->pose_type[pos_idx] == ANY_YAW ) + { + 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] ); + } + 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] ); + } + + 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 ); + } + } + else if ( hBinHrSplitPreRend->pose_type[pos_idx] == PITCH_ONLY ) + { + 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 ); + } + } + else + { + 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 ); + } + 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 ); + } + } + } + } + + /*get base2 bits and check if its within target. if yes then code with base2 to save complexity on post renderer*/ + start_bit = pBits->bits_written; + + ISAR_SPLIT_REND_BITStream_write_int32( pBits, 1, 1 ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, q, quant_strat_bits ); + + huff_bits = pBits->bits_written; + isar_SplitRenderer_code_md_huff( + hBinHrSplitPreRend, + pMultiBinPoseData, + num_subframes, + pred_real_bands_yaw[q], + pred_imag_bands_yaw[q], + pred_quant_pnts_yaw[q], + d_bands_yaw[q], + bands_pitch[q], + pred_real_bands_roll[q], + 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 ) ) ) + { + if ( huff_bits > base2bits[q] ) + { + pBits->bits_written = start_bit; + + ISAR_SPLIT_REND_BITStream_write_int32( pBits, 0, 1 ); + ISAR_SPLIT_REND_BITStream_write_int32( pBits, q, quant_strat_bits ); + + isar_SplitRenderer_code_md_base2( hBinHrSplitPreRend, pMultiBinPoseData, num_subframes, pred_real_bands_yaw[q], pred_imag_bands_yaw[q], + pred_quant_pnts_yaw[q], + d_bands_yaw[q], bands_pitch[q], pred_real_bands_roll[q], pred_imag_bands_roll[q], pBits ); + } + break; + } + + pBits->bits_written = start_bit; + } + +#ifdef SPLIT_MD_CODING_DEBUG + for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) + { + int16_t val, quant_strat, ch1, ch2; + char filename[200] = "split_md_debug_indices.bin"; + quant_strat = q; + for ( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses - 1; pos_idx++ ) + { + if ( hBinHrSplitPreRend->pose_type[pos_idx] == ANY_YAW ) + { + for ( b = 0; b < pred_real_bands_yaw[quant_strat]; b++ ) + { + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_re_idx[ch1][ch2]; + dbgwrite( &val, sizeof( int16_t ), 1, 1, filename ); + } + } + } + for ( b = 0; b < pred_imag_bands_yaw[quant_strat]; b++ ) + { + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_im_idx[ch1][ch2]; + dbgwrite( &val, sizeof( int16_t ), 1, 1, filename ); + } + } + } + for ( b = 0; b < d_bands_yaw[quant_strat]; b++ ) + { + val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd_idx; + dbgwrite( &val, sizeof( int16_t ), 1, 1, filename ); + } + } + else if ( hBinHrSplitPreRend->pose_type[pos_idx] == PITCH_ONLY ) + { + for ( b = 0; b < bands_pitch[quant_strat]; b++ ) + { + val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd_idx; + dbgwrite( &val, sizeof( int16_t ), 1, 1, filename ); + val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd2_idx; + dbgwrite( &val, sizeof( int16_t ), 1, 1, filename ); + } + } + else + { + for ( b = 0; b < pred_real_bands_roll[quant_strat]; b++ ) + { + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_re_idx[ch1][ch2]; + dbgwrite( &val, sizeof( int16_t ), 1, 1, filename ); + } + } + } + for ( b = 0; b < pred_imag_bands_roll[quant_strat]; b++ ) + { + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_im_idx[ch1][ch2]; + dbgwrite( &val, sizeof( int16_t ), 1, 1, filename ); + } + } + } + } + } + } +#endif + + return; +} + + +/*------------------------------------------------------------------------- + * Function isar_SplitRenderer_GetRotMd() + * + * + *------------------------------------------------------------------------*/ + +static void isar_SplitRenderer_GetRotMd( + 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 ) +{ + 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" ); + + num_md_bands = MAX_SPLIT_REND_MD_BANDS; + num_poses = pMultiBinPoseData->num_poses; + + if ( low_res ) + { + num_slots = CLDFB_NO_COL_MAX; + num_subframes = 1; + } + else + { + num_slots = MAX_PARAM_SPATIAL_SUBFRAMES; + num_subframes = MAX_PARAM_SPATIAL_SUBFRAMES; + } + + /* compute reference signal covariance */ + 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++ ) + { + if ( ( b < SPLIT_REND_RO_MD_BAND_THRESH ) || ( !ro_md_flag && b < COMPLEX_MD_BAND_THRESH ) ) + { + real_only = 0; + } + else + { + real_only = 1; + } + + 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 ); + + /* compute rotated signal covariance */ + for ( pos_idx = 0; pos_idx < num_poses - 1; pos_idx++ ) + { + if ( hBinHrSplitPreRend->pose_type[pos_idx] == ANY_ROLL ) + { + if ( 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 ); + + 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 ); + + 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 ); + } + } + } + + 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], + 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 ) +{ + push_wmops( "isar_rend_CldfbSplitPreRendProcess" ); + + isar_SplitRenderer_GetRotMd( hBinHrSplitPreRend, pMultiBinPoseData, Cldfb_In_BinReal, Cldfb_In_BinImag, low_res_pre_rend_rot, ro_md_flag ); + +#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 ); +#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; + float Cldfb_RealBuffer_Binaural_5ms[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; + float Cldfb_ImagBuffer_Binaural_5ms[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; + int16_t sf_idx, pos_idx, b, ch1, ch2; + int32_t read_off, write_off; + for ( sf_idx = 0; sf_idx < MAX_PARAM_SPATIAL_SUBFRAMES; sf_idx++ ) + { + QuaternionsPost[sf_idx].w = -3.0f; + QuaternionsPost[sf_idx].x = 0.0f; + QuaternionsPost[sf_idx].y = 0.0f; + QuaternionsPost[sf_idx].z = 0.0f; + } + + hBinHrSplitPreRend->hBinHrSplitPostRend->low_Res = 1; + set_fix_rotation_mat( hBinHrSplitPreRend->hBinHrSplitPostRend->fix_pos_rot_mat, pMultiBinPoseData ); + set_pose_types( hBinHrSplitPreRend->hBinHrSplitPostRend->pose_type, pMultiBinPoseData ); + for ( sf_idx = 0; sf_idx < MAX_PARAM_SPATIAL_SUBFRAMES; sf_idx++ ) + { + Quat2EulerDegree( headPosition, &head_pos_euler.z, &head_pos_euler.y, &head_pos_euler.x ); + hBinHrSplitPreRend->hBinHrSplitPostRend->QuaternionsPre[sf_idx].w = -3.0f; + hBinHrSplitPreRend->hBinHrSplitPostRend->QuaternionsPre[sf_idx].x = roundf( head_pos_euler.x ); + hBinHrSplitPreRend->hBinHrSplitPostRend->QuaternionsPre[sf_idx].y = roundf( head_pos_euler.y ); + hBinHrSplitPreRend->hBinHrSplitPostRend->QuaternionsPre[sf_idx].z = roundf( head_pos_euler.z ); + } + for ( sf_idx = 0; sf_idx < 1; sf_idx++ ) + { + for ( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses - 1; pos_idx++ ) + { + for ( b = 0; b < MAX_SPLIT_REND_MD_BANDS; b++ ) + { + hBinHrSplitPreRend->hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b] = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; + BIN_HR_SPLIT_REND_MD_HANDLE hMd; + hMd = &hBinHrSplitPreRend->hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; + minv = -1.4f; + maxv = 1.4f; + step = ( maxv - minv ) / 62.0f; + if ( b >= 20 ) + { + float sign; + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + 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; + } + } + } + + for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) + { + for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) + { + quant_val = hMd->pred_mat_re[ch1][ch2] - hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx][ch1][ch2]; + quant_val = min( maxv, max( quant_val, minv ) ); + quant_val = (int16_t) roundf( quant_val / step ); + hMd->pred_mat_re[ch1][ch2] = quant_val * step; + hMd->pred_mat_re[ch1][ch2] += hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx][ch1][ch2]; + + quant_val = hMd->pred_mat_im[ch1][ch2]; + quant_val = min( maxv, max( quant_val, minv ) ); + quant_val = (int16_t) roundf( quant_val / step ); + hMd->pred_mat_im[ch1][ch2] = quant_val * step; + } + } + } + } + } + + for ( sf_idx = 0; sf_idx < MAX_PARAM_SPATIAL_SUBFRAMES; sf_idx++ ) + { + mvr2r( (float *) Cldfb_In_BinReal[0][sf_idx * MAX_PARAM_SPATIAL_SUBFRAMES], (float *) Cldfb_RealBuffer_Binaural_5ms[0], MAX_PARAM_SPATIAL_SUBFRAMES * CLDFB_NO_CHANNELS_MAX ); + mvr2r( (float *) Cldfb_In_BinReal[1][sf_idx * MAX_PARAM_SPATIAL_SUBFRAMES], (float *) Cldfb_RealBuffer_Binaural_5ms[1], MAX_PARAM_SPATIAL_SUBFRAMES * CLDFB_NO_CHANNELS_MAX ); + mvr2r( (float *) Cldfb_In_BinImag[0][sf_idx * MAX_PARAM_SPATIAL_SUBFRAMES], (float *) Cldfb_ImagBuffer_Binaural_5ms[0], MAX_PARAM_SPATIAL_SUBFRAMES * CLDFB_NO_CHANNELS_MAX ); + mvr2r( (float *) Cldfb_In_BinImag[1][sf_idx * MAX_PARAM_SPATIAL_SUBFRAMES], (float *) Cldfb_ImagBuffer_Binaural_5ms[1], MAX_PARAM_SPATIAL_SUBFRAMES * CLDFB_NO_CHANNELS_MAX ); + isar_rend_CldfbSplitPostRendProcess( hBinHrSplitPreRend->hBinHrSplitPostRend, pMultiBinPoseData, QuaternionsPost[0], Cldfb_RealBuffer_Binaural_5ms, Cldfb_ImagBuffer_Binaural_5ms, tmpCrendBuffer, 1 ); + + { + float *pOut[2]; + char fname[200] = "ref_act_pos.wav"; + pOut[0] = tmpCrendBuffer[0]; + pOut[1] = tmpCrendBuffer[1]; + dbgwrite_wav( pOut, CLDFB_NO_COL_MAX * hBinHrSplitPreRend->hBinHrSplitPostRend->cldfbSyn[0]->no_channels, fname, 48000, 2 ); + } + } +#endif + + pop_wmops(); + return; +} + + +/*------------------------------------------------------------------------- + * Function isar_splitBinPreRendOpen() + * + * + *------------------------------------------------------------------------*/ + +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 +) +{ + ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinRend; +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + ivas_error error; + int16_t ch; +#endif + int16_t pos_idx, sf_idx, bandIdx; + + 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" ) ); + } + +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + for ( int16_t i = 0; i < MAX_HEAD_ROT_POSES + 1; i++ ) + { + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + hBinRend->cldfbSynRotBinDec[i][ch] = NULL; + } + } + + for ( int16_t i = 0; i < MAX_HEAD_ROT_POSES + 1; i++ ) + { + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + if ( ( error = openCldfb( &( hBinRend->cldfbSynRotBinDec[i][ch] ), CLDFB_SYNTHESIS, output_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) + { + return error; + } + } + } +#endif + + 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 ( bandIdx = 0; bandIdx < MAX_SPLIT_REND_MD_BANDS; bandIdx++ ) + { + hBinRend->rot_md[pos_idx][sf_idx][bandIdx].gd = 0.0f; + } + } + } + + set_fix_rotation_mat( hBinRend->fix_pos_rot_mat, pMultiBinPoseData ); + + set_pose_types( hBinRend->pose_type, pMultiBinPoseData ); + + isar_split_rend_init_huff_cfg( &hBinRend->huff_cfg ); + +#ifdef SPLIT_POSE_CORRECTION_DEBUG + ivas_error error; + if ( ( error = isar_splitBinPostRendOpen( &hBinRend->hBinHrSplitPostRend, pMultiBinPoseData, 48000 ) ) != IVAS_ERR_OK ) + { + return error; + } +#endif + + *hBinHrSplitPreRend = hBinRend; + + return IVAS_ERR_OK; +} + + +/*------------------------------------------------------------------------- + * Function isar_splitBinPreRendClose() + * + * + *------------------------------------------------------------------------*/ + +void isar_splitBinPreRendClose( + ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE *hBinHrSplitPreRend ) +{ + if ( ( *hBinHrSplitPreRend ) != NULL ) + { +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + { + int16_t i, n; + for ( i = 0; i < MAX_HEAD_ROT_POSES + 1; i++ ) + { + for ( n = 0; n < BINAURAL_CHANNELS; n++ ) + { + if ( ( *hBinHrSplitPreRend )->cldfbSynRotBinDec[i][n] != NULL ) + { + deleteCldfb( &( ( *hBinHrSplitPreRend )->cldfbSynRotBinDec[i][n] ) ); + ( *hBinHrSplitPreRend )->cldfbSynRotBinDec[i][n] = NULL; + } + } + } + } +#endif +#ifdef SPLIT_POSE_CORRECTION_DEBUG + isar_splitBinPostRendClose( &( *hBinHrSplitPreRend )->hBinHrSplitPostRend ); +#endif + + free( ( *hBinHrSplitPreRend ) ); + ( *hBinHrSplitPreRend ) = NULL; + } + + return; +} + + +/*-------------------------------------------------------------------------* + * isar_set_split_rend_ht_setup() + * + * + *-------------------------------------------------------------------------*/ + +void isar_set_split_rend_ht_setup( + SPLIT_REND_WRAPPER *hSplitrend, + IVAS_QUATERNION Quaternions[MAX_PARAM_SPATIAL_SUBFRAMES], + float Rmat[MAX_PARAM_SPATIAL_SUBFRAMES][3][3] ) +{ + int16_t sf, i, j; + if ( hSplitrend->multiBinPoseData.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) + { + for ( sf = 1; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ ) + { + Quaternions[sf] = Quaternions[0]; + + for ( i = 0; i < 3; i++ ) + { + for ( j = 0; j < 3; j++ ) + { + Rmat[sf][i][j] = Rmat[0][i][j]; + } + } + } + } + + return; +} + + +/*------------------------------------------------------------------------- + * Function isar_init_split_rend_handles() + * + * + *------------------------------------------------------------------------*/ + +void isar_init_split_rend_handles( + SPLIT_REND_WRAPPER *hSplitRendWrapper ) +{ + int16_t i; + + hSplitRendWrapper->hBinHrSplitPreRend = NULL; + hSplitRendWrapper->hCldfbHandles = NULL; + hSplitRendWrapper->hSplitBinLCLDEnc = NULL; + hSplitRendWrapper->hLc3plusEnc = NULL; + + for ( i = 0; i < MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS; ++i ) + { + hSplitRendWrapper->lc3plusDelayBuffers[i] = NULL; + } + hSplitRendWrapper->lc3plusDelaySamples = 0; + + isar_init_multi_bin_pose_data( &hSplitRendWrapper->multiBinPoseData ); + + return; +} + +/*------------------------------------------------------------------------- + * Function split_renderer_open_lc3plus() + * + * + *------------------------------------------------------------------------*/ + +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 isar_frame_size +#else + const int16_t num_subframes +#endif +) +{ + ivas_error error; + int16_t i, delayBufferLength; + LC3PLUS_CONFIG config; +#if defined ISAR_BITSTREAM_UPDATE_LC3PLUS + int16_t isar_frame_size_ms; + + if ( ( error = isar_framesize_to_ms( isar_frame_size, &isar_frame_size_ms ) ) != IVAS_ERR_OK ) + { + return error; + } +#endif + +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + /* Check configuration validity */ + if ( isar_frame_size_ms < pSplitRendConfig->codec_frame_size_ms ) + { + return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "SR codec frame doesn't fit in one output frame" ); + } +#endif + + 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; +#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 + config.channels = BINAURAL_CHANNELS; + + if ( ( error = ISAR_LC3PLUS_ENC_Open( config, +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + isar_get_lcld_bitrate( pSplitRendConfig->splitRendBitRate, pSplitRendConfig->poseCorrectionMode ), +#else + isar_get_lc3plus_bitrate( pSplitRendConfig->splitRendBitRate, pSplitRendConfig->poseCorrectionMode, (int16_t) ( config.isar_frame_duration_us / 1000 ) ), +#endif + &hSplitRendWrapper->hLc3plusEnc ) ) != IVAS_ERR_OK ) + { + return error; + } + + /* This returns delay of entire LC3plus chain (enc + dec) */ + 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 ) + { + delayBufferLength = (int16_t) ( 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 ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for multiBinPoseData handle\n" ) ); + } + + set_zero( hSplitRendWrapper->lc3plusDelayBuffers[i], delayBufferLength ); + } + } + 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 ) + { + 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 ); + } + } + + return IVAS_ERR_OK; +} + + +/*------------------------------------------------------------------------- + * Function splitRendLc3plusEncodeAndWrite() + * + * + *------------------------------------------------------------------------*/ + +ivas_error splitRendLc3plusEncodeAndWrite( + SPLIT_REND_WRAPPER *hSplitBin, + ISAR_SPLIT_REND_BITS_HANDLE pBits, +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + const int32_t available_bits, +#endif +#else + const int32_t SplitRendBitRate, +#endif + float *in[] ) +{ + ivas_error error; + int16_t i; + int32_t lc3plusBitstreamSize; + float *channel_ptrs[MAX_HEAD_ROT_POSES * 2]; + assert( hSplitBin->hLc3plusEnc != NULL ); + + /* Find next byte boundary and zero-pad to it */ + while ( pBits->bits_written % 8 != 0 ) + { + ISAR_SPLIT_REND_BITStream_write_int32( pBits, 0L, 1 ); + } + + for ( i = 0; i < BINAURAL_CHANNELS * hSplitBin->multiBinPoseData.num_poses; ++i ) + { + channel_ptrs[i] = in[i]; + } + +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + if ( ( error = IVAS_LC3PLUS_ENC_SetBitrate( hSplitBin->hLc3plusEnc, available_bits * FRAMES_PER_SEC ) ) != IVAS_ERR_OK ) + { + return error; + } +#endif + + if ( ( error = ISAR_LC3PLUS_ENC_GetOutputBitstreamSize( hSplitBin->hLc3plusEnc, &lc3plusBitstreamSize ) ) != IVAS_ERR_OK ) + { + return error; + } + +#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 ) +#else + if ( ( error = ISAR_LC3PLUS_ENC_Encode( hSplitBin->hLc3plusEnc, channel_ptrs, &pBits->bits_buf[pBits->bits_written / 8] ) ) != IVAS_ERR_OK ) +#endif + { + return error; + } + + pBits->bits_written += 8 * lc3plusBitstreamSize; + pBits->codec = ISAR_SPLIT_REND_CODEC_LC3PLUS; + pBits->pose_correction = hSplitBin->multiBinPoseData.poseCorrectionMode; + pBits->codec_frame_size_ms = (int16_t) ( hSplitBin->hLc3plusEnc->config.lc3plus_frame_duration_us / 1000 ); +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + pBits->isar_frame_size_ms = (int16_t) ( hSplitBin->hLc3plusEnc->config.isar_frame_duration_us / 1000 ); +#endif + return IVAS_ERR_OK; +} + +/*------------------------------------------------------------------------- + * Function isar_renderMultiTDBinToSplitBinaural() + * + * + *------------------------------------------------------------------------*/ + +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, + 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 ) +{ + ivas_error error; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + int32_t bit_len, available_bits, target_md_bits; +#else + int32_t bit_len, available_bits, target_md_bits, actual_md_bits; +#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; + + push_wmops( "isar_renderMultiTDBinToSplitBinaural" ); + + error = IVAS_ERR_OK; + num_poses = hSplitBin->multiBinPoseData.num_poses; + + useLc3plus = hSplitBin->hLc3plusEnc != NULL; + + 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 ) + { + /* 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 ); + } + } + else + { + for ( i = 0; i < num_poses * BINAURAL_CHANNELS; ++i ) + { + in_delayed[i] = in[i]; + } + } + +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS + actual_md_bits = pBits->bits_written; +#endif + if ( ( hSplitBin->multiBinPoseData.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) || ( !useLc3plus && !pcm_out_flag ) ) + { + num_slots = ( hSplitBin->multiBinPoseData.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) ? CLDFB_NO_COL_MAX : ( hSplitBin->hSplitBinLCLDEnc->iNumBlocks * hSplitBin->hSplitBinLCLDEnc->iNumIterations ); + num_cldfb_bands = hSplitBin->hCldfbHandles->cldfbAna[0]->no_channels; + + /* CLDFB Analysis*/ + for ( pos_idx = 0; pos_idx < num_poses; pos_idx++ ) + { +#ifdef SPLIT_POSE_CORRECTION_DEBUG + { + float *pOut[2]; + char fname[200] = "ref_out_pos"; + char tag[2]; + tag[0] = (char) ( '0' + pos_idx ); + tag[1] = '\0'; + strcat( fname, tag ); + strcat( fname, ".wav" ); + + pOut[0] = in_delayed[2 * pos_idx]; + pOut[1] = in_delayed[2 * pos_idx + 1]; + dbgwrite_wav( pOut, CLDFB_NO_COL_MAX * max_bands, fname, 48000, 2 ); + } + +#endif + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + 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] ); + } + } + } + } + + 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 ); + } + + if ( 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 ) + { + available_bits = ( SplitRendBitRate * hSplitBin->hSplitBinLCLDEnc->iNumBlocks * hSplitBin->hSplitBinLCLDEnc->iNumIterations ) / ( 16 * FRAMES_PER_SEC ); +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + available_bits -= pBits->bits_written; +#else + actual_md_bits = pBits->bits_written - actual_md_bits; + available_bits -= actual_md_bits; +#endif + pBits->codec_frame_size_ms = codec_frame_size_ms; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + pBits->isar_frame_size_ms = isar_frame_size_ms; +#endif + + isar_splitBinLCLDEncProcess( hSplitBin->hSplitBinLCLDEnc, Cldfb_In_BinReal, Cldfb_In_BinImag, available_bits, pBits ); + } + 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 +#else + if ( ( error = splitRendLc3plusEncodeAndWrite( hSplitBin, pBits, SplitRendBitRate, in ) ) != IVAS_ERR_OK ) +#endif + { + return error; + } + } + } + else + { + pBits->pose_correction = hSplitBin->multiBinPoseData.poseCorrectionMode; + pBits->codec = ISAR_SPLIT_REND_CODEC_NONE; + } + + /*zero pad*/ + if ( pcm_out_flag ) + { + bit_len = SplitRendBitRate / FRAMES_PER_SEC; + } + else + { + if ( !useLc3plus ) + { + bit_len = ( SplitRendBitRate * hSplitBin->hSplitBinLCLDEnc->iNumBlocks * hSplitBin->hSplitBinLCLDEnc->iNumIterations ) / ( 16 * FRAMES_PER_SEC ); + } + else + { + bit_len = hSplitBin->hLc3plusEnc->config.isar_frame_duration_us / 1000; + bit_len = SplitRendBitRate * bit_len / 1000; + } + } + + while ( pBits->bits_written < bit_len ) + { + ISAR_SPLIT_REND_BITStream_write_int32( pBits, 0L, 1 ); + } + + pop_wmops(); + + 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] ) +{ + 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; + + for ( pose = 0; pose < hSplitBin->multiBinPoseData.num_poses; ++pose ) + { + for ( ch = 0; ch < BINAURAL_CHANNELS; ++ch ) + { + bufRead = hSplitBin->lc3plusDelayBuffers[pose * BINAURAL_CHANNELS + ch]; + bufWrite = bufRead; + + /* Save last 2 columns for next frame */ + 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 ); + } + + /* Delay existing columns by 2 slots */ + 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 ); + } + + /* Fill 2 first columns from buffer */ + 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; + } + + /* Copy last 2 columns to buffer */ + 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; + } + } + } + + return; +} +#endif diff --git a/lib_isar/isar_splitRenderer_utils.c b/lib_isar/isar_splitRenderer_utils.c new file mode 100644 index 000000000..eff0ecdae --- /dev/null +++ b/lib_isar/isar_splitRenderer_utils.c @@ -0,0 +1,1289 @@ +/****************************************************************************************************** + + (C) 2022-2023 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. + +*******************************************************************************************************/ + +#include +#include "options.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT +#include +#include "ivas_prot.h" +#include "isar_rom_post_rend.h" +#include "lib_isar_post_rend.h" +#include "isar_prot.h" +#ifdef DEBUGGING +#include "debug.h" +#endif +#include "wmc_auto.h" + + +/*------------------------------------------------------------------------- + * Function isar_mat_mult_2by2_complex() + * + * + *------------------------------------------------------------------------*/ + +void isar_mat_mult_2by2_complex( + float in_re1[2][2], + float in_im1[2][2], + float in_re2[2][2], + float in_im2[2][2], + float out_re2[2][2], + float out_im2[2][2] ) +{ + int16_t i, j; + float tmp_re, tmp_im; + + for ( i = 0; i < 2; i++ ) + { + for ( j = 0; j < 2; j++ ) + { + IVAS_CMULT_FLOAT( in_re1[i][0], in_im1[i][0], in_re2[0][j], in_im2[0][j], tmp_re, tmp_im ); + out_re2[i][j] = tmp_re; + out_im2[i][j] = tmp_im; + + IVAS_CMULT_FLOAT( in_re1[i][1], in_im1[i][1], in_re2[1][j], in_im2[1][j], tmp_re, tmp_im ); + out_re2[i][j] += tmp_re; + out_im2[i][j] += tmp_im; + } + } + + return; +} + + +/*------------------------------------------------------------------------- + * Function ISAR_SPLIT_REND_BITStream_init() + * + * + *------------------------------------------------------------------------*/ + +void ISAR_SPLIT_REND_BITStream_init( + ISAR_SPLIT_REND_BITS_HANDLE pBits, + const int32_t buf_len_bytes, + uint8_t *pbuf ) +{ + pBits->bits_buf = pbuf; + pBits->buf_len = buf_len_bytes; + pBits->bits_read = 0; + pBits->bits_written = 0; + + return; +} + + +/*------------------------------------------------------------------------- + * Function isar_split_rend_huffman_dec_init_min_max_len() + * + * + *------------------------------------------------------------------------*/ + +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; + + codebook = p_huff_cfg->codebook; + + p_huff_cfg->min_len = p_huff_cfg->sym_len; + p_huff_cfg->max_len = 0; + + for ( i = 0; i < p_huff_cfg->sym_len; i++ ) + { + code_len = (int16_t) codebook[1]; + if ( p_huff_cfg->min_len > code_len ) + { + p_huff_cfg->min_len = code_len; + } + if ( p_huff_cfg->max_len < code_len ) + { + p_huff_cfg->max_len = code_len; + } + codebook = codebook + 3; + } + + return; +} + + +/*------------------------------------------------------------------------- + * Function is_idx_present() + * + * + *------------------------------------------------------------------------*/ + +static int16_t is_idx_present( + int16_t *idx_list, + const int16_t idx, + const int16_t len ) +{ + int16_t i; + + for ( i = 0; i < len; i++ ) + { + if ( idx_list[i] == idx ) + { + return 1; + } + } + + return 0; +} + + +/*------------------------------------------------------------------------- + * Function isar_split_huff_get_idx_trav_list() + * + * + *------------------------------------------------------------------------*/ + +static void isar_split_huff_get_idx_trav_list( + int16_t *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; + + for ( i = 0; i < p_huff_cfg->sym_len; i++ ) + { + idx_list[i] = -1; + } + + for ( i = 0; i < p_huff_cfg->sym_len; i++ ) + { + codebook = p_huff_cfg->codebook; + min_bits = p_huff_cfg->max_len; + min_idx = -1; + for ( j = 0; j < p_huff_cfg->sym_len; j++ ) + { + if ( ( min_bits >= codebook[1] ) && ( is_idx_present( idx_list, j, i + 1 ) == 0 ) ) + { + min_bits = codebook[1]; + min_idx = j; + } + codebook += 3; + } + idx_list[i] = min_idx; + } + + return; +} + + +/*------------------------------------------------------------------------- + * Function isar_split_rend_init_huff_cfg() + * + * + *------------------------------------------------------------------------*/ + +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].sym_len = ISAR_SPLIT_REND_PRED_31QUANT_PNTS; + 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 ) ); + + pHuff_cfg->pred[1].codebook = &isar_split_rend_huff_pred63_consts[0][0]; + pHuff_cfg->pred[1].sym_len = ISAR_SPLIT_REND_PRED_63QUANT_PNTS; + 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 ) ); + + + pHuff_cfg->pred_roll.codebook = &isar_split_rend_huff_roll_pred_consts[0][0]; + pHuff_cfg->pred_roll.sym_len = ISAR_SPLIT_REND_ROLL_PRED_QUANT_PNTS; + 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 ) ); + + pHuff_cfg->gd.codebook = &isar_split_rend_huff_d_consts[0][0]; + pHuff_cfg->gd.sym_len = ISAR_SPLIT_REND_D_QUANT_PNTS; + 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 ) ); + + pHuff_cfg->p_gd.codebook = &isar_split_rend_huff_p_d_consts[0][0]; + pHuff_cfg->p_gd.sym_len = ISAR_SPLIT_REND_D_QUANT_PNTS; + 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 ) ); + + pHuff_cfg->p_gd_diff.codebook = &isar_split_rend_huff_p_d_diff_consts[0][0]; + pHuff_cfg->p_gd_diff.sym_len = ISAR_SPLIT_REND_D_QUANT_PNTS; + 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 ) ); + + return; +} + + +/*------------------------------------------------------------------------- + * Function set_fix_rotation_mat() + * + * + *------------------------------------------------------------------------*/ + +void set_fix_rotation_mat( + float fix_pos_rot_mat[][BINAURAL_CHANNELS][BINAURAL_CHANNELS], + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData ) +{ + float yaw_a, cos_yaw, sin_yaw; + int16_t pos_idx; + yaw_a = 0.0f; + + for ( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses - 1; pos_idx++ ) + { + yaw_a = pMultiBinPoseData->relative_head_poses[pos_idx + 1][0]; + cos_yaw = cosf( EVS_PI * yaw_a / 180.0f ); + sin_yaw = sinf( EVS_PI * yaw_a / 180.0f ); + sin_yaw = 0.0f; + fix_pos_rot_mat[pos_idx][0][0] = cos_yaw; + fix_pos_rot_mat[pos_idx][1][1] = cos_yaw; + fix_pos_rot_mat[pos_idx][0][1] = sin_yaw; + fix_pos_rot_mat[pos_idx][1][0] = -1.0f * sin_yaw; + } + + return; +} + + +/*------------------------------------------------------------------------- + * Function set_pose_types() + * + * + *------------------------------------------------------------------------*/ + +void set_pose_types( + ISAR_SPLIT_REND_POSE_TYPE pose_type[MAX_HEAD_ROT_POSES - 1], + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData ) +{ + int16_t pos_idx; + + for ( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses - 1; pos_idx++ ) + { + if ( fabs( pMultiBinPoseData->relative_head_poses[pos_idx + 1][0] ) > EPSILON ) + { + pose_type[pos_idx] = ANY_YAW; + } + else if ( fabs( pMultiBinPoseData->relative_head_poses[pos_idx + 1][2] ) > EPSILON ) + { + pose_type[pos_idx] = ANY_ROLL; + } + else + { + pose_type[pos_idx] = PITCH_ONLY; + } + } + + return; +} + + +/*------------------------------------------------------------------------- + * Function wrap_a() + * + * + *------------------------------------------------------------------------*/ + +int16_t wrap_a( + int16_t val, + const int16_t min_val, + const int16_t max_val ) +{ + if ( val < min_val ) + { + val = max_val - min_val + val + 1; + } + + if ( val > max_val ) + { + val = min_val + val - max_val - 1; + } + + return val; +} + + +/*------------------------------------------------------------------------- + * Function isar_SplitRenderer_getdiagdiff() + * + * + *------------------------------------------------------------------------*/ + +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 ) +{ + out_idx[0][0] = in_idx[0][0]; + out_idx[0][1] = in_idx[0][1]; + out_idx[1][1] = in_idx[1][1] + sign * out_idx[0][0]; + 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]; + out_idx[1][0] = wrap_a( out_idx[1][0], min_val, max_val ); + + return; +} + + +/*------------------------------------------------------------------------- + * Function ISAR_SPLIT_REND_BITStream_read_int32() + * + * + *------------------------------------------------------------------------*/ + +int32_t ISAR_SPLIT_REND_BITStream_read_int32( + ISAR_SPLIT_REND_BITS_HANDLE pBits, + const int32_t bits ) +{ + int32_t val, k, bit_val; + +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + assert( ( pBits->bits_written - pBits->bits_read ) >= bits ); + assert( bits <= 32 ); +#endif + + /* write bit by bit */ + val = 0; + for ( k = 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++; + } + + return val; +} + + +/*------------------------------------------------------------------------- + * Function ISAR_SPLIT_REND_BITStream_write_int32() + * + * + *------------------------------------------------------------------------*/ + +void ISAR_SPLIT_REND_BITStream_write_int32( + ISAR_SPLIT_REND_BITS_HANDLE pBits, + const int32_t val, + const int32_t bits ) +{ + int32_t mask, k; + +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + /*protection check*/ + if ( ( pBits->buf_len << 3 ) < ( pBits->bits_written + bits ) ) + { + assert( 0 ); + } +#endif + + mask = 1 << ( bits - 1 ); + /* write bit by bit */ + for ( k = 0; k < bits; k++ ) + { + if ( val & mask ) + { + pBits->bits_buf[pBits->bits_written >> 3] |= ( 1 << ( pBits->bits_written & 7 ) ); + } + else + { + pBits->bits_buf[pBits->bits_written >> 3] &= ~( 1 << ( pBits->bits_written & 7 ) ); + } + pBits->bits_written++; + mask >>= 1; + } + + return; +} + + +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG +/*------------------------------------------------------------------------- + * isar_log_cldfb2wav_data() + * + * + *------------------------------------------------------------------------*/ + +void isar_log_cldfb2wav_data( + float Cldfb_In_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + float Cldfb_In_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + HANDLE_CLDFB_FILTER_BANK *cldfbSyn, + const int16_t num_chs, + const int16_t num_freq_bands, + const int32_t output_Fs, + const int16_t num_slots, + const int16_t start_slot_idx, + const char *filename ) +{ + float *RealBuffer[CLDFB_NO_COL_MAX]; + float *ImagBuffer[CLDFB_NO_COL_MAX]; + float pcm_out[BINAURAL_CHANNELS][L_FRAME48k]; + float *pPcm[BINAURAL_CHANNELS]; + float Cldfb_local_Real[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + float Cldfb_local_Imag[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + int16_t sf, ch; + + assert( num_chs <= BINAURAL_CHANNELS ); + for ( ch = 0; ch < num_chs; ch++ ) + { + for ( sf = start_slot_idx; sf < start_slot_idx + num_slots; sf++ ) + { + mvr2r( Cldfb_In_Real[ch][sf], Cldfb_local_Real[ch][sf], num_freq_bands ); + mvr2r( Cldfb_In_Imag[ch][sf], Cldfb_local_Imag[ch][sf], num_freq_bands ); + RealBuffer[sf - start_slot_idx] = Cldfb_local_Real[ch][sf]; + ImagBuffer[sf - start_slot_idx] = Cldfb_local_Imag[ch][sf]; + } + cldfbSynthesis( RealBuffer, ImagBuffer, &( pcm_out[ch][0] ), num_freq_bands * num_slots, cldfbSyn[ch] ); + pPcm[ch] = pcm_out[ch]; + } + dbgwrite_wav( pPcm, num_freq_bands * num_slots, filename, output_Fs, num_chs ); + + return; +} +#endif + + +/*------------------------------------------------------------------------- + * Function isar_get_split_rend_md_target_brate() + * + * + *------------------------------------------------------------------------*/ + +int32_t isar_get_split_rend_md_target_brate( + const int32_t SplitRendBitRate, + const int16_t pcm_out_flag ) +{ + int32_t md_bitrate; + + if ( pcm_out_flag == 1 ) + { + md_bitrate = SplitRendBitRate; + } + else + { + switch ( SplitRendBitRate ) + { + case SPLIT_REND_768k: + { + md_bitrate = 256000; + break; + } + case SPLIT_REND_512k: + { + md_bitrate = 128000; + break; + } + case SPLIT_REND_384k: + { + md_bitrate = 128000; + break; + } + default: + { + return -1; + } + } + } + + return md_bitrate; +} + + +/*------------------------------------------------------------------------- + * Function isar_get_lcld_bitrate() + * + * + *------------------------------------------------------------------------*/ + +int32_t isar_get_lcld_bitrate( + const int32_t SplitRendBitRate, + const ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode ) +{ + if ( poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) + { + switch ( SplitRendBitRate ) + { + case SPLIT_REND_768k: + { + return IVAS_512k; + } + case SPLIT_REND_512k: + { + return IVAS_384k; + } + case SPLIT_REND_384k: + { + return IVAS_256k; + } + default: + { + assert( 0 ); + } + } + } + else + { + return SplitRendBitRate; + } + + return -1; +} + + +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS +/*------------------------------------------------------------------------- + * Function isar_get_lc3plus_bitrate() + * + * + *------------------------------------------------------------------------*/ + +int32_t isar_get_lc3plus_bitrate( + const int32_t SplitRendBitRate, + ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode, + const int16_t split_prerender_frame_size_ms ) +{ + if ( 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; + } + + if ( poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) + { + return SplitRendBitRate; + } + + /* Should not be reached */ + assert( 0 ); + return -1; +} + + +/*------------------------------------------------------------------------- + * Function isar_get_lc3plus_bitrate_id() + * + * + *------------------------------------------------------------------------*/ + +int8_t isar_get_lc3plus_bitrate_id( + const int32_t SplitRendBitRate ) +{ + switch ( SplitRendBitRate ) + { + case SPLIT_REND_768k: + { + return 4; + } + case SPLIT_REND_512k: + { + return 3; + } + case SPLIT_REND_384k: + { + return 2; + } + case SPLIT_REND_320k: + { + return 1; + } + case SPLIT_REND_256k: + { + return 0; + } + default: + { + break; + } + } + + return -1; +} + + +/*------------------------------------------------------------------------- + * Function isar_get_lc3plus_size_from_id() + * + * + *------------------------------------------------------------------------*/ + +int32_t isar_get_lc3plus_size_from_id( + const int8_t SplitRendBitRateId, + const ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode, + const int16_t split_prerender_frame_size_ms ) +{ + int32_t bitrate; + + switch ( SplitRendBitRateId ) + { + case 4: + { + bitrate = SPLIT_REND_768k; + break; + } + case 3: + { + bitrate = SPLIT_REND_512k; + break; + } + case 2: + { + bitrate = SPLIT_REND_384k; + break; + } + case 1: + { + bitrate = SPLIT_REND_320k; + break; + } + case 0: + { + bitrate = SPLIT_REND_256k; + break; + } + default: + { + bitrate = -1; + 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 ); +} +#endif + + +/*------------------------------------------------------------------------- + * Function isar_split_rend_validate_config() + * + * + *------------------------------------------------------------------------*/ + +ivas_error isar_split_rend_validate_config( + const ISAR_SPLIT_REND_CONFIG_DATA *pSplitRendConfig, + const int16_t is_pcm_out ) +{ + /* Valid DOF range is 0-3 */ + if ( pSplitRendConfig->dof < 0 || 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 ) + { + 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 ) ) + { + 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 ( 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 ) + { + 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 ) ) + { + return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "Invalid framing for LC3plus codec" ); + } + } + + /* Validate bitrate */ + if ( is_pcm_out == 0 ) + { + switch ( pSplitRendConfig->splitRendBitRate ) + { + case SPLIT_REND_256k: + if ( 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; + case SPLIT_REND_320k: + /* Only valid with 0 DOF */ + if ( 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; + case SPLIT_REND_384k: + case SPLIT_REND_512k: +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + case SPLIT_REND_768k: +#endif + /* Always valid */ + break; +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS + case SPLIT_REND_768k: + if ( pSplitRendConfig->dof == 0 && 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; +#endif + default: + return IVAS_ERR_LC3PLUS_INVALID_BITRATE; + } + } + else + { + if ( pSplitRendConfig->dof == 1 ) + { +#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + if ( pSplitRendConfig->splitRendBitRate < 34000 ) + { + return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "1DOF metadata needs atleast 34 kbps" ); + } +#else + if ( pSplitRendConfig->splitRendBitRate < 50000 ) + { + return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "1DOF metadata needs atleast 50 kbps" ); + } +#endif + } + else if ( 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" ); + } +#else + if ( pSplitRendConfig->splitRendBitRate < 66000 ) + { + return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "2DOF metadata needs atleast 66 kbps" ); + } +#endif + } + else if ( 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" ); + } +#else + if ( pSplitRendConfig->splitRendBitRate < 128000 ) + { + return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "3DOF metadata needs atleast 128 kbps" ); + } +#endif + } + } + + return IVAS_ERR_OK; +} + + +/*------------------------------------------------------------------------- + * Function isar_split_rend_get_quant_params() + * + * + *------------------------------------------------------------------------*/ + +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], +#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 q; + + *num_quant_strats = ISAR_SPLIT_REND_NUM_QUANT_STRATS; +#ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + *num_complex_bands = COMPLEX_MD_BAND_THRESH_LOW; + 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++ ) + { + 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; + } + + for ( q = 0; q < *num_quant_strats; q++ ) + { + pred_real_bands_yaw[q] = num_md_bands; + pred_real_bands_roll[q] = num_md_bands; + } + +#ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + pred_imag_bands_yaw[0] = num_md_bands; + pred_imag_bands_roll[0] = num_md_bands; + pred_imag_bands_yaw[1] = num_md_bands; + pred_imag_bands_roll[1] = num_md_bands; + 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_roll[q] = *num_complex_bands; + } +#else + if ( ro_flag ) + { + for ( q = 0; q < *num_quant_strats; q++ ) + { + pred_imag_bands_yaw[q] = SPLIT_REND_RO_MD_BAND_THRESH; + } + } + else + { + for ( q = 0; q < *num_quant_strats - 2; q++ ) + { + pred_imag_bands_yaw[q] = num_md_bands; + } + pred_imag_bands_yaw[( *num_quant_strats - 2 )] = COMPLEX_MD_BAND_THRESH_HIGH; + pred_imag_bands_yaw[( *num_quant_strats - 1 )] = COMPLEX_MD_BAND_THRESH_LOW; + } + + for ( q = 0; q < *num_quant_strats; q++ ) + { + pred_imag_bands_roll[q] = SPLIT_REND_RO_MD_BAND_THRESH; + } +#endif + + for ( q = 0; q < *num_quant_strats; q++ ) + { + d_bands_yaw[q] = 0; + bands_pitch[q] = num_md_bands; + } + + return; +} + +#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS +/*------------------------------------------------------------------------- + * Function isar_renderSplitGetRot_axisNumBits() + * + * + *------------------------------------------------------------------------*/ + +int16_t isar_renderSplitGetRot_axisNumBits( + const int16_t dof ) +{ + int16_t num_bits; + if ( dof < 3 ) + { + num_bits = 2; + } + else + { + num_bits = 0; + } + return num_bits; +} + +/*------------------------------------------------------------------------- + * Function isar_renderSplitGetRot_axisFromCode() + * + * + *------------------------------------------------------------------------*/ + +ISAR_SPLIT_REND_ROT_AXIS isar_renderSplitGetRot_axisFromCode( + const int16_t dof, + const int16_t code ) +{ + ISAR_SPLIT_REND_ROT_AXIS rot_axis; + + if ( dof == 1 ) + { + rot_axis = (ISAR_SPLIT_REND_ROT_AXIS) code; + } + else if ( dof == 2 ) + { + if ( code == 0 ) + { + rot_axis = (ISAR_SPLIT_REND_ROT_AXIS) code; + } + else + { + rot_axis = (ISAR_SPLIT_REND_ROT_AXIS) ( code - 1 ) + YAW_PITCH; + } + } + else + { + rot_axis = (ISAR_SPLIT_REND_ROT_AXIS) DEFAULT_AXIS; + } + + return rot_axis; +} + +/*------------------------------------------------------------------------- + * Function isar_renderSplitGetCodeFromRot_axis() + * + * + *------------------------------------------------------------------------*/ + +int16_t isar_renderSplitGetCodeFromRot_axis( + const int16_t dof, + const ISAR_SPLIT_REND_ROT_AXIS rot_axis, + int16_t *num_bits ) +{ + int16_t code = 0; + if ( dof == 1 ) + { + code = (int16_t) rot_axis; + } + else if ( dof == 2 ) + { + if ( rot_axis == DEFAULT_AXIS ) + { + code = (int16_t) rot_axis; + } + else + { + code = (int16_t) ( rot_axis - YAW_PITCH ) + 1; + } + } + else + { + code = (int16_t) DEFAULT_AXIS; + } + *num_bits = isar_renderSplitGetRot_axisNumBits( dof ); + + return code; +} +#endif + +/*------------------------------------------------------------------------- + * Function isar_renderSplitGetMultiBinPoseData() + * + * + *------------------------------------------------------------------------*/ + +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 ) +{ + 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; + + 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; + } + + /* 0 DOF defaults */ + num_yaw_poses = 0; + num_pitch_poses = 0; + num_roll_poses = 0; + + /* 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; + + if ( pSplit_rend_config->dof == 1 ) + { + switch ( rot_axis ) + { + case DEFAULT_AXIS: + case YAW: + { + num_yaw_poses = SPLIT_REND_MAX_YAW_ONLY_POSES; + break; + } + case PITCH: + { + num_pitch_poses = SPLIT_REND_MAX_PITCH_ONLY_POSES; + break; + } + case ROLL: + { + num_roll_poses = SPLIT_REND_MAX_ROLL_ONLY_POSES; + break; + } + default: + { + assert( 0 && "unsupported rotation axis value" ); + } + } + } + else if ( pSplit_rend_config->dof == 2 ) + { + switch ( rot_axis ) + { + case DEFAULT_AXIS: +#ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + case YAW: + case PITCH: +#endif + case YAW_PITCH: + { + num_yaw_poses = SPLIT_REND_MAX_YAW_ONLY_POSES; + num_pitch_poses = SPLIT_REND_MAX_PITCH_ONLY_POSES; + break; + } +#ifndef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + case ROLL: +#endif + case YAW_ROLL: + { + num_yaw_poses = SPLIT_REND_MAX_YAW_ONLY_POSES; + num_roll_poses = SPLIT_REND_MAX_ROLL_ONLY_POSES; + break; + } + case PITCH_ROLL: + { + num_pitch_poses = SPLIT_REND_MAX_PITCH_ONLY_POSES; + num_roll_poses = SPLIT_REND_MAX_ROLL_ONLY_POSES; + break; + } + default: + { + assert( 0 && "unsupported rotation axis value" ); + } + } + } + else if ( pSplit_rend_config->dof == 3 ) + { + if ( 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; + num_yaw_poses = SPLIT_REND_MAX_YAW_ONLY_POSES; + num_pitch_poses = SPLIT_REND_MAX_PITCH_ONLY_POSES; + num_roll_poses = SPLIT_REND_MAX_ROLL_ONLY_POSES; + } + 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; + num_yaw_poses = SPLIT_REND_MAX_YAW_ONLY_POSES; + num_pitch_poses = 1; + num_roll_poses = 1; + } + } + + pMultiBinPoseData->num_poses = num_yaw_poses + num_pitch_poses + num_roll_poses + 1; + assert( pMultiBinPoseData->num_poses <= MAX_HEAD_ROT_POSES ); + + for ( pos_idx = 0; pos_idx < num_yaw_poses; pos_idx++ ) + { + pMultiBinPoseData->relative_head_poses[pos_idx + 1][0] = relative_yaw_angles[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]; + } + + 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->dof = pSplit_rend_config->dof; + pMultiBinPoseData->hq_mode = pSplit_rend_config->hq_mode; + pMultiBinPoseData->rot_axis = rot_axis; + pMultiBinPoseData->poseCorrectionMode = pSplit_rend_config->poseCorrectionMode; + + return; +} + + +/*------------------------------------------------------------------------- + * Function isar_renderSplitUpdateNoCorrectionPoseData() + * + * + *------------------------------------------------------------------------*/ + +void isar_renderSplitUpdateNoCorrectionPoseData( + const ISAR_SPLIT_REND_CONFIG_DATA *pSplit_rend_config, + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData ) +{ + pMultiBinPoseData->num_poses = 1; + assert( pSplit_rend_config->dof == 0 ); + pMultiBinPoseData->dof = pSplit_rend_config->dof; + assert( pSplit_rend_config->poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE ); + pMultiBinPoseData->poseCorrectionMode = pSplit_rend_config->poseCorrectionMode; + + return; +} + + +/*------------------------------------------------------------------------- + * Function isar_init_multi_bin_pose_data() + * + * + *------------------------------------------------------------------------*/ + +void isar_init_multi_bin_pose_data( + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData ) +{ + int16_t 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->num_poses = 1; + pMultiBinPoseData->dof = 3; + pMultiBinPoseData->hq_mode = 0; + pMultiBinPoseData->rot_axis = DEFAULT_AXIS; + + return; +} + +#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 */ +) +{ + switch ( frame_size ) + { + case IVAS_RENDER_FRAMESIZE_5MS: + *ms = 5; + break; + case IVAS_RENDER_FRAMESIZE_10MS: + *ms = 10; + break; + case IVAS_RENDER_FRAMESIZE_20MS: + *ms = 20; + break; + default: + return IVAS_ERROR( IVAS_ERR_INTERNAL, "Unsupported ISAR frame size" ); + } + + return IVAS_ERR_OK; +} +#endif + + +/*------------------------------------------------------------------------- + * Function isar_split_rend_choose_default_codec() + * + * + *------------------------------------------------------------------------*/ + +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 */ +#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 */ +) +{ + if ( pcm_out_flag == 0 ) + { + if ( *pCodec == ISAR_SPLIT_REND_CODEC_DEFAULT ) + { + *pCodec = cldfb_in_flag ? ISAR_SPLIT_REND_CODEC_LCLD : ISAR_SPLIT_REND_CODEC_LC3PLUS; + } + } + else + { + *pCodec = ISAR_SPLIT_REND_CODEC_NONE; + } + + if ( *pCodec_frame_size_ms == 0 ) /* codec frame size hasn't been set yet - use default for current configuration */ + { + switch ( *pCodec ) + { + case ISAR_SPLIT_REND_CODEC_LCLD: + *pCodec_frame_size_ms = num_subframes * 5; + break; + case ISAR_SPLIT_REND_CODEC_LC3PLUS: + case ISAR_SPLIT_REND_CODEC_NONE: + *pCodec_frame_size_ms = 5; + 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 */ + { + *pIsar_frame_size_ms = 20; + } +#endif + return IVAS_ERR_OK; +} + +/*-------------------------------------------------------------------* + * Function get_bit() + * + * + *-------------------------------------------------------------------*/ + +int32_t get_bit( + const int32_t state, + const int32_t bit_id ) +{ + return ( state & ( 1 << bit_id ) ); +} + +#endif diff --git a/lib_isar/isar_stat.h b/lib_isar/isar_stat.h new file mode 100644 index 000000000..1451cc7bf --- /dev/null +++ b/lib_isar/isar_stat.h @@ -0,0 +1,259 @@ +/****************************************************************************************************** + + (C) 2022-2023 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 ISAR_STAT_H +#define ISAR_STAT_H + + +#include +#include "options.h" +#include "stat_com.h" +#include "ivas_stat_com.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT +#include "isar_lcld_prot.h" +#include "isar_lc3plus_enc.h" +#include "isar_lc3plus_dec.h" +#include "isar_cnst.h" + + +/*-------------------------------------------------------------------* + * ISAR post rend constants + *-------------------------------------------------------------------*/ + +#define MAX_CLDFB_BUFFER_LENGTH_PER_CHANNEL ( MAX_BUFFER_LENGTH_PER_CHANNEL * 2 ) +#define MAX_CLDFB_BUFFER_LENGTH ( MAX_CLDFB_BUFFER_LENGTH_PER_CHANNEL * MAX_INPUT_CHANNELS ) +#define MAX_BIN_BUFFER_LENGTH ( MAX_BUFFER_LENGTH_PER_CHANNEL * BINAURAL_CHANNELS ) +#define MAX_CLDFB_BIN_BUFFER_LENGTH ( MAX_CLDFB_BUFFER_LENGTH_PER_CHANNEL * BINAURAL_CHANNELS ) + +/*-------------------------------------------------------------------* + * ISAR post rend structs + *-------------------------------------------------------------------*/ + +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]; + ISAR_SPLIT_REND_ROT_AXIS sr_pose_pred_axis; + +} ISAR_POST_REND_HeadRotData; + +typedef struct +{ +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + HANDLE_CLDFB_FILTER_BANK cldfbAna[( 1 + MAX_HEAD_ROT_POSES ) * BINAURAL_CHANNELS]; +#else + HANDLE_CLDFB_FILTER_BANK cldfbAna[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS]; +#endif + HANDLE_CLDFB_FILTER_BANK cldfbSyn[BINAURAL_CHANNELS]; + +} CLDFB_HANDLES_WRAPPER, *CLDFB_HANDLES_WRAPPER_HANDLE; + +typedef struct isar_split_rend_huffman_cfg_t +{ + const int32_t *codebook; + int16_t min_len; + int16_t max_len; + int16_t sym_len; + +} isar_split_rend_huffman_cfg_t; + +typedef struct isar_binaural_head_rot_split_rendering_huff_struct +{ + isar_split_rend_huffman_cfg_t pred[2]; + int16_t pred_idx_trav[2][ISAR_SPLIT_REND_PRED_63QUANT_PNTS]; + int16_t pred_base2_code_len[2]; + isar_split_rend_huffman_cfg_t pred_roll; + int16_t pred_roll_idx_trav[ISAR_SPLIT_REND_ROLL_PRED_QUANT_PNTS]; + int16_t pred_roll_base2_code_len; + isar_split_rend_huffman_cfg_t gd; + int16_t gd_base2_code_len; + int16_t gd_idx_trav[ISAR_SPLIT_REND_D_QUANT_PNTS]; + isar_split_rend_huffman_cfg_t p_gd; + int16_t p_gd_base2_code_len; + int16_t p_gd_idx_trav[ISAR_SPLIT_REND_D_QUANT_PNTS]; + isar_split_rend_huffman_cfg_t p_gd_diff; + int16_t p_gd_diff_base2_code_len; + int16_t p_gd_diff_idx_trav[ISAR_SPLIT_REND_D_QUANT_PNTS]; + +} ISAR_BIN_HR_SPLIT_REND_HUFF, *ISAR_BIN_HR_SPLIT_REND_HUFF_HANDLE; + +/* 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]; +#ifdef SPLIT_REND_POSE_CORRECTION_UNUSED_BITS + float pred_mat_re2[BINAURAL_CHANNELS]; +#endif + float gd; + float 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]; + 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; +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + HANDLE_CLDFB_FILTER_BANK cldfbSynRotBinDec[MAX_HEAD_ROT_POSES + 1][BINAURAL_CHANNELS]; +#endif + +#ifdef SPLIT_POSE_CORRECTION_DEBUG + BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend; +#endif + +} ISAR_BIN_HR_SPLIT_PRE_REND, *ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE; + +/*----------------------------------------------------------------------------------* + * Output configuration for renderer (e.g. DirAC, MASA, Binaural Renderer...) + *----------------------------------------------------------------------------------*/ + +typedef struct isar_binaural_head_rot_split_rendering_lcld_enc_struct +{ + void *pLcld_enc; + int16_t iChannels; + LCLDEncoder *psLCLDEncoder; + float ***pppfLCLDReal; + float ***pppfLCLDImag; +#ifdef CLDFB_DEBUG + FILE *cldfbIn; + int16_t numFrame; +#endif + int16_t iNumIterations; + int16_t 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; + +typedef struct +{ + ISAR_CLDFB_PLC CldfbPLC_state; + int16_t prev_bfi; + int16_t bf_count; + int16_t 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; + LCLDDecoder *psLCLDDecoder; + float ***pppfDecLCLDReal; + float ***pppfDecLCLDImag; +#ifdef CLDFB_DEBUG + FILE *cldfbOut; + int16_t numFrame; +#endif + ISAR_SPLIT_REND_PLC_HANDLE hSplitRendPLC; + + int16_t iNumBlocks; + int16_t 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]; + IVAS_QUATERNION QuaternionsPre[MAX_PARAM_SPATIAL_SUBFRAMES]; + int16_t low_Res; + + 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; +#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]; +#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]; +#endif + int16_t cf_flag; + HANDLE_CLDFB_FILTER_BANK cldfbAna[BINAURAL_CHANNELS]; + HANDLE_CLDFB_FILTER_BANK cldfbSyn[BINAURAL_CHANNELS]; +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + HANDLE_CLDFB_FILTER_BANK cldfbSynReconsBinDec[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS]; +#endif + +} ISAR_BIN_HR_SPLIT_POST_REND, *ISAR_BIN_HR_SPLIT_POST_REND_HANDLE; + +typedef struct +{ + int16_t num_poses; + float relative_head_poses[MAX_HEAD_ROT_POSES][3]; + int16_t dof; + int16_t hq_mode; + ISAR_SPLIT_REND_ROT_AXIS rot_axis; + ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode; + +} MULTI_BIN_REND_POSE_DATA; + +typedef struct +{ + MULTI_BIN_REND_POSE_DATA multiBinPoseData; + ISAR_BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend; + ISAR_BIN_HR_SPLIT_LCLD_DEC_HANDLE hSplitBinLCLDDec; + int16_t first_good_frame_received; + ISAR_LC3PLUS_DEC_HANDLE hLc3plusDec; + +} ISAR_SPLIT_POST_REND_WRAPPER; + +typedef struct +{ + MULTI_BIN_REND_POSE_DATA multiBinPoseData; + ISAR_BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend; + 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; + +} 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 new file mode 100644 index 000000000..af43d273e --- /dev/null +++ b/lib_isar/lib_isar_post_rend.c @@ -0,0 +1,1911 @@ +/****************************************************************************************************** + + (C) 2022-2023 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. + +*******************************************************************************************************/ + + +#include "options.h" +#include "lib_isar_post_rend.h" +#include "isar_stat.h" +#include "isar_prot.h" +#include "prot.h" +#include "ivas_prot.h" + +#ifndef SPLIT_REND_WITH_HEAD_ROT + +int32_t ISAR_POST_REND_void_func( void ) +{ + return 0; +} + +#else + +#include "ivas_prot_rend.h" +#include +#include +#include "wmc_auto.h" + + +/*-------------------------------------------------------------------* + * Local constants + *-------------------------------------------------------------------*/ + +/*-------------------------------------------------------------------* + * Local types + *-------------------------------------------------------------------*/ + +/* EFAP wrapper to simplify writing panning gains to a vector that includes LFE channels */ +typedef struct +{ + EFAP_HANDLE hEfap; + AUDIO_CONFIG speakerConfig; + const LSSETUP_CUSTOM_STRUCT *pCustomLsSetup; /* Pointer to main custom LS struct from renderer handle - doesn't need freeing */ +} EFAP_WRAPPER; + +/* Lightweight helper struct that gathers all information required for rendering + * any config to any other config. Used to simplify signatures of rendering functions. + * + * This struct should store ONLY CONST POINTERS to data existing elsewhere. + * Storing pointers instead of data itself ensures that no additional updates + * are required when any of these are changed in the renderer. Making the pointers + * const ensures that this data is only read, but not modified by the rendering functions. */ +typedef struct +{ + const int32_t *pOutSampleRate; + const AUDIO_CONFIG *pOutConfig; +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS + const LSSETUP_CUSTOM_STRUCT *pCustomLsOut; + const EFAP_WRAPPER *pEfapOutWrapper; +#endif + const ISAR_POST_REND_HeadRotData *pHeadRotData; +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS + const RENDER_CONFIG_HANDLE *hhRendererConfig; +#endif + const int16_t *pSplitRendBFI; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + const ISAR_SPLIT_REND_CONFIG_DATA *pSplitRenderConfig; +#endif +} rendering_context; + +/* Common base for input structs */ +typedef struct +{ + AUDIO_CONFIG inConfig; + ISAR_POST_REND_InputId id; + IVAS_REND_AudioBuffer inputBuffer; + float gain; /* 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; + +typedef struct +{ + input_base base; + ISAR_SPLIT_POST_REND_WRAPPER splitPostRendWrapper; + float *bufferData; + 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; + +struct ISAR_POST_REND +{ + int32_t sampleRateOut; + + IVAS_LIMITER_HANDLE hLimiter; +#ifdef DEBUGGING + int32_t numClipping; /* Counter of clipped output samples */ +#endif + + input_split_post_rend inputsSplitPost[RENDERER_MAX_BIN_INPUTS]; + + AUDIO_CONFIG inputConfig; + AUDIO_CONFIG outputConfig; + + ISAR_POST_REND_HeadRotData headRotData; + int16_t splitRendBFI; + + int8_t rendererConfigEnabled; + ISAR_SPLIT_REND_CONFIG_DATA splitRenderConfig; + + int16_t num_subframes; +}; + +/*-------------------------------------------------------------------* + * getAudioConfigType() + * + * + *-------------------------------------------------------------------*/ + +ISAR_POST_REND_AudioConfigType isar_getAudioConfigType( + const AUDIO_CONFIG config ) +{ + ISAR_POST_REND_AudioConfigType type; + + 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; + default: + type = ISAR_POST_REND_AUDIO_CONFIG_TYPE_UNKNOWN; + break; + } + + return type; +} + + +/*-------------------------------------------------------------------* + * Local function prototypes + *-------------------------------------------------------------------*/ + +/*-------------------------------------------------------------------* + * Local functions + *-------------------------------------------------------------------*/ + +static ivas_error allocateInputBaseBufferData( + float **data, + const int16_t data_size ) +{ + *data = (float *) malloc( data_size * sizeof( float ) ); + 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 ) +{ + if ( *data != NULL ) + { + free( *data ); + *data = NULL; + } + + return; +} + + +static IVAS_QUATERNION quaternionInit( + void ) +{ + IVAS_QUATERNION q; + q.w = 1.0f; + q.x = q.y = q.z = 0.0f; + return q; +} + +static void convertBitsBufferToInternalBitsBuff( + const ISAR_POST_REND_BitstreamBuffer outBits, + ISAR_SPLIT_REND_BITS_HANDLE hBits ) +{ + hBits->bits_buf = outBits.bits; + hBits->bits_read = outBits.config.bitsRead; + hBits->bits_written = outBits.config.bitsWritten; + hBits->buf_len = outBits.config.bufLenInBytes; + hBits->codec = outBits.config.codec; + hBits->pose_correction = outBits.config.poseCorrection; + hBits->codec_frame_size_ms = outBits.config.codec_frame_size_ms; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + hBits->isar_frame_size_ms = outBits.config.isar_frame_size_ms; + hBits->lc3plus_highres = outBits.config.lc3plusHighRes; +#endif + + return; +} + +static void convertInternalBitsBuffToBitsBuffer( + ISAR_POST_REND_BitstreamBuffer *hOutBits, + const ISAR_SPLIT_REND_BITS_DATA bits ) +{ + hOutBits->bits = bits.bits_buf; + hOutBits->config.bitsRead = bits.bits_read; + hOutBits->config.bitsWritten = bits.bits_written; + hOutBits->config.bufLenInBytes = bits.buf_len; + hOutBits->config.codec = bits.codec; + hOutBits->config.poseCorrection = bits.pose_correction; + hOutBits->config.codec_frame_size_ms = bits.codec_frame_size_ms; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + hOutBits->config.isar_frame_size_ms = bits.isar_frame_size_ms; + hOutBits->config.lc3plusHighRes = bits.lc3plus_highres; +#endif + + return; +} + +static void copyBufferTo2dArray( + const IVAS_REND_AudioBuffer buffer, + float array[][L_FRAME48k] ) +{ + uint32_t smplIdx; + uint32_t chnlIdx; + const float *readPtr; + + assert( ( buffer.config.is_cldfb == 0 ) && "for CLDFB input call copyBufferToCLDFBarray()" ); + readPtr = buffer.data; + + for ( chnlIdx = 0; chnlIdx < (uint32_t) buffer.config.numChannels; ++chnlIdx ) + { + for ( smplIdx = 0; smplIdx < (uint32_t) buffer.config.numSamplesPerChannel; ++smplIdx ) + { + array[chnlIdx][smplIdx] = *readPtr++; + } + } + + return; +} + +static void accumulate2dArrayToBuffer( + float array[][L_FRAME48k], + const IVAS_REND_AudioBuffer *buffer ) +{ + int16_t smplIdx, chnlIdx; + float *writePtr; + + writePtr = buffer->data; + for ( chnlIdx = 0; chnlIdx < buffer->config.numChannels; ++chnlIdx ) + { + for ( smplIdx = 0; smplIdx < buffer->config.numSamplesPerChannel; ++smplIdx ) + { + *writePtr++ += array[chnlIdx][smplIdx]; + } + } + + return; +} + +/*-------------------------------------------------------------------* + * limitRendererOutput() + * + * In-place saturation control for multichannel buffers with adaptive release time + *-------------------------------------------------------------------*/ + +#ifndef DISABLE_LIMITER +/*! r: number of clipped output samples */ +static int32_t limitRendererOutput( + 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 */ +) +{ + int16_t i; + float **channels; + int16_t num_channels; + int32_t numClipping = 0; + + /* return early if given bad parameters */ + if ( hLimiter == NULL || output == NULL || output_frame <= 0 ) + { + return 0; + } + + channels = hLimiter->channel_ptrs; + num_channels = hLimiter->num_channels; + + for ( i = 0; i < num_channels; ++i ) + { + channels[i] = output + i * output_frame; + } + + limiter_process( hLimiter, output_frame, threshold, 0, NULL ); + + /* Apply clipping to buffer in case the limiter let through some samples > 1.0f */ + 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 ); + } + + return numClipping; +} +#endif + + +/*-------------------------------------------------------------------* + * validateOutputSampleRate() + * + * + *-------------------------------------------------------------------*/ + +static ivas_error validateOutputSampleRate( + const int32_t sampleRate, + const AUDIO_CONFIG outConfig ) +{ + if ( ( outConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || outConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) && sampleRate != 48000 ) + { + return IVAS_ERROR( IVAS_ERR_INVALID_SAMPLING_RATE, "Error: Only 48kHz output sampling rate is supported for split rendering." ); + } + else + { + /* Otherwise rendering to binaural, support the same set as IVAS decoder */ + switch ( sampleRate ) + { + case 8000: + case 16000: + case 32000: + case 48000: + return IVAS_ERR_OK; + } + + return IVAS_ERR_INVALID_SAMPLING_RATE; + } +} + + +/*-------------------------------------------------------------------* + * Local functions + *-------------------------------------------------------------------*/ + +static ivas_error initLimiter( + IVAS_LIMITER_HANDLE *phLimiter, + const int16_t numChannels, + const int32_t sampleRate ) +{ + ivas_error error; + + /* If re-initializing with unchanged values, return early */ + 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 ) + { + ivas_limiter_close( phLimiter ); + } + + if ( ( error = ivas_limiter_open( phLimiter, numChannels, sampleRate ) ) != IVAS_ERR_OK ) + { + return error; + } + + return IVAS_ERR_OK; +} + + +static ivas_error initHeadRotation( + ISAR_POST_REND_HANDLE hIvasRend ) +{ + int16_t i, crossfade_len; + float 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++ ) + { + hIvasRend->headRotData.crossfade[i] = i * tmp; + } + + /* Initialize with unit quaternions */ + for ( i = 0; i < hIvasRend->num_subframes; ++i ) + { + hIvasRend->headRotData.headPositions[i] = quaternionInit(); + } + + hIvasRend->headRotData.sr_pose_pred_axis = DEFAULT_AXIS; + + return IVAS_ERR_OK; +} + + +static void initRendInputBase( + input_base *inputBase, + const AUDIO_CONFIG inConfig, + const IVAS_REND_InputId id, + const rendering_context rendCtx, + float *dataBuf, + const int16_t dataBufSize ) +{ + inputBase->inConfig = inConfig; + inputBase->id = id; + inputBase->gain = 1.0f; + 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 ) + { + set_zero( inputBase->inputBuffer.data, dataBufSize ); + } + + return; +} + + +static rendering_context getRendCtx( + ISAR_POST_REND_HANDLE hIvasRend ) +{ + rendering_context ctx; + + /* Note: when refactoring this, always take the ADDRESS of a member of the + * renderer struct, so that the context stores a POINTER to the member, even + * if the member is a pointer or handle itself. */ + ctx.pOutConfig = &hIvasRend->outputConfig; + ctx.pOutSampleRate = &hIvasRend->sampleRateOut; + ctx.pHeadRotData = &hIvasRend->headRotData; + ctx.pSplitRendBFI = &hIvasRend->splitRendBFI; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + ctx.pSplitRenderConfig = &hIvasRend->splitRenderConfig; +#endif + + return ctx; +} + + +static ivas_error getRendInputNumChannels( + const void *rendInput, + int16_t *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 */ + (void) rendInput; + + *numInChannels = 2; + + return IVAS_ERR_OK; +} + + +static ivas_error updateSplitPostRendPanGains( + input_split_post_rend *inputSplitPostRend, + const AUDIO_CONFIG outConfig, + ISAR_SPLIT_REND_CONFIG_DATA *hRendCfg +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS + , + int16_t num_subframes +#endif +) +{ + ivas_error error; + rendering_context rendCtx; + LC3PLUS_CONFIG config; + int16_t iNumBlocksPerFrame, iNumLCLDIterationsPerFrame; + + (void) outConfig; + + rendCtx = inputSplitPostRend->base.ctx; + isar_renderSplitGetMultiBinPoseData( hRendCfg, &inputSplitPostRend->splitPostRendWrapper.multiBinPoseData, rendCtx.pHeadRotData->sr_pose_pred_axis ); + +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + config.high_res_mode_enabled = ( hRendCfg->lc3plus_highres != 0 ); +#endif + config.lc3plus_frame_duration_us = hRendCfg->codec_frame_size_ms * 1000; +#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 ( 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; + } + else + { + config.isar_frame_duration_us = ( hRendCfg->poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) ? config.lc3plus_frame_duration_us : 20000; + } + iNumLCLDIterationsPerFrame = 1; + } + else + { + config.isar_frame_duration_us = 20000; + } +#endif + + if ( hRendCfg->codec_frame_size_ms > 0 ) + { + iNumLCLDIterationsPerFrame = (int16_t) 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 + { + iNumLCLDIterationsPerFrame = 1; + iNumBlocksPerFrame = CLDFB_NO_COL_MAX; + } + + config.channels = BINAURAL_CHANNELS; + config.samplerate = *inputSplitPostRend->base.ctx.pOutSampleRate; + + 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 ) + { + return error; + } + } + else if ( hRendCfg->codec == ISAR_SPLIT_REND_CODEC_LC3PLUS ) + { + 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 ) + { + return error; + } + + return IVAS_ERR_OK; +} + + +static ivas_error setRendInputActiveSplitPostRend( + void *input, + const AUDIO_CONFIG inConfig, + const IVAS_REND_InputId id, + ISAR_SPLIT_REND_CONFIG_DATA *hRendCfg +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS + , + const int16_t num_subframes +#endif +) +{ + ivas_error error; + rendering_context rendCtx; + AUDIO_CONFIG outConfig; + input_split_post_rend *inputSplitPostRend; + + inputSplitPostRend = (input_split_post_rend *) input; + rendCtx = inputSplitPostRend->base.ctx; + outConfig = *rendCtx.pOutConfig; + + if ( ( error = allocateInputBaseBufferData( &inputSplitPostRend->bufferData, MAX_CLDFB_BIN_BUFFER_LENGTH ) ) != IVAS_ERR_OK ) + { + return error; + } + + initRendInputBase( &inputSplitPostRend->base, inConfig, id, rendCtx, inputSplitPostRend->bufferData, MAX_CLDFB_BIN_BUFFER_LENGTH ); + inputSplitPostRend->numCachedSamples = 0; + + if ( ( error = updateSplitPostRendPanGains( inputSplitPostRend, outConfig, hRendCfg +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS + , + num_subframes +#endif + ) ) != IVAS_ERR_OK ) + { + return error; + } + + return IVAS_ERR_OK; +} + + +static void clearInputSplitRend( + input_split_post_rend *inputSplitRend ) +{ + rendering_context rendCtx; + + rendCtx = inputSplitRend->base.ctx; + + freeInputBaseBufferData( &inputSplitRend->bufferData ); + + initRendInputBase( &inputSplitRend->base, IVAS_AUDIO_CONFIG_INVALID, 0, rendCtx, NULL, 0 ); + + if ( inputSplitRend->splitPostRendWrapper.hBinHrSplitPostRend != NULL ) + { + isar_splitBinPostRendClose( &inputSplitRend->splitPostRendWrapper.hBinHrSplitPostRend ); + } + + if ( inputSplitRend->splitPostRendWrapper.hSplitBinLCLDDec != NULL ) + { + isar_splitBinLCLDDecClose( &inputSplitRend->splitPostRendWrapper.hSplitBinLCLDDec ); + } + + if ( inputSplitRend->splitPostRendWrapper.hLc3plusDec != NULL ) + { + ISAR_LC3PLUS_DEC_Close( &inputSplitRend->splitPostRendWrapper.hLc3plusDec ); + } + + return; +} + + +/*------------------------------------------------------------------------- + * ISAR_POST_REND_open() + * + * + *------------------------------------------------------------------------*/ + +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 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 */ +) +{ + int16_t i; + ISAR_POST_REND_HANDLE hIvasRend; + ivas_error error; + int16_t numOutChannels; + + (void) asHrtfBinary; + (void) nonDiegeticPan; + (void) nonDiegeticPanGain; + + /* Validate function arguments */ + if ( phIvasRend == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + if ( ( error = validateOutputSampleRate( outputSampleRate, outConfig ) ) != IVAS_ERR_OK ) + { + return error; + } + + *phIvasRend = (ISAR_POST_REND_HANDLE) malloc( sizeof( struct ISAR_POST_REND ) ); + if ( *phIvasRend == NULL ) + { + return IVAS_ERR_FAILED_ALLOC; + } + + hIvasRend = *phIvasRend; + hIvasRend->sampleRateOut = outputSampleRate; + hIvasRend->outputConfig = outConfig; + hIvasRend->hLimiter = NULL; + hIvasRend->num_subframes = 1; +#ifdef DEBUGGING + hIvasRend->numClipping = 0; +#endif + hIvasRend->num_subframes = num_subframes; + + /* Initialize limiter */ + if ( ( error = ISAR_POST_REND_NumOutChannels( hIvasRend, &numOutChannels ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( ( error = initLimiter( &hIvasRend->hLimiter, numOutChannels, outputSampleRate ) ) != IVAS_ERR_OK ) + { + return error; + } + + /* Initialize headrotation data */ + if ( ( error = initHeadRotation( hIvasRend ) ) != IVAS_ERR_OK ) + { + return error; + } + + /* Initialize inputs */ + + for ( i = 0; i < RENDERER_MAX_BIN_INPUTS; ++i ) + { + initRendInputBase( &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; + } + + 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 */ +) +{ + /* Validate function arguments */ + if ( hIvasRend == NULL || numOutChannels == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + *numOutChannels = 2; + + return IVAS_ERR_OK; +} + + +static IVAS_REND_InputId makeInputId( + AUDIO_CONFIG config, + const int32_t 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 ) ); +} + + +static ivas_error getInputById( + ISAR_POST_REND_HANDLE hIvasRend, + const IVAS_REND_InputId inputId, + void **ppInput ) +{ + int32_t inputIndex; + IVAS_REND_AudioConfigType configType; + input_base *pInputBase; + + /* Reverse makeInputId() */ + inputIndex = ( inputId & 0xFF ) - 1; + configType = ( inputId & 0xFF00 ) >> 8; + + /* Validate values derived from input ID */ + if ( inputIndex < 0 ) + { + return IVAS_ERR_INVALID_INPUT_ID; + } + switch ( configType ) + { + case ISAR_POST_REND_AUDIO_CONFIG_TYPE_BINAURAL: + if ( inputIndex > RENDERER_MAX_BIN_INPUTS ) + { + return IVAS_ERR_INVALID_INPUT_ID; + } + pInputBase = &hIvasRend->inputsSplitPost[inputIndex].base; + 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 ) + { + return IVAS_ERR_INVALID_INPUT_ID; + } + + /* Validation done, set value via output parameter */ + *ppInput = pInputBase; + + return IVAS_ERR_OK; +} + +/*-------------------------------------------------------------------* + * ISAR_POST_REND_SetInputGain() + * + * + *-------------------------------------------------------------------*/ + +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) */ +) +{ + input_base *inputBase; + ivas_error error; + + /* Validate function arguments */ + if ( hIvasRend == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + if ( ( error = getInputById( hIvasRend, inputId, (void **) &inputBase ) ) != IVAS_ERR_OK ) + { + printf( "Hoo\n" ); + return error; + } + + inputBase->gain = gain; + + return IVAS_ERR_OK; +} + +static ivas_error getConstInputById( + ISAR_POST_REND_CONST_HANDLE hIvasRend, + const ISAR_POST_REND_InputId inputId, + const void **ppInput ) +{ + int32_t inputIndex; + IVAS_REND_AudioConfigType configType; + const input_base *pInputBase; + + /* Reverse makeInputId() */ + inputIndex = ( inputId & 0xFF ) - 1; + configType = ( inputId & 0xFF00 ) >> 8; + + /* Validate values derived from input ID */ + if ( inputIndex < 0 ) + { + return IVAS_ERR_INVALID_INPUT_ID; + } + switch ( configType ) + { + case ISAR_POST_REND_AUDIO_CONFIG_TYPE_BINAURAL: + if ( inputIndex > RENDERER_MAX_BIN_INPUTS ) + { + return IVAS_ERR_INVALID_INPUT_ID; + } + pInputBase = &hIvasRend->inputsSplitPost[inputIndex].base; + 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 ) + { + return IVAS_ERR_INVALID_INPUT_ID; + } + + /* Validation done, set value via output parameter */ + *ppInput = pInputBase; + + return IVAS_ERR_OK; +} + + +static ivas_error findFreeInputSlot( + const void *inputs, + const int32_t inputStructSize, + const int32_t maxInputs, + int32_t *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). + Assumptions: + - input_base is always the first member in the input struct + - provided size is correct + */ + + int32_t i; + bool canAddInput; + const uint8_t *pByte; + const input_base *pInputBase; + + canAddInput = false; + + /* Find first unused input in array */ + for ( i = 0, pByte = inputs; i < maxInputs; ++i, pByte += inputStructSize ) + { + pInputBase = (const input_base *) pByte; + + if ( pInputBase->inConfig == IVAS_AUDIO_CONFIG_INVALID ) + { + *inputIndex = i; + canAddInput = true; + break; + } + } + + if ( !canAddInput ) + { + return IVAS_ERR_TOO_MANY_INPUTS; + } + + return IVAS_ERR_OK; +} + + +/*-------------------------------------------------------------------* + * ISAR_POST_REND_AddInput() + * + * + *-------------------------------------------------------------------*/ + +ivas_error ISAR_POST_REND_AddInput( + ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + const IVAS_AUDIO_CONFIG inConfig, /* i : audio config for a new input */ + ISAR_POST_REND_InputId *inputId /* o : ID of the new input */ +) +{ + ivas_error error; + int32_t maxNumInputsOfType; + void *inputsArray; + int32_t 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; + + /* Validate function arguments */ + if ( hIvasRend == NULL || inputId == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + 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; + 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 ) + { + return error; + } + + *inputId = makeInputId( inConfig, inputIndex ); + if ( ( error = activateInput( (uint8_t *) inputsArray + inputStructSize * inputIndex, inConfig, *inputId, &hIvasRend->splitRenderConfig +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS + , + hIvasRend->num_subframes +#endif + ) ) != IVAS_ERR_OK ) + { + return error; + } + + return IVAS_ERR_OK; +} + + +/*-------------------------------------------------------------------* + * ISAR_POST_REND_GetInputNumChannels() + * + * + *-------------------------------------------------------------------*/ + +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 */ +) +{ + ivas_error error; + const input_base *pInput; + + /* Validate function arguments */ + if ( hIvasRend == NULL || numChannels == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + if ( ( error = getConstInputById( hIvasRend, inputId, (const void **) &pInput ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( ( error = getRendInputNumChannels( pInput, numChannels ) ) != IVAS_ERR_OK ) + { + return error; + } + + return IVAS_ERR_OK; +} + + +/*-------------------------------------------------------------------* + * ISAR_POST_REND_GetDelay() + * + * + *-------------------------------------------------------------------*/ + +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 */ +) +{ + int16_t i; + int32_t latency_ns; + int32_t max_latency_ns; + + /* Validate function arguments */ + if ( hIvasRend == NULL || nSamples == NULL || timeScale == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + *timeScale = hIvasRend->sampleRateOut; + *nSamples = 0; + 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 ) + { + 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 ); + } + } + + *nSamples = (int16_t) roundf( (float) max_latency_ns * *timeScale / 1000000000.f ); + + 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 */ + const ISAR_POST_REND_ReadOnlyAudioBuffer inputAudio /* i : buffer with input audio */ +) +{ + ivas_error error; + input_base *inputBase; + int16_t numInputChannels; + int16_t cldfb2tdSampleFact; + + /* Validate function arguments */ + if ( hIvasRend == NULL || inputAudio.data == 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 ) ) + { + 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 ) + { + 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 ) + { + return IVAS_ERROR( IVAS_ERR_INVALID_BUFFER_SIZE, "Binaural rendering requires specific frame size" ); + } + + if ( ( error = getInputById( hIvasRend, inputId, (void **) &inputBase ) ) != IVAS_ERR_OK ) + { + printf( "Foo\n" ); + return error; + } + + if ( ( error = getRendInputNumChannels( inputBase, &numInputChannels ) ) != IVAS_ERR_OK ) + { + return error; + } + + 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 ); + + 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 */ +) +{ + bool rendererConfigEnabled; + + rendererConfigEnabled = ( isar_getAudioConfigType( outAudioConfig ) == ISAR_POST_REND_AUDIO_CONFIG_TYPE_BINAURAL ); + + if ( rendererConfigEnabled ) + { + hIvasRend->rendererConfigEnabled = 1; + } + else + { + hIvasRend->rendererConfigEnabled = 0; + } + + if ( rendererConfigEnabled ) + { + hIvasRend->splitRenderConfig.splitRendBitRate = SPLIT_REND_768k; + hIvasRend->splitRenderConfig.dof = 3; + hIvasRend->splitRenderConfig.hq_mode = 0; + hIvasRend->splitRenderConfig.codec_delay_ms = 0; + hIvasRend->splitRenderConfig.codec_frame_size_ms = 0; /* 0 means "use default for selected codec" */ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + hIvasRend->splitRenderConfig.isar_frame_size_ms = 0; /* 0 means "use default for selected codec" */ +#endif + hIvasRend->splitRenderConfig.codec = ISAR_SPLIT_REND_CODEC_DEFAULT; + hIvasRend->splitRenderConfig.poseCorrectionMode = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB; + hIvasRend->splitRenderConfig.rendererSelection = ISAR_SPLIT_REND_RENDERER_SELECTION_DEFAULT; + } + + return IVAS_ERR_OK; +} + + +/*-------------------------------------------------------------------* + * ISAR_POST_REND_GetRenderConfig() + * + * + *-------------------------------------------------------------------*/ + +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 */ +) +{ + ISAR_SPLIT_REND_CONFIG_DATA hRCin; + + if ( hIvasRend == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + hRCin = hIvasRend->splitRenderConfig; + + splitRenderConfig->splitRendBitRate = SPLIT_REND_768k; + splitRenderConfig->dof = 3; + splitRenderConfig->hq_mode = 0; + splitRenderConfig->codec_delay_ms = 0; + splitRenderConfig->codec_frame_size_ms = 0; /* 0 means "use default for selected codec" */ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + splitRenderConfig->isar_frame_size_ms = 0; /* 0 means "use default for selected codec" */ +#endif + splitRenderConfig->codec = ISAR_SPLIT_REND_CODEC_DEFAULT; + splitRenderConfig->poseCorrectionMode = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB; + splitRenderConfig->rendererSelection = hRCin.rendererSelection; + + 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 */ + ISAR_POST_REND_BitstreamBuffer *hBits /* i : buffer for input bitstream */ +) +{ + ivas_error error; + input_base *inputBase; + input_split_post_rend *inputSplitPostRend; + + /* Validate function arguments */ + if ( hIvasRend == NULL || hBits == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + if ( ( error = getInputById( hIvasRend, inputId, (void **) &inputBase ) ) != IVAS_ERR_OK ) + { + printf( "Goo\n" ); + return error; + } + + inputSplitPostRend = (input_split_post_rend *) inputBase; + inputSplitPostRend->hBits = hBits; + + return IVAS_ERR_OK; +} + + +/*-------------------------------------------------------------------* + * ISAR_POST_REND_SetHeadRotation() + * + * + *-------------------------------------------------------------------*/ + +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 */ +) +{ + IVAS_QUATERNION rotQuat; + + /* Validate function arguments */ + if ( hIvasRend == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + 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; + } + + hIvasRend->headRotData.headRotEnabled = 1; + + /* check for Euler angle signaling */ + if ( headRot.w == -3.0f ) + { + Euler2Quat( deg2rad( headRot.x ), deg2rad( headRot.y ), deg2rad( headRot.z ), &rotQuat ); + } + else + { + rotQuat = headRot; + } + + hIvasRend->headRotData.headPositions[sf_idx] = rotQuat; + hIvasRend->headRotData.Pos[sf_idx] = Pos; + hIvasRend->headRotData.sr_pose_pred_axis = rot_axis; + + return IVAS_ERR_OK; +} + + +/*-------------------------------------------------------------------* + * ISAR_POST_REND_SetSplitRendBFI() + * + * + *-------------------------------------------------------------------*/ + +ivas_error ISAR_POST_REND_SetSplitRendBFI( + ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + const int16_t bfi /* i: BFI flag */ +) +{ + hIvasRend->splitRendBFI = bfi; + + return IVAS_ERR_OK; +} + + +/*-------------------------------------------------------------------* + * Local functions + *-------------------------------------------------------------------*/ + + +static ivas_error splitBinLc3plusDecode( + ISAR_SPLIT_POST_REND_WRAPPER *hSplitBin, + ISAR_SPLIT_REND_BITS_HANDLE bits, + float 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]; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + int32_t lc3plusBitstreamSize; +#else + int32_t lc3plusBitrateId, lc3plusBitstreamSize; +#endif + + push_wmops( "splitBinLc3plusDecode" ); + assert( hSplitBin->hLc3plusDec != NULL ); + + for ( int16_t i = 0; i < BINAURAL_CHANNELS * hSplitBin->multiBinPoseData.num_poses; ++i ) + { + channel_ptrs[i] = outputBuffer[i]; + } + + if ( SplitRendBFI == 0 ) + { + /* Find next byte boundary */ + while ( bits->bits_read % 8 != 0 ) + { + ++bits->bits_read; + } +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + /* Size is in bytes */ + assert( ( bits->bits_written - bits->bits_read ) % 8 == 0 ); + lc3plusBitstreamSize = ( bits->bits_written - bits->bits_read ) / 8; +#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 ) ); +#endif + + if ( ( error = ISAR_LC3PLUS_DEC_Decode( hSplitBin->hLc3plusDec, &bits->bits_buf[bits->bits_read / 8], lc3plusBitstreamSize, channel_ptrs ) ) != IVAS_ERR_OK ) + { + return error; + } + } + else + { + if ( ( error = ISAR_LC3PLUS_DEC_Conceal( hSplitBin->hLc3plusDec, channel_ptrs ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + pop_wmops(); + 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 ) +{ + 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]; + 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]; + 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]; + 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; +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS + uint32_t ivas_frame_duration_us; +#endif + int16_t iNumBlocksPerFrame, iNumLCLDIterationsPerFrame; + const ISAR_POST_REND_HeadRotData *pHeadRotData; + + isPostRendInputCldfb = 0; + push_wmops( "renderSplitBinauralWithPostRot" ); + error = IVAS_ERR_OK; + +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + if ( outAudio.config.numSamplesPerChannel / *splitBinInput->base.ctx.pOutSampleRate > splitBinInput->hBits->config.isar_frame_size_ms ) + { + return IVAS_ERR_INTERNAL_FATAL; + } +#endif + + pHeadRotData = splitBinInput->base.ctx.pHeadRotData; + hSplitBin = &splitBinInput->splitPostRendWrapper; + convertBitsBufferToInternalBitsBuff( *splitBinInput->hBits, &bits ); + +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS + ivas_frame_duration_us = 20000; + if ( splitBinInput->splitPostRendWrapper.hLc3plusDec != NULL ) + { + ivas_frame_duration_us = splitBinInput->splitPostRendWrapper.hLc3plusDec->config.isar_frame_duration_us; + } +#endif + + iNumLCLDIterationsPerFrame = 1; + iNumBlocksPerFrame = CLDFB_NO_COL_MAX; + 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++ ) + { + QuaternionsPost[sf_idx] = pHeadRotData->headPositions[sf_idx]; + } + + if ( !SplitRendBFI ) + { + hSplitBin->first_good_frame_received = 1; + } + + if ( hSplitBin->first_good_frame_received == 1 ) + { + if ( bits.pose_correction == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) + { + if ( !SplitRendBFI ) + { +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + isar_splitBinPostRendMdDec( &bits, hSplitBin->hBinHrSplitPostRend, &hSplitBin->multiBinPoseData, hSplitBin->hBinHrSplitPreRend ); +#else + isar_splitBinPostRendMdDec( &bits, hSplitBin->hBinHrSplitPostRend, &hSplitBin->multiBinPoseData ); +#endif + } + } + + /*copy pose correction after MD is parsed*/ + hSplitBin->multiBinPoseData.poseCorrectionMode = bits.pose_correction; + + /* decode audio */ + if ( splitBinInput->base.inConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) + { + if ( bits.codec == ISAR_SPLIT_REND_CODEC_LCLD ) + { + isPostRendInputCldfb = 1; + } +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + numSamplesPerChannelCacheSize = (int16_t) ( *splitBinInput->base.ctx.pOutSampleRate * bits.isar_frame_size_ms / 1000 ) - outBufNumSamplesPerChannel; +#else + preRendFrameSize_ms = (int16_t) ( ivas_frame_duration_us ) / 1000; + + numSamplesPerChannelCacheSize = (int16_t) ( *splitBinInput->base.ctx.pOutSampleRate * ( preRendFrameSize_ms - bits.codec_frame_size_ms ) / 1000 ); +#endif + + outBufNumColPerChannel = MAX_PARAM_SPATIAL_SUBFRAMES; + numColPerChannelCacheSize = ( iNumBlocksPerFrame * iNumLCLDIterationsPerFrame ) - outBufNumColPerChannel; + + for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) + { + if ( splitBinInput->numCachedSamples == 0 ) + { + if ( bits.codec == ISAR_SPLIT_REND_CODEC_LCLD ) + { + isar_splitBinLCLDDecProcess( hSplitBin->hSplitBinLCLDDec, &bits, Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, SplitRendBFI ); + + /* copy data over to 5ms buffer */ + for ( chnlIdx = 0; chnlIdx < BINAURAL_CHANNELS; ++chnlIdx ) + { + for ( slotIdx = 0; slotIdx < 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 ); + } + } + + /* cache the remaining 15ms */ + splitBinInput->numCachedSamples = numColPerChannelCacheSize; + writePtr = splitBinInput->bufferData; + for ( slotIdx = CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES; slotIdx < ( iNumBlocksPerFrame * iNumLCLDIterationsPerFrame ); ++slotIdx ) + { + for ( chnlIdx = 0; chnlIdx < BINAURAL_CHANNELS; ++chnlIdx ) + { + for ( smplIdx = 0; smplIdx < CLDFB_NO_CHANNELS_MAX; ++smplIdx ) + { + *writePtr++ = Cldfb_RealBuffer_Binaural[chnlIdx][slotIdx][smplIdx]; + } + for ( smplIdx = 0; smplIdx < CLDFB_NO_CHANNELS_MAX; ++smplIdx ) + { + *writePtr++ = Cldfb_ImagBuffer_Binaural[chnlIdx][slotIdx][smplIdx]; + } + } + } + } + else + { + if ( ( error = splitBinLc3plusDecode( hSplitBin, &bits, tmpCrendBuffer, +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS + bits.pose_correction, +#endif + SplitRendBFI ) ) != IVAS_ERR_OK ) + { + return error; + } + + /* cache the remaining decoded audio */ + splitBinInput->numCachedSamples = numSamplesPerChannelCacheSize; + mvr2r( &tmpCrendBuffer[0][outBufNumSamplesPerChannel], splitBinInput->bufferData, numSamplesPerChannelCacheSize ); + mvr2r( &tmpCrendBuffer[1][outBufNumSamplesPerChannel], splitBinInput->bufferData + numSamplesPerChannelCacheSize, numSamplesPerChannelCacheSize ); + } + } + else + { + /* copy from cache */ + if ( bits.codec == ISAR_SPLIT_REND_CODEC_LCLD ) + { + int16_t readOffset = ( numColPerChannelCacheSize - splitBinInput->numCachedSamples ); + readPtr = splitBinInput->bufferData; + isPostRendInputCldfb = 1; + + readPtr += 2 * readOffset * CLDFB_NO_CHANNELS_MAX * BINAURAL_CHANNELS; + for ( slotIdx = 0; slotIdx < CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES; ++slotIdx ) + { + for ( chnlIdx = 0; chnlIdx < BINAURAL_CHANNELS; ++chnlIdx ) + { + for ( smplIdx = 0; smplIdx < CLDFB_NO_CHANNELS_MAX; ++smplIdx ) + { + Cldfb_RealBuffer_Binaural_5ms[sf_idx][chnlIdx][slotIdx][smplIdx] = *readPtr++; + } + for ( smplIdx = 0; smplIdx < CLDFB_NO_CHANNELS_MAX; ++smplIdx ) + { + Cldfb_ImagBuffer_Binaural_5ms[sf_idx][chnlIdx][slotIdx][smplIdx] = *readPtr++; + } + } + } + + splitBinInput->numCachedSamples -= outBufNumColPerChannel; + } + 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 ); + splitBinInput->numCachedSamples -= outBufNumSamplesPerChannel; + } + } + } + } + else + { + copyBufferTo2dArray( splitBinInput->base.inputBuffer, tmpCrendBuffer ); + 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 -= outAudio.config.numSamplesPerChannel; + splitBinInput->numCachedSamples = numSamplesPerChannelCacheSize; + } + else + { + splitBinInput->numCachedSamples -= outAudio.config.numSamplesPerChannel; + } + } + + /* apply pose correction if enabled */ + for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) + { + if ( bits.pose_correction == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE && isPostRendInputCldfb ) + { + /* 0DOF with LCLD codec requires CLDFB synthesis */ + int16_t slot_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]; + + 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]; + } + + 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] ); + } + } + 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 ); + + 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 ); + + mvr2r( tmpCrendBuffer_sf[0], &tmpCrendBuffer[0][sf_idx * outBufNumSamplesPerChannel], outBufNumSamplesPerChannel ); + mvr2r( tmpCrendBuffer_sf[1], &tmpCrendBuffer[1][sf_idx * outBufNumSamplesPerChannel], outBufNumSamplesPerChannel ); + } + } + } + else + { + if ( splitBinInput->base.inConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) + { + for ( ch_idx = 0; ch_idx < BINAURAL_CHANNELS; ch_idx++ ) + { + set_zero( tmpCrendBuffer[ch_idx], outAudio.config.numSamplesPerChannel ); + } + } + else + { + copyBufferTo2dArray( splitBinInput->base.inputBuffer, tmpCrendBuffer ); + } + } + + convertInternalBitsBuffToBitsBuffer( splitBinInput->hBits, bits ); + accumulate2dArrayToBuffer( tmpCrendBuffer, &outAudio ); + + pop_wmops(); + return error; +} + +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 ) +{ + ivas_error error; + IVAS_REND_AudioBuffer inAudio; + + inAudio = splitBinInput->base.inputBuffer; + + 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 ) + { + case IVAS_AUDIO_CONFIG_BINAURAL: + error = renderSplitBinauralWithPostRot( splitBinInput, outAudio, SplitRendBFI, num_subframes ); + break; + default: + return IVAS_ERR_INVALID_OUTPUT_FORMAT; + } + + return error; +} + +static ivas_error renderActiveInputsSplitBin( + ISAR_POST_REND_HANDLE hIvasRend, + IVAS_REND_AudioBuffer outAudio ) +{ + int16_t i; + input_split_post_rend *pCurrentInput; + ivas_error error; + + for ( i = 0, pCurrentInput = hIvasRend->inputsSplitPost; i < RENDERER_MAX_BIN_INPUTS; ++i, ++pCurrentInput ) + { + if ( pCurrentInput->base.inConfig == IVAS_AUDIO_CONFIG_INVALID ) + { + /* Skip inactive inputs */ + continue; + } + + if ( ( error = renderInputSplitBin( pCurrentInput, hIvasRend->outputConfig, outAudio, hIvasRend->splitRendBFI, hIvasRend->num_subframes ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + return IVAS_ERR_OK; +} + + +/*-------------------------------------------------------------------* + * ISAR_POST_REND_getSamples() + * + * + *-------------------------------------------------------------------*/ + +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 */ +) +{ + ivas_error error; + int16_t numOutChannels; + int16_t cldfb2tdSampleFact; + + /* Validate function arguments */ + if ( hIvasRend == NULL || outAudio.data == 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 ) ) + { + return IVAS_ERR_INVALID_BUFFER_SIZE; + } + + if ( outAudio.config.numChannels <= 0 || 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 ) + { + 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 ) + { + return error; + } + + 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 ); + + if ( ( error = renderActiveInputsSplitBin( hIvasRend, outAudio ) ) != IVAS_ERR_OK ) + { + return error; + } + +#ifndef DISABLE_LIMITER +#ifdef DEBUGGING + hIvasRend->numClipping += +#endif + limitRendererOutput( hIvasRend->hLimiter, outAudio.data, outAudio.config.numSamplesPerChannel, IVAS_LIMITER_THRESHOLD ); +#endif + + return IVAS_ERR_OK; +} + +/*-------------------------------------------------------------------* + * ISAR_POST_REND_GetSplitBinauralSamples() + * + * + *-------------------------------------------------------------------*/ + +ivas_error ISAR_POST_REND_GetSplitBinauralSamples( + ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + IVAS_REND_AudioBuffer outAudio, /* i/o: buffer for output audio */ + bool *needNewFrame ) +{ + ivas_error error; + + if ( ( error = ISAR_POST_REND_getSamples( hIvasRend, outAudio ) ) != IVAS_ERR_OK ) + { + return error; + } + *needNewFrame = hIvasRend->inputsSplitPost[0].numCachedSamples == 0; + + return IVAS_ERR_OK; +} + + +/*-------------------------------------------------------------------* + * ISAR_POST_REND_Close() + * + * + *-------------------------------------------------------------------*/ + +void ISAR_POST_REND_Close( + ISAR_POST_REND_HANDLE *phIvasRend /* i/o: Pointer to renderer handle */ +) +{ + uint16_t i; + ISAR_POST_REND_HANDLE hIvasRend; + + /* Validate function arguments */ + if ( phIvasRend == NULL || *phIvasRend == NULL ) + { + return; + } + hIvasRend = *phIvasRend; + + for ( i = 0; i < RENDERER_MAX_BIN_INPUTS; ++i ) + { + clearInputSplitRend( &hIvasRend->inputsSplitPost[i] ); + } + + ivas_limiter_close( &hIvasRend->hLimiter ); + + free( hIvasRend ); + *phIvasRend = NULL; + + return; +} + + +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 */ + const int16_t codec_frame_size_ms /* i: codec frame size setting */ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + , + const int16_t isar_frame_size_ms, /* i: isar codec frame size setting */ + const int16_t lc3plus_highres /* i: LC3plus Hig-Res setting. Ignored if codec is not LC3plus */ +#endif +) +{ + if ( hIvasRend == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + hIvasRend->splitRenderConfig.codec = codec; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + hIvasRend->splitRenderConfig.isar_frame_size_ms = isar_frame_size_ms; +#endif + hIvasRend->splitRenderConfig.codec_frame_size_ms = codec_frame_size_ms; + hIvasRend->splitRenderConfig.poseCorrectionMode = poseCorrection; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + hIvasRend->splitRenderConfig.lc3plus_highres = lc3plus_highres; +#endif + return IVAS_ERR_OK; +} + +#ifdef DEBUGGING +/*-------------------------------------------------------------------* + * ISAR_POST_REND_GetNoCLipping() + * + * + *-------------------------------------------------------------------*/ + +int32_t ISAR_POST_REND_GetNoCLipping( + ISAR_POST_REND_HANDLE hIvasRend ) +{ + return hIvasRend->numClipping; +} + +int32_t ISAR_POST_REND_GetCntFramesLimited( + ISAR_POST_REND_CONST_HANDLE hIvasRend ) +{ + if ( hIvasRend->hLimiter == NULL ) + { + return 0; + } + + return hIvasRend->hLimiter->cnt_frames_limited; +} +#endif + + +#endif diff --git a/lib_isar/lib_isar_post_rend.h b/lib_isar/lib_isar_post_rend.h new file mode 100644 index 000000000..d5fdd605b --- /dev/null +++ b/lib_isar/lib_isar_post_rend.h @@ -0,0 +1,231 @@ +/****************************************************************************************************** + + (C) 2022-2023 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 LIB_ISAR_POST_REND_H +#define LIB_ISAR_POST_REND_H + +#include +#include "common_api_types.h" + + +#ifndef SPLIT_REND_WITH_HEAD_ROT + +int32_t ISAR_POST_REND_void_func( void ); + +#else + +/*---------------------------------------------------------------------* + * Renderer constants + *---------------------------------------------------------------------*/ + +#define RENDERER_MAX_ISAR_MD_INPUTS 1 +#define RENDERER_MAX_BIN_INPUTS 1 + +/*---------------------------------------------------------------------* + * Renderer structures + *---------------------------------------------------------------------*/ + +typedef struct +{ + int32_t bufLenInBytes; + int32_t bitsWritten; + int32_t bitsRead; + ISAR_SPLIT_REND_CODEC codec; + ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrection; + int16_t codec_frame_size_ms; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + int16_t isar_frame_size_ms; + int16_t lc3plusHighRes; +#endif +} ISAR_POST_REND_BitstreamBufferConfig; + +typedef struct +{ + ISAR_POST_REND_BitstreamBufferConfig config; + uint8_t *bits; +} ISAR_POST_REND_BitstreamBuffer; + +typedef enum +{ + ISAR_POST_REND_AUDIO_CONFIG_TYPE_BINAURAL = 0, + ISAR_POST_REND_AUDIO_CONFIG_TYPE_UNKNOWN, +} ISAR_POST_REND_AudioConfigType; + +typedef struct +{ + IVAS_REND_AudioBufferConfig config; + const float *data; +} ISAR_POST_REND_ReadOnlyAudioBuffer; + +typedef struct ISAR_POST_REND *ISAR_POST_REND_HANDLE; +typedef struct ISAR_POST_REND const *ISAR_POST_REND_CONST_HANDLE; + +typedef uint16_t ISAR_POST_REND_InputId; + +typedef enum _ISAR_POST_REND_COMPLEXITY_LEVEL +{ + ISAR_POST_REND_COMPLEXITY_LEVEL_ONE = 1, + ISAR_POST_REND_COMPLEXITY_LEVEL_TWO = 2, + ISAR_POST_REND_COMPLEXITY_LEVEL_THREE = 3 +} ISAR_POST_REND_COMPLEXITY_LEVEL; + + +/* clang-format off */ +/*----------------------------------------------------------------------------------* + * Renderer function prototypes + *----------------------------------------------------------------------------------*/ + +/* 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 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 */ +); + +/* 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 */ +); + +ivas_error ISAR_POST_REND_AddInput( + ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + const IVAS_AUDIO_CONFIG inConfig, /* i : audio config for a new input */ + ISAR_POST_REND_InputId *inputId /* o : ID of the new input */ +); + +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) */ +); + +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 */ +); + +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 */ +); + +/* Functions to be called during rendering */ + +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 */ + const ISAR_POST_REND_ReadOnlyAudioBuffer inputAudio /* i : buffer with input audio */ +); + +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 */ +); + +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 */ + ISAR_POST_REND_BitstreamBuffer *hBits /* i : buffer for input bitstream */ +); + +ivas_error ISAR_POST_REND_GetSplitBinauralSamples( + ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + IVAS_REND_AudioBuffer outAudio, /* i/o: buffer for output audio */ + bool* needNewFrame +); + +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 */ +); + +ivas_error ISAR_POST_REND_SetSplitRendBFI( + ISAR_POST_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + const int16_t 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 */ +); + +/* Functions to be called after rendering */ + +void ISAR_POST_REND_Close( + ISAR_POST_REND_HANDLE* phIvasRend /* i/o: Pointer to renderer handle */ +); + +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 */ + const int16_t codec_frame_size_ms /* i: codec frame size setting */ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + , + const int16_t isar_frame_size_ms, /* i: isar frame size setting */ + const int16_t lc3plus_highres /* i: LC3plus Hig-Res setting. Ignored if codec is not LC3plus */ +#endif +); + +#ifdef DEBUGGING +int32_t ISAR_POST_REND_GetNoCLipping( + ISAR_POST_REND_HANDLE hIvasRend /* i : Renderer handle */ +); + +int32_t ISAR_POST_REND_GetCntFramesLimited( + ISAR_POST_REND_CONST_HANDLE hIvasRend /* i : Renderer handle */ +); +#endif + +#endif /* SPLIT_REND_WITH_HEAD_ROT */ + +/* clang-format on */ + +#endif /* LIB_ISAR_POST_REND_H */ diff --git a/lib_isar/lib_isar_pre_rend.c b/lib_isar/lib_isar_pre_rend.c new file mode 100644 index 000000000..56d3edf55 --- /dev/null +++ b/lib_isar/lib_isar_pre_rend.c @@ -0,0 +1,497 @@ +/****************************************************************************************************** + + (C) 2022-2023 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. + +*******************************************************************************************************/ + + +#include +#include "options.h" +#include +#include "ivas_prot.h" +#include "prot.h" +#include "ivas_cnst.h" +#include "isar_rom_post_rend.h" +#include "lib_isar_pre_rend.h" +#include "isar_prot.h" +#ifdef DEBUGGING +#include "debug.h" +#endif +#include "wmc_auto.h" + + +#ifndef SPLIT_REND_WITH_HEAD_ROT +int32_t ISAR_PRE_REND_void_func( void ) +{ + return 0; +} + +#else + +/*-------------------------------------------------------------------* + * Local constants + *-------------------------------------------------------------------*/ + +/*-------------------------------------------------------------------* + * Local types + *-------------------------------------------------------------------*/ + +/*-------------------------------------------------------------------* + * Local function prototypes + *-------------------------------------------------------------------*/ + +/*-------------------------------------------------------------------* + * Local functions + *-------------------------------------------------------------------*/ + +/*------------------------------------------------------------------------- + * Function ISAR_PRE_REND_open() + * + * + *------------------------------------------------------------------------*/ + +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 */ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + 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 */ +) +{ + ivas_error error, ch, num_ch; + uint8_t isCldfbNeeded = 0; + + int16_t cldfb_in_flag_local = cldfb_in_flag; + + if ( ( error = isar_split_rend_choose_default_codec( &( pSplitRendConfig->codec ), +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + &pSplitRendConfig->isar_frame_size_ms, +#endif + &pSplitRendConfig->codec_frame_size_ms, + cldfb_in_flag_local, + pcm_out_flag, (int16_t) +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + ivas_frame_size +#else + num_subframes +#endif + ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( mixed_td_cldfb_flag ) + { + cldfb_in_flag_local = 0; + } + + if ( ( error = isar_split_rend_validate_config( pSplitRendConfig, pcm_out_flag ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( cldfb_in_flag_local == 0 ) + { + isCldfbNeeded = 1; + } + else if ( pSplitRendConfig->codec == ISAR_SPLIT_REND_CODEC_LC3PLUS && cldfb_in_flag_local ) + { + isCldfbNeeded = 1; + } + else if ( pcm_out_flag && cldfb_in_flag_local ) + { + isCldfbNeeded = 1; + } + + hSplitBinRend->hCldfbHandles = NULL; + + if ( isCldfbNeeded ) + { + if ( ( hSplitBinRend->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++ ) + { + hSplitBinRend->hCldfbHandles->cldfbAna[ch] = NULL; + } + + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + hSplitBinRend->hCldfbHandles->cldfbSyn[ch] = NULL; + } + + num_ch = hSplitBinRend->multiBinPoseData.num_poses * BINAURAL_CHANNELS; + + for ( ch = 0; ch < num_ch; ch++ ) + { + if ( ( error = openCldfb( &( hSplitBinRend->hCldfbHandles->cldfbAna[ch] ), + CLDFB_ANALYSIS, + output_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + 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 ) + { + return error; + } + } + } + + if ( pSplitRendConfig->poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) + { + if ( ( error = isar_splitBinPreRendOpen( &hSplitBinRend->hBinHrSplitPreRend, &hSplitBinRend->multiBinPoseData +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + , + OutSampleRate +#endif + ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + if ( pcm_out_flag == 0 ) + { + if ( pSplitRendConfig->codec == ISAR_SPLIT_REND_CODEC_LC3PLUS ) + { + if ( ( error = split_renderer_open_lc3plus( hSplitBinRend, pSplitRendConfig, output_Fs, +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + ivas_frame_size +#else + num_subframes +#endif + ) ) != IVAS_ERR_OK ) + { + return error; + } + } + else + { + int16_t 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 ) + { + return error; + } + } + } + + return IVAS_ERR_OK; +} + +/*------------------------------------------------------------------------- + * Function ISAR_PRE_REND_close() + * + * + *------------------------------------------------------------------------*/ + +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; + + if ( hSplitBinRend->hBinHrSplitPreRend != NULL ) + { + isar_splitBinPreRendClose( &hSplitBinRend->hBinHrSplitPreRend ); + } + + if ( hSplitBinRend->hSplitBinLCLDEnc != NULL ) + { + isar_splitBinLCLDEncClose( &hSplitBinRend->hSplitBinLCLDEnc ); + } + + if ( hSplitBinRend->hCldfbHandles != NULL ) + { + int16_t num_ch, ch; + num_ch = MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS; + for ( ch = 0; ch < num_ch; ch++ ) + { + if ( hSplitBinRend->hCldfbHandles->cldfbAna[ch] != NULL ) + { + deleteCldfb( &hSplitBinRend->hCldfbHandles->cldfbAna[ch] ); + hSplitBinRend->hCldfbHandles->cldfbAna[ch] = NULL; + } + } + + for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) + { + if ( hSplitBinRend->hCldfbHandles->cldfbSyn[ch] != NULL ) + { + deleteCldfb( &hSplitBinRend->hCldfbHandles->cldfbSyn[ch] ); + hSplitBinRend->hCldfbHandles->cldfbSyn[ch] = NULL; + } + } + + free( hSplitBinRend->hCldfbHandles ); + hSplitBinRend->hCldfbHandles = NULL; + } + + if ( hSplitBinRend->hLc3plusEnc != NULL ) + { + ISAR_LC3PLUS_ENC_Close( &hSplitBinRend->hLc3plusEnc ); + } + + for ( i = 0; i < MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS; ++i ) + { + if ( hSplitBinRend->lc3plusDelayBuffers[i] != NULL ) + { + free( hSplitBinRend->lc3plusDelayBuffers[i] ); + hSplitBinRend->lc3plusDelayBuffers[i] = NULL; + } + } + + if ( pSplitRendEncBuffer != NULL ) + { + + if ( pSplitRendEncBuffer->data != NULL ) + { + free( pSplitRendEncBuffer->data ); + pSplitRendEncBuffer->data = NULL; + } + + pSplitRendEncBuffer->config.numChannels = 0; + pSplitRendEncBuffer->config.numSamplesPerChannel = 0; + } + + return; +} + +/*-------------------------------------------------------------------------* + * ISAR_PRE_REND_GetMultiBinPoseData() + * + * + *-------------------------------------------------------------------------*/ + +void ISAR_PRE_REND_GetMultiBinPoseData( + const ISAR_SPLIT_REND_CONFIG_DATA *pSplit_rend_config, /* i: Split renderer pre-renerer config */ + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, /* i/o: pose correction data handle */ + const ISAR_SPLIT_REND_ROT_AXIS rot_axis /* i: Rotation axis */ +) +{ + isar_renderSplitGetMultiBinPoseData( pSplit_rend_config, pMultiBinPoseData, rot_axis ); +} + +/*------------------------------------------------------------------------- + * Function ISAR_PRE_REND_MultiBinToSplitBinaural() + * + * + *------------------------------------------------------------------------*/ + +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 */ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + const int16_t 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 */ +) +{ + ivas_error error; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + int32_t bit_len, target_md_bits, available_bits; +#else + int32_t bit_len, target_md_bits, actual_md_bits, available_bits; +#endif + + error = IVAS_ERR_OK; + push_wmops( "isar_pre_rend_MultiBinToSplitBinaural" ); + + 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 ); + } + + if ( 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, +#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 ); + + pop_wmops(); + return error; + } + + 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 ); + } + +#ifndef ISAR_BITSTREAM_UPDATE_LC3PLUS + actual_md_bits = pBits->bits_written; +#endif + 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 ); + } + + if ( pcm_out_flag == 0 ) + { + pBits->codec = splitCodec; + pBits->pose_correction = hSplitBin->multiBinPoseData.poseCorrectionMode; + + if ( splitCodec == ISAR_SPLIT_REND_CODEC_LCLD ) + { + available_bits = ( SplitRendBitRate * hSplitBin->hSplitBinLCLDEnc->iNumBlocks * hSplitBin->hSplitBinLCLDEnc->iNumIterations ) / ( 16 * FRAMES_PER_SEC ); +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + available_bits -= pBits->bits_written; +#else + actual_md_bits = pBits->bits_written - actual_md_bits; + 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 ); + } + 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; + /* CLDFB synthesis of main pose */ + 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]; + + 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]; + } + + cldfbSynthesis( Cldfb_In_BinReal_p, Cldfb_In_BinImag_p, output[ch], hSplitBin->hCldfbHandles->cldfbSyn[0]->no_channels * num_slots, hSplitBin->hCldfbHandles->cldfbSyn[ch] ); + } + +#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 ) +#else + if ( ( error = splitRendLc3plusEncodeAndWrite( hSplitBin, pBits, SplitRendBitRate, output ) ) != IVAS_ERR_OK ) +#endif + { + return error; + } + } + } + else + { + int16_t ch, slot_idx; + /* CLDFB synthesis of main pose */ + 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]; + + 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]; + } + + 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] ); + } + + pBits->pose_correction = hSplitBin->multiBinPoseData.poseCorrectionMode; + pBits->codec = ISAR_SPLIT_REND_CODEC_NONE; + } + + /*zero pad*/ + if ( pcm_out_flag ) + { + bit_len = SplitRendBitRate / FRAMES_PER_SEC; + } + else + { + if ( splitCodec == ISAR_SPLIT_REND_CODEC_LCLD ) + { + bit_len = ( SplitRendBitRate * hSplitBin->hSplitBinLCLDEnc->iNumBlocks * hSplitBin->hSplitBinLCLDEnc->iNumIterations ) / ( 16 * FRAMES_PER_SEC ); + } + else + { + bit_len = hSplitBin->hLc3plusEnc->config.isar_frame_duration_us / 1000; + bit_len = SplitRendBitRate * bit_len / 1000; + } + } + + while ( pBits->bits_written < bit_len ) + { + ISAR_SPLIT_REND_BITStream_write_int32( pBits, 0L, 1 ); + } + + pop_wmops(); + + return error; +} + +#endif diff --git a/lib_isar/lib_isar_pre_rend.h b/lib_isar/lib_isar_pre_rend.h new file mode 100644 index 000000000..938787314 --- /dev/null +++ b/lib_isar/lib_isar_pre_rend.h @@ -0,0 +1,91 @@ +/****************************************************************************************************** + + (C) 2022-2023 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 LIB_ISAR_PRE_REND_H +#define LIB_ISAR_PRE_REND_H + +#include "isar_stat.h" +#include "isar_prot.h" + +#ifndef SPLIT_REND_WITH_HEAD_ROT + +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 */ + 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 */ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + 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 */ +); + +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 */ +); + +void ISAR_PRE_REND_GetMultiBinPoseData( + const ISAR_SPLIT_REND_CONFIG_DATA *pSplit_rend_config, /* i: Split renderer pre-renerer config */ + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, /* i/o: pose correction data handle */ + const ISAR_SPLIT_REND_ROT_AXIS rot_axis /* i: Rotation axis */ +); + +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 */ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + const int16_t 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 */ +); + +#endif +#endif /* LIB_ISAR_PRE_REND_H */ diff --git a/lib_lc3plus/adjust_global_gain.c b/lib_lc3plus/adjust_global_gain.c index e7674dd71..24eb596c8 100644 --- a/lib_lc3plus/adjust_global_gain.c +++ b/lib_lc3plus/adjust_global_gain.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -9,17 +9,21 @@ #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 = 0; - LC3_INT delta2 = 0; + 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) { @@ -32,7 +36,14 @@ void processAdjustGlobalGain_fl(LC3_INT* gg_idx, LC3_INT gg_idx_min, LC3_INT gg_ } else if (frame_dms == 50) { factor = 2; - } else + } +#ifdef CR8_G_ADD_75MS + else if (frame_dms == 75) + { + factor = 1.2; + } +#endif + else { factor = 1; } @@ -60,7 +71,7 @@ void processAdjustGlobalGain_fl(LC3_INT* gg_idx, LC3_INT gg_idx_min, LC3_INT gg_ if (hrmode) { if (nBits > target) { - gg_idx_inc = (int) factor * (((nBits - target)/ delta) + 1); + gg_idx_inc = (int) (factor * (((nBits - target)/ delta) + 1)); gg_idx_inc = MIN(gg_idx_inc, 10 * factor); *gg_idx += gg_idx_inc; diff --git a/lib_lc3plus/al_fec_fl.c b/lib_lc3plus/al_fec_fl.c index 0cae36dad..92861d65b 100644 --- a/lib_lc3plus/al_fec_fl.c +++ b/lib_lc3plus/al_fec_fl.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -9,6 +9,7 @@ #include "options.h" +#include "wmc_auto.h" #include "stdint.h" #include #include diff --git a/lib_lc3plus/apply_global_gain.c b/lib_lc3plus/apply_global_gain.c index c67432e2c..450997e20 100644 --- a/lib_lc3plus/apply_global_gain.c +++ b/lib_lc3plus/apply_global_gain.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -9,11 +9,12 @@ #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 = 0; + LC3_FLOAT gg; gg = LC3_POW(10, (LC3_FLOAT)(global_gain_idx + global_gain_off) / 28); diff --git a/lib_lc3plus/ari_codec.c b/lib_lc3plus/ari_codec.c index 80c75fcf0..23a540e91 100644 --- a/lib_lc3plus/ari_codec.c +++ b/lib_lc3plus/ari_codec.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -9,30 +9,131 @@ #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 tns_order_freq_enc(LC3_INT enable_lpc_weighting, LC3_INT order, LC3_INT* symfreq, LC3_INT* cumfreq); -static void tns_coef_freq_enc(LC3_INT k, LC3_INT idx, LC3_INT* symfreq, LC3_INT* cumfreq); -static void ac_freq_fl(LC3_INT pki, LC3_INT s, LC3_INT* symfreq, LC3_INT* cumfreq); 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); -static void tns_order_freq(LC3_INT enable_lpc_weighting, 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); +#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); -static void ac_freq(LC3_INT pki, LC3_INT* symfreq, LC3_INT* cumfreq, LC3_INT* numsym); -static void findNonZero(LC3_INT* in, LC3_INT* out, LC3_INT len, LC3_INT* outLen); +#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) +{ + LC3_INT i = 0, j = 0; + + *numsym = 18 - 1; + + j = 0; + for (i = 1; i <= *numsym; i++) { + symfreq[j] = ari_spec_cumfreq_fl[pki][i]; + j++; + } + + for (i = 0; i < *numsym; i++) { + symfreq[i] -= ari_spec_cumfreq_fl[pki][i]; + } + + for (i = 0; i < *numsym; i++) { + cumfreq[i] = ari_spec_cumfreq_fl[pki][i]; + } +} + +void tns_coef_freq(LC3_INT k, LC3_INT* symfreq, LC3_INT* cumfreq, LC3_INT* numsym) +{ + LC3_INT i = 0, j = 0; + + *numsym = 18 - 1; + + j = 0; + for (i = 1; i <= *numsym; i++) { + symfreq[j] = ari_tns_freq_cf[k][i]; + j++; + } + + for (i = 0; i < *numsym; i++) { + symfreq[i] -= ari_tns_freq_cf[k][i]; + } + + for (i = 0; i < *numsym; i++) { + cumfreq[i] = ari_tns_freq_cf[k][i]; + } +} + +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; + + j = 0; + for (i = 1; i < 9; i++) { + symfreq[j] = ari_tns_order_cf[enable_lpc_weighting][i]; + j++; + } + + for (i = 0; i < *numsym; i++) { + symfreq[i] -= ari_tns_order_cf[enable_lpc_weighting][i]; + } + + for (i = 0; i < *numsym; i++) { + cumfreq[i] = ari_tns_order_cf[enable_lpc_weighting][i]; + } +} + +#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++; + } + } + + *outLen = j; +} void calculate_nfseed(LC3_INT *x, LC3_INT L_spec, LC3_INT *nf_seed) { - LC3_INT k = 0; + LC3_INT k; *nf_seed = 0; @@ -46,6 +147,102 @@ void calculate_nfseed(LC3_INT *x, LC3_INT L_spec, LC3_INT *nf_seed) } } +#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) +{ + LC3_INT32 bp_local, bp_side_local, offset; +#ifdef WMOPS + push_wmops("pc_check_bytes"); +#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; + } + + 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) + { + offset = offset + st_fl->pc_bytes; + } + + if ((bp_side_local + offset - bp_local) == st_fl->pc_bytes) + { + st_fl->pc_b_left = bp_local + 1; + st_fl->pc_b_right = bp_side_local - 1; + + if (st_fl->pc_enc) + { + assert(st_fl->pc_b_right - st_fl->pc_b_left + 1 == st_fl->pc_bytes); + return 1; + } + } + } + + 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) + { + *bp_side = st_fl->pc_bytes - 1; + st_fl->pc_c_bp_side = 1; + } + + if (st_fl->pc_bfi == 2) + { + + 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)) + { + 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))) + { + st_fl->pc_inv_bin = MIN(st_fl->pc_inv_bin, cur_bin); + return 0; + } + } + } + } + +#ifdef WMOPS + pop_wmops(); +#endif + return 0; +} + +#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; @@ -130,6 +327,35 @@ static void pc_check_bytes(LC3_INT32* bp, Decoder_State_fl* st_fl, LC3_INT32 fro return; } +#endif + +#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; + + if (!st_fl->pc_enc) + { + *bp = *bp + st_fl->pc_bytes; + } + + 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) + { + return; + } + + 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) { @@ -153,145 +379,573 @@ void ac_dec_init_fl(LC3_UINT8* ptr, LC3_INT* bp, Decoder_State_fl* st_fl, LC3_IN st_fl->BER_detect = 0; } -void tns_order_freq(LC3_INT enable_lpc_weighting, LC3_INT* symfreq, LC3_INT* cumfreq, LC3_INT* numsym) -{ - LC3_INT i = 0, j = 0; +#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) +{ + LC3_INT val, tmp, symfreq_loc; +#ifdef WMOPS + push_wmops("ac_decode_fl"); +#endif + + tmp = st->ac_range_fl >> 10; + + if (st->ac_low_fl >= (LC3_UINT32)(tmp << 10)) { + st->BER_detect = 1; + } + + val = num_sym - 1; + + while (st->ac_low_fl < (LC3_UINT32)(tmp * freq[val])) { + val--; + } + + 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)); + + 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; + } + +#ifdef WMOPS + pop_wmops(); +#endif + return val; +} + +#else + +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; + + + tmp = st->ac_range_fl >> 10; + + if (st->ac_low_fl >= (LC3_UINT32)(tmp << 10)) { + st->BER_detect = 1; + } + + val = num_sym - 1; + + while (st->ac_low_fl < (LC3_UINT32)(tmp * cum_freq[val])) { + val--; + } + + st->ac_low_fl = st->ac_low_fl - tmp * cum_freq[val]; + st->ac_range_fl = tmp * sym_freq[val]; + + 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; + } + + return val; +} + + +#endif + +#ifdef CR9_SIMPLIFY_ARI_DECODER +void read_bit_fl(LC3_UINT8* ptr, LC3_INT* mask_side, LC3_INT* bp_side, LC3_INT* bit) +{ + 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; + } +} + +#else + +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) +{ + *bit = 0; + + UNUSED(bp); + UNUSED(st_fl); + UNUSED(from_left); + + 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; + } +} + +#endif + +#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 +) +{ + 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 + + 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); + + /* Rate flag */ + if (fs_idx != 5) + { + if (total_bits > (160 + fs_idx * 160)) { + rateFlag = 512; + } + } + + /* 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 <= 50) + { + tmp /= 2; + } + + /* 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) + { + goto ber_detect; + } + + for (k = 0; k < tns_order[n]; k++) { + if (bp_side < bp) + { + *bfi = 1; + return; + } + + 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) + { + goto ber_detect; + } + } + } + } + + /* 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) + { + goto ber_detect; + } + 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) + { + goto ber_detect; + } + read_bit_fl(ptr, &mask_side, &bp_side, &bit); + + x[k + 1] = x[k + 1] + (bit << lev); + } + } + + if ((lev - 1) == 13 && sym == 16) + { + 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; + + if (((bp - bp_side) > 3 && (st.pc_c_bp == st.pc_c_bp_side))) { - *numsym = 8; + if ((0 < *spec_inv_idx) && (*spec_inv_idx < (L_spec + 1))) + { + *bfi = 2; + calculate_nfseed(x, k, nf_seed); + return; + } - j = 0; - for (i = 1; i < 9; i++) { - symfreq[j] = ari_tns_order_cf[enable_lpc_weighting][i]; - j++; + *bfi = 1; + return; + } + + if (st.BER_detect > 0) + { + goto ber_detect; + } } - for (i = 0; i < *numsym; i++) { - symfreq[i] -= ari_tns_order_cf[enable_lpc_weighting][i]; - } + /* 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)); - for (i = 0; i < *numsym; i++) { - cumfreq[i] = ari_tns_order_cf[enable_lpc_weighting][i]; + if (enc == 0) + { + 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)); + } } -} -/* Returns val */ -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; + *nbits_residual = total_bits - (nbits_side + nbits_ari + extra_bits); - tmp = st->ac_range_fl >> 10; - - if (st->ac_low_fl >= (LC3_UINT32)(tmp << 10)) { - st->BER_detect = 1; + 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; } - val = num_sym - 1; + if (lsbMode == 0) { + findNonZero(x, L_spec, &idx_len); - while (st->ac_low_fl < (LC3_UINT32)(tmp * cum_freq[val])) { - val--; - } + if (hrmode) + { + idx_len *= EXT_RES_ITER_MAX; + } + *nbits_residual = MIN(*nbits_residual, idx_len); + *residualPresent = 1; - st->ac_low_fl = st->ac_low_fl - tmp * cum_freq[val]; - st->ac_range_fl = tmp * sym_freq[val]; + memset(resBits, 0, MAX_RESBITS_LEN); - 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; - } + for (k = 0; k < *nbits_residual; k++) { + 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, &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; + } - return val; -} + 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; -void tns_coef_freq(LC3_INT k, LC3_INT* symfreq, LC3_INT* cumfreq, LC3_INT* numsym) -{ - LC3_INT i = 0, j = 0; + 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; + } - *numsym = 18 - 1; + 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; - j = 0; - for (i = 1; i <= *numsym; i++) { - symfreq[j] = ari_tns_freq_cf[k][i]; - j++; - } + if (bit == 0) { + x[k] = 1; + } else { + x[k] = -1; + } + } + } - for (i = 0; i < *numsym; i++) { - symfreq[i] -= ari_tns_freq_cf[k][i]; - } + if (*nbits_residual == 0) { + break; + } - for (i = 0; i < *numsym; i++) { - cumfreq[i] = ari_tns_freq_cf[k][i]; - } -} + 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; -void ac_freq(LC3_INT pki, LC3_INT* symfreq, LC3_INT* cumfreq, LC3_INT* numsym) -{ - LC3_INT i = 0, j = 0; + 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; + } - *numsym = 18 - 1; + 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; - j = 0; - for (i = 1; i <= *numsym; i++) { - symfreq[j] = ari_spec_cumfreq_fl[pki][i]; - j++; + if (bit == 0) { + x[k + 1] = 1; + } else { + x[k + 1] = -1; + } + } + } + } + } } - for (i = 0; i < *numsym; i++) { - symfreq[i] -= ari_spec_cumfreq_fl[pki][i]; - } + /* Noise-filling seed */ + calculate_nfseed(x, L_spec, nf_seed); - for (i = 0; i < *numsym; i++) { - cumfreq[i] = ari_spec_cumfreq_fl[pki][i]; + /* 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; } -} - -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) -{ - *bit = 0; - UNUSED(bp); - UNUSED(st_fl); - UNUSED(from_left); - - if (ptr[*bp_side] & *mask_side) { - *bit = 1; + if (enc) + { + if (st.pc_bytes > 0) + { + if (st.pc_b_left > numbytes) + { + *b_left = bp_side - st.pc_bytes; + } + } } else { - *bit = 0; + if (st.pc_bytes > 0) + { + if (st.pc_b_left > numbytes) + { + *b_left = bp_side; + } + } } - - if (*mask_side == 128) { - *mask_side = 1; - *bp_side = *bp_side - 1; - } else { - *mask_side = *mask_side * 2; + + if ((*bfi == 2) && (*spec_inv_idx == (L_spec + 1))) + { + *bfi = 0; } -} + + *spec_inv_idx = *spec_inv_idx - 1; -void findNonZero(LC3_INT* in, LC3_INT* out, LC3_INT len, LC3_INT* outLen) -{ - LC3_INT i = 0, j = 0; + goto bail; - for (i = 0; i < len; i++) { - if (in[i] != 0) { - out[j] = i; - j++; - } - } +/* goto for bit error handling */ +ber_detect: + *bfi = 1; + *b_left = st.pc_b_left; - *outLen = j; + if (st.pc_inv_bin > 0 && (st.pc_inv_bin - L_spec) <= 0) + { + *spec_inv_idx = st.pc_inv_bin; + *bfi = 2; + *resBits = 0; + *zero_frame = 0; + /* Noise Filling seed */ + calculate_nfseed(x, *spec_inv_idx, nf_seed); + } + goto bail; + +/* goto for bit error handling in residual signal */ +ber_detect_res: + *b_left = st.pc_b_left; + *resBits = 0; + *bfi = 0; + *zero_frame = 0; + /* Noise Filling seed */ + calculate_nfseed(x, *spec_inv_idx, nf_seed); + 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; } +#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_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 ) { @@ -303,7 +957,7 @@ void processAriDecoder_fl(LC3_UINT8* bytes, LC3_INT bp_side, LC3_INT mask_side, 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, idx[MAX_LEN] = {0}, rateFlag = 0; + save_lev[MAX_LEN] = {0}, idx_len = 0, total_bits = 0, nbits_ari = 0, rateFlag = 0; total_bits = 8 * numbytes; @@ -641,7 +1295,7 @@ void processAriDecoder_fl(LC3_UINT8* bytes, LC3_INT bp_side, LC3_INT mask_side, } if (lsbMode == 0) { - findNonZero(x, idx, L_spec, &idx_len); + findNonZero(x, L_spec, &idx_len); if (hrmode) { idx_len *= EXT_RES_ITER_MAX; @@ -826,22 +1480,24 @@ void processAriDecoder_fl(LC3_UINT8* bytes, LC3_INT bp_side, LC3_INT mask_side, *spec_inv_idx = *spec_inv_idx - 1; } +#endif + void ac_encode_fl(Encoder_State_fl* st, LC3_INT sym_freq, LC3_INT cum_freq) { - LC3_INT r = 0; + LC3_INT r; r = st->range >> 10; - st->low = st->low + r * cum_freq; + st->low += r * cum_freq; if ((st->low >> 24) == 1) { st->carry = 1; } - st->low = (st->low) & ((LC3_INT)pow(2, 24) - 1); + st->low &= (16777215); /* 2^24 -1 */ st->range = r * sym_freq; - while (st->range < (LC3_INT)pow(2, 16)) { - st->range = st->range << 8; + while (st->range < 65536) { /* 2^16 */ + st->range <<= 8; ac_shift_fl(st); } } @@ -867,47 +1523,30 @@ void ac_shift_fl(Encoder_State_fl* st) } st->low = st->low << 8; - st->low = (st->low) & ((LC3_INT)pow(2, 24) - 1); -} - -void tns_order_freq_enc(LC3_INT enable_lpc_weighting, LC3_INT order, LC3_INT* symfreq, LC3_INT* cumfreq) -{ - *symfreq = tns_freq_cf[enable_lpc_weighting][order] - tns_freq_cf[enable_lpc_weighting][order - 1]; - *cumfreq = tns_freq_cf[enable_lpc_weighting][order - 1]; -} - -void tns_coef_freq_enc(LC3_INT k, LC3_INT idx, LC3_INT* symfreq, LC3_INT* cumfreq) -{ - *symfreq = tns_cf[k][idx + 1] - tns_cf[k][idx]; - *cumfreq = tns_cf[k][idx]; + st->low = (st->low) & (16777215); /* 2^24 - 1 */ } -void ac_freq_fl(LC3_INT pki, LC3_INT s, LC3_INT* symfreq, LC3_INT* cumfreq) -{ - *symfreq = ari_spec_cumfreq_fl[pki][s + 1] - ari_spec_cumfreq_fl[pki][s]; - *cumfreq = ari_spec_cumfreq_fl[pki][s]; -} void ac_finalize_fl(Encoder_State_fl* st) { LC3_INT bits = 0, mask = 0, val = 0, over1 = 0, high = 0, over2 = 0, c = 0, b = 0; - bits = 24 - floor(LC3_LOGTWO(st->range)); - mask = ((LC3_INT)pow(2, 24) - 1) >> bits; + bits = 24 - (31 - clz_func(st->range)); + mask = 16777215 >> bits; val = st->low + mask; over1 = val >> 24; - val = (val) & ((LC3_INT)pow(2, 24) - 1); + val = (val) & 16777215; high = st->low + st->range; over2 = high >> 24; - high = high & ((LC3_INT)pow(2, 24) - 1); - val = val & (((LC3_INT)pow(2, 24) - 1) - mask); + high = high & 16777215; + val = val & (16777215 - mask); if (over1 == over2) { if (val + mask >= high) { bits = bits + 1; mask = mask >> 1; - val = ((st->low + mask) & ((LC3_INT)pow(2, 24) - 1)) & (((LC3_INT)pow(2, 24) - 1) - mask); + val = ((st->low + mask) & (16777215)) & (16777215 - mask); } if (val < st->low) { @@ -949,7 +1588,7 @@ void ac_finalize_fl(Encoder_State_fl* st) void write_uint_forward_fl(Encoder_State_fl* st, LC3_INT val, LC3_INT numbits) { - LC3_INT k = 0, bit = 0, mask = 128; + LC3_INT k, bit, mask = 128; for (k = 0; k < numbits; k++) { bit = val & mask; @@ -971,7 +1610,7 @@ void ari_enc_init(Encoder_State_fl* st, LC3_UINT8* bytes, LC3_INT* bp_side, LC3_ st->mask_side = mask_side; st->bp = 0; st->low = 0; - st->range = (LC3_INT)pow(2, 24) - 1; + st->range = 16777215; st->cache = -1; st->carry = 0; st->carry_count = 0; @@ -992,11 +1631,16 @@ void processAriEncoder_fl(LC3_UINT8* bytes, LC3_INT bp_side, LC3_INT mask_side, 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) { - LC3_INT total_bits = 0, cumfreq = 0, symfreq = 0, k = 0, i = 0, j = 0, lev = 0, lev1 = 0; - LC3_INT bit1 = 0, bit2 = 0, lsb1 = 0, lsb2 = 0, a = 0, b = 0, bit = 0, pki = 0, nbits_side = 0; - LC3_INT nbits_residual_enc = 0, nbits_ari = 0, lsbs[MAX_LEN] = {0}, lsbsLen = 0; + 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 + ari_enc_init(&st, bytes, &bp_side, &mask_side); total_bits = nbbits; @@ -1004,11 +1648,13 @@ void processAriEncoder_fl(LC3_UINT8* bytes, LC3_INT bp_side, LC3_INT mask_side, /* TNS data */ for (i = 0; i < tns_numfilters; i++) { if (tns_order[i] > 0) { - tns_order_freq_enc(enable_lpc_weighting, tns_order[i], &symfreq, &cumfreq); + 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); for (j = 0; j < tns_order[i]; j++) { - tns_coef_freq_enc(j, tns_idx[i * 8 + j], &symfreq, &cumfreq); + 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); } } @@ -1016,14 +1662,18 @@ void processAriEncoder_fl(LC3_UINT8* bytes, LC3_INT bp_side, LC3_INT mask_side, /* 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]; - ac_freq_fl(pki, 16, &symfreq, &cumfreq); + 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[k + 1]) >> lev) & 1; + bit1 = (abs_x_k >> lev) & 1; + bit2 = (abs_x_kp1 >> lev) & 1; + if (lsbMode == 1 && lev == 0) { lsb1 = bit1; @@ -1037,11 +1687,12 @@ void processAriEncoder_fl(LC3_UINT8* bytes, LC3_INT bp_side, LC3_INT mask_side, lev1 = MIN(MAX(codingdata[1], 0), 3); pki = ari_spec_lookup_fl[codingdata[0] + lev1 * 1024]; - ac_freq_fl(pki, codingdata[2], &symfreq, &cumfreq); + 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); - a = abs(x[k]); - b = abs(x[k + 1]); + a = abs_x_k; + b = abs_x_kp1; if (lsbMode == 1 && codingdata[1] > 0) { a = a >> 1; @@ -1079,8 +1730,8 @@ void processAriEncoder_fl(LC3_UINT8* bytes, LC3_INT bp_side, LC3_INT mask_side, } /* Residual bits */ - nbits_side = total_bits - (8 * (*(st.bp_side) + 1) + 8 - LC3_LOGTWO(*(st.mask_side))); - nbits_ari = (st.bp + 1) * 8 + 25 - floor(LC3_LOGTWO(st.range)); + 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 )) ; if (st.cache >= 0) { nbits_ari = nbits_ari + 8; @@ -1118,5 +1769,8 @@ void processAriEncoder_fl(LC3_UINT8* bytes, LC3_INT bp_side, LC3_INT mask_side, } ac_finalize_fl(&st); +#ifdef WMOPS + pop_wmops(); +#endif } diff --git a/lib_lc3plus/attack_detector.c b/lib_lc3plus/attack_detector.c index c9f7c0a94..59af3abfd 100644 --- a/lib_lc3plus/attack_detector.c +++ b/lib_lc3plus/attack_detector.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -9,31 +9,25 @@ #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] = {0}, block_nrg[4] = {0}, sum = 0, tmpEne = 0, *ptr = NULL, tmp[162] = {0}; - LC3_INT i = 0, j = 0, attackPosition = 0; - LC3_FLOAT mval = 0; - LC3_INT frame_size_16k = attdec_nblocks * 40; - - - ptr = &tmp[2]; - - + 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) { - /* Decimate 96, 48 and 32 kHz signals to 16 kHz */ - if (fs == 96000) { - for (i = 0; i < frame_size;) { - ptr[j] = in[i] + in[i + 1] + in[i + 2] + in[i + 3] + in[i + 4] + in[i + 5]; - i = i + 6; - j++; - } - mval = 1e-5; - } else if (fs == 48000) { + + 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]); @@ -47,13 +41,6 @@ void attack_detector_fl(LC3_FLOAT* in, LC3_INT frame_size, LC3_INT fs, LC3_INT* i = i + 2; j++; } - } else if (fs == 24000) { - j = 0; - for (i = 0; i < frame_size;) { - ptr[j] = (in[i] + (in[i + 1] + in[i + 2]) / 2.0); - i = i + 3; - j++; - } } /* Filter */ diff --git a/lib_lc3plus/clib.h b/lib_lc3plus/clib.h index bd7092780..44e70de78 100644 --- a/lib_lc3plus/clib.h +++ b/lib_lc3plus/clib.h @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -11,6 +11,8 @@ #ifndef CLIB_H #define CLIB_H +#include "options.h" +#include "wmc_auto.h" #include #include #include diff --git a/lib_lc3plus/constants.c b/lib_lc3plus/constants.c index 8189761a0..3709a3f5a 100644 --- a/lib_lc3plus/constants.c +++ b/lib_lc3plus/constants.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -9,6 +9,7 @@ #include "options.h" +#include "wmc_auto.h" #include "functions.h" /* DCT */ @@ -48,10 +49,10 @@ ENTRY_DCT2_15, ENTRY_DCT2_16 }; -const LC3_INT ari_tns_order_cf[2][9] = {{0, 3, 12, 35, 89, 200, 390, 658, 1024}, +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}}; -const LC3_INT ari_tns_freq_cf[8][18] = { +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}, @@ -279,7 +280,7 @@ 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_INT ari_spec_cumfreq_fl[64][18] = { +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}, @@ -653,6 +654,22 @@ const LC3_FLOAT quants_thr_tns[18] = {-1, 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}; @@ -983,6 +1000,31 @@ 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 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}; + +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}; + +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}; + +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}; + +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}; + +const LC3_INT brickwall_dist_7_5ms[4] = {4, 4, 3, 2}; + +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}; +#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}, @@ -998,6 +1040,2372 @@ const LC3_INT tns_freq_cf[2][9] = {{0, 3, 12, 35, 89, 200, 390, 658, 1024}, {0, /* MDCT Windows */ +#ifdef CR8_G_ADD_75MS + +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 +}; + +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 +}; + +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 */ + 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, @@ -3080,6 +5488,12 @@ const LC3_FLOAT* MDCT_WINS_10ms[2][6] = { {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}; +#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}; +#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, @@ -3094,11 +5508,12 @@ const LC3_INT MDCT_la_zeroes_5ms[6] = {10, 20, 30, 40, 60, 120}; const LC3_INT MDCT_WINDOWS_LENGTHS_10ms[6] = {160, 320, 480, 640, 960, 1920}; /* Last 960 dummy */ -const LC3_INT MDCT_WINDOWS_LENGTHS_2_5ms[6] = {40, 80, 120, 160, 240, 480}; - +const LC3_INT MDCT_WINDOWS_LENGTHS_7_5ms[6] = {120, 240, 360, 480, 720, 1440}; /* Last 960 dummy */ const LC3_INT MDCT_WINDOWS_LENGTHS_5ms[6] = {80, 160, 240, 320, 480, 960}; +const LC3_INT MDCT_WINDOWS_LENGTHS_2_5ms[6] = {40, 80, 120, 160, 240, 480}; + /* 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, @@ -3209,8 +5624,97 @@ const LC3_INT* ACC_COEFF_PER_BAND_5ms[5] = {ACC_COEFF_PER_BAND_8_5ms, ACC_COEFF_ ACC_COEFF_PER_BAND_24_5ms, ACC_COEFF_PER_BAND_32_5ms, ACC_COEFF_PER_BAND_48_5ms}; +#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}; + +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}; + +const LC3_INT ACC_COEFF_PER_BAND_24_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}; + +const LC3_INT ACC_COEFF_PER_BAND_32_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}; + +const LC3_INT ACC_COEFF_PER_BAND_48_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}; +#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 const LC3_INT32 xavg_N_grp[5] = { 4, 5, 6, 7, 8 }; @@ -3219,6 +5723,31 @@ const LC3_INT32 xavg_N_grp[5] = { 4, 5, 6, 7, 8 }; 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 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 */ + +}; + + + +/*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 }; +#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, @@ -3801,3 +6330,7 @@ const LC3_INT* ACC_COEFF_PER_BAND_PLC_5ms[] = { const LC3_INT32 mdct_grp_bins[10] = { 4, 14, 24, 44, 84, 164, 244, 324, 404, 484 }; +#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}; +#endif diff --git a/lib_lc3plus/constants.h b/lib_lc3plus/constants.h index c0c9e286e..ace0f9383 100644 --- a/lib_lc3plus/constants.h +++ b/lib_lc3plus/constants.h @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -11,6 +11,8 @@ #ifndef CONSTANTS_H #define CONSTANTS_H +#include "options.h" +#include "wmc_auto.h" #include "defines.h" #include "structs.h" @@ -18,13 +20,15 @@ extern const Complex dct2_16[16]; /* Ari coder */ -extern const LC3_INT ari_tns_order_cf[2][9]; -extern const LC3_INT ari_tns_freq_cf[8][18]; +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_INT ari_spec_cumfreq_fl[64][18]; +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]; @@ -128,6 +132,16 @@ 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]; +#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]; @@ -150,7 +164,6 @@ 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]; @@ -159,12 +172,15 @@ 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]; -extern const LC3_INT MDCT_WINDOWS_LENGTHS_10ms[6]; - -extern const LC3_INT MDCT_WINDOWS_LENGTHS_2_5ms[6]; - +#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]; +#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]; /* Per band energy */ extern const LC3_INT* ACC_COEFF_PER_BAND[6]; @@ -173,17 +189,31 @@ extern const LC3_INT* ACC_COEFF_PER_BAND_HR[6]; extern const LC3_INT* ACC_COEFF_PER_BAND_2_5ms_HR[6]; extern const LC3_INT* ACC_COEFF_PER_BAND_2_5ms[5]; +#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]; +#endif extern const LC3_INT* ACC_COEFF_PER_BAND_5ms_HR[6]; extern const LC3_INT* ACC_COEFF_PER_BAND_5ms[5]; /* 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]; @@ -200,4 +230,9 @@ 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]; +#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]; #endif + +#endif /* CONSTANTS_H */ diff --git a/lib_lc3plus/cutoff_bandwidth.c b/lib_lc3plus/cutoff_bandwidth.c index 642b2afda..c0ee62c62 100644 --- a/lib_lc3plus/cutoff_bandwidth.c +++ b/lib_lc3plus/cutoff_bandwidth.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -9,11 +9,12 @@ #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) { - LC3_INT i = 0; + LC3_INT i; if (len > bw_bin){ for (i = -1; i < 3; i++) { diff --git a/lib_lc3plus/dct4.c b/lib_lc3plus/dct4.c index 8fd5784b2..055db02cb 100644 --- a/lib_lc3plus/dct4.c +++ b/lib_lc3plus/dct4.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -9,6 +9,7 @@ #include "options.h" +#include "wmc_auto.h" #include "functions.h" void dct2_init(Dct2* dct, int length) @@ -30,18 +31,17 @@ void dct2_apply(Dct2* dct, const LC3_FLOAT* input, LC3_FLOAT* output) { Complex tmp1[MAX_LEN]; Complex tmp2[MAX_LEN]; - int i = 0; - const int len = dct->length; + int i; assert(input != output); - for (i = 0; i < len / 2; i++) { + for (i = 0; i < 8; i++) { tmp1[i] = cmplx(input[i * 2], 0); - tmp1[len - i - 1] = cmplx(input[i * 2 + 1], 0); + tmp1[16 - i - 1] = cmplx(input[i * 2 + 1], 0); } fft_apply(&dct->fft, tmp1, tmp2); - for (i = 0; i < len; i++) { + for (i = 0; i < 16; i++) { output[i] = cmul(tmp2[i], dct2_16[i]).r; } output[0] /= (LC3_FLOAT)1.414213562373095; /* SQRT(2) */ @@ -50,7 +50,7 @@ void dct2_apply(Dct2* dct, const LC3_FLOAT* input, LC3_FLOAT* output) void dct4_init(Dct4* dct, int length) { - int i = 0; + int i; assert(length <= MAX_LEN); dct->length = length; dct->twid1 = calloc(sizeof(*dct->twid1), length / 2); @@ -81,13 +81,13 @@ void dct4_apply(Dct4* dct, const LC3_FLOAT* input, LC3_FLOAT* output) const LC3_FLOAT norm = (LC3_FLOAT)1.0 / LC3_SQRT((LC3_FLOAT)(len >> 1)); assert(input != output); - for (i = 0; i < len / 2; i++) { + 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 / 2; i++) { + 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/dec_entropy.c b/lib_lc3plus/dec_entropy.c index d8512a106..4e1f830a2 100644 --- a/lib_lc3plus/dec_entropy.c +++ b/lib_lc3plus/dec_entropy.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -9,6 +9,7 @@ #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); @@ -32,7 +33,7 @@ void read_bit_fl(LC3_UINT8* ptr, LC3_INT* mask_side, LC3_INT* bp_side, LC3_INT* void read_uint_fl(LC3_INT nbits, LC3_UINT8* ptr, LC3_INT* mask_side, LC3_INT* bp_side, LC3_INT* val) { - LC3_INT bit = 0, i = 0; + LC3_INT bit, i; read_bit_fl(ptr, mask_side, bp_side, val); @@ -131,8 +132,8 @@ void processDecoderEntropy_fl(LC3_UINT8* bytes, LC3_INT numbytes, LC3_INT* mask_ LC3_INT* lsbMode, LC3_INT frame_dms) { - LC3_INT plc_trigger_bw = 0, plc_trigger_last_nz = 0, plc_trigger_SNS1 = 0, plc_trigger_SNS2 = 0, tmp = 0, bit = 0, - submodeMSB = 0, i = 0, ltpf_tmp[3] = {0}, ind = 0, submodeLSB = 0, bp_side_local = 0, mask_side_local = 0; + 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}; @@ -174,7 +175,7 @@ void processDecoderEntropy_fl(LC3_UINT8* bytes, LC3_INT numbytes, LC3_INT* mask_ } /* Last non-zero tuple */ - read_uint_fl(ceil(LC3_LOGTWO(N / 2)), ptr, &mask_side_local, &bp_side_local, lastnz); + read_uint_fl(ceil(LC3_LOGTWO(N >> 1)), ptr, &mask_side_local, &bp_side_local, lastnz); *lastnz = (*lastnz + 1) * 2; if (*lastnz > N) { diff --git a/lib_lc3plus/dec_lc3_fl.c b/lib_lc3plus/dec_lc3_fl.c index 88c528b0f..648326567 100644 --- a/lib_lc3plus/dec_lc3_fl.c +++ b/lib_lc3plus/dec_lc3_fl.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -9,6 +9,7 @@ #include "options.h" +#include "wmc_auto.h" #include "functions.h" @@ -58,21 +59,17 @@ static int Dec_LC3PLUS_Channel_fl(LC3PLUS_Dec* decoder, int channel, uint8_t* bs bfi = 2; switch (decoder->frame_dms) { -# ifdef ENABLE_025_DMS_MODE case 25: max_bw_stopband = max_bw_stopband >> 2; break; -# endif -# ifdef ENABLE_050_DMS_MODE case 50: max_bw_stopband = max_bw_stopband >> 1; break; -# endif -# ifdef ENABLE_075_DMS_MODE +#ifdef CR8_G_ADD_75MS case 75: max_bw_stopband = 3 * (max_bw_stopband >> 2); break; -# endif +#endif case 100: break; } @@ -151,7 +148,11 @@ static int Dec_LC3PLUS_Channel_fl(LC3PLUS_Dec* decoder, int channel, uint8_t* bs &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); + &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 ) @@ -171,6 +172,9 @@ static int Dec_LC3PLUS_Channel_fl(LC3PLUS_Dec* decoder, int channel, uint8_t* bs 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 ); { @@ -360,6 +364,10 @@ LC3PLUS_Error Dec_LC3PLUS_fl(LC3PLUS_Dec* decoder, uint8_t* input, LC3_INT32 num } } - if (decoder->last_error == LC3PLUS_OK && bfi) decoder->last_error = LC3PLUS_DECODE_ERROR; + 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 d978fa4e1..2ee688e6c 100644 --- a/lib_lc3plus/defines.h +++ b/lib_lc3plus/defines.h @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -11,6 +11,8 @@ #ifndef DEFINES_H #define DEFINES_H +#include "options.h" +#include "wmc_auto.h" #include "stdint.h" @@ -24,13 +26,14 @@ typedef int8_t LC3_INT8; typedef uint32_t LC3_UINT32; /* Release defines */ -// #define ENABLE_2_5MS_MODE +#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_HR_MODE_FL #define ENABLE_PADDING #define ENABLE_RFRAME_FL #define ENABLE_PLC @@ -41,90 +44,190 @@ typedef uint32_t LC3_UINT32; #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 +#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 +#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 +#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 0.2 +#define FAC2_FADEOUT 1.5 +#define FAC3_FADEOUT 1.75 +#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 + /* Precision Defines */ -#define LC3_FABS(x) (fabsf(x)) -#define LC3_POW(x, y) (powf(x, y)) +#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)) - -# 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 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)) + +#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 */ + +#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 */ typedef int32_t LC3_INT32; -# if defined(__xtensa__) -# define ALIGNMENT_BALLOC 4 -# define ALIGNMENT_BALLOC_RED 3 -# else -# define ALIGNMENT_BALLOC 8 -# define ALIGNMENT_BALLOC_RED 7 -# endif - -# define PLC2_FADEOUT_IN_MS 30 -# 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 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) */ - -# 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*/ -# 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 FEC_SLOT_BYTES_MIN 40 -# define FEC_SLOT_BYTES_MAX 400 - - -# 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 - -# define LC3_CONST_POW_2_100 1.267650600228229e+30 +#if defined(__xtensa__) +#define ALIGNMENT_BALLOC 4 +#define ALIGNMENT_BALLOC_RED 3 +#else +#define ALIGNMENT_BALLOC 8 +#define ALIGNMENT_BALLOC_RED 7 +#endif + +#ifndef CR8_A_PLC_FADEOUT_TUNING +#define PLC2_FADEOUT_IN_MS 30 +#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 */ + +#endif + +#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 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 FEC_SLOT_BYTES_MIN 40 +#define FEC_SLOT_BYTES_MAX 400 + +#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 + +#define LC3_CONST_POW_2_100 1.267650600228229e+30 /* G192 bitstream writing/reading */ #define G192_REDUNDANCY_FRAME 0x6B22 @@ -134,16 +237,30 @@ typedef int32_t LC3_INT32; #define G192_ONE 0x0081 #define READ_G192FER /* Allow C executable to also read G192 formatted FER files */ -# define LC3_EPS (1.1e-7f) +#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 */ +#endif +#endif + + +#define LC3_EPS (1.1e-7f) #define M_PI 3.14159265358979323846 /* FUNCTION MACROS */ #define CEILING(x, y) (((x) + (y)-1) / (y)) + + +#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)) @@ -154,11 +271,12 @@ typedef int32_t LC3_INT32; /* 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_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)) /* OPTIONS */ +#define MAX_LEN_NR 480 #define MAX_SR 96000 #define EXT_RES_ITER_MAX 20 #define MAX_BW_BANDS_NUMBER 6 @@ -175,25 +293,25 @@ typedef int32_t LC3_INT32; #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 +#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) #define MAX_BW_BIN 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 +#ifdef ENABLE_HR_MODE_FL +#define MAX_BW_HR 960 +#endif /* SCF */ #define M 16 diff --git a/lib_lc3plus/detect_cutoff_warped.c b/lib_lc3plus/detect_cutoff_warped.c index 939286720..21b73e806 100644 --- a/lib_lc3plus/detect_cutoff_warped.c +++ b/lib_lc3plus/detect_cutoff_warped.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -9,14 +9,15 @@ #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 = NULL, *warp_idx_stop = NULL; - LC3_INT counter = 0, brickwall = 0, i = 0, stop = 0, dist = 0; - LC3_FLOAT d2_mean = 0, d2_sum = 0, e_diff = 0, thr = 0; - const LC3_INT *bw_dist = NULL; + 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]; @@ -33,6 +34,13 @@ void processDetectCutoffWarped_fl(LC3_FLOAT* d2, LC3_INT fs_idx, LC3_INT frame_d 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]; diff --git a/lib_lc3plus/enc_entropy.c b/lib_lc3plus/enc_entropy.c index a7ff8cd70..dc285088a 100644 --- a/lib_lc3plus/enc_entropy.c +++ b/lib_lc3plus/enc_entropy.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -9,8 +9,12 @@ #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}; + 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 @@ -18,8 +22,8 @@ void processEncoderEntropy_fl(LC3_UINT8* bytes, LC3_INT* bp_side, LC3_INT* mask_ ) { LC3_UINT8* ptr; - LC3_INT i = 0, submodeMSB = 0, submodeLSB = 0, tmp = 0, gainMSB = 0, gainLSB = 0; - LC3_INT gainMSBbits[4] = {1, 1, 2, 2}, gainLSBbits[4] = {0, 1, 0, 1}; + LC3_INT i, submodeMSB, submodeLSB, tmp, gainMSB, gainLSB; + LC3_INT16 lastnzTrigger[5] = {63, 127, 127, 255, 255}; @@ -38,7 +42,7 @@ void processEncoderEntropy_fl(LC3_UINT8* bytes, LC3_INT* bp_side, LC3_INT* mask_ } else { - write_uint_backward_fl(ptr, bp_side, mask_side, lastnz / 2 - 1, ceil(LC3_LOGTWO(N / 2))); + write_uint_backward_fl(ptr, bp_side, mask_side, lastnz / 2 - 1, ceil(LC3_LOGTWO(N >> 1))); } /* LSB mode bit */ @@ -100,27 +104,25 @@ void processEncoderEntropy_fl(LC3_UINT8* bytes, LC3_INT* bp_side, LC3_INT* mask_ void write_uint_backward_fl(LC3_UINT8* ptr, LC3_INT* bp_side, LC3_INT* mask_side, LC3_INT val, LC3_INT numbits) { - LC3_INT k = 0, bit = 0; + 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 / 2; + val = val >> 1; } } 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] & (255 - *mask_side); - } else { + 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 * 2; + *mask_side = *mask_side << 1; } } diff --git a/lib_lc3plus/enc_lc3_fl.c b/lib_lc3plus/enc_lc3_fl.c index c89f7244c..56771ce5b 100644 --- a/lib_lc3plus/enc_lc3_fl.c +++ b/lib_lc3plus/enc_lc3_fl.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -9,6 +9,7 @@ #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 @@ -62,14 +63,22 @@ static void Enc_LC3PLUS_Channel_fl(LC3PLUS_Enc* encoder, int channel, int32_t* s /* Pitch estimation */ processOlpa_fl(h_EncSetup->s_12k8, h_EncSetup->olpa_mem_s12k8, h_EncSetup->olpa_mem_s6k4, - &h_EncSetup->olpa_mem_pitch, &T0_out, &normcorr, s_12k8_len, encoder->frame_dms); + &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); + <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, @@ -79,8 +88,12 @@ static void Enc_LC3PLUS_Channel_fl(LC3PLUS_Enc* encoder, int channel, int32_t* s /* 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); - + 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) { @@ -100,8 +113,8 @@ static void Enc_LC3PLUS_Channel_fl(LC3PLUS_Enc* encoder, int channel, int32_t* s BW_cutoff_idx = 0; } - processSnsComputeScf_fl(h_EncSetup->ener, encoder->tilt, encoder->bands_number, h_EncSetup->scf, - h_EncSetup->attdec_detected, encoder->sns_damping, encoder->attdec_damping); + 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); diff --git a/lib_lc3plus/estimate_global_gain.c b/lib_lc3plus/estimate_global_gain.c index df9b1f5f2..2e69d239b 100644 --- a/lib_lc3plus/estimate_global_gain.c +++ b/lib_lc3plus/estimate_global_gain.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -9,6 +9,7 @@ #include "options.h" +#include "wmc_auto.h" #include "functions.h" @@ -19,9 +20,9 @@ void processEstimateGlobalGain_fl(LC3_FLOAT x[], LC3_INT lg, LC3_INT nbitsSQ, LC ) { - LC3_INT i = 0, N = 0, offset = 0, j = 0, iszero = 0; - LC3_FLOAT g_min = 0, x_max = 0, tmp = 0, ind = 0, ind_min = 0, target = 0, fac = 0, ener = 0; - LC3_FLOAT en[MAX_LEN / 4] = {0}; + 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) { @@ -61,7 +62,7 @@ void processEstimateGlobalGain_fl(LC3_FLOAT x[], LC3_INT lg, LC3_INT nbitsSQ, LC } else { g_min = x_max / (32767 - 0.375); } - /* Prevent positive rounding errors from LC3_LOGTEN function */ + /* 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); @@ -85,8 +86,9 @@ void processEstimateGlobalGain_fl(LC3_FLOAT x[], LC3_INT lg, LC3_INT nbitsSQ, LC fac = 256; offset = 255 + quantizedGainOff; - for (i = 0; i < 8; i++) { - fac = fac * 0.5; + for (i = 0; i < 8; i++) + { + fac = fac >> 1; offset = offset - fac; ener = 0; iszero = 1; diff --git a/lib_lc3plus/fft/cfft.c b/lib_lc3plus/fft/cfft.c index 4bd8d29ad..d96516391 100644 --- a/lib_lc3plus/fft/cfft.c +++ b/lib_lc3plus/fft/cfft.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -8,7 +8,9 @@ ******************************************************************************/ + #include "options.h" +#include "wmc_auto.h" #include "cfft.h" #include "iisfft.h" /* for M_PIl */ #include /* for abs() */ @@ -385,8 +387,10 @@ void LC3_cfft(LC3_FLOAT* re, LC3_FLOAT* im, LC3_INT length, LC3_INT stride, LC3_ 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) + if (!CFFT_PLAN_SUPPORT(length) || (abs(sign) != 1)) + { return 0; + } handle->len = length; handle->sign = sign; @@ -417,5 +421,7 @@ void LC3_cfft_apply(Cfft* handle, LC3_FLOAT* re, LC3_FLOAT* im, LC3_INT 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 index 3902b4c39..18f1e80ad 100644 --- a/lib_lc3plus/fft/cfft.h +++ b/lib_lc3plus/fft/cfft.h @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -9,6 +9,8 @@ +#include "options.h" +#include "wmc_auto.h" #include "../functions.h" #ifndef CFFT_H diff --git a/lib_lc3plus/fft/fft_15_16.h b/lib_lc3plus/fft/fft_15_16.h index 83ca77353..c527f1bf5 100644 --- a/lib_lc3plus/fft/fft_15_16.h +++ b/lib_lc3plus/fft/fft_15_16.h @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * diff --git a/lib_lc3plus/fft/fft_240_480.h b/lib_lc3plus/fft/fft_240_480.h index c1d96c87b..18a0c8707 100644 --- a/lib_lc3plus/fft/fft_240_480.h +++ b/lib_lc3plus/fft/fft_240_480.h @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * diff --git a/lib_lc3plus/fft/fft_2_9.h b/lib_lc3plus/fft/fft_2_9.h index 54f4f839d..55fe84f3b 100644 --- a/lib_lc3plus/fft/fft_2_9.h +++ b/lib_lc3plus/fft/fft_2_9.h @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * diff --git a/lib_lc3plus/fft/fft_32.h b/lib_lc3plus/fft/fft_32.h index 48b891108..803923a01 100644 --- a/lib_lc3plus/fft/fft_32.h +++ b/lib_lc3plus/fft/fft_32.h @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * diff --git a/lib_lc3plus/fft/fft_384_768.h b/lib_lc3plus/fft/fft_384_768.h index 47f42e90d..bd89393c1 100644 --- a/lib_lc3plus/fft/fft_384_768.h +++ b/lib_lc3plus/fft/fft_384_768.h @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * diff --git a/lib_lc3plus/fft/fft_60_128.h b/lib_lc3plus/fft/fft_60_128.h index 75f1aaef4..e5a88ccad 100644 --- a/lib_lc3plus/fft/fft_60_128.h +++ b/lib_lc3plus/fft/fft_60_128.h @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * diff --git a/lib_lc3plus/fft/fft_generic.h b/lib_lc3plus/fft/fft_generic.h index e517ffb25..903875ab5 100644 --- a/lib_lc3plus/fft/fft_generic.h +++ b/lib_lc3plus/fft/fft_generic.h @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * diff --git a/lib_lc3plus/fft/iis_fft.c b/lib_lc3plus/fft/iis_fft.c index b1f8ab5ab..be71d8e4a 100644 --- a/lib_lc3plus/fft/iis_fft.c +++ b/lib_lc3plus/fft/iis_fft.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -9,14 +9,15 @@ #include "options.h" +#include "wmc_auto.h" #include #include #include #include #include #include - #include "iis_fft.h" + /**************************************************************************************************/ /* AFFT uses two fft implementations @@ -25,7 +26,6 @@ fast lengths, check the fft_n function. */ - #define FFT_COMPLEX 1 #define FFT_REAL 2 @@ -38,14 +38,20 @@ static IIS_FFT_ERROR create(HANDLE_IIS_FFT* handle, LC3_INT type, LC3_INT len, I LC3_INT trlen = (type == FFT_COMPLEX) ? len : len / 2; /* check argument sanity */ - if (sign != IIS_FFT_FWD && sign != IIS_FFT_BWD) + 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)); + { + (*handle) = (HANDLE_IIS_FFT)calloc(1, sizeof(IIS_FFT)); + } + if (!(*handle)) + { return IIS_FFT_MEMORY_ERROR; + } (*handle)->len = len; (*handle)->sign = sign; @@ -122,7 +128,9 @@ IIS_FFT_ERROR LC3_IIS_FFT_Apply_CFFT(HANDLE_IIS_FFT handle, const Complex* input { LC3_FLOAT* dummy; if (!handle) + { return IIS_FFT_INTERNAL_ERROR; + } /* check for inplace operation */ memmove(output, input, sizeof(*input) * handle->len); diff --git a/lib_lc3plus/fft/iis_fft.h b/lib_lc3plus/fft/iis_fft.h index b658930fa..a145c490d 100644 --- a/lib_lc3plus/fft/iis_fft.h +++ b/lib_lc3plus/fft/iis_fft.h @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -11,6 +11,8 @@ #ifndef IIS_FFT_H #define IIS_FFT_H +#include "options.h" +#include "wmc_auto.h" #include "../structs.h" #include "../defines.h" #include "cfft.h" diff --git a/lib_lc3plus/fft/iisfft.c b/lib_lc3plus/fft/iisfft.c index 227d2b603..bcd00503f 100644 --- a/lib_lc3plus/fft/iisfft.c +++ b/lib_lc3plus/fft/iisfft.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -8,8 +8,9 @@ ******************************************************************************/ -#include "options.h" +#include "options.h" +#include "wmc_auto.h" #include #include /* for mmove */ #include @@ -60,7 +61,9 @@ 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)) { @@ -68,7 +71,9 @@ IIS_FFT_ERROR LC3_iisfft_plan(Iisfft* handle, LC3_INT length, LC3_INT sign) 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) { @@ -78,7 +83,9 @@ IIS_FFT_ERROR LC3_iisfft_plan(Iisfft* handle, LC3_INT length, LC3_INT sign) if (lengthOfPrimeScratch > BORDER_FOR_SECOND_SCRATCH) { handle->scratch2 = (LC3_INT*)malloc(sizeof(LC3_INT) * lengthOfPrimeScratch); if (!handle->scratch2) + { return IIS_FFT_MEMORY_ERROR; + } } } @@ -89,7 +96,9 @@ void LC3_iisfft_free(Iisfft* handle) { handle->length = 0; if (handle->scratch2) + { free(handle->scratch2); + } } diff --git a/lib_lc3plus/fft/iisfft.h b/lib_lc3plus/fft/iisfft.h index 7b448e2bb..a77a1af7e 100644 --- a/lib_lc3plus/fft/iisfft.h +++ b/lib_lc3plus/fft/iisfft.h @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -11,6 +11,8 @@ #ifndef IISFFT_H #define IISFFT_H +#include "options.h" +#include "wmc_auto.h" #include "../defines.h" #ifndef M_PIl diff --git a/lib_lc3plus/functions.h b/lib_lc3plus/functions.h index 7a529a25d..01ad936f0 100644 --- a/lib_lc3plus/functions.h +++ b/lib_lc3plus/functions.h @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -11,6 +11,8 @@ #ifndef FUNCTIONS_H #define FUNCTIONS_H +#include "options.h" +#include "wmc_auto.h" #include "clib.h" #include "defines.h" #include "float.h" @@ -106,8 +108,11 @@ void processNoiseFactor_fl(LC3_INT* fac_ns_idx, LC3_FLOAT x[], LC3_INT xq[], LC3 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 processOlpa_fl(LC3_FLOAT* s_12k8, LC3_FLOAT* mem_s12k8, LC3_FLOAT* mem_s6k4, LC3_INT* mem_old_T0, LC3_INT* T0_out, - LC3_FLOAT* normcorr_out, LC3_INT len, LC3_INT frame_dms); +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); 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 @@ -117,14 +122,18 @@ void levinsonDurbin(LC3_FLOAT* r, LC3_FLOAT* out_lev, LC3_FLOAT* rc_unq, LC3_FLO 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); -void processSnsComputeScf_fl(LC3_FLOAT* x, LC3_INT tilt, LC3_INT xLen, LC3_FLOAT* gains, LC3_INT smooth, LC3_FLOAT sns_damping, LC3_FLOAT attdec_damping_factor); +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); void processSnsInterpolateScf_fl(LC3_FLOAT* gains, LC3_INT encoder_side, LC3_INT bands_number, LC3_FLOAT* gains_LC3_INT); 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); - + const LC3_INT bands_number, const LC3_FLOAT* ener +#ifdef CR8_E_TONE_DETECTOR + , const LC3_INT16 frame_dms, const LC3_INT16 hrmode ); +#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, @@ -134,12 +143,19 @@ void ProcessingITDA_WIN_OLA_fl(LC3_FLOAT* x_tda, LC3_INT32 yLen, const LC3_FLOAT 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); + LC3_INT* param, LC3_FLOAT* mem_norm_corr_past_past, LC3_INT* bits +#ifdef CR9_K_REDUCE_NORM_CORR_TH + ,LC3_INT16 hrmode +#endif +); 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 +#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[], @@ -225,10 +241,19 @@ void processPlcDampingScramblingMain_fl(LC3_INT32 *ns_seed, 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); + LC3_FLOAT *cum_fflcAtten +#ifdef CR8_A_PLC_FADEOUT_TUNING + , LC3_UINT8 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); + 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 + ); 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); @@ -253,7 +278,12 @@ void plc_phEcu_spec_ana(LC3_FLOAT* xfp, LC3_INT32 xfp_len, const LC3_FLOAT* 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, LC3_FLOAT *corr_phase_dbg, + LC3_INT32 t_adv_in, LC3_INT32 Lprot, LC3_INT32 delta_corr, +#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, @@ -268,12 +298,21 @@ void plc_phEcu_tba_per_band_gain(LC3_INT32 n_grp, LC3_FLOAT *gr_pow_left, LC3_FL 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); + LC3_FLOAT *att_val, LC3_INT32 *attDegreeFrames, + LC3_FLOAT *thresh_dbg +#ifdef CR8_A_PLC_FADEOUT_TUNING + , LC3_UINT8 plc_fadeout_type +#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); + LC3_INT32 *tr_dec_dbg, LC3_FLOAT *gpc_dbg +#ifdef CR8_A_PLC_FADEOUT_TUNING + , LC3_UINT8 plc_fadeout_type +#endif + ); void plc_phEcu_hq_ecu( LC3_FLOAT *f0binPtr, LC3_FLOAT *f0ltpGainPtr, LC3_FLOAT *xfp, LC3_INT16 prev_bfi, LC3_INT32 *short_flag_prev, @@ -287,6 +326,10 @@ void plc_phEcu_hq_ecu( 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 +#endif ); void processTdcPreemphasis_fl(LC3_FLOAT *in, LC3_FLOAT *pre_emph_factor, LC3_INT32 n_bands); @@ -296,7 +339,11 @@ void processTdcInverseOdft_fl(LC3_FLOAT *in, LC3_INT32 n_bands, LC3_FLOAT *out, 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); + 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 +); void* balloc(void* base, size_t* base_size, size_t size); diff --git a/lib_lc3plus/imdct.c b/lib_lc3plus/imdct.c index 5d38aa6cc..b2ef8ee92 100644 --- a/lib_lc3plus/imdct.c +++ b/lib_lc3plus/imdct.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -9,13 +9,14 @@ #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] = {0}, x_ov[2 * MAX_LEN] = {0}; - LC3_INT i = 0, j = 0; + LC3_FLOAT x_tda[MAX_LEN], x_ov[2 * MAX_LEN]; + LC3_INT i, j; /* Flip imdct window up to down */ i = winLen - 1; @@ -61,7 +62,7 @@ void ProcessingIMDCT_fl(LC3_FLOAT* y, LC3_INT yLen, const LC3_FLOAT* win, LC3_IN 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] = {0}; + LC3_FLOAT x_ov[2 * MAX_LEN]; LC3_INT32 i, j; move_float(x_ov, &x_tda[yLen / 2], yLen / 2); diff --git a/lib_lc3plus/lc3.c b/lib_lc3plus/lc3.c index 17d2ccb71..e3f4491d2 100644 --- a/lib_lc3plus/lc3.c +++ b/lib_lc3plus/lc3.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -9,6 +9,7 @@ #include "options.h" +#include "wmc_auto.h" #include "lc3.h" #include "defines.h" #include "functions.h" @@ -71,6 +72,9 @@ static int lc3plus_frame_size_supported(float frame_ms) { case 25: /* fallthru */ case 50: /* fallthru */ +#ifdef CR8_G_ADD_75MS + case 75: /* fallthru */ +#endif case 100: return 1; default: break; } @@ -102,7 +106,6 @@ int32_t lc3_enc_supported_lfe(void) LC3PLUS_Error lc3plus_enc_init(LC3PLUS_Enc *encoder, int samplerate, int channels, int hrmode, 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); @@ -198,7 +201,6 @@ LC3PLUS_Error lc3plus_enc_set_frame_dms(LC3PLUS_Enc *encoder, int frame_dms) 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); @@ -359,7 +361,7 @@ LC3PLUS_Error lc3plus_free_encoder_structs(LC3PLUS_Enc* encoder) LC3PLUS_Error lc3plus_free_decoder_structs(LC3PLUS_Dec* decoder) { - int ch = 0; + int ch = 0; RETURN_IF(!decoder, LC3PLUS_NULL_ERROR); for (ch = 0; ch < decoder->channels; ch++) { @@ -388,7 +390,6 @@ LC3PLUS_Error lc3plus_enc_set_ep_mode(LC3PLUS_Enc *encoder, LC3PLUS_EpMode epmod { 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; diff --git a/lib_lc3plus/lc3.h b/lib_lc3plus/lc3.h index 3e45438fe..fab259e96 100644 --- a/lib_lc3plus/lc3.h +++ b/lib_lc3plus/lc3.h @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -25,6 +25,8 @@ #define LC3PLUS_H #ifndef _MSC_VER +#include "options.h" +#include "wmc_auto.h" #include #else typedef unsigned char uint8_t; @@ -36,7 +38,7 @@ typedef __int32 int32_t; #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, 6, 9) +#define LC3PLUS_VERSION LC3PLUS_VERSION_INT(1, 7, 2) /*! Maximum number of supported channels. The actual binary might support * less, use lc3plus_channels_supported() to check. */ diff --git a/lib_lc3plus/lc3plus_fft.c b/lib_lc3plus/lc3plus_fft.c index 14f443f86..c7911b92d 100644 --- a/lib_lc3plus/lc3plus_fft.c +++ b/lib_lc3plus/lc3plus_fft.c @@ -1,14 +1,15 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* 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" @@ -19,11 +20,11 @@ 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; } @@ -31,10 +32,10 @@ void fft_init(Fft* fft, int length) 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)); } @@ -82,7 +83,7 @@ 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); } @@ -90,10 +91,11 @@ void fft_apply(Fft* fft, const Complex* input, Complex* output) 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); + error = LC3_IIS_FFT_Apply_RFFT(fft->handle, input, output); assert(error == IIS_FFT_NO_ERROR); } + diff --git a/lib_lc3plus/license.h b/lib_lc3plus/license.h index d9d6c8967..077df126e 100644 --- a/lib_lc3plus/license.h +++ b/lib_lc3plus/license.h @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -8,11 +8,13 @@ ******************************************************************************/ +#include "options.h" +#include "wmc_auto.h" #include "defines.h" static const char *const LICENSE = "*******************************************************************************\n" - "* ETSI TS 103 634 V1.4.1 *\n" + "* ETSI TS 103 634 V1.4.3 *\n" "* Low Complexity Communication Codec Plus (LC3plus) *\n" "* Floating Point Software V%i.%i.%iETSI, " __DATE__ " *\n" "* Copyright licence is solely granted through ETSI Intellectual Property *\n" diff --git a/lib_lc3plus/ltpf_coder.c b/lib_lc3plus/ltpf_coder.c index fac8c481c..81a491ab9 100644 --- a/lib_lc3plus/ltpf_coder.c +++ b/lib_lc3plus/ltpf_coder.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -9,13 +9,14 @@ #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 = 0; + LC3_INT max_i = 0, i; LC3_FLOAT max = 0; if (len <= 0) { @@ -34,16 +35,29 @@ LC3_INT searchMaxIndice(LC3_FLOAT* in, LC3_INT len) 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) + 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)] = {0}, sum = 0, buf_tmp[MAX_LEN] = {0}, cor_up[MAX_LEN] = {0}, *x; - LC3_INT i = 0, j = 0, k = 0, n = 0, step = 0, N = 0, ltpf_active = 0, pitch_search_delta = 0, + 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 norm_corr = 0, cor[MAX_LEN] = {0}, cor_int[MAX_LEN] = {0}, currFrame[MAX_LEN] = {0}, predFrame[MAX_LEN] = {0}, sum1 = 0, sum2 = 0, sum3 = 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]; @@ -59,7 +73,12 @@ void process_ltpf_coder_fl(LC3_FLOAT* xin, LC3_INT xLen, LC3_INT ltpf_enable, LC pitch_search_upsamp = 4; pitch_search_L_interpol1 = 4; - if (pitch_ol_norm_corr > 0.6) { +#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; @@ -83,19 +102,24 @@ void process_ltpf_coder_fl(LC3_FLOAT* xin, LC3_INT xLen, LC3_INT ltpf_enable, LC 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; i <= t_max; i++) { - sum = 0; - for (j = 0; j < acflen; j++) { - sum += x[j] * x[j - i]; - } + for (i = t_min + 1; i <= t_max; i++) { + sum = mac_loop(x, &x[-i], acflen); - if (i > t_min) { - sum2 = sum2 + x[-i]*x[-i] + sum2 = sum2 + x[-i]*x[-i] - x[acflen - 1 - ( i - 1 )]*x[acflen - 1 - ( i - 1 )]; - } - sum3 = LC3_SQRT(sum1 * sum2) + LC3_POW(10, -5); + + sum3 = LC3_SQRT(sum1 * sum2) + 1.00e-05; norm_corr = sum / sum3; norm_corr = MAX(0, norm_corr); @@ -104,13 +128,7 @@ void process_ltpf_coder_fl(LC3_FLOAT* xin, LC3_INT xLen, LC3_INT ltpf_enable, LC } /* Find Integer Pitch-Lag */ - j = 0; - for (i = pitch_search_L_interpol1; i <= t_max - t_min - pitch_search_L_interpol1; i++) { - buf_tmp[j] = cor[i]; - j++; - } - - temp2 = searchMaxIndice(buf_tmp, j); + 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); @@ -128,13 +146,7 @@ void process_ltpf_coder_fl(LC3_FLOAT* xin, LC3_INT xLen, LC3_INT ltpf_enable, LC } for (i = 0; i < pitch_search_upsamp * (t0_max - t0_min + 1); i++) { - sum = 0; - - k = 0; - for (j = i; j < i + 32; j++) { - sum += cor_up[j] * inter4_1[k]; - k++; - } + sum = mac_loop(&cor_up[i], (const LC3_FLOAT *)inter4_1, 32); cor_int[i] = sum; } @@ -153,14 +165,15 @@ void process_ltpf_coder_fl(LC3_FLOAT* xin, LC3_INT xLen, LC3_INT ltpf_enable, LC } else { delta_down = pitch_search_upsamp - step; } - + j = 0; for (i = midpoint - delta_down - 1; i <= midpoint + delta_up; i = i + step) { - buf_tmp[j] = cor_int[i]; + cor[j] = cor_int[i]; j++; } - temp2 = searchMaxIndice(buf_tmp, ((midpoint + delta_up) - (midpoint - delta_down)) / step + 1); + + temp2 = searchMaxIndice(cor, ((midpoint + delta_up) - (midpoint - delta_down)) / step + 1); pitch_fr = temp2 * step - delta_down; if (pitch_fr >= 0) { @@ -188,34 +201,25 @@ void process_ltpf_coder_fl(LC3_FLOAT* xin, LC3_INT xLen, LC3_INT ltpf_enable, LC pitch = (LC3_FLOAT) pitch_int + (LC3_FLOAT) pitch_fr / 4.0; + /* Normalized Correlation */ + sum1 = sum2 = sum3 = 0; for (n = 0; n < acflen; n++) { - currFrame[n] = x[n + 1] * enc_inter_filter[0][0] + + 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]; - predFrame[n] = x[n - pitch_int + 1] * enc_inter_filter[pitch_fr][0] + + 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; } - /* Normalized Correlation */ - sum1 = sum2 = sum3 = 0; - - for (i = 0; i < acflen; i++) { - sum1 += currFrame[i] * predFrame[i]; - } - - for (i = 0; i < acflen; i++) { - sum2 += currFrame[i] * currFrame[i]; - } - - for (i = 0; i < acflen; i++) { - sum3 += predFrame[i] * predFrame[i]; - } - - sum2 = LC3_SQRT(sum2 * sum3) + LC3_POW(10, -5); + sum2 = LC3_SQRT(sum2 * sum3) + 1.00e-05; norm_corr = sum1 / sum2; assert(norm_corr >= -1.00001 && norm_corr <= 1.00001); diff --git a/lib_lc3plus/ltpf_decoder.c b/lib_lc3plus/ltpf_decoder.c index a40c85213..d51c7ffe3 100644 --- a/lib_lc3plus/ltpf_decoder.c +++ b/lib_lc3plus/ltpf_decoder.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -9,6 +9,7 @@ #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, @@ -16,18 +17,31 @@ void process_ltpf_decoder_fl(LC3_FLOAT* x, LC3_INT xLen, LC3_FLOAT* y, LC3_INT f 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 = 0, j = 0, n = 0, N = 0, L_past_x = 0, N4 = 0, N34 = 0, - pitch_int = 0, pitch_fr = 0, p1 = 0, p2 = 0, L_past_y = 0, inter_len = 0, tilt_len = 0, - tilt_len_r = 0, inter_len_r = 0, old_x_len = 0, old_y_len = 0; - - LC3_FLOAT conf_alpha = 0, gain = 0, a1[MAX_LEN] = {0}, a2[MAX_LEN] = {0}, b1[MAX_LEN] = {0}, b2[MAX_LEN] = {0}, - buf_x[4 * MAX_LEN] = {0}, buf_y[4 * MAX_LEN] = {0}, buf_z[4 * MAX_LEN] = {0}, pitch = 0, sum1 = 0, sum2 = 0; - + 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) { @@ -213,6 +227,13 @@ void process_ltpf_decoder_fl(LC3_FLOAT* x, LC3_INT xLen, LC3_FLOAT* y, LC3_INT f } /* 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); @@ -232,8 +253,14 @@ void process_ltpf_decoder_fl(LC3_FLOAT* x, LC3_INT xLen, LC3_FLOAT* y, LC3_INT f 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) { @@ -252,7 +279,12 @@ void process_ltpf_decoder_fl(LC3_FLOAT* x, LC3_INT xLen, LC3_FLOAT* y, LC3_INT f 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++) { @@ -273,6 +305,69 @@ void process_ltpf_decoder_fl(LC3_FLOAT* x, LC3_INT xLen, LC3_FLOAT* y, LC3_INT f 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; @@ -292,7 +387,7 @@ void process_ltpf_decoder_fl(LC3_FLOAT* x, LC3_INT xLen, LC3_FLOAT* y, LC3_INT f (((LC3_FLOAT)N4 - (LC3_FLOAT)n) / (LC3_FLOAT)N4) * sum2; } - memmove(buf_z, buf_y, sizeof(LC3_FLOAT) * 4 * MAX_LEN); + memmove(buf_z, buf_y, sizeof(LC3_FLOAT) * (old_y_len + xLen)); for (n = 0; n < N4; n++) { sum1 = 0; @@ -311,8 +406,45 @@ void process_ltpf_decoder_fl(LC3_FLOAT* x, LC3_INT xLen, LC3_FLOAT* y, LC3_INT f 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], @@ -336,7 +468,7 @@ void process_ltpf_decoder_fl(LC3_FLOAT* x, LC3_INT xLen, LC3_FLOAT* y, LC3_INT f 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); @@ -353,4 +485,14 @@ void process_ltpf_decoder_fl(LC3_FLOAT* x, LC3_INT xLen, LC3_FLOAT* y, LC3_INT f *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/mdct.c b/lib_lc3plus/mdct.c index 11618b946..ef2d7c087 100644 --- a/lib_lc3plus/mdct.c +++ b/lib_lc3plus/mdct.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -9,6 +9,7 @@ #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) @@ -31,6 +32,26 @@ static const LC3_FLOAT* mdct_window(LC3_INT length, LC3_INT frame_dms, LC3_INT h 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: @@ -74,10 +95,15 @@ void mdct_init(Mdct* mdct, LC3_INT length, LC3_INT frame_dms, LC3_INT fs_idx, LC { 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]; } @@ -103,8 +129,8 @@ void mdct_free(Mdct* mdct) void mdct_apply(const LC3_FLOAT* input, LC3_FLOAT* output, Mdct* mdct) { - LC3_FLOAT tmp[MAX_LEN * 2] = {0}; - LC3_INT i = 0; + LC3_FLOAT tmp[MAX_LEN * 2]; + LC3_INT i; LC3_INT hlen; move_float(tmp, mdct->mem, mdct->mem_length); @@ -125,4 +151,7 @@ void mdct_apply(const LC3_FLOAT* input, LC3_FLOAT* output, Mdct* mdct) dct4_apply(&mdct->dct, tmp, output); } -void processMdct_fl(LC3_FLOAT* in, LC3_FLOAT* out, Mdct* mdctStruct) { mdct_apply(in, out, mdctStruct); } +void processMdct_fl(LC3_FLOAT* in, LC3_FLOAT* out, Mdct* mdctStruct) +{ + mdct_apply(in, out, mdctStruct); +} diff --git a/lib_lc3plus/mdct_shaping.c b/lib_lc3plus/mdct_shaping.c index 187619250..eba6f3270 100644 --- a/lib_lc3plus/mdct_shaping.c +++ b/lib_lc3plus/mdct_shaping.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -9,15 +9,20 @@ #include "options.h" +#include "wmc_auto.h" #include "functions.h" void processMdctShaping_fl(LC3_FLOAT x[], LC3_FLOAT scf[], const LC3_INT bands_offset[], LC3_INT fdns_npts) { - LC3_INT i = 0, j = 0; + LC3_INT i, j; + LC3_FLOAT val; + j = 0; for (i = 0; i < fdns_npts; i++) { + val = scf[i]; + for (; j < bands_offset[i + 1]; j++) { - x[j] = x[j] * scf[i]; + x[j] = x[j] * val; } } } diff --git a/lib_lc3plus/near_nyquist_detector.c b/lib_lc3plus/near_nyquist_detector.c index ce9435130..ee34361ef 100644 --- a/lib_lc3plus/near_nyquist_detector.c +++ b/lib_lc3plus/near_nyquist_detector.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -7,32 +7,87 @@ * estoppel or otherwise. * ******************************************************************************/ -#include "functions.h" #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) + 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 { - LC3_INT i = 0; - LC3_FLOAT ener_low = FLT_EPSILON, ener_high = 0; + // 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; - for (i=0; i NN_thresh * ener_low){ - *near_nyquist_flag = 1; + // 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/noise_factor.c b/lib_lc3plus/noise_factor.c index c5aa582e4..5e4ecd7b9 100644 --- a/lib_lc3plus/noise_factor.c +++ b/lib_lc3plus/noise_factor.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -9,100 +9,118 @@ #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, end = 0, start = 0, i = 0, j = 0, k = 0, - allZeros = 0, m = 0; - LC3_FLOAT fac_ns_unq = 0, mean = 0, idx = 0, nsf1 = 0, nsf2 = 0; - LC3_INT zeroLines[MAX_LEN] = {0}, zL1[MAX_LEN] = {0}, zL2[MAX_LEN] = {0}; + 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 = 4; + nTransWidth = 1; startOffset = 6; break; case 50: - nTransWidth = 4; + nTransWidth = 1; startOffset = 12; break; +#ifdef CR8_G_ADD_75MS + case 75: + nTransWidth = 2; + startOffset = 18; + break; +#endif case 100: - nTransWidth = 8; + nTransWidth = 3; startOffset = 24; break; } - for (k = startOffset; k < BW_cutoff_idx; k++) { - allZeros = 1; - - start = k - (nTransWidth - 2) / 2; - end = MIN(BW_cutoff_idx - 1, k + (nTransWidth - 2) / 2); - - for (i = start; i <= end; i++) { - if (xq[i] != 0) { - allZeros = 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_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; + } + } - if (allZeros == 1) { - zeroLines[j] = k + 1; - kZeroLines++; - j++; + for (k = BW_cutoff_idx - nTransWidth; k < BW_cutoff_idx; k++) + { + nzeros ++; + if (nzeros >= 0) + { + zeroLines[j++] = k; } } - for (i = 0; i < kZeroLines; i++) { - sumZeroLines += zeroLines[i]; + if (j == 0) { + fac_ns_unq = 0; } + else + { + kZeroLines = j; - if (sumZeroLines > 0) { + fac_ns_unq = 0; for (j = 0; j < kZeroLines; j++) { - mean += LC3_FABS(x[zeroLines[j] - 1]); + fac_ns_unq += LC3_FABS(x[zeroLines[j]]); } - fac_ns_unq = mean / (gg * kZeroLines); - } else { - fac_ns_unq = 0; - } + 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]; + } - if (kZeroLines > 0) - { - if (target_bytes <= 20 && frame_dms == 100) { - j = 0, k = 0; m = floor(sumZeroLines / kZeroLines); for (i = 0; i < kZeroLines; i++) { if (zeroLines[i] <= m) { - zL1[j] = zeroLines[i]; j++; + nsf1 += LC3_FABS(x[zeroLines[i]]); } - - if (zeroLines[i] > m) { - zL2[k] = zeroLines[i]; + else { + nsf2 += LC3_FABS(x[zeroLines[i]]); k++; } } - mean = 0; - for (i = 0; i < j; i++) { - mean += LC3_FABS(x[zL1[i] - 1]) / gg; - } - - nsf1 = mean / j; - - mean = 0; - for (i = 0; i < k; i++) { - mean += LC3_FABS(x[zL2[i] - 1]) / gg; - } - - nsf2 = mean / k; + nsf1 /= (gg) * j; + nsf2 /= (gg) * k; fac_ns_unq = MIN(nsf1, nsf2); } + } idx = round(8 - 16 * fac_ns_unq); diff --git a/lib_lc3plus/noise_filling.c b/lib_lc3plus/noise_filling.c index 7fac5e0f7..b844aef08 100644 --- a/lib_lc3plus/noise_filling.c +++ b/lib_lc3plus/noise_filling.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -9,12 +9,13 @@ #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] = {0}; - LC3_INT nTransWidth = 0, startOffset = 0, i = 0, j = 0, k = 0, start = 0, end = 0, allZeros = 0, kZeroLines = 0; + LC3_INT zeroLines[MAX_LEN]; + LC3_INT nTransWidth, startOffset, j, k, nzeros = 0, kZeroLines; LC3_FLOAT fac_ns = 0; switch (frame_dms) @@ -27,6 +28,12 @@ void processNoiseFilling_fl(LC3_FLOAT xq[], LC3_INT nfseed, LC3_INT fac_ns_idx, nTransWidth = 1; startOffset = 12; break; +#ifdef CR8_G_ADD_75MS + case 75: + nTransWidth = 2; + startOffset = 18; + break; +#endif case 100: nTransWidth = 3; startOffset = 24; @@ -37,25 +44,44 @@ void processNoiseFilling_fl(LC3_FLOAT xq[], LC3_INT nfseed, LC3_INT fac_ns_idx, j = 0; - for (k = startOffset; k < bw_stopband; k++) { - allZeros = 1; - - start = k - nTransWidth; - end = MIN(bw_stopband - 1, k + nTransWidth); - - for (i = start; i <= end; i++) { - if (xq[i] != 0) { - allZeros = 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; } + } - if (allZeros == 1) { - zeroLines[j] = k; - kZeroLines++; - j++; + 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; diff --git a/lib_lc3plus/olpa.c b/lib_lc3plus/olpa.c index 6bec50952..62a303f26 100644 --- a/lib_lc3plus/olpa.c +++ b/lib_lc3plus/olpa.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -9,31 +9,27 @@ #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_FLOAT len_buf, LC3_INT len_input); -static LC3_INT searchMaxIndice(LC3_FLOAT* in, LC3_INT len); +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_FLOAT len_buf, LC3_INT len_input) +void filter_olpa(LC3_FLOAT* in, LC3_FLOAT* out, const LC3_FLOAT* buf, LC3_INT32 len_input) { - LC3_INT i = 0, j = 0; - LC3_FLOAT sum = 0; /* a = 1, so denominator == 1, nothing to do here */ + LC3_INT32 i, j; - for (i = 0; i < len_input; i++) { - j = 0; - sum = 0; - for (j = 0; (j < len_buf) && (j <= i); j++) { - sum += buf[j] * in[i - j]; - } - out[i] = sum; + 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 = 0; + LC3_INT max_i = 0, i; LC3_FLOAT max = in[0]; if (len <= 0) { @@ -50,52 +46,84 @@ LC3_INT searchMaxIndice(LC3_FLOAT* in, LC3_INT len) return max_i; } -void processOlpa_fl(LC3_FLOAT* s_12k8, LC3_FLOAT* mem_s12k8, LC3_FLOAT* mem_s6k4, LC3_INT* mem_old_T0, LC3_INT* T0_out, - LC3_FLOAT* normcorr_out, LC3_INT len, LC3_INT frame_dms) +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] = {0}, filt_out[LEN_12K8 + 3] = {0}, d_wsp[LEN_6K4] = {0}, R0[RANGE_PITCH_6K4] = {0}, R[RANGE_PITCH_6K4] = {0}; /* constant length */ - LC3_INT i = 0, j = 0, len2 = 0, T0 = 0, T02 = 0, min_pitch = 0, max_pitch = 0, L = 0, mem_in_len = 0, acflen = 0; - + 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; - mem_in_len = MAX_PITCH_6K4; 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, filt_out, olpa_down2, 5, len + 3); - for (i = 4, j = 0; i < len + 3; i = i + 2) { - d_wsp[j] = filt_out[i]; - j++; - } + 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, d_wsp, len2); + 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 = 0; - for (j = 0; j < acflen; j++) { - sum += s6k4[j] * s6k4[j - i]; - } + sum = mac_loop(s6k4, &s6k4[-i], acflen); R0[i - MIN_PITCH_6K4] = sum; } /* Weight autocorrelation and find maximum */ - move_float(R, R0, RANGE_PITCH_6K4); + + /* 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]; } @@ -104,22 +132,17 @@ void processOlpa_fl(LC3_FLOAT* s_12k8, LC3_FLOAT* mem_s12k8, LC3_FLOAT* mem_s6k4 /* 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) + LC3_POW(10.0, -5.0); + sum1 = LC3_SQRT(sum1) + 1.00e-05; norm_corr = sum0 / sum1; norm_corr = MAX(0, norm_corr); - /* 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(&R[min_pitch - MIN_PITCH_6K4], max_pitch - min_pitch + 1 ); - T02 = L + min_pitch; - if (T02 != T0) { sum0 = sum1 = sum2 = 0; for (i = 0; i < acflen; i++) { @@ -128,7 +151,7 @@ void processOlpa_fl(LC3_FLOAT* s_12k8, LC3_FLOAT* mem_s12k8, LC3_FLOAT* mem_s6k4 sum2 += s6k4[i] * s6k4[i]; } sum1 = sum1 * sum2; - sum1 = LC3_SQRT(sum1) + LC3_POW(10.0, -5.0); + sum1 = LC3_SQRT(sum1) + 1.00e-05; norm_corr2 = sum0 / sum1; norm_corr2 = MAX(0, norm_corr2); @@ -138,7 +161,41 @@ void processOlpa_fl(LC3_FLOAT* s_12k8, LC3_FLOAT* mem_s12k8, LC3_FLOAT* mem_s6k4 } } +#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/pc_apply.c b/lib_lc3plus/pc_apply.c index 1d1bc4000..89bab44eb 100644 --- a/lib_lc3plus/pc_apply.c +++ b/lib_lc3plus/pc_apply.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -9,6 +9,7 @@ #include "options.h" +#include "wmc_auto.h" #include "functions.h" diff --git a/lib_lc3plus/pc_classify.c b/lib_lc3plus/pc_classify.c index 71196edb8..9ea5e02da 100644 --- a/lib_lc3plus/pc_classify.c +++ b/lib_lc3plus/pc_classify.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -9,6 +9,7 @@ #include "options.h" +#include "wmc_auto.h" #include "functions.h" diff --git a/lib_lc3plus/pc_main.c b/lib_lc3plus/pc_main.c index 268ee94d2..6ee2bc072 100644 --- a/lib_lc3plus/pc_main.c +++ b/lib_lc3plus/pc_main.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -9,6 +9,7 @@ #include "options.h" +#include "wmc_auto.h" #include "functions.h" diff --git a/lib_lc3plus/pc_update.c b/lib_lc3plus/pc_update.c index 57539b507..e57016d40 100644 --- a/lib_lc3plus/pc_update.c +++ b/lib_lc3plus/pc_update.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -9,6 +9,7 @@ #include "options.h" +#include "wmc_auto.h" #include "functions.h" diff --git a/lib_lc3plus/per_band_energy.c b/lib_lc3plus/per_band_energy.c index db1b5b2d0..5785ef82b 100644 --- a/lib_lc3plus/per_band_energy.c +++ b/lib_lc3plus/per_band_energy.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -9,37 +9,43 @@ #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 = 0, j = 0, start = 0, stop = 0, maxBwBin = 0; - LC3_FLOAT sum = 0; + LC3_INT i, j, start, stop, maxBwBin; + LC3_FLOAT sum; -# ifdef ENABLE_HR_MODE_FL +#ifdef ENABLE_HR_MODE_FL if (hrmode) { maxBwBin = MAX_BW_HR; } else -# else +#else UNUSED(hrmode); -# endif +#endif { maxBwBin = MAX_BW; } switch (frame_dms) { -# ifdef ENABLE_2_5MS_MODE +#ifdef ENABLE_2_5MS_MODE case 25: maxBwBin = maxBwBin >> 2; break; -# endif -# ifdef ENABLE_5MS_MODE +#endif +#ifdef ENABLE_5MS_MODE case 50: maxBwBin = maxBwBin >> 1; break; -# endif +#endif +#ifdef CR8_G_ADD_75MS + case 75: + maxBwBin = (maxBwBin >> 2) * 3; + break; +#endif } for (i = 0; i < bands_number; i++) { diff --git a/lib_lc3plus/plc_classify.c b/lib_lc3plus/plc_classify.c index 619a1f741..fe650f44b 100644 --- a/lib_lc3plus/plc_classify.c +++ b/lib_lc3plus/plc_classify.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -9,8 +9,90 @@ #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); @@ -22,21 +104,46 @@ void processPlcClassify_fl(LC3_INT plcMeth, LC3_INT *concealMethod, LC3_INT32 *n ) { 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) { @@ -44,24 +151,53 @@ void processPlcClassify_fl(LC3_INT plcMeth, LC3_INT *concealMethod, LC3_INT32 *n 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; - + 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 } } } diff --git a/lib_lc3plus/plc_compute_stab_fac.c b/lib_lc3plus/plc_compute_stab_fac.c index 4a1111a2c..5c7a736e6 100644 --- a/lib_lc3plus/plc_compute_stab_fac.c +++ b/lib_lc3plus/plc_compute_stab_fac.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -9,6 +9,7 @@ #include "options.h" +#include "wmc_auto.h" #include "functions.h" diff --git a/lib_lc3plus/plc_damping_scrambling.c b/lib_lc3plus/plc_damping_scrambling.c index ecea32be5..fd9efd7c0 100644 --- a/lib_lc3plus/plc_damping_scrambling.c +++ b/lib_lc3plus/plc_damping_scrambling.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -9,6 +9,7 @@ #include "options.h" +#include "wmc_auto.h" #include "functions.h" @@ -17,7 +18,11 @@ void processPlcDampingScramblingMain_fl(LC3_INT32 *ns_seed, 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) + LC3_FLOAT *cum_fflcAtten +#ifdef CR8_A_PLC_FADEOUT_TUNING + , LC3_UINT8 plc_fadeout_type +#endif + ) { LC3_INT32 processDampScramb; @@ -31,15 +36,33 @@ void processPlcDampingScramblingMain_fl(LC3_INT32 *ns_seed, { 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); + 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); + 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); } } @@ -47,13 +70,18 @@ void processPlcDampingScramblingMain_fl(LC3_INT32 *ns_seed, 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) + 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) { @@ -61,6 +89,7 @@ void processPlcDampingScrambling_fl(LC3_FLOAT *spec, LC3_INT32 yLen, LC3_INT32 n *cum_fading_fast = 1; *cum_fflcAtten = 1; } +#endif slow = 0.8 + 0.2 * (*stabFac); fast = 0.3 + 0.2 * (*stabFac); @@ -75,64 +104,104 @@ void processPlcDampingScrambling_fl(LC3_FLOAT *spec, LC3_INT32 yLen, LC3_INT32 n 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 } - *cum_fading_slow = *cum_fading_slow * slow; - *cum_fading_fast = *cum_fading_fast * fast; - - if (processDampScramb == 1) +#ifdef CR8_A_PLC_FADEOUT_TUNING + if (plc_fadeout_type == 0) { - 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; - 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; - } +#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; + } - if (pitch_present == 0) - { - plc_start_inFrames = 1; - } else { - plc_start_inFrames = floor(PLC4_TRANSIT_START_IN_MS / (frame_dms / 10.0)); - } + *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; - plc_end_inFrames = floor(PLC4_TRANSIT_END_IN_MS / (frame_dms / 10.0)); - plc_duration_inFrames = plc_end_inFrames - plc_start_inFrames; + 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; + } + } - 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; + + *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++) { @@ -146,37 +215,52 @@ void processPlcDampingScrambling_fl(LC3_FLOAT *spec, LC3_INT32 yLen, LC3_INT32 n 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]; } } } - 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) +#ifdef CR8_A_PLC_FADEOUT_TUNING + if (plc_fadeout_type == 0) { - for (i = spec_inv_idx; i < yLen; i++) +#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 { - frame_energy = frame_energy + (spec[i] * spec[i]); + mean_energy = 0; } - mean_energy = frame_energy * 1 / (yLen - spec_inv_idx); + energThreshold = LC3_SQRT(ad_threshFac * mean_energy); + fac = (cum_fading_slow_local - cum_fading_fast_local) * energThreshold; +#ifdef CR8_A_PLC_FADEOUT_TUNING } - else - { - mean_energy = 0; - } - - energThreshold = LC3_SQRT(ad_threshFac * mean_energy); - fac = (cum_fading_slow_local - cum_fading_fast_local) * energThreshold; +#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; diff --git a/lib_lc3plus/plc_main.c b/lib_lc3plus/plc_main.c index df3fd184d..ca4a6bbcb 100644 --- a/lib_lc3plus/plc_main.c +++ b/lib_lc3plus/plc_main.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -9,6 +9,7 @@ #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, @@ -24,6 +25,16 @@ void processPlcMain_fl(LC3_FLOAT *q_d_fl_c, LC3_FLOAT *syntM_fl_c, LC3PLUS_Dec* 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) @@ -53,14 +64,114 @@ void processPlcMain_fl(LC3_FLOAT *q_d_fl_c, LC3_FLOAT *syntM_fl_c, LC3PLUS_Dec* 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 + /* phaseECU supports only 10ms framing*/ assert(PlcSetup->nbLostCmpt != 0 || decoder->frame_dms == 100); if (decoder->frame_dms != 100) @@ -155,6 +266,10 @@ void processPlcMain_fl(LC3_FLOAT *q_d_fl_c, LC3_FLOAT *syntM_fl_c, LC3PLUS_Dec* , &(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 ); @@ -162,8 +277,7 @@ void processPlcMain_fl(LC3_FLOAT *q_d_fl_c, LC3_FLOAT *syntM_fl_c, LC3PLUS_Dec* h_DecSetup->imdct_mem, synth); move_float(syntM_fl_c, synth, decoder->frame_length); - - + } } break; @@ -180,7 +294,11 @@ void processPlcMain_fl(LC3_FLOAT *q_d_fl_c, LC3_FLOAT *syntM_fl_c, LC3PLUS_Dec* 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); + &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); diff --git a/lib_lc3plus/plc_noise_substitution.c b/lib_lc3plus/plc_noise_substitution.c index 4913ee53e..c366015fc 100644 --- a/lib_lc3plus/plc_noise_substitution.c +++ b/lib_lc3plus/plc_noise_substitution.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -9,6 +9,7 @@ #include "options.h" +#include "wmc_auto.h" #include "functions.h" diff --git a/lib_lc3plus/plc_phecu_f0_refine_first.c b/lib_lc3plus/plc_phecu_f0_refine_first.c index 11ebf276b..c3f8edfab 100644 --- a/lib_lc3plus/plc_phecu_f0_refine_first.c +++ b/lib_lc3plus/plc_phecu_f0_refine_first.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -9,6 +9,7 @@ #include "options.h" +#include "wmc_auto.h" #include "defines.h" #include "functions.h" diff --git a/lib_lc3plus/plc_phecu_fec_hq.c b/lib_lc3plus/plc_phecu_fec_hq.c index c25466c3e..9213b9ea5 100644 --- a/lib_lc3plus/plc_phecu_fec_hq.c +++ b/lib_lc3plus/plc_phecu_fec_hq.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -9,6 +9,7 @@ #include "options.h" +#include "wmc_auto.h" #include "defines.h" #include "functions.h" diff --git a/lib_lc3plus/plc_phecu_hq_ecu.c b/lib_lc3plus/plc_phecu_hq_ecu.c index 5b1978bca..577a56e83 100644 --- a/lib_lc3plus/plc_phecu_hq_ecu.c +++ b/lib_lc3plus/plc_phecu_hq_ecu.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -9,10 +9,12 @@ #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, @@ -24,7 +26,12 @@ void plc_phEcu_hq_ecu( 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) + 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; @@ -48,6 +55,8 @@ void plc_phEcu_hq_ecu( Lxfp_inuse = (LC3_INT32)(L*(3.75/10.0)); } + + UNUSED(env_stabPtr); UNUSED(xsubst_dbg); UNUSED(X_out_m_dbg); @@ -69,12 +78,20 @@ void plc_phEcu_hq_ecu( 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); + 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); } @@ -85,7 +102,11 @@ void plc_phEcu_hq_ecu( 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); + st_mag_chg_1st, st_Xavg, alpha, beta, mag_chg, NULL, NULL +#ifdef CR8_A_PLC_FADEOUT_TUNING + ,plc_fadeout_type +#endif + ); } @@ -100,6 +121,12 @@ void plc_phEcu_hq_ecu( /* 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); diff --git a/lib_lc3plus/plc_phecu_lf_peak_analysis.c b/lib_lc3plus/plc_phecu_lf_peak_analysis.c index 0bcc98d7a..53c10410c 100644 --- a/lib_lc3plus/plc_phecu_lf_peak_analysis.c +++ b/lib_lc3plus/plc_phecu_lf_peak_analysis.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -9,6 +9,7 @@ #include "options.h" +#include "wmc_auto.h" #include "defines.h" #include "functions.h" diff --git a/lib_lc3plus/plc_phecu_rec_frame.c b/lib_lc3plus/plc_phecu_rec_frame.c index 0e6570743..4586e1d62 100644 --- a/lib_lc3plus/plc_phecu_rec_frame.c +++ b/lib_lc3plus/plc_phecu_rec_frame.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -9,6 +9,7 @@ #include "options.h" +#include "wmc_auto.h" #include "defines.h" #include "functions.h" @@ -51,7 +52,12 @@ void plc_phEcu_rec_frame(Complex *X_in, UNUSED(ifft_out_dbg); UNUSED(xsubst_dbg); UNUSED(xsubst_LL); - fs_idx = FRAME2FS_IDX(L); + +#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]*/ diff --git a/lib_lc3plus/plc_phecu_setf0hz.c b/lib_lc3plus/plc_phecu_setf0hz.c index b14327e2b..79a82d092 100644 --- a/lib_lc3plus/plc_phecu_setf0hz.c +++ b/lib_lc3plus/plc_phecu_setf0hz.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -9,6 +9,7 @@ #include "options.h" +#include "wmc_auto.h" #include "defines.h" #include "functions.h" diff --git a/lib_lc3plus/plc_phecu_spec_ana.c b/lib_lc3plus/plc_phecu_spec_ana.c index b49690030..463d3d1ae 100644 --- a/lib_lc3plus/plc_phecu_spec_ana.c +++ b/lib_lc3plus/plc_phecu_spec_ana.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -9,6 +9,7 @@ #include "options.h" +#include "wmc_auto.h" #include "defines.h" #include "functions.h" diff --git a/lib_lc3plus/plc_phecu_subst_spec.c b/lib_lc3plus/plc_phecu_subst_spec.c index 43f806339..388ae3cb8 100644 --- a/lib_lc3plus/plc_phecu_subst_spec.c +++ b/lib_lc3plus/plc_phecu_subst_spec.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -9,39 +9,52 @@ #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, LC3_FLOAT *corr_phase_dbg, + 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; + 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, subInd; - + 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 */ - + lprotBy2Minus1 = imin(320, Lprot/2 - 1); /* limit to 20 KHz */ t_adv = t_adv_in + time_offs; @@ -49,15 +62,33 @@ void plc_phEcu_subst_spec(LC3_INT32* plocs, LC3_INT32 n_plocs, LC3_FLOAT* f0est, corr_phase[i] = (LC3_FLOAT)2.0 * (LC3_FLOAT)M_PI * (f0est[i]/Lprot)*(LC3_FLOAT)t_adv; } - // EVOLVE PHASE ----------------- - binCounter = 1; - subInd = 0; 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) { @@ -69,6 +100,29 @@ void plc_phEcu_subst_spec(LC3_INT32* plocs, LC3_INT32 n_plocs, LC3_FLOAT* f0est, 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++) { @@ -221,11 +275,11 @@ void plc_phEcu_subst_spec(LC3_INT32* plocs, LC3_INT32 n_plocs, LC3_FLOAT* f0est, } 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); + LC3_INT32 retSeed; + assert(seed <= 32767 && seed >= -32768); + retSeed = (13849 + (seed + 32768) * 31821) & 65535; + retSeed -= 32768; + assert(retSeed <= 32767 && retSeed >= -32768); return retSeed; } @@ -245,3 +299,158 @@ static LC3_INT32 rand_phase(LC3_INT32 seed_in, LC3_FLOAT* cos_F) { 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 index 9f585f28d..10aef9234 100644 --- a/lib_lc3plus/plc_phecu_tba_per_band_gain.c +++ b/lib_lc3plus/plc_phecu_tba_per_band_gain.c @@ -1,19 +1,20 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* 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) +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; @@ -39,6 +40,5 @@ void plc_phEcu_tba_per_band_gain(LC3_INT32 n_grp, LC3_FLOAT *gr_pow_left, LC3_FL } - return; + return; } - diff --git a/lib_lc3plus/plc_phecu_tba_spect_Xavg.c b/lib_lc3plus/plc_phecu_tba_spect_Xavg.c index 600b9714e..20baf4e79 100644 --- a/lib_lc3plus/plc_phecu_tba_spect_Xavg.c +++ b/lib_lc3plus/plc_phecu_tba_spect_Xavg.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -9,6 +9,7 @@ #include "options.h" +#include "wmc_auto.h" #include "defines.h" #include "functions.h" diff --git a/lib_lc3plus/plc_phecu_tba_trans_dect_gains.c b/lib_lc3plus/plc_phecu_tba_trans_dect_gains.c index e5f0d3caa..69d6bf396 100644 --- a/lib_lc3plus/plc_phecu_tba_trans_dect_gains.c +++ b/lib_lc3plus/plc_phecu_tba_trans_dect_gains.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -9,6 +9,7 @@ #include "options.h" +#include "wmc_auto.h" #include "defines.h" #include "functions.h" @@ -40,11 +41,29 @@ const LC3_INT32 POW_ATT_TABLE0[OFF_FRAMES_LIMIT + 1] = { 32767, 31293, 29885, 28 #ifdef PLC2_FADEOUT_IN_MS #if PLC2_FADEOUT_IN_MS == 0 -/* default setting only requieres two tables */ +#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, @@ -81,6 +100,19 @@ const LC3_INT32 POW_ATT_TABLE_p4x1_6[OFF_FRAMES_LIMIT + 1] = { 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, @@ -90,13 +122,18 @@ const LC3_INT32* const POW_ATT_TABLES[1 + 10] = 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) + 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; @@ -108,14 +145,19 @@ void plc_phEcu_tba_trans_dect_gains(LC3_INT32 burst_len, LC3_INT32 n_grp, LC3_FL 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 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 */ @@ -123,32 +165,31 @@ void plc_phEcu_tba_trans_dect_gains(LC3_INT32 burst_len, LC3_INT32 n_grp, LC3_FL XavgFadeinFactor = -1.0; - if (PLC2_FADEOUT_IN_MS != 0) +#ifndef CR8_A_PLC_FADEOUT_TUNING + if (PLC2_FADEOUT_IN_MS < 0) { - if (PLC2_FADEOUT_IN_MS < 0) - { - FADEOUT_IN_MS = PLC_FADEOUT_IN_MS; /* % use TDC - SETTING as input */ - } - else - { - FADEOUT_IN_MS = PLC2_FADEOUT_IN_MS; /* % use a PLC2 individual settinsg */ - } - - PLC_P800_SPEECH_FADEOUT_IN_FRAMES = (LC3_INT32) LC3_FLOOR((LC3_FLOAT)FADEOUT_IN_MS / (LC3_FLOAT)10.0); /* % nominal svaleu for speech */ + 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 - 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 */ +#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 */ - 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 fot assumed music */ + 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 */ - 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 */ - } + 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 */ +/* 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 */ @@ -158,10 +199,26 @@ void plc_phEcu_tba_trans_dect_gains(LC3_INT32 burst_len, LC3_INT32 n_grp, LC3_FL 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) @@ -203,7 +260,6 @@ void plc_phEcu_tba_trans_dect_gains(LC3_INT32 burst_len, LC3_INT32 n_grp, LC3_FL /* transient processing */ /* transients may be both rise and decay transients !! */ - if(LC3_FABS(grp_pow_change[i]) >= thresh_tr_dB) { @@ -233,13 +289,20 @@ void plc_phEcu_tba_trans_dect_gains(LC3_INT32 burst_len, LC3_INT32 n_grp, LC3_FL 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 { @@ -252,7 +315,7 @@ void plc_phEcu_tba_trans_dect_gains(LC3_INT32 burst_len, LC3_INT32 n_grp, LC3_FL 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) ) { @@ -270,8 +333,12 @@ void plc_phEcu_tba_trans_dect_gains(LC3_INT32 burst_len, LC3_INT32 n_grp, LC3_FL } - +#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; } diff --git a/lib_lc3plus/plc_phecu_trans_burst_ana_sub.c b/lib_lc3plus/plc_phecu_trans_burst_ana_sub.c index c860cd6ce..a25947a18 100644 --- a/lib_lc3plus/plc_phecu_trans_burst_ana_sub.c +++ b/lib_lc3plus/plc_phecu_trans_burst_ana_sub.c @@ -1,22 +1,29 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* 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, + + +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) + 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]; @@ -28,7 +35,7 @@ void plc_phEcu_trans_burst_ana_sub(LC3_INT32 fs_idx, LC3_INT32 burst_len, LC3_IN LC3_INT32 attDegreeFrames; LC3_FLOAT thresh_dbg; - + UNUSED(tr_dec_dbg); UNUSED(gpc_dbg); @@ -40,8 +47,13 @@ void plc_phEcu_trans_burst_ana_sub(LC3_INT32 fs_idx, LC3_INT32 burst_len, LC3_IN } + 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 + ); + - 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); return; } diff --git a/lib_lc3plus/plc_tdc.c b/lib_lc3plus/plc_tdc.c index 1a1a408f4..25c4aa064 100644 --- a/lib_lc3plus/plc_tdc.c +++ b/lib_lc3plus/plc_tdc.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -8,11 +8,12 @@ ******************************************************************************/ -#include "options.h" /***************************************************************************\ * contents/description: Main function for Time domain concealment \***************************************************************************/ +#include "options.h" +#include "wmc_auto.h" #include #include "functions.h" @@ -61,6 +62,9 @@ void processTdcApply_fl(const LC3_INT32 pitch_int, 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; @@ -77,6 +81,9 @@ void processTdcApply_fl(const LC3_INT32 pitch_int, 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)); @@ -91,7 +98,20 @@ void processTdcApply_fl(const LC3_INT32 pitch_int, 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; @@ -198,7 +218,14 @@ void processTdcApply_fl(const LC3_INT32 pitch_int, { 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) @@ -231,7 +258,14 @@ void processTdcApply_fl(const LC3_INT32 pitch_int, 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; } } @@ -240,7 +274,9 @@ void processTdcApply_fl(const LC3_INT32 pitch_int, { 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. * @@ -377,7 +413,11 @@ void processTdcApply_fl(const LC3_INT32 pitch_int, *----------------------------------------------------------*/ 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; diff --git a/lib_lc3plus/plc_tdc_tdac.c b/lib_lc3plus/plc_tdc_tdac.c index 329361b14..596c23db0 100644 --- a/lib_lc3plus/plc_tdc_tdac.c +++ b/lib_lc3plus/plc_tdc_tdac.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -9,6 +9,7 @@ #include "options.h" +#include "wmc_auto.h" #include "functions.h" diff --git a/lib_lc3plus/plc_update.c b/lib_lc3plus/plc_update.c index a151420eb..40520fb25 100644 --- a/lib_lc3plus/plc_update.c +++ b/lib_lc3plus/plc_update.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -7,8 +7,9 @@ * estoppel or otherwise. * ******************************************************************************/ -#include "functions.h" #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, diff --git a/lib_lc3plus/quantize_spec.c b/lib_lc3plus/quantize_spec.c index 7886b4586..fdaee2890 100644 --- a/lib_lc3plus/quantize_spec.c +++ b/lib_lc3plus/quantize_spec.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -9,60 +9,121 @@ #include "options.h" +#include "wmc_auto.h" #include "functions.h" -static LC3_INT sign(LC3_FLOAT x); - -LC3_INT sign(LC3_FLOAT x) +LC3_INT32 find_last_nz_pair(LC3_INT32 x[], LC3_INT32 length); +LC3_INT32 find_last_nz_pair(LC3_INT32 x[], LC3_INT32 length) { - if (x > 0) - return 1; + 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)); + - if (x < 0) - return -1; + 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 0; + 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 = 0, i = 0, lastnz2 = 0, m = 0, maxlev = 0, k = 0; - LC3_INT nbits_lsb = 0; - LC3_INT c = 0; - LC3_INT a = 0, b = 0, lev1 = 0, sym = 0, t = 0, pki = 0; - LC3_INT a1_msb = 0, b1_msb = 0; - LC3_INT lastnz = 1; + 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++) { - xq[i] = trunc(x[i] / gain + offset * sign(x[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 < 48000 && totalBits > 320 + (fs / 8000 - 2) * 160) || (fs == 48000 && totalBits > 800)) { + if (fs != 96000 && (totalBits > (160 + FS2FS_IDX(fs) * 160))) + { rateFlag = 512; } /* Init */ - if (mode == 0 && ((fs < 48000 && totalBits >= 640 + (fs / 8000 - 2) * 160) || (fs == 48000 && totalBits >= 1120))) { + 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; @@ -70,21 +131,24 @@ void processQuantizeSpec_fl(LC3_FLOAT x[], LC3_FLOAT gain, LC3_INT xq[], LC3_INT } } - - if (mode < 0) { + if (mode < 0) + { lastnz2 = lastnz + 1; - } else { + } + else + { lastnz2 = 2; } - *nbits = 0; - *nbits2 = 0; + bits = bits2 = 0; /* Calculate number of estimated bits */ - for (k = 0; k < lastnz; k = k + 2) { + for (k = 0; k < lastnz; k = k + 2) + { t = c + rateFlag; - if (k > nt / 2) { + if (k > nt_half) + { t += 256; } @@ -94,29 +158,36 @@ void processQuantizeSpec_fl(LC3_FLOAT x[], LC3_FLOAT gain, LC3_INT xq[], LC3_INT b = abs(xq[k + 1]); m = MAX(a, b); - if (m == 0) { + if (m == 0) + { maxlev = -1; - } else { + } + else + { maxlev = 29 - (clz_func(MAX(m, 3)) - 1); } codingdata[1] = maxlev; if (mode <= 0) { - *nbits = *nbits + MIN(a, 1) * 2048; - *nbits = *nbits + MIN(b, 1) * 2048; + 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]; - *nbits = *nbits + ari_spec_bits_fl[pki][16]; + 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) { + if (lev1 == 0 && mode > 0) + { nbits_lsb += 2; - } else { - *nbits = *nbits + 2 * 2048; + } + else + { + bits = bits + 2 * 2048; } a = a >> 1; @@ -127,68 +198,84 @@ void processQuantizeSpec_fl(LC3_FLOAT x[], LC3_FLOAT gain, LC3_INT xq[], LC3_INT pki = ari_spec_lookup_fl[t + lev1 * 1024]; sym = a + 4 * b; codingdata[2] = sym; - codingdata += 3; - *nbits = *nbits + ari_spec_bits_fl[pki][sym]; + codingdata += 3; + bits = bits + ari_spec_bits_fl[pki][sym]; - if (mode > 0) { + if (mode > 0) + { a1_msb = abs(xq[k]); b1_msb = abs(xq[k + 1]); - if (lev1 > 0) { + if (lev1 > 0) + { a1_msb = a1_msb >> 1; b1_msb = b1_msb >> 1; - if (a1_msb == 0 && xq[k] != 0) { + if (a1_msb == 0 && xq[k] != 0) + { nbits_lsb++; } - if (b1_msb == 0 && xq[k + 1] != 0) { + if (b1_msb == 0 && xq[k + 1] != 0) + { nbits_lsb++; } } - *nbits = *nbits + MIN(a1_msb, 1) * 2048; - *nbits = *nbits + MIN(b1_msb, 1) * 2048; + 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) && *nbits <= target * 2048) { + if (mode >= 0 && (abs(xq[k]) != 0 || abs(xq[k + 1]) != 0) && bits <= target * 2048) + { lastnz2 = k + 2; - *nbits2 = *nbits; + bits2 = bits; } lev1 = lev1 - 1; - if (lev1 <= 0) { + + if (lev1 <= 0) + { t = 1 + (a + b) * (lev1 + 2); - } else { + } + else + { t = 13 + lev1; } c = (c & 15) * 16 + t; } - /* Number of bits */ - *nbits = ceil((LC3_FLOAT)*nbits / 2048.0); + *nbits = (bits + 2047) >> 11; // Exactly same as ceil((LC3_FLOAT)*nbits / 2048.0); - if (mode >= 0) { - *nbits2 = ceil((LC3_FLOAT)*nbits2 / 2048.0); - } else { + if (mode >= 0) + { + *nbits2 = (bits2 + 2047) >> 11; //ceil((LC3_FLOAT)*nbits2 / 2048.0); + } + else + { *nbits2 = *nbits; } - if (mode > 0) { - *nbits += nbits_lsb; + if (mode > 0) + { + *nbits += nbits_lsb; *nbits2 += nbits_lsb; } /* Truncation of high-frequency coefficients */ - for (i = lastnz2; i <= lastnz; i++) { + for (i = lastnz2; i <= lastnz; i++) + { xq[i] = 0; } /* Truncation of LSBs */ - if (mode > 0 && *nbits > target) { + if (mode > 0 && *nbits > target) + { *lsbMode = 1; - } else { + } + else + { *lsbMode = 0; } diff --git a/lib_lc3plus/reorder_bitstream.c b/lib_lc3plus/reorder_bitstream.c index 77b50d7a1..118a05b6e 100644 --- a/lib_lc3plus/reorder_bitstream.c +++ b/lib_lc3plus/reorder_bitstream.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -9,6 +9,7 @@ #include "options.h" +#include "wmc_auto.h" #include "functions.h" diff --git a/lib_lc3plus/resamp12k8.c b/lib_lc3plus/resamp12k8.c index 0cab5daae..295b6e7f2 100644 --- a/lib_lc3plus/resamp12k8.c +++ b/lib_lc3plus/resamp12k8.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -9,6 +9,7 @@ #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[], @@ -16,15 +17,13 @@ void process_resamp12k8_fl(LC3_FLOAT x[], LC3_INT x_len, LC3_FLOAT mem_in[], LC3 { - LC3_INT len_12k8 = 0, N12k8 = 0, i = 0, k = 0; - LC3_FLOAT mac = 0, buf_out[120 + MAX_LEN] = {0}, bufdown[128] = {0}, buf[120 + MAX_LEN] = {0}; + 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: @@ -33,6 +32,11 @@ void process_resamp12k8_fl(LC3_FLOAT x[], LC3_INT x_len, LC3_FLOAT mem_in[], LC3 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; @@ -46,8 +50,6 @@ void process_resamp12k8_fl(LC3_FLOAT x[], LC3_INT x_len, LC3_FLOAT mem_in[], LC3 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 */ @@ -97,11 +99,11 @@ void process_resamp12k8_fl(LC3_FLOAT x[], LC3_INT x_len, LC3_FLOAT mem_in[], LC3 mem_50[1] = (LC3_FLOAT)u_21; /* Output Buffer */ - memmove(buf_out, mem_out, mem_out_len * sizeof(LC3_FLOAT)); + memmove(buf, mem_out, mem_out_len * sizeof(LC3_FLOAT)); - memmove(&buf_out[mem_out_len], bufdown, len_12k8 * sizeof(LC3_FLOAT)); + memmove(&buf[mem_out_len], bufdown, len_12k8 * sizeof(LC3_FLOAT)); - memmove(y, buf_out, (*y_len + 1) * sizeof(LC3_FLOAT)); + memmove(y, buf, (*y_len + 1) * sizeof(LC3_FLOAT)); - memmove(mem_out, &buf_out[N12k8], mem_out_len * sizeof(LC3_FLOAT)); + memmove(mem_out, &buf[N12k8], mem_out_len * sizeof(LC3_FLOAT)); } diff --git a/lib_lc3plus/residual_coding.c b/lib_lc3plus/residual_coding.c index 42094d275..777b97d73 100644 --- a/lib_lc3plus/residual_coding.c +++ b/lib_lc3plus/residual_coding.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -9,6 +9,7 @@ #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 @@ -19,7 +20,7 @@ void processResidualCoding_fl(LC3_FLOAT x[], LC3_INT xq[], LC3_FLOAT gain, LC3_I LC3_INT iter=0; LC3_FLOAT offset; LC3_INT iter_max = 1; - LC3_INT nz_idx[MAX_LEN] = {0}; + LC3_INT nz_idx[MAX_LEN]; LC3_INT N_nz = 0, idx = 0; diff --git a/lib_lc3plus/residual_decoding.c b/lib_lc3plus/residual_decoding.c index 97fd94afc..90084c981 100644 --- a/lib_lc3plus/residual_decoding.c +++ b/lib_lc3plus/residual_decoding.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -9,6 +9,7 @@ #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 @@ -18,7 +19,7 @@ void processResidualDecoding_fl(LC3_INT* bitsRead, LC3_FLOAT x[], LC3_INT L_spec LC3_INT k = 0, n = 0; LC3_FLOAT offset1 = 0, offset2 = 0; LC3_FLOAT offset = 0; - LC3_INT nz_idx[MAX_LEN] = {0}; + LC3_INT nz_idx[MAX_LEN]; LC3_INT N_nz = 0, idx = 0; LC3_INT iter = 0, iter_max = 1; @@ -65,7 +66,7 @@ void processResidualDecoding_fl(LC3_INT* bitsRead, LC3_FLOAT x[], LC3_INT L_spec break; } } - offset /= 2; + offset *= 0.5; iter ++; } } diff --git a/lib_lc3plus/setup_com_lc3.c b/lib_lc3plus/setup_com_lc3.c index 17054d1ff..33574f577 100644 --- a/lib_lc3plus/setup_com_lc3.c +++ b/lib_lc3plus/setup_com_lc3.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -7,8 +7,9 @@ * estoppel or otherwise. * ******************************************************************************/ -#include "functions.h" #include "options.h" +#include "wmc_auto.h" +#include "functions.h" LC3_FLOAT array_max_abs(LC3_FLOAT *in, LC3_INT32 len) { diff --git a/lib_lc3plus/setup_dec_lc3.c b/lib_lc3plus/setup_dec_lc3.c index c14309720..1a6e4e7cc 100644 --- a/lib_lc3plus/setup_dec_lc3.c +++ b/lib_lc3plus/setup_dec_lc3.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -9,6 +9,7 @@ #include "options.h" +#include "wmc_auto.h" #include "setup_dec_lc3.h" #include "functions.h" #include @@ -19,8 +20,8 @@ int alloc_decoder(LC3PLUS_Dec* decoder, int samplerate, int channels) { - int ch = 0; - size_t size = sizeof(LC3PLUS_Dec); + int ch = 0; + size_t size = sizeof(LC3PLUS_Dec); size_t frame_len = DYN_MAX_LEN_EXT(samplerate); void *PlcAdvSetup = NULL; @@ -34,6 +35,11 @@ int alloc_decoder(LC3PLUS_Dec* decoder, int samplerate, int channels) HANDLE_IIS_FFT handle_fft_phaseecu; HANDLE_IIS_FFT handle_ifft_phaseecu; LC3_FLOAT *q_old_res; + +#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; +#endif for (ch = 0; ch < channels; ch++) { DecSetup* setup = balloc(decoder, &size, sizeof(DecSetup)); @@ -57,6 +63,15 @@ int alloc_decoder(LC3PLUS_Dec* decoder, int samplerate, int channels) 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)); + +#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]; + + + 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); +#endif q_old_res = balloc(decoder, &size, sizeof(LC3_FLOAT) * frame_len); @@ -80,6 +95,14 @@ int alloc_decoder(LC3PLUS_Dec* decoder, int samplerate, int channels) setup->PlcAdvSetup->PlcPhEcuSetup.handle_fft_phaseecu->sine_table = sine_table1_phecu; setup->PlcAdvSetup->PlcPhEcuSetup.handle_ifft_phaseecu->sine_table = sine_table2_phecu; + +#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->PlcAdvSetup->plc_longterm_advc_tdc = plc_longterm_advc_tdc; + setup->PlcAdvSetup->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)); @@ -104,10 +127,12 @@ LC3PLUS_Error FillDecSetup(LC3PLUS_Dec* decoder, int samplerate, int channels, L 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; @@ -175,6 +200,21 @@ void set_dec_frame_params(LC3PLUS_Dec* decoder) 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) { @@ -221,6 +261,20 @@ void set_dec_frame_params(LC3PLUS_Dec* decoder) } decoder->cutoffBins = BW_cutoff_bin_all_5ms; } +#ifdef CR8_G_ADD_75MS + else if (decoder->frame_ms == 7.5) + { + if (decoder->hrmode) + { + decoder->bands_offset = ACC_COEFF_PER_BAND_7_5ms_HR[decoder->fs_idx]; + } + 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); @@ -246,6 +300,23 @@ void set_dec_frame_params(LC3PLUS_Dec* decoder) 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) { @@ -263,6 +334,13 @@ void set_dec_frame_params(LC3PLUS_Dec* decoder) 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; @@ -307,6 +385,11 @@ void set_dec_frame_params(LC3PLUS_Dec* decoder) setup->PlcAdvSetup->cum_fading_fast = 1; setup->PlcAdvSetup->cum_fading_slow = 1; setup->PlcAdvSetup->cum_fflcAtten = 1; + +#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) { @@ -340,6 +423,9 @@ void set_dec_frame_params(LC3PLUS_Dec* decoder) } 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 } } } @@ -362,6 +448,12 @@ LC3PLUS_Error update_dec_bitrate(LC3PLUS_Dec* decoder, int ch, int nBytes) maxBytes = 375; minBytes = MIN_NBYTES; break; +#ifdef CR8_G_ADD_75MS + case 75: + maxBytes = 625; + minBytes = MIN_NBYTES; + break; +#endif case 100: maxBytes = 625; minBytes = MIN_NBYTES; @@ -406,6 +498,12 @@ LC3PLUS_Error update_dec_bitrate(LC3PLUS_Dec* decoder, int ch, int nBytes) setup->enable_lpc_weighting = (setup->total_bits < 240); totalBits = setup->total_bits * 2 - 160; } +#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); diff --git a/lib_lc3plus/setup_dec_lc3.h b/lib_lc3plus/setup_dec_lc3.h index 6ed0f438e..17201a4a9 100644 --- a/lib_lc3plus/setup_dec_lc3.h +++ b/lib_lc3plus/setup_dec_lc3.h @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -11,6 +11,8 @@ #ifndef SETUP_DEC_LC3_FL_H #define SETUP_DEC_LC3_FL_H +#include "options.h" +#include "wmc_auto.h" #include "constants.h" /* Channel state and bitrate-derived values go in this struct */ @@ -49,6 +51,9 @@ typedef struct { LC3_FLOAT x_fl[MAX_LEN]; LC3_FLOAT imdct_mem[MAX_LEN]; LC3_FLOAT alpha; +#ifdef CR9_N_SHORT_FADE_FOR_UNSTABLE_PITCH + LC3_FLOAT rel_pitch_change; +#endif Dct4 dct4structImdct; diff --git a/lib_lc3plus/setup_enc_lc3.c b/lib_lc3plus/setup_enc_lc3.c index 986b43d60..e991c50f4 100644 --- a/lib_lc3plus/setup_enc_lc3.c +++ b/lib_lc3plus/setup_enc_lc3.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -9,6 +9,7 @@ #include "options.h" +#include "wmc_auto.h" #include "setup_enc_lc3.h" #include "functions.h" #include @@ -42,9 +43,12 @@ LC3PLUS_Error FillEncSetup(LC3PLUS_Enc* encoder, int samplerate, int channels 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; } +#endif encoder->hrmode = hrmode != 0; @@ -103,6 +107,7 @@ void set_enc_frame_params(LC3PLUS_Enc* encoder) encoder->yLen = MIN(MAX_BW, encoder->frame_length); encoder->sns_damping = 0.85; } + encoder->stEnc_mdct_mem_len = encoder->frame_length - encoder->la_zeroes; encoder->bands_number = 64; encoder->nSubdivisions = 3; @@ -140,19 +145,46 @@ void set_enc_frame_params(LC3PLUS_Enc* encoder) encoder->attdec_damping = 0.5; encoder->attdec_hangover_thresh = 2; } - else if (encoder->frame_ms == 2.5) { - encoder->la_zeroes = MDCT_la_zeroes_2_5ms[encoder->fs_idx]; +#ifdef CR8_G_ADD_75MS + else if (encoder->frame_ms == 7.5) { if (encoder->hrmode) { - encoder->bands_offset = ACC_COEFF_PER_BAND_2_5ms_HR[encoder->fs_idx]; + encoder->bands_offset = ACC_COEFF_PER_BAND_7_5ms_HR[encoder->fs_idx]; } else { - encoder->bands_offset = ACC_COEFF_PER_BAND_2_5ms[encoder->fs_idx]; + encoder->bands_offset = ACC_COEFF_PER_BAND_7_5ms[encoder->fs_idx]; } - encoder->cutoffBins = BW_cutoff_bin_all_2_5ms; + 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->stEnc_mdct_mem_len = encoder->frame_length - encoder->la_zeroes; + if (encoder->hrmode) + { + encoder->bands_number = bands_number_7_5ms_HR[encoder->fs_idx]; + } + else + { + encoder->bands_number = bands_number_7_5ms[encoder->fs_idx]; + } + 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) { @@ -164,8 +196,17 @@ void set_enc_frame_params(LC3PLUS_Enc* encoder) } encoder->cutoffBins = BW_cutoff_bin_all_5ms; } - - if (encoder->frame_ms == 2.5) { + 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; @@ -182,22 +223,14 @@ void set_enc_frame_params(LC3PLUS_Enc* encoder) encoder->near_nyquist_index = encoder->bands_number - 2; encoder->ltpf_mem_in_len = LTPF_MEMIN_LEN + (LEN_12K8 >> 2); } - - - 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; - } 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); @@ -219,9 +252,9 @@ 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; +#ifdef ENABLE_HR_MODE_FL if (encoder->hrmode) { -#ifdef ENABLE_HR_MODE_FL switch (encoder->frame_dms) { case 25: @@ -236,6 +269,14 @@ LC3PLUS_Error update_enc_bitrate(LC3PLUS_Enc* encoder, int bitrate) else if (encoder->fs == 96000) {minBR = MIN_BR_50MS_96KHZ_HR;} else { return LC3PLUS_HRMODE_ERROR;} break; +#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 case 100: maxBR = 500000; if (encoder->fs == 48000) {minBR = MIN_BR_100MS_48KHZ_HR;} @@ -245,9 +286,9 @@ LC3PLUS_Error update_enc_bitrate(LC3PLUS_Enc* encoder, int bitrate) default: return LC3PLUS_HRMODE_ERROR; } -#endif } else +#endif /* ENABLE_HR_MODE_FL */ { minBR = (MIN_NBYTES << 3); maxBR = MAX_BR; @@ -268,6 +309,20 @@ LC3PLUS_Error update_enc_bitrate(LC3PLUS_Enc* encoder, int bitrate) default: break; } break; +#ifdef CR8_G_ADD_75MS + case 75: + minBR = MIN_BR_075DMS; + maxBR = MAX_BR_075DMS; + /* have additional limitations for 7.5ms */ + 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; + } + break; +#endif case 100: /* have additional limitations for 10ms */ minBR = MIN_BR_100DMS; @@ -388,6 +443,11 @@ LC3PLUS_Error update_enc_bitrate(LC3PLUS_Enc* encoder, int bitrate) setup->targetBitsAri = setup->total_bits; setup->enable_lpc_weighting = setup->total_bits < 480; +#ifdef CR8_G_ADD_75MS + if (encoder->frame_ms == 7.5) { + setup->enable_lpc_weighting = setup->total_bits < 360; + } +#endif if (encoder->frame_ms == 5) { setup->enable_lpc_weighting = setup->total_bits < 240; } @@ -433,6 +493,11 @@ LC3PLUS_Error update_enc_bitrate(LC3PLUS_Enc* encoder, int bitrate) 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; @@ -461,6 +526,14 @@ LC3PLUS_Error update_enc_bitrate(LC3PLUS_Enc* encoder, int bitrate) encoder->sns_damping = 6881.0/32768.0; } } +#ifdef CR8_G_ADD_75MS + if (encoder->frame_ms == 7.5) + { + if (setup->total_bits > 3*4400/4) { + encoder->sns_damping = 5898.0/32768.0; + } + } +#endif if (encoder->frame_ms == 5) { if (setup->total_bits > 4600/2) { @@ -487,6 +560,12 @@ LC3PLUS_Error update_enc_bitrate(LC3PLUS_Enc* encoder, int bitrate) { setup->regBits +=2; } +#ifdef CR8_G_ADD_75MS + if (encoder->frame_ms == 7.5) + { + setup->regBits +=1; + } +#endif if (encoder->frame_ms == 2.5) { setup->regBits -= 6; @@ -502,6 +581,12 @@ LC3PLUS_Error update_enc_bitrate(LC3PLUS_Enc* encoder, int bitrate) { setup->regBits += 0; } +#ifdef CR8_G_ADD_75MS + if (encoder->frame_ms == 7.5) + { + setup->regBits +=2; + } +#endif if (encoder->frame_ms == 10) { setup->regBits += 5; @@ -538,9 +623,11 @@ void update_enc_bandwidth(LC3PLUS_Enc* encoder, int bandwidth) { 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 31f0cbeb5..e3f62ba55 100644 --- a/lib_lc3plus/setup_enc_lc3.h +++ b/lib_lc3plus/setup_enc_lc3.h @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -11,6 +11,8 @@ #ifndef SETUP_ENC_LC3_FL_H #define SETUP_ENC_LC3_FL_H +#include "options.h" +#include "wmc_auto.h" #include "constants.h" /* Channel state and bitrate-derived values go in this struct */ @@ -22,7 +24,11 @@ typedef struct { 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]; +#else LC3_FLOAT r12k8_mem_out[24]; +#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]; @@ -44,6 +50,9 @@ typedef struct { LC3_INT tns_bits; LC3_INT targetBitsQuant; LC3_INT olpa_mem_pitch; +#ifdef CR9_F_PITCH_WIN_LEN_FIX + LC3_INT pitch_flag; +#endif LC3_INT ltpf_mem_ltpf_on; LC3_INT mem_targetBits; LC3_INT mem_specBits; diff --git a/lib_lc3plus/sns_compute_scf.c b/lib_lc3plus/sns_compute_scf.c index 5cb041925..7f78b3666 100644 --- a/lib_lc3plus/sns_compute_scf.c +++ b/lib_lc3plus/sns_compute_scf.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -9,14 +9,19 @@ #include "options.h" +#include "wmc_auto.h" #include "functions.h" -void processSnsComputeScf_fl(LC3_FLOAT* x, LC3_INT tilt, LC3_INT xLen, LC3_FLOAT* gains, LC3_INT smooth, LC3_FLOAT sns_damping, LC3_FLOAT attdec_damping_factor) +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 = 0, d = 0, i = 0, j = 0, n = 0, n2 = 0, n4 = 0, mapping[64] = {0}; - LC3_FLOAT tmp[64] = {0}, x_tmp1[MAX_LEN] = {0}, x_tmp2[MAX_LEN] = {0}, sum = 0, mean = 0, xl4[16] = {0}, nf = 0, xl[64] = {0}, gains_smooth[M] = {0}, ratio = 0; - LC3_FLOAT W[6] = {1.0 / 12.0, 2.0 / 12.0, 3.0 / 12.0, 3.0 / 12.0, 2.0 / 12.0, 1.0 / 12.0}; - + 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); @@ -28,13 +33,14 @@ void processSnsComputeScf_fl(LC3_FLOAT* x, LC3_INT tilt, LC3_INT xLen, LC3_FLOAT { j = 0; for (i = 0; i < 2 * d; i = i + 2) { - tmp[i] = x[j]; - tmp[i + 1] = x[j]; + x_tmp1[i] = x[j]; + x_tmp1[i + 1] = x[j]; j++; } - move_float(&tmp[2 * d], &x[d], 64 - 2 * d); - } else if (ceil(64.0 / (LC3_FLOAT) xLen) == 4) + 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); @@ -60,13 +66,13 @@ void processSnsComputeScf_fl(LC3_FLOAT* x, LC3_INT tilt, LC3_INT xLen, LC3_FLOAT for (i = 0; i < 64; i++) { - tmp[i] = x[mapping[i] - 1]; + x_tmp1[i] = x[mapping[i] - 1]; } } else { assert(0 && "Unsupported number of bands!"); } - move_float(x, tmp, 64); + move_float(x, x_tmp1, 64); bands_number = 64; xLen = bands_number; @@ -76,20 +82,17 @@ void processSnsComputeScf_fl(LC3_FLOAT* x, LC3_INT tilt, LC3_INT xLen, LC3_FLOAT /* Smoothing */ x_tmp1[0] = x[0]; + move_float(&x_tmp1[1], &x[0], 63); - move_float(&x_tmp1[1], &x[0], xLen - 1); - - move_float(&x_tmp2[0], &x[1], xLen - 1); - - x_tmp2[xLen - 1] = x[xLen - 1]; - - for (i = 0; i < xLen; i++) { - x[i] = 0.5 * x[i] + 0.25 * (x_tmp1[i] + x_tmp2[i]); + 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 < xLen; i++) { - x[i] = x[i] * LC3_POW(10.0, (LC3_FLOAT)i * (LC3_FLOAT)tilt / ((LC3_FLOAT)bands_number - 1.0) / 10.0); + for (i = 0; i < 64; i++) { + x[i] = x[i] * sns_preemph[i]; } /* Noise floor at -40dB */ @@ -97,10 +100,10 @@ void processSnsComputeScf_fl(LC3_FLOAT* x, LC3_INT tilt, LC3_INT xLen, LC3_FLOAT sum += x[i]; } - mean = sum / (LC3_FLOAT)xLen; + mean = sum * 0.015625; /* 1/64 */ - nf = mean * LC3_POW(10.0, -40.0 / 10.0); - nf = MAX(nf, LC3_POW(2.0, -32.0)); + nf = mean * 1.00e-04; + nf = MAX(nf, 2.328306436538696e-10); for (i = 0; i < 64; i++) { if (x[i] < nf) { @@ -110,45 +113,40 @@ void processSnsComputeScf_fl(LC3_FLOAT* x, LC3_INT tilt, LC3_INT xLen, LC3_FLOAT /* Log-domain */ for (i = 0; i < 64; i++) { - xl[i] = LC3_LOGTWO(x[i]) / 2.0; + x[i] = LC3_LOGTWO(x[i]) * 0.5; } /* Downsampling */ - for (n = 0; n < bands_number / 4; n++) { + for (n = 0; n < 16; n++) { if (n == 0) { - tmp[0] = xl[0]; + x_tmp1[0] = x[0]; - move_float(&tmp[1], &xl[0], 5); + move_float(&x_tmp1[1], &x[0], 5); - } else if (n == (bands_number / 4 - 1)) { - move_float(tmp, &xl[59], 5); + } else if (n == 15) { + move_float(x_tmp1, &x[59], 5); - tmp[5] = xl[63]; + x_tmp1[5] = x[63]; } else { - move_float(tmp, &xl[n * 4 - 1], ((n * 4 + 5 - 1) - (n * 4 - 1) + 1)); + 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 += tmp[i] * W[i]; + sum += x_tmp1[i] * sns_W[i]; } - xl4[n] = sum; + gains_smooth[n] = sum; + sum_gains_smooth += sum; } /* Remove mean and scaling */ + mean = sum_gains_smooth / 16.0; - sum = 0; - for (i = 0; i < bands_number / 4; i++) { - sum += xl4[i]; - } - - mean = sum / ((LC3_FLOAT)bands_number / 4.0); - - for (i = 0; i < bands_number / 4; i++) { - gains[i] = sns_damping * (xl4[i] - mean); + for (i = 0; i < 16; i++) { + gains[i] = sns_damping * (gains_smooth[i] - mean); } /* Smoothing */ diff --git a/lib_lc3plus/sns_interpolate_scf.c b/lib_lc3plus/sns_interpolate_scf.c index 441939789..98b54909b 100644 --- a/lib_lc3plus/sns_interpolate_scf.c +++ b/lib_lc3plus/sns_interpolate_scf.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -9,27 +9,28 @@ #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 = 0, n = 0, d = 0, n4 = 0; - LC3_FLOAT tmp[MAX_BANDS_NUMBER_PLC] = {0}, ratio = 0; + 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]) / 8.0; - gains_int[n * 4 + 3] = gains[n] + 3.0 * (gains[n + 1] - gains[n]) / 8.0; - gains_int[n * 4 + 4] = gains[n] + 5.0 * (gains[n + 1] - gains[n]) / 8.0; - gains_int[n * 4 + 5] = gains[n] + 7.0 * (gains[n + 1] - gains[n]) / 8.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]) / 8.0; - gains_int[63] = gains[15] + 3.0 * (gains[15] - gains[14]) / 8.0; + gains_int[62] = gains[15] + (gains[15] - gains[14]) * 0.125; + gains_int[63] = gains[15] + (gains[15] - gains[14]) * 0.375; /* For 5ms */ @@ -53,7 +54,8 @@ void processSnsInterpolateScf_fl(LC3_FLOAT* gains, LC3_INT encoder_side, LC3_INT } move_float(gains_int, tmp, d); - } else if (ceil(64.0 / (LC3_FLOAT) bands_number) == 4) + } + 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); diff --git a/lib_lc3plus/sns_quantize_scf.c b/lib_lc3plus/sns_quantize_scf.c index 704127cce..e3fa34d83 100644 --- a/lib_lc3plus/sns_quantize_scf.c +++ b/lib_lc3plus/sns_quantize_scf.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -9,6 +9,7 @@ #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); @@ -421,7 +422,7 @@ LC3_INT find_last_indice_le(LC3_INT compare, const LC3_INT* array, LC3_INT len) void pvq_dec(LC3_INT k, LC3_INT m, LC3_INT LS_ind, LC3_INT MPVQ_ind, LC3_INT* pulses) { - LC3_INT leading_sign = 0, idx = 0, k_delta = 0, pos = 0; + LC3_INT leading_sign, idx, k_delta = 0, pos; leading_sign = 1 - 2 * LS_ind; @@ -454,9 +455,9 @@ void pvq_dec(LC3_INT k, LC3_INT m, LC3_INT LS_ind, LC3_INT MPVQ_ind, LC3_INT* pu void process_snsQuantizesScf_Dec(LC3_INT* scf_idx, LC3_FLOAT* scf_q) { - LC3_INT i = 0, submode = 0; + LC3_INT i, submode; LC3_INT pulses2[6] = {0}, pulses[M] = {0}; - LC3_FLOAT st2_vector[M] = {0}, st2_vector_idct[M] = {0}, sum = 0; + LC3_FLOAT st2_vector[M], st2_vector_idct[M], sum = 0; /* Decode first stage */ @@ -505,13 +506,18 @@ void process_snsQuantizesScf_Dec(LC3_INT* scf_idx, LC3_FLOAT* scf_q) 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]]; } - /* Add stage 1 and stage 2 */ - for (i = 0; i < M; i++) { scf_q[i] = scf_q[i] + st2_vector_idct[i]; } +#endif } diff --git a/lib_lc3plus/structs.h b/lib_lc3plus/structs.h index fea377da4..59425744e 100644 --- a/lib_lc3plus/structs.h +++ b/lib_lc3plus/structs.h @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -11,6 +11,8 @@ #ifndef STRUCTS_H #define STRUCTS_H +#include "options.h" +#include "wmc_auto.h" #include "defines.h" #include "fft/iisfft.h" @@ -66,6 +68,7 @@ typedef struct { 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 { @@ -154,6 +157,9 @@ typedef struct { 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; @@ -179,8 +185,24 @@ typedef struct { LC3_FLOAT cum_fflcAtten; LC3_FLOAT scf_q_old[M]; LC3_FLOAT scf_q_old_old[M]; - PlcPhEcuSetup PlcPhEcuSetup; + 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/tns_coder.c b/lib_lc3plus/tns_coder.c index ff3883d2b..6870ba1e1 100644 --- a/lib_lc3plus/tns_coder.c +++ b/lib_lc3plus/tns_coder.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -9,40 +9,28 @@ #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); -static LC3_INT findRC_idx(const LC3_FLOAT* in1, const LC3_FLOAT* in2, LC3_FLOAT checkValue); void xcorr(LC3_FLOAT* in, LC3_FLOAT* out, LC3_INT lag, LC3_INT inLen) { - LC3_INT i = 0, m = 0; - LC3_FLOAT sum = 0, tmp_buf[MAX_LEN] = {0}; + LC3_INT32 m; - for (m = -lag; m <= lag; m++) { - /* Append zeros and input vector */ - zero_float(tmp_buf, abs(m)); - - move_float(&tmp_buf[abs(m)], in, inLen - abs(m)); - - /* Calculate sum */ - sum = 0; - - for (i = 0; i < inLen; i++) { - sum += in[i] * tmp_buf[i]; - } - - out[m + lag] = sum; + 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 = 0, i = 0, j = 0; - LC3_FLOAT g = 0, v = 0, sum = 0, buf_tmp[MAX_LEN] = {0}; + LC3_INT t, i, j; + LC3_FLOAT g, v, sum, buf_tmp[10]; g = r[1] / r[0]; out_lev[0] = g; @@ -51,7 +39,6 @@ void levinsonDurbin(LC3_FLOAT* r, LC3_FLOAT* out_lev, LC3_FLOAT* rc_unq, LC3_FLO rc_unq[0] = -g; for (t = 1; t < len; t++) { - zero_float(buf_tmp, len + 1); sum = 0; for (i = 1; i <= t; i++) { @@ -91,33 +78,33 @@ void levinsonDurbin(LC3_FLOAT* r, LC3_FLOAT* out_lev, LC3_FLOAT* rc_unq, LC3_FLO void levdown(LC3_FLOAT* anxt, LC3_FLOAT* out_a, LC3_INT* len) { - LC3_INT i = 0, j = 0; - LC3_FLOAT tmp_buf[8] = {0}, tmp_buf1[8] = {0}, tmp_buf2[8] = {0}, knxt = 0; + 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 */ - move_float(&tmp_buf[0], &anxt[1], (*len - 1)); - *len = *len - 1; /* Lenght = 8 */ /* Last coefficient */ - knxt = tmp_buf[*len - 1]; /* At [7] */ + knxt = anxt[*len]; /* At [7] */ *len = *len - 1; /* Lenght = 7 */ - move_float(tmp_buf1, tmp_buf, *len); - j = 0; for (i = *len - 1; i >= 0; i--) { - tmp_buf2[j] = knxt * tmp_buf[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] = (tmp_buf1[i] - tmp_buf2[i]) / (1.0 - (LC3_FABS(knxt)) * (LC3_FABS(knxt))); + out_a[i + 1] = (anxt[i + 1] - tmp_buf[i]) * norm; } *len = *len + 1; /* Length = 8 */ @@ -125,8 +112,8 @@ void levdown(LC3_FLOAT* anxt, LC3_FLOAT* out_a, LC3_INT* len) void poly2rc(LC3_FLOAT* a, LC3_FLOAT* out, LC3_INT len) { - LC3_INT k = 0, i = 0, len_old = 0; - LC3_FLOAT buf[9] = {0}; + LC3_INT k, i, len_old; + LC3_FLOAT buf[9]; len_old = len; @@ -155,30 +142,21 @@ void poly2rc(LC3_FLOAT* a, LC3_FLOAT* out, LC3_INT len) } } -LC3_INT findRC_idx(const LC3_FLOAT* in1, const LC3_FLOAT* in2, LC3_FLOAT checkValue) -{ - LC3_INT i = 0, ret = 0; - - for (i = 0; i < 17; i++) { - if (checkValue <= in1[i] && checkValue > in2[i]) { - ret = i; - } - } - - return ret; -} 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 = 0, stopfreq[2] = {0}, startfreq[2] = {0}, f = 0, numfilters = 0, maxOrder = 0, bits = 0, sub = 0, - subdiv_startfreq = 0, subdiv_stopfreq = 0, j = 0, rc_idx_tmp[8] = {0}, order_tmp[8] = {0}, tmp = 0, tns = 0; - LC3_FLOAT minPGfac = 0, minPredictionGain = 0, maxPG = 0, xcorr_out[MAX_LEN] = {0}, buf_tmp[MAX_LEN] = {0}, sum = 0, - subdiv_len = 0, nSubdivisions = 0, r[9] = {0}, out_lev[9] = {0}, rc_unq[9] = {0}, error_lev = 0, predGain = 0, - alpha = 0, rc[8] = {0}, st[9] = {0}, s = 0, tmpSave = 0, tmp_fl = 0; + 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 */ @@ -188,8 +166,10 @@ void processTnsCoder_fl(LC3_FLOAT* x, LC3_INT bw_cutoff_idx, LC3_INT bw_fcbin, L numfilters = 1; } - if (N > 40 * ((LC3_FLOAT) (frame_dms) / 10.0)) { - N = 40 * ((LC3_FLOAT) (frame_dms) / 10.0); + /* 40 * frame_dms / 10 = 4 * frame_dms */ + if (N > 4 * frame_dms) + { + N = 4 * frame_dms; fs = 40000; } @@ -213,21 +193,21 @@ void processTnsCoder_fl(LC3_FLOAT* x, LC3_INT bw_cutoff_idx, LC3_INT bw_fcbin, L 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; } - minPGfac = 0.85; - maxPG = 2; minPredictionGain = 1.5; - if ((frame_dms >= 50 && nBits >= 48 * ((LC3_FLOAT) frame_dms / 10.0)) || frame_dms == 25) { - maxPG = minPredictionGain; - } - - if ((frame_dms >= 50 && nBits >= 48 * ((LC3_FLOAT) frame_dms / 10.0)) || frame_dms == 25) { + if (nBits >= 4.8 * frame_dms) { order = order1_tns; } else { order = order2_tns; @@ -249,32 +229,53 @@ void processTnsCoder_fl(LC3_FLOAT* x, LC3_INT bw_cutoff_idx, LC3_INT bw_fcbin, L for (f = 0; f < numfilters; f++) { subdiv_len = ((LC3_FLOAT)stopfreq[f] + 1.0 - (LC3_FLOAT)startfreq[f]) / nSubdivisions; - zero_float(r, 9); + 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, 9); + if (sum < LC3_EPS) { + zero_float(r, MAXLAG+1); r[0] = 1; break; } - move_float(buf_tmp, &x[subdiv_startfreq], subdiv_stopfreq - subdiv_startfreq); - - xcorr(buf_tmp, xcorr_out, maxOrder, subdiv_stopfreq - subdiv_startfreq); + xcorr(&x[subdiv_startfreq], xcorr_out, maxOrder, subdiv_stopfreq - subdiv_startfreq); - j = 0; - for (i = maxOrder; i >= 0; i--) { - r[j] = r[j] + xcorr_out[i] / sum; - j++; + inv_sum = 1.0 / sum; + for (i = 0; i <= maxOrder; i++) { + r[i] = r[i] + xcorr_out[i] * inv_sum; } } @@ -282,7 +283,7 @@ void processTnsCoder_fl(LC3_FLOAT* x, LC3_INT bw_cutoff_idx, LC3_INT bw_fcbin, L r[i] = r[i] * lagw_tns[i]; } - levinsonDurbin(r, out_lev, rc_unq, &error_lev, maxOrder); + levinsonDurbin(r, xcorr_out, rc_unq, &error_lev, maxOrder); predGain = r[0] / error_lev; @@ -295,34 +296,50 @@ void processTnsCoder_fl(LC3_FLOAT* x, LC3_INT bw_cutoff_idx, LC3_INT bw_fcbin, L 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++) { - out_lev[i] = out_lev[i] * LC3_POW(alpha, i); + xcorr_out[i] = xcorr_out[i] * alpha_loc; + alpha_loc *= alpha; } - poly2rc(out_lev, rc_unq, maxOrder + 1); + poly2rc(xcorr_out, rc_unq, maxOrder + 1); } /* PARCOR Quantization */ - for (i = 0; i < maxOrder; i++) { - rc_idx_tmp[i] = findRC_idx(&quants_thr_tns[1], &quants_thr_tns[0], rc_unq[i]); + 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 */ - j = 0; + order_tmp = 0; for (i = 0; i < maxOrder; i++) { rc[i] = quants_pts_tns[rc_idx_tmp[i]]; if (rc[i] != 0) { - order_tmp[j] = i + 1; - j++; + order_tmp = i + 1; } } - order_out[f] = order_tmp[j - 1]; + order_out[f] = order_tmp; + // Disable TNS if order is 0: if (order_out[f] == 0) { tns = 0; @@ -344,6 +361,9 @@ void processTnsCoder_fl(LC3_FLOAT* x, LC3_INT bw_cutoff_idx, LC3_INT bw_fcbin, L rc_idx[i] = rc_idx_tmp[j]; j++; } + } else { +tns_disabled: + order_out[f] = 0; } /* Filtering */ @@ -367,7 +387,6 @@ void processTnsCoder_fl(LC3_FLOAT* x, LC3_INT bw_cutoff_idx, LC3_INT bw_fcbin, L } } } -tns_disabled: *tns_numfilters = numfilters; *bits_out = bits; diff --git a/lib_lc3plus/tns_decoder.c b/lib_lc3plus/tns_decoder.c index d3aeefc3a..dbdadaeaf 100644 --- a/lib_lc3plus/tns_decoder.c +++ b/lib_lc3plus/tns_decoder.c @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -9,12 +9,14 @@ #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] = {0}, stopfreq[2] = {0}, f = 0, i = 0, j = 0, m = 0, l = 0, rc_idx_f[9] = {0}; - LC3_FLOAT rc[9] = {0}, s = 0, st[9] = {0}; + 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; @@ -27,19 +29,20 @@ void processTnsDecoder_fl(LC3_FLOAT* x, LC3_INT* rc_idx, LC3_INT* order, LC3_INT } for (f = 0; f < numfilters; f++) { - if (order[f] > 0) { + order_tmp = order[f]; + + if (order_tmp > 0) { j = 0; - for (i = f * 8; i < f * 8 + 8; i++) { - rc_idx_f[j] = rc_idx[i]; - rc[j] = quants_pts_tns[rc_idx_f[j]]; + 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[f] - 1] * st[order[f] - 1]; + s = x[m - 1] - rc[order_tmp - 1] * st[order_tmp - 1]; - for (l = order[f] - 2; l >= 0; l--) { + for (l = order_tmp - 2; l >= 0; l--) { s = s - rc[l] * st[l]; st[l + 1] = rc[l] * s + st[l]; } diff --git a/lib_lc3plus/util.h b/lib_lc3plus/util.h index 7ef6dedef..069e89371 100644 --- a/lib_lc3plus/util.h +++ b/lib_lc3plus/util.h @@ -1,5 +1,5 @@ /****************************************************************************** -* ETSI TS 103 634 V1.4.1 * +* ETSI TS 103 634 V1.4.3 * * Low Complexity Communication Codec Plus (LC3plus) * * * * Copyright licence is solely granted through ETSI Intellectual Property * @@ -11,6 +11,8 @@ #ifndef UTIL_H #define UTIL_H +#include "options.h" +#include "wmc_auto.h" #include "clib.h" #include "math.h" @@ -51,18 +53,50 @@ 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 */ -- GitLab From fcdaf9b17bfec4671347f58253a8800fe26c86ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20M=C3=BCller?= Date: Thu, 16 Jan 2025 13:12:41 +0100 Subject: [PATCH 12/33] Change ref_using_main to ref_using_target --- .gitlab-ci.yml | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index a3881a16c..ec3297e68 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -780,7 +780,9 @@ split-rendering-pytest-on-merge-request: # write to temporary file as workaround for failures observed with piping echo - echo $CI_MERGE_REQUEST_TITLE > tmp.txt - non_be_flag=$(grep -c --ignore-case "\[split*[ -]*non[ -]*be\]" tmp.txt) || true - - ref_using_main=$(grep -c --ignore-case "\[ref[ -]*using[ -]*main\]" tmp.txt) || true + - # TODO: ref_using_target comes from float repo, but does not apply here - disable for now + - # - ref_using_target=$(grep -c --ignore-case "\[ref[ -]*using[ -]*target\]" tmp.txt) || true + - ref_using_target=0 # store the current commit hash - source_branch_commit_sha=$(git rev-parse HEAD) @@ -796,9 +798,9 @@ split-rendering-pytest-on-merge-request: - mv IVAS_dec IVAS_dec_ref - mv IVAS_rend IVAS_rend_ref - ### If ref_using_main is not set, checkout the source branch to use scripts and input from there - - if [ $ref_using_main == 0 ]; then git restore lib_com/options.h; fi # Revert changes back before checking out another branch to avoid conflicts - - if [ $ref_using_main == 0 ]; then git checkout $source_branch_commit_sha; fi + ### If ref_using_target is not set, checkout the source branch to use scripts and input from there + - if [ $ref_using_target == 0 ]; then git restore lib_com/options.h; fi # Revert changes back before checking out another branch to avoid conflicts + - if [ $ref_using_target == 0 ]; then git checkout $source_branch_commit_sha; fi - exit_code=0 - testcase_timeout=60 - python3 -m pytest -q --log-level ERROR -n auto -rA --html=report.html --self-contained-html --junit-xml=report-junit.xml tests/split_rendering/test_split_rendering.py --create_ref --testcase_timeout=$testcase_timeout || exit_code=$? @@ -810,8 +812,8 @@ split-rendering-pytest-on-merge-request: - make -j ### Run test using scripts and input from main - - if [ $ref_using_main == 1 ]; then git restore lib_com/options.h; fi # Revert changes back before checking out another branch to avoid conflicts - - if [ $ref_using_main == 1 ]; then git checkout $source_branch_commit_sha; fi + - if [ $ref_using_target == 1 ]; then git restore lib_com/options.h; fi # Revert changes back before checking out another branch to avoid conflicts + - if [ $ref_using_target == 1 ]; then git checkout $source_branch_commit_sha; fi # run test - python3 -m pytest -q --log-level ERROR -n auto -rA --html=report.html --self-contained-html --junit-xml=report-junit.xml tests/split_rendering/test_split_rendering.py --create_cut --testcase_timeout=$testcase_timeout || exit_code=$? -- GitLab From b9422f43aa674c5801d7b618d4d5d260308275ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fabian=20M=C3=BCller?= Date: Thu, 16 Jan 2025 13:21:17 +0100 Subject: [PATCH 13/33] fixup! Change ref_using_main to ref_using_target --- .gitlab-ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index ec3297e68..b3f455f02 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -780,8 +780,8 @@ split-rendering-pytest-on-merge-request: # write to temporary file as workaround for failures observed with piping echo - echo $CI_MERGE_REQUEST_TITLE > tmp.txt - non_be_flag=$(grep -c --ignore-case "\[split*[ -]*non[ -]*be\]" tmp.txt) || true - - # TODO: ref_using_target comes from float repo, but does not apply here - disable for now - - # - ref_using_target=$(grep -c --ignore-case "\[ref[ -]*using[ -]*target\]" tmp.txt) || true + # TODO: ref_using_target comes from float repo, but does not apply here - disable for now + # - ref_using_target=$(grep -c --ignore-case "\[ref[ -]*using[ -]*target\]" tmp.txt) || true - ref_using_target=0 # store the current commit hash -- GitLab From 6939453551613454a1bb8a089537537f03a197b4 Mon Sep 17 00:00:00 2001 From: rtyag Date: Sat, 18 Jan 2025 01:07:34 +1100 Subject: [PATCH 14/33] remainder of SR float changes (not compiling yet) --- CMakeLists.txt | 97 +- Makefile | 57 +- Workspace_msvc/Workspace_msvc.sln | 6 +- Workspace_msvc/decoder.vcxproj | 7 +- Workspace_msvc/isar_post_rend.vcxproj | 177 + Workspace_msvc/lib_com.vcxproj | 7 +- Workspace_msvc/lib_dec.vcxproj | 4 +- Workspace_msvc/lib_enc.vcxproj | 4 +- Workspace_msvc/lib_isar.vcxproj | 200 + Workspace_msvc/lib_lc3plus.vcxproj | 4 +- Workspace_msvc/lib_rend.vcxproj | 28 +- Workspace_msvc/lib_util.vcxproj | 4 +- Workspace_msvc/renderer.vcxproj | 7 +- apps/decoder.c | 323 +- apps/renderer.c | 470 +- lib_com/ivas_cnst.h | 92 - lib_com/ivas_error.h | 6 + {lib_rend => lib_com}/ivas_limiter.c | 2 +- .../ivas_osba_com.c | 51 +- lib_com/ivas_prot.h | 51 + lib_com/ivas_rotation_com.c | 137 + lib_com/options.h | 2 + lib_dec/ivas_binRenderer_internal.c | 83 +- lib_dec/ivas_dirac_dec.c | 36 +- lib_dec/ivas_init_dec.c | 169 +- lib_dec/ivas_ism_dec.c | 4 +- lib_dec/ivas_jbm_dec.c | 34 +- lib_dec/ivas_masa_dec.c | 11 +- lib_dec/ivas_mc_param_dec.c | 14 +- lib_dec/ivas_mc_paramupmix_dec.c | 56 +- lib_dec/ivas_mct_dec.c | 4 +- lib_dec/ivas_objectRenderer_internal.c | 22 +- lib_dec/ivas_omasa_dec.c | 71 +- lib_dec/ivas_osba_dec.c | 22 +- lib_dec/ivas_output_config.c | 3 - lib_dec/ivas_rom_dec.c | 138 - lib_dec/ivas_rom_dec.h | 26 - lib_dec/ivas_stat_dec.h | 67 +- lib_dec/lib_dec.c | 451 +- lib_dec/lib_dec.h | 28 +- lib_rend/ivas_MSPred.c | 564 - lib_rend/ivas_NoiseGen.c | 100 - lib_rend/ivas_PerceptualModel.c | 257 - lib_rend/ivas_PredDecoder.c | 335 - lib_rend/ivas_PredEncoder.c | 531 - lib_rend/ivas_RMSEnvGrouping.c | 951 - lib_rend/ivas_crend.c | 25 +- lib_rend/ivas_dirac_dec_binaural_functions.c | 53 +- lib_rend/ivas_dirac_output_synthesis_dec.c | 197 +- lib_rend/ivas_dirac_rend.c | 4 - lib_rend/ivas_lc3plus_common.h | 57 - lib_rend/ivas_lc3plus_dec.c | 703 - lib_rend/ivas_lc3plus_dec.h | 119 - lib_rend/ivas_lc3plus_enc.c | 334 - lib_rend/ivas_lc3plus_enc.h | 76 - lib_rend/ivas_lcld_decoder.c | 1668 -- lib_rend/ivas_lcld_encoder.c | 2011 -- lib_rend/ivas_lcld_prot.h | 370 - lib_rend/ivas_lcld_rom_tables.c | 19854 ---------------- lib_rend/ivas_lcld_rom_tables.h | 225 - lib_rend/ivas_objectRenderer.c | 150 - lib_rend/ivas_output_init.c | 2 +- lib_rend/ivas_prot_rend.h | 388 +- lib_rend/ivas_render_config.c | 12 +- lib_rend/ivas_rom_rend.h | 8 - lib_rend/ivas_rotation.c | 107 +- lib_rend/ivas_splitRend_lcld_dec.c | 239 - lib_rend/ivas_splitRend_lcld_enc.c | 232 - lib_rend/ivas_splitRendererPLC.c | 552 - lib_rend/ivas_splitRendererPost.c | 1799 -- lib_rend/ivas_splitRendererPre.c | 2474 -- lib_rend/ivas_splitRenderer_utils.c | 1089 - lib_rend/ivas_stat_rend.h | 108 +- lib_rend/lib_rend.c | 975 +- lib_rend/lib_rend.h | 41 +- lib_util/render_config_reader.c | 29 +- lib_util/split_rend_bfi_file_reader.c | 4 +- lib_util/split_render_file_read_write.c | 151 +- lib_util/split_render_file_read_write.h | 37 +- 79 files changed, 2318 insertions(+), 37488 deletions(-) create mode 100644 Workspace_msvc/isar_post_rend.vcxproj create mode 100644 Workspace_msvc/lib_isar.vcxproj rename {lib_rend => lib_com}/ivas_limiter.c (99%) rename lib_rend/ivas_lc3plus_common.c => lib_com/ivas_osba_com.c (76%) create mode 100644 lib_com/ivas_rotation_com.c delete mode 100644 lib_rend/ivas_MSPred.c delete mode 100644 lib_rend/ivas_NoiseGen.c delete mode 100644 lib_rend/ivas_PerceptualModel.c delete mode 100644 lib_rend/ivas_PredDecoder.c delete mode 100644 lib_rend/ivas_PredEncoder.c delete mode 100644 lib_rend/ivas_RMSEnvGrouping.c delete mode 100644 lib_rend/ivas_lc3plus_common.h delete mode 100644 lib_rend/ivas_lc3plus_dec.c delete mode 100644 lib_rend/ivas_lc3plus_dec.h delete mode 100644 lib_rend/ivas_lc3plus_enc.c delete mode 100644 lib_rend/ivas_lc3plus_enc.h delete mode 100644 lib_rend/ivas_lcld_decoder.c delete mode 100644 lib_rend/ivas_lcld_encoder.c delete mode 100644 lib_rend/ivas_lcld_prot.h delete mode 100644 lib_rend/ivas_lcld_rom_tables.c delete mode 100644 lib_rend/ivas_lcld_rom_tables.h delete mode 100644 lib_rend/ivas_splitRend_lcld_dec.c delete mode 100644 lib_rend/ivas_splitRend_lcld_enc.c delete mode 100644 lib_rend/ivas_splitRendererPLC.c delete mode 100644 lib_rend/ivas_splitRendererPost.c delete mode 100644 lib_rend/ivas_splitRendererPre.c delete mode 100644 lib_rend/ivas_splitRenderer_utils.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 435773d7b..17799f0db 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,14 +27,12 @@ # # or build on command line, e.g.: # cmake --build . --config Debug # cmake --build . --config Release -# -# INCLUDE_SPLIT is not set by default. If split rendering is used, then add -D INCLUDE_SPLIT=1 to the build command + cmake_minimum_required(VERSION 3.1) set(CMAKE_C_STANDARD 99) - # configuration options for UNIX if(UNIX) set(TARGET_PLATFORM "" CACHE STRING "i686 / x86_64") @@ -60,7 +58,10 @@ if(UNIX) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ffp-contract=off") # disable floating point operation contraction set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -pedantic -Wcast-qual -Wall -W -Wextra -Wno-long-long") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wpointer-arith -Wstrict-prototypes -Wmissing-prototypes") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror-implicit-function-declaration -Wno-unused-parameter") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-parameter") + # to be uncommented in CI + # set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror") + # CLANG if(CLANG) find_program(clangBin NAMES /home/amm-archiv/soft/Linux/clang/current/bin/clang clang REQUIRED) @@ -112,8 +113,6 @@ elseif(WIN32) -D_CRT_SECURE_NO_WARNINGS /MP ) - # CMake sets /W3 by default, until CMake version 3.15. Instead of setting /W4 separately, replace in existing settings - string(REGEX REPLACE "/W3" "/W4" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}") endif() # configuration options for all platforms @@ -132,88 +131,61 @@ add_library(lib_com ${libComSrcs} ${libComHeaders}) if(UNIX) target_link_libraries(lib_com PRIVATE m) endif() -target_include_directories(lib_com PUBLIC lib_com PRIVATE lib_enc lib_dec lib_rend lib_debug) -if(INCLUDE_SPLIT) - target_include_directories(lib_com PRIVATE lib_lc3plus) -endif() +target_include_directories(lib_com PUBLIC lib_com PRIVATE lib_enc lib_dec lib_rend lib_debug lib_isar) +target_include_directories(lib_com PRIVATE lib_lc3plus) file(GLOB libDebugSrcs "lib_debug/*.c") file(GLOB libDebugHeaders "lib_debug/*.h") add_library(lib_debug ${libDebugSrcs} ${libDebugHeaders}) target_link_libraries(lib_debug lib_com) -target_include_directories(lib_debug PUBLIC lib_debug PRIVATE lib_enc lib_dec lib_rend) +target_include_directories(lib_debug PUBLIC lib_debug PRIVATE lib_enc lib_dec lib_rend lib_isar) file(GLOB libEncSrcs "lib_enc/*.c") file(GLOB libEncHeaders "lib_enc/*.h") add_library(lib_enc ${libEncSrcs} ${libEncHeaders}) target_link_libraries(lib_enc lib_com lib_debug) -target_include_directories(lib_enc PUBLIC lib_enc PRIVATE lib_dec lib_rend) -if(INCLUDE_SPLIT) - target_include_directories(lib_enc PRIVATE lib_lc3plus) -endif() +target_include_directories(lib_enc PUBLIC lib_enc PRIVATE lib_dec lib_rend lib_isar) +target_include_directories(lib_enc PRIVATE lib_lc3plus) -if(INCLUDE_SPLIT) - file(GLOB libLC3plusSrcs "lib_lc3plus/*.c") - file(GLOB libLC3plusHeaders "lib_lc3plus/*.h") - add_library(lib_lc3plus ${libLC3plusSrcs} ${libLC3plusHeaders}) - target_include_directories(lib_lc3plus PUBLIC lib_lc3plus) - target_link_libraries(lib_lc3plus lib_com) # For including options.h, which is needed for instrumentation to work correctly - if(WMOPS) - target_link_libraries(lib_lc3plus lib_debug) - endif() -endif() +file(GLOB libLC3plusSrcs "lib_lc3plus/*.c") +file(GLOB libLC3plusHeaders "lib_lc3plus/*.h") +add_library(lib_lc3plus ${libLC3plusSrcs} ${libLC3plusHeaders}) +target_include_directories(lib_lc3plus PUBLIC lib_lc3plus PRIVATE lib_com lib_debug) file(GLOB libRendSrcs "lib_rend/*.c") file(GLOB libRendHeaders "lib_rend/*.h") -if(NOT INCLUDE_SPLIT) - list(FILTER libRendSrcs EXCLUDE REGEX ".*lib_rend\/.*lc3plus.*\.c$") - list(FILTER libRendSrcs EXCLUDE REGEX ".*lib_rend\/.*ivas_cldfb_codec.*\.c$") - list(FILTER libRendSrcs EXCLUDE REGEX ".*lib_rend\/.*splitRend.*\.c$") - list(FILTER libRendSrcs EXCLUDE REGEX ".*lib_rend\/.*splitrenderer.*\.c$") - list(FILTER libRendSrcs EXCLUDE REGEX ".*lib_rend\/.*ivas_lcld.*\.c$") - list(FILTER libRendSrcs EXCLUDE REGEX ".*lib_rend\/.*ivas_Pred.*\.c$") - list(FILTER libRendSrcs EXCLUDE REGEX ".*lib_rend\/.*ivas_RMSEnv.*\.c$") - list(FILTER libRendSrcs EXCLUDE REGEX ".*lib_rend\/.*ivas_PerceptualModel.*\.c$") - list(FILTER libRendSrcs EXCLUDE REGEX ".*lib_rend\/.*ivas_lcld_rom_tables.*\.c$") - list(FILTER libRendHeaders EXCLUDE REGEX ".*lib_rend\/.*lc3plus.*\.h$") - list(FILTER libRendHeaders EXCLUDE REGEX ".*lib_rend\/.*splitRend.*\.h$") - list(FILTER libRendHeaders EXCLUDE REGEX ".*lib_rend\/.*ivas_cldfb_codec.*\.h$") - list(FILTER libRendHeaders EXCLUDE REGEX ".*lib_rend\/.*ivas_lcld_rom_tables.*\.h$") -endif() add_library(lib_rend ${libRendSrcs} ${libRendHeaders}) target_link_libraries(lib_rend lib_dec lib_com lib_debug) # Todo refactor: This dependency on lib_dec should be removed. -if(INCLUDE_SPLIT) - target_link_libraries(lib_rend lib_lc3plus) -endif() -target_include_directories(lib_rend PUBLIC lib_rend PRIVATE lib_enc) +target_link_libraries(lib_rend lib_lc3plus lib_isar) +target_include_directories(lib_rend PUBLIC lib_rend PRIVATE lib_enc lib_isar) file(GLOB libDecSrcs "lib_dec/*.c") file(GLOB libDecHeaders "lib_dec/*.h") add_library(lib_dec ${libDecSrcs} ${libDecHeaders}) -target_link_libraries(lib_dec lib_com lib_rend lib_debug) -target_include_directories(lib_dec PUBLIC lib_dec lib_rend PRIVATE lib_enc) +target_link_libraries(lib_dec lib_com lib_rend lib_debug lib_isar) +target_include_directories(lib_dec PUBLIC lib_dec lib_rend PRIVATE lib_enc lib_isar) file(GLOB libUtilSrcs "lib_util/*.c") file(GLOB libUtilHeaders "lib_util/*.h") -if(NOT INCLUDE_SPLIT) - list(FILTER libUtilSrcs EXCLUDE REGEX ".*lib_util\/.*split_rend.*\.c$") -endif() add_library(lib_util ${libUtilSrcs} ${libUtilHeaders}) target_include_directories(lib_util PUBLIC lib_util PRIVATE lib_com lib_enc lib_dec lib_rend lib_debug) -if(INCLUDE_SPLIT) - target_include_directories(lib_util PRIVATE lib_lc3plus) -endif() +target_include_directories(lib_util PRIVATE lib_lc3plus lib_isar) -if(INCLUDE_SPLIT) - if(NOT WMOPS) - file(GLOB unitTestIvasLc3plusSrcs "scripts/split_rendering/lc3plus/*.c") - add_executable(ivas_lc3plus_unit_test ${unitTestIvasLc3plusSrcs}) - target_link_libraries(ivas_lc3plus_unit_test lib_rend lib_dec lib_util lib_com lib_debug) - endif() +if(NOT WMOPS) + add_executable(ivas_lc3plus_unit_test ${CMAKE_SOURCE_DIR}/scripts/split_rendering/lc3plus/ivas_lc3plus_unit_test.c) + target_link_libraries(ivas_lc3plus_unit_test lib_rend lib_dec lib_util lib_com lib_debug lib_isar) endif() +file(GLOB libISARSrcs "lib_isar/*.c") +file(GLOB libISARHeaders "lib_isar/*.h") + +add_library(lib_isar ${libISARSrcs} ${libISARHeaders}) +target_link_libraries(lib_isar lib_com lib_debug lib_lc3plus) # Todo refactor: This dependency on lib_dec should be removed. +target_include_directories(lib_isar PUBLIC lib_isar PRIVATE lib_enc lib_dec lib_rend) + + add_executable(IVAS_cod apps/encoder.c) target_link_libraries(IVAS_cod lib_enc lib_util) if(WIN32) @@ -227,19 +199,22 @@ if(WIN32) endif() add_executable(IVAS_rend apps/renderer.c) -target_link_libraries(IVAS_rend lib_rend lib_util) +target_link_libraries(IVAS_rend lib_rend lib_util lib_isar) target_include_directories(IVAS_rend PRIVATE lib_enc) +add_executable(ISAR_post_rend apps/isar_post_rend.c) +target_link_libraries(ISAR_post_rend lib_isar lib_util) +target_include_directories(ISAR_post_rend PRIVATE lib_isar) + if(COPY_EXECUTABLES_FROM_BUILD_DIR) # Optionally copy executables to the same place where Make puts them (useful for tests that expect executables in specific places) add_custom_command(TARGET IVAS_cod POST_BUILD VERBATIM COMMAND "${CMAKE_COMMAND}" -E copy "$" "${CMAKE_CURRENT_SOURCE_DIR}/") add_custom_command(TARGET IVAS_dec POST_BUILD VERBATIM COMMAND "${CMAKE_COMMAND}" -E copy "$" "${CMAKE_CURRENT_SOURCE_DIR}/") add_custom_command(TARGET IVAS_rend POST_BUILD VERBATIM COMMAND "${CMAKE_COMMAND}" -E copy "$" "${CMAKE_CURRENT_SOURCE_DIR}/") - if(INCLUDE_SPLIT) + add_custom_command(TARGET ISAR_post_rend POST_BUILD VERBATIM COMMAND "${CMAKE_COMMAND}" -E copy "$" "${CMAKE_CURRENT_SOURCE_DIR}/") if (NOT WMOPS) add_custom_command(TARGET ivas_lc3plus_unit_test POST_BUILD VERBATIM COMMAND "${CMAKE_COMMAND}" -E copy "$" "${CMAKE_CURRENT_SOURCE_DIR}/scripts/split_rendering/lc3plus") endif() - endif() endif() # Allow creating packages for CMake install diff --git a/Makefile b/Makefile index 9ebcb7aa9..63ac29842 100644 --- a/Makefile +++ b/Makefile @@ -6,25 +6,29 @@ SRC_LIBDEBUG = lib_debug SRC_LIBDEC = lib_dec SRC_LIBENC = lib_enc SRC_LIBREND = lib_rend +SRC_LIBISAR = lib_isar SRC_LC3PLUS = lib_lc3plus lib_lc3plus/fft SRC_LIBUTIL = lib_util SRC_APP = apps BUILD = build OBJDIR = obj -SRC_DIRS = $(sort -u $(SRC_LIBCOM) $(SRC_LIBDEBUG) $(SRC_LIBDEC) $(SRC_LIBENC) $(SRC_LIBREND) $(SRC_LC3PLUS) $(SRC_LIBUTIL) $(SRC_APP)) +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 -CLI_APIDEC ?= IVAS_dec -CLI_APIENC ?= IVAS_cod -CLI_APIREND ?= IVAS_rend -LIB_LIBCOM ?= libivascom.a -LIB_LIBDEBUG ?= libivasdebug.a -LIB_LIBDEC ?= libivasdec.a -LIB_LIBENC ?= libivasenc.a -LIB_LIBREND ?= libivasrend.a -LIB_LC3PLUS ?= liblc3plus.a -LIB_LIBUTIL ?= libivasutil.a +CLI_APIDEC ?= IVAS_dec +CLI_APIENC ?= IVAS_cod +CLI_APIREND ?= IVAS_rend +CLI_APIPOSTREND ?= ISAR_post_rend +LIB_LIBCOM ?= libivascom.a +LIB_LIBDEBUG ?= libivasdebug.a +LIB_LIBDEC ?= libivasdec.a +LIB_LIBENC ?= libivasenc.a +LIB_LIBREND ?= libivasrend.a +LIB_LIBISAR ?= libisar.a +LIB_LC3PLUS ?= liblc3plus.a +LIB_LIBUTIL ?= libivasutil.a + # Default tool settings CC ?= gcc @@ -57,8 +61,9 @@ endif # C compiler flags CFLAGS += -std=c99 -pedantic -Wcast-qual -Wall -W -Wextra -Wno-long-long \ -Wpointer-arith -Wstrict-prototypes -Wmissing-prototypes \ - -Werror-implicit-function-declaration \ -Wno-implicit-fallthrough -ffp-contract=off +# to be uncommented in CI +# CFLAGS += -Werror # libs to link LDLIBS += -lm @@ -134,6 +139,7 @@ SRCS_LIBDEC = $(foreach DIR,$(SRC_LIBDEC),$(patsubst $(DIR)/%,%,$(wildcard $(D SRCS_LIBENC = $(foreach DIR,$(SRC_LIBENC),$(patsubst $(DIR)/%,%,$(wildcard $(DIR)/*.c))) 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))) SRCS_LC3PLUS = $(foreach DIR,$(SRC_LC3PLUS),$(patsubst $(DIR)/%,%,$(wildcard $(DIR)/*.c))) OBJS_LIBCOM = $(addprefix $(OBJDIR)/,$(SRCS_LIBCOM:.c=.o)) @@ -141,20 +147,23 @@ OBJS_LIBDEBUG = $(addprefix $(OBJDIR)/,$(SRCS_LIBDEBUG:.c=.o)) OBJS_LIBDEC = $(addprefix $(OBJDIR)/,$(SRCS_LIBDEC:.c=.o)) OBJS_LIBENC = $(addprefix $(OBJDIR)/,$(SRCS_LIBENC:.c=.o)) OBJS_LIBREND = $(addprefix $(OBJDIR)/,$(SRCS_LIBREND:.c=.o)) +OBJS_LIBISAR = $(addprefix $(OBJDIR)/,$(SRCS_LIBISAR:.c=.o)) OBJS_LC3PLUS = $(addprefix $(OBJDIR)/,$(SRCS_LC3PLUS:.c=.o)) OBJS_LIBUTIL = $(addprefix $(OBJDIR)/,$(SRCS_LIBUTIL:.c=.o)) OBJS_CLI_APIDEC = $(OBJDIR)/decoder.o OBJS_CLI_APIENC = $(OBJDIR)/encoder.o OBJS_CLI_APPREND = $(OBJDIR)/renderer.o +OBJS_CLI_APPPOSTREND = $(OBJDIR)/isar_post_rend.o DEPS = $(addprefix $(OBJDIR)/,$(SRCS_LIBCOM:.c=.P) $(SRCS_LIBDEBUG:.c=.P) $(SRCS_LIBDEC:.c=.P) \ - $(SRCS_LIBENC:.c=.P) $(SRCS_LIBUTIL:.c=.P) $(SRCS_LIBREND:.c=.P) $(SRCS_LC3PLUS:.c=.P)) + $(SRCS_LIBENC:.c=.P) $(SRCS_LIBUTIL:.c=.P) $(SRCS_LIBREND:.c=.P) $(SRCS_LIBISAR:.c=.P) \ + $(SRCS_LC3PLUS:.c=.P)) ############################################################################### .PHONY: all clean -all: $(CLI_APIENC) $(CLI_APIDEC) $(CLI_APIREND) +all: $(CLI_APIENC) $(CLI_APIDEC) $(CLI_APIREND) $(CLI_APIPOSTREND) $(OBJDIR): $(QUIET)mkdir -p $(OBJDIR) @@ -162,16 +171,19 @@ $(OBJDIR): $(LIB_LIBCOM): $(OBJS_LIBCOM) $(QUIET_AR)$(AR) rcs $@ $^ -$(LIB_LIBDEC): $(OBJS_LIBDEC) $(OBJS_LIBREND) +$(LIB_LIBDEC): $(OBJS_LIBDEC) $(OBJS_LIBREND) $(OBJS_LIBISAR) $(QUIET_AR)$(AR) rcs $@ $^ $(LIB_LIBDEBUG): $(OBJS_LIBDEBUG) $(QUIET_AR)$(AR) rcs $@ $^ +$(LIB_LIBISAR): $(OBJS_LIBISAR) + $(QUIET_AR)$(AR) rcs $@ $^ + $(LIB_LIBENC): $(OBJS_LIBENC) $(QUIET_AR)$(AR) rcs $@ $^ -$(LIB_LIBREND): $(OBJS_LIBREND) +$(LIB_LIBREND): $(OBJS_LIBREND) $(OBJS_LIBISAR) $(QUIET_AR)$(AR) rcs $@ $^ $(LIB_LC3PLUS): $(OBJS_LC3PLUS) @@ -183,19 +195,22 @@ $(LIB_LIBUTIL): $(OBJS_LIBUTIL) $(CLI_APIENC): $(OBJS_CLI_APIENC) $(LIB_LIBENC) $(LIB_LIBCOM) $(LIB_LIBUTIL) $(LIB_LIBDEBUG) $(LIB_LC3PLUS) $(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) +$(CLI_APIDEC): $(OBJS_CLI_APIDEC) $(LIB_LIBDEC) $(LIB_LIBCOM) $(LIB_LIBUTIL) $(LIB_LIBDEBUG) $(LIB_LC3PLUS) $(LIB_LIBISAR) $(QUIET_LINK)$(CC) $(LDFLAGS) $(OBJS_CLI_APIDEC) -L. -livasdec -livascom -livasutil -livasdebug -llc3plus $(LDLIBS) -o $(CLI_APIDEC) -$(CLI_APIREND): $(OBJS_CLI_APPREND) $(LIB_LIBREND) $(LIB_LIBCOM) $(LIB_LIBUTIL) $(LIB_LIBDEBUG) $(LIB_LIBDEC) $(LIB_LC3PLUS) - $(QUIET_LINK)$(CC) $(LDFLAGS) $(OBJS_CLI_APPREND) -L. -livasrend -livasdec -livasutil -livasdebug -livascom -llc3plus $(LDLIBS) -o $(CLI_APIREND) +$(CLI_APIREND): $(OBJS_CLI_APPREND) $(LIB_LIBREND) $(LIB_LIBCOM) $(LIB_LIBUTIL) $(LIB_LIBDEBUG) $(LIB_LIBDEC) $(LIB_LC3PLUS) $(LIB_LIBISAR) + $(QUIET_LINK)$(CC) $(LDFLAGS) $(OBJS_CLI_APPREND) -L. -livasrend -lisar -livasdec -livasutil -livasdebug -livascom -llc3plus $(LDLIBS) -o $(CLI_APIREND) + +$(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) -libs: $(LIB_LIBENC) $(LIB_LIBDEBUG) $(LIB_LIBCOM) $(LIB_LIBDEC) $(LIB_LIBREND) $(LIB_LC3PLUS) $(LIB_LIBUTIL) +libs: $(LIB_LIBENC) $(LIB_LIBDEBUG) $(LIB_LIBCOM) $(LIB_LIBDEC) $(LIB_LIBREND) $(LIB_LIBISAR) $(LIB_LC3PLUS) $(LIB_LIBUTIL) clean: $(QUIET)$(RM) $(OBJS_LIBENC) $(OBJS_LIBDEC) $(DEPS) $(QUIET)$(RM) $(DEPS:.P=.d) $(QUIET)test ! -d $(OBJDIR) || rm -rf $(OBJDIR) - $(QUIET)$(RM) $(CLI_APIENC) $(CLI_APIDEC) $(CLI_APIREND) $(LIB_LIBENC) $(LIB_LIBDEBUG) $(LIB_LIBCOM) $(LIB_LIBDEC) $(LIB_LIBUTIL) $(LIB_LIBREND) $(LIB_LC3PLUS) + $(QUIET)$(RM) $(CLI_APIENC) $(CLI_APIDEC) $(CLI_APIREND) $(CLI_APIPOSTREND) $(LIB_LIBENC) $(LIB_LIBDEBUG) $(LIB_LIBCOM) $(LIB_LIBDEC) $(LIB_LIBUTIL) $(LIB_LIBREND) $(LIB_LIBISAR) $(LIB_LC3PLUS) $(OBJDIR)/%.o : %.c | $(OBJDIR) $(QUIET_CC)$(CC) $(CFLAGS) -c -MD -o $@ $< diff --git a/Workspace_msvc/Workspace_msvc.sln b/Workspace_msvc/Workspace_msvc.sln index f7a8d6f9e..5449368aa 100644 --- a/Workspace_msvc/Workspace_msvc.sln +++ b/Workspace_msvc/Workspace_msvc.sln @@ -20,13 +20,17 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "encoder", "encoder.vcxproj" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "renderer", "renderer.vcxproj", "{12B4C8A5-1E06-4E30-B443-D1F916F52B47}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LC3plus", "lib_lc3plus.vcxproj", "{95030B82-70CD-4C6B-84D4-61096035BEA2}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lib_lc3plus", "lib_lc3plus.vcxproj", "{95030B82-70CD-4C6B-84D4-61096035BEA2}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{51160D4C-55C9-4C16-A792-D94507225746}" ProjectSection(SolutionItems) = preProject ..\.clang-format = ..\.clang-format EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lib_isar", "lib_isar.vcxproj", "{869A305E-D99E-4C3A-BDB3-AA57ABCCE619}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "isar_post_rend", "isar_post_rend.vcxproj", "{12374ADC-0E5C-4FDD-B903-71D572413831}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 diff --git a/Workspace_msvc/decoder.vcxproj b/Workspace_msvc/decoder.vcxproj index e59992847..648f01e82 100644 --- a/Workspace_msvc/decoder.vcxproj +++ b/Workspace_msvc/decoder.vcxproj @@ -68,7 +68,7 @@ Disabled - ..\lib_dec;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) + ..\lib_dec;..\lib_com;..\lib_util;..\lib_debug;..\lib_isar;%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;WIN32;$(Macros);%(PreprocessorDefinitions) EnableFastChecks @@ -112,7 +112,7 @@ Neither false false - ..\lib_dec;..\lib_com;..\lib_util;..\lib_debug;%(AdditionalIncludeDirectories) + ..\lib_dec;..\lib_com;..\lib_util;..\lib_debug;..\lib_isar;%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) true @@ -155,6 +155,9 @@ {e822ddaf-0f5f-4cd0-a694-38ae69de74d3} false + + {869a305e-d99e-4c3a-bdb3-aa57abcce619} + {2fa8f384-0775-f3b7-f8c3-85209222fc70} false diff --git a/Workspace_msvc/isar_post_rend.vcxproj b/Workspace_msvc/isar_post_rend.vcxproj new file mode 100644 index 000000000..170ff2054 --- /dev/null +++ b/Workspace_msvc/isar_post_rend.vcxproj @@ -0,0 +1,177 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + isar_post_rend + {12374ADC-0E5C-4FDD-B903-71D572413831} + isar_post_rend + 10.0.17763.0 + + + + Application + v141 + false + MultiByte + + + Application + v141 + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + ..\ + .\Debug_$(ProjectName)\ + false + false + ISAR_post_rend + + + ..\ + .\Release_$(ProjectName)\ + false + false + ISAR_post_rend + + + + $(IntDir)$(ProjectName).tlb + + + + Disabled + ..\lib_com;..\lib_debug;..\lib_util;..\lib_isar;..\lib_lc3plus;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;WIN32;$(Macros);%(PreprocessorDefinitions) + + EnableFastChecks + MultiThreadedDebug + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + OldStyle + Default + %(DisableSpecificWarnings) + false + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + + $(OutDir)$(TargetName).exe + true + + true + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX86 + + + + + $(IntDir)$(ProjectName).tlb + + + + MaxSpeed + AnySuitable + false + Neither + false + false + ..\lib_com;..\lib_debug;..\lib_util;..\lib_isar;..\lib_lc3plus;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + Precise + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + + Default + %(DisableSpecificWarnings) + false + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + $(OutDir)$(TargetName).exe + true + + false + $(IntDir)$(ProjectName).pdb + Console + false + + MachineX86 + libcmtd.lib + + + + + + + + {54509728-928B-44D9-A118-A6F92F08B34F} + false + + + {869a305e-d99e-4c3a-bdb3-aa57abcce619} + + + {2FA8F384-0775-F3B7-F8C3-85209222FC70} + false + + + {39ec200d-7795-4ff8-b214-b24eda5526ae} + false + + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/lib_com.vcxproj b/Workspace_msvc/lib_com.vcxproj index cdf577df2..9d0563c1e 100644 --- a/Workspace_msvc/lib_com.vcxproj +++ b/Workspace_msvc/lib_com.vcxproj @@ -59,7 +59,7 @@ Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_lc3plus;%(AdditionalIncludeDirectories) + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_isar;..\lib_lc3plus;%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) EnableFastChecks @@ -94,7 +94,7 @@ Neither false false - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_lc3plus;%(AdditionalIncludeDirectories) + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_isar;..\lib_rend;..\lib_lc3plus;%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) true @@ -203,6 +203,7 @@ + @@ -219,6 +220,8 @@ + + diff --git a/Workspace_msvc/lib_dec.vcxproj b/Workspace_msvc/lib_dec.vcxproj index 662502a1a..59758d289 100644 --- a/Workspace_msvc/lib_dec.vcxproj +++ b/Workspace_msvc/lib_dec.vcxproj @@ -68,7 +68,7 @@ Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_lc3plus;%(AdditionalIncludeDirectories) + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_isar;..\lib_rend;..\lib_lc3plus;%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) EnableFastChecks @@ -108,7 +108,7 @@ Neither false false - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_lc3plus;%(AdditionalIncludeDirectories) + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_isar;..\lib_rend;..\lib_lc3plus;%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) true diff --git a/Workspace_msvc/lib_enc.vcxproj b/Workspace_msvc/lib_enc.vcxproj index 6ef1fcabe..c5ddc83be 100644 --- a/Workspace_msvc/lib_enc.vcxproj +++ b/Workspace_msvc/lib_enc.vcxproj @@ -68,7 +68,7 @@ Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_lc3plus;%(AdditionalIncludeDirectories) + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_isar;..\lib_lc3plus;%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) EnableFastChecks @@ -111,7 +111,7 @@ Neither false false - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_lc3plus;%(AdditionalIncludeDirectories) + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_isar;..\lib_lc3plus;%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) true diff --git a/Workspace_msvc/lib_isar.vcxproj b/Workspace_msvc/lib_isar.vcxproj new file mode 100644 index 000000000..fceeb731c --- /dev/null +++ b/Workspace_msvc/lib_isar.vcxproj @@ -0,0 +1,200 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + lib_isar + {869A305E-D99E-4C3A-BDB3-AA57ABCCE619} + evs_dec + 10.0.17763.0 + + + StaticLibrary + v141 + false + MultiByte + + + + StaticLibrary + v141 + false + MultiByte + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + .\Debug_$(ProjectName)\ + .\Debug_$(ProjectName)\ + false + false + libivasrend + + + .\Release_$(ProjectName)\ + .\Release_$(ProjectName)\ + false + false + libivasrend + + + + + + + .\Debug\$(ProjectName).tlb + + + + Disabled + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_isar;..\lib_lc3plus;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) + + EnableFastChecks + MultiThreadedDebug + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + OldStyle + Default + %(DisableSpecificWarnings) + false + + + _DEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + + + + $(IntDir)$(ProjectName).tlb + + + + MaxSpeed + AnySuitable + false + Neither + false + false + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_isar;..\lib_lc3plus;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) + true + + Default + MultiThreaded + true + false + + + $(IntDir)$(ProjectName).pdb + Level4 + true + + Default + %(DisableSpecificWarnings) + false + + + NDEBUG;%(PreprocessorDefinitions) + 0x0c0c + + + WS2_32.lib; %(AdditionalDependencies) + $(OutDir)$(TargetName).lib + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {39ec200d-7795-4ff8-b214-b24eda5526ae} + false + + + {54509728-928b-44d9-a118-a6f92f08b34f} + false + + + {95030B82-70CD-4C6B-84D4-61096035BEA2} + false + + + + + + + + + + + diff --git a/Workspace_msvc/lib_lc3plus.vcxproj b/Workspace_msvc/lib_lc3plus.vcxproj index 207b6903c..eb2a91d36 100644 --- a/Workspace_msvc/lib_lc3plus.vcxproj +++ b/Workspace_msvc/lib_lc3plus.vcxproj @@ -65,7 +65,7 @@ Level3 - ..\lib_com;%(AdditionalIncludeDirectories) + ..\lib_com;..\lib_debug;%(AdditionalIncludeDirectories) Disabled MultiThreadedDebug WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) @@ -83,7 +83,7 @@ Level3 - ..\lib_com;%(AdditionalIncludeDirectories) + ..\lib_com;..\lib_debug;%(AdditionalIncludeDirectories) MaxSpeed MultiThreaded true diff --git a/Workspace_msvc/lib_rend.vcxproj b/Workspace_msvc/lib_rend.vcxproj index f248ab541..3e90febe0 100644 --- a/Workspace_msvc/lib_rend.vcxproj +++ b/Workspace_msvc/lib_rend.vcxproj @@ -68,7 +68,7 @@ Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_lc3plus;%(AdditionalIncludeDirectories) + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_isar;..\lib_lc3plus;%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) EnableFastChecks @@ -108,7 +108,7 @@ Neither false false - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_lc3plus;%(AdditionalIncludeDirectories) + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_isar;..\lib_lc3plus;%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) true @@ -142,30 +142,11 @@ - - - - - - - - - - - - - - - - - - - @@ -196,8 +177,6 @@ - - @@ -205,9 +184,6 @@ - - - diff --git a/Workspace_msvc/lib_util.vcxproj b/Workspace_msvc/lib_util.vcxproj index 4b787f1d0..190ed5026 100644 --- a/Workspace_msvc/lib_util.vcxproj +++ b/Workspace_msvc/lib_util.vcxproj @@ -55,7 +55,7 @@ Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_util;..\lib_lc3plus;%(AdditionalIncludeDirectories) + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_isar;..\lib_rend;..\lib_util;..\lib_lc3plus;%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;$(Macros);ZLIB_WINAPI;%(PreprocessorDefinitions) false @@ -78,7 +78,7 @@ AnySuitable false false - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;..\lib_util;..\lib_lc3plus;%(AdditionalIncludeDirectories) + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_isar;..\lib_rend;..\lib_util;..\lib_lc3plus;%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;$(Macros);ZLIB_WINAPI;%(PreprocessorDefinitions) true diff --git a/Workspace_msvc/renderer.vcxproj b/Workspace_msvc/renderer.vcxproj index bf4a162d1..324c71373 100644 --- a/Workspace_msvc/renderer.vcxproj +++ b/Workspace_msvc/renderer.vcxproj @@ -65,7 +65,7 @@ Disabled - ..\lib_com;..\lib_debug;..\lib_util;..\lib_rend;..\lib_lc3plus;%(AdditionalIncludeDirectories) + ..\lib_com;..\lib_debug;..\lib_util;..\lib_isar;..\lib_rend;..\lib_lc3plus;%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;WIN32;$(Macros);%(PreprocessorDefinitions) EnableFastChecks @@ -109,7 +109,7 @@ Neither false false - ..\lib_com;..\lib_debug;..\lib_util;..\lib_rend;..\lib_lc3plus;%(AdditionalIncludeDirectories) + ..\lib_com;..\lib_debug;..\lib_util;..\lib_isar;..\lib_rend;..\lib_lc3plus;%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) true @@ -156,6 +156,9 @@ {E822DDAF-0F5F-4CD0-A694-38AE69DE74D3} false + + {869a305e-d99e-4c3a-bdb3-aa57abcce619} + {2FA8F384-0775-F3B7-F8C3-85209222FC70} false diff --git a/apps/decoder.c b/apps/decoder.c index 4d42bcbf3..23405b1ae 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -43,7 +43,9 @@ #include "masa_file_writer.h" #include "render_config_reader.h" #include "rotation_file_reader.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT #include "split_render_file_read_write.h" +#endif #ifdef VARIABLE_SPEED_DECODING #include "tsm_scale_file_reader.h" #include @@ -122,7 +124,9 @@ typedef struct float non_diegetic_pan_gain; bool renderConfigEnabled; char *renderConfigFilename; +#ifdef SPLIT_REND_WITH_HEAD_ROT char *outputMdFilename; +#endif IVAS_DEC_COMPLEXITY_LEVEL complexityLevel; bool tsmEnabled; IVAS_RENDER_FRAMESIZE renderFramesize; @@ -150,7 +154,11 @@ typedef struct static bool parseCmdlIVAS_dec( int16_t argc, char **argv, DecArguments *arg ); static void usage_dec( void ); -static ivas_error decodeG192( DecArguments arg, BS_READER_HANDLE hBsReader, RotFileReader *headRotReader, RotFileReader *externalOrientationFileReader, RotFileReader *refRotReader, Vector3PairFileReader *referenceVectorReader, uint8_t *splitRendBitsBuf, IVAS_DEC_HANDLE hIvasDec, int16_t *pcmBuf ); +#ifdef SPLIT_REND_WITH_HEAD_ROT +static ivas_error decodeG192( DecArguments arg, BS_READER_HANDLE hBsReader, RotFileReader *headRotReader, RotFileReader *externalOrientationFileReader, RotFileReader *refRotReader, Vector3PairFileReader *referenceVectorReader, ISAR_SPLIT_REND_BITS_DATA *splitRendBits, IVAS_DEC_HANDLE hIvasDec, int16_t *pcmBuf ); +#else +static ivas_error decodeG192( DecArguments arg, BS_READER_HANDLE hBsReader, RotFileReader *headRotReader, RotFileReader *externalOrientationFileReader, RotFileReader *refRotReader, Vector3PairFileReader *referenceVectorReader, IVAS_DEC_HANDLE hIvasDec, int16_t *pcmBuf ); +#endif static ivas_error decodeVoIP( DecArguments arg, BS_READER_HANDLE hBsReader, RotFileReader *headRotReader, RotFileReader *externalOrientationFileReader, RotFileReader *refRotReader, Vector3PairFileReader *referenceVectorReader, IVAS_DEC_HANDLE hIvasDec ); #ifdef DEBUGGING @@ -172,7 +180,10 @@ int main( bool mainFailed = true; /* Assume main failed until cleanup is reached without errors */ DecArguments arg; ivas_error error = IVAS_ERR_UNKNOWN; - uint8_t splitRendBitsBuf[IVAS_MAX_SPLIT_REND_BITS_BUFFER_SIZE_IN_BYTES]; +#ifdef SPLIT_REND_WITH_HEAD_ROT + ISAR_SPLIT_REND_BITS_DATA splitRendBits; + uint8_t splitRendBitsBuf[ISAR_MAX_SPLIT_REND_BITS_BUFFER_SIZE_IN_BYTES]; +#endif /* Any handles that require cleanup must be declared here and initialized to NULL */ IVAS_DEC_HANDLE hIvasDec = NULL; @@ -202,6 +213,10 @@ int main( reset_mem( USE_BYTES ); #endif +#ifdef SPLIT_REND_WITH_HEAD_ROT + splitRendBits.bits_buf = splitRendBitsBuf; +#endif + /*------------------------------------------------------------------------------------------* * Parse command-line arguments *------------------------------------------------------------------------------------------*/ @@ -248,6 +263,7 @@ int main( } } +#ifdef SPLIT_REND_WITH_HEAD_ROT if ( arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) { fprintf( stdout, "Output metadata file: %s\n", arg.outputWavFilename ); @@ -258,6 +274,7 @@ int main( fprintf( stdout, "Output metadata file: %s\n", arg.outputMdFilename ); } else +#endif { fprintf( stdout, "Output synthesis file: %s\n", arg.outputWavFilename ); } @@ -292,7 +309,9 @@ int main( { /* sanity check */ if ( arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB +#ifdef SPLIT_REND_WITH_HEAD_ROT && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM +#endif ) { fprintf( stderr, "\nError: Head-rotation file file cannot be used in this output configuration.\n\n" ); @@ -394,7 +413,10 @@ int main( { /* sanity check */ if ( arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB - && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM +#ifdef SPLIT_REND_WITH_HEAD_ROT + && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM && + arg.Opt_non_diegetic_pan == 0 +#endif ) { fprintf( stderr, "\nError: Renderer configuration file cannot be used in this output configuration.\n\n" ); @@ -431,13 +453,14 @@ int main( fprintf( stderr, "\nChanged render framesize, only 20ms are allowed for decoding to EXT!\n" ); } +#ifdef SPLIT_REND_WITH_HEAD_ROT /*------------------------------------------------------------------------------------------* * Configure Split rendering *------------------------------------------------------------------------------------------*/ + asked_frame_size = arg.renderFramesize; if ( arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) { - asked_frame_size = arg.renderFramesize; if ( ( error = IVAS_DEC_EnableSplitRendering( hIvasDec ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nConfigure failed: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); @@ -450,13 +473,9 @@ int main( goto cleanup; } - if ( arg.renderFramesize != asked_frame_size ) - { - fprintf( stderr, "\nChanged render framesize, only 20ms are allowed for split rendering!\n" ); - } - arg.enableHeadRotation = true; } +#endif /*------------------------------------------------------------------------------------------* * Configure VoIP mode @@ -585,36 +604,28 @@ int main( IVAS_RENDER_CONFIG_DATA renderConfig; /* sanity check */ +#ifdef SPLIT_REND_WITH_HEAD_ROT if ( arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB && - arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM && + arg.Opt_non_diegetic_pan == 0 ) { fprintf( stderr, "\nExternal Renderer Config is supported only when binaural output configurations is used as output OR when Split rendering mode is enabled. Exiting. \n" ); goto cleanup; } - - if ( ( error = IVAS_DEC_GetRenderConfig( hIvasDec, &renderConfig ) ) != IVAS_ERR_OK ) +#else + if ( arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR && arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) { - fprintf( stderr, "\nIVAS_DEC_GetRenderConfig failed: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); + fprintf( stderr, "\nExternal Renderer Config is supported only for binaural output configurations. Exiting. \n\n" ); goto cleanup; } +#endif - if ( arg.renderFramesize == IVAS_RENDER_FRAMESIZE_5MS && ( renderConfig.split_rend_config.poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE || - renderConfig.split_rend_config.dof == 0 ) ) - { -/*TODO : needs to be refined as this wont work with LCLD codec*/ - arg.renderFramesize = IVAS_RENDER_FRAMESIZE_5MS; - } - else - { - arg.renderFramesize = IVAS_RENDER_FRAMESIZE_20MS; - } - - if ( ( error = IVAS_DEC_SetRenderFramesize( hIvasDec, arg.renderFramesize ) ) != IVAS_ERR_OK ) + if ( ( error = IVAS_DEC_GetRenderConfig( hIvasDec, &renderConfig ) ) != IVAS_ERR_OK ) { - return error; + fprintf( stderr, "\nIVAS_DEC_GetRenderConfig failed: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); + goto cleanup; } - if ( RenderConfigReader_read( renderConfigReader, arg.renderConfigFilename, &renderConfig ) != IVAS_ERR_OK ) { fprintf( stderr, "Failed to read renderer configuration from file %s\n\n", arg.renderConfigFilename ); @@ -626,6 +637,32 @@ int main( fprintf( stderr, "Failed to get directivity patterns for one or more of IDs: %d %d %d %d\n\n", arg.directivityPatternId[0], arg.directivityPatternId[1], arg.directivityPatternId[2], arg.directivityPatternId[3] ); goto cleanup; } +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( ( arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || + arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) + { + if ( asked_frame_size != IVAS_RENDER_FRAMESIZE_20MS && + ( renderConfig.split_rend_config.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE || + renderConfig.split_rend_config.dof == 0 ) ) + { + arg.renderFramesize = asked_frame_size; + } + else + { + arg.renderFramesize = IVAS_RENDER_FRAMESIZE_20MS; + } + + if ( ( error = IVAS_DEC_SetRenderFramesize( hIvasDec, arg.renderFramesize ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( arg.renderFramesize != asked_frame_size ) + { + fprintf( stderr, "\nChanged render framesize, only 20ms are allowed for non-0dof split rendering!\n" ); + } + } +#endif if ( arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) { @@ -644,6 +681,13 @@ int main( } renderConfig.roomAcoustics.override = true; } +#ifdef SPLIT_REND_WITH_HEAD_ROT +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + /* ISAR frame size is set from command line, not renderer config file. + * This will be ignored if output format is not split rendering. */ + renderConfig.split_rend_config.isar_frame_size_ms = (int16_t) arg.renderFramesize /* given in number of 5ms subframes */ * 5; +#endif +#endif if ( ( error = IVAS_DEC_FeedRenderConfig( hIvasDec, renderConfig ) ) != IVAS_ERR_OK ) { @@ -757,7 +801,11 @@ int main( } else { - error = decodeG192( arg, hBsReader, headRotReader, externalOrientationFileReader, refRotReader, referenceVectorReader, splitRendBitsBuf, hIvasDec, pcmBuf ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + error = decodeG192( arg, hBsReader, headRotReader, externalOrientationFileReader, refRotReader, referenceVectorReader, &splitRendBits, hIvasDec, pcmBuf ); +#else + error = decodeG192( arg, hBsReader, headRotReader, externalOrientationFileReader, refRotReader, referenceVectorReader, hIvasDec, pcmBuf ); +#endif } if ( error == IVAS_ERR_OK || error == IVAS_ERR_END_OF_FILE ) @@ -910,6 +958,7 @@ static IVAS_AUDIO_CONFIG cmdline2config( { output_config = IVAS_AUDIO_CONFIG_BINAURAL; } +#ifdef SPLIT_REND_WITH_HEAD_ROT else if ( strcmp( argv_to_upper, "BINAURAL_SPLIT_CODED" ) == 0 ) { output_config = IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED; @@ -918,6 +967,7 @@ static IVAS_AUDIO_CONFIG cmdline2config( { output_config = IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM; } +#endif else if ( strcmp( argv_to_upper, "BINAURAL_ROOM_IR" ) == 0 ) { output_config = IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR; @@ -993,7 +1043,9 @@ static bool parseCmdlIVAS_dec( arg->renderConfigFilename = NULL; arg->Opt_dpid_on = 0; +#ifdef SPLIT_REND_WITH_HEAD_ROT arg->outputMdFilename = NULL; +#endif arg->inputFormat = IVAS_DEC_INPUT_FORMAT_G192; arg->Opt_non_diegetic_pan = 0; @@ -1317,6 +1369,7 @@ static bool parseCmdlIVAS_dec( } i += 2; } +#ifdef SPLIT_REND_WITH_HEAD_ROT else if ( strcmp( argv_to_upper, "-OM" ) == 0 ) { arg->outputMdFilename = argv[i + 1]; @@ -1328,6 +1381,7 @@ static bool parseCmdlIVAS_dec( } i += 2; } +#endif else if ( strcmp( argv_to_upper, "-NON_DIEGETIC_PAN" ) == 0 ) { i++; @@ -1469,6 +1523,13 @@ static bool parseCmdlIVAS_dec( usage_dec(); return false; } + + if ( arg->outputMdFilename != NULL && arg->outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { + fprintf( stderr, "Error: Output split rendering metadata file is supported for BINAURAL_SPLIT_PCM output config. only\n\n" ); + usage_dec(); + return false; + } } else { @@ -1545,8 +1606,13 @@ static void usage_dec( void ) fprintf( stdout, "Mandatory parameters:\n" ); fprintf( stdout, "---------------------\n" ); +#ifdef SPLIT_REND_WITH_HEAD_ROT fprintf( stdout, "OutputConf : Output configuration: MONO, STEREO, 5_1, 7_1, 5_1_2, 5_1_4, 7_1_4, FOA,\n" ); fprintf( stdout, " HOA2, HOA3, BINAURAL, BINAURAL_ROOM_IR, BINAURAL_ROOM_REVERB, BINAURAL_SPLIT_CODED, BINAURAL_SPLIT_PCM, EXT\n" ); +#else + fprintf( stdout, "OutputConf : Output configuration: MONO, STEREO, 5_1, 7_1, 5_1_2, 5_1_4, 7_1_4, FOA,\n" ); + fprintf( stdout, " HOA2, HOA3, BINAURAL, BINAURAL_ROOM_IR, BINAURAL_ROOM_REVERB, EXT\n" ); +#endif fprintf( stdout, " By default, channel order and loudspeaker positions are equal to the\n" ); fprintf( stdout, " encoder. For loudspeaker outputs, OutputConf can be a custom loudspeaker\n" ); fprintf( stdout, " layout file. See readme.txt for details.\n" ); @@ -1592,7 +1658,9 @@ static void usage_dec( void ) fprintf( stdout, "-rvf File : Reference vector specified by external trajectory File\n" ); fprintf( stdout, " works only in combination with '-otr ref_vec' and 'ref_vec_lev' modes\n" ); fprintf( stdout, "-render_config File : Renderer configuration File\n" ); +#ifdef SPLIT_REND_WITH_HEAD_ROT fprintf( stdout, "-om File : Metadata output File for BINAURAL_SPLIT_PCM OutputConf (only for Fs = 48 kHz)\n" ); +#endif fprintf( stdout, "-non_diegetic_pan P : panning mono non-diegetic sound to stereo with paning P, -90<= P <=90,\n" ); fprintf( stdout, " left or l or 90->left, right or r or -90->right, center or c or 0->middle\n" ); #ifdef DEBUGGING @@ -1650,8 +1718,12 @@ static ivas_error initOnFirstGoodFrame( IVAS_DEC_HANDLE hIvasDec, /* i/o: */ const DecArguments arg, /* i : */ const int16_t numInitialBadFrames, /* i : */ +#ifdef SPLIT_REND_WITH_HEAD_ROT int16_t *numOutSamples, /* i/o: */ - int16_t *vec_pos_len, /* i/o: */ + int16_t *vec_pos_len, /* i/o: */ +#else + const uint16_t numOutSamples, /* i : */ +#endif int16_t *pFullDelayNumSamples, /* o : */ int16_t *pRemainingDelayNumSamples, /* o : */ int32_t *delayTimeScale, /* o : */ @@ -1660,8 +1732,12 @@ static ivas_error initOnFirstGoodFrame( MasaFileWriter **ppMasaWriter, /* o : */ IsmFileWriter *ismWriters[IVAS_MAX_NUM_OBJECTS], /* o : */ int16_t *pNumOutChannels, /* o : */ +#ifdef SPLIT_REND_WITH_HEAD_ROT uint16_t *pNumObj, /* o : */ SplitFileReadWrite **splitRendWriter +#else + uint16_t *pNumObj /* o : */ +#endif ) { ivas_error error = IVAS_ERR_UNKNOWN; @@ -1673,10 +1749,12 @@ static ivas_error initOnFirstGoodFrame( return error; } - if ( arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( IVAS_DEC_is_split_rendering_enabled( hIvasDec ) ) { pFullDelayNumSamples[0] = 0; } +#endif if ( !arg.delayCompensationEnabled ) { @@ -1698,11 +1776,19 @@ static ivas_error initOnFirstGoodFrame( return error; } - if ( arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( IVAS_DEC_is_split_rendering_enabled( hIvasDec ) ) { /* Open split rendering metadata writer */ int16_t delayNumSamples_temp[3]; int32_t delayTimeScale_temp; + ISAR_SPLIT_REND_CODEC splitRendCodec; + int16_t splitRendCodecFrameSizeMs; + ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrection; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + int16_t splitRendIsarFrameSizeMs; + int16_t lc3plusHighRes; +#endif if ( ( error = IVAS_DEC_GetDelay( hIvasDec, delayNumSamples_temp, &delayTimeScale_temp ) ) != IVAS_ERR_OK ) { @@ -1710,9 +1796,39 @@ static ivas_error initOnFirstGoodFrame( return error; } - if ( arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) + if ( ( error = IVAS_DEC_GetSplitRendBitstreamHeader( hIvasDec, + &splitRendCodec, + &poseCorrection, +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + &splitRendIsarFrameSizeMs, +#endif + &splitRendCodecFrameSizeMs +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + , + &lc3plusHighRes +#endif + ) ) != IVAS_ERR_OK ) { - if ( ( error = split_rend_writer_open( splitRendWriter, arg.outputWavFilename, delayNumSamples_temp[0], delayTimeScale_temp ) ) != IVAS_ERR_OK ) + fprintf( stderr, "\nUnable to get split renderer bitstream header: %s\n", ivas_error_to_string( error ) ); + return error; + } + + if ( IVAS_DEC_is_split_rendering_coded_out( hIvasDec ) ) + { + if ( ( error = split_rend_writer_open( splitRendWriter, + arg.outputWavFilename, + delayNumSamples_temp[0], + delayTimeScale_temp, + splitRendCodec, + poseCorrection, + splitRendCodecFrameSizeMs +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + , + splitRendIsarFrameSizeMs, + arg.output_Fs, + lc3plusHighRes +#endif + ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nUnable to open output split rendering metadata file %s\n", arg.outputWavFilename ); return error; @@ -1720,7 +1836,26 @@ static ivas_error initOnFirstGoodFrame( } else { - if ( ( error = split_rend_writer_open( splitRendWriter, arg.outputMdFilename, delayNumSamples_temp[0], delayTimeScale_temp ) ) != IVAS_ERR_OK ) + if ( arg.outputMdFilename == NULL ) + { + fprintf( stderr, "\nOutput split rendering metadata file not specified\n" ); + return IVAS_ERR_INVALID_SPLIT_REND_CONFIG; + } + + if ( ( error = split_rend_writer_open( splitRendWriter, + arg.outputMdFilename, + delayNumSamples_temp[0], + delayTimeScale_temp, + splitRendCodec, + poseCorrection, + splitRendCodecFrameSizeMs +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + , + splitRendIsarFrameSizeMs, + arg.output_Fs, + lc3plusHighRes +#endif + ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nUnable to open output split rendering metadata file %s\n", arg.outputWavFilename ); return error; @@ -1728,33 +1863,42 @@ static ivas_error initOnFirstGoodFrame( } } - if ( arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) + if ( IVAS_DEC_is_split_rendering_coded_out( hIvasDec ) == 0 ) { +#endif /* Open audio writer and write all previously skipped bad frames now that frame size is known */ if ( ( error = AudioFileWriter_open( ppAfWriter, arg.outputWavFilename, arg.output_Fs, *pNumOutChannels ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nUnable to open output file %s\n", arg.outputWavFilename ); return error; } +#ifdef SPLIT_REND_WITH_HEAD_ROT } +#endif int16_t *zeroBuf = malloc( pcmFrameSize * sizeof( int16_t ) ); memset( zeroBuf, 0, pcmFrameSize * sizeof( int16_t ) ); for ( int16_t i = 0; i < numInitialBadFrames; ++i ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT if ( *splitRendWriter != NULL ) { - IVAS_SPLIT_REND_BITS_DATA splitRendBitsZero; + ISAR_SPLIT_REND_BITS_DATA splitRendBitsZero; splitRendBitsZero.bits_buf = NULL; splitRendBitsZero.bits_read = 0; splitRendBitsZero.bits_written = 0; splitRendBitsZero.buf_len = 0; - splitRendBitsZero.codec = IVAS_SPLIT_REND_CODEC_DEFAULT; - splitRendBitsZero.pose_correction = IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE; + splitRendBitsZero.codec = ISAR_SPLIT_REND_CODEC_DEFAULT; + splitRendBitsZero.pose_correction = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + splitRendBitsZero.codec_frame_size_ms = 0; + splitRendBitsZero.isar_frame_size_ms = 20; +#else splitRendBitsZero.codec_frame_size_ms = 20; +#endif - if ( split_rend_write_bitstream_to_file( *splitRendWriter, splitRendBitsZero.bits_buf, &splitRendBitsZero.bits_read, &splitRendBitsZero.bits_written, -1, IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE, splitRendBitsZero.codec_frame_size_ms ) != IVAS_ERR_OK ) + if ( split_rend_write_bitstream_to_file( *splitRendWriter, splitRendBitsZero.bits_buf, &splitRendBitsZero.bits_read, &splitRendBitsZero.bits_written ) != IVAS_ERR_OK ) { fprintf( stderr, "\nUnable to write to bitstream file!\n" ); return error; @@ -1762,10 +1906,19 @@ static ivas_error initOnFirstGoodFrame( } else { +#endif +#ifdef SPLIT_REND_WITH_HEAD_ROT if ( *pRemainingDelayNumSamples < *numOutSamples ) +#else + if ( *pRemainingDelayNumSamples < numOutSamples ) +#endif { +#ifdef SPLIT_REND_WITH_HEAD_ROT if ( ( error = AudioFileWriter_write( *ppAfWriter, zeroBuf, *numOutSamples * *pNumOutChannels - ( *pRemainingDelayNumSamples * *pNumOutChannels ) ) ) != IVAS_ERR_OK ) +#else + if ( ( error = AudioFileWriter_write( *ppAfWriter, zeroBuf, numOutSamples * *pNumOutChannels - ( *pRemainingDelayNumSamples * *pNumOutChannels ) ) ) != IVAS_ERR_OK ) +#endif { fprintf( stderr, "\nOutput audio file writer error\n" ); return error; @@ -1774,9 +1927,15 @@ static ivas_error initOnFirstGoodFrame( } else { +#ifdef SPLIT_REND_WITH_HEAD_ROT *pRemainingDelayNumSamples -= *numOutSamples; +#else + *pRemainingDelayNumSamples -= numOutSamples; +#endif } +#ifdef SPLIT_REND_WITH_HEAD_ROT } +#endif } free( zeroBuf ); @@ -1843,6 +2002,7 @@ static ivas_error initOnFirstGoodFrame( { /* Duplicate good first frame metadata to fill the beginning of stream. */ IVAS_MASA_DECODER_EXT_OUT_META_HANDLE hMasaExtOutMeta = NULL; + if ( ( error = IVAS_DEC_GetMasaMetadata( hIvasDec, &hMasaExtOutMeta, 0 ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nError in IVAS_DEC_GetMasaMetadata: %s\n", IVAS_DEC_GetErrorMessage( error ) ); @@ -1861,6 +2021,7 @@ static ivas_error initOnFirstGoodFrame( } } +#ifdef SPLIT_REND_WITH_HEAD_ROT if ( *splitRendWriter != NULL ) { if ( numOutSamples == NULL || vec_pos_len == NULL ) @@ -1880,6 +2041,7 @@ static ivas_error initOnFirstGoodFrame( return error; } } +#endif return IVAS_ERR_OK; } @@ -1898,7 +2060,9 @@ static ivas_error decodeG192( RotFileReader *externalOrientationFileReader, RotFileReader *refRotReader, Vector3PairFileReader *referenceVectorReader, - uint8_t *splitRendBitsBuf, +#ifdef SPLIT_REND_WITH_HEAD_ROT + ISAR_SPLIT_REND_BITS_DATA *splitRendBits, +#endif IVAS_DEC_HANDLE hIvasDec, int16_t *pcmBuf ) @@ -1934,7 +2098,9 @@ static ivas_error decodeG192( 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 } }; int16_t vec_pos_update, vec_pos_len; +#ifdef SPLIT_REND_WITH_HEAD_ROT SplitFileReadWrite *splitRendWriter = NULL; +#endif for ( i = 0; i < IVAS_MAX_NUM_OBJECTS; ++i ) { @@ -2069,6 +2235,7 @@ static ivas_error decodeG192( { IVAS_QUATERNION Quaternions[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES]; +#ifdef SPLIT_REND_WITH_HEAD_ROT if ( headRotReader == NULL ) { for ( i = 0; i < num_subframes; i++ ) @@ -2084,6 +2251,7 @@ static ivas_error decodeG192( } else { +#endif for ( i = 0; i < num_subframes; i++ ) { if ( ( error = HeadRotationFileReading( headRotReader, &Quaternions[i], &Pos[i] ) ) != IVAS_ERR_OK ) @@ -2092,11 +2260,17 @@ static ivas_error decodeG192( goto cleanup; } } +#ifdef SPLIT_REND_WITH_HEAD_ROT } +#endif for ( i = 0; i < num_subframes; i++ ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT if ( ( error = IVAS_DEC_FeedHeadTrackData( hIvasDec, Quaternions[i], Pos[i], i, DEFAULT_AXIS ) ) != IVAS_ERR_OK ) +#else + if ( ( error = IVAS_DEC_FeedHeadTrackData( hIvasDec, Quaternions[i], Pos[i], i ) ) != IVAS_ERR_OK ) +#endif { fprintf( stderr, "\nIVAS_DEC_FeedHeadTrackData failed: %s\n", IVAS_DEC_GetErrorMessage( error ) ); goto cleanup; @@ -2190,9 +2364,10 @@ static ivas_error decodeG192( } } - if ( arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( IVAS_DEC_is_split_rendering_enabled( hIvasDec ) ) { - if ( ( error = IVAS_DEC_GetSplitBinauralBitstream( hIvasDec, (void *) ( pcmBuf + nOutChannels * nSamplesRendered ), splitRendBitsBuf, &nSamplesRendered_loop, &needNewFrame ) ) != IVAS_ERR_OK ) + if ( ( error = IVAS_DEC_GetSplitBinauralBitstream( hIvasDec, (void *) ( pcmBuf + nOutChannels * nSamplesRendered ), splitRendBits, &nSamplesRendered_loop, &needNewFrame ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nError in IVAS_DEC_GetSplitBinauralBitstream: %s\n", IVAS_DEC_GetErrorMessage( error ) ); goto cleanup; @@ -2203,15 +2378,23 @@ static ivas_error decodeG192( } else { +#endif +#ifdef SPLIT_REND_WITH_HEAD_ROT if ( ( error = IVAS_DEC_GetSamples( hIvasDec, nSamplesToRender, IVAS_DEC_PCM_INT16, (void *) ( pcmBuf + nOutChannels * nSamplesRendered ), &nSamplesRendered_loop, &needNewFrame ) ) != IVAS_ERR_OK ) +#else + if ( ( error = IVAS_DEC_GetSamples( hIvasDec, nSamplesToRender, ( pcmBuf + nOutChannels * nSamplesRendered ), &nSamplesRendered_loop, &needNewFrame ) ) != IVAS_ERR_OK ) + +#endif { fprintf( stderr, "\nError in IVAS_DEC_GetSamples: %s\n", IVAS_DEC_GetErrorMessage( error ) ); goto cleanup; } nSamplesRendered += nSamplesRendered_loop; nSamplesToRender -= nSamplesRendered_loop; +#ifdef SPLIT_REND_WITH_HEAD_ROT } +#endif if ( needNewFrame ) { frame++; @@ -2226,7 +2409,6 @@ static ivas_error decodeG192( #endif } } - } while ( nSamplesRendered < nOutSamples && error == IVAS_ERR_OK ); if ( error == IVAS_ERR_END_OF_FILE ) @@ -2246,7 +2428,11 @@ static ivas_error decodeG192( /* Once good frame decoded, catch up */ if ( decodedGoodFrame ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT if ( ( error = initOnFirstGoodFrame( hIvasDec, arg, numInitialBadFrames, &nOutSamples, &vec_pos_len, delayNumSamples_orig, &delayNumSamples, &delayTimeScale, &bsFormat, &afWriter, &masaWriter, ismWriters, &nOutChannels, &numObj, &splitRendWriter ) ) != IVAS_ERR_OK ) +#else + if ( ( error = initOnFirstGoodFrame( hIvasDec, arg, numInitialBadFrames, nOutSamples, delayNumSamples_orig, &delayNumSamples, &delayTimeScale, &bsFormat, &afWriter, &masaWriter, ismWriters, &nOutChannels, &numObj ) ) != IVAS_ERR_OK ) +#endif { goto cleanup; } @@ -2260,25 +2446,19 @@ static ivas_error decodeG192( /* Write current frame */ if ( decodedGoodFrame ) { - if ( arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || arg.outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( IVAS_DEC_is_split_rendering_enabled( hIvasDec ) ) { - IVAS_SPLIT_REND_BITS_DATA splitRendBits; - - if ( ( error = IVAS_DEC_GetSplitRendBits( hIvasDec, &splitRendBits ) ) != IVAS_ERR_OK ) - { - fprintf( stderr, "\nError in IVAS_DEC_SplitRendBits: %s\n", IVAS_DEC_GetErrorMessage( error ) ); - goto cleanup; - } - - if ( split_rend_write_bitstream_to_file( splitRendWriter, splitRendBits.bits_buf, &splitRendBits.bits_read, &splitRendBits.bits_written, splitRendBits.codec, splitRendBits.pose_correction, splitRendBits.codec_frame_size_ms ) != IVAS_ERR_OK ) + if ( split_rend_write_bitstream_to_file( splitRendWriter, splitRendBits->bits_buf, &splitRendBits->bits_read, &splitRendBits->bits_written ) != IVAS_ERR_OK ) { fprintf( stderr, "\nUnable to write to bitstream file!\n" ); goto cleanup; } } - if ( arg.outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) + if ( IVAS_DEC_is_split_rendering_coded_out( hIvasDec ) == 0 ) { +#endif if ( delayNumSamples < nOutSamples ) { if ( ( error = AudioFileWriter_write( afWriter, &pcmBuf[delayNumSamples * nOutChannels], nOutSamples * nOutChannels - ( delayNumSamples * nOutChannels ) ) ) != IVAS_ERR_OK ) @@ -2292,7 +2472,9 @@ static ivas_error decodeG192( { delayNumSamples -= nOutSamples; } +#ifdef SPLIT_REND_WITH_HEAD_ROT } +#endif } /* Write ISm metadata to external file(s) */ @@ -2407,7 +2589,11 @@ static ivas_error decodeG192( goto cleanup; } +#ifdef SPLIT_REND_WITH_HEAD_ROT if ( ( error = IVAS_DEC_FeedHeadTrackData( hIvasDec, Quaternion, Pos[0], 0, DEFAULT_AXIS ) ) != IVAS_ERR_OK ) +#else + if ( ( error = IVAS_DEC_FeedHeadTrackData( hIvasDec, Quaternion, Pos[0], 0 ) ) != IVAS_ERR_OK ) +#endif { fprintf( stderr, "\nIVAS_DEC_FeedHeadTrackData failed: %s\n", IVAS_DEC_GetErrorMessage( error ) ); goto cleanup; @@ -2415,7 +2601,11 @@ static ivas_error decodeG192( } /* decode and get samples */ +#ifdef SPLIT_REND_WITH_HEAD_ROT if ( ( error = IVAS_DEC_Flush( hIvasDec, nOutSamples, IVAS_DEC_PCM_INT16, (void *) pcmBuf, &nSamplesFlushed ) ) != IVAS_ERR_OK ) +#else + if ( ( error = IVAS_DEC_Flush( hIvasDec, nOutSamples, pcmBuf, &nSamplesFlushed ) ) != IVAS_ERR_OK ) +#endif { fprintf( stderr, "\nError in IVAS_DEC_VoIP_Flush: %s\n", IVAS_DEC_GetErrorMessage( error ) ); goto cleanup; @@ -2525,14 +2715,18 @@ static ivas_error decodeG192( *------------------------------------------------------------------------------------------*/ memset( pcmBuf, 0, delayNumSamples_orig[0] * nOutChannels * sizeof( int16_t ) ); +#ifdef SPLIT_REND_WITH_HEAD_ROT if ( afWriter != NULL ) { +#endif if ( ( error = AudioFileWriter_write( afWriter, pcmBuf, delayNumSamples_orig[0] * nOutChannels ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nError writing output file: %s\n", ivas_error_to_string( error ) ); goto cleanup; } +#ifdef SPLIT_REND_WITH_HEAD_ROT } +#endif /*------------------------------------------------------------------------------------------* * Close files and deallocate resources @@ -2542,7 +2736,9 @@ static ivas_error decodeG192( cleanup: +#ifdef SPLIT_REND_WITH_HEAD_ROT split_rend_reader_writer_close( &splitRendWriter ); +#endif AudioFileWriter_close( &afWriter ); MasaFileWriter_close( &masaWriter ); #ifdef DEBUGGING @@ -2894,6 +3090,7 @@ static ivas_error decodeVoIP( { IVAS_QUATERNION Quaternions[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES]; +#ifdef SPLIT_REND_WITH_HEAD_ROT if ( headRotReader == NULL ) { for ( i = 0; i < num_subframes; i++ ) @@ -2909,6 +3106,7 @@ static ivas_error decodeVoIP( } else { +#endif for ( i = 0; i < num_subframes; i++ ) { if ( ( error = HeadRotationFileReading( headRotReader, &Quaternions[i], &Pos[i] ) ) != IVAS_ERR_OK ) @@ -2918,13 +3116,17 @@ static ivas_error decodeVoIP( goto cleanup; } } +#ifdef SPLIT_REND_WITH_HEAD_ROT } +#endif for ( i = 0; i < num_subframes; i++ ) { if ( ( error = IVAS_DEC_FeedHeadTrackData( hIvasDec, Quaternions[i], Pos[i], i +#ifdef SPLIT_REND_WITH_HEAD_ROT , DEFAULT_AXIS +#endif ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nIVAS_DEC_FeedHeadTrackData failed: %s\n", IVAS_DEC_GetErrorMessage( error ) ); @@ -3013,10 +3215,18 @@ static ivas_error decodeVoIP( /* decode and get samples */ +#ifdef SPLIT_REND_WITH_HEAD_ROT #ifdef SUPPORT_JBM_TRACEFILE if ( ( error = IVAS_DEC_VoIP_GetSamples( hIvasDec, nOutSamples, IVAS_DEC_PCM_INT16, (void *) pcmBuf, systemTime_ms, writeJbmTraceFileFrameWrapper, jbmTraceWriter ) ) != IVAS_ERR_OK ) #else if ( ( error = IVAS_DEC_VoIP_GetSamples( hIvasDec, nOutSamples, IVAS_DEC_PCM_INT16, (void *) pcmBuf, systemTime_ms ) ) != IVAS_ERR_OK ) +#endif +#else +#ifdef SUPPORT_JBM_TRACEFILE + if ( ( error = IVAS_DEC_VoIP_GetSamples( hIvasDec, nOutSamples, pcmBuf, systemTime_ms, writeJbmTraceFileFrameWrapper, jbmTraceWriter ) ) != IVAS_ERR_OK ) +#else + if ( ( error = IVAS_DEC_VoIP_GetSamples( hIvasDec, nOutSamples, pcmBuf, systemTime_ms ) ) != IVAS_ERR_OK ) +#endif #endif { fprintf( stderr, "\nError in IVAS_DEC_VoIP_GetSamples: %s\n", IVAS_DEC_GetErrorMessage( error ) ); @@ -3053,10 +3263,15 @@ static ivas_error decodeVoIP( /* Once good frame decoded, catch up */ if ( decodedGoodFrame ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT SplitFileReadWrite *splitRendWriter = NULL; if ( ( error = initOnFirstGoodFrame( hIvasDec, arg, numInitialBadFrames, &nOutSamples, NULL, delayNumSamples_orig, &delayNumSamples, &delayTimeScale, &bsFormat, &afWriter, &masaWriter, ismWriters, &nOutChannels, &numObj, &splitRendWriter ) ) != IVAS_ERR_OK ) +#else + if ( ( error = initOnFirstGoodFrame( hIvasDec, arg, numInitialBadFrames, nOutSamples, delayNumSamples_orig, &delayNumSamples, &delayTimeScale, + &bsFormat, &afWriter, &masaWriter, ismWriters, &nOutChannels, &numObj ) ) != IVAS_ERR_OK ) +#endif { goto cleanup; } diff --git a/apps/renderer.c b/apps/renderer.c index bfcd10f8a..0c30c6f69 100644 --- a/apps/renderer.c +++ b/apps/renderer.c @@ -45,8 +45,10 @@ #include "masa_file_writer.h" #include "render_config_reader.h" #include "rotation_file_reader.h" +#ifdef SPLIT_REND_WITH_HEAD_ROT #include "split_render_file_read_write.h" #include "split_rend_bfi_file_reader.h" +#endif #include "vector3_pair_file_reader.h" #ifdef DEBUGGING #include "debug.h" @@ -64,8 +66,6 @@ #define RENDERER_MAX_METADATA_LENGTH 8192 #define RENDERER_MAX_METADATA_LINE_LENGTH 1024 -#define SPLIT_REND_BITS_BUFF_SIZE ( ( ( ( (int32_t) IVAS_MAX_SPLIT_REND_BITRATE / IVAS_NUM_FRAMES_PER_SEC ) + 7 ) >> 3 ) + IVAS_SPLIT_REND_ADDITIONAL_BYTES_TO_READ ) - #define IVAS_MAX16B_FLT 32767.0f #define IVAS_MIN16B_FLT ( -32768.0f ) @@ -134,8 +134,6 @@ typedef struct IVAS_CUSTOM_LS_DATA inSetupCustom; RendererInput masaBuses[RENDERER_MAX_MASA_INPUTS]; uint16_t numMasaBuses; - RendererInput binBuses[RENDERER_MAX_BIN_INPUTS]; - uint16_t numBinBuses; } InputConfig; typedef struct @@ -154,9 +152,13 @@ typedef struct OutputConfig outConfig; char inMetadataFilePaths[RENDERER_MAX_ISM_INPUTS][RENDERER_MAX_CLI_ARG_LENGTH]; int16_t numInMetadataFiles; +#ifdef SPLIT_REND_WITH_HEAD_ROT char outMetadataFilePath[RENDERER_MAX_CLI_ARG_LENGTH]; +#endif char headRotationFilePath[RENDERER_MAX_CLI_ARG_LENGTH]; +#ifdef SPLIT_REND_WITH_HEAD_ROT char splitRendBFIFilePath[RENDERER_MAX_CLI_ARG_LENGTH]; +#endif char referenceVectorFilePath[RENDERER_MAX_CLI_ARG_LENGTH]; char referenceRotationFilePath[RENDERER_MAX_CLI_ARG_LENGTH]; char externalOrientationFilePath[RENDERER_MAX_CLI_ARG_LENGTH]; @@ -203,8 +205,10 @@ typedef enum CmdLnOptionId_inputMetadata, CmdLnOptionId_listFormats, CmdLnOptionId_inputGain, +#ifdef SPLIT_REND_WITH_HEAD_ROT CmdLnOptionId_outputMetadata, CmdLnOptionId_SplitRendBFIFile, +#endif CmdLnOptionId_referenceVectorFile, CmdLnOptionId_exteriorOrientationFile, CmdLnOptionId_framing, @@ -230,7 +234,11 @@ static const CmdLnParser_Option cliOptions[] = { .id = CmdLnOptionId_inputMetadata, .match = "input_metadata", .matchShort = "im", +#ifdef SPLIT_REND_WITH_HEAD_ROT .description = "Space-separated list of path to metadata files for ISM or MASA inputs or BINAURAL_SPLIT_PCM input mode", +#else + .description = "Space-separated list of path to metadata files for ISM or MASA inputs", +#endif }, { .id = CmdLnOptionId_outputFile, @@ -256,6 +264,7 @@ static const CmdLnParser_Option cliOptions[] = { .matchShort = "T", .description = "Head rotation trajectory file for simulation of head tracking (only for binaural outputs)", }, +#ifdef SPLIT_REND_WITH_HEAD_ROT { .id = CmdLnOptionId_outputMetadata, .match = "output_metadata", @@ -268,6 +277,7 @@ static const CmdLnParser_Option cliOptions[] = { .matchShort = "prbfi", .description = "Split rendering option: bfi file", }, +#endif { .id = CmdLnOptionId_refRotFile, .match = "reference_rotation_file", @@ -425,9 +435,15 @@ static void printSupportedAudioConfigs( void ); static IVAS_AUDIO_CONFIG parseAudioConfig( const char *configString ); +#ifdef SPLIT_REND_WITH_HEAD_ROT static void convertInputBuffer( const int16_t *intBuffer, const int16_t numIntSamplesPerChannel, const int16_t numFloatSamplesPerChannel, const int16_t numChannels, float *floatBuffer, const int16_t cldfb_in, IVAS_CLDFB_FILTER_BANK_HANDLE *cldfbAna ); static void convertOutputBuffer( const float *floatBuffer, const int16_t numSamplesPerChannel, const int16_t numChannels, int16_t *intBuffer, const int16_t cldfb_in, IVAS_CLDFB_FILTER_BANK_HANDLE *cldfbSyn ); +#else +static void convertInputBuffer( const int16_t *intBuffer, const int16_t numIntSamplesPerChannel, const int16_t numFloatSamplesPerChannel, const int16_t numChannels, float *floatBuffer ); + +static void convertOutputBuffer( const float *floatBuffer, const int16_t numSamplesPerChannel, const int16_t numChannels, int16_t *intBuffer ); +#endif /*------------------------------------------------------------------------------------------* @@ -454,9 +470,7 @@ static int16_t getTotalNumInChannels( IVAS_REND_InputId mcIds[RENDERER_MAX_MC_INPUTS], IVAS_REND_InputId ismIds[RENDERER_MAX_ISM_INPUTS], IVAS_REND_InputId sbaIds[RENDERER_MAX_SBA_INPUTS], - IVAS_REND_InputId masaIds[RENDERER_MAX_MASA_INPUTS], - IVAS_REND_InputId splitBinIds[RENDERER_MAX_BIN_INPUTS] -) + IVAS_REND_InputId masaIds[RENDERER_MAX_MASA_INPUTS] ) { int16_t totalNumInChannels = 0; int16_t i, numInputChannels; @@ -533,22 +547,6 @@ static int16_t getTotalNumInChannels( totalNumInChannels += numInputChannels; } - for ( i = 0; i < RENDERER_MAX_BIN_INPUTS; ++i ) - { - if ( splitBinIds[i] == 0 ) - { - /* Skip inactive inputs */ - continue; - } - - if ( ( error = IVAS_REND_GetInputNumChannels( hIvasRend, splitBinIds[i], &numInputChannels ) ) != IVAS_ERR_OK ) - { - fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); - exit( -1 ); - } - totalNumInChannels += numInputChannels; - } - return totalNumInChannels; } @@ -557,9 +555,7 @@ static void setupWithSingleFormatInput( CmdlnArgs args, char *audioFilePath, IsmPositionProvider *positionProvider, - MasaFileReader **masaReaders, - SplitFileReadWrite **hhSplitRendFileReadWrite -) + MasaFileReader **masaReaders ) { /* With single-format input, inputFilePath is the path to input audio file. */ strncpy( audioFilePath, args.inputFilePath, FILENAME_MAX - 1 ); @@ -606,20 +602,6 @@ static void setupWithSingleFormatInput( } } } - else if ( args.inConfig.numBinBuses != 0 ) - { - *hhSplitRendFileReadWrite = NULL; - if ( args.inConfig.binBuses[0].audioConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) - { - ivas_error error; - error = split_rend_reader_open( hhSplitRendFileReadWrite, args.inMetadataFilePaths[0] ); - if ( error != IVAS_ERR_OK ) - { - fprintf( stderr, "Could not open split rend metadata file %s\n", args.inMetadataFilePaths[0] ); - exit( -1 ); - } - } - } return; } @@ -632,14 +614,15 @@ static float dBToLin( } +#ifdef SPLIT_REND_WITH_HEAD_ROT static int16_t get_cldfb_in_flag( const IVAS_AUDIO_CONFIG audioConfig, - IVAS_RENDER_CONFIG_DATA *renderConfig ) + const IVAS_RENDER_CONFIG_DATA *renderConfig ) { int16_t cldfb_in_flag; cldfb_in_flag = 0; - if ( renderConfig->split_rend_config.rendererSelection == IVAS_SPLIT_REND_RENDERER_SELECTION_FASTCONV ) + if ( renderConfig->split_rend_config.rendererSelection == ISAR_SPLIT_REND_RENDERER_SELECTION_FASTCONV ) { #ifdef DEBUGGING cldfb_in_flag = 1; @@ -653,21 +636,6 @@ static int16_t get_cldfb_in_flag( return cldfb_in_flag; } - -static int16_t is_split_post_rend_mode( - CmdlnArgs *args ) -{ - int16_t flag; - - flag = 0; - if ( args->inConfig.numBinBuses > 0 && ( args->inConfig.binBuses[0].audioConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || args->inConfig.binBuses[0].audioConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) - { - flag = 1; - } - - return flag; -} - static int16_t is_split_pre_rend_mode( CmdlnArgs *args ) { @@ -681,6 +649,7 @@ static int16_t is_split_pre_rend_mode( return flag; } +#endif /*------------------------------------------------------------------------------------------* @@ -697,10 +666,12 @@ int main( RotFileReader *headRotReader = NULL; RotFileReader *externalOrientationFileReader = NULL; RotFileReader *referenceRotReader = NULL; +#ifdef SPLIT_REND_WITH_HEAD_ROT IVAS_CLDFB_FILTER_BANK_HANDLE cldfbAna[IVAS_MAX_INPUT_CHANNELS]; IVAS_CLDFB_FILTER_BANK_HANDLE cldfbSyn[IVAS_MAX_INPUT_CHANNELS]; int16_t cldfb_in_flag, CLDFBframeSize_smpls; SplitRendBFIFileReader *splitRendBFIReader = NULL; +#endif Vector3PairFileReader *referenceVectorReader = NULL; hrtfFileReader *hrtfFileReader = NULL; IsmPositionProvider *positionProvider; @@ -714,18 +685,24 @@ int main( AudioFileWriter *audioWriter; int32_t inBufferSize; int32_t outBufferSize; +#ifdef SPLIT_REND_WITH_HEAD_ROT int32_t bitsBufferSize; +#endif int16_t *inpInt16Buffer; float *inFloatBuffer; int16_t *outInt16Buffer; float *outFloatBuffer; - uint8_t *bitsBufferData; +#ifdef SPLIT_REND_WITH_HEAD_ROT + uint8_t *bitsBufferData = NULL; +#endif IVAS_REND_AudioBuffer inBuffer; IVAS_REND_AudioBuffer outBuffer; +#ifdef SPLIT_REND_WITH_HEAD_ROT IVAS_REND_BitstreamBuffer bitsBuffer; SplitFileReadWrite *hSplitRendFileReadWrite; int16_t delayNumSamples_temp; int32_t delayTimeScale_temp; +#endif int16_t numSamplesRead; int16_t delayNumSamples = -1; int16_t delayNumSamples_orig = 0; @@ -734,7 +711,6 @@ int main( int32_t delayTimeScale = 0; int16_t i, numChannels; ivas_error error = IVAS_ERR_OK; - bool splitBinNeedsNewFrame = true; #ifdef WMOPS reset_wmops(); @@ -747,7 +723,24 @@ int main( hMasaMetadata[i] = NULL; } +#ifdef SPLIT_REND_WITH_HEAD_ROT hSplitRendFileReadWrite = NULL; + CLDFBframeSize_smpls = 0; + cldfb_in_flag = 0; + bitsBuffer.bits = NULL; + bitsBuffer.config.bitsRead = 0; + bitsBuffer.config.bitsWritten = 0; + bitsBuffer.config.bufLenInBytes = 0; + bitsBuffer.config.codec = ISAR_SPLIT_REND_CODEC_DEFAULT; + bitsBuffer.config.poseCorrection = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + bitsBuffer.config.codec_frame_size_ms = 5; + bitsBuffer.config.isar_frame_size_ms = 20; + bitsBuffer.config.lc3plus_highres = 0; +#else + bitsBuffer.config.codec_frame_size_ms = 20; +#endif +#endif for ( i = 0; i < RENDERER_MAX_MC_INPUTS; ++i ) { lfeRoutingConfigs[i] = NULL; @@ -804,11 +797,13 @@ int main( } } +#ifdef SPLIT_REND_WITH_HEAD_ROT if ( !isEmptyString( args.splitRendBFIFilePath ) ) { convert_backslash( args.splitRendBFIFilePath ); SplitRendBFIFileReader_open( args.splitRendBFIFilePath, &splitRendBFIReader ); } +#endif if ( !isEmptyString( args.externalOrientationFilePath ) ) { if ( RotationFileReader_open( args.externalOrientationFilePath, &externalOrientationFileReader ) != IVAS_ERR_OK ) @@ -845,7 +840,7 @@ int main( else { /* With single-format input, all information is given on command line. */ - setupWithSingleFormatInput( args, audioFilePath, positionProvider, masaReaders, &hSplitRendFileReadWrite ); + setupWithSingleFormatInput( args, audioFilePath, positionProvider, masaReaders ); } /* Check that there is allowed configuration for MASA format output */ @@ -866,36 +861,14 @@ int main( } } - /*if split renderer is running in post renderer mode*/ - if ( ( args.inConfig.numBinBuses > 0 ) && ( args.inConfig.binBuses[0].audioConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) ) - { - error = split_rend_reader_open( &hSplitRendFileReadWrite, args.inputFilePath ); - if ( error != IVAS_ERR_OK ) - { - fprintf( stderr, "Could not open split rend metadata file %s\n", args.inputFilePath ); - exit( -1 ); - } - audioReader = NULL; - } - else + if ( AudioFileReader_open( &audioReader, audioFilePath ) != IVAS_ERR_OK ) { - if ( AudioFileReader_open( &audioReader, audioFilePath ) != IVAS_ERR_OK ) - { - fprintf( stderr, "Error opening file: %s\n", audioFilePath ); - exit( -1 ); - } + fprintf( stderr, "Error opening file: %s\n", audioFilePath ); + exit( -1 ); } int32_t inFileSampleRate = 0; - if ( audioReader != NULL ) - { - error = AudioFileReader_getSamplingRate( audioReader, &inFileSampleRate ); - } - else - { - inFileSampleRate = args.sampleRate; - } - + error = AudioFileReader_getSamplingRate( audioReader, &inFileSampleRate ); switch ( error ) { case IVAS_ERR_OK: @@ -924,15 +897,13 @@ int main( } int16_t inFileNumChannels = 0; - if ( audioReader != NULL ) + error = AudioFileReader_getNumChannels( audioReader, &inFileNumChannels ); + if ( error != IVAS_ERR_OK && error != IVAS_ERR_NUM_CHANNELS_UNKNOWN ) { - error = AudioFileReader_getNumChannels( audioReader, &inFileNumChannels ); - if ( error != IVAS_ERR_OK && error != IVAS_ERR_NUM_CHANNELS_UNKNOWN ) - { - fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); - exit( -1 ); - } + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); } + const int16_t frameSize_smpls = (int16_t) ( ( args.render_framesize ) * args.sampleRate * 5 / ( 1000 ) ); if ( ( error = IVAS_REND_Open( &hIvasRend, args.sampleRate, args.outConfig.audioConfig, args.nonDiegeticPan, args.nonDiegeticPanGain, (int16_t) args.render_framesize ) ) != IVAS_ERR_OK ) @@ -948,24 +919,33 @@ int main( exit( -1 ); } - CLDFBframeSize_smpls = 0; - cldfb_in_flag = 0; - if ( args.renderConfigFilePath[0] != '\0' ) { IVAS_RENDER_CONFIG_DATA renderConfig; /* sanity check */ +#ifdef SPLIT_REND_WITH_HEAD_ROT if ( ( args.outConfig.audioConfig != IVAS_AUDIO_CONFIG_BINAURAL ) && ( args.outConfig.audioConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) && ( args.outConfig.audioConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) && !is_split_pre_rend_mode( &args ) ) { fprintf( stderr, "\nExternal Renderer Config is supported only when binaural output configurations is used as output OR when Split pre-rendering mode is enabled. Exiting. \n" ); exit( -1 ); } +#else + if ( ( args.outConfig.audioConfig != IVAS_AUDIO_CONFIG_BINAURAL ) && ( args.outConfig.audioConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR ) && ( args.outConfig.audioConfig != IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ) + { + fprintf( stderr, "\nExternal Renderer Config is only supported for binaural output configurations. Exiting. \n" ); + exit( -1 ); + } +#endif if ( ( error = IVAS_REND_GetRenderConfig( hIvasRend, &renderConfig ) ) != IVAS_ERR_OK ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT fprintf( stderr, "\nIVAS_DEC_GetRenderConfig failed: %s\n", ivas_error_to_string( error ) ); +#else + fprintf( stderr, "\nIVAS_DEC_GetRenderConfig failed\n" ); +#endif exit( -1 ); } @@ -993,17 +973,28 @@ int main( renderConfig.roomAcoustics.override = 1; } +#ifdef SPLIT_REND_WITH_HEAD_ROT +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + /* ISAR frame size is set from command line, not renderer config file. + * This will be ignored if output format is not split rendering. */ + renderConfig.split_rend_config.isar_frame_size_ms = (int16_t) args.render_framesize /* given in number of 5ms subframes */ * 5; +#endif +#endif + if ( ( error = IVAS_REND_FeedRenderConfig( hIvasRend, renderConfig ) ) != IVAS_ERR_OK ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT fprintf( stderr, "\nIVAS_REND_FeedRenderConfig failed: %s\n", ivas_error_to_string( error ) ); +#else + fprintf( stderr, "\nIVAS_DEC_FeedRenderConfig failed\n" ); +#endif exit( -1 ); } - if ( !is_split_post_rend_mode( &args ) ) - { - CLDFBframeSize_smpls = frameSize_smpls * 2; - cldfb_in_flag = get_cldfb_in_flag( args.outConfig.audioConfig, &renderConfig ); - } +#ifdef SPLIT_REND_WITH_HEAD_ROT + CLDFBframeSize_smpls = frameSize_smpls * 2; + cldfb_in_flag = get_cldfb_in_flag( args.outConfig.audioConfig, &renderConfig ); +#endif } if ( ( error = IVAS_REND_SetOrientationTrackingMode( hIvasRend, args.orientation_tracking ) ) != IVAS_ERR_OK ) @@ -1065,7 +1056,6 @@ int main( IVAS_REND_InputId ismIds[RENDERER_MAX_ISM_INPUTS]; IVAS_REND_InputId sbaIds[RENDERER_MAX_SBA_INPUTS]; IVAS_REND_InputId masaIds[RENDERER_MAX_MASA_INPUTS]; - IVAS_REND_InputId splitBinIds[RENDERER_MAX_BIN_INPUTS]; for ( i = 0; i < RENDERER_MAX_MC_INPUTS; i++ ) { @@ -1083,10 +1073,6 @@ int main( { masaIds[i] = 0u; } - for ( i = 0; i < RENDERER_MAX_BIN_INPUTS; i++ ) - { - splitBinIds[i] = 0u; - } for ( i = 0; i < args.inConfig.numMultiChannelBuses; ++i ) { @@ -1204,21 +1190,6 @@ int main( } } - for ( i = 0; i < args.inConfig.numBinBuses; ++i ) - { - if ( ( error = IVAS_REND_AddInput( hIvasRend, args.inConfig.binBuses[i].audioConfig, &splitBinIds[i] ) ) != IVAS_ERR_OK ) - { - fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); - exit( -1 ); - } - - if ( ( error = IVAS_REND_SetInputGain( hIvasRend, splitBinIds[i], args.inputGainGlobal * dBToLin( args.inConfig.binBuses[i].gain_dB ) ) ) != IVAS_ERR_OK ) - { - fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); - exit( -1 ); - } - } - for ( i = 0; i < args.inConfig.numMasaBuses; ++i ) { if ( ( error = IVAS_REND_AddInput( hIvasRend, args.inConfig.masaBuses[i].audioConfig, &masaIds[i] ) ) != IVAS_ERR_OK ) @@ -1234,7 +1205,7 @@ int main( } } - const int16_t totalNumInChannels = getTotalNumInChannels( hIvasRend, mcIds, ismIds, sbaIds, masaIds, splitBinIds ); + const int16_t totalNumInChannels = getTotalNumInChannels( hIvasRend, mcIds, ismIds, sbaIds, masaIds ); if ( inFileNumChannels != 0 /* inFileNumChannels is 0 with raw PCM input */ && totalNumInChannels != inFileNumChannels ) { @@ -1257,6 +1228,7 @@ int main( exit( -1 ); } +#ifdef SPLIT_REND_WITH_HEAD_ROT if ( cldfb_in_flag ) { if ( ( error = IVAS_REND_openCldfb( cldfbAna, cldfbSyn, totalNumInChannels, numOutChannels, args.sampleRate ) ) != IVAS_ERR_OK ) @@ -1268,13 +1240,37 @@ int main( if ( args.outConfig.audioConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) { + + IVAS_REND_GetSplitRendBitstreamHeader( hIvasRend, + &bitsBuffer.config.codec, + &bitsBuffer.config.poseCorrection, + &bitsBuffer.config.codec_frame_size_ms +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + , + &bitsBuffer.config.isar_frame_size_ms +#endif + ); + if ( IVAS_REND_GetDelay( hIvasRend, &delayNumSamples_temp, &delayTimeScale_temp ) != IVAS_ERR_OK ) { fprintf( stderr, "\nUnable to get delay of renderer!\n" ); exit( -1 ); } - if ( ( error = split_rend_writer_open( &hSplitRendFileReadWrite, args.outputFilePath, delayNumSamples_temp, delayTimeScale_temp ) ) != IVAS_ERR_OK ) + if ( ( error = split_rend_writer_open( &hSplitRendFileReadWrite, + args.outputFilePath, + delayNumSamples_temp, + delayTimeScale_temp, + bitsBuffer.config.codec, + bitsBuffer.config.poseCorrection, + bitsBuffer.config.codec_frame_size_ms +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + , + bitsBuffer.config.isar_frame_size_ms, + args.sampleRate, + bitsBuffer.config.lc3plus_highres +#endif + ) ) != IVAS_ERR_OK ) { fprintf( stderr, "Could not open split rend metadata file %s\n", args.outputFilePath ); exit( -1 ); @@ -1285,30 +1281,58 @@ int main( { if ( args.outConfig.audioConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) { + + IVAS_REND_GetSplitRendBitstreamHeader( hIvasRend, + &bitsBuffer.config.codec, + &bitsBuffer.config.poseCorrection, + &bitsBuffer.config.codec_frame_size_ms +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + , + &bitsBuffer.config.isar_frame_size_ms +#endif + ); + if ( IVAS_REND_GetDelay( hIvasRend, &delayNumSamples_temp, &delayTimeScale_temp ) != IVAS_ERR_OK ) { fprintf( stderr, "\nUnable to get delay of renderer!\n" ); exit( -1 ); } - if ( ( error = split_rend_writer_open( &hSplitRendFileReadWrite, args.outMetadataFilePath, delayNumSamples_temp, delayTimeScale_temp ) ) != IVAS_ERR_OK ) + if ( ( error = split_rend_writer_open( &hSplitRendFileReadWrite, + args.outMetadataFilePath, + delayNumSamples_temp, + delayTimeScale_temp, + bitsBuffer.config.codec, + bitsBuffer.config.poseCorrection, + bitsBuffer.config.codec_frame_size_ms +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + , + bitsBuffer.config.isar_frame_size_ms, + args.sampleRate, + bitsBuffer.config.lc3plus_highres +#endif + ) ) != IVAS_ERR_OK ) { fprintf( stderr, "Could not open split rend metadata file %s\n", args.outMetadataFilePath ); exit( -1 ); } } +#endif if ( AudioFileWriter_open( &audioWriter, args.outputFilePath, args.sampleRate, numOutChannels ) != IVAS_ERR_OK ) { fprintf( stderr, "Failed to open file: %s\n", args.outputFilePath ); exit( -1 ); } +#ifdef SPLIT_REND_WITH_HEAD_ROT } +#endif inBufferSize = frameSize_smpls * totalNumInChannels; outBufferSize = frameSize_smpls * numOutChannels; inpInt16Buffer = malloc( inBufferSize * sizeof( int16_t ) ); +#ifdef SPLIT_REND_WITH_HEAD_ROT if ( cldfb_in_flag == 0 ) { inFloatBuffer = malloc( inBufferSize * sizeof( float ) ); @@ -1335,7 +1359,7 @@ int main( memset( outBuffer.data, 0, outBuffer.config.numSamplesPerChannel * outBuffer.config.numChannels * sizeof( float ) ); - if ( is_split_pre_rend_mode( &args ) || is_split_post_rend_mode( &args ) ) + if ( is_split_pre_rend_mode( &args ) ) { bitsBufferSize = SPLIT_REND_BITS_BUFF_SIZE; } @@ -1357,9 +1381,19 @@ int main( bitsBuffer.config.bitsRead = 0; bitsBuffer.config.bitsWritten = 0; bitsBuffer.config.bufLenInBytes = bitsBufferSize; - bitsBuffer.config.codec = IVAS_SPLIT_REND_CODEC_DEFAULT; - bitsBuffer.config.poseCorrection = IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE; - bitsBuffer.config.codec_frame_size_ms = 20; +#else + inFloatBuffer = malloc( inBufferSize * sizeof( float ) ); + outInt16Buffer = malloc( outBufferSize * sizeof( int16_t ) ); + outFloatBuffer = malloc( outBufferSize * sizeof( float ) ); + + inBuffer.config.numSamplesPerChannel = (int16_t) frameSize_smpls; + inBuffer.config.numChannels = (int16_t) totalNumInChannels; + inBuffer.data = inFloatBuffer; + + outBuffer.config.numSamplesPerChannel = (int16_t) frameSize_smpls; + outBuffer.config.numChannels = (int16_t) numOutChannels; + outBuffer.data = outFloatBuffer; +#endif #ifdef WMOPS reset_stack(); @@ -1385,45 +1419,25 @@ int main( const bool isCurrentFrameMultipleOf20ms = frame % ( 4 / args.render_framesize ) == 0; numSamplesRead = 0; - if ( ( hSplitRendFileReadWrite != NULL ) && is_split_post_rend_mode( &args ) && splitBinNeedsNewFrame ) + /* Read the input data */ + if ( ( error = AudioFileReader_read( audioReader, inpInt16Buffer, (int16_t) inBufferSize, &numSamplesRead ) ) != IVAS_ERR_OK ) { - ivas_error error_tmp; - numSamplesRead = (int16_t) inBufferSize; - error_tmp = split_rend_read_bits_from_file( hSplitRendFileReadWrite, bitsBuffer.bits, &bitsBuffer.config.bitsRead, &bitsBuffer.config.bitsWritten, - &bitsBuffer.config.codec, &bitsBuffer.config.poseCorrection, - &bitsBuffer.config.codec_frame_size_ms ); - if ( error_tmp != IVAS_ERR_OK ) - { - if ( error_tmp == IVAS_ERR_END_OF_FILE ) - { - numSamplesRead = 0; - } - else - { - fprintf( stderr, "\nUnable to read from bitstream file!\n" ); - exit( -1 ); - } - } - } - - if ( audioReader != NULL ) - { - /* Read the input data */ - if ( ( error = AudioFileReader_read( audioReader, inpInt16Buffer, (int16_t) inBufferSize, &numSamplesRead ) ) != IVAS_ERR_OK ) - { - fprintf( stderr, "\nError reading from file %s\n", audioFilePath ); - exit( -1 ); - } + fprintf( stderr, "\nError reading from file %s\n", audioFilePath ); + exit( -1 ); } - if ( numSamplesRead == 0 && splitBinNeedsNewFrame ) + if ( numSamplesRead == 0 ) { /* end of input data */ break; } /* Convert from int to float and from interleaved to packed */ +#ifdef SPLIT_REND_WITH_HEAD_ROT convertInputBuffer( inpInt16Buffer, numSamplesRead, inBuffer.config.numSamplesPerChannel, num_in_channels, inFloatBuffer, inBuffer.config.is_cldfb, cldfbAna ); +#else + convertInputBuffer( inpInt16Buffer, numSamplesRead, inBuffer.config.numSamplesPerChannel, num_in_channels, inFloatBuffer ); +#endif int16_t num_subframes, sf_idx; num_subframes = (int16_t) args.render_framesize; @@ -1481,7 +1495,11 @@ int main( exit( -1 ); } +#ifdef SPLIT_REND_WITH_HEAD_ROT if ( ( error = IVAS_REND_SetHeadRotation( hIvasRend, headRot, Pos, DEFAULT_AXIS, sf_idx ) ) != IVAS_ERR_OK ) +#else + if ( ( error = IVAS_REND_SetHeadRotation( hIvasRend, headRot, Pos, sf_idx ) ) != IVAS_ERR_OK ) +#endif { fprintf( stderr, "Error setting Head Rotation: %s\n", ivas_error_to_string( error ) ); exit( -1 ); @@ -1497,23 +1515,6 @@ int main( } } - /* Read from split renderer bfi file if specified */ - if ( splitRendBFIReader != NULL && splitBinNeedsNewFrame ) - { - int16_t bfi; - if ( ( error = SplitRendBFIFileReading( splitRendBFIReader, &bfi ) ) != IVAS_ERR_OK ) - { - fprintf( stderr, "Error in SplitRendBFIFileReading(): %s\n", ivas_error_to_string( error ) ); - exit( -1 ); - } - - if ( ( error = IVAS_REND_SetSplitRendBFI( hIvasRend, bfi ) ) != IVAS_ERR_OK ) - { - fprintf( stderr, "Error in IVAS_REND_SetSplitRendBFI(): %s\n", ivas_error_to_string( error ) ); - exit( -1 ); - } - } - /* Read from external orientation file if specified */ if ( externalOrientationFileReader != NULL ) { @@ -1654,41 +1655,8 @@ int main( } } - - for ( i = 0; i < args.inConfig.numBinBuses; ++i ) - { - if ( splitBinNeedsNewFrame ) - { - if ( ( error = IVAS_REND_GetInputNumChannels( hIvasRend, splitBinIds[i], &numChannels ) ) != IVAS_ERR_OK ) - { - fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); - exit( -1 ); - } - IVAS_REND_ReadOnlyAudioBuffer tmpBuffer = getReadOnlySubBuffer( inBuffer, (int16_t) args.inConfig.binBuses[i].inputChannelIndex, numChannels ); - - if ( ( error = IVAS_REND_FeedInputAudio( hIvasRend, splitBinIds[i], tmpBuffer ) ) != IVAS_ERR_OK ) - { - fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); - exit( -1 ); - } - - if ( ( error = IVAS_REND_FeedSplitBinauralBitstream( hIvasRend, splitBinIds[i], &bitsBuffer ) ) != IVAS_ERR_OK ) - { - fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); - exit( -1 ); - } - } - } - - if ( args.inConfig.numBinBuses != 0 ) - { - if ( ( error = IVAS_REND_GetSplitBinauralSamples( hIvasRend, outBuffer, &splitBinNeedsNewFrame ) ) != IVAS_ERR_OK ) - { - fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); - exit( -1 ); - } - } - else if ( args.outConfig.audioConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || args.outConfig.audioConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( args.outConfig.audioConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || args.outConfig.audioConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) { if ( ( error = IVAS_REND_GetSplitBinauralBitstream( hIvasRend, outBuffer, &bitsBuffer ) ) != IVAS_ERR_OK ) { @@ -1698,23 +1666,38 @@ int main( } else { +#endif if ( ( error = IVAS_REND_GetSamples( hIvasRend, outBuffer ) ) != IVAS_ERR_OK ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT fprintf( stderr, "Error %s\n", ivas_error_to_string( error ) ); +#else + fprintf( stderr, "Error in getting samples\n" ); +#endif exit( -1 ); } +#ifdef SPLIT_REND_WITH_HEAD_ROT } +#endif int16_t num_out_channels; num_out_channels = outBuffer.config.numChannels; /* Convert from float to int and from packed to interleaved. * Values in outFloatBuffer are guaranteed to be within range INT16_MIN:INT16_MAX */ +#ifdef SPLIT_REND_WITH_HEAD_ROT convertOutputBuffer( outFloatBuffer, outBuffer.config.numSamplesPerChannel, num_out_channels, outInt16Buffer, cldfb_in_flag, cldfbSyn ); +#else + convertOutputBuffer( outFloatBuffer, outBuffer.config.numSamplesPerChannel, num_out_channels, outInt16Buffer ); +#endif if ( delayNumSamples == -1 ) { +#ifdef SPLIT_REND_WITH_HEAD_ROT if ( args.delayCompensationEnabled && !is_split_pre_rend_mode( &args ) ) +#else + if ( args.delayCompensationEnabled ) +#endif { if ( IVAS_REND_GetDelay( hIvasRend, &delayNumSamples, &delayTimeScale ) != IVAS_ERR_OK ) { @@ -1722,13 +1705,6 @@ int main( exit( -1 ); } - if ( is_split_post_rend_mode( &args ) && ( hSplitRendFileReadWrite != NULL ) ) - { - 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_orig = delayNumSamples; } else @@ -1738,11 +1714,11 @@ int main( zeroPad = delayNumSamples; } +#ifdef SPLIT_REND_WITH_HEAD_ROT if ( is_split_pre_rend_mode( &args ) ) { - if ( split_rend_write_bitstream_to_file( hSplitRendFileReadWrite, bitsBuffer.bits, &bitsBuffer.config.bitsRead, &bitsBuffer.config.bitsWritten, - bitsBuffer.config.codec, bitsBuffer.config.poseCorrection, - bitsBuffer.config.codec_frame_size_ms ) != IVAS_ERR_OK ) + if ( split_rend_write_bitstream_to_file( hSplitRendFileReadWrite, bitsBuffer.bits, &bitsBuffer.config.bitsRead, + &bitsBuffer.config.bitsWritten ) != IVAS_ERR_OK ) { fprintf( stderr, "\nUnable to write to bitstream file!\n" ); exit( -1 ); @@ -1751,6 +1727,7 @@ int main( if ( audioWriter != NULL ) { +#endif if ( delayNumSamples * num_out_channels < outBufferSize ) { if ( AudioFileWriter_write( audioWriter, &outInt16Buffer[delayNumSamples * num_out_channels], outBufferSize - ( delayNumSamples * num_out_channels ) ) != IVAS_ERR_OK ) @@ -1764,10 +1741,12 @@ int main( { delayNumSamples -= (int16_t) ( outBufferSize / num_out_channels ); } +#ifdef SPLIT_REND_WITH_HEAD_ROT } bitsBuffer.config.bitsRead = 0; bitsBuffer.config.bitsWritten = 0; +#endif /* Write MASA metadata for MASA outputs */ if ( args.outConfig.audioConfig == IVAS_AUDIO_CONFIG_MASA1 || args.outConfig.audioConfig == IVAS_AUDIO_CONFIG_MASA2 ) @@ -1872,8 +1851,10 @@ int main( } /* add zeros at the end to have equal length of synthesized signals */ +#ifdef SPLIT_REND_WITH_HEAD_ROT if ( audioWriter != NULL ) { +#endif for ( zeroPadToWrite = zeroPad; zeroPadToWrite > frameSize_smpls; zeroPadToWrite -= frameSize_smpls ) { memset( outInt16Buffer, 0, outBufferSize * sizeof( int16_t ) ); @@ -1891,7 +1872,9 @@ int main( exit( -1 ); } zeroPadToWrite = 0; +#ifdef SPLIT_REND_WITH_HEAD_ROT } +#endif if ( args.inConfig.numAudioObjects != 0 && ( args.outConfig.audioConfig == IVAS_AUDIO_CONFIG_BINAURAL || args.outConfig.audioConfig == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB ) ) @@ -1923,21 +1906,29 @@ int main( free( inFloatBuffer ); free( outInt16Buffer ); free( outFloatBuffer ); + +cleanup: + +#ifdef SPLIT_REND_WITH_HEAD_ROT if ( bitsBufferData != NULL ) { free( bitsBufferData ); } +#endif for ( i = 0; i < RENDERER_MAX_MASA_INPUTS; ++i ) { MasaFileReader_close( &masaReaders[i] ); } +#ifdef SPLIT_REND_WITH_HEAD_ROT if ( cldfb_in_flag ) { IVAS_REND_closeCldfb( cldfbAna, cldfbSyn ); } split_rend_reader_writer_close( &hSplitRendFileReadWrite ); + SplitRendBFIFileReader_close( &splitRendBFIReader ); +#endif for ( i = 0; i < RENDERER_MAX_MC_INPUTS; ++i ) { @@ -1949,6 +1940,7 @@ int main( RotationFileReader_close( &headRotReader ); RotationFileReader_close( &externalOrientationFileReader ); RotationFileReader_close( &referenceRotReader ); + Vector3PairFileReader_close( &referenceVectorReader ); hrtfFileReader_close( &hrtfFileReader ); IVAS_REND_Close( &hIvasRend ); @@ -2013,7 +2005,6 @@ static bool parseInConfig( inConfig->numAmbisonicsBuses = 0; inConfig->numMultiChannelBuses = 0; inConfig->numMasaBuses = 0; - inConfig->numBinBuses = 0; /* First check if input is being set to scene description file - this is not covered by parseAudioConfig(). */ strncpy( charBuf, inFormatStr, sizeof( charBuf ) - 1 ); @@ -2051,13 +2042,6 @@ static bool parseInConfig( inConfig->ambisonicsBuses[0].inputChannelIndex = 0; inConfig->ambisonicsBuses[0].gain_dB = 0.0f; break; - case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED: - case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM: - inConfig->numBinBuses = 1; - inConfig->binBuses[0].audioConfig = audioConfig; - inConfig->binBuses[0].inputChannelIndex = 0; - inConfig->binBuses[0].gain_dB = 0.0f; - break; case IVAS_AUDIO_CONFIG_MASA1: case IVAS_AUDIO_CONFIG_MASA2: inConfig->numMasaBuses = 1; @@ -2248,8 +2232,13 @@ static bool parseOrientationTracking( static IVAS_AUDIO_CONFIG parseAudioConfig( const char *configString ) { +#ifndef SPLIT_REND_WITH_HEAD_ROT + char charBuf[21]; + charBuf[20] = '\0'; +#else char charBuf[25]; charBuf[24] = '\0'; +#endif strncpy( charBuf, configString, sizeof( charBuf ) - 1 ); charBuf[sizeof( charBuf ) - 1] = '\0'; @@ -2324,6 +2313,7 @@ static IVAS_AUDIO_CONFIG parseAudioConfig( { return IVAS_AUDIO_CONFIG_BINAURAL; } +#ifdef SPLIT_REND_WITH_HEAD_ROT if ( strcmp( charBuf, "BINAURAL_SPLIT_PCM" ) == 0 ) { return IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM; @@ -2332,6 +2322,7 @@ static IVAS_AUDIO_CONFIG parseAudioConfig( { return IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED; } +#endif if ( strcmp( charBuf, "BINAURAL_ROOM_IR" ) == 0 ) { return IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR; @@ -2407,8 +2398,7 @@ static bool checkRequiredArgs( const bool singleInputSpecified = args.inConfig.numAudioObjects != 0 || args.inConfig.numAmbisonicsBuses != 0 || args.inConfig.numMultiChannelBuses != 0 || - args.inConfig.numMasaBuses != 0 || - args.inConfig.numBinBuses != 0; + args.inConfig.numMasaBuses != 0; if ( !args.sceneDescriptionInput && !singleInputSpecified ) { @@ -2465,8 +2455,10 @@ static CmdlnArgs defaultArgs( args.numInMetadataFiles = 0; clearString( args.headRotationFilePath ); +#ifdef SPLIT_REND_WITH_HEAD_ROT clearString( args.outMetadataFilePath ); clearString( args.splitRendBFIFilePath ); +#endif clearString( args.referenceVectorFilePath ); clearString( args.referenceRotationFilePath ); clearString( args.customHrtfFilePath ); @@ -2559,6 +2551,7 @@ static void parseOption( assert( numOptionValues == 1 ); strncpy( args->headRotationFilePath, optionValues[0], RENDERER_MAX_CLI_ARG_LENGTH - 1 ); break; +#ifdef SPLIT_REND_WITH_HEAD_ROT case CmdLnOptionId_outputMetadata: assert( numOptionValues == 1 ); strncpy( args->outMetadataFilePath, optionValues[0], RENDERER_MAX_CLI_ARG_LENGTH - 1 ); @@ -2567,6 +2560,7 @@ static void parseOption( assert( numOptionValues == 1 ); strncpy( args->splitRendBFIFilePath, optionValues[0], RENDERER_MAX_CLI_ARG_LENGTH - 1 ); break; +#endif case CmdLnOptionId_referenceVectorFile: assert( numOptionValues == 1 ); strncpy( args->referenceVectorFilePath, optionValues[0], RENDERER_MAX_CLI_ARG_LENGTH - 1 ); @@ -3569,8 +3563,10 @@ static void printSupportedAudioConfigs( void ) "ISMx (input only)", "MASAx", "BINAURAL (output only)", +#ifdef SPLIT_REND_WITH_HEAD_ROT "BINAURAL_SPLIT_PCM", "BINAURAL_SPLIT_CODED", +#endif "BINAURAL_ROOM_IR (output only)", "BINAURAL_ROOM_REVERB (output only)", }; @@ -3667,15 +3663,20 @@ static void convertInputBuffer( const int16_t numIntSamplesPerChannel, const int16_t numFloatSamplesPerChannel, const int16_t numChannels, +#ifdef SPLIT_REND_WITH_HEAD_ROT float *floatBuffer, const int16_t cldfb_in_flag, IVAS_CLDFB_FILTER_BANK_HANDLE *cldfbAna +#else + float *floatBuffer +#endif ) { int16_t chnl, smpl, i; i = 0; +#ifdef SPLIT_REND_WITH_HEAD_ROT if ( cldfb_in_flag ) { int16_t slotIdx, numCldfbBands, numFloatPcmSamples; @@ -3716,6 +3717,7 @@ static void convertInputBuffer( } else { +#endif for ( smpl = 0; smpl < numFloatSamplesPerChannel; ++smpl ) { for ( chnl = 0; chnl < numChannels; ++chnl ) @@ -3732,7 +3734,9 @@ static void convertInputBuffer( ++i; } } +#ifdef SPLIT_REND_WITH_HEAD_ROT } +#endif return; } @@ -3748,9 +3752,13 @@ static void convertOutputBuffer( const float *floatBuffer, const int16_t numSamplesPerChannel, const int16_t numChannels, +#ifdef SPLIT_REND_WITH_HEAD_ROT int16_t *intBuffer, const int16_t cldfb_in_flag, IVAS_CLDFB_FILTER_BANK_HANDLE *cldfbSyn +#else + int16_t *intBuffer +#endif ) { int16_t chnl, smpl, i; @@ -3758,6 +3766,7 @@ static void convertOutputBuffer( i = 0; +#ifdef SPLIT_REND_WITH_HEAD_ROT if ( cldfb_in_flag ) { int16_t slotIdx, numCldfbBands, numPcmSamples, b; @@ -3806,6 +3815,7 @@ static void convertOutputBuffer( } else { +#endif for ( smpl = 0; smpl < numSamplesPerChannel; ++smpl ) { for ( chnl = 0; chnl < numChannels; ++chnl ) @@ -3825,7 +3835,9 @@ static void convertOutputBuffer( ++i; } } +#ifdef SPLIT_REND_WITH_HEAD_ROT } +#endif return; } diff --git a/lib_com/ivas_cnst.h b/lib_com/ivas_cnst.h index 1da90b5ac..4c1ada713 100644 --- a/lib_com/ivas_cnst.h +++ b/lib_com/ivas_cnst.h @@ -121,14 +121,6 @@ typedef enum RENDERER_OSBA_LS } RENDERER_TYPE; -#ifdef SPLIT_REND_WITH_HEAD_ROT -typedef enum -{ - PCM_INT16, - PCM_FLOAT32, - PCM_NOT_KNOW = 0xffff -} PCM_RESOLUTION; -#endif /*----------------------------------------------------------------------------------* * IVAS general constants @@ -1487,18 +1479,6 @@ typedef enum EFAP_DMX_INTENSITY } EFAP_VTX_DMX_TYPE; -#ifdef SPLIT_REND_WITH_HEAD_ROT -typedef enum -{ - ANY_YAW, - PITCH_ONLY, - ANY_ROLL, - PRED_ONLY, - PRED_ROLL_ONLY, - COM_GAIN_ONLY, - LR_GAIN_ONLY -} IVAS_SPLIT_REND_POSE_TYPE; -#endif #define VBAP_NUM_SEARCH_SECTORS 4 @@ -1541,65 +1521,6 @@ typedef enum #define HEADROT_SHMAT_DIM2 ( HEADROT_SHMAT_DIM * HEADROT_SHMAT_DIM ) -#ifdef SPLIT_REND_WITH_HEAD_ROT -/*----------------------------------------------------------------------------------* - * Split Binaural Rendering Constants - *----------------------------------------------------------------------------------*/ - -#ifdef SPLIT_REND_WITH_HEAD_ROT -#define CLDFB_PLC_XF 2 /* Length of cross-fade into first good frame after frame loss in CLDFB cols. */ -#endif - -#define SPLIT_REND_DECOR_ALPHA 0.25f - -#define SPLIT_REND_MAX_YAW_ONLY_POSES 2 -#define SPLIT_REND_MAX_PITCH_ONLY_POSES 2 -#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 SPLIT_REND_MAX_DOF 3 - -#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 -#define MAX_SPLIT_MD_SUBFRAMES 1 -#define COMPLEX_MD_BAND_THRESH MAX_SPLIT_REND_MD_BANDS -#define COMPLEX_MD_BAND_THRESH_LOW 5 - -#define IVAS_SPLIT_REND_NUM_QUANT_STRATS 4 -#define IVAS_SPLIT_REND_PRED_63QUANT_PNTS 63 -#define IVAS_SPLIT_REND_PRED_31QUANT_PNTS 31 -#define IVAS_SPLIT_REND_ROLL_PRED_QUANT_PNTS 31 -#define IVAS_SPLIT_REND_D_QUANT_PNTS 15 -#define IVAS_SPLIT_REND_PRED_MIN_VAL -1.4f -#define IVAS_SPLIT_REND_PRED_MAX_VAL 1.4f - -#define IVAS_SPLIT_REND_PITCH_G_MIN_VAL 0.5f -#define IVAS_SPLIT_REND_PITCH_G_MAX_VAL 1.5f -#define IVAS_SPLIT_REND_PITCH_G_QUANT_PNTS IVAS_SPLIT_REND_D_QUANT_PNTS -#define IVAS_SPLIT_REND_D_MIN_VAL 0.0f -#define IVAS_SPLIT_REND_D_MAX_VAL 1.0f - -#define IVAS_SPLIT_REND_PRED_ROLL_Q_STEP (( IVAS_SPLIT_REND_PRED_MAX_VAL - IVAS_SPLIT_REND_PRED_MIN_VAL ) / ( IVAS_SPLIT_REND_ROLL_PRED_QUANT_PNTS - 1 )) -#define IVAS_SPLIT_REND_PRED_ROLL_1BYQ_STEP (( IVAS_SPLIT_REND_ROLL_PRED_QUANT_PNTS - 1 )/( IVAS_SPLIT_REND_PRED_MAX_VAL - IVAS_SPLIT_REND_PRED_MIN_VAL )) -#define IVAS_SPLIT_REND_PRED31_Q_STEP (( IVAS_SPLIT_REND_PRED_MAX_VAL - IVAS_SPLIT_REND_PRED_MIN_VAL ) / ( IVAS_SPLIT_REND_PRED_31QUANT_PNTS - 1 )) -#define IVAS_SPLIT_REND_PRED31_1BYQ_STEP (( IVAS_SPLIT_REND_PRED_31QUANT_PNTS - 1 )/( IVAS_SPLIT_REND_PRED_MAX_VAL - IVAS_SPLIT_REND_PRED_MIN_VAL )) -#define IVAS_SPLIT_REND_PRED63_Q_STEP (( IVAS_SPLIT_REND_PRED_MAX_VAL - IVAS_SPLIT_REND_PRED_MIN_VAL ) / ( IVAS_SPLIT_REND_PRED_63QUANT_PNTS - 1 )) -#define IVAS_SPLIT_REND_PRED63_1BYQ_STEP (( IVAS_SPLIT_REND_PRED_63QUANT_PNTS - 1 )/( IVAS_SPLIT_REND_PRED_MAX_VAL - IVAS_SPLIT_REND_PRED_MIN_VAL )) - -#define IVAS_SPLIT_REND_D_Q_STEP (( IVAS_SPLIT_REND_D_MAX_VAL - IVAS_SPLIT_REND_D_MIN_VAL ) / ( IVAS_SPLIT_REND_D_QUANT_PNTS - 1 )) -#define IVAS_SPLIT_REND_D_1BYQ_STEP (( IVAS_SPLIT_REND_D_QUANT_PNTS - 1 )/( IVAS_SPLIT_REND_D_MAX_VAL - IVAS_SPLIT_REND_D_MIN_VAL )) -#define IVAS_SPLIT_REND_PITCH_G_Q_STEP (( IVAS_SPLIT_REND_PITCH_G_MAX_VAL - IVAS_SPLIT_REND_PITCH_G_MIN_VAL ) / ( IVAS_SPLIT_REND_PITCH_G_QUANT_PNTS - 1 )) -#define IVAS_SPLIT_REND_PITCH_G_1BYQ_STEP (( IVAS_SPLIT_REND_PITCH_G_QUANT_PNTS - 1 )/( IVAS_SPLIT_REND_PITCH_G_MAX_VAL - IVAS_SPLIT_REND_PITCH_G_MIN_VAL )) - -#define IVAS_SPLIT_REND_MAX_NUM_BYTES 4000 -#define IVAS_SPLIT_REND_HEAD_POSE_BITS 9 -#define IVAS_SPLIT_REND_DOF_BITS 2 -#define IVAS_SPLIT_REND_HQ_MODE_BITS 1 -#define IVAS_SPLIT_REND_ROT_AXIS_BITS 3 -#endif - - /*----------------------------------------------------------------------------------* * TD Binaural Object renderer *----------------------------------------------------------------------------------*/ @@ -1802,19 +1723,6 @@ typedef enum #define QUANT_STRAT_0 0 #define QUANT_STRAT_2 2 -#ifdef SPLIT_REND_WITH_HEAD_ROT -/*----------------------------------------------------------------------------------* - * Split rendering bitrate constants - *----------------------------------------------------------------------------------*/ - -#define SPLIT_REND_256k 256000 -#define SPLIT_REND_320k 320000 -#define SPLIT_REND_384k 384000 -#define SPLIT_REND_512k 512000 -#define SPLIT_REND_768k 768000 -#define SPLIT_REND_MAX_BRATE SPLIT_REND_768k - -#endif /*----------------------------------------------------------------------------------* * Limiter constants diff --git a/lib_com/ivas_error.h b/lib_com/ivas_error.h index ff803803f..08cae1d00 100644 --- a/lib_com/ivas_error.h +++ b/lib_com/ivas_error.h @@ -103,6 +103,12 @@ typedef enum * input data errors * *----------------------------------------*/ IVAS_ERR_INVALID_BITSTREAM = 0x2000, +#ifdef SPLIT_REND_WITH_HEAD_ROT +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + IVAS_ERR_UNEXPECTED_LC3PLUS_BITSTREAM, + IVAS_ERR_UNEXPECTED_LC3PLUS_BITSTREAM_CONFIG, +#endif +#endif /*----------------------------------------* * hardware errors * diff --git a/lib_rend/ivas_limiter.c b/lib_com/ivas_limiter.c similarity index 99% rename from lib_rend/ivas_limiter.c rename to lib_com/ivas_limiter.c index 0953e8a82..a4cf152df 100644 --- a/lib_rend/ivas_limiter.c +++ b/lib_com/ivas_limiter.c @@ -34,7 +34,7 @@ #include "options.h" #include #include "prot.h" -#include "ivas_prot_rend.h" +#include "ivas_prot.h" #include "wmc_auto.h" #include diff --git a/lib_rend/ivas_lc3plus_common.c b/lib_com/ivas_osba_com.c similarity index 76% rename from lib_rend/ivas_lc3plus_common.c rename to lib_com/ivas_osba_com.c index db33f9861..e3b997dc3 100644 --- a/lib_rend/ivas_lc3plus_common.c +++ b/lib_com/ivas_osba_com.c @@ -31,30 +31,39 @@ *******************************************************************************************************/ #include "options.h" -#include "ivas_lc3plus_common.h" -#include "ivas_error.h" -#include "lc3.h" - -#ifdef SPLIT_REND_WITH_HEAD_ROT -/*-----------------------------------------------------------------------------------------* - * Function IVAS_LC3PLUS_LC3plusErrToIvasErr() - * - * - *-----------------------------------------------------------------------------------------*/ - -ivas_error IVAS_LC3PLUS_LC3plusErrToIvasErr( - const LC3PLUS_Error lc3PlusError ) +#include "ivas_cnst.h" +#include "ivas_prot.h" +#include "prot.h" +#include "ivas_rom_com.h" +#ifdef DEBUGGING +#include "debug.h" +#endif + +/*! r : ISM format mode */ +ISM_MODE ivas_osba_ism_mode_select( + const int32_t ivas_total_brate, /* i : IVAS total bitrate */ + const int16_t nchan_ism /* i : number of input ISM's */ +) { - switch ( lc3PlusError ) + ISM_MODE ism_mode = ISM_MODE_NONE; + + switch ( nchan_ism ) { - case LC3PLUS_OK: - return IVAS_ERR_OK; - case LC3PLUS_BITRATE_ERROR: - return IVAS_ERR_LC3PLUS_INVALID_BITRATE; - default: + case 1: + if ( ivas_total_brate >= IVAS_96k ) + { + ism_mode = ISM_SBA_MODE_DISC; + } + break; + case 2: + case 3: + case 4: + if ( ivas_total_brate >= IVAS_128k ) + { + ism_mode = ISM_SBA_MODE_DISC; + } break; } - return IVAS_ERR_INTERNAL; + return ism_mode; } -#endif diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index 815b3aff4..6236012a7 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -42,6 +42,7 @@ #include "stat_com.h" #include "ivas_stat_enc.h" #include "ivas_stat_dec.h" +#include "ivas_stat_rend.h" #include "ivas_stat_com.h" #include "ivas_error_utils.h" @@ -5957,6 +5958,56 @@ int16_t ivas_get_num_bands_from_bw_idx( const int16_t bwidth /* i : audio bandwidth */ ); +void Euler2Quat( + const float yaw, /* i : yaw (x) */ + const float pitch, /* i : pitch (y) */ + const float roll, /* i : roll (z) */ + IVAS_QUATERNION *quat /* o : quaternion describing the rotation */ +); + +float deg2rad( + float degrees +); + +#ifdef SPLIT_REND_WITH_HEAD_ROT +void Quat2EulerDegree( + const IVAS_QUATERNION quat, /* i : quaternion describing the rotation */ + float *yaw, /* o : yaw */ + float *pitch, /* o : pitch */ + float *roll /* o : roll */ +); +#endif + +/*----------------------------------------------------------------------------------* + * Limiter prototypes + *----------------------------------------------------------------------------------*/ + +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( + IVAS_LIMITER_HANDLE* phLimiter /* i/o: pointer to limiter handle, can be NULL */ +); + +void ivas_limiter_dec +( + IVAS_LIMITER_HANDLE hLimiter, /* i/o: limiter struct handle */ + float *output[MAX_OUTPUT_CHANNELS], /* i/o: input/output buffer */ + const int16_t num_channels, /* i : number of channels to be processed */ + const int16_t output_frame, /* i : number of samples per channel in the buffer */ + const int16_t BER_detect /* i : BER detect flag */ +); + +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 */ + const float threshold, /* i : signal amplitude above which limiting starts to be applied */ + const int16_t BER_detect, /* i : BER detect flag */ + int16_t *strong_saturation_cnt /* i/o: counter of strong saturations (can be NULL) */ +); /* clang-format on */ diff --git a/lib_com/ivas_rotation_com.c b/lib_com/ivas_rotation_com.c new file mode 100644 index 000000000..eb9eb61c3 --- /dev/null +++ b/lib_com/ivas_rotation_com.c @@ -0,0 +1,137 @@ +/****************************************************************************************************** + + (C) 2022-2023 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. + +*******************************************************************************************************/ + +#include "ivas_cnst.h" +#include +#include +#include "options.h" +#include +#include "cnst.h" +#include "prot.h" +#include "ivas_prot.h" +#ifdef DEBUGGING +#include "debug.h" +#endif +#include "wmc_auto.h" + +/*------------------------------------------------------------------------- + * Euler2Quat() + * + * Calculate corresponding Quaternion from Euler angles in radians + *------------------------------------------------------------------------*/ + +void Euler2Quat( + const float yaw, /* i : yaw (x) */ + const float pitch, /* i : pitch (y) */ + const float roll, /* i : roll (z) */ + IVAS_QUATERNION *quat /* o : quaternion describing the rotation */ +) +{ + float cr = cosf( roll * 0.5f ); + float sr = sinf( roll * 0.5f ); + float cp = cosf( pitch * 0.5f ); + float sp = sinf( pitch * 0.5f ); + float cy = cosf( yaw * 0.5f ); + float sy = sinf( yaw * 0.5f ); + quat->w = cr * cp * cy + sr * sp * sy; + quat->x = sr * cp * cy - cr * sp * sy; + quat->y = sr * cp * sy + cr * sp * cy; + quat->z = cr * cp * sy - sr * sp * cy; + + return; +} + + +#ifdef SPLIT_REND_WITH_HEAD_ROT +/*------------------------------------------------------------------------- + * Quat2EulerDegree() + * + * Quaternion handling: calculate corresponding Euler angles in degrees + *------------------------------------------------------------------------*/ + +void Quat2EulerDegree( + const IVAS_QUATERNION quat, /* i : quaternion describing the rotation */ + float *yaw, /* o : yaw */ + float *pitch, /* o : pitch */ + float *roll /* o : roll */ +) +{ + 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; + } + 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 = quat.z; + *pitch = quat.y; + *roll = quat.x; + } + + return; +} +#endif + + +/*------------------------------------------------------------------------- + * deg2rad() + * + * Converts degrees to normalized radians + *------------------------------------------------------------------------*/ + +float deg2rad( + float degrees ) +{ + while ( degrees >= 180.0f ) + { + degrees = degrees - 360.0f; + } + while ( degrees <= -180.0f ) + { + degrees = degrees + 360.0f; + } + + return PI_OVER_180 * degrees; +} diff --git a/lib_com/options.h b/lib_com/options.h index 4b686bcf5..7ca7f7027 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -179,6 +179,8 @@ #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_POSE_CORRECTION_UNUSED_BITS /* clang-format on */ diff --git a/lib_dec/ivas_binRenderer_internal.c b/lib_dec/ivas_binRenderer_internal.c index 92de9041c..95d81f1aa 100644 --- a/lib_dec/ivas_binRenderer_internal.c +++ b/lib_dec/ivas_binRenderer_internal.c @@ -42,10 +42,6 @@ #include "ivas_rom_dec.h" #include "ivas_rom_com.h" #include "ivas_rom_binauralRenderer.h" -#ifdef SPLIT_REND_WITH_HEAD_ROT -#include "ivas_rom_dec.h" -#include "lib_rend.h" -#endif #ifdef DEBUGGING #include "debug.h" #endif @@ -1107,9 +1103,9 @@ ivas_error ivas_binRenderer_open( if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) { #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG - hBinRenderer->numPoses = st_ivas->hSplitBinRend.splitrend.multiBinPoseData.num_poses + 1; + hBinRenderer->numPoses = st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses + 1; #else - hBinRenderer->numPoses = st_ivas->hSplitBinRend.splitrend.multiBinPoseData.num_poses; + hBinRenderer->numPoses = st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses; #endif } else @@ -1535,6 +1531,7 @@ void ivas_binaural_add_LFE( { int16_t render_lfe, idx_lfe; float gain; + float lfe_tc[L_FRAME48k]; if ( st_ivas->hBinRenderer != NULL ) { @@ -1558,10 +1555,10 @@ void ivas_binaural_add_LFE( for ( idx_lfe = 0; idx_lfe < st_ivas->hIntSetup.num_lfe; idx_lfe++ ) { - v_multc( input_f[st_ivas->hIntSetup.index_lfe[idx_lfe]], gain, input_f[st_ivas->hIntSetup.index_lfe[idx_lfe]], output_frame ); + v_multc( input_f[st_ivas->hIntSetup.index_lfe[idx_lfe]], gain, lfe_tc, output_frame ); /* copy LFE to left and right channels */ - v_add( output_f[0], input_f[st_ivas->hIntSetup.index_lfe[idx_lfe]], output_f[0], output_frame ); - v_add( output_f[1], input_f[st_ivas->hIntSetup.index_lfe[idx_lfe]], output_f[1], output_frame ); + v_add( output_f[0], lfe_tc, output_f[0], output_frame ); + v_add( output_f[1], lfe_tc, output_f[1], output_frame ); } } @@ -1807,7 +1804,7 @@ void ivas_binaural_cldfb_sf( idx_in++; } -#ifdef SPLIT_REND_WITH_HEAD_ROT /* Erik: Nested, should be removed */ +#ifdef SPLIT_REND_WITH_HEAD_ROT if ( st_ivas->hSplitBinRend.hCldfbDataOut != NULL ) { for ( ch = 0; ch < ( st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe ); ch++ ) @@ -1820,7 +1817,6 @@ void ivas_binaural_cldfb_sf( #endif } #endif -======= } /* Implement binaural rendering */ @@ -1902,7 +1898,7 @@ void ivas_binRenderer( const MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, #endif COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i : combined head and external orientation handle*/ - const int16_t numTimeSlots, /* i : number of time slots to render */ + const int16_t numTimeSlots, /* i : number of time slots to render */ #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG HEAD_TRACK_DATA_HANDLE hPostRendHeadTrackData, #endif @@ -1920,6 +1916,8 @@ void ivas_binRenderer( int16_t chIdx, k; #ifdef SPLIT_REND_WITH_HEAD_ROT int16_t pos_idx, num_poses; + float RealBuffer_local[MAX_OUTPUT_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; + float ImagBuffer_local[MAX_OUTPUT_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; #endif push_wmops( "fastconv_binaural_rendering" ); @@ -1941,6 +1939,15 @@ void ivas_binRenderer( } } } + + for ( chIdx = 0; chIdx < hBinRenderer->hInputSetup->nchan_out_woLFE; chIdx++ ) + { + for ( k = 0; k < numTimeSlots; k++ ) + { + mvr2r( RealBuffer[chIdx][k], RealBuffer_local[chIdx][k], CLDFB_NO_CHANNELS_MAX ); + mvr2r( ImagBuffer[chIdx][k], ImagBuffer_local[chIdx][k], CLDFB_NO_CHANNELS_MAX ); + } + } #else for ( chIdx = 0; chIdx < BINAURAL_CHANNELS; chIdx++ ) { @@ -1987,7 +1994,6 @@ void ivas_binRenderer( #endif #ifdef SPLIT_REND_WITH_HEAD_ROT - /*TODO : move this to a separate function*/ if ( pMultiBinPoseData != NULL ) { if ( pMultiBinPoseData->num_poses > 1 ) @@ -1998,12 +2004,32 @@ void ivas_binRenderer( if ( hCombinedOrientationData && hBinRenderer->rotInCldfb ) { Quaternions_ref = &hCombinedOrientationData->Quaternions[0]; - Quaternions_rel.w = -3.0f; /*euler*/ - Quaternions_abs.w = -3.0f; /*euler*/ - Quat2EulerDegree( *Quaternions_ref, &Quaternions_abs.z, &Quaternions_abs.y, &Quaternions_abs.x ); /*order in Quat2Euler seems to be reversed ?*/ + Quaternions_rel.w = -3.0f; /*euler*/ + Quaternions_abs.w = -3.0f; + + if ( hCombinedOrientationData->shd_rot_max_order == 0 ) + { + /*HOA signal already rotated by DirAC*/ + Quaternions_abs.x = 0.0f; + Quaternions_abs.y = 0.0f; + Quaternions_abs.z = 0.0f; + } + else + { + /*euler*/ + Quat2EulerDegree( *Quaternions_ref, &Quaternions_abs.z, &Quaternions_abs.y, &Quaternions_abs.x ); /*order in Quat2Euler seems to be reversed ?*/ + } for ( pos_idx = 1; pos_idx < pMultiBinPoseData->num_poses; pos_idx++ ) { + for ( chIdx = 0; chIdx < hBinRenderer->hInputSetup->nchan_out_woLFE; chIdx++ ) + { + for ( k = 0; k < numTimeSlots; k++ ) + { + mvr2r( RealBuffer_local[chIdx][k], RealBuffer[chIdx][k], CLDFB_NO_CHANNELS_MAX ); + mvr2r( ImagBuffer_local[chIdx][k], ImagBuffer[chIdx][k], CLDFB_NO_CHANNELS_MAX ); + } + } Quaternions_rel.x = pMultiBinPoseData->relative_head_poses[pos_idx][0] - pMultiBinPoseData->relative_head_poses[pos_idx - 1][0]; Quaternions_rel.y = pMultiBinPoseData->relative_head_poses[pos_idx][1] - pMultiBinPoseData->relative_head_poses[pos_idx - 1][1]; Quaternions_rel.z = pMultiBinPoseData->relative_head_poses[pos_idx][2] - pMultiBinPoseData->relative_head_poses[pos_idx - 1][2]; @@ -2011,7 +2037,7 @@ void ivas_binRenderer( Quaternions_abs.y = Quaternions_abs.y + Quaternions_rel.y; Quaternions_abs.z = Quaternions_abs.z + Quaternions_rel.z; - QuatToRotMat( Quaternions_rel, Rmat_local ); + QuatToRotMat( Quaternions_abs, Rmat_local ); if ( hBinRenderer->hInputSetup->is_loudspeaker_setup ) { @@ -2024,27 +2050,6 @@ void ivas_binRenderer( ivas_binRenderer_filterModule( Cldfb_RealBuffer_Binaural[pos_idx], Cldfb_ImagBuffer_Binaural[pos_idx], RealBuffer, ImagBuffer, numTimeSlots, hBinRenderer, pos_idx ); } - -#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG - if ( hPostRendHeadTrackData != NULL ) - { - IVAS_QUATERNION *Quaternions_new1; - IVAS_QUATERNION Quaternions_new; - Quaternions_new1 = &hPostRendHeadTrackData->Quaternions[hPostRendHeadTrackData->num_quaternions++]; - Quaternions_new.w = -3.0f; /*euler*/ - Quat2EulerDegree( *Quaternions_new1, &Quaternions_new.z, &Quaternions_new.y, &Quaternions_new.x ); /*order in Quat2Euler seems to be reversed ?*/ - Quaternions_rel.x = Quaternions_new.x - Quaternions_abs.x; - Quaternions_rel.y = Quaternions_new.y - Quaternions_abs.y; - Quaternions_rel.z = Quaternions_new.z - Quaternions_abs.z; - Quaternions_abs.x = Quaternions_abs.x + Quaternions_rel.x; - Quaternions_abs.y = Quaternions_abs.y + Quaternions_rel.y; - Quaternions_abs.z = Quaternions_abs.z + Quaternions_rel.z; - - QuatToRotMat( Quaternions_rel, Rmat_local ); - rotateFrame_shd_cldfb( RealBuffer, ImagBuffer, Rmat_local, hBinRenderer->hInputSetup->nchan_out_woLFE, 3 ); - ivas_binRenderer_filterModule( Cldfb_RealBuffer_Binaural[num_poses], Cldfb_ImagBuffer_Binaural[num_poses], RealBuffer, ImagBuffer, numTimeSlots, hBinRenderer, num_poses ); - } -#endif } } } @@ -2142,7 +2147,7 @@ void ivas_rend_CldfbMultiBinRendProcess( if ( ( *pCombinedOrientationData ) != NULL ) { - if ( ( low_res_pre_rend_rot ) && ( pMultiBinPoseData->poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) ) + if ( ( low_res_pre_rend_rot ) && ( pMultiBinPoseData->poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) ) { ( *pCombinedOrientationData )->Quaternions[sf_idx] = ( *pCombinedOrientationData )->Quaternions[0]; for ( i = 0; i < 3; i++ ) diff --git a/lib_dec/ivas_dirac_dec.c b/lib_dec/ivas_dirac_dec.c index bdc5e1827..53223dd6b 100644 --- a/lib_dec/ivas_dirac_dec.c +++ b/lib_dec/ivas_dirac_dec.c @@ -765,6 +765,9 @@ ivas_error ivas_dirac_dec_config( int16_t need_parambin; int16_t dec_param_estim_old; int16_t dec_param_estim_new; +#ifdef SPLIT_REND_WITH_HEAD_ROT + int16_t num_poses, pos_idx; +#endif error = IVAS_ERR_OK; @@ -775,6 +778,14 @@ ivas_error ivas_dirac_dec_config( hodirac_flag = ivas_get_hodirac_flag( st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->sba_analysis_order ); dec_param_estim_old = ( dec_config_flag == DIRAC_RECONFIGURE ) ? st_ivas->hDirAC->hConfig->dec_param_estim : FALSE; +#ifdef SPLIT_REND_WITH_HEAD_ROT + num_poses = 1; + if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { + num_poses = st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses; + } +#endif + sparfoa_flag = 0; if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_FOA && st_ivas->ivas_format == SBA_FORMAT && !hodirac_flag ) { @@ -904,7 +915,7 @@ ivas_error ivas_dirac_dec_config( #ifdef SPLIT_REND_WITH_HEAD_ROT /* copy td-decorr flag to split renderer side rendereres */ - for ( int16_t pos_idx = 1; pos_idx < st_ivas->hSplitBinRend.splitrend.multiBinPoseData.num_poses; pos_idx++ ) + for ( pos_idx = 1; pos_idx < num_poses; pos_idx++ ) { st_ivas->hDiracDecBin[pos_idx]->useTdDecorr = st_ivas->hDiracDecBin[0]->useTdDecorr; } @@ -925,12 +936,13 @@ ivas_error ivas_dirac_dec_config( ivas_dirac_dec_get_frequency_axis( frequency_axis, st_ivas->hDecoderConfig->output_Fs, st_ivas->hSpatParamRendCom->num_freq_bands ); + if ( ( error = ivas_dirac_dec_decorr_open( #ifdef SPLIT_REND_WITH_HEAD_ROT - if ( ( error = ivas_dirac_dec_decorr_open( &( st_ivas->hDiracDecBin[0]->h_freq_domain_decorr_ap_params ), &( st_ivas->hDiracDecBin[0]->h_freq_domain_decorr_ap_state ), st_ivas->hSpatParamRendCom->num_freq_bands, BINAURAL_CHANNELS, BINAURAL_CHANNELS, + &( st_ivas->hDiracDecBin[0]->h_freq_domain_decorr_ap_params ), &( st_ivas->hDiracDecBin[0]->h_freq_domain_decorr_ap_state ), st_ivas->hSpatParamRendCom->num_freq_bands, BINAURAL_CHANNELS, BINAURAL_CHANNELS, #else - if ( ( error = ivas_dirac_dec_decorr_open( &( st_ivas->hDiracDecBin->h_freq_domain_decorr_ap_params ), &( st_ivas->hDiracDecBin->h_freq_domain_decorr_ap_state ), st_ivas->hSpatParamRendCom->num_freq_bands, BINAURAL_CHANNELS, BINAURAL_CHANNELS, + &( st_ivas->hDiracDecBin->h_freq_domain_decorr_ap_params ), &( st_ivas->hDiracDecBin->h_freq_domain_decorr_ap_state ), st_ivas->hSpatParamRendCom->num_freq_bands, BINAURAL_CHANNELS, BINAURAL_CHANNELS, #endif - DIRAC_SYNTHESIS_PSD_LS, frequency_axis, BINAURAL_CHANNELS, st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK ) + DIRAC_SYNTHESIS_PSD_LS, frequency_axis, BINAURAL_CHANNELS, st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK ) { return error; } @@ -938,7 +950,7 @@ ivas_error ivas_dirac_dec_config( } #ifdef SPLIT_REND_WITH_HEAD_ROT - for ( int16_t pos_idx = 0; pos_idx < st_ivas->hSplitBinRend.splitrend.multiBinPoseData.num_poses; pos_idx++ ) + for ( pos_idx = 0; pos_idx < num_poses; pos_idx++ ) { st_ivas->hDiracDecBin[pos_idx]->reqularizationFactor = configure_reqularization_factor( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate ); } @@ -2378,17 +2390,17 @@ void ivas_dirac_dec_render_sf( #ifdef SPLIT_REND_WITH_HEAD_ROT if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) { - if ( st_ivas->hSplitBinRend.hCldfbDataOut != NULL ) + if ( st_ivas->hSplitBinRend->hCldfbDataOut != NULL ) { for ( slot_idx = 0; slot_idx < hSpatParamRendCom->subframe_nbslots[subframe_idx]; slot_idx++ ) { for ( ch = 0; ch < st_ivas->hBinRenderer->nInChannels; ch++ ) { - mvr2r( Cldfb_RealBuffer[ch][slot_idx], st_ivas->hSplitBinRend.hCldfbDataOut->Cldfb_RealBuffer[ch][slot_idx_start + slot_idx], hSpatParamRendCom->num_freq_bands ); - mvr2r( Cldfb_ImagBuffer[ch][slot_idx], st_ivas->hSplitBinRend.hCldfbDataOut->Cldfb_ImagBuffer[ch][slot_idx_start + slot_idx], hSpatParamRendCom->num_freq_bands ); + mvr2r( Cldfb_RealBuffer[ch][slot_idx], st_ivas->hSplitBinRend->hCldfbDataOut->Cldfb_RealBuffer[ch][slot_idx_start + slot_idx], hSpatParamRendCom->num_freq_bands ); + mvr2r( Cldfb_ImagBuffer[ch][slot_idx], st_ivas->hSplitBinRend->hCldfbDataOut->Cldfb_ImagBuffer[ch][slot_idx_start + slot_idx], hSpatParamRendCom->num_freq_bands ); } } - st_ivas->hSplitBinRend.hCldfbDataOut->config = st_ivas->hIntSetup.output_config; + st_ivas->hSplitBinRend->hCldfbDataOut->config = st_ivas->hIntSetup.output_config; } } #endif @@ -2396,7 +2408,7 @@ void ivas_dirac_dec_render_sf( /* Perform binaural rendering */ ivas_binRenderer( st_ivas->hBinRenderer, #ifdef SPLIT_REND_WITH_HEAD_ROT - &st_ivas->hSplitBinRend.splitrend.multiBinPoseData, + ( st_ivas->hSplitBinRend == NULL ) ? NULL : &st_ivas->hSplitBinRend->splitrend.multiBinPoseData, #endif st_ivas->hCombinedOrientationData, @@ -2415,8 +2427,8 @@ void ivas_dirac_dec_render_sf( { for ( ch = 0; ch < st_ivas->hDecoderConfig->nchan_out; ch++ ) { - mvr2r( Cldfb_RealBuffer_Binaural[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend.hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[( pos_idx * BINAURAL_CHANNELS ) + ch][slot_idx_start + slot_idx], hSpatParamRendCom->num_freq_bands ); - mvr2r( Cldfb_ImagBuffer_Binaural[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend.hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[( pos_idx * BINAURAL_CHANNELS ) + ch][slot_idx_start + slot_idx], hSpatParamRendCom->num_freq_bands ); + mvr2r( Cldfb_RealBuffer_Binaural[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[( pos_idx * BINAURAL_CHANNELS ) + ch][slot_idx_start + slot_idx], hSpatParamRendCom->num_freq_bands ); + mvr2r( Cldfb_ImagBuffer_Binaural[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[( pos_idx * BINAURAL_CHANNELS ) + ch][slot_idx_start + slot_idx], hSpatParamRendCom->num_freq_bands ); } } } diff --git a/lib_dec/ivas_init_dec.c b/lib_dec/ivas_init_dec.c index dcf35207d..723249156 100644 --- a/lib_dec/ivas_init_dec.c +++ b/lib_dec/ivas_init_dec.c @@ -38,7 +38,9 @@ #include "ivas_stat_enc.h" #include "prot.h" #ifdef SPLIT_REND_WITH_HEAD_ROT -#include "common_api_types.h" +#include "lib_isar_pre_rend.h" +#include "isar_prot.h" +#include "isar_stat.h" #endif #include #include @@ -74,11 +76,8 @@ static ivas_error ivas_dec_reconfig_split_rend( ivas_error error; int16_t cldfb_in_flag, num_ch, ch, isCldfbNeeded, i, pcm_out_flag; SPLIT_REND_WRAPPER *hSplitRendWrapper; -#ifndef SPLIT_REND_WITH_HEAD_ROT - CLDFB_TYPE cldfbMode; -#endif - hSplitRendWrapper = &st_ivas->hSplitBinRend.splitrend; + hSplitRendWrapper = &st_ivas->hSplitBinRend->splitrend; pcm_out_flag = ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0; cldfb_in_flag = 0; @@ -90,42 +89,35 @@ static ivas_error ivas_dec_reconfig_split_rend( cldfb_in_flag = 1; } - ivas_renderSplitGetMultiBinPoseData( &st_ivas->hRenderConfig->split_rend_config, &hSplitRendWrapper->multiBinPoseData, st_ivas->hHeadTrackData->sr_pose_pred_axis ); + 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 ); isCldfbNeeded = 0; -#ifndef SPLIT_REND_WITH_HEAD_ROT - cldfbMode = CLDFB_ANALYSIS; -#else - if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV && st_ivas->ivas_format == SBA_ISM_FORMAT ) + + if ( ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV && st_ivas->ivas_format == SBA_ISM_FORMAT ) || + ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC && st_ivas->ivas_format == MASA_ISM_FORMAT && st_ivas->ism_mode == ISM_MASA_MODE_DISC ) ) { cldfb_in_flag = 0; } -#endif if ( st_ivas->renderer_type != RENDERER_DISABLE ) { if ( cldfb_in_flag == 0 ) { isCldfbNeeded = 1; -#ifndef SPLIT_REND_WITH_HEAD_ROT - cldfbMode = CLDFB_ANALYSIS; -#endif } - else if ( st_ivas->hRenderConfig->split_rend_config.codec == IVAS_SPLIT_REND_CODEC_LC3PLUS && cldfb_in_flag ) + else if ( st_ivas->hRenderConfig->split_rend_config.codec == ISAR_SPLIT_REND_CODEC_LC3PLUS && cldfb_in_flag ) { isCldfbNeeded = 1; -#ifndef SPLIT_REND_WITH_HEAD_ROT - cldfbMode = CLDFB_SYNTHESIS; -#endif } else if ( pcm_out_flag && cldfb_in_flag ) { isCldfbNeeded = 1; -#ifndef SPLIT_REND_WITH_HEAD_ROT - cldfbMode = CLDFB_SYNTHESIS; -#endif } } + else if ( st_ivas->hDecoderConfig->Opt_non_diegetic_pan ) + { + isCldfbNeeded = 1; + } if ( isCldfbNeeded == 1 && hSplitRendWrapper->hCldfbHandles == NULL ) { @@ -144,18 +136,12 @@ static ivas_error ivas_dec_reconfig_split_rend( for ( ch = 0; ch < num_ch; ch++ ) { -#ifndef SPLIT_REND_WITH_HEAD_ROT - if ( ( error = openCldfb( &( hSplitRendWrapper->hCldfbHandles->cldfbAna[ch] ), cldfbMode, st_ivas->hDecoderConfig->output_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) -#else if ( ( error = openCldfb( &( hSplitRendWrapper->hCldfbHandles->cldfbAna[ch] ), CLDFB_ANALYSIS, st_ivas->hDecoderConfig->output_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) -#endif - { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not open CLDFB handles\n" ) ); } } -#ifdef SPLIT_REND_WITH_HEAD_ROT for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) { if ( ( error = openCldfb( &( hSplitRendWrapper->hCldfbHandles->cldfbSyn[ch] ), CLDFB_SYNTHESIS, st_ivas->hDecoderConfig->output_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) @@ -163,7 +149,6 @@ static ivas_error ivas_dec_reconfig_split_rend( return error; } } -#endif } else if ( isCldfbNeeded == 0 && hSplitRendWrapper->hCldfbHandles != NULL ) { @@ -177,7 +162,6 @@ static ivas_error ivas_dec_reconfig_split_rend( } } -#ifdef SPLIT_REND_WITH_HEAD_ROT for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) { if ( hSplitRendWrapper->hCldfbHandles->cldfbSyn[ch] != NULL ) @@ -186,25 +170,21 @@ static ivas_error ivas_dec_reconfig_split_rend( hSplitRendWrapper->hCldfbHandles->cldfbSyn[ch] = NULL; } } -#endif free( hSplitRendWrapper->hCldfbHandles ); hSplitRendWrapper->hCldfbHandles = NULL; } -#ifdef SPLIT_REND_WITH_HEAD_ROT if ( ( st_ivas->renderer_type != RENDERER_BINAURAL_OBJECTS_TD ) && - ( st_ivas->renderer_type != RENDERER_BINAURAL_FASTCONV || st_ivas->ivas_format != SBA_ISM_FORMAT ) ) -#else - if ( st_ivas->renderer_type != RENDERER_BINAURAL_OBJECTS_TD ) -#endif + ( st_ivas->renderer_type != RENDERER_BINAURAL_FASTCONV || st_ivas->ivas_format != SBA_ISM_FORMAT ) && + !( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC && st_ivas->ivas_format == MASA_ISM_FORMAT && st_ivas->ism_mode == ISM_MASA_MODE_DISC ) ) /* td-rend not needed? */ { for ( i = 0; i < MAX_HEAD_ROT_POSES - 1; ++i ) { - if ( hSplitRendWrapper->hTdRendHandles[i] != NULL ) + if ( st_ivas->hTdRendHandles[i] != NULL ) { - hSplitRendWrapper->hTdRendHandles[i]->HrFiltSet_p = NULL; - ivas_td_binaural_close( &hSplitRendWrapper->hTdRendHandles[i] ); + st_ivas->hTdRendHandles[i]->HrFiltSet_p = NULL; + ivas_td_binaural_close( &st_ivas->hTdRendHandles[i] ); } } } @@ -225,6 +205,7 @@ static ivas_error ivas_dec_init_split_rend( { ivas_error error; int16_t cldfb_in_flag, pcm_out_flag; + int16_t mixed_td_cldfb_flag; pcm_out_flag = ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0; cldfb_in_flag = 0; @@ -237,30 +218,24 @@ static ivas_error ivas_dec_init_split_rend( cldfb_in_flag = 1; } - ivas_renderSplitGetMultiBinPoseData( &st_ivas->hRenderConfig->split_rend_config, &st_ivas->hSplitBinRend.splitrend.multiBinPoseData, st_ivas->hHeadTrackData->sr_pose_pred_axis ); + 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 ); - if ( cldfb_in_flag == 1 && ( st_ivas->hSplitBinRend.splitrend.multiBinPoseData.poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) ) + if ( cldfb_in_flag == 1 && ( st_ivas->hSplitBinRend->splitrend.multiBinPoseData.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) ) { - if ( ( st_ivas->hSplitBinRend.hCldfbDataOut = (IVAS_DEC_SPLIT_REND_CLDFB_OUT_DATA_HANDLE) malloc( sizeof( IVAS_DEC_SPLIT_REND_CLDFB_OUT_DATA ) ) ) == NULL ) + if ( ( st_ivas->hSplitBinRend->hCldfbDataOut = (ISAR_DEC_SPLIT_REND_CLDFB_OUT_DATA_HANDLE) malloc( sizeof( ISAR_DEC_SPLIT_REND_CLDFB_OUT_DATA ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for cldfb data out buffer\n" ) ); } } - if ( ( error = ivas_split_rend_choose_default_codec( &st_ivas->hRenderConfig->split_rend_config.codec, &st_ivas->hRenderConfig->split_rend_config.codec_frame_size_ms, cldfb_in_flag, pcm_out_flag ) ) != IVAS_ERR_OK ) + mixed_td_cldfb_flag = 0; + if ( ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV && st_ivas->ivas_format == SBA_ISM_FORMAT ) || + ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC && st_ivas->ivas_format == MASA_ISM_FORMAT && st_ivas->ism_mode == ISM_MASA_MODE_DISC ) ) { - return error; + mixed_td_cldfb_flag = 1; } -#ifdef SPLIT_REND_WITH_HEAD_ROT - if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV && st_ivas->ivas_format == SBA_ISM_FORMAT ) - { - cldfb_in_flag = 0; - } -#endif - - error = ivas_split_renderer_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 == IVAS_RENDER_FRAMESIZE_5MS ); - + 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 ); return error; } #endif @@ -1074,7 +1049,8 @@ ivas_error ivas_init_decoder_front( if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_ROOM_REVERB #ifdef SPLIT_REND_WITH_HEAD_ROT - || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM + || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM || + ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_STEREO && st_ivas->hDecoderConfig->Opt_non_diegetic_pan ) #endif ) { @@ -1224,17 +1200,14 @@ ivas_error ivas_init_decoder( * Initialize binuaral split rendering *-----------------------------------------------------------------*/ - if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + if ( st_ivas->hSplitBinRend != NULL && ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM || + ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_STEREO && st_ivas->hDecoderConfig->Opt_non_diegetic_pan && st_ivas->hRenderConfig->split_rend_config.dof == 0 ) ) ) { if ( ( error = ivas_dec_init_split_rend( st_ivas ) ) != IVAS_ERR_OK ) { return error; } } - else - { - st_ivas->hSplitBinRend.splitrend.multiBinPoseData.num_poses = 1; - } #endif /*-----------------------------------------------------------------* @@ -1980,13 +1953,13 @@ ivas_error ivas_init_decoder( } } - granularity = NS2SA( st_ivas->hDecoderConfig->output_Fs, FRAME_SIZE_NS / MAX_PARAM_SPATIAL_SUBFRAMES ); - n_channels_transport_jbm = ivas_jbm_dec_get_num_tc_channels( st_ivas ); + granularity = NS2SA( st_ivas->hDecoderConfig->output_Fs, FRAME_SIZE_NS / MAX_PARAM_SPATIAL_SUBFRAMES ); + n_channels_transport_jbm = ivas_jbm_dec_get_num_tc_channels( st_ivas ); - if ( ( error = ivas_jbm_dec_tc_buffer_open( st_ivas, TC_BUFFER_MODE_RENDERER, n_channels_transport_jbm, n_channels_transport_jbm, n_channels_transport_jbm, granularity ) ) != IVAS_ERR_OK ) - { - return error; - } + if ( ( error = ivas_jbm_dec_tc_buffer_open( st_ivas, TC_BUFFER_MODE_RENDERER, n_channels_transport_jbm, n_channels_transport_jbm, n_channels_transport_jbm, granularity ) ) != IVAS_ERR_OK ) + { + return error; + } } else if ( st_ivas->renderer_type == RENDERER_MC ) { @@ -2014,7 +1987,7 @@ ivas_error ivas_init_decoder( #ifdef SPLIT_REND_WITH_HEAD_ROT if ( ( error = ivas_rend_openCrend( &( st_ivas->hCrendWrapper ), st_ivas->intern_config, st_ivas->hDecoderConfig->output_config, - st_ivas->hRenderConfig, st_ivas->hSetOfHRTF, st_ivas->hDecoderConfig->output_Fs, st_ivas->hSplitBinRend.splitrend.multiBinPoseData.num_poses ) ) != IVAS_ERR_OK ) + st_ivas->hRenderConfig, st_ivas->hSetOfHRTF, st_ivas->hDecoderConfig->output_Fs, ( st_ivas->hSplitBinRend == NULL ) ? 1 : st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses ) ) != IVAS_ERR_OK ) #else if ( ( error = ivas_rend_openCrend( &( st_ivas->hCrendWrapper ), st_ivas->intern_config, st_ivas->hDecoderConfig->output_config, st_ivas->hRenderConfig, st_ivas->hSetOfHRTF, st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK ) @@ -2025,28 +1998,28 @@ ivas_error ivas_init_decoder( st_ivas->binaural_latency_ns = st_ivas->hCrendWrapper->binaural_latency_ns; - if ( ( st_ivas->ivas_format == MC_FORMAT ) && ( st_ivas->mc_mode == MC_MODE_PARAMUPMIX ) ) - { - granularity = NS2SA( output_Fs, CLDFB_SLOT_NS ); + if ( ( st_ivas->ivas_format == MC_FORMAT ) && ( st_ivas->mc_mode == MC_MODE_PARAMUPMIX ) ) + { + granularity = NS2SA( output_Fs, CLDFB_SLOT_NS ); - n_channels_transport_jbm = ivas_jbm_dec_get_num_tc_channels( st_ivas ); + n_channels_transport_jbm = ivas_jbm_dec_get_num_tc_channels( st_ivas ); - if ( ( error = ivas_jbm_dec_tc_buffer_open( st_ivas, TC_BUFFER_MODE_RENDERER, n_channels_transport_jbm, MC_PARAMUPMIX_MAX_INPUT_CHANS, MC_PARAMUPMIX_MAX_INPUT_CHANS, granularity ) ) != IVAS_ERR_OK ) - { - return error; - } - } - else + if ( ( error = ivas_jbm_dec_tc_buffer_open( st_ivas, TC_BUFFER_MODE_RENDERER, n_channels_transport_jbm, MC_PARAMUPMIX_MAX_INPUT_CHANS, MC_PARAMUPMIX_MAX_INPUT_CHANS, granularity ) ) != IVAS_ERR_OK ) { - granularity = NS2SA( st_ivas->hDecoderConfig->output_Fs, FRAME_SIZE_NS / MAX_PARAM_SPATIAL_SUBFRAMES ); + return error; + } + } + else + { + granularity = NS2SA( st_ivas->hDecoderConfig->output_Fs, FRAME_SIZE_NS / MAX_PARAM_SPATIAL_SUBFRAMES ); - n_channels_transport_jbm = ivas_jbm_dec_get_num_tc_channels( st_ivas ); + n_channels_transport_jbm = ivas_jbm_dec_get_num_tc_channels( st_ivas ); - if ( ( error = ivas_jbm_dec_tc_buffer_open( st_ivas, TC_BUFFER_MODE_RENDERER, n_channels_transport_jbm, n_channels_transport_jbm, n_channels_transport_jbm, granularity ) ) != IVAS_ERR_OK ) - { - return error; - } + if ( ( error = ivas_jbm_dec_tc_buffer_open( st_ivas, TC_BUFFER_MODE_RENDERER, n_channels_transport_jbm, n_channels_transport_jbm, n_channels_transport_jbm, granularity ) ) != IVAS_ERR_OK ) + { + return error; } + } } if ( st_ivas->ivas_format == MASA_ISM_FORMAT ) @@ -2476,12 +2449,11 @@ void ivas_initialize_handles_dec( st_ivas->hCombinedOrientationData = NULL; #ifdef SPLIT_REND_WITH_HEAD_ROT - st_ivas->hSplitBinRend.hMultiBinCldfbData = NULL; - st_ivas->hSplitBinRend.hSplitRendBits = NULL; - st_ivas->hSplitBinRend.hCldfbDataOut = NULL; - st_ivas->hSplitBinRend.tdDataOut = NULL; - st_ivas->hSplitBinRend.numTdSamplesPerChannelCached = 0; - ivas_init_split_rend_handles( &st_ivas->hSplitBinRend.splitrend ); + st_ivas->hSplitBinRend = NULL; + for ( i = 0; i < MAX_HEAD_ROT_POSES - 1; ++i ) + { + st_ivas->hTdRendHandles[i] = NULL; + } #endif /* JBM handles */ @@ -2621,18 +2593,14 @@ void ivas_destroy_dec( ivas_binRenderer_close( &st_ivas->hBinRenderer ); #ifdef SPLIT_REND_WITH_HEAD_ROT - /* Split binaural renderer handle */ - ivas_split_renderer_close( &st_ivas->hSplitBinRend.splitrend ); - - if ( st_ivas->hSplitBinRend.hCldfbDataOut != NULL ) + /* TD binaural renderer handles */ + for ( i = 0; i < MAX_HEAD_ROT_POSES - 1; ++i ) { - free( st_ivas->hSplitBinRend.hCldfbDataOut ); - st_ivas->hSplitBinRend.hCldfbDataOut = NULL; - } - - if ( st_ivas->hSplitBinRend.tdDataOut != NULL ) - { - free( st_ivas->hSplitBinRend.tdDataOut ); + if ( st_ivas->hTdRendHandles[i] != NULL ) + { + st_ivas->hTdRendHandles[i]->HrFiltSet_p = NULL; + ivas_td_binaural_close( &st_ivas->hTdRendHandles[i] ); + } } #endif @@ -2646,7 +2614,7 @@ void ivas_destroy_dec( /* Crend handle */ #ifdef SPLIT_REND_WITH_HEAD_ROT - ivas_rend_closeCrend( &( st_ivas->hCrendWrapper ), st_ivas->hSplitBinRend.splitrend.multiBinPoseData.num_poses ); + ivas_rend_closeCrend( &( st_ivas->hCrendWrapper ), ( st_ivas->hSplitBinRend == NULL ) ? 1 : st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses ); #else ivas_rend_closeCrend( &( st_ivas->hCrendWrapper ) ); #endif @@ -2687,7 +2655,8 @@ void ivas_destroy_dec( { ivas_td_binaural_close( &st_ivas->hBinRendererTd ); } - else if ( st_ivas->hHrtfTD != NULL ) + + if ( st_ivas->hHrtfTD != NULL ) { BSplineModelEvalDealloc( &st_ivas->hHrtfTD->ModelParams, &st_ivas->hHrtfTD->ModelEval ); diff --git a/lib_dec/ivas_ism_dec.c b/lib_dec/ivas_ism_dec.c index 52349b9e6..8981d68c5 100644 --- a/lib_dec/ivas_ism_dec.c +++ b/lib_dec/ivas_ism_dec.c @@ -230,7 +230,7 @@ static ivas_error ivas_ism_bitrate_switching_dec( /* Open Crend Binaural renderer */ #ifdef SPLIT_REND_WITH_HEAD_ROT - if ( ( error = ivas_rend_openCrend( &( st_ivas->hCrendWrapper ), st_ivas->intern_config, st_ivas->hOutSetup.output_config, st_ivas->hRenderConfig, st_ivas->hSetOfHRTF, st_ivas->hDecoderConfig->output_Fs, st_ivas->hSplitBinRend.splitrend.multiBinPoseData.num_poses ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_rend_openCrend( &( st_ivas->hCrendWrapper ), st_ivas->intern_config, st_ivas->hOutSetup.output_config, st_ivas->hRenderConfig, st_ivas->hSetOfHRTF, st_ivas->hDecoderConfig->output_Fs, ( st_ivas->hSplitBinRend == NULL ) ? 1 : st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses ) ) != IVAS_ERR_OK ) #else if ( ( error = ivas_rend_openCrend( &( st_ivas->hCrendWrapper ), st_ivas->intern_config, st_ivas->hOutSetup.output_config, st_ivas->hRenderConfig, st_ivas->hSetOfHRTF, st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK ) #endif @@ -301,7 +301,7 @@ static ivas_error ivas_ism_bitrate_switching_dec( /* close the crend binaural renderer */ #ifdef SPLIT_REND_WITH_HEAD_ROT - ivas_rend_closeCrend( &( st_ivas->hCrendWrapper ), st_ivas->hSplitBinRend.splitrend.multiBinPoseData.num_poses ); + ivas_rend_closeCrend( &( st_ivas->hCrendWrapper ), ( st_ivas->hSplitBinRend == NULL ) ? 1 : st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses ); #else ivas_rend_closeCrend( &( st_ivas->hCrendWrapper ) ); #endif diff --git a/lib_dec/ivas_jbm_dec.c b/lib_dec/ivas_jbm_dec.c index 2d0000960..64eaf39e3 100644 --- a/lib_dec/ivas_jbm_dec.c +++ b/lib_dec/ivas_jbm_dec.c @@ -1090,7 +1090,7 @@ ivas_error ivas_jbm_dec_render( } else if ( st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV_ROOM ) { -#ifdef SPLIT_REND_WITH_HEAD_ROT +#if defined SPLIT_REND_WITH_HEAD_ROT if ( ( error = ivas_rend_crendProcessSubframe( st_ivas->hCrendWrapper, IVAS_AUDIO_CONFIG_7_1_4, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR, st_ivas->hDecoderConfig, NULL, NULL, NULL, st_ivas->hTcBuffer, p_output, p_output, *nSamplesRendered, output_Fs, 0 ) ) != IVAS_ERR_OK ) #else @@ -1279,7 +1279,7 @@ ivas_error ivas_jbm_dec_render( #ifdef SPLIT_REND_WITH_HEAD_ROT if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) { - if ( ( error = ivas_rend_crendProcessSubframesSplitBin( st_ivas->hCrendWrapper, st_ivas->intern_config, st_ivas->hOutSetup.output_config, &st_ivas->hSplitBinRend.splitrend.multiBinPoseData, st_ivas->hDecoderConfig, st_ivas->hCombinedOrientationData, + if ( ( error = ivas_rend_crendProcessSubframesSplitBin( st_ivas->hCrendWrapper, st_ivas->intern_config, st_ivas->hOutSetup.output_config, ( st_ivas->hSplitBinRend == NULL ) ? NULL : &st_ivas->hSplitBinRend->splitrend.multiBinPoseData, st_ivas->hDecoderConfig, st_ivas->hCombinedOrientationData, &st_ivas->hIntSetup, st_ivas->hEFAPdata, st_ivas->hTcBuffer, crendInPlaceRotation ? p_output : p_tc, p_output, *nSamplesRendered, output_Fs ) ) != IVAS_ERR_OK ) { return error; @@ -1289,7 +1289,7 @@ ivas_error ivas_jbm_dec_render( { #endif -#ifdef SPLIT_REND_WITH_HEAD_ROT +#if defined SPLIT_REND_WITH_HEAD_ROT if ( ( error = ivas_rend_crendProcessSubframe( st_ivas->hCrendWrapper, st_ivas->intern_config, st_ivas->hOutSetup.output_config, st_ivas->hDecoderConfig, st_ivas->hCombinedOrientationData, &st_ivas->hIntSetup, st_ivas->hEFAPdata, st_ivas->hTcBuffer, crendInPlaceRotation ? p_output : p_tc, p_output, *nSamplesRendered, output_Fs, 0 ) ) != IVAS_ERR_OK ) #else @@ -1364,29 +1364,6 @@ ivas_error ivas_jbm_dec_render( { ivas_mc2sba( st_ivas->hIntSetup, p_output, p_output, *nSamplesRendered, st_ivas->hOutSetup.ambisonics_order, 0.f ); } - else if ( st_ivas->renderer_type == RENDERER_BINAURAL_OBJECTS_TD ) - { -#ifdef SPLIT_REND_WITH_HEAD_ROT - if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) - { - if ( ( error = ivas_td_binaural_renderer_sf_splitBinaural( st_ivas, p_output, *nSamplesRendered ) ) != IVAS_ERR_OK ) - { - return error; - } - } - else - { -#endif - if ( ( error = ivas_td_binaural_renderer( st_ivas, p_output, *nSamplesRendered ) ) != IVAS_ERR_OK ) - { - return error; - } - - ivas_binaural_add_LFE( st_ivas, *nSamplesRendered, p_output, p_output ); -#ifdef SPLIT_REND_WITH_HEAD_ROT - } -#endif - } } else if ( st_ivas->mc_mode == MC_MODE_PARAMMC ) { @@ -1396,7 +1373,6 @@ ivas_error ivas_jbm_dec_render( { int16_t offset = hSpatParamRendCom->slots_rendered * hSpatParamRendCom->slot_size; nchan_remapped = st_ivas->nchan_transport; - if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM || st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC ) { ivas_dirac_dec_binaural_render( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, nchan_remapped, p_output ); @@ -1468,7 +1444,7 @@ ivas_error ivas_jbm_dec_render( #ifdef SPLIT_REND_WITH_HEAD_ROT if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) { - nchan_out_syn_output = BINAURAL_CHANNELS * st_ivas->hSplitBinRend.splitrend.multiBinPoseData.num_poses; + nchan_out_syn_output = BINAURAL_CHANNELS * st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses; } else { @@ -1620,7 +1596,7 @@ ivas_error ivas_jbm_dec_flush_renderer( ivas_ism_render_sf( st_ivas, p_output, hTcBuffer->n_samples_granularity ); -#ifdef SPLIT_REND_WITH_HEAD_ROT +#if defined SPLIT_REND_WITH_HEAD_ROT if ( ( error = ivas_rend_crendProcessSubframe( st_ivas->hCrendWrapper, IVAS_AUDIO_CONFIG_7_1_4, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR, st_ivas->hDecoderConfig, NULL, NULL, NULL, st_ivas->hTcBuffer, p_output, p_output, hTcBuffer->n_samples_granularity, st_ivas->hDecoderConfig->output_Fs, 0 ) ) != IVAS_ERR_OK ) #else diff --git a/lib_dec/ivas_masa_dec.c b/lib_dec/ivas_masa_dec.c index 0e2202107..190042724 100644 --- a/lib_dec/ivas_masa_dec.c +++ b/lib_dec/ivas_masa_dec.c @@ -1382,20 +1382,17 @@ ivas_error ivas_masa_dec_reconfigure( { if ( st_ivas->hDiracDecBin[pos_idx] != NULL ) { -#else - if ( st_ivas->hDiracDecBin != NULL ) - { - -#endif /* regularization factor is bitrate-dependent */ -#ifdef SPLIT_REND_WITH_HEAD_ROT st_ivas->hDiracDecBin[pos_idx]->reqularizationFactor = configure_reqularization_factor( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate ); } + } #else + if ( st_ivas->hDiracDecBin != NULL ) + { /* regularization factor is bitrate-dependent */ st_ivas->hDiracDecBin->reqularizationFactor = configure_reqularization_factor( st_ivas->ivas_format, st_ivas->hDecoderConfig->ivas_total_brate ); -#endif } +#endif if ( st_ivas->ivas_format == MASA_FORMAT && st_ivas->last_ivas_format == MASA_FORMAT ) /* note: switching within OMASA is handled in ivas_omasa_dec_config() */ { diff --git a/lib_dec/ivas_mc_param_dec.c b/lib_dec/ivas_mc_param_dec.c index 6f2970ada..8980886e2 100644 --- a/lib_dec/ivas_mc_param_dec.c +++ b/lib_dec/ivas_mc_param_dec.c @@ -1944,24 +1944,24 @@ void ivas_param_mc_dec_render( #ifdef SPLIT_REND_WITH_HEAD_ROT if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) { - if ( st_ivas->hSplitBinRend.hCldfbDataOut != NULL ) + if ( st_ivas->hSplitBinRend->hCldfbDataOut != NULL ) { for ( slot_idx = 0; slot_idx < MAX_PARAM_SPATIAL_SUBFRAMES; slot_idx++ ) { for ( ch = 0; ch < ( st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe ); ch++ ) { - mvr2r( Cldfb_RealBuffer[ch][slot_idx], st_ivas->hSplitBinRend.hCldfbDataOut->Cldfb_RealBuffer[ch][slot_idx_start + slot_idx], hParamMC->num_freq_bands ); - mvr2r( Cldfb_ImagBuffer[ch][slot_idx], st_ivas->hSplitBinRend.hCldfbDataOut->Cldfb_ImagBuffer[ch][slot_idx_start + slot_idx], hParamMC->num_freq_bands ); + mvr2r( Cldfb_RealBuffer[ch][slot_idx], st_ivas->hSplitBinRend->hCldfbDataOut->Cldfb_RealBuffer[ch][slot_idx_start + slot_idx], hParamMC->num_freq_bands ); + mvr2r( Cldfb_ImagBuffer[ch][slot_idx], st_ivas->hSplitBinRend->hCldfbDataOut->Cldfb_ImagBuffer[ch][slot_idx_start + slot_idx], hParamMC->num_freq_bands ); } } - st_ivas->hSplitBinRend.hCldfbDataOut->config = st_ivas->hIntSetup.output_config; + st_ivas->hSplitBinRend->hCldfbDataOut->config = st_ivas->hIntSetup.output_config; } } #endif ivas_binRenderer( st_ivas->hBinRenderer, #ifdef SPLIT_REND_WITH_HEAD_ROT - &st_ivas->hSplitBinRend.splitrend.multiBinPoseData, + ( st_ivas->hSplitBinRend == NULL ) ? NULL : &st_ivas->hSplitBinRend->splitrend.multiBinPoseData, #ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG NULL, #endif @@ -1980,8 +1980,8 @@ void ivas_param_mc_dec_render( { for ( ch = 0; ch < nchan_out_cldfb; ch++ ) { - mvr2r( Cldfb_RealBuffer_Binaural[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend.hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[( pos_idx * BINAURAL_CHANNELS ) + ch][slot_idx_start + slot_idx], hParamMC->num_freq_bands ); - mvr2r( Cldfb_ImagBuffer_Binaural[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend.hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[( pos_idx * BINAURAL_CHANNELS ) + ch][slot_idx_start + slot_idx], hParamMC->num_freq_bands ); + mvr2r( Cldfb_RealBuffer_Binaural[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[( pos_idx * BINAURAL_CHANNELS ) + ch][slot_idx_start + slot_idx], hParamMC->num_freq_bands ); + mvr2r( Cldfb_ImagBuffer_Binaural[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[( pos_idx * BINAURAL_CHANNELS ) + ch][slot_idx_start + slot_idx], hParamMC->num_freq_bands ); } } } diff --git a/lib_dec/ivas_mc_paramupmix_dec.c b/lib_dec/ivas_mc_paramupmix_dec.c index a9be77ec8..a28d71ae6 100644 --- a/lib_dec/ivas_mc_paramupmix_dec.c +++ b/lib_dec/ivas_mc_paramupmix_dec.c @@ -66,11 +66,7 @@ const int16_t MC_PARAMUPMIX_CHIDX2[MC_PARAMUPMIX_COMBINATIONS] = { 2, 3, 6, 7 }; static void ps_pred_process_sf( MC_PARAMUPMIX_DEC_HANDLE hMCParamUpmix, DECODER_TC_BUFFER_HANDLE hTcBuffer, float qmf_mod_re[JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float qmf_mod_im[JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float qmf_side_re[JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float qmf_side_im[JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float *param_interpol, const int16_t ch, const int16_t slots_rendered ); -#ifdef SPLIT_REND_WITH_HEAD_ROT -static void ivas_mc_paramupmix_dec_sf( Decoder_Struct *st_ivas, float *output_f[MAX_OUTPUT_CHANNELS], const int16_t slot_index_start ); -#else static void ivas_mc_paramupmix_dec_sf( Decoder_Struct *st_ivas, float *output_f[MAX_OUTPUT_CHANNELS] ); -#endif static void ivas_param_upmix_dec_decorr_subframes( Decoder_Struct *st_ivas, const int16_t nSamplesForRendering ); @@ -208,9 +204,6 @@ void ivas_mc_paramupmix_dec_render( int16_t slots_to_render, first_sf, last_sf, subframe_idx; uint16_t slot_size, ch; float *output_f_local[MAX_OUTPUT_CHANNELS]; -#ifdef SPLIT_REND_WITH_HEAD_ROT - int16_t slot_index_start; -#endif MC_PARAMUPMIX_DEC_HANDLE hMCParamUpmix; hMCParamUpmix = st_ivas->hMCParamUpmix; @@ -252,20 +245,11 @@ void ivas_mc_paramupmix_dec_render( mvr2r( hMCParamUpmix->beta_prev[ch], hMCParamUpmix->beta_sf[ch], IVAS_MAX_NUM_BANDS ); } -#ifdef SPLIT_REND_WITH_HEAD_ROT - slot_index_start = 0; -#endif + for ( subframe_idx = first_sf; subframe_idx < last_sf; subframe_idx++ ) { int16_t n_samples_sf = slot_size * st_ivas->hTcBuffer->subframe_nbslots[subframe_idx]; - -#ifdef SPLIT_REND_WITH_HEAD_ROT - ivas_mc_paramupmix_dec_sf( st_ivas, output_f_local, slot_index_start ); - - slot_index_start += st_ivas->hTcBuffer->subframe_nbslots[subframe_idx]; -#else ivas_mc_paramupmix_dec_sf( st_ivas, output_f_local ); -#endif for ( ch = 0; ch < min( MAX_OUTPUT_CHANNELS, ivas_get_nchan_buffers_dec( st_ivas, -1, -1 ) ); ch++ ) { @@ -370,13 +354,13 @@ ivas_error ivas_mc_paramupmix_dec_open( hMCParamUpmix->free_param_interpolator = 0; hMCParamUpmix->param_interpolator = NULL; - if ( ( hMCParamUpmix->param_interpolator = (float *) malloc( MAX_JBM_CLDFB_TIMESLOTS * sizeof( float ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for interpolator\n" ) ); - } - hMCParamUpmix->free_param_interpolator = 1; + if ( ( hMCParamUpmix->param_interpolator = (float *) malloc( MAX_JBM_CLDFB_TIMESLOTS * sizeof( float ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for interpolator\n" ) ); + } + hMCParamUpmix->free_param_interpolator = 1; - ivas_jbm_dec_get_adapted_linear_interpolator( DEFAULT_JBM_CLDFB_TIMESLOTS, DEFAULT_JBM_CLDFB_TIMESLOTS, hMCParamUpmix->param_interpolator ); + ivas_jbm_dec_get_adapted_linear_interpolator( DEFAULT_JBM_CLDFB_TIMESLOTS, DEFAULT_JBM_CLDFB_TIMESLOTS, hMCParamUpmix->param_interpolator ); if ( st_ivas->hTcBuffer == NULL ) { @@ -644,15 +628,9 @@ static void ps_pred_process_sf( return; } - static void ivas_mc_paramupmix_dec_sf( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ -#ifdef SPLIT_REND_WITH_HEAD_ROT - float *output_f[MAX_OUTPUT_CHANNELS], /* i/o: synthesized core-coder transport channels */ - const int16_t slot_index_start -#else + Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ float *output_f[MAX_OUTPUT_CHANNELS] /* i/o: synthesized core-coder transport channels */ -#endif ) { int16_t i, ch, slot_idx, k; @@ -668,6 +646,7 @@ static void ivas_mc_paramupmix_dec_sf( #ifdef SPLIT_REND_WITH_HEAD_ROT float Cldfb_RealBuffer_Binaural[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; float Cldfb_ImagBuffer_Binaural[MAX_HEAD_ROT_POSES][BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; + int16_t slot_index_start; #else float Cldfb_RealBuffer_Binaural[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; float Cldfb_ImagBuffer_Binaural[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; @@ -677,6 +656,9 @@ static void ivas_mc_paramupmix_dec_sf( assert( hMCParamUpmix ); push_wmops( "ivas_mc_paramupmix_dec_sf" ); +#ifdef SPLIT_REND_WITH_HEAD_ROT + slot_index_start = st_ivas->hTcBuffer->slots_rendered; +#endif for ( i = 0; i < MC_PARAMUPMIX_COMBINATIONS; i++ ) { pPcm_temp[2 * i] = output_f[i + 4]; /* un-decorrelated */ @@ -771,18 +753,18 @@ static void ivas_mc_paramupmix_dec_sf( /*LFE handling for split rendering cases*/ if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) { - if ( st_ivas->hSplitBinRend.hCldfbDataOut != NULL ) + if ( st_ivas->hSplitBinRend->hCldfbDataOut != NULL ) { for ( slot_idx = 0; slot_idx < st_ivas->hTcBuffer->subframe_nbslots[st_ivas->hTcBuffer->subframes_rendered]; slot_idx++ ) { for ( ch = 0; ch < ( st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe ); ch++ ) { - mvr2r( Cldfb_RealBuffer_subfr[ch][slot_idx], st_ivas->hSplitBinRend.hCldfbDataOut->Cldfb_RealBuffer[ch][slot_index_start + slot_idx], maxBand ); - mvr2r( Cldfb_ImagBuffer_subfr[ch][slot_idx], st_ivas->hSplitBinRend.hCldfbDataOut->Cldfb_ImagBuffer[ch][slot_index_start + slot_idx], maxBand ); + mvr2r( Cldfb_RealBuffer_subfr[ch][slot_idx], st_ivas->hSplitBinRend->hCldfbDataOut->Cldfb_RealBuffer[ch][slot_index_start + slot_idx], maxBand ); + mvr2r( Cldfb_ImagBuffer_subfr[ch][slot_idx], st_ivas->hSplitBinRend->hCldfbDataOut->Cldfb_ImagBuffer[ch][slot_index_start + slot_idx], maxBand ); } } - st_ivas->hSplitBinRend.hCldfbDataOut->config = st_ivas->hIntSetup.output_config; + st_ivas->hSplitBinRend->hCldfbDataOut->config = st_ivas->hIntSetup.output_config; } } #endif @@ -790,7 +772,7 @@ static void ivas_mc_paramupmix_dec_sf( /* Implement binaural rendering */ ivas_binRenderer( st_ivas->hBinRenderer, #ifdef SPLIT_REND_WITH_HEAD_ROT - &st_ivas->hSplitBinRend.splitrend.multiBinPoseData, + ( st_ivas->hSplitBinRend == NULL ) ? NULL : &st_ivas->hSplitBinRend->splitrend.multiBinPoseData, #endif st_ivas->hCombinedOrientationData, st_ivas->hTcBuffer->subframe_nbslots[subframeIdx], @@ -808,8 +790,8 @@ static void ivas_mc_paramupmix_dec_sf( { for ( ch = 0; ch < st_ivas->hDecoderConfig->nchan_out; ch++ ) { - mvr2r( Cldfb_RealBuffer_Binaural[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend.hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[( pos_idx * BINAURAL_CHANNELS ) + ch][slot_index_start + slot_idx], maxBand ); - mvr2r( Cldfb_ImagBuffer_Binaural[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend.hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[( pos_idx * BINAURAL_CHANNELS ) + ch][slot_index_start + slot_idx], maxBand ); + mvr2r( Cldfb_RealBuffer_Binaural[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[( pos_idx * BINAURAL_CHANNELS ) + ch][slot_index_start + slot_idx], maxBand ); + mvr2r( Cldfb_ImagBuffer_Binaural[pos_idx][ch][slot_idx], st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[( pos_idx * BINAURAL_CHANNELS ) + ch][slot_index_start + slot_idx], maxBand ); } } } diff --git a/lib_dec/ivas_mct_dec.c b/lib_dec/ivas_mct_dec.c index 4e6397b26..7f8878ec2 100644 --- a/lib_dec/ivas_mct_dec.c +++ b/lib_dec/ivas_mct_dec.c @@ -1199,7 +1199,7 @@ static ivas_error ivas_mc_dec_reconfig( { #ifdef SPLIT_REND_WITH_HEAD_ROT - ivas_rend_closeCrend( &( st_ivas->hCrendWrapper ), st_ivas->hSplitBinRend.splitrend.multiBinPoseData.num_poses ); + ivas_rend_closeCrend( &( st_ivas->hCrendWrapper ), ( st_ivas->hSplitBinRend == NULL ) ? 1 : st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses ); #else ivas_rend_closeCrend( &( st_ivas->hCrendWrapper ) ); #endif @@ -1280,7 +1280,7 @@ static ivas_error ivas_mc_dec_reconfig( else if ( st_ivas->hCrendWrapper == NULL && ( st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV || st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV_ROOM ) ) { #ifdef SPLIT_REND_WITH_HEAD_ROT - if ( ( error = ivas_rend_openCrend( &( st_ivas->hCrendWrapper ), st_ivas->intern_config, st_ivas->hDecoderConfig->output_config, st_ivas->hRenderConfig, st_ivas->hSetOfHRTF, st_ivas->hDecoderConfig->output_Fs, st_ivas->hSplitBinRend.splitrend.multiBinPoseData.num_poses ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_rend_openCrend( &( st_ivas->hCrendWrapper ), st_ivas->intern_config, st_ivas->hDecoderConfig->output_config, st_ivas->hRenderConfig, st_ivas->hSetOfHRTF, st_ivas->hDecoderConfig->output_Fs, ( st_ivas->hSplitBinRend == NULL ) ? 1 : st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses ) ) != IVAS_ERR_OK ) #else if ( ( error = ivas_rend_openCrend( &( st_ivas->hCrendWrapper ), st_ivas->intern_config, st_ivas->hDecoderConfig->output_config, st_ivas->hRenderConfig, st_ivas->hSetOfHRTF, st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK ) #endif diff --git a/lib_dec/ivas_objectRenderer_internal.c b/lib_dec/ivas_objectRenderer_internal.c index 9991ed32a..851e8dc90 100644 --- a/lib_dec/ivas_objectRenderer_internal.c +++ b/lib_dec/ivas_objectRenderer_internal.c @@ -280,7 +280,7 @@ ivas_error ivas_td_binaural_renderer_sf( ivas_error ivas_td_binaural_renderer_sf_splitBinaural( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ float *output[], /* i/o: SCE channels / Binaural synthesis */ - int16_t nSamplesRendered /* i : number of samples to render */ + const int16_t nSamplesRendered /* i : number of samples to render */ ) { int16_t i; @@ -292,15 +292,15 @@ ivas_error ivas_td_binaural_renderer_sf_splitBinaural( int16_t original_subframes_rendered; int16_t original_slots_rendered; float *p_bin_output[BINAURAL_CHANNELS]; - float output_local[MAX_OUTPUT_CHANNELS][L_FRAME48k]; // VE2SB: TBV + float output_local[MAX_OUTPUT_CHANNELS][L_FRAME48k]; push_wmops( "ivas_td_binaural_renderer_sf_splitBinaural" ); - pMultiBinPoseData = &st_ivas->hSplitBinRend.splitrend.multiBinPoseData; + pMultiBinPoseData = &st_ivas->hSplitBinRend->splitrend.multiBinPoseData; /* If not yet allocated, open additional instances of TD renderer */ for ( i = 0; i < pMultiBinPoseData->num_poses - 1; ++i ) { - if ( st_ivas->hSplitBinRend.splitrend.hTdRendHandles[i] != NULL ) + if ( st_ivas->hTdRendHandles[i] != NULL ) { continue; } @@ -312,7 +312,7 @@ ivas_error ivas_td_binaural_renderer_sf_splitBinaural( st_ivas->transport_config, st_ivas->hRenderConfig->directivity, st_ivas->hTransSetup, - &st_ivas->hSplitBinRend.splitrend.hTdRendHandles[i], + &st_ivas->hTdRendHandles[i], &st_ivas->binaural_latency_ns ) ) != IVAS_ERR_OK ) { return error; @@ -373,13 +373,23 @@ ivas_error ivas_td_binaural_renderer_sf_splitBinaural( /* Render */ if ( pos_idx != 0 ) { - st_ivas->hBinRendererTd = st_ivas->hSplitBinRend.splitrend.hTdRendHandles[pos_idx - 1]; + st_ivas->hBinRendererTd = st_ivas->hTdRendHandles[pos_idx - 1]; } if ( ( error = ivas_td_binaural_renderer_sf( st_ivas, p_bin_output, nSamplesRendered ) ) != IVAS_ERR_OK ) { return error; } + + if ( st_ivas->ivas_format == MC_FORMAT ) + { + float *p_tc[MAX_TRANSPORT_CHANNELS]; + for ( i = 0; i < st_ivas->nchan_transport; i++ ) + { + p_tc[i] = st_ivas->hTcBuffer->tc[i] + st_ivas->hTcBuffer->n_samples_rendered; + } + ivas_binaural_add_LFE( st_ivas, nSamplesRendered, p_tc, p_bin_output ); + } } for ( i = 0; i < pMultiBinPoseData->num_poses * BINAURAL_CHANNELS; i++ ) diff --git a/lib_dec/ivas_omasa_dec.c b/lib_dec/ivas_omasa_dec.c index 9c0c891d8..39741dbfe 100644 --- a/lib_dec/ivas_omasa_dec.c +++ b/lib_dec/ivas_omasa_dec.c @@ -648,45 +648,74 @@ ivas_error ivas_omasa_dirac_td_binaural_jbm( { int16_t n; float data_separated_objects[MAX_NUM_OBJECTS][L_FRAME48k]; - float gain = OMASA_TDREND_MATCHING_GAIN; ivas_error error; float *p_sepobj[MAX_NUM_OBJECTS]; - float *tc_local[MAX_TRANSPORT_CHANNELS]; +#ifdef SPLIT_REND_WITH_HEAD_ROT + int16_t slot_idx_start; + + slot_idx_start = st_ivas->hSpatParamRendCom->slots_rendered; +#endif for ( n = 0; n < MAX_NUM_OBJECTS; n++ ) { p_sepobj[n] = &data_separated_objects[n][0]; } - /* Delay the object signals to match the CLDFB delay. Delay the whole buffer with the first rendering call of the stretched buffer. */ - if ( st_ivas->hSpatParamRendCom->slots_rendered == 0 ) - { - int16_t tcBufferSize; + ivas_dirac_dec_binaural_render( st_ivas, nSamplesAsked, nSamplesRendered, nSamplesAvailable, nchan_transport, output_f ); - tcBufferSize = st_ivas->hSpatParamRendCom->num_slots * st_ivas->hSpatParamRendCom->slot_size; + /* reset combined orientation access index before calling the td renderer */ + ivas_combined_orientation_set_to_start_index( st_ivas->hCombinedOrientationData ); - for ( n = 0; n < st_ivas->nchan_ism; n++ ) +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { + int16_t slot_idx, num_cldfb_bands, nchan_transport_orig, cldfb_slots; + float Cldfb_RealBuffer[CLDFB_NO_CHANNELS_MAX]; + float Cldfb_ImagBuffer[CLDFB_NO_CHANNELS_MAX]; + float *p_rend_obj[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS]; /* [8 * 2] */ + + for ( n = 0; n < st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses * BINAURAL_CHANNELS; n++ ) { - tc_local[n] = st_ivas->hTcBuffer->tc[n + 2]; - v_multc( tc_local[n], gain, tc_local[n], tcBufferSize ); - delay_signal( tc_local[n], tcBufferSize, st_ivas->hMasaIsmData->delayBuffer[n], st_ivas->hMasaIsmData->delayBuffer_size ); + p_rend_obj[n] = &output_f[n][0]; } - } - ivas_dirac_dec_binaural_render( st_ivas, nSamplesAsked, nSamplesRendered, nSamplesAvailable, nchan_transport, output_f ); + num_cldfb_bands = st_ivas->hSplitBinRend->splitrend.hCldfbHandles->cldfbAna[0]->no_channels; + nchan_transport_orig = st_ivas->nchan_transport; + st_ivas->nchan_transport = st_ivas->nchan_ism; - /* reset combined orientation access index before calling the td renderer */ - ivas_combined_orientation_set_to_start_index( st_ivas->hCombinedOrientationData ); + if ( ( error = ivas_td_binaural_renderer_sf_splitBinaural( st_ivas, p_rend_obj, *nSamplesRendered ) ) != IVAS_ERR_OK ) /* objects are read from st_ivas->hTcBuffer->tc[2..(1+n_isms)] */ + { + return error; + } + st_ivas->nchan_transport = nchan_transport_orig; + cldfb_slots = *nSamplesRendered / num_cldfb_bands; - if ( ( error = ivas_td_binaural_renderer_sf( st_ivas, p_sepobj, *nSamplesRendered ) ) != IVAS_ERR_OK ) - { - return error; + for ( n = 0; n < st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses * BINAURAL_CHANNELS; ++n ) + { + for ( slot_idx = 0; slot_idx < cldfb_slots; slot_idx++ ) + { + cldfbAnalysis_ts( &( p_rend_obj[n][num_cldfb_bands * slot_idx] ), Cldfb_RealBuffer, Cldfb_ImagBuffer, num_cldfb_bands, st_ivas->hSplitBinRend->splitrend.hCldfbHandles->cldfbAna[n] ); + + /* note: this intentionally differs from OSBA by: no scaling by 0.5 */ + v_add( st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[n][slot_idx_start + slot_idx], Cldfb_RealBuffer, st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[n][slot_idx_start + slot_idx], num_cldfb_bands ); + v_add( st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[n][slot_idx_start + slot_idx], Cldfb_ImagBuffer, st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[n][slot_idx_start + slot_idx], num_cldfb_bands ); + } + } } - for ( n = 0; n < BINAURAL_CHANNELS; n++ ) + else { - v_add( output_f[n], p_sepobj[n], output_f[n], *nSamplesRendered ); +#endif + if ( ( error = ivas_td_binaural_renderer_sf( st_ivas, p_sepobj, *nSamplesRendered ) ) != IVAS_ERR_OK ) + { + return error; + } + for ( n = 0; n < BINAURAL_CHANNELS; n++ ) + { + v_add( output_f[n], p_sepobj[n], output_f[n], *nSamplesRendered ); + } +#ifdef SPLIT_REND_WITH_HEAD_ROT } - +#endif return IVAS_ERR_OK; } diff --git a/lib_dec/ivas_osba_dec.c b/lib_dec/ivas_osba_dec.c index 32c8b0fef..2a0d6251d 100644 --- a/lib_dec/ivas_osba_dec.c +++ b/lib_dec/ivas_osba_dec.c @@ -137,6 +137,11 @@ ivas_error ivas_osba_dirac_td_binaural_jbm( float output_separated_objects[BINAURAL_CHANNELS][L_FRAME48k]; // VE2SB: TBV float *p_sepobj[BINAURAL_CHANNELS]; int16_t channel_offset; +#ifdef SPLIT_REND_WITH_HEAD_ROT + int16_t slot_idx_start; + + slot_idx_start = st_ivas->hSpatParamRendCom->slots_rendered; +#endif for ( n = 0; n < BINAURAL_CHANNELS; n++ ) { @@ -155,14 +160,13 @@ ivas_error ivas_osba_dirac_td_binaural_jbm( if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) { int16_t slot_idx, num_cldfb_bands, b, nchan_transport_orig; - int16_t cldfb_slots, slot_idx_start; + int16_t cldfb_slots; float Cldfb_RealBuffer[CLDFB_NO_CHANNELS_MAX]; float Cldfb_ImagBuffer[CLDFB_NO_CHANNELS_MAX]; - num_cldfb_bands = st_ivas->hSplitBinRend.splitrend.hCldfbHandles->cldfbAna[0]->no_channels; + num_cldfb_bands = st_ivas->hSplitBinRend->splitrend.hCldfbHandles->cldfbAna[0]->no_channels; nchan_transport_orig = st_ivas->nchan_transport; st_ivas->nchan_transport = st_ivas->nchan_ism; - slot_idx_start = st_ivas->hTcBuffer->n_samples_rendered / num_cldfb_bands; if ( ( error = ivas_td_binaural_renderer_sf_splitBinaural( st_ivas, output_f, *nSamplesRendered ) ) != IVAS_ERR_OK ) { return error; @@ -170,20 +174,20 @@ ivas_error ivas_osba_dirac_td_binaural_jbm( st_ivas->nchan_transport = nchan_transport_orig; cldfb_slots = *nSamplesRendered / num_cldfb_bands; - for ( n = 0; n < st_ivas->hSplitBinRend.splitrend.multiBinPoseData.num_poses * BINAURAL_CHANNELS; ++n ) + for ( n = 0; n < st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses * BINAURAL_CHANNELS; ++n ) { for ( slot_idx = 0; slot_idx < cldfb_slots; slot_idx++ ) { - cldfbAnalysis_ts( &( output_f[n][num_cldfb_bands * slot_idx] ), Cldfb_RealBuffer, Cldfb_ImagBuffer, num_cldfb_bands, st_ivas->hSplitBinRend.splitrend.hCldfbHandles->cldfbAna[n] ); + cldfbAnalysis_ts( &( output_f[n][num_cldfb_bands * slot_idx] ), Cldfb_RealBuffer, Cldfb_ImagBuffer, num_cldfb_bands, st_ivas->hSplitBinRend->splitrend.hCldfbHandles->cldfbAna[n] ); for ( b = 0; b < num_cldfb_bands; b++ ) { - st_ivas->hSplitBinRend.hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[n][slot_idx][b] = - ( 0.5f * st_ivas->hSplitBinRend.hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[n][slot_idx_start + slot_idx][b] ) + + st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[n][slot_idx_start + slot_idx][b] = + ( 0.5f * st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[n][slot_idx_start + slot_idx][b] ) + ( 0.5f * Cldfb_RealBuffer[b] ); - st_ivas->hSplitBinRend.hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[n][slot_idx][b] = - ( 0.5f * st_ivas->hSplitBinRend.hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[n][slot_idx_start + slot_idx][b] ) + + st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[n][slot_idx_start + slot_idx][b] = + ( 0.5f * st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[n][slot_idx_start + slot_idx][b] ) + ( 0.5f * Cldfb_ImagBuffer[b] ); } } diff --git a/lib_dec/ivas_output_config.c b/lib_dec/ivas_output_config.c index 15d185efa..dff884bbe 100644 --- a/lib_dec/ivas_output_config.c +++ b/lib_dec/ivas_output_config.c @@ -34,9 +34,6 @@ #include "options.h" #include "ivas_cnst.h" #include "ivas_prot.h" -#ifdef SPLIT_REND_WITH_HEAD_ROT -#include "ivas_prot_rend.h" -#endif #include "ivas_stat_dec.h" #ifdef DEBUGGING #include "debug.h" diff --git a/lib_dec/ivas_rom_dec.c b/lib_dec/ivas_rom_dec.c index cfe91dfab..270f4270d 100644 --- a/lib_dec/ivas_rom_dec.c +++ b/lib_dec/ivas_rom_dec.c @@ -401,144 +401,6 @@ const float dmxmtx_table[BINAURAL_CHANNELS][11] = }; -#ifdef SPLIT_REND_WITH_HEAD_ROT -/*----------------------------------------------------------------------* - * Binuaral split rendering ROM tables - *-----------------------------------------------------------------------*/ - -/* rotations in this array are relative to ref rotation */ -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 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}; - -const int16_t ivas_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 ivas_split_rend_huff_p_d_consts[IVAS_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 ivas_split_rend_huff_p_d_diff_consts[IVAS_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 }, - { 8, 9, 510 },{ 9, 10, 1022 },{ 10, 11, 2046 },{ 11, 12, 4094 }, - { 12, 13, 8190 },{ 13, 14, 16382 },{ 14, 14, 16383 } -}; - -const int32_t ivas_split_rend_huff_d_consts[IVAS_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 }, - { 8, 9, 510 },{ 9, 10, 1022 },{ 10, 11, 2046 },{ 11, 12, 4094 }, - { 12, 13, 8190 },{ 13, 14, 16382 },{ 14, 14, 16383 } -}; - -const int32_t ivas_split_rend_huff_pred63_consts[IVAS_SPLIT_REND_PRED_63QUANT_PNTS][3] = -{ - {-31,11,2040}, - {-30,11,2041}, - {-29,11,2042}, - {-28,11,2043}, - {-27,10,1012}, - {-26,10,1013}, - {-25,10,1014}, - {-24,10,1015}, - {-23,9,498}, - {-22,9,499}, - {-21,9,500}, - {-20,9,501}, - {-19,8,242}, - {-18,8,243}, - {-17,8,244}, - {-16,8,245}, - {-15,7,112}, - {-14,7,113}, - {-13,7,114}, - {-12,7,115}, - {-11,6,48}, - {-10,6,49}, - {-9,6,50}, - {-8,6,51}, - {-7,5,16}, - {-6,5,17}, - {-5,5,18}, - {-4,5,19}, - {-3,4,2}, - {-2,4,3}, - {-1,4,4}, - {0,3,0}, - {1,4,5}, - {2,4,6}, - {3,4,7}, - {4,5,20}, - {5,5,21}, - {6,5,22}, - {7,5,23}, - {8,6,52}, - {9,6,53}, - {10,6,54}, - {11,6,55}, - {12,7,116}, - {13,7,117}, - {14,7,118}, - {15,7,119}, - {16,7,120}, - {17,8,246}, - {18,8,247}, - {19,8,248}, - {20,9,502}, - {21,9,503}, - {22,9,504}, - {23,9,505}, - {24,10,1016}, - {25,10,1017}, - {26,10,1018}, - {27,10,1019}, - {28,11,2044}, - {29,11,2045}, - {30,11,2046}, - {31,11,2047}, -}; - -const int32_t ivas_split_rend_huff_pred31_consts[IVAS_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}, - {-7,6,56},{-6,6,57},{-5,5,24},{-4,5,25},{-3,4,8}, - {-2,4,9},{-1,3,2},{0,2,0},{1,3,3}, - {2,4,10},{3,4,11},{4,5,26},{5,5,27}, - {6,6,58},{7,6,59},{8,7,122},{9,7,123}, - {10,7,124},{11,8,252},{12,9,508},{13,9,509}, - {14,10,1022},{15,10,1023}, -}; - -const int32_t ivas_split_rend_huff_roll_pred_consts[IVAS_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}, - {-7,6,56},{-6,6,57},{-5,5,24},{-4,5,25},{-3,4,8}, - {-2,4,9},{-1,3,2},{0,2,0},{1,3,3}, - {2,4,10},{3,4,11},{4,5,26},{5,5,27}, - {6,6,58},{7,6,59},{8,7,122},{9,7,123}, - {10,7,124},{11,8,252},{12,9,508},{13,9,509}, -{14,10,1022},{15,10,1023}, -}; - -#endif - - /*----------------------------------------------------------------------* * MC ParamUpmix ROM tables *-----------------------------------------------------------------------*/ diff --git a/lib_dec/ivas_rom_dec.h b/lib_dec/ivas_rom_dec.h index 46bc99352..16655db6c 100644 --- a/lib_dec/ivas_rom_dec.h +++ b/lib_dec/ivas_rom_dec.h @@ -103,32 +103,6 @@ extern const float dirac_dithering_ele_scale[DIRAC_DIFFUSE_LEVELS]; extern const float dmxmtx_table[BINAURAL_CHANNELS][11]; -#ifdef SPLIT_REND_WITH_HEAD_ROT -/*----------------------------------------------------------------------* - * Binuaral split rendering ROM tables - *-----------------------------------------------------------------------*/ - -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 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 ivas_split_rend_relative_pos_angles[MAX_HEAD_ROT_POSES][3]; -extern const int16_t ivas_split_rend_band_grouping[MAX_SPLIT_REND_MD_BANDS + 1]; -extern const int32_t ivas_split_rend_huff_d_consts[IVAS_SPLIT_REND_D_QUANT_PNTS][3]; -extern const int32_t ivas_split_rend_huff_pred63_consts[IVAS_SPLIT_REND_PRED_31QUANT_PNTS][3]; -extern const int32_t ivas_split_rend_huff_pred31_consts[IVAS_SPLIT_REND_PRED_31QUANT_PNTS][3]; -extern const int32_t ivas_split_rend_huff_roll_pred_consts[IVAS_SPLIT_REND_ROLL_PRED_QUANT_PNTS][3]; -extern const int32_t ivas_split_rend_huff_p_d_consts[IVAS_SPLIT_REND_D_QUANT_PNTS][3]; -extern const int32_t ivas_split_rend_huff_p_d_diff_consts[IVAS_SPLIT_REND_D_QUANT_PNTS][3]; -extern const int32_t split_rend_brate_tbl[]; -#endif - /*----------------------------------------------------------------------* * MC ParamUpmix ROM tables diff --git a/lib_dec/ivas_stat_dec.h b/lib_dec/ivas_stat_dec.h index 684d4b3e3..4ef289373 100644 --- a/lib_dec/ivas_stat_dec.h +++ b/lib_dec/ivas_stat_dec.h @@ -40,6 +40,7 @@ #include "stat_dec.h" #include "ivas_stat_com.h" #include "ivas_stat_rend.h" +#include "isar_stat.h" /*----------------------------------------------------------------------------------* @@ -837,6 +838,36 @@ typedef struct ivas_binaural_rendering_struct } BINAURAL_RENDERER, *BINAURAL_RENDERER_HANDLE; #endif +#ifdef SPLIT_REND_WITH_HEAD_ROT +/*----------------------------------------------------------------------------------* + * IVAS decoder specific ISAR wrapper structures + *----------------------------------------------------------------------------------*/ + +typedef struct +{ + 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]; + +} ISAR_DEC_SPLIT_REND_MULTI_BIN_CLDFB_DATA, *ISAR_DEC_SPLIT_REND_MULTI_BIN_CLDFB_DATA_HANDLE; + +typedef struct +{ + float Cldfb_RealBuffer[MAX_OUTPUT_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + float Cldfb_ImagBuffer[MAX_OUTPUT_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; + IVAS_AUDIO_CONFIG config; + +} ISAR_DEC_SPLIT_REND_CLDFB_OUT_DATA, *ISAR_DEC_SPLIT_REND_CLDFB_OUT_DATA_HANDLE; + +typedef struct +{ + ISAR_DEC_SPLIT_REND_MULTI_BIN_CLDFB_DATA_HANDLE hMultiBinCldfbData; /*scratch buffer for frame by frame processing*/ + ISAR_SPLIT_REND_BITS_HANDLE hSplitRendBits; /*scratch buffer for frame by frame processing*/ + SPLIT_REND_WRAPPER splitrend; + ISAR_DEC_SPLIT_REND_CLDFB_OUT_DATA_HANDLE hCldfbDataOut; /*buffer to store cldfb data before binauralization*/ + int16_t numTdSamplesPerChannelCached; + +} ISAR_DEC_SPLIT_REND_WRAPPER, *ISAR_DEC_SPLIT_REND_WRAPPER_HANDLE; +#endif /*----------------------------------------------------------------------------------* * MASA decoder structures @@ -953,39 +984,6 @@ typedef struct jbm_metadata_structure } JBM_METADATA, *JBM_METADATA_HANDLE; -#ifdef SPLIT_REND_WITH_HEAD_ROT -/*----------------------------------------------------------------------------------* - * Split rendering structures - *----------------------------------------------------------------------------------*/ - -typedef struct -{ - 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]; - -} IVAS_DEC_SPLIT_REND_MULTI_BIN_CLDFB_DATA, *IVAS_DEC_SPLIT_REND_MULTI_BIN_CLDFB_DATA_HANDLE; - -typedef struct -{ - float Cldfb_RealBuffer[MAX_OUTPUT_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; - float Cldfb_ImagBuffer[MAX_OUTPUT_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; - AUDIO_CONFIG config; - -} IVAS_DEC_SPLIT_REND_CLDFB_OUT_DATA, *IVAS_DEC_SPLIT_REND_CLDFB_OUT_DATA_HANDLE; - -typedef struct -{ - IVAS_DEC_SPLIT_REND_MULTI_BIN_CLDFB_DATA_HANDLE hMultiBinCldfbData; /*scratch buffer for frame by frame processing*/ - IVAS_SPLIT_REND_BITS_HANDLE hSplitRendBits; /*scratch buffer for frame by frame processing*/ - SPLIT_REND_WRAPPER splitrend; - IVAS_DEC_SPLIT_REND_CLDFB_OUT_DATA_HANDLE hCldfbDataOut; /*buffer to store cldfb data before binauralization*/ - float *tdDataOut; /*buffer to store TD data before binauralization*/ - int16_t numTdSamplesPerChannelCached; - -} IVAS_DEC_SPLIT_REND_WRAPPER; -#endif - - /*----------------------------------------------------------------------------------* * Decoder configuration structure *----------------------------------------------------------------------------------*/ @@ -1125,7 +1123,8 @@ typedef struct Decoder_Struct int16_t flag_omasa_brate; #ifdef SPLIT_REND_WITH_HEAD_ROT - IVAS_DEC_SPLIT_REND_WRAPPER hSplitBinRend; /* split binuaral rendering handle */ + ISAR_DEC_SPLIT_REND_WRAPPER_HANDLE hSplitBinRend; /* ISAR split binaural rendering handle */ + BINAURAL_TD_OBJECT_RENDERER_HANDLE hTdRendHandles[MAX_HEAD_ROT_POSES - 1]; #endif /* JBM module */ diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index 65babe812..20ea61a1b 100644 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -34,6 +34,8 @@ #include "ivas_cnst.h" #include "ivas_prot.h" #include "ivas_prot_rend.h" +#include "isar_prot.h" +#include "lib_isar_pre_rend.h" #include "prot.h" #include "jbm_jb4sb.h" #include "jbm_pcmdsp_apa.h" @@ -123,6 +125,9 @@ static ivas_error IVAS_DEC_GetBufferedNumberOfSamples( IVAS_DEC_HANDLE hIvasDec, static PCM_RESOLUTION pcm_type_API_to_internal( const IVAS_DEC_PCM_TYPE pcmType ); static void *pcm_buffer_offset( void *buffer, const IVAS_DEC_PCM_TYPE pcmType, const int32_t offset ); static ivas_error set_pcm_buffer_to_zero( void *buffer, const IVAS_DEC_PCM_TYPE pcmType, const int16_t nZeroSamples ); +static ivas_error isar_set_split_rend_setup( ISAR_DEC_SPLIT_REND_WRAPPER *hSplitBinRend, const ISAR_SPLIT_REND_CONFIG_DATA *hSplitBinConfig, const COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, ISAR_SPLIT_REND_BITS_DATA *splitRendBits ); +static ivas_error ivas_create_handle_isar( ISAR_DEC_SPLIT_REND_WRAPPER_HANDLE *hSplitBinRend_out ); +static void ivas_destroy_handle_isar( ISAR_DEC_SPLIT_REND_WRAPPER_HANDLE *hSplitBinRend_out ); #endif static int16_t get_render_frame_size_ms( IVAS_RENDER_FRAMESIZE render_framesize ); @@ -244,6 +249,46 @@ ivas_error IVAS_DEC_Open( return IVAS_ERR_WRONG_PARAMS; } +#ifdef SPLIT_REND_WITH_HEAD_ROT +/*-------------------------------------------------------------------------* + * isar_set_split_rend_setup() + * + * Setup IVAS split rendering + *-------------------------------------------------------------------------*/ + +static ivas_error isar_set_split_rend_setup( + ISAR_DEC_SPLIT_REND_WRAPPER *hSplitBinRend, + const ISAR_SPLIT_REND_CONFIG_DATA *hSplitBinConfig, + const COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, + ISAR_SPLIT_REND_BITS_DATA *splitRendBits /* o : output split rendering bits */ +) +{ + splitRendBits->bits_read = 0; + splitRendBits->bits_written = 0; + splitRendBits->buf_len = ISAR_MAX_SPLIT_REND_BITS_BUFFER_SIZE_IN_BYTES; + splitRendBits->codec = ISAR_SPLIT_REND_CODEC_DEFAULT; + splitRendBits->pose_correction = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE; + splitRendBits->codec_frame_size_ms = 0; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + splitRendBits->isar_frame_size_ms = 0; + splitRendBits->lc3plus_highres = 0; +#endif + + if ( ( hSplitBinRend->hMultiBinCldfbData = (ISAR_DEC_SPLIT_REND_MULTI_BIN_CLDFB_DATA_HANDLE) malloc( sizeof( ISAR_DEC_SPLIT_REND_MULTI_BIN_CLDFB_DATA ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for split rendering structure" ); + } + + ISAR_PRE_REND_GetMultiBinPoseData( hSplitBinConfig, &hSplitBinRend->splitrend.multiBinPoseData, ( hCombinedOrientationData != NULL ) ? hCombinedOrientationData->sr_pose_pred_axis : DEFAULT_AXIS ); + + if ( hCombinedOrientationData != NULL ) + { + isar_set_split_rend_ht_setup( &hSplitBinRend->splitrend, hCombinedOrientationData->Quaternions, hCombinedOrientationData->Rmat ); + } + + return IVAS_ERR_OK; +} +#endif /*---------------------------------------------------------------------* * init_decoder_config() @@ -300,6 +345,11 @@ void IVAS_DEC_Close( ( *phIvasDec )->hVoIP = NULL; } +#ifdef SPLIT_REND_WITH_HEAD_ROT + /* destroy Split binaural renderer (ISAR) handle */ + ivas_destroy_handle_isar( &( *phIvasDec )->st_ivas->hSplitBinRend ); +#endif + if ( ( *phIvasDec )->st_ivas ) { ivas_destroy_dec( ( *phIvasDec )->st_ivas ); @@ -464,6 +514,17 @@ ivas_error IVAS_DEC_Configure( return error; } +#ifdef SPLIT_REND_WITH_HEAD_ROT + /* create ISAR handle */ + if ( hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + { + if ( ( error = ivas_create_handle_isar( &st_ivas->hSplitBinRend ) ) != IVAS_ERR_OK ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for ISAR handle" ); + } + } +#endif + if ( hIvasDec->mode == IVAS_DEC_MODE_EVS ) { hIvasDec->st_ivas->ivas_format = MONO_FORMAT; @@ -544,6 +605,15 @@ ivas_error IVAS_DEC_SetRenderFramesize( hIvasDec->st_ivas->hDecoderConfig->render_framesize = render_framesize; + if ( hIvasDec->st_ivas->hExtOrientationData != NULL ) + { + hIvasDec->st_ivas->hExtOrientationData->num_subframes = (int16_t) render_framesize; + } + if ( hIvasDec->st_ivas->hCombinedOrientationData != NULL ) + { + hIvasDec->st_ivas->hCombinedOrientationData->num_subframes = (int16_t) render_framesize; + } + return IVAS_ERR_OK; } @@ -876,9 +946,9 @@ ivas_error IVAS_DEC_GetSamples( * Binaural split rendering setup *----------------------------------------------------------------*/ - 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 ) + 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 ) ) { - ivas_set_split_rend_ht_setup( &hIvasDec->st_ivas->hSplitBinRend, hIvasDec->st_ivas->hCombinedOrientationData ); + isar_set_split_rend_ht_setup( &hIvasDec->st_ivas->hSplitBinRend->splitrend, hIvasDec->st_ivas->hCombinedOrientationData->Quaternions, hIvasDec->st_ivas->hCombinedOrientationData->Rmat ); } #endif @@ -924,9 +994,6 @@ ivas_error IVAS_DEC_GetSamples( { return error; } -#ifdef SPLIT_REND_WITH_HEAD_ROT - /* :TODO: change nSamplesAsked also if we are in 5ms 0dof split rendering... */ -#endif } { /* check if we need to run the setup function, tc decoding and feeding the renderer */ @@ -1026,31 +1093,32 @@ ivas_error IVAS_DEC_GetSamples( *---------------------------------------------------------------------*/ ivas_error IVAS_DEC_GetSplitBinauralBitstream( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - void *pcmBuf_out, /* o : output synthesis signal for BINAURAL_SPLIT_PCM */ - uint8_t *splitRendBitsBuf, /* o : output split rendering bits */ - int16_t *nOutSamples, /* o : number of samples per channel written to output buffer */ - bool *needNewFrame /* o : indication that the decoder needs a new frame */ + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + void *pcmBuf_out, /* o : output synthesis signal for BINAURAL_SPLIT_PCM */ + ISAR_SPLIT_REND_BITS_DATA *splitRendBits, /* o : output split rendering bits */ + int16_t *nOutSamples, /* o : number of samples per channel written to output buffer */ + bool *needNewFrame /* o : indication that the decoder needs a new frame */ ) { Decoder_Struct *st_ivas; AUDIO_CONFIG output_config; int32_t output_Fs; - float *writePtr; - float *readPtr, *readEnd; float *pOutput[BINAURAL_CHANNELS * MAX_HEAD_ROT_POSES]; float output[BINAURAL_CHANNELS * MAX_HEAD_ROT_POSES][L_FRAME48k]; float pcmBuf[BINAURAL_CHANNELS * MAX_HEAD_ROT_POSES * L_FRAME48k]; - int16_t numSamplesPerChannelCacheSize; + 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]; int16_t numSamplesPerChannelToDecode; - int16_t numSamplesPerChannelToSplitEncode; int16_t i, j; ivas_error error; - IVAS_DEC_SPLIT_REND_WRAPPER *hSplitBinRend; + ISAR_DEC_SPLIT_REND_WRAPPER_HANDLE hSplitBinRend; int16_t max_band; int16_t pcm_out_flag; int16_t td_input; int16_t numPoses; + int16_t slots_rendered, slots_rendered_new; + int16_t ro_md_flag; + IVAS_QUATERNION Quaternion; error = IVAS_ERR_OK; st_ivas = hIvasDec->st_ivas; @@ -1059,85 +1127,54 @@ ivas_error IVAS_DEC_GetSplitBinauralBitstream( numSamplesPerChannelToDecode = (int16_t) ( output_Fs / FRAMES_PER_SEC ); *needNewFrame = false; - hSplitBinRend = &st_ivas->hSplitBinRend; + hSplitBinRend = st_ivas->hSplitBinRend; - if ( ( error = ivas_set_split_rend_setup( hSplitBinRend, &st_ivas->hRenderConfig->split_rend_config, st_ivas->hCombinedOrientationData, splitRendBitsBuf ) ) != IVAS_ERR_OK ) + if ( ( error = isar_set_split_rend_setup( hSplitBinRend, &st_ivas->hRenderConfig->split_rend_config, st_ivas->hCombinedOrientationData, splitRendBits ) ) != IVAS_ERR_OK ) { return error; } numPoses = hSplitBinRend->splitrend.multiBinPoseData.num_poses; - if ( st_ivas->hDecoderConfig->render_framesize == IVAS_RENDER_FRAMESIZE_5MS && hIvasDec->st_ivas->hRenderConfig->split_rend_config.codec == IVAS_SPLIT_REND_CODEC_LC3PLUS && - ( hIvasDec->st_ivas->hRenderConfig->split_rend_config.poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE || + if ( st_ivas->hDecoderConfig->render_framesize != IVAS_RENDER_FRAMESIZE_20MS && + ( hIvasDec->st_ivas->hRenderConfig->split_rend_config.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE || hIvasDec->st_ivas->hRenderConfig->split_rend_config.dof == 0 ) ) { - numSamplesPerChannelToSplitEncode = (int16_t) ( output_Fs / FRAMES_PER_SEC / MAX_PARAM_SPATIAL_SUBFRAMES ); - numSamplesPerChannelCacheSize = numSamplesPerChannelToDecode - numSamplesPerChannelToSplitEncode; - - if ( hSplitBinRend->tdDataOut == NULL ) - { - /* Allocate enough space to save all decoded samples that will not be split encoded directly after decoding */ - if ( ( hSplitBinRend->tdDataOut = malloc( numSamplesPerChannelCacheSize * BINAURAL_CHANNELS * numPoses * sizeof( float ) ) ) == NULL ) - { - return IVAS_ERR_FAILED_ALLOC; - } - } - } - else - { - numSamplesPerChannelToSplitEncode = (int16_t) ( output_Fs / FRAMES_PER_SEC ); - numSamplesPerChannelCacheSize = 0; + numSamplesPerChannelToDecode = (int16_t) ( output_Fs / FRAMES_PER_SEC / MAX_PARAM_SPATIAL_SUBFRAMES ); + numSamplesPerChannelToDecode *= (int16_t) st_ivas->hDecoderConfig->render_framesize; } - if ( output_config != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED && output_config != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) + if ( IVAS_DEC_is_split_rendering_enabled( hIvasDec ) == 0 ) { return IVAS_ERR_WRONG_PARAMS; } - if ( numSamplesPerChannelToDecode == numSamplesPerChannelToSplitEncode || hSplitBinRend->numTdSamplesPerChannelCached == 0 ) + if ( st_ivas->hTcBuffer == NULL || hIvasDec->hasBeenFedFrame ) + { + slots_rendered = 0; + } + else { - /* Decode and render */ - if ( ( error = IVAS_DEC_GetSamples( hIvasDec, numSamplesPerChannelToDecode, IVAS_DEC_PCM_FLOAT, pcmBuf, nOutSamples, needNewFrame ) ) != IVAS_ERR_OK ) + /* this is needed for OMASA-DISC, because the td-rend granularity is 240 samples at 48kHz, leading to wrong slot count. */ + if ( st_ivas->ivas_format == MASA_ISM_FORMAT && st_ivas->ism_mode == ISM_MASA_MODE_DISC ) { - return error; + slots_rendered = st_ivas->hTcBuffer->n_samples_rendered / NS2SA( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ); } -#ifdef DEBUGGING - assert( numSamplesPerChannelToDecode == *nOutSamples ); -#endif - - /* copy to cache if cache is in use */ - if ( hSplitBinRend->tdDataOut != NULL ) + else { - writePtr = hSplitBinRend->tdDataOut; - readPtr = pcmBuf + numSamplesPerChannelToSplitEncode * BINAURAL_CHANNELS * numPoses; - readEnd = pcmBuf + *nOutSamples * BINAURAL_CHANNELS * numPoses; - - while ( readPtr != readEnd ) - { - *writePtr++ = *readPtr++; - } - hSplitBinRend->numTdSamplesPerChannelCached = *nOutSamples - numSamplesPerChannelToSplitEncode; + slots_rendered = st_ivas->hTcBuffer->n_samples_rendered / st_ivas->hTcBuffer->n_samples_granularity; } } - else - { - /* copy from cache */ - assert( hSplitBinRend->tdDataOut != NULL ); - readPtr = hSplitBinRend->tdDataOut + ( numSamplesPerChannelCacheSize - hSplitBinRend->numTdSamplesPerChannelCached ) * BINAURAL_CHANNELS * numPoses; - readEnd = readPtr + numSamplesPerChannelToSplitEncode * BINAURAL_CHANNELS * numPoses; - writePtr = pcmBuf; - while ( readPtr != readEnd ) - { - *writePtr++ = *readPtr++; - } - hSplitBinRend->numTdSamplesPerChannelCached -= numSamplesPerChannelToSplitEncode; + /* Decode and render */ + if ( ( error = IVAS_DEC_GetSamples( hIvasDec, numSamplesPerChannelToDecode, IVAS_DEC_PCM_FLOAT, pcmBuf, nOutSamples, needNewFrame ) ) != IVAS_ERR_OK ) + { + return error; } /* change buffer layout */ - for ( i = 0; i < numSamplesPerChannelToSplitEncode; ++i ) + for ( i = 0; i < numSamplesPerChannelToDecode; ++i ) { for ( j = 0; j < BINAURAL_CHANNELS * numPoses; ++j ) { @@ -1149,19 +1186,69 @@ ivas_error IVAS_DEC_GetSplitBinauralBitstream( pOutput[i] = output[i]; } + if ( st_ivas->hTcBuffer == NULL ) + { + slots_rendered_new = 0; + } + else + { + /* this is needed for OMASA-DISC, because the td-rend granularity is 240 samples at 48kHz, leading to wrong slot count. */ + if ( st_ivas->ivas_format == MASA_ISM_FORMAT && st_ivas->ism_mode == ISM_MASA_MODE_DISC ) + { + slots_rendered_new = st_ivas->hTcBuffer->n_samples_rendered / NS2SA( st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS ); + } + else + { + slots_rendered_new = st_ivas->hTcBuffer->n_samples_rendered / st_ivas->hTcBuffer->n_samples_granularity; + } + } + + for ( i = 0; i < BINAURAL_CHANNELS * numPoses; ++i ) + { + for ( j = slots_rendered; j < slots_rendered_new; ++j ) + { + mvr2r( hSplitBinRend->hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[i][j], Cldfb_RealBuffer_Binaural[i][j - slots_rendered], CLDFB_NO_CHANNELS_MAX ); + mvr2r( hSplitBinRend->hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[i][j], Cldfb_ImagBuffer_Binaural[i][j - slots_rendered], CLDFB_NO_CHANNELS_MAX ); + } + } + max_band = (int16_t) ( ( BINAURAL_MAXBANDS * output_Fs ) / 48000 ); pcm_out_flag = ( output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0; td_input = st_ivas->renderer_type != RENDERER_BINAURAL_FASTCONV && st_ivas->renderer_type != RENDERER_BINAURAL_PARAMETRIC && st_ivas->renderer_type != RENDERER_BINAURAL_PARAMETRIC_ROOM && st_ivas->renderer_type != RENDERER_STEREO_PARAMETRIC; - if ( ( error = ivas_renderMultiBinToSplitBinaural( &hSplitBinRend->splitrend, - st_ivas->hHeadTrackData->Quaternions[0], - st_ivas->hRenderConfig->split_rend_config.splitRendBitRate, - st_ivas->hRenderConfig->split_rend_config.codec, - st_ivas->hRenderConfig->split_rend_config.codec_frame_size_ms, - hSplitBinRend->hSplitRendBits, - hSplitBinRend->hMultiBinCldfbData->Cldfb_RealBuffer_Binaural, - hSplitBinRend->hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural, - max_band, pOutput, 1, !td_input, pcm_out_flag ) ) != IVAS_ERR_OK ) + if ( st_ivas->hBinRendererTd != NULL ) + { + ro_md_flag = 1; + } + else + { + ro_md_flag = 0; + } + + if ( st_ivas->hHeadTrackData != NULL ) + { + Quaternion = st_ivas->hHeadTrackData->Quaternions[0]; + } + else + { + Quaternion.w = -3.0f; + Quaternion.x = 0.0f; + Quaternion.y = 0.0f; + Quaternion.z = 0.0f; + } + if ( ( error = ISAR_PRE_REND_MultiBinToSplitBinaural( &hSplitBinRend->splitrend, + Quaternion, + st_ivas->hRenderConfig->split_rend_config.splitRendBitRate, + st_ivas->hRenderConfig->split_rend_config.codec, +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + st_ivas->hRenderConfig->split_rend_config.isar_frame_size_ms, +#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 ) + { return error; } @@ -1172,21 +1259,21 @@ ivas_error IVAS_DEC_GetSplitBinauralBitstream( if ( st_ivas->hDecoderConfig->render_framesize == IVAS_RENDER_FRAMESIZE_5MS ) { #ifndef DISABLE_LIMITER - ivas_limiter_dec( st_ivas->hLimiter, pOutput, st_ivas->hDecoderConfig->nchan_out, numSamplesPerChannelToSplitEncode, st_ivas->BER_detect ); + ivas_limiter_dec( st_ivas->hLimiter, pOutput, st_ivas->hDecoderConfig->nchan_out, numSamplesPerChannelToDecode, st_ivas->BER_detect ); #endif } else { - ivas_limiter_dec( st_ivas->hLimiter, pOutput, st_ivas->hDecoderConfig->nchan_out, numSamplesPerChannelToSplitEncode, st_ivas->BER_detect ); + ivas_limiter_dec( st_ivas->hLimiter, pOutput, st_ivas->hDecoderConfig->nchan_out, numSamplesPerChannelToDecode, st_ivas->BER_detect ); } #ifdef DEBUGGING st_ivas->noClipping += #endif - ivas_syn_output( pOutput, numSamplesPerChannelToSplitEncode, st_ivas->hDecoderConfig->nchan_out, (int16_t *) pcmBuf_out ); + ivas_syn_output( pOutput, numSamplesPerChannelToDecode, st_ivas->hDecoderConfig->nchan_out, (int16_t *) pcmBuf_out ); } - free( st_ivas->hSplitBinRend.hMultiBinCldfbData ); + free( st_ivas->hSplitBinRend->hMultiBinCldfbData ); return error; } @@ -1357,7 +1444,7 @@ static ivas_error IVAS_DEC_GetRenderedSamples( uint16_t *nSamplesRendered, /* o : number of samples rendered */ uint16_t *nSamplesAvailableNext, /* o : number of samples still available in the renerer pipeline */ #ifdef SPLIT_REND_WITH_HEAD_ROT - IVAS_DEC_PCM_TYPE pcmType, + const IVAS_DEC_PCM_TYPE pcmType, void *pcmBuf #else int16_t *pcmBuf @@ -1659,7 +1746,7 @@ ivas_error IVAS_DEC_FeedHeadTrackData( IVAS_VECTOR3 Pos, /* i : listener position */ #ifdef SPLIT_REND_WITH_HEAD_ROT const int16_t subframe_idx, /* i : subframe index */ - const IVAS_SPLIT_REND_ROT_AXIS rot_axis /* i : external control for rotation axis for split rendering */ + const ISAR_SPLIT_REND_ROT_AXIS rot_axis /* i : external control for rotation axis for split rendering */ #else const int16_t subframe_idx /* i : subframe index */ #endif @@ -1989,14 +2076,22 @@ 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; hRCout->split_rend_config.codec_delay_ms = 0; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + hRCout->split_rend_config.isar_frame_size_ms = 20; +#endif hRCout->split_rend_config.codec_frame_size_ms = 0; /* 0 means "use default for selected codec" */ - hRCout->split_rend_config.codec = IVAS_SPLIT_REND_CODEC_DEFAULT; - hRCout->split_rend_config.poseCorrectionMode = IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB; + hRCout->split_rend_config.codec = ISAR_SPLIT_REND_CODEC_DEFAULT; + hRCout->split_rend_config.poseCorrectionMode = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB; hRCout->split_rend_config.rendererSelection = hRCin->split_rend_config.rendererSelection; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + hRCout->split_rend_config.lc3plus_highres = hRCin->split_rend_config.lc3plus_highres; +#endif #endif hRCout->roomAcoustics.use_er = hRCin->roomAcoustics.use_er; hRCout->roomAcoustics.lowComplexity = hRCin->roomAcoustics.lowComplexity; @@ -2103,10 +2198,10 @@ ivas_error IVAS_DEC_FeedRenderConfig( /* Overwrite any pose correction settings if 0 DOF (no pose correction) was selected */ if ( hRenderConfig->split_rend_config.dof == 0 ) { - hRenderConfig->split_rend_config.poseCorrectionMode = IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE; + hRenderConfig->split_rend_config.poseCorrectionMode = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE; } - if ( ( error = ivas_split_rend_validate_config( &hRenderConfig->split_rend_config, ( hIvasDec->st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0 ) ) != IVAS_ERR_OK ) + if ( ( error = isar_split_rend_validate_config( &hRenderConfig->split_rend_config, ( hIvasDec->st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0 ) ) != IVAS_ERR_OK ) { return error; } @@ -2417,7 +2512,7 @@ ivas_error IVAS_DEC_VoIP_GetSamples( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ uint16_t nSamplesPerChannel, /* i : number of samples per channel requested to be written to output buffer */ #ifdef SPLIT_REND_WITH_HEAD_ROT - IVAS_DEC_PCM_TYPE pcmType, + const IVAS_DEC_PCM_TYPE pcmType, void *pcmBuf, #else int16_t *pcmBuf, /* i/o: buffer for decoded PCM output. The memory must already be allocated and be able to hold the expected number of output samples, based on frame size and number of output channels */ @@ -3566,30 +3661,37 @@ static ivas_error IVAS_DEC_VoIP_reconfigure( #ifdef SPLIT_REND_WITH_HEAD_ROT /*---------------------------------------------------------------------* - * IVAS_DEC_GetSplitRendBits() + * IVAS_DEC_GetSplitRendBitstreamHeader() * * *---------------------------------------------------------------------*/ -/*! r: decoder error code */ -ivas_error IVAS_DEC_GetSplitRendBits( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - IVAS_SPLIT_REND_BITS_HANDLE splitRendBits /* o : split rendering Bits structue */ +ivas_error IVAS_DEC_GetSplitRendBitstreamHeader( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + ISAR_SPLIT_REND_CODEC *pCodec, /* o: pointer to codec setting */ + ISAR_SPLIT_REND_POSE_CORRECTION_MODE *poseCorrection, /* o: pointer to pose correction mode */ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + int16_t *pIsar_frame_size_ms, /* o: pointer to isar frame size setting */ +#endif + int16_t *pCodec_frame_size_ms /* o: pointer to codec frame size setting */ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + , + int16_t *pLc3plusHighRes +#endif ) { - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL /*|| hIvasDec->st_ivas->hSplitBinRend == NULL */ ) + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) { return IVAS_ERR_UNEXPECTED_NULL_POINTER; } - splitRendBits->bits_buf = hIvasDec->st_ivas->hSplitBinRend.hSplitRendBits->bits_buf; - splitRendBits->bits_read = hIvasDec->st_ivas->hSplitBinRend.hSplitRendBits->bits_read; - splitRendBits->bits_written = hIvasDec->st_ivas->hSplitBinRend.hSplitRendBits->bits_written; - splitRendBits->buf_len = hIvasDec->st_ivas->hSplitBinRend.hSplitRendBits->buf_len; - splitRendBits->codec = hIvasDec->st_ivas->hSplitBinRend.hSplitRendBits->codec; - splitRendBits->pose_correction = hIvasDec->st_ivas->hSplitBinRend.hSplitRendBits->pose_correction; - splitRendBits->codec_frame_size_ms = hIvasDec->st_ivas->hSplitBinRend.hSplitRendBits->codec_frame_size_ms; - + *pCodec = hIvasDec->st_ivas->hRenderConfig->split_rend_config.codec; + *pCodec_frame_size_ms = hIvasDec->st_ivas->hRenderConfig->split_rend_config.codec_frame_size_ms; + *poseCorrection = hIvasDec->st_ivas->hRenderConfig->split_rend_config.poseCorrectionMode; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + *pIsar_frame_size_ms = hIvasDec->st_ivas->hRenderConfig->split_rend_config.isar_frame_size_ms; + *pLc3plusHighRes = hIvasDec->st_ivas->hRenderConfig->split_rend_config.lc3plus_highres; +#endif return IVAS_ERR_OK; } @@ -3597,10 +3699,9 @@ ivas_error IVAS_DEC_GetSplitRendBits( /*---------------------------------------------------------------------* * IVAS_DEC_GetCldfbSamples() * - * + * API function to output CLDFB samples *---------------------------------------------------------------------*/ -// ToDo: currently unused ivas_error IVAS_DEC_GetCldfbSamples( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ float *out_real, /* o : buffer for decoded PCM real output in CLDFB domain */ @@ -3609,24 +3710,24 @@ ivas_error IVAS_DEC_GetCldfbSamples( int16_t *nOutSamples /* o : number of samples per channel written to output buffer */ ) { - Decoder_Struct *st_ivas; + ISAR_DEC_SPLIT_REND_WRAPPER_HANDLE hSplitBinRend; int16_t ch, b, slot_idx, num_chs, maxBand, num_samples; - if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL || hIvasDec->st_ivas->hSplitBinRend == NULL ) { return IVAS_ERR_UNEXPECTED_NULL_POINTER; } - st_ivas = hIvasDec->st_ivas; + hSplitBinRend = hIvasDec->st_ivas->hSplitBinRend; num_samples = 0; - if ( st_ivas->hSplitBinRend.hCldfbDataOut != NULL ) + if ( hSplitBinRend->hCldfbDataOut != NULL ) { - *audio_config = st_ivas->hSplitBinRend.hCldfbDataOut->config; - if ( st_ivas->hSplitBinRend.hCldfbDataOut->config != IVAS_AUDIO_CONFIG_INVALID ) + *audio_config = hSplitBinRend->hCldfbDataOut->config; + if ( hSplitBinRend->hCldfbDataOut->config != IVAS_AUDIO_CONFIG_INVALID ) { - num_chs = audioCfg2channels( st_ivas->hSplitBinRend.hCldfbDataOut->config ); - maxBand = (int16_t) ( ( CLDFB_NO_CHANNELS_MAX * st_ivas->hDecoderConfig->output_Fs ) / 48000 ); + num_chs = audioCfg2channels( hSplitBinRend->hCldfbDataOut->config ); + maxBand = (int16_t) ( ( CLDFB_NO_CHANNELS_MAX * hIvasDec->st_ivas->hDecoderConfig->output_Fs ) / 48000 ); for ( slot_idx = 0; slot_idx < CLDFB_NO_COL_MAX; slot_idx++ ) { @@ -3634,8 +3735,8 @@ ivas_error IVAS_DEC_GetCldfbSamples( { for ( ch = 0; ch < num_chs; ch++ ) { - *out_real++ = st_ivas->hSplitBinRend.hCldfbDataOut->Cldfb_RealBuffer[ch][slot_idx][b]; - *out_imag++ = st_ivas->hSplitBinRend.hCldfbDataOut->Cldfb_ImagBuffer[ch][slot_idx][b]; + *out_real++ = hSplitBinRend->hCldfbDataOut->Cldfb_RealBuffer[ch][slot_idx][b]; + *out_imag++ = hSplitBinRend->hCldfbDataOut->Cldfb_ImagBuffer[ch][slot_idx][b]; } } } @@ -3651,10 +3752,8 @@ ivas_error IVAS_DEC_GetCldfbSamples( return IVAS_ERR_OK; } -#endif -#ifdef SPLIT_REND_WITH_HEAD_ROT /*---------------------------------------------------------------------* * pcm_buffer_offset() * @@ -3681,8 +3780,10 @@ static void *pcm_buffer_offset( } break; default: - return NULL; + break; } + + return NULL; } @@ -3699,6 +3800,7 @@ static ivas_error set_pcm_buffer_to_zero( { ivas_error error; + error = IVAS_ERR_OK; switch ( pcmType ) { case IVAS_DEC_PCM_FLOAT: @@ -3711,7 +3813,7 @@ static ivas_error set_pcm_buffer_to_zero( error = IVAS_ERR_INTERNAL; } - return IVAS_ERR_OK; + return error; } @@ -3742,4 +3844,117 @@ PCM_RESOLUTION pcm_type_API_to_internal( return pcm_resolution; } + +/*-------------------------------------------------------------------* + * ivas_create_handle_isar() + * + * Initialize IVAS decoder split rend handle + *-------------------------------------------------------------------*/ + +static ivas_error ivas_create_handle_isar( + ISAR_DEC_SPLIT_REND_WRAPPER_HANDLE *hSplitBinRend_out /* o : ISAR split binaural rendering handle */ +) +{ + ISAR_DEC_SPLIT_REND_WRAPPER_HANDLE hSplitBinRend; + + if ( ( hSplitBinRend = (ISAR_DEC_SPLIT_REND_WRAPPER_HANDLE) malloc( sizeof( ISAR_DEC_SPLIT_REND_WRAPPER ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for IVAS decoder handle" ); + } + + isar_init_split_rend_handles( &hSplitBinRend->splitrend ); + + hSplitBinRend->hMultiBinCldfbData = NULL; + hSplitBinRend->hCldfbDataOut = NULL; + hSplitBinRend->numTdSamplesPerChannelCached = 0; + + *hSplitBinRend_out = hSplitBinRend; + + return IVAS_ERR_OK; +} + + +/*-------------------------------------------------------------------* + * ivas_destroy_handle_isar() + * + * destroy IVAS decoder split rend handle + *-------------------------------------------------------------------*/ + +static void ivas_destroy_handle_isar( + ISAR_DEC_SPLIT_REND_WRAPPER_HANDLE *hSplitBinRend /* i/o: ISAR split binaural rendering handle */ +) +{ + if ( *hSplitBinRend != NULL ) + { + ISAR_PRE_REND_close( &( *hSplitBinRend )->splitrend, NULL ); + + if ( ( *hSplitBinRend )->hCldfbDataOut != NULL ) + { + free( ( *hSplitBinRend )->hCldfbDataOut ); + ( *hSplitBinRend )->hCldfbDataOut = NULL; + } + } + + return; +} + + +/*---------------------------------------------------------------------* + * IVAS_DEC_is_split_rendering_enabled() + * + * + *---------------------------------------------------------------------*/ + +int16_t IVAS_DEC_is_split_rendering_enabled( + IVAS_DEC_HANDLE hIvasDec /* i/o: IVAS decoder handle */ +) +{ + Decoder_Struct *st_ivas; + int16_t isSplitRend; + + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + st_ivas = hIvasDec->st_ivas; + isSplitRend = 0; + + if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM || + ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_STEREO && st_ivas->hDecoderConfig->Opt_non_diegetic_pan && st_ivas->hRenderConfig->split_rend_config.dof == 0 ) ) + { + isSplitRend = 1; + } + + return isSplitRend; +} + + +/*---------------------------------------------------------------------* + * IVAS_DEC_is_split_rendering_coded_out() + * + * + *---------------------------------------------------------------------*/ + +int16_t IVAS_DEC_is_split_rendering_coded_out( + IVAS_DEC_HANDLE hIvasDec /* i/o: IVAS decoder handle */ +) +{ + Decoder_Struct *st_ivas; + int16_t isSplitCoded; + + if ( hIvasDec == NULL || hIvasDec->st_ivas == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + st_ivas = hIvasDec->st_ivas; + isSplitCoded = 0; + + if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || + ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_STEREO && st_ivas->hDecoderConfig->Opt_non_diegetic_pan && st_ivas->hRenderConfig->split_rend_config.dof == 0 ) ) + { + isSplitCoded = 1; + } + + return isSplitCoded; +} #endif diff --git a/lib_dec/lib_dec.h b/lib_dec/lib_dec.h index 5ed4da72d..1f1a63cd1 100644 --- a/lib_dec/lib_dec.h +++ b/lib_dec/lib_dec.h @@ -172,15 +172,24 @@ ivas_error IVAS_DEC_GetSamples( ivas_error IVAS_DEC_GetSplitBinauralBitstream( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ void *pcmBuf_out, /* o : output synthesis signal for BINAURAL_SPLIT_PCM */ - uint8_t *splitRendBitsBuf, /* o : output split rendering bits */ + ISAR_SPLIT_REND_BITS_DATA *splitRendBits, /* o : output split rendering bits */ int16_t *nOutSamples, /* o : number of samples per channel written to output buffer */ bool *needNewFrame /* o : indication that the decoder needs a new frame */ ); /*! r: decoder error code */ -ivas_error IVAS_DEC_GetSplitRendBits( - IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ - IVAS_SPLIT_REND_BITS_HANDLE splitRendBits /* o : split rendering Bits structure */ +ivas_error IVAS_DEC_GetSplitRendBitstreamHeader( + IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ + ISAR_SPLIT_REND_CODEC *pCodec, /* o: pointer to codec setting */ + ISAR_SPLIT_REND_POSE_CORRECTION_MODE *poseCorrection, /* o: pointer to pose correction mode */ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + int16_t *pIsar_frame_size_ms, /* o: pointer to isar frame size setting */ +#endif + int16_t *pCodec_frame_size_ms /* o: pointer to codec frame size setting */ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + , + int16_t *pLc3plusHighRes /* o: pointer to LC3plus High-Res setting */ +#endif ); /*! r: decoder error code */ @@ -191,6 +200,13 @@ ivas_error IVAS_DEC_GetCldfbSamples( IVAS_AUDIO_CONFIG *audio_config, /* o : audio configuration */ int16_t *nOutSamples /* o : number of samples per channel written to output buffer */ ); + +int16_t IVAS_DEC_is_split_rendering_enabled( + IVAS_DEC_HANDLE hIvasDec /* i: IVAS decoder handle */ +); +int16_t IVAS_DEC_is_split_rendering_coded_out( + IVAS_DEC_HANDLE hIvasDec /* i/o: IVAS decoder handle */ +); #endif /*! r: error code */ @@ -215,7 +231,7 @@ ivas_error IVAS_DEC_FeedHeadTrackData( IVAS_VECTOR3 Pos, /* i : listener position */ #ifdef SPLIT_REND_WITH_HEAD_ROT const int16_t subframe_idx, /* i : subframe index */ - IVAS_SPLIT_REND_ROT_AXIS rot_axis /* i : external control for rotation axis for split rendering */ + const ISAR_SPLIT_REND_ROT_AXIS rot_axis /* i : external control for rotation axis for split rendering */ #else const int16_t subframe_idx /* i : subframe index */ #endif @@ -272,7 +288,7 @@ ivas_error IVAS_DEC_VoIP_GetSamples( IVAS_DEC_HANDLE hIvasDec, /* i/o: IVAS decoder handle */ uint16_t nSamplesPerChannel, /* i : number of samples per channel requested to be written to output buffer */ #ifdef SPLIT_REND_WITH_HEAD_ROT - IVAS_DEC_PCM_TYPE pcmType, + const IVAS_DEC_PCM_TYPE pcmType, void *pcmBuf, #else int16_t *pcmBuf, /* i/o: buffer for decoded PCM output. The memory must already be allocated and be able to hold the expected number of output samples, based on frame size and number of output channels */ diff --git a/lib_rend/ivas_MSPred.c b/lib_rend/ivas_MSPred.c deleted file mode 100644 index 4dcdbbb1c..000000000 --- a/lib_rend/ivas_MSPred.c +++ /dev/null @@ -1,564 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2023 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. - -*******************************************************************************************************/ - -#include "options.h" -#include -#ifdef SPLIT_REND_WITH_HEAD_ROT -#include "ivas_lcld_rom_tables.h" -#include "ivas_lcld_prot.h" -#include "ivas_prot_rend.h" -#include "wmc_auto.h" - - -/*-------------------------------------------------------------------* - * Function _round() - * - * - *-------------------------------------------------------------------*/ - -static int32_t _round( - float val ) -{ - return ( val > 0.0f ? (int32_t) ( val + 0.5f ) : (int32_t) ( val - 0.5f ) ); -} - - -/*-------------------------------------------------------------------* - * Function quantPhase() - * - * - *-------------------------------------------------------------------*/ - -int32_t quantPhase( - float phase ) -{ -#ifdef SIMPLE_PHASE - int32_t phaseQ; - if ( phase < 0.0f ) - { - phase += 2.0f * _PI_; - } - phaseQ = _round( phase * SIMPLE_PHASE_QUANT_FACTOR ); - phaseQ = ( phaseQ > SIMPLE_PHASE_MAX_VAL ? SIMPLE_PHASE_MIN_VAL : phaseQ ); -#else - int32_t phaseQ; - - phaseQ = _round( phase * PHASE_QUANT_FACTOR ); - if ( phaseQ == PHASE_MAX_VAL ) - { - phaseQ = PHASE_MIN_VAL; - } -#endif - return phaseQ; -} - -#ifdef SIMPLE_PHASE -/*-------------------------------------------------------------------* - * Function rot_pm_pi() - * - * - *-------------------------------------------------------------------*/ - -void rot_pm_pi( - float *pr, - float *pi ) -{ - /* (-1 + j0) */ - *pr = -( *pr ); - *pi = -( *pi ); - - return; -} - - -/*-------------------------------------------------------------------* - * Function ApplyInversePredictros() - * - * - *-------------------------------------------------------------------*/ - -void rot_p_pi_2( - float *pr, - float *pi ) -{ - /* (0 + j) */ - float r = *pr; - - *pr = -( *pi ); - *pi = r; - - return; -} - -/*-------------------------------------------------------------------* - * Function rot_zero() - * - * - *-------------------------------------------------------------------*/ - -void rot_zero( - float *pr, - float *pi ) -{ - *pr = *pr; - *pi = *pi; - - return; -} - -/*-------------------------------------------------------------------* - * Function rot_m_pi_2() - * - * - *-------------------------------------------------------------------*/ - -void rot_m_pi_2( - float *pr, - float *pi ) -{ - /* (0 - j) */ - float r = *pr; - - *pr = *pi; - *pi = -r; - - return; -} -#endif - -/*-------------------------------------------------------------------* - * Function cplxmult() - * - * - *-------------------------------------------------------------------*/ - -void cplxmult( - float *pr1, - float *pi1, - float r2, - float i2 ) -{ - float r1 = *pr1, i1 = *pi1; - - *pr1 = r1 * r2 - i1 * i2; - *pi1 = r1 * i2 + i1 * r2; - - return; -} - - -/*-------------------------------------------------------------------* - * Function requantPhase() - * - * - *-------------------------------------------------------------------*/ - -int32_t requantPhase( - int32_t phaseQ ) -{ - - if ( phaseQ >= PHASE_MAX_VAL ) - { - phaseQ += PHASE_MAX_VAL; - phaseQ %= ( 2 * PHASE_MAX_VAL ); - phaseQ -= PHASE_MAX_VAL; - } - else if ( phaseQ < PHASE_MIN_VAL ) - { - phaseQ -= PHASE_MAX_VAL; - phaseQ %= ( 2 * PHASE_MAX_VAL ); - phaseQ += PHASE_MAX_VAL; - if ( phaseQ == PHASE_MAX_VAL ) - { - phaseQ = PHASE_MIN_VAL; - } - } - - return phaseQ; -} - - -/*-------------------------------------------------------------------* - * Function quantPred() - * - * - *-------------------------------------------------------------------*/ - -int32_t quantPred( - const float pred ) -{ - int32_t predQ = _round( pred * PRED_QUANT_FACTOR ); - predQ = predQ > PRED_MAX_VAL ? PRED_MAX_VAL : predQ; - predQ = predQ < PRED_MIN_VAL ? PRED_MIN_VAL : predQ; - - return predQ; -} - - -/*-------------------------------------------------------------------* - * Function dequantPhase() - * - * - *-------------------------------------------------------------------*/ - -float dequantPhase( - const int32_t phaseQ ) -{ -#ifdef SIMPLE_PHASE - return (float) phaseQ / SIMPLE_PHASE_QUANT_FACTOR; -#else - return (float) phaseQ / PHASE_QUANT_FACTOR; -#endif -} - - -/*-------------------------------------------------------------------* - * Function dequantPred() - * - * - *-------------------------------------------------------------------*/ - -float dequantPred( int32_t predQ ) -{ - return (float) predQ / PRED_QUANT_FACTOR; -} - - -/*-------------------------------------------------------------------* - * Function PrepEncode() - * - * - *-------------------------------------------------------------------*/ - -int32_t PrepEncode( - int32_t *piQuant, - const int32_t *piMSFlags, - const int32_t numBands ) -{ - int32_t b, numMSBands = 0; - - for ( b = 0; b < numBands; b++ ) - { - if ( piMSFlags[b] ) - { - piQuant[numMSBands++] = piQuant[b]; - } - } - - for ( b = numMSBands; b < numBands; b++ ) - { - piQuant[b] = 0; - } - - return numMSBands; -} - - -/*-------------------------------------------------------------------* - * Function EncodePhase() - * - * - *-------------------------------------------------------------------*/ - -void EncodePhase( - int32_t *phaseQuant, - const int32_t numMSBands, - const int32_t diffDim ) -{ - int32_t b; - - if ( diffDim > 0 ) - { - int32_t tmp1, tmp2; - tmp1 = phaseQuant[0]; - for ( b = 1; b < numMSBands; b++ ) - { - tmp2 = phaseQuant[b]; - phaseQuant[b] -= tmp1; - tmp1 = tmp2; - } - } - - if ( diffDim > 1 ) - { - int32_t tmp1, tmp2; - tmp1 = phaseQuant[1]; - for ( b = 2; b < numMSBands; b++ ) - { - tmp2 = phaseQuant[b]; - phaseQuant[b] -= tmp1; - tmp1 = tmp2; - } - } - for ( b = 1; b < numMSBands; b++ ) - { - phaseQuant[b] = requantPhase( phaseQuant[b] ); - } - - return; -} - - -/*-------------------------------------------------------------------* - * Function DecodePhase() - * - * - *-------------------------------------------------------------------*/ - -void DecodePhase( - int32_t *phaseQuant, - const int32_t numMSBands, - const int32_t diffDim ) -{ - int32_t b; - - if ( diffDim > 1 ) - { - for ( b = 2; b < numMSBands; b++ ) - { - phaseQuant[b] += phaseQuant[b - 1]; - } - } - - if ( diffDim > 0 ) - { - for ( b = 1; b < numMSBands; b++ ) - { - phaseQuant[b] += phaseQuant[b - 1]; - } - } - - for ( b = 1; b < numMSBands; b++ ) - { - phaseQuant[b] = requantPhase( phaseQuant[b] ); - } - - return; -} - - -/*-------------------------------------------------------------------* - * Function EncodePredCoef() - * - * - *-------------------------------------------------------------------*/ - -int32_t EncodePredCoef( - int32_t *predQuant, - const int32_t numMSBands ) -{ - int32_t b, tmp1, tmp2; - - tmp1 = predQuant[0]; - for ( b = 1; b < numMSBands; b++ ) - { - tmp2 = predQuant[b]; - predQuant[b] -= tmp1; - tmp1 = tmp2; - } - - return numMSBands; -} - - -/*-------------------------------------------------------------------* - * Function DecodePredCoef() - * - * - *-------------------------------------------------------------------*/ - -void DecodePredCoef( - int32_t *phaseQuant, - const int32_t numMSBands ) -{ - int32_t b; - - for ( b = 1; b < numMSBands; b++ ) - { - phaseQuant[b] += phaseQuant[b - 1]; - } - - return; -} - - -/*-------------------------------------------------------------------* - * Function CountMSBits() - * - * - *-------------------------------------------------------------------*/ - -int32_t CountMSBits( - int32_t iNumBands, - const int32_t iMSMode, - const int32_t *piMSFlags, - const int32_t *piLRPhaseDiff, - const int32_t *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++ ) - { - piPhaseCopy[b] = 0; - piPredCopy[b] = 0; - } - - iBitsWritten += 2; /* iMSMode */ - for ( b = 0; b < iNumBands; b++ ) - { - iNumMSBands += ( piMSFlags[b] != 0 ); - } - - if ( iNumMSBands == 0 ) - { - return iBitsWritten; - } - - if ( iNumMSBands < iNumBands ) - { - iBitsWritten += iNumBands; /* piMSFlags */ - } - - if ( iMSMode < 3 ) - { - return iBitsWritten; - } - - /* prepare arrays for coding evaluation */ - for ( b = 0; b < iNumBands; b++ ) - { - piPhaseCopy[b] = piLRPhaseDiff[b]; - piPredCopy[b] = piMSPredCoef[b]; - } - - /* Differential Coding of Phase Data*/ - PrepEncode( piPhaseCopy, piMSFlags, iNumBands ); - PrepEncode( piPredCopy, piMSFlags, iNumBands ); -#ifndef SIMPLE_PHASE - EncodePhase( piPhaseCopy, iNumMSBands, PHASE_DIFF_DIM ); -#endif - EncodePredCoef( piPredCopy, iNumMSBands ); - - iBitsWritten += 1; /* iMSPredAll */ - anyNonZero = 0; /* phase */ - for ( b = 0; b < iNumMSBands; b++ ) - { - if ( piPhaseCopy[b] != 0 ) - { - anyNonZero = 1; - break; - } - } - iBitsWritten++; /*anyNonZero Phase*/ - if ( anyNonZero ) - { -#ifdef SIMPLE_PHASE - iBitsWritten += iNumMSBands * SIMPLE_PHASE_BITS; -#else - iBitsWritten += PHASE_BAND0_BITS; - for ( b = 1; b < iNumMSBands; b++ ) - { - int32_t tabIdx = piPhaseCopy[b] - ENV_DELTA_MIN; - iBitsWritten += c_aaiRMSEnvHuffEnc[tabIdx][0]; - } -#endif - } - anyNonZero = 0; /* prediction */ - for ( b = 0; b < iNumMSBands; b++ ) - { - if ( piPredCopy[b] != 0 ) - { - anyNonZero = 1; - break; - } - } - - iBitsWritten++; /* any nonZero Pred */ - if ( anyNonZero ) - { - iBitsWritten += PRED_BAND0_BITS; - for ( b = 1; b < iNumMSBands; b++ ) - { - int32_t tabIdx = piPredCopy[b] - ENV_DELTA_MIN; - iBitsWritten += c_aaiRMSEnvHuffEnc[tabIdx][0]; - } - } - - return iBitsWritten; -} - - -#ifdef DEBUG_WRITE_MS_PRED -void writeMSPred( - int32_t *phaseQuant, - int32_t *predQuant, - int32_t MSMode, - int32_t numMSBands, - int32_t numBands, - void *fid, - int32_t *piMsFlags ) -{ - int32_t b; - - fid = (FILE *) fid; - fprintf( fid, "%d %d", MSMode, numMSBands ); - for ( b = 0; b < numMSBands; b++ ) - { - fprintf( fid, " %d", phaseQuant[b] ); - } - for ( b = numMSBands; b < numBands; b++ ) - { - fprintf( fid, " %d", 0 ); - } - for ( b = 0; b < numMSBands; b++ ) - { - fprintf( fid, " %d", predQuant[b] ); - } - for ( b = numMSBands; b < numBands; b++ ) - { - fprintf( fid, " %d", 0 ); - } - for ( b = 0; b < numBands; b++ ) - { - fprintf( fid, " %d", piMsFlags[b] ); - } - fprintf( fid, "\n" ); - - return; -} -#endif -#endif diff --git a/lib_rend/ivas_NoiseGen.c b/lib_rend/ivas_NoiseGen.c deleted file mode 100644 index e4a24fabd..000000000 --- a/lib_rend/ivas_NoiseGen.c +++ /dev/null @@ -1,100 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2023 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. - -*******************************************************************************************************/ - -#include -#include "options.h" -#ifdef SPLIT_REND_WITH_HEAD_ROT -#include -#include "prot.h" -#include "ivas_lcld_prot.h" -#include "ivas_prot_rend.h" -#include "wmc_auto.h" - - -/*------------------------------------------------------------------------------------------* - * Function CreateNoiseGen() - * - * - *------------------------------------------------------------------------------------------*/ -// todo: not used!! -NoiseGen *CreateNoiseGen( void ) -{ - int32_t n; - - NoiseGen *psNoiseGen = NULL; - - psNoiseGen = (NoiseGen *) malloc( sizeof( NoiseGen ) ); - psNoiseGen->iNoiseBufferLength = 2048; - psNoiseGen->iNoiseBufferMask = 2047; - psNoiseGen->iNoiseBufferIndex = 0; - - psNoiseGen->pfNoiseBuffer = (float *) malloc( psNoiseGen->iNoiseBufferLength * sizeof( float ) ); - - /* Generate Laplacian distributed noise */ - for ( n = 0; n < psNoiseGen->iNoiseBufferLength; n++ ) - { - float fNoise = 0.0f; - float fScale = 0.707f; - fNoise = (float) ( ( rand() & ( RAND_MAX - 1 ) ) - ( RAND_MAX >> 1 ) ) / (float) RAND_MAX; - - if ( fNoise < 0.0 ) - { - fNoise = fScale * (float) logf( 1.0f + 1.9999999f * fNoise ); - } - else - { - fNoise = -fScale * (float) logf( 1.0f - 1.9999999f * fNoise ); - } - - psNoiseGen->pfNoiseBuffer[n] = fNoise; - } - - return psNoiseGen; -} - - -/*------------------------------------------------------------------------------------------* - * Function DeleteNoiseGen() - * - * - *------------------------------------------------------------------------------------------*/ - -void DeleteNoiseGen( NoiseGen *psNoiseGen ) -{ - free( psNoiseGen->pfNoiseBuffer ); - free( psNoiseGen ); - - return; -} - -extern float GetNoise( NoiseGen *psNoiseGen ); -#endif diff --git a/lib_rend/ivas_PerceptualModel.c b/lib_rend/ivas_PerceptualModel.c deleted file mode 100644 index 4250a4fe8..000000000 --- a/lib_rend/ivas_PerceptualModel.c +++ /dev/null @@ -1,257 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2023 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. - -*******************************************************************************************************/ - -#include -#include "options.h" -#ifdef SPLIT_REND_WITH_HEAD_ROT -#include "ivas_lcld_prot.h" -#include "prot.h" -#include "ivas_prot_rend.h" -#include "ivas_lcld_rom_tables.h" -#include -#include "wmc_auto.h" - - -/*------------------------------------------------------------------------------------------* - * Local constants - *------------------------------------------------------------------------------------------*/ - -#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 int32_t LogAdd( - const int32_t iVal1, - const int32_t iVal2 ) -{ - int32_t iRetVal; - - if ( iVal1 > iVal2 ) - { - iRetVal = iVal1 - iVal2; - iRetVal = ( iRetVal < ( LOG_ADD_TABLE_LENGTH - 1 ) ) ? iRetVal : ( LOG_ADD_TABLE_LENGTH - 1 ); - iRetVal = iVal1 + c_aiLogAddTable[iRetVal]; - } - else - { - iRetVal = iVal2 - iVal1; - iRetVal = ( iRetVal < ( LOG_ADD_TABLE_LENGTH - 1 ) ) ? iRetVal : ( LOG_ADD_TABLE_LENGTH - 1 ); - iRetVal = iVal2 + c_aiLogAddTable[iRetVal]; - } - - return iRetVal; -} - - -/*------------------------------------------------------------------------------------------* - * Function PerceptualModel() - * - * - *------------------------------------------------------------------------------------------*/ - -void PerceptualModel( - const int32_t iMaxQuantBands, - const int32_t *piRMSEnvelope, - int32_t *piExcitation, - int32_t *piSMR ) -{ - int32_t n; - - for ( n = 0; n < iMaxQuantBands; n++ ) - { - int32_t iSLOffset; - - piExcitation[n] = PERCEPTUAL_MODEL_SCALE * piRMSEnvelope[n] + c_aiBandwidthAdjust48[n]; - - /* 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; - - /* Convert to loudness domain (x^0.3) */ - piExcitation[n] = PERCEPTUAL_MODEL_ALPHA_SCALE * piExcitation[n] >> PERCEPTUAL_MODEL_ALPHA_SHIFT; - } - - /* Spread excitation function */ - for ( n = 0; n < iMaxQuantBands; n++ ) - { - int32_t k; - const int32_t *piSpread; - - piSpread = &c_aaiSpreadFunction48[n * MAX_BANDS_48]; - piSMR[n] = piExcitation[n] + piSpread[n]; - for ( k = 0; k < iMaxQuantBands; k++ ) - { - if ( k != n ) - { - piSMR[n] = LogAdd( piSMR[n], piExcitation[k] + piSpread[k] ); - } - } - } - - for ( n = 0; n < iMaxQuantBands; n++ ) - { - piSMR[n] = PERCEPTUAL_MODEL_ALPHA_INV_SCALE * piSMR[n] >> PERCEPTUAL_MODEL_ALPHA_SHIFT; - piSMR[n] = PERCEPTUAL_MODEL_SCALE * piRMSEnvelope[n] + c_aiBandwidthAdjust48[n] - piSMR[n]; - } - - return; -} - - -/*------------------------------------------------------------------------------------------* - * Function PerceptualModelStereo() - * - * - *------------------------------------------------------------------------------------------*/ - -void PerceptualModelStereo( - const int32_t iMaxQuantBands, - const int32_t *piMSFlags, - const int32_t *piRMSEnvelope0, - const int32_t *piRMSEnvelope1, - int32_t *piExcitation0, - int32_t *piExcitation1, - int32_t *piSMR0, - int32_t *piSMR1 ) -{ - int32_t n; - - for ( n = 0; n < iMaxQuantBands; n++ ) - { - int32_t iMaxRMSEnv; - int32_t iSLOffset; - - iMaxRMSEnv = piRMSEnvelope0[n]; - - piExcitation0[n] = PERCEPTUAL_MODEL_SCALE * iMaxRMSEnv + c_aiBandwidthAdjust48[n]; /* piRMSEnvelope0[n] */ - - /* 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; - - /* Convert to loudness domain (x^0.3) */ - piExcitation0[n] = PERCEPTUAL_MODEL_ALPHA_SCALE * piExcitation0[n] >> PERCEPTUAL_MODEL_ALPHA_SHIFT; - } - - /* Spread excitation function */ - for ( n = 0; n < iMaxQuantBands; n++ ) - { - int32_t k; - const int32_t *piSpread; - - piSpread = &c_aaiSpreadFunction48[n * MAX_BANDS_48]; - piSMR0[n] = piExcitation0[n] + piSpread[n]; - for ( k = 0; k < iMaxQuantBands; k++ ) - { - if ( k != n ) - { - piSMR0[n] = LogAdd( piSMR0[n], piExcitation0[k] + piSpread[k] ); - } - } - } - - for ( n = 0; n < iMaxQuantBands; n++ ) - { - int32_t iMaxRMSEnv; - int32_t iSLOffset; - - iMaxRMSEnv = piRMSEnvelope1[n]; - - piExcitation1[n] = PERCEPTUAL_MODEL_SCALE * iMaxRMSEnv + c_aiBandwidthAdjust48[n]; /* piRMSEnvelope1[n] */ - - /* 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; - - /* Convert to loudness domain (x^0.3) */ - piExcitation1[n] = PERCEPTUAL_MODEL_ALPHA_SCALE * piExcitation1[n] >> PERCEPTUAL_MODEL_ALPHA_SHIFT; - } - - /* Spread excitation function */ - for ( n = 0; n < iMaxQuantBands; n++ ) - { - int32_t k; - const int32_t *piSpread; - - piSpread = &c_aaiSpreadFunction48[n * MAX_BANDS_48]; - piSMR1[n] = piExcitation1[n] + piSpread[n]; - for ( k = 0; k < iMaxQuantBands; k++ ) - { - if ( k != n ) - { - piSMR1[n] = LogAdd( piSMR1[n], piExcitation1[k] + piSpread[k] ); - } - } - } - - for ( n = 0; n < iMaxQuantBands; n++ ) - { - if ( piMSFlags[n] == 1 ) - { - piSMR0[n] = ( piSMR0[n] > piSMR1[n] ) ? piSMR0[n] : piSMR1[n]; - piSMR1[n] = piSMR0[n]; - } - } - - for ( n = 0; n < iMaxQuantBands; n++ ) - { - piSMR0[n] = PERCEPTUAL_MODEL_ALPHA_INV_SCALE * piSMR0[n] >> PERCEPTUAL_MODEL_ALPHA_SHIFT; - piSMR0[n] = PERCEPTUAL_MODEL_SCALE * piRMSEnvelope0[n] + c_aiBandwidthAdjust48[n] - piSMR0[n]; - } - - for ( n = 0; n < iMaxQuantBands; n++ ) - { - piSMR1[n] = PERCEPTUAL_MODEL_ALPHA_INV_SCALE * piSMR1[n] >> PERCEPTUAL_MODEL_ALPHA_SHIFT; - piSMR1[n] = PERCEPTUAL_MODEL_SCALE * piRMSEnvelope1[n] + c_aiBandwidthAdjust48[n] - piSMR1[n]; - } - - return; -} -#endif diff --git a/lib_rend/ivas_PredDecoder.c b/lib_rend/ivas_PredDecoder.c deleted file mode 100644 index 914435e2f..000000000 --- a/lib_rend/ivas_PredDecoder.c +++ /dev/null @@ -1,335 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2023 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. - -*******************************************************************************************************/ - -#include -#include "options.h" -#ifdef SPLIT_REND_WITH_HEAD_ROT -#include -#include "prot.h" -#include "ivas_prot_rend.h" -#include "ivas_lcld_prot.h" -#include "ivas_lcld_rom_tables.h" -#include "wmc_auto.h" - - -/*-------------------------------------------------------------------* - * Function CreatePredictionDecoder() - * - * - *-------------------------------------------------------------------*/ - -ivas_error CreatePredictionDecoder( - PredictionDecoder **psPredictionDecoder_out, - const int32_t iChannels, - const int32_t iNumBlocks ) -{ - int16_t n; - PredictionDecoder *psPredictionDecoder = 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; - psPredictionDecoder->iNumBlocks = iNumBlocks; - - if ( ( psPredictionDecoder->piPredChanEnable = (int32_t *) malloc( sizeof( int32_t ) * iChannels ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); - } - if ( ( psPredictionDecoder->piNumPredBands = (int32_t *) malloc( sizeof( int32_t ) * iChannels ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); - } - - if ( ( psPredictionDecoder->ppfEstPredGain = (float **) malloc( sizeof( float * ) * 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 ) - { - 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 ) - { - 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 ) - { - 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 ) - { - 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 ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); - } - - for ( n = 0; n < psPredictionDecoder->iChannels; n++ ) - { - if ( ( psPredictionDecoder->ppfEstPredGain[n] = (float *) malloc( sizeof( float ) * LCLD_BANDS ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); - } - if ( ( psPredictionDecoder->ppiPredBandEnable[n] = (int32_t *) malloc( sizeof( int32_t ) * LCLD_BANDS ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); - } - if ( ( psPredictionDecoder->ppfA1Real[n] = (float *) malloc( sizeof( float ) * 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 ) - { - 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 ) - { - 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 ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); - } - } - - /* pre-define these tables? */ - 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 ); - } - - 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_out = psPredictionDecoder; - - return IVAS_ERR_OK; -} - - -/*-------------------------------------------------------------------* - * Function DeletePredictionDecoder() - * - * - *-------------------------------------------------------------------*/ - -void DeletePredictionDecoder( - PredictionDecoder *psPredictionDecoder ) -{ - int32_t n; - - for ( n = 0; n < psPredictionDecoder->iChannels; n++ ) - { - free( psPredictionDecoder->ppfEstPredGain[n] ); - free( psPredictionDecoder->ppiPredBandEnable[n] ); - free( psPredictionDecoder->ppfA1Real[n] ); - free( psPredictionDecoder->ppfA1Imag[n] ); - free( psPredictionDecoder->ppiA1Mag[n] ); - free( psPredictionDecoder->ppiA1Phase[n] ); - } - free( psPredictionDecoder->piPredChanEnable ); - free( psPredictionDecoder->piNumPredBands ); - free( psPredictionDecoder->ppfEstPredGain ); - free( psPredictionDecoder->ppiPredBandEnable ); - free( psPredictionDecoder->ppfA1Real ); - free( psPredictionDecoder->ppfA1Imag ); - free( psPredictionDecoder->ppiA1Mag ); - free( psPredictionDecoder->ppiA1Phase ); - - free( psPredictionDecoder ); - psPredictionDecoder = NULL; - - return; -} - - -#define USE_TABLE_LOOKUP -/*-------------------------------------------------------------------* - * Function ReadPredictors() - * - * - *-------------------------------------------------------------------*/ - -int32_t ReadPredictors( - PredictionDecoder *psPredictionDecoder, - IVAS_SPLIT_REND_BITS_HANDLE pBits ) -{ - int16_t iBitsRead = 0; - int32_t c; - - for ( c = 0; c < psPredictionDecoder->iChannels; c++ ) - { - psPredictionDecoder->piPredChanEnable[c] = ivas_split_rend_bitstream_read_int32( pBits, 1 ); - iBitsRead += 1; - - if ( psPredictionDecoder->piPredChanEnable[c] ) - { - int32_t b; - - for ( b = 0; b < LCLD_BANDS; b++ ) - { - psPredictionDecoder->ppiPredBandEnable[c][b] = 0; - } - psPredictionDecoder->piNumPredBands[c] = ivas_split_rend_bitstream_read_int32( pBits, 6 ); - iBitsRead += 6; - - for ( b = 0; b < psPredictionDecoder->piNumPredBands[c]; b++ ) - { - psPredictionDecoder->ppiPredBandEnable[c][b] = ivas_split_rend_bitstream_read_int32( pBits, 1 ); - iBitsRead += 1; - - if ( psPredictionDecoder->ppiPredBandEnable[c][b] == 1 ) - { -#ifdef USE_TABLE_LOOKUP - int32_t iA1Mag; - int32_t iA1Phase; - float fA1Real; - float fA1Imag; - iA1Mag = ivas_split_rend_bitstream_read_int32( pBits, PRED_QUNAT_FILTER_MAG_BITS ); - iBitsRead += PRED_QUNAT_FILTER_MAG_BITS; - iA1Phase = ivas_split_rend_bitstream_read_int32( pBits, PRED_QUANT_FILTER_PHASE_BITS ); - iBitsRead += PRED_QUANT_FILTER_PHASE_BITS; - - psPredictionDecoder->ppiA1Mag[c][b] = iA1Mag; - psPredictionDecoder->ppiA1Phase[c][b] = iA1Phase + PRED_QUANT_FILTER_PHASE_MIN; - - fA1Real = psPredictionDecoder->pfMagLUT[iA1Mag] * psPredictionDecoder->pfP2RRealLUT[iA1Phase]; - fA1Imag = psPredictionDecoder->pfMagLUT[iA1Mag] * psPredictionDecoder->pfP2RImagLUT[iA1Phase]; - - psPredictionDecoder->ppfA1Real[c][b] = fA1Real; - psPredictionDecoder->ppfA1Imag[c][b] = fA1Imag; -#else - const float fInvMagScale = M_PI / ( 2.0 * (float) ( 1 << ( PRED_QUNAT_FILTER_MAG_BITS ) ) + 1.0 ); - const float fInvPhaseScale = M_PI / (float) ( 1 << ( PRED_QUANT_FILTER_PHASE_BITS - 1 ) ); - int32_t iA1Mag; - int32_t iA1Phase; - float fA1Mag; - float fA1Phase; - float fA1Real; - float fA1Imag; - - iA1Mag = ivas_split_rend_bitstream_read_int32( pBits, PRED_QUNAT_FILTER_MAG_BITS ); - iBitsRead += PRED_QUNAT_FILTER_MAG_BITS; - - iA1Phase = ivas_split_rend_bitstream_read_int32( pBits, PRED_QUANT_FILTER_PHASE_BITS ); - iBitsRead += PRED_QUANT_FILTER_PHASE_BITS; - iA1Phase += PRED_QUANT_FILTER_PHASE_MIN; - - psPredictionDecoder->ppiA1Mag[c][b] = iA1Mag; - psPredictionDecoder->ppiA1Phase[c][b] = iA1Phase; - - fA1Mag = sinf( fInvMagScale * (float) iA1Mag ); - fA1Phase = fInvPhaseScale * (float) iA1Phase; - - fA1Real = fA1Mag * cosf( fA1Phase ); - fA1Imag = fA1Mag * sinf( fA1Phase ); - - psPredictionDecoder->ppfA1Real[c][b] = fA1Real; - psPredictionDecoder->ppfA1Imag[c][b] = fA1Imag; - - /* printf("Dec %f\t%f\t%f\n",fA1Real,fA1Imag,fA1Real * fA1Real + fA1Imag * fA1Imag); */ -#endif - } - } - } - else - { - int16_t b; - for ( b = 0; b < LCLD_BANDS; b++ ) - { - psPredictionDecoder->ppiPredBandEnable[c][b] = 0; - } - } - } - - return iBitsRead; -} - - -/*-------------------------------------------------------------------* - * Function ApplyInversePredictros() - * - * - *-------------------------------------------------------------------*/ - -void ApplyInversePredictros( - PredictionDecoder *psPredictionDecoder, - float ***pppfReal, - float ***pppfImag ) -{ - int32_t c; - for ( c = 0; c < psPredictionDecoder->iChannels; c++ ) - { - if ( psPredictionDecoder->piPredChanEnable[c] == 1 ) - { - int32_t b; - for ( b = 0; b < psPredictionDecoder->piNumPredBands[c]; b++ ) - { - if ( psPredictionDecoder->ppiPredBandEnable[c][b] == 1 ) - { - int32_t n; - float fA1Real; - float fA1Imag; - - fA1Real = psPredictionDecoder->ppfA1Real[c][b]; - fA1Imag = psPredictionDecoder->ppfA1Imag[c][b]; - for ( n = 1; n < psPredictionDecoder->iNumBlocks; n++ ) - { - float fReal; - float fImag; - - fReal = pppfReal[c][n][b] - fA1Real * pppfReal[c][n - 1][b] + fA1Imag * pppfImag[c][n - 1][b]; - fImag = pppfImag[c][n][b] - fA1Real * pppfImag[c][n - 1][b] - fA1Imag * pppfReal[c][n - 1][b]; - - pppfReal[c][n][b] = fReal; - pppfImag[c][n][b] = fImag; - } - } - } - } - } - - return; -} -#endif diff --git a/lib_rend/ivas_PredEncoder.c b/lib_rend/ivas_PredEncoder.c deleted file mode 100644 index 804a00a6a..000000000 --- a/lib_rend/ivas_PredEncoder.c +++ /dev/null @@ -1,531 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2023 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. - -*******************************************************************************************************/ - -#include -#include "options.h" -#ifdef SPLIT_REND_WITH_HEAD_ROT -#include -#include "ivas_lcld_prot.h" -#include "ivas_lcld_rom_tables.h" -#include "prot.h" -#include "ivas_prot_rend.h" -#include "wmc_auto.h" - - -/*-------------------------------------------------------------------* - * Function CreatePredictionEncoder() - * - * - *-------------------------------------------------------------------*/ - -ivas_error CreatePredictionEncoder( - PredictionEncoder **psPredictionEncoder_out, - const int32_t iChannels, - const int32_t iNumBlocks ) -{ - int32_t 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; - psPredictionEncoder->iNumBlocks = iNumBlocks; - - if ( ( psPredictionEncoder->pfWindow = (float *) malloc( sizeof( float ) * iNumBlocks ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); - } - for ( n = 0; n < iNumBlocks; n++ ) - { - psPredictionEncoder->pfWindow[n] = 0.54f - 0.46f * cosf( 2.0f * M_PI * ( (float) n + 0.5f ) / (float) iNumBlocks ); - } - - if ( ( psPredictionEncoder->piPredChanEnable = (int32_t *) malloc( sizeof( int32_t ) * iChannels ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); - } - - if ( ( psPredictionEncoder->piNumPredBands = (int32_t *) malloc( sizeof( int32_t ) * 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; - psPredictionEncoder->piNumPredBands[n] = 40; // Will need to be set correctly - } - - if ( ( psPredictionEncoder->ppfEstPredGain = (float **) malloc( sizeof( float * ) * iChannels ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); - } - if ( ( psPredictionEncoder->ppfEstPredBitGain = (float **) malloc( sizeof( float * ) * iChannels ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); - } - if ( ( psPredictionEncoder->ppiPredBandEnable = (int32_t **) malloc( sizeof( int32_t * ) * iChannels ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); - } - if ( ( psPredictionEncoder->ppfA1Real = (float **) malloc( sizeof( float * ) * iChannels ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); - } - if ( ( psPredictionEncoder->ppfA1Imag = (float **) malloc( sizeof( float * ) * iChannels ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); - } - if ( ( psPredictionEncoder->ppiA1Mag = (int32_t **) malloc( sizeof( int32_t * ) * iChannels ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); - } - if ( ( psPredictionEncoder->ppiA1Phase = (int32_t **) malloc( sizeof( int32_t * ) * 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->ppfEstPredGain[n] = (float *) malloc( sizeof( float ) * LCLD_BANDS ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); - } - if ( ( psPredictionEncoder->ppfEstPredBitGain[n] = (float *) malloc( sizeof( float ) * LCLD_BANDS ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); - } - if ( ( psPredictionEncoder->ppiPredBandEnable[n] = (int32_t *) malloc( sizeof( int32_t ) * LCLD_BANDS ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); - } - if ( ( psPredictionEncoder->ppfA1Real[n] = (float *) malloc( sizeof( float ) * LCLD_BANDS ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); - } - if ( ( psPredictionEncoder->ppfA1Imag[n] = (float *) malloc( sizeof( float ) * LCLD_BANDS ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); - } - if ( ( psPredictionEncoder->ppiA1Mag[n] = (int32_t *) malloc( sizeof( int32_t ) * LCLD_BANDS ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); - } - if ( ( psPredictionEncoder->ppiA1Phase[n] = (int32_t *) malloc( sizeof( int32_t ) * LCLD_BANDS ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD PredictionEncoder Module \n" ) ); - } - for ( k = 0; k < LCLD_BANDS; k++ ) - { - psPredictionEncoder->ppiPredBandEnable[n][k] = 0; - psPredictionEncoder->ppfA1Real[n][k] = 0.0; - psPredictionEncoder->ppfA1Imag[n][k] = 0.0; - } - } - - *psPredictionEncoder_out = psPredictionEncoder; - - return IVAS_ERR_OK; -} - - -/*-------------------------------------------------------------------* - * Function DeletePredictionEncoder() - * - * - *-------------------------------------------------------------------*/ - -void DeletePredictionEncoder( - PredictionEncoder *psPredictionEncoder ) -{ - int32_t n; - - free( psPredictionEncoder->pfWindow ); - - for ( n = 0; n < psPredictionEncoder->iChannels; n++ ) - { - free( psPredictionEncoder->ppfEstPredGain[n] ); - free( psPredictionEncoder->ppfEstPredBitGain[n] ); - free( psPredictionEncoder->ppiPredBandEnable[n] ); - free( psPredictionEncoder->ppfA1Real[n] ); - free( psPredictionEncoder->ppfA1Imag[n] ); - free( psPredictionEncoder->ppiA1Mag[n] ); - free( psPredictionEncoder->ppiA1Phase[n] ); - } - free( psPredictionEncoder->piPredChanEnable ); - free( psPredictionEncoder->piNumPredBands ); - free( psPredictionEncoder->ppfEstPredGain ); - free( psPredictionEncoder->ppfEstPredBitGain ); - free( psPredictionEncoder->ppiPredBandEnable ); - free( psPredictionEncoder->ppfA1Real ); - free( psPredictionEncoder->ppfA1Imag ); - free( psPredictionEncoder->ppiA1Mag ); - free( psPredictionEncoder->ppiA1Phase ); - - free( psPredictionEncoder ); - - return; -} - - -//#define USE_RXX_WINDOW - -/*-------------------------------------------------------------------* - * Function ComputePredictors() - * - * - *-------------------------------------------------------------------*/ - -int32_t ComputePredictors( - PredictionEncoder *psPredictionEncoder, - float ***pppfReal, - float ***pppfImag ) -{ - int32_t c; - int32_t iPredictionBits = 0; - - for ( c = 0; c < psPredictionEncoder->iChannels; c++ ) - { - int32_t b; - psPredictionEncoder->piNumPredBands[c] = 50; - for ( b = 0; b < psPredictionEncoder->piNumPredBands[c]; b++ ) - { - int32_t n; - int32_t iNumBlocks; - float fGain = 0.0; - float fBitGain = 0.0; - float *pfRxxReal; - float *pfRxxImag; - float fA1Real; - float fA1Imag; - int32_t iA1Mag; - int32_t iA1Phase; - - iNumBlocks = psPredictionEncoder->iNumBlocks; - - pfRxxReal = psPredictionEncoder->pfRxxReal; - pfRxxImag = psPredictionEncoder->pfRxxImag; - - pfRxxReal[0] = 0.0; - pfRxxImag[0] = 0.0; - for ( n = 0; n < iNumBlocks; n++ ) - { -#ifdef USE_RXX_WINDOW - float fReal; - float fImag; - fReal = psPredictionEncoder->pfWindow[n] * pppfReal[c][n][b]; - fImag = psPredictionEncoder->pfWindow[n] * pppfImag[c][n][b]; - pfRxxReal[0] += ( fReal * fReal + fImag * fImag ); -#else - pfRxxReal[0] += ( pppfReal[c][n][b] * pppfReal[c][n][b] + pppfImag[c][n][b] * pppfImag[c][n][b] ); -#endif - } - - pfRxxReal[1] = 0.0; - pfRxxImag[1] = 0.0; - for ( n = 1; n < iNumBlocks; n++ ) - { -#ifdef USE_RXX_WINDOW - float fReal1; - float fImag1; - float fReal2; - float fImag2; - fReal1 = psPredictionEncoder->pfWindow[n] * pppfReal[c][n][b]; - fImag1 = psPredictionEncoder->pfWindow[n] * pppfImag[c][n][b]; - fReal2 = psPredictionEncoder->pfWindow[n - 1] * pppfReal[c][n - 1][b]; - fImag2 = psPredictionEncoder->pfWindow[n - 1] * pppfImag[c][n - 1][b]; - pfRxxReal[1] += ( fReal1 * fReal2 + fImag1 * fImag2 ); - pfRxxImag[1] += ( fImag1 * fReal2 - fReal1 * fImag2 ); -#else - pfRxxReal[1] += ( pppfReal[c][n][b] * pppfReal[c][n - 1][b] + pppfImag[c][n][b] * pppfImag[c][n - 1][b] ); - pfRxxImag[1] += ( pppfImag[c][n][b] * pppfReal[c][n - 1][b] - pppfReal[c][n][b] * pppfImag[c][n - 1][b] ); -#endif - } - - if ( pfRxxReal[0] > 1e-12f ) - { - float fA1Mag; - float fA1Phase; - float fGain2; - float fBitGain2; - - const float fMagScale = ( 2.0f * (float) ( 1 << ( PRED_QUNAT_FILTER_MAG_BITS ) ) + 1.0f ) / M_PI; - const float fInvMagScale = M_PI / ( 2.0f * (float) ( 1 << ( PRED_QUNAT_FILTER_MAG_BITS ) ) + 1.0f ); - const float fPhaseScale = (float) ( 1 << ( PRED_QUANT_FILTER_PHASE_BITS - 1 ) ) / M_PI; - const float fInvPhaseScale = M_PI / (float) ( 1 << ( PRED_QUANT_FILTER_PHASE_BITS - 1 ) ); - - /* Compute filter coefficeints */ - fA1Real = -pfRxxReal[1] / pfRxxReal[0]; - fA1Imag = -pfRxxImag[1] / pfRxxReal[0]; - - /* compute these before quant */ - /* Compute est coding gain based on quantized filter coefficients */ - fGain = 1.0f / ( 1.0f - fA1Real * fA1Real - fA1Imag * fA1Imag ); - fBitGain = 0.6f * log2f( fGain ) * (float) ( iNumBlocks ) - (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 ); - 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 ); - - fA1Phase = atan2f( fA1Imag, fA1Real ); - 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; // 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.6f * log2f( fGain ) * (float) ( iNumBlocks ) - (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; - } - else - { - psPredictionEncoder->ppfEstPredGain[c][b] = 0.0f; - fA1Real = 0.0f; - fA1Imag = 0.0f; - // iA1Real = 0; - // iA1Imag = 0; - iA1Mag = 0; - iA1Phase = 0; - fGain = -10.0f; // Fix this - } - - psPredictionEncoder->ppfEstPredGain[c][b] = fGain; - psPredictionEncoder->ppfEstPredBitGain[c][b] = fBitGain; - psPredictionEncoder->ppiPredBandEnable[c][b] = ( fBitGain > 0 ) ? 1 : 0; // Initial prediction enable - psPredictionEncoder->ppfA1Real[c][b] = fA1Real; - psPredictionEncoder->ppfA1Imag[c][b] = fA1Imag; - psPredictionEncoder->ppiA1Mag[c][b] = iA1Mag; - psPredictionEncoder->ppiA1Phase[c][b] = iA1Phase; - } - - { - /*int32_t iDone; - int32_t iPredBands; - - iDone = 0; - iPredBands = 30; - while(iPredBands > 0 && iDone == 0){ - int32_t b; - float fBitGain; - - fBitGain = -7.0; - for(b = 0; b < iPredBands; b ++){ - fBitGain -= 1.0; - if(psPredictionEncoder->ppiPredBandEnable[c][b] == 1){ - fBitGain += psPredictionEncoder->ppfEstPredBitGain[c][b]; - } - } - if(fBitGain > 0.0){ //thresh - iDone ++; - } - else{ - iPredBands --; - } - }*/ - // int32_t b; - float fBestCost; - int32_t iPredBands; - float fBitGain; - - fBestCost = 0.0; - iPredBands = 0; - fBitGain = -7.0; - for ( b = 0; b < 30; b++ ) - { // still getting this decision wrong! - fBitGain -= 1.0; - if ( psPredictionEncoder->ppiPredBandEnable[c][b] == 1 ) - { - fBitGain += psPredictionEncoder->ppfEstPredBitGain[c][b]; - } - if ( fBitGain > fBestCost ) - { - fBestCost = fBitGain; - iPredBands = b; - } - } - - // printf("%d\t%f\n",iPredBands,fBestCost); - /*if(fBestCost < 300.0){ - iPredBands = 0; - }*/ - - if ( iPredBands > 0 ) - { - // int32_t b; - iPredictionBits += 1; - iPredictionBits += 6; - for ( b = 0; b < iPredBands; b++ ) - { - iPredictionBits += 1; - if ( psPredictionEncoder->ppiPredBandEnable[c][b] == 1 ) - { - iPredictionBits += ( PRED_QUNAT_FILTER_MAG_BITS + PRED_QUANT_FILTER_PHASE_BITS ); - } - } - for ( b = iPredBands; b < LCLD_BANDS; b++ ) - { - psPredictionEncoder->ppiPredBandEnable[c][b] = 0; - } - psPredictionEncoder->piPredChanEnable[c] = 1; - psPredictionEncoder->piNumPredBands[c] = iPredBands; - } - else - { - // int32_t b; - iPredictionBits += 1; - for ( b = 0; b < LCLD_BANDS; b++ ) - { - psPredictionEncoder->ppiPredBandEnable[c][b] = 0; - } - psPredictionEncoder->piPredChanEnable[c] = 0; - psPredictionEncoder->piNumPredBands[c] = 0; - } - } - } - - return iPredictionBits; -} - - -/*-------------------------------------------------------------------* - * Function ApplyForwardPredictors() - * - * - *-------------------------------------------------------------------*/ - -void ApplyForwardPredictors( - PredictionEncoder *psPredictionEncoder, - float ***pppfReal, - float ***pppfImag ) -{ - int32_t c; - for ( c = 0; c < psPredictionEncoder->iChannels; c++ ) - { - int32_t b; - if ( psPredictionEncoder->piPredChanEnable[c] == 1 ) - { - for ( b = 0; b < psPredictionEncoder->piNumPredBands[c]; b++ ) - { - if ( psPredictionEncoder->ppiPredBandEnable[c][b] == 1 ) - { - int32_t n; - float fOldReal; - float fOldImag; - float fA1Real; - float fA1Imag; - - fOldReal = pppfReal[c][0][b]; - fOldImag = pppfImag[c][0][b]; - fA1Real = psPredictionEncoder->ppfA1Real[c][b]; - fA1Imag = psPredictionEncoder->ppfA1Imag[c][b]; - for ( n = 1; n < psPredictionEncoder->iNumBlocks; n++ ) - { - float fReal; - float fImag; - - fReal = pppfReal[c][n][b] + fA1Real * fOldReal - fA1Imag * fOldImag; - fImag = pppfImag[c][n][b] + fA1Real * fOldImag + fA1Imag * fOldReal; - - fOldReal = pppfReal[c][n][b]; - fOldImag = pppfImag[c][n][b]; - - pppfReal[c][n][b] = fReal; - pppfImag[c][n][b] = fImag; - } - } - } - } - } - - return; -} - - -/*-------------------------------------------------------------------* - * Function WritePredictors() - * - * - *-------------------------------------------------------------------*/ - -int32_t WritePredictors( - PredictionEncoder *psPredictionEncoder, - IVAS_SPLIT_REND_BITS_HANDLE pBits ) -{ - int32_t iBitsWritten = 0; - int32_t c; - - for ( c = 0; c < psPredictionEncoder->iChannels; c++ ) - { - int32_t b; - ivas_split_rend_bitstream_write_int32( pBits, psPredictionEncoder->piPredChanEnable[c], 1 ); - iBitsWritten += 1; - - if ( psPredictionEncoder->piPredChanEnable[c] == 1 ) - { - ivas_split_rend_bitstream_write_int32( pBits, psPredictionEncoder->piNumPredBands[c], 6 ); - iBitsWritten += 6; - - for ( b = 0; b < psPredictionEncoder->piNumPredBands[c]; b++ ) - { - ivas_split_rend_bitstream_write_int32( pBits, psPredictionEncoder->ppiPredBandEnable[c][b], 1 ); - iBitsWritten += 1; - - if ( psPredictionEncoder->ppiPredBandEnable[c][b] == 1 ) - { - int32_t iA1Mag; - int32_t iA1Phase; - - iA1Mag = psPredictionEncoder->ppiA1Mag[c][b]; - iA1Phase = psPredictionEncoder->ppiA1Phase[c][b] - PRED_QUANT_FILTER_PHASE_MIN; - ivas_split_rend_bitstream_write_int32( pBits, iA1Mag, PRED_QUNAT_FILTER_MAG_BITS ); - iBitsWritten += PRED_QUNAT_FILTER_MAG_BITS; - ivas_split_rend_bitstream_write_int32( pBits, iA1Phase, PRED_QUANT_FILTER_PHASE_BITS ); - iBitsWritten += PRED_QUANT_FILTER_PHASE_BITS; - } - } - } - } - - return iBitsWritten; -} -#endif diff --git a/lib_rend/ivas_RMSEnvGrouping.c b/lib_rend/ivas_RMSEnvGrouping.c deleted file mode 100644 index 770165ba6..000000000 --- a/lib_rend/ivas_RMSEnvGrouping.c +++ /dev/null @@ -1,951 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2023 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. - -*******************************************************************************************************/ - -/* Double check cost function calculation */ - -#include -#include "options.h" -#ifdef SPLIT_REND_WITH_HEAD_ROT -#include -#include "prot.h" -#include "ivas_prot_rend.h" -#include "ivas_lcld_prot.h" -#include "ivas_lcld_rom_tables.h" -#include "wmc_auto.h" - - -/*-------------------------------------------------------------------* - * 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 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, -}; - -typedef struct GMNODE -{ - int32_t iGroupStart; - int32_t iGroupLength; - float *pfMergedEnergydB; - int32_t *piQRMSEnvelope; - - int32_t iGroupRMSEnvelopeCost; - float fGroupSNRPenalty; - - struct GMNODE *psNext; -} GMNode; - -struct RMS_ENVELOPE_GROUPING -{ - int32_t iNumBlocks; - int32_t iMaxGroups; - float **ppfBandEnergy; - float **ppfBandEnergydB; - float **ppfWeight; - GMNode *psGMNodes; -}; - - -/*-------------------------------------------------------------------* - * Function CreateRMSEnvelopeGrouping() - * - * - *-------------------------------------------------------------------*/ - -RMSEnvelopeGrouping *CreateRMSEnvelopeGrouping( - const int32_t iNumBlocks ) -{ - int32_t n; - - RMSEnvelopeGrouping *psRMSEnvelopeGrouping; - - psRMSEnvelopeGrouping = (RMSEnvelopeGrouping *) malloc( sizeof( RMSEnvelopeGrouping ) ); - psRMSEnvelopeGrouping->iNumBlocks = iNumBlocks; - - psRMSEnvelopeGrouping->iMaxGroups = iNumBlocks >> 1; - - 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->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].iGroupRMSEnvelopeCost = -1; - psRMSEnvelopeGrouping->psGMNodes[n].fGroupSNRPenalty = -1.0; - } - - return psRMSEnvelopeGrouping; -} - - -/*-------------------------------------------------------------------* - * Function DeleteRMSEnvelopeGrouping() - * - * - *-------------------------------------------------------------------*/ - -void DeleteRMSEnvelopeGrouping( - RMSEnvelopeGrouping *psRMSEnvelopeGrouping ) -{ - int32_t n; - - for ( n = 0; n < psRMSEnvelopeGrouping->iNumBlocks; n++ ) - { - free( psRMSEnvelopeGrouping->ppfBandEnergy[n] ); - free( psRMSEnvelopeGrouping->ppfBandEnergydB[n] ); - free( psRMSEnvelopeGrouping->ppfWeight[n] ); - } - free( psRMSEnvelopeGrouping->ppfBandEnergy ); - free( psRMSEnvelopeGrouping->ppfBandEnergydB ); - free( psRMSEnvelopeGrouping->ppfWeight ); - - for ( n = 0; n < psRMSEnvelopeGrouping->iNumBlocks; n++ ) - { - free( psRMSEnvelopeGrouping->psGMNodes[n].pfMergedEnergydB ); - free( psRMSEnvelopeGrouping->psGMNodes[n].piQRMSEnvelope ); - } - free( psRMSEnvelopeGrouping->psGMNodes ); - - free( psRMSEnvelopeGrouping ); - - return; -} - - -/*-------------------------------------------------------------------* - * Function ComputeBandEnergy() - * - * - *-------------------------------------------------------------------*/ - -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 ) -{ - int32_t n; - - for ( n = 0; n < iChannels; n++ ) - { - int32_t k; - int32_t iChanOffset; - - iChanOffset = n * iNumBands; - for ( k = 0; k < iNumBlocks; k++ ) - { - int32_t b; - int32_t iFBOffset; - float fMaxWeight; - - iFBOffset = 0; - fMaxWeight = 0.0f; - for ( b = 0; b < iNumBands; b++ ) - { - int32_t m; - float fEnergy = 1e-12f; - float fWeight; - - for ( m = 0; m < piBandwidths[b]; m++ ) - { - fEnergy += ( pppfReal[n][k][iFBOffset] * pppfReal[n][k][iFBOffset] + pppfImag[n][k][iFBOffset] * pppfImag[n][k][iFBOffset] ); - 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; - -#ifdef APPLY_TEMPORAL_SMOOTHING - if ( k > 0 ) - { - float fSmoothEnergy; - fSmoothEnergy = 0.7f * ppfBandEnergy[k - 1][iChanOffset + b] + 0.3f * fEnergy; - - fEnergy = ( fEnergy > fSmoothEnergy ) ? fEnergy : fSmoothEnergy; - } -#endif - fEnergy = 10.0f * log10f( fEnergy ); - ppfBandEnergydB[k][iChanOffset + b] = fEnergy; - } - for ( b = 0; b < iNumBands; b++ ) - { - ppfWeight[k][iChanOffset + b] /= fMaxWeight; - } - } - } - - return; -} - - -/*-------------------------------------------------------------------* - * Function TryMerge() - * - * - *-------------------------------------------------------------------*/ - -/* THis is temporary cost function */ -static float TryMerge( - const int32_t iNumBands, - const int32_t iStartBlock, - const int32_t iGroupLength, - const float fMaxAllowedDiffdB, - float **ppfBandEnergy, - float **ppfBandEnergydB, -#ifdef APPLY_WEIGHT - float **ppfWeight, -#endif - float *pfMegredEnergydB ) -{ - int32_t b; - int32_t n; - float fMeanCost; - float fMaxCost; - float fMinDiffCost; - float fMaxDiffCost; - float fInvGroupSize = 1.0f / (float) iGroupLength; - float fInvNumBands = 1.0f / (float) iNumBands; - - for ( b = 0; b < iNumBands; b++ ) - { - float fGroupEnergy; - - - fGroupEnergy = 0.0; - for ( n = iStartBlock; n < ( iStartBlock + iGroupLength ); n++ ) - { - fGroupEnergy += ppfBandEnergy[n][b]; - } - fGroupEnergy *= fInvGroupSize; - fGroupEnergy = 10.0f * log10f( fGroupEnergy ); // Note epsolon was added when computing BandEnergy; - - pfMegredEnergydB[b] = fGroupEnergy; - } - - fMeanCost = 0.0; - fMaxCost = 0.0; - fMinDiffCost = 0.0; - fMaxDiffCost = 0.0; - for ( n = iStartBlock; n < ( iStartBlock + iGroupLength ); n++ ) - { - float fMeanAbsDiff; - float fMaxAbsDiff; - float fMaxDiff; - float fMinDiff; - - fMeanAbsDiff = 0.0; - fMaxAbsDiff = 0.0; - fMaxDiff = 0.0; - fMinDiff = 0.0; - for ( b = 0; b < iNumBands; b++ ) - { - float fDiff; - float fAbsDiff; - - fDiff = pfMegredEnergydB[b] - ppfBandEnergydB[n][b]; // Changed the order of this - fAbsDiff = fabsf( fDiff ); -#ifdef APPLY_WEIGHT - fAbsDiff *= ppfWeight[n][b]; -#endif - - fMeanAbsDiff += fAbsDiff; - fMaxAbsDiff = ( fMaxAbsDiff > fAbsDiff ) ? fMaxAbsDiff : fAbsDiff; - - - fMaxDiff = ( fMaxDiff > fDiff ) ? fMaxDiff : fDiff; - fMinDiff = ( fMinDiff < fDiff ) ? fMinDiff : fDiff; - } - fMeanAbsDiff *= fInvNumBands; - - fMeanCost = ( fMeanCost > fMeanAbsDiff ) ? fMeanCost : fMeanAbsDiff; - fMaxCost = ( fMaxCost > fMaxAbsDiff ) ? fMaxCost : fMaxAbsDiff; - - fMaxDiffCost = ( fMaxDiffCost > fMaxDiff ) ? fMaxDiffCost : fMaxDiff; - fMinDiffCost = ( fMinDiffCost < fMinDiff ) ? fMinDiffCost : fMinDiff; - } - - // printf("%f\t%f\t%f\t%f\n",fMeanCost,fMaxCost,fMaxDiffCost,fMinDiffCost); - - /*if(fMinDiffCost < -9.0){ // This prevents cliping - fMeanCost = 1e12; //Some large value - }*/ - - if ( fMaxCost > fMaxAllowedDiffdB ) - { - fMeanCost = 1e12f; // Some large value - } - - return fMeanCost; -} - - -/*-------------------------------------------------------------------* - * Function ComputeMergeRMS() - * - * - *-------------------------------------------------------------------*/ - -static void ComputeMergeRMS( - const int32_t iNumBands, - const int32_t iStartBlock, - const int32_t iGroupLength, - float **ppfBandEnergy, - float *pfMergedEnergydB, - int32_t *piQRMSEnvelope ) -{ - int32_t b; - float fInvGroupSize = 1.0f / (float) iGroupLength; - - 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++ ) - { - fGroupEnergy += ppfBandEnergy[n][b]; - } - 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 epsolon was added when computing BandEnergy; - - pfMergedEnergydB[b] = fGroupEnergy; - piQRMSEnvelope[b] = iQRMSEnvelope; - } - - return; -} - - -/*-------------------------------------------------------------------* - * Function ComputeRMSEnvelopeBits() - * - * - *-------------------------------------------------------------------*/ - -static int32_t ComputeRMSEnvelopeBits( - const int32_t iChannels, - const int32_t iNumBands, - const int32_t *piQRMSEnevelope ) -{ - int32_t n; - int32_t iRMSEnvelopeBits = 0; - int32_t iChanOffset = 0; - - for ( n = 0; n < iChannels; n++ ) - { - int32_t b; - int32_t iLastRMSVal; - - iRMSEnvelopeBits += ENV0_BITS; - iLastRMSVal = piQRMSEnevelope[iChanOffset]; - for ( b = 1; b < iNumBands; b++ ) - { - int32_t iDelta; - - iDelta = 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]; - - iLastRMSVal = piQRMSEnevelope[iChanOffset + b]; - } - - 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 ) -{ - int32_t n; - int32_t iChanOffset; - float fSNRPenalty = 0.0; - - iChanOffset = 0; - for ( n = 0; n < iChannels; n++ ) - { - int32_t 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++ ) - { - float fDeltadB; - - fDeltadB = fRMSVal - ppfBandEnergydB[k][iChanOffset + b]; - if ( fDeltadB < -9.0309f ) - { - fSNRPenalty += 1e10f; // Some large number to prevent clipping - } - else /*if(fDeltadB < 0.0)*/ - { - fSNRPenalty += fabsf( c_fiDefaultTheta48[b] * fDeltadB - fDeltadB ) * 2.0f * (float) piBandwidths[b] / 6.0f; - } - } - } - - iChanOffset += iNumBands; - } - - return fSNRPenalty; -} - - -/*-------------------------------------------------------------------* - * Function TryMerge2() - * - * - *-------------------------------------------------------------------*/ - -static float TryMerge2( - const int32_t iChannels, - const int32_t iNumBands, - const int32_t *piBandwidths, - float **ppfBandEnergy, - float **ppfBandEnergydB, - GMNode *psGMNode1, - GMNode *psGMNode2 ) -{ - int32_t iRMSEnvBits1; - int32_t iRMSEnvBits2; - int32_t iRMSEnvBitsMerged; - float fSNRPenalty1; - float fSNRPenalty2; - float fSNRPenaltyMerged; - float fMergedCost = 0.0; - - /* First compute current RMS Envelope for each group */ - if ( psGMNode1->iGroupRMSEnvelopeCost == -1 || psGMNode1->fGroupSNRPenalty == -1.0 ) - { - ComputeMergeRMS( iNumBands * iChannels, psGMNode1->iGroupStart, psGMNode1->iGroupLength, ppfBandEnergy, psGMNode1->pfMergedEnergydB, psGMNode1->piQRMSEnvelope ); - - iRMSEnvBits1 = ComputeRMSEnvelopeBits( iChannels, iNumBands, psGMNode1->piQRMSEnvelope ); - - fSNRPenalty1 = ComputeSNRPenalty( iChannels, iNumBands, piBandwidths, psGMNode1->iGroupStart, psGMNode1->iGroupLength, ppfBandEnergydB, psGMNode1->piQRMSEnvelope ); - - psGMNode1->iGroupRMSEnvelopeCost = iRMSEnvBits1; - psGMNode1->fGroupSNRPenalty = fSNRPenalty1; - } - else - { - iRMSEnvBits1 = psGMNode1->iGroupRMSEnvelopeCost; - fSNRPenalty1 = psGMNode1->fGroupSNRPenalty; - } - - if ( psGMNode2->iGroupRMSEnvelopeCost == -1 || psGMNode2->fGroupSNRPenalty == -1.0 ) - { - ComputeMergeRMS( iNumBands * iChannels, psGMNode2->iGroupStart, psGMNode2->iGroupLength, ppfBandEnergy, psGMNode2->pfMergedEnergydB, psGMNode2->piQRMSEnvelope ); - - iRMSEnvBits2 = ComputeRMSEnvelopeBits( iChannels, iNumBands, psGMNode2->piQRMSEnvelope ); - - fSNRPenalty2 = ComputeSNRPenalty( iChannels, iNumBands, piBandwidths, psGMNode2->iGroupStart, psGMNode2->iGroupLength, ppfBandEnergydB, psGMNode2->piQRMSEnvelope ); - - psGMNode2->iGroupRMSEnvelopeCost = iRMSEnvBits2; - psGMNode2->fGroupSNRPenalty = fSNRPenalty2; - } - else - { - iRMSEnvBits2 = psGMNode2->iGroupRMSEnvelopeCost; - fSNRPenalty2 = psGMNode2->fGroupSNRPenalty; - } - - /* Compute the merged group */ - ComputeMergeRMS( iNumBands * iChannels, psGMNode1->iGroupStart, psGMNode1->iGroupLength + psGMNode2->iGroupLength, ppfBandEnergy, psGMNode1->pfMergedEnergydB, psGMNode1->piQRMSEnvelope ); - - /* Compute the RMS Envelope cost for merged group */ - iRMSEnvBitsMerged = ComputeRMSEnvelopeBits( iChannels, iNumBands, psGMNode1->piQRMSEnvelope ); - - /* 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; -} - - -/*-------------------------------------------------------------------* - * Function ComputeGreedyGroups() - * - * - *-------------------------------------------------------------------*/ - -static void ComputeGreedyGroups( - RMSEnvelopeGrouping *psRMSEnvelopeGrouping, - const int32_t iChannels, - const int32_t iNumBands, - const float fMeanAllowedDiffdB, - const float fMaxAllowedDiffdB ) -{ - float fBestMeanCost; - - fBestMeanCost = 0.0; - while ( fBestMeanCost < fMeanAllowedDiffdB ) - { - GMNode *psGMNode; - GMNode *psBestGMNode; - - fBestMeanCost = fMeanAllowedDiffdB; - psGMNode = &psRMSEnvelopeGrouping->psGMNodes[0]; - psBestGMNode = NULL; - while ( psGMNode->psNext != NULL ) - { - float fMeanCost; - int32_t iGroupLength; - - iGroupLength = psGMNode->iGroupLength + psGMNode->psNext->iGroupLength; - - fMeanCost = TryMerge( iNumBands * iChannels, - psGMNode->iGroupStart, - iGroupLength, // psGMNode->iGroupLength, //Fix this bug - fMaxAllowedDiffdB, - psRMSEnvelopeGrouping->ppfBandEnergy, - psRMSEnvelopeGrouping->ppfBandEnergydB, -#ifdef APPLY_WEIGHT - psRMSEnvelopeGrouping->ppfWeight, -#endif - psGMNode->pfMergedEnergydB ); - - - if ( fMeanCost < fBestMeanCost ) - { - fBestMeanCost = fMeanCost; - psBestGMNode = psGMNode; - } - - psGMNode = psGMNode->psNext; - } - - if ( fBestMeanCost < fMeanAllowedDiffdB && psBestGMNode != NULL && psBestGMNode->psNext != NULL ) - { - psBestGMNode->iGroupLength += psBestGMNode->psNext->iGroupLength; - psBestGMNode->psNext = psBestGMNode->psNext->psNext; - } - } - - return; -} - - -/*-------------------------------------------------------------------* - * Function ComputeGreedyGroups2() - * - * - *-------------------------------------------------------------------*/ - -static void ComputeGreedyGroups2( - RMSEnvelopeGrouping *psRMSEnvelopeGrouping, - const int32_t iChannels, - const int32_t iNumBands, - const int32_t *piBandwidths ) -{ - float fBestMergeCost; - // int32_t iDone = 0; - fBestMergeCost = -1.0; - - while ( fBestMergeCost < 0.0 ) - { - GMNode *psGMNode; - GMNode *psBestGMNode; - - fBestMergeCost = 0.0; - psGMNode = &psRMSEnvelopeGrouping->psGMNodes[0]; - psBestGMNode = NULL; - while ( psGMNode->psNext != NULL ) - { - float fMergeCost; - - fMergeCost = TryMerge2( iChannels, iNumBands, piBandwidths, psRMSEnvelopeGrouping->ppfBandEnergy, psRMSEnvelopeGrouping->ppfBandEnergydB, psGMNode, psGMNode->psNext ); - - if ( fMergeCost < fBestMergeCost ) - { - fBestMergeCost = fMergeCost; - psBestGMNode = psGMNode; - } - - psGMNode = psGMNode->psNext; - } - - if ( fBestMergeCost < 0.0 && psBestGMNode != NULL && psBestGMNode->psNext != NULL ) - { - psBestGMNode->iGroupLength += psBestGMNode->psNext->iGroupLength; - psBestGMNode->iGroupRMSEnvelopeCost = -1; - psBestGMNode->fGroupSNRPenalty = -1.0; - psBestGMNode->psNext = psBestGMNode->psNext->psNext; - } - } - - return; -} - - -/*-------------------------------------------------------------------* - * Function ComputeGreedyGroups3() - * - * - *-------------------------------------------------------------------*/ - -static void ComputeGreedyGroups3( - RMSEnvelopeGrouping *psRMSEnvelopeGrouping, - const int32_t iChannels, - const int32_t iNumBands, - const int32_t *piBandwidths, - const int32_t iMaxGroups ) -{ - - int32_t iDone = 0; - int32_t iNumGroups = psRMSEnvelopeGrouping->iMaxGroups; - - while ( iDone == 0 ) - { - GMNode *psGMNode; - GMNode *psBestGMNode; - float fBestMergeCost; - - fBestMergeCost = 1e20f; - psGMNode = &psRMSEnvelopeGrouping->psGMNodes[0]; - psBestGMNode = NULL; - while ( psGMNode->psNext != NULL ) - { - float fMergeCost; - - fMergeCost = TryMerge2( iChannels, iNumBands, piBandwidths, psRMSEnvelopeGrouping->ppfBandEnergy, psRMSEnvelopeGrouping->ppfBandEnergydB, psGMNode, psGMNode->psNext ); - - if ( fMergeCost < fBestMergeCost ) - { - fBestMergeCost = fMergeCost; - psBestGMNode = psGMNode; - } - - psGMNode = psGMNode->psNext; - } - - if ( fBestMergeCost > 0.0 && iNumGroups <= iMaxGroups ) - { - iDone++; - } - else if ( psBestGMNode != NULL && psBestGMNode->psNext != NULL ) - { - psBestGMNode->iGroupLength += psBestGMNode->psNext->iGroupLength; - psBestGMNode->iGroupRMSEnvelopeCost = -1; - psBestGMNode->fGroupSNRPenalty = -1.0; - psBestGMNode->psNext = psBestGMNode->psNext->psNext; - iNumGroups--; - } - else - { - 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 ) -{ - int32_t n; - - for ( n = 0; n < iChannels; n++ ) - { - int32_t b; - int32_t iChanOffset; - - iChanOffset = n * iNumBands; - for ( b = 0; b < iNumBands; b++ ) - { - int32_t k; - int32_t iBlockOffset; - - iBlockOffset = 0; - for ( k = 0; k < iNumGroups; k++ ) - { - int32_t m; - float fGroupEnergy; - fGroupEnergy = 0.0; - for ( m = 0; m < piGroupLengths[k]; m++ ) - { - fGroupEnergy += ppfBandEnergy[iBlockOffset][b + iChanOffset]; - 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 ); // Bug fix - 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; - } - } - } - - return; -} - - -/*-------------------------------------------------------------------* - * Function LimitRMSEnvelope() - * - * - *-------------------------------------------------------------------*/ - -static void LimitRMSEnvelope( - const int32_t iBandCount, - const int32_t iRMSDeltaMax, - const int32_t iRMSDeltaMin, - int32_t *piRMSEnvelope ) -{ - int32_t iBand; - int32_t iLastSCF; - - /* Increase low envelope values to ensure that the scale factors traces the large values correctly (checking for max deltas) */ - iLastSCF = piRMSEnvelope[iBandCount - 1]; - for ( iBand = iBandCount - 2; iBand > -1; iBand-- ) - { - int32_t iDelta; - - iDelta = iLastSCF - piRMSEnvelope[iBand]; - - if ( iDelta > iRMSDeltaMax ) - { -#ifdef DEBUG_VERBOSE - printf( "WARNING RMS envelope delta limited\n" ); -#endif - piRMSEnvelope[iBand] += ( iDelta - iRMSDeltaMax ); - } - - iLastSCF = piRMSEnvelope[iBand]; - } - - /* 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++ ) - { - int32_t iDelta; - - iDelta = piRMSEnvelope[iBand] - iLastSCF; - - if ( iDelta < iRMSDeltaMin ) - { -#ifdef DEBUG_VERBOSE - printf( "WARNING RMS envelope delta limited\n" ); -#endif - piRMSEnvelope[iBand] += ( iRMSDeltaMin - iDelta ); - } - - iLastSCF = piRMSEnvelope[iBand]; - } - - return; -} - - -/*-------------------------------------------------------------------* - * Function ComputeEnvelopeGrouping() - * - * - *-------------------------------------------------------------------*/ - -void ComputeEnvelopeGrouping( - RMSEnvelopeGrouping *psRMSEnvelopeGrouping, - const int32_t iChannels, - const int32_t iNumBands, - const int32_t *piBandwidths, // pass in absolute thresh - float ***pppfReal, - float ***pppfImag, - int32_t *piNumGroups, - int32_t *piGroupLengths, - int32_t ***pppiRMSEnvelope ) -{ - int32_t n; - GMNode *psGMNode; - - /* Compute Band Energies */ - ComputeBandEnergy( iChannels, psRMSEnvelopeGrouping->iNumBlocks, iNumBands, piBandwidths, pppfReal, pppfImag, psRMSEnvelopeGrouping->ppfBandEnergy, psRMSEnvelopeGrouping->ppfBandEnergydB, psRMSEnvelopeGrouping->ppfWeight ); - - /* Init GMNodes */ - psRMSEnvelopeGrouping->psGMNodes[0].iGroupStart = 0; - psRMSEnvelopeGrouping->psGMNodes[0].iGroupLength = 2; - psRMSEnvelopeGrouping->psGMNodes[0].psNext = NULL; - psRMSEnvelopeGrouping->psGMNodes[0].iGroupRMSEnvelopeCost = -1; - psRMSEnvelopeGrouping->psGMNodes[0].fGroupSNRPenalty = -1.0f; - - for ( n = 1; n < psRMSEnvelopeGrouping->iMaxGroups; n++ ) - { - psRMSEnvelopeGrouping->psGMNodes[n - 1].psNext = &psRMSEnvelopeGrouping->psGMNodes[n]; - psRMSEnvelopeGrouping->psGMNodes[n].iGroupStart = n * 2; - psRMSEnvelopeGrouping->psGMNodes[n].iGroupLength = 2; - psRMSEnvelopeGrouping->psGMNodes[n].iGroupRMSEnvelopeCost = -1; - psRMSEnvelopeGrouping->psGMNodes[n].fGroupSNRPenalty = -1.0; - psRMSEnvelopeGrouping->psGMNodes[n].psNext = NULL; - } - - /* Perform grouping via Greedy Merge */ - - /* ComputeGreedyGroups2( psRMSEnvelopeGrouping, iChannels, iNumBands, piBandwidths );*/ - - /* Allows control over max groups can call using 16 if want same as previous call */ - ComputeGreedyGroups3( psRMSEnvelopeGrouping, iChannels, iNumBands, piBandwidths, LCLD_BLOCKS_PER_FRAME ); - - /* Calc Groups from Merge Results */ - *piNumGroups = 0; - psGMNode = &psRMSEnvelopeGrouping->psGMNodes[0]; - while ( psGMNode != NULL ) - { - piGroupLengths[*piNumGroups] = psGMNode->iGroupLength; - *piNumGroups += 1; - psGMNode = psGMNode->psNext; - } - - /* Compute RMS Envelope given group lengths */ - ComputeRMSEnvelope( iChannels, iNumBands, *piNumGroups, piGroupLengths, psRMSEnvelopeGrouping->ppfBandEnergy, pppiRMSEnvelope ); - - /* Envelope Tenting */ - for ( n = 0; n < iChannels; n++ ) - { - int32_t k; - for ( k = 0; k < *piNumGroups; k++ ) - { - LimitRMSEnvelope( iNumBands, ENV_DELTA_MAX, ENV_DELTA_MIN, pppiRMSEnvelope[n][k] ); - } - } - - return; -} -#endif diff --git a/lib_rend/ivas_crend.c b/lib_rend/ivas_crend.c index 2044a095b..fd2b1a01c 100644 --- a/lib_rend/ivas_crend.c +++ b/lib_rend/ivas_crend.c @@ -1541,7 +1541,7 @@ void ivas_rend_closeCrend( #ifdef SPLIT_REND_WITH_HEAD_ROT /*------------------------------------------------------------------------- - * ivas_rend_openCldfbRend() + * ivas_rend_closeCldfbRend() * * Close CLDFB based fastconv binaural renderer memories *------------------------------------------------------------------------*/ @@ -1556,7 +1556,7 @@ void ivas_rend_closeCldfbRend( } ivas_binRenderer_close( &pCldfbRend->hCldfbRend ); - + ivas_binaural_hrtf_close( &pCldfbRend->hHrtfFastConv ); ivas_HRTF_fastconv_binary_close( &pCldfbRend->hHrtfFastConv ); return; @@ -2075,8 +2075,8 @@ ivas_error ivas_rend_crendProcessSplitBin( const AUDIO_CONFIG inConfig, const AUDIO_CONFIG outConfig, const MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, - DECODER_CONFIG_HANDLE hDecoderConfig, - COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, + const DECODER_CONFIG_HANDLE hDecoderConfig, + const COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, const IVAS_OUTPUT_SETUP_HANDLE hIntSetup, EFAP_HANDLE hEFAPdata, float *output[], @@ -2110,7 +2110,7 @@ ivas_error ivas_rend_crendProcessSplitBin( /* save current head positions */ pCombinedOrientationDataLocal = hCombinedOrientationData; combinedOrientationDataLocal = *pCombinedOrientationDataLocal; - if ( pMultiBinPoseData->poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) + if ( pMultiBinPoseData->poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) { for ( sf = 1; sf < hCombinedOrientationData->num_subframes; ++sf ) { @@ -2163,7 +2163,9 @@ ivas_error ivas_rend_crendProcessSplitBin( { mvr2r( hCombinedOrientationData->Rmat_prev[pos_idx][i], pCombinedOrientationDataLocal->Rmat_prev[0][i], 3 ); } - if ( ( error = ivas_rend_crendProcess( pCrend, inConfig, outConfig, hDecoderConfig, pCombinedOrientationDataLocal, hIntSetup, hEFAPdata, p_tmpInputBuffer, output_Fs, hCombinedOrientationData->num_subframes, pos_idx ) ) != IVAS_ERR_OK ) + + if ( ( error = ivas_rend_crendProcessSubframe( pCrend, inConfig, outConfig, hDecoderConfig, pCombinedOrientationDataLocal, hIntSetup, hEFAPdata, + NULL, p_tmpInputBuffer, p_tmpInputBuffer, output_frame, output_Fs, pos_idx ) ) != IVAS_ERR_OK ) { return error; } @@ -2203,9 +2205,8 @@ ivas_error ivas_rend_crendProcessSplitBin( return IVAS_ERR_OK; } -#endif -#ifdef SPLIT_REND_WITH_HEAD_ROT + /*-----------------------------------------------------------------------------------------* * Function ivas_rend_crend_ProcessSubframesSplitBin() * @@ -2234,7 +2235,6 @@ ivas_error ivas_rend_crendProcessSubframesSplitBin( ivas_error error; float gain_lfe; float tmpLfeBuffer[L_FRAME48k]; - float *p_bin_output[BINAURAL_CHANNELS]; int16_t original_subframes_rendered, original_slots_rendered; float tmpInputBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; float *p_tmpInputBuffer[MAX_OUTPUT_CHANNELS]; @@ -2263,7 +2263,7 @@ ivas_error ivas_rend_crendProcessSubframesSplitBin( /* save current head positions */ pCombinedOrientationDataLocal = hCombinedOrientationData; combinedOrientationDataLocal = *pCombinedOrientationDataLocal; - if ( pMultiBinPoseData->poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) + if ( pMultiBinPoseData->poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) { for ( sf = 1; sf < hCombinedOrientationData->num_subframes; ++sf ) { @@ -2309,11 +2309,6 @@ ivas_error ivas_rend_crendProcessSubframesSplitBin( pCombinedOrientationDataLocal = &combinedOrientationDataLocal; - /* set output channels */ - for ( i = 0; i < BINAURAL_CHANNELS; i++ ) - { - p_bin_output[i] = output[pos_idx * BINAURAL_CHANNELS + i]; - } hTcBuffer->subframes_rendered = original_subframes_rendered; hTcBuffer->slots_rendered = original_slots_rendered; diff --git a/lib_rend/ivas_dirac_dec_binaural_functions.c b/lib_rend/ivas_dirac_dec_binaural_functions.c index 42f9482f4..082b842f4 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions.c @@ -99,8 +99,9 @@ static void ivas_dirac_dec_binaural_internal( Decoder_Struct *st_ivas, COMBINED_ static void ivas_dirac_dec_decorrelate_slot( DIRAC_DEC_BIN_HANDLE hDiracDecBin, const int16_t num_freq_bands, const int16_t slot, float inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float decRe[][CLDFB_NO_CHANNELS_MAX], float decIm[][CLDFB_NO_CHANNELS_MAX] ); #ifdef SPLIT_REND_WITH_HEAD_ROT -static void ivas_dirac_dec_binaural_formulate_input_covariance_matrices( DIRAC_DEC_BIN_HANDLE hDiracDecBin, SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, PARAMBIN_REND_CONFIG_HANDLE hConfig, float inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], const int16_t subframe, float *subFrameTotalEne, float *IIReneLimiter ); -static void ivas_dirac_dec_binaural_formulate_target_covariance_matrices( DIRAC_DEC_BIN_HANDLE hDiracDecBin, SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, PARAMBIN_REND_CONFIG_HANDLE hConfig, float Rmat[3][3], const int16_t subframe, const int16_t isHeadtracked, const float *subFrameTotalEne, const float *IIReneLimiter, const MASA_ISM_DATA_HANDLE hMasaIsmData ); +static void ivas_dirac_dec_binaural_formulate_input_covariance_matrices( DIRAC_DEC_BIN_HANDLE hDiracDecBin, const SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, const PARAMBIN_REND_CONFIG_HANDLE hConfig, float inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], const int16_t subframe, float *subFrameTotalEne, float *IIReneLimiter ); + +static void ivas_dirac_dec_binaural_formulate_target_covariance_matrices( DIRAC_DEC_BIN_HANDLE hDiracDecBin, const SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, const PARAMBIN_REND_CONFIG_HANDLE hConfig, float Rmat[3][3], const int16_t subframe, const int16_t isHeadtracked, const float *subFrameTotalEne, const float *IIReneLimiter, const MASA_ISM_DATA_HANDLE hMasaIsmData ); #else static void ivas_dirac_dec_binaural_formulate_input_and_target_covariance_matrices( DIRAC_DEC_BIN_HANDLE hDiracDecBin, SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, PARAMBIN_REND_CONFIG_HANDLE hConfig, float inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float Rmat[3][3], const int16_t subframe, const int16_t isHeadtracked, const MASA_ISM_DATA_HANDLE hMasaIsmData ); #endif @@ -153,9 +154,15 @@ ivas_error ivas_dirac_dec_init_binaural_data( ivas_error error; float frequency_axis[CLDFB_NO_CHANNELS_MAX]; #ifdef SPLIT_REND_WITH_HEAD_ROT - int16_t pos_idx; + int16_t num_poses, pos_idx; + + num_poses = 1; + if ( st_ivas->hSplitBinRend != NULL ) + { + num_poses = st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses; + } - for ( pos_idx = 0; pos_idx < st_ivas->hSplitBinRend.splitrend.multiBinPoseData.num_poses; pos_idx++ ) + for ( pos_idx = 0; pos_idx < num_poses; pos_idx++ ) { hDiracDecBin = st_ivas->hDiracDecBin[pos_idx]; #else @@ -801,7 +808,7 @@ static void ivas_dirac_dec_binaural_internal( subFrameTotalEne, IIReneLimiter ); ivas_dirac_dec_binaural_formulate_target_covariance_matrices( hDiracDecBin, hSpatParamRendCom, &config_data, Rmat, subframe, - hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[subframe] > 0, subFrameTotalEne, IIReneLimiter, st_ivas->hMasaIsmData ); + hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[hCombinedOrientationData->subframe_idx] > 0, subFrameTotalEne, IIReneLimiter, st_ivas->hMasaIsmData ); #endif nchanSeparateChannels = 0; @@ -818,7 +825,11 @@ static void ivas_dirac_dec_binaural_internal( hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[hCombinedOrientationData->subframe_idx] > 0, nchanSeparateChannels, st_ivas->hMasaIsmData ); #ifdef SPLIT_REND_WITH_HEAD_ROT - pMultiBinPoseData = &st_ivas->hSplitBinRend.splitrend.multiBinPoseData; + pMultiBinPoseData = NULL; + if ( st_ivas->hSplitBinRend != NULL ) + { + pMultiBinPoseData = &st_ivas->hSplitBinRend->splitrend.multiBinPoseData; + } #ifdef SPLIT_REND_WITH_HEAD_ROT if ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) @@ -832,10 +843,10 @@ static void ivas_dirac_dec_binaural_internal( for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) { - for ( i = 0; i < CLDFB_SLOTS_PER_SUBFRAME; i++ ) + for ( i = 0; i < hSpatParamRendCom->subframe_nbslots[subframe]; i++ ) { - mvr2r( tmp_Cldfb_out_re[ch][i], st_ivas->hSplitBinRend.hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[ch][subframe * CLDFB_SLOTS_PER_SUBFRAME + i], CLDFB_NO_CHANNELS_MAX ); - mvr2r( tmp_Cldfb_out_im[ch][i], st_ivas->hSplitBinRend.hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[ch][subframe * CLDFB_SLOTS_PER_SUBFRAME + i], CLDFB_NO_CHANNELS_MAX ); + mvr2r( tmp_Cldfb_out_re[ch][i], st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[ch][hSpatParamRendCom->slots_rendered + i], CLDFB_NO_CHANNELS_MAX ); + mvr2r( tmp_Cldfb_out_im[ch][i], st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[ch][hSpatParamRendCom->slots_rendered + i], CLDFB_NO_CHANNELS_MAX ); } } } @@ -905,10 +916,10 @@ static void ivas_dirac_dec_binaural_internal( /* copy from temporary buffer to the main split rendering buffer */ for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) { - for ( i = 0; i < CLDFB_SLOTS_PER_SUBFRAME; i++ ) + for ( i = 0; i < hSpatParamRendCom->subframe_nbslots[subframe]; i++ ) { - mvr2r( tmp_Cldfb_out_re[ch][i], st_ivas->hSplitBinRend.hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[pos_idx * BINAURAL_CHANNELS + ch][subframe * CLDFB_SLOTS_PER_SUBFRAME + i], CLDFB_NO_CHANNELS_MAX ); - mvr2r( tmp_Cldfb_out_im[ch][i], st_ivas->hSplitBinRend.hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[pos_idx * BINAURAL_CHANNELS + ch][subframe * CLDFB_SLOTS_PER_SUBFRAME + i], CLDFB_NO_CHANNELS_MAX ); + mvr2r( tmp_Cldfb_out_re[ch][i], st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_RealBuffer_Binaural[pos_idx * BINAURAL_CHANNELS + ch][hSpatParamRendCom->slots_rendered + i], CLDFB_NO_CHANNELS_MAX ); + mvr2r( tmp_Cldfb_out_im[ch][i], st_ivas->hSplitBinRend->hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural[pos_idx * BINAURAL_CHANNELS + ch][hSpatParamRendCom->slots_rendered + i], CLDFB_NO_CHANNELS_MAX ); } } @@ -984,8 +995,8 @@ static void ivas_dirac_dec_decorrelate_slot( #ifdef SPLIT_REND_WITH_HEAD_ROT static void ivas_dirac_dec_binaural_formulate_input_covariance_matrices( DIRAC_DEC_BIN_HANDLE hDiracDecBin, - SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, - PARAMBIN_REND_CONFIG_HANDLE hConfig, + const SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, + const PARAMBIN_REND_CONFIG_HANDLE hConfig, float inRe[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], float inIm[][CLDFB_SLOTS_PER_SUBFRAME][CLDFB_NO_CHANNELS_MAX], const int16_t subframe, @@ -1148,8 +1159,8 @@ static void ivas_dirac_dec_binaural_formulate_input_covariance_matrices( static void ivas_dirac_dec_binaural_formulate_target_covariance_matrices( DIRAC_DEC_BIN_HANDLE hDiracDecBin, - SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, - PARAMBIN_REND_CONFIG_HANDLE hConfig, + const SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, + const PARAMBIN_REND_CONFIG_HANDLE hConfig, float Rmat[3][3], const int16_t subframe, const int16_t isHeadtracked, @@ -3367,10 +3378,11 @@ static void ivas_masa_ext_rend_parambin_internal( const int16_t subframe, const SPLIT_REND_WRAPPER *hSplitRendWrapper, float Cldfb_Out_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - float Cldfb_Out_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX] ) + float Cldfb_Out_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX] #else - const int16_t subframe ) + const int16_t subframe #endif +) { DIRAC_DEC_BIN_HANDLE hDiracDecBin; SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom; @@ -3613,10 +3625,11 @@ void ivas_masa_ext_rend_parambin_render( const int16_t num_subframes, /* i : number of subframes to render */ const SPLIT_REND_WRAPPER *hSplitRendWrapper, /* i : split rendering orientation data */ float Cldfb_Out_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* o : rendered orientations for split rend. real part of cldfb */ - float Cldfb_Out_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX] ) /* o : rendered orientations for split rend. imag part of cldfb */ + float Cldfb_Out_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX] /* o : rendered orientations for split rend. imag part of cldfb */ #else - const int16_t num_subframes ) /* i : number of subframes to render */ + const int16_t num_subframes /* i : number of subframes to render */ #endif +) { int16_t subframe; SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom; diff --git a/lib_rend/ivas_dirac_output_synthesis_dec.c b/lib_rend/ivas_dirac_output_synthesis_dec.c index 8ee3b1e4f..d9f091182 100644 --- a/lib_rend/ivas_dirac_output_synthesis_dec.c +++ b/lib_rend/ivas_dirac_output_synthesis_dec.c @@ -542,11 +542,9 @@ void ivas_dirac_dec_output_synthesis_process_slot( const float *diffuseness, SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, /* i/o: common spatial renderer data handle */ DIRAC_REND_HANDLE hDirACRend, /* i/o: DirAC renderer handle */ - const int16_t sh_rot_max_order, - const float *p_Rmat, /* i : rotation matrix */ - const VBAP_HANDLE hVBAPdata, /* i : VBAP structure */ - const IVAS_OUTPUT_SETUP hOutSetup, /* i : output setup structure */ - const int16_t nchan_transport, /* i : number of transport channels*/ + const VBAP_HANDLE hVBAPdata, /* i : VBAP structure */ + const IVAS_OUTPUT_SETUP hOutSetup, /* i : output setup structure */ + const int16_t nchan_transport, /* i : number of transport channels*/ const int16_t md_idx, const int16_t hodirac_flag, /* i : flag to indicate HO-DirAC mode */ const int16_t dec_param_estim ) @@ -590,8 +588,6 @@ void ivas_dirac_dec_output_synthesis_process_slot( elevation, md_idx, NULL, - 2, - p_Rmat, hodirac_flag ); } @@ -638,8 +634,6 @@ void ivas_dirac_dec_output_synthesis_process_slot( elevation, md_idx, NULL, - sh_rot_max_order, - p_Rmat, hodirac_flag ); if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD ) @@ -1571,169 +1565,6 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls( } -/*------------------------------------------------------------------------- - * ivas_dirac_dec_get_response_split_order() - * - * calculate reponse, 1 degree resolution - *------------------------------------------------------------------------*/ - -static void ivas_dirac_dec_get_response_split_order( - const int16_t azimuth, - const int16_t elevation, - float *response, - const int16_t shd_rot_max_order, - const float *p_Rmat ) -{ - int16_t index_azimuth, index_elevation; - int16_t el, e, az; - float cos_1, cos_2, sin_1, cos_az[3]; - float sin_az[3]; - float f, c; - int16_t l, m; - int16_t b, b1, b_2, b1_2, a; - float dv_0, dv_1, dv_2, dv_r_0, dv_r_1, dv_r_2; - float w; - - push_wmops( "ivas_dirac_dec_get_response_split_order" ); - - index_azimuth = ( azimuth + 180 ) % 360; - index_elevation = elevation + 90; - e = index_elevation > 90 ? -1 : 1; - el = index_elevation > 90 ? 180 - index_elevation : index_elevation; - - az = index_azimuth > 180 ? 360 - index_azimuth : index_azimuth; - f = index_azimuth > 180 ? -1.0f : 1.0f; - - cos_1 = dirac_gains_trg_term[az][0]; - sin_1 = f * dirac_gains_trg_term[az][1]; - - cos_2 = cos_1 * cos_1; - - cos_az[0] = cos_1; - cos_az[1] = 2.0f * cos_2 - 1.0f; - cos_az[2] = 2.0f * cos_1 * cos_az[1] - cos_az[0]; - sin_az[0] = sin_1; - sin_az[1] = sin_1 * 2.0f * cos_1; - sin_az[2] = sin_1 * ( 4.0f * cos_2 - 1.0f ); - - response[0] = 1.0f; - for ( l = 1; l <= shd_rot_max_order; l++ ) - { - b_2 = l * l; - b1_2 = l * l + 2 * l; - for ( m = 0; m < l; m += 2 ) - { - b = b_2 + m; - a = dirac_gains_P_idx[b]; - c = SQRT2 * dirac_gains_norm_term[a] * dirac_gains_Pnm[el][a]; - - response[b] = c * sin_az[l - m - 1]; - - b1 = b1_2 - m; - response[b1] = c * cos_az[l - m - 1]; - } - - for ( m = 1; m < l; m += 2 ) - { - b = b_2 + m; - a = dirac_gains_P_idx[b]; - c = SQRT2 * dirac_gains_norm_term[a] * dirac_gains_Pnm[el][a]; - c = c * e; - - response[b] = c * sin_az[l - m - 1]; - - b1 = b1_2 - m; - response[b1] = c * cos_az[l - m - 1]; - } - - b = b_2 + l; - a = dirac_gains_P_idx[b]; - c = dirac_gains_norm_term[a] * dirac_gains_Pnm[el][a]; - if ( l % 2 == 1 ) - { - c = c * e; - } - - response[b] = c; - } - - /*Conversion spherical to cartesian coordinates*/ - w = -dirac_gains_trg_term[el][1]; - dv_0 = w * cos_1; - dv_1 = w * sin_1; - dv_2 = e * dirac_gains_trg_term[el][0]; - - /*Rotation mtx multiplication*/ - dv_r_0 = p_Rmat[0] * dv_0 + p_Rmat[1] * dv_1 + p_Rmat[2] * dv_2; - dv_r_1 = p_Rmat[3] * dv_0 + p_Rmat[4] * dv_1 + p_Rmat[5] * dv_2; - dv_r_2 = p_Rmat[6] * dv_0 + p_Rmat[7] * dv_1 + p_Rmat[8] * dv_2; - - index_azimuth = ( (int16_t) ( atan2f( dv_r_1, dv_r_0 ) * _180_OVER_PI ) + 180 ) % 360; - index_elevation = (int16_t) ( atan2f( dv_r_2, sqrtf( dv_r_0 * dv_r_0 + dv_r_1 * dv_r_1 ) ) * _180_OVER_PI ) + 90; - e = index_elevation > 90 ? -1 : 1; - el = index_elevation > 90 ? 180 - index_elevation : index_elevation; - - az = index_azimuth > 180 ? 360 - index_azimuth : index_azimuth; - f = index_azimuth > 180 ? -1.0f : 1.0f; - - cos_1 = dirac_gains_trg_term[az][0]; - sin_1 = f * dirac_gains_trg_term[az][1]; - - cos_2 = cos_1 * cos_1; - - cos_az[0] = cos_1; - cos_az[1] = 2.0f * cos_2 - 1.0f; - cos_az[2] = 2.0f * cos_1 * cos_az[1] - cos_az[0]; - sin_az[0] = sin_1; - sin_az[1] = sin_1 * 2.0f * cos_1; - sin_az[2] = sin_1 * ( 4.0f * cos_2 - 1.0f ); - - for ( l = shd_rot_max_order + 1; l <= 3; l++ ) - { - b_2 = l * l; - b1_2 = l * l + 2 * l; - for ( m = 0; m < l; m += 2 ) - { - b = b_2 + m; - a = dirac_gains_P_idx[b]; - c = SQRT2 * dirac_gains_norm_term[a] * dirac_gains_Pnm[el][a]; - - response[b] = c * sin_az[l - m - 1]; - - b1 = b1_2 - m; - response[b1] = c * cos_az[l - m - 1]; - } - - for ( m = 1; m < l; m += 2 ) - { - b = b_2 + m; - a = dirac_gains_P_idx[b]; - c = SQRT2 * dirac_gains_norm_term[a] * dirac_gains_Pnm[el][a]; - c = c * e; - - response[b] = c * sin_az[l - m - 1]; - - b1 = b1_2 - m; - response[b1] = c * cos_az[l - m - 1]; - } - - b = b_2 + l; - a = dirac_gains_P_idx[b]; - c = dirac_gains_norm_term[a] * dirac_gains_Pnm[el][a]; - if ( l % 2 == 1 ) - { - c = c * e; - } - - response[b] = c; - } - - pop_wmops(); - - return; -} - - /*------------------------------------------------------------------------- * ivas_dirac_dec_compute_directional_responses() * @@ -1750,9 +1581,7 @@ void ivas_dirac_dec_compute_directional_responses( const int16_t *elevation, const int16_t md_idx, const float *surCohRatio, - const int16_t shd_rot_max_order, /* i : split-order rotation method */ - const float *p_Rmat, /* i : rotation matrix */ - const int16_t hodirac_flag /* i : flag to indicate HO-DirAC mode */ + const int16_t hodirac_flag /* i : flag to indicate HO-DirAC mode */ ) { int16_t k, l; @@ -1822,23 +1651,11 @@ void ivas_dirac_dec_compute_directional_responses( set_f( direct_response_hoa, 1.0f, MAX_OUTPUT_CHANNELS ); set_f( direct_response_dir2, 1.0f, MAX_OUTPUT_CHANNELS ); - if ( p_Rmat != 0 ) - { - ivas_dirac_dec_get_response_split_order( azimuth[k], elevation[k], direct_response_hoa, shd_rot_max_order, p_Rmat ); + ivas_dirac_dec_get_response( azimuth[k], elevation[k], direct_response_hoa, hDirACRend->hOutSetup.ambisonics_order ); - if ( hodirac_flag ) - { - ivas_dirac_dec_get_response_split_order( azimuth2[k], elevation2[k], direct_response_dir2, shd_rot_max_order, p_Rmat ); - } - } - else + if ( hodirac_flag ) { - ivas_dirac_dec_get_response( azimuth[k], elevation[k], direct_response_hoa, hDirACRend->hOutSetup.ambisonics_order ); - - if ( hodirac_flag ) - { - ivas_dirac_dec_get_response( azimuth2[k], elevation2[k], direct_response_dir2, hDirACRend->hOutSetup.ambisonics_order ); - } + ivas_dirac_dec_get_response( azimuth2[k], elevation2[k], direct_response_dir2, hDirACRend->hOutSetup.ambisonics_order ); } if ( masa_band_mapping == NULL && hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD ) diff --git a/lib_rend/ivas_dirac_rend.c b/lib_rend/ivas_dirac_rend.c index 9fa1ddd8e..14088be0a 100644 --- a/lib_rend/ivas_dirac_rend.c +++ b/lib_rend/ivas_dirac_rend.c @@ -2216,8 +2216,6 @@ static void ivas_masa_ext_dirac_render_sf( elevation, md_idx, surCohRatio, - 0, - NULL, 0 ); @@ -2372,8 +2370,6 @@ static void ivas_masa_ext_dirac_render_sf( hSpatParamRendCom->diffuseness_vector[md_idx], hSpatParamRendCom, hDirACRend, - 0, - 0, hMasaExtRend->hVBAPdata, hDirACRend->hOutSetup, nchan_transport, diff --git a/lib_rend/ivas_lc3plus_common.h b/lib_rend/ivas_lc3plus_common.h deleted file mode 100644 index 93a37488c..000000000 --- a/lib_rend/ivas_lc3plus_common.h +++ /dev/null @@ -1,57 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2023 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 IVAS_LC3PLUS_COM_H -#define IVAS_LC3PLUS_COM_H - - -#include -#include "ivas_error.h" -#include "lc3.h" - -/*! common configuration parameters between encoder and decoder */ -typedef struct LC3PLUS_CONFIG -{ - /*! frame duration in microseconds [10000, 5000, 2500] */ - uint32_t lc3plus_frame_duration_us; - /*! ivas frame duration in microseconds [20000, 5000] */ - uint32_t ivas_frame_duration_us; - /*! sampling rate*/ - uint32_t samplerate; - /*! number of channels */ - uint16_t channels; -} LC3PLUS_CONFIG; - -/*! utility function to convert LC3PLUS_Errors to the suitable ivas_error */ -ivas_error IVAS_LC3PLUS_LC3plusErrToIvasErr( const LC3PLUS_Error lc3PlusError ); - -#endif /* IVAS_LC3PLUS_COM_H */ diff --git a/lib_rend/ivas_lc3plus_dec.c b/lib_rend/ivas_lc3plus_dec.c deleted file mode 100644 index 5dfdb9cec..000000000 --- a/lib_rend/ivas_lc3plus_dec.c +++ /dev/null @@ -1,703 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2023 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. - -*******************************************************************************************************/ - -#include -#include "options.h" -#include "prot.h" -#include "ivas_prot.h" -#include "ivas_lc3plus_dec.h" -#include "ivas_lc3plus_common.h" -#include "lc3.h" -#include "ivas_error_utils.h" -#include "wmc_auto.h" - -#ifdef SPLIT_REND_WITH_HEAD_ROT - -/*------------------------------------------------------------------------- - * IVAS_LC3PLUS_DEC_Open() - * - * - *------------------------------------------------------------------------*/ - -ivas_error IVAS_LC3PLUS_DEC_Open( - const LC3PLUS_CONFIG config, /* i : LC3plus decoder configuration */ - IVAS_LC3PLUS_DEC_HANDLE *handle /* o : decoder handle */ -) -{ - LC3PLUS_Error err; - int32_t decoder_size; - int16_t lc3plusFrameIdx; - int16_t numLC3plusFramesPerIvasFrame; - int16_t i; - - if ( ( *handle = malloc( sizeof( struct IVAS_LC3PLUS_DEC_HANDLE ) ) ) == NULL ) - { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus wrapper handle\n" ); - } - - if ( 0 == config.lc3plus_frame_duration_us ) - { - return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "Invalid lc3plus_frame_duration_us (0)\n" ); - } - numLC3plusFramesPerIvasFrame = (int16_t) ( config.ivas_frame_duration_us / config.lc3plus_frame_duration_us ); - - - ( *handle )->num_decs = 0; - ( *handle )->pcm_conversion_buffer = NULL; - ( *handle )->handles = NULL; - ( *handle )->selective_decoding_states = NULL; - ( *handle )->bitstream_caches = NULL; - - if ( ( ( *handle )->handles = malloc( config.channels * sizeof( IVAS_LC3PLUS_DEC_HANDLE ) ) ) == NULL ) - { - IVAS_LC3PLUS_DEC_Close( handle ); - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus wrapper handle\n" ); - } - - if ( ( ( *handle )->selective_decoding_states = malloc( config.channels * sizeof( IVAS_LC3PLUS_DEC_SELECTIVE_DECODING_STATE * ) ) ) == NULL ) - { - IVAS_LC3PLUS_DEC_Close( handle ); - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus wrapper handle\n" ); - } - - for ( i = 0; i < config.channels; ++i ) - { - ( *handle )->handles[i] = NULL; - ( *handle )->selective_decoding_states[i] = NULL; - } - - if ( ( ( *handle )->bitstream_caches = malloc( config.channels * sizeof( IVAS_LC3PLUS_DEC_BITSTREAM_CACHE * ) ) ) == NULL ) - { - IVAS_LC3PLUS_DEC_Close( handle ); - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus wrapper handle\n" ); - } - for ( i = 0; i < config.channels; ++i ) - { - ( *handle )->bitstream_caches[i] = NULL; - } - - ( *handle )->num_decs = config.channels; - for ( int32_t iCh = 0; iCh < config.channels; iCh++ ) - { - ( *handle )->selective_decoding_states[iCh] = NULL; - if ( NULL != ( *handle )->bitstream_caches ) - { - ( *handle )->bitstream_caches[iCh] = NULL; - } - /* allocate and configure LC3plus decoder */ - decoder_size = lc3plus_dec_get_size( config.samplerate, 1 ); - if ( 0 == decoder_size ) - { - IVAS_LC3PLUS_DEC_Close( handle ); - return IVAS_ERROR( IVAS_ERR_INTERNAL, "lc3plus_dec_get_size failed\n" ); - } - - if ( ( ( *handle )->handles[iCh] = malloc( decoder_size ) ) == NULL ) - { - IVAS_LC3PLUS_DEC_Close( handle ); - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus decoder\n" ); - } - - err = lc3plus_dec_init( ( *handle )->handles[iCh], config.samplerate, 1, LC3PLUS_PLC_ADVANCED, 0 ); - if ( LC3PLUS_OK != err ) - { - IVAS_LC3PLUS_DEC_Close( handle ); - return IVAS_ERROR( IVAS_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_dec_init failed\n" ); - } - - err = lc3plus_dec_set_frame_dms( ( *handle )->handles[iCh], config.lc3plus_frame_duration_us / 100 ); - if ( LC3PLUS_OK != err ) - { - IVAS_LC3PLUS_DEC_Close( handle ); - return IVAS_ERROR( IVAS_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_dec_set_frame_dms failed\n" ); - } - - /* allocate and configure per LC3plus decoder skip state */ - if ( ( ( *handle )->selective_decoding_states[iCh] = malloc( sizeof( IVAS_LC3PLUS_DEC_SELECTIVE_DECODING_STATE ) ) ) == NULL ) - { - IVAS_LC3PLUS_DEC_Close( handle ); - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus decoder\n" ); - } - - if ( ( ( *handle )->selective_decoding_states[iCh]->frame_actions = malloc( numLC3plusFramesPerIvasFrame * sizeof( SelectiveDecAction ) ) ) == NULL ) - { - IVAS_LC3PLUS_DEC_Close( handle ); - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus decoder\n" ); - } - - ( *handle )->selective_decoding_states[iCh]->has_skipped_a_frame = 0; - ( *handle )->selective_decoding_states[iCh]->shall_decode_cached_frame = 0; - for ( lc3plusFrameIdx = 0; lc3plusFrameIdx < numLC3plusFramesPerIvasFrame; lc3plusFrameIdx++ ) - { - ( *handle )->selective_decoding_states[iCh]->frame_actions[lc3plusFrameIdx] = DEC_ACTION_DECODE_AND_USE; - } - - /* allocate and configure per LC3plus decoder bitstream cache */ - if ( ( ( *handle )->bitstream_caches[iCh] = malloc( sizeof( IVAS_LC3PLUS_DEC_BITSTREAM_CACHE ) ) ) == NULL ) - { - IVAS_LC3PLUS_DEC_Close( handle ); - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus decoder\n" ); - } - ( *handle )->bitstream_caches[iCh]->bitstream_cache_capacity = 400 /*LC3plus max non-HR octet count*/ * numLC3plusFramesPerIvasFrame; - if ( ( ( *handle )->bitstream_caches[iCh]->bitstream_cache = malloc( ( *handle )->bitstream_caches[iCh]->bitstream_cache_capacity ) ) == NULL ) - { - IVAS_LC3PLUS_DEC_Close( handle ); - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus decoder\n" ); - } - ( *handle )->bitstream_caches[iCh]->bitstream_cache_size = 0; - } - - ( *handle )->config = config; - if ( config.ivas_frame_duration_us < config.lc3plus_frame_duration_us || config.ivas_frame_duration_us % config.lc3plus_frame_duration_us != 0 ) - { - IVAS_LC3PLUS_DEC_Close( handle ); - return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "Current pcm_conversion_buffer sizing requires that lc3plus uses a shorter or equal frame duration than ivas\n" ); - } - - if ( ( ( *handle )->pcm_conversion_buffer = malloc( sizeof( int16_t ) * config.samplerate * config.lc3plus_frame_duration_us / 1000000 ) ) == NULL ) - { - IVAS_LC3PLUS_DEC_Close( handle ); - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus decoder wrapper pcm_conversion_buffer\n" ); - } - - return IVAS_ERR_OK; -} - - -/*------------------------------------------------------------------------- - * IVAS_LC3PLUS_DEC_AllocateSubframeDecodingMatrix() - * - * - *------------------------------------------------------------------------*/ - -ivas_error IVAS_LC3PLUS_DEC_AllocateSubframeDecodingMatrix( - int16_t ***subframeChannelMatrix, - const uint32_t num_decs ) -{ - int16_t i; - - if ( ( *subframeChannelMatrix = malloc( MAX_PARAM_SPATIAL_SUBFRAMES * sizeof( int16_t * ) ) ) == NULL ) - { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "subframeChannelMatrix allocation failed\n" ); - } - - for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) - { - ( *subframeChannelMatrix )[i] = NULL; - } - - for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) - { - if ( ( ( *subframeChannelMatrix )[i] = malloc( num_decs * sizeof( int16_t ) ) ) == NULL ) - { - IVAS_LC3PLUS_DEC_FreeSubframeDecodingMatrix( *subframeChannelMatrix ); - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "subframeChannelMatrix allocation failed\n" ); - } - } - - return IVAS_ERR_OK; -} - - -/*------------------------------------------------------------------------- - * IVAS_LC3PLUS_DEC_AllocateSubframeDecodingMatrix() - * - * - *------------------------------------------------------------------------*/ - -void IVAS_LC3PLUS_DEC_FreeSubframeDecodingMatrix( - int16_t **subframeChannelMatrix ) -{ - for ( int16_t i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) - { - free( subframeChannelMatrix[i] ); - } - - free( subframeChannelMatrix ); - - return; -} - - -/*------------------------------------------------------------------------- - * IVAS_LC3PLUS_DEC_SetSelectiveDecodingMatrix() - * - * - *------------------------------------------------------------------------*/ - -ivas_error IVAS_LC3PLUS_DEC_SetSelectiveDecodingMatrix( - IVAS_LC3PLUS_DEC_HANDLE handle, /* i : LC3plus decoder handle */ - int16_t *subframeChannelMatrix[MAX_PARAM_SPATIAL_SUBFRAMES] ) -{ - int16_t numIvasSubFramesPerLC3frame; - uint32_t decIdx; - int16_t ivasSubframeIdx; - int16_t effectiveIvasSubframeDuration; - int16_t actual_num_spatial_subframes; - - if ( NULL == handle ) - { - return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "IVAS_LC3PLUS_DEC_HANDLE is NULL\n" ); - } - - if ( NULL == subframeChannelMatrix ) - { - return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "subframeChannelMatrix is NULL\n" ); - } - - if ( handle->config.lc3plus_frame_duration_us == 0 || handle->config.ivas_frame_duration_us % handle->config.lc3plus_frame_duration_us != 0 ) - { - return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "invalid ivas_frame_duration_us/lc3plus_frame_duration_us values\n" ); - } - - effectiveIvasSubframeDuration = (int16_t) ( handle->config.ivas_frame_duration_us == 20000 ? handle->config.ivas_frame_duration_us / MAX_PARAM_SPATIAL_SUBFRAMES : handle->config.ivas_frame_duration_us ); - numIvasSubFramesPerLC3frame = (int16_t) handle->config.lc3plus_frame_duration_us / effectiveIvasSubframeDuration; - actual_num_spatial_subframes = (int16_t) handle->config.ivas_frame_duration_us / effectiveIvasSubframeDuration; - /* 0.5(0) = 10ms lc3plus, 5ms subframe */ - if ( numIvasSubFramesPerLC3frame != 1 ) - { - return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "Selective decoding is only implemented for aligned IVAS-Subframes & LC3plus \n" ); - } - - /* map subframeChannelMatrix to lc3plus skip states */ - /* 1st pass: Flag the required frames */ - for ( decIdx = 0; decIdx < handle->num_decs; decIdx++ ) - { - for ( ivasSubframeIdx = 0; ivasSubframeIdx < actual_num_spatial_subframes; ivasSubframeIdx++ ) - { - if ( 1 == subframeChannelMatrix[ivasSubframeIdx][decIdx] ) - { - /* subframe needed by the user, definitely decode */ - handle->selective_decoding_states[decIdx]->frame_actions[ivasSubframeIdx] = DEC_ACTION_DECODE_AND_USE; - } - else - { - - /* subframe not needed by the user, but might be required to re-initialize a decoder after inactivity */ - if ( - ( ivasSubframeIdx != actual_num_spatial_subframes - 1 ) && 1 == subframeChannelMatrix[ivasSubframeIdx + 1][decIdx] ) - { - /* ... but if the following subframe is required, it needs to be decoded and dropped */ - handle->selective_decoding_states[decIdx]->frame_actions[ivasSubframeIdx] = DEC_ACTION_DECODE_AND_DROP; - } - else - { - handle->selective_decoding_states[decIdx]->frame_actions[ivasSubframeIdx] = DEC_ACTION_SKIP; - } - } - } - } - - /* if a decoder was paused before, it needs to either: - * - Decode the cached frame (if available) and the first required frame OR - * - Decode the previous LC3plus subframe, even if it isn't needed by the user */ - for ( decIdx = 0; decIdx < handle->num_decs; decIdx++ ) - { - if ( handle->selective_decoding_states[decIdx]->has_skipped_a_frame ) - { - /* find the first frame required by the user */ - for ( ivasSubframeIdx = 0; ivasSubframeIdx < actual_num_spatial_subframes; ivasSubframeIdx++ ) - { - if ( DEC_ACTION_DECODE_AND_USE == handle->selective_decoding_states[decIdx]->frame_actions[ivasSubframeIdx] ) - { - /* The first required frame is the first subframe. To flush the decoder, the cached frame must be decoded and dropped */ - if ( 0 == ivasSubframeIdx ) - { - handle->selective_decoding_states[decIdx]->shall_decode_cached_frame = 1; - break; - } - /* The first required frame is not the first frame, so the cache is useless. Instead we decode & drop the previous frame*/ - else - { - handle->selective_decoding_states[decIdx]->frame_actions[ivasSubframeIdx - 1] = DEC_ACTION_DECODE_AND_DROP; - break; - } - } - } - } - } - - /* if a dec gets paused & caching is activated we need to flag the last useful LC3plus frame for caching */ - for ( decIdx = 0; decIdx < handle->num_decs; decIdx++ ) - { - for ( ivasSubframeIdx = 0; ivasSubframeIdx < actual_num_spatial_subframes; ivasSubframeIdx++ ) - { - if ( handle->selective_decoding_states[decIdx]->frame_actions[ivasSubframeIdx] == DEC_ACTION_SKIP && handle->selective_decoding_states[decIdx]->frame_actions[actual_num_spatial_subframes - 1] != DEC_ACTION_DECODE_AND_USE ) - { - handle->selective_decoding_states[decIdx]->frame_actions[actual_num_spatial_subframes - 1] = DEC_ACTION_CACHE; - } - } - } - - return IVAS_ERR_OK; -} - - -/*------------------------------------------------------------------------- - * IVAS_LC3PLUS_DEC_GetDelay() - * - * - *------------------------------------------------------------------------*/ - -ivas_error IVAS_LC3PLUS_DEC_GetDelay( - IVAS_LC3PLUS_DEC_HANDLE handle, /* i : LC3plus decoder handle */ - int32_t *delayInSamples /* o : decoder delay in number of samples per channel */ -) -{ - int32_t tmpDelayInSamples; - - if ( NULL == handle ) - { - return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "IVAS_LC3PLUS_DEC_HANDLE is NULL\n" ); - } - if ( NULL == delayInSamples ) - { - return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "delayInSamples is NULL\n" ); - } - - *delayInSamples = 0; - /* sanity check whether all encoders are actually configured identically */ - for ( uint32_t iDec = 0; iDec < handle->num_decs; iDec++ ) - { - if ( NULL == handle->handles[iDec] ) - { - return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "LC3plus decoder handle is NULL\n" ); - } - - tmpDelayInSamples = lc3plus_dec_get_delay( handle->handles[iDec] ); - if ( 0 != *delayInSamples && tmpDelayInSamples != *delayInSamples ) - { - return IVAS_ERROR( IVAS_ERR_INTERNAL, "Not all mono LC3plus decoders are configured identically\n" ); - } - - *delayInSamples = tmpDelayInSamples; - } - - return IVAS_ERR_OK; -} - - -/*------------------------------------------------------------------------- - * IVAS_LC3PLUS_DEC_Close() - * - * - *------------------------------------------------------------------------*/ - -void IVAS_LC3PLUS_DEC_Close( - IVAS_LC3PLUS_DEC_HANDLE *handle /* i/o: Pointer to LC3plus decoder handle */ -) -{ - if ( NULL == handle || NULL == *handle ) - { - return; - } - for ( uint32_t iDec = 0; iDec < ( *handle )->num_decs; iDec++ ) - { - if ( NULL != ( *handle )->handles && NULL != ( *handle )->handles[iDec] ) - { - lc3plus_free_decoder_structs( ( *handle )->handles[iDec] ); - free( ( *handle )->handles[iDec] ); - } - - if ( NULL != ( *handle )->selective_decoding_states && NULL != ( *handle )->selective_decoding_states[iDec] ) - { - free( ( *handle )->selective_decoding_states[iDec]->frame_actions ); - free( ( *handle )->selective_decoding_states[iDec] ); - } - - if ( NULL != ( *handle )->bitstream_caches && NULL != ( *handle )->bitstream_caches[iDec] ) - { - free( ( *handle )->bitstream_caches[iDec]->bitstream_cache ); - free( ( *handle )->bitstream_caches[iDec] ); - } - } - - if ( NULL != ( *handle )->pcm_conversion_buffer ) - { - free( ( *handle )->pcm_conversion_buffer ); - } - free( ( *handle )->handles ); - - if ( NULL != ( *handle )->bitstream_caches ) - { - free( ( *handle )->bitstream_caches ); - } - free( ( *handle )->selective_decoding_states ); - - free( *handle ); - *handle = NULL; - - return; -} - - -/*------------------------------------------------------------------------- - * decode_or_conceal_one_lc3plus_frame() - * - * - *------------------------------------------------------------------------*/ - -static ivas_error decode_or_conceal_one_lc3plus_frame( - LC3PLUS_Dec *dec, - uint8_t *bitstream_in, - const int32_t bitstream_in_length, - int16_t **pcm_out_buffer, - const int32_t badFrameIndicator ) -{ - LC3PLUS_Error err; - - push_wmops( "lc3plus_dec16" ); - err = lc3plus_dec16( dec, bitstream_in, bitstream_in_length, pcm_out_buffer, NULL, badFrameIndicator ); - pop_wmops(); - - if ( err == LC3PLUS_DECODE_ERROR && 1 == badFrameIndicator ) - { - /* LC3PLUS_DECODE_ERROR && badFrameIndicator means that the decoder has successfully concealed, which is actually OK. */ - err = LC3PLUS_OK; - } - - if ( err != LC3PLUS_OK ) - { - return IVAS_ERROR( IVAS_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_dec16 failed\n" ); - } - - return IVAS_ERR_OK; -} - - -/*------------------------------------------------------------------------- - * IVAS_LC3PLUS_DEC_Decode_or_Conceal_internal() - * - * - *------------------------------------------------------------------------*/ - -static ivas_error IVAS_LC3PLUS_DEC_Decode_or_Conceal_internal( - IVAS_LC3PLUS_DEC_HANDLE handle, /* i : LC3plus decoder configuration */ - 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 */ -) -{ - uint32_t iDec; - int32_t iLc3plusFrame; - int32_t lc3framesPerIvasFrame; - int32_t ivasSampleIndex; - int16_t numSamplesPerLC3plusChannel; - int32_t bitstreamOffsetPerCoder; - ivas_error err; - uint8_t *bitstream_in_iter = bitstream_in; - - if ( NULL == handle ) - { - return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "LC3PLUS_Dec_Wrap_Handle is NULL\n" ); - } - if ( NULL == bitstream_in ) - { - return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "bitstream_in is NULL\n" ); - } - if ( NULL == pcm_out ) - { - return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "pcm_out is NULL\n" ); - } - if ( badFrameIndicator != 0 && badFrameIndicator != 1 ) - { - return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "badFrameIndicator must be 1 or 0\n" ); - } - if ( badFrameIndicator == 0 && bitstream_in_size <= 0 ) - { - return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "bitstream_in_size must be positive\n" ); - } - - if ( handle->config.ivas_frame_duration_us % handle->config.lc3plus_frame_duration_us != 0 ) - { - return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "ivas_frame_duration_us must be equal or multiple of lc3plus_frame_duration_us \n" ); - } - - lc3framesPerIvasFrame = handle->config.ivas_frame_duration_us / handle->config.lc3plus_frame_duration_us; - - numSamplesPerLC3plusChannel = (int16_t) ( handle->config.samplerate / ( 1000000 / handle->config.ivas_frame_duration_us ) / lc3framesPerIvasFrame ); - bitstreamOffsetPerCoder = bitstream_in_size / handle->num_decs / lc3framesPerIvasFrame; - for ( iDec = 0; iDec < handle->num_decs; iDec++ ) - { - for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) - { - if ( handle->selective_decoding_states[iDec]->shall_decode_cached_frame ) - { - if ( 0 == handle->bitstream_caches[iDec]->bitstream_cache_size ) - { - 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 ); - if ( err != IVAS_ERR_OK ) - { - return IVAS_ERROR( err, "lc3plus decoding failed\n" ); - } - handle->selective_decoding_states[iDec]->shall_decode_cached_frame = 0; - handle->selective_decoding_states[iDec]->has_skipped_a_frame = 0; - } - - /* reset cache if caching is enabled - it has either been decoded or is not needed */ - if ( NULL != handle->bitstream_caches ) - { - handle->bitstream_caches[iDec]->bitstream_cache_size = 0; - } - switch ( handle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] ) - { - 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 ); - if ( err != IVAS_ERR_OK ) - { - return IVAS_ERROR( err, "lc3plus decoding failed\n" ); - } - handle->selective_decoding_states[iDec]->has_skipped_a_frame = 0; - break; - } - case DEC_ACTION_DECODE_AND_USE: - { - err = decode_or_conceal_one_lc3plus_frame( handle->handles[iDec], bitstream_in_iter, bitstreamOffsetPerCoder, &handle->pcm_conversion_buffer, badFrameIndicator ); - if ( err != IVAS_ERR_OK ) - { - return IVAS_ERROR( err, "lc3plus decoding failed\n" ); - } - - for ( int32_t iSampleInt16 = 0; iSampleInt16 < numSamplesPerLC3plusChannel; iSampleInt16++ ) - { - ivasSampleIndex = iSampleInt16 + iLc3plusFrame * numSamplesPerLC3plusChannel; - pcm_out[iDec][ivasSampleIndex] = (float) handle->pcm_conversion_buffer[iSampleInt16]; - } - handle->selective_decoding_states[iDec]->has_skipped_a_frame = 0; - break; - } - case DEC_ACTION_SKIP: - { - /* log that this instance has skipped a frame and must decode twice once reactivated */ - handle->selective_decoding_states[iDec]->has_skipped_a_frame = 1; - break; - } - case DEC_ACTION_CACHE: - { - if ( handle->bitstream_caches[iDec]->bitstream_cache_capacity < bitstreamOffsetPerCoder ) - { - return IVAS_ERROR( IVAS_ERR_INVALID_BUFFER_SIZE, "bitstream_cache_capacity is too low for LC3plus frame size\n" ); - } - /* store bit rate of cached frame */ - mvc2c( bitstream_in_iter, handle->bitstream_caches[iDec]->bitstream_cache, (int16_t) bitstreamOffsetPerCoder ); - handle->bitstream_caches[iDec]->bitstream_cache_size = bitstreamOffsetPerCoder; - /* log that this instance has skipped a frame and must decode twice once reactivated */ - handle->selective_decoding_states[iDec]->has_skipped_a_frame = 1; - break; - } - case DEC_ACTION_NUM_ENUMS: - default: - return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "invalid LC3plus decoder state\n" ); - } - - bitstream_in_iter += bitstreamOffsetPerCoder; - } - - /* reset skipping state, must be set by the user before each decode call*/ - for ( iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) - { - handle->selective_decoding_states[iDec]->frame_actions[iLc3plusFrame] = DEC_ACTION_DECODE_AND_USE; - } - } - - return IVAS_ERR_OK; -} - - -/*------------------------------------------------------------------------- - * IVAS_LC3PLUS_DEC_Decode() - * - * - *------------------------------------------------------------------------*/ - -ivas_error IVAS_LC3PLUS_DEC_Decode( - IVAS_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 */ -) -{ - int16_t badFrameIndicator; - - if ( NULL == handle ) - { - return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "LC3PLUS_Dec_Wrap_Handle is NULL\n" ); - } - if ( NULL == bitstream_in ) - { - return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "bitstream_in is NULL\n" ); - } - if ( NULL == pcm_out ) - { - return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "pcm_out is NULL\n" ); - } - badFrameIndicator = 0; - - return IVAS_LC3PLUS_DEC_Decode_or_Conceal_internal( handle, bitstream_in, bitstream_in_size, badFrameIndicator, pcm_out ); -} - - -/*------------------------------------------------------------------------- - * IVAS_LC3PLUS_DEC_Conceal() - * - * - *------------------------------------------------------------------------*/ - -ivas_error IVAS_LC3PLUS_DEC_Conceal( - IVAS_LC3PLUS_DEC_HANDLE handle, /* i : LC3plus decoder handle */ - float **pcm_out /* o : concealed samples */ -) -{ - uint8_t bitstream_in[LC3PLUS_MAX_BYTES]; - int16_t badFrameIndicator; - - if ( NULL == handle ) - { - return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "LC3PLUS_Dec_Wrap_Handle is NULL\n" ); - } - - if ( NULL == pcm_out ) - { - return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "pcm_out is NULL\n" ); - } - - /* LC3plus API requires a non-NULL bitstream pointer, even when triggering concealment */ - badFrameIndicator = 1; - - return IVAS_LC3PLUS_DEC_Decode_or_Conceal_internal( handle, bitstream_in, 0, badFrameIndicator, pcm_out ); -} -#endif /* SPLIT_REND_WITH_HEAD_ROT */ diff --git a/lib_rend/ivas_lc3plus_dec.h b/lib_rend/ivas_lc3plus_dec.h deleted file mode 100644 index 6e6f13f62..000000000 --- a/lib_rend/ivas_lc3plus_dec.h +++ /dev/null @@ -1,119 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2023 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 IVAS_LC3PLUS_DEC_H -#define IVAS_LC3PLUS_DEC_H - -#include -#include "options.h" -#include "lc3.h" -#include "ivas_error.h" -#include "ivas_lc3plus_common.h" -#include "ivas_cnst.h" - -typedef enum -{ - DEC_ACTION_DECODE_AND_DROP = 0, - DEC_ACTION_DECODE_AND_USE, - DEC_ACTION_SKIP, - DEC_ACTION_CACHE, - DEC_ACTION_NUM_ENUMS -} SelectiveDecAction; - - -typedef struct IVAS_LC3PLUS_DEC_SELECTIVE_DECODING_STATE -{ - /*! indicates that the decoder has skipped one or more frames. This means it must decode two frames to flush algorithmic delay when re-activated */ - int16_t has_skipped_a_frame; - /*! if set to 1, decoder will skip decoding for the next frame */ - SelectiveDecAction *frame_actions; - /*! if set to 1, decoder will decode the cache before decoding any of current frames */ - int16_t shall_decode_cached_frame; -} IVAS_LC3PLUS_DEC_SELECTIVE_DECODING_STATE; - -typedef struct IVAS_LC3PLUS_DEC_BITSTREAM_CACHE -{ - uint8_t *bitstream_cache; - int32_t bitstream_cache_capacity; - int32_t bitstream_cache_size; -} IVAS_LC3PLUS_DEC_BITSTREAM_CACHE; - -/* decoder wrapper */ -typedef struct IVAS_LC3PLUS_DEC_HANDLE -{ - LC3PLUS_Dec **handles; - IVAS_LC3PLUS_DEC_SELECTIVE_DECODING_STATE **selective_decoding_states; - IVAS_LC3PLUS_DEC_BITSTREAM_CACHE **bitstream_caches; - uint32_t num_decs; - int16_t *pcm_conversion_buffer; - LC3PLUS_CONFIG config; -} * IVAS_LC3PLUS_DEC_HANDLE; - -ivas_error IVAS_LC3PLUS_DEC_Open( - const LC3PLUS_CONFIG config, /* i : decoder configuration */ - IVAS_LC3PLUS_DEC_HANDLE *handle /* o : decoder handle */ -); - -ivas_error IVAS_LC3PLUS_DEC_GetDelay( - IVAS_LC3PLUS_DEC_HANDLE handle, /* i : decoder handle */ - int32_t *delayInSamples /* o : algorithmic delay of encoding and decoding in number of samples per channel */ -); - -void IVAS_LC3PLUS_DEC_Close( - IVAS_LC3PLUS_DEC_HANDLE *handle /* i/o: pointer to decoder handle */ -); - -/*! Sets a matrix[MAX_PARAM_SPATIAL_SUBFRAMES][numLC3plusDecoders] where all require subframes must be flagged with 1, frames that are not required with 0 */ -ivas_error IVAS_LC3PLUS_DEC_SetSelectiveDecodingMatrix( - IVAS_LC3PLUS_DEC_HANDLE handle, /* i : decoder handle */ - int16_t *subframeChannelMatrix[MAX_PARAM_SPATIAL_SUBFRAMES] /* i : */ -); - -ivas_error IVAS_LC3PLUS_DEC_Decode( - IVAS_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 */ -); - -ivas_error IVAS_LC3PLUS_DEC_Conceal( - IVAS_LC3PLUS_DEC_HANDLE handle, /* i : decoder handle */ - float **pcm_out /* o : concealed samples */ -); - -ivas_error IVAS_LC3PLUS_DEC_AllocateSubframeDecodingMatrix( - int16_t ***subframeChannelMatrix, - const uint32_t num_decs ); - -void IVAS_LC3PLUS_DEC_FreeSubframeDecodingMatrix( int16_t **subframeChannelMatrix ); - -#endif /* IVAS_LC3PLUS_DEC_H */ diff --git a/lib_rend/ivas_lc3plus_enc.c b/lib_rend/ivas_lc3plus_enc.c deleted file mode 100644 index 8751d3dac..000000000 --- a/lib_rend/ivas_lc3plus_enc.c +++ /dev/null @@ -1,334 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2023 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. - -*******************************************************************************************************/ - -#include "ivas_lc3plus_enc.h" -#include "ivas_lc3plus_common.h" -#include "lc3.h" -#include "ivas_error_utils.h" -#include "prot.h" -#include "wmc_auto.h" - -#ifdef SPLIT_REND_WITH_HEAD_ROT -/*-------------------------------------------------------------------* - * Function IVAS_LC3PLUS_ENC_Open() - * - * - *-------------------------------------------------------------------*/ - -ivas_error IVAS_LC3PLUS_ENC_Open( - const LC3PLUS_CONFIG config, /* i : LC3plus encoder configuration */ - const uint32_t bitsPerSecond, /* i : bit rate */ - IVAS_LC3PLUS_ENC_HANDLE *handle /* o : encoder handle */ -) -{ - int32_t bitsPerSecondPerChannel; - int32_t encoder_size; - LC3PLUS_Error err; - int32_t lfeChans[1]; - int16_t i; - - lfeChans[0] = 0; - - if ( 0U == config.channels ) - { - return IVAS_ERROR( IVAS_ERR_INTERNAL, "Invalid number of channels\n" ); - } - bitsPerSecondPerChannel = bitsPerSecond / config.channels; - - encoder_size = lc3plus_enc_get_size( config.samplerate, 1 ); - if ( 0 == encoder_size ) - { - return IVAS_ERROR( IVAS_ERR_INTERNAL, "lc3plus_enc_get_size failed\n" ); - } - - if ( ( *handle = malloc( sizeof( struct IVAS_LC3PLUS_ENC_HANDLE ) ) ) == NULL ) - { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus wrapper handle\n" ); - } - - ( *handle )->pcm_conversion_buffer = NULL; - ( *handle )->num_encs = 0; - if ( ( ( *handle )->handles = malloc( config.channels * sizeof( IVAS_LC3PLUS_ENC_HANDLE ) ) ) == NULL ) - { - IVAS_LC3PLUS_ENC_Close( handle ); - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus wrapper handle\n" ); - } - - for ( i = 0; i < config.channels; ++i ) - { - ( *handle )->handles[i] = NULL; - } - ( *handle )->num_encs = config.channels; - - for ( int32_t iCh = 0; iCh < config.channels; iCh++ ) - { - if ( ( ( *handle )->handles[iCh] = malloc( encoder_size ) ) == NULL ) - { - IVAS_LC3PLUS_ENC_Close( handle ); - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus encoder\n" ); - } - - err = lc3plus_enc_init( ( *handle )->handles[iCh], config.samplerate, 1, 0, lfeChans ); - if ( err != LC3PLUS_OK ) - { - IVAS_LC3PLUS_ENC_Close( handle ); - return IVAS_ERROR( IVAS_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_enc_init failed\n" ); - } - - err = lc3plus_enc_set_frame_dms( ( *handle )->handles[iCh], config.lc3plus_frame_duration_us / 100 ); - if ( err != LC3PLUS_OK ) - { - IVAS_LC3PLUS_ENC_Close( handle ); - return IVAS_ERROR( IVAS_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_enc_set_frame_dms failed\n" ); - } - - err = lc3plus_enc_set_bitrate( ( *handle )->handles[iCh], bitsPerSecondPerChannel ); - if ( err != LC3PLUS_OK ) - { - IVAS_LC3PLUS_ENC_Close( handle ); - return IVAS_ERROR( IVAS_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_enc_set_bitrate failed\n" ); - } - } - - if ( config.ivas_frame_duration_us < config.lc3plus_frame_duration_us || config.ivas_frame_duration_us % config.lc3plus_frame_duration_us != 0 ) - { - IVAS_LC3PLUS_ENC_Close( handle ); - return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "Current pcm_conversion_buffer sizing requires that lc3plus uses a shorter or equal frame duration than ivas\n" ); - } - - ( *handle )->config = config; - ( *handle )->pcm_conversion_buffer = malloc( sizeof( int16_t ) * config.samplerate * config.lc3plus_frame_duration_us / 1000000 ); - if ( NULL == ( *handle )->pcm_conversion_buffer ) - { - IVAS_LC3PLUS_ENC_Close( handle ); - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LC3plus encoder wrapper pcm_conversion_buffer\n" ); - } - - return IVAS_ERR_OK; -} - - -/*-------------------------------------------------------------------* - * Function IVAS_LC3PLUS_ENC_GetDelay() - * - * - *-------------------------------------------------------------------*/ - -ivas_error IVAS_LC3PLUS_ENC_GetDelay( - IVAS_LC3PLUS_ENC_HANDLE handle, /* i : LC3plus encoder handle */ - int32_t *delayInSamples /* o : encoder delay in number of samples per channel */ -) -{ - int32_t tmpDelayInSamples; - - if ( NULL == handle ) - { - return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "LC3PLUS_Enc_Wrap_Handle is NULL\n" ); - } - if ( NULL == delayInSamples ) - { - return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "delayInSamples is NULL\n" ); - } - - *delayInSamples = 0; - /* sanity check whether all encoders are actually configured identically */ - for ( uint32_t iEnc = 0; iEnc < handle->num_encs; iEnc++ ) - { - if ( NULL == handle->handles[iEnc] ) - { - return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "LC3plus encoder handle is NULL\n" ); - } - - tmpDelayInSamples = lc3plus_enc_get_delay( handle->handles[iEnc] ); - if ( 0 != *delayInSamples && tmpDelayInSamples != *delayInSamples ) - { - return IVAS_ERROR( IVAS_ERR_INTERNAL, "Not all mono LC3plus encoders are configured identically\n" ); - } - *delayInSamples = tmpDelayInSamples; - } - - return IVAS_ERR_OK; -} - - -/*-------------------------------------------------------------------* - * Function IVAS_LC3PLUS_ENC_GetOutputBitstreamSize() - * - * - *-------------------------------------------------------------------*/ - -ivas_error IVAS_LC3PLUS_ENC_GetOutputBitstreamSize( - IVAS_LC3PLUS_ENC_HANDLE handle, /* i : LC3plus encoder handle */ - int32_t *bsSize /* o : size of each bitstream frame in bytes */ -) -{ - int32_t bitstreamSizeMultiplier; - if ( NULL == handle ) - { - return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "LC3PLUS_Enc_Wrap_Handle is NULL\n" ); - } - if ( NULL == bsSize ) - { - return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "bsSize is NULL\n" ); - } - - *bsSize = 0; - for ( uint32_t iEnc = 0; iEnc < handle->num_encs; iEnc++ ) - { - if ( NULL == handle->handles[iEnc] ) - { - return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "LC3plus encoder handle is NULL\n" ); - } - *bsSize += lc3plus_enc_get_num_bytes( handle->handles[iEnc] ); - } - - if ( handle->config.ivas_frame_duration_us % handle->config.lc3plus_frame_duration_us != 0 ) - { - return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "ivas_frame_duration_us must be equal or multiple of lc3plus_frame_duration_us \n" ); - } - bitstreamSizeMultiplier = handle->config.ivas_frame_duration_us / handle->config.lc3plus_frame_duration_us; - - *bsSize *= bitstreamSizeMultiplier; - - return IVAS_ERR_OK; -} - - -/*-------------------------------------------------------------------* - * Function IVAS_LC3PLUS_ENC_Close() - * - * - *-------------------------------------------------------------------*/ - -void IVAS_LC3PLUS_ENC_Close( - IVAS_LC3PLUS_ENC_HANDLE *handle /* i/o: pointer to LC3plus encoder handle */ -) -{ - if ( NULL == handle || NULL == *handle ) - { - return; - } - for ( uint32_t iEnc = 0; iEnc < ( *handle )->num_encs; iEnc++ ) - { - if ( NULL != ( *handle )->handles[iEnc] ) - { - lc3plus_free_encoder_structs( ( *handle )->handles[iEnc] ); - free( ( *handle )->handles[iEnc] ); - } - } - if ( NULL != ( *handle )->pcm_conversion_buffer ) - { - free( ( *handle )->pcm_conversion_buffer ); - } - - free( ( *handle )->handles ); - free( *handle ); - - *handle = NULL; - - return; -} - - -/*-------------------------------------------------------------------* - * Function IVAS_LC3PLUS_ENC_Encode() - * - * - *-------------------------------------------------------------------*/ - -ivas_error IVAS_LC3PLUS_ENC_Encode( - IVAS_LC3PLUS_ENC_HANDLE handle, /* i : LC3plus encoder handle */ - float **pcm_in, /* i : pointer input samples */ - void *bitstream_out /* o : pointer to bitstream frame */ -) -{ - uint32_t numSamplesPerLC3plusChannel; - uint32_t lc3framesPerIvasFrame; - int32_t ivasSampleIndex; - uint8_t *bitstream_out_iter = bitstream_out; - int32_t num_bytes = 0; - LC3PLUS_Error err; - - push_wmops( "IVAS_LC3PLUS_ENC_Encode" ); - - if ( NULL == handle ) - { - return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "LC3PLUS_Enc_Wrap_Handle is NULL\n" ); - } - if ( NULL == pcm_in ) - { - return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "pcm_in is NULL\n" ); - } - if ( NULL == bitstream_out ) - { - return IVAS_ERROR( IVAS_ERR_UNEXPECTED_NULL_POINTER, "bitstream_out is NULL\n" ); - } - - if ( handle->config.ivas_frame_duration_us % handle->config.lc3plus_frame_duration_us != 0 ) - { - return IVAS_ERROR( IVAS_ERR_NOT_IMPLEMENTED, "ivas_frame_duration_us must be equal or multiple of lc3plus_frame_duration_us \n" ); - } - lc3framesPerIvasFrame = handle->config.ivas_frame_duration_us / handle->config.lc3plus_frame_duration_us; - - numSamplesPerLC3plusChannel = handle->config.samplerate / ( 1000000 / handle->config.ivas_frame_duration_us ) / lc3framesPerIvasFrame; - for ( uint32_t iEnc = 0; iEnc < handle->num_encs; iEnc++ ) - { - for ( uint32_t iLc3plusFrame = 0; iLc3plusFrame < lc3framesPerIvasFrame; iLc3plusFrame++ ) - { - for ( uint32_t iSampleInt16 = 0; iSampleInt16 < numSamplesPerLC3plusChannel; iSampleInt16++ ) - { - ivasSampleIndex = iSampleInt16 + iLc3plusFrame * numSamplesPerLC3plusChannel; - handle->pcm_conversion_buffer[iSampleInt16] = (int16_t) max( INT16_MIN, min( pcm_in[iEnc][ivasSampleIndex], INT16_MAX ) ); - } - - num_bytes = 0; - push_wmops( "lc3plus_enc16" ); - err = lc3plus_enc16( handle->handles[iEnc], &handle->pcm_conversion_buffer, bitstream_out_iter, &num_bytes, NULL ); - pop_wmops(); - if ( err != LC3PLUS_OK ) - { - return IVAS_ERROR( IVAS_LC3PLUS_LC3plusErrToIvasErr( err ), "lc3plus_enc16 failed\n" ); - } - if ( 0 == num_bytes ) - { - return IVAS_ERROR( IVAS_ERR_INTERNAL, "lc3plus_enc16 did not produce output\n" ); - } - - bitstream_out_iter += num_bytes; - } - } - - pop_wmops(); - - return IVAS_ERR_OK; -} -#endif /* SPLIT_REND_WITH_HEAD_ROT */ diff --git a/lib_rend/ivas_lc3plus_enc.h b/lib_rend/ivas_lc3plus_enc.h deleted file mode 100644 index d58ecf1b6..000000000 --- a/lib_rend/ivas_lc3plus_enc.h +++ /dev/null @@ -1,76 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2023 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 IVAS_LC3PLUS_ENC_H -#define IVAS_LC3PLUS_ENC_H - -#include -#include "lc3.h" -#include "ivas_error.h" -#include "ivas_lc3plus_common.h" - -/* encoder wrapper */ -typedef struct IVAS_LC3PLUS_ENC_HANDLE -{ - LC3PLUS_CONFIG config; - LC3PLUS_Enc **handles; - uint32_t num_encs; - int16_t *pcm_conversion_buffer; -} * IVAS_LC3PLUS_ENC_HANDLE; - -ivas_error IVAS_LC3PLUS_ENC_Open( - const LC3PLUS_CONFIG config, /* i : encoder configuration */ - const uint32_t bitsPerSecond, /* i : bit rate */ - IVAS_LC3PLUS_ENC_HANDLE *handle /* o : LC3plus encoder handle */ -); - -ivas_error IVAS_LC3PLUS_ENC_GetDelay( - IVAS_LC3PLUS_ENC_HANDLE handle, /* i : LC3plus encoder handle */ - int32_t *delayInSamples /* o : algorithmic delay of encoding and decoding in number of samples per channel */ -); - -ivas_error IVAS_LC3PLUS_ENC_GetOutputBitstreamSize( - IVAS_LC3PLUS_ENC_HANDLE handle, /* i : LC3plus encoder handle */ - int32_t *bsSize /* o : size of each bitstream frame in bytes */ -); - -void IVAS_LC3PLUS_ENC_Close( - IVAS_LC3PLUS_ENC_HANDLE *handle /* i/o: pointer to LC3plus encoder handle */ -); - -ivas_error IVAS_LC3PLUS_ENC_Encode( - IVAS_LC3PLUS_ENC_HANDLE handle, /* i : LC3plus encoder handle */ - float **pcm_in, /* i : pointer input samples */ - void *bitstream_out /* o : pointer to bitstream frame */ -); - -#endif /* IVAS_LC3PLUS_ENC_H */ diff --git a/lib_rend/ivas_lcld_decoder.c b/lib_rend/ivas_lcld_decoder.c deleted file mode 100644 index 8aafcb1fa..000000000 --- a/lib_rend/ivas_lcld_decoder.c +++ /dev/null @@ -1,1668 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2023 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. - -*******************************************************************************************************/ - -#include -#include "options.h" -#ifdef SPLIT_REND_WITH_HEAD_ROT -#include "ivas_lcld_prot.h" -#include "ivas_lcld_rom_tables.h" -#include "prot.h" -#include -#include "ivas_prot_rend.h" -#include "wmc_auto.h" - - -/*------------------------------------------------------------------------------------------* - * Local constants - *------------------------------------------------------------------------------------------*/ - -#define HUFF_READ_SIZE ( 4 ) - -/*------------------------------------------------------------------------------------------* - * Local structures - *------------------------------------------------------------------------------------------*/ - -typedef struct TableNode -{ - struct TableNode **ppoNextTable; - struct TableNode *poOrderedNext; - - int32_t *piCodeIndex; - int32_t *piDifference; - int32_t *piLength; -} TableNode; -typedef struct TableList -{ - TableNode *poOrderedTop; - TableNode *poOrderedBottom; - -} TableList; - -struct LCLD_DECODER -{ - int32_t iSampleRate; - int32_t iChannels; - int32_t iNumBlocks; - - int32_t iNumBands; - const int32_t *piBandwidths; - - int32_t iMSMode; - int32_t *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]; -#ifdef ENABLE_PMOD_ADJUST - int32_t **ppiHiSMRFlags; -#endif - 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 ***pppiLCLDSignReal; - int32_t ***pppiLCLDSignImag; - int32_t ***pppiQLCLDReal; - int32_t ***pppiQLCLDImag; - - PredictionDecoder *psPredictionDecoder; - - - NoiseGen *psNoiseGen; -}; - -static void CreateDecodeTable( LCLDDecoder *psLCLDDecoder, int32_t num, const uint16_t ( *ppuiEncTable )[2], int32_t iSize, int32_t iReadLength, uint32_t *iTables ); -static TableNode *CreateTableList( int32_t iReadLength ); -static void DeleteTableList( TableList *ptable_list, int32_t iTables ); -static TableNode *GetNextTable( int32_t iIndex, TableList *table_list, TableNode *poParent, int32_t iReadLength, uint32_t *iTablesCreated ); -static void AddcodeTableList( TableList *ptable_list, int32_t iLength, int32_t iCode, int32_t iCodeIndex, int32_t iReadLength, uint32_t *iTables ); -static void CompleteTables( LCLDDecoder *psLCLDDecoder, int32_t n, TableList *ptable_list, int32_t iReadLength, int32_t iTablesCreated ); - -static TableNode *CreateTableList( int32_t iReadLength ) -{ - int32_t n; - int32_t iMaxTables; - TableNode *ptable_top; - iMaxTables = 1 << 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->ppoNextTable[n] = NULL; - ptable_top->piCodeIndex[n] = 0xffff; - ptable_top->piDifference[n] = 0; - ptable_top->piLength[n] = 0; - } - - return ptable_top; -} -static void DeleteTableList( TableList *ptable_list, int32_t iTables ) -{ - - TableNode *node; - node = ptable_list->poOrderedTop; - - while ( ( iTables ) ) - { - - TableNode *node1 = node; - node = node1->poOrderedNext; - if ( node1->piCodeIndex != NULL ) - { - free( node1->piCodeIndex ); - } - if ( node1->piLength != NULL ) - { - free( node1->piLength ); - } - if ( node1->piDifference != NULL ) - { - free( node1->piDifference ); - } - if ( node1->ppoNextTable != NULL ) - { - free( node1->ppoNextTable ); - } - if ( node1 != NULL ) - { - free( node1 ); - } - iTables--; - } - if ( ptable_list != NULL ) - { - free( ptable_list ); - } -} -static TableNode *GetNextTable( int32_t iIndex, TableList *table_list, TableNode *poParent, int32_t iReadLength, uint32_t *iTablesCreated ) -{ - TableNode *poNextNode; - - 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 */ - table_list->poOrderedBottom->poOrderedNext = poNextNode; - table_list->poOrderedBottom = poNextNode; - - ( *iTablesCreated )++; - } - else - { - poNextNode = poParent->ppoNextTable[iIndex]; - } - - return poNextNode; -} -static void CompleteTables( LCLDDecoder *psLCLDDecoder, int32_t n, TableList *ptable_list, int32_t iReadLength, int32_t iTablesCreated ) -{ - - int32_t iMaxTables; - int32_t j; - TableNode *poNode; - - iMaxTables = 1 << iReadLength; - psLCLDDecoder->c_apauiHuffDecTable_RAM[n] = - malloc( iTablesCreated * iMaxTables * sizeof( uint32_t * ) ); - - poNode = ptable_list->poOrderedTop; - for ( j = 0; j < iTablesCreated; j++ ) - { - int32_t k; - if ( poNode != NULL ) - { - for ( k = 0; k < iMaxTables; k++ ) - { - uint32_t uiCode; - uiCode = poNode->piDifference[k]; - uiCode <<= 16; - uiCode |= poNode->piCodeIndex[k]; - psLCLDDecoder->c_apauiHuffDecTable_RAM[n][j][k] = uiCode; - } - } - poNode = poNode->poOrderedNext; - } -} -static void AddcodeTableList( TableList *ptable_list, int32_t iLength, int32_t iCode, int32_t iCodeIndex, int32_t iReadLength, uint32_t *iTables ) -{ - int32_t iDifference; - int32_t iMask; - int32_t iCurrentLength; - int32_t iIndex; - int32_t iCodeLow; - int32_t iCodeHigh; - - TableNode *poNode; - poNode = ptable_list->poOrderedTop; - iMask = ( 1 << iReadLength ) - 1; - iCurrentLength = iLength; - while ( iCurrentLength > iReadLength ) - { - iDifference = iCurrentLength - iReadLength; - iIndex = iCode >> iDifference; - iIndex &= iMask; - poNode = GetNextTable( iIndex, ptable_list, poNode, iReadLength, iTables ); - 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++ ) - { - poNode->piCodeIndex[iIndex] = iCodeIndex; - poNode->piDifference[iIndex] = iDifference; - poNode->piLength[iIndex] = iLength; - } -} - -static void CreateDecodeTable( LCLDDecoder *psLCLDDecoder, int32_t num, const uint16_t ( *ppuiEncTable )[2], int32_t iSize, int32_t iReadLength, uint32_t *iTables ) -{ - int32_t n; - uint32_t **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[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; - } - - for ( n = 0; n < iSize; n++ ) - { - uint32_t iMin; - int32_t iMinIndex; - int32_t k; - - iMin = ppsort_enc_table[n][0]; - iMinIndex = n; - for ( k = n; k < iSize; k++ ) - { - if ( ppsort_enc_table[k][0] < iMin ) - { - iMin = ppsort_enc_table[k][0]; - iMinIndex = k; - } - } - - if ( iMinIndex != n ) - { - uint32_t uiLength; - uint32_t uiCode; - uint32_t uiCodeIndex; - - uiLength = ppsort_enc_table[n][0]; - uiCode = ppsort_enc_table[n][1]; - uiCodeIndex = ppsort_enc_table[n][2]; - - ppsort_enc_table[n][0] = ppsort_enc_table[iMinIndex][0]; - ppsort_enc_table[n][1] = ppsort_enc_table[iMinIndex][1]; - ppsort_enc_table[n][2] = ppsort_enc_table[iMinIndex][2]; - - ppsort_enc_table[iMinIndex][0] = uiLength; - ppsort_enc_table[iMinIndex][1] = uiCode; - ppsort_enc_table[iMinIndex][2] = uiCodeIndex; - } - } - ptable_list->poOrderedTop = CreateTableList( iReadLength ); - ptable_list->poOrderedBottom = ptable_list->poOrderedTop; - for ( n = 0; n < iSize; n++ ) - { - int32_t iLength; - int32_t iCode; - int32_t iCodeIndex; - - iLength = ppsort_enc_table[n][0]; - iCode = ppsort_enc_table[n][1]; - iCodeIndex = ppsort_enc_table[n][2]; - 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++ ) - { - free( ppsort_enc_table[n] ); - } - free( ppsort_enc_table ); -} - - -/*------------------------------------------------------------------------------------------* - * Function CreateLCLDDecoder() - * - * - *------------------------------------------------------------------------------------------*/ - -ivas_error CreateLCLDDecoder( - LCLDDecoder **psLCLDDecoder_out, - const int32_t iSampleRate, - const int32_t iChannels ) -{ - int32_t n; - int32_t read_length; - ivas_error error; - LCLDDecoder *psLCLDDecoder = NULL; - - assert( iSampleRate == 48000 ); // Fix - - 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; - psLCLDDecoder->iChannels = iChannels; - psLCLDDecoder->iNumBlocks = LCLD_BLOCKS_PER_FRAME; - psLCLDDecoder->iAllocOffset = 0; - - psLCLDDecoder->iNumBands = MAX_BANDS_48; // Fix - psLCLDDecoder->piBandwidths = c_aiBandwidths48; // Fix - - psLCLDDecoder->iMSMode = 0; - if ( ( psLCLDDecoder->piMSFlags = (int32_t *) malloc( MAX_BANDS * sizeof( int32_t ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); - } - for ( n = 0; n < MAX_BANDS; n++ ) - { - psLCLDDecoder->piLRPhaseDiffs[n] = 0; - psLCLDDecoder->piMSPredCoefs[n] = 0; - } -#ifdef ENABLE_PMOD_ADJUST - psLCLDDecoder->ppiHiSMRFlags = - (int32_t **) malloc( psLCLDDecoder->iChannels * sizeof( int32_t * ) ); -#endif - - psLCLDDecoder->iCommonGrouping = 1; /* Common grouping always on only impacts stereo */ - if ( ( psLCLDDecoder->piNumGroups = (int32_t *) malloc( psLCLDDecoder->iChannels * sizeof( int32_t ) ) ) == 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 ) - { - 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 ) - { - 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 ) - { - 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 ) - { - 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 ) - { - 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 ) - { - 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 ) - { - 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 ) - { - 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 ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); - } - - for ( n = 0; n < iChannels; n++ ) - { - int16_t k; -#ifdef ENABLE_PMOD_ADJUST - psLCLDDecoder->ppiHiSMRFlags[n] = - (int32_t *) malloc( MAX_BANDS * sizeof( int32_t ) ); - ; -#endif - if ( ( psLCLDDecoder->ppiGroupLengths[n] = (int32_t *) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( int32_t ) ) ) == 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 ) - { - 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 ) - { - 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 ) - { - 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 ) - { - 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 ) - { - 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 ) - { - 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 ) - { - 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 ) - { - 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++ ) - { - if ( ( psLCLDDecoder->pppiRMSEnvelope[n][k] = (int32_t *) malloc( MAX_BANDS * sizeof( int32_t ) ) ) == 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 ) - { - 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 ) - { - 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 ) - { - 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 ) - { - 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 ) - { - 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 ) - { - 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 ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); - } - } - } - - read_length = READ_LENGTH; - for ( n = 0; n < ALLOC_TABLE_SIZE * 2; n++ ) - { - psLCLDDecoder->num_decode_table[n] = 1; - if ( c_apauiHuffEncTabels[n] != NULL ) - { - - CreateDecodeTable( psLCLDDecoder, n, c_apauiHuffEncTabels[n], num_row_aauiLCLDHuff[n], read_length, &psLCLDDecoder->num_decode_table[n] ); - } - else - { - psLCLDDecoder->c_apauiHuffDecTable_RAM[n] = NULL; - } - } - - if ( ( error = CreatePredictionDecoder( &psLCLDDecoder->psPredictionDecoder, iChannels, psLCLDDecoder->iNumBlocks ) ) != IVAS_ERR_OK ) - { - return error; - } - psLCLDDecoder->psNoiseGen = NULL; // CreateNoiseGen(); // No noise fill for now - *psLCLDDecoder_out = psLCLDDecoder; - - return IVAS_ERR_OK; -} - - -/*------------------------------------------------------------------------------------------* - * Function CreateLCLDDecoder() - * - * - *------------------------------------------------------------------------------------------*/ - -void DeleteLCLDDecoder( LCLDDecoder *psLCLDDecoder ) -{ - int32_t k, n; - - if ( psLCLDDecoder != NULL ) - { - if ( psLCLDDecoder->piMSFlags != NULL ) - { - free( psLCLDDecoder->piMSFlags ); - } - - if ( psLCLDDecoder->piNumGroups != NULL ) - { - free( psLCLDDecoder->piNumGroups ); - } - - if ( psLCLDDecoder->ppiGroupLengths != NULL ) - { - for ( n = 0; n < psLCLDDecoder->iChannels; n++ ) - { - free( psLCLDDecoder->ppiGroupLengths[n] ); - } - free( psLCLDDecoder->ppiGroupLengths ); - } - - if ( psLCLDDecoder->pppiRMSEnvelope != NULL ) - { - for ( n = 0; n < psLCLDDecoder->iChannels; n++ ) - { - for ( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) - { - free( psLCLDDecoder->pppiRMSEnvelope[n][k] ); - } - free( psLCLDDecoder->pppiRMSEnvelope[n] ); - } - free( psLCLDDecoder->pppiRMSEnvelope ); - } - - if ( psLCLDDecoder->pppiSMR != NULL ) - { - for ( n = 0; n < psLCLDDecoder->iChannels; n++ ) - { - for ( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) - { - free( psLCLDDecoder->pppiSMR[n][k] ); - } - free( psLCLDDecoder->pppiSMR[n] ); - } - free( psLCLDDecoder->pppiSMR ); - } - - if ( psLCLDDecoder->pppiExcitation != NULL ) - { - for ( n = 0; n < psLCLDDecoder->iChannels; n++ ) - { - for ( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) - { - free( psLCLDDecoder->pppiExcitation[n][k] ); - } - free( psLCLDDecoder->pppiExcitation[n] ); - } - free( psLCLDDecoder->pppiExcitation ); - } - -#ifdef ENABLE_PMOD_ADJUST - if ( psLCLDDecoder->ppiHiSMRFlags != NULL ) - { - for ( n = 0; n < psLCLDDecoder->iChannels; n++ ) - { - free( psLCLDDecoder->ppiHiSMRFlags[n] ); - } - free( psLCLDDecoder->ppiHiSMRFlags ); - } -#endif - - if ( psLCLDDecoder->pppiAlloc != NULL ) - { - for ( n = 0; n < psLCLDDecoder->iChannels; n++ ) - { - for ( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) - { - free( psLCLDDecoder->pppiAlloc[n][k] ); - } - free( psLCLDDecoder->pppiAlloc[n] ); - } - free( psLCLDDecoder->pppiAlloc ); - } - - if ( psLCLDDecoder->pppiLCLDSignReal != NULL ) - { - for ( n = 0; n < psLCLDDecoder->iChannels; n++ ) - { - for ( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) - { - free( psLCLDDecoder->pppiLCLDSignReal[n][k] ); - } - free( psLCLDDecoder->pppiLCLDSignReal[n] ); - } - free( psLCLDDecoder->pppiLCLDSignReal ); - } - - if ( psLCLDDecoder->pppiLCLDSignImag != NULL ) - { - for ( n = 0; n < psLCLDDecoder->iChannels; n++ ) - { - for ( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) - { - free( psLCLDDecoder->pppiLCLDSignImag[n][k] ); - } - free( psLCLDDecoder->pppiLCLDSignImag[n] ); - } - free( psLCLDDecoder->pppiLCLDSignImag ); - } - - if ( psLCLDDecoder->pppiQLCLDReal != NULL ) - { - for ( n = 0; n < psLCLDDecoder->iChannels; n++ ) - { - for ( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) - { - free( psLCLDDecoder->pppiQLCLDReal[n][k] ); - } - free( psLCLDDecoder->pppiQLCLDReal[n] ); - } - free( psLCLDDecoder->pppiQLCLDReal ); - } - - if ( psLCLDDecoder->pppiQLCLDImag != NULL ) - { - for ( n = 0; n < psLCLDDecoder->iChannels; n++ ) - { - for ( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) - { - free( psLCLDDecoder->pppiQLCLDImag[n][k] ); - } - free( psLCLDDecoder->pppiQLCLDImag[n] ); - } - free( psLCLDDecoder->pppiQLCLDImag ); - } - - for ( n = 0; n < ALLOC_TABLE_SIZE * 2; n++ ) - { - if ( psLCLDDecoder->num_decode_table[n] > 1 ) - { - - if ( psLCLDDecoder->c_apauiHuffDecTable_RAM[n] != NULL ) - { - free( psLCLDDecoder->c_apauiHuffDecTable_RAM[n] ); - } - } - } - - if ( psLCLDDecoder->psPredictionDecoder != NULL ) - { - DeletePredictionDecoder( psLCLDDecoder->psPredictionDecoder ); - psLCLDDecoder->psPredictionDecoder = NULL; - } - - if ( psLCLDDecoder->psNoiseGen != NULL ) - { - DeleteNoiseGen( psLCLDDecoder->psNoiseGen ); - } - - free( psLCLDDecoder ); - } -} - -/*------------------------------------------------------------------------------------------* - * Local function declarations - * - * - *------------------------------------------------------------------------------------------*/ - -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 ReplaceSign( const int32_t iNumBlocks, const int32_t iNumLCLDBands, int32_t **ppiSignReal, int32_t **ppiSignImag, float **ppfReal, float **ppfImag ); - -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 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 int32_t ReadHeaderInformation( int32_t *piNumBands, IVAS_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, IVAS_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, IVAS_SPLIT_REND_BITS_HANDLE pBits ); - -static int32_t ReadHuff( const uint32_t ( *pauiHuffDecTable )[HUFF_DEC_TABLE_SIZE], int32_t *piSymbol, IVAS_SPLIT_REND_BITS_HANDLE pBits ); - -static int32_t ReadRMSEnvelope( const int32_t iChannels, const int32_t *piNumGroups, const int32_t iNumBands, int32_t ***pppiRMSEnvelope, IVAS_SPLIT_REND_BITS_HANDLE pBits ); - -static int32_t ReadAllocInformation( int32_t *piAllocOffset, IVAS_SPLIT_REND_BITS_HANDLE pBits ); - -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, IVAS_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 ); - - -/*------------------------------------------------------------------------------------------* - * Function DecodeLCLDFrame() - * - * - *------------------------------------------------------------------------------------------*/ - -int32_t DecodeLCLDFrame( - LCLDDecoder *psLCLDDecoder, - IVAS_SPLIT_REND_BITS_HANDLE pBits, - float ***pppfLCLDReal, - float ***pppfLCLDImag ) -{ - int32_t k, n; - - ReadHeaderInformation( &psLCLDDecoder->iNumBands, pBits ); - - if ( psLCLDDecoder->iChannels == 2 ) - { - ReadMSInformation( psLCLDDecoder->iNumBands, &psLCLDDecoder->iMSMode, psLCLDDecoder->piMSFlags, psLCLDDecoder->piLRPhaseDiffs, psLCLDDecoder->piMSPredCoefs, pBits ); - } - - ReadPredictors( psLCLDDecoder->psPredictionDecoder, pBits ); - - 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 ); - -#ifdef ENABLE_PMOD_ADJUST - ReadPmodInformation( psLCLDDecoder->ppiHiSMRFlags, pBits, psLCLDDecoder->iChannels, psLCLDDecoder->iNumBands ); -#endif - - ReadAllocInformation( &psLCLDDecoder->iAllocOffset, pBits ); - - if ( psLCLDDecoder->iChannels == 2 && psLCLDDecoder->iCommonGrouping == 1 ) - { /* MS Mode? */ - 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] ); - } - } - else - { - for ( n = 0; n < psLCLDDecoder->iChannels; n++ ) - { // This will be updated to support multiple sample rates - for ( k = 0; k < psLCLDDecoder->piNumGroups[n]; k++ ) - { - PerceptualModel( 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 ); - - for ( n = 0; n < psLCLDDecoder->iChannels; n++ ) - { - ReadLCLDData( - psLCLDDecoder->piNumGroups[n], - (const int32_t *) psLCLDDecoder->ppiGroupLengths[n], - psLCLDDecoder->iNumBands, psLCLDDecoder->piBandwidths, - (const int32_t *) - psLCLDDecoder->psPredictionDecoder->ppiPredBandEnable[n], - psLCLDDecoder->pppiAlloc[n], - psLCLDDecoder->pppiLCLDSignReal[n], psLCLDDecoder->pppiLCLDSignImag[n], - psLCLDDecoder->pppiQLCLDReal[n], psLCLDDecoder->pppiQLCLDImag[n], - pBits, - psLCLDDecoder->c_apauiHuffDecTable_RAM ); - } - - 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, LCLD_BANDS, - psLCLDDecoder->pppiLCLDSignReal[n], - psLCLDDecoder->pppiLCLDSignImag[n], - pppfLCLDReal[n], pppfLCLDImag[n] ); - } - - ApplyInversePredictros( psLCLDDecoder->psPredictionDecoder, pppfLCLDReal, pppfLCLDImag ); - - for ( n = 0; n < psLCLDDecoder->iChannels; n++ ) - { - ApplyRMSEnvelope( psLCLDDecoder->iNumBands, psLCLDDecoder->piBandwidths, - psLCLDDecoder->piNumGroups[n], - (const int32_t *) psLCLDDecoder->ppiGroupLengths[n], - psLCLDDecoder->pppiRMSEnvelope[n], - pppfLCLDReal[n], pppfLCLDImag[n] ); - } - - if ( psLCLDDecoder->iChannels == 2 && psLCLDDecoder->iMSMode > 0 ) - { - 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 ); - } - - return 0; -} - - -/*------------------------------------------------------------------------------------------* - * 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 ) -{ - int32_t b, k, n; - int32_t iBlockOffset, iFBOffset; - - iBlockOffset = 0; - for ( n = 0; n < iNumGroups; n++ ) - { - for ( k = 0; k < piGroupLengths[n]; k++ ) - { - iFBOffset = 0; - for ( b = 0; b < iNumBands; b++ ) - { - int32_t m; - int32_t iRMSEnv; - float fGain; - - iRMSEnv = ppiRMSEnvelope[n][b]; - fGain = - c_afRMSEnvReconstructTable[ENV_RECONSTRUCT_TABLE_CENTER + iRMSEnv]; - for ( m = 0; m < piBandwidths[b]; m++ ) - { - ppfReal[iBlockOffset][iFBOffset] *= fGain; - ppfImag[iBlockOffset][iFBOffset] *= fGain; - iFBOffset++; - } - } - iBlockOffset++; - } - } - - return; -} - - -static void ReplaceSign( - const int32_t iNumBlocks, - const int32_t iNumLCLDBands, - int32_t **ppiSignReal, - int32_t **ppiSignImag, - float **ppfReal, - float **ppfImag ) -{ - int32_t b, n; - - for ( n = 0; n < iNumBlocks; n++ ) - { - for ( b = 0; b < iNumLCLDBands; b++ ) - { - if ( ppiSignReal[n][b] == 1 ) - { - ppfReal[n][b] = -ppfReal[n][b]; - } - - if ( ppiSignImag[n][b] == 1 ) - { - ppfImag[n][b] = -ppfImag[n][b]; - } - } - } - - 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, - NoiseGen *psNoiseGen /* Pass in NULL to switch off noise gen */ -) -{ - int32_t b, k, n; - int32_t iBlockOffest, iFBOffset; - - iBlockOffest = 0; - for ( n = 0; n < iNumGroups; n++ ) - { - for ( k = 0; k < piGroupLengths[n]; k++ ) - { - iFBOffset = 0; - for ( b = 0; b < iNumBands; b++ ) - { - int32_t m; - int32_t iAlloc; - float fInvSCFGain; - - iAlloc = ppiAlloc[n][b]; - fInvSCFGain = c_afInvScaleFactor[iAlloc]; - - if ( iAlloc > 0 ) - { - 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; - - iFBOffset++; - } - } - else if ( psNoiseGen != NULL ) - { - for ( m = 0; m < piBandwidths[b]; m++ ) - { - ppfReal[iBlockOffest][iFBOffset] = 0.7f * GetNoise( psNoiseGen ); - ppfImag[iBlockOffest][iFBOffset] = 0.7f * GetNoise( psNoiseGen ); - - iFBOffset++; - } - } - else - { - iFBOffset += piBandwidths[b]; - } - } - - iBlockOffest++; - } - } - - 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 ) -{ - if ( iMSMode > 0 ) - { - int32_t b; - int32_t iFBOffset; - int32_t bms = 0; -#if defined SIMPLE_PHASE - void( *pFuncPhaseRotateOptions[4] ) = { &rot_zero, &rot_m_pi_2, &rot_pm_pi, &rot_p_pi_2 }; -#endif - - iFBOffset = 0; - for ( b = 0; b < iNumBands; b++ ) - { - if ( piMSFlags[b] == 1 ) - { - int32_t n; -#if defined SIMPLE_PHASE - void ( *pFuncPhaseRotate )( float *, float * ) = - pFuncPhaseRotateOptions[piLRPhaseDiffs[bms]]; -#endif - for ( n = 0; n < piBandwidths[b]; n++ ) - { - int32_t k; - for ( k = 0; k < iNumBlocks; k++ ) - { - float fLeftReal; - float fLeftImag; - float fRightReal; - float fRightImag; - - if ( iMSMode == 3 ) - { - float fPred; - fPred = dequantPred( piMSPredCoefs[bms] ); - pppfReal[1][k][iFBOffset] += fPred * pppfReal[0][k][iFBOffset]; - pppfImag[1][k][iFBOffset] += fPred * pppfImag[0][k][iFBOffset]; - } - - 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] ); - - if ( iMSMode == 3 ) - { -#ifdef SIMPLE_PHASE - ( *pFuncPhaseRotate )( &fRightReal, &fRightImag ); -#else - int32_t phaseIdx; - phaseIdx = piLRPhaseDiffs[bms] - PHASE_MIN_VAL; - cplxmult( &fRightReal, &fRightImag, c_afRotRealImag[phaseIdx][0], -c_afRotRealImag[phaseIdx][1] ); -#endif - } - - pppfReal[0][k][iFBOffset] = fLeftReal; - pppfReal[1][k][iFBOffset] = fRightReal; - pppfImag[0][k][iFBOffset] = fLeftImag; - pppfImag[1][k][iFBOffset] = fRightImag; - } - iFBOffset++; - } - - bms++; - } - else - { - iFBOffset += piBandwidths[b]; - } - } - } - - return; -} - - -/* Currently only the number of bands in frame */ -static int32_t ReadHeaderInformation( - int32_t *piNumBands, - IVAS_SPLIT_REND_BITS_HANDLE pBits ) -{ - int32_t iBitsRead; - - iBitsRead = 0; - *piNumBands = ivas_split_rend_bitstream_read_int32( pBits, 5 ); - iBitsRead += 5; - - return iBitsRead; -} - - -static int32_t ReadMSInformation( - const int32_t iNumBands, - int32_t *piMSMode, - int32_t *piMSFlags, - int32_t *piLRPhaseDiffs, - int32_t *piMSPredCoefs, - IVAS_SPLIT_REND_BITS_HANDLE pBits ) -{ - int32_t iBitsRead; - - iBitsRead = 0; - *piMSMode = ivas_split_rend_bitstream_read_int32( pBits, 2 ); - iBitsRead += 2; - - if ( *piMSMode == 0 ) - { - int32_t n; - for ( n = 0; n < iNumBands; n++ ) - { - piMSFlags[n] = 0; - } - } - else if ( *piMSMode == 1 ) - { - int32_t n; - for ( n = 0; n < iNumBands; n++ ) - { - piMSFlags[n] = 1; - } - } - else if ( *piMSMode == 2 ) - { - int32_t n; - for ( n = 0; n < iNumBands; n++ ) - { - piMSFlags[n] = ivas_split_rend_bitstream_read_int32( pBits, 1 ); - iBitsRead += 1; - } - } - else if ( *piMSMode == 3 ) - { - int32_t n; - int32_t iMSPredAll; - int32_t iNumMSPredBands = 0; - int32_t anyNonZero; - iMSPredAll = ivas_split_rend_bitstream_read_int32( pBits, 1 ); - iBitsRead += 1; - if ( iMSPredAll ) - { - iNumMSPredBands = iNumBands; - for ( n = 0; n < iNumBands; n++ ) - { - piMSFlags[n] = 1; - } - } - else - { - for ( n = 0; n < iNumBands; n++ ) - { - piMSFlags[n] = ivas_split_rend_bitstream_read_int32( pBits, 1 ); - iBitsRead += 1; - if ( piMSFlags[n] ) - { - iNumMSPredBands++; - } - } - } - anyNonZero = ivas_split_rend_bitstream_read_int32( pBits, 1 ); - if ( anyNonZero ) - { -#ifdef SIMPLE_PHASE - for ( n = 0; n < iNumMSPredBands; n++ ) - { - piLRPhaseDiffs[n] = ivas_split_rend_bitstream_read_int32( pBits, SIMPLE_PHASE_BITS ); - iBitsRead += SIMPLE_PHASE_BITS; - } -#else - piLRPhaseDiffs[0] = ivas_split_rend_bitstream_read_int32( pBits, PHASE_BAND0_BITS ); - piLRPhaseDiffs[0] += PHASE_MIN_VAL; - 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; - } - DecodePhase( piLRPhaseDiffs, iNumMSPredBands, PHASE_DIFF_DIM ); -#endif - } - else - { - for ( n = 0; n < iNumMSPredBands; n++ ) - { - piLRPhaseDiffs[n] = 0; - } - } - anyNonZero = ivas_split_rend_bitstream_read_int32( pBits, 1 ); - if ( anyNonZero ) - { - piMSPredCoefs[0] = ivas_split_rend_bitstream_read_int32( pBits, PRED_BAND0_BITS ); - piMSPredCoefs[0] += PRED_MIN_VAL; - 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; - } - DecodePredCoef( piMSPredCoefs, iNumMSPredBands ); - } - else - { - for ( n = 0; n < iNumMSPredBands; n++ ) - { - piMSPredCoefs[n] = 0; - } - } -#ifdef DEBUG_WRITE_MS_PRED - { - static FILE *fid = 0; - if ( !fid ) - { - fid = fopen( "ms_mode_dec.txt", "wt" ); - } - writeMSPred( piLRPhaseDiffs, piMSPredCoefs, *piMSMode, iNumMSPredBands, iNumBands, fid, piMSFlags ); - } -#endif - } - else - { - printf( "ERROR UNSUPPORTED MS MODE\n" ); - } - - return iBitsRead; -} - - -static int32_t ReadGroupInformation( - const int32_t iChannels, - const int32_t iNumBlocks, - int32_t *piCommonGrouping, - int32_t *piNumGroups, - int32_t **ppiGroupLengths, - IVAS_SPLIT_REND_BITS_HANDLE pBits ) -{ - int32_t c, k, iBitsRead; - - iBitsRead = 0; - if ( iChannels == 2 ) - { - *piCommonGrouping = ivas_split_rend_bitstream_read_int32( pBits, 1 ); - iBitsRead += 1; - - if ( *piCommonGrouping == 1 ) - { - piNumGroups[0] = 0; - ppiGroupLengths[0][piNumGroups[0]] = 1; - for ( k = 0; k < ( iNumBlocks - 1 ); k++ ) - { - int32_t iGroupStart; - - iGroupStart = ivas_split_rend_bitstream_read_int32( pBits, 1 ); - iBitsRead += 1; - - if ( iGroupStart == 1 ) - { - piNumGroups[0]++; - ppiGroupLengths[0][piNumGroups[0]] = 1; - } - else - { - ppiGroupLengths[0][piNumGroups[0]]++; - } - } - piNumGroups[0]++; - - piNumGroups[1] = piNumGroups[0]; - for ( k = 0; k < piNumGroups[1]; k++ ) - { - ppiGroupLengths[1][k] = ppiGroupLengths[0][k]; - } - } - else - { - for ( c = 0; c < iChannels; c++ ) - { - piNumGroups[c] = 0; - ppiGroupLengths[c][piNumGroups[c]] = 1; - for ( k = 0; k < ( iNumBlocks - 1 ); k++ ) - { - int32_t iGroupStart; - - iGroupStart = ivas_split_rend_bitstream_read_int32( pBits, 1 ); - iBitsRead += 1; - - if ( iGroupStart == 1 ) - { - piNumGroups[c]++; - ppiGroupLengths[c][piNumGroups[c]] = 1; - } - else - { - ppiGroupLengths[c][piNumGroups[c]]++; - } - } - piNumGroups[c]++; - } - } - } - else - { - for ( c = 0; c < iChannels; c++ ) - { - piNumGroups[c] = 0; - ppiGroupLengths[c][piNumGroups[c]] = 1; - for ( k = 0; k < ( iNumBlocks - 1 ); k++ ) - { - int32_t iGroupStart; - - iGroupStart = ivas_split_rend_bitstream_read_int32( pBits, 1 ); - iBitsRead += 1; - - if ( iGroupStart == 1 ) - { - piNumGroups[c]++; - ppiGroupLengths[c][piNumGroups[c]] = 1; - } - else - { - ppiGroupLengths[c][piNumGroups[c]]++; - } - } - piNumGroups[c]++; - } - } - - return iBitsRead; -} - - -static int32_t BSForceBack( - IVAS_SPLIT_REND_BITS_HANDLE pBits, - int32_t iValue, - int32_t iBitCount ) -{ - pBits->bits_read -= iBitCount; - - return ( iValue >> iBitCount ); -} - - -static int32_t ReadHuff( - const uint32_t ( *pauiHuffDecTable )[HUFF_DEC_TABLE_SIZE], - int32_t *piSymbol, - IVAS_SPLIT_REND_BITS_HANDLE pBits ) -{ - int32_t iBitsRead; - int32_t iSymbol; - int32_t iIndex; - int32_t iVal; - - iVal = 0; - iIndex = 0; - iSymbol = 0xFFFF; - iBitsRead = 0; - while ( iSymbol == 0xFFFF ) - { - iIndex = ivas_split_rend_bitstream_read_int32( pBits, HUFF_READ_SIZE ); - iBitsRead += HUFF_READ_SIZE; - - iIndex = pauiHuffDecTable[iVal][iIndex]; - iSymbol = ( iIndex & 0xFFFF ); - - iVal = ( iIndex >> 16 ); - } - - if ( iVal ) - { - BSForceBack( pBits, iIndex, iVal ); - iBitsRead -= iVal; - } - - *piSymbol = iSymbol; - - return iBitsRead; -} - - -static int32_t ReadRMSEnvelope( - const int32_t iChannels, - const int32_t *piNumGroups, - const int32_t iNumBands, - int32_t ***pppiRMSEnvelope, - IVAS_SPLIT_REND_BITS_HANDLE pBits ) -{ - int32_t b, k, n; - int32_t iBitsRead, iLastRMSVal; - - iBitsRead = 0; - for ( n = 0; n < iChannels; n++ ) - { - for ( k = 0; k < piNumGroups[n]; k++ ) - { - iLastRMSVal = ivas_split_rend_bitstream_read_int32( pBits, ENV0_BITS ); - iBitsRead += ENV0_BITS; - - iLastRMSVal += ENV_MIN; - pppiRMSEnvelope[n][k][0] = iLastRMSVal; - for ( b = 1; b < iNumBands; b++ ) - { - int32_t iDelta; - - iBitsRead += ReadHuff( c_aaiRMSEnvHuffDec, &iDelta, pBits ); - - iDelta += ENV_DELTA_MIN; - iLastRMSVal += iDelta; - pppiRMSEnvelope[n][k][b] = iLastRMSVal; - } - } - } - - return iBitsRead; -} - - -#ifdef ENABLE_PMOD_ADJUST -static int32_t ReadPmodInformation( - int32_t **ppiHiSMRFlags, - IVAS_SPLIT_REND_BITS_HANDLE pBits, - int32_t iChannels, - int32_t iNumBands ) -{ - int32_t iBitsRead; - int32_t c; - iBitsRead = 0; - for ( c = 0; c < iChannels; c++ ) - { - int32_t b; - int32_t iFlags = ivas_split_rend_bitstream_read_int32( pBits, 1 ); - iBitsRead += 1; - if ( iFlags ) - { - for ( b = 0; b < iNumBands; b++ ) - { - ppiHiSMRFlags[c][b] = ivas_split_rend_bitstream_read_int32( pBits, 1 ); - iBitsRead += 1; - } - } - else - { - for ( b = 0; b < iNumBands; b++ ) - { - ppiHiSMRFlags[c][b] = 0; - } - } - } -#ifdef WRITE_HISMR_FLAGS - { - static FILE *fid = 0; - if ( !fid ) - { - fid = fopen( "hismr_dec.txt", "wt" ); - } - for ( c = 0; c < iChannels; c++ ) - { - int32_t b; - for ( b = 0; b < iNumBands; b++ ) - { - if ( c == iChannels - 1 && b == iNumBands - 1 ) - { - fprintf( fid, "%d\n", ppiHiSMRFlags[c][b] ); - } - else - { - fprintf( fid, "%d ", ppiHiSMRFlags[c][b] ); - } - } - } - } -#endif - return iBitsRead; -} -#endif - - -static int32_t ReadAllocInformation( - int32_t *piAllocOffset, - IVAS_SPLIT_REND_BITS_HANDLE pBits ) -{ - int32_t iBitsRead; - - iBitsRead = 0; - *piAllocOffset = ivas_split_rend_bitstream_read_int32( pBits, ALLOC_OFFSET_BITS ); - *piAllocOffset += MIN_ALLOC_OFFSET; - iBitsRead += ALLOC_OFFSET_BITS; - - return iBitsRead; -} - -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, - IVAS_SPLIT_REND_BITS_HANDLE pBits, - uint32_t ( *c_apauiHuffDecTables[2 * ALLOC_TABLE_SIZE] )[HUFF_DEC_TABLE_SIZE] ) -{ - int32_t b, k, m, n; - int32_t iBitsRead, iBlockOffest, iFBOffset; - int32_t iAlloc, iHuffDim, iHuffMod; - - iBitsRead = 0; - iBlockOffest = 0; - for ( n = 0; n < iNumGroups; n++ ) - { - for ( k = 0; k < piGroupLengths[n]; k++ ) - { - iFBOffset = 0; - for ( b = 0; b < iNumBands; b++ ) - { - iAlloc = ppiAlloc[n][b]; - - iHuffDim = c_aiHuffmanDim[iAlloc]; - iHuffMod = c_aiHuffmanMod[iAlloc]; - - if ( iAlloc > 0 ) - { - const uint32_t( *pauiHuffmanTable )[HUFF_DEC_TABLE_SIZE] = NULL; - const uint32_t( *pauiHuffmanTableDPCM )[HUFF_DEC_TABLE_SIZE] = NULL; -#ifdef USE_DEMOD_TABLES - const int32_t( *paiDemodTable )[2] = NULL; -#endif - 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]; -#ifdef USE_DEMOD_TABLES - paiDemodTable = c_apaiDemodTables[iAlloc]; -#endif - for ( m = 0; m < piBandwidths[b]; m++ ) - { - int32_t iQuantValue1 = 0; - int32_t iQuantValue2 = 0; - - if ( piPredEnable[iFBOffset] == 1 ) - { - if ( iHuffDim == 2 ) - { - int32_t iSymbol; - iBitsRead += ReadHuff( pauiHuffmanTableDPCM, &iSymbol, pBits ); -#ifdef USE_DEMOD_TABLES - iQuantValue1 = paiDemodTable[iSymbol][0]; - iQuantValue2 = paiDemodTable[iSymbol][1]; -#else - iQuantValue1 = iSymbol / iHuffMod; - iQuantValue2 = iSymbol % iHuffMod; -#endif - } - else - { - iBitsRead += ReadHuff( pauiHuffmanTableDPCM, &iQuantValue1, pBits ); - iBitsRead += ReadHuff( pauiHuffmanTableDPCM, &iQuantValue2, pBits ); - } - } - else - { - if ( iHuffDim == 2 ) - { - int32_t iSymbol; - - iBitsRead += ReadHuff( pauiHuffmanTable, &iSymbol, pBits ); -#ifdef USE_DEMOD_TABLES - iQuantValue1 = paiDemodTable[iSymbol][0]; - iQuantValue2 = paiDemodTable[iSymbol][1]; -#else - iQuantValue1 = iSymbol / iHuffMod; - iQuantValue2 = iSymbol % iHuffMod; -#endif - } - else - { - iBitsRead += ReadHuff( pauiHuffmanTable, &iQuantValue1, pBits ); - iBitsRead += ReadHuff( pauiHuffmanTable, &iQuantValue2, pBits ); - } - } - - ppiQReal[iBlockOffest][iFBOffset] = iQuantValue1; - ppiQImag[iBlockOffest][iFBOffset] = iQuantValue2; - - if ( iQuantValue1 > 0 ) - { - ppiSignReal[iBlockOffest][iFBOffset] = ivas_split_rend_bitstream_read_int32( pBits, 1 ); - iBitsRead += 1; - } - else - { - ppiSignReal[iBlockOffest][iFBOffset] = 0; - } - if ( iQuantValue2 > 0 ) - { - ppiSignImag[iBlockOffest][iFBOffset] = ivas_split_rend_bitstream_read_int32( pBits, 1 ); - iBitsRead += 1; - } - else - { - ppiSignImag[iBlockOffest][iFBOffset] = 0; - } - - iFBOffset++; - } - } - else - { - for ( m = 0; m < piBandwidths[b]; m++ ) - { - ppiSignReal[iBlockOffest][iFBOffset] = 0; - ppiSignImag[iBlockOffest][iFBOffset] = 0; - iFBOffset++; - } - } - } - - iBlockOffest++; - } - } - - return iBitsRead; -} - - -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 ) -{ - int32_t b, k, n, iAlloc; - - for ( n = 0; n < iChannels; n++ ) - { - for ( k = 0; k < piNumGroups[n]; k++ ) - { - for ( b = 0; b < iNumBands; b++ ) - { - iAlloc = ( ( pppiSMR[n][k][b] + iAllocOffset * ALLOC_OFFSET_SCALE ) >> 5 ); - iAlloc = ( iAlloc > MIN_ALLOC ) ? iAlloc : MIN_ALLOC; - iAlloc = ( iAlloc < MAX_ALLOC ) ? iAlloc : MAX_ALLOC; - pppiAlloc[n][k][b] = iAlloc; - } - } - } - - return; -} -#endif diff --git a/lib_rend/ivas_lcld_encoder.c b/lib_rend/ivas_lcld_encoder.c deleted file mode 100644 index 127aaea5c..000000000 --- a/lib_rend/ivas_lcld_encoder.c +++ /dev/null @@ -1,2011 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2023 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. - -*******************************************************************************************************/ - -#include -#include "options.h" -#ifdef SPLIT_REND_WITH_HEAD_ROT -#include -#include -#include "ivas_lcld_prot.h" -#include "ivas_lcld_rom_tables.h" -#include "prot.h" -#include "ivas_prot_rend.h" -#ifdef ENABLE_PMOD_ADJUST -#include "ton_corr.h" -#endif -#include "wmc_auto.h" - -/*------------------------------------------------------------------------------------------* - * Local structures - *------------------------------------------------------------------------------------------*/ - -struct LCLD_ENCODER -{ - int32_t iSampleRate; - int32_t iChannels; - int32_t iNumBlocks; - - int32_t iTargetBitRate; - int32_t iTargetBitsPerFrame; - - int32_t iNumBands; - const int32_t *piBandwidths; - - int32_t iMSMode; - int32_t *piMSFlags; - int32_t piMSPredCoefs[MAX_BANDS]; - int32_t piLRPhaseDiffs[MAX_BANDS]; - int32_t iAllowSidePred; - -#ifdef ENABLE_PMOD_ADJUST - int32_t **ppiHiSMRFlags; -#endif - - RMSEnvelopeGrouping *psRMSEnvelopeGrouping; - - 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 ***pppiLCLDSignReal; - int32_t ***pppiLCLDSignImag; - int32_t ***pppiQLCLDReal; - int32_t ***pppiQLCLDImag; - - - PredictionEncoder *psPredictionEncoder; -}; - - -/*------------------------------------------------------------------------------------------* - * Function CreateLCLDEncoder() - * - * - *------------------------------------------------------------------------------------------*/ - -ivas_error CreateLCLDEncoder( - LCLDEncoder **psLCLDEncoder_out, - const int32_t iSampleRate, - const int32_t iChannels, - const int32_t iTargetBitRate, - const int32_t iAllowSidePred ) -{ - int32_t n; - LCLDEncoder *psLCLDEncoder; - ivas_error error; - - assert( iSampleRate == 48000 ); // Fix - - 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; - psLCLDEncoder->iChannels = iChannels; - psLCLDEncoder->iNumBlocks = LCLD_BLOCKS_PER_FRAME; - psLCLDEncoder->iAllocOffset = 0; - - psLCLDEncoder->iTargetBitRate = iTargetBitRate; - psLCLDEncoder->iTargetBitsPerFrame = iTargetBitRate * LCLD_BLOCKS_PER_FRAME * LCLD_BANDS / iSampleRate; - - psLCLDEncoder->iNumBands = MAX_BANDS_48; // Fix - psLCLDEncoder->piBandwidths = c_aiBandwidths48; // Fix - - psLCLDEncoder->iMSMode = 0; - if ( ( psLCLDEncoder->piMSFlags = (int32_t *) malloc( MAX_BANDS * sizeof( int32_t ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); - } - - for ( n = 0; n < MAX_BANDS; n++ ) - { - psLCLDEncoder->piLRPhaseDiffs[n] = 0; - psLCLDEncoder->piMSPredCoefs[n] = 0; - } - psLCLDEncoder->iAllowSidePred = iAllowSidePred; - - 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 ) - { - 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 ) - { - 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 ) - { - 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 ) - { - 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 ) - { - 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 ) - { - 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 ) - { - 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 ) - { - 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 ) - { - 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 ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); - } -#ifdef ENABLE_PMOD_ADJUST - if ( ( psLCLDEncoder->ppiHiSMRFlags = (int32_t **) malloc( psLCLDEncoder->iChannels * sizeof( int32_t * ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); - } -#endif - - - for ( n = 0; n < iChannels; n++ ) - { - int32_t k; -#ifdef ENABLE_PMOD_ADJUST - if ( ( psLCLDEncoder->ppiHiSMRFlags[n] = (int32_t *) malloc( MAX_BANDS * sizeof( int32_t ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); - } -#endif - if ( ( psLCLDEncoder->ppiGroupLengths[n] = (int32_t *) malloc( LCLD_BLOCKS_PER_FRAME * sizeof( int32_t ) ) ) == 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 ) - { - 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 ) - { - 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 ) - { - 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 ) - { - 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 ) - { - 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 ) - { - 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 ) - { - 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 ) - { - 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++ ) - { - if ( ( psLCLDEncoder->pppiRMSEnvelope[n][k] = (int32_t *) malloc( MAX_BANDS * sizeof( int32_t ) ) ) == 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 ) - { - 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 ) - { - 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 ) - { - 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 ) - { - 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 ) - { - 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 ) - { - 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 ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); - } - } - } - - if ( ( error = CreatePredictionEncoder( &( psLCLDEncoder->psPredictionEncoder ), iChannels, psLCLDEncoder->iNumBlocks ) ) != IVAS_ERR_OK ) - { - return error; - } - - *psLCLDEncoder_out = psLCLDEncoder; - - return IVAS_ERR_OK; -} - - -/*------------------------------------------------------------------------------------------* - * Function DeleteLCLDEncoder() - * - * - *------------------------------------------------------------------------------------------*/ - -void DeleteLCLDEncoder( - LCLDEncoder *psLCLDEncoder ) -{ - int32_t k, n; - - if ( psLCLDEncoder != NULL ) - { - - if ( psLCLDEncoder->piMSFlags != NULL ) - { - free( psLCLDEncoder->piMSFlags ); - } - - if ( psLCLDEncoder->piNumGroups != NULL ) - { - free( psLCLDEncoder->piNumGroups ); - } - - if ( psLCLDEncoder->psRMSEnvelopeGrouping != NULL ) - { - DeleteRMSEnvelopeGrouping( psLCLDEncoder->psRMSEnvelopeGrouping ); - } - - if ( psLCLDEncoder->ppiGroupLengths != NULL ) - { - for ( n = 0; n < psLCLDEncoder->iChannels; n++ ) - { - free( psLCLDEncoder->ppiGroupLengths[n] ); - } - free( psLCLDEncoder->ppiGroupLengths ); - } -#ifdef ENABLE_PMOD_ADJUST - if ( psLCLDEncoder->ppiHiSMRFlags != NULL ) - { - for ( n = 0; n < psLCLDEncoder->iChannels; n++ ) - { - free( psLCLDEncoder->ppiHiSMRFlags[n] ); - } - free( psLCLDEncoder->ppiHiSMRFlags ); - } -#endif - if ( psLCLDEncoder->pppiRMSEnvelope != NULL ) - { - for ( n = 0; n < psLCLDEncoder->iChannels; n++ ) - { - for ( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) - { - free( psLCLDEncoder->pppiRMSEnvelope[n][k] ); - } - free( psLCLDEncoder->pppiRMSEnvelope[n] ); - } - free( psLCLDEncoder->pppiRMSEnvelope ); - } - - if ( psLCLDEncoder->pppiSMR != NULL ) - { - for ( n = 0; n < psLCLDEncoder->iChannels; n++ ) - { - for ( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) - { - free( psLCLDEncoder->pppiSMR[n][k] ); - } - free( psLCLDEncoder->pppiSMR[n] ); - } - free( psLCLDEncoder->pppiSMR ); - } - - if ( psLCLDEncoder->pppiExcitation != NULL ) - { - for ( n = 0; n < psLCLDEncoder->iChannels; n++ ) - { - for ( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) - { - free( psLCLDEncoder->pppiExcitation[n][k] ); - } - free( psLCLDEncoder->pppiExcitation[n] ); - } - free( psLCLDEncoder->pppiExcitation ); - } - - if ( psLCLDEncoder->pppiAlloc != NULL ) - { - for ( n = 0; n < psLCLDEncoder->iChannels; n++ ) - { - for ( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) - { - free( psLCLDEncoder->pppiAlloc[n][k] ); - } - free( psLCLDEncoder->pppiAlloc[n] ); - } - free( psLCLDEncoder->pppiAlloc ); - } - - if ( psLCLDEncoder->pppiLCLDSignReal != NULL ) - { - for ( n = 0; n < psLCLDEncoder->iChannels; n++ ) - { - for ( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) - { - free( psLCLDEncoder->pppiLCLDSignReal[n][k] ); - } - free( psLCLDEncoder->pppiLCLDSignReal[n] ); - } - free( psLCLDEncoder->pppiLCLDSignReal ); - } - - if ( psLCLDEncoder->pppiLCLDSignImag != NULL ) - { - for ( n = 0; n < psLCLDEncoder->iChannels; n++ ) - { - for ( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) - { - free( psLCLDEncoder->pppiLCLDSignImag[n][k] ); - } - free( psLCLDEncoder->pppiLCLDSignImag[n] ); - } - free( psLCLDEncoder->pppiLCLDSignImag ); - } - - if ( psLCLDEncoder->pppiQLCLDReal != NULL ) - { - for ( n = 0; n < psLCLDEncoder->iChannels; n++ ) - { - for ( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) - { - free( psLCLDEncoder->pppiQLCLDReal[n][k] ); - } - free( psLCLDEncoder->pppiQLCLDReal[n] ); - } - free( psLCLDEncoder->pppiQLCLDReal ); - } - - if ( psLCLDEncoder->pppiQLCLDImag != NULL ) - { - for ( n = 0; n < psLCLDEncoder->iChannels; n++ ) - { - for ( k = 0; k < LCLD_BLOCKS_PER_FRAME; k++ ) - { - free( psLCLDEncoder->pppiQLCLDImag[n][k] ); - } - free( psLCLDEncoder->pppiQLCLDImag[n] ); - } - free( psLCLDEncoder->pppiQLCLDImag ); - } - - DeletePredictionEncoder( psLCLDEncoder->psPredictionEncoder ); - free( psLCLDEncoder ); - } - - return; -} - -/*------------------------------------------------------------------------------------------* - * 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, int32_t *piMSFlags ); - -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 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 int32_t WriteHeaderInformation( const int32_t iNumBands, IVAS_SPLIT_REND_BITS_HANDLE pBits ); - -static int32_t WritePmodInformation( const int32_t **ppiHiSMRFlags, IVAS_SPLIT_REND_BITS_HANDLE pBits, int32_t iChannels, int32_t iNumBands ); - -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, IVAS_SPLIT_REND_BITS_HANDLE pBits ); - -static int32_t WriteGroupInformation( const int32_t iChannels, const int32_t iCommonGrouping, const int32_t *piNumGroups, int32_t **ppiGroupLengths, IVAS_SPLIT_REND_BITS_HANDLE pBits ); - -static int32_t WriteRMSEnvelope( const int32_t iChannels, const int32_t *piNumGroups, const int32_t iNumBands, int32_t ***pppiRMSEnvelope, IVAS_SPLIT_REND_BITS_HANDLE pBits ); - -static int32_t WriteAllocInformation( const int32_t iAllocOffset, IVAS_SPLIT_REND_BITS_HANDLE pBits ); - -static int32_t WriteLCLDData( 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, IVAS_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, int32_t **ppiPredEnable, float **ppfA1Real, float **ppfA1Imag ); - - -/*------------------------------------------------------------------------------------------* - * Function EncodeLCLDFrame() - * - * - *------------------------------------------------------------------------------------------*/ - -int32_t EncodeLCLDFrame( - LCLDEncoder *psLCLDEncoder, - float ***pppfLCLDReal, - float ***pppfLCLDImag, - int32_t *piBitsWritten, - const int32_t available_bits, - IVAS_SPLIT_REND_BITS_HANDLE pBits ) -{ - int32_t n; - int32_t iAvailableBits, iBitsWritten; - int32_t iNumMSBands = 0; - iAvailableBits = available_bits; // HCBR for now - iBitsWritten = 0; - - /* Do MS calc here */ - if ( psLCLDEncoder->iChannels == 2 ) - { - iNumMSBands = MSModeCalculation( psLCLDEncoder->iNumBlocks, - psLCLDEncoder->iNumBands, - psLCLDEncoder->piBandwidths, - pppfLCLDReal, - pppfLCLDImag, - &psLCLDEncoder->iMSMode, - psLCLDEncoder->piLRPhaseDiffs, - psLCLDEncoder->piMSPredCoefs, - psLCLDEncoder->iAllowSidePred, - psLCLDEncoder->piMSFlags ); - - if ( psLCLDEncoder->iMSMode > 0 ) - { - psLCLDEncoder->iCommonGrouping = 1; // Make sure common grouping is enabled when MS is in use - } - } - -#ifdef ENABLE_PMOD_ADJUST - CalcTonQuotas( psLCLDEncoder->iChannels, psLCLDEncoder->iNumBands, psLCLDEncoder->piBandwidths, pppfLCLDReal, pppfLCLDImag, psLCLDEncoder->ppiHiSMRFlags ); -#endif - - /* Compute Grouping and RMS Envelopes */ - if ( psLCLDEncoder->iChannels == 2 && psLCLDEncoder->iCommonGrouping == 1 ) - { - ComputeEnvelopeGrouping( psLCLDEncoder->psRMSEnvelopeGrouping, - psLCLDEncoder->iChannels, - psLCLDEncoder->iNumBands, - psLCLDEncoder->piBandwidths, - pppfLCLDReal, - pppfLCLDImag, - &psLCLDEncoder->piNumGroups[0], - psLCLDEncoder->ppiGroupLengths[0], - psLCLDEncoder->pppiRMSEnvelope ); - - psLCLDEncoder->piNumGroups[1] = psLCLDEncoder->piNumGroups[0]; - for ( n = 0; n < psLCLDEncoder->piNumGroups[0]; n++ ) - { - psLCLDEncoder->ppiGroupLengths[1][n] = psLCLDEncoder->ppiGroupLengths[0][n]; - } - } - else - { - for ( n = 0; n < psLCLDEncoder->iChannels; n++ ) - { - ComputeEnvelopeGrouping( psLCLDEncoder->psRMSEnvelopeGrouping, - psLCLDEncoder->iChannels, - psLCLDEncoder->iNumBands, - psLCLDEncoder->piBandwidths, - &pppfLCLDReal[n], - &pppfLCLDImag[n], - &psLCLDEncoder->piNumGroups[n], - psLCLDEncoder->ppiGroupLengths[n], - &psLCLDEncoder->pppiRMSEnvelope[n] ); - } - } - - for ( n = 0; n < psLCLDEncoder->iChannels; n++ ) - { - RemoveRMSEnvelope( psLCLDEncoder->iNumBands, - psLCLDEncoder->piBandwidths, - psLCLDEncoder->piNumGroups[n], - (const int32_t *) psLCLDEncoder->ppiGroupLengths[n], - psLCLDEncoder->pppiRMSEnvelope[n], - pppfLCLDReal[n], - pppfLCLDImag[n] ); - } - - ComputePredictors( psLCLDEncoder->psPredictionEncoder, pppfLCLDReal, pppfLCLDImag ); - - iBitsWritten += WriteHeaderInformation( psLCLDEncoder->iNumBands, pBits ); - - if ( 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 += WritePredictors( psLCLDEncoder->psPredictionEncoder, pBits ); - - iBitsWritten += WriteGroupInformation( psLCLDEncoder->iChannels, psLCLDEncoder->iCommonGrouping, (const int32_t *) psLCLDEncoder->piNumGroups, psLCLDEncoder->ppiGroupLengths, pBits ); - - iBitsWritten += WriteRMSEnvelope( psLCLDEncoder->iChannels, (const int32_t *) psLCLDEncoder->piNumGroups, psLCLDEncoder->iNumBands, psLCLDEncoder->pppiRMSEnvelope, pBits ); - -#ifdef ENABLE_PMOD_ADJUST - iBitsWritten += WritePmodInformation( psLCLDEncoder->ppiHiSMRFlags, - pBits, - psLCLDEncoder->iChannels, - psLCLDEncoder->iNumBands ); -#endif - - if ( psLCLDEncoder->iChannels == 2 && psLCLDEncoder->iCommonGrouping == 1 ) - { - int32_t 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] ); - } - } - else - { - for ( n = 0; n < psLCLDEncoder->iChannels; n++ ) - { - int32_t k; - for ( k = 0; k < psLCLDEncoder->piNumGroups[n]; k++ ) - { - PerceptualModel( psLCLDEncoder->iNumBands, - psLCLDEncoder->pppiRMSEnvelope[n][k], - psLCLDEncoder->pppiExcitation[n][k], - psLCLDEncoder->pppiSMR[n][k] ); - } - } - } - - iAvailableBits -= iBitsWritten; - ComputeAllocation( psLCLDEncoder->iChannels, - (const int32_t *) psLCLDEncoder->piNumGroups, - psLCLDEncoder->ppiGroupLengths, - psLCLDEncoder->iNumBands, - psLCLDEncoder->piBandwidths, - pppfLCLDReal, - pppfLCLDImag, - psLCLDEncoder->pppiSMR, - iAvailableBits, - &psLCLDEncoder->iAllocOffset, - psLCLDEncoder->pppiAlloc, - psLCLDEncoder->pppiQLCLDReal, - psLCLDEncoder->pppiQLCLDImag, - psLCLDEncoder->pppiLCLDSignReal, - psLCLDEncoder->pppiLCLDSignImag, - psLCLDEncoder->psPredictionEncoder->ppiPredBandEnable, - psLCLDEncoder->psPredictionEncoder->ppfA1Real, - psLCLDEncoder->psPredictionEncoder->ppfA1Imag ); - - iBitsWritten += WriteAllocInformation( psLCLDEncoder->iAllocOffset, - pBits ); - - for ( n = 0; n < psLCLDEncoder->iChannels; n++ ) - { - iBitsWritten += WriteLCLDData( psLCLDEncoder->piNumGroups[n], - (const int32_t *) psLCLDEncoder->ppiGroupLengths[n], - psLCLDEncoder->iNumBands, - psLCLDEncoder->piBandwidths, - (const int32_t *) psLCLDEncoder->psPredictionEncoder->ppiPredBandEnable[n], - psLCLDEncoder->pppiAlloc[n], - psLCLDEncoder->pppiLCLDSignReal[n], - psLCLDEncoder->pppiLCLDSignImag[n], - psLCLDEncoder->pppiQLCLDReal[n], - psLCLDEncoder->pppiQLCLDImag[n], - pBits ); - } - *piBitsWritten = iBitsWritten; - - return 0; -} - - -/*------------------------------------------------------------------------------------------* - * Function GetNumGroups() - * - * - *------------------------------------------------------------------------------------------*/ - -int32_t GetNumGroups( LCLDEncoder *psLCLDEncoder ) -{ - return psLCLDEncoder->piNumGroups[0]; -} - - -/*------------------------------------------------------------------------------------------* - * Local functions - * - * - *------------------------------------------------------------------------------------------*/ - -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, - int32_t *piMSFlags ) -{ - int32_t b; - int32_t iFBOffset; - int32_t iNumMSBands; - int32_t piMSPredFlags[MAX_BANDS]; - int32_t iNumMSPredBands = 0; - float msBitsReduction = 0.0f; - float msPredBitsReduction = 0.0f; - int32_t msBits; - int32_t msPredBits; - float fPred; -#if defined SIMPLE_PHASE - void( *pFuncPhaseRotateOptions[4] ) = { &rot_zero, &rot_p_pi_2, &rot_pm_pi, &rot_m_pi_2 }; -#endif - const float one_by_log10_2 = 3.32192809488736f; - - set_l( piMSPredFlags, 0, MAX_BANDS ); - *piMSMode = 0; - iFBOffset = 0; - iNumMSBands = 0; - for ( b = 0; b < iNumBands; b++ ) - { - int32_t n; - float fLeftEnergy; - float fRightEnergy; - float fMidEnergy; - float fSideEnergy; - float fLRRatio; - float fMSRatio; - float fMSPredRatio; - float fMidEnergyPred; - float fSideEnergyPred; - float fLRCovReal = 0.0f; - float fLRCovImag = 0.0f; - int32_t iPhase; - int32_t iPred; - int32_t tabIdx = 0; - - fLeftEnergy = 0.0f; - fRightEnergy = 0.0f; - fMidEnergy = 0.0; - fSideEnergy = 0.0; - - for ( n = 0; n < piBandwidths[b]; n++ ) - { - int32_t k; - for ( k = 0; k < iNumBlocks; k++ ) - { - 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] ); - } - - iFBOffset++; - } - - /* compute L/R phase difference if high coherence */ - if ( fLRCovReal * fLRCovReal + fLRCovImag * fLRCovImag > 0.5f * fLeftEnergy * fRightEnergy ) - { - float fPhase = (float) atan2( fLRCovImag, fLRCovReal ); // ToDo: replace by atan2f() - iPhase = quantPhase( fPhase ); - } - else - { - iPhase = 0; - } - piLRPhaseDiffs[b] = iPhase; - - /* adjust covariance based on phase rotation */ -#ifdef SIMPLE_PHASE - cplxmult( &fLRCovReal, &fLRCovImag, c_afRotRealImagSimple[iPhase][0], -c_afRotRealImagSimple[iPhase][1] ); -#else - tabIdx = iPhase - PHASE_MIN_VAL; - cplxmult( &fLRCovReal, &fLRCovImag, c_afRotRealImag[tabIdx][0], -c_afRotRealImag[tabIdx][1] ); -#endif - /* compute MS prediction coefficient based on LR covariance*/ - fMidEnergyPred = 0.25f * ( fLeftEnergy + fRightEnergy + 2.0f * fLRCovReal ); - fSideEnergyPred = 0.25f * ( fLeftEnergy + fRightEnergy - 2.0f * fLRCovReal ); - - /* M/S prediction */ - fPred = fMidEnergyPred == 0.0f ? 0.0f : 0.25f * ( fLeftEnergy - fRightEnergy ) / fMidEnergyPred; - iPred = quantPred( fPred ); - fPred = dequantPred( iPred ); - piMSPredCoefs[b] = iPred; - - /* evaluation */ - fSideEnergyPred += ( fPred * fPred * fMidEnergyPred - 2.0f * fPred * 0.25f * ( fLeftEnergy - fRightEnergy ) ); - /* -= fPred * fPred * fMidEnergyPred doesn't work because fPred is quantized and does not match MS/MM exactly */ - fMSPredRatio = log10f( ( fMidEnergyPred + 1e-12f ) / ( fSideEnergyPred + 1e-12f ) ); - - fLeftEnergy = log10f( fLeftEnergy + 1e-12f ); - fRightEnergy = log10f( fRightEnergy + 1e-12f ); - fMidEnergy = log10f( fMidEnergy + 1e-12f ); - fSideEnergy = log10f( fSideEnergy + 1e-12f ); - - if ( fLeftEnergy > fRightEnergy ) - { - fLRRatio = fLeftEnergy - fRightEnergy; - } - else - { - fLRRatio = fRightEnergy - fLeftEnergy; - } - - if ( fMidEnergy > fSideEnergy ) - { - fMSRatio = fMidEnergy - fSideEnergy; - } - else - { - fMSRatio = fSideEnergy - fMidEnergy; - } - - if ( fMSRatio > fLRRatio ) - { - iNumMSBands++; - piMSFlags[b] = 1; - } - else - { - piMSFlags[b] = 0; - } - - if ( fMSRatio > fLRRatio ) - { - float maskThresShift_dB_by_10 = ( fMSRatio - fLRRatio ) * (float) c_aiDefaultTheta48[b] / 16.0f; - msBitsReduction += (float) ( piBandwidths[b] * iNumBlocks * 2 ) * one_by_log10_2 * maskThresShift_dB_by_10; /* * 2 for real/imag */ - } - - if ( fMSPredRatio > fLRRatio ) - { - float maskThresShift_dB_by_10 = ( fMSPredRatio - fLRRatio ) * (float) c_aiDefaultTheta48[b] / 16.0f; - msPredBitsReduction += (float) ( piBandwidths[b] * iNumBlocks * 2 ) * one_by_log10_2 * maskThresShift_dB_by_10; - iNumMSPredBands++; - piMSPredFlags[b] = 1; - } - else - { - piMSPredFlags[b] = 0; - } - } - - msPredBits = CountMSBits( iNumBands, 3, piMSPredFlags, piLRPhaseDiffs, piMSPredCoefs ); - msPredBitsReduction = max( msPredBitsReduction - (float) msPredBits, 0.0f ); - msBits = CountMSBits( iNumBands, 2, piMSFlags, NULL, NULL ); - msBitsReduction = max( msBitsReduction - (float) msBits, 0.0f ); -#ifdef DEBUG_WRITE_MS_PRED - { - static FILE *fid = 0; - if ( !fid ) - { - fid = fopen( "bit_red.txt", "wt" ); - } - fprintf( fid, "%.1f %.1f %d %d\n", msBitsReduction, msPredBitsReduction, msBits, msPredBits ); - } -#endif - - if ( iAllowSidePred && msPredBitsReduction > 1.1f * msBitsReduction ) - { - *piMSMode = 3; - for ( b = 0; b < iNumBands; b++ ) - { - piMSFlags[b] = piMSPredFlags[b]; - } - iNumMSBands = iNumMSPredBands; - } - else if ( iNumMSBands == iNumBands ) - { - *piMSMode = 1; - } - else if ( iNumMSBands > 0 ) - { - *piMSMode = 2; - } - else - { - *piMSMode = 0; - } - - if ( *piMSMode > 0 ) - { - iFBOffset = 0; - for ( b = 0; b < iNumBands; b++ ) - { -#if defined SIMPLE_PHASE - void ( *pFuncPhaseRotate )( float *, float * ) = pFuncPhaseRotateOptions[piLRPhaseDiffs[b]]; -#endif - if ( piMSFlags[b] == 1 ) - { - int32_t n; - for ( n = 0; n < piBandwidths[b]; n++ ) - { - int32_t k; - for ( k = 0; k < iNumBlocks; k++ ) - { - float fMidReal; - float fMidImag; - float fSideReal; - float fSideImag; - - if ( *piMSMode == 3 ) - { -#ifdef SIMPLE_PHASE - ( *pFuncPhaseRotate )( &pppfReal[1][k][iFBOffset], &pppfImag[1][k][iFBOffset] ); -#else - int32_t phaseIdx; - - phaseIdx = piLRPhaseDiffs[b] - PHASE_MIN_VAL; - cplxmult( &pppfReal[1][k][iFBOffset], &pppfImag[1][k][iFBOffset], c_afRotRealImag[phaseIdx][0], c_afRotRealImag[phaseIdx][1] ); -#endif - } - - 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] ); - - if ( *piMSMode == 3 ) - { - fPred = dequantPred( piMSPredCoefs[b] ); - fSideReal -= fPred * fMidReal; - fSideImag -= fPred * fMidImag; - } - - pppfReal[0][k][iFBOffset] = fMidReal; - pppfReal[1][k][iFBOffset] = fSideReal; - pppfImag[0][k][iFBOffset] = fMidImag; - pppfImag[1][k][iFBOffset] = fSideImag; - } - iFBOffset++; - } - } - else - { - iFBOffset += piBandwidths[b]; - } - } - } - -#ifdef DEBUG_WRITE_MS_PRED - { - static FILE *fid = 0; - if ( !fid ) - { - fid = fopen( "ms_mode_enc_raw.txt", "wt" ); - } - writeMSPred( piLRPhaseDiffs, piMSPredCoefs, *piMSMode, iNumBands, iNumBands, fid, piMSFlags ); - } -#endif - if ( *piMSMode == 3 ) - { - /* Differential Coding of Phase Data*/ - PrepEncode( piLRPhaseDiffs, piMSFlags, iNumBands ); - PrepEncode( piMSPredCoefs, piMSFlags, iNumBands ); -#ifdef DEBUG_WRITE_MS_PRED - { - static FILE *fid = 0; - if ( !fid ) - { - fid = fopen( "ms_mode_enc.txt", "wt" ); - } - writeMSPred( piLRPhaseDiffs, piMSPredCoefs, *piMSMode, iNumMSBands, iNumBands, fid, piMSFlags ); - } -#endif - /* Differential Coding*/ -#ifndef SIMPLE_PHASE - EncodePhase( piLRPhaseDiffs, iNumMSBands, PHASE_DIFF_DIM ); -#endif - EncodePredCoef( piMSPredCoefs, iNumMSBands ); -#ifdef DEBUG_WRITE_MS_PRED - { - static FILE *fid = 0; - if ( !fid ) - { - fid = fopen( "ms_mode_enc_diff.txt", "wt" ); - } - writeMSPred( piLRPhaseDiffs, piMSPredCoefs, *piMSMode, iNumMSBands, iNumBands, fid, piMSFlags ); - } -#endif - } - - 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 ) -{ - int32_t k, n, b, iFBOffset, m, iRMSEnv; - int32_t iBlockOffset; - float fGain; - - iBlockOffset = 0; - for ( n = 0; n < iNumGroups; n++ ) - { - for ( k = 0; k < piGroupLengths[n]; k++ ) - { - iFBOffset = 0; - 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++ ) - { - ppfReal[iBlockOffset][iFBOffset] *= fGain; - ppfImag[iBlockOffset][iFBOffset] *= fGain; - iFBOffset++; - } - } - iBlockOffset++; - } - } - - 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, - int32_t *piPredEnable, - float *pfA1Real, - float *pfA1Imag ) /* Pass in 2 previous value buffers NULLABLE */ -{ - int32_t b, m, n, iBlockOffset; - float fVal, fPrevReal, fPrevImag, fPredReal, fPredImag; - int32_t iFBOffset; - int32_t k, iAlloc, iQuantValue, iMaxQuantVal; - float fSCFGain, fInvSCFGain; - - iFBOffset = 0; - for ( b = 0; b < iNumBands; b++ ) - { - for ( m = 0; m < piBandwidths[b]; m++ ) - { - iBlockOffset = 0; - fPrevReal = 0.0; - fPrevImag = 0.0; - for ( n = 0; n < iNumGroups; n++ ) - { - iAlloc = ppiAlloc[n][b]; - iMaxQuantVal = c_aiQuantMaxValues[iAlloc]; - fSCFGain = c_afScaleFactor[iAlloc]; - fInvSCFGain = c_afInvScaleFactor[iAlloc]; - - if ( piPredEnable[iFBOffset] == 1 ) - { - for ( k = 0; k < piGroupLengths[n]; k++ ) - { - fPredReal = 0.0; - fPredImag = 0.0; - - fPredReal = pfA1Real[iFBOffset] * fPrevReal - pfA1Imag[iFBOffset] * fPrevImag; - fPredImag = pfA1Real[iFBOffset] * fPrevImag + pfA1Imag[iFBOffset] * fPrevReal; - - fVal = ppfReal[iBlockOffset][iFBOffset] + fPredReal; - if ( fVal > 0.0 ) - { - iQuantValue = (int32_t) ( fSCFGain * fVal + 0.5 ); - ppiSignReal[iBlockOffset][iFBOffset] = 0; - } - else - { - iQuantValue = (int32_t) ( -fSCFGain * fVal + 0.5 ); - ppiSignReal[iBlockOffset][iFBOffset] = 1; - } - iQuantValue = ( iQuantValue < iMaxQuantVal ) ? iQuantValue : iMaxQuantVal; - - ppiQReal[iBlockOffset][iFBOffset] = iQuantValue; - - fVal = ppfImag[iBlockOffset][iFBOffset] + fPredImag; - if ( fVal > 0.0 ) - { - iQuantValue = (int32_t) ( fSCFGain * fVal + 0.5 ); - ppiSignImag[iBlockOffset][iFBOffset] = 0; - } - else - { - iQuantValue = (int32_t) ( -fSCFGain * fVal + 0.5 ); - ppiSignImag[iBlockOffset][iFBOffset] = 1; - } - - iQuantValue = ( iQuantValue < iMaxQuantVal ) ? iQuantValue : iMaxQuantVal; - ppiQImag[iBlockOffset][iFBOffset] = iQuantValue; - - - if ( ppiSignReal[iBlockOffset][iFBOffset] == 0 ) - { - fPrevReal = fInvSCFGain * (float) ppiQReal[iBlockOffset][iFBOffset] - fPredReal; - } - else - { - fPrevReal = -fInvSCFGain * (float) ppiQReal[iBlockOffset][iFBOffset] - fPredReal; - } - if ( ppiSignImag[iBlockOffset][iFBOffset] == 0 ) - { - fPrevImag = fInvSCFGain * (float) ppiQImag[iBlockOffset][iFBOffset] - fPredImag; - } - else - { - fPrevImag = -fInvSCFGain * (float) ppiQImag[iBlockOffset][iFBOffset] - fPredImag; - } - - iBlockOffset++; - } - } - else - { - for ( k = 0; k < piGroupLengths[n]; k++ ) - { - fVal = ppfReal[iBlockOffset][iFBOffset]; - if ( fVal > 0.0 ) - { - iQuantValue = (int32_t) ( fSCFGain * fVal + 0.5 ); - ppiSignReal[iBlockOffset][iFBOffset] = 0; - } - else - { - iQuantValue = (int32_t) ( -fSCFGain * fVal + 0.5 ); - ppiSignReal[iBlockOffset][iFBOffset] = 1; - } - iQuantValue = ( iQuantValue < iMaxQuantVal ) ? iQuantValue : iMaxQuantVal; - - ppiQReal[iBlockOffset][iFBOffset] = iQuantValue; - - fVal = ppfImag[iBlockOffset][iFBOffset]; - if ( fVal > 0.0 ) - { - iQuantValue = (int32_t) ( fSCFGain * fVal + 0.5 ); - ppiSignImag[iBlockOffset][iFBOffset] = 0; - } - else - { - iQuantValue = (int32_t) ( -fSCFGain * fVal + 0.5 ); - ppiSignImag[iBlockOffset][iFBOffset] = 1; - } - iQuantValue = ( iQuantValue < iMaxQuantVal ) ? iQuantValue : iMaxQuantVal; - ppiQImag[iBlockOffset][iFBOffset] = iQuantValue; - iBlockOffset++; - } - } - } - - iFBOffset++; - } - } - - return; -} - - -static void QuantizeSpectrumDPCM( - 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, - int32_t *piPredEnable, - float *pfA1Real, - float *pfA1Imag ) /* Pass in 2 previous value buffers NULLABLE */ -{ - int32_t b, m, n, iBlockOffset; - float fVal, fPrevReal, fPrevImag, fPredReal, fPredImag; - int32_t iFBOffset; - int32_t k, iAlloc, iQuantValue, iMaxQuantVal; - float fSCFGain, fInvSCFGain; - - iFBOffset = 0; - for ( b = 0; b < iNumBands; b++ ) - { - for ( m = 0; m < piBandwidths[b]; m++ ) - { - iBlockOffset = 0; - fPrevReal = 0.0; - fPrevImag = 0.0; - 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++ ) - { - fPredReal = 0.0; - fPredImag = 0.0; - - if ( piPredEnable[iFBOffset] == 1 ) - { - fPredReal = pfA1Real[iFBOffset] * fPrevReal - pfA1Imag[iFBOffset] * fPrevImag; - fPredImag = pfA1Real[iFBOffset] * fPrevImag + pfA1Imag[iFBOffset] * fPrevReal; - } - else - { // don't need - fPredReal = 0.0; - fPredImag = 0.0; - } - - fVal = ppfReal[iBlockOffset][iFBOffset] + fPredReal; - if ( fVal > 0.0 ) - { - iQuantValue = (int32_t) ( fSCFGain * fVal + 0.5 ); - ppiSignReal[iBlockOffset][iFBOffset] = 0; - } - else - { - iQuantValue = (int32_t) ( -fSCFGain * fVal + 0.5 ); - ppiSignReal[iBlockOffset][iFBOffset] = 1; - } -#ifdef _DEBUG_VERBOSE - if ( iQuantValue > iMaxQuantVal ) - { - printf( "Value out of range %d\t%d\t%d\t%d\n", b, iAlloc, iQuantValue, iMaxQuantVal ); - iQuantValue = iMaxQuantVal; - } -#else - iQuantValue = ( iQuantValue < iMaxQuantVal ) ? iQuantValue : iMaxQuantVal; -#endif - - ppiQReal[iBlockOffset][iFBOffset] = iQuantValue; - - fVal = ppfImag[iBlockOffset][iFBOffset] + fPredImag; - if ( fVal > 0.0 ) - { - iQuantValue = (int32_t) ( fSCFGain * fVal + 0.5 ); - ppiSignImag[iBlockOffset][iFBOffset] = 0; - } - else - { - iQuantValue = (int32_t) ( -fSCFGain * fVal + 0.5 ); - ppiSignImag[iBlockOffset][iFBOffset] = 1; - } - -#ifdef _DEBUG_VERBOSE - if ( iQuantValue > iMaxQuantVal ) - { - printf( "Value out of range %d\t%d\t%d\t%d\n", b, iAlloc, iQuantValue, iMaxQuantVal ); - iQuantValue = iMaxQuantVal; - } -#else - iQuantValue = ( iQuantValue < iMaxQuantVal ) ? iQuantValue : iMaxQuantVal; -#endif - ppiQImag[iBlockOffset][iFBOffset] = iQuantValue; - - if ( piPredEnable[iFBOffset] == 1 ) - { - if ( ppiSignReal[iBlockOffset][iFBOffset] == 0 ) - { - fPrevReal = fInvSCFGain * (float) ppiQReal[iBlockOffset][iFBOffset] - fPredReal; - } - else - { - fPrevReal = -fInvSCFGain * (float) ppiQReal[iBlockOffset][iFBOffset] - fPredReal; - } - if ( ppiSignImag[iBlockOffset][iFBOffset] == 0 ) - { - fPrevImag = fInvSCFGain * (float) ppiQImag[iBlockOffset][iFBOffset] - fPredImag; - } - else - { - fPrevImag = -fInvSCFGain * (float) ppiQImag[iBlockOffset][iFBOffset] - fPredImag; - } - } - else - { - fPrevReal = 0.0; - fPrevImag = 0.0; - } - - iBlockOffset++; - } - } - - iFBOffset++; - } - } - - return; -} - - -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 ) -{ - int32_t k, n, b, iFBOffset; - int32_t iBits, iBlockOffest; - int32_t m, iAlloc, iHuffDim, iHuffMod; - - iBits = 0; - iBlockOffest = 0; - for ( n = 0; n < iNumGroups; n++ ) - { - for ( k = 0; k < piGroupLengths[n]; k++ ) - { - iFBOffset = 0; - for ( b = 0; b < iNumBands; b++ ) - { - iAlloc = ppiAlloc[n][b]; - - iHuffDim = c_aiHuffmanDim[iAlloc]; - iHuffMod = c_aiHuffmanMod[iAlloc]; - - if ( iAlloc > 0 ) - { - const uint16_t( *pauiHuffmanTable )[2] = NULL; - const uint16_t( *pauiHuffmanTableDPCM )[2] = NULL; - pauiHuffmanTable = c_apauiHuffEncTabels[iAlloc]; - pauiHuffmanTableDPCM = c_apauiHuffEncTabels[ALLOC_TABLE_SIZE + iAlloc]; - for ( m = 0; m < piBandwidths[b]; m++ ) - { - int32_t iQuantValue1; - int32_t iQuantValue2; - - iQuantValue1 = ppiQReal[iBlockOffest][iFBOffset]; - iQuantValue2 = ppiQImag[iBlockOffest][iFBOffset]; - - iBits += ( iQuantValue1 > 0 ) ? 1 : 0; /* Sign bit for vals > 0 */ - iBits += ( iQuantValue2 > 0 ) ? 1 : 0; /* Sign bit for vals > 0 */ - - if ( piPredEnable[iFBOffset] == 1 ) - { - if ( iHuffDim == 2 ) - { - iQuantValue1 *= iHuffMod; - iQuantValue1 += iQuantValue2; - iBits += pauiHuffmanTableDPCM[iQuantValue1][0]; - } - else - { - iBits += pauiHuffmanTableDPCM[iQuantValue1][0]; - iBits += pauiHuffmanTableDPCM[iQuantValue2][0]; - } - } - else - { - if ( iHuffDim == 2 ) - { - iQuantValue1 *= iHuffMod; - iQuantValue1 += iQuantValue2; - iBits += pauiHuffmanTable[iQuantValue1][0]; - } - else - { - iBits += pauiHuffmanTable[iQuantValue1][0]; - iBits += pauiHuffmanTable[iQuantValue2][0]; - } - } - - iFBOffset++; - } - } - else - { - iFBOffset += piBandwidths[b]; - } - } - - iBlockOffest++; - } - } - - return iBits; -} - - -/* Currently only the number of bands in frame */ -static int32_t WriteHeaderInformation( - const int32_t iNumBands, - IVAS_SPLIT_REND_BITS_HANDLE pBits ) -{ - int32_t iBitsWritten; - - iBitsWritten = 0; - ivas_split_rend_bitstream_write_int32( pBits, iNumBands, 5 ); - 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, - IVAS_SPLIT_REND_BITS_HANDLE pBits ) -{ - int32_t iBitsWritten; - int32_t iMSPredAll = ( iNumMSPredBands == iNumBands ); -#ifdef DEBUG_WRITE_MS_PRED - int32_t iBitsWrittenTmp = 0; -#endif - iBitsWritten = 0; - ivas_split_rend_bitstream_write_int32( pBits, iMSMode, 2 ); - iBitsWritten += 2; - - if ( iMSMode == 3 ) - { - ivas_split_rend_bitstream_write_int32( pBits, iMSPredAll, 1 ); - iBitsWritten += 1; - } - - if ( iMSMode == 2 || ( iMSMode == 3 && !iMSPredAll ) ) - { - int32_t n; - for ( n = 0; n < iNumBands; n++ ) - { - ivas_split_rend_bitstream_write_int32( pBits, piMSFlags[n], 1 ); - iBitsWritten += 1; - } - } - -#ifdef DEBUG_WRITE_MS_PRED - iBitsWrittenTmp = iBitsWritten; -#endif - if ( iMSMode == 3 ) - { - int32_t b; - int32_t anyNonZero; - anyNonZero = 0; - for ( b = 0; b < iNumMSPredBands; b++ ) - { - if ( piLRPhaseDiff[b] != 0 ) - { - anyNonZero = 1; - break; - } - } - ivas_split_rend_bitstream_write_int32( pBits, anyNonZero, 1 ); - iBitsWritten++; - - if ( anyNonZero ) - { -#ifdef SIMPLE_PHASE - for ( b = 0; b < iNumMSPredBands; b++ ) - { - ivas_split_rend_bitstream_write_int32( pBits, piLRPhaseDiff[b], SIMPLE_PHASE_BITS ); - iBitsWritten += SIMPLE_PHASE_BITS; - } -#else - ivas_split_rend_bitstream_write_int32( pBits, piLRPhaseDiff[0] - PHASE_MIN_VAL, PHASE_BAND0_BITS ); - iBitsWritten += PHASE_BAND0_BITS; - for ( b = 1; b < iNumMSPredBands; b++ ) - { - int32_t tabIdx = piLRPhaseDiff[b] - ENV_DELTA_MIN; - ivas_split_rend_bitstream_write_int32( pBits, c_aaiRMSEnvHuffEnc[tabIdx][1], c_aaiRMSEnvHuffEnc[tabIdx][0] ); - iBitsWritten += c_aaiRMSEnvHuffEnc[tabIdx][0]; - } -#endif - } - - anyNonZero = 0; - for ( b = 0; b < iNumMSPredBands; b++ ) - { - if ( piMSPredCoef[b] != 0 ) - { - anyNonZero = 1; - break; - } - } - - ivas_split_rend_bitstream_write_int32( pBits, anyNonZero, 1 ); - iBitsWritten++; - - if ( anyNonZero ) - { - ivas_split_rend_bitstream_write_int32( pBits, piMSPredCoef[0] - PRED_MIN_VAL, PRED_BAND0_BITS ); - iBitsWritten += PRED_BAND0_BITS; - for ( b = 1; b < iNumMSPredBands; b++ ) - { - int32_t tabIdx = piMSPredCoef[b] - ENV_DELTA_MIN; - ivas_split_rend_bitstream_write_int32( pBits, c_aaiRMSEnvHuffEnc[tabIdx][1], c_aaiRMSEnvHuffEnc[tabIdx][0] ); - iBitsWritten += c_aaiRMSEnvHuffEnc[tabIdx][0]; - } - } - } -#ifdef DEBUG_WRITE_MS_PRED - { - static FILE *fid = 0; - if ( !fid ) - { - fid = fopen( "ms_pred_bitrate.txt", "wt" ); - } - fprintf( fid, "%f\n", (float) ( ( iBitsWritten - iBitsWrittenTmp ) * ( iMSMode == 3 ) * 50 ) / 1000.0f ); /*kb/s*/ - } -#endif - - return iBitsWritten; -} - - -static int32_t WriteGroupInformation( - const int32_t iChannels, - const int32_t iCommonGrouping, - const int32_t *piNumGroups, - int32_t **ppiGroupLengths, - IVAS_SPLIT_REND_BITS_HANDLE pBits ) -{ - int32_t c, k, n, iBitsWritten; - - iBitsWritten = 0; - if ( iChannels == 2 && iCommonGrouping == 1 ) - { - ivas_split_rend_bitstream_write_int32( pBits, iCommonGrouping, 1 ); - iBitsWritten += 1; - - for ( n = 0; n < piNumGroups[0]; n++ ) - { - for ( k = 1; k < ppiGroupLengths[0][n]; k++ ) - { - ivas_split_rend_bitstream_write_int32( pBits, 0, 1 ); - iBitsWritten += 1; - } - if ( n < ( piNumGroups[0] - 1 ) ) - { - ivas_split_rend_bitstream_write_int32( pBits, 1, 1 ); - iBitsWritten += 1; - } - } - } - else if ( iChannels == 2 ) - { - ivas_split_rend_bitstream_write_int32( pBits, iCommonGrouping, 1 ); - iBitsWritten += 1; - - for ( c = 0; c < iChannels; c++ ) - { - for ( n = 0; n < piNumGroups[c]; n++ ) - { - for ( k = 1; k < ppiGroupLengths[c][n]; k++ ) - { - ivas_split_rend_bitstream_write_int32( pBits, 0, 1 ); - iBitsWritten += 1; - } - if ( n < ( piNumGroups[c] - 1 ) ) - { - ivas_split_rend_bitstream_write_int32( pBits, 1, 1 ); - iBitsWritten += 1; - } - } - } - } - else - { - for ( c = 0; c < iChannels; c++ ) - { - for ( n = 0; n < piNumGroups[c]; n++ ) - { - for ( k = 1; k < ppiGroupLengths[c][n]; k++ ) - { - ivas_split_rend_bitstream_write_int32( pBits, 0, 1 ); - iBitsWritten += 1; - } - - if ( n < ( piNumGroups[c] - 1 ) ) - { - ivas_split_rend_bitstream_write_int32( pBits, 1, 1 ); - iBitsWritten += 1; - } - } - } - } - - return iBitsWritten; -} - - -static int32_t WriteRMSEnvelope( - const int32_t iChannels, - const int32_t *piNumGroups, - const int32_t iNumBands, - int32_t ***pppiRMSEnvelope, - IVAS_SPLIT_REND_BITS_HANDLE pBits ) -{ - int32_t k, n; - int32_t iBitsWritten; - - iBitsWritten = 0; - for ( n = 0; n < iChannels; n++ ) - { - for ( k = 0; k < piNumGroups[n]; k++ ) - { - int32_t b; - int32_t iLastRMSVal; - - iLastRMSVal = pppiRMSEnvelope[n][k][0]; - iLastRMSVal = ( iLastRMSVal > ENV_MIN ) ? iLastRMSVal : ENV_MIN; - iLastRMSVal = ( iLastRMSVal < ENV_MAX ) ? iLastRMSVal : ENV_MAX; - ivas_split_rend_bitstream_write_int32( pBits, ( iLastRMSVal - ENV_MIN ), ENV0_BITS ); - 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; - ivas_split_rend_bitstream_write_int32( pBits, c_aaiRMSEnvHuffEnc[iDelta][1], c_aaiRMSEnvHuffEnc[iDelta][0] ); - iBitsWritten += c_aaiRMSEnvHuffEnc[iDelta][0]; - - iLastRMSVal = pppiRMSEnvelope[n][k][b]; - } - } - } - - return iBitsWritten; -} - - -#ifdef ENABLE_PMOD_ADJUST -static int32_t WritePmodInformation( - const int32_t **ppiHiSMRFlags, - IVAS_SPLIT_REND_BITS_HANDLE pBits, - int32_t iChannels, - int32_t iNumBands ) -{ - int32_t iBitsWritten, c, b; - - iBitsWritten = 0; - - for ( c = 0; c < iChannels; c++ ) - { - int32_t anyNonZero = 0; - const int32_t *flags = ppiHiSMRFlags[c]; - for ( b = 0; b < iNumBands; b++ ) - { - if ( flags[b] ) - { - anyNonZero = 1; - break; - } - } - ivas_split_rend_bitstream_write_int32( pBits, anyNonZero, 1 ); - iBitsWritten += 1; - if ( anyNonZero ) - { - for ( b = 0; b < iNumBands; b++ ) - { - ivas_split_rend_bitstream_write_int32( pBits, flags[b], 1 ); - iBitsWritten += 1; - } - } - } -#ifdef WRITE_HISMR_FLAGS - { - static FILE *fid = 0; - if ( !fid ) - { - fid = fopen( "hismr_enc.txt", "wt" ); - } - for ( c = 0; c < iChannels; c++ ) - { - int32_t b; - for ( b = 0; b < iNumBands; b++ ) - { - if ( c == iChannels - 1 && b == iNumBands - 1 ) - { - fprintf( fid, "%d\n", ppiHiSMRFlags[c][b] ); - } - else - { - fprintf( fid, "%d ", ppiHiSMRFlags[c][b] ); - } - } - } - } -#endif - - return iBitsWritten; -} -#endif - - -static int32_t WriteAllocInformation( - const int32_t iAllocOffset, - IVAS_SPLIT_REND_BITS_HANDLE pBits ) -{ - int32_t iBitsWritten; - - iBitsWritten = 0; - - if ( iAllocOffset < MIN_ALLOC_OFFSET || iAllocOffset > MAX_ALLOC_OFFSET ) - { - printf( "Serious error\n" ); - } - - ivas_split_rend_bitstream_write_int32( pBits, ( iAllocOffset - MIN_ALLOC_OFFSET ), ALLOC_OFFSET_BITS ); - iBitsWritten += ALLOC_OFFSET_BITS; - - return iBitsWritten; -} - - -static int32_t WriteLCLDData( - 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, - IVAS_SPLIT_REND_BITS_HANDLE pBits ) -{ - int32_t n; - int32_t iBitsWritten; - int32_t iBlockOffest; - - iBitsWritten = 0; - iBlockOffest = 0; - - for ( n = 0; n < iNumGroups; n++ ) - { - int32_t k; - for ( k = 0; k < piGroupLengths[n]; k++ ) - { - int32_t b; - int32_t iFBOffset; - - iFBOffset = 0; - for ( b = 0; b < iNumBands; b++ ) - { - int32_t m; - int32_t iAlloc; - int32_t iHuffDim; - int32_t iHuffMod; - - iAlloc = ppiAlloc[n][b]; - - iHuffDim = c_aiHuffmanDim[iAlloc]; - iHuffMod = c_aiHuffmanMod[iAlloc]; - - if ( iAlloc > 0 ) - { - const uint16_t( *pauiHuffmanTable )[2] = NULL; - const uint16_t( *pauiHuffmanTableDPCM )[2] = NULL; - pauiHuffmanTable = c_apauiHuffEncTabels[iAlloc]; - pauiHuffmanTableDPCM = c_apauiHuffEncTabels[ALLOC_TABLE_SIZE + iAlloc]; - for ( m = 0; m < piBandwidths[b]; m++ ) - { - int32_t iQuantValue1; - int32_t iQuantValue2; - - iQuantValue1 = ppiQReal[iBlockOffest][iFBOffset]; - iQuantValue2 = ppiQImag[iBlockOffest][iFBOffset]; - - if ( piPredEnable[iFBOffset] == 1 ) - { - if ( iHuffDim == 2 ) - { - int32_t iSymbol; - iSymbol = iQuantValue1; - iSymbol *= iHuffMod; - iSymbol += iQuantValue2; - ivas_split_rend_bitstream_write_int32( pBits, pauiHuffmanTableDPCM[iSymbol][1], pauiHuffmanTableDPCM[iSymbol][0] ); - iBitsWritten += pauiHuffmanTableDPCM[iSymbol][0]; - } - else - { - ivas_split_rend_bitstream_write_int32( pBits, pauiHuffmanTableDPCM[iQuantValue1][1], pauiHuffmanTableDPCM[iQuantValue1][0] ); - iBitsWritten += pauiHuffmanTableDPCM[iQuantValue1][0]; - - ivas_split_rend_bitstream_write_int32( pBits, pauiHuffmanTableDPCM[iQuantValue2][1], pauiHuffmanTableDPCM[iQuantValue2][0] ); - iBitsWritten += pauiHuffmanTableDPCM[iQuantValue2][0]; - } - } - else - { - if ( iHuffDim == 2 ) - { - int32_t iSymbol; - iSymbol = iQuantValue1; - iSymbol *= iHuffMod; - iSymbol += iQuantValue2; - ivas_split_rend_bitstream_write_int32( pBits, pauiHuffmanTable[iSymbol][1], pauiHuffmanTable[iSymbol][0] ); - iBitsWritten += pauiHuffmanTable[iSymbol][0]; - } - else - { - ivas_split_rend_bitstream_write_int32( pBits, pauiHuffmanTable[iQuantValue1][1], pauiHuffmanTable[iQuantValue1][0] ); - iBitsWritten += pauiHuffmanTable[iQuantValue1][0]; - - ivas_split_rend_bitstream_write_int32( pBits, pauiHuffmanTable[iQuantValue2][1], pauiHuffmanTable[iQuantValue2][0] ); - iBitsWritten += pauiHuffmanTable[iQuantValue2][0]; - } - } - - if ( iQuantValue1 > 0 ) - { - ivas_split_rend_bitstream_write_int32( pBits, ppiSignReal[iBlockOffest][iFBOffset], 1 ); - iBitsWritten += 1; - } - if ( iQuantValue2 > 0 ) - { - ivas_split_rend_bitstream_write_int32( pBits, ppiSignImag[iBlockOffest][iFBOffset], 1 ); - iBitsWritten += 1; - } - - iFBOffset++; - } - } - else - { - iFBOffset += piBandwidths[b]; - } - } - - iBlockOffest++; - } - } - - 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, - int32_t **ppiPredEnable, - float **ppfA1Real, - float **ppfA1Imag ) -{ - int32_t iBitsUsed, iDone, iDelta; - int32_t b, k, n; - int32_t iLimitAllocOffset; - - iBitsUsed = ALLOC_OFFSET_BITS; /* Bits used for Alloc Offset */ - - iDone = 0; - iDelta = -MIN_ALLOC_OFFSET; - *piAllocOffset = 0; - - while ( iDone == 0 ) - { - iBitsUsed = ALLOC_OFFSET_BITS; - - iLimitAllocOffset = *piAllocOffset; - iLimitAllocOffset = ( iLimitAllocOffset > MIN_ALLOC_OFFSET ) ? iLimitAllocOffset : MIN_ALLOC_OFFSET; - iLimitAllocOffset = ( iLimitAllocOffset < MAX_ALLOC_OFFSET ) ? iLimitAllocOffset : MAX_ALLOC_OFFSET; - - for ( n = 0; n < iChannels; n++ ) - { - for ( k = 0; k < piNumGroups[n]; k++ ) - { - 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; - pppiAlloc[n][k][b] = iAlloc; - } - } - - QuantizeSpectrumDPCM_Opt( piNumGroups[n], - (const int32_t *) ppiGroupLengths[n], - iNumBands, - piBandwidths, - pppiAlloc[n], - pppfReal[n], - pppfImag[n], - pppiQReal[n], - pppiQImag[n], - pppiSignReal[n], - pppiSignImag[n], - ppiPredEnable[n], - ppfA1Real[n], - ppfA1Imag[n] ); - - iBitsUsed += CountLCLDBits( piNumGroups[n], - (const int32_t *) ppiGroupLengths[n], - iNumBands, - piBandwidths, - (const int32_t *) ppiPredEnable[n], - pppiAlloc[n], - pppiQReal[n], - pppiQImag[n] ); - } - - if ( *piAllocOffset <= MIN_ALLOC_OFFSET && iBitsUsed > iAvailableBits ) - { -#ifdef DEBUG_VERBOSE - printf( "Frame can not be coded with the number of bits available\n" ); -#endif - // iLastError = ENC_ERROR_STREAM_FAILURE; - return -1; - } - else if ( *piAllocOffset >= MAX_ALLOC_OFFSET && iBitsUsed < iAvailableBits ) - { - *piAllocOffset = MAX_ALLOC_OFFSET; - iDone++; - } - else - { - if ( iDelta == 0 && iBitsUsed > iAvailableBits ) - { - iDelta = 1; - } - else if ( iDelta == 0 && iBitsUsed < iAvailableBits ) - { - iDone++; - } - else if ( iBitsUsed == iAvailableBits ) - { - iDone++; - } - - if ( iBitsUsed > iAvailableBits ) - { - *piAllocOffset -= iDelta; - iDelta >>= 1; - } - else if ( iBitsUsed < iAvailableBits ) - { - *piAllocOffset += iDelta; - iDelta >>= 1; - } - } - } - - // 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_rend/ivas_lcld_prot.h b/lib_rend/ivas_lcld_prot.h deleted file mode 100644 index ad35e50f0..000000000 --- a/lib_rend/ivas_lcld_prot.h +++ /dev/null @@ -1,370 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2023 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 _IVAS_LCLD_ENCODER_H_ -#define _IVAS_LCLD_ENCODER_H_ - -#include "options.h" -#ifdef SPLIT_REND_WITH_HEAD_ROT -#include "lib_rend.h" -#include "ivas_lcld_rom_tables.h" - -/* clang-format off */ - -typedef struct LCLD_ENCODER LCLDEncoder; - -ivas_error CreateLCLDEncoder( - LCLDEncoder **psLCLDEncoder, - const int32_t iSampleRate, - const int32_t iChannels, - const int32_t iTargetBitRate, - const int32_t iAllowSidePred ); - -void DeleteLCLDEncoder( - LCLDEncoder *psLCLDEncoder -); - -int32_t EncodeLCLDFrame( - LCLDEncoder *psLCLDEncoder, - float ***pppfLCLDReal, - float ***pppfLCLDImag, - int32_t *piNumiBites, - const int32_t available_bits, - IVAS_SPLIT_REND_BITS_HANDLE pBits ); - -int32_t GetNumGroups( - LCLDEncoder *psLCLDEncoder -); - - -typedef struct LCLD_DECODER LCLDDecoder; - -ivas_error CreateLCLDDecoder( - LCLDDecoder **psLCLDDecoder_out, - const int32_t iSampleRate, - const int32_t iChannels ); - -void DeleteLCLDDecoder( - LCLDDecoder *psLCLDDecoder -); - -int32_t DecodeLCLDFrame( - LCLDDecoder *psLCLDDecoder, - IVAS_SPLIT_REND_BITS_HANDLE pBits, - float ***pppfLCLDReal, - float ***pppfLCLDImag -); - - -/*----------------------------------------------------------------------------------* - * MSPred prototypes - *----------------------------------------------------------------------------------*/ - -int32_t quantPhase( - float phase -); - -void cplxmult( - float *pr1, - float *pi1, - float r2, - float i2 -); - -#ifdef SIMPLE_PHASE -void rot_pm_pi( - float *pr, - float *pi ); - -void rot_p_pi_2( - float *pr, - float *pi -); - -void rot_m_pi_2( - float *pr, - float *pi ); - -void rot_zero( - float *pr, - float *pi -); -#endif - -int32_t requantPhase( - int32_t phaseQ -); - -int32_t quantPred( - const float pred -); - -float dequantPhase( - const int32_t phaseQ -); - -float dequantPred( - int32_t predQ -); - -int32_t PrepEncode( - int32_t *piQuant, - const int32_t *piMSFlags, - const int32_t numBands -); - -void EncodePhase( - int32_t *phaseQuant, - const int32_t numMSBands, - const int32_t diffDim -); - -void DecodePhase( - int32_t *phaseQuant, - const int32_t numMSBands, - const int32_t diffDim -); - -int32_t EncodePredCoef( - int32_t *predQuant, - const int32_t numMSBands -); - -void DecodePredCoef( - int32_t *phaseQuant, - const int32_t numMSBands -); - -void writeMSPred( - int32_t *phaseQuant, - int32_t *predQuant, - const int32_t MSMode, - const int32_t numMSBands, - int32_t numBands, - void *fid, - 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 -); - - -/*----------------------------------------------------------------------------------* - * NoiseGen prototypes - *----------------------------------------------------------------------------------*/ - -typedef struct NOISE_GEN -{ - int32_t iNoiseBufferLength; - int32_t iNoiseBufferMask; - int32_t iNoiseBufferIndex; - float *pfNoiseBuffer; -} NoiseGen; - -NoiseGen *CreateNoiseGen( - void -); - -void DeleteNoiseGen( - NoiseGen *psNoiseGen -); - -inline float GetNoise( NoiseGen *psNoiseGen ) -{ - float fNoiseSample; - - fNoiseSample = psNoiseGen->pfNoiseBuffer[psNoiseGen->iNoiseBufferIndex]; - psNoiseGen->iNoiseBufferIndex++; - psNoiseGen->iNoiseBufferIndex &= psNoiseGen->iNoiseBufferMask; - - return fNoiseSample; -} - - -/*----------------------------------------------------------------------------------* - * PereptualModel prototypes - *----------------------------------------------------------------------------------*/ - -extern void PerceptualModel( - const int32_t iMaxQuantBands, - const int32_t *piRMSEnvelope, - int32_t *piExcitation, - int32_t *piSMR -); - -extern void PerceptualModelStereo( - const int32_t iMaxQuantBands, - const int32_t *piMSFlags, - const int32_t *piRMSEnvelope0, - const int32_t *piRMSEnvelope1, - int32_t *piExcitation0, - int32_t *piExcitation1, - int32_t *piSMR0, - int32_t *piSMR1 -); - - -/*----------------------------------------------------------------------------------* - * PredEncoder/PredDecoder prototypes - *----------------------------------------------------------------------------------*/ - -typedef struct PREDICTION_ENCODER -{ - int32_t iChannels; - int32_t iNumBlocks; - - float *pfWindow; - float pfRxxReal[2]; - float pfRxxImag[2]; - - int32_t *piPredChanEnable; - int32_t *piNumPredBands; - - float **ppfEstPredGain; - float **ppfEstPredBitGain; - int32_t **ppiPredBandEnable; - - float **ppfA1Real; - float **ppfA1Imag; - - int32_t **ppiA1Mag; - int32_t **ppiA1Phase; -} PredictionEncoder; - -ivas_error CreatePredictionEncoder( - PredictionEncoder **psPredictionEncoder_out, - const int32_t iChannels, - const int32_t iNumBlocks -); - -void DeletePredictionEncoder( - PredictionEncoder *psPredictionEncoder -); - -int32_t ComputePredictors( - PredictionEncoder *psPredictionEncoder, - float ***pppfReal, - float ***pppfImag -); - -void ApplyForwardPredictors( - PredictionEncoder *psPredictionEncoder, - float ***pppfReal, - float ***pppfImag -); - -int32_t WritePredictors( - PredictionEncoder *psPredictionEncoder, - IVAS_SPLIT_REND_BITS_HANDLE pBits -); - -typedef struct PREDICTION_DECODER -{ - int32_t iChannels; - int32_t iNumBlocks; - - int32_t *piPredChanEnable; - int32_t *piNumPredBands; - - float **ppfEstPredGain; - int32_t **ppiPredBandEnable; - - float **ppfA1Real; - float **ppfA1Imag; - - 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]; - -} PredictionDecoder; - -ivas_error CreatePredictionDecoder( - PredictionDecoder **psPredictionDecoder_out, - const int32_t iChannels, - const int32_t iNumBlocks -); - -void DeletePredictionDecoder( - PredictionDecoder *psPredictionDecoder -); - -int32_t ReadPredictors( - PredictionDecoder *psPredictionDecoder, - IVAS_SPLIT_REND_BITS_HANDLE pBits -); - -void ApplyInversePredictros( - PredictionDecoder *psPredictionDecoder, - float ***pppfReal, - float ***pppfImag -); - - -/*----------------------------------------------------------------------------------* - * RMSEnvGrouping prototypes - *----------------------------------------------------------------------------------*/ - -typedef struct RMS_ENVELOPE_GROUPING RMSEnvelopeGrouping; - -RMSEnvelopeGrouping *CreateRMSEnvelopeGrouping( - const int32_t iNumBlocks -); - -void DeleteRMSEnvelopeGrouping( - RMSEnvelopeGrouping *psRMSEnvelopeGrouping -); - -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 -); - - -#endif -/* clang-format on */ - -#endif /* _LCLD_ENCODER_H_ */ diff --git a/lib_rend/ivas_lcld_rom_tables.c b/lib_rend/ivas_lcld_rom_tables.c deleted file mode 100644 index 144c44718..000000000 --- a/lib_rend/ivas_lcld_rom_tables.c +++ /dev/null @@ -1,19854 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2023 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. - -*******************************************************************************************************/ - -#include "ivas_lcld_rom_tables.h" -#include "options.h" -#ifdef SPLIT_REND_WITH_HEAD_ROT -#include "wmc_auto.h" -#include "prot.h" -#include "ivas_lcld_prot.h" - -/* clang-format off */ - -const float c_afRotRealImagSimple[SIMPLE_PHASE_MAX_VAL + 1][2] = { - { 1.0f, 0.0f }, /* zero */ - { 0.0f, 1.0f }, /* pi/2 */ - { -1.0f, 0.0f }, /* pi */ - { 0.0f, -1.0f }, /* 3*pi/2 */ -}; - -/* 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] = -{ - { -1.00000000f, -0.00000000f }, - { -0.96592583f, -0.25881905f }, - { -0.86602540f, -0.50000000f }, - { -0.70710678f, -0.70710678f }, - { -0.50000000f, -0.86602540f }, - { -0.25881905f, -0.96592583f }, - { 0.00000000f, -1.00000000f }, - { 0.25881905f, -0.96592583f }, - { 0.50000000f, -0.86602540f }, - { 0.70710678f, -0.70710678f }, - { 0.86602540f, -0.50000000f }, - { 0.96592583f, -0.25881905f }, - { 1.00000000f, 0.00000000f }, - { 0.96592583f, 0.25881905f }, - { 0.86602540f, 0.50000000f }, - { 0.70710678f, 0.70710678f }, - { 0.50000000f, 0.86602540f }, - { 0.25881905f, 0.96592583f }, - { 0.00000000f, 1.00000000f }, - { -0.25881905f, 0.96592583f }, - { -0.50000000f, 0.86602540f }, - { -0.70710678f, 0.70710678f }, - { -0.86602540f, 0.50000000f }, - { -0.96592583f, 0.25881905f }, - { -1.00000000f, 0.00000000f } -}; - -/* Move this to perceptual model ? */ -const int32_t c_aiBandwidths48[MAX_BANDS_48] = -{ - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 1, - 2, - 2, - 2, - 2, - 2, - 3, - 3, - 4, - 6, - 6, - 7, - 10, -}; - - -const float c_afScaleFactor[ALLOC_TABLE_SIZE] = { - 0.0f, - 0.353553390593f, - 0.420448207627f, - 0.500000000000f, - 0.594603557501f, - 0.707106781187f, - 0.840896415254f, - 1.000000000000f, - 1.189207115003f, - 1.414213562373f, - 1.681792830507f, - 2.000000000000f, - 2.378414230005f, - 2.828427124746f, - 3.363585661015f, - 4.0f, - 4.756828460011f, - 5.656854249492f, - 6.727171322030f, - 8.0f, - 9.513656920022f, - 11.31370849898f, - 13.45434264406f, - 16.00000000000f, - 19.02731384004f, - 22.62741699797f, - 26.90868528812f, - 32.000000000000000f, - 38.054627680087073f, - 45.254833995939038f, - 53.817370576237735f, - 64.000000000000000f, -}; - -const float c_afInvScaleFactor[ALLOC_TABLE_SIZE] = { - 0.0f, - 2.367513562373095f, - 2.046407115002721f, - 1.775900000000000f, - 1.536446415253715f, - 1.323056781186548f, - 1.132903557501360f, - 0.965800000000000f, - 0.821348207626857f, - 0.695103390593274f, - 0.587801778750680f, - 0.495800000000000f, - 0.418124103813429f, - 0.352176695296637f, - 0.296200889375340f, - 0.249400000000000f, - 0.209812051906714f, - 0.176538347648318f, - 0.148525444687670f, - 0.124900000000000f, - 0.105056025953357f, - 0.088388347648318f, - 0.074325444687670f, - 0.062500000000000f, - 0.052556025953357f, - 0.044194173824159f, - 0.037162722343835f, - 0.031250000000000f, - 0.026278012976679f, - 0.022097086912080f, - 0.018581361171918f, - 0.015625000000000f, -}; - -const float c_afRMSEnvReconstructTable[ENV_RECONSTRUCT_TABLE_SIZE] = { - 2.32830644e-10f, - 3.29272254e-10f, - 4.65661287e-10f, - 6.58544508e-10f, - 9.31322575e-10f, - 1.31708902e-09f, - 1.86264515e-09f, - 2.63417803e-09f, - 3.72529030e-09f, - 5.26835606e-09f, - 7.45058060e-09f, - 1.05367121e-08f, - 1.49011612e-08f, - 2.10734243e-08f, - 2.98023224e-08f, - 4.21468485e-08f, - 5.96046448e-08f, - 8.42936970e-08f, - 1.19209290e-07f, - 1.68587394e-07f, - 2.38418579e-07f, - 3.37174788e-07f, - 4.76837158e-07f, - 6.74349576e-07f, - 9.53674316e-07f, - 1.34869915e-06f, - 1.90734863e-06f, - 2.69739830e-06f, - 3.81469727e-06f, - 5.39479661e-06f, - 7.62939453e-06f, - 1.07895932e-05f, - 1.52587891e-05f, - 2.15791864e-05f, - 3.05175781e-05f, - 4.31583729e-05f, - 6.10351562e-05f, - 8.63167458e-05f, - 1.22070312e-04f, - 1.72633492e-04f, - 2.44140625e-04f, - 3.45266983e-04f, - 4.88281250e-04f, - 6.90533966e-04f, - 9.76562500e-04f, - 1.38106793e-03f, - 1.95312500e-03f, - 2.76213586e-03f, - 3.90625000e-03f, - 5.52427173e-03f, - 7.81250000e-03f, - 1.10485435e-02f, - 1.56250000e-02f, - 2.20970869e-02f, - 3.12500000e-02f, - 4.41941738e-02f, - 6.25000000e-02f, - 8.83883476e-02f, - 1.25000000e-01f, - 1.76776695e-01f, - 2.50000000e-01f, - 3.53553391e-01f, - 5.00000000e-01f, - 7.07106781e-01f, - 1.00000000e+00f, - 1.41421356e+00f, - 2.00000000e+00f, - 2.82842712e+00f, - 4.00000000e+00f, - 5.65685425e+00f, - 8.00000000e+00f, - 1.13137085e+01f, - 1.60000000e+01f, - 2.26274170e+01f, - 3.20000000e+01f, - 4.52548340e+01f, - 6.40000000e+01f, - 9.05096680e+01f, - 1.28000000e+02f, - 1.81019336e+02f, - 2.56000000e+02f, - 3.62038672e+02f, - 5.12000000e+02f, - 7.24077344e+02f, - 1.02400000e+03f, - 1.44815469e+03f, - 2.04800000e+03f, - 2.89630938e+03f, - 4.09600000e+03f, - 5.79261875e+03f, - 8.19200000e+03f, - 1.15852375e+04f, - 1.63840000e+04f, - 2.31704750e+04f, - 3.27680000e+04f, - 4.63409500e+04f, - 6.55360000e+04f, - 9.26819000e+04f, - 1.31072000e+05f, - 1.85363800e+05f, - 2.62144000e+05f, - 3.70727600e+05f, - 5.24288000e+05f, - 7.41455200e+05f, - 1.04857600e+06f, - 1.48291040e+06f, - 2.09715200e+06f, - 2.96582080e+06f, - 4.19430400e+06f, - 5.93164160e+06f, - 8.38860800e+06f, - 1.18632832e+07f, - 1.67772160e+07f, - 2.37265664e+07f, - 3.35544320e+07f, - 4.74531328e+07f, - 6.71088640e+07f, - 9.49062656e+07f, - 1.34217728e+08f, - 1.89812531e+08f, - 2.68435456e+08f, - 3.79625062e+08f, - 5.36870912e+08f, - 7.59250125e+08f, - 1.07374182e+09f, - 1.51850025e+09f, - 2.14748365e+09f, - 3.03700050e+09f, - 4.29496730e+09f, -}; - -const int32_t c_aiQuantMaxValues[ALLOC_TABLE_SIZE] = { - 0, - 3, - 3, - 4, - 5, - 5, - 6, - 7, - 8, - 9, - 12, - 13, - 16, - 17, - 19, - 23, - 26, - 26, - 27, - 28, - 31, - 36, - 38, - 45, - 54, - 64, - 76, - 90, - 108, - 128, - 152, - 180, -}; - -const int32_t c_aiHuffmanDim[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 int32_t c_aiHuffmanMod[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_aiHuffmanSize[ALLOC_TABLE_SIZE] = { - 1, - 16, - 16, - 25, - 36, - 36, - 49, - 64, - 81, - 100, - 169, - 196, - 289, - 324, - 400, - 576, - 729, - 729, - 28, - 29, - 32, - 37, - 39, - 46, - 55, - 65, - 77, - 91, - 109, - 129, - 153, - 181, -}; - -const uint32_t c_aaiRMSEnvHuffEnc[64][2] = { - { 0x0014, 0x0000 }, - { 0x0014, 0x0001 }, - { 0x0014, 0x0002 }, - { 0x0014, 0x0003 }, - { 0x0014, 0x0004 }, - { 0x0014, 0x0005 }, - { 0x0013, 0x0003 }, - { 0x0013, 0x0004 }, - { 0x0013, 0x0005 }, - { 0x0013, 0x0006 }, - { 0x0013, 0x0007 }, - { 0x0012, 0x000b }, - { 0x000d, 0x0002 }, - { 0x000e, 0x0001 }, - { 0x000e, 0x0002 }, - { 0x000d, 0x0003 }, - { 0x000b, 0x0002 }, - { 0x000a, 0x0003 }, - { 0x000a, 0x0004 }, - { 0x000a, 0x0005 }, - { 0x0009, 0x0004 }, - { 0x0009, 0x0005 }, - { 0x0009, 0x0006 }, - { 0x0008, 0x0005 }, - { 0x0008, 0x0006 }, - { 0x0007, 0x0004 }, - { 0x0006, 0x0003 }, - { 0x0006, 0x0004 }, - { 0x0005, 0x0003 }, - { 0x0004, 0x0002 }, - { 0x0003, 0x0002 }, - { 0x0002, 0x0002 }, - { 0x0002, 0x0003 }, - { 0x0003, 0x0003 }, - { 0x0004, 0x0003 }, - { 0x0006, 0x0005 }, - { 0x0007, 0x0005 }, - { 0x0008, 0x0007 }, - { 0x0009, 0x0007 }, - { 0x0009, 0x0008 }, - { 0x0009, 0x0009 }, - { 0x000a, 0x0006 }, - { 0x000a, 0x0007 }, - { 0x000b, 0x0003 }, - { 0x000c, 0x0002 }, - { 0x000c, 0x0003 }, - { 0x000b, 0x0004 }, - { 0x000b, 0x0005 }, - { 0x000e, 0x0003 }, - { 0x0010, 0x0003 }, - { 0x0013, 0x0008 }, - { 0x0013, 0x0009 }, - { 0x0013, 0x000a }, - { 0x0013, 0x000b }, - { 0x0013, 0x000c }, - { 0x0013, 0x000d }, - { 0x0013, 0x000e }, - { 0x0013, 0x000f }, - { 0x0013, 0x0010 }, - { 0x0013, 0x0011 }, - { 0x0013, 0x0012 }, - { 0x0013, 0x0013 }, - { 0x0013, 0x0014 }, - { 0x0013, 0x0015 }, -}; - -const uint32_t c_aaiRMSEnvHuffDec[13][HUFF_DEC_TABLE_SIZE] = { - { - 0x0002ffff, - 0x0001ffff, - 0x0000001d, - 0x00000022, - 0x0001001e, - 0x0001001e, - 0x00010021, - 0x00010021, - 0x0002001f, - 0x0002001f, - 0x0002001f, - 0x0002001f, - 0x00020020, - 0x00020020, - 0x00020020, - 0x00020020, - }, - { - 0x0002001b, - 0x0002001b, - 0x0002001b, - 0x0002001b, - 0x00020023, - 0x00020023, - 0x00020023, - 0x00020023, - 0x0003001c, - 0x0003001c, - 0x0003001c, - 0x0003001c, - 0x0003001c, - 0x0003001c, - 0x0003001c, - 0x0003001c, - }, - { - 0x0006ffff, - 0x0007ffff, - 0x0003ffff, - 0x0004ffff, - 0x0005ffff, - 0x00000017, - 0x00000018, - 0x00000025, - 0x00010019, - 0x00010019, - 0x00010024, - 0x00010024, - 0x0002001a, - 0x0002001a, - 0x0002001a, - 0x0002001a, - }, - { - 0x00030014, - 0x00030014, - 0x00030014, - 0x00030014, - 0x00030014, - 0x00030014, - 0x00030014, - 0x00030014, - 0x00030015, - 0x00030015, - 0x00030015, - 0x00030015, - 0x00030015, - 0x00030015, - 0x00030015, - 0x00030015, - }, - { - 0x00030016, - 0x00030016, - 0x00030016, - 0x00030016, - 0x00030016, - 0x00030016, - 0x00030016, - 0x00030016, - 0x00030026, - 0x00030026, - 0x00030026, - 0x00030026, - 0x00030026, - 0x00030026, - 0x00030026, - 0x00030026, - }, - { - 0x00030027, - 0x00030027, - 0x00030027, - 0x00030027, - 0x00030027, - 0x00030027, - 0x00030027, - 0x00030027, - 0x00030028, - 0x00030028, - 0x00030028, - 0x00030028, - 0x00030028, - 0x00030028, - 0x00030028, - 0x00030028, - }, - { - 0x0009ffff, - 0x0008ffff, - 0x0000002c, - 0x0000002d, - 0x00010010, - 0x00010010, - 0x0001002b, - 0x0001002b, - 0x0001002e, - 0x0001002e, - 0x0001002f, - 0x0001002f, - 0x00020011, - 0x00020011, - 0x00020011, - 0x00020011, - }, - { - 0x00020012, - 0x00020012, - 0x00020012, - 0x00020012, - 0x00020013, - 0x00020013, - 0x00020013, - 0x00020013, - 0x00020029, - 0x00020029, - 0x00020029, - 0x00020029, - 0x0002002a, - 0x0002002a, - 0x0002002a, - 0x0002002a, - }, - { - 0x0003000c, - 0x0003000c, - 0x0003000c, - 0x0003000c, - 0x0003000c, - 0x0003000c, - 0x0003000c, - 0x0003000c, - 0x0003000f, - 0x0003000f, - 0x0003000f, - 0x0003000f, - 0x0003000f, - 0x0003000f, - 0x0003000f, - 0x0003000f, - }, - { - 0x000bffff, - 0x000cffff, - 0x000affff, - 0x00000031, - 0x0002000d, - 0x0002000d, - 0x0002000d, - 0x0002000d, - 0x0002000e, - 0x0002000e, - 0x0002000e, - 0x0002000e, - 0x00020030, - 0x00020030, - 0x00020030, - 0x00020030, - }, - { - 0x0001003a, - 0x0001003a, - 0x0001003b, - 0x0001003b, - 0x0001003c, - 0x0001003c, - 0x0001003d, - 0x0001003d, - 0x0001003e, - 0x0001003e, - 0x0001003f, - 0x0001003f, - 0x0002000b, - 0x0002000b, - 0x0002000b, - 0x0002000b, - }, - { - 0x00000000, - 0x00000001, - 0x00000002, - 0x00000003, - 0x00000004, - 0x00000005, - 0x00010006, - 0x00010006, - 0x00010007, - 0x00010007, - 0x00010008, - 0x00010008, - 0x00010009, - 0x00010009, - 0x0001000a, - 0x0001000a, - }, - { - 0x00010032, - 0x00010032, - 0x00010033, - 0x00010033, - 0x00010034, - 0x00010034, - 0x00010035, - 0x00010035, - 0x00010036, - 0x00010036, - 0x00010037, - 0x00010037, - 0x00010038, - 0x00010038, - 0x00010039, - 0x00010039, - }, -}; - -const uint16_t c_aauiLCLDHuffEnc1[16][2] = - { - { 0x0001, 0x0001 }, - { 0x0003, 0x0001 }, - { 0x0005, 0x0001 }, - { 0x000b, 0x0000 }, - { 0x0002, 0x0001 }, - { 0x0004, 0x0001 }, - { 0x0007, 0x0001 }, - { 0x000b, 0x0001 }, - { 0x0006, 0x0001 }, - { 0x0008, 0x0001 }, - { 0x000b, 0x0002 }, - { 0x000b, 0x0003 }, - { 0x000b, 0x0004 }, - { 0x000b, 0x0005 }, - { 0x000b, 0x0006 }, - { 0x000b, 0x0007 }, - }; - -const uint16_t c_aauiLCLDHuffEnc2[16][2] = - { - { 0x0001, 0x0001 }, - { 0x0003, 0x0001 }, - { 0x0005, 0x0001 }, - { 0x000c, 0x0000 }, - { 0x0002, 0x0001 }, - { 0x0004, 0x0001 }, - { 0x0007, 0x0001 }, - { 0x000c, 0x0001 }, - { 0x0006, 0x0001 }, - { 0x0008, 0x0001 }, - { 0x0009, 0x0001 }, - { 0x000c, 0x0002 }, - { 0x000c, 0x0003 }, - { 0x000c, 0x0004 }, - { 0x000c, 0x0005 }, - { 0x000b, 0x0003 }, - }; - -const uint16_t c_aauiLCLDHuffEnc3[25][2] = - { - { 0x0001, 0x0001 }, - { 0x0003, 0x0001 }, - { 0x0006, 0x0001 }, - { 0x000d, 0x0000 }, - { 0x000d, 0x0001 }, - { 0x0002, 0x0001 }, - { 0x0004, 0x0001 }, - { 0x0007, 0x0001 }, - { 0x000d, 0x0002 }, - { 0x000d, 0x0003 }, - { 0x0006, 0x0002 }, - { 0x0006, 0x0003 }, - { 0x0008, 0x0001 }, - { 0x000d, 0x0004 }, - { 0x000d, 0x0005 }, - { 0x0009, 0x0001 }, - { 0x000c, 0x0007 }, - { 0x000d, 0x0006 }, - { 0x000d, 0x0007 }, - { 0x000d, 0x0008 }, - { 0x000d, 0x0009 }, - { 0x000d, 0x000a }, - { 0x000d, 0x000b }, - { 0x000d, 0x000c }, - { 0x000d, 0x000d }, - - }; - -const uint16_t c_aauiLCLDHuffEnc4[36][2] = - { - { 0x0001, 0x0001 }, - { 0x0003, 0x0001 }, - { 0x0006, 0x0001 }, - { 0x000b, 0x0001 }, - { 0x0010, 0x0000 }, - { 0x0010, 0x0001 }, - { 0x0002, 0x0001 }, - { 0x0004, 0x0001 }, - { 0x0007, 0x0001 }, - { 0x000a, 0x0001 }, - { 0x0010, 0x0002 }, - { 0x0010, 0x0003 }, - { 0x0006, 0x0002 }, - { 0x0006, 0x0003 }, - { 0x0008, 0x0001 }, - { 0x000e, 0x0006 }, - { 0x0010, 0x0004 }, - { 0x0010, 0x0005 }, - { 0x000a, 0x0002 }, - { 0x000a, 0x0003 }, - { 0x000e, 0x0007 }, - { 0x0010, 0x0006 }, - { 0x0010, 0x0007 }, - { 0x0010, 0x0008 }, - { 0x0010, 0x0009 }, - { 0x0010, 0x000a }, - { 0x0010, 0x000b }, - { 0x0010, 0x000c }, - { 0x0010, 0x000d }, - { 0x0010, 0x000e }, - { 0x0010, 0x000f }, - { 0x0010, 0x0010 }, - { 0x0010, 0x0011 }, - { 0x000f, 0x0009 }, - { 0x000f, 0x000a }, - { 0x000f, 0x000b }, - - }; - -const uint16_t c_aauiLCLDHuffEnc5[36][2] = - { - { 0x0001, 0x0001 }, - { 0x0003, 0x0001 }, - { 0x0006, 0x0001 }, - { 0x000a, 0x0001 }, - { 0x000f, 0x0003 }, - { 0x0012, 0x0000 }, - { 0x0002, 0x0001 }, - { 0x0004, 0x0001 }, - { 0x0007, 0x0001 }, - { 0x000b, 0x0001 }, - { 0x0011, 0x0008 }, - { 0x0012, 0x0001 }, - { 0x0006, 0x0002 }, - { 0x0006, 0x0003 }, - { 0x0008, 0x0001 }, - { 0x000c, 0x0001 }, - { 0x0012, 0x0002 }, - { 0x0012, 0x0003 }, - { 0x000a, 0x0002 }, - { 0x000a, 0x0003 }, - { 0x000d, 0x0001 }, - { 0x0012, 0x0004 }, - { 0x0012, 0x0005 }, - { 0x0012, 0x0006 }, - { 0x0011, 0x0009 }, - { 0x0011, 0x000a }, - { 0x0012, 0x0007 }, - { 0x0012, 0x0008 }, - { 0x0012, 0x0009 }, - { 0x0012, 0x000a }, - { 0x0012, 0x000b }, - { 0x0012, 0x000c }, - { 0x0012, 0x000d }, - { 0x0012, 0x000e }, - { 0x0012, 0x000f }, - { 0x0011, 0x000b }, - - }; - -const uint16_t c_aauiLCLDHuffEnc6[49][2] = - { - { 0x0001, 0x0001 }, - { 0x0003, 0x0001 }, - { 0x0006, 0x0001 }, - { 0x000a, 0x0001 }, - { 0x0010, 0x0003 }, - { 0x0014, 0x0000 }, - { 0x0014, 0x0001 }, - { 0x0002, 0x0001 }, - { 0x0004, 0x0001 }, - { 0x0007, 0x0001 }, - { 0x000a, 0x0002 }, - { 0x0010, 0x0004 }, - { 0x0014, 0x0002 }, - { 0x0014, 0x0003 }, - { 0x0006, 0x0002 }, - { 0x0006, 0x0003 }, - { 0x0008, 0x0001 }, - { 0x000d, 0x0001 }, - { 0x0012, 0x0007 }, - { 0x0014, 0x0004 }, - { 0x0014, 0x0005 }, - { 0x000a, 0x0003 }, - { 0x000b, 0x0001 }, - { 0x000c, 0x0001 }, - { 0x0011, 0x0004 }, - { 0x0014, 0x0006 }, - { 0x0014, 0x0007 }, - { 0x0014, 0x0008 }, - { 0x0010, 0x0005 }, - { 0x000f, 0x0003 }, - { 0x0011, 0x0005 }, - { 0x0014, 0x0009 }, - { 0x0014, 0x000a }, - { 0x0014, 0x000b }, - { 0x0014, 0x000c }, - { 0x0014, 0x000d }, - { 0x0013, 0x000d }, - { 0x0014, 0x000e }, - { 0x0014, 0x000f }, - { 0x0014, 0x0010 }, - { 0x0014, 0x0011 }, - { 0x0014, 0x0012 }, - { 0x0014, 0x0013 }, - { 0x0014, 0x0014 }, - { 0x0014, 0x0015 }, - { 0x0014, 0x0016 }, - { 0x0014, 0x0017 }, - { 0x0014, 0x0018 }, - { 0x0014, 0x0019 }, - - }; - -const uint16_t c_aauiLCLDHuffEnc7[64][2] = - { - { 0x0002, 0x0001 }, - { 0x0002, 0x0002 }, - { 0x0005, 0x0001 }, - { 0x0009, 0x0001 }, - { 0x000f, 0x0002 }, - { 0x0015, 0x0000 }, - { 0x0015, 0x0001 }, - { 0x0015, 0x0002 }, - { 0x0002, 0x0003 }, - { 0x0003, 0x0001 }, - { 0x0006, 0x0001 }, - { 0x0009, 0x0002 }, - { 0x000f, 0x0003 }, - { 0x0014, 0x0011 }, - { 0x0015, 0x0003 }, - { 0x0015, 0x0004 }, - { 0x0005, 0x0002 }, - { 0x0005, 0x0003 }, - { 0x0007, 0x0001 }, - { 0x000b, 0x0001 }, - { 0x0010, 0x0002 }, - { 0x0015, 0x0005 }, - { 0x0015, 0x0006 }, - { 0x0015, 0x0007 }, - { 0x000a, 0x0001 }, - { 0x0009, 0x0003 }, - { 0x000c, 0x0001 }, - { 0x000f, 0x0004 }, - { 0x0012, 0x0006 }, - { 0x0015, 0x0008 }, - { 0x0015, 0x0009 }, - { 0x0015, 0x000a }, - { 0x000f, 0x0005 }, - { 0x000e, 0x0003 }, - { 0x0010, 0x0003 }, - { 0x0012, 0x0007 }, - { 0x0014, 0x0012 }, - { 0x0015, 0x000b }, - { 0x0015, 0x000c }, - { 0x0015, 0x000d }, - { 0x0014, 0x0013 }, - { 0x0014, 0x0014 }, - { 0x0013, 0x000b }, - { 0x0014, 0x0015 }, - { 0x0015, 0x000e }, - { 0x0015, 0x000f }, - { 0x0015, 0x0010 }, - { 0x0015, 0x0011 }, - { 0x0015, 0x0012 }, - { 0x0015, 0x0013 }, - { 0x0015, 0x0014 }, - { 0x0015, 0x0015 }, - { 0x0015, 0x0016 }, - { 0x0015, 0x0017 }, - { 0x0015, 0x0018 }, - { 0x0015, 0x0019 }, - { 0x0015, 0x001a }, - { 0x0015, 0x001b }, - { 0x0015, 0x001c }, - { 0x0015, 0x001d }, - { 0x0015, 0x001e }, - { 0x0015, 0x001f }, - { 0x0015, 0x0020 }, - { 0x0015, 0x0021 }, - }; - -const uint16_t c_aauiLCLDHuffEnc8[81][2] = - { - { 0x0001, 0x0001 }, - { 0x0003, 0x0001 }, - { 0x0006, 0x0001 }, - { 0x000a, 0x0001 }, - { 0x000f, 0x0002 }, - { 0x0014, 0x0008 }, - { 0x0017, 0x0000 }, - { 0x0017, 0x0001 }, - { 0x0017, 0x0002 }, - { 0x0003, 0x0002 }, - { 0x0003, 0x0003 }, - { 0x0005, 0x0001 }, - { 0x0009, 0x0001 }, - { 0x000f, 0x0003 }, - { 0x0012, 0x0004 }, - { 0x0015, 0x000d }, - { 0x0017, 0x0003 }, - { 0x0017, 0x0004 }, - { 0x0005, 0x0002 }, - { 0x0005, 0x0003 }, - { 0x0007, 0x0001 }, - { 0x000c, 0x0001 }, - { 0x0010, 0x0002 }, - { 0x0013, 0x0005 }, - { 0x0017, 0x0005 }, - { 0x0017, 0x0006 }, - { 0x0017, 0x0007 }, - { 0x0009, 0x0002 }, - { 0x0009, 0x0003 }, - { 0x000b, 0x0001 }, - { 0x000f, 0x0004 }, - { 0x0012, 0x0005 }, - { 0x0016, 0x0015 }, - { 0x0017, 0x0008 }, - { 0x0017, 0x0009 }, - { 0x0017, 0x000a }, - { 0x000f, 0x0005 }, - { 0x000e, 0x0003 }, - { 0x0010, 0x0003 }, - { 0x0012, 0x0006 }, - { 0x0014, 0x0009 }, - { 0x0017, 0x000b }, - { 0x0017, 0x000c }, - { 0x0017, 0x000d }, - { 0x0017, 0x000e }, - { 0x0013, 0x0006 }, - { 0x0012, 0x0007 }, - { 0x0013, 0x0007 }, - { 0x0015, 0x000e }, - { 0x0017, 0x000f }, - { 0x0017, 0x0010 }, - { 0x0017, 0x0011 }, - { 0x0017, 0x0012 }, - { 0x0017, 0x0013 }, - { 0x0016, 0x0016 }, - { 0x0016, 0x0017 }, - { 0x0015, 0x000f }, - { 0x0016, 0x0018 }, - { 0x0017, 0x0014 }, - { 0x0017, 0x0015 }, - { 0x0017, 0x0016 }, - { 0x0017, 0x0017 }, - { 0x0017, 0x0018 }, - { 0x0017, 0x0019 }, - { 0x0017, 0x001a }, - { 0x0017, 0x001b }, - { 0x0017, 0x001c }, - { 0x0017, 0x001d }, - { 0x0017, 0x001e }, - { 0x0017, 0x001f }, - { 0x0017, 0x0020 }, - { 0x0017, 0x0021 }, - { 0x0017, 0x0022 }, - { 0x0017, 0x0023 }, - { 0x0017, 0x0024 }, - { 0x0017, 0x0025 }, - { 0x0017, 0x0026 }, - { 0x0017, 0x0027 }, - { 0x0017, 0x0028 }, - { 0x0017, 0x0029 }, - { 0x0016, 0x0019 }, - - }; - -const uint16_t c_aauiLCLDHuffEnc9[100][2] = - { - { 0x0001, 0x0001 }, - { 0x0003, 0x0001 }, - { 0x0006, 0x0001 }, - { 0x0009, 0x0001 }, - { 0x000d, 0x0002 }, - { 0x0011, 0x0004 }, - { 0x0014, 0x000a }, - { 0x0017, 0x0000 }, - { 0x0017, 0x0001 }, - { 0x0017, 0x0002 }, - { 0x0003, 0x0002 }, - { 0x0003, 0x0003 }, - { 0x0005, 0x0001 }, - { 0x0009, 0x0002 }, - { 0x000d, 0x0003 }, - { 0x0010, 0x0004 }, - { 0x0013, 0x0007 }, - { 0x0016, 0x0018 }, - { 0x0017, 0x0003 }, - { 0x0017, 0x0004 }, - { 0x0005, 0x0002 }, - { 0x0005, 0x0003 }, - { 0x0008, 0x0002 }, - { 0x000b, 0x0002 }, - { 0x000e, 0x0002 }, - { 0x0011, 0x0005 }, - { 0x0014, 0x000b }, - { 0x0016, 0x0019 }, - { 0x0017, 0x0005 }, - { 0x0017, 0x0006 }, - { 0x0009, 0x0003 }, - { 0x0008, 0x0003 }, - { 0x000b, 0x0003 }, - { 0x000d, 0x0004 }, - { 0x0010, 0x0005 }, - { 0x0012, 0x0006 }, - { 0x0015, 0x000f }, - { 0x0017, 0x0007 }, - { 0x0017, 0x0008 }, - { 0x0017, 0x0009 }, - { 0x000d, 0x0005 }, - { 0x000c, 0x0003 }, - { 0x000e, 0x0003 }, - { 0x0010, 0x0006 }, - { 0x0012, 0x0007 }, - { 0x0014, 0x000c }, - { 0x0017, 0x000a }, - { 0x0016, 0x001a }, - { 0x0017, 0x000b }, - { 0x0017, 0x000c }, - { 0x0011, 0x0006 }, - { 0x0010, 0x0007 }, - { 0x0011, 0x0007 }, - { 0x0013, 0x0008 }, - { 0x0013, 0x0009 }, - { 0x0015, 0x0010 }, - { 0x0017, 0x000d }, - { 0x0017, 0x000e }, - { 0x0017, 0x000f }, - { 0x0017, 0x0010 }, - { 0x0013, 0x000a }, - { 0x0013, 0x000b }, - { 0x0014, 0x000d }, - { 0x0015, 0x0011 }, - { 0x0017, 0x0011 }, - { 0x0016, 0x001b }, - { 0x0017, 0x0012 }, - { 0x0017, 0x0013 }, - { 0x0017, 0x0014 }, - { 0x0017, 0x0015 }, - { 0x0017, 0x0016 }, - { 0x0015, 0x0012 }, - { 0x0015, 0x0013 }, - { 0x0017, 0x0017 }, - { 0x0016, 0x001c }, - { 0x0017, 0x0018 }, - { 0x0017, 0x0019 }, - { 0x0017, 0x001a }, - { 0x0017, 0x001b }, - { 0x0017, 0x001c }, - { 0x0017, 0x001d }, - { 0x0017, 0x001e }, - { 0x0017, 0x001f }, - { 0x0017, 0x0020 }, - { 0x0017, 0x0021 }, - { 0x0017, 0x0022 }, - { 0x0017, 0x0023 }, - { 0x0017, 0x0024 }, - { 0x0017, 0x0025 }, - { 0x0017, 0x0026 }, - { 0x0017, 0x0027 }, - { 0x0017, 0x0028 }, - { 0x0017, 0x0029 }, - { 0x0017, 0x002a }, - { 0x0017, 0x002b }, - { 0x0017, 0x002c }, - { 0x0017, 0x002d }, - { 0x0017, 0x002e }, - { 0x0017, 0x002f }, - { 0x0016, 0x001d }, - - }; - -const uint16_t c_aauiLCLDHuffEnc10[169][2] = - { - { 0x0001, 0x0001 }, - { 0x0004, 0x0002 }, - { 0x0005, 0x0002 }, - { 0x0007, 0x0002 }, - { 0x000a, 0x0002 }, - { 0x000e, 0x0004 }, - { 0x0011, 0x0007 }, - { 0x0013, 0x0012 }, - { 0x0016, 0x0000 }, - { 0x0016, 0x0001 }, - { 0x0016, 0x0002 }, - { 0x0016, 0x0003 }, - { 0x0016, 0x0004 }, - { 0x0004, 0x0003 }, - { 0x0003, 0x0003 }, - { 0x0004, 0x0004 }, - { 0x0007, 0x0003 }, - { 0x000a, 0x0003 }, - { 0x000d, 0x0004 }, - { 0x0010, 0x0007 }, - { 0x0013, 0x0013 }, - { 0x0015, 0x0035 }, - { 0x0016, 0x0005 }, - { 0x0016, 0x0006 }, - { 0x0016, 0x0007 }, - { 0x0016, 0x0008 }, - { 0x0005, 0x0003 }, - { 0x0004, 0x0005 }, - { 0x0006, 0x0003 }, - { 0x0008, 0x0002 }, - { 0x000b, 0x0002 }, - { 0x000e, 0x0005 }, - { 0x0010, 0x0008 }, - { 0x0013, 0x0014 }, - { 0x0014, 0x001d }, - { 0x0016, 0x0009 }, - { 0x0016, 0x000a }, - { 0x0016, 0x000b }, - { 0x0016, 0x000c }, - { 0x0007, 0x0004 }, - { 0x0007, 0x0005 }, - { 0x0008, 0x0003 }, - { 0x000a, 0x0004 }, - { 0x000d, 0x0005 }, - { 0x000f, 0x0005 }, - { 0x0011, 0x0008 }, - { 0x0014, 0x001e }, - { 0x0014, 0x001f }, - { 0x0016, 0x000d }, - { 0x0016, 0x000e }, - { 0x0016, 0x000f }, - { 0x0016, 0x0010 }, - { 0x000a, 0x0005 }, - { 0x0009, 0x0003 }, - { 0x000b, 0x0003 }, - { 0x000d, 0x0006 }, - { 0x000f, 0x0006 }, - { 0x0011, 0x0009 }, - { 0x0013, 0x0015 }, - { 0x0014, 0x0020 }, - { 0x0016, 0x0011 }, - { 0x0016, 0x0012 }, - { 0x0016, 0x0013 }, - { 0x0016, 0x0014 }, - { 0x0016, 0x0015 }, - { 0x000e, 0x0006 }, - { 0x000d, 0x0007 }, - { 0x000e, 0x0007 }, - { 0x000f, 0x0007 }, - { 0x0011, 0x000a }, - { 0x0012, 0x000c }, - { 0x0016, 0x0016 }, - { 0x0016, 0x0017 }, - { 0x0016, 0x0018 }, - { 0x0016, 0x0019 }, - { 0x0016, 0x001a }, - { 0x0016, 0x001b }, - { 0x0016, 0x001c }, - { 0x0011, 0x000b }, - { 0x0010, 0x0009 }, - { 0x0011, 0x000c }, - { 0x0011, 0x000d }, - { 0x0013, 0x0016 }, - { 0x0016, 0x001d }, - { 0x0016, 0x001e }, - { 0x0016, 0x001f }, - { 0x0016, 0x0020 }, - { 0x0016, 0x0021 }, - { 0x0016, 0x0022 }, - { 0x0016, 0x0023 }, - { 0x0016, 0x0024 }, - { 0x0014, 0x0021 }, - { 0x0014, 0x0022 }, - { 0x0012, 0x000d }, - { 0x0013, 0x0017 }, - { 0x0016, 0x0025 }, - { 0x0016, 0x0026 }, - { 0x0016, 0x0027 }, - { 0x0016, 0x0028 }, - { 0x0016, 0x0029 }, - { 0x0016, 0x002a }, - { 0x0016, 0x002b }, - { 0x0016, 0x002c }, - { 0x0016, 0x002d }, - { 0x0015, 0x0036 }, - { 0x0015, 0x0037 }, - { 0x0014, 0x0023 }, - { 0x0015, 0x0038 }, - { 0x0016, 0x002e }, - { 0x0016, 0x002f }, - { 0x0016, 0x0030 }, - { 0x0016, 0x0031 }, - { 0x0016, 0x0032 }, - { 0x0016, 0x0033 }, - { 0x0016, 0x0034 }, - { 0x0016, 0x0035 }, - { 0x0016, 0x0036 }, - { 0x0016, 0x0037 }, - { 0x0016, 0x0038 }, - { 0x0016, 0x0039 }, - { 0x0016, 0x003a }, - { 0x0016, 0x003b }, - { 0x0016, 0x003c }, - { 0x0016, 0x003d }, - { 0x0016, 0x003e }, - { 0x0016, 0x003f }, - { 0x0016, 0x0040 }, - { 0x0016, 0x0041 }, - { 0x0016, 0x0042 }, - { 0x0016, 0x0043 }, - { 0x0016, 0x0044 }, - { 0x0016, 0x0045 }, - { 0x0016, 0x0046 }, - { 0x0016, 0x0047 }, - { 0x0016, 0x0048 }, - { 0x0016, 0x0049 }, - { 0x0016, 0x004a }, - { 0x0016, 0x004b }, - { 0x0016, 0x004c }, - { 0x0016, 0x004d }, - { 0x0016, 0x004e }, - { 0x0016, 0x004f }, - { 0x0016, 0x0050 }, - { 0x0016, 0x0051 }, - { 0x0016, 0x0052 }, - { 0x0016, 0x0053 }, - { 0x0016, 0x0054 }, - { 0x0016, 0x0055 }, - { 0x0016, 0x0056 }, - { 0x0016, 0x0057 }, - { 0x0016, 0x0058 }, - { 0x0016, 0x0059 }, - { 0x0016, 0x005a }, - { 0x0016, 0x005b }, - { 0x0016, 0x005c }, - { 0x0016, 0x005d }, - { 0x0016, 0x005e }, - { 0x0016, 0x005f }, - { 0x0016, 0x0060 }, - { 0x0016, 0x0061 }, - { 0x0016, 0x0062 }, - { 0x0016, 0x0063 }, - { 0x0016, 0x0064 }, - { 0x0016, 0x0065 }, - { 0x0016, 0x0066 }, - { 0x0016, 0x0067 }, - { 0x0016, 0x0068 }, - { 0x0016, 0x0069 }, - { 0x0015, 0x0039 }, - - }; - -const uint16_t c_aauiLCLDHuffEnc11[196][2] = - { - { 0x0001, 0x0001 }, - { 0x0004, 0x0003 }, - { 0x0005, 0x0003 }, - { 0x0007, 0x0002 }, - { 0x0009, 0x0003 }, - { 0x000c, 0x0004 }, - { 0x000f, 0x0005 }, - { 0x0012, 0x000d }, - { 0x0014, 0x001f }, - { 0x0016, 0x0000 }, - { 0x0016, 0x0001 }, - { 0x0016, 0x0002 }, - { 0x0016, 0x0003 }, - { 0x0016, 0x0004 }, - { 0x0004, 0x0004 }, - { 0x0003, 0x0003 }, - { 0x0005, 0x0004 }, - { 0x0006, 0x0003 }, - { 0x0009, 0x0004 }, - { 0x000b, 0x0004 }, - { 0x000e, 0x0005 }, - { 0x0010, 0x0007 }, - { 0x0012, 0x000e }, - { 0x0014, 0x0020 }, - { 0x0016, 0x0005 }, - { 0x0016, 0x0006 }, - { 0x0016, 0x0007 }, - { 0x0016, 0x0008 }, - { 0x0005, 0x0005 }, - { 0x0004, 0x0005 }, - { 0x0006, 0x0004 }, - { 0x0007, 0x0003 }, - { 0x000a, 0x0004 }, - { 0x000c, 0x0005 }, - { 0x000e, 0x0006 }, - { 0x0011, 0x000a }, - { 0x0012, 0x000f }, - { 0x0015, 0x003b }, - { 0x0016, 0x0009 }, - { 0x0016, 0x000a }, - { 0x0016, 0x000b }, - { 0x0016, 0x000c }, - { 0x0007, 0x0004 }, - { 0x0006, 0x0005 }, - { 0x0007, 0x0005 }, - { 0x0009, 0x0005 }, - { 0x000b, 0x0005 }, - { 0x000d, 0x0005 }, - { 0x000f, 0x0006 }, - { 0x0012, 0x0010 }, - { 0x0014, 0x0021 }, - { 0x0016, 0x000d }, - { 0x0016, 0x000e }, - { 0x0016, 0x000f }, - { 0x0016, 0x0010 }, - { 0x0016, 0x0011 }, - { 0x0009, 0x0006 }, - { 0x0009, 0x0007 }, - { 0x000a, 0x0005 }, - { 0x000b, 0x0006 }, - { 0x000d, 0x0006 }, - { 0x000f, 0x0007 }, - { 0x0011, 0x000b }, - { 0x0013, 0x0017 }, - { 0x0014, 0x0022 }, - { 0x0016, 0x0012 }, - { 0x0016, 0x0013 }, - { 0x0016, 0x0014 }, - { 0x0016, 0x0015 }, - { 0x0016, 0x0016 }, - { 0x000c, 0x0006 }, - { 0x000b, 0x0007 }, - { 0x000c, 0x0007 }, - { 0x000d, 0x0007 }, - { 0x000e, 0x0007 }, - { 0x0010, 0x0008 }, - { 0x0012, 0x0011 }, - { 0x0014, 0x0023 }, - { 0x0015, 0x003c }, - { 0x0016, 0x0017 }, - { 0x0016, 0x0018 }, - { 0x0016, 0x0019 }, - { 0x0016, 0x001a }, - { 0x0016, 0x001b }, - { 0x000f, 0x0008 }, - { 0x000e, 0x0008 }, - { 0x000e, 0x0009 }, - { 0x000f, 0x0009 }, - { 0x0011, 0x000c }, - { 0x0013, 0x0018 }, - { 0x0014, 0x0024 }, - { 0x0016, 0x001c }, - { 0x0016, 0x001d }, - { 0x0016, 0x001e }, - { 0x0016, 0x001f }, - { 0x0016, 0x0020 }, - { 0x0016, 0x0021 }, - { 0x0016, 0x0022 }, - { 0x0011, 0x000d }, - { 0x0010, 0x0009 }, - { 0x0012, 0x0012 }, - { 0x0012, 0x0013 }, - { 0x0014, 0x0025 }, - { 0x0015, 0x003d }, - { 0x0014, 0x0026 }, - { 0x0016, 0x0023 }, - { 0x0016, 0x0024 }, - { 0x0016, 0x0025 }, - { 0x0016, 0x0026 }, - { 0x0016, 0x0027 }, - { 0x0016, 0x0028 }, - { 0x0016, 0x0029 }, - { 0x0014, 0x0027 }, - { 0x0013, 0x0019 }, - { 0x0014, 0x0028 }, - { 0x0014, 0x0029 }, - { 0x0014, 0x002a }, - { 0x0016, 0x002a }, - { 0x0016, 0x002b }, - { 0x0016, 0x002c }, - { 0x0016, 0x002d }, - { 0x0016, 0x002e }, - { 0x0016, 0x002f }, - { 0x0016, 0x0030 }, - { 0x0016, 0x0031 }, - { 0x0016, 0x0032 }, - { 0x0014, 0x002b }, - { 0x0014, 0x002c }, - { 0x0014, 0x002d }, - { 0x0016, 0x0033 }, - { 0x0016, 0x0034 }, - { 0x0016, 0x0035 }, - { 0x0016, 0x0036 }, - { 0x0016, 0x0037 }, - { 0x0016, 0x0038 }, - { 0x0016, 0x0039 }, - { 0x0016, 0x003a }, - { 0x0016, 0x003b }, - { 0x0016, 0x003c }, - { 0x0016, 0x003d }, - { 0x0016, 0x003e }, - { 0x0016, 0x003f }, - { 0x0016, 0x0040 }, - { 0x0016, 0x0041 }, - { 0x0016, 0x0042 }, - { 0x0016, 0x0043 }, - { 0x0016, 0x0044 }, - { 0x0016, 0x0045 }, - { 0x0016, 0x0046 }, - { 0x0016, 0x0047 }, - { 0x0016, 0x0048 }, - { 0x0016, 0x0049 }, - { 0x0016, 0x004a }, - { 0x0016, 0x004b }, - { 0x0016, 0x004c }, - { 0x0016, 0x004d }, - { 0x0016, 0x004e }, - { 0x0016, 0x004f }, - { 0x0016, 0x0050 }, - { 0x0016, 0x0051 }, - { 0x0016, 0x0052 }, - { 0x0016, 0x0053 }, - { 0x0016, 0x0054 }, - { 0x0016, 0x0055 }, - { 0x0016, 0x0056 }, - { 0x0016, 0x0057 }, - { 0x0016, 0x0058 }, - { 0x0016, 0x0059 }, - { 0x0016, 0x005a }, - { 0x0016, 0x005b }, - { 0x0016, 0x005c }, - { 0x0016, 0x005d }, - { 0x0016, 0x005e }, - { 0x0016, 0x005f }, - { 0x0016, 0x0060 }, - { 0x0016, 0x0061 }, - { 0x0016, 0x0062 }, - { 0x0016, 0x0063 }, - { 0x0016, 0x0064 }, - { 0x0016, 0x0065 }, - { 0x0016, 0x0066 }, - { 0x0016, 0x0067 }, - { 0x0016, 0x0068 }, - { 0x0016, 0x0069 }, - { 0x0016, 0x006a }, - { 0x0016, 0x006b }, - { 0x0016, 0x006c }, - { 0x0016, 0x006d }, - { 0x0016, 0x006e }, - { 0x0016, 0x006f }, - { 0x0016, 0x0070 }, - { 0x0016, 0x0071 }, - { 0x0016, 0x0072 }, - { 0x0016, 0x0073 }, - { 0x0016, 0x0074 }, - { 0x0016, 0x0075 }, - - }; - -const uint16_t c_aauiLCLDHuffEnc12[289][2] = - { - { 0x0001, 0x0001 }, - { 0x0004, 0x0004 }, - { 0x0005, 0x0004 }, - { 0x0007, 0x0004 }, - { 0x0008, 0x0002 }, - { 0x000b, 0x0004 }, - { 0x000e, 0x0006 }, - { 0x0010, 0x0009 }, - { 0x0012, 0x0014 }, - { 0x0013, 0x001f }, - { 0x0016, 0x0000 }, - { 0x0016, 0x0001 }, - { 0x0016, 0x0002 }, - { 0x0016, 0x0003 }, - { 0x0016, 0x0004 }, - { 0x0016, 0x0005 }, - { 0x0016, 0x0006 }, - { 0x0004, 0x0005 }, - { 0x0004, 0x0006 }, - { 0x0005, 0x0005 }, - { 0x0006, 0x0003 }, - { 0x0008, 0x0003 }, - { 0x000a, 0x0004 }, - { 0x000d, 0x0006 }, - { 0x000f, 0x0008 }, - { 0x0011, 0x000c }, - { 0x0013, 0x0020 }, - { 0x0016, 0x0007 }, - { 0x0015, 0x0063 }, - { 0x0016, 0x0008 }, - { 0x0016, 0x0009 }, - { 0x0016, 0x000a }, - { 0x0016, 0x000b }, - { 0x0016, 0x000c }, - { 0x0005, 0x0006 }, - { 0x0004, 0x0007 }, - { 0x0005, 0x0007 }, - { 0x0006, 0x0004 }, - { 0x0008, 0x0004 }, - { 0x000b, 0x0005 }, - { 0x000d, 0x0007 }, - { 0x0010, 0x000a }, - { 0x0012, 0x0015 }, - { 0x0015, 0x0064 }, - { 0x0016, 0x000d }, - { 0x0016, 0x000e }, - { 0x0016, 0x000f }, - { 0x0016, 0x0010 }, - { 0x0016, 0x0011 }, - { 0x0016, 0x0012 }, - { 0x0016, 0x0013 }, - { 0x0006, 0x0005 }, - { 0x0006, 0x0006 }, - { 0x0006, 0x0007 }, - { 0x0008, 0x0005 }, - { 0x000a, 0x0005 }, - { 0x000c, 0x0005 }, - { 0x000e, 0x0007 }, - { 0x0010, 0x000b }, - { 0x0012, 0x0016 }, - { 0x0014, 0x0037 }, - { 0x0015, 0x0065 }, - { 0x0016, 0x0014 }, - { 0x0016, 0x0015 }, - { 0x0016, 0x0016 }, - { 0x0016, 0x0017 }, - { 0x0016, 0x0018 }, - { 0x0016, 0x0019 }, - { 0x0008, 0x0006 }, - { 0x0007, 0x0005 }, - { 0x0008, 0x0007 }, - { 0x000a, 0x0006 }, - { 0x000c, 0x0006 }, - { 0x000e, 0x0008 }, - { 0x0010, 0x000c }, - { 0x0011, 0x000d }, - { 0x0013, 0x0021 }, - { 0x0015, 0x0066 }, - { 0x0016, 0x001a }, - { 0x0016, 0x001b }, - { 0x0016, 0x001c }, - { 0x0016, 0x001d }, - { 0x0016, 0x001e }, - { 0x0016, 0x001f }, - { 0x0016, 0x0020 }, - { 0x000b, 0x0006 }, - { 0x000a, 0x0007 }, - { 0x000b, 0x0007 }, - { 0x000c, 0x0007 }, - { 0x000e, 0x0009 }, - { 0x000f, 0x0009 }, - { 0x0011, 0x000e }, - { 0x0013, 0x0022 }, - { 0x0015, 0x0067 }, - { 0x0015, 0x0068 }, - { 0x0016, 0x0021 }, - { 0x0016, 0x0022 }, - { 0x0016, 0x0023 }, - { 0x0016, 0x0024 }, - { 0x0016, 0x0025 }, - { 0x0016, 0x0026 }, - { 0x0016, 0x0027 }, - { 0x000e, 0x000a }, - { 0x000d, 0x0008 }, - { 0x000d, 0x0009 }, - { 0x000e, 0x000b }, - { 0x000f, 0x000a }, - { 0x0011, 0x000f }, - { 0x0013, 0x0023 }, - { 0x0014, 0x0038 }, - { 0x0016, 0x0028 }, - { 0x0016, 0x0029 }, - { 0x0016, 0x002a }, - { 0x0016, 0x002b }, - { 0x0016, 0x002c }, - { 0x0016, 0x002d }, - { 0x0016, 0x002e }, - { 0x0016, 0x002f }, - { 0x0016, 0x0030 }, - { 0x0010, 0x000d }, - { 0x000f, 0x000b }, - { 0x0010, 0x000e }, - { 0x0010, 0x000f }, - { 0x0012, 0x0017 }, - { 0x0013, 0x0024 }, - { 0x0014, 0x0039 }, - { 0x0016, 0x0031 }, - { 0x0016, 0x0032 }, - { 0x0016, 0x0033 }, - { 0x0016, 0x0034 }, - { 0x0016, 0x0035 }, - { 0x0016, 0x0036 }, - { 0x0016, 0x0037 }, - { 0x0016, 0x0038 }, - { 0x0016, 0x0039 }, - { 0x0016, 0x003a }, - { 0x0013, 0x0025 }, - { 0x0011, 0x0010 }, - { 0x0011, 0x0011 }, - { 0x0013, 0x0026 }, - { 0x0013, 0x0027 }, - { 0x0014, 0x003a }, - { 0x0014, 0x003b }, - { 0x0016, 0x003b }, - { 0x0016, 0x003c }, - { 0x0016, 0x003d }, - { 0x0016, 0x003e }, - { 0x0016, 0x003f }, - { 0x0016, 0x0040 }, - { 0x0016, 0x0041 }, - { 0x0016, 0x0042 }, - { 0x0016, 0x0043 }, - { 0x0016, 0x0044 }, - { 0x0015, 0x0069 }, - { 0x0014, 0x003c }, - { 0x0014, 0x003d }, - { 0x0015, 0x006a }, - { 0x0015, 0x006b }, - { 0x0015, 0x006c }, - { 0x0016, 0x0045 }, - { 0x0016, 0x0046 }, - { 0x0016, 0x0047 }, - { 0x0016, 0x0048 }, - { 0x0016, 0x0049 }, - { 0x0016, 0x004a }, - { 0x0016, 0x004b }, - { 0x0016, 0x004c }, - { 0x0016, 0x004d }, - { 0x0016, 0x004e }, - { 0x0016, 0x004f }, - { 0x0016, 0x0050 }, - { 0x0016, 0x0051 }, - { 0x0015, 0x006d }, - { 0x0016, 0x0052 }, - { 0x0016, 0x0053 }, - { 0x0016, 0x0054 }, - { 0x0016, 0x0055 }, - { 0x0016, 0x0056 }, - { 0x0016, 0x0057 }, - { 0x0016, 0x0058 }, - { 0x0016, 0x0059 }, - { 0x0016, 0x005a }, - { 0x0016, 0x005b }, - { 0x0016, 0x005c }, - { 0x0016, 0x005d }, - { 0x0016, 0x005e }, - { 0x0016, 0x005f }, - { 0x0016, 0x0060 }, - { 0x0016, 0x0061 }, - { 0x0016, 0x0062 }, - { 0x0016, 0x0063 }, - { 0x0016, 0x0064 }, - { 0x0016, 0x0065 }, - { 0x0016, 0x0066 }, - { 0x0016, 0x0067 }, - { 0x0016, 0x0068 }, - { 0x0016, 0x0069 }, - { 0x0016, 0x006a }, - { 0x0016, 0x006b }, - { 0x0016, 0x006c }, - { 0x0016, 0x006d }, - { 0x0016, 0x006e }, - { 0x0016, 0x006f }, - { 0x0016, 0x0070 }, - { 0x0016, 0x0071 }, - { 0x0016, 0x0072 }, - { 0x0016, 0x0073 }, - { 0x0016, 0x0074 }, - { 0x0016, 0x0075 }, - { 0x0016, 0x0076 }, - { 0x0016, 0x0077 }, - { 0x0016, 0x0078 }, - { 0x0016, 0x0079 }, - { 0x0016, 0x007a }, - { 0x0016, 0x007b }, - { 0x0016, 0x007c }, - { 0x0016, 0x007d }, - { 0x0016, 0x007e }, - { 0x0016, 0x007f }, - { 0x0016, 0x0080 }, - { 0x0016, 0x0081 }, - { 0x0016, 0x0082 }, - { 0x0016, 0x0083 }, - { 0x0016, 0x0084 }, - { 0x0016, 0x0085 }, - { 0x0016, 0x0086 }, - { 0x0016, 0x0087 }, - { 0x0016, 0x0088 }, - { 0x0016, 0x0089 }, - { 0x0016, 0x008a }, - { 0x0016, 0x008b }, - { 0x0016, 0x008c }, - { 0x0016, 0x008d }, - { 0x0016, 0x008e }, - { 0x0016, 0x008f }, - { 0x0016, 0x0090 }, - { 0x0016, 0x0091 }, - { 0x0016, 0x0092 }, - { 0x0016, 0x0093 }, - { 0x0016, 0x0094 }, - { 0x0016, 0x0095 }, - { 0x0016, 0x0096 }, - { 0x0016, 0x0097 }, - { 0x0016, 0x0098 }, - { 0x0016, 0x0099 }, - { 0x0016, 0x009a }, - { 0x0016, 0x009b }, - { 0x0016, 0x009c }, - { 0x0016, 0x009d }, - { 0x0016, 0x009e }, - { 0x0016, 0x009f }, - { 0x0016, 0x00a0 }, - { 0x0016, 0x00a1 }, - { 0x0016, 0x00a2 }, - { 0x0016, 0x00a3 }, - { 0x0016, 0x00a4 }, - { 0x0016, 0x00a5 }, - { 0x0016, 0x00a6 }, - { 0x0016, 0x00a7 }, - { 0x0016, 0x00a8 }, - { 0x0016, 0x00a9 }, - { 0x0016, 0x00aa }, - { 0x0016, 0x00ab }, - { 0x0016, 0x00ac }, - { 0x0016, 0x00ad }, - { 0x0016, 0x00ae }, - { 0x0016, 0x00af }, - { 0x0016, 0x00b0 }, - { 0x0016, 0x00b1 }, - { 0x0016, 0x00b2 }, - { 0x0016, 0x00b3 }, - { 0x0016, 0x00b4 }, - { 0x0016, 0x00b5 }, - { 0x0016, 0x00b6 }, - { 0x0016, 0x00b7 }, - { 0x0016, 0x00b8 }, - { 0x0016, 0x00b9 }, - { 0x0016, 0x00ba }, - { 0x0016, 0x00bb }, - { 0x0016, 0x00bc }, - { 0x0016, 0x00bd }, - { 0x0016, 0x00be }, - { 0x0016, 0x00bf }, - { 0x0016, 0x00c0 }, - { 0x0016, 0x00c1 }, - { 0x0016, 0x00c2 }, - { 0x0016, 0x00c3 }, - { 0x0016, 0x00c4 }, - { 0x0016, 0x00c5 }, - - }; - -const uint16_t c_aauiLCLDHuffEnc13[324][2] = - { - { 0x0004, 0x0006 }, - { 0x0004, 0x0007 }, - { 0x0005, 0x0005 }, - { 0x0005, 0x0006 }, - { 0x0006, 0x0004 }, - { 0x0008, 0x0005 }, - { 0x000a, 0x0005 }, - { 0x000c, 0x0007 }, - { 0x000e, 0x000b }, - { 0x0010, 0x0011 }, - { 0x0012, 0x002d }, - { 0x0015, 0x0000 }, - { 0x0014, 0x0035 }, - { 0x0015, 0x0001 }, - { 0x0015, 0x0002 }, - { 0x0015, 0x0003 }, - { 0x0015, 0x0004 }, - { 0x0015, 0x0005 }, - { 0x0004, 0x0008 }, - { 0x0003, 0x0007 }, - { 0x0004, 0x0009 }, - { 0x0004, 0x000a }, - { 0x0006, 0x0005 }, - { 0x0008, 0x0006 }, - { 0x0009, 0x0006 }, - { 0x000c, 0x0008 }, - { 0x000d, 0x0009 }, - { 0x0010, 0x0012 }, - { 0x0011, 0x001a }, - { 0x0015, 0x0006 }, - { 0x0015, 0x0007 }, - { 0x0015, 0x0008 }, - { 0x0015, 0x0009 }, - { 0x0015, 0x000a }, - { 0x0015, 0x000b }, - { 0x0015, 0x000c }, - { 0x0005, 0x0007 }, - { 0x0004, 0x000b }, - { 0x0004, 0x000c }, - { 0x0005, 0x0008 }, - { 0x0006, 0x0006 }, - { 0x0008, 0x0007 }, - { 0x000a, 0x0006 }, - { 0x000c, 0x0009 }, - { 0x000e, 0x000c }, - { 0x0010, 0x0013 }, - { 0x0012, 0x002e }, - { 0x0015, 0x000d }, - { 0x0015, 0x000e }, - { 0x0015, 0x000f }, - { 0x0015, 0x0010 }, - { 0x0015, 0x0011 }, - { 0x0015, 0x0012 }, - { 0x0015, 0x0013 }, - { 0x0005, 0x0009 }, - { 0x0004, 0x000d }, - { 0x0005, 0x000a }, - { 0x0006, 0x0007 }, - { 0x0007, 0x0005 }, - { 0x0009, 0x0007 }, - { 0x000b, 0x0008 }, - { 0x000d, 0x000a }, - { 0x000f, 0x000e }, - { 0x0010, 0x0014 }, - { 0x0011, 0x001b }, - { 0x0014, 0x0036 }, - { 0x0015, 0x0014 }, - { 0x0015, 0x0015 }, - { 0x0015, 0x0016 }, - { 0x0015, 0x0017 }, - { 0x0015, 0x0018 }, - { 0x0015, 0x0019 }, - { 0x0006, 0x0008 }, - { 0x0005, 0x000b }, - { 0x0006, 0x0009 }, - { 0x0007, 0x0006 }, - { 0x0009, 0x0008 }, - { 0x000a, 0x0007 }, - { 0x000c, 0x000a }, - { 0x000e, 0x000d }, - { 0x0010, 0x0015 }, - { 0x0011, 0x001c }, - { 0x0013, 0x0053 }, - { 0x0015, 0x001a }, - { 0x0015, 0x001b }, - { 0x0015, 0x001c }, - { 0x0015, 0x001d }, - { 0x0015, 0x001e }, - { 0x0015, 0x001f }, - { 0x0015, 0x0020 }, - { 0x0008, 0x0008 }, - { 0x0007, 0x0007 }, - { 0x0008, 0x0009 }, - { 0x0009, 0x0009 }, - { 0x000a, 0x0008 }, - { 0x000c, 0x000b }, - { 0x000d, 0x000b }, - { 0x000f, 0x000f }, - { 0x0010, 0x0016 }, - { 0x0011, 0x001d }, - { 0x0014, 0x0037 }, - { 0x0015, 0x0021 }, - { 0x0015, 0x0022 }, - { 0x0015, 0x0023 }, - { 0x0015, 0x0024 }, - { 0x0015, 0x0025 }, - { 0x0015, 0x0026 }, - { 0x0015, 0x0027 }, - { 0x000a, 0x0009 }, - { 0x000a, 0x000a }, - { 0x000a, 0x000b }, - { 0x000b, 0x0009 }, - { 0x000c, 0x000c }, - { 0x000d, 0x000c }, - { 0x000f, 0x0010 }, - { 0x0010, 0x0017 }, - { 0x0012, 0x002f }, - { 0x0015, 0x0028 }, - { 0x0015, 0x0029 }, - { 0x0015, 0x002a }, - { 0x0015, 0x002b }, - { 0x0015, 0x002c }, - { 0x0015, 0x002d }, - { 0x0015, 0x002e }, - { 0x0015, 0x002f }, - { 0x0015, 0x0030 }, - { 0x000c, 0x000d }, - { 0x000c, 0x000e }, - { 0x000c, 0x000f }, - { 0x000d, 0x000d }, - { 0x000e, 0x000e }, - { 0x000f, 0x0011 }, - { 0x0010, 0x0018 }, - { 0x0011, 0x001e }, - { 0x0014, 0x0038 }, - { 0x0015, 0x0031 }, - { 0x0015, 0x0032 }, - { 0x0015, 0x0033 }, - { 0x0015, 0x0034 }, - { 0x0015, 0x0035 }, - { 0x0015, 0x0036 }, - { 0x0015, 0x0037 }, - { 0x0015, 0x0038 }, - { 0x0015, 0x0039 }, - { 0x000f, 0x0012 }, - { 0x000e, 0x000f }, - { 0x000e, 0x0010 }, - { 0x000e, 0x0011 }, - { 0x000f, 0x0013 }, - { 0x0010, 0x0019 }, - { 0x0011, 0x001f }, - { 0x0013, 0x0054 }, - { 0x0015, 0x003a }, - { 0x0014, 0x0039 }, - { 0x0015, 0x003b }, - { 0x0015, 0x003c }, - { 0x0015, 0x003d }, - { 0x0015, 0x003e }, - { 0x0015, 0x003f }, - { 0x0015, 0x0040 }, - { 0x0015, 0x0041 }, - { 0x0015, 0x0042 }, - { 0x0010, 0x001a }, - { 0x000f, 0x0014 }, - { 0x000f, 0x0015 }, - { 0x0010, 0x001b }, - { 0x0011, 0x0020 }, - { 0x0012, 0x0030 }, - { 0x0013, 0x0055 }, - { 0x0015, 0x0043 }, - { 0x0015, 0x0044 }, - { 0x0014, 0x003a }, - { 0x0015, 0x0045 }, - { 0x0015, 0x0046 }, - { 0x0015, 0x0047 }, - { 0x0015, 0x0048 }, - { 0x0015, 0x0049 }, - { 0x0015, 0x004a }, - { 0x0015, 0x004b }, - { 0x0015, 0x004c }, - { 0x0012, 0x0031 }, - { 0x0011, 0x0021 }, - { 0x0013, 0x0056 }, - { 0x0013, 0x0057 }, - { 0x0012, 0x0032 }, - { 0x0015, 0x004d }, - { 0x0015, 0x004e }, - { 0x0015, 0x004f }, - { 0x0015, 0x0050 }, - { 0x0015, 0x0051 }, - { 0x0015, 0x0052 }, - { 0x0015, 0x0053 }, - { 0x0015, 0x0054 }, - { 0x0015, 0x0055 }, - { 0x0015, 0x0056 }, - { 0x0015, 0x0057 }, - { 0x0015, 0x0058 }, - { 0x0015, 0x0059 }, - { 0x0015, 0x005a }, - { 0x0014, 0x003b }, - { 0x0012, 0x0033 }, - { 0x0013, 0x0058 }, - { 0x0013, 0x0059 }, - { 0x0015, 0x005b }, - { 0x0015, 0x005c }, - { 0x0015, 0x005d }, - { 0x0015, 0x005e }, - { 0x0015, 0x005f }, - { 0x0015, 0x0060 }, - { 0x0015, 0x0061 }, - { 0x0015, 0x0062 }, - { 0x0015, 0x0063 }, - { 0x0015, 0x0064 }, - { 0x0015, 0x0065 }, - { 0x0015, 0x0066 }, - { 0x0015, 0x0067 }, - { 0x0015, 0x0068 }, - { 0x0015, 0x0069 }, - { 0x0014, 0x003c }, - { 0x0014, 0x003d }, - { 0x0014, 0x003e }, - { 0x0014, 0x003f }, - { 0x0014, 0x0040 }, - { 0x0014, 0x0041 }, - { 0x0014, 0x0042 }, - { 0x0014, 0x0043 }, - { 0x0014, 0x0044 }, - { 0x0014, 0x0045 }, - { 0x0014, 0x0046 }, - { 0x0014, 0x0047 }, - { 0x0014, 0x0048 }, - { 0x0014, 0x0049 }, - { 0x0014, 0x004a }, - { 0x0014, 0x004b }, - { 0x0014, 0x004c }, - { 0x0014, 0x004d }, - { 0x0014, 0x004e }, - { 0x0014, 0x004f }, - { 0x0014, 0x0050 }, - { 0x0014, 0x0051 }, - { 0x0014, 0x0052 }, - { 0x0014, 0x0053 }, - { 0x0014, 0x0054 }, - { 0x0014, 0x0055 }, - { 0x0014, 0x0056 }, - { 0x0014, 0x0057 }, - { 0x0014, 0x0058 }, - { 0x0014, 0x0059 }, - { 0x0014, 0x005a }, - { 0x0014, 0x005b }, - { 0x0014, 0x005c }, - { 0x0014, 0x005d }, - { 0x0014, 0x005e }, - { 0x0014, 0x005f }, - { 0x0014, 0x0060 }, - { 0x0014, 0x0061 }, - { 0x0014, 0x0062 }, - { 0x0014, 0x0063 }, - { 0x0014, 0x0064 }, - { 0x0014, 0x0065 }, - { 0x0014, 0x0066 }, - { 0x0014, 0x0067 }, - { 0x0014, 0x0068 }, - { 0x0014, 0x0069 }, - { 0x0014, 0x006a }, - { 0x0014, 0x006b }, - { 0x0014, 0x006c }, - { 0x0014, 0x006d }, - { 0x0014, 0x006e }, - { 0x0014, 0x006f }, - { 0x0014, 0x0070 }, - { 0x0014, 0x0071 }, - { 0x0014, 0x0072 }, - { 0x0014, 0x0073 }, - { 0x0014, 0x0074 }, - { 0x0014, 0x0075 }, - { 0x0014, 0x0076 }, - { 0x0014, 0x0077 }, - { 0x0014, 0x0078 }, - { 0x0014, 0x0079 }, - { 0x0014, 0x007a }, - { 0x0014, 0x007b }, - { 0x0014, 0x007c }, - { 0x0014, 0x007d }, - { 0x0014, 0x007e }, - { 0x0014, 0x007f }, - { 0x0014, 0x0080 }, - { 0x0014, 0x0081 }, - { 0x0014, 0x0082 }, - { 0x0014, 0x0083 }, - { 0x0014, 0x0084 }, - { 0x0014, 0x0085 }, - { 0x0014, 0x0086 }, - { 0x0014, 0x0087 }, - { 0x0014, 0x0088 }, - { 0x0014, 0x0089 }, - { 0x0014, 0x008a }, - { 0x0014, 0x008b }, - { 0x0014, 0x008c }, - { 0x0014, 0x008d }, - { 0x0014, 0x008e }, - { 0x0014, 0x008f }, - { 0x0014, 0x0090 }, - { 0x0014, 0x0091 }, - { 0x0014, 0x0092 }, - { 0x0014, 0x0093 }, - { 0x0014, 0x0094 }, - { 0x0014, 0x0095 }, - { 0x0014, 0x0096 }, - { 0x0014, 0x0097 }, - { 0x0014, 0x0098 }, - { 0x0014, 0x0099 }, - { 0x0014, 0x009a }, - { 0x0014, 0x009b }, - { 0x0014, 0x009c }, - { 0x0014, 0x009d }, - { 0x0014, 0x009e }, - { 0x0014, 0x009f }, - { 0x0014, 0x00a0 }, - { 0x0014, 0x00a1 }, - { 0x0014, 0x00a2 }, - { 0x0014, 0x00a3 }, - { 0x0014, 0x00a4 }, - { 0x0014, 0x00a5 }, - - }; - -const uint16_t c_aauiLCLDHuffEnc14[400][2] = - { - { 0x0005, 0x0007 }, - { 0x0004, 0x0009 }, - { 0x0005, 0x0008 }, - { 0x0005, 0x0009 }, - { 0x0006, 0x0006 }, - { 0x0007, 0x0006 }, - { 0x0009, 0x0007 }, - { 0x000b, 0x0008 }, - { 0x000d, 0x000c }, - { 0x000f, 0x0013 }, - { 0x0010, 0x001b }, - { 0x0013, 0x0082 }, - { 0x0013, 0x0083 }, - { 0x0014, 0x0000 }, - { 0x0014, 0x0001 }, - { 0x0014, 0x0002 }, - { 0x0014, 0x0003 }, - { 0x0014, 0x0004 }, - { 0x0014, 0x0005 }, - { 0x0014, 0x0006 }, - { 0x0004, 0x000a }, - { 0x0004, 0x000b }, - { 0x0004, 0x000c }, - { 0x0005, 0x000a }, - { 0x0005, 0x000b }, - { 0x0006, 0x0007 }, - { 0x0008, 0x0006 }, - { 0x000a, 0x0007 }, - { 0x000c, 0x000a }, - { 0x000e, 0x000e }, - { 0x000f, 0x0014 }, - { 0x0011, 0x002a }, - { 0x0012, 0x004a }, - { 0x0013, 0x0084 }, - { 0x0014, 0x0007 }, - { 0x0014, 0x0008 }, - { 0x0014, 0x0009 }, - { 0x0014, 0x000a }, - { 0x0014, 0x000b }, - { 0x0014, 0x000c }, - { 0x0005, 0x000c }, - { 0x0004, 0x000d }, - { 0x0004, 0x000e }, - { 0x0005, 0x000d }, - { 0x0006, 0x0008 }, - { 0x0007, 0x0007 }, - { 0x0008, 0x0007 }, - { 0x000a, 0x0008 }, - { 0x000c, 0x000b }, - { 0x000e, 0x000f }, - { 0x000f, 0x0015 }, - { 0x0012, 0x004b }, - { 0x0013, 0x0085 }, - { 0x0014, 0x000d }, - { 0x0014, 0x000e }, - { 0x0014, 0x000f }, - { 0x0014, 0x0010 }, - { 0x0014, 0x0011 }, - { 0x0014, 0x0012 }, - { 0x0014, 0x0013 }, - { 0x0005, 0x000e }, - { 0x0004, 0x000f }, - { 0x0005, 0x000f }, - { 0x0005, 0x0010 }, - { 0x0006, 0x0009 }, - { 0x0008, 0x0008 }, - { 0x0009, 0x0008 }, - { 0x000b, 0x0009 }, - { 0x000d, 0x000d }, - { 0x000e, 0x0010 }, - { 0x0010, 0x001c }, - { 0x0011, 0x002b }, - { 0x0014, 0x0014 }, - { 0x0014, 0x0015 }, - { 0x0014, 0x0016 }, - { 0x0014, 0x0017 }, - { 0x0014, 0x0018 }, - { 0x0014, 0x0019 }, - { 0x0014, 0x001a }, - { 0x0014, 0x001b }, - { 0x0006, 0x000a }, - { 0x0005, 0x0011 }, - { 0x0006, 0x000b }, - { 0x0006, 0x000c }, - { 0x0007, 0x0008 }, - { 0x0008, 0x0009 }, - { 0x000a, 0x0009 }, - { 0x000c, 0x000c }, - { 0x000e, 0x0011 }, - { 0x000f, 0x0016 }, - { 0x0010, 0x001d }, - { 0x0012, 0x004c }, - { 0x0014, 0x001c }, - { 0x0014, 0x001d }, - { 0x0014, 0x001e }, - { 0x0014, 0x001f }, - { 0x0014, 0x0020 }, - { 0x0014, 0x0021 }, - { 0x0014, 0x0022 }, - { 0x0014, 0x0023 }, - { 0x0007, 0x0009 }, - { 0x0006, 0x000d }, - { 0x0007, 0x000a }, - { 0x0007, 0x000b }, - { 0x0009, 0x0009 }, - { 0x000a, 0x000a }, - { 0x000b, 0x000a }, - { 0x000d, 0x000e }, - { 0x000f, 0x0017 }, - { 0x0011, 0x002c }, - { 0x0010, 0x001e }, - { 0x0014, 0x0024 }, - { 0x0014, 0x0025 }, - { 0x0014, 0x0026 }, - { 0x0014, 0x0027 }, - { 0x0014, 0x0028 }, - { 0x0014, 0x0029 }, - { 0x0014, 0x002a }, - { 0x0014, 0x002b }, - { 0x0014, 0x002c }, - { 0x0009, 0x000a }, - { 0x0008, 0x000a }, - { 0x0008, 0x000b }, - { 0x0009, 0x000b }, - { 0x000a, 0x000b }, - { 0x000b, 0x000b }, - { 0x000d, 0x000f }, - { 0x000e, 0x0012 }, - { 0x000f, 0x0018 }, - { 0x0011, 0x002d }, - { 0x0011, 0x002e }, - { 0x0013, 0x0086 }, - { 0x0014, 0x002d }, - { 0x0014, 0x002e }, - { 0x0014, 0x002f }, - { 0x0014, 0x0030 }, - { 0x0014, 0x0031 }, - { 0x0014, 0x0032 }, - { 0x0014, 0x0033 }, - { 0x0014, 0x0034 }, - { 0x000b, 0x000c }, - { 0x000a, 0x000c }, - { 0x000a, 0x000d }, - { 0x000b, 0x000d }, - { 0x000c, 0x000d }, - { 0x000d, 0x0010 }, - { 0x000e, 0x0013 }, - { 0x000f, 0x0019 }, - { 0x0010, 0x001f }, - { 0x0013, 0x0087 }, - { 0x0014, 0x0035 }, - { 0x0014, 0x0036 }, - { 0x0013, 0x0088 }, - { 0x0014, 0x0037 }, - { 0x0014, 0x0038 }, - { 0x0014, 0x0039 }, - { 0x0014, 0x003a }, - { 0x0014, 0x003b }, - { 0x0014, 0x003c }, - { 0x0014, 0x003d }, - { 0x000d, 0x0011 }, - { 0x000c, 0x000e }, - { 0x000c, 0x000f }, - { 0x000d, 0x0012 }, - { 0x000d, 0x0013 }, - { 0x000e, 0x0014 }, - { 0x0010, 0x0020 }, - { 0x0010, 0x0021 }, - { 0x0012, 0x004d }, - { 0x0011, 0x002f }, - { 0x0014, 0x003e }, - { 0x0014, 0x003f }, - { 0x0014, 0x0040 }, - { 0x0014, 0x0041 }, - { 0x0014, 0x0042 }, - { 0x0014, 0x0043 }, - { 0x0014, 0x0044 }, - { 0x0014, 0x0045 }, - { 0x0014, 0x0046 }, - { 0x0014, 0x0047 }, - { 0x000f, 0x001a }, - { 0x000e, 0x0015 }, - { 0x000e, 0x0016 }, - { 0x000e, 0x0017 }, - { 0x000f, 0x001b }, - { 0x0011, 0x0030 }, - { 0x0011, 0x0031 }, - { 0x0013, 0x0089 }, - { 0x0013, 0x008a }, - { 0x0013, 0x008b }, - { 0x0014, 0x0048 }, - { 0x0014, 0x0049 }, - { 0x0014, 0x004a }, - { 0x0014, 0x004b }, - { 0x0014, 0x004c }, - { 0x0014, 0x004d }, - { 0x0014, 0x004e }, - { 0x0014, 0x004f }, - { 0x0014, 0x0050 }, - { 0x0014, 0x0051 }, - { 0x0010, 0x0022 }, - { 0x0010, 0x0023 }, - { 0x0010, 0x0024 }, - { 0x0010, 0x0025 }, - { 0x0011, 0x0032 }, - { 0x0011, 0x0033 }, - { 0x0012, 0x004e }, - { 0x0012, 0x004f }, - { 0x0014, 0x0052 }, - { 0x0013, 0x008c }, - { 0x0013, 0x008d }, - { 0x0014, 0x0053 }, - { 0x0014, 0x0054 }, - { 0x0014, 0x0055 }, - { 0x0014, 0x0056 }, - { 0x0014, 0x0057 }, - { 0x0014, 0x0058 }, - { 0x0014, 0x0059 }, - { 0x0014, 0x005a }, - { 0x0014, 0x005b }, - { 0x0011, 0x0034 }, - { 0x0011, 0x0035 }, - { 0x0012, 0x0050 }, - { 0x0012, 0x0051 }, - { 0x0013, 0x008e }, - { 0x0014, 0x005c }, - { 0x0014, 0x005d }, - { 0x0014, 0x005e }, - { 0x0014, 0x005f }, - { 0x0014, 0x0060 }, - { 0x0014, 0x0061 }, - { 0x0014, 0x0062 }, - { 0x0014, 0x0063 }, - { 0x0014, 0x0064 }, - { 0x0014, 0x0065 }, - { 0x0014, 0x0066 }, - { 0x0014, 0x0067 }, - { 0x0014, 0x0068 }, - { 0x0014, 0x0069 }, - { 0x0014, 0x006a }, - { 0x0012, 0x0052 }, - { 0x0013, 0x008f }, - { 0x0013, 0x0090 }, - { 0x0014, 0x006b }, - { 0x0013, 0x0091 }, - { 0x0014, 0x006c }, - { 0x0014, 0x006d }, - { 0x0014, 0x006e }, - { 0x0014, 0x006f }, - { 0x0014, 0x0070 }, - { 0x0014, 0x0071 }, - { 0x0014, 0x0072 }, - { 0x0014, 0x0073 }, - { 0x0014, 0x0074 }, - { 0x0014, 0x0075 }, - { 0x0014, 0x0076 }, - { 0x0014, 0x0077 }, - { 0x0014, 0x0078 }, - { 0x0014, 0x0079 }, - { 0x0014, 0x007a }, - { 0x0014, 0x007b }, - { 0x0014, 0x007c }, - { 0x0013, 0x0092 }, - { 0x0012, 0x0053 }, - { 0x0014, 0x007d }, - { 0x0014, 0x007e }, - { 0x0014, 0x007f }, - { 0x0014, 0x0080 }, - { 0x0014, 0x0081 }, - { 0x0014, 0x0082 }, - { 0x0014, 0x0083 }, - { 0x0014, 0x0084 }, - { 0x0014, 0x0085 }, - { 0x0014, 0x0086 }, - { 0x0014, 0x0087 }, - { 0x0014, 0x0088 }, - { 0x0014, 0x0089 }, - { 0x0014, 0x008a }, - { 0x0014, 0x008b }, - { 0x0014, 0x008c }, - { 0x0014, 0x008d }, - { 0x0014, 0x008e }, - { 0x0013, 0x0093 }, - { 0x0014, 0x008f }, - { 0x0014, 0x0090 }, - { 0x0014, 0x0091 }, - { 0x0014, 0x0092 }, - { 0x0014, 0x0093 }, - { 0x0014, 0x0094 }, - { 0x0014, 0x0095 }, - { 0x0014, 0x0096 }, - { 0x0014, 0x0097 }, - { 0x0014, 0x0098 }, - { 0x0014, 0x0099 }, - { 0x0014, 0x009a }, - { 0x0014, 0x009b }, - { 0x0014, 0x009c }, - { 0x0014, 0x009d }, - { 0x0014, 0x009e }, - { 0x0014, 0x009f }, - { 0x0014, 0x00a0 }, - { 0x0014, 0x00a1 }, - { 0x0014, 0x00a2 }, - { 0x0014, 0x00a3 }, - { 0x0014, 0x00a4 }, - { 0x0014, 0x00a5 }, - { 0x0014, 0x00a6 }, - { 0x0014, 0x00a7 }, - { 0x0014, 0x00a8 }, - { 0x0014, 0x00a9 }, - { 0x0014, 0x00aa }, - { 0x0014, 0x00ab }, - { 0x0014, 0x00ac }, - { 0x0014, 0x00ad }, - { 0x0014, 0x00ae }, - { 0x0014, 0x00af }, - { 0x0014, 0x00b0 }, - { 0x0014, 0x00b1 }, - { 0x0014, 0x00b2 }, - { 0x0014, 0x00b3 }, - { 0x0014, 0x00b4 }, - { 0x0014, 0x00b5 }, - { 0x0014, 0x00b6 }, - { 0x0014, 0x00b7 }, - { 0x0014, 0x00b8 }, - { 0x0014, 0x00b9 }, - { 0x0014, 0x00ba }, - { 0x0014, 0x00bb }, - { 0x0014, 0x00bc }, - { 0x0014, 0x00bd }, - { 0x0014, 0x00be }, - { 0x0014, 0x00bf }, - { 0x0014, 0x00c0 }, - { 0x0014, 0x00c1 }, - { 0x0014, 0x00c2 }, - { 0x0014, 0x00c3 }, - { 0x0014, 0x00c4 }, - { 0x0014, 0x00c5 }, - { 0x0014, 0x00c6 }, - { 0x0014, 0x00c7 }, - { 0x0014, 0x00c8 }, - { 0x0014, 0x00c9 }, - { 0x0014, 0x00ca }, - { 0x0014, 0x00cb }, - { 0x0014, 0x00cc }, - { 0x0014, 0x00cd }, - { 0x0014, 0x00ce }, - { 0x0014, 0x00cf }, - { 0x0014, 0x00d0 }, - { 0x0014, 0x00d1 }, - { 0x0014, 0x00d2 }, - { 0x0014, 0x00d3 }, - { 0x0014, 0x00d4 }, - { 0x0014, 0x00d5 }, - { 0x0014, 0x00d6 }, - { 0x0014, 0x00d7 }, - { 0x0014, 0x00d8 }, - { 0x0014, 0x00d9 }, - { 0x0014, 0x00da }, - { 0x0014, 0x00db }, - { 0x0014, 0x00dc }, - { 0x0014, 0x00dd }, - { 0x0014, 0x00de }, - { 0x0014, 0x00df }, - { 0x0014, 0x00e0 }, - { 0x0014, 0x00e1 }, - { 0x0014, 0x00e2 }, - { 0x0014, 0x00e3 }, - { 0x0014, 0x00e4 }, - { 0x0014, 0x00e5 }, - { 0x0014, 0x00e6 }, - { 0x0014, 0x00e7 }, - { 0x0014, 0x00e8 }, - { 0x0014, 0x00e9 }, - { 0x0014, 0x00ea }, - { 0x0014, 0x00eb }, - { 0x0014, 0x00ec }, - { 0x0014, 0x00ed }, - { 0x0014, 0x00ee }, - { 0x0014, 0x00ef }, - { 0x0014, 0x00f0 }, - { 0x0014, 0x00f1 }, - { 0x0014, 0x00f2 }, - { 0x0014, 0x00f3 }, - { 0x0014, 0x00f4 }, - { 0x0014, 0x00f5 }, - { 0x0014, 0x00f6 }, - { 0x0014, 0x00f7 }, - { 0x0014, 0x00f8 }, - { 0x0014, 0x00f9 }, - { 0x0014, 0x00fa }, - { 0x0014, 0x00fb }, - { 0x0014, 0x00fc }, - { 0x0014, 0x00fd }, - { 0x0014, 0x00fe }, - { 0x0014, 0x00ff }, - { 0x0014, 0x0100 }, - { 0x0014, 0x0101 }, - { 0x0014, 0x0102 }, - { 0x0014, 0x0103 }, - }; - -const uint16_t c_aauiLCLDHuffEnc15[576][2] = - { - { 0x0005, 0x000a }, - { 0x0005, 0x000b }, - { 0x0005, 0x000c }, - { 0x0006, 0x0009 }, - { 0x0006, 0x000a }, - { 0x0007, 0x0008 }, - { 0x0008, 0x0009 }, - { 0x0009, 0x0008 }, - { 0x000b, 0x000b }, - { 0x000d, 0x000e }, - { 0x000e, 0x0011 }, - { 0x000f, 0x001a }, - { 0x0012, 0x006e }, - { 0x0014, 0x0000 }, - { 0x0013, 0x00cc }, - { 0x0014, 0x0001 }, - { 0x0014, 0x0002 }, - { 0x0014, 0x0003 }, - { 0x0014, 0x0004 }, - { 0x0014, 0x0005 }, - { 0x0014, 0x0006 }, - { 0x0014, 0x0007 }, - { 0x0014, 0x0008 }, - { 0x0014, 0x0009 }, - { 0x0005, 0x000d }, - { 0x0004, 0x000c }, - { 0x0004, 0x000d }, - { 0x0005, 0x000e }, - { 0x0005, 0x000f }, - { 0x0006, 0x000b }, - { 0x0007, 0x0009 }, - { 0x0008, 0x000a }, - { 0x000a, 0x000a }, - { 0x000c, 0x000c }, - { 0x000d, 0x000f }, - { 0x000f, 0x001b }, - { 0x0011, 0x003d }, - { 0x0011, 0x003e }, - { 0x0013, 0x00cd }, - { 0x0014, 0x000a }, - { 0x0014, 0x000b }, - { 0x0014, 0x000c }, - { 0x0014, 0x000d }, - { 0x0014, 0x000e }, - { 0x0014, 0x000f }, - { 0x0014, 0x0010 }, - { 0x0014, 0x0011 }, - { 0x0014, 0x0012 }, - { 0x0005, 0x0010 }, - { 0x0004, 0x000e }, - { 0x0004, 0x000f }, - { 0x0005, 0x0011 }, - { 0x0005, 0x0012 }, - { 0x0006, 0x000c }, - { 0x0007, 0x000a }, - { 0x0009, 0x0009 }, - { 0x000a, 0x000b }, - { 0x000c, 0x000d }, - { 0x000e, 0x0012 }, - { 0x0010, 0x0027 }, - { 0x0011, 0x003f }, - { 0x0012, 0x006f }, - { 0x0014, 0x0013 }, - { 0x0014, 0x0014 }, - { 0x0014, 0x0015 }, - { 0x0014, 0x0016 }, - { 0x0014, 0x0017 }, - { 0x0014, 0x0018 }, - { 0x0014, 0x0019 }, - { 0x0014, 0x001a }, - { 0x0014, 0x001b }, - { 0x0014, 0x001c }, - { 0x0006, 0x000d }, - { 0x0005, 0x0013 }, - { 0x0005, 0x0014 }, - { 0x0005, 0x0015 }, - { 0x0006, 0x000e }, - { 0x0007, 0x000b }, - { 0x0008, 0x000b }, - { 0x0009, 0x000a }, - { 0x000b, 0x000c }, - { 0x000c, 0x000e }, - { 0x000e, 0x0013 }, - { 0x000f, 0x001c }, - { 0x0011, 0x0040 }, - { 0x0012, 0x0070 }, - { 0x0014, 0x001d }, - { 0x0014, 0x001e }, - { 0x0014, 0x001f }, - { 0x0014, 0x0020 }, - { 0x0014, 0x0021 }, - { 0x0014, 0x0022 }, - { 0x0014, 0x0023 }, - { 0x0014, 0x0024 }, - { 0x0014, 0x0025 }, - { 0x0014, 0x0026 }, - { 0x0006, 0x000f }, - { 0x0005, 0x0016 }, - { 0x0005, 0x0017 }, - { 0x0006, 0x0010 }, - { 0x0006, 0x0011 }, - { 0x0007, 0x000c }, - { 0x0009, 0x000b }, - { 0x000a, 0x000c }, - { 0x000b, 0x000d }, - { 0x000d, 0x0010 }, - { 0x000e, 0x0014 }, - { 0x0010, 0x0028 }, - { 0x0011, 0x0041 }, - { 0x0013, 0x00ce }, - { 0x0014, 0x0027 }, - { 0x0014, 0x0028 }, - { 0x0014, 0x0029 }, - { 0x0014, 0x002a }, - { 0x0014, 0x002b }, - { 0x0014, 0x002c }, - { 0x0014, 0x002d }, - { 0x0014, 0x002e }, - { 0x0014, 0x002f }, - { 0x0014, 0x0030 }, - { 0x0007, 0x000d }, - { 0x0006, 0x0012 }, - { 0x0006, 0x0013 }, - { 0x0007, 0x000e }, - { 0x0007, 0x000f }, - { 0x0008, 0x000c }, - { 0x0009, 0x000c }, - { 0x000b, 0x000e }, - { 0x000c, 0x000f }, - { 0x000e, 0x0015 }, - { 0x0010, 0x0029 }, - { 0x0011, 0x0042 }, - { 0x0014, 0x0031 }, - { 0x0014, 0x0032 }, - { 0x0014, 0x0033 }, - { 0x0014, 0x0034 }, - { 0x0014, 0x0035 }, - { 0x0014, 0x0036 }, - { 0x0014, 0x0037 }, - { 0x0014, 0x0038 }, - { 0x0014, 0x0039 }, - { 0x0014, 0x003a }, - { 0x0014, 0x003b }, - { 0x0014, 0x003c }, - { 0x0008, 0x000d }, - { 0x0007, 0x0010 }, - { 0x0007, 0x0011 }, - { 0x0008, 0x000e }, - { 0x0009, 0x000d }, - { 0x0009, 0x000e }, - { 0x000b, 0x000f }, - { 0x000c, 0x0010 }, - { 0x000d, 0x0011 }, - { 0x000f, 0x001d }, - { 0x0010, 0x002a }, - { 0x0011, 0x0043 }, - { 0x0014, 0x003d }, - { 0x0013, 0x00cf }, - { 0x0014, 0x003e }, - { 0x0014, 0x003f }, - { 0x0014, 0x0040 }, - { 0x0014, 0x0041 }, - { 0x0014, 0x0042 }, - { 0x0014, 0x0043 }, - { 0x0014, 0x0044 }, - { 0x0014, 0x0045 }, - { 0x0014, 0x0046 }, - { 0x0014, 0x0047 }, - { 0x0009, 0x000f }, - { 0x0008, 0x000f }, - { 0x0009, 0x0010 }, - { 0x0009, 0x0011 }, - { 0x000a, 0x000d }, - { 0x000b, 0x0010 }, - { 0x000c, 0x0011 }, - { 0x000d, 0x0012 }, - { 0x000e, 0x0016 }, - { 0x0010, 0x002b }, - { 0x0011, 0x0044 }, - { 0x0012, 0x0071 }, - { 0x0014, 0x0048 }, - { 0x0014, 0x0049 }, - { 0x0014, 0x004a }, - { 0x0014, 0x004b }, - { 0x0014, 0x004c }, - { 0x0014, 0x004d }, - { 0x0014, 0x004e }, - { 0x0014, 0x004f }, - { 0x0014, 0x0050 }, - { 0x0014, 0x0051 }, - { 0x0014, 0x0052 }, - { 0x0014, 0x0053 }, - { 0x000b, 0x0011 }, - { 0x000a, 0x000e }, - { 0x000a, 0x000f }, - { 0x000b, 0x0012 }, - { 0x000b, 0x0013 }, - { 0x000c, 0x0012 }, - { 0x000d, 0x0013 }, - { 0x000e, 0x0017 }, - { 0x0010, 0x002c }, - { 0x0012, 0x0072 }, - { 0x0011, 0x0045 }, - { 0x0013, 0x00d0 }, - { 0x0013, 0x00d1 }, - { 0x0014, 0x0054 }, - { 0x0014, 0x0055 }, - { 0x0014, 0x0056 }, - { 0x0014, 0x0057 }, - { 0x0014, 0x0058 }, - { 0x0014, 0x0059 }, - { 0x0014, 0x005a }, - { 0x0014, 0x005b }, - { 0x0014, 0x005c }, - { 0x0014, 0x005d }, - { 0x0014, 0x005e }, - { 0x000c, 0x0013 }, - { 0x000c, 0x0014 }, - { 0x000c, 0x0015 }, - { 0x000d, 0x0014 }, - { 0x000d, 0x0015 }, - { 0x000e, 0x0018 }, - { 0x000f, 0x001e }, - { 0x0010, 0x002d }, - { 0x0011, 0x0046 }, - { 0x0011, 0x0047 }, - { 0x0011, 0x0048 }, - { 0x0014, 0x005f }, - { 0x0014, 0x0060 }, - { 0x0014, 0x0061 }, - { 0x0014, 0x0062 }, - { 0x0014, 0x0063 }, - { 0x0014, 0x0064 }, - { 0x0014, 0x0065 }, - { 0x0014, 0x0066 }, - { 0x0014, 0x0067 }, - { 0x0014, 0x0068 }, - { 0x0014, 0x0069 }, - { 0x0014, 0x006a }, - { 0x0014, 0x006b }, - { 0x000e, 0x0019 }, - { 0x000d, 0x0016 }, - { 0x000d, 0x0017 }, - { 0x000e, 0x001a }, - { 0x000e, 0x001b }, - { 0x000f, 0x001f }, - { 0x0010, 0x002e }, - { 0x0011, 0x0049 }, - { 0x0012, 0x0073 }, - { 0x0014, 0x006c }, - { 0x0014, 0x006d }, - { 0x0014, 0x006e }, - { 0x0014, 0x006f }, - { 0x0014, 0x0070 }, - { 0x0014, 0x0071 }, - { 0x0014, 0x0072 }, - { 0x0014, 0x0073 }, - { 0x0014, 0x0074 }, - { 0x0014, 0x0075 }, - { 0x0014, 0x0076 }, - { 0x0014, 0x0077 }, - { 0x0014, 0x0078 }, - { 0x0014, 0x0079 }, - { 0x0014, 0x007a }, - { 0x0010, 0x002f }, - { 0x000f, 0x0020 }, - { 0x0010, 0x0030 }, - { 0x000f, 0x0021 }, - { 0x0010, 0x0031 }, - { 0x0011, 0x004a }, - { 0x0011, 0x004b }, - { 0x0012, 0x0074 }, - { 0x0014, 0x007b }, - { 0x0014, 0x007c }, - { 0x0013, 0x00d2 }, - { 0x0014, 0x007d }, - { 0x0014, 0x007e }, - { 0x0014, 0x007f }, - { 0x0014, 0x0080 }, - { 0x0014, 0x0081 }, - { 0x0014, 0x0082 }, - { 0x0014, 0x0083 }, - { 0x0014, 0x0084 }, - { 0x0014, 0x0085 }, - { 0x0014, 0x0086 }, - { 0x0014, 0x0087 }, - { 0x0014, 0x0088 }, - { 0x0014, 0x0089 }, - { 0x0012, 0x0075 }, - { 0x0010, 0x0032 }, - { 0x0010, 0x0033 }, - { 0x0011, 0x004c }, - { 0x0011, 0x004d }, - { 0x0013, 0x00d3 }, - { 0x0013, 0x00d4 }, - { 0x0012, 0x0076 }, - { 0x0013, 0x00d5 }, - { 0x0014, 0x008a }, - { 0x0014, 0x008b }, - { 0x0014, 0x008c }, - { 0x0014, 0x008d }, - { 0x0014, 0x008e }, - { 0x0014, 0x008f }, - { 0x0014, 0x0090 }, - { 0x0014, 0x0091 }, - { 0x0014, 0x0092 }, - { 0x0014, 0x0093 }, - { 0x0014, 0x0094 }, - { 0x0014, 0x0095 }, - { 0x0014, 0x0096 }, - { 0x0014, 0x0097 }, - { 0x0014, 0x0098 }, - { 0x0013, 0x00d6 }, - { 0x0013, 0x00d7 }, - { 0x0012, 0x0077 }, - { 0x0012, 0x0078 }, - { 0x0014, 0x0099 }, - { 0x0014, 0x009a }, - { 0x0013, 0x00d8 }, - { 0x0014, 0x009b }, - { 0x0014, 0x009c }, - { 0x0014, 0x009d }, - { 0x0014, 0x009e }, - { 0x0014, 0x009f }, - { 0x0014, 0x00a0 }, - { 0x0014, 0x00a1 }, - { 0x0014, 0x00a2 }, - { 0x0014, 0x00a3 }, - { 0x0014, 0x00a4 }, - { 0x0014, 0x00a5 }, - { 0x0014, 0x00a6 }, - { 0x0014, 0x00a7 }, - { 0x0014, 0x00a8 }, - { 0x0014, 0x00a9 }, - { 0x0014, 0x00aa }, - { 0x0014, 0x00ab }, - { 0x0014, 0x00ac }, - { 0x0014, 0x00ad }, - { 0x0014, 0x00ae }, - { 0x0014, 0x00af }, - { 0x0012, 0x0079 }, - { 0x0014, 0x00b0 }, - { 0x0014, 0x00b1 }, - { 0x0014, 0x00b2 }, - { 0x0014, 0x00b3 }, - { 0x0014, 0x00b4 }, - { 0x0014, 0x00b5 }, - { 0x0014, 0x00b6 }, - { 0x0014, 0x00b7 }, - { 0x0014, 0x00b8 }, - { 0x0014, 0x00b9 }, - { 0x0014, 0x00ba }, - { 0x0014, 0x00bb }, - { 0x0014, 0x00bc }, - { 0x0014, 0x00bd }, - { 0x0014, 0x00be }, - { 0x0014, 0x00bf }, - { 0x0014, 0x00c0 }, - { 0x0014, 0x00c1 }, - { 0x0014, 0x00c2 }, - { 0x0014, 0x00c3 }, - { 0x0014, 0x00c4 }, - { 0x0014, 0x00c5 }, - { 0x0014, 0x00c6 }, - { 0x0013, 0x00d9 }, - { 0x0013, 0x00da }, - { 0x0014, 0x00c7 }, - { 0x0014, 0x00c8 }, - { 0x0014, 0x00c9 }, - { 0x0014, 0x00ca }, - { 0x0014, 0x00cb }, - { 0x0014, 0x00cc }, - { 0x0014, 0x00cd }, - { 0x0014, 0x00ce }, - { 0x0014, 0x00cf }, - { 0x0014, 0x00d0 }, - { 0x0014, 0x00d1 }, - { 0x0014, 0x00d2 }, - { 0x0014, 0x00d3 }, - { 0x0014, 0x00d4 }, - { 0x0014, 0x00d5 }, - { 0x0014, 0x00d6 }, - { 0x0014, 0x00d7 }, - { 0x0014, 0x00d8 }, - { 0x0014, 0x00d9 }, - { 0x0014, 0x00da }, - { 0x0014, 0x00db }, - { 0x0014, 0x00dc }, - { 0x0014, 0x00dd }, - { 0x0014, 0x00de }, - { 0x0014, 0x00df }, - { 0x0014, 0x00e0 }, - { 0x0014, 0x00e1 }, - { 0x0014, 0x00e2 }, - { 0x0014, 0x00e3 }, - { 0x0014, 0x00e4 }, - { 0x0014, 0x00e5 }, - { 0x0014, 0x00e6 }, - { 0x0014, 0x00e7 }, - { 0x0014, 0x00e8 }, - { 0x0014, 0x00e9 }, - { 0x0014, 0x00ea }, - { 0x0014, 0x00eb }, - { 0x0014, 0x00ec }, - { 0x0014, 0x00ed }, - { 0x0014, 0x00ee }, - { 0x0014, 0x00ef }, - { 0x0014, 0x00f0 }, - { 0x0014, 0x00f1 }, - { 0x0014, 0x00f2 }, - { 0x0014, 0x00f3 }, - { 0x0014, 0x00f4 }, - { 0x0014, 0x00f5 }, - { 0x0014, 0x00f6 }, - { 0x0014, 0x00f7 }, - { 0x0014, 0x00f8 }, - { 0x0014, 0x00f9 }, - { 0x0014, 0x00fa }, - { 0x0014, 0x00fb }, - { 0x0014, 0x00fc }, - { 0x0014, 0x00fd }, - { 0x0014, 0x00fe }, - { 0x0014, 0x00ff }, - { 0x0014, 0x0100 }, - { 0x0014, 0x0101 }, - { 0x0014, 0x0102 }, - { 0x0014, 0x0103 }, - { 0x0014, 0x0104 }, - { 0x0014, 0x0105 }, - { 0x0014, 0x0106 }, - { 0x0014, 0x0107 }, - { 0x0014, 0x0108 }, - { 0x0014, 0x0109 }, - { 0x0014, 0x010a }, - { 0x0014, 0x010b }, - { 0x0014, 0x010c }, - { 0x0014, 0x010d }, - { 0x0014, 0x010e }, - { 0x0014, 0x010f }, - { 0x0014, 0x0110 }, - { 0x0014, 0x0111 }, - { 0x0014, 0x0112 }, - { 0x0014, 0x0113 }, - { 0x0014, 0x0114 }, - { 0x0014, 0x0115 }, - { 0x0014, 0x0116 }, - { 0x0014, 0x0117 }, - { 0x0014, 0x0118 }, - { 0x0014, 0x0119 }, - { 0x0014, 0x011a }, - { 0x0014, 0x011b }, - { 0x0014, 0x011c }, - { 0x0014, 0x011d }, - { 0x0014, 0x011e }, - { 0x0014, 0x011f }, - { 0x0014, 0x0120 }, - { 0x0014, 0x0121 }, - { 0x0014, 0x0122 }, - { 0x0014, 0x0123 }, - { 0x0014, 0x0124 }, - { 0x0014, 0x0125 }, - { 0x0014, 0x0126 }, - { 0x0014, 0x0127 }, - { 0x0014, 0x0128 }, - { 0x0014, 0x0129 }, - { 0x0014, 0x012a }, - { 0x0014, 0x012b }, - { 0x0014, 0x012c }, - { 0x0014, 0x012d }, - { 0x0014, 0x012e }, - { 0x0014, 0x012f }, - { 0x0014, 0x0130 }, - { 0x0014, 0x0131 }, - { 0x0014, 0x0132 }, - { 0x0014, 0x0133 }, - { 0x0014, 0x0134 }, - { 0x0014, 0x0135 }, - { 0x0014, 0x0136 }, - { 0x0014, 0x0137 }, - { 0x0014, 0x0138 }, - { 0x0014, 0x0139 }, - { 0x0014, 0x013a }, - { 0x0014, 0x013b }, - { 0x0014, 0x013c }, - { 0x0014, 0x013d }, - { 0x0014, 0x013e }, - { 0x0014, 0x013f }, - { 0x0014, 0x0140 }, - { 0x0014, 0x0141 }, - { 0x0014, 0x0142 }, - { 0x0014, 0x0143 }, - { 0x0014, 0x0144 }, - { 0x0014, 0x0145 }, - { 0x0014, 0x0146 }, - { 0x0014, 0x0147 }, - { 0x0014, 0x0148 }, - { 0x0014, 0x0149 }, - { 0x0014, 0x014a }, - { 0x0014, 0x014b }, - { 0x0014, 0x014c }, - { 0x0014, 0x014d }, - { 0x0014, 0x014e }, - { 0x0014, 0x014f }, - { 0x0014, 0x0150 }, - { 0x0014, 0x0151 }, - { 0x0014, 0x0152 }, - { 0x0014, 0x0153 }, - { 0x0014, 0x0154 }, - { 0x0014, 0x0155 }, - { 0x0014, 0x0156 }, - { 0x0014, 0x0157 }, - { 0x0014, 0x0158 }, - { 0x0014, 0x0159 }, - { 0x0014, 0x015a }, - { 0x0014, 0x015b }, - { 0x0014, 0x015c }, - { 0x0014, 0x015d }, - { 0x0014, 0x015e }, - { 0x0014, 0x015f }, - { 0x0014, 0x0160 }, - { 0x0014, 0x0161 }, - { 0x0014, 0x0162 }, - { 0x0014, 0x0163 }, - { 0x0014, 0x0164 }, - { 0x0014, 0x0165 }, - { 0x0014, 0x0166 }, - { 0x0014, 0x0167 }, - { 0x0014, 0x0168 }, - { 0x0014, 0x0169 }, - { 0x0014, 0x016a }, - { 0x0014, 0x016b }, - { 0x0014, 0x016c }, - { 0x0014, 0x016d }, - { 0x0014, 0x016e }, - { 0x0014, 0x016f }, - { 0x0014, 0x0170 }, - { 0x0014, 0x0171 }, - { 0x0014, 0x0172 }, - { 0x0014, 0x0173 }, - { 0x0014, 0x0174 }, - { 0x0014, 0x0175 }, - { 0x0014, 0x0176 }, - { 0x0014, 0x0177 }, - { 0x0014, 0x0178 }, - { 0x0014, 0x0179 }, - { 0x0014, 0x017a }, - { 0x0014, 0x017b }, - { 0x0014, 0x017c }, - { 0x0014, 0x017d }, - { 0x0014, 0x017e }, - { 0x0014, 0x017f }, - { 0x0014, 0x0180 }, - { 0x0014, 0x0181 }, - { 0x0014, 0x0182 }, - { 0x0014, 0x0183 }, - { 0x0014, 0x0184 }, - { 0x0014, 0x0185 }, - { 0x0014, 0x0186 }, - { 0x0014, 0x0187 }, - { 0x0014, 0x0188 }, - { 0x0014, 0x0189 }, - { 0x0014, 0x018a }, - { 0x0014, 0x018b }, - { 0x0014, 0x018c }, - { 0x0014, 0x018d }, - { 0x0014, 0x018e }, - { 0x0014, 0x018f }, - { 0x0014, 0x0190 }, - { 0x0014, 0x0191 }, - { 0x0014, 0x0192 }, - { 0x0014, 0x0193 }, - { 0x0014, 0x0194 }, - { 0x0014, 0x0195 }, - { 0x0014, 0x0196 }, - { 0x0014, 0x0197 }, - { 0x0013, 0x00db }, - }; - -const uint16_t c_aauiLCLDHuffEnc16[729][2] = - { - { 0x0006, 0x000d }, - { 0x0005, 0x0010 }, - { 0x0006, 0x000e }, - { 0x0006, 0x000f }, - { 0x0006, 0x0010 }, - { 0x0007, 0x000a }, - { 0x0007, 0x000b }, - { 0x0008, 0x000a }, - { 0x0009, 0x000b }, - { 0x000b, 0x000d }, - { 0x000c, 0x000e }, - { 0x000e, 0x0016 }, - { 0x0010, 0x002d }, - { 0x0011, 0x0051 }, - { 0x0012, 0x008c }, - { 0x0014, 0x0000 }, - { 0x0014, 0x0001 }, - { 0x0014, 0x0002 }, - { 0x0014, 0x0003 }, - { 0x0014, 0x0004 }, - { 0x0014, 0x0005 }, - { 0x0014, 0x0006 }, - { 0x0014, 0x0007 }, - { 0x0014, 0x0008 }, - { 0x0014, 0x0009 }, - { 0x0014, 0x000a }, - { 0x0014, 0x000b }, - { 0x0005, 0x0011 }, - { 0x0004, 0x000f }, - { 0x0005, 0x0012 }, - { 0x0005, 0x0013 }, - { 0x0005, 0x0014 }, - { 0x0006, 0x0011 }, - { 0x0006, 0x0012 }, - { 0x0007, 0x000c }, - { 0x0008, 0x000b }, - { 0x000a, 0x000c }, - { 0x000b, 0x000e }, - { 0x000d, 0x0010 }, - { 0x000e, 0x0017 }, - { 0x000f, 0x001c }, - { 0x0013, 0x010b }, - { 0x0013, 0x010c }, - { 0x0014, 0x000c }, - { 0x0014, 0x000d }, - { 0x0014, 0x000e }, - { 0x0014, 0x000f }, - { 0x0014, 0x0010 }, - { 0x0014, 0x0011 }, - { 0x0014, 0x0012 }, - { 0x0014, 0x0013 }, - { 0x0014, 0x0014 }, - { 0x0014, 0x0015 }, - { 0x0014, 0x0016 }, - { 0x0006, 0x0013 }, - { 0x0005, 0x0015 }, - { 0x0005, 0x0016 }, - { 0x0005, 0x0017 }, - { 0x0005, 0x0018 }, - { 0x0006, 0x0014 }, - { 0x0007, 0x000d }, - { 0x0007, 0x000e }, - { 0x0009, 0x000c }, - { 0x000a, 0x000d }, - { 0x000c, 0x000f }, - { 0x000d, 0x0011 }, - { 0x000f, 0x001d }, - { 0x0011, 0x0052 }, - { 0x0012, 0x008d }, - { 0x0012, 0x008e }, - { 0x0014, 0x0017 }, - { 0x0014, 0x0018 }, - { 0x0014, 0x0019 }, - { 0x0014, 0x001a }, - { 0x0014, 0x001b }, - { 0x0014, 0x001c }, - { 0x0014, 0x001d }, - { 0x0014, 0x001e }, - { 0x0014, 0x001f }, - { 0x0014, 0x0020 }, - { 0x0014, 0x0021 }, - { 0x0006, 0x0015 }, - { 0x0005, 0x0019 }, - { 0x0005, 0x001a }, - { 0x0005, 0x001b }, - { 0x0006, 0x0016 }, - { 0x0006, 0x0017 }, - { 0x0007, 0x000f }, - { 0x0008, 0x000c }, - { 0x0009, 0x000d }, - { 0x000b, 0x000f }, - { 0x000c, 0x0010 }, - { 0x000d, 0x0012 }, - { 0x000f, 0x001e }, - { 0x0012, 0x008f }, - { 0x0014, 0x0022 }, - { 0x0014, 0x0023 }, - { 0x0014, 0x0024 }, - { 0x0014, 0x0025 }, - { 0x0014, 0x0026 }, - { 0x0014, 0x0027 }, - { 0x0014, 0x0028 }, - { 0x0014, 0x0029 }, - { 0x0014, 0x002a }, - { 0x0014, 0x002b }, - { 0x0014, 0x002c }, - { 0x0014, 0x002d }, - { 0x0014, 0x002e }, - { 0x0006, 0x0018 }, - { 0x0005, 0x001c }, - { 0x0005, 0x001d }, - { 0x0006, 0x0019 }, - { 0x0006, 0x001a }, - { 0x0007, 0x0010 }, - { 0x0007, 0x0011 }, - { 0x0008, 0x000d }, - { 0x000a, 0x000e }, - { 0x000b, 0x0010 }, - { 0x000c, 0x0011 }, - { 0x000e, 0x0018 }, - { 0x0010, 0x002e }, - { 0x0012, 0x0090 }, - { 0x0013, 0x010d }, - { 0x0013, 0x010e }, - { 0x0014, 0x002f }, - { 0x0014, 0x0030 }, - { 0x0014, 0x0031 }, - { 0x0014, 0x0032 }, - { 0x0014, 0x0033 }, - { 0x0014, 0x0034 }, - { 0x0014, 0x0035 }, - { 0x0014, 0x0036 }, - { 0x0014, 0x0037 }, - { 0x0014, 0x0038 }, - { 0x0014, 0x0039 }, - { 0x0007, 0x0012 }, - { 0x0006, 0x001b }, - { 0x0006, 0x001c }, - { 0x0006, 0x001d }, - { 0x0007, 0x0013 }, - { 0x0007, 0x0014 }, - { 0x0008, 0x000e }, - { 0x0009, 0x000e }, - { 0x000b, 0x0011 }, - { 0x000c, 0x0012 }, - { 0x000d, 0x0013 }, - { 0x000e, 0x0019 }, - { 0x0010, 0x002f }, - { 0x0012, 0x0091 }, - { 0x0014, 0x003a }, - { 0x0014, 0x003b }, - { 0x0014, 0x003c }, - { 0x0014, 0x003d }, - { 0x0014, 0x003e }, - { 0x0014, 0x003f }, - { 0x0014, 0x0040 }, - { 0x0014, 0x0041 }, - { 0x0014, 0x0042 }, - { 0x0014, 0x0043 }, - { 0x0014, 0x0044 }, - { 0x0014, 0x0045 }, - { 0x0014, 0x0046 }, - { 0x0007, 0x0015 }, - { 0x0006, 0x001e }, - { 0x0006, 0x001f }, - { 0x0007, 0x0016 }, - { 0x0007, 0x0017 }, - { 0x0008, 0x000f }, - { 0x0009, 0x000f }, - { 0x000a, 0x000f }, - { 0x000b, 0x0012 }, - { 0x000d, 0x0014 }, - { 0x000e, 0x001a }, - { 0x000f, 0x001f }, - { 0x0013, 0x010f }, - { 0x0011, 0x0053 }, - { 0x0014, 0x0047 }, - { 0x0014, 0x0048 }, - { 0x0014, 0x0049 }, - { 0x0014, 0x004a }, - { 0x0014, 0x004b }, - { 0x0014, 0x004c }, - { 0x0014, 0x004d }, - { 0x0014, 0x004e }, - { 0x0014, 0x004f }, - { 0x0014, 0x0050 }, - { 0x0014, 0x0051 }, - { 0x0014, 0x0052 }, - { 0x0014, 0x0053 }, - { 0x0008, 0x0010 }, - { 0x0007, 0x0018 }, - { 0x0007, 0x0019 }, - { 0x0008, 0x0011 }, - { 0x0008, 0x0012 }, - { 0x0009, 0x0010 }, - { 0x000a, 0x0010 }, - { 0x000b, 0x0013 }, - { 0x000c, 0x0013 }, - { 0x000e, 0x001b }, - { 0x000f, 0x0020 }, - { 0x0010, 0x0030 }, - { 0x0012, 0x0092 }, - { 0x0014, 0x0054 }, - { 0x0014, 0x0055 }, - { 0x0014, 0x0056 }, - { 0x0014, 0x0057 }, - { 0x0014, 0x0058 }, - { 0x0014, 0x0059 }, - { 0x0014, 0x005a }, - { 0x0014, 0x005b }, - { 0x0014, 0x005c }, - { 0x0014, 0x005d }, - { 0x0014, 0x005e }, - { 0x0014, 0x005f }, - { 0x0014, 0x0060 }, - { 0x0014, 0x0061 }, - { 0x0009, 0x0011 }, - { 0x0008, 0x0013 }, - { 0x0009, 0x0012 }, - { 0x0009, 0x0013 }, - { 0x000a, 0x0011 }, - { 0x000a, 0x0012 }, - { 0x000b, 0x0014 }, - { 0x000c, 0x0014 }, - { 0x000d, 0x0015 }, - { 0x000e, 0x001c }, - { 0x000f, 0x0021 }, - { 0x0013, 0x0110 }, - { 0x0012, 0x0093 }, - { 0x0012, 0x0094 }, - { 0x0014, 0x0062 }, - { 0x0014, 0x0063 }, - { 0x0014, 0x0064 }, - { 0x0014, 0x0065 }, - { 0x0014, 0x0066 }, - { 0x0014, 0x0067 }, - { 0x0014, 0x0068 }, - { 0x0014, 0x0069 }, - { 0x0014, 0x006a }, - { 0x0014, 0x006b }, - { 0x0014, 0x006c }, - { 0x0014, 0x006d }, - { 0x0014, 0x006e }, - { 0x000b, 0x0015 }, - { 0x000a, 0x0013 }, - { 0x000a, 0x0014 }, - { 0x000a, 0x0015 }, - { 0x000b, 0x0016 }, - { 0x000c, 0x0015 }, - { 0x000d, 0x0016 }, - { 0x000d, 0x0017 }, - { 0x000f, 0x0022 }, - { 0x0010, 0x0031 }, - { 0x0012, 0x0095 }, - { 0x0012, 0x0096 }, - { 0x0014, 0x006f }, - { 0x0013, 0x0111 }, - { 0x0014, 0x0070 }, - { 0x0014, 0x0071 }, - { 0x0014, 0x0072 }, - { 0x0014, 0x0073 }, - { 0x0014, 0x0074 }, - { 0x0014, 0x0075 }, - { 0x0014, 0x0076 }, - { 0x0014, 0x0077 }, - { 0x0014, 0x0078 }, - { 0x0014, 0x0079 }, - { 0x0014, 0x007a }, - { 0x0014, 0x007b }, - { 0x0014, 0x007c }, - { 0x000c, 0x0016 }, - { 0x000b, 0x0017 }, - { 0x000c, 0x0017 }, - { 0x000c, 0x0018 }, - { 0x000c, 0x0019 }, - { 0x000d, 0x0018 }, - { 0x000e, 0x001d }, - { 0x000f, 0x0023 }, - { 0x000f, 0x0024 }, - { 0x0011, 0x0054 }, - { 0x0012, 0x0097 }, - { 0x0014, 0x007d }, - { 0x0014, 0x007e }, - { 0x0014, 0x007f }, - { 0x0014, 0x0080 }, - { 0x0014, 0x0081 }, - { 0x0014, 0x0082 }, - { 0x0014, 0x0083 }, - { 0x0014, 0x0084 }, - { 0x0014, 0x0085 }, - { 0x0014, 0x0086 }, - { 0x0014, 0x0087 }, - { 0x0014, 0x0088 }, - { 0x0014, 0x0089 }, - { 0x0014, 0x008a }, - { 0x0014, 0x008b }, - { 0x0014, 0x008c }, - { 0x000e, 0x001e }, - { 0x000d, 0x0019 }, - { 0x000d, 0x001a }, - { 0x000d, 0x001b }, - { 0x000e, 0x001f }, - { 0x000f, 0x0025 }, - { 0x000f, 0x0026 }, - { 0x0010, 0x0032 }, - { 0x0010, 0x0033 }, - { 0x0012, 0x0098 }, - { 0x0013, 0x0112 }, - { 0x0014, 0x008d }, - { 0x0014, 0x008e }, - { 0x0014, 0x008f }, - { 0x0014, 0x0090 }, - { 0x0014, 0x0091 }, - { 0x0014, 0x0092 }, - { 0x0014, 0x0093 }, - { 0x0014, 0x0094 }, - { 0x0014, 0x0095 }, - { 0x0014, 0x0096 }, - { 0x0014, 0x0097 }, - { 0x0014, 0x0098 }, - { 0x0014, 0x0099 }, - { 0x0014, 0x009a }, - { 0x0014, 0x009b }, - { 0x0014, 0x009c }, - { 0x000f, 0x0027 }, - { 0x000f, 0x0028 }, - { 0x000f, 0x0029 }, - { 0x000f, 0x002a }, - { 0x0010, 0x0034 }, - { 0x000f, 0x002b }, - { 0x0011, 0x0055 }, - { 0x0012, 0x0099 }, - { 0x0012, 0x009a }, - { 0x0012, 0x009b }, - { 0x0014, 0x009d }, - { 0x0013, 0x0113 }, - { 0x0014, 0x009e }, - { 0x0014, 0x009f }, - { 0x0014, 0x00a0 }, - { 0x0014, 0x00a1 }, - { 0x0014, 0x00a2 }, - { 0x0014, 0x00a3 }, - { 0x0014, 0x00a4 }, - { 0x0014, 0x00a5 }, - { 0x0014, 0x00a6 }, - { 0x0014, 0x00a7 }, - { 0x0014, 0x00a8 }, - { 0x0014, 0x00a9 }, - { 0x0014, 0x00aa }, - { 0x0014, 0x00ab }, - { 0x0014, 0x00ac }, - { 0x0011, 0x0056 }, - { 0x0010, 0x0035 }, - { 0x0010, 0x0036 }, - { 0x0010, 0x0037 }, - { 0x0011, 0x0057 }, - { 0x0012, 0x009c }, - { 0x0012, 0x009d }, - { 0x0012, 0x009e }, - { 0x0014, 0x00ad }, - { 0x0014, 0x00ae }, - { 0x0014, 0x00af }, - { 0x0014, 0x00b0 }, - { 0x0014, 0x00b1 }, - { 0x0014, 0x00b2 }, - { 0x0014, 0x00b3 }, - { 0x0014, 0x00b4 }, - { 0x0014, 0x00b5 }, - { 0x0014, 0x00b6 }, - { 0x0014, 0x00b7 }, - { 0x0014, 0x00b8 }, - { 0x0014, 0x00b9 }, - { 0x0014, 0x00ba }, - { 0x0014, 0x00bb }, - { 0x0014, 0x00bc }, - { 0x0014, 0x00bd }, - { 0x0014, 0x00be }, - { 0x0014, 0x00bf }, - { 0x0012, 0x009f }, - { 0x0011, 0x0058 }, - { 0x0012, 0x00a0 }, - { 0x0014, 0x00c0 }, - { 0x0011, 0x0059 }, - { 0x0013, 0x0114 }, - { 0x0012, 0x00a1 }, - { 0x0014, 0x00c1 }, - { 0x0013, 0x0115 }, - { 0x0014, 0x00c2 }, - { 0x0014, 0x00c3 }, - { 0x0014, 0x00c4 }, - { 0x0014, 0x00c5 }, - { 0x0014, 0x00c6 }, - { 0x0014, 0x00c7 }, - { 0x0014, 0x00c8 }, - { 0x0014, 0x00c9 }, - { 0x0014, 0x00ca }, - { 0x0014, 0x00cb }, - { 0x0014, 0x00cc }, - { 0x0014, 0x00cd }, - { 0x0014, 0x00ce }, - { 0x0014, 0x00cf }, - { 0x0014, 0x00d0 }, - { 0x0014, 0x00d1 }, - { 0x0014, 0x00d2 }, - { 0x0014, 0x00d3 }, - { 0x0014, 0x00d4 }, - { 0x0014, 0x00d5 }, - { 0x0014, 0x00d6 }, - { 0x0014, 0x00d7 }, - { 0x0014, 0x00d8 }, - { 0x0014, 0x00d9 }, - { 0x0014, 0x00da }, - { 0x0014, 0x00db }, - { 0x0014, 0x00dc }, - { 0x0014, 0x00dd }, - { 0x0014, 0x00de }, - { 0x0014, 0x00df }, - { 0x0014, 0x00e0 }, - { 0x0014, 0x00e1 }, - { 0x0014, 0x00e2 }, - { 0x0014, 0x00e3 }, - { 0x0014, 0x00e4 }, - { 0x0014, 0x00e5 }, - { 0x0014, 0x00e6 }, - { 0x0014, 0x00e7 }, - { 0x0014, 0x00e8 }, - { 0x0014, 0x00e9 }, - { 0x0014, 0x00ea }, - { 0x0014, 0x00eb }, - { 0x0014, 0x00ec }, - { 0x0014, 0x00ed }, - { 0x0014, 0x00ee }, - { 0x0014, 0x00ef }, - { 0x0014, 0x00f0 }, - { 0x0014, 0x00f1 }, - { 0x0014, 0x00f2 }, - { 0x0014, 0x00f3 }, - { 0x0014, 0x00f4 }, - { 0x0014, 0x00f5 }, - { 0x0014, 0x00f6 }, - { 0x0014, 0x00f7 }, - { 0x0014, 0x00f8 }, - { 0x0014, 0x00f9 }, - { 0x0014, 0x00fa }, - { 0x0014, 0x00fb }, - { 0x0014, 0x00fc }, - { 0x0014, 0x00fd }, - { 0x0014, 0x00fe }, - { 0x0014, 0x00ff }, - { 0x0014, 0x0100 }, - { 0x0014, 0x0101 }, - { 0x0014, 0x0102 }, - { 0x0014, 0x0103 }, - { 0x0014, 0x0104 }, - { 0x0014, 0x0105 }, - { 0x0014, 0x0106 }, - { 0x0014, 0x0107 }, - { 0x0014, 0x0108 }, - { 0x0014, 0x0109 }, - { 0x0014, 0x010a }, - { 0x0014, 0x010b }, - { 0x0014, 0x010c }, - { 0x0014, 0x010d }, - { 0x0014, 0x010e }, - { 0x0014, 0x010f }, - { 0x0014, 0x0110 }, - { 0x0014, 0x0111 }, - { 0x0014, 0x0112 }, - { 0x0014, 0x0113 }, - { 0x0014, 0x0114 }, - { 0x0014, 0x0115 }, - { 0x0014, 0x0116 }, - { 0x0014, 0x0117 }, - { 0x0014, 0x0118 }, - { 0x0014, 0x0119 }, - { 0x0014, 0x011a }, - { 0x0014, 0x011b }, - { 0x0014, 0x011c }, - { 0x0014, 0x011d }, - { 0x0014, 0x011e }, - { 0x0014, 0x011f }, - { 0x0014, 0x0120 }, - { 0x0014, 0x0121 }, - { 0x0014, 0x0122 }, - { 0x0014, 0x0123 }, - { 0x0014, 0x0124 }, - { 0x0014, 0x0125 }, - { 0x0013, 0x0116 }, - { 0x0014, 0x0126 }, - { 0x0014, 0x0127 }, - { 0x0014, 0x0128 }, - { 0x0014, 0x0129 }, - { 0x0014, 0x012a }, - { 0x0014, 0x012b }, - { 0x0014, 0x012c }, - { 0x0014, 0x012d }, - { 0x0014, 0x012e }, - { 0x0014, 0x012f }, - { 0x0014, 0x0130 }, - { 0x0014, 0x0131 }, - { 0x0014, 0x0132 }, - { 0x0014, 0x0133 }, - { 0x0014, 0x0134 }, - { 0x0014, 0x0135 }, - { 0x0014, 0x0136 }, - { 0x0014, 0x0137 }, - { 0x0014, 0x0138 }, - { 0x0014, 0x0139 }, - { 0x0014, 0x013a }, - { 0x0014, 0x013b }, - { 0x0014, 0x013c }, - { 0x0014, 0x013d }, - { 0x0014, 0x013e }, - { 0x0014, 0x013f }, - { 0x0014, 0x0140 }, - { 0x0014, 0x0141 }, - { 0x0014, 0x0142 }, - { 0x0014, 0x0143 }, - { 0x0014, 0x0144 }, - { 0x0014, 0x0145 }, - { 0x0014, 0x0146 }, - { 0x0014, 0x0147 }, - { 0x0014, 0x0148 }, - { 0x0014, 0x0149 }, - { 0x0014, 0x014a }, - { 0x0014, 0x014b }, - { 0x0014, 0x014c }, - { 0x0014, 0x014d }, - { 0x0014, 0x014e }, - { 0x0014, 0x014f }, - { 0x0014, 0x0150 }, - { 0x0014, 0x0151 }, - { 0x0014, 0x0152 }, - { 0x0014, 0x0153 }, - { 0x0014, 0x0154 }, - { 0x0014, 0x0155 }, - { 0x0014, 0x0156 }, - { 0x0014, 0x0157 }, - { 0x0014, 0x0158 }, - { 0x0014, 0x0159 }, - { 0x0014, 0x015a }, - { 0x0014, 0x015b }, - { 0x0014, 0x015c }, - { 0x0014, 0x015d }, - { 0x0014, 0x015e }, - { 0x0014, 0x015f }, - { 0x0014, 0x0160 }, - { 0x0014, 0x0161 }, - { 0x0014, 0x0162 }, - { 0x0014, 0x0163 }, - { 0x0014, 0x0164 }, - { 0x0014, 0x0165 }, - { 0x0014, 0x0166 }, - { 0x0014, 0x0167 }, - { 0x0014, 0x0168 }, - { 0x0014, 0x0169 }, - { 0x0014, 0x016a }, - { 0x0014, 0x016b }, - { 0x0014, 0x016c }, - { 0x0014, 0x016d }, - { 0x0014, 0x016e }, - { 0x0014, 0x016f }, - { 0x0014, 0x0170 }, - { 0x0014, 0x0171 }, - { 0x0014, 0x0172 }, - { 0x0014, 0x0173 }, - { 0x0014, 0x0174 }, - { 0x0014, 0x0175 }, - { 0x0014, 0x0176 }, - { 0x0014, 0x0177 }, - { 0x0014, 0x0178 }, - { 0x0014, 0x0179 }, - { 0x0014, 0x017a }, - { 0x0014, 0x017b }, - { 0x0014, 0x017c }, - { 0x0014, 0x017d }, - { 0x0014, 0x017e }, - { 0x0014, 0x017f }, - { 0x0014, 0x0180 }, - { 0x0014, 0x0181 }, - { 0x0014, 0x0182 }, - { 0x0014, 0x0183 }, - { 0x0014, 0x0184 }, - { 0x0014, 0x0185 }, - { 0x0014, 0x0186 }, - { 0x0014, 0x0187 }, - { 0x0014, 0x0188 }, - { 0x0014, 0x0189 }, - { 0x0014, 0x018a }, - { 0x0014, 0x018b }, - { 0x0014, 0x018c }, - { 0x0014, 0x018d }, - { 0x0014, 0x018e }, - { 0x0014, 0x018f }, - { 0x0014, 0x0190 }, - { 0x0014, 0x0191 }, - { 0x0014, 0x0192 }, - { 0x0014, 0x0193 }, - { 0x0014, 0x0194 }, - { 0x0014, 0x0195 }, - { 0x0014, 0x0196 }, - { 0x0014, 0x0197 }, - { 0x0014, 0x0198 }, - { 0x0014, 0x0199 }, - { 0x0014, 0x019a }, - { 0x0014, 0x019b }, - { 0x0014, 0x019c }, - { 0x0014, 0x019d }, - { 0x0014, 0x019e }, - { 0x0014, 0x019f }, - { 0x0014, 0x01a0 }, - { 0x0014, 0x01a1 }, - { 0x0014, 0x01a2 }, - { 0x0014, 0x01a3 }, - { 0x0014, 0x01a4 }, - { 0x0014, 0x01a5 }, - { 0x0014, 0x01a6 }, - { 0x0014, 0x01a7 }, - { 0x0014, 0x01a8 }, - { 0x0014, 0x01a9 }, - { 0x0014, 0x01aa }, - { 0x0014, 0x01ab }, - { 0x0014, 0x01ac }, - { 0x0014, 0x01ad }, - { 0x0014, 0x01ae }, - { 0x0014, 0x01af }, - { 0x0014, 0x01b0 }, - { 0x0014, 0x01b1 }, - { 0x0014, 0x01b2 }, - { 0x0014, 0x01b3 }, - { 0x0014, 0x01b4 }, - { 0x0014, 0x01b5 }, - { 0x0014, 0x01b6 }, - { 0x0014, 0x01b7 }, - { 0x0014, 0x01b8 }, - { 0x0014, 0x01b9 }, - { 0x0014, 0x01ba }, - { 0x0014, 0x01bb }, - { 0x0014, 0x01bc }, - { 0x0014, 0x01bd }, - { 0x0014, 0x01be }, - { 0x0014, 0x01bf }, - { 0x0014, 0x01c0 }, - { 0x0014, 0x01c1 }, - { 0x0014, 0x01c2 }, - { 0x0014, 0x01c3 }, - { 0x0014, 0x01c4 }, - { 0x0014, 0x01c5 }, - { 0x0014, 0x01c6 }, - { 0x0014, 0x01c7 }, - { 0x0014, 0x01c8 }, - { 0x0014, 0x01c9 }, - { 0x0014, 0x01ca }, - { 0x0014, 0x01cb }, - { 0x0014, 0x01cc }, - { 0x0014, 0x01cd }, - { 0x0014, 0x01ce }, - { 0x0014, 0x01cf }, - { 0x0014, 0x01d0 }, - { 0x0014, 0x01d1 }, - { 0x0014, 0x01d2 }, - { 0x0014, 0x01d3 }, - { 0x0014, 0x01d4 }, - { 0x0014, 0x01d5 }, - { 0x0014, 0x01d6 }, - { 0x0014, 0x01d7 }, - { 0x0014, 0x01d8 }, - { 0x0014, 0x01d9 }, - { 0x0014, 0x01da }, - { 0x0014, 0x01db }, - { 0x0014, 0x01dc }, - { 0x0014, 0x01dd }, - { 0x0014, 0x01de }, - { 0x0014, 0x01df }, - { 0x0014, 0x01e0 }, - { 0x0014, 0x01e1 }, - { 0x0014, 0x01e2 }, - { 0x0014, 0x01e3 }, - { 0x0014, 0x01e4 }, - { 0x0014, 0x01e5 }, - { 0x0014, 0x01e6 }, - { 0x0014, 0x01e7 }, - { 0x0014, 0x01e8 }, - { 0x0014, 0x01e9 }, - { 0x0014, 0x01ea }, - { 0x0014, 0x01eb }, - { 0x0014, 0x01ec }, - { 0x0014, 0x01ed }, - { 0x0014, 0x01ee }, - { 0x0014, 0x01ef }, - { 0x0014, 0x01f0 }, - { 0x0014, 0x01f1 }, - { 0x0014, 0x01f2 }, - { 0x0014, 0x01f3 }, - { 0x0014, 0x01f4 }, - { 0x0014, 0x01f5 }, - { 0x0014, 0x01f6 }, - { 0x0014, 0x01f7 }, - { 0x0014, 0x01f8 }, - { 0x0014, 0x01f9 }, - { 0x0014, 0x01fa }, - { 0x0014, 0x01fb }, - { 0x0014, 0x01fc }, - { 0x0014, 0x01fd }, - { 0x0014, 0x01fe }, - { 0x0014, 0x01ff }, - { 0x0014, 0x0200 }, - { 0x0014, 0x0201 }, - { 0x0014, 0x0202 }, - { 0x0014, 0x0203 }, - { 0x0014, 0x0204 }, - { 0x0014, 0x0205 }, - { 0x0014, 0x0206 }, - { 0x0014, 0x0207 }, - { 0x0014, 0x0208 }, - { 0x0014, 0x0209 }, - { 0x0014, 0x020a }, - { 0x0014, 0x020b }, - { 0x0014, 0x020c }, - { 0x0014, 0x020d }, - { 0x0014, 0x020e }, - { 0x0014, 0x020f }, - { 0x0014, 0x0210 }, - { 0x0014, 0x0211 }, - { 0x0014, 0x0212 }, - { 0x0014, 0x0213 }, - { 0x0014, 0x0214 }, - { 0x0014, 0x0215 }, - { 0x0013, 0x0117 }, - - }; - - -const uint16_t c_aauiLCLDHuffEnc17[729][2] = - { - { 0x0006, 0x0012 }, - { 0x0006, 0x0013 }, - { 0x0006, 0x0014 }, - { 0x0006, 0x0015 }, - { 0x0007, 0x000f }, - { 0x0007, 0x0010 }, - { 0x0007, 0x0011 }, - { 0x0008, 0x000e }, - { 0x0008, 0x000f }, - { 0x0009, 0x000f }, - { 0x000a, 0x000f }, - { 0x000c, 0x0011 }, - { 0x000d, 0x0014 }, - { 0x000e, 0x0017 }, - { 0x0010, 0x002d }, - { 0x0011, 0x004c }, - { 0x0012, 0x008a }, - { 0x0014, 0x0000 }, - { 0x0014, 0x0001 }, - { 0x0014, 0x0002 }, - { 0x0014, 0x0003 }, - { 0x0014, 0x0004 }, - { 0x0014, 0x0005 }, - { 0x0014, 0x0006 }, - { 0x0014, 0x0007 }, - { 0x0014, 0x0008 }, - { 0x0014, 0x0009 }, - { 0x0006, 0x0016 }, - { 0x0005, 0x0018 }, - { 0x0005, 0x0019 }, - { 0x0005, 0x001a }, - { 0x0006, 0x0017 }, - { 0x0006, 0x0018 }, - { 0x0006, 0x0019 }, - { 0x0007, 0x0012 }, - { 0x0007, 0x0013 }, - { 0x0008, 0x0010 }, - { 0x000a, 0x0010 }, - { 0x000b, 0x0011 }, - { 0x000c, 0x0012 }, - { 0x000e, 0x0018 }, - { 0x000f, 0x0020 }, - { 0x0011, 0x004d }, - { 0x0013, 0x00e4 }, - { 0x0014, 0x000a }, - { 0x0014, 0x000b }, - { 0x0014, 0x000c }, - { 0x0014, 0x000d }, - { 0x0014, 0x000e }, - { 0x0014, 0x000f }, - { 0x0014, 0x0010 }, - { 0x0014, 0x0011 }, - { 0x0014, 0x0012 }, - { 0x0014, 0x0013 }, - { 0x0006, 0x001a }, - { 0x0005, 0x001b }, - { 0x0005, 0x001c }, - { 0x0005, 0x001d }, - { 0x0006, 0x001b }, - { 0x0006, 0x001c }, - { 0x0006, 0x001d }, - { 0x0007, 0x0014 }, - { 0x0008, 0x0011 }, - { 0x0009, 0x0010 }, - { 0x000a, 0x0011 }, - { 0x000b, 0x0012 }, - { 0x000c, 0x0013 }, - { 0x000e, 0x0019 }, - { 0x000f, 0x0021 }, - { 0x0010, 0x002e }, - { 0x0013, 0x00e5 }, - { 0x0013, 0x00e6 }, - { 0x0014, 0x0014 }, - { 0x0014, 0x0015 }, - { 0x0014, 0x0016 }, - { 0x0014, 0x0017 }, - { 0x0014, 0x0018 }, - { 0x0014, 0x0019 }, - { 0x0014, 0x001a }, - { 0x0014, 0x001b }, - { 0x0014, 0x001c }, - { 0x0006, 0x001e }, - { 0x0005, 0x001e }, - { 0x0005, 0x001f }, - { 0x0006, 0x001f }, - { 0x0006, 0x0020 }, - { 0x0006, 0x0021 }, - { 0x0006, 0x0022 }, - { 0x0007, 0x0015 }, - { 0x0008, 0x0012 }, - { 0x0009, 0x0011 }, - { 0x000a, 0x0012 }, - { 0x000b, 0x0013 }, - { 0x000c, 0x0014 }, - { 0x000e, 0x001a }, - { 0x000f, 0x0022 }, - { 0x0010, 0x002f }, - { 0x0013, 0x00e7 }, - { 0x0013, 0x00e8 }, - { 0x0014, 0x001d }, - { 0x0014, 0x001e }, - { 0x0014, 0x001f }, - { 0x0014, 0x0020 }, - { 0x0014, 0x0021 }, - { 0x0014, 0x0022 }, - { 0x0014, 0x0023 }, - { 0x0014, 0x0024 }, - { 0x0014, 0x0025 }, - { 0x0006, 0x0023 }, - { 0x0006, 0x0024 }, - { 0x0006, 0x0025 }, - { 0x0006, 0x0026 }, - { 0x0006, 0x0027 }, - { 0x0006, 0x0028 }, - { 0x0007, 0x0016 }, - { 0x0007, 0x0017 }, - { 0x0008, 0x0013 }, - { 0x0009, 0x0012 }, - { 0x000a, 0x0013 }, - { 0x000c, 0x0015 }, - { 0x000d, 0x0015 }, - { 0x000f, 0x0023 }, - { 0x0010, 0x0030 }, - { 0x0011, 0x004e }, - { 0x0014, 0x0026 }, - { 0x0014, 0x0027 }, - { 0x0014, 0x0028 }, - { 0x0014, 0x0029 }, - { 0x0014, 0x002a }, - { 0x0014, 0x002b }, - { 0x0014, 0x002c }, - { 0x0014, 0x002d }, - { 0x0014, 0x002e }, - { 0x0014, 0x002f }, - { 0x0014, 0x0030 }, - { 0x0007, 0x0018 }, - { 0x0006, 0x0029 }, - { 0x0006, 0x002a }, - { 0x0006, 0x002b }, - { 0x0006, 0x002c }, - { 0x0007, 0x0019 }, - { 0x0007, 0x001a }, - { 0x0008, 0x0014 }, - { 0x0009, 0x0013 }, - { 0x000a, 0x0014 }, - { 0x000b, 0x0014 }, - { 0x000c, 0x0016 }, - { 0x000d, 0x0016 }, - { 0x000f, 0x0024 }, - { 0x0010, 0x0031 }, - { 0x0011, 0x004f }, - { 0x0014, 0x0031 }, - { 0x0014, 0x0032 }, - { 0x0014, 0x0033 }, - { 0x0014, 0x0034 }, - { 0x0014, 0x0035 }, - { 0x0014, 0x0036 }, - { 0x0014, 0x0037 }, - { 0x0014, 0x0038 }, - { 0x0014, 0x0039 }, - { 0x0014, 0x003a }, - { 0x0014, 0x003b }, - { 0x0007, 0x001b }, - { 0x0006, 0x002d }, - { 0x0006, 0x002e }, - { 0x0006, 0x002f }, - { 0x0007, 0x001c }, - { 0x0007, 0x001d }, - { 0x0008, 0x0015 }, - { 0x0009, 0x0014 }, - { 0x000a, 0x0015 }, - { 0x000a, 0x0016 }, - { 0x000c, 0x0017 }, - { 0x000d, 0x0017 }, - { 0x000e, 0x001b }, - { 0x000f, 0x0025 }, - { 0x0011, 0x0050 }, - { 0x0011, 0x0051 }, - { 0x0014, 0x003c }, - { 0x0014, 0x003d }, - { 0x0014, 0x003e }, - { 0x0014, 0x003f }, - { 0x0014, 0x0040 }, - { 0x0014, 0x0041 }, - { 0x0014, 0x0042 }, - { 0x0014, 0x0043 }, - { 0x0014, 0x0044 }, - { 0x0014, 0x0045 }, - { 0x0014, 0x0046 }, - { 0x0008, 0x0016 }, - { 0x0007, 0x001e }, - { 0x0007, 0x001f }, - { 0x0007, 0x0020 }, - { 0x0007, 0x0021 }, - { 0x0008, 0x0017 }, - { 0x0008, 0x0018 }, - { 0x0009, 0x0015 }, - { 0x000a, 0x0017 }, - { 0x000b, 0x0015 }, - { 0x000c, 0x0018 }, - { 0x000e, 0x001c }, - { 0x000e, 0x001d }, - { 0x0010, 0x0032 }, - { 0x0012, 0x008b }, - { 0x0012, 0x008c }, - { 0x0014, 0x0047 }, - { 0x0014, 0x0048 }, - { 0x0014, 0x0049 }, - { 0x0014, 0x004a }, - { 0x0014, 0x004b }, - { 0x0014, 0x004c }, - { 0x0014, 0x004d }, - { 0x0014, 0x004e }, - { 0x0014, 0x004f }, - { 0x0014, 0x0050 }, - { 0x0014, 0x0051 }, - { 0x0008, 0x0019 }, - { 0x0007, 0x0022 }, - { 0x0007, 0x0023 }, - { 0x0008, 0x001a }, - { 0x0008, 0x001b }, - { 0x0009, 0x0016 }, - { 0x0009, 0x0017 }, - { 0x000a, 0x0018 }, - { 0x000b, 0x0016 }, - { 0x000c, 0x0019 }, - { 0x000d, 0x0018 }, - { 0x000e, 0x001e }, - { 0x0010, 0x0033 }, - { 0x0011, 0x0052 }, - { 0x0014, 0x0052 }, - { 0x0013, 0x00e9 }, - { 0x0014, 0x0053 }, - { 0x0014, 0x0054 }, - { 0x0014, 0x0055 }, - { 0x0014, 0x0056 }, - { 0x0014, 0x0057 }, - { 0x0014, 0x0058 }, - { 0x0014, 0x0059 }, - { 0x0014, 0x005a }, - { 0x0014, 0x005b }, - { 0x0014, 0x005c }, - { 0x0014, 0x005d }, - { 0x0009, 0x0018 }, - { 0x0008, 0x001c }, - { 0x0008, 0x001d }, - { 0x0009, 0x0019 }, - { 0x0009, 0x001a }, - { 0x000a, 0x0019 }, - { 0x000a, 0x001a }, - { 0x000b, 0x0017 }, - { 0x000c, 0x001a }, - { 0x000d, 0x0019 }, - { 0x000e, 0x001f }, - { 0x000f, 0x0026 }, - { 0x0010, 0x0034 }, - { 0x0012, 0x008d }, - { 0x0013, 0x00ea }, - { 0x0014, 0x005e }, - { 0x0014, 0x005f }, - { 0x0014, 0x0060 }, - { 0x0014, 0x0061 }, - { 0x0014, 0x0062 }, - { 0x0014, 0x0063 }, - { 0x0014, 0x0064 }, - { 0x0014, 0x0065 }, - { 0x0014, 0x0066 }, - { 0x0014, 0x0067 }, - { 0x0014, 0x0068 }, - { 0x0014, 0x0069 }, - { 0x000b, 0x0018 }, - { 0x0009, 0x001b }, - { 0x000a, 0x001b }, - { 0x000a, 0x001c }, - { 0x000a, 0x001d }, - { 0x000b, 0x0019 }, - { 0x000b, 0x001a }, - { 0x000c, 0x001b }, - { 0x000d, 0x001a }, - { 0x000e, 0x0020 }, - { 0x000f, 0x0027 }, - { 0x0012, 0x008e }, - { 0x0011, 0x0053 }, - { 0x0013, 0x00eb }, - { 0x0014, 0x006a }, - { 0x0014, 0x006b }, - { 0x0014, 0x006c }, - { 0x0014, 0x006d }, - { 0x0014, 0x006e }, - { 0x0014, 0x006f }, - { 0x0014, 0x0070 }, - { 0x0014, 0x0071 }, - { 0x0014, 0x0072 }, - { 0x0014, 0x0073 }, - { 0x0014, 0x0074 }, - { 0x0014, 0x0075 }, - { 0x0014, 0x0076 }, - { 0x000c, 0x001c }, - { 0x000b, 0x001b }, - { 0x000b, 0x001c }, - { 0x000b, 0x001d }, - { 0x000c, 0x001d }, - { 0x000c, 0x001e }, - { 0x000d, 0x001b }, - { 0x000d, 0x001c }, - { 0x000e, 0x0021 }, - { 0x0010, 0x0035 }, - { 0x0010, 0x0036 }, - { 0x0011, 0x0054 }, - { 0x0013, 0x00ec }, - { 0x0014, 0x0077 }, - { 0x0014, 0x0078 }, - { 0x0014, 0x0079 }, - { 0x0014, 0x007a }, - { 0x0014, 0x007b }, - { 0x0014, 0x007c }, - { 0x0014, 0x007d }, - { 0x0014, 0x007e }, - { 0x0014, 0x007f }, - { 0x0014, 0x0080 }, - { 0x0014, 0x0081 }, - { 0x0014, 0x0082 }, - { 0x0014, 0x0083 }, - { 0x0014, 0x0084 }, - { 0x000d, 0x001d }, - { 0x000c, 0x001f }, - { 0x000c, 0x0020 }, - { 0x000c, 0x0021 }, - { 0x000d, 0x001e }, - { 0x000d, 0x001f }, - { 0x000e, 0x0022 }, - { 0x000f, 0x0028 }, - { 0x0010, 0x0037 }, - { 0x0010, 0x0038 }, - { 0x0010, 0x0039 }, - { 0x0012, 0x008f }, - { 0x0013, 0x00ed }, - { 0x0014, 0x0085 }, - { 0x0014, 0x0086 }, - { 0x0014, 0x0087 }, - { 0x0014, 0x0088 }, - { 0x0014, 0x0089 }, - { 0x0014, 0x008a }, - { 0x0014, 0x008b }, - { 0x0014, 0x008c }, - { 0x0014, 0x008d }, - { 0x0014, 0x008e }, - { 0x0014, 0x008f }, - { 0x0014, 0x0090 }, - { 0x0014, 0x0091 }, - { 0x0014, 0x0092 }, - { 0x000e, 0x0023 }, - { 0x000d, 0x0020 }, - { 0x000d, 0x0021 }, - { 0x000e, 0x0024 }, - { 0x000e, 0x0025 }, - { 0x000e, 0x0026 }, - { 0x000f, 0x0029 }, - { 0x0010, 0x003a }, - { 0x0010, 0x003b }, - { 0x0012, 0x0090 }, - { 0x0014, 0x0093 }, - { 0x0014, 0x0094 }, - { 0x0014, 0x0095 }, - { 0x0014, 0x0096 }, - { 0x0014, 0x0097 }, - { 0x0014, 0x0098 }, - { 0x0014, 0x0099 }, - { 0x0014, 0x009a }, - { 0x0014, 0x009b }, - { 0x0014, 0x009c }, - { 0x0014, 0x009d }, - { 0x0014, 0x009e }, - { 0x0014, 0x009f }, - { 0x0014, 0x00a0 }, - { 0x0014, 0x00a1 }, - { 0x0014, 0x00a2 }, - { 0x0014, 0x00a3 }, - { 0x000f, 0x002a }, - { 0x000e, 0x0027 }, - { 0x000f, 0x002b }, - { 0x000f, 0x002c }, - { 0x000f, 0x002d }, - { 0x0010, 0x003c }, - { 0x0010, 0x003d }, - { 0x0011, 0x0055 }, - { 0x0011, 0x0056 }, - { 0x0014, 0x00a4 }, - { 0x0014, 0x00a5 }, - { 0x0014, 0x00a6 }, - { 0x0014, 0x00a7 }, - { 0x0014, 0x00a8 }, - { 0x0014, 0x00a9 }, - { 0x0014, 0x00aa }, - { 0x0014, 0x00ab }, - { 0x0014, 0x00ac }, - { 0x0014, 0x00ad }, - { 0x0014, 0x00ae }, - { 0x0014, 0x00af }, - { 0x0014, 0x00b0 }, - { 0x0014, 0x00b1 }, - { 0x0014, 0x00b2 }, - { 0x0014, 0x00b3 }, - { 0x0014, 0x00b4 }, - { 0x0014, 0x00b5 }, - { 0x0012, 0x0091 }, - { 0x0010, 0x003e }, - { 0x0010, 0x003f }, - { 0x0011, 0x0057 }, - { 0x0011, 0x0058 }, - { 0x0011, 0x0059 }, - { 0x0012, 0x0092 }, - { 0x0013, 0x00ee }, - { 0x0013, 0x00ef }, - { 0x0012, 0x0093 }, - { 0x0014, 0x00b6 }, - { 0x0014, 0x00b7 }, - { 0x0014, 0x00b8 }, - { 0x0014, 0x00b9 }, - { 0x0014, 0x00ba }, - { 0x0014, 0x00bb }, - { 0x0014, 0x00bc }, - { 0x0014, 0x00bd }, - { 0x0014, 0x00be }, - { 0x0014, 0x00bf }, - { 0x0014, 0x00c0 }, - { 0x0014, 0x00c1 }, - { 0x0014, 0x00c2 }, - { 0x0014, 0x00c3 }, - { 0x0014, 0x00c4 }, - { 0x0014, 0x00c5 }, - { 0x0014, 0x00c6 }, - { 0x0013, 0x00f0 }, - { 0x0012, 0x0094 }, - { 0x0012, 0x0095 }, - { 0x0012, 0x0096 }, - { 0x0014, 0x00c7 }, - { 0x0014, 0x00c8 }, - { 0x0014, 0x00c9 }, - { 0x0014, 0x00ca }, - { 0x0014, 0x00cb }, - { 0x0014, 0x00cc }, - { 0x0014, 0x00cd }, - { 0x0014, 0x00ce }, - { 0x0014, 0x00cf }, - { 0x0014, 0x00d0 }, - { 0x0014, 0x00d1 }, - { 0x0014, 0x00d2 }, - { 0x0014, 0x00d3 }, - { 0x0014, 0x00d4 }, - { 0x0014, 0x00d5 }, - { 0x0014, 0x00d6 }, - { 0x0014, 0x00d7 }, - { 0x0014, 0x00d8 }, - { 0x0014, 0x00d9 }, - { 0x0014, 0x00da }, - { 0x0014, 0x00db }, - { 0x0014, 0x00dc }, - { 0x0014, 0x00dd }, - { 0x0014, 0x00de }, - { 0x0012, 0x0097 }, - { 0x0014, 0x00df }, - { 0x0014, 0x00e0 }, - { 0x0014, 0x00e1 }, - { 0x0014, 0x00e2 }, - { 0x0014, 0x00e3 }, - { 0x0014, 0x00e4 }, - { 0x0014, 0x00e5 }, - { 0x0014, 0x00e6 }, - { 0x0014, 0x00e7 }, - { 0x0014, 0x00e8 }, - { 0x0014, 0x00e9 }, - { 0x0014, 0x00ea }, - { 0x0014, 0x00eb }, - { 0x0014, 0x00ec }, - { 0x0014, 0x00ed }, - { 0x0014, 0x00ee }, - { 0x0014, 0x00ef }, - { 0x0014, 0x00f0 }, - { 0x0014, 0x00f1 }, - { 0x0014, 0x00f2 }, - { 0x0014, 0x00f3 }, - { 0x0014, 0x00f4 }, - { 0x0014, 0x00f5 }, - { 0x0014, 0x00f6 }, - { 0x0014, 0x00f7 }, - { 0x0014, 0x00f8 }, - { 0x0014, 0x00f9 }, - { 0x0014, 0x00fa }, - { 0x0014, 0x00fb }, - { 0x0014, 0x00fc }, - { 0x0014, 0x00fd }, - { 0x0014, 0x00fe }, - { 0x0014, 0x00ff }, - { 0x0014, 0x0100 }, - { 0x0014, 0x0101 }, - { 0x0014, 0x0102 }, - { 0x0014, 0x0103 }, - { 0x0014, 0x0104 }, - { 0x0014, 0x0105 }, - { 0x0014, 0x0106 }, - { 0x0014, 0x0107 }, - { 0x0014, 0x0108 }, - { 0x0014, 0x0109 }, - { 0x0014, 0x010a }, - { 0x0014, 0x010b }, - { 0x0014, 0x010c }, - { 0x0014, 0x010d }, - { 0x0014, 0x010e }, - { 0x0014, 0x010f }, - { 0x0014, 0x0110 }, - { 0x0014, 0x0111 }, - { 0x0014, 0x0112 }, - { 0x0014, 0x0113 }, - { 0x0014, 0x0114 }, - { 0x0014, 0x0115 }, - { 0x0014, 0x0116 }, - { 0x0014, 0x0117 }, - { 0x0014, 0x0118 }, - { 0x0014, 0x0119 }, - { 0x0014, 0x011a }, - { 0x0014, 0x011b }, - { 0x0014, 0x011c }, - { 0x0014, 0x011d }, - { 0x0014, 0x011e }, - { 0x0014, 0x011f }, - { 0x0014, 0x0120 }, - { 0x0014, 0x0121 }, - { 0x0014, 0x0122 }, - { 0x0014, 0x0123 }, - { 0x0014, 0x0124 }, - { 0x0014, 0x0125 }, - { 0x0014, 0x0126 }, - { 0x0014, 0x0127 }, - { 0x0014, 0x0128 }, - { 0x0014, 0x0129 }, - { 0x0014, 0x012a }, - { 0x0014, 0x012b }, - { 0x0014, 0x012c }, - { 0x0014, 0x012d }, - { 0x0014, 0x012e }, - { 0x0014, 0x012f }, - { 0x0014, 0x0130 }, - { 0x0014, 0x0131 }, - { 0x0014, 0x0132 }, - { 0x0014, 0x0133 }, - { 0x0014, 0x0134 }, - { 0x0014, 0x0135 }, - { 0x0014, 0x0136 }, - { 0x0014, 0x0137 }, - { 0x0014, 0x0138 }, - { 0x0014, 0x0139 }, - { 0x0014, 0x013a }, - { 0x0014, 0x013b }, - { 0x0014, 0x013c }, - { 0x0014, 0x013d }, - { 0x0014, 0x013e }, - { 0x0014, 0x013f }, - { 0x0014, 0x0140 }, - { 0x0014, 0x0141 }, - { 0x0014, 0x0142 }, - { 0x0014, 0x0143 }, - { 0x0014, 0x0144 }, - { 0x0014, 0x0145 }, - { 0x0014, 0x0146 }, - { 0x0014, 0x0147 }, - { 0x0014, 0x0148 }, - { 0x0014, 0x0149 }, - { 0x0014, 0x014a }, - { 0x0014, 0x014b }, - { 0x0014, 0x014c }, - { 0x0014, 0x014d }, - { 0x0014, 0x014e }, - { 0x0014, 0x014f }, - { 0x0014, 0x0150 }, - { 0x0014, 0x0151 }, - { 0x0014, 0x0152 }, - { 0x0014, 0x0153 }, - { 0x0014, 0x0154 }, - { 0x0014, 0x0155 }, - { 0x0014, 0x0156 }, - { 0x0014, 0x0157 }, - { 0x0014, 0x0158 }, - { 0x0014, 0x0159 }, - { 0x0014, 0x015a }, - { 0x0014, 0x015b }, - { 0x0014, 0x015c }, - { 0x0014, 0x015d }, - { 0x0014, 0x015e }, - { 0x0014, 0x015f }, - { 0x0014, 0x0160 }, - { 0x0014, 0x0161 }, - { 0x0014, 0x0162 }, - { 0x0014, 0x0163 }, - { 0x0014, 0x0164 }, - { 0x0014, 0x0165 }, - { 0x0014, 0x0166 }, - { 0x0014, 0x0167 }, - { 0x0014, 0x0168 }, - { 0x0014, 0x0169 }, - { 0x0014, 0x016a }, - { 0x0014, 0x016b }, - { 0x0014, 0x016c }, - { 0x0014, 0x016d }, - { 0x0014, 0x016e }, - { 0x0014, 0x016f }, - { 0x0014, 0x0170 }, - { 0x0014, 0x0171 }, - { 0x0014, 0x0172 }, - { 0x0014, 0x0173 }, - { 0x0014, 0x0174 }, - { 0x0014, 0x0175 }, - { 0x0014, 0x0176 }, - { 0x0014, 0x0177 }, - { 0x0014, 0x0178 }, - { 0x0014, 0x0179 }, - { 0x0014, 0x017a }, - { 0x0014, 0x017b }, - { 0x0014, 0x017c }, - { 0x0014, 0x017d }, - { 0x0014, 0x017e }, - { 0x0014, 0x017f }, - { 0x0014, 0x0180 }, - { 0x0014, 0x0181 }, - { 0x0014, 0x0182 }, - { 0x0014, 0x0183 }, - { 0x0014, 0x0184 }, - { 0x0014, 0x0185 }, - { 0x0014, 0x0186 }, - { 0x0014, 0x0187 }, - { 0x0014, 0x0188 }, - { 0x0014, 0x0189 }, - { 0x0014, 0x018a }, - { 0x0014, 0x018b }, - { 0x0014, 0x018c }, - { 0x0014, 0x018d }, - { 0x0014, 0x018e }, - { 0x0014, 0x018f }, - { 0x0014, 0x0190 }, - { 0x0014, 0x0191 }, - { 0x0014, 0x0192 }, - { 0x0014, 0x0193 }, - { 0x0014, 0x0194 }, - { 0x0014, 0x0195 }, - { 0x0014, 0x0196 }, - { 0x0014, 0x0197 }, - { 0x0014, 0x0198 }, - { 0x0014, 0x0199 }, - { 0x0014, 0x019a }, - { 0x0014, 0x019b }, - { 0x0014, 0x019c }, - { 0x0014, 0x019d }, - { 0x0014, 0x019e }, - { 0x0014, 0x019f }, - { 0x0014, 0x01a0 }, - { 0x0014, 0x01a1 }, - { 0x0014, 0x01a2 }, - { 0x0014, 0x01a3 }, - { 0x0014, 0x01a4 }, - { 0x0014, 0x01a5 }, - { 0x0014, 0x01a6 }, - { 0x0014, 0x01a7 }, - { 0x0014, 0x01a8 }, - { 0x0014, 0x01a9 }, - { 0x0014, 0x01aa }, - { 0x0014, 0x01ab }, - { 0x0014, 0x01ac }, - { 0x0014, 0x01ad }, - { 0x0014, 0x01ae }, - { 0x0014, 0x01af }, - { 0x0014, 0x01b0 }, - { 0x0014, 0x01b1 }, - { 0x0014, 0x01b2 }, - { 0x0014, 0x01b3 }, - { 0x0014, 0x01b4 }, - { 0x0014, 0x01b5 }, - { 0x0014, 0x01b6 }, - { 0x0014, 0x01b7 }, - { 0x0014, 0x01b8 }, - { 0x0014, 0x01b9 }, - { 0x0014, 0x01ba }, - { 0x0014, 0x01bb }, - { 0x0014, 0x01bc }, - { 0x0014, 0x01bd }, - { 0x0014, 0x01be }, - { 0x0014, 0x01bf }, - { 0x0014, 0x01c0 }, - { 0x0014, 0x01c1 }, - { 0x0014, 0x01c2 }, - { 0x0014, 0x01c3 }, - { 0x0014, 0x01c4 }, - { 0x0014, 0x01c5 }, - { 0x0014, 0x01c6 }, - { 0x0014, 0x01c7 }, - { 0x0013, 0x00f1 }, - { 0x0013, 0x00f2 }, - { 0x0013, 0x00f3 }, - { 0x0013, 0x00f4 }, - { 0x0013, 0x00f5 }, - { 0x0013, 0x00f6 }, - { 0x0013, 0x00f7 }, - { 0x0013, 0x00f8 }, - { 0x0013, 0x00f9 }, - { 0x0013, 0x00fa }, - { 0x0013, 0x00fb }, - { 0x0013, 0x00fc }, - { 0x0013, 0x00fd }, - { 0x0013, 0x00fe }, - { 0x0013, 0x00ff }, - { 0x0013, 0x0100 }, - { 0x0013, 0x0101 }, - { 0x0013, 0x0102 }, - { 0x0013, 0x0103 }, - { 0x0013, 0x0104 }, - { 0x0013, 0x0105 }, - { 0x0013, 0x0106 }, - { 0x0013, 0x0107 }, - { 0x0013, 0x0108 }, - { 0x0013, 0x0109 }, - { 0x0013, 0x010a }, - { 0x0013, 0x010b }, - { 0x0013, 0x010c }, - { 0x0013, 0x010d }, - { 0x0013, 0x010e }, - { 0x0013, 0x010f }, - { 0x0013, 0x0110 }, - { 0x0013, 0x0111 }, - { 0x0013, 0x0112 }, - { 0x0013, 0x0113 }, - - }; - -const uint16_t c_aauiLCLDHuffEnc18[28][2] = - { - { 0x0004, 0x0001 }, - { 0x0003, 0x0002 }, - { 0x0003, 0x0003 }, - { 0x0003, 0x0004 }, - { 0x0003, 0x0005 }, - { 0x0003, 0x0006 }, - { 0x0003, 0x0007 }, - { 0x0004, 0x0002 }, - { 0x0004, 0x0003 }, - { 0x0005, 0x0001 }, - { 0x0006, 0x0001 }, - { 0x0007, 0x0001 }, - { 0x0008, 0x0001 }, - { 0x0009, 0x0001 }, - { 0x000a, 0x0001 }, - { 0x000b, 0x0001 }, - { 0x000c, 0x0001 }, - { 0x000d, 0x0001 }, - { 0x000e, 0x0001 }, - { 0x000f, 0x0001 }, - { 0x0011, 0x0003 }, - { 0x0012, 0x0001 }, - { 0x0012, 0x0002 }, - { 0x0012, 0x0003 }, - { 0x0013, 0x0000 }, - { 0x0013, 0x0001 }, - { 0x0012, 0x0004 }, - { 0x0012, 0x0005 }, - - }; - - -const uint16_t c_aauiLCLDHuffEnc19[29][2] = - { - { 0x0004, 0x0002 }, - { 0x0003, 0x0003 }, - { 0x0003, 0x0004 }, - { 0x0003, 0x0005 }, - { 0x0003, 0x0006 }, - { 0x0003, 0x0007 }, - { 0x0004, 0x0003 }, - { 0x0004, 0x0004 }, - { 0x0004, 0x0005 }, - { 0x0005, 0x0001 }, - { 0x0005, 0x0002 }, - { 0x0005, 0x0003 }, - { 0x0006, 0x0001 }, - { 0x0007, 0x0001 }, - { 0x0008, 0x0001 }, - { 0x0009, 0x0001 }, - { 0x000a, 0x0001 }, - { 0x000b, 0x0001 }, - { 0x000c, 0x0001 }, - { 0x000d, 0x0001 }, - { 0x000e, 0x0001 }, - { 0x000f, 0x0001 }, - { 0x0010, 0x0001 }, - { 0x0012, 0x0002 }, - { 0x0013, 0x0000 }, - { 0x0013, 0x0001 }, - { 0x0013, 0x0002 }, - { 0x0013, 0x0003 }, - { 0x0012, 0x0003 }, - - }; - -const uint16_t c_aauiLCLDHuffEnc20[32][2] = - { - { 0x0004, 0x0002 }, - { 0x0003, 0x0005 }, - { 0x0003, 0x0006 }, - { 0x0003, 0x0007 }, - { 0x0004, 0x0003 }, - { 0x0004, 0x0004 }, - { 0x0004, 0x0005 }, - { 0x0004, 0x0006 }, - { 0x0004, 0x0007 }, - { 0x0004, 0x0008 }, - { 0x0004, 0x0009 }, - { 0x0005, 0x0002 }, - { 0x0005, 0x0003 }, - { 0x0006, 0x0001 }, - { 0x0006, 0x0002 }, - { 0x0006, 0x0003 }, - { 0x0007, 0x0001 }, - { 0x0008, 0x0001 }, - { 0x0009, 0x0001 }, - { 0x000a, 0x0001 }, - { 0x000b, 0x0001 }, - { 0x000c, 0x0001 }, - { 0x000d, 0x0001 }, - { 0x000e, 0x0001 }, - { 0x000f, 0x0001 }, - { 0x0010, 0x0001 }, - { 0x0011, 0x0001 }, - { 0x0014, 0x0000 }, - { 0x0014, 0x0001 }, - { 0x0013, 0x0001 }, - { 0x0013, 0x0002 }, - { 0x0013, 0x0003 }, - }; - -const uint16_t c_aauiLCLDHuffEnc21[37][2] = - { - { 0x0005, 0x0002 }, - { 0x0003, 0x0006 }, - { 0x0003, 0x0007 }, - { 0x0004, 0x0003 }, - { 0x0004, 0x0004 }, - { 0x0004, 0x0005 }, - { 0x0004, 0x0006 }, - { 0x0004, 0x0007 }, - { 0x0004, 0x0008 }, - { 0x0004, 0x0009 }, - { 0x0004, 0x000a }, - { 0x0004, 0x000b }, - { 0x0005, 0x0003 }, - { 0x0005, 0x0004 }, - { 0x0005, 0x0005 }, - { 0x0006, 0x0002 }, - { 0x0006, 0x0003 }, - { 0x0007, 0x0002 }, - { 0x0007, 0x0003 }, - { 0x0008, 0x0001 }, - { 0x0008, 0x0002 }, - { 0x0008, 0x0003 }, - { 0x0009, 0x0001 }, - { 0x000b, 0x0001 }, - { 0x000b, 0x0002 }, - { 0x000b, 0x0003 }, - { 0x000c, 0x0001 }, - { 0x000d, 0x0001 }, - { 0x000e, 0x0001 }, - { 0x000f, 0x0001 }, - { 0x0010, 0x0001 }, - { 0x0011, 0x0001 }, - { 0x0014, 0x0000 }, - { 0x0014, 0x0001 }, - { 0x0013, 0x0001 }, - { 0x0013, 0x0002 }, - { 0x0013, 0x0003 }, - - }; - -const uint16_t c_aauiLCLDHuffEnc22[39][2] = - { - { 0x0005, 0x0002 }, - { 0x0004, 0x0004 }, - { 0x0004, 0x0005 }, - { 0x0004, 0x0006 }, - { 0x0004, 0x0007 }, - { 0x0004, 0x0008 }, - { 0x0004, 0x0009 }, - { 0x0004, 0x000a }, - { 0x0004, 0x000b }, - { 0x0004, 0x000c }, - { 0x0004, 0x000d }, - { 0x0004, 0x000e }, - { 0x0004, 0x000f }, - { 0x0005, 0x0003 }, - { 0x0005, 0x0004 }, - { 0x0005, 0x0005 }, - { 0x0005, 0x0006 }, - { 0x0005, 0x0007 }, - { 0x0006, 0x0002 }, - { 0x0006, 0x0003 }, - { 0x0007, 0x0002 }, - { 0x0007, 0x0003 }, - { 0x0008, 0x0002 }, - { 0x0008, 0x0003 }, - { 0x0009, 0x0002 }, - { 0x0009, 0x0003 }, - { 0x000a, 0x0001 }, - { 0x000a, 0x0002 }, - { 0x000a, 0x0003 }, - { 0x000c, 0x0001 }, - { 0x000c, 0x0002 }, - { 0x000c, 0x0003 }, - { 0x000e, 0x0001 }, - { 0x000e, 0x0002 }, - { 0x000f, 0x0001 }, - { 0x000e, 0x0003 }, - { 0x0011, 0x0000 }, - { 0x0010, 0x0001 }, - { 0x0011, 0x0001 }, - - }; - -const uint16_t c_aauiLCLDHuffEnc23[46][2] = - { - { 0x0005, 0x0003 }, - { 0x0004, 0x0006 }, - { 0x0004, 0x0007 }, - { 0x0004, 0x0008 }, - { 0x0004, 0x0009 }, - { 0x0004, 0x000a }, - { 0x0004, 0x000b }, - { 0x0004, 0x000c }, - { 0x0004, 0x000d }, - { 0x0004, 0x000e }, - { 0x0004, 0x000f }, - { 0x0005, 0x0004 }, - { 0x0005, 0x0005 }, - { 0x0005, 0x0006 }, - { 0x0005, 0x0007 }, - { 0x0005, 0x0008 }, - { 0x0005, 0x0009 }, - { 0x0005, 0x000a }, - { 0x0005, 0x000b }, - { 0x0006, 0x0003 }, - { 0x0006, 0x0004 }, - { 0x0006, 0x0005 }, - { 0x0007, 0x0002 }, - { 0x0007, 0x0003 }, - { 0x0007, 0x0004 }, - { 0x0007, 0x0005 }, - { 0x0008, 0x0002 }, - { 0x0008, 0x0003 }, - { 0x0009, 0x0002 }, - { 0x0009, 0x0003 }, - { 0x000a, 0x0002 }, - { 0x000a, 0x0003 }, - { 0x000b, 0x0002 }, - { 0x000b, 0x0003 }, - { 0x000c, 0x0002 }, - { 0x000c, 0x0003 }, - { 0x000d, 0x0002 }, - { 0x000d, 0x0003 }, - { 0x000e, 0x0001 }, - { 0x000e, 0x0002 }, - { 0x000e, 0x0003 }, - { 0x000f, 0x0001 }, - { 0x0010, 0x0001 }, - { 0x0012, 0x0000 }, - { 0x0012, 0x0001 }, - { 0x0011, 0x0001 }, - - }; - -const uint16_t c_aauiLCLDHuffEnc24[55][2] = - { - { 0x0005, 0x0004 }, - { 0x0004, 0x0009 }, - { 0x0004, 0x000a }, - { 0x0004, 0x000b }, - { 0x0004, 0x000c }, - { 0x0004, 0x000d }, - { 0x0004, 0x000e }, - { 0x0004, 0x000f }, - { 0x0005, 0x0005 }, - { 0x0005, 0x0006 }, - { 0x0005, 0x0007 }, - { 0x0005, 0x0008 }, - { 0x0005, 0x0009 }, - { 0x0005, 0x000a }, - { 0x0005, 0x000b }, - { 0x0005, 0x000c }, - { 0x0005, 0x000d }, - { 0x0005, 0x000e }, - { 0x0005, 0x000f }, - { 0x0005, 0x0010 }, - { 0x0005, 0x0011 }, - { 0x0006, 0x0003 }, - { 0x0006, 0x0004 }, - { 0x0006, 0x0005 }, - { 0x0006, 0x0006 }, - { 0x0006, 0x0007 }, - { 0x0007, 0x0003 }, - { 0x0007, 0x0004 }, - { 0x0007, 0x0005 }, - { 0x0008, 0x0003 }, - { 0x0008, 0x0004 }, - { 0x0008, 0x0005 }, - { 0x0009, 0x0002 }, - { 0x0009, 0x0003 }, - { 0x0009, 0x0004 }, - { 0x0009, 0x0005 }, - { 0x000a, 0x0002 }, - { 0x000a, 0x0003 }, - { 0x000b, 0x0002 }, - { 0x000b, 0x0003 }, - { 0x000c, 0x0003 }, - { 0x000d, 0x0002 }, - { 0x000d, 0x0003 }, - { 0x000d, 0x0004 }, - { 0x000d, 0x0005 }, - { 0x000e, 0x0002 }, - { 0x000e, 0x0003 }, - { 0x000f, 0x0001 }, - { 0x000f, 0x0002 }, - { 0x000f, 0x0003 }, - { 0x0010, 0x0001 }, - { 0x0011, 0x0001 }, - { 0x0013, 0x0000 }, - { 0x0012, 0x0001 }, - { 0x0013, 0x0001 }, - - }; - -const uint16_t c_aauiLCLDHuffEnc25[65][2] = - { - { 0x0005, 0x0005 }, - { 0x0004, 0x000c }, - { 0x0004, 0x000d }, - { 0x0004, 0x000e }, - { 0x0005, 0x0006 }, - { 0x0004, 0x000f }, - { 0x0005, 0x0007 }, - { 0x0005, 0x0008 }, - { 0x0005, 0x0009 }, - { 0x0005, 0x000a }, - { 0x0005, 0x000b }, - { 0x0005, 0x000c }, - { 0x0005, 0x000d }, - { 0x0005, 0x000e }, - { 0x0005, 0x000f }, - { 0x0005, 0x0010 }, - { 0x0005, 0x0011 }, - { 0x0005, 0x0012 }, - { 0x0005, 0x0013 }, - { 0x0005, 0x0014 }, - { 0x0005, 0x0015 }, - { 0x0005, 0x0016 }, - { 0x0005, 0x0017 }, - { 0x0006, 0x0004 }, - { 0x0006, 0x0005 }, - { 0x0006, 0x0006 }, - { 0x0006, 0x0007 }, - { 0x0006, 0x0008 }, - { 0x0006, 0x0009 }, - { 0x0007, 0x0003 }, - { 0x0007, 0x0004 }, - { 0x0007, 0x0005 }, - { 0x0007, 0x0006 }, - { 0x0007, 0x0007 }, - { 0x0008, 0x0003 }, - { 0x0008, 0x0004 }, - { 0x0008, 0x0005 }, - { 0x0009, 0x0003 }, - { 0x0009, 0x0004 }, - { 0x0009, 0x0005 }, - { 0x000a, 0x0003 }, - { 0x000a, 0x0004 }, - { 0x000a, 0x0005 }, - { 0x000b, 0x0003 }, - { 0x000b, 0x0004 }, - { 0x000b, 0x0005 }, - { 0x000c, 0x0002 }, - { 0x000c, 0x0003 }, - { 0x000c, 0x0004 }, - { 0x000c, 0x0005 }, - { 0x000d, 0x0003 }, - { 0x000e, 0x0003 }, - { 0x000e, 0x0004 }, - { 0x000f, 0x0003 }, - { 0x000e, 0x0005 }, - { 0x000f, 0x0004 }, - { 0x0010, 0x0001 }, - { 0x000f, 0x0005 }, - { 0x0010, 0x0002 }, - { 0x0010, 0x0003 }, - { 0x0010, 0x0004 }, - { 0x0010, 0x0005 }, - { 0x0011, 0x0001 }, - { 0x0012, 0x0000 }, - { 0x0012, 0x0001 }, - - }; - -const uint16_t c_aauiLCLDHuffEnc26[77][2] = - { - { 0x0006, 0x0004 }, - { 0x0005, 0x0007 }, - { 0x0005, 0x0008 }, - { 0x0005, 0x0009 }, - { 0x0005, 0x000a }, - { 0x0005, 0x000b }, - { 0x0005, 0x000c }, - { 0x0005, 0x000d }, - { 0x0005, 0x000e }, - { 0x0005, 0x000f }, - { 0x0005, 0x0010 }, - { 0x0005, 0x0011 }, - { 0x0005, 0x0012 }, - { 0x0005, 0x0013 }, - { 0x0005, 0x0014 }, - { 0x0005, 0x0015 }, - { 0x0005, 0x0016 }, - { 0x0005, 0x0017 }, - { 0x0005, 0x0018 }, - { 0x0005, 0x0019 }, - { 0x0005, 0x001a }, - { 0x0005, 0x001b }, - { 0x0005, 0x001c }, - { 0x0005, 0x001d }, - { 0x0005, 0x001e }, - { 0x0005, 0x001f }, - { 0x0006, 0x0005 }, - { 0x0006, 0x0006 }, - { 0x0006, 0x0007 }, - { 0x0006, 0x0008 }, - { 0x0006, 0x0009 }, - { 0x0006, 0x000a }, - { 0x0006, 0x000b }, - { 0x0006, 0x000c }, - { 0x0006, 0x000d }, - { 0x0007, 0x0004 }, - { 0x0007, 0x0005 }, - { 0x0007, 0x0006 }, - { 0x0007, 0x0007 }, - { 0x0008, 0x0004 }, - { 0x0008, 0x0005 }, - { 0x0008, 0x0006 }, - { 0x0008, 0x0007 }, - { 0x0009, 0x0003 }, - { 0x0009, 0x0004 }, - { 0x0009, 0x0005 }, - { 0x0009, 0x0006 }, - { 0x0009, 0x0007 }, - { 0x000a, 0x0003 }, - { 0x000a, 0x0004 }, - { 0x000a, 0x0005 }, - { 0x000b, 0x0004 }, - { 0x000b, 0x0005 }, - { 0x000c, 0x0003 }, - { 0x000c, 0x0004 }, - { 0x000c, 0x0005 }, - { 0x000c, 0x0006 }, - { 0x000c, 0x0007 }, - { 0x000d, 0x0003 }, - { 0x000d, 0x0004 }, - { 0x000e, 0x0002 }, - { 0x000d, 0x0005 }, - { 0x000e, 0x0003 }, - { 0x000e, 0x0004 }, - { 0x000f, 0x0003 }, - { 0x000e, 0x0005 }, - { 0x0010, 0x0002 }, - { 0x0010, 0x0003 }, - { 0x0010, 0x0004 }, - { 0x0011, 0x0002 }, - { 0x0012, 0x0001 }, - { 0x0010, 0x0005 }, - { 0x0012, 0x0002 }, - { 0x0011, 0x0003 }, - { 0x0012, 0x0003 }, - { 0x0013, 0x0000 }, - { 0x0013, 0x0001 }, - - }; - - -const uint16_t c_aauiLCLDHuffEnc27[91][2] = - { - { 0x0006, 0x0006 }, - { 0x0005, 0x000b }, - { 0x0005, 0x000c }, - { 0x0005, 0x000d }, - { 0x0005, 0x000e }, - { 0x0005, 0x000f }, - { 0x0005, 0x0010 }, - { 0x0005, 0x0011 }, - { 0x0005, 0x0012 }, - { 0x0005, 0x0013 }, - { 0x0005, 0x0014 }, - { 0x0005, 0x0015 }, - { 0x0005, 0x0016 }, - { 0x0005, 0x0017 }, - { 0x0005, 0x0018 }, - { 0x0005, 0x0019 }, - { 0x0005, 0x001a }, - { 0x0005, 0x001b }, - { 0x0005, 0x001c }, - { 0x0005, 0x001d }, - { 0x0005, 0x001e }, - { 0x0005, 0x001f }, - { 0x0006, 0x0007 }, - { 0x0006, 0x0008 }, - { 0x0006, 0x0009 }, - { 0x0006, 0x000a }, - { 0x0006, 0x000b }, - { 0x0006, 0x000c }, - { 0x0006, 0x000d }, - { 0x0006, 0x000e }, - { 0x0006, 0x000f }, - { 0x0006, 0x0010 }, - { 0x0006, 0x0011 }, - { 0x0006, 0x0012 }, - { 0x0006, 0x0013 }, - { 0x0006, 0x0014 }, - { 0x0006, 0x0015 }, - { 0x0007, 0x0005 }, - { 0x0007, 0x0006 }, - { 0x0007, 0x0007 }, - { 0x0007, 0x0008 }, - { 0x0007, 0x0009 }, - { 0x0007, 0x000a }, - { 0x0007, 0x000b }, - { 0x0008, 0x0004 }, - { 0x0008, 0x0005 }, - { 0x0008, 0x0006 }, - { 0x0008, 0x0007 }, - { 0x0008, 0x0008 }, - { 0x0008, 0x0009 }, - { 0x0009, 0x0004 }, - { 0x0009, 0x0005 }, - { 0x0009, 0x0006 }, - { 0x0009, 0x0007 }, - { 0x000a, 0x0004 }, - { 0x000a, 0x0005 }, - { 0x000a, 0x0006 }, - { 0x000a, 0x0007 }, - { 0x000b, 0x0004 }, - { 0x000b, 0x0005 }, - { 0x000b, 0x0006 }, - { 0x000b, 0x0007 }, - { 0x000c, 0x0004 }, - { 0x000c, 0x0005 }, - { 0x000c, 0x0006 }, - { 0x000c, 0x0007 }, - { 0x000d, 0x0004 }, - { 0x000d, 0x0005 }, - { 0x000d, 0x0006 }, - { 0x000d, 0x0007 }, - { 0x000e, 0x0003 }, - { 0x000e, 0x0004 }, - { 0x000e, 0x0005 }, - { 0x000e, 0x0006 }, - { 0x000e, 0x0007 }, - { 0x000f, 0x0003 }, - { 0x000f, 0x0004 }, - { 0x0010, 0x0003 }, - { 0x000f, 0x0005 }, - { 0x0012, 0x0000 }, - { 0x0010, 0x0004 }, - { 0x0010, 0x0005 }, - { 0x0012, 0x0001 }, - { 0x0012, 0x0002 }, - { 0x0011, 0x0004 }, - { 0x0011, 0x0005 }, - { 0x0012, 0x0003 }, - { 0x0012, 0x0004 }, - { 0x0012, 0x0005 }, - { 0x0012, 0x0006 }, - { 0x0012, 0x0007 }, - - }; - -const uint16_t c_aauiLCLDHuffEnc28[109][2] = - { - { 0x0006, 0x0008 }, - { 0x0005, 0x0010 }, - { 0x0005, 0x0011 }, - { 0x0005, 0x0012 }, - { 0x0005, 0x0013 }, - { 0x0005, 0x0014 }, - { 0x0005, 0x0015 }, - { 0x0005, 0x0016 }, - { 0x0005, 0x0017 }, - { 0x0005, 0x0018 }, - { 0x0005, 0x0019 }, - { 0x0005, 0x001a }, - { 0x0005, 0x001b }, - { 0x0005, 0x001c }, - { 0x0005, 0x001d }, - { 0x0005, 0x001e }, - { 0x0006, 0x0009 }, - { 0x0005, 0x001f }, - { 0x0006, 0x000a }, - { 0x0006, 0x000b }, - { 0x0006, 0x000c }, - { 0x0006, 0x000d }, - { 0x0006, 0x000e }, - { 0x0006, 0x000f }, - { 0x0006, 0x0010 }, - { 0x0006, 0x0011 }, - { 0x0006, 0x0012 }, - { 0x0006, 0x0013 }, - { 0x0006, 0x0014 }, - { 0x0006, 0x0015 }, - { 0x0006, 0x0016 }, - { 0x0006, 0x0017 }, - { 0x0006, 0x0018 }, - { 0x0006, 0x0019 }, - { 0x0006, 0x001a }, - { 0x0006, 0x001b }, - { 0x0006, 0x001c }, - { 0x0006, 0x001d }, - { 0x0006, 0x001e }, - { 0x0006, 0x001f }, - { 0x0007, 0x0006 }, - { 0x0007, 0x0007 }, - { 0x0007, 0x0008 }, - { 0x0007, 0x0009 }, - { 0x0007, 0x000a }, - { 0x0007, 0x000b }, - { 0x0007, 0x000c }, - { 0x0007, 0x000d }, - { 0x0007, 0x000e }, - { 0x0007, 0x000f }, - { 0x0008, 0x0005 }, - { 0x0008, 0x0006 }, - { 0x0008, 0x0007 }, - { 0x0008, 0x0008 }, - { 0x0008, 0x0009 }, - { 0x0008, 0x000a }, - { 0x0008, 0x000b }, - { 0x0009, 0x0004 }, - { 0x0009, 0x0005 }, - { 0x0009, 0x0006 }, - { 0x0009, 0x0007 }, - { 0x0009, 0x0008 }, - { 0x0009, 0x0009 }, - { 0x000a, 0x0005 }, - { 0x000a, 0x0006 }, - { 0x000a, 0x0007 }, - { 0x000b, 0x0005 }, - { 0x000b, 0x0006 }, - { 0x000b, 0x0007 }, - { 0x000b, 0x0008 }, - { 0x000b, 0x0009 }, - { 0x000c, 0x0004 }, - { 0x000c, 0x0005 }, - { 0x000c, 0x0006 }, - { 0x000c, 0x0007 }, - { 0x000c, 0x0008 }, - { 0x000c, 0x0009 }, - { 0x000d, 0x0004 }, - { 0x000d, 0x0005 }, - { 0x000d, 0x0006 }, - { 0x000d, 0x0007 }, - { 0x000e, 0x0004 }, - { 0x000e, 0x0005 }, - { 0x000e, 0x0006 }, - { 0x000e, 0x0007 }, - { 0x0010, 0x0004 }, - { 0x000f, 0x0005 }, - { 0x0010, 0x0005 }, - { 0x000f, 0x0006 }, - { 0x000f, 0x0007 }, - { 0x0010, 0x0006 }, - { 0x0011, 0x0006 }, - { 0x0010, 0x0007 }, - { 0x0013, 0x0000 }, - { 0x0010, 0x0008 }, - { 0x0010, 0x0009 }, - { 0x0013, 0x0001 }, - { 0x0011, 0x0007 }, - { 0x0012, 0x0001 }, - { 0x0012, 0x0002 }, - { 0x0012, 0x0003 }, - { 0x0012, 0x0004 }, - { 0x0012, 0x0005 }, - { 0x0012, 0x0006 }, - { 0x0012, 0x0007 }, - { 0x0012, 0x0008 }, - { 0x0012, 0x0009 }, - { 0x0012, 0x000a }, - { 0x0012, 0x000b }, - - }; - -const uint16_t c_aauiLCLDHuffEnc29[129][2] = - { - { 0x0006, 0x0009 }, - { 0x0005, 0x0019 }, - { 0x0006, 0x000a }, - { 0x0005, 0x001a }, - { 0x0005, 0x001b }, - { 0x0005, 0x001c }, - { 0x0006, 0x000b }, - { 0x0005, 0x001d }, - { 0x0005, 0x001e }, - { 0x0006, 0x000c }, - { 0x0006, 0x000d }, - { 0x0005, 0x001f }, - { 0x0006, 0x000e }, - { 0x0006, 0x000f }, - { 0x0006, 0x0010 }, - { 0x0006, 0x0011 }, - { 0x0006, 0x0012 }, - { 0x0006, 0x0013 }, - { 0x0006, 0x0014 }, - { 0x0006, 0x0015 }, - { 0x0006, 0x0016 }, - { 0x0006, 0x0017 }, - { 0x0006, 0x0018 }, - { 0x0006, 0x0019 }, - { 0x0006, 0x001a }, - { 0x0006, 0x001b }, - { 0x0006, 0x001c }, - { 0x0006, 0x001d }, - { 0x0006, 0x001e }, - { 0x0006, 0x001f }, - { 0x0006, 0x0020 }, - { 0x0006, 0x0021 }, - { 0x0006, 0x0022 }, - { 0x0006, 0x0023 }, - { 0x0006, 0x0024 }, - { 0x0006, 0x0025 }, - { 0x0006, 0x0026 }, - { 0x0006, 0x0027 }, - { 0x0006, 0x0028 }, - { 0x0006, 0x0029 }, - { 0x0006, 0x002a }, - { 0x0006, 0x002b }, - { 0x0006, 0x002c }, - { 0x0006, 0x002d }, - { 0x0006, 0x002e }, - { 0x0006, 0x002f }, - { 0x0006, 0x0030 }, - { 0x0006, 0x0031 }, - { 0x0007, 0x0007 }, - { 0x0007, 0x0008 }, - { 0x0007, 0x0009 }, - { 0x0007, 0x000a }, - { 0x0007, 0x000b }, - { 0x0007, 0x000c }, - { 0x0007, 0x000d }, - { 0x0007, 0x000e }, - { 0x0007, 0x000f }, - { 0x0007, 0x0010 }, - { 0x0007, 0x0011 }, - { 0x0008, 0x0006 }, - { 0x0008, 0x0007 }, - { 0x0008, 0x0008 }, - { 0x0008, 0x0009 }, - { 0x0008, 0x000a }, - { 0x0008, 0x000b }, - { 0x0008, 0x000c }, - { 0x0008, 0x000d }, - { 0x0009, 0x0006 }, - { 0x0009, 0x0007 }, - { 0x0009, 0x0008 }, - { 0x0009, 0x0009 }, - { 0x0009, 0x000a }, - { 0x0009, 0x000b }, - { 0x000a, 0x0005 }, - { 0x000a, 0x0006 }, - { 0x000a, 0x0007 }, - { 0x000a, 0x0008 }, - { 0x000a, 0x0009 }, - { 0x000a, 0x000a }, - { 0x000a, 0x000b }, - { 0x000b, 0x0006 }, - { 0x000b, 0x0007 }, - { 0x000b, 0x0008 }, - { 0x000b, 0x0009 }, - { 0x000c, 0x0006 }, - { 0x000c, 0x0007 }, - { 0x000c, 0x0008 }, - { 0x000c, 0x0009 }, - { 0x000c, 0x000a }, - { 0x000c, 0x000b }, - { 0x000d, 0x0005 }, - { 0x000d, 0x0006 }, - { 0x000d, 0x0007 }, - { 0x000d, 0x0008 }, - { 0x000d, 0x0009 }, - { 0x000d, 0x000a }, - { 0x000d, 0x000b }, - { 0x000e, 0x0006 }, - { 0x000e, 0x0007 }, - { 0x000e, 0x0008 }, - { 0x000e, 0x0009 }, - { 0x000f, 0x0004 }, - { 0x000f, 0x0005 }, - { 0x000f, 0x0006 }, - { 0x000f, 0x0007 }, - { 0x0011, 0x0007 }, - { 0x000f, 0x0008 }, - { 0x0012, 0x0000 }, - { 0x000f, 0x0009 }, - { 0x0010, 0x0005 }, - { 0x000f, 0x000a }, - { 0x000f, 0x000b }, - { 0x0012, 0x0001 }, - { 0x0010, 0x0006 }, - { 0x0010, 0x0007 }, - { 0x0012, 0x0002 }, - { 0x0012, 0x0003 }, - { 0x0012, 0x0004 }, - { 0x0012, 0x0005 }, - { 0x0012, 0x0006 }, - { 0x0012, 0x0007 }, - { 0x0012, 0x0008 }, - { 0x0011, 0x0008 }, - { 0x0012, 0x0009 }, - { 0x0012, 0x000a }, - { 0x0012, 0x000b }, - { 0x0012, 0x000c }, - { 0x0012, 0x000d }, - { 0x0011, 0x0009 }, - - }; - -const uint16_t c_aauiLCLDHuffEnc30[153][2] = - { - { 0x0007, 0x0009 }, - { 0x0006, 0x000e }, - { 0x0006, 0x000f }, - { 0x0006, 0x0010 }, - { 0x0006, 0x0011 }, - { 0x0006, 0x0012 }, - { 0x0006, 0x0013 }, - { 0x0006, 0x0014 }, - { 0x0006, 0x0015 }, - { 0x0006, 0x0016 }, - { 0x0006, 0x0017 }, - { 0x0006, 0x0018 }, - { 0x0006, 0x0019 }, - { 0x0006, 0x001a }, - { 0x0006, 0x001b }, - { 0x0006, 0x001c }, - { 0x0006, 0x001d }, - { 0x0006, 0x001e }, - { 0x0006, 0x001f }, - { 0x0006, 0x0020 }, - { 0x0006, 0x0021 }, - { 0x0006, 0x0022 }, - { 0x0006, 0x0023 }, - { 0x0006, 0x0024 }, - { 0x0006, 0x0025 }, - { 0x0006, 0x0026 }, - { 0x0006, 0x0027 }, - { 0x0006, 0x0028 }, - { 0x0006, 0x0029 }, - { 0x0006, 0x002a }, - { 0x0006, 0x002b }, - { 0x0006, 0x002c }, - { 0x0006, 0x002d }, - { 0x0006, 0x002e }, - { 0x0006, 0x002f }, - { 0x0006, 0x0030 }, - { 0x0006, 0x0031 }, - { 0x0006, 0x0032 }, - { 0x0006, 0x0033 }, - { 0x0006, 0x0034 }, - { 0x0006, 0x0035 }, - { 0x0006, 0x0036 }, - { 0x0006, 0x0037 }, - { 0x0006, 0x0038 }, - { 0x0006, 0x0039 }, - { 0x0006, 0x003a }, - { 0x0006, 0x003b }, - { 0x0006, 0x003c }, - { 0x0006, 0x003d }, - { 0x0006, 0x003e }, - { 0x0006, 0x003f }, - { 0x0007, 0x000a }, - { 0x0007, 0x000b }, - { 0x0007, 0x000c }, - { 0x0007, 0x000d }, - { 0x0007, 0x000e }, - { 0x0007, 0x000f }, - { 0x0007, 0x0010 }, - { 0x0007, 0x0011 }, - { 0x0007, 0x0012 }, - { 0x0007, 0x0013 }, - { 0x0007, 0x0014 }, - { 0x0007, 0x0015 }, - { 0x0007, 0x0016 }, - { 0x0007, 0x0017 }, - { 0x0007, 0x0018 }, - { 0x0007, 0x0019 }, - { 0x0007, 0x001a }, - { 0x0007, 0x001b }, - { 0x0008, 0x0008 }, - { 0x0008, 0x0009 }, - { 0x0008, 0x000a }, - { 0x0008, 0x000b }, - { 0x0008, 0x000c }, - { 0x0008, 0x000d }, - { 0x0008, 0x000e }, - { 0x0008, 0x000f }, - { 0x0008, 0x0010 }, - { 0x0008, 0x0011 }, - { 0x0009, 0x0007 }, - { 0x0009, 0x0008 }, - { 0x0009, 0x0009 }, - { 0x0009, 0x000a }, - { 0x0009, 0x000b }, - { 0x0009, 0x000c }, - { 0x0009, 0x000d }, - { 0x0009, 0x000e }, - { 0x000a, 0x0008 }, - { 0x0009, 0x000f }, - { 0x000a, 0x0009 }, - { 0x000a, 0x000a }, - { 0x000a, 0x000b }, - { 0x000a, 0x000c }, - { 0x000a, 0x000d }, - { 0x000b, 0x0007 }, - { 0x000b, 0x0008 }, - { 0x000b, 0x0009 }, - { 0x000b, 0x000a }, - { 0x000b, 0x000b }, - { 0x000b, 0x000c }, - { 0x000b, 0x000d }, - { 0x000c, 0x0008 }, - { 0x000b, 0x000e }, - { 0x000b, 0x000f }, - { 0x000c, 0x0009 }, - { 0x000c, 0x000a }, - { 0x000d, 0x0008 }, - { 0x000c, 0x000b }, - { 0x000c, 0x000c }, - { 0x000d, 0x0009 }, - { 0x000c, 0x000d }, - { 0x000d, 0x000a }, - { 0x000d, 0x000b }, - { 0x000d, 0x000c }, - { 0x000d, 0x000d }, - { 0x000e, 0x0008 }, - { 0x000d, 0x000e }, - { 0x000d, 0x000f }, - { 0x000e, 0x0009 }, - { 0x000e, 0x000a }, - { 0x000e, 0x000b }, - { 0x000e, 0x000c }, - { 0x000f, 0x0006 }, - { 0x000f, 0x0007 }, - { 0x000f, 0x0008 }, - { 0x0010, 0x0006 }, - { 0x000e, 0x000d }, - { 0x000e, 0x000e }, - { 0x000e, 0x000f }, - { 0x0010, 0x0007 }, - { 0x000f, 0x0009 }, - { 0x0010, 0x0008 }, - { 0x000f, 0x000a }, - { 0x000f, 0x000b }, - { 0x000f, 0x000c }, - { 0x000f, 0x000d }, - { 0x0010, 0x0009 }, - { 0x0011, 0x0000 }, - { 0x0011, 0x0001 }, - { 0x0011, 0x0002 }, - { 0x000f, 0x000e }, - { 0x0010, 0x000a }, - { 0x0011, 0x0003 }, - { 0x0011, 0x0004 }, - { 0x0011, 0x0005 }, - { 0x000f, 0x000f }, - { 0x0011, 0x0006 }, - { 0x0011, 0x0007 }, - { 0x0011, 0x0008 }, - { 0x0011, 0x0009 }, - { 0x0011, 0x000a }, - { 0x0011, 0x000b }, - { 0x0010, 0x000b }, - - }; - -const uint16_t c_aauiLCLDHuffEnc31[181][2] = - { - { 0x0007, 0x000b }, - { 0x0006, 0x0015 }, - { 0x0006, 0x0016 }, - { 0x0006, 0x0017 }, - { 0x0006, 0x0018 }, - { 0x0006, 0x0019 }, - { 0x0006, 0x001a }, - { 0x0006, 0x001b }, - { 0x0006, 0x001c }, - { 0x0006, 0x001d }, - { 0x0006, 0x001e }, - { 0x0006, 0x001f }, - { 0x0006, 0x0020 }, - { 0x0006, 0x0021 }, - { 0x0006, 0x0022 }, - { 0x0006, 0x0023 }, - { 0x0006, 0x0024 }, - { 0x0006, 0x0025 }, - { 0x0006, 0x0026 }, - { 0x0006, 0x0027 }, - { 0x0006, 0x0028 }, - { 0x0006, 0x0029 }, - { 0x0006, 0x002a }, - { 0x0006, 0x002b }, - { 0x0006, 0x002c }, - { 0x0006, 0x002d }, - { 0x0006, 0x002e }, - { 0x0006, 0x002f }, - { 0x0006, 0x0030 }, - { 0x0006, 0x0031 }, - { 0x0006, 0x0032 }, - { 0x0006, 0x0033 }, - { 0x0006, 0x0034 }, - { 0x0006, 0x0035 }, - { 0x0006, 0x0036 }, - { 0x0006, 0x0037 }, - { 0x0006, 0x0038 }, - { 0x0006, 0x0039 }, - { 0x0006, 0x003a }, - { 0x0006, 0x003b }, - { 0x0006, 0x003c }, - { 0x0006, 0x003d }, - { 0x0006, 0x003e }, - { 0x0007, 0x000c }, - { 0x0006, 0x003f }, - { 0x0007, 0x000d }, - { 0x0007, 0x000e }, - { 0x0007, 0x000f }, - { 0x0007, 0x0010 }, - { 0x0007, 0x0011 }, - { 0x0007, 0x0012 }, - { 0x0007, 0x0013 }, - { 0x0007, 0x0014 }, - { 0x0007, 0x0015 }, - { 0x0007, 0x0016 }, - { 0x0007, 0x0017 }, - { 0x0007, 0x0018 }, - { 0x0007, 0x0019 }, - { 0x0007, 0x001a }, - { 0x0007, 0x001b }, - { 0x0007, 0x001c }, - { 0x0007, 0x001d }, - { 0x0007, 0x001e }, - { 0x0007, 0x001f }, - { 0x0007, 0x0020 }, - { 0x0007, 0x0021 }, - { 0x0007, 0x0022 }, - { 0x0007, 0x0023 }, - { 0x0007, 0x0024 }, - { 0x0007, 0x0025 }, - { 0x0007, 0x0026 }, - { 0x0007, 0x0027 }, - { 0x0007, 0x0028 }, - { 0x0007, 0x0029 }, - { 0x0008, 0x0009 }, - { 0x0008, 0x000a }, - { 0x0008, 0x000b }, - { 0x0008, 0x000c }, - { 0x0008, 0x000d }, - { 0x0008, 0x000e }, - { 0x0008, 0x000f }, - { 0x0008, 0x0010 }, - { 0x0008, 0x0011 }, - { 0x0008, 0x0012 }, - { 0x0008, 0x0013 }, - { 0x0008, 0x0014 }, - { 0x0008, 0x0015 }, - { 0x0009, 0x0008 }, - { 0x0009, 0x0009 }, - { 0x0009, 0x000a }, - { 0x0009, 0x000b }, - { 0x0009, 0x000c }, - { 0x0009, 0x000d }, - { 0x0009, 0x000e }, - { 0x0009, 0x000f }, - { 0x0009, 0x0010 }, - { 0x0009, 0x0011 }, - { 0x000a, 0x0008 }, - { 0x000a, 0x0009 }, - { 0x000a, 0x000a }, - { 0x000a, 0x000b }, - { 0x000a, 0x000c }, - { 0x000a, 0x000d }, - { 0x000a, 0x000e }, - { 0x000a, 0x000f }, - { 0x000b, 0x0008 }, - { 0x000b, 0x0009 }, - { 0x000b, 0x000a }, - { 0x000b, 0x000b }, - { 0x000b, 0x000c }, - { 0x000b, 0x000d }, - { 0x000b, 0x000e }, - { 0x000c, 0x0008 }, - { 0x000c, 0x0009 }, - { 0x000b, 0x000f }, - { 0x000c, 0x000a }, - { 0x000c, 0x000b }, - { 0x000c, 0x000c }, - { 0x000c, 0x000d }, - { 0x000d, 0x0008 }, - { 0x000c, 0x000e }, - { 0x000d, 0x0009 }, - { 0x000d, 0x000a }, - { 0x000c, 0x000f }, - { 0x000d, 0x000b }, - { 0x000d, 0x000c }, - { 0x000d, 0x000d }, - { 0x000d, 0x000e }, - { 0x000d, 0x000f }, - { 0x000e, 0x0008 }, - { 0x000e, 0x0009 }, - { 0x000e, 0x000a }, - { 0x000e, 0x000b }, - { 0x000e, 0x000c }, - { 0x000e, 0x000d }, - { 0x000e, 0x000e }, - { 0x000e, 0x000f }, - { 0x000f, 0x0009 }, - { 0x000f, 0x000a }, - { 0x000f, 0x000b }, - { 0x000f, 0x000c }, - { 0x0010, 0x0009 }, - { 0x000f, 0x000d }, - { 0x000f, 0x000e }, - { 0x0010, 0x000a }, - { 0x0010, 0x000b }, - { 0x0010, 0x000c }, - { 0x0010, 0x000d }, - { 0x0011, 0x000a }, - { 0x0010, 0x000e }, - { 0x000f, 0x000f }, - { 0x0010, 0x000f }, - { 0x0012, 0x0000 }, - { 0x0012, 0x0001 }, - { 0x0011, 0x000b }, - { 0x0011, 0x000c }, - { 0x0010, 0x0010 }, - { 0x0012, 0x0002 }, - { 0x0012, 0x0003 }, - { 0x0011, 0x000d }, - { 0x0011, 0x000e }, - { 0x0011, 0x000f }, - { 0x0011, 0x0010 }, - { 0x0011, 0x0011 }, - { 0x0010, 0x0011 }, - { 0x0012, 0x0004 }, - { 0x0012, 0x0005 }, - { 0x0012, 0x0006 }, - { 0x0012, 0x0007 }, - { 0x0012, 0x0008 }, - { 0x0012, 0x0009 }, - { 0x0012, 0x000a }, - { 0x0012, 0x000b }, - { 0x0012, 0x000c }, - { 0x0012, 0x000d }, - { 0x0012, 0x000e }, - { 0x0012, 0x000f }, - { 0x0012, 0x0010 }, - { 0x0012, 0x0011 }, - { 0x0012, 0x0012 }, - { 0x0012, 0x0013 }, - - }; - -const uint16_t c_aauiLCLDHuffEnc33[16][2] = - { - { 0x0001, 0x0001 }, - { 0x0003, 0x0001 }, - { 0x0008, 0x0000 }, - { 0x0008, 0x0001 }, - { 0x0002, 0x0001 }, - { 0x0004, 0x0001 }, - { 0x0008, 0x0002 }, - { 0x0008, 0x0003 }, - { 0x0008, 0x0004 }, - { 0x0008, 0x0005 }, - { 0x0008, 0x0006 }, - { 0x0008, 0x0007 }, - { 0x0007, 0x0004 }, - { 0x0007, 0x0005 }, - { 0x0007, 0x0006 }, - { 0x0007, 0x0007 }, - }; - -const uint16_t c_aauiLCLDHuffEnc34[16][2] = - { - { 0x0001, 0x0001 }, - { 0x0003, 0x0001 }, - { 0x0008, 0x0000 }, - { 0x0008, 0x0001 }, - { 0x0002, 0x0001 }, - { 0x0004, 0x0001 }, - { 0x0008, 0x0002 }, - { 0x0008, 0x0003 }, - { 0x0008, 0x0004 }, - { 0x0008, 0x0005 }, - { 0x0008, 0x0006 }, - { 0x0008, 0x0007 }, - { 0x0007, 0x0004 }, - { 0x0007, 0x0005 }, - { 0x0007, 0x0006 }, - { 0x0007, 0x0007 }, - }; - -const uint16_t c_aauiLCLDHuffEnc35[25][2] = - { - { 0x0001, 0x0001 }, - { 0x0003, 0x0001 }, - { 0x0007, 0x0006 }, - { 0x0009, 0x0000 }, - { 0x0009, 0x0001 }, - { 0x0002, 0x0001 }, - { 0x0004, 0x0001 }, - { 0x0009, 0x0002 }, - { 0x0009, 0x0003 }, - { 0x0009, 0x0004 }, - { 0x0007, 0x0007 }, - { 0x0009, 0x0005 }, - { 0x0009, 0x0006 }, - { 0x0009, 0x0007 }, - { 0x0009, 0x0008 }, - { 0x0009, 0x0009 }, - { 0x0009, 0x000a }, - { 0x0009, 0x000b }, - { 0x0009, 0x000c }, - { 0x0009, 0x000d }, - { 0x0008, 0x0007 }, - { 0x0008, 0x0008 }, - { 0x0008, 0x0009 }, - { 0x0008, 0x000a }, - { 0x0008, 0x000b }, - - }; - -const uint16_t c_aauiLCLDHuffEnc36[36][2] = - { - { 0x0001, 0x0001 }, - { 0x0002, 0x0001 }, - { 0x0006, 0x0002 }, - { 0x000b, 0x0000 }, - { 0x000b, 0x0001 }, - { 0x000b, 0x0002 }, - { 0x0003, 0x0001 }, - { 0x0004, 0x0001 }, - { 0x0008, 0x0005 }, - { 0x000b, 0x0003 }, - { 0x000b, 0x0004 }, - { 0x000b, 0x0005 }, - { 0x0006, 0x0003 }, - { 0x0007, 0x0003 }, - { 0x000b, 0x0006 }, - { 0x000b, 0x0007 }, - { 0x000b, 0x0008 }, - { 0x000b, 0x0009 }, - { 0x000b, 0x000a }, - { 0x000b, 0x000b }, - { 0x000b, 0x000c }, - { 0x000b, 0x000d }, - { 0x000b, 0x000e }, - { 0x000b, 0x000f }, - { 0x000a, 0x0008 }, - { 0x000a, 0x0009 }, - { 0x000a, 0x000a }, - { 0x000a, 0x000b }, - { 0x000a, 0x000c }, - { 0x000a, 0x000d }, - { 0x000a, 0x000e }, - { 0x000a, 0x000f }, - { 0x000a, 0x0010 }, - { 0x000a, 0x0011 }, - { 0x000a, 0x0012 }, - { 0x000a, 0x0013 }, - - }; - -const uint16_t c_aauiLCLDHuffEnc37[36][2] = - { - { 0x0001, 0x0001 }, - { 0x0002, 0x0001 }, - { 0x0006, 0x0001 }, - { 0x000c, 0x0000 }, - { 0x000c, 0x0001 }, - { 0x000c, 0x0002 }, - { 0x0003, 0x0001 }, - { 0x0004, 0x0001 }, - { 0x0006, 0x0002 }, - { 0x000c, 0x0003 }, - { 0x000c, 0x0004 }, - { 0x000c, 0x0005 }, - { 0x0006, 0x0003 }, - { 0x0007, 0x0001 }, - { 0x000a, 0x0007 }, - { 0x000c, 0x0006 }, - { 0x000c, 0x0007 }, - { 0x000c, 0x0008 }, - { 0x000c, 0x0009 }, - { 0x000c, 0x000a }, - { 0x000c, 0x000b }, - { 0x000c, 0x000c }, - { 0x000c, 0x000d }, - { 0x000c, 0x000e }, - { 0x000c, 0x000f }, - { 0x000c, 0x0010 }, - { 0x000c, 0x0011 }, - { 0x000c, 0x0012 }, - { 0x000c, 0x0013 }, - { 0x000c, 0x0014 }, - { 0x000c, 0x0015 }, - { 0x000c, 0x0016 }, - { 0x000c, 0x0017 }, - { 0x000c, 0x0018 }, - { 0x000c, 0x0019 }, - { 0x000b, 0x000d }, - - }; - -const uint16_t c_aauiLCLDHuffEnc38[49][2] = - { - { 0x0001, 0x0001 }, - { 0x0003, 0x0001 }, - { 0x0006, 0x0001 }, - { 0x000c, 0x0012 }, - { 0x000d, 0x0000 }, - { 0x000d, 0x0001 }, - { 0x000d, 0x0002 }, - { 0x0002, 0x0001 }, - { 0x0004, 0x0001 }, - { 0x0007, 0x0001 }, - { 0x000b, 0x000a }, - { 0x000d, 0x0003 }, - { 0x000d, 0x0004 }, - { 0x000d, 0x0005 }, - { 0x0006, 0x0002 }, - { 0x0006, 0x0003 }, - { 0x0009, 0x0003 }, - { 0x000d, 0x0006 }, - { 0x000d, 0x0007 }, - { 0x000d, 0x0008 }, - { 0x000d, 0x0009 }, - { 0x000c, 0x0013 }, - { 0x000b, 0x000b }, - { 0x000d, 0x000a }, - { 0x000d, 0x000b }, - { 0x000d, 0x000c }, - { 0x000d, 0x000d }, - { 0x000d, 0x000e }, - { 0x000d, 0x000f }, - { 0x000d, 0x0010 }, - { 0x000d, 0x0011 }, - { 0x000d, 0x0012 }, - { 0x000d, 0x0013 }, - { 0x000d, 0x0014 }, - { 0x000d, 0x0015 }, - { 0x000d, 0x0016 }, - { 0x000d, 0x0017 }, - { 0x000d, 0x0018 }, - { 0x000d, 0x0019 }, - { 0x000d, 0x001a }, - { 0x000d, 0x001b }, - { 0x000d, 0x001c }, - { 0x000d, 0x001d }, - { 0x000d, 0x001e }, - { 0x000d, 0x001f }, - { 0x000d, 0x0020 }, - { 0x000d, 0x0021 }, - { 0x000d, 0x0022 }, - { 0x000d, 0x0023 }, - - }; - -const uint16_t c_aauiLCLDHuffEnc39[64][2] = - { - { 0x0001, 0x0001 }, - { 0x0002, 0x0001 }, - { 0x0006, 0x0001 }, - { 0x000a, 0x0002 }, - { 0x000f, 0x0000 }, - { 0x000f, 0x0001 }, - { 0x000f, 0x0002 }, - { 0x000f, 0x0003 }, - { 0x0003, 0x0001 }, - { 0x0004, 0x0001 }, - { 0x0007, 0x0001 }, - { 0x000a, 0x0003 }, - { 0x000f, 0x0004 }, - { 0x000f, 0x0005 }, - { 0x000f, 0x0006 }, - { 0x000f, 0x0007 }, - { 0x0006, 0x0002 }, - { 0x0006, 0x0003 }, - { 0x0009, 0x0003 }, - { 0x000d, 0x000e }, - { 0x000f, 0x0008 }, - { 0x000f, 0x0009 }, - { 0x000f, 0x000a }, - { 0x000f, 0x000b }, - { 0x000a, 0x0004 }, - { 0x000a, 0x0005 }, - { 0x000d, 0x000f }, - { 0x000f, 0x000c }, - { 0x000f, 0x000d }, - { 0x000f, 0x000e }, - { 0x000f, 0x000f }, - { 0x000f, 0x0010 }, - { 0x000f, 0x0011 }, - { 0x000f, 0x0012 }, - { 0x000f, 0x0013 }, - { 0x000f, 0x0014 }, - { 0x000f, 0x0015 }, - { 0x000f, 0x0016 }, - { 0x000f, 0x0017 }, - { 0x000f, 0x0018 }, - { 0x000f, 0x0019 }, - { 0x000f, 0x001a }, - { 0x000f, 0x001b }, - { 0x000f, 0x001c }, - { 0x000f, 0x001d }, - { 0x000f, 0x001e }, - { 0x000f, 0x001f }, - { 0x000f, 0x0020 }, - { 0x000f, 0x0021 }, - { 0x000f, 0x0022 }, - { 0x000f, 0x0023 }, - { 0x000f, 0x0024 }, - { 0x000f, 0x0025 }, - { 0x000f, 0x0026 }, - { 0x000f, 0x0027 }, - { 0x000f, 0x0028 }, - { 0x000f, 0x0029 }, - { 0x000e, 0x0015 }, - { 0x000e, 0x0016 }, - { 0x000e, 0x0017 }, - { 0x000e, 0x0018 }, - { 0x000e, 0x0019 }, - { 0x000e, 0x001a }, - { 0x000e, 0x001b }, - }; - -const uint16_t c_aauiLCLDHuffEnc40[81][2] = - { - { 0x0001, 0x0001 }, - { 0x0002, 0x0001 }, - { 0x0006, 0x0001 }, - { 0x000b, 0x0002 }, - { 0x000f, 0x0011 }, - { 0x0011, 0x0000 }, - { 0x0011, 0x0001 }, - { 0x0011, 0x0002 }, - { 0x0011, 0x0003 }, - { 0x0003, 0x0001 }, - { 0x0004, 0x0001 }, - { 0x0007, 0x0001 }, - { 0x000a, 0x0002 }, - { 0x000e, 0x0009 }, - { 0x0011, 0x0004 }, - { 0x0011, 0x0005 }, - { 0x0011, 0x0006 }, - { 0x0011, 0x0007 }, - { 0x0006, 0x0002 }, - { 0x0006, 0x0003 }, - { 0x0008, 0x0001 }, - { 0x000d, 0x0005 }, - { 0x0011, 0x0008 }, - { 0x0011, 0x0009 }, - { 0x0011, 0x000a }, - { 0x0011, 0x000b }, - { 0x0011, 0x000c }, - { 0x000b, 0x0003 }, - { 0x000a, 0x0003 }, - { 0x000c, 0x0003 }, - { 0x0011, 0x000d }, - { 0x0011, 0x000e }, - { 0x0011, 0x000f }, - { 0x0011, 0x0010 }, - { 0x0011, 0x0011 }, - { 0x0011, 0x0012 }, - { 0x0011, 0x0013 }, - { 0x0011, 0x0014 }, - { 0x0011, 0x0015 }, - { 0x0011, 0x0016 }, - { 0x0011, 0x0017 }, - { 0x0011, 0x0018 }, - { 0x0011, 0x0019 }, - { 0x0011, 0x001a }, - { 0x0011, 0x001b }, - { 0x0011, 0x001c }, - { 0x0011, 0x001d }, - { 0x0011, 0x001e }, - { 0x0011, 0x001f }, - { 0x0011, 0x0020 }, - { 0x0011, 0x0021 }, - { 0x0011, 0x0022 }, - { 0x0011, 0x0023 }, - { 0x0011, 0x0024 }, - { 0x0011, 0x0025 }, - { 0x0011, 0x0026 }, - { 0x0011, 0x0027 }, - { 0x0011, 0x0028 }, - { 0x0011, 0x0029 }, - { 0x0011, 0x002a }, - { 0x0011, 0x002b }, - { 0x0011, 0x002c }, - { 0x0011, 0x002d }, - { 0x0011, 0x002e }, - { 0x0011, 0x002f }, - { 0x0011, 0x0030 }, - { 0x0011, 0x0031 }, - { 0x0011, 0x0032 }, - { 0x0011, 0x0033 }, - { 0x0011, 0x0034 }, - { 0x0011, 0x0035 }, - { 0x0011, 0x0036 }, - { 0x0011, 0x0037 }, - { 0x0011, 0x0038 }, - { 0x0011, 0x0039 }, - { 0x0011, 0x003a }, - { 0x0011, 0x003b }, - { 0x0010, 0x001e }, - { 0x0010, 0x001f }, - { 0x0010, 0x0020 }, - { 0x0010, 0x0021 }, - - }; - -const uint16_t c_aauiLCLDHuffEnc41[100][2] = - { - { 0x0001, 0x0001 }, - { 0x0003, 0x0001 }, - { 0x0006, 0x0001 }, - { 0x000b, 0x0001 }, - { 0x0011, 0x0014 }, - { 0x0013, 0x0000 }, - { 0x0013, 0x0001 }, - { 0x0013, 0x0002 }, - { 0x0013, 0x0003 }, - { 0x0013, 0x0004 }, - { 0x0002, 0x0001 }, - { 0x0004, 0x0001 }, - { 0x0007, 0x0001 }, - { 0x000a, 0x0001 }, - { 0x0010, 0x000b }, - { 0x0013, 0x0005 }, - { 0x0013, 0x0006 }, - { 0x0013, 0x0007 }, - { 0x0013, 0x0008 }, - { 0x0013, 0x0009 }, - { 0x0006, 0x0002 }, - { 0x0006, 0x0003 }, - { 0x0008, 0x0001 }, - { 0x000d, 0x0002 }, - { 0x0011, 0x0015 }, - { 0x0013, 0x000a }, - { 0x0013, 0x000b }, - { 0x0013, 0x000c }, - { 0x0013, 0x000d }, - { 0x0013, 0x000e }, - { 0x000a, 0x0002 }, - { 0x000a, 0x0003 }, - { 0x000d, 0x0003 }, - { 0x0010, 0x000c }, - { 0x0013, 0x000f }, - { 0x0013, 0x0010 }, - { 0x0013, 0x0011 }, - { 0x0013, 0x0012 }, - { 0x0013, 0x0013 }, - { 0x0013, 0x0014 }, - { 0x0010, 0x000d }, - { 0x000f, 0x0007 }, - { 0x0012, 0x0027 }, - { 0x0013, 0x0015 }, - { 0x0013, 0x0016 }, - { 0x0013, 0x0017 }, - { 0x0013, 0x0018 }, - { 0x0013, 0x0019 }, - { 0x0013, 0x001a }, - { 0x0013, 0x001b }, - { 0x0013, 0x001c }, - { 0x0013, 0x001d }, - { 0x0013, 0x001e }, - { 0x0013, 0x001f }, - { 0x0013, 0x0020 }, - { 0x0013, 0x0021 }, - { 0x0013, 0x0022 }, - { 0x0013, 0x0023 }, - { 0x0013, 0x0024 }, - { 0x0013, 0x0025 }, - { 0x0013, 0x0026 }, - { 0x0013, 0x0027 }, - { 0x0013, 0x0028 }, - { 0x0013, 0x0029 }, - { 0x0013, 0x002a }, - { 0x0013, 0x002b }, - { 0x0013, 0x002c }, - { 0x0013, 0x002d }, - { 0x0013, 0x002e }, - { 0x0013, 0x002f }, - { 0x0013, 0x0030 }, - { 0x0013, 0x0031 }, - { 0x0013, 0x0032 }, - { 0x0013, 0x0033 }, - { 0x0013, 0x0034 }, - { 0x0013, 0x0035 }, - { 0x0013, 0x0036 }, - { 0x0013, 0x0037 }, - { 0x0013, 0x0038 }, - { 0x0013, 0x0039 }, - { 0x0013, 0x003a }, - { 0x0013, 0x003b }, - { 0x0013, 0x003c }, - { 0x0013, 0x003d }, - { 0x0013, 0x003e }, - { 0x0013, 0x003f }, - { 0x0013, 0x0040 }, - { 0x0013, 0x0041 }, - { 0x0013, 0x0042 }, - { 0x0013, 0x0043 }, - { 0x0013, 0x0044 }, - { 0x0013, 0x0045 }, - { 0x0013, 0x0046 }, - { 0x0013, 0x0047 }, - { 0x0013, 0x0048 }, - { 0x0013, 0x0049 }, - { 0x0013, 0x004a }, - { 0x0013, 0x004b }, - { 0x0013, 0x004c }, - { 0x0013, 0x004d }, - - }; - -const uint16_t c_aauiLCLDHuffEnc42[169][2] = - { - { 0x0001, 0x0001 }, - { 0x0003, 0x0001 }, - { 0x0006, 0x0001 }, - { 0x0009, 0x0001 }, - { 0x000e, 0x0006 }, - { 0x0013, 0x0000 }, - { 0x0013, 0x0001 }, - { 0x0013, 0x0002 }, - { 0x0013, 0x0003 }, - { 0x0013, 0x0004 }, - { 0x0013, 0x0005 }, - { 0x0013, 0x0006 }, - { 0x0013, 0x0007 }, - { 0x0003, 0x0002 }, - { 0x0003, 0x0003 }, - { 0x0005, 0x0001 }, - { 0x0009, 0x0002 }, - { 0x000d, 0x0004 }, - { 0x0010, 0x0013 }, - { 0x0013, 0x0008 }, - { 0x0013, 0x0009 }, - { 0x0013, 0x000a }, - { 0x0013, 0x000b }, - { 0x0013, 0x000c }, - { 0x0013, 0x000d }, - { 0x0013, 0x000e }, - { 0x0005, 0x0002 }, - { 0x0005, 0x0003 }, - { 0x0008, 0x0002 }, - { 0x000b, 0x0002 }, - { 0x000f, 0x000b }, - { 0x0011, 0x0025 }, - { 0x0013, 0x000f }, - { 0x0013, 0x0010 }, - { 0x0013, 0x0011 }, - { 0x0013, 0x0012 }, - { 0x0013, 0x0013 }, - { 0x0013, 0x0014 }, - { 0x0013, 0x0015 }, - { 0x0009, 0x0003 }, - { 0x0008, 0x0003 }, - { 0x000b, 0x0003 }, - { 0x000d, 0x0005 }, - { 0x0010, 0x0014 }, - { 0x0013, 0x0016 }, - { 0x0013, 0x0017 }, - { 0x0013, 0x0018 }, - { 0x0013, 0x0019 }, - { 0x0013, 0x001a }, - { 0x0013, 0x001b }, - { 0x0013, 0x001c }, - { 0x0013, 0x001d }, - { 0x000d, 0x0006 }, - { 0x000d, 0x0007 }, - { 0x000e, 0x0007 }, - { 0x0010, 0x0015 }, - { 0x0013, 0x001e }, - { 0x0013, 0x001f }, - { 0x0013, 0x0020 }, - { 0x0013, 0x0021 }, - { 0x0013, 0x0022 }, - { 0x0013, 0x0023 }, - { 0x0013, 0x0024 }, - { 0x0013, 0x0025 }, - { 0x0013, 0x0026 }, - { 0x0012, 0x0045 }, - { 0x0013, 0x0027 }, - { 0x0013, 0x0028 }, - { 0x0013, 0x0029 }, - { 0x0013, 0x002a }, - { 0x0013, 0x002b }, - { 0x0013, 0x002c }, - { 0x0013, 0x002d }, - { 0x0013, 0x002e }, - { 0x0013, 0x002f }, - { 0x0013, 0x0030 }, - { 0x0013, 0x0031 }, - { 0x0013, 0x0032 }, - { 0x0013, 0x0033 }, - { 0x0013, 0x0034 }, - { 0x0013, 0x0035 }, - { 0x0013, 0x0036 }, - { 0x0013, 0x0037 }, - { 0x0013, 0x0038 }, - { 0x0013, 0x0039 }, - { 0x0013, 0x003a }, - { 0x0013, 0x003b }, - { 0x0013, 0x003c }, - { 0x0013, 0x003d }, - { 0x0013, 0x003e }, - { 0x0013, 0x003f }, - { 0x0013, 0x0040 }, - { 0x0013, 0x0041 }, - { 0x0013, 0x0042 }, - { 0x0013, 0x0043 }, - { 0x0013, 0x0044 }, - { 0x0013, 0x0045 }, - { 0x0013, 0x0046 }, - { 0x0013, 0x0047 }, - { 0x0013, 0x0048 }, - { 0x0013, 0x0049 }, - { 0x0013, 0x004a }, - { 0x0013, 0x004b }, - { 0x0013, 0x004c }, - { 0x0013, 0x004d }, - { 0x0013, 0x004e }, - { 0x0013, 0x004f }, - { 0x0013, 0x0050 }, - { 0x0013, 0x0051 }, - { 0x0013, 0x0052 }, - { 0x0013, 0x0053 }, - { 0x0013, 0x0054 }, - { 0x0013, 0x0055 }, - { 0x0013, 0x0056 }, - { 0x0013, 0x0057 }, - { 0x0013, 0x0058 }, - { 0x0013, 0x0059 }, - { 0x0013, 0x005a }, - { 0x0013, 0x005b }, - { 0x0013, 0x005c }, - { 0x0013, 0x005d }, - { 0x0013, 0x005e }, - { 0x0013, 0x005f }, - { 0x0013, 0x0060 }, - { 0x0013, 0x0061 }, - { 0x0013, 0x0062 }, - { 0x0013, 0x0063 }, - { 0x0013, 0x0064 }, - { 0x0013, 0x0065 }, - { 0x0013, 0x0066 }, - { 0x0013, 0x0067 }, - { 0x0013, 0x0068 }, - { 0x0013, 0x0069 }, - { 0x0013, 0x006a }, - { 0x0013, 0x006b }, - { 0x0013, 0x006c }, - { 0x0013, 0x006d }, - { 0x0013, 0x006e }, - { 0x0013, 0x006f }, - { 0x0013, 0x0070 }, - { 0x0013, 0x0071 }, - { 0x0013, 0x0072 }, - { 0x0013, 0x0073 }, - { 0x0013, 0x0074 }, - { 0x0013, 0x0075 }, - { 0x0013, 0x0076 }, - { 0x0013, 0x0077 }, - { 0x0013, 0x0078 }, - { 0x0013, 0x0079 }, - { 0x0013, 0x007a }, - { 0x0013, 0x007b }, - { 0x0013, 0x007c }, - { 0x0013, 0x007d }, - { 0x0013, 0x007e }, - { 0x0013, 0x007f }, - { 0x0013, 0x0080 }, - { 0x0013, 0x0081 }, - { 0x0013, 0x0082 }, - { 0x0013, 0x0083 }, - { 0x0013, 0x0084 }, - { 0x0013, 0x0085 }, - { 0x0013, 0x0086 }, - { 0x0013, 0x0087 }, - { 0x0013, 0x0088 }, - { 0x0013, 0x0089 }, - { 0x0012, 0x0046 }, - { 0x0012, 0x0047 }, - { 0x0012, 0x0048 }, - { 0x0012, 0x0049 }, - - }; - -const uint16_t c_aauiLCLDHuffEnc43[196][2] = - { - { 0x0001, 0x0001 }, - { 0x0003, 0x0001 }, - { 0x0006, 0x0001 }, - { 0x0009, 0x0002 }, - { 0x000c, 0x0003 }, - { 0x0010, 0x0017 }, - { 0x0013, 0x0000 }, - { 0x0013, 0x0001 }, - { 0x0013, 0x0002 }, - { 0x0013, 0x0003 }, - { 0x0013, 0x0004 }, - { 0x0013, 0x0005 }, - { 0x0013, 0x0006 }, - { 0x0013, 0x0007 }, - { 0x0003, 0x0002 }, - { 0x0003, 0x0003 }, - { 0x0005, 0x0001 }, - { 0x0009, 0x0003 }, - { 0x000c, 0x0004 }, - { 0x0010, 0x0018 }, - { 0x0012, 0x0050 }, - { 0x0013, 0x0008 }, - { 0x0013, 0x0009 }, - { 0x0013, 0x000a }, - { 0x0013, 0x000b }, - { 0x0013, 0x000c }, - { 0x0013, 0x000d }, - { 0x0013, 0x000e }, - { 0x0005, 0x0002 }, - { 0x0005, 0x0003 }, - { 0x0008, 0x0003 }, - { 0x000a, 0x0002 }, - { 0x000d, 0x0004 }, - { 0x0011, 0x002a }, - { 0x0013, 0x000f }, - { 0x0013, 0x0010 }, - { 0x0013, 0x0011 }, - { 0x0013, 0x0012 }, - { 0x0013, 0x0013 }, - { 0x0013, 0x0014 }, - { 0x0013, 0x0015 }, - { 0x0013, 0x0016 }, - { 0x0009, 0x0004 }, - { 0x0009, 0x0005 }, - { 0x000a, 0x0003 }, - { 0x000c, 0x0005 }, - { 0x000f, 0x000d }, - { 0x0012, 0x0051 }, - { 0x0013, 0x0017 }, - { 0x0013, 0x0018 }, - { 0x0013, 0x0019 }, - { 0x0013, 0x001a }, - { 0x0013, 0x001b }, - { 0x0013, 0x001c }, - { 0x0013, 0x001d }, - { 0x0013, 0x001e }, - { 0x000c, 0x0006 }, - { 0x000c, 0x0007 }, - { 0x000d, 0x0005 }, - { 0x000f, 0x000e }, - { 0x0011, 0x002b }, - { 0x0013, 0x001f }, - { 0x0013, 0x0020 }, - { 0x0013, 0x0021 }, - { 0x0013, 0x0022 }, - { 0x0013, 0x0023 }, - { 0x0013, 0x0024 }, - { 0x0013, 0x0025 }, - { 0x0013, 0x0026 }, - { 0x0013, 0x0027 }, - { 0x0011, 0x002c }, - { 0x000f, 0x000f }, - { 0x0010, 0x0019 }, - { 0x0012, 0x0052 }, - { 0x0012, 0x0053 }, - { 0x0013, 0x0028 }, - { 0x0013, 0x0029 }, - { 0x0013, 0x002a }, - { 0x0013, 0x002b }, - { 0x0013, 0x002c }, - { 0x0013, 0x002d }, - { 0x0013, 0x002e }, - { 0x0013, 0x002f }, - { 0x0013, 0x0030 }, - { 0x0013, 0x0031 }, - { 0x0011, 0x002d }, - { 0x0013, 0x0032 }, - { 0x0013, 0x0033 }, - { 0x0013, 0x0034 }, - { 0x0013, 0x0035 }, - { 0x0013, 0x0036 }, - { 0x0013, 0x0037 }, - { 0x0013, 0x0038 }, - { 0x0013, 0x0039 }, - { 0x0013, 0x003a }, - { 0x0013, 0x003b }, - { 0x0013, 0x003c }, - { 0x0013, 0x003d }, - { 0x0013, 0x003e }, - { 0x0013, 0x003f }, - { 0x0013, 0x0040 }, - { 0x0013, 0x0041 }, - { 0x0013, 0x0042 }, - { 0x0013, 0x0043 }, - { 0x0013, 0x0044 }, - { 0x0013, 0x0045 }, - { 0x0013, 0x0046 }, - { 0x0013, 0x0047 }, - { 0x0013, 0x0048 }, - { 0x0013, 0x0049 }, - { 0x0013, 0x004a }, - { 0x0013, 0x004b }, - { 0x0013, 0x004c }, - { 0x0013, 0x004d }, - { 0x0013, 0x004e }, - { 0x0013, 0x004f }, - { 0x0013, 0x0050 }, - { 0x0013, 0x0051 }, - { 0x0013, 0x0052 }, - { 0x0013, 0x0053 }, - { 0x0013, 0x0054 }, - { 0x0013, 0x0055 }, - { 0x0013, 0x0056 }, - { 0x0013, 0x0057 }, - { 0x0013, 0x0058 }, - { 0x0013, 0x0059 }, - { 0x0013, 0x005a }, - { 0x0013, 0x005b }, - { 0x0013, 0x005c }, - { 0x0013, 0x005d }, - { 0x0013, 0x005e }, - { 0x0013, 0x005f }, - { 0x0013, 0x0060 }, - { 0x0013, 0x0061 }, - { 0x0013, 0x0062 }, - { 0x0013, 0x0063 }, - { 0x0013, 0x0064 }, - { 0x0013, 0x0065 }, - { 0x0013, 0x0066 }, - { 0x0013, 0x0067 }, - { 0x0013, 0x0068 }, - { 0x0013, 0x0069 }, - { 0x0013, 0x006a }, - { 0x0013, 0x006b }, - { 0x0013, 0x006c }, - { 0x0013, 0x006d }, - { 0x0013, 0x006e }, - { 0x0013, 0x006f }, - { 0x0013, 0x0070 }, - { 0x0013, 0x0071 }, - { 0x0013, 0x0072 }, - { 0x0013, 0x0073 }, - { 0x0013, 0x0074 }, - { 0x0013, 0x0075 }, - { 0x0013, 0x0076 }, - { 0x0013, 0x0077 }, - { 0x0013, 0x0078 }, - { 0x0013, 0x0079 }, - { 0x0013, 0x007a }, - { 0x0013, 0x007b }, - { 0x0013, 0x007c }, - { 0x0013, 0x007d }, - { 0x0013, 0x007e }, - { 0x0013, 0x007f }, - { 0x0013, 0x0080 }, - { 0x0013, 0x0081 }, - { 0x0013, 0x0082 }, - { 0x0013, 0x0083 }, - { 0x0013, 0x0084 }, - { 0x0013, 0x0085 }, - { 0x0013, 0x0086 }, - { 0x0013, 0x0087 }, - { 0x0013, 0x0088 }, - { 0x0013, 0x0089 }, - { 0x0013, 0x008a }, - { 0x0013, 0x008b }, - { 0x0013, 0x008c }, - { 0x0013, 0x008d }, - { 0x0013, 0x008e }, - { 0x0013, 0x008f }, - { 0x0013, 0x0090 }, - { 0x0013, 0x0091 }, - { 0x0013, 0x0092 }, - { 0x0013, 0x0093 }, - { 0x0013, 0x0094 }, - { 0x0013, 0x0095 }, - { 0x0013, 0x0096 }, - { 0x0013, 0x0097 }, - { 0x0013, 0x0098 }, - { 0x0013, 0x0099 }, - { 0x0013, 0x009a }, - { 0x0013, 0x009b }, - { 0x0013, 0x009c }, - { 0x0013, 0x009d }, - { 0x0013, 0x009e }, - { 0x0013, 0x009f }, - - }; - -const uint16_t c_aauiLCLDHuffEnc44[289][2] = - { - { 0x0001, 0x0001 }, - { 0x0003, 0x0001 }, - { 0x0006, 0x0002 }, - { 0x0008, 0x0002 }, - { 0x000b, 0x0002 }, - { 0x000f, 0x000a }, - { 0x0011, 0x0022 }, - { 0x0014, 0x0000 }, - { 0x0014, 0x0001 }, - { 0x0014, 0x0002 }, - { 0x0014, 0x0003 }, - { 0x0014, 0x0004 }, - { 0x0014, 0x0005 }, - { 0x0014, 0x0006 }, - { 0x0014, 0x0007 }, - { 0x0014, 0x0008 }, - { 0x0014, 0x0009 }, - { 0x0003, 0x0002 }, - { 0x0003, 0x0003 }, - { 0x0005, 0x0002 }, - { 0x0008, 0x0003 }, - { 0x000b, 0x0003 }, - { 0x000e, 0x0007 }, - { 0x0012, 0x003f }, - { 0x0014, 0x000a }, - { 0x0014, 0x000b }, - { 0x0014, 0x000c }, - { 0x0014, 0x000d }, - { 0x0014, 0x000e }, - { 0x0014, 0x000f }, - { 0x0014, 0x0010 }, - { 0x0014, 0x0011 }, - { 0x0014, 0x0012 }, - { 0x0014, 0x0013 }, - { 0x0006, 0x0003 }, - { 0x0005, 0x0003 }, - { 0x0007, 0x0003 }, - { 0x0009, 0x0002 }, - { 0x000c, 0x0003 }, - { 0x000f, 0x000b }, - { 0x0012, 0x0040 }, - { 0x0014, 0x0014 }, - { 0x0014, 0x0015 }, - { 0x0014, 0x0016 }, - { 0x0014, 0x0017 }, - { 0x0014, 0x0018 }, - { 0x0014, 0x0019 }, - { 0x0014, 0x001a }, - { 0x0014, 0x001b }, - { 0x0014, 0x001c }, - { 0x0014, 0x001d }, - { 0x0008, 0x0004 }, - { 0x0008, 0x0005 }, - { 0x0009, 0x0003 }, - { 0x000b, 0x0004 }, - { 0x000d, 0x0005 }, - { 0x0010, 0x0013 }, - { 0x0014, 0x001e }, - { 0x0014, 0x001f }, - { 0x0014, 0x0020 }, - { 0x0014, 0x0021 }, - { 0x0014, 0x0022 }, - { 0x0014, 0x0023 }, - { 0x0014, 0x0024 }, - { 0x0014, 0x0025 }, - { 0x0014, 0x0026 }, - { 0x0014, 0x0027 }, - { 0x0014, 0x0028 }, - { 0x000b, 0x0005 }, - { 0x000b, 0x0006 }, - { 0x000b, 0x0007 }, - { 0x000e, 0x0008 }, - { 0x0011, 0x0023 }, - { 0x0012, 0x0041 }, - { 0x0014, 0x0029 }, - { 0x0014, 0x002a }, - { 0x0013, 0x007b }, - { 0x0014, 0x002b }, - { 0x0014, 0x002c }, - { 0x0014, 0x002d }, - { 0x0014, 0x002e }, - { 0x0014, 0x002f }, - { 0x0014, 0x0030 }, - { 0x0014, 0x0031 }, - { 0x0014, 0x0032 }, - { 0x000f, 0x000c }, - { 0x000e, 0x0009 }, - { 0x000f, 0x000d }, - { 0x0011, 0x0024 }, - { 0x0012, 0x0042 }, - { 0x0014, 0x0033 }, - { 0x0014, 0x0034 }, - { 0x0014, 0x0035 }, - { 0x0014, 0x0036 }, - { 0x0014, 0x0037 }, - { 0x0014, 0x0038 }, - { 0x0014, 0x0039 }, - { 0x0014, 0x003a }, - { 0x0014, 0x003b }, - { 0x0014, 0x003c }, - { 0x0014, 0x003d }, - { 0x0014, 0x003e }, - { 0x0013, 0x007c }, - { 0x0011, 0x0025 }, - { 0x0012, 0x0043 }, - { 0x0014, 0x003f }, - { 0x0014, 0x0040 }, - { 0x0014, 0x0041 }, - { 0x0014, 0x0042 }, - { 0x0014, 0x0043 }, - { 0x0014, 0x0044 }, - { 0x0014, 0x0045 }, - { 0x0014, 0x0046 }, - { 0x0014, 0x0047 }, - { 0x0014, 0x0048 }, - { 0x0014, 0x0049 }, - { 0x0014, 0x004a }, - { 0x0014, 0x004b }, - { 0x0014, 0x004c }, - { 0x0014, 0x004d }, - { 0x0014, 0x004e }, - { 0x0014, 0x004f }, - { 0x0014, 0x0050 }, - { 0x0014, 0x0051 }, - { 0x0014, 0x0052 }, - { 0x0014, 0x0053 }, - { 0x0014, 0x0054 }, - { 0x0014, 0x0055 }, - { 0x0014, 0x0056 }, - { 0x0014, 0x0057 }, - { 0x0014, 0x0058 }, - { 0x0014, 0x0059 }, - { 0x0014, 0x005a }, - { 0x0014, 0x005b }, - { 0x0014, 0x005c }, - { 0x0014, 0x005d }, - { 0x0014, 0x005e }, - { 0x0014, 0x005f }, - { 0x0014, 0x0060 }, - { 0x0014, 0x0061 }, - { 0x0014, 0x0062 }, - { 0x0014, 0x0063 }, - { 0x0014, 0x0064 }, - { 0x0014, 0x0065 }, - { 0x0014, 0x0066 }, - { 0x0014, 0x0067 }, - { 0x0014, 0x0068 }, - { 0x0014, 0x0069 }, - { 0x0014, 0x006a }, - { 0x0014, 0x006b }, - { 0x0014, 0x006c }, - { 0x0014, 0x006d }, - { 0x0014, 0x006e }, - { 0x0014, 0x006f }, - { 0x0014, 0x0070 }, - { 0x0014, 0x0071 }, - { 0x0014, 0x0072 }, - { 0x0014, 0x0073 }, - { 0x0014, 0x0074 }, - { 0x0014, 0x0075 }, - { 0x0014, 0x0076 }, - { 0x0014, 0x0077 }, - { 0x0014, 0x0078 }, - { 0x0014, 0x0079 }, - { 0x0014, 0x007a }, - { 0x0014, 0x007b }, - { 0x0014, 0x007c }, - { 0x0014, 0x007d }, - { 0x0014, 0x007e }, - { 0x0014, 0x007f }, - { 0x0014, 0x0080 }, - { 0x0014, 0x0081 }, - { 0x0014, 0x0082 }, - { 0x0014, 0x0083 }, - { 0x0014, 0x0084 }, - { 0x0014, 0x0085 }, - { 0x0014, 0x0086 }, - { 0x0014, 0x0087 }, - { 0x0014, 0x0088 }, - { 0x0014, 0x0089 }, - { 0x0014, 0x008a }, - { 0x0014, 0x008b }, - { 0x0014, 0x008c }, - { 0x0014, 0x008d }, - { 0x0014, 0x008e }, - { 0x0014, 0x008f }, - { 0x0014, 0x0090 }, - { 0x0014, 0x0091 }, - { 0x0014, 0x0092 }, - { 0x0014, 0x0093 }, - { 0x0014, 0x0094 }, - { 0x0014, 0x0095 }, - { 0x0014, 0x0096 }, - { 0x0014, 0x0097 }, - { 0x0014, 0x0098 }, - { 0x0014, 0x0099 }, - { 0x0014, 0x009a }, - { 0x0014, 0x009b }, - { 0x0014, 0x009c }, - { 0x0014, 0x009d }, - { 0x0014, 0x009e }, - { 0x0014, 0x009f }, - { 0x0014, 0x00a0 }, - { 0x0014, 0x00a1 }, - { 0x0014, 0x00a2 }, - { 0x0014, 0x00a3 }, - { 0x0014, 0x00a4 }, - { 0x0014, 0x00a5 }, - { 0x0014, 0x00a6 }, - { 0x0014, 0x00a7 }, - { 0x0014, 0x00a8 }, - { 0x0014, 0x00a9 }, - { 0x0014, 0x00aa }, - { 0x0014, 0x00ab }, - { 0x0014, 0x00ac }, - { 0x0014, 0x00ad }, - { 0x0014, 0x00ae }, - { 0x0014, 0x00af }, - { 0x0014, 0x00b0 }, - { 0x0014, 0x00b1 }, - { 0x0014, 0x00b2 }, - { 0x0014, 0x00b3 }, - { 0x0014, 0x00b4 }, - { 0x0014, 0x00b5 }, - { 0x0014, 0x00b6 }, - { 0x0014, 0x00b7 }, - { 0x0014, 0x00b8 }, - { 0x0014, 0x00b9 }, - { 0x0014, 0x00ba }, - { 0x0014, 0x00bb }, - { 0x0014, 0x00bc }, - { 0x0014, 0x00bd }, - { 0x0014, 0x00be }, - { 0x0014, 0x00bf }, - { 0x0014, 0x00c0 }, - { 0x0014, 0x00c1 }, - { 0x0014, 0x00c2 }, - { 0x0014, 0x00c3 }, - { 0x0014, 0x00c4 }, - { 0x0014, 0x00c5 }, - { 0x0014, 0x00c6 }, - { 0x0014, 0x00c7 }, - { 0x0014, 0x00c8 }, - { 0x0014, 0x00c9 }, - { 0x0014, 0x00ca }, - { 0x0014, 0x00cb }, - { 0x0014, 0x00cc }, - { 0x0014, 0x00cd }, - { 0x0014, 0x00ce }, - { 0x0014, 0x00cf }, - { 0x0014, 0x00d0 }, - { 0x0014, 0x00d1 }, - { 0x0014, 0x00d2 }, - { 0x0014, 0x00d3 }, - { 0x0014, 0x00d4 }, - { 0x0014, 0x00d5 }, - { 0x0014, 0x00d6 }, - { 0x0014, 0x00d7 }, - { 0x0014, 0x00d8 }, - { 0x0014, 0x00d9 }, - { 0x0014, 0x00da }, - { 0x0014, 0x00db }, - { 0x0014, 0x00dc }, - { 0x0014, 0x00dd }, - { 0x0014, 0x00de }, - { 0x0014, 0x00df }, - { 0x0014, 0x00e0 }, - { 0x0014, 0x00e1 }, - { 0x0014, 0x00e2 }, - { 0x0014, 0x00e3 }, - { 0x0014, 0x00e4 }, - { 0x0014, 0x00e5 }, - { 0x0014, 0x00e6 }, - { 0x0014, 0x00e7 }, - { 0x0014, 0x00e8 }, - { 0x0014, 0x00e9 }, - { 0x0014, 0x00ea }, - { 0x0014, 0x00eb }, - { 0x0014, 0x00ec }, - { 0x0014, 0x00ed }, - { 0x0014, 0x00ee }, - { 0x0014, 0x00ef }, - { 0x0014, 0x00f0 }, - { 0x0014, 0x00f1 }, - { 0x0014, 0x00f2 }, - { 0x0014, 0x00f3 }, - { 0x0014, 0x00f4 }, - { 0x0014, 0x00f5 }, - { 0x0013, 0x007d }, - - }; - - -const uint16_t c_aauiLCLDHuffEnc45[324][2] = - { - { 0x0002, 0x0002 }, - { 0x0003, 0x0002 }, - { 0x0005, 0x0003 }, - { 0x0007, 0x0002 }, - { 0x0009, 0x0003 }, - { 0x000c, 0x0005 }, - { 0x0010, 0x0025 }, - { 0x0012, 0x0088 }, - { 0x0013, 0x0000 }, - { 0x0013, 0x0001 }, - { 0x0013, 0x0002 }, - { 0x0013, 0x0003 }, - { 0x0013, 0x0004 }, - { 0x0013, 0x0005 }, - { 0x0013, 0x0006 }, - { 0x0013, 0x0007 }, - { 0x0013, 0x0008 }, - { 0x0013, 0x0009 }, - { 0x0002, 0x0003 }, - { 0x0003, 0x0003 }, - { 0x0005, 0x0004 }, - { 0x0006, 0x0003 }, - { 0x0009, 0x0004 }, - { 0x000b, 0x0004 }, - { 0x000f, 0x0014 }, - { 0x0011, 0x0048 }, - { 0x0013, 0x000a }, - { 0x0013, 0x000b }, - { 0x0013, 0x000c }, - { 0x0013, 0x000d }, - { 0x0013, 0x000e }, - { 0x0013, 0x000f }, - { 0x0013, 0x0010 }, - { 0x0013, 0x0011 }, - { 0x0013, 0x0012 }, - { 0x0013, 0x0013 }, - { 0x0005, 0x0005 }, - { 0x0004, 0x0003 }, - { 0x0006, 0x0004 }, - { 0x0007, 0x0003 }, - { 0x000a, 0x0004 }, - { 0x000d, 0x0007 }, - { 0x000f, 0x0015 }, - { 0x0013, 0x0014 }, - { 0x0013, 0x0015 }, - { 0x0013, 0x0016 }, - { 0x0013, 0x0017 }, - { 0x0013, 0x0018 }, - { 0x0013, 0x0019 }, - { 0x0013, 0x001a }, - { 0x0013, 0x001b }, - { 0x0013, 0x001c }, - { 0x0013, 0x001d }, - { 0x0013, 0x001e }, - { 0x0007, 0x0004 }, - { 0x0006, 0x0005 }, - { 0x0007, 0x0005 }, - { 0x0009, 0x0005 }, - { 0x000b, 0x0005 }, - { 0x000d, 0x0008 }, - { 0x0010, 0x0026 }, - { 0x0012, 0x0089 }, - { 0x0012, 0x008a }, - { 0x0013, 0x001f }, - { 0x0013, 0x0020 }, - { 0x0013, 0x0021 }, - { 0x0013, 0x0022 }, - { 0x0013, 0x0023 }, - { 0x0013, 0x0024 }, - { 0x0013, 0x0025 }, - { 0x0013, 0x0026 }, - { 0x0013, 0x0027 }, - { 0x0009, 0x0006 }, - { 0x0009, 0x0007 }, - { 0x000a, 0x0005 }, - { 0x000b, 0x0006 }, - { 0x000d, 0x0009 }, - { 0x000f, 0x0016 }, - { 0x0011, 0x0049 }, - { 0x0013, 0x0028 }, - { 0x0013, 0x0029 }, - { 0x0013, 0x002a }, - { 0x0013, 0x002b }, - { 0x0013, 0x002c }, - { 0x0013, 0x002d }, - { 0x0013, 0x002e }, - { 0x0013, 0x002f }, - { 0x0013, 0x0030 }, - { 0x0013, 0x0031 }, - { 0x0013, 0x0032 }, - { 0x000c, 0x0006 }, - { 0x000b, 0x0007 }, - { 0x000c, 0x0007 }, - { 0x000e, 0x000d }, - { 0x0010, 0x0027 }, - { 0x0012, 0x008b }, - { 0x0012, 0x008c }, - { 0x0013, 0x0033 }, - { 0x0013, 0x0034 }, - { 0x0013, 0x0035 }, - { 0x0013, 0x0036 }, - { 0x0013, 0x0037 }, - { 0x0013, 0x0038 }, - { 0x0013, 0x0039 }, - { 0x0013, 0x003a }, - { 0x0013, 0x003b }, - { 0x0013, 0x003c }, - { 0x0013, 0x003d }, - { 0x000f, 0x0017 }, - { 0x000f, 0x0018 }, - { 0x000f, 0x0019 }, - { 0x0012, 0x008d }, - { 0x0013, 0x003e }, - { 0x0013, 0x003f }, - { 0x0013, 0x0040 }, - { 0x0013, 0x0041 }, - { 0x0013, 0x0042 }, - { 0x0013, 0x0043 }, - { 0x0013, 0x0044 }, - { 0x0013, 0x0045 }, - { 0x0013, 0x0046 }, - { 0x0013, 0x0047 }, - { 0x0013, 0x0048 }, - { 0x0013, 0x0049 }, - { 0x0013, 0x004a }, - { 0x0013, 0x004b }, - { 0x0013, 0x004c }, - { 0x0012, 0x008e }, - { 0x0012, 0x008f }, - { 0x0013, 0x004d }, - { 0x0013, 0x004e }, - { 0x0013, 0x004f }, - { 0x0013, 0x0050 }, - { 0x0013, 0x0051 }, - { 0x0013, 0x0052 }, - { 0x0013, 0x0053 }, - { 0x0013, 0x0054 }, - { 0x0013, 0x0055 }, - { 0x0013, 0x0056 }, - { 0x0013, 0x0057 }, - { 0x0013, 0x0058 }, - { 0x0013, 0x0059 }, - { 0x0013, 0x005a }, - { 0x0013, 0x005b }, - { 0x0013, 0x005c }, - { 0x0013, 0x005d }, - { 0x0013, 0x005e }, - { 0x0013, 0x005f }, - { 0x0013, 0x0060 }, - { 0x0013, 0x0061 }, - { 0x0013, 0x0062 }, - { 0x0013, 0x0063 }, - { 0x0013, 0x0064 }, - { 0x0013, 0x0065 }, - { 0x0013, 0x0066 }, - { 0x0013, 0x0067 }, - { 0x0013, 0x0068 }, - { 0x0013, 0x0069 }, - { 0x0013, 0x006a }, - { 0x0013, 0x006b }, - { 0x0013, 0x006c }, - { 0x0013, 0x006d }, - { 0x0013, 0x006e }, - { 0x0013, 0x006f }, - { 0x0013, 0x0070 }, - { 0x0013, 0x0071 }, - { 0x0013, 0x0072 }, - { 0x0013, 0x0073 }, - { 0x0013, 0x0074 }, - { 0x0013, 0x0075 }, - { 0x0013, 0x0076 }, - { 0x0013, 0x0077 }, - { 0x0013, 0x0078 }, - { 0x0013, 0x0079 }, - { 0x0013, 0x007a }, - { 0x0013, 0x007b }, - { 0x0013, 0x007c }, - { 0x0013, 0x007d }, - { 0x0013, 0x007e }, - { 0x0013, 0x007f }, - { 0x0013, 0x0080 }, - { 0x0013, 0x0081 }, - { 0x0013, 0x0082 }, - { 0x0013, 0x0083 }, - { 0x0013, 0x0084 }, - { 0x0013, 0x0085 }, - { 0x0013, 0x0086 }, - { 0x0013, 0x0087 }, - { 0x0013, 0x0088 }, - { 0x0013, 0x0089 }, - { 0x0013, 0x008a }, - { 0x0013, 0x008b }, - { 0x0013, 0x008c }, - { 0x0013, 0x008d }, - { 0x0013, 0x008e }, - { 0x0013, 0x008f }, - { 0x0013, 0x0090 }, - { 0x0013, 0x0091 }, - { 0x0013, 0x0092 }, - { 0x0013, 0x0093 }, - { 0x0013, 0x0094 }, - { 0x0013, 0x0095 }, - { 0x0013, 0x0096 }, - { 0x0013, 0x0097 }, - { 0x0013, 0x0098 }, - { 0x0013, 0x0099 }, - { 0x0013, 0x009a }, - { 0x0013, 0x009b }, - { 0x0013, 0x009c }, - { 0x0013, 0x009d }, - { 0x0013, 0x009e }, - { 0x0013, 0x009f }, - { 0x0013, 0x00a0 }, - { 0x0013, 0x00a1 }, - { 0x0013, 0x00a2 }, - { 0x0013, 0x00a3 }, - { 0x0013, 0x00a4 }, - { 0x0013, 0x00a5 }, - { 0x0013, 0x00a6 }, - { 0x0013, 0x00a7 }, - { 0x0013, 0x00a8 }, - { 0x0013, 0x00a9 }, - { 0x0013, 0x00aa }, - { 0x0013, 0x00ab }, - { 0x0013, 0x00ac }, - { 0x0013, 0x00ad }, - { 0x0013, 0x00ae }, - { 0x0013, 0x00af }, - { 0x0013, 0x00b0 }, - { 0x0013, 0x00b1 }, - { 0x0013, 0x00b2 }, - { 0x0013, 0x00b3 }, - { 0x0013, 0x00b4 }, - { 0x0013, 0x00b5 }, - { 0x0013, 0x00b6 }, - { 0x0013, 0x00b7 }, - { 0x0013, 0x00b8 }, - { 0x0013, 0x00b9 }, - { 0x0013, 0x00ba }, - { 0x0013, 0x00bb }, - { 0x0013, 0x00bc }, - { 0x0013, 0x00bd }, - { 0x0013, 0x00be }, - { 0x0013, 0x00bf }, - { 0x0013, 0x00c0 }, - { 0x0013, 0x00c1 }, - { 0x0013, 0x00c2 }, - { 0x0013, 0x00c3 }, - { 0x0013, 0x00c4 }, - { 0x0013, 0x00c5 }, - { 0x0013, 0x00c6 }, - { 0x0013, 0x00c7 }, - { 0x0013, 0x00c8 }, - { 0x0013, 0x00c9 }, - { 0x0013, 0x00ca }, - { 0x0013, 0x00cb }, - { 0x0013, 0x00cc }, - { 0x0013, 0x00cd }, - { 0x0013, 0x00ce }, - { 0x0013, 0x00cf }, - { 0x0013, 0x00d0 }, - { 0x0013, 0x00d1 }, - { 0x0013, 0x00d2 }, - { 0x0013, 0x00d3 }, - { 0x0013, 0x00d4 }, - { 0x0013, 0x00d5 }, - { 0x0013, 0x00d6 }, - { 0x0013, 0x00d7 }, - { 0x0013, 0x00d8 }, - { 0x0013, 0x00d9 }, - { 0x0013, 0x00da }, - { 0x0013, 0x00db }, - { 0x0013, 0x00dc }, - { 0x0013, 0x00dd }, - { 0x0013, 0x00de }, - { 0x0013, 0x00df }, - { 0x0013, 0x00e0 }, - { 0x0013, 0x00e1 }, - { 0x0013, 0x00e2 }, - { 0x0013, 0x00e3 }, - { 0x0013, 0x00e4 }, - { 0x0013, 0x00e5 }, - { 0x0013, 0x00e6 }, - { 0x0013, 0x00e7 }, - { 0x0013, 0x00e8 }, - { 0x0013, 0x00e9 }, - { 0x0013, 0x00ea }, - { 0x0013, 0x00eb }, - { 0x0013, 0x00ec }, - { 0x0013, 0x00ed }, - { 0x0013, 0x00ee }, - { 0x0013, 0x00ef }, - { 0x0013, 0x00f0 }, - { 0x0013, 0x00f1 }, - { 0x0013, 0x00f2 }, - { 0x0013, 0x00f3 }, - { 0x0013, 0x00f4 }, - { 0x0013, 0x00f5 }, - { 0x0013, 0x00f6 }, - { 0x0013, 0x00f7 }, - { 0x0013, 0x00f8 }, - { 0x0013, 0x00f9 }, - { 0x0013, 0x00fa }, - { 0x0013, 0x00fb }, - { 0x0013, 0x00fc }, - { 0x0013, 0x00fd }, - { 0x0013, 0x00fe }, - { 0x0013, 0x00ff }, - { 0x0013, 0x0100 }, - { 0x0013, 0x0101 }, - { 0x0013, 0x0102 }, - { 0x0013, 0x0103 }, - { 0x0013, 0x0104 }, - { 0x0013, 0x0105 }, - { 0x0013, 0x0106 }, - { 0x0013, 0x0107 }, - { 0x0013, 0x0108 }, - { 0x0013, 0x0109 }, - { 0x0013, 0x010a }, - { 0x0013, 0x010b }, - { 0x0013, 0x010c }, - { 0x0013, 0x010d }, - { 0x0013, 0x010e }, - { 0x0013, 0x010f }, - - }; - -const uint16_t c_aauiLCLDHuffEnc46[400][2] = - { - { 0x0002, 0x0002 }, - { 0x0003, 0x0002 }, - { 0x0005, 0x0003 }, - { 0x0007, 0x0004 }, - { 0x0009, 0x0005 }, - { 0x000b, 0x0006 }, - { 0x000d, 0x000a }, - { 0x000f, 0x0018 }, - { 0x0012, 0x00a6 }, - { 0x0013, 0x0000 }, - { 0x0013, 0x0001 }, - { 0x0013, 0x0002 }, - { 0x0013, 0x0003 }, - { 0x0013, 0x0004 }, - { 0x0013, 0x0005 }, - { 0x0013, 0x0006 }, - { 0x0013, 0x0007 }, - { 0x0013, 0x0008 }, - { 0x0013, 0x0009 }, - { 0x0013, 0x000a }, - { 0x0002, 0x0003 }, - { 0x0003, 0x0003 }, - { 0x0005, 0x0004 }, - { 0x0006, 0x0004 }, - { 0x0008, 0x0004 }, - { 0x000a, 0x0006 }, - { 0x000c, 0x0008 }, - { 0x000e, 0x0011 }, - { 0x0012, 0x00a7 }, - { 0x0013, 0x000b }, - { 0x0013, 0x000c }, - { 0x0013, 0x000d }, - { 0x0013, 0x000e }, - { 0x0013, 0x000f }, - { 0x0013, 0x0010 }, - { 0x0013, 0x0011 }, - { 0x0013, 0x0012 }, - { 0x0013, 0x0013 }, - { 0x0013, 0x0014 }, - { 0x0013, 0x0015 }, - { 0x0005, 0x0005 }, - { 0x0005, 0x0006 }, - { 0x0005, 0x0007 }, - { 0x0007, 0x0005 }, - { 0x0009, 0x0006 }, - { 0x000b, 0x0007 }, - { 0x000d, 0x000b }, - { 0x000f, 0x0019 }, - { 0x0013, 0x0016 }, - { 0x0013, 0x0017 }, - { 0x0013, 0x0018 }, - { 0x0013, 0x0019 }, - { 0x0013, 0x001a }, - { 0x0013, 0x001b }, - { 0x0013, 0x001c }, - { 0x0013, 0x001d }, - { 0x0013, 0x001e }, - { 0x0013, 0x001f }, - { 0x0013, 0x0020 }, - { 0x0013, 0x0021 }, - { 0x0007, 0x0006 }, - { 0x0006, 0x0005 }, - { 0x0007, 0x0007 }, - { 0x0008, 0x0005 }, - { 0x000a, 0x0007 }, - { 0x000c, 0x0009 }, - { 0x000e, 0x0012 }, - { 0x000f, 0x001a }, - { 0x0012, 0x00a8 }, - { 0x0013, 0x0022 }, - { 0x0013, 0x0023 }, - { 0x0013, 0x0024 }, - { 0x0013, 0x0025 }, - { 0x0013, 0x0026 }, - { 0x0013, 0x0027 }, - { 0x0013, 0x0028 }, - { 0x0013, 0x0029 }, - { 0x0013, 0x002a }, - { 0x0013, 0x002b }, - { 0x0013, 0x002c }, - { 0x0009, 0x0007 }, - { 0x0008, 0x0006 }, - { 0x0008, 0x0007 }, - { 0x000a, 0x0008 }, - { 0x000b, 0x0008 }, - { 0x000d, 0x000c }, - { 0x000e, 0x0013 }, - { 0x0010, 0x002c }, - { 0x0013, 0x002d }, - { 0x0013, 0x002e }, - { 0x0013, 0x002f }, - { 0x0013, 0x0030 }, - { 0x0013, 0x0031 }, - { 0x0013, 0x0032 }, - { 0x0013, 0x0033 }, - { 0x0013, 0x0034 }, - { 0x0013, 0x0035 }, - { 0x0013, 0x0036 }, - { 0x0013, 0x0037 }, - { 0x0013, 0x0038 }, - { 0x000b, 0x0009 }, - { 0x000a, 0x0009 }, - { 0x000b, 0x000a }, - { 0x000b, 0x000b }, - { 0x000d, 0x000d }, - { 0x000f, 0x001b }, - { 0x0010, 0x002d }, - { 0x0013, 0x0039 }, - { 0x0013, 0x003a }, - { 0x0013, 0x003b }, - { 0x0013, 0x003c }, - { 0x0013, 0x003d }, - { 0x0013, 0x003e }, - { 0x0013, 0x003f }, - { 0x0013, 0x0040 }, - { 0x0013, 0x0041 }, - { 0x0013, 0x0042 }, - { 0x0013, 0x0043 }, - { 0x0013, 0x0044 }, - { 0x0013, 0x0045 }, - { 0x000d, 0x000e }, - { 0x000c, 0x000a }, - { 0x000c, 0x000b }, - { 0x000d, 0x000f }, - { 0x000f, 0x001c }, - { 0x000f, 0x001d }, - { 0x0013, 0x0046 }, - { 0x0013, 0x0047 }, - { 0x0013, 0x0048 }, - { 0x0013, 0x0049 }, - { 0x0013, 0x004a }, - { 0x0013, 0x004b }, - { 0x0013, 0x004c }, - { 0x0013, 0x004d }, - { 0x0013, 0x004e }, - { 0x0013, 0x004f }, - { 0x0013, 0x0050 }, - { 0x0013, 0x0051 }, - { 0x0013, 0x0052 }, - { 0x0013, 0x0053 }, - { 0x000f, 0x001e }, - { 0x000f, 0x001f }, - { 0x000f, 0x0020 }, - { 0x000f, 0x0021 }, - { 0x0010, 0x002e }, - { 0x0012, 0x00a9 }, - { 0x0013, 0x0054 }, - { 0x0013, 0x0055 }, - { 0x0012, 0x00aa }, - { 0x0013, 0x0056 }, - { 0x0013, 0x0057 }, - { 0x0013, 0x0058 }, - { 0x0013, 0x0059 }, - { 0x0013, 0x005a }, - { 0x0013, 0x005b }, - { 0x0013, 0x005c }, - { 0x0013, 0x005d }, - { 0x0013, 0x005e }, - { 0x0013, 0x005f }, - { 0x0013, 0x0060 }, - { 0x0013, 0x0061 }, - { 0x0010, 0x002f }, - { 0x0013, 0x0062 }, - { 0x0011, 0x0057 }, - { 0x0013, 0x0063 }, - { 0x0013, 0x0064 }, - { 0x0013, 0x0065 }, - { 0x0013, 0x0066 }, - { 0x0013, 0x0067 }, - { 0x0013, 0x0068 }, - { 0x0013, 0x0069 }, - { 0x0013, 0x006a }, - { 0x0013, 0x006b }, - { 0x0013, 0x006c }, - { 0x0013, 0x006d }, - { 0x0013, 0x006e }, - { 0x0013, 0x006f }, - { 0x0013, 0x0070 }, - { 0x0013, 0x0071 }, - { 0x0013, 0x0072 }, - { 0x0013, 0x0073 }, - { 0x0013, 0x0074 }, - { 0x0013, 0x0075 }, - { 0x0013, 0x0076 }, - { 0x0013, 0x0077 }, - { 0x0013, 0x0078 }, - { 0x0013, 0x0079 }, - { 0x0013, 0x007a }, - { 0x0013, 0x007b }, - { 0x0013, 0x007c }, - { 0x0013, 0x007d }, - { 0x0013, 0x007e }, - { 0x0013, 0x007f }, - { 0x0013, 0x0080 }, - { 0x0013, 0x0081 }, - { 0x0013, 0x0082 }, - { 0x0013, 0x0083 }, - { 0x0013, 0x0084 }, - { 0x0013, 0x0085 }, - { 0x0013, 0x0086 }, - { 0x0013, 0x0087 }, - { 0x0013, 0x0088 }, - { 0x0013, 0x0089 }, - { 0x0013, 0x008a }, - { 0x0013, 0x008b }, - { 0x0013, 0x008c }, - { 0x0013, 0x008d }, - { 0x0013, 0x008e }, - { 0x0013, 0x008f }, - { 0x0013, 0x0090 }, - { 0x0013, 0x0091 }, - { 0x0013, 0x0092 }, - { 0x0013, 0x0093 }, - { 0x0013, 0x0094 }, - { 0x0013, 0x0095 }, - { 0x0013, 0x0096 }, - { 0x0013, 0x0097 }, - { 0x0013, 0x0098 }, - { 0x0013, 0x0099 }, - { 0x0013, 0x009a }, - { 0x0013, 0x009b }, - { 0x0013, 0x009c }, - { 0x0013, 0x009d }, - { 0x0013, 0x009e }, - { 0x0013, 0x009f }, - { 0x0013, 0x00a0 }, - { 0x0013, 0x00a1 }, - { 0x0013, 0x00a2 }, - { 0x0013, 0x00a3 }, - { 0x0013, 0x00a4 }, - { 0x0013, 0x00a5 }, - { 0x0013, 0x00a6 }, - { 0x0013, 0x00a7 }, - { 0x0013, 0x00a8 }, - { 0x0013, 0x00a9 }, - { 0x0013, 0x00aa }, - { 0x0013, 0x00ab }, - { 0x0013, 0x00ac }, - { 0x0013, 0x00ad }, - { 0x0013, 0x00ae }, - { 0x0013, 0x00af }, - { 0x0013, 0x00b0 }, - { 0x0013, 0x00b1 }, - { 0x0013, 0x00b2 }, - { 0x0013, 0x00b3 }, - { 0x0013, 0x00b4 }, - { 0x0013, 0x00b5 }, - { 0x0013, 0x00b6 }, - { 0x0013, 0x00b7 }, - { 0x0013, 0x00b8 }, - { 0x0013, 0x00b9 }, - { 0x0013, 0x00ba }, - { 0x0013, 0x00bb }, - { 0x0013, 0x00bc }, - { 0x0013, 0x00bd }, - { 0x0013, 0x00be }, - { 0x0013, 0x00bf }, - { 0x0013, 0x00c0 }, - { 0x0013, 0x00c1 }, - { 0x0013, 0x00c2 }, - { 0x0013, 0x00c3 }, - { 0x0013, 0x00c4 }, - { 0x0013, 0x00c5 }, - { 0x0013, 0x00c6 }, - { 0x0013, 0x00c7 }, - { 0x0013, 0x00c8 }, - { 0x0013, 0x00c9 }, - { 0x0013, 0x00ca }, - { 0x0013, 0x00cb }, - { 0x0013, 0x00cc }, - { 0x0013, 0x00cd }, - { 0x0013, 0x00ce }, - { 0x0013, 0x00cf }, - { 0x0013, 0x00d0 }, - { 0x0013, 0x00d1 }, - { 0x0013, 0x00d2 }, - { 0x0013, 0x00d3 }, - { 0x0013, 0x00d4 }, - { 0x0013, 0x00d5 }, - { 0x0013, 0x00d6 }, - { 0x0013, 0x00d7 }, - { 0x0013, 0x00d8 }, - { 0x0013, 0x00d9 }, - { 0x0013, 0x00da }, - { 0x0013, 0x00db }, - { 0x0013, 0x00dc }, - { 0x0013, 0x00dd }, - { 0x0013, 0x00de }, - { 0x0013, 0x00df }, - { 0x0013, 0x00e0 }, - { 0x0013, 0x00e1 }, - { 0x0013, 0x00e2 }, - { 0x0013, 0x00e3 }, - { 0x0013, 0x00e4 }, - { 0x0013, 0x00e5 }, - { 0x0013, 0x00e6 }, - { 0x0013, 0x00e7 }, - { 0x0013, 0x00e8 }, - { 0x0013, 0x00e9 }, - { 0x0013, 0x00ea }, - { 0x0013, 0x00eb }, - { 0x0013, 0x00ec }, - { 0x0013, 0x00ed }, - { 0x0013, 0x00ee }, - { 0x0013, 0x00ef }, - { 0x0013, 0x00f0 }, - { 0x0013, 0x00f1 }, - { 0x0013, 0x00f2 }, - { 0x0013, 0x00f3 }, - { 0x0013, 0x00f4 }, - { 0x0013, 0x00f5 }, - { 0x0013, 0x00f6 }, - { 0x0013, 0x00f7 }, - { 0x0013, 0x00f8 }, - { 0x0013, 0x00f9 }, - { 0x0013, 0x00fa }, - { 0x0013, 0x00fb }, - { 0x0013, 0x00fc }, - { 0x0013, 0x00fd }, - { 0x0013, 0x00fe }, - { 0x0013, 0x00ff }, - { 0x0013, 0x0100 }, - { 0x0013, 0x0101 }, - { 0x0013, 0x0102 }, - { 0x0013, 0x0103 }, - { 0x0013, 0x0104 }, - { 0x0013, 0x0105 }, - { 0x0013, 0x0106 }, - { 0x0013, 0x0107 }, - { 0x0013, 0x0108 }, - { 0x0013, 0x0109 }, - { 0x0013, 0x010a }, - { 0x0013, 0x010b }, - { 0x0013, 0x010c }, - { 0x0013, 0x010d }, - { 0x0013, 0x010e }, - { 0x0013, 0x010f }, - { 0x0013, 0x0110 }, - { 0x0013, 0x0111 }, - { 0x0013, 0x0112 }, - { 0x0013, 0x0113 }, - { 0x0013, 0x0114 }, - { 0x0013, 0x0115 }, - { 0x0013, 0x0116 }, - { 0x0013, 0x0117 }, - { 0x0013, 0x0118 }, - { 0x0013, 0x0119 }, - { 0x0013, 0x011a }, - { 0x0013, 0x011b }, - { 0x0013, 0x011c }, - { 0x0013, 0x011d }, - { 0x0013, 0x011e }, - { 0x0013, 0x011f }, - { 0x0013, 0x0120 }, - { 0x0013, 0x0121 }, - { 0x0013, 0x0122 }, - { 0x0013, 0x0123 }, - { 0x0013, 0x0124 }, - { 0x0013, 0x0125 }, - { 0x0013, 0x0126 }, - { 0x0013, 0x0127 }, - { 0x0013, 0x0128 }, - { 0x0013, 0x0129 }, - { 0x0013, 0x012a }, - { 0x0013, 0x012b }, - { 0x0013, 0x012c }, - { 0x0013, 0x012d }, - { 0x0013, 0x012e }, - { 0x0013, 0x012f }, - { 0x0013, 0x0130 }, - { 0x0013, 0x0131 }, - { 0x0013, 0x0132 }, - { 0x0013, 0x0133 }, - { 0x0013, 0x0134 }, - { 0x0013, 0x0135 }, - { 0x0013, 0x0136 }, - { 0x0013, 0x0137 }, - { 0x0013, 0x0138 }, - { 0x0013, 0x0139 }, - { 0x0013, 0x013a }, - { 0x0013, 0x013b }, - { 0x0013, 0x013c }, - { 0x0013, 0x013d }, - { 0x0013, 0x013e }, - { 0x0013, 0x013f }, - { 0x0013, 0x0140 }, - { 0x0013, 0x0141 }, - { 0x0013, 0x0142 }, - { 0x0013, 0x0143 }, - { 0x0013, 0x0144 }, - { 0x0013, 0x0145 }, - { 0x0013, 0x0146 }, - { 0x0013, 0x0147 }, - { 0x0013, 0x0148 }, - { 0x0013, 0x0149 }, - { 0x0013, 0x014a }, - { 0x0013, 0x014b }, - { 0x0012, 0x00ab }, - { 0x0012, 0x00ac }, - { 0x0012, 0x00ad }, - }; - -const uint16_t c_aauiLCLDHuffEnc47[576][2] = - { - { 0x0002, 0x0003 }, - { 0x0003, 0x0003 }, - { 0x0005, 0x0005 }, - { 0x0006, 0x0004 }, - { 0x0008, 0x0006 }, - { 0x000a, 0x0007 }, - { 0x000c, 0x000b }, - { 0x000d, 0x000d }, - { 0x0010, 0x0041 }, - { 0x0013, 0x0000 }, - { 0x0013, 0x0001 }, - { 0x0013, 0x0002 }, - { 0x0013, 0x0003 }, - { 0x0013, 0x0004 }, - { 0x0013, 0x0005 }, - { 0x0013, 0x0006 }, - { 0x0013, 0x0007 }, - { 0x0013, 0x0008 }, - { 0x0013, 0x0009 }, - { 0x0013, 0x000a }, - { 0x0013, 0x000b }, - { 0x0013, 0x000c }, - { 0x0013, 0x000d }, - { 0x0013, 0x000e }, - { 0x0003, 0x0004 }, - { 0x0003, 0x0005 }, - { 0x0004, 0x0004 }, - { 0x0006, 0x0005 }, - { 0x0007, 0x0005 }, - { 0x0009, 0x0006 }, - { 0x000b, 0x0007 }, - { 0x000d, 0x000e }, - { 0x000f, 0x0025 }, - { 0x000f, 0x0026 }, - { 0x0012, 0x00f6 }, - { 0x0013, 0x000f }, - { 0x0013, 0x0010 }, - { 0x0013, 0x0011 }, - { 0x0013, 0x0012 }, - { 0x0013, 0x0013 }, - { 0x0013, 0x0014 }, - { 0x0013, 0x0015 }, - { 0x0013, 0x0016 }, - { 0x0013, 0x0017 }, - { 0x0013, 0x0018 }, - { 0x0013, 0x0019 }, - { 0x0013, 0x001a }, - { 0x0013, 0x001b }, - { 0x0005, 0x0006 }, - { 0x0004, 0x0005 }, - { 0x0005, 0x0007 }, - { 0x0006, 0x0006 }, - { 0x0008, 0x0007 }, - { 0x0009, 0x0007 }, - { 0x000b, 0x0008 }, - { 0x000d, 0x000f }, - { 0x000f, 0x0027 }, - { 0x0012, 0x00f7 }, - { 0x0013, 0x001c }, - { 0x0013, 0x001d }, - { 0x0013, 0x001e }, - { 0x0013, 0x001f }, - { 0x0013, 0x0020 }, - { 0x0013, 0x0021 }, - { 0x0013, 0x0022 }, - { 0x0013, 0x0023 }, - { 0x0013, 0x0024 }, - { 0x0013, 0x0025 }, - { 0x0013, 0x0026 }, - { 0x0013, 0x0027 }, - { 0x0013, 0x0028 }, - { 0x0013, 0x0029 }, - { 0x0006, 0x0007 }, - { 0x0006, 0x0008 }, - { 0x0006, 0x0009 }, - { 0x0007, 0x0006 }, - { 0x0009, 0x0008 }, - { 0x000a, 0x0008 }, - { 0x000c, 0x000c }, - { 0x000e, 0x0017 }, - { 0x0010, 0x0042 }, - { 0x0012, 0x00f8 }, - { 0x0013, 0x002a }, - { 0x0013, 0x002b }, - { 0x0013, 0x002c }, - { 0x0013, 0x002d }, - { 0x0013, 0x002e }, - { 0x0013, 0x002f }, - { 0x0013, 0x0030 }, - { 0x0013, 0x0031 }, - { 0x0013, 0x0032 }, - { 0x0013, 0x0033 }, - { 0x0013, 0x0034 }, - { 0x0013, 0x0035 }, - { 0x0013, 0x0036 }, - { 0x0013, 0x0037 }, - { 0x0008, 0x0008 }, - { 0x0007, 0x0007 }, - { 0x0008, 0x0009 }, - { 0x0009, 0x0009 }, - { 0x000a, 0x0009 }, - { 0x000b, 0x0009 }, - { 0x000d, 0x0010 }, - { 0x000f, 0x0028 }, - { 0x000f, 0x0029 }, - { 0x0011, 0x007f }, - { 0x0013, 0x0038 }, - { 0x0013, 0x0039 }, - { 0x0013, 0x003a }, - { 0x0013, 0x003b }, - { 0x0013, 0x003c }, - { 0x0013, 0x003d }, - { 0x0013, 0x003e }, - { 0x0013, 0x003f }, - { 0x0013, 0x0040 }, - { 0x0013, 0x0041 }, - { 0x0013, 0x0042 }, - { 0x0013, 0x0043 }, - { 0x0013, 0x0044 }, - { 0x0013, 0x0045 }, - { 0x000a, 0x000a }, - { 0x0009, 0x000a }, - { 0x0009, 0x000b }, - { 0x000a, 0x000b }, - { 0x000b, 0x000a }, - { 0x000d, 0x0011 }, - { 0x000f, 0x002a }, - { 0x0010, 0x0043 }, - { 0x0012, 0x00f9 }, - { 0x0013, 0x0046 }, - { 0x0013, 0x0047 }, - { 0x0013, 0x0048 }, - { 0x0013, 0x0049 }, - { 0x0013, 0x004a }, - { 0x0013, 0x004b }, - { 0x0013, 0x004c }, - { 0x0013, 0x004d }, - { 0x0013, 0x004e }, - { 0x0013, 0x004f }, - { 0x0013, 0x0050 }, - { 0x0013, 0x0051 }, - { 0x0013, 0x0052 }, - { 0x0013, 0x0053 }, - { 0x0013, 0x0054 }, - { 0x000b, 0x000b }, - { 0x000b, 0x000c }, - { 0x000b, 0x000d }, - { 0x000c, 0x000d }, - { 0x000d, 0x0012 }, - { 0x000e, 0x0018 }, - { 0x0010, 0x0044 }, - { 0x0013, 0x0055 }, - { 0x0013, 0x0056 }, - { 0x0013, 0x0057 }, - { 0x0013, 0x0058 }, - { 0x0013, 0x0059 }, - { 0x0013, 0x005a }, - { 0x0013, 0x005b }, - { 0x0013, 0x005c }, - { 0x0013, 0x005d }, - { 0x0013, 0x005e }, - { 0x0013, 0x005f }, - { 0x0013, 0x0060 }, - { 0x0013, 0x0061 }, - { 0x0013, 0x0062 }, - { 0x0013, 0x0063 }, - { 0x0013, 0x0064 }, - { 0x0013, 0x0065 }, - { 0x000e, 0x0019 }, - { 0x000d, 0x0013 }, - { 0x000d, 0x0014 }, - { 0x000d, 0x0015 }, - { 0x000f, 0x002b }, - { 0x0010, 0x0045 }, - { 0x0013, 0x0066 }, - { 0x0012, 0x00fa }, - { 0x0013, 0x0067 }, - { 0x0013, 0x0068 }, - { 0x0013, 0x0069 }, - { 0x0013, 0x006a }, - { 0x0013, 0x006b }, - { 0x0013, 0x006c }, - { 0x0013, 0x006d }, - { 0x0013, 0x006e }, - { 0x0013, 0x006f }, - { 0x0013, 0x0070 }, - { 0x0013, 0x0071 }, - { 0x0013, 0x0072 }, - { 0x0013, 0x0073 }, - { 0x0013, 0x0074 }, - { 0x0013, 0x0075 }, - { 0x0013, 0x0076 }, - { 0x0010, 0x0046 }, - { 0x000f, 0x002c }, - { 0x000f, 0x002d }, - { 0x0010, 0x0047 }, - { 0x0011, 0x0080 }, - { 0x0013, 0x0077 }, - { 0x0013, 0x0078 }, - { 0x0013, 0x0079 }, - { 0x0013, 0x007a }, - { 0x0013, 0x007b }, - { 0x0013, 0x007c }, - { 0x0013, 0x007d }, - { 0x0013, 0x007e }, - { 0x0013, 0x007f }, - { 0x0013, 0x0080 }, - { 0x0013, 0x0081 }, - { 0x0013, 0x0082 }, - { 0x0013, 0x0083 }, - { 0x0013, 0x0084 }, - { 0x0013, 0x0085 }, - { 0x0013, 0x0086 }, - { 0x0013, 0x0087 }, - { 0x0013, 0x0088 }, - { 0x0013, 0x0089 }, - { 0x0013, 0x008a }, - { 0x0010, 0x0048 }, - { 0x0010, 0x0049 }, - { 0x0011, 0x0081 }, - { 0x0013, 0x008b }, - { 0x0012, 0x00fb }, - { 0x0013, 0x008c }, - { 0x0013, 0x008d }, - { 0x0013, 0x008e }, - { 0x0013, 0x008f }, - { 0x0013, 0x0090 }, - { 0x0013, 0x0091 }, - { 0x0013, 0x0092 }, - { 0x0013, 0x0093 }, - { 0x0013, 0x0094 }, - { 0x0013, 0x0095 }, - { 0x0013, 0x0096 }, - { 0x0013, 0x0097 }, - { 0x0013, 0x0098 }, - { 0x0013, 0x0099 }, - { 0x0013, 0x009a }, - { 0x0013, 0x009b }, - { 0x0013, 0x009c }, - { 0x0013, 0x009d }, - { 0x0013, 0x009e }, - { 0x0013, 0x009f }, - { 0x0013, 0x00a0 }, - { 0x0012, 0x00fc }, - { 0x0013, 0x00a1 }, - { 0x0013, 0x00a2 }, - { 0x0013, 0x00a3 }, - { 0x0013, 0x00a4 }, - { 0x0013, 0x00a5 }, - { 0x0013, 0x00a6 }, - { 0x0013, 0x00a7 }, - { 0x0013, 0x00a8 }, - { 0x0013, 0x00a9 }, - { 0x0013, 0x00aa }, - { 0x0013, 0x00ab }, - { 0x0013, 0x00ac }, - { 0x0013, 0x00ad }, - { 0x0013, 0x00ae }, - { 0x0013, 0x00af }, - { 0x0013, 0x00b0 }, - { 0x0013, 0x00b1 }, - { 0x0013, 0x00b2 }, - { 0x0013, 0x00b3 }, - { 0x0013, 0x00b4 }, - { 0x0013, 0x00b5 }, - { 0x0013, 0x00b6 }, - { 0x0013, 0x00b7 }, - { 0x0013, 0x00b8 }, - { 0x0013, 0x00b9 }, - { 0x0013, 0x00ba }, - { 0x0013, 0x00bb }, - { 0x0013, 0x00bc }, - { 0x0013, 0x00bd }, - { 0x0013, 0x00be }, - { 0x0013, 0x00bf }, - { 0x0013, 0x00c0 }, - { 0x0013, 0x00c1 }, - { 0x0013, 0x00c2 }, - { 0x0013, 0x00c3 }, - { 0x0013, 0x00c4 }, - { 0x0013, 0x00c5 }, - { 0x0013, 0x00c6 }, - { 0x0013, 0x00c7 }, - { 0x0013, 0x00c8 }, - { 0x0013, 0x00c9 }, - { 0x0013, 0x00ca }, - { 0x0013, 0x00cb }, - { 0x0013, 0x00cc }, - { 0x0013, 0x00cd }, - { 0x0013, 0x00ce }, - { 0x0013, 0x00cf }, - { 0x0013, 0x00d0 }, - { 0x0013, 0x00d1 }, - { 0x0013, 0x00d2 }, - { 0x0013, 0x00d3 }, - { 0x0013, 0x00d4 }, - { 0x0013, 0x00d5 }, - { 0x0013, 0x00d6 }, - { 0x0013, 0x00d7 }, - { 0x0013, 0x00d8 }, - { 0x0013, 0x00d9 }, - { 0x0013, 0x00da }, - { 0x0013, 0x00db }, - { 0x0013, 0x00dc }, - { 0x0013, 0x00dd }, - { 0x0013, 0x00de }, - { 0x0013, 0x00df }, - { 0x0013, 0x00e0 }, - { 0x0013, 0x00e1 }, - { 0x0013, 0x00e2 }, - { 0x0013, 0x00e3 }, - { 0x0013, 0x00e4 }, - { 0x0013, 0x00e5 }, - { 0x0013, 0x00e6 }, - { 0x0013, 0x00e7 }, - { 0x0013, 0x00e8 }, - { 0x0013, 0x00e9 }, - { 0x0013, 0x00ea }, - { 0x0013, 0x00eb }, - { 0x0013, 0x00ec }, - { 0x0013, 0x00ed }, - { 0x0013, 0x00ee }, - { 0x0013, 0x00ef }, - { 0x0013, 0x00f0 }, - { 0x0013, 0x00f1 }, - { 0x0013, 0x00f2 }, - { 0x0013, 0x00f3 }, - { 0x0013, 0x00f4 }, - { 0x0013, 0x00f5 }, - { 0x0013, 0x00f6 }, - { 0x0013, 0x00f7 }, - { 0x0013, 0x00f8 }, - { 0x0013, 0x00f9 }, - { 0x0013, 0x00fa }, - { 0x0013, 0x00fb }, - { 0x0013, 0x00fc }, - { 0x0013, 0x00fd }, - { 0x0013, 0x00fe }, - { 0x0013, 0x00ff }, - { 0x0013, 0x0100 }, - { 0x0013, 0x0101 }, - { 0x0013, 0x0102 }, - { 0x0013, 0x0103 }, - { 0x0013, 0x0104 }, - { 0x0013, 0x0105 }, - { 0x0013, 0x0106 }, - { 0x0013, 0x0107 }, - { 0x0013, 0x0108 }, - { 0x0013, 0x0109 }, - { 0x0013, 0x010a }, - { 0x0013, 0x010b }, - { 0x0013, 0x010c }, - { 0x0013, 0x010d }, - { 0x0013, 0x010e }, - { 0x0013, 0x010f }, - { 0x0013, 0x0110 }, - { 0x0013, 0x0111 }, - { 0x0013, 0x0112 }, - { 0x0013, 0x0113 }, - { 0x0013, 0x0114 }, - { 0x0013, 0x0115 }, - { 0x0013, 0x0116 }, - { 0x0013, 0x0117 }, - { 0x0013, 0x0118 }, - { 0x0013, 0x0119 }, - { 0x0013, 0x011a }, - { 0x0013, 0x011b }, - { 0x0013, 0x011c }, - { 0x0013, 0x011d }, - { 0x0013, 0x011e }, - { 0x0013, 0x011f }, - { 0x0013, 0x0120 }, - { 0x0013, 0x0121 }, - { 0x0013, 0x0122 }, - { 0x0013, 0x0123 }, - { 0x0013, 0x0124 }, - { 0x0013, 0x0125 }, - { 0x0013, 0x0126 }, - { 0x0013, 0x0127 }, - { 0x0013, 0x0128 }, - { 0x0013, 0x0129 }, - { 0x0013, 0x012a }, - { 0x0013, 0x012b }, - { 0x0013, 0x012c }, - { 0x0013, 0x012d }, - { 0x0013, 0x012e }, - { 0x0013, 0x012f }, - { 0x0013, 0x0130 }, - { 0x0013, 0x0131 }, - { 0x0013, 0x0132 }, - { 0x0013, 0x0133 }, - { 0x0013, 0x0134 }, - { 0x0013, 0x0135 }, - { 0x0013, 0x0136 }, - { 0x0013, 0x0137 }, - { 0x0013, 0x0138 }, - { 0x0013, 0x0139 }, - { 0x0013, 0x013a }, - { 0x0013, 0x013b }, - { 0x0013, 0x013c }, - { 0x0013, 0x013d }, - { 0x0013, 0x013e }, - { 0x0013, 0x013f }, - { 0x0013, 0x0140 }, - { 0x0013, 0x0141 }, - { 0x0013, 0x0142 }, - { 0x0013, 0x0143 }, - { 0x0013, 0x0144 }, - { 0x0013, 0x0145 }, - { 0x0013, 0x0146 }, - { 0x0013, 0x0147 }, - { 0x0013, 0x0148 }, - { 0x0013, 0x0149 }, - { 0x0013, 0x014a }, - { 0x0013, 0x014b }, - { 0x0013, 0x014c }, - { 0x0013, 0x014d }, - { 0x0013, 0x014e }, - { 0x0013, 0x014f }, - { 0x0013, 0x0150 }, - { 0x0013, 0x0151 }, - { 0x0013, 0x0152 }, - { 0x0013, 0x0153 }, - { 0x0013, 0x0154 }, - { 0x0013, 0x0155 }, - { 0x0013, 0x0156 }, - { 0x0013, 0x0157 }, - { 0x0013, 0x0158 }, - { 0x0013, 0x0159 }, - { 0x0013, 0x015a }, - { 0x0013, 0x015b }, - { 0x0013, 0x015c }, - { 0x0013, 0x015d }, - { 0x0013, 0x015e }, - { 0x0013, 0x015f }, - { 0x0013, 0x0160 }, - { 0x0013, 0x0161 }, - { 0x0013, 0x0162 }, - { 0x0013, 0x0163 }, - { 0x0013, 0x0164 }, - { 0x0013, 0x0165 }, - { 0x0013, 0x0166 }, - { 0x0013, 0x0167 }, - { 0x0013, 0x0168 }, - { 0x0013, 0x0169 }, - { 0x0013, 0x016a }, - { 0x0013, 0x016b }, - { 0x0013, 0x016c }, - { 0x0013, 0x016d }, - { 0x0013, 0x016e }, - { 0x0013, 0x016f }, - { 0x0013, 0x0170 }, - { 0x0013, 0x0171 }, - { 0x0013, 0x0172 }, - { 0x0013, 0x0173 }, - { 0x0013, 0x0174 }, - { 0x0013, 0x0175 }, - { 0x0013, 0x0176 }, - { 0x0013, 0x0177 }, - { 0x0013, 0x0178 }, - { 0x0013, 0x0179 }, - { 0x0013, 0x017a }, - { 0x0013, 0x017b }, - { 0x0013, 0x017c }, - { 0x0013, 0x017d }, - { 0x0013, 0x017e }, - { 0x0013, 0x017f }, - { 0x0013, 0x0180 }, - { 0x0013, 0x0181 }, - { 0x0013, 0x0182 }, - { 0x0013, 0x0183 }, - { 0x0013, 0x0184 }, - { 0x0013, 0x0185 }, - { 0x0013, 0x0186 }, - { 0x0013, 0x0187 }, - { 0x0013, 0x0188 }, - { 0x0013, 0x0189 }, - { 0x0013, 0x018a }, - { 0x0013, 0x018b }, - { 0x0013, 0x018c }, - { 0x0013, 0x018d }, - { 0x0013, 0x018e }, - { 0x0013, 0x018f }, - { 0x0013, 0x0190 }, - { 0x0013, 0x0191 }, - { 0x0013, 0x0192 }, - { 0x0013, 0x0193 }, - { 0x0013, 0x0194 }, - { 0x0013, 0x0195 }, - { 0x0013, 0x0196 }, - { 0x0013, 0x0197 }, - { 0x0013, 0x0198 }, - { 0x0013, 0x0199 }, - { 0x0013, 0x019a }, - { 0x0013, 0x019b }, - { 0x0013, 0x019c }, - { 0x0013, 0x019d }, - { 0x0013, 0x019e }, - { 0x0013, 0x019f }, - { 0x0013, 0x01a0 }, - { 0x0013, 0x01a1 }, - { 0x0013, 0x01a2 }, - { 0x0013, 0x01a3 }, - { 0x0013, 0x01a4 }, - { 0x0013, 0x01a5 }, - { 0x0013, 0x01a6 }, - { 0x0013, 0x01a7 }, - { 0x0013, 0x01a8 }, - { 0x0013, 0x01a9 }, - { 0x0013, 0x01aa }, - { 0x0013, 0x01ab }, - { 0x0013, 0x01ac }, - { 0x0013, 0x01ad }, - { 0x0013, 0x01ae }, - { 0x0013, 0x01af }, - { 0x0013, 0x01b0 }, - { 0x0013, 0x01b1 }, - { 0x0013, 0x01b2 }, - { 0x0013, 0x01b3 }, - { 0x0013, 0x01b4 }, - { 0x0013, 0x01b5 }, - { 0x0013, 0x01b6 }, - { 0x0013, 0x01b7 }, - { 0x0013, 0x01b8 }, - { 0x0013, 0x01b9 }, - { 0x0013, 0x01ba }, - { 0x0013, 0x01bb }, - { 0x0013, 0x01bc }, - { 0x0013, 0x01bd }, - { 0x0013, 0x01be }, - { 0x0013, 0x01bf }, - { 0x0013, 0x01c0 }, - { 0x0013, 0x01c1 }, - { 0x0013, 0x01c2 }, - { 0x0013, 0x01c3 }, - { 0x0013, 0x01c4 }, - { 0x0013, 0x01c5 }, - { 0x0013, 0x01c6 }, - { 0x0013, 0x01c7 }, - { 0x0013, 0x01c8 }, - { 0x0013, 0x01c9 }, - { 0x0013, 0x01ca }, - { 0x0013, 0x01cb }, - { 0x0013, 0x01cc }, - { 0x0013, 0x01cd }, - { 0x0013, 0x01ce }, - { 0x0013, 0x01cf }, - { 0x0013, 0x01d0 }, - { 0x0013, 0x01d1 }, - { 0x0013, 0x01d2 }, - { 0x0013, 0x01d3 }, - { 0x0013, 0x01d4 }, - { 0x0013, 0x01d5 }, - { 0x0013, 0x01d6 }, - { 0x0013, 0x01d7 }, - { 0x0013, 0x01d8 }, - { 0x0013, 0x01d9 }, - { 0x0013, 0x01da }, - { 0x0013, 0x01db }, - { 0x0013, 0x01dc }, - { 0x0013, 0x01dd }, - { 0x0013, 0x01de }, - { 0x0013, 0x01df }, - { 0x0013, 0x01e0 }, - { 0x0013, 0x01e1 }, - { 0x0013, 0x01e2 }, - { 0x0013, 0x01e3 }, - { 0x0013, 0x01e4 }, - { 0x0013, 0x01e5 }, - { 0x0013, 0x01e6 }, - { 0x0013, 0x01e7 }, - { 0x0013, 0x01e8 }, - { 0x0013, 0x01e9 }, - { 0x0013, 0x01ea }, - { 0x0013, 0x01eb }, - { 0x0012, 0x00fd }, - }; - -const uint16_t c_aauiLCLDHuffEnc48[729][2] = - { - { 0x0002, 0x0003 }, - { 0x0003, 0x0003 }, - { 0x0005, 0x0006 }, - { 0x0006, 0x0006 }, - { 0x0008, 0x0006 }, - { 0x0009, 0x0007 }, - { 0x000b, 0x000b }, - { 0x000c, 0x000d }, - { 0x000f, 0x0030 }, - { 0x0010, 0x0055 }, - { 0x0012, 0x0136 }, - { 0x0013, 0x0000 }, - { 0x0013, 0x0001 }, - { 0x0013, 0x0002 }, - { 0x0013, 0x0003 }, - { 0x0013, 0x0004 }, - { 0x0013, 0x0005 }, - { 0x0013, 0x0006 }, - { 0x0013, 0x0007 }, - { 0x0013, 0x0008 }, - { 0x0013, 0x0009 }, - { 0x0013, 0x000a }, - { 0x0013, 0x000b }, - { 0x0013, 0x000c }, - { 0x0013, 0x000d }, - { 0x0013, 0x000e }, - { 0x0013, 0x000f }, - { 0x0003, 0x0004 }, - { 0x0003, 0x0005 }, - { 0x0005, 0x0007 }, - { 0x0006, 0x0007 }, - { 0x0007, 0x0007 }, - { 0x0008, 0x0007 }, - { 0x000a, 0x0008 }, - { 0x000c, 0x000e }, - { 0x000d, 0x0012 }, - { 0x000f, 0x0031 }, - { 0x0011, 0x00a0 }, - { 0x0013, 0x0010 }, - { 0x0013, 0x0011 }, - { 0x0013, 0x0012 }, - { 0x0013, 0x0013 }, - { 0x0013, 0x0014 }, - { 0x0013, 0x0015 }, - { 0x0013, 0x0016 }, - { 0x0013, 0x0017 }, - { 0x0013, 0x0018 }, - { 0x0013, 0x0019 }, - { 0x0013, 0x001a }, - { 0x0013, 0x001b }, - { 0x0013, 0x001c }, - { 0x0013, 0x001d }, - { 0x0013, 0x001e }, - { 0x0013, 0x001f }, - { 0x0005, 0x0008 }, - { 0x0004, 0x0005 }, - { 0x0005, 0x0009 }, - { 0x0006, 0x0008 }, - { 0x0007, 0x0008 }, - { 0x0008, 0x0008 }, - { 0x000a, 0x0009 }, - { 0x000c, 0x000f }, - { 0x000d, 0x0013 }, - { 0x000f, 0x0032 }, - { 0x0011, 0x00a1 }, - { 0x0013, 0x0020 }, - { 0x0013, 0x0021 }, - { 0x0013, 0x0022 }, - { 0x0013, 0x0023 }, - { 0x0013, 0x0024 }, - { 0x0013, 0x0025 }, - { 0x0013, 0x0026 }, - { 0x0013, 0x0027 }, - { 0x0013, 0x0028 }, - { 0x0013, 0x0029 }, - { 0x0013, 0x002a }, - { 0x0013, 0x002b }, - { 0x0013, 0x002c }, - { 0x0013, 0x002d }, - { 0x0013, 0x002e }, - { 0x0013, 0x002f }, - { 0x0006, 0x0009 }, - { 0x0006, 0x000a }, - { 0x0006, 0x000b }, - { 0x0007, 0x0009 }, - { 0x0008, 0x0009 }, - { 0x0009, 0x0008 }, - { 0x000b, 0x000c }, - { 0x000d, 0x0014 }, - { 0x000e, 0x001d }, - { 0x000f, 0x0033 }, - { 0x0012, 0x0137 }, - { 0x0013, 0x0030 }, - { 0x0013, 0x0031 }, - { 0x0013, 0x0032 }, - { 0x0013, 0x0033 }, - { 0x0013, 0x0034 }, - { 0x0013, 0x0035 }, - { 0x0013, 0x0036 }, - { 0x0013, 0x0037 }, - { 0x0013, 0x0038 }, - { 0x0013, 0x0039 }, - { 0x0013, 0x003a }, - { 0x0013, 0x003b }, - { 0x0013, 0x003c }, - { 0x0013, 0x003d }, - { 0x0013, 0x003e }, - { 0x0013, 0x003f }, - { 0x0008, 0x000a }, - { 0x0007, 0x000a }, - { 0x0007, 0x000b }, - { 0x0008, 0x000b }, - { 0x0009, 0x0009 }, - { 0x000a, 0x000a }, - { 0x000c, 0x0010 }, - { 0x000d, 0x0015 }, - { 0x000f, 0x0034 }, - { 0x0010, 0x0056 }, - { 0x0012, 0x0138 }, - { 0x0013, 0x0040 }, - { 0x0013, 0x0041 }, - { 0x0013, 0x0042 }, - { 0x0013, 0x0043 }, - { 0x0013, 0x0044 }, - { 0x0013, 0x0045 }, - { 0x0013, 0x0046 }, - { 0x0013, 0x0047 }, - { 0x0013, 0x0048 }, - { 0x0013, 0x0049 }, - { 0x0013, 0x004a }, - { 0x0013, 0x004b }, - { 0x0013, 0x004c }, - { 0x0013, 0x004d }, - { 0x0013, 0x004e }, - { 0x0013, 0x004f }, - { 0x0009, 0x000a }, - { 0x0008, 0x000c }, - { 0x0008, 0x000d }, - { 0x0009, 0x000b }, - { 0x000a, 0x000b }, - { 0x000c, 0x0011 }, - { 0x000d, 0x0016 }, - { 0x000e, 0x001e }, - { 0x0010, 0x0057 }, - { 0x0011, 0x00a2 }, - { 0x0011, 0x00a3 }, - { 0x0013, 0x0050 }, - { 0x0013, 0x0051 }, - { 0x0013, 0x0052 }, - { 0x0013, 0x0053 }, - { 0x0013, 0x0054 }, - { 0x0013, 0x0055 }, - { 0x0013, 0x0056 }, - { 0x0013, 0x0057 }, - { 0x0013, 0x0058 }, - { 0x0013, 0x0059 }, - { 0x0013, 0x005a }, - { 0x0013, 0x005b }, - { 0x0013, 0x005c }, - { 0x0013, 0x005d }, - { 0x0013, 0x005e }, - { 0x0013, 0x005f }, - { 0x000b, 0x000d }, - { 0x000a, 0x000c }, - { 0x000a, 0x000d }, - { 0x000b, 0x000e }, - { 0x000c, 0x0012 }, - { 0x000d, 0x0017 }, - { 0x000e, 0x001f }, - { 0x0010, 0x0058 }, - { 0x0012, 0x0139 }, - { 0x0011, 0x00a4 }, - { 0x0012, 0x013a }, - { 0x0013, 0x0060 }, - { 0x0013, 0x0061 }, - { 0x0013, 0x0062 }, - { 0x0013, 0x0063 }, - { 0x0013, 0x0064 }, - { 0x0013, 0x0065 }, - { 0x0013, 0x0066 }, - { 0x0013, 0x0067 }, - { 0x0013, 0x0068 }, - { 0x0013, 0x0069 }, - { 0x0013, 0x006a }, - { 0x0013, 0x006b }, - { 0x0013, 0x006c }, - { 0x0013, 0x006d }, - { 0x0013, 0x006e }, - { 0x0013, 0x006f }, - { 0x000c, 0x0013 }, - { 0x000b, 0x000f }, - { 0x000c, 0x0014 }, - { 0x000c, 0x0015 }, - { 0x000d, 0x0018 }, - { 0x000e, 0x0020 }, - { 0x000f, 0x0035 }, - { 0x0012, 0x013b }, - { 0x0013, 0x0070 }, - { 0x0013, 0x0071 }, - { 0x0013, 0x0072 }, - { 0x0013, 0x0073 }, - { 0x0013, 0x0074 }, - { 0x0013, 0x0075 }, - { 0x0013, 0x0076 }, - { 0x0013, 0x0077 }, - { 0x0013, 0x0078 }, - { 0x0013, 0x0079 }, - { 0x0013, 0x007a }, - { 0x0013, 0x007b }, - { 0x0013, 0x007c }, - { 0x0013, 0x007d }, - { 0x0013, 0x007e }, - { 0x0013, 0x007f }, - { 0x0013, 0x0080 }, - { 0x0013, 0x0081 }, - { 0x0013, 0x0082 }, - { 0x000e, 0x0021 }, - { 0x000d, 0x0019 }, - { 0x000e, 0x0022 }, - { 0x000e, 0x0023 }, - { 0x000f, 0x0036 }, - { 0x0010, 0x0059 }, - { 0x0011, 0x00a5 }, - { 0x0013, 0x0083 }, - { 0x0011, 0x00a6 }, - { 0x0012, 0x013c }, - { 0x0013, 0x0084 }, - { 0x0013, 0x0085 }, - { 0x0013, 0x0086 }, - { 0x0013, 0x0087 }, - { 0x0013, 0x0088 }, - { 0x0013, 0x0089 }, - { 0x0013, 0x008a }, - { 0x0013, 0x008b }, - { 0x0013, 0x008c }, - { 0x0013, 0x008d }, - { 0x0013, 0x008e }, - { 0x0013, 0x008f }, - { 0x0013, 0x0090 }, - { 0x0013, 0x0091 }, - { 0x0013, 0x0092 }, - { 0x0013, 0x0093 }, - { 0x0013, 0x0094 }, - { 0x0010, 0x005a }, - { 0x000f, 0x0037 }, - { 0x000f, 0x0038 }, - { 0x000f, 0x0039 }, - { 0x0010, 0x005b }, - { 0x0010, 0x005c }, - { 0x0013, 0x0095 }, - { 0x0011, 0x00a7 }, - { 0x0013, 0x0096 }, - { 0x0013, 0x0097 }, - { 0x0013, 0x0098 }, - { 0x0013, 0x0099 }, - { 0x0013, 0x009a }, - { 0x0013, 0x009b }, - { 0x0013, 0x009c }, - { 0x0013, 0x009d }, - { 0x0013, 0x009e }, - { 0x0013, 0x009f }, - { 0x0013, 0x00a0 }, - { 0x0013, 0x00a1 }, - { 0x0013, 0x00a2 }, - { 0x0013, 0x00a3 }, - { 0x0013, 0x00a4 }, - { 0x0013, 0x00a5 }, - { 0x0013, 0x00a6 }, - { 0x0013, 0x00a7 }, - { 0x0013, 0x00a8 }, - { 0x0010, 0x005d }, - { 0x0010, 0x005e }, - { 0x0013, 0x00a9 }, - { 0x0010, 0x005f }, - { 0x0013, 0x00aa }, - { 0x0012, 0x013d }, - { 0x0013, 0x00ab }, - { 0x0013, 0x00ac }, - { 0x0013, 0x00ad }, - { 0x0013, 0x00ae }, - { 0x0013, 0x00af }, - { 0x0013, 0x00b0 }, - { 0x0013, 0x00b1 }, - { 0x0013, 0x00b2 }, - { 0x0013, 0x00b3 }, - { 0x0013, 0x00b4 }, - { 0x0013, 0x00b5 }, - { 0x0013, 0x00b6 }, - { 0x0013, 0x00b7 }, - { 0x0013, 0x00b8 }, - { 0x0013, 0x00b9 }, - { 0x0013, 0x00ba }, - { 0x0013, 0x00bb }, - { 0x0013, 0x00bc }, - { 0x0013, 0x00bd }, - { 0x0013, 0x00be }, - { 0x0013, 0x00bf }, - { 0x0013, 0x00c0 }, - { 0x0011, 0x00a8 }, - { 0x0013, 0x00c1 }, - { 0x0011, 0x00a9 }, - { 0x0013, 0x00c2 }, - { 0x0013, 0x00c3 }, - { 0x0013, 0x00c4 }, - { 0x0013, 0x00c5 }, - { 0x0013, 0x00c6 }, - { 0x0013, 0x00c7 }, - { 0x0013, 0x00c8 }, - { 0x0013, 0x00c9 }, - { 0x0013, 0x00ca }, - { 0x0013, 0x00cb }, - { 0x0013, 0x00cc }, - { 0x0013, 0x00cd }, - { 0x0013, 0x00ce }, - { 0x0013, 0x00cf }, - { 0x0013, 0x00d0 }, - { 0x0013, 0x00d1 }, - { 0x0013, 0x00d2 }, - { 0x0013, 0x00d3 }, - { 0x0013, 0x00d4 }, - { 0x0013, 0x00d5 }, - { 0x0013, 0x00d6 }, - { 0x0013, 0x00d7 }, - { 0x0013, 0x00d8 }, - { 0x0013, 0x00d9 }, - { 0x0013, 0x00da }, - { 0x0012, 0x013e }, - { 0x0013, 0x00db }, - { 0x0013, 0x00dc }, - { 0x0013, 0x00dd }, - { 0x0013, 0x00de }, - { 0x0013, 0x00df }, - { 0x0013, 0x00e0 }, - { 0x0013, 0x00e1 }, - { 0x0013, 0x00e2 }, - { 0x0013, 0x00e3 }, - { 0x0013, 0x00e4 }, - { 0x0013, 0x00e5 }, - { 0x0013, 0x00e6 }, - { 0x0013, 0x00e7 }, - { 0x0013, 0x00e8 }, - { 0x0013, 0x00e9 }, - { 0x0013, 0x00ea }, - { 0x0013, 0x00eb }, - { 0x0013, 0x00ec }, - { 0x0013, 0x00ed }, - { 0x0013, 0x00ee }, - { 0x0013, 0x00ef }, - { 0x0013, 0x00f0 }, - { 0x0013, 0x00f1 }, - { 0x0013, 0x00f2 }, - { 0x0013, 0x00f3 }, - { 0x0013, 0x00f4 }, - { 0x0013, 0x00f5 }, - { 0x0013, 0x00f6 }, - { 0x0013, 0x00f7 }, - { 0x0013, 0x00f8 }, - { 0x0013, 0x00f9 }, - { 0x0013, 0x00fa }, - { 0x0013, 0x00fb }, - { 0x0013, 0x00fc }, - { 0x0013, 0x00fd }, - { 0x0013, 0x00fe }, - { 0x0013, 0x00ff }, - { 0x0013, 0x0100 }, - { 0x0013, 0x0101 }, - { 0x0013, 0x0102 }, - { 0x0013, 0x0103 }, - { 0x0013, 0x0104 }, - { 0x0013, 0x0105 }, - { 0x0013, 0x0106 }, - { 0x0013, 0x0107 }, - { 0x0013, 0x0108 }, - { 0x0013, 0x0109 }, - { 0x0013, 0x010a }, - { 0x0013, 0x010b }, - { 0x0013, 0x010c }, - { 0x0013, 0x010d }, - { 0x0013, 0x010e }, - { 0x0013, 0x010f }, - { 0x0013, 0x0110 }, - { 0x0013, 0x0111 }, - { 0x0013, 0x0112 }, - { 0x0013, 0x0113 }, - { 0x0013, 0x0114 }, - { 0x0013, 0x0115 }, - { 0x0013, 0x0116 }, - { 0x0013, 0x0117 }, - { 0x0013, 0x0118 }, - { 0x0013, 0x0119 }, - { 0x0013, 0x011a }, - { 0x0013, 0x011b }, - { 0x0013, 0x011c }, - { 0x0013, 0x011d }, - { 0x0013, 0x011e }, - { 0x0013, 0x011f }, - { 0x0013, 0x0120 }, - { 0x0013, 0x0121 }, - { 0x0013, 0x0122 }, - { 0x0013, 0x0123 }, - { 0x0013, 0x0124 }, - { 0x0013, 0x0125 }, - { 0x0013, 0x0126 }, - { 0x0013, 0x0127 }, - { 0x0013, 0x0128 }, - { 0x0013, 0x0129 }, - { 0x0013, 0x012a }, - { 0x0013, 0x012b }, - { 0x0013, 0x012c }, - { 0x0013, 0x012d }, - { 0x0013, 0x012e }, - { 0x0013, 0x012f }, - { 0x0013, 0x0130 }, - { 0x0013, 0x0131 }, - { 0x0013, 0x0132 }, - { 0x0013, 0x0133 }, - { 0x0013, 0x0134 }, - { 0x0013, 0x0135 }, - { 0x0013, 0x0136 }, - { 0x0013, 0x0137 }, - { 0x0013, 0x0138 }, - { 0x0013, 0x0139 }, - { 0x0013, 0x013a }, - { 0x0013, 0x013b }, - { 0x0013, 0x013c }, - { 0x0013, 0x013d }, - { 0x0013, 0x013e }, - { 0x0013, 0x013f }, - { 0x0013, 0x0140 }, - { 0x0013, 0x0141 }, - { 0x0013, 0x0142 }, - { 0x0013, 0x0143 }, - { 0x0013, 0x0144 }, - { 0x0013, 0x0145 }, - { 0x0013, 0x0146 }, - { 0x0013, 0x0147 }, - { 0x0013, 0x0148 }, - { 0x0013, 0x0149 }, - { 0x0013, 0x014a }, - { 0x0013, 0x014b }, - { 0x0013, 0x014c }, - { 0x0013, 0x014d }, - { 0x0013, 0x014e }, - { 0x0013, 0x014f }, - { 0x0013, 0x0150 }, - { 0x0013, 0x0151 }, - { 0x0013, 0x0152 }, - { 0x0013, 0x0153 }, - { 0x0013, 0x0154 }, - { 0x0013, 0x0155 }, - { 0x0013, 0x0156 }, - { 0x0013, 0x0157 }, - { 0x0013, 0x0158 }, - { 0x0013, 0x0159 }, - { 0x0013, 0x015a }, - { 0x0013, 0x015b }, - { 0x0013, 0x015c }, - { 0x0013, 0x015d }, - { 0x0013, 0x015e }, - { 0x0013, 0x015f }, - { 0x0013, 0x0160 }, - { 0x0013, 0x0161 }, - { 0x0013, 0x0162 }, - { 0x0013, 0x0163 }, - { 0x0013, 0x0164 }, - { 0x0013, 0x0165 }, - { 0x0013, 0x0166 }, - { 0x0013, 0x0167 }, - { 0x0013, 0x0168 }, - { 0x0013, 0x0169 }, - { 0x0013, 0x016a }, - { 0x0013, 0x016b }, - { 0x0013, 0x016c }, - { 0x0013, 0x016d }, - { 0x0013, 0x016e }, - { 0x0013, 0x016f }, - { 0x0013, 0x0170 }, - { 0x0013, 0x0171 }, - { 0x0013, 0x0172 }, - { 0x0013, 0x0173 }, - { 0x0013, 0x0174 }, - { 0x0013, 0x0175 }, - { 0x0013, 0x0176 }, - { 0x0013, 0x0177 }, - { 0x0013, 0x0178 }, - { 0x0013, 0x0179 }, - { 0x0013, 0x017a }, - { 0x0013, 0x017b }, - { 0x0013, 0x017c }, - { 0x0013, 0x017d }, - { 0x0013, 0x017e }, - { 0x0013, 0x017f }, - { 0x0013, 0x0180 }, - { 0x0013, 0x0181 }, - { 0x0013, 0x0182 }, - { 0x0013, 0x0183 }, - { 0x0013, 0x0184 }, - { 0x0013, 0x0185 }, - { 0x0013, 0x0186 }, - { 0x0013, 0x0187 }, - { 0x0013, 0x0188 }, - { 0x0013, 0x0189 }, - { 0x0013, 0x018a }, - { 0x0013, 0x018b }, - { 0x0013, 0x018c }, - { 0x0013, 0x018d }, - { 0x0013, 0x018e }, - { 0x0013, 0x018f }, - { 0x0013, 0x0190 }, - { 0x0013, 0x0191 }, - { 0x0013, 0x0192 }, - { 0x0013, 0x0193 }, - { 0x0013, 0x0194 }, - { 0x0013, 0x0195 }, - { 0x0013, 0x0196 }, - { 0x0013, 0x0197 }, - { 0x0013, 0x0198 }, - { 0x0013, 0x0199 }, - { 0x0013, 0x019a }, - { 0x0013, 0x019b }, - { 0x0013, 0x019c }, - { 0x0013, 0x019d }, - { 0x0013, 0x019e }, - { 0x0013, 0x019f }, - { 0x0013, 0x01a0 }, - { 0x0013, 0x01a1 }, - { 0x0013, 0x01a2 }, - { 0x0013, 0x01a3 }, - { 0x0013, 0x01a4 }, - { 0x0013, 0x01a5 }, - { 0x0013, 0x01a6 }, - { 0x0013, 0x01a7 }, - { 0x0013, 0x01a8 }, - { 0x0013, 0x01a9 }, - { 0x0013, 0x01aa }, - { 0x0013, 0x01ab }, - { 0x0013, 0x01ac }, - { 0x0013, 0x01ad }, - { 0x0013, 0x01ae }, - { 0x0013, 0x01af }, - { 0x0013, 0x01b0 }, - { 0x0013, 0x01b1 }, - { 0x0013, 0x01b2 }, - { 0x0013, 0x01b3 }, - { 0x0013, 0x01b4 }, - { 0x0013, 0x01b5 }, - { 0x0013, 0x01b6 }, - { 0x0013, 0x01b7 }, - { 0x0013, 0x01b8 }, - { 0x0013, 0x01b9 }, - { 0x0013, 0x01ba }, - { 0x0013, 0x01bb }, - { 0x0013, 0x01bc }, - { 0x0013, 0x01bd }, - { 0x0013, 0x01be }, - { 0x0013, 0x01bf }, - { 0x0013, 0x01c0 }, - { 0x0013, 0x01c1 }, - { 0x0013, 0x01c2 }, - { 0x0013, 0x01c3 }, - { 0x0013, 0x01c4 }, - { 0x0013, 0x01c5 }, - { 0x0013, 0x01c6 }, - { 0x0013, 0x01c7 }, - { 0x0013, 0x01c8 }, - { 0x0013, 0x01c9 }, - { 0x0013, 0x01ca }, - { 0x0013, 0x01cb }, - { 0x0013, 0x01cc }, - { 0x0013, 0x01cd }, - { 0x0013, 0x01ce }, - { 0x0013, 0x01cf }, - { 0x0013, 0x01d0 }, - { 0x0013, 0x01d1 }, - { 0x0013, 0x01d2 }, - { 0x0013, 0x01d3 }, - { 0x0013, 0x01d4 }, - { 0x0013, 0x01d5 }, - { 0x0013, 0x01d6 }, - { 0x0013, 0x01d7 }, - { 0x0013, 0x01d8 }, - { 0x0013, 0x01d9 }, - { 0x0013, 0x01da }, - { 0x0013, 0x01db }, - { 0x0013, 0x01dc }, - { 0x0013, 0x01dd }, - { 0x0013, 0x01de }, - { 0x0013, 0x01df }, - { 0x0013, 0x01e0 }, - { 0x0013, 0x01e1 }, - { 0x0013, 0x01e2 }, - { 0x0013, 0x01e3 }, - { 0x0013, 0x01e4 }, - { 0x0013, 0x01e5 }, - { 0x0013, 0x01e6 }, - { 0x0013, 0x01e7 }, - { 0x0013, 0x01e8 }, - { 0x0013, 0x01e9 }, - { 0x0013, 0x01ea }, - { 0x0013, 0x01eb }, - { 0x0013, 0x01ec }, - { 0x0013, 0x01ed }, - { 0x0013, 0x01ee }, - { 0x0013, 0x01ef }, - { 0x0013, 0x01f0 }, - { 0x0013, 0x01f1 }, - { 0x0013, 0x01f2 }, - { 0x0013, 0x01f3 }, - { 0x0013, 0x01f4 }, - { 0x0013, 0x01f5 }, - { 0x0013, 0x01f6 }, - { 0x0013, 0x01f7 }, - { 0x0013, 0x01f8 }, - { 0x0013, 0x01f9 }, - { 0x0013, 0x01fa }, - { 0x0013, 0x01fb }, - { 0x0013, 0x01fc }, - { 0x0013, 0x01fd }, - { 0x0013, 0x01fe }, - { 0x0013, 0x01ff }, - { 0x0013, 0x0200 }, - { 0x0013, 0x0201 }, - { 0x0013, 0x0202 }, - { 0x0013, 0x0203 }, - { 0x0013, 0x0204 }, - { 0x0013, 0x0205 }, - { 0x0013, 0x0206 }, - { 0x0013, 0x0207 }, - { 0x0013, 0x0208 }, - { 0x0013, 0x0209 }, - { 0x0013, 0x020a }, - { 0x0013, 0x020b }, - { 0x0013, 0x020c }, - { 0x0013, 0x020d }, - { 0x0013, 0x020e }, - { 0x0013, 0x020f }, - { 0x0013, 0x0210 }, - { 0x0013, 0x0211 }, - { 0x0013, 0x0212 }, - { 0x0013, 0x0213 }, - { 0x0013, 0x0214 }, - { 0x0013, 0x0215 }, - { 0x0013, 0x0216 }, - { 0x0013, 0x0217 }, - { 0x0013, 0x0218 }, - { 0x0013, 0x0219 }, - { 0x0013, 0x021a }, - { 0x0013, 0x021b }, - { 0x0013, 0x021c }, - { 0x0013, 0x021d }, - { 0x0013, 0x021e }, - { 0x0013, 0x021f }, - { 0x0013, 0x0220 }, - { 0x0013, 0x0221 }, - { 0x0013, 0x0222 }, - { 0x0013, 0x0223 }, - { 0x0013, 0x0224 }, - { 0x0013, 0x0225 }, - { 0x0013, 0x0226 }, - { 0x0013, 0x0227 }, - { 0x0013, 0x0228 }, - { 0x0013, 0x0229 }, - { 0x0013, 0x022a }, - { 0x0013, 0x022b }, - { 0x0013, 0x022c }, - { 0x0013, 0x022d }, - { 0x0013, 0x022e }, - { 0x0013, 0x022f }, - { 0x0013, 0x0230 }, - { 0x0013, 0x0231 }, - { 0x0013, 0x0232 }, - { 0x0013, 0x0233 }, - { 0x0013, 0x0234 }, - { 0x0013, 0x0235 }, - { 0x0013, 0x0236 }, - { 0x0013, 0x0237 }, - { 0x0013, 0x0238 }, - { 0x0013, 0x0239 }, - { 0x0013, 0x023a }, - { 0x0013, 0x023b }, - { 0x0013, 0x023c }, - { 0x0013, 0x023d }, - { 0x0013, 0x023e }, - { 0x0013, 0x023f }, - { 0x0013, 0x0240 }, - { 0x0013, 0x0241 }, - { 0x0013, 0x0242 }, - { 0x0013, 0x0243 }, - { 0x0013, 0x0244 }, - { 0x0013, 0x0245 }, - { 0x0013, 0x0246 }, - { 0x0013, 0x0247 }, - { 0x0013, 0x0248 }, - { 0x0013, 0x0249 }, - { 0x0013, 0x024a }, - { 0x0013, 0x024b }, - { 0x0013, 0x024c }, - { 0x0013, 0x024d }, - { 0x0013, 0x024e }, - { 0x0013, 0x024f }, - { 0x0013, 0x0250 }, - { 0x0013, 0x0251 }, - { 0x0013, 0x0252 }, - { 0x0013, 0x0253 }, - { 0x0013, 0x0254 }, - { 0x0013, 0x0255 }, - { 0x0013, 0x0256 }, - { 0x0013, 0x0257 }, - { 0x0013, 0x0258 }, - { 0x0013, 0x0259 }, - { 0x0013, 0x025a }, - { 0x0013, 0x025b }, - { 0x0013, 0x025c }, - { 0x0013, 0x025d }, - { 0x0013, 0x025e }, - { 0x0013, 0x025f }, - { 0x0013, 0x0260 }, - { 0x0013, 0x0261 }, - { 0x0013, 0x0262 }, - { 0x0013, 0x0263 }, - { 0x0013, 0x0264 }, - { 0x0013, 0x0265 }, - { 0x0013, 0x0266 }, - { 0x0013, 0x0267 }, - { 0x0013, 0x0268 }, - { 0x0013, 0x0269 }, - { 0x0013, 0x026a }, - { 0x0013, 0x026b }, - { 0x0012, 0x013f }, - - }; - -const uint16_t c_aauiLCLDHuffEnc49[729][2] = - { - { 0x0002, 0x0003 }, - { 0x0003, 0x0003 }, - { 0x0005, 0x0007 }, - { 0x0007, 0x000a }, - { 0x0008, 0x0009 }, - { 0x0008, 0x000a }, - { 0x0009, 0x0009 }, - { 0x000b, 0x000d }, - { 0x000d, 0x0014 }, - { 0x000d, 0x0015 }, - { 0x0010, 0x0052 }, - { 0x0011, 0x0098 }, - { 0x0013, 0x0000 }, - { 0x0013, 0x0001 }, - { 0x0013, 0x0002 }, - { 0x0013, 0x0003 }, - { 0x0013, 0x0004 }, - { 0x0013, 0x0005 }, - { 0x0013, 0x0006 }, - { 0x0013, 0x0007 }, - { 0x0013, 0x0008 }, - { 0x0013, 0x0009 }, - { 0x0013, 0x000a }, - { 0x0013, 0x000b }, - { 0x0013, 0x000c }, - { 0x0013, 0x000d }, - { 0x0013, 0x000e }, - { 0x0003, 0x0004 }, - { 0x0003, 0x0005 }, - { 0x0005, 0x0008 }, - { 0x0006, 0x000a }, - { 0x0007, 0x000b }, - { 0x0008, 0x000b }, - { 0x0008, 0x000c }, - { 0x000a, 0x000a }, - { 0x000b, 0x000e }, - { 0x000d, 0x0016 }, - { 0x000f, 0x0031 }, - { 0x0010, 0x0053 }, - { 0x0012, 0x012a }, - { 0x0013, 0x000f }, - { 0x0013, 0x0010 }, - { 0x0013, 0x0011 }, - { 0x0013, 0x0012 }, - { 0x0013, 0x0013 }, - { 0x0013, 0x0014 }, - { 0x0013, 0x0015 }, - { 0x0013, 0x0016 }, - { 0x0013, 0x0017 }, - { 0x0013, 0x0018 }, - { 0x0013, 0x0019 }, - { 0x0013, 0x001a }, - { 0x0013, 0x001b }, - { 0x0013, 0x001c }, - { 0x0005, 0x0009 }, - { 0x0005, 0x000a }, - { 0x0005, 0x000b }, - { 0x0006, 0x000b }, - { 0x0007, 0x000c }, - { 0x0008, 0x000d }, - { 0x0009, 0x000a }, - { 0x000a, 0x000b }, - { 0x000c, 0x000f }, - { 0x000d, 0x0017 }, - { 0x000f, 0x0032 }, - { 0x0010, 0x0054 }, - { 0x0013, 0x001d }, - { 0x0013, 0x001e }, - { 0x0013, 0x001f }, - { 0x0013, 0x0020 }, - { 0x0013, 0x0021 }, - { 0x0013, 0x0022 }, - { 0x0013, 0x0023 }, - { 0x0013, 0x0024 }, - { 0x0013, 0x0025 }, - { 0x0013, 0x0026 }, - { 0x0013, 0x0027 }, - { 0x0013, 0x0028 }, - { 0x0013, 0x0029 }, - { 0x0013, 0x002a }, - { 0x0013, 0x002b }, - { 0x0007, 0x000d }, - { 0x0006, 0x000c }, - { 0x0006, 0x000d }, - { 0x0007, 0x000e }, - { 0x0007, 0x000f }, - { 0x0008, 0x000e }, - { 0x0009, 0x000b }, - { 0x000b, 0x000f }, - { 0x000c, 0x0010 }, - { 0x000e, 0x001d }, - { 0x000f, 0x0033 }, - { 0x0011, 0x0099 }, - { 0x0013, 0x002c }, - { 0x0013, 0x002d }, - { 0x0013, 0x002e }, - { 0x0013, 0x002f }, - { 0x0013, 0x0030 }, - { 0x0013, 0x0031 }, - { 0x0013, 0x0032 }, - { 0x0013, 0x0033 }, - { 0x0013, 0x0034 }, - { 0x0013, 0x0035 }, - { 0x0013, 0x0036 }, - { 0x0013, 0x0037 }, - { 0x0013, 0x0038 }, - { 0x0013, 0x0039 }, - { 0x0013, 0x003a }, - { 0x0008, 0x000f }, - { 0x0007, 0x0010 }, - { 0x0007, 0x0011 }, - { 0x0007, 0x0012 }, - { 0x0008, 0x0010 }, - { 0x0009, 0x000c }, - { 0x000a, 0x000c }, - { 0x000c, 0x0011 }, - { 0x000d, 0x0018 }, - { 0x000e, 0x001e }, - { 0x0011, 0x009a }, - { 0x0011, 0x009b }, - { 0x0013, 0x003b }, - { 0x0013, 0x003c }, - { 0x0013, 0x003d }, - { 0x0013, 0x003e }, - { 0x0013, 0x003f }, - { 0x0013, 0x0040 }, - { 0x0013, 0x0041 }, - { 0x0013, 0x0042 }, - { 0x0013, 0x0043 }, - { 0x0013, 0x0044 }, - { 0x0013, 0x0045 }, - { 0x0013, 0x0046 }, - { 0x0013, 0x0047 }, - { 0x0013, 0x0048 }, - { 0x0013, 0x0049 }, - { 0x0008, 0x0011 }, - { 0x0007, 0x0013 }, - { 0x0008, 0x0012 }, - { 0x0008, 0x0013 }, - { 0x0009, 0x000d }, - { 0x000a, 0x000d }, - { 0x000b, 0x0010 }, - { 0x000c, 0x0012 }, - { 0x000e, 0x001f }, - { 0x000e, 0x0020 }, - { 0x0010, 0x0055 }, - { 0x0011, 0x009c }, - { 0x0013, 0x004a }, - { 0x0013, 0x004b }, - { 0x0013, 0x004c }, - { 0x0013, 0x004d }, - { 0x0013, 0x004e }, - { 0x0013, 0x004f }, - { 0x0013, 0x0050 }, - { 0x0013, 0x0051 }, - { 0x0013, 0x0052 }, - { 0x0013, 0x0053 }, - { 0x0013, 0x0054 }, - { 0x0013, 0x0055 }, - { 0x0013, 0x0056 }, - { 0x0013, 0x0057 }, - { 0x0013, 0x0058 }, - { 0x0009, 0x000e }, - { 0x0009, 0x000f }, - { 0x0009, 0x0010 }, - { 0x0009, 0x0011 }, - { 0x000a, 0x000e }, - { 0x000b, 0x0011 }, - { 0x000c, 0x0013 }, - { 0x000d, 0x0019 }, - { 0x000e, 0x0021 }, - { 0x0010, 0x0056 }, - { 0x0010, 0x0057 }, - { 0x0013, 0x0059 }, - { 0x0013, 0x005a }, - { 0x0013, 0x005b }, - { 0x0013, 0x005c }, - { 0x0013, 0x005d }, - { 0x0013, 0x005e }, - { 0x0013, 0x005f }, - { 0x0013, 0x0060 }, - { 0x0013, 0x0061 }, - { 0x0013, 0x0062 }, - { 0x0013, 0x0063 }, - { 0x0013, 0x0064 }, - { 0x0013, 0x0065 }, - { 0x0013, 0x0066 }, - { 0x0013, 0x0067 }, - { 0x0013, 0x0068 }, - { 0x000b, 0x0012 }, - { 0x000a, 0x000f }, - { 0x000a, 0x0010 }, - { 0x000a, 0x0011 }, - { 0x000c, 0x0014 }, - { 0x000c, 0x0015 }, - { 0x000d, 0x001a }, - { 0x000e, 0x0022 }, - { 0x0010, 0x0058 }, - { 0x0010, 0x0059 }, - { 0x0013, 0x0069 }, - { 0x0013, 0x006a }, - { 0x0013, 0x006b }, - { 0x0013, 0x006c }, - { 0x0013, 0x006d }, - { 0x0013, 0x006e }, - { 0x0013, 0x006f }, - { 0x0013, 0x0070 }, - { 0x0013, 0x0071 }, - { 0x0013, 0x0072 }, - { 0x0013, 0x0073 }, - { 0x0013, 0x0074 }, - { 0x0013, 0x0075 }, - { 0x0013, 0x0076 }, - { 0x0013, 0x0077 }, - { 0x0013, 0x0078 }, - { 0x0013, 0x0079 }, - { 0x000c, 0x0016 }, - { 0x000b, 0x0013 }, - { 0x000c, 0x0017 }, - { 0x000c, 0x0018 }, - { 0x000c, 0x0019 }, - { 0x000e, 0x0023 }, - { 0x000e, 0x0024 }, - { 0x000f, 0x0034 }, - { 0x0010, 0x005a }, - { 0x0011, 0x009d }, - { 0x0013, 0x007a }, - { 0x0013, 0x007b }, - { 0x0013, 0x007c }, - { 0x0013, 0x007d }, - { 0x0013, 0x007e }, - { 0x0013, 0x007f }, - { 0x0013, 0x0080 }, - { 0x0013, 0x0081 }, - { 0x0013, 0x0082 }, - { 0x0013, 0x0083 }, - { 0x0013, 0x0084 }, - { 0x0013, 0x0085 }, - { 0x0013, 0x0086 }, - { 0x0013, 0x0087 }, - { 0x0013, 0x0088 }, - { 0x0013, 0x0089 }, - { 0x0013, 0x008a }, - { 0x000e, 0x0025 }, - { 0x000d, 0x001b }, - { 0x000d, 0x001c }, - { 0x000d, 0x001d }, - { 0x000e, 0x0026 }, - { 0x000f, 0x0035 }, - { 0x0010, 0x005b }, - { 0x0011, 0x009e }, - { 0x0011, 0x009f }, - { 0x0012, 0x012b }, - { 0x0013, 0x008b }, - { 0x0013, 0x008c }, - { 0x0013, 0x008d }, - { 0x0013, 0x008e }, - { 0x0013, 0x008f }, - { 0x0013, 0x0090 }, - { 0x0013, 0x0091 }, - { 0x0013, 0x0092 }, - { 0x0013, 0x0093 }, - { 0x0013, 0x0094 }, - { 0x0013, 0x0095 }, - { 0x0013, 0x0096 }, - { 0x0013, 0x0097 }, - { 0x0013, 0x0098 }, - { 0x0013, 0x0099 }, - { 0x0013, 0x009a }, - { 0x0013, 0x009b }, - { 0x0010, 0x005c }, - { 0x000f, 0x0036 }, - { 0x000e, 0x0027 }, - { 0x000f, 0x0037 }, - { 0x000f, 0x0038 }, - { 0x0010, 0x005d }, - { 0x0011, 0x00a0 }, - { 0x0013, 0x009c }, - { 0x0012, 0x012c }, - { 0x0013, 0x009d }, - { 0x0013, 0x009e }, - { 0x0013, 0x009f }, - { 0x0013, 0x00a0 }, - { 0x0013, 0x00a1 }, - { 0x0013, 0x00a2 }, - { 0x0013, 0x00a3 }, - { 0x0013, 0x00a4 }, - { 0x0013, 0x00a5 }, - { 0x0013, 0x00a6 }, - { 0x0013, 0x00a7 }, - { 0x0013, 0x00a8 }, - { 0x0013, 0x00a9 }, - { 0x0013, 0x00aa }, - { 0x0013, 0x00ab }, - { 0x0013, 0x00ac }, - { 0x0013, 0x00ad }, - { 0x0013, 0x00ae }, - { 0x0010, 0x005e }, - { 0x000f, 0x0039 }, - { 0x0010, 0x005f }, - { 0x0010, 0x0060 }, - { 0x0011, 0x00a1 }, - { 0x0010, 0x0061 }, - { 0x0013, 0x00af }, - { 0x0013, 0x00b0 }, - { 0x0012, 0x012d }, - { 0x0013, 0x00b1 }, - { 0x0013, 0x00b2 }, - { 0x0013, 0x00b3 }, - { 0x0013, 0x00b4 }, - { 0x0013, 0x00b5 }, - { 0x0013, 0x00b6 }, - { 0x0013, 0x00b7 }, - { 0x0013, 0x00b8 }, - { 0x0013, 0x00b9 }, - { 0x0013, 0x00ba }, - { 0x0013, 0x00bb }, - { 0x0013, 0x00bc }, - { 0x0013, 0x00bd }, - { 0x0013, 0x00be }, - { 0x0013, 0x00bf }, - { 0x0013, 0x00c0 }, - { 0x0013, 0x00c1 }, - { 0x0013, 0x00c2 }, - { 0x0012, 0x012e }, - { 0x0011, 0x00a2 }, - { 0x0011, 0x00a3 }, - { 0x0013, 0x00c3 }, - { 0x0013, 0x00c4 }, - { 0x0013, 0x00c5 }, - { 0x0013, 0x00c6 }, - { 0x0013, 0x00c7 }, - { 0x0013, 0x00c8 }, - { 0x0013, 0x00c9 }, - { 0x0013, 0x00ca }, - { 0x0013, 0x00cb }, - { 0x0013, 0x00cc }, - { 0x0013, 0x00cd }, - { 0x0013, 0x00ce }, - { 0x0013, 0x00cf }, - { 0x0013, 0x00d0 }, - { 0x0013, 0x00d1 }, - { 0x0013, 0x00d2 }, - { 0x0013, 0x00d3 }, - { 0x0013, 0x00d4 }, - { 0x0013, 0x00d5 }, - { 0x0013, 0x00d6 }, - { 0x0013, 0x00d7 }, - { 0x0013, 0x00d8 }, - { 0x0013, 0x00d9 }, - { 0x0013, 0x00da }, - { 0x0013, 0x00db }, - { 0x0013, 0x00dc }, - { 0x0013, 0x00dd }, - { 0x0013, 0x00de }, - { 0x0013, 0x00df }, - { 0x0012, 0x012f }, - { 0x0013, 0x00e0 }, - { 0x0013, 0x00e1 }, - { 0x0013, 0x00e2 }, - { 0x0013, 0x00e3 }, - { 0x0013, 0x00e4 }, - { 0x0013, 0x00e5 }, - { 0x0013, 0x00e6 }, - { 0x0013, 0x00e7 }, - { 0x0013, 0x00e8 }, - { 0x0013, 0x00e9 }, - { 0x0013, 0x00ea }, - { 0x0013, 0x00eb }, - { 0x0013, 0x00ec }, - { 0x0013, 0x00ed }, - { 0x0013, 0x00ee }, - { 0x0013, 0x00ef }, - { 0x0013, 0x00f0 }, - { 0x0013, 0x00f1 }, - { 0x0013, 0x00f2 }, - { 0x0013, 0x00f3 }, - { 0x0013, 0x00f4 }, - { 0x0013, 0x00f5 }, - { 0x0013, 0x00f6 }, - { 0x0013, 0x00f7 }, - { 0x0013, 0x00f8 }, - { 0x0013, 0x00f9 }, - { 0x0013, 0x00fa }, - { 0x0013, 0x00fb }, - { 0x0013, 0x00fc }, - { 0x0013, 0x00fd }, - { 0x0013, 0x00fe }, - { 0x0013, 0x00ff }, - { 0x0013, 0x0100 }, - { 0x0013, 0x0101 }, - { 0x0013, 0x0102 }, - { 0x0013, 0x0103 }, - { 0x0013, 0x0104 }, - { 0x0013, 0x0105 }, - { 0x0013, 0x0106 }, - { 0x0013, 0x0107 }, - { 0x0013, 0x0108 }, - { 0x0013, 0x0109 }, - { 0x0013, 0x010a }, - { 0x0013, 0x010b }, - { 0x0013, 0x010c }, - { 0x0013, 0x010d }, - { 0x0013, 0x010e }, - { 0x0013, 0x010f }, - { 0x0013, 0x0110 }, - { 0x0013, 0x0111 }, - { 0x0013, 0x0112 }, - { 0x0013, 0x0113 }, - { 0x0013, 0x0114 }, - { 0x0013, 0x0115 }, - { 0x0013, 0x0116 }, - { 0x0013, 0x0117 }, - { 0x0013, 0x0118 }, - { 0x0013, 0x0119 }, - { 0x0013, 0x011a }, - { 0x0013, 0x011b }, - { 0x0013, 0x011c }, - { 0x0013, 0x011d }, - { 0x0013, 0x011e }, - { 0x0013, 0x011f }, - { 0x0013, 0x0120 }, - { 0x0013, 0x0121 }, - { 0x0013, 0x0122 }, - { 0x0013, 0x0123 }, - { 0x0013, 0x0124 }, - { 0x0013, 0x0125 }, - { 0x0013, 0x0126 }, - { 0x0013, 0x0127 }, - { 0x0013, 0x0128 }, - { 0x0013, 0x0129 }, - { 0x0013, 0x012a }, - { 0x0013, 0x012b }, - { 0x0013, 0x012c }, - { 0x0013, 0x012d }, - { 0x0013, 0x012e }, - { 0x0013, 0x012f }, - { 0x0013, 0x0130 }, - { 0x0013, 0x0131 }, - { 0x0013, 0x0132 }, - { 0x0013, 0x0133 }, - { 0x0013, 0x0134 }, - { 0x0013, 0x0135 }, - { 0x0013, 0x0136 }, - { 0x0013, 0x0137 }, - { 0x0013, 0x0138 }, - { 0x0013, 0x0139 }, - { 0x0013, 0x013a }, - { 0x0013, 0x013b }, - { 0x0013, 0x013c }, - { 0x0013, 0x013d }, - { 0x0013, 0x013e }, - { 0x0013, 0x013f }, - { 0x0013, 0x0140 }, - { 0x0013, 0x0141 }, - { 0x0013, 0x0142 }, - { 0x0013, 0x0143 }, - { 0x0013, 0x0144 }, - { 0x0013, 0x0145 }, - { 0x0013, 0x0146 }, - { 0x0013, 0x0147 }, - { 0x0013, 0x0148 }, - { 0x0013, 0x0149 }, - { 0x0013, 0x014a }, - { 0x0013, 0x014b }, - { 0x0013, 0x014c }, - { 0x0013, 0x014d }, - { 0x0013, 0x014e }, - { 0x0013, 0x014f }, - { 0x0013, 0x0150 }, - { 0x0013, 0x0151 }, - { 0x0013, 0x0152 }, - { 0x0013, 0x0153 }, - { 0x0013, 0x0154 }, - { 0x0013, 0x0155 }, - { 0x0013, 0x0156 }, - { 0x0013, 0x0157 }, - { 0x0013, 0x0158 }, - { 0x0013, 0x0159 }, - { 0x0013, 0x015a }, - { 0x0013, 0x015b }, - { 0x0013, 0x015c }, - { 0x0013, 0x015d }, - { 0x0013, 0x015e }, - { 0x0013, 0x015f }, - { 0x0013, 0x0160 }, - { 0x0013, 0x0161 }, - { 0x0013, 0x0162 }, - { 0x0013, 0x0163 }, - { 0x0013, 0x0164 }, - { 0x0013, 0x0165 }, - { 0x0013, 0x0166 }, - { 0x0013, 0x0167 }, - { 0x0013, 0x0168 }, - { 0x0013, 0x0169 }, - { 0x0013, 0x016a }, - { 0x0013, 0x016b }, - { 0x0013, 0x016c }, - { 0x0013, 0x016d }, - { 0x0013, 0x016e }, - { 0x0013, 0x016f }, - { 0x0013, 0x0170 }, - { 0x0013, 0x0171 }, - { 0x0013, 0x0172 }, - { 0x0013, 0x0173 }, - { 0x0013, 0x0174 }, - { 0x0013, 0x0175 }, - { 0x0013, 0x0176 }, - { 0x0013, 0x0177 }, - { 0x0013, 0x0178 }, - { 0x0013, 0x0179 }, - { 0x0013, 0x017a }, - { 0x0013, 0x017b }, - { 0x0013, 0x017c }, - { 0x0013, 0x017d }, - { 0x0013, 0x017e }, - { 0x0013, 0x017f }, - { 0x0013, 0x0180 }, - { 0x0013, 0x0181 }, - { 0x0013, 0x0182 }, - { 0x0013, 0x0183 }, - { 0x0013, 0x0184 }, - { 0x0013, 0x0185 }, - { 0x0013, 0x0186 }, - { 0x0013, 0x0187 }, - { 0x0013, 0x0188 }, - { 0x0013, 0x0189 }, - { 0x0013, 0x018a }, - { 0x0013, 0x018b }, - { 0x0013, 0x018c }, - { 0x0013, 0x018d }, - { 0x0013, 0x018e }, - { 0x0013, 0x018f }, - { 0x0013, 0x0190 }, - { 0x0013, 0x0191 }, - { 0x0013, 0x0192 }, - { 0x0013, 0x0193 }, - { 0x0013, 0x0194 }, - { 0x0013, 0x0195 }, - { 0x0013, 0x0196 }, - { 0x0013, 0x0197 }, - { 0x0013, 0x0198 }, - { 0x0013, 0x0199 }, - { 0x0013, 0x019a }, - { 0x0013, 0x019b }, - { 0x0013, 0x019c }, - { 0x0013, 0x019d }, - { 0x0013, 0x019e }, - { 0x0013, 0x019f }, - { 0x0013, 0x01a0 }, - { 0x0013, 0x01a1 }, - { 0x0013, 0x01a2 }, - { 0x0013, 0x01a3 }, - { 0x0013, 0x01a4 }, - { 0x0013, 0x01a5 }, - { 0x0013, 0x01a6 }, - { 0x0013, 0x01a7 }, - { 0x0013, 0x01a8 }, - { 0x0013, 0x01a9 }, - { 0x0013, 0x01aa }, - { 0x0013, 0x01ab }, - { 0x0013, 0x01ac }, - { 0x0013, 0x01ad }, - { 0x0013, 0x01ae }, - { 0x0013, 0x01af }, - { 0x0013, 0x01b0 }, - { 0x0013, 0x01b1 }, - { 0x0013, 0x01b2 }, - { 0x0013, 0x01b3 }, - { 0x0013, 0x01b4 }, - { 0x0013, 0x01b5 }, - { 0x0013, 0x01b6 }, - { 0x0013, 0x01b7 }, - { 0x0013, 0x01b8 }, - { 0x0013, 0x01b9 }, - { 0x0013, 0x01ba }, - { 0x0013, 0x01bb }, - { 0x0013, 0x01bc }, - { 0x0013, 0x01bd }, - { 0x0013, 0x01be }, - { 0x0013, 0x01bf }, - { 0x0013, 0x01c0 }, - { 0x0013, 0x01c1 }, - { 0x0013, 0x01c2 }, - { 0x0013, 0x01c3 }, - { 0x0013, 0x01c4 }, - { 0x0013, 0x01c5 }, - { 0x0013, 0x01c6 }, - { 0x0013, 0x01c7 }, - { 0x0013, 0x01c8 }, - { 0x0013, 0x01c9 }, - { 0x0013, 0x01ca }, - { 0x0013, 0x01cb }, - { 0x0013, 0x01cc }, - { 0x0013, 0x01cd }, - { 0x0013, 0x01ce }, - { 0x0013, 0x01cf }, - { 0x0013, 0x01d0 }, - { 0x0013, 0x01d1 }, - { 0x0013, 0x01d2 }, - { 0x0013, 0x01d3 }, - { 0x0013, 0x01d4 }, - { 0x0013, 0x01d5 }, - { 0x0013, 0x01d6 }, - { 0x0013, 0x01d7 }, - { 0x0013, 0x01d8 }, - { 0x0013, 0x01d9 }, - { 0x0013, 0x01da }, - { 0x0013, 0x01db }, - { 0x0013, 0x01dc }, - { 0x0013, 0x01dd }, - { 0x0013, 0x01de }, - { 0x0013, 0x01df }, - { 0x0013, 0x01e0 }, - { 0x0013, 0x01e1 }, - { 0x0013, 0x01e2 }, - { 0x0013, 0x01e3 }, - { 0x0013, 0x01e4 }, - { 0x0013, 0x01e5 }, - { 0x0013, 0x01e6 }, - { 0x0013, 0x01e7 }, - { 0x0013, 0x01e8 }, - { 0x0013, 0x01e9 }, - { 0x0013, 0x01ea }, - { 0x0013, 0x01eb }, - { 0x0013, 0x01ec }, - { 0x0013, 0x01ed }, - { 0x0013, 0x01ee }, - { 0x0013, 0x01ef }, - { 0x0013, 0x01f0 }, - { 0x0013, 0x01f1 }, - { 0x0013, 0x01f2 }, - { 0x0013, 0x01f3 }, - { 0x0013, 0x01f4 }, - { 0x0013, 0x01f5 }, - { 0x0013, 0x01f6 }, - { 0x0013, 0x01f7 }, - { 0x0013, 0x01f8 }, - { 0x0013, 0x01f9 }, - { 0x0013, 0x01fa }, - { 0x0013, 0x01fb }, - { 0x0013, 0x01fc }, - { 0x0013, 0x01fd }, - { 0x0013, 0x01fe }, - { 0x0013, 0x01ff }, - { 0x0013, 0x0200 }, - { 0x0013, 0x0201 }, - { 0x0013, 0x0202 }, - { 0x0013, 0x0203 }, - { 0x0013, 0x0204 }, - { 0x0013, 0x0205 }, - { 0x0013, 0x0206 }, - { 0x0013, 0x0207 }, - { 0x0013, 0x0208 }, - { 0x0013, 0x0209 }, - { 0x0013, 0x020a }, - { 0x0013, 0x020b }, - { 0x0013, 0x020c }, - { 0x0013, 0x020d }, - { 0x0013, 0x020e }, - { 0x0013, 0x020f }, - { 0x0013, 0x0210 }, - { 0x0013, 0x0211 }, - { 0x0013, 0x0212 }, - { 0x0013, 0x0213 }, - { 0x0013, 0x0214 }, - { 0x0013, 0x0215 }, - { 0x0013, 0x0216 }, - { 0x0013, 0x0217 }, - { 0x0013, 0x0218 }, - { 0x0013, 0x0219 }, - { 0x0013, 0x021a }, - { 0x0013, 0x021b }, - { 0x0013, 0x021c }, - { 0x0013, 0x021d }, - { 0x0013, 0x021e }, - { 0x0013, 0x021f }, - { 0x0013, 0x0220 }, - { 0x0013, 0x0221 }, - { 0x0013, 0x0222 }, - { 0x0013, 0x0223 }, - { 0x0013, 0x0224 }, - { 0x0013, 0x0225 }, - { 0x0013, 0x0226 }, - { 0x0013, 0x0227 }, - { 0x0013, 0x0228 }, - { 0x0013, 0x0229 }, - { 0x0013, 0x022a }, - { 0x0013, 0x022b }, - { 0x0013, 0x022c }, - { 0x0013, 0x022d }, - { 0x0013, 0x022e }, - { 0x0013, 0x022f }, - { 0x0013, 0x0230 }, - { 0x0013, 0x0231 }, - { 0x0013, 0x0232 }, - { 0x0013, 0x0233 }, - { 0x0013, 0x0234 }, - { 0x0013, 0x0235 }, - { 0x0013, 0x0236 }, - { 0x0013, 0x0237 }, - { 0x0013, 0x0238 }, - { 0x0013, 0x0239 }, - { 0x0013, 0x023a }, - { 0x0013, 0x023b }, - { 0x0013, 0x023c }, - { 0x0013, 0x023d }, - { 0x0013, 0x023e }, - { 0x0013, 0x023f }, - { 0x0013, 0x0240 }, - { 0x0013, 0x0241 }, - { 0x0013, 0x0242 }, - { 0x0013, 0x0243 }, - { 0x0013, 0x0244 }, - { 0x0013, 0x0245 }, - { 0x0013, 0x0246 }, - { 0x0013, 0x0247 }, - { 0x0013, 0x0248 }, - { 0x0013, 0x0249 }, - { 0x0013, 0x024a }, - { 0x0013, 0x024b }, - { 0x0013, 0x024c }, - { 0x0013, 0x024d }, - { 0x0013, 0x024e }, - { 0x0013, 0x024f }, - { 0x0013, 0x0250 }, - { 0x0013, 0x0251 }, - { 0x0013, 0x0252 }, - { 0x0013, 0x0253 }, - - }; - -const uint16_t c_aauiLCLDHuffEnc50[28][2] = - { - { 0x0002, 0x0001 }, - { 0x0002, 0x0002 }, - { 0x0002, 0x0003 }, - { 0x0003, 0x0001 }, - { 0x0004, 0x0001 }, - { 0x0005, 0x0001 }, - { 0x0006, 0x0001 }, - { 0x0007, 0x0001 }, - { 0x0008, 0x0001 }, - { 0x0009, 0x0001 }, - { 0x000a, 0x0001 }, - { 0x000b, 0x0001 }, - { 0x000c, 0x0001 }, - { 0x000d, 0x0001 }, - { 0x000e, 0x0001 }, - { 0x000f, 0x0001 }, - { 0x0011, 0x0003 }, - { 0x0012, 0x0005 }, - { 0x0013, 0x0000 }, - { 0x0013, 0x0001 }, - { 0x0013, 0x0002 }, - { 0x0013, 0x0003 }, - { 0x0013, 0x0004 }, - { 0x0013, 0x0005 }, - { 0x0013, 0x0006 }, - { 0x0013, 0x0007 }, - { 0x0013, 0x0008 }, - { 0x0013, 0x0009 }, - - }; - -const uint16_t c_aauiLCLDHuffEnc51[29][2] = - { - { 0x0002, 0x0002 }, - { 0x0002, 0x0003 }, - { 0x0003, 0x0002 }, - { 0x0003, 0x0003 }, - { 0x0004, 0x0001 }, - { 0x0004, 0x0002 }, - { 0x0004, 0x0003 }, - { 0x0005, 0x0001 }, - { 0x0006, 0x0001 }, - { 0x0007, 0x0001 }, - { 0x0008, 0x0001 }, - { 0x0009, 0x0001 }, - { 0x000a, 0x0001 }, - { 0x000b, 0x0001 }, - { 0x000c, 0x0001 }, - { 0x000d, 0x0001 }, - { 0x000e, 0x0001 }, - { 0x0010, 0x0002 }, - { 0x0010, 0x0003 }, - { 0x0012, 0x0002 }, - { 0x0012, 0x0003 }, - { 0x0013, 0x0000 }, - { 0x0013, 0x0001 }, - { 0x0013, 0x0002 }, - { 0x0013, 0x0003 }, - { 0x0012, 0x0004 }, - { 0x0012, 0x0005 }, - { 0x0012, 0x0006 }, - { 0x0012, 0x0007 }, - - }; - -const uint16_t c_aauiLCLDHuffEnc52[32][2] = - { - { 0x0002, 0x0002 }, - { 0x0002, 0x0003 }, - { 0x0003, 0x0002 }, - { 0x0003, 0x0003 }, - { 0x0004, 0x0002 }, - { 0x0004, 0x0003 }, - { 0x0005, 0x0001 }, - { 0x0005, 0x0002 }, - { 0x0005, 0x0003 }, - { 0x0006, 0x0001 }, - { 0x0007, 0x0001 }, - { 0x0008, 0x0001 }, - { 0x0009, 0x0001 }, - { 0x000a, 0x0001 }, - { 0x000b, 0x0001 }, - { 0x000c, 0x0001 }, - { 0x000e, 0x0001 }, - { 0x000e, 0x0002 }, - { 0x000e, 0x0003 }, - { 0x000f, 0x0001 }, - { 0x0011, 0x0002 }, - { 0x0011, 0x0003 }, - { 0x0012, 0x0003 }, - { 0x0014, 0x0000 }, - { 0x0013, 0x0003 }, - { 0x0014, 0x0001 }, - { 0x0014, 0x0002 }, - { 0x0014, 0x0003 }, - { 0x0014, 0x0004 }, - { 0x0014, 0x0005 }, - { 0x0013, 0x0004 }, - { 0x0013, 0x0005 }, - }; - -const uint16_t c_aauiLCLDHuffEnc53[37][2] = - { - { 0x0002, 0x0002 }, - { 0x0002, 0x0003 }, - { 0x0003, 0x0002 }, - { 0x0003, 0x0003 }, - { 0x0004, 0x0002 }, - { 0x0004, 0x0003 }, - { 0x0005, 0x0002 }, - { 0x0005, 0x0003 }, - { 0x0006, 0x0002 }, - { 0x0006, 0x0003 }, - { 0x0007, 0x0001 }, - { 0x0007, 0x0002 }, - { 0x0007, 0x0003 }, - { 0x0008, 0x0001 }, - { 0x0009, 0x0001 }, - { 0x000b, 0x0002 }, - { 0x000b, 0x0003 }, - { 0x000c, 0x0002 }, - { 0x000c, 0x0003 }, - { 0x000d, 0x0002 }, - { 0x000d, 0x0003 }, - { 0x000e, 0x0002 }, - { 0x000e, 0x0003 }, - { 0x000f, 0x0002 }, - { 0x000f, 0x0003 }, - { 0x0011, 0x0004 }, - { 0x0010, 0x0003 }, - { 0x0011, 0x0005 }, - { 0x0013, 0x0000 }, - { 0x0013, 0x0001 }, - { 0x0012, 0x0001 }, - { 0x0012, 0x0002 }, - { 0x0012, 0x0003 }, - { 0x0012, 0x0004 }, - { 0x0012, 0x0005 }, - { 0x0012, 0x0006 }, - { 0x0012, 0x0007 }, - - }; - -const uint16_t c_aauiLCLDHuffEnc54[39][2] = - { - { 0x0002, 0x0002 }, - { 0x0002, 0x0003 }, - { 0x0003, 0x0002 }, - { 0x0003, 0x0003 }, - { 0x0004, 0x0003 }, - { 0x0005, 0x0003 }, - { 0x0005, 0x0004 }, - { 0x0005, 0x0005 }, - { 0x0006, 0x0002 }, - { 0x0006, 0x0003 }, - { 0x0006, 0x0004 }, - { 0x0006, 0x0005 }, - { 0x0007, 0x0002 }, - { 0x0007, 0x0003 }, - { 0x0008, 0x0001 }, - { 0x0008, 0x0002 }, - { 0x0008, 0x0003 }, - { 0x000a, 0x0002 }, - { 0x000a, 0x0003 }, - { 0x000b, 0x0002 }, - { 0x000b, 0x0003 }, - { 0x000c, 0x0002 }, - { 0x000c, 0x0003 }, - { 0x000d, 0x0002 }, - { 0x000d, 0x0003 }, - { 0x000e, 0x0002 }, - { 0x000e, 0x0003 }, - { 0x000f, 0x0002 }, - { 0x000f, 0x0003 }, - { 0x0011, 0x0002 }, - { 0x0010, 0x0002 }, - { 0x0010, 0x0003 }, - { 0x0011, 0x0003 }, - { 0x0012, 0x0002 }, - { 0x0012, 0x0003 }, - { 0x0013, 0x0000 }, - { 0x0013, 0x0001 }, - { 0x0013, 0x0002 }, - { 0x0013, 0x0003 }, - - }; - -const uint16_t c_aauiLCLDHuffEnc55[46][2] = - { - { 0x0003, 0x0003 }, - { 0x0002, 0x0003 }, - { 0x0003, 0x0004 }, - { 0x0003, 0x0005 }, - { 0x0004, 0x0003 }, - { 0x0004, 0x0004 }, - { 0x0004, 0x0005 }, - { 0x0005, 0x0003 }, - { 0x0005, 0x0004 }, - { 0x0005, 0x0005 }, - { 0x0006, 0x0003 }, - { 0x0006, 0x0004 }, - { 0x0006, 0x0005 }, - { 0x0007, 0x0002 }, - { 0x0007, 0x0003 }, - { 0x0007, 0x0004 }, - { 0x0007, 0x0005 }, - { 0x0008, 0x0002 }, - { 0x0008, 0x0003 }, - { 0x0009, 0x0002 }, - { 0x0009, 0x0003 }, - { 0x000a, 0x0002 }, - { 0x000a, 0x0003 }, - { 0x000b, 0x0002 }, - { 0x000b, 0x0003 }, - { 0x000c, 0x0002 }, - { 0x000c, 0x0003 }, - { 0x000d, 0x0002 }, - { 0x000d, 0x0003 }, - { 0x000e, 0x0002 }, - { 0x000e, 0x0003 }, - { 0x000f, 0x0003 }, - { 0x0010, 0x0002 }, - { 0x0010, 0x0003 }, - { 0x0010, 0x0004 }, - { 0x0010, 0x0005 }, - { 0x0011, 0x0003 }, - { 0x0012, 0x0003 }, - { 0x0012, 0x0004 }, - { 0x0012, 0x0005 }, - { 0x0013, 0x0000 }, - { 0x0013, 0x0001 }, - { 0x0013, 0x0002 }, - { 0x0013, 0x0003 }, - { 0x0013, 0x0004 }, - { 0x0013, 0x0005 }, - - }; - -const uint16_t c_aauiLCLDHuffEnc56[55][2] = - { - { 0x0003, 0x0003 }, - { 0x0002, 0x0003 }, - { 0x0003, 0x0004 }, - { 0x0003, 0x0005 }, - { 0x0004, 0x0004 }, - { 0x0004, 0x0005 }, - { 0x0005, 0x0003 }, - { 0x0005, 0x0004 }, - { 0x0005, 0x0005 }, - { 0x0005, 0x0006 }, - { 0x0005, 0x0007 }, - { 0x0006, 0x0003 }, - { 0x0006, 0x0004 }, - { 0x0006, 0x0005 }, - { 0x0007, 0x0003 }, - { 0x0007, 0x0004 }, - { 0x0007, 0x0005 }, - { 0x0008, 0x0002 }, - { 0x0008, 0x0003 }, - { 0x0008, 0x0004 }, - { 0x0008, 0x0005 }, - { 0x0009, 0x0002 }, - { 0x0009, 0x0003 }, - { 0x000a, 0x0002 }, - { 0x000a, 0x0003 }, - { 0x000b, 0x0003 }, - { 0x000c, 0x0003 }, - { 0x000c, 0x0004 }, - { 0x000c, 0x0005 }, - { 0x000d, 0x0003 }, - { 0x000d, 0x0004 }, - { 0x000d, 0x0005 }, - { 0x000e, 0x0003 }, - { 0x000e, 0x0004 }, - { 0x000e, 0x0005 }, - { 0x000f, 0x0004 }, - { 0x000f, 0x0005 }, - { 0x0010, 0x0002 }, - { 0x0010, 0x0003 }, - { 0x0010, 0x0004 }, - { 0x0010, 0x0005 }, - { 0x0010, 0x0006 }, - { 0x0010, 0x0007 }, - { 0x0013, 0x0000 }, - { 0x0011, 0x0003 }, - { 0x0012, 0x0005 }, - { 0x0013, 0x0001 }, - { 0x0013, 0x0002 }, - { 0x0013, 0x0003 }, - { 0x0013, 0x0004 }, - { 0x0013, 0x0005 }, - { 0x0013, 0x0006 }, - { 0x0013, 0x0007 }, - { 0x0013, 0x0008 }, - { 0x0013, 0x0009 }, - - }; - -const uint16_t c_aauiLCLDHuffEnc57[65][2] = - { - { 0x0003, 0x0004 }, - { 0x0002, 0x0003 }, - { 0x0003, 0x0005 }, - { 0x0004, 0x0004 }, - { 0x0004, 0x0005 }, - { 0x0004, 0x0006 }, - { 0x0004, 0x0007 }, - { 0x0005, 0x0004 }, - { 0x0005, 0x0005 }, - { 0x0005, 0x0006 }, - { 0x0005, 0x0007 }, - { 0x0006, 0x0004 }, - { 0x0006, 0x0005 }, - { 0x0006, 0x0006 }, - { 0x0006, 0x0007 }, - { 0x0007, 0x0003 }, - { 0x0007, 0x0004 }, - { 0x0007, 0x0005 }, - { 0x0007, 0x0006 }, - { 0x0007, 0x0007 }, - { 0x0008, 0x0003 }, - { 0x0008, 0x0004 }, - { 0x0008, 0x0005 }, - { 0x0009, 0x0003 }, - { 0x0009, 0x0004 }, - { 0x0009, 0x0005 }, - { 0x000a, 0x0003 }, - { 0x000a, 0x0004 }, - { 0x000a, 0x0005 }, - { 0x000b, 0x0003 }, - { 0x000b, 0x0004 }, - { 0x000b, 0x0005 }, - { 0x000c, 0x0003 }, - { 0x000c, 0x0004 }, - { 0x000d, 0x0003 }, - { 0x000c, 0x0005 }, - { 0x000d, 0x0004 }, - { 0x000d, 0x0005 }, - { 0x000e, 0x0003 }, - { 0x000e, 0x0004 }, - { 0x000e, 0x0005 }, - { 0x000f, 0x0003 }, - { 0x0010, 0x0003 }, - { 0x000f, 0x0004 }, - { 0x000f, 0x0005 }, - { 0x0010, 0x0004 }, - { 0x0010, 0x0005 }, - { 0x0013, 0x0000 }, - { 0x0011, 0x0005 }, - { 0x0013, 0x0001 }, - { 0x0013, 0x0002 }, - { 0x0012, 0x0007 }, - { 0x0013, 0x0003 }, - { 0x0013, 0x0004 }, - { 0x0012, 0x0008 }, - { 0x0012, 0x0009 }, - { 0x0013, 0x0005 }, - { 0x0013, 0x0006 }, - { 0x0013, 0x0007 }, - { 0x0013, 0x0008 }, - { 0x0013, 0x0009 }, - { 0x0013, 0x000a }, - { 0x0013, 0x000b }, - { 0x0013, 0x000c }, - { 0x0013, 0x000d }, - - }; - -const uint16_t c_aauiLCLDHuffEnc58[77][2] = - { - { 0x0004, 0x0005 }, - { 0x0003, 0x0005 }, - { 0x0003, 0x0006 }, - { 0x0003, 0x0007 }, - { 0x0004, 0x0006 }, - { 0x0004, 0x0007 }, - { 0x0004, 0x0008 }, - { 0x0004, 0x0009 }, - { 0x0005, 0x0005 }, - { 0x0005, 0x0006 }, - { 0x0005, 0x0007 }, - { 0x0005, 0x0008 }, - { 0x0005, 0x0009 }, - { 0x0006, 0x0004 }, - { 0x0006, 0x0005 }, - { 0x0006, 0x0006 }, - { 0x0006, 0x0007 }, - { 0x0006, 0x0008 }, - { 0x0006, 0x0009 }, - { 0x0007, 0x0004 }, - { 0x0007, 0x0005 }, - { 0x0007, 0x0006 }, - { 0x0007, 0x0007 }, - { 0x0008, 0x0003 }, - { 0x0008, 0x0004 }, - { 0x0008, 0x0005 }, - { 0x0008, 0x0006 }, - { 0x0008, 0x0007 }, - { 0x0009, 0x0003 }, - { 0x0009, 0x0004 }, - { 0x0009, 0x0005 }, - { 0x000a, 0x0003 }, - { 0x000a, 0x0004 }, - { 0x000a, 0x0005 }, - { 0x000b, 0x0004 }, - { 0x000b, 0x0005 }, - { 0x000c, 0x0004 }, - { 0x000c, 0x0005 }, - { 0x000c, 0x0006 }, - { 0x000c, 0x0007 }, - { 0x000d, 0x0004 }, - { 0x000d, 0x0005 }, - { 0x000d, 0x0006 }, - { 0x000d, 0x0007 }, - { 0x000e, 0x0004 }, - { 0x000e, 0x0005 }, - { 0x000e, 0x0006 }, - { 0x000e, 0x0007 }, - { 0x000f, 0x0004 }, - { 0x000f, 0x0005 }, - { 0x000f, 0x0006 }, - { 0x0010, 0x0004 }, - { 0x000f, 0x0007 }, - { 0x0010, 0x0005 }, - { 0x0010, 0x0006 }, - { 0x0010, 0x0007 }, - { 0x0013, 0x0000 }, - { 0x0013, 0x0001 }, - { 0x0012, 0x0006 }, - { 0x0011, 0x0007 }, - { 0x0013, 0x0002 }, - { 0x0013, 0x0003 }, - { 0x0013, 0x0004 }, - { 0x0013, 0x0005 }, - { 0x0012, 0x0007 }, - { 0x0013, 0x0006 }, - { 0x0013, 0x0007 }, - { 0x0013, 0x0008 }, - { 0x0013, 0x0009 }, - { 0x0013, 0x000a }, - { 0x0013, 0x000b }, - { 0x0012, 0x0008 }, - { 0x0012, 0x0009 }, - { 0x0012, 0x000a }, - { 0x0012, 0x000b }, - { 0x0012, 0x000c }, - { 0x0012, 0x000d }, - - }; - -const uint16_t c_aauiLCLDHuffEnc59[91][2] = - { - { 0x0003, 0x0005 }, - { 0x0003, 0x0006 }, - { 0x0003, 0x0007 }, - { 0x0004, 0x0006 }, - { 0x0004, 0x0007 }, - { 0x0004, 0x0008 }, - { 0x0004, 0x0009 }, - { 0x0005, 0x0006 }, - { 0x0005, 0x0007 }, - { 0x0005, 0x0008 }, - { 0x0005, 0x0009 }, - { 0x0005, 0x000a }, - { 0x0005, 0x000b }, - { 0x0006, 0x0006 }, - { 0x0006, 0x0007 }, - { 0x0006, 0x0008 }, - { 0x0006, 0x0009 }, - { 0x0006, 0x000a }, - { 0x0006, 0x000b }, - { 0x0007, 0x0005 }, - { 0x0007, 0x0006 }, - { 0x0007, 0x0007 }, - { 0x0007, 0x0008 }, - { 0x0007, 0x0009 }, - { 0x0007, 0x000a }, - { 0x0007, 0x000b }, - { 0x0008, 0x0003 }, - { 0x0008, 0x0004 }, - { 0x0008, 0x0005 }, - { 0x0008, 0x0006 }, - { 0x0008, 0x0007 }, - { 0x0008, 0x0008 }, - { 0x0008, 0x0009 }, - { 0x0009, 0x0004 }, - { 0x0009, 0x0005 }, - { 0x000a, 0x0004 }, - { 0x000a, 0x0005 }, - { 0x000a, 0x0006 }, - { 0x000a, 0x0007 }, - { 0x000b, 0x0004 }, - { 0x000b, 0x0005 }, - { 0x000b, 0x0006 }, - { 0x000b, 0x0007 }, - { 0x000c, 0x0004 }, - { 0x000c, 0x0005 }, - { 0x000c, 0x0006 }, - { 0x000c, 0x0007 }, - { 0x000d, 0x0003 }, - { 0x000d, 0x0004 }, - { 0x000d, 0x0005 }, - { 0x000d, 0x0006 }, - { 0x000d, 0x0007 }, - { 0x000e, 0x0003 }, - { 0x000e, 0x0004 }, - { 0x000e, 0x0005 }, - { 0x000f, 0x0003 }, - { 0x000f, 0x0004 }, - { 0x000f, 0x0005 }, - { 0x0011, 0x0008 }, - { 0x0011, 0x0009 }, - { 0x0013, 0x0000 }, - { 0x0011, 0x000a }, - { 0x0013, 0x0001 }, - { 0x0013, 0x0002 }, - { 0x0012, 0x000d }, - { 0x0012, 0x000e }, - { 0x0013, 0x0003 }, - { 0x0013, 0x0004 }, - { 0x0013, 0x0005 }, - { 0x0011, 0x000b }, - { 0x0013, 0x0006 }, - { 0x0013, 0x0007 }, - { 0x0013, 0x0008 }, - { 0x0013, 0x0009 }, - { 0x0013, 0x000a }, - { 0x0013, 0x000b }, - { 0x0013, 0x000c }, - { 0x0013, 0x000d }, - { 0x0013, 0x000e }, - { 0x0013, 0x000f }, - { 0x0013, 0x0010 }, - { 0x0013, 0x0011 }, - { 0x0013, 0x0012 }, - { 0x0013, 0x0013 }, - { 0x0013, 0x0014 }, - { 0x0013, 0x0015 }, - { 0x0013, 0x0016 }, - { 0x0013, 0x0017 }, - { 0x0013, 0x0018 }, - { 0x0013, 0x0019 }, - { 0x0012, 0x000f }, - - }; - -const uint16_t c_aauiLCLDHuffEnc60[109][2] = - { - { 0x0004, 0x0007 }, - { 0x0002, 0x0003 }, - { 0x0003, 0x0005 }, - { 0x0004, 0x0008 }, - { 0x0004, 0x0009 }, - { 0x0005, 0x0007 }, - { 0x0005, 0x0008 }, - { 0x0005, 0x0009 }, - { 0x0005, 0x000a }, - { 0x0005, 0x000b }, - { 0x0005, 0x000c }, - { 0x0005, 0x000d }, - { 0x0006, 0x0007 }, - { 0x0006, 0x0008 }, - { 0x0006, 0x0009 }, - { 0x0006, 0x000a }, - { 0x0006, 0x000b }, - { 0x0006, 0x000c }, - { 0x0006, 0x000d }, - { 0x0007, 0x0006 }, - { 0x0007, 0x0007 }, - { 0x0007, 0x0008 }, - { 0x0007, 0x0009 }, - { 0x0007, 0x000a }, - { 0x0007, 0x000b }, - { 0x0007, 0x000c }, - { 0x0007, 0x000d }, - { 0x0008, 0x0006 }, - { 0x0008, 0x0007 }, - { 0x0008, 0x0008 }, - { 0x0008, 0x0009 }, - { 0x0008, 0x000a }, - { 0x0008, 0x000b }, - { 0x0009, 0x0004 }, - { 0x0009, 0x0005 }, - { 0x0009, 0x0006 }, - { 0x0009, 0x0007 }, - { 0x0009, 0x0008 }, - { 0x0009, 0x0009 }, - { 0x0009, 0x000a }, - { 0x0009, 0x000b }, - { 0x000a, 0x0004 }, - { 0x000a, 0x0005 }, - { 0x000a, 0x0006 }, - { 0x000a, 0x0007 }, - { 0x000b, 0x0004 }, - { 0x000b, 0x0005 }, - { 0x000b, 0x0006 }, - { 0x000b, 0x0007 }, - { 0x000c, 0x0004 }, - { 0x000c, 0x0005 }, - { 0x000c, 0x0006 }, - { 0x000d, 0x0005 }, - { 0x000d, 0x0006 }, - { 0x000d, 0x0007 }, - { 0x000c, 0x0007 }, - { 0x000e, 0x0005 }, - { 0x000e, 0x0006 }, - { 0x000e, 0x0007 }, - { 0x000e, 0x0008 }, - { 0x000f, 0x0005 }, - { 0x000e, 0x0009 }, - { 0x000f, 0x0006 }, - { 0x0010, 0x0006 }, - { 0x000f, 0x0007 }, - { 0x000f, 0x0008 }, - { 0x000f, 0x0009 }, - { 0x0010, 0x0007 }, - { 0x0010, 0x0008 }, - { 0x0010, 0x0009 }, - { 0x0011, 0x000a }, - { 0x0013, 0x0000 }, - { 0x0011, 0x000b }, - { 0x0013, 0x0001 }, - { 0x0013, 0x0002 }, - { 0x0012, 0x0011 }, - { 0x0012, 0x0012 }, - { 0x0013, 0x0003 }, - { 0x0013, 0x0004 }, - { 0x0013, 0x0005 }, - { 0x0013, 0x0006 }, - { 0x0013, 0x0007 }, - { 0x0013, 0x0008 }, - { 0x0013, 0x0009 }, - { 0x0013, 0x000a }, - { 0x0013, 0x000b }, - { 0x0013, 0x000c }, - { 0x0013, 0x000d }, - { 0x0013, 0x000e }, - { 0x0013, 0x000f }, - { 0x0013, 0x0010 }, - { 0x0013, 0x0011 }, - { 0x0013, 0x0012 }, - { 0x0013, 0x0013 }, - { 0x0013, 0x0014 }, - { 0x0013, 0x0015 }, - { 0x0013, 0x0016 }, - { 0x0013, 0x0017 }, - { 0x0013, 0x0018 }, - { 0x0013, 0x0019 }, - { 0x0013, 0x001a }, - { 0x0013, 0x001b }, - { 0x0013, 0x001c }, - { 0x0013, 0x001d }, - { 0x0013, 0x001e }, - { 0x0013, 0x001f }, - { 0x0013, 0x0020 }, - { 0x0013, 0x0021 }, - { 0x0012, 0x0013 }, - - }; - -const uint16_t c_aauiLCLDHuffEnc61[129][2] = - { - { 0x0004, 0x0008 }, - { 0x0003, 0x0006 }, - { 0x0003, 0x0007 }, - { 0x0004, 0x0009 }, - { 0x0004, 0x000a }, - { 0x0004, 0x000b }, - { 0x0005, 0x0008 }, - { 0x0005, 0x0009 }, - { 0x0005, 0x000a }, - { 0x0005, 0x000b }, - { 0x0005, 0x000c }, - { 0x0005, 0x000d }, - { 0x0005, 0x000e }, - { 0x0005, 0x000f }, - { 0x0006, 0x0008 }, - { 0x0006, 0x0009 }, - { 0x0006, 0x000a }, - { 0x0006, 0x000b }, - { 0x0006, 0x000c }, - { 0x0006, 0x000d }, - { 0x0006, 0x000e }, - { 0x0006, 0x000f }, - { 0x0007, 0x0008 }, - { 0x0007, 0x0009 }, - { 0x0007, 0x000a }, - { 0x0007, 0x000b }, - { 0x0007, 0x000c }, - { 0x0007, 0x000d }, - { 0x0007, 0x000e }, - { 0x0007, 0x000f }, - { 0x0008, 0x0006 }, - { 0x0008, 0x0007 }, - { 0x0008, 0x0008 }, - { 0x0008, 0x0009 }, - { 0x0008, 0x000a }, - { 0x0008, 0x000b }, - { 0x0008, 0x000c }, - { 0x0008, 0x000d }, - { 0x0008, 0x000e }, - { 0x0008, 0x000f }, - { 0x0009, 0x0006 }, - { 0x0009, 0x0007 }, - { 0x0009, 0x0008 }, - { 0x0009, 0x0009 }, - { 0x0009, 0x000a }, - { 0x0009, 0x000b }, - { 0x000a, 0x0005 }, - { 0x000a, 0x0006 }, - { 0x000a, 0x0007 }, - { 0x000a, 0x0008 }, - { 0x000a, 0x0009 }, - { 0x000a, 0x000a }, - { 0x000a, 0x000b }, - { 0x000b, 0x0005 }, - { 0x000b, 0x0006 }, - { 0x000b, 0x0007 }, - { 0x000b, 0x0008 }, - { 0x000b, 0x0009 }, - { 0x000c, 0x0006 }, - { 0x000c, 0x0007 }, - { 0x000c, 0x0008 }, - { 0x000c, 0x0009 }, - { 0x000d, 0x0005 }, - { 0x000d, 0x0006 }, - { 0x000d, 0x0007 }, - { 0x000d, 0x0008 }, - { 0x000d, 0x0009 }, - { 0x000d, 0x000a }, - { 0x000e, 0x0008 }, - { 0x000d, 0x000b }, - { 0x000e, 0x0009 }, - { 0x000f, 0x0009 }, - { 0x000f, 0x000a }, - { 0x000f, 0x000b }, - { 0x000f, 0x000c }, - { 0x000f, 0x000d }, - { 0x000f, 0x000e }, - { 0x0010, 0x000c }, - { 0x0011, 0x0015 }, - { 0x0010, 0x000d }, - { 0x000f, 0x000f }, - { 0x0010, 0x000e }, - { 0x0010, 0x000f }, - { 0x0012, 0x0000 }, - { 0x0011, 0x0016 }, - { 0x0010, 0x0010 }, - { 0x0010, 0x0011 }, - { 0x0011, 0x0017 }, - { 0x0012, 0x0001 }, - { 0x0012, 0x0002 }, - { 0x0012, 0x0003 }, - { 0x0012, 0x0004 }, - { 0x0012, 0x0005 }, - { 0x0012, 0x0006 }, - { 0x0012, 0x0007 }, - { 0x0012, 0x0008 }, - { 0x0012, 0x0009 }, - { 0x0012, 0x000a }, - { 0x0012, 0x000b }, - { 0x0012, 0x000c }, - { 0x0012, 0x000d }, - { 0x0012, 0x000e }, - { 0x0012, 0x000f }, - { 0x0012, 0x0010 }, - { 0x0012, 0x0011 }, - { 0x0012, 0x0012 }, - { 0x0012, 0x0013 }, - { 0x0012, 0x0014 }, - { 0x0012, 0x0015 }, - { 0x0012, 0x0016 }, - { 0x0012, 0x0017 }, - { 0x0012, 0x0018 }, - { 0x0012, 0x0019 }, - { 0x0012, 0x001a }, - { 0x0012, 0x001b }, - { 0x0012, 0x001c }, - { 0x0012, 0x001d }, - { 0x0012, 0x001e }, - { 0x0012, 0x001f }, - { 0x0012, 0x0020 }, - { 0x0012, 0x0021 }, - { 0x0012, 0x0022 }, - { 0x0012, 0x0023 }, - { 0x0012, 0x0024 }, - { 0x0012, 0x0025 }, - { 0x0012, 0x0026 }, - { 0x0012, 0x0027 }, - { 0x0012, 0x0028 }, - { 0x0012, 0x0029 }, - - }; - -const uint16_t c_aauiLCLDHuffEnc62[153][2] = - { - { 0x0004, 0x0009 }, - { 0x0003, 0x0006 }, - { 0x0003, 0x0007 }, - { 0x0004, 0x000a }, - { 0x0004, 0x000b }, - { 0x0005, 0x000a }, - { 0x0005, 0x000b }, - { 0x0005, 0x000c }, - { 0x0005, 0x000d }, - { 0x0005, 0x000e }, - { 0x0005, 0x000f }, - { 0x0005, 0x0010 }, - { 0x0005, 0x0011 }, - { 0x0006, 0x000a }, - { 0x0006, 0x000b }, - { 0x0006, 0x000c }, - { 0x0006, 0x000d }, - { 0x0006, 0x000e }, - { 0x0006, 0x000f }, - { 0x0006, 0x0010 }, - { 0x0006, 0x0011 }, - { 0x0006, 0x0012 }, - { 0x0006, 0x0013 }, - { 0x0007, 0x0009 }, - { 0x0007, 0x000a }, - { 0x0007, 0x000b }, - { 0x0007, 0x000c }, - { 0x0007, 0x000d }, - { 0x0007, 0x000e }, - { 0x0007, 0x000f }, - { 0x0007, 0x0010 }, - { 0x0007, 0x0011 }, - { 0x0007, 0x0012 }, - { 0x0007, 0x0013 }, - { 0x0008, 0x0009 }, - { 0x0008, 0x000a }, - { 0x0008, 0x000b }, - { 0x0008, 0x000c }, - { 0x0008, 0x000d }, - { 0x0008, 0x000e }, - { 0x0008, 0x000f }, - { 0x0008, 0x0010 }, - { 0x0008, 0x0011 }, - { 0x0009, 0x0007 }, - { 0x0009, 0x0008 }, - { 0x0009, 0x0009 }, - { 0x0009, 0x000a }, - { 0x0009, 0x000b }, - { 0x0009, 0x000c }, - { 0x0009, 0x000d }, - { 0x0009, 0x000e }, - { 0x0009, 0x000f }, - { 0x0009, 0x0010 }, - { 0x0009, 0x0011 }, - { 0x000a, 0x0004 }, - { 0x000a, 0x0005 }, - { 0x000a, 0x0006 }, - { 0x000a, 0x0007 }, - { 0x000a, 0x0008 }, - { 0x000a, 0x0009 }, - { 0x000a, 0x000a }, - { 0x000a, 0x000b }, - { 0x000a, 0x000c }, - { 0x000a, 0x000d }, - { 0x000b, 0x0007 }, - { 0x000c, 0x0007 }, - { 0x000c, 0x0008 }, - { 0x000c, 0x0009 }, - { 0x000c, 0x000a }, - { 0x000c, 0x000b }, - { 0x000c, 0x000c }, - { 0x000d, 0x0007 }, - { 0x000c, 0x000d }, - { 0x000d, 0x0008 }, - { 0x000d, 0x0009 }, - { 0x000d, 0x000a }, - { 0x000d, 0x000b }, - { 0x000e, 0x0008 }, - { 0x000d, 0x000c }, - { 0x000d, 0x000d }, - { 0x000e, 0x0009 }, - { 0x000e, 0x000a }, - { 0x000e, 0x000b }, - { 0x000e, 0x000c }, - { 0x000f, 0x000c }, - { 0x000e, 0x000d }, - { 0x000f, 0x000d }, - { 0x000f, 0x000e }, - { 0x000f, 0x000f }, - { 0x0010, 0x000f }, - { 0x0010, 0x0010 }, - { 0x0011, 0x0019 }, - { 0x0010, 0x0011 }, - { 0x0010, 0x0012 }, - { 0x0010, 0x0013 }, - { 0x0010, 0x0014 }, - { 0x0010, 0x0015 }, - { 0x0012, 0x0000 }, - { 0x0010, 0x0016 }, - { 0x0011, 0x001a }, - { 0x0010, 0x0017 }, - { 0x0012, 0x0001 }, - { 0x0012, 0x0002 }, - { 0x0012, 0x0003 }, - { 0x0011, 0x001b }, - { 0x0012, 0x0004 }, - { 0x0012, 0x0005 }, - { 0x0012, 0x0006 }, - { 0x0012, 0x0007 }, - { 0x0012, 0x0008 }, - { 0x0012, 0x0009 }, - { 0x0012, 0x000a }, - { 0x0012, 0x000b }, - { 0x0012, 0x000c }, - { 0x0012, 0x000d }, - { 0x0012, 0x000e }, - { 0x0012, 0x000f }, - { 0x0012, 0x0010 }, - { 0x0012, 0x0011 }, - { 0x0012, 0x0012 }, - { 0x0012, 0x0013 }, - { 0x0012, 0x0014 }, - { 0x0012, 0x0015 }, - { 0x0012, 0x0016 }, - { 0x0012, 0x0017 }, - { 0x0012, 0x0018 }, - { 0x0011, 0x001c }, - { 0x0012, 0x0019 }, - { 0x0012, 0x001a }, - { 0x0012, 0x001b }, - { 0x0012, 0x001c }, - { 0x0012, 0x001d }, - { 0x0012, 0x001e }, - { 0x0012, 0x001f }, - { 0x0012, 0x0020 }, - { 0x0012, 0x0021 }, - { 0x0012, 0x0022 }, - { 0x0012, 0x0023 }, - { 0x0012, 0x0024 }, - { 0x0012, 0x0025 }, - { 0x0012, 0x0026 }, - { 0x0012, 0x0027 }, - { 0x0012, 0x0028 }, - { 0x0012, 0x0029 }, - { 0x0012, 0x002a }, - { 0x0012, 0x002b }, - { 0x0012, 0x002c }, - { 0x0012, 0x002d }, - { 0x0012, 0x002e }, - { 0x0012, 0x002f }, - { 0x0012, 0x0030 }, - { 0x0012, 0x0031 }, - { 0x0011, 0x001d }, - - }; - -const uint16_t c_aauiLCLDHuffEnc63[181][2] = - { - { 0x0004, 0x0008 }, - { 0x0003, 0x0005 }, - { 0x0002, 0x0003 }, - { 0x0004, 0x0009 }, - { 0x0005, 0x000c }, - { 0x0005, 0x000d }, - { 0x0005, 0x000e }, - { 0x0005, 0x000f }, - { 0x0006, 0x000c }, - { 0x0006, 0x000d }, - { 0x0006, 0x000e }, - { 0x0006, 0x000f }, - { 0x0006, 0x0010 }, - { 0x0006, 0x0011 }, - { 0x0006, 0x0012 }, - { 0x0006, 0x0013 }, - { 0x0006, 0x0014 }, - { 0x0006, 0x0015 }, - { 0x0006, 0x0016 }, - { 0x0006, 0x0017 }, - { 0x0007, 0x000b }, - { 0x0007, 0x000c }, - { 0x0007, 0x000d }, - { 0x0007, 0x000e }, - { 0x0007, 0x000f }, - { 0x0007, 0x0010 }, - { 0x0007, 0x0011 }, - { 0x0007, 0x0012 }, - { 0x0007, 0x0013 }, - { 0x0007, 0x0014 }, - { 0x0007, 0x0015 }, - { 0x0007, 0x0016 }, - { 0x0007, 0x0017 }, - { 0x0008, 0x000c }, - { 0x0008, 0x000d }, - { 0x0008, 0x000e }, - { 0x0008, 0x000f }, - { 0x0008, 0x0010 }, - { 0x0008, 0x0011 }, - { 0x0008, 0x0012 }, - { 0x0008, 0x0013 }, - { 0x0008, 0x0014 }, - { 0x0008, 0x0015 }, - { 0x0009, 0x0008 }, - { 0x0009, 0x0009 }, - { 0x0009, 0x000a }, - { 0x0009, 0x000b }, - { 0x0009, 0x000c }, - { 0x0009, 0x000d }, - { 0x0009, 0x000e }, - { 0x0009, 0x000f }, - { 0x0009, 0x0010 }, - { 0x0009, 0x0011 }, - { 0x0009, 0x0012 }, - { 0x0009, 0x0013 }, - { 0x0009, 0x0014 }, - { 0x0009, 0x0015 }, - { 0x000a, 0x0007 }, - { 0x0009, 0x0016 }, - { 0x0009, 0x0017 }, - { 0x000a, 0x0008 }, - { 0x000a, 0x0009 }, - { 0x000a, 0x000a }, - { 0x000a, 0x000b }, - { 0x000a, 0x000c }, - { 0x000a, 0x000d }, - { 0x000a, 0x000e }, - { 0x000b, 0x0008 }, - { 0x000b, 0x0009 }, - { 0x000b, 0x000a }, - { 0x000a, 0x000f }, - { 0x000b, 0x000b }, - { 0x000b, 0x000c }, - { 0x000b, 0x000d }, - { 0x000c, 0x0009 }, - { 0x000c, 0x000a }, - { 0x000c, 0x000b }, - { 0x000c, 0x000c }, - { 0x000c, 0x000d }, - { 0x000c, 0x000e }, - { 0x000c, 0x000f }, - { 0x000d, 0x0008 }, - { 0x000d, 0x0009 }, - { 0x000d, 0x000a }, - { 0x000d, 0x000b }, - { 0x000d, 0x000c }, - { 0x000d, 0x000d }, - { 0x000d, 0x000e }, - { 0x000d, 0x000f }, - { 0x000d, 0x0010 }, - { 0x000d, 0x0011 }, - { 0x000e, 0x0007 }, - { 0x000e, 0x0008 }, - { 0x000e, 0x0009 }, - { 0x000e, 0x000a }, - { 0x000e, 0x000b }, - { 0x000e, 0x000c }, - { 0x000e, 0x000d }, - { 0x000e, 0x000e }, - { 0x000e, 0x000f }, - { 0x000f, 0x0008 }, - { 0x000f, 0x0009 }, - { 0x000f, 0x000a }, - { 0x000f, 0x000b }, - { 0x000f, 0x000c }, - { 0x0010, 0x0009 }, - { 0x0010, 0x000a }, - { 0x000f, 0x000d }, - { 0x0010, 0x000b }, - { 0x0010, 0x000c }, - { 0x0010, 0x000d }, - { 0x0011, 0x000e }, - { 0x0011, 0x000f }, - { 0x0010, 0x000e }, - { 0x0011, 0x0010 }, - { 0x0011, 0x0011 }, - { 0x0012, 0x0014 }, - { 0x0014, 0x0000 }, - { 0x0010, 0x000f }, - { 0x0012, 0x0015 }, - { 0x0012, 0x0016 }, - { 0x0014, 0x0001 }, - { 0x0012, 0x0017 }, - { 0x0012, 0x0018 }, - { 0x0012, 0x0019 }, - { 0x0013, 0x0010 }, - { 0x0012, 0x001a }, - { 0x0014, 0x0002 }, - { 0x0012, 0x001b }, - { 0x0014, 0x0003 }, - { 0x0014, 0x0004 }, - { 0x0014, 0x0005 }, - { 0x0013, 0x0011 }, - { 0x0014, 0x0006 }, - { 0x0013, 0x0012 }, - { 0x0014, 0x0007 }, - { 0x0014, 0x0008 }, - { 0x0014, 0x0009 }, - { 0x0014, 0x000a }, - { 0x0014, 0x000b }, - { 0x0014, 0x000c }, - { 0x0014, 0x000d }, - { 0x0014, 0x000e }, - { 0x0013, 0x0013 }, - { 0x0014, 0x000f }, - { 0x0014, 0x0010 }, - { 0x0014, 0x0011 }, - { 0x0014, 0x0012 }, - { 0x0014, 0x0013 }, - { 0x0014, 0x0014 }, - { 0x0014, 0x0015 }, - { 0x0014, 0x0016 }, - { 0x0014, 0x0017 }, - { 0x0014, 0x0018 }, - { 0x0014, 0x0019 }, - { 0x0014, 0x001a }, - { 0x0014, 0x001b }, - { 0x0014, 0x001c }, - { 0x0014, 0x001d }, - { 0x0014, 0x001e }, - { 0x0014, 0x001f }, - { 0x0013, 0x0014 }, - { 0x0013, 0x0015 }, - { 0x0013, 0x0016 }, - { 0x0013, 0x0017 }, - { 0x0013, 0x0018 }, - { 0x0013, 0x0019 }, - { 0x0013, 0x001a }, - { 0x0013, 0x001b }, - { 0x0013, 0x001c }, - { 0x0013, 0x001d }, - { 0x0013, 0x001e }, - { 0x0013, 0x001f }, - { 0x0013, 0x0020 }, - { 0x0013, 0x0021 }, - { 0x0013, 0x0022 }, - { 0x0013, 0x0023 }, - { 0x0013, 0x0024 }, - { 0x0013, 0x0025 }, - { 0x0013, 0x0026 }, - { 0x0013, 0x0027 }, - - }; - -const uint16_t ( *c_apauiHuffEncTabels[2 * ALLOC_TABLE_SIZE] )[2] = - { - NULL, - c_aauiLCLDHuffEnc1, - c_aauiLCLDHuffEnc2, - c_aauiLCLDHuffEnc3, - c_aauiLCLDHuffEnc4, - c_aauiLCLDHuffEnc5, - c_aauiLCLDHuffEnc6, - c_aauiLCLDHuffEnc7, - c_aauiLCLDHuffEnc8, - c_aauiLCLDHuffEnc9, - c_aauiLCLDHuffEnc10, - c_aauiLCLDHuffEnc11, - c_aauiLCLDHuffEnc12, - c_aauiLCLDHuffEnc13, - c_aauiLCLDHuffEnc14, - c_aauiLCLDHuffEnc15, - c_aauiLCLDHuffEnc16, - c_aauiLCLDHuffEnc17, - c_aauiLCLDHuffEnc18, - c_aauiLCLDHuffEnc19, - c_aauiLCLDHuffEnc20, - c_aauiLCLDHuffEnc21, - c_aauiLCLDHuffEnc22, - c_aauiLCLDHuffEnc23, - c_aauiLCLDHuffEnc24, - c_aauiLCLDHuffEnc25, - c_aauiLCLDHuffEnc26, - c_aauiLCLDHuffEnc27, - c_aauiLCLDHuffEnc28, - c_aauiLCLDHuffEnc29, - c_aauiLCLDHuffEnc30, - c_aauiLCLDHuffEnc31, - NULL, - c_aauiLCLDHuffEnc33, - c_aauiLCLDHuffEnc34, - c_aauiLCLDHuffEnc35, - c_aauiLCLDHuffEnc36, - c_aauiLCLDHuffEnc37, - c_aauiLCLDHuffEnc38, - c_aauiLCLDHuffEnc39, - c_aauiLCLDHuffEnc40, - c_aauiLCLDHuffEnc41, - c_aauiLCLDHuffEnc42, - c_aauiLCLDHuffEnc43, - c_aauiLCLDHuffEnc44, - c_aauiLCLDHuffEnc45, - c_aauiLCLDHuffEnc46, - c_aauiLCLDHuffEnc47, - c_aauiLCLDHuffEnc48, - c_aauiLCLDHuffEnc49, - c_aauiLCLDHuffEnc50, - c_aauiLCLDHuffEnc51, - c_aauiLCLDHuffEnc52, - c_aauiLCLDHuffEnc53, - c_aauiLCLDHuffEnc54, - c_aauiLCLDHuffEnc55, - c_aauiLCLDHuffEnc56, - c_aauiLCLDHuffEnc57, - c_aauiLCLDHuffEnc58, - c_aauiLCLDHuffEnc59, - c_aauiLCLDHuffEnc60, - c_aauiLCLDHuffEnc61, - c_aauiLCLDHuffEnc62, - c_aauiLCLDHuffEnc63, - }; - -const uint32_t num_row_aauiLCLDHuff[2 * ALLOC_TABLE_SIZE] = { 0, 16, 16, 25, 36, 36, 49, 64, 81, 100, - 169, 196, 289, 324, 400, 576, 729, 729, 28, 29, - 32, 37, 39, 46, 55, 65, 77, 91, 109, 129, - 153, 181, 0, 16, 16, 25, 36, 36, 49, 64, 81, - 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_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 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, - 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_aiBandwidthAdjust48[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_aiAbsoluteThresh48[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, -}; - - -#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 - -const int32_t c_aaiSpreadFunction48[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, -}; -#endif diff --git a/lib_rend/ivas_lcld_rom_tables.h b/lib_rend/ivas_lcld_rom_tables.h deleted file mode 100644 index 132f52add..000000000 --- a/lib_rend/ivas_lcld_rom_tables.h +++ /dev/null @@ -1,225 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2023 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 _IVAS_TABLES_H_ -#define _IVAS_TABLES_H_ - -#include -#include "options.h" - -#ifndef M_PI - -#define M_PI 3.14159265358979323846264338327950288f // todo: replace by EVS_PI - -#endif - -#define LCLD_BLOCKS_PER_FRAME ( 16 ) -#define LCLD_MAX_BLOCKS_PER_FRAME ( 16 ) -#define LCLD_BANDS ( 60 ) - -#define MAX_BANDS ( 23 ) -#define MAX_BANDS_48 ( 23 ) - -#define ENV_MIN ( -64 ) -#define ENV_MAX ( 64 ) - -#define ENV0_BITS ( 7 ) - -#define ENV_DELTA_MIN ( -32 ) -#define ENV_DELTA_MAX ( 31 ) - -#define ENV_RECONSTRUCT_TABLE_SIZE ( 129 ) - -#define ENV_RECONSTRUCT_TABLE_CENTER ( 64 ) - -#define MIN_ALLOC ( 0 ) -#define MAX_ALLOC ( 31 ) - -#define ALLOC_OFFSET_SCALE ( 8 ) - -#define ALLOC_OFFSET_BITS ( 8 ) - -#define MIN_ALLOC_OFFSET ( -128 ) -#define MAX_ALLOC_OFFSET ( 127 ) -#define READ_LENGTH ( 4 ) - -#define ALLOC_TABLE_SIZE ( 32 ) - -#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 SIMPLE_PHASE_MAX_VAL ( 3 ) -#define SIMPLE_PHASE_MIN_VAL ( 0 ) -#define SIMPLE_PHASE_BITS ( 2 ) -#define SIMPLE_PHASE_QUANT_FACTOR ( 2.0f / _PI_ ) - -#define TON_QUOTA_ABS_THRESHOLD ( 8.0f ) -#define TON_QUOTA_INC_THRESHOLD ( 4.0f ) - -#define PERCEPTUAL_MODEL_SLGAIN_SHIFT ( 8 ) - -//#define USE_DEMOD_TABLES - -#define HUFF_DEC_TABLE_SIZE ( 16 ) - -extern const float c_afRotRealImag[PRED_MAX_VAL - PRED_MIN_VAL + 1][2]; -extern const float c_afRotRealImagSimple[SIMPLE_PHASE_MAX_VAL + 1][2]; -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 float c_afRMSEnvReconstructTable[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 int32_t c_aiHuffmanSize[ALLOC_TABLE_SIZE]; - - -#define LOG_ADD_TABLE_LENGTH ( 512 ) - -extern const int32_t c_aiBandwidths48[MAX_BANDS_48]; -extern const int32_t c_aiLogAddTable[LOG_ADD_TABLE_LENGTH]; -extern const int32_t c_aiBandwidthAdjust48[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]; - - -#define PRED_QUNAT_FILTER_MAG_BITS ( 3 ) -#define PRED_QUANT_FILTER_PHASE_BITS ( 5 ) -#define PRED_QUANT_FILTER_MAG_MIN ( 0 ) -#define PRED_QUANT_FILTER_MAG_MAX ( 7 ) -#define PRED_QUANT_FILTER_PHASE_MIN ( -16 ) -#define PRED_QUANT_FILTER_PHASE_MAX ( 15 ) - -extern const uint16_t c_aauiLCLDHuffEnc1[16][2]; -extern const uint16_t c_aauiLCLDHuffEnc2[16][2]; -extern const uint16_t c_aauiLCLDHuffEnc3[25][2]; -extern const uint16_t c_aauiLCLDHuffEnc4[36][2]; -extern const uint16_t c_aauiLCLDHuffEnc5[36][2]; -extern const uint16_t c_aauiLCLDHuffEnc6[49][2]; -extern const uint16_t c_aauiLCLDHuffEnc7[64][2]; -extern const uint16_t c_aauiLCLDHuffEnc8[81][2]; -extern const uint16_t c_aauiLCLDHuffEnc9[100][2]; -extern const uint16_t c_aauiLCLDHuffEnc10[169][2]; -extern const uint16_t c_aauiLCLDHuffEnc11[196][2]; -extern const uint16_t c_aauiLCLDHuffEnc12[289][2]; -extern const uint16_t c_aauiLCLDHuffEnc13[324][2]; -extern const uint16_t c_aauiLCLDHuffEnc14[400][2]; -extern const uint16_t c_aauiLCLDHuffEnc15[576][2]; -extern const uint16_t c_aauiLCLDHuffEnc16[729][2]; -extern const uint16_t c_aauiLCLDHuffEnc17[729][2]; -extern const uint16_t c_aauiLCLDHuffEnc18[28][2]; -extern const uint16_t c_aauiLCLDHuffEnc19[29][2]; -extern const uint16_t c_aauiLCLDHuffEnc20[32][2]; -extern const uint16_t c_aauiLCLDHuffEnc21[37][2]; -extern const uint16_t c_aauiLCLDHuffEnc22[39][2]; -extern const uint16_t c_aauiLCLDHuffEnc23[46][2]; -extern const uint16_t c_aauiLCLDHuffEnc24[55][2]; -extern const uint16_t c_aauiLCLDHuffEnc25[65][2]; -extern const uint16_t c_aauiLCLDHuffEnc26[77][2]; -extern const uint16_t c_aauiLCLDHuffEnc27[91][2]; -extern const uint16_t c_aauiLCLDHuffEnc28[109][2]; -extern const uint16_t c_aauiLCLDHuffEnc29[129][2]; -extern const uint16_t c_aauiLCLDHuffEnc30[153][2]; -extern const uint16_t c_aauiLCLDHuffEnc31[181][2]; -extern const uint16_t c_aauiLCLDHuffEnc33[16][2]; -extern const uint16_t c_aauiLCLDHuffEnc34[16][2]; -extern const uint16_t c_aauiLCLDHuffEnc35[25][2]; -extern const uint16_t c_aauiLCLDHuffEnc36[36][2]; -extern const uint16_t c_aauiLCLDHuffEnc37[36][2]; -extern const uint16_t c_aauiLCLDHuffEnc38[49][2]; -extern const uint16_t c_aauiLCLDHuffEnc39[64][2]; -extern const uint16_t c_aauiLCLDHuffEnc40[81][2]; -extern const uint16_t c_aauiLCLDHuffEnc41[100][2]; -extern const uint16_t c_aauiLCLDHuffEnc42[169][2]; -extern const uint16_t c_aauiLCLDHuffEnc43[196][2]; -extern const uint16_t c_aauiLCLDHuffEnc44[289][2]; -extern const uint16_t c_aauiLCLDHuffEnc45[324][2]; -extern const uint16_t c_aauiLCLDHuffEnc46[400][2]; -extern const uint16_t c_aauiLCLDHuffEnc47[576][2]; -extern const uint16_t c_aauiLCLDHuffEnc48[729][2]; -extern const uint16_t c_aauiLCLDHuffEnc49[729][2]; -extern const uint16_t c_aauiLCLDHuffEnc50[28][2]; -extern const uint16_t c_aauiLCLDHuffEnc51[29][2]; -extern const uint16_t c_aauiLCLDHuffEnc52[32][2]; -extern const uint16_t c_aauiLCLDHuffEnc53[37][2]; -extern const uint16_t c_aauiLCLDHuffEnc54[39][2]; -extern const uint16_t c_aauiLCLDHuffEnc55[46][2]; -extern const uint16_t c_aauiLCLDHuffEnc56[55][2]; -extern const uint16_t c_aauiLCLDHuffEnc57[65][2]; -extern const uint16_t c_aauiLCLDHuffEnc58[77][2]; -extern const uint16_t c_aauiLCLDHuffEnc59[91][2]; -extern const uint16_t c_aauiLCLDHuffEnc60[109][2]; -extern const uint16_t c_aauiLCLDHuffEnc61[129][2]; -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 /* _TABLES_H_ */ diff --git a/lib_rend/ivas_objectRenderer.c b/lib_rend/ivas_objectRenderer.c index 8fc8935ec..bbb5f8c1a 100644 --- a/lib_rend/ivas_objectRenderer.c +++ b/lib_rend/ivas_objectRenderer.c @@ -36,9 +36,6 @@ #include "prot.h" #include "ivas_prot.h" #include "ivas_prot_rend.h" -#ifdef SPLIT_REND_WITH_HEAD_ROT -#include "ivas_prot.h" -#endif #include #include "ivas_rom_com.h" #ifdef DEBUGGING @@ -762,153 +759,6 @@ ivas_error ivas_td_binaural_renderer_ext( } -#ifdef SPLIT_REND_WITH_HEAD_ROT -/*---------------------------------------------------------------------* - * ObjRenderIvasFrame_splitBinaural() - * - * Render to multiple binaural pairs based on relative head positions for split rendering. - *---------------------------------------------------------------------*/ - -ivas_error ObjRenderIvasFrame_splitBinaural( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - float *output[], /* i/o: SCE channels / Binaural synthesis */ - const int16_t output_frame /* i : output frame length */ -) -{ - int16_t i; - float tmpProcessing[MAX_OUTPUT_CHANNELS][L_FRAME48k]; - float tmpBinaural[MAX_HEAD_ROT_POSES * 2][L_FRAME48k]; - float *p_tmpProcessing[MAX_OUTPUT_CHANNELS]; - int16_t pos_idx; - IVAS_QUATERNION originalHeadRot[MAX_PARAM_SPATIAL_SUBFRAMES]; - MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData; - BINAURAL_TD_OBJECT_RENDERER_HANDLE tmpTdRendHandle; - ivas_error error; - - push_wmops( "ObjRenderIvasFrame_splitBinaural" ); - pMultiBinPoseData = &st_ivas->hSplitBinRend.splitrend.multiBinPoseData; - - /* If not yet allocated, open additional instances of TD renderer */ - for ( i = 0; i < pMultiBinPoseData->num_poses - 1; ++i ) - { - if ( st_ivas->hSplitBinRend.splitrend.hTdRendHandles[i] != NULL ) - { - continue; - } - - if ( ( error = ivas_td_binaural_open_unwrap( &st_ivas->hHrtfTD, - st_ivas->hDecoderConfig->output_Fs, - st_ivas->nchan_transport, - st_ivas->ivas_format, - st_ivas->transport_config, - st_ivas->hRenderConfig->directivity, - st_ivas->hTransSetup, - &st_ivas->hSplitBinRend.splitrend.hTdRendHandles[i], - &st_ivas->binaural_latency_ns ) ) != IVAS_ERR_OK ) - { - return error; - } - } - - /* Save current head positions */ - for ( i = 0; i < st_ivas->hCombinedOrientationData->num_subframes; ++i ) - { - originalHeadRot[i] = st_ivas->hCombinedOrientationData->Quaternions[i]; - } - - /* Copy input audio to a processing buffer. Cannot render in-place because binaurally rendered - * audio would overwrite original material, which is still needed for rendering next head pose. */ - for ( i = 0; i < st_ivas->nchan_transport; ++i ) - { - mvr2r( output[i], tmpProcessing[i], output_frame ); - } - - for ( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses; pos_idx++ ) - { - /* Update head positions */ - if ( pos_idx != 0 ) - { - for ( i = 0; i < st_ivas->hCombinedOrientationData->num_subframes; ++i ) - { - if ( originalHeadRot[i].w == -3.0f ) - { - st_ivas->hCombinedOrientationData->Quaternions[i].w = -3.0f; - st_ivas->hCombinedOrientationData->Quaternions[i].x = originalHeadRot[i].x + pMultiBinPoseData->relative_head_poses[pos_idx][0]; - st_ivas->hCombinedOrientationData->Quaternions[i].y = originalHeadRot[i].y + pMultiBinPoseData->relative_head_poses[pos_idx][1]; - st_ivas->hCombinedOrientationData->Quaternions[i].z = originalHeadRot[i].z + pMultiBinPoseData->relative_head_poses[pos_idx][2]; - } - else - { - st_ivas->hCombinedOrientationData->Quaternions[i].w = -3.0f; - - Quat2EulerDegree( originalHeadRot[i], /* TODO tmu : fix bug with ordering*/ - &st_ivas->hCombinedOrientationData->Quaternions[i].z, - &st_ivas->hCombinedOrientationData->Quaternions[i].y, - &st_ivas->hCombinedOrientationData->Quaternions[i].x ); - - st_ivas->hCombinedOrientationData->Quaternions[i].x += pMultiBinPoseData->relative_head_poses[pos_idx][0]; - st_ivas->hCombinedOrientationData->Quaternions[i].y += pMultiBinPoseData->relative_head_poses[pos_idx][1]; - st_ivas->hCombinedOrientationData->Quaternions[i].z += pMultiBinPoseData->relative_head_poses[pos_idx][2]; - } - } - } - - /* Handle the 1 ISM case where there is only one channel in the input buffer */ - for ( i = 0; i < max( st_ivas->nchan_transport, BINAURAL_CHANNELS ); ++i ) - { - p_tmpProcessing[i] = tmpProcessing[i]; - } - - /* Render */ - if ( pos_idx == 0 ) - { - if ( ( error = ivas_td_binaural_renderer( st_ivas, p_tmpProcessing, output_frame ) ) != IVAS_ERR_OK ) - { - return error; - } - } - else - { - /* Tmp swap renderer handles for rendering call */ - tmpTdRendHandle = st_ivas->hBinRendererTd; - st_ivas->hBinRendererTd = st_ivas->hSplitBinRend.splitrend.hTdRendHandles[pos_idx - 1]; - - if ( ( error = ivas_td_binaural_renderer( st_ivas, p_tmpProcessing, output_frame ) ) != IVAS_ERR_OK ) - { - return error; - } - - st_ivas->hBinRendererTd = tmpTdRendHandle; - } - - /* Copy rendered audio to tmp storage buffer. Copying directly to output would - * overwrite original audio, which is still needed for rendering next head pose. */ - mvr2r( tmpProcessing[0], tmpBinaural[2 * pos_idx], output_frame ); - mvr2r( tmpProcessing[1], tmpBinaural[2 * pos_idx + 1], output_frame ); - - /* Overwrite first 2 channels with original input audio again */ - mvr2r( output[0], tmpProcessing[0], output_frame ); - mvr2r( output[1], tmpProcessing[1], output_frame ); - } - - /* Copy from storage buffer to output */ - for ( i = 0; i < pMultiBinPoseData->num_poses * BINAURAL_CHANNELS; ++i ) - { - mvr2r( tmpBinaural[i], output[i], output_frame ); - } - - /* Restore original head rotation */ - for ( i = 0; i < st_ivas->hCombinedOrientationData->num_subframes; ++i ) - { - st_ivas->hCombinedOrientationData->Quaternions[i] = originalHeadRot[i]; - } - - pop_wmops(); - return IVAS_ERR_OK; -} -#endif - - /*---------------------------------------------------------------------* * angles_to_vec() * diff --git a/lib_rend/ivas_output_init.c b/lib_rend/ivas_output_init.c index 78db534f7..741974632 100644 --- a/lib_rend/ivas_output_init.c +++ b/lib_rend/ivas_output_init.c @@ -409,7 +409,7 @@ int16_t ivas_get_nchan_buffers_dec( #ifdef SPLIT_REND_WITH_HEAD_ROT if ( output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) { - nchan_out_buff = max( nchan_out_buff, st_ivas->hSplitBinRend.splitrend.multiBinPoseData.num_poses * BINAURAL_CHANNELS ); + nchan_out_buff = max( nchan_out_buff, st_ivas->hSplitBinRend->splitrend.multiBinPoseData.num_poses * BINAURAL_CHANNELS ); } #endif diff --git a/lib_rend/ivas_prot_rend.h b/lib_rend/ivas_prot_rend.h index de3830bea..d05b5ea7b 100644 --- a/lib_rend/ivas_prot_rend.h +++ b/lib_rend/ivas_prot_rend.h @@ -77,37 +77,6 @@ int16_t ivas_get_nchan_buffers_dec( const int32_t ivas_total_brate /* i : total IVAS bitrate */ ); -/*----------------------------------------------------------------------------------* - * Limiter prototypes - *----------------------------------------------------------------------------------*/ - - -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( - IVAS_LIMITER_HANDLE* phLimiter /* i/o: pointer to limiter handle, can be NULL */ -); - -void ivas_limiter_dec -( - IVAS_LIMITER_HANDLE hLimiter, /* i/o: limiter struct handle */ - float *output[MAX_OUTPUT_CHANNELS], /* i/o: input/output buffer */ - const int16_t num_channels, /* i : number of channels to be processed */ - const int16_t output_frame, /* i : number of samples per channel in the buffer */ - const int16_t BER_detect /* i : BER detect flag */ -); - -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 */ - const float threshold, /* i : signal amplitude above which limiting starts to be applied */ - const int16_t BER_detect, /* i : BER detect flag */ - int16_t *strong_saturation_cnt /* i/o: counter of strong saturations (can be NULL) */ -); /*----------------------------------------------------------------------------------* * TD decorr. function prototypes @@ -466,8 +435,6 @@ void ivas_dirac_dec_output_synthesis_process_slot( const float *diffuseness, SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, /* i/o: common spatial renderer data handle */ DIRAC_REND_HANDLE hDirACRend, /* i/o: DirAC renderer handle */ - const int16_t sh_rot_max_order, - const float *p_Rmat, /* i : rotation matrix */ const VBAP_HANDLE hVBAPdata, /* i : VBAP structure */ const IVAS_OUTPUT_SETUP hOutSetup, /* i : output setup structure */ const int16_t nchan_transport, /* i : number of transport channels */ @@ -534,8 +501,6 @@ void ivas_dirac_dec_compute_directional_responses( const int16_t *elevation, const int16_t md_idx, const float *surCohRatio, - const int16_t shd_rot_max_order, /* i : split-order rotation method */ - const float *p_Rmat, /* i : rotation matrix */ const int16_t hodirac_flag /* i : flag to indicate HO-DirAC mode */ ); @@ -1262,10 +1227,6 @@ void Euler2Quat( IVAS_QUATERNION *quat /* o : quaternion describing the rotation */ ); -float deg2rad( - float degrees -); - float rad2deg( float radians ); @@ -1461,232 +1422,6 @@ ivas_error ivas_orient_trk_Process( IVAS_QUATERNION *pTrkRot /* o : tracked rotation */ ); -#ifdef SPLIT_REND_WITH_HEAD_ROT -void ivas_set_split_rend_ht_setup( - IVAS_DEC_SPLIT_REND_WRAPPER *hSplitBinRend, - COMBINED_ORIENTATION_HANDLE hCombinedOrientationData -); - -/*----------------------------------------------------------------------------------* - * Split binaural renderer prototypes - *----------------------------------------------------------------------------------*/ - -void ivas_set_split_rend_ht_setup( - IVAS_DEC_SPLIT_REND_WRAPPER *hSplitBinRend, - COMBINED_ORIENTATION_HANDLE hCombinedOrientationData -); - -ivas_error ivas_set_split_rend_setup( - IVAS_DEC_SPLIT_REND_WRAPPER *hSplitBinRend, - IVAS_SPLIT_REND_CONFIG_DATA *hSplitBinConfig, - COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i/o: combined orientation handle */ - uint8_t *splitRendBitsBuf -); - -void ivas_init_split_rend_handles( - SPLIT_REND_WRAPPER *hSplitRendWrapper -); - -void ivas_init_split_post_rend_handles( - SPLIT_POST_REND_WRAPPER *hSplitRendWrapper -); - -ivas_error ivas_split_renderer_open( - SPLIT_REND_WRAPPER *hSplitBinRend, - const IVAS_SPLIT_REND_CONFIG_DATA *pSplitRendConfig, - const int32_t output_Fs, - const int16_t cldfb_in_flag, - const int16_t pcm_out_flag, - const int16_t is_5ms_frame -); - -void ivas_split_renderer_close( - SPLIT_REND_WRAPPER *hSplitBinRend -); - -ivas_error ivas_splitBinLCLDEncOpen( - BIN_HR_SPLIT_LCLD_ENC_HANDLE *hSplitBinLCLDEnc, - const int32_t iSampleRate, - const int16_t iChannels, - const int32_t iDataRate -); - -void ivas_splitBinLCLDEncClose( - BIN_HR_SPLIT_LCLD_ENC_HANDLE *hSplitBinLCLDEnc -); - -void ivas_splitBinLCLDEncProcess( - 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, - IVAS_SPLIT_REND_BITS_HANDLE pBits -); - -ivas_error ivas_splitBinLCLDDecOpen( - BIN_HR_SPLIT_LCLD_DEC_HANDLE *hSplitBinLCLDDec, - const int32_t iSampleRate, - const int16_t iChannels -); - -void ivas_splitBinLCLDDecClose( - BIN_HR_SPLIT_LCLD_DEC_HANDLE *hSplitBinLCLDDec -); - -void ivas_splitBinLCLDDecProcess( - BIN_HR_SPLIT_LCLD_DEC_HANDLE hSplitBinLCLDDec, - IVAS_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 -); - -ivas_error ivas_splitBinPreRendOpen( - 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 -); - -ivas_error ivas_splitBinPostRendOpen( - BIN_HR_SPLIT_POST_REND_HANDLE *hBinHrSplitPostRend, - MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, - const int32_t output_Fs -); - -void ivas_init_multi_bin_pose_data( - MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData -); - -void ivas_renderSplitGetMultiBinPoseData( - const IVAS_SPLIT_REND_CONFIG_DATA *pSplit_rend_config, - MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, - const IVAS_SPLIT_REND_ROT_AXIS rot_axis -); - -void ivas_renderSplitUpdateNoCorrectionPoseData( - const IVAS_SPLIT_REND_CONFIG_DATA *pSplit_rend_config, - MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData -); - -ivas_error ivas_renderMultiBinToSplitBinaural( - SPLIT_REND_WRAPPER *hSplitBin, - const IVAS_QUATERNION headPosition, - const int32_t SplitRendBitRate, - IVAS_SPLIT_REND_CODEC splitCodec, - int16_t codec_frame_size_ms, - IVAS_SPLIT_REND_BITS_HANDLE pBits, - float Cldfb_In_BinReal[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - float Cldfb_In_BinImag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - const int16_t max_bands, - float *output[], - const int16_t low_res_pre_rend_rot, - const int16_t cldfb_in_flag, - const int16_t pcm_out_flag -); - -void ivas_rend_CldfbSplitPreRendProcess( - const 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], - IVAS_SPLIT_REND_BITS_HANDLE pBits, - const int32_t target_md_bits, - const int16_t low_res_pre_rend_rot -); - -void ivas_rend_CldfbSplitPostRendProcess( - 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 -); - -void ivas_splitBinPreRendClose( - BIN_HR_SPLIT_PRE_REND_HANDLE *hBinHrSplitPreRend -); - -void ivas_splitBinPostRendClose( - BIN_HR_SPLIT_POST_REND_HANDLE *hBinHrSplitPostRend ); - -void ivas_splitBinPostRendMdDec( - IVAS_SPLIT_REND_BITS_HANDLE pBits, - BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend, -#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 -); - -ivas_error ivas_splitBinRendPLCOpen( - SPLIT_REND_PLC_HANDLE* phSplitRendPLC -); - -void ivas_splitBinRendPLCClose( - SPLIT_REND_PLC_HANDLE* phSplitRendPLC -); - -void ivas_splitBinRendPLCsaveState( - 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 -); - -void ivas_splitBinRendPLC_xf( - 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 -); - -void ivas_splitBinRendPLC( - 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 -); - -#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG -void ivas_log_cldfb2wav_data( - float Cldfb_In_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - float Cldfb_In_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - HANDLE_CLDFB_FILTER_BANK *cldfbSyn, - const int16_t num_chs, - const int16_t num_freq_bands, - const int32_t output_Fs, - const int16_t start_slot_idx, - const int16_t md_band_idx, - const char *filename -); -#endif - -void ivas_SplitRenderer_GetRotMd( - 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 -); - -void ivas_SplitRenderer_PostRenderer( - 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 -); - -#endif /*----------------------------------------------------------------------------------* * Rendering & merging to MASA format @@ -1802,17 +1537,10 @@ void masaPrerendClose( * Split rendering *----------------------------------------------------------------------------------*/ -/* TODO(sgi): Rework interface */ -ivas_error ObjRenderIvasFrame_splitBinaural( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ - float *output[], /* i/o: SCE channels / Binaural synthesis */ - const int16_t output_frame /* i : output frame length */ -); - ivas_error ivas_td_binaural_renderer_sf_splitBinaural( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ float *output[], /* i/o: SCE channels / Binaural synthesis */ - int16_t nSamplesRendered /* i : number of samples to render */ + const int16_t nSamplesRendered /* i : number of samples to render */ ); ivas_error ivas_rend_crendProcessSubframesSplitBin( @@ -1836,8 +1564,8 @@ ivas_error ivas_rend_crendProcessSplitBin( const AUDIO_CONFIG inConfig, const AUDIO_CONFIG outConfig, const MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, - DECODER_CONFIG_HANDLE hDecoderConfig, - COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, + const DECODER_CONFIG_HANDLE hDecoderConfig, + const COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, const IVAS_OUTPUT_SETUP_HANDLE hIntSetup, EFAP_HANDLE hEFAPdata, float *output[], @@ -1878,120 +1606,10 @@ ivas_error ivas_rend_openCldfbRend( const int32_t output_Fs ); -void ivas_mat_mult_2by2_complex( - float in_re1[2][2], - float in_im1[2][2], - float in_re2[2][2], - float in_im2[2][2], - float out_re2[2][2], - float out_im2[2][2] -); - -void ivas_split_rend_bitstream_init( - IVAS_SPLIT_REND_BITS_HANDLE pBits, - const int32_t buf_len_bytes, uint8_t *pbuf -); - -void ivas_split_rend_huffman_dec_init_min_max_len( - ivas_split_rend_huffman_cfg_t *p_huff_cfg -); - -void ivas_split_rend_init_huff_cfg( - BIN_HR_SPLIT_REND_HUFF_HANDLE pHuff_cfg ); - -void set_fix_rotation_mat( - float fix_pos_rot_mat[][BINAURAL_CHANNELS][BINAURAL_CHANNELS], - MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData -); - -void set_pose_types( - IVAS_SPLIT_REND_POSE_TYPE pose_type[MAX_HEAD_ROT_POSES - 1], - MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData -); - -int16_t wrap_a( - int16_t val, - const int16_t min_val, - const int16_t max_val -); - -void ivas_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 -); - -void ivas_split_rend_bitstream_write_int32( - IVAS_SPLIT_REND_BITS_HANDLE pBits, - const int32_t val, - const int32_t bits -); - -int32_t ivas_split_rend_bitstream_read_int32( - IVAS_SPLIT_REND_BITS_HANDLE pBits, - const int32_t bits -); - - void ivas_rend_closeCldfbRend( CLDFB_REND_WRAPPER *pCldfbRend ); -int32_t ivas_get_lcld_bitrate( - const int32_t SplitRendBitRate, - const IVAS_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode -); - -int32_t ivas_get_split_rend_md_target_brate( - const int32_t SplitRendBitRate, - const int16_t pcm_out_flag -); - -int32_t ivas_get_lc3plus_bitrate( - const int32_t SplitRendBitRate, - const IVAS_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode, - const int16_t split_prerender_frame_size_ms -); - -int8_t ivas_get_lc3plus_bitrate_id( - const int32_t SplitRendBitRate -); - -int32_t ivas_get_lc3plus_size_from_id( - const int8_t SplitRendBitRateId, - const IVAS_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode, - const int16_t split_prerender_frame_size_ms -); - -ivas_error ivas_split_rend_validate_config( - const IVAS_SPLIT_REND_CONFIG_DATA *pSplitRendConfig, - const int16_t pcm_out_flag -); - -void ivas_split_rend_get_quant_params( - const int16_t num_md_bands, - int16_t pred_real_bands_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], - int16_t pred_imag_bands_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], - int16_t pred_quant_pnts_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], - float pred_quantstep_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], - float pred_1byquantstep_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], - int16_t d_bands_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], - int16_t bands_pitch[IVAS_SPLIT_REND_NUM_QUANT_STRATS], - int16_t pred_real_bands_roll[IVAS_SPLIT_REND_NUM_QUANT_STRATS], - int16_t pred_imag_bands_roll[IVAS_SPLIT_REND_NUM_QUANT_STRATS], - int16_t *num_quant_strats, - int16_t *num_complex_bands -); - -ivas_error ivas_split_rend_choose_default_codec( - IVAS_SPLIT_REND_CODEC *pCodec, /* i/o: pointer to codec setting */ - 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 CLDFB */ - const int16_t pcm_out_flag /* i : flag to indicate PCM output */ -); - #endif /* clang-format on */ diff --git a/lib_rend/ivas_render_config.c b/lib_rend/ivas_render_config.c index c7a1abacf..96898d7ef 100644 --- a/lib_rend/ivas_render_config.c +++ b/lib_rend/ivas_render_config.c @@ -136,10 +136,16 @@ ivas_error ivas_render_config_init_from_rom( ( *hRenderConfig )->split_rend_config.dof = 3; ( *hRenderConfig )->split_rend_config.hq_mode = 0; ( *hRenderConfig )->split_rend_config.codec_delay_ms = 0; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + ( *hRenderConfig )->split_rend_config.isar_frame_size_ms = 20; +#endif ( *hRenderConfig )->split_rend_config.codec_frame_size_ms = 0; /* 0 means "use default for selected codec" */ - ( *hRenderConfig )->split_rend_config.codec = IVAS_SPLIT_REND_CODEC_DEFAULT; - ( *hRenderConfig )->split_rend_config.poseCorrectionMode = IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB; - ( *hRenderConfig )->split_rend_config.rendererSelection = IVAS_SPLIT_REND_RENDERER_SELECTION_DEFAULT; + ( *hRenderConfig )->split_rend_config.codec = ISAR_SPLIT_REND_CODEC_DEFAULT; + ( *hRenderConfig )->split_rend_config.poseCorrectionMode = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB; + ( *hRenderConfig )->split_rend_config.rendererSelection = ISAR_SPLIT_REND_RENDERER_SELECTION_DEFAULT; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + ( *hRenderConfig )->split_rend_config.lc3plus_highres = 0; +#endif #endif return IVAS_ERR_OK; diff --git a/lib_rend/ivas_rom_rend.h b/lib_rend/ivas_rom_rend.h index 165f4791c..a6f309c26 100644 --- a/lib_rend/ivas_rom_rend.h +++ b/lib_rend/ivas_rom_rend.h @@ -148,12 +148,4 @@ extern const float ls_conversion_cicpX_stereo[12][2]; extern const LS_CONVERSION_MAPPING ls_conversion_mapping[]; -#ifdef SPLIT_REND_WITH_HEAD_ROT -/*----------------------------------------------------------------------------------* - * Split binaural rendering ROM tables - *----------------------------------------------------------------------------------*/ - -extern const int32_t split_rend_brate_tbl[]; -#endif - #endif /* IVAS_ROM_REND_H */ diff --git a/lib_rend/ivas_rotation.c b/lib_rend/ivas_rotation.c index 28d5b805b..d61c3bba7 100644 --- a/lib_rend/ivas_rotation.c +++ b/lib_rend/ivas_rotation.c @@ -37,6 +37,7 @@ #include #include "cnst.h" #include "prot.h" +#include "ivas_prot.h" #include "ivas_prot_rend.h" #ifdef DEBUGGING #include "debug.h" @@ -52,7 +53,7 @@ static ivas_error combine_external_and_head_orientations( IVAS_QUATERNION *headRotQuaternions, IVAS_VECTOR3 *listenerPos, #ifdef SPLIT_REND_WITH_HEAD_ROT - IVAS_SPLIT_REND_ROT_AXIS sr_pose_pred_axis, /* i : split rend pose prediction axis*/ + ISAR_SPLIT_REND_ROT_AXIS sr_pose_pred_axis, /* i : split rend pose prediction axis*/ #endif EXTERNAL_ORIENTATION_HANDLE hExtOrientationData, COMBINED_ORIENTATION_HANDLE hCombinedOrientationData ); @@ -186,100 +187,6 @@ void QuatToRotMat( } -/*------------------------------------------------------------------------- - * Euler2Quat() - * - * Calculate corresponding Quaternion from Euler angles in radians - *------------------------------------------------------------------------*/ - -void Euler2Quat( - const float yaw, /* i : yaw (x) */ - const float pitch, /* i : pitch (y) */ - const float roll, /* i : roll (z) */ - IVAS_QUATERNION *quat /* o : quaternion describing the rotation */ -) -{ - float cr = cosf( roll * 0.5f ); - float sr = sinf( roll * 0.5f ); - float cp = cosf( pitch * 0.5f ); - float sp = sinf( pitch * 0.5f ); - float cy = cosf( yaw * 0.5f ); - float sy = sinf( yaw * 0.5f ); - quat->w = cr * cp * cy + sr * sp * sy; - quat->x = sr * cp * cy - cr * sp * sy; - quat->y = sr * cp * sy + cr * sp * cy; - quat->z = cr * cp * sy - sr * sp * cy; - - return; -} - - -#ifdef SPLIT_REND_WITH_HEAD_ROT -/*------------------------------------------------------------------------- - * Quat2EulerDegree() - * - * Quaternion handling: calculate corresponding Euler angles in degrees - *------------------------------------------------------------------------*/ - -void Quat2EulerDegree( - const IVAS_QUATERNION quat, /* i : quaternion describing the rotation */ - float *yaw, /* o : yaw */ - float *pitch, /* o : pitch */ - float *roll /* o : roll */ -) -{ - 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; - } - 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 = quat.z; - *pitch = quat.y; - *roll = quat.x; - } - - return; -} -#endif - - -/*------------------------------------------------------------------------- - * deg2rad() - * - * Converts degrees to normalized radians - *------------------------------------------------------------------------*/ - -float deg2rad( - float degrees ) -{ - while ( degrees >= 180.0f ) - { - degrees = degrees - 360.0f; - } - while ( degrees <= -180.0f ) - { - degrees = degrees + 360.0f; - } - - return PI_OVER_180 * degrees; -} - - /*------------------------------------------------------------------------- * rad2deg() * @@ -872,8 +779,8 @@ void ivas_external_orientation_close( ivas_error ivas_combined_orientation_open( COMBINED_ORIENTATION_HANDLE *hCombinedOrientationData, /* o : combined orientation handle */ - const int32_t fs, /* i : sampling rate */ - const int16_t num_subframes /* i : number of subframes */ + const int32_t fs, /* i : sampling rate */ + const int16_t num_subframes /* i : number of subframes */ ) { int16_t i; @@ -1002,7 +909,7 @@ ivas_error combine_external_and_head_orientations_dec( ) { #ifdef SPLIT_REND_WITH_HEAD_ROT - IVAS_SPLIT_REND_ROT_AXIS sr_pose_pred_axis; + ISAR_SPLIT_REND_ROT_AXIS sr_pose_pred_axis; #endif IVAS_QUATERNION *pHeadRotQuaternion = NULL; IVAS_VECTOR3 *listenerPos = NULL; @@ -1043,7 +950,7 @@ ivas_error combine_external_and_head_orientations_rend( ) { #ifdef SPLIT_REND_WITH_HEAD_ROT - IVAS_SPLIT_REND_ROT_AXIS sr_pose_pred_axis; + ISAR_SPLIT_REND_ROT_AXIS sr_pose_pred_axis; #endif IVAS_QUATERNION *headRotQuaternions = NULL; IVAS_VECTOR3 *listenerPos = NULL; @@ -1094,7 +1001,7 @@ ivas_error combine_external_and_head_orientations( IVAS_QUATERNION *headRotQuaternions, /* i : quaternions for head rotation */ IVAS_VECTOR3 *listenerPos, /* i : listener position */ #ifdef SPLIT_REND_WITH_HEAD_ROT - IVAS_SPLIT_REND_ROT_AXIS sr_pose_pred_axis, /* i : split rend pose prediction axis */ + ISAR_SPLIT_REND_ROT_AXIS sr_pose_pred_axis, /* i : split rend pose prediction axis */ #endif EXTERNAL_ORIENTATION_HANDLE hExtOrientationData, /* i : external orientation handle */ COMBINED_ORIENTATION_HANDLE hCombinedOrientationData /* i/o: combined orientation handle */ diff --git a/lib_rend/ivas_splitRend_lcld_dec.c b/lib_rend/ivas_splitRend_lcld_dec.c deleted file mode 100644 index 1d81dfebc..000000000 --- a/lib_rend/ivas_splitRend_lcld_dec.c +++ /dev/null @@ -1,239 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2023 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. - -*******************************************************************************************************/ - -#include -#include "options.h" -#ifdef SPLIT_REND_WITH_HEAD_ROT -#include "ivas_prot_rend.h" -#include "ivas_prot.h" -#include "prot.h" -#ifdef DEBUGGING -#include "debug.h" -#endif -#include "wmc_auto.h" - - -/*------------------------------------------------------------------------- - * Function ivas_splitBinLCLDDecOpen() - * - * - *------------------------------------------------------------------------*/ - -ivas_error ivas_splitBinLCLDDecOpen( - BIN_HR_SPLIT_LCLD_DEC_HANDLE *hSplitBinLCLDDec, - const int32_t iSampleRate, - const int16_t iChannels ) -{ - int16_t n; - BIN_HR_SPLIT_LCLD_DEC_HANDLE splitBinLCLDDec; - ivas_error error; - - if ( ( splitBinLCLDDec = (BIN_HR_SPLIT_LCLD_DEC_HANDLE) malloc( sizeof( BIN_HR_SPLIT_LCLD_DEC ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD decoder Module \n" ) ); - } - - splitBinLCLDDec->pLcld_dec = NULL; /* place holder for CLDFB decoder handle */ - - splitBinLCLDDec->iChannels = iChannels; - if ( ( error = CreateLCLDDecoder( &splitBinLCLDDec->psLCLDDecoder, iSampleRate, iChannels ) ) != IVAS_ERR_OK ) - { - return error; - } - - if ( ( splitBinLCLDDec->pppfDecLCLDReal = (float ***) malloc( iChannels * sizeof( float ** ) ) ) == 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 ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD decoder Module \n" ) ); - } - - for ( n = 0; n < splitBinLCLDDec->iChannels; n++ ) - { - if ( ( splitBinLCLDDec->pppfDecLCLDReal[n] = (float **) malloc( CLDFB_NO_COL_MAX * sizeof( float * ) ) ) == 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 ) - { - 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"; - if ( ( splitBinLCLDDec->cldfbOut = fopen( cldfbFilename, "wb" ) ) == NULL ) - { - fprintf( stderr, "Error: CLDFB bitstream file %s could not be opened\n\n", cldfbFilename ); - exit( -1 ); - } - int16_t num_bands = CLDFB_NO_CHANNELS_MAX; - fwrite( &iChannels, sizeof( int16_t ), 1, splitBinLCLDDec->cldfbOut ); - fwrite( &num_bands, sizeof( int16_t ), 1, splitBinLCLDDec->cldfbOut ); -#endif - - if ( ( error = ivas_splitBinRendPLCOpen( &splitBinLCLDDec->hSplitRendPLC ) ) != IVAS_ERR_OK ) - { - return error; - } - - *hSplitBinLCLDDec = splitBinLCLDDec; - - return IVAS_ERR_OK; -} - - -/*------------------------------------------------------------------------- - * Function ivas_splitBinLCLDDecClose() - * - * - *------------------------------------------------------------------------*/ - -void ivas_splitBinLCLDDecClose( - BIN_HR_SPLIT_LCLD_DEC_HANDLE *hSplitBinLCLDDec ) -{ - int16_t n; - - if ( ( *hSplitBinLCLDDec ) != NULL ) - { - if ( ( *hSplitBinLCLDDec )->psLCLDDecoder != NULL ) - { - DeleteLCLDDecoder( ( *hSplitBinLCLDDec )->psLCLDDecoder ); - } - - for ( n = 0; n < ( *hSplitBinLCLDDec )->iChannels; n++ ) - { - free( ( *hSplitBinLCLDDec )->pppfDecLCLDReal[n] ); - free( ( *hSplitBinLCLDDec )->pppfDecLCLDImag[n] ); - } - free( ( *hSplitBinLCLDDec )->pppfDecLCLDReal ); - free( ( *hSplitBinLCLDDec )->pppfDecLCLDImag ); - -#ifdef CLDFB_DEBUG - if ( ( *hSplitBinLCLDDec )->cldfbOut != NULL ) - { - fclose( ( *hSplitBinLCLDDec )->cldfbOut ); - } -#endif - ivas_splitBinRendPLCClose( &( *hSplitBinLCLDDec )->hSplitRendPLC ); - - free( *hSplitBinLCLDDec ); - *hSplitBinLCLDDec = NULL; - } - - return; -} - - -/*------------------------------------------------------------------------- - * Function ivas_splitBinLCLDDecProcess() - * - * - *------------------------------------------------------------------------*/ - -void ivas_splitBinLCLDDecProcess( - BIN_HR_SPLIT_LCLD_DEC_HANDLE hSplitBinLCLDDec, - IVAS_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 ) -{ - int16_t k, n; - - push_wmops( "ivas_splitBinLCLDDecProcess" ); - - assert( hSplitBinLCLDDec != NULL ); - assert( Cldfb_Out_Real != NULL ); - assert( Cldfb_Out_Imag != NULL ); - assert( pBits != NULL ); - -#ifdef CLDFB_DEBUG - printf( "Bytes read = %d\n", iBytesWritten ); -#endif - if ( !bfi ) - { - /* Initialized with zeros....... */ - for ( n = 0; n < hSplitBinLCLDDec->iChannels; n++ ) - { - for ( k = 0; k < CLDFB_NO_COL_MAX; k++ ) - { - hSplitBinLCLDDec->pppfDecLCLDReal[n][k] = Cldfb_Out_Real[n][k]; - hSplitBinLCLDDec->pppfDecLCLDImag[n][k] = Cldfb_Out_Imag[n][k]; - set_f( hSplitBinLCLDDec->pppfDecLCLDReal[n][k], 0, CLDFB_NO_CHANNELS_MAX ); - set_f( hSplitBinLCLDDec->pppfDecLCLDImag[n][k], 0, CLDFB_NO_CHANNELS_MAX ); - } - } - - DecodeLCLDFrame( hSplitBinLCLDDec->psLCLDDecoder, pBits, hSplitBinLCLDDec->pppfDecLCLDReal, hSplitBinLCLDDec->pppfDecLCLDImag ); - -#ifdef CLDFB_DEBUG - printf( "Frame Decoded = %d\n", ++hSplitBinLCLDDec->numFrame ); - int16_t writeByte = 0; - for ( k = 0; k < CLDFB_NO_COL_MAX; k++ ) - { - for ( int16_t b = 0; b < CLDFB_NO_CHANNELS_MAX; b++ ) - { - for ( n = 0; n < hSplitBinLCLDDec->iChannels; n++ ) - { - writeByte = fwrite( &hSplitBinLCLDDec->pppfDecLCLDReal[n][k][b], sizeof( float ), 1, hSplitBinLCLDDec->cldfbOut ); - if ( writeByte != 1 ) - exit( -1 ); - writeByte = fwrite( &hSplitBinLCLDDec->pppfDecLCLDImag[n][k][b], sizeof( float ), 1, hSplitBinLCLDDec->cldfbOut ); - if ( writeByte != 1 ) - exit( -1 ); - } - } - } -#endif - if ( hSplitBinLCLDDec->hSplitRendPLC->prev_bfi != 0 ) - { - /* cross-fade recovered frame into good frame */ - ivas_splitBinRendPLC_xf( hSplitBinLCLDDec->hSplitRendPLC, Cldfb_Out_Real, Cldfb_Out_Imag, (int16_t) hSplitBinLCLDDec->iChannels ); - } - } - else - { - /* do PLC for lost split renderer frame */ - ivas_splitBinRendPLC( hSplitBinLCLDDec->hSplitRendPLC, Cldfb_Out_Real, Cldfb_Out_Imag, (int16_t) hSplitBinLCLDDec->iChannels ); - } - - /* save PLC state */ - ivas_splitBinRendPLCsaveState( hSplitBinLCLDDec->hSplitRendPLC, Cldfb_Out_Real, Cldfb_Out_Imag, (int16_t) hSplitBinLCLDDec->iChannels ); - - pop_wmops(); - - return; -} -#endif diff --git a/lib_rend/ivas_splitRend_lcld_enc.c b/lib_rend/ivas_splitRend_lcld_enc.c deleted file mode 100644 index a0789d63a..000000000 --- a/lib_rend/ivas_splitRend_lcld_enc.c +++ /dev/null @@ -1,232 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2023 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. - -*******************************************************************************************************/ - -#include -#include "options.h" -#ifdef SPLIT_REND_WITH_HEAD_ROT -#include "ivas_prot_rend.h" -#include "ivas_prot.h" -#ifdef DEBUGGING -#include "debug.h" -#endif -#include "wmc_auto.h" - - -/*------------------------------------------------------------------------- - * Function ivas_splitBinLCLDEncOpen() - * - * - *------------------------------------------------------------------------*/ - -ivas_error ivas_splitBinLCLDEncOpen( - BIN_HR_SPLIT_LCLD_ENC_HANDLE *hSplitBinLCLDEnc, - const int32_t iSampleRate, - const int16_t iChannels, - const int32_t iDataRate ) -{ - BIN_HR_SPLIT_LCLD_ENC_HANDLE splitBinLCLDEnc; - ivas_error error; - - if ( ( splitBinLCLDEnc = (BIN_HR_SPLIT_LCLD_ENC_HANDLE) malloc( sizeof( BIN_HR_SPLIT_LCLD_ENC ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); - } - - splitBinLCLDEnc->pLcld_enc = NULL; // place holder for CLDFB encoder handle - - splitBinLCLDEnc->iChannels = iChannels; - if ( ( error = CreateLCLDEncoder( &( splitBinLCLDEnc->psLCLDEncoder ), iSampleRate, iChannels, iDataRate, 1 ) ) != IVAS_ERR_OK ) - { - return error; - } - - if ( ( splitBinLCLDEnc->pppfLCLDReal = (float ***) malloc( iChannels * sizeof( float ** ) ) ) == 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 ) - { - 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++ ) - { - if ( ( splitBinLCLDEnc->pppfLCLDReal[n] = (float **) malloc( CLDFB_NO_COL_MAX * sizeof( float * ) ) ) == 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 ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LCLD encoder Module \n" ) ); - } - } - -#ifdef CLDFB_DEBUG - splitBinLCLDEnc->numFrame = 0; - char cldfbFilename[50] = "cldfb_in_ref.qmf"; - if ( ( splitBinLCLDEnc->cldfbIn = fopen( cldfbFilename, "rb" ) ) == NULL ) - { - fprintf( stderr, "Error: CLDFB bitstream file %s could not be opened\n\n", cldfbFilename ); - exit( -1 ); - } - int16_t chan, band; - fread( &chan, sizeof( int16_t ), 1, splitBinLCLDEnc->cldfbIn ); - fread( &band, sizeof( int16_t ), 1, splitBinLCLDEnc->cldfbIn ); -#endif - - *hSplitBinLCLDEnc = splitBinLCLDEnc; - - return IVAS_ERR_OK; -} - - -/*------------------------------------------------------------------------- - * Function ivas_splitBinLCLDEncClose() - * - * - *------------------------------------------------------------------------*/ - -void ivas_splitBinLCLDEncClose( - BIN_HR_SPLIT_LCLD_ENC_HANDLE *hSplitBinLCLDEnc ) -{ - if ( ( *hSplitBinLCLDEnc ) != NULL ) - { - DeleteLCLDEncoder( ( *hSplitBinLCLDEnc )->psLCLDEncoder ); - - for ( int16_t n = 0; n < ( *hSplitBinLCLDEnc )->iChannels; n++ ) - { - free( ( *hSplitBinLCLDEnc )->pppfLCLDReal[n] ); - free( ( *hSplitBinLCLDEnc )->pppfLCLDImag[n] ); - } - free( ( *hSplitBinLCLDEnc )->pppfLCLDReal ); - free( ( *hSplitBinLCLDEnc )->pppfLCLDImag ); - -#ifdef CLDFB_DEBUG - if ( ( *hSplitBinLCLDEnc )->cldfbIn != NULL ) - { - fclose( ( *hSplitBinLCLDEnc )->cldfbIn ); - } -#endif - - free( *hSplitBinLCLDEnc ); - *hSplitBinLCLDEnc = NULL; - } - - return; -} - - -/*------------------------------------------------------------------------- - * Function ivas_splitBinLCLDEncProcess() - * - * - *------------------------------------------------------------------------*/ - -void ivas_splitBinLCLDEncProcess( - 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, - IVAS_SPLIT_REND_BITS_HANDLE pBits ) -{ - int32_t iBitsWritten; - - push_wmops( "ivas_splitBinLCLDEncProcess" ); - - assert( hSplitBinLCLDEnc != NULL ); - assert( Cldfb_In_Real != NULL ); - assert( Cldfb_In_Imag != NULL ); - assert( pBits != NULL ); - - /* A conversion is needed for the 3d pointer interface here ........ */ - for ( int32_t n = 0; n < hSplitBinLCLDEnc->iChannels; n++ ) - { - for ( int32_t k = 0; k < CLDFB_NO_COL_MAX; k++ ) - { - hSplitBinLCLDEnc->pppfLCLDReal[n][k] = Cldfb_In_Real[n][k]; - hSplitBinLCLDEnc->pppfLCLDImag[n][k] = Cldfb_In_Imag[n][k]; - } - } - -#ifdef CLDFB_DEBUG - int16_t readByte = 0; - for ( int16_t k = 0; k < CLDFB_NO_COL_MAX; k++ ) - { - for ( int16_t b = 0; b < CLDFB_NO_CHANNELS_MAX; b++ ) - { - for ( int16_t n = 0; n < hSplitBinLCLDEnc->iChannels; n++ ) - { - readByte = fread( &Cldfb_In_Real[n][k][b], sizeof( float ), 1, hSplitBinLCLDEnc->cldfbIn ); - if ( readByte != 1 ) - break; - readByte = fread( &Cldfb_In_Imag[n][k][b], sizeof( float ), 1, hSplitBinLCLDEnc->cldfbIn ); - } - } - } - - if ( readByte == 1 ) - { - printf( "Frame Read = %d\n", ++hSplitBinLCLDEnc->numFrame ); - } - else - { - printf( "Writing zeroes...\n" ); - for ( int16_T k = 0; k < CLDFB_NO_COL_MAX; k++ ) - { - for ( int16_t b = 0; b < CLDFB_NO_CHANNELS_MAX; b++ ) - { - for ( int16_t n = 0; n < hSplitBinLCLDEnc->iChannels; n++ ) - { - hSplitBinLCLDEnc->pppfLCLDReal[n][k][b] = 0.f; - hSplitBinLCLDEnc->pppfLCLDImag[n][k][b] = 0.f; - } - } - } - } -#endif - - EncodeLCLDFrame( hSplitBinLCLDEnc->psLCLDEncoder, hSplitBinLCLDEnc->pppfLCLDReal, hSplitBinLCLDEnc->pppfLCLDImag, &iBitsWritten, available_bits, pBits ); - -#ifdef DEBUGGING - if ( iBitsWritten > available_bits ) - assert( iBitsWritten <= available_bits ); -#endif - -#ifdef CLDFB_DEBUG - printf( "Bits written = %d\n", iBitsWritten ); -#endif - - pop_wmops(); - - return; -} -#endif diff --git a/lib_rend/ivas_splitRendererPLC.c b/lib_rend/ivas_splitRendererPLC.c deleted file mode 100644 index 0c75b55eb..000000000 --- a/lib_rend/ivas_splitRendererPLC.c +++ /dev/null @@ -1,552 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2023 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. - -*******************************************************************************************************/ - -#include -#include "options.h" -#ifdef SPLIT_REND_WITH_HEAD_ROT -#include -#include "ivas_prot.h" -#include "prot.h" -#include "ivas_cnst.h" -#include "ivas_prot_rend.h" -#ifdef DEBUGGING -#include "debug.h" -#endif -#include "wmc_auto.h" - - -/*------------------------------------------------------------------------- - * Local constants - *------------------------------------------------------------------------*/ - -#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 STH_THRESH ( 2.f / 3.f * PI2 / 12 ) - - -/*------------------------------------------------------------------------- - * Function adaptive_polar_ext_plc() - * - * - *------------------------------------------------------------------------*/ - -static void adaptive_polar_ext_plc( - const float *prev_real, - const float *prev_imag, - float *rec_real, - float *rec_imag -#if CLDFB_PLC_XF > 0 - , - float xf_alp[CLDFB_PLC_XF], - float xf_bet[CLDFB_PLC_XF] -#endif -) -{ - 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; - - /* reset of accumulators */ - ph_adj = 0.0f; - drho = 0.0f; - srho = 0.0f; - dth = 0.0f; - sth = 0.0f; - - /* calculate per-sample phase and magnitude evolution in preceding frame */ - for ( k = 0; k < CLDFB_NO_COL_MAX; k++ ) - { - urh[k] = sqrtf( prev_imag[k] * prev_imag[k] + prev_real[k] * prev_real[k] ); - if ( urh[k] < EPSILON ) - { - /* zero encountered */ - break; - } - uth[k] = atan2f( prev_imag[k], prev_real[k] ); - - /* phase unwrap */ - if ( k == 0 ) - { - uthu[0] = uth[0]; - } - else - { - /* phase unwrap */ - ph_diff = uth[k] - uth[k - 1]; - uthu[k] = uth[k]; - if ( fabsf( ph_diff ) >= PI2 / 2 ) - { - ph_adj_t = ph_diff / PI2; - if ( fabsf( ph_adj_t - truncf( ph_adj_t ) ) == 0.5f ) - { - ph_adj_t = truncf( ph_adj_t ); - } - ph_adj = -PI2 * roundf( ph_adj_t ) + ph_adj; - } - uthu[k] += ph_adj; - /* unwrapped phase in uthu */ - - /* mean and stdev of per-sample magnitude ratios */ - quot = urh[k] / urh[k - 1]; - drho += quot; - srho += SQR( quot ); - /* 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 == CLDFB_NO_COL_MAX ) - { - /* mean and stdev of per-sample magnitude ratios */ - drho *= 1.0f / ( CLDFB_NO_COL_MAX - 1 ); - temp = srho - ( CLDFB_NO_COL_MAX - 1 ) * SQR( drho ); - if ( temp > 0 ) - { - srho = sqrtf( temp * ( 1.0f / ( CLDFB_NO_COL_MAX - 2 ) ) ); - } - else - { - srho = 0.0f; - } - - /* mean and stdev of per-sample phase differences */ - dth *= 1.0f / ( CLDFB_NO_COL_MAX - 1 ); - temp = sth - ( CLDFB_NO_COL_MAX - 1 ) * SQR( dth ); - if ( temp > 0 ) - { - sth = sqrtf( temp * ( 1.0f / ( CLDFB_NO_COL_MAX - 2 ) ) ); - } - else - { - sth = 0.0f; - } - - /* do phase extension only if the std deviations are small */ - if ( ( srho < SRHO_THRESH ) || ( sth < STH_THRESH ) ) - { - /* 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; - -#if START_VAL_AVG_LEN > 1 - /* Calculate start value for evolution from last samples of previous frame */ - fac_powj_real = fac_real; - fac_powj_imag = fac_imag; - start_real = prev_real[CLDFB_NO_COL_MAX - 1]; - start_imag = prev_imag[CLDFB_NO_COL_MAX - 1]; - for ( j = 1; j < START_VAL_AVG_LEN; j++ ) - { - start_real += fac_powj_real * prev_real[CLDFB_NO_COL_MAX - j - 1] - fac_powj_imag * prev_imag[CLDFB_NO_COL_MAX - j - 1]; - start_imag += fac_powj_imag * prev_real[CLDFB_NO_COL_MAX - j - 1] + fac_powj_real * prev_imag[CLDFB_NO_COL_MAX - 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; - } - start_real *= 1.0f / START_VAL_AVG_LEN; - start_imag *= 1.0f / START_VAL_AVG_LEN; -#else - /* take last sample of previous frame as start value */ - start_real = prev_real[CLDFB_NO_COL_MAX - 1]; - start_imag = prev_imag[CLDFB_NO_COL_MAX - 1]; -#endif - -#if DO_PERTURB != 0 - /* 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] ); -#if PH_PERT_ONLY != 0 - /* 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; -#else - /* phase and magnitude perturbation */ - abs2inv = 1 / ( max( 1, drho ) * ( SQR( prev_real[0] ) + SQR( prev_imag[0] ) ) ); - rat_real *= abs2inv; - rat_imag *= abs2inv; -#endif - - /* 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 < CLDFB_NO_COL_MAX; j++ ) - { - /* 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] ); -#if PH_PERT_ONLY != 0 - /* only phase perturbation */ - 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; - /* 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]; - } - - /* 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 PH_PERT_ONLY != 0 - abs_temp = sqrtf( SQR( rat_real ) + SQR( rat_imag ) ); - abs2inv = min( 1, drho ) / max( EPSILON, abs_temp ); -#else - 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 + CLDFB_NO_COL_MAX - 2] = rat_real * rec_real[j + CLDFB_NO_COL_MAX - 3] - rat_imag * rec_imag[j + CLDFB_NO_COL_MAX - 3]; - rec_imag[j + CLDFB_NO_COL_MAX - 2] = rat_imag * rec_real[j + CLDFB_NO_COL_MAX - 3] + rat_real * rec_imag[j + CLDFB_NO_COL_MAX - 3]; - } -#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 < CLDFB_NO_COL_MAX + 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++ ) - { - rec_real[CLDFB_NO_COL_MAX + j] *= xf_alp[j]; - rec_imag[CLDFB_NO_COL_MAX + j] *= xf_alp[j]; - xf_bet[j] = 1 - xf_alp[j]; - } -#endif - } - else - { - /* 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 < CLDFB_NO_COL_MAX; 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]; - } - if ( Ruu_real[0] > EPSILON ) - { - /* prediction coefficient */ - fac_real = Ruu_real[1] / Ruu_real[0]; - fac_imag = Ruu_imag[1] / Ruu_real[0]; - } - else - { - fac_real = 0; - fac_imag = 0; - } - - /* 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 < CLDFB_NO_COL_MAX; j++ ) - { - comp_fac = 1 - abs_fac_powj; - rec_real[j] = prev_real[CLDFB_NO_COL_MAX - 1] * fac_powj_real - prev_imag[CLDFB_NO_COL_MAX - 1] * fac_powj_imag + - prev_real[j] * comp_fac; - rec_imag[j] = prev_real[CLDFB_NO_COL_MAX - 1] * fac_powj_imag + prev_imag[CLDFB_NO_COL_MAX - 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; - } - - /* prepare XF to next frame using prediction */ - fac_powj_real = fac_real; - fac_powj_imag = fac_imag; - abs_fac_powj = abs_fac; -#if CLDFB_PLC_XF > 0 - for ( j = 0; j < CLDFB_PLC_XF; j++ ) - { - xf_bet[j] = 1 - abs_fac_powj; - rec_real[j + CLDFB_NO_COL_MAX] = rec_real[CLDFB_NO_COL_MAX - 1] * fac_powj_real - rec_imag[CLDFB_NO_COL_MAX - 1] * fac_powj_imag; - rec_imag[j + CLDFB_NO_COL_MAX] = rec_real[CLDFB_NO_COL_MAX - 1] * fac_powj_imag + rec_imag[CLDFB_NO_COL_MAX - 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; - } -#endif - } - } - else - { - for ( j = 0; j < CLDFB_NO_COL_MAX; j++ ) - { - rec_real[j] = prev_real[j]; - rec_imag[j] = prev_imag[j]; - } -#if CLDFB_PLC_XF > 0 - for ( j = 0; j < CLDFB_PLC_XF; j++ ) - { - xf_bet[j] = 1; - rec_real[j + CLDFB_NO_COL_MAX] = 0; - rec_imag[j + CLDFB_NO_COL_MAX] = 0; - } -#endif - } - - return; -} - - -/*------------------------------------------------------------------------- - * Function ivas_splitBinRendPLCOpen() - * - * - *------------------------------------------------------------------------*/ - -ivas_error ivas_splitBinRendPLCOpen( - SPLIT_REND_PLC_HANDLE *phSplitRendPLC ) -{ - ivas_error error; - SPLIT_REND_PLC_HANDLE hSplitRendPLC; - - error = IVAS_ERR_OK; - if ( ( hSplitRendPLC = (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" ) ); - } - - hSplitRendPLC->prev_bfi = 0; - hSplitRendPLC->bf_count = 0; - 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 ); - *phSplitRendPLC = hSplitRendPLC; - - return error; -} - - -/*------------------------------------------------------------------------- - * Function ivas_splitBinRendPLCClose() - * - * - *------------------------------------------------------------------------*/ - -void ivas_splitBinRendPLCClose( - SPLIT_REND_PLC_HANDLE *phSplitRendPLC ) -{ - if ( ( *phSplitRendPLC ) != NULL ) - { - free( ( *phSplitRendPLC ) ); - ( *phSplitRendPLC ) = NULL; - } - - return; -} - - -/*------------------------------------------------------------------------- - * Function ivas_splitBinRendPLCsaveState() - * - * - *------------------------------------------------------------------------*/ - -void ivas_splitBinRendPLCsaveState( - 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 ) -{ - int16_t k, n; - - /* Save Cldfb frame */ - for ( k = 0; k < CLDFB_NO_COL_MAX; k++ ) - { - 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 ); - } - } - - return; -} - - -/*------------------------------------------------------------------------- - * Function ivas_splitBinRendPLC_xf() - * - * Cross-fade of preceding bad frame into good frame - *------------------------------------------------------------------------*/ - -void ivas_splitBinRendPLC_xf( - 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 ) -{ - int16_t n, i, k; - - /* Indicate that next transition will be from a good frame */ - hSplitRendPLC->prev_bfi = 0; - - /* Reset bf conter */ - hSplitRendPLC->bf_count = 0; - - - /* Do the cross fade */ - for ( n = 0; n < num_chs; n++ ) - { - for ( i = 0; i < CLDFB_NO_CHANNELS_MAX; i++ ) - { -#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 + CLDFB_NO_COL_MAX][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 + CLDFB_NO_COL_MAX][i]; - } -#endif - } - } - - return; -} - - -/*------------------------------------------------------------------------- - * Function ivas_splitBinRendPLC() - * - * Conceal bad frame - *------------------------------------------------------------------------*/ - -void ivas_splitBinRendPLC( - 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 ) -{ - 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]; -#if CLDFB_PLC_XF > 0 - float xf_alp[CLDFB_PLC_XF]; -#endif - - /* Indicate that next transition will be from a bad frame */ - hSplitRendPLC->prev_bfi = 1; - - -#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 ); - } -#endif - - for ( n = 0; n < num_chs; n++ ) - { - for ( i = 0; i < CLDFB_NO_CHANNELS_MAX; i++ ) - { - for ( k = 0; k < CLDFB_NO_COL_MAX; 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]; - } - - adaptive_polar_ext_plc( prev_real, prev_imag, rec_real, rec_imag -#if CLDFB_PLC_XF > 0 - , - xf_alp, hSplitRendPLC->CldfbPLC_state.xf_bet[n][i] -#endif - ); - - for ( k = 0; k < CLDFB_NO_COL_MAX; k++ ) - { - Cldfb_RealBuffer_Binaural[n][k][i] = rec_real[k]; - hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinReal[n][k][i] = rec_real[k]; - Cldfb_ImagBuffer_Binaural[n][k][i] = rec_imag[k]; - hSplitRendPLC->CldfbPLC_state.Cldfb_Prev_BinImag[n][k][i] = rec_imag[k]; - } - -#if CLDFB_PLC_XF > 0 - for ( k = CLDFB_NO_COL_MAX; k < CLDFB_NO_COL_MAX + 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]; - } -#endif - } - } - - - /* Check bf counter */ - if ( hSplitRendPLC->bf_count++ >= SR_PLC_FADE_START ) - { - if ( hSplitRendPLC->bf_count < SR_PLC_MUTE ) - { - fade_fac = powf( 10, ( hSplitRendPLC->bf_count - SR_PLC_FADE_START ) * SR_PLC_FADE_DEGREE / 20.0f ); - v_multc( &Cldfb_RealBuffer_Binaural[0][0][0], fade_fac, &Cldfb_RealBuffer_Binaural[0][0][0], (int16_t) ( (CLDFB_NO_COL_MAX) *num_chs * CLDFB_NO_CHANNELS_MAX ) ); - v_multc( &Cldfb_ImagBuffer_Binaural[0][0][0], fade_fac, &Cldfb_ImagBuffer_Binaural[0][0][0], (int16_t) ( (CLDFB_NO_COL_MAX) *num_chs * CLDFB_NO_CHANNELS_MAX ) ); - } - else - { - set_zero( &Cldfb_RealBuffer_Binaural[0][0][0], (int16_t) ( (CLDFB_NO_COL_MAX) *num_chs * CLDFB_NO_CHANNELS_MAX ) ); - set_zero( &Cldfb_ImagBuffer_Binaural[0][0][0], (int16_t) ( (CLDFB_NO_COL_MAX) *num_chs * CLDFB_NO_CHANNELS_MAX ) ); - hSplitRendPLC->bf_count = SR_PLC_MUTE; - } - } - - return; -} - -#endif diff --git a/lib_rend/ivas_splitRendererPost.c b/lib_rend/ivas_splitRendererPost.c deleted file mode 100644 index 8eb542892..000000000 --- a/lib_rend/ivas_splitRendererPost.c +++ /dev/null @@ -1,1799 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2023 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. - -*******************************************************************************************************/ - -#include -#include "options.h" -#ifdef SPLIT_REND_WITH_HEAD_ROT -#include -#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG -#include -#endif -#include "ivas_prot.h" -#include "prot.h" -#include "ivas_rom_dec.h" -#include "ivas_prot_rend.h" -#ifdef DEBUGGING -#include "debug.h" -#endif -#include "wmc_auto.h" - - -/*------------------------------------------------------------------------- - * ivas_splitBinPostRendOpen() - * - * - *------------------------------------------------------------------------*/ - -ivas_error ivas_splitBinPostRendOpen( - BIN_HR_SPLIT_POST_REND_HANDLE *hBinHrSplitPostRend, - MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, - const int32_t output_Fs ) -{ - BIN_HR_SPLIT_POST_REND_HANDLE hBinRend; - ivas_error error; - int16_t ch; - - if ( ( hBinRend = (BIN_HR_SPLIT_POST_REND_HANDLE) malloc( sizeof( 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++ ) - { - hBinRend->cldfbSyn[ch] = NULL; - hBinRend->cldfbAna[ch] = NULL; - } -#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG - for ( int16_t i = 0; i < MAX_HEAD_ROT_POSES; i++ ) - { - for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) - { - hBinRend->cldfbSynReconsBinDec[i][ch] = NULL; - } - } -#endif - - for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) - { - if ( ( error = openCldfb( &( 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 ) - { - return error; - } - } - -#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG - for ( int16_t i = 0; i < MAX_HEAD_ROT_POSES; i++ ) - { - for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) - { - if ( ( error = openCldfb( &( hBinRend->cldfbSynReconsBinDec[i][ch] ), CLDFB_SYNTHESIS, output_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) - { - return error; - } - } - } -#endif - hBinRend->cf_flag = 0; - set_fix_rotation_mat( hBinRend->fix_pos_rot_mat, pMultiBinPoseData ); - set_pose_types( hBinRend->pose_type, pMultiBinPoseData ); - ivas_split_rend_init_huff_cfg( &hBinRend->huff_cfg ); - *hBinHrSplitPostRend = hBinRend; - - return IVAS_ERR_OK; -} - - -/*------------------------------------------------------------------------- - * ivas_splitBinPostRendClose() - * - * - *------------------------------------------------------------------------*/ - -void ivas_splitBinPostRendClose( - BIN_HR_SPLIT_POST_REND_HANDLE *hBinHrSplitPostRend ) -{ - int16_t ch; - - if ( ( *hBinHrSplitPostRend ) != NULL ) - { - for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) - { - if ( ( *hBinHrSplitPostRend )->cldfbSyn[ch] != NULL ) - { - deleteCldfb( &( ( *hBinHrSplitPostRend )->cldfbSyn[ch] ) ); - ( *hBinHrSplitPostRend )->cldfbSyn[ch] = NULL; - } - if ( ( *hBinHrSplitPostRend )->cldfbAna[ch] != NULL ) - { - deleteCldfb( &( ( *hBinHrSplitPostRend )->cldfbAna[ch] ) ); - ( *hBinHrSplitPostRend )->cldfbAna[ch] = NULL; - } - } -#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG - for ( int16_t i = 0; i < MAX_HEAD_ROT_POSES; i++ ) - { - for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) - { - if ( ( *hBinHrSplitPostRend )->cldfbSynReconsBinDec[i][ch] != NULL ) - { - deleteCldfb( &( ( *hBinHrSplitPostRend )->cldfbSynReconsBinDec[i][ch] ) ); - ( *hBinHrSplitPostRend )->cldfbSynReconsBinDec[i][ch] = NULL; - } - } - } -#endif - - free( ( *hBinHrSplitPostRend ) ); - ( *hBinHrSplitPostRend ) = NULL; - } - - return; -} - - -/*-----------------------------------------------------------------------------------------* - * Function ivas_huffman_code_bits_present() - * - * Huffman code bits present - *-----------------------------------------------------------------------------------------*/ - -static int32_t ivas_split_rend_huffman_code_bits_present( - const int32_t *codebook, - const int32_t code, - const int32_t bits, - const int16_t len ) -{ - int16_t index = len + 1; - int16_t i = 0; - int32_t code_t, ind_t, bits_t; - - while ( i < len ) - { - ind_t = codebook[0]; - bits_t = codebook[1]; - code_t = codebook[2]; - if ( ( code == code_t ) && ( bits == bits_t ) ) - { - return ind_t; - } - codebook = codebook + 3; - i++; - } - - return index; -} - - -/*-----------------------------------------------------------------------------------------* - * Function ivas_split_rend_huffman_decode_opt() - * - * - *-----------------------------------------------------------------------------------------*/ - -static int16_t ivas_split_rend_huffman_decode_opt( - ivas_split_rend_huffman_cfg_t *huff_cfg, - IVAS_SPLIT_REND_BITS_HANDLE pBits, - const int16_t *idx_trav_list ) -{ - int32_t i, ind, code, num_bits, code_b, num_bits_read; - const int32_t *codebook; - - codebook = huff_cfg->codebook; - num_bits_read = 0; - ind = huff_cfg->codebook[0] - 1; - code = 0; - for ( i = 0; i < huff_cfg->sym_len; i++ ) - { - codebook = codebook + idx_trav_list[i] * 3; - num_bits = codebook[1]; - code_b = codebook[2]; - num_bits_read = num_bits - num_bits_read; - code = code << num_bits_read; - if ( num_bits_read > 0 ) - { - code |= ivas_split_rend_bitstream_read_int32( pBits, num_bits_read ); - } - - if ( code == code_b ) - { - ind = codebook[0]; - break; - } - - num_bits_read = num_bits; - codebook = huff_cfg->codebook; - } - -#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG - assert( ind >= huff_cfg->codebook[0] ); -#endif - return (int16_t) ind; -} - -/*-----------------------------------------------------------------------------------------* - * Function ivas_split_rend_unquant_md() - * - * - *-----------------------------------------------------------------------------------------*/ - -static void ivas_split_rend_unquant_md( - BIN_HR_SPLIT_REND_MD_HANDLE hMd, - IVAS_SPLIT_REND_POSE_TYPE pose_type, - int16_t real_only, - float fix_pos_rot_mat[][BINAURAL_CHANNELS], - const float pred_quant_step ) -{ - int16_t ch1, ch2; - int16_t gd_idx_min; - - if ( pose_type == PRED_ONLY || pose_type == PRED_ROLL_ONLY ) - { - float quantstep; - - quantstep = pred_quant_step; - - for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) - { - 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]; - } - } - if ( real_only ) - { - for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) - { - for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) - { - hMd->pred_mat_im[ch1][ch2] = 0.0f; - } - } - } - else - { - for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) - { - for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) - { - hMd->pred_mat_im[ch1][ch2] = hMd->pred_mat_im_idx[ch1][ch2] * quantstep; - } - } - } - } - else if ( pose_type == COM_GAIN_ONLY ) - { - gd_idx_min = (int16_t) roundf( IVAS_SPLIT_REND_D_1BYQ_STEP * IVAS_SPLIT_REND_D_MIN_VAL ); - hMd->gd_idx += gd_idx_min; - hMd->gd = hMd->gd_idx * IVAS_SPLIT_REND_D_Q_STEP; - } - else if ( pose_type == LR_GAIN_ONLY ) - { - gd_idx_min = (int16_t) roundf( IVAS_SPLIT_REND_PITCH_G_1BYQ_STEP * IVAS_SPLIT_REND_PITCH_G_MIN_VAL ); - hMd->gd_idx += gd_idx_min; - hMd->gd = hMd->gd_idx * IVAS_SPLIT_REND_PITCH_G_Q_STEP; - - hMd->gd2_idx += gd_idx_min; - hMd->gd2 = hMd->gd2_idx * IVAS_SPLIT_REND_PITCH_G_Q_STEP; - } - else - { - hMd->gd = 0.0f; - } - - return; -} - - -/*-----------------------------------------------------------------------------------------* - * Function ivas_splitBinPostRendMdBase2Dec() - * - * - *-----------------------------------------------------------------------------------------*/ - -static void ivas_splitBinPostRendMdBase2Dec( - IVAS_SPLIT_REND_BITS_HANDLE pBits, - 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 ) -{ - 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; - BIN_HR_SPLIT_REND_MD_HANDLE hMd; - BIN_HR_SPLIT_REND_HUFF_HANDLE pHuff_cfg; - - pHuff_cfg = &hBinHrSplitPostRend->huff_cfg; - - if ( pred_quant_pnts_yaw == IVAS_SPLIT_REND_PRED_63QUANT_PNTS ) - { - pred_cb_idx = 1; - } - else - { - pred_cb_idx = 0; - } - 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]; - pred_code_len = pHuff_cfg->pred_base2_code_len[pred_cb_idx]; - pred_roll_code_len = pHuff_cfg->pred_roll_base2_code_len; - gd_code_len = pHuff_cfg->gd_base2_code_len; - p_gd_code_len = pHuff_cfg->p_gd_base2_code_len; - - for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) - { - for ( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses - 1; pos_idx++ ) - { - if ( hBinHrSplitPostRend->pose_type[pos_idx] == ANY_YAW ) - { - 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 ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) - { - code = (int16_t) ivas_split_rend_bitstream_read_int32( pBits, pred_code_len ); - hMd->pred_mat_re_idx[ch1][ch2] = code + min_pred_idx; - } - } - } - 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 ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) - { - code = (int16_t) ivas_split_rend_bitstream_read_int32( pBits, pred_code_len ); - hMd->pred_mat_im_idx[ch1][ch2] = code + min_pred_idx; - } - } - } - for ( b = 0; b < d_bands_yaw; b++ ) - { - hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; - code = (int16_t) ivas_split_rend_bitstream_read_int32( pBits, gd_code_len ); - hMd->gd_idx = code + min_gd_idx; - } - } - else if ( hBinHrSplitPostRend->pose_type[pos_idx] == PITCH_ONLY ) - { - for ( b = 0; b < bands_pitch; b++ ) - { - hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; - code = (int16_t) ivas_split_rend_bitstream_read_int32( pBits, p_gd_code_len ); - hMd->gd_idx = code + min_p_gd_idx; - code = (int16_t) ivas_split_rend_bitstream_read_int32( pBits, p_gd_code_len ); - hMd->gd2_idx = code + min_p_gd_idx; - } - } - else - { - 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 ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) - { - code = (int16_t) ivas_split_rend_bitstream_read_int32( pBits, pred_roll_code_len ); - hMd->pred_mat_re_idx[ch1][ch2] = code + min_pred_roll_idx; - } - } - } - 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 ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) - { - code = (int16_t) ivas_split_rend_bitstream_read_int32( pBits, pred_roll_code_len ); - hMd->pred_mat_im_idx[ch1][ch2] = code + min_pred_roll_idx; - } - } - } - } - } - } - - return; -} - - -/*-----------------------------------------------------------------------------------------* - * Function ivas_splitBinPostRendMdHuffDec() - * - * - *-----------------------------------------------------------------------------------------*/ - -static void ivas_splitBinPostRendMdHuffDec( - IVAS_SPLIT_REND_BITS_HANDLE pBits, - 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 ) -{ - 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; - BIN_HR_SPLIT_REND_MD_HANDLE hMd; - BIN_HR_SPLIT_REND_HUFF_HANDLE pHuff_cfg; - - pHuff_cfg = &hBinHrSplitPostRend->huff_cfg; - - if ( pred_quant_pnts_yaw == IVAS_SPLIT_REND_PRED_63QUANT_PNTS ) - { - pred_cb_idx = 1; - } - else - { - pred_cb_idx = 0; - } - 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[( IVAS_SPLIT_REND_ROLL_PRED_QUANT_PNTS - 1 ) * 3]; - - for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) - { - for ( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses - 1; pos_idx++ ) - { - if ( hBinHrSplitPostRend->pose_type[pos_idx] == ANY_YAW ) - { - 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 ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) - { - 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] ); - // sym_adj_idx[ch1][ch2] = ivas_split_rend_huffman_decode( &pHuff_cfg->pred, pBits ); - } - } - ivas_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++ ) - { - hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; - for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) - { - for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) - { - 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] ); - // sym_adj_idx[ch1][ch2] = ivas_split_rend_huffman_decode( &pHuff_cfg->pred, pBits ); - } - } - ivas_SplitRenderer_getdiagdiff( sym_adj_idx, hMd->pred_mat_im_idx, -1, min_pred_idx, max_pred_idx ); - } - for ( b = 0; b < d_bands_yaw; b++ ) - { - hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; - 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 ) - { - for ( b = 0; b < bands_pitch; b++ ) - { - hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; - 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 = ivas_split_rend_huffman_decode_opt( &pHuff_cfg->p_gd, pBits, pHuff_cfg->p_gd_idx_trav ); - } - } - else - { - 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 ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) - { - sym_adj_idx[ch1][ch2] = ivas_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( &pHuff_cfg->pred_roll, pBits ); - } - } - ivas_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++ ) - { - hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; - for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) - { - for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) - { - sym_adj_idx[ch1][ch2] = ivas_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( &pHuff_cfg->pred_roll, pBits ); - } - } - ivas_SplitRenderer_getdiagdiff( sym_adj_idx, hMd->pred_mat_im_idx, -1, min_pred_roll_idx, max_pred_roll_idx ); - } - } - } - } - - return; -} - - -/*-----------------------------------------------------------------------------------------* - * Function ivas_splitBinPostRendMdDec() - * - * - *-----------------------------------------------------------------------------------------*/ - -void ivas_splitBinPostRendMdDec( - IVAS_SPLIT_REND_BITS_HANDLE pBits, - BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend, - MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData -#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG - , - BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend -#endif -) -{ - int16_t pos_idx, b, sf_idx, num_subframes, ch1; - int16_t pred_real_bands_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], pred_real_bands_roll[IVAS_SPLIT_REND_NUM_QUANT_STRATS]; - int16_t pred_imag_bands_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], pred_imag_bands_roll[IVAS_SPLIT_REND_NUM_QUANT_STRATS]; - int16_t d_bands_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], bands_pitch[IVAS_SPLIT_REND_NUM_QUANT_STRATS]; - int16_t num_complex_bands, num_quant_strats; - int32_t quant_strat_bits, is_huff_coding, quant_strat; - int16_t pred_quant_pnts_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS]; - float pred_1byquantstep_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS]; - float pred_quantstep_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS]; -#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG - int16_t ch1, ch2; -#endif - BIN_HR_SPLIT_REND_MD_HANDLE hMd; - IVAS_SPLIT_REND_CONFIG_DATA split_rend_config; - IVAS_SPLIT_REND_ROT_AXIS rot_axis; - - hBinHrSplitPostRend->low_Res = 1; - - split_rend_config.dof = (int16_t) ivas_split_rend_bitstream_read_int32( pBits, IVAS_SPLIT_REND_DOF_BITS ); - split_rend_config.hq_mode = (int16_t) ivas_split_rend_bitstream_read_int32( pBits, IVAS_SPLIT_REND_HQ_MODE_BITS ); - rot_axis = (IVAS_SPLIT_REND_ROT_AXIS) ivas_split_rend_bitstream_read_int32( pBits, IVAS_SPLIT_REND_ROT_AXIS_BITS ); - - ivas_renderSplitGetMultiBinPoseData( &split_rend_config, pMultiBinPoseData, rot_axis ); - - set_fix_rotation_mat( hBinHrSplitPostRend->fix_pos_rot_mat, pMultiBinPoseData ); - set_pose_types( 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++ ) - { - int16_t angle; - - hBinHrSplitPostRend->QuaternionsPre[sf_idx].w = -3.0f; - - angle = (int16_t) ivas_split_rend_bitstream_read_int32( pBits, IVAS_SPLIT_REND_HEAD_POSE_BITS ); - angle -= 180; - hBinHrSplitPostRend->QuaternionsPre[sf_idx].x = (float) angle; - - angle = (int16_t) ivas_split_rend_bitstream_read_int32( pBits, IVAS_SPLIT_REND_HEAD_POSE_BITS ); - angle -= 180; - hBinHrSplitPostRend->QuaternionsPre[sf_idx].y = (float) angle; - - angle = (int16_t) ivas_split_rend_bitstream_read_int32( pBits, IVAS_SPLIT_REND_HEAD_POSE_BITS ); - angle -= 180; - hBinHrSplitPostRend->QuaternionsPre[sf_idx].z = (float) angle; - } - - ivas_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 ); - - quant_strat_bits = (int32_t) ceilf( log2f( num_quant_strats ) ); - is_huff_coding = ivas_split_rend_bitstream_read_int32( pBits, 1 ); - quant_strat = ivas_split_rend_bitstream_read_int32( pBits, quant_strat_bits ); - - if ( is_huff_coding == 0 ) - { - ivas_splitBinPostRendMdBase2Dec( - pBits, hBinHrSplitPostRend, - pMultiBinPoseData, - num_subframes, - pred_real_bands_yaw[quant_strat], - pred_imag_bands_yaw[quant_strat], - pred_quant_pnts_yaw[quant_strat], - d_bands_yaw[quant_strat], - bands_pitch[quant_strat], - pred_real_bands_roll[quant_strat], - pred_imag_bands_roll[quant_strat] ); - } - else - { - ivas_splitBinPostRendMdHuffDec( - pBits, hBinHrSplitPostRend, - pMultiBinPoseData, - num_subframes, - pred_real_bands_yaw[quant_strat], - pred_imag_bands_yaw[quant_strat], - pred_quant_pnts_yaw[quant_strat], - d_bands_yaw[quant_strat], - bands_pitch[quant_strat], - pred_real_bands_roll[quant_strat], - pred_imag_bands_roll[quant_strat] ); - } -#ifdef SPLIT_MD_CODING_DEBUG - for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) - { - int16_t val, ch2, val_ref; - char filename[200] = "split_md_debug_indices.bin"; - for ( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses - 1; pos_idx++ ) - { - if ( hBinHrSplitPostRend->pose_type[pos_idx] == ANY_YAW ) - { - for ( b = 0; b < pred_real_bands_yaw[quant_strat]; b++ ) - { - for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) - { - for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) - { - val = hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b].pred_mat_re_idx[ch1][ch2]; - dbgread( &val_ref, sizeof( int16_t ), 1, filename ); - if ( abs( val_ref - val ) > 0 ) - { - assert( 0 ); - } - } - } - } - for ( b = 0; b < pred_imag_bands_yaw[quant_strat]; b++ ) - { - for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) - { - for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) - { - val = hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b].pred_mat_im_idx[ch1][ch2]; - dbgread( &val_ref, sizeof( int16_t ), 1, filename ); - if ( abs( val_ref - val ) > 0 ) - { - assert( 0 ); - } - } - } - } - for ( b = 0; b < d_bands_yaw[quant_strat]; b++ ) - { - val = hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b].gd_idx; - dbgread( &val_ref, sizeof( int16_t ), 1, filename ); - if ( abs( val_ref - val ) > 0 ) - { - assert( 0 ); - } - } - } - else if ( hBinHrSplitPostRend->pose_type[pos_idx] == PITCH_ONLY ) - { - for ( b = 0; b < bands_pitch[quant_strat]; b++ ) - { - val = hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b].gd_idx; - dbgread( &val_ref, sizeof( int16_t ), 1, filename ); - if ( abs( val_ref - val ) > 0 ) - { - assert( 0 ); - } - val = hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b].gd2_idx; - dbgread( &val_ref, sizeof( int16_t ), 1, filename ); - if ( abs( val_ref - val ) > 0 ) - { - assert( 0 ); - } - } - } - else - { - for ( b = 0; b < pred_real_bands_roll[quant_strat]; b++ ) - { - for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) - { - for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) - { - val = hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b].pred_mat_re_idx[ch1][ch2]; - dbgread( &val_ref, sizeof( int16_t ), 1, filename ); - if ( abs( val_ref - val ) > 0 ) - { - assert( 0 ); - } - } - } - } - for ( b = 0; b < pred_imag_bands_roll[quant_strat]; b++ ) - { - for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) - { - for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) - { - val = hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b].pred_mat_im_idx[ch1][ch2]; - dbgread( &val_ref, sizeof( int16_t ), 1, filename ); - if ( abs( val_ref - val ) > 0 ) - { - assert( 0 ); - } - } - } - } - } - } - } -#endif - - for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) - { - for ( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses - 1; pos_idx++ ) - { - if ( hBinHrSplitPostRend->pose_type[pos_idx] == ANY_YAW ) - { - for ( b = 0; b < pred_imag_bands_yaw[quant_strat]; b++ ) - { - hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; - ivas_split_rend_unquant_md( hMd, PRED_ONLY, 0, hBinHrSplitPostRend->fix_pos_rot_mat[pos_idx], pred_quantstep_yaw[quant_strat] ); - } - for ( ; b < pred_real_bands_yaw[quant_strat]; b++ ) - { - hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; - ivas_split_rend_unquant_md( hMd, PRED_ONLY, 1, hBinHrSplitPostRend->fix_pos_rot_mat[pos_idx], pred_quantstep_yaw[quant_strat] ); - } - for ( ; b < MAX_SPLIT_REND_MD_BANDS; b++ ) - { - hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; - 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; - } - } - for ( b = 0; b < d_bands_yaw[quant_strat]; b++ ) - { - hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; - ivas_split_rend_unquant_md( hMd, COM_GAIN_ONLY, 1, hBinHrSplitPostRend->fix_pos_rot_mat[pos_idx], 0 ); - } - for ( ; b < MAX_SPLIT_REND_MD_BANDS; b++ ) - { - hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; - hMd->gd = 0.0f; - } - } - else if ( hBinHrSplitPostRend->pose_type[pos_idx] == PITCH_ONLY ) - { - for ( b = 0; b < bands_pitch[quant_strat]; b++ ) - { - hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; - ivas_split_rend_unquant_md( hMd, LR_GAIN_ONLY, 1, hBinHrSplitPostRend->fix_pos_rot_mat[pos_idx], 0 ); - } - 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; - } - } - else - { - for ( b = 0; b < pred_imag_bands_roll[quant_strat]; b++ ) - { - hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; - ivas_split_rend_unquant_md( hMd, PRED_ROLL_ONLY, 0, hBinHrSplitPostRend->fix_pos_rot_mat[pos_idx], IVAS_SPLIT_REND_PRED_ROLL_Q_STEP ); - } - for ( ; b < pred_real_bands_roll[quant_strat]; b++ ) - { - hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; - ivas_split_rend_unquant_md( hMd, PRED_ROLL_ONLY, 1, hBinHrSplitPostRend->fix_pos_rot_mat[pos_idx], IVAS_SPLIT_REND_PRED_ROLL_Q_STEP ); - } - for ( ; b < MAX_SPLIT_REND_MD_BANDS; b++ ) - { - hMd = &hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; - 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; - } - } - } - } - } - -#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG - for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) - { - float val; - for ( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses - 1; pos_idx++ ) - { - if ( hBinHrSplitPostRend->pose_type[pos_idx] == ANY_YAW ) - { - for ( b = 0; b < pred_real_bands_yaw[quant_strat]; b++ ) - { - for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) - { - for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) - { - val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_re_idx[ch1][ch2]; - if ( fabsf( hMd->pred_mat_re_idx[ch1][ch2] - val ) > 1e-20 ) - { - assert( 0 ); - } - } - } - } - for ( b = 0; b < pred_imag_bands_yaw[quant_strat]; b++ ) - { - for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) - { - for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) - { - val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_im_idx[ch1][ch2]; - if ( fabsf( hMd->pred_mat_im_idx[ch1][ch2] - val ) > 1e-20 ) - { - assert( 0 ); - } - } - } - } - for ( b = 0; b < d_bands_yaw[quant_strat]; b++ ) - { - val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd_idx; - if ( fabsf( hMd->gd_idx - val ) > 1e-20 ) - { - assert( 0 ); - } - } - } - else if ( hBinHrSplitPostRend->pose_type[pos_idx] == PITCH_ONLY ) - { - for ( b = 0; b < bands_pitch[quant_strat]; b++ ) - { - val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd_idx; - if ( fabsf( hMd->gd_idx - val ) > 1e-20 ) - { - assert( 0 ); - } - val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd2_idx; - if ( fabsf( hMd->gd2_idx - val ) > 1e-20 ) - { - assert( 0 ); - } - } - } - else - { - for ( b = 0; b < pred_real_bands_roll[quant_strat]; b++ ) - { - for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) - { - for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) - { - val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_re_idx[ch1][ch2]; - if ( fabsf( hMd->pred_mat_re_idx[ch1][ch2] - val ) > 1e-20 ) - { - assert( 0 ); - } - } - } - } - for ( b = 0; b < pred_imag_bands_roll[quant_strat]; b++ ) - { - for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) - { - for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) - { - val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_im_idx[ch1][ch2]; - if ( fabsf( hMd->pred_mat_im_idx[ch1][ch2] - val ) > 1e-20 ) - { - assert( 0 ); - } - } - } - } - } - } - } -#endif - - return; -} - - -/*-----------------------------------------------------------------------------------------* - * Function wrap_around_angle() - * - * - *-----------------------------------------------------------------------------------------*/ - -static void wrap_around_angle( - float *a ) -{ - if ( ( *a ) > 180.0f ) - { - ( *a ) = ( *a ) - 360; - } - else if ( ( *a ) < -180.0f ) - { - ( *a ) = ( *a ) + 360; - } - return; -} - - -/*-----------------------------------------------------------------------------------------* - * Function wrap_around_angle() - * - * - *-----------------------------------------------------------------------------------------*/ - -static void wrap_around_ypr( - IVAS_QUATERNION *Quaternions ) -{ - /*only if quat is actually yaw, pitch , roll angles*/ - if ( Quaternions->w == -3.0f ) - { - wrap_around_angle( &Quaternions->x ); - wrap_around_angle( &Quaternions->y ); - wrap_around_angle( &Quaternions->z ); - } - 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] ) -{ - float n, d, interp_fact; - - if ( 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 ) - { - 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; - } - } - else - { - interp_fact = 0.0f; - } - - return interp_fact; -} - - -/*-----------------------------------------------------------------------------------------* - * 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 ) -{ - float min_diff, diff; - int16_t pos_idx; - - ind[0] = 0; - ind[1] = 0; - min_diff = 360.0f; - - /*find the closest pose from assumed poses*/ - for ( pos_idx = 0; pos_idx < num_poses; pos_idx++ ) - { - diff = fabsf( p_t - p[pos_idx] ); - if ( diff < min_diff ) - { - ind[0] = pos_idx; - min_diff = (float) diff; - } - } - - min_diff = 360.0; - 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 ) ) - { - ind[1] = pos_idx; - min_diff = (float) diff; - } - } - - return; -} - - -/*-----------------------------------------------------------------------------------------* - * Function get_interpolation_vars() - * - * - *-----------------------------------------------------------------------------------------*/ - -static void get_interpolation_vars( - MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, - const IVAS_QUATERNION *Quaternions_ref, - const IVAS_QUATERNION *Quaternions_act, - 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 ) -{ - 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]; - int16_t pos_idx, num_poses; - - quaternions_diff.x = 0.0f; - quaternions_diff.y = 0.0f; - quaternions_diff.z = 0.0f; - - num_poses = pMultiBinPoseData->num_poses; - 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; - } - - /*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 ); - - interp_yaw_pose_idx[0] = 0; - interp_yaw_pose_idx[1] = 0; - if ( fabs( quaternions_diff.x ) > EPSILON ) - { - get_nearest_pose_ind( y, quaternions_diff.x, interp_yaw_pose_idx, num_poses ); - } - *interp_yaw_fact = get_interp_fact( y, quaternions_diff.x, interp_yaw_pose_idx ); - - interp_pitch_pose_idx[0] = 0; - interp_pitch_pose_idx[1] = 0; - if ( fabs( quaternions_diff.y ) > EPSILON ) - { - get_nearest_pose_ind( p, quaternions_diff.y, interp_pitch_pose_idx, num_poses ); - } - *interp_pitch_fact = get_interp_fact( p, quaternions_diff.y, interp_pitch_pose_idx ); - - interp_roll_pose_idx[0] = 0; - interp_roll_pose_idx[1] = 0; - if ( fabs( quaternions_diff.z ) > EPSILON ) - { - get_nearest_pose_ind( r, quaternions_diff.z, interp_roll_pose_idx, num_poses ); - } - *interp_roll_fact = get_interp_fact( r, quaternions_diff.z, interp_roll_pose_idx ); - - return; -} - - -/*-----------------------------------------------------------------------------------------* - * Function interpolate_gain_matrix() - * - * - *-----------------------------------------------------------------------------------------*/ - -static void interpolate_gain_matrix( - 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 gain[BINAURAL_CHANNELS] ) -{ - float gd1, gd2, gd3, gd4, diff; - - gd1 = 1.0f; - gd2 = 1.0f; - gd3 = 1.0f; - gd4 = 1.0f; - if ( ind[0] != 0 ) - { - gd1 = rot_md[ind[0] - 1][sf_idx][band_idx].gd; - gd3 = rot_md[ind[0] - 1][sf_idx][band_idx].gd2; - } - if ( ind[1] != 0 ) - { - gd2 = rot_md[ind[1] - 1][sf_idx][band_idx].gd; - gd4 = rot_md[ind[1] - 1][sf_idx][band_idx].gd2; - } -#if 0 - diff = gd1 / gd2; - pitch_gain_l = gd2 * powf( diff, 1.0f - interp_pitch_fact ); - pitch_gain_l = max( 0.0f, pitch_gain_l ); - - diff = gd3 / gd4; - pitch_gain_r = gd4 * powf( diff, 1.0f - interp_pitch_fact ); - pitch_gain_r = max( 0.0f, pitch_gain_r ); -#else - diff = gd1 - gd2; - gain[0] = gd1 - ( diff * interp_fact ); - gain[0] = max( 0.0f, gain[0] ); - - diff = gd3 - gd4; - gain[1] = gd3 - ( diff * interp_fact ); - gain[1] = max( 0.0f, gain[1] ); -#endif - - return; -} - - -/*-----------------------------------------------------------------------------------------* - * Function interpolate_pred_matrix() - * - * - *-----------------------------------------------------------------------------------------*/ - -static void interpolate_pred_matrix( - 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] ) -{ - int16_t ch_idx1, ch_idx2; - float diff; - 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++ ) - { - 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; - - 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; - } - - 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_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]; - } - } - } - - 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_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]; - } - } - } - - for ( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) - { - 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 ); - - 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 ); - } - } - - return; -} - - -/*-----------------------------------------------------------------------------------------* - * Function interpolate_rend_md() - * - * - *-----------------------------------------------------------------------------------------*/ - -static void interpolate_rend_md( - 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 ) -{ - 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; - - gd1 = 0.0f; - gd2 = 0.0f; - - idx1 = interp_yaw_pose_idx[0]; - idx2 = interp_yaw_pose_idx[1]; - if ( ( idx1 != 0 ) || ( idx2 != 0 ) ) - { - interpolate_pred_matrix( rot_md, sf_idx, band_idx, interp_yaw_pose_idx, interp_yaw_fact, mix_mat_re, mix_mat_im ); - - if ( idx1 != 0 ) - { - gd1 = rot_md[idx1 - 1][sf_idx][band_idx].gd; - } - - if ( idx2 != 0 ) - { - gd2 = rot_md[idx2 - 1][sf_idx][band_idx].gd; - } - - diff = gd1 - gd2; - *gd_int = gd1 - ( diff * interp_yaw_fact ); - } - else - { - /*P = P'*/ - 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; - } - *gd_int = 0.0f; - } - - idx1 = interp_pitch_pose_idx[0]; - idx2 = interp_pitch_pose_idx[1]; - if ( ( idx1 != 0 ) || ( idx2 != 0 ) ) - { - gd1 = 1.0f; - gd2 = 1.0f; - - gd3 = 1.0f; - gd4 = 1.0f; - - if ( idx1 != 0 ) - { - gd1 = rot_md[idx1 - 1][sf_idx][band_idx].gd; - gd3 = rot_md[idx1 - 1][sf_idx][band_idx].gd2; - } - if ( idx2 != 0 ) - { - gd2 = rot_md[idx2 - 1][sf_idx][band_idx].gd; - gd4 = rot_md[idx2 - 1][sf_idx][band_idx].gd2; - } -#if 0 - diff = gd1 / gd2; - pitch_gain_l = gd2 * powf( diff, 1.0f - interp_pitch_fact ); - pitch_gain_l = max( 0.0f, pitch_gain_l ); - - diff = gd3 / gd4; - pitch_gain_r = gd4 * powf( diff, 1.0f - interp_pitch_fact ); - pitch_gain_r = max( 0.0f, pitch_gain_r ); -#else - 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 ); -#endif - - for ( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) - { - 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; - } - } - else - { - pitch_gain_l = 1.0f; - pitch_gain_r = 1.0f; - } - - idx1 = interp_roll_pose_idx[0]; - idx2 = interp_roll_pose_idx[1]; - if ( ( idx1 != 0 ) || ( idx2 != 0 ) ) - { - interpolate_pred_matrix( rot_md, sf_idx, band_idx, interp_roll_pose_idx, interp_roll_fact, mix_mat_re3, mix_mat_im3 ); - - ivas_mat_mult_2by2_complex( mix_mat_re, mix_mat_im, mix_mat_re3, mix_mat_im3, mix_mat_re1, mix_mat_im1 ); - - for ( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) - { - 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]; - } - } - } - - return; -} - - -/*-----------------------------------------------------------------------------------------* - * Function ivas_SplitRenderer_PostRenderer() - * - * - *-----------------------------------------------------------------------------------------*/ - -void ivas_SplitRenderer_PostRenderer( - 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 */ - const IVAS_QUATERNION Quaternion_act ) -{ - int16_t pos_idx, b, brange[2], ch_idx1; - int16_t num_md_bands, slot_idx, b2, index_slot, num_slots, sf_idx_md; - float pred_out_re[BINAURAL_CHANNELS], pred_out_im[BINAURAL_CHANNELS], tmp_re, tmp_im, gd_int; -#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG - BIN_HR_SPLIT_REND_MD rot_md_act[MAX_HEAD_ROT_POSES][MAX_SPLIT_REND_MD_BANDS]; -#else - 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]; -#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]; - const int16_t *pBand_grouping = ivas_split_rend_band_grouping; - - num_md_bands = MAX_SPLIT_REND_MD_BANDS; - - push_wmops( "ivas_SplitRenderer_PostRenderer" ); - - num_slots = MAX_PARAM_SPATIAL_SUBFRAMES; -#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG - pos_idx = MAX_HEAD_ROT_POSES - 1; -#else - pos_idx = 0; -#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++ ) - { - 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; - } - 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++ ) - { - /*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; - } - } - - -#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG - for ( pos_idx = 0; pos_idx < MAX_HEAD_ROT_POSES - 1; pos_idx++ ) - { - for ( b = 0; b < num_md_bands; b++ ) - { - if ( hBinPostRenderer->pose_type[pos_idx] == PITCH_ONLY ) - { - - for ( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) - { - set_zero( hBinPostRenderer->rot_md[pos_idx][sf_idx][b].pred_mat_re[ch_idx1], BINAURAL_CHANNELS ); - set_zero( hBinPostRenderer->rot_md[pos_idx][sf_idx][b].pred_mat_im[ch_idx1], BINAURAL_CHANNELS ); - hBinPostRenderer->rot_md[pos_idx][sf_idx][b].pred_mat_re[ch_idx1][ch_idx1] = 1.0f; - } - hBinPostRenderer->rot_md[pos_idx][sf_idx][b].pred_mat_re[0][0] *= hBinPostRenderer->rot_md[pos_idx][sf_idx][b].gd; - hBinPostRenderer->rot_md[pos_idx][sf_idx][b].pred_mat_re[1][1] *= hBinPostRenderer->rot_md[pos_idx][sf_idx][b].gd2; - hBinPostRenderer->rot_md[pos_idx][sf_idx][b].gd = 0.0f; - } - else if ( hBinPostRenderer->pose_type[pos_idx] == ANY_ROLL ) - { - hBinPostRenderer->rot_md[pos_idx][sf_idx][b].gd = 0.0f; - } - - 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] = hBinPostRenderer->rot_md[pos_idx][sf_idx][b].pred_mat_re[ch_idx1][0]; - rot_md_act[pos_idx][b].pred_mat_re[ch_idx1][1] = hBinPostRenderer->rot_md[pos_idx][sf_idx][b].pred_mat_re[ch_idx1][1]; - rot_md_act[pos_idx][b].pred_mat_im[ch_idx1][0] = hBinPostRenderer->rot_md[pos_idx][sf_idx][b].pred_mat_im[ch_idx1][0]; - rot_md_act[pos_idx][b].pred_mat_im[ch_idx1][1] = hBinPostRenderer->rot_md[pos_idx][sf_idx][b].pred_mat_im[ch_idx1][1]; - rot_md_act[pos_idx][b].gd = hBinPostRenderer->rot_md[pos_idx][sf_idx][b].gd; - } - } - } - -#endif - -#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG - for ( pos_idx = 0; pos_idx < MAX_HEAD_ROT_POSES; pos_idx++ ) -#else - pos_idx = 0; -#endif - { - for ( slot_idx = 0; slot_idx < num_slots; slot_idx++ ) - { - index_slot = slot_idx; /* TODO: can be cleaned up */ - fade = ( (float) slot_idx + 1.0f ) / MAX_PARAM_SPATIAL_SUBFRAMES; - fade = min( fade, 1.0f ); - for ( b = 0; b < num_md_bands; b++ ) - { - for ( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) - { - 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]; - } - 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]; - } - } - - brange[0] = pBand_grouping[b]; - brange[1] = pBand_grouping[b + 1]; - for ( b2 = brange[0]; b2 < brange[1]; b2++ ) - { - for ( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) - { - /* Apply prediction matrix */ - IVAS_CMULT_FLOAT( Cldfb_RealBuffer_Ref_Binaural[0][index_slot][b2], - Cldfb_ImagBuffer_Ref_Binaural[0][index_slot][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][index_slot][b2], - Cldfb_ImagBuffer_Ref_Binaural[1][index_slot][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; - } - - - 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][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][index_slot][b2] = pred_out_re[ch_idx1]; - Cldfb_ImagBuffer_Ref_Binaural[ch_idx1][index_slot][b2] = pred_out_im[ch_idx1]; -#endif - } - } - } - } - } - -#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG - for ( pos_idx = 0; pos_idx < MAX_HEAD_ROT_POSES; pos_idx++ ) -#else - pos_idx = 0; -#endif - { - for ( b = 0; b < num_md_bands; b++ ) - { - 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->gd_mem[pos_idx][b] = rot_md_act[pos_idx][b].gd; - } - } - hBinPostRenderer->cf_flag = 1; - -#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG - { - int16_t num_cldfb_bands; - num_cldfb_bands = CLDFB_NO_CHANNELS_MAX; - for ( slot_idx = 0; slot_idx < num_slots; slot_idx++ ) - { - index_slot = sf_idx * num_slots + slot_idx; - for ( ch_idx1 = 0; ch_idx1 < BINAURAL_CHANNELS; ch_idx1++ ) - { - mvr2r( Cldfb_RealBuffer_Recons_Binaural[MAX_HEAD_ROT_POSES - 1][ch_idx1][index_slot], Cldfb_RealBuffer_Ref_Binaural[ch_idx1][index_slot], num_cldfb_bands ); - mvr2r( Cldfb_ImagBuffer_Recons_Binaural[MAX_HEAD_ROT_POSES - 1][ch_idx1][index_slot], Cldfb_ImagBuffer_Ref_Binaural[ch_idx1][index_slot], num_cldfb_bands ); - } - } - - for ( pos_idx = 0; pos_idx < MAX_HEAD_ROT_POSES; pos_idx++ ) - { - char fname[200] = "recons_out_pos"; - char tag[2]; - tag[0] = (char) ( '0' + pos_idx ); - tag[1] = '\0'; - strcat( fname, tag ); - strcat( fname, ".wav" ); - ivas_log_cldfb2wav_data( - Cldfb_RealBuffer_Recons_Binaural[pos_idx], - Cldfb_ImagBuffer_Recons_Binaural[pos_idx], - hBinPostRenderer->cldfbSynReconsBinDec[pos_idx], - BINAURAL_CHANNELS, - num_cldfb_bands, - 48000, - num_slots, - sf_idx * num_slots, - fname ); - } - } -#endif - - pop_wmops(); - return; -} - - -/*-----------------------------------------------------------------------------------------* - * Function ivas_rend_CldfbSplitPostRendProcessTdIn() - * - * - *-----------------------------------------------------------------------------------------*/ - -static void ivas_rend_CldfbSplitPostRendProcessTdIn( - BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend, - MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, - const IVAS_QUATERNION QuaternionPost, - float output[][L_FRAME48k] ) -{ - 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]; - num_cldfb_bands = hBinHrSplitPostRend->cldfbSyn[0]->no_channels; - - /* Implement CLDFB analysis */ - 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++ ) - { - 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] ); - } - } - - ivas_SplitRenderer_PostRenderer( hBinHrSplitPostRend, pMultiBinPoseData, Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, QuaternionPost ); - - /* Implement CLDFB synthesis */ - 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]; - - 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]; - } - - cldfbSynthesis( RealBuffer, ImagBuffer, &( output[ch_idx][0] ), num_cldfb_bands * CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, hBinHrSplitPostRend->cldfbSyn[ch_idx] ); - } - - return; -} - - -/*-----------------------------------------------------------------------------------------* - * Function ivas_rend_CldfbSplitPostRendProcess() - * - * - *-----------------------------------------------------------------------------------------*/ - -void ivas_rend_CldfbSplitPostRendProcess( - 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 ) -{ - int16_t ch_idx, slot_idx, num_cldfb_bands; - - push_wmops( "ivas_rend_CldfbSplitPostRendProcess" ); - - num_cldfb_bands = hBinHrSplitPostRend->cldfbSyn[0]->no_channels; - - if ( cldfb_in_flag == 0 ) - { - ivas_rend_CldfbSplitPostRendProcessTdIn( hBinHrSplitPostRend, pMultiBinPoseData, QuaternionPost, output ); - pop_wmops(); - return; - } - - ivas_SplitRenderer_PostRenderer( hBinHrSplitPostRend, pMultiBinPoseData, Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, QuaternionPost ); - - /* Implement CLDFB synthesis */ - 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]; - - 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]; - } - - cldfbSynthesis( RealBuffer, ImagBuffer, &( output[ch_idx][0] ), num_cldfb_bands * CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, hBinHrSplitPostRend->cldfbSyn[ch_idx] ); - } - - pop_wmops(); - return; -} - - -/*-----------------------------------------------------------------------------------------* - * Function ivas_init_split_post_rend_handles() - * - * - *-----------------------------------------------------------------------------------------*/ - -void ivas_init_split_post_rend_handles( - SPLIT_POST_REND_WRAPPER *hSplitRendWrapper ) -{ - hSplitRendWrapper->hBinHrSplitPostRend = NULL; - hSplitRendWrapper->hSplitBinLCLDDec = NULL; - hSplitRendWrapper->hLc3plusDec = NULL; - ivas_init_multi_bin_pose_data( &hSplitRendWrapper->multiBinPoseData ); - hSplitRendWrapper->first_good_frame_received = 0; - - return; -} -#endif diff --git a/lib_rend/ivas_splitRendererPre.c b/lib_rend/ivas_splitRendererPre.c deleted file mode 100644 index 700117931..000000000 --- a/lib_rend/ivas_splitRendererPre.c +++ /dev/null @@ -1,2474 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2023 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. - -*******************************************************************************************************/ - -#include -#include "options.h" -#ifdef SPLIT_REND_WITH_HEAD_ROT -#include -#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG -#include -#endif -#include "ivas_prot.h" -#include "prot.h" -#include "ivas_cnst.h" -#include "ivas_rom_dec.h" -#include "ivas_prot_rend.h" -#ifdef DEBUGGING -#include "debug.h" -#endif -#include "wmc_auto.h" -#ifdef DBG_WAV_WRITER -#include "string.h" -#endif - - -/*------------------------------------------------------------------------- - * Local functions - * - * - *------------------------------------------------------------------------*/ - -static void ivas_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 ) -{ - float re1, im1, re2, im2; - - 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; - - return; -} - - -static int16_t ivas_is_mat_inv_2by2_complex( - float in_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS], - float in_im[BINAURAL_CHANNELS][BINAURAL_CHANNELS] ) -{ - int16_t is_det_zero = 1; - float det, det_re, det_im; - - ivas_calc_mat_det_2by2_complex( in_re, in_im, &det_re, &det_im ); - - det = ( ( det_re * det_re ) + ( det_im * det_im ) ); - - if ( det < EPSILON ) - { - is_det_zero = 0; - } - - return is_det_zero; -} - - -static void ivas_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] ) -{ - float det_re, det_im; - float re, im, det; - - ivas_calc_mat_det_2by2_complex( in_re, in_im, &det_re, &det_im ); - - det = ( det_re * det_re ) + ( det_im * det_im ); - -#ifdef DEBUGGING - /* assert to catch cases when input is singular matrix */ - assert( det > 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; - - 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; - - 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; - - 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], - int16_t num_chs, - int16_t 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; - - trace_cov = 0.0f; - for ( i = 0; i < num_chs; i++ ) - { - trace_cov += cov_ii_re[i][i]; - } - - trace_cov = max( 0.0f, trace_cov ); - - if ( trace_cov < EPSILON ) - { - 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 ); - } - return; - } - - for ( i = 0; i < num_chs; i++ ) - { - mvr2r( cov_ii_re[i], cov_ii_local_re[i], num_chs ); - } - - for ( i = 0; i < num_chs; i++ ) - { - cov_ii_local_re[i][i] = cov_ii_re[i][i] + ( trace_cov * 0.0001f ); - } - - if ( ivas_is_mat_inv_2by2_complex( cov_ii_local_re, cov_ii_im ) ) - { - ivas_calc_mat_inv_2by2_complex( cov_ii_local_re, cov_ii_im, cov_ii_inv_re, cov_ii_inv_im ); - ivas_mat_mult_2by2_complex( cov_ii_inv_re, cov_ii_inv_im, cov_io_re, cov_io_im, pred_mat_re, pred_mat_im ); - } - else - { - int16_t max_var_idx; - for ( i = 0; i < num_chs; i++ ) - { - set_zero( pred_mat_re[i], BINAURAL_CHANNELS ); - set_zero( pred_mat_im[i], BINAURAL_CHANNELS ); - } - - max_var_idx = 0; - if ( cov_ii_local_re[1][1] > cov_ii_local_re[0][0] ) - { - max_var_idx = 1; - } - - if ( cov_ii_local_re[max_var_idx][max_var_idx] > EPSILON ) - { - 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]; - } - } - } - - if ( real_only ) - { - for ( i = 0; i < num_chs; i++ ) - { - set_zero( pred_mat_im[i], 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], - float postpred_cov_im[][BINAURAL_CHANNELS], - int16_t 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]; - - assert( num_chs == BINAURAL_CHANNELS ); - for ( i = 0; i < num_chs; i++ ) - { - 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]; - } - set_zero( postpred_cov_re[i], BINAURAL_CHANNELS ); - set_zero( postpred_cov_im[i], BINAURAL_CHANNELS ); - } - - /* 2x2 mult */ - ivas_mat_mult_2by2_complex( dmx_mat_conj_re, dmx_mat_conj_im, cov_ii_re, cov_ii_im, temp_mat_re, temp_mat_im ); - ivas_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 ( j = 0; j < i; j++ ) - { - postpred_cov_re[i][j] = postpred_cov_re[j][i]; - postpred_cov_im[i][j] = -postpred_cov_im[j][i]; - } - postpred_cov_im[i][i] = 0; - } - - 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 ) -{ - int16_t sf, cldfb_band_idx, ch_idx1, ch_idx2; - int16_t brange[2]; - - 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 ); - } - - brange[0] = pBand_grouping[md_band_idx]; - brange[1] = pBand_grouping[md_band_idx + 1]; - - for ( ch_idx1 = 0; ch_idx1 < num_chs; ch_idx1++ ) - { - for ( ch_idx2 = 0; ch_idx2 < num_chs; ch_idx2++ ) - { - if ( real_only == 0 ) - { - for ( sf = start_slot_idx; sf < start_slot_idx + num_slots; sf++ ) - { - 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]; - } - } - } - else - { - for ( sf = start_slot_idx; sf < start_slot_idx + num_slots; sf++ ) - { - 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; - } - } - } - } - } - - 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 ) -{ - int16_t sf, cldfb_band_idx, ch_idx1, ch_idx2; - int16_t brange[2]; - - 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 ); - } - - brange[0] = pBand_grouping[md_band_idx]; - brange[1] = pBand_grouping[md_band_idx + 1]; - - for ( ch_idx1 = 0; ch_idx1 < num_chs; ch_idx1++ ) - { - for ( ch_idx2 = 0; ch_idx2 <= ch_idx1; ch_idx2++ ) - { - if ( ( ch_idx2 != ch_idx1 ) && ( real_only == 0 ) ) - { - for ( sf = start_slot_idx; sf < start_slot_idx + num_slots; sf++ ) - { - 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]; - } - } - } - else - { - for ( sf = start_slot_idx; sf < start_slot_idx + num_slots; sf++ ) - { - 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] = 0.0f; - } - } - } - } - } - - for ( ch_idx1 = 0; ch_idx1 < num_chs; ch_idx1++ ) - { - for ( ch_idx2 = ch_idx1 + 1; ch_idx2 < num_chs; ch_idx2++ ) - { - 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]; - } - } - - return; -} - - -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] ) -{ - int16_t i, j; - float norm_fact, abs_val; - - norm_fact = 0.0f; - for ( i = 0; i < BINAURAL_CHANNELS; i++ ) - { - 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_RABS( cov_oo_re[i][j], abs_val ); - norm_fact = max( norm_fact, abs_val ); - } - } - - norm_fact = ( norm_fact > EPSILON ) ? norm_fact : 1.0f; - - norm_fact = PCM16_TO_FLT_FAC / norm_fact; - - return norm_fact; -} - - -static void ivas_split_rend_huffman_encode( - ivas_split_rend_huffman_cfg_t *huff_cfg, - int16_t in, - int32_t *hcode, - int32_t *hlen ) -{ - int32_t min_sym_val; - const int32_t *codebook; - - min_sym_val = huff_cfg->codebook[0]; - - codebook = &huff_cfg->codebook[3 * ( in - min_sym_val )]; - *hlen = codebook[1]; - *hcode = codebook[2]; - - return; -} - - -static void ivas_split_rend_quant_md( - BIN_HR_SPLIT_REND_MD_HANDLE hMd, - IVAS_SPLIT_REND_POSE_TYPE pose_type, - int16_t real_only, - float fix_pos_rot_mat[][BINAURAL_CHANNELS], - const float pred_1byquantstep ) -{ - int16_t ch1, ch2; - int16_t gd_idx_min; - float sign, quant_val; - - if ( pose_type == PRED_ONLY || pose_type == PRED_ROLL_ONLY ) - { - float onebyquantstep; - - onebyquantstep = pred_1byquantstep; - if ( real_only == 1 ) - { - for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) - { - 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; - } - } - } - - for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) - { - for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) - { - quant_val = hMd->pred_mat_re[ch1][ch2] - fix_pos_rot_mat[ch1][ch2]; - quant_val = min( IVAS_SPLIT_REND_PRED_MAX_VAL, max( quant_val, IVAS_SPLIT_REND_PRED_MIN_VAL ) ); - hMd->pred_mat_re_idx[ch1][ch2] = (int16_t) roundf( onebyquantstep * quant_val ); - } - } - - if ( real_only == 0 ) - { - for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) - { - for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) - { - quant_val = min( IVAS_SPLIT_REND_PRED_MAX_VAL, max( hMd->pred_mat_im[ch1][ch2], IVAS_SPLIT_REND_PRED_MIN_VAL ) ); - hMd->pred_mat_im_idx[ch1][ch2] = (int16_t) roundf( onebyquantstep * quant_val ); - // hMd->pred_mat_im[ch1][ch2] = hMd->pred_mat_im_idx[ch1][ch2] * IVAS_SPLIT_REND_PRED_Q_STEP; - } - } - } - } - else if ( pose_type == COM_GAIN_ONLY ) - { - quant_val = min( IVAS_SPLIT_REND_D_MAX_VAL, max( hMd->gd, IVAS_SPLIT_REND_D_MIN_VAL ) ); - gd_idx_min = (int16_t) roundf( IVAS_SPLIT_REND_D_1BYQ_STEP * IVAS_SPLIT_REND_D_MIN_VAL ); - hMd->gd_idx = (int16_t) roundf( IVAS_SPLIT_REND_D_1BYQ_STEP * quant_val ); - hMd->gd = hMd->gd_idx * IVAS_SPLIT_REND_D_Q_STEP; - hMd->gd_idx = hMd->gd_idx - gd_idx_min; - } - else if ( pose_type == LR_GAIN_ONLY ) - { - quant_val = min( IVAS_SPLIT_REND_PITCH_G_MAX_VAL, max( hMd->gd, IVAS_SPLIT_REND_PITCH_G_MIN_VAL ) ); - gd_idx_min = (int16_t) roundf( IVAS_SPLIT_REND_PITCH_G_1BYQ_STEP * IVAS_SPLIT_REND_PITCH_G_MIN_VAL ); - hMd->gd_idx = (int16_t) roundf( IVAS_SPLIT_REND_PITCH_G_1BYQ_STEP * quant_val ); - hMd->gd_idx = hMd->gd_idx - gd_idx_min; - - quant_val = min( IVAS_SPLIT_REND_PITCH_G_MAX_VAL, max( hMd->gd2, IVAS_SPLIT_REND_PITCH_G_MIN_VAL ) ); - hMd->gd2_idx = (int16_t) roundf( IVAS_SPLIT_REND_PITCH_G_1BYQ_STEP * quant_val ); - hMd->gd2_idx = hMd->gd2_idx - gd_idx_min; - } - - return; -} - - -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], - BIN_HR_SPLIT_REND_MD_HANDLE hMd, - const IVAS_SPLIT_REND_POSE_TYPE pose_type, - const int16_t real_only ) -{ - float postpred_cov_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; - float postpred_cov_im[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]; - - for ( i = 0; i < BINAURAL_CHANNELS; i++ ) - { - gd_tmp[i] = cov_ii_re[i][i]; - if ( gd_tmp[i] < EPSILON ) - { - gd_tmp[i] = 1.0f; - } - else - { - gd_tmp[i] = ( cov_oo_re[i][i] ) / gd_tmp[i]; - gd_tmp[i] = sqrtf( gd_tmp[i] ); - } - } - hMd->gd = gd_tmp[0]; - hMd->gd2 = gd_tmp[1]; - } - else - { - cov_norm_fact = GetNormFact( cov_ii_re, cov_ii_im, cov_io_re, cov_io_im, cov_oo_re ); - - /* normalize the covariance */ - for ( i = 0; i < BINAURAL_CHANNELS; i++ ) - { - 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; - } - } - - 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 ); - - /*TODO : change this function to real only as thats what is needed*/ - ComputePostPredCov( cov_ii_norm_re, cov_ii_norm_im, hMd->pred_mat_re, hMd->pred_mat_im, postpred_cov_re, postpred_cov_im, BINAURAL_CHANNELS ); - - /* normalize everything to +-1 range */ - gd = 1.0f / ( PCM16_TO_FLT_FAC ); - for ( i = 0; i < BINAURAL_CHANNELS; i++ ) - { - 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; - } - } - -#if 0 - if ( 1 ) - { -#endif - gd2 = 0.0f; - sigma_d = 0.0f; - hMd->gd = 0.0f; -#if 0 - } - else - { - - sigma_d = cov_ii_norm_re[0][0] + cov_ii_norm_re[1][1] + cov_ii_norm_re[0][1] + cov_ii_norm_re[1][0] + EPSILON; - - rho_hat = max( EPSILON, sqrtf( postpred_cov_re[0][0] * postpred_cov_re[1][1] ) ); - rho_hat = postpred_cov_re[0][1] / rho_hat; - rho = max( EPSILON, sqrtf( cov_oo_norm_re[0][0] * cov_oo_norm_re[1][1] ) ); - rho = cov_oo_norm_re[0][1] / rho; - rho_hat = min( max( rho_hat, -0.9999f ), 0.9999f ); - rho = min( max( rho, -0.9999f ), 0.9999f ); - - // Compute decorrelator gain : gd2 = 0; - gd = 0; - gd2 = 0; - - aa = ( sigma_d * sigma_d ) * ( ( rho_hat * rho_hat ) - 1 ) + EPSILON; - bb = -( rho_hat * rho_hat ) * sigma_d * ( cov_oo_norm_re[0][0] + cov_oo_norm_re[1][1] ); - cc = ( rho_hat * rho_hat ) * cov_oo_norm_re[0][0] * cov_oo_norm_re[1][1]; - cc -= cov_oo_norm_re[0][1] * cov_oo_norm_re[0][1]; - - sign = +1.0f; - if ( rho < ( rho_hat - 0.0001 ) ) - { - bb -= 2 * sigma_d * cov_oo_norm_re[0][1]; - sign = -1.0f; - } - else if ( rho > ( rho_hat + 0.0001 ) ) - { - bb += 2 * sigma_d * cov_oo_norm_re[0][1]; - } - dd = bb * bb - ( 4 * aa * cc ); - if ( dd >= 0 ) - { - float gd2_1, gd2_2; - gd2_1 = ( -bb + sqrtf( dd ) ) / ( 2 * aa ); - gd2_2 = ( -bb - sqrtf( dd ) ) / ( 2 * aa ); - if ( ( gd2_1 >= 0 ) && ( gd2_2 >= 0 ) ) - { - gd2 = min( gd2_1, gd2_2 ); - } - else - { - gd2 = max( 0, max( gd2_1, gd2_2 ) ); - } - gd = sign * sqrtf( gd2 ); - } - - gd = min( IVAS_SPLIT_REND_D_MAX_VAL, max( gd, IVAS_SPLIT_REND_D_MIN_VAL ) ); - hMd->gd = SPLIT_REND_DECOR_ALPHA * gd + ( 1 - SPLIT_REND_DECOR_ALPHA ) * hMd->gd; - gd2 = min( gd2, cov_oo_norm_re[0][0] / sigma_d ); - gd2 = min( gd2, cov_oo_norm_re[1][1] / sigma_d ); - } -#endif /* 0 */ - - if ( postpred_cov_re[0][0] > EPSILON ) - { - 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 ); - } - else - { - gl2 = 1.0f; - } - - if ( postpred_cov_re[1][1] > EPSILON ) - { - 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 ); - } - else - { - gr2 = 1.0f; - } - - for ( i = 0; i < BINAURAL_CHANNELS; i++ ) - { - hMd->pred_mat_re[i][0] *= gl2; - hMd->pred_mat_re[i][1] *= gr2; - } - - if ( real_only == 0 ) - { - for ( i = 0; i < BINAURAL_CHANNELS; i++ ) - { - hMd->pred_mat_im[i][0] *= gl2; - hMd->pred_mat_im[i][1] *= gr2; - } - } - } - - return; -} - - -static void get_base2_bits( - const 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[IVAS_SPLIT_REND_NUM_QUANT_STRATS], - const int16_t pred_imag_bands_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], - int16_t pred_quant_pnts_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], - const int16_t d_bands_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], - const int16_t bands_pitch[IVAS_SPLIT_REND_NUM_QUANT_STRATS], - const int16_t pred_real_bands_roll[IVAS_SPLIT_REND_NUM_QUANT_STRATS], - const int16_t pred_imag_bands_roll[IVAS_SPLIT_REND_NUM_QUANT_STRATS], - int32_t base2bits[IVAS_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[IVAS_SPLIT_REND_NUM_QUANT_STRATS]; - - IVAS_SPLIT_REND_POSE_TYPE pose_type; - - for ( q = 0; q < num_quant_strats; q++ ) - { - pred_yaw_bits[q] = (int16_t) ceilf( log2f( pred_quant_pnts_yaw[q] ) ); - } - pred_roll_bits = (int16_t) ceilf( log2f( IVAS_SPLIT_REND_ROLL_PRED_QUANT_PNTS ) ); - - d_gain_bits = (int16_t) ceilf( log2f( IVAS_SPLIT_REND_D_QUANT_PNTS ) ); - pitch_gain_bits = d_gain_bits; - - for ( q = 0; q < num_quant_strats; q++ ) - { - base2bits[q] = 0; - } - - for ( q = 0; q < num_quant_strats; q++ ) - { - for ( pose_idx = 0; pose_idx < pMultiBinPoseData->num_poses - 1; pose_idx++ ) - { - pose_type = hBinHrSplitPreRend->pose_type[pose_idx]; - if ( pose_type == ANY_YAW ) - { - 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] += d_gain_bits * d_bands_yaw[q] * num_subframes; - } - else if ( pose_type == PITCH_ONLY ) - { - base2bits[q] += pitch_gain_bits * bands_pitch[q] * num_subframes; - base2bits[q] += pitch_gain_bits * bands_pitch[q] * num_subframes; - } - else - { - 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; - } - } - } - - return; -} - - -static void ivas_SplitRenderer_code_md_base2( - const 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, - IVAS_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; - BIN_HR_SPLIT_REND_MD_HANDLE hMd; - BIN_HR_SPLIT_REND_HUFF_HANDLE pHuff_cfg; - - pHuff_cfg = &hBinHrSplitPreRend->huff_cfg; - if ( pred_quant_pnts_yaw == IVAS_SPLIT_REND_PRED_63QUANT_PNTS ) - { - pred_cb_idx = 1; - } - else - { - pred_cb_idx = 0; - } - 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]; - - pred_code_len = pHuff_cfg->pred_base2_code_len[pred_cb_idx]; - pred_roll_code_len = pHuff_cfg->pred_roll_base2_code_len; - gd_code_len = pHuff_cfg->gd_base2_code_len; - p_gd_code_len = pHuff_cfg->p_gd_base2_code_len; - - num_poses = pMultiBinPoseData->num_poses; - - for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) - { - for ( pos_idx = 0; pos_idx < num_poses - 1; pos_idx++ ) - { - if ( hBinHrSplitPreRend->pose_type[pos_idx] == ANY_YAW ) - { - 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 ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) - { - code = hMd->pred_mat_re_idx[ch1][ch2] - min_pred_idx; - ivas_split_rend_bitstream_write_int32( pBits, code, pred_code_len ); - } - } - } - - 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 ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) - { - code = hMd->pred_mat_im_idx[ch1][ch2] - min_pred_idx; - ivas_split_rend_bitstream_write_int32( pBits, code, pred_code_len ); - } - } - } - for ( b = 0; b < d_bands_yaw; b++ ) - { - hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; - code = hMd->gd_idx - min_gd_idx; - ivas_split_rend_bitstream_write_int32( pBits, code, gd_code_len ); - } - } - else if ( hBinHrSplitPreRend->pose_type[pos_idx] == PITCH_ONLY ) - { - for ( b = 0; b < bands_pitch; b++ ) - { - hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; - code = hMd->gd_idx - min_p_gd_idx; - ivas_split_rend_bitstream_write_int32( pBits, code, p_gd_code_len ); - - code = hMd->gd2_idx - min_p_gd_idx; - ivas_split_rend_bitstream_write_int32( pBits, code, p_gd_code_len ); - } - } - else - { - 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 ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) - { - code = hMd->pred_mat_re_idx[ch1][ch2] - min_pred_roll_idx; - ivas_split_rend_bitstream_write_int32( pBits, code, pred_roll_code_len ); - } - } - } - - 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 ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) - { - code = hMd->pred_mat_im_idx[ch1][ch2] - min_pred_roll_idx; - ivas_split_rend_bitstream_write_int32( pBits, code, pred_roll_code_len ); - } - } - } - } - } - } - -#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG - { - static int16_t num_bits = 0; - static int16_t cntr = 0; - float fnum_bits; - - cntr++; - - num_bits += pBits->bits_written; - /* collect bits for every second */ - if ( cntr == 50 ) - { - cntr = 0; - fnum_bits = (float) num_bits / 1000.0f; - dbgwrite_txt( &fnum_bits, 1, "split_rend_MD_bitrate.txt", "MD bitrate (kbps)" ); - num_bits = 0; - } - } -#endif - return; -} - - -static void ivas_SplitRenderer_code_md_huff( - const 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, - IVAS_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; - BIN_HR_SPLIT_REND_MD_HANDLE hMd; - BIN_HR_SPLIT_REND_HUFF_HANDLE pHuff_cfg; - - pHuff_cfg = &hBinHrSplitPreRend->huff_cfg; - - if ( pred_quant_pnts_yaw == IVAS_SPLIT_REND_PRED_63QUANT_PNTS ) - { - pred_cb_idx = 1; - } - else - { - pred_cb_idx = 0; - } - - 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[( IVAS_SPLIT_REND_ROLL_PRED_QUANT_PNTS - 1 ) * 3]; - - num_poses = pMultiBinPoseData->num_poses; - - for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) - { - for ( pos_idx = 0; pos_idx < num_poses - 1; pos_idx++ ) - { - if ( hBinHrSplitPreRend->pose_type[pos_idx] == ANY_YAW ) - { - for ( b = 0; b < pred_real_bands_yaw; b++ ) - { - hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; - ivas_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 ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) - { - ivas_split_rend_huffman_encode( &pHuff_cfg->pred[pred_cb_idx], sym_adj_idx[ch1][ch2], &code, &len ); - ivas_split_rend_bitstream_write_int32( pBits, code, len ); - } - } - } - for ( b = 0; b < pred_imag_bands_yaw; b++ ) - { - hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; - ivas_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 ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) - { - - ivas_split_rend_huffman_encode( &pHuff_cfg->pred[pred_cb_idx], sym_adj_idx[ch1][ch2], &code, &len ); - - ivas_split_rend_bitstream_write_int32( pBits, code, len ); - } - } - } - for ( b = 0; b < d_bands_yaw; b++ ) - { - hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; - ivas_split_rend_huffman_encode( &pHuff_cfg->gd, hMd->gd_idx, &code, &len ); - ivas_split_rend_bitstream_write_int32( pBits, code, len ); - } - } - else if ( hBinHrSplitPreRend->pose_type[pos_idx] == PITCH_ONLY ) - { - for ( b = 0; b < bands_pitch; b++ ) - { - hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; - ivas_split_rend_huffman_encode( &pHuff_cfg->p_gd, hMd->gd_idx, &code, &len ); - ivas_split_rend_bitstream_write_int32( pBits, code, len ); - - ivas_split_rend_huffman_encode( &pHuff_cfg->p_gd, hMd->gd2_idx, &code, &len ); - ivas_split_rend_bitstream_write_int32( pBits, code, len ); - } - } - else - { - for ( b = 0; b < pred_real_bands_roll; b++ ) - { - hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; - ivas_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 ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) - { - ivas_split_rend_huffman_encode( &pHuff_cfg->pred_roll, sym_adj_idx[ch1][ch2], &code, &len ); - ivas_split_rend_bitstream_write_int32( pBits, code, len ); - } - } - } - for ( b = 0; b < pred_imag_bands_roll; b++ ) - { - hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; - ivas_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 ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) - { - ivas_split_rend_huffman_encode( &pHuff_cfg->pred_roll, sym_adj_idx[ch1][ch2], &code, &len ); - ivas_split_rend_bitstream_write_int32( pBits, code, len ); - } - } - } - } - } - } - -#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG - { - static int16_t num_bits = 0; - static int16_t cntr = 0; - float fnum_bits; - - cntr++; - num_bits += pBits->bits_written; - /* collect bits for every second */ - if ( cntr == 50 ) - { - cntr = 0; - fnum_bits = (float) num_bits / 1000.0f; - dbgwrite_txt( &fnum_bits, 1, "split_rend_MD_bitrate.txt", "MD bitrate (kbps)" ); - num_bits = 0; - } - } -#endif - return; -} - - -static void ivas_SplitRenderer_quant_code( - const BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, - const IVAS_QUATERNION headPosition, - MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, - IVAS_SPLIT_REND_BITS_HANDLE pBits, - const int16_t low_res_pre_rend_rot, - const int32_t target_md_bits ) -{ - int16_t num_complex_bands, q, num_subframes, sf_idx, pos_idx, b, num_quant_strats; - int32_t overhead_bits, quant_strat_bits, huff_bits, start_bit; - int16_t pred_real_bands_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], pred_real_bands_roll[IVAS_SPLIT_REND_NUM_QUANT_STRATS]; - int16_t pred_imag_bands_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], pred_imag_bands_roll[IVAS_SPLIT_REND_NUM_QUANT_STRATS]; - int16_t d_bands_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], bands_pitch[IVAS_SPLIT_REND_NUM_QUANT_STRATS]; - int32_t base2bits[IVAS_SPLIT_REND_NUM_QUANT_STRATS]; - int16_t pred_quant_pnts_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS]; - float pred_1byquantstep_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS]; - float pred_quantstep_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS]; - BIN_HR_SPLIT_REND_MD_HANDLE hMd; - - if ( low_res_pre_rend_rot ) - { - num_subframes = 1; - } - else - { - num_subframes = MAX_PARAM_SPATIAL_SUBFRAMES; - } - - overhead_bits = pBits->bits_written; - - ivas_split_rend_bitstream_write_int32( pBits, pMultiBinPoseData->dof, IVAS_SPLIT_REND_DOF_BITS ); - ivas_split_rend_bitstream_write_int32( pBits, pMultiBinPoseData->hq_mode, IVAS_SPLIT_REND_HQ_MODE_BITS ); - ivas_split_rend_bitstream_write_int32( pBits, (int32_t) pMultiBinPoseData->rot_axis, IVAS_SPLIT_REND_ROT_AXIS_BITS ); - - /* code ref pose*/ - for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) - { - int16_t 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; - ivas_split_rend_bitstream_write_int32( pBits, angle, IVAS_SPLIT_REND_HEAD_POSE_BITS ); - - angle = (int16_t) roundf( head_pos_euler.y ); - angle += 180; - ivas_split_rend_bitstream_write_int32( pBits, angle, IVAS_SPLIT_REND_HEAD_POSE_BITS ); - - angle = (int16_t) roundf( head_pos_euler.z ); - angle += 180; - - ivas_split_rend_bitstream_write_int32( pBits, angle, IVAS_SPLIT_REND_HEAD_POSE_BITS ); - } - - ivas_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 ); - - 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 */ - - 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 ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) - { - for ( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses - 1; pos_idx++ ) - { - if ( hBinHrSplitPreRend->pose_type[pos_idx] == ANY_YAW ) - { - for ( b = 0; b < pred_imag_bands_yaw[q]; b++ ) - { - hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; - - ivas_split_rend_quant_md( hMd, PRED_ONLY, 0, hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx], pred_1byquantstep_yaw[q] ); - } - for ( ; b < pred_real_bands_yaw[q]; b++ ) - { - hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; - - ivas_split_rend_quant_md( hMd, PRED_ONLY, 1, hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx], pred_1byquantstep_yaw[q] ); - } - - for ( b = 0; b < d_bands_yaw[q]; b++ ) - { - hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; - - ivas_split_rend_quant_md( hMd, COM_GAIN_ONLY, 1, hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx], 0 ); - } - } - else if ( hBinHrSplitPreRend->pose_type[pos_idx] == PITCH_ONLY ) - { - for ( b = 0; b < bands_pitch[q]; b++ ) - { - hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; - ivas_split_rend_quant_md( hMd, LR_GAIN_ONLY, 1, hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx], 0 ); - } - } - else - { - for ( b = 0; b < pred_imag_bands_roll[q]; b++ ) - { - hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; - ivas_split_rend_quant_md( hMd, PRED_ROLL_ONLY, 0, hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx], IVAS_SPLIT_REND_PRED_ROLL_1BYQ_STEP ); - } - for ( ; b < pred_real_bands_roll[q]; b++ ) - { - hMd = &hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; - ivas_split_rend_quant_md( hMd, PRED_ROLL_ONLY, 1, hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx], IVAS_SPLIT_REND_PRED_ROLL_1BYQ_STEP ); - } - } - } - } - - /*get base2 bits and check if its within target. if yes then code with base2 to save complexity on post renderer*/ - start_bit = pBits->bits_written; - - ivas_split_rend_bitstream_write_int32( pBits, 1, 1 ); - ivas_split_rend_bitstream_write_int32( pBits, q, quant_strat_bits ); - - huff_bits = pBits->bits_written; - ivas_SplitRenderer_code_md_huff( - hBinHrSplitPreRend, - pMultiBinPoseData, - num_subframes, - pred_real_bands_yaw[q], - pred_imag_bands_yaw[q], - pred_quant_pnts_yaw[q], - d_bands_yaw[q], - bands_pitch[q], - pred_real_bands_roll[q], - 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 ) ) ) - { - if ( huff_bits > base2bits[q] ) - { - pBits->bits_written = start_bit; - - ivas_split_rend_bitstream_write_int32( pBits, 0, 1 ); - ivas_split_rend_bitstream_write_int32( pBits, q, quant_strat_bits ); - - ivas_SplitRenderer_code_md_base2( hBinHrSplitPreRend, pMultiBinPoseData, num_subframes, pred_real_bands_yaw[q], pred_imag_bands_yaw[q], - pred_quant_pnts_yaw[q], - d_bands_yaw[q], bands_pitch[q], pred_real_bands_roll[q], pred_imag_bands_roll[q], pBits ); - } - break; - } - - pBits->bits_written = start_bit; - } - -#ifdef SPLIT_MD_CODING_DEBUG - for ( sf_idx = 0; sf_idx < num_subframes; sf_idx++ ) - { - int16_t val, quant_strat, ch1, ch2; - char filename[200] = "split_md_debug_indices.bin"; - quant_strat = q; - for ( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses - 1; pos_idx++ ) - { - if ( hBinHrSplitPreRend->pose_type[pos_idx] == ANY_YAW ) - { - for ( b = 0; b < pred_real_bands_yaw[quant_strat]; b++ ) - { - for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) - { - for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) - { - val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_re_idx[ch1][ch2]; - dbgwrite( &val, sizeof( int16_t ), 1, 1, filename ); - } - } - } - for ( b = 0; b < pred_imag_bands_yaw[quant_strat]; b++ ) - { - for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) - { - for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) - { - val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_im_idx[ch1][ch2]; - dbgwrite( &val, sizeof( int16_t ), 1, 1, filename ); - } - } - } - for ( b = 0; b < d_bands_yaw[quant_strat]; b++ ) - { - val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd_idx; - dbgwrite( &val, sizeof( int16_t ), 1, 1, filename ); - } - } - else if ( hBinHrSplitPreRend->pose_type[pos_idx] == PITCH_ONLY ) - { - for ( b = 0; b < bands_pitch[quant_strat]; b++ ) - { - val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd_idx; - dbgwrite( &val, sizeof( int16_t ), 1, 1, filename ); - val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].gd2_idx; - dbgwrite( &val, sizeof( int16_t ), 1, 1, filename ); - } - } - else - { - for ( b = 0; b < pred_real_bands_roll[quant_strat]; b++ ) - { - for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) - { - for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) - { - val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_re_idx[ch1][ch2]; - dbgwrite( &val, sizeof( int16_t ), 1, 1, filename ); - } - } - } - for ( b = 0; b < pred_imag_bands_roll[quant_strat]; b++ ) - { - for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) - { - for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) - { - val = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b].pred_mat_im_idx[ch1][ch2]; - dbgwrite( &val, sizeof( int16_t ), 1, 1, filename ); - } - } - } - } - } - } -#endif - - return; -} - - -/*------------------------------------------------------------------------- - * Function ivas_SplitRenderer_GetRotMd() - * - * - *------------------------------------------------------------------------*/ - -void ivas_SplitRenderer_GetRotMd( - 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 ) -{ - 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 = ivas_split_rend_band_grouping; - - push_wmops( "ivas_SplitRenderer_GetRotMd" ); - - num_md_bands = MAX_SPLIT_REND_MD_BANDS; - num_poses = pMultiBinPoseData->num_poses; - - if ( low_res ) - { - num_slots = CLDFB_NO_COL_MAX; - num_subframes = 1; - } - else - { - num_slots = MAX_PARAM_SPATIAL_SUBFRAMES; - num_subframes = MAX_PARAM_SPATIAL_SUBFRAMES; - } - - /* compute reference signal covariance */ - 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++ ) - { - if ( b < COMPLEX_MD_BAND_THRESH ) - { - real_only = 0; - } - else - { - real_only = 1; - } - - 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 ); - - /* compute rotated signal covariance */ - for ( pos_idx = 0; pos_idx < num_poses - 1; pos_idx++ ) - { - 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 ); - - 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 ); - - 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 ); - } - } - } - - pop_wmops(); - return; -} - - -/*------------------------------------------------------------------------- - * Function ivas_rend_CldfbSplitPreRendProcess() - * - * - *------------------------------------------------------------------------*/ - -void ivas_rend_CldfbSplitPreRendProcess( - const 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], - IVAS_SPLIT_REND_BITS_HANDLE pBits, - const int32_t target_md_bits, - const int16_t low_res_pre_rend_rot ) -{ - push_wmops( "ivas_rend_CldfbSplitPreRendProcess" ); - - ivas_SplitRenderer_GetRotMd( hBinHrSplitPreRend, pMultiBinPoseData, Cldfb_In_BinReal, Cldfb_In_BinImag, low_res_pre_rend_rot ); - - ivas_SplitRenderer_quant_code( hBinHrSplitPreRend, headPosition, pMultiBinPoseData, pBits, low_res_pre_rend_rot, target_md_bits ); - -#ifdef SPLIT_POSE_CORRECTION_DEBUG - float tmpCrendBuffer[2][L_FRAME48k], quant_val, step, minv, maxv; - IVAS_QUATERNION QuaternionsPost[MAX_PARAM_SPATIAL_SUBFRAMES]; - int16_t sf_idx, pos_idx, b, ch1, ch2; - int32_t read_off, write_off; - for ( sf_idx = 0; sf_idx < MAX_PARAM_SPATIAL_SUBFRAMES; sf_idx++ ) - { - QuaternionsPost[sf_idx].w = -3.0f; - QuaternionsPost[sf_idx].x = 0.0f; - QuaternionsPost[sf_idx].y = 0.0f; - QuaternionsPost[sf_idx].z = 0.0f; - } - -#if 0 - read_off = pBits->bits_read; - write_off = pBits->bits_written; - ivas_splitBinPostRendMdDec( - pBits, - hBinHrSplitPreRend->hBinHrSplitPostRend, - pMultiBinPoseData ); - pMultiBinPoseData->poseCorrectionMode = IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB; - pBits->bits_read = read_off; - pBits->bits_written = write_off; -#else - hBinHrSplitPreRend->hBinHrSplitPostRend->low_Res = 1; - set_fix_rotation_mat( hBinHrSplitPreRend->hBinHrSplitPostRend->fix_pos_rot_mat, pMultiBinPoseData ); - set_pose_types( hBinHrSplitPreRend->hBinHrSplitPostRend->pose_type, pMultiBinPoseData ); - for ( sf_idx = 0; sf_idx < MAX_PARAM_SPATIAL_SUBFRAMES; sf_idx++ ) - { - hBinHrSplitPreRend->hBinHrSplitPostRend->QuaternionsPre[sf_idx] = headPositions[sf_idx]; - } - for ( sf_idx = 0; sf_idx < 1; sf_idx++ ) - { - for ( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses - 1; pos_idx++ ) - { - for ( b = 0; b < MAX_SPLIT_REND_MD_BANDS; b++ ) - { - hBinHrSplitPreRend->hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b] = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; -#if 0 - BIN_HR_SPLIT_REND_MD_HANDLE hMd; - hMd = &hBinHrSplitPreRend->hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; - minv = -1.4f; - maxv = 1.4f; - step = ( maxv - minv ) / 30.0f; - if ( b >= 20 ) - { - float sign; - for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) - { - 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; - } - } - } - - for ( ch1 = 0; ch1 < BINAURAL_CHANNELS; ch1++ ) - { - for ( ch2 = 0; ch2 < BINAURAL_CHANNELS; ch2++ ) - { - quant_val = hMd->pred_mat_re[ch1][ch2] - hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx][ch1][ch2]; - quant_val = min( maxv, max( quant_val, minv ) ); - quant_val = (int16_t) roundf( quant_val / step ); - hMd->pred_mat_re[ch1][ch2] = quant_val * step; - hMd->pred_mat_re[ch1][ch2] += hBinHrSplitPreRend->fix_pos_rot_mat[pos_idx][ch1][ch2]; - - quant_val = hMd->pred_mat_im[ch1][ch2]; - quant_val = min( maxv, max( quant_val, minv ) ); - quant_val = (int16_t) roundf( quant_val / step ); - hMd->pred_mat_im[ch1][ch2] = quant_val * step; - } - } -#endif - } - } - } - -#endif - ivas_rend_CldfbSplitPostRendProcess( hBinHrSplitPreRend->hBinHrSplitPostRend, pMultiBinPoseData, QuaternionsPost, Cldfb_In_BinReal[0], Cldfb_In_BinImag[0], tmpCrendBuffer, 1 ); - - { - float *pOut[2]; - char fname[200] = "ref_act_pos.wav"; - pOut[0] = tmpCrendBuffer[0]; - pOut[1] = tmpCrendBuffer[1]; - dbgwrite_wav( pOut, CLDFB_NO_COL_MAX * hBinHrSplitPreRend->hBinHrSplitPostRend->cldfbSyn[0]->no_channels, fname, 48000, 2 ); - } -#endif - - pop_wmops(); - return; -} - - -/*------------------------------------------------------------------------- - * Function ivas_splitBinPreRendOpen() - * - * - *------------------------------------------------------------------------*/ - -ivas_error ivas_splitBinPreRendOpen( - 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 -) -{ - BIN_HR_SPLIT_PRE_REND_HANDLE hBinRend; -#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG - ivas_error error; - int16_t ch; -#endif - int16_t pos_idx, sf_idx, bandIdx; - - if ( ( hBinRend = (BIN_HR_SPLIT_PRE_REND_HANDLE) malloc( sizeof( BIN_HR_SPLIT_PRE_REND ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for bin split pre renderer Module \n" ) ); - } - -#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG - for ( int16_t i = 0; i < MAX_HEAD_ROT_POSES + 1; i++ ) - { - for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) - { - hBinRend->cldfbSynRotBinDec[i][ch] = NULL; - } - } - - for ( int16_t i = 0; i < MAX_HEAD_ROT_POSES + 1; i++ ) - { - for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) - { - if ( ( error = openCldfb( &( hBinRend->cldfbSynRotBinDec[i][ch] ), CLDFB_SYNTHESIS, output_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) - { - return error; - } - } - } -#endif - - 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 ( bandIdx = 0; bandIdx < MAX_SPLIT_REND_MD_BANDS; bandIdx++ ) - { - hBinRend->rot_md[pos_idx][sf_idx][bandIdx].gd = 0.0f; - } - } - } - - set_fix_rotation_mat( hBinRend->fix_pos_rot_mat, pMultiBinPoseData ); - - set_pose_types( hBinRend->pose_type, pMultiBinPoseData ); - - ivas_split_rend_init_huff_cfg( &hBinRend->huff_cfg ); - -#ifdef SPLIT_POSE_CORRECTION_DEBUG - if ( ( error = ivas_splitBinPostRendOpen( &hBinRend->hBinHrSplitPostRend, pMultiBinPoseData, 48000 ) ) != IVAS_ERR_OK ) - { - return error; - } -#endif - - *hBinHrSplitPreRend = hBinRend; - - return IVAS_ERR_OK; -} - - -/*------------------------------------------------------------------------- - * Function ivas_splitBinPreRendClose() - * - * - *------------------------------------------------------------------------*/ - -void ivas_splitBinPreRendClose( - BIN_HR_SPLIT_PRE_REND_HANDLE *hBinHrSplitPreRend ) -{ - if ( ( *hBinHrSplitPreRend ) != NULL ) - { -#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG - { - int16_t i, n; - for ( i = 0; i < MAX_HEAD_ROT_POSES + 1; i++ ) - { - for ( n = 0; n < BINAURAL_CHANNELS; n++ ) - { - if ( ( *hBinHrSplitPreRend )->cldfbSynRotBinDec[i][n] != NULL ) - { - deleteCldfb( &( ( *hBinHrSplitPreRend )->cldfbSynRotBinDec[i][n] ) ); - ( *hBinHrSplitPreRend )->cldfbSynRotBinDec[i][n] = NULL; - } - } - } - } -#endif -#ifdef SPLIT_POSE_CORRECTION_DEBUG - ivas_splitBinPostRendClose( &( *hBinHrSplitPreRend )->hBinHrSplitPostRend ); -#endif - - free( ( *hBinHrSplitPreRend ) ); - ( *hBinHrSplitPreRend ) = NULL; - } - - return; -} - - -/*-------------------------------------------------------------------------* - * ivas_set_split_rend_ht_setup() - * - * - *-------------------------------------------------------------------------*/ - -void ivas_set_split_rend_ht_setup( - IVAS_DEC_SPLIT_REND_WRAPPER *hSplitBinRend, - COMBINED_ORIENTATION_HANDLE hCombinedOrientationData ) -{ - int16_t sf, i, j; - if ( hCombinedOrientationData != NULL && hSplitBinRend->splitrend.multiBinPoseData.poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) - { - for ( sf = 1; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ ) - { - hCombinedOrientationData->Quaternions[sf] = hCombinedOrientationData->Quaternions[0]; - - for ( i = 0; i < 3; i++ ) - { - for ( j = 0; j < 3; j++ ) - { - hCombinedOrientationData->Rmat[sf][i][j] = hCombinedOrientationData->Rmat[0][i][j]; - } - } - } - } - - return; -} - - -/*-------------------------------------------------------------------------* - * ivas_set_split_rend_setup() - * - * Setup IVAS split rendering - *-------------------------------------------------------------------------*/ - -ivas_error ivas_set_split_rend_setup( - IVAS_DEC_SPLIT_REND_WRAPPER *hSplitBinRend, - IVAS_SPLIT_REND_CONFIG_DATA *hSplitBinConfig, - COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, - uint8_t *splitRendBitsBuf ) -{ - int16_t sf, i, j; - - if ( ( hSplitBinRend->hSplitRendBits = (IVAS_SPLIT_REND_BITS_HANDLE) malloc( sizeof( IVAS_SPLIT_REND_BITS_DATA ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for split renderer Bits buffer\n" ) ); - } - - hSplitBinRend->hSplitRendBits->bits_buf = splitRendBitsBuf; - hSplitBinRend->hSplitRendBits->bits_read = 0; - hSplitBinRend->hSplitRendBits->bits_written = 0; - hSplitBinRend->hSplitRendBits->buf_len = IVAS_MAX_SPLIT_REND_BITS_BUFFER_SIZE_IN_BYTES; - hSplitBinRend->hSplitRendBits->codec = IVAS_SPLIT_REND_CODEC_DEFAULT; - hSplitBinRend->hSplitRendBits->pose_correction = IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE; - hSplitBinRend->hSplitRendBits->codec_frame_size_ms = 0; - - - if ( ( hSplitBinRend->hMultiBinCldfbData = (IVAS_DEC_SPLIT_REND_MULTI_BIN_CLDFB_DATA_HANDLE) malloc( sizeof( IVAS_DEC_SPLIT_REND_MULTI_BIN_CLDFB_DATA ) ) ) == NULL ) - { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for split rendering structure" ); - } - - ivas_renderSplitGetMultiBinPoseData( hSplitBinConfig, &hSplitBinRend->splitrend.multiBinPoseData, hCombinedOrientationData->sr_pose_pred_axis ); - - if ( hCombinedOrientationData != NULL && hSplitBinRend->splitrend.multiBinPoseData.poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) - { - for ( sf = 1; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ ) - { - hCombinedOrientationData->Quaternions[sf] = hCombinedOrientationData->Quaternions[0]; - - for ( i = 0; i < 3; i++ ) - { - for ( j = 0; j < 3; j++ ) - { - hCombinedOrientationData->Rmat[sf][i][j] = hCombinedOrientationData->Rmat[0][i][j]; - } - } - } - } - - return IVAS_ERR_OK; -} - - -/*------------------------------------------------------------------------- - * Function ivas_init_split_rend_handles() - * - * - *------------------------------------------------------------------------*/ - -void ivas_init_split_rend_handles( - SPLIT_REND_WRAPPER *hSplitRendWrapper ) -{ - int16_t i; - - hSplitRendWrapper->hBinHrSplitPreRend = NULL; - hSplitRendWrapper->hCldfbHandles = NULL; - hSplitRendWrapper->hSplitBinLCLDEnc = NULL; - hSplitRendWrapper->hLc3plusEnc = NULL; - - for ( i = 0; i < MAX_HEAD_ROT_POSES - 1; ++i ) - { - hSplitRendWrapper->hTdRendHandles[i] = NULL; - } - - for ( i = 0; i < MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS; ++i ) - { - hSplitRendWrapper->lc3plusDelayBuffers[i] = NULL; - } - hSplitRendWrapper->lc3plusDelaySamples = 0; - - ivas_init_multi_bin_pose_data( &hSplitRendWrapper->multiBinPoseData ); - - return; -} - - -/*------------------------------------------------------------------------- - * Function split_renderer_open_lc3plus() - * - * - *------------------------------------------------------------------------*/ - -static ivas_error split_renderer_open_lc3plus( - SPLIT_REND_WRAPPER *hSplitRendWrapper, - const IVAS_SPLIT_REND_CONFIG_DATA *pSplitRendConfig, - const int32_t OutSampleRate, - const int16_t is_5ms_frame ) -{ - ivas_error error; - int16_t i, delayBufferLength; - LC3PLUS_CONFIG config; - - if ( is_5ms_frame ) - { - config.lc3plus_frame_duration_us = pSplitRendConfig->codec_frame_size_ms * 1000; - config.ivas_frame_duration_us = ( pSplitRendConfig->dof == 0 ) ? config.lc3plus_frame_duration_us : 20000; - } - else - { - config.lc3plus_frame_duration_us = 5000; - config.ivas_frame_duration_us = 20000; - } - config.samplerate = OutSampleRate; - - config.channels = BINAURAL_CHANNELS; - - if ( ( error = IVAS_LC3PLUS_ENC_Open( config, ivas_get_lc3plus_bitrate( pSplitRendConfig->splitRendBitRate, pSplitRendConfig->poseCorrectionMode, (int16_t) ( config.ivas_frame_duration_us / 1000 ) ), &hSplitRendWrapper->hLc3plusEnc ) ) != IVAS_ERR_OK ) - { - return error; - } - - /* This returns delay of entire LC3plus chain (enc + dec) */ - if ( ( error = IVAS_LC3PLUS_ENC_GetDelay( hSplitRendWrapper->hLc3plusEnc, &hSplitRendWrapper->lc3plusDelaySamples ) ) != IVAS_ERR_OK ) - { - return error; - } - - /* Alocate buffers for delay compensation */ - if ( pSplitRendConfig->codec == IVAS_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 ) - { - 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 ); - } - } - 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 ) - { - 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 ); - } - } - - return IVAS_ERR_OK; -} - - -/*------------------------------------------------------------------------- - * Function ivas_split_renderer_open() - * - * - *------------------------------------------------------------------------*/ - -ivas_error ivas_split_renderer_open( - SPLIT_REND_WRAPPER *hSplitRendWrapper, - const IVAS_SPLIT_REND_CONFIG_DATA *pSplitRendConfig, - const int32_t OutSampleRate, - const int16_t cldfb_in_flag, - const int16_t pcm_out_flag, - const int16_t is_5ms_frame ) -{ - ivas_error error, ch, num_ch; -#ifndef SPLIT_REND_WITH_HEAD_ROT - CLDFB_TYPE cldfbMode; -#endif - uint8_t isCldfbNeeded = 0; -#ifndef SPLIT_REND_WITH_HEAD_ROT - cldfbMode = CLDFB_ANALYSIS; -#endif - - if ( ( error = ivas_split_rend_validate_config( pSplitRendConfig, pcm_out_flag ) ) != IVAS_ERR_OK ) - { - return error; - } - - if ( cldfb_in_flag == 0 ) - { - isCldfbNeeded = 1; -#ifndef SPLIT_REND_WITH_HEAD_ROT - cldfbMode = CLDFB_ANALYSIS; -#endif - } - else if ( pSplitRendConfig->codec == IVAS_SPLIT_REND_CODEC_LC3PLUS && cldfb_in_flag ) - { -#ifdef SPLIT_REND_WITH_HEAD_ROT - isCldfbNeeded = 1; -#else - isCldfbNeeded = 1; - cldfbMode = CLDFB_SYNTHESIS; -#endif - } - else if ( pcm_out_flag && cldfb_in_flag ) - { -#ifdef SPLIT_REND_WITH_HEAD_ROT - isCldfbNeeded = 1; -#else - isCldfbNeeded = 1; - cldfbMode = CLDFB_SYNTHESIS; -#endif - } - - hSplitRendWrapper->hCldfbHandles = NULL; - - if ( isCldfbNeeded ) - { - 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++ ) - { - hSplitRendWrapper->hCldfbHandles->cldfbAna[ch] = NULL; - } - -#ifdef SPLIT_REND_WITH_HEAD_ROT - for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) - { - hSplitRendWrapper->hCldfbHandles->cldfbSyn[ch] = NULL; - } -#endif - - num_ch = hSplitRendWrapper->multiBinPoseData.num_poses * BINAURAL_CHANNELS; - - for ( ch = 0; ch < num_ch; ch++ ) - { - if ( ( error = openCldfb( &( hSplitRendWrapper->hCldfbHandles->cldfbAna[ch] ), -#ifndef SPLIT_REND_WITH_HEAD_ROT - cldfbMode, -#else - CLDFB_ANALYSIS, -#endif - OutSampleRate, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) - { - return error; - } - } - -#ifdef SPLIT_REND_WITH_HEAD_ROT - for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) - { - if ( ( error = openCldfb( &( hSplitRendWrapper->hCldfbHandles->cldfbSyn[ch] ), CLDFB_SYNTHESIS, OutSampleRate, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) - { - return error; - } - } -#endif - } - - if ( pSplitRendConfig->poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) - { - if ( ( error = ivas_splitBinPreRendOpen( &hSplitRendWrapper->hBinHrSplitPreRend, &hSplitRendWrapper->multiBinPoseData -#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG - , - OutSampleRate -#endif - ) ) != IVAS_ERR_OK ) - { - return error; - } - } - - if ( pcm_out_flag == 0 ) - { - if ( pSplitRendConfig->codec == IVAS_SPLIT_REND_CODEC_LC3PLUS ) - { - if ( ( error = split_renderer_open_lc3plus( hSplitRendWrapper, pSplitRendConfig, OutSampleRate, is_5ms_frame ) ) != IVAS_ERR_OK ) - { - return error; - } - } - else - { - if ( ( error = ivas_splitBinLCLDEncOpen( &hSplitRendWrapper->hSplitBinLCLDEnc, OutSampleRate, BINAURAL_CHANNELS, ivas_get_lcld_bitrate( pSplitRendConfig->splitRendBitRate, hSplitRendWrapper->multiBinPoseData.poseCorrectionMode ) ) ) != IVAS_ERR_OK ) - { - return error; - } - } - } - - return IVAS_ERR_OK; -} - - -/*------------------------------------------------------------------------- - * Function ivas_split_renderer_close() - * - * - *------------------------------------------------------------------------*/ - -void ivas_split_renderer_close( - SPLIT_REND_WRAPPER *hSplitBinRend ) -{ - int16_t i; - - if ( hSplitBinRend->hBinHrSplitPreRend != NULL ) - { - ivas_splitBinPreRendClose( &hSplitBinRend->hBinHrSplitPreRend ); - } - - if ( hSplitBinRend->hSplitBinLCLDEnc != NULL ) - { - ivas_splitBinLCLDEncClose( &hSplitBinRend->hSplitBinLCLDEnc ); - } - - if ( hSplitBinRend->hCldfbHandles != NULL ) - { - int16_t num_ch, ch; - num_ch = MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS; - for ( ch = 0; ch < num_ch; ch++ ) - { - if ( hSplitBinRend->hCldfbHandles->cldfbAna[ch] != NULL ) - { - deleteCldfb( &hSplitBinRend->hCldfbHandles->cldfbAna[ch] ); - hSplitBinRend->hCldfbHandles->cldfbAna[ch] = NULL; - } - } - -#ifdef SPLIT_REND_WITH_HEAD_ROT - for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) - { - 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 ) - { - IVAS_LC3PLUS_ENC_Close( &hSplitBinRend->hLc3plusEnc ); - } - - for ( i = 0; i < MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS; ++i ) - { - if ( hSplitBinRend->lc3plusDelayBuffers[i] != NULL ) - { - free( hSplitBinRend->lc3plusDelayBuffers[i] ); - hSplitBinRend->lc3plusDelayBuffers[i] = NULL; - } - } - - for ( i = 0; i < MAX_HEAD_ROT_POSES - 1; ++i ) - { - if ( hSplitBinRend->hTdRendHandles[i] != NULL ) - { - hSplitBinRend->hTdRendHandles[i]->HrFiltSet_p = NULL; - ivas_td_binaural_close( &hSplitBinRend->hTdRendHandles[i] ); - } - } - - return; -} - - -/*------------------------------------------------------------------------- - * Function splitRendLc3plusEncodeAndWrite() - * - * - *------------------------------------------------------------------------*/ - -static ivas_error splitRendLc3plusEncodeAndWrite( - SPLIT_REND_WRAPPER *hSplitBin, - IVAS_SPLIT_REND_BITS_HANDLE pBits, - const int32_t SplitRendBitRate, - float *in[] ) -{ - ivas_error error; - int16_t i; - int32_t lc3plusBitstreamSize; - float *channel_ptrs[MAX_HEAD_ROT_POSES * 2]; - assert( hSplitBin->hLc3plusEnc != NULL ); - - /* Find next byte boundary and zero-pad to it */ - while ( pBits->bits_written % 8 != 0 ) - { - ivas_split_rend_bitstream_write_int32( pBits, 0L, 1 ); - } - - for ( i = 0; i < BINAURAL_CHANNELS * hSplitBin->multiBinPoseData.num_poses; ++i ) - { - channel_ptrs[i] = in[i]; - } - - if ( ( error = IVAS_LC3PLUS_ENC_GetOutputBitstreamSize( hSplitBin->hLc3plusEnc, &lc3plusBitstreamSize ) ) != IVAS_ERR_OK ) - { - return error; - } - - ivas_split_rend_bitstream_write_int32( pBits, ivas_get_lc3plus_bitrate_id( SplitRendBitRate ), 8 ); - - /* Write bitstream */ - if ( ( error = IVAS_LC3PLUS_ENC_Encode( hSplitBin->hLc3plusEnc, channel_ptrs, &pBits->bits_buf[pBits->bits_written / 8] ) ) != IVAS_ERR_OK ) - { - return error; - } - - pBits->bits_written += 8 * lc3plusBitstreamSize; - pBits->codec = IVAS_SPLIT_REND_CODEC_LC3PLUS; - pBits->pose_correction = hSplitBin->multiBinPoseData.poseCorrectionMode; - pBits->codec_frame_size_ms = (int16_t) ( hSplitBin->hLc3plusEnc->config.lc3plus_frame_duration_us / 1000 ); - return IVAS_ERR_OK; -} - - -/*------------------------------------------------------------------------- - * Function ivas_renderMultiTDBinToSplitBinaural() - * - * - *------------------------------------------------------------------------*/ - -static ivas_error ivas_renderMultiTDBinToSplitBinaural( - SPLIT_REND_WRAPPER *hSplitBin, - const IVAS_QUATERNION headPosition, - const int32_t SplitRendBitRate, - const int16_t codec_frame_size_ms, - IVAS_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 ) -{ - ivas_error error; - int32_t bit_len, available_bits, target_md_bits, actual_md_bits; - 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; - - push_wmops( "ivas_renderMultiTDBinToSplitBinaural" ); - - error = IVAS_ERR_OK; - num_poses = hSplitBin->multiBinPoseData.num_poses; - - useLc3plus = hSplitBin->hLc3plusEnc != NULL; - - 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 ) - { - /* 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 ); - } - } - else - { - for ( i = 0; i < num_poses * BINAURAL_CHANNELS; ++i ) - { - in_delayed[i] = in[i]; - } - } - - actual_md_bits = pBits->bits_written; - if ( ( hSplitBin->multiBinPoseData.poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) || ( !useLc3plus && !pcm_out_flag ) ) - { - if ( !useLc3plus && codec_frame_size_ms != 20 && !pcm_out_flag ) - { - return IVAS_ERROR( IVAS_ERR_INVALID_INPUT_BUFFER_SIZE, "Unsupported framing for LCLD codec!" ); - } - num_cldfb_bands = hSplitBin->hCldfbHandles->cldfbAna[0]->no_channels; - - /* CLDFB Analysis*/ - for ( pos_idx = 0; pos_idx < num_poses; pos_idx++ ) - { -#ifdef SPLIT_POSE_CORRECTION_DEBUG - { - float *pOut[2]; - char fname[200] = "ref_out_pos"; - char tag[2]; - tag[0] = (char) ( '0' + pos_idx ); - tag[1] = '\0'; - strcat( fname, tag ); - strcat( fname, ".wav" ); - - pOut[0] = in_delayed[2 * pos_idx]; - pOut[1] = in_delayed[2 * pos_idx + 1]; - dbgwrite_wav( pOut, CLDFB_NO_COL_MAX * max_bands, fname, 48000, 2 ); - } - -#endif - for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) - { - for ( slot_idx = 0; slot_idx < CLDFB_NO_COL_MAX; 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] ); - } - } - } - } - - if ( hSplitBin->multiBinPoseData.poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) - { - target_md_bits = ivas_get_split_rend_md_target_brate( SplitRendBitRate, pcm_out_flag ) * L_FRAME48k / 48000; - - actual_md_bits = pBits->bits_written; - - ivas_rend_CldfbSplitPreRendProcess( hSplitBin->hBinHrSplitPreRend, headPosition, &hSplitBin->multiBinPoseData, Cldfb_In_BinReal, Cldfb_In_BinImag, pBits, target_md_bits, low_res_pre_rend_rot ); - } - - if ( pcm_out_flag == 0 ) - { - pBits->pose_correction = hSplitBin->multiBinPoseData.poseCorrectionMode; - pBits->codec = useLc3plus ? IVAS_SPLIT_REND_CODEC_LC3PLUS : IVAS_SPLIT_REND_CODEC_LCLD; - - if ( !useLc3plus ) - { - available_bits = SplitRendBitRate * L_FRAME48k / 48000; - actual_md_bits = pBits->bits_written - actual_md_bits; - available_bits -= actual_md_bits; - pBits->codec_frame_size_ms = 20; - - ivas_splitBinLCLDEncProcess( hSplitBin->hSplitBinLCLDEnc, Cldfb_In_BinReal, Cldfb_In_BinImag, available_bits, pBits ); - } - else - { - if ( ( error = splitRendLc3plusEncodeAndWrite( hSplitBin, pBits, SplitRendBitRate, in ) ) != IVAS_ERR_OK ) - { - return error; - } - } - } - else - { - pBits->pose_correction = hSplitBin->multiBinPoseData.poseCorrectionMode; - pBits->codec = IVAS_SPLIT_REND_CODEC_NONE; - } - - /*zero pad*/ - if ( pcm_out_flag ) - { - bit_len = SplitRendBitRate / FRAMES_PER_SEC; - } - else - { - if ( !useLc3plus ) - { - bit_len = SplitRendBitRate / FRAMES_PER_SEC; - } - else - { - bit_len = hSplitBin->hLc3plusEnc->config.ivas_frame_duration_us / 1000; - bit_len = SplitRendBitRate * bit_len / 1000; - } - } - - while ( pBits->bits_written < bit_len ) - { - ivas_split_rend_bitstream_write_int32( pBits, 0L, 1 ); - } - - pop_wmops(); - - return error; -} - - -/*------------------------------------------------------------------------- - * Function lc3plusTimeAlignCldfbPoseCorr() - * - * - *------------------------------------------------------------------------*/ - -static 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] ) -{ - 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; - - for ( pose = 0; pose < hSplitBin->multiBinPoseData.num_poses; ++pose ) - { - for ( ch = 0; ch < BINAURAL_CHANNELS; ++ch ) - { - bufRead = hSplitBin->lc3plusDelayBuffers[pose * BINAURAL_CHANNELS + ch]; - bufWrite = bufRead; - - /* Save last 2 columns for next frame */ - 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 ); - } - - /* Delay existing columns by 2 slots */ - /*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 ); - } - - /* Fill 2 first columns from buffer */ - 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; - } - - /* Copy last 2 columns to buffer */ - 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; - } - } - } - - return; -} - - -/*------------------------------------------------------------------------- - * Function ivas_renderMultiBinToSplitBinaural() - * - * - *------------------------------------------------------------------------*/ - -ivas_error ivas_renderMultiBinToSplitBinaural( - SPLIT_REND_WRAPPER *hSplitBin, - const IVAS_QUATERNION headPosition, - const int32_t SplitRendBitRate, - IVAS_SPLIT_REND_CODEC splitCodec, - int16_t codec_frame_size_ms, - IVAS_SPLIT_REND_BITS_HANDLE pBits, - float Cldfb_In_BinReal[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - float Cldfb_In_BinImag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - const int16_t max_bands, - float *output[], - const int16_t low_res_pre_rend_rot, - const int16_t cldfb_in_flag, - const int16_t pcm_out_flag ) -{ - ivas_error error; - int32_t bit_len, target_md_bits, actual_md_bits, available_bits; - - error = IVAS_ERR_OK; - push_wmops( "ivas_renderMultiBinToSplitBinaural" ); - - if ( hSplitBin->multiBinPoseData.poseCorrectionMode == IVAS_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 ); - } - - /* Needs to be done at runtime. If this was in another API function, - * there would be no guarantee that the user did not change - * the split rendering config before calling the main rendering function */ - if ( ( error = ivas_split_rend_choose_default_codec( &splitCodec, &codec_frame_size_ms, cldfb_in_flag, pcm_out_flag ) ) != IVAS_ERR_OK ) - { - return error; - } - - if ( 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 = ivas_renderMultiTDBinToSplitBinaural( hSplitBin, headPosition, SplitRendBitRate, codec_frame_size_ms, pBits, max_bands, output, low_res_pre_rend_rot, pcm_out_flag ); - - pop_wmops(); - return error; - } - - if ( splitCodec == IVAS_SPLIT_REND_CODEC_LC3PLUS && hSplitBin->multiBinPoseData.poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) - { - /* Time-align pose correction to delay of LC3plus */ - lc3plusTimeAlignCldfbPoseCorr( hSplitBin, Cldfb_In_BinReal, Cldfb_In_BinImag ); - } - - actual_md_bits = pBits->bits_written; - if ( hSplitBin->multiBinPoseData.poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) - { - target_md_bits = ivas_get_split_rend_md_target_brate( SplitRendBitRate, pcm_out_flag ) * L_FRAME48k / 48000; - - actual_md_bits = pBits->bits_written; - ivas_rend_CldfbSplitPreRendProcess( hSplitBin->hBinHrSplitPreRend, headPosition, &hSplitBin->multiBinPoseData, Cldfb_In_BinReal, Cldfb_In_BinImag, pBits, target_md_bits, low_res_pre_rend_rot ); - } - - if ( pcm_out_flag == 0 ) - { - pBits->codec = splitCodec; - pBits->pose_correction = hSplitBin->multiBinPoseData.poseCorrectionMode; - - if ( splitCodec == IVAS_SPLIT_REND_CODEC_LCLD ) - { - available_bits = SplitRendBitRate * L_FRAME48k / 48000; - actual_md_bits = pBits->bits_written - actual_md_bits; - available_bits -= actual_md_bits; - - ivas_splitBinLCLDEncProcess( hSplitBin->hSplitBinLCLDEnc, Cldfb_In_BinReal, Cldfb_In_BinImag, available_bits, pBits ); - } - else - { - int16_t ch, slot_idx; - - /* CLDFB synthesis of main pose */ - 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]; - - 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]; - } -#ifndef SPLIT_REND_WITH_HEAD_ROT - cldfbSynthesis( Cldfb_In_BinReal_p, Cldfb_In_BinImag_p, output[ch], hSplitBin->hCldfbHandles->cldfbAna[0]->no_channels * CLDFB_NO_COL_MAX, hSplitBin->hCldfbHandles->cldfbAna[ch] ); -#else - 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] ); -#endif - } - - if ( ( error = splitRendLc3plusEncodeAndWrite( hSplitBin, pBits, SplitRendBitRate, output ) ) != IVAS_ERR_OK ) - { - return error; - } - } - } - else - { - int16_t ch, slot_idx; - /* CLDFB synthesis of main pose */ - 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]; - - 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]; - } - -#ifndef SPLIT_REND_WITH_HEAD_ROT - cldfbSynthesis( Cldfb_In_BinReal_p, Cldfb_In_BinImag_p, output[ch], hSplitBin->hCldfbHandles->cldfbAna[0]->no_channels * CLDFB_NO_COL_MAX, hSplitBin->hCldfbHandles->cldfbAna[ch] ); -#else - 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] ); -#endif - } - - pBits->pose_correction = hSplitBin->multiBinPoseData.poseCorrectionMode; - pBits->codec = IVAS_SPLIT_REND_CODEC_NONE; - } - - /*zero pad*/ - /*TODO: do this inside the LCLD ENC codec */ - if ( pcm_out_flag ) - { - bit_len = SplitRendBitRate / FRAMES_PER_SEC; - } - else - { - if ( splitCodec == IVAS_SPLIT_REND_CODEC_LCLD ) - { - bit_len = SplitRendBitRate / FRAMES_PER_SEC; - } - else - { - bit_len = hSplitBin->hLc3plusEnc->config.ivas_frame_duration_us / 1000; - bit_len = SplitRendBitRate * bit_len / 1000; - } - } - - while ( pBits->bits_written < bit_len ) - { - ivas_split_rend_bitstream_write_int32( pBits, 0L, 1 ); - } - - pop_wmops(); - - return error; -} -#endif diff --git a/lib_rend/ivas_splitRenderer_utils.c b/lib_rend/ivas_splitRenderer_utils.c deleted file mode 100644 index daf6eb6f2..000000000 --- a/lib_rend/ivas_splitRenderer_utils.c +++ /dev/null @@ -1,1089 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2023 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. - -*******************************************************************************************************/ - -#include -#include "options.h" -#ifdef SPLIT_REND_WITH_HEAD_ROT -#include -#include "ivas_prot.h" -#include "prot.h" -#include "cnst.h" -#include "ivas_cnst.h" -#include "ivas_rom_rend.h" -#include "ivas_rom_com.h" -#include "ivas_rom_dec.h" -#include "ivas_rom_binauralRenderer.h" -#include "lib_rend.h" -#include "ivas_prot_rend.h" -#ifdef DEBUGGING -#include "debug.h" -#endif -#include "wmc_auto.h" - - -/*------------------------------------------------------------------------- - * Function ivas_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], - float in_im2[2][2], - float out_re2[2][2], - float out_im2[2][2] ) -{ - int16_t i, j; - float tmp_re, tmp_im; - - for ( i = 0; i < 2; i++ ) - { - for ( j = 0; j < 2; j++ ) - { - IVAS_CMULT_FLOAT( in_re1[i][0], in_im1[i][0], in_re2[0][j], in_im2[0][j], tmp_re, tmp_im ); - out_re2[i][j] = tmp_re; - out_im2[i][j] = tmp_im; - - IVAS_CMULT_FLOAT( in_re1[i][1], in_im1[i][1], in_re2[1][j], in_im2[1][j], tmp_re, tmp_im ); - out_re2[i][j] += tmp_re; - out_im2[i][j] += tmp_im; - } - } - - return; -} - - -/*------------------------------------------------------------------------- - * Function ivas_split_rend_bitstream_init() - * - * - *------------------------------------------------------------------------*/ - -void ivas_split_rend_bitstream_init( - IVAS_SPLIT_REND_BITS_HANDLE pBits, - const int32_t buf_len_bytes, - uint8_t *pbuf ) -{ - pBits->bits_buf = pbuf; - pBits->buf_len = buf_len_bytes; - pBits->bits_read = 0; - pBits->bits_written = 0; - - return; -} - - -/*------------------------------------------------------------------------- - * Function ivas_split_rend_huffman_dec_init_min_max_len() - * - * - *------------------------------------------------------------------------*/ - -void ivas_split_rend_huffman_dec_init_min_max_len( - ivas_split_rend_huffman_cfg_t *p_huff_cfg ) -{ - int16_t i, code_len; - const int32_t *codebook; - - codebook = p_huff_cfg->codebook; - - p_huff_cfg->min_len = p_huff_cfg->sym_len; - p_huff_cfg->max_len = 0; - - for ( i = 0; i < p_huff_cfg->sym_len; i++ ) - { - code_len = (int16_t) codebook[1]; - if ( p_huff_cfg->min_len > code_len ) - { - p_huff_cfg->min_len = code_len; - } - if ( p_huff_cfg->max_len < code_len ) - { - p_huff_cfg->max_len = code_len; - } - codebook = codebook + 3; - } - - return; -} - - -/*------------------------------------------------------------------------- - * Function is_idx_present() - * - * - *------------------------------------------------------------------------*/ - -static int16_t is_idx_present( - int16_t *idx_list, - const int16_t idx, - const int16_t len ) -{ - int16_t i; - - for ( i = 0; i < len; i++ ) - { - if ( idx_list[i] == idx ) - { - return 1; - } - } - - return 0; -} - - -/*------------------------------------------------------------------------- - * Function ivas_split_huff_get_idx_trav_list() - * - * - *------------------------------------------------------------------------*/ - -static void ivas_split_huff_get_idx_trav_list( - int16_t *idx_list, - ivas_split_rend_huffman_cfg_t *p_huff_cfg ) -{ - int16_t i, j, min_idx; - int32_t min_bits; - const int32_t *codebook; - - for ( i = 0; i < p_huff_cfg->sym_len; i++ ) - { - idx_list[i] = -1; - } - - for ( i = 0; i < p_huff_cfg->sym_len; i++ ) - { - codebook = p_huff_cfg->codebook; - min_bits = p_huff_cfg->max_len; - min_idx = -1; - for ( j = 0; j < p_huff_cfg->sym_len; j++ ) - { - if ( ( min_bits >= codebook[1] ) && ( is_idx_present( idx_list, j, i + 1 ) == 0 ) ) - { - min_bits = codebook[1]; - min_idx = j; - } - codebook += 3; - } - idx_list[i] = min_idx; - } - - return; -} - - -/*------------------------------------------------------------------------- - * Function ivas_split_rend_init_huff_cfg() - * - * - *------------------------------------------------------------------------*/ - -void ivas_split_rend_init_huff_cfg( - BIN_HR_SPLIT_REND_HUFF_HANDLE pHuff_cfg ) -{ - pHuff_cfg->pred[0].codebook = &ivas_split_rend_huff_pred31_consts[0][0]; - pHuff_cfg->pred[0].sym_len = IVAS_SPLIT_REND_PRED_31QUANT_PNTS; - ivas_split_rend_huffman_dec_init_min_max_len( &pHuff_cfg->pred[0] ); - ivas_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 ) ); - - pHuff_cfg->pred[1].codebook = &ivas_split_rend_huff_pred63_consts[0][0]; - pHuff_cfg->pred[1].sym_len = IVAS_SPLIT_REND_PRED_63QUANT_PNTS; - ivas_split_rend_huffman_dec_init_min_max_len( &pHuff_cfg->pred[1] ); - ivas_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 ) ); - - - pHuff_cfg->pred_roll.codebook = &ivas_split_rend_huff_roll_pred_consts[0][0]; - pHuff_cfg->pred_roll.sym_len = IVAS_SPLIT_REND_ROLL_PRED_QUANT_PNTS; - ivas_split_rend_huffman_dec_init_min_max_len( &pHuff_cfg->pred_roll ); - ivas_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 ) ); - - pHuff_cfg->gd.codebook = &ivas_split_rend_huff_d_consts[0][0]; - pHuff_cfg->gd.sym_len = IVAS_SPLIT_REND_D_QUANT_PNTS; - ivas_split_rend_huffman_dec_init_min_max_len( &pHuff_cfg->gd ); - ivas_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 ) ); - - pHuff_cfg->p_gd.codebook = &ivas_split_rend_huff_p_d_consts[0][0]; - pHuff_cfg->p_gd.sym_len = IVAS_SPLIT_REND_D_QUANT_PNTS; - ivas_split_rend_huffman_dec_init_min_max_len( &pHuff_cfg->p_gd ); - ivas_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 ) ); - - pHuff_cfg->p_gd_diff.codebook = &ivas_split_rend_huff_p_d_diff_consts[0][0]; - pHuff_cfg->p_gd_diff.sym_len = IVAS_SPLIT_REND_D_QUANT_PNTS; - ivas_split_rend_huffman_dec_init_min_max_len( &pHuff_cfg->p_gd_diff ); - 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 = (int16_t) ceilf( log2f( pHuff_cfg->p_gd_diff.sym_len ) ); - - return; -} - - -/*------------------------------------------------------------------------- - * Function set_fix_rotation_mat() - * - * - *------------------------------------------------------------------------*/ - -void set_fix_rotation_mat( - float fix_pos_rot_mat[][BINAURAL_CHANNELS][BINAURAL_CHANNELS], - MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData ) -{ - float yaw_a, cos_yaw, sin_yaw; - int16_t pos_idx; - yaw_a = 0.0f; - - for ( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses - 1; pos_idx++ ) - { - yaw_a = pMultiBinPoseData->relative_head_poses[pos_idx + 1][0]; - cos_yaw = cosf( EVS_PI * yaw_a / 180.0f ); - sin_yaw = sinf( EVS_PI * yaw_a / 180.0f ); - sin_yaw = 0.0f; - fix_pos_rot_mat[pos_idx][0][0] = cos_yaw; - fix_pos_rot_mat[pos_idx][1][1] = cos_yaw; - fix_pos_rot_mat[pos_idx][0][1] = sin_yaw; - fix_pos_rot_mat[pos_idx][1][0] = -1.0f * sin_yaw; - } - - return; -} - - -/*------------------------------------------------------------------------- - * Function set_pose_types() - * - * - *------------------------------------------------------------------------*/ - -void set_pose_types( - IVAS_SPLIT_REND_POSE_TYPE pose_type[MAX_HEAD_ROT_POSES - 1], - MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData ) -{ - int16_t pos_idx; - - for ( pos_idx = 0; pos_idx < pMultiBinPoseData->num_poses - 1; pos_idx++ ) - { - if ( fabs( pMultiBinPoseData->relative_head_poses[pos_idx + 1][0] ) > EPSILON ) - { - pose_type[pos_idx] = ANY_YAW; - } - else if ( fabs( pMultiBinPoseData->relative_head_poses[pos_idx + 1][2] ) > EPSILON ) - { - pose_type[pos_idx] = ANY_ROLL; - } - else - { - pose_type[pos_idx] = PITCH_ONLY; - } - } - - return; -} - - -/*------------------------------------------------------------------------- - * Function wrap_a() - * - * - *------------------------------------------------------------------------*/ - -int16_t wrap_a( - int16_t val, - const int16_t min_val, - const int16_t max_val ) -{ - if ( val < min_val ) - { - val = max_val - min_val + val + 1; - } - - if ( val > max_val ) - { - val = min_val + val - max_val - 1; - } - - return val; -} - - -/*------------------------------------------------------------------------- - * Function ivas_SplitRenderer_getdiagdiff() - * - * - *------------------------------------------------------------------------*/ - -void ivas_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 ) -{ - out_idx[0][0] = in_idx[0][0]; - out_idx[0][1] = in_idx[0][1]; - out_idx[1][1] = in_idx[1][1] + sign * out_idx[0][0]; - 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]; - out_idx[1][0] = wrap_a( out_idx[1][0], min_val, max_val ); - - return; -} - - -/*------------------------------------------------------------------------- - * Function ivas_split_rend_bitstream_read_int32() - * - * - *------------------------------------------------------------------------*/ - -int32_t ivas_split_rend_bitstream_read_int32( - IVAS_SPLIT_REND_BITS_HANDLE pBits, - const int32_t bits ) -{ - int32_t val, k, bit_val; - -#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG - assert( ( pBits->bits_written - pBits->bits_read ) >= bits ); - assert( bits <= 32 ); -#endif - - /* write bit by bit */ - val = 0; - for ( k = 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++; - } - - return val; -} - - -/*------------------------------------------------------------------------- - * Function ivas_split_rend_bitstream_write_int32() - * - * - *------------------------------------------------------------------------*/ - -void ivas_split_rend_bitstream_write_int32( - IVAS_SPLIT_REND_BITS_HANDLE pBits, - const int32_t val, - const int32_t bits ) -{ - int32_t mask, k; - -#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG - /*protection check*/ - if ( ( pBits->buf_len << 3 ) < ( pBits->bits_written + bits ) ) - { - assert( 0 ); - } -#endif - - mask = 1 << ( bits - 1 ); - /* write bit by bit */ - for ( k = 0; k < bits; k++ ) - { - if ( val & mask ) - { - pBits->bits_buf[pBits->bits_written >> 3] |= ( 1 << ( pBits->bits_written & 7 ) ); - } - else - { - pBits->bits_buf[pBits->bits_written >> 3] &= ~( 1 << ( pBits->bits_written & 7 ) ); - } - pBits->bits_written++; - mask >>= 1; - } - - return; -} - - -#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG -/*------------------------------------------------------------------------- - * ivas_mat_mult_2by2_complex() - * - * - *------------------------------------------------------------------------*/ - -void ivas_log_cldfb2wav_data( - float Cldfb_In_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - float Cldfb_In_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], - HANDLE_CLDFB_FILTER_BANK *cldfbSyn, - const int16_t num_chs, - const int16_t num_freq_bands, - const int32_t output_Fs, - const int16_t num_slots, - const int16_t start_slot_idx, - const char *filename ) -{ - float *RealBuffer[CLDFB_NO_COL_MAX]; - float *ImagBuffer[CLDFB_NO_COL_MAX]; - float pcm_out[BINAURAL_CHANNELS][L_FRAME48k]; - float *pPcm[BINAURAL_CHANNELS]; - float Cldfb_local_Real[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; - float Cldfb_local_Imag[BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; - int16_t sf, ch; - - assert( num_chs <= BINAURAL_CHANNELS ); - for ( ch = 0; ch < num_chs; ch++ ) - { - for ( sf = start_slot_idx; sf < start_slot_idx + num_slots; sf++ ) - { - mvr2r( Cldfb_In_Real[ch][sf], Cldfb_local_Real[ch][sf], num_freq_bands ); - mvr2r( Cldfb_In_Imag[ch][sf], Cldfb_local_Imag[ch][sf], num_freq_bands ); - RealBuffer[sf - start_slot_idx] = Cldfb_local_Real[ch][sf]; - ImagBuffer[sf - start_slot_idx] = Cldfb_local_Imag[ch][sf]; - } - cldfbSynthesis( RealBuffer, ImagBuffer, &( pcm_out[ch][0] ), num_freq_bands * num_slots, cldfbSyn[ch] ); - pPcm[ch] = pcm_out[ch]; - } - dbgwrite_wav( pPcm, num_freq_bands * num_slots, filename, output_Fs, num_chs ); - - return; -} -#endif - - -/*------------------------------------------------------------------------- - * Function ivas_get_split_rend_md_target_brate() - * - * - *------------------------------------------------------------------------*/ - -int32_t ivas_get_split_rend_md_target_brate( - const int32_t SplitRendBitRate, - const int16_t pcm_out_flag ) -{ - int32_t md_bitrate; - - if ( pcm_out_flag == 1 ) - { - md_bitrate = SplitRendBitRate; - } - else - { - switch ( SplitRendBitRate ) - { - case SPLIT_REND_768k: - { - md_bitrate = 256000; - break; - } - case SPLIT_REND_512k: - { - md_bitrate = 128000; - break; - } - case SPLIT_REND_384k: - { - md_bitrate = 128000; - break; - } - default: - { - return -1; - } - } - } - - return md_bitrate; -} - - -/*------------------------------------------------------------------------- - * Function ivas_get_lcld_bitrate() - * - * - *------------------------------------------------------------------------*/ - -int32_t ivas_get_lcld_bitrate( - const int32_t SplitRendBitRate, - const IVAS_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode ) -{ - if ( poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) - { - switch ( SplitRendBitRate ) - { - case SPLIT_REND_768k: - { - return IVAS_512k; - } - case SPLIT_REND_512k: - { - return IVAS_384k; - } - case SPLIT_REND_384k: - { - return IVAS_256k; - } - default: - { - assert( 0 ); - } - } - } - else - { - return SplitRendBitRate; - } - - return -1; -} - - -/*------------------------------------------------------------------------- - * Function ivas_get_lc3plus_bitrate() - * - * - *------------------------------------------------------------------------*/ - -int32_t ivas_get_lc3plus_bitrate( - const int32_t SplitRendBitRate, - IVAS_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode, - const int16_t split_prerender_frame_size_ms ) -{ - if ( poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) - { - int32_t inBandMdBps = (int32_t) ( 8 * 1000 / split_prerender_frame_size_ms ); - return ivas_get_lcld_bitrate( SplitRendBitRate, poseCorrectionMode ) - inBandMdBps; - } - - if ( poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) - { - return SplitRendBitRate; - } - - /* Should not be reached */ - assert( 0 ); - return -1; -} - - -/*------------------------------------------------------------------------- - * Function ivas_get_lc3plus_bitrate_id() - * - * - *------------------------------------------------------------------------*/ - -int8_t ivas_get_lc3plus_bitrate_id( - const int32_t SplitRendBitRate ) -{ - switch ( SplitRendBitRate ) - { - case SPLIT_REND_768k: - { - return 4; - } - case SPLIT_REND_512k: - { - return 3; - } - case SPLIT_REND_384k: - { - return 2; - } - case SPLIT_REND_320k: - { - return 1; - } - case SPLIT_REND_256k: - { - return 0; - } - default: - { - break; - } - } - - return -1; -} - - -/*------------------------------------------------------------------------- - * Function ivas_mat_mult_2by2_complex() - * - * - *------------------------------------------------------------------------*/ - -int32_t ivas_get_lc3plus_size_from_id( - const int8_t SplitRendBitRateId, - const IVAS_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode, - const int16_t split_prerender_frame_size_ms ) -{ - int32_t bitrate; - - switch ( SplitRendBitRateId ) - { - case 4: - { - bitrate = SPLIT_REND_768k; - break; - } - case 3: - { - bitrate = SPLIT_REND_512k; - break; - } - case 2: - { - bitrate = SPLIT_REND_384k; - break; - } - case 1: - { - bitrate = SPLIT_REND_320k; - break; - } - case 0: - { - bitrate = SPLIT_REND_256k; - break; - } - default: - { - bitrate = -1; - break; - } - } - - bitrate = ivas_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 ); -} - - -/*------------------------------------------------------------------------- - * Function ivas_split_rend_validate_config() - * - * - *------------------------------------------------------------------------*/ - -ivas_error ivas_split_rend_validate_config( - const IVAS_SPLIT_REND_CONFIG_DATA *pSplitRendConfig, - const int16_t is_pcm_out ) -{ - /* Valid DOF range is 0-3 */ - if ( pSplitRendConfig->dof < 0 || 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 != IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB && 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 == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE && pSplitRendConfig->dof != 0 ) || - ( pSplitRendConfig->poseCorrectionMode != IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE && 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 ( pSplitRendConfig->codec == IVAS_SPLIT_REND_CODEC_LCLD && pSplitRendConfig->codec_frame_size_ms != 20 ) - { - return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "Invalid framing for LCLD codec" ); - } - - if ( pSplitRendConfig->codec == IVAS_SPLIT_REND_CODEC_LC3PLUS && ( pSplitRendConfig->codec_frame_size_ms != 5 && 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 ) - { - switch ( pSplitRendConfig->splitRendBitRate ) - { - case SPLIT_REND_256k: - if ( 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; - case SPLIT_REND_320k: - /* Only valid with 0 DOF */ - if ( 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; - case SPLIT_REND_384k: - case SPLIT_REND_512k: - /* Always valid */ - break; - case SPLIT_REND_768k: - if ( pSplitRendConfig->dof == 0 && pSplitRendConfig->codec == IVAS_SPLIT_REND_CODEC_LC3PLUS ) - { - return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "Bitrate is too high for LC3plus with 0 DOF" ); - } - break; - default: - return IVAS_ERR_LC3PLUS_INVALID_BITRATE; - } - } - else - { - if ( pSplitRendConfig->dof == 1 ) - { - if ( pSplitRendConfig->splitRendBitRate < 50000 ) - { - return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "1DOF metadata needs atleast 50 kbps" ); - } - } - else if ( pSplitRendConfig->dof == 2 ) - { - if ( pSplitRendConfig->splitRendBitRate < 66000 ) - { - return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "2DOF metadata needs atleast 66 kbps" ); - } - } - else if ( pSplitRendConfig->dof == 3 ) - { - if ( pSplitRendConfig->splitRendBitRate < 128000 ) - { - return IVAS_ERROR( IVAS_ERR_INVALID_SPLIT_REND_CONFIG, "3DOF metadata needs atleast 128 kbps" ); - } - } - } - - return IVAS_ERR_OK; -} - - -/*------------------------------------------------------------------------- - * Function ivas_split_rend_get_quant_params() - * - * - *------------------------------------------------------------------------*/ - -void ivas_split_rend_get_quant_params( - const int16_t num_md_bands, - int16_t pred_real_bands_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], - int16_t pred_imag_bands_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], - int16_t pred_quant_pnts_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], - float pred_quantstep_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], - float pred_1byquantstep_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], - int16_t d_bands_yaw[IVAS_SPLIT_REND_NUM_QUANT_STRATS], - int16_t bands_pitch[IVAS_SPLIT_REND_NUM_QUANT_STRATS], - int16_t pred_real_bands_roll[IVAS_SPLIT_REND_NUM_QUANT_STRATS], - int16_t pred_imag_bands_roll[IVAS_SPLIT_REND_NUM_QUANT_STRATS], - int16_t *num_quant_strats, - int16_t *num_complex_bands ) -{ - int16_t q; - - *num_quant_strats = IVAS_SPLIT_REND_NUM_QUANT_STRATS; - *num_complex_bands = COMPLEX_MD_BAND_THRESH_LOW; - assert( *num_complex_bands <= num_md_bands ); - - pred_quant_pnts_yaw[0] = IVAS_SPLIT_REND_PRED_63QUANT_PNTS; - pred_quantstep_yaw[0] = IVAS_SPLIT_REND_PRED63_Q_STEP; - pred_1byquantstep_yaw[0] = IVAS_SPLIT_REND_PRED63_1BYQ_STEP; - for ( q = 1; q < *num_quant_strats; q++ ) - { - pred_quant_pnts_yaw[q] = IVAS_SPLIT_REND_PRED_31QUANT_PNTS; - pred_quantstep_yaw[q] = IVAS_SPLIT_REND_PRED31_Q_STEP; - pred_1byquantstep_yaw[q] = IVAS_SPLIT_REND_PRED31_1BYQ_STEP; - } - - for ( q = 0; q < *num_quant_strats; q++ ) - { - pred_real_bands_yaw[q] = num_md_bands; - pred_real_bands_roll[q] = num_md_bands; - } - pred_imag_bands_yaw[0] = num_md_bands; - pred_imag_bands_roll[0] = num_md_bands; - pred_imag_bands_yaw[1] = num_md_bands; - pred_imag_bands_roll[1] = num_md_bands; - - 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_roll[q] = *num_complex_bands; - } - - for ( q = 0; q < *num_quant_strats; q++ ) - { - d_bands_yaw[q] = 0; - bands_pitch[q] = num_md_bands; - } - - return; -} - - -/*------------------------------------------------------------------------- - * Function ivas_renderSplitGetMultiBinPoseData() - * - * - *------------------------------------------------------------------------*/ - -void ivas_renderSplitGetMultiBinPoseData( - const IVAS_SPLIT_REND_CONFIG_DATA *pSplit_rend_config, - MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, - const IVAS_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; - - 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; - } - - /* 0 DOF defaults */ - num_yaw_poses = 0; - num_pitch_poses = 0; - num_roll_poses = 0; - - /* defaults for all DOF except 3DOF HQ */ - relative_yaw_angles = ivas_split_rend_relative_yaw_pos_angles_hq; - relative_pitch_angles = ivas_split_rend_relative_pitch_pos_angles_hq; - relative_roll_angles = ivas_split_rend_relative_roll_pos_angles_hq; - - if ( pSplit_rend_config->dof == 1 ) - { - switch ( rot_axis ) - { - case DEFAULT_AXIS: - case YAW: - { - num_yaw_poses = SPLIT_REND_MAX_YAW_ONLY_POSES; - break; - } - case PITCH: - { - num_pitch_poses = SPLIT_REND_MAX_PITCH_ONLY_POSES; - break; - } - case ROLL: - { - num_roll_poses = SPLIT_REND_MAX_ROLL_ONLY_POSES; - break; - } - default: - { - assert( 0 && "unsupported rotation axis value" ); - } - } - } - else if ( pSplit_rend_config->dof == 2 ) - { - switch ( rot_axis ) - { - case DEFAULT_AXIS: - case YAW: - case PITCH: - case YAW_PITCH: - { - num_yaw_poses = SPLIT_REND_MAX_YAW_ONLY_POSES; - num_pitch_poses = SPLIT_REND_MAX_PITCH_ONLY_POSES; - break; - } - case ROLL: - case YAW_ROLL: - { - num_yaw_poses = SPLIT_REND_MAX_YAW_ONLY_POSES; - num_roll_poses = SPLIT_REND_MAX_ROLL_ONLY_POSES; - break; - } - case PITCH_ROLL: - { - num_pitch_poses = SPLIT_REND_MAX_PITCH_ONLY_POSES; - num_roll_poses = SPLIT_REND_MAX_ROLL_ONLY_POSES; - break; - } - default: - { - assert( 0 && "unsupported rotation axis value" ); - } - } - } - else if ( pSplit_rend_config->dof == 3 ) - { - if ( pSplit_rend_config->hq_mode == 1 ) - { - relative_yaw_angles = ivas_split_rend_relative_yaw_pos_angles_hq; - relative_pitch_angles = ivas_split_rend_relative_pitch_pos_angles_hq; - relative_roll_angles = ivas_split_rend_relative_roll_pos_angles_hq; - num_yaw_poses = SPLIT_REND_MAX_YAW_ONLY_POSES; - num_pitch_poses = SPLIT_REND_MAX_PITCH_ONLY_POSES; - num_roll_poses = SPLIT_REND_MAX_ROLL_ONLY_POSES; - } - else - { - relative_yaw_angles = ivas_split_rend_relative_yaw_pos_angles; - relative_pitch_angles = ivas_split_rend_relative_pitch_pos_angles; - relative_roll_angles = ivas_split_rend_relative_roll_pos_angles; - num_yaw_poses = SPLIT_REND_MAX_YAW_ONLY_POSES; - num_pitch_poses = 1; - num_roll_poses = 1; - } - } - - pMultiBinPoseData->num_poses = num_yaw_poses + num_pitch_poses + num_roll_poses + 1; - assert( pMultiBinPoseData->num_poses <= MAX_HEAD_ROT_POSES ); - - for ( pos_idx = 0; pos_idx < num_yaw_poses; pos_idx++ ) - { - pMultiBinPoseData->relative_head_poses[pos_idx + 1][0] = relative_yaw_angles[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]; - } - - 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->dof = pSplit_rend_config->dof; - pMultiBinPoseData->hq_mode = pSplit_rend_config->hq_mode; - pMultiBinPoseData->rot_axis = rot_axis; - pMultiBinPoseData->poseCorrectionMode = pSplit_rend_config->poseCorrectionMode; - - return; -} - - -/*------------------------------------------------------------------------- - * Function ivas_renderSplitUpdateNoCorrectionPoseData() - * - * - *------------------------------------------------------------------------*/ - -void ivas_renderSplitUpdateNoCorrectionPoseData( - const IVAS_SPLIT_REND_CONFIG_DATA *pSplit_rend_config, - MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData ) -{ - pMultiBinPoseData->num_poses = 1; - assert( pSplit_rend_config->dof == 0 ); - pMultiBinPoseData->dof = pSplit_rend_config->dof; - assert( pSplit_rend_config->poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE ); - pMultiBinPoseData->poseCorrectionMode = pSplit_rend_config->poseCorrectionMode; - - return; -} - - -/*------------------------------------------------------------------------- - * Function ivas_init_multi_bin_pose_data() - * - * - *------------------------------------------------------------------------*/ - -void ivas_init_multi_bin_pose_data( - MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData ) -{ - int16_t 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->num_poses = 1; - pMultiBinPoseData->dof = 3; - pMultiBinPoseData->hq_mode = 0; - pMultiBinPoseData->rot_axis = DEFAULT_AXIS; - - return; -} - - -/*------------------------------------------------------------------------- - * Function ivas_split_rend_choose_default_codec() - * - * - *------------------------------------------------------------------------*/ - -ivas_error ivas_split_rend_choose_default_codec( - IVAS_SPLIT_REND_CODEC *pCodec, /* i/o: pointer to codec setting */ - 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 */ -) -{ - if ( pcm_out_flag == 0 ) - { - if ( *pCodec == IVAS_SPLIT_REND_CODEC_DEFAULT ) - { - *pCodec = cldfb_in_flag ? IVAS_SPLIT_REND_CODEC_LCLD : IVAS_SPLIT_REND_CODEC_LC3PLUS; - } - } - else - { - *pCodec = IVAS_SPLIT_REND_CODEC_NONE; - } - - if ( *pCodec_frame_size_ms == 0 ) /* codec frame size hasn't been set yet - use default for current configuration */ - { - switch ( *pCodec ) - { - case IVAS_SPLIT_REND_CODEC_LCLD: - *pCodec_frame_size_ms = 20; - break; - case IVAS_SPLIT_REND_CODEC_LC3PLUS: - case IVAS_SPLIT_REND_CODEC_NONE: - *pCodec_frame_size_ms = 5; - break; - default: - return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Unknown split codec value" ); - } - } - - return IVAS_ERR_OK; -} -#endif diff --git a/lib_rend/ivas_stat_rend.h b/lib_rend/ivas_stat_rend.h index ccd6641b5..a8dd46e57 100644 --- a/lib_rend/ivas_stat_rend.h +++ b/lib_rend/ivas_stat_rend.h @@ -39,12 +39,7 @@ #include "ivas_stat_com.h" // note: needed for DIRAC_DEC_BIN_HANDLE until #156 is solved #include "stat_com.h" /* Note: Currently needed for CLDFB. */ #include "common_api_types.h" -#ifdef SPLIT_REND_WITH_HEAD_ROT -#include "stat_com.h" -#include "ivas_lcld_prot.h" -#include "ivas_lc3plus_enc.h" -#include "ivas_lc3plus_dec.h" -#endif +#include "isar_stat.h" /*----------------------------------------------------------------------------------* @@ -655,7 +650,7 @@ typedef struct IVAS_VECTOR3 Pos[MAX_PARAM_SPATIAL_SUBFRAMES]; float crossfade[L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES]; #ifdef SPLIT_REND_WITH_HEAD_ROT - IVAS_SPLIT_REND_ROT_AXIS sr_pose_pred_axis; + ISAR_SPLIT_REND_ROT_AXIS sr_pose_pred_axis; #endif ivas_orient_trk_state_t *hOrientationTracker; @@ -679,7 +674,7 @@ typedef struct ivas_binaural_head_track_struct ivas_orient_trk_state_t *OrientationTracker; #ifdef SPLIT_REND_WITH_HEAD_ROT - IVAS_SPLIT_REND_ROT_AXIS sr_pose_pred_axis; + ISAR_SPLIT_REND_ROT_AXIS sr_pose_pred_axis; #endif } HEAD_TRACK_DATA, *HEAD_TRACK_DATA_HANDLE; @@ -728,7 +723,7 @@ typedef struct ivas_combined_orientation_struct int16_t shd_rot_max_order; IVAS_VECTOR3 listenerPos[MAX_PARAM_SPATIAL_SUBFRAMES]; #ifdef SPLIT_REND_WITH_HEAD_ROT - IVAS_SPLIT_REND_ROT_AXIS sr_pose_pred_axis; + ISAR_SPLIT_REND_ROT_AXIS sr_pose_pred_axis; int16_t sr_low_res_flag; #endif IVAS_QUATERNION Quaternion_frozen_ext; @@ -1356,38 +1351,23 @@ typedef struct ivas_split_rend_huffman_cfg_t typedef struct ivas_binaural_head_rot_split_rendering_huff_struct { ivas_split_rend_huffman_cfg_t pred[2]; - int16_t pred_idx_trav[2][IVAS_SPLIT_REND_PRED_63QUANT_PNTS]; + int16_t pred_idx_trav[2][ISAR_SPLIT_REND_PRED_63QUANT_PNTS]; int16_t pred_base2_code_len[2]; ivas_split_rend_huffman_cfg_t pred_roll; - int16_t pred_roll_idx_trav[IVAS_SPLIT_REND_ROLL_PRED_QUANT_PNTS]; + int16_t pred_roll_idx_trav[ISAR_SPLIT_REND_ROLL_PRED_QUANT_PNTS]; int16_t pred_roll_base2_code_len; ivas_split_rend_huffman_cfg_t gd; int16_t gd_base2_code_len; - int16_t gd_idx_trav[IVAS_SPLIT_REND_D_QUANT_PNTS]; + int16_t gd_idx_trav[ISAR_SPLIT_REND_D_QUANT_PNTS]; ivas_split_rend_huffman_cfg_t p_gd; int16_t p_gd_base2_code_len; - int16_t p_gd_idx_trav[IVAS_SPLIT_REND_D_QUANT_PNTS]; + int16_t p_gd_idx_trav[ISAR_SPLIT_REND_D_QUANT_PNTS]; ivas_split_rend_huffman_cfg_t p_gd_diff; int16_t p_gd_diff_base2_code_len; - int16_t p_gd_diff_idx_trav[IVAS_SPLIT_REND_D_QUANT_PNTS]; + int16_t p_gd_diff_idx_trav[ISAR_SPLIT_REND_D_QUANT_PNTS]; } BIN_HR_SPLIT_REND_HUFF, *BIN_HR_SPLIT_REND_HUFF_HANDLE; -typedef struct ivas_binaural_head_rot_split_pre_rendering_struct -{ - BIN_HR_SPLIT_REND_MD rot_md[MAX_HEAD_ROT_POSES - 1][MAX_SPLIT_MD_SUBFRAMES][MAX_SPLIT_REND_MD_BANDS]; - float fix_pos_rot_mat[MAX_HEAD_ROT_POSES - 1][BINAURAL_CHANNELS][BINAURAL_CHANNELS]; - IVAS_SPLIT_REND_POSE_TYPE pose_type[MAX_HEAD_ROT_POSES - 1]; - BIN_HR_SPLIT_REND_HUFF huff_cfg; -#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG - HANDLE_CLDFB_FILTER_BANK cldfbSynRotBinDec[MAX_HEAD_ROT_POSES + 1][BINAURAL_CHANNELS]; -#endif - -#ifdef SPLIT_POSE_CORRECTION_DEBUG - BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend; -#endif - -} BIN_HR_SPLIT_PRE_REND, *BIN_HR_SPLIT_PRE_REND_HANDLE; typedef struct ivas_binaural_head_rot_split_post_rendering_struct { @@ -1396,7 +1376,7 @@ typedef struct ivas_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]; - IVAS_SPLIT_REND_POSE_TYPE pose_type[MAX_HEAD_ROT_POSES - 1]; + ISAR_SPLIT_REND_POSE_TYPE pose_type[MAX_HEAD_ROT_POSES - 1]; 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]; @@ -1416,6 +1396,22 @@ typedef struct ivas_binaural_head_rot_split_post_rendering_struct } BIN_HR_SPLIT_POST_REND, *BIN_HR_SPLIT_POST_REND_HANDLE; +typedef struct ivas_binaural_head_rot_split_pre_rendering_struct +{ + BIN_HR_SPLIT_REND_MD rot_md[MAX_HEAD_ROT_POSES - 1][MAX_SPLIT_MD_SUBFRAMES][MAX_SPLIT_REND_MD_BANDS]; + 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]; + BIN_HR_SPLIT_REND_HUFF huff_cfg; +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + HANDLE_CLDFB_FILTER_BANK cldfbSynRotBinDec[MAX_HEAD_ROT_POSES + 1][BINAURAL_CHANNELS]; +#endif + +#ifdef SPLIT_POSE_CORRECTION_DEBUG + BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend; +#endif + +} BIN_HR_SPLIT_PRE_REND, *BIN_HR_SPLIT_PRE_REND_HANDLE; + typedef struct ivas_binaural_head_rot_split_rendering_lcld_enc_struct { void *pLcld_enc; @@ -1427,6 +1423,8 @@ typedef struct ivas_binaural_head_rot_split_rendering_lcld_enc_struct FILE *cldfbIn; int16_t numFrame; #endif + int16_t iNumIterations; + int16_t iNumBlocks; } BIN_HR_SPLIT_LCLD_ENC, *BIN_HR_SPLIT_LCLD_ENC_HANDLE; @@ -1434,10 +1432,7 @@ 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]; -#if CLDFB_PLC_XF > 0 float xf_bet[2][CLDFB_NO_CHANNELS_MAX][CLDFB_PLC_XF]; -#endif - } CLDFB_PLC, *CLDFB_PLC_HANDLE; typedef struct @@ -1445,6 +1440,7 @@ typedef struct CLDFB_PLC CldfbPLC_state; int16_t prev_bfi; int16_t bf_count; + int16_t iNumSubSets; } SPLIT_REND_PLC_STRUCT, *SPLIT_REND_PLC_HANDLE; @@ -1460,53 +1456,11 @@ typedef struct ivas_binaural_head_rot_split_rendering_lcld_dec_struct int16_t numFrame; #endif SPLIT_REND_PLC_HANDLE hSplitRendPLC; + int16_t iNumBlocks; + int16_t iNumIterations; } BIN_HR_SPLIT_LCLD_DEC, *BIN_HR_SPLIT_LCLD_DEC_HANDLE; -typedef struct -{ -#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG - HANDLE_CLDFB_FILTER_BANK cldfbAna[( 1 + MAX_HEAD_ROT_POSES ) * BINAURAL_CHANNELS]; -#else - HANDLE_CLDFB_FILTER_BANK cldfbAna[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS]; -#endif - HANDLE_CLDFB_FILTER_BANK cldfbSyn[BINAURAL_CHANNELS]; - -} CLDFB_HANDLES_WRAPPER, *CLDFB_HANDLES_WRAPPER_HANDLE; - -typedef struct -{ - int16_t num_poses; - float relative_head_poses[MAX_HEAD_ROT_POSES][3]; - int16_t dof; - int16_t hq_mode; - IVAS_SPLIT_REND_ROT_AXIS rot_axis; - IVAS_SPLIT_REND_POSE_CORRECTION_MODE poseCorrectionMode; - -} MULTI_BIN_REND_POSE_DATA; - -typedef struct -{ - MULTI_BIN_REND_POSE_DATA multiBinPoseData; - BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend; - BIN_HR_SPLIT_LCLD_ENC_HANDLE hSplitBinLCLDEnc; - CLDFB_HANDLES_WRAPPER_HANDLE hCldfbHandles; - IVAS_LC3PLUS_ENC_HANDLE hLc3plusEnc; - BINAURAL_TD_OBJECT_RENDERER_HANDLE hTdRendHandles[MAX_HEAD_ROT_POSES - 1]; - float *lc3plusDelayBuffers[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS]; /* Used to time-align head pose correction metadata with LC3plus-coded reference audio */ - int32_t lc3plusDelaySamples; - -} SPLIT_REND_WRAPPER; - -typedef struct -{ - MULTI_BIN_REND_POSE_DATA multiBinPoseData; - BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend; - BIN_HR_SPLIT_LCLD_DEC_HANDLE hSplitBinLCLDDec; - int16_t first_good_frame_received; - IVAS_LC3PLUS_DEC_HANDLE hLc3plusDec; - -} SPLIT_POST_REND_WRAPPER; #endif diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index be74abaed..ba8fd3207 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -35,6 +35,9 @@ #include "prot.h" #include "ivas_prot.h" #include "ivas_prot_rend.h" +#include "isar_prot.h" +#include "isar_stat.h" +#include "lib_isar_pre_rend.h" #include "ivas_cnst.h" #include "ivas_rom_com.h" #include "ivas_rom_rend.h" @@ -48,29 +51,9 @@ * Local constants *-------------------------------------------------------------------*/ -/* Maximum buffer length (per channel) in samples. - * Keep this separate from L_FRAME48k in case we want to support different size later */ -#define MAX_BUFFER_LENGTH_PER_CHANNEL ( L_FRAME48k ) -#ifdef SPLIT_REND_WITH_HEAD_ROT -#define MAX_CLDFB_BUFFER_LENGTH_PER_CHANNEL ( MAX_BUFFER_LENGTH_PER_CHANNEL * 2 ) -#endif - -/* Maximum buffer length (total) in samples. */ /* Maximum buffer length (total) in samples. */ -#ifdef SPLIT_REND_WITH_HEAD_ROT -#define MAX_BUFFER_LENGTH ( MAX_BUFFER_LENGTH_PER_CHANNEL * MAX_INPUT_CHANNELS ) -#define MAX_CLDFB_BUFFER_LENGTH ( MAX_CLDFB_BUFFER_LENGTH_PER_CHANNEL * MAX_INPUT_CHANNELS ) -#define MAX_BIN_BUFFER_LENGTH ( MAX_BUFFER_LENGTH_PER_CHANNEL * BINAURAL_CHANNELS ) -#define MAX_CLDFB_BIN_BUFFER_LENGTH ( MAX_CLDFB_BUFFER_LENGTH_PER_CHANNEL * BINAURAL_CHANNELS ) -#else -#define MAX_BUFFER_LENGTH ( MAX_BUFFER_LENGTH_PER_CHANNEL * MAX_INPUT_CHANNELS ) -#endif - -#define MAX_BIN_DELAY_SAMPLES 50 /* Maximum supported rendering latency for binaural IRs */ - -/* Frame size required when rendering to binaural */ -#define BINAURAL_RENDERING_FRAME_SIZE_MS 5 - +#define MAX_BUFFER_LENGTH ( MAX_BUFFER_LENGTH_PER_CHANNEL * MAX_INPUT_CHANNELS ) +#define MAX_BIN_DELAY_SAMPLES 150 /* Maximum supported rendering latency for binaural IRs */ /*-------------------------------------------------------------------* * Local types @@ -201,18 +184,6 @@ typedef struct DIRAC_ANA_HANDLE hDirAC; } input_sba; -#ifdef SPLIT_REND_WITH_HEAD_ROT -typedef struct -{ - input_base base; - SPLIT_POST_REND_WRAPPER splitPostRendWrapper; - float *bufferData; - int16_t numCachedSamples; /* Number of decoded samples in bufferData that have not yet been played out */ - IVAS_REND_BitstreamBuffer *hBits; -} input_split_post_rend; -#endif - - typedef struct { input_base base; @@ -236,9 +207,6 @@ struct IVAS_REND input_mc inputsMc[RENDERER_MAX_MC_INPUTS]; input_sba inputsSba[RENDERER_MAX_SBA_INPUTS]; input_masa inputsMasa[RENDERER_MAX_MASA_INPUTS]; -#ifdef SPLIT_REND_WITH_HEAD_ROT - input_split_post_rend inputsSplitPost[RENDERER_MAX_BIN_INPUTS]; -#endif AUDIO_CONFIG inputConfig; AUDIO_CONFIG outputConfig; @@ -271,6 +239,20 @@ struct IVAS_REND static ivas_error initMasaExtRenderer( input_masa *inputMasa, const AUDIO_CONFIG outConfig ); static void freeMasaExtRenderer( MASA_EXT_REND_HANDLE *hMasaExtRendOut ); +#ifdef SPLIT_REND_WITH_HEAD_ROT +static ivas_error renderSbaToMultiBinauralCldfb( + input_sba *sbaInput, + 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 low_res_pre_rend_rot, + const int16_t num_subframes ); + +static ivas_error renderSbaToMultiBinaural( + input_sba *sbaInput, + const AUDIO_CONFIG outConfig, + float out[][L_FRAME48k] ); +#endif + /*-------------------------------------------------------------------* * Local functions *-------------------------------------------------------------------*/ @@ -345,7 +327,7 @@ static float *getSmplPtr( #ifdef SPLIT_REND_WITH_HEAD_ROT static void convertBitsBufferToInternalBitsBuff( const IVAS_REND_BitstreamBuffer outBits, - IVAS_SPLIT_REND_BITS_HANDLE hBits ) + ISAR_SPLIT_REND_BITS_HANDLE hBits ) { hBits->bits_buf = outBits.bits; hBits->bits_read = outBits.config.bitsRead; @@ -360,7 +342,7 @@ static void convertBitsBufferToInternalBitsBuff( static void convertInternalBitsBuffToBitsBuffer( IVAS_REND_BitstreamBuffer *hOutBits, - const IVAS_SPLIT_REND_BITS_DATA bits ) + const ISAR_SPLIT_REND_BITS_DATA bits ) { hOutBits->bits = bits.bits_buf; hOutBits->config.bitsRead = bits.bits_read; @@ -2608,35 +2590,6 @@ static ivas_error initSbaPanGainsForSbaOut( } -#ifdef SPLIT_REND_WITH_HEAD_ROT -static ivas_error updateSplitPostRendPanGains( - input_split_post_rend *inputSplitPostRend, - const AUDIO_CONFIG outConfig, - RENDER_CONFIG_DATA *hRendCfg ) -{ - ivas_error error; - rendering_context rendCtx; - int16_t numOutChannels; - - if ( ( error = getAudioConfigNumChannels( outConfig, &numOutChannels ) ) != IVAS_ERR_OK ) - { - - return error; - } - - rendCtx = inputSplitPostRend->base.ctx; - ivas_renderSplitGetMultiBinPoseData( &hRendCfg->split_rend_config, &inputSplitPostRend->splitPostRendWrapper.multiBinPoseData, rendCtx.pHeadRotData->sr_pose_pred_axis ); - - if ( ( error = ivas_splitBinPostRendOpen( &inputSplitPostRend->splitPostRendWrapper.hBinHrSplitPostRend, &inputSplitPostRend->splitPostRendWrapper.multiBinPoseData, *rendCtx.pOutSampleRate ) ) != IVAS_ERR_OK ) - { - return error; - } - - return IVAS_ERR_OK; -} -#endif - - static ivas_error updateSbaPanGains( input_sba *inputSba, const AUDIO_CONFIG outConfig, @@ -2667,7 +2620,7 @@ static ivas_error updateSbaPanGains( case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED: case IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM: { - if ( hRendCfg->split_rend_config.rendererSelection == IVAS_SPLIT_REND_RENDERER_SELECTION_FASTCONV ) + if ( hRendCfg->split_rend_config.rendererSelection == ISAR_SPLIT_REND_RENDERER_SELECTION_FASTCONV ) { assert( inConfig == IVAS_AUDIO_CONFIG_HOA3 && ( *rendCtx.pOutSampleRate == 48000 ) && "split binaural fast conv mode is currently supported with HOA3 input and 48k sampling rate only" ); @@ -2689,7 +2642,7 @@ static ivas_error updateSbaPanGains( #endif case IVAS_AUDIO_CONFIG_BINAURAL: #ifdef SPLIT_REND_WITH_HEAD_ROT - if ( hRendCfg->split_rend_config.rendererSelection == IVAS_SPLIT_REND_RENDERER_SELECTION_FASTCONV ) + if ( hRendCfg->split_rend_config.rendererSelection == ISAR_SPLIT_REND_RENDERER_SELECTION_FASTCONV ) { if ( ( error = ivas_rend_openCldfbRend( &inputSba->cldfbRendWrapper, inConfig, outConfig, &rendCtx.pSplitRendWrapper->multiBinPoseData, *rendCtx.pOutSampleRate ) ) != IVAS_ERR_OK ) { @@ -2747,40 +2700,6 @@ static ivas_error updateSbaPanGains( } -#ifdef SPLIT_REND_WITH_HEAD_ROT -static ivas_error setRendInputActiveSplitPostRend( - void *input, - const AUDIO_CONFIG inConfig, - const IVAS_REND_InputId id, - RENDER_CONFIG_DATA *hRendCfg ) -{ - ivas_error error; - rendering_context rendCtx; - AUDIO_CONFIG outConfig; - input_split_post_rend *inputSplitPostRend; - - inputSplitPostRend = (input_split_post_rend *) input; - rendCtx = inputSplitPostRend->base.ctx; - outConfig = *rendCtx.pOutConfig; - - if ( ( error = allocateInputBaseBufferData( &inputSplitPostRend->bufferData, MAX_CLDFB_BIN_BUFFER_LENGTH ) ) != IVAS_ERR_OK ) - { - return error; - } - - initRendInputBase( &inputSplitPostRend->base, inConfig, id, rendCtx, inputSplitPostRend->bufferData, MAX_CLDFB_BIN_BUFFER_LENGTH ); - inputSplitPostRend->numCachedSamples = 0; - - if ( ( error = updateSplitPostRendPanGains( inputSplitPostRend, outConfig, hRendCfg ) ) != IVAS_ERR_OK ) - { - return error; - } - - return IVAS_ERR_OK; -} -#endif - - static ivas_error initSbaMasaRendering( input_sba *inputSba, int32_t inSampleRate ) @@ -2871,38 +2790,6 @@ static ivas_error setRendInputActiveSba( } -#ifdef SPLIT_REND_WITH_HEAD_ROT -static void clearInputSplitRend( - input_split_post_rend *inputSplitRend ) -{ - rendering_context rendCtx; - - rendCtx = inputSplitRend->base.ctx; - - freeInputBaseBufferData( &inputSplitRend->bufferData ); - - initRendInputBase( &inputSplitRend->base, IVAS_AUDIO_CONFIG_INVALID, 0, rendCtx, NULL, 0 ); - - if ( inputSplitRend->splitPostRendWrapper.hBinHrSplitPostRend != NULL ) - { - ivas_splitBinPostRendClose( &inputSplitRend->splitPostRendWrapper.hBinHrSplitPostRend ); - } - - if ( inputSplitRend->splitPostRendWrapper.hSplitBinLCLDDec != NULL ) - { - ivas_splitBinLCLDDecClose( &inputSplitRend->splitPostRendWrapper.hSplitBinLCLDDec ); - } - - if ( inputSplitRend->splitPostRendWrapper.hLc3plusDec != NULL ) - { - IVAS_LC3PLUS_DEC_Close( &inputSplitRend->splitPostRendWrapper.hLc3plusDec ); - } - - return; -} -#endif /* SPLIT_REND_WITH_HEAD_ROT */ - - static void clearInputSba( input_sba *inputSba ) { @@ -3005,63 +2892,6 @@ static void clearInputMasa( } -#ifdef SPLIT_REND_WITH_HEAD_ROT -static ivas_error initSplitRend( - SPLIT_REND_WRAPPER *pSplitRendWrapper, - IVAS_REND_AudioBuffer *pSplitRendEncBuffer, - const IVAS_SPLIT_REND_CONFIG_DATA *pSplit_rend_config, - IVAS_REND_HeadRotData headRotData, - const int32_t outputSampleRate, - const AUDIO_CONFIG outConfig, - const int16_t cldfb_in_flag, - const int16_t is_5ms_frame ) -{ - ivas_error error; - IVAS_REND_AudioBufferConfig bufConfig; - - if ( outConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || outConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) - { - if ( pSplit_rend_config->poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) - { - ivas_renderSplitGetMultiBinPoseData( pSplit_rend_config, &pSplitRendWrapper->multiBinPoseData, headRotData.sr_pose_pred_axis ); - } - else if ( pSplit_rend_config->poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) - { - ivas_renderSplitUpdateNoCorrectionPoseData( pSplit_rend_config, &pSplitRendWrapper->multiBinPoseData ); - } - - if ( ( error = ivas_split_renderer_open( pSplitRendWrapper, pSplit_rend_config, outputSampleRate, cldfb_in_flag, outConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM, is_5ms_frame ) ) != IVAS_ERR_OK ) - { - return error; - } - - /*allocate for CLDFB in and change to TD during process if needed*/ - bufConfig.numSamplesPerChannel = MAX_CLDFB_BUFFER_LENGTH_PER_CHANNEL; - bufConfig.numChannels = BINAURAL_CHANNELS * pSplitRendWrapper->multiBinPoseData.num_poses; - bufConfig.is_cldfb = 1; - pSplitRendEncBuffer->config = bufConfig; - - if ( ( pSplitRendEncBuffer->data = malloc( bufConfig.numChannels * bufConfig.numSamplesPerChannel * sizeof( float ) ) ) == NULL ) - { - return IVAS_ERR_FAILED_ALLOC; - } - } - else - { - IVAS_REND_AudioBufferConfig bufConfig2; - - bufConfig2.numSamplesPerChannel = 0; - bufConfig2.numChannels = 0; - bufConfig2.is_cldfb = 0; - pSplitRendEncBuffer->config = bufConfig2; - pSplitRendEncBuffer->data = NULL; - } - - return IVAS_ERR_OK; -} -#endif - - /*------------------------------------------------------------------------- * IVAS_REND_Open() * @@ -3155,7 +2985,7 @@ ivas_error IVAS_REND_Open( /* Initialize inputs */ #ifdef SPLIT_REND_WITH_HEAD_ROT - ivas_init_split_rend_handles( &hIvasRend->splitRendWrapper ); + isar_init_split_rend_handles( &hIvasRend->splitRendWrapper ); hIvasRend->splitRendEncBuffer.data = NULL; #endif @@ -3224,19 +3054,6 @@ ivas_error IVAS_REND_Open( hIvasRend->inputsMasa[i].hMasaExtRend = NULL; } -#ifdef SPLIT_REND_WITH_HEAD_ROT - for ( i = 0; i < RENDERER_MAX_BIN_INPUTS; ++i ) - { - initRendInputBase( &hIvasRend->inputsSplitPost[i].base, IVAS_AUDIO_CONFIG_INVALID, 0, getRendCtx( hIvasRend ), NULL, 0 ); - - ivas_init_split_post_rend_handles( &hIvasRend->inputsSplitPost[i].splitPostRendWrapper ); - -#ifdef SPLIT_REND_WITH_HEAD_ROT - hIvasRend->splitRendBFI = 0; -#endif - hIvasRend->inputsSplitPost[i].bufferData = NULL; - } -#endif return IVAS_ERR_OK; } @@ -3487,15 +3304,6 @@ static ivas_error getInputById( } pInputBase = &hIvasRend->inputsMasa[inputIndex].base; break; -#ifdef SPLIT_REND_WITH_HEAD_ROT - case IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL: - if ( inputIndex > RENDERER_MAX_BIN_INPUTS ) - { - return IVAS_ERR_INVALID_INPUT_ID; - } - pInputBase = &hIvasRend->inputsSplitPost[inputIndex].base; - break; -#endif default: return IVAS_ERR_INVALID_INPUT_ID; } @@ -3561,15 +3369,6 @@ static ivas_error getConstInputById( } pInputBase = &hIvasRend->inputsMasa[inputIndex].base; break; -#ifdef SPLIT_REND_WITH_HEAD_ROT - case IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL: - if ( inputIndex > RENDERER_MAX_BIN_INPUTS ) - { - return IVAS_ERR_INVALID_INPUT_ID; - } - pInputBase = &hIvasRend->inputsSplitPost[inputIndex].base; - break; -#endif default: return IVAS_ERR_INVALID_INPUT_ID; } @@ -3662,7 +3461,7 @@ static int16_t getCldfbRendFlag( { isCldfbRend = 0; } - else if ( ( numMasaInputs > 0 ) || ( numSbaInputs > 0 && hIvasRend->hRendererConfig->split_rend_config.rendererSelection == IVAS_SPLIT_REND_RENDERER_SELECTION_FASTCONV ) ) + else if ( ( numMasaInputs > 0 ) || ( numSbaInputs > 0 && hIvasRend->hRendererConfig->split_rend_config.rendererSelection == ISAR_SPLIT_REND_RENDERER_SELECTION_FASTCONV ) ) { isCldfbRend = 1; } @@ -3671,24 +3470,66 @@ static int16_t getCldfbRendFlag( return isCldfbRend; } +/*------------------------------------------------------------------------- + * Function ivas_pre_rend_init() + * + * + *------------------------------------------------------------------------*/ -static void closeSplitRend( +static ivas_error ivas_pre_rend_init( SPLIT_REND_WRAPPER *pSplitRendWrapper, - IVAS_REND_AudioBuffer *pSplitRendEncBuffer ) + IVAS_REND_AudioBuffer *pSplitRendEncBuffer, + ISAR_SPLIT_REND_CONFIG_DATA *pSplit_rend_config, + IVAS_REND_HeadRotData headRotData, + const int32_t outputSampleRate, + const AUDIO_CONFIG outConfig, + const int16_t cldfb_in_flag, + const int16_t num_subframes ) { - ivas_split_renderer_close( pSplitRendWrapper ); + ivas_error error; + IVAS_REND_AudioBufferConfig bufConfig; - if ( pSplitRendEncBuffer->data != NULL ) + if ( outConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || outConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) { - free( pSplitRendEncBuffer->data ); - pSplitRendEncBuffer->data = NULL; + if ( pSplit_rend_config->poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) + { + ISAR_PRE_REND_GetMultiBinPoseData( pSplit_rend_config, &pSplitRendWrapper->multiBinPoseData, headRotData.sr_pose_pred_axis ); + } + else if ( pSplit_rend_config->poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) + { + isar_renderSplitUpdateNoCorrectionPoseData( pSplit_rend_config, &pSplitRendWrapper->multiBinPoseData ); + } + + if ( ( error = ISAR_PRE_REND_open( pSplitRendWrapper, pSplit_rend_config, outputSampleRate, cldfb_in_flag, outConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM, num_subframes, 0 ) ) != IVAS_ERR_OK ) + { + return error; + } + + /*allocate for CLDFB in and change to TD during process if needed*/ + bufConfig.numSamplesPerChannel = MAX_CLDFB_BUFFER_LENGTH_PER_CHANNEL; + bufConfig.numChannels = BINAURAL_CHANNELS * pSplitRendWrapper->multiBinPoseData.num_poses; + bufConfig.is_cldfb = 1; + pSplitRendEncBuffer->config = bufConfig; + + if ( ( pSplitRendEncBuffer->data = malloc( bufConfig.numChannels * bufConfig.numSamplesPerChannel * sizeof( float ) ) ) == NULL ) + { + return IVAS_ERR_FAILED_ALLOC; + } } + else + { + IVAS_REND_AudioBufferConfig bufConfig2; - pSplitRendEncBuffer->config.numChannels = 0; - pSplitRendEncBuffer->config.numSamplesPerChannel = 0; + bufConfig2.numSamplesPerChannel = 0; + bufConfig2.numChannels = 0; + bufConfig2.is_cldfb = 0; + pSplitRendEncBuffer->config = bufConfig2; + pSplitRendEncBuffer->data = NULL; + } - return; + return IVAS_ERR_OK; } + #endif @@ -3723,12 +3564,7 @@ ivas_error IVAS_REND_AddInput( int16_t cldfb_in_flag; cldfb_in_flag = getCldfbRendFlag( hIvasRend, getAudioConfigType( inConfig ) ); - if ( ( error = ivas_split_rend_choose_default_codec( &hIvasRend->hRendererConfig->split_rend_config.codec, &hIvasRend->hRendererConfig->split_rend_config.codec_frame_size_ms, cldfb_in_flag, hIvasRend->outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) != IVAS_ERR_OK ) - { - return error; - } - - if ( ( error = initSplitRend( &hIvasRend->splitRendWrapper, &hIvasRend->splitRendEncBuffer, &hIvasRend->hRendererConfig->split_rend_config, hIvasRend->headRotData, hIvasRend->sampleRateOut, hIvasRend->outputConfig, cldfb_in_flag, ( hIvasRend->num_subframes == 1 ) ? 1 : 0 ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_pre_rend_init( &hIvasRend->splitRendWrapper, &hIvasRend->splitRendEncBuffer, &hIvasRend->hRendererConfig->split_rend_config, hIvasRend->headRotData, hIvasRend->sampleRateOut, hIvasRend->outputConfig, cldfb_in_flag, hIvasRend->num_subframes ) ) != IVAS_ERR_OK ) { return error; } @@ -3761,14 +3597,6 @@ ivas_error IVAS_REND_AddInput( inputStructSize = sizeof( *hIvasRend->inputsMasa ); activateInput = setRendInputActiveMasa; break; -#ifdef SPLIT_REND_WITH_HEAD_ROT - case IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL: - maxNumInputsOfType = RENDERER_MAX_BIN_INPUTS; - inputsArray = hIvasRend->inputsSplitPost; - inputStructSize = sizeof( *hIvasRend->inputsSplitPost ); - activateInput = setRendInputActiveSplitPostRend; - break; -#endif default: return IVAS_ERR_INVALID_INPUT_FORMAT; } @@ -4032,11 +3860,6 @@ ivas_error IVAS_REND_RemoveInput( case IVAS_REND_AUDIO_CONFIG_TYPE_MASA: clearInputMasa( (input_masa *) inputBase ); break; -#ifdef SPLIT_REND_WITH_HEAD_ROT - case IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL: - clearInputSplitRend( (input_split_post_rend *) inputBase ); - break; -#endif default: return IVAS_ERR_INVALID_INPUT_FORMAT; } @@ -4162,7 +3985,7 @@ ivas_error IVAS_REND_GetDelay( #ifdef SPLIT_REND_WITH_HEAD_ROT if ( hIvasRend->splitRendWrapper.hBinHrSplitPreRend != NULL ) { - if ( hIvasRend->hRendererConfig->split_rend_config.rendererSelection == IVAS_SPLIT_REND_RENDERER_SELECTION_FASTCONV ) + if ( hIvasRend->hRendererConfig->split_rend_config.rendererSelection == ISAR_SPLIT_REND_RENDERER_SELECTION_FASTCONV ) { latency_ns = hIvasRend->inputsSba[i].cldfbRendWrapper.binaural_latency_ns; } @@ -4187,27 +4010,6 @@ ivas_error IVAS_REND_GetDelay( } } -#ifdef SPLIT_REND_WITH_HEAD_ROT - 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; - IVAS_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 == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) - { - latency_ns += IVAS_FB_DEC_DELAY_NS; - } - max_latency_ns = max( max_latency_ns, latency_ns ); - } - } -#endif - for ( i = 0; i < RENDERER_MAX_MASA_INPUTS; i++ ) { if ( hIvasRend->inputsMasa[i].base.inConfig != IVAS_AUDIO_CONFIG_INVALID ) @@ -4513,10 +4315,16 @@ int16_t IVAS_REND_GetRenderConfig( hRCout->split_rend_config.dof = 3; hRCout->split_rend_config.hq_mode = 0; hRCout->split_rend_config.codec_delay_ms = 0; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + hRCout->split_rend_config.isar_frame_size_ms = 20; +#endif hRCout->split_rend_config.codec_frame_size_ms = 0; /* 0 means "use default for selected codec" */ - hRCout->split_rend_config.codec = IVAS_SPLIT_REND_CODEC_DEFAULT; - hRCout->split_rend_config.poseCorrectionMode = IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB; + hRCout->split_rend_config.codec = ISAR_SPLIT_REND_CODEC_DEFAULT; + hRCout->split_rend_config.poseCorrectionMode = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB; hRCout->split_rend_config.rendererSelection = hRCin->split_rend_config.rendererSelection; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + hRCout->split_rend_config.lc3plus_highres = 0; +#endif #endif hRCout->roomAcoustics.use_er = hRCin->roomAcoustics.use_er; @@ -4576,12 +4384,12 @@ int16_t IVAS_REND_FeedRenderConfig( /* Overwrite any pose correction settings if 0 DOF (no pose correction) was selected */ if ( hRenderConfig->split_rend_config.dof == 0 ) { - hRenderConfig->split_rend_config.poseCorrectionMode = IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE; + hRenderConfig->split_rend_config.poseCorrectionMode = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE; } hRenderConfig->split_rend_config.codec = renderConfig.split_rend_config.codec; - if ( ( error = ivas_split_rend_validate_config( &hRenderConfig->split_rend_config, ( hIvasRend->outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0 ) ) != IVAS_ERR_OK ) + if ( ( error = isar_split_rend_validate_config( &hRenderConfig->split_rend_config, ( hIvasRend->outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0 ) ) != IVAS_ERR_OK ) { return error; } @@ -4592,14 +4400,9 @@ int16_t IVAS_REND_FeedRenderConfig( { int16_t cldfb_in_flag; cldfb_in_flag = getCldfbRendFlag( hIvasRend, IVAS_REND_AUDIO_CONFIG_TYPE_UNKNOWN ); - closeSplitRend( &hIvasRend->splitRendWrapper, &hIvasRend->splitRendEncBuffer ); - - if ( ( error = ivas_split_rend_choose_default_codec( &hIvasRend->hRendererConfig->split_rend_config.codec, &hIvasRend->hRendererConfig->split_rend_config.codec_frame_size_ms, cldfb_in_flag, hIvasRend->outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ) != IVAS_ERR_OK ) - { - return error; - } + ISAR_PRE_REND_close( &hIvasRend->splitRendWrapper, &hIvasRend->splitRendEncBuffer ); - if ( ( error = initSplitRend( &hIvasRend->splitRendWrapper, &hIvasRend->splitRendEncBuffer, &hIvasRend->hRendererConfig->split_rend_config, hIvasRend->headRotData, hIvasRend->sampleRateOut, hIvasRend->outputConfig, cldfb_in_flag, ( hIvasRend->num_subframes == 1 ) ? 1 : 0 ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_pre_rend_init( &hIvasRend->splitRendWrapper, &hIvasRend->splitRendEncBuffer, &hIvasRend->hRendererConfig->split_rend_config, hIvasRend->headRotData, hIvasRend->sampleRateOut, hIvasRend->outputConfig, cldfb_in_flag, hIvasRend->num_subframes ) ) != IVAS_ERR_OK ) { return error; } @@ -4610,44 +4413,8 @@ int16_t IVAS_REND_FeedRenderConfig( } -#ifdef SPLIT_REND_WITH_HEAD_ROT /*-------------------------------------------------------------------* - * IVAS_REND_FeedSplitBinauralBitstream() - * - * - *-------------------------------------------------------------------*/ - -ivas_error IVAS_REND_FeedSplitBinauralBitstream( - IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ - const IVAS_REND_InputId inputId, /* i : ID of the input */ - IVAS_REND_BitstreamBuffer *hBits /* i : buffer for input bitstream */ -) -{ - ivas_error error; - input_base *inputBase; - input_split_post_rend *inputSplitPostRend; - - /* Validate function arguments */ - if ( hIvasRend == NULL || hBits == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } - - if ( ( error = getInputById( hIvasRend, inputId, (void **) &inputBase ) ) != IVAS_ERR_OK ) - { - return error; - } - - inputSplitPostRend = (input_split_post_rend *) inputBase; - inputSplitPostRend->hBits = hBits; - - return IVAS_ERR_OK; -} -#endif - - -/*-------------------------------------------------------------------* - * IVAS_REND_SetHeadRotation() + * IVAS_REND_SetHeadRotation() * * *-------------------------------------------------------------------*/ @@ -4657,7 +4424,7 @@ ivas_error IVAS_REND_SetHeadRotation( const IVAS_QUATERNION headRot, /* i : head orientations for next rendering call */ const IVAS_VECTOR3 Pos, /* i : listener positions for next rendering call */ #ifdef SPLIT_REND_WITH_HEAD_ROT - const IVAS_SPLIT_REND_ROT_AXIS rot_axis, /* i : external control for rotation axis for split rendering */ + const ISAR_SPLIT_REND_ROT_AXIS rot_axis, /* i : external control for rotation axis for split rendering */ #endif const int16_t sf_idx /* i : subframe index */ ) @@ -5370,32 +5137,22 @@ static ivas_error renderIsmToBinaural( return IVAS_ERR_OK; } - +#ifdef SPLIT_REND_WITH_HEAD_ROT static int16_t getNumSubframesInBuffer( const IVAS_REND_AudioBuffer *buffer, const int32_t sampleRate ) { -#ifdef SPLIT_REND_WITH_HEAD_ROT int16_t cldfb2tdSampleFact; cldfb2tdSampleFact = buffer->config.is_cldfb ? 2 : 1; -#endif #ifdef DEBUGGING -#ifdef SPLIT_REND_WITH_HEAD_ROT assert( buffer->config.numSamplesPerChannel % ( sampleRate / FRAMES_PER_SEC / MAX_PARAM_SPATIAL_SUBFRAMES * cldfb2tdSampleFact ) == 0 ); -#else - assert( buffer->config.numSamplesPerChannel % ( sampleRate / FRAMES_PER_SEC / MAX_PARAM_SPATIAL_SUBFRAMES ) == 0 ); -#endif #endif -#ifdef SPLIT_REND_WITH_HEAD_ROT return (int16_t) ( buffer->config.numSamplesPerChannel / ( sampleRate / FRAMES_PER_SEC / MAX_PARAM_SPATIAL_SUBFRAMES * cldfb2tdSampleFact ) ); -#else - return (int16_t) ( buffer->config.numSamplesPerChannel / ( sampleRate / FRAMES_PER_SEC / MAX_PARAM_SPATIAL_SUBFRAMES ) ); -#endif } - +#endif static ivas_error renderIsmToBinauralRoom( input_ism *ismInput, @@ -5544,13 +5301,11 @@ static ivas_error renderIsmToBinauralRoom( /* render 7_1_4 with BRIRs */ #ifdef SPLIT_REND_WITH_HEAD_ROT - if ( ( error = ivas_rend_crendProcess( ismInput->crendWrapper, IVAS_AUDIO_CONFIG_7_1_4, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR, - NULL, NULL, NULL, NULL, p_tmpRendBuffer, *ismInput->base.ctx.pOutSampleRate, - getNumSubframesInBuffer( &outAudio, *ismInput->base.ctx.pOutSampleRate ), 0 ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_rend_crendProcessSubframe( ismInput->crendWrapper, IVAS_AUDIO_CONFIG_7_1_4, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR, NULL, NULL, + NULL, NULL, NULL, p_tmpRendBuffer, p_tmpRendBuffer, ismInput->base.inputBuffer.config.numSamplesPerChannel, *ismInput->base.ctx.pOutSampleRate, 0 ) ) != IVAS_ERR_OK ) #else - if ( ( error = ivas_rend_crendProcess( ismInput->crendWrapper, IVAS_AUDIO_CONFIG_7_1_4, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR, - NULL, NULL, NULL, NULL, p_tmpRendBuffer, *ismInput->base.ctx.pOutSampleRate, - getNumSubframesInBuffer( &outAudio, *ismInput->base.ctx.pOutSampleRate ) ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_rend_crendProcessSubframe( ismInput->crendWrapper, IVAS_AUDIO_CONFIG_7_1_4, IVAS_AUDIO_CONFIG_BINAURAL_ROOM_IR, NULL, NULL, + NULL, NULL, NULL, p_tmpRendBuffer, p_tmpRendBuffer, ismInput->base.inputBuffer.config.numSamplesPerChannel, *ismInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) #endif { @@ -5760,7 +5515,7 @@ static ivas_error renderIsmToSplitBinaural( pCombinedOrientationData = *ismInput->base.ctx.pCombinedOrientationData; - if ( pMultiBinPoseData->poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) + if ( pMultiBinPoseData->poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) { for ( i = 1; i < pCombinedOrientationData->num_subframes; ++i ) { @@ -6123,11 +5878,11 @@ static ivas_error renderMcToBinaural( /* call CREND */ #ifdef SPLIT_REND_WITH_HEAD_ROT - if ( ( error = ivas_rend_crendProcess( mcInput->crendWrapper, mcInput->base.inConfig, outConfig, NULL, NULL, NULL, NULL, p_tmpRendBuffer, *mcInput->base.ctx.pOutSampleRate, - getNumSubframesInBuffer( &outAudio, *mcInput->base.ctx.pOutSampleRate ), 0 ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_rend_crendProcessSubframe( mcInput->crendWrapper, mcInput->base.inConfig, outConfig, NULL, NULL, + NULL, NULL, NULL, p_tmpRendBuffer, p_tmpRendBuffer, mcInput->base.inputBuffer.config.numSamplesPerChannel, *mcInput->base.ctx.pOutSampleRate, 0 ) ) != IVAS_ERR_OK ) #else - if ( ( error = ivas_rend_crendProcess( mcInput->crendWrapper, mcInput->base.inConfig, outConfig, NULL, NULL, NULL, NULL, p_tmpRendBuffer, *mcInput->base.ctx.pOutSampleRate, - getNumSubframesInBuffer( &outAudio, *mcInput->base.ctx.pOutSampleRate ) ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_rend_crendProcessSubframe( mcInput->crendWrapper, mcInput->base.inConfig, outConfig, NULL, NULL, + NULL, NULL, NULL, p_tmpRendBuffer, p_tmpRendBuffer, mcInput->base.inputBuffer.config.numSamplesPerChannel, *mcInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) #endif { return error; @@ -6228,11 +5983,11 @@ static ivas_error renderMcToBinauralRoom( /* call CREND */ #ifdef SPLIT_REND_WITH_HEAD_ROT - if ( ( error = ivas_rend_crendProcess( mcInput->crendWrapper, mcInput->base.inConfig, outConfig, NULL, NULL, NULL, NULL, p_tmpRendBuffer, *mcInput->base.ctx.pOutSampleRate, - getNumSubframesInBuffer( &outAudio, *mcInput->base.ctx.pOutSampleRate ), 0 ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_rend_crendProcessSubframe( mcInput->crendWrapper, mcInput->base.inConfig, outConfig, NULL, NULL, + NULL, NULL, NULL, p_tmpRendBuffer, p_tmpRendBuffer, mcInput->base.inputBuffer.config.numSamplesPerChannel, *mcInput->base.ctx.pOutSampleRate, 0 ) ) != IVAS_ERR_OK ) #else - if ( ( error = ivas_rend_crendProcess( mcInput->crendWrapper, mcInput->base.inConfig, outConfig, NULL, NULL, NULL, NULL, p_tmpRendBuffer, *mcInput->base.ctx.pOutSampleRate, - getNumSubframesInBuffer( &outAudio, *mcInput->base.ctx.pOutSampleRate ) ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_rend_crendProcessSubframe( mcInput->crendWrapper, mcInput->base.inConfig, outConfig, NULL, NULL, + NULL, NULL, NULL, p_tmpRendBuffer, p_tmpRendBuffer, mcInput->base.inputBuffer.config.numSamplesPerChannel, *mcInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) #endif { return error; @@ -6334,11 +6089,11 @@ static ivas_error renderMcCustomLsToBinauralRoom( /* call CREND */ #ifdef SPLIT_REND_WITH_HEAD_ROT - if ( ( error = ivas_rend_crendProcess( mcInput->crendWrapper, IVAS_AUDIO_CONFIG_7_1_4, outConfig, NULL, NULL, NULL, NULL, - p_tmpCrendBuffer, *mcInput->base.ctx.pOutSampleRate, getNumSubframesInBuffer( &outAudio, *mcInput->base.ctx.pOutSampleRate ), 0 ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_rend_crendProcessSubframe( mcInput->crendWrapper, IVAS_AUDIO_CONFIG_7_1_4, outConfig, NULL, NULL, + NULL, NULL, NULL, p_tmpCrendBuffer, p_tmpCrendBuffer, mcInput->base.inputBuffer.config.numSamplesPerChannel, *mcInput->base.ctx.pOutSampleRate, 0 ) ) != IVAS_ERR_OK ) #else - if ( ( error = ivas_rend_crendProcess( mcInput->crendWrapper, IVAS_AUDIO_CONFIG_7_1_4, outConfig, NULL, NULL, NULL, NULL, - p_tmpCrendBuffer, *mcInput->base.ctx.pOutSampleRate, getNumSubframesInBuffer( &outAudio, *mcInput->base.ctx.pOutSampleRate ) ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_rend_crendProcessSubframe( mcInput->crendWrapper, IVAS_AUDIO_CONFIG_7_1_4, outConfig, NULL, NULL, + NULL, NULL, NULL, p_tmpCrendBuffer, p_tmpCrendBuffer, mcInput->base.inputBuffer.config.numSamplesPerChannel, *mcInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) #endif { return error; @@ -6459,7 +6214,7 @@ static ivas_error renderMcToSplitBinaural( /* save current head positions */ pCombinedOrientationDataLocal = *mcInput->base.ctx.pCombinedOrientationData; combinedOrientationDataLocal = *pCombinedOrientationDataLocal; - if ( pMultiBinPoseData->poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) + if ( pMultiBinPoseData->poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) { for ( sf = 1; sf < combinedOrientationDataLocal.num_subframes; ++sf ) { @@ -6535,7 +6290,7 @@ static ivas_error renderMcToSplitBinaural( /* copy input for in-place rotation */ - mvr2r( mcInput->base.inputBuffer.data, tmpRotBuffer.data, tmpRotBuffer.config.numChannels * tmpRotBuffer.config.numSamplesPerChannel ); + set_zero( tmpRotBuffer.data, tmpRotBuffer.config.numSamplesPerChannel * tmpRotBuffer.config.numChannels ); /* perform rotation in source format to tmpRotBuffer */ pCombinedOrientationDataLocal = &combinedOrientationDataLocal; @@ -6547,7 +6302,8 @@ static ivas_error renderMcToSplitBinaural( copyBufferTo2dArray( tmpRotBuffer, tmpRendBuffer ); /* call CREND (rotation already performed) */ - if ( ( error = ivas_rend_crendProcess( mcInput->crendWrapper, mcInput->base.inConfig, outConfig, NULL, NULL, NULL, NULL, p_tmpRendBuffer, *mcInput->base.ctx.pOutSampleRate, getNumSubframesInBuffer( &mcInput->base.inputBuffer, *mcInput->base.ctx.pOutSampleRate ), pos_idx ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_rend_crendProcessSubframe( mcInput->crendWrapper, mcInput->base.inConfig, outConfig, NULL, NULL, + NULL, NULL, NULL, p_tmpRendBuffer, p_tmpRendBuffer, mcInput->base.inputBuffer.config.numSamplesPerChannel, *mcInput->base.ctx.pOutSampleRate, pos_idx ) ) != IVAS_ERR_OK ) { return error; } @@ -6571,13 +6327,13 @@ static ivas_error renderMcToSplitBinaural( free( tmpRotBuffer.data ); } + accumulate2dArrayToBuffer( tmpSplitBinauralBuffer, &outAudio ); + if ( ( error = renderLfeToBinaural( mcInput, outConfig, outAudio ) ) != IVAS_ERR_OK ) { return error; } - accumulate2dArrayToBuffer( tmpSplitBinauralBuffer, &outAudio ); - pop_wmops(); return IVAS_ERR_OK; } @@ -6720,301 +6476,6 @@ static void renderSbaToSba( } #ifdef SPLIT_REND_WITH_HEAD_ROT -static ivas_error splitBinLc3plusDecode( - SPLIT_POST_REND_WRAPPER *hSplitBin, - IVAS_SPLIT_REND_BITS_HANDLE bits, - float outputBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k], - IVAS_SPLIT_REND_POSE_CORRECTION_MODE pose_correction ) -{ - ivas_error error; - float *channel_ptrs[MAX_HEAD_ROT_POSES * 2]; - int32_t lc3plusBitrateId, lc3plusBitstreamSize; - - push_wmops( "splitBinLc3plusDecode" ); - assert( hSplitBin->hLc3plusDec != NULL ); - - /* Find next byte boundary */ - while ( bits->bits_read % 8 != 0 ) - { - ++bits->bits_read; - } - /* Read LC3plus bitstream size info */ - lc3plusBitrateId = ivas_split_rend_bitstream_read_int32( bits, 8 ); - lc3plusBitstreamSize = ivas_get_lc3plus_size_from_id( (int8_t) lc3plusBitrateId, pose_correction, (int16_t) ( hSplitBin->hLc3plusDec->config.ivas_frame_duration_us / 1000 ) ); - - for ( int16_t i = 0; i < BINAURAL_CHANNELS * hSplitBin->multiBinPoseData.num_poses; ++i ) - { - channel_ptrs[i] = outputBuffer[i]; - } - - if ( ( error = IVAS_LC3PLUS_DEC_Decode( hSplitBin->hLc3plusDec, &bits->bits_buf[bits->bits_read / 8], lc3plusBitstreamSize, channel_ptrs ) ) != IVAS_ERR_OK ) - { - return error; - } - - pop_wmops(); - return IVAS_ERR_OK; -} - - -static ivas_error renderSplitBinauralWithPostRot( - input_split_post_rend *splitBinInput, - IVAS_REND_AudioBuffer outAudio, - const int16_t SplitRendBFI ) -{ - 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]; - 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]; - IVAS_QUATERNION QuaternionsPost[MAX_PARAM_SPATIAL_SUBFRAMES]; - int16_t sf_idx, ch_idx; - IVAS_SPLIT_REND_BITS_DATA bits; - float tmpCrendBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; - float tmpCrendBuffer_sf[BINAURAL_CHANNELS][L_FRAME48k]; - COMBINED_ORIENTATION_HANDLE pCombinedOrientationData; - 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; - - isPostRendInputCldfb = 0; - push_wmops( "renderSplitBinauralWithPostRot" ); - error = IVAS_ERR_OK; - - pCombinedOrientationData = *splitBinInput->base.ctx.pCombinedOrientationData; - hSplitBin = &splitBinInput->splitPostRendWrapper; - convertBitsBufferToInternalBitsBuff( *splitBinInput->hBits, &bits ); - - if ( bits.codec == IVAS_SPLIT_REND_CODEC_LCLD && splitBinInput->splitPostRendWrapper.hSplitBinLCLDDec == NULL ) - { - if ( ( error = ivas_splitBinLCLDDecOpen( &splitBinInput->splitPostRendWrapper.hSplitBinLCLDDec, *splitBinInput->base.ctx.pOutSampleRate, BINAURAL_CHANNELS ) ) != IVAS_ERR_OK ) - { - return error; - } - } - else if ( bits.codec == IVAS_SPLIT_REND_CODEC_LC3PLUS && splitBinInput->splitPostRendWrapper.hLc3plusDec == NULL ) - { - LC3PLUS_CONFIG config; - - if ( outAudio.config.numSamplesPerChannel == 240 ) - { - config.lc3plus_frame_duration_us = bits.codec_frame_size_ms * 1000; - config.ivas_frame_duration_us = ( bits.pose_correction == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) ? config.lc3plus_frame_duration_us : 20000; - } - else - { - config.lc3plus_frame_duration_us = 5000; - config.ivas_frame_duration_us = 20000; - } - config.channels = BINAURAL_CHANNELS; - config.samplerate = *splitBinInput->base.ctx.pOutSampleRate; - - if ( ( error = IVAS_LC3PLUS_DEC_Open( config, - &splitBinInput->splitPostRendWrapper.hLc3plusDec ) ) != IVAS_ERR_OK ) - { - return error; - } - } - - outBufNumSamplesPerChannel = outAudio.config.numSamplesPerChannel / pCombinedOrientationData->num_subframes; - for ( sf_idx = 0; sf_idx < pCombinedOrientationData->num_subframes; sf_idx++ ) - { - QuaternionsPost[sf_idx] = pCombinedOrientationData->Quaternions[sf_idx]; - } - - - if ( !SplitRendBFI ) - { - hSplitBin->first_good_frame_received = 1; - } - - if ( hSplitBin->first_good_frame_received == 1 ) - { - if ( bits.pose_correction == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) - { - if ( !SplitRendBFI ) - { -#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG - ivas_splitBinPostRendMdDec( &bits, hSplitBin->hBinHrSplitPostRend, &hSplitBin->multiBinPoseData, hSplitBin->hBinHrSplitPreRend ); -#else - ivas_splitBinPostRendMdDec( &bits, hSplitBin->hBinHrSplitPostRend, &hSplitBin->multiBinPoseData ); -#endif - } - } - - /*copy pose correction after MD is parsed*/ - hSplitBin->multiBinPoseData.poseCorrectionMode = bits.pose_correction; - - /* decode audio */ - if ( splitBinInput->base.inConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) - { - if ( bits.codec == IVAS_SPLIT_REND_CODEC_LCLD ) - { - isPostRendInputCldfb = 1; - } - - preRendFrameSize_ms = bits.codec == IVAS_SPLIT_REND_CODEC_LC3PLUS ? (int16_t) ( hSplitBin->hLc3plusDec->config.ivas_frame_duration_us ) / 1000 : 20; - - numSamplesPerChannelCacheSize = (int16_t) ( *splitBinInput->base.ctx.pOutSampleRate * ( preRendFrameSize_ms - bits.codec_frame_size_ms ) / 1000 ); - - outBufNumColPerChannel = MAX_PARAM_SPATIAL_SUBFRAMES; - numColPerChannelCacheSize = CLDFB_NO_COL_MAX - outBufNumColPerChannel; - - for ( sf_idx = 0; sf_idx < pCombinedOrientationData->num_subframes; sf_idx++ ) - { - if ( splitBinInput->numCachedSamples == 0 ) - { - if ( bits.codec == IVAS_SPLIT_REND_CODEC_LCLD ) - { - ivas_splitBinLCLDDecProcess( hSplitBin->hSplitBinLCLDDec, &bits, Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, SplitRendBFI ); - - /* copy data over to 5ms buffer */ - for ( chnlIdx = 0; chnlIdx < BINAURAL_CHANNELS; ++chnlIdx ) - { - for ( slotIdx = 0; slotIdx < 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 ); - } - } - - /* cache the remaining 15ms */ - splitBinInput->numCachedSamples = numColPerChannelCacheSize; - writePtr = splitBinInput->bufferData; - for ( slotIdx = CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES; slotIdx < CLDFB_NO_COL_MAX; ++slotIdx ) - { - for ( chnlIdx = 0; chnlIdx < BINAURAL_CHANNELS; ++chnlIdx ) - { - for ( smplIdx = 0; smplIdx < CLDFB_NO_CHANNELS_MAX; ++smplIdx ) - { - *writePtr++ = Cldfb_RealBuffer_Binaural[chnlIdx][slotIdx][smplIdx]; - } - for ( smplIdx = 0; smplIdx < CLDFB_NO_CHANNELS_MAX; ++smplIdx ) - { - *writePtr++ = Cldfb_ImagBuffer_Binaural[chnlIdx][slotIdx][smplIdx]; - } - } - } - } - else - { - if ( ( error = splitBinLc3plusDecode( hSplitBin, &bits, tmpCrendBuffer, bits.pose_correction ) ) != IVAS_ERR_OK ) - { - return error; - } - - /* cache the remaining 15ms */ - splitBinInput->numCachedSamples = numSamplesPerChannelCacheSize; - mvr2r( &tmpCrendBuffer[0][outBufNumSamplesPerChannel], splitBinInput->bufferData, numSamplesPerChannelCacheSize ); - mvr2r( &tmpCrendBuffer[1][outBufNumSamplesPerChannel], splitBinInput->bufferData + numSamplesPerChannelCacheSize, numSamplesPerChannelCacheSize ); - } - } - else - { - /* copy from cache */ - if ( bits.codec == IVAS_SPLIT_REND_CODEC_LCLD ) - { - int16_t readOffset = ( numColPerChannelCacheSize - splitBinInput->numCachedSamples ); - readPtr = splitBinInput->bufferData; - isPostRendInputCldfb = 1; - - readPtr += 2 * readOffset * CLDFB_NO_CHANNELS_MAX * BINAURAL_CHANNELS; - for ( slotIdx = 0; slotIdx < CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES; ++slotIdx ) - { - for ( chnlIdx = 0; chnlIdx < BINAURAL_CHANNELS; ++chnlIdx ) - { - for ( smplIdx = 0; smplIdx < CLDFB_NO_CHANNELS_MAX; ++smplIdx ) - { - Cldfb_RealBuffer_Binaural_5ms[sf_idx][chnlIdx][slotIdx][smplIdx] = *readPtr++; - } - for ( smplIdx = 0; smplIdx < CLDFB_NO_CHANNELS_MAX; ++smplIdx ) - { - Cldfb_ImagBuffer_Binaural_5ms[sf_idx][chnlIdx][slotIdx][smplIdx] = *readPtr++; - } - } - } - - splitBinInput->numCachedSamples -= outBufNumColPerChannel; - } - 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 ); - splitBinInput->numCachedSamples -= outBufNumSamplesPerChannel; - } - } - } - } - else - { - copyBufferTo2dArray( splitBinInput->base.inputBuffer, tmpCrendBuffer ); - } - - /* apply pose correction if enabled */ - for ( sf_idx = 0; sf_idx < pCombinedOrientationData->num_subframes; sf_idx++ ) - { - if ( bits.pose_correction == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE && isPostRendInputCldfb ) - { - /* 0DOF with LCLD codec requires CLDFB synthesis */ - int16_t slot_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]; - - 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]; - } - - 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] ); - } - } - else if ( bits.pose_correction == IVAS_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 ); - - ivas_rend_CldfbSplitPostRendProcess( hSplitBin->hBinHrSplitPostRend, &hSplitBin->multiBinPoseData, QuaternionsPost[sf_idx], Cldfb_RealBuffer_Binaural_5ms[sf_idx], Cldfb_ImagBuffer_Binaural_5ms[sf_idx], tmpCrendBuffer_sf, isPostRendInputCldfb ); - - mvr2r( tmpCrendBuffer_sf[0], &tmpCrendBuffer[0][sf_idx * outBufNumSamplesPerChannel], outBufNumSamplesPerChannel ); - mvr2r( tmpCrendBuffer_sf[1], &tmpCrendBuffer[1][sf_idx * outBufNumSamplesPerChannel], outBufNumSamplesPerChannel ); - } - } - } - else - { - if ( splitBinInput->base.inConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED ) - { - for ( ch_idx = 0; ch_idx < BINAURAL_CHANNELS; ch_idx++ ) - { - set_zero( tmpCrendBuffer[ch_idx], outAudio.config.numSamplesPerChannel ); - } - } - else - { - copyBufferTo2dArray( splitBinInput->base.inputBuffer, tmpCrendBuffer ); - } - } - - convertInternalBitsBuffToBitsBuffer( splitBinInput->hBits, bits ); - accumulate2dArrayToBuffer( tmpCrendBuffer, &outAudio ); - - pop_wmops(); - return error; -} - static ivas_error renderSbaToMultiBinaural( input_sba *sbaInput, @@ -7040,7 +6501,7 @@ static ivas_error renderSbaToMultiBinaural( pCombinedOrientationDataLocal = *sbaInput->base.ctx.pCombinedOrientationData; combinedOrientationDataLocal = *pCombinedOrientationDataLocal; - if ( pMultiBinPoseData->poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) + if ( pMultiBinPoseData->poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB ) { for ( sf = 1; sf < combinedOrientationDataLocal.num_subframes; sf++ ) { @@ -7090,8 +6551,8 @@ static ivas_error renderSbaToMultiBinaural( assert( sbaInput->crendWrapper->hCrend[0]->hReverb == NULL ); /* call CREND */ - if ( ( error = ivas_rend_crendProcess( sbaInput->crendWrapper, sbaInput->base.inConfig, outConfig, NULL, NULL, NULL, NULL, p_tmpCrendBuffer, *sbaInput->base.ctx.pOutSampleRate, - getNumSubframesInBuffer( &sbaInput->base.inputBuffer, *sbaInput->base.ctx.pOutSampleRate ), pos_idx ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_rend_crendProcessSubframe( sbaInput->crendWrapper, sbaInput->base.inConfig, outConfig, NULL, NULL, + NULL, NULL, NULL, p_tmpCrendBuffer, p_tmpCrendBuffer, sbaInput->base.inputBuffer.config.numSamplesPerChannel, *sbaInput->base.ctx.pOutSampleRate, pos_idx ) ) != IVAS_ERR_OK ) { return error; } @@ -7151,7 +6612,7 @@ static ivas_error renderSbaToSplitBinaural( push_wmops( "renderSbaToSplitBinaural" ); error = IVAS_ERR_OK; - if ( sbaInput->base.ctx.hhRendererConfig[0]->split_rend_config.rendererSelection == IVAS_SPLIT_REND_RENDERER_SELECTION_FASTCONV ) + if ( sbaInput->base.ctx.hhRendererConfig[0]->split_rend_config.rendererSelection == ISAR_SPLIT_REND_RENDERER_SELECTION_FASTCONV ) { if ( ( renderSbaToMultiBinauralCldfb( sbaInput, Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, low_res_pre_rend_rot, getNumSubframesInBuffer( &outAudio, *sbaInput->base.ctx.pOutSampleRate ) ) ) != IVAS_ERR_OK ) @@ -7193,7 +6654,7 @@ static ivas_error renderSbaToBinaural( push_wmops( "renderSbaToBinaural" ); #ifdef SPLIT_REND_WITH_HEAD_ROT - if ( sbaInput->base.ctx.hhRendererConfig[0]->split_rend_config.rendererSelection == IVAS_SPLIT_REND_RENDERER_SELECTION_FASTCONV ) + if ( sbaInput->base.ctx.hhRendererConfig[0]->split_rend_config.rendererSelection == ISAR_SPLIT_REND_RENDERER_SELECTION_FASTCONV ) { 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]; @@ -7258,11 +6719,11 @@ static ivas_error renderSbaToBinaural( /* call CREND */ #ifdef SPLIT_REND_WITH_HEAD_ROT - if ( ( error = ivas_rend_crendProcess( sbaInput->crendWrapper, sbaInput->base.inConfig, outConfig, NULL, NULL, NULL, NULL, p_tmpCrendBuffer, *sbaInput->base.ctx.pOutSampleRate, - getNumSubframesInBuffer( &outAudio, *sbaInput->base.ctx.pOutSampleRate ), 0 ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_rend_crendProcessSubframe( sbaInput->crendWrapper, sbaInput->base.inConfig, outConfig, NULL, NULL, + NULL, NULL, NULL, p_tmpCrendBuffer, p_tmpCrendBuffer, sbaInput->base.inputBuffer.config.numSamplesPerChannel, *sbaInput->base.ctx.pOutSampleRate, 0 ) ) != IVAS_ERR_OK ) #else - if ( ( error = ivas_rend_crendProcess( sbaInput->crendWrapper, sbaInput->base.inConfig, outConfig, NULL, NULL, NULL, NULL, p_tmpCrendBuffer, *sbaInput->base.ctx.pOutSampleRate, - getNumSubframesInBuffer( &outAudio, *sbaInput->base.ctx.pOutSampleRate ) ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_rend_crendProcessSubframe( sbaInput->crendWrapper, sbaInput->base.inConfig, outConfig, NULL, NULL, + NULL, NULL, NULL, p_tmpCrendBuffer, p_tmpCrendBuffer, sbaInput->base.inputBuffer.config.numSamplesPerChannel, *sbaInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) #endif { return error; @@ -7358,12 +6819,12 @@ static ivas_error renderSbaToBinauralRoom( copyBufferTo2dArray( tmpMcBuffer, tmpCrendBuffer ); /* call CREND */ - if ( ( error = ivas_rend_crendProcess( sbaInput->crendWrapper, IVAS_AUDIO_CONFIG_7_1_4, outConfig, - NULL, NULL, NULL, NULL, p_tmpCrendBuffer, *sbaInput->base.ctx.pOutSampleRate, #ifdef SPLIT_REND_WITH_HEAD_ROT - getNumSubframesInBuffer( &outAudio, *sbaInput->base.ctx.pOutSampleRate ), 0 ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_rend_crendProcessSubframe( sbaInput->crendWrapper, IVAS_AUDIO_CONFIG_7_1_4, outConfig, NULL, NULL, + NULL, NULL, NULL, p_tmpCrendBuffer, p_tmpCrendBuffer, sbaInput->base.inputBuffer.config.numSamplesPerChannel, *sbaInput->base.ctx.pOutSampleRate, 0 ) ) != IVAS_ERR_OK ) #else - getNumSubframesInBuffer( &outAudio, *sbaInput->base.ctx.pOutSampleRate ) ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_rend_crendProcessSubframe( sbaInput->crendWrapper, IVAS_AUDIO_CONFIG_7_1_4, outConfig, NULL, NULL, + NULL, NULL, NULL, p_tmpCrendBuffer, p_tmpCrendBuffer, sbaInput->base.inputBuffer.config.numSamplesPerChannel, *sbaInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) #endif { return error; @@ -7382,39 +6843,6 @@ static ivas_error renderSbaToBinauralRoom( } -#ifdef SPLIT_REND_WITH_HEAD_ROT -static ivas_error renderInputSplitBin( - input_split_post_rend *splitBinInput, - const AUDIO_CONFIG outConfig, - IVAS_REND_AudioBuffer outAudio, - const int16_t SplitRendBFI ) -{ - ivas_error error; - IVAS_REND_AudioBuffer inAudio; - - inAudio = splitBinInput->base.inputBuffer; - - 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 ); /* TODO: the output buffer is empty at this point, should be moved to a point after decoding the split bitstream */ - switch ( outConfig ) - { - case IVAS_AUDIO_CONFIG_BINAURAL: - error = renderSplitBinauralWithPostRot( splitBinInput, outAudio, SplitRendBFI ); - break; - default: - return IVAS_ERR_INVALID_OUTPUT_FORMAT; - } - - return error; -} -#endif - - static void renderSbaToMasa( input_sba *sbaInput, IVAS_REND_AudioBuffer outAudio ) @@ -7502,34 +6930,6 @@ static ivas_error renderInputSba( } -#ifdef SPLIT_REND_WITH_HEAD_ROT -static ivas_error renderActiveInputsSplitBin( - IVAS_REND_HANDLE hIvasRend, - IVAS_REND_AudioBuffer outAudio ) -{ - int16_t i; - input_split_post_rend *pCurrentInput; - ivas_error error; - - for ( i = 0, pCurrentInput = hIvasRend->inputsSplitPost; i < RENDERER_MAX_BIN_INPUTS; ++i, ++pCurrentInput ) - { - if ( pCurrentInput->base.inConfig == IVAS_AUDIO_CONFIG_INVALID ) - { - /* Skip inactive inputs */ - continue; - } - - if ( ( error = renderInputSplitBin( pCurrentInput, hIvasRend->outputConfig, outAudio, hIvasRend->splitRendBFI ) ) != IVAS_ERR_OK ) - { - return error; - } - } - - return IVAS_ERR_OK; -} -#endif - - static ivas_error renderActiveInputsSba( IVAS_REND_HANDLE hIvasRend, IVAS_REND_AudioBuffer outAudio ) @@ -8160,7 +7560,7 @@ static ivas_error getSamplesInternal( int16_t num_poses_orig; num_poses_orig = hIvasRend->splitRendWrapper.multiBinPoseData.num_poses; outAudio = hIvasRend->splitRendEncBuffer; - ivas_renderSplitGetMultiBinPoseData( &hIvasRend->hRendererConfig->split_rend_config, &hIvasRend->splitRendWrapper.multiBinPoseData, hIvasRend->headRotData.sr_pose_pred_axis ); + ISAR_PRE_REND_GetMultiBinPoseData( &hIvasRend->hRendererConfig->split_rend_config, &hIvasRend->splitRendWrapper.multiBinPoseData, hIvasRend->headRotData.sr_pose_pred_axis ); assert( num_poses_orig == hIvasRend->splitRendWrapper.multiBinPoseData.num_poses && "number of poses should not change dynamically" ); /* Clear output buffer for split rendering bitstream */ @@ -8188,23 +7588,7 @@ static ivas_error getSamplesInternal( return error; } -#ifdef SPLIT_REND_WITH_HEAD_ROT - if ( ( error = renderActiveInputsSplitBin( hIvasRend, outAudio ) ) != IVAS_ERR_OK ) - { - return error; - } - - if ( outAudio.config.is_cldfb == 0 ) - { -#ifndef DISABLE_LIMITER -#ifdef DEBUGGING - hIvasRend->numClipping += -#endif - limitRendererOutput( hIvasRend->hLimiter, outAudio.data, outAudio.config.numSamplesPerChannel, IVAS_LIMITER_THRESHOLD ); -#endif - } -#else - +#ifndef SPLIT_REND_WITH_HEAD_ROT #ifndef DISABLE_LIMITER #ifdef DEBUGGING hIvasRend->numClipping += @@ -8212,15 +7596,15 @@ static ivas_error getSamplesInternal( limitRendererOutput( hIvasRend->hLimiter, outAudio.data, outAudio.config.numSamplesPerChannel, IVAS_LIMITER_THRESHOLD ); #endif #endif - #ifdef SPLIT_REND_WITH_HEAD_ROT if ( hIvasRend->outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_CODED || hIvasRend->outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) { - IVAS_SPLIT_REND_BITS_DATA bits; + ISAR_SPLIT_REND_BITS_DATA bits; 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]; 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]; for ( ch = 0; ch < MAX_OUTPUT_CHANNELS; ch++ ) @@ -8242,8 +7626,33 @@ static ivas_error getSamplesInternal( /* Encode split rendering bitstream */ convertBitsBufferToInternalBitsBuff( *hBits, &bits ); - if ( ( error = ivas_renderMultiBinToSplitBinaural( &hIvasRend->splitRendWrapper, hIvasRend->headRotData.headPositions[0], hIvasRend->hRendererConfig->split_rend_config.splitRendBitRate, hIvasRend->hRendererConfig->split_rend_config.codec, 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 ) ) != IVAS_ERR_OK ) + ro_md_flag = 0; + for ( i = 0; i < RENDERER_MAX_ISM_INPUTS; ++i ) + { + if ( hIvasRend->inputsIsm[i].base.inConfig != IVAS_AUDIO_CONFIG_INVALID ) + { + ro_md_flag = 1; + break; + } + } + + 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 ) { return error; } @@ -8260,6 +7669,18 @@ static ivas_error getSamplesInternal( } #endif +#ifdef SPLIT_REND_WITH_HEAD_ROT + if ( outAudio.config.is_cldfb == 0 ) + { +#ifndef DISABLE_LIMITER +#ifdef DEBUGGING + hIvasRend->numClipping += +#endif + limitRendererOutput( hIvasRend->hLimiter, outAudio.data, outAudio.config.numSamplesPerChannel, IVAS_LIMITER_THRESHOLD ); +#endif + } +#endif + /* update global cominbed orientation start index */ ivas_combined_orientation_update_start_index( hIvasRend->hCombinedOrientationData, outAudio.config.numSamplesPerChannel ); @@ -8304,11 +7725,9 @@ ivas_error IVAS_REND_GetSplitBinauralBitstream( cldfb_in_flag = getCldfbRendFlag( hIvasRend, IVAS_REND_AUDIO_CONFIG_TYPE_UNKNOWN ); hIvasRend->splitRendEncBuffer.config.is_cldfb = cldfb_in_flag; - - if ( hIvasRend->hRendererConfig->split_rend_config.codec == IVAS_SPLIT_REND_CODEC_LC3PLUS && - ( hIvasRend->hRendererConfig->split_rend_config.dof == 0 || hIvasRend->hRendererConfig->split_rend_config.poseCorrectionMode == IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) ) + if ( hIvasRend->hRendererConfig->split_rend_config.dof == 0 || hIvasRend->hRendererConfig->split_rend_config.poseCorrectionMode == ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE ) { - hIvasRend->splitRendEncBuffer.config.numSamplesPerChannel = hIvasRend->hRendererConfig->split_rend_config.codec_frame_size_ms * hIvasRend->num_subframes * (int16_t) ( hIvasRend->sampleRateOut / 1000 ); + hIvasRend->splitRendEncBuffer.config.numSamplesPerChannel = outAudio.config.numSamplesPerChannel; } else { @@ -8321,28 +7740,30 @@ ivas_error IVAS_REND_GetSplitBinauralBitstream( return getSamplesInternal( hIvasRend, outAudio, hBits ); } - -/*-------------------------------------------------------------------* - * IVAS_REND_GetSplitBinauralSamples() - * - * - *-------------------------------------------------------------------*/ - -ivas_error IVAS_REND_GetSplitBinauralSamples( - IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ - IVAS_REND_AudioBuffer outAudio, /* i/o: buffer for output audio */ - bool *needNewFrame ) +ivas_error IVAS_REND_GetSplitRendBitstreamHeader( + IVAS_REND_HANDLE hIvasRend, /* i/o: IVAS renderer handle */ + ISAR_SPLIT_REND_CODEC *pCodec, /* o: pointer to codec setting */ + ISAR_SPLIT_REND_POSE_CORRECTION_MODE *poseCorrection, /* o: pointer to pose correction mode */ + int16_t *pCodec_frame_size_ms /* o: pointer to codec frame size setting */ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + , + int16_t *pIsar_frame_size_ms /* o: pointer to isar frame size setting */ +#endif +) { - ivas_error error; - - if ( ( error = getSamplesInternal( hIvasRend, outAudio, NULL ) ) != IVAS_ERR_OK ) + if ( hIvasRend == NULL || hIvasRend->hRendererConfig == NULL ) { - return error; + return IVAS_ERR_UNEXPECTED_NULL_POINTER; } - *needNewFrame = hIvasRend->inputsSplitPost[0].numCachedSamples == 0; - + *pCodec = hIvasRend->hRendererConfig->split_rend_config.codec; + *pCodec_frame_size_ms = hIvasRend->hRendererConfig->split_rend_config.codec_frame_size_ms; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + *pIsar_frame_size_ms = hIvasRend->hRendererConfig->split_rend_config.isar_frame_size_ms; +#endif + *poseCorrection = hIvasRend->hRendererConfig->split_rend_config.poseCorrectionMode; return IVAS_ERR_OK; } + #endif @@ -8388,12 +7809,6 @@ void IVAS_REND_Close( { clearInputMasa( &hIvasRend->inputsMasa[i] ); } -#ifdef SPLIT_REND_WITH_HEAD_ROT - for ( i = 0; i < RENDERER_MAX_BIN_INPUTS; ++i ) - { - clearInputSplitRend( &hIvasRend->inputsSplitPost[i] ); - } -#endif /* clear Config. Renderer */ ivas_render_config_close( &( hIvasRend->hRendererConfig ) ); @@ -8402,7 +7817,7 @@ void IVAS_REND_Close( #ifdef SPLIT_REND_WITH_HEAD_ROT /* Split binaural rendering */ - closeSplitRend( &hIvasRend->splitRendWrapper, &hIvasRend->splitRendEncBuffer ); + ISAR_PRE_REND_close( &hIvasRend->splitRendWrapper, &hIvasRend->splitRendEncBuffer ); #endif closeHeadRotation( hIvasRend ); diff --git a/lib_rend/lib_rend.h b/lib_rend/lib_rend.h index 6df2ff3f4..3e815b69e 100644 --- a/lib_rend/lib_rend.h +++ b/lib_rend/lib_rend.h @@ -35,6 +35,7 @@ #include "common_api_types.h" #include +#include "ivas_stat_rend.h" /*---------------------------------------------------------------------* * Renderer constants @@ -45,10 +46,6 @@ #define RENDERER_MAX_SBA_INPUTS 1 #define RENDERER_MAX_MASA_INPUTS 1 #define RENDERER_MAX_INPUT_LFE_CHANNELS 4 -#ifdef SPLIT_REND_WITH_HEAD_ROT -#define RENDERER_MAX_BIN_INPUTS 1 -#endif - /*---------------------------------------------------------------------* * Renderer structures @@ -56,30 +53,19 @@ typedef float IVAS_REND_LfePanMtx[RENDERER_MAX_INPUT_LFE_CHANNELS][IVAS_MAX_OUTPUT_CHANNELS]; -typedef struct -{ - int16_t numSamplesPerChannel; - int16_t numChannels; -#ifdef SPLIT_REND_WITH_HEAD_ROT - int16_t is_cldfb; -#endif -} IVAS_REND_AudioBufferConfig; - -typedef struct -{ - IVAS_REND_AudioBufferConfig config; - float *data; -} IVAS_REND_AudioBuffer; - #ifdef SPLIT_REND_WITH_HEAD_ROT typedef struct { int32_t bufLenInBytes; int32_t bitsWritten; int32_t bitsRead; - IVAS_SPLIT_REND_CODEC codec; - IVAS_SPLIT_REND_POSE_CORRECTION_MODE poseCorrection; + ISAR_SPLIT_REND_CODEC codec; + ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrection; int16_t codec_frame_size_ms; +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + int16_t isar_frame_size_ms; + int16_t lc3plus_highres; +#endif } IVAS_REND_BitstreamBufferConfig; typedef struct { @@ -256,6 +242,17 @@ ivas_error IVAS_REND_GetSplitBinauralBitstream( IVAS_REND_AudioBuffer outAudio, /* i/o: buffer for output audio */ IVAS_REND_BitstreamBuffer *hBits /* o : buffer for output bitstream */ ); + +ivas_error IVAS_REND_GetSplitRendBitstreamHeader( + IVAS_REND_HANDLE hIvasRend, /* i/o: IVAS renderer handle */ + ISAR_SPLIT_REND_CODEC *pCodec, /* o: pointer to codec setting */ + ISAR_SPLIT_REND_POSE_CORRECTION_MODE *poseCorrection, /* o: pointer to pose correction mode */ + int16_t *pCodec_frame_size_ms /* o: pointer to codec frame size setting */ +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + , + int16_t *pIsar_frame_size_ms /* o: pointer to isar frame size setting */ +#endif +); #endif ivas_error IVAS_REND_SetHeadRotation( @@ -263,7 +260,7 @@ ivas_error IVAS_REND_SetHeadRotation( const IVAS_QUATERNION headRot, /* i : head orientations for next rendering call */ const IVAS_VECTOR3 Pos, /* i : listener positions for next rendering call */ #ifdef SPLIT_REND_WITH_HEAD_ROT - const IVAS_SPLIT_REND_ROT_AXIS rot_axis, /* i : external control for rotation axis for split rendering*/ + const ISAR_SPLIT_REND_ROT_AXIS rot_axis, /* i : external control for rotation axis for split rendering*/ #endif const int16_t sf_idx /* i : subframe index */ ); diff --git a/lib_util/render_config_reader.c b/lib_util/render_config_reader.c index a1d778980..f8d2921d0 100644 --- a/lib_util/render_config_reader.c +++ b/lib_util/render_config_reader.c @@ -2452,7 +2452,9 @@ ivas_error RenderConfigReader_read( while ( sscanf( pParams + params_idx, "%64[^=]=%[^;];", item, pValue ) == 2 ) { params_idx += (int32_t) ( strlen( item ) + strlen( pValue ) + 2 ); +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG fprintf( stderr, " PARAM: %s -> %s\n", item, pValue ); +#endif if ( strcmp( item, "CODECDELAY" ) == 0 ) { if ( !sscanf( pValue, "%hd", &hRenderConfig->split_rend_config.codec_delay_ms ) ) @@ -2484,18 +2486,18 @@ ivas_error RenderConfigReader_read( /* 0 DOF implies no pose correction */ if ( hRenderConfig->split_rend_config.dof == 0 && !poseCorrProvided ) { - hRenderConfig->split_rend_config.poseCorrectionMode = IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE; + hRenderConfig->split_rend_config.poseCorrectionMode = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE; } } else if ( strcmp( item, "CODEC" ) == 0 ) { if ( strcmp( pValue, "LCLD" ) == 0 ) { - hRenderConfig->split_rend_config.codec = IVAS_SPLIT_REND_CODEC_LCLD; + hRenderConfig->split_rend_config.codec = ISAR_SPLIT_REND_CODEC_LCLD; } else if ( strcmp( pValue, "LC3PLUS" ) == 0 ) { - hRenderConfig->split_rend_config.codec = IVAS_SPLIT_REND_CODEC_LC3PLUS; + hRenderConfig->split_rend_config.codec = ISAR_SPLIT_REND_CODEC_LC3PLUS; } else { @@ -2520,11 +2522,11 @@ ivas_error RenderConfigReader_read( poseCorrProvided = true; if ( strcmp( pValue, "CLDFB" ) == 0 ) { - hRenderConfig->split_rend_config.poseCorrectionMode = IVAS_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB; + hRenderConfig->split_rend_config.poseCorrectionMode = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_CLDFB; } else if ( strcmp( pValue, "NONE" ) == 0 ) { - hRenderConfig->split_rend_config.poseCorrectionMode = IVAS_SPLIT_REND_POSE_CORRECTION_MODE_NONE; + hRenderConfig->split_rend_config.poseCorrectionMode = ISAR_SPLIT_REND_POSE_CORRECTION_MODE_NONE; /* no pose correction implies 0 DOF */ if ( !dofProvided ) { @@ -2540,25 +2542,34 @@ ivas_error RenderConfigReader_read( { if ( strcmp( pValue, "CREND" ) == 0 ) { - hRenderConfig->split_rend_config.rendererSelection = IVAS_SPLIT_REND_RENDERER_SELECTION_CREND; + hRenderConfig->split_rend_config.rendererSelection = ISAR_SPLIT_REND_RENDERER_SELECTION_CREND; } else if ( strcmp( pValue, "FASTCONV" ) == 0 ) { - hRenderConfig->split_rend_config.rendererSelection = IVAS_SPLIT_REND_RENDERER_SELECTION_FASTCONV; + hRenderConfig->split_rend_config.rendererSelection = ISAR_SPLIT_REND_RENDERER_SELECTION_FASTCONV; } else if ( strcmp( pValue, "PARAMBIN" ) == 0 ) { - hRenderConfig->split_rend_config.rendererSelection = IVAS_SPLIT_REND_RENDERER_SELECTION_PARAMBIN; + hRenderConfig->split_rend_config.rendererSelection = ISAR_SPLIT_REND_RENDERER_SELECTION_PARAMBIN; } else if ( strcmp( pValue, "TDREND" ) == 0 ) { - hRenderConfig->split_rend_config.rendererSelection = IVAS_SPLIT_REND_RENDERER_SELECTION_TDREND; + hRenderConfig->split_rend_config.rendererSelection = ISAR_SPLIT_REND_RENDERER_SELECTION_TDREND; } else { errorHandler( pValue, ERROR_VALUE_INVALID ); } } +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + else if ( strcmp( item, "LC3PLUS_HIGHRES" ) == 0 ) + { + if ( !sscanf( pValue, "%hd", &hRenderConfig->split_rend_config.lc3plus_highres ) ) + { + errorHandler( item, ERROR_VALUE_INVALID ); + } + } +#endif #ifdef DEBUGGING else { diff --git a/lib_util/split_rend_bfi_file_reader.c b/lib_util/split_rend_bfi_file_reader.c index 66f0a17ec..96b78972f 100644 --- a/lib_util/split_rend_bfi_file_reader.c +++ b/lib_util/split_rend_bfi_file_reader.c @@ -32,10 +32,8 @@ #include #include "options.h" -#ifdef SPLIT_REND_WITH_HEAD_ROT #include "split_rend_bfi_file_reader.h" -#include -#include +#ifdef SPLIT_REND_WITH_HEAD_ROT #include #include "prot.h" diff --git a/lib_util/split_render_file_read_write.c b/lib_util/split_render_file_read_write.c index 1a08a6929..8a4dea8fd 100644 --- a/lib_util/split_render_file_read_write.c +++ b/lib_util/split_render_file_read_write.c @@ -32,15 +32,10 @@ #include #include "options.h" -#ifdef SPLIT_REND_WITH_HEAD_ROT #include "split_render_file_read_write.h" -#include +#ifdef SPLIT_REND_WITH_HEAD_ROT #include -#include -#include -#include "cmdl_tools.h" #include "prot.h" -#include "ivas_cnst.h" /*------------------------------------------------------------------------------------------* @@ -68,7 +63,17 @@ struct SplitFileReadWrite ivas_error split_rend_reader_open( SplitFileReadWrite **hhSplitRendFileReadWrite, - char *filename ) + char *filename, + ISAR_SPLIT_REND_CODEC *codec, + ISAR_SPLIT_REND_POSE_CORRECTION_MODE *poseCorrection, + int16_t *codec_frame_size_ms +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + , + int16_t *isar_frame_size_ms, + int32_t *sampling_rate, + int16_t *lc3plus_highres +#endif +) { SplitFileReadWrite *hSplitRendFileReadWrite; size_t header_len, h; @@ -104,6 +109,40 @@ ivas_error split_rend_reader_open( fread( &hSplitRendFileReadWrite->delay_ns, sizeof( uint32_t ), 1, hSplitRendFileReadWrite->file ); + /* read codec signalling */ + if ( fread( codec, sizeof( *codec ), 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_FAILED_FILE_READ; + } + + /* read pose correction signalling */ + if ( fread( poseCorrection, sizeof( *poseCorrection ), 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_FAILED_FILE_READ; + } + /* read transport codec frame size signalling */ + if ( fread( codec_frame_size_ms, sizeof( *codec_frame_size_ms ), 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_FAILED_FILE_READ; + } +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + /* read isar bitstream frame size signalling */ + if ( fread( isar_frame_size_ms, sizeof( *isar_frame_size_ms ), 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_FAILED_FILE_READ; + } + /* read sampling rate signalling */ + if ( fread( sampling_rate, sizeof( *sampling_rate ), 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_FAILED_FILE_READ; + } + /* read LC3plus highres signalling */ + if ( fread( lc3plus_highres, sizeof( *lc3plus_highres ), 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_FAILED_FILE_READ; + } +#endif + *hhSplitRendFileReadWrite = hSplitRendFileReadWrite; return IVAS_ERR_OK; @@ -120,7 +159,17 @@ ivas_error split_rend_writer_open( SplitFileReadWrite **hhSplitRendFileReadWrite, char *filename, const int16_t delayNumSamples, - const int32_t delayTimeScale ) + const int32_t delayTimeScale, + ISAR_SPLIT_REND_CODEC codec, + ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrection, + int16_t codec_frame_size_ms +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + , + const int16_t isar_frame_size_ms, + const int32_t sampling_rate, + const int16_t lc3plus_highres +#endif +) { SplitFileReadWrite *hSplitRendFileReadWrite; size_t header_len, h; @@ -155,6 +204,40 @@ ivas_error split_rend_writer_open( hSplitRendFileReadWrite->delay_ns = (int32_t) ( (float) delayNumSamples * 1000000000.0f / (float) delayTimeScale ); fwrite( &hSplitRendFileReadWrite->delay_ns, sizeof( int32_t ), 1, hSplitRendFileReadWrite->file ); + /* Write codec signalling */ + if ( fwrite( &codec, sizeof( codec ), 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_FAILED_FILE_WRITE; + } + + /* Write pose correction signalling */ + if ( fwrite( &poseCorrection, sizeof( poseCorrection ), 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_FAILED_FILE_WRITE; + } + /* Write transport codec frame size signalling */ + if ( fwrite( &codec_frame_size_ms, sizeof( codec_frame_size_ms ), 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_FAILED_FILE_WRITE; + } +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + /* Write isar bit stream frame size signalling */ + if ( fwrite( &isar_frame_size_ms, sizeof( isar_frame_size_ms ), 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_FAILED_FILE_WRITE; + } + /* Write sampling rate signalling */ + if ( fwrite( &sampling_rate, sizeof( sampling_rate ), 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_FAILED_FILE_WRITE; + } + /* Write LC3plus highres signalling */ + if ( fwrite( &lc3plus_highres, sizeof( lc3plus_highres ), 1, hSplitRendFileReadWrite->file ) != 1 ) + { + return IVAS_ERR_FAILED_FILE_WRITE; + } +#endif + *hhSplitRendFileReadWrite = hSplitRendFileReadWrite; return IVAS_ERR_OK; @@ -167,7 +250,7 @@ ivas_error split_rend_writer_open( * *-----------------------------------------------------------------------------------------*/ -ivas_error split_rend_reader_writer_close( +void split_rend_reader_writer_close( SplitFileReadWrite **hhSplitRendFileReadWrite ) { if ( ( *hhSplitRendFileReadWrite ) != NULL ) @@ -182,7 +265,7 @@ ivas_error split_rend_reader_writer_close( *hhSplitRendFileReadWrite = NULL; } - return IVAS_ERR_OK; + return; } @@ -196,10 +279,7 @@ ivas_error split_rend_write_bitstream_to_file( SplitFileReadWrite *hSplitRendFileReadWrite, uint8_t *bits, int32_t *bits_read, - int32_t *bits_written, - IVAS_SPLIT_REND_CODEC codec, - IVAS_SPLIT_REND_POSE_CORRECTION_MODE poseCorrection, - int16_t codec_frame_size_ms ) + int32_t *bits_written ) { char header[SPLIT_RENDERER_FRAME_HEADER_LEN] = "SPLIT_FRAME"; size_t header_len, i, num_bytes; @@ -232,23 +312,6 @@ ivas_error split_rend_write_bitstream_to_file( return IVAS_ERR_FAILED_FILE_WRITE; } - /* Write codec signalling */ - if ( fwrite( &codec, sizeof( codec ), 1, hSplitRendFileReadWrite->file ) != 1 ) - { - return IVAS_ERR_FAILED_FILE_WRITE; - } - - /* Write pose correction signalling */ - if ( fwrite( &poseCorrection, sizeof( poseCorrection ), 1, hSplitRendFileReadWrite->file ) != 1 ) - { - return IVAS_ERR_FAILED_FILE_WRITE; - } - /* Write frame size signalling */ - if ( fwrite( &codec_frame_size_ms, sizeof( codec_frame_size_ms ), 1, hSplitRendFileReadWrite->file ) != 1 ) - { - return IVAS_ERR_FAILED_FILE_WRITE; - } - /* write num bytes */ if ( fwrite( bits_written, sizeof( int32_t ), 1, hSplitRendFileReadWrite->file ) != 1 ) { @@ -278,10 +341,7 @@ ivas_error split_rend_read_bits_from_file( SplitFileReadWrite *hSplitRendFileReadWrite, uint8_t *bits, int32_t *bits_read, - int32_t *bits_written, - IVAS_SPLIT_REND_CODEC *codec, - IVAS_SPLIT_REND_POSE_CORRECTION_MODE *poseCorrection, - int16_t *codec_frame_size_ms ) + int32_t *bits_written ) { char header[SPLIT_RENDERER_FRAME_HEADER_LEN] = "SPLIT_FRAME"; char header_read[SPLIT_RENDERER_FRAME_HEADER_LEN]; @@ -298,7 +358,7 @@ ivas_error split_rend_read_bits_from_file( return IVAS_ERR_FAILED_FILE_READ; } - header_len = strlen( header ); + header_len = (int32_t) strlen( header ); /* read frame header */ for ( i = 0; i < header_len; i++ ) @@ -326,23 +386,6 @@ ivas_error split_rend_read_bits_from_file( return IVAS_ERR_FAILED_FILE_READ; } - /* read codec signalling */ - if ( fread( codec, sizeof( *codec ), 1, hSplitRendFileReadWrite->file ) != 1 ) - { - return IVAS_ERR_FAILED_FILE_READ; - } - - /* read pose correction signalling */ - if ( fread( poseCorrection, sizeof( *poseCorrection ), 1, hSplitRendFileReadWrite->file ) != 1 ) - { - return IVAS_ERR_FAILED_FILE_READ; - } - /* read frame size signalling */ - if ( fread( codec_frame_size_ms, sizeof( *codec_frame_size_ms ), 1, hSplitRendFileReadWrite->file ) != 1 ) - { - return IVAS_ERR_FAILED_FILE_READ; - } - /* write num bytes */ if ( fread( &bit_len, sizeof( int32_t ), 1, hSplitRendFileReadWrite->file ) != 1 ) { @@ -354,7 +397,7 @@ ivas_error split_rend_read_bits_from_file( { return IVAS_ERR_FAILED_FILE_READ; } - for ( i = 0; i < IVAS_SPLIT_REND_ADDITIONAL_BYTES_TO_READ; i++ ) + for ( i = 0; i < ISAR_SPLIT_REND_ADDITIONAL_BYTES_TO_READ; i++ ) { bits[num_bytes + i] = 0; } diff --git a/lib_util/split_render_file_read_write.h b/lib_util/split_render_file_read_write.h index 40028c2ad..1d6529ef2 100644 --- a/lib_util/split_render_file_read_write.h +++ b/lib_util/split_render_file_read_write.h @@ -41,7 +41,17 @@ typedef struct SplitFileReadWrite SplitFileReadWrite; /* Allocates and initializes a a split renderer reader instance */ ivas_error split_rend_reader_open( SplitFileReadWrite **hhSplitRendFileReadWrite, - char *filename ); + char *filename, + ISAR_SPLIT_REND_CODEC *codec, + ISAR_SPLIT_REND_POSE_CORRECTION_MODE *poseCorrection, + int16_t *codec_frame_size_ms +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + , + int16_t *isar_frame_size_ms, + int32_t *sampling_rate, + int16_t *lc3plus_highres +#endif +); /* Allocates and initializes a a split renderer writer instance */ @@ -49,10 +59,21 @@ ivas_error split_rend_writer_open( SplitFileReadWrite **hhSplitRendFileReadWrite, char *filename, const int16_t delayNumSamples, - const int32_t delayTimeScale ); + const int32_t delayTimeScale, + ISAR_SPLIT_REND_CODEC codec, + ISAR_SPLIT_REND_POSE_CORRECTION_MODE poseCorrection, + int16_t codec_frame_size_ms +#ifdef ISAR_BITSTREAM_UPDATE_LC3PLUS + , + const int16_t isar_frame_size_ms, + const int32_t sampling_rate, + const int16_t lc3plus_highres +#endif +); + /* Closes the split renderer reader/writer and deallocates memory */ -ivas_error split_rend_reader_writer_close( +void split_rend_reader_writer_close( SplitFileReadWrite **hhSplitRendFileReadWrite ); /*write split rend coded bitstream to file */ @@ -60,20 +81,14 @@ ivas_error split_rend_write_bitstream_to_file( SplitFileReadWrite *hSplitRendFileReadWrite, uint8_t *bits, int32_t *bits_read, - int32_t *bits_written, - IVAS_SPLIT_REND_CODEC codec, - IVAS_SPLIT_REND_POSE_CORRECTION_MODE poseCorrection, - int16_t codec_frame_size_ms ); + int32_t *bits_written ); /* read split rend coded bits from file */ ivas_error split_rend_read_bits_from_file( SplitFileReadWrite *hSplitRendFileReadWrite, uint8_t *bits, int32_t *bits_read, - int32_t *bits_written, - IVAS_SPLIT_REND_CODEC *codec, - IVAS_SPLIT_REND_POSE_CORRECTION_MODE *poseCorrection, - int16_t *codec_frame_size_ms ); + int32_t *bits_written ); /* read split pre rend delay */ ivas_error split_rend_read_pre_rend_delay_ns( -- GitLab From c0d66be501c0d3e68b1de12faff46ec48d0532f0 Mon Sep 17 00:00:00 2001 From: rtyag Date: Sat, 18 Jan 2025 01:19:20 +1100 Subject: [PATCH 15/33] compilation fixes, compiles on windows --- Workspace_msvc/Workspace_msvc.sln | 12 +++++ apps/renderer.c | 1 - lib_dec/ivas_dirac_dec.c | 90 ++++++++----------------------- lib_enc/ivas_osba_enc.c | 2 + lib_rend/ivas_shoebox.c | 1 + 5 files changed, 38 insertions(+), 68 deletions(-) diff --git a/Workspace_msvc/Workspace_msvc.sln b/Workspace_msvc/Workspace_msvc.sln index 5449368aa..ac2e76b52 100644 --- a/Workspace_msvc/Workspace_msvc.sln +++ b/Workspace_msvc/Workspace_msvc.sln @@ -99,6 +99,18 @@ Global {95030B82-70CD-4C6B-84D4-61096035BEA2}.Release|Win32.ActiveCfg = Release|Win32 {95030B82-70CD-4C6B-84D4-61096035BEA2}.Release|Win32.Build.0 = Release|Win32 {95030B82-70CD-4C6B-84D4-61096035BEA2}.Release|x64.ActiveCfg = Release|Win32 + {869A305E-D99E-4C3A-BDB3-AA57ABCCE619}.Debug|Win32.ActiveCfg = Debug|Win32 + {869A305E-D99E-4C3A-BDB3-AA57ABCCE619}.Debug|Win32.Build.0 = Debug|Win32 + {869A305E-D99E-4C3A-BDB3-AA57ABCCE619}.Debug|x64.ActiveCfg = Debug|Win32 + {869A305E-D99E-4C3A-BDB3-AA57ABCCE619}.Release|Win32.ActiveCfg = Release|Win32 + {869A305E-D99E-4C3A-BDB3-AA57ABCCE619}.Release|Win32.Build.0 = Release|Win32 + {869A305E-D99E-4C3A-BDB3-AA57ABCCE619}.Release|x64.ActiveCfg = Release|Win32 + {12374ADC-0E5C-4FDD-B903-71D572413831}.Debug|Win32.ActiveCfg = Debug|Win32 + {12374ADC-0E5C-4FDD-B903-71D572413831}.Debug|Win32.Build.0 = Debug|Win32 + {12374ADC-0E5C-4FDD-B903-71D572413831}.Debug|x64.ActiveCfg = Debug|Win32 + {12374ADC-0E5C-4FDD-B903-71D572413831}.Release|Win32.ActiveCfg = Release|Win32 + {12374ADC-0E5C-4FDD-B903-71D572413831}.Release|Win32.Build.0 = Release|Win32 + {12374ADC-0E5C-4FDD-B903-71D572413831}.Release|x64.ActiveCfg = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/apps/renderer.c b/apps/renderer.c index 0c30c6f69..ba1d2ac87 100644 --- a/apps/renderer.c +++ b/apps/renderer.c @@ -1907,7 +1907,6 @@ int main( free( outInt16Buffer ); free( outFloatBuffer ); -cleanup: #ifdef SPLIT_REND_WITH_HEAD_ROT if ( bitsBufferData != NULL ) diff --git a/lib_dec/ivas_dirac_dec.c b/lib_dec/ivas_dirac_dec.c index 53223dd6b..4a9b7cebe 100644 --- a/lib_dec/ivas_dirac_dec.c +++ b/lib_dec/ivas_dirac_dec.c @@ -1849,37 +1849,16 @@ void ivas_dirac_dec_render_sf( set_zero( surCohRatio, hSpatParamRendCom->num_freq_bands ); } } - - if ( st_ivas->hCombinedOrientationData && st_ivas->hCombinedOrientationData->enableCombinedOrientation[st_ivas->hCombinedOrientationData->subframe_idx] && st_ivas->hCombinedOrientationData->shd_rot_max_order == 1 ) - { - ivas_dirac_dec_compute_directional_responses( hSpatParamRendCom, - hDirACRend, - st_ivas->hVBAPdata, - st_ivas->hMasa == NULL ? NULL : st_ivas->hMasa->data.band_mapping, - st_ivas->hMasaIsmData, - azimuth, - elevation, - md_idx, - surCohRatio, - st_ivas->hCombinedOrientationData->shd_rot_max_order, - p_Rmat, - hodirac_flag ); - } - else - { - ivas_dirac_dec_compute_directional_responses( hSpatParamRendCom, - hDirACRend, - st_ivas->hVBAPdata, - st_ivas->hMasa == NULL ? NULL : st_ivas->hMasa->data.band_mapping, - st_ivas->hMasaIsmData, - azimuth, - elevation, - md_idx, - surCohRatio, - 0, - NULL, - hodirac_flag ); - } + ivas_dirac_dec_compute_directional_responses( hSpatParamRendCom, + hDirACRend, + st_ivas->hVBAPdata, + st_ivas->hMasa == NULL ? NULL : st_ivas->hMasa->data.band_mapping, + st_ivas->hMasaIsmData, + azimuth, + elevation, + md_idx, + surCohRatio, + hodirac_flag ); } if ( st_ivas->ivas_format == MASA_ISM_FORMAT && nchan_transport == 2 ) @@ -2209,42 +2188,19 @@ void ivas_dirac_dec_render_sf( } /*Compute PSDs*/ - if ( st_ivas->hCombinedOrientationData && st_ivas->hCombinedOrientationData->enableCombinedOrientation[st_ivas->hCombinedOrientationData->subframe_idx] && st_ivas->hCombinedOrientationData->shd_rot_max_order > 0 ) - { - ivas_dirac_dec_output_synthesis_process_slot( reference_power, - p_onset_filter, - azimuth, - elevation, - hSpatParamRendCom->diffuseness_vector[md_idx], - hSpatParamRendCom, - hDirACRend, - st_ivas->hCombinedOrientationData->shd_rot_max_order, - p_Rmat, - st_ivas->hVBAPdata, - hDirACRend->hOutSetup, - nchan_transport, - md_idx, - hodirac_flag, - hDirAC->hConfig->dec_param_estim ); - } - else - { - ivas_dirac_dec_output_synthesis_process_slot( reference_power, - p_onset_filter, - azimuth, - elevation, - hSpatParamRendCom->diffuseness_vector[md_idx], - hSpatParamRendCom, - hDirACRend, - 0, - 0, - st_ivas->hVBAPdata, - hDirACRend->hOutSetup, - nchan_transport, - md_idx, - hodirac_flag, - hDirAC->hConfig->dec_param_estim ); - } + ivas_dirac_dec_output_synthesis_process_slot( reference_power, + p_onset_filter, + azimuth, + elevation, + hSpatParamRendCom->diffuseness_vector[md_idx], + hSpatParamRendCom, + hDirACRend, + st_ivas->hVBAPdata, + hDirACRend->hOutSetup, + nchan_transport, + md_idx, + hodirac_flag, + hDirAC->hConfig->dec_param_estim ); if ( hDirAC->hConfig->dec_param_estim ) { diff --git a/lib_enc/ivas_osba_enc.c b/lib_enc/ivas_osba_enc.c index dffebcf19..8199069cd 100644 --- a/lib_enc/ivas_osba_enc.c +++ b/lib_enc/ivas_osba_enc.c @@ -447,7 +447,9 @@ static void ivas_osba_render_ism_to_sba( int16_t azimuth, elevation; float gains[MAX_INPUT_CHANNELS]; float g1, g2; +#ifndef NONE_BE_FIX_BASOP_1044_OSBA_PRERENDER_MIX_GAINS float output_gain; +#endif int16_t nchan_sba; diff --git a/lib_rend/ivas_shoebox.c b/lib_rend/ivas_shoebox.c index 12368f5fd..e81c41162 100644 --- a/lib_rend/ivas_shoebox.c +++ b/lib_rend/ivas_shoebox.c @@ -33,6 +33,7 @@ #include "options.h" #include #include +#include "ivas_prot.h" #include "ivas_prot_rend.h" #include "ivas_stat_rend.h" #include "ivas_cnst.h" -- GitLab From cf8aad7918bbd9b8e0c9788ec6f381e1d82e3d48 Mon Sep 17 00:00:00 2001 From: rtyag Date: Mon, 20 Jan 2025 14:52:51 +1100 Subject: [PATCH 16/33] remove unused file/function --- Workspace_msvc/lib_com.vcxproj | 1 - lib_com/ivas_osba_com.c | 69 ---------------------------------- 2 files changed, 70 deletions(-) delete mode 100644 lib_com/ivas_osba_com.c diff --git a/Workspace_msvc/lib_com.vcxproj b/Workspace_msvc/lib_com.vcxproj index 9d0563c1e..9eb1af512 100644 --- a/Workspace_msvc/lib_com.vcxproj +++ b/Workspace_msvc/lib_com.vcxproj @@ -203,7 +203,6 @@ - diff --git a/lib_com/ivas_osba_com.c b/lib_com/ivas_osba_com.c deleted file mode 100644 index e3b997dc3..000000000 --- a/lib_com/ivas_osba_com.c +++ /dev/null @@ -1,69 +0,0 @@ -/****************************************************************************************************** - - (C) 2022-2023 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. - -*******************************************************************************************************/ - -#include "options.h" -#include "ivas_cnst.h" -#include "ivas_prot.h" -#include "prot.h" -#include "ivas_rom_com.h" -#ifdef DEBUGGING -#include "debug.h" -#endif - -/*! r : ISM format mode */ -ISM_MODE ivas_osba_ism_mode_select( - const int32_t ivas_total_brate, /* i : IVAS total bitrate */ - const int16_t nchan_ism /* i : number of input ISM's */ -) -{ - ISM_MODE ism_mode = ISM_MODE_NONE; - - switch ( nchan_ism ) - { - case 1: - if ( ivas_total_brate >= IVAS_96k ) - { - ism_mode = ISM_SBA_MODE_DISC; - } - break; - case 2: - case 3: - case 4: - if ( ivas_total_brate >= IVAS_128k ) - { - ism_mode = ISM_SBA_MODE_DISC; - } - break; - } - - return ism_mode; -} -- GitLab From 86438fdf4b557ecddd88153b673da394dd2cc6c5 Mon Sep 17 00:00:00 2001 From: rtyag Date: Tue, 21 Jan 2025 00:44:13 +1100 Subject: [PATCH 17/33] retain BE w.r.t ivas-float-update --- apps/decoder.c | 3 ++- lib_dec/ivas_init_dec.c | 3 +-- lib_dec/ivas_jbm_dec.c | 10 ++++++++++ lib_dec/ivas_omasa_dec.c | 17 +++++++++++++++++ lib_enc/acelp_core_switch_enc.c | 21 --------------------- lib_enc/evs_enc.c | 10 ---------- lib_enc/pre_proc.c | 4 ---- lib_rend/ivas_objectRenderer.c | 2 ++ 8 files changed, 32 insertions(+), 38 deletions(-) diff --git a/apps/decoder.c b/apps/decoder.c index 23405b1ae..00a928685 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -1523,13 +1523,14 @@ static bool parseCmdlIVAS_dec( usage_dec(); return false; } - +#ifdef SPLIT_REND_WITH_HEAD_ROT if ( arg->outputMdFilename != NULL && arg->outputConfig != IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) { fprintf( stderr, "Error: Output split rendering metadata file is supported for BINAURAL_SPLIT_PCM output config. only\n\n" ); usage_dec(); return false; } +#endif } else { diff --git a/lib_dec/ivas_init_dec.c b/lib_dec/ivas_init_dec.c index 723249156..be5d64bbd 100644 --- a/lib_dec/ivas_init_dec.c +++ b/lib_dec/ivas_init_dec.c @@ -2655,8 +2655,7 @@ void ivas_destroy_dec( { ivas_td_binaural_close( &st_ivas->hBinRendererTd ); } - - if ( st_ivas->hHrtfTD != NULL ) + else if ( st_ivas->hHrtfTD != NULL ) { BSplineModelEvalDealloc( &st_ivas->hHrtfTD->ModelParams, &st_ivas->hHrtfTD->ModelEval ); diff --git a/lib_dec/ivas_jbm_dec.c b/lib_dec/ivas_jbm_dec.c index 64eaf39e3..5af113dda 100644 --- a/lib_dec/ivas_jbm_dec.c +++ b/lib_dec/ivas_jbm_dec.c @@ -1364,6 +1364,15 @@ ivas_error ivas_jbm_dec_render( { ivas_mc2sba( st_ivas->hIntSetup, p_output, p_output, *nSamplesRendered, st_ivas->hOutSetup.ambisonics_order, 0.f ); } + else if ( st_ivas->renderer_type == RENDERER_BINAURAL_OBJECTS_TD ) + { + if ( ( error = ivas_td_binaural_renderer( st_ivas, p_output, *nSamplesRendered ) ) != IVAS_ERR_OK ) + { + return error; + } + + ivas_binaural_add_LFE( st_ivas, *nSamplesRendered, p_output, p_output ); + } } else if ( st_ivas->mc_mode == MC_MODE_PARAMMC ) { @@ -1373,6 +1382,7 @@ ivas_error ivas_jbm_dec_render( { int16_t offset = hSpatParamRendCom->slots_rendered * hSpatParamRendCom->slot_size; nchan_remapped = st_ivas->nchan_transport; + if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM || st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC ) { ivas_dirac_dec_binaural_render( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, nchan_remapped, p_output ); diff --git a/lib_dec/ivas_omasa_dec.c b/lib_dec/ivas_omasa_dec.c index 39741dbfe..435db1cae 100644 --- a/lib_dec/ivas_omasa_dec.c +++ b/lib_dec/ivas_omasa_dec.c @@ -648,8 +648,10 @@ ivas_error ivas_omasa_dirac_td_binaural_jbm( { int16_t n; float data_separated_objects[MAX_NUM_OBJECTS][L_FRAME48k]; + float gain = OMASA_TDREND_MATCHING_GAIN; ivas_error error; float *p_sepobj[MAX_NUM_OBJECTS]; + float *tc_local[MAX_TRANSPORT_CHANNELS]; #ifdef SPLIT_REND_WITH_HEAD_ROT int16_t slot_idx_start; @@ -661,6 +663,21 @@ ivas_error ivas_omasa_dirac_td_binaural_jbm( p_sepobj[n] = &data_separated_objects[n][0]; } + /* Delay the object signals to match the CLDFB delay. Delay the whole buffer with the first rendering call of the stretched buffer. */ + if ( st_ivas->hSpatParamRendCom->slots_rendered == 0 ) + { + int16_t tcBufferSize; + + tcBufferSize = st_ivas->hSpatParamRendCom->num_slots * st_ivas->hSpatParamRendCom->slot_size; + + for ( n = 0; n < st_ivas->nchan_ism; n++ ) + { + tc_local[n] = st_ivas->hTcBuffer->tc[n + 2]; + v_multc( tc_local[n], gain, tc_local[n], tcBufferSize ); + delay_signal( tc_local[n], tcBufferSize, st_ivas->hMasaIsmData->delayBuffer[n], st_ivas->hMasaIsmData->delayBuffer_size ); + } + } + ivas_dirac_dec_binaural_render( st_ivas, nSamplesAsked, nSamplesRendered, nSamplesAvailable, nchan_transport, output_f ); /* reset combined orientation access index before calling the td renderer */ diff --git a/lib_enc/acelp_core_switch_enc.c b/lib_enc/acelp_core_switch_enc.c index 0d65ed608..efa33ff8a 100644 --- a/lib_enc/acelp_core_switch_enc.c +++ b/lib_enc/acelp_core_switch_enc.c @@ -123,32 +123,11 @@ void acelp_core_switch_enc( } } -#ifdef FIX_I4_OL_PITCH - if ( st->last_codec_mode == MODE1 ) - { - /* in MODE1 T_op is at 12.8 kHz */ - if ( st->last_L_frame != L_FRAME ) /* ACELP@16k core -> convert T_op to 16 kHz */ - { - T_op[0] = (short) ( 1.25f * T_op[0] + 0.5f ); - T_op[1] = (short) ( 1.25f * T_op[1] + 0.5f ); - } - } - else - { - /* in MODE2 T_op is at 16 kHz */ - if ( st->last_L_frame == L_FRAME ) /* ACELP@12.8k core -> convert T_op to 12.8 kHz */ - { - T_op[0] = (short) ( 0.8f * T_op[0] + 0.5f ); - T_op[1] = (short) ( 0.8f * T_op[1] + 0.5f ); - } - } -#else if ( st->last_L_frame != L_FRAME ) /* ACELP@16k core */ { T_op[0] = (short) ( 1.25f * T_op[0] + 0.5f ); T_op[1] = (short) ( 1.25f * T_op[1] + 0.5f ); } -#endif /*----------------------------------------------------------------* * Excitation encoding *----------------------------------------------------------------*/ diff --git a/lib_enc/evs_enc.c b/lib_enc/evs_enc.c index cc01594b7..0398876b9 100644 --- a/lib_enc/evs_enc.c +++ b/lib_enc/evs_enc.c @@ -95,9 +95,7 @@ ivas_error evs_enc( int16_t padBits; float realBuffer[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; /* real buffer */ float imagBuffer[CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; /* imag buffer */ -#ifndef FIX_I4_OL_PITCH int16_t pitch_orig[3]; /* original open-loop pitch values that might be altered in core_acelp_tcx20_switching() within MODE2 */ -#endif ivas_error error; error = IVAS_ERR_OK; @@ -170,11 +168,7 @@ ivas_error evs_enc( * Pre-processing *---------------------------------------------------------------------*/ -#ifdef FIX_I4_OL_PITCH - pre_proc( st, input_frame, old_inp_12k8, old_inp_16k, &inp, fr_bands, Etot, &ener, A, Aw, epsP, lsp_new, lsp_mid, &vad_hover_flag, &attack_flag, new_inp_resamp16k, &Voicing_flag, realBuffer, imagBuffer, &hq_core_type ); -#else pre_proc( st, input_frame, old_inp_12k8, old_inp_16k, &inp, fr_bands, &ener, pitch_orig, A, Aw, epsP, lsp_new, lsp_mid, &vad_hover_flag, &attack_flag, new_inp_resamp16k, &Voicing_flag, realBuffer, imagBuffer, &hq_core_type ); -#endif if ( st->mdct_sw == MODE2 ) { @@ -263,12 +257,10 @@ ivas_error evs_enc( core_switching_post_enc( st, old_inp_12k8, old_inp_16k, A ); -#ifndef FIX_I4_OL_PITCH if ( st->core == HQ_CORE ) { mvs2s( pitch_orig, st->pitch, 3 ); /* original open-loop pitch values might be altered in core_acelp_tcx20_switching() */ } -#endif } else /* MODE2 */ @@ -293,9 +285,7 @@ ivas_error evs_enc( /* Call main encoding function */ enc_acelp_tcx_main( st, old_inp_16k + L_INP_MEM, Aw, lsp_new, lsp_mid, bwe_exc_extended, voice_factors, pitch_buf, vad_hover_flag ); -#ifndef FIX_I4_OL_PITCH mvs2s( pitch_orig, st->pitch, 3 ); /* populate the original OL pitch values back */ -#endif /*---------------------------------------------------------------------* * Postprocessing for Mode 1/2 switching diff --git a/lib_enc/pre_proc.c b/lib_enc/pre_proc.c index c035ef5ac..d6ddbc2b6 100644 --- a/lib_enc/pre_proc.c +++ b/lib_enc/pre_proc.c @@ -60,9 +60,7 @@ void pre_proc( float **inp, /* o : ptr. to inp. signal in the current frame*/ float fr_bands[2 * NB_BANDS], /* i : energy in frequency bands */ float *ener, /* o : residual energy from Levinson-Durbin */ -#ifndef FIX_I4_OL_PITCH int16_t pitch_orig[3], /* o : open-loop pitch values for quantization */ -#endif float A[NB_SUBFR16k * ( M + 1 )], /* i/o: A(z) unquantized for the 4 subframes */ float Aw[NB_SUBFR16k * ( M + 1 )], /* i/o: weighted A(z) unquantized for subframes */ float epsP[M + 1], /* i/o: LP prediction errors */ @@ -849,9 +847,7 @@ void pre_proc( * ACELP/TCX20 Switching Decision *-----------------------------------------------------------------*/ -#ifndef FIX_I4_OL_PITCH mvs2s( st->pitch, pitch_orig, 3 ); -#endif if ( st->codec_mode == MODE2 ) { diff --git a/lib_rend/ivas_objectRenderer.c b/lib_rend/ivas_objectRenderer.c index bbb5f8c1a..b80732620 100644 --- a/lib_rend/ivas_objectRenderer.c +++ b/lib_rend/ivas_objectRenderer.c @@ -759,6 +759,8 @@ ivas_error ivas_td_binaural_renderer_ext( } + + /*---------------------------------------------------------------------* * angles_to_vec() * -- GitLab From 051f07b0500bdd093987a84f4fde05a44bf08483 Mon Sep 17 00:00:00 2001 From: rtyag Date: Tue, 21 Jan 2025 15:28:17 +1100 Subject: [PATCH 18/33] fix for failing OSBA HT test --- lib_dec/ivas_dirac_dec.c | 90 +++++++--- lib_rend/ivas_dirac_output_synthesis_dec.c | 197 ++++++++++++++++++++- lib_rend/ivas_dirac_rend.c | 4 + lib_rend/ivas_prot_rend.h | 4 + 4 files changed, 265 insertions(+), 30 deletions(-) diff --git a/lib_dec/ivas_dirac_dec.c b/lib_dec/ivas_dirac_dec.c index 4a9b7cebe..53223dd6b 100644 --- a/lib_dec/ivas_dirac_dec.c +++ b/lib_dec/ivas_dirac_dec.c @@ -1849,16 +1849,37 @@ void ivas_dirac_dec_render_sf( set_zero( surCohRatio, hSpatParamRendCom->num_freq_bands ); } } - ivas_dirac_dec_compute_directional_responses( hSpatParamRendCom, - hDirACRend, - st_ivas->hVBAPdata, - st_ivas->hMasa == NULL ? NULL : st_ivas->hMasa->data.band_mapping, - st_ivas->hMasaIsmData, - azimuth, - elevation, - md_idx, - surCohRatio, - hodirac_flag ); + + if ( st_ivas->hCombinedOrientationData && st_ivas->hCombinedOrientationData->enableCombinedOrientation[st_ivas->hCombinedOrientationData->subframe_idx] && st_ivas->hCombinedOrientationData->shd_rot_max_order == 1 ) + { + ivas_dirac_dec_compute_directional_responses( hSpatParamRendCom, + hDirACRend, + st_ivas->hVBAPdata, + st_ivas->hMasa == NULL ? NULL : st_ivas->hMasa->data.band_mapping, + st_ivas->hMasaIsmData, + azimuth, + elevation, + md_idx, + surCohRatio, + st_ivas->hCombinedOrientationData->shd_rot_max_order, + p_Rmat, + hodirac_flag ); + } + else + { + ivas_dirac_dec_compute_directional_responses( hSpatParamRendCom, + hDirACRend, + st_ivas->hVBAPdata, + st_ivas->hMasa == NULL ? NULL : st_ivas->hMasa->data.band_mapping, + st_ivas->hMasaIsmData, + azimuth, + elevation, + md_idx, + surCohRatio, + 0, + NULL, + hodirac_flag ); + } } if ( st_ivas->ivas_format == MASA_ISM_FORMAT && nchan_transport == 2 ) @@ -2188,19 +2209,42 @@ void ivas_dirac_dec_render_sf( } /*Compute PSDs*/ - ivas_dirac_dec_output_synthesis_process_slot( reference_power, - p_onset_filter, - azimuth, - elevation, - hSpatParamRendCom->diffuseness_vector[md_idx], - hSpatParamRendCom, - hDirACRend, - st_ivas->hVBAPdata, - hDirACRend->hOutSetup, - nchan_transport, - md_idx, - hodirac_flag, - hDirAC->hConfig->dec_param_estim ); + if ( st_ivas->hCombinedOrientationData && st_ivas->hCombinedOrientationData->enableCombinedOrientation[st_ivas->hCombinedOrientationData->subframe_idx] && st_ivas->hCombinedOrientationData->shd_rot_max_order > 0 ) + { + ivas_dirac_dec_output_synthesis_process_slot( reference_power, + p_onset_filter, + azimuth, + elevation, + hSpatParamRendCom->diffuseness_vector[md_idx], + hSpatParamRendCom, + hDirACRend, + st_ivas->hCombinedOrientationData->shd_rot_max_order, + p_Rmat, + st_ivas->hVBAPdata, + hDirACRend->hOutSetup, + nchan_transport, + md_idx, + hodirac_flag, + hDirAC->hConfig->dec_param_estim ); + } + else + { + ivas_dirac_dec_output_synthesis_process_slot( reference_power, + p_onset_filter, + azimuth, + elevation, + hSpatParamRendCom->diffuseness_vector[md_idx], + hSpatParamRendCom, + hDirACRend, + 0, + 0, + st_ivas->hVBAPdata, + hDirACRend->hOutSetup, + nchan_transport, + md_idx, + hodirac_flag, + hDirAC->hConfig->dec_param_estim ); + } if ( hDirAC->hConfig->dec_param_estim ) { diff --git a/lib_rend/ivas_dirac_output_synthesis_dec.c b/lib_rend/ivas_dirac_output_synthesis_dec.c index d9f091182..8ee3b1e4f 100644 --- a/lib_rend/ivas_dirac_output_synthesis_dec.c +++ b/lib_rend/ivas_dirac_output_synthesis_dec.c @@ -542,9 +542,11 @@ void ivas_dirac_dec_output_synthesis_process_slot( const float *diffuseness, SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, /* i/o: common spatial renderer data handle */ DIRAC_REND_HANDLE hDirACRend, /* i/o: DirAC renderer handle */ - const VBAP_HANDLE hVBAPdata, /* i : VBAP structure */ - const IVAS_OUTPUT_SETUP hOutSetup, /* i : output setup structure */ - const int16_t nchan_transport, /* i : number of transport channels*/ + const int16_t sh_rot_max_order, + const float *p_Rmat, /* i : rotation matrix */ + const VBAP_HANDLE hVBAPdata, /* i : VBAP structure */ + const IVAS_OUTPUT_SETUP hOutSetup, /* i : output setup structure */ + const int16_t nchan_transport, /* i : number of transport channels*/ const int16_t md_idx, const int16_t hodirac_flag, /* i : flag to indicate HO-DirAC mode */ const int16_t dec_param_estim ) @@ -588,6 +590,8 @@ void ivas_dirac_dec_output_synthesis_process_slot( elevation, md_idx, NULL, + 2, + p_Rmat, hodirac_flag ); } @@ -634,6 +638,8 @@ void ivas_dirac_dec_output_synthesis_process_slot( elevation, md_idx, NULL, + sh_rot_max_order, + p_Rmat, hodirac_flag ); if ( hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD ) @@ -1565,6 +1571,169 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls( } +/*------------------------------------------------------------------------- + * ivas_dirac_dec_get_response_split_order() + * + * calculate reponse, 1 degree resolution + *------------------------------------------------------------------------*/ + +static void ivas_dirac_dec_get_response_split_order( + const int16_t azimuth, + const int16_t elevation, + float *response, + const int16_t shd_rot_max_order, + const float *p_Rmat ) +{ + int16_t index_azimuth, index_elevation; + int16_t el, e, az; + float cos_1, cos_2, sin_1, cos_az[3]; + float sin_az[3]; + float f, c; + int16_t l, m; + int16_t b, b1, b_2, b1_2, a; + float dv_0, dv_1, dv_2, dv_r_0, dv_r_1, dv_r_2; + float w; + + push_wmops( "ivas_dirac_dec_get_response_split_order" ); + + index_azimuth = ( azimuth + 180 ) % 360; + index_elevation = elevation + 90; + e = index_elevation > 90 ? -1 : 1; + el = index_elevation > 90 ? 180 - index_elevation : index_elevation; + + az = index_azimuth > 180 ? 360 - index_azimuth : index_azimuth; + f = index_azimuth > 180 ? -1.0f : 1.0f; + + cos_1 = dirac_gains_trg_term[az][0]; + sin_1 = f * dirac_gains_trg_term[az][1]; + + cos_2 = cos_1 * cos_1; + + cos_az[0] = cos_1; + cos_az[1] = 2.0f * cos_2 - 1.0f; + cos_az[2] = 2.0f * cos_1 * cos_az[1] - cos_az[0]; + sin_az[0] = sin_1; + sin_az[1] = sin_1 * 2.0f * cos_1; + sin_az[2] = sin_1 * ( 4.0f * cos_2 - 1.0f ); + + response[0] = 1.0f; + for ( l = 1; l <= shd_rot_max_order; l++ ) + { + b_2 = l * l; + b1_2 = l * l + 2 * l; + for ( m = 0; m < l; m += 2 ) + { + b = b_2 + m; + a = dirac_gains_P_idx[b]; + c = SQRT2 * dirac_gains_norm_term[a] * dirac_gains_Pnm[el][a]; + + response[b] = c * sin_az[l - m - 1]; + + b1 = b1_2 - m; + response[b1] = c * cos_az[l - m - 1]; + } + + for ( m = 1; m < l; m += 2 ) + { + b = b_2 + m; + a = dirac_gains_P_idx[b]; + c = SQRT2 * dirac_gains_norm_term[a] * dirac_gains_Pnm[el][a]; + c = c * e; + + response[b] = c * sin_az[l - m - 1]; + + b1 = b1_2 - m; + response[b1] = c * cos_az[l - m - 1]; + } + + b = b_2 + l; + a = dirac_gains_P_idx[b]; + c = dirac_gains_norm_term[a] * dirac_gains_Pnm[el][a]; + if ( l % 2 == 1 ) + { + c = c * e; + } + + response[b] = c; + } + + /*Conversion spherical to cartesian coordinates*/ + w = -dirac_gains_trg_term[el][1]; + dv_0 = w * cos_1; + dv_1 = w * sin_1; + dv_2 = e * dirac_gains_trg_term[el][0]; + + /*Rotation mtx multiplication*/ + dv_r_0 = p_Rmat[0] * dv_0 + p_Rmat[1] * dv_1 + p_Rmat[2] * dv_2; + dv_r_1 = p_Rmat[3] * dv_0 + p_Rmat[4] * dv_1 + p_Rmat[5] * dv_2; + dv_r_2 = p_Rmat[6] * dv_0 + p_Rmat[7] * dv_1 + p_Rmat[8] * dv_2; + + index_azimuth = ( (int16_t) ( atan2f( dv_r_1, dv_r_0 ) * _180_OVER_PI ) + 180 ) % 360; + index_elevation = (int16_t) ( atan2f( dv_r_2, sqrtf( dv_r_0 * dv_r_0 + dv_r_1 * dv_r_1 ) ) * _180_OVER_PI ) + 90; + e = index_elevation > 90 ? -1 : 1; + el = index_elevation > 90 ? 180 - index_elevation : index_elevation; + + az = index_azimuth > 180 ? 360 - index_azimuth : index_azimuth; + f = index_azimuth > 180 ? -1.0f : 1.0f; + + cos_1 = dirac_gains_trg_term[az][0]; + sin_1 = f * dirac_gains_trg_term[az][1]; + + cos_2 = cos_1 * cos_1; + + cos_az[0] = cos_1; + cos_az[1] = 2.0f * cos_2 - 1.0f; + cos_az[2] = 2.0f * cos_1 * cos_az[1] - cos_az[0]; + sin_az[0] = sin_1; + sin_az[1] = sin_1 * 2.0f * cos_1; + sin_az[2] = sin_1 * ( 4.0f * cos_2 - 1.0f ); + + for ( l = shd_rot_max_order + 1; l <= 3; l++ ) + { + b_2 = l * l; + b1_2 = l * l + 2 * l; + for ( m = 0; m < l; m += 2 ) + { + b = b_2 + m; + a = dirac_gains_P_idx[b]; + c = SQRT2 * dirac_gains_norm_term[a] * dirac_gains_Pnm[el][a]; + + response[b] = c * sin_az[l - m - 1]; + + b1 = b1_2 - m; + response[b1] = c * cos_az[l - m - 1]; + } + + for ( m = 1; m < l; m += 2 ) + { + b = b_2 + m; + a = dirac_gains_P_idx[b]; + c = SQRT2 * dirac_gains_norm_term[a] * dirac_gains_Pnm[el][a]; + c = c * e; + + response[b] = c * sin_az[l - m - 1]; + + b1 = b1_2 - m; + response[b1] = c * cos_az[l - m - 1]; + } + + b = b_2 + l; + a = dirac_gains_P_idx[b]; + c = dirac_gains_norm_term[a] * dirac_gains_Pnm[el][a]; + if ( l % 2 == 1 ) + { + c = c * e; + } + + response[b] = c; + } + + pop_wmops(); + + return; +} + + /*------------------------------------------------------------------------- * ivas_dirac_dec_compute_directional_responses() * @@ -1581,7 +1750,9 @@ void ivas_dirac_dec_compute_directional_responses( const int16_t *elevation, const int16_t md_idx, const float *surCohRatio, - const int16_t hodirac_flag /* i : flag to indicate HO-DirAC mode */ + const int16_t shd_rot_max_order, /* i : split-order rotation method */ + const float *p_Rmat, /* i : rotation matrix */ + const int16_t hodirac_flag /* i : flag to indicate HO-DirAC mode */ ) { int16_t k, l; @@ -1651,11 +1822,23 @@ void ivas_dirac_dec_compute_directional_responses( set_f( direct_response_hoa, 1.0f, MAX_OUTPUT_CHANNELS ); set_f( direct_response_dir2, 1.0f, MAX_OUTPUT_CHANNELS ); - ivas_dirac_dec_get_response( azimuth[k], elevation[k], direct_response_hoa, hDirACRend->hOutSetup.ambisonics_order ); + if ( p_Rmat != 0 ) + { + ivas_dirac_dec_get_response_split_order( azimuth[k], elevation[k], direct_response_hoa, shd_rot_max_order, p_Rmat ); - if ( hodirac_flag ) + if ( hodirac_flag ) + { + ivas_dirac_dec_get_response_split_order( azimuth2[k], elevation2[k], direct_response_dir2, shd_rot_max_order, p_Rmat ); + } + } + else { - ivas_dirac_dec_get_response( azimuth2[k], elevation2[k], direct_response_dir2, hDirACRend->hOutSetup.ambisonics_order ); + ivas_dirac_dec_get_response( azimuth[k], elevation[k], direct_response_hoa, hDirACRend->hOutSetup.ambisonics_order ); + + if ( hodirac_flag ) + { + ivas_dirac_dec_get_response( azimuth2[k], elevation2[k], direct_response_dir2, hDirACRend->hOutSetup.ambisonics_order ); + } } if ( masa_band_mapping == NULL && hDirACRend->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD ) diff --git a/lib_rend/ivas_dirac_rend.c b/lib_rend/ivas_dirac_rend.c index 14088be0a..9fa1ddd8e 100644 --- a/lib_rend/ivas_dirac_rend.c +++ b/lib_rend/ivas_dirac_rend.c @@ -2216,6 +2216,8 @@ static void ivas_masa_ext_dirac_render_sf( elevation, md_idx, surCohRatio, + 0, + NULL, 0 ); @@ -2370,6 +2372,8 @@ static void ivas_masa_ext_dirac_render_sf( hSpatParamRendCom->diffuseness_vector[md_idx], hSpatParamRendCom, hDirACRend, + 0, + 0, hMasaExtRend->hVBAPdata, hDirACRend->hOutSetup, nchan_transport, diff --git a/lib_rend/ivas_prot_rend.h b/lib_rend/ivas_prot_rend.h index d05b5ea7b..1d1fb670e 100644 --- a/lib_rend/ivas_prot_rend.h +++ b/lib_rend/ivas_prot_rend.h @@ -435,6 +435,8 @@ void ivas_dirac_dec_output_synthesis_process_slot( const float *diffuseness, SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, /* i/o: common spatial renderer data handle */ DIRAC_REND_HANDLE hDirACRend, /* i/o: DirAC renderer handle */ + const int16_t sh_rot_max_order, + const float *p_Rmat, /* i : rotation matrix */ const VBAP_HANDLE hVBAPdata, /* i : VBAP structure */ const IVAS_OUTPUT_SETUP hOutSetup, /* i : output setup structure */ const int16_t nchan_transport, /* i : number of transport channels */ @@ -501,6 +503,8 @@ void ivas_dirac_dec_compute_directional_responses( const int16_t *elevation, const int16_t md_idx, const float *surCohRatio, + const int16_t shd_rot_max_order, /* i : split-order rotation method */ + const float *p_Rmat, /* i : rotation matrix */ const int16_t hodirac_flag /* i : flag to indicate HO-DirAC mode */ ); -- GitLab From e44fc56faab533b353f8bdfb34366d9583bf4de8 Mon Sep 17 00:00:00 2001 From: rtyag Date: Tue, 28 Jan 2025 23:14:19 +1100 Subject: [PATCH 19/33] revert changes in ci yml file --- .gitlab-ci.yml | 98 +++++++++++++++++++++++++++++--------------------- 1 file changed, 58 insertions(+), 40 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index d24fc2c66..b36c59ebf 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -98,7 +98,7 @@ workflow: IVAS_PIPELINE_NAME: 'Voip BE test on $CI_COMMIT_BRANCH' - if: $CI_PIPELINE_SOURCE == 'schedule' # Scheduled in any branch variables: - IVAS_PIPELINE_NAME: 'Scheduled pipeline: $CI_COMMIT_BRANCH' + IVAS_PIPELINE_NAME: 'Scheduled pipeline: $CI_COMMIT_BRANCH' stages: @@ -205,6 +205,7 @@ stages: - git restore . - git checkout $current_commit_sha + .build-reference-and-dut-binaries: &build-reference-and-dut-binaries ### build reference binaries - *build-reference-binaries @@ -427,7 +428,6 @@ stages: needs: [] timeout: "4 minutes" tags: - # TODO: set up ivas-basop-windows runners - ivas-windows # template for test jobs on linux that need the TESTV_DIR @@ -1003,11 +1003,19 @@ build-codec-sanitizers-linux: - *activate-Werror-linux - bash ci/build_codec_sanitizers_linux.sh - # TODO: reactivate once windows runners are available in BASOP project -.build-codec-windows-msbuild: +build-codec-windows-msbuild: + rules: + - if: $CI_PIPELINE_SOURCE == 'web' + - if: $CI_PIPELINE_SOURCE == 'push' && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH + - if: $CI_PIPELINE_SOURCE == 'merge_request_event' # trigger build job for all MRs + - if: $CI_PIPELINE_SOURCE == 'schedule' + - if: $CI_PIPELINE_SOURCE == 'push' + when: never extends: - .build-job-windows - - .rules-basis + timeout: "7 minutes" + tags: + - ivas-windows script: - *print-common-info-windows - *activate-WX-windows @@ -1908,11 +1916,21 @@ ivas-interop-on-merge-request: - rm artifacts.zip - rm -rf $public_dir + ### 2. part: setup specific for BASOP repo + # hack for using the reference encoder -> need to build manually to make script use ref enc and BASOP dec + - mkdir COMPLEXITY + - cp IVAS_cod_ref COMPLEXITY/IVAS_cod + # build branch code aain with instrumentation + - make clean + - bash scripts/prepare_instrumentation.sh -p BASOP -m MEM_ONLY + - make -j -C $INSTR_DIR + - cp $INSTR_DIR/IVAS_dec COMPLEXITY/IVAS_dec + .complexity-measurements-prepare-artifacts: &complexity-measurements-prepare-artifacts # prepare artifacts -> move to public directory - public_dir="$CI_JOB_NAME-public" - mkdir $public_dir - - mv -f wmops/log_*_all.txt ./*.js ${public_dir}/ + - mv -f wmops/log_*_all.txt wmops/*.js ${public_dir}/ # move logfiles for links - mkdir $public_dir/logs # first move logs @@ -1920,7 +1938,6 @@ ivas-interop-on-merge-request: - echo $log_files - ls wmops/logs - for f in $log_files; do [ -f wmops/logs/$f ] && mv wmops/logs/$f $public_dir/logs/$f; done - - mv wmops/logs/latest_WMOPS.csv $public_dir/logs/ # copy index page blueprint - cp ci/complexity_measurements/index_complexity.html ${public_dir}/index.html # patch the format in the title @@ -1940,6 +1957,7 @@ ivas-interop-on-merge-request: - *print-common-info - *update-scripts-repo - *update-ltv-repo + - *build-reference-and-dut-binaries - *complexity-measurements-setup - which coan artifacts: @@ -1957,7 +1975,7 @@ complexity-stereo-in-stereo-out: script: - in_format=stereo - out_format=stereo - - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" full basop || ret_val=$? + - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" mem_only || ret_val=$? - *complexity-measurements-prepare-artifacts - exit $ret_val @@ -1972,7 +1990,7 @@ complexity-ism-in-binaural-out: - in_format=ISM - out_format=BINAURAL - ret_val=0 - - bash ci/complexity_measurements/getWmops.sh "ISM+1 ISM+2 ISM+3 ISM+4" "$out_format" full basop || ret_val=$? + - bash ci/complexity_measurements/getWmops.sh "ISM+1 ISM+2 ISM+3 ISM+4" "$out_format" || ret_val=$? - *complexity-measurements-prepare-artifacts - exit $ret_val @@ -1987,7 +2005,7 @@ complexity-ism-in-binaural_room_ir-out: - in_format=ISM - out_format=BINAURAL_ROOM_IR - ret_val=0 - - bash ci/complexity_measurements/getWmops.sh "ISM+1 ISM+2 ISM+3 ISM+4" "$out_format" full basop || ret_val=$? + - bash ci/complexity_measurements/getWmops.sh "ISM+1 ISM+2 ISM+3 ISM+4" "$out_format" || ret_val=$? - *complexity-measurements-prepare-artifacts - exit $ret_val @@ -1997,12 +2015,12 @@ complexity-ism-in-ext-out: rules: - if: $MEASURE_COMPLEXITY_LINUX when: delayed - start_in: 3 hours + start_in: 3 hours 30 minutes script: - in_format=ISM - out_format=EXT - ret_val=0 - - bash ci/complexity_measurements/getWmops.sh "ISM+1 ISM+2 ISM+3 ISM+4" "$out_format" full basop || ret_val=$? + - bash ci/complexity_measurements/getWmops.sh "ISM+1 ISM+2 ISM+3 ISM+4" "$out_format" || ret_val=$? - *complexity-measurements-prepare-artifacts - exit $ret_val @@ -2012,12 +2030,12 @@ complexity-sba-hoa3-in-hoa3-out: rules: - if: $MEASURE_COMPLEXITY_LINUX when: delayed - start_in: 4 hours + start_in: 4 hours 30 minutes script: - in_format=HOA3 - out_format=HOA3 - ret_val=0 - - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" full basop || ret_val=$? + - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" || ret_val=$? - *complexity-measurements-prepare-artifacts - exit $ret_val @@ -2027,12 +2045,12 @@ complexity-sba-hoa3-in-binaural-out: rules: - if: $MEASURE_COMPLEXITY_LINUX when: delayed - start_in: 5 hours + start_in: 5 hours 30 minutes script: - in_format=HOA3 - out_format=BINAURAL - ret_val=0 - - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" full basop || ret_val=$? + - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" || ret_val=$? - *complexity-measurements-prepare-artifacts - exit $ret_val @@ -2042,12 +2060,12 @@ complexity-sba-hoa3-in-binaural_room_ir-out: rules: - if: $MEASURE_COMPLEXITY_LINUX when: delayed - start_in: 6 hours + start_in: 6 hours 30 minutes script: - in_format=HOA3 - out_format=BINAURAL_ROOM_IR - ret_val=0 - - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" full basop || ret_val=$? + - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" || ret_val=$? - *complexity-measurements-prepare-artifacts - exit $ret_val @@ -2057,12 +2075,12 @@ complexity-mc-in-7_1_4-out: rules: - if: $MEASURE_COMPLEXITY_LINUX when: delayed - start_in: 7 hours + start_in: 7 hours 30 minutes script: - in_format=MC - out_format=7_1_4 - ret_val=0 - - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" full basop || ret_val=$? + - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" || ret_val=$? - *complexity-measurements-prepare-artifacts - exit $ret_val @@ -2072,12 +2090,12 @@ complexity-mc-in-binaural-out: rules: - if: $MEASURE_COMPLEXITY_LINUX when: delayed - start_in: 8 hours + start_in: 10 hours script: - in_format=MC - out_format=BINAURAL - ret_val=0 - - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" full basop || ret_val=$? + - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" || ret_val=$? - *complexity-measurements-prepare-artifacts - exit $ret_val @@ -2087,12 +2105,12 @@ complexity-mc-in-binaural_room_ir-out: rules: - if: $MEASURE_COMPLEXITY_LINUX when: delayed - start_in: 9 hours + start_in: 12 hours 30 minutes script: - in_format=MC - out_format=BINAURAL_ROOM_IR - ret_val=0 - - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" full basop || ret_val=$? + - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" || ret_val=$? - *complexity-measurements-prepare-artifacts - exit $ret_val @@ -2102,12 +2120,12 @@ complexity-masa-in-ext-out: rules: - if: $MEASURE_COMPLEXITY_LINUX when: delayed - start_in: 10 hours + start_in: 15 hours script: - in_format=MASA - out_format=EXT - ret_val=0 - - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" full basop || ret_val=$? + - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" || ret_val=$? - *complexity-measurements-prepare-artifacts - exit $ret_val @@ -2117,12 +2135,12 @@ complexity-masa-in-binaural-out: rules: - if: $MEASURE_COMPLEXITY_LINUX when: delayed - start_in: 11 hours + start_in: 16 hours script: - in_format=MASA - out_format=BINAURAL - ret_val=0 - - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" full basop || ret_val=$? + - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" || ret_val=$? - *complexity-measurements-prepare-artifacts - exit $ret_val @@ -2132,12 +2150,12 @@ complexity-masa-in-hoa3-out: rules: - if: $MEASURE_COMPLEXITY_LINUX when: delayed - start_in: 12 hours + start_in: 17 hours script: - in_format=MASA - out_format=HOA3 - ret_val=0 - - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" full basop || ret_val=$? + - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" || ret_val=$? - *complexity-measurements-prepare-artifacts - exit $ret_val @@ -2152,7 +2170,7 @@ complexity-masa-in-hoa3-out: # - in_format=OMASA # - out_format=EXT # - ret_val=0 -# - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" full basop || ret_val=$? +# - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" || ret_val=$? # - *complexity-measurements-prepare-artifacts # - exit $ret_val @@ -2162,12 +2180,12 @@ complexity-omasa-in-binaural-out: rules: - if: $MEASURE_COMPLEXITY_LINUX when: delayed - start_in: 14 hours + start_in: 18 hours script: - in_format=OMASA - out_format=BINAURAL - ret_val=0 - - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" full basop || ret_val=$? + - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" || ret_val=$? - *complexity-measurements-prepare-artifacts - exit $ret_val @@ -2177,12 +2195,12 @@ complexity-omasa-in-hoa3-out: rules: - if: $MEASURE_COMPLEXITY_LINUX when: delayed - start_in: 15 hours + start_in: 20 hours script: - in_format=OMASA - out_format=HOA3 - ret_val=0 - - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" full basop || ret_val=$? + - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" || ret_val=$? - *complexity-measurements-prepare-artifacts - exit $ret_val @@ -2192,12 +2210,12 @@ complexity-StereoDmxEVS-stereo-in-mono-out: rules: - if: $MEASURE_COMPLEXITY_LINUX when: delayed - start_in: 16 hours + start_in: 22 hours script: - in_format=StereoDmxEVS - out_format=mono - ret_val=0 - - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" full basop || ret_val=$? + - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" || ret_val=$? - *complexity-measurements-prepare-artifacts - exit $ret_val @@ -2222,7 +2240,7 @@ complexity-osba-in-binaural-out: rules: - if: $MEASURE_COMPLEXITY_LINUX when: delayed - start_in: 18 hours + start_in: 22 hours 30 minutes script: - in_format=OSBA - out_format=BINAURAL @@ -2237,7 +2255,7 @@ complexity-osba-in-binaural_room_ir-out: rules: - if: $MEASURE_COMPLEXITY_LINUX when: delayed - start_in: 19 hours + start_in: 25 hours script: - in_format=OSBA - out_format=BINAURAL_ROOM_IR @@ -2258,7 +2276,7 @@ pages: - *update-scripts-repo - python3 ci/setup_pages.py - ls - - ls public + - ls -lh public artifacts: paths: - public -- GitLab From 4c79a00a87f74afe4f7c7a672da3c1e0511ea99a Mon Sep 17 00:00:00 2001 From: rtyag Date: Fri, 31 Jan 2025 21:59:52 +1100 Subject: [PATCH 20/33] revert change in git ci yml file --- .gitlab-ci.yml | 83 ++++++++++++++++++++++---------------------------- 1 file changed, 36 insertions(+), 47 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index b36c59ebf..d5b078e8b 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -98,7 +98,7 @@ workflow: IVAS_PIPELINE_NAME: 'Voip BE test on $CI_COMMIT_BRANCH' - if: $CI_PIPELINE_SOURCE == 'schedule' # Scheduled in any branch variables: - IVAS_PIPELINE_NAME: 'Scheduled pipeline: $CI_COMMIT_BRANCH' + IVAS_PIPELINE_NAME: 'Scheduled pipeline: $CI_COMMIT_BRANCH' stages: @@ -205,7 +205,6 @@ stages: - git restore . - git checkout $current_commit_sha - .build-reference-and-dut-binaries: &build-reference-and-dut-binaries ### build reference binaries - *build-reference-binaries @@ -1916,21 +1915,11 @@ ivas-interop-on-merge-request: - rm artifacts.zip - rm -rf $public_dir - ### 2. part: setup specific for BASOP repo - # hack for using the reference encoder -> need to build manually to make script use ref enc and BASOP dec - - mkdir COMPLEXITY - - cp IVAS_cod_ref COMPLEXITY/IVAS_cod - # build branch code aain with instrumentation - - make clean - - bash scripts/prepare_instrumentation.sh -p BASOP -m MEM_ONLY - - make -j -C $INSTR_DIR - - cp $INSTR_DIR/IVAS_dec COMPLEXITY/IVAS_dec - .complexity-measurements-prepare-artifacts: &complexity-measurements-prepare-artifacts # prepare artifacts -> move to public directory - public_dir="$CI_JOB_NAME-public" - mkdir $public_dir - - mv -f wmops/log_*_all.txt wmops/*.js ${public_dir}/ + - mv -f wmops/log_*_all.txt ./*.js ${public_dir}/ # move logfiles for links - mkdir $public_dir/logs # first move logs @@ -1938,6 +1927,7 @@ ivas-interop-on-merge-request: - echo $log_files - ls wmops/logs - for f in $log_files; do [ -f wmops/logs/$f ] && mv wmops/logs/$f $public_dir/logs/$f; done + - mv wmops/logs/latest_WMOPS.csv $public_dir/logs/ # copy index page blueprint - cp ci/complexity_measurements/index_complexity.html ${public_dir}/index.html # patch the format in the title @@ -1957,7 +1947,6 @@ ivas-interop-on-merge-request: - *print-common-info - *update-scripts-repo - *update-ltv-repo - - *build-reference-and-dut-binaries - *complexity-measurements-setup - which coan artifacts: @@ -1975,7 +1964,7 @@ complexity-stereo-in-stereo-out: script: - in_format=stereo - out_format=stereo - - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" mem_only || ret_val=$? + - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" full basop || ret_val=$? - *complexity-measurements-prepare-artifacts - exit $ret_val @@ -1990,7 +1979,7 @@ complexity-ism-in-binaural-out: - in_format=ISM - out_format=BINAURAL - ret_val=0 - - bash ci/complexity_measurements/getWmops.sh "ISM+1 ISM+2 ISM+3 ISM+4" "$out_format" || ret_val=$? + - bash ci/complexity_measurements/getWmops.sh "ISM+1 ISM+2 ISM+3 ISM+4" "$out_format" full basop || ret_val=$? - *complexity-measurements-prepare-artifacts - exit $ret_val @@ -2005,7 +1994,7 @@ complexity-ism-in-binaural_room_ir-out: - in_format=ISM - out_format=BINAURAL_ROOM_IR - ret_val=0 - - bash ci/complexity_measurements/getWmops.sh "ISM+1 ISM+2 ISM+3 ISM+4" "$out_format" || ret_val=$? + - bash ci/complexity_measurements/getWmops.sh "ISM+1 ISM+2 ISM+3 ISM+4" "$out_format" full basop || ret_val=$? - *complexity-measurements-prepare-artifacts - exit $ret_val @@ -2015,12 +2004,12 @@ complexity-ism-in-ext-out: rules: - if: $MEASURE_COMPLEXITY_LINUX when: delayed - start_in: 3 hours 30 minutes + start_in: 3 hours script: - in_format=ISM - out_format=EXT - ret_val=0 - - bash ci/complexity_measurements/getWmops.sh "ISM+1 ISM+2 ISM+3 ISM+4" "$out_format" || ret_val=$? + - bash ci/complexity_measurements/getWmops.sh "ISM+1 ISM+2 ISM+3 ISM+4" "$out_format" full basop || ret_val=$? - *complexity-measurements-prepare-artifacts - exit $ret_val @@ -2030,12 +2019,12 @@ complexity-sba-hoa3-in-hoa3-out: rules: - if: $MEASURE_COMPLEXITY_LINUX when: delayed - start_in: 4 hours 30 minutes + start_in: 4 hours script: - in_format=HOA3 - out_format=HOA3 - ret_val=0 - - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" || ret_val=$? + - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" full basop || ret_val=$? - *complexity-measurements-prepare-artifacts - exit $ret_val @@ -2045,12 +2034,12 @@ complexity-sba-hoa3-in-binaural-out: rules: - if: $MEASURE_COMPLEXITY_LINUX when: delayed - start_in: 5 hours 30 minutes + start_in: 5 hours script: - in_format=HOA3 - out_format=BINAURAL - ret_val=0 - - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" || ret_val=$? + - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" full basop || ret_val=$? - *complexity-measurements-prepare-artifacts - exit $ret_val @@ -2060,12 +2049,12 @@ complexity-sba-hoa3-in-binaural_room_ir-out: rules: - if: $MEASURE_COMPLEXITY_LINUX when: delayed - start_in: 6 hours 30 minutes + start_in: 6 hours script: - in_format=HOA3 - out_format=BINAURAL_ROOM_IR - ret_val=0 - - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" || ret_val=$? + - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" full basop || ret_val=$? - *complexity-measurements-prepare-artifacts - exit $ret_val @@ -2075,12 +2064,12 @@ complexity-mc-in-7_1_4-out: rules: - if: $MEASURE_COMPLEXITY_LINUX when: delayed - start_in: 7 hours 30 minutes + start_in: 7 hours script: - in_format=MC - out_format=7_1_4 - ret_val=0 - - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" || ret_val=$? + - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" full basop || ret_val=$? - *complexity-measurements-prepare-artifacts - exit $ret_val @@ -2090,12 +2079,12 @@ complexity-mc-in-binaural-out: rules: - if: $MEASURE_COMPLEXITY_LINUX when: delayed - start_in: 10 hours + start_in: 8 hours script: - in_format=MC - out_format=BINAURAL - ret_val=0 - - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" || ret_val=$? + - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" full basop || ret_val=$? - *complexity-measurements-prepare-artifacts - exit $ret_val @@ -2105,12 +2094,12 @@ complexity-mc-in-binaural_room_ir-out: rules: - if: $MEASURE_COMPLEXITY_LINUX when: delayed - start_in: 12 hours 30 minutes + start_in: 9 hours script: - in_format=MC - out_format=BINAURAL_ROOM_IR - ret_val=0 - - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" || ret_val=$? + - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" full basop || ret_val=$? - *complexity-measurements-prepare-artifacts - exit $ret_val @@ -2120,12 +2109,12 @@ complexity-masa-in-ext-out: rules: - if: $MEASURE_COMPLEXITY_LINUX when: delayed - start_in: 15 hours + start_in: 10 hours script: - in_format=MASA - out_format=EXT - ret_val=0 - - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" || ret_val=$? + - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" full basop || ret_val=$? - *complexity-measurements-prepare-artifacts - exit $ret_val @@ -2135,12 +2124,12 @@ complexity-masa-in-binaural-out: rules: - if: $MEASURE_COMPLEXITY_LINUX when: delayed - start_in: 16 hours + start_in: 11 hours script: - in_format=MASA - out_format=BINAURAL - ret_val=0 - - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" || ret_val=$? + - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" full basop || ret_val=$? - *complexity-measurements-prepare-artifacts - exit $ret_val @@ -2150,12 +2139,12 @@ complexity-masa-in-hoa3-out: rules: - if: $MEASURE_COMPLEXITY_LINUX when: delayed - start_in: 17 hours + start_in: 12 hours script: - in_format=MASA - out_format=HOA3 - ret_val=0 - - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" || ret_val=$? + - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" full basop || ret_val=$? - *complexity-measurements-prepare-artifacts - exit $ret_val @@ -2170,7 +2159,7 @@ complexity-masa-in-hoa3-out: # - in_format=OMASA # - out_format=EXT # - ret_val=0 -# - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" || ret_val=$? +# - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" full basop || ret_val=$? # - *complexity-measurements-prepare-artifacts # - exit $ret_val @@ -2180,12 +2169,12 @@ complexity-omasa-in-binaural-out: rules: - if: $MEASURE_COMPLEXITY_LINUX when: delayed - start_in: 18 hours + start_in: 14 hours script: - in_format=OMASA - out_format=BINAURAL - ret_val=0 - - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" || ret_val=$? + - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" full basop || ret_val=$? - *complexity-measurements-prepare-artifacts - exit $ret_val @@ -2195,12 +2184,12 @@ complexity-omasa-in-hoa3-out: rules: - if: $MEASURE_COMPLEXITY_LINUX when: delayed - start_in: 20 hours + start_in: 15 hours script: - in_format=OMASA - out_format=HOA3 - ret_val=0 - - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" || ret_val=$? + - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" full basop || ret_val=$? - *complexity-measurements-prepare-artifacts - exit $ret_val @@ -2210,12 +2199,12 @@ complexity-StereoDmxEVS-stereo-in-mono-out: rules: - if: $MEASURE_COMPLEXITY_LINUX when: delayed - start_in: 22 hours + start_in: 16 hours script: - in_format=StereoDmxEVS - out_format=mono - ret_val=0 - - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" || ret_val=$? + - bash ci/complexity_measurements/getWmops.sh "$in_format" "$out_format" full basop || ret_val=$? - *complexity-measurements-prepare-artifacts - exit $ret_val @@ -2240,7 +2229,7 @@ complexity-osba-in-binaural-out: rules: - if: $MEASURE_COMPLEXITY_LINUX when: delayed - start_in: 22 hours 30 minutes + start_in: 18 hours script: - in_format=OSBA - out_format=BINAURAL @@ -2255,7 +2244,7 @@ complexity-osba-in-binaural_room_ir-out: rules: - if: $MEASURE_COMPLEXITY_LINUX when: delayed - start_in: 25 hours + start_in: 19 hours script: - in_format=OSBA - out_format=BINAURAL_ROOM_IR @@ -2276,7 +2265,7 @@ pages: - *update-scripts-repo - python3 ci/setup_pages.py - ls - - ls -lh public + - ls public artifacts: paths: - public -- GitLab From aa1d6f0966c4aef306d83c66e8ac80ddf3929f3e Mon Sep 17 00:00:00 2001 From: rtyag Date: Fri, 31 Jan 2025 22:07:37 +1100 Subject: [PATCH 21/33] clang formatting fix --- lib_rend/ivas_dirac_dec_binaural_functions.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib_rend/ivas_dirac_dec_binaural_functions.c b/lib_rend/ivas_dirac_dec_binaural_functions.c index 082b842f4..2b1c028bc 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions.c @@ -240,11 +240,11 @@ ivas_error ivas_dirac_dec_init_binaural_data( ivas_binaural_reverb_close( &( hDiracDecBin->hReverb ) ); } + if ( hDiracDecBin->hReverb == NULL #ifdef SPLIT_REND_WITH_HEAD_ROT - if ( hDiracDecBin->hReverb == NULL && pos_idx == 0 ) /* open reverb only for the main direction */ -#else - if ( hDiracDecBin->hReverb == NULL ) + && pos_idx == 0 #endif + ) /* open reverb only for the main direction */ { /* Todo Philips: Room acoustics should be passed here once the underlying part works. Probably enough to pick it from st_ivas but you know best. */ if ( ( error = ivas_binaural_reverb_open_parambin( &hDiracDecBin->hReverb, nBins, CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES, NULL, output_Fs, st_ivas->hHrtfParambin ) ) != IVAS_ERR_OK ) @@ -3622,9 +3622,9 @@ void ivas_masa_ext_rend_parambin_render( COMBINED_ORIENTATION_HANDLE hCombinedOrientationData, /* i : combined orientation handle */ float *output_f[], /* i/o: synthesized core-coder transport channels/DirAC output */ #ifdef SPLIT_REND_WITH_HEAD_ROT - const int16_t num_subframes, /* i : number of subframes to render */ - const SPLIT_REND_WRAPPER *hSplitRendWrapper, /* i : split rendering orientation data */ - float Cldfb_Out_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* o : rendered orientations for split rend. real part of cldfb */ + const int16_t num_subframes, /* i : number of subframes to render */ + const SPLIT_REND_WRAPPER *hSplitRendWrapper, /* i : split rendering orientation data */ + float Cldfb_Out_Real[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* o : rendered orientations for split rend. real part of cldfb */ float Cldfb_Out_Imag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX] /* o : rendered orientations for split rend. imag part of cldfb */ #else const int16_t num_subframes /* i : number of subframes to render */ -- GitLab From 18f6fe3abda75f454ee56be5c20a8e213815fbcd Mon Sep 17 00:00:00 2001 From: Erik Norvell Date: Mon, 3 Feb 2025 08:38:26 +0100 Subject: [PATCH 22/33] Fixes for CI builds --- .gitlab-ci.yml | 3 ++- lib_enc/ivas_qmetadata_enc.c | 19 ++++++++++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index d5b078e8b..11eea433d 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -173,6 +173,7 @@ stages: ### build reference binaries - *disable-debugging-macro + - make clean - make -j - mv IVAS_cod IVAS_cod_ref - mv IVAS_dec IVAS_dec_ref @@ -986,7 +987,7 @@ build-codec-linux-instrumented-make: script: - *print-common-info - *update-scripts-repo - - bash scripts/prepare_instrumentation.sh -m MEM_ONLY -p BASOP + - bash scripts/prepare_instrumentation.sh -m MEM_ONLY -p FLOAT - make -j -C $INSTR_DIR # make sure that the codec builds with msan, asan and usan diff --git a/lib_enc/ivas_qmetadata_enc.c b/lib_enc/ivas_qmetadata_enc.c index 9a4be19f4..c7afb7fb4 100644 --- a/lib_enc/ivas_qmetadata_enc.c +++ b/lib_enc/ivas_qmetadata_enc.c @@ -3772,12 +3772,15 @@ static ivas_error requantize_direction_EC_3( /* gradually increase the bits following the performance of the EC layer*/ int16_t j, k; int16_t use_vq; - int16_t diff, allowed_bits, nbits, last_j; + int16_t diff, allowed_bits, last_j; int16_t no_subframes, start_band; float st[MAX_PARAM_SPATIAL_SUBFRAMES], ct[MAX_PARAM_SPATIAL_SUBFRAMES]; int16_t *bits_dir0; +#ifdef DEBUGGING + int16_t nbits; nbits = 0; +#endif no_subframes = q_direction->cfg.nblocks; start_band = q_direction->cfg.start_band; @@ -3808,7 +3811,9 @@ static ivas_error requantize_direction_EC_3( else /* 2D */ { diff = 0; +#ifdef DEBUGGING nbits = 0; +#endif for ( j = start_band; j < coding_subbands; j++ ) { bits_dir0 = (int16_t *) q_direction->band_data[j].bits_sph_idx; @@ -3834,11 +3839,19 @@ static ivas_error requantize_direction_EC_3( if ( q_direction->cfg.mc_ls_setup != MC_LS_SETUP_INVALID ) { +#ifdef DEBUGGING nbits += truncGR0_chan( azimuth_orig[j], q_direction->band_data[j].azimuth, q_direction->band_data[j].azimuth_index, no_subframes, allowed_bits, st, ct ); +#else + truncGR0_chan( azimuth_orig[j], q_direction->band_data[j].azimuth, q_direction->band_data[j].azimuth_index, no_subframes, allowed_bits, st, ct ); +#endif } else { +#ifdef DEBUGGING nbits += truncGR0( azimuth_orig[j], q_direction->band_data[j].azimuth, q_direction->band_data[j].azimuth_index, no_subframes, allowed_bits, st, ct ); +#else + truncGR0( azimuth_orig[j], q_direction->band_data[j].azimuth, q_direction->band_data[j].azimuth_index, no_subframes, allowed_bits, st, ct ); +#endif } if ( allowed_bits <= no_subframes + 1 ) @@ -3865,7 +3878,11 @@ static ivas_error requantize_direction_EC_3( &q_direction->band_data[j].azimuth_index[k], q_direction->cfg.mc_ls_setup ); q_direction->band_data[j].elevation_index[k] = 0; } +#ifdef DEBUGGING nbits += write_fixed_rate_direction( hMetaData, q_direction, j, no_subframes ); +#else + write_fixed_rate_direction( hMetaData, q_direction, j, no_subframes ); +#endif } } } -- GitLab From d7759ec3dd6492313190cd15806b32646e2dba05 Mon Sep 17 00:00:00 2001 From: Erik Norvell Date: Mon, 3 Feb 2025 08:52:46 +0100 Subject: [PATCH 23/33] Add debugging fixes in lib_dec/ACcontextMapping_dec.c to resolve build warning --- lib_dec/ACcontextMapping_dec.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/lib_dec/ACcontextMapping_dec.c b/lib_dec/ACcontextMapping_dec.c index 5139106d9..5ea080a9d 100644 --- a/lib_dec/ACcontextMapping_dec.c +++ b/lib_dec/ACcontextMapping_dec.c @@ -348,9 +348,11 @@ int16_t RCcontextMapping_decode2_no_mem_s17_LCS( int16_t lastnz, n; uint16_t r; int16_t resQBits; +#ifdef DEBUGGING + int16_t nbbits_m2; int16_t rest_bits; +#endif int16_t nt_half; - int16_t nbbits_m2; int16_t bits_tups; /* No. of bits for coding the no. of tuples */ set_s( x, 0, nt ); @@ -424,8 +426,10 @@ int16_t RCcontextMapping_decode2_no_mem_s17_LCS( /* Initialize range decoder */ rc_uni_dec_init( &rc_st_dec, &st->bit_stream[st->next_bit_pos], nbbits ); /* (nbbits + 30) entries are read by the decoder */ +#ifdef DEBUGGING nbbits_m2 = nbbits; rest_bits = -nbbits_m2; +#endif /* Main Loop through the 2-tuples */ for ( k = 0; k < lastnz; k += 2 ) @@ -484,11 +488,13 @@ int16_t RCcontextMapping_decode2_no_mem_s17_LCS( a += a1 << lev; b += b1 << lev; +#ifdef DEBUGGING /* Add 2 LSB bits per bit-plane */ rest_bits += 2 * lev; /* Sign bits */ rest_bits += min( a, 1 ); rest_bits += min( b, 1 ); +#endif /* Update bitstream pointer */ st->next_bit_pos = start_bit_pos + bits_tups + rc_uni_dec_virtual_finish( &rc_st_dec ); @@ -570,8 +576,10 @@ int16_t RCcontextMapping_decode2_no_mem_s17_LCS( /* Initialize range decoder */ rc_uni_dec_init( &rc_st_dec, &st->bit_stream[st->next_bit_pos], nbbits ); /* (nbbits + 30) entries are read by the decoder */ +#ifdef DEBUGGING nbbits_m2 = nbbits; rest_bits = -nbbits_m2; +#endif t = 0; s = 0; @@ -624,11 +632,13 @@ int16_t RCcontextMapping_decode2_no_mem_s17_LCS( a += a1 << lev; b += b1 << lev; +#ifdef DEBUGGING /* Add 2 LSB bits per bit-plane */ rest_bits += 2 * lev; /* Sign bits */ rest_bits += min( a, 1 ); rest_bits += min( b, 1 ); +#endif /* Update bitstream pointer */ st->next_bit_pos = start_bit_pos + bits_tups + rc_uni_dec_virtual_finish( &rc_st_dec ); -- GitLab From f3be33ce1a3a799a2ced1a0b3de1b184ddb24f6f Mon Sep 17 00:00:00 2001 From: Erik Norvell Date: Mon, 3 Feb 2025 09:20:48 +0100 Subject: [PATCH 24/33] Add missing allow_failure and artifacts in renderer-pytest-on-merge-request --- .gitlab-ci.yml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 11eea433d..5d0916322 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1780,6 +1780,21 @@ renderer-pytest-on-merge-request: - *merge-request-comparison-check + allow_failure: + exit_codes: + - 123 + artifacts: + name: "mr-$CI_MERGE_REQUEST_IID--sha-$CI_COMMIT_SHORT_SHA--job-$CI_JOB_NAME--results" + expire_in: 1 week + when: always + paths: + - report-junit.xml + - report.html + expose_as: "pytest renderer results" + reports: + junit: + - report-junit.xml + # compare bit exactness between target and source branch ivas-pytest-on-merge-request: extends: -- GitLab From c0d04d8d082d044170f1575fcdb533454ba2db7e Mon Sep 17 00:00:00 2001 From: rtyag Date: Wed, 5 Feb 2025 12:55:12 +1100 Subject: [PATCH 25/33] add tc buffer NULL check in ivas_crend --- lib_rend/ivas_crend.c | 43 ++++++++++++++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 11 deletions(-) diff --git a/lib_rend/ivas_crend.c b/lib_rend/ivas_crend.c index b897083eb..864963deb 100644 --- a/lib_rend/ivas_crend.c +++ b/lib_rend/ivas_crend.c @@ -1956,22 +1956,35 @@ ivas_error ivas_rend_crendProcessSubframe( p_pcm_tmp[ch] = pcm_tmp[ch]; } - slot_size = hTcBuffer->n_samples_granularity; + if ( hTcBuffer != NULL ) + { + slot_size = hTcBuffer->n_samples_granularity; - /* loop for synthesis, assume we always have to render in multiples of 5ms subframes with spills */ - slots_to_render = min( hTcBuffer->num_slots - hTcBuffer->slots_rendered, n_samples_to_render / slot_size ); - first_sf = hTcBuffer->subframes_rendered; - last_sf = first_sf; + /* loop for synthesis, assume we always have to render in multiples of 5ms subframes with spills */ + slots_to_render = min( hTcBuffer->num_slots - hTcBuffer->slots_rendered, n_samples_to_render / slot_size ); + first_sf = hTcBuffer->subframes_rendered; + last_sf = first_sf; - while ( slots_to_render > 0 ) + while ( slots_to_render > 0 ) + { + slots_to_render -= hTcBuffer->subframe_nbslots[last_sf]; + last_sf++; + } + subframe_len = -1; /* will be set later */ + } + else { - slots_to_render -= hTcBuffer->subframe_nbslots[last_sf]; - last_sf++; + subframe_len = (int16_t) ( output_Fs / ( FRAMES_PER_SEC * MAX_PARAM_SPATIAL_SUBFRAMES ) ); + first_sf = 0; + last_sf = n_samples_to_render / subframe_len; } for ( subframe_idx = first_sf; subframe_idx < last_sf; subframe_idx++ ) { - subframe_len = hTcBuffer->subframe_nbslots[subframe_idx] * hTcBuffer->n_samples_granularity; + if ( hTcBuffer != NULL ) + { + subframe_len = hTcBuffer->subframe_nbslots[subframe_idx] * hTcBuffer->n_samples_granularity; + } /* Early Reflections */ if ( hCrend->reflections != NULL ) @@ -2040,7 +2053,11 @@ ivas_error ivas_rend_crendProcessSubframe( { p_pcm_tmp[ch] += subframe_len; } - hTcBuffer->slots_rendered += hTcBuffer->subframe_nbslots[subframe_idx]; + + if ( hTcBuffer != NULL ) + { + hTcBuffer->slots_rendered += hTcBuffer->subframe_nbslots[subframe_idx]; + } } else { @@ -2057,7 +2074,11 @@ ivas_error ivas_rend_crendProcessSubframe( mvr2r( pcm_tmp[ch], output[ch], n_samples_to_render ); } - hTcBuffer->subframes_rendered = last_sf; + if ( hTcBuffer != NULL ) + { + hTcBuffer->subframes_rendered = last_sf; + } + pop_wmops(); return IVAS_ERR_OK; -- GitLab From 4a3ca9d92109b70e27d9af5b60f0a0614262c6de Mon Sep 17 00:00:00 2001 From: rtyag Date: Wed, 5 Feb 2025 15:29:27 +1100 Subject: [PATCH 26/33] MASA BE failure fix --- lib_rend/ivas_dirac_dec_binaural_functions.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_rend/ivas_dirac_dec_binaural_functions.c b/lib_rend/ivas_dirac_dec_binaural_functions.c index 2b1c028bc..945e9209e 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions.c @@ -3507,7 +3507,7 @@ static void ivas_masa_ext_rend_parambin_internal( ivas_dirac_dec_binaural_formulate_input_covariance_matrices( hDiracDecBin, hSpatParamRendCom, &config_data, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in, subframe, subFrameTotalEne, IIReneLimiter ); ivas_dirac_dec_binaural_formulate_target_covariance_matrices( hDiracDecBin, hSpatParamRendCom, &config_data, Rmat, subframe, - hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[subframe] > 0, + hCombinedOrientationData && hCombinedOrientationData->enableCombinedOrientation[hCombinedOrientationData->subframe_idx] > 0, subFrameTotalEne, IIReneLimiter, NULL ); #endif -- GitLab From 04a61511f2f53a2860d85e6f4411f7ab523e4e5d Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Wed, 5 Feb 2025 08:21:07 +0100 Subject: [PATCH 27/33] disable no-commits-for-draft-MRs rule --- .gitlab-ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index a258686e1..99fa2ac1c 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -57,8 +57,8 @@ workflow: - if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS && $CI_PIPELINE_SOURCE == "push" when: never # do not spawn pipelines for Draft MRs, see https://docs.gitlab.com/ee/ci/yaml/workflow.html#skip-pipelines-for-draft-merge-requests - - if: $CI_PIPELINE_SOURCE == "merge_request_event" && $CI_MERGE_REQUEST_TITLE =~ /^(\[Draft\]|\(Draft\)|Draft:)/ - when: never + # - if: $CI_PIPELINE_SOURCE == "merge_request_event" && $CI_MERGE_REQUEST_TITLE =~ /^(\[Draft\]|\(Draft\)|Draft:)/ + # when: never - if: $CI_PIPELINE_SOURCE == 'merge_request_event' variables: IVAS_PIPELINE_NAME: 'MR pipeline: $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME' -- GitLab From 5cbed7515ccf10e608613f7e43b3ca574dc77031 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Wed, 5 Feb 2025 08:23:35 +0100 Subject: [PATCH 28/33] add split rendering smoke test --- .gitlab-ci.yml | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 99fa2ac1c..3130dbe71 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1083,6 +1083,27 @@ build-codec-windows-msbuild: # Test jobs for merge requests # --------------------------------------------------------------- +split-rendering-smoke-test: + extends: + - .test-job-linux + - .rules-merge-request + needs: ["build-codec-linux-make"] + stage: test + script: + - make -j + - testcase_timeout=10 + - python3 -m pytest -q -n auto -rA --junit-xml=report-junit.xml tests/split_rendering/test_split_rendering.py --testcase_timeout=$testcase_timeout + artifacts: + name: "mr-$CI_MERGE_REQUEST_IID--sha-$CI_COMMIT_SHORT_SHA--job-$CI_JOB_NAME--results" + expire_in: 1 week + when: always + paths: + - report-junit.xml + expose_as: "split rendering smoke results" + reports: + junit: + - report-junit.xml + lc3-wrapper-unit-test: extends: - .test-job-linux -- GitLab From a68586adbf3f3afc0876f65e2bbc7ebc9bfa7028 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Wed, 5 Feb 2025 08:25:06 +0100 Subject: [PATCH 29/33] use cmake for building the lc3 unit test --- .gitlab-ci.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 3130dbe71..44aa07e32 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1111,7 +1111,8 @@ lc3-wrapper-unit-test: needs: ["build-codec-linux-make"] stage: test script: - - make -j + - cmake -B cmake-build -G "Unix Makefiles" -DCOPY_EXECUTABLES_FROM_BUILD_DIR=true + - cmake --build cmake-build -- -j - scripts/split_rendering/lc3plus/ivas_lc3plus_unit_test # compare split-rendering bitexactness between target and source branch -- GitLab From a5bbb2e46d1ad02dde839f107fb2e3bee12b8f46 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Wed, 5 Feb 2025 08:28:46 +0100 Subject: [PATCH 30/33] add needed script anchors --- .gitlab-ci.yml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 44aa07e32..613239820 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1090,6 +1090,9 @@ split-rendering-smoke-test: needs: ["build-codec-linux-make"] stage: test script: + - *print-common-info + - *update-scripts-repo + - make -j - testcase_timeout=10 - python3 -m pytest -q -n auto -rA --junit-xml=report-junit.xml tests/split_rendering/test_split_rendering.py --testcase_timeout=$testcase_timeout @@ -1111,6 +1114,9 @@ lc3-wrapper-unit-test: needs: ["build-codec-linux-make"] stage: test script: + - *print-common-info + - *update-scripts-repo + - cmake -B cmake-build -G "Unix Makefiles" -DCOPY_EXECUTABLES_FROM_BUILD_DIR=true - cmake --build cmake-build -- -j - scripts/split_rendering/lc3plus/ivas_lc3plus_unit_test @@ -1126,6 +1132,7 @@ split-rendering-pytest-on-merge-request: stage: compare script: - *print-common-info + - *update-scripts-repo - *get-commits-behind-count - *check-commits-behind-count-in-compare-jobs -- GitLab From 5cef07989d2df39559a7640532bf1dbb5e239cab Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Mon, 24 Feb 2025 10:38:35 +0100 Subject: [PATCH 31/33] [revert-me] disable SR comparison test temporarily --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 613239820..987cdc532 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1122,7 +1122,7 @@ lc3-wrapper-unit-test: - scripts/split_rendering/lc3plus/ivas_lc3plus_unit_test # compare split-rendering bitexactness between target and source branch -split-rendering-pytest-on-merge-request: +.split-rendering-pytest-on-merge-request: extends: - .test-job-linux-needs-testv-dir - .rules-merge-request -- GitLab From 5ecfdc477665de0a4b6b6677fef9194d151f6b3b Mon Sep 17 00:00:00 2001 From: Archit Tamarapu Date: Mon, 24 Feb 2025 16:20:36 +0100 Subject: [PATCH 32/33] update path to LC3plus unit test in CMakeLists.txt --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 17799f0db..3e2d69728 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -174,7 +174,7 @@ target_include_directories(lib_util PUBLIC lib_util PRIVATE lib_com lib_enc lib_ target_include_directories(lib_util PRIVATE lib_lc3plus lib_isar) if(NOT WMOPS) - add_executable(ivas_lc3plus_unit_test ${CMAKE_SOURCE_DIR}/scripts/split_rendering/lc3plus/ivas_lc3plus_unit_test.c) + add_executable(ivas_lc3plus_unit_test scripts/split_rendering/lc3plus_float/ivas_lc3plus_unit_test.c) target_link_libraries(ivas_lc3plus_unit_test lib_rend lib_dec lib_util lib_com lib_debug lib_isar) endif() @@ -213,7 +213,7 @@ if(COPY_EXECUTABLES_FROM_BUILD_DIR) add_custom_command(TARGET IVAS_rend POST_BUILD VERBATIM COMMAND "${CMAKE_COMMAND}" -E copy "$" "${CMAKE_CURRENT_SOURCE_DIR}/") add_custom_command(TARGET ISAR_post_rend POST_BUILD VERBATIM COMMAND "${CMAKE_COMMAND}" -E copy "$" "${CMAKE_CURRENT_SOURCE_DIR}/") if (NOT WMOPS) - add_custom_command(TARGET ivas_lc3plus_unit_test POST_BUILD VERBATIM COMMAND "${CMAKE_COMMAND}" -E copy "$" "${CMAKE_CURRENT_SOURCE_DIR}/scripts/split_rendering/lc3plus") + add_custom_command(TARGET ivas_lc3plus_unit_test POST_BUILD VERBATIM COMMAND "${CMAKE_COMMAND}" -E copy "$" "${CMAKE_CURRENT_SOURCE_DIR}/scripts/split_rendering/lc3plus_float") endif() endif() -- GitLab From b90e6f8bed2246367b736df22828948bf945e2cf Mon Sep 17 00:00:00 2001 From: Archit Tamarapu Date: Mon, 24 Feb 2025 16:25:03 +0100 Subject: [PATCH 33/33] update path to LC3plus unit test in .gitlab-ci.yml too --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index de93cad66..3dc131ed7 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1140,7 +1140,7 @@ lc3-wrapper-unit-test: - cmake -B cmake-build -G "Unix Makefiles" -DCOPY_EXECUTABLES_FROM_BUILD_DIR=true - cmake --build cmake-build -- -j - - scripts/split_rendering/lc3plus/ivas_lc3plus_unit_test + - scripts/split_rendering/lc3plus_float/ivas_lc3plus_unit_test # compare split-rendering bitexactness between target and source branch .split-rendering-pytest-on-merge-request: -- GitLab