From ed713cee703945c57adc486e1397fd40e078cf12 Mon Sep 17 00:00:00 2001 From: Kacper Sagnowski Date: Wed, 10 Aug 2022 18:19:23 +0200 Subject: [PATCH 001/101] External renderer - first version [WIP] --- .gitignore | 8 +- .gitlab-ci.yml | 41 +- CMakeLists.txt | 23 +- Makefile | 34 +- Workspace_msvc/Workspace_msvc.sln | 22 + Workspace_msvc/lib_com.vcxproj | 8 +- Workspace_msvc/lib_debug.vcxproj | 8 +- Workspace_msvc/lib_dec.vcxproj | 41 +- Workspace_msvc/lib_dec.vcxproj.filters | 94 +- Workspace_msvc/lib_enc.vcxproj | 8 +- Workspace_msvc/lib_rend.vcxproj | 257 ++ Workspace_msvc/lib_util.vcxproj | 8 +- .../renderer.vcxproj | 132 +- apps/decoder.c | 1 - apps/renderer.c | 1912 ++++++++++++ ci/build_all_linux.sh | 2 - lib_com/ivas_cnst.h | 9 + lib_com/options.h | 3 +- lib_dec/ivas_rom_dec.c | 664 ---- lib_dec/ivas_rom_dec.h | 48 - lib_dec/ivas_sba_dec.c | 728 ++--- lib_dec/ivas_sba_rendering.c | 526 ---- lib_dec/ivas_stat_dec.h | 54 +- {lib_dec => lib_rend}/ivas_allrad_dec.c | 2 +- {lib_dec => lib_rend}/ivas_binauralRenderer.c | 2 +- {lib_dec => lib_rend}/ivas_binaural_reverb.c | 0 {lib_dec => lib_rend}/ivas_crend.c | 2 +- {lib_dec => lib_rend}/ivas_efap.c | 8 + {lib_dec => lib_rend}/ivas_hrtf.c | 1 - {lib_dec => lib_rend}/ivas_limiter.c | 0 {lib_dec => lib_rend}/ivas_ls_custom_dec.c | 0 {lib_dec => lib_rend}/ivas_objectRenderer.c | 14 +- .../ivas_objectRenderer_hrFilt.c | 2 +- .../ivas_objectRenderer_mix.c | 0 .../ivas_objectRenderer_sfx.c | 2 +- .../ivas_objectRenderer_sources.c | 0 .../ivas_objectRenderer_vec.c | 0 {lib_dec => lib_rend}/ivas_orient_trk.c | 0 {lib_dec => lib_rend}/ivas_output_init.c | 0 {lib_dec => lib_rend}/ivas_render_config.c | 2 +- {lib_dec => lib_rend}/ivas_reverb.c | 2 +- .../ivas_reverb_delay_line.c | 0 .../ivas_reverb_fft_filter.c | 0 .../ivas_reverb_filter_design.c | 0 .../ivas_reverb_iir_filter.c | 0 {lib_dec => lib_rend}/ivas_reverb_utils.c | 2 +- .../ivas_rom_TdBinauralRenderer.c | 0 .../ivas_rom_TdBinauralRenderer.h | 0 .../ivas_rom_binauralRenderer.c | 0 .../ivas_rom_binauralRenderer.h | 0 .../ivas_rom_binaural_crend_head.c | 0 .../ivas_rom_binaural_crend_head.h | 0 lib_rend/ivas_rom_rend.c | 755 +++++ lib_rend/ivas_rom_rend.h | 141 + {lib_dec => lib_rend}/ivas_rotation.c | 20 + lib_rend/ivas_sba_rendering.c | 584 ++++ .../ivas_stat_rend.h | 69 +- lib_rend/lib_rend.c | 2672 +++++++++++++++++ lib_rend/lib_rend.h | 212 ++ lib_util/cmdln_parser.c | 375 +++ ...{ivas_rom_prerenderer.h => cmdln_parser.h} | 44 +- lib_util/ivas_prerenderer.c | 1733 ----------- lib_util/ivas_prerenderer.h | 190 -- scripts/deco.bin | 3 + scripts/eigen_to_foa_cldfb_domain_filters.bin | 3 + .../eigen_to_hoa2_cldfb_domain_filters.bin | 3 + scripts/find_unused_symbols.sh | 3 +- scripts/hrir.bin | 0 .../crend/ivas_crend_unit_test.vcxproj | 5 +- scripts/prepare_instrumentation.sh | 3 +- scripts/prerenderer/Makefile | 172 -- .../Workspace_msvc_prerenderer.sln | 48 - .../prerenderer.vcxproj.filters | 50 - scripts/prerenderer/prerenderer.c | 1553 ---------- scripts/pyaudio3dtools/EFAP.py | 82 +- scripts/pyaudio3dtools/audio3dtools.py | 11 +- scripts/pyaudio3dtools/audioarray.py | 2 +- scripts/pyaudio3dtools/audiofile.py | 8 +- scripts/pyaudio3dtools/binauralrenderer.py | 157 +- scripts/pyaudio3dtools/constants.py | 26 +- scripts/pyaudio3dtools/hoadecoder.py | 12 +- .../{rotateISM.py => masarenderer.py} | 91 +- .../{rotateHOA.py => rotation.py} | 105 +- scripts/pyaudio3dtools/spatialaudioconvert.py | 200 +- scripts/pyaudio3dtools/spatialaudioformat.py | 45 +- scripts/pyaudio3dtools/spatialmetadata.py | 27 +- scripts/pyivastest/IvasModeRunner.py | 0 scripts/sector_filters.bin | 3 + .../object_renderer_standalone/Makefile | 15 +- .../object_renderer_standalone.sln | 16 +- .../rotateMC.py => tests/__init__.py} | 69 - scripts/tests/compare_audio.py | 69 + scripts/tests/constants.py | 189 ++ scripts/tests/cut/.gitignore | 1 + .../data}/IVAS_ISM_metadata_-30_0.csv | 0 .../data}/IVAS_ISM_metadata_0_0.csv | 0 .../data}/IVAS_ISM_metadata_30_0.csv | 0 .../data}/IVAS_ISM_metadata_circle.csv | 0 .../data}/ism1_ivas_mtdt_config.txt | 0 .../data}/ism1_shorthand_config.txt | 0 .../data}/ism2_ivas_mtdt_config.txt | 0 .../data}/ism2_shorthand_config.txt | 0 .../data}/ism3_ivas_mtdt_config.txt | 0 .../data}/ism3_shorthand_config.txt | 0 .../data}/ism4_ivas_mtdt_config.txt | 0 .../data}/ism4_shorthand_config.txt | 0 scripts/tests/data/ism_-90a_0e.csv | 750 +++++ scripts/tests/data/ism_0a_0e.csv | 750 +++++ scripts/tests/data/ism_180a_0e.csv | 750 +++++ scripts/tests/data/ism_90a_0e.csv | 750 +++++ .../data}/mixed_ivas_mtdt_config.txt | 2 +- .../data}/mixed_ivas_mtdt_gain_config.txt | 2 +- scripts/tests/data/mixed_scene.txt | 15 + .../data}/mixed_shorthand_config.txt | 2 +- .../data}/mixed_shorthand_gain_config.txt | 3 +- .../data}/mixed_shorthand_limiter_config.txt | 4 +- scripts/tests/data/pink_noise_10ch_48kHz.wav | 3 + scripts/tests/data/pink_noise_11ch_48kHz.wav | 3 + scripts/tests/data/pink_noise_12ch_48kHz.wav | 3 + scripts/tests/data/pink_noise_13ch_48kHz.wav | 3 + scripts/tests/data/pink_noise_14ch_48kHz.wav | 3 + scripts/tests/data/pink_noise_15ch_48kHz.wav | 3 + scripts/tests/data/pink_noise_16ch_48kHz.wav | 3 + scripts/tests/data/pink_noise_1ch_48kHz.wav | 3 + scripts/tests/data/pink_noise_2ch_48kHz.wav | 3 + scripts/tests/data/pink_noise_3ch_48kHz.wav | 3 + scripts/tests/data/pink_noise_4ch_48kHz.wav | 3 + scripts/tests/data/pink_noise_5ch_48kHz.wav | 3 + scripts/tests/data/pink_noise_6ch_48kHz.wav | 3 + scripts/tests/data/pink_noise_7ch_48kHz.wav | 3 + scripts/tests/data/pink_noise_8ch_48kHz.wav | 3 + scripts/tests/data/pink_noise_9ch_48kHz.wav | 3 + .../data/renderer_config_format_readme.txt} | 12 +- .../tests/data/spectral_test_10ch_48kHz.wav | 3 + .../tests/data/spectral_test_11ch_48kHz.wav | 3 + .../tests/data/spectral_test_12ch_48kHz.wav | 3 + .../tests/data/spectral_test_15ch_48kHz.wav | 3 + .../tests/data/spectral_test_16ch_48kHz.wav | 3 + .../tests/data/spectral_test_1ch_48kHz.wav | 3 + .../tests/data/spectral_test_2ch_48kHz.wav | 3 + .../tests/data/spectral_test_3ch_48kHz.wav | 3 + .../tests/data/spectral_test_4ch_48kHz.wav | 3 + .../tests/data/spectral_test_5ch_48kHz.wav | 3 + .../tests/data/spectral_test_6ch_48kHz.wav | 3 + .../tests/data/spectral_test_8ch_48kHz.wav | 3 + .../tests/data/spectral_test_9ch_48kHz.wav | 3 + scripts/tests/data/spectral_test_ism1.txt | 5 + scripts/tests/data/spectral_test_ism2.txt | 8 + scripts/tests/data/spectral_test_ism3.txt | 11 + scripts/tests/data/spectral_test_ism4.txt | 14 + scripts/tests/data/stvISM1.csv | 1500 +++++++++ scripts/tests/data/stvISM2.csv | 1500 +++++++++ scripts/tests/data/stvISM3.csv | 1500 +++++++++ scripts/tests/data/stvISM4.csv | 1500 +++++++++ scripts/tests/data/stv_IVASMASA_1dir1TC.met | 3 + scripts/tests/data/stv_IVASMASA_1dir1TC.pcm | 3 + scripts/tests/data/stv_IVASMASA_1dir2TC.met | 3 + scripts/tests/data/stv_IVASMASA_1dir2TC.pcm | 3 + scripts/tests/data/stv_IVASMASA_2dir1TC.met | 3 + scripts/tests/data/stv_IVASMASA_2dir1TC.pcm | 3 + scripts/tests/data/stv_IVASMASA_2dir2TC.met | 3 + scripts/tests/data/stv_IVASMASA_2dir2TC.pcm | 3 + scripts/tests/ref/.gitignore | 1 + scripts/tests/test_renderer.py | 387 +++ scripts/vbap_51_table.bin | 3 + scripts/vbap_714_table.bin | 3 + scripts/vbap_bin_table.bin | 3 + 167 files changed, 17971 insertions(+), 6051 deletions(-) create mode 100644 Workspace_msvc/lib_rend.vcxproj rename scripts/prerenderer/Workspace_msvc/prerenderer.vcxproj => Workspace_msvc/renderer.vcxproj (58%) create mode 100644 apps/renderer.c delete mode 100644 lib_dec/ivas_sba_rendering.c rename {lib_dec => lib_rend}/ivas_allrad_dec.c (99%) rename {lib_dec => lib_rend}/ivas_binauralRenderer.c (99%) rename {lib_dec => lib_rend}/ivas_binaural_reverb.c (100%) rename {lib_dec => lib_rend}/ivas_crend.c (99%) rename {lib_dec => lib_rend}/ivas_efap.c (99%) rename {lib_dec => lib_rend}/ivas_hrtf.c (99%) rename {lib_dec => lib_rend}/ivas_limiter.c (100%) rename {lib_dec => lib_rend}/ivas_ls_custom_dec.c (100%) rename {lib_dec => lib_rend}/ivas_objectRenderer.c (97%) rename {lib_dec => lib_rend}/ivas_objectRenderer_hrFilt.c (99%) rename {lib_dec => lib_rend}/ivas_objectRenderer_mix.c (100%) rename {lib_dec => lib_rend}/ivas_objectRenderer_sfx.c (99%) rename {lib_dec => lib_rend}/ivas_objectRenderer_sources.c (100%) rename {lib_dec => lib_rend}/ivas_objectRenderer_vec.c (100%) rename {lib_dec => lib_rend}/ivas_orient_trk.c (100%) rename {lib_dec => lib_rend}/ivas_output_init.c (100%) rename {lib_dec => lib_rend}/ivas_render_config.c (99%) rename {lib_dec => lib_rend}/ivas_reverb.c (99%) rename {lib_dec => lib_rend}/ivas_reverb_delay_line.c (100%) rename {lib_dec => lib_rend}/ivas_reverb_fft_filter.c (100%) rename {lib_dec => lib_rend}/ivas_reverb_filter_design.c (100%) rename {lib_dec => lib_rend}/ivas_reverb_iir_filter.c (100%) rename {lib_dec => lib_rend}/ivas_reverb_utils.c (99%) rename {lib_dec => lib_rend}/ivas_rom_TdBinauralRenderer.c (100%) rename {lib_dec => lib_rend}/ivas_rom_TdBinauralRenderer.h (100%) rename {lib_dec => lib_rend}/ivas_rom_binauralRenderer.c (100%) rename {lib_dec => lib_rend}/ivas_rom_binauralRenderer.h (100%) rename {lib_dec => lib_rend}/ivas_rom_binaural_crend_head.c (100%) rename {lib_dec => lib_rend}/ivas_rom_binaural_crend_head.h (100%) create mode 100644 lib_rend/ivas_rom_rend.c create mode 100644 lib_rend/ivas_rom_rend.h rename {lib_dec => lib_rend}/ivas_rotation.c (98%) create mode 100644 lib_rend/ivas_sba_rendering.c rename lib_util/ivas_rom_prerenderer.c => lib_rend/ivas_stat_rend.h (51%) create mode 100644 lib_rend/lib_rend.c create mode 100644 lib_rend/lib_rend.h create mode 100644 lib_util/cmdln_parser.c rename lib_util/{ivas_rom_prerenderer.h => cmdln_parser.h} (66%) delete mode 100644 lib_util/ivas_prerenderer.c delete mode 100644 lib_util/ivas_prerenderer.h create mode 100644 scripts/deco.bin create mode 100644 scripts/eigen_to_foa_cldfb_domain_filters.bin create mode 100644 scripts/eigen_to_hoa2_cldfb_domain_filters.bin create mode 100644 scripts/hrir.bin delete mode 100644 scripts/prerenderer/Makefile delete mode 100644 scripts/prerenderer/Workspace_msvc/Workspace_msvc_prerenderer.sln delete mode 100644 scripts/prerenderer/Workspace_msvc/prerenderer.vcxproj.filters delete mode 100644 scripts/prerenderer/prerenderer.c mode change 100755 => 100644 scripts/pyaudio3dtools/audiofile.py rename scripts/pyaudio3dtools/{rotateISM.py => masarenderer.py} (51%) rename scripts/pyaudio3dtools/{rotateHOA.py => rotation.py} (74%) mode change 100755 => 100644 scripts/pyivastest/IvasModeRunner.py create mode 100644 scripts/sector_filters.bin rename scripts/{pyaudio3dtools/rotateMC.py => tests/__init__.py} (50%) create mode 100644 scripts/tests/compare_audio.py create mode 100644 scripts/tests/constants.py create mode 100644 scripts/tests/cut/.gitignore rename scripts/{prerenderer_configs => tests/data}/IVAS_ISM_metadata_-30_0.csv (100%) rename scripts/{prerenderer_configs => tests/data}/IVAS_ISM_metadata_0_0.csv (100%) rename scripts/{prerenderer_configs => tests/data}/IVAS_ISM_metadata_30_0.csv (100%) rename scripts/{prerenderer_configs => tests/data}/IVAS_ISM_metadata_circle.csv (100%) rename scripts/{prerenderer_configs => tests/data}/ism1_ivas_mtdt_config.txt (100%) rename scripts/{prerenderer_configs => tests/data}/ism1_shorthand_config.txt (100%) rename scripts/{prerenderer_configs => tests/data}/ism2_ivas_mtdt_config.txt (100%) rename scripts/{prerenderer_configs => tests/data}/ism2_shorthand_config.txt (100%) rename scripts/{prerenderer_configs => tests/data}/ism3_ivas_mtdt_config.txt (100%) rename scripts/{prerenderer_configs => tests/data}/ism3_shorthand_config.txt (100%) rename scripts/{prerenderer_configs => tests/data}/ism4_ivas_mtdt_config.txt (100%) rename scripts/{prerenderer_configs => tests/data}/ism4_shorthand_config.txt (100%) create mode 100644 scripts/tests/data/ism_-90a_0e.csv create mode 100644 scripts/tests/data/ism_0a_0e.csv create mode 100644 scripts/tests/data/ism_180a_0e.csv create mode 100644 scripts/tests/data/ism_90a_0e.csv rename scripts/{prerenderer_configs => tests/data}/mixed_ivas_mtdt_config.txt (93%) rename scripts/{prerenderer_configs => tests/data}/mixed_ivas_mtdt_gain_config.txt (95%) create mode 100644 scripts/tests/data/mixed_scene.txt rename scripts/{prerenderer_configs => tests/data}/mixed_shorthand_config.txt (89%) rename scripts/{prerenderer_configs => tests/data}/mixed_shorthand_gain_config.txt (91%) rename scripts/{prerenderer_configs => tests/data}/mixed_shorthand_limiter_config.txt (83%) create mode 100644 scripts/tests/data/pink_noise_10ch_48kHz.wav create mode 100644 scripts/tests/data/pink_noise_11ch_48kHz.wav create mode 100644 scripts/tests/data/pink_noise_12ch_48kHz.wav create mode 100644 scripts/tests/data/pink_noise_13ch_48kHz.wav create mode 100644 scripts/tests/data/pink_noise_14ch_48kHz.wav create mode 100644 scripts/tests/data/pink_noise_15ch_48kHz.wav create mode 100644 scripts/tests/data/pink_noise_16ch_48kHz.wav create mode 100644 scripts/tests/data/pink_noise_1ch_48kHz.wav create mode 100644 scripts/tests/data/pink_noise_2ch_48kHz.wav create mode 100644 scripts/tests/data/pink_noise_3ch_48kHz.wav create mode 100644 scripts/tests/data/pink_noise_4ch_48kHz.wav create mode 100644 scripts/tests/data/pink_noise_5ch_48kHz.wav create mode 100644 scripts/tests/data/pink_noise_6ch_48kHz.wav create mode 100644 scripts/tests/data/pink_noise_7ch_48kHz.wav create mode 100644 scripts/tests/data/pink_noise_8ch_48kHz.wav create mode 100644 scripts/tests/data/pink_noise_9ch_48kHz.wav rename scripts/{prerenderer_configs/prerenderer_config_format_readme.txt => tests/data/renderer_config_format_readme.txt} (94%) create mode 100644 scripts/tests/data/spectral_test_10ch_48kHz.wav create mode 100644 scripts/tests/data/spectral_test_11ch_48kHz.wav create mode 100644 scripts/tests/data/spectral_test_12ch_48kHz.wav create mode 100644 scripts/tests/data/spectral_test_15ch_48kHz.wav create mode 100644 scripts/tests/data/spectral_test_16ch_48kHz.wav create mode 100644 scripts/tests/data/spectral_test_1ch_48kHz.wav create mode 100644 scripts/tests/data/spectral_test_2ch_48kHz.wav create mode 100644 scripts/tests/data/spectral_test_3ch_48kHz.wav create mode 100644 scripts/tests/data/spectral_test_4ch_48kHz.wav create mode 100644 scripts/tests/data/spectral_test_5ch_48kHz.wav create mode 100644 scripts/tests/data/spectral_test_6ch_48kHz.wav create mode 100644 scripts/tests/data/spectral_test_8ch_48kHz.wav create mode 100644 scripts/tests/data/spectral_test_9ch_48kHz.wav create mode 100644 scripts/tests/data/spectral_test_ism1.txt create mode 100644 scripts/tests/data/spectral_test_ism2.txt create mode 100644 scripts/tests/data/spectral_test_ism3.txt create mode 100644 scripts/tests/data/spectral_test_ism4.txt create mode 100644 scripts/tests/data/stvISM1.csv create mode 100644 scripts/tests/data/stvISM2.csv create mode 100644 scripts/tests/data/stvISM3.csv create mode 100644 scripts/tests/data/stvISM4.csv create mode 100644 scripts/tests/data/stv_IVASMASA_1dir1TC.met create mode 100644 scripts/tests/data/stv_IVASMASA_1dir1TC.pcm create mode 100644 scripts/tests/data/stv_IVASMASA_1dir2TC.met create mode 100644 scripts/tests/data/stv_IVASMASA_1dir2TC.pcm create mode 100644 scripts/tests/data/stv_IVASMASA_2dir1TC.met create mode 100644 scripts/tests/data/stv_IVASMASA_2dir1TC.pcm create mode 100644 scripts/tests/data/stv_IVASMASA_2dir2TC.met create mode 100644 scripts/tests/data/stv_IVASMASA_2dir2TC.pcm create mode 100644 scripts/tests/ref/.gitignore create mode 100644 scripts/tests/test_renderer.py create mode 100644 scripts/vbap_51_table.bin create mode 100644 scripts/vbap_714_table.bin create mode 100644 scripts/vbap_bin_table.bin diff --git a/.gitignore b/.gitignore index eaf8b0cb7b..6b784623d5 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ # Compiler output Unix IVAS_cod IVAS_dec +IVAS_rend obj/ *.a *.o @@ -14,6 +15,7 @@ build/**/* # Compiler output VS2017 IVAS_cod.exe IVAS_dec.exe +IVAS_rend.exe *.user .vs/ Debug_*/ @@ -31,10 +33,6 @@ scripts/ivas_pytests/tests/unit_tests/crend/Release_*/ scripts/td_object_renderer/object_renderer_standalone/renderer_standalone scripts/td_object_renderer/object_renderer_standalone/renderer_standalone.exe -# Prerenderer -scripts/prerenderer/IVAS_prerenderer -scripts/prerenderer/IVAS_prerenderer.exe - # General/scripts .DS_Store .vscode @@ -45,6 +43,8 @@ scripts/ifdef_instrument.list scripts/ref/ scripts/test/ scripts/self_test_summary.txt +scripts/tests/cut/ +scripts/tests/ref/ # Python files that pop up when running scripts __pycache__/ diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 56420ae02e..91ddc62ad5 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -123,16 +123,6 @@ build-unittests-linux: # need to use the "|| exit $?" suffix to get the allowed_failure return code, otherwise the job fails with code 1...< - ci/check_for_warnings.py $BUILD_OUTPUT || exit $? -build-prerenderer-linux: - extends: - - .build-job-with-check-for-warnings - - .rules-basis - script: - - *print-common-info - - make -C scripts/prerenderer -j 2>&1 | tee $BUILD_OUTPUT - # need to use the "|| exit $?" suffix to get the allowed_failure return code, otherwise the job fails with code 1...< - - ci/check_for_warnings.py $BUILD_OUTPUT || exit $? - build-td-object-renderer-standalone-linux: extends: - .build-job-with-check-for-warnings @@ -233,6 +223,37 @@ asan-on-merge-request-linux: - run_errors=$(cat test_output.txt | grep -ic "run errors") || true - if [ $run_errors != 0 ] ; then echo "Run errors in self_test.py with Clang address-sanitizer"; exit 1; fi +# test external renderer executable +external-renderer-make-pytest: + extends: + - .test-job-linux + - .rules-merge-request + needs: [ "build-codec-linux-make" ] + script: + - make -j IVAS_rend + - python3 -m pytest scripts/tests/test_renderer.py --capture=no --tb=no -n auto + +# test external renderer executable with cmake + asan +external-renderer-cmake-asan-pytest: + extends: + - .test-job-linux + - .rules-merge-request + needs: [ "build-codec-linux-cmake" ] + script: + - cmake -B cmake-build -G "Unix Makefiles" -DCLANG=asan + - cmake --build cmake-build -- -j + - python3 -m pytest scripts/tests/test_renderer.py --capture=no --tb=no -n auto + +# test external renderer executable with cmake + msan +external-renderer-cmake-msan-pytest: + extends: + - .test-job-linux + - .rules-merge-request + needs: [ "build-codec-linux-cmake" ] + script: + - cmake -B cmake-build -G "Unix Makefiles" -DCLANG=msan + - cmake --build cmake-build -- -j + - python3 -m pytest scripts/tests/test_renderer.py --capture=no --tb=no -n auto # compare bit exactness between target and source branch self-test-on-merge-request: diff --git a/CMakeLists.txt b/CMakeLists.txt index ad70b85844..e333918c91 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -118,6 +118,7 @@ include_directories( lib_debug lib_dec lib_enc + lib_rend lib_util ) @@ -137,10 +138,15 @@ file(GLOB libEncHeaders "lib_enc/*.h") add_library(lib_enc ${libEncSrcs} ${libEncHeaders}) target_link_libraries(lib_enc lib_com lib_debug) +file(GLOB libRendSrcs "lib_rend/*.c") +file(GLOB libRendHeaders "lib_rend/*.h") +add_library(lib_rend ${libRendSrcs} ${libRendHeaders}) +target_link_libraries(lib_rend lib_com lib_debug) + 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_debug) +target_link_libraries(lib_dec lib_com lib_rend lib_debug) file(GLOB libUtilSrcs "lib_util/*.c") file(GLOB libUtilHeaders "lib_util/*.h") @@ -158,11 +164,10 @@ if(WIN32) target_link_libraries(IVAS_dec Ws2_32) endif() -if(${IVAS_BUILD_PRERENDERER}) - add_executable(IVAS_prerenderer - scripts/prerenderer/prerenderer.c - ${libEncSrcs} - ${libDecSrcs} - ) - target_link_libraries(IVAS_prerenderer lib_com lib_dec lib_debug lib_util) -endif() +add_executable(IVAS_rend apps/renderer.c) +target_link_libraries(IVAS_rend lib_rend lib_util) + +# Copy executables to root directory after build +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}/") \ No newline at end of file diff --git a/Makefile b/Makefile index 76c916c1d2..8eafa71deb 100644 --- a/Makefile +++ b/Makefile @@ -5,6 +5,7 @@ SRC_LIBCOM = lib_com SRC_LIBDEBUG = lib_debug SRC_LIBDEC = lib_dec SRC_LIBENC = lib_enc +SRC_LIBREND = lib_rend SRC_LIBUTIL = lib_util SRC_APP = apps BUILD = build @@ -19,15 +20,17 @@ UTESTS_CREND_DIR = $(UTESTS_DIR)/crend SRC_UTESTS = $(UTESTS_CREND_DIR) -SRC_DIRS = $(sort -u $(SRC_LIBCOM) $(SRC_LIBDEBUG) $(SRC_LIBDEC) $(SRC_LIBENC) $(SRC_LIBUTIL) $(SRC_APP) $(SRC_UTESTS)) +SRC_DIRS = $(sort -u $(SRC_LIBCOM) $(SRC_LIBDEBUG) $(SRC_LIBDEC) $(SRC_LIBENC) $(SRC_LIBREND) $(SRC_LIBUTIL) $(SRC_APP) $(SRC_UTESTS)) # 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_LIBUTIL ?= libivasutil.a CLI_UTESTS_CREND ?= IVAS_crend_unit_test @@ -125,6 +128,7 @@ SRCS_LIBCOM = $(foreach DIR,$(SRC_LIBCOM),$(patsubst $(DIR)/%,%,$(wildcard $(D SRCS_LIBDEBUG = $(foreach DIR,$(SRC_LIBDEBUG),$(patsubst $(DIR)/%,%,$(wildcard $(DIR)/*.c))) SRCS_LIBDEC = $(foreach DIR,$(SRC_LIBDEC),$(patsubst $(DIR)/%,%,$(wildcard $(DIR)/*.c))) 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_UTESTS_CREND = $(foreach DIR,$(UTESTS_CREND_DIR),$(patsubst $(DIR)/%,%,$(wildcard $(DIR)/*.c))) @@ -133,9 +137,11 @@ 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_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_UTESTS_CREND = $(addprefix $(OBJDIR)/,$(SRCS_UTESTS_CREND:.c=.o)) @@ -149,7 +155,7 @@ DEPS = $(addprefix $(OBJDIR)/,$(SRCS_LIBCOM:.c=.P) $(SRCS_LIBDEBUG:.c=.P) $(SRCS .PHONY: all clean clean_unittests clean_all -all: $(CLI_APIENC) $(CLI_APIDEC) +all: $(CLI_APIENC) $(CLI_APIDEC) $(CLI_APIREND) $(OBJDIR): $(QUIET)mkdir -p $(OBJDIR) @@ -157,7 +163,7 @@ $(OBJDIR): $(LIB_LIBCOM): $(OBJS_LIBCOM) $(QUIET_AR)$(AR) rcs $@ $^ -$(LIB_LIBDEC): $(OBJS_LIBDEC) +$(LIB_LIBDEC): $(OBJS_LIBDEC) $(OBJS_LIBREND) $(QUIET_AR)$(AR) rcs $@ $^ $(LIB_LIBDEBUG): $(OBJS_LIBDEBUG) @@ -166,27 +172,33 @@ $(LIB_LIBDEBUG): $(OBJS_LIBDEBUG) $(LIB_LIBENC): $(OBJS_LIBENC) $(QUIET_AR)$(AR) rcs $@ $^ +$(LIB_LIBREND): $(OBJS_LIBREND) + $(QUIET_AR)$(AR) rcs $@ $^ + $(LIB_LIBUTIL): $(OBJS_LIBUTIL) $(QUIET_AR)$(AR) rcs $@ $^ -$(CLI_APIENC): $(LIB_LIBENC) $(LIB_LIBDEBUG) $(LIB_LIBCOM) $(LIB_LIBUTIL) $(OBJS_CLI_APIENC) - $(QUIET_LINK)$(CC) $(LDFLAGS) $(OBJS_CLI_APIENC) -L. -livasutil -livasenc -livascom -livasdebug $(LDLIBS) -o $(CLI_APIENC) +$(CLI_APIENC): $(OBJS_CLI_APIENC) $(LIB_LIBENC) $(LIB_LIBCOM) $(LIB_LIBUTIL) $(LIB_LIBDEBUG) + $(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) + $(QUIET_LINK)$(CC) $(LDFLAGS) $(OBJS_CLI_APIDEC) -L. -livasdec -livascom -livasutil -livasdebug $(LDLIBS) -o $(CLI_APIDEC) -$(CLI_APIDEC): $(LIB_LIBDEC) $(LIB_LIBDEBUG) $(LIB_LIBCOM) $(LIB_LIBUTIL) $(OBJS_CLI_APIDEC) - $(QUIET_LINK)$(CC) $(OBJS_CLI_APIDEC) $(LDFLAGS) -L. -livasutil -livasdec -livascom -livasdebug $(LDLIBS) -o $(CLI_APIDEC) +$(CLI_APIREND): $(OBJS_CLI_APPREND) $(LIB_LIBREND) $(LIB_LIBCOM) $(LIB_LIBUTIL) $(LIB_LIBDEBUG) + $(QUIET_LINK)$(CC) $(LDFLAGS) $(OBJS_CLI_APPREND) -L. -livasrend -livascom -livasutil -livasdebug $(LDLIBS) -o $(CLI_APIREND) -$(CLI_UTESTS_CREND): $(LIB_LIBDEC) $(LIB_LIBDEBUG) $(LIB_LIBCOM) $(LIB_LIBENC) $(LIB_LIBUTIL) $(OBJS_CLI_UTESTS_CREND) - $(QUIET_LINK)$(CC) $(OBJS_CLI_UTESTS_CREND) $(LDFLAGS) -L. -livasutil -livasdec -livascom -livasdebug $(LDLIBS) -o $(UTESTS_CREND_DIR)/$(CLI_UTESTS_CREND) +$(CLI_UTESTS_CREND): $(OBJS_CLI_UTESTS_CREND) $(LIB_LIBDEC) $(LIB_LIBCOM) $(LIB_LIBUTIL) $(LIB_LIBDEBUG) + $(QUIET_LINK)$(CC) $(LDFLAGS) $(OBJS_CLI_UTESTS_CREND) -L. -livasdec -livascom -livasutil -livasdebug $(LDLIBS) -o $(UTESTS_CREND_DIR)/$(CLI_UTESTS_CREND) unittests: $(CLI_UTESTS_CREND) -libs: $(LIB_LIBENC) $(LIB_LIBDEBUG) $(LIB_LIBCOM) $(LIB_LIBDEC) $(LIB_LIBUTIL) +libs: $(LIB_LIBENC) $(LIB_LIBDEBUG) $(LIB_LIBCOM) $(LIB_LIBDEC) $(LIB_LIBREND) $(LIB_LIBUTIL) clean: clean_unittests $(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_PRD) $(LIB_LIBENC) $(LIB_LIBDEBUG) $(LIB_LIBCOM) $(LIB_LIBDEC) $(LIB_LIBUTIL) + $(QUIET)$(RM) $(CLI_APIENC) $(CLI_APIDEC) $(CLI_APIREND) $(LIB_LIBENC) $(LIB_LIBDEBUG) $(LIB_LIBCOM) $(LIB_LIBDEC) $(LIB_LIBUTIL) $(LIB_LIBREND) clean_unittests: $(QUIET)$(RM) $(OBJS_UTESTS) diff --git a/Workspace_msvc/Workspace_msvc.sln b/Workspace_msvc/Workspace_msvc.sln index be693e81cc..32f41bb6dd 100644 --- a/Workspace_msvc/Workspace_msvc.sln +++ b/Workspace_msvc/Workspace_msvc.sln @@ -8,6 +8,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lib_enc", "lib_enc.vcxproj" 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}" @@ -16,6 +18,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "decoder", "decoder.vcxproj" 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 @@ -60,6 +64,15 @@ Global {39EC200D-7795-4FF8-B214-B24EDA5526AE}.Unittests|Win32.ActiveCfg = Unittests|Win32 {39EC200D-7795-4FF8-B214-B24EDA5526AE}.Unittests|Win32.Build.0 = Unittests|Win32 {39EC200D-7795-4FF8-B214-B24EDA5526AE}.Unittests|x64.ActiveCfg = Unittests|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 + {718DE063-A18B-BB72-9150-62B892E6FFA6}.Unittests|Win32.ActiveCfg = Unittests|Win32 + {718DE063-A18B-BB72-9150-62B892E6FFA6}.Unittests|Win32.Build.0 = Unittests|Win32 + {718DE063-A18B-BB72-9150-62B892E6FFA6}.Unittests|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 @@ -96,6 +109,15 @@ Global {B3FC9DFC-7268-8660-7C0D-B60BAF02C554}.Unittests|Win32.ActiveCfg = Unittests|Win32 {B3FC9DFC-7268-8660-7C0D-B60BAF02C554}.Unittests|Win32.Build.0 = Unittests|Win32 {B3FC9DFC-7268-8660-7C0D-B60BAF02C554}.Unittests|x64.ActiveCfg = Unittests|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 + {12B4C8A5-1E06-4E30-B443-D1F916F52B47}.Unittests|Win32.ActiveCfg = Unittests|Win32 + {12B4C8A5-1E06-4E30-B443-D1F916F52B47}.Unittests|Win32.Build.0 = Unittests|Win32 + {12B4C8A5-1E06-4E30-B443-D1F916F52B47}.Unittests|x64.ActiveCfg = Release|Win32 {32354377-ACA7-40F9-9A0E-87FC956F0B78}.Debug|Win32.ActiveCfg = Debug|Win32 {32354377-ACA7-40F9-9A0E-87FC956F0B78}.Debug|x64.ActiveCfg = Debug|Win32 {32354377-ACA7-40F9-9A0E-87FC956F0B78}.Release|Win32.ActiveCfg = Release|Win32 diff --git a/Workspace_msvc/lib_com.vcxproj b/Workspace_msvc/lib_com.vcxproj index ed091573fc..994b1ec429 100644 --- a/Workspace_msvc/lib_com.vcxproj +++ b/Workspace_msvc/lib_com.vcxproj @@ -78,7 +78,7 @@ Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_util;%(AdditionalIncludeDirectories) + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) EnableFastChecks @@ -109,7 +109,7 @@ Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_util;%(AdditionalIncludeDirectories) + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) @@ -147,7 +147,7 @@ Neither false false - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_util;%(AdditionalIncludeDirectories) + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) true @@ -358,4 +358,4 @@ - \ No newline at end of file + diff --git a/Workspace_msvc/lib_debug.vcxproj b/Workspace_msvc/lib_debug.vcxproj index d8efa0879d..5dc36d4633 100644 --- a/Workspace_msvc/lib_debug.vcxproj +++ b/Workspace_msvc/lib_debug.vcxproj @@ -73,7 +73,7 @@ Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_util;%(AdditionalIncludeDirectories) + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) false @@ -97,7 +97,7 @@ Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_util;%(AdditionalIncludeDirectories) + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) false @@ -124,7 +124,7 @@ AnySuitable false false - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_util;%(AdditionalIncludeDirectories) + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) true @@ -166,4 +166,4 @@ - \ No newline at end of file + diff --git a/Workspace_msvc/lib_dec.vcxproj b/Workspace_msvc/lib_dec.vcxproj index 3bde19ca47..414e14e35b 100644 --- a/Workspace_msvc/lib_dec.vcxproj +++ b/Workspace_msvc/lib_dec.vcxproj @@ -89,7 +89,7 @@ Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_util;%(AdditionalIncludeDirectories) + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_util;..\lib_rend;%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) EnableFastChecks @@ -126,7 +126,7 @@ Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_util;%(AdditionalIncludeDirectories) + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_util;..\lib_rend;%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) @@ -169,7 +169,7 @@ Neither false false - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_util;%(AdditionalIncludeDirectories) + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_util;..\lib_rend;%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) true @@ -264,12 +264,8 @@ - - - - @@ -278,17 +274,13 @@ - - - - @@ -296,35 +288,15 @@ - - - - - - - - - - - - - - - - - - - - @@ -392,10 +364,7 @@ - - - @@ -418,6 +387,10 @@ {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 155b8dfc45..8b2ccec3bb 100644 --- a/Workspace_msvc/lib_dec.vcxproj.filters +++ b/Workspace_msvc/lib_dec.vcxproj.filters @@ -28,24 +28,6 @@ dec_ivas_c - - dec_ivas_c - - - dec_ivas_c - - - dec_ivas_c - - - dec_ivas_c - - - dec_ivas_c - - - dec_ivas_c - dec_ivas_c @@ -406,24 +388,9 @@ dec_ivas_c - - dec_ivas_c - - - dec_ivas_c - dec_ivas_c - - dec_ivas_c - - - dec_ivas_c - - - dec_ivas_c - dec_ivas_c @@ -448,15 +415,9 @@ dec_ivas_c - - dec_ivas_c - dec_ivas_c - - dec_ivas_c - dec_ivas_c @@ -512,42 +473,21 @@ dec_ivas_c - - dec_ivas_c - - - dec_ivas_c - - - dec_ivas_c - dec_ivas_c - + dec_ivas_c dec_ivas_c - - dec_ivas_c - - + dec_ivas_c dec_ivas_c - - dec_ivas_c - - - dec_ivas_c - - - dec_ivas_c - dec_ivas_c @@ -560,27 +500,6 @@ dec_ivas_c - - dec_ivas_c - - - dec_ivas_c - - - dec_ivas_c - - - dec_ivas_c - - - dec_ivas_c - - - dec_ivas_c - - - dec_ivas_c - @@ -595,9 +514,6 @@ dec_h - - dec_h - dec_h @@ -623,12 +539,6 @@ dec_h - - dec_h - - - dec_h - diff --git a/Workspace_msvc/lib_enc.vcxproj b/Workspace_msvc/lib_enc.vcxproj index 40302c56cd..060776c99a 100644 --- a/Workspace_msvc/lib_enc.vcxproj +++ b/Workspace_msvc/lib_enc.vcxproj @@ -89,7 +89,7 @@ Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_util;%(AdditionalIncludeDirectories) + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) EnableFastChecks @@ -129,7 +129,7 @@ Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_util;%(AdditionalIncludeDirectories) + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;$(Macros);WIN32;%(PreprocessorDefinitions) @@ -176,7 +176,7 @@ Neither false false - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_util;%(AdditionalIncludeDirectories) + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_rend;%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) true @@ -422,4 +422,4 @@ - \ No newline at end of file + diff --git a/Workspace_msvc/lib_rend.vcxproj b/Workspace_msvc/lib_rend.vcxproj new file mode 100644 index 0000000000..e87baf5605 --- /dev/null +++ b/Workspace_msvc/lib_rend.vcxproj @@ -0,0 +1,257 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Unittests + Win32 + + + + lib_rend + {718DE063-A18B-BB72-9150-62B892E6FFA6} + evs_dec + 10.0.17763.0 + + + StaticLibrary + v141 + false + MultiByte + + + StaticLibrary + v141 + false + MultiByte + + + + StaticLibrary + v141 + false + MultiByte + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>15.0.27428.2015 + + + .\Debug_$(ProjectName)\ + .\Debug_$(ProjectName)\ + false + false + libivasrend + + + .\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 + + + + + + + + + .\Debug\$(ProjectName).tlb + + + + + Disabled + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_util;%(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 + + + + + + + + + + + \ No newline at end of file diff --git a/Workspace_msvc/lib_util.vcxproj b/Workspace_msvc/lib_util.vcxproj index 0bb399c153..3e269dab4b 100644 --- a/Workspace_msvc/lib_util.vcxproj +++ b/Workspace_msvc/lib_util.vcxproj @@ -73,7 +73,7 @@ Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_util;%(AdditionalIncludeDirectories) + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_util;..\lib_rend;%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;$(Macros);ZLIB_WINAPI;%(PreprocessorDefinitions) false @@ -93,7 +93,7 @@ Disabled - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_util;%(AdditionalIncludeDirectories) + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_util;..\lib_rend;%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;$(Macros);ZLIB_WINAPI;%(PreprocessorDefinitions) false @@ -117,7 +117,7 @@ AnySuitable false false - ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_util;%(AdditionalIncludeDirectories) + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_util;..\lib_rend;%(AdditionalIncludeDirectories) _CRT_SECURE_NO_WARNINGS;$(Macros);ZLIB_WINAPI;%(PreprocessorDefinitions) true @@ -141,6 +141,7 @@ + @@ -162,6 +163,7 @@ + diff --git a/scripts/prerenderer/Workspace_msvc/prerenderer.vcxproj b/Workspace_msvc/renderer.vcxproj similarity index 58% rename from scripts/prerenderer/Workspace_msvc/prerenderer.vcxproj rename to Workspace_msvc/renderer.vcxproj index ed2ad4ff85..69ae363370 100644 --- a/scripts/prerenderer/Workspace_msvc/prerenderer.vcxproj +++ b/Workspace_msvc/renderer.vcxproj @@ -9,11 +9,15 @@ Release Win32 + + Unittests + Win32 + - prerenderer - {12b4c8a5-1e06-4e30-b443-d1f916f52b47} - prerenderer + renderer + {12B4C8A5-1E06-4E30-B443-D1F916F52B47} + renderer 10.0.17763.0 @@ -23,6 +27,12 @@ false MultiByte + + Application + v141 + false + MultiByte + Application v141 @@ -34,27 +44,40 @@ + + + + + + <_ProjectFileVersion>15.0.27428.2015 - .. + ..\ + .\Debug_$(ProjectName)\ + false + false + IVAS_rend + + + ..\ .\Debug_$(ProjectName)\ false false - IVAS_prerenderer + IVAS_rend - .. + ..\ .\Release_$(ProjectName)\ false false - IVAS_prerenderer + IVAS_rend @@ -63,8 +86,8 @@ Disabled - ..\..\..\lib_com;..\..\..\lib_debug;..\..\..\lib_dec;..\..\..\lib_enc;..\..\..\lib_util;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_util;..\lib_rend;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;WIN32;$(Macros);%(PreprocessorDefinitions) EnableFastChecks MultiThreadedDebug @@ -76,7 +99,7 @@ true OldStyle Default - 4100;%(DisableSpecificWarnings) + %(DisableSpecificWarnings) _DEBUG;%(PreprocessorDefinitions) @@ -87,16 +110,64 @@ $(OutDir)$(TargetName).exe true - false true $(IntDir)$(ProjectName).pdb Console - false MachineX86 + + + + + + + $(IntDir)$(ProjectName).tlb + + + + + Disabled + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\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 @@ -109,8 +180,8 @@ Neither false false - ..\..\..\lib_com;..\..\..\lib_debug;..\..\..\lib_dec;..\..\..\lib_enc;..\..\..\lib_util;%(AdditionalIncludeDirectories) - _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + ..\lib_com;..\lib_debug;..\lib_dec;..\lib_enc;..\lib_util;..\lib_rend;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;$(Macros);%(PreprocessorDefinitions) true Default @@ -125,7 +196,7 @@ true Default - 4100;%(DisableSpecificWarnings) + %(DisableSpecificWarnings) NDEBUG;%(PreprocessorDefinitions) @@ -141,43 +212,30 @@ false MachineX86 + libcmtd.lib - + + + + {54509728-928B-44D9-A118-A6F92F08B34F} false - + {2FA8F384-0775-F3B7-F8C3-85209222FC70} false - + {39ec200d-7795-4ff8-b214-b24eda5526ae} false - - {E822DDAF-0F5F-4CD0-A694-38AE69DE74D3} + + {718DE063-A18B-BB72-9150-62B892E6FFA6} false - - - - - - - - - - - - - - - - - diff --git a/apps/decoder.c b/apps/decoder.c index cb81edc24b..953df8d6b8 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -158,7 +158,6 @@ static void print_mem_dec( size_t SRAM_size ) fprintf( stdout, "PROM size (common): %d words (or instructions)\n", PROM_Size_lib_com ); fprintf( stdout, "Stack size (decoder): %ld words in %s() in frame #%d\n", ( ( ptr_base_stack - ptr_max_stack ) * sizeof( int16_t ) ) / sizeof( float ), location_max_stack, wc_frame ); fprintf( stdout, "Table ROM size (decoder): %ld words\n", ( Const_Data_Size_rom_dec() + Const_Data_Size_ivas_rom_dec() ) / sizeof( float ) ); - fprintf( stdout, "Table ROM size (binaural renderer): %ld words\n", ( Const_Data_Size_ivas_rom_binauralRen() + Const_Data_Size_ivas_rom_TdBinauralR() + Const_Data_Size_ivas_rom_binaural_cr() ) / sizeof( float ) ); fprintf( stdout, "Table ROM size (common): %ld words\n", ( Const_Data_Size_rom_com() + Const_Data_Size_ivas_rom_com() ) / sizeof( float ) ); #ifdef RAM_COUNTING_TOOL fprintf( stdout, "Static RAM size (decoder): %ld words\n\n", SRAM_size ); diff --git a/apps/renderer.c b/apps/renderer.c new file mode 100644 index 0000000000..38c28e3dc4 --- /dev/null +++ b/apps/renderer.c @@ -0,0 +1,1912 @@ +/****************************************************************************************************** + + (C) 2022 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 "audio_file_reader.h" +#include "audio_file_writer.h" +#include "cmdln_parser.h" +#include "cmdl_tools.h" +#include "common_api_types.h" +#include "head_rotation_file_reader.h" +#include "hrtf_file_reader.h" +#include "ism_file_reader.h" +#include "lib_rend.h" +#include "ls_custom_file_reader.h" +#include "render_config_reader.h" +#include "ivas_stat_dec.h" +#include "prot.h" +#ifdef WMOPS +#include "wmops.h" +#include "PROM_Size_lib_rend.h" +#endif +#ifdef RAM_COUNTING_TOOL +#include "mem_count.h" +#endif +#include +#include +#include +#include +#include +#include +#include + +#ifndef count_malloc +#ifdef RAM_COUNTING_TOOL +#define count_malloc( n1 ) MALLOC_FCT_CALL( n1 ) +#define count_calloc( n1, n2 ) CALLOC_FCT_CALL( n1, n2 ) +#define count_free( ptr ) FREE_FCT_CALL( ptr ) +#else +#define count_malloc( n1 ) malloc( n1 ) +#define count_calloc( n1, n2 ) calloc( n1, n2 ) +#define count_free( ptr ) free( ptr ) +#endif +#endif + +#ifndef min +#define min( x, y ) ( ( x ) < ( y ) ? ( x ) : ( y ) ) +#endif + +#ifndef max +#define max( x, y ) ( ( x ) > ( y ) ? ( x ) : ( y ) ) +#endif + +#define RENDERER_MAX_METADATA_LENGTH 8192 +#define RENDERER_MAX_METADATA_LINE_LENGTH 1024 + +#if !defined( DEBUGGING ) && !defined( WMOPS ) +static +#endif + int32_t frame = 0; + +#ifdef _WIN32 +#define SEP_FOLDER '\\' +#else +#define SEP_FOLDER '/' +#endif + +#ifdef WMOPS +void print_stack_call_tree( void ); +int Const_Data_Size_ivas_rom_rend( void ); +extern int16_t *ptr_base_stack; +extern int16_t *ptr_max_stack; +extern int32_t wc_frame; +extern char location_max_stack[256]; + +/* clang-format off */ +/*------------------------------------------------------------------------------------------* +* Function to print complexity & memory estimates +*------------------------------------------------------------------------------------------*/ +static void print_mem_renderer(size_t SRAM_size) +{ + fprintf( stdout, "\n\n --- Renderer cmdln demo memory usage --- \n\n" ); + + fprintf( stdout, "PROM size (renderer): %d words (or instructions)\n", PROM_Size_lib_rend ); + fprintf( stdout, "Stack size: %d words in %s() in frame #%d\n", ( ptr_base_stack - ptr_max_stack ) * sizeof( int16_t ) / sizeof( float ), location_max_stack, wc_frame ); + fprintf( stdout, "Table ROM size(renderer): %d words\n", (Const_Data_Size_ivas_rom_rend() ) / sizeof( float ) ); + fprintf( stdout, "Table ROM size (binaural renderer): %ld words\n", ( Const_Data_Size_ivas_rom_binauralRen() + Const_Data_Size_ivas_rom_TdBinauralR() + Const_Data_Size_ivas_rom_binaural_cr() ) / sizeof( float ) ); +#ifdef RAM_COUNTING_TOOL + fprintf( stdout, "Static RAM size: %d words\n\n", SRAM_size ); +#endif + print_stack_call_tree(); + + fprintf( stdout, "Note: this is an optimistic estimate of the memory consumption assuming\n" ); + fprintf( stdout, " that each variable (short, long or float) in the codec requires\n" ); + fprintf( stdout, " 32 bits of memory and may therefore be represented by 1 word.\n" ); + fprintf( stdout, " The following formula is used: sizeof('memory array')/sizeof(float)\n\n" ); +} +/* clang-format on */ +#endif + +typedef struct IsmPositionProvider +{ + uint32_t frameCounter; + uint16_t numObjects; + IsmFileReader *ismReaders[RENDERER_MAX_ISM_INPUTS]; + uint32_t numPositions[RENDERER_MAX_ISM_INPUTS]; + IVAS_REND_AudioObjectPosition *positions[RENDERER_MAX_ISM_INPUTS]; /* size: [RENDERER_MAX_ISM_INPUTS][numPositions[object_index]] */ + uint16_t *positionDurations[RENDERER_MAX_ISM_INPUTS]; /* size: [RENDERER_MAX_ISM_INPUTS][numPositions[object_index]] */ + uint32_t currentPositionIdxs[RENDERER_MAX_ISM_INPUTS]; /* Index of current position as listed in the metadata file */ + uint16_t durationCounters[RENDERER_MAX_ISM_INPUTS]; /* Number of frames spent at current position */ +} IsmPositionProvider; + +typedef enum InputFormat +{ + INPUT_FORMAT_NONE = 0, + INPUT_FORMAT_SBA, + INPUT_FORMAT_ISM, + INPUT_FORMAT_MC +} InputFormat; + +typedef struct CmdlnArgs +{ + char inputFilePath[FILENAME_MAX]; + char outputFilePath[FILENAME_MAX]; + int32_t sampleRate; + AUDIO_CONFIG inputFormat; + IVAS_REND_InputConfig inConfig; + IVAS_REND_OutputConfig outConfig; + uint8_t numAudioObjects; + char metaDataFiles[RENDERER_MAX_ISM_INPUTS][FILENAME_MAX]; + char trajectoryFile[FILENAME_MAX]; + char customHrtfFile[FILENAME_MAX]; + char renderConfigFile[FILENAME_MAX]; + int8_t orientationTracking; + float noDiegeticPan; + bool neverDropLfe; /* flag */ + bool delayCompensationEnabled; /* flag */ + bool quietModeEnabled; +} CmdlnArgs; + +static int8_t setInConfig( + int16_t numChannels, + AUDIO_CONFIG input_config, + IVAS_REND_InputConfig *inConfig, + IsmPositionProvider *positionProvider ); + +static IVAS_REND_Ambisonics ambisonicsOrderToEnum( + int32_t order ); + +static IVAS_REND_Ambisonics audioCfgToAmbiEnum( + AUDIO_CONFIG cfg ); + +static IVAS_REND_SpeakerLayout speakerLayoutCicpToEnum( + int32_t cicpIndex ); + +static IVAS_REND_SpeakerLayout audioCfgToMcEnum( + AUDIO_CONFIG cfg ); + +static int8_t parseInFormat( + char **optionValues, + CmdlnArgs *args ); + +static int8_t parseOutConfig( + char *configString, + IVAS_REND_OutputConfig *outConfig ); + +static void parseConfigFile( + char *path, + char *audioFilePath, + IVAS_REND_InputConfig *inConfig, + IsmPositionProvider *positionProvider ); + +static void parseCustomLayoutFile( + char *filePath, + IVAS_LSSETUP_CUSTOM_HANDLE *hLsSetupCustom ); + +static CmdlnArgs parseCmdlnArgs( + int32_t argc, + char **argv ); + +static IsmPositionProvider *IsmPositionProvider_open( + void ); + +static void IsmPositionProvider_getNextFrame( + IsmPositionProvider *positionProvider, + IVAS_REND_AudioObjectMetadataBuffer *objectMetadataBuffer ); + +static void IsmPositionProvider_close( + IsmPositionProvider *positionProvider ); + +static void readFromShorthandMetadata( + IsmPositionProvider *positionProvider, + IVAS_REND_AudioObjectMetadataBuffer *objectMetadataBuffer, + uint32_t objIdx ); + +void getMetadataFromFileReader( + IsmFileReader *ismReader, + IVAS_REND_AudioObjectMetadataBuffer *objectMetadataBuffer, + uint32_t objIdx ); + +static void splitConfigFile( + const char *mdfFilePath, + char *metadataString, + uint32_t *metadataStringLength, + char *wavFileName, + uint32_t *wavFileNameLength ); + +static char *readNextMetadataChunk( + char *line, + const char *delimiter ); + +static void parseUint8( + const char *line, + uint8_t *ret ); + +static void parseUint16( + const char *line, + uint16_t *ret ); + +static int8_t parseUint32( + const char *line, + uint32_t *ret ); + +static void parseObjectPosition( + char *line, + IVAS_REND_AudioObjectPosition *position, + uint16_t *positionDuration ); + +static void parseIsm( + char *line, + char *inDir, + IVAS_REND_InputConfig *inConfig, + IsmPositionProvider *positionProvider, + int32_t idx ); + +static void parseSba( + char *line, + IVAS_REND_InputConfig *inConfig, + int32_t idx ); + +static void parseMc( + char *line, + IVAS_REND_InputConfig *inConfig, + int32_t idx ); + +static void parseMetadata( + char *metadataString, + char *inDir, + IVAS_REND_InputConfig *inConfig, + IsmPositionProvider *positionProvider ); + +static void convert_backslash( + char *str ); + +static void remove_cr( + char *str ); + + +/* ============================================================================ */ + +int32_t main( int32_t argc, char **argv ) +{ + IVAS_REND_HANDLE hIvasRend; + HeadRotFileReader *headRotReader = NULL; + hrtfFileReader *hrtfFileReader = NULL; + IsmPositionProvider *positionProvider; + RenderConfigReader *renderConfigReader = NULL; + char audioFilePath[FILENAME_MAX]; + AudioFileReader *audioReader = NULL; + int16_t numInChannels; + AudioFileWriter *audioWriter; + int16_t inBufferSize; + int32_t outBufferSize; + int16_t *inpInt16Buffer; + float *inFloatBuffer; + int16_t *outInt16Buffer; + float *outFloatBuffer; + IVAS_REND_AudioBuffer inBuffer; + IVAS_REND_AudioBuffer outBuffer; + int16_t numSamplesRead; + int16_t delayNumSamples = -1; + int16_t delayNumSamples_orig = 0; + int16_t zeroPad = 0; + int32_t delayTimeScale = 0; + int16_t i; + ivas_error error = IVAS_ERR_OK; +#ifdef WMOPS + size_t SRAM_size; +#endif + +#ifdef WMOPS + reset_wmops(); + reset_stack(); +#endif + +#ifdef RAM_COUNTING_TOOL + mem_count_init( 0, USE_32BITS ); +#endif + + CmdlnArgs args = parseCmdlnArgs( argc, argv ); + const int16_t frameSize_smpls = (int16_t) ( 20 * args.sampleRate / 1000 ); + + /* === Open === */ + hIvasRend = IVAS_REND_Open(); + positionProvider = IsmPositionProvider_open(); + + convert_backslash( args.inputFilePath ); + convert_backslash( args.outputFilePath ); + convert_backslash( args.trajectoryFile ); + + if ( args.trajectoryFile[0] != '\0' ) + { + HeadRotationFileReader_open( args.trajectoryFile, &headRotReader ); + } + + if ( args.customHrtfFile[0] != '\0' ) + { + hrtfFileReader_open( args.customHrtfFile, &hrtfFileReader ); + } + + if ( args.renderConfigFile[0] != '\0' ) + { + RenderConfigReader_open( args.renderConfigFile, &renderConfigReader ); + } + + /* === Parse === */ + if ( args.inputFormat == AUDIO_CONFIG_INVALID || args.inputFormat == AUDIO_CONFIG_META ) + { + /* Only parse config file if input config is none */ + parseConfigFile( args.inputFilePath, audioFilePath, &args.inConfig, positionProvider ); + } + else + { + /* If input config is set, input file path is the input audio file, not config file */ + strncpy( audioFilePath, args.inputFilePath, FILENAME_MAX ); + + /* Initialize inConfig - this will be overwritten when applying forced parameters, + * but not initializing here causes a compiler warning on msvc */ + args.inConfig.numAmbisonicsBuses = 0; + args.inConfig.numMultiChannelBuses = 0; + args.inConfig.numAudioObjects = args.numAudioObjects; + } + + /* === Apply forced parameters === */ + if ( AudioFileReader_open( &audioReader, audioFilePath, args.sampleRate ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error opening file: %s\n", audioFilePath ); + exit( -1 ); + } + + if ( args.inputFormat != AUDIO_CONFIG_INVALID ) + { + numInChannels = AudioFileReader_getNumChannels( audioReader ); + if ( numInChannels == 0 ) + { + fprintf( stderr, "File does not contain number of channels metadata, probably a raw file: %s\n", audioFilePath ); + exit( -1 ); + } + + for ( i = 0; i < args.numAudioObjects; i++ ) + { + positionProvider->ismReaders[i] = IsmFileReader_open( args.metaDataFiles[i] ); + } + + if ( setInConfig( numInChannels, args.inputFormat, &args.inConfig, positionProvider ) != 0 ) + { + fprintf( stderr, "File cannot be used: %s\n", audioFilePath ); + exit( -1 ); + } + } + + /* === Configure === */ + if ( ( error = IVAS_REND_Configure( hIvasRend, args.inConfig, args.outConfig, args.sampleRate, args.trajectoryFile[0] != '\0' ) ) != IVAS_ERR_OK ) + { + exit( -1 ); + } + + if ( args.neverDropLfe ) + { + IVAS_REND_SetNeverDropLfe( hIvasRend, 1 ); + } + + if ( IVAS_REND_GetInChannels( hIvasRend ) != AudioFileReader_getNumChannels( audioReader ) ) + { + fprintf( stderr, "Number of channels in input file does not match selected configuration\n" ); + exit( -1 ); + } + + /* === Process === */ + if ( AudioFileWriter_open( &audioWriter, args.outputFilePath, args.sampleRate, IVAS_REND_GetOutChannels( hIvasRend ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Failed to open file: %s\n", args.outputFilePath ); + exit( -1 ); + } + + inBufferSize = frameSize_smpls * IVAS_REND_GetInChannels( hIvasRend ); + outBufferSize = frameSize_smpls * IVAS_REND_GetOutChannels( hIvasRend ); + inpInt16Buffer = count_calloc( inBufferSize, sizeof( int16_t ) ); + inFloatBuffer = count_calloc( inBufferSize, sizeof( float ) ); + outInt16Buffer = count_calloc( outBufferSize, sizeof( int16_t ) ); + outFloatBuffer = count_calloc( outBufferSize, sizeof( float ) ); + + inBuffer.config.sampleRate = args.sampleRate; + inBuffer.config.bufferSize = frameSize_smpls; + inBuffer.config.numChannels = IVAS_REND_GetInChannels( hIvasRend ); + inBuffer.data = inFloatBuffer; + + outBuffer.config.sampleRate = args.sampleRate; + outBuffer.config.bufferSize = frameSize_smpls; + outBuffer.config.numChannels = IVAS_REND_GetOutChannels( hIvasRend ); + outBuffer.data = outFloatBuffer; + +#ifdef WMOPS + reset_wmops(); +#endif + + if ( !args.quietModeEnabled ) + { + fprintf( stdout, "\n------ Running the renderer ------\n\n" ); + fprintf( stdout, "Frames processed: " ); + } + else + { + fprintf( stdout, "\n\n-- Start the renderer (quiet mode) --\n\n" ); + } + + while ( 1 ) + { + int32_t chnl, smpl; + int32_t num_in_channels; + num_in_channels = inBuffer.config.numChannels; + i = 0; + + /* Read the input data */ + if ( ( error = AudioFileReader_read( audioReader, inpInt16Buffer, inBufferSize, &numSamplesRead ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError reading from file %s\n", audioFilePath ); + exit( -1 ); + } + + if ( numSamplesRead == 0 ) + { + /* end of input data */ + break; + } + + /* Convert from int to float and from interleaved to packed */ + for ( smpl = 0; smpl < frameSize_smpls; ++smpl ) + { + for ( chnl = 0; chnl < num_in_channels; ++chnl ) + { + if ( i < numSamplesRead ) + { + inFloatBuffer[chnl * frameSize_smpls + smpl] = (float) inpInt16Buffer[i] / INT16_MAX; + } + else + { + inFloatBuffer[chnl * frameSize_smpls + smpl] = 0.f; + } + + ++i; + } + } + + IVAS_REND_AudioObjectMetadataBuffer mtdBuffer; + IsmPositionProvider_getNextFrame( positionProvider, &mtdBuffer ); + + /* Read from head rotation trajectory file if specified */ + if ( headRotReader != NULL ) + { + IVAS_QUATERNION quatBuffer[RENDERER_HEAD_POSITIONS_PER_FRAME]; + HeadRotationFileReading( headRotReader, quatBuffer, frame ); + IVAS_REND_SetHeadRotation( hIvasRend, quatBuffer ); + } + + IVAS_REND_Render( hIvasRend, inBuffer, mtdBuffer, outBuffer ); + + int32_t num_out_channels; + num_out_channels = outBuffer.config.numChannels; + i = 0; + + /* Convert from float to int and from packed to interleaved */ + for ( smpl = 0; smpl < frameSize_smpls; ++smpl ) + { + for ( chnl = 0; chnl < num_out_channels; ++chnl ) + { + outInt16Buffer[i] = (int16_t) ( outFloatBuffer[chnl * frameSize_smpls + smpl] * INT16_MAX ); + + ++i; + } + } + + /* TODO tmu : delay compensation not finalized yet */ + if ( delayNumSamples == -1 ) + { + if ( args.delayCompensationEnabled ) + { + if ( IVAS_REND_GetDelay( hIvasRend, &delayNumSamples, &delayTimeScale ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nUnable to get delay of renderer!\n" ); + exit( -1 ); + } + delayNumSamples_orig = delayNumSamples; + } + else + { + delayNumSamples = 0; + } + zeroPad = delayNumSamples; + } + + if ( delayNumSamples < 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 -= outBufferSize; + } + + frame++; + if ( !args.quietModeEnabled ) + { + fprintf( stdout, "%-8d\b\b\b\b\b\b\b\b", frame ); + } + +#ifdef WMOPS + update_wmops(); +#endif + } + + /* add zeros at the end to have equal length of synthesized signals */ + memset( outInt16Buffer, 0, zeroPad * outBuffer.config.numChannels * sizeof( int16_t ) ); + if ( ( error = AudioFileWriter_write( audioWriter, outInt16Buffer, zeroPad * outBuffer.config.numChannels ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nOutput audio file writer error\n" ); + exit( -1 ); + } + + 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", frame ); + + /* === Close === */ + count_free( inpInt16Buffer ); + count_free( inFloatBuffer ); + count_free( outInt16Buffer ); + count_free( outFloatBuffer ); + AudioFileReader_close( &audioReader ); + AudioFileWriter_close( &audioWriter ); + HeadRotationFileReader_close( &headRotReader ); + hrtfFileReader_close( &hrtfFileReader ); + IVAS_REND_Close( &hIvasRend ); + IsmPositionProvider_close( positionProvider ); + RenderConfigReader_close( &renderConfigReader ); + +#ifdef RAM_COUNTING_TOOL +#ifdef WMOPS + SRAM_size = +#endif + mem_count_summary( USE_DEFAULT ); +#endif +#ifdef WMOPS + print_wmops(); + /* print_mem_renderer( SRAM_size ); */ +#endif + + return 0; +} + +static int8_t setInConfig( int16_t numChannels, AUDIO_CONFIG input_config, IVAS_REND_InputConfig *inConfig, IsmPositionProvider *positionProvider ) +{ + int8_t success; /* flag */ + int16_t i; + + success = 1; + + switch ( input_config ) + { + case AUDIO_CONFIG_MONO: + case AUDIO_CONFIG_STEREO: + case AUDIO_CONFIG_5_1: + case AUDIO_CONFIG_7_1: + case AUDIO_CONFIG_5_1_2: + case AUDIO_CONFIG_5_1_4: + case AUDIO_CONFIG_7_1_4: + case AUDIO_CONFIG_LS_CUSTOM: + inConfig->numAudioObjects = 0; + inConfig->numAmbisonicsBuses = 0; + inConfig->numMultiChannelBuses = 1; + inConfig->multiChannelBuses[0].speakerLayout = audioCfgToMcEnum( input_config ); + inConfig->multiChannelBuses[0].inputChannelIndex = 0; + inConfig->multiChannelBuses[0].gain_dB = 0; + break; + case AUDIO_CONFIG_FOA: + case AUDIO_CONFIG_HOA2: + case AUDIO_CONFIG_HOA3: + inConfig->numAudioObjects = 0; + inConfig->numMultiChannelBuses = 0; + inConfig->numAmbisonicsBuses = 1; + inConfig->ambisonicsBuses[0].ambisonicsConfig = audioCfgToAmbiEnum( input_config ); + inConfig->ambisonicsBuses[0].inputChannelIndex = 0; + inConfig->ambisonicsBuses[0].gain_dB = 0; + break; + case AUDIO_CONFIG_ISM1: + case AUDIO_CONFIG_ISM2: + case AUDIO_CONFIG_ISM3: + case AUDIO_CONFIG_ISM4: + inConfig->numAmbisonicsBuses = 0; + inConfig->numMultiChannelBuses = 0; + inConfig->numAudioObjects = numChannels; + positionProvider->numObjects = numChannels; + + for ( i = 0; i < numChannels; ++i ) + { + inConfig->audioObjects[i].inputChannelIndex = i; + inConfig->audioObjects[i].gain_dB = 0; + + positionProvider->numPositions[i] = 1; + positionProvider->positions[i] = count_malloc( sizeof( IVAS_REND_AudioObjectPosition ) ); + IVAS_REND_AudioObjectPosition position; + + /* Spread objects starting from 0, then -/+ 30, then -/+ 60 etc. */ + position.azimuth = (float) ( ( i + 1 ) / 2 ) * 30 * ( i % 2 == 0 ? -1 : 1 ); + position.elevation = 0.0f; + positionProvider->positions[i][0] = position; + + positionProvider->positionDurations[i] = count_malloc( sizeof( uint16_t ) ); + positionProvider->positionDurations[i][0] = 1; + } + break; + case AUDIO_CONFIG_META: + break; + default: + success = 0; + fprintf( stderr, "Invalid or bad config\n" ); + } + + return success ? 0 : -1; +} + +static IVAS_REND_Ambisonics ambisonicsOrderToEnum( int32_t order ) +{ + switch ( order ) + { + case 0: + return IVAS_REND_AMBISONICS_MONO; + case 1: + return IVAS_REND_AMBISONICS_FOA; + case 2: + return IVAS_REND_AMBISONICS_SOA; + case 3: + return IVAS_REND_AMBISONICS_TOA; + } + + return IVAS_REND_AMBISONICS_NONE; +} + +static IVAS_REND_Ambisonics audioCfgToAmbiEnum( AUDIO_CONFIG cfg ) +{ + if ( cfg == AUDIO_CONFIG_MONO ) + { + return IVAS_REND_AMBISONICS_MONO; + } + else if ( cfg == AUDIO_CONFIG_FOA ) + { + return IVAS_REND_AMBISONICS_FOA; + } + else if ( cfg == AUDIO_CONFIG_HOA2 ) + { + return IVAS_REND_AMBISONICS_SOA; + } + else if ( cfg == AUDIO_CONFIG_HOA3 ) + { + return IVAS_REND_AMBISONICS_TOA; + } + + return IVAS_REND_AMBISONICS_NONE; +} + +static IVAS_REND_SpeakerLayout speakerLayoutCicpToEnum( int32_t cicpIndex ) +{ + switch ( cicpIndex ) + { + case 0: + return IVAS_REND_SPEAKER_LAYOUT_CUSTOM; + case 1: + return IVAS_REND_SPEAKER_LAYOUT_MONO; + case 2: + return IVAS_REND_SPEAKER_LAYOUT_STEREO; + case 6: + return IVAS_REND_SPEAKER_LAYOUT_5_1; + case 12: + return IVAS_REND_SPEAKER_LAYOUT_7_1; + case 14: + return IVAS_REND_SPEAKER_LAYOUT_5_1_2; + case 16: + return IVAS_REND_SPEAKER_LAYOUT_5_1_4; + case 19: + return IVAS_REND_SPEAKER_LAYOUT_7_1_4; + } + + return IVAS_REND_SPEAKER_LAYOUT_NONE; +} + +static IVAS_REND_SpeakerLayout audioCfgToMcEnum( AUDIO_CONFIG cfg ) +{ + if ( cfg == AUDIO_CONFIG_LS_CUSTOM ) + { + return IVAS_REND_SPEAKER_LAYOUT_CUSTOM; + } + else if ( cfg == AUDIO_CONFIG_MONO ) + { + return IVAS_REND_SPEAKER_LAYOUT_MONO; + } + else if ( cfg == AUDIO_CONFIG_STEREO ) + { + return IVAS_REND_SPEAKER_LAYOUT_STEREO; + } + else if ( cfg == AUDIO_CONFIG_5_1 ) + { + return IVAS_REND_SPEAKER_LAYOUT_5_1; + } + else if ( cfg == AUDIO_CONFIG_7_1 ) + { + return IVAS_REND_SPEAKER_LAYOUT_7_1; + } + else if ( cfg == AUDIO_CONFIG_5_1_2 ) + { + return IVAS_REND_SPEAKER_LAYOUT_5_1_2; + } + else if ( cfg == AUDIO_CONFIG_5_1_4 ) + { + return IVAS_REND_SPEAKER_LAYOUT_5_1_4; + } + else if ( cfg == AUDIO_CONFIG_7_1_4 ) + { + return IVAS_REND_SPEAKER_LAYOUT_7_1_4; + } + + return IVAS_REND_SPEAKER_LAYOUT_NONE; +} + +static AUDIO_CONFIG parseStrToAudioCfg( char *config_str ) +{ + char format[14]; + uint8_t numObjects; + + format[13] = '\0'; + strncpy( format, config_str, 13 ); + to_upper( format ); + + if ( ( strcmp( format, "MONO" ) == 0 ) || ( strcmp( format, "HOA0" ) == 0 ) || ( strcmp( format, "SBA0" ) == 0 ) ) + { + return AUDIO_CONFIG_MONO; + } + else if ( ( strcmp( format, "STEREO" ) == 0 ) || ( strcmp( format, "CICP2" ) == 0 ) ) + { + return AUDIO_CONFIG_STEREO; + } + else if ( ( strcmp( format, "FOA" ) == 0 ) || ( strcmp( format, "SBA1" ) == 0 ) ) + { + return AUDIO_CONFIG_FOA; + } + else if ( ( strcmp( format, "HOA2" ) == 0 ) || ( strcmp( format, "SBA2" ) == 0 ) ) + { + return AUDIO_CONFIG_HOA2; + } + else if ( ( strcmp( format, "HOA3" ) == 0 ) || ( strcmp( format, "SBA3" ) == 0 ) ) + { + return AUDIO_CONFIG_HOA3; + } + else if ( ( strcmp( format, "5_1" ) == 0 ) || ( strcmp( format, "CICP6" ) == 0 ) ) + { + return AUDIO_CONFIG_5_1; + } + else if ( ( strcmp( format, "7_1" ) == 0 ) || ( strcmp( format, "CICP12" ) == 0 ) ) + { + return AUDIO_CONFIG_7_1; + } + else if ( ( strcmp( format, "5_1_2" ) == 0 ) || ( strcmp( format, "CICP14" ) == 0 ) ) + { + return AUDIO_CONFIG_5_1_2; + } + else if ( ( strcmp( format, "5_1_4" ) == 0 ) || ( strcmp( format, "CICP16" ) == 0 ) ) + { + return AUDIO_CONFIG_5_1_4; + } + else if ( ( strcmp( format, "7_1_4" ) == 0 ) || ( strcmp( format, "CICP19" ) == 0 ) ) + { + return AUDIO_CONFIG_7_1_4; + } + else if ( strncmp( format, "ISM", 3 ) == 0 ) + { + parseUint8( &format[3], &numObjects ); + return AUDIO_CONFIG_ISM1 + numObjects - 1; + } + else if ( strncmp( format, "MASA", 4 ) == 0 ) + { + parseUint8( &format[4], &numObjects ); + return AUDIO_CONFIG_MASA1 + numObjects - 1; + } + else if ( strncmp( format, "META", 4 ) == 0 ) + { + return AUDIO_CONFIG_META; + } + else if ( strncmp( format, "EXT", 3 ) == 0 ) + { + return AUDIO_CONFIG_EXTERNAL; + } + else if ( strcmp( format, "BINAURAL_ROOM" ) == 0 ) + { + return AUDIO_CONFIG_BINAURAL_ROOM; + } + else if ( strcmp( format, "BINAURAL" ) == 0 ) + { + return AUDIO_CONFIG_BINAURAL; + } + else + { + /* check extension to see if it is a custom loudspeaker layout file */ + if ( strcmp( strrchr( config_str, '.' ), ".txt" ) == 0 ) + { + return AUDIO_CONFIG_LS_CUSTOM; + } + else + { + return AUDIO_CONFIG_INVALID; + } + } +} + +static int8_t parseInFormat( char **optionValues, CmdlnArgs *args ) +{ + int8_t success; /* flag */ + success = 1; + + args->inputFormat = parseStrToAudioCfg( optionValues[0] ); + switch ( args->inputFormat ) + { + case AUDIO_CONFIG_LS_CUSTOM: + args->numAudioObjects = 0; + parseCustomLayoutFile( optionValues[0], &args->inConfig.inSetupCustom ); + break; + case AUDIO_CONFIG_ISM1: + case AUDIO_CONFIG_MASA1: + args->numAudioObjects = 1; + break; + case AUDIO_CONFIG_ISM2: + case AUDIO_CONFIG_MASA2: + args->numAudioObjects = 2; + break; + case AUDIO_CONFIG_ISM3: + args->numAudioObjects = 3; + break; + case AUDIO_CONFIG_ISM4: + args->numAudioObjects = 4; + break; + case AUDIO_CONFIG_BINAURAL: + case AUDIO_CONFIG_BINAURAL_ROOM: + fprintf( stderr, "BINAURAL input is not supported!\n" ); + success = 0; + break; + case AUDIO_CONFIG_EXTERNAL: + fprintf( stderr, "No rendering possible for EXT format!\n" ); + success = 0; + default: + args->numAudioObjects = 0; + } + + for ( int16_t i = 0; i < args->numAudioObjects; i++ ) + { + if ( ( strcmp( optionValues[i + 1], "NULL" ) == 0 ) || ( strcmp( optionValues[i + 1], "null" ) == 0 ) ) + { + args->metaDataFiles[i][0] = '\0'; + } + else + { + strcpy( args->metaDataFiles[i], optionValues[i + 1] ); + convert_backslash( args->metaDataFiles[i] ); + } + } + + return success ? 0 : -1; +} + +static int8_t parseOutConfig( char *configString, IVAS_REND_OutputConfig *outConfig ) +{ + int8_t success; /* flag */ + success = 1; + + AUDIO_CONFIG outCfg; + + outCfg = parseStrToAudioCfg( configString ); + switch ( outCfg ) + { + case AUDIO_CONFIG_MONO: + case AUDIO_CONFIG_STEREO: + case AUDIO_CONFIG_5_1: + case AUDIO_CONFIG_7_1: + case AUDIO_CONFIG_5_1_2: + case AUDIO_CONFIG_5_1_4: + case AUDIO_CONFIG_7_1_4: + outConfig->speakerLayout = audioCfgToMcEnum( outCfg ); + break; + case AUDIO_CONFIG_LS_CUSTOM: + outConfig->speakerLayout = IVAS_REND_SPEAKER_LAYOUT_CUSTOM; + parseCustomLayoutFile( configString, &outConfig->outSetupCustom ); + case AUDIO_CONFIG_FOA: + case AUDIO_CONFIG_HOA2: + case AUDIO_CONFIG_HOA3: + outConfig->ambisonics = audioCfgToAmbiEnum( outCfg ); + break; + case AUDIO_CONFIG_BINAURAL: + case AUDIO_CONFIG_BINAURAL_ROOM: + outConfig->binaural = 1; + break; + case AUDIO_CONFIG_META: + /* handled by parseConfigFile() */ + break; + case AUDIO_CONFIG_ISM1: + case AUDIO_CONFIG_ISM2: + case AUDIO_CONFIG_ISM3: + case AUDIO_CONFIG_ISM4: + fprintf( stderr, "ISM is not a valid output format!\n" ); + success = 0; + break; + case AUDIO_CONFIG_MASA1: + case AUDIO_CONFIG_MASA2: + fprintf( stderr, "MASA is not a valid output format!\n" ); + success = 0; + break; + case AUDIO_CONFIG_EXTERNAL: + fprintf( stderr, "No rendering possible for EXT format!\n" ); + success = 0; + break; + default: + success = 0; + fprintf( stderr, "Invalid or bad config\n" ); + } + + return success ? 0 : -1; +} + +static int8_t parseDiegeticPan( char *value, float *noDiegeticPan ) +{ + int8_t success; + success = 1; + to_upper( value ); + + if ( ( strcmp( value, "CENTER" ) == 0 ) || ( strchr( value, 'C' ) != NULL ) ) + { + *noDiegeticPan = 0.f; + } + else if ( ( strcmp( value, "LEFT" ) == 0 ) || ( strchr( value, 'L' ) != NULL ) ) + { + *noDiegeticPan = -1.f; + } + else if ( ( strcmp( value, "RIGHT" ) == 0 ) || ( strchr( value, 'R' ) != NULL ) ) + { + *noDiegeticPan = 1.f; + } + else + { + *noDiegeticPan = (float) atof( value ); + + if ( *noDiegeticPan > 1.0f || *noDiegeticPan < -1.0f ) + { + fprintf( stderr, "Error: Incorrect value for panning option argument specified!\n\n" ); + success = 0; + } + } + return success ? 0 : -1; +} + +static int8_t parseOrientationTracking( char *value, int8_t *tracking_type ) +{ + int8_t success; + success = 1; + + to_upper( value ); + + if ( strcmp( value, "REF" ) == 0 ) + { + *tracking_type = IVAS_ORIENT_TRK_REF; + } + else if ( strcmp( value, "AVG" ) == 0 ) + { + *tracking_type = IVAS_ORIENT_TRK_AVG; + } + else + { + fprintf( stderr, "Error: Invalid orientation tracking type %s \n\n", value ); + success = 0; + } + + return success ? 0 : -1; +} + +static CmdlnArgs defaultArgs( void ) +{ + CmdlnArgs args; + + args.inputFilePath[0] = '\0'; + args.outputFilePath[0] = '\0'; + args.sampleRate = -1; + +#ifdef RAM_COUNTING_TOOL + /* Zero-initialize entire input and output config struct. This is only needed when RAM counting + is active - when freeing memory, it reads all bytes from these structs, which results in msan + failures without full initialization. Without RAM counting the uninitialized struct members will + not be accessed. */ + memset( &args.inConfig, 0, sizeof( args.inConfig ) ); + memset( &args.outConfig, 0, sizeof( args.outConfig ) ); +#endif + args.inConfig.inSetupCustom = NULL; + args.inConfig.numAudioObjects = 0; + args.inConfig.numAmbisonicsBuses = 0; + args.inConfig.numMultiChannelBuses = 0; + + args.outConfig.ambisonics = IVAS_REND_AMBISONICS_NONE; + args.outConfig.speakerLayout = IVAS_REND_SPEAKER_LAYOUT_NONE; + args.outConfig.outSetupCustom = NULL; + + args.outConfig.binaural = 0; + args.orientationTracking = IVAS_ORIENT_TRK_REF; + args.trajectoryFile[0] = '\0'; + args.customHrtfFile[0] = '\0'; + args.renderConfigFile[0] = '\0'; + + args.numAudioObjects = 0; + + args.noDiegeticPan = 0; + + args.neverDropLfe = false; + args.delayCompensationEnabled = true; + args.quietModeEnabled = false; + + for ( size_t i = 0; i < RENDERER_MAX_ISM_INPUTS; i++ ) + { + args.metaDataFiles[i][0] = '\0'; + } + + return args; +} + +typedef enum +{ + CmdLnOptionId_inputFile = 1, + CmdLnOptionId_inputFormat, + CmdLnOptionId_outputFile, + CmdLnOptionId_outputFormat, + CmdLnOptionId_sampleRate, + CmdLnOptionId_trajFile, + CmdLnOptionId_customHrtfFile, + CmdLnOptionId_renderConfigFile, + CmdLnOptionId_noDiegeticPan, + CmdLnOptionId_orientationTracking, + CmdLnOptionId_neverDropLfe, + CmdLnOptionId_noDelayCmp, + CmdLnOptionId_quietModeEnabled, +} CmdLnOptionId; + +static void parseOption( int32_t optionId, char **optionValues, int16_t numOptionValues, void *pOutputStruct ) +{ + CmdlnArgs *args = pOutputStruct; + + switch ( optionId ) + { + case CmdLnOptionId_inputFile: + assert( numOptionValues == 1 ); + strncpy( args->inputFilePath, optionValues[0], FILENAME_MAX ); + break; + case CmdLnOptionId_inputFormat: + assert( numOptionValues <= RENDERER_MAX_ISM_INPUTS + 1 ); + if ( parseInFormat( optionValues, args ) != 0 ) + { + fprintf( stderr, "Unknown input or bad config: %s\n", optionValues[0] ); + exit( -1 ); + } + break; + case CmdLnOptionId_outputFile: + assert( numOptionValues == 1 ); + strncpy( args->outputFilePath, optionValues[0], FILENAME_MAX ); + break; + case CmdLnOptionId_outputFormat: + assert( numOptionValues == 1 ); + if ( parseOutConfig( optionValues[0], &args->outConfig ) != 0 ) + { + fprintf( stderr, "Unknown output or bad config: %s\n", optionValues[0] ); + exit( -1 ); + } + break; + case CmdLnOptionId_sampleRate: + assert( numOptionValues == 1 ); + args->sampleRate = (int32_t) ( strtof( optionValues[0], NULL ) * 1000 ); + break; + case CmdLnOptionId_trajFile: + assert( numOptionValues == 1 ); + strncpy( args->trajectoryFile, optionValues[0], FILENAME_MAX ); + break; + case CmdLnOptionId_customHrtfFile: + assert( numOptionValues == 1 ); + strncpy( args->customHrtfFile, optionValues[0], FILENAME_MAX ); + break; + case CmdLnOptionId_renderConfigFile: + assert( numOptionValues == 1 ); + strncpy( args->renderConfigFile, optionValues[0], FILENAME_MAX ); + break; + case CmdLnOptionId_noDiegeticPan: + assert( numOptionValues == 1 ); + if ( parseDiegeticPan( optionValues[0], &args->noDiegeticPan ) != 0 ) + { + fprintf( stderr, "Unknown option for diegetic panning: %s\n", optionValues[0] ); + exit( -1 ); + } + break; + case CmdLnOptionId_orientationTracking: + assert( numOptionValues == 1 ); + if ( parseOrientationTracking( optionValues[0], &args->orientationTracking ) != 0 ) + { + fprintf( stderr, "Unknown option for orientation tracking: %s\n", optionValues[0] ); + exit( -1 ); + } + break; + case CmdLnOptionId_neverDropLfe: + assert( numOptionValues == 0 ); + args->neverDropLfe = true; + break; + case CmdLnOptionId_noDelayCmp: + assert( numOptionValues == 0 ); + args->delayCompensationEnabled = false; + break; + case CmdLnOptionId_quietModeEnabled: + assert( numOptionValues == 0 ); + args->quietModeEnabled = true; + break; + default: + /* Unreachable */ + break; + } +} + +static CmdlnArgs parseCmdlnArgs( int32_t argc, char **argv ) +{ + CmdLnParser_Option optionsToMatch[] = { + { + .id = CmdLnOptionId_inputFile, + .match = "input_file", + .matchShort = "i", + .description = "Path to the input file", + }, + { + .id = CmdLnOptionId_inputFormat, + .match = "input_format", + .matchShort = "if", + .description = "Format of input file", + }, + { + .id = CmdLnOptionId_outputFile, + .match = "output_file", + .matchShort = "o", + .isRequired = 1, + .description = "Path to the output file", + }, + { + .id = CmdLnOptionId_outputFormat, + .match = "output_format", + .matchShort = "of", + .description = "Output format to render.\nAlternatively, can be a custom loudspeaker layout file", + }, + { + .id = CmdLnOptionId_sampleRate, + .match = "sample_rate", + .matchShort = "fs", + .isRequired = 1, + .description = "Input sampling rate in kHz", + }, + { + .id = CmdLnOptionId_trajFile, + .match = "trajectory_file", + .matchShort = "tf", + .description = "Head rotation trajectory file", + }, + { + .id = CmdLnOptionId_customHrtfFile, + .match = "custom_hrtf", + .matchShort = "hrtf", + .description = "Custom HRTF file for binaural rendering", + }, + { + .id = CmdLnOptionId_renderConfigFile, + .match = "render_config", + .matchShort = "rc", + .description = "Renderer configuration file", + }, + { + .id = CmdLnOptionId_noDiegeticPan, + .match = "no_diegetic_pan", + .matchShort = "ndl", + .description = "Panning mono no dietic sound to stereo -1<= pan <= 1\nleft or l or 1->left, right or r or -1->right, center or c or 0 ->middle", + }, + { + .id = CmdLnOptionId_orientationTracking, + .match = "tracking_type", + .matchShort = "otr", + .description = "Head orientation tracking type: 'ref' or 'avg' (only for binaural rendering)", + }, + { + .id = CmdLnOptionId_neverDropLfe, + .match = "neverDropLfe", + .matchShort = "ndl", + .description = "[flag] If set, renderer tries to render LFE into other channels in an optimal way when rendering to configs w/o LFE", + }, + { + .id = CmdLnOptionId_noDelayCmp, + .match = "no_delay_cmp", + .matchShort = "ndc", + .description = "[flag] Turn off delay compensation", + }, + { + .id = CmdLnOptionId_quietModeEnabled, + .match = "quiet", + .matchShort = "q", + .description = "[flag] Limit printouts to terminal", + }, + }; + + CmdlnArgs parsedArgs = defaultArgs(); + int32_t numOptions = sizeof( optionsToMatch ) / sizeof( CmdLnParser_Option ); + + if ( CmdLnParser_parseArgs( argc, argv, optionsToMatch, numOptions, &parsedArgs, parseOption ) != 0 ) + { + /* Error printout handled internally by CmdLnParser_parseArgs() */ + exit( -1 ); + } + + return parsedArgs; +} + + +IsmPositionProvider *IsmPositionProvider_open( void ) +{ + IsmPositionProvider *ipp; + uint32_t i; + + ipp = (IsmPositionProvider *) count_malloc( sizeof( IsmPositionProvider ) ); + ipp->frameCounter = 0; + ipp->numObjects = 0; + + for ( i = 0; i < RENDERER_MAX_ISM_INPUTS; ++i ) + { + ipp->ismReaders[i] = NULL; + ipp->positions[i] = NULL; + ipp->positionDurations[i] = NULL; + ipp->currentPositionIdxs[i] = 0; + ipp->durationCounters[i] = 0; + } + + return ipp; +} + +void getMetadataFromFileReader( + IsmFileReader *ismReader, + IVAS_REND_AudioObjectMetadataBuffer *objectMetadataBuffer, + uint32_t objIdx ) +{ + IVAS_ISM_METADATA ismMetadata; + ivas_error error; + + if ( ( error = IsmFileReader_readNextFrame( ismReader, &ismMetadata ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError (%s) while reading ism metadata from: %s\n\n", ivas_error_to_string( error ), IsmFileReader_getFilePath( ismReader ) ); + exit( -1 ); + } + + objectMetadataBuffer->positions[objIdx].azimuth = ismMetadata.azimuth; + objectMetadataBuffer->positions[objIdx].elevation = ismMetadata.elevation; +} + +void readFromShorthandMetadata( IsmPositionProvider *positionProvider, + IVAS_REND_AudioObjectMetadataBuffer *objectMetadataBuffer, + uint32_t objIdx ) +{ + uint32_t preUpdatePositionIdx; + uint32_t postUpdatePositionIdx; + + preUpdatePositionIdx = positionProvider->currentPositionIdxs[objIdx]; + + if ( positionProvider->durationCounters[objIdx] == positionProvider->positionDurations[objIdx][preUpdatePositionIdx] ) + { + positionProvider->durationCounters[objIdx] = 0; + positionProvider->currentPositionIdxs[objIdx] = ( positionProvider->currentPositionIdxs[objIdx] + 1 ) % positionProvider->numPositions[objIdx]; + } + + ++positionProvider->durationCounters[objIdx]; + + postUpdatePositionIdx = positionProvider->currentPositionIdxs[objIdx]; + + objectMetadataBuffer->positions[objIdx] = positionProvider->positions[objIdx][postUpdatePositionIdx]; +} + +void IsmPositionProvider_getNextFrame( + IsmPositionProvider *positionProvider, + IVAS_REND_AudioObjectMetadataBuffer *objectMetadataBuffer ) +{ + uint32_t objIdx; + + objectMetadataBuffer->numObjects = positionProvider->numObjects; + + for ( objIdx = 0; objIdx < positionProvider->numObjects; ++objIdx ) + { + if ( positionProvider->ismReaders[objIdx] != NULL ) + { + getMetadataFromFileReader( positionProvider->ismReaders[objIdx], objectMetadataBuffer, objIdx ); + } + else + { + readFromShorthandMetadata( positionProvider, objectMetadataBuffer, objIdx ); + } + + /* Wrap azimuth to lie within (-180, 180] range */ + while ( objectMetadataBuffer->positions[objIdx].azimuth < 0.0f ) + { + objectMetadataBuffer->positions[objIdx].azimuth += 360.0f; + } + while ( objectMetadataBuffer->positions[objIdx].azimuth >= 360.0f ) + { + objectMetadataBuffer->positions[objIdx].azimuth -= 360.0f; + } + + /* Clamp elevation to lie within [-90, 90] range (can't be wrapped easily) */ + objectMetadataBuffer->positions[objIdx].elevation = min( max( objectMetadataBuffer->positions[objIdx].elevation, -90 ), 90 ); + } + + ++positionProvider->frameCounter; +} + +void IsmPositionProvider_close( IsmPositionProvider *positionProvider ) +{ + uint32_t i; + + if ( positionProvider == NULL ) + { + assert( !"Can't close IsmPositionProvider - pointer is NULL" ); + } + + for ( i = 0; i < RENDERER_MAX_ISM_INPUTS; ++i ) + { + if ( positionProvider->ismReaders[i] != NULL ) + { + IsmFileReader_close( &positionProvider->ismReaders[i] ); + } + + if ( positionProvider->positions[i] != NULL ) + { + count_free( positionProvider->positions[i] ); + } + + if ( positionProvider->positionDurations[i] != NULL ) + { + count_free( positionProvider->positionDurations[i] ); + } + } + + count_free( positionProvider ); +} + +static void splitConfigFile( const char *mdfFilePath, + char *metadataString, + uint32_t *metadataStringLength, + char *wavFileName, + uint32_t *wavFileNameLength ) +{ + FILE *file; + uint32_t bufferlength; + char wavLine[FILENAME_MAX]; + uint32_t currentPositionIdxs; + uint32_t mdlength; + + memset( metadataString, 0, *metadataStringLength ); + memset( wavFileName, 0, (int16_t) *wavFileNameLength ); + + file = fopen( mdfFilePath, "rb" ); + if ( !file ) + { + fprintf( stderr, "Couldn't open metadata file %s\n", mdfFilePath ); + exit( -1 ); + } + + fseek( file, 0, SEEK_END ); + bufferlength = ftell( file ); + fseek( file, 0, SEEK_SET ); + + if ( fgets( wavLine, (int) *wavFileNameLength, file ) == NULL ) + { + fprintf( stderr, "Error reading metadata\n" ); + exit( -1 ); + } + currentPositionIdxs = ftell( file ); + if ( *wavFileNameLength < currentPositionIdxs ) + { + assert( !"Couldn't read wavFileName, string buffer too small" ); + } + if ( !sscanf( wavLine, "%s", wavFileName ) ) + { + fprintf( stderr, "Error reading metadata\n" ); + exit( -1 ); + } + *wavFileNameLength = strlen( wavFileName ); + + mdlength = bufferlength - currentPositionIdxs; + /* "+1" for null termination */ + if ( *metadataStringLength + 1 < mdlength ) + { + assert( !"Couldn't read metadata string, string buffer too small" ); + } + + fread( metadataString, 1, mdlength, file ); + metadataString[mdlength] = '\0'; + *metadataStringLength = mdlength + 1; + + fclose( file ); +} + +/* r: pointer to character following last found delimiter */ +static char *readNextMetadataChunkFrom( char *start_char, char *line, const char *delimiter ) +{ + char *token; + + /* start_char can be NULL - it's used to continue parsing with strtok */ + assert( line != NULL && delimiter != NULL && "unexpected NULL ptr given to readNextMetadataChunkFrom()" ); + + token = strtok( start_char, delimiter ); + + /* End of string reached */ + if ( token == NULL ) + { + /* Clear `line` from previous contents and return NULL */ + line[0] = '\0'; + return NULL; + } + + strcpy( line, token ); + + return token + strlen( token ) + 1; +} + +/* r: pointer to character following last found delimiter */ +static char *readNextMetadataChunk( char *line, const char *delimiter ) +{ + return readNextMetadataChunkFrom( NULL, line, delimiter ); +} + +static void parseUint8( const char *line, uint8_t *ret ) +{ + char *ptr; + ptr = NULL; + + *ret = (uint8_t) strtol( line, &ptr, 10 ); + if ( ptr == NULL || *ptr != '\0' ) + { + fprintf( stderr, "Cannot parse string \"%s\" as an integer value\n", line ); + exit( -1 ); + } +} + +static void parseUint16( const char *line, uint16_t *ret ) +{ + char *ptr; + ptr = NULL; + + *ret = (uint16_t) strtol( line, &ptr, 10 ); + if ( ptr == NULL || *ptr != '\0' ) + { + fprintf( stderr, "Cannot parse string \"%s\" as an integer value\n", line ); + exit( -1 ); + } +} + +static int8_t parseUint32( const char *line, uint32_t *ret ) +{ + char *ptr; + ptr = NULL; + + *ret = strtol( line, &ptr, 10 ); + if ( ptr == NULL || *ptr != '\0' ) + { + return -1; + } + + return 0; +} + +static void parseOptionalInputValues( + char *line, + float *gain_dB ) +{ + char *parse_pos; + char *key; + char *value; + char *endptr; + + endptr = NULL; + + /* Set default values, in case some values are not specified */ + *gain_dB = 0.f; + + /* Save parsing position - will have to be passed to strtok to resume parsing after using strtok with non-NULL value below */ + parse_pos = readNextMetadataChunk( line, "\n" ); + + /* Look for optional metadata until end of string or next input identifier is found */ + while ( parse_pos != NULL && strcmp( line, "MC" ) != 0 && strcmp( line, "SBA" ) != 0 && strcmp( line, "ISM" ) != 0 ) + { + key = strtok( line, ":" ); + value = strtok( NULL, "\n" ); + + if ( strcmp( key, "gain_dB" ) == 0 ) + { + *gain_dB = (float) strtod( value, &endptr ); + + if ( *endptr != '\0' ) + { + fprintf( stderr, "Cannot parse string string \"%s\" as a float value\n", value ); + exit( -1 ); + } + } + else + { + fprintf( stderr, "Unsupported optional key: %s\n", key ); + exit( -1 ); + } + + parse_pos = readNextMetadataChunkFrom( parse_pos, line, "\n" ); + } +} + +static void parseObjectPosition( char *line, + IVAS_REND_AudioObjectPosition *position, + uint16_t *positionDuration ) +{ + char *endptr; + + readNextMetadataChunk( line, "," ); + *positionDuration = (uint16_t) strtol( line, &endptr, 10 ); + + if ( *endptr != '\0' ) + { + fprintf( stderr, "Error reading metadata\n" ); + exit( -1 ); + } + + readNextMetadataChunk( line, "," ); + position->azimuth = strtof( line, &endptr ); + + if ( *endptr != '\0' ) + { + fprintf( stderr, "Error reading metadata\n" ); + exit( -1 ); + } + + readNextMetadataChunk( line, "\n" ); + position->elevation = strtof( line, &endptr ); + if ( *endptr != '\0' ) + { + fprintf( stderr, "Error reading metadata\n" ); + exit( -1 ); + } +} + +static void parseIsm( + char *line, + char *inDir, + IVAS_REND_InputConfig *inConfig, + IsmPositionProvider *positionProvider, + int32_t idx ) +{ + uint32_t numberOfObjectPositionsToRead; + uint32_t i; + + readNextMetadataChunk( line, "\n" ); + parseUint16( line, &inConfig->audioObjects[idx].inputChannelIndex ); + --inConfig->audioObjects[idx].inputChannelIndex; /* Convert from 1-indexing */ + + readNextMetadataChunk( line, "\n" ); + + /* Try to interpret line as number of positions to read */ + if ( parseUint32( line, &numberOfObjectPositionsToRead ) == 0 ) + { + positionProvider->numPositions[idx] = numberOfObjectPositionsToRead; + positionProvider->positions[idx] = count_calloc( numberOfObjectPositionsToRead, sizeof( IVAS_REND_AudioObjectPosition ) ); + positionProvider->positionDurations[idx] = count_calloc( numberOfObjectPositionsToRead, sizeof( uint16_t ) ); + + for ( i = 0; i < numberOfObjectPositionsToRead; ++i ) + { + parseObjectPosition( line, &positionProvider->positions[idx][i], &positionProvider->positionDurations[idx][i] ); + } + } + else /* If not a number, it is a relative path from main metadata file to a metadata file */ + { + char fullpath[FILENAME_MAX]; + *fullpath = '\0'; + strncat( fullpath, inDir, strlen( inDir ) ); + strncat( fullpath, line, sizeof( fullpath ) - strlen( fullpath ) - 1 ); + if ( ( positionProvider->ismReaders[idx] = IsmFileReader_open( fullpath ) ) == NULL ) + { + fprintf( stderr, "Error: ISM input metadata file %s could not be opened\n", line ); + exit( -1 ); + } + } + + /* Read optional values */ + parseOptionalInputValues( line, &inConfig->audioObjects[idx].gain_dB ); +} + +static void parseSba( char *line, + IVAS_REND_InputConfig *inConfig, + int32_t idx ) +{ + uint8_t ambiOrder; + + readNextMetadataChunk( line, "\n" ); + parseUint8( line, &inConfig->ambisonicsBuses[idx].inputChannelIndex ); + --inConfig->ambisonicsBuses[idx].inputChannelIndex; /* Convert from 1-indexing */ + + readNextMetadataChunk( line, "\n" ); + parseUint8( line, &ambiOrder ); + inConfig->ambisonicsBuses[idx].ambisonicsConfig = ambisonicsOrderToEnum( ambiOrder ); + + /* Read optional values */ + parseOptionalInputValues( line, &inConfig->ambisonicsBuses[idx].gain_dB ); +} + +static void parseMc( char *line, + IVAS_REND_InputConfig *inConfig, + int32_t idx ) +{ + AUDIO_CONFIG cfg; + + readNextMetadataChunk( line, "\n" ); + parseUint8( line, &inConfig->multiChannelBuses[idx].inputChannelIndex ); + --inConfig->multiChannelBuses[idx].inputChannelIndex; /* Convert from 1-indexing */ + + readNextMetadataChunk( line, "\n" ); + cfg = parseStrToAudioCfg( line ); + if ( cfg == AUDIO_CONFIG_LS_CUSTOM ) + { + parseCustomLayoutFile( line, &inConfig->inSetupCustom ); + } + else + { + inConfig->multiChannelBuses[idx].speakerLayout = audioCfgToMcEnum( cfg ); + } + + /* Read optional values */ + parseOptionalInputValues( line, &inConfig->multiChannelBuses[idx].gain_dB ); +} + +static void parseCustomLayoutFile( + char *filePath, + IVAS_LSSETUP_CUSTOM_HANDLE *hLsSetupCustom ) +{ + int16_t i, is_planar; + + LsCustomFileReader *hLsCustomReader = NULL; + IVAS_CUSTOM_LS_DATA hLsCustomData; + + IVAS_REND_OpenCustomLayout( hLsSetupCustom ); + CustomLsReader_open( filePath, &hLsCustomReader ); + if ( CustomLsFileReading( hLsCustomReader, &hLsCustomData ) != LS_CUSTOM_FILEREADER_NO_ERROR ) + { + fprintf( stderr, "Error while reading custom loudspeaker layout file\n" ); + exit( -1 ); + } + + ( *hLsSetupCustom )->num_spk = hLsCustomData.num_spk; + mvr2r( hLsCustomData.azimuth, ( *hLsSetupCustom )->ls_azimuth, hLsCustomData.num_spk ); + mvr2r( hLsCustomData.elevation, ( *hLsSetupCustom )->ls_elevation, hLsCustomData.num_spk ); + + /* Set planar flag */ + is_planar = 1; + for ( i = 0; i < hLsCustomData.num_spk; i++ ) + { + if ( is_planar && ( *hLsSetupCustom )->ls_elevation[i] != 0.0f ) + { + is_planar = 0; + } + } + ( *hLsSetupCustom )->is_planar_setup = is_planar; + + /* Loudspeaker LFE */ + ( *hLsSetupCustom )->num_lfe = hLsCustomData.num_lfe; + mvs2s( hLsCustomData.lfe_idx, ( *hLsSetupCustom )->lfe_idx, hLsCustomData.num_lfe ); + + CustomLsReader_close( &hLsCustomReader ); +} + +static void parseMetadata( + char *metadataString, + char *inDir, + IVAS_REND_InputConfig *inConfig, + IsmPositionProvider *positionProvider ) +{ + char line[RENDERER_MAX_METADATA_LINE_LENGTH]; + char *delimiter; + char *token; + uint8_t totalNumberOfAudioObjects; + uint8_t counterChannelAudioObjects; + uint8_t counterAmbisonicsAudioObjects; + uint8_t counterMonoAudioObjects; + uint8_t num_parsed_inputs; + + delimiter = "\n"; + + token = strtok( metadataString, delimiter ); + if ( token == NULL ) + { + fprintf( stderr, "Unexpected metadata format\n" ); + exit( -1 ); + } + if ( !sscanf( token, "%s", line ) ) + { + fprintf( stderr, "Unexpected metadata format\n" ); + exit( -1 ); + } + + parseUint8( line, &totalNumberOfAudioObjects ); + if ( totalNumberOfAudioObjects <= 0 ) + { + fprintf( stderr, "Invalid metadata: number of inputs should be > 0\n" ); + exit( -1 ); + } + + num_parsed_inputs = 0; + counterChannelAudioObjects = 0; + counterAmbisonicsAudioObjects = 0; + counterMonoAudioObjects = 0; + + readNextMetadataChunk( line, delimiter ); + + while ( num_parsed_inputs < totalNumberOfAudioObjects ) + { + /* `line` will already contain the identifier ("MC", "SBA" or "ISM") after previous iteration */ + if ( strcmp( line, "MC" ) == 0 ) + { + ++counterChannelAudioObjects; + if ( counterChannelAudioObjects > RENDERER_MAX_MC_INPUTS ) + { + fprintf( stderr, "Metadata exceeds the supported number of MC inputs\n" ); + exit( -1 ); + } + parseMc( line, inConfig, counterChannelAudioObjects - 1 ); + } + else if ( strcmp( line, "SBA" ) == 0 ) + { + ++counterAmbisonicsAudioObjects; + if ( counterAmbisonicsAudioObjects > RENDERER_MAX_SBA_INPUTS ) + { + fprintf( stderr, "Metadata exceeds the supported number of SBA inputs\n" ); + exit( -1 ); + } + parseSba( line, inConfig, counterAmbisonicsAudioObjects - 1 ); + } + else if ( strcmp( line, "ISM" ) == 0 ) + { + ++counterMonoAudioObjects; + if ( counterMonoAudioObjects > RENDERER_MAX_ISM_INPUTS ) + { + fprintf( stderr, "Metadata exceeds the supported number of ISM inputs\n" ); + exit( -1 ); + } + parseIsm( line, inDir, inConfig, positionProvider, counterMonoAudioObjects - 1 ); + } + else if ( line[0] == '\0' ) + { + fprintf( stderr, "Metadata string too short - expected %d inputs, found %d.\n", totalNumberOfAudioObjects, num_parsed_inputs ); + exit( -1 ); + } + else + { + fprintf( stderr, "Unexpected metadata identifier\n" ); + exit( -1 ); + } + + ++num_parsed_inputs; + } + + inConfig->numAudioObjects = counterMonoAudioObjects; + inConfig->numAmbisonicsBuses = counterAmbisonicsAudioObjects; + inConfig->numMultiChannelBuses = counterChannelAudioObjects; + positionProvider->numObjects = counterMonoAudioObjects; + + /* check for trailing text */ + token = strtok( NULL, delimiter ); + if ( token != NULL && sscanf( token, "%s", line ) ) + { + fprintf( stderr, "Trailing text in metadata file\n" ); + exit( -1 ); + } +} + +void parseConfigFile( char *path, char *audioFilePath, IVAS_REND_InputConfig *inConfig, IsmPositionProvider *positionProvider ) +{ + uint32_t inAudioFilePathLen; + char inAudioFilePath[FILENAME_MAX]; + uint32_t mtdStrLen; + char mtdStr[RENDERER_MAX_METADATA_LENGTH]; + char inDir[FILENAME_MAX]; + char *lastSlash = NULL; + + inAudioFilePathLen = FILENAME_MAX; + mtdStrLen = RENDERER_MAX_METADATA_LENGTH; + splitConfigFile( path, + mtdStr, + &mtdStrLen, + inAudioFilePath, + &inAudioFilePathLen ); + + remove_cr( mtdStr ); + convert_backslash( inAudioFilePath ); + + /* Trim config file path to get path to the dir containing it */ + lastSlash = strrchr( path, SEP_FOLDER ); + *inDir = '\0'; + if ( lastSlash != NULL ) + { + strncat( inDir, path, ( lastSlash - path + 1 ) ); + } + + /* Append audio file path (relative to config file location) + * to config file location path to get full absolute path */ + strcpy( audioFilePath, inDir ); + strncat( audioFilePath, inAudioFilePath, inAudioFilePathLen ); + + parseMetadata( mtdStr, inDir, inConfig, positionProvider ); +} + +static void convert_backslash( char *str ) +{ + int i, len; + + /* check that all backslashes are correct on the given platform */ + len = strlen( str ); + + for ( i = 0; i < len; i++ ) + { +#ifdef _WIN32 + if ( str[i] == '/' ) + { + str[i] = '\\'; + } +#else + if ( str[i] == '\\' ) + { + str[i] = '/'; + } +#endif + } + + return; +} + +static void remove_cr( char *str ) +{ + char *pos; + + /* remove all \r characters from the string */ + pos = strchr( str, '\r' ); + while ( pos != NULL ) + { + strcpy( pos, pos + 1 ); + pos = strchr( pos, '\r' ); + } + + return; +} diff --git a/ci/build_all_linux.sh b/ci/build_all_linux.sh index 65ea1461fa..6dcfd92ad9 100755 --- a/ci/build_all_linux.sh +++ b/ci/build_all_linux.sh @@ -9,8 +9,6 @@ fi make clean && make all -j # build unittests make unittests -j -# build prerenderer -make -C scripts/prerenderer -j # build standalone TD object renderer make -C scripts/td_object_renderer/object_renderer_standalone -j diff --git a/lib_com/ivas_cnst.h b/lib_com/ivas_cnst.h index fde64164c9..b9fb27f5e5 100644 --- a/lib_com/ivas_cnst.h +++ b/lib_com/ivas_cnst.h @@ -107,6 +107,11 @@ typedef enum AUDIO_CONFIG_ISM2, /* ISM2 */ AUDIO_CONFIG_ISM3, /* ISM3 */ AUDIO_CONFIG_ISM4, /* ISM4 */ +#ifdef EXT_RENDERER /* TODO tmu : temporary, or use something like IVAS_ENC input format */ + AUDIO_CONFIG_MASA1, /* MASA1 */ + AUDIO_CONFIG_MASA2, /* MASA2 */ + AUDIO_CONFIG_META, /* scene description */ +#endif AUDIO_CONFIG_EXTERNAL /* external renderer */ } AUDIO_CONFIG; @@ -1148,7 +1153,11 @@ typedef enum *----------------------------------------------------------------------------------*/ #define MC_LS_SETUP_BITS 3 /* number of bits for writing the MC LS configuration */ +#ifdef EXT_RENDERER +#define LS_SETUP_CONVERSION_NUM_MAPPINGS 37 /* number of mappings for LS setup conversion */ +#else #define LS_SETUP_CONVERSION_NUM_MAPPINGS 35 /* number of mappings for LS setup conversion */ +#endif typedef enum { diff --git a/lib_com/options.h b/lib_com/options.h index a51b60d748..f1d1978e09 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -156,7 +156,8 @@ #define FIX_I54_LS_CONVERSION /* FhG: fix incorrect downmix matrix for 5_1_4 to 5_1_2 and upmix matrix for 7_1 to 7_1_4 */ #define FIX_I25_FBE_FB_BITS /* issue 25: properly skip reading of TBE FB bits when decoder output sampling rate is not 48 kHz */ #define ORDER_BITS_ADDITION /* issue 14: Transmit SBA order and planar bits at all bitrates */ - +#define EXT_RENDERER /* FhG: external renderer library and standalone application */ +#define FIX_EFAP_MATH /* fix for EFAP: remove angle quantization and a bug in polygon lookup causing incorrect gains. minor tweak for ALLRAD. non-BE for modes using EFAP */ /* ################## End DEVELOPMENT switches ######################### */ /* clang-format on */ diff --git a/lib_dec/ivas_rom_dec.c b/lib_dec/ivas_rom_dec.c index baf77c1984..3a08c33e79 100644 --- a/lib_dec/ivas_rom_dec.c +++ b/lib_dec/ivas_rom_dec.c @@ -512,418 +512,11 @@ const int16_t sba_map_tc[8] = 0, 1, 2, 3, 4, 8, 9, 15 }; -/*----------------------------------------------------------------------------------* - * LS Renderer ROM tables - *----------------------------------------------------------------------------------*/ - - /* All matrices are stored with dimensions nchan_in x nchan_out */ - /* Downmix matrices */ -const float ls_conversion_cicpX_mono[12][1] = -{ - {1.00000000f}, - {1.00000000f}, - {0.70710677f}, - {0.70710677f}, - {0.79999995f}, - {0.79999995f}, - {0.79999995f}, - {0.79999995f}, - {0.849999964f}, - {0.849999964f}, - {0.849999964f}, - {0.849999964f} -}; - -const float ls_conversion_cicpX_stereo[12][2] = -{ - {1.00000000f, 0.00000000f}, - {0.00000000f, 1.00000000f}, - {0.70710677f, 0.70710677f}, - {0.70710677f, 0.70710677f}, - {0.79999995f, 0.00000000f}, - {0.00000000f, 0.79999995f}, - {0.79999995f, 0.00000000f}, - {0.00000000f, 0.79999995f}, - {0.849999964f, 0.000000000f}, - {0.000000000f, 0.849999964f}, - {0.849999964f, 0.000000000f}, - {0.000000000f, 0.849999964f} -}; - -const LS_CONVERSION_MATRIX ls_conversion_cicp12_cicp6[] = -{ - /* First row indicates the number of non-zero elements */ - {8, 0.0f}, - /* Index of non-zero element, value of non-zero element*/ - {0, 1.000000000f}, - {7, 1.000000000f}, - {14, 1.000000000f}, - {21, 1.000000000f}, - {28, 1.000000000f}, - {35, 1.000000000f}, - {40, 1.000000000f}, - {47, 1.000000000f} -}; - -const LS_CONVERSION_MATRIX ls_conversion_cicp14_cicp6[] = -{ - /* First row indicates the number of non-zero elements */ - {8, 0.0f}, - /* Index of non-zero element, value of non-zero element*/ - {0, 1.000000000f}, - {7, 1.000000000f}, - {14, 1.000000000f}, - {21, 1.000000000f}, - {28, 1.000000000f}, - {35, 1.000000000f}, - {36, 0.849999964f}, - {43, 0.849999964f} -}; - -#ifdef FIX_I54_LS_CONVERSION -const LS_CONVERSION_MATRIX ls_conversion_cicp14_cicp12[] = -{ - /* First row indicates the number of non-zero elements */ - {8, 0.0f}, - /* Index of non-zero element, value of non-zero element*/ - {0, 1.000000000f}, - {9, 1.000000000f}, - {18, 1.000000000f}, - {27, 1.000000000f}, - {36, 1.000000000f}, - {45, 1.000000000f}, - {48, 0.849999964f}, - {57, 0.849999964f} -}; -#endif - -const LS_CONVERSION_MATRIX ls_conversion_cicp16_cicp6[] = -{ - /* First row indicates the number of non-zero elements */ - {10, 0.0f}, - /* Index of non-zero element, value of non-zero element*/ - {0, 1.000000000f}, - {7, 1.000000000f}, - {14, 1.000000000f}, - {21, 1.000000000f}, - {28, 1.000000000f}, - {35, 1.000000000f}, - {36, 0.849999964f}, - {43, 0.849999964f}, - {52, 0.849999964f}, - {59, 0.849999964f} -}; - -const LS_CONVERSION_MATRIX ls_conversion_cicp16_cicp12[] = -{ - /* First row indicates the number of non-zero elements */ - {10, 0.0f}, - /* Index of non-zero element, value of non-zero element*/ - {0, 1.000000000f}, - {9, 1.000000000f}, - {18, 1.000000000f}, - {27, 1.000000000f}, - {36, 1.000000000f}, - {45, 1.000000000f}, - {48, 0.849999964f}, - {57, 0.849999964f}, - {68, 0.849999964f}, - {77, 0.849999964f} - -}; - -const LS_CONVERSION_MATRIX ls_conversion_cicp16_cicp14[] = -{ - /* First row indicates the number of non-zero elements */ - {10, 0.0f}, - /* Index of non-zero element, value of non-zero element*/ -#ifdef FIX_I54_LS_CONVERSION - {0, 1.000000000f}, - {9, 1.000000000f}, - {18, 1.000000000f}, - {27, 1.000000000f}, - {36, 1.000000000f}, - {45, 1.000000000f}, - {54, 1.000000000f}, - {63, 1.000000000f}, - {68, 0.849999964f}, - {77, 0.849999964f}, -#else - {0, 1.000000000f}, - {11, 1.000000000f}, - {22, 1.000000000f}, - {33, 1.000000000f}, - {44, 1.000000000f}, - {48, 0.849999964f}, - {55, 1.000000000f}, - {59, 0.849999964f}, - {66, 1.000000000f}, - {77, 1.000000000f}, -#endif -}; - -const LS_CONVERSION_MATRIX ls_conversion_cicp19_cicp6[] = -{ - /* First row indicates the number of non-zero elements */ - {14, 0.0f}, - /* Index of non-zero element, value of non-zero element*/ - {0, 1.000000000f}, - {7, 1.000000000f}, - {14, 1.000000000f}, - {21, 1.000000000f}, - {28, 1.000000000f}, - {35, 1.000000000f}, - {36, 0.367322683f}, - {40, 0.930093586f}, - {43, 0.367322683f}, - {47, 0.930093586f}, - {48, 0.849999964f}, - {55, 0.849999964f}, - {64, 0.849999964f}, - {71, 0.849999964f} -}; - -const LS_CONVERSION_MATRIX ls_conversion_cicp19_cicp12[] = -{ - /* First row indicates the number of non-zero elements */ - {14, 0.0f}, - /* Index of non-zero element, value of non-zero element*/ - {0, 1.000000000f}, - {9, 1.000000000f}, - {18, 1.000000000f}, - {27, 1.000000000f}, - {38, 1.000000000f}, - {47, 1.000000000f}, - {48, 0.367322683f}, - {52, 0.930093586f}, - {57, 0.367322683f}, - {61, 0.930093586f}, - {64, 0.849999964f}, - {73, 0.849999964f}, - {84, 0.849999964f}, - {93, 0.849999964f} -}; - -const LS_CONVERSION_MATRIX ls_conversion_cicp19_cicp14[] = -{ - /* First row indicates the number of non-zero elements */ - {14, 0.0f}, - /* Index of non-zero element, value of non-zero element*/ - {0, 1.000000000f}, - {9, 1.000000000f}, - {18, 1.000000000f}, - {27, 1.000000000f}, - {36, 1.000000000f}, - {45, 1.000000000f}, - {48, 0.367322683f}, - {52, 0.930093586f}, - {57, 0.367322683f}, - {61, 0.930093586f}, - {70, 1.000000000f}, - {79, 1.000000000f}, - {84, 0.849999964f}, - {93, 0.849999964f} -}; - -const LS_CONVERSION_MATRIX ls_conversion_cicp19_cicp16[] = -{ - /* First row indicates the number of non-zero elements */ - {14, 0.0f}, - /* Index of non-zero element, value of non-zero element*/ - {0, 1.000000000f}, - {11, 1.000000000f}, - {22, 1.000000000f}, - {33, 1.000000000f}, - {44, 1.000000000f}, - {55, 1.000000000f}, - {60, 0.367322683f}, - {64, 0.930093586f}, - {71, 0.367322683f}, - {75, 0.930093586f}, - {86, 1.000000000f}, - {97, 1.000000000f}, - {108, 1.000000000f}, - {119, 1.000000000f} -}; - -/* Upmix matrices */ -const LS_CONVERSION_MATRIX ls_conversion_cicp12_cicp14[] = -{ - /* First row indicates the number of non-zero elements */ - {8, 0.0f}, - /* Index of non-zero element, value of non-zero element*/ - {0, 1.0f}, - {9, 1.0f}, - {18, 1.0f}, - {27, 1.0f}, - {36, 1.0f}, - {45, 1.0f}, - {52, 1.0f}, - {61, 1.0f} -}; - -const LS_CONVERSION_MATRIX ls_conversion_cicp12_cicp16[] = -{ - /* First row indicates the number of non-zero elements */ - {8, 0.0f}, - /* Index of non-zero element, value of non-zero element*/ - {0, 1.0f}, - {11, 1.0f}, - {22, 1.0f}, - {33, 1.0f}, - {44, 1.0f}, - {55, 1.0f}, - {64, 1.0f}, - {75, 1.0f} -}; - -#ifdef FIX_I54_LS_CONVERSION -const LS_CONVERSION_MATRIX ls_conversion_cicp12_cicp19[] = -{ - /* First row indicates the number of non-zero elements */ - {8, 0.0f}, - /* Index of non-zero element, value of non-zero element*/ - {0, 1.0f}, - {13, 1.0f}, - {26, 1.0f}, - {39, 1.0f}, - {54, 1.0f}, - {67, 1.0f}, - {76, 1.0f}, - {89, 1.0f} -}; -#endif - -const LS_CONVERSION_MATRIX ls_conversion_cicp14_cicp19[] = -{ - /* First row indicates the number of non-zero elements */ - {8, 0.0f}, - /* Index of non-zero element, value of non-zero element*/ - {0, 1.0f}, - {13, 1.0f}, - {26, 1.0f}, - {39, 1.0f}, - {52, 1.0f}, - {65, 1.0f}, - {80, 1.0f}, - {93, 1.0f} -}; - -const LS_CONVERSION_MATRIX ls_conversion_cicp16_cicp19[] = -{ - /* First row indicates the number of non-zero elements */ - {10, 0.0f}, - /* Index of non-zero element, value of non-zero element*/ - {0, 1.0f}, - {13, 1.0f}, - {26, 1.0f}, - {39, 1.0f}, - {52, 1.0f}, - {65, 1.0f}, - {80, 1.0f}, - {93, 1.0f}, - {106, 1.0f}, - {119, 1.0f} -}; - -/* - * Mapping table of input config : output config with corresponding matrix - * NULL indicates a 1:1 mapping of existing input channels to output channels ( used for upmix ) - */ - -const LS_CONVERSION_MAPPING ls_conversion_mapping[LS_SETUP_CONVERSION_NUM_MAPPINGS] = -{ - /* Dowmix mappings - NULL is a special case for MONO / STEREO downmix */ - {AUDIO_CONFIG_5_1, AUDIO_CONFIG_MONO, NULL}, - {AUDIO_CONFIG_7_1, AUDIO_CONFIG_MONO, NULL}, - {AUDIO_CONFIG_5_1_2, AUDIO_CONFIG_MONO, NULL}, - {AUDIO_CONFIG_5_1_4, AUDIO_CONFIG_MONO, NULL}, - {AUDIO_CONFIG_7_1_4, AUDIO_CONFIG_MONO, NULL}, - - {AUDIO_CONFIG_5_1, AUDIO_CONFIG_STEREO, NULL}, - {AUDIO_CONFIG_7_1, AUDIO_CONFIG_STEREO, NULL}, - {AUDIO_CONFIG_5_1_2, AUDIO_CONFIG_STEREO, NULL}, - {AUDIO_CONFIG_5_1_4, AUDIO_CONFIG_STEREO, NULL}, - {AUDIO_CONFIG_7_1_4, AUDIO_CONFIG_STEREO, NULL}, - - {AUDIO_CONFIG_7_1, AUDIO_CONFIG_5_1, ls_conversion_cicp12_cicp6}, - - {AUDIO_CONFIG_5_1_2, AUDIO_CONFIG_5_1, ls_conversion_cicp14_cicp6}, -#ifdef FIX_I54_LS_CONVERSION - {AUDIO_CONFIG_5_1_2, AUDIO_CONFIG_7_1, ls_conversion_cicp14_cicp12}, -#else - {AUDIO_CONFIG_5_1_2, AUDIO_CONFIG_7_1, ls_conversion_cicp14_cicp6}, -#endif - - {AUDIO_CONFIG_5_1_4, AUDIO_CONFIG_5_1, ls_conversion_cicp16_cicp6}, - {AUDIO_CONFIG_5_1_4, AUDIO_CONFIG_7_1, ls_conversion_cicp16_cicp12}, - {AUDIO_CONFIG_5_1_4, AUDIO_CONFIG_5_1_2, ls_conversion_cicp16_cicp14}, - - {AUDIO_CONFIG_7_1_4, AUDIO_CONFIG_5_1, ls_conversion_cicp19_cicp6}, - {AUDIO_CONFIG_7_1_4, AUDIO_CONFIG_7_1, ls_conversion_cicp19_cicp12}, - {AUDIO_CONFIG_7_1_4, AUDIO_CONFIG_5_1_2, ls_conversion_cicp19_cicp14}, - {AUDIO_CONFIG_7_1_4, AUDIO_CONFIG_5_1_4, ls_conversion_cicp19_cicp16}, - - /* Upmix mappings - NULL implies a 1:1 upmix */ - {AUDIO_CONFIG_STEREO, AUDIO_CONFIG_5_1, NULL}, - {AUDIO_CONFIG_STEREO, AUDIO_CONFIG_7_1, NULL}, - {AUDIO_CONFIG_STEREO, AUDIO_CONFIG_5_1_2, NULL}, - {AUDIO_CONFIG_STEREO, AUDIO_CONFIG_5_1_4, NULL}, - {AUDIO_CONFIG_STEREO, AUDIO_CONFIG_7_1_4, NULL}, - - {AUDIO_CONFIG_5_1, AUDIO_CONFIG_7_1, NULL}, - {AUDIO_CONFIG_5_1, AUDIO_CONFIG_5_1_2, NULL}, - {AUDIO_CONFIG_5_1, AUDIO_CONFIG_5_1_4, NULL}, - {AUDIO_CONFIG_5_1, AUDIO_CONFIG_7_1_4, NULL}, - - {AUDIO_CONFIG_7_1, AUDIO_CONFIG_5_1_2, ls_conversion_cicp12_cicp14}, - {AUDIO_CONFIG_7_1, AUDIO_CONFIG_5_1_4, ls_conversion_cicp12_cicp16}, -#ifdef FIX_I54_LS_CONVERSION - {AUDIO_CONFIG_7_1, AUDIO_CONFIG_7_1_4, ls_conversion_cicp12_cicp19}, -#else - {AUDIO_CONFIG_7_1, AUDIO_CONFIG_7_1_4, NULL}, -#endif - - {AUDIO_CONFIG_5_1_2, AUDIO_CONFIG_5_1_4, NULL}, - {AUDIO_CONFIG_5_1_2, AUDIO_CONFIG_7_1_4, ls_conversion_cicp14_cicp19}, - - {AUDIO_CONFIG_5_1_4, AUDIO_CONFIG_7_1_4, ls_conversion_cicp16_cicp19}, -}; - /*----------------------------------------------------------------------------------* * FASTCONV and PARAMETRIC binaural renderer ROM tables *----------------------------------------------------------------------------------*/ -const float dmxmtx[BINAURAL_CHANNELS][11] = -{ - { 1.0f, 0.0f, 0.70709997f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f }, - { 0.0f, 1.0f, 0.70709997f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f }, -}; - -/* -* 0 = 30,0 -* 1 = -30,0 -* 2 = 0,0 -* 3 = 135,0 -* 4 = -135,0 -* 5 = 110,0 -* 6 = -110,0 -* 7 = 90,0 -* 8 = -90,0 -* 9 = 30,35 -* 10 = -30,35 -* 11 = 110,35 -* 12 = -110,35 -* 13 = 135, 35 -* 14 = -135, 35 -*/ -const int16_t channelIndex_CICP6[5] = { 0, 1, 2, 5, 6 }; -const int16_t channelIndex_CICP12[7] = { 0, 1, 2, 5, 6, 3, 4 }; -const int16_t channelIndex_CICP14[7] = { 0, 1, 2, 5, 6, 9, 10 }; -const int16_t channelIndex_CICP16[9] = { 0, 1, 2, 5, 6, 9, 10, 11, 12 }; -const int16_t channelIndex_CICP19[11] = { 0, 1, 2, 3, 4, 7, 8, 9, 10, 13, 14 }; - const float surCohEne[MASA_NUM_DEFINED_SUR_SPR_COH_ENE_BINS] = { 3.0903f, 2.0053f, 1.0860f, 0.8072f, 0.7079f @@ -959,261 +552,4 @@ const float diffuseFieldCoherenceDifferenceZ[BINAURAL_COHERENCE_DIFFERENCE_BINS] 0.048207f, 0.10796f, 0.11845f, 0.047886f, 0.035917f, 0.045196f, 0.018863f, 0.015547f, 0.014157f }; - -/*----------------------------------------------------------------------------------* - * TD ISm binaural renderer ROM tables - *----------------------------------------------------------------------------------*/ - - /* The maximum target times set to 100 msec. */ -const int16_t TDREND_SRC_REND_MaxTargetTimes[IVAS_NUM_SUPPORTED_FS] = -{ - 1600, 3200, 4800 /* Corresponds to 16kHz, 32kHz, 48kHz */ -}; - -/* The maximum lengths of the blocks internally in the effect. Corresponds to 6 msec. This means also that */ -/* if the length of the input block is just above 6 msec, the block will be divided into two 3 msec blocks. */ -const int16_t TDREND_SRC_REND_MaxBlockLengths[IVAS_NUM_SUPPORTED_FS] = -{ - 96, 192, 288 /* Corresponds to 16kHz, 32kHz, 48kHz */ -}; - -const int16_t TDREND_MaxITD[IVAS_NUM_SUPPORTED_FS] = -{ - 111, 222, 333 /* Corresponds to 16kHz, 32kHz, 48kHz */ -}; - -const float TDREND_MaxITD_Incr[IVAS_NUM_SUPPORTED_FS] = -{ - 0.0925f, 0.1850f, 0.2775f /* Corresponds to 16kHz, 32kHz, 48kHz, e.g. ( ( 2 * MaxITD ) / ( 0.05 * 48000 ) ) */ -}; - -const int16_t HRTF_MODEL_N_CPTS_VAR[HRTF_MODEL_N_SECTIONS] = -{ - 13, 12, 11 -}; - -const float SincTable[321] = -{ - 1.00000000f, 0.99957629f, 0.99830587f, 0.99619078f, 0.99323448f, 0.98944177f, 0.98481881f, 0.97937311f, - 0.97311350f, 0.96605012f, 0.95819441f, 0.94955907f, 0.94015803f, 0.93000645f, 0.91912066f, 0.90751815f, - 0.89521750f, 0.88223838f, 0.86860150f, 0.85432856f, 0.83944219f, 0.82396595f, 0.80792425f, 0.79134231f, - 0.77424608f, 0.75666226f, 0.73861817f, 0.72014174f, 0.70126144f, 0.68200624f, 0.66240553f, 0.64248906f, - 0.62228691f, 0.60182943f, 0.58114713f, 0.56027070f, 0.53923087f, 0.51805843f, 0.49678411f, 0.47543856f, - 0.45405225f, 0.43265547f, 0.41127824f, 0.38995024f, 0.36870081f, 0.34755883f, 0.32655271f, 0.30571035f, - 0.28505905f, 0.26462549f, 0.24443569f, 0.22451493f, 0.20488776f, 0.18557791f, 0.16660829f, 0.14800093f, - 0.12977695f, 0.11195656f, 0.09455895f, 0.07760236f, 0.06110400f, 0.04508003f, 0.02954554f, 0.01451456f, - 0.00000000f, -0.01398631f, -0.02743368f, -0.04033255f, -0.05267447f, -0.06445214f, -0.07565940f, -0.08629121f, - -0.09634367f, -0.10581400f, -0.11470052f, -0.12300268f, -0.13072098f, -0.13785702f, -0.14441345f, -0.15039394f, - -0.15580318f, -0.16064685f, -0.16493160f, -0.16866498f, -0.17185547f, -0.17451243f, -0.17664604f, -0.17826729f, - -0.17938796f, -0.18002054f, -0.18017822f, -0.17987486f, -0.17912493f, -0.17794347f, -0.17634608f, -0.17434883f, - -0.17196824f, -0.16922125f, -0.16612516f, -0.16269761f, -0.15895648f, -0.15491992f, -0.15060625f, -0.14603396f, - -0.14122162f, -0.13618787f, -0.13095139f, -0.12553081f, -0.11994473f, -0.11421163f, -0.10834984f, -0.10237755f, - -0.09631271f, -0.09017300f, -0.08397586f, -0.07773838f, -0.07147731f, -0.06520902f, -0.05894946f, -0.05271415f, - -0.04651815f, -0.04037601f, -0.03430179f, -0.02830902f, -0.02241063f, -0.01661904f, -0.01094605f, -0.00540284f, - -0.00000000f, 0.00525251f, 0.01034538f, 0.01526993f, 0.02001814f, 0.02458266f, 0.02895676f, 0.03313441f, - 0.03711021f, 0.04087943f, 0.04443799f, 0.04778246f, 0.05091003f, 0.05381856f, 0.05650650f, 0.05897292f, - 0.06121749f, 0.06324047f, 0.06504268f, 0.06662549f, 0.06799083f, 0.06914112f, 0.07007930f, 0.07080878f, - 0.07133343f, 0.07165755f, 0.07178588f, 0.07172352f, 0.07147595f, 0.07104902f, 0.07044886f, 0.06968193f, - 0.06875494f, 0.06767485f, 0.06644886f, 0.06508435f, 0.06358888f, 0.06197015f, 0.06023599f, 0.05839432f, - 0.05645314f, 0.05442051f, 0.05230450f, 0.05011320f, 0.04785466f, 0.04553692f, 0.04316793f, 0.04075558f, - 0.03830765f, 0.03583181f, 0.03333557f, 0.03082630f, 0.02831121f, 0.02579730f, 0.02329137f, 0.02080003f, - 0.01832963f, 0.01588629f, 0.01347589f, 0.01110403f, 0.00877607f, 0.00649705f, 0.00427175f, 0.00210467f, - 0.00000000f, -0.00203837f, -0.00400686f, -0.00590216f, -0.00772131f, -0.00946162f, -0.01112072f, -0.01269654f, - -0.01418731f, -0.01559156f, -0.01690810f, -0.01813605f, -0.01927478f, -0.02032396f, -0.02128352f, -0.02215366f, - -0.02293482f, -0.02362769f, -0.02423318f, -0.02475245f, -0.02518686f, -0.02553797f, -0.02580754f, -0.02599752f, - -0.02611000f, -0.02614728f, -0.02611175f, -0.02600597f, -0.02583262f, -0.02559449f, -0.02529446f, -0.02493550f, - -0.02452066f, -0.02405306f, -0.02353586f, -0.02297226f, -0.02236549f, -0.02171881f, -0.02103547f, -0.02031874f, - -0.01957185f, -0.01879802f, -0.01800043f, -0.01718225f, -0.01634655f, -0.01549638f, -0.01463471f, -0.01376443f, - -0.01288838f, -0.01200928f, -0.01112977f, -0.01025241f, -0.00937962f, -0.00851376f, -0.00765705f, -0.00681160f, - -0.00597942f, -0.00516238f, -0.00436225f, -0.00358068f, -0.00281917f, -0.00207914f, -0.00136185f, -0.00066846f, - -0.00000000f, 0.00064260f, 0.00125856f, 0.00184718f, 0.00240790f, 0.00294026f, 0.00344390f, 0.00391857f, - 0.00436413f, 0.00478051f, 0.00516776f, 0.00552600f, 0.00585544f, 0.00615637f, 0.00642915f, 0.00667420f, - 0.00689203f, 0.00708318f, 0.00724827f, 0.00738795f, 0.00750293f, 0.00759395f, 0.00766178f, 0.00770723f, - 0.00773114f, 0.00773435f, 0.00771774f, 0.00768218f, 0.00762857f, 0.00755779f, 0.00747075f, 0.00736831f, - 0.00725138f, 0.00712082f, 0.00697748f, 0.00682221f, 0.00665584f, 0.00647916f, 0.00629295f, 0.00609797f, - 0.00589494f, 0.00568458f, 0.00546754f, 0.00524448f, 0.00501600f, 0.00478270f, 0.00454511f, 0.00430377f, - 0.00405916f, 0.00381176f, 0.00356198f, 0.00331023f, 0.00305690f, 0.00280234f, 0.00254687f, 0.00229079f, - 0.00203440f, 0.00177795f, 0.00152168f, 0.00126584f, 0.00101062f, 0.00075625f, 0.00050289f, 0.00025075f, - 0.00000000f -}; - -const float orange53_left_avg_power[257] = /* 257 == IVAS_REVERB_FFT_SIZE_48K/2 + 1 */ -{ - 0.999231100f, 0.992580175f, 0.969233215f, 0.925614893f, 0.871408045f, 0.826101780f, 0.803222895f, 0.800087631f, 0.802672029f, - 0.801490188f, 0.796555817f, 0.790879488f, 0.784882724f, 0.777585745f, 0.769326210f, 0.761789441f, 0.756145239f, 0.752754092f, - 0.751703024f, 0.752594173f, 0.754317880f, 0.755515277f, 0.754378498f, 0.748860359f, 0.738919020f, 0.727488697f, 0.718792558f, - 0.714865267f, 0.713446736f, 0.711076498f, 0.706021905f, 0.697553098f, 0.684623063f, 0.667031527f, 0.647006035f, 0.627680719f, - 0.609939933f, 0.592472672f, 0.574803054f, 0.558499217f, 0.544599831f, 0.532128096f, 0.520152628f, 0.509682238f, 0.501904130f, - 0.496162385f, 0.491121918f, 0.486813396f, 0.483951330f, 0.482198298f, 0.480713189f, 0.479654074f, 0.479590476f, 0.479965866f, - 0.479589254f, 0.478181243f, 0.476334095f, 0.474199444f, 0.471616089f, 0.469089746f, 0.467486322f, 0.466943622f, 0.467153549f, - 0.468381166f, 0.470996737f, 0.474416614f, 0.477639019f, 0.480612457f, 0.483910263f, 0.487287015f, 0.489909321f, 0.491668850f, - 0.493155539f, 0.494319856f, 0.494512051f, 0.493615031f, 0.492155492f, 0.490116775f, 0.486886710f, 0.482303619f, 0.476902038f, - 0.470775038f, 0.463377595f, 0.454571068f, 0.445130944f, 0.435581058f, 0.425568998f, 0.414717495f, 0.403531373f, 0.392556936f, - 0.381436378f, 0.369506508f, 0.357099295f, 0.345049500f, 0.333368897f, 0.321326375f, 0.308959186f, 0.297232091f, 0.286592871f, - 0.276453108f, 0.266589880f, 0.257950366f, 0.251341701f, 0.246435612f, 0.242861211f, 0.241405189f, 0.242839754f, 0.246688128f, - 0.252115428f, 0.259297341f, 0.268399984f, 0.278481483f, 0.288520366f, 0.298599035f, 0.308846802f, 0.318350822f, 0.326248646f, - 0.332813978f, 0.338464528f, 0.342543274f, 0.344278336f, 0.344031811f, 0.342641503f, 0.339995682f, 0.335437506f, 0.329174429f, - 0.322237372f, 0.315035462f, 0.306967229f, 0.297821850f, 0.288482070f, 0.279766560f, 0.271234214f, 0.262228251f, 0.253214896f, - 0.245183259f, 0.237939596f, 0.230546176f, 0.223051578f, 0.216552779f, 0.211263061f, 0.206180066f, 0.200917527f, 0.196485907f, - 0.193453044f, 0.190857053f, 0.187853232f, 0.185171053f, 0.183685005f, 0.182665780f, 0.180928215f, 0.178784713f, 0.177342966f, - 0.176323384f, 0.174430951f, 0.171496049f, 0.168740034f, 0.166518897f, 0.163711995f, 0.159658119f, 0.155442193f, 0.152056932f, - 0.148795277f, 0.144545168f, 0.139905334f, 0.136263832f, 0.133493021f, 0.130194828f, 0.126240104f, 0.123071767f, 0.121281922f, - 0.119557180f, 0.117016964f, 0.114773229f, 0.114072219f, 0.114103459f, 0.113414355f, 0.112460621f, 0.112842396f, 0.114564091f, - 0.115944758f, 0.116569765f, 0.117913686f, 0.120910525f, 0.124211200f, 0.126575813f, 0.128826424f, 0.132578567f, 0.137430578f, - 0.141675219f, 0.144987956f, 0.148879051f, 0.154273912f, 0.159992099f, 0.164641231f, 0.168560207f, 0.173201621f, 0.178906262f, - 0.184429348f, 0.188756809f, 0.192309171f, 0.196154252f, 0.200732291f, 0.205381230f, 0.209404662f, 0.212832779f, 0.216197237f, - 0.220162451f, 0.225029215f, 0.230637416f, 0.236752108f, 0.243243530f, 0.249900997f, 0.256293535f, 0.261716694f, 0.265186161f, - 0.265652657f, 0.262010813f, 0.253508776f, 0.243198514f, 0.244490802f, 0.255167097f, 0.258825988f, 0.257396817f, 0.256197631f, - 0.256865948f, 0.258354962f, 0.259370565f, 0.259730458f, 0.259894609f, 0.260285556f, 0.260970831f, 0.261650831f, 0.262020200f, - 0.262095064f, 0.262225062f, 0.262741268f, 0.263585031f, 0.264350951f, 0.264654577f, 0.264539272f, 0.264409125f, 0.264633715f, - 0.265172601f, 0.265621960f, 0.265678704f, 0.265469313f, 0.265454412f, 0.265907466f, 0.266625792f, 0.267101586f, 0.266997635f, - 0.266522497f, 0.266185820f, 0.266298562f, 0.266692907f, 0.266907692f -}; - -const float orange53_right_avg_power[257] = -{ - 0.999231100f, 0.992580175f, 0.969233215f, 0.925614893f, 0.871408045f, 0.826101780f, 0.803222895f, 0.800087631f, 0.802672029f, - 0.801490188f, 0.796555817f, 0.790879488f, 0.784882724f, 0.777585745f, 0.769326210f, 0.761789441f, 0.756145239f, 0.752754092f, - 0.751703024f, 0.752594173f, 0.754317880f, 0.755515277f, 0.754378498f, 0.748860359f, 0.738919020f, 0.727488697f, 0.718792558f, - 0.714865267f, 0.713446736f, 0.711076498f, 0.706021905f, 0.697553098f, 0.684623063f, 0.667031527f, 0.647006035f, 0.627680719f, - 0.609939933f, 0.592472672f, 0.574803054f, 0.558499217f, 0.544599831f, 0.532128096f, 0.520152628f, 0.509682238f, 0.501904130f, - 0.496162385f, 0.491121918f, 0.486813396f, 0.483951330f, 0.482198298f, 0.480713189f, 0.479654074f, 0.479590476f, 0.479965866f, - 0.479589254f, 0.478181243f, 0.476334095f, 0.474199444f, 0.471616089f, 0.469089746f, 0.467486322f, 0.466943622f, 0.467153549f, - 0.468381166f, 0.470996737f, 0.474416614f, 0.477639019f, 0.480612457f, 0.483910263f, 0.487287015f, 0.489909321f, 0.491668850f, - 0.493155539f, 0.494319856f, 0.494512051f, 0.493615031f, 0.492155492f, 0.490116775f, 0.486886710f, 0.482303619f, 0.476902038f, - 0.470775038f, 0.463377595f, 0.454571068f, 0.445130944f, 0.435581058f, 0.425568998f, 0.414717495f, 0.403531373f, 0.392556936f, - 0.381436378f, 0.369506508f, 0.357099295f, 0.345049500f, 0.333368897f, 0.321326375f, 0.308959186f, 0.297232091f, 0.286592871f, - 0.276453108f, 0.266589880f, 0.257950366f, 0.251341701f, 0.246435612f, 0.242861211f, 0.241405189f, 0.242839754f, 0.246688128f, - 0.252115428f, 0.259297341f, 0.268399984f, 0.278481483f, 0.288520366f, 0.298599035f, 0.308846802f, 0.318350822f, 0.326248646f, - 0.332813978f, 0.338464528f, 0.342543274f, 0.344278336f, 0.344031811f, 0.342641503f, 0.339995682f, 0.335437506f, 0.329174429f, - 0.322237372f, 0.315035462f, 0.306967229f, 0.297821850f, 0.288482070f, 0.279766560f, 0.271234214f, 0.262228251f, 0.253214896f, - 0.245183259f, 0.237939596f, 0.230546176f, 0.223051578f, 0.216552779f, 0.211263061f, 0.206180066f, 0.200917527f, 0.196485907f, - 0.193453044f, 0.190857053f, 0.187853232f, 0.185171053f, 0.183685005f, 0.182665780f, 0.180928215f, 0.178784713f, 0.177342966f, - 0.176323384f, 0.174430951f, 0.171496049f, 0.168740034f, 0.166518897f, 0.163711995f, 0.159658119f, 0.155442193f, 0.152056932f, - 0.148795277f, 0.144545168f, 0.139905334f, 0.136263832f, 0.133493021f, 0.130194828f, 0.126240104f, 0.123071767f, 0.121281922f, - 0.119557180f, 0.117016964f, 0.114773229f, 0.114072219f, 0.114103459f, 0.113414355f, 0.112460621f, 0.112842396f, 0.114564091f, - 0.115944758f, 0.116569765f, 0.117913686f, 0.120910525f, 0.124211200f, 0.126575813f, 0.128826424f, 0.132578567f, 0.137430578f, - 0.141675219f, 0.144987956f, 0.148879051f, 0.154273912f, 0.159992099f, 0.164641231f, 0.168560207f, 0.173201621f, 0.178906262f, - 0.184429348f, 0.188756809f, 0.192309171f, 0.196154252f, 0.200732291f, 0.205381230f, 0.209404662f, 0.212832779f, 0.216197237f, - 0.220162451f, 0.225029215f, 0.230637416f, 0.236752108f, 0.243243530f, 0.249900997f, 0.256293535f, 0.261716694f, 0.265186161f, - 0.265652657f, 0.262010813f, 0.253508776f, 0.243198514f, 0.244490802f, 0.255167097f, 0.258825988f, 0.257396817f, 0.256197631f, - 0.256865948f, 0.258354962f, 0.259370565f, 0.259730458f, 0.259894609f, 0.260285556f, 0.260970831f, 0.261650831f, 0.262020200f, - 0.262095064f, 0.262225062f, 0.262741268f, 0.263585031f, 0.264350951f, 0.264654577f, 0.264539272f, 0.264409125f, 0.264633715f, - 0.265172601f, 0.265621960f, 0.265678704f, 0.265469313f, 0.265454412f, 0.265907466f, 0.266625792f, 0.267101586f, 0.266997635f, - 0.266522497f, 0.266185820f, 0.266298562f, 0.266692907f, 0.266907692f -}; - -const float orange53_coherence[257] = -{ - 0.929530263f, 0.921171963f, 0.900268972f, 0.876067519f, 0.855227590f, 0.837884128f, 0.823401272f, 0.818804145f, 0.835025251f, - 0.871971071f, 0.911253273f, 0.929330528f, 0.921199203f, 0.900894165f, 0.882577479f, 0.867001534f, 0.849280477f, 0.832460761f, - 0.824062645f, 0.823441386f, 0.820908070f, 0.811902404f, 0.802339375f, 0.798648477f, 0.797345281f, 0.791158736f, 0.779512227f, - 0.768243194f, 0.760565042f, 0.754912853f, 0.751044095f, 0.752276063f, 0.759258866f, 0.766927004f, 0.769716740f, 0.767338514f, - 0.763358235f, 0.759508014f, 0.755201221f, 0.750362694f, 0.746060252f, 0.742611766f, 0.739434779f, 0.736354828f, 0.733443379f, - 0.730109870f, 0.726028502f, 0.722365141f, 0.720153689f, 0.718220115f, 0.714793265f, 0.710619092f, 0.708084404f, 0.707218647f, - 0.705624878f, 0.702472746f, 0.700073540f, 0.699947894f, 0.700519860f, 0.699934483f, 0.699344158f, 0.700895131f, 0.704551995f, - 0.708814025f, 0.713567019f, 0.719995975f, 0.728467822f, 0.738399088f, 0.749545693f, 0.761859894f, 0.774593413f, 0.787218869f, - 0.800481200f, 0.814727187f, 0.828367889f, 0.839860320f, 0.850490928f, 0.862034321f, 0.873037636f, 0.880097568f, 0.883217216f, - 0.885473788f, 0.887664974f, 0.886511028f, 0.880120754f, 0.871120989f, 0.862524390f, 0.853262126f, 0.840783834f, 0.825854301f, - 0.811407208f, 0.798167706f, 0.784307659f, 0.769172490f, 0.754072189f, 0.739893615f, 0.726129174f, 0.712544501f, 0.699519753f, - 0.686980069f, 0.674778104f, 0.663931608f, 0.655511260f, 0.648816824f, 0.642671287f, 0.638217211f, 0.637585819f, 0.640332758f, - 0.643755615f, 0.647433281f, 0.653589368f, 0.662824631f, 0.672268033f, 0.680022597f, 0.687623680f, 0.696763635f, 0.705829978f, - 0.712574661f, 0.717432320f, 0.721986175f, 0.725707173f, 0.727064371f, 0.726255059f, 0.724350274f, 0.720927835f, 0.715189219f, - 0.708206475f, 0.701428175f, 0.693923056f, 0.684313059f, 0.674107075f, 0.666009307f, 0.659245491f, 0.650998116f, 0.641600072f, - 0.634524226f, 0.630267978f, 0.625348687f, 0.618164837f, 0.611785769f, 0.608430445f, 0.605561733f, 0.600407422f, 0.594782710f, - 0.591767371f, 0.590365708f, 0.587845862f, 0.584915996f, 0.584355533f, 0.585834682f, 0.586913347f, 0.587935925f, 0.591403484f, - 0.596784472f, 0.601111054f, 0.604539037f, 0.610374093f, 0.618451059f, 0.624519289f, 0.627448440f, 0.631859899f, 0.639748096f, - 0.646256745f, 0.647378445f, 0.647664309f, 0.652599990f, 0.659044445f, 0.659743190f, 0.656243205f, 0.656651020f, 0.662200928f, - 0.664544880f, 0.660030127f, 0.656303048f, 0.659881413f, 0.664978266f, 0.662953973f, 0.657274961f, 0.658065319f, 0.665406108f, - 0.668446958f, 0.663809955f, 0.661349833f, 0.668595374f, 0.677367866f, 0.677208483f, 0.672289610f, 0.675831020f, 0.688208520f, - 0.695776582f, 0.691749871f, 0.687812865f, 0.696674168f, 0.711764693f, 0.716045380f, 0.706839681f, 0.701565385f, 0.711955190f, - 0.726487696f, 0.723370016f, 0.700417101f, 0.677427649f, 0.670733511f, 0.671355724f, 0.654210806f, 0.608316183f, 0.549225986f, - 0.504217446f, 0.484227657f, 0.475346446f, 0.452598959f, 0.399407327f, 0.319485664f, 0.229244962f, 0.146649837f, 0.083417825f, - 0.041744832f, 0.018142883f, 0.006854009f, 0.002511850f, 0.001177550f, 0.000840970f, 0.000701097f, 0.000571384f, 0.000458581f, - 0.000376965f, 0.000320562f, 0.000278847f, 0.000245546f, 0.000218281f, 0.000195632f, 0.000176647f, 0.000160827f, 0.000147978f, - 0.000137649f, 0.000129066f, 0.000121431f, 0.000114406f, 0.000108067f, 0.000102595f, 0.000097917f, 0.000093750f, 0.000089854f, - 0.000086255f, 0.000083183f, 0.000080804f, 0.000079026f, 0.000077552f, 0.000076117f, 0.000074693f, 0.000073431f, 0.000072456f, - 0.000071701f, 0.000071002f, 0.000070286f, 0.000069692f, 0.000069457f -}; - -/*----------------------------------------------------------------------------------* - * t-design and SN3D normalization table - *----------------------------------------------------------------------------------*/ - - /* SN3D norm */ -const float norm_sn3d_hoa3[16] = -{ - 1.f, 1.7320508f, 1.7320508f, 1.7320508f, 2.2360680f, 2.2360680f, 2.2360680f, 2.2360680f, - 2.2360680f, 2.6457512f, 2.6457512f, 2.6457512f, 2.6457512f, 2.6457512f, 2.6457512f, 2.6457512f -}; - -/* Order 11 t-design */ -const float t_design_11_azimuth[SBA_T_DESIGN_11_SIZE] = -{ - 1.329273e+02f, -8.393495e+01f, 8.474100e+00f, -1.133408e+02f, -1.032659e+02f, -3.323704e+01f, 2.185643e+01f, -1.565395e+02f, - -6.426475e+01f, 1.657795e+02f, -2.520283e+01f, -9.700380e+01f, 2.785464e+01f, 1.532142e+02f, -1.550616e+02f, -1.184214e+01f, - 8.053873e+01f, -4.205616e+01f, -3.122333e+01f, 3.883790e+01f, 9.376069e+01f, -8.475602e+01f, 7.755368e+00f, -1.222769e+02f, - 4.680127e+01f, -2.476863e+01f, 9.989047e+01f, -1.347840e+02f, -8.308802e+01f, 6.012817e+01f, 1.526447e+02f, 2.975767e+01f, - 4.077932e+01f, 1.101839e+02f, 1.656521e+02f, -1.299266e+01f, 7.973599e+01f, -5.052453e+01f, 1.189239e+02f, 4.722029e+01f, - 1.719253e+02f, -6.251458e+01f, -1.111567e+01f, 1.320180e+02f, -1.353555e+02f, 1.023709e+02f, 1.127393e+02f, -1.783050e+02f, - -1.223199e+02f, 5.907635e+01f, 1.517042e+02f, 2.137634e+01f, -1.690055e+02f, 1.189808e+02f, -1.160893e+02f, 9.647679e+00f, - 6.089332e+01f, -1.560215e+02f, -6.346030e+01f, 1.749298e+02f, -1.752888e+02f, -1.059519e+02f, -5.019283e+01f, 1.313583e+02f, - -1.362968e+02f, 9.356446e+01f, -9.708401e+01f, -1.691583e+02f, -4.413238e+01f, 8.147954e+01f -}; - -const float t_design_11_elevation[SBA_T_DESIGN_11_SIZE] = -{ - 7.692547e+00f, -2.373007e+01f, 2.351276e+01f, 7.042259e+01f, -9.896944e+00f, -7.075133e+01f, -2.646185e+01f, 4.777649e+01f, - -7.720470e+00f, 4.453436e+01f, 2.638979e+01f, -4.465789e+01f, 9.767035e+00f, -4.770533e+01f, 7.453029e+00f, -2.359012e+01f, - 2.371945e+01f, 7.043827e+01f, -9.835416e+00f, -7.049808e+01f, -2.629492e+01f, 4.761480e+01f, -7.517185e+00f, 4.428623e+01f, - 2.664426e+01f, -4.456937e+01f, 9.912719e+00f, -4.795996e+01f, 7.296799e+00f, -2.334460e+01f, 2.364153e+01f, 7.068431e+01f, - -9.581404e+00f, -7.039345e+01f, -2.642582e+01f, 4.775107e+01f, -7.308536e+00f, 4.426328e+01f, 2.671406e+01f, -4.431497e+01f, - 9.758997e+00f, -4.803619e+01f, 7.439651e+00f, -2.333261e+01f, 2.338690e+01f, 7.082191e+01f, -9.485964e+00f, -7.058019e+01f, - -2.667403e+01f, 4.799784e+01f, -7.382762e+00f, 4.449706e+01f, 2.650250e+01f, -4.424619e+01f, 9.518451e+00f, -4.782814e+01f, - 7.684274e+00f, -2.357068e+01f, 2.330745e+01f, 7.065865e+01f, -9.680889e+00f, -7.080268e+01f, -2.669635e+01f, 4.801363e+01f, - -7.637348e+00f, 4.466512e+01f, 2.630235e+01f, -4.445764e+01f, 9.523415e+00f, -4.762422e+01f -}; - - -/*----------------------------------------------------------------------* -* Reverberator ROM tables -*-----------------------------------------------------------------------*/ - -const float ivas_reverb_default_fc[IVAS_REVERB_DEFAULT_N_BANDS] = -{ - 20.0f, 25.0f, 31.5f, 40.0f, - 50.0f, 63.0f, 80.0f, 100.0f, - 125.0f, 160.0f, 200.0f, 250.0f, - 315.0f, 400.0f, 500.0f, 630.0f, - 800.0f, 1000.0f, 1250.0f, 1600.0f, - 2000.0f, 2500.0f, 3150.0f, 4000.0f, - 5000.0f, 6300.0f, 8000.0f, 10000.0f, - 12500.0f, 16000.0f, 20000.0f -}; - -const float ivas_reverb_default_RT60[IVAS_REVERB_DEFAULT_N_BANDS] = -{ - 1.3622f, 1.4486f, 1.3168f, 1.5787f, - 1.4766f, 1.3954f, 1.2889f, 1.3462f, - 1.0759f, 1.0401f, 1.097f, 1.085f, - 1.091f, 1.0404f, 1.0499f, 1.0699f, - 1.1028f, 1.1714f, 1.1027f, 1.0666f, - 1.055f, 1.0553f, 1.0521f, 1.0569f, - 1.0421f, 0.97822f, 0.80487f, 0.75944f, - 0.71945f, 0.61682f, 0.60031f -}; - -const float ivas_reverb_default_DSR[IVAS_REVERB_DEFAULT_N_BANDS] = -{ - 1.8811e-08f, 2.1428e-08f, 1.3972e-08f, 1.51e-08f, - 1.287e-08f, 1.8747e-08f, 2.413e-08f, 3.9927e-08f, - 8.9719e-08f, 1.902e-07f, 3.702e-07f, 6.1341e-07f, - 7.1432e-07f, 6.5331e-07f, 4.6094e-07f, 5.4683e-07f, - 7.0134e-07f, 6.856e-07f, 7.114e-07f, 6.9604e-07f, - 5.2939e-07f, 5.699e-07f, 6.1773e-07f, 5.7488e-07f, - 4.7748e-07f, 2.7213e-07f, 1.3681e-07f, 1.0941e-07f, - 6.2001e-08f, 2.8483e-08f, 2.6267e-08f -}; - - /* clang-format on */ diff --git a/lib_dec/ivas_rom_dec.h b/lib_dec/ivas_rom_dec.h index a92aad2533..7b0b3b4bad 100644 --- a/lib_dec/ivas_rom_dec.h +++ b/lib_dec/ivas_rom_dec.h @@ -118,7 +118,6 @@ extern const int16_t sba_map_tc[8]; extern const float ls_conversion_cicpX_mono[12][1]; extern const float ls_conversion_cicpX_stereo[12][2]; extern const LS_CONVERSION_MATRIX ls_conversion_cicp12_cicp6[]; -extern const LS_CONVERSION_MATRIX ls_conversion_cicp12_cicp6[]; extern const LS_CONVERSION_MATRIX ls_conversion_cicp14_cicp6[]; #ifdef FIX_I54_LS_CONVERSION extern const LS_CONVERSION_MATRIX ls_conversion_cicp14_cicp12[]; @@ -147,13 +146,6 @@ extern const LS_CONVERSION_MAPPING ls_conversion_mapping[]; * FASTCONV and PARAMETRIC binaural renderer ROM tables *----------------------------------------------------------------------------------*/ -extern const float dmxmtx[BINAURAL_CHANNELS][11]; -extern const int16_t channelIndex_CICP6[5]; -extern const int16_t channelIndex_CICP12[7]; -extern const int16_t channelIndex_CICP14[9]; -extern const int16_t channelIndex_CICP16[9]; -extern const int16_t channelIndex_CICP19[11]; - /* These are equalization values for spread and surround coherent sounds, approximating the spectrum * for such sounds at anechoic multichannel listening. */ extern const float surCohEne[MASA_NUM_DEFINED_SUR_SPR_COH_ENE_BINS]; @@ -168,44 +160,4 @@ extern const float diffuseFieldCoherenceDifferenceX[BINAURAL_COHERENCE_DIFFERENC extern const float diffuseFieldCoherenceDifferenceY[BINAURAL_COHERENCE_DIFFERENCE_BINS]; extern const float diffuseFieldCoherenceDifferenceZ[BINAURAL_COHERENCE_DIFFERENCE_BINS]; -/*----------------------------------------------------------------------------------* - * TD ISM Object renderer - *----------------------------------------------------------------------------------*/ - -extern const int16_t TDREND_SRC_REND_MaxTargetTimes[IVAS_NUM_SUPPORTED_FS]; -extern const int16_t TDREND_SRC_REND_MaxBlockLengths[IVAS_NUM_SUPPORTED_FS]; -extern const int16_t TDREND_MaxITD[IVAS_NUM_SUPPORTED_FS]; -extern const float TDREND_MaxITD_Incr[IVAS_NUM_SUPPORTED_FS]; - -extern const int16_t HRTF_MODEL_N_CPTS_VAR[HRTF_MODEL_N_SECTIONS]; - -extern const float SincTable[321]; - -extern const float orange53_left_avg_power[257]; -extern const float orange53_right_avg_power[257]; -extern const float orange53_coherence[257]; - - -/*----------------------------------------------------------------------------------* - * t-design and SN3D normalization table - *----------------------------------------------------------------------------------*/ - -/* SN3D norm */ -extern const float norm_sn3d_hoa3[16]; - -/* Order 11 t-design */ -extern const uint16_t t_design_11_size; -extern const float t_design_11_azimuth[SBA_T_DESIGN_11_SIZE]; -extern const float t_design_11_elevation[SBA_T_DESIGN_11_SIZE]; - - -/*----------------------------------------------------------------------* - * Reverberator ROM tables - *-----------------------------------------------------------------------*/ - -extern const float ivas_reverb_default_fc[]; -extern const float ivas_reverb_default_RT60[]; -extern const float ivas_reverb_default_DSR[]; - - #endif diff --git a/lib_dec/ivas_sba_dec.c b/lib_dec/ivas_sba_dec.c index 52ecc69e27..5e3efeccdb 100644 --- a/lib_dec/ivas_sba_dec.c +++ b/lib_dec/ivas_sba_dec.c @@ -38,409 +38,13 @@ #include "prot.h" #include "ivas_prot.h" #include "ivas_rom_dec.h" +#include #ifdef DEBUGGING #include "debug.h" #endif #include "wmops.h" -/*-----------------------------------------------------------------------* - * Local function prototypes - *-----------------------------------------------------------------------*/ - -static void ivas_sba_dmx_dec( float sba_data[][L_FRAME48k], const int16_t nchan_transport, const int16_t output_frame ); - -#ifdef DEBUG_MODE_DIRAC -static void debug_mode_dirac( float output[MAX_OUTPUT_CHANNELS][L_FRAME48k], const int16_t nchan_transport, const int16_t output_frame ); -#endif - - -/*-------------------------------------------------------------------------* - * ivas_mc2sba() - * - * MC signals transformed into SBA in TD domain - *-------------------------------------------------------------------------*/ - -void ivas_mc2sba( - IVAS_OUTPUT_SETUP hIntSetup, /* i : Format of decoder output */ - float buffer_td[][L_FRAME48k], /* i/o: MC signals (on input) and the HOA3 (on output) */ - const int16_t output_frame, /* i : output frame length per channel */ - const int16_t sba_order, /* i : Ambisonic (SBA) order */ - const float gain_lfe /* i : gain for LFE, 0 = ignore LFE */ -) -{ - int16_t i, j, k; - int16_t idx_lfe, idx_in; - float buffer_tmp[16][L_FRAME48k]; - float gains[16]; - int16_t azimuth, elevation; - int16_t sba_num_chans; - - assert( ( sba_order <= 3 ) && "Only order up to 3 is supported!" ); - - /* 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 ); - } - - /* HOA encoding*/ - idx_lfe = 0; - idx_in = 0; - for ( i = 0; i < hIntSetup.nchan_out_woLFE + hIntSetup.num_lfe; i++ ) - { - if ( ( hIntSetup.num_lfe > 0 ) && ( i == hIntSetup.index_lfe[idx_lfe] ) ) - { - if ( gain_lfe > 0.f ) - { - /* Add LFE to omni W with gain*/ - for ( k = 0; k < output_frame; k++ ) - { - buffer_tmp[0][k] += gain_lfe * buffer_td[i][k]; - } - } - - if ( idx_lfe < ( hIntSetup.num_lfe - 1 ) ) - { - idx_lfe++; - } - } - else - { - azimuth = (int16_t) ( hIntSetup.ls_azimuth[idx_in] ); - elevation = (int16_t) ( hIntSetup.ls_elevation[idx_in] ); - idx_in++; - - /* get HOA response for direction (ACN/SN3D)*/ - ivas_dirac_dec_get_response( - azimuth, - elevation, - gains, - sba_order ); - - for ( j = 0; j < sba_num_chans; j++ ) - { - for ( k = 0; k < output_frame; k++ ) - { - buffer_tmp[j][k] += gains[j] * buffer_td[i][k]; - } - } - } - } - - for ( j = 0; j < sba_num_chans; j++ ) - { - mvr2r( buffer_tmp[j], buffer_td[j], output_frame ); - } - - return; -} - - -/*-------------------------------------------------------------------------* - * ivas_sba2MC_cldfb() - * - * SBA signals transformed into MC in CLDFB domain - *-------------------------------------------------------------------------*/ - -void ivas_sba2mc_cldfb( - IVAS_OUTPUT_SETUP hInSetup, /* i : Format of input layout */ - float RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i/o: cldfb real part */ - float ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i/o: cldfb imag part */ - const int16_t nb_channels_out, /* i : nb of output channels */ - const int16_t nb_bands, /* i : nb of CLDFB bands to process */ - const float *hoa_dec_mtx /* i : HOA decoding mtx */ -) -{ - int16_t iBlock, iBand, n, m; - float realOut[16][MAX_PARAM_SPATIAL_SUBFRAMES * CLDFB_NO_CHANNELS_MAX], imagOut[16][MAX_PARAM_SPATIAL_SUBFRAMES * CLDFB_NO_CHANNELS_MAX]; - float g; - float *p_real, *p_imag, *p_realOut, *p_imagOut; - int16_t nb_channels_in; - - wmops_sub_start( "ivas_sba2mc_cldfb" ); - - nb_channels_in = hInSetup.nchan_out_woLFE; - assert( ( nb_channels_in == 16 ) && ( nb_channels_out == 11 ) && "ivas_sba2mc_cldfb; only HOA3 to CICP19 is for now supported!" ); - - for ( n = 0; n < nb_channels_out; n++ ) - { - set_zero( realOut[n], MAX_PARAM_SPATIAL_SUBFRAMES * nb_bands ); - set_zero( imagOut[n], MAX_PARAM_SPATIAL_SUBFRAMES * nb_bands ); - - for ( m = 0; m < nb_channels_in; m++ ) - { - g = hoa_dec_mtx[SBA_NHARM_HOA3 * n + m]; - p_realOut = realOut[n]; - p_imagOut = imagOut[n]; - for ( iBlock = 0; iBlock < MAX_PARAM_SPATIAL_SUBFRAMES; iBlock++ ) - { - p_real = RealBuffer[m][iBlock]; - p_imag = ImagBuffer[m][iBlock]; - for ( iBand = 0; iBand < nb_bands; iBand++ ) - { - *p_realOut = *p_realOut + g * *( p_real++ ); - *p_imagOut = *p_imagOut + g * *( p_imag++ ); - p_realOut++; - p_imagOut++; - } - } - } - } - - for ( n = 0; n < nb_channels_out; n++ ) - { - p_realOut = realOut[n]; - p_imagOut = imagOut[n]; - for ( iBlock = 0; iBlock < MAX_PARAM_SPATIAL_SUBFRAMES; iBlock++ ) - { - p_real = RealBuffer[n][iBlock]; - p_imag = ImagBuffer[n][iBlock]; - for ( iBand = 0; iBand < nb_bands; iBand++ ) - { - *( p_real++ ) = *p_realOut++; - *( p_imag++ ) = *p_imagOut++; - } - } - } - - wmops_sub_end(); - - return; -} - -/*-------------------------------------------------------------------* - * ivas_sba_remapTCs() - * - * Get TCs from Ambisonics signal in ACN - *-------------------------------------------------------------------*/ - -int16_t ivas_sba_remapTCs( - float sba_data[][L_FRAME48k], /* i/o: SBA signals */ - Decoder_Struct *st_ivas, /* i/o: decoder struct */ - const int16_t output_frame /* i : frame length */ -) -{ - 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 ( ( st_ivas->sba_mode != SBA_MODE_SPAR && st_ivas->sba_planar && nchan_remapped >= 3 ) || - ( ( st_ivas->sba_mode == SBA_MODE_SPAR ) && nchan_remapped == 3 ) ) - { - - nchan_remapped++; - if ( st_ivas->sba_mode != SBA_MODE_SPAR ) - { - assert( ( ( st_ivas->nchan_transport == 3 ) || ( st_ivas->nchan_transport == 5 ) || ( st_ivas->nchan_transport == 7 ) ) && "Number of channels must be odd for SBA planar!" ); - } - - if ( nchan_remapped == 4 ) - { - /*For planar A-format channel 2 and 3 are identical -> Z=0*/ - mvr2r( sba_data[2], sba_data[3], output_frame ); - } - } - - if ( st_ivas->sba_mode == SBA_MODE_SPAR ) - { - int16_t i = 0; - float temp; - - if ( st_ivas->nchan_transport >= 3 ) - { - /*convert WYXZ downmix to WYZX*/ - for ( i = 0; i < output_frame; i++ ) - { - temp = sba_data[2][i]; - sba_data[2][i] = sba_data[3][i]; - sba_data[3][i] = temp; - if ( st_ivas->nchan_transport == 3 ) - { - sba_data[2][i] = 0; - } - } - } - } - else - { - ivas_sba_dmx_dec( sba_data, nchan_remapped, output_frame ); - } - - if ( st_ivas->sba_mode != SBA_MODE_SPAR ) - { - ivas_sba_zero_vert_comp( sba_data, st_ivas->sba_order, st_ivas->sba_planar, output_frame ); - } - - return ( nchan_remapped ); -} - - -/*-------------------------------------------------------------------* - * ivas_sba_dmx_dec() - * - * - *-------------------------------------------------------------------*/ - -static void ivas_sba_dmx_dec( - float sba_data[][L_FRAME48k], /* i : SBA signals */ - const int16_t nchan_transport, /* i : number of transport channels */ - const int16_t output_frame /* i : frame length */ -) -{ - int16_t i; - float tmp_f[DIRAC_MAX_TRANS_CHANS]; - - if ( nchan_transport >= 7 ) - { - for ( i = 0; i < output_frame; i++ ) - { - tmp_f[0] = 0.506415f * sba_data[0][i] + 0.506415f * sba_data[1][i] + 0.506415f * sba_data[2][i] + 0.506415f * sba_data[3][i] + 0.506415f * sba_data[4][i] + 0.506415f * sba_data[5][i] + 0.506415f * sba_data[6][i]; - tmp_f[1] = -0.000000f * sba_data[0][i] + 0.531020f * sba_data[1][i] + 0.662171f * sba_data[2][i] + 0.294694f * sba_data[3][i] + -0.294694f * sba_data[4][i] + -0.662171f * sba_data[5][i] + -0.531020f * sba_data[6][i]; - tmp_f[2] = 0.679200f * sba_data[0][i] + 0.423475f * sba_data[1][i] + -0.151136f * sba_data[2][i] + -0.611938f * sba_data[3][i] + -0.611938f * sba_data[4][i] + -0.151136f * sba_data[5][i] + 0.423475f * sba_data[6][i]; - tmp_f[3] = 0.000000f * sba_data[0][i] + 0.833385f * sba_data[1][i] + -0.370891f * sba_data[2][i] + -0.668323f * sba_data[3][i] + 0.668323f * sba_data[4][i] + 0.370891f * sba_data[5][i] + -0.833385f * sba_data[6][i]; - tmp_f[4] = 0.854817f * sba_data[0][i] + -0.190215f * sba_data[1][i] + -0.770164f * sba_data[2][i] + 0.532970f * sba_data[3][i] + 0.532970f * sba_data[4][i] + -0.770164f * sba_data[5][i] + -0.190215f * sba_data[6][i]; - tmp_f[5] = 0.000000f * sba_data[0][i] + 0.691125f * sba_data[1][i] + -1.245365f * sba_data[2][i] + 1.552944f * sba_data[3][i] + -1.552944f * sba_data[4][i] + 1.245365f * sba_data[5][i] + -0.691125f * sba_data[6][i]; - tmp_f[6] = 1.592881f * sba_data[0][i] + -1.435137f * sba_data[1][i] + 0.993145f * sba_data[2][i] + -0.354449f * sba_data[3][i] + -0.354449f * sba_data[4][i] + 0.993145f * sba_data[5][i] + -1.435137f * sba_data[6][i]; - - sba_data[0][i] = tmp_f[0]; - sba_data[1][i] = tmp_f[1]; - sba_data[2][i] = sba_data[7][i]; - sba_data[3][i] = tmp_f[2]; - sba_data[4][i] = tmp_f[3]; - sba_data[8][i] = tmp_f[4]; - sba_data[9][i] = tmp_f[5]; - sba_data[15][i] = tmp_f[6]; - } - - return; - } - else if ( nchan_transport >= 5 ) - { - for ( i = 0; i < output_frame; i++ ) - { - tmp_f[0] = 0.708982f * sba_data[0][i] + 0.708982f * sba_data[1][i] + 0.708982f * sba_data[2][i] + 0.708982f * sba_data[3][i] + 0.708982f * sba_data[4][i]; - tmp_f[1] = 0.000000f * sba_data[0][i] + 1.005966f * sba_data[1][i] + 0.621721f * sba_data[2][i] + -0.621721f * sba_data[3][i] + -1.005966f * sba_data[4][i]; - tmp_f[2] = 1.057735f * sba_data[0][i] + 0.326858f * sba_data[1][i] + -0.855726f * sba_data[2][i] + -0.855726f * sba_data[3][i] + 0.326858f * sba_data[4][i]; - tmp_f[3] = 0.000000f * sba_data[0][i] + 1.079884f * sba_data[1][i] + -1.747289f * sba_data[2][i] + 1.747289f * sba_data[3][i] + -1.079884f * sba_data[4][i]; - tmp_f[4] = 1.837208f * sba_data[0][i] + -1.486333f * sba_data[1][i] + 0.567729f * sba_data[2][i] + 0.567729f * sba_data[3][i] + -1.486333f * sba_data[4][i]; - - sba_data[0][i] = tmp_f[0]; - sba_data[1][i] = tmp_f[1]; - sba_data[2][i] = sba_data[5][i]; - sba_data[3][i] = tmp_f[2]; - sba_data[4][i] = tmp_f[3]; - sba_data[8][i] = tmp_f[4]; - } - - return; - } - else if ( nchan_transport >= 3 ) - { - - /*A-format to ACN/SN3D*/ - for ( i = 0; i < output_frame; i++ ) - { - tmp_f[0] = 0.5f * ( sba_data[0][i] + sba_data[1][i] + sba_data[2][i] + sba_data[3][i] ); - tmp_f[1] = sba_data[0][i] - sba_data[1][i]; - tmp_f[2] = sba_data[2][i] - sba_data[3][i]; - tmp_f[3] = sba_data[0][i] + sba_data[1][i] - sba_data[2][i] - sba_data[3][i]; - - sba_data[0][i] = tmp_f[0]; - sba_data[1][i] = tmp_f[1]; - sba_data[2][i] = tmp_f[2]; - sba_data[3][i] = tmp_f[3]; - } - - return; - } - else if ( nchan_transport == 2 ) - { - /* do nothing for stereo DMX, upmix done in DirAC*/ - return; - } - else if ( nchan_transport == 1 ) - { - /* do nothing; simply use omni */ - return; - } - else - { - assert( 0 && "SBA: number of transport channels not supported." ); - } -} - - -/*-------------------------------------------------------------------------* - * ivas_ism2sba() - * - * ISM transformed into SBA in TD domain. - *-------------------------------------------------------------------------*/ - -void ivas_ism2sba( - float buffer_td[][L_FRAME48k], /* i/o: TD signal buffers */ - ISM_RENDERER_HANDLE hIsmRendererData, /* i/o: renderer data */ - const ISM_METADATA_HANDLE hIsmMetaData[], /* i : object metadata */ - const int16_t num_objects, /* 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 < num_objects; i++ ) - { - azimuth = (int16_t) ( hIsmMetaData[i]->azimuth + 0.5f ); - elevation = (int16_t) ( 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++ ) - { - g2 = 0.f; - for ( k = 0; k < output_frame; k++ ) - { - g2 += 1.f / output_frame; - g1 = 1.0f - g2; - buffer_tmp[j][k] += ( g2 * gains[j] + g1 * hIsmRendererData->prev_gains[i][j] ) * buffer_td[i][k]; - } - 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; -} - - /*-------------------------------------------------------------------* * ivas_sba_dec_decoder() * @@ -935,6 +539,336 @@ ivas_error ivas_sba_dec_reconfigure( return error; } +/*-------------------------------------------------------------------* + * ivas_sba_upmixer_renderer() + * + * SBA upmix rendering + *-------------------------------------------------------------------*/ + +void ivas_sba_upmixer_renderer( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder struct */ + float output[][L_FRAME48k], /* i/o: transport/output audio channels */ + const int16_t nchan_remapped, /* i : num channels after remapping of TCs */ + const int16_t output_frame /* i : output frame length */ +) +{ + int16_t i, ch, nchan_out; +#ifdef SIMPLIFY_SBA_RENDERING_LOGIC + float temp; +#else + float clip, temp; +#endif + int16_t nchan_internal; + + wmops_sub_start( "ivas_sba_upmixer_renderer" ); + + nchan_internal = ivas_sba_get_nchan_metadata( st_ivas->sba_order ); + nchan_out = st_ivas->hDecoderConfig->nchan_out; + + for ( ch = 0; ch < nchan_remapped; ch++ ) + { + for ( i = 0; i < output_frame; i++ ) + { + temp = output[ch][i]; + temp = floorf( temp + 0.5f ); + + if ( temp > MAX16B_FLT ) + { + temp = MAX16B_FLT; + } + else if ( temp < ( -1.0f * PCM16_TO_FLT_FAC ) ) + { + temp = ( -1.0f * PCM16_TO_FLT_FAC ); + } + temp *= ( 1.0f / PCM16_TO_FLT_FAC ); + output[ch][i] = temp; + } + } + + if ( st_ivas->nchan_transport >= 3 ) + { + /*convert WYZX downmix to WYXZ*/ + for ( i = 0; i < output_frame; i++ ) + { + temp = output[2][i]; + output[2][i] = output[3][i]; + output[3][i] = temp; + } + } + +#ifdef SIMPLIFY_SBA_RENDERING_LOGIC + /* Upmixer + Renderer */ +#else + /* Upmixer */ +#endif + ivas_spar_dec_upmixer( st_ivas, output, nchan_internal, output_frame ); + +#ifndef SIMPLIFY_SBA_RENDERING_LOGIC + /* Renderer */ + if ( st_ivas->hDirAC != NULL && st_ivas->renderer_type == RENDERER_DIRAC ) + { + nchan_out = st_ivas->hDirAC->hOutSetup.nchan_out_woLFE + st_ivas->hDirAC->hOutSetup.num_lfe; + } +#endif + if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_DEC ) + { + ivas_sba_linear_renderer( output, output_frame, st_ivas->hIntSetup.nchan_out_woLFE, st_ivas->hDecoderConfig->output_config, st_ivas->hOutSetup, st_ivas->hoa_dec_mtx ); + } + +#ifndef SIMPLIFY_SBA_RENDERING_LOGIC + clip = 1.0f; +#endif + for ( ch = 0; ch < nchan_out; ch++ ) + { + for ( i = 0; i < output_frame; i++ ) + { +#ifndef SIMPLIFY_SBA_RENDERING_LOGIC + clip = max( clip, fabsf( output[ch][i] ) ); +#endif + output[ch][i] = output[ch][i] * PCM16_TO_FLT_FAC; + } + } + +#ifndef SIMPLIFY_SBA_RENDERING_LOGIC +#ifdef DEBUGGING + if ( clip > 1.0f ) + { + fprintf( stderr, "IVAS Crend Clipped: max gain = %f\n", clip ); + } +#endif +#endif + + wmops_sub_end(); + + return; +} + + + +/*-------------------------------------------------------------------* + * ivas_sba_mix_matrix_determiner() + * + * Determine SBA mixing matrices + *-------------------------------------------------------------------*/ + +void ivas_sba_mix_matrix_determiner( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder struct */ + float output[][L_FRAME48k], /* i/o: transport/output audio channels */ + const int16_t nchan_remapped, /* i : num channels after remapping of TCs */ + const int16_t output_frame /* i : output frame length */ +) +{ + int16_t i, ch; + float temp; + SPAR_DEC_HANDLE pState; + int16_t num_bands_out, nchan_transport, nchan_out; + + /* Convert numeric range */ + for ( ch = 0; ch < nchan_remapped; ch++ ) + { + for ( i = 0; i < output_frame; i++ ) + { + temp = output[ch][i]; + temp = floorf( temp + 0.5f ); + + if ( temp > MAX16B_FLT ) + { + temp = MAX16B_FLT; + } + else if ( temp < ( -1.0f * PCM16_TO_FLT_FAC ) ) + { + temp = ( -1.0f * PCM16_TO_FLT_FAC ); + } + temp *= ( 1.0f / PCM16_TO_FLT_FAC ); + output[ch][i] = temp; + } + } + + /* AGC */ + pState = st_ivas->hSpar; + nchan_transport = pState->hMdDec->spar_md_cfg.nchan_transport; + nchan_out = nchan_transport; + ivas_agc_dec_process( pState->hAgcDec, output, output, nchan_transport, output_frame ); + + /* Convert numeric range back */ + for ( ch = 0; ch < nchan_out; ch++ ) + { + for ( i = 0; i < output_frame; i++ ) + { + output[ch][i] = output[ch][i] * PCM16_TO_FLT_FAC; + } + } + + /* Mixing matrix determiner */ + num_bands_out = pState->hFbMixer->pFb->filterbank_num_bands; + ivas_spar_dec_gen_umx_mat( pState->hMdDec, nchan_transport, num_bands_out, st_ivas->bfi ); + + wmops_sub_end(); + + return; +} + + + +/*-------------------------------------------------------------------* + * ivas_sba_prototype_renderer() + * + * Render prototype audio signals using SBA mixing matrices + *-------------------------------------------------------------------*/ + +void ivas_sba_prototype_renderer( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder struct */ + float inRe[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i : Input audio in CLDFB domain, real */ + float inIm[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i : Input audio in CLDFB domain, imag */ + const int16_t firstSubframe, /* i : First subframe to map */ + const int16_t nSubframes /* i : Number of subframes to map */ +) +{ + float mixer_mat[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH][IVAS_MAX_NUM_BANDS]; + SPAR_DEC_HANDLE hSpar; + DECODER_CONFIG_HANDLE hDecoderConfig; + int16_t num_spar_bands, spar_band; + int16_t b, ts; + int16_t num_cldfb_bands, numch_in, numch_out; + int16_t cldfb_band; + int16_t out_ch, in_ch; + int16_t firstSlot, slotEnd, firstInCh, inChEnd, firstOutCh, outChEnd; + int16_t sf_idx; + + wmops_sub_start( "ivas_sba_prototype_renderer" ); + + hSpar = st_ivas->hSpar; + hDecoderConfig = st_ivas->hDecoderConfig; + num_spar_bands = hSpar->hFbMixer->pFb->filterbank_num_bands; + + firstSlot = firstSubframe * ( CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES ); + slotEnd = ( firstSubframe + nSubframes ) * ( CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES ); + + num_cldfb_bands = hSpar->hFbMixer->pFb->fb_bin_to_band.num_cldfb_bands; + numch_in = hSpar->hFbMixer->fb_cfg->num_in_chans; + numch_out = hSpar->hFbMixer->fb_cfg->num_out_chans; + + if ( st_ivas->nchan_transport == 1 ) + { + firstInCh = 0; + inChEnd = 1; + firstOutCh = 0; + outChEnd = 1; + } + else /* 2 TC */ + { + firstInCh = 0; + inChEnd = 2; + firstOutCh = 1; + outChEnd = 2; + } + + /* Apply mixing matrix */ + for ( ts = firstSlot; ts < slotEnd; ts++ ) + { + /* determine SPAR parameters for this time slot */ + ivas_spar_get_parameters( hSpar, hDecoderConfig, ts, numch_out, numch_in, num_spar_bands, mixer_mat ); + + for ( cldfb_band = 0; cldfb_band < num_cldfb_bands; cldfb_band++ ) + { + float out_re[IVAS_SPAR_MAX_CH]; + float out_im[IVAS_SPAR_MAX_CH]; + float cldfb_par; + ivas_fb_bin_to_band_data_t *bin2band = &hSpar->hFbMixer->pFb->fb_bin_to_band; + + for ( out_ch = firstOutCh; out_ch < outChEnd; out_ch++ ) + { + out_re[out_ch] = 0.0f; + out_im[out_ch] = 0.0f; + + for ( in_ch = firstInCh; in_ch < inChEnd; in_ch++ ) + { + if ( cldfb_band < CLDFB_PAR_WEIGHT_START_BAND ) /* tuning parameter, depends on how much SPAR Filters overlap for the CLDFB bands */ + { + spar_band = bin2band->p_cldfb_map_to_spar_band[cldfb_band]; + cldfb_par = mixer_mat[out_ch][in_ch][spar_band]; + } + else + { + cldfb_par = 0.0f; + for ( spar_band = bin2band->p_spar_start_bands[cldfb_band]; spar_band < num_spar_bands; spar_band++ ) + { + /* accumulate contributions from all SPAR bands */ + cldfb_par += mixer_mat[out_ch][in_ch][spar_band] * bin2band->pp_cldfb_weights_per_spar_band[cldfb_band][spar_band]; + } + } + + out_re[out_ch] += inRe[in_ch][ts][cldfb_band] * cldfb_par; + out_im[out_ch] += inIm[in_ch][ts][cldfb_band] * cldfb_par; + } + } + + /*update CLDFB data with the parameter-modified data*/ + for ( out_ch = firstOutCh; out_ch < outChEnd; out_ch++ ) + { + inRe[out_ch][ts][cldfb_band] = out_re[out_ch]; + inIm[out_ch][ts][cldfb_band] = out_im[out_ch]; + } + } + + /* Update mixing matrices */ + if ( ( ( ts + 1 ) % MAX_PARAM_SPATIAL_SUBFRAMES ) == 0 ) + { + sf_idx = ts / MAX_PARAM_SPATIAL_SUBFRAMES; + hSpar->i_subframe++; + hSpar->i_subframe = min( hSpar->i_subframe, MAX_PARAM_SPATIAL_SUBFRAMES ); + mvr2r( hSpar->hMdDec->mixer_mat_prev[1][0][0], hSpar->hMdDec->mixer_mat_prev[0][0][0], IVAS_MAX_FB_MIXER_OUT_CH * IVAS_MAX_FB_MIXER_IN_CH * IVAS_MAX_NUM_BANDS ); + mvr2r( hSpar->hMdDec->mixer_mat_prev[2][0][0], hSpar->hMdDec->mixer_mat_prev[1][0][0], IVAS_MAX_FB_MIXER_OUT_CH * IVAS_MAX_FB_MIXER_IN_CH * IVAS_MAX_NUM_BANDS ); + mvr2r( hSpar->hMdDec->mixer_mat_prev[3][0][0], hSpar->hMdDec->mixer_mat_prev[2][0][0], IVAS_MAX_FB_MIXER_OUT_CH * IVAS_MAX_FB_MIXER_IN_CH * IVAS_MAX_NUM_BANDS ); + mvr2r( hSpar->hMdDec->mixer_mat_prev[4][0][0], hSpar->hMdDec->mixer_mat_prev[3][0][0], IVAS_MAX_FB_MIXER_OUT_CH * IVAS_MAX_FB_MIXER_IN_CH * IVAS_MAX_NUM_BANDS ); + + for ( out_ch = 0; out_ch < numch_out; out_ch++ ) + { + for ( in_ch = 0; in_ch < numch_in; in_ch++ ) + { + for ( b = 0; b < num_spar_bands; b++ ) + { + hSpar->hMdDec->mixer_mat_prev[4][out_ch][in_ch][b] = hSpar->hMdDec->mixer_mat[out_ch][in_ch][b + sf_idx * IVAS_MAX_NUM_BANDS]; + } + } + } + } + } + + /* Create prototypes */ + if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) + { + for ( ts = firstSlot; ts < slotEnd; ts++ ) + { + if ( st_ivas->nchan_transport == 1 ) /* Dual mono */ + { + mvr2r( inRe[0][ts], inRe[1][ts], CLDFB_NO_CHANNELS_MAX ); + mvr2r( inIm[0][ts], inIm[1][ts], CLDFB_NO_CHANNELS_MAX ); + } + else if ( st_ivas->nchan_transport == 2 ) /* Opposing cardioids */ + { + float temp_signal[CLDFB_NO_CHANNELS_MAX]; + + v_add( inRe[0][ts], inRe[1][ts], temp_signal, CLDFB_NO_CHANNELS_MAX ); + v_sub( inRe[0][ts], inRe[1][ts], inRe[1][ts], CLDFB_NO_CHANNELS_MAX ); + mvr2r( temp_signal, inRe[0][ts], CLDFB_NO_CHANNELS_MAX ); + v_multc( inRe[0][ts], 0.5f, inRe[0][ts], CLDFB_NO_CHANNELS_MAX ); + v_multc( inRe[1][ts], 0.5f, inRe[1][ts], CLDFB_NO_CHANNELS_MAX ); + + v_add( inIm[0][ts], inIm[1][ts], temp_signal, CLDFB_NO_CHANNELS_MAX ); + v_sub( inIm[0][ts], inIm[1][ts], inIm[1][ts], CLDFB_NO_CHANNELS_MAX ); + mvr2r( temp_signal, inIm[0][ts], CLDFB_NO_CHANNELS_MAX ); + v_multc( inIm[0][ts], 0.5f, inIm[0][ts], CLDFB_NO_CHANNELS_MAX ); + v_multc( inIm[1][ts], 0.5f, inIm[1][ts], CLDFB_NO_CHANNELS_MAX ); + } + } + } + + wmops_sub_end(); + + return; +} + #ifdef DEBUG_MODE_DIRAC /*-----------------------------------------------------------------------* diff --git a/lib_dec/ivas_sba_rendering.c b/lib_dec/ivas_sba_rendering.c deleted file mode 100644 index 1b8572b6fc..0000000000 --- a/lib_dec/ivas_sba_rendering.c +++ /dev/null @@ -1,526 +0,0 @@ -/****************************************************************************************************** - - (C) 2022 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_stat_dec.h" -#include "ivas_cnst.h" -#include -#ifdef DEBUGGING -#include "debug.h" -#endif -#include "wmops.h" - - -/*-----------------------------------------------------------------------* - * Local function prototypes - *-----------------------------------------------------------------------*/ - -static void ivas_sba_mtx_mult( float output_f[][L_FRAME48k], const int16_t output_frame, const int16_t nchan_in, IVAS_OUTPUT_SETUP output_setup, const float *mtx_hoa_decoder ); - - -/*-------------------------------------------------------------------* - * ivas_sba_linear_renderer() - * - * Linear rendering for SBA format - *-------------------------------------------------------------------*/ - -ivas_error ivas_sba_linear_renderer( - float output_f[][L_FRAME48k], /* i/o: synthesized core-coder transport channels/DirAC output */ - const int16_t output_frame, /* i : output frame length per channel */ - const int16_t nchan_in, /* i : number of input ambisonics channels */ - const AUDIO_CONFIG output_config, /* i : output audio configuration */ - const IVAS_OUTPUT_SETUP output_setup, /* i : output format setup */ - const float hoa_dec_mtx[] /* i : HOA decoding mtx */ -) -{ - int16_t i; - float dmx_l; - int16_t nchan_hoa; - ivas_error error; - - error = IVAS_ERR_OK; - - /* Number of channels of HOA depends of transport format which is mixed order xH1V*/ - nchan_hoa = nchan_in; - - if ( nchan_in == 6 ) /*2H1V*/ - { - nchan_hoa = 9; - } - else if ( nchan_in == 8 ) /*3H1V*/ - { - nchan_hoa = 16; - } - - switch ( output_config ) - { - case AUDIO_CONFIG_MONO: - /* If stereo DMX, MONO = W = Cardioids L + R*/ - if ( nchan_in == 2 ) - { - for ( i = 0; i < output_frame; i++ ) - { - output_f[0][i] += output_f[1][i]; - } - } - /* else: do nothing, MONO = W*/ - break; - case AUDIO_CONFIG_STEREO: - assert( ( nchan_in >= 2 ) && "Number of input channels must be at least 2 (for W and Y)!\n" ); - - /* Compute L and R cardioids from SB format except if stereo DMX is transmitted already in this format*/ - if ( nchan_in > 2 ) - { - /*Build L/R cardioids*/ - for ( i = 0; i < output_frame; i++ ) - { - dmx_l = 0.5f * ( output_f[0][i] + output_f[1][i] ); /* cardioid_left = 0.5(W + Y) */ - output_f[1][i] = 0.5f * ( output_f[0][i] - output_f[1][i] ); /* cardioid_right = 0.5(W - Y) */ - output_f[0][i] = dmx_l; - } - } - break; - case AUDIO_CONFIG_5_1: - case AUDIO_CONFIG_7_1: - case AUDIO_CONFIG_5_1_2: - case AUDIO_CONFIG_5_1_4: - case AUDIO_CONFIG_7_1_4: - case AUDIO_CONFIG_LS_CUSTOM: - ivas_sba_mtx_mult( output_f, output_frame, nchan_hoa, output_setup, hoa_dec_mtx ); - break; - case AUDIO_CONFIG_FOA: /* Ambisonics output, order: 1 */ - case AUDIO_CONFIG_HOA2: /* Ambisonics output, order: 2 */ - case AUDIO_CONFIG_HOA3: /* Ambisonics output, order: 3 */ - for ( i = nchan_hoa; i < output_setup.nchan_out_woLFE; i++ ) - { - set_zero( output_f[i], output_frame ); - } - break; - default: - return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Error: illegal output configuration, Exiting.\n" ); - } - - return error; -} - - -/*-------------------------------------------------------------------* - * ivas_sba_mtx_mult() - * - * HOA decoding with LFE insertion - *-------------------------------------------------------------------*/ - -static void ivas_sba_mtx_mult( - float output_f[][L_FRAME48k], /* i/o: synthesized core-coder transport channels/DirAC output */ - const int16_t output_frame, /* i : output frame length per channel */ - const int16_t nchan_in, /* i : Number of ambisonic channels */ - IVAS_OUTPUT_SETUP output_setup, /* i : Output configuration */ - const float *mtx_hoa_decoder /* i : HOA decoding mtx */ -) -{ - int16_t i, k, ch_idx; - int16_t idx_lfe; - float input_f[16]; - const float *hoa_decoder; - - assert( ( nchan_in >= FOA_CHANNELS ) && "Number of input channels must be at least 4 (FOA)!\n" ); - - for ( i = 0; i < output_frame; i++ ) - { - /* init*/ - idx_lfe = 0; - hoa_decoder = &mtx_hoa_decoder[0]; - for ( k = 0; k < nchan_in; k++ ) - { - input_f[k] = output_f[k][i]; - } - - /* mtx mult with LFE insertion*/ - for ( ch_idx = 0; ch_idx < ( output_setup.nchan_out_woLFE + output_setup.num_lfe ); ch_idx++ ) - { - if ( ( output_setup.num_lfe > 0 ) && ( output_setup.index_lfe[idx_lfe] == ch_idx ) ) - { - /*LFE insertion*/ - output_f[ch_idx][i] = 0.f; - if ( idx_lfe < ( output_setup.num_lfe - 1 ) ) - { - idx_lfe++; - } - } - else - { - /*HOA decoding*/ - output_f[ch_idx][i] = input_f[0] * hoa_decoder[0]; - for ( k = 1; k < nchan_in; k++ ) - { - output_f[ch_idx][i] += input_f[k] * hoa_decoder[k]; - } - hoa_decoder += 16; - } - } - } - - return; -} - - -/*-------------------------------------------------------------------* - * ivas_sba_upmixer_renderer() - * - * SBA upmix & rendering - *-------------------------------------------------------------------*/ - -void ivas_sba_upmixer_renderer( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder struct */ - float output[][L_FRAME48k], /* i/o: transport/output audio channels */ - const int16_t nchan_remapped, /* i : num channels after remapping of TCs */ - const int16_t output_frame /* i : output frame length */ -) -{ - int16_t i, ch, nchan_out; -#ifdef SIMPLIFY_SBA_RENDERING_LOGIC - float temp; -#else - float clip, temp; -#endif - int16_t nchan_internal; - - wmops_sub_start( "ivas_sba_upmixer_renderer" ); - - nchan_internal = ivas_sba_get_nchan_metadata( st_ivas->sba_order ); - nchan_out = st_ivas->hDecoderConfig->nchan_out; - - for ( ch = 0; ch < nchan_remapped; ch++ ) - { - for ( i = 0; i < output_frame; i++ ) - { - temp = output[ch][i]; - temp = floorf( temp + 0.5f ); - - if ( temp > MAX16B_FLT ) - { - temp = MAX16B_FLT; - } - else if ( temp < ( -1.0f * PCM16_TO_FLT_FAC ) ) - { - temp = ( -1.0f * PCM16_TO_FLT_FAC ); - } - temp *= ( 1.0f / PCM16_TO_FLT_FAC ); - output[ch][i] = temp; - } - } - - if ( st_ivas->nchan_transport >= 3 ) - { - /*convert WYZX downmix to WYXZ*/ - for ( i = 0; i < output_frame; i++ ) - { - temp = output[2][i]; - output[2][i] = output[3][i]; - output[3][i] = temp; - } - } - -#ifdef SIMPLIFY_SBA_RENDERING_LOGIC - /* Upmixer + Renderer */ -#else - /* Upmixer */ -#endif - ivas_spar_dec_upmixer( st_ivas, output, nchan_internal, output_frame ); - -#ifndef SIMPLIFY_SBA_RENDERING_LOGIC - /* Renderer */ - if ( st_ivas->hDirAC != NULL && st_ivas->renderer_type == RENDERER_DIRAC ) - { - nchan_out = st_ivas->hDirAC->hOutSetup.nchan_out_woLFE + st_ivas->hDirAC->hOutSetup.num_lfe; - } -#endif - if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_DEC ) - { - ivas_sba_linear_renderer( output, output_frame, st_ivas->hIntSetup.nchan_out_woLFE, st_ivas->hDecoderConfig->output_config, st_ivas->hOutSetup, st_ivas->hoa_dec_mtx ); - } - -#ifndef SIMPLIFY_SBA_RENDERING_LOGIC - clip = 1.0f; -#endif - for ( ch = 0; ch < nchan_out; ch++ ) - { - for ( i = 0; i < output_frame; i++ ) - { -#ifndef SIMPLIFY_SBA_RENDERING_LOGIC - clip = max( clip, fabsf( output[ch][i] ) ); -#endif - output[ch][i] = output[ch][i] * PCM16_TO_FLT_FAC; - } - } - -#ifndef SIMPLIFY_SBA_RENDERING_LOGIC -#ifdef DEBUGGING - if ( clip > 1.0f ) - { - fprintf( stderr, "IVAS Crend Clipped: max gain = %f\n", clip ); - } -#endif -#endif - - wmops_sub_end(); - - return; -} - - -/*-------------------------------------------------------------------* - * ivas_sba_mix_matrix_determiner() - * - * Determine SBA mixing matrices - *-------------------------------------------------------------------*/ - -void ivas_sba_mix_matrix_determiner( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder struct */ - float output[][L_FRAME48k], /* i/o: transport/output audio channels */ - const int16_t nchan_remapped, /* i : num channels after remapping of TCs */ - const int16_t output_frame /* i : output frame length */ -) -{ - int16_t i, ch; - float temp; - SPAR_DEC_HANDLE hSpar; - int16_t num_bands_out, nchan_transport, nchan_out; - - hSpar = st_ivas->hSpar; - - /* Convert numeric range */ - for ( ch = 0; ch < nchan_remapped; ch++ ) - { - for ( i = 0; i < output_frame; i++ ) - { - temp = output[ch][i]; - temp = floorf( temp + 0.5f ); - - if ( temp > MAX16B_FLT ) - { - temp = MAX16B_FLT; - } - else if ( temp < ( -1.0f * PCM16_TO_FLT_FAC ) ) - { - temp = ( -1.0f * PCM16_TO_FLT_FAC ); - } - temp *= ( 1.0f / PCM16_TO_FLT_FAC ); - output[ch][i] = temp; - } - } - - /* AGC */ - nchan_transport = hSpar->hMdDec->spar_md_cfg.nchan_transport; - nchan_out = nchan_transport; - ivas_agc_dec_process( hSpar->hAgcDec, output, output, nchan_transport, output_frame ); - - /* Convert numeric range back */ - for ( ch = 0; ch < nchan_out; ch++ ) - { - for ( i = 0; i < output_frame; i++ ) - { - output[ch][i] = output[ch][i] * PCM16_TO_FLT_FAC; - } - } - - /* Mixing matrix determiner */ - num_bands_out = hSpar->hFbMixer->pFb->filterbank_num_bands; - ivas_spar_dec_gen_umx_mat( hSpar->hMdDec, nchan_transport, num_bands_out, st_ivas->bfi ); - - wmops_sub_end(); - - return; -} - - -/*-------------------------------------------------------------------* - * ivas_sba_prototype_renderer() - * - * Render prototype audio signals using SBA mixing matrices - *-------------------------------------------------------------------*/ - -void ivas_sba_prototype_renderer( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder struct */ - float inRe[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i : Input audio in CLDFB domain, real */ - float inIm[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i : Input audio in CLDFB domain, imag */ - const int16_t firstSubframe, /* i : First subframe to map */ - const int16_t nSubframes /* i : Number of subframes to map */ -) -{ - float mixer_mat[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH][IVAS_MAX_NUM_BANDS]; - SPAR_DEC_HANDLE hSpar; - DECODER_CONFIG_HANDLE hDecoderConfig; - int16_t num_spar_bands, spar_band; - int16_t b, ts; - int16_t num_cldfb_bands, numch_in, numch_out; - int16_t cldfb_band; - int16_t out_ch, in_ch; - int16_t firstSlot, slotEnd, firstInCh, inChEnd, firstOutCh, outChEnd; - int16_t sf_idx; - - wmops_sub_start( "ivas_sba_prototype_renderer" ); - - hSpar = st_ivas->hSpar; - hDecoderConfig = st_ivas->hDecoderConfig; - num_spar_bands = hSpar->hFbMixer->pFb->filterbank_num_bands; - - firstSlot = firstSubframe * ( CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES ); - slotEnd = ( firstSubframe + nSubframes ) * ( CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES ); - - num_cldfb_bands = hSpar->hFbMixer->pFb->fb_bin_to_band.num_cldfb_bands; - numch_in = hSpar->hFbMixer->fb_cfg->num_in_chans; - numch_out = hSpar->hFbMixer->fb_cfg->num_out_chans; - - if ( st_ivas->nchan_transport == 1 ) - { - firstInCh = 0; - inChEnd = 1; - firstOutCh = 0; - outChEnd = 1; - } - else /* 2 TC */ - { - firstInCh = 0; - inChEnd = 2; - firstOutCh = 1; - outChEnd = 2; - } - - /* Apply mixing matrix */ - for ( ts = firstSlot; ts < slotEnd; ts++ ) - { - /* determine SPAR parameters for this time slot */ - ivas_spar_get_parameters( hSpar, hDecoderConfig, ts, numch_out, numch_in, num_spar_bands, mixer_mat ); - - for ( cldfb_band = 0; cldfb_band < num_cldfb_bands; cldfb_band++ ) - { - float out_re[IVAS_SPAR_MAX_CH]; - float out_im[IVAS_SPAR_MAX_CH]; - float cldfb_par; - ivas_fb_bin_to_band_data_t *bin2band = &hSpar->hFbMixer->pFb->fb_bin_to_band; - - for ( out_ch = firstOutCh; out_ch < outChEnd; out_ch++ ) - { - out_re[out_ch] = 0.0f; - out_im[out_ch] = 0.0f; - - for ( in_ch = firstInCh; in_ch < inChEnd; in_ch++ ) - { - if ( cldfb_band < CLDFB_PAR_WEIGHT_START_BAND ) /* tuning parameter, depends on how much SPAR Filters overlap for the CLDFB bands */ - { - spar_band = bin2band->p_cldfb_map_to_spar_band[cldfb_band]; - cldfb_par = mixer_mat[out_ch][in_ch][spar_band]; - } - else - { - cldfb_par = 0.0f; - for ( spar_band = bin2band->p_spar_start_bands[cldfb_band]; spar_band < num_spar_bands; spar_band++ ) - { - /* accumulate contributions from all SPAR bands */ - cldfb_par += mixer_mat[out_ch][in_ch][spar_band] * bin2band->pp_cldfb_weights_per_spar_band[cldfb_band][spar_band]; - } - } - - out_re[out_ch] += inRe[in_ch][ts][cldfb_band] * cldfb_par; - out_im[out_ch] += inIm[in_ch][ts][cldfb_band] * cldfb_par; - } - } - - /*update CLDFB data with the parameter-modified data*/ - for ( out_ch = firstOutCh; out_ch < outChEnd; out_ch++ ) - { - inRe[out_ch][ts][cldfb_band] = out_re[out_ch]; - inIm[out_ch][ts][cldfb_band] = out_im[out_ch]; - } - } - - /* Update mixing matrices */ - if ( ( ( ts + 1 ) % MAX_PARAM_SPATIAL_SUBFRAMES ) == 0 ) - { - sf_idx = ts / MAX_PARAM_SPATIAL_SUBFRAMES; - hSpar->i_subframe++; - hSpar->i_subframe = min( hSpar->i_subframe, MAX_PARAM_SPATIAL_SUBFRAMES ); - mvr2r( hSpar->hMdDec->mixer_mat_prev[1][0][0], hSpar->hMdDec->mixer_mat_prev[0][0][0], IVAS_MAX_FB_MIXER_OUT_CH * IVAS_MAX_FB_MIXER_IN_CH * IVAS_MAX_NUM_BANDS ); - mvr2r( hSpar->hMdDec->mixer_mat_prev[2][0][0], hSpar->hMdDec->mixer_mat_prev[1][0][0], IVAS_MAX_FB_MIXER_OUT_CH * IVAS_MAX_FB_MIXER_IN_CH * IVAS_MAX_NUM_BANDS ); - mvr2r( hSpar->hMdDec->mixer_mat_prev[3][0][0], hSpar->hMdDec->mixer_mat_prev[2][0][0], IVAS_MAX_FB_MIXER_OUT_CH * IVAS_MAX_FB_MIXER_IN_CH * IVAS_MAX_NUM_BANDS ); - mvr2r( hSpar->hMdDec->mixer_mat_prev[4][0][0], hSpar->hMdDec->mixer_mat_prev[3][0][0], IVAS_MAX_FB_MIXER_OUT_CH * IVAS_MAX_FB_MIXER_IN_CH * IVAS_MAX_NUM_BANDS ); - - for ( out_ch = 0; out_ch < numch_out; out_ch++ ) - { - for ( in_ch = 0; in_ch < numch_in; in_ch++ ) - { - for ( b = 0; b < num_spar_bands; b++ ) - { - hSpar->hMdDec->mixer_mat_prev[4][out_ch][in_ch][b] = hSpar->hMdDec->mixer_mat[out_ch][in_ch][b + sf_idx * IVAS_MAX_NUM_BANDS]; - } - } - } - } - } - - /* Create prototypes */ - if ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) - { - for ( ts = firstSlot; ts < slotEnd; ts++ ) - { - if ( st_ivas->nchan_transport == 1 ) /* Dual mono */ - { - mvr2r( inRe[0][ts], inRe[1][ts], CLDFB_NO_CHANNELS_MAX ); - mvr2r( inIm[0][ts], inIm[1][ts], CLDFB_NO_CHANNELS_MAX ); - } - else if ( st_ivas->nchan_transport == 2 ) /* Opposing cardioids */ - { - float temp_signal[CLDFB_NO_CHANNELS_MAX]; - - v_add( inRe[0][ts], inRe[1][ts], temp_signal, CLDFB_NO_CHANNELS_MAX ); - v_sub( inRe[0][ts], inRe[1][ts], inRe[1][ts], CLDFB_NO_CHANNELS_MAX ); - mvr2r( temp_signal, inRe[0][ts], CLDFB_NO_CHANNELS_MAX ); - v_multc( inRe[0][ts], 0.5f, inRe[0][ts], CLDFB_NO_CHANNELS_MAX ); - v_multc( inRe[1][ts], 0.5f, inRe[1][ts], CLDFB_NO_CHANNELS_MAX ); - - v_add( inIm[0][ts], inIm[1][ts], temp_signal, CLDFB_NO_CHANNELS_MAX ); - v_sub( inIm[0][ts], inIm[1][ts], inIm[1][ts], CLDFB_NO_CHANNELS_MAX ); - mvr2r( temp_signal, inIm[0][ts], CLDFB_NO_CHANNELS_MAX ); - v_multc( inIm[0][ts], 0.5f, inIm[0][ts], CLDFB_NO_CHANNELS_MAX ); - v_multc( inIm[1][ts], 0.5f, inIm[1][ts], CLDFB_NO_CHANNELS_MAX ); - } - } - } - - wmops_sub_end(); - - return; -} diff --git a/lib_dec/ivas_stat_dec.h b/lib_dec/ivas_stat_dec.h index 18fc4b4741..ca3996af4a 100644 --- a/lib_dec/ivas_stat_dec.h +++ b/lib_dec/ivas_stat_dec.h @@ -39,6 +39,7 @@ #include "stat_dec.h" #include "ivas_cnst.h" #include "ivas_stat_com.h" +#include "ivas_stat_rend.h" /*----------------------------------------------------------------------------------* @@ -1114,59 +1115,6 @@ typedef struct renderer_struct } ISM_RENDERER_DATA, *ISM_RENDERER_HANDLE; -/*----------------------------------------------------------------------------------* - * Loudspeaker Configuration Conversion structure - *----------------------------------------------------------------------------------*/ - -typedef struct ivas_LS_setupconversion_struct -{ - float *dmxMtx[MAX_OUTPUT_CHANNELS]; - float *targetEnergyPrev[MAX_OUTPUT_CHANNELS]; - float *dmxEnergyPrev[MAX_OUTPUT_CHANNELS]; - int16_t sfbOffset[MAX_SFB + 2]; - int16_t sfbCnt; - -} LSSETUP_CONVERSION_STRUCT, *LSSETUP_CONVERSION_HANDLE; - - -typedef struct ivas_LS_setupconversion_matrix -{ - int16_t index; - float value; -} LS_CONVERSION_MATRIX; - -typedef struct ivas_LS_setupconversion_mapping -{ - AUDIO_CONFIG input_config; - AUDIO_CONFIG output_config; - const LS_CONVERSION_MATRIX *conversion_matrix; -} LS_CONVERSION_MAPPING; - -typedef struct ivas_mono_downmix_renderer_struct -{ - float inputEnergy[CLDFB_NO_CHANNELS_MAX]; - float protoEnergy[CLDFB_NO_CHANNELS_MAX]; - -} MONO_DOWNMIX_RENDERER_STRUCT, *MONO_DOWNMIX_RENDERER_HANDLE; - - -/*----------------------------------------------------------------------------------* - * Custom Loudspeaker configuration structure - *----------------------------------------------------------------------------------*/ - -typedef struct ivas_LS_setup_custom -{ - int16_t is_planar_setup; /* flag to indicate if setup is planar or not */ - int16_t num_spk; /* number of custom loudspeakers */ - float ls_azimuth[MAX_OUTPUT_CHANNELS]; /* custom loudspeaker azimuths */ - float ls_elevation[MAX_OUTPUT_CHANNELS]; /* custom loudspeaker elevations */ - int16_t num_lfe; /* number of LFE channels */ - int16_t lfe_idx[MAX_OUTPUT_CHANNELS]; /* index for LFE channel insertion */ - int16_t separate_ch_found; /* flag to indicate if a center channel was found */ - float separate_ch_gains[MAX_OUTPUT_CHANNELS]; /* gains to pan McMASA separateChannel in case no center channel is present */ - -} LSSETUP_CUSTOM_STRUCT, *LSSETUP_CUSTOM_HANDLE; - /*----------------------------------------------------------------------------------* * MASA decoder structures diff --git a/lib_dec/ivas_allrad_dec.c b/lib_rend/ivas_allrad_dec.c similarity index 99% rename from lib_dec/ivas_allrad_dec.c rename to lib_rend/ivas_allrad_dec.c index d4301c07ac..5083002298 100644 --- a/lib_dec/ivas_allrad_dec.c +++ b/lib_rend/ivas_allrad_dec.c @@ -39,7 +39,7 @@ #include "prot.h" #include "ivas_prot.h" #include "ivas_stat_dec.h" -#include "ivas_rom_dec.h" +#include "ivas_rom_rend.h" #ifdef DEBUGGING #include "debug.h" #endif diff --git a/lib_dec/ivas_binauralRenderer.c b/lib_rend/ivas_binauralRenderer.c similarity index 99% rename from lib_dec/ivas_binauralRenderer.c rename to lib_rend/ivas_binauralRenderer.c index 153e159adc..f9067c4fed 100644 --- a/lib_dec/ivas_binauralRenderer.c +++ b/lib_rend/ivas_binauralRenderer.c @@ -37,7 +37,7 @@ #include "prot.h" #include "cnst.h" #include "ivas_cnst.h" -#include "ivas_rom_dec.h" +#include "ivas_rom_rend.h" #include "ivas_rom_com.h" #include "ivas_rom_binauralRenderer.h" #ifdef DEBUGGING diff --git a/lib_dec/ivas_binaural_reverb.c b/lib_rend/ivas_binaural_reverb.c similarity index 100% rename from lib_dec/ivas_binaural_reverb.c rename to lib_rend/ivas_binaural_reverb.c diff --git a/lib_dec/ivas_crend.c b/lib_rend/ivas_crend.c similarity index 99% rename from lib_dec/ivas_crend.c rename to lib_rend/ivas_crend.c index 26f559ca82..0473fa38aa 100644 --- a/lib_dec/ivas_crend.c +++ b/lib_rend/ivas_crend.c @@ -35,7 +35,7 @@ #include "prot.h" #include "ivas_prot.h" #include "ivas_cnst.h" -#include "ivas_rom_dec.h" +#include "ivas_rom_rend.h" #include "ivas_stat_dec.h" #include #include "ivas_rom_binaural_crend_head.h" diff --git a/lib_dec/ivas_efap.c b/lib_rend/ivas_efap.c similarity index 99% rename from lib_dec/ivas_efap.c rename to lib_rend/ivas_efap.c index efd7795dfe..34d9586a95 100644 --- a/lib_dec/ivas_efap.c +++ b/lib_rend/ivas_efap.c @@ -1324,17 +1324,21 @@ static void efap_panning( float tmpBuff[EFAP_MAX_CHAN_NUM]; float normTmpBuff; float P[2]; +#ifndef FIX_EFAP_MATH float P_tmp[2]; +#endif P[0] = azi; P[1] = ele; /* Finding in which polygon the point is */ +#ifndef FIX_EFAP_MATH P_tmp[0] = roundf( P[0] / PANNING_AZI_RESOLUTION ); P_tmp[1] = roundf( P[1] / PANNING_ELE_RESOLUTION ); P[0] = P_tmp[0] * PANNING_AZI_RESOLUTION; P[1] = P_tmp[1] * PANNING_ELE_RESOLUTION; +#endif polyIdx = get_poly_num( P, polyData ); @@ -2201,7 +2205,11 @@ static int16_t in_tri( /* Verification of the non-colinearity */ invFactor = tmpDot1[0] * tmpDot2[1] - tmpDot1[1] * tmpDot2[0]; +#ifdef FIX_EFAP_MATH + if ( fabsf( invFactor ) < thresh ) +#else if ( invFactor < thresh ) +#endif { return 0; } diff --git a/lib_dec/ivas_hrtf.c b/lib_rend/ivas_hrtf.c similarity index 99% rename from lib_dec/ivas_hrtf.c rename to lib_rend/ivas_hrtf.c index eebe3b037f..8b5f1ba217 100644 --- a/lib_dec/ivas_hrtf.c +++ b/lib_rend/ivas_hrtf.c @@ -32,7 +32,6 @@ #include #include "options.h" -#include "hrtf_file_reader.h" #include "prot.h" #include "ivas_prot.h" #include "lib_dec.h" diff --git a/lib_dec/ivas_limiter.c b/lib_rend/ivas_limiter.c similarity index 100% rename from lib_dec/ivas_limiter.c rename to lib_rend/ivas_limiter.c diff --git a/lib_dec/ivas_ls_custom_dec.c b/lib_rend/ivas_ls_custom_dec.c similarity index 100% rename from lib_dec/ivas_ls_custom_dec.c rename to lib_rend/ivas_ls_custom_dec.c diff --git a/lib_dec/ivas_objectRenderer.c b/lib_rend/ivas_objectRenderer.c similarity index 97% rename from lib_dec/ivas_objectRenderer.c rename to lib_rend/ivas_objectRenderer.c index 458bcaa702..8aa7ae80e1 100644 --- a/lib_dec/ivas_objectRenderer.c +++ b/lib_rend/ivas_objectRenderer.c @@ -142,6 +142,12 @@ ivas_error ivas_td_binaural_open( ls_azimuth = ls_azimuth_CICP19; ls_elevation = ls_elevation_CICP19; break; +#ifdef EXT_RENDERER /* TODO tmu : possibly could be adopted for the above cases too ? */ + case AUDIO_CONFIG_LS_CUSTOM: + ls_azimuth = st_ivas->hTransSetup.ls_azimuth; + ls_elevation = st_ivas->hTransSetup.ls_elevation; + break; +#endif default: ls_azimuth = NULL; ls_elevation = NULL; @@ -239,7 +245,13 @@ ivas_error ObjRenderIVASFrame( Pos[1] = 0.0f; Pos[2] = 0.0f; - if ( st_ivas->hHeadTrackData != NULL ) + if ( + st_ivas->hHeadTrackData != NULL +#ifdef EXT_RENDERER + && st_ivas->hDecoderConfig->Opt_Headrotation +#endif + ) + { /* Obtain head rotation matrix */ QuatToRotMat( st_ivas->hHeadTrackData->Quaternions[0], Rmat ); diff --git a/lib_dec/ivas_objectRenderer_hrFilt.c b/lib_rend/ivas_objectRenderer_hrFilt.c similarity index 99% rename from lib_dec/ivas_objectRenderer_hrFilt.c rename to lib_rend/ivas_objectRenderer_hrFilt.c index fd2011a7d6..4ece382b4f 100644 --- a/lib_dec/ivas_objectRenderer_hrFilt.c +++ b/lib_rend/ivas_objectRenderer_hrFilt.c @@ -36,7 +36,7 @@ #include "prot.h" #include #include "ivas_prot.h" -#include "ivas_rom_dec.h" +#include "ivas_rom_rend.h" #include "ivas_cnst.h" #include "ivas_rom_TdBinauralRenderer.h" #include "wmops.h" diff --git a/lib_dec/ivas_objectRenderer_mix.c b/lib_rend/ivas_objectRenderer_mix.c similarity index 100% rename from lib_dec/ivas_objectRenderer_mix.c rename to lib_rend/ivas_objectRenderer_mix.c diff --git a/lib_dec/ivas_objectRenderer_sfx.c b/lib_rend/ivas_objectRenderer_sfx.c similarity index 99% rename from lib_dec/ivas_objectRenderer_sfx.c rename to lib_rend/ivas_objectRenderer_sfx.c index 57b2d52c80..4f03ada392 100644 --- a/lib_dec/ivas_objectRenderer_sfx.c +++ b/lib_rend/ivas_objectRenderer_sfx.c @@ -34,7 +34,7 @@ #include "options.h" #include #include "ivas_prot.h" -#include "ivas_rom_dec.h" +#include "ivas_rom_rend.h" #include "prot.h" #include "wmops.h" diff --git a/lib_dec/ivas_objectRenderer_sources.c b/lib_rend/ivas_objectRenderer_sources.c similarity index 100% rename from lib_dec/ivas_objectRenderer_sources.c rename to lib_rend/ivas_objectRenderer_sources.c diff --git a/lib_dec/ivas_objectRenderer_vec.c b/lib_rend/ivas_objectRenderer_vec.c similarity index 100% rename from lib_dec/ivas_objectRenderer_vec.c rename to lib_rend/ivas_objectRenderer_vec.c diff --git a/lib_dec/ivas_orient_trk.c b/lib_rend/ivas_orient_trk.c similarity index 100% rename from lib_dec/ivas_orient_trk.c rename to lib_rend/ivas_orient_trk.c diff --git a/lib_dec/ivas_output_init.c b/lib_rend/ivas_output_init.c similarity index 100% rename from lib_dec/ivas_output_init.c rename to lib_rend/ivas_output_init.c diff --git a/lib_dec/ivas_render_config.c b/lib_rend/ivas_render_config.c similarity index 99% rename from lib_dec/ivas_render_config.c rename to lib_rend/ivas_render_config.c index d03ce0fa75..7e8caec092 100644 --- a/lib_dec/ivas_render_config.c +++ b/lib_rend/ivas_render_config.c @@ -34,7 +34,7 @@ #include "options.h" #include "prot.h" #include "ivas_prot.h" -#include "ivas_rom_dec.h" +#include "ivas_rom_rend.h" #include "ivas_rom_TdBinauralRenderer.h" #ifdef DEBUGGING #include "debug.h" diff --git a/lib_dec/ivas_reverb.c b/lib_rend/ivas_reverb.c similarity index 99% rename from lib_dec/ivas_reverb.c rename to lib_rend/ivas_reverb.c index c56b778138..9b3e21146a 100644 --- a/lib_dec/ivas_reverb.c +++ b/lib_rend/ivas_reverb.c @@ -39,7 +39,7 @@ #include "debug.h" #endif #include "math.h" -#include "ivas_rom_dec.h" +#include "ivas_rom_rend.h" #include #include "wmops.h" diff --git a/lib_dec/ivas_reverb_delay_line.c b/lib_rend/ivas_reverb_delay_line.c similarity index 100% rename from lib_dec/ivas_reverb_delay_line.c rename to lib_rend/ivas_reverb_delay_line.c diff --git a/lib_dec/ivas_reverb_fft_filter.c b/lib_rend/ivas_reverb_fft_filter.c similarity index 100% rename from lib_dec/ivas_reverb_fft_filter.c rename to lib_rend/ivas_reverb_fft_filter.c diff --git a/lib_dec/ivas_reverb_filter_design.c b/lib_rend/ivas_reverb_filter_design.c similarity index 100% rename from lib_dec/ivas_reverb_filter_design.c rename to lib_rend/ivas_reverb_filter_design.c diff --git a/lib_dec/ivas_reverb_iir_filter.c b/lib_rend/ivas_reverb_iir_filter.c similarity index 100% rename from lib_dec/ivas_reverb_iir_filter.c rename to lib_rend/ivas_reverb_iir_filter.c diff --git a/lib_dec/ivas_reverb_utils.c b/lib_rend/ivas_reverb_utils.c similarity index 99% rename from lib_dec/ivas_reverb_utils.c rename to lib_rend/ivas_reverb_utils.c index eb81313426..ebc8c43a11 100644 --- a/lib_dec/ivas_reverb_utils.c +++ b/lib_rend/ivas_reverb_utils.c @@ -35,7 +35,7 @@ #include "prot.h" #include "ivas_prot.h" #include "ivas_rom_binauralRenderer.h" -#include "ivas_rom_dec.h" +#include "ivas_rom_rend.h" #include #ifdef DEBUGGING #include "debug.h" diff --git a/lib_dec/ivas_rom_TdBinauralRenderer.c b/lib_rend/ivas_rom_TdBinauralRenderer.c similarity index 100% rename from lib_dec/ivas_rom_TdBinauralRenderer.c rename to lib_rend/ivas_rom_TdBinauralRenderer.c diff --git a/lib_dec/ivas_rom_TdBinauralRenderer.h b/lib_rend/ivas_rom_TdBinauralRenderer.h similarity index 100% rename from lib_dec/ivas_rom_TdBinauralRenderer.h rename to lib_rend/ivas_rom_TdBinauralRenderer.h diff --git a/lib_dec/ivas_rom_binauralRenderer.c b/lib_rend/ivas_rom_binauralRenderer.c similarity index 100% rename from lib_dec/ivas_rom_binauralRenderer.c rename to lib_rend/ivas_rom_binauralRenderer.c diff --git a/lib_dec/ivas_rom_binauralRenderer.h b/lib_rend/ivas_rom_binauralRenderer.h similarity index 100% rename from lib_dec/ivas_rom_binauralRenderer.h rename to lib_rend/ivas_rom_binauralRenderer.h diff --git a/lib_dec/ivas_rom_binaural_crend_head.c b/lib_rend/ivas_rom_binaural_crend_head.c similarity index 100% rename from lib_dec/ivas_rom_binaural_crend_head.c rename to lib_rend/ivas_rom_binaural_crend_head.c diff --git a/lib_dec/ivas_rom_binaural_crend_head.h b/lib_rend/ivas_rom_binaural_crend_head.h similarity index 100% rename from lib_dec/ivas_rom_binaural_crend_head.h rename to lib_rend/ivas_rom_binaural_crend_head.h diff --git a/lib_rend/ivas_rom_rend.c b/lib_rend/ivas_rom_rend.c new file mode 100644 index 0000000000..0f680f929d --- /dev/null +++ b/lib_rend/ivas_rom_rend.c @@ -0,0 +1,755 @@ +/****************************************************************************************************** + + (C) 2022 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 DEBUGGING +#include "debug.h" +#endif +#include "ivas_rom_rend.h" + +/* clang-format off */ + +/*----------------------------------------------------------------------------------* + * FASTCONV and PARAMETRIC binaural renderer ROM tables + *----------------------------------------------------------------------------------*/ + +const float dmxmtx[BINAURAL_CHANNELS][11] = +{ + { 1.0f, 0.0f, 0.70709997f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f }, + { 0.0f, 1.0f, 0.70709997f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f }, +}; + +/* +* 0 = 30,0 +* 1 = -30,0 +* 2 = 0,0 +* 3 = 135,0 +* 4 = -135,0 +* 5 = 110,0 +* 6 = -110,0 +* 7 = 90,0 +* 8 = -90,0 +* 9 = 30,35 +* 10 = -30,35 +* 11 = 110,35 +* 12 = -110,35 +* 13 = 135, 35 +* 14 = -135, 35 +*/ +const int16_t channelIndex_CICP6[5] = { 0, 1, 2, 5, 6 }; +const int16_t channelIndex_CICP12[7] = { 0, 1, 2, 5, 6, 3, 4 }; +const int16_t channelIndex_CICP14[7] = { 0, 1, 2, 5, 6, 9, 10 }; +const int16_t channelIndex_CICP16[9] = { 0, 1, 2, 5, 6, 9, 10, 11, 12 }; +const int16_t channelIndex_CICP19[11] = { 0, 1, 2, 3, 4, 7, 8, 9, 10, 13, 14 }; + +/*----------------------------------------------------------------------------------* + * TD ISm binaural renderer ROM tables + *----------------------------------------------------------------------------------*/ + + /* The maximum target times set to 100 msec. */ +const int16_t TDREND_SRC_REND_MaxTargetTimes[IVAS_NUM_SUPPORTED_FS] = +{ + 1600, 3200, 4800 /* Corresponds to 16kHz, 32kHz, 48kHz */ +}; + +/* The maximum lengths of the blocks internally in the effect. Corresponds to 6 msec. This means also that */ +/* if the length of the input block is just above 6 msec, the block will be divided into two 3 msec blocks. */ +const int16_t TDREND_SRC_REND_MaxBlockLengths[IVAS_NUM_SUPPORTED_FS] = +{ + 96, 192, 288 /* Corresponds to 16kHz, 32kHz, 48kHz */ +}; + +const int16_t TDREND_MaxITD[IVAS_NUM_SUPPORTED_FS] = +{ + 111, 222, 333 /* Corresponds to 16kHz, 32kHz, 48kHz */ +}; + +const float TDREND_MaxITD_Incr[IVAS_NUM_SUPPORTED_FS] = +{ + 0.0925f, 0.1850f, 0.2775f /* Corresponds to 16kHz, 32kHz, 48kHz, e.g. ( ( 2 * MaxITD ) / ( 0.05 * 48000 ) ) */ +}; + +const int16_t HRTF_MODEL_N_CPTS_VAR[HRTF_MODEL_N_SECTIONS] = +{ + 13, 12, 11 +}; + +const float SincTable[321] = +{ + 1.00000000f, 0.99957629f, 0.99830587f, 0.99619078f, 0.99323448f, 0.98944177f, 0.98481881f, 0.97937311f, + 0.97311350f, 0.96605012f, 0.95819441f, 0.94955907f, 0.94015803f, 0.93000645f, 0.91912066f, 0.90751815f, + 0.89521750f, 0.88223838f, 0.86860150f, 0.85432856f, 0.83944219f, 0.82396595f, 0.80792425f, 0.79134231f, + 0.77424608f, 0.75666226f, 0.73861817f, 0.72014174f, 0.70126144f, 0.68200624f, 0.66240553f, 0.64248906f, + 0.62228691f, 0.60182943f, 0.58114713f, 0.56027070f, 0.53923087f, 0.51805843f, 0.49678411f, 0.47543856f, + 0.45405225f, 0.43265547f, 0.41127824f, 0.38995024f, 0.36870081f, 0.34755883f, 0.32655271f, 0.30571035f, + 0.28505905f, 0.26462549f, 0.24443569f, 0.22451493f, 0.20488776f, 0.18557791f, 0.16660829f, 0.14800093f, + 0.12977695f, 0.11195656f, 0.09455895f, 0.07760236f, 0.06110400f, 0.04508003f, 0.02954554f, 0.01451456f, + 0.00000000f, -0.01398631f, -0.02743368f, -0.04033255f, -0.05267447f, -0.06445214f, -0.07565940f, -0.08629121f, + -0.09634367f, -0.10581400f, -0.11470052f, -0.12300268f, -0.13072098f, -0.13785702f, -0.14441345f, -0.15039394f, + -0.15580318f, -0.16064685f, -0.16493160f, -0.16866498f, -0.17185547f, -0.17451243f, -0.17664604f, -0.17826729f, + -0.17938796f, -0.18002054f, -0.18017822f, -0.17987486f, -0.17912493f, -0.17794347f, -0.17634608f, -0.17434883f, + -0.17196824f, -0.16922125f, -0.16612516f, -0.16269761f, -0.15895648f, -0.15491992f, -0.15060625f, -0.14603396f, + -0.14122162f, -0.13618787f, -0.13095139f, -0.12553081f, -0.11994473f, -0.11421163f, -0.10834984f, -0.10237755f, + -0.09631271f, -0.09017300f, -0.08397586f, -0.07773838f, -0.07147731f, -0.06520902f, -0.05894946f, -0.05271415f, + -0.04651815f, -0.04037601f, -0.03430179f, -0.02830902f, -0.02241063f, -0.01661904f, -0.01094605f, -0.00540284f, + -0.00000000f, 0.00525251f, 0.01034538f, 0.01526993f, 0.02001814f, 0.02458266f, 0.02895676f, 0.03313441f, + 0.03711021f, 0.04087943f, 0.04443799f, 0.04778246f, 0.05091003f, 0.05381856f, 0.05650650f, 0.05897292f, + 0.06121749f, 0.06324047f, 0.06504268f, 0.06662549f, 0.06799083f, 0.06914112f, 0.07007930f, 0.07080878f, + 0.07133343f, 0.07165755f, 0.07178588f, 0.07172352f, 0.07147595f, 0.07104902f, 0.07044886f, 0.06968193f, + 0.06875494f, 0.06767485f, 0.06644886f, 0.06508435f, 0.06358888f, 0.06197015f, 0.06023599f, 0.05839432f, + 0.05645314f, 0.05442051f, 0.05230450f, 0.05011320f, 0.04785466f, 0.04553692f, 0.04316793f, 0.04075558f, + 0.03830765f, 0.03583181f, 0.03333557f, 0.03082630f, 0.02831121f, 0.02579730f, 0.02329137f, 0.02080003f, + 0.01832963f, 0.01588629f, 0.01347589f, 0.01110403f, 0.00877607f, 0.00649705f, 0.00427175f, 0.00210467f, + 0.00000000f, -0.00203837f, -0.00400686f, -0.00590216f, -0.00772131f, -0.00946162f, -0.01112072f, -0.01269654f, + -0.01418731f, -0.01559156f, -0.01690810f, -0.01813605f, -0.01927478f, -0.02032396f, -0.02128352f, -0.02215366f, + -0.02293482f, -0.02362769f, -0.02423318f, -0.02475245f, -0.02518686f, -0.02553797f, -0.02580754f, -0.02599752f, + -0.02611000f, -0.02614728f, -0.02611175f, -0.02600597f, -0.02583262f, -0.02559449f, -0.02529446f, -0.02493550f, + -0.02452066f, -0.02405306f, -0.02353586f, -0.02297226f, -0.02236549f, -0.02171881f, -0.02103547f, -0.02031874f, + -0.01957185f, -0.01879802f, -0.01800043f, -0.01718225f, -0.01634655f, -0.01549638f, -0.01463471f, -0.01376443f, + -0.01288838f, -0.01200928f, -0.01112977f, -0.01025241f, -0.00937962f, -0.00851376f, -0.00765705f, -0.00681160f, + -0.00597942f, -0.00516238f, -0.00436225f, -0.00358068f, -0.00281917f, -0.00207914f, -0.00136185f, -0.00066846f, + -0.00000000f, 0.00064260f, 0.00125856f, 0.00184718f, 0.00240790f, 0.00294026f, 0.00344390f, 0.00391857f, + 0.00436413f, 0.00478051f, 0.00516776f, 0.00552600f, 0.00585544f, 0.00615637f, 0.00642915f, 0.00667420f, + 0.00689203f, 0.00708318f, 0.00724827f, 0.00738795f, 0.00750293f, 0.00759395f, 0.00766178f, 0.00770723f, + 0.00773114f, 0.00773435f, 0.00771774f, 0.00768218f, 0.00762857f, 0.00755779f, 0.00747075f, 0.00736831f, + 0.00725138f, 0.00712082f, 0.00697748f, 0.00682221f, 0.00665584f, 0.00647916f, 0.00629295f, 0.00609797f, + 0.00589494f, 0.00568458f, 0.00546754f, 0.00524448f, 0.00501600f, 0.00478270f, 0.00454511f, 0.00430377f, + 0.00405916f, 0.00381176f, 0.00356198f, 0.00331023f, 0.00305690f, 0.00280234f, 0.00254687f, 0.00229079f, + 0.00203440f, 0.00177795f, 0.00152168f, 0.00126584f, 0.00101062f, 0.00075625f, 0.00050289f, 0.00025075f, + 0.00000000f +}; + +const float orange53_left_avg_power[257] = { + 0.999231100f, 0.992580175f, 0.969233215f, 0.925614893f, 0.871408045f, 0.826101780f, 0.803222895f, 0.800087631f, 0.802672029f, + 0.801490188f, 0.796555817f, 0.790879488f, 0.784882724f, 0.777585745f, 0.769326210f, 0.761789441f, 0.756145239f, 0.752754092f, + 0.751703024f, 0.752594173f, 0.754317880f, 0.755515277f, 0.754378498f, 0.748860359f, 0.738919020f, 0.727488697f, 0.718792558f, + 0.714865267f, 0.713446736f, 0.711076498f, 0.706021905f, 0.697553098f, 0.684623063f, 0.667031527f, 0.647006035f, 0.627680719f, + 0.609939933f, 0.592472672f, 0.574803054f, 0.558499217f, 0.544599831f, 0.532128096f, 0.520152628f, 0.509682238f, 0.501904130f, + 0.496162385f, 0.491121918f, 0.486813396f, 0.483951330f, 0.482198298f, 0.480713189f, 0.479654074f, 0.479590476f, 0.479965866f, + 0.479589254f, 0.478181243f, 0.476334095f, 0.474199444f, 0.471616089f, 0.469089746f, 0.467486322f, 0.466943622f, 0.467153549f, + 0.468381166f, 0.470996737f, 0.474416614f, 0.477639019f, 0.480612457f, 0.483910263f, 0.487287015f, 0.489909321f, 0.491668850f, + 0.493155539f, 0.494319856f, 0.494512051f, 0.493615031f, 0.492155492f, 0.490116775f, 0.486886710f, 0.482303619f, 0.476902038f, + 0.470775038f, 0.463377595f, 0.454571068f, 0.445130944f, 0.435581058f, 0.425568998f, 0.414717495f, 0.403531373f, 0.392556936f, + 0.381436378f, 0.369506508f, 0.357099295f, 0.345049500f, 0.333368897f, 0.321326375f, 0.308959186f, 0.297232091f, 0.286592871f, + 0.276453108f, 0.266589880f, 0.257950366f, 0.251341701f, 0.246435612f, 0.242861211f, 0.241405189f, 0.242839754f, 0.246688128f, + 0.252115428f, 0.259297341f, 0.268399984f, 0.278481483f, 0.288520366f, 0.298599035f, 0.308846802f, 0.318350822f, 0.326248646f, + 0.332813978f, 0.338464528f, 0.342543274f, 0.344278336f, 0.344031811f, 0.342641503f, 0.339995682f, 0.335437506f, 0.329174429f, + 0.322237372f, 0.315035462f, 0.306967229f, 0.297821850f, 0.288482070f, 0.279766560f, 0.271234214f, 0.262228251f, 0.253214896f, + 0.245183259f, 0.237939596f, 0.230546176f, 0.223051578f, 0.216552779f, 0.211263061f, 0.206180066f, 0.200917527f, 0.196485907f, + 0.193453044f, 0.190857053f, 0.187853232f, 0.185171053f, 0.183685005f, 0.182665780f, 0.180928215f, 0.178784713f, 0.177342966f, + 0.176323384f, 0.174430951f, 0.171496049f, 0.168740034f, 0.166518897f, 0.163711995f, 0.159658119f, 0.155442193f, 0.152056932f, + 0.148795277f, 0.144545168f, 0.139905334f, 0.136263832f, 0.133493021f, 0.130194828f, 0.126240104f, 0.123071767f, 0.121281922f, + 0.119557180f, 0.117016964f, 0.114773229f, 0.114072219f, 0.114103459f, 0.113414355f, 0.112460621f, 0.112842396f, 0.114564091f, + 0.115944758f, 0.116569765f, 0.117913686f, 0.120910525f, 0.124211200f, 0.126575813f, 0.128826424f, 0.132578567f, 0.137430578f, + 0.141675219f, 0.144987956f, 0.148879051f, 0.154273912f, 0.159992099f, 0.164641231f, 0.168560207f, 0.173201621f, 0.178906262f, + 0.184429348f, 0.188756809f, 0.192309171f, 0.196154252f, 0.200732291f, 0.205381230f, 0.209404662f, 0.212832779f, 0.216197237f, + 0.220162451f, 0.225029215f, 0.230637416f, 0.236752108f, 0.243243530f, 0.249900997f, 0.256293535f, 0.261716694f, 0.265186161f, + 0.265652657f, 0.262010813f, 0.253508776f, 0.243198514f, 0.244490802f, 0.255167097f, 0.258825988f, 0.257396817f, 0.256197631f, + 0.256865948f, 0.258354962f, 0.259370565f, 0.259730458f, 0.259894609f, 0.260285556f, 0.260970831f, 0.261650831f, 0.262020200f, + 0.262095064f, 0.262225062f, 0.262741268f, 0.263585031f, 0.264350951f, 0.264654577f, 0.264539272f, 0.264409125f, 0.264633715f, + 0.265172601f, 0.265621960f, 0.265678704f, 0.265469313f, 0.265454412f, 0.265907466f, 0.266625792f, 0.267101586f, 0.266997635f, + 0.266522497f, 0.266185820f, 0.266298562f, 0.266692907f, 0.266907692f +}; + +const float orange53_right_avg_power[257] = { + 0.999231100f, 0.992580175f, 0.969233215f, 0.925614893f, 0.871408045f, 0.826101780f, 0.803222895f, 0.800087631f, 0.802672029f, + 0.801490188f, 0.796555817f, 0.790879488f, 0.784882724f, 0.777585745f, 0.769326210f, 0.761789441f, 0.756145239f, 0.752754092f, + 0.751703024f, 0.752594173f, 0.754317880f, 0.755515277f, 0.754378498f, 0.748860359f, 0.738919020f, 0.727488697f, 0.718792558f, + 0.714865267f, 0.713446736f, 0.711076498f, 0.706021905f, 0.697553098f, 0.684623063f, 0.667031527f, 0.647006035f, 0.627680719f, + 0.609939933f, 0.592472672f, 0.574803054f, 0.558499217f, 0.544599831f, 0.532128096f, 0.520152628f, 0.509682238f, 0.501904130f, + 0.496162385f, 0.491121918f, 0.486813396f, 0.483951330f, 0.482198298f, 0.480713189f, 0.479654074f, 0.479590476f, 0.479965866f, + 0.479589254f, 0.478181243f, 0.476334095f, 0.474199444f, 0.471616089f, 0.469089746f, 0.467486322f, 0.466943622f, 0.467153549f, + 0.468381166f, 0.470996737f, 0.474416614f, 0.477639019f, 0.480612457f, 0.483910263f, 0.487287015f, 0.489909321f, 0.491668850f, + 0.493155539f, 0.494319856f, 0.494512051f, 0.493615031f, 0.492155492f, 0.490116775f, 0.486886710f, 0.482303619f, 0.476902038f, + 0.470775038f, 0.463377595f, 0.454571068f, 0.445130944f, 0.435581058f, 0.425568998f, 0.414717495f, 0.403531373f, 0.392556936f, + 0.381436378f, 0.369506508f, 0.357099295f, 0.345049500f, 0.333368897f, 0.321326375f, 0.308959186f, 0.297232091f, 0.286592871f, + 0.276453108f, 0.266589880f, 0.257950366f, 0.251341701f, 0.246435612f, 0.242861211f, 0.241405189f, 0.242839754f, 0.246688128f, + 0.252115428f, 0.259297341f, 0.268399984f, 0.278481483f, 0.288520366f, 0.298599035f, 0.308846802f, 0.318350822f, 0.326248646f, + 0.332813978f, 0.338464528f, 0.342543274f, 0.344278336f, 0.344031811f, 0.342641503f, 0.339995682f, 0.335437506f, 0.329174429f, + 0.322237372f, 0.315035462f, 0.306967229f, 0.297821850f, 0.288482070f, 0.279766560f, 0.271234214f, 0.262228251f, 0.253214896f, + 0.245183259f, 0.237939596f, 0.230546176f, 0.223051578f, 0.216552779f, 0.211263061f, 0.206180066f, 0.200917527f, 0.196485907f, + 0.193453044f, 0.190857053f, 0.187853232f, 0.185171053f, 0.183685005f, 0.182665780f, 0.180928215f, 0.178784713f, 0.177342966f, + 0.176323384f, 0.174430951f, 0.171496049f, 0.168740034f, 0.166518897f, 0.163711995f, 0.159658119f, 0.155442193f, 0.152056932f, + 0.148795277f, 0.144545168f, 0.139905334f, 0.136263832f, 0.133493021f, 0.130194828f, 0.126240104f, 0.123071767f, 0.121281922f, + 0.119557180f, 0.117016964f, 0.114773229f, 0.114072219f, 0.114103459f, 0.113414355f, 0.112460621f, 0.112842396f, 0.114564091f, + 0.115944758f, 0.116569765f, 0.117913686f, 0.120910525f, 0.124211200f, 0.126575813f, 0.128826424f, 0.132578567f, 0.137430578f, + 0.141675219f, 0.144987956f, 0.148879051f, 0.154273912f, 0.159992099f, 0.164641231f, 0.168560207f, 0.173201621f, 0.178906262f, + 0.184429348f, 0.188756809f, 0.192309171f, 0.196154252f, 0.200732291f, 0.205381230f, 0.209404662f, 0.212832779f, 0.216197237f, + 0.220162451f, 0.225029215f, 0.230637416f, 0.236752108f, 0.243243530f, 0.249900997f, 0.256293535f, 0.261716694f, 0.265186161f, + 0.265652657f, 0.262010813f, 0.253508776f, 0.243198514f, 0.244490802f, 0.255167097f, 0.258825988f, 0.257396817f, 0.256197631f, + 0.256865948f, 0.258354962f, 0.259370565f, 0.259730458f, 0.259894609f, 0.260285556f, 0.260970831f, 0.261650831f, 0.262020200f, + 0.262095064f, 0.262225062f, 0.262741268f, 0.263585031f, 0.264350951f, 0.264654577f, 0.264539272f, 0.264409125f, 0.264633715f, + 0.265172601f, 0.265621960f, 0.265678704f, 0.265469313f, 0.265454412f, 0.265907466f, 0.266625792f, 0.267101586f, 0.266997635f, + 0.266522497f, 0.266185820f, 0.266298562f, 0.266692907f, 0.266907692f +}; + +const float orange53_coherence[257] = { + 0.929530263f, 0.921171963f, 0.900268972f, 0.876067519f, 0.855227590f, 0.837884128f, 0.823401272f, 0.818804145f, 0.835025251f, + 0.871971071f, 0.911253273f, 0.929330528f, 0.921199203f, 0.900894165f, 0.882577479f, 0.867001534f, 0.849280477f, 0.832460761f, + 0.824062645f, 0.823441386f, 0.820908070f, 0.811902404f, 0.802339375f, 0.798648477f, 0.797345281f, 0.791158736f, 0.779512227f, + 0.768243194f, 0.760565042f, 0.754912853f, 0.751044095f, 0.752276063f, 0.759258866f, 0.766927004f, 0.769716740f, 0.767338514f, + 0.763358235f, 0.759508014f, 0.755201221f, 0.750362694f, 0.746060252f, 0.742611766f, 0.739434779f, 0.736354828f, 0.733443379f, + 0.730109870f, 0.726028502f, 0.722365141f, 0.720153689f, 0.718220115f, 0.714793265f, 0.710619092f, 0.708084404f, 0.707218647f, + 0.705624878f, 0.702472746f, 0.700073540f, 0.699947894f, 0.700519860f, 0.699934483f, 0.699344158f, 0.700895131f, 0.704551995f, + 0.708814025f, 0.713567019f, 0.719995975f, 0.728467822f, 0.738399088f, 0.749545693f, 0.761859894f, 0.774593413f, 0.787218869f, + 0.800481200f, 0.814727187f, 0.828367889f, 0.839860320f, 0.850490928f, 0.862034321f, 0.873037636f, 0.880097568f, 0.883217216f, + 0.885473788f, 0.887664974f, 0.886511028f, 0.880120754f, 0.871120989f, 0.862524390f, 0.853262126f, 0.840783834f, 0.825854301f, + 0.811407208f, 0.798167706f, 0.784307659f, 0.769172490f, 0.754072189f, 0.739893615f, 0.726129174f, 0.712544501f, 0.699519753f, + 0.686980069f, 0.674778104f, 0.663931608f, 0.655511260f, 0.648816824f, 0.642671287f, 0.638217211f, 0.637585819f, 0.640332758f, + 0.643755615f, 0.647433281f, 0.653589368f, 0.662824631f, 0.672268033f, 0.680022597f, 0.687623680f, 0.696763635f, 0.705829978f, + 0.712574661f, 0.717432320f, 0.721986175f, 0.725707173f, 0.727064371f, 0.726255059f, 0.724350274f, 0.720927835f, 0.715189219f, + 0.708206475f, 0.701428175f, 0.693923056f, 0.684313059f, 0.674107075f, 0.666009307f, 0.659245491f, 0.650998116f, 0.641600072f, + 0.634524226f, 0.630267978f, 0.625348687f, 0.618164837f, 0.611785769f, 0.608430445f, 0.605561733f, 0.600407422f, 0.594782710f, + 0.591767371f, 0.590365708f, 0.587845862f, 0.584915996f, 0.584355533f, 0.585834682f, 0.586913347f, 0.587935925f, 0.591403484f, + 0.596784472f, 0.601111054f, 0.604539037f, 0.610374093f, 0.618451059f, 0.624519289f, 0.627448440f, 0.631859899f, 0.639748096f, + 0.646256745f, 0.647378445f, 0.647664309f, 0.652599990f, 0.659044445f, 0.659743190f, 0.656243205f, 0.656651020f, 0.662200928f, + 0.664544880f, 0.660030127f, 0.656303048f, 0.659881413f, 0.664978266f, 0.662953973f, 0.657274961f, 0.658065319f, 0.665406108f, + 0.668446958f, 0.663809955f, 0.661349833f, 0.668595374f, 0.677367866f, 0.677208483f, 0.672289610f, 0.675831020f, 0.688208520f, + 0.695776582f, 0.691749871f, 0.687812865f, 0.696674168f, 0.711764693f, 0.716045380f, 0.706839681f, 0.701565385f, 0.711955190f, + 0.726487696f, 0.723370016f, 0.700417101f, 0.677427649f, 0.670733511f, 0.671355724f, 0.654210806f, 0.608316183f, 0.549225986f, + 0.504217446f, 0.484227657f, 0.475346446f, 0.452598959f, 0.399407327f, 0.319485664f, 0.229244962f, 0.146649837f, 0.083417825f, + 0.041744832f, 0.018142883f, 0.006854009f, 0.002511850f, 0.001177550f, 0.000840970f, 0.000701097f, 0.000571384f, 0.000458581f, + 0.000376965f, 0.000320562f, 0.000278847f, 0.000245546f, 0.000218281f, 0.000195632f, 0.000176647f, 0.000160827f, 0.000147978f, + 0.000137649f, 0.000129066f, 0.000121431f, 0.000114406f, 0.000108067f, 0.000102595f, 0.000097917f, 0.000093750f, 0.000089854f, + 0.000086255f, 0.000083183f, 0.000080804f, 0.000079026f, 0.000077552f, 0.000076117f, 0.000074693f, 0.000073431f, 0.000072456f, + 0.000071701f, 0.000071002f, 0.000070286f, 0.000069692f, 0.000069457f +}; + +/*----------------------------------------------------------------------------------* + * t-design and SN3D normalization table + *----------------------------------------------------------------------------------*/ + + /* SN3D norm */ +const float norm_sn3d_hoa3[16] = +{ + 1.f, 1.7320508f, 1.7320508f, 1.7320508f, 2.2360680f, 2.2360680f, 2.2360680f, 2.2360680f, + 2.2360680f, 2.6457512f, 2.6457512f, 2.6457512f, 2.6457512f, 2.6457512f, 2.6457512f, 2.6457512f +}; + +/* Order 11 t-design */ +const uint16_t t_design_11_size = 70; + +const float t_design_11_azimuth[70] = +{ + 1.329273e+02f, -8.393495e+01f, 8.474100e+00f, -1.133408e+02f, -1.032659e+02f, -3.323704e+01f, 2.185643e+01f, -1.565395e+02f, + -6.426475e+01f, 1.657795e+02f, -2.520283e+01f, -9.700380e+01f, 2.785464e+01f, 1.532142e+02f, -1.550616e+02f, -1.184214e+01f, + 8.053873e+01f, -4.205616e+01f, -3.122333e+01f, 3.883790e+01f, 9.376069e+01f, -8.475602e+01f, 7.755368e+00f, -1.222769e+02f, + 4.680127e+01f, -2.476863e+01f, 9.989047e+01f, -1.347840e+02f, -8.308802e+01f, 6.012817e+01f, 1.526447e+02f, 2.975767e+01f, + 4.077932e+01f, 1.101839e+02f, 1.656521e+02f, -1.299266e+01f, 7.973599e+01f, -5.052453e+01f, 1.189239e+02f, 4.722029e+01f, + 1.719253e+02f, -6.251458e+01f, -1.111567e+01f, 1.320180e+02f, -1.353555e+02f, 1.023709e+02f, 1.127393e+02f, -1.783050e+02f, + -1.223199e+02f, 5.907635e+01f, 1.517042e+02f, 2.137634e+01f, -1.690055e+02f, 1.189808e+02f, -1.160893e+02f, 9.647679e+00f, + 6.089332e+01f, -1.560215e+02f, -6.346030e+01f, 1.749298e+02f, -1.752888e+02f, -1.059519e+02f, -5.019283e+01f, 1.313583e+02f, + -1.362968e+02f, 9.356446e+01f, -9.708401e+01f, -1.691583e+02f, -4.413238e+01f, 8.147954e+01f +}; + +const float t_design_11_elevation[70] = +{ + 7.692547e+00f, -2.373007e+01f, 2.351276e+01f, 7.042259e+01f, -9.896944e+00f, -7.075133e+01f, -2.646185e+01f, 4.777649e+01f, + -7.720470e+00f, 4.453436e+01f, 2.638979e+01f, -4.465789e+01f, 9.767035e+00f, -4.770533e+01f, 7.453029e+00f, -2.359012e+01f, + 2.371945e+01f, 7.043827e+01f, -9.835416e+00f, -7.049808e+01f, -2.629492e+01f, 4.761480e+01f, -7.517185e+00f, 4.428623e+01f, + 2.664426e+01f, -4.456937e+01f, 9.912719e+00f, -4.795996e+01f, 7.296799e+00f, -2.334460e+01f, 2.364153e+01f, 7.068431e+01f, + -9.581404e+00f, -7.039345e+01f, -2.642582e+01f, 4.775107e+01f, -7.308536e+00f, 4.426328e+01f, 2.671406e+01f, -4.431497e+01f, + 9.758997e+00f, -4.803619e+01f, 7.439651e+00f, -2.333261e+01f, 2.338690e+01f, 7.082191e+01f, -9.485964e+00f, -7.058019e+01f, + -2.667403e+01f, 4.799784e+01f, -7.382762e+00f, 4.449706e+01f, 2.650250e+01f, -4.424619e+01f, 9.518451e+00f, -4.782814e+01f, + 7.684274e+00f, -2.357068e+01f, 2.330745e+01f, 7.065865e+01f, -9.680889e+00f, -7.080268e+01f, -2.669635e+01f, 4.801363e+01f, + -7.637348e+00f, 4.466512e+01f, 2.630235e+01f, -4.445764e+01f, 9.523415e+00f, -4.762422e+01f +}; + + +/*----------------------------------------------------------------------* +* Reverberator ROM tables +*-----------------------------------------------------------------------*/ + +const float ivas_reverb_default_fc[IVAS_REVERB_DEFAULT_N_BANDS] = +{ + 20.0f, 25.0f, 31.5f, 40.0f, + 50.0f, 63.0f, 80.0f, 100.0f, + 125.0f, 160.0f, 200.0f, 250.0f, + 315.0f, 400.0f, 500.0f, 630.0f, + 800.0f, 1000.0f, 1250.0f, 1600.0f, + 2000.0f, 2500.0f, 3150.0f, 4000.0f, + 5000.0f, 6300.0f, 8000.0f, 10000.0f, + 12500.0f, 16000.0f, 20000.0f +}; + +const float ivas_reverb_default_RT60[IVAS_REVERB_DEFAULT_N_BANDS] = +{ + 1.3622f, 1.4486f, 1.3168f, 1.5787f, + 1.4766f, 1.3954f, 1.2889f, 1.3462f, + 1.0759f, 1.0401f, 1.097f, 1.085f, + 1.091f, 1.0404f, 1.0499f, 1.0699f, + 1.1028f, 1.1714f, 1.1027f, 1.0666f, + 1.055f, 1.0553f, 1.0521f, 1.0569f, + 1.0421f, 0.97822f, 0.80487f, 0.75944f, + 0.71945f, 0.61682f, 0.60031f +}; + +const float ivas_reverb_default_DSR[IVAS_REVERB_DEFAULT_N_BANDS] = +{ + 1.8811e-08f, 2.1428e-08f, 1.3972e-08f, 1.51e-08f, + 1.287e-08f, 1.8747e-08f, 2.413e-08f, 3.9927e-08f, + 8.9719e-08f, 1.902e-07f, 3.702e-07f, 6.1341e-07f, + 7.1432e-07f, 6.5331e-07f, 4.6094e-07f, 5.4683e-07f, + 7.0134e-07f, 6.856e-07f, 7.114e-07f, 6.9604e-07f, + 5.2939e-07f, 5.699e-07f, 6.1773e-07f, 5.7488e-07f, + 4.7748e-07f, 2.7213e-07f, 1.3681e-07f, 1.0941e-07f, + 6.2001e-08f, 2.8483e-08f, 2.6267e-08f +}; + +/*----------------------------------------------------------------------------------* + * Renderer SBA & MC enc/dec matrices + *----------------------------------------------------------------------------------*/ + +/* CICP1 - Mono */ +const float ls_azimuth_CICP1[1] = { 0.0f }; +const float ls_elevation_CICP1[1] = { 0.0f }; +const uint32_t ls_LFE_last_idx_CICP1[1] = { 0 }; + +/* CICP2 - Stereo */ +const uint32_t ls_LFE_last_idx_CICP2[2] = { 0, 1 }; + +/* CICP6 - 5.1 */ +const uint32_t ls_LFE_last_idx_CICP6[6] = { 0, 1, 2, 4, 5, 3 }; + +/* CICP12 - 7.1 */ +const uint32_t ls_LFE_last_idx_CICP12[8] = { 0, 1, 2, 4, 5, 6, 7, 3 }; + +/* CICP14 - 5.1.2 */ +const uint32_t ls_LFE_last_idx_CICP14[8] = { 0, 1, 2, 4, 5, 6, 7, 3 }; + +/* CICP16 - 5.1.4 */ +const uint32_t ls_LFE_last_idx_CICP16[10] = { 0, 1, 2, 4, 5, 6, 7, 8, 9, 3 }; + +/* CICP19 - 7.1.4 */ +const uint32_t ls_LFE_last_idx_CICP19[12] = { 0, 1, 2, 4, 5, 6, 7, 8, 9, 10, 11, 3 }; + +/*----------------------------------------------------------------------------------* + * LS Renderer ROM tables + *----------------------------------------------------------------------------------*/ + + /* All matrices are stored with dimensions nchan_in x nchan_out */ + /* Downmix matrices */ +const float ls_conversion_cicpX_mono[12][1] = +{ +#ifdef EXT_RENDERER + {1.00000000f}, + {1.00000000f}, + {1.00000000f}, + {1.00000000f}, + {1.00000000f}, + {1.00000000f}, + {1.00000000f}, + {1.00000000f}, + {1.00000000f}, + {1.00000000f}, + {1.00000000f}, + {1.00000000f}, +#else + {1.00000000f}, + {1.00000000f}, + {0.70710677f}, + {0.70710677f}, + {0.79999995f}, + {0.79999995f}, + {0.79999995f}, + {0.79999995f}, + {0.849999964f}, + {0.849999964f}, + {0.849999964f}, + {0.849999964f} +#endif +}; + +const float ls_conversion_cicpX_stereo[12][2] = +{ + {1.00000000f, 0.00000000f}, + {0.00000000f, 1.00000000f}, + {0.70710677f, 0.70710677f}, + {0.70710677f, 0.70710677f}, + {0.79999995f, 0.00000000f}, + {0.00000000f, 0.79999995f}, + {0.79999995f, 0.00000000f}, + {0.00000000f, 0.79999995f}, + {0.849999964f, 0.000000000f}, + {0.000000000f, 0.849999964f}, + {0.849999964f, 0.000000000f}, + {0.000000000f, 0.849999964f} +}; + +const LS_CONVERSION_MATRIX ls_conversion_cicp12_cicp6[] = +{ + /* First row indicates the number of non-zero elements */ + {8, 0.0f}, + /* Index of non-zero element, value of non-zero element*/ + {0, 1.000000000f}, + {7, 1.000000000f}, + {14, 1.000000000f}, + {21, 1.000000000f}, + {28, 1.000000000f}, + {35, 1.000000000f}, + {40, 1.000000000f}, + {47, 1.000000000f} +}; + +const LS_CONVERSION_MATRIX ls_conversion_cicp14_cicp6[] = +{ + /* First row indicates the number of non-zero elements */ + {8, 0.0f}, + /* Index of non-zero element, value of non-zero element*/ + {0, 1.000000000f}, + {7, 1.000000000f}, + {14, 1.000000000f}, + {21, 1.000000000f}, + {28, 1.000000000f}, + {35, 1.000000000f}, + {36, 0.849999964f}, + {43, 0.849999964f} +}; + +#ifdef FIX_I54_LS_CONVERSION +const LS_CONVERSION_MATRIX ls_conversion_cicp14_cicp12[] = +{ + /* First row indicates the number of non-zero elements */ + {8, 0.0f}, + /* Index of non-zero element, value of non-zero element*/ + {0, 1.000000000f}, + {9, 1.000000000f}, + {18, 1.000000000f}, + {27, 1.000000000f}, + {36, 1.000000000f}, + {45, 1.000000000f}, + {48, 0.849999964f}, + {57, 0.849999964f} +}; +#endif + +const LS_CONVERSION_MATRIX ls_conversion_cicp16_cicp6[] = +{ + /* First row indicates the number of non-zero elements */ + {10, 0.0f}, + /* Index of non-zero element, value of non-zero element*/ + {0, 1.000000000f}, + {7, 1.000000000f}, + {14, 1.000000000f}, + {21, 1.000000000f}, + {28, 1.000000000f}, + {35, 1.000000000f}, + {36, 0.849999964f}, + {43, 0.849999964f}, + {52, 0.849999964f}, + {59, 0.849999964f} +}; + +const LS_CONVERSION_MATRIX ls_conversion_cicp16_cicp12[] = +{ + /* First row indicates the number of non-zero elements */ + {10, 0.0f}, + /* Index of non-zero element, value of non-zero element*/ + {0, 1.000000000f}, + {9, 1.000000000f}, + {18, 1.000000000f}, + {27, 1.000000000f}, + {36, 1.000000000f}, + {45, 1.000000000f}, + {48, 0.849999964f}, + {57, 0.849999964f}, + {68, 0.849999964f}, + {77, 0.849999964f} + +}; + +const LS_CONVERSION_MATRIX ls_conversion_cicp16_cicp14[] = +{ + /* First row indicates the number of non-zero elements */ + {10, 0.0f}, + /* Index of non-zero element, value of non-zero element*/ +#ifdef FIX_I54_LS_CONVERSION + {0, 1.000000000f}, + {9, 1.000000000f}, + {18, 1.000000000f}, + {27, 1.000000000f}, + {36, 1.000000000f}, + {45, 1.000000000f}, + {54, 1.000000000f}, + {63, 1.000000000f}, + {68, 0.849999964f}, + {77, 0.849999964f}, +#else + {0, 1.000000000f}, + {11, 1.000000000f}, + {22, 1.000000000f}, + {33, 1.000000000f}, + {44, 1.000000000f}, + {48, 0.849999964f}, + {55, 1.000000000f}, + {59, 0.849999964f}, + {66, 1.000000000f}, + {77, 1.000000000f}, +#endif +}; + +const LS_CONVERSION_MATRIX ls_conversion_cicp19_cicp6[] = +{ + /* First row indicates the number of non-zero elements */ + {14, 0.0f}, + /* Index of non-zero element, value of non-zero element*/ + {0, 1.000000000f}, + {7, 1.000000000f}, + {14, 1.000000000f}, + {21, 1.000000000f}, + {28, 1.000000000f}, + {35, 1.000000000f}, + {36, 0.367322683f}, + {40, 0.930093586f}, + {43, 0.367322683f}, + {47, 0.930093586f}, + {48, 0.849999964f}, + {55, 0.849999964f}, + {64, 0.849999964f}, + {71, 0.849999964f} +}; + +const LS_CONVERSION_MATRIX ls_conversion_cicp19_cicp12[] = +{ + /* First row indicates the number of non-zero elements */ + {14, 0.0f}, + /* Index of non-zero element, value of non-zero element*/ + {0, 1.000000000f}, + {9, 1.000000000f}, + {18, 1.000000000f}, + {27, 1.000000000f}, + {38, 1.000000000f}, + {47, 1.000000000f}, + {48, 0.367322683f}, + {52, 0.930093586f}, + {57, 0.367322683f}, + {61, 0.930093586f}, + {64, 0.849999964f}, + {73, 0.849999964f}, + {84, 0.849999964f}, + {93, 0.849999964f} +}; + +const LS_CONVERSION_MATRIX ls_conversion_cicp19_cicp14[] = +{ + /* First row indicates the number of non-zero elements */ + {14, 0.0f}, + /* Index of non-zero element, value of non-zero element*/ + {0, 1.000000000f}, + {9, 1.000000000f}, + {18, 1.000000000f}, + {27, 1.000000000f}, + {36, 1.000000000f}, + {45, 1.000000000f}, + {48, 0.367322683f}, + {52, 0.930093586f}, + {57, 0.367322683f}, + {61, 0.930093586f}, + {70, 1.000000000f}, + {79, 1.000000000f}, + {84, 0.849999964f}, + {93, 0.849999964f} +}; + +const LS_CONVERSION_MATRIX ls_conversion_cicp19_cicp16[] = +{ + /* First row indicates the number of non-zero elements */ + {14, 0.0f}, + /* Index of non-zero element, value of non-zero element*/ + {0, 1.000000000f}, + {11, 1.000000000f}, + {22, 1.000000000f}, + {33, 1.000000000f}, + {44, 1.000000000f}, + {55, 1.000000000f}, + {60, 0.367322683f}, + {64, 0.930093586f}, + {71, 0.367322683f}, + {75, 0.930093586f}, + {86, 1.000000000f}, + {97, 1.000000000f}, + {108, 1.000000000f}, + {119, 1.000000000f} +}; + +/* Upmix matrices */ +const LS_CONVERSION_MATRIX ls_conversion_cicp12_cicp14[] = +{ + /* First row indicates the number of non-zero elements */ + {8, 0.0f}, + /* Index of non-zero element, value of non-zero element*/ + {0, 1.0f}, + {9, 1.0f}, + {18, 1.0f}, + {27, 1.0f}, + {36, 1.0f}, + {45, 1.0f}, + {52, 1.0f}, + {61, 1.0f} +}; + +const LS_CONVERSION_MATRIX ls_conversion_cicp12_cicp16[] = +{ + /* First row indicates the number of non-zero elements */ + {8, 0.0f}, + /* Index of non-zero element, value of non-zero element*/ + {0, 1.0f}, + {11, 1.0f}, + {22, 1.0f}, + {33, 1.0f}, + {44, 1.0f}, + {55, 1.0f}, + {64, 1.0f}, + {75, 1.0f} +}; + +#ifdef FIX_I54_LS_CONVERSION +const LS_CONVERSION_MATRIX ls_conversion_cicp12_cicp19[] = +{ + /* First row indicates the number of non-zero elements */ + {8, 0.0f}, + /* Index of non-zero element, value of non-zero element*/ + {0, 1.0f}, + {13, 1.0f}, + {26, 1.0f}, + {39, 1.0f}, + {54, 1.0f}, + {67, 1.0f}, + {76, 1.0f}, + {89, 1.0f} +}; +#endif + +const LS_CONVERSION_MATRIX ls_conversion_cicp14_cicp19[] = +{ + /* First row indicates the number of non-zero elements */ + {8, 0.0f}, + /* Index of non-zero element, value of non-zero element*/ + {0, 1.0f}, + {13, 1.0f}, + {26, 1.0f}, + {39, 1.0f}, + {52, 1.0f}, + {65, 1.0f}, + {80, 1.0f}, + {93, 1.0f} +}; + +const LS_CONVERSION_MATRIX ls_conversion_cicp16_cicp19[] = +{ + /* First row indicates the number of non-zero elements */ + {10, 0.0f}, + /* Index of non-zero element, value of non-zero element*/ + {0, 1.0f}, + {13, 1.0f}, + {26, 1.0f}, + {39, 1.0f}, + {52, 1.0f}, + {65, 1.0f}, + {80, 1.0f}, + {93, 1.0f}, + {106, 1.0f}, + {119, 1.0f} +}; + +/* + * Mapping table of input config : output config with corresponding matrix + * NULL indicates a 1:1 mapping of existing input channels to output channels ( used for upmix ) + */ + +const LS_CONVERSION_MAPPING ls_conversion_mapping[LS_SETUP_CONVERSION_NUM_MAPPINGS] = +{ + /* Dowmix mappings - NULL is a special case for MONO / STEREO downmix */ +#ifdef EXT_RENDERER + {AUDIO_CONFIG_STEREO, AUDIO_CONFIG_MONO, NULL}, +#endif + {AUDIO_CONFIG_5_1, AUDIO_CONFIG_MONO, NULL}, + {AUDIO_CONFIG_7_1, AUDIO_CONFIG_MONO, NULL}, + {AUDIO_CONFIG_5_1_2, AUDIO_CONFIG_MONO, NULL}, + {AUDIO_CONFIG_5_1_4, AUDIO_CONFIG_MONO, NULL}, + {AUDIO_CONFIG_7_1_4, AUDIO_CONFIG_MONO, NULL}, + + {AUDIO_CONFIG_5_1, AUDIO_CONFIG_STEREO, NULL}, + {AUDIO_CONFIG_7_1, AUDIO_CONFIG_STEREO, NULL}, + {AUDIO_CONFIG_5_1_2, AUDIO_CONFIG_STEREO, NULL}, + {AUDIO_CONFIG_5_1_4, AUDIO_CONFIG_STEREO, NULL}, + {AUDIO_CONFIG_7_1_4, AUDIO_CONFIG_STEREO, NULL}, + + {AUDIO_CONFIG_7_1, AUDIO_CONFIG_5_1, ls_conversion_cicp12_cicp6}, + + {AUDIO_CONFIG_5_1_2, AUDIO_CONFIG_5_1, ls_conversion_cicp14_cicp6}, +#ifdef FIX_I54_LS_CONVERSION + {AUDIO_CONFIG_5_1_2, AUDIO_CONFIG_7_1, ls_conversion_cicp14_cicp12}, +#else + {AUDIO_CONFIG_5_1_2, AUDIO_CONFIG_7_1, ls_conversion_cicp14_cicp6}, +#endif + + {AUDIO_CONFIG_5_1_4, AUDIO_CONFIG_5_1, ls_conversion_cicp16_cicp6}, + {AUDIO_CONFIG_5_1_4, AUDIO_CONFIG_7_1, ls_conversion_cicp16_cicp12}, + {AUDIO_CONFIG_5_1_4, AUDIO_CONFIG_5_1_2, ls_conversion_cicp16_cicp14}, + + {AUDIO_CONFIG_7_1_4, AUDIO_CONFIG_5_1, ls_conversion_cicp19_cicp6}, + {AUDIO_CONFIG_7_1_4, AUDIO_CONFIG_7_1, ls_conversion_cicp19_cicp12}, + {AUDIO_CONFIG_7_1_4, AUDIO_CONFIG_5_1_2, ls_conversion_cicp19_cicp14}, + {AUDIO_CONFIG_7_1_4, AUDIO_CONFIG_5_1_4, ls_conversion_cicp19_cicp16}, + + /* Upmix mappings - NULL implies a 1:1 upmix */ +#ifdef EXT_RENDERER + {AUDIO_CONFIG_MONO, AUDIO_CONFIG_STEREO, NULL}, +#endif + {AUDIO_CONFIG_STEREO, AUDIO_CONFIG_5_1, NULL}, + {AUDIO_CONFIG_STEREO, AUDIO_CONFIG_7_1, NULL}, + {AUDIO_CONFIG_STEREO, AUDIO_CONFIG_5_1_2, NULL}, + {AUDIO_CONFIG_STEREO, AUDIO_CONFIG_5_1_4, NULL}, + {AUDIO_CONFIG_STEREO, AUDIO_CONFIG_7_1_4, NULL}, + + {AUDIO_CONFIG_5_1, AUDIO_CONFIG_7_1, NULL}, + {AUDIO_CONFIG_5_1, AUDIO_CONFIG_5_1_2, NULL}, + {AUDIO_CONFIG_5_1, AUDIO_CONFIG_5_1_4, NULL}, + {AUDIO_CONFIG_5_1, AUDIO_CONFIG_7_1_4, NULL}, + + {AUDIO_CONFIG_7_1, AUDIO_CONFIG_5_1_2, ls_conversion_cicp12_cicp14}, + {AUDIO_CONFIG_7_1, AUDIO_CONFIG_5_1_4, ls_conversion_cicp12_cicp16}, +#ifdef FIX_I54_LS_CONVERSION + {AUDIO_CONFIG_7_1, AUDIO_CONFIG_7_1_4, ls_conversion_cicp12_cicp19}, +#else + {AUDIO_CONFIG_7_1, AUDIO_CONFIG_7_1_4, NULL}, +#endif + + {AUDIO_CONFIG_5_1_2, AUDIO_CONFIG_5_1_4, NULL}, + {AUDIO_CONFIG_5_1_2, AUDIO_CONFIG_7_1_4, ls_conversion_cicp14_cicp19}, + + {AUDIO_CONFIG_5_1_4, AUDIO_CONFIG_7_1_4, ls_conversion_cicp16_cicp19}, +}; + +/* clang-format on */ diff --git a/lib_rend/ivas_rom_rend.h b/lib_rend/ivas_rom_rend.h new file mode 100644 index 0000000000..166e417692 --- /dev/null +++ b/lib_rend/ivas_rom_rend.h @@ -0,0 +1,141 @@ +/****************************************************************************************************** + + (C) 2022 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_ROM_REND_H +#define IVAS_ROM_REND_H + +#include +#include "options.h" +#ifdef DEBUGGING +#include "debug.h" +#endif +#include "ivas_cnst.h" +#include "ivas_stat_rend.h" + +/*----------------------------------------------------------------------------------* + * FASTCONV and PARAMETRIC binaural renderer ROM tables + *----------------------------------------------------------------------------------*/ + +extern const float dmxmtx[BINAURAL_CHANNELS][11]; + +extern const int16_t channelIndex_CICP6[5]; +extern const int16_t channelIndex_CICP12[7]; +extern const int16_t channelIndex_CICP14[7]; +extern const int16_t channelIndex_CICP16[9]; +extern const int16_t channelIndex_CICP19[11]; + +/*----------------------------------------------------------------------------------* + * TD ISM Object renderer + *----------------------------------------------------------------------------------*/ + +extern const int16_t TDREND_SRC_REND_MaxTargetTimes[IVAS_NUM_SUPPORTED_FS]; +extern const int16_t TDREND_SRC_REND_MaxBlockLengths[IVAS_NUM_SUPPORTED_FS]; +extern const int16_t TDREND_MaxITD[IVAS_NUM_SUPPORTED_FS]; +extern const float TDREND_MaxITD_Incr[IVAS_NUM_SUPPORTED_FS]; + +extern const int16_t HRTF_MODEL_N_CPTS_VAR[HRTF_MODEL_N_SECTIONS]; + +extern const float SincTable[321]; + +extern const float orange53_left_avg_power[257]; +extern const float orange53_right_avg_power[257]; +extern const float orange53_coherence[257]; + + +/*----------------------------------------------------------------------------------* + * t-design and SN3D normalization table + *----------------------------------------------------------------------------------*/ + +/* SN3D norm */ +extern const float norm_sn3d_hoa3[16]; + +/* Order 11 t-design */ +extern const uint16_t t_design_11_size; +extern const float t_design_11_azimuth[70]; +extern const float t_design_11_elevation[70]; + + +/*----------------------------------------------------------------------* + * Reverberator ROM tables + *-----------------------------------------------------------------------*/ + +extern const float ivas_reverb_default_fc[]; +extern const float ivas_reverb_default_RT60[]; +extern const float ivas_reverb_default_DSR[]; + +/*----------------------------------------------------------------------------------* + * Renderer SBA & MC enc/dec matrices + *----------------------------------------------------------------------------------*/ + +extern const float hoa_dec_mtx_CICP1[16]; +extern const float ls_azimuth_CICP1[1]; +extern const float ls_elevation_CICP1[1]; +extern const uint32_t ls_LFE_last_idx_CICP1[1]; +extern const uint32_t ls_LFE_last_idx_CICP2[2]; +extern const uint32_t ls_LFE_last_idx_CICP6[6]; +extern const uint32_t ls_LFE_last_idx_CICP12[8]; +extern const uint32_t ls_LFE_last_idx_CICP14[8]; +extern const uint32_t ls_LFE_last_idx_CICP16[10]; +extern const uint32_t ls_LFE_last_idx_CICP19[12]; + +/*----------------------------------------------------------------------------------* + * LS Configuration Converter ROM tables + *----------------------------------------------------------------------------------*/ + +/* Downmix matrices */ +extern const float ls_conversion_cicpX_mono[12][1]; +extern const float ls_conversion_cicpX_stereo[12][2]; +extern const LS_CONVERSION_MATRIX ls_conversion_cicp12_cicp6[]; +extern const LS_CONVERSION_MATRIX ls_conversion_cicp14_cicp6[]; +#ifdef FIX_I54_LS_CONVERSION +extern const LS_CONVERSION_MATRIX ls_conversion_cicp14_cicp12[]; +#endif +extern const LS_CONVERSION_MATRIX ls_conversion_cicp16_cicp6[]; +extern const LS_CONVERSION_MATRIX ls_conversion_cicp16_cicp14[]; +extern const LS_CONVERSION_MATRIX ls_conversion_cicp19_cicp6[]; +extern const LS_CONVERSION_MATRIX ls_conversion_cicp19_cicp12[]; +extern const LS_CONVERSION_MATRIX ls_conversion_cicp19_cicp14[]; +extern const LS_CONVERSION_MATRIX ls_conversion_cicp19_cicp16[]; + +/* Upmix matrices */ +extern const LS_CONVERSION_MATRIX ls_conversion_cicp12_cicp14[]; +extern const LS_CONVERSION_MATRIX ls_conversion_cicp12_cicp16[]; +#ifdef FIX_I54_LS_CONVERSION +extern const LS_CONVERSION_MATRIX ls_conversion_cicp12_cicp19[]; +#endif +extern const LS_CONVERSION_MATRIX ls_conversion_cicp14_cicp19[]; +extern const LS_CONVERSION_MATRIX ls_conversion_cicp16_cicp19[]; + +/* Mapping table of input config : output config with corresponding matrix */ +extern const LS_CONVERSION_MAPPING ls_conversion_mapping[]; + +#endif /* IVAS_ROM_REND_H */ diff --git a/lib_dec/ivas_rotation.c b/lib_rend/ivas_rotation.c similarity index 98% rename from lib_dec/ivas_rotation.c rename to lib_rend/ivas_rotation.c index 77809d8270..d141025ab6 100644 --- a/lib_dec/ivas_rotation.c +++ b/lib_rend/ivas_rotation.c @@ -322,11 +322,19 @@ void rotateFrame_shd( /* 1ms linear crossfade */ fade_len_smp = NS2SA( output_fs, 1000000 ); +#ifdef EXT_RENDERER + tmp = 1.0f / (fade_len_smp - 1); + for ( i = 0; i < fade_len_smp; i++ ) + { + cross_fade[i] = i * tmp; + } +#else tmp = 1.0f / fade_len_smp; for ( i = 0; i < fade_len_smp; i++ ) { cross_fade[i] = ( i + 1 ) * tmp; } +#endif /* initialize rotation matrices with zeros */ for ( i = 0; i < HEADROT_SHMAT_DIM; i++ ) @@ -442,11 +450,19 @@ void rotateFrame_sd( /* 1ms linear crossfade */ fade_len_smp = NS2SA( output_Fs, 1000000 ); +#ifdef EXT_RENDERER + tmp = 1.0f / (fade_len_smp - 1); + for ( i = 0; i < fade_len_smp; i++ ) + { + cross_fade[i] = i * tmp; + } +#else tmp = 1.0f / fade_len_smp; for ( i = 0; i < fade_len_smp; i++ ) { cross_fade[i] = ( i + 1 ) * tmp; } +#endif /* Get next quaternion and calculate rotation matrix */ QuatToRotMat( hHeadTrackData->Quaternions[hHeadTrackData->num_quaternions++], hHeadTrackData->Rmat ); @@ -473,7 +489,11 @@ void rotateFrame_sd( /* gains for previous subframe rotation */ rotateAziEle( hTransSetup.ls_azimuth[ch_in_woLFE], hTransSetup.ls_elevation[ch_in_woLFE], &azimuth, &elevation, hHeadTrackData->Rmat_prev, hTransSetup.is_planar_setup ); +#ifdef EXT_RENDERER + if ( hEFAPdata != NULL && ( hTransSetup.ls_azimuth[ch_in_woLFE] != azimuth || hTransSetup.ls_elevation[ch_in_woLFE] != elevation ) ) +#else if ( hEFAPdata != NULL && ( hTransSetup.ls_azimuth[ch_in_woLFE] != azimuth && hTransSetup.ls_elevation[ch_in_woLFE] != elevation ) ) +#endif { efap_determine_gains( hEFAPdata, tmp_gains, azimuth, elevation, EFAP_MODE_EFAP ); for ( ch_out = 0; ch_out < nchan; ch_out++ ) diff --git a/lib_rend/ivas_sba_rendering.c b/lib_rend/ivas_sba_rendering.c new file mode 100644 index 0000000000..1e8b61caca --- /dev/null +++ b/lib_rend/ivas_sba_rendering.c @@ -0,0 +1,584 @@ +/****************************************************************************************************** + + (C) 2022 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_stat_dec.h" +#include "ivas_cnst.h" +#ifdef DEBUGGING +#include "debug.h" +#endif +#include "wmops.h" + + +/*-----------------------------------------------------------------------* + * Local function prototypes + *-----------------------------------------------------------------------*/ + +static void ivas_sba_mtx_mult( float output_f[][L_FRAME48k], const int16_t output_frame, const int16_t nchan_in, IVAS_OUTPUT_SETUP output_setup, const float *mtx_hoa_decoder ); +static void ivas_sba_dmx_dec( float sba_data[][L_FRAME48k], const int16_t nchan_transport, const int16_t output_frame ); + +#ifdef DEBUG_MODE_DIRAC +static void debug_mode_dirac( float output[MAX_OUTPUT_CHANNELS][L_FRAME48k], const int16_t nchan_transport, const int16_t output_frame ); +#endif + + +/*-------------------------------------------------------------------------* + * ivas_mc2sba() + * + * MC signals transformed into SBA in TD domain + *-------------------------------------------------------------------------*/ + +void ivas_mc2sba( + IVAS_OUTPUT_SETUP hIntSetup, /* i : Format of decoder output */ + float buffer_td[][L_FRAME48k], /* i/o: MC signals (on input) and the HOA3 (on output) */ + const int16_t output_frame, /* i : output frame length per channel */ + const int16_t sba_order, /* i : Ambisonic (SBA) order */ + const float gain_lfe /* i : gain for LFE, 0 = ignore LFE */ +) +{ + int16_t i, j, k; + int16_t idx_lfe, idx_in; + float buffer_tmp[16][L_FRAME48k]; + float gains[16]; + int16_t azimuth, elevation; + int16_t sba_num_chans; + + assert( ( sba_order <= 3 ) && "Only order up to 3 is supported!" ); + + /* 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 ); + } + + /* HOA encoding*/ + idx_lfe = 0; + idx_in = 0; + for ( i = 0; i < hIntSetup.nchan_out_woLFE + hIntSetup.num_lfe; i++ ) + { + if ( ( hIntSetup.num_lfe > 0 ) && ( i == hIntSetup.index_lfe[idx_lfe] ) ) + { + if ( gain_lfe > 0.f ) + { + /* Add LFE to omni W with gain*/ + for ( k = 0; k < output_frame; k++ ) + { + buffer_tmp[0][k] += gain_lfe * buffer_td[i][k]; + } + } + + if ( idx_lfe < ( hIntSetup.num_lfe - 1 ) ) + { + idx_lfe++; + } + } + else + { + azimuth = (int16_t) ( hIntSetup.ls_azimuth[idx_in] ); + elevation = (int16_t) ( hIntSetup.ls_elevation[idx_in] ); + idx_in++; + + /* get HOA response for direction (ACN/SN3D)*/ + ivas_dirac_dec_get_response( + azimuth, + elevation, + gains, + sba_order ); + + for ( j = 0; j < sba_num_chans; j++ ) + { + for ( k = 0; k < output_frame; k++ ) + { + buffer_tmp[j][k] += gains[j] * buffer_td[i][k]; + } + } + } + } + + for ( j = 0; j < sba_num_chans; j++ ) + { + mvr2r( buffer_tmp[j], buffer_td[j], output_frame ); + } + + return; +} + + +/*-------------------------------------------------------------------------* + * ivas_sba2MC_cldfb() + * + * SBA signals transformed into MC in CLDFB domain + *-------------------------------------------------------------------------*/ + +void ivas_sba2mc_cldfb( + IVAS_OUTPUT_SETUP hInSetup, /* i : Format of input layout */ + float RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i/o: cldfb real part */ + float ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i/o: cldfb imag part */ + const int16_t nb_channels_out, /* i : nb of output channels */ + const int16_t nb_bands, /* i : nb of CLDFB bands to process */ + const float *hoa_dec_mtx /* i : hoa decoding mtx */ +) +{ + int16_t iBlock, iBand, n, m; + float realOut[16][MAX_PARAM_SPATIAL_SUBFRAMES * CLDFB_NO_CHANNELS_MAX], imagOut[16][MAX_PARAM_SPATIAL_SUBFRAMES * CLDFB_NO_CHANNELS_MAX]; + float g; + float *p_real, *p_imag, *p_realOut, *p_imagOut; + int16_t nb_channels_in; + + wmops_sub_start( "ivas_sba2mc_cldfb" ); + + nb_channels_in = hInSetup.nchan_out_woLFE; + assert( ( nb_channels_in == 16 ) && ( nb_channels_out == 11 ) && "ivas_sba2mc_cldfb; only HOA3 to CICP19 is for now supported!" ); + + for ( n = 0; n < nb_channels_out; n++ ) + { + set_zero( realOut[n], MAX_PARAM_SPATIAL_SUBFRAMES * nb_bands ); + set_zero( imagOut[n], MAX_PARAM_SPATIAL_SUBFRAMES * nb_bands ); + + for ( m = 0; m < nb_channels_in; m++ ) + { + g = hoa_dec_mtx[SBA_NHARM_HOA3 * n + m]; + p_realOut = realOut[n]; + p_imagOut = imagOut[n]; + for ( iBlock = 0; iBlock < MAX_PARAM_SPATIAL_SUBFRAMES; iBlock++ ) + { + p_real = RealBuffer[m][iBlock]; + p_imag = ImagBuffer[m][iBlock]; + for ( iBand = 0; iBand < nb_bands; iBand++ ) + { + *p_realOut = *p_realOut + g * *( p_real++ ); + *p_imagOut = *p_imagOut + g * *( p_imag++ ); + p_realOut++; + p_imagOut++; + } + } + } + } + + for ( n = 0; n < nb_channels_out; n++ ) + { + p_realOut = realOut[n]; + p_imagOut = imagOut[n]; + for ( iBlock = 0; iBlock < MAX_PARAM_SPATIAL_SUBFRAMES; iBlock++ ) + { + p_real = RealBuffer[n][iBlock]; + p_imag = ImagBuffer[n][iBlock]; + for ( iBand = 0; iBand < nb_bands; iBand++ ) + { + *( p_real++ ) = *p_realOut++; + *( p_imag++ ) = *p_imagOut++; + } + } + } + + wmops_sub_end(); + + return; +} + +/*-------------------------------------------------------------------* + * ivas_sba_remapTCs() + * + * Get TCs from Ambisonics signal in ACN + *-------------------------------------------------------------------*/ + +int16_t ivas_sba_remapTCs( + float sba_data[][L_FRAME48k], /* i/o: SBA signals */ + Decoder_Struct *st_ivas, /* i/o: decoder struct */ + const int16_t output_frame /* i : frame length */ +) +{ + 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 ( ( st_ivas->sba_mode != SBA_MODE_SPAR && st_ivas->sba_planar && nchan_remapped >= 3 ) || + ( ( st_ivas->sba_mode == SBA_MODE_SPAR ) && nchan_remapped == 3 ) ) + { + + nchan_remapped++; + if ( st_ivas->sba_mode != SBA_MODE_SPAR ) + { + assert( ( ( st_ivas->nchan_transport == 3 ) || ( st_ivas->nchan_transport == 5 ) || ( st_ivas->nchan_transport == 7 ) ) && "Number of channels must be odd for sba planar!" ); + } + + if ( nchan_remapped == 4 ) + { + /*For planar A-format channel 2 and 3 are identical -> Z=0*/ + mvr2r( sba_data[2], sba_data[3], output_frame ); + } + } + + if ( st_ivas->sba_mode == SBA_MODE_SPAR ) + { + int16_t i = 0; + float temp; + + if ( st_ivas->nchan_transport >= 3 ) + { + /*convert WYXZ downmix to WYZX*/ + for ( i = 0; i < output_frame; i++ ) + { + temp = sba_data[2][i]; + sba_data[2][i] = sba_data[3][i]; + sba_data[3][i] = temp; + if ( st_ivas->nchan_transport == 3 ) + { + sba_data[2][i] = 0; + } + } + } + } + else + { + ivas_sba_dmx_dec( sba_data, nchan_remapped, output_frame ); + } + + if ( st_ivas->sba_mode != SBA_MODE_SPAR ) + { + ivas_sba_zero_vert_comp( sba_data, st_ivas->sba_order, st_ivas->sba_planar, output_frame ); + } + return ( nchan_remapped ); +} + + +/*-------------------------------------------------------------------* + * ivas_sba_dmx_dec() + * + * + *-------------------------------------------------------------------*/ + +static void ivas_sba_dmx_dec( + float sba_data[][L_FRAME48k], /* i : SBA signals */ + const int16_t nchan_transport, /* i : number of transport channels */ + const int16_t output_frame /* i : frame length */ +) +{ + int16_t i; + float tmp_f[DIRAC_MAX_TRANS_CHANS]; + + if ( nchan_transport >= 7 ) + { + for ( i = 0; i < output_frame; i++ ) + { + tmp_f[0] = 0.506415f * sba_data[0][i] + 0.506415f * sba_data[1][i] + 0.506415f * sba_data[2][i] + 0.506415f * sba_data[3][i] + 0.506415f * sba_data[4][i] + 0.506415f * sba_data[5][i] + 0.506415f * sba_data[6][i]; + tmp_f[1] = -0.000000f * sba_data[0][i] + 0.531020f * sba_data[1][i] + 0.662171f * sba_data[2][i] + 0.294694f * sba_data[3][i] + -0.294694f * sba_data[4][i] + -0.662171f * sba_data[5][i] + -0.531020f * sba_data[6][i]; + tmp_f[2] = 0.679200f * sba_data[0][i] + 0.423475f * sba_data[1][i] + -0.151136f * sba_data[2][i] + -0.611938f * sba_data[3][i] + -0.611938f * sba_data[4][i] + -0.151136f * sba_data[5][i] + 0.423475f * sba_data[6][i]; + tmp_f[3] = 0.000000f * sba_data[0][i] + 0.833385f * sba_data[1][i] + -0.370891f * sba_data[2][i] + -0.668323f * sba_data[3][i] + 0.668323f * sba_data[4][i] + 0.370891f * sba_data[5][i] + -0.833385f * sba_data[6][i]; + tmp_f[4] = 0.854817f * sba_data[0][i] + -0.190215f * sba_data[1][i] + -0.770164f * sba_data[2][i] + 0.532970f * sba_data[3][i] + 0.532970f * sba_data[4][i] + -0.770164f * sba_data[5][i] + -0.190215f * sba_data[6][i]; + tmp_f[5] = 0.000000f * sba_data[0][i] + 0.691125f * sba_data[1][i] + -1.245365f * sba_data[2][i] + 1.552944f * sba_data[3][i] + -1.552944f * sba_data[4][i] + 1.245365f * sba_data[5][i] + -0.691125f * sba_data[6][i]; + tmp_f[6] = 1.592881f * sba_data[0][i] + -1.435137f * sba_data[1][i] + 0.993145f * sba_data[2][i] + -0.354449f * sba_data[3][i] + -0.354449f * sba_data[4][i] + 0.993145f * sba_data[5][i] + -1.435137f * sba_data[6][i]; + + sba_data[0][i] = tmp_f[0]; + sba_data[1][i] = tmp_f[1]; + sba_data[2][i] = sba_data[7][i]; + sba_data[3][i] = tmp_f[2]; + sba_data[4][i] = tmp_f[3]; + sba_data[8][i] = tmp_f[4]; + sba_data[9][i] = tmp_f[5]; + sba_data[15][i] = tmp_f[6]; + } + + return; + } + else if ( nchan_transport >= 5 ) + { + for ( i = 0; i < output_frame; i++ ) + { + tmp_f[0] = 0.708982f * sba_data[0][i] + 0.708982f * sba_data[1][i] + 0.708982f * sba_data[2][i] + 0.708982f * sba_data[3][i] + 0.708982f * sba_data[4][i]; + tmp_f[1] = 0.000000f * sba_data[0][i] + 1.005966f * sba_data[1][i] + 0.621721f * sba_data[2][i] + -0.621721f * sba_data[3][i] + -1.005966f * sba_data[4][i]; + tmp_f[2] = 1.057735f * sba_data[0][i] + 0.326858f * sba_data[1][i] + -0.855726f * sba_data[2][i] + -0.855726f * sba_data[3][i] + 0.326858f * sba_data[4][i]; + tmp_f[3] = 0.000000f * sba_data[0][i] + 1.079884f * sba_data[1][i] + -1.747289f * sba_data[2][i] + 1.747289f * sba_data[3][i] + -1.079884f * sba_data[4][i]; + tmp_f[4] = 1.837208f * sba_data[0][i] + -1.486333f * sba_data[1][i] + 0.567729f * sba_data[2][i] + 0.567729f * sba_data[3][i] + -1.486333f * sba_data[4][i]; + + sba_data[0][i] = tmp_f[0]; + sba_data[1][i] = tmp_f[1]; + sba_data[2][i] = sba_data[5][i]; + sba_data[3][i] = tmp_f[2]; + sba_data[4][i] = tmp_f[3]; + sba_data[8][i] = tmp_f[4]; + } + + return; + } + else if ( nchan_transport >= 3 ) + { + + /*A-format to ACN/SN3D*/ + for ( i = 0; i < output_frame; i++ ) + { + tmp_f[0] = 0.5f * ( sba_data[0][i] + sba_data[1][i] + sba_data[2][i] + sba_data[3][i] ); + tmp_f[1] = sba_data[0][i] - sba_data[1][i]; + tmp_f[2] = sba_data[2][i] - sba_data[3][i]; + tmp_f[3] = sba_data[0][i] + sba_data[1][i] - sba_data[2][i] - sba_data[3][i]; + + sba_data[0][i] = tmp_f[0]; + sba_data[1][i] = tmp_f[1]; + sba_data[2][i] = tmp_f[2]; + sba_data[3][i] = tmp_f[3]; + } + + return; + } + else if ( nchan_transport == 2 ) + { + /* do nothing for stereo DMX, upmix done in DirAC*/ + return; + } + else if ( nchan_transport == 1 ) + { + /* do nothing; simply use omni */ + return; + } + else + { + assert( 0 && "SBA: number of transport channels not supported." ); + } +} + + +/*-------------------------------------------------------------------------* + * ivas_ism2sba() + * + * ISM transformed into SBA in TD domain. + *-------------------------------------------------------------------------*/ + +void ivas_ism2sba( + float buffer_td[][L_FRAME48k], /* i/o: TD signal buffers */ + ISM_RENDERER_HANDLE hIsmRendererData, /* i/o: renderer data */ + const ISM_METADATA_HANDLE hIsmMetaData[], /* i : object metadata */ + const int16_t num_objects, /* 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 < num_objects; i++ ) + { + azimuth = (int16_t) ( hIsmMetaData[i]->azimuth + 0.5f ); + elevation = (int16_t) ( 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++ ) + { + g2 = 0.f; + for ( k = 0; k < output_frame; k++ ) + { + g2 += 1.f / output_frame; + g1 = 1.0f - g2; + buffer_tmp[j][k] += ( g2 * gains[j] + g1 * hIsmRendererData->prev_gains[i][j] ) * buffer_td[i][k]; + } + 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; +} + +/*-------------------------------------------------------------------* + * ivas_sba_linear_renderer() + * + * Linear rendering for SBA format + *-------------------------------------------------------------------*/ + +ivas_error ivas_sba_linear_renderer( + float output_f[][L_FRAME48k], /* i/o: synthesized core-coder transport channels/DirAC output */ + const int16_t output_frame, /* i : output frame length per channel */ + const int16_t nchan_in, /* i : number of input ambisonics channels */ + const AUDIO_CONFIG output_config, /* i : output audio configuration */ + const IVAS_OUTPUT_SETUP output_setup, /* i : output format setup */ + const float hoa_dec_mtx[] /* i : hoa decoding mtx */ +) +{ + int16_t i; + float dmx_l; + int16_t nchan_hoa; + ivas_error error; + + error = IVAS_ERR_OK; + + /* Number of channels of HOA depends of transport format which is mixed order xH1V*/ + nchan_hoa = nchan_in; + + if ( nchan_in == 6 ) /*2H1V*/ + { + nchan_hoa = 9; + } + else if ( nchan_in == 8 ) /*3H1V*/ + { + nchan_hoa = 16; + } + + switch ( output_config ) + { + case AUDIO_CONFIG_MONO: + /* If stereo DMX, MONO = W = Cardioids L + R*/ + if ( nchan_in == 2 ) + { + for ( i = 0; i < output_frame; i++ ) + { + output_f[0][i] += output_f[1][i]; + } + } + /* else: do nothing, MONO = W*/ + break; + case AUDIO_CONFIG_STEREO: + assert( ( nchan_in >= 2 ) && "Number of input channels must be at least 2 (for W and Y)!\n" ); + + /* Compute L and R cardioids from SB format except if stereo DMX is transmitted already in this format*/ + if ( nchan_in > 2 ) + { + /*Build L/R cardioids*/ + for ( i = 0; i < output_frame; i++ ) + { + dmx_l = 0.5f * ( output_f[0][i] + output_f[1][i] ); /* cardioid_left = 0.5(W + Y) */ + output_f[1][i] = 0.5f * ( output_f[0][i] - output_f[1][i] ); /* cardioid_right = 0.5(W - Y) */ + output_f[0][i] = dmx_l; + } + } + break; + case AUDIO_CONFIG_5_1: + case AUDIO_CONFIG_7_1: + case AUDIO_CONFIG_5_1_2: + case AUDIO_CONFIG_5_1_4: + case AUDIO_CONFIG_7_1_4: + case AUDIO_CONFIG_LS_CUSTOM: + ivas_sba_mtx_mult( output_f, output_frame, nchan_hoa, output_setup, hoa_dec_mtx ); + break; + case AUDIO_CONFIG_FOA: /* Ambisonics output, order: 1 */ + case AUDIO_CONFIG_HOA2: /* Ambisonics output, order: 2 */ + case AUDIO_CONFIG_HOA3: /* Ambisonics output, order: 3 */ + for ( i = nchan_hoa; i < output_setup.nchan_out_woLFE; i++ ) + { + set_zero( output_f[i], output_frame ); + } + break; + default: + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Error: illegal output configuration, Exiting.\n" ); + } + + return error; +} + + +/*-------------------------------------------------------------------* + * ivas_sba_mtx_mult() + * + * HOA decoding with LFE insertion + *-------------------------------------------------------------------*/ + +static void ivas_sba_mtx_mult( + float output_f[][L_FRAME48k], /* i/o: synthesized core-coder transport channels/DirAC output */ + const int16_t output_frame, /* i : output frame length per channel */ + const int16_t nchan_in, /* i : Number of ambisonic channels */ + IVAS_OUTPUT_SETUP output_setup, /* i : Output configuration */ + const float *mtx_hoa_decoder /* i : Hoa decoding mtx */ +) +{ + int16_t i, k, ch_idx; + int16_t idx_lfe; + float input_f[16]; + const float *hoa_decoder; + + assert( ( nchan_in >= FOA_CHANNELS ) && "Number of input channels must be at least 4 (FOA)!\n" ); + + for ( i = 0; i < output_frame; i++ ) + { + /* init*/ + idx_lfe = 0; + hoa_decoder = &mtx_hoa_decoder[0]; + for ( k = 0; k < nchan_in; k++ ) + { + input_f[k] = output_f[k][i]; + } + + /* mtx mult with LFE insertion*/ + for ( ch_idx = 0; ch_idx < ( output_setup.nchan_out_woLFE + output_setup.num_lfe ); ch_idx++ ) + { + if ( ( output_setup.num_lfe > 0 ) && ( output_setup.index_lfe[idx_lfe] == ch_idx ) ) + { + /*LFE insertion*/ + output_f[ch_idx][i] = 0.f; + if ( idx_lfe < ( output_setup.num_lfe - 1 ) ) + { + idx_lfe++; + } + } + else + { + /*HOA decoding*/ + output_f[ch_idx][i] = input_f[0] * hoa_decoder[0]; + for ( k = 1; k < nchan_in; k++ ) + { + output_f[ch_idx][i] += input_f[k] * hoa_decoder[k]; + } + hoa_decoder += 16; + } + } + } + + return; +} diff --git a/lib_util/ivas_rom_prerenderer.c b/lib_rend/ivas_stat_rend.h similarity index 51% rename from lib_util/ivas_rom_prerenderer.c rename to lib_rend/ivas_stat_rend.h index 4342116577..7c4841a08a 100644 --- a/lib_util/ivas_rom_prerenderer.c +++ b/lib_rend/ivas_stat_rend.h @@ -30,33 +30,64 @@ *******************************************************************************************************/ -#include "ivas_rom_prerenderer.h" -#include "wmops.h" +#ifndef IVAS_STAT_REND_H +#define IVAS_STAT_REND_H + +#include +#include "ivas_cnst.h" -/* clang-format off */ /*----------------------------------------------------------------------------------* - * Prerenderer SBA & MC enc/dec matrices + * Loudspeaker Configuration Conversion structure *----------------------------------------------------------------------------------*/ -/* CICP1 - Mono */ -const float ls_azimuth_CICP1[1] = { 0.0f }; -const float ls_elevation_CICP1[1] = { 0.0f }; -const uint32_t ls_LFE_last_idx_CICP1[1] = { 0 }; +typedef struct ivas_LS_setupconversion_struct +{ + float *dmxMtx[MAX_OUTPUT_CHANNELS]; + float *targetEnergyPrev[MAX_OUTPUT_CHANNELS]; + float *dmxEnergyPrev[MAX_OUTPUT_CHANNELS]; + int16_t sfbOffset[MAX_SFB + 2]; + int16_t sfbCnt; + +} LSSETUP_CONVERSION_STRUCT, *LSSETUP_CONVERSION_HANDLE; + + +typedef struct ivas_LS_setupconversion_matrix +{ + int16_t index; + float value; +} LS_CONVERSION_MATRIX; -/* CICP2 - Stereo */ -const uint32_t ls_LFE_last_idx_CICP2[2] = { 0, 1 }; +typedef struct ivas_LS_setupconversion_mapping +{ + AUDIO_CONFIG input_config; + AUDIO_CONFIG output_config; + const LS_CONVERSION_MATRIX *conversion_matrix; +} LS_CONVERSION_MAPPING; -/* CICP6 - 5.1 */ -const uint32_t ls_LFE_last_idx_CICP6[6] = { 0, 1, 2, 4, 5, 3 }; +typedef struct ivas_mono_downmix_renderer_struct +{ + float inputEnergy[CLDFB_NO_CHANNELS_MAX]; + float protoEnergy[CLDFB_NO_CHANNELS_MAX]; -/* CICP12 - 7.1 */ -const uint32_t ls_LFE_last_idx_CICP12[8] = { 0, 1, 2, 4, 5, 6, 7, 3 }; +} MONO_DOWNMIX_RENDERER_STRUCT, *MONO_DOWNMIX_RENDERER_HANDLE; + + +/*----------------------------------------------------------------------------------* + * Custom Loudspeaker configuration structure + *----------------------------------------------------------------------------------*/ -/* CICP16 - 5.1.4 */ -const uint32_t ls_LFE_last_idx_CICP16[10] = { 0, 1, 2, 4, 5, 6, 7, 8, 9, 3 }; +typedef struct ivas_LS_setup_custom +{ + int16_t is_planar_setup; /* flag to indicate if setup is planar or not */ + int16_t num_spk; /* number of custom loudspeakers */ + float ls_azimuth[MAX_OUTPUT_CHANNELS]; /* custom loudspeaker azimuths */ + float ls_elevation[MAX_OUTPUT_CHANNELS]; /* custom loudspeaker elevations */ + int16_t num_lfe; /* number of LFE channels */ + int16_t lfe_idx[MAX_OUTPUT_CHANNELS]; /* index for LFE channel insertion */ + int16_t separate_ch_found; /* flag to indicate if a center channel was found */ + float separate_ch_gains[MAX_OUTPUT_CHANNELS]; /* gains to pan McMASA separateChannel in case no center channel is present */ -/* CICP19 - 7.1.4 */ -const uint32_t ls_LFE_last_idx_CICP19[12] = { 0, 1, 2, 4, 5, 6, 7, 8, 9, 10, 11, 3 }; +} LSSETUP_CUSTOM_STRUCT, *LSSETUP_CUSTOM_HANDLE; -/* clang-format on */ +#endif /* IVAS_STAT_REND_H */ diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c new file mode 100644 index 0000000000..2d568e8837 --- /dev/null +++ b/lib_rend/lib_rend.c @@ -0,0 +1,2672 @@ +/****************************************************************************************************** + + (C) 2022 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_rend.h" +#include "ivas_prot.h" +#include "ivas_rom_com.h" +#include "ivas_rom_dec.h" +#include "ivas_rom_rend.h" +#include "prot.h" +#include "wmops.h" + +#include +#include +#include +#include +#include + + +#define LIMITER_THRESHOLD 0.9988493699f /* -0.01 dBFS */ + +/* Due to API of some rendering methods, the renderer has to use the decoder struct. + Only struct members relevant for rendering will be initialized, therefore typedef as "dummy" decoder struct */ +typedef Decoder_Struct DecoderDummy; + +struct IVAS_REND +{ + int32_t sampleRate; + + int8_t isConfigured; /* flag */ + int8_t firstFrame; /* flag */ + + /* I/O */ + IVAS_REND_InputConfig inConfig; + IVAS_REND_OutputConfig outConfig; + + /* =========== Panning =========== */ + EFAP_HANDLE efapRenderer; + + IVAS_REND_ObjPanInfo *objPanInfo; /* size: [numInObjects] */ + + float ***speakerPanGains; /* size: [numInMc][numSpeakers][numOutChannels] */ + + float *tmpGainBuffer; /* size: [numOutChannels] */ + float *noLfePanBuffer; /* size: [numOutChannels] */ + float *crossfade; /* size: [frameSize] */ + /* =============================== */ + + /* Helpers */ + int16_t numOutChannels; /* Total number of output channels */ + int16_t numInChannels; /* Total number of input channels */ + int16_t numInChannelsObj; /* Total number of input channels of object inputs */ + int16_t numInChannelsAmbi; /* Total number of input channels of ambisonics inputs */ + int16_t numInChannelsMc; /* Total number of input channels of multichannel inputs */ + + /* For each channel of MC inputs mcPassThrough contains the corresponding + * output channel index if a passthrough is possible, otherwise contains -1 */ + int32_t *mcPassthrough; /* size: [numInChannelsMc] */ + + /* =========== LFE Handling =========== */ + /* Do not drop LFE when rendering to a layout that does not have + * an LFE channel - render LFE into other channels*/ + int8_t neverDropLfe; /* flag */ + float *lfePanGains; + ivas_filters_process_state_t lfeLpFilter; + + /* =========== limiter handle =========== */ + IVAS_LIMITER_HANDLE hLimiter; + + /* Ambisonics decoding matrix */ + float *ambi_dec_mtx; + + /* Dummy decoders for binaural rendering */ + DecoderDummy *decDummyAmbiBin; + DecoderDummy *decDummyObjBin; + DecoderDummy *decDummyMcBin; + + /* Head rotation data */ + int8_t enableHeadRotation; /* head rotation flag */ + IVAS_QUATERNION headRotationData[RENDERER_HEAD_POSITIONS_PER_FRAME]; +}; + +/*---------------------------------------------------------------------* + * Prototypes + *---------------------------------------------------------------------*/ +/* clang-off */ +static void renderAmbiToAmbi( + const IVAS_REND_HANDLE st, + const IVAS_REND_AudioBuffer inAudio, + IVAS_REND_AudioBuffer outAudio ); + +static void renderChannelsToAmbi( + IVAS_REND_HANDLE st, + const IVAS_REND_AudioBuffer inAudio, + IVAS_REND_AudioBuffer outAudio ); + +static void renderObjectsToAmbi( + IVAS_REND_HANDLE st, + const IVAS_REND_AudioBuffer inAudio, + const IVAS_REND_AudioObjectMetadataBuffer metadataBuffer, + IVAS_REND_AudioBuffer outAudio ); + +static void renderAmbiToChannels( + const IVAS_REND_HANDLE st, + const IVAS_REND_AudioBuffer inAudio, + IVAS_REND_AudioBuffer outAudio ); + +static void renderChannelsToChannels( + const IVAS_REND_HANDLE st, + const IVAS_REND_AudioBuffer inAudio, + IVAS_REND_AudioBuffer outAudio ); + +static void renderObjectsToChannels( + IVAS_REND_HANDLE st, + const IVAS_REND_AudioBuffer inAudio, + const IVAS_REND_AudioObjectMetadataBuffer metadataBuffer, + IVAS_REND_AudioBuffer outAudio ); + +static void renderAmbiToBinaural( + const IVAS_REND_HANDLE st, + const IVAS_REND_AudioBuffer inAudio, + IVAS_REND_AudioBuffer outAudio ); + +static void renderChannelsToBinaural( + const IVAS_REND_HANDLE st, + const IVAS_REND_AudioBuffer inAudio, + IVAS_REND_AudioBuffer outAudio ); + +static void renderObjectsToBinaural( + IVAS_REND_HANDLE st, + const IVAS_REND_AudioBuffer inAudio, + const IVAS_REND_AudioObjectMetadataBuffer metadataBuffer, + IVAS_REND_AudioBuffer outAudio ); + +static void renderSingleObjectToAmbi( + IVAS_REND_HANDLE st, + const IVAS_REND_AudioBuffer inAudio, + const uint32_t itemChnlIdx, /* Index of the item within input audio buffer */ + IVAS_REND_ObjPanInfo *prevPanInfo, + const IVAS_REND_AudioObjectPosition curFrmPos, + const float gain_lin, + IVAS_REND_AudioBuffer outAudio ); + +static void renderSingleObjectToChannels( + IVAS_REND_HANDLE st, + const IVAS_REND_AudioBuffer inAudio, + const uint32_t itemChnlIdx, /* Index of the item within input audio buffer */ + IVAS_REND_ObjPanInfo *prevPanInfo, + const IVAS_REND_AudioObjectPosition curFrmPos, + const float gain_lin, + IVAS_REND_AudioBuffer outAudio ); + +/* Multiply a single channel by a vector of gains and add result to corresponding output channels */ +static void applyChannelGainsAndAddToOutput( + const IVAS_REND_AudioBuffer inAudio, + const uint32_t itemChnlIdx, /* Index of the item within input audio buffer */ + const float *const gainsCurrent, /* Vector of gains for current frame, corresponding to output channels */ + const float *const gainsPrev, /* Vector of previously applied gains, used for interpolation. Set to NULL for no interpolation */ + const float gain_lin, /* Additional linear gain to be applied when mixing with output buffer */ + const float *const crossfade, + IVAS_REND_AudioBuffer outAudio ); + +static void prepareMcPanGains( + IVAS_REND_HANDLE st ); + +static void prepareLfeHandling( + IVAS_REND_HANDLE st ); + +static void prepareMcPassthrough( + IVAS_REND_HANDLE st ); + +static void passthroughChannel( + const IVAS_REND_AudioBuffer inAudio, + const uint32_t srcChnlIdx, + const uint32_t dstChnlIdx, + const float gain_lin, + IVAS_REND_AudioBuffer outAudio ); + +static void getSpeakerGains( + const IVAS_REND_HANDLE st, + const float azi, + const float ele, + float *const spkGains ); + +static int16_t getNumChannelsAmbisonics( + IVAS_REND_Ambisonics ambisonics ); + +static int16_t getAmbisonicsOrder( + IVAS_REND_Ambisonics ambisonics ); + +static int16_t getNumChannelsInSpeakerLayout( + IVAS_REND_SpeakerLayout layout ); + +static int16_t getNumNonLfeChannelsInSpeakerLayout( + IVAS_REND_SpeakerLayout layout ); + +static const float *getSpeakerAzimuths( + IVAS_REND_SpeakerLayout layout ); + +static const float *getSpeakerElevations( + IVAS_REND_SpeakerLayout layout ); + +static const uint32_t *getReorderedChannelIndices( + IVAS_REND_SpeakerLayout layout ); + +static int32_t reverseChannelIndexMapping( int32_t originalChannelIndex, + const uint32_t *channelReorderingMap, + uint32_t numNonLfeSpeakers ); + +static ivas_error getHoaRenderMtx( + const IVAS_REND_OutputConfig outConfig, + float **decMtx, + uint32_t ambiOrder ); + +static void getHoaDecVecForAmbiChnl( + uint32_t ambiChnnlIdx, + const IVAS_REND_OutputConfig outConfig, + const float *decMtx, + float *decCoeffs ); + +static void ivas_limiter_renderer( + 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 */ +); + +static float dBToLin( const float gain_dB ); + +static AUDIO_CONFIG mapRendLayoutToAudioConfig( + IVAS_REND_SpeakerLayout speakerLayout ); + +/* clang-on */ +/* ========================================================================== */ + +static IVAS_QUATERNION quaternionInit( void ) +{ + IVAS_QUATERNION q; + q.w = 1.0f; + q.x = q.y = q.z = 0.0f; + return q; +} + +IVAS_REND_HANDLE IVAS_REND_Open() +{ + int16_t i; + IVAS_REND_HANDLE st; + + st = (IVAS_REND_HANDLE) count_malloc( sizeof( struct IVAS_REND ) ); + st->isConfigured = 0; + st->efapRenderer = NULL; + + st->objPanInfo = NULL; + st->speakerPanGains = NULL; + st->tmpGainBuffer = NULL; + st->noLfePanBuffer = NULL; + st->crossfade = NULL; + st->mcPassthrough = NULL; + st->neverDropLfe = 0; + st->lfePanGains = NULL; + st->hLimiter = NULL; + st->ambi_dec_mtx = NULL; + st->decDummyAmbiBin = NULL; + st->decDummyMcBin = NULL; + st->decDummyObjBin = NULL; + st->enableHeadRotation = 0; + + for ( i = 0; i < RENDERER_HEAD_POSITIONS_PER_FRAME; ++i ) + { + st->headRotationData[i] = quaternionInit(); + } + + return st; +} + +static DecoderDummy *allocDecoderDummy( int32_t sampleRate, int16_t numOutChannels, const uint8_t enableHeadRotation ) +{ + int16_t i; + DecoderDummy *decDummy; + + decDummy = count_malloc( sizeof( DecoderDummy ) ); + decDummy->hDecoderConfig = count_malloc( sizeof( DECODER_CONFIG ) ); + decDummy->hDecoderConfig->output_Fs = sampleRate; + decDummy->hDecoderConfig->nchan_out = numOutChannels; + + ivas_render_config_open( &decDummy->hRenderConfig ); + decDummy->hRenderConfig->roomAcoustics.late_reverb_on = 0; + decDummy->hRenderConfig->roomAcoustics.use_brir = 0; + + if ( enableHeadRotation ) + { + decDummy->hHeadTrackData = count_malloc( sizeof( HEAD_TRACK_DATA ) ); + /* Initialise Rmat_prev to I, Rmat will be computed later */ + for ( i = 0; i < 3; i++ ) + { + set_zero( decDummy->hHeadTrackData->Rmat_prev[i], 3 ); + decDummy->hHeadTrackData->Rmat_prev[i][i] = 1.0f; + } + + decDummy->hHeadTrackData->num_quaternions = 0; + decDummy->hHeadTrackData->lrSwitchInterpVal = 0.0f; + decDummy->hHeadTrackData->lrSwitchedCurrent = 0; + decDummy->hHeadTrackData->lrSwitchedNext = 0; + } + else + { + decDummy->hHeadTrackData = NULL; + } + + decDummy->renderer_type = RENDERER_DISABLE; + + return decDummy; +} + +static ivas_error initDecoderDummyForAmbiToBinaural( DecoderDummy *decDummyAmbiBin, IVAS_REND_InputConfig inConfig ) +{ + ivas_error error; + assert( inConfig.numAmbisonicsBuses == 1 && "For now only 1 ambisonics input is supported" ); + + error = IVAS_ERR_OK; + + decDummyAmbiBin->renderer_type = RENDERER_BINAURAL_MIXER_CONV; + decDummyAmbiBin->hHrtf = NULL; + decDummyAmbiBin->hBinRenderer = NULL; + decDummyAmbiBin->intern_config = decDummyAmbiBin->transport_config = + inConfig.ambisonicsBuses[0].ambisonicsConfig == IVAS_REND_AMBISONICS_FOA ? AUDIO_CONFIG_FOA + : inConfig.ambisonicsBuses[0].ambisonicsConfig == IVAS_REND_AMBISONICS_SOA ? AUDIO_CONFIG_HOA2 + : inConfig.ambisonicsBuses[0].ambisonicsConfig == IVAS_REND_AMBISONICS_TOA ? AUDIO_CONFIG_HOA3 + : AUDIO_CONFIG_INVALID; + + ivas_output_init( &decDummyAmbiBin->hIntSetup, decDummyAmbiBin->intern_config ); + ivas_output_init( &decDummyAmbiBin->hTransSetup, decDummyAmbiBin->transport_config ); + + if ( ( error = ivas_crend_open( decDummyAmbiBin ) ) != IVAS_ERR_OK ) + { + return error; + } + + return error; +} + +static ivas_error initDecoderDummyForObjToBinaural( DecoderDummy *decDummyObjBin, IVAS_REND_InputConfig inConfig ) +{ + ivas_error error; + int32_t n; + + assert( inConfig.numAudioObjects <= MAX_NUM_OBJECTS && "IVAS decoder is used for binaural rendering, which limits number of objects" ); + + error = IVAS_ERR_OK; + + decDummyObjBin->renderer_type = RENDERER_BINAURAL_OBJECTS_TD; + decDummyObjBin->hHrtfTD = NULL; + decDummyObjBin->hBinRenderer = NULL; + decDummyObjBin->ivas_format = ISM_FORMAT; + decDummyObjBin->nSCE = inConfig.numAudioObjects; + decDummyObjBin->nchan_transport = inConfig.numAudioObjects; + + for ( n = 0; n < inConfig.numAudioObjects; ++n ) + { + decDummyObjBin->hIsmMetaData[n] = count_malloc( sizeof( ISM_METADATA_FRAME ) ); + } + for ( n = inConfig.numAudioObjects; n < MAX_NUM_OBJECTS; ++n ) + { + decDummyObjBin->hIsmMetaData[n] = NULL; + } + + if ( ( error = ivas_td_binaural_open( decDummyObjBin ) ) != IVAS_ERR_OK ) + { + return error; + } + + return error; +} + +static ivas_error initDecoderDummyForMcToBinaural( DecoderDummy *decDummyMcBin, IVAS_REND_InputConfig inConfig, const uint8_t enableHeadRotation ) +{ + ivas_error error; + IVAS_REND_SpeakerLayout spkLayout; + + assert( inConfig.numMultiChannelBuses == 1 && "For now supporting one multichannel input" ); + + error = IVAS_ERR_OK; + + decDummyMcBin->hHrtf = NULL; + decDummyMcBin->hHrtfTD = NULL; + decDummyMcBin->hBinRenderer = NULL; + decDummyMcBin->ivas_format = MC_FORMAT; + decDummyMcBin->mc_mode = MC_MODE_MCT; + + spkLayout = inConfig.multiChannelBuses[0].speakerLayout; + + switch ( spkLayout ) + { + case IVAS_REND_SPEAKER_LAYOUT_5_1: + decDummyMcBin->intern_config = decDummyMcBin->transport_config = AUDIO_CONFIG_5_1; + break; + case IVAS_REND_SPEAKER_LAYOUT_7_1: + decDummyMcBin->intern_config = decDummyMcBin->transport_config = AUDIO_CONFIG_7_1; + break; + case IVAS_REND_SPEAKER_LAYOUT_5_1_2: + decDummyMcBin->intern_config = decDummyMcBin->transport_config = AUDIO_CONFIG_5_1_2; + break; + case IVAS_REND_SPEAKER_LAYOUT_5_1_4: + decDummyMcBin->intern_config = decDummyMcBin->transport_config = AUDIO_CONFIG_5_1_4; + break; + case IVAS_REND_SPEAKER_LAYOUT_7_1_4: + decDummyMcBin->intern_config = decDummyMcBin->transport_config = AUDIO_CONFIG_7_1_4; + break; + case IVAS_REND_SPEAKER_LAYOUT_CUSTOM: + decDummyMcBin->intern_config = decDummyMcBin->transport_config = AUDIO_CONFIG_LS_CUSTOM; + break; + default: + assert( false && "Not supported yet" ); + break; + } + + if ( spkLayout == IVAS_REND_SPEAKER_LAYOUT_CUSTOM ) + { + decDummyMcBin->nchan_transport = inConfig.inSetupCustom->num_spk + inConfig.inSetupCustom->num_lfe; + + ivas_ls_custom_setup( &decDummyMcBin->hIntSetup, inConfig.inSetupCustom ); + ivas_ls_custom_setup( &decDummyMcBin->hTransSetup, inConfig.inSetupCustom ); + } + else + { + decDummyMcBin->nchan_transport = getNumChannelsInSpeakerLayout( spkLayout ); + + ivas_output_init( &decDummyMcBin->hIntSetup, decDummyMcBin->intern_config ); + ivas_output_init( &decDummyMcBin->hTransSetup, decDummyMcBin->transport_config ); + } + + + if ( enableHeadRotation && ( ( error = efap_init_data( &decDummyMcBin->hEFAPdata, decDummyMcBin->hTransSetup.ls_azimuth, decDummyMcBin->hTransSetup.ls_elevation, decDummyMcBin->hTransSetup.nchan_out_woLFE, EFAP_MODE_EFAP ) ) != IVAS_ERR_OK ) ) + { + return error; + } + + /* Use TD binaural renderer only for 5_1 and 7_1 with headrotation or Custom LS */ + if ( spkLayout == IVAS_REND_SPEAKER_LAYOUT_CUSTOM || + ( ( spkLayout == IVAS_REND_SPEAKER_LAYOUT_5_1 || spkLayout == IVAS_REND_SPEAKER_LAYOUT_7_1 ) && enableHeadRotation ) ) + { + decDummyMcBin->renderer_type = RENDERER_BINAURAL_OBJECTS_TD; + decDummyMcBin->hCrend = NULL; + if ( ( error = ivas_td_binaural_open( decDummyMcBin ) ) != IVAS_ERR_OK ) + { + return error; + } + } + else + { + decDummyMcBin->renderer_type = RENDERER_BINAURAL_MIXER_CONV; + decDummyMcBin->hBinRendererTd = NULL; + if ( ( error = ivas_crend_open( decDummyMcBin ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + return error; +} + +ivas_error IVAS_REND_Configure( IVAS_REND_HANDLE st, + const IVAS_REND_InputConfig inConfig, + const IVAS_REND_OutputConfig outConfig, + uint32_t sampleRate, + bool headRotationEnabled ) +{ + uint32_t i; + int32_t j; + ivas_error error; + uint8_t numActiveOutputs; + int32_t frameSize_smpls; + + error = IVAS_ERR_OK; + + /* ============================= Error checks ============================= */ + assert( st != NULL && "Can't configure renderer - pointer is NULL" ); + assert( !st->isConfigured && "Re-configuring a renderer is not supported" ); + assert( !( inConfig.numAudioObjects == 0 && inConfig.numMultiChannelBuses == 0 && inConfig.numAmbisonicsBuses == 0 ) && "At least one input must be active" ); + + numActiveOutputs = + ( outConfig.ambisonics == IVAS_REND_AMBISONICS_NONE ? 0 : 1 ) + + ( outConfig.speakerLayout == IVAS_REND_SPEAKER_LAYOUT_NONE ? 0 : 1 ) + + ( outConfig.binaural == 0 ? 0 : 1 ); + assert( numActiveOutputs == 1 && "Only one output must be selected" ); + + /* ========================== Store useful values ========================= */ + st->sampleRate = sampleRate; + st->isConfigured = 1; + st->firstFrame = 1; + st->inConfig = inConfig; + st->outConfig = outConfig; + + /* Save total number of channels in ambisonics inputs */ + st->numInChannelsAmbi = 0; + for ( i = 0; i < inConfig.numAmbisonicsBuses; ++i ) + { + st->numInChannelsAmbi += getNumChannelsAmbisonics( inConfig.ambisonicsBuses[i].ambisonicsConfig ); + } + + /* Save total number of channels in MC input */ + st->numInChannelsMc = 0; + for ( i = 0; i < inConfig.numMultiChannelBuses; ++i ) + { + if ( inConfig.multiChannelBuses[i].speakerLayout == IVAS_REND_SPEAKER_LAYOUT_CUSTOM ) + { + st->numInChannelsMc += inConfig.inSetupCustom->num_spk + inConfig.inSetupCustom->num_lfe; + } + else + { + st->numInChannelsMc += getNumChannelsInSpeakerLayout( inConfig.multiChannelBuses[i].speakerLayout ); + } + } + + + /* Save total number of channels of audio object inputs */ + st->numInChannelsObj = st->inConfig.numAudioObjects; + + /* Save total number of input channels */ + st->numInChannels = st->numInChannelsObj + st->numInChannelsAmbi + st->numInChannelsMc; + + if ( st->outConfig.ambisonics != IVAS_REND_AMBISONICS_NONE ) + { + /* Save number of output channels */ + st->numOutChannels = getNumChannelsAmbisonics( st->outConfig.ambisonics ); + } + else if ( st->outConfig.binaural ) + { + st->numOutChannels = 2; + } + + /* ============================ Prepare panning and ambisonics =========================== */ + if ( st->outConfig.speakerLayout != IVAS_REND_SPEAKER_LAYOUT_NONE ) + { + if ( st->outConfig.speakerLayout == IVAS_REND_SPEAKER_LAYOUT_CUSTOM ) + { + /* Save number of output channels */ + st->numOutChannels = st->outConfig.outSetupCustom->num_spk + st->outConfig.outSetupCustom->num_lfe; + + /* Open and initialize EFAP struct */ + if ( ( error = efap_init_data( &st->efapRenderer, st->outConfig.outSetupCustom->ls_azimuth, st->outConfig.outSetupCustom->ls_elevation, st->outConfig.outSetupCustom->num_spk, EFAP_MODE_EFAP ) ) != IVAS_ERR_OK ) + { + return error; + } + } + else + { + /* Save number of output channels */ + st->numOutChannels = getNumChannelsInSpeakerLayout( st->outConfig.speakerLayout ); + + /* Open and initialize EFAP struct */ + if ( ( error = efap_init_data( &st->efapRenderer, getSpeakerAzimuths( st->outConfig.speakerLayout ), getSpeakerElevations( st->outConfig.speakerLayout ), getNumNonLfeChannelsInSpeakerLayout( st->outConfig.speakerLayout ), EFAP_MODE_EFAP ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + + assert( st->efapRenderer != NULL && "Could not init EFAP" ); + + /* Compute Ambisonics to loudspeaker decoding matrix */ + if ( ( error = getHoaRenderMtx( st->outConfig, &st->ambi_dec_mtx, 3 ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + /* Allocate temporary pan/enc buffer to avoid allocations during rendering */ + st->tmpGainBuffer = count_calloc( st->numOutChannels, sizeof( float ) ); + + /* Allocate temporary buffer for panning gains with lfe omitted */ + if ( st->outConfig.speakerLayout != IVAS_REND_SPEAKER_LAYOUT_NONE ) + { + if ( st->outConfig.speakerLayout == IVAS_REND_SPEAKER_LAYOUT_CUSTOM ) + { + st->noLfePanBuffer = count_calloc( st->outConfig.outSetupCustom->num_spk, sizeof( float ) ); + } + else + { + st->noLfePanBuffer = count_calloc( getNumNonLfeChannelsInSpeakerLayout( st->outConfig.speakerLayout ), sizeof( float ) ); + } + } + + /* Create lookup tables for panning/encoding speaker signals */ + if ( st->inConfig.numMultiChannelBuses != 0 ) + { + prepareMcPanGains( st ); + prepareLfeHandling( st ); + } + + /* Allocate structs for interpolation of object pan/enc gains between frames */ + if ( st->inConfig.numAudioObjects != 0 ) + { + st->objPanInfo = count_calloc( st->inConfig.numAudioObjects, sizeof( IVAS_REND_ObjPanInfo ) ); + + for ( i = 0; i < st->inConfig.numAudioObjects; ++i ) + { + st->objPanInfo[i].panGains = count_calloc( st->numOutChannels, sizeof( float ) ); + } + } + + if ( st->outConfig.binaural ) + { + if ( headRotationEnabled ) + { + st->enableHeadRotation = 1; + } + + if ( st->inConfig.numAmbisonicsBuses != 0 ) + { + st->decDummyAmbiBin = allocDecoderDummy( st->sampleRate, st->numOutChannels, st->enableHeadRotation ); + if ( ( error = initDecoderDummyForAmbiToBinaural( st->decDummyAmbiBin, st->inConfig ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + if ( st->inConfig.numMultiChannelBuses != 0 ) + { + st->decDummyMcBin = allocDecoderDummy( st->sampleRate, st->numOutChannels, st->enableHeadRotation ); + if ( ( error = initDecoderDummyForMcToBinaural( st->decDummyMcBin, st->inConfig, st->enableHeadRotation ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + if ( st->inConfig.numAudioObjects != 0 ) + { + st->decDummyObjBin = allocDecoderDummy( st->sampleRate, st->numOutChannels, st->enableHeadRotation ); + if ( ( error = initDecoderDummyForObjToBinaural( st->decDummyObjBin, st->inConfig ) ) != IVAS_ERR_OK ) + { + return error; + } + } + } + + /* =========================== Prepare crossfades ========================= */ + frameSize_smpls = sampleRate / FRAMES_PER_SEC; + st->crossfade = count_calloc( frameSize_smpls, sizeof( float ) ); + + for ( j = 0; j < frameSize_smpls; ++j ) + { + st->crossfade[j] = (float) j / ( frameSize_smpls - 1 ); + } + + /* ========================= Prepare optimizations ======================== */ + /* Make note of possible processing shortcuts in cases where input and output + * config is the same or similar. This only needs to be done for MC I/O, since + * Ambisonics I/O can always be passed through and objects can never be passed + * through */ + if ( st->inConfig.numMultiChannelBuses > 0 && st->outConfig.speakerLayout != IVAS_REND_SPEAKER_LAYOUT_NONE ) + { + prepareMcPassthrough( st ); + } + + /* ============================ Configure limiter =========================== */ + st->hLimiter = ivas_limiter_open( st->numOutChannels, st->sampleRate ); + + return error; +} + +void IVAS_REND_SetHeadRotation( + IVAS_REND_HANDLE st, + const IVAS_QUATERNION headRot[RENDERER_HEAD_POSITIONS_PER_FRAME] ) +{ + int16_t i; + + assert( st != NULL ); + + for ( i = 0; i < RENDERER_HEAD_POSITIONS_PER_FRAME; ++i ) + { + st->headRotationData[i] = headRot[i]; + } +} + +void IVAS_REND_Render( + IVAS_REND_HANDLE st, + const IVAS_REND_AudioBuffer inAudio, + const IVAS_REND_AudioObjectMetadataBuffer metadataBuffer, + IVAS_REND_AudioBuffer outAudio ) +{ +#ifdef WMOPS + wmops_sub_start( "IVAS_REND_Render" ); +#endif + + /* ============================= Error checks ============================= */ + assert( st != NULL && "Can't render - renderer pointer is NULL" ); + assert( st->isConfigured && "Can't render - renderer pointer is not configured" ); + assert( inAudio.config.sampleRate == outAudio.config.sampleRate && "Input and output sample rate must be the same" ); + assert( inAudio.config.bufferSize == outAudio.config.bufferSize && "Input and output frame size must be the same" ); + assert( inAudio.config.numChannels == st->numInChannels && "Number of input channels does not match between renderer and input config" ); + assert( outAudio.config.numChannels == st->numOutChannels && "Number of input channels does not match between renderer and input config" ); + assert( inAudio.config.sampleRate != 0 && "Invalid sample rate" ); + assert( inAudio.config.bufferSize != 0 && "Invalid frame size" ); + assert( inAudio.data != NULL && "Can't render - input buffer is empty" ); + + /* ========================== Actual processing =========================== */ + /* Clear output buffer */ + set_zero( outAudio.data, outAudio.config.numChannels * outAudio.config.bufferSize ); + + /* Render target format: Ambisonics */ + if ( st->outConfig.ambisonics != IVAS_REND_AMBISONICS_NONE ) + { + if ( st->inConfig.numAmbisonicsBuses != 0 ) + { + renderAmbiToAmbi( st, inAudio, outAudio ); + } + + if ( st->inConfig.numMultiChannelBuses != 0 ) + { + renderChannelsToAmbi( st, inAudio, outAudio ); + } + + if ( st->inConfig.numAudioObjects != 0 ) + { + renderObjectsToAmbi( st, inAudio, metadataBuffer, outAudio ); + } + } /* Render target format: multichannel */ + else if ( st->outConfig.speakerLayout != IVAS_REND_SPEAKER_LAYOUT_NONE ) + { + if ( st->inConfig.numAmbisonicsBuses != 0 ) + { + renderAmbiToChannels( st, inAudio, outAudio ); + } + + if ( st->inConfig.numMultiChannelBuses != 0 ) + { + renderChannelsToChannels( st, inAudio, outAudio ); + } + + if ( st->inConfig.numAudioObjects != 0 ) + { + renderObjectsToChannels( st, inAudio, metadataBuffer, outAudio ); + } + } /* Render target format: binaural */ + else if ( st->outConfig.binaural ) + { + /* Rendering to binaural using dummy IVAS decoders */ + assert( inAudio.config.bufferSize == st->sampleRate / FRAMES_PER_SEC && "Using IVAS components requires frame size of 20 ms" ); + assert( inAudio.config.numChannels <= MAX_OUTPUT_CHANNELS && "Max 16 input channels supported" ); + assert( outAudio.config.numChannels == 2 && "2 output channels expected for rendering to binaural" ); + + if ( st->inConfig.numAmbisonicsBuses != 0 ) + { + renderAmbiToBinaural( st, inAudio, outAudio ); + } + + if ( st->inConfig.numMultiChannelBuses != 0 ) + { + renderChannelsToBinaural( st, inAudio, outAudio ); + } + + if ( st->inConfig.numAudioObjects != 0 ) + { + renderObjectsToBinaural( st, inAudio, metadataBuffer, outAudio ); + } + } + + /* Apply limiting in place */ + ivas_limiter_renderer( + st->hLimiter, + outAudio.data, + outAudio.config.bufferSize, + LIMITER_THRESHOLD ); + + if ( st->firstFrame ) + { + st->firstFrame = 0; + } + +#ifdef WMOPS + wmops_sub_end(); +#endif +} + +void IVAS_REND_OpenCustomLayout( + IVAS_LSSETUP_CUSTOM_HANDLE *outSetupCustom ) +{ + ivas_ls_custom_open( outSetupCustom ); +} + +void IVAS_REND_SetNeverDropLfe( + IVAS_REND_HANDLE st, + int8_t neverDropLfe ) +{ + st->neverDropLfe = neverDropLfe; +} + +int16_t IVAS_REND_GetInChannels( + IVAS_REND_HANDLE st ) +{ + assert( st != NULL && "Can't get number of input channels - renderer pointer is NULL" ); + if ( st ) + { + return st->numInChannels; + } + return 0; +} + +int16_t IVAS_REND_GetOutChannels( + IVAS_REND_HANDLE st ) +{ + assert( st != NULL && "Can't get number of output channels - renderer pointer is NULL" ); + if ( st ) + { + return st->numOutChannels; + } + return 0; +} + +void IVAS_REND_Close( IVAS_REND_HANDLE *st ) +{ + uint32_t i; + uint32_t j; + uint32_t numNonLfeChannels; + IVAS_REND_HANDLE hIvasRend; + + if ( st == NULL || *st == NULL ) + { + return; + } + hIvasRend = *st; + + if ( hIvasRend->efapRenderer != NULL ) + { + efap_free_data( &hIvasRend->efapRenderer ); + } + + if ( hIvasRend->objPanInfo != NULL ) + { + for ( i = 0; i < hIvasRend->inConfig.numAudioObjects; ++i ) + { + if ( hIvasRend->objPanInfo[i].panGains != NULL ) + { + count_free( hIvasRend->objPanInfo[i].panGains ); + } + } + + count_free( hIvasRend->objPanInfo ); + } + + if ( hIvasRend->speakerPanGains != NULL ) + { + for ( i = 0; i < hIvasRend->inConfig.numMultiChannelBuses; ++i ) + { + if ( hIvasRend->inConfig.multiChannelBuses[i].speakerLayout == IVAS_REND_SPEAKER_LAYOUT_CUSTOM ) + { + numNonLfeChannels = hIvasRend->inConfig.inSetupCustom->num_spk; + } + else + { + numNonLfeChannels = getNumNonLfeChannelsInSpeakerLayout( hIvasRend->inConfig.multiChannelBuses[i].speakerLayout ); + } + + for ( j = 0; j < numNonLfeChannels; ++j ) + { + count_free( hIvasRend->speakerPanGains[i][j] ); + } + + count_free( hIvasRend->speakerPanGains[i] ); + } + + count_free( hIvasRend->speakerPanGains ); + } + + if ( hIvasRend->inConfig.inSetupCustom != NULL ) + { + count_free( hIvasRend->inConfig.inSetupCustom ); + hIvasRend->inConfig.inSetupCustom = NULL; + } + + if ( hIvasRend->outConfig.outSetupCustom != NULL ) + { + count_free( hIvasRend->outConfig.outSetupCustom ); + hIvasRend->outConfig.outSetupCustom = NULL; + } + + if ( hIvasRend->tmpGainBuffer != NULL ) + { + count_free( hIvasRend->tmpGainBuffer ); + } + + if ( hIvasRend->noLfePanBuffer != NULL ) + { + count_free( hIvasRend->noLfePanBuffer ); + } + + if ( hIvasRend->crossfade != NULL ) + { + count_free( hIvasRend->crossfade ); + } + + if ( hIvasRend->mcPassthrough != NULL ) + { + count_free( hIvasRend->mcPassthrough ); + } + + if ( hIvasRend->lfePanGains ) + { + count_free( hIvasRend->lfePanGains ); + } + + if ( hIvasRend->ambi_dec_mtx != NULL ) + { + count_free( hIvasRend->ambi_dec_mtx ); + } + + if ( hIvasRend->decDummyAmbiBin != NULL ) + { + ivas_crend_close( hIvasRend->decDummyAmbiBin ); + ivas_render_config_close( &hIvasRend->decDummyAmbiBin->hRenderConfig ); + count_free( hIvasRend->decDummyAmbiBin->hDecoderConfig ); + if ( hIvasRend->enableHeadRotation ) + { + count_free( hIvasRend->decDummyAmbiBin->hHeadTrackData ); + } + count_free( hIvasRend->decDummyAmbiBin ); + } + + if ( hIvasRend->decDummyMcBin != NULL ) + { + ivas_crend_close( hIvasRend->decDummyMcBin ); + ivas_td_binaural_close( &hIvasRend->decDummyMcBin->hBinRendererTd ); + ivas_render_config_close( &hIvasRend->decDummyMcBin->hRenderConfig ); + count_free( hIvasRend->decDummyMcBin->hDecoderConfig ); + if ( hIvasRend->enableHeadRotation ) + { + count_free( hIvasRend->decDummyMcBin->hHeadTrackData ); + } + count_free( hIvasRend->decDummyMcBin ); + } + + if ( hIvasRend->decDummyObjBin != NULL ) + { + ivas_td_binaural_close( &hIvasRend->decDummyObjBin->hBinRendererTd ); + ivas_render_config_close( &hIvasRend->decDummyObjBin->hRenderConfig ); + count_free( hIvasRend->decDummyObjBin->hDecoderConfig ); + + if ( hIvasRend->enableHeadRotation ) + { + count_free( hIvasRend->decDummyObjBin->hHeadTrackData ); + } + + for ( i = 0; i < hIvasRend->inConfig.numAudioObjects; ++i ) + { + count_free( hIvasRend->decDummyObjBin->hIsmMetaData[i] ); + } + + count_free( hIvasRend->decDummyObjBin ); + } + + ivas_limiter_close( &hIvasRend->hLimiter ); + + count_free( hIvasRend ); + *st = NULL; +} + +ivas_error IVAS_REND_GetDelay( + IVAS_REND_HANDLE st, /* 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 */ +) +{ + + if ( st == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + if ( st->outConfig.binaural ) + { + if ( ( st->decDummyAmbiBin != NULL && st->decDummyAmbiBin->renderer_type == RENDERER_BINAURAL_OBJECTS_TD ) || + ( st->decDummyObjBin != NULL && st->decDummyObjBin->renderer_type == RENDERER_BINAURAL_OBJECTS_TD ) || + ( st->decDummyMcBin != NULL && st->decDummyMcBin->renderer_type == RENDERER_BINAURAL_OBJECTS_TD ) ) + { + *nSamples = NS2SA( st->sampleRate, (int32_t) ( (float) IVAS_FB_DEC_DELAY_NS + 0.5f ) ); + } + else if ( ( st->decDummyAmbiBin != NULL && st->decDummyAmbiBin->renderer_type == RENDERER_BINAURAL_MIXER_CONV ) ) + { + *nSamples = NS2SA( st->sampleRate, (int32_t) ( (float) st->decDummyAmbiBin->binaural_latency_ns + 0.5f ) ); + } + else if ( st->decDummyObjBin != NULL && st->decDummyObjBin->renderer_type == RENDERER_BINAURAL_MIXER_CONV ) + { + *nSamples = NS2SA( st->sampleRate, (int32_t) ( (float) st->decDummyObjBin->binaural_latency_ns + 0.5f ) ); + } + else if ( st->decDummyMcBin != NULL && st->decDummyMcBin->renderer_type == RENDERER_BINAURAL_MIXER_CONV ) + { + *nSamples = NS2SA( st->sampleRate, (int32_t) ( (float) st->decDummyMcBin->binaural_latency_ns + 0.5f ) ); + } + } + else + { + *nSamples = 0; + } + + *timeScale = st->sampleRate; + + return IVAS_ERR_OK; +} + +/* ============================= Local functions ============================ */ +static float *get_smpl_ptr( IVAS_REND_AudioBuffer buffer, uint32_t chnlIdx, uint32_t smplIdx ) +{ + return buffer.data + chnlIdx * buffer.config.bufferSize + smplIdx; +} + +static void renderAmbiToAmbi( const IVAS_REND_HANDLE st, + const IVAS_REND_AudioBuffer inAudio, + IVAS_REND_AudioBuffer outAudio ) +{ + float *inSmpl; + float *outSmpl; + int16_t lastChannelIdx; + int16_t smplIdx; + int16_t chnlIdx; + uint32_t inAmbiChannelIdx; + uint32_t ambiIdx; + float gain_lin; + + +#ifdef WMOPS + wmops_sub_start( "renderAmbiToAmbi" ); +#endif + + /* Iterate over given Ambisonics inputs */ + for ( ambiIdx = 0; ambiIdx < st->inConfig.numAmbisonicsBuses; ++ambiIdx ) + { + inAmbiChannelIdx = st->inConfig.ambisonicsBuses[ambiIdx].inputChannelIndex; + + /* Find out how many channels to process */ + lastChannelIdx = min( getNumChannelsAmbisonics( st->inConfig.ambisonicsBuses[ambiIdx].ambisonicsConfig ), st->numOutChannels ) - 1; + + gain_lin = dBToLin( st->inConfig.ambisonicsBuses[ambiIdx].gain_dB ); + + /* Passthrough channels */ + for ( chnlIdx = 0; chnlIdx <= lastChannelIdx; ++chnlIdx ) + { + inSmpl = get_smpl_ptr( inAudio, chnlIdx + inAmbiChannelIdx, 0 ); + outSmpl = get_smpl_ptr( outAudio, chnlIdx, 0 ); + + for ( smplIdx = 0; smplIdx < inAudio.config.bufferSize; ++smplIdx ) + { + *outSmpl += *inSmpl * gain_lin; + + ++inSmpl; + ++outSmpl; + } + } + } + +#ifdef WMOPS + wmops_sub_end(); +#endif +} + +static void renderChannelsToAmbi( IVAS_REND_HANDLE st, + const IVAS_REND_AudioBuffer inAudio, + IVAS_REND_AudioBuffer outAudio ) +{ + const uint32_t *lfeLastIdxs; + uint32_t inMcChannelIdx; + uint32_t numNonLfeInChannels; + uint32_t numInChannels; + uint32_t mcIdx; + uint32_t inChIdx; + uint32_t lfeLastIdx_lsCustom[MAX_OUTPUT_CHANNELS]; + float gain_lin; + +#ifdef WMOPS + wmops_sub_start( "renderChannelsToAmbi" ); +#endif + + /* Iterate over given MC inputs */ + for ( mcIdx = 0; mcIdx < st->inConfig.numMultiChannelBuses; ++mcIdx ) + { + /* Get channel idx of current MC input within the multitrack buffer */ + inMcChannelIdx = st->inConfig.multiChannelBuses[mcIdx].inputChannelIndex; + + /* Number of input speakers */ + if ( st->inConfig.multiChannelBuses[mcIdx].speakerLayout == IVAS_REND_SPEAKER_LAYOUT_CUSTOM ) + { + numInChannels = st->inConfig.inSetupCustom->num_spk + st->inConfig.inSetupCustom->num_lfe; + numNonLfeInChannels = st->inConfig.inSetupCustom->num_spk; + + /* Reordered indices for custom loudspeaker input */ + if ( st->inConfig.inSetupCustom->num_lfe > 0 ) + { + lfeLastIdx_lsCustom[numNonLfeInChannels] = st->inConfig.inSetupCustom->lfe_idx[0]; + } + + for ( inChIdx = 0; inChIdx < numNonLfeInChannels; ++inChIdx ) + { + ( ( st->inConfig.inSetupCustom->num_lfe > 0 ) && ( (int16_t) inChIdx >= st->inConfig.inSetupCustom->lfe_idx[0] ) ) ? ( lfeLastIdx_lsCustom[inChIdx] = inChIdx + 1 ) : ( lfeLastIdx_lsCustom[inChIdx] = inChIdx ); + } + + lfeLastIdxs = &lfeLastIdx_lsCustom[0]; + } + else + { + numInChannels = getNumChannelsInSpeakerLayout( st->inConfig.multiChannelBuses[mcIdx].speakerLayout ); + numNonLfeInChannels = getNumNonLfeChannelsInSpeakerLayout( st->inConfig.multiChannelBuses[mcIdx].speakerLayout ); + + lfeLastIdxs = getReorderedChannelIndices( st->inConfig.multiChannelBuses[mcIdx].speakerLayout ); + } + + gain_lin = dBToLin( st->inConfig.multiChannelBuses[mcIdx].gain_dB ); + + /* Iterate over channels */ + for ( inChIdx = 0; inChIdx < numNonLfeInChannels; ++inChIdx ) + { + applyChannelGainsAndAddToOutput( inAudio, + inMcChannelIdx + lfeLastIdxs[inChIdx], + st->speakerPanGains[mcIdx][inChIdx], + NULL, + gain_lin, + st->crossfade, + outAudio ); + } + + if ( st->neverDropLfe ) + { + /* Render LFE channels into the scene */ + for ( ; inChIdx < numInChannels; ++inChIdx ) + { + applyChannelGainsAndAddToOutput( inAudio, + inMcChannelIdx + lfeLastIdxs[inChIdx], + st->lfePanGains, + NULL, + gain_lin, + st->crossfade, + outAudio ); + } + } + } + +#ifdef WMOPS + wmops_sub_end(); +#endif +} + +static void renderObjectsToAmbi( + IVAS_REND_HANDLE st, + const IVAS_REND_AudioBuffer inAudio, + const IVAS_REND_AudioObjectMetadataBuffer metadataBuffer, + IVAS_REND_AudioBuffer outAudio ) +{ + const IVAS_REND_AudioObject *curObj; + uint32_t objIdx; + IVAS_REND_AudioObjectPosition pos; + float gain_lin; + +#ifdef WMOPS + wmops_sub_start( "renderObjectsToAmbi" ); +#endif + + assert( st->inConfig.numAudioObjects == metadataBuffer.numObjects && "Metadata provided for a different number of objects than found in input" ); + + /* Iterate over given audio objects */ + for ( objIdx = 0; objIdx < st->inConfig.numAudioObjects; ++objIdx ) + { + /* Get pointer to current object and its metadata */ + curObj = &st->inConfig.audioObjects[objIdx]; + pos = metadataBuffer.positions[objIdx]; + gain_lin = dBToLin( st->inConfig.audioObjects[objIdx].gain_dB ); + + /* Render to ambisonics */ + renderSingleObjectToAmbi( + st, + inAudio, + curObj->inputChannelIndex, + &st->objPanInfo[objIdx], + pos, + gain_lin, + outAudio ); + } + +#ifdef WMOPS + wmops_sub_end(); +#endif +} + +static void renderAmbiToChannels( const IVAS_REND_HANDLE st, + const IVAS_REND_AudioBuffer inAudio, + IVAS_REND_AudioBuffer outAudio ) +{ + uint32_t inAmbiChannelIdx; + uint32_t ambiIdx; + uint32_t numInAmbiChnls; + uint32_t ambiChnIdx; + float gain_lin; + +#ifdef WMOPS + wmops_sub_start( "renderAmbiToChannels" ); +#endif + + /* Iterate over all given ambisonics inputs */ + for ( ambiIdx = 0; ambiIdx < st->inConfig.numAmbisonicsBuses; ++ambiIdx ) + { + inAmbiChannelIdx = st->inConfig.ambisonicsBuses[ambiIdx].inputChannelIndex; + + /* Number of input channels */ + numInAmbiChnls = getNumChannelsAmbisonics( st->inConfig.ambisonicsBuses[ambiIdx].ambisonicsConfig ); + + gain_lin = dBToLin( st->inConfig.multiChannelBuses[ambiIdx].gain_dB ); + + /* Render each ambisonics channel */ + for ( ambiChnIdx = 0; ambiChnIdx < numInAmbiChnls; ++ambiChnIdx ) + { + /* Write decoding gains to temp buffer */ + getHoaDecVecForAmbiChnl( ambiChnIdx, st->outConfig, st->ambi_dec_mtx, st->tmpGainBuffer ); + + /* Apply decoding gains and add to output */ + applyChannelGainsAndAddToOutput( inAudio, + inAmbiChannelIdx + ambiChnIdx, + st->tmpGainBuffer, + NULL, + gain_lin, + st->crossfade, + outAudio ); + } + } + +#ifdef WMOPS + wmops_sub_end(); +#endif +} + +static void renderChannelsToChannels( + const IVAS_REND_HANDLE st, + const IVAS_REND_AudioBuffer inAudio, + IVAS_REND_AudioBuffer outAudio ) +{ + const uint32_t *lfeLastIdxs; + uint32_t inMcChannelIdx; + uint32_t numNonLfeInChannels; + uint32_t numInChannels; + uint32_t passThroughIdx; + uint32_t mcIdx; + uint32_t inChIdx; + uint32_t lfeLastIdx_lsCustom[MAX_OUTPUT_CHANNELS]; + float gain_lin; + +#ifdef WMOPS + wmops_sub_start( "renderChannelsToChannels" ); +#endif + + passThroughIdx = 0; + + /* Iterate over given MC inputs */ + for ( mcIdx = 0; mcIdx < st->inConfig.numMultiChannelBuses; ++mcIdx ) + { + /* Get channel idx of current MC input within the multitrack buffer */ + inMcChannelIdx = st->inConfig.multiChannelBuses[mcIdx].inputChannelIndex; + + if ( st->inConfig.multiChannelBuses[mcIdx].speakerLayout == IVAS_REND_SPEAKER_LAYOUT_CUSTOM ) + { + /* Number of non-LFE input channels */ + numNonLfeInChannels = st->inConfig.inSetupCustom->num_spk; + + /* Number of all input channels */ + numInChannels = st->inConfig.inSetupCustom->num_spk + st->inConfig.inSetupCustom->num_lfe; + + /* Reordered indices for custom loudspeaker input */ + if ( st->inConfig.inSetupCustom->num_lfe > 0 ) + { + lfeLastIdx_lsCustom[numNonLfeInChannels] = st->inConfig.inSetupCustom->lfe_idx[0]; + } + + for ( inChIdx = 0; inChIdx < numNonLfeInChannels; ++inChIdx ) + { + ( ( st->inConfig.inSetupCustom->num_lfe > 0 ) && ( (int16_t) inChIdx >= st->inConfig.inSetupCustom->lfe_idx[0] ) ) ? ( lfeLastIdx_lsCustom[inChIdx] = inChIdx + 1 ) : ( lfeLastIdx_lsCustom[inChIdx] = inChIdx ); + } + + lfeLastIdxs = &lfeLastIdx_lsCustom[0]; + } + else + { + /* Number of non-LFE input channels */ + numNonLfeInChannels = getNumNonLfeChannelsInSpeakerLayout( st->inConfig.multiChannelBuses[mcIdx].speakerLayout ); + + /* Number of all input channels */ + numInChannels = getNumChannelsInSpeakerLayout( st->inConfig.multiChannelBuses[mcIdx].speakerLayout ); + + lfeLastIdxs = getReorderedChannelIndices( st->inConfig.multiChannelBuses[mcIdx].speakerLayout ); + } + + + gain_lin = dBToLin( st->inConfig.multiChannelBuses[mcIdx].gain_dB ); + + /* Iterate over non-LFE channels */ + for ( inChIdx = 0; inChIdx < numNonLfeInChannels; ++inChIdx ) + { + if ( st->mcPassthrough[passThroughIdx] == -1 ) + { + applyChannelGainsAndAddToOutput( inAudio, + inMcChannelIdx + lfeLastIdxs[inChIdx], + st->speakerPanGains[mcIdx][inChIdx], + NULL, + gain_lin, + st->crossfade, + outAudio ); + } + else + { + passthroughChannel( inAudio, + inMcChannelIdx + lfeLastIdxs[inChIdx], + st->mcPassthrough[passThroughIdx], + gain_lin, + outAudio ); + } + + ++passThroughIdx; + } + + /* Iterate over LFE channels */ + for ( ; inChIdx < numInChannels; ++inChIdx ) + { + /* Pass through if possible */ + if ( st->mcPassthrough[passThroughIdx] != -1 ) + { + passthroughChannel( inAudio, + inMcChannelIdx + lfeLastIdxs[inChIdx], + st->mcPassthrough[passThroughIdx], + gain_lin, + outAudio ); + } + else + { + if ( st->neverDropLfe ) + { + applyChannelGainsAndAddToOutput( inAudio, + inMcChannelIdx + lfeLastIdxs[inChIdx], + st->lfePanGains, + NULL, + gain_lin, + st->crossfade, + outAudio ); + } + } + + ++passThroughIdx; + } + } + +#ifdef WMOPS + wmops_sub_end(); +#endif +} + +static void renderObjectsToChannels( + IVAS_REND_HANDLE st, + const IVAS_REND_AudioBuffer inAudio, + const IVAS_REND_AudioObjectMetadataBuffer metadataBuffer, + IVAS_REND_AudioBuffer outAudio ) +{ + const IVAS_REND_AudioObject *curObj; + uint32_t objIdx; + IVAS_REND_AudioObjectPosition pos; + float gain_lin; + +#ifdef WMOPS + wmops_sub_start( "renderObjectsToChannels" ); +#endif + + assert( st->inConfig.numAudioObjects == metadataBuffer.numObjects && "Metadata provided for a different number of objects than found in input" ); + + /* Iterate over given audio objects */ + for ( objIdx = 0; objIdx < st->inConfig.numAudioObjects; ++objIdx ) + { + /* Get pointer to current object and its metadata */ + curObj = &st->inConfig.audioObjects[objIdx]; + pos = metadataBuffer.positions[objIdx]; + gain_lin = dBToLin( st->inConfig.audioObjects[objIdx].gain_dB ); + + /* Render to MC */ + renderSingleObjectToChannels( + st, + inAudio, + curObj->inputChannelIndex, + &st->objPanInfo[objIdx], + pos, + gain_lin, + outAudio ); + } + +#ifdef WMOPS + wmops_sub_end(); +#endif +} + +static void applyGainToBuffer( const IVAS_REND_AudioBuffer buffer, const uint32_t bufChIdx, float gain_lin ) +{ + int32_t smplIdx, chnlIdx; + float *smplPtr; + + smplPtr = buffer.data + bufChIdx; + for ( chnlIdx = 0; chnlIdx < buffer.config.numChannels; ++chnlIdx ) + { + for ( smplIdx = 0; smplIdx < buffer.config.bufferSize; ++smplIdx ) + { + *smplPtr++ *= gain_lin; + } + } +} + +static void copyBufferTo2dArray( const IVAS_REND_AudioBuffer buffer, const uint32_t bufChIdx, float array[MAX_OUTPUT_CHANNELS][L_FRAME48k] ) +{ + int32_t smplIdx, chnlIdx; + const float *readPtr; + + readPtr = buffer.data + bufChIdx; + for ( chnlIdx = 0; chnlIdx < buffer.config.numChannels; ++chnlIdx ) + { + for ( smplIdx = 0; smplIdx < buffer.config.bufferSize; ++smplIdx ) + { + array[chnlIdx][smplIdx] = *readPtr++; + } + } +} + +static void copy2dArrayToBuffer( float array[MAX_OUTPUT_CHANNELS][L_FRAME48k], IVAS_REND_AudioBuffer *buffer, const uint32_t bufChIdx ) +{ + int32_t smplIdx, chnlIdx; + float *writePtr; + + writePtr = buffer->data + bufChIdx; + for ( chnlIdx = 0; chnlIdx < buffer->config.numChannels; ++chnlIdx ) + { + for ( smplIdx = 0; smplIdx < buffer->config.bufferSize; ++smplIdx ) + { + *writePtr++ = array[chnlIdx][smplIdx]; + } + } +} + +static void copyHeadRotToDecDummy( const IVAS_QUATERNION *headRot, DecoderDummy *decDummy ) +{ + int16_t i; + + assert( decDummy != NULL && decDummy->hHeadTrackData != NULL ); + + for ( i = 0; i < RENDERER_HEAD_POSITIONS_PER_FRAME; ++i ) + { + decDummy->hHeadTrackData->Quaternions[i].w = headRot[i].w; + decDummy->hHeadTrackData->Quaternions[i].x = headRot[i].x; + decDummy->hHeadTrackData->Quaternions[i].y = headRot[i].y; + decDummy->hHeadTrackData->Quaternions[i].z = headRot[i].z; + } + + decDummy->hHeadTrackData->num_quaternions = 0; + + /* Make sure head rotation is not performed in the renderer(s) */ + decDummy->hDecoderConfig->Opt_Headrotation = 0; +} + +static void renderAmbiToBinaural( + const IVAS_REND_HANDLE st, + const IVAS_REND_AudioBuffer inAudio, + IVAS_REND_AudioBuffer outAudio ) +{ + int16_t i; + int16_t subFrameLength; + uint32_t ambiIdx; + uint32_t inAmbiChannelIdx; + float tmpBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; + float gain_lin; + +#ifdef WMOPS + wmops_sub_start( "renderAmbiToBinaural" ); +#endif + + subFrameLength = (int16_t) ( st->sampleRate / FRAMES_PER_SEC / RENDERER_HEAD_POSITIONS_PER_FRAME ); + if ( st->enableHeadRotation ) + { + copyHeadRotToDecDummy( st->headRotationData, st->decDummyAmbiBin ); + } + + for ( ambiIdx = 0; ambiIdx < st->inConfig.numAmbisonicsBuses; ++ambiIdx ) + { + inAmbiChannelIdx = st->inConfig.ambisonicsBuses[ambiIdx].inputChannelIndex; + gain_lin = dBToLin( st->inConfig.ambisonicsBuses[ambiIdx].gain_dB ); + + applyGainToBuffer( inAudio, inAmbiChannelIdx, gain_lin ); + copyBufferTo2dArray( inAudio, inAmbiChannelIdx, tmpBuffer ); + + if ( st->enableHeadRotation ) + { + for ( i = 0; i < RENDERER_HEAD_POSITIONS_PER_FRAME; i++ ) + { + rotateFrame_shd( st->decDummyAmbiBin->hHeadTrackData, tmpBuffer, st->sampleRate, subFrameLength, st->decDummyAmbiBin->hTransSetup, i ); + } + } + + ivas_crend_process( st->decDummyAmbiBin, tmpBuffer ); + + copy2dArrayToBuffer( tmpBuffer, &outAudio, inAmbiChannelIdx ); + } + + +#ifdef WMOPS + wmops_sub_end(); +#endif +} + +static void renderChannelsToBinaural( + const IVAS_REND_HANDLE st, + const IVAS_REND_AudioBuffer inAudio, + IVAS_REND_AudioBuffer outAudio ) +{ + int16_t i; + int16_t subFrameLength; + int16_t lfeLpDelay; + uint32_t mcIdx; + uint32_t inMcChannelIdx; + uint32_t lfeChIdx; + float tmpLfeBuffer[L_FRAME48k]; + float tmpBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; + float gain_lin; + +#ifdef WMOPS + wmops_sub_start( "renderChannelsToBinaural" ); +#endif + + subFrameLength = (int16_t) ( st->sampleRate / FRAMES_PER_SEC / RENDERER_HEAD_POSITIONS_PER_FRAME ); + if ( st->enableHeadRotation ) + { + copyHeadRotToDecDummy( st->headRotationData, st->decDummyMcBin ); + } + + for ( mcIdx = 0; mcIdx < st->inConfig.numMultiChannelBuses; ++mcIdx ) + { + inMcChannelIdx = st->inConfig.multiChannelBuses[mcIdx].inputChannelIndex; + gain_lin = dBToLin( st->inConfig.multiChannelBuses[mcIdx].gain_dB ); + + applyGainToBuffer( inAudio, inMcChannelIdx, gain_lin ); + copyBufferTo2dArray( inAudio, inMcChannelIdx, tmpBuffer ); + + /* Rotation in spatial domain */ + if ( st->enableHeadRotation ) + { + for ( i = 0; i < RENDERER_HEAD_POSITIONS_PER_FRAME; i++ ) + { + rotateFrame_sd( st->decDummyMcBin->hHeadTrackData, tmpBuffer, st->sampleRate, subFrameLength, st->decDummyMcBin->hTransSetup, st->decDummyMcBin->hEFAPdata, i ); + } + } + + /* TD object renderer initialised only for 7_1 and 5_1 with headrotation or custom layout input */ + if ( ( st->inConfig.multiChannelBuses[mcIdx].speakerLayout == IVAS_REND_SPEAKER_LAYOUT_CUSTOM ) || + ( st->decDummyMcBin->hBinRendererTd != NULL && st->enableHeadRotation ) ) + { + ObjRenderIVASFrame( st->decDummyMcBin, tmpBuffer, inAudio.config.bufferSize ); + /* TODO tmu : needs delay compensation otherwise LFE is added out of alignment */ + } + else + { + ivas_crend_process( st->decDummyMcBin, tmpBuffer ); + } + + /* Low-pass filter the LFE channel with delay compensation */ + lfeLpDelay = (int16_t) ( ivas_lfe_lpf_delay[1] * (float) st->sampleRate ); + if ( st->inConfig.multiChannelBuses[mcIdx].speakerLayout == IVAS_REND_SPEAKER_LAYOUT_CUSTOM ) + { + lfeChIdx = st->inConfig.inSetupCustom->lfe_idx[0]; + } + else + { + lfeChIdx = LFE_CHANNEL; + } + // TODO tmu verify + mvr2r( tmpBuffer[lfeChIdx], tmpLfeBuffer, L_FRAME48k ); + ivas_filter_process( &st->lfeLpFilter, tmpLfeBuffer, L_FRAME48k ); + set_zero( tmpBuffer[lfeChIdx], L_FRAME48k ); + mvr2r( &tmpLfeBuffer[lfeLpDelay], &tmpBuffer[lfeChIdx][0], L_FRAME48k - lfeLpDelay ); + + ivas_binaural_add_LFE( st->decDummyMcBin, L_FRAME48k, tmpBuffer ); + copy2dArrayToBuffer( tmpBuffer, &outAudio, inMcChannelIdx ); + } + + +#ifdef WMOPS + wmops_sub_end(); +#endif +} + +static void renderObjectsToBinaural( + IVAS_REND_HANDLE st, + const IVAS_REND_AudioBuffer inAudio, + const IVAS_REND_AudioObjectMetadataBuffer metadataBuffer, + IVAS_REND_AudioBuffer outAudio ) +{ + int16_t objIdx; + int16_t tmpAzi, tmpEle; + float tmpBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; + float gain_lin; + +#ifdef WMOPS + wmops_sub_start( "renderObjectsToBinaural" ); +#endif + + assert( st->inConfig.numAudioObjects == metadataBuffer.numObjects && "Metadata provided for a different number of objects than found in input" ); + + if ( st->enableHeadRotation ) + { + copyHeadRotToDecDummy( st->headRotationData, st->decDummyObjBin ); + } + + /* Iterate over given audio objects */ + for ( objIdx = 0; objIdx < metadataBuffer.numObjects; ++objIdx ) + { + /* Apply head rotation directly to object positions */ + /* TODO tmu 20ms only right now... */ + if ( st->enableHeadRotation ) + { + /* save original positions */ + tmpAzi = (int16_t) metadataBuffer.positions[objIdx].azimuth; + tmpEle = (int16_t) metadataBuffer.positions[objIdx].elevation; + + /* apply rotation */ + QuatToRotMat( st->decDummyObjBin->hHeadTrackData->Quaternions[0], st->decDummyObjBin->hHeadTrackData->Rmat ); + rotateAziEle( + metadataBuffer.positions[objIdx].azimuth, + metadataBuffer.positions[objIdx].elevation, + &tmpAzi, + &tmpEle, + st->decDummyObjBin->hHeadTrackData->Rmat, + 0 ); + + /* set rotated positions in decoder dummy */ + st->decDummyObjBin->hIsmMetaData[objIdx]->azimuth = (float) tmpAzi; + st->decDummyObjBin->hIsmMetaData[objIdx]->elevation = (float) tmpEle; + } + } + + /* TODO tmu : enable per-object gains */ + gain_lin = dBToLin( st->inConfig.audioObjects[0].gain_dB ); + applyGainToBuffer( inAudio, 0, gain_lin ); + + copyBufferTo2dArray( inAudio, 0, tmpBuffer ); + ObjRenderIVASFrame( st->decDummyObjBin, tmpBuffer, inAudio.config.bufferSize ); + copy2dArrayToBuffer( tmpBuffer, &outAudio, 0 ); + +#ifdef WMOPS + wmops_sub_end(); +#endif +} + +static void renderSingleObjectToAmbi( + IVAS_REND_HANDLE st, + const IVAS_REND_AudioBuffer inAudio, + const uint32_t itemChnlIdx, + IVAS_REND_ObjPanInfo *prevPanInfo, + const IVAS_REND_AudioObjectPosition curFrmPos, + const float gain_lin, + IVAS_REND_AudioBuffer outAudio ) +{ + float *swapPtr; + +#ifdef WMOPS + wmops_sub_start( "renderSingleObjectToAmbi" ); +#endif + + /* Update panning gains if position changed */ + if ( prevPanInfo->position.azimuth != curFrmPos.azimuth || + prevPanInfo->position.elevation != curFrmPos.elevation || + st->firstFrame ) + { + /* Write current panning gains to tmpBuffer */ + ivas_dirac_dec_get_response( (int16_t) curFrmPos.azimuth, + (int16_t) curFrmPos.elevation, + st->tmpGainBuffer, + getAmbisonicsOrder( st->outConfig.ambisonics ) ); + + prevPanInfo->position.azimuth = curFrmPos.azimuth; + prevPanInfo->position.elevation = curFrmPos.elevation; + + applyChannelGainsAndAddToOutput( inAudio, + itemChnlIdx, + st->tmpGainBuffer, + st->firstFrame ? NULL : prevPanInfo->panGains, + gain_lin, + st->crossfade, + outAudio ); + + /* Save current gains as most recently applied gains */ + swapPtr = prevPanInfo->panGains; + prevPanInfo->panGains = st->tmpGainBuffer; + st->tmpGainBuffer = swapPtr; + } + /* Otherwise use most recent gains and no interpolation */ + else + { + applyChannelGainsAndAddToOutput( inAudio, + itemChnlIdx, + prevPanInfo->panGains, + NULL, + gain_lin, + st->crossfade, + outAudio ); + } + +#ifdef WMOPS + wmops_sub_end(); +#endif +} + +static void renderSingleObjectToChannels( + IVAS_REND_HANDLE st, + const IVAS_REND_AudioBuffer inAudio, + const uint32_t itemChnlIdx, + IVAS_REND_ObjPanInfo *prevPanInfo, + const IVAS_REND_AudioObjectPosition curFrmPos, + const float gain_lin, + IVAS_REND_AudioBuffer outAudio ) +{ + float *swapPtr; + +#ifdef WMOPS + wmops_sub_start( "renderSingleObjectToChannels" ); +#endif + + /* Update panning gains if position changed */ + if ( prevPanInfo->position.azimuth != curFrmPos.azimuth || + prevPanInfo->position.elevation != curFrmPos.elevation || + st->firstFrame ) + { + /* Write current panning gains to tmpBuffer */ + getSpeakerGains( st, curFrmPos.azimuth, curFrmPos.elevation, st->tmpGainBuffer ); + prevPanInfo->position.azimuth = curFrmPos.azimuth; + prevPanInfo->position.elevation = curFrmPos.elevation; + + applyChannelGainsAndAddToOutput( inAudio, + itemChnlIdx, + st->tmpGainBuffer, + st->firstFrame ? NULL : prevPanInfo->panGains, + gain_lin, + st->crossfade, + outAudio ); + + /* Save current gains as most recently applied gains */ + swapPtr = prevPanInfo->panGains; + prevPanInfo->panGains = st->tmpGainBuffer; + st->tmpGainBuffer = swapPtr; + } + /* Otherwise use most recent gains and no interpolation */ + else + { + applyChannelGainsAndAddToOutput( inAudio, + itemChnlIdx, + prevPanInfo->panGains, + NULL, + gain_lin, + st->crossfade, + outAudio ); + } + +#ifdef WMOPS + wmops_sub_end(); +#endif +} + +static void applyChannelGainsAndAddToOutput( + const IVAS_REND_AudioBuffer inAudio, + const uint32_t itemChnlIdx, + const float *const gainsCurrent, + const float *const gainsPrev, + const float gain_lin, + const float *const crossfade, + IVAS_REND_AudioBuffer outAudio ) +{ + float *inSmpl; + float *outSmpl; + const float *fadeIn; + const float *fadeOut; + const float *lastInSmpl; + int16_t outChnlIdx; + float currentGain; + float previousGain; + +#ifdef WMOPS + wmops_sub_start( "applyChannelGainsAndAddToOutput" ); +#endif + + + /* Pointer to behind last input sample */ + lastInSmpl = get_smpl_ptr( inAudio, itemChnlIdx, inAudio.config.bufferSize ); + + for ( outChnlIdx = 0; outChnlIdx < outAudio.config.numChannels; ++outChnlIdx ) + { +#ifdef WMOPS + wmops_sub_start( "applyChannelGainsAndAddToOutput_chnl_loop" ); +#endif + currentGain = gainsCurrent[outChnlIdx] * gain_lin; + previousGain = gainsPrev == NULL ? 0.f : gainsPrev[outChnlIdx] * gain_lin; + + /* Process current output channel only if applying non-zero gains */ + if ( fabsf( currentGain ) > EPSILON || ( gainsPrev != NULL && fabsf( previousGain ) > EPSILON ) ) + { + /* Reset crossfade pointers */ + fadeIn = crossfade; + fadeOut = &crossfade[inAudio.config.bufferSize - 1]; + + /* Reset input pointer to the beginning of input channel */ + inSmpl = get_smpl_ptr( inAudio, itemChnlIdx, 0 ); + + /* Set output pointer to first output channel sample */ + outSmpl = get_smpl_ptr( outAudio, outChnlIdx, 0 ); + + if ( gainsPrev == NULL || fabsf( previousGain - currentGain ) <= EPSILON ) + { +#ifdef WMOPS + wmops_sub_start( "applyChannelGainsAndAddToOutput_smpl_loop_no_intrpl" ); +#endif + /* If no interpolation from previous frame, apply current gain */ + do + { + *outSmpl += currentGain * ( *inSmpl ); + ++outSmpl; + ++inSmpl; + + } while ( inSmpl != lastInSmpl ); +#ifdef WMOPS + wmops_sub_end(); +#endif + } + else + { +#ifdef WMOPS + wmops_sub_start( "applyChannelGainsAndAddToOutput_smpl_loop_intrpl" ); +#endif + /* Otherwise use weighted average between previous and current gain */ + do + { + *outSmpl += ( ( *fadeIn ) * currentGain + ( *fadeOut ) * previousGain ) * ( *inSmpl ); + ++outSmpl; + ++inSmpl; + + ++fadeIn; + --fadeOut; + } while ( inSmpl != lastInSmpl ); +#ifdef WMOPS + wmops_sub_end(); +#endif + } + } + +#ifdef WMOPS + wmops_sub_end(); +#endif + } + +#ifdef WMOPS + wmops_sub_end(); +#endif +} + +static void prepareLfeHandling( + IVAS_REND_HANDLE st ) +{ + const float *filtCoeff; +#ifdef WMOPS + wmops_sub_start( "prepareLfeHandling" ); +#endif + /* Panning gains */ + st->lfePanGains = count_calloc( st->numOutChannels, sizeof( float ) ); + + if ( st->outConfig.ambisonics != IVAS_REND_AMBISONICS_NONE ) + { + /* TODO tmu : LFE in ambisonics disabled for now */ + /* Pan LFE to south pole (experimental) */ + // ivas_dirac_dec_get_response( 0, + // -90, + // st->lfePanGains, + // getAmbisonicsOrder( st->outConfig.ambisonics ) ); + } + else + { + set_zero( st->lfePanGains, st->numOutChannels ); + + /* Pan LFE to L and R with -3dB gain */ + if ( st->numOutChannels > 1 ) + { + st->lfePanGains[0] = sqrtf( 0.5f ); + st->lfePanGains[1] = sqrtf( 0.5f ); + } + else + { + /* Put LFE in center channel, do not add 10dB gain to avoid clipping */ + st->lfePanGains[0] = 1.f; + } + } + + /* Low-pass filter */ + ivas_lfe_lpf_select_filt_coeff( st->sampleRate, IVAS_FILTER_ORDER_4, &filtCoeff ); + ivas_filters_init( &st->lfeLpFilter, filtCoeff, IVAS_FILTER_ORDER_4 ); + +#ifdef WMOPS + wmops_sub_end(); +#endif +} + +static void prepareMcPanGains( IVAS_REND_HANDLE st ) +{ + uint32_t mcIdx; + int32_t spkIdx; + int32_t numNonLfeChannelsIn; + const float *spkAzi; + const float *spkEle; + +#ifdef WMOPS + wmops_sub_start( "prepareMcPanGains" ); +#endif + /* No gains required for binaural output */ + if ( ( st->outConfig.binaural ) && + ( st->outConfig.ambisonics == IVAS_REND_AMBISONICS_NONE || st->outConfig.speakerLayout == IVAS_REND_SPEAKER_LAYOUT_NONE ) ) + { + st->speakerPanGains = NULL; + return; + } + + st->speakerPanGains = count_calloc( st->inConfig.numMultiChannelBuses, sizeof( float ** ) ); + + for ( mcIdx = 0; mcIdx < st->inConfig.numMultiChannelBuses; ++mcIdx ) + { + if ( st->inConfig.multiChannelBuses[mcIdx].speakerLayout == IVAS_REND_SPEAKER_LAYOUT_CUSTOM ) + { + numNonLfeChannelsIn = st->inConfig.inSetupCustom->num_spk; + spkAzi = st->inConfig.inSetupCustom->ls_azimuth; + spkEle = st->inConfig.inSetupCustom->ls_elevation; + } + else + { + numNonLfeChannelsIn = getNumNonLfeChannelsInSpeakerLayout( st->inConfig.multiChannelBuses[mcIdx].speakerLayout ); + spkAzi = getSpeakerAzimuths( st->inConfig.multiChannelBuses[mcIdx].speakerLayout ); + spkEle = getSpeakerElevations( st->inConfig.multiChannelBuses[mcIdx].speakerLayout ); + } + + st->speakerPanGains[mcIdx] = count_calloc( numNonLfeChannelsIn, sizeof( float * ) ); + + + if ( st->outConfig.ambisonics != IVAS_REND_AMBISONICS_NONE ) + { + for ( spkIdx = 0; spkIdx < numNonLfeChannelsIn; ++spkIdx ) + { + st->speakerPanGains[mcIdx][spkIdx] = count_calloc( st->numOutChannels, sizeof( float ) ); + ivas_dirac_dec_get_response( (int16_t) spkAzi[spkIdx], + (int16_t) spkEle[spkIdx], + st->speakerPanGains[mcIdx][spkIdx], + getAmbisonicsOrder( st->outConfig.ambisonics ) ); + } + } + else if ( st->outConfig.speakerLayout != IVAS_REND_SPEAKER_LAYOUT_NONE ) + { + /* Custom loudspeaker layout gains */ + for ( spkIdx = 0; spkIdx < numNonLfeChannelsIn; ++spkIdx ) + { + st->speakerPanGains[mcIdx][spkIdx] = count_calloc( st->numOutChannels, sizeof( float ) ); + if ( + ( st->inConfig.multiChannelBuses[mcIdx].speakerLayout == IVAS_REND_SPEAKER_LAYOUT_CUSTOM ) || + ( st->outConfig.speakerLayout == IVAS_REND_SPEAKER_LAYOUT_CUSTOM ) ) + { + getSpeakerGains( st, spkAzi[spkIdx], spkEle[spkIdx], st->speakerPanGains[mcIdx][spkIdx] ); + } + } + + /* Table lookup for loudspeaker layout gains */ + if ( ( st->inConfig.multiChannelBuses[mcIdx].speakerLayout != IVAS_REND_SPEAKER_LAYOUT_CUSTOM ) && + ( st->outConfig.speakerLayout != IVAS_REND_SPEAKER_LAYOUT_CUSTOM ) ) + { + int16_t i, k; + int16_t ch_in, ch_out; + int16_t index; + int16_t nchan_out; + float value; + const uint32_t *lfeLastIdxMap; + const LS_CONVERSION_MATRIX *conversion_matrix; + AUDIO_CONFIG input_config, output_config; + IVAS_REND_SpeakerLayout spkLayoutIn; + + conversion_matrix = NULL; + spkLayoutIn = st->inConfig.multiChannelBuses[mcIdx].speakerLayout; + + input_config = mapRendLayoutToAudioConfig( spkLayoutIn ); + output_config = mapRendLayoutToAudioConfig( st->outConfig.speakerLayout ); + nchan_out = audioCfg2channels( output_config ); + lfeLastIdxMap = getReorderedChannelIndices( spkLayoutIn ); + + /* Search the table for a mapping */ + for ( i = 0; i < LS_SETUP_CONVERSION_NUM_MAPPINGS; i++ ) + { + if ( ( input_config == ls_conversion_mapping[i].input_config ) && ( output_config == ls_conversion_mapping[i].output_config ) ) + { + /* Special handling for MONO and STEREO downmix */ + if ( output_config == AUDIO_CONFIG_MONO || output_config == AUDIO_CONFIG_STEREO ) + { + for ( spkIdx = 0; spkIdx < numNonLfeChannelsIn; spkIdx++ ) + { + k = lfeLastIdxMap[spkIdx]; + + /* Skip two rows in the matrix for 5.1.x formats */ + if ( spkIdx >= 5 && ( input_config == AUDIO_CONFIG_5_1_2 || input_config == AUDIO_CONFIG_5_1_4 ) ) + { + k += 2; + } + + for ( ch_out = 0; ch_out < nchan_out; ch_out++ ) + { + if ( output_config == AUDIO_CONFIG_MONO ) + { + st->speakerPanGains[mcIdx][spkIdx][ch_out] = ls_conversion_cicpX_mono[k][ch_out]; + } + else + { + if ( input_config == AUDIO_CONFIG_MONO ) + { + st->speakerPanGains[mcIdx][spkIdx][ch_out] = ls_conversion_cicpX_stereo[k + 2][ch_out]; + } + else + { + st->speakerPanGains[mcIdx][spkIdx][ch_out] = ls_conversion_cicpX_stereo[k][ch_out]; + } + } + } + } + } + else + { + conversion_matrix = ls_conversion_mapping[i].conversion_matrix; + + /* If a mapping is defined with a NULL matrix, 1:1 upmix of input channels */ + if ( conversion_matrix == NULL ) + { + for ( spkIdx = 0; spkIdx < numNonLfeChannelsIn; spkIdx++ ) + { + ch_out = lfeLastIdxMap[spkIdx]; + st->speakerPanGains[mcIdx][spkIdx][ch_out] = 1.0f; + } + } + else + { + for ( k = 1; k < ( conversion_matrix[0].index + 1 ); k++ ) + { + index = conversion_matrix[k].index; + value = conversion_matrix[k].value; + + /* Second dimension of speakerPanGains (ch_in here) is the input channel index with LFE channels skipped. + Use lfeLastIdxMap to do a reverse lookup over non-LFE channels. + reverseChannelIndexMapping will return -1 for LFE channels - those should be skipped */ + ch_in = reverseChannelIndexMapping( index / nchan_out, lfeLastIdxMap, numNonLfeChannelsIn ); + if ( ch_in < 0 ) + { + continue; + } + + ch_out = index % nchan_out; + + st->speakerPanGains[mcIdx][ch_in][ch_out] = value; + } + } + } + } + } + } + } + } + +#ifdef WMOPS + wmops_sub_end(); +#endif +} + +static void prepareMcPassthrough( IVAS_REND_HANDLE st ) +{ + /* Output config */ + const float *outSpkAzi; + const float *outSpkEle; + const uint32_t *lfeLastIdxs; + uint32_t numNonLfeOutChannels; + uint32_t numOutChannels; + uint32_t lfeLastIdx_lsCustom[MAX_OUTPUT_CHANNELS]; + + /* Input config */ + const float *inSpkAzi; + const float *inSpkEle; + uint32_t numInChannels; + uint32_t numNonLfeInChannels; + + /* Input channel index */ + uint32_t passThroughIdx; + + uint32_t mcIdx; + uint32_t inChIdx; + uint32_t outChIdx; + +#ifdef WMOPS + wmops_sub_start( "prepareMcPassthrough" ); +#endif + + st->mcPassthrough = count_calloc( st->numInChannelsMc, sizeof( int32_t ) ); + + + if ( st->outConfig.speakerLayout == IVAS_REND_SPEAKER_LAYOUT_CUSTOM ) + { + /* Number of non-LFE output channels */ + numNonLfeOutChannels = st->outConfig.outSetupCustom->num_spk; + + /* Number of output channels */ + numOutChannels = st->outConfig.outSetupCustom->num_spk + st->outConfig.outSetupCustom->num_lfe; + + /* Output speaker coordinates */ + outSpkAzi = st->outConfig.outSetupCustom->ls_azimuth; + outSpkEle = st->outConfig.outSetupCustom->ls_elevation; + + /* num_spk + num_lfe must be <= MAX_OUTPUT_CHANNELS for custom loudspeaker layouts */ + if ( st->outConfig.outSetupCustom->num_lfe > 0 ) + { + lfeLastIdx_lsCustom[numNonLfeOutChannels] = st->outConfig.outSetupCustom->lfe_idx[0]; + } + + for ( outChIdx = 0; outChIdx < numNonLfeOutChannels; ++outChIdx ) + { + ( ( st->outConfig.outSetupCustom->num_lfe > 0 ) && ( (int16_t) outChIdx >= st->outConfig.outSetupCustom->lfe_idx[0] ) ) ? ( lfeLastIdx_lsCustom[outChIdx] = outChIdx + 1 ) : ( lfeLastIdx_lsCustom[outChIdx] = outChIdx ); + } + + lfeLastIdxs = &lfeLastIdx_lsCustom[0]; + } + else + { + /* Number of non-LFE output channels */ + numNonLfeOutChannels = getNumNonLfeChannelsInSpeakerLayout( st->outConfig.speakerLayout ); + + /* Number of output channels */ + numOutChannels = getNumChannelsInSpeakerLayout( st->outConfig.speakerLayout ); + + /* Output speaker coordinates */ + outSpkAzi = getSpeakerAzimuths( st->outConfig.speakerLayout ); + outSpkEle = getSpeakerElevations( st->outConfig.speakerLayout ); + + lfeLastIdxs = getReorderedChannelIndices( st->outConfig.speakerLayout ); + } + + passThroughIdx = 0; + for ( mcIdx = 0; mcIdx < st->inConfig.numMultiChannelBuses; ++mcIdx ) + { + if ( st->inConfig.multiChannelBuses[mcIdx].speakerLayout == IVAS_REND_SPEAKER_LAYOUT_CUSTOM ) + { + /* Number of non-LFE input channels for current MC input */ + numNonLfeInChannels = st->inConfig.inSetupCustom->num_spk; + + /* Number of input channels for current MC input */ + numInChannels = st->inConfig.inSetupCustom->num_spk + st->inConfig.inSetupCustom->num_lfe; + + /* Input speaker coordinates */ + inSpkAzi = st->inConfig.inSetupCustom->ls_azimuth; + inSpkEle = st->inConfig.inSetupCustom->ls_elevation; + } + else + { + /* Number of non-LFE input channels for current MC input */ + numNonLfeInChannels = getNumNonLfeChannelsInSpeakerLayout( st->inConfig.multiChannelBuses[mcIdx].speakerLayout ); + + /* Number of input channels for current MC input */ + numInChannels = getNumChannelsInSpeakerLayout( st->inConfig.multiChannelBuses[mcIdx].speakerLayout ); + + /* Input speaker coordinates */ + inSpkAzi = getSpeakerAzimuths( st->inConfig.multiChannelBuses[mcIdx].speakerLayout ); + inSpkEle = getSpeakerElevations( st->inConfig.multiChannelBuses[mcIdx].speakerLayout ); + } + + /* Check if passthrough is possible, save I/O mapping */ + for ( inChIdx = 0; inChIdx < numNonLfeInChannels; ++inChIdx ) + { + st->mcPassthrough[passThroughIdx] = -1; + + for ( outChIdx = 0; outChIdx < numNonLfeOutChannels; ++outChIdx ) + { + if ( inSpkAzi[inChIdx] == outSpkAzi[outChIdx] && + inSpkEle[inChIdx] == outSpkEle[outChIdx] ) + { + st->mcPassthrough[passThroughIdx] = lfeLastIdxs[outChIdx]; + break; + } + } + + ++passThroughIdx; + } + + /* Setup LFE passthrough, save I/O mapping */ + outChIdx = numNonLfeOutChannels; + for ( ; inChIdx < numInChannels; ++inChIdx ) + { + if ( outChIdx < numOutChannels ) + { + st->mcPassthrough[passThroughIdx] = lfeLastIdxs[outChIdx]; + } + else + { + st->mcPassthrough[passThroughIdx] = -1; + } + + ++outChIdx; + ++passThroughIdx; + } + } + +#ifdef WMOPS + wmops_sub_end(); +#endif +} + +static void passthroughChannel( const IVAS_REND_AudioBuffer inAudio, + const uint32_t srcChnlIdx, + const uint32_t dstChnlIdx, + const float gain_lin, + IVAS_REND_AudioBuffer outAudio ) +{ + float *inSmpl; + float *outSmpl; + int16_t smplIdx; + +#ifdef WMOPS + wmops_sub_start( "passthroughChannel" ); +#endif + + inSmpl = get_smpl_ptr( inAudio, srcChnlIdx, 0 ); + outSmpl = get_smpl_ptr( outAudio, dstChnlIdx, 0 ); + + for ( smplIdx = 0; smplIdx < inAudio.config.bufferSize; ++smplIdx ) + { + *outSmpl += *inSmpl * gain_lin; + + ++outSmpl; + ++inSmpl; + } + +#ifdef WMOPS + wmops_sub_end(); +#endif +} + +static void getSpeakerGains( const IVAS_REND_HANDLE st, + const float azi, + const float ele, + float *const spkGains ) +{ + const uint32_t *lfeLastIdxs; + int16_t numNonLfeOutChannels; + int16_t noLfeIdx; + IVAS_REND_SpeakerLayout speakerLayout; + +#ifdef WMOPS + wmops_sub_start( "getSpeakerGains" ); +#endif + + /* EFAP returns an array of gains only for non-LFE speakers */ + efap_determine_gains( st->efapRenderer, st->noLfePanBuffer, azi, ele, EFAP_MODE_EFAP ); + + speakerLayout = st->outConfig.speakerLayout; + if ( speakerLayout == IVAS_REND_SPEAKER_LAYOUT_CUSTOM ) + { + uint32_t lfeIdx; + + numNonLfeOutChannels = st->outConfig.outSetupCustom->num_spk; + + /* Clear speaker gains - not all elements will be overwritten below */ + set_zero( spkGains, numNonLfeOutChannels + st->outConfig.outSetupCustom->num_lfe ); + + /* Copy to gain array where LFE channel(s) are included */ + for ( lfeIdx = 0, noLfeIdx = 0; noLfeIdx < numNonLfeOutChannels; lfeIdx++, noLfeIdx++ ) + { + if ( noLfeIdx == st->outConfig.outSetupCustom->lfe_idx[0] ) + { + lfeIdx++; + } + spkGains[lfeIdx] = st->noLfePanBuffer[noLfeIdx]; + } + } + else + { + numNonLfeOutChannels = getNumNonLfeChannelsInSpeakerLayout( speakerLayout ); + lfeLastIdxs = getReorderedChannelIndices( speakerLayout ); + + /* Clear speaker gains - not all elements will be overwritten below */ + set_zero( spkGains, getNumChannelsInSpeakerLayout( speakerLayout ) ); + + /* Copy to gain array where LFE channel(s) are included */ + for ( noLfeIdx = 0; noLfeIdx < numNonLfeOutChannels; ++noLfeIdx ) + { + spkGains[lfeLastIdxs[noLfeIdx]] = st->noLfePanBuffer[noLfeIdx]; + } + } + +#ifdef WMOPS + wmops_sub_end(); +#endif +} + +int16_t getNumChannelsAmbisonics( IVAS_REND_Ambisonics ambisonics ) +{ + switch ( ambisonics ) + { + case IVAS_REND_AMBISONICS_NONE: + return 0; + case IVAS_REND_AMBISONICS_MONO: + return 1; + case IVAS_REND_AMBISONICS_FOA: + return 4; + case IVAS_REND_AMBISONICS_SOA: + return 9; + case IVAS_REND_AMBISONICS_TOA: + return 16; + default: + assert( !"Invalid ambisonics config" ); + } + + return 0; +} + +static int16_t getAmbisonicsOrder( IVAS_REND_Ambisonics ambisonics ) +{ + assert( ambisonics != IVAS_REND_AMBISONICS_NONE && "Invalid ambisonics config" ); + return ambisonics; /* Enum values map to ambisonics order */ +} + +int16_t getNumChannelsInSpeakerLayout( IVAS_REND_SpeakerLayout layout ) +{ + switch ( layout ) + { + case IVAS_REND_SPEAKER_LAYOUT_NONE: + return 0; + case IVAS_REND_SPEAKER_LAYOUT_MONO: + return 1; + case IVAS_REND_SPEAKER_LAYOUT_STEREO: + return 2; + case IVAS_REND_SPEAKER_LAYOUT_5_1: + return 6; + case IVAS_REND_SPEAKER_LAYOUT_5_1_2: + case IVAS_REND_SPEAKER_LAYOUT_7_1: + return 8; + case IVAS_REND_SPEAKER_LAYOUT_5_1_4: + return 10; + case IVAS_REND_SPEAKER_LAYOUT_7_1_4: + return 12; + default: + assert( !"Invalid speaker layout" ); + } + + return 0; +} + +int16_t getNumNonLfeChannelsInSpeakerLayout( IVAS_REND_SpeakerLayout layout ) +{ + switch ( layout ) + { + case IVAS_REND_SPEAKER_LAYOUT_MONO: + return 1; + case IVAS_REND_SPEAKER_LAYOUT_STEREO: + return 2; + case IVAS_REND_SPEAKER_LAYOUT_5_1: + return 5; + case IVAS_REND_SPEAKER_LAYOUT_5_1_2: + case IVAS_REND_SPEAKER_LAYOUT_7_1: + return 7; + case IVAS_REND_SPEAKER_LAYOUT_5_1_4: + return 9; + case IVAS_REND_SPEAKER_LAYOUT_7_1_4: + return 11; + default: + assert( !"Invalid speaker layout" ); + } + + return 0; +} + +const float *getSpeakerAzimuths( IVAS_REND_SpeakerLayout layout ) +{ + switch ( layout ) + { + case IVAS_REND_SPEAKER_LAYOUT_MONO: + return ls_azimuth_CICP1; + case IVAS_REND_SPEAKER_LAYOUT_STEREO: + return ls_azimuth_CICP2; + case IVAS_REND_SPEAKER_LAYOUT_5_1: + return ls_azimuth_CICP6; + case IVAS_REND_SPEAKER_LAYOUT_7_1: + return ls_azimuth_CICP12; + case IVAS_REND_SPEAKER_LAYOUT_5_1_2: + return ls_azimuth_CICP14; + case IVAS_REND_SPEAKER_LAYOUT_5_1_4: + return ls_azimuth_CICP16; + case IVAS_REND_SPEAKER_LAYOUT_7_1_4: + return ls_azimuth_CICP19; + default: + assert( !"Invalid speaker layout" ); + } + + return NULL; +} + +const float *getSpeakerElevations( IVAS_REND_SpeakerLayout layout ) +{ + switch ( layout ) + { + case IVAS_REND_SPEAKER_LAYOUT_MONO: + return ls_elevation_CICP1; + case IVAS_REND_SPEAKER_LAYOUT_STEREO: + return ls_elevation_CICP2; + case IVAS_REND_SPEAKER_LAYOUT_5_1: + return ls_elevation_CICP6; + case IVAS_REND_SPEAKER_LAYOUT_7_1: + return ls_elevation_CICP12; + case IVAS_REND_SPEAKER_LAYOUT_5_1_2: + return ls_elevation_CICP14; + case IVAS_REND_SPEAKER_LAYOUT_5_1_4: + return ls_elevation_CICP16; + case IVAS_REND_SPEAKER_LAYOUT_7_1_4: + return ls_elevation_CICP19; + default: + assert( !"Invalid speaker layout" ); + } + + return NULL; +} + +static const uint32_t *getReorderedChannelIndices( IVAS_REND_SpeakerLayout layout ) +{ + switch ( layout ) + { + case IVAS_REND_SPEAKER_LAYOUT_MONO: + return ls_LFE_last_idx_CICP1; + case IVAS_REND_SPEAKER_LAYOUT_STEREO: + return ls_LFE_last_idx_CICP2; + case IVAS_REND_SPEAKER_LAYOUT_5_1: + return ls_LFE_last_idx_CICP6; + case IVAS_REND_SPEAKER_LAYOUT_7_1: + return ls_LFE_last_idx_CICP12; + case IVAS_REND_SPEAKER_LAYOUT_5_1_2: + return ls_LFE_last_idx_CICP14; + case IVAS_REND_SPEAKER_LAYOUT_5_1_4: + return ls_LFE_last_idx_CICP16; + case IVAS_REND_SPEAKER_LAYOUT_7_1_4: + return ls_LFE_last_idx_CICP19; + default: + assert( !"Invalid speaker layout" ); + } + + return NULL; +} + +static int32_t reverseChannelIndexMapping( int32_t originalChannelIndex, const uint32_t *channelReorderingMap, uint32_t numNonLfeSpeakers ) +{ + int32_t i; + + for ( i = 0; i < (int32_t) numNonLfeSpeakers; ++i ) + { + if ( (int32_t) channelReorderingMap[i] == originalChannelIndex ) + { + return i; + } + } + + return -1; +} + +static ivas_error getHoaRenderMtx( + const IVAS_REND_OutputConfig outConfig, + float **decMtx, + uint32_t ambiOrder ) +{ + IVAS_OUTPUT_SETUP hOutSetup; + ivas_error error; + + error = IVAS_ERR_OK; + +#ifdef WMOPS + wmops_sub_start( "getHoaRenderMtx" ); +#endif + + switch ( outConfig.speakerLayout ) + { + case IVAS_REND_SPEAKER_LAYOUT_MONO: + ivas_output_init( &hOutSetup, AUDIO_CONFIG_MONO ); + hOutSetup.ls_azimuth = ls_azimuth_CICP1; + hOutSetup.ls_elevation = ls_elevation_CICP1; + break; + case IVAS_REND_SPEAKER_LAYOUT_STEREO: + ivas_output_init( &hOutSetup, AUDIO_CONFIG_STEREO ); + break; + case IVAS_REND_SPEAKER_LAYOUT_5_1: + ivas_output_init( &hOutSetup, AUDIO_CONFIG_5_1 ); + break; + case IVAS_REND_SPEAKER_LAYOUT_7_1: + ivas_output_init( &hOutSetup, AUDIO_CONFIG_7_1 ); + break; + case IVAS_REND_SPEAKER_LAYOUT_5_1_2: + ivas_output_init( &hOutSetup, AUDIO_CONFIG_5_1_2 ); + break; + case IVAS_REND_SPEAKER_LAYOUT_5_1_4: + ivas_output_init( &hOutSetup, AUDIO_CONFIG_5_1_4 ); + break; + case IVAS_REND_SPEAKER_LAYOUT_7_1_4: + ivas_output_init( &hOutSetup, AUDIO_CONFIG_7_1_4 ); + break; + case IVAS_REND_SPEAKER_LAYOUT_CUSTOM: + ivas_ls_custom_setup( &hOutSetup, outConfig.outSetupCustom ); + break; + default: + assert( !"Invalid speaker config" ); + return IVAS_ERR_WRONG_PARAMS; + } + + if ( ( error = ivas_sba_get_hoa_dec_matrix( hOutSetup, decMtx, (int16_t) ambiOrder ) ) != IVAS_ERR_OK ) + { + return error; + } + + +#ifdef WMOPS + wmops_sub_end(); +#endif + + return error; +} + +void getHoaDecVecForAmbiChnl( + uint32_t ambiChnnlIdx, + const IVAS_REND_OutputConfig outConfig, + const float *decMtx, + float *decCoeffs ) +{ + + const uint32_t *lfeLastIdxs; + int16_t numNonLfeChannels; + int16_t nonLfeChIdx; + +#ifdef WMOPS + wmops_sub_start( "getHoaDecVecForAmbiChnl" ); +#endif + + + if ( outConfig.speakerLayout == IVAS_REND_SPEAKER_LAYOUT_CUSTOM ) + { + uint32_t lfeIdx; + + numNonLfeChannels = outConfig.outSetupCustom->num_spk; + + /* Clear speaker gains - not all elements will be overwritten below */ + set_zero( decCoeffs, numNonLfeChannels + outConfig.outSetupCustom->num_lfe ); + + /* Copy to gain array where LFE channel(s) are included */ + for ( lfeIdx = 0, nonLfeChIdx = 0; nonLfeChIdx < numNonLfeChannels; lfeIdx++, nonLfeChIdx++ ) + { + if ( nonLfeChIdx == outConfig.outSetupCustom->lfe_idx[0] ) + { + lfeIdx++; + } + decCoeffs[lfeIdx] = decMtx[16 * nonLfeChIdx + ambiChnnlIdx]; + } + } + else + { + numNonLfeChannels = getNumNonLfeChannelsInSpeakerLayout( outConfig.speakerLayout ); + + lfeLastIdxs = getReorderedChannelIndices( outConfig.speakerLayout ); + + /* Clear decoding coefficients - not all elements will be overwritten below */ + set_zero( decCoeffs, getNumChannelsInSpeakerLayout( outConfig.speakerLayout ) ); + + for ( nonLfeChIdx = 0; nonLfeChIdx < numNonLfeChannels; ++nonLfeChIdx ) + { + decCoeffs[lfeLastIdxs[nonLfeChIdx]] = decMtx[16 * nonLfeChIdx + ambiChnnlIdx]; + } + } + +#ifdef WMOPS + wmops_sub_end(); +#endif +} + +/*-------------------------------------------------------------------* + * ivas_limiter_renderer() + * + * In-place saturation control for multichannel buffers with adaptive release time + *-------------------------------------------------------------------*/ +static void ivas_limiter_renderer( + 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 c; + float **channels; + int16_t num_channels; + + /* return early if given bad parameters */ + if ( hLimiter == NULL || output == NULL || output_frame <= 0 ) + { + return; + } + + channels = hLimiter->channel_ptrs; + num_channels = hLimiter->num_channels; + + for ( c = 0; c < num_channels; ++c ) + { + channels[c] = output + c * output_frame; + } + + limiter_process( hLimiter, output_frame, threshold, 0, NULL ); + + return; +} + +static float dBToLin( const float gain_dB ) +{ + return powf( 10.f, gain_dB / 20.f ); +} + +static AUDIO_CONFIG mapRendLayoutToAudioConfig( IVAS_REND_SpeakerLayout speakerLayout ) +{ + switch ( speakerLayout ) + { + case IVAS_REND_SPEAKER_LAYOUT_MONO: + return AUDIO_CONFIG_MONO; + case IVAS_REND_SPEAKER_LAYOUT_STEREO: + return AUDIO_CONFIG_STEREO; + case IVAS_REND_SPEAKER_LAYOUT_5_1: + return AUDIO_CONFIG_5_1; + case IVAS_REND_SPEAKER_LAYOUT_7_1: + return AUDIO_CONFIG_7_1; + case IVAS_REND_SPEAKER_LAYOUT_5_1_2: + return AUDIO_CONFIG_5_1_2; + case IVAS_REND_SPEAKER_LAYOUT_5_1_4: + return AUDIO_CONFIG_5_1_4; + case IVAS_REND_SPEAKER_LAYOUT_7_1_4: + return AUDIO_CONFIG_7_1_4; + case IVAS_REND_SPEAKER_LAYOUT_CUSTOM: + return AUDIO_CONFIG_LS_CUSTOM; + case IVAS_REND_SPEAKER_LAYOUT_NONE: + default: + return AUDIO_CONFIG_INVALID; + } +} diff --git a/lib_rend/lib_rend.h b/lib_rend/lib_rend.h new file mode 100644 index 0000000000..536a6da997 --- /dev/null +++ b/lib_rend/lib_rend.h @@ -0,0 +1,212 @@ +/****************************************************************************************************** + + (C) 2022 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_REND_H +#define LIB_REND_H + +#include +#include +#include + +#include "options.h" +#include "common_api_types.h" +#include "ivas_error.h" + +#define RENDERER_MAX_ISM_INPUTS 4 +#define RENDERER_MAX_MC_INPUTS 1 +#define RENDERER_MAX_SBA_INPUTS 1 + +#define RENDERER_HEAD_POSITIONS_PER_FRAME 4 + +typedef enum IVAS_REND_Ambisonics +{ + IVAS_REND_AMBISONICS_NONE = -1, + IVAS_REND_AMBISONICS_MONO = 0, + IVAS_REND_AMBISONICS_FOA = 1, + IVAS_REND_AMBISONICS_SOA = 2, + IVAS_REND_AMBISONICS_TOA = 3 +} IVAS_REND_Ambisonics; /* Numerical value corresponds to Ambisonics order */ + +typedef enum IVAS_REND_SpeakerLayout +{ + IVAS_REND_SPEAKER_LAYOUT_NONE = -1, + IVAS_REND_SPEAKER_LAYOUT_CUSTOM = 0, + IVAS_REND_SPEAKER_LAYOUT_MONO = 1, + IVAS_REND_SPEAKER_LAYOUT_STEREO = 2, + IVAS_REND_SPEAKER_LAYOUT_5_1 = 6, + IVAS_REND_SPEAKER_LAYOUT_5_1_2 = 14, + IVAS_REND_SPEAKER_LAYOUT_5_1_4 = 16, + IVAS_REND_SPEAKER_LAYOUT_7_1 = 12, + IVAS_REND_SPEAKER_LAYOUT_7_1_4 = 19 +} IVAS_REND_SpeakerLayout; /* Numerical value corresponds to CICP index */ + +typedef struct IVAS_REND_AudioObjectPosition +{ + float azimuth; + float elevation; +} IVAS_REND_AudioObjectPosition; + +typedef struct IVAS_REND_AudioObjectMetadataBuffer +{ + IVAS_REND_AudioObjectPosition positions[RENDERER_MAX_ISM_INPUTS]; + int16_t numObjects; +} IVAS_REND_AudioObjectMetadataBuffer; + +typedef struct IVAS_REND_AudioObject +{ + uint16_t inputChannelIndex; + float gain_dB; +} IVAS_REND_AudioObject; + +typedef struct IVAS_REND_ObjPanInfo +{ + IVAS_REND_AudioObjectPosition position; + float *panGains; +} IVAS_REND_ObjPanInfo; + +typedef struct IVAS_REND_AmbisonicsBus +{ + IVAS_REND_Ambisonics ambisonicsConfig; + uint8_t inputChannelIndex; + float gain_dB; +} IVAS_REND_AmbisonicsBus; + +typedef struct IVAS_REND_MultiChannelBus +{ + IVAS_REND_SpeakerLayout speakerLayout; + uint8_t inputChannelIndex; + float gain_dB; +} IVAS_REND_MultiChannelBus; + +typedef struct IVAS_REND_AudioBufferConfig +{ + int32_t sampleRate; + int16_t bufferSize; + int16_t numChannels; +} IVAS_REND_AudioBufferConfig; + +typedef struct IVAS_REND_AudioBuffer +{ + IVAS_REND_AudioBufferConfig config; + float *data; +} IVAS_REND_AudioBuffer; + +typedef struct IVAS_REND_InputConfig +{ + IVAS_REND_AudioObject audioObjects[RENDERER_MAX_ISM_INPUTS]; + uint16_t numAudioObjects; + IVAS_REND_MultiChannelBus multiChannelBuses[RENDERER_MAX_MC_INPUTS]; + uint16_t numMultiChannelBuses; + IVAS_REND_AmbisonicsBus ambisonicsBuses[RENDERER_MAX_SBA_INPUTS]; + uint16_t numAmbisonicsBuses; + IVAS_LSSETUP_CUSTOM_HANDLE inSetupCustom; +} IVAS_REND_InputConfig; + +typedef struct IVAS_REND_OutputConfig +{ + IVAS_REND_SpeakerLayout speakerLayout; + IVAS_REND_Ambisonics ambisonics; + IVAS_LSSETUP_CUSTOM_HANDLE outSetupCustom; + uint8_t binaural; /* flag */ +} IVAS_REND_OutputConfig; + +typedef struct IVAS_REND *IVAS_REND_HANDLE; + +/* clang-format off */ +/*----------------------------------------------------------------------------------* + * Function prototypes + *----------------------------------------------------------------------------------*/ + +/*! Creates a renderer state. + * r: pointer to opened renderer */ +IVAS_REND_HANDLE IVAS_REND_Open( /* TODO(sgi): Return ivas_error type */ + void +); + +/* TODO(sgi): Use hIvasRend as name for handle arg */ +/*! Configures the renderer - needs to be called after IVAS_REND_Open(). */ +ivas_error IVAS_REND_Configure( + IVAS_REND_HANDLE st, /* i : Renderer state */ + const IVAS_REND_InputConfig inConfig, /* i : Input configuration */ + const IVAS_REND_OutputConfig outConfig, /* i : Output configuration */ + uint32_t sampleRate, /* i : Processing sampling rate */ + bool headRotationEnabled /* i : enable head rotation for binaural output, ignored for other output formats */ +); + +void IVAS_REND_SetHeadRotation( + IVAS_REND_HANDLE st, + const IVAS_QUATERNION headRot[RENDERER_HEAD_POSITIONS_PER_FRAME] +); + +/*! Renders one frame of audio samples */ +void IVAS_REND_Render( + IVAS_REND_HANDLE st, /* i : Renderer state */ + const IVAS_REND_AudioBuffer inAudio, /* i : Buffer with pointer to input samples and associated info */ + const IVAS_REND_AudioObjectMetadataBuffer metadataBuffer, /* i : Buffer with object metadata for current frame */ + IVAS_REND_AudioBuffer outAudio /* o : Buffer with pointer to output samples and associated info */ +); + +/*! Returns the delay depending on which renderer was used */ +ivas_error IVAS_REND_GetDelay( + IVAS_REND_HANDLE st, /* 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 */ +); + +/*! Allocate memory for custom loudspeaker layout */ +void IVAS_REND_OpenCustomLayout( + IVAS_LSSETUP_CUSTOM_HANDLE *outSetupCustom ); + +/*! Enable/disable experimental LFE handling */ +void IVAS_REND_SetNeverDropLfe( + IVAS_REND_HANDLE st, /* i : Renderer state */ + int8_t neverDropLfe /* i : If 0, LFE channel will be dropped when rendering to configs w/o LFE. + If 1, tries to render LFE into other channels in an optimal way when rendering to configs w/o LFE. */ +); + +/*! Get number of input channels based on InputConfig */ +int16_t IVAS_REND_GetInChannels( + IVAS_REND_HANDLE st /* i : Renderer state */ +); + +/*! Get number of output channels based on OutputConfig */ +int16_t IVAS_REND_GetOutChannels( + IVAS_REND_HANDLE st /* i : Renderer state */ +); + +/*! Destructs the renderer state and frees memory */ +void IVAS_REND_Close( + IVAS_REND_HANDLE* st /* i : Renderer state */ +); +/* clang-format on */ + +#endif /* LIB_REND_H */ diff --git a/lib_util/cmdln_parser.c b/lib_util/cmdln_parser.c new file mode 100644 index 0000000000..323ed3fee6 --- /dev/null +++ b/lib_util/cmdln_parser.c @@ -0,0 +1,375 @@ +/****************************************************************************************************** + + (C) 2022 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 "cmdln_parser.h" + +#include +#include +#include +#include + +#define MAX_SUPPORTED_OPTS ( 1024 ) +#define MAX_OPTION_LENGTH ( 1024 ) + +typedef CmdLnParser_Option OptionProps; + +typedef struct +{ + OptionProps props; + int8_t hasBeenParsed; +} Option; + +static int16_t validateNoDuplicateIds( const OptionProps *props, int32_t numOpts ) +{ + for ( int32_t i = 0; i < numOpts; ++i ) + { + for ( int32_t j = i + 1; j < numOpts; ++j ) + { + if ( props[i].id == props[j].id ) + { + fprintf( stderr, "[dev] Duplicate ID == %d between options %s and %s\n", props[i].id, props[i].match, props[j].match ); + return -1; + } + } + } + + return 0; +} + +static int16_t validateOptionProps( OptionProps props ) +{ + /* Check required properties */ + if ( props.match == NULL ) + { + /* TODO(sgi): Don't print out usage after this - props.match is used there */ + fprintf( stderr, "[dev] Option with ID == %d - missing required property \"match\"\n", props.id ); + return -1; + } + + if ( props.id == 0 ) + { + fprintf( stderr, "[dev] Invalid ID for option %s. ID == %d is reserved.\n", props.match, props.id ); + return -1; + } + + return 0; +} + +/* Validate given OptionProps and use them to initialize array of Options */ +static int16_t initOpts( const OptionProps *options, int32_t numOpts, Option *opts ) +{ + for ( int32_t i = 0; i < numOpts; ++i ) + { + if ( validateOptionProps( options[i] ) != 0 ) + { + return -1; + } + + Option tmp = { + .hasBeenParsed = 0 + }; + tmp.props = options[i]; /* Cannot assign in aggregate initializer above - causes Visual Studio warning */ + + opts[i] = tmp; + } + + /* Check for duplicate IDs */ + if ( validateNoDuplicateIds( options, numOpts ) != 0 ) + { + return -1; + } + + return 0; +} + +static int8_t stringLooksLikeOption( const char *str ) +{ + if ( str[0] == '-' ) + { + return 1; + } + + return 0; +} + +static const char *stringToOptionName( const char *str ) +{ + while ( *str == '-' ) + { + ++str; + } + + return str; +} + +static int8_t optionMatchesString( Option opt, const char *str ) +{ + if ( !stringLooksLikeOption( str ) ) + { + return 0; + } + + const char *optionName = stringToOptionName( str ); + + if ( strncmp( optionName, opt.props.match, MAX_OPTION_LENGTH ) == 0 || strncmp( optionName, opt.props.matchShort, MAX_OPTION_LENGTH ) == 0 ) + { + return 1; + } + + return 0; +} + +static int16_t parseOpts( int32_t argc, + char **argv, + Option *opts, + int32_t numOpts, + void *pOutputStruct, + CmdLnParser_FnPtr_ParseOption parseOption ) +{ + Option *currOpt = NULL; + int32_t currOptIdx = 1; + Option *nextOpt = NULL; + int32_t nextOptIdx = 0; + int16_t numValues = 0; + + /* Go through all given argv */ + for ( int32_t argIdx = 1; argIdx < argc; ++argIdx ) + { + /* For current argument from argv go through all options and try to match */ + for ( int32_t optIdx = 0; optIdx < numOpts; ++optIdx ) + { + Option *optToMatch = &opts[optIdx]; + if ( optionMatchesString( *optToMatch, argv[argIdx] ) ) + { + nextOpt = optToMatch; + nextOptIdx = argIdx; + + /* Check if already parsed */ + if ( optToMatch->hasBeenParsed ) + { + fprintf( stderr, "Duplicate option: %s (%s)\n", optToMatch->props.match, optToMatch->props.matchShort ); + return -1; + } + + break; + } + } + + /* If no option matched, it is either a value belonging to current option or an invalid option */ + if ( nextOpt == NULL ) + { + /* Invalid option */ + if ( stringLooksLikeOption( argv[argIdx] ) ) + { + fprintf( stderr, "Unknown option `%s`\n", stringToOptionName( argv[argIdx] ) ); + return -1; + } + + /* Otherwise, value following current option. + * Exception: at the beginning of parsing (when current option is NULL) no values are allowed, throw error*/ + if ( currOpt != NULL ) + { + ++numValues; + } + else + { + fprintf( stderr, "Unexpected token `%s`\n", argv[argIdx] ); + return -1; + } + } + + /* If current argument is a recognized option or no more arguments left, parse current option into output struct*/ + if ( nextOpt != NULL || argIdx + 1 == argc ) + { + /* currOpt will be NULL when first nextOpt matches */ + if ( currOpt != NULL ) + { + parseOption( currOpt->props.id, &argv[currOptIdx + 1], numValues, pOutputStruct ); + currOpt->hasBeenParsed = 1; + } + + currOpt = nextOpt; + currOptIdx = nextOptIdx; + nextOpt = NULL; + nextOptIdx = 0; + numValues = 0; + } + } + + return 0; +} + +static int16_t validateOpts( const Option *opts, + int32_t numOpts ) +{ + for ( int32_t i = 0; i < numOpts; ++i ) + { + const Option *currOpt = &opts[i]; + + if ( currOpt->props.isRequired && !currOpt->hasBeenParsed ) + { + fprintf( stderr, "Error: option --%s (-%s) is required, but was not provided\n", currOpt->props.match, currOpt->props.matchShort ); + return -1; + } + } + + return 0; +} + +static const char *getBasename( const char *path ) +{ + /* Find last forward slash in path */ + const char *namePtr = strrchr( path, '/' ); + if ( namePtr != NULL ) + { + return namePtr + 1; + } + + /* If not found, try to find last backslash in path */ + namePtr = strrchr( path, '\\' ); + if ( namePtr != NULL ) + { + return namePtr + 1; + } + + /* If also not found, return full path, which implictly should be the basename */ + return path; +} + +static int32_t totalOptionNameLength( const OptionProps opt ) +{ + return strlen( opt.match ) + strlen( opt.matchShort ); +} + +static void printWhitespace( int32_t n ) +{ + for ( int32_t i = 0; i < n; ++i ) + { + fprintf( stderr, " " ); + } +} + +static void printOptDescriptionAligned( const char *descPtr, int32_t descriptionColumnIdx ) +{ + if ( descPtr == NULL ) + { + fprintf( stderr, "\n" ); + return; + } + + while ( 1 ) + { + if ( *descPtr == '\0' ) + { + fprintf( stderr, "\n" ); + break; + } + + fprintf( stderr, "%c", *descPtr ); + if ( *descPtr == '\n' ) + { + printWhitespace( descriptionColumnIdx ); + } + ++descPtr; + } +} + +static void printUsage( + const char *argv0, + const OptionProps *optionProps, + int32_t numOptions ) +{ + fprintf( stderr, "\n" ); + fprintf( stderr, "Usage: %s [options]\n", getBasename( argv0 ) ); + fprintf( stderr, "\n" ); + fprintf( stderr, "Valid options:\n" ); + + /* Find option with longest name, used for pretty formatting */ + int32_t maxOptNameLength = 0; + for ( int32_t i = 0; i < numOptions; ++i ) + { + const int32_t optNameLength = totalOptionNameLength( optionProps[i] ); + if ( maxOptNameLength < optNameLength ) + { + maxOptNameLength = optNameLength; + } + } + + const int32_t preDescriptionWhitespace = 8; + const int32_t leftColumnAdditionalChars = 7; + for ( int32_t i = 0; i < numOptions; ++i ) + { + OptionProps opt = optionProps[i]; + const int32_t optNameLength = totalOptionNameLength( optionProps[i] ); + + /* TODO(sgi): make matchShort optional */ + fprintf( stderr, " --%s, -%s", opt.match, opt.matchShort ); + + printWhitespace( maxOptNameLength - optNameLength + preDescriptionWhitespace ); + printOptDescriptionAligned( opt.description, maxOptNameLength + preDescriptionWhitespace + leftColumnAdditionalChars ); + } +} + +int16_t CmdLnParser_parseArgs( int32_t argc, + char **argv, + const OptionProps *optionProps, + int32_t numOptions, + void *pOutputStruct, + CmdLnParser_FnPtr_ParseOption parseOption ) +{ + assert( numOptions <= MAX_SUPPORTED_OPTS ); + + /* Prepare option array */ + Option opts[MAX_SUPPORTED_OPTS]; + if ( initOpts( optionProps, numOptions, opts ) != 0 ) + { + goto fail; + } + + /* Iterate over argv and parse */ + if ( parseOpts( argc, argv, opts, numOptions, pOutputStruct, parseOption ) != 0 ) + { + goto fail; + } + + /* Validate parsed options */ + if ( validateOpts( opts, numOptions ) != 0 ) + { + goto fail; + } + + return 0; + +fail: + printUsage( argv[0], optionProps, numOptions ); + return -1; +} diff --git a/lib_util/ivas_rom_prerenderer.h b/lib_util/cmdln_parser.h similarity index 66% rename from lib_util/ivas_rom_prerenderer.h rename to lib_util/cmdln_parser.h index 6be6ae9863..692072df63 100644 --- a/lib_util/ivas_rom_prerenderer.h +++ b/lib_util/cmdln_parser.h @@ -30,24 +30,34 @@ *******************************************************************************************************/ -#ifndef IVAS_ROM_PRERENDERER_H -#define IVAS_ROM_PRERENDERER_H +#ifndef CMDLN_PARSER_H +#define CMDLN_PARSER_H #include + #include "options.h" -/*----------------------------------------------------------------------------------* - * Prerenderer SBA & MC enc/dec matrices - *----------------------------------------------------------------------------------*/ - -extern const float hoa_dec_mtx_CICP1[16]; -extern const float ls_azimuth_CICP1[1]; -extern const float ls_elevation_CICP1[1]; -extern const uint32_t ls_LFE_last_idx_CICP1[1]; -extern const uint32_t ls_LFE_last_idx_CICP2[2]; -extern const uint32_t ls_LFE_last_idx_CICP6[6]; -extern const uint32_t ls_LFE_last_idx_CICP12[8]; -extern const uint32_t ls_LFE_last_idx_CICP16[10]; -extern const uint32_t ls_LFE_last_idx_CICP19[12]; - -#endif /* IVAS_ROM_PRERENDERER_H */ +typedef struct +{ + int32_t id; + const char *match; + const char *matchShort; + int8_t isRequired; + const char *description; +} CmdLnParser_Option; + +/* Function for parsing option values into an output struct, to be implemented by the user */ +typedef void ( *CmdLnParser_FnPtr_ParseOption )( int32_t optionId, /* i : option ID of matched option */ + char **optionValues, /* i : array of string values following the matched option in argv */ + int16_t numOptionValues, /* i : number of string values following the matched option in argv */ + void *pOutputStruct /* o : struct to store parsed values */ +); + +int16_t CmdLnParser_parseArgs( int32_t argc, + char **argv, + const CmdLnParser_Option *options, + int32_t numOptions, + void *pOutputStruct, + CmdLnParser_FnPtr_ParseOption parseOption ); + +#endif /* CMDLN_PARSER_H */ diff --git a/lib_util/ivas_prerenderer.c b/lib_util/ivas_prerenderer.c deleted file mode 100644 index a2c0b4c710..0000000000 --- a/lib_util/ivas_prerenderer.c +++ /dev/null @@ -1,1733 +0,0 @@ -/****************************************************************************************************** - - (C) 2022 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_prerenderer.h" -#include "ivas_prot.h" -#include "ivas_rom_com.h" -#include "ivas_rom_dec.h" -#include "ivas_rom_prerenderer.h" -#include "prot.h" -#include "wmops.h" - -#include -#include -#include -#include -#include - -#define LIMITER_THRESHOLD 0.9988493699f /* -0.01 dBFS */ - -struct Prndr_Prerenderer -{ - uint32_t sampleRate; - - int8_t isConfigured; /* flag */ - int8_t firstFrame; /* flag */ - - /* I/O */ - Prndr_InputConfig inConfig; - Prndr_OutputConfig outConfig; - - /* =========== Panning =========== */ - EFAP_HANDLE efapRenderer; - - Prndr_ObjPanInfo *objPanInfo; /* size: [numInObjects] */ - - float ***speakerPanGains; /* size: [numInMc][numSpeakers][numOutChannels] */ - - float *tmpGainBuffer; /* size: [numOutChannels] */ - float *noLfePanBuffer; /* size: [numOutChannels] */ - float *crossfade; /* size: [frameSize] */ - /* =============================== */ - - /* Helpers */ - int16_t numOutChannels; /* Total number of output channels */ - int16_t numInChannels; /* Total number of input channels */ - int16_t numInChannelsObj; /* Total number of input channels of object inputs */ - int16_t numInChannelsAmbi; /* Total number of input channels of ambisonics inputs */ - int16_t numInChannelsMc; /* Total number of input channels of multichannel inputs */ - - /* For each channel of MC inputs mcPassThrough contains the corresponding - * output channel index if a passthrough is possible, otherwise contains -1 */ - int32_t *mcPassthrough; /* size: [numInChannelsMc] */ - - /* =========== LFE Handling =========== */ - /* Do not drop LFE when rendering to a layout that does not have - * an LFE channel - render LFE into other channels*/ - int8_t neverDropLfe; /* flag */ - float *lfePanGains; - - /* =========== limiter handle =========== */ - IVAS_LIMITER_HANDLE hLimiter; - - /* Ambisonics decoding matrix */ - float *ambi_dec_mtx; -}; - -/*---------------------------------------------------------------------* - * Prototypes - *---------------------------------------------------------------------*/ -/* clang-off */ -static void renderAmbiToAmbi( - const Prndr_Prerenderer *const st, - const Prndr_AudioBuffer inAudio, - Prndr_AudioBuffer outAudio ); - -static void renderChannelsToAmbi( - Prndr_Prerenderer *const st, - const Prndr_AudioBuffer inAudio, - Prndr_AudioBuffer outAudio ); - -static void renderObjectsToAmbi( - Prndr_Prerenderer *const st, - const Prndr_AudioBuffer inAudio, - const Prndr_AudioObjectMetadataBuffer metadataBuffer, - Prndr_AudioBuffer outAudio ); - -static void renderAmbiToChannels( - const Prndr_Prerenderer *const st, - const Prndr_AudioBuffer inAudio, - Prndr_AudioBuffer outAudio ); - -static void renderChannelsToChannels( - const Prndr_Prerenderer *const st, - const Prndr_AudioBuffer inAudio, - Prndr_AudioBuffer outAudio ); - -static void renderObjectsToChannels( - Prndr_Prerenderer *const st, - const Prndr_AudioBuffer inAudio, - const Prndr_AudioObjectMetadataBuffer metadataBuffer, - Prndr_AudioBuffer outAudio ); - -static void renderSingleObjectToAmbi( - Prndr_Prerenderer *const st, - const Prndr_AudioBuffer inAudio, - const uint32_t itemChnlIdx, /* Index of the item within input audio buffer */ - Prndr_ObjPanInfo *prevPanInfo, - const Prndr_AudioObjectPosition curFrmPos, - const float gain_lin, - Prndr_AudioBuffer outAudio ); - -static void renderSingleObjectToChannels( - Prndr_Prerenderer *const st, - const Prndr_AudioBuffer inAudio, - const uint32_t itemChnlIdx, /* Index of the item within input audio buffer */ - Prndr_ObjPanInfo *prevPanInfo, - const Prndr_AudioObjectPosition curFrmPos, - const float gain_lin, - Prndr_AudioBuffer outAudio ); - -/* Multiply a single channel by a vector of gains and add result to corresponding output channels */ -static void applyChannelGainsAndAddToOutput( - const Prndr_AudioBuffer inAudio, - const uint32_t itemChnlIdx, /* Index of the item within input audio buffer */ - const float *const gainsCurrent, /* Vector of gains for current frame, corresponding to output channels */ - const float *const gainsPrev, /* Vector of previously applied gains, used for interpolation. Set to NULL for no interpolation */ - const float gain_lin, /* Additional linear gain to be applied when mixing with output buffer */ - const float *const crossfade, - Prndr_AudioBuffer outAudio ); - -static void prepareMcPanGains( - Prndr_Prerenderer *const st ); - -static void prepareLfeHandling( - Prndr_Prerenderer *const st ); - -static void prepareMcPassthrough( - Prndr_Prerenderer *const st ); - -static void passthroughChannel( - const Prndr_AudioBuffer inAudio, - const uint32_t srcChnlIdx, - const uint32_t dstChnlIdx, - const float gain_lin, - Prndr_AudioBuffer outAudio ); - -static void getSpeakerGains( - const Prndr_Prerenderer *const st, - const float azi, - const float ele, - float *const spkGains ); - -static int16_t Prndr_getNumChannelsAmbisonics( - Prndr_Ambisonics ambisonics ); - -static int16_t Prndr_getAmbisonicsOrder( - Prndr_Ambisonics ambisonics ); - -static int16_t Prndr_getNumChannelsInSpeakerLayout( - Prndr_SpeakerLayout layout ); - -static int16_t Prndr_getNumNonLfeChannelsInSpeakerLayout( - Prndr_SpeakerLayout layout ); - -static const float *Prndr_getSpeakerAzimuths( - Prndr_SpeakerLayout layout ); - -static const float *Prndr_getSpeakerElevations( - Prndr_SpeakerLayout layout ); - -static const uint32_t *Prndr_getReorderedChannelIndices( - Prndr_SpeakerLayout layout ); - -static ivas_error Prndr_getHoaRenderMtx( - const Prndr_OutputConfig outConfig, - float **decMtx, - uint32_t ambiOrder ); - -static void Prndr_getHoaDecVecForAmbiChnl( - uint32_t ambiChnnlIdx, - const Prndr_OutputConfig outConfig, - const float *decMtx, - float *decCoeffs ); - -static void ivas_limiter_prerenderer( - 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 */ -); - -static float dBToLin( const float gain_dB ); -/* clang-on */ -/* ========================================================================== */ - -Prndr_Prerenderer *Prndr_Prerenderer_open() -{ - Prndr_Prerenderer *st; - st = (Prndr_Prerenderer *) count_malloc( sizeof( Prndr_Prerenderer ) ); - st->isConfigured = 0; - st->efapRenderer = NULL; - - st->objPanInfo = NULL; - st->speakerPanGains = NULL; - st->tmpGainBuffer = NULL; - st->noLfePanBuffer = NULL; - st->crossfade = NULL; - st->mcPassthrough = NULL; - st->neverDropLfe = 0; - st->lfePanGains = NULL; - st->hLimiter = NULL; - st->ambi_dec_mtx = NULL; - - return st; -} - -ivas_error Prndr_Prerenderer_configure( Prndr_Prerenderer *const st, - const Prndr_InputConfig inConfig, - const Prndr_OutputConfig outConfig, - int32_t frameSize, - uint32_t sampleRate ) -{ - uint32_t i; - int32_t j; - ivas_error error; - - error = IVAS_ERR_OK; - - /* ============================= Error checks ============================= */ - assert( st != NULL && "Can't configure prerenderer - pointer is NULL" ); - assert( !st->isConfigured && "Re-configuring a prerenderer is not supported" ); - assert( !( outConfig.ambisonics != prndr_ambisonics_none && outConfig.speakerLayout != prndr_speaker_layout_none ) && "Multiple outputs not supported" ); - assert( !( outConfig.ambisonics == prndr_ambisonics_none && outConfig.speakerLayout == prndr_speaker_layout_none ) && "At least one output must be selected" ); - assert( !( inConfig.numAudioObjects == 0 && inConfig.numMultiChannelBuses == 0 && inConfig.numAmbisonicsBuses == 0 ) && "At least one input must be active" ); - - /* ========================== Store useful values ========================= */ - st->sampleRate = sampleRate; - st->isConfigured = 1; - st->firstFrame = 1; - st->inConfig = inConfig; - st->outConfig = outConfig; - - /* Save total number of channels in ambisonics inputs */ - st->numInChannelsAmbi = 0; - for ( i = 0; i < inConfig.numAmbisonicsBuses; ++i ) - { - st->numInChannelsAmbi += Prndr_getNumChannelsAmbisonics( inConfig.ambisonicsBuses[i].ambisonicsConfig ); - } - - /* Save total number of channels in MC input */ - st->numInChannelsMc = 0; - for ( i = 0; i < inConfig.numMultiChannelBuses; ++i ) - { - st->numInChannelsMc += Prndr_getNumChannelsInSpeakerLayout( inConfig.multiChannelBuses[i].speakerLayout ); - } - - /* Save total number of channels of audio object inputs */ - st->numInChannelsObj = st->inConfig.numAudioObjects; - - /* Save total number of input channels */ - st->numInChannels = st->numInChannelsObj + st->numInChannelsAmbi + st->numInChannelsMc; - - if ( st->outConfig.ambisonics != prndr_ambisonics_none ) - { - /* Save number of output channels */ - st->numOutChannels = Prndr_getNumChannelsAmbisonics( st->outConfig.ambisonics ); - } - - /* ============================ Prepare panning and ambisonics =========================== */ - if ( st->outConfig.speakerLayout != prndr_speaker_layout_none ) - { - if ( st->outConfig.speakerLayout == prndr_speaker_layout_custom ) - { - /* Save number of output channels */ - st->numOutChannels = st->outConfig.outSetupCustom->num_spk + st->outConfig.outSetupCustom->num_lfe; - - /* Open and initialize EFAP struct */ - if ( ( error = efap_init_data( &st->efapRenderer, st->outConfig.outSetupCustom->ls_azimuth, st->outConfig.outSetupCustom->ls_elevation, st->outConfig.outSetupCustom->num_spk, EFAP_MODE_EFAP ) ) != IVAS_ERR_OK ) - { - return error; - } - } - else - { - /* Save number of output channels */ - st->numOutChannels = Prndr_getNumChannelsInSpeakerLayout( st->outConfig.speakerLayout ); - - /* Open and initialize EFAP struct */ - if ( ( error = efap_init_data( &st->efapRenderer, Prndr_getSpeakerAzimuths( st->outConfig.speakerLayout ), Prndr_getSpeakerElevations( st->outConfig.speakerLayout ), Prndr_getNumNonLfeChannelsInSpeakerLayout( st->outConfig.speakerLayout ), EFAP_MODE_EFAP ) ) != IVAS_ERR_OK ) - { - return error; - } - } - - - assert( st->efapRenderer != NULL && "Could not init EFAP" ); - - /* Compute Ambisonics to loudspeaker decoding matrix */ - if ( ( error = Prndr_getHoaRenderMtx( st->outConfig, &st->ambi_dec_mtx, 3 ) ) != IVAS_ERR_OK ) - { - return error; - } - } - - /* Allocate temporary pan/enc buffer to avoid allocations during rendering */ - st->tmpGainBuffer = count_calloc( st->numOutChannels, sizeof( float ) ); - - /* Allocate temporary buffer for panning gains with lfe omitted */ - if ( st->outConfig.speakerLayout != prndr_speaker_layout_none ) - { - if ( st->outConfig.speakerLayout == prndr_speaker_layout_custom ) - { - st->noLfePanBuffer = count_calloc( st->outConfig.outSetupCustom->num_spk, sizeof( float ) ); - } - else - { - st->noLfePanBuffer = count_calloc( Prndr_getNumNonLfeChannelsInSpeakerLayout( st->outConfig.speakerLayout ), sizeof( float ) ); - } - } - - /* Create lookup tables for panning/encoding speaker signals */ - if ( st->inConfig.numMultiChannelBuses != 0 ) - { - prepareMcPanGains( st ); - prepareLfeHandling( st ); - } - - /* Allocate structs for interpolation of object pan/enc gains between frames */ - if ( st->inConfig.numAudioObjects != 0 ) - { - st->objPanInfo = count_calloc( st->inConfig.numAudioObjects, sizeof( Prndr_ObjPanInfo ) ); - - for ( i = 0; i < st->inConfig.numAudioObjects; ++i ) - { - st->objPanInfo[i].panGains = count_calloc( st->numOutChannels, sizeof( float ) ); - } - } - - /* =========================== Prepare crossfades ========================= */ - st->crossfade = count_calloc( frameSize, sizeof( float ) ); - - for ( j = 0; j < frameSize; ++j ) - { - st->crossfade[j] = (float) j / ( frameSize - 1 ); - } - - /* ========================= Prepare optimizations ======================== */ - /* Make note of possible processing shortcuts in cases where input and output - * config is the same or similar. This only needs to be done for MC I/O, since - * Ambisonics I/O can always be passed through and objects can never be passed - * through */ - if ( st->inConfig.numMultiChannelBuses > 0 && st->outConfig.speakerLayout != prndr_speaker_layout_none ) - { - prepareMcPassthrough( st ); - } - - /* ============================ Configure limiter =========================== */ - st->hLimiter = ivas_limiter_open( st->numOutChannels, st->sampleRate ); - - return error; -} - -void Prndr_Prerenderer_render( - Prndr_Prerenderer *const st, - const Prndr_AudioBuffer inAudio, - const Prndr_AudioObjectMetadataBuffer metadataBuffer, - Prndr_AudioBuffer outAudio ) -{ -#ifdef WMOPS - wmops_sub_start( "Prndr_Prerenderer_render" ); -#endif - - /* ============================= Error checks ============================= */ - assert( st != NULL && "Can't render - prerenderer pointer is NULL" ); - assert( st->isConfigured && "Can't render - prerenderer pointer is not configured" ); - assert( inAudio.config.sampleRate == outAudio.config.sampleRate && "Input and output sample rate must be the same" ); - assert( inAudio.config.bufferSize == outAudio.config.bufferSize && "Input and output frame size must be the same" ); - assert( inAudio.config.numChannels == st->numInChannels && "Number of input channels does not match between prerenderer and input config" ); - assert( outAudio.config.numChannels == st->numOutChannels && "Number of input channels does not match between prerenderer and input config" ); - assert( inAudio.config.sampleRate != 0 && "Invalid sample rate" ); - assert( inAudio.config.bufferSize != 0 && "Invalid frame size" ); - assert( inAudio.data != NULL && "Can't render - input buffer is empty" ); - - /* ========================== Actual processing =========================== */ - /* Clear output buffer */ - set_zero( outAudio.data, outAudio.config.numChannels * outAudio.config.bufferSize ); - - /* Render target format: Ambisonics */ - if ( st->outConfig.ambisonics != prndr_ambisonics_none ) - { - if ( st->inConfig.numAmbisonicsBuses != 0 ) - { - renderAmbiToAmbi( st, inAudio, outAudio ); - } - - if ( st->inConfig.numMultiChannelBuses != 0 ) - { - renderChannelsToAmbi( st, inAudio, outAudio ); - } - - if ( st->inConfig.numAudioObjects != 0 ) - { - renderObjectsToAmbi( st, inAudio, metadataBuffer, outAudio ); - } - } /* Render target format: multichannel */ - else if ( st->outConfig.speakerLayout != prndr_speaker_layout_none ) - { - if ( st->inConfig.numAmbisonicsBuses != 0 ) - { - renderAmbiToChannels( st, inAudio, outAudio ); - } - - if ( st->inConfig.numMultiChannelBuses != 0 ) - { - renderChannelsToChannels( st, inAudio, outAudio ); - } - - if ( st->inConfig.numAudioObjects != 0 ) - { - renderObjectsToChannels( st, inAudio, metadataBuffer, outAudio ); - } - } - - /* Apply limiting in place */ - ivas_limiter_prerenderer( - st->hLimiter, - outAudio.data, - outAudio.config.bufferSize, - LIMITER_THRESHOLD ); - - if ( st->firstFrame ) - { - st->firstFrame = 0; - } - -#ifdef WMOPS - wmops_sub_end(); -#endif -} - -void Prndr_Prerenderer_setNeverDropLfe( - Prndr_Prerenderer *st, - int8_t neverDropLfe ) -{ - st->neverDropLfe = neverDropLfe; -} - -int16_t Prndr_Prerenderer_getInChannels( - Prndr_Prerenderer *st ) -{ - assert( st != NULL && "Can't get number of input channels - prerenderer pointer is NULL" ); - if ( st ) - { - return st->numInChannels; - } - return 0; -} - -int16_t Prndr_Prerenderer_getOutChannels( - Prndr_Prerenderer *st ) -{ - assert( st != NULL && "Can't get number of output channels - prerenderer pointer is NULL" ); - if ( st ) - { - return st->numOutChannels; - } - return 0; -} - -void Prndr_Prerenderer_close( Prndr_Prerenderer *st ) -{ - uint32_t i; - uint32_t j; - uint32_t numChannels; - assert( st != NULL && "Can't close prerenderer - pointer is NULL" ); - - if ( st->efapRenderer != NULL ) - { - efap_free_data( &st->efapRenderer ); - } - - if ( st->objPanInfo != NULL ) - { - for ( i = 0; i < st->inConfig.numAudioObjects; ++i ) - { - if ( st->objPanInfo[i].panGains != NULL ) - { - count_free( st->objPanInfo[i].panGains ); - } - } - - count_free( st->objPanInfo ); - } - - if ( st->speakerPanGains != NULL ) - { - for ( i = 0; i < st->inConfig.numMultiChannelBuses; ++i ) - { - numChannels = Prndr_getNumChannelsInSpeakerLayout( st->inConfig.multiChannelBuses[i].speakerLayout ); - - for ( j = 0; j < numChannels; ++j ) - { - count_free( st->speakerPanGains[i][j] ); - } - - count_free( st->speakerPanGains[i] ); - } - - count_free( st->speakerPanGains ); - } - - if ( st->outConfig.speakerLayout == prndr_speaker_layout_custom ) - { - count_free( st->outConfig.outSetupCustom ); - st->outConfig.outSetupCustom = NULL; - } - - if ( st->tmpGainBuffer != NULL ) - { - count_free( st->tmpGainBuffer ); - } - - if ( st->noLfePanBuffer != NULL ) - { - count_free( st->noLfePanBuffer ); - } - - if ( st->crossfade != NULL ) - { - count_free( st->crossfade ); - } - - if ( st->mcPassthrough != NULL ) - { - count_free( st->mcPassthrough ); - } - - if ( st->lfePanGains ) - { - count_free( st->lfePanGains ); - } - - if ( st->ambi_dec_mtx != NULL ) - { - count_free( st->ambi_dec_mtx ); - } - - ivas_limiter_close( &st->hLimiter ); - - count_free( st ); -} - -/* ============================= Local functions ============================ */ -static float *get_smpl_ptr( Prndr_AudioBuffer buffer, uint32_t chnlIdx, uint32_t smplIdx ) -{ - return buffer.data + chnlIdx * buffer.config.bufferSize + smplIdx; -} - -static void renderAmbiToAmbi( const Prndr_Prerenderer *const st, - const Prndr_AudioBuffer inAudio, - Prndr_AudioBuffer outAudio ) -{ - float *inSmpl; - float *outSmpl; - int16_t lastChannelIdx; - int16_t smplIdx; - int16_t chnlIdx; - uint32_t inAmbiChannelIdx; - uint32_t ambiIdx; - float gain_lin; - - -#ifdef WMOPS - wmops_sub_start( "renderAmbiToAmbi" ); -#endif - - /* Iterate over given Ambisonics inputs */ - for ( ambiIdx = 0; ambiIdx < st->inConfig.numAmbisonicsBuses; ++ambiIdx ) - { - inAmbiChannelIdx = st->inConfig.ambisonicsBuses[ambiIdx].inputChannelIndex; - - /* Find out how many channels to process */ - lastChannelIdx = min( Prndr_getNumChannelsAmbisonics( st->inConfig.ambisonicsBuses[ambiIdx].ambisonicsConfig ), st->numOutChannels ) - 1; - - gain_lin = dBToLin( st->inConfig.ambisonicsBuses[ambiIdx].gain_dB ); - - /* Passthrough channels */ - for ( chnlIdx = 0; chnlIdx <= lastChannelIdx; ++chnlIdx ) - { - inSmpl = get_smpl_ptr( inAudio, chnlIdx + inAmbiChannelIdx, 0 ); - outSmpl = get_smpl_ptr( outAudio, chnlIdx, 0 ); - - for ( smplIdx = 0; smplIdx < inAudio.config.bufferSize; ++smplIdx ) - { - *outSmpl += *inSmpl * gain_lin; - - ++inSmpl; - ++outSmpl; - } - } - } - -#ifdef WMOPS - wmops_sub_end(); -#endif -} - -static void renderChannelsToAmbi( Prndr_Prerenderer *const st, - const Prndr_AudioBuffer inAudio, - Prndr_AudioBuffer outAudio ) -{ - const uint32_t *lfeLastIdxs; - uint32_t inMcChannelIdx; - uint32_t numNonLfeInChannels; - uint32_t numInChannels; - uint32_t mcIdx; - uint32_t inChIdx; - float gain_lin; - -#ifdef WMOPS - wmops_sub_start( "renderChannelsToAmbi" ); -#endif - - /* Iterate over given MC inputs */ - for ( mcIdx = 0; mcIdx < st->inConfig.numMultiChannelBuses; ++mcIdx ) - { - /* Get channel idx of current MC input within the multitrack buffer */ - inMcChannelIdx = st->inConfig.multiChannelBuses[mcIdx].inputChannelIndex; - - /* Number of input speakers */ - numInChannels = Prndr_getNumChannelsInSpeakerLayout( st->inConfig.multiChannelBuses[mcIdx].speakerLayout ); - numNonLfeInChannels = Prndr_getNumNonLfeChannelsInSpeakerLayout( st->inConfig.multiChannelBuses[mcIdx].speakerLayout ); - - lfeLastIdxs = Prndr_getReorderedChannelIndices( st->inConfig.multiChannelBuses[mcIdx].speakerLayout ); - - gain_lin = dBToLin( st->inConfig.multiChannelBuses[mcIdx].gain_dB ); - - /* Iterate over channels */ - for ( inChIdx = 0; inChIdx < numNonLfeInChannels; ++inChIdx ) - { - applyChannelGainsAndAddToOutput( inAudio, - inMcChannelIdx + lfeLastIdxs[inChIdx], - st->speakerPanGains[mcIdx][inChIdx], - NULL, - gain_lin, - st->crossfade, - outAudio ); - } - - if ( st->neverDropLfe ) - { - /* Render LFE channels into the scene */ - for ( ; inChIdx < numInChannels; ++inChIdx ) - { - applyChannelGainsAndAddToOutput( inAudio, - inMcChannelIdx + lfeLastIdxs[inChIdx], - st->lfePanGains, - NULL, - gain_lin, - st->crossfade, - outAudio ); - } - } - } - -#ifdef WMOPS - wmops_sub_end(); -#endif -} - -static void renderObjectsToAmbi( - Prndr_Prerenderer *const st, - const Prndr_AudioBuffer inAudio, - const Prndr_AudioObjectMetadataBuffer metadataBuffer, - Prndr_AudioBuffer outAudio ) -{ - const Prndr_AudioObject *curObj; - uint32_t objIdx; - Prndr_AudioObjectPosition pos; - float gain_lin; - -#ifdef WMOPS - wmops_sub_start( "renderObjectsToAmbi" ); -#endif - - assert( st->inConfig.numAudioObjects == metadataBuffer.numObjects && "Metadata provided for a different number of objects than found in input" ); - - /* Iterate over given audio objects */ - for ( objIdx = 0; objIdx < st->inConfig.numAudioObjects; ++objIdx ) - { - /* Get pointer to current object and its metadata */ - curObj = &st->inConfig.audioObjects[objIdx]; - pos = metadataBuffer.positions[objIdx]; - gain_lin = dBToLin( st->inConfig.audioObjects[objIdx].gain_dB ); - - /* Render to ambisonics */ - renderSingleObjectToAmbi( - st, - inAudio, - curObj->inputChannelIndex, - &st->objPanInfo[objIdx], - pos, - gain_lin, - outAudio ); - } - -#ifdef WMOPS - wmops_sub_end(); -#endif -} - -static void renderAmbiToChannels( const Prndr_Prerenderer *const st, - const Prndr_AudioBuffer inAudio, - Prndr_AudioBuffer outAudio ) -{ - uint32_t inAmbiChannelIdx; - uint32_t ambiIdx; - uint32_t numInAmbiChnls; - uint32_t ambiChnIdx; - float gain_lin; - -#ifdef WMOPS - wmops_sub_start( "renderAmbiToChannels" ); -#endif - - /* Iterate over all given ambisonics inputs */ - for ( ambiIdx = 0; ambiIdx < st->inConfig.numAmbisonicsBuses; ++ambiIdx ) - { - inAmbiChannelIdx = st->inConfig.ambisonicsBuses[ambiIdx].inputChannelIndex; - - /* Number of input channels */ - numInAmbiChnls = Prndr_getNumChannelsAmbisonics( st->inConfig.ambisonicsBuses[ambiIdx].ambisonicsConfig ); - - gain_lin = dBToLin( st->inConfig.multiChannelBuses[ambiIdx].gain_dB ); - - /* Render each ambisonics channel */ - for ( ambiChnIdx = 0; ambiChnIdx < numInAmbiChnls; ++ambiChnIdx ) - { - /* Write decoding gains to temp buffer */ - Prndr_getHoaDecVecForAmbiChnl( ambiChnIdx, st->outConfig, st->ambi_dec_mtx, st->tmpGainBuffer ); - - /* Apply decoding gains and add to output */ - applyChannelGainsAndAddToOutput( inAudio, - inAmbiChannelIdx + ambiChnIdx, - st->tmpGainBuffer, - NULL, - gain_lin, - st->crossfade, - outAudio ); - } - } - -#ifdef WMOPS - wmops_sub_end(); -#endif -} - -static void renderChannelsToChannels( - const Prndr_Prerenderer *const st, - const Prndr_AudioBuffer inAudio, - Prndr_AudioBuffer outAudio ) -{ - const uint32_t *lfeLastIdxs; - uint32_t inMcChannelIdx; - uint32_t numNonLfeInChannels; - uint32_t numInChannels; - uint32_t passThroughIdx; - uint32_t mcIdx; - uint32_t inChIdx; - float gain_lin; - -#ifdef WMOPS - wmops_sub_start( "renderChannelsToChannels" ); -#endif - - passThroughIdx = 0; - - /* Iterate over given MC inputs */ - for ( mcIdx = 0; mcIdx < st->inConfig.numMultiChannelBuses; ++mcIdx ) - { - /* Get channel idx of current MC input within the multitrack buffer */ - inMcChannelIdx = st->inConfig.multiChannelBuses[mcIdx].inputChannelIndex; - - /* Number of non-LFE input channels */ - numNonLfeInChannels = Prndr_getNumNonLfeChannelsInSpeakerLayout( st->inConfig.multiChannelBuses[mcIdx].speakerLayout ); - - /* Number of all input channels */ - numInChannels = Prndr_getNumChannelsInSpeakerLayout( st->inConfig.multiChannelBuses[mcIdx].speakerLayout ); - - lfeLastIdxs = Prndr_getReorderedChannelIndices( st->inConfig.multiChannelBuses[mcIdx].speakerLayout ); - - gain_lin = dBToLin( st->inConfig.multiChannelBuses[mcIdx].gain_dB ); - - /* Iterate over non-LFE channels */ - for ( inChIdx = 0; inChIdx < numNonLfeInChannels; ++inChIdx ) - { - if ( st->mcPassthrough[passThroughIdx] == -1 ) - { - applyChannelGainsAndAddToOutput( inAudio, - inMcChannelIdx + lfeLastIdxs[inChIdx], - st->speakerPanGains[mcIdx][inChIdx], - NULL, - gain_lin, - st->crossfade, - outAudio ); - } - else - { - passthroughChannel( inAudio, - inMcChannelIdx + lfeLastIdxs[inChIdx], - st->mcPassthrough[passThroughIdx], - gain_lin, - outAudio ); - } - - ++passThroughIdx; - } - - /* Iterate over LFE channels */ - for ( ; inChIdx < numInChannels; ++inChIdx ) - { - /* Pass through if possible */ - if ( st->mcPassthrough[passThroughIdx] != -1 ) - { - passthroughChannel( inAudio, - inMcChannelIdx + lfeLastIdxs[inChIdx], - st->mcPassthrough[passThroughIdx], - gain_lin, - outAudio ); - } - else - { - if ( st->neverDropLfe ) - { - applyChannelGainsAndAddToOutput( inAudio, - inMcChannelIdx + lfeLastIdxs[inChIdx], - st->lfePanGains, - NULL, - gain_lin, - st->crossfade, - outAudio ); - } - } - - ++passThroughIdx; - } - } - -#ifdef WMOPS - wmops_sub_end(); -#endif -} - -static void renderObjectsToChannels( - Prndr_Prerenderer *const st, - const Prndr_AudioBuffer inAudio, - const Prndr_AudioObjectMetadataBuffer metadataBuffer, - Prndr_AudioBuffer outAudio ) -{ - const Prndr_AudioObject *curObj; - uint32_t objIdx; - Prndr_AudioObjectPosition pos; - float gain_lin; - -#ifdef WMOPS - wmops_sub_start( "renderObjectsToChannels" ); -#endif - - assert( st->inConfig.numAudioObjects == metadataBuffer.numObjects && "Metadata provided for a different number of objects than found in input" ); - - /* Iterate over given audio objects */ - for ( objIdx = 0; objIdx < st->inConfig.numAudioObjects; ++objIdx ) - { - /* Get pointer to current object and its metadata */ - curObj = &st->inConfig.audioObjects[objIdx]; - pos = metadataBuffer.positions[objIdx]; - gain_lin = dBToLin( st->inConfig.audioObjects[objIdx].gain_dB ); - - /* Render to MC */ - renderSingleObjectToChannels( - st, - inAudio, - curObj->inputChannelIndex, - &st->objPanInfo[objIdx], - pos, - gain_lin, - outAudio ); - } - -#ifdef WMOPS - wmops_sub_end(); -#endif -} - -static void renderSingleObjectToAmbi( - Prndr_Prerenderer *const st, - const Prndr_AudioBuffer inAudio, - const uint32_t itemChnlIdx, - Prndr_ObjPanInfo *prevPanInfo, - const Prndr_AudioObjectPosition curFrmPos, - const float gain_lin, - Prndr_AudioBuffer outAudio ) -{ - float *swapPtr; - -#ifdef WMOPS - wmops_sub_start( "renderSingleObjectToAmbi" ); -#endif - - /* Update panning gains if position changed */ - if ( prevPanInfo->position.azimuth != curFrmPos.azimuth || - prevPanInfo->position.elevation != curFrmPos.elevation || - st->firstFrame ) - { - /* Write current panning gains to tmpBuffer */ - ivas_dirac_dec_get_response( curFrmPos.azimuth, - curFrmPos.elevation, - st->tmpGainBuffer, - Prndr_getAmbisonicsOrder( st->outConfig.ambisonics ) ); - - prevPanInfo->position.azimuth = curFrmPos.azimuth; - prevPanInfo->position.elevation = curFrmPos.elevation; - - applyChannelGainsAndAddToOutput( inAudio, - itemChnlIdx, - st->tmpGainBuffer, - st->firstFrame ? NULL : prevPanInfo->panGains, - gain_lin, - st->crossfade, - outAudio ); - - /* Save current gains as most recently applied gains */ - swapPtr = prevPanInfo->panGains; - prevPanInfo->panGains = st->tmpGainBuffer; - st->tmpGainBuffer = swapPtr; - } - /* Otherwise use most recent gains and no interpolation */ - else - { - applyChannelGainsAndAddToOutput( inAudio, - itemChnlIdx, - prevPanInfo->panGains, - NULL, - gain_lin, - st->crossfade, - outAudio ); - } - -#ifdef WMOPS - wmops_sub_end(); -#endif -} - -static void renderSingleObjectToChannels( - Prndr_Prerenderer *const st, - const Prndr_AudioBuffer inAudio, - const uint32_t itemChnlIdx, - Prndr_ObjPanInfo *prevPanInfo, - const Prndr_AudioObjectPosition curFrmPos, - const float gain_lin, - Prndr_AudioBuffer outAudio ) -{ - float *swapPtr; - -#ifdef WMOPS - wmops_sub_start( "renderSingleObjectToChannels" ); -#endif - - /* Update panning gains if position changed */ - if ( prevPanInfo->position.azimuth != curFrmPos.azimuth || - prevPanInfo->position.elevation != curFrmPos.elevation || - st->firstFrame ) - { - /* Write current panning gains to tmpBuffer */ - getSpeakerGains( st, curFrmPos.azimuth, curFrmPos.elevation, st->tmpGainBuffer ); - prevPanInfo->position.azimuth = curFrmPos.azimuth; - prevPanInfo->position.elevation = curFrmPos.elevation; - - applyChannelGainsAndAddToOutput( inAudio, - itemChnlIdx, - st->tmpGainBuffer, - st->firstFrame ? NULL : prevPanInfo->panGains, - gain_lin, - st->crossfade, - outAudio ); - - /* Save current gains as most recently applied gains */ - swapPtr = prevPanInfo->panGains; - prevPanInfo->panGains = st->tmpGainBuffer; - st->tmpGainBuffer = swapPtr; - } - /* Otherwise use most recent gains and no interpolation */ - else - { - applyChannelGainsAndAddToOutput( inAudio, - itemChnlIdx, - prevPanInfo->panGains, - NULL, - gain_lin, - st->crossfade, - outAudio ); - } - -#ifdef WMOPS - wmops_sub_end(); -#endif -} - -static void applyChannelGainsAndAddToOutput( - const Prndr_AudioBuffer inAudio, - const uint32_t itemChnlIdx, - const float *const gainsCurrent, - const float *const gainsPrev, - const float gain_lin, - const float *const crossfade, - Prndr_AudioBuffer outAudio ) -{ - float *inSmpl; - float *outSmpl; - const float *fadeIn; - const float *fadeOut; - const float *lastInSmpl; - int16_t outChnlIdx; - float currentGain; - float previousGain; - -#ifdef WMOPS - wmops_sub_start( "applyChannelGainsAndAddToOutput" ); -#endif - - - /* Pointer to behind last input sample */ - lastInSmpl = get_smpl_ptr( inAudio, itemChnlIdx, inAudio.config.bufferSize ); - - for ( outChnlIdx = 0; outChnlIdx < outAudio.config.numChannels; ++outChnlIdx ) - { -#ifdef WMOPS - wmops_sub_start( "applyChannelGainsAndAddToOutput_chnl_loop" ); -#endif - currentGain = gainsCurrent[outChnlIdx] * gain_lin; - previousGain = gainsPrev == NULL ? 0.f : gainsPrev[outChnlIdx] * gain_lin; - - /* Process current output channel only if applying non-zero gains */ - if ( fabsf( currentGain ) > EPSILON || ( gainsPrev != NULL && fabsf( previousGain ) > EPSILON ) ) - { - /* Reset crossfade pointers */ - fadeIn = crossfade; - fadeOut = &crossfade[inAudio.config.bufferSize - 1]; - - /* Reset input pointer to the beginning of input channel */ - inSmpl = get_smpl_ptr( inAudio, itemChnlIdx, 0 ); - - /* Set output pointer to first output channel sample */ - outSmpl = get_smpl_ptr( outAudio, outChnlIdx, 0 ); - - if ( gainsPrev == NULL || fabsf( previousGain - currentGain ) <= EPSILON ) - { -#ifdef WMOPS - wmops_sub_start( "applyChannelGainsAndAddToOutput_smpl_loop_no_intrpl" ); -#endif - /* If no interpolation from previous frame, apply current gain */ - do - { - *outSmpl += currentGain * ( *inSmpl ); - ++outSmpl; - ++inSmpl; - - } while ( inSmpl != lastInSmpl ); -#ifdef WMOPS - wmops_sub_end(); -#endif - } - else - { -#ifdef WMOPS - wmops_sub_start( "applyChannelGainsAndAddToOutput_smpl_loop_intrpl" ); -#endif - /* Otherwise use weighted average between previous and current gain */ - do - { - *outSmpl += ( ( *fadeIn ) * currentGain + ( *fadeOut ) * previousGain ) * ( *inSmpl ); - ++outSmpl; - ++inSmpl; - - ++fadeIn; - --fadeOut; - } while ( inSmpl != lastInSmpl ); -#ifdef WMOPS - wmops_sub_end(); -#endif - } - } - -#ifdef WMOPS - wmops_sub_end(); -#endif - } - -#ifdef WMOPS - wmops_sub_end(); -#endif -} - -static void prepareLfeHandling( - Prndr_Prerenderer *const st ) -{ - /* uint32_t i; */ - -#ifdef WMOPS - wmops_sub_start( "prepareLfeHandling" ); -#endif - - st->lfePanGains = count_calloc( st->numOutChannels, sizeof( float ) ); - - if ( st->outConfig.ambisonics != prndr_ambisonics_none ) - { - /* Pan LFE to south pole (experimental) */ - ivas_dirac_dec_get_response( 0, - -90, - st->lfePanGains, - Prndr_getAmbisonicsOrder( st->outConfig.ambisonics ) ); - - /* TODO(sgi): Apply 10 dB gain? Almost surely will clip */ - /* for (i=0; i< st->numOutChannels; ++i) { - st->lfePanGains[i] *= 3.1622776602f; - } */ - } - else - { - set_zero( st->lfePanGains, st->numOutChannels ); - - /* Pan LFE to L and R with 4dB gain each (== 10dB - 6dB) */ - if ( st->numOutChannels > 1 ) - { - st->lfePanGains[0] = 1.5848931925f; - st->lfePanGains[1] = 1.5848931925f; - } - else - { - /* Put LFE in center channel, do not add 10dB gain to avoid clipping */ - st->lfePanGains[1] = 1.f; - } - } - -#ifdef WMOPS - wmops_sub_end(); -#endif -} - -static void prepareMcPanGains( Prndr_Prerenderer *const st ) -{ - uint32_t mcIdx; - int32_t spkIdx; - int32_t numChannels; - const float *spkAzi; - const float *spkEle; - -#ifdef WMOPS - wmops_sub_start( "prepareMcPanGains" ); -#endif - - st->speakerPanGains = count_calloc( st->inConfig.numMultiChannelBuses, sizeof( float ** ) ); - - for ( mcIdx = 0; mcIdx < st->inConfig.numMultiChannelBuses; ++mcIdx ) - { - numChannels = Prndr_getNumChannelsInSpeakerLayout( st->inConfig.multiChannelBuses[mcIdx].speakerLayout ); - st->speakerPanGains[mcIdx] = count_calloc( numChannels, sizeof( float * ) ); - - spkAzi = Prndr_getSpeakerAzimuths( st->inConfig.multiChannelBuses[mcIdx].speakerLayout ); - spkEle = Prndr_getSpeakerElevations( st->inConfig.multiChannelBuses[mcIdx].speakerLayout ); - - if ( st->outConfig.ambisonics != prndr_ambisonics_none ) - { - for ( spkIdx = 0; spkIdx < numChannels; ++spkIdx ) - { - st->speakerPanGains[mcIdx][spkIdx] = count_calloc( st->numOutChannels, sizeof( float ) ); - ivas_dirac_dec_get_response( (int16_t) spkAzi[spkIdx], - (int16_t) spkEle[spkIdx], - st->speakerPanGains[mcIdx][spkIdx], - Prndr_getAmbisonicsOrder( st->outConfig.ambisonics ) ); - } - } - else if ( st->outConfig.speakerLayout != prndr_speaker_layout_none ) - { - for ( spkIdx = 0; spkIdx < numChannels; ++spkIdx ) - { - st->speakerPanGains[mcIdx][spkIdx] = count_calloc( st->numOutChannels, sizeof( float ) ); - getSpeakerGains( st, spkAzi[spkIdx], spkEle[spkIdx], st->speakerPanGains[mcIdx][spkIdx] ); - } - } - } - -#ifdef WMOPS - wmops_sub_end(); -#endif -} - -static void prepareMcPassthrough( Prndr_Prerenderer *const st ) -{ - /* Output config */ - const float *outSpkAzi; - const float *outSpkEle; - const uint32_t *lfeLastIdxs; - uint32_t numNonLfeOutChannels; - uint32_t numOutChannels; - uint32_t lfeLastIdx_lsCustom[MAX_OUTPUT_CHANNELS]; - - /* Input config */ - const float *inSpkAzi; - const float *inSpkEle; - uint32_t numInChannels; - uint32_t numNonLfeInChannels; - - /* Input channel index */ - uint32_t passThroughIdx; - - uint32_t mcIdx; - uint32_t inChIdx; - uint32_t outChIdx; - -#ifdef WMOPS - wmops_sub_start( "prepareMcPassthrough" ); -#endif - - st->mcPassthrough = count_calloc( st->numInChannelsMc, sizeof( int32_t ) ); - - - if ( st->outConfig.speakerLayout == prndr_speaker_layout_custom ) - { - /* Number of non-LFE output channels */ - numNonLfeOutChannels = st->outConfig.outSetupCustom->num_spk; - - /* Number of output channels */ - numOutChannels = st->outConfig.outSetupCustom->num_spk + st->outConfig.outSetupCustom->num_lfe; - - /* Output speaker coordinates */ - outSpkAzi = st->outConfig.outSetupCustom->ls_azimuth; - outSpkEle = st->outConfig.outSetupCustom->ls_elevation; - - /* num_spk + num_lfe must be <= MAX_OUTPUT_CHANNELS for custom loudspeaker layouts */ - if ( st->outConfig.outSetupCustom->num_lfe > 0 ) - { - lfeLastIdx_lsCustom[numNonLfeOutChannels] = st->outConfig.outSetupCustom->lfe_idx[0]; - } - - for ( outChIdx = 0; outChIdx < numNonLfeOutChannels; ++outChIdx ) - { - ( ( st->outConfig.outSetupCustom->num_lfe > 0 ) && ( (int16_t) outChIdx >= st->outConfig.outSetupCustom->lfe_idx[0] ) ) ? ( lfeLastIdx_lsCustom[outChIdx] = outChIdx + 1 ) : ( lfeLastIdx_lsCustom[outChIdx] = outChIdx ); - } - - lfeLastIdxs = &lfeLastIdx_lsCustom[0]; - } - else - { - /* Number of non-LFE output channels */ - numNonLfeOutChannels = Prndr_getNumNonLfeChannelsInSpeakerLayout( st->outConfig.speakerLayout ); - - /* Number of output channels */ - numOutChannels = Prndr_getNumChannelsInSpeakerLayout( st->outConfig.speakerLayout ); - - /* Output speaker coordinates */ - outSpkAzi = Prndr_getSpeakerAzimuths( st->outConfig.speakerLayout ); - outSpkEle = Prndr_getSpeakerElevations( st->outConfig.speakerLayout ); - - lfeLastIdxs = Prndr_getReorderedChannelIndices( st->outConfig.speakerLayout ); - } - - passThroughIdx = 0; - for ( mcIdx = 0; mcIdx < st->inConfig.numMultiChannelBuses; ++mcIdx ) - { - /* Number of non-LFE input channels for current MC input */ - numNonLfeInChannels = Prndr_getNumNonLfeChannelsInSpeakerLayout( st->inConfig.multiChannelBuses[mcIdx].speakerLayout ); - - /* Number of input channels for current MC input */ - numInChannels = Prndr_getNumChannelsInSpeakerLayout( st->inConfig.multiChannelBuses[mcIdx].speakerLayout ); - - /* Input speaker coordinates */ - inSpkAzi = Prndr_getSpeakerAzimuths( st->inConfig.multiChannelBuses[mcIdx].speakerLayout ); - inSpkEle = Prndr_getSpeakerElevations( st->inConfig.multiChannelBuses[mcIdx].speakerLayout ); - - /* Check if passthrough possible for, save I/O mapping */ - for ( inChIdx = 0; inChIdx < numNonLfeInChannels; ++inChIdx ) - { - st->mcPassthrough[passThroughIdx] = -1; - - for ( outChIdx = 0; outChIdx < numNonLfeOutChannels; ++outChIdx ) - { - if ( inSpkAzi[inChIdx] == outSpkAzi[outChIdx] && - inSpkEle[inChIdx] == outSpkEle[outChIdx] ) - { - st->mcPassthrough[passThroughIdx] = lfeLastIdxs[outChIdx]; - break; - } - } - - ++passThroughIdx; - } - - /* Setup LFE passthrough, save I/O mapping */ - outChIdx = numNonLfeOutChannels; - for ( ; inChIdx < numInChannels; ++inChIdx ) - { - if ( outChIdx < numOutChannels ) - { - st->mcPassthrough[passThroughIdx] = lfeLastIdxs[outChIdx]; - } - else - { - st->mcPassthrough[passThroughIdx] = -1; - } - - ++outChIdx; - ++passThroughIdx; - } - } - -#ifdef WMOPS - wmops_sub_end(); -#endif -} - -static void passthroughChannel( const Prndr_AudioBuffer inAudio, - const uint32_t srcChnlIdx, - const uint32_t dstChnlIdx, - const float gain_lin, - Prndr_AudioBuffer outAudio ) -{ - float *inSmpl; - float *outSmpl; - int16_t smplIdx; - -#ifdef WMOPS - wmops_sub_start( "passthroughChannel" ); -#endif - - inSmpl = get_smpl_ptr( inAudio, srcChnlIdx, 0 ); - outSmpl = get_smpl_ptr( outAudio, dstChnlIdx, 0 ); - - for ( smplIdx = 0; smplIdx < inAudio.config.bufferSize; ++smplIdx ) - { - *outSmpl += *inSmpl * gain_lin; - - ++outSmpl; - ++inSmpl; - } - -#ifdef WMOPS - wmops_sub_end(); -#endif -} - -static void getSpeakerGains( const Prndr_Prerenderer *const st, - const float azi, - const float ele, - float *const spkGains ) -{ - const uint32_t *lfeLastIdxs; - int16_t numNonLfeOutChannels; - int16_t noLfeIdx; - Prndr_SpeakerLayout speakerLayout; - -#ifdef WMOPS - wmops_sub_start( "getSpeakerGains" ); -#endif - - /* EFAP returns an array of gains only for non-LFE speakers */ - efap_determine_gains( st->efapRenderer, st->noLfePanBuffer, azi, ele, EFAP_MODE_EFAP ); - - speakerLayout = st->outConfig.speakerLayout; - if ( speakerLayout == prndr_speaker_layout_custom ) - { - uint32_t lfeIdx; - - numNonLfeOutChannels = st->outConfig.outSetupCustom->num_spk; - - /* Clear speaker gains - not all elements will be overwritten below */ - set_zero( spkGains, numNonLfeOutChannels + st->outConfig.outSetupCustom->num_lfe ); - - /* Copy to gain array where LFE channel(s) are included */ - for ( lfeIdx = 0, noLfeIdx = 0; noLfeIdx < numNonLfeOutChannels; lfeIdx++, noLfeIdx++ ) - { - if ( noLfeIdx == st->outConfig.outSetupCustom->lfe_idx[0] ) - { - lfeIdx++; - } - spkGains[lfeIdx] = st->noLfePanBuffer[noLfeIdx]; - } - } - else - { - numNonLfeOutChannels = Prndr_getNumNonLfeChannelsInSpeakerLayout( speakerLayout ); - lfeLastIdxs = Prndr_getReorderedChannelIndices( speakerLayout ); - - /* Clear speaker gains - not all elements will be overwritten below */ - set_zero( spkGains, Prndr_getNumChannelsInSpeakerLayout( speakerLayout ) ); - - /* Copy to gain array where LFE channel(s) are included */ - for ( noLfeIdx = 0; noLfeIdx < numNonLfeOutChannels; ++noLfeIdx ) - { - spkGains[lfeLastIdxs[noLfeIdx]] = st->noLfePanBuffer[noLfeIdx]; - } - } - -#ifdef WMOPS - wmops_sub_end(); -#endif -} - -int16_t Prndr_getNumChannelsAmbisonics( Prndr_Ambisonics ambisonics ) -{ - switch ( ambisonics ) - { - case prndr_ambisonics_none: - return 0; - case prndr_ambisonics_mono: - return 1; - case prndr_ambisonics_foa: - return 4; - case prndr_ambisonics_soa: - return 9; - case prndr_ambisonics_toa: - return 16; - default: - assert( !"Invalid ambisonics config" ); - } - - return 0; -} - -static int16_t Prndr_getAmbisonicsOrder( Prndr_Ambisonics ambisonics ) -{ - assert( ambisonics != prndr_ambisonics_none && "Invalid ambisonics config" ); - return ambisonics; /* Enum values map to ambisonics order */ -} - -int16_t Prndr_getNumChannelsInSpeakerLayout( Prndr_SpeakerLayout layout ) -{ - switch ( layout ) - { - case prndr_speaker_layout_none: - return 0; - case prndr_speaker_layout_mono: - return 1; - case prndr_speaker_layout_stereo: - return 2; - case prndr_speaker_layout_5_1: - return 6; - case prndr_speaker_layout_7_1: - return 8; - case prndr_speaker_layout_5_1_4: - return 10; - case prndr_speaker_layout_7_1_4: - return 12; - default: - assert( !"Invalid speaker layout" ); - } - - return 0; -} - -int16_t Prndr_getNumNonLfeChannelsInSpeakerLayout( Prndr_SpeakerLayout layout ) -{ - switch ( layout ) - { - case prndr_speaker_layout_mono: - return 1; - case prndr_speaker_layout_stereo: - return 2; - case prndr_speaker_layout_5_1: - return 5; - case prndr_speaker_layout_7_1: - return 7; - case prndr_speaker_layout_5_1_4: - return 9; - case prndr_speaker_layout_7_1_4: - return 11; - default: - assert( !"Invalid speaker layout" ); - } - - return 0; -} - -const float *Prndr_getSpeakerAzimuths( Prndr_SpeakerLayout layout ) -{ - switch ( layout ) - { - case prndr_speaker_layout_mono: - return ls_azimuth_CICP1; - case prndr_speaker_layout_stereo: - return ls_azimuth_CICP2; - case prndr_speaker_layout_5_1: - return ls_azimuth_CICP6; - case prndr_speaker_layout_7_1: - return ls_azimuth_CICP12; - case prndr_speaker_layout_5_1_4: - return ls_azimuth_CICP16; - case prndr_speaker_layout_7_1_4: - return ls_azimuth_CICP19; - default: - assert( !"Invalid speaker layout" ); - } - - return NULL; -} - -const float *Prndr_getSpeakerElevations( Prndr_SpeakerLayout layout ) -{ - switch ( layout ) - { - case prndr_speaker_layout_mono: - return ls_elevation_CICP1; - case prndr_speaker_layout_stereo: - return ls_elevation_CICP2; - case prndr_speaker_layout_5_1: - return ls_elevation_CICP6; - case prndr_speaker_layout_7_1: - return ls_elevation_CICP12; - case prndr_speaker_layout_5_1_4: - return ls_elevation_CICP16; - case prndr_speaker_layout_7_1_4: - return ls_elevation_CICP19; - default: - assert( !"Invalid speaker layout" ); - } - - return NULL; -} - -const uint32_t *Prndr_getReorderedChannelIndices( Prndr_SpeakerLayout layout ) -{ - switch ( layout ) - { - case prndr_speaker_layout_mono: - return ls_LFE_last_idx_CICP1; - case prndr_speaker_layout_stereo: - return ls_LFE_last_idx_CICP2; - case prndr_speaker_layout_5_1: - return ls_LFE_last_idx_CICP6; - case prndr_speaker_layout_7_1: - return ls_LFE_last_idx_CICP12; - case prndr_speaker_layout_5_1_4: - return ls_LFE_last_idx_CICP16; - case prndr_speaker_layout_7_1_4: - return ls_LFE_last_idx_CICP19; - default: - assert( !"Invalid speaker layout" ); - } - - return NULL; -} - -static ivas_error Prndr_getHoaRenderMtx( - const Prndr_OutputConfig outConfig, - float **decMtx, - uint32_t ambiOrder ) -{ - IVAS_OUTPUT_SETUP hOutSetup; - ivas_error error; - - error = IVAS_ERR_OK; - -#ifdef WMOPS - wmops_sub_start( "Prndr_getHoaRenderMtx" ); -#endif - - switch ( outConfig.speakerLayout ) - { - case prndr_speaker_layout_mono: - ivas_output_init( &hOutSetup, AUDIO_CONFIG_MONO ); - hOutSetup.ls_azimuth = ls_azimuth_CICP1; - hOutSetup.ls_elevation = ls_elevation_CICP1; - break; - case prndr_speaker_layout_stereo: - ivas_output_init( &hOutSetup, AUDIO_CONFIG_STEREO ); - break; - case prndr_speaker_layout_5_1: - ivas_output_init( &hOutSetup, AUDIO_CONFIG_5_1 ); - break; - case prndr_speaker_layout_7_1: - ivas_output_init( &hOutSetup, AUDIO_CONFIG_7_1 ); - break; - case prndr_speaker_layout_5_1_4: - ivas_output_init( &hOutSetup, AUDIO_CONFIG_5_1_4 ); - break; - case prndr_speaker_layout_7_1_4: - ivas_output_init( &hOutSetup, AUDIO_CONFIG_7_1_4 ); - break; - case prndr_speaker_layout_custom: - ivas_ls_custom_setup( &hOutSetup, outConfig.outSetupCustom ); - break; - default: - assert( !"Invalid speaker config" ); - return IVAS_ERR_WRONG_PARAMS; - } - - if ( ( error = ivas_sba_get_hoa_dec_matrix( hOutSetup, decMtx, (int16_t) ambiOrder ) ) != IVAS_ERR_OK ) - { - return error; - } - - -#ifdef WMOPS - wmops_sub_end(); -#endif - - return error; -} - -void Prndr_getHoaDecVecForAmbiChnl( - uint32_t ambiChnnlIdx, - const Prndr_OutputConfig outConfig, - const float *decMtx, - float *decCoeffs ) -{ - - const uint32_t *lfeLastIdxs; - int16_t numNonLfeChannels; - int16_t nonLfeChIdx; - -#ifdef WMOPS - wmops_sub_start( "Prndr_getHoaDecVecForAmbiChnl" ); -#endif - - - if ( outConfig.speakerLayout == prndr_speaker_layout_custom ) - { - uint32_t lfeIdx; - - numNonLfeChannels = outConfig.outSetupCustom->num_spk; - - /* Clear speaker gains - not all elements will be overwritten below */ - set_zero( decCoeffs, numNonLfeChannels + outConfig.outSetupCustom->num_lfe ); - - /* Copy to gain array where LFE channel(s) are included */ - for ( lfeIdx = 0, nonLfeChIdx = 0; nonLfeChIdx < numNonLfeChannels; lfeIdx++, nonLfeChIdx++ ) - { - if ( nonLfeChIdx == outConfig.outSetupCustom->lfe_idx[0] ) - { - lfeIdx++; - } - decCoeffs[lfeIdx] = decMtx[16 * nonLfeChIdx + ambiChnnlIdx]; - } - } - else - { - numNonLfeChannels = Prndr_getNumNonLfeChannelsInSpeakerLayout( outConfig.speakerLayout ); - - lfeLastIdxs = Prndr_getReorderedChannelIndices( outConfig.speakerLayout ); - - /* Clear decoding coefficients - not all elements will be overwritten below */ - set_zero( decCoeffs, Prndr_getNumChannelsInSpeakerLayout( outConfig.speakerLayout ) ); - - for ( nonLfeChIdx = 0; nonLfeChIdx < numNonLfeChannels; ++nonLfeChIdx ) - { - decCoeffs[lfeLastIdxs[nonLfeChIdx]] = decMtx[16 * nonLfeChIdx + ambiChnnlIdx]; - } - } - -#ifdef WMOPS - wmops_sub_end(); -#endif -} - -/*-------------------------------------------------------------------* - * ivas_limiter_prerenderer() - * - * In-place saturation control for multichannel buffers with adaptive release time - *-------------------------------------------------------------------*/ -static void ivas_limiter_prerenderer( - 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 c; - float **channels; - int16_t num_channels; - - /* return early if given bad parameters */ - if ( hLimiter == NULL || output == NULL || output_frame <= 0 ) - { - return; - } - - channels = hLimiter->channel_ptrs; - num_channels = hLimiter->num_channels; - - for ( c = 0; c < num_channels; ++c ) - { - channels[c] = output + c * output_frame; - } - - limiter_process( hLimiter, output_frame, threshold, 0, NULL ); - - return; -} - -static float dBToLin( const float gain_dB ) -{ - return powf( 10.f, gain_dB / 20.f ); -} diff --git a/lib_util/ivas_prerenderer.h b/lib_util/ivas_prerenderer.h deleted file mode 100644 index f21f893dc9..0000000000 --- a/lib_util/ivas_prerenderer.h +++ /dev/null @@ -1,190 +0,0 @@ -/****************************************************************************************************** - - (C) 2022 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_PRERENDERER_H -#define IVAS_PRERENDERER_H - -#include -#include - -#include "options.h" -#include "common_api_types.h" -#include "ls_custom_file_reader.h" -#include "ivas_error.h" - -#define PRERENDERER_MAX_ISM_INPUTS 16 -#define PRERENDERER_MAX_MC_INPUTS 2 -#define PRERENDERER_MAX_SBA_INPUTS 2 - -typedef enum Prndr_Ambisonics -{ - prndr_ambisonics_none = -1, - prndr_ambisonics_mono = 0, - prndr_ambisonics_foa = 1, - prndr_ambisonics_soa = 2, - prndr_ambisonics_toa = 3 -} Prndr_Ambisonics; /* Numerical value corresponds to Ambisonics order */ - -typedef enum Prndr_SpeakerLayout -{ - prndr_speaker_layout_none = -1, - prndr_speaker_layout_custom = 0, - prndr_speaker_layout_mono = 1, - prndr_speaker_layout_stereo = 2, - prndr_speaker_layout_5_1 = 6, - prndr_speaker_layout_5_1_4 = 16, - prndr_speaker_layout_7_1 = 12, - prndr_speaker_layout_7_1_4 = 19 -} Prndr_SpeakerLayout; /* Numerical value corresponds to CICP index */ - -typedef struct Prndr_AudioObjectPosition -{ - int16_t azimuth; - int16_t elevation; -} Prndr_AudioObjectPosition; - -typedef struct Prndr_AudioObjectMetadataBuffer -{ - Prndr_AudioObjectPosition positions[PRERENDERER_MAX_ISM_INPUTS]; - uint32_t numObjects; -} Prndr_AudioObjectMetadataBuffer; - -typedef struct Prndr_AudioObject -{ - uint8_t inputChannelIndex; - float gain_dB; -} Prndr_AudioObject; - -typedef struct Prndr_ObjPanInfo -{ - Prndr_AudioObjectPosition position; - float *panGains; -} Prndr_ObjPanInfo; - -typedef struct Prndr_AmbisonicsBus -{ - Prndr_Ambisonics ambisonicsConfig; - uint8_t inputChannelIndex; - float gain_dB; -} Prndr_AmbisonicsBus; - -typedef struct Prndr_MultiChannelBus -{ - Prndr_SpeakerLayout speakerLayout; - uint8_t inputChannelIndex; - float gain_dB; -} Prndr_MultiChannelBus; - -typedef struct Prndr_AudioBufferConfig -{ - int32_t sampleRate; - int16_t bufferSize; - int16_t numChannels; -} Prndr_AudioBufferConfig; - -typedef struct Prndr_AudioBuffer -{ - Prndr_AudioBufferConfig config; - float *data; -} Prndr_AudioBuffer; - -typedef struct Prndr_InputConfig -{ - Prndr_AudioObject audioObjects[PRERENDERER_MAX_ISM_INPUTS]; - uint8_t numAudioObjects; - Prndr_MultiChannelBus multiChannelBuses[PRERENDERER_MAX_MC_INPUTS]; - uint8_t numMultiChannelBuses; - Prndr_AmbisonicsBus ambisonicsBuses[PRERENDERER_MAX_SBA_INPUTS]; - uint8_t numAmbisonicsBuses; -} Prndr_InputConfig; - -typedef struct Prndr_OutputConfig -{ - Prndr_SpeakerLayout speakerLayout; - Prndr_Ambisonics ambisonics; - IVAS_LSSETUP_CUSTOM_HANDLE outSetupCustom; -} Prndr_OutputConfig; - -typedef struct Prndr_Prerenderer Prndr_Prerenderer; - -/* clang-format off */ -/*----------------------------------------------------------------------------------* - * Prerenderer prototypes - *----------------------------------------------------------------------------------*/ - -/*! Creates a prerenderer state. - * r: pointer to opened prerenderer */ -Prndr_Prerenderer *Prndr_Prerenderer_open( - void -); - -/*! Configures the prerenderer - needs to be called after Prndr_Prerenderer_open(). */ -ivas_error Prndr_Prerenderer_configure( - Prndr_Prerenderer *const st, /* i : Prerenderer state */ - const Prndr_InputConfig inConfig, /* i : Input configuration */ - const Prndr_OutputConfig outConfig, /* i : Output configuration */ - int32_t frameSize, /* i : Processing frame size in samples */ - uint32_t sampleRate /* i : Processing sampling rate */ -); - -/*! Renders one frame of audio samples */ -void Prndr_Prerenderer_render( - Prndr_Prerenderer *const st, /* i : Prerenderer state */ - const Prndr_AudioBuffer inAudio, /* i : Buffer with pointer to input samples and associated info */ - const Prndr_AudioObjectMetadataBuffer metadataBuffer, /* i : Buffer with object metadata for current frame */ - Prndr_AudioBuffer outAudio /* o : Buffer with pointer to output samples and associated info */ -); - -/*! Enable/disable experimental LFE handling */ -void Prndr_Prerenderer_setNeverDropLfe( - Prndr_Prerenderer *st, /* i : Prerenderer state */ - int8_t neverDropLfe /* i : If 0, LFE channel will be dropped when rendering to configs w/o LFE. - If 1, tries to render LFE into other channels in an optimal way when rendering to configs w/o LFE. */ -); - -/*! Get number of input channels based on InputConfig */ -int16_t Prndr_Prerenderer_getInChannels( - Prndr_Prerenderer *st /* i : Prerenderer state */ -); - -/*! Get number of output channels based on OutputConfig */ -int16_t Prndr_Prerenderer_getOutChannels( - Prndr_Prerenderer *st /* i : Prerenderer state */ -); - -/*! Destructs the prerenderer state and frees memory */ -void Prndr_Prerenderer_close( - Prndr_Prerenderer *st /* i : Prerenderer state */ -); -/* clang-format on */ - -#endif /* IVAS_PRERENDERER_H */ diff --git a/scripts/deco.bin b/scripts/deco.bin new file mode 100644 index 0000000000..3ea11b0fad --- /dev/null +++ b/scripts/deco.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c24505426ee0d7f5eb019af6d918647eebb363dd96a45ae50be65a4aa2f809c0 +size 229376 diff --git a/scripts/eigen_to_foa_cldfb_domain_filters.bin b/scripts/eigen_to_foa_cldfb_domain_filters.bin new file mode 100644 index 0000000000..3a9d67c0c7 --- /dev/null +++ b/scripts/eigen_to_foa_cldfb_domain_filters.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3c3ebc3d9e031d2d640a32639132771da974874686a378fb323645b9dbb553fe +size 61440 diff --git a/scripts/eigen_to_hoa2_cldfb_domain_filters.bin b/scripts/eigen_to_hoa2_cldfb_domain_filters.bin new file mode 100644 index 0000000000..4c586da3d5 --- /dev/null +++ b/scripts/eigen_to_hoa2_cldfb_domain_filters.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c9097ecbf3b26b814abe141edadc701f1ffec5a141f2becc746926d6d32a7e58 +size 138240 diff --git a/scripts/find_unused_symbols.sh b/scripts/find_unused_symbols.sh index 1498fa172b..68a6cdad8f 100755 --- a/scripts/find_unused_symbols.sh +++ b/scripts/find_unused_symbols.sh @@ -32,7 +32,7 @@ options=$1 OBJDIR=obj -EXECUTABLES="../IVAS_cod ../IVAS_dec ./prerenderer/IVAS_prerenderer" +EXECUTABLES="../IVAS_cod ../IVAS_dec ../IVAS_rend" evaluateTables=1 evaluateFunctions=1 @@ -68,7 +68,6 @@ fi # build if [ $compile -ne 0 ]; then make -C .. DEBUG=0 STRIP=1 clean all 1>&2 - make -C prerenderer DEBUG=0 STRIP=1 clean all 1>&2 fi if [ $evaluateFunctions != 0 ]; then diff --git a/scripts/hrir.bin b/scripts/hrir.bin new file mode 100644 index 0000000000..e69de29bb2 diff --git a/scripts/ivas_pytests/tests/unit_tests/crend/ivas_crend_unit_test.vcxproj b/scripts/ivas_pytests/tests/unit_tests/crend/ivas_crend_unit_test.vcxproj index 3d8e7ab07f..5061b8e414 100644 --- a/scripts/ivas_pytests/tests/unit_tests/crend/ivas_crend_unit_test.vcxproj +++ b/scripts/ivas_pytests/tests/unit_tests/crend/ivas_crend_unit_test.vcxproj @@ -17,6 +17,9 @@ {e822ddaf-0f5f-4cd0-a694-38ae69de74d3} + + {12B4C8A5-1E06-4E30-B443-D1F916F52B47} + {2fa8f384-0775-f3b7-f8c3-85209222fc70} @@ -97,7 +100,7 @@ Neither false false - ..\..\..\..\..\lib_util;..\..\..\..\..\lib_dec;..\..\..\..\..\lib_com;..\..\..\..\..\lib_enc;..\..\..\..\..\lib_debug;..\..\..\..\..\lib_util;%(AdditionalIncludeDirectories) + ..\..\..\..\..\lib_util;..\..\..\..\..\lib_dec;..\..\..\..\..\lib_rend;..\..\..\..\..\lib_com;..\..\..\..\..\lib_enc;..\..\..\..\..\lib_debug;..\..\..\..\..\lib_util;%(AdditionalIncludeDirectories) UNIT_TEST_CREND_TD_BINAURAL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) true diff --git a/scripts/prepare_instrumentation.sh b/scripts/prepare_instrumentation.sh index 8ab50080a2..602768d4d6 100755 --- a/scripts/prepare_instrumentation.sh +++ b/scripts/prepare_instrumentation.sh @@ -91,7 +91,7 @@ fi # strip switches, to remove the macros if coan_exists; then - coan source --replace --no-transients -E -K --file $ifdef_list $targetdir/lib_{com,dec,enc,util,debug}/*.[hc] + coan source --replace --no-transients -E -K --file $ifdef_list $targetdir/lib_{com,dec,enc,rend,util,debug}/*.[hc] coan source --replace --no-transients -E -K --file $ifdef_list $targetdir/apps/*.[hc] else ./strip_defines_cpppnet.sh $targetdir $ifdef_list @@ -104,6 +104,7 @@ find $targetdir -name "*.[ch]" -exec sed -i.bak -e "s/\(0x[0-9a-fA-F]*\)UL/\(\(u ${emulator} ./wmc_tool.exe $targetdir/lib_enc/*.c /ic /op > /dev/null ${emulator} ./wmc_tool.exe $targetdir/lib_com/*.c /ic /op > /dev/null ${emulator} ./wmc_tool.exe $targetdir/lib_dec/*.c /ic /op > /dev/null +${emulator} ./wmc_tool.exe $targetdir/lib_rend/*.c /ic /op > /dev/null # automatically enable #define WMOPS in options.h sed -i.bak -e "s/\/\*\s*\(#define\s*WMOPS\)\s*\*\//\1/g" $targetdir/lib_com/options.h diff --git a/scripts/prerenderer/Makefile b/scripts/prerenderer/Makefile deleted file mode 100644 index 4201cd75e3..0000000000 --- a/scripts/prerenderer/Makefile +++ /dev/null @@ -1,172 +0,0 @@ -# GNU Makefile - -# Paths -SRC_LIBCOM = ../../lib_com -SRC_LIBDEBUG = ../../lib_debug -SRC_LIBDEC = ../../lib_dec -SRC_LIBENC = ../../lib_enc -SRC_LIBUTIL = ../../lib_util -SRC_APP = . -BUILD = build -OBJDIR = obj - -SRC_DIRS = $(sort -u $(SRC_LIBCOM) $(SRC_LIBDEBUG) $(SRC_LIBDEC) $(SRC_LIBENC) $(SRC_LIBUTIL) $(SRC_APP)) - -# Name of CLI binaries -CLI_PRD ?= IVAS_prerenderer -LIB_LIBCOM ?= libivascom.a -LIB_LIBDEBUG ?= libivasdebug.a -LIB_LIBDEC ?= libivasdec.a -LIB_LIBENC ?= libivasenc.a -LIB_LIBUTIL ?= libivasutil.a - -# Default tool settings -CC ?= gcc -RM ?= rm -f -AR ?= ar - -# Detect system -UNAME_S := $(shell uname -s) - -# Switches for cross-platform builds (i.e. build 32 bit code on 64 bit platforms) -ifneq "$(TARGET_PLATFORM)" "" -ifeq ("$(TARGET_PLATFORM)", "$(findstring $(TARGET_PLATFORM), i386 i586 i686)") - CFLAGS += -m32 - LDFLAGS += -m32 -endif - -ifeq ("$(TARGET_PLATFORM)", "$(findstring $(TARGET_PLATFORM), x86_64)") - CFLAGS += -m64 - LDFLAGS += -m64 -endif -endif - -ifndef VERBOSE -QUIET_CC = @echo ' ' Compiling $<; -QUIET_LINK= @echo ' ' Linking $@; -QUIET_AR = @echo ' ' Archiving $@; -QUIET = @ -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-unused-parameter \ - -Wno-unused-function -Wno-implicit-fallthrough - -# libs to link -LDLIBS += -lm - -# Clang sanitizer compiler options -CCCLANG = clang -ifeq "$(CLANG)" "1" -CC = $(CCCLANG) -CFLAGS += -fsanitize=memory -LDFLAGS += -fsanitize=memory -endif -ifeq "$(CLANG)" "2" -CC = $(CCCLANG) -CFLAGS += -fsanitize=address -LDFLAGS += -fsanitize=address -endif -ifeq "$(CLANG)" "3" -CC = $(CCCLANG) -CFLAGS += -fsanitize=undefined -LDFLAGS += -fsanitize=undefined -endif - -ifeq "$(RELEASE)" "1" -CFLAGS += -DRELEASE -OPTIM ?= 2 -endif - -ifneq "$(DEBUG)" "0" -CFLAGS += -g3 -LDFLAGS += -g3 -endif - -ifeq "$(GCOV)" "1" -CFLAGS += -fprofile-arcs -ftest-coverage -LDFLAGS += -fprofile-arcs -ftest-coverage -endif - -ifeq "$(STRIP)" "1" -CFLAGS += -fdata-sections -ffunction-sections -ifneq ($(UNAME_S),Darwin) -LDFLAGS += -Wl,-gc-sections -static -else -LDFLAGS += -Wl,-dead_strip -endif -endif - -OPTIM ?= 0 -CFLAGS += -O$(OPTIM) - -CFLAGS += $(foreach DIR,$(SRC_DIRS),-I$(DIR)) - -# Source file search paths -VPATH = $(SRC_DIRS) - -############################################################################### - -SRCS_LIBCOM = $(foreach DIR,$(SRC_LIBCOM),$(patsubst $(DIR)/%,%,$(wildcard $(DIR)/*.c))) -SRCS_LIBDEBUG = $(foreach DIR,$(SRC_LIBDEBUG),$(patsubst $(DIR)/%,%,$(wildcard $(DIR)/*.c))) -SRCS_LIBDEC = $(foreach DIR,$(SRC_LIBDEC),$(patsubst $(DIR)/%,%,$(wildcard $(DIR)/*.c))) -SRCS_LIBENC = $(foreach DIR,$(SRC_LIBENC),$(patsubst $(DIR)/%,%,$(wildcard $(DIR)/*.c))) -SRCS_LIBUTIL = $(foreach DIR,$(SRC_LIBUTIL),$(patsubst $(DIR)/%,%,$(wildcard $(DIR)/*.c))) - -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_LIBUTIL = $(addprefix $(OBJDIR)/,$(SRCS_LIBUTIL:.c=.o)) -OBJS_CLI_APPPRD = $(OBJDIR)/prerenderer.o - -DEPS = $(addprefix $(OBJDIR)/,$(SRCS_LIBCOM:.c=.P) $(SRCS_LIBDEBUG:.c=.P) $(SRCS_LIBDEC:.c=.P) \ - $(SRCS_LIBENC:.c=.P) $(SRCS_LIBUTIL:.c=.P)) - -############################################################################### - -.PHONY: all clean clean_all - -all: $(CLI_PRD) - -$(OBJDIR): - $(QUIET)mkdir -p $(OBJDIR) - -$(LIB_LIBCOM): $(OBJS_LIBCOM) - $(QUIET_AR)$(AR) rcs $@ $^ - -$(LIB_LIBDEBUG): $(OBJS_LIBDEBUG) - $(QUIET_AR)$(AR) rcs $@ $^ - -$(LIB_LIBDEC): $(OBJS_LIBDEC) - $(QUIET_AR)$(AR) rcs $@ $^ - -$(LIB_LIBENC): $(OBJS_LIBENC) - $(QUIET_AR)$(AR) rcs $@ $^ - -$(LIB_LIBUTIL): $(OBJS_LIBUTIL) - $(QUIET_AR)$(AR) rcs $@ $^ - -$(CLI_PRD): $(LIB_LIBENC) $(LIB_LIBDEC) $(LIB_LIBDEBUG) $(LIB_LIBCOM) $(LIB_LIBUTIL) $(OBJS_CLI_APPPRD) - $(QUIET_LINK)$(CC) $(LDFLAGS) $(OBJS_CLI_APPPRD) -L. -livasutil -livasenc -livasdec -livascom -livasdebug $(LDLIBS) -o $(CLI_PRD) - -libs: $(LIB_LIBENC) $(LIB_LIBDEBUG) $(LIB_LIBCOM) $(LIB_LIBDEC) $(LIB_LIBUTIL) - -clean: - $(QUIET)$(RM) $(OBJS_LIBENC) $(OBJS_LIBDEC) $(OBJS_CLI_APPPRD) $(DEPS) - $(QUIET)$(RM) $(DEPS:.P=.d) - $(QUIET)test ! -d $(OBJDIR) || rm -rf $(OBJDIR) - -clean_all: clean - $(QUIET)$(RM) $(CLI_PRD) $(LIB_LIBENC) $(LIB_LIBDEBUG) $(LIB_LIBCOM) $(LIB_LIBDEC) $(LIB_LIBUTIL) - -$(OBJDIR)/%.o : %.c | $(OBJDIR) - $(QUIET_CC)$(CC) $(CFLAGS) -c -MD -o $@ $< - @cp $(OBJDIR)/$*.d $(OBJDIR)/$*.P; \ - sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \ - -e '/^$$/ d' -e 's/$$/ :/' < $(OBJDIR)/$*.d >> $(OBJDIR)/$*.P; \ - $(RM) $(OBJDIR)/$*.d - --include $(DEPS) diff --git a/scripts/prerenderer/Workspace_msvc/Workspace_msvc_prerenderer.sln b/scripts/prerenderer/Workspace_msvc/Workspace_msvc_prerenderer.sln deleted file mode 100644 index b36220e618..0000000000 --- a/scripts/prerenderer/Workspace_msvc/Workspace_msvc_prerenderer.sln +++ /dev/null @@ -1,48 +0,0 @@ -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.27428.2027 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "prerenderer", "prerenderer.vcxproj", "{12B4C8A5-1E06-4E30-B443-D1F916F52B47}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lib_util", "..\..\..\Workspace_msvc\lib_util.vcxproj", "{2FA8F384-0775-F3B7-F8C3-85209222FC70}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lib_debug", "..\..\..\Workspace_msvc\lib_debug.vcxproj", "{54509728-928B-44D9-A118-A6F92F08B34F}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lib_com", "..\..\..\Workspace_msvc\lib_com.vcxproj", "{39EC200D-7795-4FF8-B214-B24EDA5526AE}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lib_dec", "..\..\..\Workspace_msvc\lib_dec.vcxproj", "{E822DDAF-0F5F-4CD0-A694-38AE69DE74D3}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Release|Win32 = Release|Win32 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {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}.Release|Win32.ActiveCfg = Release|Win32 - {12B4C8A5-1E06-4E30-B443-D1F916F52B47}.Release|Win32.Build.0 = 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}.Release|Win32.ActiveCfg = Release|Win32 - {2FA8F384-0775-F3B7-F8C3-85209222FC70}.Release|Win32.Build.0 = 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}.Release|Win32.ActiveCfg = Release|Win32 - {54509728-928B-44D9-A118-A6F92F08B34F}.Release|Win32.Build.0 = 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}.Release|Win32.ActiveCfg = Release|Win32 - {39EC200D-7795-4FF8-B214-B24EDA5526AE}.Release|Win32.Build.0 = Release|Win32 - {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}.Release|Win32.ActiveCfg = Release|Win32 - {E822DDAF-0F5F-4CD0-A694-38AE69DE74D3}.Release|Win32.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {06AC6878-76C6-4079-956D-B3FF3DB2C9A5} - EndGlobalSection -EndGlobal diff --git a/scripts/prerenderer/Workspace_msvc/prerenderer.vcxproj.filters b/scripts/prerenderer/Workspace_msvc/prerenderer.vcxproj.filters deleted file mode 100644 index ae26ad88ba..0000000000 --- a/scripts/prerenderer/Workspace_msvc/prerenderer.vcxproj.filters +++ /dev/null @@ -1,50 +0,0 @@ - - - - - dec_ivas_c - - - dec_ivas_c - - - dec_ivas_c - - - dec_ivas_c - - - dec_ivas_c - - - dec_ivas_c - - - dec_ivas_c - - - enc_ivas_c - - - - - - - - {4fc737f1-c7a5-4376-a066-2a32d752a2ff} - - - {93995380-89bd-4b04-88eb-625fbe52ebfb} - - - {46364e80-1212-3600-1d53-58d3725f5bdc} - - - {67da6ab6-f800-4c08-8b7a-83bb121aad01} - - - - - - - \ No newline at end of file diff --git a/scripts/prerenderer/prerenderer.c b/scripts/prerenderer/prerenderer.c deleted file mode 100644 index 57515e5fd2..0000000000 --- a/scripts/prerenderer/prerenderer.c +++ /dev/null @@ -1,1553 +0,0 @@ -/****************************************************************************************************** - - (C) 2022 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 "audio_file_reader.h" -#include "audio_file_writer.h" -#include "common_api_types.h" -#include "ivas_prerenderer.h" -#include "ism_file_reader.h" -#include "ivas_stat_dec.h" -#include "prot.h" -#ifdef WMOPS -#include "wmops.h" -#endif -#ifdef RAM_COUNTING_TOOL -#include "mem_count.h" -#endif -#include -#include -#include -#include -#include -#include - -#ifndef count_malloc -#ifdef RAM_COUNTING_TOOL -#define count_malloc( n1 ) MALLOC_FCT_CALL( n1 ) -#define count_calloc( n1, n2 ) CALLOC_FCT_CALL( n1, n2 ) -#define count_free( ptr ) FREE_FCT_CALL( ptr ) -#else -#define count_malloc( n1 ) malloc( n1 ) -#define count_calloc( n1, n2 ) calloc( n1, n2 ) -#define count_free( ptr ) free( ptr ) -#endif -#endif - -#ifndef min -#define min( x, y ) ( ( x ) < ( y ) ? ( x ) : ( y ) ) -#endif - -#ifndef max -#define max( x, y ) ( ( x ) > ( y ) ? ( x ) : ( y ) ) -#endif - -#define PRERENDERER_MAX_METADATA_LENGTH 8192 -#define PRERENDERER_MAX_METADATA_LINE_LENGTH 1024 -#define PRERENDERER_MAX_CMDLN_ARG_LENGTH FILENAME_MAX - -#if !defined( DEBUGGING ) && !defined( WMOPS ) -static -#endif - int32_t frame = 0; - -#ifdef _WIN32 -#define SEP_FOLDER '\\' -#else -#define SEP_FOLDER '/' -#endif - -#ifdef WMOPS -/* void print_stack_call_tree( void ); -int Const_Data_Size_ivas_prerenderer_mai( void ); // Not a typo -int Const_Data_Size_ivas_rom_prerenderer( void ); -extern int16_t *ptr_base_stack; -extern int16_t *ptr_max_stack; -extern int32_t wc_frame; -extern char location_max_stack[256]; */ - -/* clang-format off */ -/*------------------------------------------------------------------------------------------* -* Function to print complexity & memory estimates -*------------------------------------------------------------------------------------------*/ -/* void print_mem_prerenderer(size_t SRAM_size) -{ - fprintf( stdout, "\n\n --- Prerenderer cmdln demo memory usage --- \n\n" ); - - fprintf( stdout, "PROM size (prerenderer): %d words (or instructions)\n", PROM_Size_prerenderer ); - fprintf( stdout, "Stack size: %d words in %s() in frame #%d\n", ( ptr_base_stack - ptr_max_stack ) * sizeof( int16_t ) / sizeof( float ), location_max_stack, wc_frame ); - fprintf( stdout, "Table ROM size(prerenderer_main): %d words\n", (Const_Data_Size_ivas_prerenderer_mai() ) / sizeof( float ) ); - fprintf( stdout, "Table ROM size(prerenderer): %d words\n", (Const_Data_Size_ivas_rom_prerenderer() ) / sizeof( float ) ); -#ifdef RAM_COUNTING_TOOL - fprintf( stdout, "Static RAM size: %d words\n\n", SRAM_size ); -#endif - print_stack_call_tree(); - - fprintf( stdout, "Note: this is an optimistic estimate of the memory consumption assuming\n" ); - fprintf( stdout, " that each variable (short, long or float) in the codec requires\n" ); - fprintf( stdout, " 32 bits of memory and may therefore be represented by 1 word.\n" ); - fprintf( stdout, " The following formula is used: sizeof('memory array')/sizeof(float)\n\n" ); -} */ -/* clang-format on */ -#endif - -static const char *optInputFile = "--inputFile"; -static const char *optInputFileShort = "-if"; -static const char *optInputAmbisonics = "--inputAmbisonics"; -static const char *optInputAmbisonicsShort = "-if-sba"; -static const char *optInputMultichannel = "--inputMultichannel"; -static const char *optInputMultichannelShort = "-if-mc"; -static const char *optOutputFile = "--outputFile"; -static const char *optOutputFileShort = "-of"; -static const char *optInputAudio = "--inputAudio"; -static const char *optInputAudioShort = "-ia"; -static const char *optFrameSize = "--frameSize"; -static const char *optFrameSizeShort = "-fr"; -static const char *optOutputConfig = "--outputConfig"; -static const char *optOutputConfigShort = "-oc"; -static const char *optSampleRate = "--sampleRate"; -static const char *optSampleRateShort = "-fs"; -static const char *optNeverDropLfe = "--neverDropLfe"; -static const char *optNeverDropLfeShort = "-ndl"; - -typedef struct Prndr_IsmPositionProvider -{ - uint32_t frameCounter; - uint32_t numObjects; - IsmFileReader *ismReaders[PRERENDERER_MAX_ISM_INPUTS]; - uint32_t numPositions[PRERENDERER_MAX_ISM_INPUTS]; - Prndr_AudioObjectPosition *positions[PRERENDERER_MAX_ISM_INPUTS]; /* size: [PRERENDERER_MAX_ISM_INPUTS][numPositions[object_index]] */ - uint16_t *positionDurations[PRERENDERER_MAX_ISM_INPUTS]; /* size: [PRERENDERER_MAX_ISM_INPUTS][numPositions[object_index]] */ - uint32_t currentPositionIdxs[PRERENDERER_MAX_ISM_INPUTS]; /* Index of current position as listed in the metadata file */ - uint16_t durationCounters[PRERENDERER_MAX_ISM_INPUTS]; /* Number of frames spent at current position */ -} Prndr_IsmPositionProvider; - -typedef enum Prndr_ForcedInputFormat -{ - prndr_forced_input_format_none = 0, - prndr_forced_input_format_sba, - prndr_forced_input_format_mc -} Prndr_ForcedInputFormat; - -typedef struct Prndr_CmdlnArgs -{ - char inputFilePath[FILENAME_MAX]; - char outputFilePath[FILENAME_MAX]; - int16_t frameSize; - int32_t sampleRate; - Prndr_OutputConfig outConfig; - Prndr_ForcedInputFormat forcedInputFormat; - char forcedAudioInputFile[FILENAME_MAX]; - int8_t neverDropLfe; /* flag */ -} Prndr_CmdlnArgs; - -static int8_t getAmbisonicsFromNumChannels( - uint32_t numChannels, - Prndr_Ambisonics *ambisonics ); - -static int8_t getSpeakerLayoutFromNumChannels( - uint32_t numChannels, - Prndr_SpeakerLayout *layout ); - -static int8_t setInConfigFromSbaNumChannels( - int16_t numChannels, - Prndr_InputConfig *inConfig ); - -static int8_t setInConfigFromMcNumChannels( - int16_t numChannels, - Prndr_InputConfig *inConfig ); - -static Prndr_Ambisonics ambisonicsOrderToEnum( - int32_t order ); - -static Prndr_SpeakerLayout speakerLayoutCicpToEnum( - int32_t cicpIndex ); - -static int8_t parseOutConfig( - char *configString, - Prndr_OutputConfig *outConfig ); - -static void printUsage( - void ); - -static void parseConfigFile( - char *path, - char *audioFilePath, - Prndr_InputConfig *inConfig, - Prndr_IsmPositionProvider *positionProvider ); - -static Prndr_CmdlnArgs parseCmdlnArgs( - int32_t argc, - char **argv ); - -static Prndr_IsmPositionProvider *Prndr_IsmPositionProvider_open( - void ); - -static void Prndr_IsmPositionProvider_getNextFrame( - Prndr_IsmPositionProvider *positionProvider, - Prndr_AudioObjectMetadataBuffer *objectMetadataBuffer ); - -static void Prndr_IsmPositionProvider_close( - Prndr_IsmPositionProvider *positionProvider ); - -static void readFromShorthandMetadata( - Prndr_IsmPositionProvider *positionProvider, - Prndr_AudioObjectMetadataBuffer *objectMetadataBuffer, - uint32_t objIdx ); - -void getMetadataFromFileReader( - IsmFileReader *ismReader, - Prndr_AudioObjectMetadataBuffer *objectMetadataBuffer, - uint32_t objIdx ); - -static void splitConfigFile( - const char *mdfFilePath, - char *metadataString, - uint32_t *metadataStringLength, - char *wavFileName, - uint32_t *wavFileNameLength ); - -static char *readNextMetadataChunk( - char *line, - const char *delimiter ); - -static void parseUint8( - char *line, - uint8_t *ret ); - -static int8_t parseUint32( - char *line, - uint32_t *ret ); - -static void parseObjectPosition( - char *line, - Prndr_AudioObjectPosition *position, - uint16_t *positionDuration ); - -static void parseIsm( - char *line, - char *inDir, - Prndr_InputConfig *inConfig, - Prndr_IsmPositionProvider *positionProvider, - int32_t idx ); - -static void parseSba( - char *line, - Prndr_InputConfig *inConfig, - int32_t idx ); - -static void parseMc( - char *line, - Prndr_InputConfig *inConfig, - int32_t idx ); - -static void parseMetadata( - char *metadataString, - char *inDir, - Prndr_InputConfig *inConfig, - Prndr_IsmPositionProvider *positionProvider ); - -static void convert_backslash( - char *str ); - -static void remove_cr( - char *str ); - - -/* ============================================================================ */ - -int32_t main( int32_t argc, char **argv ) -{ - Prndr_CmdlnArgs args; - Prndr_Prerenderer *prerenderer; - Prndr_IsmPositionProvider *positionProvider; - Prndr_InputConfig inConfig; - char audioFilePath[FILENAME_MAX]; - AudioFileReader *audioReader = NULL; - int16_t numInChannels; - AudioFileWriter *audioWriter; - int32_t inBufferSize; - int32_t outBufferSize; - int16_t *inpInt16Buffer; - float *inFloatBuffer; - int16_t *outInt16Buffer; - float *outFloatBuffer; - Prndr_AudioBuffer inPrndrBuffer; - Prndr_AudioBuffer outPrndrBuffer; - int16_t numSamplesRead; - int16_t i; - ivas_error error = IVAS_ERR_OK; -#ifdef WMOPS - size_t SRAM_size; -#endif - -#ifdef WMOPS - reset_wmops(); - reset_stack(); -#endif - -#ifdef RAM_COUNTING_TOOL - mem_count_init( 0, USE_32BITS ); -#endif - - args = parseCmdlnArgs( argc, argv ); - - /* === Open === */ - prerenderer = Prndr_Prerenderer_open(); - positionProvider = Prndr_IsmPositionProvider_open(); - - convert_backslash( args.inputFilePath ); - convert_backslash( args.outputFilePath ); - convert_backslash( args.forcedAudioInputFile ); - - /* === Parse === */ - if ( args.forcedInputFormat == prndr_forced_input_format_none ) - { - /* Only parse config file if input config is not forced at cmdln */ - parseConfigFile( args.inputFilePath, audioFilePath, &inConfig, positionProvider ); - } - else - { - /* If input config is forced, input file path is the input audio file, not config file */ - strncpy( audioFilePath, args.inputFilePath, FILENAME_MAX ); - - /* Initialize inConfig - this will be overwritten when applying forced parameters, - * but not initializing here causes a compiler warning on msvc */ - inConfig.numAmbisonicsBuses = 0; - inConfig.numMultiChannelBuses = 0; - inConfig.numAudioObjects = 0; - } - - /* === Apply forced parameters === */ - if ( strlen( args.forcedAudioInputFile ) != 0 ) - { - strncpy( audioFilePath, args.forcedAudioInputFile, FILENAME_MAX ); - } - - AudioFileReader_open( &audioReader, audioFilePath, args.sampleRate ); - if ( !audioReader ) - { - fprintf( stderr, "Error opening file: %s\n", audioFilePath ); - exit( -1 ); - } - - if ( args.forcedInputFormat != prndr_forced_input_format_none ) - { - numInChannels = AudioFileReader_getNumChannels( audioReader ); - if ( numInChannels == 0 ) - { - fprintf( stderr, "File does not contain number of channels metadata, probably a raw file: %s\n", audioFilePath ); - exit( -1 ); - } - - if ( args.forcedInputFormat == prndr_forced_input_format_sba ) - { - - if ( setInConfigFromSbaNumChannels( numInChannels, &inConfig ) != 0 ) - { - fprintf( stderr, "File cannot be used with forced sba input: %s\n", audioFilePath ); - exit( -1 ); - } - } - else if ( args.forcedInputFormat == prndr_forced_input_format_mc ) - { - if ( setInConfigFromMcNumChannels( numInChannels, &inConfig ) != 0 ) - { - fprintf( stderr, "File cannot be used with forced mc input: %s\n", audioFilePath ); - exit( -1 ); - } - } - } - - /* === Configure === */ - if ( ( error = Prndr_Prerenderer_configure( prerenderer, inConfig, args.outConfig, args.frameSize, args.sampleRate ) ) != IVAS_ERR_OK ) - { - exit( -1 ); - } - - if ( args.neverDropLfe ) - { - Prndr_Prerenderer_setNeverDropLfe( prerenderer, 1 ); - } - - if ( Prndr_Prerenderer_getInChannels( prerenderer ) != AudioFileReader_getNumChannels( audioReader ) ) - { - fprintf( stderr, "Number of channels in input file does not match that defined in the config file\n" ); - exit( -1 ); - } - - /* === Process === */ - AudioFileWriter_open( &audioWriter, args.outputFilePath, args.sampleRate, Prndr_Prerenderer_getOutChannels( prerenderer ) ); - - if ( audioWriter == NULL ) - { - exit( -1 ); - } - - inBufferSize = args.frameSize * Prndr_Prerenderer_getInChannels( prerenderer ); - outBufferSize = args.frameSize * Prndr_Prerenderer_getOutChannels( prerenderer ); - inpInt16Buffer = count_calloc( inBufferSize, sizeof( int16_t ) ); - inFloatBuffer = count_calloc( inBufferSize, sizeof( float ) ); - outInt16Buffer = count_calloc( outBufferSize, sizeof( int16_t ) ); - outFloatBuffer = count_calloc( outBufferSize, sizeof( float ) ); - - inPrndrBuffer.config.sampleRate = args.sampleRate; - inPrndrBuffer.config.bufferSize = args.frameSize; - inPrndrBuffer.config.numChannels = Prndr_Prerenderer_getInChannels( prerenderer ); - inPrndrBuffer.data = inFloatBuffer; - - outPrndrBuffer.config.sampleRate = args.sampleRate; - outPrndrBuffer.config.bufferSize = args.frameSize; - outPrndrBuffer.config.numChannels = Prndr_Prerenderer_getOutChannels( prerenderer ); - outPrndrBuffer.data = outFloatBuffer; - -#ifdef WMOPS - reset_wmops(); -#endif - - while ( 1 ) - { - int32_t chnl, smpl; - int32_t num_in_channels; - num_in_channels = inPrndrBuffer.config.numChannels; - i = 0; - - /* Read the input data */ - if ( ( error = AudioFileReader_read( audioReader, inpInt16Buffer, inBufferSize, &numSamplesRead ) ) != IVAS_ERR_OK ) - { - fprintf( stderr, "\nError reading from file %s\n", audioFilePath ); - break; - } - - if ( numSamplesRead == 0 ) - { - /* end of input data */ - break; - } - - /* Convert from int to float and from interleaved to packed */ - for ( smpl = 0; smpl < args.frameSize; ++smpl ) - { - for ( chnl = 0; chnl < num_in_channels; ++chnl ) - { - if ( i < numSamplesRead ) - { - inFloatBuffer[chnl * args.frameSize + smpl] = (float) inpInt16Buffer[i] / INT16_MAX; - } - else - { - inFloatBuffer[chnl * args.frameSize + smpl] = 0.f; - } - - ++i; - } - } - - Prndr_AudioObjectMetadataBuffer mtdBuffer; - Prndr_IsmPositionProvider_getNextFrame( positionProvider, &mtdBuffer ); - - Prndr_Prerenderer_render( prerenderer, inPrndrBuffer, mtdBuffer, outPrndrBuffer ); - - int32_t num_out_channels; - num_out_channels = outPrndrBuffer.config.numChannels; - i = 0; - - /* Convert from float to int and from packed to interleaved */ - for ( smpl = 0; smpl < args.frameSize; ++smpl ) - { - for ( chnl = 0; chnl < num_out_channels; ++chnl ) - { - outInt16Buffer[i] = (int16_t)(outFloatBuffer[chnl * args.frameSize + smpl] * INT16_MAX); - - ++i; - } - } - - if ( AudioFileWriter_write( audioWriter, outInt16Buffer, outBufferSize ) != 0 ) - { - fprintf( stderr, "Error writing audio file %s\n", args.outputFilePath ); - exit( -1 ); - } - - frame++; - fprintf( stdout, "%-8d\b\b\b\b\b\b\b\b", frame ); - -#ifdef WMOPS - update_wmops(); -#endif - } - fprintf( stdout, "\n" ); - - /* === Close === */ - count_free( inpInt16Buffer ); - count_free( inFloatBuffer ); - count_free( outInt16Buffer ); - count_free( outFloatBuffer ); - AudioFileReader_close( &audioReader ); - AudioFileWriter_close( &audioWriter ); - Prndr_Prerenderer_close( prerenderer ); - Prndr_IsmPositionProvider_close( positionProvider ); - -#ifdef RAM_COUNTING_TOOL -#ifdef WMOPS - SRAM_size = -#endif - mem_count_summary( USE_DEFAULT ); -#endif -#ifdef WMOPS - print_wmops(); - /* print_mem_prerenderer( SRAM_size ); */ -#endif - - return 0; -} - -static int8_t getAmbisonicsFromNumChannels( uint32_t numChannels, - Prndr_Ambisonics *ambisonics ) -{ - switch ( numChannels ) - { - case 1: - *ambisonics = prndr_ambisonics_mono; - break; - case 4: - *ambisonics = prndr_ambisonics_foa; - break; - case 9: - *ambisonics = prndr_ambisonics_soa; - break; - case 16: - *ambisonics = prndr_ambisonics_toa; - break; - default: - fprintf( stderr, "Unable to infer ambisonics order from number of channels: %d\n", numChannels ); - return -1; - } - - return 0; -} - -static int8_t getSpeakerLayoutFromNumChannels( uint32_t numChannels, - Prndr_SpeakerLayout *layout ) -{ - switch ( numChannels ) - { - case 1: - *layout = prndr_speaker_layout_mono; - break; - case 2: - *layout = prndr_speaker_layout_stereo; - break; - case 6: - *layout = prndr_speaker_layout_5_1; - break; - case 8: - *layout = prndr_speaker_layout_7_1; - break; - case 10: - *layout = prndr_speaker_layout_5_1_4; - break; - case 12: - *layout = prndr_speaker_layout_7_1_4; - break; - default: - fprintf( stderr, "Unable to infer speaker layout from number of channels: %d\n", numChannels ); - return -1; - } - - return 0; -} - -static int8_t setInConfigFromSbaNumChannels( int16_t numChannels, Prndr_InputConfig *inConfig ) -{ - inConfig->numAmbisonicsBuses = 1; - inConfig->numAudioObjects = 0; - inConfig->numMultiChannelBuses = 0; - - inConfig->ambisonicsBuses[0].inputChannelIndex = 0; - return getAmbisonicsFromNumChannels( numChannels, &inConfig->ambisonicsBuses[0].ambisonicsConfig ); -} - -static int8_t setInConfigFromMcNumChannels( int16_t numChannels, Prndr_InputConfig *inConfig ) -{ - inConfig->numAmbisonicsBuses = 0; - inConfig->numAudioObjects = 0; - inConfig->numMultiChannelBuses = 1; - - inConfig->multiChannelBuses[0].inputChannelIndex = 0; - return getSpeakerLayoutFromNumChannels( numChannels, &inConfig->multiChannelBuses[0].speakerLayout ); -} - -static Prndr_Ambisonics ambisonicsOrderToEnum( int32_t order ) -{ - switch ( order ) - { - case 0: - return prndr_ambisonics_mono; - case 1: - return prndr_ambisonics_foa; - case 2: - return prndr_ambisonics_soa; - case 3: - return prndr_ambisonics_toa; - } - - return prndr_ambisonics_none; -} - -static Prndr_SpeakerLayout speakerLayoutCicpToEnum( int32_t cicpIndex ) -{ - switch ( cicpIndex ) - { - case 0: - return prndr_speaker_layout_custom; - case 1: - return prndr_speaker_layout_mono; - case 2: - return prndr_speaker_layout_stereo; - case 6: - return prndr_speaker_layout_5_1; - case 16: - return prndr_speaker_layout_5_1_4; - case 12: - return prndr_speaker_layout_7_1; - case 19: - return prndr_speaker_layout_7_1_4; - } - - return prndr_speaker_layout_none; -} - -static int8_t parseOutConfig( char *configString, Prndr_OutputConfig *outConfig ) -{ - char outType[5]; - int32_t num; - int8_t success; /* flag */ - - outType[4] = '\0'; - strncpy( outType, configString, 4 ); - - success = 1; - - if ( ( outType[0] == 's' || outType[0] == 'S' ) && - ( outType[1] == 'b' || outType[1] == 'B' ) && - ( outType[2] == 'a' || outType[2] == 'A' ) ) - { - num = strtol( &configString[3], NULL, 10 ); - - /* If num is 0, ensure it's because user requested it and not because of strtol error */ - if ( num == 0 && configString[3] != 0 && configString[4] != '\0' ) - { - success = 0; - } - else - { - outConfig->ambisonics = ambisonicsOrderToEnum( num ); - outConfig->outSetupCustom = NULL; - } - } - else if ( ( outType[0] == 'c' || outType[0] == 'C' ) && - ( outType[1] == 'i' || outType[1] == 'I' ) && - ( outType[2] == 'c' || outType[2] == 'C' ) && - ( outType[3] == 'p' || outType[3] == 'P' ) ) - { - num = strtol( &configString[4], NULL, 10 ); - outConfig->speakerLayout = speakerLayoutCicpToEnum( num ); - outConfig->outSetupCustom = NULL; - } - else - { - int16_t i, is_planar; - LsCustomFileReader *hLsCustomReader = NULL; - IVAS_CUSTOM_LS_DATA hLsCustomData; - - /* Default to interpreting as a custom loudspeaker layout file */ - outConfig->speakerLayout = speakerLayoutCicpToEnum( 0 ); - - CustomLsReader_open( configString, &hLsCustomReader ); - success = ( CustomLsFileReading( hLsCustomReader, &hLsCustomData ) == LS_CUSTOM_FILEREADER_NO_ERROR ); - - outConfig->outSetupCustom->num_spk = hLsCustomData.num_spk; - mvr2r( hLsCustomData.azimuth, outConfig->outSetupCustom->ls_azimuth, hLsCustomData.num_spk ); - mvr2r( hLsCustomData.elevation, outConfig->outSetupCustom->ls_elevation, hLsCustomData.num_spk ); - - /* Set planar flag */ - is_planar = 1; - for ( i = 0; i < hLsCustomData.num_spk; i++ ) - { - if ( is_planar && outConfig->outSetupCustom->ls_elevation[i] != 0.0f ) - { - is_planar = 0; - } - } - outConfig->outSetupCustom->is_planar_setup = is_planar; - - /* Loudspeaker LFE */ - outConfig->outSetupCustom->num_lfe = hLsCustomData.num_lfe; - mvs2s( hLsCustomData.lfe_idx, outConfig->outSetupCustom->lfe_idx, hLsCustomData.num_lfe ); - - CustomLsReader_close( &hLsCustomReader ); - } - - return success ? 0 : -1; -} - -static void printUsage( void ) -{ - printf( "\n" ); - printf( "Usage: ./IVAS_prerenderer [options]\n" ); - printf( "\n" ); - printf( "Valid options:\n" ); - printf( "%s %s Path to the input file (txt config file).\n", optInputFileShort, optInputFile ); - printf( "%s %s Path to the ambisonics audio file. Use this optionally instead of the config file for single-item input configurations.\n", optInputAmbisonicsShort, optInputAmbisonics ); - printf( "%s %s Path to the multichannel audio file. Use this optionally instead of the config file for single-item input configurations.\n", optInputMultichannelShort, optInputMultichannel ); - printf( "%s %s Path to the output file.\n", optOutputFileShort, optOutputFile ); - printf( "%s %s Path to the input audio (overrides audio path from txt config file or -if-sba and -if-mc options) - for debugging/testing purposes.\n", optInputAudioShort, optInputAudio ); - printf( "%s %s Size of processing frame (in ms). Default value is 20ms.\n", optFrameSizeShort, optFrameSize ); - printf( "%s %s Input sampling rate in kHz.\n", optSampleRateShort, optSampleRate ); - printf( "%s %s Output configuration. For ambisonics of order n, select SBAn (e.g. SBA1 for order 1).\n", optOutputConfigShort, optOutputConfig ); - printf( " For multichannel, select CICP followed by CICP index (e.g. CICP6, CICP19).\n" ); - printf( " Alternatively, can be a custom loudspeaker layout file.\n" ); - printf( "%s %s [flag] If set, prerenderer tries to render LFE into other channels in an optimal way when rendering to configs w/o LFE.\n", optNeverDropLfeShort, optNeverDropLfe ); -} - -static int8_t checkOpt( uint32_t argc, char **argv, uint32_t idx, uint32_t numFollowingTokens ) -{ - uint32_t i; - - if ( idx + numFollowingTokens >= argc ) - { - fprintf( stderr, "Error: option %s requires %d following tokens\n", argv[idx], numFollowingTokens ); - return 0; - } - - for ( i = 1; i < numFollowingTokens; ++i ) - { - if ( strlen( argv[idx + i] ) > PRERENDERER_MAX_CMDLN_ARG_LENGTH ) - { - fprintf( stderr, "Too many characters in token: %s\n", argv[idx + i] ); - return 0; - } - } - - return 1; -} - -static Prndr_CmdlnArgs parseCmdlnArgs( int32_t argc, char **argv ) -{ - Prndr_CmdlnArgs parsedArgs; - int8_t success; /* flag */ - int32_t i; - uint32_t numFollowingTokens; - - success = 1; - - parsedArgs.inputFilePath[0] = '\0'; - parsedArgs.outputFilePath[0] = '\0'; - parsedArgs.frameSize = -1; - parsedArgs.sampleRate = -1; - parsedArgs.outConfig.ambisonics = prndr_ambisonics_none; - parsedArgs.outConfig.speakerLayout = prndr_speaker_layout_none; - parsedArgs.forcedInputFormat = prndr_forced_input_format_none; - parsedArgs.forcedAudioInputFile[0] = '\0'; - parsedArgs.neverDropLfe = false; - - i = 1; - while ( i < argc ) - { - numFollowingTokens = 1; /* Default number of expected tokens after an option */ - - if ( strcmp( argv[i], optInputFileShort ) == 0 || strcmp( argv[i], optInputFile ) == 0 ) - { - if ( ( success = checkOpt( argc, argv, i, numFollowingTokens ) ) == 1 ) - { - if ( strlen( parsedArgs.inputFilePath ) == 0 ) - { - strncpy( parsedArgs.inputFilePath, argv[i + 1], FILENAME_MAX ); - } - else - { - fprintf( stderr, "Duplicate option: %s (%s)\n", optInputFile, optInputFileShort ); - success = 0; - } - } - } - else if ( strcmp( argv[i], optInputAmbisonicsShort ) == 0 || strcmp( argv[i], optInputAmbisonics ) == 0 ) - { - if ( ( success = checkOpt( argc, argv, i, numFollowingTokens ) ) == 1 ) - { - if ( strlen( parsedArgs.inputFilePath ) == 0 ) - { - strncpy( parsedArgs.inputFilePath, argv[i + 1], FILENAME_MAX ); - parsedArgs.forcedInputFormat = prndr_forced_input_format_sba; - } - else - { - fprintf( stderr, "Duplicate option: %s (%s)\n", optInputAmbisonics, optInputAmbisonicsShort ); - success = 0; - } - } - } - else if ( strcmp( argv[i], optInputMultichannelShort ) == 0 || strcmp( argv[i], optInputMultichannel ) == 0 ) - { - if ( ( success = checkOpt( argc, argv, i, numFollowingTokens ) ) == 1 ) - { - if ( strlen( parsedArgs.inputFilePath ) == 0 ) - { - strncpy( parsedArgs.inputFilePath, argv[i + 1], FILENAME_MAX ); - parsedArgs.forcedInputFormat = prndr_forced_input_format_mc; - } - else - { - fprintf( stderr, "Duplicate option: %s (%s)\n", optInputMultichannel, optInputMultichannelShort ); - success = 0; - } - } - } - else if ( strcmp( argv[i], optOutputFileShort ) == 0 || strcmp( argv[i], optOutputFile ) == 0 ) - { - if ( ( success = checkOpt( argc, argv, i, numFollowingTokens ) ) == 1 ) - { - if ( strlen( parsedArgs.outputFilePath ) == 0 ) - { - strncpy( parsedArgs.outputFilePath, argv[i + 1], FILENAME_MAX ); - } - else - { - fprintf( stderr, "Duplicate option: %s (%s)\n", optOutputFile, optOutputFileShort ); - success = 0; - } - } - } - else if ( strcmp( argv[i], optInputAudioShort ) == 0 || strcmp( argv[i], optInputAudio ) == 0 ) - { - if ( ( success = checkOpt( argc, argv, i, numFollowingTokens ) ) == 1 ) - { - if ( strlen( parsedArgs.forcedAudioInputFile ) == 0 ) - { - strncpy( parsedArgs.forcedAudioInputFile, argv[i + 1], FILENAME_MAX ); - } - else - { - fprintf( stderr, "Duplicate option: %s (%s)\n", optInputAudio, optInputAudioShort ); - success = 0; - } - } - } - else if ( strcmp( argv[i], optFrameSizeShort ) == 0 || strcmp( argv[i], optFrameSize ) == 0 ) - { - if ( ( success = checkOpt( argc, argv, i, numFollowingTokens ) ) == 1 ) - { - if ( parsedArgs.frameSize <= 0 ) - { - /* Save value in ms for now - later converted to samples once sample rate is known */ - parsedArgs.frameSize = strtol( argv[i + 1], NULL, 10 ); - } - else - { - fprintf( stderr, "Duplicate option: %s (%s)\n", optFrameSize, optFrameSizeShort ); - success = 0; - } - } - } - else if ( strcmp( argv[i], optOutputConfigShort ) == 0 || strcmp( argv[i], optOutputConfig ) == 0 ) - { - if ( ( success = checkOpt( argc, argv, i, numFollowingTokens ) ) == 1 ) - { - if ( parsedArgs.outConfig.ambisonics == prndr_ambisonics_none && parsedArgs.outConfig.speakerLayout == prndr_speaker_layout_none ) - { - if ( parseOutConfig( argv[i + 1], &parsedArgs.outConfig ) != 0 ) - { - fprintf( stderr, "Unknown output or bad config: %s\n", argv[i + 1] ); - success = 0; - } - } - else - { - fprintf( stderr, "Duplicate option: %s (%s)\n", optOutputConfig, optOutputConfigShort ); - success = 0; - } - } - } - else if ( strcmp( argv[i], optSampleRateShort ) == 0 || strcmp( argv[i], optSampleRate ) == 0 ) - { - if ( ( success = checkOpt( argc, argv, i, numFollowingTokens ) ) == 1 ) - { - if ( parsedArgs.sampleRate <= 0 ) - { - parsedArgs.sampleRate = ( int32_t )( strtof( argv[i + 1], NULL ) * 1000 ); - } - else - { - fprintf( stderr, "Duplicate option: %s (%s)\n", optSampleRate, optSampleRateShort ); - success = 0; - } - } - } - else if ( strcmp( argv[i], optNeverDropLfeShort ) == 0 || strcmp( argv[i], optNeverDropLfe ) == 0 ) - { - numFollowingTokens = 0; - - if ( ( success = checkOpt( argc, argv, i, numFollowingTokens ) ) == 1 ) - { - parsedArgs.neverDropLfe = true; - } - } - else - { - fprintf( stderr, "Unknown option: %s\n", argv[i] ); - success = 0; - } - - i += 1 + numFollowingTokens; - } - - /* Check if any of required args is missing */ - if ( strlen( parsedArgs.inputFilePath ) == 0 ) - { - fprintf( stderr, "Required option missing or invalid value: %s (%s) or %s (%s) or %s (%s)\n", - optInputFile, - optInputFileShort, - optInputAmbisonics, - optInputAmbisonicsShort, - optInputMultichannel, - optInputMultichannelShort ); - success = 0; - } - if ( strlen( parsedArgs.outputFilePath ) == 0 ) - { - fprintf( stderr, "Required option missing or invalid value: %s (%s)\n", optOutputFile, optOutputFileShort ); - success = 0; - } - if ( parsedArgs.outConfig.ambisonics == prndr_ambisonics_none && parsedArgs.outConfig.speakerLayout == prndr_speaker_layout_none ) - { - fprintf( stderr, "Required option missing or invalid value: %s (%s)\n", optOutputConfig, optOutputConfigShort ); - success = 0; - } - if ( parsedArgs.sampleRate <= 0 ) - { - fprintf( stderr, "Required option missing or invalid value: %s (%s)\n", optSampleRate, optSampleRateShort ); - success = 0; - } - - /* Set default values if not specified */ - if ( parsedArgs.frameSize <= 0 ) - { - parsedArgs.frameSize = parsedArgs.sampleRate / 50; - } - else - { - /* Convert from ms to samples */ - parsedArgs.frameSize = parsedArgs.sampleRate * parsedArgs.frameSize / 1000; - } - - if ( !success ) - { - printUsage(); - exit( -1 ); - } - - return parsedArgs; -} - - -Prndr_IsmPositionProvider *Prndr_IsmPositionProvider_open( void ) -{ - Prndr_IsmPositionProvider *ipp; - uint32_t i; - - ipp = (Prndr_IsmPositionProvider *) count_malloc( sizeof( Prndr_IsmPositionProvider ) ); - ipp->frameCounter = 0; - ipp->numObjects = 0; - - for ( i = 0; i < PRERENDERER_MAX_ISM_INPUTS; ++i ) - { - ipp->ismReaders[i] = NULL; - ipp->positions[i] = NULL; - ipp->positionDurations[i] = NULL; - ipp->currentPositionIdxs[i] = 0; - ipp->durationCounters[i] = 0; - } - - return ipp; -} - -void getMetadataFromFileReader( - IsmFileReader *ismReader, - Prndr_AudioObjectMetadataBuffer *objectMetadataBuffer, - uint32_t objIdx ) -{ - IVAS_ISM_METADATA ismMetadata; - ivas_error error; - - if ( ( error = IsmFileReader_readNextFrame( ismReader, &ismMetadata ) ) != IVAS_ERR_OK ) - { - fprintf( stderr, "\nError (%s) while reading ism metadata from: %s\n\n", ivas_error_to_string( error ), IsmFileReader_getFilePath( ismReader ) ); - exit( -1 ); - } - - objectMetadataBuffer->positions[objIdx].azimuth = ismMetadata.azimuth; - objectMetadataBuffer->positions[objIdx].elevation = ismMetadata.elevation; -} - -void readFromShorthandMetadata( Prndr_IsmPositionProvider *positionProvider, - Prndr_AudioObjectMetadataBuffer *objectMetadataBuffer, - uint32_t objIdx ) -{ - uint32_t preUpdatePositionIdx; - uint32_t postUpdatePositionIdx; - - preUpdatePositionIdx = positionProvider->currentPositionIdxs[objIdx]; - - if ( positionProvider->durationCounters[objIdx] == positionProvider->positionDurations[objIdx][preUpdatePositionIdx] ) - { - positionProvider->durationCounters[objIdx] = 0; - positionProvider->currentPositionIdxs[objIdx] = ( positionProvider->currentPositionIdxs[objIdx] + 1 ) % positionProvider->numPositions[objIdx]; - } - - ++positionProvider->durationCounters[objIdx]; - - postUpdatePositionIdx = positionProvider->currentPositionIdxs[objIdx]; - - objectMetadataBuffer->positions[objIdx] = positionProvider->positions[objIdx][postUpdatePositionIdx]; -} - -void Prndr_IsmPositionProvider_getNextFrame( - Prndr_IsmPositionProvider *positionProvider, - Prndr_AudioObjectMetadataBuffer *objectMetadataBuffer ) -{ - uint32_t objIdx; - int16_t aziShifted; - - objectMetadataBuffer->numObjects = positionProvider->numObjects; - - for ( objIdx = 0; objIdx < positionProvider->numObjects; ++objIdx ) - { - if ( positionProvider->ismReaders[objIdx] != NULL ) - { - getMetadataFromFileReader( positionProvider->ismReaders[objIdx], objectMetadataBuffer, objIdx ); - } - else - { - readFromShorthandMetadata( positionProvider, objectMetadataBuffer, objIdx ); - } - - /* Wrap azimuth to lie within (-180, 180] range */ - aziShifted = objectMetadataBuffer->positions[objIdx].azimuth + 180; - objectMetadataBuffer->positions[objIdx].azimuth = aziShifted <= 0 || aziShifted % 360 == 0 ? ( aziShifted % 360 ) + 180 : ( aziShifted % 360 ) - 180; - - /* Clamp elevation to lie within [-90, 90] range (can't be wrapped easily) */ - objectMetadataBuffer->positions[objIdx].elevation = min( max( objectMetadataBuffer->positions[objIdx].elevation, -90 ), 90 ); - } - - ++positionProvider->frameCounter; -} - -void Prndr_IsmPositionProvider_close( Prndr_IsmPositionProvider *positionProvider ) -{ - uint32_t i; - - if ( positionProvider == NULL ) - { - assert( !"Can't close Prndr_IsmPositionProvider - pointer is NULL" ); - } - - for ( i = 0; i < PRERENDERER_MAX_ISM_INPUTS; ++i ) - { - if ( positionProvider->ismReaders[i] != NULL ) - { - IsmFileReader_close( &positionProvider->ismReaders[i] ); - } - - if ( positionProvider->positions[i] != NULL ) - { - count_free( positionProvider->positions[i] ); - } - - if ( positionProvider->positionDurations[i] != NULL ) - { - count_free( positionProvider->positionDurations[i] ); - } - } - - count_free( positionProvider ); -} - -static void splitConfigFile( const char *mdfFilePath, - char *metadataString, - uint32_t *metadataStringLength, - char *wavFileName, - uint32_t *wavFileNameLength ) -{ - FILE *file; - uint32_t bufferlength; - char wavLine[FILENAME_MAX]; - uint32_t currentPositionIdxs; - uint32_t mdlength; - - memset( metadataString, 0, *metadataStringLength ); - memset( wavFileName, 0, (int16_t) *wavFileNameLength ); - - file = fopen( mdfFilePath, "rb" ); - if ( !file ) - { - fprintf( stderr, "Couldn't open metadata file %s\n", mdfFilePath ); - exit( -1 ); - } - - fseek( file, 0, SEEK_END ); - bufferlength = ftell( file ); - fseek( file, 0, SEEK_SET ); - - if ( fgets( wavLine, (int) *wavFileNameLength, file ) == NULL ) - { - fprintf( stderr, "Error reading metadata\n" ); - exit( -1 ); - } - currentPositionIdxs = ftell( file ); - if ( *wavFileNameLength < currentPositionIdxs ) - { - assert( !"Couldn't read wavFileName, string buffer too small" ); - } - if ( !sscanf( wavLine, "%s", wavFileName ) ) - { - fprintf( stderr, "Error reading metadata\n" ); - exit( -1 ); - } - *wavFileNameLength = strlen( wavFileName ); - - mdlength = bufferlength - currentPositionIdxs; - /* "+1" for null termination */ - if ( *metadataStringLength + 1 < mdlength ) - { - assert( !"Couldn't read metadata string, string buffer too small" ); - } - - fread( metadataString, 1, mdlength, file ); - metadataString[mdlength] = '\0'; - *metadataStringLength = mdlength + 1; - - fclose( file ); -} - -/* r: pointer to character following last found delimiter */ -static char *readNextMetadataChunkFrom( char *start_char, char *line, const char *delimiter ) -{ - char *token; - - /* start_char can be NULL - it's used to continue parsing with strtok */ - assert( line != NULL && delimiter != NULL && "unexpected NULL ptr given to readNextMetadataChunkFrom()" ); - - token = strtok( start_char, delimiter ); - - /* End of string reached */ - if ( token == NULL ) - { - /* Clear `line` from previous contents and return NULL */ - line[0] = '\0'; - return NULL; - } - - strcpy( line, token ); - - return token + strlen( token ) + 1; -} - -/* r: pointer to character following last found delimiter */ -static char *readNextMetadataChunk( char *line, const char *delimiter ) -{ - return readNextMetadataChunkFrom( NULL, line, delimiter ); -} - -static void parseUint8( char *line, uint8_t *ret ) -{ - char *ptr; - ptr = NULL; - - *ret = strtol( line, &ptr, 10 ); - if ( *ptr != '\0' ) - { - fprintf( stderr, "Cannot parse string \"%s\" as an integer value\n", line ); - exit( -1 ); - } -} - -static int8_t parseUint32( char *line, uint32_t *ret ) -{ - char *ptr; - ptr = " "; - - *ret = strtol( line, &ptr, 10 ); - if ( *ptr != '\0' ) - { - return -1; - } - - return 0; -} - -static void parseOptionalInputValues( - char *line, - float *gain_dB ) -{ - char *parse_pos; - char *key; - char *value; - char *endptr; - - endptr = NULL; - - /* Set default values, in case some values are not specified */ - *gain_dB = 0.f; - - /* Save parsing position - will have to be passed to strtok to resume parsing after using strtok with non-NULL value below */ - parse_pos = readNextMetadataChunk( line, "\n" ); - - /* Look for optional metadata until end of string or next input identifier is found */ - while ( parse_pos != NULL && strcmp( line, "MC" ) != 0 && strcmp( line, "SBA" ) != 0 && strcmp( line, "ISM" ) != 0 ) - { - key = strtok( line, ":" ); - value = strtok( NULL, "\n" ); - - if ( strcmp( key, "gain_dB" ) == 0 ) - { - *gain_dB = (float) strtod( value, &endptr ); - - if ( *endptr != '\0' ) - { - fprintf( stderr, "Cannot parse string string \"%s\" as a float value\n", value ); - exit( -1 ); - } - } - else - { - fprintf( stderr, "Unsupported optional key: %s\n", key ); - exit( -1 ); - } - - parse_pos = readNextMetadataChunkFrom( parse_pos, line, "\n" ); - } -} - -static void parseObjectPosition( char *line, - Prndr_AudioObjectPosition *position, - uint16_t *positionDuration ) -{ - char *endptr; - - readNextMetadataChunk( line, "," ); - *positionDuration = strtol( line, &endptr, 10 ); - - if ( *endptr != '\0' ) - { - fprintf( stderr, "Error reading metadata\n" ); - exit( -1 ); - } - - readNextMetadataChunk( line, "," ); - position->azimuth = strtol( line, &endptr, 10 ); - - if ( *endptr != '\0' ) - { - fprintf( stderr, "Error reading metadata\n" ); - exit( -1 ); - } - - readNextMetadataChunk( line, "\n" ); - position->elevation = strtol( line, &endptr, 10 ); - if ( *endptr != '\0' ) - { - fprintf( stderr, "Error reading metadata\n" ); - exit( -1 ); - } -} - -static void parseIsm( - char *line, - char *inDir, - Prndr_InputConfig *inConfig, - Prndr_IsmPositionProvider *positionProvider, - int32_t idx ) -{ - uint32_t numberOfObjectPositionsToRead; - uint32_t i; - - readNextMetadataChunk( line, "\n" ); - parseUint8( line, &inConfig->audioObjects[idx].inputChannelIndex ); - --inConfig->audioObjects[idx].inputChannelIndex; /* Convert from 1-indexing */ - - readNextMetadataChunk( line, "\n" ); - - /* Try to interpret line as number of positions to read */ - if ( parseUint32( line, &numberOfObjectPositionsToRead ) == 0 ) - { - positionProvider->numPositions[idx] = numberOfObjectPositionsToRead; - positionProvider->positions[idx] = count_calloc( numberOfObjectPositionsToRead, sizeof( Prndr_AudioObjectPosition ) ); - positionProvider->positionDurations[idx] = count_calloc( numberOfObjectPositionsToRead, sizeof( uint16_t ) ); - - for ( i = 0; i < numberOfObjectPositionsToRead; ++i ) - { - parseObjectPosition( line, &positionProvider->positions[idx][i], &positionProvider->positionDurations[idx][i] ); - } - } - else /* If not a number, it is a relative path from main metadata file to a metadata file */ - { - char fullpath[FILENAME_MAX]; - *fullpath = '\0'; - strncat( fullpath, inDir, strlen( inDir ) ); - strncat( fullpath, line, sizeof( fullpath ) - strlen( fullpath ) - 1 ); - if ( ( positionProvider->ismReaders[idx] = IsmFileReader_open( fullpath ) ) == NULL ) - { - fprintf( stderr, "Error: ISM input metadata file %s could not be opened\n", line ); - exit( -1 ); - } - } - - /* Read optional values */ - parseOptionalInputValues( line, &inConfig->audioObjects[idx].gain_dB ); -} - -static void parseSba( char *line, - Prndr_InputConfig *inConfig, - int32_t idx ) -{ - uint8_t ambiOrder; - - readNextMetadataChunk( line, "\n" ); - parseUint8( line, &inConfig->ambisonicsBuses[idx].inputChannelIndex ); - --inConfig->ambisonicsBuses[idx].inputChannelIndex; /* Convert from 1-indexing */ - - readNextMetadataChunk( line, "\n" ); - parseUint8( line, &ambiOrder ); - inConfig->ambisonicsBuses[idx].ambisonicsConfig = ambisonicsOrderToEnum( ambiOrder ); - - /* Read optional values */ - parseOptionalInputValues( line, &inConfig->ambisonicsBuses[idx].gain_dB ); -} - -static void parseMc( char *line, - Prndr_InputConfig *inConfig, - int32_t idx ) -{ - uint8_t cicpIndex; - - readNextMetadataChunk( line, "\n" ); - parseUint8( line, &inConfig->multiChannelBuses[idx].inputChannelIndex ); - --inConfig->multiChannelBuses[idx].inputChannelIndex; /* Convert from 1-indexing */ - - readNextMetadataChunk( line, "\n" ); - parseUint8( line, &cicpIndex ); - inConfig->multiChannelBuses[idx].speakerLayout = speakerLayoutCicpToEnum( cicpIndex ); - - /* Read optional values */ - parseOptionalInputValues( line, &inConfig->multiChannelBuses[idx].gain_dB ); -} - -static void parseMetadata( - char *metadataString, - char *inDir, - Prndr_InputConfig *inConfig, - Prndr_IsmPositionProvider *positionProvider ) -{ - char line[PRERENDERER_MAX_METADATA_LINE_LENGTH]; - char *delimiter; - char *token; - uint8_t totalNumberOfAudioObjects; - uint8_t counterChannelAudioObjects; - uint8_t counterAmbisonicsAudioObjects; - uint8_t counterMonoAudioObjects; - uint8_t num_parsed_inputs; - - delimiter = "\n"; - - token = strtok( metadataString, delimiter ); - if ( token == NULL ) - { - fprintf( stderr, "Unexpected metadata format\n" ); - exit( -1 ); - } - if ( !sscanf( token, "%s", line ) ) - { - fprintf( stderr, "Unexpected metadata format\n" ); - exit( -1 ); - } - - parseUint8( line, &totalNumberOfAudioObjects ); - if ( totalNumberOfAudioObjects <= 0 ) - { - fprintf( stderr, "Invalid metadata: number of inputs should be > 0\n" ); - exit( -1 ); - } - - num_parsed_inputs = 0; - counterChannelAudioObjects = 0; - counterAmbisonicsAudioObjects = 0; - counterMonoAudioObjects = 0; - - readNextMetadataChunk( line, delimiter ); - - while ( num_parsed_inputs < totalNumberOfAudioObjects ) - { - /* `line` will already contain the identifier ("MC", "SBA" or "ISM") after previous iteration */ - if ( strcmp( line, "MC" ) == 0 ) - { - ++counterChannelAudioObjects; - if ( counterChannelAudioObjects > PRERENDERER_MAX_MC_INPUTS ) - { - fprintf( stderr, "Metadata exceeds the supported number of MC inputs\n" ); - exit( -1 ); - } - parseMc( line, inConfig, counterChannelAudioObjects - 1 ); - } - else if ( strcmp( line, "SBA" ) == 0 ) - { - ++counterAmbisonicsAudioObjects; - if ( counterAmbisonicsAudioObjects > PRERENDERER_MAX_SBA_INPUTS ) - { - fprintf( stderr, "Metadata exceeds the supported number of SBA inputs\n" ); - exit( -1 ); - } - parseSba( line, inConfig, counterAmbisonicsAudioObjects - 1 ); - } - else if ( strcmp( line, "ISM" ) == 0 ) - { - ++counterMonoAudioObjects; - if ( counterMonoAudioObjects > PRERENDERER_MAX_ISM_INPUTS ) - { - fprintf( stderr, "Metadata exceeds the supported number of ISM inputs\n" ); - exit( -1 ); - } - parseIsm( line, inDir, inConfig, positionProvider, counterMonoAudioObjects - 1 ); - } - else if ( line[0] == '\0' ) - { - fprintf( stderr, "Metadata string too short - expected %d inputs, found %d.\n", totalNumberOfAudioObjects, num_parsed_inputs ); - exit( -1 ); - } - else - { - fprintf( stderr, "Unexpected metadata identifier\n" ); - exit( -1 ); - } - - ++num_parsed_inputs; - } - - inConfig->numAudioObjects = counterMonoAudioObjects; - inConfig->numAmbisonicsBuses = counterAmbisonicsAudioObjects; - inConfig->numMultiChannelBuses = counterChannelAudioObjects; - positionProvider->numObjects = counterMonoAudioObjects; - - /* check for trailing text */ - token = strtok( NULL, delimiter ); - if ( token != NULL && sscanf( token, "%s", line ) ) - { - fprintf( stderr, "Trailing text in metadata file\n" ); - exit( -1 ); - } -} - -void parseConfigFile( char *path, char *audioFilePath, Prndr_InputConfig *inConfig, Prndr_IsmPositionProvider *positionProvider ) -{ - uint32_t inAudioFilePathLen; - char inAudioFilePath[FILENAME_MAX]; - uint32_t mtdStrLen; - char mtdStr[PRERENDERER_MAX_METADATA_LENGTH]; - char inDir[FILENAME_MAX]; - char *lastSlash = NULL; - - inAudioFilePathLen = FILENAME_MAX; - mtdStrLen = PRERENDERER_MAX_METADATA_LENGTH; - splitConfigFile( path, - mtdStr, - &mtdStrLen, - inAudioFilePath, - &inAudioFilePathLen ); - - remove_cr( mtdStr ); - convert_backslash( inAudioFilePath ); - - /* Trim config file path to get path to the dir containing it */ - lastSlash = strrchr( path, SEP_FOLDER ); - *inDir = '\0'; - if ( lastSlash != NULL ) - { - strncat( inDir, path, ( lastSlash - path + 1 ) ); - } - - /* Append audio file path (relative to config file location) - * to config file location path to get full absolute path */ - strcpy( audioFilePath, inDir ); - strncat( audioFilePath, inAudioFilePath, inAudioFilePathLen ); - - parseMetadata( mtdStr, inDir, inConfig, positionProvider ); -} - -static void convert_backslash( char *str ) -{ - int i, len; - - /* check that all backslashes are correct on the given platform */ - len = strlen( str ); - - for ( i = 0; i < len; i++ ) - { -#ifdef _WIN32 - if ( str[i] == '/' ) - { - str[i] = '\\'; - } -#else - if ( str[i] == '\\' ) - { - str[i] = '/'; - } -#endif - } - - return; -} - -static void remove_cr( char *str ) -{ - char *pos; - - /* remove all \r characters from the string */ - pos = strchr( str, '\r' ); - while ( pos != NULL ) - { - strcpy( pos, pos + 1 ); - pos = strchr( pos, '\r' ); - } - - return; -} diff --git a/scripts/pyaudio3dtools/EFAP.py b/scripts/pyaudio3dtools/EFAP.py index 73b8df6ee0..171cbb4c28 100644 --- a/scripts/pyaudio3dtools/EFAP.py +++ b/scripts/pyaudio3dtools/EFAP.py @@ -28,6 +28,7 @@ import argparse import os +from enum import Enum from itertools import combinations from typing import Optional, Tuple, Union @@ -75,6 +76,12 @@ def wrap_angles( return azi, ele +class EfapDmxType(Enum): + NONE = 0 + AMPLITUDE = 1 + INTENSITY = 2 + + class EfapVertex: """ Vertex data structure for EFAP @@ -89,9 +96,17 @@ class EfapVertex: Elevation of vertex is_ghost : bool Whether the vertex is a ghost, default is False + dmx_type : EfapDmxType + Downmix type for ghost vertices """ - def __init__(self, azi: float, ele: float, is_ghost: Optional[bool] = False): + def __init__( + self, + azi: float, + ele: float, + is_ghost: Optional[bool] = False, + dmx_type: Optional[EfapDmxType] = EfapDmxType.INTENSITY, + ): self.azi, self.ele = wrap_angles(azi, ele) self.pos = np.array( [ @@ -108,6 +123,7 @@ class EfapVertex: ) # vertices on the median plane have lowest index self.is_ghost = is_ghost + self.dmx_type = dmx_type def __str__(self): str_ = f"a{self.azi}e{self.ele}" @@ -132,13 +148,15 @@ class EFAP: Azimuth positions of the loudspeaker array elevations : npndarray Elevation postions of the loudspeaker array + intensity_panning : bool + Whether intensity panning is enabled or not Examples -------- >>> from EFAP import EFAP - >>> panner = EFAP([30, -30, 0, 110, -110], [0, 0, 0, 0, 0]]) - >>> panner.pan(15, 45, intensity_panning=False) + >>> panner = EFAP([30, -30, 0, 110, -110], [0, 0, 0, 0, 0], False) + >>> panner.pan(15, 45) array([0.66742381, 0.19069252, 0.66742381, 0.19069252, 0.19069252]) """ @@ -152,7 +170,10 @@ class EFAP: _EFAP_THRESH_TRI = 1e-10 # tolerance for a point to be inside a triangle def __init__( - self, azimuths: Union[list, np.ndarray], elevations: Union[list, np.ndarray] + self, + azimuths: Union[list, np.ndarray], + elevations: Union[list, np.ndarray], + intensity_panning: Optional[bool] = False, ): # validation azimuths = np.array(azimuths) @@ -164,6 +185,9 @@ class EFAP: if azimuths.shape != elevations.shape: raise ValueError("Mismatch between loudspeaker azimuths and elevations") + # set EFIP flag + self.intensity_panning = intensity_panning + # initialise vertices and add ghost loudspeakers if needed self.verts = np.array( [EfapVertex(azi, ele) for azi, ele in zip(azimuths, elevations)] @@ -198,11 +222,28 @@ class EFAP: """ ele = [v.ele for v in self.verts] + dmx_type = EfapDmxType.INTENSITY + # add ghost loudspeakers at the poles if necessary if max(ele) < self._EFAP_POLAR_ELE: - self.verts = np.append(self.verts, EfapVertex(0, 90, True)) + + if self.intensity_panning: + if max(ele) > self._EFAP_THRESH_MID_LAYER: + dmx_type = EfapDmxType.NONE + else: + dmx_type = EfapDmxType.AMPLITUDE + + self.verts = np.append(self.verts, EfapVertex(0, 90, True, dmx_type)) + if min(ele) > -self._EFAP_POLAR_ELE: - self.verts = np.append(self.verts, EfapVertex(0, -90, True)) + + if self.intensity_panning: + if min(ele) < -self._EFAP_THRESH_MID_LAYER: + dmx_type = EfapDmxType.NONE + else: + dmx_type = EfapDmxType.AMPLITUDE + + self.verts = np.append(self.verts, EfapVertex(0, -90, True, dmx_type)) # check for large gaps in the middle horizontal layer mid_spkrs = [ @@ -390,10 +431,21 @@ class EFAP: vec = M @ vec M2[:, i] = vec - # energy distribution for real LS and amplitude distribution for ghost LS self.dmx_mat = M2[:-n_ghost, :] + + # amplitude downmix for real loudspeakers self.dmx_mat[:, :-n_ghost] = np.sqrt(self.dmx_mat[:, :-n_ghost]) + # distribute ghosts according to downmix type + for i, v in enumerate(self.verts): + if v.is_ghost: + if v.dmx_type == EfapDmxType.NONE: + self.dmx_mat[:, i] = 0 + elif v.dmx_type == EfapDmxType.AMPLITUDE: + pass + else: + self.dmx_mat[:, i] = np.sqrt(self.dmx_mat[:, i]) + def _tri2poly(self) -> None: """ Merge hull triangles into polygons if they are coplanar @@ -711,9 +763,7 @@ class EFAP: return surface - def _compute_gains_point( - self, azimuth: float, elevation: float, intensity_panning: bool = False - ) -> np.ndarray: + def _compute_gains_point(self, azimuth: float, elevation: float) -> np.ndarray: """ Compute gains for the requested panning position @@ -724,8 +774,6 @@ class EFAP: Azimuth of requested panning position elevation : float Elevation of requested panning position - intensity_panning : bool - Flag whether to use intensity panning (Default is False == amplitude panning) Returns ------- @@ -757,7 +805,7 @@ class EFAP: gains = gains @ self.dmx_mat.T gains = gains / np.linalg.norm(gains) - if intensity_panning: + if self.intensity_panning: gains = np.sqrt(gains / np.sum(gains)) return gains @@ -788,11 +836,11 @@ class EFAP: azimuths = np.array(azimuths) elevations = np.array(elevations) if azimuths.size == 1 and elevations.size == 1: - return self._compute_gains_point(azimuths, elevations, intensity_panning) + return self._compute_gains_point(azimuths, elevations) elif np.squeeze(azimuths).ndim == 1 and np.squeeze(elevations).ndim == 1: gains = [] for a, e in zip(azimuths, elevations): - gains.append(self._compute_gains_point(a, e, intensity_panning)) + gains.append(self._compute_gains_point(a, e)) return np.vstack(gains) else: raise ValueError( @@ -816,8 +864,8 @@ def main(args): speaker_positions = np.loadtxt( os.path.abspath(args.input), delimiter=",", max_rows=2 ) - panner = EFAP(speaker_positions[0, :], speaker_positions[1, :]) - print(panner.pan(args.azimuth, args.elevation, args.efip)) + panner = EFAP(speaker_positions[0, :], speaker_positions[1, :], args.efip) + print(panner.pan(args.azimuth, args.elevation)) if __name__ == "__main__": diff --git a/scripts/pyaudio3dtools/audio3dtools.py b/scripts/pyaudio3dtools/audio3dtools.py index 99ae71351b..c2b1ff46d1 100644 --- a/scripts/pyaudio3dtools/audio3dtools.py +++ b/scripts/pyaudio3dtools/audio3dtools.py @@ -84,7 +84,7 @@ def main(): "--outformat", type=str, metavar="OUTFORMAT", - help="Output format (default = %(default)s, same as input format)", + help="Output format (default = %(default)s, same as input format). Can be a custom loudspeaker layout file.", default=None, ) parser.add_argument( @@ -116,13 +116,6 @@ def main(): help="list of input metadata files (only relevant for ISM and MASA input)", default=None, ) - parser.add_argument( - "-y", - "--layoutfile", - help="File describing a custom LS layout", - type=str, - default=None, - ) parser.add_argument( "-fc", "--outfc", @@ -249,7 +242,6 @@ def main(): in_fs=args.infs, in_nchans=args.inchan, in_meta_files=args.metadata, - in_ls_layout_file=args.layoutfile, out_format=args.outformat, out_fs=args.outfs, out_fc=args.outfc, @@ -277,7 +269,6 @@ def main(): in_format=args.outformat, in_fs=args.outfs, in_meta_files=args.metadata, - in_ls_layout_file=args.layoutfile, out_format="BINAURAL", output_loudness=args.normalize, loudness_tool=args.loudness_tool, diff --git a/scripts/pyaudio3dtools/audioarray.py b/scripts/pyaudio3dtools/audioarray.py index 16569e1ec7..dd2c5fca5f 100644 --- a/scripts/pyaudio3dtools/audioarray.py +++ b/scripts/pyaudio3dtools/audioarray.py @@ -286,7 +286,7 @@ def compare(ref: np.ndarray, test: np.ndarray, fs: int) -> dict: def getdelay(x: np.ndarray, y: np.ndarray) -> int: - """Get the delay between two audios signals + """Get the delay between two audio signals Parameters ---------- diff --git a/scripts/pyaudio3dtools/audiofile.py b/scripts/pyaudio3dtools/audiofile.py old mode 100755 new mode 100644 index 46bb452082..32d8460e1d --- a/scripts/pyaudio3dtools/audiofile.py +++ b/scripts/pyaudio3dtools/audiofile.py @@ -489,7 +489,6 @@ def loudnessinfo( in_sig: np.ndarray, in_fs: Optional[int] = 48000, in_format: Optional[str] = "MONO", - in_ls_layout_file: Optional[str] = None, output_loudness: Optional[int] = -26, loudness_tool: Optional[str] = "bs1770demo", use_rms: Optional[bool] = False, @@ -524,13 +523,10 @@ def loudnessinfo( else: null_file = "/dev/null" - # check for binary if shutil.which(loudness_tool) is None: raise FileNotFoundError(f"The binary {loudness_tool} was not found in path!") - in_spfmt = spatialaudioformat.Format( - in_format=in_format, ls_layout_file=in_ls_layout_file - ) + in_spfmt = spatialaudioformat.Format(in_format=in_format) if not (in_spfmt.isheadphones or in_spfmt.isloudspeaker or in_spfmt.ambi_order > 1): raise NotImplementedError( @@ -543,7 +539,7 @@ def loudnessinfo( ) with TemporaryDirectory() as tmp_dir: - tmp_file = os.path.join(tmp_dir, "tmp.pcm") + tmp_file = os.path.join(tmp_dir, "tmp_loudness.pcm") if "bs1770demo" in loudness_tool: """ diff --git a/scripts/pyaudio3dtools/binauralrenderer.py b/scripts/pyaudio3dtools/binauralrenderer.py index ca56618a01..52fc800242 100644 --- a/scripts/pyaudio3dtools/binauralrenderer.py +++ b/scripts/pyaudio3dtools/binauralrenderer.py @@ -39,12 +39,10 @@ import numpy as np import scipy.interpolate as interp import scipy.io as sio import scipy.signal as sig +from pyaudio3dtools.rotation import rotateHOA, rotateISM, rotateMC from pyaudio3dtools import audioarray, spatialaudioformat from pyaudio3dtools.constants import * -from pyaudio3dtools.rotateHOA import rotateHOA -from pyaudio3dtools.rotateISM import rotateISM -from pyaudio3dtools.rotateMC import rotateMC main_logger = logging.getLogger("__main__") logger = main_logger.getChild(__name__) @@ -256,7 +254,7 @@ def binaural_fftconv_framewise( SourcePosition: np.ndarray, azi: np.ndarray = None, ele: np.ndarray = None, - frame_len: int = (IVAS_FRAME_LEN_MS // 4) * 48000, + frame_len: int = (IVAS_FRAME_LEN_MS // 4) * 48, interp_method="linear", verbose=False, ) -> np.ndarray: @@ -290,7 +288,7 @@ def binaural_fftconv_framewise( """ sig_len = x.shape[0] - frame_len = (IVAS_FRAME_LEN_MS // 4) * 48000 + frame_len = (IVAS_FRAME_LEN_MS // 4) * 48 N_frames = int(sig_len / frame_len) N_HRIR_taps = IR.shape[2] @@ -396,8 +394,8 @@ def binaural_fftconv_framewise( y = np.zeros([sig_len + T_rev, 2]) y0 = np.zeros([N_rev, sig_len + T_rev, 2]) - b = np.linspace(0.0, 1.0, frame_len, endpoint=False) - a = 1.0 - b + fade_in = np.linspace(0.0, 1.0, frame_len, endpoint=False) + fade_out = 1.0 - fade_in for i_ear in [0, 1]: @@ -419,8 +417,8 @@ def binaural_fftconv_framewise( i2 = (i_frame + 1) * frame_len i2p = i1 + T_rev - a = np.linspace(0.0, 1.0, T_rev, endpoint=False) - b = 1.0 - a + fade_out = np.linspace(0.0, 1.0, T_rev, endpoint=False) + fade_in = 1.0 - fade_out for j_frame in [0, 1]: G_n_m = G[min(j_frame + i_frame, N_frames - 1), :] @@ -428,7 +426,9 @@ def binaural_fftconv_framewise( np.squeeze(x[i1:i2]), G_n_m ) - y[i1:i2p, i_ear] += a * y0[0, i1:i2p, i_ear] + b * y0[1, i1:i2p, i_ear] + y[i1:i2p, i_ear] += ( + fade_out * y0[0, i1:i2p, i_ear] + fade_in * y0[1, i1:i2p, i_ear] + ) t1 = timeit.default_timer() fps = (i_frame + 1) / (t1 - t0) @@ -464,7 +464,9 @@ def binaural_fftconv_framewise( y0[0, j1:j2p, i_ear] += sig.oaconvolve(np.squeeze(x[j1:j2]), G0) y0[1, j1:j2p, i_ear] += sig.oaconvolve(np.squeeze(x[j1:j2]), G1) - y[i1:i2, i_ear] = a * y0[0, i1:i2, i_ear] + b * y0[1, i1:i2, i_ear] + y[i1:i2, i_ear] = ( + fade_out * y0[0, i1:i2, i_ear] + fade_in * y0[1, i1:i2, i_ear] + ) t1 = timeit.default_timer() fps = (i_frame + 1) / (t1 - t0) @@ -531,10 +533,6 @@ def render_custom_ls_binaural( SourcePosition: np.ndarray, trajectory: np.ndarray, ) -> np.ndarray: - if in_format.name != "CUSTOM_LS": - raise ValueError( - f"Unsupported format {in_format.name} for CUSTOM_LS binaural rendering!" - ) ls_azi_all = in_format.ls_azi ls_ele_all = in_format.ls_ele @@ -545,31 +543,30 @@ def render_custom_ls_binaural( logger.info("ele: {}".format(ls_ele_all)) logger.info("lfe_index: {}".format(lfe_index_all)) - y = audioarray.resample(x, fs, 48000) - frame_len = (IVAS_FRAME_LEN_MS // 4) * (fs // 1000) - sig_len = y.shape[0] + sig_len = x.shape[0] N_frames = int(sig_len / frame_len) i_ls = 0 - y_all = np.zeros([sig_len, 2]) - for i_chan in range(y.shape[1]): + y = np.zeros([sig_len, 2]) + for i_chan in range(x.shape[1]): # skip LFE if i_chan in lfe_index_all: continue # skip silent (or very low volume) channels - if np.allclose(y[:, i_chan], 0.0, atol=32.0): + if np.allclose(x[:, i_chan], 0.0, atol=32.0): continue ls_azi = np.repeat(ls_azi_all[i_ls], N_frames) ls_ele = np.repeat(ls_ele_all[i_ls], N_frames) - azi, ele = rotateISM(ls_azi, ls_ele, trajectory=trajectory) + if trajectory is not None: + azi, ele = rotateISM(ls_azi, ls_ele, trajectory=trajectory) - y_all += binaural_fftconv_framewise( - y[:, i_chan], + y += binaural_fftconv_framewise( + x[:, i_chan], IR, SourcePosition, frame_len=frame_len, @@ -579,9 +576,7 @@ def render_custom_ls_binaural( ) i_ls += 1 - y = audioarray.resample(y_all, 48000, fs) - - return y_all + return y def render_ism_binaural( @@ -593,10 +588,9 @@ def render_ism_binaural( trajectory: np.ndarray, in_pos: np.ndarray, ) -> np.ndarray: - y = audioarray.resample(x, fs, 48000) frame_len = (IVAS_FRAME_LEN_MS // 4) * (fs // 1000) - sig_len = y.shape[0] + sig_len = x.shape[0] N_frames = int(sig_len / frame_len) # get ISM metadata and repeat it nsubframe times @@ -611,12 +605,12 @@ def render_ism_binaural( # extract positions only according to the audio duration pos_data = pos_data[:N_frames, :] - y_all = np.zeros([sig_len, 2]) - - azi, ele = rotateISM(pos_data[:, 0], pos_data[:, 1], trajectory=trajectory) + if trajectory is not None: + azi, ele = rotateISM(pos_data[:, 0], pos_data[:, 1], trajectory=trajectory) - y_all += binaural_fftconv_framewise( - y, + y = np.zeros([sig_len, 2]) + y += binaural_fftconv_framewise( + x, IR, SourcePosition, frame_len=frame_len, @@ -625,9 +619,40 @@ def render_ism_binaural( verbose=False, ) - y = audioarray.resample(y_all, 48000, fs) + return y + + +def render_masa_binaural( + x: np.ndarray, + fs: int, + in_format: spatialaudioformat.Format, + IR: np.ndarray, + SourcePosition: np.ndarray, + trajectory: np.ndarray, +): + y = x[:, :2] + # TODO + return y + + +def render_ambi_ls_binaural( + x: np.ndarray, + fs: int, + in_format: spatialaudioformat.Format, + IR: np.ndarray, + trajectory: np.ndarray, +) -> np.ndarray: + + y = x[:] + if trajectory is not None: + if in_format.ambi_order > 0: + y = rotateHOA(y, trajectory) + if in_format.isloudspeaker: + y = rotateMC(y, trajectory, in_format) - return y_all + y = binaural_fftconv(y, IR, in_format.nchannels, in_format.lfe_index) + + return y """ Wrapper function for generic binaural rendering """ @@ -642,7 +667,6 @@ def binaural_rendering( trajectory: str = None, include_LFE: bool = False, LFE_gain: float = 10 ** (5.5 / 20), - in_ls_layout_file: str = None, in_pos: dict = None, ): """Binaural rendering @@ -672,17 +696,24 @@ def binaural_rendering( " performing rotation along trajectory from file {}".format(trajectory) ) + # resample to 48 kHz + y = audioarray.resample(x, fs, 48000) + # get IR corresponding to the input and output formats IR, SourcePosition = get_IR(in_format, out_format, dataset) + latency_smp = np.argmax(np.sum(np.abs(IR), axis=(1, 2))) + + # prepare LFE signal to be added to output + if include_LFE and in_format.isloudspeaker: + lfe = binaural_render_LFE(x, 48000, in_format.lfe_index, LFE_gain, latency_smp) + # get binauralized signal based on format if in_format.name.startswith("CUSTOM_LS"): - return render_custom_ls_binaural( - x, fs, in_format, IR, SourcePosition, trajectory - ) + y = render_custom_ls_binaural(x, fs, in_format, IR, SourcePosition, trajectory) elif in_format.name.startswith("ISM"): if not in_pos: raise ValueError("ISM metadata empty!") - return render_ism_binaural( + y = render_ism_binaural( x, fs, in_format, @@ -692,37 +723,23 @@ def binaural_rendering( in_pos, ) elif in_format.name.startswith("MASA"): - pass # TODO - # return render_masa_binaural() + y = render_masa_binaural(x, fs, in_format, IR, SourcePosition, trajectory) elif in_format.ambi_order > 0 or in_format.isloudspeaker: - y = audioarray.resample(x, fs, 48000) - - if trajectory is not None: - if in_format.ambi_order > 0: - y = rotateHOA(y, trajectory) - if in_format.isloudspeaker: - y = rotateMC(y, trajectory, in_format) - - if include_LFE: - lfe = binaural_render_LFE( - y, 48000, in_format.lfe_index, LFE_gain, latency_smp - ) - - y = binaural_fftconv(y, IR, in_format.nchannels, in_format.lfe_index) - - if include_LFE: - y += lfe - - # HRTF delay compensation - latency_smp = np.argmax(np.sum(np.abs(IR), axis=(1, 2))) - y = np.roll(y, latency_smp, axis=0) - if latency_smp > 0: - y[:latency_smp, :] = 0 - - y = audioarray.resample(y, 48000, fs) - - return y + y = render_ambi_ls_binaural(x, fs, in_format, IR, trajectory) else: raise NotImplementedError( f"{in_format.name} -> {out_format.name}: format conversion not implemented" ) + + # add LFE signal to output + if include_LFE and in_format.isloudspeaker: + y += lfe + + # HRTF delay compensation + y = np.roll(y, -latency_smp, axis=0) + y[-latency_smp:, :] = 0 + + # resample back to original rate + y = audioarray.resample(y, 48000, fs) + + return y diff --git a/scripts/pyaudio3dtools/constants.py b/scripts/pyaudio3dtools/constants.py index 24c8b7aaba..b9523fc4ae 100644 --- a/scripts/pyaudio3dtools/constants.py +++ b/scripts/pyaudio3dtools/constants.py @@ -35,16 +35,16 @@ IVAS_CICPX_TO_MONO = np.array( [ 1, 1, - np.sqrt(0.5), - np.sqrt(0.5), - 0.79999995, - 0.79999995, - 0.79999995, - 0.79999995, - 0.849999964, - 0.849999964, - 0.849999964, - 0.849999964, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, ] ] ).T @@ -198,8 +198,10 @@ IVAS_MC_CONVERSION = { }, "5_1_4": { # downmix - "MONO": IVAS_CICPX_TO_MONO[:10, :], - "STEREO": IVAS_CICPX_TO_STEREO[:10, :], + "MONO": np.vstack([IVAS_CICPX_TO_MONO[:6, :], IVAS_CICPX_TO_MONO[-4:, :]]), + "STEREO": np.vstack( + [IVAS_CICPX_TO_STEREO[:6, :], IVAS_CICPX_TO_STEREO[-4:, :]] + ), "5_1": IVAS_CICP16_TO_6, "7_1": IVAS_CICP16_TO_12, "5_1_2": IVAS_CICP16_TO_14, diff --git a/scripts/pyaudio3dtools/hoadecoder.py b/scripts/pyaudio3dtools/hoadecoder.py index 331e86f52f..b774c0a9ec 100644 --- a/scripts/pyaudio3dtools/hoadecoder.py +++ b/scripts/pyaudio3dtools/hoadecoder.py @@ -65,15 +65,21 @@ def get_hoa_mtx( mtx_hoa_dec[1, 0] = 0.5 mtx_hoa_dec[1, 1] = -0.5 elif spkrlayout.isloudspeaker: - Y_td = getRSH(T_DESIGN_11_AZI, T_DESIGN_11_ELE, ambi_order, norm="ortho") + # TODO getRSH in IVAS casts to int16_t , decide on final behaviour for scripts + Y_td = getRSH( + T_DESIGN_11_AZI.astype(np.int16), + T_DESIGN_11_ELE.astype(np.int16), + ambi_order, + norm="ortho", + ) Y_td *= np.sqrt(4 * np.pi) n_ls_woLFE = spkrlayout.nchannels - len(spkrlayout.lfe_index) ls_azi_woLFE = np.delete(spkrlayout.ls_azi, spkrlayout.lfe_index).astype(float) ls_ele_woLFE = np.delete(spkrlayout.ls_ele, spkrlayout.lfe_index).astype(float) - panner = EFAP(ls_azi_woLFE, ls_ele_woLFE) - G_td = panner.pan(T_DESIGN_11_AZI, T_DESIGN_11_ELE, intensity_panning) + panner = EFAP(ls_azi_woLFE, ls_ele_woLFE, intensity_panning) + G_td = panner.pan(T_DESIGN_11_AZI, T_DESIGN_11_ELE) mtx_hoa_dec = (G_td.T @ Y_td.T) / T_DESIGN_11_AZI.size diff --git a/scripts/pyaudio3dtools/rotateISM.py b/scripts/pyaudio3dtools/masarenderer.py similarity index 51% rename from scripts/pyaudio3dtools/rotateISM.py rename to scripts/pyaudio3dtools/masarenderer.py index 4ed88f43ba..4ae7a9da3b 100644 --- a/scripts/pyaudio3dtools/rotateISM.py +++ b/scripts/pyaudio3dtools/masarenderer.py @@ -30,34 +30,83 @@ the United Nations Convention on Contracts on the International Sales of Goods. """ + +import os +import shutil +import subprocess as sp +from tempfile import TemporaryDirectory + import numpy as np -from pyaudio3dtools.quaternions.functions import Quat2RotMat, rotateAziEle +from pyaudio3dtools.audiofile import readfile, writefile +from pyaudio3dtools.spatialaudioformat import Format + + +def render_masa( + in_sig: str, + in_meta: str, + in_spfmt: Format, + out_spfmt: Format, +) -> np.ndarray: + """Python wrapper for masaRenderer binaray + + Parameters + ---------- + in_sig: np.ndarray + Input signal with MASA transport channels + in_meta: str + Input MASA metadata file + in_spfmt: Format + Input spatial audio format + out_spfmt: Format + Output spatial audio format + + Returns + ------- + out_sig: np.ndarray + Rendered signal + fs : int + Sampling frequency (always 48 kHz for masaRenderer) + """ + + if shutil.which("masaRenderer") is None: + raise FileNotFoundError("The masaRenderer binary was not found in path!") + with TemporaryDirectory() as tmp_dir: + MASA_RENDERER_CMD = [ + "masaRenderer", + "", # outputMode -LS51, -LS714 or BINAURAL + "", # input PCM + in_meta[0], + "", # output PCM + ] -def rotateISM( - azi: np.ndarray, - ele: np.ndarray, - trajectory: str = None, -) -> tuple: + cmd = MASA_RENDERER_CMD[:] + if out_spfmt.name.startswith("BINAURAL"): + cmd[1] = "-BINAURAL" + out_nchan = 2 + elif out_spfmt.name == "5_1": + cmd[1] = "-LS51" + out_nchan = 6 + else: + cmd[1] = "-LS714" + out_nchan = 12 - if trajectory is None: - return azi, ele + tmp_in = os.path.join(tmp_dir, "tmp_masa_in.pcm") + tmp_out = os.path.join(tmp_dir, "tmp_masa_out.pcm") - trj_data = np.genfromtxt(trajectory, delimiter=",") - trj_frames = trj_data.shape[0] + cmd[2] = tmp_in + cmd[4] = tmp_out - N_frames = azi.shape[0] - if ele.shape[0] != azi.shape[0]: - raise ValueError("Inconsistent input in azi and ele") + writefile(tmp_in, in_sig, 48000) - azi_rot = np.zeros([N_frames]) - ele_rot = np.zeros([N_frames]) + try: + result = sp.run(cmd, check=True, capture_output=True, text=True) + except sp.CalledProcessError as e: + raise SystemError( + f"Command returned non-zero exit status ({e.returncode}): {' '.join(e.cmd)}\n{e.stderr}\n{e.stdout}" + ) - for i_frame in range(N_frames): - q = trj_data[i_frame % trj_frames, 1:] - azi_rot[i_frame], ele_rot[i_frame] = rotateAziEle( - azi[i_frame], ele[i_frame], Quat2RotMat(q) - ) + out_sig, _ = readfile(tmp_out, out_nchan, 48000) - return azi_rot, ele_rot + return out_sig diff --git a/scripts/pyaudio3dtools/rotateHOA.py b/scripts/pyaudio3dtools/rotation.py similarity index 74% rename from scripts/pyaudio3dtools/rotateHOA.py rename to scripts/pyaudio3dtools/rotation.py index cd11be2e59..0457f6b8e9 100644 --- a/scripts/pyaudio3dtools/rotateHOA.py +++ b/scripts/pyaudio3dtools/rotation.py @@ -32,8 +32,9 @@ import numpy as np +from pyaudio3dtools import EFAP, spatialaudioformat from pyaudio3dtools.constants import * -from pyaudio3dtools.quaternions.functions import Quat2RotMat +from pyaudio3dtools.quaternions.functions import Quat2RotMat, rotateAziEle ######################################################################### # Helper functions used by Ruedenberg, @@ -219,7 +220,7 @@ def rotateHOA(x: np.ndarray, trajectory: str) -> np.ndarray: sig_len = x.shape[0] sig_dim = x.shape[1] - frame_len = (IVAS_FRAME_LEN_MS // 4) * 48000 + frame_len = (IVAS_FRAME_LEN_MS // 4) * 48 N_frames = int(sig_len / frame_len) if sig_dim not in [4, 9, 16]: @@ -227,8 +228,8 @@ def rotateHOA(x: np.ndarray, trajectory: str) -> np.ndarray: y = np.zeros([sig_len, sig_dim]) - a = np.linspace(0, 1.0, frame_len, endpoint=False)[:, np.newaxis] - b = 1.0 - a + fade_in = np.linspace(0, 1.0, frame_len, endpoint=False)[:, np.newaxis] + fade_out = 1.0 - fade_in R = np.eye(sig_dim) R_old = np.eye(sig_dim) @@ -244,8 +245,102 @@ def rotateHOA(x: np.ndarray, trajectory: str) -> np.ndarray: frame_in = x[i1:i2, :] frame_out = y[i1:i2, :] - frame_out[:, :] = (frame_in @ R_old.T) * b + (frame_in @ R.T) * a + frame_out[:, :] = (fade_in * frame_in @ R.T) + (fade_out * frame_in @ R_old.T) R_old[:, :] = R.copy() return y + + +def rotateISM( + azi: np.ndarray, + ele: np.ndarray, + trajectory: str = None, +) -> tuple: + + if trajectory is None: + return azi, ele + + trj_data = np.genfromtxt(trajectory, delimiter=",") + trj_frames = trj_data.shape[0] + + N_frames = azi.shape[0] + if ele.shape[0] != azi.shape[0]: + raise ValueError("Inconsistent input in azi and ele") + + azi_rot = np.zeros([N_frames]) + ele_rot = np.zeros([N_frames]) + + for i_frame in range(N_frames): + q = trj_data[i_frame % trj_frames, 1:] + azi_rot[i_frame], ele_rot[i_frame] = rotateAziEle( + azi[i_frame], ele[i_frame], Quat2RotMat(q) + ) + + return azi_rot, ele_rot + + +def rotateMC(x: np.ndarray, trajectory: str, layout: spatialaudioformat) -> np.ndarray: + """Rotate MC signal by applying a rotation matrix calculated from the current quaternion + in each subframe + + Parameters: + ---------- + x: np.ndarray + input multichannel signal + trajectory: str + path to trajectory file + + Returns: + ---------- + y: np.ndarray + rotated multichannel signal + """ + + # TODO needs optimization, currently slow + trj_data = np.genfromtxt(trajectory, delimiter=",") + trj_frames = trj_data.shape[0] + + sig_len = x.shape[0] + sig_dim = x.shape[1] + frame_len = (IVAS_FRAME_LEN_MS // 4) * 48 + N_frames = int(sig_len / frame_len) + + y = np.zeros([sig_len, sig_dim]) + + # TODO LFE handling here + panner = EFAP.EFAP(layout.ls_azi, layout.ls_ele) + + fade_in = np.linspace(0, 1.0, frame_len, endpoint=False)[:, np.newaxis] + fade_out = 1.0 - fade_in + + R = np.eye(layout.nchannels) + R_old = np.eye(layout.nchannels) + + for i_frame in range(N_frames): + + start = i_frame * frame_len + end = (i_frame + 1) * frame_len + + q = trj_data[i_frame % trj_frames, 1:] + + rotated_pos = np.array( + [ + rotateAziEle(a, e, Quat2RotMat(q)) + for a, e in zip(layout.ls_azi, layout.ls_ele) + ] + ).astype( + np.int16 + ) # TODO tmu for alignment with IVAS + R = panner.pan(rotated_pos[:, 0], rotated_pos[:, 1]) + R[:, layout.lfe_index] = np.zeros([layout.nchannels, 1]) + R[layout.lfe_index, layout.lfe_index] = 1 + + frame_in = x[start:end, :] + frame_out = y[start:end, :] + + frame_out[:, :] = (fade_in * frame_in @ R) + (fade_out * frame_in @ R_old) + + R_old = R.copy() + + return y diff --git a/scripts/pyaudio3dtools/spatialaudioconvert.py b/scripts/pyaudio3dtools/spatialaudioconvert.py index 3d71dc0e6f..259a01159e 100644 --- a/scripts/pyaudio3dtools/spatialaudioconvert.py +++ b/scripts/pyaudio3dtools/spatialaudioconvert.py @@ -32,6 +32,7 @@ import logging import os +import warnings from typing import Optional, Tuple import numpy as np @@ -42,6 +43,7 @@ from pyaudio3dtools import ( audiofile, binauralrenderer, hoadecoder, + masarenderer, spatialaudioformat, spatialmetadata, ) @@ -59,7 +61,6 @@ def spatial_audio_convert( in_fs: Optional[int] = None, in_nchans: Optional[int] = None, in_meta_files: Optional[list] = None, - in_ls_layout_file: Optional[str] = None, out_format: Optional[str] = None, out_fs: Optional[int] = None, out_fc: Optional[int] = None, @@ -68,7 +69,7 @@ def spatial_audio_convert( limit_output: Optional[bool] = False, cut_preamble_s: Optional[int] = None, trajectory: Optional[str] = None, - bin_rend_include_LFE: Optional[bool] = False, + bin_rend_include_LFE: Optional[bool] = True, bin_rend_LFE_gain: Optional[float] = 10 ** (5.5 / 20), binaural_dataset: Optional[str] = "orange53", ) -> Tuple[np.ndarray, int]: @@ -88,8 +89,6 @@ def spatial_audio_convert( input sampling frequency in_nchans: Optional[int] input number of channels (deduced for .wav) - in_ls_layout_file: Optional[str] - input loudspeaker layout file out_format: Optional[str] output spatial audio format @@ -122,76 +121,76 @@ def spatial_audio_convert( Returns ------- - out_spfmt.name: str - output spatial audio format name - out_fs: int + out_sig : np.ndarray + output signal + out_fs : int output sampling frequency """ + + """ get spatial input and audio format configurations """ + if in_format is None: + in_format = spatialaudioformat.Format.detect_format(in_nchans) + logger.info(f" Input spatial audio format detected: {in_format}") + else: + logger.info(f" Input spatial audio format: {in_format}") + in_spfmt = spatialaudioformat.Format(in_format) + + if out_format is None: + out_format = in_format + logger.info( + f" Output spatial audio format not specified, defaulting to pass-through: {out_format}" + ) + out_spfmt = spatialaudioformat.Format(out_format) + + """ read input file """ # Input is either waveform file (.pcm or .wav) or iis metadata (.txt) _, input_ext = os.path.splitext(os.path.basename(in_file)) - """ read input file """ if input_ext == ".pcm": if in_fs is None: - if out_fs is not None: + if out_fs: in_fs = out_fs else: - raise Exception("Input and output fs not defined.") + raise ValueError("Input and output fs not defined.") if in_nchans is None: - if in_format is not None: - in_spfmt = spatialaudioformat.Format( - in_format=in_format, ls_layout_file=in_ls_layout_file - ) + if in_spfmt is not None: in_nchans = in_spfmt.nchannels - elif out_format is not None: - out_spfmt = spatialaudioformat.Format(in_format=out_format) - in_nchans = out_spfmt.nchannels else: - raise Exception( - "Number if input channels not defined and can't be deduced." + raise ValueError( + "Number of input channels not defined and can't be deduced." ) in_sig, in_fs = audiofile.readfile(in_file, fs=in_fs, nchannels=in_nchans) elif input_ext == ".wav": in_sig, in_fs = audiofile.readfile(in_file) - if in_format is not None: - in_spfmt = spatialaudioformat.Format( - in_format=in_format, ls_layout_file=in_ls_layout_file - ) - # Adjust number of channels if case of HOA, zeroed vert channels if planar - if in_spfmt.ambi_order > 0: - in_sig = audioarray.convert(in_sig, out_nchans=in_spfmt.nchannels) + # Adjust number of channels if case of HOA, zeroed vert channels if planar + if in_spfmt.ambi_order > 0: + in_sig = audioarray.convert(in_sig, out_nchans=in_spfmt.nchannels) elif input_ext == ".txt": metadata_obj = spatialmetadata.Metadata(in_file, audio_fs=in_fs) in_sig, in_fs = metadata_obj.get_audio_array() - if in_format != "META": + if in_spfmt.name != "META": logger.info( - f" {in_format} specified with .txt input file: overriding to META format" + f" {in_spfmt.name} specified with .txt input file: overriding to META format" ) in_format = "META" + in_spfmt = spatialaudioformat.Format(in_format) else: raise Exception(f"Not supported file {input_ext}") _, in_nchans = in_sig.shape - """ attempt to detect input format if not specified """ - if in_format is None: - in_format = spatialaudioformat.Format.detect_format(in_nchans) - logger.info(f" Input spatial audio format detected: {in_format}") - else: - logger.info(f" Input spatial audio format: {in_format}") - - """ convert metadata based formats directly to output format """ - if in_format.startswith("META") or in_format.startswith("ISM"): - if out_format is None: + """ convert metadata based formats (ISM / META) directly to output format """ + if in_spfmt.name.startswith("META") or in_spfmt.name.startswith("ISM"): + if out_spfmt.name.startswith("META"): raise Exception("out format must be specified for META (.txt) or ISM input") - if in_format.startswith("ISM"): + if in_spfmt.name.startswith("ISM"): if in_meta_files is None: raise ValueError( - f"Please specify a list of metadata files for {in_format}" + f"Please specify a list of metadata files for {in_spfmt.name}" ) - if len(in_meta_files) != int(in_format[-1]): + if len(in_meta_files) != int(in_spfmt.name[-1]): raise ValueError( - f"Mismatch between number of streams and number of specified metadata files for {in_format}" + f"Mismatch between number of streams and number of specified metadata files for {in_spfmt.name}" ) # initialise metadata object for ISM @@ -199,22 +198,17 @@ def spatial_audio_convert( metadata_obj.init_for_ism(in_file, in_fs, in_meta_files) # TODO alternative paths for binaural rendering for now - if out_format.startswith("BINAURAL_ROOM"): + if out_spfmt.name.startswith("BINAURAL_ROOM"): in_format = "7_1_4" - elif out_format.startswith("BINAURAL"): + elif out_spfmt.name.startswith("BINAURAL"): in_format = "HOA3" else: in_format = out_format - in_spfmt = spatialaudioformat.Format(in_format) - out_spfmt = spatialaudioformat.Format(out_format) else: # set input format to output format # render_meta() handles all conversions - in_spfmt = spatialaudioformat.Format(in_format) - out_spfmt = spatialaudioformat.Format(out_format) - in_format = out_format in_spfmt = out_spfmt @@ -224,12 +218,9 @@ def spatial_audio_convert( dataset=binaural_dataset, fs=in_fs, trajectory=trajectory, - in_ls_layout_file=in_ls_layout_file, include_LFE=bin_rend_include_LFE, LFE_gain=bin_rend_LFE_gain, ) - elif in_format.startswith("MASA"): - raise NotImplementedError(f"Rendering of MASA is not yet supported!") """ cut preamble """ if cut_preamble_s is not None: @@ -238,27 +229,21 @@ def spatial_audio_convert( logger.info(f" Cut preample by {samples_to_cut} samples") in_sig = audioarray.cut(in_sig, (samples_to_cut, -1)) - """ get spatial input and audio format configurations """ - in_spfmt = spatialaudioformat.Format( - in_format=in_format, ls_layout_file=in_ls_layout_file - ) - if out_format is None: - out_format = in_format - out_spfmt = spatialaudioformat.Format(in_format=out_format) - """ zero non-planar input ambisonics channels """ if in_spfmt.ambi_order > 0 and in_spfmt.isplanar: in_sig = spatialaudioformat.Format.zero_vert_hoa_channels(in_sig) """ Spatial audio format conversion """ out_sig = in_sig - if (out_format != in_format) and not ( + if (in_spfmt.name != out_spfmt.name) and not ( in_spfmt.isheadphones and out_spfmt.isheadphones ): logger.info(f" {in_spfmt.name} -> {out_spfmt.name}") - # binaural output - if out_spfmt.name.startswith("BINAURAL"): + # binaural output (except MASA) + if out_spfmt.name.startswith("BINAURAL") and not in_spfmt.name.startswith( + "MASA" + ): out_sig = binauralrenderer.binaural_rendering( in_sig, in_spfmt, @@ -266,7 +251,6 @@ def spatial_audio_convert( dataset=binaural_dataset, fs=in_fs, trajectory=trajectory, - in_ls_layout_file=in_ls_layout_file, include_LFE=bin_rend_include_LFE, LFE_gain=bin_rend_LFE_gain, ) @@ -279,14 +263,9 @@ def spatial_audio_convert( elif in_spfmt.isloudspeaker: out_sig = convert_mc(in_sig, in_spfmt, out_spfmt) - # ISM conversion - elif in_spfmt.name.startswith("ISM"): - out_sig = convert_ism(in_sig, in_fs, in_spfmt, out_spfmt) - # MASA conversion elif in_spfmt.name.startswith("MASA"): - raise AssertionError(f"Shouldn't execute!") # TODO remove - out_sig = convert_masa(in_sig, in_spfmt, out_spfmt) + out_sig = convert_masa(in_sig, in_fs, in_meta_files, in_spfmt, out_spfmt) else: raise NotImplementedError( f"{in_spfmt.name} -> {out_spfmt.name}: format conversion not implemented" @@ -358,13 +337,25 @@ def convert_mc( try: MC2LS = IVAS_MC_CONVERSION[in_spfmt.name][out_spfmt.name] except KeyError: - panner = EFAP.EFAP(in_spfmt.ls_azi, in_spfmt.ls_ele) - MC2LS = np.vstack( - [panner.pan(a, e) for a, e in zip(out_spfmt.ls_azi, out_spfmt.ls_ele)] - ).T + ls_azi_woLFE = np.delete(out_spfmt.ls_azi, out_spfmt.lfe_index).astype( + float + ) + ls_ele_woLFE = np.delete(out_spfmt.ls_ele, out_spfmt.lfe_index).astype( + float + ) + + panner = EFAP.EFAP(ls_azi_woLFE, ls_ele_woLFE) + MC2LS = np.vstack( + [ + panner.pan(a, e).T + for i, (a, e) in enumerate(zip(in_spfmt.ls_azi, in_spfmt.ls_ele)) + if i not in in_spfmt.lfe_index + ] + ) # pass-through for LFE - MC2LS[in_spfmt.lfe_index, :] = 0 + MC2LS = np.insert(MC2LS, in_spfmt.lfe_index, 0, axis=0) + MC2LS = np.insert(MC2LS, out_spfmt.lfe_index, 0, axis=1) MC2LS[in_spfmt.lfe_index, out_spfmt.lfe_index] = 1 return in_sig @ MC2LS @@ -373,7 +364,8 @@ def convert_mc( # SH response for loudspeaker positions MC2HOA = np.hstack( [ - hoadecoder.getRSH([a], [e], out_spfmt.ambi_order) + # TODO getRSH in IVAS casts to int16_t , decide on final behaviour for scripts + hoadecoder.getRSH([int(a)], [int(e)], out_spfmt.ambi_order) for a, e in zip(in_spfmt.ls_azi, in_spfmt.ls_ele) ] ).T @@ -434,7 +426,10 @@ def convert_ism( gains = gains[:, np.newaxis] # ISM -> HOA elif out_spfmt.ambi_order > 0: - gains = hoadecoder.getRSH([pos[0]], [pos[1]], out_spfmt.ambi_order) + # TODO getRSH in IVAS casts to int16_t , decide on final behaviour for scripts + gains = hoadecoder.getRSH( + [int(pos[0])], [int(pos[1])], out_spfmt.ambi_order + ) else: raise NotImplementedError( f"{in_spfmt.name} -> {out_spfmt.name}: format conversion not implemented" @@ -443,9 +438,9 @@ def convert_ism( if gains_old is None: gains_old = gains.copy() - out_frame[:] = (in_frame @ gains.T) * fade_in + ( - in_frame @ gains_old.T - ) * fade_out + out_frame[:] = (fade_in * in_frame @ gains.T) + ( + fade_out * in_frame @ gains_old.T + ) gains_old = gains.copy() @@ -454,28 +449,48 @@ def convert_ism( def convert_masa( in_sig: np.ndarray, + in_fs: int, + in_meta: str, in_spfmt: spatialaudioformat.Format, out_spfmt: spatialaudioformat.Format, ) -> np.ndarray: """Convert a MASA signal to the requested output format""" + + if in_fs != 48000: + raise ValueError(f"{in_spfmt.name} rendering only support for 48kHz!") + + tmp_spfmt = out_spfmt + # MASA -> LS if out_spfmt.isloudspeaker: - # TODO - raise NotImplementedError( - f"{in_spfmt.name} -> {out_spfmt.name}: format conversion not implemented" - ) + if not (out_spfmt.name == "5_1" or out_spfmt.name == "7_1_4"): + tmp_spfmt = spatialaudioformat.Format("7_1_4") + warnings.warn( + f"{out_spfmt.name} not natively supported by masaRenderer, using {tmp_spfmt.name} as intermediate format" + ) # MASA -> HOA elif out_spfmt.ambi_order > 0: - # TODO - raise NotImplementedError( - f"{in_spfmt.name} -> {out_spfmt.name}: format conversion not implemented" + tmp_spfmt = spatialaudioformat.Format("7_1_4") + warnings.warn( + f"{out_spfmt.name} not natively supported by masaRenderer, using {tmp_spfmt.name} as intermediate format" + ) + elif out_spfmt.name == "BINAURAL": + warnings.warn( + f"Using masaRenderer for rendering; any binaural_dataset setting will be ignored!" ) else: raise NotImplementedError( f"{in_spfmt.name} -> {out_spfmt.name}: format conversion not implemented" ) - return out_sig + out_sig = masarenderer.render_masa(in_sig, in_meta, in_spfmt, tmp_spfmt) + + # conversion done + if tmp_spfmt.name == out_spfmt.name: + return out_sig + # only rendered an intermediate format, more conversion needed + else: + return convert_mc(out_sig, tmp_spfmt, out_spfmt) def render_meta( @@ -484,7 +499,6 @@ def render_meta( dataset: str, fs: int, trajectory: str, - in_ls_layout_file: str, include_LFE: bool = False, LFE_gain: float = 10 ** (5.5 / 20), ) -> np.ndarray: @@ -499,6 +513,9 @@ def render_meta( start = object["track_index"] stop = start + object["nb_tracks"] obj_sig = metadata_obj.audio_array[:, start:stop] + # apply gain + if hasattr(object, "gain"): + obj_sig *= object["gain"] if dest_fmt.name.startswith("BINAURAL"): if object["input_type"] == "ism": @@ -520,7 +537,6 @@ def render_meta( trajectory=trajectory, include_LFE=include_LFE, LFE_gain=LFE_gain, - in_ls_layout_file=in_ls_layout_file, in_pos=positions, ) else: @@ -530,10 +546,10 @@ def render_meta( obj_sig, fs, object["positions"], src_format, dest_fmt ) elif object["input_type"] == "sba": - src_format = spatialaudioformat.Format(f"SBA{object['order']}") + src_format = object["format"] out_sig += convert_sba(obj_sig, src_format, dest_fmt) elif object["input_type"] == "mc": - src_format = spatialaudioformat.Format(f"CICP{object['cicp_index']}") + src_format = object["format"] out_sig += convert_mc(obj_sig, src_format, dest_fmt) return out_sig diff --git a/scripts/pyaudio3dtools/spatialaudioformat.py b/scripts/pyaudio3dtools/spatialaudioformat.py index 83eb4b6802..01721f4329 100644 --- a/scripts/pyaudio3dtools/spatialaudioformat.py +++ b/scripts/pyaudio3dtools/spatialaudioformat.py @@ -30,6 +30,8 @@ the United Nations Convention on Contracts on the International Sales of Goods. """ +import os + import numpy as np _format_configs = { @@ -363,28 +365,18 @@ _vert_hoa_channels = np.array([2, 5, 6, 7, 10, 11, 12, 13, 14]) class Format: - def __init__(self, in_format: str = "FOA", ls_layout_file: str = None): + def __init__(self, in_format: str = "FOA"): self.name = None + self.altname = None self.ambi_order = -1 self.nchannels = None self.isloudspeaker = False + self.isheadphones = False self.lfe_index = [] - for config_name, config_dict in _format_configs.items(): - if ( - in_format.upper() == config_name - or in_format.upper() == config_dict["altname"].upper() - ): - for k, v in _format_configs[config_name].items(): - setattr(self, k, v) - - if not self.name: - raise SystemExit( - "Spatial audio format not supported. If 'EXT' is used, please change to ISM or MASA. Ensure it is same as 'in_format'" - ) - - if self.name == "CUSTOM_LS" and ls_layout_file is not None: - with open(ls_layout_file, "r") as f_ls: + # if it is a path, then treat as custom layout + if not isinstance(in_format, str) or in_format[-4:].lower() == ".txt": + with open(in_format, "r") as f_ls: self.ls_azi = [ float(x.strip()) for x in f_ls.readline().strip().split(",") ] @@ -402,6 +394,27 @@ class Format: [self.ls_azi.insert(i, 0.0) for i in self.lfe_index] [self.ls_ele.insert(i, 0.0) for i in self.lfe_index] + self.name = os.path.basename(in_format).replace(".txt", "") + self.altname = "CUSTOM_LS" + self.config_file = str(in_format) + self.isloudspeaker = True + self.nchannels = len(self.ls_azi) + self.isplanar = np.all([e == 0.0 for e in self.ls_ele]) + # search in predefined dictionary + else: + for config_name, config_dict in _format_configs.items(): + if ( + in_format.upper() == config_name + or in_format.upper() == config_dict["altname"].upper() + ): + for k, v in _format_configs[config_name].items(): + setattr(self, k, v) + + if not self.name: + raise SystemExit( + f"Spatial audio format '{in_format}' not supported. If 'EXT' is used, please change to ISM or MASA. Ensure it is same as 'in_format'" + ) + def get_nchannels(self): return self.nchannels diff --git a/scripts/pyaudio3dtools/spatialmetadata.py b/scripts/pyaudio3dtools/spatialmetadata.py index 829bd298bc..4bbb4b95fe 100644 --- a/scripts/pyaudio3dtools/spatialmetadata.py +++ b/scripts/pyaudio3dtools/spatialmetadata.py @@ -294,6 +294,7 @@ def read_ism_input(file_handle: TextIO, dirname: str) -> dict: ism["track_index"] = int(file_handle.readline()) - 1 ism["nb_tracks"] = 1 ism["positions"] = [] + ism["gain"] = 1 line = file_handle.readline() try: @@ -307,6 +308,7 @@ def read_ism_input(file_handle: TextIO, dirname: str) -> dict: pos["azimuth"] = int(azimuth) pos["elevation"] = int(elevation) ism["positions"].append(pos) + ism["gain"] = read_gain_value(file_handle) except: meta_csv = os.path.join(dirname, line.strip()) pos_idx = 0 @@ -380,8 +382,10 @@ def write_ism_input( def read_sba_input(file_handle: TextIO) -> dict: sba = {"input_type": "sba"} sba["track_index"] = int(file_handle.readline()) - 1 - sba["order"] = int(file_handle.readline()) + sba["format"] = spatialaudioformat.Format(f"SBA{int(file_handle.readline())}") + sba["order"] = sba["format"].ambi_order sba["nb_tracks"] = (sba["order"] + 1) ** 2 + sba["gain"] = read_gain_value(file_handle) return sba @@ -396,10 +400,9 @@ def write_sba_input(file_handle: TextIO, sba_dict: dict) -> None: def read_mc_input(file_handle: TextIO) -> dict: mc = {"input_type": "mc"} mc["track_index"] = int(file_handle.readline()) - 1 - mc["cicp_index"] = int( - file_handle.readline() - ) # TODO try to support custom LS files? - mc["nb_tracks"] = spatialaudioformat.Format(f"CICP{mc['cicp_index']}").nchannels + mc["format"] = spatialaudioformat.Format(file_handle.readline().strip()) + mc["nb_tracks"] = mc["format"].nchannels + mc["gain"] = read_gain_value(file_handle) return mc @@ -407,9 +410,19 @@ def write_mc_input(file_handle: TextIO, mc_dict: dict) -> None: file_handle.write("MC\n") track_index = mc_dict["track_index"] file_handle.write(f"{str(track_index + 1)}\n") - order = mc_dict["order"] - file_handle.write(f"{str(order)}\n") + name = mc_dict["format"].name + file_handle.write(f"{name}\n") + +def read_gain_value(file_handle: TextIO) -> float: + original_pos = file_handle.tell() + gain = file_handle.readline().lower() + if gain.startswith("gain_db"): + gain = float(gain.replace("gain_db", "")) + return 10 ** (gain / 20) + else: + file_handle.seek(original_pos) + return 1 ################################################## # Helper functions for ISM IVAS metadata diff --git a/scripts/pyivastest/IvasModeRunner.py b/scripts/pyivastest/IvasModeRunner.py old mode 100755 new mode 100644 diff --git a/scripts/sector_filters.bin b/scripts/sector_filters.bin new file mode 100644 index 0000000000..88adf401ba --- /dev/null +++ b/scripts/sector_filters.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c4ff3f7d925b868aa98e366318c1bb2530ad9738ff53a187dafa5dcebcf3ec68 +size 288 diff --git a/scripts/td_object_renderer/object_renderer_standalone/Makefile b/scripts/td_object_renderer/object_renderer_standalone/Makefile index 1f7571b867..c8a43fc6f1 100644 --- a/scripts/td_object_renderer/object_renderer_standalone/Makefile +++ b/scripts/td_object_renderer/object_renderer_standalone/Makefile @@ -5,12 +5,13 @@ SRC_LIBCOM = ../../../lib_com SRC_LIBDEBUG = ../../../lib_debug SRC_LIBDEC = ../../../lib_dec SRC_LIBENC = ../../../lib_enc +SRC_LIBREND = ../../../lib_rend SRC_LIBUTIL = ../../../lib_util SRC_APP = ./object_renderer_standalone BUILD = build OBJDIR = obj -SRC_DIRS = $(sort -u $(SRC_LIBCOM) $(SRC_LIBDEBUG) $(SRC_LIBDEC) $(SRC_LIBENC) $(SRC_LIBUTIL) $(SRC_APP)) +SRC_DIRS = $(sort -u $(SRC_LIBCOM) $(SRC_LIBDEBUG) $(SRC_LIBDEC) $(SRC_LIBENC) $(SRC_LIBREND) $(SRC_LIBUTIL) $(SRC_APP)) # Name of CLI binaries CLI_REN ?= renderer_standalone @@ -18,6 +19,7 @@ LIB_LIBCOM ?= libivascom.a LIB_LIBDEBUG ?= libivasdebug.a LIB_LIBDEC ?= libivasdec.a LIB_LIBENC ?= libivasenc.a +LIB_LIBREND ?= libivasrend.a LIB_LIBUTIL ?= libivasutil.a # Default tool settings @@ -117,12 +119,14 @@ SRCS_LIBCOM = $(foreach DIR,$(SRC_LIBCOM),$(patsubst $(DIR)/%,%,$(wildcard $(D SRCS_LIBDEBUG = $(foreach DIR,$(SRC_LIBDEBUG),$(patsubst $(DIR)/%,%,$(wildcard $(DIR)/*.c))) SRCS_LIBDEC = $(foreach DIR,$(SRC_LIBDEC),$(patsubst $(DIR)/%,%,$(wildcard $(DIR)/*.c))) 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))) 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_LIBUTIL = $(addprefix $(OBJDIR)/,$(SRCS_LIBUTIL:.c=.o)) OBJS_REN = $(OBJDIR)/renderer_standalone.o @@ -145,19 +149,22 @@ $(LIB_LIBCOM): $(OBJS_LIBCOM) $(LIB_LIBDEBUG): $(OBJS_LIBDEBUG) $(QUIET_AR)$(AR) rcs $@ $^ -$(LIB_LIBDEC): $(OBJS_LIBDEC) +$(LIB_LIBDEC): $(OBJS_LIBDEC) $(OBJS_LIBREND) $(QUIET_AR)$(AR) rcs $@ $^ $(LIB_LIBENC): $(OBJS_LIBENC) $(QUIET_AR)$(AR) rcs $@ $^ +$(LIB_LIBREND): $(OBJS_LIBREND) + $(QUIET_AR)$(AR) rcs $@ $^ + $(LIB_LIBUTIL): $(OBJS_LIBUTIL) $(QUIET_AR)$(AR) rcs $@ $^ $(CLI_REN): $(LIB_LIBENC) $(LIB_LIBDEC) $(LIB_LIBDEBUG) $(LIB_LIBCOM) $(LIB_LIBUTIL) $(OBJS_REN) $(QUIET_LINK)$(CC) $(LDFLAGS) $(OBJS_REN) -L. -livasdebug -livasutil -livasenc -livasdec -livascom $(LDLIBS) -o $(CLI_REN) -libs: $(LIB_LIBENC) $(LIB_LIBDEBUG) $(LIB_LIBCOM) $(LIB_LIBDEC) $(LIB_LIBUTIL) +libs: $(LIB_LIBENC) $(LIB_LIBDEBUG) $(LIB_LIBCOM) $(LIB_LIBDEC) $(LIB_LIBREND) $(LIB_LIBUTIL) clean: $(QUIET)$(RM) $(OBJS_LIBENC) $(OBJS_LIBDEC) $(OBJS_REN) $(DEPS) @@ -165,7 +172,7 @@ clean: $(QUIET)test ! -d $(OBJDIR) || rm -rf $(OBJDIR) clean_all: clean - $(QUIET)$(RM) $(CLI_REN) $(LIB_LIBENC) $(LIB_LIBDEBUG) $(LIB_LIBCOM) $(LIB_LIBDEC) $(LIB_LIBUTIL) + $(QUIET)$(RM) $(CLI_REN) $(LIB_LIBENC) $(LIB_LIBDEBUG) $(LIB_LIBCOM) $(LIB_LIBDEC) $(LIB_LIBUTIL) $(LIB_LIBREND) $(OBJDIR)/%.o : %.c | $(OBJDIR) $(QUIET_CC)$(CC) $(CFLAGS) -c -MD -o $@ $< diff --git a/scripts/td_object_renderer/object_renderer_standalone/object_renderer_standalone.sln b/scripts/td_object_renderer/object_renderer_standalone/object_renderer_standalone.sln index 18c18b0ace..72b9350406 100644 --- a/scripts/td_object_renderer/object_renderer_standalone/object_renderer_standalone.sln +++ b/scripts/td_object_renderer/object_renderer_standalone/object_renderer_standalone.sln @@ -3,16 +3,18 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 VisualStudioVersion = 15.0.28307.136 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "object_renderer_standalone", "object_renderer_standalone.vcxproj", "{75AE3898-3FDF-4AE2-86A1-838D0E78545E}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lib_util", "..\..\..\Workspace_msvc\lib_util.vcxproj", "{2FA8F384-0775-F3B7-F8C3-85209222FC70}" -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lib_dec", "..\..\..\Workspace_msvc\lib_dec.vcxproj", "{E822DDAF-0F5F-4CD0-A694-38AE69DE74D3}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lib_com", "..\..\..\Workspace_msvc\lib_com.vcxproj", "{39EC200D-7795-4FF8-B214-B24EDA5526AE}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lib_rend", "..\..\..\Workspace_msvc\lib_rend.vcxproj", "{718DE063-A18B-BB72-9150-62B892E6FFA6}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lib_util", "..\..\..\Workspace_msvc\lib_util.vcxproj", "{2FA8F384-0775-F3B7-F8C3-85209222FC70}" +EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "lib_debug", "..\..\..\Workspace_msvc\lib_debug.vcxproj", "{54509728-928B-44D9-A118-A6F92F08B34F}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "object_renderer_standalone", "object_renderer_standalone.vcxproj", "{75AE3898-3FDF-4AE2-86A1-838D0E78545E}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 @@ -50,6 +52,12 @@ Global {54509728-928B-44D9-A118-A6F92F08B34F}.Release|Win32.Build.0 = Release|Win32 {54509728-928B-44D9-A118-A6F92F08B34F}.Unittests|Win32.ActiveCfg = Unittests|Win32 {54509728-928B-44D9-A118-A6F92F08B34F}.Unittests|Win32.Build.0 = Unittests|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}.Release|Win32.ActiveCfg = Release|Win32 + {718DE063-A18B-BB72-9150-62B892E6FFA6}.Release|Win32.Build.0 = Release|Win32 + {718DE063-A18B-BB72-9150-62B892E6FFA6}.Unittests|Win32.ActiveCfg = Unittests|Win32 + {718DE063-A18B-BB72-9150-62B892E6FFA6}.Unittests|Win32.Build.0 = Unittests|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/scripts/pyaudio3dtools/rotateMC.py b/scripts/tests/__init__.py similarity index 50% rename from scripts/pyaudio3dtools/rotateMC.py rename to scripts/tests/__init__.py index 65b47b9b18..c2c14754b4 100644 --- a/scripts/pyaudio3dtools/rotateMC.py +++ b/scripts/tests/__init__.py @@ -25,72 +25,3 @@ 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. """ - -import numpy as np - -from pyaudio3dtools import EFAP, spatialaudioformat -from pyaudio3dtools.constants import * -from pyaudio3dtools.quaternions.functions import Quat2RotMat, rotateAziEle - - -def rotateMC(x: np.ndarray, trajectory: str, layout: spatialaudioformat) -> np.ndarray: - """Rotate MC signal by applying a rotation matrix calculated from the current quaternion - in each subframe - - Parameters: - ---------- - x: np.ndarray - input multichannel signal - trajectory: str - path to trajectory file - - Returns: - ---------- - y: np.ndarray - rotated multichannel signal - """ - - # TODO needs optimization, currently slow - trj_data = np.genfromtxt(trajectory, delimiter=",") - trj_frames = trj_data.shape[0] - - sig_len = x.shape[0] - sig_dim = x.shape[1] - frame_len = (IVAS_FRAME_LEN_MS // 4) * 48000 - N_frames = int(sig_len / frame_len) - - y = np.zeros([sig_len, sig_dim]) - - panner = EFAP.EFAP(layout.ls_azi, layout.ls_ele) - - a = np.linspace(0, 1.0, frame_len, endpoint=False)[:, np.newaxis] - b = 1.0 - a - - R = np.eye(layout.nchannels) - R_old = np.eye(layout.nchannels) - - for i_frame in range(N_frames): - - start = i_frame * frame_len - end = (i_frame + 1) * frame_len - - q = trj_data[i_frame % trj_frames, 1:] - - rotated_pos = np.array( - [ - rotateAziEle(a, e, Quat2RotMat(q)) - for a, e in zip(layout.ls_azi, layout.ls_ele) - ] - ) - R = panner.pan(rotated_pos[:, 0], rotated_pos[:, 1]) - R[:, layout.lfe_index] = np.zeros([layout.nchannels, 1]) - R[layout.lfe_index, layout.lfe_index] = 1 - - frame_in = x[start:end, :] - frame_out = y[start:end, :] - - frame_out[:, :] = (frame_in @ R_old) * b + (frame_in @ R) * a - - R_old = R.copy() - - return y diff --git a/scripts/tests/compare_audio.py b/scripts/tests/compare_audio.py new file mode 100644 index 0000000000..56f35735fc --- /dev/null +++ b/scripts/tests/compare_audio.py @@ -0,0 +1,69 @@ +import warnings +from typing import Tuple + +import numpy as np +from pyaudio3dtools.audioarray import getdelay + + +def compare_audio_arrays( + left: np.ndarray, left_fs: int, right: np.ndarray, right_fs: int +) -> Tuple[float, float]: + + if left_fs != right_fs: + return ValueError(f"Differing samplerates: {left_fs} vs {right_fs}!") + + if left.shape[1] != right.shape[1]: + cmp_ch = min(left.shape[1], right.shape[1]) + warnings.warn( + f"Differing number of channels: {left.shape[1]} vs {right.shape[1]}! Comparing first {cmp_ch} channel(s)", + category=RuntimeWarning, + ) + left = left[:, :cmp_ch] + right = right[:, cmp_ch] + + if left.shape[0] != right.shape[0]: + cmp_smp = min(left.shape[0], right.shape[0]) + warnings.warn( + f"Warning - different durations: {left.shape[0] / left_fs:.2f}s vs {right.shape[0] / right_fs:.2f}s! Comparing first {cmp_smp / left_fs : .2f} sample(s)", + category=RuntimeWarning, + ) + left = left[:cmp_smp, :] + right = right[:cmp_smp, :] + + if not np.array_equal(left, right): + delay = getdelay(left, right) + delay_abs = np.abs(delay) + # getdelay can return large values if signals are quite different + # limit any delay compensation to 20 ms + if delay != 0 and (delay_abs < left_fs / 50): + warnings.warn( + f"File B is delayed by {delay} samples ({delay*1000 / left_fs : .2f}ms)!", + category=RuntimeWarning, + ) + + # shift array + left = np.roll(left, delay, axis=0) + + # zero shifted out samples + if delay < 0: + left[-np.abs(delay) :, :] = 0 + elif delay > 0: + left[: np.abs(delay), :] = 0 + """ + http://www-mmsp.ece.mcgill.ca/Documents/Software/Packages/AFsp/AFsp/CompAudio.html + """ + num = np.sum(left * right) + den = np.sqrt(np.sum(left**2) * np.sum(right**2)) + if den > 0: + r = num / den + else: + r = np.inf + snr = 10 * np.log10(1 / (1 - (r**2))) + gain_b = num / np.sum(right**2) + max_diff = np.abs(np.max(left - right)) + else: + snr = np.inf + gain_b = 1 + max_diff = 0 + + return snr, gain_b, max_diff diff --git a/scripts/tests/constants.py b/scripts/tests/constants.py new file mode 100644 index 0000000000..07a5cbc5a9 --- /dev/null +++ b/scripts/tests/constants.py @@ -0,0 +1,189 @@ +#!/usr/bin/env python3 + +""" + (C) 2022 Baseline Development Group 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 Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The Baseline Development Group 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 Corporation, Qualcomm Technologies, Inc., and VoiceAge Corporation retain full ownership + rights in their respective contributions in the software. No license of any kind, including but not + limited to patent license, of any foregoing parties is hereby granted by implication, estoppel or + otherwise. + + 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/or 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. +""" + +from pathlib import PurePath + +""" Set up paths """ +TESTS_DIR = PurePath(__file__).parent +TEST_VECTOR_DIR = TESTS_DIR.joinpath("data") + +OUTPUT_PATH_REF = TESTS_DIR.joinpath("ref") +OUTPUT_PATH_CUT = TESTS_DIR.joinpath("cut") + +CUSTOM_LAYOUT_DIR = TEST_VECTOR_DIR.parent.parent.joinpath("ls_layouts") +HR_TRAJECTORY_DIR = TEST_VECTOR_DIR.parent.parent.joinpath("trajectories") + +""" Renderer commandline template """ +RENDERER_CMD = [ + str(TESTS_DIR.parent.parent.joinpath("IVAS_rend")), + "-i", + "", # 2 -> input file + "-if", + "", # 4 -> input format + "-o", + "/dev/null", # 6 -> output file + "-of", + "", # 8 -> output format + "-fs", + "48", # 10 -> input fs + "-q", + # "-ndl", +] + +""" Format to file mappings """ +NCHAN_TO_FILE = { + 1: TEST_VECTOR_DIR.joinpath("spectral_test_1ch_48kHz.wav"), + 2: TEST_VECTOR_DIR.joinpath("spectral_test_2ch_48kHz.wav"), + 3: TEST_VECTOR_DIR.joinpath("spectral_test_3ch_48kHz.wav"), + 4: TEST_VECTOR_DIR.joinpath("spectral_test_4ch_48kHz.wav"), + 5: TEST_VECTOR_DIR.joinpath("spectral_test_5ch_48kHz.wav"), + 6: TEST_VECTOR_DIR.joinpath("spectral_test_6ch_48kHz.wav"), + 8: TEST_VECTOR_DIR.joinpath("spectral_test_8ch_48kHz.wav"), + 9: TEST_VECTOR_DIR.joinpath("spectral_test_9ch_48kHz.wav"), + 10: TEST_VECTOR_DIR.joinpath("spectral_test_10ch_48kHz.wav"), + 11: TEST_VECTOR_DIR.joinpath("spectral_test_11ch_48kHz.wav"), + 12: TEST_VECTOR_DIR.joinpath("spectral_test_12ch_48kHz.wav"), + 15: TEST_VECTOR_DIR.joinpath("spectral_test_15ch_48kHz.wav"), + 16: TEST_VECTOR_DIR.joinpath("spectral_test_16ch_48kHz.wav"), +} + +FORMAT_TO_FILE = { + "MONO": NCHAN_TO_FILE[1], + "STEREO": NCHAN_TO_FILE[2], + "5_1": NCHAN_TO_FILE[6], + "7_1": NCHAN_TO_FILE[8], + "5_1_2": NCHAN_TO_FILE[8], + "5_1_4": NCHAN_TO_FILE[10], + "7_1_4": NCHAN_TO_FILE[12], + "FOA": NCHAN_TO_FILE[4], + "HOA2": NCHAN_TO_FILE[9], + "HOA3": NCHAN_TO_FILE[16], + "ISM1": NCHAN_TO_FILE[1], + "ISM2": NCHAN_TO_FILE[2], + "ISM3": NCHAN_TO_FILE[3], + "ISM4": NCHAN_TO_FILE[4], + # "ISM1": TEST_VECTOR_DIR.joinpath("spectral_test_ism1.txt"), + # "ISM2": TEST_VECTOR_DIR.joinpath("spectral_test_ism2.txt"), + # "ISM3": TEST_VECTOR_DIR.joinpath("spectral_test_ism3.txt"), + # "ISM4": TEST_VECTOR_DIR.joinpath("spectral_test_ism4.txt"), + "MASA1": NCHAN_TO_FILE[1], + "MASA2": NCHAN_TO_FILE[2], + # "MASA1": TEST_VECTOR_DIR.joinpath("stv_IVASMASA_1dir1TC.pcm"), + # "MASA2": TEST_VECTOR_DIR.joinpath("stv_IVASMASA_2dir2TC.pcm"), + "META": TEST_VECTOR_DIR.joinpath("mixed_scene.txt"), + # Custom loudspeaker inputs (WIP) + "16ch_8+4+4": NCHAN_TO_FILE[16], + "4d0": NCHAN_TO_FILE[4], + "4d4": NCHAN_TO_FILE[8], + "cicp1": NCHAN_TO_FILE[1], + "cicp20": NCHAN_TO_FILE[15], + "cicp2": NCHAN_TO_FILE[2], + "custom1": NCHAN_TO_FILE[11], + "itu_4+5+1": NCHAN_TO_FILE[11], + "t_design_4": NCHAN_TO_FILE[12], +} + +FORMAT_TO_METADATA_FILES = { + "ISM1": [str(TEST_VECTOR_DIR.joinpath("stvISM1.csv"))], + "ISM2": [ + str(TEST_VECTOR_DIR.joinpath("stvISM1.csv")), + str(TEST_VECTOR_DIR.joinpath("stvISM2.csv")), + ], + "ISM3": [ + str(TEST_VECTOR_DIR.joinpath("stvISM1.csv")), + str(TEST_VECTOR_DIR.joinpath("stvISM2.csv")), + str(TEST_VECTOR_DIR.joinpath("stvISM3.csv")), + ], + "ISM4": [ + str(TEST_VECTOR_DIR.joinpath("stvISM1.csv")), + str(TEST_VECTOR_DIR.joinpath("stvISM2.csv")), + str(TEST_VECTOR_DIR.joinpath("stvISM3.csv")), + str(TEST_VECTOR_DIR.joinpath("stvISM4.csv")), + ], + "MASA1": [str(TEST_VECTOR_DIR.joinpath("stv_IVASMASAQ_1dir1TC.met"))], + "MASA2": [str(TEST_VECTOR_DIR.joinpath("stv_IVASMASAQ_2dir2TC.met"))], +} + +""" Input formats """ +INPUT_FORMATS_AMBI = ["FOA", "HOA2", "HOA3"] +INPUT_FORMATS_MC = ["MONO", "STEREO", "5_1", "5_1_2", "5_1_4", "7_1", "7_1_4"] +INPUT_FORMATS_ISM = ["ISM1", "ISM2", "ISM3", "ISM4"] +INPUT_FORMATS_MASA = ["MASA1", "MASA2"] + +""" Non binaural / parametric output formats """ +OUTPUT_FORMATS = [ + "MONO", + "STEREO", + "5_1", + "5_1_2", + "5_1_4", + "7_1", + "7_1_4", + "FOA", + "HOA2", + "HOA3", +] + +""" Custom loudspeaker input/output """ +CUSTOM_LS_TO_TEST = [ + # "cicp1", + # "cicp2", + "t_design_4", + # "4d0", + "4d4", + "itu_4+5+1", + "custom1", + # "cicp20", + "16ch_8+4+4", +] + +""" Mixed scene ( metadata ) rendering """ +METADATA_SCENES_TO_TEST = ["mixed_scene"] + +""" Binaural rendering """ +INPUT_FORMATS_BINAURAL = OUTPUT_FORMATS[2:] +INPUT_FORMATS_BINAURAL.extend( + [ + "ISM1", + "ISM2", + "ISM3", + "ISM4", + # "MASA1", + # "MASA2", + ] + ) +OUTPUT_FORMATS_BINAURAL = [ + "BINAURAL", + # "BINAURAL_ROOM" # TODO +] +HR_TRAJECTORIES_TO_TEST = [ + # "const000", + # "full_circle_in_15s", + "full_circle_in_15s-Euler", + "rotate_yaw_pitch_roll1", +] diff --git a/scripts/tests/cut/.gitignore b/scripts/tests/cut/.gitignore new file mode 100644 index 0000000000..f935021a8f --- /dev/null +++ b/scripts/tests/cut/.gitignore @@ -0,0 +1 @@ +!.gitignore diff --git a/scripts/prerenderer_configs/IVAS_ISM_metadata_-30_0.csv b/scripts/tests/data/IVAS_ISM_metadata_-30_0.csv similarity index 100% rename from scripts/prerenderer_configs/IVAS_ISM_metadata_-30_0.csv rename to scripts/tests/data/IVAS_ISM_metadata_-30_0.csv diff --git a/scripts/prerenderer_configs/IVAS_ISM_metadata_0_0.csv b/scripts/tests/data/IVAS_ISM_metadata_0_0.csv similarity index 100% rename from scripts/prerenderer_configs/IVAS_ISM_metadata_0_0.csv rename to scripts/tests/data/IVAS_ISM_metadata_0_0.csv diff --git a/scripts/prerenderer_configs/IVAS_ISM_metadata_30_0.csv b/scripts/tests/data/IVAS_ISM_metadata_30_0.csv similarity index 100% rename from scripts/prerenderer_configs/IVAS_ISM_metadata_30_0.csv rename to scripts/tests/data/IVAS_ISM_metadata_30_0.csv diff --git a/scripts/prerenderer_configs/IVAS_ISM_metadata_circle.csv b/scripts/tests/data/IVAS_ISM_metadata_circle.csv similarity index 100% rename from scripts/prerenderer_configs/IVAS_ISM_metadata_circle.csv rename to scripts/tests/data/IVAS_ISM_metadata_circle.csv diff --git a/scripts/prerenderer_configs/ism1_ivas_mtdt_config.txt b/scripts/tests/data/ism1_ivas_mtdt_config.txt similarity index 100% rename from scripts/prerenderer_configs/ism1_ivas_mtdt_config.txt rename to scripts/tests/data/ism1_ivas_mtdt_config.txt diff --git a/scripts/prerenderer_configs/ism1_shorthand_config.txt b/scripts/tests/data/ism1_shorthand_config.txt similarity index 100% rename from scripts/prerenderer_configs/ism1_shorthand_config.txt rename to scripts/tests/data/ism1_shorthand_config.txt diff --git a/scripts/prerenderer_configs/ism2_ivas_mtdt_config.txt b/scripts/tests/data/ism2_ivas_mtdt_config.txt similarity index 100% rename from scripts/prerenderer_configs/ism2_ivas_mtdt_config.txt rename to scripts/tests/data/ism2_ivas_mtdt_config.txt diff --git a/scripts/prerenderer_configs/ism2_shorthand_config.txt b/scripts/tests/data/ism2_shorthand_config.txt similarity index 100% rename from scripts/prerenderer_configs/ism2_shorthand_config.txt rename to scripts/tests/data/ism2_shorthand_config.txt diff --git a/scripts/prerenderer_configs/ism3_ivas_mtdt_config.txt b/scripts/tests/data/ism3_ivas_mtdt_config.txt similarity index 100% rename from scripts/prerenderer_configs/ism3_ivas_mtdt_config.txt rename to scripts/tests/data/ism3_ivas_mtdt_config.txt diff --git a/scripts/prerenderer_configs/ism3_shorthand_config.txt b/scripts/tests/data/ism3_shorthand_config.txt similarity index 100% rename from scripts/prerenderer_configs/ism3_shorthand_config.txt rename to scripts/tests/data/ism3_shorthand_config.txt diff --git a/scripts/prerenderer_configs/ism4_ivas_mtdt_config.txt b/scripts/tests/data/ism4_ivas_mtdt_config.txt similarity index 100% rename from scripts/prerenderer_configs/ism4_ivas_mtdt_config.txt rename to scripts/tests/data/ism4_ivas_mtdt_config.txt diff --git a/scripts/prerenderer_configs/ism4_shorthand_config.txt b/scripts/tests/data/ism4_shorthand_config.txt similarity index 100% rename from scripts/prerenderer_configs/ism4_shorthand_config.txt rename to scripts/tests/data/ism4_shorthand_config.txt diff --git a/scripts/tests/data/ism_-90a_0e.csv b/scripts/tests/data/ism_-90a_0e.csv new file mode 100644 index 0000000000..766ba1023f --- /dev/null +++ b/scripts/tests/data/ism_-90a_0e.csv @@ -0,0 +1,750 @@ +0,-90,0,1,0,1 +1,-90,0,1,0,1 +2,-90,0,1,0,1 +3,-90,0,1,0,1 +4,-90,0,1,0,1 +5,-90,0,1,0,1 +6,-90,0,1,0,1 +7,-90,0,1,0,1 +8,-90,0,1,0,1 +9,-90,0,1,0,1 +10,-90,0,1,0,1 +11,-90,0,1,0,1 +12,-90,0,1,0,1 +13,-90,0,1,0,1 +14,-90,0,1,0,1 +15,-90,0,1,0,1 +16,-90,0,1,0,1 +17,-90,0,1,0,1 +18,-90,0,1,0,1 +19,-90,0,1,0,1 +20,-90,0,1,0,1 +21,-90,0,1,0,1 +22,-90,0,1,0,1 +23,-90,0,1,0,1 +24,-90,0,1,0,1 +25,-90,0,1,0,1 +26,-90,0,1,0,1 +27,-90,0,1,0,1 +28,-90,0,1,0,1 +29,-90,0,1,0,1 +30,-90,0,1,0,1 +31,-90,0,1,0,1 +32,-90,0,1,0,1 +33,-90,0,1,0,1 +34,-90,0,1,0,1 +35,-90,0,1,0,1 +36,-90,0,1,0,1 +37,-90,0,1,0,1 +38,-90,0,1,0,1 +39,-90,0,1,0,1 +40,-90,0,1,0,1 +41,-90,0,1,0,1 +42,-90,0,1,0,1 +43,-90,0,1,0,1 +44,-90,0,1,0,1 +45,-90,0,1,0,1 +46,-90,0,1,0,1 +47,-90,0,1,0,1 +48,-90,0,1,0,1 +49,-90,0,1,0,1 +50,-90,0,1,0,1 +51,-90,0,1,0,1 +52,-90,0,1,0,1 +53,-90,0,1,0,1 +54,-90,0,1,0,1 +55,-90,0,1,0,1 +56,-90,0,1,0,1 +57,-90,0,1,0,1 +58,-90,0,1,0,1 +59,-90,0,1,0,1 +60,-90,0,1,0,1 +61,-90,0,1,0,1 +62,-90,0,1,0,1 +63,-90,0,1,0,1 +64,-90,0,1,0,1 +65,-90,0,1,0,1 +66,-90,0,1,0,1 +67,-90,0,1,0,1 +68,-90,0,1,0,1 +69,-90,0,1,0,1 +70,-90,0,1,0,1 +71,-90,0,1,0,1 +72,-90,0,1,0,1 +73,-90,0,1,0,1 +74,-90,0,1,0,1 +75,-90,0,1,0,1 +76,-90,0,1,0,1 +77,-90,0,1,0,1 +78,-90,0,1,0,1 +79,-90,0,1,0,1 +80,-90,0,1,0,1 +81,-90,0,1,0,1 +82,-90,0,1,0,1 +83,-90,0,1,0,1 +84,-90,0,1,0,1 +85,-90,0,1,0,1 +86,-90,0,1,0,1 +87,-90,0,1,0,1 +88,-90,0,1,0,1 +89,-90,0,1,0,1 +90,-90,0,1,0,1 +91,-90,0,1,0,1 +92,-90,0,1,0,1 +93,-90,0,1,0,1 +94,-90,0,1,0,1 +95,-90,0,1,0,1 +96,-90,0,1,0,1 +97,-90,0,1,0,1 +98,-90,0,1,0,1 +99,-90,0,1,0,1 +100,-90,0,1,0,1 +101,-90,0,1,0,1 +102,-90,0,1,0,1 +103,-90,0,1,0,1 +104,-90,0,1,0,1 +105,-90,0,1,0,1 +106,-90,0,1,0,1 +107,-90,0,1,0,1 +108,-90,0,1,0,1 +109,-90,0,1,0,1 +110,-90,0,1,0,1 +111,-90,0,1,0,1 +112,-90,0,1,0,1 +113,-90,0,1,0,1 +114,-90,0,1,0,1 +115,-90,0,1,0,1 +116,-90,0,1,0,1 +117,-90,0,1,0,1 +118,-90,0,1,0,1 +119,-90,0,1,0,1 +120,-90,0,1,0,1 +121,-90,0,1,0,1 +122,-90,0,1,0,1 +123,-90,0,1,0,1 +124,-90,0,1,0,1 +125,-90,0,1,0,1 +126,-90,0,1,0,1 +127,-90,0,1,0,1 +128,-90,0,1,0,1 +129,-90,0,1,0,1 +130,-90,0,1,0,1 +131,-90,0,1,0,1 +132,-90,0,1,0,1 +133,-90,0,1,0,1 +134,-90,0,1,0,1 +135,-90,0,1,0,1 +136,-90,0,1,0,1 +137,-90,0,1,0,1 +138,-90,0,1,0,1 +139,-90,0,1,0,1 +140,-90,0,1,0,1 +141,-90,0,1,0,1 +142,-90,0,1,0,1 +143,-90,0,1,0,1 +144,-90,0,1,0,1 +145,-90,0,1,0,1 +146,-90,0,1,0,1 +147,-90,0,1,0,1 +148,-90,0,1,0,1 +149,-90,0,1,0,1 +150,-90,0,1,0,1 +151,-90,0,1,0,1 +152,-90,0,1,0,1 +153,-90,0,1,0,1 +154,-90,0,1,0,1 +155,-90,0,1,0,1 +156,-90,0,1,0,1 +157,-90,0,1,0,1 +158,-90,0,1,0,1 +159,-90,0,1,0,1 +160,-90,0,1,0,1 +161,-90,0,1,0,1 +162,-90,0,1,0,1 +163,-90,0,1,0,1 +164,-90,0,1,0,1 +165,-90,0,1,0,1 +166,-90,0,1,0,1 +167,-90,0,1,0,1 +168,-90,0,1,0,1 +169,-90,0,1,0,1 +170,-90,0,1,0,1 +171,-90,0,1,0,1 +172,-90,0,1,0,1 +173,-90,0,1,0,1 +174,-90,0,1,0,1 +175,-90,0,1,0,1 +176,-90,0,1,0,1 +177,-90,0,1,0,1 +178,-90,0,1,0,1 +179,-90,0,1,0,1 +180,-90,0,1,0,1 +181,-90,0,1,0,1 +182,-90,0,1,0,1 +183,-90,0,1,0,1 +184,-90,0,1,0,1 +185,-90,0,1,0,1 +186,-90,0,1,0,1 +187,-90,0,1,0,1 +188,-90,0,1,0,1 +189,-90,0,1,0,1 +190,-90,0,1,0,1 +191,-90,0,1,0,1 +192,-90,0,1,0,1 +193,-90,0,1,0,1 +194,-90,0,1,0,1 +195,-90,0,1,0,1 +196,-90,0,1,0,1 +197,-90,0,1,0,1 +198,-90,0,1,0,1 +199,-90,0,1,0,1 +200,-90,0,1,0,1 +201,-90,0,1,0,1 +202,-90,0,1,0,1 +203,-90,0,1,0,1 +204,-90,0,1,0,1 +205,-90,0,1,0,1 +206,-90,0,1,0,1 +207,-90,0,1,0,1 +208,-90,0,1,0,1 +209,-90,0,1,0,1 +210,-90,0,1,0,1 +211,-90,0,1,0,1 +212,-90,0,1,0,1 +213,-90,0,1,0,1 +214,-90,0,1,0,1 +215,-90,0,1,0,1 +216,-90,0,1,0,1 +217,-90,0,1,0,1 +218,-90,0,1,0,1 +219,-90,0,1,0,1 +220,-90,0,1,0,1 +221,-90,0,1,0,1 +222,-90,0,1,0,1 +223,-90,0,1,0,1 +224,-90,0,1,0,1 +225,-90,0,1,0,1 +226,-90,0,1,0,1 +227,-90,0,1,0,1 +228,-90,0,1,0,1 +229,-90,0,1,0,1 +230,-90,0,1,0,1 +231,-90,0,1,0,1 +232,-90,0,1,0,1 +233,-90,0,1,0,1 +234,-90,0,1,0,1 +235,-90,0,1,0,1 +236,-90,0,1,0,1 +237,-90,0,1,0,1 +238,-90,0,1,0,1 +239,-90,0,1,0,1 +240,-90,0,1,0,1 +241,-90,0,1,0,1 +242,-90,0,1,0,1 +243,-90,0,1,0,1 +244,-90,0,1,0,1 +245,-90,0,1,0,1 +246,-90,0,1,0,1 +247,-90,0,1,0,1 +248,-90,0,1,0,1 +249,-90,0,1,0,1 +250,-90,0,1,0,1 +251,-90,0,1,0,1 +252,-90,0,1,0,1 +253,-90,0,1,0,1 +254,-90,0,1,0,1 +255,-90,0,1,0,1 +256,-90,0,1,0,1 +257,-90,0,1,0,1 +258,-90,0,1,0,1 +259,-90,0,1,0,1 +260,-90,0,1,0,1 +261,-90,0,1,0,1 +262,-90,0,1,0,1 +263,-90,0,1,0,1 +264,-90,0,1,0,1 +265,-90,0,1,0,1 +266,-90,0,1,0,1 +267,-90,0,1,0,1 +268,-90,0,1,0,1 +269,-90,0,1,0,1 +270,-90,0,1,0,1 +271,-90,0,1,0,1 +272,-90,0,1,0,1 +273,-90,0,1,0,1 +274,-90,0,1,0,1 +275,-90,0,1,0,1 +276,-90,0,1,0,1 +277,-90,0,1,0,1 +278,-90,0,1,0,1 +279,-90,0,1,0,1 +280,-90,0,1,0,1 +281,-90,0,1,0,1 +282,-90,0,1,0,1 +283,-90,0,1,0,1 +284,-90,0,1,0,1 +285,-90,0,1,0,1 +286,-90,0,1,0,1 +287,-90,0,1,0,1 +288,-90,0,1,0,1 +289,-90,0,1,0,1 +290,-90,0,1,0,1 +291,-90,0,1,0,1 +292,-90,0,1,0,1 +293,-90,0,1,0,1 +294,-90,0,1,0,1 +295,-90,0,1,0,1 +296,-90,0,1,0,1 +297,-90,0,1,0,1 +298,-90,0,1,0,1 +299,-90,0,1,0,1 +300,-90,0,1,0,1 +301,-90,0,1,0,1 +302,-90,0,1,0,1 +303,-90,0,1,0,1 +304,-90,0,1,0,1 +305,-90,0,1,0,1 +306,-90,0,1,0,1 +307,-90,0,1,0,1 +308,-90,0,1,0,1 +309,-90,0,1,0,1 +310,-90,0,1,0,1 +311,-90,0,1,0,1 +312,-90,0,1,0,1 +313,-90,0,1,0,1 +314,-90,0,1,0,1 +315,-90,0,1,0,1 +316,-90,0,1,0,1 +317,-90,0,1,0,1 +318,-90,0,1,0,1 +319,-90,0,1,0,1 +320,-90,0,1,0,1 +321,-90,0,1,0,1 +322,-90,0,1,0,1 +323,-90,0,1,0,1 +324,-90,0,1,0,1 +325,-90,0,1,0,1 +326,-90,0,1,0,1 +327,-90,0,1,0,1 +328,-90,0,1,0,1 +329,-90,0,1,0,1 +330,-90,0,1,0,1 +331,-90,0,1,0,1 +332,-90,0,1,0,1 +333,-90,0,1,0,1 +334,-90,0,1,0,1 +335,-90,0,1,0,1 +336,-90,0,1,0,1 +337,-90,0,1,0,1 +338,-90,0,1,0,1 +339,-90,0,1,0,1 +340,-90,0,1,0,1 +341,-90,0,1,0,1 +342,-90,0,1,0,1 +343,-90,0,1,0,1 +344,-90,0,1,0,1 +345,-90,0,1,0,1 +346,-90,0,1,0,1 +347,-90,0,1,0,1 +348,-90,0,1,0,1 +349,-90,0,1,0,1 +350,-90,0,1,0,1 +351,-90,0,1,0,1 +352,-90,0,1,0,1 +353,-90,0,1,0,1 +354,-90,0,1,0,1 +355,-90,0,1,0,1 +356,-90,0,1,0,1 +357,-90,0,1,0,1 +358,-90,0,1,0,1 +359,-90,0,1,0,1 +360,-90,0,1,0,1 +361,-90,0,1,0,1 +362,-90,0,1,0,1 +363,-90,0,1,0,1 +364,-90,0,1,0,1 +365,-90,0,1,0,1 +366,-90,0,1,0,1 +367,-90,0,1,0,1 +368,-90,0,1,0,1 +369,-90,0,1,0,1 +370,-90,0,1,0,1 +371,-90,0,1,0,1 +372,-90,0,1,0,1 +373,-90,0,1,0,1 +374,-90,0,1,0,1 +375,-90,0,1,0,1 +376,-90,0,1,0,1 +377,-90,0,1,0,1 +378,-90,0,1,0,1 +379,-90,0,1,0,1 +380,-90,0,1,0,1 +381,-90,0,1,0,1 +382,-90,0,1,0,1 +383,-90,0,1,0,1 +384,-90,0,1,0,1 +385,-90,0,1,0,1 +386,-90,0,1,0,1 +387,-90,0,1,0,1 +388,-90,0,1,0,1 +389,-90,0,1,0,1 +390,-90,0,1,0,1 +391,-90,0,1,0,1 +392,-90,0,1,0,1 +393,-90,0,1,0,1 +394,-90,0,1,0,1 +395,-90,0,1,0,1 +396,-90,0,1,0,1 +397,-90,0,1,0,1 +398,-90,0,1,0,1 +399,-90,0,1,0,1 +400,-90,0,1,0,1 +401,-90,0,1,0,1 +402,-90,0,1,0,1 +403,-90,0,1,0,1 +404,-90,0,1,0,1 +405,-90,0,1,0,1 +406,-90,0,1,0,1 +407,-90,0,1,0,1 +408,-90,0,1,0,1 +409,-90,0,1,0,1 +410,-90,0,1,0,1 +411,-90,0,1,0,1 +412,-90,0,1,0,1 +413,-90,0,1,0,1 +414,-90,0,1,0,1 +415,-90,0,1,0,1 +416,-90,0,1,0,1 +417,-90,0,1,0,1 +418,-90,0,1,0,1 +419,-90,0,1,0,1 +420,-90,0,1,0,1 +421,-90,0,1,0,1 +422,-90,0,1,0,1 +423,-90,0,1,0,1 +424,-90,0,1,0,1 +425,-90,0,1,0,1 +426,-90,0,1,0,1 +427,-90,0,1,0,1 +428,-90,0,1,0,1 +429,-90,0,1,0,1 +430,-90,0,1,0,1 +431,-90,0,1,0,1 +432,-90,0,1,0,1 +433,-90,0,1,0,1 +434,-90,0,1,0,1 +435,-90,0,1,0,1 +436,-90,0,1,0,1 +437,-90,0,1,0,1 +438,-90,0,1,0,1 +439,-90,0,1,0,1 +440,-90,0,1,0,1 +441,-90,0,1,0,1 +442,-90,0,1,0,1 +443,-90,0,1,0,1 +444,-90,0,1,0,1 +445,-90,0,1,0,1 +446,-90,0,1,0,1 +447,-90,0,1,0,1 +448,-90,0,1,0,1 +449,-90,0,1,0,1 +450,-90,0,1,0,1 +451,-90,0,1,0,1 +452,-90,0,1,0,1 +453,-90,0,1,0,1 +454,-90,0,1,0,1 +455,-90,0,1,0,1 +456,-90,0,1,0,1 +457,-90,0,1,0,1 +458,-90,0,1,0,1 +459,-90,0,1,0,1 +460,-90,0,1,0,1 +461,-90,0,1,0,1 +462,-90,0,1,0,1 +463,-90,0,1,0,1 +464,-90,0,1,0,1 +465,-90,0,1,0,1 +466,-90,0,1,0,1 +467,-90,0,1,0,1 +468,-90,0,1,0,1 +469,-90,0,1,0,1 +470,-90,0,1,0,1 +471,-90,0,1,0,1 +472,-90,0,1,0,1 +473,-90,0,1,0,1 +474,-90,0,1,0,1 +475,-90,0,1,0,1 +476,-90,0,1,0,1 +477,-90,0,1,0,1 +478,-90,0,1,0,1 +479,-90,0,1,0,1 +480,-90,0,1,0,1 +481,-90,0,1,0,1 +482,-90,0,1,0,1 +483,-90,0,1,0,1 +484,-90,0,1,0,1 +485,-90,0,1,0,1 +486,-90,0,1,0,1 +487,-90,0,1,0,1 +488,-90,0,1,0,1 +489,-90,0,1,0,1 +490,-90,0,1,0,1 +491,-90,0,1,0,1 +492,-90,0,1,0,1 +493,-90,0,1,0,1 +494,-90,0,1,0,1 +495,-90,0,1,0,1 +496,-90,0,1,0,1 +497,-90,0,1,0,1 +498,-90,0,1,0,1 +499,-90,0,1,0,1 +500,-90,0,1,0,1 +501,-90,0,1,0,1 +502,-90,0,1,0,1 +503,-90,0,1,0,1 +504,-90,0,1,0,1 +505,-90,0,1,0,1 +506,-90,0,1,0,1 +507,-90,0,1,0,1 +508,-90,0,1,0,1 +509,-90,0,1,0,1 +510,-90,0,1,0,1 +511,-90,0,1,0,1 +512,-90,0,1,0,1 +513,-90,0,1,0,1 +514,-90,0,1,0,1 +515,-90,0,1,0,1 +516,-90,0,1,0,1 +517,-90,0,1,0,1 +518,-90,0,1,0,1 +519,-90,0,1,0,1 +520,-90,0,1,0,1 +521,-90,0,1,0,1 +522,-90,0,1,0,1 +523,-90,0,1,0,1 +524,-90,0,1,0,1 +525,-90,0,1,0,1 +526,-90,0,1,0,1 +527,-90,0,1,0,1 +528,-90,0,1,0,1 +529,-90,0,1,0,1 +530,-90,0,1,0,1 +531,-90,0,1,0,1 +532,-90,0,1,0,1 +533,-90,0,1,0,1 +534,-90,0,1,0,1 +535,-90,0,1,0,1 +536,-90,0,1,0,1 +537,-90,0,1,0,1 +538,-90,0,1,0,1 +539,-90,0,1,0,1 +540,-90,0,1,0,1 +541,-90,0,1,0,1 +542,-90,0,1,0,1 +543,-90,0,1,0,1 +544,-90,0,1,0,1 +545,-90,0,1,0,1 +546,-90,0,1,0,1 +547,-90,0,1,0,1 +548,-90,0,1,0,1 +549,-90,0,1,0,1 +550,-90,0,1,0,1 +551,-90,0,1,0,1 +552,-90,0,1,0,1 +553,-90,0,1,0,1 +554,-90,0,1,0,1 +555,-90,0,1,0,1 +556,-90,0,1,0,1 +557,-90,0,1,0,1 +558,-90,0,1,0,1 +559,-90,0,1,0,1 +560,-90,0,1,0,1 +561,-90,0,1,0,1 +562,-90,0,1,0,1 +563,-90,0,1,0,1 +564,-90,0,1,0,1 +565,-90,0,1,0,1 +566,-90,0,1,0,1 +567,-90,0,1,0,1 +568,-90,0,1,0,1 +569,-90,0,1,0,1 +570,-90,0,1,0,1 +571,-90,0,1,0,1 +572,-90,0,1,0,1 +573,-90,0,1,0,1 +574,-90,0,1,0,1 +575,-90,0,1,0,1 +576,-90,0,1,0,1 +577,-90,0,1,0,1 +578,-90,0,1,0,1 +579,-90,0,1,0,1 +580,-90,0,1,0,1 +581,-90,0,1,0,1 +582,-90,0,1,0,1 +583,-90,0,1,0,1 +584,-90,0,1,0,1 +585,-90,0,1,0,1 +586,-90,0,1,0,1 +587,-90,0,1,0,1 +588,-90,0,1,0,1 +589,-90,0,1,0,1 +590,-90,0,1,0,1 +591,-90,0,1,0,1 +592,-90,0,1,0,1 +593,-90,0,1,0,1 +594,-90,0,1,0,1 +595,-90,0,1,0,1 +596,-90,0,1,0,1 +597,-90,0,1,0,1 +598,-90,0,1,0,1 +599,-90,0,1,0,1 +600,-90,0,1,0,1 +601,-90,0,1,0,1 +602,-90,0,1,0,1 +603,-90,0,1,0,1 +604,-90,0,1,0,1 +605,-90,0,1,0,1 +606,-90,0,1,0,1 +607,-90,0,1,0,1 +608,-90,0,1,0,1 +609,-90,0,1,0,1 +610,-90,0,1,0,1 +611,-90,0,1,0,1 +612,-90,0,1,0,1 +613,-90,0,1,0,1 +614,-90,0,1,0,1 +615,-90,0,1,0,1 +616,-90,0,1,0,1 +617,-90,0,1,0,1 +618,-90,0,1,0,1 +619,-90,0,1,0,1 +620,-90,0,1,0,1 +621,-90,0,1,0,1 +622,-90,0,1,0,1 +623,-90,0,1,0,1 +624,-90,0,1,0,1 +625,-90,0,1,0,1 +626,-90,0,1,0,1 +627,-90,0,1,0,1 +628,-90,0,1,0,1 +629,-90,0,1,0,1 +630,-90,0,1,0,1 +631,-90,0,1,0,1 +632,-90,0,1,0,1 +633,-90,0,1,0,1 +634,-90,0,1,0,1 +635,-90,0,1,0,1 +636,-90,0,1,0,1 +637,-90,0,1,0,1 +638,-90,0,1,0,1 +639,-90,0,1,0,1 +640,-90,0,1,0,1 +641,-90,0,1,0,1 +642,-90,0,1,0,1 +643,-90,0,1,0,1 +644,-90,0,1,0,1 +645,-90,0,1,0,1 +646,-90,0,1,0,1 +647,-90,0,1,0,1 +648,-90,0,1,0,1 +649,-90,0,1,0,1 +650,-90,0,1,0,1 +651,-90,0,1,0,1 +652,-90,0,1,0,1 +653,-90,0,1,0,1 +654,-90,0,1,0,1 +655,-90,0,1,0,1 +656,-90,0,1,0,1 +657,-90,0,1,0,1 +658,-90,0,1,0,1 +659,-90,0,1,0,1 +660,-90,0,1,0,1 +661,-90,0,1,0,1 +662,-90,0,1,0,1 +663,-90,0,1,0,1 +664,-90,0,1,0,1 +665,-90,0,1,0,1 +666,-90,0,1,0,1 +667,-90,0,1,0,1 +668,-90,0,1,0,1 +669,-90,0,1,0,1 +670,-90,0,1,0,1 +671,-90,0,1,0,1 +672,-90,0,1,0,1 +673,-90,0,1,0,1 +674,-90,0,1,0,1 +675,-90,0,1,0,1 +676,-90,0,1,0,1 +677,-90,0,1,0,1 +678,-90,0,1,0,1 +679,-90,0,1,0,1 +680,-90,0,1,0,1 +681,-90,0,1,0,1 +682,-90,0,1,0,1 +683,-90,0,1,0,1 +684,-90,0,1,0,1 +685,-90,0,1,0,1 +686,-90,0,1,0,1 +687,-90,0,1,0,1 +688,-90,0,1,0,1 +689,-90,0,1,0,1 +690,-90,0,1,0,1 +691,-90,0,1,0,1 +692,-90,0,1,0,1 +693,-90,0,1,0,1 +694,-90,0,1,0,1 +695,-90,0,1,0,1 +696,-90,0,1,0,1 +697,-90,0,1,0,1 +698,-90,0,1,0,1 +699,-90,0,1,0,1 +700,-90,0,1,0,1 +701,-90,0,1,0,1 +702,-90,0,1,0,1 +703,-90,0,1,0,1 +704,-90,0,1,0,1 +705,-90,0,1,0,1 +706,-90,0,1,0,1 +707,-90,0,1,0,1 +708,-90,0,1,0,1 +709,-90,0,1,0,1 +710,-90,0,1,0,1 +711,-90,0,1,0,1 +712,-90,0,1,0,1 +713,-90,0,1,0,1 +714,-90,0,1,0,1 +715,-90,0,1,0,1 +716,-90,0,1,0,1 +717,-90,0,1,0,1 +718,-90,0,1,0,1 +719,-90,0,1,0,1 +720,-90,0,1,0,1 +721,-90,0,1,0,1 +722,-90,0,1,0,1 +723,-90,0,1,0,1 +724,-90,0,1,0,1 +725,-90,0,1,0,1 +726,-90,0,1,0,1 +727,-90,0,1,0,1 +728,-90,0,1,0,1 +729,-90,0,1,0,1 +730,-90,0,1,0,1 +731,-90,0,1,0,1 +732,-90,0,1,0,1 +733,-90,0,1,0,1 +734,-90,0,1,0,1 +735,-90,0,1,0,1 +736,-90,0,1,0,1 +737,-90,0,1,0,1 +738,-90,0,1,0,1 +739,-90,0,1,0,1 +740,-90,0,1,0,1 +741,-90,0,1,0,1 +742,-90,0,1,0,1 +743,-90,0,1,0,1 +744,-90,0,1,0,1 +745,-90,0,1,0,1 +746,-90,0,1,0,1 +747,-90,0,1,0,1 +748,-90,0,1,0,1 +749,-90,0,1,0,1 diff --git a/scripts/tests/data/ism_0a_0e.csv b/scripts/tests/data/ism_0a_0e.csv new file mode 100644 index 0000000000..fa12ec7c33 --- /dev/null +++ b/scripts/tests/data/ism_0a_0e.csv @@ -0,0 +1,750 @@ +0,0,0,1,0,1 +1,0,0,1,0,1 +2,0,0,1,0,1 +3,0,0,1,0,1 +4,0,0,1,0,1 +5,0,0,1,0,1 +6,0,0,1,0,1 +7,0,0,1,0,1 +8,0,0,1,0,1 +9,0,0,1,0,1 +10,0,0,1,0,1 +11,0,0,1,0,1 +12,0,0,1,0,1 +13,0,0,1,0,1 +14,0,0,1,0,1 +15,0,0,1,0,1 +16,0,0,1,0,1 +17,0,0,1,0,1 +18,0,0,1,0,1 +19,0,0,1,0,1 +20,0,0,1,0,1 +21,0,0,1,0,1 +22,0,0,1,0,1 +23,0,0,1,0,1 +24,0,0,1,0,1 +25,0,0,1,0,1 +26,0,0,1,0,1 +27,0,0,1,0,1 +28,0,0,1,0,1 +29,0,0,1,0,1 +30,0,0,1,0,1 +31,0,0,1,0,1 +32,0,0,1,0,1 +33,0,0,1,0,1 +34,0,0,1,0,1 +35,0,0,1,0,1 +36,0,0,1,0,1 +37,0,0,1,0,1 +38,0,0,1,0,1 +39,0,0,1,0,1 +40,0,0,1,0,1 +41,0,0,1,0,1 +42,0,0,1,0,1 +43,0,0,1,0,1 +44,0,0,1,0,1 +45,0,0,1,0,1 +46,0,0,1,0,1 +47,0,0,1,0,1 +48,0,0,1,0,1 +49,0,0,1,0,1 +50,0,0,1,0,1 +51,0,0,1,0,1 +52,0,0,1,0,1 +53,0,0,1,0,1 +54,0,0,1,0,1 +55,0,0,1,0,1 +56,0,0,1,0,1 +57,0,0,1,0,1 +58,0,0,1,0,1 +59,0,0,1,0,1 +60,0,0,1,0,1 +61,0,0,1,0,1 +62,0,0,1,0,1 +63,0,0,1,0,1 +64,0,0,1,0,1 +65,0,0,1,0,1 +66,0,0,1,0,1 +67,0,0,1,0,1 +68,0,0,1,0,1 +69,0,0,1,0,1 +70,0,0,1,0,1 +71,0,0,1,0,1 +72,0,0,1,0,1 +73,0,0,1,0,1 +74,0,0,1,0,1 +75,0,0,1,0,1 +76,0,0,1,0,1 +77,0,0,1,0,1 +78,0,0,1,0,1 +79,0,0,1,0,1 +80,0,0,1,0,1 +81,0,0,1,0,1 +82,0,0,1,0,1 +83,0,0,1,0,1 +84,0,0,1,0,1 +85,0,0,1,0,1 +86,0,0,1,0,1 +87,0,0,1,0,1 +88,0,0,1,0,1 +89,0,0,1,0,1 +90,0,0,1,0,1 +91,0,0,1,0,1 +92,0,0,1,0,1 +93,0,0,1,0,1 +94,0,0,1,0,1 +95,0,0,1,0,1 +96,0,0,1,0,1 +97,0,0,1,0,1 +98,0,0,1,0,1 +99,0,0,1,0,1 +100,0,0,1,0,1 +101,0,0,1,0,1 +102,0,0,1,0,1 +103,0,0,1,0,1 +104,0,0,1,0,1 +105,0,0,1,0,1 +106,0,0,1,0,1 +107,0,0,1,0,1 +108,0,0,1,0,1 +109,0,0,1,0,1 +110,0,0,1,0,1 +111,0,0,1,0,1 +112,0,0,1,0,1 +113,0,0,1,0,1 +114,0,0,1,0,1 +115,0,0,1,0,1 +116,0,0,1,0,1 +117,0,0,1,0,1 +118,0,0,1,0,1 +119,0,0,1,0,1 +120,0,0,1,0,1 +121,0,0,1,0,1 +122,0,0,1,0,1 +123,0,0,1,0,1 +124,0,0,1,0,1 +125,0,0,1,0,1 +126,0,0,1,0,1 +127,0,0,1,0,1 +128,0,0,1,0,1 +129,0,0,1,0,1 +130,0,0,1,0,1 +131,0,0,1,0,1 +132,0,0,1,0,1 +133,0,0,1,0,1 +134,0,0,1,0,1 +135,0,0,1,0,1 +136,0,0,1,0,1 +137,0,0,1,0,1 +138,0,0,1,0,1 +139,0,0,1,0,1 +140,0,0,1,0,1 +141,0,0,1,0,1 +142,0,0,1,0,1 +143,0,0,1,0,1 +144,0,0,1,0,1 +145,0,0,1,0,1 +146,0,0,1,0,1 +147,0,0,1,0,1 +148,0,0,1,0,1 +149,0,0,1,0,1 +150,0,0,1,0,1 +151,0,0,1,0,1 +152,0,0,1,0,1 +153,0,0,1,0,1 +154,0,0,1,0,1 +155,0,0,1,0,1 +156,0,0,1,0,1 +157,0,0,1,0,1 +158,0,0,1,0,1 +159,0,0,1,0,1 +160,0,0,1,0,1 +161,0,0,1,0,1 +162,0,0,1,0,1 +163,0,0,1,0,1 +164,0,0,1,0,1 +165,0,0,1,0,1 +166,0,0,1,0,1 +167,0,0,1,0,1 +168,0,0,1,0,1 +169,0,0,1,0,1 +170,0,0,1,0,1 +171,0,0,1,0,1 +172,0,0,1,0,1 +173,0,0,1,0,1 +174,0,0,1,0,1 +175,0,0,1,0,1 +176,0,0,1,0,1 +177,0,0,1,0,1 +178,0,0,1,0,1 +179,0,0,1,0,1 +180,0,0,1,0,1 +181,0,0,1,0,1 +182,0,0,1,0,1 +183,0,0,1,0,1 +184,0,0,1,0,1 +185,0,0,1,0,1 +186,0,0,1,0,1 +187,0,0,1,0,1 +188,0,0,1,0,1 +189,0,0,1,0,1 +190,0,0,1,0,1 +191,0,0,1,0,1 +192,0,0,1,0,1 +193,0,0,1,0,1 +194,0,0,1,0,1 +195,0,0,1,0,1 +196,0,0,1,0,1 +197,0,0,1,0,1 +198,0,0,1,0,1 +199,0,0,1,0,1 +200,0,0,1,0,1 +201,0,0,1,0,1 +202,0,0,1,0,1 +203,0,0,1,0,1 +204,0,0,1,0,1 +205,0,0,1,0,1 +206,0,0,1,0,1 +207,0,0,1,0,1 +208,0,0,1,0,1 +209,0,0,1,0,1 +210,0,0,1,0,1 +211,0,0,1,0,1 +212,0,0,1,0,1 +213,0,0,1,0,1 +214,0,0,1,0,1 +215,0,0,1,0,1 +216,0,0,1,0,1 +217,0,0,1,0,1 +218,0,0,1,0,1 +219,0,0,1,0,1 +220,0,0,1,0,1 +221,0,0,1,0,1 +222,0,0,1,0,1 +223,0,0,1,0,1 +224,0,0,1,0,1 +225,0,0,1,0,1 +226,0,0,1,0,1 +227,0,0,1,0,1 +228,0,0,1,0,1 +229,0,0,1,0,1 +230,0,0,1,0,1 +231,0,0,1,0,1 +232,0,0,1,0,1 +233,0,0,1,0,1 +234,0,0,1,0,1 +235,0,0,1,0,1 +236,0,0,1,0,1 +237,0,0,1,0,1 +238,0,0,1,0,1 +239,0,0,1,0,1 +240,0,0,1,0,1 +241,0,0,1,0,1 +242,0,0,1,0,1 +243,0,0,1,0,1 +244,0,0,1,0,1 +245,0,0,1,0,1 +246,0,0,1,0,1 +247,0,0,1,0,1 +248,0,0,1,0,1 +249,0,0,1,0,1 +250,0,0,1,0,1 +251,0,0,1,0,1 +252,0,0,1,0,1 +253,0,0,1,0,1 +254,0,0,1,0,1 +255,0,0,1,0,1 +256,0,0,1,0,1 +257,0,0,1,0,1 +258,0,0,1,0,1 +259,0,0,1,0,1 +260,0,0,1,0,1 +261,0,0,1,0,1 +262,0,0,1,0,1 +263,0,0,1,0,1 +264,0,0,1,0,1 +265,0,0,1,0,1 +266,0,0,1,0,1 +267,0,0,1,0,1 +268,0,0,1,0,1 +269,0,0,1,0,1 +270,0,0,1,0,1 +271,0,0,1,0,1 +272,0,0,1,0,1 +273,0,0,1,0,1 +274,0,0,1,0,1 +275,0,0,1,0,1 +276,0,0,1,0,1 +277,0,0,1,0,1 +278,0,0,1,0,1 +279,0,0,1,0,1 +280,0,0,1,0,1 +281,0,0,1,0,1 +282,0,0,1,0,1 +283,0,0,1,0,1 +284,0,0,1,0,1 +285,0,0,1,0,1 +286,0,0,1,0,1 +287,0,0,1,0,1 +288,0,0,1,0,1 +289,0,0,1,0,1 +290,0,0,1,0,1 +291,0,0,1,0,1 +292,0,0,1,0,1 +293,0,0,1,0,1 +294,0,0,1,0,1 +295,0,0,1,0,1 +296,0,0,1,0,1 +297,0,0,1,0,1 +298,0,0,1,0,1 +299,0,0,1,0,1 +300,0,0,1,0,1 +301,0,0,1,0,1 +302,0,0,1,0,1 +303,0,0,1,0,1 +304,0,0,1,0,1 +305,0,0,1,0,1 +306,0,0,1,0,1 +307,0,0,1,0,1 +308,0,0,1,0,1 +309,0,0,1,0,1 +310,0,0,1,0,1 +311,0,0,1,0,1 +312,0,0,1,0,1 +313,0,0,1,0,1 +314,0,0,1,0,1 +315,0,0,1,0,1 +316,0,0,1,0,1 +317,0,0,1,0,1 +318,0,0,1,0,1 +319,0,0,1,0,1 +320,0,0,1,0,1 +321,0,0,1,0,1 +322,0,0,1,0,1 +323,0,0,1,0,1 +324,0,0,1,0,1 +325,0,0,1,0,1 +326,0,0,1,0,1 +327,0,0,1,0,1 +328,0,0,1,0,1 +329,0,0,1,0,1 +330,0,0,1,0,1 +331,0,0,1,0,1 +332,0,0,1,0,1 +333,0,0,1,0,1 +334,0,0,1,0,1 +335,0,0,1,0,1 +336,0,0,1,0,1 +337,0,0,1,0,1 +338,0,0,1,0,1 +339,0,0,1,0,1 +340,0,0,1,0,1 +341,0,0,1,0,1 +342,0,0,1,0,1 +343,0,0,1,0,1 +344,0,0,1,0,1 +345,0,0,1,0,1 +346,0,0,1,0,1 +347,0,0,1,0,1 +348,0,0,1,0,1 +349,0,0,1,0,1 +350,0,0,1,0,1 +351,0,0,1,0,1 +352,0,0,1,0,1 +353,0,0,1,0,1 +354,0,0,1,0,1 +355,0,0,1,0,1 +356,0,0,1,0,1 +357,0,0,1,0,1 +358,0,0,1,0,1 +359,0,0,1,0,1 +360,0,0,1,0,1 +361,0,0,1,0,1 +362,0,0,1,0,1 +363,0,0,1,0,1 +364,0,0,1,0,1 +365,0,0,1,0,1 +366,0,0,1,0,1 +367,0,0,1,0,1 +368,0,0,1,0,1 +369,0,0,1,0,1 +370,0,0,1,0,1 +371,0,0,1,0,1 +372,0,0,1,0,1 +373,0,0,1,0,1 +374,0,0,1,0,1 +375,0,0,1,0,1 +376,0,0,1,0,1 +377,0,0,1,0,1 +378,0,0,1,0,1 +379,0,0,1,0,1 +380,0,0,1,0,1 +381,0,0,1,0,1 +382,0,0,1,0,1 +383,0,0,1,0,1 +384,0,0,1,0,1 +385,0,0,1,0,1 +386,0,0,1,0,1 +387,0,0,1,0,1 +388,0,0,1,0,1 +389,0,0,1,0,1 +390,0,0,1,0,1 +391,0,0,1,0,1 +392,0,0,1,0,1 +393,0,0,1,0,1 +394,0,0,1,0,1 +395,0,0,1,0,1 +396,0,0,1,0,1 +397,0,0,1,0,1 +398,0,0,1,0,1 +399,0,0,1,0,1 +400,0,0,1,0,1 +401,0,0,1,0,1 +402,0,0,1,0,1 +403,0,0,1,0,1 +404,0,0,1,0,1 +405,0,0,1,0,1 +406,0,0,1,0,1 +407,0,0,1,0,1 +408,0,0,1,0,1 +409,0,0,1,0,1 +410,0,0,1,0,1 +411,0,0,1,0,1 +412,0,0,1,0,1 +413,0,0,1,0,1 +414,0,0,1,0,1 +415,0,0,1,0,1 +416,0,0,1,0,1 +417,0,0,1,0,1 +418,0,0,1,0,1 +419,0,0,1,0,1 +420,0,0,1,0,1 +421,0,0,1,0,1 +422,0,0,1,0,1 +423,0,0,1,0,1 +424,0,0,1,0,1 +425,0,0,1,0,1 +426,0,0,1,0,1 +427,0,0,1,0,1 +428,0,0,1,0,1 +429,0,0,1,0,1 +430,0,0,1,0,1 +431,0,0,1,0,1 +432,0,0,1,0,1 +433,0,0,1,0,1 +434,0,0,1,0,1 +435,0,0,1,0,1 +436,0,0,1,0,1 +437,0,0,1,0,1 +438,0,0,1,0,1 +439,0,0,1,0,1 +440,0,0,1,0,1 +441,0,0,1,0,1 +442,0,0,1,0,1 +443,0,0,1,0,1 +444,0,0,1,0,1 +445,0,0,1,0,1 +446,0,0,1,0,1 +447,0,0,1,0,1 +448,0,0,1,0,1 +449,0,0,1,0,1 +450,0,0,1,0,1 +451,0,0,1,0,1 +452,0,0,1,0,1 +453,0,0,1,0,1 +454,0,0,1,0,1 +455,0,0,1,0,1 +456,0,0,1,0,1 +457,0,0,1,0,1 +458,0,0,1,0,1 +459,0,0,1,0,1 +460,0,0,1,0,1 +461,0,0,1,0,1 +462,0,0,1,0,1 +463,0,0,1,0,1 +464,0,0,1,0,1 +465,0,0,1,0,1 +466,0,0,1,0,1 +467,0,0,1,0,1 +468,0,0,1,0,1 +469,0,0,1,0,1 +470,0,0,1,0,1 +471,0,0,1,0,1 +472,0,0,1,0,1 +473,0,0,1,0,1 +474,0,0,1,0,1 +475,0,0,1,0,1 +476,0,0,1,0,1 +477,0,0,1,0,1 +478,0,0,1,0,1 +479,0,0,1,0,1 +480,0,0,1,0,1 +481,0,0,1,0,1 +482,0,0,1,0,1 +483,0,0,1,0,1 +484,0,0,1,0,1 +485,0,0,1,0,1 +486,0,0,1,0,1 +487,0,0,1,0,1 +488,0,0,1,0,1 +489,0,0,1,0,1 +490,0,0,1,0,1 +491,0,0,1,0,1 +492,0,0,1,0,1 +493,0,0,1,0,1 +494,0,0,1,0,1 +495,0,0,1,0,1 +496,0,0,1,0,1 +497,0,0,1,0,1 +498,0,0,1,0,1 +499,0,0,1,0,1 +500,0,0,1,0,1 +501,0,0,1,0,1 +502,0,0,1,0,1 +503,0,0,1,0,1 +504,0,0,1,0,1 +505,0,0,1,0,1 +506,0,0,1,0,1 +507,0,0,1,0,1 +508,0,0,1,0,1 +509,0,0,1,0,1 +510,0,0,1,0,1 +511,0,0,1,0,1 +512,0,0,1,0,1 +513,0,0,1,0,1 +514,0,0,1,0,1 +515,0,0,1,0,1 +516,0,0,1,0,1 +517,0,0,1,0,1 +518,0,0,1,0,1 +519,0,0,1,0,1 +520,0,0,1,0,1 +521,0,0,1,0,1 +522,0,0,1,0,1 +523,0,0,1,0,1 +524,0,0,1,0,1 +525,0,0,1,0,1 +526,0,0,1,0,1 +527,0,0,1,0,1 +528,0,0,1,0,1 +529,0,0,1,0,1 +530,0,0,1,0,1 +531,0,0,1,0,1 +532,0,0,1,0,1 +533,0,0,1,0,1 +534,0,0,1,0,1 +535,0,0,1,0,1 +536,0,0,1,0,1 +537,0,0,1,0,1 +538,0,0,1,0,1 +539,0,0,1,0,1 +540,0,0,1,0,1 +541,0,0,1,0,1 +542,0,0,1,0,1 +543,0,0,1,0,1 +544,0,0,1,0,1 +545,0,0,1,0,1 +546,0,0,1,0,1 +547,0,0,1,0,1 +548,0,0,1,0,1 +549,0,0,1,0,1 +550,0,0,1,0,1 +551,0,0,1,0,1 +552,0,0,1,0,1 +553,0,0,1,0,1 +554,0,0,1,0,1 +555,0,0,1,0,1 +556,0,0,1,0,1 +557,0,0,1,0,1 +558,0,0,1,0,1 +559,0,0,1,0,1 +560,0,0,1,0,1 +561,0,0,1,0,1 +562,0,0,1,0,1 +563,0,0,1,0,1 +564,0,0,1,0,1 +565,0,0,1,0,1 +566,0,0,1,0,1 +567,0,0,1,0,1 +568,0,0,1,0,1 +569,0,0,1,0,1 +570,0,0,1,0,1 +571,0,0,1,0,1 +572,0,0,1,0,1 +573,0,0,1,0,1 +574,0,0,1,0,1 +575,0,0,1,0,1 +576,0,0,1,0,1 +577,0,0,1,0,1 +578,0,0,1,0,1 +579,0,0,1,0,1 +580,0,0,1,0,1 +581,0,0,1,0,1 +582,0,0,1,0,1 +583,0,0,1,0,1 +584,0,0,1,0,1 +585,0,0,1,0,1 +586,0,0,1,0,1 +587,0,0,1,0,1 +588,0,0,1,0,1 +589,0,0,1,0,1 +590,0,0,1,0,1 +591,0,0,1,0,1 +592,0,0,1,0,1 +593,0,0,1,0,1 +594,0,0,1,0,1 +595,0,0,1,0,1 +596,0,0,1,0,1 +597,0,0,1,0,1 +598,0,0,1,0,1 +599,0,0,1,0,1 +600,0,0,1,0,1 +601,0,0,1,0,1 +602,0,0,1,0,1 +603,0,0,1,0,1 +604,0,0,1,0,1 +605,0,0,1,0,1 +606,0,0,1,0,1 +607,0,0,1,0,1 +608,0,0,1,0,1 +609,0,0,1,0,1 +610,0,0,1,0,1 +611,0,0,1,0,1 +612,0,0,1,0,1 +613,0,0,1,0,1 +614,0,0,1,0,1 +615,0,0,1,0,1 +616,0,0,1,0,1 +617,0,0,1,0,1 +618,0,0,1,0,1 +619,0,0,1,0,1 +620,0,0,1,0,1 +621,0,0,1,0,1 +622,0,0,1,0,1 +623,0,0,1,0,1 +624,0,0,1,0,1 +625,0,0,1,0,1 +626,0,0,1,0,1 +627,0,0,1,0,1 +628,0,0,1,0,1 +629,0,0,1,0,1 +630,0,0,1,0,1 +631,0,0,1,0,1 +632,0,0,1,0,1 +633,0,0,1,0,1 +634,0,0,1,0,1 +635,0,0,1,0,1 +636,0,0,1,0,1 +637,0,0,1,0,1 +638,0,0,1,0,1 +639,0,0,1,0,1 +640,0,0,1,0,1 +641,0,0,1,0,1 +642,0,0,1,0,1 +643,0,0,1,0,1 +644,0,0,1,0,1 +645,0,0,1,0,1 +646,0,0,1,0,1 +647,0,0,1,0,1 +648,0,0,1,0,1 +649,0,0,1,0,1 +650,0,0,1,0,1 +651,0,0,1,0,1 +652,0,0,1,0,1 +653,0,0,1,0,1 +654,0,0,1,0,1 +655,0,0,1,0,1 +656,0,0,1,0,1 +657,0,0,1,0,1 +658,0,0,1,0,1 +659,0,0,1,0,1 +660,0,0,1,0,1 +661,0,0,1,0,1 +662,0,0,1,0,1 +663,0,0,1,0,1 +664,0,0,1,0,1 +665,0,0,1,0,1 +666,0,0,1,0,1 +667,0,0,1,0,1 +668,0,0,1,0,1 +669,0,0,1,0,1 +670,0,0,1,0,1 +671,0,0,1,0,1 +672,0,0,1,0,1 +673,0,0,1,0,1 +674,0,0,1,0,1 +675,0,0,1,0,1 +676,0,0,1,0,1 +677,0,0,1,0,1 +678,0,0,1,0,1 +679,0,0,1,0,1 +680,0,0,1,0,1 +681,0,0,1,0,1 +682,0,0,1,0,1 +683,0,0,1,0,1 +684,0,0,1,0,1 +685,0,0,1,0,1 +686,0,0,1,0,1 +687,0,0,1,0,1 +688,0,0,1,0,1 +689,0,0,1,0,1 +690,0,0,1,0,1 +691,0,0,1,0,1 +692,0,0,1,0,1 +693,0,0,1,0,1 +694,0,0,1,0,1 +695,0,0,1,0,1 +696,0,0,1,0,1 +697,0,0,1,0,1 +698,0,0,1,0,1 +699,0,0,1,0,1 +700,0,0,1,0,1 +701,0,0,1,0,1 +702,0,0,1,0,1 +703,0,0,1,0,1 +704,0,0,1,0,1 +705,0,0,1,0,1 +706,0,0,1,0,1 +707,0,0,1,0,1 +708,0,0,1,0,1 +709,0,0,1,0,1 +710,0,0,1,0,1 +711,0,0,1,0,1 +712,0,0,1,0,1 +713,0,0,1,0,1 +714,0,0,1,0,1 +715,0,0,1,0,1 +716,0,0,1,0,1 +717,0,0,1,0,1 +718,0,0,1,0,1 +719,0,0,1,0,1 +720,0,0,1,0,1 +721,0,0,1,0,1 +722,0,0,1,0,1 +723,0,0,1,0,1 +724,0,0,1,0,1 +725,0,0,1,0,1 +726,0,0,1,0,1 +727,0,0,1,0,1 +728,0,0,1,0,1 +729,0,0,1,0,1 +730,0,0,1,0,1 +731,0,0,1,0,1 +732,0,0,1,0,1 +733,0,0,1,0,1 +734,0,0,1,0,1 +735,0,0,1,0,1 +736,0,0,1,0,1 +737,0,0,1,0,1 +738,0,0,1,0,1 +739,0,0,1,0,1 +740,0,0,1,0,1 +741,0,0,1,0,1 +742,0,0,1,0,1 +743,0,0,1,0,1 +744,0,0,1,0,1 +745,0,0,1,0,1 +746,0,0,1,0,1 +747,0,0,1,0,1 +748,0,0,1,0,1 +749,0,0,1,0,1 diff --git a/scripts/tests/data/ism_180a_0e.csv b/scripts/tests/data/ism_180a_0e.csv new file mode 100644 index 0000000000..2db0f1a477 --- /dev/null +++ b/scripts/tests/data/ism_180a_0e.csv @@ -0,0 +1,750 @@ +0,180,0,1,0,1 +1,180,0,1,0,1 +2,180,0,1,0,1 +3,180,0,1,0,1 +4,180,0,1,0,1 +5,180,0,1,0,1 +6,180,0,1,0,1 +7,180,0,1,0,1 +8,180,0,1,0,1 +9,180,0,1,0,1 +10,180,0,1,0,1 +11,180,0,1,0,1 +12,180,0,1,0,1 +13,180,0,1,0,1 +14,180,0,1,0,1 +15,180,0,1,0,1 +16,180,0,1,0,1 +17,180,0,1,0,1 +18,180,0,1,0,1 +19,180,0,1,0,1 +20,180,0,1,0,1 +21,180,0,1,0,1 +22,180,0,1,0,1 +23,180,0,1,0,1 +24,180,0,1,0,1 +25,180,0,1,0,1 +26,180,0,1,0,1 +27,180,0,1,0,1 +28,180,0,1,0,1 +29,180,0,1,0,1 +30,180,0,1,0,1 +31,180,0,1,0,1 +32,180,0,1,0,1 +33,180,0,1,0,1 +34,180,0,1,0,1 +35,180,0,1,0,1 +36,180,0,1,0,1 +37,180,0,1,0,1 +38,180,0,1,0,1 +39,180,0,1,0,1 +40,180,0,1,0,1 +41,180,0,1,0,1 +42,180,0,1,0,1 +43,180,0,1,0,1 +44,180,0,1,0,1 +45,180,0,1,0,1 +46,180,0,1,0,1 +47,180,0,1,0,1 +48,180,0,1,0,1 +49,180,0,1,0,1 +50,180,0,1,0,1 +51,180,0,1,0,1 +52,180,0,1,0,1 +53,180,0,1,0,1 +54,180,0,1,0,1 +55,180,0,1,0,1 +56,180,0,1,0,1 +57,180,0,1,0,1 +58,180,0,1,0,1 +59,180,0,1,0,1 +60,180,0,1,0,1 +61,180,0,1,0,1 +62,180,0,1,0,1 +63,180,0,1,0,1 +64,180,0,1,0,1 +65,180,0,1,0,1 +66,180,0,1,0,1 +67,180,0,1,0,1 +68,180,0,1,0,1 +69,180,0,1,0,1 +70,180,0,1,0,1 +71,180,0,1,0,1 +72,180,0,1,0,1 +73,180,0,1,0,1 +74,180,0,1,0,1 +75,180,0,1,0,1 +76,180,0,1,0,1 +77,180,0,1,0,1 +78,180,0,1,0,1 +79,180,0,1,0,1 +80,180,0,1,0,1 +81,180,0,1,0,1 +82,180,0,1,0,1 +83,180,0,1,0,1 +84,180,0,1,0,1 +85,180,0,1,0,1 +86,180,0,1,0,1 +87,180,0,1,0,1 +88,180,0,1,0,1 +89,180,0,1,0,1 +90,180,0,1,0,1 +91,180,0,1,0,1 +92,180,0,1,0,1 +93,180,0,1,0,1 +94,180,0,1,0,1 +95,180,0,1,0,1 +96,180,0,1,0,1 +97,180,0,1,0,1 +98,180,0,1,0,1 +99,180,0,1,0,1 +100,180,0,1,0,1 +101,180,0,1,0,1 +102,180,0,1,0,1 +103,180,0,1,0,1 +104,180,0,1,0,1 +105,180,0,1,0,1 +106,180,0,1,0,1 +107,180,0,1,0,1 +108,180,0,1,0,1 +109,180,0,1,0,1 +110,180,0,1,0,1 +111,180,0,1,0,1 +112,180,0,1,0,1 +113,180,0,1,0,1 +114,180,0,1,0,1 +115,180,0,1,0,1 +116,180,0,1,0,1 +117,180,0,1,0,1 +118,180,0,1,0,1 +119,180,0,1,0,1 +120,180,0,1,0,1 +121,180,0,1,0,1 +122,180,0,1,0,1 +123,180,0,1,0,1 +124,180,0,1,0,1 +125,180,0,1,0,1 +126,180,0,1,0,1 +127,180,0,1,0,1 +128,180,0,1,0,1 +129,180,0,1,0,1 +130,180,0,1,0,1 +131,180,0,1,0,1 +132,180,0,1,0,1 +133,180,0,1,0,1 +134,180,0,1,0,1 +135,180,0,1,0,1 +136,180,0,1,0,1 +137,180,0,1,0,1 +138,180,0,1,0,1 +139,180,0,1,0,1 +140,180,0,1,0,1 +141,180,0,1,0,1 +142,180,0,1,0,1 +143,180,0,1,0,1 +144,180,0,1,0,1 +145,180,0,1,0,1 +146,180,0,1,0,1 +147,180,0,1,0,1 +148,180,0,1,0,1 +149,180,0,1,0,1 +150,180,0,1,0,1 +151,180,0,1,0,1 +152,180,0,1,0,1 +153,180,0,1,0,1 +154,180,0,1,0,1 +155,180,0,1,0,1 +156,180,0,1,0,1 +157,180,0,1,0,1 +158,180,0,1,0,1 +159,180,0,1,0,1 +160,180,0,1,0,1 +161,180,0,1,0,1 +162,180,0,1,0,1 +163,180,0,1,0,1 +164,180,0,1,0,1 +165,180,0,1,0,1 +166,180,0,1,0,1 +167,180,0,1,0,1 +168,180,0,1,0,1 +169,180,0,1,0,1 +170,180,0,1,0,1 +171,180,0,1,0,1 +172,180,0,1,0,1 +173,180,0,1,0,1 +174,180,0,1,0,1 +175,180,0,1,0,1 +176,180,0,1,0,1 +177,180,0,1,0,1 +178,180,0,1,0,1 +179,180,0,1,0,1 +180,180,0,1,0,1 +181,180,0,1,0,1 +182,180,0,1,0,1 +183,180,0,1,0,1 +184,180,0,1,0,1 +185,180,0,1,0,1 +186,180,0,1,0,1 +187,180,0,1,0,1 +188,180,0,1,0,1 +189,180,0,1,0,1 +190,180,0,1,0,1 +191,180,0,1,0,1 +192,180,0,1,0,1 +193,180,0,1,0,1 +194,180,0,1,0,1 +195,180,0,1,0,1 +196,180,0,1,0,1 +197,180,0,1,0,1 +198,180,0,1,0,1 +199,180,0,1,0,1 +200,180,0,1,0,1 +201,180,0,1,0,1 +202,180,0,1,0,1 +203,180,0,1,0,1 +204,180,0,1,0,1 +205,180,0,1,0,1 +206,180,0,1,0,1 +207,180,0,1,0,1 +208,180,0,1,0,1 +209,180,0,1,0,1 +210,180,0,1,0,1 +211,180,0,1,0,1 +212,180,0,1,0,1 +213,180,0,1,0,1 +214,180,0,1,0,1 +215,180,0,1,0,1 +216,180,0,1,0,1 +217,180,0,1,0,1 +218,180,0,1,0,1 +219,180,0,1,0,1 +220,180,0,1,0,1 +221,180,0,1,0,1 +222,180,0,1,0,1 +223,180,0,1,0,1 +224,180,0,1,0,1 +225,180,0,1,0,1 +226,180,0,1,0,1 +227,180,0,1,0,1 +228,180,0,1,0,1 +229,180,0,1,0,1 +230,180,0,1,0,1 +231,180,0,1,0,1 +232,180,0,1,0,1 +233,180,0,1,0,1 +234,180,0,1,0,1 +235,180,0,1,0,1 +236,180,0,1,0,1 +237,180,0,1,0,1 +238,180,0,1,0,1 +239,180,0,1,0,1 +240,180,0,1,0,1 +241,180,0,1,0,1 +242,180,0,1,0,1 +243,180,0,1,0,1 +244,180,0,1,0,1 +245,180,0,1,0,1 +246,180,0,1,0,1 +247,180,0,1,0,1 +248,180,0,1,0,1 +249,180,0,1,0,1 +250,180,0,1,0,1 +251,180,0,1,0,1 +252,180,0,1,0,1 +253,180,0,1,0,1 +254,180,0,1,0,1 +255,180,0,1,0,1 +256,180,0,1,0,1 +257,180,0,1,0,1 +258,180,0,1,0,1 +259,180,0,1,0,1 +260,180,0,1,0,1 +261,180,0,1,0,1 +262,180,0,1,0,1 +263,180,0,1,0,1 +264,180,0,1,0,1 +265,180,0,1,0,1 +266,180,0,1,0,1 +267,180,0,1,0,1 +268,180,0,1,0,1 +269,180,0,1,0,1 +270,180,0,1,0,1 +271,180,0,1,0,1 +272,180,0,1,0,1 +273,180,0,1,0,1 +274,180,0,1,0,1 +275,180,0,1,0,1 +276,180,0,1,0,1 +277,180,0,1,0,1 +278,180,0,1,0,1 +279,180,0,1,0,1 +280,180,0,1,0,1 +281,180,0,1,0,1 +282,180,0,1,0,1 +283,180,0,1,0,1 +284,180,0,1,0,1 +285,180,0,1,0,1 +286,180,0,1,0,1 +287,180,0,1,0,1 +288,180,0,1,0,1 +289,180,0,1,0,1 +290,180,0,1,0,1 +291,180,0,1,0,1 +292,180,0,1,0,1 +293,180,0,1,0,1 +294,180,0,1,0,1 +295,180,0,1,0,1 +296,180,0,1,0,1 +297,180,0,1,0,1 +298,180,0,1,0,1 +299,180,0,1,0,1 +300,180,0,1,0,1 +301,180,0,1,0,1 +302,180,0,1,0,1 +303,180,0,1,0,1 +304,180,0,1,0,1 +305,180,0,1,0,1 +306,180,0,1,0,1 +307,180,0,1,0,1 +308,180,0,1,0,1 +309,180,0,1,0,1 +310,180,0,1,0,1 +311,180,0,1,0,1 +312,180,0,1,0,1 +313,180,0,1,0,1 +314,180,0,1,0,1 +315,180,0,1,0,1 +316,180,0,1,0,1 +317,180,0,1,0,1 +318,180,0,1,0,1 +319,180,0,1,0,1 +320,180,0,1,0,1 +321,180,0,1,0,1 +322,180,0,1,0,1 +323,180,0,1,0,1 +324,180,0,1,0,1 +325,180,0,1,0,1 +326,180,0,1,0,1 +327,180,0,1,0,1 +328,180,0,1,0,1 +329,180,0,1,0,1 +330,180,0,1,0,1 +331,180,0,1,0,1 +332,180,0,1,0,1 +333,180,0,1,0,1 +334,180,0,1,0,1 +335,180,0,1,0,1 +336,180,0,1,0,1 +337,180,0,1,0,1 +338,180,0,1,0,1 +339,180,0,1,0,1 +340,180,0,1,0,1 +341,180,0,1,0,1 +342,180,0,1,0,1 +343,180,0,1,0,1 +344,180,0,1,0,1 +345,180,0,1,0,1 +346,180,0,1,0,1 +347,180,0,1,0,1 +348,180,0,1,0,1 +349,180,0,1,0,1 +350,180,0,1,0,1 +351,180,0,1,0,1 +352,180,0,1,0,1 +353,180,0,1,0,1 +354,180,0,1,0,1 +355,180,0,1,0,1 +356,180,0,1,0,1 +357,180,0,1,0,1 +358,180,0,1,0,1 +359,180,0,1,0,1 +360,180,0,1,0,1 +361,180,0,1,0,1 +362,180,0,1,0,1 +363,180,0,1,0,1 +364,180,0,1,0,1 +365,180,0,1,0,1 +366,180,0,1,0,1 +367,180,0,1,0,1 +368,180,0,1,0,1 +369,180,0,1,0,1 +370,180,0,1,0,1 +371,180,0,1,0,1 +372,180,0,1,0,1 +373,180,0,1,0,1 +374,180,0,1,0,1 +375,180,0,1,0,1 +376,180,0,1,0,1 +377,180,0,1,0,1 +378,180,0,1,0,1 +379,180,0,1,0,1 +380,180,0,1,0,1 +381,180,0,1,0,1 +382,180,0,1,0,1 +383,180,0,1,0,1 +384,180,0,1,0,1 +385,180,0,1,0,1 +386,180,0,1,0,1 +387,180,0,1,0,1 +388,180,0,1,0,1 +389,180,0,1,0,1 +390,180,0,1,0,1 +391,180,0,1,0,1 +392,180,0,1,0,1 +393,180,0,1,0,1 +394,180,0,1,0,1 +395,180,0,1,0,1 +396,180,0,1,0,1 +397,180,0,1,0,1 +398,180,0,1,0,1 +399,180,0,1,0,1 +400,180,0,1,0,1 +401,180,0,1,0,1 +402,180,0,1,0,1 +403,180,0,1,0,1 +404,180,0,1,0,1 +405,180,0,1,0,1 +406,180,0,1,0,1 +407,180,0,1,0,1 +408,180,0,1,0,1 +409,180,0,1,0,1 +410,180,0,1,0,1 +411,180,0,1,0,1 +412,180,0,1,0,1 +413,180,0,1,0,1 +414,180,0,1,0,1 +415,180,0,1,0,1 +416,180,0,1,0,1 +417,180,0,1,0,1 +418,180,0,1,0,1 +419,180,0,1,0,1 +420,180,0,1,0,1 +421,180,0,1,0,1 +422,180,0,1,0,1 +423,180,0,1,0,1 +424,180,0,1,0,1 +425,180,0,1,0,1 +426,180,0,1,0,1 +427,180,0,1,0,1 +428,180,0,1,0,1 +429,180,0,1,0,1 +430,180,0,1,0,1 +431,180,0,1,0,1 +432,180,0,1,0,1 +433,180,0,1,0,1 +434,180,0,1,0,1 +435,180,0,1,0,1 +436,180,0,1,0,1 +437,180,0,1,0,1 +438,180,0,1,0,1 +439,180,0,1,0,1 +440,180,0,1,0,1 +441,180,0,1,0,1 +442,180,0,1,0,1 +443,180,0,1,0,1 +444,180,0,1,0,1 +445,180,0,1,0,1 +446,180,0,1,0,1 +447,180,0,1,0,1 +448,180,0,1,0,1 +449,180,0,1,0,1 +450,180,0,1,0,1 +451,180,0,1,0,1 +452,180,0,1,0,1 +453,180,0,1,0,1 +454,180,0,1,0,1 +455,180,0,1,0,1 +456,180,0,1,0,1 +457,180,0,1,0,1 +458,180,0,1,0,1 +459,180,0,1,0,1 +460,180,0,1,0,1 +461,180,0,1,0,1 +462,180,0,1,0,1 +463,180,0,1,0,1 +464,180,0,1,0,1 +465,180,0,1,0,1 +466,180,0,1,0,1 +467,180,0,1,0,1 +468,180,0,1,0,1 +469,180,0,1,0,1 +470,180,0,1,0,1 +471,180,0,1,0,1 +472,180,0,1,0,1 +473,180,0,1,0,1 +474,180,0,1,0,1 +475,180,0,1,0,1 +476,180,0,1,0,1 +477,180,0,1,0,1 +478,180,0,1,0,1 +479,180,0,1,0,1 +480,180,0,1,0,1 +481,180,0,1,0,1 +482,180,0,1,0,1 +483,180,0,1,0,1 +484,180,0,1,0,1 +485,180,0,1,0,1 +486,180,0,1,0,1 +487,180,0,1,0,1 +488,180,0,1,0,1 +489,180,0,1,0,1 +490,180,0,1,0,1 +491,180,0,1,0,1 +492,180,0,1,0,1 +493,180,0,1,0,1 +494,180,0,1,0,1 +495,180,0,1,0,1 +496,180,0,1,0,1 +497,180,0,1,0,1 +498,180,0,1,0,1 +499,180,0,1,0,1 +500,180,0,1,0,1 +501,180,0,1,0,1 +502,180,0,1,0,1 +503,180,0,1,0,1 +504,180,0,1,0,1 +505,180,0,1,0,1 +506,180,0,1,0,1 +507,180,0,1,0,1 +508,180,0,1,0,1 +509,180,0,1,0,1 +510,180,0,1,0,1 +511,180,0,1,0,1 +512,180,0,1,0,1 +513,180,0,1,0,1 +514,180,0,1,0,1 +515,180,0,1,0,1 +516,180,0,1,0,1 +517,180,0,1,0,1 +518,180,0,1,0,1 +519,180,0,1,0,1 +520,180,0,1,0,1 +521,180,0,1,0,1 +522,180,0,1,0,1 +523,180,0,1,0,1 +524,180,0,1,0,1 +525,180,0,1,0,1 +526,180,0,1,0,1 +527,180,0,1,0,1 +528,180,0,1,0,1 +529,180,0,1,0,1 +530,180,0,1,0,1 +531,180,0,1,0,1 +532,180,0,1,0,1 +533,180,0,1,0,1 +534,180,0,1,0,1 +535,180,0,1,0,1 +536,180,0,1,0,1 +537,180,0,1,0,1 +538,180,0,1,0,1 +539,180,0,1,0,1 +540,180,0,1,0,1 +541,180,0,1,0,1 +542,180,0,1,0,1 +543,180,0,1,0,1 +544,180,0,1,0,1 +545,180,0,1,0,1 +546,180,0,1,0,1 +547,180,0,1,0,1 +548,180,0,1,0,1 +549,180,0,1,0,1 +550,180,0,1,0,1 +551,180,0,1,0,1 +552,180,0,1,0,1 +553,180,0,1,0,1 +554,180,0,1,0,1 +555,180,0,1,0,1 +556,180,0,1,0,1 +557,180,0,1,0,1 +558,180,0,1,0,1 +559,180,0,1,0,1 +560,180,0,1,0,1 +561,180,0,1,0,1 +562,180,0,1,0,1 +563,180,0,1,0,1 +564,180,0,1,0,1 +565,180,0,1,0,1 +566,180,0,1,0,1 +567,180,0,1,0,1 +568,180,0,1,0,1 +569,180,0,1,0,1 +570,180,0,1,0,1 +571,180,0,1,0,1 +572,180,0,1,0,1 +573,180,0,1,0,1 +574,180,0,1,0,1 +575,180,0,1,0,1 +576,180,0,1,0,1 +577,180,0,1,0,1 +578,180,0,1,0,1 +579,180,0,1,0,1 +580,180,0,1,0,1 +581,180,0,1,0,1 +582,180,0,1,0,1 +583,180,0,1,0,1 +584,180,0,1,0,1 +585,180,0,1,0,1 +586,180,0,1,0,1 +587,180,0,1,0,1 +588,180,0,1,0,1 +589,180,0,1,0,1 +590,180,0,1,0,1 +591,180,0,1,0,1 +592,180,0,1,0,1 +593,180,0,1,0,1 +594,180,0,1,0,1 +595,180,0,1,0,1 +596,180,0,1,0,1 +597,180,0,1,0,1 +598,180,0,1,0,1 +599,180,0,1,0,1 +600,180,0,1,0,1 +601,180,0,1,0,1 +602,180,0,1,0,1 +603,180,0,1,0,1 +604,180,0,1,0,1 +605,180,0,1,0,1 +606,180,0,1,0,1 +607,180,0,1,0,1 +608,180,0,1,0,1 +609,180,0,1,0,1 +610,180,0,1,0,1 +611,180,0,1,0,1 +612,180,0,1,0,1 +613,180,0,1,0,1 +614,180,0,1,0,1 +615,180,0,1,0,1 +616,180,0,1,0,1 +617,180,0,1,0,1 +618,180,0,1,0,1 +619,180,0,1,0,1 +620,180,0,1,0,1 +621,180,0,1,0,1 +622,180,0,1,0,1 +623,180,0,1,0,1 +624,180,0,1,0,1 +625,180,0,1,0,1 +626,180,0,1,0,1 +627,180,0,1,0,1 +628,180,0,1,0,1 +629,180,0,1,0,1 +630,180,0,1,0,1 +631,180,0,1,0,1 +632,180,0,1,0,1 +633,180,0,1,0,1 +634,180,0,1,0,1 +635,180,0,1,0,1 +636,180,0,1,0,1 +637,180,0,1,0,1 +638,180,0,1,0,1 +639,180,0,1,0,1 +640,180,0,1,0,1 +641,180,0,1,0,1 +642,180,0,1,0,1 +643,180,0,1,0,1 +644,180,0,1,0,1 +645,180,0,1,0,1 +646,180,0,1,0,1 +647,180,0,1,0,1 +648,180,0,1,0,1 +649,180,0,1,0,1 +650,180,0,1,0,1 +651,180,0,1,0,1 +652,180,0,1,0,1 +653,180,0,1,0,1 +654,180,0,1,0,1 +655,180,0,1,0,1 +656,180,0,1,0,1 +657,180,0,1,0,1 +658,180,0,1,0,1 +659,180,0,1,0,1 +660,180,0,1,0,1 +661,180,0,1,0,1 +662,180,0,1,0,1 +663,180,0,1,0,1 +664,180,0,1,0,1 +665,180,0,1,0,1 +666,180,0,1,0,1 +667,180,0,1,0,1 +668,180,0,1,0,1 +669,180,0,1,0,1 +670,180,0,1,0,1 +671,180,0,1,0,1 +672,180,0,1,0,1 +673,180,0,1,0,1 +674,180,0,1,0,1 +675,180,0,1,0,1 +676,180,0,1,0,1 +677,180,0,1,0,1 +678,180,0,1,0,1 +679,180,0,1,0,1 +680,180,0,1,0,1 +681,180,0,1,0,1 +682,180,0,1,0,1 +683,180,0,1,0,1 +684,180,0,1,0,1 +685,180,0,1,0,1 +686,180,0,1,0,1 +687,180,0,1,0,1 +688,180,0,1,0,1 +689,180,0,1,0,1 +690,180,0,1,0,1 +691,180,0,1,0,1 +692,180,0,1,0,1 +693,180,0,1,0,1 +694,180,0,1,0,1 +695,180,0,1,0,1 +696,180,0,1,0,1 +697,180,0,1,0,1 +698,180,0,1,0,1 +699,180,0,1,0,1 +700,180,0,1,0,1 +701,180,0,1,0,1 +702,180,0,1,0,1 +703,180,0,1,0,1 +704,180,0,1,0,1 +705,180,0,1,0,1 +706,180,0,1,0,1 +707,180,0,1,0,1 +708,180,0,1,0,1 +709,180,0,1,0,1 +710,180,0,1,0,1 +711,180,0,1,0,1 +712,180,0,1,0,1 +713,180,0,1,0,1 +714,180,0,1,0,1 +715,180,0,1,0,1 +716,180,0,1,0,1 +717,180,0,1,0,1 +718,180,0,1,0,1 +719,180,0,1,0,1 +720,180,0,1,0,1 +721,180,0,1,0,1 +722,180,0,1,0,1 +723,180,0,1,0,1 +724,180,0,1,0,1 +725,180,0,1,0,1 +726,180,0,1,0,1 +727,180,0,1,0,1 +728,180,0,1,0,1 +729,180,0,1,0,1 +730,180,0,1,0,1 +731,180,0,1,0,1 +732,180,0,1,0,1 +733,180,0,1,0,1 +734,180,0,1,0,1 +735,180,0,1,0,1 +736,180,0,1,0,1 +737,180,0,1,0,1 +738,180,0,1,0,1 +739,180,0,1,0,1 +740,180,0,1,0,1 +741,180,0,1,0,1 +742,180,0,1,0,1 +743,180,0,1,0,1 +744,180,0,1,0,1 +745,180,0,1,0,1 +746,180,0,1,0,1 +747,180,0,1,0,1 +748,180,0,1,0,1 +749,180,0,1,0,1 diff --git a/scripts/tests/data/ism_90a_0e.csv b/scripts/tests/data/ism_90a_0e.csv new file mode 100644 index 0000000000..bcd91364fe --- /dev/null +++ b/scripts/tests/data/ism_90a_0e.csv @@ -0,0 +1,750 @@ +0,90,0,1,0,1 +1,90,0,1,0,1 +2,90,0,1,0,1 +3,90,0,1,0,1 +4,90,0,1,0,1 +5,90,0,1,0,1 +6,90,0,1,0,1 +7,90,0,1,0,1 +8,90,0,1,0,1 +9,90,0,1,0,1 +10,90,0,1,0,1 +11,90,0,1,0,1 +12,90,0,1,0,1 +13,90,0,1,0,1 +14,90,0,1,0,1 +15,90,0,1,0,1 +16,90,0,1,0,1 +17,90,0,1,0,1 +18,90,0,1,0,1 +19,90,0,1,0,1 +20,90,0,1,0,1 +21,90,0,1,0,1 +22,90,0,1,0,1 +23,90,0,1,0,1 +24,90,0,1,0,1 +25,90,0,1,0,1 +26,90,0,1,0,1 +27,90,0,1,0,1 +28,90,0,1,0,1 +29,90,0,1,0,1 +30,90,0,1,0,1 +31,90,0,1,0,1 +32,90,0,1,0,1 +33,90,0,1,0,1 +34,90,0,1,0,1 +35,90,0,1,0,1 +36,90,0,1,0,1 +37,90,0,1,0,1 +38,90,0,1,0,1 +39,90,0,1,0,1 +40,90,0,1,0,1 +41,90,0,1,0,1 +42,90,0,1,0,1 +43,90,0,1,0,1 +44,90,0,1,0,1 +45,90,0,1,0,1 +46,90,0,1,0,1 +47,90,0,1,0,1 +48,90,0,1,0,1 +49,90,0,1,0,1 +50,90,0,1,0,1 +51,90,0,1,0,1 +52,90,0,1,0,1 +53,90,0,1,0,1 +54,90,0,1,0,1 +55,90,0,1,0,1 +56,90,0,1,0,1 +57,90,0,1,0,1 +58,90,0,1,0,1 +59,90,0,1,0,1 +60,90,0,1,0,1 +61,90,0,1,0,1 +62,90,0,1,0,1 +63,90,0,1,0,1 +64,90,0,1,0,1 +65,90,0,1,0,1 +66,90,0,1,0,1 +67,90,0,1,0,1 +68,90,0,1,0,1 +69,90,0,1,0,1 +70,90,0,1,0,1 +71,90,0,1,0,1 +72,90,0,1,0,1 +73,90,0,1,0,1 +74,90,0,1,0,1 +75,90,0,1,0,1 +76,90,0,1,0,1 +77,90,0,1,0,1 +78,90,0,1,0,1 +79,90,0,1,0,1 +80,90,0,1,0,1 +81,90,0,1,0,1 +82,90,0,1,0,1 +83,90,0,1,0,1 +84,90,0,1,0,1 +85,90,0,1,0,1 +86,90,0,1,0,1 +87,90,0,1,0,1 +88,90,0,1,0,1 +89,90,0,1,0,1 +90,90,0,1,0,1 +91,90,0,1,0,1 +92,90,0,1,0,1 +93,90,0,1,0,1 +94,90,0,1,0,1 +95,90,0,1,0,1 +96,90,0,1,0,1 +97,90,0,1,0,1 +98,90,0,1,0,1 +99,90,0,1,0,1 +100,90,0,1,0,1 +101,90,0,1,0,1 +102,90,0,1,0,1 +103,90,0,1,0,1 +104,90,0,1,0,1 +105,90,0,1,0,1 +106,90,0,1,0,1 +107,90,0,1,0,1 +108,90,0,1,0,1 +109,90,0,1,0,1 +110,90,0,1,0,1 +111,90,0,1,0,1 +112,90,0,1,0,1 +113,90,0,1,0,1 +114,90,0,1,0,1 +115,90,0,1,0,1 +116,90,0,1,0,1 +117,90,0,1,0,1 +118,90,0,1,0,1 +119,90,0,1,0,1 +120,90,0,1,0,1 +121,90,0,1,0,1 +122,90,0,1,0,1 +123,90,0,1,0,1 +124,90,0,1,0,1 +125,90,0,1,0,1 +126,90,0,1,0,1 +127,90,0,1,0,1 +128,90,0,1,0,1 +129,90,0,1,0,1 +130,90,0,1,0,1 +131,90,0,1,0,1 +132,90,0,1,0,1 +133,90,0,1,0,1 +134,90,0,1,0,1 +135,90,0,1,0,1 +136,90,0,1,0,1 +137,90,0,1,0,1 +138,90,0,1,0,1 +139,90,0,1,0,1 +140,90,0,1,0,1 +141,90,0,1,0,1 +142,90,0,1,0,1 +143,90,0,1,0,1 +144,90,0,1,0,1 +145,90,0,1,0,1 +146,90,0,1,0,1 +147,90,0,1,0,1 +148,90,0,1,0,1 +149,90,0,1,0,1 +150,90,0,1,0,1 +151,90,0,1,0,1 +152,90,0,1,0,1 +153,90,0,1,0,1 +154,90,0,1,0,1 +155,90,0,1,0,1 +156,90,0,1,0,1 +157,90,0,1,0,1 +158,90,0,1,0,1 +159,90,0,1,0,1 +160,90,0,1,0,1 +161,90,0,1,0,1 +162,90,0,1,0,1 +163,90,0,1,0,1 +164,90,0,1,0,1 +165,90,0,1,0,1 +166,90,0,1,0,1 +167,90,0,1,0,1 +168,90,0,1,0,1 +169,90,0,1,0,1 +170,90,0,1,0,1 +171,90,0,1,0,1 +172,90,0,1,0,1 +173,90,0,1,0,1 +174,90,0,1,0,1 +175,90,0,1,0,1 +176,90,0,1,0,1 +177,90,0,1,0,1 +178,90,0,1,0,1 +179,90,0,1,0,1 +180,90,0,1,0,1 +181,90,0,1,0,1 +182,90,0,1,0,1 +183,90,0,1,0,1 +184,90,0,1,0,1 +185,90,0,1,0,1 +186,90,0,1,0,1 +187,90,0,1,0,1 +188,90,0,1,0,1 +189,90,0,1,0,1 +190,90,0,1,0,1 +191,90,0,1,0,1 +192,90,0,1,0,1 +193,90,0,1,0,1 +194,90,0,1,0,1 +195,90,0,1,0,1 +196,90,0,1,0,1 +197,90,0,1,0,1 +198,90,0,1,0,1 +199,90,0,1,0,1 +200,90,0,1,0,1 +201,90,0,1,0,1 +202,90,0,1,0,1 +203,90,0,1,0,1 +204,90,0,1,0,1 +205,90,0,1,0,1 +206,90,0,1,0,1 +207,90,0,1,0,1 +208,90,0,1,0,1 +209,90,0,1,0,1 +210,90,0,1,0,1 +211,90,0,1,0,1 +212,90,0,1,0,1 +213,90,0,1,0,1 +214,90,0,1,0,1 +215,90,0,1,0,1 +216,90,0,1,0,1 +217,90,0,1,0,1 +218,90,0,1,0,1 +219,90,0,1,0,1 +220,90,0,1,0,1 +221,90,0,1,0,1 +222,90,0,1,0,1 +223,90,0,1,0,1 +224,90,0,1,0,1 +225,90,0,1,0,1 +226,90,0,1,0,1 +227,90,0,1,0,1 +228,90,0,1,0,1 +229,90,0,1,0,1 +230,90,0,1,0,1 +231,90,0,1,0,1 +232,90,0,1,0,1 +233,90,0,1,0,1 +234,90,0,1,0,1 +235,90,0,1,0,1 +236,90,0,1,0,1 +237,90,0,1,0,1 +238,90,0,1,0,1 +239,90,0,1,0,1 +240,90,0,1,0,1 +241,90,0,1,0,1 +242,90,0,1,0,1 +243,90,0,1,0,1 +244,90,0,1,0,1 +245,90,0,1,0,1 +246,90,0,1,0,1 +247,90,0,1,0,1 +248,90,0,1,0,1 +249,90,0,1,0,1 +250,90,0,1,0,1 +251,90,0,1,0,1 +252,90,0,1,0,1 +253,90,0,1,0,1 +254,90,0,1,0,1 +255,90,0,1,0,1 +256,90,0,1,0,1 +257,90,0,1,0,1 +258,90,0,1,0,1 +259,90,0,1,0,1 +260,90,0,1,0,1 +261,90,0,1,0,1 +262,90,0,1,0,1 +263,90,0,1,0,1 +264,90,0,1,0,1 +265,90,0,1,0,1 +266,90,0,1,0,1 +267,90,0,1,0,1 +268,90,0,1,0,1 +269,90,0,1,0,1 +270,90,0,1,0,1 +271,90,0,1,0,1 +272,90,0,1,0,1 +273,90,0,1,0,1 +274,90,0,1,0,1 +275,90,0,1,0,1 +276,90,0,1,0,1 +277,90,0,1,0,1 +278,90,0,1,0,1 +279,90,0,1,0,1 +280,90,0,1,0,1 +281,90,0,1,0,1 +282,90,0,1,0,1 +283,90,0,1,0,1 +284,90,0,1,0,1 +285,90,0,1,0,1 +286,90,0,1,0,1 +287,90,0,1,0,1 +288,90,0,1,0,1 +289,90,0,1,0,1 +290,90,0,1,0,1 +291,90,0,1,0,1 +292,90,0,1,0,1 +293,90,0,1,0,1 +294,90,0,1,0,1 +295,90,0,1,0,1 +296,90,0,1,0,1 +297,90,0,1,0,1 +298,90,0,1,0,1 +299,90,0,1,0,1 +300,90,0,1,0,1 +301,90,0,1,0,1 +302,90,0,1,0,1 +303,90,0,1,0,1 +304,90,0,1,0,1 +305,90,0,1,0,1 +306,90,0,1,0,1 +307,90,0,1,0,1 +308,90,0,1,0,1 +309,90,0,1,0,1 +310,90,0,1,0,1 +311,90,0,1,0,1 +312,90,0,1,0,1 +313,90,0,1,0,1 +314,90,0,1,0,1 +315,90,0,1,0,1 +316,90,0,1,0,1 +317,90,0,1,0,1 +318,90,0,1,0,1 +319,90,0,1,0,1 +320,90,0,1,0,1 +321,90,0,1,0,1 +322,90,0,1,0,1 +323,90,0,1,0,1 +324,90,0,1,0,1 +325,90,0,1,0,1 +326,90,0,1,0,1 +327,90,0,1,0,1 +328,90,0,1,0,1 +329,90,0,1,0,1 +330,90,0,1,0,1 +331,90,0,1,0,1 +332,90,0,1,0,1 +333,90,0,1,0,1 +334,90,0,1,0,1 +335,90,0,1,0,1 +336,90,0,1,0,1 +337,90,0,1,0,1 +338,90,0,1,0,1 +339,90,0,1,0,1 +340,90,0,1,0,1 +341,90,0,1,0,1 +342,90,0,1,0,1 +343,90,0,1,0,1 +344,90,0,1,0,1 +345,90,0,1,0,1 +346,90,0,1,0,1 +347,90,0,1,0,1 +348,90,0,1,0,1 +349,90,0,1,0,1 +350,90,0,1,0,1 +351,90,0,1,0,1 +352,90,0,1,0,1 +353,90,0,1,0,1 +354,90,0,1,0,1 +355,90,0,1,0,1 +356,90,0,1,0,1 +357,90,0,1,0,1 +358,90,0,1,0,1 +359,90,0,1,0,1 +360,90,0,1,0,1 +361,90,0,1,0,1 +362,90,0,1,0,1 +363,90,0,1,0,1 +364,90,0,1,0,1 +365,90,0,1,0,1 +366,90,0,1,0,1 +367,90,0,1,0,1 +368,90,0,1,0,1 +369,90,0,1,0,1 +370,90,0,1,0,1 +371,90,0,1,0,1 +372,90,0,1,0,1 +373,90,0,1,0,1 +374,90,0,1,0,1 +375,90,0,1,0,1 +376,90,0,1,0,1 +377,90,0,1,0,1 +378,90,0,1,0,1 +379,90,0,1,0,1 +380,90,0,1,0,1 +381,90,0,1,0,1 +382,90,0,1,0,1 +383,90,0,1,0,1 +384,90,0,1,0,1 +385,90,0,1,0,1 +386,90,0,1,0,1 +387,90,0,1,0,1 +388,90,0,1,0,1 +389,90,0,1,0,1 +390,90,0,1,0,1 +391,90,0,1,0,1 +392,90,0,1,0,1 +393,90,0,1,0,1 +394,90,0,1,0,1 +395,90,0,1,0,1 +396,90,0,1,0,1 +397,90,0,1,0,1 +398,90,0,1,0,1 +399,90,0,1,0,1 +400,90,0,1,0,1 +401,90,0,1,0,1 +402,90,0,1,0,1 +403,90,0,1,0,1 +404,90,0,1,0,1 +405,90,0,1,0,1 +406,90,0,1,0,1 +407,90,0,1,0,1 +408,90,0,1,0,1 +409,90,0,1,0,1 +410,90,0,1,0,1 +411,90,0,1,0,1 +412,90,0,1,0,1 +413,90,0,1,0,1 +414,90,0,1,0,1 +415,90,0,1,0,1 +416,90,0,1,0,1 +417,90,0,1,0,1 +418,90,0,1,0,1 +419,90,0,1,0,1 +420,90,0,1,0,1 +421,90,0,1,0,1 +422,90,0,1,0,1 +423,90,0,1,0,1 +424,90,0,1,0,1 +425,90,0,1,0,1 +426,90,0,1,0,1 +427,90,0,1,0,1 +428,90,0,1,0,1 +429,90,0,1,0,1 +430,90,0,1,0,1 +431,90,0,1,0,1 +432,90,0,1,0,1 +433,90,0,1,0,1 +434,90,0,1,0,1 +435,90,0,1,0,1 +436,90,0,1,0,1 +437,90,0,1,0,1 +438,90,0,1,0,1 +439,90,0,1,0,1 +440,90,0,1,0,1 +441,90,0,1,0,1 +442,90,0,1,0,1 +443,90,0,1,0,1 +444,90,0,1,0,1 +445,90,0,1,0,1 +446,90,0,1,0,1 +447,90,0,1,0,1 +448,90,0,1,0,1 +449,90,0,1,0,1 +450,90,0,1,0,1 +451,90,0,1,0,1 +452,90,0,1,0,1 +453,90,0,1,0,1 +454,90,0,1,0,1 +455,90,0,1,0,1 +456,90,0,1,0,1 +457,90,0,1,0,1 +458,90,0,1,0,1 +459,90,0,1,0,1 +460,90,0,1,0,1 +461,90,0,1,0,1 +462,90,0,1,0,1 +463,90,0,1,0,1 +464,90,0,1,0,1 +465,90,0,1,0,1 +466,90,0,1,0,1 +467,90,0,1,0,1 +468,90,0,1,0,1 +469,90,0,1,0,1 +470,90,0,1,0,1 +471,90,0,1,0,1 +472,90,0,1,0,1 +473,90,0,1,0,1 +474,90,0,1,0,1 +475,90,0,1,0,1 +476,90,0,1,0,1 +477,90,0,1,0,1 +478,90,0,1,0,1 +479,90,0,1,0,1 +480,90,0,1,0,1 +481,90,0,1,0,1 +482,90,0,1,0,1 +483,90,0,1,0,1 +484,90,0,1,0,1 +485,90,0,1,0,1 +486,90,0,1,0,1 +487,90,0,1,0,1 +488,90,0,1,0,1 +489,90,0,1,0,1 +490,90,0,1,0,1 +491,90,0,1,0,1 +492,90,0,1,0,1 +493,90,0,1,0,1 +494,90,0,1,0,1 +495,90,0,1,0,1 +496,90,0,1,0,1 +497,90,0,1,0,1 +498,90,0,1,0,1 +499,90,0,1,0,1 +500,90,0,1,0,1 +501,90,0,1,0,1 +502,90,0,1,0,1 +503,90,0,1,0,1 +504,90,0,1,0,1 +505,90,0,1,0,1 +506,90,0,1,0,1 +507,90,0,1,0,1 +508,90,0,1,0,1 +509,90,0,1,0,1 +510,90,0,1,0,1 +511,90,0,1,0,1 +512,90,0,1,0,1 +513,90,0,1,0,1 +514,90,0,1,0,1 +515,90,0,1,0,1 +516,90,0,1,0,1 +517,90,0,1,0,1 +518,90,0,1,0,1 +519,90,0,1,0,1 +520,90,0,1,0,1 +521,90,0,1,0,1 +522,90,0,1,0,1 +523,90,0,1,0,1 +524,90,0,1,0,1 +525,90,0,1,0,1 +526,90,0,1,0,1 +527,90,0,1,0,1 +528,90,0,1,0,1 +529,90,0,1,0,1 +530,90,0,1,0,1 +531,90,0,1,0,1 +532,90,0,1,0,1 +533,90,0,1,0,1 +534,90,0,1,0,1 +535,90,0,1,0,1 +536,90,0,1,0,1 +537,90,0,1,0,1 +538,90,0,1,0,1 +539,90,0,1,0,1 +540,90,0,1,0,1 +541,90,0,1,0,1 +542,90,0,1,0,1 +543,90,0,1,0,1 +544,90,0,1,0,1 +545,90,0,1,0,1 +546,90,0,1,0,1 +547,90,0,1,0,1 +548,90,0,1,0,1 +549,90,0,1,0,1 +550,90,0,1,0,1 +551,90,0,1,0,1 +552,90,0,1,0,1 +553,90,0,1,0,1 +554,90,0,1,0,1 +555,90,0,1,0,1 +556,90,0,1,0,1 +557,90,0,1,0,1 +558,90,0,1,0,1 +559,90,0,1,0,1 +560,90,0,1,0,1 +561,90,0,1,0,1 +562,90,0,1,0,1 +563,90,0,1,0,1 +564,90,0,1,0,1 +565,90,0,1,0,1 +566,90,0,1,0,1 +567,90,0,1,0,1 +568,90,0,1,0,1 +569,90,0,1,0,1 +570,90,0,1,0,1 +571,90,0,1,0,1 +572,90,0,1,0,1 +573,90,0,1,0,1 +574,90,0,1,0,1 +575,90,0,1,0,1 +576,90,0,1,0,1 +577,90,0,1,0,1 +578,90,0,1,0,1 +579,90,0,1,0,1 +580,90,0,1,0,1 +581,90,0,1,0,1 +582,90,0,1,0,1 +583,90,0,1,0,1 +584,90,0,1,0,1 +585,90,0,1,0,1 +586,90,0,1,0,1 +587,90,0,1,0,1 +588,90,0,1,0,1 +589,90,0,1,0,1 +590,90,0,1,0,1 +591,90,0,1,0,1 +592,90,0,1,0,1 +593,90,0,1,0,1 +594,90,0,1,0,1 +595,90,0,1,0,1 +596,90,0,1,0,1 +597,90,0,1,0,1 +598,90,0,1,0,1 +599,90,0,1,0,1 +600,90,0,1,0,1 +601,90,0,1,0,1 +602,90,0,1,0,1 +603,90,0,1,0,1 +604,90,0,1,0,1 +605,90,0,1,0,1 +606,90,0,1,0,1 +607,90,0,1,0,1 +608,90,0,1,0,1 +609,90,0,1,0,1 +610,90,0,1,0,1 +611,90,0,1,0,1 +612,90,0,1,0,1 +613,90,0,1,0,1 +614,90,0,1,0,1 +615,90,0,1,0,1 +616,90,0,1,0,1 +617,90,0,1,0,1 +618,90,0,1,0,1 +619,90,0,1,0,1 +620,90,0,1,0,1 +621,90,0,1,0,1 +622,90,0,1,0,1 +623,90,0,1,0,1 +624,90,0,1,0,1 +625,90,0,1,0,1 +626,90,0,1,0,1 +627,90,0,1,0,1 +628,90,0,1,0,1 +629,90,0,1,0,1 +630,90,0,1,0,1 +631,90,0,1,0,1 +632,90,0,1,0,1 +633,90,0,1,0,1 +634,90,0,1,0,1 +635,90,0,1,0,1 +636,90,0,1,0,1 +637,90,0,1,0,1 +638,90,0,1,0,1 +639,90,0,1,0,1 +640,90,0,1,0,1 +641,90,0,1,0,1 +642,90,0,1,0,1 +643,90,0,1,0,1 +644,90,0,1,0,1 +645,90,0,1,0,1 +646,90,0,1,0,1 +647,90,0,1,0,1 +648,90,0,1,0,1 +649,90,0,1,0,1 +650,90,0,1,0,1 +651,90,0,1,0,1 +652,90,0,1,0,1 +653,90,0,1,0,1 +654,90,0,1,0,1 +655,90,0,1,0,1 +656,90,0,1,0,1 +657,90,0,1,0,1 +658,90,0,1,0,1 +659,90,0,1,0,1 +660,90,0,1,0,1 +661,90,0,1,0,1 +662,90,0,1,0,1 +663,90,0,1,0,1 +664,90,0,1,0,1 +665,90,0,1,0,1 +666,90,0,1,0,1 +667,90,0,1,0,1 +668,90,0,1,0,1 +669,90,0,1,0,1 +670,90,0,1,0,1 +671,90,0,1,0,1 +672,90,0,1,0,1 +673,90,0,1,0,1 +674,90,0,1,0,1 +675,90,0,1,0,1 +676,90,0,1,0,1 +677,90,0,1,0,1 +678,90,0,1,0,1 +679,90,0,1,0,1 +680,90,0,1,0,1 +681,90,0,1,0,1 +682,90,0,1,0,1 +683,90,0,1,0,1 +684,90,0,1,0,1 +685,90,0,1,0,1 +686,90,0,1,0,1 +687,90,0,1,0,1 +688,90,0,1,0,1 +689,90,0,1,0,1 +690,90,0,1,0,1 +691,90,0,1,0,1 +692,90,0,1,0,1 +693,90,0,1,0,1 +694,90,0,1,0,1 +695,90,0,1,0,1 +696,90,0,1,0,1 +697,90,0,1,0,1 +698,90,0,1,0,1 +699,90,0,1,0,1 +700,90,0,1,0,1 +701,90,0,1,0,1 +702,90,0,1,0,1 +703,90,0,1,0,1 +704,90,0,1,0,1 +705,90,0,1,0,1 +706,90,0,1,0,1 +707,90,0,1,0,1 +708,90,0,1,0,1 +709,90,0,1,0,1 +710,90,0,1,0,1 +711,90,0,1,0,1 +712,90,0,1,0,1 +713,90,0,1,0,1 +714,90,0,1,0,1 +715,90,0,1,0,1 +716,90,0,1,0,1 +717,90,0,1,0,1 +718,90,0,1,0,1 +719,90,0,1,0,1 +720,90,0,1,0,1 +721,90,0,1,0,1 +722,90,0,1,0,1 +723,90,0,1,0,1 +724,90,0,1,0,1 +725,90,0,1,0,1 +726,90,0,1,0,1 +727,90,0,1,0,1 +728,90,0,1,0,1 +729,90,0,1,0,1 +730,90,0,1,0,1 +731,90,0,1,0,1 +732,90,0,1,0,1 +733,90,0,1,0,1 +734,90,0,1,0,1 +735,90,0,1,0,1 +736,90,0,1,0,1 +737,90,0,1,0,1 +738,90,0,1,0,1 +739,90,0,1,0,1 +740,90,0,1,0,1 +741,90,0,1,0,1 +742,90,0,1,0,1 +743,90,0,1,0,1 +744,90,0,1,0,1 +745,90,0,1,0,1 +746,90,0,1,0,1 +747,90,0,1,0,1 +748,90,0,1,0,1 +749,90,0,1,0,1 diff --git a/scripts/prerenderer_configs/mixed_ivas_mtdt_config.txt b/scripts/tests/data/mixed_ivas_mtdt_config.txt similarity index 93% rename from scripts/prerenderer_configs/mixed_ivas_mtdt_config.txt rename to scripts/tests/data/mixed_ivas_mtdt_config.txt index 851d507f9d..de4d877f73 100644 --- a/scripts/prerenderer_configs/mixed_ivas_mtdt_config.txt +++ b/scripts/tests/data/mixed_ivas_mtdt_config.txt @@ -11,4 +11,4 @@ SBA 1 MC 7 -2 \ No newline at end of file +STEREO diff --git a/scripts/prerenderer_configs/mixed_ivas_mtdt_gain_config.txt b/scripts/tests/data/mixed_ivas_mtdt_gain_config.txt similarity index 95% rename from scripts/prerenderer_configs/mixed_ivas_mtdt_gain_config.txt rename to scripts/tests/data/mixed_ivas_mtdt_gain_config.txt index 3d4e576fcc..fea4161535 100644 --- a/scripts/prerenderer_configs/mixed_ivas_mtdt_gain_config.txt +++ b/scripts/tests/data/mixed_ivas_mtdt_gain_config.txt @@ -13,4 +13,4 @@ SBA gain_dB:0.5 MC 7 -2 \ No newline at end of file +CICP2 diff --git a/scripts/tests/data/mixed_scene.txt b/scripts/tests/data/mixed_scene.txt new file mode 100644 index 0000000000..2501c75383 --- /dev/null +++ b/scripts/tests/data/mixed_scene.txt @@ -0,0 +1,15 @@ +spectral_test_16ch_48kHz.wav +4 +ISM +1 +ism_0a_0e.csv +ISM +2 +1 +1,-30,0 +SBA +3 +1 +MC +7 +5_1_4 diff --git a/scripts/prerenderer_configs/mixed_shorthand_config.txt b/scripts/tests/data/mixed_shorthand_config.txt similarity index 89% rename from scripts/prerenderer_configs/mixed_shorthand_config.txt rename to scripts/tests/data/mixed_shorthand_config.txt index edb510e237..b674960789 100644 --- a/scripts/prerenderer_configs/mixed_shorthand_config.txt +++ b/scripts/tests/data/mixed_shorthand_config.txt @@ -13,4 +13,4 @@ SBA 1 MC 7 -2 \ No newline at end of file +STEREO diff --git a/scripts/prerenderer_configs/mixed_shorthand_gain_config.txt b/scripts/tests/data/mixed_shorthand_gain_config.txt similarity index 91% rename from scripts/prerenderer_configs/mixed_shorthand_gain_config.txt rename to scripts/tests/data/mixed_shorthand_gain_config.txt index b0cd5770a2..cb1c9fa156 100644 --- a/scripts/prerenderer_configs/mixed_shorthand_gain_config.txt +++ b/scripts/tests/data/mixed_shorthand_gain_config.txt @@ -15,4 +15,5 @@ SBA gain_dB:0.5 MC 7 -2 \ No newline at end of file +STEREO + diff --git a/scripts/prerenderer_configs/mixed_shorthand_limiter_config.txt b/scripts/tests/data/mixed_shorthand_limiter_config.txt similarity index 83% rename from scripts/prerenderer_configs/mixed_shorthand_limiter_config.txt rename to scripts/tests/data/mixed_shorthand_limiter_config.txt index 7e39b33737..55bf08aeef 100644 --- a/scripts/prerenderer_configs/mixed_shorthand_limiter_config.txt +++ b/scripts/tests/data/mixed_shorthand_limiter_config.txt @@ -16,5 +16,5 @@ SBA gain_dB:20 MC 7 -2 -gain_dB:20 \ No newline at end of file +STEREO +gain_dB:20 diff --git a/scripts/tests/data/pink_noise_10ch_48kHz.wav b/scripts/tests/data/pink_noise_10ch_48kHz.wav new file mode 100644 index 0000000000..d62a4a2e45 --- /dev/null +++ b/scripts/tests/data/pink_noise_10ch_48kHz.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d91e0bde3e5efd507b50ab9635504918936f406be5655a33859ecc7cce8e6578 +size 960044 diff --git a/scripts/tests/data/pink_noise_11ch_48kHz.wav b/scripts/tests/data/pink_noise_11ch_48kHz.wav new file mode 100644 index 0000000000..1d6de74f3c --- /dev/null +++ b/scripts/tests/data/pink_noise_11ch_48kHz.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:91c84157cb13d5c61493f907e4b38302d1e838a04610e708186e67a066ebb0c2 +size 1056044 diff --git a/scripts/tests/data/pink_noise_12ch_48kHz.wav b/scripts/tests/data/pink_noise_12ch_48kHz.wav new file mode 100644 index 0000000000..a6ec8c67ae --- /dev/null +++ b/scripts/tests/data/pink_noise_12ch_48kHz.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:90ea167b7228a7ec54658bf4d0d61814fbe288bf4e7bd5a72a6ab3ef691f2008 +size 1152044 diff --git a/scripts/tests/data/pink_noise_13ch_48kHz.wav b/scripts/tests/data/pink_noise_13ch_48kHz.wav new file mode 100644 index 0000000000..222397e8e1 --- /dev/null +++ b/scripts/tests/data/pink_noise_13ch_48kHz.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6b3afeddf57940780add178ff098515940556752758f87ac160386ff7125071e +size 1248044 diff --git a/scripts/tests/data/pink_noise_14ch_48kHz.wav b/scripts/tests/data/pink_noise_14ch_48kHz.wav new file mode 100644 index 0000000000..098b57d3dd --- /dev/null +++ b/scripts/tests/data/pink_noise_14ch_48kHz.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c542f1421067546614e47b17715c89d5e705f904faf41bdbd1d439e0abd9e1e0 +size 1344044 diff --git a/scripts/tests/data/pink_noise_15ch_48kHz.wav b/scripts/tests/data/pink_noise_15ch_48kHz.wav new file mode 100644 index 0000000000..f059f92c69 --- /dev/null +++ b/scripts/tests/data/pink_noise_15ch_48kHz.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9becb4e4c271590ead4c898992e593baaf4678887f67153e91a8de87c7b5c3ca +size 1440044 diff --git a/scripts/tests/data/pink_noise_16ch_48kHz.wav b/scripts/tests/data/pink_noise_16ch_48kHz.wav new file mode 100644 index 0000000000..3ee7f71d89 --- /dev/null +++ b/scripts/tests/data/pink_noise_16ch_48kHz.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:90027b3f8b8514bafb2e1dee80a77fc200bafcf45219852b3b7bd97ca60369c2 +size 1536044 diff --git a/scripts/tests/data/pink_noise_1ch_48kHz.wav b/scripts/tests/data/pink_noise_1ch_48kHz.wav new file mode 100644 index 0000000000..5ed1fe6292 --- /dev/null +++ b/scripts/tests/data/pink_noise_1ch_48kHz.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:54ee3a0aa4cbb5295a33fe0637a1854900d2b14813911c7316193cab53b609dc +size 96044 diff --git a/scripts/tests/data/pink_noise_2ch_48kHz.wav b/scripts/tests/data/pink_noise_2ch_48kHz.wav new file mode 100644 index 0000000000..0e0e43f682 --- /dev/null +++ b/scripts/tests/data/pink_noise_2ch_48kHz.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ce34623cf87d56cf5d695e79388d1229f74ba266e0977c18cdf03df174675e3d +size 192044 diff --git a/scripts/tests/data/pink_noise_3ch_48kHz.wav b/scripts/tests/data/pink_noise_3ch_48kHz.wav new file mode 100644 index 0000000000..a9ae37feb4 --- /dev/null +++ b/scripts/tests/data/pink_noise_3ch_48kHz.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:de99e669d4300cd94d3f4966f96ba0f2ca85c40c7cc6cfeb8d09058050ab0909 +size 288044 diff --git a/scripts/tests/data/pink_noise_4ch_48kHz.wav b/scripts/tests/data/pink_noise_4ch_48kHz.wav new file mode 100644 index 0000000000..7881c149f0 --- /dev/null +++ b/scripts/tests/data/pink_noise_4ch_48kHz.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a9310f2e04af7f544f70dfd7360b93c9bafff7e35d9c919e003b27ed549974d8 +size 384044 diff --git a/scripts/tests/data/pink_noise_5ch_48kHz.wav b/scripts/tests/data/pink_noise_5ch_48kHz.wav new file mode 100644 index 0000000000..f99dc847d9 --- /dev/null +++ b/scripts/tests/data/pink_noise_5ch_48kHz.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:be89b959d794e780a04956637d3a6f0128452e54153ad7f54e516b2596b52589 +size 480044 diff --git a/scripts/tests/data/pink_noise_6ch_48kHz.wav b/scripts/tests/data/pink_noise_6ch_48kHz.wav new file mode 100644 index 0000000000..deaea297fe --- /dev/null +++ b/scripts/tests/data/pink_noise_6ch_48kHz.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c6bfe70996dee2eb3bad563eed9bfaf6824449cbec165d666670de2641660b6d +size 576044 diff --git a/scripts/tests/data/pink_noise_7ch_48kHz.wav b/scripts/tests/data/pink_noise_7ch_48kHz.wav new file mode 100644 index 0000000000..70a4cf75da --- /dev/null +++ b/scripts/tests/data/pink_noise_7ch_48kHz.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9e582f2584abdce32381f1f1366c73171f71a08334751c3c6114ec2f49945b2c +size 672044 diff --git a/scripts/tests/data/pink_noise_8ch_48kHz.wav b/scripts/tests/data/pink_noise_8ch_48kHz.wav new file mode 100644 index 0000000000..3b42c83e48 --- /dev/null +++ b/scripts/tests/data/pink_noise_8ch_48kHz.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:418a1cc37dec9dc9a51efd208afe7b6843787e3ed64c86fa69c5780cfb5d3c18 +size 768044 diff --git a/scripts/tests/data/pink_noise_9ch_48kHz.wav b/scripts/tests/data/pink_noise_9ch_48kHz.wav new file mode 100644 index 0000000000..6c5859184d --- /dev/null +++ b/scripts/tests/data/pink_noise_9ch_48kHz.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d1ef5804949cabfb17ce103010ff33c6229e5c6e28d2cd93c7c8c6060a894023 +size 864044 diff --git a/scripts/prerenderer_configs/prerenderer_config_format_readme.txt b/scripts/tests/data/renderer_config_format_readme.txt similarity index 94% rename from scripts/prerenderer_configs/prerenderer_config_format_readme.txt rename to scripts/tests/data/renderer_config_format_readme.txt index 9f78ca4327..790d52bfc5 100644 --- a/scripts/prerenderer_configs/prerenderer_config_format_readme.txt +++ b/scripts/tests/data/renderer_config_format_readme.txt @@ -43,12 +43,8 @@ channel 5 - an object and channels 6-11 - a 5.1 channel bed. The path given must be relative to the location of the config file. -This path has lower priority than the one given on the command line: -* The path in the config file is ignored if the --inputAudio argument to the - pre-renderer executable is specified. -* When running together with the encoder using EVS_cod_prerenderer.sh, the path in - the config file is ignored and the one provided as script argument is used - instead. +This path has lower priority than the one given on the command line: it is +ignored if the --inputAudio argument to the renderer executable is specified. ------------------------------------ Line 2: ------------------------------------ Contains number of inputs. An input can either be an Ambisonics scene, an @@ -78,7 +74,7 @@ Ambisonics order MC Index of the first channel of this input in the multitrack file (1-indexed) -CICP index of the speaker layout +Name of speaker layout (X_Y_Z or CICPx format) ISM Index of this input's audio in the multitrack file (1-indexed) @@ -133,7 +129,7 @@ SBA gain_dB:-6 MC 5 -6 +5_1 ISM 11 2 diff --git a/scripts/tests/data/spectral_test_10ch_48kHz.wav b/scripts/tests/data/spectral_test_10ch_48kHz.wav new file mode 100644 index 0000000000..4f96b5075c --- /dev/null +++ b/scripts/tests/data/spectral_test_10ch_48kHz.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1dff871cc4787b53ef73920e9611938c85ab698024cb58384c29d74eb089cfe0 +size 960080 diff --git a/scripts/tests/data/spectral_test_11ch_48kHz.wav b/scripts/tests/data/spectral_test_11ch_48kHz.wav new file mode 100644 index 0000000000..4406f9e2fa --- /dev/null +++ b/scripts/tests/data/spectral_test_11ch_48kHz.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:79501e014bb57ae483875fd0626b0135d1a3f5273584acd7b8f367a332fc9228 +size 1056044 diff --git a/scripts/tests/data/spectral_test_12ch_48kHz.wav b/scripts/tests/data/spectral_test_12ch_48kHz.wav new file mode 100644 index 0000000000..4ee3e1d862 --- /dev/null +++ b/scripts/tests/data/spectral_test_12ch_48kHz.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:17b2c1303af29e39ff72075b12b58dc0595411711bdcfdf52ebcc30074d1e987 +size 1152080 diff --git a/scripts/tests/data/spectral_test_15ch_48kHz.wav b/scripts/tests/data/spectral_test_15ch_48kHz.wav new file mode 100644 index 0000000000..b74d476014 --- /dev/null +++ b/scripts/tests/data/spectral_test_15ch_48kHz.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7ab7acc0e905b617a3f1053fb1c61e8ac9f4da9c7f22d1290ad4fe457e933b35 +size 1440044 diff --git a/scripts/tests/data/spectral_test_16ch_48kHz.wav b/scripts/tests/data/spectral_test_16ch_48kHz.wav new file mode 100644 index 0000000000..9a367181c9 --- /dev/null +++ b/scripts/tests/data/spectral_test_16ch_48kHz.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0df9a7fc7739481190e8a04bbe31dc352481e362114fcbca827f54b7bc32a9e8 +size 1536080 diff --git a/scripts/tests/data/spectral_test_1ch_48kHz.wav b/scripts/tests/data/spectral_test_1ch_48kHz.wav new file mode 100644 index 0000000000..ae67b5138c --- /dev/null +++ b/scripts/tests/data/spectral_test_1ch_48kHz.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:dd111053f9742063020e4ffb0f2705971ccaa87b5fbb78bb34626e0e3f7742e7 +size 96044 diff --git a/scripts/tests/data/spectral_test_2ch_48kHz.wav b/scripts/tests/data/spectral_test_2ch_48kHz.wav new file mode 100644 index 0000000000..334a479916 --- /dev/null +++ b/scripts/tests/data/spectral_test_2ch_48kHz.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2f612f319abdd28cf859d75ae912364fd73b2b591200e307ab6903c629bc10e4 +size 192044 diff --git a/scripts/tests/data/spectral_test_3ch_48kHz.wav b/scripts/tests/data/spectral_test_3ch_48kHz.wav new file mode 100644 index 0000000000..b68e211f2e --- /dev/null +++ b/scripts/tests/data/spectral_test_3ch_48kHz.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:16559e4b0603e7d1079c9df98fd5763b84194e882b3e6d8086f6ddd6455bbb4f +size 288080 diff --git a/scripts/tests/data/spectral_test_4ch_48kHz.wav b/scripts/tests/data/spectral_test_4ch_48kHz.wav new file mode 100644 index 0000000000..6b9296e281 --- /dev/null +++ b/scripts/tests/data/spectral_test_4ch_48kHz.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:80437a0e2cbb2adb8d9b6ca8a8fab8da229d88af6a14ce64f1cd703f4645bebf +size 384080 diff --git a/scripts/tests/data/spectral_test_5ch_48kHz.wav b/scripts/tests/data/spectral_test_5ch_48kHz.wav new file mode 100644 index 0000000000..f76de9fb58 --- /dev/null +++ b/scripts/tests/data/spectral_test_5ch_48kHz.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:36254bd6bbc80967d9148635286ae9b192c05c31fe8ae0f2c88203cacf1789ce +size 480044 diff --git a/scripts/tests/data/spectral_test_6ch_48kHz.wav b/scripts/tests/data/spectral_test_6ch_48kHz.wav new file mode 100644 index 0000000000..41ed7967c9 --- /dev/null +++ b/scripts/tests/data/spectral_test_6ch_48kHz.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:28c44d1f897897fa8331889ab4de4464f7cee9bd80ea0936f715e4e9860b1c9f +size 576080 diff --git a/scripts/tests/data/spectral_test_8ch_48kHz.wav b/scripts/tests/data/spectral_test_8ch_48kHz.wav new file mode 100644 index 0000000000..6bf42f52fa --- /dev/null +++ b/scripts/tests/data/spectral_test_8ch_48kHz.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:220829574ff2adebece2c38afa607f0e2df00443519c5ffe795ce6db9a329666 +size 768080 diff --git a/scripts/tests/data/spectral_test_9ch_48kHz.wav b/scripts/tests/data/spectral_test_9ch_48kHz.wav new file mode 100644 index 0000000000..5c7d9f2a71 --- /dev/null +++ b/scripts/tests/data/spectral_test_9ch_48kHz.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a99522fe24aa91c8be4cca8aaa9b6817e85bdf3e255f8705dee1b82b4e39dbab +size 864080 diff --git a/scripts/tests/data/spectral_test_ism1.txt b/scripts/tests/data/spectral_test_ism1.txt new file mode 100644 index 0000000000..84b3b25268 --- /dev/null +++ b/scripts/tests/data/spectral_test_ism1.txt @@ -0,0 +1,5 @@ +spectral_test_1ch_48kHz.wav +1 +ISM +1 +stvISM1.csv diff --git a/scripts/tests/data/spectral_test_ism2.txt b/scripts/tests/data/spectral_test_ism2.txt new file mode 100644 index 0000000000..18f3e7a24c --- /dev/null +++ b/scripts/tests/data/spectral_test_ism2.txt @@ -0,0 +1,8 @@ +spectral_test_2ch_48kHz.wav +2 +ISM +1 +stvISM1.csv +ISM +2 +stvISM2.csv diff --git a/scripts/tests/data/spectral_test_ism3.txt b/scripts/tests/data/spectral_test_ism3.txt new file mode 100644 index 0000000000..c25d0d0dff --- /dev/null +++ b/scripts/tests/data/spectral_test_ism3.txt @@ -0,0 +1,11 @@ +spectral_test_3ch_48kHz.wav +3 +ISM +1 +stvISM1.csv +ISM +2 +stvISM2.csv +ISM +3 +stvISM3.csv diff --git a/scripts/tests/data/spectral_test_ism4.txt b/scripts/tests/data/spectral_test_ism4.txt new file mode 100644 index 0000000000..f4a95d1e09 --- /dev/null +++ b/scripts/tests/data/spectral_test_ism4.txt @@ -0,0 +1,14 @@ +spectral_test_4ch_48kHz.wav +4 +ISM +1 +stvISM1.csv +ISM +2 +stvISM2.csv +ISM +3 +stvISM3.csv +ISM +4 +stvISM4.csv diff --git a/scripts/tests/data/stvISM1.csv b/scripts/tests/data/stvISM1.csv new file mode 100644 index 0000000000..574c537028 --- /dev/null +++ b/scripts/tests/data/stvISM1.csv @@ -0,0 +1,1500 @@ +0,0.00,0.00,1.00,0.00,1.00 +1,4.80,0.00,1.00,0.00,1.00 +2,9.60,0.00,1.00,0.00,1.00 +3,14.40,0.00,1.00,0.00,1.00 +4,19.20,0.00,1.00,0.00,1.00 +5,24.00,0.00,1.00,0.00,1.00 +6,28.80,0.00,1.00,0.00,1.00 +7,33.60,0.00,1.00,0.00,1.00 +8,38.40,0.00,1.00,0.00,1.00 +9,43.20,0.00,1.00,0.00,1.00 +10,48.00,0.00,1.00,0.00,1.00 +11,52.80,0.00,1.00,0.00,1.00 +12,57.60,0.00,1.00,0.00,1.00 +13,62.40,0.00,1.00,0.00,1.00 +14,67.20,0.00,1.00,0.00,1.00 +15,72.00,0.00,1.00,0.00,1.00 +16,76.80,0.00,1.00,0.00,1.00 +17,81.60,0.00,1.00,0.00,1.00 +18,86.40,0.00,1.00,0.00,1.00 +19,91.20,0.00,1.00,0.00,1.00 +20,96.00,0.00,1.00,0.00,1.00 +21,100.80,0.00,1.00,0.00,1.00 +22,105.60,0.00,1.00,0.00,1.00 +23,110.40,0.00,1.00,0.00,1.00 +24,115.20,0.00,1.00,0.00,1.00 +25,120.00,0.00,1.00,0.00,1.00 +26,124.80,0.00,1.00,0.00,1.00 +27,129.60,0.00,1.00,0.00,1.00 +28,134.40,0.00,1.00,0.00,1.00 +29,139.20,0.00,1.00,0.00,1.00 +30,144.00,0.00,1.00,0.00,1.00 +31,148.80,0.00,1.00,0.00,1.00 +32,153.60,0.00,1.00,0.00,1.00 +33,158.40,0.00,1.00,0.00,1.00 +34,163.20,0.00,1.00,0.00,1.00 +35,168.00,0.00,1.00,0.00,1.00 +36,172.80,0.00,1.00,0.00,1.00 +37,177.60,0.00,1.00,0.00,1.00 +38,-177.60,0.00,1.00,0.00,1.00 +39,-172.80,0.00,1.00,0.00,1.00 +40,-168.00,0.00,1.00,0.00,1.00 +41,-163.20,0.00,1.00,0.00,1.00 +42,-158.40,0.00,1.00,0.00,1.00 +43,-153.60,0.00,1.00,0.00,1.00 +44,-148.80,0.00,1.00,0.00,1.00 +45,-144.00,0.00,1.00,0.00,1.00 +46,-139.20,0.00,1.00,0.00,1.00 +47,-134.40,0.00,1.00,0.00,1.00 +48,-129.60,0.00,1.00,0.00,1.00 +49,-124.80,0.00,1.00,0.00,1.00 +50,-120.00,0.00,1.00,0.00,1.00 +51,-115.20,0.00,1.00,0.00,1.00 +52,-110.40,0.00,1.00,0.00,1.00 +53,-105.60,0.00,1.00,0.00,1.00 +54,-100.80,0.00,1.00,0.00,1.00 +55,-96.00,0.00,1.00,0.00,1.00 +56,-91.20,0.00,1.00,0.00,1.00 +57,-86.40,0.00,1.00,0.00,1.00 +58,-81.60,0.00,1.00,0.00,1.00 +59,-76.80,0.00,1.00,0.00,1.00 +60,-72.00,0.00,1.00,0.00,1.00 +61,-67.20,0.00,1.00,0.00,1.00 +62,-62.40,0.00,1.00,0.00,1.00 +63,-57.60,0.00,1.00,0.00,1.00 +64,-52.80,0.00,1.00,0.00,1.00 +65,-48.00,0.00,1.00,0.00,1.00 +66,-43.20,0.00,1.00,0.00,1.00 +67,-38.40,0.00,1.00,0.00,1.00 +68,-33.60,0.00,1.00,0.00,1.00 +69,-28.80,0.00,1.00,0.00,1.00 +70,-24.00,0.00,1.00,0.00,1.00 +71,-19.20,0.00,1.00,0.00,1.00 +72,-14.40,0.00,1.00,0.00,1.00 +73,-9.60,0.00,1.00,0.00,1.00 +74,-4.80,0.00,1.00,0.00,1.00 +75,0.00,0.00,1.00,0.00,1.00 +76,4.80,-0.00,1.00,0.00,1.00 +77,9.60,-0.00,1.00,0.00,1.00 +78,14.40,-0.00,1.00,0.00,1.00 +79,19.20,-0.00,1.00,0.00,1.00 +80,24.00,-0.00,1.00,0.00,1.00 +81,28.80,-0.00,1.00,0.00,1.00 +82,33.60,-4.80,1.00,0.00,1.00 +83,38.40,-4.80,1.00,0.00,1.00 +84,43.20,-4.80,1.00,0.00,1.00 +85,48.00,-4.80,1.00,0.00,1.00 +86,52.80,-4.80,1.00,0.00,1.00 +87,57.60,-4.80,1.00,0.00,1.00 +88,62.40,-4.80,1.00,0.00,1.00 +89,67.20,-4.80,1.00,0.00,1.00 +90,72.00,-4.80,1.00,0.00,1.00 +91,76.80,-4.80,1.00,0.00,1.00 +92,81.60,-4.80,1.00,0.00,1.00 +93,86.40,-4.80,1.00,0.00,1.00 +94,91.20,-4.80,1.00,0.00,1.00 +95,96.00,-4.80,1.00,0.00,1.00 +96,100.80,-4.80,1.00,0.00,1.00 +97,105.60,-4.80,1.00,0.00,1.00 +98,110.40,-4.80,1.00,0.00,1.00 +99,115.20,-4.80,1.00,0.00,1.00 +100,120.00,-4.80,1.00,0.00,1.00 +101,124.80,-4.80,1.00,0.00,1.00 +102,129.60,-4.80,1.00,0.00,1.00 +103,134.40,-4.80,1.00,0.00,1.00 +104,139.20,-4.80,1.00,0.00,1.00 +105,144.00,-4.80,1.00,0.00,1.00 +106,148.80,-4.80,1.00,0.00,1.00 +107,153.60,-0.00,1.00,0.00,1.00 +108,158.40,-0.00,1.00,0.00,1.00 +109,163.20,-0.00,1.00,0.00,1.00 +110,168.00,-0.00,1.00,0.00,1.00 +111,172.80,-0.00,1.00,0.00,1.00 +112,177.60,-0.00,1.00,0.00,1.00 +113,-177.60,0.00,1.00,0.00,1.00 +114,-172.80,0.00,1.00,0.00,1.00 +115,-168.00,0.00,1.00,0.00,1.00 +116,-163.20,0.00,1.00,0.00,1.00 +117,-158.40,0.00,1.00,0.00,1.00 +118,-153.60,0.00,1.00,0.00,1.00 +119,-148.80,4.80,1.00,0.00,1.00 +120,-144.00,4.80,1.00,0.00,1.00 +121,-139.20,4.80,1.00,0.00,1.00 +122,-134.40,4.80,1.00,0.00,1.00 +123,-129.60,4.80,1.00,0.00,1.00 +124,-124.80,4.80,1.00,0.00,1.00 +125,-120.00,4.80,1.00,0.00,1.00 +126,-115.20,4.80,1.00,0.00,1.00 +127,-110.40,4.80,1.00,0.00,1.00 +128,-105.60,4.80,1.00,0.00,1.00 +129,-100.80,4.80,1.00,0.00,1.00 +130,-96.00,4.80,1.00,0.00,1.00 +131,-91.20,4.80,1.00,0.00,1.00 +132,-86.40,4.80,1.00,0.00,1.00 +133,-81.60,4.80,1.00,0.00,1.00 +134,-76.80,4.80,1.00,0.00,1.00 +135,-72.00,4.80,1.00,0.00,1.00 +136,-67.20,4.80,1.00,0.00,1.00 +137,-62.40,4.80,1.00,0.00,1.00 +138,-57.60,4.80,1.00,0.00,1.00 +139,-52.80,4.80,1.00,0.00,1.00 +140,-48.00,4.80,1.00,0.00,1.00 +141,-43.20,4.80,1.00,0.00,1.00 +142,-38.40,4.80,1.00,0.00,1.00 +143,-33.60,4.80,1.00,0.00,1.00 +144,-28.80,0.00,1.00,0.00,1.00 +145,-24.00,0.00,1.00,0.00,1.00 +146,-19.20,0.00,1.00,0.00,1.00 +147,-14.40,0.00,1.00,0.00,1.00 +148,-9.60,0.00,1.00,0.00,1.00 +149,-4.80,0.00,1.00,0.00,1.00 +150,0.00,0.00,1.00,0.00,1.00 +151,4.80,-0.00,1.00,0.00,1.00 +152,9.60,-0.00,1.00,0.00,1.00 +153,14.40,-0.00,1.00,0.00,1.00 +154,19.20,-4.80,1.00,0.00,1.00 +155,24.00,-4.80,1.00,0.00,1.00 +156,28.80,-4.80,1.00,0.00,1.00 +157,33.60,-4.80,1.00,0.00,1.00 +158,38.40,-4.80,1.00,0.00,1.00 +159,43.20,-4.80,1.00,0.00,1.00 +160,48.00,-4.80,1.00,0.00,1.00 +161,52.80,-9.60,1.00,0.00,1.00 +162,57.60,-9.60,1.00,0.00,1.00 +163,62.40,-9.60,1.00,0.00,1.00 +164,67.20,-9.60,1.00,0.00,1.00 +165,72.00,-9.60,1.00,0.00,1.00 +166,76.80,-9.60,1.00,0.00,1.00 +167,81.60,-9.60,1.00,0.00,1.00 +168,86.40,-9.60,1.00,0.00,1.00 +169,91.20,-9.60,1.00,0.00,1.00 +170,96.00,-9.60,1.00,0.00,1.00 +171,100.80,-9.60,1.00,0.00,1.00 +172,105.60,-9.60,1.00,0.00,1.00 +173,110.40,-9.60,1.00,0.00,1.00 +174,115.20,-9.60,1.00,0.00,1.00 +175,120.00,-9.60,1.00,0.00,1.00 +176,124.80,-9.60,1.00,0.00,1.00 +177,129.60,-9.60,1.00,0.00,1.00 +178,134.40,-4.80,1.00,0.00,1.00 +179,139.20,-4.80,1.00,0.00,1.00 +180,144.00,-4.80,1.00,0.00,1.00 +181,148.80,-4.80,1.00,0.00,1.00 +182,153.60,-4.80,1.00,0.00,1.00 +183,158.40,-4.80,1.00,0.00,1.00 +184,163.20,-4.80,1.00,0.00,1.00 +185,168.00,-0.00,1.00,0.00,1.00 +186,172.80,-0.00,1.00,0.00,1.00 +187,177.60,-0.00,1.00,0.00,1.00 +188,-177.60,0.00,1.00,0.00,1.00 +189,-172.80,0.00,1.00,0.00,1.00 +190,-168.00,0.00,1.00,0.00,1.00 +191,-163.20,4.80,1.00,0.00,1.00 +192,-158.40,4.80,1.00,0.00,1.00 +193,-153.60,4.80,1.00,0.00,1.00 +194,-148.80,4.80,1.00,0.00,1.00 +195,-144.00,4.80,1.00,0.00,1.00 +196,-139.20,4.80,1.00,0.00,1.00 +197,-134.40,4.80,1.00,0.00,1.00 +198,-129.60,9.60,1.00,0.00,1.00 +199,-124.80,9.60,1.00,0.00,1.00 +200,-120.00,9.60,1.00,0.00,1.00 +201,-115.20,9.60,1.00,0.00,1.00 +202,-110.40,9.60,1.00,0.00,1.00 +203,-105.60,9.60,1.00,0.00,1.00 +204,-100.80,9.60,1.00,0.00,1.00 +205,-96.00,9.60,1.00,0.00,1.00 +206,-91.20,9.60,1.00,0.00,1.00 +207,-86.40,9.60,1.00,0.00,1.00 +208,-81.60,9.60,1.00,0.00,1.00 +209,-76.80,9.60,1.00,0.00,1.00 +210,-72.00,9.60,1.00,0.00,1.00 +211,-67.20,9.60,1.00,0.00,1.00 +212,-62.40,9.60,1.00,0.00,1.00 +213,-57.60,9.60,1.00,0.00,1.00 +214,-52.80,9.60,1.00,0.00,1.00 +215,-48.00,4.80,1.00,0.00,1.00 +216,-43.20,4.80,1.00,0.00,1.00 +217,-38.40,4.80,1.00,0.00,1.00 +218,-33.60,4.80,1.00,0.00,1.00 +219,-28.80,4.80,1.00,0.00,1.00 +220,-24.00,4.80,1.00,0.00,1.00 +221,-19.20,4.80,1.00,0.00,1.00 +222,-14.40,0.00,1.00,0.00,1.00 +223,-9.60,0.00,1.00,0.00,1.00 +224,-4.80,0.00,1.00,0.00,1.00 +225,0.00,0.00,1.00,0.00,1.00 +226,4.80,-0.00,1.00,0.00,1.00 +227,9.60,-0.00,1.00,0.00,1.00 +228,14.40,-4.80,1.00,0.00,1.00 +229,19.20,-4.80,1.00,0.00,1.00 +230,24.00,-4.80,1.00,0.00,1.00 +231,28.80,-4.80,1.00,0.00,1.00 +232,33.60,-9.60,1.00,0.00,1.00 +233,38.40,-9.60,1.00,0.00,1.00 +234,43.20,-9.60,1.00,0.00,1.00 +235,48.00,-9.60,1.00,0.00,1.00 +236,52.80,-9.60,1.00,0.00,1.00 +237,57.60,-14.40,1.00,0.00,1.00 +238,62.40,-14.40,1.00,0.00,1.00 +239,67.20,-14.40,1.00,0.00,1.00 +240,72.00,-14.40,1.00,0.00,1.00 +241,76.80,-14.40,1.00,0.00,1.00 +242,81.60,-14.40,1.00,0.00,1.00 +243,86.40,-14.40,1.00,0.00,1.00 +244,91.20,-14.40,1.00,0.00,1.00 +245,96.00,-14.40,1.00,0.00,1.00 +246,100.80,-14.40,1.00,0.00,1.00 +247,105.60,-14.40,1.00,0.00,1.00 +248,110.40,-14.40,1.00,0.00,1.00 +249,115.20,-14.40,1.00,0.00,1.00 +250,120.00,-14.40,1.00,0.00,1.00 +251,124.80,-9.60,1.00,0.00,1.00 +252,129.60,-9.60,1.00,0.00,1.00 +253,134.40,-9.60,1.00,0.00,1.00 +254,139.20,-9.60,1.00,0.00,1.00 +255,144.00,-9.60,1.00,0.00,1.00 +256,148.80,-9.60,1.00,0.00,1.00 +257,153.60,-4.80,1.00,0.00,1.00 +258,158.40,-4.80,1.00,0.00,1.00 +259,163.20,-4.80,1.00,0.00,1.00 +260,168.00,-4.80,1.00,0.00,1.00 +261,172.80,-0.00,1.00,0.00,1.00 +262,177.60,-0.00,1.00,0.00,1.00 +263,-177.60,0.00,1.00,0.00,1.00 +264,-172.80,0.00,1.00,0.00,1.00 +265,-168.00,4.80,1.00,0.00,1.00 +266,-163.20,4.80,1.00,0.00,1.00 +267,-158.40,4.80,1.00,0.00,1.00 +268,-153.60,4.80,1.00,0.00,1.00 +269,-148.80,9.60,1.00,0.00,1.00 +270,-144.00,9.60,1.00,0.00,1.00 +271,-139.20,9.60,1.00,0.00,1.00 +272,-134.40,9.60,1.00,0.00,1.00 +273,-129.60,9.60,1.00,0.00,1.00 +274,-124.80,9.60,1.00,0.00,1.00 +275,-120.00,14.40,1.00,0.00,1.00 +276,-115.20,14.40,1.00,0.00,1.00 +277,-110.40,14.40,1.00,0.00,1.00 +278,-105.60,14.40,1.00,0.00,1.00 +279,-100.80,14.40,1.00,0.00,1.00 +280,-96.00,14.40,1.00,0.00,1.00 +281,-91.20,14.40,1.00,0.00,1.00 +282,-86.40,14.40,1.00,0.00,1.00 +283,-81.60,14.40,1.00,0.00,1.00 +284,-76.80,14.40,1.00,0.00,1.00 +285,-72.00,14.40,1.00,0.00,1.00 +286,-67.20,14.40,1.00,0.00,1.00 +287,-62.40,14.40,1.00,0.00,1.00 +288,-57.60,14.40,1.00,0.00,1.00 +289,-52.80,9.60,1.00,0.00,1.00 +290,-48.00,9.60,1.00,0.00,1.00 +291,-43.20,9.60,1.00,0.00,1.00 +292,-38.40,9.60,1.00,0.00,1.00 +293,-33.60,9.60,1.00,0.00,1.00 +294,-28.80,4.80,1.00,0.00,1.00 +295,-24.00,4.80,1.00,0.00,1.00 +296,-19.20,4.80,1.00,0.00,1.00 +297,-14.40,4.80,1.00,0.00,1.00 +298,-9.60,0.00,1.00,0.00,1.00 +299,-4.80,0.00,1.00,0.00,1.00 +300,0.00,0.00,1.00,0.00,1.00 +301,4.80,-0.00,1.00,0.00,1.00 +302,9.60,-4.80,1.00,0.00,1.00 +303,14.40,-4.80,1.00,0.00,1.00 +304,19.20,-4.80,1.00,0.00,1.00 +305,24.00,-9.60,1.00,0.00,1.00 +306,28.80,-9.60,1.00,0.00,1.00 +307,33.60,-9.60,1.00,0.00,1.00 +308,38.40,-9.60,1.00,0.00,1.00 +309,43.20,-14.40,1.00,0.00,1.00 +310,48.00,-14.40,1.00,0.00,1.00 +311,52.80,-14.40,1.00,0.00,1.00 +312,57.60,-14.40,1.00,0.00,1.00 +313,62.40,-19.20,1.00,0.00,1.00 +314,67.20,-19.20,1.00,0.00,1.00 +315,72.00,-19.20,1.00,0.00,1.00 +316,76.80,-19.20,1.00,0.00,1.00 +317,81.60,-19.20,1.00,0.00,1.00 +318,86.40,-19.20,1.00,0.00,1.00 +319,91.20,-19.20,1.00,0.00,1.00 +320,96.00,-19.20,1.00,0.00,1.00 +321,100.80,-19.20,1.00,0.00,1.00 +322,105.60,-19.20,1.00,0.00,1.00 +323,110.40,-19.20,1.00,0.00,1.00 +324,115.20,-19.20,1.00,0.00,1.00 +325,120.00,-14.40,1.00,0.00,1.00 +326,124.80,-14.40,1.00,0.00,1.00 +327,129.60,-14.40,1.00,0.00,1.00 +328,134.40,-14.40,1.00,0.00,1.00 +329,139.20,-14.40,1.00,0.00,1.00 +330,144.00,-9.60,1.00,0.00,1.00 +331,148.80,-9.60,1.00,0.00,1.00 +332,153.60,-9.60,1.00,0.00,1.00 +333,158.40,-4.80,1.00,0.00,1.00 +334,163.20,-4.80,1.00,0.00,1.00 +335,168.00,-4.80,1.00,0.00,1.00 +336,172.80,-0.00,1.00,0.00,1.00 +337,177.60,-0.00,1.00,0.00,1.00 +338,-177.60,0.00,1.00,0.00,1.00 +339,-172.80,0.00,1.00,0.00,1.00 +340,-168.00,4.80,1.00,0.00,1.00 +341,-163.20,4.80,1.00,0.00,1.00 +342,-158.40,4.80,1.00,0.00,1.00 +343,-153.60,9.60,1.00,0.00,1.00 +344,-148.80,9.60,1.00,0.00,1.00 +345,-144.00,9.60,1.00,0.00,1.00 +346,-139.20,14.40,1.00,0.00,1.00 +347,-134.40,14.40,1.00,0.00,1.00 +348,-129.60,14.40,1.00,0.00,1.00 +349,-124.80,14.40,1.00,0.00,1.00 +350,-120.00,14.40,1.00,0.00,1.00 +351,-115.20,19.20,1.00,0.00,1.00 +352,-110.40,19.20,1.00,0.00,1.00 +353,-105.60,19.20,1.00,0.00,1.00 +354,-100.80,19.20,1.00,0.00,1.00 +355,-96.00,19.20,1.00,0.00,1.00 +356,-91.20,19.20,1.00,0.00,1.00 +357,-86.40,19.20,1.00,0.00,1.00 +358,-81.60,19.20,1.00,0.00,1.00 +359,-76.80,19.20,1.00,0.00,1.00 +360,-72.00,19.20,1.00,0.00,1.00 +361,-67.20,19.20,1.00,0.00,1.00 +362,-62.40,19.20,1.00,0.00,1.00 +363,-57.60,14.40,1.00,0.00,1.00 +364,-52.80,14.40,1.00,0.00,1.00 +365,-48.00,14.40,1.00,0.00,1.00 +366,-43.20,14.40,1.00,0.00,1.00 +367,-38.40,9.60,1.00,0.00,1.00 +368,-33.60,9.60,1.00,0.00,1.00 +369,-28.80,9.60,1.00,0.00,1.00 +370,-24.00,9.60,1.00,0.00,1.00 +371,-19.20,4.80,1.00,0.00,1.00 +372,-14.40,4.80,1.00,0.00,1.00 +373,-9.60,4.80,1.00,0.00,1.00 +374,-4.80,0.00,1.00,0.00,1.00 +375,0.00,0.00,1.00,0.00,1.00 +376,4.80,-0.00,1.00,0.00,1.00 +377,9.60,-4.80,1.00,0.00,1.00 +378,14.40,-4.80,1.00,0.00,1.00 +379,19.20,-9.60,1.00,0.00,1.00 +380,24.00,-9.60,1.00,0.00,1.00 +381,28.80,-9.60,1.00,0.00,1.00 +382,33.60,-14.40,1.00,0.00,1.00 +383,33.60,-14.40,1.00,0.00,1.00 +384,38.40,-14.40,1.00,0.00,1.00 +385,43.20,-19.20,1.00,0.00,1.00 +386,48.00,-19.20,1.00,0.00,1.00 +387,57.60,-19.20,1.00,0.00,1.00 +388,62.40,-19.20,1.00,0.00,1.00 +389,67.20,-24.00,1.00,0.00,1.00 +390,72.00,-24.00,1.00,0.00,1.00 +391,76.80,-24.00,1.00,0.00,1.00 +392,81.60,-24.00,1.00,0.00,1.00 +393,86.40,-24.00,1.00,0.00,1.00 +394,91.20,-24.00,1.00,0.00,1.00 +395,96.00,-24.00,1.00,0.00,1.00 +396,100.80,-24.00,1.00,0.00,1.00 +397,105.60,-24.00,1.00,0.00,1.00 +398,110.40,-24.00,1.00,0.00,1.00 +399,115.20,-19.20,1.00,0.00,1.00 +400,120.00,-19.20,1.00,0.00,1.00 +401,129.60,-19.20,1.00,0.00,1.00 +402,134.40,-19.20,1.00,0.00,1.00 +403,139.20,-19.20,1.00,0.00,1.00 +404,144.00,-14.40,1.00,0.00,1.00 +405,148.80,-14.40,1.00,0.00,1.00 +406,148.80,-14.40,1.00,0.00,1.00 +407,153.60,-9.60,1.00,0.00,1.00 +408,158.40,-9.60,1.00,0.00,1.00 +409,163.20,-4.80,1.00,0.00,1.00 +410,168.00,-4.80,1.00,0.00,1.00 +411,172.80,-4.80,1.00,0.00,1.00 +412,177.60,-0.00,1.00,0.00,1.00 +413,-177.60,0.00,1.00,0.00,1.00 +414,-172.80,4.80,1.00,0.00,1.00 +415,-168.00,4.80,1.00,0.00,1.00 +416,-163.20,4.80,1.00,0.00,1.00 +417,-158.40,9.60,1.00,0.00,1.00 +418,-153.60,9.60,1.00,0.00,1.00 +419,-148.80,14.40,1.00,0.00,1.00 +420,-148.80,14.40,1.00,0.00,1.00 +421,-144.00,14.40,1.00,0.00,1.00 +422,-139.20,19.20,1.00,0.00,1.00 +423,-134.40,19.20,1.00,0.00,1.00 +424,-129.60,19.20,1.00,0.00,1.00 +425,-120.00,19.20,1.00,0.00,1.00 +426,-115.20,19.20,1.00,0.00,1.00 +427,-110.40,24.00,1.00,0.00,1.00 +428,-105.60,24.00,1.00,0.00,1.00 +429,-100.80,24.00,1.00,0.00,1.00 +430,-96.00,24.00,1.00,0.00,1.00 +431,-91.20,24.00,1.00,0.00,1.00 +432,-86.40,24.00,1.00,0.00,1.00 +433,-81.60,24.00,1.00,0.00,1.00 +434,-76.80,24.00,1.00,0.00,1.00 +435,-72.00,24.00,1.00,0.00,1.00 +436,-67.20,24.00,1.00,0.00,1.00 +437,-62.40,19.20,1.00,0.00,1.00 +438,-57.60,19.20,1.00,0.00,1.00 +439,-48.00,19.20,1.00,0.00,1.00 +440,-43.20,19.20,1.00,0.00,1.00 +441,-38.40,14.40,1.00,0.00,1.00 +442,-33.60,14.40,1.00,0.00,1.00 +443,-33.60,14.40,1.00,0.00,1.00 +444,-28.80,9.60,1.00,0.00,1.00 +445,-24.00,9.60,1.00,0.00,1.00 +446,-19.20,9.60,1.00,0.00,1.00 +447,-14.40,4.80,1.00,0.00,1.00 +448,-9.60,4.80,1.00,0.00,1.00 +449,-4.80,0.00,1.00,0.00,1.00 +450,0.00,0.00,1.00,0.00,1.00 +451,4.80,-0.00,1.00,0.00,1.00 +452,9.60,-4.80,1.00,0.00,1.00 +453,14.40,-4.80,1.00,0.00,1.00 +454,19.20,-9.60,1.00,0.00,1.00 +455,19.20,-9.60,1.00,0.00,1.00 +456,24.00,-14.40,1.00,0.00,1.00 +457,28.80,-14.40,1.00,0.00,1.00 +458,33.60,-19.20,1.00,0.00,1.00 +459,38.40,-19.20,1.00,0.00,1.00 +460,43.20,-19.20,1.00,0.00,1.00 +461,48.00,-24.00,1.00,0.00,1.00 +462,52.80,-24.00,1.00,0.00,1.00 +463,57.60,-24.00,1.00,0.00,1.00 +464,62.40,-24.00,1.00,0.00,1.00 +465,72.00,-28.80,1.00,0.00,1.00 +466,76.80,-28.80,1.00,0.00,1.00 +467,81.60,-28.80,1.00,0.00,1.00 +468,86.40,-28.80,1.00,0.00,1.00 +469,91.20,-28.80,1.00,0.00,1.00 +470,96.00,-28.80,1.00,0.00,1.00 +471,100.80,-28.80,1.00,0.00,1.00 +472,105.60,-28.80,1.00,0.00,1.00 +473,115.20,-28.80,1.00,0.00,1.00 +474,120.00,-24.00,1.00,0.00,1.00 +475,124.80,-24.00,1.00,0.00,1.00 +476,129.60,-24.00,1.00,0.00,1.00 +477,134.40,-24.00,1.00,0.00,1.00 +478,139.20,-19.20,1.00,0.00,1.00 +479,144.00,-19.20,1.00,0.00,1.00 +480,148.80,-14.40,1.00,0.00,1.00 +481,153.60,-14.40,1.00,0.00,1.00 +482,158.40,-14.40,1.00,0.00,1.00 +483,163.20,-9.60,1.00,0.00,1.00 +484,163.20,-9.60,1.00,0.00,1.00 +485,168.00,-4.80,1.00,0.00,1.00 +486,172.80,-4.80,1.00,0.00,1.00 +487,177.60,-0.00,1.00,0.00,1.00 +488,-177.60,0.00,1.00,0.00,1.00 +489,-172.80,4.80,1.00,0.00,1.00 +490,-168.00,4.80,1.00,0.00,1.00 +491,-163.20,9.60,1.00,0.00,1.00 +492,-163.20,9.60,1.00,0.00,1.00 +493,-158.40,14.40,1.00,0.00,1.00 +494,-153.60,14.40,1.00,0.00,1.00 +495,-148.80,14.40,1.00,0.00,1.00 +496,-144.00,19.20,1.00,0.00,1.00 +497,-139.20,19.20,1.00,0.00,1.00 +498,-134.40,24.00,1.00,0.00,1.00 +499,-129.60,24.00,1.00,0.00,1.00 +500,-124.80,24.00,1.00,0.00,1.00 +501,-120.00,24.00,1.00,0.00,1.00 +502,-115.20,28.80,1.00,0.00,1.00 +503,-105.60,28.80,1.00,0.00,1.00 +504,-100.80,28.80,1.00,0.00,1.00 +505,-96.00,28.80,1.00,0.00,1.00 +506,-91.20,28.80,1.00,0.00,1.00 +507,-86.40,28.80,1.00,0.00,1.00 +508,-81.60,28.80,1.00,0.00,1.00 +509,-76.80,28.80,1.00,0.00,1.00 +510,-72.00,28.80,1.00,0.00,1.00 +511,-62.40,24.00,1.00,0.00,1.00 +512,-57.60,24.00,1.00,0.00,1.00 +513,-52.80,24.00,1.00,0.00,1.00 +514,-48.00,24.00,1.00,0.00,1.00 +515,-43.20,19.20,1.00,0.00,1.00 +516,-38.40,19.20,1.00,0.00,1.00 +517,-33.60,19.20,1.00,0.00,1.00 +518,-28.80,14.40,1.00,0.00,1.00 +519,-24.00,14.40,1.00,0.00,1.00 +520,-19.20,9.60,1.00,0.00,1.00 +521,-19.20,9.60,1.00,0.00,1.00 +522,-14.40,4.80,1.00,0.00,1.00 +523,-9.60,4.80,1.00,0.00,1.00 +524,-4.80,0.00,1.00,0.00,1.00 +525,0.00,0.00,1.00,0.00,1.00 +526,4.80,-4.80,1.00,0.00,1.00 +527,9.60,-4.80,1.00,0.00,1.00 +528,14.40,-9.60,1.00,0.00,1.00 +529,14.40,-9.60,1.00,0.00,1.00 +530,19.20,-14.40,1.00,0.00,1.00 +531,24.00,-14.40,1.00,0.00,1.00 +532,28.80,-19.20,1.00,0.00,1.00 +533,33.60,-19.20,1.00,0.00,1.00 +534,38.40,-24.00,1.00,0.00,1.00 +535,43.20,-24.00,1.00,0.00,1.00 +536,48.00,-24.00,1.00,0.00,1.00 +537,52.80,-28.80,1.00,0.00,1.00 +538,57.60,-28.80,1.00,0.00,1.00 +539,62.40,-28.80,1.00,0.00,1.00 +540,67.20,-33.60,1.00,0.00,1.00 +541,72.00,-33.60,1.00,0.00,1.00 +542,81.60,-33.60,1.00,0.00,1.00 +543,86.40,-33.60,1.00,0.00,1.00 +544,91.20,-33.60,1.00,0.00,1.00 +545,96.00,-33.60,1.00,0.00,1.00 +546,100.80,-33.60,1.00,0.00,1.00 +547,110.40,-33.60,1.00,0.00,1.00 +548,115.20,-33.60,1.00,0.00,1.00 +549,120.00,-28.80,1.00,0.00,1.00 +550,124.80,-28.80,1.00,0.00,1.00 +551,129.60,-28.80,1.00,0.00,1.00 +552,134.40,-24.00,1.00,0.00,1.00 +553,139.20,-24.00,1.00,0.00,1.00 +554,144.00,-19.20,1.00,0.00,1.00 +555,148.80,-19.20,1.00,0.00,1.00 +556,153.60,-14.40,1.00,0.00,1.00 +557,158.40,-14.40,1.00,0.00,1.00 +558,163.20,-9.60,1.00,0.00,1.00 +559,168.00,-9.60,1.00,0.00,1.00 +560,168.00,-4.80,1.00,0.00,1.00 +561,172.80,-4.80,1.00,0.00,1.00 +562,177.60,-0.00,1.00,0.00,1.00 +563,-177.60,0.00,1.00,0.00,1.00 +564,-172.80,4.80,1.00,0.00,1.00 +565,-168.00,4.80,1.00,0.00,1.00 +566,-168.00,9.60,1.00,0.00,1.00 +567,-163.20,9.60,1.00,0.00,1.00 +568,-158.40,14.40,1.00,0.00,1.00 +569,-153.60,14.40,1.00,0.00,1.00 +570,-148.80,19.20,1.00,0.00,1.00 +571,-144.00,19.20,1.00,0.00,1.00 +572,-139.20,24.00,1.00,0.00,1.00 +573,-134.40,24.00,1.00,0.00,1.00 +574,-129.60,28.80,1.00,0.00,1.00 +575,-124.80,28.80,1.00,0.00,1.00 +576,-120.00,28.80,1.00,0.00,1.00 +577,-115.20,33.60,1.00,0.00,1.00 +578,-110.40,33.60,1.00,0.00,1.00 +579,-100.80,33.60,1.00,0.00,1.00 +580,-96.00,33.60,1.00,0.00,1.00 +581,-91.20,33.60,1.00,0.00,1.00 +582,-86.40,33.60,1.00,0.00,1.00 +583,-81.60,33.60,1.00,0.00,1.00 +584,-72.00,33.60,1.00,0.00,1.00 +585,-67.20,33.60,1.00,0.00,1.00 +586,-62.40,28.80,1.00,0.00,1.00 +587,-57.60,28.80,1.00,0.00,1.00 +588,-52.80,28.80,1.00,0.00,1.00 +589,-48.00,24.00,1.00,0.00,1.00 +590,-43.20,24.00,1.00,0.00,1.00 +591,-38.40,24.00,1.00,0.00,1.00 +592,-33.60,19.20,1.00,0.00,1.00 +593,-28.80,19.20,1.00,0.00,1.00 +594,-24.00,14.40,1.00,0.00,1.00 +595,-19.20,14.40,1.00,0.00,1.00 +596,-14.40,9.60,1.00,0.00,1.00 +597,-14.40,9.60,1.00,0.00,1.00 +598,-9.60,4.80,1.00,0.00,1.00 +599,-4.80,4.80,1.00,0.00,1.00 +600,0.00,0.00,1.00,0.00,1.00 +601,4.80,-4.80,1.00,0.00,1.00 +602,9.60,-4.80,1.00,0.00,1.00 +603,9.60,-9.60,1.00,0.00,1.00 +604,14.40,-9.60,1.00,0.00,1.00 +605,19.20,-14.40,1.00,0.00,1.00 +606,24.00,-19.20,1.00,0.00,1.00 +607,28.80,-19.20,1.00,0.00,1.00 +608,33.60,-24.00,1.00,0.00,1.00 +609,38.40,-24.00,1.00,0.00,1.00 +610,43.20,-28.80,1.00,0.00,1.00 +611,48.00,-28.80,1.00,0.00,1.00 +612,52.80,-33.60,1.00,0.00,1.00 +613,57.60,-33.60,1.00,0.00,1.00 +614,62.40,-33.60,1.00,0.00,1.00 +615,67.20,-38.40,1.00,0.00,1.00 +616,72.00,-38.40,1.00,0.00,1.00 +617,81.60,-38.40,1.00,0.00,1.00 +618,86.40,-38.40,1.00,0.00,1.00 +619,91.20,-38.40,1.00,0.00,1.00 +620,96.00,-38.40,1.00,0.00,1.00 +621,105.60,-38.40,1.00,0.00,1.00 +622,110.40,-38.40,1.00,0.00,1.00 +623,115.20,-33.60,1.00,0.00,1.00 +624,120.00,-33.60,1.00,0.00,1.00 +625,124.80,-33.60,1.00,0.00,1.00 +626,129.60,-28.80,1.00,0.00,1.00 +627,134.40,-28.80,1.00,0.00,1.00 +628,139.20,-24.00,1.00,0.00,1.00 +629,144.00,-24.00,1.00,0.00,1.00 +630,148.80,-19.20,1.00,0.00,1.00 +631,153.60,-19.20,1.00,0.00,1.00 +632,158.40,-14.40,1.00,0.00,1.00 +633,163.20,-14.40,1.00,0.00,1.00 +634,168.00,-9.60,1.00,0.00,1.00 +635,172.80,-9.60,1.00,0.00,1.00 +636,172.80,-4.80,1.00,0.00,1.00 +637,177.60,-0.00,1.00,0.00,1.00 +638,-177.60,0.00,1.00,0.00,1.00 +639,-172.80,4.80,1.00,0.00,1.00 +640,-172.80,9.60,1.00,0.00,1.00 +641,-168.00,9.60,1.00,0.00,1.00 +642,-163.20,14.40,1.00,0.00,1.00 +643,-158.40,14.40,1.00,0.00,1.00 +644,-153.60,19.20,1.00,0.00,1.00 +645,-148.80,19.20,1.00,0.00,1.00 +646,-144.00,24.00,1.00,0.00,1.00 +647,-139.20,24.00,1.00,0.00,1.00 +648,-134.40,28.80,1.00,0.00,1.00 +649,-129.60,28.80,1.00,0.00,1.00 +650,-124.80,33.60,1.00,0.00,1.00 +651,-120.00,33.60,1.00,0.00,1.00 +652,-115.20,33.60,1.00,0.00,1.00 +653,-110.40,38.40,1.00,0.00,1.00 +654,-105.60,38.40,1.00,0.00,1.00 +655,-96.00,38.40,1.00,0.00,1.00 +656,-91.20,38.40,1.00,0.00,1.00 +657,-86.40,38.40,1.00,0.00,1.00 +658,-81.60,38.40,1.00,0.00,1.00 +659,-72.00,38.40,1.00,0.00,1.00 +660,-67.20,38.40,1.00,0.00,1.00 +661,-62.40,33.60,1.00,0.00,1.00 +662,-57.60,33.60,1.00,0.00,1.00 +663,-52.80,33.60,1.00,0.00,1.00 +664,-48.00,28.80,1.00,0.00,1.00 +665,-43.20,28.80,1.00,0.00,1.00 +666,-38.40,24.00,1.00,0.00,1.00 +667,-33.60,24.00,1.00,0.00,1.00 +668,-28.80,19.20,1.00,0.00,1.00 +669,-24.00,19.20,1.00,0.00,1.00 +670,-19.20,14.40,1.00,0.00,1.00 +671,-14.40,9.60,1.00,0.00,1.00 +672,-9.60,9.60,1.00,0.00,1.00 +673,-9.60,4.80,1.00,0.00,1.00 +674,-4.80,4.80,1.00,0.00,1.00 +675,0.00,0.00,1.00,0.00,1.00 +676,4.80,-4.80,1.00,0.00,1.00 +677,4.80,-4.80,1.00,0.00,1.00 +678,9.60,-9.60,1.00,0.00,1.00 +679,14.40,-14.40,1.00,0.00,1.00 +680,19.20,-14.40,1.00,0.00,1.00 +681,24.00,-19.20,1.00,0.00,1.00 +682,24.00,-24.00,1.00,0.00,1.00 +683,28.80,-24.00,1.00,0.00,1.00 +684,33.60,-28.80,1.00,0.00,1.00 +685,38.40,-28.80,1.00,0.00,1.00 +686,43.20,-33.60,1.00,0.00,1.00 +687,48.00,-33.60,1.00,0.00,1.00 +688,52.80,-38.40,1.00,0.00,1.00 +689,62.40,-38.40,1.00,0.00,1.00 +690,67.20,-38.40,1.00,0.00,1.00 +691,72.00,-43.20,1.00,0.00,1.00 +692,76.80,-43.20,1.00,0.00,1.00 +693,86.40,-43.20,1.00,0.00,1.00 +694,91.20,-43.20,1.00,0.00,1.00 +695,96.00,-43.20,1.00,0.00,1.00 +696,105.60,-43.20,1.00,0.00,1.00 +697,110.40,-43.20,1.00,0.00,1.00 +698,115.20,-38.40,1.00,0.00,1.00 +699,124.80,-38.40,1.00,0.00,1.00 +700,129.60,-38.40,1.00,0.00,1.00 +701,134.40,-33.60,1.00,0.00,1.00 +702,139.20,-33.60,1.00,0.00,1.00 +703,144.00,-28.80,1.00,0.00,1.00 +704,148.80,-28.80,1.00,0.00,1.00 +705,153.60,-24.00,1.00,0.00,1.00 +706,158.40,-19.20,1.00,0.00,1.00 +707,158.40,-19.20,1.00,0.00,1.00 +708,163.20,-14.40,1.00,0.00,1.00 +709,168.00,-9.60,1.00,0.00,1.00 +710,172.80,-9.60,1.00,0.00,1.00 +711,172.80,-4.80,1.00,0.00,1.00 +712,177.60,-0.00,1.00,0.00,1.00 +713,-177.60,0.00,1.00,0.00,1.00 +714,-172.80,4.80,1.00,0.00,1.00 +715,-172.80,9.60,1.00,0.00,1.00 +716,-168.00,9.60,1.00,0.00,1.00 +717,-163.20,14.40,1.00,0.00,1.00 +718,-158.40,19.20,1.00,0.00,1.00 +719,-158.40,19.20,1.00,0.00,1.00 +720,-153.60,24.00,1.00,0.00,1.00 +721,-148.80,28.80,1.00,0.00,1.00 +722,-144.00,28.80,1.00,0.00,1.00 +723,-139.20,33.60,1.00,0.00,1.00 +724,-134.40,33.60,1.00,0.00,1.00 +725,-129.60,38.40,1.00,0.00,1.00 +726,-124.80,38.40,1.00,0.00,1.00 +727,-115.20,38.40,1.00,0.00,1.00 +728,-110.40,43.20,1.00,0.00,1.00 +729,-105.60,43.20,1.00,0.00,1.00 +730,-96.00,43.20,1.00,0.00,1.00 +731,-91.20,43.20,1.00,0.00,1.00 +732,-86.40,43.20,1.00,0.00,1.00 +733,-76.80,43.20,1.00,0.00,1.00 +734,-72.00,43.20,1.00,0.00,1.00 +735,-67.20,38.40,1.00,0.00,1.00 +736,-62.40,38.40,1.00,0.00,1.00 +737,-52.80,38.40,1.00,0.00,1.00 +738,-48.00,33.60,1.00,0.00,1.00 +739,-43.20,33.60,1.00,0.00,1.00 +740,-38.40,28.80,1.00,0.00,1.00 +741,-33.60,28.80,1.00,0.00,1.00 +742,-28.80,24.00,1.00,0.00,1.00 +743,-24.00,24.00,1.00,0.00,1.00 +744,-24.00,19.20,1.00,0.00,1.00 +745,-19.20,14.40,1.00,0.00,1.00 +746,-14.40,14.40,1.00,0.00,1.00 +747,-9.60,9.60,1.00,0.00,1.00 +748,-4.80,4.80,1.00,0.00,1.00 +749,-4.80,4.80,1.00,0.00,1.00 +750,0.00,0.00,1.00,0.00,1.00 +751,4.80,-4.80,1.00,0.00,1.00 +752,4.80,-4.80,1.00,0.00,1.00 +753,9.60,-9.60,1.00,0.00,1.00 +754,14.40,-14.40,1.00,0.00,1.00 +755,14.40,-19.20,1.00,0.00,1.00 +756,19.20,-19.20,1.00,0.00,1.00 +757,24.00,-24.00,1.00,0.00,1.00 +758,28.80,-28.80,1.00,0.00,1.00 +759,33.60,-28.80,1.00,0.00,1.00 +760,38.40,-33.60,1.00,0.00,1.00 +761,43.20,-38.40,1.00,0.00,1.00 +762,48.00,-38.40,1.00,0.00,1.00 +763,52.80,-43.20,1.00,0.00,1.00 +764,57.60,-43.20,1.00,0.00,1.00 +765,62.40,-43.20,1.00,0.00,1.00 +766,72.00,-48.00,1.00,0.00,1.00 +767,76.80,-48.00,1.00,0.00,1.00 +768,86.40,-48.00,1.00,0.00,1.00 +769,91.20,-48.00,1.00,0.00,1.00 +770,100.80,-48.00,1.00,0.00,1.00 +771,105.60,-48.00,1.00,0.00,1.00 +772,110.40,-48.00,1.00,0.00,1.00 +773,120.00,-43.20,1.00,0.00,1.00 +774,124.80,-43.20,1.00,0.00,1.00 +775,129.60,-38.40,1.00,0.00,1.00 +776,134.40,-38.40,1.00,0.00,1.00 +777,139.20,-33.60,1.00,0.00,1.00 +778,144.00,-33.60,1.00,0.00,1.00 +779,148.80,-28.80,1.00,0.00,1.00 +780,153.60,-24.00,1.00,0.00,1.00 +781,158.40,-24.00,1.00,0.00,1.00 +782,163.20,-19.20,1.00,0.00,1.00 +783,163.20,-14.40,1.00,0.00,1.00 +784,168.00,-14.40,1.00,0.00,1.00 +785,172.80,-9.60,1.00,0.00,1.00 +786,172.80,-4.80,1.00,0.00,1.00 +787,177.60,-0.00,1.00,0.00,1.00 +788,-177.60,0.00,1.00,0.00,1.00 +789,-172.80,4.80,1.00,0.00,1.00 +790,-172.80,9.60,1.00,0.00,1.00 +791,-168.00,14.40,1.00,0.00,1.00 +792,-163.20,14.40,1.00,0.00,1.00 +793,-163.20,19.20,1.00,0.00,1.00 +794,-158.40,24.00,1.00,0.00,1.00 +795,-153.60,24.00,1.00,0.00,1.00 +796,-148.80,28.80,1.00,0.00,1.00 +797,-144.00,33.60,1.00,0.00,1.00 +798,-139.20,33.60,1.00,0.00,1.00 +799,-134.40,38.40,1.00,0.00,1.00 +800,-129.60,38.40,1.00,0.00,1.00 +801,-124.80,43.20,1.00,0.00,1.00 +802,-120.00,43.20,1.00,0.00,1.00 +803,-110.40,48.00,1.00,0.00,1.00 +804,-105.60,48.00,1.00,0.00,1.00 +805,-100.80,48.00,1.00,0.00,1.00 +806,-91.20,48.00,1.00,0.00,1.00 +807,-86.40,48.00,1.00,0.00,1.00 +808,-76.80,48.00,1.00,0.00,1.00 +809,-72.00,48.00,1.00,0.00,1.00 +810,-62.40,43.20,1.00,0.00,1.00 +811,-57.60,43.20,1.00,0.00,1.00 +812,-52.80,43.20,1.00,0.00,1.00 +813,-48.00,38.40,1.00,0.00,1.00 +814,-43.20,38.40,1.00,0.00,1.00 +815,-38.40,33.60,1.00,0.00,1.00 +816,-33.60,28.80,1.00,0.00,1.00 +817,-28.80,28.80,1.00,0.00,1.00 +818,-24.00,24.00,1.00,0.00,1.00 +819,-19.20,19.20,1.00,0.00,1.00 +820,-14.40,19.20,1.00,0.00,1.00 +821,-14.40,14.40,1.00,0.00,1.00 +822,-9.60,9.60,1.00,0.00,1.00 +823,-4.80,4.80,1.00,0.00,1.00 +824,-4.80,4.80,1.00,0.00,1.00 +825,0.00,0.00,1.00,0.00,1.00 +826,4.80,-4.80,1.00,0.00,1.00 +827,4.80,-9.60,1.00,0.00,1.00 +828,9.60,-9.60,1.00,0.00,1.00 +829,9.60,-14.40,1.00,0.00,1.00 +830,14.40,-19.20,1.00,0.00,1.00 +831,19.20,-24.00,1.00,0.00,1.00 +832,24.00,-24.00,1.00,0.00,1.00 +833,24.00,-28.80,1.00,0.00,1.00 +834,28.80,-33.60,1.00,0.00,1.00 +835,33.60,-38.40,1.00,0.00,1.00 +836,38.40,-38.40,1.00,0.00,1.00 +837,43.20,-43.20,1.00,0.00,1.00 +838,48.00,-43.20,1.00,0.00,1.00 +839,52.80,-48.00,1.00,0.00,1.00 +840,62.40,-48.00,1.00,0.00,1.00 +841,67.20,-52.80,1.00,0.00,1.00 +842,76.80,-52.80,1.00,0.00,1.00 +843,86.40,-52.80,1.00,0.00,1.00 +844,91.20,-52.80,1.00,0.00,1.00 +845,100.80,-52.80,1.00,0.00,1.00 +846,105.60,-52.80,1.00,0.00,1.00 +847,115.20,-48.00,1.00,0.00,1.00 +848,120.00,-48.00,1.00,0.00,1.00 +849,129.60,-48.00,1.00,0.00,1.00 +850,134.40,-43.20,1.00,0.00,1.00 +851,139.20,-43.20,1.00,0.00,1.00 +852,144.00,-38.40,1.00,0.00,1.00 +853,148.80,-33.60,1.00,0.00,1.00 +854,153.60,-33.60,1.00,0.00,1.00 +855,158.40,-28.80,1.00,0.00,1.00 +856,158.40,-24.00,1.00,0.00,1.00 +857,163.20,-19.20,1.00,0.00,1.00 +858,168.00,-19.20,1.00,0.00,1.00 +859,168.00,-14.40,1.00,0.00,1.00 +860,172.80,-9.60,1.00,0.00,1.00 +861,177.60,-4.80,1.00,0.00,1.00 +862,177.60,-0.00,1.00,0.00,1.00 +863,-177.60,0.00,1.00,0.00,1.00 +864,-177.60,4.80,1.00,0.00,1.00 +865,-172.80,9.60,1.00,0.00,1.00 +866,-168.00,14.40,1.00,0.00,1.00 +867,-168.00,19.20,1.00,0.00,1.00 +868,-163.20,19.20,1.00,0.00,1.00 +869,-158.40,24.00,1.00,0.00,1.00 +870,-158.40,28.80,1.00,0.00,1.00 +871,-153.60,33.60,1.00,0.00,1.00 +872,-148.80,33.60,1.00,0.00,1.00 +873,-144.00,38.40,1.00,0.00,1.00 +874,-139.20,43.20,1.00,0.00,1.00 +875,-134.40,43.20,1.00,0.00,1.00 +876,-129.60,48.00,1.00,0.00,1.00 +877,-120.00,48.00,1.00,0.00,1.00 +878,-115.20,48.00,1.00,0.00,1.00 +879,-105.60,52.80,1.00,0.00,1.00 +880,-100.80,52.80,1.00,0.00,1.00 +881,-91.20,52.80,1.00,0.00,1.00 +882,-86.40,52.80,1.00,0.00,1.00 +883,-76.80,52.80,1.00,0.00,1.00 +884,-67.20,52.80,1.00,0.00,1.00 +885,-62.40,48.00,1.00,0.00,1.00 +886,-52.80,48.00,1.00,0.00,1.00 +887,-48.00,43.20,1.00,0.00,1.00 +888,-43.20,43.20,1.00,0.00,1.00 +889,-38.40,38.40,1.00,0.00,1.00 +890,-33.60,38.40,1.00,0.00,1.00 +891,-28.80,33.60,1.00,0.00,1.00 +892,-24.00,28.80,1.00,0.00,1.00 +893,-24.00,24.00,1.00,0.00,1.00 +894,-19.20,24.00,1.00,0.00,1.00 +895,-14.40,19.20,1.00,0.00,1.00 +896,-9.60,14.40,1.00,0.00,1.00 +897,-9.60,9.60,1.00,0.00,1.00 +898,-4.80,9.60,1.00,0.00,1.00 +899,-4.80,4.80,1.00,0.00,1.00 +900,0.00,0.00,1.00,0.00,1.00 +901,4.80,-4.80,1.00,0.00,1.00 +902,4.80,-9.60,1.00,0.00,1.00 +903,9.60,-14.40,1.00,0.00,1.00 +904,9.60,-14.40,1.00,0.00,1.00 +905,14.40,-19.20,1.00,0.00,1.00 +906,14.40,-24.00,1.00,0.00,1.00 +907,19.20,-28.80,1.00,0.00,1.00 +908,24.00,-33.60,1.00,0.00,1.00 +909,28.80,-33.60,1.00,0.00,1.00 +910,28.80,-38.40,1.00,0.00,1.00 +911,33.60,-43.20,1.00,0.00,1.00 +912,38.40,-43.20,1.00,0.00,1.00 +913,48.00,-48.00,1.00,0.00,1.00 +914,52.80,-52.80,1.00,0.00,1.00 +915,57.60,-52.80,1.00,0.00,1.00 +916,67.20,-57.60,1.00,0.00,1.00 +917,76.80,-57.60,1.00,0.00,1.00 +918,81.60,-57.60,1.00,0.00,1.00 +919,91.20,-57.60,1.00,0.00,1.00 +920,100.80,-57.60,1.00,0.00,1.00 +921,110.40,-57.60,1.00,0.00,1.00 +922,115.20,-52.80,1.00,0.00,1.00 +923,124.80,-52.80,1.00,0.00,1.00 +924,129.60,-48.00,1.00,0.00,1.00 +925,139.20,-48.00,1.00,0.00,1.00 +926,144.00,-43.20,1.00,0.00,1.00 +927,148.80,-38.40,1.00,0.00,1.00 +928,153.60,-38.40,1.00,0.00,1.00 +929,153.60,-33.60,1.00,0.00,1.00 +930,158.40,-28.80,1.00,0.00,1.00 +931,163.20,-24.00,1.00,0.00,1.00 +932,163.20,-24.00,1.00,0.00,1.00 +933,168.00,-19.20,1.00,0.00,1.00 +934,172.80,-14.40,1.00,0.00,1.00 +935,172.80,-9.60,1.00,0.00,1.00 +936,177.60,-4.80,1.00,0.00,1.00 +937,177.60,-0.00,1.00,0.00,1.00 +938,-177.60,0.00,1.00,0.00,1.00 +939,-177.60,4.80,1.00,0.00,1.00 +940,-172.80,9.60,1.00,0.00,1.00 +941,-172.80,14.40,1.00,0.00,1.00 +942,-168.00,19.20,1.00,0.00,1.00 +943,-163.20,24.00,1.00,0.00,1.00 +944,-163.20,24.00,1.00,0.00,1.00 +945,-158.40,28.80,1.00,0.00,1.00 +946,-153.60,33.60,1.00,0.00,1.00 +947,-153.60,38.40,1.00,0.00,1.00 +948,-148.80,38.40,1.00,0.00,1.00 +949,-144.00,43.20,1.00,0.00,1.00 +950,-139.20,48.00,1.00,0.00,1.00 +951,-129.60,48.00,1.00,0.00,1.00 +952,-124.80,52.80,1.00,0.00,1.00 +953,-115.20,52.80,1.00,0.00,1.00 +954,-110.40,57.60,1.00,0.00,1.00 +955,-100.80,57.60,1.00,0.00,1.00 +956,-91.20,57.60,1.00,0.00,1.00 +957,-81.60,57.60,1.00,0.00,1.00 +958,-76.80,57.60,1.00,0.00,1.00 +959,-67.20,57.60,1.00,0.00,1.00 +960,-57.60,52.80,1.00,0.00,1.00 +961,-52.80,52.80,1.00,0.00,1.00 +962,-48.00,48.00,1.00,0.00,1.00 +963,-38.40,43.20,1.00,0.00,1.00 +964,-33.60,43.20,1.00,0.00,1.00 +965,-28.80,38.40,1.00,0.00,1.00 +966,-28.80,33.60,1.00,0.00,1.00 +967,-24.00,33.60,1.00,0.00,1.00 +968,-19.20,28.80,1.00,0.00,1.00 +969,-14.40,24.00,1.00,0.00,1.00 +970,-14.40,19.20,1.00,0.00,1.00 +971,-9.60,14.40,1.00,0.00,1.00 +972,-9.60,14.40,1.00,0.00,1.00 +973,-4.80,9.60,1.00,0.00,1.00 +974,-4.80,4.80,1.00,0.00,1.00 +975,0.00,0.00,1.00,0.00,1.00 +976,0.00,-4.80,1.00,0.00,1.00 +977,4.80,-9.60,1.00,0.00,1.00 +978,4.80,-14.40,1.00,0.00,1.00 +979,9.60,-19.20,1.00,0.00,1.00 +980,9.60,-19.20,1.00,0.00,1.00 +981,14.40,-24.00,1.00,0.00,1.00 +982,19.20,-28.80,1.00,0.00,1.00 +983,19.20,-33.60,1.00,0.00,1.00 +984,24.00,-38.40,1.00,0.00,1.00 +985,28.80,-43.20,1.00,0.00,1.00 +986,33.60,-43.20,1.00,0.00,1.00 +987,38.40,-48.00,1.00,0.00,1.00 +988,43.20,-52.80,1.00,0.00,1.00 +989,48.00,-52.80,1.00,0.00,1.00 +990,52.80,-57.60,1.00,0.00,1.00 +991,62.40,-57.60,1.00,0.00,1.00 +992,72.00,-62.40,1.00,0.00,1.00 +993,81.60,-62.40,1.00,0.00,1.00 +994,91.20,-62.40,1.00,0.00,1.00 +995,100.80,-62.40,1.00,0.00,1.00 +996,110.40,-62.40,1.00,0.00,1.00 +997,120.00,-57.60,1.00,0.00,1.00 +998,129.60,-57.60,1.00,0.00,1.00 +999,134.40,-52.80,1.00,0.00,1.00 +1000,139.20,-48.00,1.00,0.00,1.00 +1001,144.00,-48.00,1.00,0.00,1.00 +1002,148.80,-43.20,1.00,0.00,1.00 +1003,153.60,-38.40,1.00,0.00,1.00 +1004,158.40,-33.60,1.00,0.00,1.00 +1005,163.20,-33.60,1.00,0.00,1.00 +1006,163.20,-28.80,1.00,0.00,1.00 +1007,168.00,-24.00,1.00,0.00,1.00 +1008,168.00,-19.20,1.00,0.00,1.00 +1009,172.80,-14.40,1.00,0.00,1.00 +1010,172.80,-9.60,1.00,0.00,1.00 +1011,177.60,-4.80,1.00,0.00,1.00 +1012,177.60,-0.00,1.00,0.00,1.00 +1013,-177.60,0.00,1.00,0.00,1.00 +1014,-177.60,4.80,1.00,0.00,1.00 +1015,-172.80,9.60,1.00,0.00,1.00 +1016,-172.80,14.40,1.00,0.00,1.00 +1017,-168.00,19.20,1.00,0.00,1.00 +1018,-168.00,24.00,1.00,0.00,1.00 +1019,-163.20,28.80,1.00,0.00,1.00 +1020,-163.20,33.60,1.00,0.00,1.00 +1021,-158.40,33.60,1.00,0.00,1.00 +1022,-153.60,38.40,1.00,0.00,1.00 +1023,-148.80,43.20,1.00,0.00,1.00 +1024,-144.00,48.00,1.00,0.00,1.00 +1025,-139.20,48.00,1.00,0.00,1.00 +1026,-134.40,52.80,1.00,0.00,1.00 +1027,-129.60,57.60,1.00,0.00,1.00 +1028,-120.00,57.60,1.00,0.00,1.00 +1029,-110.40,62.40,1.00,0.00,1.00 +1030,-100.80,62.40,1.00,0.00,1.00 +1031,-91.20,62.40,1.00,0.00,1.00 +1032,-81.60,62.40,1.00,0.00,1.00 +1033,-72.00,62.40,1.00,0.00,1.00 +1034,-62.40,57.60,1.00,0.00,1.00 +1035,-52.80,57.60,1.00,0.00,1.00 +1036,-48.00,52.80,1.00,0.00,1.00 +1037,-43.20,52.80,1.00,0.00,1.00 +1038,-38.40,48.00,1.00,0.00,1.00 +1039,-33.60,43.20,1.00,0.00,1.00 +1040,-28.80,43.20,1.00,0.00,1.00 +1041,-24.00,38.40,1.00,0.00,1.00 +1042,-19.20,33.60,1.00,0.00,1.00 +1043,-19.20,28.80,1.00,0.00,1.00 +1044,-14.40,24.00,1.00,0.00,1.00 +1045,-9.60,19.20,1.00,0.00,1.00 +1046,-9.60,19.20,1.00,0.00,1.00 +1047,-4.80,14.40,1.00,0.00,1.00 +1048,-4.80,9.60,1.00,0.00,1.00 +1049,-0.00,4.80,1.00,0.00,1.00 +1050,0.00,0.00,1.00,0.00,1.00 +1051,0.00,-4.80,1.00,0.00,1.00 +1052,4.80,-9.60,1.00,0.00,1.00 +1053,4.80,-14.40,1.00,0.00,1.00 +1054,9.60,-19.20,1.00,0.00,1.00 +1055,9.60,-24.00,1.00,0.00,1.00 +1056,14.40,-24.00,1.00,0.00,1.00 +1057,14.40,-28.80,1.00,0.00,1.00 +1058,19.20,-33.60,1.00,0.00,1.00 +1059,19.20,-38.40,1.00,0.00,1.00 +1060,24.00,-43.20,1.00,0.00,1.00 +1061,28.80,-48.00,1.00,0.00,1.00 +1062,33.60,-52.80,1.00,0.00,1.00 +1063,38.40,-52.80,1.00,0.00,1.00 +1064,43.20,-57.60,1.00,0.00,1.00 +1065,48.00,-62.40,1.00,0.00,1.00 +1066,57.60,-62.40,1.00,0.00,1.00 +1067,67.20,-67.20,1.00,0.00,1.00 +1068,81.60,-67.20,1.00,0.00,1.00 +1069,91.20,-67.20,1.00,0.00,1.00 +1070,105.60,-67.20,1.00,0.00,1.00 +1071,115.20,-67.20,1.00,0.00,1.00 +1072,124.80,-62.40,1.00,0.00,1.00 +1073,134.40,-57.60,1.00,0.00,1.00 +1074,139.20,-57.60,1.00,0.00,1.00 +1075,144.00,-52.80,1.00,0.00,1.00 +1076,148.80,-48.00,1.00,0.00,1.00 +1077,153.60,-43.20,1.00,0.00,1.00 +1078,158.40,-43.20,1.00,0.00,1.00 +1079,163.20,-38.40,1.00,0.00,1.00 +1080,163.20,-33.60,1.00,0.00,1.00 +1081,168.00,-28.80,1.00,0.00,1.00 +1082,168.00,-24.00,1.00,0.00,1.00 +1083,172.80,-19.20,1.00,0.00,1.00 +1084,172.80,-14.40,1.00,0.00,1.00 +1085,177.60,-9.60,1.00,0.00,1.00 +1086,177.60,-4.80,1.00,0.00,1.00 +1087,177.60,-0.00,1.00,0.00,1.00 +1088,-177.60,0.00,1.00,0.00,1.00 +1089,-177.60,4.80,1.00,0.00,1.00 +1090,-177.60,9.60,1.00,0.00,1.00 +1091,-172.80,14.40,1.00,0.00,1.00 +1092,-172.80,19.20,1.00,0.00,1.00 +1093,-168.00,24.00,1.00,0.00,1.00 +1094,-168.00,28.80,1.00,0.00,1.00 +1095,-163.20,33.60,1.00,0.00,1.00 +1096,-163.20,38.40,1.00,0.00,1.00 +1097,-158.40,43.20,1.00,0.00,1.00 +1098,-153.60,43.20,1.00,0.00,1.00 +1099,-148.80,48.00,1.00,0.00,1.00 +1100,-144.00,52.80,1.00,0.00,1.00 +1101,-139.20,57.60,1.00,0.00,1.00 +1102,-134.40,57.60,1.00,0.00,1.00 +1103,-124.80,62.40,1.00,0.00,1.00 +1104,-115.20,67.20,1.00,0.00,1.00 +1105,-105.60,67.20,1.00,0.00,1.00 +1106,-91.20,67.20,1.00,0.00,1.00 +1107,-81.60,67.20,1.00,0.00,1.00 +1108,-67.20,67.20,1.00,0.00,1.00 +1109,-57.60,62.40,1.00,0.00,1.00 +1110,-48.00,62.40,1.00,0.00,1.00 +1111,-43.20,57.60,1.00,0.00,1.00 +1112,-38.40,52.80,1.00,0.00,1.00 +1113,-33.60,52.80,1.00,0.00,1.00 +1114,-28.80,48.00,1.00,0.00,1.00 +1115,-24.00,43.20,1.00,0.00,1.00 +1116,-19.20,38.40,1.00,0.00,1.00 +1117,-19.20,33.60,1.00,0.00,1.00 +1118,-14.40,28.80,1.00,0.00,1.00 +1119,-14.40,24.00,1.00,0.00,1.00 +1120,-9.60,24.00,1.00,0.00,1.00 +1121,-9.60,19.20,1.00,0.00,1.00 +1122,-4.80,14.40,1.00,0.00,1.00 +1123,-4.80,9.60,1.00,0.00,1.00 +1124,-0.00,4.80,1.00,0.00,1.00 +1125,0.00,0.00,1.00,0.00,1.00 +1126,0.00,-4.80,1.00,0.00,1.00 +1127,4.80,-9.60,1.00,0.00,1.00 +1128,4.80,-14.40,1.00,0.00,1.00 +1129,4.80,-19.20,1.00,0.00,1.00 +1130,9.60,-24.00,1.00,0.00,1.00 +1131,9.60,-28.80,1.00,0.00,1.00 +1132,9.60,-33.60,1.00,0.00,1.00 +1133,14.40,-38.40,1.00,0.00,1.00 +1134,14.40,-38.40,1.00,0.00,1.00 +1135,19.20,-43.20,1.00,0.00,1.00 +1136,24.00,-48.00,1.00,0.00,1.00 +1137,24.00,-52.80,1.00,0.00,1.00 +1138,28.80,-57.60,1.00,0.00,1.00 +1139,38.40,-62.40,1.00,0.00,1.00 +1140,43.20,-62.40,1.00,0.00,1.00 +1141,52.80,-67.20,1.00,0.00,1.00 +1142,62.40,-72.00,1.00,0.00,1.00 +1143,76.80,-72.00,1.00,0.00,1.00 +1144,96.00,-72.00,1.00,0.00,1.00 +1145,110.40,-72.00,1.00,0.00,1.00 +1146,120.00,-67.20,1.00,0.00,1.00 +1147,134.40,-67.20,1.00,0.00,1.00 +1148,139.20,-62.40,1.00,0.00,1.00 +1149,148.80,-57.60,1.00,0.00,1.00 +1150,153.60,-57.60,1.00,0.00,1.00 +1151,158.40,-52.80,1.00,0.00,1.00 +1152,158.40,-48.00,1.00,0.00,1.00 +1153,163.20,-43.20,1.00,0.00,1.00 +1154,163.20,-38.40,1.00,0.00,1.00 +1155,168.00,-33.60,1.00,0.00,1.00 +1156,168.00,-28.80,1.00,0.00,1.00 +1157,172.80,-24.00,1.00,0.00,1.00 +1158,172.80,-19.20,1.00,0.00,1.00 +1159,172.80,-14.40,1.00,0.00,1.00 +1160,177.60,-9.60,1.00,0.00,1.00 +1161,177.60,-4.80,1.00,0.00,1.00 +1162,177.60,-0.00,1.00,0.00,1.00 +1163,-177.60,0.00,1.00,0.00,1.00 +1164,-177.60,4.80,1.00,0.00,1.00 +1165,-177.60,9.60,1.00,0.00,1.00 +1166,-172.80,14.40,1.00,0.00,1.00 +1167,-172.80,19.20,1.00,0.00,1.00 +1168,-172.80,24.00,1.00,0.00,1.00 +1169,-168.00,28.80,1.00,0.00,1.00 +1170,-168.00,33.60,1.00,0.00,1.00 +1171,-163.20,38.40,1.00,0.00,1.00 +1172,-163.20,43.20,1.00,0.00,1.00 +1173,-158.40,48.00,1.00,0.00,1.00 +1174,-158.40,52.80,1.00,0.00,1.00 +1175,-153.60,57.60,1.00,0.00,1.00 +1176,-148.80,57.60,1.00,0.00,1.00 +1177,-139.20,62.40,1.00,0.00,1.00 +1178,-134.40,67.20,1.00,0.00,1.00 +1179,-120.00,67.20,1.00,0.00,1.00 +1180,-110.40,72.00,1.00,0.00,1.00 +1181,-96.00,72.00,1.00,0.00,1.00 +1182,-76.80,72.00,1.00,0.00,1.00 +1183,-62.40,72.00,1.00,0.00,1.00 +1184,-52.80,67.20,1.00,0.00,1.00 +1185,-43.20,62.40,1.00,0.00,1.00 +1186,-38.40,62.40,1.00,0.00,1.00 +1187,-28.80,57.60,1.00,0.00,1.00 +1188,-24.00,52.80,1.00,0.00,1.00 +1189,-24.00,48.00,1.00,0.00,1.00 +1190,-19.20,43.20,1.00,0.00,1.00 +1191,-14.40,38.40,1.00,0.00,1.00 +1192,-14.40,38.40,1.00,0.00,1.00 +1193,-9.60,33.60,1.00,0.00,1.00 +1194,-9.60,28.80,1.00,0.00,1.00 +1195,-9.60,24.00,1.00,0.00,1.00 +1196,-4.80,19.20,1.00,0.00,1.00 +1197,-4.80,14.40,1.00,0.00,1.00 +1198,-4.80,9.60,1.00,0.00,1.00 +1199,-0.00,4.80,1.00,0.00,1.00 +1200,0.00,0.00,1.00,0.00,1.00 +1201,0.00,-4.80,1.00,0.00,1.00 +1202,0.00,-9.60,1.00,0.00,1.00 +1203,4.80,-14.40,1.00,0.00,1.00 +1204,4.80,-19.20,1.00,0.00,1.00 +1205,4.80,-24.00,1.00,0.00,1.00 +1206,4.80,-28.80,1.00,0.00,1.00 +1207,9.60,-33.60,1.00,0.00,1.00 +1208,9.60,-38.40,1.00,0.00,1.00 +1209,14.40,-43.20,1.00,0.00,1.00 +1210,14.40,-48.00,1.00,0.00,1.00 +1211,14.40,-52.80,1.00,0.00,1.00 +1212,19.20,-57.60,1.00,0.00,1.00 +1213,24.00,-57.60,1.00,0.00,1.00 +1214,28.80,-62.40,1.00,0.00,1.00 +1215,33.60,-67.20,1.00,0.00,1.00 +1216,43.20,-72.00,1.00,0.00,1.00 +1217,57.60,-72.00,1.00,0.00,1.00 +1218,76.80,-76.80,1.00,0.00,1.00 +1219,96.00,-76.80,1.00,0.00,1.00 +1220,115.20,-76.80,1.00,0.00,1.00 +1221,129.60,-72.00,1.00,0.00,1.00 +1222,139.20,-72.00,1.00,0.00,1.00 +1223,148.80,-67.20,1.00,0.00,1.00 +1224,153.60,-62.40,1.00,0.00,1.00 +1225,158.40,-57.60,1.00,0.00,1.00 +1226,163.20,-52.80,1.00,0.00,1.00 +1227,163.20,-48.00,1.00,0.00,1.00 +1228,168.00,-43.20,1.00,0.00,1.00 +1229,168.00,-38.40,1.00,0.00,1.00 +1230,172.80,-33.60,1.00,0.00,1.00 +1231,172.80,-28.80,1.00,0.00,1.00 +1232,172.80,-24.00,1.00,0.00,1.00 +1233,172.80,-19.20,1.00,0.00,1.00 +1234,177.60,-14.40,1.00,0.00,1.00 +1235,177.60,-9.60,1.00,0.00,1.00 +1236,177.60,-4.80,1.00,0.00,1.00 +1237,177.60,-0.00,1.00,0.00,1.00 +1238,-177.60,0.00,1.00,0.00,1.00 +1239,-177.60,4.80,1.00,0.00,1.00 +1240,-177.60,9.60,1.00,0.00,1.00 +1241,-177.60,14.40,1.00,0.00,1.00 +1242,-172.80,19.20,1.00,0.00,1.00 +1243,-172.80,24.00,1.00,0.00,1.00 +1244,-172.80,28.80,1.00,0.00,1.00 +1245,-172.80,33.60,1.00,0.00,1.00 +1246,-168.00,38.40,1.00,0.00,1.00 +1247,-168.00,43.20,1.00,0.00,1.00 +1248,-163.20,48.00,1.00,0.00,1.00 +1249,-163.20,52.80,1.00,0.00,1.00 +1250,-158.40,57.60,1.00,0.00,1.00 +1251,-153.60,62.40,1.00,0.00,1.00 +1252,-148.80,67.20,1.00,0.00,1.00 +1253,-139.20,72.00,1.00,0.00,1.00 +1254,-129.60,72.00,1.00,0.00,1.00 +1255,-115.20,76.80,1.00,0.00,1.00 +1256,-96.00,76.80,1.00,0.00,1.00 +1257,-76.80,76.80,1.00,0.00,1.00 +1258,-57.60,72.00,1.00,0.00,1.00 +1259,-43.20,72.00,1.00,0.00,1.00 +1260,-33.60,67.20,1.00,0.00,1.00 +1261,-28.80,62.40,1.00,0.00,1.00 +1262,-24.00,57.60,1.00,0.00,1.00 +1263,-19.20,57.60,1.00,0.00,1.00 +1264,-14.40,52.80,1.00,0.00,1.00 +1265,-14.40,48.00,1.00,0.00,1.00 +1266,-14.40,43.20,1.00,0.00,1.00 +1267,-9.60,38.40,1.00,0.00,1.00 +1268,-9.60,33.60,1.00,0.00,1.00 +1269,-4.80,28.80,1.00,0.00,1.00 +1270,-4.80,24.00,1.00,0.00,1.00 +1271,-4.80,19.20,1.00,0.00,1.00 +1272,-4.80,14.40,1.00,0.00,1.00 +1273,-0.00,9.60,1.00,0.00,1.00 +1274,-0.00,4.80,1.00,0.00,1.00 +1275,0.00,0.00,1.00,0.00,1.00 +1276,0.00,-4.80,1.00,0.00,1.00 +1277,0.00,-9.60,1.00,0.00,1.00 +1278,0.00,-14.40,1.00,0.00,1.00 +1279,4.80,-19.20,1.00,0.00,1.00 +1280,4.80,-24.00,1.00,0.00,1.00 +1281,4.80,-28.80,1.00,0.00,1.00 +1282,4.80,-33.60,1.00,0.00,1.00 +1283,4.80,-38.40,1.00,0.00,1.00 +1284,9.60,-43.20,1.00,0.00,1.00 +1285,9.60,-48.00,1.00,0.00,1.00 +1286,9.60,-52.80,1.00,0.00,1.00 +1287,14.40,-57.60,1.00,0.00,1.00 +1288,14.40,-62.40,1.00,0.00,1.00 +1289,19.20,-67.20,1.00,0.00,1.00 +1290,24.00,-72.00,1.00,0.00,1.00 +1291,33.60,-72.00,1.00,0.00,1.00 +1292,43.20,-76.80,1.00,0.00,1.00 +1293,67.20,-81.60,1.00,0.00,1.00 +1294,96.00,-81.60,1.00,0.00,1.00 +1295,124.80,-81.60,1.00,0.00,1.00 +1296,144.00,-76.80,1.00,0.00,1.00 +1297,153.60,-72.00,1.00,0.00,1.00 +1298,158.40,-67.20,1.00,0.00,1.00 +1299,163.20,-62.40,1.00,0.00,1.00 +1300,168.00,-57.60,1.00,0.00,1.00 +1301,168.00,-52.80,1.00,0.00,1.00 +1302,168.00,-48.00,1.00,0.00,1.00 +1303,172.80,-43.20,1.00,0.00,1.00 +1304,172.80,-38.40,1.00,0.00,1.00 +1305,172.80,-33.60,1.00,0.00,1.00 +1306,172.80,-28.80,1.00,0.00,1.00 +1307,177.60,-24.00,1.00,0.00,1.00 +1308,177.60,-19.20,1.00,0.00,1.00 +1309,177.60,-14.40,1.00,0.00,1.00 +1310,177.60,-9.60,1.00,0.00,1.00 +1311,177.60,-4.80,1.00,0.00,1.00 +1312,177.60,-0.00,1.00,0.00,1.00 +1313,-177.60,0.00,1.00,0.00,1.00 +1314,-177.60,4.80,1.00,0.00,1.00 +1315,-177.60,9.60,1.00,0.00,1.00 +1316,-177.60,14.40,1.00,0.00,1.00 +1317,-177.60,19.20,1.00,0.00,1.00 +1318,-177.60,24.00,1.00,0.00,1.00 +1319,-172.80,28.80,1.00,0.00,1.00 +1320,-172.80,33.60,1.00,0.00,1.00 +1321,-172.80,38.40,1.00,0.00,1.00 +1322,-172.80,43.20,1.00,0.00,1.00 +1323,-168.00,48.00,1.00,0.00,1.00 +1324,-168.00,52.80,1.00,0.00,1.00 +1325,-168.00,57.60,1.00,0.00,1.00 +1326,-163.20,62.40,1.00,0.00,1.00 +1327,-158.40,67.20,1.00,0.00,1.00 +1328,-153.60,72.00,1.00,0.00,1.00 +1329,-144.00,76.80,1.00,0.00,1.00 +1330,-124.80,81.60,1.00,0.00,1.00 +1331,-96.00,81.60,1.00,0.00,1.00 +1332,-67.20,81.60,1.00,0.00,1.00 +1333,-43.20,76.80,1.00,0.00,1.00 +1334,-33.60,72.00,1.00,0.00,1.00 +1335,-24.00,72.00,1.00,0.00,1.00 +1336,-19.20,67.20,1.00,0.00,1.00 +1337,-14.40,62.40,1.00,0.00,1.00 +1338,-14.40,57.60,1.00,0.00,1.00 +1339,-9.60,52.80,1.00,0.00,1.00 +1340,-9.60,48.00,1.00,0.00,1.00 +1341,-9.60,43.20,1.00,0.00,1.00 +1342,-4.80,38.40,1.00,0.00,1.00 +1343,-4.80,33.60,1.00,0.00,1.00 +1344,-4.80,28.80,1.00,0.00,1.00 +1345,-4.80,24.00,1.00,0.00,1.00 +1346,-4.80,19.20,1.00,0.00,1.00 +1347,-0.00,14.40,1.00,0.00,1.00 +1348,-0.00,9.60,1.00,0.00,1.00 +1349,-0.00,4.80,1.00,0.00,1.00 +1350,0.00,0.00,1.00,0.00,1.00 +1351,0.00,-4.80,1.00,0.00,1.00 +1352,0.00,-9.60,1.00,0.00,1.00 +1353,0.00,-14.40,1.00,0.00,1.00 +1354,0.00,-19.20,1.00,0.00,1.00 +1355,0.00,-24.00,1.00,0.00,1.00 +1356,0.00,-28.80,1.00,0.00,1.00 +1357,0.00,-33.60,1.00,0.00,1.00 +1358,4.80,-38.40,1.00,0.00,1.00 +1359,4.80,-43.20,1.00,0.00,1.00 +1360,4.80,-48.00,1.00,0.00,1.00 +1361,4.80,-52.80,1.00,0.00,1.00 +1362,4.80,-57.60,1.00,0.00,1.00 +1363,4.80,-62.40,1.00,0.00,1.00 +1364,9.60,-67.20,1.00,0.00,1.00 +1365,9.60,-72.00,1.00,0.00,1.00 +1366,14.40,-76.80,1.00,0.00,1.00 +1367,24.00,-81.60,1.00,0.00,1.00 +1368,43.20,-86.40,1.00,0.00,1.00 +1369,110.40,-86.40,1.00,0.00,1.00 +1370,148.80,-81.60,1.00,0.00,1.00 +1371,163.20,-76.80,1.00,0.00,1.00 +1372,168.00,-72.00,1.00,0.00,1.00 +1373,172.80,-67.20,1.00,0.00,1.00 +1374,172.80,-62.40,1.00,0.00,1.00 +1375,172.80,-57.60,1.00,0.00,1.00 +1376,172.80,-52.80,1.00,0.00,1.00 +1377,177.60,-48.00,1.00,0.00,1.00 +1378,177.60,-43.20,1.00,0.00,1.00 +1379,177.60,-38.40,1.00,0.00,1.00 +1380,177.60,-33.60,1.00,0.00,1.00 +1381,177.60,-28.80,1.00,0.00,1.00 +1382,177.60,-24.00,1.00,0.00,1.00 +1383,177.60,-19.20,1.00,0.00,1.00 +1384,177.60,-14.40,1.00,0.00,1.00 +1385,177.60,-9.60,1.00,0.00,1.00 +1386,177.60,-4.80,1.00,0.00,1.00 +1387,177.60,-0.00,1.00,0.00,1.00 +1388,-177.60,0.00,1.00,0.00,1.00 +1389,-177.60,4.80,1.00,0.00,1.00 +1390,-177.60,9.60,1.00,0.00,1.00 +1391,-177.60,14.40,1.00,0.00,1.00 +1392,-177.60,19.20,1.00,0.00,1.00 +1393,-177.60,24.00,1.00,0.00,1.00 +1394,-177.60,28.80,1.00,0.00,1.00 +1395,-177.60,33.60,1.00,0.00,1.00 +1396,-177.60,38.40,1.00,0.00,1.00 +1397,-177.60,43.20,1.00,0.00,1.00 +1398,-177.60,48.00,1.00,0.00,1.00 +1399,-172.80,52.80,1.00,0.00,1.00 +1400,-172.80,57.60,1.00,0.00,1.00 +1401,-172.80,62.40,1.00,0.00,1.00 +1402,-172.80,67.20,1.00,0.00,1.00 +1403,-168.00,72.00,1.00,0.00,1.00 +1404,-163.20,76.80,1.00,0.00,1.00 +1405,-148.80,81.60,1.00,0.00,1.00 +1406,-110.40,86.40,1.00,0.00,1.00 +1407,-43.20,86.40,1.00,0.00,1.00 +1408,-24.00,81.60,1.00,0.00,1.00 +1409,-14.40,76.80,1.00,0.00,1.00 +1410,-9.60,72.00,1.00,0.00,1.00 +1411,-9.60,67.20,1.00,0.00,1.00 +1412,-4.80,62.40,1.00,0.00,1.00 +1413,-4.80,57.60,1.00,0.00,1.00 +1414,-4.80,52.80,1.00,0.00,1.00 +1415,-4.80,48.00,1.00,0.00,1.00 +1416,-4.80,43.20,1.00,0.00,1.00 +1417,-4.80,38.40,1.00,0.00,1.00 +1418,-0.00,33.60,1.00,0.00,1.00 +1419,-0.00,28.80,1.00,0.00,1.00 +1420,-0.00,24.00,1.00,0.00,1.00 +1421,-0.00,19.20,1.00,0.00,1.00 +1422,-0.00,14.40,1.00,0.00,1.00 +1423,-0.00,9.60,1.00,0.00,1.00 +1424,-0.00,4.80,1.00,0.00,1.00 +1425,-0.00,0.00,1.00,0.00,1.00 +1426,-0.00,-4.80,1.00,0.00,1.00 +1427,-0.00,-9.60,1.00,0.00,1.00 +1428,-0.00,-14.40,1.00,0.00,1.00 +1429,-0.00,-19.20,1.00,0.00,1.00 +1430,-0.00,-24.00,1.00,0.00,1.00 +1431,-0.00,-28.80,1.00,0.00,1.00 +1432,-0.00,-33.60,1.00,0.00,1.00 +1433,-0.00,-38.40,1.00,0.00,1.00 +1434,-0.00,-43.20,1.00,0.00,1.00 +1435,-0.00,-48.00,1.00,0.00,1.00 +1436,-0.00,-52.80,1.00,0.00,1.00 +1437,-0.00,-57.60,1.00,0.00,1.00 +1438,-0.00,-62.40,1.00,0.00,1.00 +1439,-4.80,-67.20,1.00,0.00,1.00 +1440,-4.80,-72.00,1.00,0.00,1.00 +1441,-4.80,-76.80,1.00,0.00,1.00 +1442,-9.60,-81.60,1.00,0.00,1.00 +1443,-19.20,-86.40,1.00,0.00,1.00 +1444,-134.40,-86.40,1.00,0.00,1.00 +1445,-168.00,-81.60,1.00,0.00,1.00 +1446,-172.80,-76.80,1.00,0.00,1.00 +1447,-177.60,-72.00,1.00,0.00,1.00 +1448,-177.60,-67.20,1.00,0.00,1.00 +1449,-177.60,-62.40,1.00,0.00,1.00 +1450,-177.60,-57.60,1.00,0.00,1.00 +1451,-177.60,-52.80,1.00,0.00,1.00 +1452,-177.60,-48.00,1.00,0.00,1.00 +1453,-177.60,-43.20,1.00,0.00,1.00 +1454,-177.60,-38.40,1.00,0.00,1.00 +1455,-177.60,-33.60,1.00,0.00,1.00 +1456,-177.60,-28.80,1.00,0.00,1.00 +1457,-177.60,-24.00,1.00,0.00,1.00 +1458,-177.60,-19.20,1.00,0.00,1.00 +1459,-177.60,-14.40,1.00,0.00,1.00 +1460,-177.60,-9.60,1.00,0.00,1.00 +1461,-177.60,-4.80,1.00,0.00,1.00 +1462,-177.60,-0.00,1.00,0.00,1.00 +1463,177.60,0.00,1.00,0.00,1.00 +1464,177.60,4.80,1.00,0.00,1.00 +1465,177.60,9.60,1.00,0.00,1.00 +1466,177.60,14.40,1.00,0.00,1.00 +1467,177.60,19.20,1.00,0.00,1.00 +1468,177.60,24.00,1.00,0.00,1.00 +1469,177.60,28.80,1.00,0.00,1.00 +1470,177.60,33.60,1.00,0.00,1.00 +1471,177.60,38.40,1.00,0.00,1.00 +1472,177.60,43.20,1.00,0.00,1.00 +1473,177.60,48.00,1.00,0.00,1.00 +1474,177.60,52.80,1.00,0.00,1.00 +1475,177.60,57.60,1.00,0.00,1.00 +1476,177.60,62.40,1.00,0.00,1.00 +1477,177.60,67.20,1.00,0.00,1.00 +1478,177.60,72.00,1.00,0.00,1.00 +1479,172.80,76.80,1.00,0.00,1.00 +1480,168.00,81.60,1.00,0.00,1.00 +1481,134.40,86.40,1.00,0.00,1.00 +1482,19.20,86.40,1.00,0.00,1.00 +1483,9.60,81.60,1.00,0.00,1.00 +1484,4.80,76.80,1.00,0.00,1.00 +1485,4.80,72.00,1.00,0.00,1.00 +1486,4.80,67.20,1.00,0.00,1.00 +1487,0.00,62.40,1.00,0.00,1.00 +1488,0.00,57.60,1.00,0.00,1.00 +1489,0.00,52.80,1.00,0.00,1.00 +1490,0.00,48.00,1.00,0.00,1.00 +1491,0.00,43.20,1.00,0.00,1.00 +1492,0.00,38.40,1.00,0.00,1.00 +1493,0.00,33.60,1.00,0.00,1.00 +1494,0.00,28.80,1.00,0.00,1.00 +1495,0.00,24.00,1.00,0.00,1.00 +1496,0.00,19.20,1.00,0.00,1.00 +1497,0.00,14.40,1.00,0.00,1.00 +1498,0.00,9.60,1.00,0.00,1.00 +1499,0.00,4.80,1.00,0.00,1.00 diff --git a/scripts/tests/data/stvISM2.csv b/scripts/tests/data/stvISM2.csv new file mode 100644 index 0000000000..9fd14fdf63 --- /dev/null +++ b/scripts/tests/data/stvISM2.csv @@ -0,0 +1,1500 @@ +0,0.00,4.80,1.00,0.00,1.00 +1,0.00,9.60,1.00,0.00,1.00 +2,0.00,14.40,1.00,0.00,1.00 +3,0.00,19.20,1.00,0.00,1.00 +4,0.00,24.00,1.00,0.00,1.00 +5,0.00,28.80,1.00,0.00,1.00 +6,0.00,33.60,1.00,0.00,1.00 +7,0.00,38.40,1.00,0.00,1.00 +8,0.00,43.20,1.00,0.00,1.00 +9,0.00,48.00,1.00,0.00,1.00 +10,0.00,52.80,1.00,0.00,1.00 +11,0.00,57.60,1.00,0.00,1.00 +12,0.00,62.40,1.00,0.00,1.00 +13,4.80,67.20,1.00,0.00,1.00 +14,4.80,72.00,1.00,0.00,1.00 +15,4.80,76.80,1.00,0.00,1.00 +16,9.60,81.60,1.00,0.00,1.00 +17,19.20,86.40,1.00,0.00,1.00 +18,134.40,86.40,1.00,0.00,1.00 +19,168.00,81.60,1.00,0.00,1.00 +20,172.80,76.80,1.00,0.00,1.00 +21,177.60,72.00,1.00,0.00,1.00 +22,177.60,67.20,1.00,0.00,1.00 +23,177.60,62.40,1.00,0.00,1.00 +24,177.60,57.60,1.00,0.00,1.00 +25,177.60,52.80,1.00,0.00,1.00 +26,177.60,48.00,1.00,0.00,1.00 +27,177.60,43.20,1.00,0.00,1.00 +28,177.60,38.40,1.00,0.00,1.00 +29,177.60,33.60,1.00,0.00,1.00 +30,177.60,28.80,1.00,0.00,1.00 +31,177.60,24.00,1.00,0.00,1.00 +32,177.60,19.20,1.00,0.00,1.00 +33,177.60,14.40,1.00,0.00,1.00 +34,177.60,9.60,1.00,0.00,1.00 +35,177.60,4.80,1.00,0.00,1.00 +36,177.60,0.00,1.00,0.00,1.00 +37,-177.60,-0.00,1.00,0.00,1.00 +38,-177.60,-4.80,1.00,0.00,1.00 +39,-177.60,-9.60,1.00,0.00,1.00 +40,-177.60,-14.40,1.00,0.00,1.00 +41,-177.60,-19.20,1.00,0.00,1.00 +42,-177.60,-24.00,1.00,0.00,1.00 +43,-177.60,-28.80,1.00,0.00,1.00 +44,-177.60,-33.60,1.00,0.00,1.00 +45,-177.60,-38.40,1.00,0.00,1.00 +46,-177.60,-43.20,1.00,0.00,1.00 +47,-177.60,-48.00,1.00,0.00,1.00 +48,-177.60,-52.80,1.00,0.00,1.00 +49,-177.60,-57.60,1.00,0.00,1.00 +50,-177.60,-62.40,1.00,0.00,1.00 +51,-177.60,-67.20,1.00,0.00,1.00 +52,-177.60,-72.00,1.00,0.00,1.00 +53,-172.80,-76.80,1.00,0.00,1.00 +54,-168.00,-81.60,1.00,0.00,1.00 +55,-134.40,-86.40,1.00,0.00,1.00 +56,-19.20,-86.40,1.00,0.00,1.00 +57,-9.60,-81.60,1.00,0.00,1.00 +58,-4.80,-76.80,1.00,0.00,1.00 +59,-4.80,-72.00,1.00,0.00,1.00 +60,-4.80,-67.20,1.00,0.00,1.00 +61,-0.00,-62.40,1.00,0.00,1.00 +62,-0.00,-57.60,1.00,0.00,1.00 +63,-0.00,-52.80,1.00,0.00,1.00 +64,-0.00,-48.00,1.00,0.00,1.00 +65,-0.00,-43.20,1.00,0.00,1.00 +66,-0.00,-38.40,1.00,0.00,1.00 +67,-0.00,-33.60,1.00,0.00,1.00 +68,-0.00,-28.80,1.00,0.00,1.00 +69,-0.00,-24.00,1.00,0.00,1.00 +70,-0.00,-19.20,1.00,0.00,1.00 +71,-0.00,-14.40,1.00,0.00,1.00 +72,-0.00,-9.60,1.00,0.00,1.00 +73,-0.00,-4.80,1.00,0.00,1.00 +74,-0.00,0.00,1.00,0.00,1.00 +75,-0.00,4.80,1.00,0.00,1.00 +76,-0.00,9.60,1.00,0.00,1.00 +77,-0.00,14.40,1.00,0.00,1.00 +78,-0.00,19.20,1.00,0.00,1.00 +79,-0.00,24.00,1.00,0.00,1.00 +80,-0.00,28.80,1.00,0.00,1.00 +81,-0.00,33.60,1.00,0.00,1.00 +82,-4.80,38.40,1.00,0.00,1.00 +83,-4.80,43.20,1.00,0.00,1.00 +84,-4.80,48.00,1.00,0.00,1.00 +85,-4.80,52.80,1.00,0.00,1.00 +86,-4.80,57.60,1.00,0.00,1.00 +87,-4.80,62.40,1.00,0.00,1.00 +88,-9.60,67.20,1.00,0.00,1.00 +89,-9.60,72.00,1.00,0.00,1.00 +90,-14.40,76.80,1.00,0.00,1.00 +91,-24.00,81.60,1.00,0.00,1.00 +92,-43.20,86.40,1.00,0.00,1.00 +93,-110.40,86.40,1.00,0.00,1.00 +94,-148.80,81.60,1.00,0.00,1.00 +95,-163.20,76.80,1.00,0.00,1.00 +96,-168.00,72.00,1.00,0.00,1.00 +97,-172.80,67.20,1.00,0.00,1.00 +98,-172.80,62.40,1.00,0.00,1.00 +99,-172.80,57.60,1.00,0.00,1.00 +100,-172.80,52.80,1.00,0.00,1.00 +101,-177.60,48.00,1.00,0.00,1.00 +102,-177.60,43.20,1.00,0.00,1.00 +103,-177.60,38.40,1.00,0.00,1.00 +104,-177.60,33.60,1.00,0.00,1.00 +105,-177.60,28.80,1.00,0.00,1.00 +106,-177.60,24.00,1.00,0.00,1.00 +107,-177.60,19.20,1.00,0.00,1.00 +108,-177.60,14.40,1.00,0.00,1.00 +109,-177.60,9.60,1.00,0.00,1.00 +110,-177.60,4.80,1.00,0.00,1.00 +111,-177.60,0.00,1.00,0.00,1.00 +112,177.60,-0.00,1.00,0.00,1.00 +113,177.60,-4.80,1.00,0.00,1.00 +114,177.60,-9.60,1.00,0.00,1.00 +115,177.60,-14.40,1.00,0.00,1.00 +116,177.60,-19.20,1.00,0.00,1.00 +117,177.60,-24.00,1.00,0.00,1.00 +118,177.60,-28.80,1.00,0.00,1.00 +119,177.60,-33.60,1.00,0.00,1.00 +120,177.60,-38.40,1.00,0.00,1.00 +121,177.60,-43.20,1.00,0.00,1.00 +122,177.60,-48.00,1.00,0.00,1.00 +123,172.80,-52.80,1.00,0.00,1.00 +124,172.80,-57.60,1.00,0.00,1.00 +125,172.80,-62.40,1.00,0.00,1.00 +126,172.80,-67.20,1.00,0.00,1.00 +127,168.00,-72.00,1.00,0.00,1.00 +128,163.20,-76.80,1.00,0.00,1.00 +129,148.80,-81.60,1.00,0.00,1.00 +130,110.40,-86.40,1.00,0.00,1.00 +131,43.20,-86.40,1.00,0.00,1.00 +132,24.00,-81.60,1.00,0.00,1.00 +133,14.40,-76.80,1.00,0.00,1.00 +134,9.60,-72.00,1.00,0.00,1.00 +135,9.60,-67.20,1.00,0.00,1.00 +136,4.80,-62.40,1.00,0.00,1.00 +137,4.80,-57.60,1.00,0.00,1.00 +138,4.80,-52.80,1.00,0.00,1.00 +139,4.80,-48.00,1.00,0.00,1.00 +140,4.80,-43.20,1.00,0.00,1.00 +141,4.80,-38.40,1.00,0.00,1.00 +142,0.00,-33.60,1.00,0.00,1.00 +143,0.00,-28.80,1.00,0.00,1.00 +144,0.00,-24.00,1.00,0.00,1.00 +145,0.00,-19.20,1.00,0.00,1.00 +146,0.00,-14.40,1.00,0.00,1.00 +147,0.00,-9.60,1.00,0.00,1.00 +148,0.00,-4.80,1.00,0.00,1.00 +149,0.00,0.00,1.00,0.00,1.00 +150,-0.00,4.80,1.00,0.00,1.00 +151,-0.00,9.60,1.00,0.00,1.00 +152,-0.00,14.40,1.00,0.00,1.00 +153,-4.80,19.20,1.00,0.00,1.00 +154,-4.80,24.00,1.00,0.00,1.00 +155,-4.80,28.80,1.00,0.00,1.00 +156,-4.80,33.60,1.00,0.00,1.00 +157,-4.80,38.40,1.00,0.00,1.00 +158,-9.60,43.20,1.00,0.00,1.00 +159,-9.60,48.00,1.00,0.00,1.00 +160,-9.60,52.80,1.00,0.00,1.00 +161,-14.40,57.60,1.00,0.00,1.00 +162,-14.40,62.40,1.00,0.00,1.00 +163,-19.20,67.20,1.00,0.00,1.00 +164,-24.00,72.00,1.00,0.00,1.00 +165,-33.60,72.00,1.00,0.00,1.00 +166,-43.20,76.80,1.00,0.00,1.00 +167,-67.20,81.60,1.00,0.00,1.00 +168,-96.00,81.60,1.00,0.00,1.00 +169,-124.80,81.60,1.00,0.00,1.00 +170,-144.00,76.80,1.00,0.00,1.00 +171,-153.60,72.00,1.00,0.00,1.00 +172,-158.40,67.20,1.00,0.00,1.00 +173,-163.20,62.40,1.00,0.00,1.00 +174,-168.00,57.60,1.00,0.00,1.00 +175,-168.00,52.80,1.00,0.00,1.00 +176,-168.00,48.00,1.00,0.00,1.00 +177,-172.80,43.20,1.00,0.00,1.00 +178,-172.80,38.40,1.00,0.00,1.00 +179,-172.80,33.60,1.00,0.00,1.00 +180,-172.80,28.80,1.00,0.00,1.00 +181,-177.60,24.00,1.00,0.00,1.00 +182,-177.60,19.20,1.00,0.00,1.00 +183,-177.60,14.40,1.00,0.00,1.00 +184,-177.60,9.60,1.00,0.00,1.00 +185,-177.60,4.80,1.00,0.00,1.00 +186,-177.60,0.00,1.00,0.00,1.00 +187,177.60,-0.00,1.00,0.00,1.00 +188,177.60,-4.80,1.00,0.00,1.00 +189,177.60,-9.60,1.00,0.00,1.00 +190,177.60,-14.40,1.00,0.00,1.00 +191,177.60,-19.20,1.00,0.00,1.00 +192,177.60,-24.00,1.00,0.00,1.00 +193,172.80,-28.80,1.00,0.00,1.00 +194,172.80,-33.60,1.00,0.00,1.00 +195,172.80,-38.40,1.00,0.00,1.00 +196,172.80,-43.20,1.00,0.00,1.00 +197,168.00,-48.00,1.00,0.00,1.00 +198,168.00,-52.80,1.00,0.00,1.00 +199,168.00,-57.60,1.00,0.00,1.00 +200,163.20,-62.40,1.00,0.00,1.00 +201,158.40,-67.20,1.00,0.00,1.00 +202,153.60,-72.00,1.00,0.00,1.00 +203,144.00,-76.80,1.00,0.00,1.00 +204,124.80,-81.60,1.00,0.00,1.00 +205,96.00,-81.60,1.00,0.00,1.00 +206,67.20,-81.60,1.00,0.00,1.00 +207,43.20,-76.80,1.00,0.00,1.00 +208,33.60,-72.00,1.00,0.00,1.00 +209,24.00,-72.00,1.00,0.00,1.00 +210,19.20,-67.20,1.00,0.00,1.00 +211,14.40,-62.40,1.00,0.00,1.00 +212,14.40,-57.60,1.00,0.00,1.00 +213,9.60,-52.80,1.00,0.00,1.00 +214,9.60,-48.00,1.00,0.00,1.00 +215,9.60,-43.20,1.00,0.00,1.00 +216,4.80,-38.40,1.00,0.00,1.00 +217,4.80,-33.60,1.00,0.00,1.00 +218,4.80,-28.80,1.00,0.00,1.00 +219,4.80,-24.00,1.00,0.00,1.00 +220,4.80,-19.20,1.00,0.00,1.00 +221,0.00,-14.40,1.00,0.00,1.00 +222,0.00,-9.60,1.00,0.00,1.00 +223,0.00,-4.80,1.00,0.00,1.00 +224,0.00,0.00,1.00,0.00,1.00 +225,-0.00,4.80,1.00,0.00,1.00 +226,-0.00,9.60,1.00,0.00,1.00 +227,-4.80,14.40,1.00,0.00,1.00 +228,-4.80,19.20,1.00,0.00,1.00 +229,-4.80,24.00,1.00,0.00,1.00 +230,-4.80,28.80,1.00,0.00,1.00 +231,-9.60,33.60,1.00,0.00,1.00 +232,-9.60,38.40,1.00,0.00,1.00 +233,-14.40,43.20,1.00,0.00,1.00 +234,-14.40,48.00,1.00,0.00,1.00 +235,-14.40,52.80,1.00,0.00,1.00 +236,-19.20,57.60,1.00,0.00,1.00 +237,-24.00,57.60,1.00,0.00,1.00 +238,-28.80,62.40,1.00,0.00,1.00 +239,-33.60,67.20,1.00,0.00,1.00 +240,-43.20,72.00,1.00,0.00,1.00 +241,-57.60,72.00,1.00,0.00,1.00 +242,-76.80,76.80,1.00,0.00,1.00 +243,-96.00,76.80,1.00,0.00,1.00 +244,-115.20,76.80,1.00,0.00,1.00 +245,-129.60,72.00,1.00,0.00,1.00 +246,-139.20,72.00,1.00,0.00,1.00 +247,-148.80,67.20,1.00,0.00,1.00 +248,-153.60,62.40,1.00,0.00,1.00 +249,-158.40,57.60,1.00,0.00,1.00 +250,-163.20,52.80,1.00,0.00,1.00 +251,-163.20,48.00,1.00,0.00,1.00 +252,-168.00,43.20,1.00,0.00,1.00 +253,-168.00,38.40,1.00,0.00,1.00 +254,-172.80,33.60,1.00,0.00,1.00 +255,-172.80,28.80,1.00,0.00,1.00 +256,-172.80,24.00,1.00,0.00,1.00 +257,-172.80,19.20,1.00,0.00,1.00 +258,-177.60,14.40,1.00,0.00,1.00 +259,-177.60,9.60,1.00,0.00,1.00 +260,-177.60,4.80,1.00,0.00,1.00 +261,-177.60,0.00,1.00,0.00,1.00 +262,177.60,-0.00,1.00,0.00,1.00 +263,177.60,-4.80,1.00,0.00,1.00 +264,177.60,-9.60,1.00,0.00,1.00 +265,177.60,-14.40,1.00,0.00,1.00 +266,172.80,-19.20,1.00,0.00,1.00 +267,172.80,-24.00,1.00,0.00,1.00 +268,172.80,-28.80,1.00,0.00,1.00 +269,172.80,-33.60,1.00,0.00,1.00 +270,168.00,-38.40,1.00,0.00,1.00 +271,168.00,-43.20,1.00,0.00,1.00 +272,163.20,-48.00,1.00,0.00,1.00 +273,163.20,-52.80,1.00,0.00,1.00 +274,158.40,-57.60,1.00,0.00,1.00 +275,153.60,-62.40,1.00,0.00,1.00 +276,148.80,-67.20,1.00,0.00,1.00 +277,139.20,-72.00,1.00,0.00,1.00 +278,129.60,-72.00,1.00,0.00,1.00 +279,115.20,-76.80,1.00,0.00,1.00 +280,96.00,-76.80,1.00,0.00,1.00 +281,76.80,-76.80,1.00,0.00,1.00 +282,57.60,-72.00,1.00,0.00,1.00 +283,43.20,-72.00,1.00,0.00,1.00 +284,33.60,-67.20,1.00,0.00,1.00 +285,28.80,-62.40,1.00,0.00,1.00 +286,24.00,-57.60,1.00,0.00,1.00 +287,19.20,-57.60,1.00,0.00,1.00 +288,14.40,-52.80,1.00,0.00,1.00 +289,14.40,-48.00,1.00,0.00,1.00 +290,14.40,-43.20,1.00,0.00,1.00 +291,9.60,-38.40,1.00,0.00,1.00 +292,9.60,-33.60,1.00,0.00,1.00 +293,4.80,-28.80,1.00,0.00,1.00 +294,4.80,-24.00,1.00,0.00,1.00 +295,4.80,-19.20,1.00,0.00,1.00 +296,4.80,-14.40,1.00,0.00,1.00 +297,0.00,-9.60,1.00,0.00,1.00 +298,0.00,-4.80,1.00,0.00,1.00 +299,0.00,0.00,1.00,0.00,1.00 +300,-0.00,4.80,1.00,0.00,1.00 +301,-4.80,9.60,1.00,0.00,1.00 +302,-4.80,14.40,1.00,0.00,1.00 +303,-4.80,19.20,1.00,0.00,1.00 +304,-9.60,24.00,1.00,0.00,1.00 +305,-9.60,28.80,1.00,0.00,1.00 +306,-9.60,33.60,1.00,0.00,1.00 +307,-14.40,38.40,1.00,0.00,1.00 +308,-14.40,38.40,1.00,0.00,1.00 +309,-19.20,43.20,1.00,0.00,1.00 +310,-24.00,48.00,1.00,0.00,1.00 +311,-24.00,52.80,1.00,0.00,1.00 +312,-28.80,57.60,1.00,0.00,1.00 +313,-38.40,62.40,1.00,0.00,1.00 +314,-43.20,62.40,1.00,0.00,1.00 +315,-52.80,67.20,1.00,0.00,1.00 +316,-62.40,72.00,1.00,0.00,1.00 +317,-76.80,72.00,1.00,0.00,1.00 +318,-96.00,72.00,1.00,0.00,1.00 +319,-110.40,72.00,1.00,0.00,1.00 +320,-120.00,67.20,1.00,0.00,1.00 +321,-134.40,67.20,1.00,0.00,1.00 +322,-139.20,62.40,1.00,0.00,1.00 +323,-148.80,57.60,1.00,0.00,1.00 +324,-153.60,57.60,1.00,0.00,1.00 +325,-158.40,52.80,1.00,0.00,1.00 +326,-158.40,48.00,1.00,0.00,1.00 +327,-163.20,43.20,1.00,0.00,1.00 +328,-163.20,38.40,1.00,0.00,1.00 +329,-168.00,33.60,1.00,0.00,1.00 +330,-168.00,28.80,1.00,0.00,1.00 +331,-172.80,24.00,1.00,0.00,1.00 +332,-172.80,19.20,1.00,0.00,1.00 +333,-172.80,14.40,1.00,0.00,1.00 +334,-177.60,9.60,1.00,0.00,1.00 +335,-177.60,4.80,1.00,0.00,1.00 +336,-177.60,0.00,1.00,0.00,1.00 +337,177.60,-0.00,1.00,0.00,1.00 +338,177.60,-4.80,1.00,0.00,1.00 +339,177.60,-9.60,1.00,0.00,1.00 +340,172.80,-14.40,1.00,0.00,1.00 +341,172.80,-19.20,1.00,0.00,1.00 +342,172.80,-24.00,1.00,0.00,1.00 +343,168.00,-28.80,1.00,0.00,1.00 +344,168.00,-33.60,1.00,0.00,1.00 +345,163.20,-38.40,1.00,0.00,1.00 +346,163.20,-43.20,1.00,0.00,1.00 +347,158.40,-48.00,1.00,0.00,1.00 +348,158.40,-52.80,1.00,0.00,1.00 +349,153.60,-57.60,1.00,0.00,1.00 +350,148.80,-57.60,1.00,0.00,1.00 +351,139.20,-62.40,1.00,0.00,1.00 +352,134.40,-67.20,1.00,0.00,1.00 +353,120.00,-67.20,1.00,0.00,1.00 +354,110.40,-72.00,1.00,0.00,1.00 +355,96.00,-72.00,1.00,0.00,1.00 +356,76.80,-72.00,1.00,0.00,1.00 +357,62.40,-72.00,1.00,0.00,1.00 +358,52.80,-67.20,1.00,0.00,1.00 +359,43.20,-62.40,1.00,0.00,1.00 +360,38.40,-62.40,1.00,0.00,1.00 +361,28.80,-57.60,1.00,0.00,1.00 +362,24.00,-52.80,1.00,0.00,1.00 +363,24.00,-48.00,1.00,0.00,1.00 +364,19.20,-43.20,1.00,0.00,1.00 +365,14.40,-38.40,1.00,0.00,1.00 +366,14.40,-38.40,1.00,0.00,1.00 +367,9.60,-33.60,1.00,0.00,1.00 +368,9.60,-28.80,1.00,0.00,1.00 +369,9.60,-24.00,1.00,0.00,1.00 +370,4.80,-19.20,1.00,0.00,1.00 +371,4.80,-14.40,1.00,0.00,1.00 +372,4.80,-9.60,1.00,0.00,1.00 +373,0.00,-4.80,1.00,0.00,1.00 +374,0.00,0.00,1.00,0.00,1.00 +375,-0.00,4.80,1.00,0.00,1.00 +376,-4.80,9.60,1.00,0.00,1.00 +377,-4.80,14.40,1.00,0.00,1.00 +378,-9.60,19.20,1.00,0.00,1.00 +379,-9.60,24.00,1.00,0.00,1.00 +380,-14.40,24.00,1.00,0.00,1.00 +381,-14.40,28.80,1.00,0.00,1.00 +382,-19.20,33.60,1.00,0.00,1.00 +383,-19.20,38.40,1.00,0.00,1.00 +384,-24.00,43.20,1.00,0.00,1.00 +385,-28.80,48.00,1.00,0.00,1.00 +386,-33.60,52.80,1.00,0.00,1.00 +387,-38.40,52.80,1.00,0.00,1.00 +388,-43.20,57.60,1.00,0.00,1.00 +389,-48.00,62.40,1.00,0.00,1.00 +390,-57.60,62.40,1.00,0.00,1.00 +391,-67.20,67.20,1.00,0.00,1.00 +392,-81.60,67.20,1.00,0.00,1.00 +393,-91.20,67.20,1.00,0.00,1.00 +394,-105.60,67.20,1.00,0.00,1.00 +395,-115.20,67.20,1.00,0.00,1.00 +396,-124.80,62.40,1.00,0.00,1.00 +397,-134.40,57.60,1.00,0.00,1.00 +398,-139.20,57.60,1.00,0.00,1.00 +399,-144.00,52.80,1.00,0.00,1.00 +400,-148.80,48.00,1.00,0.00,1.00 +401,-153.60,43.20,1.00,0.00,1.00 +402,-158.40,43.20,1.00,0.00,1.00 +403,-163.20,38.40,1.00,0.00,1.00 +404,-163.20,33.60,1.00,0.00,1.00 +405,-168.00,28.80,1.00,0.00,1.00 +406,-168.00,24.00,1.00,0.00,1.00 +407,-172.80,19.20,1.00,0.00,1.00 +408,-172.80,14.40,1.00,0.00,1.00 +409,-177.60,9.60,1.00,0.00,1.00 +410,-177.60,4.80,1.00,0.00,1.00 +411,-177.60,0.00,1.00,0.00,1.00 +412,177.60,-0.00,1.00,0.00,1.00 +413,177.60,-4.80,1.00,0.00,1.00 +414,177.60,-9.60,1.00,0.00,1.00 +415,172.80,-14.40,1.00,0.00,1.00 +416,172.80,-19.20,1.00,0.00,1.00 +417,168.00,-24.00,1.00,0.00,1.00 +418,168.00,-28.80,1.00,0.00,1.00 +419,163.20,-33.60,1.00,0.00,1.00 +420,163.20,-38.40,1.00,0.00,1.00 +421,158.40,-43.20,1.00,0.00,1.00 +422,153.60,-43.20,1.00,0.00,1.00 +423,148.80,-48.00,1.00,0.00,1.00 +424,144.00,-52.80,1.00,0.00,1.00 +425,139.20,-57.60,1.00,0.00,1.00 +426,134.40,-57.60,1.00,0.00,1.00 +427,124.80,-62.40,1.00,0.00,1.00 +428,115.20,-67.20,1.00,0.00,1.00 +429,105.60,-67.20,1.00,0.00,1.00 +430,91.20,-67.20,1.00,0.00,1.00 +431,81.60,-67.20,1.00,0.00,1.00 +432,67.20,-67.20,1.00,0.00,1.00 +433,57.60,-62.40,1.00,0.00,1.00 +434,48.00,-62.40,1.00,0.00,1.00 +435,43.20,-57.60,1.00,0.00,1.00 +436,38.40,-52.80,1.00,0.00,1.00 +437,33.60,-52.80,1.00,0.00,1.00 +438,28.80,-48.00,1.00,0.00,1.00 +439,24.00,-43.20,1.00,0.00,1.00 +440,19.20,-38.40,1.00,0.00,1.00 +441,19.20,-33.60,1.00,0.00,1.00 +442,14.40,-28.80,1.00,0.00,1.00 +443,14.40,-24.00,1.00,0.00,1.00 +444,9.60,-24.00,1.00,0.00,1.00 +445,9.60,-19.20,1.00,0.00,1.00 +446,4.80,-14.40,1.00,0.00,1.00 +447,4.80,-9.60,1.00,0.00,1.00 +448,0.00,-4.80,1.00,0.00,1.00 +449,0.00,0.00,1.00,0.00,1.00 +450,-0.00,4.80,1.00,0.00,1.00 +451,-4.80,9.60,1.00,0.00,1.00 +452,-4.80,14.40,1.00,0.00,1.00 +453,-9.60,19.20,1.00,0.00,1.00 +454,-9.60,19.20,1.00,0.00,1.00 +455,-14.40,24.00,1.00,0.00,1.00 +456,-19.20,28.80,1.00,0.00,1.00 +457,-19.20,33.60,1.00,0.00,1.00 +458,-24.00,38.40,1.00,0.00,1.00 +459,-28.80,43.20,1.00,0.00,1.00 +460,-33.60,43.20,1.00,0.00,1.00 +461,-38.40,48.00,1.00,0.00,1.00 +462,-43.20,52.80,1.00,0.00,1.00 +463,-48.00,52.80,1.00,0.00,1.00 +464,-52.80,57.60,1.00,0.00,1.00 +465,-62.40,57.60,1.00,0.00,1.00 +466,-72.00,62.40,1.00,0.00,1.00 +467,-81.60,62.40,1.00,0.00,1.00 +468,-91.20,62.40,1.00,0.00,1.00 +469,-100.80,62.40,1.00,0.00,1.00 +470,-110.40,62.40,1.00,0.00,1.00 +471,-120.00,57.60,1.00,0.00,1.00 +472,-129.60,57.60,1.00,0.00,1.00 +473,-134.40,52.80,1.00,0.00,1.00 +474,-139.20,48.00,1.00,0.00,1.00 +475,-144.00,48.00,1.00,0.00,1.00 +476,-148.80,43.20,1.00,0.00,1.00 +477,-153.60,38.40,1.00,0.00,1.00 +478,-158.40,33.60,1.00,0.00,1.00 +479,-163.20,33.60,1.00,0.00,1.00 +480,-163.20,28.80,1.00,0.00,1.00 +481,-168.00,24.00,1.00,0.00,1.00 +482,-168.00,19.20,1.00,0.00,1.00 +483,-172.80,14.40,1.00,0.00,1.00 +484,-172.80,9.60,1.00,0.00,1.00 +485,-177.60,4.80,1.00,0.00,1.00 +486,-177.60,0.00,1.00,0.00,1.00 +487,177.60,-0.00,1.00,0.00,1.00 +488,177.60,-4.80,1.00,0.00,1.00 +489,172.80,-9.60,1.00,0.00,1.00 +490,172.80,-14.40,1.00,0.00,1.00 +491,168.00,-19.20,1.00,0.00,1.00 +492,168.00,-24.00,1.00,0.00,1.00 +493,163.20,-28.80,1.00,0.00,1.00 +494,163.20,-33.60,1.00,0.00,1.00 +495,158.40,-33.60,1.00,0.00,1.00 +496,153.60,-38.40,1.00,0.00,1.00 +497,148.80,-43.20,1.00,0.00,1.00 +498,144.00,-48.00,1.00,0.00,1.00 +499,139.20,-48.00,1.00,0.00,1.00 +500,134.40,-52.80,1.00,0.00,1.00 +501,129.60,-57.60,1.00,0.00,1.00 +502,120.00,-57.60,1.00,0.00,1.00 +503,110.40,-62.40,1.00,0.00,1.00 +504,100.80,-62.40,1.00,0.00,1.00 +505,91.20,-62.40,1.00,0.00,1.00 +506,81.60,-62.40,1.00,0.00,1.00 +507,72.00,-62.40,1.00,0.00,1.00 +508,62.40,-57.60,1.00,0.00,1.00 +509,52.80,-57.60,1.00,0.00,1.00 +510,48.00,-52.80,1.00,0.00,1.00 +511,43.20,-52.80,1.00,0.00,1.00 +512,38.40,-48.00,1.00,0.00,1.00 +513,33.60,-43.20,1.00,0.00,1.00 +514,28.80,-43.20,1.00,0.00,1.00 +515,24.00,-38.40,1.00,0.00,1.00 +516,19.20,-33.60,1.00,0.00,1.00 +517,19.20,-28.80,1.00,0.00,1.00 +518,14.40,-24.00,1.00,0.00,1.00 +519,9.60,-19.20,1.00,0.00,1.00 +520,9.60,-19.20,1.00,0.00,1.00 +521,4.80,-14.40,1.00,0.00,1.00 +522,4.80,-9.60,1.00,0.00,1.00 +523,0.00,-4.80,1.00,0.00,1.00 +524,0.00,0.00,1.00,0.00,1.00 +525,-4.80,4.80,1.00,0.00,1.00 +526,-4.80,9.60,1.00,0.00,1.00 +527,-9.60,14.40,1.00,0.00,1.00 +528,-9.60,14.40,1.00,0.00,1.00 +529,-14.40,19.20,1.00,0.00,1.00 +530,-14.40,24.00,1.00,0.00,1.00 +531,-19.20,28.80,1.00,0.00,1.00 +532,-24.00,33.60,1.00,0.00,1.00 +533,-28.80,33.60,1.00,0.00,1.00 +534,-28.80,38.40,1.00,0.00,1.00 +535,-33.60,43.20,1.00,0.00,1.00 +536,-38.40,43.20,1.00,0.00,1.00 +537,-48.00,48.00,1.00,0.00,1.00 +538,-52.80,52.80,1.00,0.00,1.00 +539,-57.60,52.80,1.00,0.00,1.00 +540,-67.20,57.60,1.00,0.00,1.00 +541,-76.80,57.60,1.00,0.00,1.00 +542,-81.60,57.60,1.00,0.00,1.00 +543,-91.20,57.60,1.00,0.00,1.00 +544,-100.80,57.60,1.00,0.00,1.00 +545,-110.40,57.60,1.00,0.00,1.00 +546,-115.20,52.80,1.00,0.00,1.00 +547,-124.80,52.80,1.00,0.00,1.00 +548,-129.60,48.00,1.00,0.00,1.00 +549,-139.20,48.00,1.00,0.00,1.00 +550,-144.00,43.20,1.00,0.00,1.00 +551,-148.80,38.40,1.00,0.00,1.00 +552,-153.60,38.40,1.00,0.00,1.00 +553,-153.60,33.60,1.00,0.00,1.00 +554,-158.40,28.80,1.00,0.00,1.00 +555,-163.20,24.00,1.00,0.00,1.00 +556,-163.20,24.00,1.00,0.00,1.00 +557,-168.00,19.20,1.00,0.00,1.00 +558,-172.80,14.40,1.00,0.00,1.00 +559,-172.80,9.60,1.00,0.00,1.00 +560,-177.60,4.80,1.00,0.00,1.00 +561,-177.60,0.00,1.00,0.00,1.00 +562,177.60,-0.00,1.00,0.00,1.00 +563,177.60,-4.80,1.00,0.00,1.00 +564,172.80,-9.60,1.00,0.00,1.00 +565,172.80,-14.40,1.00,0.00,1.00 +566,168.00,-19.20,1.00,0.00,1.00 +567,163.20,-24.00,1.00,0.00,1.00 +568,163.20,-24.00,1.00,0.00,1.00 +569,158.40,-28.80,1.00,0.00,1.00 +570,153.60,-33.60,1.00,0.00,1.00 +571,153.60,-38.40,1.00,0.00,1.00 +572,148.80,-38.40,1.00,0.00,1.00 +573,144.00,-43.20,1.00,0.00,1.00 +574,139.20,-48.00,1.00,0.00,1.00 +575,129.60,-48.00,1.00,0.00,1.00 +576,124.80,-52.80,1.00,0.00,1.00 +577,115.20,-52.80,1.00,0.00,1.00 +578,110.40,-57.60,1.00,0.00,1.00 +579,100.80,-57.60,1.00,0.00,1.00 +580,91.20,-57.60,1.00,0.00,1.00 +581,81.60,-57.60,1.00,0.00,1.00 +582,76.80,-57.60,1.00,0.00,1.00 +583,67.20,-57.60,1.00,0.00,1.00 +584,57.60,-52.80,1.00,0.00,1.00 +585,52.80,-52.80,1.00,0.00,1.00 +586,48.00,-48.00,1.00,0.00,1.00 +587,38.40,-43.20,1.00,0.00,1.00 +588,33.60,-43.20,1.00,0.00,1.00 +589,28.80,-38.40,1.00,0.00,1.00 +590,28.80,-33.60,1.00,0.00,1.00 +591,24.00,-33.60,1.00,0.00,1.00 +592,19.20,-28.80,1.00,0.00,1.00 +593,14.40,-24.00,1.00,0.00,1.00 +594,14.40,-19.20,1.00,0.00,1.00 +595,9.60,-14.40,1.00,0.00,1.00 +596,9.60,-14.40,1.00,0.00,1.00 +597,4.80,-9.60,1.00,0.00,1.00 +598,4.80,-4.80,1.00,0.00,1.00 +599,0.00,0.00,1.00,0.00,1.00 +600,-4.80,4.80,1.00,0.00,1.00 +601,-4.80,9.60,1.00,0.00,1.00 +602,-9.60,9.60,1.00,0.00,1.00 +603,-9.60,14.40,1.00,0.00,1.00 +604,-14.40,19.20,1.00,0.00,1.00 +605,-19.20,24.00,1.00,0.00,1.00 +606,-24.00,24.00,1.00,0.00,1.00 +607,-24.00,28.80,1.00,0.00,1.00 +608,-28.80,33.60,1.00,0.00,1.00 +609,-33.60,38.40,1.00,0.00,1.00 +610,-38.40,38.40,1.00,0.00,1.00 +611,-43.20,43.20,1.00,0.00,1.00 +612,-48.00,43.20,1.00,0.00,1.00 +613,-52.80,48.00,1.00,0.00,1.00 +614,-62.40,48.00,1.00,0.00,1.00 +615,-67.20,52.80,1.00,0.00,1.00 +616,-76.80,52.80,1.00,0.00,1.00 +617,-86.40,52.80,1.00,0.00,1.00 +618,-91.20,52.80,1.00,0.00,1.00 +619,-100.80,52.80,1.00,0.00,1.00 +620,-105.60,52.80,1.00,0.00,1.00 +621,-115.20,48.00,1.00,0.00,1.00 +622,-120.00,48.00,1.00,0.00,1.00 +623,-129.60,48.00,1.00,0.00,1.00 +624,-134.40,43.20,1.00,0.00,1.00 +625,-139.20,43.20,1.00,0.00,1.00 +626,-144.00,38.40,1.00,0.00,1.00 +627,-148.80,33.60,1.00,0.00,1.00 +628,-153.60,33.60,1.00,0.00,1.00 +629,-158.40,28.80,1.00,0.00,1.00 +630,-158.40,24.00,1.00,0.00,1.00 +631,-163.20,19.20,1.00,0.00,1.00 +632,-168.00,19.20,1.00,0.00,1.00 +633,-168.00,14.40,1.00,0.00,1.00 +634,-172.80,9.60,1.00,0.00,1.00 +635,-177.60,4.80,1.00,0.00,1.00 +636,-177.60,0.00,1.00,0.00,1.00 +637,177.60,-0.00,1.00,0.00,1.00 +638,177.60,-4.80,1.00,0.00,1.00 +639,172.80,-9.60,1.00,0.00,1.00 +640,168.00,-14.40,1.00,0.00,1.00 +641,168.00,-19.20,1.00,0.00,1.00 +642,163.20,-19.20,1.00,0.00,1.00 +643,158.40,-24.00,1.00,0.00,1.00 +644,158.40,-28.80,1.00,0.00,1.00 +645,153.60,-33.60,1.00,0.00,1.00 +646,148.80,-33.60,1.00,0.00,1.00 +647,144.00,-38.40,1.00,0.00,1.00 +648,139.20,-43.20,1.00,0.00,1.00 +649,134.40,-43.20,1.00,0.00,1.00 +650,129.60,-48.00,1.00,0.00,1.00 +651,120.00,-48.00,1.00,0.00,1.00 +652,115.20,-48.00,1.00,0.00,1.00 +653,105.60,-52.80,1.00,0.00,1.00 +654,100.80,-52.80,1.00,0.00,1.00 +655,91.20,-52.80,1.00,0.00,1.00 +656,86.40,-52.80,1.00,0.00,1.00 +657,76.80,-52.80,1.00,0.00,1.00 +658,67.20,-52.80,1.00,0.00,1.00 +659,62.40,-48.00,1.00,0.00,1.00 +660,52.80,-48.00,1.00,0.00,1.00 +661,48.00,-43.20,1.00,0.00,1.00 +662,43.20,-43.20,1.00,0.00,1.00 +663,38.40,-38.40,1.00,0.00,1.00 +664,33.60,-38.40,1.00,0.00,1.00 +665,28.80,-33.60,1.00,0.00,1.00 +666,24.00,-28.80,1.00,0.00,1.00 +667,24.00,-24.00,1.00,0.00,1.00 +668,19.20,-24.00,1.00,0.00,1.00 +669,14.40,-19.20,1.00,0.00,1.00 +670,9.60,-14.40,1.00,0.00,1.00 +671,9.60,-9.60,1.00,0.00,1.00 +672,4.80,-9.60,1.00,0.00,1.00 +673,4.80,-4.80,1.00,0.00,1.00 +674,0.00,0.00,1.00,0.00,1.00 +675,-4.80,4.80,1.00,0.00,1.00 +676,-4.80,4.80,1.00,0.00,1.00 +677,-9.60,9.60,1.00,0.00,1.00 +678,-14.40,14.40,1.00,0.00,1.00 +679,-14.40,19.20,1.00,0.00,1.00 +680,-19.20,19.20,1.00,0.00,1.00 +681,-24.00,24.00,1.00,0.00,1.00 +682,-28.80,28.80,1.00,0.00,1.00 +683,-33.60,28.80,1.00,0.00,1.00 +684,-38.40,33.60,1.00,0.00,1.00 +685,-43.20,38.40,1.00,0.00,1.00 +686,-48.00,38.40,1.00,0.00,1.00 +687,-52.80,43.20,1.00,0.00,1.00 +688,-57.60,43.20,1.00,0.00,1.00 +689,-62.40,43.20,1.00,0.00,1.00 +690,-72.00,48.00,1.00,0.00,1.00 +691,-76.80,48.00,1.00,0.00,1.00 +692,-86.40,48.00,1.00,0.00,1.00 +693,-91.20,48.00,1.00,0.00,1.00 +694,-100.80,48.00,1.00,0.00,1.00 +695,-105.60,48.00,1.00,0.00,1.00 +696,-110.40,48.00,1.00,0.00,1.00 +697,-120.00,43.20,1.00,0.00,1.00 +698,-124.80,43.20,1.00,0.00,1.00 +699,-129.60,38.40,1.00,0.00,1.00 +700,-134.40,38.40,1.00,0.00,1.00 +701,-139.20,33.60,1.00,0.00,1.00 +702,-144.00,33.60,1.00,0.00,1.00 +703,-148.80,28.80,1.00,0.00,1.00 +704,-153.60,24.00,1.00,0.00,1.00 +705,-158.40,24.00,1.00,0.00,1.00 +706,-163.20,19.20,1.00,0.00,1.00 +707,-163.20,14.40,1.00,0.00,1.00 +708,-168.00,14.40,1.00,0.00,1.00 +709,-172.80,9.60,1.00,0.00,1.00 +710,-172.80,4.80,1.00,0.00,1.00 +711,-177.60,0.00,1.00,0.00,1.00 +712,177.60,-0.00,1.00,0.00,1.00 +713,172.80,-4.80,1.00,0.00,1.00 +714,172.80,-9.60,1.00,0.00,1.00 +715,168.00,-14.40,1.00,0.00,1.00 +716,163.20,-14.40,1.00,0.00,1.00 +717,163.20,-19.20,1.00,0.00,1.00 +718,158.40,-24.00,1.00,0.00,1.00 +719,153.60,-24.00,1.00,0.00,1.00 +720,148.80,-28.80,1.00,0.00,1.00 +721,144.00,-33.60,1.00,0.00,1.00 +722,139.20,-33.60,1.00,0.00,1.00 +723,134.40,-38.40,1.00,0.00,1.00 +724,129.60,-38.40,1.00,0.00,1.00 +725,124.80,-43.20,1.00,0.00,1.00 +726,120.00,-43.20,1.00,0.00,1.00 +727,110.40,-48.00,1.00,0.00,1.00 +728,105.60,-48.00,1.00,0.00,1.00 +729,100.80,-48.00,1.00,0.00,1.00 +730,91.20,-48.00,1.00,0.00,1.00 +731,86.40,-48.00,1.00,0.00,1.00 +732,76.80,-48.00,1.00,0.00,1.00 +733,72.00,-48.00,1.00,0.00,1.00 +734,62.40,-43.20,1.00,0.00,1.00 +735,57.60,-43.20,1.00,0.00,1.00 +736,52.80,-43.20,1.00,0.00,1.00 +737,48.00,-38.40,1.00,0.00,1.00 +738,43.20,-38.40,1.00,0.00,1.00 +739,38.40,-33.60,1.00,0.00,1.00 +740,33.60,-28.80,1.00,0.00,1.00 +741,28.80,-28.80,1.00,0.00,1.00 +742,24.00,-24.00,1.00,0.00,1.00 +743,19.20,-19.20,1.00,0.00,1.00 +744,14.40,-19.20,1.00,0.00,1.00 +745,14.40,-14.40,1.00,0.00,1.00 +746,9.60,-9.60,1.00,0.00,1.00 +747,4.80,-4.80,1.00,0.00,1.00 +748,4.80,-4.80,1.00,0.00,1.00 +749,0.00,0.00,1.00,0.00,1.00 +750,-4.80,4.80,1.00,0.00,1.00 +751,-4.80,4.80,1.00,0.00,1.00 +752,-9.60,9.60,1.00,0.00,1.00 +753,-14.40,14.40,1.00,0.00,1.00 +754,-19.20,14.40,1.00,0.00,1.00 +755,-24.00,19.20,1.00,0.00,1.00 +756,-24.00,24.00,1.00,0.00,1.00 +757,-28.80,24.00,1.00,0.00,1.00 +758,-33.60,28.80,1.00,0.00,1.00 +759,-38.40,28.80,1.00,0.00,1.00 +760,-43.20,33.60,1.00,0.00,1.00 +761,-48.00,33.60,1.00,0.00,1.00 +762,-52.80,38.40,1.00,0.00,1.00 +763,-62.40,38.40,1.00,0.00,1.00 +764,-67.20,38.40,1.00,0.00,1.00 +765,-72.00,43.20,1.00,0.00,1.00 +766,-76.80,43.20,1.00,0.00,1.00 +767,-86.40,43.20,1.00,0.00,1.00 +768,-91.20,43.20,1.00,0.00,1.00 +769,-96.00,43.20,1.00,0.00,1.00 +770,-105.60,43.20,1.00,0.00,1.00 +771,-110.40,43.20,1.00,0.00,1.00 +772,-115.20,38.40,1.00,0.00,1.00 +773,-124.80,38.40,1.00,0.00,1.00 +774,-129.60,38.40,1.00,0.00,1.00 +775,-134.40,33.60,1.00,0.00,1.00 +776,-139.20,33.60,1.00,0.00,1.00 +777,-144.00,28.80,1.00,0.00,1.00 +778,-148.80,28.80,1.00,0.00,1.00 +779,-153.60,24.00,1.00,0.00,1.00 +780,-158.40,19.20,1.00,0.00,1.00 +781,-158.40,19.20,1.00,0.00,1.00 +782,-163.20,14.40,1.00,0.00,1.00 +783,-168.00,9.60,1.00,0.00,1.00 +784,-172.80,9.60,1.00,0.00,1.00 +785,-172.80,4.80,1.00,0.00,1.00 +786,-177.60,0.00,1.00,0.00,1.00 +787,177.60,-0.00,1.00,0.00,1.00 +788,172.80,-4.80,1.00,0.00,1.00 +789,172.80,-9.60,1.00,0.00,1.00 +790,168.00,-9.60,1.00,0.00,1.00 +791,163.20,-14.40,1.00,0.00,1.00 +792,158.40,-19.20,1.00,0.00,1.00 +793,158.40,-19.20,1.00,0.00,1.00 +794,153.60,-24.00,1.00,0.00,1.00 +795,148.80,-28.80,1.00,0.00,1.00 +796,144.00,-28.80,1.00,0.00,1.00 +797,139.20,-33.60,1.00,0.00,1.00 +798,134.40,-33.60,1.00,0.00,1.00 +799,129.60,-38.40,1.00,0.00,1.00 +800,124.80,-38.40,1.00,0.00,1.00 +801,115.20,-38.40,1.00,0.00,1.00 +802,110.40,-43.20,1.00,0.00,1.00 +803,105.60,-43.20,1.00,0.00,1.00 +804,96.00,-43.20,1.00,0.00,1.00 +805,91.20,-43.20,1.00,0.00,1.00 +806,86.40,-43.20,1.00,0.00,1.00 +807,76.80,-43.20,1.00,0.00,1.00 +808,72.00,-43.20,1.00,0.00,1.00 +809,67.20,-38.40,1.00,0.00,1.00 +810,62.40,-38.40,1.00,0.00,1.00 +811,52.80,-38.40,1.00,0.00,1.00 +812,48.00,-33.60,1.00,0.00,1.00 +813,43.20,-33.60,1.00,0.00,1.00 +814,38.40,-28.80,1.00,0.00,1.00 +815,33.60,-28.80,1.00,0.00,1.00 +816,28.80,-24.00,1.00,0.00,1.00 +817,24.00,-24.00,1.00,0.00,1.00 +818,24.00,-19.20,1.00,0.00,1.00 +819,19.20,-14.40,1.00,0.00,1.00 +820,14.40,-14.40,1.00,0.00,1.00 +821,9.60,-9.60,1.00,0.00,1.00 +822,4.80,-4.80,1.00,0.00,1.00 +823,4.80,-4.80,1.00,0.00,1.00 +824,0.00,0.00,1.00,0.00,1.00 +825,-4.80,4.80,1.00,0.00,1.00 +826,-9.60,4.80,1.00,0.00,1.00 +827,-9.60,9.60,1.00,0.00,1.00 +828,-14.40,9.60,1.00,0.00,1.00 +829,-19.20,14.40,1.00,0.00,1.00 +830,-24.00,19.20,1.00,0.00,1.00 +831,-28.80,19.20,1.00,0.00,1.00 +832,-33.60,24.00,1.00,0.00,1.00 +833,-38.40,24.00,1.00,0.00,1.00 +834,-43.20,28.80,1.00,0.00,1.00 +835,-48.00,28.80,1.00,0.00,1.00 +836,-52.80,33.60,1.00,0.00,1.00 +837,-57.60,33.60,1.00,0.00,1.00 +838,-62.40,33.60,1.00,0.00,1.00 +839,-67.20,38.40,1.00,0.00,1.00 +840,-72.00,38.40,1.00,0.00,1.00 +841,-81.60,38.40,1.00,0.00,1.00 +842,-86.40,38.40,1.00,0.00,1.00 +843,-91.20,38.40,1.00,0.00,1.00 +844,-96.00,38.40,1.00,0.00,1.00 +845,-105.60,38.40,1.00,0.00,1.00 +846,-110.40,38.40,1.00,0.00,1.00 +847,-115.20,33.60,1.00,0.00,1.00 +848,-120.00,33.60,1.00,0.00,1.00 +849,-124.80,33.60,1.00,0.00,1.00 +850,-129.60,28.80,1.00,0.00,1.00 +851,-134.40,28.80,1.00,0.00,1.00 +852,-139.20,24.00,1.00,0.00,1.00 +853,-144.00,24.00,1.00,0.00,1.00 +854,-148.80,19.20,1.00,0.00,1.00 +855,-153.60,19.20,1.00,0.00,1.00 +856,-158.40,14.40,1.00,0.00,1.00 +857,-163.20,14.40,1.00,0.00,1.00 +858,-168.00,9.60,1.00,0.00,1.00 +859,-172.80,9.60,1.00,0.00,1.00 +860,-172.80,4.80,1.00,0.00,1.00 +861,-177.60,0.00,1.00,0.00,1.00 +862,177.60,-0.00,1.00,0.00,1.00 +863,172.80,-4.80,1.00,0.00,1.00 +864,172.80,-9.60,1.00,0.00,1.00 +865,168.00,-9.60,1.00,0.00,1.00 +866,163.20,-14.40,1.00,0.00,1.00 +867,158.40,-14.40,1.00,0.00,1.00 +868,153.60,-19.20,1.00,0.00,1.00 +869,148.80,-19.20,1.00,0.00,1.00 +870,144.00,-24.00,1.00,0.00,1.00 +871,139.20,-24.00,1.00,0.00,1.00 +872,134.40,-28.80,1.00,0.00,1.00 +873,129.60,-28.80,1.00,0.00,1.00 +874,124.80,-33.60,1.00,0.00,1.00 +875,120.00,-33.60,1.00,0.00,1.00 +876,115.20,-33.60,1.00,0.00,1.00 +877,110.40,-38.40,1.00,0.00,1.00 +878,105.60,-38.40,1.00,0.00,1.00 +879,96.00,-38.40,1.00,0.00,1.00 +880,91.20,-38.40,1.00,0.00,1.00 +881,86.40,-38.40,1.00,0.00,1.00 +882,81.60,-38.40,1.00,0.00,1.00 +883,72.00,-38.40,1.00,0.00,1.00 +884,67.20,-38.40,1.00,0.00,1.00 +885,62.40,-33.60,1.00,0.00,1.00 +886,57.60,-33.60,1.00,0.00,1.00 +887,52.80,-33.60,1.00,0.00,1.00 +888,48.00,-28.80,1.00,0.00,1.00 +889,43.20,-28.80,1.00,0.00,1.00 +890,38.40,-24.00,1.00,0.00,1.00 +891,33.60,-24.00,1.00,0.00,1.00 +892,28.80,-19.20,1.00,0.00,1.00 +893,24.00,-19.20,1.00,0.00,1.00 +894,19.20,-14.40,1.00,0.00,1.00 +895,14.40,-9.60,1.00,0.00,1.00 +896,9.60,-9.60,1.00,0.00,1.00 +897,9.60,-4.80,1.00,0.00,1.00 +898,4.80,-4.80,1.00,0.00,1.00 +899,0.00,0.00,1.00,0.00,1.00 +900,-4.80,4.80,1.00,0.00,1.00 +901,-9.60,4.80,1.00,0.00,1.00 +902,-14.40,9.60,1.00,0.00,1.00 +903,-14.40,9.60,1.00,0.00,1.00 +904,-19.20,14.40,1.00,0.00,1.00 +905,-24.00,14.40,1.00,0.00,1.00 +906,-28.80,19.20,1.00,0.00,1.00 +907,-33.60,19.20,1.00,0.00,1.00 +908,-38.40,24.00,1.00,0.00,1.00 +909,-43.20,24.00,1.00,0.00,1.00 +910,-48.00,24.00,1.00,0.00,1.00 +911,-52.80,28.80,1.00,0.00,1.00 +912,-57.60,28.80,1.00,0.00,1.00 +913,-62.40,28.80,1.00,0.00,1.00 +914,-67.20,33.60,1.00,0.00,1.00 +915,-72.00,33.60,1.00,0.00,1.00 +916,-81.60,33.60,1.00,0.00,1.00 +917,-86.40,33.60,1.00,0.00,1.00 +918,-91.20,33.60,1.00,0.00,1.00 +919,-96.00,33.60,1.00,0.00,1.00 +920,-100.80,33.60,1.00,0.00,1.00 +921,-110.40,33.60,1.00,0.00,1.00 +922,-115.20,33.60,1.00,0.00,1.00 +923,-120.00,28.80,1.00,0.00,1.00 +924,-124.80,28.80,1.00,0.00,1.00 +925,-129.60,28.80,1.00,0.00,1.00 +926,-134.40,24.00,1.00,0.00,1.00 +927,-139.20,24.00,1.00,0.00,1.00 +928,-144.00,19.20,1.00,0.00,1.00 +929,-148.80,19.20,1.00,0.00,1.00 +930,-153.60,14.40,1.00,0.00,1.00 +931,-158.40,14.40,1.00,0.00,1.00 +932,-163.20,9.60,1.00,0.00,1.00 +933,-168.00,9.60,1.00,0.00,1.00 +934,-168.00,4.80,1.00,0.00,1.00 +935,-172.80,4.80,1.00,0.00,1.00 +936,-177.60,0.00,1.00,0.00,1.00 +937,177.60,-0.00,1.00,0.00,1.00 +938,172.80,-4.80,1.00,0.00,1.00 +939,168.00,-4.80,1.00,0.00,1.00 +940,168.00,-9.60,1.00,0.00,1.00 +941,163.20,-9.60,1.00,0.00,1.00 +942,158.40,-14.40,1.00,0.00,1.00 +943,153.60,-14.40,1.00,0.00,1.00 +944,148.80,-19.20,1.00,0.00,1.00 +945,144.00,-19.20,1.00,0.00,1.00 +946,139.20,-24.00,1.00,0.00,1.00 +947,134.40,-24.00,1.00,0.00,1.00 +948,129.60,-28.80,1.00,0.00,1.00 +949,124.80,-28.80,1.00,0.00,1.00 +950,120.00,-28.80,1.00,0.00,1.00 +951,115.20,-33.60,1.00,0.00,1.00 +952,110.40,-33.60,1.00,0.00,1.00 +953,100.80,-33.60,1.00,0.00,1.00 +954,96.00,-33.60,1.00,0.00,1.00 +955,91.20,-33.60,1.00,0.00,1.00 +956,86.40,-33.60,1.00,0.00,1.00 +957,81.60,-33.60,1.00,0.00,1.00 +958,72.00,-33.60,1.00,0.00,1.00 +959,67.20,-33.60,1.00,0.00,1.00 +960,62.40,-28.80,1.00,0.00,1.00 +961,57.60,-28.80,1.00,0.00,1.00 +962,52.80,-28.80,1.00,0.00,1.00 +963,48.00,-24.00,1.00,0.00,1.00 +964,43.20,-24.00,1.00,0.00,1.00 +965,38.40,-24.00,1.00,0.00,1.00 +966,33.60,-19.20,1.00,0.00,1.00 +967,28.80,-19.20,1.00,0.00,1.00 +968,24.00,-14.40,1.00,0.00,1.00 +969,19.20,-14.40,1.00,0.00,1.00 +970,14.40,-9.60,1.00,0.00,1.00 +971,14.40,-9.60,1.00,0.00,1.00 +972,9.60,-4.80,1.00,0.00,1.00 +973,4.80,-4.80,1.00,0.00,1.00 +974,0.00,0.00,1.00,0.00,1.00 +975,-4.80,0.00,1.00,0.00,1.00 +976,-9.60,4.80,1.00,0.00,1.00 +977,-14.40,4.80,1.00,0.00,1.00 +978,-19.20,9.60,1.00,0.00,1.00 +979,-19.20,9.60,1.00,0.00,1.00 +980,-24.00,14.40,1.00,0.00,1.00 +981,-28.80,14.40,1.00,0.00,1.00 +982,-33.60,19.20,1.00,0.00,1.00 +983,-38.40,19.20,1.00,0.00,1.00 +984,-43.20,19.20,1.00,0.00,1.00 +985,-48.00,24.00,1.00,0.00,1.00 +986,-52.80,24.00,1.00,0.00,1.00 +987,-57.60,24.00,1.00,0.00,1.00 +988,-62.40,24.00,1.00,0.00,1.00 +989,-72.00,28.80,1.00,0.00,1.00 +990,-76.80,28.80,1.00,0.00,1.00 +991,-81.60,28.80,1.00,0.00,1.00 +992,-86.40,28.80,1.00,0.00,1.00 +993,-91.20,28.80,1.00,0.00,1.00 +994,-96.00,28.80,1.00,0.00,1.00 +995,-100.80,28.80,1.00,0.00,1.00 +996,-105.60,28.80,1.00,0.00,1.00 +997,-115.20,28.80,1.00,0.00,1.00 +998,-120.00,24.00,1.00,0.00,1.00 +999,-124.80,24.00,1.00,0.00,1.00 +1000,-129.60,24.00,1.00,0.00,1.00 +1001,-134.40,24.00,1.00,0.00,1.00 +1002,-139.20,19.20,1.00,0.00,1.00 +1003,-144.00,19.20,1.00,0.00,1.00 +1004,-148.80,14.40,1.00,0.00,1.00 +1005,-153.60,14.40,1.00,0.00,1.00 +1006,-158.40,14.40,1.00,0.00,1.00 +1007,-163.20,9.60,1.00,0.00,1.00 +1008,-163.20,9.60,1.00,0.00,1.00 +1009,-168.00,4.80,1.00,0.00,1.00 +1010,-172.80,4.80,1.00,0.00,1.00 +1011,-177.60,0.00,1.00,0.00,1.00 +1012,177.60,-0.00,1.00,0.00,1.00 +1013,172.80,-4.80,1.00,0.00,1.00 +1014,168.00,-4.80,1.00,0.00,1.00 +1015,163.20,-9.60,1.00,0.00,1.00 +1016,163.20,-9.60,1.00,0.00,1.00 +1017,158.40,-14.40,1.00,0.00,1.00 +1018,153.60,-14.40,1.00,0.00,1.00 +1019,148.80,-14.40,1.00,0.00,1.00 +1020,144.00,-19.20,1.00,0.00,1.00 +1021,139.20,-19.20,1.00,0.00,1.00 +1022,134.40,-24.00,1.00,0.00,1.00 +1023,129.60,-24.00,1.00,0.00,1.00 +1024,124.80,-24.00,1.00,0.00,1.00 +1025,120.00,-24.00,1.00,0.00,1.00 +1026,115.20,-28.80,1.00,0.00,1.00 +1027,105.60,-28.80,1.00,0.00,1.00 +1028,100.80,-28.80,1.00,0.00,1.00 +1029,96.00,-28.80,1.00,0.00,1.00 +1030,91.20,-28.80,1.00,0.00,1.00 +1031,86.40,-28.80,1.00,0.00,1.00 +1032,81.60,-28.80,1.00,0.00,1.00 +1033,76.80,-28.80,1.00,0.00,1.00 +1034,72.00,-28.80,1.00,0.00,1.00 +1035,62.40,-24.00,1.00,0.00,1.00 +1036,57.60,-24.00,1.00,0.00,1.00 +1037,52.80,-24.00,1.00,0.00,1.00 +1038,48.00,-24.00,1.00,0.00,1.00 +1039,43.20,-19.20,1.00,0.00,1.00 +1040,38.40,-19.20,1.00,0.00,1.00 +1041,33.60,-19.20,1.00,0.00,1.00 +1042,28.80,-14.40,1.00,0.00,1.00 +1043,24.00,-14.40,1.00,0.00,1.00 +1044,19.20,-9.60,1.00,0.00,1.00 +1045,19.20,-9.60,1.00,0.00,1.00 +1046,14.40,-4.80,1.00,0.00,1.00 +1047,9.60,-4.80,1.00,0.00,1.00 +1048,4.80,-0.00,1.00,0.00,1.00 +1049,0.00,0.00,1.00,0.00,1.00 +1050,-4.80,0.00,1.00,0.00,1.00 +1051,-9.60,4.80,1.00,0.00,1.00 +1052,-14.40,4.80,1.00,0.00,1.00 +1053,-19.20,9.60,1.00,0.00,1.00 +1054,-24.00,9.60,1.00,0.00,1.00 +1055,-28.80,9.60,1.00,0.00,1.00 +1056,-33.60,14.40,1.00,0.00,1.00 +1057,-33.60,14.40,1.00,0.00,1.00 +1058,-38.40,14.40,1.00,0.00,1.00 +1059,-43.20,19.20,1.00,0.00,1.00 +1060,-48.00,19.20,1.00,0.00,1.00 +1061,-57.60,19.20,1.00,0.00,1.00 +1062,-62.40,19.20,1.00,0.00,1.00 +1063,-67.20,24.00,1.00,0.00,1.00 +1064,-72.00,24.00,1.00,0.00,1.00 +1065,-76.80,24.00,1.00,0.00,1.00 +1066,-81.60,24.00,1.00,0.00,1.00 +1067,-86.40,24.00,1.00,0.00,1.00 +1068,-91.20,24.00,1.00,0.00,1.00 +1069,-96.00,24.00,1.00,0.00,1.00 +1070,-100.80,24.00,1.00,0.00,1.00 +1071,-105.60,24.00,1.00,0.00,1.00 +1072,-110.40,24.00,1.00,0.00,1.00 +1073,-115.20,19.20,1.00,0.00,1.00 +1074,-120.00,19.20,1.00,0.00,1.00 +1075,-129.60,19.20,1.00,0.00,1.00 +1076,-134.40,19.20,1.00,0.00,1.00 +1077,-139.20,19.20,1.00,0.00,1.00 +1078,-144.00,14.40,1.00,0.00,1.00 +1079,-148.80,14.40,1.00,0.00,1.00 +1080,-148.80,14.40,1.00,0.00,1.00 +1081,-153.60,9.60,1.00,0.00,1.00 +1082,-158.40,9.60,1.00,0.00,1.00 +1083,-163.20,4.80,1.00,0.00,1.00 +1084,-168.00,4.80,1.00,0.00,1.00 +1085,-172.80,4.80,1.00,0.00,1.00 +1086,-177.60,0.00,1.00,0.00,1.00 +1087,177.60,-0.00,1.00,0.00,1.00 +1088,172.80,-4.80,1.00,0.00,1.00 +1089,168.00,-4.80,1.00,0.00,1.00 +1090,163.20,-4.80,1.00,0.00,1.00 +1091,158.40,-9.60,1.00,0.00,1.00 +1092,153.60,-9.60,1.00,0.00,1.00 +1093,148.80,-14.40,1.00,0.00,1.00 +1094,148.80,-14.40,1.00,0.00,1.00 +1095,144.00,-14.40,1.00,0.00,1.00 +1096,139.20,-19.20,1.00,0.00,1.00 +1097,134.40,-19.20,1.00,0.00,1.00 +1098,129.60,-19.20,1.00,0.00,1.00 +1099,120.00,-19.20,1.00,0.00,1.00 +1100,115.20,-19.20,1.00,0.00,1.00 +1101,110.40,-24.00,1.00,0.00,1.00 +1102,105.60,-24.00,1.00,0.00,1.00 +1103,100.80,-24.00,1.00,0.00,1.00 +1104,96.00,-24.00,1.00,0.00,1.00 +1105,91.20,-24.00,1.00,0.00,1.00 +1106,86.40,-24.00,1.00,0.00,1.00 +1107,81.60,-24.00,1.00,0.00,1.00 +1108,76.80,-24.00,1.00,0.00,1.00 +1109,72.00,-24.00,1.00,0.00,1.00 +1110,67.20,-24.00,1.00,0.00,1.00 +1111,62.40,-19.20,1.00,0.00,1.00 +1112,57.60,-19.20,1.00,0.00,1.00 +1113,48.00,-19.20,1.00,0.00,1.00 +1114,43.20,-19.20,1.00,0.00,1.00 +1115,38.40,-14.40,1.00,0.00,1.00 +1116,33.60,-14.40,1.00,0.00,1.00 +1117,33.60,-14.40,1.00,0.00,1.00 +1118,28.80,-9.60,1.00,0.00,1.00 +1119,24.00,-9.60,1.00,0.00,1.00 +1120,19.20,-9.60,1.00,0.00,1.00 +1121,14.40,-4.80,1.00,0.00,1.00 +1122,9.60,-4.80,1.00,0.00,1.00 +1123,4.80,-0.00,1.00,0.00,1.00 +1124,0.00,0.00,1.00,0.00,1.00 +1125,-4.80,0.00,1.00,0.00,1.00 +1126,-9.60,4.80,1.00,0.00,1.00 +1127,-14.40,4.80,1.00,0.00,1.00 +1128,-19.20,4.80,1.00,0.00,1.00 +1129,-24.00,9.60,1.00,0.00,1.00 +1130,-28.80,9.60,1.00,0.00,1.00 +1131,-33.60,9.60,1.00,0.00,1.00 +1132,-38.40,9.60,1.00,0.00,1.00 +1133,-43.20,14.40,1.00,0.00,1.00 +1134,-48.00,14.40,1.00,0.00,1.00 +1135,-52.80,14.40,1.00,0.00,1.00 +1136,-57.60,14.40,1.00,0.00,1.00 +1137,-62.40,19.20,1.00,0.00,1.00 +1138,-67.20,19.20,1.00,0.00,1.00 +1139,-72.00,19.20,1.00,0.00,1.00 +1140,-76.80,19.20,1.00,0.00,1.00 +1141,-81.60,19.20,1.00,0.00,1.00 +1142,-86.40,19.20,1.00,0.00,1.00 +1143,-91.20,19.20,1.00,0.00,1.00 +1144,-96.00,19.20,1.00,0.00,1.00 +1145,-100.80,19.20,1.00,0.00,1.00 +1146,-105.60,19.20,1.00,0.00,1.00 +1147,-110.40,19.20,1.00,0.00,1.00 +1148,-115.20,19.20,1.00,0.00,1.00 +1149,-120.00,14.40,1.00,0.00,1.00 +1150,-124.80,14.40,1.00,0.00,1.00 +1151,-129.60,14.40,1.00,0.00,1.00 +1152,-134.40,14.40,1.00,0.00,1.00 +1153,-139.20,14.40,1.00,0.00,1.00 +1154,-144.00,9.60,1.00,0.00,1.00 +1155,-148.80,9.60,1.00,0.00,1.00 +1156,-153.60,9.60,1.00,0.00,1.00 +1157,-158.40,4.80,1.00,0.00,1.00 +1158,-163.20,4.80,1.00,0.00,1.00 +1159,-168.00,4.80,1.00,0.00,1.00 +1160,-172.80,0.00,1.00,0.00,1.00 +1161,-177.60,0.00,1.00,0.00,1.00 +1162,177.60,-0.00,1.00,0.00,1.00 +1163,172.80,-0.00,1.00,0.00,1.00 +1164,168.00,-4.80,1.00,0.00,1.00 +1165,163.20,-4.80,1.00,0.00,1.00 +1166,158.40,-4.80,1.00,0.00,1.00 +1167,153.60,-9.60,1.00,0.00,1.00 +1168,148.80,-9.60,1.00,0.00,1.00 +1169,144.00,-9.60,1.00,0.00,1.00 +1170,139.20,-14.40,1.00,0.00,1.00 +1171,134.40,-14.40,1.00,0.00,1.00 +1172,129.60,-14.40,1.00,0.00,1.00 +1173,124.80,-14.40,1.00,0.00,1.00 +1174,120.00,-14.40,1.00,0.00,1.00 +1175,115.20,-19.20,1.00,0.00,1.00 +1176,110.40,-19.20,1.00,0.00,1.00 +1177,105.60,-19.20,1.00,0.00,1.00 +1178,100.80,-19.20,1.00,0.00,1.00 +1179,96.00,-19.20,1.00,0.00,1.00 +1180,91.20,-19.20,1.00,0.00,1.00 +1181,86.40,-19.20,1.00,0.00,1.00 +1182,81.60,-19.20,1.00,0.00,1.00 +1183,76.80,-19.20,1.00,0.00,1.00 +1184,72.00,-19.20,1.00,0.00,1.00 +1185,67.20,-19.20,1.00,0.00,1.00 +1186,62.40,-19.20,1.00,0.00,1.00 +1187,57.60,-14.40,1.00,0.00,1.00 +1188,52.80,-14.40,1.00,0.00,1.00 +1189,48.00,-14.40,1.00,0.00,1.00 +1190,43.20,-14.40,1.00,0.00,1.00 +1191,38.40,-9.60,1.00,0.00,1.00 +1192,33.60,-9.60,1.00,0.00,1.00 +1193,28.80,-9.60,1.00,0.00,1.00 +1194,24.00,-9.60,1.00,0.00,1.00 +1195,19.20,-4.80,1.00,0.00,1.00 +1196,14.40,-4.80,1.00,0.00,1.00 +1197,9.60,-4.80,1.00,0.00,1.00 +1198,4.80,-0.00,1.00,0.00,1.00 +1199,0.00,0.00,1.00,0.00,1.00 +1200,-4.80,0.00,1.00,0.00,1.00 +1201,-9.60,0.00,1.00,0.00,1.00 +1202,-14.40,4.80,1.00,0.00,1.00 +1203,-19.20,4.80,1.00,0.00,1.00 +1204,-24.00,4.80,1.00,0.00,1.00 +1205,-28.80,4.80,1.00,0.00,1.00 +1206,-33.60,9.60,1.00,0.00,1.00 +1207,-38.40,9.60,1.00,0.00,1.00 +1208,-43.20,9.60,1.00,0.00,1.00 +1209,-48.00,9.60,1.00,0.00,1.00 +1210,-52.80,9.60,1.00,0.00,1.00 +1211,-57.60,14.40,1.00,0.00,1.00 +1212,-62.40,14.40,1.00,0.00,1.00 +1213,-67.20,14.40,1.00,0.00,1.00 +1214,-72.00,14.40,1.00,0.00,1.00 +1215,-76.80,14.40,1.00,0.00,1.00 +1216,-81.60,14.40,1.00,0.00,1.00 +1217,-86.40,14.40,1.00,0.00,1.00 +1218,-91.20,14.40,1.00,0.00,1.00 +1219,-96.00,14.40,1.00,0.00,1.00 +1220,-100.80,14.40,1.00,0.00,1.00 +1221,-105.60,14.40,1.00,0.00,1.00 +1222,-110.40,14.40,1.00,0.00,1.00 +1223,-115.20,14.40,1.00,0.00,1.00 +1224,-120.00,14.40,1.00,0.00,1.00 +1225,-124.80,9.60,1.00,0.00,1.00 +1226,-129.60,9.60,1.00,0.00,1.00 +1227,-134.40,9.60,1.00,0.00,1.00 +1228,-139.20,9.60,1.00,0.00,1.00 +1229,-144.00,9.60,1.00,0.00,1.00 +1230,-148.80,9.60,1.00,0.00,1.00 +1231,-153.60,4.80,1.00,0.00,1.00 +1232,-158.40,4.80,1.00,0.00,1.00 +1233,-163.20,4.80,1.00,0.00,1.00 +1234,-168.00,4.80,1.00,0.00,1.00 +1235,-172.80,0.00,1.00,0.00,1.00 +1236,-177.60,0.00,1.00,0.00,1.00 +1237,177.60,-0.00,1.00,0.00,1.00 +1238,172.80,-0.00,1.00,0.00,1.00 +1239,168.00,-4.80,1.00,0.00,1.00 +1240,163.20,-4.80,1.00,0.00,1.00 +1241,158.40,-4.80,1.00,0.00,1.00 +1242,153.60,-4.80,1.00,0.00,1.00 +1243,148.80,-9.60,1.00,0.00,1.00 +1244,144.00,-9.60,1.00,0.00,1.00 +1245,139.20,-9.60,1.00,0.00,1.00 +1246,134.40,-9.60,1.00,0.00,1.00 +1247,129.60,-9.60,1.00,0.00,1.00 +1248,124.80,-9.60,1.00,0.00,1.00 +1249,120.00,-14.40,1.00,0.00,1.00 +1250,115.20,-14.40,1.00,0.00,1.00 +1251,110.40,-14.40,1.00,0.00,1.00 +1252,105.60,-14.40,1.00,0.00,1.00 +1253,100.80,-14.40,1.00,0.00,1.00 +1254,96.00,-14.40,1.00,0.00,1.00 +1255,91.20,-14.40,1.00,0.00,1.00 +1256,86.40,-14.40,1.00,0.00,1.00 +1257,81.60,-14.40,1.00,0.00,1.00 +1258,76.80,-14.40,1.00,0.00,1.00 +1259,72.00,-14.40,1.00,0.00,1.00 +1260,67.20,-14.40,1.00,0.00,1.00 +1261,62.40,-14.40,1.00,0.00,1.00 +1262,57.60,-14.40,1.00,0.00,1.00 +1263,52.80,-9.60,1.00,0.00,1.00 +1264,48.00,-9.60,1.00,0.00,1.00 +1265,43.20,-9.60,1.00,0.00,1.00 +1266,38.40,-9.60,1.00,0.00,1.00 +1267,33.60,-9.60,1.00,0.00,1.00 +1268,28.80,-4.80,1.00,0.00,1.00 +1269,24.00,-4.80,1.00,0.00,1.00 +1270,19.20,-4.80,1.00,0.00,1.00 +1271,14.40,-4.80,1.00,0.00,1.00 +1272,9.60,-0.00,1.00,0.00,1.00 +1273,4.80,-0.00,1.00,0.00,1.00 +1274,0.00,0.00,1.00,0.00,1.00 +1275,-4.80,0.00,1.00,0.00,1.00 +1276,-9.60,0.00,1.00,0.00,1.00 +1277,-14.40,0.00,1.00,0.00,1.00 +1278,-19.20,4.80,1.00,0.00,1.00 +1279,-24.00,4.80,1.00,0.00,1.00 +1280,-28.80,4.80,1.00,0.00,1.00 +1281,-33.60,4.80,1.00,0.00,1.00 +1282,-38.40,4.80,1.00,0.00,1.00 +1283,-43.20,4.80,1.00,0.00,1.00 +1284,-48.00,4.80,1.00,0.00,1.00 +1285,-52.80,9.60,1.00,0.00,1.00 +1286,-57.60,9.60,1.00,0.00,1.00 +1287,-62.40,9.60,1.00,0.00,1.00 +1288,-67.20,9.60,1.00,0.00,1.00 +1289,-72.00,9.60,1.00,0.00,1.00 +1290,-76.80,9.60,1.00,0.00,1.00 +1291,-81.60,9.60,1.00,0.00,1.00 +1292,-86.40,9.60,1.00,0.00,1.00 +1293,-91.20,9.60,1.00,0.00,1.00 +1294,-96.00,9.60,1.00,0.00,1.00 +1295,-100.80,9.60,1.00,0.00,1.00 +1296,-105.60,9.60,1.00,0.00,1.00 +1297,-110.40,9.60,1.00,0.00,1.00 +1298,-115.20,9.60,1.00,0.00,1.00 +1299,-120.00,9.60,1.00,0.00,1.00 +1300,-124.80,9.60,1.00,0.00,1.00 +1301,-129.60,9.60,1.00,0.00,1.00 +1302,-134.40,4.80,1.00,0.00,1.00 +1303,-139.20,4.80,1.00,0.00,1.00 +1304,-144.00,4.80,1.00,0.00,1.00 +1305,-148.80,4.80,1.00,0.00,1.00 +1306,-153.60,4.80,1.00,0.00,1.00 +1307,-158.40,4.80,1.00,0.00,1.00 +1308,-163.20,4.80,1.00,0.00,1.00 +1309,-168.00,0.00,1.00,0.00,1.00 +1310,-172.80,0.00,1.00,0.00,1.00 +1311,-177.60,0.00,1.00,0.00,1.00 +1312,177.60,-0.00,1.00,0.00,1.00 +1313,172.80,-0.00,1.00,0.00,1.00 +1314,168.00,-0.00,1.00,0.00,1.00 +1315,163.20,-4.80,1.00,0.00,1.00 +1316,158.40,-4.80,1.00,0.00,1.00 +1317,153.60,-4.80,1.00,0.00,1.00 +1318,148.80,-4.80,1.00,0.00,1.00 +1319,144.00,-4.80,1.00,0.00,1.00 +1320,139.20,-4.80,1.00,0.00,1.00 +1321,134.40,-4.80,1.00,0.00,1.00 +1322,129.60,-9.60,1.00,0.00,1.00 +1323,124.80,-9.60,1.00,0.00,1.00 +1324,120.00,-9.60,1.00,0.00,1.00 +1325,115.20,-9.60,1.00,0.00,1.00 +1326,110.40,-9.60,1.00,0.00,1.00 +1327,105.60,-9.60,1.00,0.00,1.00 +1328,100.80,-9.60,1.00,0.00,1.00 +1329,96.00,-9.60,1.00,0.00,1.00 +1330,91.20,-9.60,1.00,0.00,1.00 +1331,86.40,-9.60,1.00,0.00,1.00 +1332,81.60,-9.60,1.00,0.00,1.00 +1333,76.80,-9.60,1.00,0.00,1.00 +1334,72.00,-9.60,1.00,0.00,1.00 +1335,67.20,-9.60,1.00,0.00,1.00 +1336,62.40,-9.60,1.00,0.00,1.00 +1337,57.60,-9.60,1.00,0.00,1.00 +1338,52.80,-9.60,1.00,0.00,1.00 +1339,48.00,-4.80,1.00,0.00,1.00 +1340,43.20,-4.80,1.00,0.00,1.00 +1341,38.40,-4.80,1.00,0.00,1.00 +1342,33.60,-4.80,1.00,0.00,1.00 +1343,28.80,-4.80,1.00,0.00,1.00 +1344,24.00,-4.80,1.00,0.00,1.00 +1345,19.20,-4.80,1.00,0.00,1.00 +1346,14.40,-0.00,1.00,0.00,1.00 +1347,9.60,-0.00,1.00,0.00,1.00 +1348,4.80,-0.00,1.00,0.00,1.00 +1349,0.00,0.00,1.00,0.00,1.00 +1350,-4.80,0.00,1.00,0.00,1.00 +1351,-9.60,0.00,1.00,0.00,1.00 +1352,-14.40,0.00,1.00,0.00,1.00 +1353,-19.20,0.00,1.00,0.00,1.00 +1354,-24.00,0.00,1.00,0.00,1.00 +1355,-28.80,0.00,1.00,0.00,1.00 +1356,-33.60,4.80,1.00,0.00,1.00 +1357,-38.40,4.80,1.00,0.00,1.00 +1358,-43.20,4.80,1.00,0.00,1.00 +1359,-48.00,4.80,1.00,0.00,1.00 +1360,-52.80,4.80,1.00,0.00,1.00 +1361,-57.60,4.80,1.00,0.00,1.00 +1362,-62.40,4.80,1.00,0.00,1.00 +1363,-67.20,4.80,1.00,0.00,1.00 +1364,-72.00,4.80,1.00,0.00,1.00 +1365,-76.80,4.80,1.00,0.00,1.00 +1366,-81.60,4.80,1.00,0.00,1.00 +1367,-86.40,4.80,1.00,0.00,1.00 +1368,-91.20,4.80,1.00,0.00,1.00 +1369,-96.00,4.80,1.00,0.00,1.00 +1370,-100.80,4.80,1.00,0.00,1.00 +1371,-105.60,4.80,1.00,0.00,1.00 +1372,-110.40,4.80,1.00,0.00,1.00 +1373,-115.20,4.80,1.00,0.00,1.00 +1374,-120.00,4.80,1.00,0.00,1.00 +1375,-124.80,4.80,1.00,0.00,1.00 +1376,-129.60,4.80,1.00,0.00,1.00 +1377,-134.40,4.80,1.00,0.00,1.00 +1378,-139.20,4.80,1.00,0.00,1.00 +1379,-144.00,4.80,1.00,0.00,1.00 +1380,-148.80,4.80,1.00,0.00,1.00 +1381,-153.60,0.00,1.00,0.00,1.00 +1382,-158.40,0.00,1.00,0.00,1.00 +1383,-163.20,0.00,1.00,0.00,1.00 +1384,-168.00,0.00,1.00,0.00,1.00 +1385,-172.80,0.00,1.00,0.00,1.00 +1386,-177.60,0.00,1.00,0.00,1.00 +1387,177.60,-0.00,1.00,0.00,1.00 +1388,172.80,-0.00,1.00,0.00,1.00 +1389,168.00,-0.00,1.00,0.00,1.00 +1390,163.20,-0.00,1.00,0.00,1.00 +1391,158.40,-0.00,1.00,0.00,1.00 +1392,153.60,-0.00,1.00,0.00,1.00 +1393,148.80,-4.80,1.00,0.00,1.00 +1394,144.00,-4.80,1.00,0.00,1.00 +1395,139.20,-4.80,1.00,0.00,1.00 +1396,134.40,-4.80,1.00,0.00,1.00 +1397,129.60,-4.80,1.00,0.00,1.00 +1398,124.80,-4.80,1.00,0.00,1.00 +1399,120.00,-4.80,1.00,0.00,1.00 +1400,115.20,-4.80,1.00,0.00,1.00 +1401,110.40,-4.80,1.00,0.00,1.00 +1402,105.60,-4.80,1.00,0.00,1.00 +1403,100.80,-4.80,1.00,0.00,1.00 +1404,96.00,-4.80,1.00,0.00,1.00 +1405,91.20,-4.80,1.00,0.00,1.00 +1406,86.40,-4.80,1.00,0.00,1.00 +1407,81.60,-4.80,1.00,0.00,1.00 +1408,76.80,-4.80,1.00,0.00,1.00 +1409,72.00,-4.80,1.00,0.00,1.00 +1410,67.20,-4.80,1.00,0.00,1.00 +1411,62.40,-4.80,1.00,0.00,1.00 +1412,57.60,-4.80,1.00,0.00,1.00 +1413,52.80,-4.80,1.00,0.00,1.00 +1414,48.00,-4.80,1.00,0.00,1.00 +1415,43.20,-4.80,1.00,0.00,1.00 +1416,38.40,-4.80,1.00,0.00,1.00 +1417,33.60,-4.80,1.00,0.00,1.00 +1418,28.80,-0.00,1.00,0.00,1.00 +1419,24.00,-0.00,1.00,0.00,1.00 +1420,19.20,-0.00,1.00,0.00,1.00 +1421,14.40,-0.00,1.00,0.00,1.00 +1422,9.60,-0.00,1.00,0.00,1.00 +1423,4.80,-0.00,1.00,0.00,1.00 +1424,0.00,0.00,1.00,0.00,1.00 +1425,-4.80,0.00,1.00,0.00,1.00 +1426,-9.60,0.00,1.00,0.00,1.00 +1427,-14.40,0.00,1.00,0.00,1.00 +1428,-19.20,0.00,1.00,0.00,1.00 +1429,-24.00,0.00,1.00,0.00,1.00 +1430,-28.80,0.00,1.00,0.00,1.00 +1431,-33.60,0.00,1.00,0.00,1.00 +1432,-38.40,0.00,1.00,0.00,1.00 +1433,-43.20,0.00,1.00,0.00,1.00 +1434,-48.00,0.00,1.00,0.00,1.00 +1435,-52.80,0.00,1.00,0.00,1.00 +1436,-57.60,0.00,1.00,0.00,1.00 +1437,-62.40,0.00,1.00,0.00,1.00 +1438,-67.20,0.00,1.00,0.00,1.00 +1439,-72.00,0.00,1.00,0.00,1.00 +1440,-76.80,0.00,1.00,0.00,1.00 +1441,-81.60,0.00,1.00,0.00,1.00 +1442,-86.40,0.00,1.00,0.00,1.00 +1443,-91.20,0.00,1.00,0.00,1.00 +1444,-96.00,0.00,1.00,0.00,1.00 +1445,-100.80,0.00,1.00,0.00,1.00 +1446,-105.60,0.00,1.00,0.00,1.00 +1447,-110.40,0.00,1.00,0.00,1.00 +1448,-115.20,0.00,1.00,0.00,1.00 +1449,-120.00,0.00,1.00,0.00,1.00 +1450,-124.80,0.00,1.00,0.00,1.00 +1451,-129.60,0.00,1.00,0.00,1.00 +1452,-134.40,0.00,1.00,0.00,1.00 +1453,-139.20,0.00,1.00,0.00,1.00 +1454,-144.00,0.00,1.00,0.00,1.00 +1455,-148.80,0.00,1.00,0.00,1.00 +1456,-153.60,0.00,1.00,0.00,1.00 +1457,-158.40,0.00,1.00,0.00,1.00 +1458,-163.20,0.00,1.00,0.00,1.00 +1459,-168.00,0.00,1.00,0.00,1.00 +1460,-172.80,0.00,1.00,0.00,1.00 +1461,-177.60,0.00,1.00,0.00,1.00 +1462,177.60,0.00,1.00,0.00,1.00 +1463,172.80,0.00,1.00,0.00,1.00 +1464,168.00,0.00,1.00,0.00,1.00 +1465,163.20,0.00,1.00,0.00,1.00 +1466,158.40,0.00,1.00,0.00,1.00 +1467,153.60,0.00,1.00,0.00,1.00 +1468,148.80,0.00,1.00,0.00,1.00 +1469,144.00,0.00,1.00,0.00,1.00 +1470,139.20,0.00,1.00,0.00,1.00 +1471,134.40,0.00,1.00,0.00,1.00 +1472,129.60,0.00,1.00,0.00,1.00 +1473,124.80,0.00,1.00,0.00,1.00 +1474,120.00,0.00,1.00,0.00,1.00 +1475,115.20,0.00,1.00,0.00,1.00 +1476,110.40,0.00,1.00,0.00,1.00 +1477,105.60,0.00,1.00,0.00,1.00 +1478,100.80,0.00,1.00,0.00,1.00 +1479,96.00,0.00,1.00,0.00,1.00 +1480,91.20,0.00,1.00,0.00,1.00 +1481,86.40,0.00,1.00,0.00,1.00 +1482,81.60,0.00,1.00,0.00,1.00 +1483,76.80,0.00,1.00,0.00,1.00 +1484,72.00,0.00,1.00,0.00,1.00 +1485,67.20,0.00,1.00,0.00,1.00 +1486,62.40,0.00,1.00,0.00,1.00 +1487,57.60,0.00,1.00,0.00,1.00 +1488,52.80,0.00,1.00,0.00,1.00 +1489,48.00,0.00,1.00,0.00,1.00 +1490,43.20,0.00,1.00,0.00,1.00 +1491,38.40,0.00,1.00,0.00,1.00 +1492,33.60,0.00,1.00,0.00,1.00 +1493,28.80,0.00,1.00,0.00,1.00 +1494,24.00,0.00,1.00,0.00,1.00 +1495,19.20,0.00,1.00,0.00,1.00 +1496,14.40,0.00,1.00,0.00,1.00 +1497,9.60,0.00,1.00,0.00,1.00 +1498,4.80,0.00,1.00,0.00,1.00 +1499,0.00,0.00,1.00,0.00,1.00 diff --git a/scripts/tests/data/stvISM3.csv b/scripts/tests/data/stvISM3.csv new file mode 100644 index 0000000000..6b57caab12 --- /dev/null +++ b/scripts/tests/data/stvISM3.csv @@ -0,0 +1,1500 @@ +0,0.00,0.00,1.00,0.00,1.00 +1,-177.60,-4.80,1.00,0.00,1.00 +2,4.80,4.80,1.00,0.00,1.00 +3,-168.00,-9.60,1.00,0.00,1.00 +4,14.40,14.40,1.00,0.00,1.00 +5,-163.20,-14.40,1.00,0.00,1.00 +6,19.20,19.20,1.00,0.00,1.00 +7,-153.60,-24.00,1.00,0.00,1.00 +8,28.80,24.00,1.00,0.00,1.00 +9,-148.80,-28.80,1.00,0.00,1.00 +10,38.40,33.60,1.00,0.00,1.00 +11,-139.20,-33.60,1.00,0.00,1.00 +12,48.00,38.40,1.00,0.00,1.00 +13,-124.80,-38.40,1.00,0.00,1.00 +14,57.60,38.40,1.00,0.00,1.00 +15,-115.20,-43.20,1.00,0.00,1.00 +16,72.00,43.20,1.00,0.00,1.00 +17,-100.80,-43.20,1.00,0.00,1.00 +18,86.40,43.20,1.00,0.00,1.00 +19,-86.40,-43.20,1.00,0.00,1.00 +20,100.80,43.20,1.00,0.00,1.00 +21,-76.80,-43.20,1.00,0.00,1.00 +22,110.40,43.20,1.00,0.00,1.00 +23,-62.40,-43.20,1.00,0.00,1.00 +24,124.80,38.40,1.00,0.00,1.00 +25,-52.80,-38.40,1.00,0.00,1.00 +26,134.40,33.60,1.00,0.00,1.00 +27,-38.40,-33.60,1.00,0.00,1.00 +28,144.00,28.80,1.00,0.00,1.00 +29,-33.60,-28.80,1.00,0.00,1.00 +30,153.60,24.00,1.00,0.00,1.00 +31,-24.00,-19.20,1.00,0.00,1.00 +32,158.40,19.20,1.00,0.00,1.00 +33,-14.40,-14.40,1.00,0.00,1.00 +34,168.00,9.60,1.00,0.00,1.00 +35,-9.60,-9.60,1.00,0.00,1.00 +36,172.80,4.80,1.00,0.00,1.00 +37,-0.00,-0.00,1.00,0.00,1.00 +38,-177.60,-0.00,1.00,0.00,1.00 +39,4.80,4.80,1.00,0.00,1.00 +40,-172.80,-9.60,1.00,0.00,1.00 +41,14.40,9.60,1.00,0.00,1.00 +42,-163.20,-14.40,1.00,0.00,1.00 +43,19.20,19.20,1.00,0.00,1.00 +44,-158.40,-19.20,1.00,0.00,1.00 +45,28.80,24.00,1.00,0.00,1.00 +46,-148.80,-28.80,1.00,0.00,1.00 +47,33.60,28.80,1.00,0.00,1.00 +48,-139.20,-33.60,1.00,0.00,1.00 +49,43.20,33.60,1.00,0.00,1.00 +50,-129.60,-38.40,1.00,0.00,1.00 +51,57.60,38.40,1.00,0.00,1.00 +52,-120.00,-43.20,1.00,0.00,1.00 +53,67.20,43.20,1.00,0.00,1.00 +54,-105.60,-43.20,1.00,0.00,1.00 +55,81.60,43.20,1.00,0.00,1.00 +56,-91.20,-43.20,1.00,0.00,1.00 +57,96.00,43.20,1.00,0.00,1.00 +58,-76.80,-43.20,1.00,0.00,1.00 +59,110.40,43.20,1.00,0.00,1.00 +60,-67.20,-43.20,1.00,0.00,1.00 +61,120.00,38.40,1.00,0.00,1.00 +62,-52.80,-38.40,1.00,0.00,1.00 +63,129.60,38.40,1.00,0.00,1.00 +64,-43.20,-33.60,1.00,0.00,1.00 +65,144.00,33.60,1.00,0.00,1.00 +66,-33.60,-28.80,1.00,0.00,1.00 +67,148.80,24.00,1.00,0.00,1.00 +68,-24.00,-24.00,1.00,0.00,1.00 +69,158.40,19.20,1.00,0.00,1.00 +70,-19.20,-14.40,1.00,0.00,1.00 +71,168.00,14.40,1.00,0.00,1.00 +72,-9.60,-9.60,1.00,0.00,1.00 +73,172.80,4.80,1.00,0.00,1.00 +74,-4.80,-4.80,1.00,0.00,1.00 +75,0.00,0.00,1.00,0.00,1.00 +76,-177.60,-4.80,1.00,0.00,1.00 +77,9.60,4.80,1.00,0.00,1.00 +78,-168.00,-9.60,1.00,0.00,1.00 +79,14.40,14.40,1.00,0.00,1.00 +80,-163.20,-14.40,1.00,0.00,1.00 +81,24.00,19.20,1.00,0.00,1.00 +82,-153.60,-19.20,1.00,0.00,1.00 +83,28.80,24.00,1.00,0.00,1.00 +84,-144.00,-24.00,1.00,0.00,1.00 +85,38.40,28.80,1.00,0.00,1.00 +86,-134.40,-28.80,1.00,0.00,1.00 +87,48.00,33.60,1.00,0.00,1.00 +88,-124.80,-33.60,1.00,0.00,1.00 +89,62.40,38.40,1.00,0.00,1.00 +90,-115.20,-38.40,1.00,0.00,1.00 +91,72.00,38.40,1.00,0.00,1.00 +92,-100.80,-38.40,1.00,0.00,1.00 +93,86.40,38.40,1.00,0.00,1.00 +94,-86.40,-38.40,1.00,0.00,1.00 +95,96.00,38.40,1.00,0.00,1.00 +96,-76.80,-38.40,1.00,0.00,1.00 +97,110.40,38.40,1.00,0.00,1.00 +98,-62.40,-38.40,1.00,0.00,1.00 +99,120.00,33.60,1.00,0.00,1.00 +100,-52.80,-33.60,1.00,0.00,1.00 +101,134.40,33.60,1.00,0.00,1.00 +102,-43.20,-28.80,1.00,0.00,1.00 +103,144.00,28.80,1.00,0.00,1.00 +104,-33.60,-24.00,1.00,0.00,1.00 +105,148.80,24.00,1.00,0.00,1.00 +106,-24.00,-19.20,1.00,0.00,1.00 +107,158.40,14.40,1.00,0.00,1.00 +108,-19.20,-14.40,1.00,0.00,1.00 +109,168.00,9.60,1.00,0.00,1.00 +110,-9.60,-9.60,1.00,0.00,1.00 +111,172.80,4.80,1.00,0.00,1.00 +112,-0.00,-0.00,1.00,0.00,1.00 +113,-177.60,-0.00,1.00,0.00,1.00 +114,4.80,4.80,1.00,0.00,1.00 +115,-172.80,-9.60,1.00,0.00,1.00 +116,14.40,9.60,1.00,0.00,1.00 +117,-163.20,-14.40,1.00,0.00,1.00 +118,19.20,14.40,1.00,0.00,1.00 +119,-153.60,-19.20,1.00,0.00,1.00 +120,28.80,24.00,1.00,0.00,1.00 +121,-148.80,-24.00,1.00,0.00,1.00 +122,38.40,28.80,1.00,0.00,1.00 +123,-139.20,-28.80,1.00,0.00,1.00 +124,48.00,33.60,1.00,0.00,1.00 +125,-124.80,-33.60,1.00,0.00,1.00 +126,57.60,33.60,1.00,0.00,1.00 +127,-115.20,-38.40,1.00,0.00,1.00 +128,72.00,38.40,1.00,0.00,1.00 +129,-105.60,-38.40,1.00,0.00,1.00 +130,81.60,38.40,1.00,0.00,1.00 +131,-91.20,-38.40,1.00,0.00,1.00 +132,96.00,38.40,1.00,0.00,1.00 +133,-76.80,-38.40,1.00,0.00,1.00 +134,105.60,38.40,1.00,0.00,1.00 +135,-67.20,-38.40,1.00,0.00,1.00 +136,120.00,38.40,1.00,0.00,1.00 +137,-57.60,-33.60,1.00,0.00,1.00 +138,129.60,33.60,1.00,0.00,1.00 +139,-43.20,-28.80,1.00,0.00,1.00 +140,139.20,28.80,1.00,0.00,1.00 +141,-33.60,-24.00,1.00,0.00,1.00 +142,148.80,24.00,1.00,0.00,1.00 +143,-28.80,-19.20,1.00,0.00,1.00 +144,158.40,19.20,1.00,0.00,1.00 +145,-19.20,-14.40,1.00,0.00,1.00 +146,163.20,14.40,1.00,0.00,1.00 +147,-9.60,-9.60,1.00,0.00,1.00 +148,172.80,4.80,1.00,0.00,1.00 +149,-4.80,-4.80,1.00,0.00,1.00 +150,0.00,0.00,1.00,0.00,1.00 +151,-177.60,-4.80,1.00,0.00,1.00 +152,9.60,4.80,1.00,0.00,1.00 +153,-168.00,-9.60,1.00,0.00,1.00 +154,14.40,9.60,1.00,0.00,1.00 +155,-158.40,-14.40,1.00,0.00,1.00 +156,24.00,14.40,1.00,0.00,1.00 +157,-153.60,-19.20,1.00,0.00,1.00 +158,33.60,19.20,1.00,0.00,1.00 +159,-144.00,-24.00,1.00,0.00,1.00 +160,43.20,24.00,1.00,0.00,1.00 +161,-134.40,-28.80,1.00,0.00,1.00 +162,52.80,28.80,1.00,0.00,1.00 +163,-124.80,-28.80,1.00,0.00,1.00 +164,62.40,33.60,1.00,0.00,1.00 +165,-110.40,-33.60,1.00,0.00,1.00 +166,72.00,33.60,1.00,0.00,1.00 +167,-100.80,-33.60,1.00,0.00,1.00 +168,86.40,33.60,1.00,0.00,1.00 +169,-86.40,-33.60,1.00,0.00,1.00 +170,96.00,33.60,1.00,0.00,1.00 +171,-76.80,-33.60,1.00,0.00,1.00 +172,110.40,33.60,1.00,0.00,1.00 +173,-67.20,-33.60,1.00,0.00,1.00 +174,120.00,33.60,1.00,0.00,1.00 +175,-52.80,-28.80,1.00,0.00,1.00 +176,129.60,28.80,1.00,0.00,1.00 +177,-43.20,-28.80,1.00,0.00,1.00 +178,139.20,24.00,1.00,0.00,1.00 +179,-33.60,-24.00,1.00,0.00,1.00 +180,148.80,19.20,1.00,0.00,1.00 +181,-24.00,-19.20,1.00,0.00,1.00 +182,158.40,14.40,1.00,0.00,1.00 +183,-19.20,-14.40,1.00,0.00,1.00 +184,168.00,9.60,1.00,0.00,1.00 +185,-9.60,-4.80,1.00,0.00,1.00 +186,172.80,4.80,1.00,0.00,1.00 +187,-0.00,-0.00,1.00,0.00,1.00 +188,-177.60,-0.00,1.00,0.00,1.00 +189,4.80,4.80,1.00,0.00,1.00 +190,-168.00,-4.80,1.00,0.00,1.00 +191,14.40,9.60,1.00,0.00,1.00 +192,-163.20,-14.40,1.00,0.00,1.00 +193,24.00,14.40,1.00,0.00,1.00 +194,-153.60,-19.20,1.00,0.00,1.00 +195,28.80,19.20,1.00,0.00,1.00 +196,-144.00,-24.00,1.00,0.00,1.00 +197,38.40,24.00,1.00,0.00,1.00 +198,-134.40,-28.80,1.00,0.00,1.00 +199,48.00,28.80,1.00,0.00,1.00 +200,-124.80,-28.80,1.00,0.00,1.00 +201,62.40,33.60,1.00,0.00,1.00 +202,-115.20,-33.60,1.00,0.00,1.00 +203,72.00,33.60,1.00,0.00,1.00 +204,-100.80,-33.60,1.00,0.00,1.00 +205,81.60,33.60,1.00,0.00,1.00 +206,-91.20,-33.60,1.00,0.00,1.00 +207,96.00,33.60,1.00,0.00,1.00 +208,-81.60,-33.60,1.00,0.00,1.00 +209,105.60,33.60,1.00,0.00,1.00 +210,-67.20,-33.60,1.00,0.00,1.00 +211,115.20,33.60,1.00,0.00,1.00 +212,-57.60,-28.80,1.00,0.00,1.00 +213,129.60,28.80,1.00,0.00,1.00 +214,-48.00,-28.80,1.00,0.00,1.00 +215,139.20,24.00,1.00,0.00,1.00 +216,-38.40,-24.00,1.00,0.00,1.00 +217,148.80,19.20,1.00,0.00,1.00 +218,-28.80,-19.20,1.00,0.00,1.00 +219,153.60,14.40,1.00,0.00,1.00 +220,-19.20,-14.40,1.00,0.00,1.00 +221,163.20,9.60,1.00,0.00,1.00 +222,-9.60,-9.60,1.00,0.00,1.00 +223,172.80,4.80,1.00,0.00,1.00 +224,-4.80,-4.80,1.00,0.00,1.00 +225,0.00,0.00,1.00,0.00,1.00 +226,-177.60,-4.80,1.00,0.00,1.00 +227,9.60,4.80,1.00,0.00,1.00 +228,-168.00,-9.60,1.00,0.00,1.00 +229,14.40,9.60,1.00,0.00,1.00 +230,-158.40,-9.60,1.00,0.00,1.00 +231,24.00,14.40,1.00,0.00,1.00 +232,-148.80,-14.40,1.00,0.00,1.00 +233,33.60,19.20,1.00,0.00,1.00 +234,-139.20,-19.20,1.00,0.00,1.00 +235,43.20,24.00,1.00,0.00,1.00 +236,-129.60,-24.00,1.00,0.00,1.00 +237,52.80,24.00,1.00,0.00,1.00 +238,-120.00,-28.80,1.00,0.00,1.00 +239,62.40,28.80,1.00,0.00,1.00 +240,-110.40,-28.80,1.00,0.00,1.00 +241,76.80,28.80,1.00,0.00,1.00 +242,-100.80,-28.80,1.00,0.00,1.00 +243,86.40,28.80,1.00,0.00,1.00 +244,-86.40,-28.80,1.00,0.00,1.00 +245,96.00,28.80,1.00,0.00,1.00 +246,-76.80,-28.80,1.00,0.00,1.00 +247,105.60,28.80,1.00,0.00,1.00 +248,-67.20,-28.80,1.00,0.00,1.00 +249,120.00,28.80,1.00,0.00,1.00 +250,-57.60,-24.00,1.00,0.00,1.00 +251,129.60,24.00,1.00,0.00,1.00 +252,-48.00,-24.00,1.00,0.00,1.00 +253,139.20,19.20,1.00,0.00,1.00 +254,-38.40,-19.20,1.00,0.00,1.00 +255,148.80,19.20,1.00,0.00,1.00 +256,-28.80,-14.40,1.00,0.00,1.00 +257,158.40,14.40,1.00,0.00,1.00 +258,-19.20,-9.60,1.00,0.00,1.00 +259,163.20,9.60,1.00,0.00,1.00 +260,-9.60,-4.80,1.00,0.00,1.00 +261,172.80,4.80,1.00,0.00,1.00 +262,-0.00,-0.00,1.00,0.00,1.00 +263,-177.60,-0.00,1.00,0.00,1.00 +264,4.80,4.80,1.00,0.00,1.00 +265,-168.00,-4.80,1.00,0.00,1.00 +266,14.40,9.60,1.00,0.00,1.00 +267,-163.20,-9.60,1.00,0.00,1.00 +268,24.00,14.40,1.00,0.00,1.00 +269,-153.60,-14.40,1.00,0.00,1.00 +270,33.60,19.20,1.00,0.00,1.00 +271,-144.00,-19.20,1.00,0.00,1.00 +272,43.20,19.20,1.00,0.00,1.00 +273,-134.40,-24.00,1.00,0.00,1.00 +274,52.80,24.00,1.00,0.00,1.00 +275,-124.80,-24.00,1.00,0.00,1.00 +276,62.40,28.80,1.00,0.00,1.00 +277,-115.20,-28.80,1.00,0.00,1.00 +278,72.00,28.80,1.00,0.00,1.00 +279,-100.80,-28.80,1.00,0.00,1.00 +280,81.60,28.80,1.00,0.00,1.00 +281,-91.20,-28.80,1.00,0.00,1.00 +282,96.00,28.80,1.00,0.00,1.00 +283,-81.60,-28.80,1.00,0.00,1.00 +284,105.60,28.80,1.00,0.00,1.00 +285,-67.20,-28.80,1.00,0.00,1.00 +286,115.20,28.80,1.00,0.00,1.00 +287,-57.60,-28.80,1.00,0.00,1.00 +288,124.80,24.00,1.00,0.00,1.00 +289,-48.00,-24.00,1.00,0.00,1.00 +290,134.40,24.00,1.00,0.00,1.00 +291,-38.40,-19.20,1.00,0.00,1.00 +292,144.00,19.20,1.00,0.00,1.00 +293,-28.80,-14.40,1.00,0.00,1.00 +294,153.60,14.40,1.00,0.00,1.00 +295,-19.20,-9.60,1.00,0.00,1.00 +296,163.20,9.60,1.00,0.00,1.00 +297,-14.40,-9.60,1.00,0.00,1.00 +298,172.80,4.80,1.00,0.00,1.00 +299,-4.80,-4.80,1.00,0.00,1.00 +300,0.00,0.00,1.00,0.00,1.00 +301,-177.60,-0.00,1.00,0.00,1.00 +302,9.60,4.80,1.00,0.00,1.00 +303,-168.00,-4.80,1.00,0.00,1.00 +304,19.20,9.60,1.00,0.00,1.00 +305,-158.40,-9.60,1.00,0.00,1.00 +306,24.00,14.40,1.00,0.00,1.00 +307,-148.80,-14.40,1.00,0.00,1.00 +308,33.60,14.40,1.00,0.00,1.00 +309,-139.20,-19.20,1.00,0.00,1.00 +310,43.20,19.20,1.00,0.00,1.00 +311,-129.60,-19.20,1.00,0.00,1.00 +312,52.80,19.20,1.00,0.00,1.00 +313,-120.00,-24.00,1.00,0.00,1.00 +314,67.20,24.00,1.00,0.00,1.00 +315,-110.40,-24.00,1.00,0.00,1.00 +316,76.80,24.00,1.00,0.00,1.00 +317,-100.80,-24.00,1.00,0.00,1.00 +318,86.40,24.00,1.00,0.00,1.00 +319,-86.40,-24.00,1.00,0.00,1.00 +320,96.00,24.00,1.00,0.00,1.00 +321,-76.80,-24.00,1.00,0.00,1.00 +322,105.60,24.00,1.00,0.00,1.00 +323,-67.20,-24.00,1.00,0.00,1.00 +324,115.20,24.00,1.00,0.00,1.00 +325,-57.60,-24.00,1.00,0.00,1.00 +326,129.60,19.20,1.00,0.00,1.00 +327,-48.00,-19.20,1.00,0.00,1.00 +328,139.20,19.20,1.00,0.00,1.00 +329,-38.40,-14.40,1.00,0.00,1.00 +330,148.80,14.40,1.00,0.00,1.00 +331,-28.80,-14.40,1.00,0.00,1.00 +332,153.60,9.60,1.00,0.00,1.00 +333,-19.20,-9.60,1.00,0.00,1.00 +334,163.20,9.60,1.00,0.00,1.00 +335,-9.60,-4.80,1.00,0.00,1.00 +336,172.80,4.80,1.00,0.00,1.00 +337,-0.00,-0.00,1.00,0.00,1.00 +338,-177.60,-0.00,1.00,0.00,1.00 +339,4.80,4.80,1.00,0.00,1.00 +340,-168.00,-4.80,1.00,0.00,1.00 +341,14.40,9.60,1.00,0.00,1.00 +342,-158.40,-9.60,1.00,0.00,1.00 +343,24.00,9.60,1.00,0.00,1.00 +344,-153.60,-14.40,1.00,0.00,1.00 +345,33.60,14.40,1.00,0.00,1.00 +346,-144.00,-14.40,1.00,0.00,1.00 +347,43.20,19.20,1.00,0.00,1.00 +348,-134.40,-19.20,1.00,0.00,1.00 +349,52.80,19.20,1.00,0.00,1.00 +350,-124.80,-24.00,1.00,0.00,1.00 +351,62.40,24.00,1.00,0.00,1.00 +352,-110.40,-24.00,1.00,0.00,1.00 +353,72.00,24.00,1.00,0.00,1.00 +354,-100.80,-24.00,1.00,0.00,1.00 +355,81.60,24.00,1.00,0.00,1.00 +356,-91.20,-24.00,1.00,0.00,1.00 +357,96.00,24.00,1.00,0.00,1.00 +358,-81.60,-24.00,1.00,0.00,1.00 +359,105.60,24.00,1.00,0.00,1.00 +360,-72.00,-24.00,1.00,0.00,1.00 +361,115.20,24.00,1.00,0.00,1.00 +362,-57.60,-24.00,1.00,0.00,1.00 +363,124.80,19.20,1.00,0.00,1.00 +364,-48.00,-19.20,1.00,0.00,1.00 +365,134.40,19.20,1.00,0.00,1.00 +366,-38.40,-19.20,1.00,0.00,1.00 +367,144.00,14.40,1.00,0.00,1.00 +368,-28.80,-14.40,1.00,0.00,1.00 +369,153.60,14.40,1.00,0.00,1.00 +370,-24.00,-9.60,1.00,0.00,1.00 +371,163.20,9.60,1.00,0.00,1.00 +372,-14.40,-4.80,1.00,0.00,1.00 +373,172.80,4.80,1.00,0.00,1.00 +374,-4.80,-0.00,1.00,0.00,1.00 +375,0.00,0.00,1.00,0.00,1.00 +376,-177.60,-0.00,1.00,0.00,1.00 +377,9.60,4.80,1.00,0.00,1.00 +378,-168.00,-4.80,1.00,0.00,1.00 +379,19.20,4.80,1.00,0.00,1.00 +380,-158.40,-9.60,1.00,0.00,1.00 +381,28.80,9.60,1.00,0.00,1.00 +382,-148.80,-9.60,1.00,0.00,1.00 +383,38.40,14.40,1.00,0.00,1.00 +384,-139.20,-14.40,1.00,0.00,1.00 +385,48.00,14.40,1.00,0.00,1.00 +386,-129.60,-14.40,1.00,0.00,1.00 +387,57.60,19.20,1.00,0.00,1.00 +388,-120.00,-19.20,1.00,0.00,1.00 +389,67.20,19.20,1.00,0.00,1.00 +390,-110.40,-19.20,1.00,0.00,1.00 +391,76.80,19.20,1.00,0.00,1.00 +392,-100.80,-19.20,1.00,0.00,1.00 +393,86.40,19.20,1.00,0.00,1.00 +394,-86.40,-19.20,1.00,0.00,1.00 +395,96.00,19.20,1.00,0.00,1.00 +396,-76.80,-19.20,1.00,0.00,1.00 +397,105.60,19.20,1.00,0.00,1.00 +398,-67.20,-19.20,1.00,0.00,1.00 +399,115.20,19.20,1.00,0.00,1.00 +400,-57.60,-19.20,1.00,0.00,1.00 +401,124.80,19.20,1.00,0.00,1.00 +402,-48.00,-14.40,1.00,0.00,1.00 +403,134.40,14.40,1.00,0.00,1.00 +404,-38.40,-14.40,1.00,0.00,1.00 +405,144.00,14.40,1.00,0.00,1.00 +406,-28.80,-9.60,1.00,0.00,1.00 +407,153.60,9.60,1.00,0.00,1.00 +408,-19.20,-9.60,1.00,0.00,1.00 +409,163.20,4.80,1.00,0.00,1.00 +410,-9.60,-4.80,1.00,0.00,1.00 +411,172.80,4.80,1.00,0.00,1.00 +412,-0.00,-0.00,1.00,0.00,1.00 +413,-177.60,-0.00,1.00,0.00,1.00 +414,4.80,4.80,1.00,0.00,1.00 +415,-168.00,-4.80,1.00,0.00,1.00 +416,14.40,4.80,1.00,0.00,1.00 +417,-158.40,-9.60,1.00,0.00,1.00 +418,24.00,9.60,1.00,0.00,1.00 +419,-148.80,-9.60,1.00,0.00,1.00 +420,33.60,14.40,1.00,0.00,1.00 +421,-139.20,-14.40,1.00,0.00,1.00 +422,43.20,14.40,1.00,0.00,1.00 +423,-129.60,-14.40,1.00,0.00,1.00 +424,52.80,19.20,1.00,0.00,1.00 +425,-120.00,-19.20,1.00,0.00,1.00 +426,62.40,19.20,1.00,0.00,1.00 +427,-110.40,-19.20,1.00,0.00,1.00 +428,72.00,19.20,1.00,0.00,1.00 +429,-100.80,-19.20,1.00,0.00,1.00 +430,81.60,19.20,1.00,0.00,1.00 +431,-91.20,-19.20,1.00,0.00,1.00 +432,96.00,19.20,1.00,0.00,1.00 +433,-81.60,-19.20,1.00,0.00,1.00 +434,105.60,19.20,1.00,0.00,1.00 +435,-72.00,-19.20,1.00,0.00,1.00 +436,115.20,19.20,1.00,0.00,1.00 +437,-62.40,-19.20,1.00,0.00,1.00 +438,124.80,19.20,1.00,0.00,1.00 +439,-52.80,-14.40,1.00,0.00,1.00 +440,134.40,14.40,1.00,0.00,1.00 +441,-43.20,-14.40,1.00,0.00,1.00 +442,144.00,14.40,1.00,0.00,1.00 +443,-33.60,-9.60,1.00,0.00,1.00 +444,153.60,9.60,1.00,0.00,1.00 +445,-24.00,-9.60,1.00,0.00,1.00 +446,163.20,4.80,1.00,0.00,1.00 +447,-14.40,-4.80,1.00,0.00,1.00 +448,172.80,4.80,1.00,0.00,1.00 +449,-4.80,-0.00,1.00,0.00,1.00 +450,0.00,0.00,1.00,0.00,1.00 +451,-177.60,-0.00,1.00,0.00,1.00 +452,9.60,4.80,1.00,0.00,1.00 +453,-168.00,-4.80,1.00,0.00,1.00 +454,19.20,4.80,1.00,0.00,1.00 +455,-158.40,-4.80,1.00,0.00,1.00 +456,28.80,9.60,1.00,0.00,1.00 +457,-148.80,-9.60,1.00,0.00,1.00 +458,38.40,9.60,1.00,0.00,1.00 +459,-139.20,-9.60,1.00,0.00,1.00 +460,48.00,9.60,1.00,0.00,1.00 +461,-129.60,-14.40,1.00,0.00,1.00 +462,57.60,14.40,1.00,0.00,1.00 +463,-120.00,-14.40,1.00,0.00,1.00 +464,67.20,14.40,1.00,0.00,1.00 +465,-110.40,-14.40,1.00,0.00,1.00 +466,76.80,14.40,1.00,0.00,1.00 +467,-100.80,-14.40,1.00,0.00,1.00 +468,86.40,14.40,1.00,0.00,1.00 +469,-86.40,-14.40,1.00,0.00,1.00 +470,96.00,14.40,1.00,0.00,1.00 +471,-76.80,-14.40,1.00,0.00,1.00 +472,105.60,14.40,1.00,0.00,1.00 +473,-67.20,-14.40,1.00,0.00,1.00 +474,115.20,14.40,1.00,0.00,1.00 +475,-57.60,-14.40,1.00,0.00,1.00 +476,124.80,14.40,1.00,0.00,1.00 +477,-48.00,-14.40,1.00,0.00,1.00 +478,134.40,9.60,1.00,0.00,1.00 +479,-38.40,-9.60,1.00,0.00,1.00 +480,144.00,9.60,1.00,0.00,1.00 +481,-28.80,-9.60,1.00,0.00,1.00 +482,153.60,4.80,1.00,0.00,1.00 +483,-19.20,-4.80,1.00,0.00,1.00 +484,163.20,4.80,1.00,0.00,1.00 +485,-9.60,-4.80,1.00,0.00,1.00 +486,172.80,0.00,1.00,0.00,1.00 +487,-0.00,-0.00,1.00,0.00,1.00 +488,-177.60,-0.00,1.00,0.00,1.00 +489,4.80,0.00,1.00,0.00,1.00 +490,-168.00,-4.80,1.00,0.00,1.00 +491,14.40,4.80,1.00,0.00,1.00 +492,-158.40,-4.80,1.00,0.00,1.00 +493,24.00,4.80,1.00,0.00,1.00 +494,-148.80,-9.60,1.00,0.00,1.00 +495,33.60,9.60,1.00,0.00,1.00 +496,-139.20,-9.60,1.00,0.00,1.00 +497,43.20,9.60,1.00,0.00,1.00 +498,-129.60,-14.40,1.00,0.00,1.00 +499,52.80,14.40,1.00,0.00,1.00 +500,-120.00,-14.40,1.00,0.00,1.00 +501,62.40,14.40,1.00,0.00,1.00 +502,-110.40,-14.40,1.00,0.00,1.00 +503,72.00,14.40,1.00,0.00,1.00 +504,-100.80,-14.40,1.00,0.00,1.00 +505,81.60,14.40,1.00,0.00,1.00 +506,-91.20,-14.40,1.00,0.00,1.00 +507,96.00,14.40,1.00,0.00,1.00 +508,-81.60,-14.40,1.00,0.00,1.00 +509,105.60,14.40,1.00,0.00,1.00 +510,-72.00,-14.40,1.00,0.00,1.00 +511,115.20,14.40,1.00,0.00,1.00 +512,-62.40,-14.40,1.00,0.00,1.00 +513,124.80,14.40,1.00,0.00,1.00 +514,-52.80,-14.40,1.00,0.00,1.00 +515,134.40,9.60,1.00,0.00,1.00 +516,-43.20,-9.60,1.00,0.00,1.00 +517,144.00,9.60,1.00,0.00,1.00 +518,-33.60,-9.60,1.00,0.00,1.00 +519,153.60,9.60,1.00,0.00,1.00 +520,-24.00,-4.80,1.00,0.00,1.00 +521,163.20,4.80,1.00,0.00,1.00 +522,-14.40,-4.80,1.00,0.00,1.00 +523,172.80,4.80,1.00,0.00,1.00 +524,-4.80,-0.00,1.00,0.00,1.00 +525,0.00,0.00,1.00,0.00,1.00 +526,-177.60,-0.00,1.00,0.00,1.00 +527,9.60,0.00,1.00,0.00,1.00 +528,-168.00,-4.80,1.00,0.00,1.00 +529,19.20,4.80,1.00,0.00,1.00 +530,-158.40,-4.80,1.00,0.00,1.00 +531,28.80,4.80,1.00,0.00,1.00 +532,-148.80,-4.80,1.00,0.00,1.00 +533,38.40,4.80,1.00,0.00,1.00 +534,-139.20,-9.60,1.00,0.00,1.00 +535,48.00,9.60,1.00,0.00,1.00 +536,-129.60,-9.60,1.00,0.00,1.00 +537,57.60,9.60,1.00,0.00,1.00 +538,-120.00,-9.60,1.00,0.00,1.00 +539,67.20,9.60,1.00,0.00,1.00 +540,-110.40,-9.60,1.00,0.00,1.00 +541,76.80,9.60,1.00,0.00,1.00 +542,-100.80,-9.60,1.00,0.00,1.00 +543,86.40,9.60,1.00,0.00,1.00 +544,-86.40,-9.60,1.00,0.00,1.00 +545,96.00,9.60,1.00,0.00,1.00 +546,-76.80,-9.60,1.00,0.00,1.00 +547,105.60,9.60,1.00,0.00,1.00 +548,-67.20,-9.60,1.00,0.00,1.00 +549,115.20,9.60,1.00,0.00,1.00 +550,-57.60,-9.60,1.00,0.00,1.00 +551,124.80,9.60,1.00,0.00,1.00 +552,-48.00,-9.60,1.00,0.00,1.00 +553,134.40,9.60,1.00,0.00,1.00 +554,-38.40,-9.60,1.00,0.00,1.00 +555,144.00,4.80,1.00,0.00,1.00 +556,-28.80,-4.80,1.00,0.00,1.00 +557,153.60,4.80,1.00,0.00,1.00 +558,-19.20,-4.80,1.00,0.00,1.00 +559,163.20,4.80,1.00,0.00,1.00 +560,-9.60,-0.00,1.00,0.00,1.00 +561,172.80,0.00,1.00,0.00,1.00 +562,-0.00,-0.00,1.00,0.00,1.00 +563,-177.60,-0.00,1.00,0.00,1.00 +564,4.80,0.00,1.00,0.00,1.00 +565,-168.00,-0.00,1.00,0.00,1.00 +566,14.40,4.80,1.00,0.00,1.00 +567,-158.40,-4.80,1.00,0.00,1.00 +568,24.00,4.80,1.00,0.00,1.00 +569,-148.80,-4.80,1.00,0.00,1.00 +570,33.60,4.80,1.00,0.00,1.00 +571,-139.20,-9.60,1.00,0.00,1.00 +572,43.20,9.60,1.00,0.00,1.00 +573,-129.60,-9.60,1.00,0.00,1.00 +574,52.80,9.60,1.00,0.00,1.00 +575,-120.00,-9.60,1.00,0.00,1.00 +576,62.40,9.60,1.00,0.00,1.00 +577,-110.40,-9.60,1.00,0.00,1.00 +578,72.00,9.60,1.00,0.00,1.00 +579,-100.80,-9.60,1.00,0.00,1.00 +580,81.60,9.60,1.00,0.00,1.00 +581,-91.20,-9.60,1.00,0.00,1.00 +582,96.00,9.60,1.00,0.00,1.00 +583,-81.60,-9.60,1.00,0.00,1.00 +584,105.60,9.60,1.00,0.00,1.00 +585,-72.00,-9.60,1.00,0.00,1.00 +586,115.20,9.60,1.00,0.00,1.00 +587,-62.40,-9.60,1.00,0.00,1.00 +588,124.80,9.60,1.00,0.00,1.00 +589,-52.80,-9.60,1.00,0.00,1.00 +590,134.40,9.60,1.00,0.00,1.00 +591,-43.20,-9.60,1.00,0.00,1.00 +592,144.00,4.80,1.00,0.00,1.00 +593,-33.60,-4.80,1.00,0.00,1.00 +594,153.60,4.80,1.00,0.00,1.00 +595,-24.00,-4.80,1.00,0.00,1.00 +596,163.20,4.80,1.00,0.00,1.00 +597,-14.40,-4.80,1.00,0.00,1.00 +598,172.80,0.00,1.00,0.00,1.00 +599,-4.80,-0.00,1.00,0.00,1.00 +600,0.00,0.00,1.00,0.00,1.00 +601,-177.60,-0.00,1.00,0.00,1.00 +602,9.60,0.00,1.00,0.00,1.00 +603,-168.00,-0.00,1.00,0.00,1.00 +604,19.20,0.00,1.00,0.00,1.00 +605,-158.40,-4.80,1.00,0.00,1.00 +606,28.80,4.80,1.00,0.00,1.00 +607,-148.80,-4.80,1.00,0.00,1.00 +608,38.40,4.80,1.00,0.00,1.00 +609,-139.20,-4.80,1.00,0.00,1.00 +610,48.00,4.80,1.00,0.00,1.00 +611,-129.60,-4.80,1.00,0.00,1.00 +612,57.60,4.80,1.00,0.00,1.00 +613,-120.00,-4.80,1.00,0.00,1.00 +614,67.20,4.80,1.00,0.00,1.00 +615,-110.40,-4.80,1.00,0.00,1.00 +616,76.80,4.80,1.00,0.00,1.00 +617,-100.80,-4.80,1.00,0.00,1.00 +618,86.40,4.80,1.00,0.00,1.00 +619,-86.40,-4.80,1.00,0.00,1.00 +620,96.00,4.80,1.00,0.00,1.00 +621,-76.80,-4.80,1.00,0.00,1.00 +622,105.60,4.80,1.00,0.00,1.00 +623,-67.20,-4.80,1.00,0.00,1.00 +624,115.20,4.80,1.00,0.00,1.00 +625,-57.60,-4.80,1.00,0.00,1.00 +626,124.80,4.80,1.00,0.00,1.00 +627,-48.00,-4.80,1.00,0.00,1.00 +628,134.40,4.80,1.00,0.00,1.00 +629,-38.40,-4.80,1.00,0.00,1.00 +630,144.00,4.80,1.00,0.00,1.00 +631,-28.80,-4.80,1.00,0.00,1.00 +632,153.60,4.80,1.00,0.00,1.00 +633,-19.20,-4.80,1.00,0.00,1.00 +634,163.20,0.00,1.00,0.00,1.00 +635,-9.60,-0.00,1.00,0.00,1.00 +636,172.80,0.00,1.00,0.00,1.00 +637,-0.00,-0.00,1.00,0.00,1.00 +638,-177.60,-0.00,1.00,0.00,1.00 +639,4.80,0.00,1.00,0.00,1.00 +640,-168.00,-0.00,1.00,0.00,1.00 +641,14.40,0.00,1.00,0.00,1.00 +642,-158.40,-4.80,1.00,0.00,1.00 +643,24.00,4.80,1.00,0.00,1.00 +644,-148.80,-4.80,1.00,0.00,1.00 +645,33.60,4.80,1.00,0.00,1.00 +646,-139.20,-4.80,1.00,0.00,1.00 +647,43.20,4.80,1.00,0.00,1.00 +648,-129.60,-4.80,1.00,0.00,1.00 +649,52.80,4.80,1.00,0.00,1.00 +650,-120.00,-4.80,1.00,0.00,1.00 +651,62.40,4.80,1.00,0.00,1.00 +652,-110.40,-4.80,1.00,0.00,1.00 +653,72.00,4.80,1.00,0.00,1.00 +654,-100.80,-4.80,1.00,0.00,1.00 +655,81.60,4.80,1.00,0.00,1.00 +656,-91.20,-4.80,1.00,0.00,1.00 +657,96.00,4.80,1.00,0.00,1.00 +658,-81.60,-4.80,1.00,0.00,1.00 +659,105.60,4.80,1.00,0.00,1.00 +660,-72.00,-4.80,1.00,0.00,1.00 +661,115.20,4.80,1.00,0.00,1.00 +662,-62.40,-4.80,1.00,0.00,1.00 +663,124.80,4.80,1.00,0.00,1.00 +664,-52.80,-4.80,1.00,0.00,1.00 +665,134.40,4.80,1.00,0.00,1.00 +666,-43.20,-4.80,1.00,0.00,1.00 +667,144.00,4.80,1.00,0.00,1.00 +668,-33.60,-4.80,1.00,0.00,1.00 +669,153.60,4.80,1.00,0.00,1.00 +670,-24.00,-4.80,1.00,0.00,1.00 +671,163.20,0.00,1.00,0.00,1.00 +672,-14.40,-0.00,1.00,0.00,1.00 +673,172.80,0.00,1.00,0.00,1.00 +674,-4.80,-0.00,1.00,0.00,1.00 +675,0.00,0.00,1.00,0.00,1.00 +676,-177.60,-0.00,1.00,0.00,1.00 +677,9.60,0.00,1.00,0.00,1.00 +678,-168.00,-0.00,1.00,0.00,1.00 +679,19.20,0.00,1.00,0.00,1.00 +680,-158.40,-0.00,1.00,0.00,1.00 +681,28.80,0.00,1.00,0.00,1.00 +682,-148.80,-0.00,1.00,0.00,1.00 +683,38.40,0.00,1.00,0.00,1.00 +684,-139.20,-0.00,1.00,0.00,1.00 +685,48.00,0.00,1.00,0.00,1.00 +686,-129.60,-0.00,1.00,0.00,1.00 +687,57.60,0.00,1.00,0.00,1.00 +688,-120.00,-0.00,1.00,0.00,1.00 +689,67.20,0.00,1.00,0.00,1.00 +690,-110.40,-0.00,1.00,0.00,1.00 +691,76.80,0.00,1.00,0.00,1.00 +692,-100.80,-0.00,1.00,0.00,1.00 +693,86.40,0.00,1.00,0.00,1.00 +694,-86.40,-0.00,1.00,0.00,1.00 +695,96.00,0.00,1.00,0.00,1.00 +696,-76.80,-0.00,1.00,0.00,1.00 +697,105.60,0.00,1.00,0.00,1.00 +698,-67.20,-0.00,1.00,0.00,1.00 +699,115.20,0.00,1.00,0.00,1.00 +700,-57.60,-0.00,1.00,0.00,1.00 +701,124.80,0.00,1.00,0.00,1.00 +702,-48.00,-0.00,1.00,0.00,1.00 +703,134.40,0.00,1.00,0.00,1.00 +704,-38.40,-0.00,1.00,0.00,1.00 +705,144.00,0.00,1.00,0.00,1.00 +706,-28.80,-0.00,1.00,0.00,1.00 +707,153.60,0.00,1.00,0.00,1.00 +708,-19.20,-0.00,1.00,0.00,1.00 +709,163.20,0.00,1.00,0.00,1.00 +710,-9.60,-0.00,1.00,0.00,1.00 +711,172.80,0.00,1.00,0.00,1.00 +712,-0.00,-0.00,1.00,0.00,1.00 +713,-177.60,-0.00,1.00,0.00,1.00 +714,4.80,0.00,1.00,0.00,1.00 +715,-168.00,-0.00,1.00,0.00,1.00 +716,14.40,0.00,1.00,0.00,1.00 +717,-158.40,-0.00,1.00,0.00,1.00 +718,24.00,0.00,1.00,0.00,1.00 +719,-148.80,-0.00,1.00,0.00,1.00 +720,33.60,0.00,1.00,0.00,1.00 +721,-139.20,-0.00,1.00,0.00,1.00 +722,43.20,0.00,1.00,0.00,1.00 +723,-129.60,-0.00,1.00,0.00,1.00 +724,52.80,0.00,1.00,0.00,1.00 +725,-120.00,-0.00,1.00,0.00,1.00 +726,62.40,0.00,1.00,0.00,1.00 +727,-110.40,-0.00,1.00,0.00,1.00 +728,72.00,0.00,1.00,0.00,1.00 +729,-100.80,-0.00,1.00,0.00,1.00 +730,81.60,0.00,1.00,0.00,1.00 +731,-91.20,-0.00,1.00,0.00,1.00 +732,96.00,0.00,1.00,0.00,1.00 +733,-81.60,-0.00,1.00,0.00,1.00 +734,105.60,0.00,1.00,0.00,1.00 +735,-72.00,-0.00,1.00,0.00,1.00 +736,115.20,0.00,1.00,0.00,1.00 +737,-62.40,-0.00,1.00,0.00,1.00 +738,124.80,0.00,1.00,0.00,1.00 +739,-52.80,-0.00,1.00,0.00,1.00 +740,134.40,0.00,1.00,0.00,1.00 +741,-43.20,-0.00,1.00,0.00,1.00 +742,144.00,0.00,1.00,0.00,1.00 +743,-33.60,-0.00,1.00,0.00,1.00 +744,153.60,0.00,1.00,0.00,1.00 +745,-24.00,-0.00,1.00,0.00,1.00 +746,163.20,0.00,1.00,0.00,1.00 +747,-14.40,-0.00,1.00,0.00,1.00 +748,172.80,0.00,1.00,0.00,1.00 +749,-4.80,-0.00,1.00,0.00,1.00 +750,0.00,0.00,1.00,0.00,1.00 +751,-177.60,0.00,1.00,0.00,1.00 +752,9.60,-0.00,1.00,0.00,1.00 +753,-168.00,0.00,1.00,0.00,1.00 +754,19.20,-0.00,1.00,0.00,1.00 +755,-158.40,0.00,1.00,0.00,1.00 +756,28.80,-0.00,1.00,0.00,1.00 +757,-148.80,0.00,1.00,0.00,1.00 +758,38.40,-0.00,1.00,0.00,1.00 +759,-139.20,0.00,1.00,0.00,1.00 +760,48.00,-0.00,1.00,0.00,1.00 +761,-129.60,0.00,1.00,0.00,1.00 +762,57.60,-4.80,1.00,0.00,1.00 +763,-120.00,4.80,1.00,0.00,1.00 +764,67.20,-4.80,1.00,0.00,1.00 +765,-110.40,4.80,1.00,0.00,1.00 +766,76.80,-4.80,1.00,0.00,1.00 +767,-100.80,4.80,1.00,0.00,1.00 +768,86.40,-4.80,1.00,0.00,1.00 +769,-86.40,4.80,1.00,0.00,1.00 +770,96.00,-4.80,1.00,0.00,1.00 +771,-76.80,4.80,1.00,0.00,1.00 +772,105.60,-4.80,1.00,0.00,1.00 +773,-67.20,4.80,1.00,0.00,1.00 +774,115.20,-4.80,1.00,0.00,1.00 +775,-57.60,4.80,1.00,0.00,1.00 +776,124.80,-4.80,1.00,0.00,1.00 +777,-48.00,0.00,1.00,0.00,1.00 +778,134.40,-0.00,1.00,0.00,1.00 +779,-38.40,0.00,1.00,0.00,1.00 +780,144.00,-0.00,1.00,0.00,1.00 +781,-28.80,0.00,1.00,0.00,1.00 +782,153.60,-0.00,1.00,0.00,1.00 +783,-19.20,0.00,1.00,0.00,1.00 +784,163.20,-0.00,1.00,0.00,1.00 +785,-9.60,0.00,1.00,0.00,1.00 +786,172.80,-0.00,1.00,0.00,1.00 +787,-0.00,0.00,1.00,0.00,1.00 +788,-177.60,0.00,1.00,0.00,1.00 +789,4.80,-0.00,1.00,0.00,1.00 +790,-168.00,0.00,1.00,0.00,1.00 +791,14.40,-0.00,1.00,0.00,1.00 +792,-158.40,0.00,1.00,0.00,1.00 +793,24.00,-0.00,1.00,0.00,1.00 +794,-148.80,0.00,1.00,0.00,1.00 +795,33.60,-0.00,1.00,0.00,1.00 +796,-139.20,0.00,1.00,0.00,1.00 +797,43.20,-0.00,1.00,0.00,1.00 +798,-129.60,0.00,1.00,0.00,1.00 +799,52.80,-4.80,1.00,0.00,1.00 +800,-120.00,4.80,1.00,0.00,1.00 +801,62.40,-4.80,1.00,0.00,1.00 +802,-110.40,4.80,1.00,0.00,1.00 +803,72.00,-4.80,1.00,0.00,1.00 +804,-100.80,4.80,1.00,0.00,1.00 +805,81.60,-4.80,1.00,0.00,1.00 +806,-91.20,4.80,1.00,0.00,1.00 +807,96.00,-4.80,1.00,0.00,1.00 +808,-81.60,4.80,1.00,0.00,1.00 +809,105.60,-4.80,1.00,0.00,1.00 +810,-72.00,4.80,1.00,0.00,1.00 +811,115.20,-4.80,1.00,0.00,1.00 +812,-62.40,4.80,1.00,0.00,1.00 +813,124.80,-4.80,1.00,0.00,1.00 +814,-52.80,0.00,1.00,0.00,1.00 +815,134.40,-0.00,1.00,0.00,1.00 +816,-43.20,0.00,1.00,0.00,1.00 +817,144.00,-0.00,1.00,0.00,1.00 +818,-33.60,0.00,1.00,0.00,1.00 +819,153.60,-0.00,1.00,0.00,1.00 +820,-24.00,0.00,1.00,0.00,1.00 +821,163.20,-0.00,1.00,0.00,1.00 +822,-14.40,0.00,1.00,0.00,1.00 +823,172.80,-0.00,1.00,0.00,1.00 +824,-4.80,0.00,1.00,0.00,1.00 +825,0.00,0.00,1.00,0.00,1.00 +826,-177.60,0.00,1.00,0.00,1.00 +827,9.60,-0.00,1.00,0.00,1.00 +828,-168.00,0.00,1.00,0.00,1.00 +829,19.20,-4.80,1.00,0.00,1.00 +830,-158.40,4.80,1.00,0.00,1.00 +831,28.80,-4.80,1.00,0.00,1.00 +832,-148.80,4.80,1.00,0.00,1.00 +833,38.40,-4.80,1.00,0.00,1.00 +834,-139.20,4.80,1.00,0.00,1.00 +835,48.00,-4.80,1.00,0.00,1.00 +836,-129.60,4.80,1.00,0.00,1.00 +837,57.60,-4.80,1.00,0.00,1.00 +838,-120.00,4.80,1.00,0.00,1.00 +839,67.20,-4.80,1.00,0.00,1.00 +840,-110.40,9.60,1.00,0.00,1.00 +841,76.80,-9.60,1.00,0.00,1.00 +842,-100.80,9.60,1.00,0.00,1.00 +843,86.40,-9.60,1.00,0.00,1.00 +844,-86.40,9.60,1.00,0.00,1.00 +845,96.00,-9.60,1.00,0.00,1.00 +846,-76.80,9.60,1.00,0.00,1.00 +847,105.60,-9.60,1.00,0.00,1.00 +848,-67.20,9.60,1.00,0.00,1.00 +849,115.20,-4.80,1.00,0.00,1.00 +850,-57.60,4.80,1.00,0.00,1.00 +851,124.80,-4.80,1.00,0.00,1.00 +852,-48.00,4.80,1.00,0.00,1.00 +853,134.40,-4.80,1.00,0.00,1.00 +854,-38.40,4.80,1.00,0.00,1.00 +855,144.00,-4.80,1.00,0.00,1.00 +856,-28.80,4.80,1.00,0.00,1.00 +857,153.60,-4.80,1.00,0.00,1.00 +858,-19.20,4.80,1.00,0.00,1.00 +859,163.20,-0.00,1.00,0.00,1.00 +860,-9.60,0.00,1.00,0.00,1.00 +861,172.80,-0.00,1.00,0.00,1.00 +862,-0.00,0.00,1.00,0.00,1.00 +863,-177.60,0.00,1.00,0.00,1.00 +864,4.80,-0.00,1.00,0.00,1.00 +865,-168.00,0.00,1.00,0.00,1.00 +866,14.40,-0.00,1.00,0.00,1.00 +867,-158.40,4.80,1.00,0.00,1.00 +868,24.00,-4.80,1.00,0.00,1.00 +869,-148.80,4.80,1.00,0.00,1.00 +870,33.60,-4.80,1.00,0.00,1.00 +871,-139.20,4.80,1.00,0.00,1.00 +872,43.20,-4.80,1.00,0.00,1.00 +873,-129.60,4.80,1.00,0.00,1.00 +874,52.80,-4.80,1.00,0.00,1.00 +875,-120.00,4.80,1.00,0.00,1.00 +876,62.40,-4.80,1.00,0.00,1.00 +877,-110.40,9.60,1.00,0.00,1.00 +878,72.00,-9.60,1.00,0.00,1.00 +879,-100.80,9.60,1.00,0.00,1.00 +880,81.60,-9.60,1.00,0.00,1.00 +881,-91.20,9.60,1.00,0.00,1.00 +882,96.00,-9.60,1.00,0.00,1.00 +883,-81.60,9.60,1.00,0.00,1.00 +884,105.60,-9.60,1.00,0.00,1.00 +885,-72.00,9.60,1.00,0.00,1.00 +886,115.20,-4.80,1.00,0.00,1.00 +887,-62.40,4.80,1.00,0.00,1.00 +888,124.80,-4.80,1.00,0.00,1.00 +889,-52.80,4.80,1.00,0.00,1.00 +890,134.40,-4.80,1.00,0.00,1.00 +891,-43.20,4.80,1.00,0.00,1.00 +892,144.00,-4.80,1.00,0.00,1.00 +893,-33.60,4.80,1.00,0.00,1.00 +894,153.60,-4.80,1.00,0.00,1.00 +895,-24.00,4.80,1.00,0.00,1.00 +896,163.20,-4.80,1.00,0.00,1.00 +897,-14.40,0.00,1.00,0.00,1.00 +898,172.80,-0.00,1.00,0.00,1.00 +899,-4.80,0.00,1.00,0.00,1.00 +900,0.00,0.00,1.00,0.00,1.00 +901,-177.60,0.00,1.00,0.00,1.00 +902,9.60,-0.00,1.00,0.00,1.00 +903,-168.00,4.80,1.00,0.00,1.00 +904,19.20,-4.80,1.00,0.00,1.00 +905,-158.40,4.80,1.00,0.00,1.00 +906,28.80,-4.80,1.00,0.00,1.00 +907,-148.80,4.80,1.00,0.00,1.00 +908,38.40,-9.60,1.00,0.00,1.00 +909,-139.20,9.60,1.00,0.00,1.00 +910,48.00,-9.60,1.00,0.00,1.00 +911,-129.60,9.60,1.00,0.00,1.00 +912,57.60,-9.60,1.00,0.00,1.00 +913,-120.00,9.60,1.00,0.00,1.00 +914,67.20,-9.60,1.00,0.00,1.00 +915,-110.40,9.60,1.00,0.00,1.00 +916,76.80,-14.40,1.00,0.00,1.00 +917,-100.80,14.40,1.00,0.00,1.00 +918,86.40,-14.40,1.00,0.00,1.00 +919,-86.40,14.40,1.00,0.00,1.00 +920,96.00,-14.40,1.00,0.00,1.00 +921,-76.80,14.40,1.00,0.00,1.00 +922,105.60,-14.40,1.00,0.00,1.00 +923,-67.20,9.60,1.00,0.00,1.00 +924,115.20,-9.60,1.00,0.00,1.00 +925,-57.60,9.60,1.00,0.00,1.00 +926,124.80,-9.60,1.00,0.00,1.00 +927,-48.00,9.60,1.00,0.00,1.00 +928,134.40,-9.60,1.00,0.00,1.00 +929,-38.40,9.60,1.00,0.00,1.00 +930,144.00,-9.60,1.00,0.00,1.00 +931,-28.80,4.80,1.00,0.00,1.00 +932,153.60,-4.80,1.00,0.00,1.00 +933,-19.20,4.80,1.00,0.00,1.00 +934,163.20,-4.80,1.00,0.00,1.00 +935,-9.60,4.80,1.00,0.00,1.00 +936,172.80,-0.00,1.00,0.00,1.00 +937,-0.00,0.00,1.00,0.00,1.00 +938,-177.60,0.00,1.00,0.00,1.00 +939,4.80,-0.00,1.00,0.00,1.00 +940,-168.00,4.80,1.00,0.00,1.00 +941,14.40,-4.80,1.00,0.00,1.00 +942,-158.40,4.80,1.00,0.00,1.00 +943,24.00,-4.80,1.00,0.00,1.00 +944,-148.80,4.80,1.00,0.00,1.00 +945,33.60,-9.60,1.00,0.00,1.00 +946,-139.20,9.60,1.00,0.00,1.00 +947,43.20,-9.60,1.00,0.00,1.00 +948,-129.60,9.60,1.00,0.00,1.00 +949,52.80,-9.60,1.00,0.00,1.00 +950,-120.00,9.60,1.00,0.00,1.00 +951,62.40,-9.60,1.00,0.00,1.00 +952,-110.40,9.60,1.00,0.00,1.00 +953,72.00,-14.40,1.00,0.00,1.00 +954,-100.80,14.40,1.00,0.00,1.00 +955,81.60,-14.40,1.00,0.00,1.00 +956,-91.20,14.40,1.00,0.00,1.00 +957,96.00,-14.40,1.00,0.00,1.00 +958,-81.60,14.40,1.00,0.00,1.00 +959,105.60,-14.40,1.00,0.00,1.00 +960,-72.00,9.60,1.00,0.00,1.00 +961,115.20,-9.60,1.00,0.00,1.00 +962,-62.40,9.60,1.00,0.00,1.00 +963,124.80,-9.60,1.00,0.00,1.00 +964,-52.80,9.60,1.00,0.00,1.00 +965,134.40,-9.60,1.00,0.00,1.00 +966,-43.20,9.60,1.00,0.00,1.00 +967,144.00,-9.60,1.00,0.00,1.00 +968,-33.60,4.80,1.00,0.00,1.00 +969,153.60,-4.80,1.00,0.00,1.00 +970,-24.00,4.80,1.00,0.00,1.00 +971,163.20,-4.80,1.00,0.00,1.00 +972,-14.40,4.80,1.00,0.00,1.00 +973,172.80,-0.00,1.00,0.00,1.00 +974,-4.80,0.00,1.00,0.00,1.00 +975,0.00,0.00,1.00,0.00,1.00 +976,-177.60,0.00,1.00,0.00,1.00 +977,9.60,-4.80,1.00,0.00,1.00 +978,-168.00,4.80,1.00,0.00,1.00 +979,19.20,-4.80,1.00,0.00,1.00 +980,-158.40,4.80,1.00,0.00,1.00 +981,28.80,-9.60,1.00,0.00,1.00 +982,-148.80,9.60,1.00,0.00,1.00 +983,38.40,-9.60,1.00,0.00,1.00 +984,-139.20,9.60,1.00,0.00,1.00 +985,48.00,-14.40,1.00,0.00,1.00 +986,-129.60,14.40,1.00,0.00,1.00 +987,57.60,-14.40,1.00,0.00,1.00 +988,-120.00,14.40,1.00,0.00,1.00 +989,67.20,-14.40,1.00,0.00,1.00 +990,-110.40,14.40,1.00,0.00,1.00 +991,76.80,-19.20,1.00,0.00,1.00 +992,-100.80,19.20,1.00,0.00,1.00 +993,86.40,-19.20,1.00,0.00,1.00 +994,-86.40,19.20,1.00,0.00,1.00 +995,96.00,-19.20,1.00,0.00,1.00 +996,-76.80,19.20,1.00,0.00,1.00 +997,105.60,-14.40,1.00,0.00,1.00 +998,-67.20,14.40,1.00,0.00,1.00 +999,115.20,-14.40,1.00,0.00,1.00 +1000,-57.60,14.40,1.00,0.00,1.00 +1001,124.80,-14.40,1.00,0.00,1.00 +1002,-48.00,14.40,1.00,0.00,1.00 +1003,134.40,-14.40,1.00,0.00,1.00 +1004,-38.40,9.60,1.00,0.00,1.00 +1005,144.00,-9.60,1.00,0.00,1.00 +1006,-28.80,9.60,1.00,0.00,1.00 +1007,153.60,-9.60,1.00,0.00,1.00 +1008,-19.20,4.80,1.00,0.00,1.00 +1009,163.20,-4.80,1.00,0.00,1.00 +1010,-9.60,4.80,1.00,0.00,1.00 +1011,172.80,-0.00,1.00,0.00,1.00 +1012,-0.00,0.00,1.00,0.00,1.00 +1013,-177.60,0.00,1.00,0.00,1.00 +1014,4.80,-0.00,1.00,0.00,1.00 +1015,-168.00,4.80,1.00,0.00,1.00 +1016,14.40,-4.80,1.00,0.00,1.00 +1017,-158.40,4.80,1.00,0.00,1.00 +1018,24.00,-9.60,1.00,0.00,1.00 +1019,-148.80,9.60,1.00,0.00,1.00 +1020,33.60,-9.60,1.00,0.00,1.00 +1021,-139.20,9.60,1.00,0.00,1.00 +1022,43.20,-14.40,1.00,0.00,1.00 +1023,-129.60,14.40,1.00,0.00,1.00 +1024,52.80,-14.40,1.00,0.00,1.00 +1025,-120.00,14.40,1.00,0.00,1.00 +1026,62.40,-14.40,1.00,0.00,1.00 +1027,-110.40,14.40,1.00,0.00,1.00 +1028,72.00,-14.40,1.00,0.00,1.00 +1029,-100.80,19.20,1.00,0.00,1.00 +1030,81.60,-19.20,1.00,0.00,1.00 +1031,-91.20,19.20,1.00,0.00,1.00 +1032,96.00,-19.20,1.00,0.00,1.00 +1033,-81.60,19.20,1.00,0.00,1.00 +1034,105.60,-19.20,1.00,0.00,1.00 +1035,-72.00,14.40,1.00,0.00,1.00 +1036,115.20,-14.40,1.00,0.00,1.00 +1037,-62.40,14.40,1.00,0.00,1.00 +1038,124.80,-14.40,1.00,0.00,1.00 +1039,-52.80,14.40,1.00,0.00,1.00 +1040,134.40,-14.40,1.00,0.00,1.00 +1041,-43.20,9.60,1.00,0.00,1.00 +1042,144.00,-9.60,1.00,0.00,1.00 +1043,-33.60,9.60,1.00,0.00,1.00 +1044,153.60,-9.60,1.00,0.00,1.00 +1045,-24.00,4.80,1.00,0.00,1.00 +1046,163.20,-4.80,1.00,0.00,1.00 +1047,-14.40,4.80,1.00,0.00,1.00 +1048,172.80,-4.80,1.00,0.00,1.00 +1049,-4.80,0.00,1.00,0.00,1.00 +1050,0.00,0.00,1.00,0.00,1.00 +1051,-177.60,0.00,1.00,0.00,1.00 +1052,9.60,-4.80,1.00,0.00,1.00 +1053,-168.00,4.80,1.00,0.00,1.00 +1054,19.20,-4.80,1.00,0.00,1.00 +1055,-158.40,9.60,1.00,0.00,1.00 +1056,28.80,-9.60,1.00,0.00,1.00 +1057,-148.80,14.40,1.00,0.00,1.00 +1058,38.40,-14.40,1.00,0.00,1.00 +1059,-139.20,14.40,1.00,0.00,1.00 +1060,48.00,-14.40,1.00,0.00,1.00 +1061,-129.60,19.20,1.00,0.00,1.00 +1062,57.60,-19.20,1.00,0.00,1.00 +1063,-120.00,19.20,1.00,0.00,1.00 +1064,67.20,-19.20,1.00,0.00,1.00 +1065,-110.40,19.20,1.00,0.00,1.00 +1066,76.80,-19.20,1.00,0.00,1.00 +1067,-100.80,24.00,1.00,0.00,1.00 +1068,86.40,-24.00,1.00,0.00,1.00 +1069,-86.40,24.00,1.00,0.00,1.00 +1070,96.00,-24.00,1.00,0.00,1.00 +1071,-76.80,24.00,1.00,0.00,1.00 +1072,105.60,-19.20,1.00,0.00,1.00 +1073,-67.20,19.20,1.00,0.00,1.00 +1074,115.20,-19.20,1.00,0.00,1.00 +1075,-57.60,19.20,1.00,0.00,1.00 +1076,124.80,-19.20,1.00,0.00,1.00 +1077,-48.00,19.20,1.00,0.00,1.00 +1078,134.40,-14.40,1.00,0.00,1.00 +1079,-38.40,14.40,1.00,0.00,1.00 +1080,144.00,-14.40,1.00,0.00,1.00 +1081,-28.80,9.60,1.00,0.00,1.00 +1082,153.60,-9.60,1.00,0.00,1.00 +1083,-19.20,9.60,1.00,0.00,1.00 +1084,163.20,-4.80,1.00,0.00,1.00 +1085,-9.60,4.80,1.00,0.00,1.00 +1086,172.80,-4.80,1.00,0.00,1.00 +1087,-0.00,0.00,1.00,0.00,1.00 +1088,-177.60,0.00,1.00,0.00,1.00 +1089,4.80,-4.80,1.00,0.00,1.00 +1090,-168.00,4.80,1.00,0.00,1.00 +1091,14.40,-4.80,1.00,0.00,1.00 +1092,-158.40,9.60,1.00,0.00,1.00 +1093,24.00,-9.60,1.00,0.00,1.00 +1094,-148.80,9.60,1.00,0.00,1.00 +1095,33.60,-14.40,1.00,0.00,1.00 +1096,-139.20,14.40,1.00,0.00,1.00 +1097,43.20,-14.40,1.00,0.00,1.00 +1098,-129.60,19.20,1.00,0.00,1.00 +1099,52.80,-19.20,1.00,0.00,1.00 +1100,-120.00,19.20,1.00,0.00,1.00 +1101,62.40,-19.20,1.00,0.00,1.00 +1102,-110.40,19.20,1.00,0.00,1.00 +1103,72.00,-19.20,1.00,0.00,1.00 +1104,-100.80,24.00,1.00,0.00,1.00 +1105,81.60,-24.00,1.00,0.00,1.00 +1106,-91.20,24.00,1.00,0.00,1.00 +1107,96.00,-24.00,1.00,0.00,1.00 +1108,-81.60,24.00,1.00,0.00,1.00 +1109,105.60,-19.20,1.00,0.00,1.00 +1110,-72.00,19.20,1.00,0.00,1.00 +1111,115.20,-19.20,1.00,0.00,1.00 +1112,-62.40,19.20,1.00,0.00,1.00 +1113,124.80,-19.20,1.00,0.00,1.00 +1114,-52.80,19.20,1.00,0.00,1.00 +1115,134.40,-14.40,1.00,0.00,1.00 +1116,-43.20,14.40,1.00,0.00,1.00 +1117,144.00,-14.40,1.00,0.00,1.00 +1118,-33.60,14.40,1.00,0.00,1.00 +1119,153.60,-9.60,1.00,0.00,1.00 +1120,-24.00,9.60,1.00,0.00,1.00 +1121,163.20,-4.80,1.00,0.00,1.00 +1122,-14.40,4.80,1.00,0.00,1.00 +1123,172.80,-4.80,1.00,0.00,1.00 +1124,-4.80,0.00,1.00,0.00,1.00 +1125,0.00,0.00,1.00,0.00,1.00 +1126,-177.60,0.00,1.00,0.00,1.00 +1127,9.60,-4.80,1.00,0.00,1.00 +1128,-168.00,4.80,1.00,0.00,1.00 +1129,19.20,-9.60,1.00,0.00,1.00 +1130,-158.40,9.60,1.00,0.00,1.00 +1131,24.00,-14.40,1.00,0.00,1.00 +1132,-148.80,14.40,1.00,0.00,1.00 +1133,33.60,-14.40,1.00,0.00,1.00 +1134,-139.20,19.20,1.00,0.00,1.00 +1135,43.20,-19.20,1.00,0.00,1.00 +1136,-129.60,19.20,1.00,0.00,1.00 +1137,52.80,-24.00,1.00,0.00,1.00 +1138,-120.00,24.00,1.00,0.00,1.00 +1139,62.40,-24.00,1.00,0.00,1.00 +1140,-110.40,24.00,1.00,0.00,1.00 +1141,76.80,-24.00,1.00,0.00,1.00 +1142,-100.80,28.80,1.00,0.00,1.00 +1143,86.40,-28.80,1.00,0.00,1.00 +1144,-86.40,28.80,1.00,0.00,1.00 +1145,96.00,-28.80,1.00,0.00,1.00 +1146,-76.80,28.80,1.00,0.00,1.00 +1147,105.60,-24.00,1.00,0.00,1.00 +1148,-67.20,24.00,1.00,0.00,1.00 +1149,120.00,-24.00,1.00,0.00,1.00 +1150,-57.60,24.00,1.00,0.00,1.00 +1151,129.60,-24.00,1.00,0.00,1.00 +1152,-48.00,19.20,1.00,0.00,1.00 +1153,139.20,-19.20,1.00,0.00,1.00 +1154,-38.40,19.20,1.00,0.00,1.00 +1155,148.80,-14.40,1.00,0.00,1.00 +1156,-28.80,14.40,1.00,0.00,1.00 +1157,158.40,-9.60,1.00,0.00,1.00 +1158,-19.20,9.60,1.00,0.00,1.00 +1159,163.20,-9.60,1.00,0.00,1.00 +1160,-9.60,4.80,1.00,0.00,1.00 +1161,172.80,-4.80,1.00,0.00,1.00 +1162,-0.00,0.00,1.00,0.00,1.00 +1163,-177.60,0.00,1.00,0.00,1.00 +1164,4.80,-4.80,1.00,0.00,1.00 +1165,-168.00,4.80,1.00,0.00,1.00 +1166,14.40,-9.60,1.00,0.00,1.00 +1167,-158.40,9.60,1.00,0.00,1.00 +1168,24.00,-9.60,1.00,0.00,1.00 +1169,-153.60,14.40,1.00,0.00,1.00 +1170,33.60,-14.40,1.00,0.00,1.00 +1171,-144.00,19.20,1.00,0.00,1.00 +1172,43.20,-19.20,1.00,0.00,1.00 +1173,-134.40,19.20,1.00,0.00,1.00 +1174,52.80,-24.00,1.00,0.00,1.00 +1175,-124.80,24.00,1.00,0.00,1.00 +1176,62.40,-24.00,1.00,0.00,1.00 +1177,-110.40,24.00,1.00,0.00,1.00 +1178,72.00,-24.00,1.00,0.00,1.00 +1179,-100.80,28.80,1.00,0.00,1.00 +1180,81.60,-28.80,1.00,0.00,1.00 +1181,-91.20,28.80,1.00,0.00,1.00 +1182,96.00,-28.80,1.00,0.00,1.00 +1183,-81.60,28.80,1.00,0.00,1.00 +1184,105.60,-24.00,1.00,0.00,1.00 +1185,-72.00,24.00,1.00,0.00,1.00 +1186,115.20,-24.00,1.00,0.00,1.00 +1187,-57.60,24.00,1.00,0.00,1.00 +1188,124.80,-24.00,1.00,0.00,1.00 +1189,-48.00,19.20,1.00,0.00,1.00 +1190,134.40,-19.20,1.00,0.00,1.00 +1191,-38.40,19.20,1.00,0.00,1.00 +1192,144.00,-14.40,1.00,0.00,1.00 +1193,-28.80,14.40,1.00,0.00,1.00 +1194,153.60,-14.40,1.00,0.00,1.00 +1195,-24.00,9.60,1.00,0.00,1.00 +1196,163.20,-9.60,1.00,0.00,1.00 +1197,-14.40,4.80,1.00,0.00,1.00 +1198,172.80,-4.80,1.00,0.00,1.00 +1199,-4.80,0.00,1.00,0.00,1.00 +1200,0.00,0.00,1.00,0.00,1.00 +1201,-177.60,4.80,1.00,0.00,1.00 +1202,9.60,-4.80,1.00,0.00,1.00 +1203,-168.00,9.60,1.00,0.00,1.00 +1204,14.40,-9.60,1.00,0.00,1.00 +1205,-158.40,14.40,1.00,0.00,1.00 +1206,24.00,-14.40,1.00,0.00,1.00 +1207,-148.80,19.20,1.00,0.00,1.00 +1208,33.60,-19.20,1.00,0.00,1.00 +1209,-139.20,19.20,1.00,0.00,1.00 +1210,43.20,-24.00,1.00,0.00,1.00 +1211,-129.60,24.00,1.00,0.00,1.00 +1212,52.80,-28.80,1.00,0.00,1.00 +1213,-120.00,28.80,1.00,0.00,1.00 +1214,62.40,-28.80,1.00,0.00,1.00 +1215,-110.40,28.80,1.00,0.00,1.00 +1216,76.80,-28.80,1.00,0.00,1.00 +1217,-100.80,33.60,1.00,0.00,1.00 +1218,86.40,-33.60,1.00,0.00,1.00 +1219,-86.40,33.60,1.00,0.00,1.00 +1220,96.00,-33.60,1.00,0.00,1.00 +1221,-76.80,28.80,1.00,0.00,1.00 +1222,110.40,-28.80,1.00,0.00,1.00 +1223,-67.20,28.80,1.00,0.00,1.00 +1224,120.00,-28.80,1.00,0.00,1.00 +1225,-57.60,28.80,1.00,0.00,1.00 +1226,129.60,-24.00,1.00,0.00,1.00 +1227,-48.00,24.00,1.00,0.00,1.00 +1228,139.20,-24.00,1.00,0.00,1.00 +1229,-38.40,19.20,1.00,0.00,1.00 +1230,148.80,-19.20,1.00,0.00,1.00 +1231,-28.80,14.40,1.00,0.00,1.00 +1232,158.40,-14.40,1.00,0.00,1.00 +1233,-19.20,9.60,1.00,0.00,1.00 +1234,168.00,-9.60,1.00,0.00,1.00 +1235,-9.60,4.80,1.00,0.00,1.00 +1236,172.80,-4.80,1.00,0.00,1.00 +1237,-0.00,0.00,1.00,0.00,1.00 +1238,-177.60,0.00,1.00,0.00,1.00 +1239,4.80,-4.80,1.00,0.00,1.00 +1240,-168.00,4.80,1.00,0.00,1.00 +1241,14.40,-9.60,1.00,0.00,1.00 +1242,-163.20,9.60,1.00,0.00,1.00 +1243,24.00,-14.40,1.00,0.00,1.00 +1244,-153.60,14.40,1.00,0.00,1.00 +1245,33.60,-19.20,1.00,0.00,1.00 +1246,-144.00,19.20,1.00,0.00,1.00 +1247,43.20,-24.00,1.00,0.00,1.00 +1248,-134.40,24.00,1.00,0.00,1.00 +1249,52.80,-24.00,1.00,0.00,1.00 +1250,-124.80,28.80,1.00,0.00,1.00 +1251,62.40,-28.80,1.00,0.00,1.00 +1252,-115.20,28.80,1.00,0.00,1.00 +1253,72.00,-28.80,1.00,0.00,1.00 +1254,-100.80,28.80,1.00,0.00,1.00 +1255,81.60,-33.60,1.00,0.00,1.00 +1256,-91.20,33.60,1.00,0.00,1.00 +1257,96.00,-33.60,1.00,0.00,1.00 +1258,-81.60,33.60,1.00,0.00,1.00 +1259,105.60,-28.80,1.00,0.00,1.00 +1260,-67.20,28.80,1.00,0.00,1.00 +1261,115.20,-28.80,1.00,0.00,1.00 +1262,-57.60,28.80,1.00,0.00,1.00 +1263,124.80,-28.80,1.00,0.00,1.00 +1264,-48.00,24.00,1.00,0.00,1.00 +1265,134.40,-24.00,1.00,0.00,1.00 +1266,-38.40,19.20,1.00,0.00,1.00 +1267,144.00,-19.20,1.00,0.00,1.00 +1268,-28.80,19.20,1.00,0.00,1.00 +1269,153.60,-14.40,1.00,0.00,1.00 +1270,-19.20,14.40,1.00,0.00,1.00 +1271,163.20,-9.60,1.00,0.00,1.00 +1272,-14.40,9.60,1.00,0.00,1.00 +1273,172.80,-4.80,1.00,0.00,1.00 +1274,-4.80,4.80,1.00,0.00,1.00 +1275,0.00,0.00,1.00,0.00,1.00 +1276,-177.60,4.80,1.00,0.00,1.00 +1277,9.60,-4.80,1.00,0.00,1.00 +1278,-168.00,9.60,1.00,0.00,1.00 +1279,14.40,-9.60,1.00,0.00,1.00 +1280,-158.40,14.40,1.00,0.00,1.00 +1281,24.00,-14.40,1.00,0.00,1.00 +1282,-153.60,19.20,1.00,0.00,1.00 +1283,33.60,-24.00,1.00,0.00,1.00 +1284,-144.00,24.00,1.00,0.00,1.00 +1285,43.20,-24.00,1.00,0.00,1.00 +1286,-134.40,28.80,1.00,0.00,1.00 +1287,52.80,-28.80,1.00,0.00,1.00 +1288,-124.80,33.60,1.00,0.00,1.00 +1289,62.40,-33.60,1.00,0.00,1.00 +1290,-110.40,33.60,1.00,0.00,1.00 +1291,72.00,-33.60,1.00,0.00,1.00 +1292,-100.80,38.40,1.00,0.00,1.00 +1293,86.40,-38.40,1.00,0.00,1.00 +1294,-86.40,38.40,1.00,0.00,1.00 +1295,96.00,-38.40,1.00,0.00,1.00 +1296,-76.80,33.60,1.00,0.00,1.00 +1297,110.40,-33.60,1.00,0.00,1.00 +1298,-67.20,33.60,1.00,0.00,1.00 +1299,120.00,-33.60,1.00,0.00,1.00 +1300,-52.80,28.80,1.00,0.00,1.00 +1301,129.60,-28.80,1.00,0.00,1.00 +1302,-43.20,28.80,1.00,0.00,1.00 +1303,139.20,-24.00,1.00,0.00,1.00 +1304,-33.60,24.00,1.00,0.00,1.00 +1305,148.80,-19.20,1.00,0.00,1.00 +1306,-24.00,19.20,1.00,0.00,1.00 +1307,158.40,-14.40,1.00,0.00,1.00 +1308,-19.20,14.40,1.00,0.00,1.00 +1309,168.00,-9.60,1.00,0.00,1.00 +1310,-9.60,4.80,1.00,0.00,1.00 +1311,172.80,-4.80,1.00,0.00,1.00 +1312,-0.00,0.00,1.00,0.00,1.00 +1313,-177.60,0.00,1.00,0.00,1.00 +1314,4.80,-4.80,1.00,0.00,1.00 +1315,-168.00,4.80,1.00,0.00,1.00 +1316,14.40,-9.60,1.00,0.00,1.00 +1317,-163.20,14.40,1.00,0.00,1.00 +1318,24.00,-14.40,1.00,0.00,1.00 +1319,-153.60,19.20,1.00,0.00,1.00 +1320,28.80,-19.20,1.00,0.00,1.00 +1321,-144.00,24.00,1.00,0.00,1.00 +1322,38.40,-24.00,1.00,0.00,1.00 +1323,-134.40,28.80,1.00,0.00,1.00 +1324,48.00,-28.80,1.00,0.00,1.00 +1325,-124.80,28.80,1.00,0.00,1.00 +1326,57.60,-33.60,1.00,0.00,1.00 +1327,-115.20,33.60,1.00,0.00,1.00 +1328,72.00,-33.60,1.00,0.00,1.00 +1329,-105.60,33.60,1.00,0.00,1.00 +1330,81.60,-38.40,1.00,0.00,1.00 +1331,-91.20,38.40,1.00,0.00,1.00 +1332,96.00,-38.40,1.00,0.00,1.00 +1333,-81.60,38.40,1.00,0.00,1.00 +1334,105.60,-33.60,1.00,0.00,1.00 +1335,-67.20,33.60,1.00,0.00,1.00 +1336,120.00,-33.60,1.00,0.00,1.00 +1337,-57.60,33.60,1.00,0.00,1.00 +1338,129.60,-28.80,1.00,0.00,1.00 +1339,-48.00,28.80,1.00,0.00,1.00 +1340,139.20,-24.00,1.00,0.00,1.00 +1341,-38.40,24.00,1.00,0.00,1.00 +1342,148.80,-24.00,1.00,0.00,1.00 +1343,-28.80,19.20,1.00,0.00,1.00 +1344,158.40,-14.40,1.00,0.00,1.00 +1345,-19.20,14.40,1.00,0.00,1.00 +1346,163.20,-9.60,1.00,0.00,1.00 +1347,-9.60,9.60,1.00,0.00,1.00 +1348,172.80,-4.80,1.00,0.00,1.00 +1349,-4.80,4.80,1.00,0.00,1.00 +1350,0.00,0.00,1.00,0.00,1.00 +1351,-177.60,4.80,1.00,0.00,1.00 +1352,9.60,-4.80,1.00,0.00,1.00 +1353,-168.00,9.60,1.00,0.00,1.00 +1354,14.40,-14.40,1.00,0.00,1.00 +1355,-163.20,14.40,1.00,0.00,1.00 +1356,24.00,-19.20,1.00,0.00,1.00 +1357,-153.60,19.20,1.00,0.00,1.00 +1358,28.80,-24.00,1.00,0.00,1.00 +1359,-144.00,28.80,1.00,0.00,1.00 +1360,38.40,-28.80,1.00,0.00,1.00 +1361,-134.40,33.60,1.00,0.00,1.00 +1362,48.00,-33.60,1.00,0.00,1.00 +1363,-124.80,33.60,1.00,0.00,1.00 +1364,62.40,-38.40,1.00,0.00,1.00 +1365,-115.20,38.40,1.00,0.00,1.00 +1366,72.00,-38.40,1.00,0.00,1.00 +1367,-100.80,43.20,1.00,0.00,1.00 +1368,86.40,-43.20,1.00,0.00,1.00 +1369,-86.40,43.20,1.00,0.00,1.00 +1370,96.00,-43.20,1.00,0.00,1.00 +1371,-76.80,38.40,1.00,0.00,1.00 +1372,110.40,-38.40,1.00,0.00,1.00 +1373,-62.40,38.40,1.00,0.00,1.00 +1374,120.00,-38.40,1.00,0.00,1.00 +1375,-52.80,33.60,1.00,0.00,1.00 +1376,134.40,-33.60,1.00,0.00,1.00 +1377,-43.20,28.80,1.00,0.00,1.00 +1378,144.00,-28.80,1.00,0.00,1.00 +1379,-33.60,24.00,1.00,0.00,1.00 +1380,153.60,-24.00,1.00,0.00,1.00 +1381,-24.00,19.20,1.00,0.00,1.00 +1382,158.40,-19.20,1.00,0.00,1.00 +1383,-14.40,14.40,1.00,0.00,1.00 +1384,168.00,-9.60,1.00,0.00,1.00 +1385,-9.60,9.60,1.00,0.00,1.00 +1386,172.80,-4.80,1.00,0.00,1.00 +1387,-0.00,0.00,1.00,0.00,1.00 +1388,-177.60,0.00,1.00,0.00,1.00 +1389,4.80,-4.80,1.00,0.00,1.00 +1390,-172.80,9.60,1.00,0.00,1.00 +1391,14.40,-9.60,1.00,0.00,1.00 +1392,-163.20,14.40,1.00,0.00,1.00 +1393,19.20,-19.20,1.00,0.00,1.00 +1394,-153.60,19.20,1.00,0.00,1.00 +1395,28.80,-24.00,1.00,0.00,1.00 +1396,-148.80,24.00,1.00,0.00,1.00 +1397,38.40,-28.80,1.00,0.00,1.00 +1398,-139.20,28.80,1.00,0.00,1.00 +1399,48.00,-33.60,1.00,0.00,1.00 +1400,-129.60,33.60,1.00,0.00,1.00 +1401,57.60,-38.40,1.00,0.00,1.00 +1402,-115.20,38.40,1.00,0.00,1.00 +1403,67.20,-38.40,1.00,0.00,1.00 +1404,-105.60,38.40,1.00,0.00,1.00 +1405,81.60,-43.20,1.00,0.00,1.00 +1406,-91.20,43.20,1.00,0.00,1.00 +1407,96.00,-43.20,1.00,0.00,1.00 +1408,-76.80,43.20,1.00,0.00,1.00 +1409,105.60,-38.40,1.00,0.00,1.00 +1410,-67.20,38.40,1.00,0.00,1.00 +1411,120.00,-38.40,1.00,0.00,1.00 +1412,-52.80,33.60,1.00,0.00,1.00 +1413,129.60,-33.60,1.00,0.00,1.00 +1414,-43.20,33.60,1.00,0.00,1.00 +1415,139.20,-28.80,1.00,0.00,1.00 +1416,-33.60,28.80,1.00,0.00,1.00 +1417,148.80,-24.00,1.00,0.00,1.00 +1418,-28.80,19.20,1.00,0.00,1.00 +1419,158.40,-19.20,1.00,0.00,1.00 +1420,-19.20,14.40,1.00,0.00,1.00 +1421,163.20,-14.40,1.00,0.00,1.00 +1422,-9.60,9.60,1.00,0.00,1.00 +1423,172.80,-4.80,1.00,0.00,1.00 +1424,-4.80,4.80,1.00,0.00,1.00 +1425,0.00,0.00,1.00,0.00,1.00 +1426,-177.60,4.80,1.00,0.00,1.00 +1427,4.80,-4.80,1.00,0.00,1.00 +1428,-168.00,9.60,1.00,0.00,1.00 +1429,14.40,-14.40,1.00,0.00,1.00 +1430,-163.20,19.20,1.00,0.00,1.00 +1431,19.20,-19.20,1.00,0.00,1.00 +1432,-153.60,24.00,1.00,0.00,1.00 +1433,28.80,-28.80,1.00,0.00,1.00 +1434,-148.80,28.80,1.00,0.00,1.00 +1435,38.40,-33.60,1.00,0.00,1.00 +1436,-139.20,33.60,1.00,0.00,1.00 +1437,48.00,-38.40,1.00,0.00,1.00 +1438,-124.80,38.40,1.00,0.00,1.00 +1439,57.60,-43.20,1.00,0.00,1.00 +1440,-115.20,43.20,1.00,0.00,1.00 +1441,72.00,-43.20,1.00,0.00,1.00 +1442,-100.80,43.20,1.00,0.00,1.00 +1443,86.40,-48.00,1.00,0.00,1.00 +1444,-86.40,48.00,1.00,0.00,1.00 +1445,100.80,-48.00,1.00,0.00,1.00 +1446,-76.80,43.20,1.00,0.00,1.00 +1447,110.40,-43.20,1.00,0.00,1.00 +1448,-62.40,43.20,1.00,0.00,1.00 +1449,124.80,-38.40,1.00,0.00,1.00 +1450,-48.00,38.40,1.00,0.00,1.00 +1451,134.40,-38.40,1.00,0.00,1.00 +1452,-38.40,33.60,1.00,0.00,1.00 +1453,144.00,-28.80,1.00,0.00,1.00 +1454,-28.80,28.80,1.00,0.00,1.00 +1455,153.60,-24.00,1.00,0.00,1.00 +1456,-24.00,24.00,1.00,0.00,1.00 +1457,163.20,-19.20,1.00,0.00,1.00 +1458,-14.40,14.40,1.00,0.00,1.00 +1459,168.00,-14.40,1.00,0.00,1.00 +1460,-9.60,9.60,1.00,0.00,1.00 +1461,172.80,-4.80,1.00,0.00,1.00 +1462,-0.00,0.00,1.00,0.00,1.00 +1463,-177.60,0.00,1.00,0.00,1.00 +1464,4.80,-4.80,1.00,0.00,1.00 +1465,-172.80,9.60,1.00,0.00,1.00 +1466,9.60,-14.40,1.00,0.00,1.00 +1467,-163.20,14.40,1.00,0.00,1.00 +1468,19.20,-19.20,1.00,0.00,1.00 +1469,-158.40,24.00,1.00,0.00,1.00 +1470,28.80,-24.00,1.00,0.00,1.00 +1471,-148.80,28.80,1.00,0.00,1.00 +1472,33.60,-28.80,1.00,0.00,1.00 +1473,-139.20,33.60,1.00,0.00,1.00 +1474,43.20,-38.40,1.00,0.00,1.00 +1475,-129.60,38.40,1.00,0.00,1.00 +1476,57.60,-38.40,1.00,0.00,1.00 +1477,-120.00,43.20,1.00,0.00,1.00 +1478,67.20,-43.20,1.00,0.00,1.00 +1479,-105.60,43.20,1.00,0.00,1.00 +1480,81.60,-48.00,1.00,0.00,1.00 +1481,-91.20,48.00,1.00,0.00,1.00 +1482,96.00,-48.00,1.00,0.00,1.00 +1483,-76.80,43.20,1.00,0.00,1.00 +1484,110.40,-43.20,1.00,0.00,1.00 +1485,-67.20,43.20,1.00,0.00,1.00 +1486,120.00,-43.20,1.00,0.00,1.00 +1487,-52.80,38.40,1.00,0.00,1.00 +1488,134.40,-38.40,1.00,0.00,1.00 +1489,-43.20,33.60,1.00,0.00,1.00 +1490,144.00,-33.60,1.00,0.00,1.00 +1491,-33.60,28.80,1.00,0.00,1.00 +1492,153.60,-28.80,1.00,0.00,1.00 +1493,-24.00,24.00,1.00,0.00,1.00 +1494,158.40,-19.20,1.00,0.00,1.00 +1495,-19.20,19.20,1.00,0.00,1.00 +1496,168.00,-14.40,1.00,0.00,1.00 +1497,-9.60,9.60,1.00,0.00,1.00 +1498,172.80,-4.80,1.00,0.00,1.00 +1499,-4.80,4.80,1.00,0.00,1.00 diff --git a/scripts/tests/data/stvISM4.csv b/scripts/tests/data/stvISM4.csv new file mode 100644 index 0000000000..f3a2884ff0 --- /dev/null +++ b/scripts/tests/data/stvISM4.csv @@ -0,0 +1,1500 @@ +0,-0.00,0.00,1.00,0.00,1.00 +1,-0.00,4.80,1.00,0.00,1.00 +2,-0.00,9.60,1.00,0.00,1.00 +3,-0.00,14.40,1.00,0.00,1.00 +4,-0.00,19.20,1.00,0.00,1.00 +5,-0.00,24.00,1.00,0.00,1.00 +6,-0.00,28.80,1.00,0.00,1.00 +7,-0.00,33.60,1.00,0.00,1.00 +8,-0.00,38.40,1.00,0.00,1.00 +9,-0.00,43.20,1.00,0.00,1.00 +10,-0.00,48.00,1.00,0.00,1.00 +11,-0.00,52.80,1.00,0.00,1.00 +12,-0.00,57.60,1.00,0.00,1.00 +13,-0.00,62.40,1.00,0.00,1.00 +14,-0.00,67.20,1.00,0.00,1.00 +15,-0.00,72.00,1.00,0.00,1.00 +16,-0.00,76.80,1.00,0.00,1.00 +17,-0.00,81.60,1.00,0.00,1.00 +18,-0.00,86.40,1.00,0.00,1.00 +19,-177.60,91.20,1.00,0.00,1.00 +20,-177.60,86.40,1.00,0.00,1.00 +21,-177.60,81.60,1.00,0.00,1.00 +22,-177.60,76.80,1.00,0.00,1.00 +23,-177.60,72.00,1.00,0.00,1.00 +24,-177.60,67.20,1.00,0.00,1.00 +25,177.60,62.40,1.00,0.00,1.00 +26,177.60,57.60,1.00,0.00,1.00 +27,177.60,52.80,1.00,0.00,1.00 +28,177.60,48.00,1.00,0.00,1.00 +29,177.60,43.20,1.00,0.00,1.00 +30,177.60,38.40,1.00,0.00,1.00 +31,177.60,33.60,1.00,0.00,1.00 +32,177.60,28.80,1.00,0.00,1.00 +33,177.60,24.00,1.00,0.00,1.00 +34,177.60,19.20,1.00,0.00,1.00 +35,177.60,14.40,1.00,0.00,1.00 +36,177.60,9.60,1.00,0.00,1.00 +37,177.60,4.80,1.00,0.00,1.00 +38,-177.60,-0.00,1.00,0.00,1.00 +39,-177.60,-4.80,1.00,0.00,1.00 +40,-177.60,-9.60,1.00,0.00,1.00 +41,-177.60,-14.40,1.00,0.00,1.00 +42,-177.60,-19.20,1.00,0.00,1.00 +43,-177.60,-24.00,1.00,0.00,1.00 +44,-177.60,-28.80,1.00,0.00,1.00 +45,-177.60,-33.60,1.00,0.00,1.00 +46,-177.60,-38.40,1.00,0.00,1.00 +47,-177.60,-48.00,1.00,0.00,1.00 +48,-177.60,-48.00,1.00,0.00,1.00 +49,-177.60,-52.80,1.00,0.00,1.00 +50,-177.60,-57.60,1.00,0.00,1.00 +51,177.60,-62.40,1.00,0.00,1.00 +52,177.60,-67.20,1.00,0.00,1.00 +53,177.60,-76.80,1.00,0.00,1.00 +54,177.60,-76.80,1.00,0.00,1.00 +55,177.60,-86.40,1.00,0.00,1.00 +56,177.60,-91.20,1.00,0.00,1.00 +57,0.00,-86.40,1.00,0.00,1.00 +58,0.00,-81.60,1.00,0.00,1.00 +59,0.00,-76.80,1.00,0.00,1.00 +60,0.00,-72.00,1.00,0.00,1.00 +61,0.00,-67.20,1.00,0.00,1.00 +62,0.00,-62.40,1.00,0.00,1.00 +63,0.00,-57.60,1.00,0.00,1.00 +64,0.00,-52.80,1.00,0.00,1.00 +65,0.00,-48.00,1.00,0.00,1.00 +66,0.00,-43.20,1.00,0.00,1.00 +67,0.00,-38.40,1.00,0.00,1.00 +68,0.00,-33.60,1.00,0.00,1.00 +69,0.00,-28.80,1.00,0.00,1.00 +70,0.00,-24.00,1.00,0.00,1.00 +71,0.00,-19.20,1.00,0.00,1.00 +72,0.00,-14.40,1.00,0.00,1.00 +73,0.00,-9.60,1.00,0.00,1.00 +74,0.00,-4.80,1.00,0.00,1.00 +75,0.00,0.00,1.00,0.00,1.00 +76,0.00,4.80,1.00,0.00,1.00 +77,0.00,9.60,1.00,0.00,1.00 +78,0.00,14.40,1.00,0.00,1.00 +79,0.00,19.20,1.00,0.00,1.00 +80,0.00,24.00,1.00,0.00,1.00 +81,4.80,28.80,1.00,0.00,1.00 +82,4.80,33.60,1.00,0.00,1.00 +83,4.80,38.40,1.00,0.00,1.00 +84,4.80,43.20,1.00,0.00,1.00 +85,4.80,48.00,1.00,0.00,1.00 +86,4.80,52.80,1.00,0.00,1.00 +87,9.60,57.60,1.00,0.00,1.00 +88,9.60,62.40,1.00,0.00,1.00 +89,9.60,67.20,1.00,0.00,1.00 +90,14.40,72.00,1.00,0.00,1.00 +91,19.20,76.80,1.00,0.00,1.00 +92,28.80,81.60,1.00,0.00,1.00 +93,52.80,86.40,1.00,0.00,1.00 +94,105.60,86.40,1.00,0.00,1.00 +95,139.20,81.60,1.00,0.00,1.00 +96,158.40,76.80,1.00,0.00,1.00 +97,163.20,72.00,1.00,0.00,1.00 +98,168.00,67.20,1.00,0.00,1.00 +99,168.00,62.40,1.00,0.00,1.00 +100,172.80,57.60,1.00,0.00,1.00 +101,172.80,52.80,1.00,0.00,1.00 +102,172.80,48.00,1.00,0.00,1.00 +103,172.80,43.20,1.00,0.00,1.00 +104,177.60,38.40,1.00,0.00,1.00 +105,177.60,33.60,1.00,0.00,1.00 +106,177.60,28.80,1.00,0.00,1.00 +107,177.60,24.00,1.00,0.00,1.00 +108,177.60,19.20,1.00,0.00,1.00 +109,177.60,14.40,1.00,0.00,1.00 +110,177.60,9.60,1.00,0.00,1.00 +111,177.60,4.80,1.00,0.00,1.00 +112,177.60,0.00,1.00,0.00,1.00 +113,-177.60,-0.00,1.00,0.00,1.00 +114,-177.60,-4.80,1.00,0.00,1.00 +115,-177.60,-9.60,1.00,0.00,1.00 +116,-177.60,-14.40,1.00,0.00,1.00 +117,-177.60,-19.20,1.00,0.00,1.00 +118,-177.60,-24.00,1.00,0.00,1.00 +119,-177.60,-28.80,1.00,0.00,1.00 +120,-177.60,-33.60,1.00,0.00,1.00 +121,-177.60,-38.40,1.00,0.00,1.00 +122,-172.80,-43.20,1.00,0.00,1.00 +123,-172.80,-48.00,1.00,0.00,1.00 +124,-172.80,-52.80,1.00,0.00,1.00 +125,-172.80,-57.60,1.00,0.00,1.00 +126,-168.00,-62.40,1.00,0.00,1.00 +127,-168.00,-67.20,1.00,0.00,1.00 +128,-163.20,-72.00,1.00,0.00,1.00 +129,-158.40,-76.80,1.00,0.00,1.00 +130,-139.20,-81.60,1.00,0.00,1.00 +131,-105.60,-86.40,1.00,0.00,1.00 +132,-52.80,-86.40,1.00,0.00,1.00 +133,-28.80,-81.60,1.00,0.00,1.00 +134,-19.20,-76.80,1.00,0.00,1.00 +135,-14.40,-72.00,1.00,0.00,1.00 +136,-9.60,-67.20,1.00,0.00,1.00 +137,-9.60,-62.40,1.00,0.00,1.00 +138,-9.60,-57.60,1.00,0.00,1.00 +139,-4.80,-52.80,1.00,0.00,1.00 +140,-4.80,-48.00,1.00,0.00,1.00 +141,-4.80,-43.20,1.00,0.00,1.00 +142,-4.80,-38.40,1.00,0.00,1.00 +143,-4.80,-33.60,1.00,0.00,1.00 +144,-4.80,-28.80,1.00,0.00,1.00 +145,-0.00,-24.00,1.00,0.00,1.00 +146,-0.00,-19.20,1.00,0.00,1.00 +147,-0.00,-14.40,1.00,0.00,1.00 +148,-0.00,-9.60,1.00,0.00,1.00 +149,-0.00,-4.80,1.00,0.00,1.00 +150,0.00,0.00,1.00,0.00,1.00 +151,0.00,4.80,1.00,0.00,1.00 +152,0.00,9.60,1.00,0.00,1.00 +153,4.80,14.40,1.00,0.00,1.00 +154,4.80,19.20,1.00,0.00,1.00 +155,4.80,24.00,1.00,0.00,1.00 +156,4.80,28.80,1.00,0.00,1.00 +157,4.80,33.60,1.00,0.00,1.00 +158,9.60,38.40,1.00,0.00,1.00 +159,9.60,43.20,1.00,0.00,1.00 +160,9.60,48.00,1.00,0.00,1.00 +161,14.40,52.80,1.00,0.00,1.00 +162,14.40,57.60,1.00,0.00,1.00 +163,19.20,62.40,1.00,0.00,1.00 +164,24.00,67.20,1.00,0.00,1.00 +165,28.80,72.00,1.00,0.00,1.00 +166,33.60,72.00,1.00,0.00,1.00 +167,48.00,76.80,1.00,0.00,1.00 +168,67.20,81.60,1.00,0.00,1.00 +169,96.00,81.60,1.00,0.00,1.00 +170,120.00,76.80,1.00,0.00,1.00 +171,139.20,76.80,1.00,0.00,1.00 +172,148.80,72.00,1.00,0.00,1.00 +173,153.60,67.20,1.00,0.00,1.00 +174,158.40,62.40,1.00,0.00,1.00 +175,163.20,57.60,1.00,0.00,1.00 +176,168.00,52.80,1.00,0.00,1.00 +177,168.00,48.00,1.00,0.00,1.00 +178,168.00,43.20,1.00,0.00,1.00 +179,172.80,38.40,1.00,0.00,1.00 +180,172.80,33.60,1.00,0.00,1.00 +181,172.80,28.80,1.00,0.00,1.00 +182,177.60,24.00,1.00,0.00,1.00 +183,177.60,19.20,1.00,0.00,1.00 +184,177.60,14.40,1.00,0.00,1.00 +185,177.60,9.60,1.00,0.00,1.00 +186,177.60,4.80,1.00,0.00,1.00 +187,177.60,0.00,1.00,0.00,1.00 +188,-177.60,-0.00,1.00,0.00,1.00 +189,-177.60,-4.80,1.00,0.00,1.00 +190,-177.60,-9.60,1.00,0.00,1.00 +191,-177.60,-14.40,1.00,0.00,1.00 +192,-177.60,-19.20,1.00,0.00,1.00 +193,-177.60,-24.00,1.00,0.00,1.00 +194,-172.80,-28.80,1.00,0.00,1.00 +195,-172.80,-33.60,1.00,0.00,1.00 +196,-172.80,-38.40,1.00,0.00,1.00 +197,-168.00,-43.20,1.00,0.00,1.00 +198,-168.00,-48.00,1.00,0.00,1.00 +199,-168.00,-52.80,1.00,0.00,1.00 +200,-163.20,-57.60,1.00,0.00,1.00 +201,-158.40,-62.40,1.00,0.00,1.00 +202,-153.60,-67.20,1.00,0.00,1.00 +203,-148.80,-72.00,1.00,0.00,1.00 +204,-139.20,-76.80,1.00,0.00,1.00 +205,-120.00,-76.80,1.00,0.00,1.00 +206,-96.00,-81.60,1.00,0.00,1.00 +207,-67.20,-81.60,1.00,0.00,1.00 +208,-48.00,-76.80,1.00,0.00,1.00 +209,-33.60,-72.00,1.00,0.00,1.00 +210,-28.80,-72.00,1.00,0.00,1.00 +211,-24.00,-67.20,1.00,0.00,1.00 +212,-19.20,-62.40,1.00,0.00,1.00 +213,-14.40,-57.60,1.00,0.00,1.00 +214,-14.40,-52.80,1.00,0.00,1.00 +215,-9.60,-48.00,1.00,0.00,1.00 +216,-9.60,-43.20,1.00,0.00,1.00 +217,-9.60,-38.40,1.00,0.00,1.00 +218,-4.80,-33.60,1.00,0.00,1.00 +219,-4.80,-28.80,1.00,0.00,1.00 +220,-4.80,-24.00,1.00,0.00,1.00 +221,-4.80,-19.20,1.00,0.00,1.00 +222,-4.80,-14.40,1.00,0.00,1.00 +223,-0.00,-9.60,1.00,0.00,1.00 +224,-0.00,-4.80,1.00,0.00,1.00 +225,0.00,0.00,1.00,0.00,1.00 +226,0.00,4.80,1.00,0.00,1.00 +227,4.80,9.60,1.00,0.00,1.00 +228,4.80,14.40,1.00,0.00,1.00 +229,4.80,19.20,1.00,0.00,1.00 +230,4.80,24.00,1.00,0.00,1.00 +231,9.60,28.80,1.00,0.00,1.00 +232,9.60,33.60,1.00,0.00,1.00 +233,9.60,38.40,1.00,0.00,1.00 +234,14.40,43.20,1.00,0.00,1.00 +235,14.40,48.00,1.00,0.00,1.00 +236,19.20,52.80,1.00,0.00,1.00 +237,19.20,52.80,1.00,0.00,1.00 +238,24.00,57.60,1.00,0.00,1.00 +239,28.80,62.40,1.00,0.00,1.00 +240,38.40,67.20,1.00,0.00,1.00 +241,48.00,72.00,1.00,0.00,1.00 +242,57.60,72.00,1.00,0.00,1.00 +243,76.80,76.80,1.00,0.00,1.00 +244,96.00,76.80,1.00,0.00,1.00 +245,115.20,76.80,1.00,0.00,1.00 +246,129.60,72.00,1.00,0.00,1.00 +247,139.20,67.20,1.00,0.00,1.00 +248,144.00,67.20,1.00,0.00,1.00 +249,153.60,62.40,1.00,0.00,1.00 +250,158.40,57.60,1.00,0.00,1.00 +251,158.40,52.80,1.00,0.00,1.00 +252,163.20,48.00,1.00,0.00,1.00 +253,168.00,43.20,1.00,0.00,1.00 +254,168.00,38.40,1.00,0.00,1.00 +255,168.00,33.60,1.00,0.00,1.00 +256,172.80,28.80,1.00,0.00,1.00 +257,172.80,24.00,1.00,0.00,1.00 +258,172.80,19.20,1.00,0.00,1.00 +259,177.60,14.40,1.00,0.00,1.00 +260,177.60,9.60,1.00,0.00,1.00 +261,177.60,4.80,1.00,0.00,1.00 +262,177.60,0.00,1.00,0.00,1.00 +263,-177.60,-0.00,1.00,0.00,1.00 +264,-177.60,-4.80,1.00,0.00,1.00 +265,-177.60,-9.60,1.00,0.00,1.00 +266,-177.60,-14.40,1.00,0.00,1.00 +267,-172.80,-19.20,1.00,0.00,1.00 +268,-172.80,-24.00,1.00,0.00,1.00 +269,-172.80,-28.80,1.00,0.00,1.00 +270,-168.00,-33.60,1.00,0.00,1.00 +271,-168.00,-38.40,1.00,0.00,1.00 +272,-168.00,-43.20,1.00,0.00,1.00 +273,-163.20,-48.00,1.00,0.00,1.00 +274,-158.40,-52.80,1.00,0.00,1.00 +275,-158.40,-57.60,1.00,0.00,1.00 +276,-153.60,-62.40,1.00,0.00,1.00 +277,-144.00,-67.20,1.00,0.00,1.00 +278,-139.20,-67.20,1.00,0.00,1.00 +279,-129.60,-72.00,1.00,0.00,1.00 +280,-115.20,-76.80,1.00,0.00,1.00 +281,-96.00,-76.80,1.00,0.00,1.00 +282,-76.80,-76.80,1.00,0.00,1.00 +283,-57.60,-72.00,1.00,0.00,1.00 +284,-48.00,-72.00,1.00,0.00,1.00 +285,-38.40,-67.20,1.00,0.00,1.00 +286,-28.80,-62.40,1.00,0.00,1.00 +287,-24.00,-57.60,1.00,0.00,1.00 +288,-19.20,-52.80,1.00,0.00,1.00 +289,-19.20,-52.80,1.00,0.00,1.00 +290,-14.40,-48.00,1.00,0.00,1.00 +291,-14.40,-43.20,1.00,0.00,1.00 +292,-9.60,-38.40,1.00,0.00,1.00 +293,-9.60,-33.60,1.00,0.00,1.00 +294,-9.60,-28.80,1.00,0.00,1.00 +295,-4.80,-24.00,1.00,0.00,1.00 +296,-4.80,-19.20,1.00,0.00,1.00 +297,-4.80,-14.40,1.00,0.00,1.00 +298,-4.80,-9.60,1.00,0.00,1.00 +299,-0.00,-4.80,1.00,0.00,1.00 +300,0.00,0.00,1.00,0.00,1.00 +301,0.00,4.80,1.00,0.00,1.00 +302,4.80,9.60,1.00,0.00,1.00 +303,4.80,14.40,1.00,0.00,1.00 +304,4.80,19.20,1.00,0.00,1.00 +305,9.60,24.00,1.00,0.00,1.00 +306,9.60,28.80,1.00,0.00,1.00 +307,14.40,33.60,1.00,0.00,1.00 +308,14.40,33.60,1.00,0.00,1.00 +309,19.20,38.40,1.00,0.00,1.00 +310,19.20,43.20,1.00,0.00,1.00 +311,24.00,48.00,1.00,0.00,1.00 +312,28.80,52.80,1.00,0.00,1.00 +313,33.60,57.60,1.00,0.00,1.00 +314,38.40,62.40,1.00,0.00,1.00 +315,43.20,62.40,1.00,0.00,1.00 +316,52.80,67.20,1.00,0.00,1.00 +317,67.20,67.20,1.00,0.00,1.00 +318,76.80,72.00,1.00,0.00,1.00 +319,96.00,72.00,1.00,0.00,1.00 +320,105.60,72.00,1.00,0.00,1.00 +321,120.00,67.20,1.00,0.00,1.00 +322,129.60,67.20,1.00,0.00,1.00 +323,139.20,62.40,1.00,0.00,1.00 +324,144.00,57.60,1.00,0.00,1.00 +325,148.80,52.80,1.00,0.00,1.00 +326,153.60,52.80,1.00,0.00,1.00 +327,158.40,48.00,1.00,0.00,1.00 +328,163.20,43.20,1.00,0.00,1.00 +329,163.20,38.40,1.00,0.00,1.00 +330,168.00,33.60,1.00,0.00,1.00 +331,168.00,28.80,1.00,0.00,1.00 +332,172.80,24.00,1.00,0.00,1.00 +333,172.80,19.20,1.00,0.00,1.00 +334,172.80,14.40,1.00,0.00,1.00 +335,177.60,9.60,1.00,0.00,1.00 +336,177.60,4.80,1.00,0.00,1.00 +337,177.60,0.00,1.00,0.00,1.00 +338,-177.60,-0.00,1.00,0.00,1.00 +339,-177.60,-4.80,1.00,0.00,1.00 +340,-177.60,-9.60,1.00,0.00,1.00 +341,-172.80,-14.40,1.00,0.00,1.00 +342,-172.80,-19.20,1.00,0.00,1.00 +343,-172.80,-24.00,1.00,0.00,1.00 +344,-168.00,-28.80,1.00,0.00,1.00 +345,-168.00,-33.60,1.00,0.00,1.00 +346,-163.20,-38.40,1.00,0.00,1.00 +347,-163.20,-43.20,1.00,0.00,1.00 +348,-158.40,-48.00,1.00,0.00,1.00 +349,-153.60,-52.80,1.00,0.00,1.00 +350,-148.80,-52.80,1.00,0.00,1.00 +351,-144.00,-57.60,1.00,0.00,1.00 +352,-139.20,-62.40,1.00,0.00,1.00 +353,-129.60,-67.20,1.00,0.00,1.00 +354,-120.00,-67.20,1.00,0.00,1.00 +355,-105.60,-72.00,1.00,0.00,1.00 +356,-96.00,-72.00,1.00,0.00,1.00 +357,-76.80,-72.00,1.00,0.00,1.00 +358,-67.20,-67.20,1.00,0.00,1.00 +359,-52.80,-67.20,1.00,0.00,1.00 +360,-43.20,-62.40,1.00,0.00,1.00 +361,-38.40,-62.40,1.00,0.00,1.00 +362,-33.60,-57.60,1.00,0.00,1.00 +363,-28.80,-52.80,1.00,0.00,1.00 +364,-24.00,-48.00,1.00,0.00,1.00 +365,-19.20,-43.20,1.00,0.00,1.00 +366,-19.20,-38.40,1.00,0.00,1.00 +367,-14.40,-33.60,1.00,0.00,1.00 +368,-14.40,-33.60,1.00,0.00,1.00 +369,-9.60,-28.80,1.00,0.00,1.00 +370,-9.60,-24.00,1.00,0.00,1.00 +371,-4.80,-19.20,1.00,0.00,1.00 +372,-4.80,-14.40,1.00,0.00,1.00 +373,-4.80,-9.60,1.00,0.00,1.00 +374,-0.00,-4.80,1.00,0.00,1.00 +375,0.00,0.00,1.00,0.00,1.00 +376,0.00,4.80,1.00,0.00,1.00 +377,4.80,9.60,1.00,0.00,1.00 +378,4.80,14.40,1.00,0.00,1.00 +379,9.60,19.20,1.00,0.00,1.00 +380,9.60,24.00,1.00,0.00,1.00 +381,14.40,24.00,1.00,0.00,1.00 +382,14.40,28.80,1.00,0.00,1.00 +383,19.20,33.60,1.00,0.00,1.00 +384,19.20,38.40,1.00,0.00,1.00 +385,24.00,43.20,1.00,0.00,1.00 +386,28.80,48.00,1.00,0.00,1.00 +387,33.60,52.80,1.00,0.00,1.00 +388,38.40,52.80,1.00,0.00,1.00 +389,43.20,57.60,1.00,0.00,1.00 +390,52.80,62.40,1.00,0.00,1.00 +391,62.40,62.40,1.00,0.00,1.00 +392,72.00,62.40,1.00,0.00,1.00 +393,81.60,67.20,1.00,0.00,1.00 +394,91.20,67.20,1.00,0.00,1.00 +395,105.60,67.20,1.00,0.00,1.00 +396,115.20,62.40,1.00,0.00,1.00 +397,124.80,62.40,1.00,0.00,1.00 +398,134.40,57.60,1.00,0.00,1.00 +399,139.20,57.60,1.00,0.00,1.00 +400,144.00,52.80,1.00,0.00,1.00 +401,148.80,48.00,1.00,0.00,1.00 +402,153.60,43.20,1.00,0.00,1.00 +403,158.40,38.40,1.00,0.00,1.00 +404,158.40,38.40,1.00,0.00,1.00 +405,163.20,33.60,1.00,0.00,1.00 +406,168.00,28.80,1.00,0.00,1.00 +407,168.00,24.00,1.00,0.00,1.00 +408,172.80,19.20,1.00,0.00,1.00 +409,172.80,14.40,1.00,0.00,1.00 +410,172.80,9.60,1.00,0.00,1.00 +411,177.60,4.80,1.00,0.00,1.00 +412,177.60,0.00,1.00,0.00,1.00 +413,-177.60,-0.00,1.00,0.00,1.00 +414,-177.60,-4.80,1.00,0.00,1.00 +415,-172.80,-9.60,1.00,0.00,1.00 +416,-172.80,-14.40,1.00,0.00,1.00 +417,-172.80,-19.20,1.00,0.00,1.00 +418,-168.00,-24.00,1.00,0.00,1.00 +419,-168.00,-28.80,1.00,0.00,1.00 +420,-163.20,-33.60,1.00,0.00,1.00 +421,-158.40,-38.40,1.00,0.00,1.00 +422,-158.40,-38.40,1.00,0.00,1.00 +423,-153.60,-43.20,1.00,0.00,1.00 +424,-148.80,-48.00,1.00,0.00,1.00 +425,-144.00,-52.80,1.00,0.00,1.00 +426,-139.20,-57.60,1.00,0.00,1.00 +427,-134.40,-57.60,1.00,0.00,1.00 +428,-124.80,-62.40,1.00,0.00,1.00 +429,-115.20,-62.40,1.00,0.00,1.00 +430,-105.60,-67.20,1.00,0.00,1.00 +431,-91.20,-67.20,1.00,0.00,1.00 +432,-81.60,-67.20,1.00,0.00,1.00 +433,-72.00,-62.40,1.00,0.00,1.00 +434,-62.40,-62.40,1.00,0.00,1.00 +435,-52.80,-62.40,1.00,0.00,1.00 +436,-43.20,-57.60,1.00,0.00,1.00 +437,-38.40,-52.80,1.00,0.00,1.00 +438,-33.60,-52.80,1.00,0.00,1.00 +439,-28.80,-48.00,1.00,0.00,1.00 +440,-24.00,-43.20,1.00,0.00,1.00 +441,-19.20,-38.40,1.00,0.00,1.00 +442,-19.20,-33.60,1.00,0.00,1.00 +443,-14.40,-28.80,1.00,0.00,1.00 +444,-14.40,-24.00,1.00,0.00,1.00 +445,-9.60,-24.00,1.00,0.00,1.00 +446,-9.60,-19.20,1.00,0.00,1.00 +447,-4.80,-14.40,1.00,0.00,1.00 +448,-4.80,-9.60,1.00,0.00,1.00 +449,-0.00,-4.80,1.00,0.00,1.00 +450,0.00,0.00,1.00,0.00,1.00 +451,0.00,4.80,1.00,0.00,1.00 +452,4.80,9.60,1.00,0.00,1.00 +453,4.80,14.40,1.00,0.00,1.00 +454,9.60,14.40,1.00,0.00,1.00 +455,14.40,19.20,1.00,0.00,1.00 +456,14.40,24.00,1.00,0.00,1.00 +457,19.20,28.80,1.00,0.00,1.00 +458,19.20,33.60,1.00,0.00,1.00 +459,24.00,38.40,1.00,0.00,1.00 +460,28.80,38.40,1.00,0.00,1.00 +461,33.60,43.20,1.00,0.00,1.00 +462,38.40,48.00,1.00,0.00,1.00 +463,43.20,52.80,1.00,0.00,1.00 +464,48.00,52.80,1.00,0.00,1.00 +465,57.60,57.60,1.00,0.00,1.00 +466,62.40,57.60,1.00,0.00,1.00 +467,72.00,62.40,1.00,0.00,1.00 +468,81.60,62.40,1.00,0.00,1.00 +469,91.20,62.40,1.00,0.00,1.00 +470,100.80,62.40,1.00,0.00,1.00 +471,110.40,57.60,1.00,0.00,1.00 +472,120.00,57.60,1.00,0.00,1.00 +473,129.60,57.60,1.00,0.00,1.00 +474,134.40,52.80,1.00,0.00,1.00 +475,139.20,48.00,1.00,0.00,1.00 +476,144.00,48.00,1.00,0.00,1.00 +477,148.80,43.20,1.00,0.00,1.00 +478,153.60,38.40,1.00,0.00,1.00 +479,158.40,33.60,1.00,0.00,1.00 +480,158.40,28.80,1.00,0.00,1.00 +481,163.20,28.80,1.00,0.00,1.00 +482,168.00,24.00,1.00,0.00,1.00 +483,168.00,19.20,1.00,0.00,1.00 +484,172.80,14.40,1.00,0.00,1.00 +485,172.80,9.60,1.00,0.00,1.00 +486,177.60,4.80,1.00,0.00,1.00 +487,177.60,0.00,1.00,0.00,1.00 +488,-177.60,-0.00,1.00,0.00,1.00 +489,-177.60,-4.80,1.00,0.00,1.00 +490,-172.80,-9.60,1.00,0.00,1.00 +491,-172.80,-14.40,1.00,0.00,1.00 +492,-168.00,-19.20,1.00,0.00,1.00 +493,-168.00,-24.00,1.00,0.00,1.00 +494,-163.20,-28.80,1.00,0.00,1.00 +495,-158.40,-28.80,1.00,0.00,1.00 +496,-158.40,-33.60,1.00,0.00,1.00 +497,-153.60,-38.40,1.00,0.00,1.00 +498,-148.80,-43.20,1.00,0.00,1.00 +499,-144.00,-48.00,1.00,0.00,1.00 +500,-139.20,-48.00,1.00,0.00,1.00 +501,-134.40,-52.80,1.00,0.00,1.00 +502,-129.60,-57.60,1.00,0.00,1.00 +503,-120.00,-57.60,1.00,0.00,1.00 +504,-110.40,-57.60,1.00,0.00,1.00 +505,-100.80,-62.40,1.00,0.00,1.00 +506,-91.20,-62.40,1.00,0.00,1.00 +507,-81.60,-62.40,1.00,0.00,1.00 +508,-72.00,-62.40,1.00,0.00,1.00 +509,-62.40,-57.60,1.00,0.00,1.00 +510,-57.60,-57.60,1.00,0.00,1.00 +511,-48.00,-52.80,1.00,0.00,1.00 +512,-43.20,-52.80,1.00,0.00,1.00 +513,-38.40,-48.00,1.00,0.00,1.00 +514,-33.60,-43.20,1.00,0.00,1.00 +515,-28.80,-38.40,1.00,0.00,1.00 +516,-24.00,-38.40,1.00,0.00,1.00 +517,-19.20,-33.60,1.00,0.00,1.00 +518,-19.20,-28.80,1.00,0.00,1.00 +519,-14.40,-24.00,1.00,0.00,1.00 +520,-14.40,-19.20,1.00,0.00,1.00 +521,-9.60,-14.40,1.00,0.00,1.00 +522,-4.80,-14.40,1.00,0.00,1.00 +523,-4.80,-9.60,1.00,0.00,1.00 +524,-0.00,-4.80,1.00,0.00,1.00 +525,0.00,0.00,1.00,0.00,1.00 +526,4.80,4.80,1.00,0.00,1.00 +527,4.80,9.60,1.00,0.00,1.00 +528,9.60,9.60,1.00,0.00,1.00 +529,9.60,14.40,1.00,0.00,1.00 +530,14.40,19.20,1.00,0.00,1.00 +531,19.20,24.00,1.00,0.00,1.00 +532,19.20,28.80,1.00,0.00,1.00 +533,24.00,28.80,1.00,0.00,1.00 +534,28.80,33.60,1.00,0.00,1.00 +535,33.60,38.40,1.00,0.00,1.00 +536,38.40,43.20,1.00,0.00,1.00 +537,43.20,43.20,1.00,0.00,1.00 +538,48.00,48.00,1.00,0.00,1.00 +539,52.80,48.00,1.00,0.00,1.00 +540,57.60,52.80,1.00,0.00,1.00 +541,67.20,52.80,1.00,0.00,1.00 +542,76.80,57.60,1.00,0.00,1.00 +543,81.60,57.60,1.00,0.00,1.00 +544,91.20,57.60,1.00,0.00,1.00 +545,100.80,57.60,1.00,0.00,1.00 +546,110.40,52.80,1.00,0.00,1.00 +547,115.20,52.80,1.00,0.00,1.00 +548,124.80,52.80,1.00,0.00,1.00 +549,129.60,48.00,1.00,0.00,1.00 +550,134.40,48.00,1.00,0.00,1.00 +551,139.20,43.20,1.00,0.00,1.00 +552,144.00,38.40,1.00,0.00,1.00 +553,148.80,38.40,1.00,0.00,1.00 +554,153.60,33.60,1.00,0.00,1.00 +555,158.40,28.80,1.00,0.00,1.00 +556,163.20,24.00,1.00,0.00,1.00 +557,163.20,24.00,1.00,0.00,1.00 +558,168.00,19.20,1.00,0.00,1.00 +559,172.80,14.40,1.00,0.00,1.00 +560,172.80,9.60,1.00,0.00,1.00 +561,177.60,4.80,1.00,0.00,1.00 +562,177.60,0.00,1.00,0.00,1.00 +563,-177.60,-0.00,1.00,0.00,1.00 +564,-177.60,-4.80,1.00,0.00,1.00 +565,-172.80,-9.60,1.00,0.00,1.00 +566,-172.80,-14.40,1.00,0.00,1.00 +567,-168.00,-19.20,1.00,0.00,1.00 +568,-163.20,-24.00,1.00,0.00,1.00 +569,-163.20,-24.00,1.00,0.00,1.00 +570,-158.40,-28.80,1.00,0.00,1.00 +571,-153.60,-33.60,1.00,0.00,1.00 +572,-148.80,-38.40,1.00,0.00,1.00 +573,-144.00,-38.40,1.00,0.00,1.00 +574,-139.20,-43.20,1.00,0.00,1.00 +575,-134.40,-48.00,1.00,0.00,1.00 +576,-129.60,-48.00,1.00,0.00,1.00 +577,-124.80,-52.80,1.00,0.00,1.00 +578,-115.20,-52.80,1.00,0.00,1.00 +579,-110.40,-52.80,1.00,0.00,1.00 +580,-100.80,-57.60,1.00,0.00,1.00 +581,-91.20,-57.60,1.00,0.00,1.00 +582,-81.60,-57.60,1.00,0.00,1.00 +583,-76.80,-57.60,1.00,0.00,1.00 +584,-67.20,-52.80,1.00,0.00,1.00 +585,-57.60,-52.80,1.00,0.00,1.00 +586,-52.80,-48.00,1.00,0.00,1.00 +587,-48.00,-48.00,1.00,0.00,1.00 +588,-43.20,-43.20,1.00,0.00,1.00 +589,-38.40,-43.20,1.00,0.00,1.00 +590,-33.60,-38.40,1.00,0.00,1.00 +591,-28.80,-33.60,1.00,0.00,1.00 +592,-24.00,-28.80,1.00,0.00,1.00 +593,-19.20,-28.80,1.00,0.00,1.00 +594,-19.20,-24.00,1.00,0.00,1.00 +595,-14.40,-19.20,1.00,0.00,1.00 +596,-9.60,-14.40,1.00,0.00,1.00 +597,-9.60,-9.60,1.00,0.00,1.00 +598,-4.80,-9.60,1.00,0.00,1.00 +599,-4.80,-4.80,1.00,0.00,1.00 +600,0.00,0.00,1.00,0.00,1.00 +601,4.80,4.80,1.00,0.00,1.00 +602,4.80,9.60,1.00,0.00,1.00 +603,9.60,9.60,1.00,0.00,1.00 +604,14.40,14.40,1.00,0.00,1.00 +605,14.40,19.20,1.00,0.00,1.00 +606,19.20,24.00,1.00,0.00,1.00 +607,24.00,24.00,1.00,0.00,1.00 +608,24.00,28.80,1.00,0.00,1.00 +609,28.80,33.60,1.00,0.00,1.00 +610,33.60,33.60,1.00,0.00,1.00 +611,38.40,38.40,1.00,0.00,1.00 +612,43.20,43.20,1.00,0.00,1.00 +613,48.00,43.20,1.00,0.00,1.00 +614,57.60,48.00,1.00,0.00,1.00 +615,62.40,48.00,1.00,0.00,1.00 +616,67.20,48.00,1.00,0.00,1.00 +617,76.80,52.80,1.00,0.00,1.00 +618,86.40,52.80,1.00,0.00,1.00 +619,91.20,52.80,1.00,0.00,1.00 +620,100.80,52.80,1.00,0.00,1.00 +621,105.60,48.00,1.00,0.00,1.00 +622,115.20,48.00,1.00,0.00,1.00 +623,120.00,48.00,1.00,0.00,1.00 +624,124.80,43.20,1.00,0.00,1.00 +625,134.40,43.20,1.00,0.00,1.00 +626,139.20,38.40,1.00,0.00,1.00 +627,144.00,38.40,1.00,0.00,1.00 +628,148.80,33.60,1.00,0.00,1.00 +629,153.60,28.80,1.00,0.00,1.00 +630,153.60,28.80,1.00,0.00,1.00 +631,158.40,24.00,1.00,0.00,1.00 +632,163.20,19.20,1.00,0.00,1.00 +633,168.00,14.40,1.00,0.00,1.00 +634,168.00,14.40,1.00,0.00,1.00 +635,172.80,9.60,1.00,0.00,1.00 +636,177.60,4.80,1.00,0.00,1.00 +637,177.60,0.00,1.00,0.00,1.00 +638,-177.60,-0.00,1.00,0.00,1.00 +639,-177.60,-4.80,1.00,0.00,1.00 +640,-172.80,-9.60,1.00,0.00,1.00 +641,-168.00,-14.40,1.00,0.00,1.00 +642,-168.00,-14.40,1.00,0.00,1.00 +643,-163.20,-19.20,1.00,0.00,1.00 +644,-158.40,-24.00,1.00,0.00,1.00 +645,-153.60,-28.80,1.00,0.00,1.00 +646,-153.60,-28.80,1.00,0.00,1.00 +647,-148.80,-33.60,1.00,0.00,1.00 +648,-144.00,-38.40,1.00,0.00,1.00 +649,-139.20,-38.40,1.00,0.00,1.00 +650,-134.40,-43.20,1.00,0.00,1.00 +651,-124.80,-43.20,1.00,0.00,1.00 +652,-120.00,-48.00,1.00,0.00,1.00 +653,-115.20,-48.00,1.00,0.00,1.00 +654,-105.60,-48.00,1.00,0.00,1.00 +655,-100.80,-52.80,1.00,0.00,1.00 +656,-91.20,-52.80,1.00,0.00,1.00 +657,-86.40,-52.80,1.00,0.00,1.00 +658,-76.80,-52.80,1.00,0.00,1.00 +659,-67.20,-48.00,1.00,0.00,1.00 +660,-62.40,-48.00,1.00,0.00,1.00 +661,-57.60,-48.00,1.00,0.00,1.00 +662,-48.00,-43.20,1.00,0.00,1.00 +663,-43.20,-43.20,1.00,0.00,1.00 +664,-38.40,-38.40,1.00,0.00,1.00 +665,-33.60,-33.60,1.00,0.00,1.00 +666,-28.80,-33.60,1.00,0.00,1.00 +667,-24.00,-28.80,1.00,0.00,1.00 +668,-24.00,-24.00,1.00,0.00,1.00 +669,-19.20,-24.00,1.00,0.00,1.00 +670,-14.40,-19.20,1.00,0.00,1.00 +671,-14.40,-14.40,1.00,0.00,1.00 +672,-9.60,-9.60,1.00,0.00,1.00 +673,-4.80,-9.60,1.00,0.00,1.00 +674,-4.80,-4.80,1.00,0.00,1.00 +675,0.00,0.00,1.00,0.00,1.00 +676,4.80,4.80,1.00,0.00,1.00 +677,4.80,4.80,1.00,0.00,1.00 +678,9.60,9.60,1.00,0.00,1.00 +679,14.40,14.40,1.00,0.00,1.00 +680,19.20,19.20,1.00,0.00,1.00 +681,19.20,19.20,1.00,0.00,1.00 +682,24.00,24.00,1.00,0.00,1.00 +683,28.80,28.80,1.00,0.00,1.00 +684,33.60,28.80,1.00,0.00,1.00 +685,38.40,33.60,1.00,0.00,1.00 +686,43.20,33.60,1.00,0.00,1.00 +687,48.00,38.40,1.00,0.00,1.00 +688,52.80,38.40,1.00,0.00,1.00 +689,57.60,43.20,1.00,0.00,1.00 +690,62.40,43.20,1.00,0.00,1.00 +691,72.00,43.20,1.00,0.00,1.00 +692,76.80,48.00,1.00,0.00,1.00 +693,86.40,48.00,1.00,0.00,1.00 +694,91.20,48.00,1.00,0.00,1.00 +695,100.80,48.00,1.00,0.00,1.00 +696,105.60,48.00,1.00,0.00,1.00 +697,110.40,43.20,1.00,0.00,1.00 +698,120.00,43.20,1.00,0.00,1.00 +699,124.80,43.20,1.00,0.00,1.00 +700,129.60,38.40,1.00,0.00,1.00 +701,134.40,38.40,1.00,0.00,1.00 +702,139.20,33.60,1.00,0.00,1.00 +703,144.00,33.60,1.00,0.00,1.00 +704,148.80,28.80,1.00,0.00,1.00 +705,153.60,24.00,1.00,0.00,1.00 +706,158.40,24.00,1.00,0.00,1.00 +707,163.20,19.20,1.00,0.00,1.00 +708,163.20,14.40,1.00,0.00,1.00 +709,168.00,14.40,1.00,0.00,1.00 +710,172.80,9.60,1.00,0.00,1.00 +711,172.80,4.80,1.00,0.00,1.00 +712,177.60,0.00,1.00,0.00,1.00 +713,-177.60,-0.00,1.00,0.00,1.00 +714,-172.80,-4.80,1.00,0.00,1.00 +715,-172.80,-9.60,1.00,0.00,1.00 +716,-168.00,-14.40,1.00,0.00,1.00 +717,-163.20,-14.40,1.00,0.00,1.00 +718,-163.20,-19.20,1.00,0.00,1.00 +719,-158.40,-24.00,1.00,0.00,1.00 +720,-153.60,-24.00,1.00,0.00,1.00 +721,-148.80,-28.80,1.00,0.00,1.00 +722,-144.00,-33.60,1.00,0.00,1.00 +723,-139.20,-33.60,1.00,0.00,1.00 +724,-134.40,-38.40,1.00,0.00,1.00 +725,-129.60,-38.40,1.00,0.00,1.00 +726,-124.80,-43.20,1.00,0.00,1.00 +727,-120.00,-43.20,1.00,0.00,1.00 +728,-110.40,-43.20,1.00,0.00,1.00 +729,-105.60,-48.00,1.00,0.00,1.00 +730,-100.80,-48.00,1.00,0.00,1.00 +731,-91.20,-48.00,1.00,0.00,1.00 +732,-86.40,-48.00,1.00,0.00,1.00 +733,-76.80,-48.00,1.00,0.00,1.00 +734,-72.00,-43.20,1.00,0.00,1.00 +735,-62.40,-43.20,1.00,0.00,1.00 +736,-57.60,-43.20,1.00,0.00,1.00 +737,-52.80,-38.40,1.00,0.00,1.00 +738,-48.00,-38.40,1.00,0.00,1.00 +739,-43.20,-33.60,1.00,0.00,1.00 +740,-38.40,-33.60,1.00,0.00,1.00 +741,-33.60,-28.80,1.00,0.00,1.00 +742,-28.80,-28.80,1.00,0.00,1.00 +743,-24.00,-24.00,1.00,0.00,1.00 +744,-19.20,-19.20,1.00,0.00,1.00 +745,-19.20,-19.20,1.00,0.00,1.00 +746,-14.40,-14.40,1.00,0.00,1.00 +747,-9.60,-9.60,1.00,0.00,1.00 +748,-4.80,-4.80,1.00,0.00,1.00 +749,-4.80,-4.80,1.00,0.00,1.00 +750,0.00,0.00,1.00,0.00,1.00 +751,4.80,4.80,1.00,0.00,1.00 +752,4.80,4.80,1.00,0.00,1.00 +753,9.60,9.60,1.00,0.00,1.00 +754,14.40,14.40,1.00,0.00,1.00 +755,19.20,14.40,1.00,0.00,1.00 +756,24.00,19.20,1.00,0.00,1.00 +757,24.00,24.00,1.00,0.00,1.00 +758,28.80,24.00,1.00,0.00,1.00 +759,33.60,28.80,1.00,0.00,1.00 +760,38.40,28.80,1.00,0.00,1.00 +761,43.20,33.60,1.00,0.00,1.00 +762,48.00,33.60,1.00,0.00,1.00 +763,52.80,38.40,1.00,0.00,1.00 +764,62.40,38.40,1.00,0.00,1.00 +765,67.20,38.40,1.00,0.00,1.00 +766,72.00,38.40,1.00,0.00,1.00 +767,76.80,43.20,1.00,0.00,1.00 +768,86.40,43.20,1.00,0.00,1.00 +769,91.20,43.20,1.00,0.00,1.00 +770,96.00,43.20,1.00,0.00,1.00 +771,105.60,43.20,1.00,0.00,1.00 +772,110.40,38.40,1.00,0.00,1.00 +773,115.20,38.40,1.00,0.00,1.00 +774,120.00,38.40,1.00,0.00,1.00 +775,129.60,33.60,1.00,0.00,1.00 +776,134.40,33.60,1.00,0.00,1.00 +777,139.20,28.80,1.00,0.00,1.00 +778,144.00,28.80,1.00,0.00,1.00 +779,148.80,24.00,1.00,0.00,1.00 +780,153.60,24.00,1.00,0.00,1.00 +781,153.60,19.20,1.00,0.00,1.00 +782,158.40,19.20,1.00,0.00,1.00 +783,163.20,14.40,1.00,0.00,1.00 +784,168.00,9.60,1.00,0.00,1.00 +785,172.80,9.60,1.00,0.00,1.00 +786,172.80,4.80,1.00,0.00,1.00 +787,177.60,0.00,1.00,0.00,1.00 +788,-177.60,-0.00,1.00,0.00,1.00 +789,-172.80,-4.80,1.00,0.00,1.00 +790,-172.80,-9.60,1.00,0.00,1.00 +791,-168.00,-9.60,1.00,0.00,1.00 +792,-163.20,-14.40,1.00,0.00,1.00 +793,-158.40,-19.20,1.00,0.00,1.00 +794,-153.60,-19.20,1.00,0.00,1.00 +795,-153.60,-24.00,1.00,0.00,1.00 +796,-148.80,-24.00,1.00,0.00,1.00 +797,-144.00,-28.80,1.00,0.00,1.00 +798,-139.20,-28.80,1.00,0.00,1.00 +799,-134.40,-33.60,1.00,0.00,1.00 +800,-129.60,-33.60,1.00,0.00,1.00 +801,-120.00,-38.40,1.00,0.00,1.00 +802,-115.20,-38.40,1.00,0.00,1.00 +803,-110.40,-38.40,1.00,0.00,1.00 +804,-105.60,-43.20,1.00,0.00,1.00 +805,-96.00,-43.20,1.00,0.00,1.00 +806,-91.20,-43.20,1.00,0.00,1.00 +807,-86.40,-43.20,1.00,0.00,1.00 +808,-76.80,-43.20,1.00,0.00,1.00 +809,-72.00,-38.40,1.00,0.00,1.00 +810,-67.20,-38.40,1.00,0.00,1.00 +811,-62.40,-38.40,1.00,0.00,1.00 +812,-52.80,-38.40,1.00,0.00,1.00 +813,-48.00,-33.60,1.00,0.00,1.00 +814,-43.20,-33.60,1.00,0.00,1.00 +815,-38.40,-28.80,1.00,0.00,1.00 +816,-33.60,-28.80,1.00,0.00,1.00 +817,-28.80,-24.00,1.00,0.00,1.00 +818,-24.00,-24.00,1.00,0.00,1.00 +819,-24.00,-19.20,1.00,0.00,1.00 +820,-19.20,-14.40,1.00,0.00,1.00 +821,-14.40,-14.40,1.00,0.00,1.00 +822,-9.60,-9.60,1.00,0.00,1.00 +823,-4.80,-4.80,1.00,0.00,1.00 +824,-4.80,-4.80,1.00,0.00,1.00 +825,0.00,0.00,1.00,0.00,1.00 +826,4.80,4.80,1.00,0.00,1.00 +827,9.60,4.80,1.00,0.00,1.00 +828,9.60,9.60,1.00,0.00,1.00 +829,14.40,9.60,1.00,0.00,1.00 +830,19.20,14.40,1.00,0.00,1.00 +831,24.00,19.20,1.00,0.00,1.00 +832,28.80,19.20,1.00,0.00,1.00 +833,33.60,24.00,1.00,0.00,1.00 +834,38.40,24.00,1.00,0.00,1.00 +835,43.20,28.80,1.00,0.00,1.00 +836,48.00,28.80,1.00,0.00,1.00 +837,52.80,28.80,1.00,0.00,1.00 +838,57.60,33.60,1.00,0.00,1.00 +839,62.40,33.60,1.00,0.00,1.00 +840,67.20,33.60,1.00,0.00,1.00 +841,72.00,38.40,1.00,0.00,1.00 +842,81.60,38.40,1.00,0.00,1.00 +843,86.40,38.40,1.00,0.00,1.00 +844,91.20,38.40,1.00,0.00,1.00 +845,96.00,38.40,1.00,0.00,1.00 +846,105.60,38.40,1.00,0.00,1.00 +847,110.40,33.60,1.00,0.00,1.00 +848,115.20,33.60,1.00,0.00,1.00 +849,120.00,33.60,1.00,0.00,1.00 +850,124.80,33.60,1.00,0.00,1.00 +851,129.60,28.80,1.00,0.00,1.00 +852,134.40,28.80,1.00,0.00,1.00 +853,139.20,24.00,1.00,0.00,1.00 +854,144.00,24.00,1.00,0.00,1.00 +855,148.80,19.20,1.00,0.00,1.00 +856,153.60,19.20,1.00,0.00,1.00 +857,158.40,14.40,1.00,0.00,1.00 +858,163.20,14.40,1.00,0.00,1.00 +859,168.00,9.60,1.00,0.00,1.00 +860,168.00,9.60,1.00,0.00,1.00 +861,172.80,4.80,1.00,0.00,1.00 +862,177.60,0.00,1.00,0.00,1.00 +863,-177.60,-0.00,1.00,0.00,1.00 +864,-172.80,-4.80,1.00,0.00,1.00 +865,-168.00,-9.60,1.00,0.00,1.00 +866,-168.00,-9.60,1.00,0.00,1.00 +867,-163.20,-14.40,1.00,0.00,1.00 +868,-158.40,-14.40,1.00,0.00,1.00 +869,-153.60,-19.20,1.00,0.00,1.00 +870,-148.80,-19.20,1.00,0.00,1.00 +871,-144.00,-24.00,1.00,0.00,1.00 +872,-139.20,-24.00,1.00,0.00,1.00 +873,-134.40,-28.80,1.00,0.00,1.00 +874,-129.60,-28.80,1.00,0.00,1.00 +875,-124.80,-33.60,1.00,0.00,1.00 +876,-120.00,-33.60,1.00,0.00,1.00 +877,-115.20,-33.60,1.00,0.00,1.00 +878,-110.40,-33.60,1.00,0.00,1.00 +879,-105.60,-38.40,1.00,0.00,1.00 +880,-96.00,-38.40,1.00,0.00,1.00 +881,-91.20,-38.40,1.00,0.00,1.00 +882,-86.40,-38.40,1.00,0.00,1.00 +883,-81.60,-38.40,1.00,0.00,1.00 +884,-72.00,-38.40,1.00,0.00,1.00 +885,-67.20,-33.60,1.00,0.00,1.00 +886,-62.40,-33.60,1.00,0.00,1.00 +887,-57.60,-33.60,1.00,0.00,1.00 +888,-52.80,-28.80,1.00,0.00,1.00 +889,-48.00,-28.80,1.00,0.00,1.00 +890,-43.20,-28.80,1.00,0.00,1.00 +891,-38.40,-24.00,1.00,0.00,1.00 +892,-33.60,-24.00,1.00,0.00,1.00 +893,-28.80,-19.20,1.00,0.00,1.00 +894,-24.00,-19.20,1.00,0.00,1.00 +895,-19.20,-14.40,1.00,0.00,1.00 +896,-14.40,-9.60,1.00,0.00,1.00 +897,-9.60,-9.60,1.00,0.00,1.00 +898,-9.60,-4.80,1.00,0.00,1.00 +899,-4.80,-4.80,1.00,0.00,1.00 +900,0.00,0.00,1.00,0.00,1.00 +901,4.80,4.80,1.00,0.00,1.00 +902,9.60,4.80,1.00,0.00,1.00 +903,14.40,9.60,1.00,0.00,1.00 +904,14.40,9.60,1.00,0.00,1.00 +905,19.20,14.40,1.00,0.00,1.00 +906,24.00,14.40,1.00,0.00,1.00 +907,28.80,19.20,1.00,0.00,1.00 +908,33.60,19.20,1.00,0.00,1.00 +909,38.40,19.20,1.00,0.00,1.00 +910,43.20,24.00,1.00,0.00,1.00 +911,48.00,24.00,1.00,0.00,1.00 +912,52.80,28.80,1.00,0.00,1.00 +913,57.60,28.80,1.00,0.00,1.00 +914,62.40,28.80,1.00,0.00,1.00 +915,67.20,28.80,1.00,0.00,1.00 +916,76.80,33.60,1.00,0.00,1.00 +917,81.60,33.60,1.00,0.00,1.00 +918,86.40,33.60,1.00,0.00,1.00 +919,91.20,33.60,1.00,0.00,1.00 +920,96.00,33.60,1.00,0.00,1.00 +921,100.80,33.60,1.00,0.00,1.00 +922,110.40,28.80,1.00,0.00,1.00 +923,115.20,28.80,1.00,0.00,1.00 +924,120.00,28.80,1.00,0.00,1.00 +925,124.80,28.80,1.00,0.00,1.00 +926,129.60,24.00,1.00,0.00,1.00 +927,134.40,24.00,1.00,0.00,1.00 +928,139.20,24.00,1.00,0.00,1.00 +929,144.00,19.20,1.00,0.00,1.00 +930,148.80,19.20,1.00,0.00,1.00 +931,153.60,14.40,1.00,0.00,1.00 +932,158.40,14.40,1.00,0.00,1.00 +933,163.20,9.60,1.00,0.00,1.00 +934,168.00,9.60,1.00,0.00,1.00 +935,168.00,4.80,1.00,0.00,1.00 +936,172.80,4.80,1.00,0.00,1.00 +937,177.60,0.00,1.00,0.00,1.00 +938,-177.60,-0.00,1.00,0.00,1.00 +939,-172.80,-4.80,1.00,0.00,1.00 +940,-168.00,-4.80,1.00,0.00,1.00 +941,-168.00,-9.60,1.00,0.00,1.00 +942,-163.20,-9.60,1.00,0.00,1.00 +943,-158.40,-14.40,1.00,0.00,1.00 +944,-153.60,-14.40,1.00,0.00,1.00 +945,-148.80,-19.20,1.00,0.00,1.00 +946,-144.00,-19.20,1.00,0.00,1.00 +947,-139.20,-24.00,1.00,0.00,1.00 +948,-134.40,-24.00,1.00,0.00,1.00 +949,-129.60,-24.00,1.00,0.00,1.00 +950,-124.80,-28.80,1.00,0.00,1.00 +951,-120.00,-28.80,1.00,0.00,1.00 +952,-115.20,-28.80,1.00,0.00,1.00 +953,-110.40,-28.80,1.00,0.00,1.00 +954,-100.80,-33.60,1.00,0.00,1.00 +955,-96.00,-33.60,1.00,0.00,1.00 +956,-91.20,-33.60,1.00,0.00,1.00 +957,-86.40,-33.60,1.00,0.00,1.00 +958,-81.60,-33.60,1.00,0.00,1.00 +959,-76.80,-33.60,1.00,0.00,1.00 +960,-67.20,-28.80,1.00,0.00,1.00 +961,-62.40,-28.80,1.00,0.00,1.00 +962,-57.60,-28.80,1.00,0.00,1.00 +963,-52.80,-28.80,1.00,0.00,1.00 +964,-48.00,-24.00,1.00,0.00,1.00 +965,-43.20,-24.00,1.00,0.00,1.00 +966,-38.40,-19.20,1.00,0.00,1.00 +967,-33.60,-19.20,1.00,0.00,1.00 +968,-28.80,-19.20,1.00,0.00,1.00 +969,-24.00,-14.40,1.00,0.00,1.00 +970,-19.20,-14.40,1.00,0.00,1.00 +971,-14.40,-9.60,1.00,0.00,1.00 +972,-14.40,-9.60,1.00,0.00,1.00 +973,-9.60,-4.80,1.00,0.00,1.00 +974,-4.80,-4.80,1.00,0.00,1.00 +975,0.00,0.00,1.00,0.00,1.00 +976,4.80,0.00,1.00,0.00,1.00 +977,9.60,4.80,1.00,0.00,1.00 +978,14.40,4.80,1.00,0.00,1.00 +979,19.20,9.60,1.00,0.00,1.00 +980,19.20,9.60,1.00,0.00,1.00 +981,24.00,14.40,1.00,0.00,1.00 +982,28.80,14.40,1.00,0.00,1.00 +983,33.60,14.40,1.00,0.00,1.00 +984,38.40,19.20,1.00,0.00,1.00 +985,43.20,19.20,1.00,0.00,1.00 +986,48.00,24.00,1.00,0.00,1.00 +987,52.80,24.00,1.00,0.00,1.00 +988,57.60,24.00,1.00,0.00,1.00 +989,62.40,24.00,1.00,0.00,1.00 +990,72.00,24.00,1.00,0.00,1.00 +991,76.80,28.80,1.00,0.00,1.00 +992,81.60,28.80,1.00,0.00,1.00 +993,86.40,28.80,1.00,0.00,1.00 +994,91.20,28.80,1.00,0.00,1.00 +995,96.00,28.80,1.00,0.00,1.00 +996,100.80,28.80,1.00,0.00,1.00 +997,105.60,28.80,1.00,0.00,1.00 +998,110.40,24.00,1.00,0.00,1.00 +999,120.00,24.00,1.00,0.00,1.00 +1000,124.80,24.00,1.00,0.00,1.00 +1001,129.60,24.00,1.00,0.00,1.00 +1002,134.40,19.20,1.00,0.00,1.00 +1003,139.20,19.20,1.00,0.00,1.00 +1004,144.00,19.20,1.00,0.00,1.00 +1005,148.80,14.40,1.00,0.00,1.00 +1006,153.60,14.40,1.00,0.00,1.00 +1007,158.40,9.60,1.00,0.00,1.00 +1008,158.40,9.60,1.00,0.00,1.00 +1009,163.20,9.60,1.00,0.00,1.00 +1010,168.00,4.80,1.00,0.00,1.00 +1011,172.80,4.80,1.00,0.00,1.00 +1012,177.60,0.00,1.00,0.00,1.00 +1013,-177.60,-0.00,1.00,0.00,1.00 +1014,-172.80,-4.80,1.00,0.00,1.00 +1015,-168.00,-4.80,1.00,0.00,1.00 +1016,-163.20,-9.60,1.00,0.00,1.00 +1017,-158.40,-9.60,1.00,0.00,1.00 +1018,-158.40,-9.60,1.00,0.00,1.00 +1019,-153.60,-14.40,1.00,0.00,1.00 +1020,-148.80,-14.40,1.00,0.00,1.00 +1021,-144.00,-19.20,1.00,0.00,1.00 +1022,-139.20,-19.20,1.00,0.00,1.00 +1023,-134.40,-19.20,1.00,0.00,1.00 +1024,-129.60,-24.00,1.00,0.00,1.00 +1025,-124.80,-24.00,1.00,0.00,1.00 +1026,-120.00,-24.00,1.00,0.00,1.00 +1027,-110.40,-24.00,1.00,0.00,1.00 +1028,-105.60,-28.80,1.00,0.00,1.00 +1029,-100.80,-28.80,1.00,0.00,1.00 +1030,-96.00,-28.80,1.00,0.00,1.00 +1031,-91.20,-28.80,1.00,0.00,1.00 +1032,-86.40,-28.80,1.00,0.00,1.00 +1033,-81.60,-28.80,1.00,0.00,1.00 +1034,-76.80,-28.80,1.00,0.00,1.00 +1035,-72.00,-24.00,1.00,0.00,1.00 +1036,-62.40,-24.00,1.00,0.00,1.00 +1037,-57.60,-24.00,1.00,0.00,1.00 +1038,-52.80,-24.00,1.00,0.00,1.00 +1039,-48.00,-24.00,1.00,0.00,1.00 +1040,-43.20,-19.20,1.00,0.00,1.00 +1041,-38.40,-19.20,1.00,0.00,1.00 +1042,-33.60,-14.40,1.00,0.00,1.00 +1043,-28.80,-14.40,1.00,0.00,1.00 +1044,-24.00,-14.40,1.00,0.00,1.00 +1045,-19.20,-9.60,1.00,0.00,1.00 +1046,-19.20,-9.60,1.00,0.00,1.00 +1047,-14.40,-4.80,1.00,0.00,1.00 +1048,-9.60,-4.80,1.00,0.00,1.00 +1049,-4.80,-0.00,1.00,0.00,1.00 +1050,0.00,0.00,1.00,0.00,1.00 +1051,4.80,0.00,1.00,0.00,1.00 +1052,9.60,4.80,1.00,0.00,1.00 +1053,14.40,4.80,1.00,0.00,1.00 +1054,19.20,9.60,1.00,0.00,1.00 +1055,24.00,9.60,1.00,0.00,1.00 +1056,28.80,9.60,1.00,0.00,1.00 +1057,33.60,14.40,1.00,0.00,1.00 +1058,38.40,14.40,1.00,0.00,1.00 +1059,43.20,14.40,1.00,0.00,1.00 +1060,48.00,14.40,1.00,0.00,1.00 +1061,52.80,19.20,1.00,0.00,1.00 +1062,57.60,19.20,1.00,0.00,1.00 +1063,62.40,19.20,1.00,0.00,1.00 +1064,67.20,19.20,1.00,0.00,1.00 +1065,72.00,24.00,1.00,0.00,1.00 +1066,76.80,24.00,1.00,0.00,1.00 +1067,81.60,24.00,1.00,0.00,1.00 +1068,86.40,24.00,1.00,0.00,1.00 +1069,91.20,24.00,1.00,0.00,1.00 +1070,96.00,24.00,1.00,0.00,1.00 +1071,100.80,24.00,1.00,0.00,1.00 +1072,105.60,24.00,1.00,0.00,1.00 +1073,110.40,19.20,1.00,0.00,1.00 +1074,115.20,19.20,1.00,0.00,1.00 +1075,120.00,19.20,1.00,0.00,1.00 +1076,124.80,19.20,1.00,0.00,1.00 +1077,129.60,19.20,1.00,0.00,1.00 +1078,134.40,14.40,1.00,0.00,1.00 +1079,139.20,14.40,1.00,0.00,1.00 +1080,144.00,14.40,1.00,0.00,1.00 +1081,148.80,9.60,1.00,0.00,1.00 +1082,153.60,9.60,1.00,0.00,1.00 +1083,158.40,9.60,1.00,0.00,1.00 +1084,163.20,4.80,1.00,0.00,1.00 +1085,168.00,4.80,1.00,0.00,1.00 +1086,172.80,4.80,1.00,0.00,1.00 +1087,177.60,0.00,1.00,0.00,1.00 +1088,-177.60,-0.00,1.00,0.00,1.00 +1089,-172.80,-4.80,1.00,0.00,1.00 +1090,-168.00,-4.80,1.00,0.00,1.00 +1091,-163.20,-4.80,1.00,0.00,1.00 +1092,-158.40,-9.60,1.00,0.00,1.00 +1093,-153.60,-9.60,1.00,0.00,1.00 +1094,-148.80,-9.60,1.00,0.00,1.00 +1095,-144.00,-14.40,1.00,0.00,1.00 +1096,-139.20,-14.40,1.00,0.00,1.00 +1097,-134.40,-14.40,1.00,0.00,1.00 +1098,-129.60,-19.20,1.00,0.00,1.00 +1099,-124.80,-19.20,1.00,0.00,1.00 +1100,-120.00,-19.20,1.00,0.00,1.00 +1101,-115.20,-19.20,1.00,0.00,1.00 +1102,-110.40,-19.20,1.00,0.00,1.00 +1103,-105.60,-24.00,1.00,0.00,1.00 +1104,-100.80,-24.00,1.00,0.00,1.00 +1105,-96.00,-24.00,1.00,0.00,1.00 +1106,-91.20,-24.00,1.00,0.00,1.00 +1107,-86.40,-24.00,1.00,0.00,1.00 +1108,-81.60,-24.00,1.00,0.00,1.00 +1109,-76.80,-24.00,1.00,0.00,1.00 +1110,-72.00,-24.00,1.00,0.00,1.00 +1111,-67.20,-19.20,1.00,0.00,1.00 +1112,-62.40,-19.20,1.00,0.00,1.00 +1113,-57.60,-19.20,1.00,0.00,1.00 +1114,-52.80,-19.20,1.00,0.00,1.00 +1115,-48.00,-14.40,1.00,0.00,1.00 +1116,-43.20,-14.40,1.00,0.00,1.00 +1117,-38.40,-14.40,1.00,0.00,1.00 +1118,-33.60,-14.40,1.00,0.00,1.00 +1119,-28.80,-9.60,1.00,0.00,1.00 +1120,-24.00,-9.60,1.00,0.00,1.00 +1121,-19.20,-9.60,1.00,0.00,1.00 +1122,-14.40,-4.80,1.00,0.00,1.00 +1123,-9.60,-4.80,1.00,0.00,1.00 +1124,-4.80,-0.00,1.00,0.00,1.00 +1125,0.00,0.00,1.00,0.00,1.00 +1126,4.80,0.00,1.00,0.00,1.00 +1127,9.60,4.80,1.00,0.00,1.00 +1128,14.40,4.80,1.00,0.00,1.00 +1129,19.20,4.80,1.00,0.00,1.00 +1130,24.00,9.60,1.00,0.00,1.00 +1131,28.80,9.60,1.00,0.00,1.00 +1132,33.60,9.60,1.00,0.00,1.00 +1133,38.40,9.60,1.00,0.00,1.00 +1134,43.20,14.40,1.00,0.00,1.00 +1135,48.00,14.40,1.00,0.00,1.00 +1136,52.80,14.40,1.00,0.00,1.00 +1137,57.60,14.40,1.00,0.00,1.00 +1138,62.40,14.40,1.00,0.00,1.00 +1139,67.20,14.40,1.00,0.00,1.00 +1140,72.00,19.20,1.00,0.00,1.00 +1141,76.80,19.20,1.00,0.00,1.00 +1142,81.60,19.20,1.00,0.00,1.00 +1143,86.40,19.20,1.00,0.00,1.00 +1144,91.20,19.20,1.00,0.00,1.00 +1145,96.00,19.20,1.00,0.00,1.00 +1146,100.80,19.20,1.00,0.00,1.00 +1147,105.60,19.20,1.00,0.00,1.00 +1148,110.40,19.20,1.00,0.00,1.00 +1149,115.20,14.40,1.00,0.00,1.00 +1150,120.00,14.40,1.00,0.00,1.00 +1151,124.80,14.40,1.00,0.00,1.00 +1152,129.60,14.40,1.00,0.00,1.00 +1153,134.40,14.40,1.00,0.00,1.00 +1154,139.20,9.60,1.00,0.00,1.00 +1155,144.00,9.60,1.00,0.00,1.00 +1156,148.80,9.60,1.00,0.00,1.00 +1157,153.60,9.60,1.00,0.00,1.00 +1158,158.40,4.80,1.00,0.00,1.00 +1159,163.20,4.80,1.00,0.00,1.00 +1160,168.00,4.80,1.00,0.00,1.00 +1161,172.80,0.00,1.00,0.00,1.00 +1162,177.60,0.00,1.00,0.00,1.00 +1163,-177.60,-0.00,1.00,0.00,1.00 +1164,-172.80,-0.00,1.00,0.00,1.00 +1165,-168.00,-4.80,1.00,0.00,1.00 +1166,-163.20,-4.80,1.00,0.00,1.00 +1167,-158.40,-4.80,1.00,0.00,1.00 +1168,-153.60,-9.60,1.00,0.00,1.00 +1169,-148.80,-9.60,1.00,0.00,1.00 +1170,-144.00,-9.60,1.00,0.00,1.00 +1171,-139.20,-9.60,1.00,0.00,1.00 +1172,-134.40,-14.40,1.00,0.00,1.00 +1173,-129.60,-14.40,1.00,0.00,1.00 +1174,-124.80,-14.40,1.00,0.00,1.00 +1175,-120.00,-14.40,1.00,0.00,1.00 +1176,-115.20,-14.40,1.00,0.00,1.00 +1177,-110.40,-19.20,1.00,0.00,1.00 +1178,-105.60,-19.20,1.00,0.00,1.00 +1179,-100.80,-19.20,1.00,0.00,1.00 +1180,-96.00,-19.20,1.00,0.00,1.00 +1181,-91.20,-19.20,1.00,0.00,1.00 +1182,-86.40,-19.20,1.00,0.00,1.00 +1183,-81.60,-19.20,1.00,0.00,1.00 +1184,-76.80,-19.20,1.00,0.00,1.00 +1185,-72.00,-19.20,1.00,0.00,1.00 +1186,-67.20,-14.40,1.00,0.00,1.00 +1187,-62.40,-14.40,1.00,0.00,1.00 +1188,-57.60,-14.40,1.00,0.00,1.00 +1189,-52.80,-14.40,1.00,0.00,1.00 +1190,-48.00,-14.40,1.00,0.00,1.00 +1191,-43.20,-14.40,1.00,0.00,1.00 +1192,-38.40,-9.60,1.00,0.00,1.00 +1193,-33.60,-9.60,1.00,0.00,1.00 +1194,-28.80,-9.60,1.00,0.00,1.00 +1195,-24.00,-9.60,1.00,0.00,1.00 +1196,-19.20,-4.80,1.00,0.00,1.00 +1197,-14.40,-4.80,1.00,0.00,1.00 +1198,-9.60,-4.80,1.00,0.00,1.00 +1199,-4.80,-0.00,1.00,0.00,1.00 +1200,0.00,0.00,1.00,0.00,1.00 +1201,4.80,0.00,1.00,0.00,1.00 +1202,9.60,0.00,1.00,0.00,1.00 +1203,14.40,4.80,1.00,0.00,1.00 +1204,19.20,4.80,1.00,0.00,1.00 +1205,24.00,4.80,1.00,0.00,1.00 +1206,28.80,4.80,1.00,0.00,1.00 +1207,33.60,9.60,1.00,0.00,1.00 +1208,38.40,9.60,1.00,0.00,1.00 +1209,43.20,9.60,1.00,0.00,1.00 +1210,48.00,9.60,1.00,0.00,1.00 +1211,52.80,9.60,1.00,0.00,1.00 +1212,57.60,9.60,1.00,0.00,1.00 +1213,62.40,9.60,1.00,0.00,1.00 +1214,67.20,14.40,1.00,0.00,1.00 +1215,72.00,14.40,1.00,0.00,1.00 +1216,76.80,14.40,1.00,0.00,1.00 +1217,81.60,14.40,1.00,0.00,1.00 +1218,86.40,14.40,1.00,0.00,1.00 +1219,91.20,14.40,1.00,0.00,1.00 +1220,96.00,14.40,1.00,0.00,1.00 +1221,100.80,14.40,1.00,0.00,1.00 +1222,105.60,14.40,1.00,0.00,1.00 +1223,110.40,14.40,1.00,0.00,1.00 +1224,115.20,9.60,1.00,0.00,1.00 +1225,120.00,9.60,1.00,0.00,1.00 +1226,124.80,9.60,1.00,0.00,1.00 +1227,129.60,9.60,1.00,0.00,1.00 +1228,134.40,9.60,1.00,0.00,1.00 +1229,139.20,9.60,1.00,0.00,1.00 +1230,144.00,9.60,1.00,0.00,1.00 +1231,148.80,4.80,1.00,0.00,1.00 +1232,153.60,4.80,1.00,0.00,1.00 +1233,158.40,4.80,1.00,0.00,1.00 +1234,163.20,4.80,1.00,0.00,1.00 +1235,168.00,4.80,1.00,0.00,1.00 +1236,172.80,0.00,1.00,0.00,1.00 +1237,177.60,0.00,1.00,0.00,1.00 +1238,-177.60,-0.00,1.00,0.00,1.00 +1239,-172.80,-0.00,1.00,0.00,1.00 +1240,-168.00,-4.80,1.00,0.00,1.00 +1241,-163.20,-4.80,1.00,0.00,1.00 +1242,-158.40,-4.80,1.00,0.00,1.00 +1243,-153.60,-4.80,1.00,0.00,1.00 +1244,-148.80,-4.80,1.00,0.00,1.00 +1245,-144.00,-9.60,1.00,0.00,1.00 +1246,-139.20,-9.60,1.00,0.00,1.00 +1247,-134.40,-9.60,1.00,0.00,1.00 +1248,-129.60,-9.60,1.00,0.00,1.00 +1249,-124.80,-9.60,1.00,0.00,1.00 +1250,-120.00,-9.60,1.00,0.00,1.00 +1251,-115.20,-9.60,1.00,0.00,1.00 +1252,-110.40,-14.40,1.00,0.00,1.00 +1253,-105.60,-14.40,1.00,0.00,1.00 +1254,-100.80,-14.40,1.00,0.00,1.00 +1255,-96.00,-14.40,1.00,0.00,1.00 +1256,-91.20,-14.40,1.00,0.00,1.00 +1257,-86.40,-14.40,1.00,0.00,1.00 +1258,-81.60,-14.40,1.00,0.00,1.00 +1259,-76.80,-14.40,1.00,0.00,1.00 +1260,-72.00,-14.40,1.00,0.00,1.00 +1261,-67.20,-14.40,1.00,0.00,1.00 +1262,-62.40,-9.60,1.00,0.00,1.00 +1263,-57.60,-9.60,1.00,0.00,1.00 +1264,-52.80,-9.60,1.00,0.00,1.00 +1265,-48.00,-9.60,1.00,0.00,1.00 +1266,-43.20,-9.60,1.00,0.00,1.00 +1267,-38.40,-9.60,1.00,0.00,1.00 +1268,-33.60,-9.60,1.00,0.00,1.00 +1269,-28.80,-4.80,1.00,0.00,1.00 +1270,-24.00,-4.80,1.00,0.00,1.00 +1271,-19.20,-4.80,1.00,0.00,1.00 +1272,-14.40,-4.80,1.00,0.00,1.00 +1273,-9.60,-0.00,1.00,0.00,1.00 +1274,-4.80,-0.00,1.00,0.00,1.00 +1275,0.00,0.00,1.00,0.00,1.00 +1276,4.80,0.00,1.00,0.00,1.00 +1277,9.60,0.00,1.00,0.00,1.00 +1278,14.40,0.00,1.00,0.00,1.00 +1279,19.20,4.80,1.00,0.00,1.00 +1280,24.00,4.80,1.00,0.00,1.00 +1281,28.80,4.80,1.00,0.00,1.00 +1282,33.60,4.80,1.00,0.00,1.00 +1283,38.40,4.80,1.00,0.00,1.00 +1284,43.20,4.80,1.00,0.00,1.00 +1285,48.00,4.80,1.00,0.00,1.00 +1286,52.80,4.80,1.00,0.00,1.00 +1287,57.60,4.80,1.00,0.00,1.00 +1288,62.40,9.60,1.00,0.00,1.00 +1289,67.20,9.60,1.00,0.00,1.00 +1290,72.00,9.60,1.00,0.00,1.00 +1291,76.80,9.60,1.00,0.00,1.00 +1292,81.60,9.60,1.00,0.00,1.00 +1293,86.40,9.60,1.00,0.00,1.00 +1294,91.20,9.60,1.00,0.00,1.00 +1295,96.00,9.60,1.00,0.00,1.00 +1296,100.80,9.60,1.00,0.00,1.00 +1297,105.60,9.60,1.00,0.00,1.00 +1298,110.40,9.60,1.00,0.00,1.00 +1299,115.20,9.60,1.00,0.00,1.00 +1300,120.00,9.60,1.00,0.00,1.00 +1301,124.80,4.80,1.00,0.00,1.00 +1302,129.60,4.80,1.00,0.00,1.00 +1303,134.40,4.80,1.00,0.00,1.00 +1304,139.20,4.80,1.00,0.00,1.00 +1305,144.00,4.80,1.00,0.00,1.00 +1306,148.80,4.80,1.00,0.00,1.00 +1307,153.60,4.80,1.00,0.00,1.00 +1308,158.40,4.80,1.00,0.00,1.00 +1309,163.20,4.80,1.00,0.00,1.00 +1310,168.00,0.00,1.00,0.00,1.00 +1311,172.80,0.00,1.00,0.00,1.00 +1312,177.60,0.00,1.00,0.00,1.00 +1313,-177.60,-0.00,1.00,0.00,1.00 +1314,-172.80,-0.00,1.00,0.00,1.00 +1315,-168.00,-0.00,1.00,0.00,1.00 +1316,-163.20,-4.80,1.00,0.00,1.00 +1317,-158.40,-4.80,1.00,0.00,1.00 +1318,-153.60,-4.80,1.00,0.00,1.00 +1319,-148.80,-4.80,1.00,0.00,1.00 +1320,-144.00,-4.80,1.00,0.00,1.00 +1321,-139.20,-4.80,1.00,0.00,1.00 +1322,-134.40,-4.80,1.00,0.00,1.00 +1323,-129.60,-4.80,1.00,0.00,1.00 +1324,-124.80,-4.80,1.00,0.00,1.00 +1325,-120.00,-9.60,1.00,0.00,1.00 +1326,-115.20,-9.60,1.00,0.00,1.00 +1327,-110.40,-9.60,1.00,0.00,1.00 +1328,-105.60,-9.60,1.00,0.00,1.00 +1329,-100.80,-9.60,1.00,0.00,1.00 +1330,-96.00,-9.60,1.00,0.00,1.00 +1331,-91.20,-9.60,1.00,0.00,1.00 +1332,-86.40,-9.60,1.00,0.00,1.00 +1333,-81.60,-9.60,1.00,0.00,1.00 +1334,-76.80,-9.60,1.00,0.00,1.00 +1335,-72.00,-9.60,1.00,0.00,1.00 +1336,-67.20,-9.60,1.00,0.00,1.00 +1337,-62.40,-9.60,1.00,0.00,1.00 +1338,-57.60,-4.80,1.00,0.00,1.00 +1339,-52.80,-4.80,1.00,0.00,1.00 +1340,-48.00,-4.80,1.00,0.00,1.00 +1341,-43.20,-4.80,1.00,0.00,1.00 +1342,-38.40,-4.80,1.00,0.00,1.00 +1343,-33.60,-4.80,1.00,0.00,1.00 +1344,-28.80,-4.80,1.00,0.00,1.00 +1345,-24.00,-4.80,1.00,0.00,1.00 +1346,-19.20,-4.80,1.00,0.00,1.00 +1347,-14.40,-0.00,1.00,0.00,1.00 +1348,-9.60,-0.00,1.00,0.00,1.00 +1349,-4.80,-0.00,1.00,0.00,1.00 +1350,0.00,0.00,1.00,0.00,1.00 +1351,4.80,0.00,1.00,0.00,1.00 +1352,9.60,0.00,1.00,0.00,1.00 +1353,14.40,0.00,1.00,0.00,1.00 +1354,19.20,0.00,1.00,0.00,1.00 +1355,24.00,0.00,1.00,0.00,1.00 +1356,28.80,0.00,1.00,0.00,1.00 +1357,33.60,0.00,1.00,0.00,1.00 +1358,38.40,0.00,1.00,0.00,1.00 +1359,43.20,4.80,1.00,0.00,1.00 +1360,48.00,4.80,1.00,0.00,1.00 +1361,52.80,4.80,1.00,0.00,1.00 +1362,57.60,4.80,1.00,0.00,1.00 +1363,62.40,4.80,1.00,0.00,1.00 +1364,67.20,4.80,1.00,0.00,1.00 +1365,72.00,4.80,1.00,0.00,1.00 +1366,76.80,4.80,1.00,0.00,1.00 +1367,81.60,4.80,1.00,0.00,1.00 +1368,86.40,4.80,1.00,0.00,1.00 +1369,91.20,4.80,1.00,0.00,1.00 +1370,96.00,4.80,1.00,0.00,1.00 +1371,100.80,4.80,1.00,0.00,1.00 +1372,105.60,4.80,1.00,0.00,1.00 +1373,110.40,4.80,1.00,0.00,1.00 +1374,115.20,4.80,1.00,0.00,1.00 +1375,120.00,4.80,1.00,0.00,1.00 +1376,124.80,4.80,1.00,0.00,1.00 +1377,129.60,4.80,1.00,0.00,1.00 +1378,134.40,4.80,1.00,0.00,1.00 +1379,139.20,0.00,1.00,0.00,1.00 +1380,144.00,0.00,1.00,0.00,1.00 +1381,148.80,0.00,1.00,0.00,1.00 +1382,153.60,0.00,1.00,0.00,1.00 +1383,158.40,0.00,1.00,0.00,1.00 +1384,163.20,0.00,1.00,0.00,1.00 +1385,168.00,0.00,1.00,0.00,1.00 +1386,172.80,0.00,1.00,0.00,1.00 +1387,177.60,0.00,1.00,0.00,1.00 +1388,-177.60,-0.00,1.00,0.00,1.00 +1389,-172.80,-0.00,1.00,0.00,1.00 +1390,-168.00,-0.00,1.00,0.00,1.00 +1391,-163.20,-0.00,1.00,0.00,1.00 +1392,-158.40,-0.00,1.00,0.00,1.00 +1393,-153.60,-0.00,1.00,0.00,1.00 +1394,-148.80,-0.00,1.00,0.00,1.00 +1395,-144.00,-0.00,1.00,0.00,1.00 +1396,-139.20,-0.00,1.00,0.00,1.00 +1397,-134.40,-4.80,1.00,0.00,1.00 +1398,-129.60,-4.80,1.00,0.00,1.00 +1399,-124.80,-4.80,1.00,0.00,1.00 +1400,-120.00,-4.80,1.00,0.00,1.00 +1401,-115.20,-4.80,1.00,0.00,1.00 +1402,-110.40,-4.80,1.00,0.00,1.00 +1403,-105.60,-4.80,1.00,0.00,1.00 +1404,-100.80,-4.80,1.00,0.00,1.00 +1405,-96.00,-4.80,1.00,0.00,1.00 +1406,-91.20,-4.80,1.00,0.00,1.00 +1407,-86.40,-4.80,1.00,0.00,1.00 +1408,-81.60,-4.80,1.00,0.00,1.00 +1409,-76.80,-4.80,1.00,0.00,1.00 +1410,-72.00,-4.80,1.00,0.00,1.00 +1411,-67.20,-4.80,1.00,0.00,1.00 +1412,-62.40,-4.80,1.00,0.00,1.00 +1413,-57.60,-4.80,1.00,0.00,1.00 +1414,-52.80,-4.80,1.00,0.00,1.00 +1415,-48.00,-4.80,1.00,0.00,1.00 +1416,-43.20,-4.80,1.00,0.00,1.00 +1417,-38.40,-0.00,1.00,0.00,1.00 +1418,-33.60,-0.00,1.00,0.00,1.00 +1419,-28.80,-0.00,1.00,0.00,1.00 +1420,-24.00,-0.00,1.00,0.00,1.00 +1421,-19.20,-0.00,1.00,0.00,1.00 +1422,-14.40,-0.00,1.00,0.00,1.00 +1423,-9.60,-0.00,1.00,0.00,1.00 +1424,-4.80,-0.00,1.00,0.00,1.00 +1425,0.00,0.00,1.00,0.00,1.00 +1426,4.80,-0.00,1.00,0.00,1.00 +1427,9.60,-0.00,1.00,0.00,1.00 +1428,14.40,-0.00,1.00,0.00,1.00 +1429,19.20,-0.00,1.00,0.00,1.00 +1430,24.00,-0.00,1.00,0.00,1.00 +1431,28.80,-0.00,1.00,0.00,1.00 +1432,33.60,-0.00,1.00,0.00,1.00 +1433,38.40,-0.00,1.00,0.00,1.00 +1434,43.20,-0.00,1.00,0.00,1.00 +1435,48.00,-0.00,1.00,0.00,1.00 +1436,52.80,-0.00,1.00,0.00,1.00 +1437,57.60,-0.00,1.00,0.00,1.00 +1438,62.40,-0.00,1.00,0.00,1.00 +1439,67.20,-0.00,1.00,0.00,1.00 +1440,72.00,-0.00,1.00,0.00,1.00 +1441,76.80,-0.00,1.00,0.00,1.00 +1442,81.60,-0.00,1.00,0.00,1.00 +1443,86.40,-0.00,1.00,0.00,1.00 +1444,91.20,-0.00,1.00,0.00,1.00 +1445,96.00,-0.00,1.00,0.00,1.00 +1446,100.80,-0.00,1.00,0.00,1.00 +1447,105.60,-0.00,1.00,0.00,1.00 +1448,110.40,-0.00,1.00,0.00,1.00 +1449,115.20,-0.00,1.00,0.00,1.00 +1450,120.00,-0.00,1.00,0.00,1.00 +1451,124.80,-0.00,1.00,0.00,1.00 +1452,129.60,-0.00,1.00,0.00,1.00 +1453,134.40,-0.00,1.00,0.00,1.00 +1454,139.20,-0.00,1.00,0.00,1.00 +1455,144.00,-0.00,1.00,0.00,1.00 +1456,148.80,-0.00,1.00,0.00,1.00 +1457,153.60,-0.00,1.00,0.00,1.00 +1458,158.40,-0.00,1.00,0.00,1.00 +1459,163.20,-0.00,1.00,0.00,1.00 +1460,168.00,-0.00,1.00,0.00,1.00 +1461,172.80,-0.00,1.00,0.00,1.00 +1462,177.60,-0.00,1.00,0.00,1.00 +1463,-177.60,0.00,1.00,0.00,1.00 +1464,-172.80,0.00,1.00,0.00,1.00 +1465,-168.00,0.00,1.00,0.00,1.00 +1466,-163.20,0.00,1.00,0.00,1.00 +1467,-158.40,0.00,1.00,0.00,1.00 +1468,-153.60,0.00,1.00,0.00,1.00 +1469,-148.80,0.00,1.00,0.00,1.00 +1470,-144.00,0.00,1.00,0.00,1.00 +1471,-139.20,0.00,1.00,0.00,1.00 +1472,-134.40,0.00,1.00,0.00,1.00 +1473,-129.60,0.00,1.00,0.00,1.00 +1474,-124.80,0.00,1.00,0.00,1.00 +1475,-120.00,0.00,1.00,0.00,1.00 +1476,-115.20,0.00,1.00,0.00,1.00 +1477,-110.40,0.00,1.00,0.00,1.00 +1478,-105.60,0.00,1.00,0.00,1.00 +1479,-100.80,0.00,1.00,0.00,1.00 +1480,-96.00,0.00,1.00,0.00,1.00 +1481,-91.20,0.00,1.00,0.00,1.00 +1482,-86.40,0.00,1.00,0.00,1.00 +1483,-81.60,0.00,1.00,0.00,1.00 +1484,-76.80,0.00,1.00,0.00,1.00 +1485,-72.00,0.00,1.00,0.00,1.00 +1486,-67.20,0.00,1.00,0.00,1.00 +1487,-62.40,0.00,1.00,0.00,1.00 +1488,-57.60,0.00,1.00,0.00,1.00 +1489,-52.80,0.00,1.00,0.00,1.00 +1490,-48.00,0.00,1.00,0.00,1.00 +1491,-43.20,0.00,1.00,0.00,1.00 +1492,-38.40,0.00,1.00,0.00,1.00 +1493,-33.60,0.00,1.00,0.00,1.00 +1494,-28.80,0.00,1.00,0.00,1.00 +1495,-24.00,0.00,1.00,0.00,1.00 +1496,-19.20,0.00,1.00,0.00,1.00 +1497,-14.40,0.00,1.00,0.00,1.00 +1498,-9.60,0.00,1.00,0.00,1.00 +1499,-4.80,0.00,1.00,0.00,1.00 diff --git a/scripts/tests/data/stv_IVASMASA_1dir1TC.met b/scripts/tests/data/stv_IVASMASA_1dir1TC.met new file mode 100644 index 0000000000..f2ce23bd20 --- /dev/null +++ b/scripts/tests/data/stv_IVASMASA_1dir1TC.met @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6349efe3448d28979b80744bcdc29d57f1c025704939b42d7b913d7fc3f23ccc +size 102300 diff --git a/scripts/tests/data/stv_IVASMASA_1dir1TC.pcm b/scripts/tests/data/stv_IVASMASA_1dir1TC.pcm new file mode 100644 index 0000000000..8f2bfc54e0 --- /dev/null +++ b/scripts/tests/data/stv_IVASMASA_1dir1TC.pcm @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4dbbaa5c75c36bc74a100bc5721bc3cf2af4e22e2854a5b85c93532556afc776 +size 288000 diff --git a/scripts/tests/data/stv_IVASMASA_1dir2TC.met b/scripts/tests/data/stv_IVASMASA_1dir2TC.met new file mode 100644 index 0000000000..00acdae539 --- /dev/null +++ b/scripts/tests/data/stv_IVASMASA_1dir2TC.met @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5a1f87bfe360dbd221a94583aa68a58ef050e968a63351730d643f2dc2cac4e1 +size 204600 diff --git a/scripts/tests/data/stv_IVASMASA_1dir2TC.pcm b/scripts/tests/data/stv_IVASMASA_1dir2TC.pcm new file mode 100644 index 0000000000..491e75f868 --- /dev/null +++ b/scripts/tests/data/stv_IVASMASA_1dir2TC.pcm @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cd34c99b89d9c1ed3514c3f8e32faf6b82fbc8bf364bc464904fc1c745266350 +size 1152000 diff --git a/scripts/tests/data/stv_IVASMASA_2dir1TC.met b/scripts/tests/data/stv_IVASMASA_2dir1TC.met new file mode 100644 index 0000000000..6468877408 --- /dev/null +++ b/scripts/tests/data/stv_IVASMASA_2dir1TC.met @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d125a4c4e3989ac55f9c2617f464431feae4ede9b2e15d087d3271c0a4a56303 +size 319800 diff --git a/scripts/tests/data/stv_IVASMASA_2dir1TC.pcm b/scripts/tests/data/stv_IVASMASA_2dir1TC.pcm new file mode 100644 index 0000000000..7c7209de2d --- /dev/null +++ b/scripts/tests/data/stv_IVASMASA_2dir1TC.pcm @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5afc7014451a8599f8399e3a503a29b23d22843ef482c0a701d4c46f6329ebc4 +size 576000 diff --git a/scripts/tests/data/stv_IVASMASA_2dir2TC.met b/scripts/tests/data/stv_IVASMASA_2dir2TC.met new file mode 100644 index 0000000000..1b62022af5 --- /dev/null +++ b/scripts/tests/data/stv_IVASMASA_2dir2TC.met @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2eb412d646d7a32c77413dea54dc44cf45dc49e6d8c2de19abe4f4b93a91fa4a +size 159900 diff --git a/scripts/tests/data/stv_IVASMASA_2dir2TC.pcm b/scripts/tests/data/stv_IVASMASA_2dir2TC.pcm new file mode 100644 index 0000000000..ac8d4d341a --- /dev/null +++ b/scripts/tests/data/stv_IVASMASA_2dir2TC.pcm @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5d6c264295987b7db2a9a6a1352dd0b9c91a824fcc37c5631e0ba39e92df33f8 +size 576000 diff --git a/scripts/tests/ref/.gitignore b/scripts/tests/ref/.gitignore new file mode 100644 index 0000000000..f935021a8f --- /dev/null +++ b/scripts/tests/ref/.gitignore @@ -0,0 +1 @@ +!.gitignore diff --git a/scripts/tests/test_renderer.py b/scripts/tests/test_renderer.py new file mode 100644 index 0000000000..d976f8f210 --- /dev/null +++ b/scripts/tests/test_renderer.py @@ -0,0 +1,387 @@ +#!/usr/bin/env python3 + +""" + (C) 2022 Baseline Development Group 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 Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The Baseline Development Group 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 Corporation, Qualcomm Technologies, Inc., and VoiceAge Corporation retain full ownership + rights in their respective contributions in the software. No license of any kind, including but not + limited to patent license, of any foregoing parties is hereby granted by implication, estoppel or + otherwise. + + 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/or 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. +""" + +import subprocess as sp +import pyaudio3dtools +import pytest +import numpy as np +from pathlib import PurePath +from typing import Optional, Tuple + +from .compare_audio import compare_audio_arrays +from .constants import * + + +def check_BE( + ref: np.ndarray, ref_fs: int, cut: np.ndarray, cut_fs: int, snr_min: float = np.inf +): + + if ref is None or np.array_equal(ref, np.zeros_like(ref)): + pytest.fail("REF signal does not exist or is zero!") + + if cut is None or np.array_equal(cut, np.zeros_like(cut)): + pytest.fail("CuT signal does not exist or is zero!") + + snr, gain_b, max_diff = compare_audio_arrays(ref, ref_fs, cut, cut_fs) + + if np.isnan(snr) or gain_b == 0: + pytest.fail("Invalid comparison result, check your signals!") + + if not np.allclose(ref, cut, rtol=0, atol=2) and snr < snr_min: + pytest.fail( + f"CuT not BE to REF! SNR : {snr:3.2f} dB, Gain CuT: {gain_b:1.3f}, Max Diff = {int(max_diff)}" + ) + + +def run_pyscripts( + in_fmt, + out_fmt, + metadata_input: Optional[str] = None, + in_meta_files: Optional[list] = None, + trj_file: Optional[str] = None, +) -> Tuple[np.ndarray, int]: + """Reference rendering with pyaudio3dtools""" + if trj_file is not None: + trj_name = f"_{trj_file.stem}" + else: + trj_name = "" + + if not isinstance(out_fmt, str): + out_name = f"{out_fmt.stem}" + else: + out_name = out_fmt + + if metadata_input is not None: + in_file = metadata_input + in_name = metadata_input.stem + elif isinstance(in_fmt, PurePath): + in_file = FORMAT_TO_FILE[in_fmt.stem] + in_name = in_fmt.stem + else: + in_file = FORMAT_TO_FILE[in_fmt] + in_name = in_fmt + + out_file = str(OUTPUT_PATH_REF.joinpath(f"{in_name}_to_{out_name}{trj_name}.wav")) + + pyaudio3dtools.spatialaudioconvert.spatial_audio_convert( + in_file, + out_file, + in_format=in_fmt, + out_format=out_fmt, + in_meta_files=in_meta_files, + trajectory=trj_file, + limit_output=True, + ) + + return pyaudio3dtools.audiofile.readfile(out_file) + + +# TODO include sampling rate, ndl ? +def run_renderer( + in_fmt: str, + out_fmt: str, + metadata_input: Optional[str] = None, + in_meta_files: Optional[list] = None, + trj_file: Optional[str] = None, +) -> Tuple[np.ndarray, int]: + """CuT creation with standalone renderer""" + if trj_file is not None: + trj_name = f"_{trj_file.stem}" + else: + trj_name = "" + + if not isinstance(out_fmt, str): + out_name = f"{out_fmt.stem}" + else: + out_name = out_fmt + + if metadata_input is not None: + in_file = metadata_input + in_name = metadata_input.stem + elif not isinstance(in_fmt, str): + in_file = FORMAT_TO_FILE[in_fmt.stem] + in_name = in_fmt.stem + else: + in_file = FORMAT_TO_FILE[in_fmt] + in_name = in_fmt + + out_file = str(OUTPUT_PATH_CUT.joinpath(f"{in_name}_to_{out_name}{trj_name}.wav")) + + cmd = RENDERER_CMD[:] + cmd[2] = str(in_file) + cmd[4] = str(in_fmt) + cmd[6] = str(out_file) + cmd[8] = str(out_fmt) + + if in_meta_files is not None: + cmd[5:5] = in_meta_files + + if trj_file is not None: + cmd.extend(["-tf", str(trj_file)]) + + try: + sp.run(cmd, check=True, capture_output=True, text=True) + except sp.CalledProcessError as e: + pytest.fail( + f"Command returned non-zero exit status ({e.returncode})!\n{' '.join(e.cmd)}\n{e.stderr}\n{e.stdout}\n{e.output}" + ) + + return pyaudio3dtools.audiofile.readfile(out_file) + + +# Ambisonics / loudspeaker based input formats +@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS) +@pytest.mark.parametrize("in_fmt", INPUT_FORMATS_AMBI) +def test_ambisonics(in_fmt, out_fmt): + ref, ref_fs = run_pyscripts(in_fmt, out_fmt) + + cut, cut_fs = run_renderer(in_fmt, out_fmt) + + check_BE(ref, ref_fs, cut, cut_fs) + + +@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS) +@pytest.mark.parametrize("in_fmt", INPUT_FORMATS_MC) +def test_multichannel(in_fmt, out_fmt): + ref, ref_fs = run_pyscripts(in_fmt, out_fmt) + + cut, cut_fs = run_renderer(in_fmt, out_fmt) + + if out_fmt in ["MONO", "STEREO"]: + check_BE(ref, ref_fs, cut, cut_fs, snr_min=10) + else: + check_BE(ref, ref_fs, cut, cut_fs) + + +@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS) +@pytest.mark.parametrize("in_layout", CUSTOM_LS_TO_TEST) +def test_custom_ls_input(in_layout, out_fmt): + ref, ref_fs = run_pyscripts( + CUSTOM_LAYOUT_DIR.joinpath(f"{in_layout}.txt"), + out_fmt, + ) + + cut, cut_fs = run_renderer(CUSTOM_LAYOUT_DIR.joinpath(f"{in_layout}.txt"), out_fmt) + + check_BE(ref, ref_fs, cut, cut_fs) + + +@pytest.mark.parametrize("out_fmt", CUSTOM_LS_TO_TEST) +@pytest.mark.parametrize("in_fmt", OUTPUT_FORMATS) +def test_custom_ls_output(in_fmt, out_fmt): + ref, ref_fs = run_pyscripts( + in_fmt, + CUSTOM_LAYOUT_DIR.joinpath(f"{out_fmt}.txt"), + ) + + cut, cut_fs = run_renderer(in_fmt, CUSTOM_LAYOUT_DIR.joinpath(f"{out_fmt}.txt")) + + check_BE(ref, ref_fs, cut, cut_fs) + + +@pytest.mark.parametrize("out_fmt", CUSTOM_LS_TO_TEST) +@pytest.mark.parametrize("in_fmt", CUSTOM_LS_TO_TEST) +def test_custom_ls_input_output(in_fmt, out_fmt): + ref, ref_fs = run_pyscripts( + CUSTOM_LAYOUT_DIR.joinpath(f"{in_fmt}.txt"), + CUSTOM_LAYOUT_DIR.joinpath(f"{out_fmt}.txt"), + ) + + cut, cut_fs = run_renderer( + CUSTOM_LAYOUT_DIR.joinpath(f"{in_fmt}.txt"), + CUSTOM_LAYOUT_DIR.joinpath(f"{out_fmt}.txt"), + ) + + check_BE(ref, ref_fs, cut, cut_fs) + + +# Metadata / parametric input formats +@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS) +@pytest.mark.parametrize("in_fmt", INPUT_FORMATS_ISM) +def test_ism(in_fmt, out_fmt): + ref, ref_fs = run_pyscripts( + in_fmt, out_fmt, in_meta_files=FORMAT_TO_METADATA_FILES[in_fmt] + ) + cut, cut_fs = run_renderer( + in_fmt, + out_fmt, + in_meta_files=FORMAT_TO_METADATA_FILES[in_fmt], + ) + + check_BE(ref, ref_fs, cut, cut_fs, snr_min=38) + + +@pytest.mark.skip(reason="MASA rendering is currently not implemented") +@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS) +@pytest.mark.parametrize("in_fmt", INPUT_FORMATS_MASA) +def test_masa(in_fmt, out_fmt): + ref, ref_fs = run_pyscripts( + in_fmt, out_fmt, in_meta_files=FORMAT_TO_METADATA_FILES[in_fmt] + ) + + cut, cut_fs = run_renderer( + in_fmt, + out_fmt, + in_meta_files=FORMAT_TO_METADATA_FILES[in_fmt], + ) + + check_BE(ref, ref_fs, cut, cut_fs) + + +@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS) +@pytest.mark.parametrize("in_fmt", METADATA_SCENES_TO_TEST) +def test_metadata(in_fmt, out_fmt): + ref, ref_fs = run_pyscripts( + "META", out_fmt, metadata_input=TEST_VECTOR_DIR.joinpath(f"{in_fmt}.txt") + ) + + cut, cut_fs = run_renderer( + "META", + out_fmt, + metadata_input=TEST_VECTOR_DIR.joinpath(f"{in_fmt}.txt"), + ) + + check_BE(ref, ref_fs, cut, cut_fs, snr_min=11) + + +# Binaural rendering (static) +@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL) +@pytest.mark.parametrize("in_fmt", INPUT_FORMATS_AMBI) +def test_ambisonics_binaural_static(in_fmt, out_fmt): + ref, ref_fs = run_pyscripts(in_fmt, out_fmt) + + cut, cut_fs = run_renderer(in_fmt, out_fmt) + + check_BE(ref, ref_fs, cut, cut_fs, snr_min=89) + + +@pytest.mark.xfail(reason="Python cannot be BE to TD Object Renderer") +@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL) +@pytest.mark.parametrize("in_fmt", INPUT_FORMATS_ISM) +def test_ism_binaural_static(in_fmt, out_fmt): + try: + in_meta_files = FORMAT_TO_METADATA_FILES[in_fmt] + except: + in_meta_files = None + + ref, ref_fs = run_pyscripts(in_fmt, out_fmt, in_meta_files=in_meta_files) + + cut, cut_fs = run_renderer(in_fmt, out_fmt, in_meta_files=in_meta_files) + + check_BE(ref, ref_fs, cut, cut_fs) + + +@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL) +@pytest.mark.parametrize("in_fmt", INPUT_FORMATS_MC[2:]) +def test_multichannel_binaural_static(in_fmt, out_fmt): + ref, ref_fs = run_pyscripts(in_fmt, out_fmt) + + cut, cut_fs = run_renderer(in_fmt, out_fmt) + + check_BE(ref, ref_fs, cut, cut_fs, snr_min=11) + + +# Binaural rendering (head rotation) +@pytest.mark.parametrize("trj_file", HR_TRAJECTORIES_TO_TEST) +@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL) +@pytest.mark.parametrize("in_fmt", INPUT_FORMATS_AMBI) +def test_ambisonics_binaural_headrotation(in_fmt, out_fmt, trj_file): + ref, ref_fs = run_pyscripts( + in_fmt, + out_fmt, + trj_file=HR_TRAJECTORY_DIR.joinpath(f"{trj_file}.csv"), + ) + + cut, cut_fs = run_renderer( + in_fmt, + out_fmt, + trj_file=HR_TRAJECTORY_DIR.joinpath(f"{trj_file}.csv"), + ) + + check_BE(ref, ref_fs, cut, cut_fs, snr_min=42) + + +@pytest.mark.xfail(reason="Python cannot be BE to TD Object Renderer") +@pytest.mark.parametrize("trj_file", HR_TRAJECTORIES_TO_TEST) +@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL) +@pytest.mark.parametrize("in_fmt", INPUT_FORMATS_ISM) +def test_ism_binaural_headrotation(in_fmt, out_fmt, trj_file): + try: + in_meta_files = FORMAT_TO_METADATA_FILES[in_fmt] + except: + in_meta_files = None + + ref, ref_fs = run_pyscripts( + in_fmt, + out_fmt, + trj_file=HR_TRAJECTORY_DIR.joinpath(f"{trj_file}.csv"), + in_meta_files=in_meta_files, + ) + + cut, cut_fs = run_renderer( + in_fmt, + out_fmt, + trj_file=HR_TRAJECTORY_DIR.joinpath(f"{trj_file}.csv"), + in_meta_files=in_meta_files, + ) + + check_BE(ref, ref_fs, cut, cut_fs) + + +@pytest.mark.parametrize("trj_file", HR_TRAJECTORIES_TO_TEST) +@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL) +@pytest.mark.parametrize( + "in_fmt", + [ + pytest.param( + "5_1", + marks=pytest.mark.xfail(reason="Python cannot be BE to TD Object Renderer"), + ), + pytest.param( + "7_1", + marks=pytest.mark.xfail(reason="Python cannot be BE to TD Object Renderer"), + ), + "5_1_2", + "5_1_4", + "7_1_4", + ], +) +def test_multichannel_binaural_headrotation(in_fmt, out_fmt, trj_file): + ref, ref_fs = run_pyscripts( + in_fmt, + out_fmt, + trj_file=HR_TRAJECTORY_DIR.joinpath(f"{trj_file}.csv"), + ) + + cut, cut_fs = run_renderer( + in_fmt, + out_fmt, + trj_file=HR_TRAJECTORY_DIR.joinpath(f"{trj_file}.csv"), + ) + + check_BE(ref, ref_fs, cut, cut_fs, snr_min=4.5) diff --git a/scripts/vbap_51_table.bin b/scripts/vbap_51_table.bin new file mode 100644 index 0000000000..2477f1194a --- /dev/null +++ b/scripts/vbap_51_table.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d5182e9d0d86d47871e34d8a2821ebef94d8f25d08c51cd0bd618d66a59e4fab +size 3620 diff --git a/scripts/vbap_714_table.bin b/scripts/vbap_714_table.bin new file mode 100644 index 0000000000..1541c1fdee --- /dev/null +++ b/scripts/vbap_714_table.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ac34d9a81d62ac12094aab948047650017019377059fdf425614ef9f345954f7 +size 294668 diff --git a/scripts/vbap_bin_table.bin b/scripts/vbap_bin_table.bin new file mode 100644 index 0000000000..1bf371c9c5 --- /dev/null +++ b/scripts/vbap_bin_table.bin @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ab7bfe8d1c01359213362e8dcce21f42b50c07ed7f7a4a8ff972f516283df027 +size 428608 -- GitLab From 7bec4a3bfe2253cd251a53891f29a1260f241952 Mon Sep 17 00:00:00 2001 From: sagnowski Date: Wed, 10 Aug 2022 16:25:59 +0000 Subject: [PATCH 002/101] Fix .gitlab-ci.yml file --- .gitlab-ci.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 91ddc62ad5..750b00eb7c 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -229,6 +229,7 @@ external-renderer-make-pytest: - .test-job-linux - .rules-merge-request needs: [ "build-codec-linux-make" ] + stage: test script: - make -j IVAS_rend - python3 -m pytest scripts/tests/test_renderer.py --capture=no --tb=no -n auto @@ -239,6 +240,7 @@ external-renderer-cmake-asan-pytest: - .test-job-linux - .rules-merge-request needs: [ "build-codec-linux-cmake" ] + stage: test script: - cmake -B cmake-build -G "Unix Makefiles" -DCLANG=asan - cmake --build cmake-build -- -j @@ -250,6 +252,7 @@ external-renderer-cmake-msan-pytest: - .test-job-linux - .rules-merge-request needs: [ "build-codec-linux-cmake" ] + stage: test script: - cmake -B cmake-build -G "Unix Makefiles" -DCLANG=msan - cmake --build cmake-build -- -j -- GitLab From 40f3499aad47b87d90ed7bbe4ee9bae664c9a7cd Mon Sep 17 00:00:00 2001 From: Kacper Sagnowski Date: Tue, 16 Aug 2022 18:02:39 +0200 Subject: [PATCH 003/101] Update external renderer and corresponding tests Includes: - Bug fixes - Improvements to tests - Fix for build issues with Make - Framework changes in preparation for MASA rendering --- .gitlab-ci.yml | 2 + Makefile | 2 +- apps/renderer.c | 161 ++++++++- ci/disable_ram_counting.py | 20 ++ lib_rend/lib_rend.c | 334 +++++++++++++++--- lib_rend/lib_rend.h | 22 ++ scripts/pyaudio3dtools/binauralrenderer.py | 3 +- scripts/pyaudio3dtools/rotation.py | 6 +- scripts/pyaudio3dtools/spatialaudioconvert.py | 3 +- scripts/tests/constants.py | 5 +- scripts/tests/data/masa_scene.txt | 6 + .../data/renderer_config_format_readme.txt | 18 +- scripts/tests/data/stv_IVASMASA_2dir2TC.wav | 3 + scripts/tests/test_renderer.py | 23 +- 14 files changed, 521 insertions(+), 87 deletions(-) create mode 100644 ci/disable_ram_counting.py create mode 100644 scripts/tests/data/masa_scene.txt create mode 100644 scripts/tests/data/stv_IVASMASA_2dir2TC.wav diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 750b00eb7c..d6cb4c70b7 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -242,6 +242,7 @@ external-renderer-cmake-asan-pytest: needs: [ "build-codec-linux-cmake" ] stage: test script: + - python3 ci/disable_ram_counting.py - cmake -B cmake-build -G "Unix Makefiles" -DCLANG=asan - cmake --build cmake-build -- -j - python3 -m pytest scripts/tests/test_renderer.py --capture=no --tb=no -n auto @@ -254,6 +255,7 @@ external-renderer-cmake-msan-pytest: needs: [ "build-codec-linux-cmake" ] stage: test script: + - python3 ci/disable_ram_counting.py - cmake -B cmake-build -G "Unix Makefiles" -DCLANG=msan - cmake --build cmake-build -- -j - python3 -m pytest scripts/tests/test_renderer.py --capture=no --tb=no -n auto diff --git a/Makefile b/Makefile index 8eafa71deb..e2bdf99b86 100644 --- a/Makefile +++ b/Makefile @@ -185,7 +185,7 @@ $(CLI_APIDEC): $(OBJS_CLI_APIDEC) $(LIB_LIBDEC) $(LIB_LIBCOM) $(LIB_LIBUTIL) $(L $(QUIET_LINK)$(CC) $(LDFLAGS) $(OBJS_CLI_APIDEC) -L. -livasdec -livascom -livasutil -livasdebug $(LDLIBS) -o $(CLI_APIDEC) $(CLI_APIREND): $(OBJS_CLI_APPREND) $(LIB_LIBREND) $(LIB_LIBCOM) $(LIB_LIBUTIL) $(LIB_LIBDEBUG) - $(QUIET_LINK)$(CC) $(LDFLAGS) $(OBJS_CLI_APPREND) -L. -livasrend -livascom -livasutil -livasdebug $(LDLIBS) -o $(CLI_APIREND) + $(QUIET_LINK)$(CC) $(LDFLAGS) $(OBJS_CLI_APPREND) -L. -livasrend -livasutil -livascom -livasdebug $(LDLIBS) -o $(CLI_APIREND) $(CLI_UTESTS_CREND): $(OBJS_CLI_UTESTS_CREND) $(LIB_LIBDEC) $(LIB_LIBCOM) $(LIB_LIBUTIL) $(LIB_LIBDEBUG) $(QUIET_LINK)$(CC) $(LDFLAGS) $(OBJS_CLI_UTESTS_CREND) -L. -livasdec -livascom -livasutil -livasdebug $(LDLIBS) -o $(UTESTS_CREND_DIR)/$(CLI_UTESTS_CREND) diff --git a/apps/renderer.c b/apps/renderer.c index 38c28e3dc4..38f1a7c16c 100644 --- a/apps/renderer.c +++ b/apps/renderer.c @@ -42,6 +42,7 @@ #include "lib_rend.h" #include "ls_custom_file_reader.h" #include "render_config_reader.h" +#include "masa_file_reader.h" #include "ivas_stat_dec.h" #include "prot.h" #ifdef WMOPS @@ -178,6 +179,9 @@ static IVAS_REND_Ambisonics ambisonicsOrderToEnum( static IVAS_REND_Ambisonics audioCfgToAmbiEnum( AUDIO_CONFIG cfg ); +static IVAS_REND_MasaTc audioCfgToMasaEnum( + AUDIO_CONFIG cfg ); + static IVAS_REND_SpeakerLayout speakerLayoutCicpToEnum( int32_t cicpIndex ); @@ -196,7 +200,8 @@ static void parseConfigFile( char *path, char *audioFilePath, IVAS_REND_InputConfig *inConfig, - IsmPositionProvider *positionProvider ); + IsmPositionProvider *positionProvider, + char *masaMetadataFilePath ); static void parseCustomLayoutFile( char *filePath, @@ -271,11 +276,17 @@ static void parseMc( IVAS_REND_InputConfig *inConfig, int32_t idx ); +static void parseMasa( + char *line, + IVAS_REND_InputConfig *inConfig, + char *masaMetadataFilePath ); + static void parseMetadata( char *metadataString, char *inDir, IVAS_REND_InputConfig *inConfig, - IsmPositionProvider *positionProvider ); + IsmPositionProvider *positionProvider, + char *masaMetadataFilePath ); static void convert_backslash( char *str ); @@ -294,6 +305,7 @@ int32_t main( int32_t argc, char **argv ) IsmPositionProvider *positionProvider; RenderConfigReader *renderConfigReader = NULL; char audioFilePath[FILENAME_MAX]; + char masaMetadataFilePath[FILENAME_MAX]; AudioFileReader *audioReader = NULL; int16_t numInChannels; AudioFileWriter *audioWriter; @@ -332,6 +344,8 @@ int32_t main( int32_t argc, char **argv ) hIvasRend = IVAS_REND_Open(); positionProvider = IsmPositionProvider_open(); + masaMetadataFilePath[0] = '\0'; + convert_backslash( args.inputFilePath ); convert_backslash( args.outputFilePath ); convert_backslash( args.trajectoryFile ); @@ -355,7 +369,7 @@ int32_t main( int32_t argc, char **argv ) if ( args.inputFormat == AUDIO_CONFIG_INVALID || args.inputFormat == AUDIO_CONFIG_META ) { /* Only parse config file if input config is none */ - parseConfigFile( args.inputFilePath, audioFilePath, &args.inConfig, positionProvider ); + parseConfigFile( args.inputFilePath, audioFilePath, &args.inConfig, positionProvider, masaMetadataFilePath ); } else { @@ -415,6 +429,21 @@ int32_t main( int32_t argc, char **argv ) } /* === Process === */ + MasaFileReader *masaReader = NULL; + IVAS_MASA_METADATA_HANDLE hMasaMetadata = NULL; + + if ( masaMetadataFilePath[0] != '\0' ) + { + masaReader = MasaFileReader_open( masaMetadataFilePath ); + if ( masaReader == NULL ) + { + fprintf( stderr, "Could not open MASA metadata file %s\n", masaMetadataFilePath ); + exit( -1 ); + } + + hMasaMetadata = MasaFileReader_getMetadataHandle( masaReader ); + } + if ( AudioFileWriter_open( &audioWriter, args.outputFilePath, args.sampleRate, IVAS_REND_GetOutChannels( hIvasRend ) ) != IVAS_ERR_OK ) { fprintf( stderr, "Failed to open file: %s\n", args.outputFilePath ); @@ -490,6 +519,17 @@ int32_t main( int32_t argc, char **argv ) } } + if ( masaReader != NULL ) + { + MasaFileReader_readNextFrame( masaReader ); + + if ( ( error = IVAS_REND_FeedMasaMetadata(hIvasRend, hMasaMetadata) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + } + IVAS_REND_AudioObjectMetadataBuffer mtdBuffer; IsmPositionProvider_getNextFrame( positionProvider, &mtdBuffer ); @@ -582,6 +622,7 @@ int32_t main( int32_t argc, char **argv ) count_free( inFloatBuffer ); count_free( outInt16Buffer ); count_free( outFloatBuffer ); + MasaFileReader_close( &masaReader ); AudioFileReader_close( &audioReader ); AudioFileWriter_close( &audioWriter ); HeadRotationFileReader_close( &headRotReader ); @@ -611,6 +652,17 @@ static int8_t setInConfig( int16_t numChannels, AUDIO_CONFIG input_config, IVAS_ success = 1; + if ( input_config == AUDIO_CONFIG_META ) + { + /* inConfig already set from metadata file, return early */ + return 0; + } + + inConfig->numAudioObjects = 0; + inConfig->numAmbisonicsBuses = 0; + inConfig->numMultiChannelBuses = 0; + inConfig->numMasaBuses = 0; + switch ( input_config ) { case AUDIO_CONFIG_MONO: @@ -621,8 +673,6 @@ static int8_t setInConfig( int16_t numChannels, AUDIO_CONFIG input_config, IVAS_ case AUDIO_CONFIG_5_1_4: case AUDIO_CONFIG_7_1_4: case AUDIO_CONFIG_LS_CUSTOM: - inConfig->numAudioObjects = 0; - inConfig->numAmbisonicsBuses = 0; inConfig->numMultiChannelBuses = 1; inConfig->multiChannelBuses[0].speakerLayout = audioCfgToMcEnum( input_config ); inConfig->multiChannelBuses[0].inputChannelIndex = 0; @@ -631,8 +681,6 @@ static int8_t setInConfig( int16_t numChannels, AUDIO_CONFIG input_config, IVAS_ case AUDIO_CONFIG_FOA: case AUDIO_CONFIG_HOA2: case AUDIO_CONFIG_HOA3: - inConfig->numAudioObjects = 0; - inConfig->numMultiChannelBuses = 0; inConfig->numAmbisonicsBuses = 1; inConfig->ambisonicsBuses[0].ambisonicsConfig = audioCfgToAmbiEnum( input_config ); inConfig->ambisonicsBuses[0].inputChannelIndex = 0; @@ -642,8 +690,6 @@ static int8_t setInConfig( int16_t numChannels, AUDIO_CONFIG input_config, IVAS_ case AUDIO_CONFIG_ISM2: case AUDIO_CONFIG_ISM3: case AUDIO_CONFIG_ISM4: - inConfig->numAmbisonicsBuses = 0; - inConfig->numMultiChannelBuses = 0; inConfig->numAudioObjects = numChannels; positionProvider->numObjects = numChannels; @@ -665,7 +711,12 @@ static int8_t setInConfig( int16_t numChannels, AUDIO_CONFIG input_config, IVAS_ positionProvider->positionDurations[i][0] = 1; } break; - case AUDIO_CONFIG_META: + case AUDIO_CONFIG_MASA1: + case AUDIO_CONFIG_MASA2: + inConfig->numMasaBuses = 1; + inConfig->masaBus.numTc = audioCfgToMasaEnum( input_config ); + inConfig->masaBus.inputChannelIndex = 0; + inConfig->masaBus.gain_dB = 0; break; default: success = 0; @@ -714,6 +765,21 @@ static IVAS_REND_Ambisonics audioCfgToAmbiEnum( AUDIO_CONFIG cfg ) return IVAS_REND_AMBISONICS_NONE; } +static IVAS_REND_MasaTc audioCfgToMasaEnum( AUDIO_CONFIG cfg ) +{ + switch ( cfg ) + { + case AUDIO_CONFIG_MASA1: + return IVAS_REND_MASA_TC_1; + case AUDIO_CONFIG_MASA2: + return IVAS_REND_MASA_TC_2; + default: + break; + } + + return IVAS_REND_MASA_TC_NONE; +} + static IVAS_REND_SpeakerLayout speakerLayoutCicpToEnum( int32_t cicpIndex ) { switch ( cicpIndex ) @@ -833,8 +899,15 @@ static AUDIO_CONFIG parseStrToAudioCfg( char *config_str ) } else if ( strncmp( format, "MASA", 4 ) == 0 ) { - parseUint8( &format[4], &numObjects ); - return AUDIO_CONFIG_MASA1 + numObjects - 1; + switch ( format[4] ) + { + case '1': + return AUDIO_CONFIG_MASA1; + case '2': + return AUDIO_CONFIG_MASA2; + default: + return AUDIO_CONFIG_INVALID; + } } else if ( strncmp( format, "META", 4 ) == 0 ) { @@ -900,6 +973,7 @@ static int8_t parseInFormat( char **optionValues, CmdlnArgs *args ) case AUDIO_CONFIG_EXTERNAL: fprintf( stderr, "No rendering possible for EXT format!\n" ); success = 0; + break; default: args->numAudioObjects = 0; } @@ -942,6 +1016,7 @@ static int8_t parseOutConfig( char *configString, IVAS_REND_OutputConfig *outCon case AUDIO_CONFIG_LS_CUSTOM: outConfig->speakerLayout = IVAS_REND_SPEAKER_LAYOUT_CUSTOM; parseCustomLayoutFile( configString, &outConfig->outSetupCustom ); + break; case AUDIO_CONFIG_FOA: case AUDIO_CONFIG_HOA2: case AUDIO_CONFIG_HOA3: @@ -1546,7 +1621,7 @@ static void parseOptionalInputValues( parse_pos = readNextMetadataChunk( line, "\n" ); /* Look for optional metadata until end of string or next input identifier is found */ - while ( parse_pos != NULL && strcmp( line, "MC" ) != 0 && strcmp( line, "SBA" ) != 0 && strcmp( line, "ISM" ) != 0 ) + while ( parse_pos != NULL && strcmp( line, "MC" ) != 0 && strcmp( line, "SBA" ) != 0 && strcmp( line, "ISM" ) != 0 && strcmp( line, "MASA" ) != 0 ) { key = strtok( line, ":" ); value = strtok( NULL, "\n" ); @@ -1692,6 +1767,36 @@ static void parseMc( char *line, parseOptionalInputValues( line, &inConfig->multiChannelBuses[idx].gain_dB ); } +static void parseMasa( + char *line, + IVAS_REND_InputConfig *inConfig, + char *masaMetadataFilePath ) +{ + AUDIO_CONFIG cfg; + + readNextMetadataChunk( line, "\n" ); + parseUint8( line, &inConfig->masaBus.inputChannelIndex ); + --inConfig->masaBus.inputChannelIndex; /* Convert from 1-indexing */ + + readNextMetadataChunk( line, "\n" ); + + /* Allow both just the number of TCs or MASAx. parseStrToAudioCfg() only accepts MASAx, so prepend if necessary. */ + if ( strncmp( line, "MASA", 4 ) != 0 ) + { + char numTcs = *line; + sprintf( line, "MASA%c", numTcs ); + } + + cfg = parseStrToAudioCfg( line ); + inConfig->masaBus.numTc = audioCfgToMasaEnum( cfg ); + + readNextMetadataChunk( line, "\n" ); + strcpy( masaMetadataFilePath, line ); + + /* Read optional values */ + parseOptionalInputValues( line, &inConfig->masaBus.gain_dB ); +} + static void parseCustomLayoutFile( char *filePath, IVAS_LSSETUP_CUSTOM_HANDLE *hLsSetupCustom ) @@ -1735,7 +1840,8 @@ static void parseMetadata( char *metadataString, char *inDir, IVAS_REND_InputConfig *inConfig, - IsmPositionProvider *positionProvider ) + IsmPositionProvider *positionProvider, + char *masaMetadataFilePath ) { char line[RENDERER_MAX_METADATA_LINE_LENGTH]; char *delimiter; @@ -1744,6 +1850,7 @@ static void parseMetadata( uint8_t counterChannelAudioObjects; uint8_t counterAmbisonicsAudioObjects; uint8_t counterMonoAudioObjects; + uint8_t counterMasaInputs; uint8_t num_parsed_inputs; delimiter = "\n"; @@ -1771,6 +1878,7 @@ static void parseMetadata( counterChannelAudioObjects = 0; counterAmbisonicsAudioObjects = 0; counterMonoAudioObjects = 0; + counterMasaInputs = 0; readNextMetadataChunk( line, delimiter ); @@ -1807,6 +1915,16 @@ static void parseMetadata( } parseIsm( line, inDir, inConfig, positionProvider, counterMonoAudioObjects - 1 ); } + else if ( strcmp( line, "MASA" ) == 0 ) + { + ++counterMasaInputs; + if ( counterMasaInputs > RENDERER_MAX_MASA_INPUTS ) + { + fprintf( stderr, "Metadata exceeds the supported number of MASA inputs\n" ); + exit( -1 ); + } + parseMasa( line, inConfig, masaMetadataFilePath ); + } else if ( line[0] == '\0' ) { fprintf( stderr, "Metadata string too short - expected %d inputs, found %d.\n", totalNumberOfAudioObjects, num_parsed_inputs ); @@ -1824,6 +1942,7 @@ static void parseMetadata( inConfig->numAudioObjects = counterMonoAudioObjects; inConfig->numAmbisonicsBuses = counterAmbisonicsAudioObjects; inConfig->numMultiChannelBuses = counterChannelAudioObjects; + inConfig->numMasaBuses = counterMasaInputs; positionProvider->numObjects = counterMonoAudioObjects; /* check for trailing text */ @@ -1835,15 +1954,17 @@ static void parseMetadata( } } -void parseConfigFile( char *path, char *audioFilePath, IVAS_REND_InputConfig *inConfig, IsmPositionProvider *positionProvider ) +void parseConfigFile( char *path, char *audioFilePath, IVAS_REND_InputConfig *inConfig, IsmPositionProvider *positionProvider, char *masaMetadataFilePath ) { uint32_t inAudioFilePathLen; char inAudioFilePath[FILENAME_MAX]; + char inMasaFilePath[FILENAME_MAX]; uint32_t mtdStrLen; char mtdStr[RENDERER_MAX_METADATA_LENGTH]; char inDir[FILENAME_MAX]; char *lastSlash = NULL; + inMasaFilePath[0] = '\0'; inAudioFilePathLen = FILENAME_MAX; mtdStrLen = RENDERER_MAX_METADATA_LENGTH; splitConfigFile( path, @@ -1868,7 +1989,15 @@ void parseConfigFile( char *path, char *audioFilePath, IVAS_REND_InputConfig *in strcpy( audioFilePath, inDir ); strncat( audioFilePath, inAudioFilePath, inAudioFilePathLen ); - parseMetadata( mtdStr, inDir, inConfig, positionProvider ); + parseMetadata( mtdStr, inDir, inConfig, positionProvider, inMasaFilePath ); + + /* Append MASA file path (relative to config file location) + * to config file location path to get full absolute path */ + if ( inMasaFilePath[0] != '\0' ) + { + strcpy( masaMetadataFilePath, inDir ); + strcat( masaMetadataFilePath, inMasaFilePath ); + } } static void convert_backslash( char *str ) diff --git a/ci/disable_ram_counting.py b/ci/disable_ram_counting.py new file mode 100644 index 0000000000..3c89153508 --- /dev/null +++ b/ci/disable_ram_counting.py @@ -0,0 +1,20 @@ +import re +import os + +FILE_PATH = os.path.join(os.path.dirname(__file__), "..", "lib_com", "options.h") +RE_TO_COMMENT_OUT = re.compile(r"#define\s+RAM_COUNTING_TOOL") + + +def main(): + with open(FILE_PATH, "r", encoding="utf-8") as file: + lines = file.readlines() + + for i, line in enumerate(lines): + lines[i] = RE_TO_COMMENT_OUT.sub(lambda x: f"/* {x.group(0)} */", line) + + with open(FILE_PATH, "w", encoding="utf-8") as file: + file.writelines(lines) + + +if __name__ == "__main__": + main() diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index 2d568e8837..903e27fe19 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -81,6 +81,7 @@ struct IVAS_REND int16_t numInChannelsObj; /* Total number of input channels of object inputs */ int16_t numInChannelsAmbi; /* Total number of input channels of ambisonics inputs */ int16_t numInChannelsMc; /* Total number of input channels of multichannel inputs */ + int16_t numInChannelsMasa; /* Total number of input channels of MASA inputs */ /* For each channel of MC inputs mcPassThrough contains the corresponding * output channel index if a passthrough is possible, otherwise contains -1 */ @@ -99,10 +100,14 @@ struct IVAS_REND /* Ambisonics decoding matrix */ float *ambi_dec_mtx; + /* =========== MASA rendering handles/structs =========== */ + MASA_METADATA_FRAME masaMetadata; /* TODO @ Nokia: add more MASA related handles here if needed */ + /* Dummy decoders for binaural rendering */ DecoderDummy *decDummyAmbiBin; DecoderDummy *decDummyObjBin; DecoderDummy *decDummyMcBin; + DecoderDummy *decDummyMasaBin; /* Head rotation data */ int8_t enableHeadRotation; /* head rotation flag */ @@ -129,6 +134,11 @@ static void renderObjectsToAmbi( const IVAS_REND_AudioObjectMetadataBuffer metadataBuffer, IVAS_REND_AudioBuffer outAudio ); +static void renderMasaToAmbi( + IVAS_REND_HANDLE st, + const IVAS_REND_AudioBuffer inAudio, + IVAS_REND_AudioBuffer outAudio ); + static void renderAmbiToChannels( const IVAS_REND_HANDLE st, const IVAS_REND_AudioBuffer inAudio, @@ -145,6 +155,11 @@ static void renderObjectsToChannels( const IVAS_REND_AudioObjectMetadataBuffer metadataBuffer, IVAS_REND_AudioBuffer outAudio ); +static void renderMasaToChannels( + IVAS_REND_HANDLE st, + const IVAS_REND_AudioBuffer inAudio, + IVAS_REND_AudioBuffer outAudio ); + static void renderAmbiToBinaural( const IVAS_REND_HANDLE st, const IVAS_REND_AudioBuffer inAudio, @@ -161,6 +176,11 @@ static void renderObjectsToBinaural( const IVAS_REND_AudioObjectMetadataBuffer metadataBuffer, IVAS_REND_AudioBuffer outAudio ); +static void renderMasaToBinaural( + IVAS_REND_HANDLE st, + const IVAS_REND_AudioBuffer inAudio, + IVAS_REND_AudioBuffer outAudio ); + static void renderSingleObjectToAmbi( IVAS_REND_HANDLE st, const IVAS_REND_AudioBuffer inAudio, @@ -292,6 +312,7 @@ IVAS_REND_HANDLE IVAS_REND_Open() st->decDummyAmbiBin = NULL; st->decDummyMcBin = NULL; st->decDummyObjBin = NULL; + st->decDummyMasaBin = NULL; st->enableHeadRotation = 0; for ( i = 0; i < RENDERER_HEAD_POSITIONS_PER_FRAME; ++i ) @@ -311,6 +332,7 @@ static DecoderDummy *allocDecoderDummy( int32_t sampleRate, int16_t numOutChanne decDummy->hDecoderConfig = count_malloc( sizeof( DECODER_CONFIG ) ); decDummy->hDecoderConfig->output_Fs = sampleRate; decDummy->hDecoderConfig->nchan_out = numOutChannels; + decDummy->hDecoderConfig->Opt_Headrotation = enableHeadRotation; ivas_render_config_open( &decDummy->hRenderConfig ); decDummy->hRenderConfig->roomAcoustics.late_reverb_on = 0; @@ -341,6 +363,42 @@ static DecoderDummy *allocDecoderDummy( int32_t sampleRate, int16_t numOutChanne return decDummy; } +static ivas_error initDecoderDummyForMasaToAmbi( DecoderDummy *decDummyMasaAmbi, IVAS_REND_InputConfig inConfig ) +{ + ivas_error error; + error = IVAS_ERR_OK; + + /* TODO @ Nokia: set relevant members of decDummy */ + (void)decDummyMasaAmbi; + (void)inConfig; + + return error; +} + +static ivas_error initDecoderDummyForMasaToChannels( DecoderDummy *decDummyMasaChannels, IVAS_REND_InputConfig inConfig ) +{ + ivas_error error; + error = IVAS_ERR_OK; + + /* TODO @ Nokia: set relevant members of decDummy */ + (void)decDummyMasaChannels; + (void)inConfig; + + return error; +} + +static ivas_error initDecoderDummyForMasaToBinaural( DecoderDummy *decDummyMasaBin, IVAS_REND_InputConfig inConfig ) +{ + ivas_error error; + error = IVAS_ERR_OK; + + /* TODO @ Nokia: set relevant members of decDummy */ + (void)decDummyMasaBin; + (void)inConfig; + + return error; +} + static ivas_error initDecoderDummyForAmbiToBinaural( DecoderDummy *decDummyAmbiBin, IVAS_REND_InputConfig inConfig ) { ivas_error error; @@ -413,6 +471,7 @@ static ivas_error initDecoderDummyForMcToBinaural( DecoderDummy *decDummyMcBin, decDummyMcBin->hHrtf = NULL; decDummyMcBin->hHrtfTD = NULL; decDummyMcBin->hBinRenderer = NULL; + decDummyMcBin->hEFAPdata = NULL; decDummyMcBin->ivas_format = MC_FORMAT; decDummyMcBin->mc_mode = MC_MODE_MCT; @@ -505,7 +564,11 @@ ivas_error IVAS_REND_Configure( IVAS_REND_HANDLE st, /* ============================= Error checks ============================= */ assert( st != NULL && "Can't configure renderer - pointer is NULL" ); assert( !st->isConfigured && "Re-configuring a renderer is not supported" ); - assert( !( inConfig.numAudioObjects == 0 && inConfig.numMultiChannelBuses == 0 && inConfig.numAmbisonicsBuses == 0 ) && "At least one input must be active" ); + assert( !( inConfig.numAudioObjects == 0 && + inConfig.numMultiChannelBuses == 0 && + inConfig.numAmbisonicsBuses == 0 && + inConfig.numMasaBuses == 0 ) && + "At least one input must be active" ); numActiveOutputs = ( outConfig.ambisonics == IVAS_REND_AMBISONICS_NONE ? 0 : 1 ) + @@ -545,8 +608,11 @@ ivas_error IVAS_REND_Configure( IVAS_REND_HANDLE st, /* Save total number of channels of audio object inputs */ st->numInChannelsObj = st->inConfig.numAudioObjects; + /* Save total number of channels of MASA inputs */ + st->numInChannelsMasa = st->inConfig.numMasaBuses == 1 ? (int16_t) st->inConfig.masaBus.numTc : 0; + /* Save total number of input channels */ - st->numInChannels = st->numInChannelsObj + st->numInChannelsAmbi + st->numInChannelsMc; + st->numInChannels = st->numInChannelsObj + st->numInChannelsAmbi + st->numInChannelsMc + st->numInChannelsMasa; if ( st->outConfig.ambisonics != IVAS_REND_AMBISONICS_NONE ) { @@ -628,6 +694,37 @@ ivas_error IVAS_REND_Configure( IVAS_REND_HANDLE st, } } + /* Prepare MASA processing */ + if ( st->inConfig.numMasaBuses != 0 ) + { + st->decDummyMasaBin = allocDecoderDummy( st->sampleRate, st->numOutChannels, st->enableHeadRotation ); + + /* TODO @ Nokia: initialize decoder dummy for MASA rendering depending on output config. + Feel free to clean this up if some other structure works better. */ + if ( st->outConfig.ambisonics != IVAS_REND_AMBISONICS_NONE ) + { + if ( ( error = initDecoderDummyForMasaToAmbi( st->decDummyMasaBin, st->inConfig ) ) != IVAS_ERR_OK ) + { + return error; + } + } + else if ( st->outConfig.speakerLayout != IVAS_REND_SPEAKER_LAYOUT_NONE ) + { + if ( ( error = initDecoderDummyForMasaToChannels( st->decDummyMasaBin, st->inConfig ) ) != IVAS_ERR_OK ) + { + return error; + } + } + else if ( st->outConfig.binaural ) + { + if ( ( error = initDecoderDummyForMasaToBinaural( st->decDummyMasaBin, st->inConfig ) ) != IVAS_ERR_OK ) + { + return error; + } + } + } + + /* Prepare binaural rendering if enabled */ if ( st->outConfig.binaural ) { if ( headRotationEnabled ) @@ -702,6 +799,25 @@ void IVAS_REND_SetHeadRotation( } } +ivas_error IVAS_REND_FeedMasaMetadata( + IVAS_REND_HANDLE st, + IVAS_MASA_METADATA_HANDLE hMasaMetadata ) +{ + if ( !st->isConfigured ) + { + return IVAS_ERR_NOT_CONFIGURED; + } + + if ( st->inConfig.numMasaBuses == 0 ) + { + return IVAS_ERR_METADATA_NOT_EXPECTED; + } + + st->masaMetadata = *hMasaMetadata; + + return IVAS_ERR_OK; +} + void IVAS_REND_Render( IVAS_REND_HANDLE st, const IVAS_REND_AudioBuffer inAudio, @@ -744,6 +860,11 @@ void IVAS_REND_Render( { renderObjectsToAmbi( st, inAudio, metadataBuffer, outAudio ); } + + if ( st->inConfig.numMasaBuses != 0 ) + { + renderMasaToAmbi( st, inAudio, outAudio ); + } } /* Render target format: multichannel */ else if ( st->outConfig.speakerLayout != IVAS_REND_SPEAKER_LAYOUT_NONE ) { @@ -761,6 +882,11 @@ void IVAS_REND_Render( { renderObjectsToChannels( st, inAudio, metadataBuffer, outAudio ); } + + if ( st->inConfig.numMasaBuses != 0 ) + { + renderMasaToChannels( st, inAudio, outAudio ); + } } /* Render target format: binaural */ else if ( st->outConfig.binaural ) { @@ -783,6 +909,11 @@ void IVAS_REND_Render( { renderObjectsToBinaural( st, inAudio, metadataBuffer, outAudio ); } + + if ( st->inConfig.numMasaBuses != 0 ) + { + renderMasaToBinaural( st, inAudio, outAudio ); + } } /* Apply limiting in place */ @@ -956,6 +1087,10 @@ void IVAS_REND_Close( IVAS_REND_HANDLE *st ) { count_free( hIvasRend->decDummyMcBin->hHeadTrackData ); } + if ( hIvasRend->decDummyMcBin->hEFAPdata ) + { + efap_free_data( &hIvasRend->decDummyMcBin->hEFAPdata ); + } count_free( hIvasRend->decDummyMcBin ); } @@ -978,6 +1113,21 @@ void IVAS_REND_Close( IVAS_REND_HANDLE *st ) count_free( hIvasRend->decDummyObjBin ); } + if ( hIvasRend->decDummyMasaBin != NULL ) + { + ivas_render_config_close( &hIvasRend->decDummyMasaBin->hRenderConfig ); + count_free( hIvasRend->decDummyMasaBin->hDecoderConfig ); + + if ( hIvasRend->enableHeadRotation ) + { + count_free( hIvasRend->decDummyMasaBin->hHeadTrackData ); + } + + /* TODO @ Nokia: free any other memory allocated in the dummy decoder */ + + count_free( hIvasRend->decDummyMasaBin ); + } + ivas_limiter_close( &hIvasRend->hLimiter ); count_free( hIvasRend ); @@ -1033,6 +1183,57 @@ static float *get_smpl_ptr( IVAS_REND_AudioBuffer buffer, uint32_t chnlIdx, uint return buffer.data + chnlIdx * buffer.config.bufferSize + smplIdx; } +static void applyGainToBuffer( const IVAS_REND_AudioBuffer buffer, const uint32_t bufChIdx, float gain_lin ) +{ + int32_t smplIdx, chnlIdx; + float *smplPtr; + + /* TODO(sgi): Fix channel indexing - provide range of channels to be modified */ + /* Return early for now, this function is buggy */ + return; + + smplPtr = buffer.data + bufChIdx; + for ( chnlIdx = 0; chnlIdx < buffer.config.numChannels; ++chnlIdx ) + { + for ( smplIdx = 0; smplIdx < buffer.config.bufferSize; ++smplIdx ) + { + *smplPtr++ *= gain_lin; + } + } +} + +static void copyBufferTo2dArray( const IVAS_REND_AudioBuffer buffer, const uint32_t chInIdx, const uint32_t numCh, float array[MAX_OUTPUT_CHANNELS][L_FRAME48k] ) +{ + int32_t smplIdx; + uint32_t chnlIdx; + const float *readPtr; + + readPtr = buffer.data + chInIdx * buffer.config.bufferSize; + for ( chnlIdx = 0; chnlIdx < numCh; ++chnlIdx ) + { + for ( smplIdx = 0; smplIdx < buffer.config.bufferSize; ++smplIdx ) + { + array[chnlIdx][smplIdx] = *readPtr++; + } + } +} + +static void copy2dArrayToBuffer( float array[MAX_OUTPUT_CHANNELS][L_FRAME48k], IVAS_REND_AudioBuffer *buffer, const uint32_t chOutIdx, const uint32_t numCh ) +{ + int32_t smplIdx; + uint32_t chnlIdx; + float *writePtr; + + writePtr = buffer->data + chOutIdx * buffer->config.bufferSize; + for ( chnlIdx = 0; chnlIdx < numCh; ++chnlIdx ) + { + for ( smplIdx = 0; smplIdx < buffer->config.bufferSize; ++smplIdx ) + { + *writePtr++ = array[chnlIdx][smplIdx]; + } + } +} + static void renderAmbiToAmbi( const IVAS_REND_HANDLE st, const IVAS_REND_AudioBuffer inAudio, IVAS_REND_AudioBuffer outAudio ) @@ -1208,6 +1409,27 @@ static void renderObjectsToAmbi( #endif } +static void renderMasaToAmbi( + IVAS_REND_HANDLE st, + const IVAS_REND_AudioBuffer inAudio, + IVAS_REND_AudioBuffer outAudio ) +{ + uint32_t inMasaChannelIdx; + float gain_lin; + float tmpBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; + + inMasaChannelIdx = st->inConfig.masaBus.inputChannelIndex; + gain_lin = dBToLin( st->inConfig.masaBus.gain_dB ); + + applyGainToBuffer( inAudio, inMasaChannelIdx, gain_lin ); + copyBufferTo2dArray( inAudio, inMasaChannelIdx, st->numInChannelsMasa, tmpBuffer ); + + /* TODO @ Nokia: Process audio in-place in tmpBuffer. MASA metadata for current frame already available in st->masaMetadata. */ + memset( tmpBuffer, 0, sizeof( tmpBuffer ) ); + + copy2dArrayToBuffer( tmpBuffer, &outAudio, 0, st->numOutChannels ); +} + static void renderAmbiToChannels( const IVAS_REND_HANDLE st, const IVAS_REND_AudioBuffer inAudio, IVAS_REND_AudioBuffer outAudio ) @@ -1417,51 +1639,6 @@ static void renderObjectsToChannels( #endif } -static void applyGainToBuffer( const IVAS_REND_AudioBuffer buffer, const uint32_t bufChIdx, float gain_lin ) -{ - int32_t smplIdx, chnlIdx; - float *smplPtr; - - smplPtr = buffer.data + bufChIdx; - for ( chnlIdx = 0; chnlIdx < buffer.config.numChannels; ++chnlIdx ) - { - for ( smplIdx = 0; smplIdx < buffer.config.bufferSize; ++smplIdx ) - { - *smplPtr++ *= gain_lin; - } - } -} - -static void copyBufferTo2dArray( const IVAS_REND_AudioBuffer buffer, const uint32_t bufChIdx, float array[MAX_OUTPUT_CHANNELS][L_FRAME48k] ) -{ - int32_t smplIdx, chnlIdx; - const float *readPtr; - - readPtr = buffer.data + bufChIdx; - for ( chnlIdx = 0; chnlIdx < buffer.config.numChannels; ++chnlIdx ) - { - for ( smplIdx = 0; smplIdx < buffer.config.bufferSize; ++smplIdx ) - { - array[chnlIdx][smplIdx] = *readPtr++; - } - } -} - -static void copy2dArrayToBuffer( float array[MAX_OUTPUT_CHANNELS][L_FRAME48k], IVAS_REND_AudioBuffer *buffer, const uint32_t bufChIdx ) -{ - int32_t smplIdx, chnlIdx; - float *writePtr; - - writePtr = buffer->data + bufChIdx; - for ( chnlIdx = 0; chnlIdx < buffer->config.numChannels; ++chnlIdx ) - { - for ( smplIdx = 0; smplIdx < buffer->config.bufferSize; ++smplIdx ) - { - *writePtr++ = array[chnlIdx][smplIdx]; - } - } -} - static void copyHeadRotToDecDummy( const IVAS_QUATERNION *headRot, DecoderDummy *decDummy ) { int16_t i; @@ -1482,6 +1659,27 @@ static void copyHeadRotToDecDummy( const IVAS_QUATERNION *headRot, DecoderDummy decDummy->hDecoderConfig->Opt_Headrotation = 0; } +static void renderMasaToChannels( + IVAS_REND_HANDLE st, + const IVAS_REND_AudioBuffer inAudio, + IVAS_REND_AudioBuffer outAudio ) +{ + uint32_t inMasaChannelIdx; + float gain_lin; + float tmpBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; + + inMasaChannelIdx = st->inConfig.masaBus.inputChannelIndex; + gain_lin = dBToLin( st->inConfig.masaBus.gain_dB ); + + applyGainToBuffer( inAudio, inMasaChannelIdx, gain_lin ); + copyBufferTo2dArray( inAudio, inMasaChannelIdx, st->numInChannelsMasa, tmpBuffer ); + + /* TODO @ Nokia: Process audio in-place in tmpBuffer. MASA metadata for current frame already available in st->masaMetadata. */ + memset( tmpBuffer, 0, sizeof( tmpBuffer ) ); + + copy2dArrayToBuffer( tmpBuffer, &outAudio, 0, st->numOutChannels ); +} + static void renderAmbiToBinaural( const IVAS_REND_HANDLE st, const IVAS_REND_AudioBuffer inAudio, @@ -1493,6 +1691,7 @@ static void renderAmbiToBinaural( uint32_t inAmbiChannelIdx; float tmpBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; float gain_lin; + int32_t numInChannels; #ifdef WMOPS wmops_sub_start( "renderAmbiToBinaural" ); @@ -1508,9 +1707,10 @@ static void renderAmbiToBinaural( { inAmbiChannelIdx = st->inConfig.ambisonicsBuses[ambiIdx].inputChannelIndex; gain_lin = dBToLin( st->inConfig.ambisonicsBuses[ambiIdx].gain_dB ); + numInChannels = getNumChannelsAmbisonics( st->inConfig.ambisonicsBuses[ambiIdx].ambisonicsConfig ); applyGainToBuffer( inAudio, inAmbiChannelIdx, gain_lin ); - copyBufferTo2dArray( inAudio, inAmbiChannelIdx, tmpBuffer ); + copyBufferTo2dArray( inAudio, inAmbiChannelIdx, numInChannels, tmpBuffer ); if ( st->enableHeadRotation ) { @@ -1522,7 +1722,7 @@ static void renderAmbiToBinaural( ivas_crend_process( st->decDummyAmbiBin, tmpBuffer ); - copy2dArrayToBuffer( tmpBuffer, &outAudio, inAmbiChannelIdx ); + copy2dArrayToBuffer( tmpBuffer, &outAudio, 0, st->numOutChannels ); } @@ -1545,6 +1745,7 @@ static void renderChannelsToBinaural( float tmpLfeBuffer[L_FRAME48k]; float tmpBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; float gain_lin; + int32_t numInChannels; #ifdef WMOPS wmops_sub_start( "renderChannelsToBinaural" ); @@ -1560,9 +1761,10 @@ static void renderChannelsToBinaural( { inMcChannelIdx = st->inConfig.multiChannelBuses[mcIdx].inputChannelIndex; gain_lin = dBToLin( st->inConfig.multiChannelBuses[mcIdx].gain_dB ); + numInChannels = getNumChannelsInSpeakerLayout( st->inConfig.multiChannelBuses[mcIdx].speakerLayout ); applyGainToBuffer( inAudio, inMcChannelIdx, gain_lin ); - copyBufferTo2dArray( inAudio, inMcChannelIdx, tmpBuffer ); + copyBufferTo2dArray( inAudio, inMcChannelIdx, numInChannels, tmpBuffer ); /* Rotation in spatial domain */ if ( st->enableHeadRotation ) @@ -1602,7 +1804,7 @@ static void renderChannelsToBinaural( mvr2r( &tmpLfeBuffer[lfeLpDelay], &tmpBuffer[lfeChIdx][0], L_FRAME48k - lfeLpDelay ); ivas_binaural_add_LFE( st->decDummyMcBin, L_FRAME48k, tmpBuffer ); - copy2dArrayToBuffer( tmpBuffer, &outAudio, inMcChannelIdx ); + copy2dArrayToBuffer( tmpBuffer, &outAudio, 0, st->numOutChannels ); } @@ -1621,6 +1823,7 @@ static void renderObjectsToBinaural( int16_t tmpAzi, tmpEle; float tmpBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; float gain_lin; + uint32_t inIsmIdx; #ifdef WMOPS wmops_sub_start( "renderObjectsToBinaural" ); @@ -1658,21 +1861,46 @@ static void renderObjectsToBinaural( st->decDummyObjBin->hIsmMetaData[objIdx]->azimuth = (float) tmpAzi; st->decDummyObjBin->hIsmMetaData[objIdx]->elevation = (float) tmpEle; } + + inIsmIdx = st->inConfig.audioObjects[objIdx].inputChannelIndex; + + /* Copy input audio to tmp buffer for processing */ + copyBufferTo2dArray( inAudio, inIsmIdx, 1, &tmpBuffer[objIdx] ); } /* TODO tmu : enable per-object gains */ gain_lin = dBToLin( st->inConfig.audioObjects[0].gain_dB ); applyGainToBuffer( inAudio, 0, gain_lin ); - copyBufferTo2dArray( inAudio, 0, tmpBuffer ); ObjRenderIVASFrame( st->decDummyObjBin, tmpBuffer, inAudio.config.bufferSize ); - copy2dArrayToBuffer( tmpBuffer, &outAudio, 0 ); + copy2dArrayToBuffer( tmpBuffer, &outAudio, 0, st->numOutChannels ); #ifdef WMOPS wmops_sub_end(); #endif } +static void renderMasaToBinaural( + IVAS_REND_HANDLE st, + const IVAS_REND_AudioBuffer inAudio, + IVAS_REND_AudioBuffer outAudio ) +{ + uint32_t inMasaChannelIdx; + float gain_lin; + float tmpBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; + + inMasaChannelIdx = st->inConfig.masaBus.inputChannelIndex; + gain_lin = dBToLin( st->inConfig.masaBus.gain_dB ); + + applyGainToBuffer( inAudio, inMasaChannelIdx, gain_lin ); + copyBufferTo2dArray( inAudio, inMasaChannelIdx, st->numInChannelsMasa, tmpBuffer ); + + /* TODO @ Nokia: Process audio in-place in tmpBuffer. MASA metadata for current frame already available in st->masaMetadata. */ + memset( tmpBuffer, 0, sizeof( tmpBuffer ) ); + + copy2dArrayToBuffer( tmpBuffer, &outAudio, 0, st->numOutChannels ); +} + static void renderSingleObjectToAmbi( IVAS_REND_HANDLE st, const IVAS_REND_AudioBuffer inAudio, diff --git a/lib_rend/lib_rend.h b/lib_rend/lib_rend.h index 536a6da997..5b8f42f2da 100644 --- a/lib_rend/lib_rend.h +++ b/lib_rend/lib_rend.h @@ -44,6 +44,7 @@ #define RENDERER_MAX_ISM_INPUTS 4 #define RENDERER_MAX_MC_INPUTS 1 #define RENDERER_MAX_SBA_INPUTS 1 +#define RENDERER_MAX_MASA_INPUTS 1 #define RENDERER_HEAD_POSITIONS_PER_FRAME 4 @@ -69,6 +70,13 @@ typedef enum IVAS_REND_SpeakerLayout IVAS_REND_SPEAKER_LAYOUT_7_1_4 = 19 } IVAS_REND_SpeakerLayout; /* Numerical value corresponds to CICP index */ +typedef enum IVAS_REND_MasaTc +{ + IVAS_REND_MASA_TC_NONE = -1, + IVAS_REND_MASA_TC_1 = 1, + IVAS_REND_MASA_TC_2 = 2, +} IVAS_REND_MasaTc; /* Numerical value corresponds to number of transport channels */ + typedef struct IVAS_REND_AudioObjectPosition { float azimuth; @@ -107,6 +115,13 @@ typedef struct IVAS_REND_MultiChannelBus float gain_dB; } IVAS_REND_MultiChannelBus; +typedef struct IVAS_REND_MasaBus +{ + IVAS_REND_MasaTc numTc; + uint8_t inputChannelIndex; + float gain_dB; +} IVAS_REND_MasaBus; + typedef struct IVAS_REND_AudioBufferConfig { int32_t sampleRate; @@ -129,6 +144,8 @@ typedef struct IVAS_REND_InputConfig IVAS_REND_AmbisonicsBus ambisonicsBuses[RENDERER_MAX_SBA_INPUTS]; uint16_t numAmbisonicsBuses; IVAS_LSSETUP_CUSTOM_HANDLE inSetupCustom; + IVAS_REND_MasaBus masaBus; /* Support one MASA input for now. Multiple inputs will be easier to implement after API rework. */ + uint16_t numMasaBuses; /* Keep for framework consistency for now. Again - this will not be necessary after API rework */ } IVAS_REND_InputConfig; typedef struct IVAS_REND_OutputConfig @@ -167,6 +184,11 @@ void IVAS_REND_SetHeadRotation( const IVAS_QUATERNION headRot[RENDERER_HEAD_POSITIONS_PER_FRAME] ); +ivas_error IVAS_REND_FeedMasaMetadata( + IVAS_REND_HANDLE st, + IVAS_MASA_METADATA_HANDLE hMasaMetadata +); + /*! Renders one frame of audio samples */ void IVAS_REND_Render( IVAS_REND_HANDLE st, /* i : Renderer state */ diff --git a/scripts/pyaudio3dtools/binauralrenderer.py b/scripts/pyaudio3dtools/binauralrenderer.py index 52fc800242..d34d59babe 100644 --- a/scripts/pyaudio3dtools/binauralrenderer.py +++ b/scripts/pyaudio3dtools/binauralrenderer.py @@ -394,7 +394,8 @@ def binaural_fftconv_framewise( y = np.zeros([sig_len + T_rev, 2]) y0 = np.zeros([N_rev, sig_len + T_rev, 2]) - fade_in = np.linspace(0.0, 1.0, frame_len, endpoint=False) + fade_in = np.arange(frame_len) / (frame_len - 1) + fade_in = fade_in[:, np.newaxis] fade_out = 1.0 - fade_in for i_ear in [0, 1]: diff --git a/scripts/pyaudio3dtools/rotation.py b/scripts/pyaudio3dtools/rotation.py index 0457f6b8e9..4e94a640ad 100644 --- a/scripts/pyaudio3dtools/rotation.py +++ b/scripts/pyaudio3dtools/rotation.py @@ -228,7 +228,8 @@ def rotateHOA(x: np.ndarray, trajectory: str) -> np.ndarray: y = np.zeros([sig_len, sig_dim]) - fade_in = np.linspace(0, 1.0, frame_len, endpoint=False)[:, np.newaxis] + fade_in = np.arange(frame_len) / (frame_len - 1) + fade_in = fade_in[:, np.newaxis] fade_out = 1.0 - fade_in R = np.eye(sig_dim) @@ -311,7 +312,8 @@ def rotateMC(x: np.ndarray, trajectory: str, layout: spatialaudioformat) -> np.n # TODO LFE handling here panner = EFAP.EFAP(layout.ls_azi, layout.ls_ele) - fade_in = np.linspace(0, 1.0, frame_len, endpoint=False)[:, np.newaxis] + fade_in = np.arange(frame_len) / (frame_len - 1) + fade_in = fade_in[:, np.newaxis] fade_out = 1.0 - fade_in R = np.eye(layout.nchannels) diff --git a/scripts/pyaudio3dtools/spatialaudioconvert.py b/scripts/pyaudio3dtools/spatialaudioconvert.py index 259a01159e..3d4a4d95d5 100644 --- a/scripts/pyaudio3dtools/spatialaudioconvert.py +++ b/scripts/pyaudio3dtools/spatialaudioconvert.py @@ -401,7 +401,8 @@ def convert_ism( out_sig = np.zeros([sig_len, out_spfmt.nchannels]) - fade_in = np.linspace(0, 1.0, frame_len, endpoint=False)[:, np.newaxis] + fade_in = np.arange(frame_len) / (frame_len - 1) + fade_in = fade_in[:, np.newaxis] fade_out = 1.0 - fade_in if out_spfmt.isloudspeaker: diff --git a/scripts/tests/constants.py b/scripts/tests/constants.py index 07a5cbc5a9..8345dc6f4b 100644 --- a/scripts/tests/constants.py +++ b/scripts/tests/constants.py @@ -51,8 +51,9 @@ RENDERER_CMD = [ "", # 8 -> output format "-fs", "48", # 10 -> input fs - "-q", + # "--no_delay_cmp", # "-ndl", + "-q", ] """ Format to file mappings """ @@ -96,7 +97,6 @@ FORMAT_TO_FILE = { # "MASA1": TEST_VECTOR_DIR.joinpath("stv_IVASMASA_1dir1TC.pcm"), # "MASA2": TEST_VECTOR_DIR.joinpath("stv_IVASMASA_2dir2TC.pcm"), "META": TEST_VECTOR_DIR.joinpath("mixed_scene.txt"), - # Custom loudspeaker inputs (WIP) "16ch_8+4+4": NCHAN_TO_FILE[16], "4d0": NCHAN_TO_FILE[4], "4d4": NCHAN_TO_FILE[8], @@ -164,6 +164,7 @@ CUSTOM_LS_TO_TEST = [ """ Mixed scene ( metadata ) rendering """ METADATA_SCENES_TO_TEST = ["mixed_scene"] +METADATA_SCENES_TO_TEST_NO_BE = ["masa_scene"] """ Binaural rendering """ INPUT_FORMATS_BINAURAL = OUTPUT_FORMATS[2:] diff --git a/scripts/tests/data/masa_scene.txt b/scripts/tests/data/masa_scene.txt new file mode 100644 index 0000000000..46baa475c1 --- /dev/null +++ b/scripts/tests/data/masa_scene.txt @@ -0,0 +1,6 @@ +stv_IVASMASA_2dir2TC.wav +1 +MASA +1 +2 +stv_IVASMASA_2dir2TC.met diff --git a/scripts/tests/data/renderer_config_format_readme.txt b/scripts/tests/data/renderer_config_format_readme.txt index 790d52bfc5..adf4f01362 100644 --- a/scripts/tests/data/renderer_config_format_readme.txt +++ b/scripts/tests/data/renderer_config_format_readme.txt @@ -31,9 +31,9 @@ *******************************************************************************************************/ -######################## Pre-renderer config file format ######################## +########################## Renderer config file format ########################## -To run, the pre-renderer requires a config file describing the input scene. +To run, the renderer requires a config file describing the input scene. The expected format of the config file is as follows: ------------------------------------ Line 1: ------------------------------------ @@ -52,10 +52,11 @@ object or a channel bed. This is NOT the total number of channels in the input audio file. -The pre-renderer currently supports simultaneously: - * Up to 2 SBA inputs - * Up to 2 MC inputs - * Up to 16 ISM inputs +The renderer currently supports simultaneously: + * 1 SBA input + * 1 MC input + * 1 MASA input + * Up to 4 ISM inputs These limits can be freely changed with pre-processor macros, if needed. @@ -76,6 +77,11 @@ MC Index of the first channel of this input in the multitrack file (1-indexed) Name of speaker layout (X_Y_Z or CICPx format) +MASA +Index of the first channel of this input in the multitrack file (1-indexed) +Number of transport channels +Path to MASA metadata file (must be relative to config file location) + ISM Index of this input's audio in the multitrack file (1-indexed) Path to ISM metadata file (must be relative to config file location) diff --git a/scripts/tests/data/stv_IVASMASA_2dir2TC.wav b/scripts/tests/data/stv_IVASMASA_2dir2TC.wav new file mode 100644 index 0000000000..e159c4f9ae --- /dev/null +++ b/scripts/tests/data/stv_IVASMASA_2dir2TC.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:60a713ed1b97cf94b16849806951ef83d8f41c8ee455b267ec0a292c695cbbc1 +size 576044 diff --git a/scripts/tests/test_renderer.py b/scripts/tests/test_renderer.py index d976f8f210..8159832aa1 100644 --- a/scripts/tests/test_renderer.py +++ b/scripts/tests/test_renderer.py @@ -233,16 +233,19 @@ def test_ism(in_fmt, out_fmt): in_meta_files=FORMAT_TO_METADATA_FILES[in_fmt], ) + # ISM to Ambisonics has differences due to optimizations in ivas_dirac_dec_get_response() + # additionally, positions parsed from the metadata files in C seem to be different + # due to (float) atof() reading being subsequently cast to int16_t check_BE(ref, ref_fs, cut, cut_fs, snr_min=38) -@pytest.mark.skip(reason="MASA rendering is currently not implemented") @pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS) @pytest.mark.parametrize("in_fmt", INPUT_FORMATS_MASA) def test_masa(in_fmt, out_fmt): - ref, ref_fs = run_pyscripts( - in_fmt, out_fmt, in_meta_files=FORMAT_TO_METADATA_FILES[in_fmt] - ) + # TODO: implement MASA in Python, compare BE + # ref, ref_fs = run_pyscripts( + # in_fmt, out_fmt, in_meta_files=FORMAT_TO_METADATA_FILES[in_fmt] + # ) cut, cut_fs = run_renderer( in_fmt, @@ -250,7 +253,7 @@ def test_masa(in_fmt, out_fmt): in_meta_files=FORMAT_TO_METADATA_FILES[in_fmt], ) - check_BE(ref, ref_fs, cut, cut_fs) + # check_BE(ref, ref_fs, cut, cut_fs) @pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS) @@ -268,6 +271,16 @@ def test_metadata(in_fmt, out_fmt): check_BE(ref, ref_fs, cut, cut_fs, snr_min=11) +@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS) +@pytest.mark.parametrize("in_fmt", METADATA_SCENES_TO_TEST_NO_BE) +def test_metadata_masa(in_fmt, out_fmt): + # TODO: unify with test_metadata once Python supports MASA + cut, cut_fs = run_renderer( + "META", + out_fmt, + metadata_input=TEST_VECTOR_DIR.joinpath(f"{in_fmt}.txt"), + ) + # Binaural rendering (static) @pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL) -- GitLab From 6f84f648942d451472beda349e21214c6f8f2a92 Mon Sep 17 00:00:00 2001 From: Kacper Sagnowski Date: Thu, 18 Aug 2022 13:23:17 +0200 Subject: [PATCH 004/101] Update external renderer Updates include: - Fix for raw PCM input - Fix for build with Make on some platforms - Implementation of BINAURAL_ROOM output config --- Makefile | 2 +- apps/renderer.c | 56 +-- lib_com/ivas_prot.h | 10 + lib_rend/ivas_sba_rendering.c | 8 +- lib_rend/lib_rend.c | 416 ++++++++++++++------ lib_rend/lib_rend.h | 20 +- scripts/tests/constants.py | 5 +- scripts/tests/data/masa_scene.txt | 2 +- scripts/tests/data/stv_IVASMASA_2dir2TC.wav | 3 - scripts/tests/test_renderer.py | 36 +- 10 files changed, 378 insertions(+), 180 deletions(-) delete mode 100644 scripts/tests/data/stv_IVASMASA_2dir2TC.wav diff --git a/Makefile b/Makefile index e2bdf99b86..9514e9a582 100644 --- a/Makefile +++ b/Makefile @@ -185,7 +185,7 @@ $(CLI_APIDEC): $(OBJS_CLI_APIDEC) $(LIB_LIBDEC) $(LIB_LIBCOM) $(LIB_LIBUTIL) $(L $(QUIET_LINK)$(CC) $(LDFLAGS) $(OBJS_CLI_APIDEC) -L. -livasdec -livascom -livasutil -livasdebug $(LDLIBS) -o $(CLI_APIDEC) $(CLI_APIREND): $(OBJS_CLI_APPREND) $(LIB_LIBREND) $(LIB_LIBCOM) $(LIB_LIBUTIL) $(LIB_LIBDEBUG) - $(QUIET_LINK)$(CC) $(LDFLAGS) $(OBJS_CLI_APPREND) -L. -livasrend -livasutil -livascom -livasdebug $(LDLIBS) -o $(CLI_APIREND) + $(QUIET_LINK)$(CC) $(LDFLAGS) $(OBJS_CLI_APPREND) -L. -livasrend -livasutil -livasdebug -livascom $(LDLIBS) -o $(CLI_APIREND) $(CLI_UTESTS_CREND): $(OBJS_CLI_UTESTS_CREND) $(LIB_LIBDEC) $(LIB_LIBCOM) $(LIB_LIBUTIL) $(LIB_LIBDEBUG) $(QUIET_LINK)$(CC) $(LDFLAGS) $(OBJS_CLI_UTESTS_CREND) -L. -livasdec -livascom -livasutil -livasdebug $(LDLIBS) -o $(UTESTS_CREND_DIR)/$(CLI_UTESTS_CREND) diff --git a/apps/renderer.c b/apps/renderer.c index 38f1a7c16c..4ffa2ed427 100644 --- a/apps/renderer.c +++ b/apps/renderer.c @@ -168,7 +168,6 @@ typedef struct CmdlnArgs } CmdlnArgs; static int8_t setInConfig( - int16_t numChannels, AUDIO_CONFIG input_config, IVAS_REND_InputConfig *inConfig, IsmPositionProvider *positionProvider ); @@ -307,7 +306,6 @@ int32_t main( int32_t argc, char **argv ) char audioFilePath[FILENAME_MAX]; char masaMetadataFilePath[FILENAME_MAX]; AudioFileReader *audioReader = NULL; - int16_t numInChannels; AudioFileWriter *audioWriter; int16_t inBufferSize; int32_t outBufferSize; @@ -392,19 +390,12 @@ int32_t main( int32_t argc, char **argv ) if ( args.inputFormat != AUDIO_CONFIG_INVALID ) { - numInChannels = AudioFileReader_getNumChannels( audioReader ); - if ( numInChannels == 0 ) - { - fprintf( stderr, "File does not contain number of channels metadata, probably a raw file: %s\n", audioFilePath ); - exit( -1 ); - } - for ( i = 0; i < args.numAudioObjects; i++ ) { positionProvider->ismReaders[i] = IsmFileReader_open( args.metaDataFiles[i] ); } - if ( setInConfig( numInChannels, args.inputFormat, &args.inConfig, positionProvider ) != 0 ) + if ( setInConfig( args.inputFormat, &args.inConfig, positionProvider ) != 0 ) { fprintf( stderr, "File cannot be used: %s\n", audioFilePath ); exit( -1 ); @@ -412,7 +403,7 @@ int32_t main( int32_t argc, char **argv ) } /* === Configure === */ - if ( ( error = IVAS_REND_Configure( hIvasRend, args.inConfig, args.outConfig, args.sampleRate, args.trajectoryFile[0] != '\0' ) ) != IVAS_ERR_OK ) + if ( ( error = IVAS_REND_Configure( hIvasRend, args.inConfig, args.outConfig, args.sampleRate, args.trajectoryFile[0] != '\0', args.renderConfigFile[0] != '\0' ) ) != IVAS_ERR_OK ) { exit( -1 ); } @@ -422,7 +413,8 @@ int32_t main( int32_t argc, char **argv ) IVAS_REND_SetNeverDropLfe( hIvasRend, 1 ); } - if ( IVAS_REND_GetInChannels( hIvasRend ) != AudioFileReader_getNumChannels( audioReader ) ) + if ( AudioFileReader_getNumChannels( audioReader ) != 0 /* If input file is raw PCM, audio reader has no info about number of channels */ + && IVAS_REND_GetInChannels( hIvasRend ) != AudioFileReader_getNumChannels( audioReader ) ) { fprintf( stderr, "Number of channels in input file does not match selected configuration\n" ); exit( -1 ); @@ -523,7 +515,7 @@ int32_t main( int32_t argc, char **argv ) { MasaFileReader_readNextFrame( masaReader ); - if ( ( error = IVAS_REND_FeedMasaMetadata(hIvasRend, hMasaMetadata) ) != IVAS_ERR_OK ) + if ( ( error = IVAS_REND_FeedMasaMetadata( hIvasRend, hMasaMetadata ) ) != IVAS_ERR_OK ) { fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); exit( -1 ); @@ -645,7 +637,7 @@ int32_t main( int32_t argc, char **argv ) return 0; } -static int8_t setInConfig( int16_t numChannels, AUDIO_CONFIG input_config, IVAS_REND_InputConfig *inConfig, IsmPositionProvider *positionProvider ) +static int8_t setInConfig( AUDIO_CONFIG input_config, IVAS_REND_InputConfig *inConfig, IsmPositionProvider *positionProvider ) { int8_t success; /* flag */ int16_t i; @@ -690,10 +682,10 @@ static int8_t setInConfig( int16_t numChannels, AUDIO_CONFIG input_config, IVAS_ case AUDIO_CONFIG_ISM2: case AUDIO_CONFIG_ISM3: case AUDIO_CONFIG_ISM4: - inConfig->numAudioObjects = numChannels; - positionProvider->numObjects = numChannels; + inConfig->numAudioObjects = input_config - AUDIO_CONFIG_ISM1 + 1; /* TODO(sgi): Don't do arithemtic on enums, find a better way */ + positionProvider->numObjects = inConfig->numAudioObjects; - for ( i = 0; i < numChannels; ++i ) + for ( i = 0; i < inConfig->numAudioObjects; ++i ) { inConfig->audioObjects[i].inputChannelIndex = i; inConfig->audioObjects[i].gain_dB = 0; @@ -765,6 +757,20 @@ static IVAS_REND_Ambisonics audioCfgToAmbiEnum( AUDIO_CONFIG cfg ) return IVAS_REND_AMBISONICS_NONE; } +static IVAS_REND_BinauralFormat audioCfgToBinauralEnum( AUDIO_CONFIG cfg ) +{ + if ( cfg == AUDIO_CONFIG_BINAURAL ) + { + return IVAS_REND_BINAURAL_DIRECT; + } + else if ( cfg == AUDIO_CONFIG_BINAURAL_ROOM ) + { + return IVAS_REND_BINAURAL_ROOM; + } + + return IVAS_REND_BINAURAL_NONE; +} + static IVAS_REND_MasaTc audioCfgToMasaEnum( AUDIO_CONFIG cfg ) { switch ( cfg ) @@ -895,7 +901,7 @@ static AUDIO_CONFIG parseStrToAudioCfg( char *config_str ) else if ( strncmp( format, "ISM", 3 ) == 0 ) { parseUint8( &format[3], &numObjects ); - return AUDIO_CONFIG_ISM1 + numObjects - 1; + return AUDIO_CONFIG_ISM1 + numObjects - 1; /* TODO(sgi): Don't do arithemtic on enums, find a better way */ } else if ( strncmp( format, "MASA", 4 ) == 0 ) { @@ -1024,7 +1030,7 @@ static int8_t parseOutConfig( char *configString, IVAS_REND_OutputConfig *outCon break; case AUDIO_CONFIG_BINAURAL: case AUDIO_CONFIG_BINAURAL_ROOM: - outConfig->binaural = 1; + outConfig->binauralFormat = audioCfgToBinauralEnum( outCfg ); break; case AUDIO_CONFIG_META: /* handled by parseConfigFile() */ @@ -1116,24 +1122,18 @@ static CmdlnArgs defaultArgs( void ) args.outputFilePath[0] = '\0'; args.sampleRate = -1; -#ifdef RAM_COUNTING_TOOL - /* Zero-initialize entire input and output config struct. This is only needed when RAM counting - is active - when freeing memory, it reads all bytes from these structs, which results in msan - failures without full initialization. Without RAM counting the uninitialized struct members will - not be accessed. */ - memset( &args.inConfig, 0, sizeof( args.inConfig ) ); - memset( &args.outConfig, 0, sizeof( args.outConfig ) ); -#endif args.inConfig.inSetupCustom = NULL; args.inConfig.numAudioObjects = 0; args.inConfig.numAmbisonicsBuses = 0; args.inConfig.numMultiChannelBuses = 0; + args.inConfig.numMasaBuses = 0; args.outConfig.ambisonics = IVAS_REND_AMBISONICS_NONE; args.outConfig.speakerLayout = IVAS_REND_SPEAKER_LAYOUT_NONE; args.outConfig.outSetupCustom = NULL; - args.outConfig.binaural = 0; + args.outConfig.binauralFormat = IVAS_REND_BINAURAL_NONE; + args.orientationTracking = IVAS_ORIENT_TRK_REF; args.trajectoryFile[0] = '\0'; args.customHrtfFile[0] = '\0'; diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index 576bf1c684..a125d558a3 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -3099,6 +3099,16 @@ ivas_error ivas_sba_get_hoa_dec_matrix( const int16_t ambisonics_order /* i : Ambisonics order */ ); +#ifdef EXT_RENDERER +void ivas_sba_mtx_mult( + float output_f[][L_FRAME48k], /* i/o: synthesized core-corder transport channels/DirAC output */ + const int16_t output_frame, /* i : frame length per channel */ + const int16_t nchan_in, /* i : Number of ambisonic channels */ + IVAS_OUTPUT_SETUP output_setup, /* i : Output configuration */ + const float *mtx_hoa_decoder /* o : HOA decoding matrix */ +); +#endif + /*----------------------------------------------------------------------------------* * DirAC prototypes *----------------------------------------------------------------------------------*/ diff --git a/lib_rend/ivas_sba_rendering.c b/lib_rend/ivas_sba_rendering.c index 1e8b61caca..dbcec392a5 100644 --- a/lib_rend/ivas_sba_rendering.c +++ b/lib_rend/ivas_sba_rendering.c @@ -46,7 +46,9 @@ * Local function prototypes *-----------------------------------------------------------------------*/ +#ifndef EXT_RENDERER static void ivas_sba_mtx_mult( float output_f[][L_FRAME48k], const int16_t output_frame, const int16_t nchan_in, IVAS_OUTPUT_SETUP output_setup, const float *mtx_hoa_decoder ); +#endif static void ivas_sba_dmx_dec( float sba_data[][L_FRAME48k], const int16_t nchan_transport, const int16_t output_frame ); #ifdef DEBUG_MODE_DIRAC @@ -530,12 +532,16 @@ ivas_error ivas_sba_linear_renderer( * HOA decoding with LFE insertion *-------------------------------------------------------------------*/ +#ifdef EXT_RENDERER +void ivas_sba_mtx_mult( +#else static void ivas_sba_mtx_mult( +#endif float output_f[][L_FRAME48k], /* i/o: synthesized core-coder transport channels/DirAC output */ const int16_t output_frame, /* i : output frame length per channel */ const int16_t nchan_in, /* i : Number of ambisonic channels */ IVAS_OUTPUT_SETUP output_setup, /* i : Output configuration */ - const float *mtx_hoa_decoder /* i : Hoa decoding mtx */ + const float *mtx_hoa_decoder /* o : HOA decoding mtx */ ) { int16_t i, k, ch_idx; diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index 903e27fe19..18f556a56f 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -112,6 +112,9 @@ struct IVAS_REND /* Head rotation data */ int8_t enableHeadRotation; /* head rotation flag */ IVAS_QUATERNION headRotationData[RENDERER_HEAD_POSITIONS_PER_FRAME]; + + /* Configurable rendering */ + int8_t rendererConfigEnabled; }; /*---------------------------------------------------------------------* @@ -279,6 +282,9 @@ static float dBToLin( const float gain_dB ); static AUDIO_CONFIG mapRendLayoutToAudioConfig( IVAS_REND_SpeakerLayout speakerLayout ); +static AUDIO_CONFIG mapRendAmbisonicsToAudioConfig( + IVAS_REND_Ambisonics ambisonics ); + /* clang-on */ /* ========================================================================== */ @@ -314,6 +320,7 @@ IVAS_REND_HANDLE IVAS_REND_Open() st->decDummyObjBin = NULL; st->decDummyMasaBin = NULL; st->enableHeadRotation = 0; + st->rendererConfigEnabled = 0; for ( i = 0; i < RENDERER_HEAD_POSITIONS_PER_FRAME; ++i ) { @@ -323,7 +330,7 @@ IVAS_REND_HANDLE IVAS_REND_Open() return st; } -static DecoderDummy *allocDecoderDummy( int32_t sampleRate, int16_t numOutChannels, const uint8_t enableHeadRotation ) +static DecoderDummy *allocDecoderDummy( int32_t sampleRate, int16_t numOutChannels, const uint8_t enableHeadRotation, const uint8_t enableRenderConfig ) { int16_t i; DecoderDummy *decDummy; @@ -334,9 +341,10 @@ static DecoderDummy *allocDecoderDummy( int32_t sampleRate, int16_t numOutChanne decDummy->hDecoderConfig->nchan_out = numOutChannels; decDummy->hDecoderConfig->Opt_Headrotation = enableHeadRotation; - ivas_render_config_open( &decDummy->hRenderConfig ); - decDummy->hRenderConfig->roomAcoustics.late_reverb_on = 0; - decDummy->hRenderConfig->roomAcoustics.use_brir = 0; + decDummy->hBinRenderer = NULL; + decDummy->hEFAPdata = NULL; + decDummy->hHrtf = NULL; + decDummy->hHrtfTD = NULL; if ( enableHeadRotation ) { @@ -358,6 +366,17 @@ static DecoderDummy *allocDecoderDummy( int32_t sampleRate, int16_t numOutChanne decDummy->hHeadTrackData = NULL; } + if ( enableRenderConfig ) + { + ivas_render_config_open( &decDummy->hRenderConfig ); + decDummy->hRenderConfig->roomAcoustics.late_reverb_on = 0; + decDummy->hRenderConfig->roomAcoustics.use_brir = 0; + } + else + { + decDummy->hRenderConfig = NULL; + } + decDummy->renderer_type = RENDERER_DISABLE; return decDummy; @@ -369,8 +388,8 @@ static ivas_error initDecoderDummyForMasaToAmbi( DecoderDummy *decDummyMasaAmbi, error = IVAS_ERR_OK; /* TODO @ Nokia: set relevant members of decDummy */ - (void)decDummyMasaAmbi; - (void)inConfig; + (void) decDummyMasaAmbi; + (void) inConfig; return error; } @@ -381,8 +400,8 @@ static ivas_error initDecoderDummyForMasaToChannels( DecoderDummy *decDummyMasaC error = IVAS_ERR_OK; /* TODO @ Nokia: set relevant members of decDummy */ - (void)decDummyMasaChannels; - (void)inConfig; + (void) decDummyMasaChannels; + (void) inConfig; return error; } @@ -393,27 +412,27 @@ static ivas_error initDecoderDummyForMasaToBinaural( DecoderDummy *decDummyMasaB error = IVAS_ERR_OK; /* TODO @ Nokia: set relevant members of decDummy */ - (void)decDummyMasaBin; - (void)inConfig; + (void) decDummyMasaBin; + (void) inConfig; return error; } -static ivas_error initDecoderDummyForAmbiToBinaural( DecoderDummy *decDummyAmbiBin, IVAS_REND_InputConfig inConfig ) +static ivas_error initDecoderDummyForAmbiToBinaural( DecoderDummy *decDummyAmbiBin, IVAS_REND_InputConfig inConfig, IVAS_REND_BinauralFormat binauralFormat ) { ivas_error error; assert( inConfig.numAmbisonicsBuses == 1 && "For now only 1 ambisonics input is supported" ); error = IVAS_ERR_OK; - decDummyAmbiBin->renderer_type = RENDERER_BINAURAL_MIXER_CONV; - decDummyAmbiBin->hHrtf = NULL; - decDummyAmbiBin->hBinRenderer = NULL; - decDummyAmbiBin->intern_config = decDummyAmbiBin->transport_config = - inConfig.ambisonicsBuses[0].ambisonicsConfig == IVAS_REND_AMBISONICS_FOA ? AUDIO_CONFIG_FOA - : inConfig.ambisonicsBuses[0].ambisonicsConfig == IVAS_REND_AMBISONICS_SOA ? AUDIO_CONFIG_HOA2 - : inConfig.ambisonicsBuses[0].ambisonicsConfig == IVAS_REND_AMBISONICS_TOA ? AUDIO_CONFIG_HOA3 - : AUDIO_CONFIG_INVALID; + decDummyAmbiBin->renderer_type = binauralFormat == IVAS_REND_BINAURAL_ROOM ? RENDERER_BINAURAL_MIXER_CONV_ROOM : RENDERER_BINAURAL_MIXER_CONV; + decDummyAmbiBin->intern_config = decDummyAmbiBin->transport_config = mapRendAmbisonicsToAudioConfig( inConfig.ambisonicsBuses[0].ambisonicsConfig ); + + /* BINAURAL_ROOM requires intermediate rendering to 7_1_4 */ + if ( binauralFormat == IVAS_REND_BINAURAL_ROOM ) + { + decDummyAmbiBin->intern_config = AUDIO_CONFIG_7_1_4; + } ivas_output_init( &decDummyAmbiBin->hIntSetup, decDummyAmbiBin->intern_config ); ivas_output_init( &decDummyAmbiBin->hTransSetup, decDummyAmbiBin->transport_config ); @@ -426,7 +445,7 @@ static ivas_error initDecoderDummyForAmbiToBinaural( DecoderDummy *decDummyAmbiB return error; } -static ivas_error initDecoderDummyForObjToBinaural( DecoderDummy *decDummyObjBin, IVAS_REND_InputConfig inConfig ) +static ivas_error initDecoderDummyForObjToBinaural( DecoderDummy *decDummyObjBin, IVAS_REND_InputConfig inConfig, IVAS_REND_BinauralFormat binauralFormat ) { ivas_error error; int32_t n; @@ -435,9 +454,6 @@ static ivas_error initDecoderDummyForObjToBinaural( DecoderDummy *decDummyObjBin error = IVAS_ERR_OK; - decDummyObjBin->renderer_type = RENDERER_BINAURAL_OBJECTS_TD; - decDummyObjBin->hHrtfTD = NULL; - decDummyObjBin->hBinRenderer = NULL; decDummyObjBin->ivas_format = ISM_FORMAT; decDummyObjBin->nSCE = inConfig.numAudioObjects; decDummyObjBin->nchan_transport = inConfig.numAudioObjects; @@ -451,15 +467,33 @@ static ivas_error initDecoderDummyForObjToBinaural( DecoderDummy *decDummyObjBin decDummyObjBin->hIsmMetaData[n] = NULL; } - if ( ( error = ivas_td_binaural_open( decDummyObjBin ) ) != IVAS_ERR_OK ) + /* BINAURAL_ROOM requires intermediate rendering to 7_1_4 */ + if ( binauralFormat == IVAS_REND_BINAURAL_ROOM ) { - return error; + decDummyObjBin->hBinRendererTd = NULL; + decDummyObjBin->renderer_type = RENDERER_BINAURAL_MIXER_CONV_ROOM; + decDummyObjBin->intern_config = AUDIO_CONFIG_7_1_4; + ivas_output_init( &decDummyObjBin->hIntSetup, decDummyObjBin->intern_config ); + + if ( ( error = ivas_crend_open( decDummyObjBin ) != IVAS_ERR_OK ) ) + { + return error; + } + } + else + { + decDummyObjBin->hCrend = NULL; + decDummyObjBin->renderer_type = RENDERER_BINAURAL_OBJECTS_TD; + if ( ( error = ivas_td_binaural_open( decDummyObjBin ) ) != IVAS_ERR_OK ) + { + return error; + } } return error; } -static ivas_error initDecoderDummyForMcToBinaural( DecoderDummy *decDummyMcBin, IVAS_REND_InputConfig inConfig, const uint8_t enableHeadRotation ) +static ivas_error initDecoderDummyForMcToBinaural( DecoderDummy *decDummyMcBin, IVAS_REND_InputConfig inConfig, IVAS_REND_BinauralFormat binauralFormat, const uint8_t enableHeadRotation ) { ivas_error error; IVAS_REND_SpeakerLayout spkLayout; @@ -468,39 +502,11 @@ static ivas_error initDecoderDummyForMcToBinaural( DecoderDummy *decDummyMcBin, error = IVAS_ERR_OK; - decDummyMcBin->hHrtf = NULL; - decDummyMcBin->hHrtfTD = NULL; - decDummyMcBin->hBinRenderer = NULL; - decDummyMcBin->hEFAPdata = NULL; decDummyMcBin->ivas_format = MC_FORMAT; decDummyMcBin->mc_mode = MC_MODE_MCT; spkLayout = inConfig.multiChannelBuses[0].speakerLayout; - - switch ( spkLayout ) - { - case IVAS_REND_SPEAKER_LAYOUT_5_1: - decDummyMcBin->intern_config = decDummyMcBin->transport_config = AUDIO_CONFIG_5_1; - break; - case IVAS_REND_SPEAKER_LAYOUT_7_1: - decDummyMcBin->intern_config = decDummyMcBin->transport_config = AUDIO_CONFIG_7_1; - break; - case IVAS_REND_SPEAKER_LAYOUT_5_1_2: - decDummyMcBin->intern_config = decDummyMcBin->transport_config = AUDIO_CONFIG_5_1_2; - break; - case IVAS_REND_SPEAKER_LAYOUT_5_1_4: - decDummyMcBin->intern_config = decDummyMcBin->transport_config = AUDIO_CONFIG_5_1_4; - break; - case IVAS_REND_SPEAKER_LAYOUT_7_1_4: - decDummyMcBin->intern_config = decDummyMcBin->transport_config = AUDIO_CONFIG_7_1_4; - break; - case IVAS_REND_SPEAKER_LAYOUT_CUSTOM: - decDummyMcBin->intern_config = decDummyMcBin->transport_config = AUDIO_CONFIG_LS_CUSTOM; - break; - default: - assert( false && "Not supported yet" ); - break; - } + decDummyMcBin->intern_config = decDummyMcBin->transport_config = mapRendLayoutToAudioConfig( spkLayout ); if ( spkLayout == IVAS_REND_SPEAKER_LAYOUT_CUSTOM ) { @@ -523,10 +529,12 @@ static ivas_error initDecoderDummyForMcToBinaural( DecoderDummy *decDummyMcBin, return error; } - /* Use TD binaural renderer only for 5_1 and 7_1 with headrotation or Custom LS */ - if ( spkLayout == IVAS_REND_SPEAKER_LAYOUT_CUSTOM || - ( ( spkLayout == IVAS_REND_SPEAKER_LAYOUT_5_1 || spkLayout == IVAS_REND_SPEAKER_LAYOUT_7_1 ) && enableHeadRotation ) ) + /* Use TD binaural renderer only for HRIRs for Custom LS or 5_1 and 7_1 with headrotation */ + if ( ( binauralFormat != IVAS_REND_BINAURAL_ROOM ) && + ( ( spkLayout == IVAS_REND_SPEAKER_LAYOUT_CUSTOM ) || + ( enableHeadRotation && ( spkLayout == IVAS_REND_SPEAKER_LAYOUT_5_1 || spkLayout == IVAS_REND_SPEAKER_LAYOUT_7_1 ) ) ) ) { + decDummyMcBin->renderer_type = RENDERER_BINAURAL_OBJECTS_TD; decDummyMcBin->hCrend = NULL; if ( ( error = ivas_td_binaural_open( decDummyMcBin ) ) != IVAS_ERR_OK ) @@ -536,7 +544,12 @@ static ivas_error initDecoderDummyForMcToBinaural( DecoderDummy *decDummyMcBin, } else { - decDummyMcBin->renderer_type = RENDERER_BINAURAL_MIXER_CONV; + /* TODO tmu : rendering custom layouts to BINAURAL_ROOM needs implementation */ + if ( spkLayout == IVAS_REND_SPEAKER_LAYOUT_CUSTOM && binauralFormat == IVAS_REND_BINAURAL_ROOM ) + { + fprintf( stderr, "Warning! BINAURAL_ROOM output not supported for custom loudspeaker input! Overriding to BINAURAL.\n" ); + } + decDummyMcBin->renderer_type = binauralFormat == IVAS_REND_BINAURAL_ROOM ? RENDERER_BINAURAL_MIXER_CONV_ROOM : RENDERER_BINAURAL_MIXER_CONV; decDummyMcBin->hBinRendererTd = NULL; if ( ( error = ivas_crend_open( decDummyMcBin ) ) != IVAS_ERR_OK ) { @@ -551,7 +564,8 @@ ivas_error IVAS_REND_Configure( IVAS_REND_HANDLE st, const IVAS_REND_InputConfig inConfig, const IVAS_REND_OutputConfig outConfig, uint32_t sampleRate, - bool headRotationEnabled ) + bool headRotationEnabled, + bool rendererConfigEnabled ) { uint32_t i; int32_t j; @@ -573,7 +587,7 @@ ivas_error IVAS_REND_Configure( IVAS_REND_HANDLE st, numActiveOutputs = ( outConfig.ambisonics == IVAS_REND_AMBISONICS_NONE ? 0 : 1 ) + ( outConfig.speakerLayout == IVAS_REND_SPEAKER_LAYOUT_NONE ? 0 : 1 ) + - ( outConfig.binaural == 0 ? 0 : 1 ); + ( outConfig.binauralFormat == IVAS_REND_BINAURAL_NONE ? 0 : 1 ); assert( numActiveOutputs == 1 && "Only one output must be selected" ); /* ========================== Store useful values ========================= */ @@ -619,7 +633,7 @@ ivas_error IVAS_REND_Configure( IVAS_REND_HANDLE st, /* Save number of output channels */ st->numOutChannels = getNumChannelsAmbisonics( st->outConfig.ambisonics ); } - else if ( st->outConfig.binaural ) + else if ( st->outConfig.binauralFormat != IVAS_REND_BINAURAL_NONE ) { st->numOutChannels = 2; } @@ -661,7 +675,15 @@ ivas_error IVAS_REND_Configure( IVAS_REND_HANDLE st, } /* Allocate temporary pan/enc buffer to avoid allocations during rendering */ - st->tmpGainBuffer = count_calloc( st->numOutChannels, sizeof( float ) ); + if ( st->outConfig.binauralFormat == IVAS_REND_BINAURAL_ROOM ) + { + st->tmpGainBuffer = count_calloc( getNumChannelsInSpeakerLayout( IVAS_REND_SPEAKER_LAYOUT_7_1_4 ), sizeof( float ) ); + st->noLfePanBuffer = count_calloc( getNumNonLfeChannelsInSpeakerLayout( IVAS_REND_SPEAKER_LAYOUT_7_1_4 ), sizeof( float ) ); + } + else + { + st->tmpGainBuffer = count_calloc( st->numOutChannels, sizeof( float ) ); + } /* Allocate temporary buffer for panning gains with lfe omitted */ if ( st->outConfig.speakerLayout != IVAS_REND_SPEAKER_LAYOUT_NONE ) @@ -690,14 +712,21 @@ ivas_error IVAS_REND_Configure( IVAS_REND_HANDLE st, for ( i = 0; i < st->inConfig.numAudioObjects; ++i ) { - st->objPanInfo[i].panGains = count_calloc( st->numOutChannels, sizeof( float ) ); + if ( st->outConfig.binauralFormat == IVAS_REND_BINAURAL_ROOM ) + { + st->objPanInfo[i].panGains = count_calloc( getNumChannelsInSpeakerLayout( IVAS_REND_SPEAKER_LAYOUT_7_1_4 ), sizeof( float ) ); + } + else + { + st->objPanInfo[i].panGains = count_calloc( st->numOutChannels, sizeof( float ) ); + } } } /* Prepare MASA processing */ if ( st->inConfig.numMasaBuses != 0 ) { - st->decDummyMasaBin = allocDecoderDummy( st->sampleRate, st->numOutChannels, st->enableHeadRotation ); + st->decDummyMasaBin = allocDecoderDummy( st->sampleRate, st->numOutChannels, st->enableHeadRotation, st->rendererConfigEnabled ); /* TODO @ Nokia: initialize decoder dummy for MASA rendering depending on output config. Feel free to clean this up if some other structure works better. */ @@ -715,7 +744,7 @@ ivas_error IVAS_REND_Configure( IVAS_REND_HANDLE st, return error; } } - else if ( st->outConfig.binaural ) + else if ( st->outConfig.binauralFormat != IVAS_REND_BINAURAL_NONE ) { if ( ( error = initDecoderDummyForMasaToBinaural( st->decDummyMasaBin, st->inConfig ) ) != IVAS_ERR_OK ) { @@ -725,38 +754,71 @@ ivas_error IVAS_REND_Configure( IVAS_REND_HANDLE st, } /* Prepare binaural rendering if enabled */ - if ( st->outConfig.binaural ) + if ( st->outConfig.binauralFormat != IVAS_REND_BINAURAL_NONE ) { if ( headRotationEnabled ) { st->enableHeadRotation = 1; } + if ( rendererConfigEnabled ) + { + st->rendererConfigEnabled = 1; + } + + if ( st->inConfig.numAmbisonicsBuses != 0 ) { - st->decDummyAmbiBin = allocDecoderDummy( st->sampleRate, st->numOutChannels, st->enableHeadRotation ); - if ( ( error = initDecoderDummyForAmbiToBinaural( st->decDummyAmbiBin, st->inConfig ) ) != IVAS_ERR_OK ) + st->decDummyAmbiBin = allocDecoderDummy( st->sampleRate, st->numOutChannels, st->enableHeadRotation, st->rendererConfigEnabled ); + if ( ( error = initDecoderDummyForAmbiToBinaural( st->decDummyAmbiBin, st->inConfig, st->outConfig.binauralFormat ) ) != IVAS_ERR_OK ) { return error; } + + /* init ALLRAD for intermediate rendering to 7_1_4 for BINAURAL_ROOM */ + if ( st->outConfig.binauralFormat == IVAS_REND_BINAURAL_ROOM ) + { + if ( ( error = getHoaRenderMtx( st->outConfig, &st->ambi_dec_mtx, 3 ) ) != IVAS_ERR_OK ) + { + return error; + } + } } - if ( st->inConfig.numMultiChannelBuses != 0 ) + if ( st->inConfig.numAudioObjects != 0 ) { - st->decDummyMcBin = allocDecoderDummy( st->sampleRate, st->numOutChannels, st->enableHeadRotation ); - if ( ( error = initDecoderDummyForMcToBinaural( st->decDummyMcBin, st->inConfig, st->enableHeadRotation ) ) != IVAS_ERR_OK ) + st->decDummyObjBin = allocDecoderDummy( st->sampleRate, st->numOutChannels, st->enableHeadRotation, st->rendererConfigEnabled ); + if ( ( error = initDecoderDummyForObjToBinaural( st->decDummyObjBin, st->inConfig, st->outConfig.binauralFormat ) ) != IVAS_ERR_OK ) { return error; } + + /* init EFAP for intermediate rendering to 7_1_4 for BINAURAL_ROOM */ + if ( st->outConfig.binauralFormat == IVAS_REND_BINAURAL_ROOM ) + { + if ( ( error = efap_init_data( &st->efapRenderer, getSpeakerAzimuths( IVAS_REND_SPEAKER_LAYOUT_7_1_4 ), getSpeakerElevations( IVAS_REND_SPEAKER_LAYOUT_7_1_4 ), getNumNonLfeChannelsInSpeakerLayout( IVAS_REND_SPEAKER_LAYOUT_7_1_4 ), EFAP_MODE_EFAP ) ) != IVAS_ERR_OK ) + { + return error; + } + } } - if ( st->inConfig.numAudioObjects != 0 ) + if ( st->inConfig.numMultiChannelBuses != 0 ) { - st->decDummyObjBin = allocDecoderDummy( st->sampleRate, st->numOutChannels, st->enableHeadRotation ); - if ( ( error = initDecoderDummyForObjToBinaural( st->decDummyObjBin, st->inConfig ) ) != IVAS_ERR_OK ) + st->decDummyMcBin = allocDecoderDummy( st->sampleRate, st->numOutChannels, st->enableHeadRotation, st->rendererConfigEnabled ); + if ( ( error = initDecoderDummyForMcToBinaural( st->decDummyMcBin, st->inConfig, st->outConfig.binauralFormat, st->enableHeadRotation ) ) != IVAS_ERR_OK ) { return error; } + + /* init EFAP for BINAURAL_ROOM via 7_1_4 */ + if ( st->outConfig.binauralFormat == IVAS_REND_BINAURAL_ROOM ) + { + if ( ( error = efap_init_data( &st->efapRenderer, getSpeakerAzimuths( IVAS_REND_SPEAKER_LAYOUT_7_1_4 ), getSpeakerElevations( IVAS_REND_SPEAKER_LAYOUT_7_1_4 ), getNumNonLfeChannelsInSpeakerLayout( IVAS_REND_SPEAKER_LAYOUT_7_1_4 ), EFAP_MODE_EFAP ) ) != IVAS_ERR_OK ) + { + return error; + } + } } } @@ -888,7 +950,7 @@ void IVAS_REND_Render( renderMasaToChannels( st, inAudio, outAudio ); } } /* Render target format: binaural */ - else if ( st->outConfig.binaural ) + else if ( st->outConfig.binauralFormat != IVAS_REND_BINAURAL_NONE ) { /* Rendering to binaural using dummy IVAS decoders */ assert( inAudio.config.bufferSize == st->sampleRate / FRAMES_PER_SEC && "Using IVAS components requires frame size of 20 ms" ); @@ -1079,6 +1141,10 @@ void IVAS_REND_Close( IVAS_REND_HANDLE *st ) if ( hIvasRend->decDummyMcBin != NULL ) { + if ( hIvasRend->decDummyMcBin->hEFAPdata != NULL ) + { + efap_free_data( &hIvasRend->decDummyMcBin->hEFAPdata ); + } ivas_crend_close( hIvasRend->decDummyMcBin ); ivas_td_binaural_close( &hIvasRend->decDummyMcBin->hBinRendererTd ); ivas_render_config_close( &hIvasRend->decDummyMcBin->hRenderConfig ); @@ -1096,6 +1162,7 @@ void IVAS_REND_Close( IVAS_REND_HANDLE *st ) if ( hIvasRend->decDummyObjBin != NULL ) { + ivas_crend_close( hIvasRend->decDummyObjBin ); ivas_td_binaural_close( &hIvasRend->decDummyObjBin->hBinRendererTd ); ivas_render_config_close( &hIvasRend->decDummyObjBin->hRenderConfig ); count_free( hIvasRend->decDummyObjBin->hDecoderConfig ); @@ -1146,7 +1213,7 @@ ivas_error IVAS_REND_GetDelay( return IVAS_ERR_UNEXPECTED_NULL_POINTER; } - if ( st->outConfig.binaural ) + if ( st->outConfig.binauralFormat != IVAS_REND_BINAURAL_NONE ) { if ( ( st->decDummyAmbiBin != NULL && st->decDummyAmbiBin->renderer_type == RENDERER_BINAURAL_OBJECTS_TD ) || ( st->decDummyObjBin != NULL && st->decDummyObjBin->renderer_type == RENDERER_BINAURAL_OBJECTS_TD ) || @@ -1154,18 +1221,28 @@ ivas_error IVAS_REND_GetDelay( { *nSamples = NS2SA( st->sampleRate, (int32_t) ( (float) IVAS_FB_DEC_DELAY_NS + 0.5f ) ); } - else if ( ( st->decDummyAmbiBin != NULL && st->decDummyAmbiBin->renderer_type == RENDERER_BINAURAL_MIXER_CONV ) ) + else if ( ( st->decDummyAmbiBin != NULL ) && + ( ( st->decDummyAmbiBin->renderer_type == RENDERER_BINAURAL_MIXER_CONV ) || + ( st->decDummyAmbiBin->renderer_type == RENDERER_BINAURAL_MIXER_CONV_ROOM ) ) ) { *nSamples = NS2SA( st->sampleRate, (int32_t) ( (float) st->decDummyAmbiBin->binaural_latency_ns + 0.5f ) ); } - else if ( st->decDummyObjBin != NULL && st->decDummyObjBin->renderer_type == RENDERER_BINAURAL_MIXER_CONV ) + else if ( ( st->decDummyObjBin != NULL ) && + ( ( st->decDummyObjBin->renderer_type == RENDERER_BINAURAL_MIXER_CONV ) || + ( st->decDummyObjBin->renderer_type == RENDERER_BINAURAL_MIXER_CONV_ROOM ) ) ) { *nSamples = NS2SA( st->sampleRate, (int32_t) ( (float) st->decDummyObjBin->binaural_latency_ns + 0.5f ) ); } - else if ( st->decDummyMcBin != NULL && st->decDummyMcBin->renderer_type == RENDERER_BINAURAL_MIXER_CONV ) + else if ( ( st->decDummyMcBin != NULL ) && + ( ( st->decDummyMcBin->renderer_type == RENDERER_BINAURAL_MIXER_CONV ) || + ( st->decDummyMcBin->renderer_type == RENDERER_BINAURAL_MIXER_CONV_ROOM ) ) ) { *nSamples = NS2SA( st->sampleRate, (int32_t) ( (float) st->decDummyMcBin->binaural_latency_ns + 0.5f ) ); } + else + { + *nSamples = 0; + } } else { @@ -1712,11 +1789,27 @@ static void renderAmbiToBinaural( applyGainToBuffer( inAudio, inAmbiChannelIdx, gain_lin ); copyBufferTo2dArray( inAudio, inAmbiChannelIdx, numInChannels, tmpBuffer ); - if ( st->enableHeadRotation ) + if ( st->outConfig.binauralFormat == IVAS_REND_BINAURAL_ROOM ) { - for ( i = 0; i < RENDERER_HEAD_POSITIONS_PER_FRAME; i++ ) + /* Convert SBA to 7_1_4 for BINAURAL_ROOM */ + ivas_sba_mtx_mult( tmpBuffer, inAudio.config.bufferSize, getNumChannelsAmbisonics( st->inConfig.ambisonicsBuses[ambiIdx].ambisonicsConfig ), st->decDummyAmbiBin->hIntSetup, st->ambi_dec_mtx ); + + if ( st->enableHeadRotation ) + { + for ( i = 0; i < RENDERER_HEAD_POSITIONS_PER_FRAME; i++ ) + { + rotateFrame_sd( st->decDummyAmbiBin->hHeadTrackData, tmpBuffer, st->sampleRate, subFrameLength, st->decDummyAmbiBin->hIntSetup, st->decDummyAmbiBin->hEFAPdata, i ); + } + } + } + else /* IVAS_REND_BINAURAL_DIRECT */ + { + if ( st->enableHeadRotation ) { - rotateFrame_shd( st->decDummyAmbiBin->hHeadTrackData, tmpBuffer, st->sampleRate, subFrameLength, st->decDummyAmbiBin->hTransSetup, i ); + for ( i = 0; i < RENDERER_HEAD_POSITIONS_PER_FRAME; i++ ) + { + rotateFrame_shd( st->decDummyAmbiBin->hHeadTrackData, tmpBuffer, st->sampleRate, subFrameLength, st->decDummyAmbiBin->hTransSetup, i ); + } } } @@ -1725,7 +1818,6 @@ static void renderAmbiToBinaural( copy2dArrayToBuffer( tmpBuffer, &outAudio, 0, st->numOutChannels ); } - #ifdef WMOPS wmops_sub_end(); #endif @@ -1776,8 +1868,8 @@ static void renderChannelsToBinaural( } /* TD object renderer initialised only for 7_1 and 5_1 with headrotation or custom layout input */ - if ( ( st->inConfig.multiChannelBuses[mcIdx].speakerLayout == IVAS_REND_SPEAKER_LAYOUT_CUSTOM ) || - ( st->decDummyMcBin->hBinRendererTd != NULL && st->enableHeadRotation ) ) + if ( ( st->outConfig.binauralFormat != IVAS_REND_BINAURAL_ROOM ) && ( ( st->inConfig.multiChannelBuses[mcIdx].speakerLayout == IVAS_REND_SPEAKER_LAYOUT_CUSTOM ) || + ( st->decDummyMcBin->hBinRendererTd != NULL && st->enableHeadRotation ) ) ) { ObjRenderIVASFrame( st->decDummyMcBin, tmpBuffer, inAudio.config.bufferSize ); /* TODO tmu : needs delay compensation otherwise LFE is added out of alignment */ @@ -1797,7 +1889,8 @@ static void renderChannelsToBinaural( { lfeChIdx = LFE_CHANNEL; } - // TODO tmu verify + + /* TODO tmu : needs verification */ mvr2r( tmpBuffer[lfeChIdx], tmpLfeBuffer, L_FRAME48k ); ivas_filter_process( &st->lfeLpFilter, tmpLfeBuffer, L_FRAME48k ); set_zero( tmpBuffer[lfeChIdx], L_FRAME48k ); @@ -1821,16 +1914,24 @@ static void renderObjectsToBinaural( { int16_t objIdx; int16_t tmpAzi, tmpEle; + int16_t chInIdx, smplIdx; float tmpBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; + float tmpBuffer2[MAX_OUTPUT_CHANNELS][L_FRAME48k]; float gain_lin; + float fadeIn, fadeOut; + float *swapPtr; uint32_t inIsmIdx; #ifdef WMOPS wmops_sub_start( "renderObjectsToBinaural" ); #endif + for ( chInIdx = 0; chInIdx < MAX_OUTPUT_CHANNELS; ++chInIdx ) + { + set_zero( tmpBuffer[chInIdx], L_FRAME48k ); + set_zero( tmpBuffer2[chInIdx], L_FRAME48k ); + } assert( st->inConfig.numAudioObjects == metadataBuffer.numObjects && "Metadata provided for a different number of objects than found in input" ); - if ( st->enableHeadRotation ) { copyHeadRotToDecDummy( st->headRotationData, st->decDummyObjBin ); @@ -1840,7 +1941,6 @@ static void renderObjectsToBinaural( for ( objIdx = 0; objIdx < metadataBuffer.numObjects; ++objIdx ) { /* Apply head rotation directly to object positions */ - /* TODO tmu 20ms only right now... */ if ( st->enableHeadRotation ) { /* save original positions */ @@ -1861,20 +1961,56 @@ static void renderObjectsToBinaural( st->decDummyObjBin->hIsmMetaData[objIdx]->azimuth = (float) tmpAzi; st->decDummyObjBin->hIsmMetaData[objIdx]->elevation = (float) tmpEle; } + else if ( st->outConfig.binauralFormat == IVAS_REND_BINAURAL_ROOM ) + { + st->decDummyObjBin->hIsmMetaData[objIdx]->azimuth = metadataBuffer.positions[objIdx].azimuth; + st->decDummyObjBin->hIsmMetaData[objIdx]->elevation = metadataBuffer.positions[objIdx].elevation; + } inIsmIdx = st->inConfig.audioObjects[objIdx].inputChannelIndex; + gain_lin = dBToLin( st->inConfig.audioObjects[objIdx].gain_dB ); + applyGainToBuffer( inAudio, objIdx, gain_lin ); + /* Copy input audio to tmp buffer for processing */ copyBufferTo2dArray( inAudio, inIsmIdx, 1, &tmpBuffer[objIdx] ); } - /* TODO tmu : enable per-object gains */ - gain_lin = dBToLin( st->inConfig.audioObjects[0].gain_dB ); - applyGainToBuffer( inAudio, 0, gain_lin ); + if ( st->outConfig.binauralFormat == IVAS_REND_BINAURAL_ROOM ) + { + for ( objIdx = 0; objIdx < metadataBuffer.numObjects; ++objIdx ) + { + /* Convert ISM to 7_1_4 for BINAURAL_ROOM */ + getSpeakerGains( st, st->decDummyObjBin->hIsmMetaData[objIdx]->azimuth, st->decDummyObjBin->hIsmMetaData[objIdx]->elevation, st->tmpGainBuffer ); - ObjRenderIVASFrame( st->decDummyObjBin, tmpBuffer, inAudio.config.bufferSize ); - copy2dArrayToBuffer( tmpBuffer, &outAudio, 0, st->numOutChannels ); + for ( chInIdx = 0; chInIdx < getNumChannelsInSpeakerLayout( IVAS_REND_SPEAKER_LAYOUT_7_1_4 ); ++chInIdx ) + { + if ( fabsf( st->tmpGainBuffer[chInIdx] ) > 0.0f || fabsf( st->objPanInfo[objIdx].panGains[chInIdx] ) > 0.0f ) + { + for ( smplIdx = 0; smplIdx < L_FRAME48k; ++smplIdx ) + { + fadeIn = st->crossfade[smplIdx]; + fadeOut = 1.0f - fadeIn; + tmpBuffer2[chInIdx][smplIdx] += ( fadeIn * st->tmpGainBuffer[chInIdx] + fadeOut * st->objPanInfo[objIdx].panGains[chInIdx] ) * tmpBuffer[objIdx][smplIdx]; + } + } + } + /* move old gains to st->objPanInfo */ + swapPtr = st->objPanInfo[objIdx].panGains; + st->objPanInfo[objIdx].panGains = st->tmpGainBuffer; + st->tmpGainBuffer = swapPtr; + } + + /* render from buffer with 7_1_4 format */ + ivas_crend_process( st->decDummyObjBin, tmpBuffer2 ); + copy2dArrayToBuffer( tmpBuffer2, &outAudio, 0, st->numOutChannels ); + } + else /* IVAS_REND_BINAURAL_DIRECT */ + { + ObjRenderIVASFrame( st->decDummyObjBin, tmpBuffer, inAudio.config.bufferSize ); + copy2dArrayToBuffer( tmpBuffer, &outAudio, 0, st->numOutChannels ); + } #ifdef WMOPS wmops_sub_end(); #endif @@ -2136,12 +2272,13 @@ static void prepareLfeHandling( /* Pan LFE to L and R with -3dB gain */ if ( st->numOutChannels > 1 ) { + /* TODO tmu : not guaranteed to be L and R for custom layouts without LFE */ st->lfePanGains[0] = sqrtf( 0.5f ); st->lfePanGains[1] = sqrtf( 0.5f ); } else { - /* Put LFE in center channel, do not add 10dB gain to avoid clipping */ + /* Put LFE in center channel */ st->lfePanGains[0] = 1.f; } } @@ -2167,7 +2304,7 @@ static void prepareMcPanGains( IVAS_REND_HANDLE st ) wmops_sub_start( "prepareMcPanGains" ); #endif /* No gains required for binaural output */ - if ( ( st->outConfig.binaural ) && + if ( ( st->outConfig.binauralFormat != IVAS_REND_BINAURAL_NONE ) && ( st->outConfig.ambisonics == IVAS_REND_AMBISONICS_NONE || st->outConfig.speakerLayout == IVAS_REND_SPEAKER_LAYOUT_NONE ) ) { st->speakerPanGains = NULL; @@ -2511,7 +2648,15 @@ static void getSpeakerGains( const IVAS_REND_HANDLE st, /* EFAP returns an array of gains only for non-LFE speakers */ efap_determine_gains( st->efapRenderer, st->noLfePanBuffer, azi, ele, EFAP_MODE_EFAP ); - speakerLayout = st->outConfig.speakerLayout; + if ( st->outConfig.binauralFormat == IVAS_REND_BINAURAL_ROOM ) + { + speakerLayout = IVAS_REND_SPEAKER_LAYOUT_7_1_4; + } + else + { + speakerLayout = st->outConfig.speakerLayout; + } + if ( speakerLayout == IVAS_REND_SPEAKER_LAYOUT_CUSTOM ) { uint32_t lfeIdx; @@ -2732,37 +2877,38 @@ static ivas_error getHoaRenderMtx( wmops_sub_start( "getHoaRenderMtx" ); #endif - switch ( outConfig.speakerLayout ) + if ( outConfig.binauralFormat == IVAS_REND_BINAURAL_NONE ) { - case IVAS_REND_SPEAKER_LAYOUT_MONO: - ivas_output_init( &hOutSetup, AUDIO_CONFIG_MONO ); - hOutSetup.ls_azimuth = ls_azimuth_CICP1; - hOutSetup.ls_elevation = ls_elevation_CICP1; - break; - case IVAS_REND_SPEAKER_LAYOUT_STEREO: - ivas_output_init( &hOutSetup, AUDIO_CONFIG_STEREO ); - break; - case IVAS_REND_SPEAKER_LAYOUT_5_1: - ivas_output_init( &hOutSetup, AUDIO_CONFIG_5_1 ); - break; - case IVAS_REND_SPEAKER_LAYOUT_7_1: - ivas_output_init( &hOutSetup, AUDIO_CONFIG_7_1 ); - break; - case IVAS_REND_SPEAKER_LAYOUT_5_1_2: - ivas_output_init( &hOutSetup, AUDIO_CONFIG_5_1_2 ); - break; - case IVAS_REND_SPEAKER_LAYOUT_5_1_4: - ivas_output_init( &hOutSetup, AUDIO_CONFIG_5_1_4 ); - break; - case IVAS_REND_SPEAKER_LAYOUT_7_1_4: - ivas_output_init( &hOutSetup, AUDIO_CONFIG_7_1_4 ); - break; - case IVAS_REND_SPEAKER_LAYOUT_CUSTOM: - ivas_ls_custom_setup( &hOutSetup, outConfig.outSetupCustom ); - break; - default: - assert( !"Invalid speaker config" ); - return IVAS_ERR_WRONG_PARAMS; + switch ( outConfig.speakerLayout ) + { + case IVAS_REND_SPEAKER_LAYOUT_MONO: + hOutSetup.ls_azimuth = ls_azimuth_CICP1; + hOutSetup.ls_elevation = ls_elevation_CICP1; + case IVAS_REND_SPEAKER_LAYOUT_STEREO: + case IVAS_REND_SPEAKER_LAYOUT_5_1: + case IVAS_REND_SPEAKER_LAYOUT_7_1: + case IVAS_REND_SPEAKER_LAYOUT_5_1_2: + case IVAS_REND_SPEAKER_LAYOUT_5_1_4: + case IVAS_REND_SPEAKER_LAYOUT_7_1_4: + ivas_output_init( &hOutSetup, mapRendLayoutToAudioConfig( outConfig.speakerLayout ) ); + break; + case IVAS_REND_SPEAKER_LAYOUT_CUSTOM: + ivas_ls_custom_setup( &hOutSetup, outConfig.outSetupCustom ); + break; + default: + assert( !"Invalid speaker config" ); + return IVAS_ERR_WRONG_PARAMS; + } + } + /* intermediate rendering to 7_1_4 for BINAURAL_ROOM */ + else if ( outConfig.binauralFormat == IVAS_REND_BINAURAL_ROOM ) + { + ivas_output_init( &hOutSetup, AUDIO_CONFIG_7_1_4 ); + } + else + { + assert( !"Invalid configuration" ); + return IVAS_ERR_WRONG_PARAMS; } if ( ( error = ivas_sba_get_hoa_dec_matrix( hOutSetup, decMtx, (int16_t) ambiOrder ) ) != IVAS_ERR_OK ) @@ -2898,3 +3044,19 @@ static AUDIO_CONFIG mapRendLayoutToAudioConfig( IVAS_REND_SpeakerLayout speakerL return AUDIO_CONFIG_INVALID; } } + +static AUDIO_CONFIG mapRendAmbisonicsToAudioConfig( IVAS_REND_Ambisonics ambisonics ) +{ + switch ( ambisonics ) + { + case IVAS_REND_AMBISONICS_FOA: + return AUDIO_CONFIG_FOA; + case IVAS_REND_AMBISONICS_SOA: + return AUDIO_CONFIG_HOA2; + case IVAS_REND_AMBISONICS_TOA: + return AUDIO_CONFIG_HOA3; + case IVAS_REND_AMBISONICS_NONE: + default: + return AUDIO_CONFIG_INVALID; + } +} diff --git a/lib_rend/lib_rend.h b/lib_rend/lib_rend.h index 5b8f42f2da..6c5ae79fa4 100644 --- a/lib_rend/lib_rend.h +++ b/lib_rend/lib_rend.h @@ -41,9 +41,9 @@ #include "common_api_types.h" #include "ivas_error.h" -#define RENDERER_MAX_ISM_INPUTS 4 -#define RENDERER_MAX_MC_INPUTS 1 -#define RENDERER_MAX_SBA_INPUTS 1 +#define RENDERER_MAX_ISM_INPUTS 4 +#define RENDERER_MAX_MC_INPUTS 1 +#define RENDERER_MAX_SBA_INPUTS 1 #define RENDERER_MAX_MASA_INPUTS 1 #define RENDERER_HEAD_POSITIONS_PER_FRAME 4 @@ -70,6 +70,13 @@ typedef enum IVAS_REND_SpeakerLayout IVAS_REND_SPEAKER_LAYOUT_7_1_4 = 19 } IVAS_REND_SpeakerLayout; /* Numerical value corresponds to CICP index */ +typedef enum IVAS_REND_BinauralFormat +{ + IVAS_REND_BINAURAL_NONE = -1, + IVAS_REND_BINAURAL_DIRECT = 0, + IVAS_REND_BINAURAL_ROOM = 2 +} IVAS_REND_BinauralFormat; + typedef enum IVAS_REND_MasaTc { IVAS_REND_MASA_TC_NONE = -1, @@ -145,15 +152,15 @@ typedef struct IVAS_REND_InputConfig uint16_t numAmbisonicsBuses; IVAS_LSSETUP_CUSTOM_HANDLE inSetupCustom; IVAS_REND_MasaBus masaBus; /* Support one MASA input for now. Multiple inputs will be easier to implement after API rework. */ - uint16_t numMasaBuses; /* Keep for framework consistency for now. Again - this will not be necessary after API rework */ + uint16_t numMasaBuses; /* Keep for framework consistency for now. Again - this will not be necessary after API rework */ } IVAS_REND_InputConfig; typedef struct IVAS_REND_OutputConfig { IVAS_REND_SpeakerLayout speakerLayout; IVAS_REND_Ambisonics ambisonics; + IVAS_REND_BinauralFormat binauralFormat; IVAS_LSSETUP_CUSTOM_HANDLE outSetupCustom; - uint8_t binaural; /* flag */ } IVAS_REND_OutputConfig; typedef struct IVAS_REND *IVAS_REND_HANDLE; @@ -176,7 +183,8 @@ ivas_error IVAS_REND_Configure( const IVAS_REND_InputConfig inConfig, /* i : Input configuration */ const IVAS_REND_OutputConfig outConfig, /* i : Output configuration */ uint32_t sampleRate, /* i : Processing sampling rate */ - bool headRotationEnabled /* i : enable head rotation for binaural output, ignored for other output formats */ + bool headRotationEnabled, /* i : enable head rotation for binaural output, ignored for other output formats */ + bool rendererConfigEnabled /* i : flag indicating if a renderer configuration file was supplied */ ); void IVAS_REND_SetHeadRotation( diff --git a/scripts/tests/constants.py b/scripts/tests/constants.py index 8345dc6f4b..7893bedd61 100644 --- a/scripts/tests/constants.py +++ b/scripts/tests/constants.py @@ -178,10 +178,7 @@ INPUT_FORMATS_BINAURAL.extend( # "MASA2", ] ) -OUTPUT_FORMATS_BINAURAL = [ - "BINAURAL", - # "BINAURAL_ROOM" # TODO -] +OUTPUT_FORMATS_BINAURAL = ["BINAURAL", "BINAURAL_ROOM"] HR_TRAJECTORIES_TO_TEST = [ # "const000", # "full_circle_in_15s", diff --git a/scripts/tests/data/masa_scene.txt b/scripts/tests/data/masa_scene.txt index 46baa475c1..b304b168d2 100644 --- a/scripts/tests/data/masa_scene.txt +++ b/scripts/tests/data/masa_scene.txt @@ -1,4 +1,4 @@ -stv_IVASMASA_2dir2TC.wav +stv_IVASMASA_2dir2TC.pcm 1 MASA 1 diff --git a/scripts/tests/data/stv_IVASMASA_2dir2TC.wav b/scripts/tests/data/stv_IVASMASA_2dir2TC.wav deleted file mode 100644 index e159c4f9ae..0000000000 --- a/scripts/tests/data/stv_IVASMASA_2dir2TC.wav +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:60a713ed1b97cf94b16849806951ef83d8f41c8ee455b267ec0a292c695cbbc1 -size 576044 diff --git a/scripts/tests/test_renderer.py b/scripts/tests/test_renderer.py index 8159832aa1..7acd2a9028 100644 --- a/scripts/tests/test_renderer.py +++ b/scripts/tests/test_renderer.py @@ -233,7 +233,7 @@ def test_ism(in_fmt, out_fmt): in_meta_files=FORMAT_TO_METADATA_FILES[in_fmt], ) - # ISM to Ambisonics has differences due to optimizations in ivas_dirac_dec_get_response() + # ISM to Ambisonics has differences due to optimizations in ivas_dirac_dec_get_response() # additionally, positions parsed from the metadata files in C seem to be different # due to (float) atof() reading being subsequently cast to int16_t check_BE(ref, ref_fs, cut, cut_fs, snr_min=38) @@ -271,6 +271,7 @@ def test_metadata(in_fmt, out_fmt): check_BE(ref, ref_fs, cut, cut_fs, snr_min=11) + @pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS) @pytest.mark.parametrize("in_fmt", METADATA_SCENES_TO_TEST_NO_BE) def test_metadata_masa(in_fmt, out_fmt): @@ -290,7 +291,7 @@ def test_ambisonics_binaural_static(in_fmt, out_fmt): cut, cut_fs = run_renderer(in_fmt, out_fmt) - check_BE(ref, ref_fs, cut, cut_fs, snr_min=89) + check_BE(ref, ref_fs, cut, cut_fs, snr_min=0.1) @pytest.mark.xfail(reason="Python cannot be BE to TD Object Renderer") @@ -316,7 +317,7 @@ def test_multichannel_binaural_static(in_fmt, out_fmt): cut, cut_fs = run_renderer(in_fmt, out_fmt) - check_BE(ref, ref_fs, cut, cut_fs, snr_min=11) + check_BE(ref, ref_fs, cut, cut_fs, snr_min=4.5) # Binaural rendering (head rotation) @@ -336,12 +337,20 @@ def test_ambisonics_binaural_headrotation(in_fmt, out_fmt, trj_file): trj_file=HR_TRAJECTORY_DIR.joinpath(f"{trj_file}.csv"), ) - check_BE(ref, ref_fs, cut, cut_fs, snr_min=42) + check_BE(ref, ref_fs, cut, cut_fs, snr_min=0.04) -@pytest.mark.xfail(reason="Python cannot be BE to TD Object Renderer") @pytest.mark.parametrize("trj_file", HR_TRAJECTORIES_TO_TEST) -@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL) +@pytest.mark.parametrize( + "out_fmt", + [ + pytest.param( + "BINAURAL", + marks=pytest.mark.xfail(reason="Python cannot be BE to TD Object Renderer"), + ), + "BINAURAL_ROOM", + ], +) @pytest.mark.parametrize("in_fmt", INPUT_FORMATS_ISM) def test_ism_binaural_headrotation(in_fmt, out_fmt, trj_file): try: @@ -363,11 +372,20 @@ def test_ism_binaural_headrotation(in_fmt, out_fmt, trj_file): in_meta_files=in_meta_files, ) - check_BE(ref, ref_fs, cut, cut_fs) + check_BE(ref, ref_fs, cut, cut_fs, snr_min=1.3) @pytest.mark.parametrize("trj_file", HR_TRAJECTORIES_TO_TEST) -@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL) +@pytest.mark.parametrize( + "out_fmt", + [ + pytest.param( + "BINAURAL", + marks=pytest.mark.xfail(reason="Python cannot be BE to TD Object Renderer"), + ), + "BINAURAL_ROOM", + ], +) @pytest.mark.parametrize( "in_fmt", [ @@ -397,4 +415,4 @@ def test_multichannel_binaural_headrotation(in_fmt, out_fmt, trj_file): trj_file=HR_TRAJECTORY_DIR.joinpath(f"{trj_file}.csv"), ) - check_BE(ref, ref_fs, cut, cut_fs, snr_min=4.5) + check_BE(ref, ref_fs, cut, cut_fs, snr_min=2.3) -- GitLab From 8ee76816f2b8e11391250ce7e1497c08692b5d47 Mon Sep 17 00:00:00 2001 From: Kacper Sagnowski Date: Thu, 18 Aug 2022 14:02:32 +0200 Subject: [PATCH 005/101] Fix sanitizer issue due to unset ivas_format --- lib_rend/lib_rend.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index 18f556a56f..f64f707230 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -339,7 +339,7 @@ static DecoderDummy *allocDecoderDummy( int32_t sampleRate, int16_t numOutChanne decDummy->hDecoderConfig = count_malloc( sizeof( DECODER_CONFIG ) ); decDummy->hDecoderConfig->output_Fs = sampleRate; decDummy->hDecoderConfig->nchan_out = numOutChannels; - decDummy->hDecoderConfig->Opt_Headrotation = enableHeadRotation; + decDummy->hDecoderConfig->Opt_Headrotation = 0; decDummy->hBinRenderer = NULL; decDummy->hEFAPdata = NULL; @@ -425,6 +425,7 @@ static ivas_error initDecoderDummyForAmbiToBinaural( DecoderDummy *decDummyAmbiB error = IVAS_ERR_OK; + decDummyAmbiBin->ivas_format = SBA_FORMAT; decDummyAmbiBin->renderer_type = binauralFormat == IVAS_REND_BINAURAL_ROOM ? RENDERER_BINAURAL_MIXER_CONV_ROOM : RENDERER_BINAURAL_MIXER_CONV; decDummyAmbiBin->intern_config = decDummyAmbiBin->transport_config = mapRendAmbisonicsToAudioConfig( inConfig.ambisonicsBuses[0].ambisonicsConfig ); -- GitLab From f3c759b086004cbe6c83c71e731f8b9dee0b1fe7 Mon Sep 17 00:00:00 2001 From: Kacper Sagnowski Date: Thu, 18 Aug 2022 18:25:18 +0200 Subject: [PATCH 006/101] CMake: make copying executables to source dir optional --- CMakeLists.txt | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e333918c91..806f1f3e2a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -167,7 +167,9 @@ endif() add_executable(IVAS_rend apps/renderer.c) target_link_libraries(IVAS_rend lib_rend lib_util) -# Copy executables to root directory after build -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}/") \ No newline at end of file +if(COPY_EXECUTABLES_TO_ROOT) + # Optionally copy executables to root directory after build + 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}/") +endif() \ No newline at end of file -- GitLab From 40e572cea6329aea2e7ae1b56442580892ca8981 Mon Sep 17 00:00:00 2001 From: Kacper Sagnowski Date: Fri, 19 Aug 2022 10:33:29 +0200 Subject: [PATCH 007/101] Fix ext renderer tests that build with CMake --- .gitlab-ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index d6cb4c70b7..8b650c203b 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -243,7 +243,7 @@ external-renderer-cmake-asan-pytest: stage: test script: - python3 ci/disable_ram_counting.py - - cmake -B cmake-build -G "Unix Makefiles" -DCLANG=asan + - cmake -B cmake-build -G "Unix Makefiles" -DCLANG=asan -DCOPY_EXECUTABLES_TO_ROOT=true - cmake --build cmake-build -- -j - python3 -m pytest scripts/tests/test_renderer.py --capture=no --tb=no -n auto @@ -256,7 +256,7 @@ external-renderer-cmake-msan-pytest: stage: test script: - python3 ci/disable_ram_counting.py - - cmake -B cmake-build -G "Unix Makefiles" -DCLANG=msan + - cmake -B cmake-build -G "Unix Makefiles" -DCLANG=msan -DCOPY_EXECUTABLES_TO_ROOT=true - cmake --build cmake-build -- -j - python3 -m pytest scripts/tests/test_renderer.py --capture=no --tb=no -n auto -- GitLab From 1af1f798122affb025069e546f6a3485a982a5d9 Mon Sep 17 00:00:00 2001 From: Archit Tamarapu Date: Thu, 25 Aug 2022 16:52:59 +0200 Subject: [PATCH 008/101] [renderer] - enabled support for BINAURAL_ROOM output - fix a bug in ISM binaural rendering - position data was not copied for TD Object Renderer without headtracking - fix differing crossfades for ambisonics to binaural with and without headrotation (changes BE for rotateFrame_sd() / rotateFrame_shd() calls) - add initial version of delay compensation for LFE in binaural rendering - fix support for raw PCM input - CLI improvements, make some options required and edit the printout - temporary fix for TD Renderer init bug [pyaudio3dtools] - various bugfixes - update ISM binaural rendering for pyaudio3dtools to use nearest filter on sphere [tests] - don't xfail tests on a function level to avoid masking run errors - enable per-testcase SNR thresholds and xfail tests accordingly instead of allowing them to pass --- .gitlab-ci-custom.yml | 2 +- .gitlab-ci.yml | 6 +- apps/renderer.c | 7 +- lib_com/options.h | 5 +- lib_dec/ivas_sba_dec.c | 1 - lib_rend/ivas_objectRenderer.c | 2 +- lib_rend/ivas_rom_rend.c | 25 -- lib_rend/ivas_rotation.c | 42 +++- lib_rend/lib_rend.c | 140 ++++++++--- scripts/pyaudio3dtools/audiofile.py | 19 +- scripts/pyaudio3dtools/binauralrenderer.py | 32 ++- scripts/pyaudio3dtools/spatialaudioconvert.py | 16 +- scripts/pyaudio3dtools/spatialaudioformat.py | 7 +- scripts/tests/test_renderer.py | 236 ++++++++++++------ 14 files changed, 352 insertions(+), 188 deletions(-) diff --git a/.gitlab-ci-custom.yml b/.gitlab-ci-custom.yml index 86c1f487e0..d39886c69c 100644 --- a/.gitlab-ci-custom.yml +++ b/.gitlab-ci-custom.yml @@ -1,4 +1,4 @@ include: - project: $CUSTOM_CI_PROJECT - ref: $CUSTOM_CI_REF + ref: external-renderer-ci file: $CUSTOM_CI_FILE diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 8b650c203b..6e279c76b0 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -232,7 +232,7 @@ external-renderer-make-pytest: stage: test script: - make -j IVAS_rend - - python3 -m pytest scripts/tests/test_renderer.py --capture=no --tb=no -n auto + - python3 -m pytest scripts/tests/test_renderer.py -q --log-level ERROR -n auto # test external renderer executable with cmake + asan external-renderer-cmake-asan-pytest: @@ -245,7 +245,7 @@ external-renderer-cmake-asan-pytest: - python3 ci/disable_ram_counting.py - cmake -B cmake-build -G "Unix Makefiles" -DCLANG=asan -DCOPY_EXECUTABLES_TO_ROOT=true - cmake --build cmake-build -- -j - - python3 -m pytest scripts/tests/test_renderer.py --capture=no --tb=no -n auto + - python3 -m pytest scripts/tests/test_renderer.py -q --log-level ERROR -n auto # test external renderer executable with cmake + msan external-renderer-cmake-msan-pytest: @@ -258,7 +258,7 @@ external-renderer-cmake-msan-pytest: - python3 ci/disable_ram_counting.py - cmake -B cmake-build -G "Unix Makefiles" -DCLANG=msan -DCOPY_EXECUTABLES_TO_ROOT=true - cmake --build cmake-build -- -j - - python3 -m pytest scripts/tests/test_renderer.py --capture=no --tb=no -n auto + - python3 -m pytest scripts/tests/test_renderer.py -q --log-level ERROR -n auto # compare bit exactness between target and source branch self-test-on-merge-request: diff --git a/apps/renderer.c b/apps/renderer.c index 4ffa2ed427..5787cb143e 100644 --- a/apps/renderer.c +++ b/apps/renderer.c @@ -1259,13 +1259,15 @@ static CmdlnArgs parseCmdlnArgs( int32_t argc, char **argv ) .id = CmdLnOptionId_inputFile, .match = "input_file", .matchShort = "i", + .isRequired = 1, .description = "Path to the input file", }, { .id = CmdLnOptionId_inputFormat, .match = "input_format", .matchShort = "if", - .description = "Format of input file", + .isRequired = 1, + .description = "Format of input file\nIn case of a metadata format this should be followed by a list of metadata file paths or NULL", }, { .id = CmdLnOptionId_outputFile, @@ -1278,6 +1280,7 @@ static CmdlnArgs parseCmdlnArgs( int32_t argc, char **argv ) .id = CmdLnOptionId_outputFormat, .match = "output_format", .matchShort = "of", + .isRequired = 1, .description = "Output format to render.\nAlternatively, can be a custom loudspeaker layout file", }, { @@ -1308,7 +1311,7 @@ static CmdlnArgs parseCmdlnArgs( int32_t argc, char **argv ) { .id = CmdLnOptionId_noDiegeticPan, .match = "no_diegetic_pan", - .matchShort = "ndl", + .matchShort = "ndp", .description = "Panning mono no dietic sound to stereo -1<= pan <= 1\nleft or l or 1->left, right or r or -1->right, center or c or 0 ->middle", }, { diff --git a/lib_com/options.h b/lib_com/options.h index 65f3ec1990..8bb532f8fb 100755 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -149,10 +149,11 @@ #define LBR_SBA_CORE_CODING_TUNING /* Contribution "3 Core Coder Tuning for low bitrate SBA with 2 TCs" */ -#define FIX_WRONG_NBANDS_IN_ITD_ESTIMATION /* Issue 85: fix incorrect setting of nbands in calc_mean_E_ratio() if bwidth is limited on commandline*/ - #define EXT_RENDERER /* FhG: external renderer library and standalone application */ #define FIX_EFAP_MATH /* fix for EFAP: remove angle quantization and a bug in polygon lookup causing incorrect gains. minor tweak for ALLRAD. non-BE for modes using EFAP */ + +#define FIX_WRONG_NBANDS_IN_ITD_ESTIMATION /* Issue 85: fix incorrect setting of nbands in calc_mean_E_ratio() if bwidth is limited on commandline*/ + #define FIX_I87 /* fix for issue 86: incorrect Ambisonics order set for head rotation in SBA */ /* ################## End DEVELOPMENT switches ######################### */ diff --git a/lib_dec/ivas_sba_dec.c b/lib_dec/ivas_sba_dec.c index 640e5cc85f..b79c598801 100644 --- a/lib_dec/ivas_sba_dec.c +++ b/lib_dec/ivas_sba_dec.c @@ -608,7 +608,6 @@ void ivas_sba_upmixer_renderer( } } - wmops_sub_end(); return; diff --git a/lib_rend/ivas_objectRenderer.c b/lib_rend/ivas_objectRenderer.c index 8dac9b71bf..153c6d7f2d 100644 --- a/lib_rend/ivas_objectRenderer.c +++ b/lib_rend/ivas_objectRenderer.c @@ -142,7 +142,7 @@ ivas_error ivas_td_binaural_open( ls_azimuth = ls_azimuth_CICP19; ls_elevation = ls_elevation_CICP19; break; -#ifdef EXT_RENDERER /* TODO tmu : possibly could be adopted for the above cases too ? */ +#ifdef EXT_RENDERER case AUDIO_CONFIG_LS_CUSTOM: ls_azimuth = st_ivas->hTransSetup.ls_azimuth; ls_elevation = st_ivas->hTransSetup.ls_elevation; diff --git a/lib_rend/ivas_rom_rend.c b/lib_rend/ivas_rom_rend.c index 0f680f929d..dd252a9969 100644 --- a/lib_rend/ivas_rom_rend.c +++ b/lib_rend/ivas_rom_rend.c @@ -436,7 +436,6 @@ const LS_CONVERSION_MATRIX ls_conversion_cicp14_cicp6[] = {43, 0.849999964f} }; -#ifdef FIX_I54_LS_CONVERSION const LS_CONVERSION_MATRIX ls_conversion_cicp14_cicp12[] = { /* First row indicates the number of non-zero elements */ @@ -451,7 +450,6 @@ const LS_CONVERSION_MATRIX ls_conversion_cicp14_cicp12[] = {48, 0.849999964f}, {57, 0.849999964f} }; -#endif const LS_CONVERSION_MATRIX ls_conversion_cicp16_cicp6[] = { @@ -493,7 +491,6 @@ const LS_CONVERSION_MATRIX ls_conversion_cicp16_cicp14[] = /* First row indicates the number of non-zero elements */ {10, 0.0f}, /* Index of non-zero element, value of non-zero element*/ -#ifdef FIX_I54_LS_CONVERSION {0, 1.000000000f}, {9, 1.000000000f}, {18, 1.000000000f}, @@ -504,18 +501,6 @@ const LS_CONVERSION_MATRIX ls_conversion_cicp16_cicp14[] = {63, 1.000000000f}, {68, 0.849999964f}, {77, 0.849999964f}, -#else - {0, 1.000000000f}, - {11, 1.000000000f}, - {22, 1.000000000f}, - {33, 1.000000000f}, - {44, 1.000000000f}, - {48, 0.849999964f}, - {55, 1.000000000f}, - {59, 0.849999964f}, - {66, 1.000000000f}, - {77, 1.000000000f}, -#endif }; const LS_CONVERSION_MATRIX ls_conversion_cicp19_cicp6[] = @@ -633,7 +618,6 @@ const LS_CONVERSION_MATRIX ls_conversion_cicp12_cicp16[] = {75, 1.0f} }; -#ifdef FIX_I54_LS_CONVERSION const LS_CONVERSION_MATRIX ls_conversion_cicp12_cicp19[] = { /* First row indicates the number of non-zero elements */ @@ -648,7 +632,6 @@ const LS_CONVERSION_MATRIX ls_conversion_cicp12_cicp19[] = {76, 1.0f}, {89, 1.0f} }; -#endif const LS_CONVERSION_MATRIX ls_conversion_cicp14_cicp19[] = { @@ -708,11 +691,7 @@ const LS_CONVERSION_MAPPING ls_conversion_mapping[LS_SETUP_CONVERSION_NUM_MAPPIN {AUDIO_CONFIG_7_1, AUDIO_CONFIG_5_1, ls_conversion_cicp12_cicp6}, {AUDIO_CONFIG_5_1_2, AUDIO_CONFIG_5_1, ls_conversion_cicp14_cicp6}, -#ifdef FIX_I54_LS_CONVERSION {AUDIO_CONFIG_5_1_2, AUDIO_CONFIG_7_1, ls_conversion_cicp14_cicp12}, -#else - {AUDIO_CONFIG_5_1_2, AUDIO_CONFIG_7_1, ls_conversion_cicp14_cicp6}, -#endif {AUDIO_CONFIG_5_1_4, AUDIO_CONFIG_5_1, ls_conversion_cicp16_cicp6}, {AUDIO_CONFIG_5_1_4, AUDIO_CONFIG_7_1, ls_conversion_cicp16_cicp12}, @@ -740,11 +719,7 @@ const LS_CONVERSION_MAPPING ls_conversion_mapping[LS_SETUP_CONVERSION_NUM_MAPPIN {AUDIO_CONFIG_7_1, AUDIO_CONFIG_5_1_2, ls_conversion_cicp12_cicp14}, {AUDIO_CONFIG_7_1, AUDIO_CONFIG_5_1_4, ls_conversion_cicp12_cicp16}, -#ifdef FIX_I54_LS_CONVERSION {AUDIO_CONFIG_7_1, AUDIO_CONFIG_7_1_4, ls_conversion_cicp12_cicp19}, -#else - {AUDIO_CONFIG_7_1, AUDIO_CONFIG_7_1_4, NULL}, -#endif {AUDIO_CONFIG_5_1_2, AUDIO_CONFIG_5_1_4, NULL}, {AUDIO_CONFIG_5_1_2, AUDIO_CONFIG_7_1_4, ls_conversion_cicp14_cicp19}, diff --git a/lib_rend/ivas_rotation.c b/lib_rend/ivas_rotation.c index d141025ab6..6cf8c65b5d 100644 --- a/lib_rend/ivas_rotation.c +++ b/lib_rend/ivas_rotation.c @@ -310,25 +310,33 @@ void rotateFrame_shd( { int16_t i, l, n, m; int16_t m1, m2; +#ifdef EXT_RENDERER + int16_t shd_rot_max_order; +#else int16_t shd_rot_max_order, fade_len_smp; +#endif float tmp; float tmpRot[2 * HEADROT_ORDER + 1]; float SHrotmat_prev[HEADROT_SHMAT_DIM][HEADROT_SHMAT_DIM]; float SHrotmat[HEADROT_SHMAT_DIM][HEADROT_SHMAT_DIM]; +#ifdef EXT_RENDERER + float cross_fade[L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES]; +#else float cross_fade[IVAS_FB_1MS_48K_SAMP]; +#endif shd_rot_max_order = hTransSetup.ambisonics_order; - /* 1ms linear crossfade */ - fade_len_smp = NS2SA( output_fs, 1000000 ); #ifdef EXT_RENDERER - tmp = 1.0f / (fade_len_smp - 1); - for ( i = 0; i < fade_len_smp; i++ ) + tmp = 1.0f / ( subframe_len - 1 ); + for ( i = 0; i < subframe_len; i++ ) { cross_fade[i] = i * tmp; } #else + /* 1ms linear crossfade */ + fade_len_smp = NS2SA( output_fs, 1000000 ); tmp = 1.0f / fade_len_smp; for ( i = 0; i < fade_len_smp; i++ ) { @@ -368,14 +376,18 @@ void rotateFrame_shd( for ( m = m1; m < m2; m++ ) { /* crossfade with previous rotation gains */ +#ifndef EXT_RENDERER if ( i < fade_len_smp ) { +#endif tmpRot[n - m1] += cross_fade[i] * SHrotmat[n][m] * output[m][subframe_idx * subframe_len + i] + ( 1 - cross_fade[i] ) * SHrotmat_prev[n][m] * output[m][subframe_idx * subframe_len + i]; +#ifndef EXT_RENDERER } else { tmpRot[n - m1] += SHrotmat[n][m] * output[m][subframe_idx * subframe_len + i]; } +#endif } } /* write back the result */ @@ -434,29 +446,35 @@ void rotateFrame_sd( int16_t nchan, index_lfe; int16_t ch_in, ch_in_woLFE, ch_out, ch_out_woLFE; int16_t azimuth, elevation; +#ifndef EXT_RENDERER int16_t fade_len_smp; +#endif float tmp; float tmp_gains[MAX_CICP_CHANNELS - 1]; float gains[MAX_CICP_CHANNELS][MAX_CICP_CHANNELS]; float gains_prev[MAX_CICP_CHANNELS][MAX_CICP_CHANNELS]; float output_tmp[MAX_CICP_CHANNELS][L_FRAME48k]; +#ifdef EXT_RENDERER + float cross_fade[L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES]; +#else float cross_fade[IVAS_FB_1MS_48K_SAMP]; +#endif wmops_sub_start( "rotateFrame_sd" ); nchan = hTransSetup.nchan_out_woLFE + hTransSetup.num_lfe; index_lfe = hTransSetup.index_lfe[0]; - /* 1ms linear crossfade */ - fade_len_smp = NS2SA( output_Fs, 1000000 ); #ifdef EXT_RENDERER - tmp = 1.0f / (fade_len_smp - 1); - for ( i = 0; i < fade_len_smp; i++ ) + tmp = 1.0f / ( subframe_len - 1 ); + for ( i = 0; i < subframe_len; i++ ) { cross_fade[i] = i * tmp; } #else + /* 1ms linear crossfade */ + fade_len_smp = NS2SA( output_Fs, 1000000 ); tmp = 1.0f / fade_len_smp; for ( i = 0; i < fade_len_smp; i++ ) { @@ -539,15 +557,21 @@ void rotateFrame_sd( { for ( ch_in = 0; ch_in < nchan; ch_in++ ) { - /* crossfade with previous rotation gains */ +/* crossfade with previous rotation gains */ +#ifdef EXT_RENDERER + for ( i = subframe_idx * subframe_len, j = 0; j < subframe_len; i++, j++ ) +#else for ( i = subframe_idx * subframe_len, j = 0; j < fade_len_smp; i++, j++ ) +#endif { output_tmp[ch_out][i] += ( cross_fade[j] ) * gains[ch_in][ch_out] * output[ch_in][i] + ( 1 - cross_fade[j] ) * gains_prev[ch_in][ch_out] * output[ch_in][i]; } +#ifndef EXT_RENDERER for ( ; i < ( subframe_idx + 1 ) * subframe_len; i++ ) { output_tmp[ch_out][i] += gains[ch_in][ch_out] * output[ch_in][i]; } +#endif } } diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index f64f707230..52acf50aab 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -76,12 +76,13 @@ struct IVAS_REND /* =============================== */ /* Helpers */ - int16_t numOutChannels; /* Total number of output channels */ - int16_t numInChannels; /* Total number of input channels */ - int16_t numInChannelsObj; /* Total number of input channels of object inputs */ - int16_t numInChannelsAmbi; /* Total number of input channels of ambisonics inputs */ - int16_t numInChannelsMc; /* Total number of input channels of multichannel inputs */ - int16_t numInChannelsMasa; /* Total number of input channels of MASA inputs */ + int16_t numOutChannels; /* Total number of output channels */ + int16_t numInChannels; /* Total number of input channels */ + int16_t numInChannelsObj; /* Total number of input channels of object inputs */ + int16_t numInChannelsAmbi; /* Total number of input channels of ambisonics inputs */ + int16_t numInChannelsMc; /* Total number of input channels of multichannel inputs */ + int16_t numInChannelsMasa; /* Total number of input channels of MASA inputs */ + float delayOffsetBuffer[MAX_OUTPUT_CHANNELS][NS2SA( 48000, IVAS_FB_DEC_DELAY_NS )]; /* Buffer for delay compensation */ /* For each channel of MC inputs mcPassThrough contains the corresponding * output channel index if a passthrough is possible, otherwise contains -1 */ @@ -90,7 +91,8 @@ struct IVAS_REND /* =========== LFE Handling =========== */ /* Do not drop LFE when rendering to a layout that does not have * an LFE channel - render LFE into other channels*/ - int8_t neverDropLfe; /* flag */ + int8_t neverDropLfe; /* flag */ + int8_t forceBinLfeLpf; /* flag : force low-pass filtering for LFE channel in binaural rendering */ float *lfePanGains; ivas_filters_process_state_t lfeLpFilter; @@ -321,12 +323,18 @@ IVAS_REND_HANDLE IVAS_REND_Open() st->decDummyMasaBin = NULL; st->enableHeadRotation = 0; st->rendererConfigEnabled = 0; + st->forceBinLfeLpf = 0; for ( i = 0; i < RENDERER_HEAD_POSITIONS_PER_FRAME; ++i ) { st->headRotationData[i] = quaternionInit(); } + for ( i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) + { + set_zero( st->delayOffsetBuffer[i], L_FRAME48k ); + } + return st; } @@ -446,6 +454,24 @@ static ivas_error initDecoderDummyForAmbiToBinaural( DecoderDummy *decDummyAmbiB return error; } +/* Fixes initialization issues in TD renderer. Should get fixed properly soon. + See issue: https://forge.3gpp.org/rep/ivas-codec-pc/ivas-codec/-/issues/81 */ +static void tmpFixBuggyTdBinRendInit(BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd) +{ + int32_t i, j; + + for (i=0; i < hBinRendererTd->NumOfSrcs; ++i) + { + for (j=0; j < SPAT_BIN_MAX_INPUT_CHANNELS; ++j) + { + hBinRendererTd->Sources[i]->SrcRend_p->SfxSpatBin_p[j].LeftFilter_p = NULL; + hBinRendererTd->Sources[i]->SrcRend_p->SfxSpatBin_p[j].LeftFilterIncr_p = NULL; + hBinRendererTd->Sources[i]->SrcRend_p->SfxSpatBin_p[j].RightFilter_p = NULL; + hBinRendererTd->Sources[i]->SrcRend_p->SfxSpatBin_p[j].RightFilterIncr_p = NULL; + } + } +} + static ivas_error initDecoderDummyForObjToBinaural( DecoderDummy *decDummyObjBin, IVAS_REND_InputConfig inConfig, IVAS_REND_BinauralFormat binauralFormat ) { ivas_error error; @@ -489,6 +515,7 @@ static ivas_error initDecoderDummyForObjToBinaural( DecoderDummy *decDummyObjBin { return error; } + tmpFixBuggyTdBinRendInit(decDummyObjBin->hBinRendererTd); } return error; @@ -681,7 +708,7 @@ ivas_error IVAS_REND_Configure( IVAS_REND_HANDLE st, st->tmpGainBuffer = count_calloc( getNumChannelsInSpeakerLayout( IVAS_REND_SPEAKER_LAYOUT_7_1_4 ), sizeof( float ) ); st->noLfePanBuffer = count_calloc( getNumNonLfeChannelsInSpeakerLayout( IVAS_REND_SPEAKER_LAYOUT_7_1_4 ), sizeof( float ) ); } - else + else if ( st->outConfig.binauralFormat == IVAS_REND_BINAURAL_NONE ) { st->tmpGainBuffer = count_calloc( st->numOutChannels, sizeof( float ) ); } @@ -717,7 +744,7 @@ ivas_error IVAS_REND_Configure( IVAS_REND_HANDLE st, { st->objPanInfo[i].panGains = count_calloc( getNumChannelsInSpeakerLayout( IVAS_REND_SPEAKER_LAYOUT_7_1_4 ), sizeof( float ) ); } - else + else if ( st->outConfig.binauralFormat == IVAS_REND_BINAURAL_NONE ) { st->objPanInfo[i].panGains = count_calloc( st->numOutChannels, sizeof( float ) ); } @@ -1238,7 +1265,16 @@ ivas_error IVAS_REND_GetDelay( ( ( st->decDummyMcBin->renderer_type == RENDERER_BINAURAL_MIXER_CONV ) || ( st->decDummyMcBin->renderer_type == RENDERER_BINAURAL_MIXER_CONV_ROOM ) ) ) { - *nSamples = NS2SA( st->sampleRate, (int32_t) ( (float) st->decDummyMcBin->binaural_latency_ns + 0.5f ) ); + if ( st->forceBinLfeLpf ) + { + *nSamples = max( + NS2SA( st->sampleRate, (int32_t) ( (float) st->decDummyMcBin->binaural_latency_ns + 0.5f ) ), + NS2SA( st->sampleRate, ivas_lfe_lpf_delay[IVAS_FILTER_ORDER_4 - 3] * 1000000000L ) ); + } + else + { + *nSamples = NS2SA( st->sampleRate, (int32_t) ( (float) st->decDummyMcBin->binaural_latency_ns + 0.5f ) ); + } } else { @@ -1830,21 +1866,22 @@ static void renderChannelsToBinaural( IVAS_REND_AudioBuffer outAudio ) { int16_t i; - int16_t subFrameLength; - int16_t lfeLpDelay; - uint32_t mcIdx; - uint32_t inMcChannelIdx; - uint32_t lfeChIdx; - float tmpLfeBuffer[L_FRAME48k]; - float tmpBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; - float gain_lin; + int16_t lfeChIdx; + int16_t frameLength, subFrameLength; + int16_t binauralDelaySmp, lfeDelaySmp; + int16_t offset; + uint32_t mcIdx, inMcChannelIdx; int32_t numInChannels; + float gain_lin; + float tmpBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; + float tmpLfeBuffer[L_FRAME48k + NS2SA( 48000, ivas_lfe_lpf_delay[IVAS_FILTER_ORDER_4 - 3] * 1000000000L )]; #ifdef WMOPS wmops_sub_start( "renderChannelsToBinaural" ); #endif - subFrameLength = (int16_t) ( st->sampleRate / FRAMES_PER_SEC / RENDERER_HEAD_POSITIONS_PER_FRAME ); + frameLength = (int16_t) ( st->sampleRate / FRAMES_PER_SEC ); + subFrameLength = (int16_t) ( frameLength / RENDERER_HEAD_POSITIONS_PER_FRAME ); if ( st->enableHeadRotation ) { copyHeadRotToDecDummy( st->headRotationData, st->decDummyMcBin ); @@ -1880,24 +1917,52 @@ static void renderChannelsToBinaural( ivas_crend_process( st->decDummyMcBin, tmpBuffer ); } - /* Low-pass filter the LFE channel with delay compensation */ - lfeLpDelay = (int16_t) ( ivas_lfe_lpf_delay[1] * (float) st->sampleRate ); - if ( st->inConfig.multiChannelBuses[mcIdx].speakerLayout == IVAS_REND_SPEAKER_LAYOUT_CUSTOM ) - { - lfeChIdx = st->inConfig.inSetupCustom->lfe_idx[0]; - } - else + /* TODO tmu : this is always disabled */ + if ( st->forceBinLfeLpf ) { - lfeChIdx = LFE_CHANNEL; + if ( st->inConfig.multiChannelBuses[mcIdx].speakerLayout == IVAS_REND_SPEAKER_LAYOUT_CUSTOM ) + { + lfeChIdx = st->inConfig.inSetupCustom->lfe_idx[0]; + } + else + { + lfeChIdx = LFE_CHANNEL; + } + set_zero( tmpLfeBuffer, frameLength ); + mvr2r( tmpBuffer[lfeChIdx], tmpLfeBuffer, frameLength ); + + /* Low pass filtering */ + ivas_filter_process( &st->lfeLpFilter, tmpLfeBuffer, frameLength ); + + /* Delay adjustment */ + lfeDelaySmp = NS2SA( st->sampleRate, ivas_lfe_lpf_delay[IVAS_FILTER_ORDER_4 - 3] * 1000000000L ); + binauralDelaySmp = NS2SA( st->sampleRate, st->decDummyMcBin->binaural_latency_ns ); + + if ( lfeDelaySmp > binauralDelaySmp ) + { + /* delay binauralised signal */ + offset = lfeDelaySmp - binauralDelaySmp; + for ( i = 0; i < numInChannels; ++i ) + { + if ( i == lfeChIdx ) + { + continue; + } + delay_signal( tmpBuffer[i], frameLength, st->delayOffsetBuffer[i], offset ); + } + } + else if ( lfeDelaySmp < binauralDelaySmp ) + { + /* delay LFE signal */ + offset = binauralDelaySmp - lfeDelaySmp; + delay_signal( tmpLfeBuffer, frameLength, st->delayOffsetBuffer[lfeChIdx], offset ); + } + + mvr2r( tmpLfeBuffer, tmpBuffer[lfeChIdx], frameLength ); } - /* TODO tmu : needs verification */ - mvr2r( tmpBuffer[lfeChIdx], tmpLfeBuffer, L_FRAME48k ); - ivas_filter_process( &st->lfeLpFilter, tmpLfeBuffer, L_FRAME48k ); - set_zero( tmpBuffer[lfeChIdx], L_FRAME48k ); - mvr2r( &tmpLfeBuffer[lfeLpDelay], &tmpBuffer[lfeChIdx][0], L_FRAME48k - lfeLpDelay ); + ivas_binaural_add_LFE( st->decDummyMcBin, frameLength, tmpBuffer ); - ivas_binaural_add_LFE( st->decDummyMcBin, L_FRAME48k, tmpBuffer ); copy2dArrayToBuffer( tmpBuffer, &outAudio, 0, st->numOutChannels ); } @@ -1962,7 +2027,7 @@ static void renderObjectsToBinaural( st->decDummyObjBin->hIsmMetaData[objIdx]->azimuth = (float) tmpAzi; st->decDummyObjBin->hIsmMetaData[objIdx]->elevation = (float) tmpEle; } - else if ( st->outConfig.binauralFormat == IVAS_REND_BINAURAL_ROOM ) + else { st->decDummyObjBin->hIsmMetaData[objIdx]->azimuth = metadataBuffer.positions[objIdx].azimuth; st->decDummyObjBin->hIsmMetaData[objIdx]->elevation = metadataBuffer.positions[objIdx].elevation; @@ -1982,13 +2047,14 @@ static void renderObjectsToBinaural( for ( objIdx = 0; objIdx < metadataBuffer.numObjects; ++objIdx ) { /* Convert ISM to 7_1_4 for BINAURAL_ROOM */ + /* TODO tmu : subframe rotation can be enabled here */ getSpeakerGains( st, st->decDummyObjBin->hIsmMetaData[objIdx]->azimuth, st->decDummyObjBin->hIsmMetaData[objIdx]->elevation, st->tmpGainBuffer ); for ( chInIdx = 0; chInIdx < getNumChannelsInSpeakerLayout( IVAS_REND_SPEAKER_LAYOUT_7_1_4 ); ++chInIdx ) { if ( fabsf( st->tmpGainBuffer[chInIdx] ) > 0.0f || fabsf( st->objPanInfo[objIdx].panGains[chInIdx] ) > 0.0f ) { - for ( smplIdx = 0; smplIdx < L_FRAME48k; ++smplIdx ) + for ( smplIdx = 0; smplIdx < inAudio.config.bufferSize; ++smplIdx ) { fadeIn = st->crossfade[smplIdx]; fadeOut = 1.0f - fadeIn; @@ -2273,7 +2339,7 @@ static void prepareLfeHandling( /* Pan LFE to L and R with -3dB gain */ if ( st->numOutChannels > 1 ) { - /* TODO tmu : not guaranteed to be L and R for custom layouts without LFE */ + /* TODO tmu : not guaranteed to be L and R for custom layouts without LFE! */ st->lfePanGains[0] = sqrtf( 0.5f ); st->lfePanGains[1] = sqrtf( 0.5f ); } @@ -2885,6 +2951,8 @@ static ivas_error getHoaRenderMtx( case IVAS_REND_SPEAKER_LAYOUT_MONO: hOutSetup.ls_azimuth = ls_azimuth_CICP1; hOutSetup.ls_elevation = ls_elevation_CICP1; + ivas_output_init( &hOutSetup, mapRendLayoutToAudioConfig( outConfig.speakerLayout ) ); + break; case IVAS_REND_SPEAKER_LAYOUT_STEREO: case IVAS_REND_SPEAKER_LAYOUT_5_1: case IVAS_REND_SPEAKER_LAYOUT_7_1: diff --git a/scripts/pyaudio3dtools/audiofile.py b/scripts/pyaudio3dtools/audiofile.py index 32d8460e1d..b03b472ae9 100644 --- a/scripts/pyaudio3dtools/audiofile.py +++ b/scripts/pyaudio3dtools/audiofile.py @@ -35,6 +35,7 @@ import platform import shutil import struct import subprocess as sp +import warnings from importlib import import_module from tempfile import TemporaryDirectory from typing import Optional, Tuple @@ -73,6 +74,18 @@ def readfile( if file_extension == ".wav": fs, data = wav.read(filename) + if data.dtype == np.int32: + data = np.interp( + data, + (np.iinfo(np.int32).min, np.iinfo(np.int32).max), + (np.iinfo(np.int16).min, np.iinfo(np.int16).max), + ) + elif data.dtype == np.float32: + data = np.interp( + data, + (-1, 1), + (np.iinfo(np.int16).min, np.iinfo(np.int16).max), + ) x = np.array(data, dtype=outdtype) file_len = x.shape[0] if x.ndim == 1: @@ -107,9 +120,11 @@ def writefile(filename: str, x: np.ndarray, fs: int = 48000) -> None: """ _, file_extension = os.path.splitext(os.path.basename(filename)) - clipped_samples = np.sum(np.logical_or(x < np.iinfo(np.int16).min, x > np.iinfo(np.int16).max)) + clipped_samples = np.sum( + np.logical_or(x < np.iinfo(np.int16).min, x > np.iinfo(np.int16).max) + ) if clipped_samples > 0: - print(" Warning: %i samples clipped"%clipped_samples) + warnings.warn(f" Warning: {clipped_samples} samples clipped") x = np.clip(x, np.iinfo(np.int16).min, np.iinfo(np.int16).max) if file_extension == ".wav": diff --git a/scripts/pyaudio3dtools/binauralrenderer.py b/scripts/pyaudio3dtools/binauralrenderer.py index d34d59babe..23f476a5fd 100644 --- a/scripts/pyaudio3dtools/binauralrenderer.py +++ b/scripts/pyaudio3dtools/binauralrenderer.py @@ -304,8 +304,8 @@ def binaural_fftconv_framewise( [np.repeat(ele, N_frames // len(ele)), ele[: N_frames % len(ele)]] ) - iGs = np.zeros([N_frames], dtype=int) - mGs = np.zeros([N_frames], dtype=int) + iGs = np.zeros([N_frames + 1], dtype=int) + mGs = np.zeros([N_frames + 1], dtype=int) # store trajectory as a sequence of indices of source positions # on the HRTF database in a compressed format such that, for @@ -427,8 +427,9 @@ def binaural_fftconv_framewise( np.squeeze(x[i1:i2]), G_n_m ) - y[i1:i2p, i_ear] += ( - fade_out * y0[0, i1:i2p, i_ear] + fade_in * y0[1, i1:i2p, i_ear] + y[i1:i2p, i_ear] = ( + np.squeeze(fade_out) * y0[0, i1:i2p, i_ear] + + np.squeeze(fade_in) * y0[1, i1:i2p, i_ear] ) t1 = timeit.default_timer() @@ -466,7 +467,8 @@ def binaural_fftconv_framewise( y0[1, j1:j2p, i_ear] += sig.oaconvolve(np.squeeze(x[j1:j2]), G1) y[i1:i2, i_ear] = ( - fade_out * y0[0, i1:i2, i_ear] + fade_in * y0[1, i1:i2, i_ear] + np.squeeze(fade_out) * y0[0, i1:i2, i_ear] + + np.squeeze(fade_in) * y0[1, i1:i2, i_ear] ) t1 = timeit.default_timer() @@ -492,7 +494,6 @@ def binaural_render_LFE( fs: int = 48000, lfe_index: list = [3], LFE_gain: float = 10 ** (5.5 / 20), - hrir_latency_smp: float = 0, ) -> np.ndarray: lfe = x[:, lfe_index].copy() @@ -511,8 +512,8 @@ def binaural_render_LFE( filter_delay = int(3.5 * fs / 1000) # delay adjustment - lfe = np.roll(lfe, filter_delay, axis=0) - lfe[:filter_delay, :] = 0 + lfe = np.roll(lfe, -filter_delay, axis=0) + lfe[-filter_delay:, :] = 0 # apply gain lfe *= LFE_gain @@ -583,7 +584,6 @@ def render_custom_ls_binaural( def render_ism_binaural( x: np.ndarray, fs: int, - in_format: spatialaudioformat.Format, IR: np.ndarray, SourcePosition: np.ndarray, trajectory: np.ndarray, @@ -606,8 +606,7 @@ def render_ism_binaural( # extract positions only according to the audio duration pos_data = pos_data[:N_frames, :] - if trajectory is not None: - azi, ele = rotateISM(pos_data[:, 0], pos_data[:, 1], trajectory=trajectory) + azi, ele = rotateISM(pos_data[:, 0], pos_data[:, 1], trajectory=trajectory) y = np.zeros([sig_len, 2]) y += binaural_fftconv_framewise( @@ -706,7 +705,7 @@ def binaural_rendering( # prepare LFE signal to be added to output if include_LFE and in_format.isloudspeaker: - lfe = binaural_render_LFE(x, 48000, in_format.lfe_index, LFE_gain, latency_smp) + lfe = binaural_render_LFE(x, 48000, in_format.lfe_index, LFE_gain) # get binauralized signal based on format if in_format.name.startswith("CUSTOM_LS"): @@ -717,7 +716,6 @@ def binaural_rendering( y = render_ism_binaural( x, fs, - in_format, IR, SourcePosition, trajectory, @@ -732,14 +730,14 @@ def binaural_rendering( f"{in_format.name} -> {out_format.name}: format conversion not implemented" ) - # add LFE signal to output - if include_LFE and in_format.isloudspeaker: - y += lfe - # HRTF delay compensation y = np.roll(y, -latency_smp, axis=0) y[-latency_smp:, :] = 0 + # add LFE signal to output + if include_LFE and in_format.isloudspeaker: + y += lfe + # resample back to original rate y = audioarray.resample(y, 48000, fs) diff --git a/scripts/pyaudio3dtools/spatialaudioconvert.py b/scripts/pyaudio3dtools/spatialaudioconvert.py index 3d4a4d95d5..28f9298924 100644 --- a/scripts/pyaudio3dtools/spatialaudioconvert.py +++ b/scripts/pyaudio3dtools/spatialaudioconvert.py @@ -129,11 +129,13 @@ def spatial_audio_convert( """ get spatial input and audio format configurations """ if in_format is None: - in_format = spatialaudioformat.Format.detect_format(in_nchans) - logger.info(f" Input spatial audio format detected: {in_format}") + if in_nchans is not None: + in_format = spatialaudioformat.Format.detect_format(in_nchans) + in_spfmt = spatialaudioformat.Format(in_format) + logger.info(f" Input spatial audio format detected: {in_format}") else: logger.info(f" Input spatial audio format: {in_format}") - in_spfmt = spatialaudioformat.Format(in_format) + in_spfmt = spatialaudioformat.Format(in_format) if out_format is None: out_format = in_format @@ -162,6 +164,10 @@ def spatial_audio_convert( in_sig, in_fs = audiofile.readfile(in_file, fs=in_fs, nchannels=in_nchans) elif input_ext == ".wav": in_sig, in_fs = audiofile.readfile(in_file) + if in_format is None: + in_format = spatialaudioformat.Format.detect_format(in_sig.shape[1]) + in_spfmt = spatialaudioformat.Format(in_format) + # Adjust number of channels if case of HOA, zeroed vert channels if planar if in_spfmt.ambi_order > 0: in_sig = audioarray.convert(in_sig, out_nchans=in_spfmt.nchannels) @@ -197,11 +203,9 @@ def spatial_audio_convert( metadata_obj = spatialmetadata.Metadata() metadata_obj.init_for_ism(in_file, in_fs, in_meta_files) - # TODO alternative paths for binaural rendering for now + # TODO decide on reference path for BINAURAL_ROOM if out_spfmt.name.startswith("BINAURAL_ROOM"): in_format = "7_1_4" - elif out_spfmt.name.startswith("BINAURAL"): - in_format = "HOA3" else: in_format = out_format in_spfmt = spatialaudioformat.Format(in_format) diff --git a/scripts/pyaudio3dtools/spatialaudioformat.py b/scripts/pyaudio3dtools/spatialaudioformat.py index 01721f4329..9125d80b64 100644 --- a/scripts/pyaudio3dtools/spatialaudioformat.py +++ b/scripts/pyaudio3dtools/spatialaudioformat.py @@ -452,10 +452,9 @@ class Format: def detect_format(nchannels: int) -> str: config_name = None - for config_name in _format_configs: - dictionary = _format_configs[config_name] - if dictionary["nchannels"] == nchannels: - config_name = dictionary["name"] + for k, v in _format_configs.items(): + if v["nchannels"] == nchannels: + config_name = v["name"] break if config_name is None: diff --git a/scripts/tests/test_renderer.py b/scripts/tests/test_renderer.py index 7acd2a9028..c66a4747d6 100644 --- a/scripts/tests/test_renderer.py +++ b/scripts/tests/test_renderer.py @@ -27,18 +27,23 @@ """ import subprocess as sp -import pyaudio3dtools -import pytest -import numpy as np from pathlib import PurePath from typing import Optional, Tuple +import numpy as np +import pyaudio3dtools +import pytest + from .compare_audio import compare_audio_arrays from .constants import * def check_BE( - ref: np.ndarray, ref_fs: int, cut: np.ndarray, cut_fs: int, snr_min: float = np.inf + test_info, + ref: np.ndarray, + ref_fs: int, + cut: np.ndarray, + cut_fs: int, ): if ref is None or np.array_equal(ref, np.zeros_like(ref)): @@ -52,10 +57,22 @@ def check_BE( if np.isnan(snr) or gain_b == 0: pytest.fail("Invalid comparison result, check your signals!") - if not np.allclose(ref, cut, rtol=0, atol=2) and snr < snr_min: - pytest.fail( - f"CuT not BE to REF! SNR : {snr:3.2f} dB, Gain CuT: {gain_b:1.3f}, Max Diff = {int(max_diff)}" - ) + # try to get a minimum SNR from the config + if test_info.node.name in pass_snr: + snr_min = pass_snr.get(test_info.node.name) + else: + snr_min = np.inf + + # check max_diff as well, since compare_audio_arrays will try to adjust for small delay differences + if not np.allclose(ref, cut, rtol=0, atol=2) and max_diff > 2: + if snr >= snr_min: + pytest.xfail( + f"xfailed with minimum SNR {snr_min} vs {snr:3.2f}dB, Gain CuT: {gain_b:1.3f}, Max Diff = {int(max_diff)}" + ) + else: + pytest.fail( + f"CuT not BE to REF! SNR : {snr:3.2f} dB, Gain CuT: {gain_b:1.3f}, Max Diff = {int(max_diff)}" + ) def run_pyscripts( @@ -101,7 +118,6 @@ def run_pyscripts( return pyaudio3dtools.audiofile.readfile(out_file) -# TODO include sampling rate, ndl ? def run_renderer( in_fmt: str, out_fmt: str, @@ -154,33 +170,39 @@ def run_renderer( return pyaudio3dtools.audiofile.readfile(out_file) +# fixture returns test information, enabling per-testcase SNR +@pytest.fixture +def test_info(request): + return request + + # Ambisonics / loudspeaker based input formats @pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS) @pytest.mark.parametrize("in_fmt", INPUT_FORMATS_AMBI) -def test_ambisonics(in_fmt, out_fmt): +def test_ambisonics(test_info, in_fmt, out_fmt): ref, ref_fs = run_pyscripts(in_fmt, out_fmt) cut, cut_fs = run_renderer(in_fmt, out_fmt) - check_BE(ref, ref_fs, cut, cut_fs) + check_BE(test_info, ref, ref_fs, cut, cut_fs) @pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS) @pytest.mark.parametrize("in_fmt", INPUT_FORMATS_MC) -def test_multichannel(in_fmt, out_fmt): +def test_multichannel(test_info, in_fmt, out_fmt): ref, ref_fs = run_pyscripts(in_fmt, out_fmt) cut, cut_fs = run_renderer(in_fmt, out_fmt) if out_fmt in ["MONO", "STEREO"]: - check_BE(ref, ref_fs, cut, cut_fs, snr_min=10) + check_BE(test_info, ref, ref_fs, cut, cut_fs) else: - check_BE(ref, ref_fs, cut, cut_fs) + check_BE(test_info, ref, ref_fs, cut, cut_fs) @pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS) @pytest.mark.parametrize("in_layout", CUSTOM_LS_TO_TEST) -def test_custom_ls_input(in_layout, out_fmt): +def test_custom_ls_input(test_info, in_layout, out_fmt): ref, ref_fs = run_pyscripts( CUSTOM_LAYOUT_DIR.joinpath(f"{in_layout}.txt"), out_fmt, @@ -188,12 +210,12 @@ def test_custom_ls_input(in_layout, out_fmt): cut, cut_fs = run_renderer(CUSTOM_LAYOUT_DIR.joinpath(f"{in_layout}.txt"), out_fmt) - check_BE(ref, ref_fs, cut, cut_fs) + check_BE(test_info, ref, ref_fs, cut, cut_fs) @pytest.mark.parametrize("out_fmt", CUSTOM_LS_TO_TEST) @pytest.mark.parametrize("in_fmt", OUTPUT_FORMATS) -def test_custom_ls_output(in_fmt, out_fmt): +def test_custom_ls_output(test_info, in_fmt, out_fmt): ref, ref_fs = run_pyscripts( in_fmt, CUSTOM_LAYOUT_DIR.joinpath(f"{out_fmt}.txt"), @@ -201,12 +223,12 @@ def test_custom_ls_output(in_fmt, out_fmt): cut, cut_fs = run_renderer(in_fmt, CUSTOM_LAYOUT_DIR.joinpath(f"{out_fmt}.txt")) - check_BE(ref, ref_fs, cut, cut_fs) + check_BE(test_info, ref, ref_fs, cut, cut_fs) @pytest.mark.parametrize("out_fmt", CUSTOM_LS_TO_TEST) @pytest.mark.parametrize("in_fmt", CUSTOM_LS_TO_TEST) -def test_custom_ls_input_output(in_fmt, out_fmt): +def test_custom_ls_input_output(test_info, in_fmt, out_fmt): ref, ref_fs = run_pyscripts( CUSTOM_LAYOUT_DIR.joinpath(f"{in_fmt}.txt"), CUSTOM_LAYOUT_DIR.joinpath(f"{out_fmt}.txt"), @@ -217,13 +239,13 @@ def test_custom_ls_input_output(in_fmt, out_fmt): CUSTOM_LAYOUT_DIR.joinpath(f"{out_fmt}.txt"), ) - check_BE(ref, ref_fs, cut, cut_fs) + check_BE(test_info, ref, ref_fs, cut, cut_fs) # Metadata / parametric input formats @pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS) @pytest.mark.parametrize("in_fmt", INPUT_FORMATS_ISM) -def test_ism(in_fmt, out_fmt): +def test_ism(test_info, in_fmt, out_fmt): ref, ref_fs = run_pyscripts( in_fmt, out_fmt, in_meta_files=FORMAT_TO_METADATA_FILES[in_fmt] ) @@ -233,15 +255,12 @@ def test_ism(in_fmt, out_fmt): in_meta_files=FORMAT_TO_METADATA_FILES[in_fmt], ) - # ISM to Ambisonics has differences due to optimizations in ivas_dirac_dec_get_response() - # additionally, positions parsed from the metadata files in C seem to be different - # due to (float) atof() reading being subsequently cast to int16_t - check_BE(ref, ref_fs, cut, cut_fs, snr_min=38) + check_BE(test_info, ref, ref_fs, cut, cut_fs) @pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS) @pytest.mark.parametrize("in_fmt", INPUT_FORMATS_MASA) -def test_masa(in_fmt, out_fmt): +def test_masa(test_info, in_fmt, out_fmt): # TODO: implement MASA in Python, compare BE # ref, ref_fs = run_pyscripts( # in_fmt, out_fmt, in_meta_files=FORMAT_TO_METADATA_FILES[in_fmt] @@ -253,12 +272,12 @@ def test_masa(in_fmt, out_fmt): in_meta_files=FORMAT_TO_METADATA_FILES[in_fmt], ) - # check_BE(ref, ref_fs, cut, cut_fs) + # check_BE(test_info, ref, ref_fs, cut, cut_fs) @pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS) @pytest.mark.parametrize("in_fmt", METADATA_SCENES_TO_TEST) -def test_metadata(in_fmt, out_fmt): +def test_metadata(test_info, in_fmt, out_fmt): ref, ref_fs = run_pyscripts( "META", out_fmt, metadata_input=TEST_VECTOR_DIR.joinpath(f"{in_fmt}.txt") ) @@ -269,12 +288,12 @@ def test_metadata(in_fmt, out_fmt): metadata_input=TEST_VECTOR_DIR.joinpath(f"{in_fmt}.txt"), ) - check_BE(ref, ref_fs, cut, cut_fs, snr_min=11) + check_BE(test_info, ref, ref_fs, cut, cut_fs) @pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS) @pytest.mark.parametrize("in_fmt", METADATA_SCENES_TO_TEST_NO_BE) -def test_metadata_masa(in_fmt, out_fmt): +def test_metadata_masa(test_info, in_fmt, out_fmt): # TODO: unify with test_metadata once Python supports MASA cut, cut_fs = run_renderer( "META", @@ -286,18 +305,17 @@ def test_metadata_masa(in_fmt, out_fmt): # Binaural rendering (static) @pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL) @pytest.mark.parametrize("in_fmt", INPUT_FORMATS_AMBI) -def test_ambisonics_binaural_static(in_fmt, out_fmt): +def test_ambisonics_binaural_static(test_info, in_fmt, out_fmt): ref, ref_fs = run_pyscripts(in_fmt, out_fmt) cut, cut_fs = run_renderer(in_fmt, out_fmt) - check_BE(ref, ref_fs, cut, cut_fs, snr_min=0.1) + check_BE(test_info, ref, ref_fs, cut, cut_fs) -@pytest.mark.xfail(reason="Python cannot be BE to TD Object Renderer") @pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL) @pytest.mark.parametrize("in_fmt", INPUT_FORMATS_ISM) -def test_ism_binaural_static(in_fmt, out_fmt): +def test_ism_binaural_static(test_info, in_fmt, out_fmt): try: in_meta_files = FORMAT_TO_METADATA_FILES[in_fmt] except: @@ -307,24 +325,24 @@ def test_ism_binaural_static(in_fmt, out_fmt): cut, cut_fs = run_renderer(in_fmt, out_fmt, in_meta_files=in_meta_files) - check_BE(ref, ref_fs, cut, cut_fs) + check_BE(test_info, ref, ref_fs, cut, cut_fs) @pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL) @pytest.mark.parametrize("in_fmt", INPUT_FORMATS_MC[2:]) -def test_multichannel_binaural_static(in_fmt, out_fmt): +def test_multichannel_binaural_static(test_info, in_fmt, out_fmt): ref, ref_fs = run_pyscripts(in_fmt, out_fmt) cut, cut_fs = run_renderer(in_fmt, out_fmt) - check_BE(ref, ref_fs, cut, cut_fs, snr_min=4.5) + check_BE(test_info, ref, ref_fs, cut, cut_fs) # Binaural rendering (head rotation) @pytest.mark.parametrize("trj_file", HR_TRAJECTORIES_TO_TEST) @pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL) @pytest.mark.parametrize("in_fmt", INPUT_FORMATS_AMBI) -def test_ambisonics_binaural_headrotation(in_fmt, out_fmt, trj_file): +def test_ambisonics_binaural_headrotation(test_info, in_fmt, out_fmt, trj_file): ref, ref_fs = run_pyscripts( in_fmt, out_fmt, @@ -337,22 +355,13 @@ def test_ambisonics_binaural_headrotation(in_fmt, out_fmt, trj_file): trj_file=HR_TRAJECTORY_DIR.joinpath(f"{trj_file}.csv"), ) - check_BE(ref, ref_fs, cut, cut_fs, snr_min=0.04) + check_BE(test_info, ref, ref_fs, cut, cut_fs) @pytest.mark.parametrize("trj_file", HR_TRAJECTORIES_TO_TEST) -@pytest.mark.parametrize( - "out_fmt", - [ - pytest.param( - "BINAURAL", - marks=pytest.mark.xfail(reason="Python cannot be BE to TD Object Renderer"), - ), - "BINAURAL_ROOM", - ], -) +@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL) @pytest.mark.parametrize("in_fmt", INPUT_FORMATS_ISM) -def test_ism_binaural_headrotation(in_fmt, out_fmt, trj_file): +def test_ism_binaural_headrotation(test_info, in_fmt, out_fmt, trj_file): try: in_meta_files = FORMAT_TO_METADATA_FILES[in_fmt] except: @@ -372,37 +381,13 @@ def test_ism_binaural_headrotation(in_fmt, out_fmt, trj_file): in_meta_files=in_meta_files, ) - check_BE(ref, ref_fs, cut, cut_fs, snr_min=1.3) + check_BE(test_info, ref, ref_fs, cut, cut_fs) @pytest.mark.parametrize("trj_file", HR_TRAJECTORIES_TO_TEST) -@pytest.mark.parametrize( - "out_fmt", - [ - pytest.param( - "BINAURAL", - marks=pytest.mark.xfail(reason="Python cannot be BE to TD Object Renderer"), - ), - "BINAURAL_ROOM", - ], -) -@pytest.mark.parametrize( - "in_fmt", - [ - pytest.param( - "5_1", - marks=pytest.mark.xfail(reason="Python cannot be BE to TD Object Renderer"), - ), - pytest.param( - "7_1", - marks=pytest.mark.xfail(reason="Python cannot be BE to TD Object Renderer"), - ), - "5_1_2", - "5_1_4", - "7_1_4", - ], -) -def test_multichannel_binaural_headrotation(in_fmt, out_fmt, trj_file): +@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL) +@pytest.mark.parametrize("in_fmt", INPUT_FORMATS_MC[2:]) +def test_multichannel_binaural_headrotation(test_info, in_fmt, out_fmt, trj_file): ref, ref_fs = run_pyscripts( in_fmt, out_fmt, @@ -415,4 +400,97 @@ def test_multichannel_binaural_headrotation(in_fmt, out_fmt, trj_file): trj_file=HR_TRAJECTORY_DIR.joinpath(f"{trj_file}.csv"), ) - check_BE(ref, ref_fs, cut, cut_fs, snr_min=2.3) + check_BE(test_info, ref, ref_fs, cut, cut_fs) + + +# per-testcase passing SNR +pass_snr = { + "test_ambisonics_binaural_headrotation[FOA-BINAURAL_ROOM-full_circle_in_15s-Euler]": 0.6, + "test_ambisonics_binaural_headrotation[FOA-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 0.1, + "test_ambisonics_binaural_headrotation[HOA2-BINAURAL_ROOM-full_circle_in_15s-Euler]": 0.4, + "test_ambisonics_binaural_headrotation[HOA2-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 0.04, + "test_ambisonics_binaural_headrotation[HOA3-BINAURAL_ROOM-full_circle_in_15s-Euler]": 0.4, + "test_ambisonics_binaural_headrotation[HOA3-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 0.05, + "test_ambisonics_binaural_static[FOA-BINAURAL_ROOM]": 0.6, + "test_ambisonics_binaural_static[HOA2-BINAURAL_ROOM]": 0.5, + "test_ambisonics_binaural_static[HOA3-BINAURAL_ROOM]": 0.1, + "test_ism[ISM1-FOA]": 45, + "test_ism[ISM1-HOA2]": 41, + "test_ism[ISM1-HOA3]": 38, + "test_ism[ISM2-FOA]": 45, + "test_ism[ISM2-HOA2]": 41, + "test_ism[ISM2-HOA3]": 38, + "test_ism[ISM3-FOA]": 45, + "test_ism[ISM3-HOA2]": 41, + "test_ism[ISM3-HOA3]": 38, + "test_ism[ISM4-FOA]": 45, + "test_ism[ISM4-HOA2]": 41, + "test_ism[ISM4-HOA3]": 38, + "test_ism_binaural_headrotation[ISM1-BINAURAL-full_circle_in_15s-Euler]": 0, + "test_ism_binaural_headrotation[ISM1-BINAURAL-rotate_yaw_pitch_roll1]": 0, + "test_ism_binaural_headrotation[ISM1-BINAURAL_ROOM-full_circle_in_15s-Euler]": 7, + "test_ism_binaural_headrotation[ISM1-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 2, + "test_ism_binaural_headrotation[ISM2-BINAURAL-full_circle_in_15s-Euler]": 0.34, + "test_ism_binaural_headrotation[ISM2-BINAURAL-rotate_yaw_pitch_roll1]": 0, + "test_ism_binaural_headrotation[ISM2-BINAURAL_ROOM-full_circle_in_15s-Euler]": 4, + "test_ism_binaural_headrotation[ISM2-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 1, + "test_ism_binaural_headrotation[ISM3-BINAURAL-full_circle_in_15s-Euler]": 0, + "test_ism_binaural_headrotation[ISM3-BINAURAL-rotate_yaw_pitch_roll1]": 0, + "test_ism_binaural_headrotation[ISM3-BINAURAL_ROOM-full_circle_in_15s-Euler]": 4, + "test_ism_binaural_headrotation[ISM3-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 1, + "test_ism_binaural_headrotation[ISM4-BINAURAL-full_circle_in_15s-Euler]": 0, + "test_ism_binaural_headrotation[ISM4-BINAURAL-rotate_yaw_pitch_roll1]": 0, + "test_ism_binaural_headrotation[ISM4-BINAURAL_ROOM-full_circle_in_15s-Euler]": 4, + "test_ism_binaural_headrotation[ISM4-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 1, + "test_ism_binaural_static[ISM1-BINAURAL]": 0.00, + "test_ism_binaural_static[ISM1-BINAURAL_ROOM]": 18, + "test_ism_binaural_static[ISM2-BINAURAL]": 0, + "test_ism_binaural_static[ISM2-BINAURAL_ROOM]": 19, + "test_ism_binaural_static[ISM3-BINAURAL]": 0, + "test_ism_binaural_static[ISM3-BINAURAL_ROOM]": 19, + "test_ism_binaural_static[ISM4-BINAURAL]": 0, + "test_ism_binaural_static[ISM4-BINAURAL_ROOM]": 19, + "test_metadata[mixed_scene-5_1_4]": 11, + "test_metadata[mixed_scene-MONO]": 13, + "test_metadata[mixed_scene-STEREO]": 12, + "test_multichannel[5_1-MONO]": 11, + "test_multichannel[5_1-STEREO]": 10, + "test_multichannel[5_1_2-MONO]": 13, + "test_multichannel[5_1_2-STEREO]": 12, + "test_multichannel[5_1_4-MONO]": 14, + "test_multichannel[5_1_4-STEREO]": 13, + "test_multichannel[7_1-MONO]": 13, + "test_multichannel[7_1-STEREO]": 12, + "test_multichannel[7_1_4-MONO]": 13, + "test_multichannel[7_1_4-STEREO]": 12, + "test_multichannel_binaural_headrotation[5_1-BINAURAL-full_circle_in_15s-Euler]": 0, + "test_multichannel_binaural_headrotation[5_1-BINAURAL-rotate_yaw_pitch_roll1]": 0, + "test_multichannel_binaural_headrotation[5_1-BINAURAL_ROOM-full_circle_in_15s-Euler]": 0, + "test_multichannel_binaural_headrotation[5_1-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 0, + "test_multichannel_binaural_headrotation[5_1_2-BINAURAL-full_circle_in_15s-Euler]": 4, + "test_multichannel_binaural_headrotation[5_1_2-BINAURAL-rotate_yaw_pitch_roll1]": 6, + "test_multichannel_binaural_headrotation[5_1_2-BINAURAL_ROOM-full_circle_in_15s-Euler]": 0, + "test_multichannel_binaural_headrotation[5_1_2-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 1, + "test_multichannel_binaural_headrotation[5_1_4-BINAURAL-full_circle_in_15s-Euler]": 5, + "test_multichannel_binaural_headrotation[5_1_4-BINAURAL-rotate_yaw_pitch_roll1]": 6, + "test_multichannel_binaural_headrotation[5_1_4-BINAURAL_ROOM-full_circle_in_15s-Euler]": 0, + "test_multichannel_binaural_headrotation[5_1_4-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 1, + "test_multichannel_binaural_headrotation[7_1-BINAURAL-full_circle_in_15s-Euler]": 0, + "test_multichannel_binaural_headrotation[7_1-BINAURAL-rotate_yaw_pitch_roll1]": 0, + "test_multichannel_binaural_headrotation[7_1-BINAURAL_ROOM-full_circle_in_15s-Euler]": 0, + "test_multichannel_binaural_headrotation[7_1-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 0, + "test_multichannel_binaural_headrotation[7_1_4-BINAURAL-full_circle_in_15s-Euler]": 4, + "test_multichannel_binaural_headrotation[7_1_4-BINAURAL-rotate_yaw_pitch_roll1]": 5, + "test_multichannel_binaural_headrotation[7_1_4-BINAURAL_ROOM-full_circle_in_15s-Euler]": 0, + "test_multichannel_binaural_headrotation[7_1_4-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 1, + "test_multichannel_binaural_static[5_1-BINAURAL]": 8, + "test_multichannel_binaural_static[5_1-BINAURAL_ROOM]": 1, + "test_multichannel_binaural_static[5_1_2-BINAURAL]": 9, + "test_multichannel_binaural_static[5_1_2-BINAURAL_ROOM]": 1, + "test_multichannel_binaural_static[5_1_4-BINAURAL]": 10, + "test_multichannel_binaural_static[5_1_4-BINAURAL_ROOM]": 2, + "test_multichannel_binaural_static[7_1-BINAURAL]": 7, + "test_multichannel_binaural_static[7_1-BINAURAL_ROOM]": 1, + "test_multichannel_binaural_static[7_1_4-BINAURAL]": 9, + "test_multichannel_binaural_static[7_1_4-BINAURAL_ROOM]": 1, +} -- GitLab From b560fbd92097e67afee61bbabce386782e082ef4 Mon Sep 17 00:00:00 2001 From: Archit Tamarapu Date: Thu, 25 Aug 2022 17:35:33 +0200 Subject: [PATCH 009/101] fix compiler error for rotateFrame_() --- lib_com/ivas_prot.h | 4 ++++ lib_rend/ivas_crend.c | 8 ++++++++ lib_rend/ivas_rotation.c | 4 ++++ lib_rend/lib_rend.c | 6 +++--- 4 files changed, 19 insertions(+), 3 deletions(-) diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index 3fc39a8011..cb94e2c1ac 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -4516,7 +4516,9 @@ ivas_error ivas_headTrack_open( void rotateFrame_shd( HEAD_TRACK_DATA_HANDLE hHeadTrackData, /* i : head track handle */ float output[][L_FRAME48k], /* i/o: unrotated HOA3 signal buffer in TD */ +#ifndef EXT_RENDERER const int32_t output_fs, /* i : output sampling frequency */ +#endif const int16_t subframe_len, /* i : subframe length per channel */ const IVAS_OUTPUT_SETUP hTransSetup, /* i : format for rotation */ const int16_t subframe_idx /* i : subframe index */ @@ -4525,7 +4527,9 @@ void rotateFrame_shd( void rotateFrame_sd( HEAD_TRACK_DATA_HANDLE hHeadTrackData, /* i : head track handle */ float output[][L_FRAME48k], /* i/o: unrotated SD signal buffer in TD */ +#ifndef EXT_RENDERER const int32_t output_fs, /* i : output sampling frequency */ +#endif const int16_t subframe_len, /* i : subframe length per channel */ const IVAS_OUTPUT_SETUP hTransSetup, /* i : format for rotation */ const EFAP_HANDLE hEFAPdata, /* i : EFAP structure */ diff --git a/lib_rend/ivas_crend.c b/lib_rend/ivas_crend.c index 177e14ec81..45a9e121ca 100644 --- a/lib_rend/ivas_crend.c +++ b/lib_rend/ivas_crend.c @@ -1073,12 +1073,20 @@ ivas_error ivas_crend_process( */ if ( intern_config == AUDIO_CONFIG_FOA || intern_config == AUDIO_CONFIG_HOA2 || intern_config == AUDIO_CONFIG_HOA3 ) { +#ifdef EXT_RENDERER + rotateFrame_shd( st_ivas->hHeadTrackData, output, subframe_len, st_ivas->hIntSetup, subframe_idx ); +#else rotateFrame_shd( st_ivas->hHeadTrackData, output, st_ivas->hDecoderConfig->output_Fs, subframe_len, st_ivas->hIntSetup, subframe_idx ); +#endif } /* Rotation in SD for MC -> BINAURAL_ROOM */ else if ( st_ivas->ivas_format != ISM_FORMAT && st_ivas->hIntSetup.is_loudspeaker_setup ) { +#ifdef EXT_RENDERER + rotateFrame_sd( st_ivas->hHeadTrackData, output, subframe_len, st_ivas->hIntSetup, st_ivas->hEFAPdata, subframe_idx ); +#else rotateFrame_sd( st_ivas->hHeadTrackData, output, st_ivas->hDecoderConfig->output_Fs, subframe_len, st_ivas->hIntSetup, st_ivas->hEFAPdata, subframe_idx ); +#endif } } diff --git a/lib_rend/ivas_rotation.c b/lib_rend/ivas_rotation.c index 6cf8c65b5d..49c937844c 100644 --- a/lib_rend/ivas_rotation.c +++ b/lib_rend/ivas_rotation.c @@ -302,7 +302,9 @@ void rotateAziEle_DirAC( void rotateFrame_shd( HEAD_TRACK_DATA_HANDLE hHeadTrackData, /* i : head track handle */ float output[][L_FRAME48k], /* i/o: unrotated HOA3 signal buffer in TD */ +#ifndef EXT_RENDERER const int32_t output_fs, /* i : output sampling frequency */ +#endif const int16_t subframe_len, /* i : subframe length per channel */ const IVAS_OUTPUT_SETUP hTransSetup, /* i : format for rotation */ const int16_t subframe_idx /* i : subframe index */ @@ -435,7 +437,9 @@ void rotateFrame_shd( void rotateFrame_sd( HEAD_TRACK_DATA_HANDLE hHeadTrackData, /* i : head track handle */ float output[][L_FRAME48k], /* i/o: unrotated SD signal buffer in TD */ +#ifndef EXT_RENDERER const int32_t output_Fs, /* i : output sampling frequency */ +#endif const int16_t subframe_len, /* i : subframe length per channel */ const IVAS_OUTPUT_SETUP hTransSetup, /* i : format for rotation */ const EFAP_HANDLE hEFAPdata, /* i : EFAP structure */ diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index 52acf50aab..f8284c685a 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -1835,7 +1835,7 @@ static void renderAmbiToBinaural( { for ( i = 0; i < RENDERER_HEAD_POSITIONS_PER_FRAME; i++ ) { - rotateFrame_sd( st->decDummyAmbiBin->hHeadTrackData, tmpBuffer, st->sampleRate, subFrameLength, st->decDummyAmbiBin->hIntSetup, st->decDummyAmbiBin->hEFAPdata, i ); + rotateFrame_sd( st->decDummyAmbiBin->hHeadTrackData, tmpBuffer, subFrameLength, st->decDummyAmbiBin->hIntSetup, st->decDummyAmbiBin->hEFAPdata, i ); } } } @@ -1845,7 +1845,7 @@ static void renderAmbiToBinaural( { for ( i = 0; i < RENDERER_HEAD_POSITIONS_PER_FRAME; i++ ) { - rotateFrame_shd( st->decDummyAmbiBin->hHeadTrackData, tmpBuffer, st->sampleRate, subFrameLength, st->decDummyAmbiBin->hTransSetup, i ); + rotateFrame_shd( st->decDummyAmbiBin->hHeadTrackData, tmpBuffer, subFrameLength, st->decDummyAmbiBin->hTransSetup, i ); } } } @@ -1901,7 +1901,7 @@ static void renderChannelsToBinaural( { for ( i = 0; i < RENDERER_HEAD_POSITIONS_PER_FRAME; i++ ) { - rotateFrame_sd( st->decDummyMcBin->hHeadTrackData, tmpBuffer, st->sampleRate, subFrameLength, st->decDummyMcBin->hTransSetup, st->decDummyMcBin->hEFAPdata, i ); + rotateFrame_sd( st->decDummyMcBin->hHeadTrackData, tmpBuffer, subFrameLength, st->decDummyMcBin->hTransSetup, st->decDummyMcBin->hEFAPdata, i ); } } -- GitLab From d1c0b7561096acbda003d7c47c882965bea93c80 Mon Sep 17 00:00:00 2001 From: Archit Tamarapu Date: Mon, 29 Aug 2022 15:29:27 +0200 Subject: [PATCH 010/101] fix compilation error on MSVC --- lib_rend/lib_rend.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index f8284c685a..581515efa4 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -1874,7 +1874,7 @@ static void renderChannelsToBinaural( int32_t numInChannels; float gain_lin; float tmpBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; - float tmpLfeBuffer[L_FRAME48k + NS2SA( 48000, ivas_lfe_lpf_delay[IVAS_FILTER_ORDER_4 - 3] * 1000000000L )]; + float tmpLfeBuffer[L_FRAME48k_EXT]; #ifdef WMOPS wmops_sub_start( "renderChannelsToBinaural" ); -- GitLab From 2f43d13928d482cdb6544d5797f96a3450db19c0 Mon Sep 17 00:00:00 2001 From: Erik Norvell Date: Tue, 30 Aug 2022 07:46:37 +0200 Subject: [PATCH 011/101] Added initialization of {Left,Right}Filter{,Incr}_p in TDREND_SFX_SpatBin_Initialize --- lib_com/options.h | 1 + lib_rend/ivas_objectRenderer_sfx.c | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/lib_com/options.h b/lib_com/options.h index 8bb532f8fb..62fb445552 100755 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -155,6 +155,7 @@ #define FIX_WRONG_NBANDS_IN_ITD_ESTIMATION /* Issue 85: fix incorrect setting of nbands in calc_mean_E_ratio() if bwidth is limited on commandline*/ #define FIX_I87 /* fix for issue 86: incorrect Ambisonics order set for head rotation in SBA */ +#define FIX_I81 /* Fix for issue 81: Initialize HR filter pointers */ /* ################## End DEVELOPMENT switches ######################### */ /* clang-format on */ diff --git a/lib_rend/ivas_objectRenderer_sfx.c b/lib_rend/ivas_objectRenderer_sfx.c index 4f03ada392..45ac83a4ae 100644 --- a/lib_rend/ivas_objectRenderer_sfx.c +++ b/lib_rend/ivas_objectRenderer_sfx.c @@ -1208,6 +1208,12 @@ ivas_error TDREND_SFX_SpatBin_Initialize( SfxSpatBin_p->TurningOnEffect = FALSE; /* Init during next SetParams-call */ SfxSpatBin_p->InitializeParams = TRUE; +#ifdef FIX_I81 + SfxSpatBin_p->LeftFilter_p = NULL; + SfxSpatBin_p->LeftFilterIncr_p = NULL; + SfxSpatBin_p->RightFilter_p = NULL; + SfxSpatBin_p->RightFilterIncr_p = NULL; +#endif /* Init MaxTargetTime and MaxBlockLength */ switch ( output_Fs ) -- GitLab From 4ef049bb8e8e191b6d3954efe69660657e264516 Mon Sep 17 00:00:00 2001 From: Archit Tamarapu Date: Tue, 30 Aug 2022 13:28:44 +0200 Subject: [PATCH 012/101] remove tmpFixBuggyTdBinRendInit() under FIX_I81 as well --- lib_rend/lib_rend.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index 581515efa4..b62ff9490b 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -454,6 +454,7 @@ static ivas_error initDecoderDummyForAmbiToBinaural( DecoderDummy *decDummyAmbiB return error; } +#ifndef FIX_I81 /* Fixes initialization issues in TD renderer. Should get fixed properly soon. See issue: https://forge.3gpp.org/rep/ivas-codec-pc/ivas-codec/-/issues/81 */ static void tmpFixBuggyTdBinRendInit(BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd) @@ -471,6 +472,7 @@ static void tmpFixBuggyTdBinRendInit(BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRend } } } +#endif static ivas_error initDecoderDummyForObjToBinaural( DecoderDummy *decDummyObjBin, IVAS_REND_InputConfig inConfig, IVAS_REND_BinauralFormat binauralFormat ) { @@ -515,7 +517,9 @@ static ivas_error initDecoderDummyForObjToBinaural( DecoderDummy *decDummyObjBin { return error; } +#ifndef FIX_I81 tmpFixBuggyTdBinRendInit(decDummyObjBin->hBinRendererTd); +#endif } return error; -- GitLab From db80a309ef89c422fb9aaf8c9a70a05d36f0c222 Mon Sep 17 00:00:00 2001 From: Kacper Sagnowski Date: Wed, 31 Aug 2022 11:47:13 +0200 Subject: [PATCH 013/101] Add leftover merge change --- lib_rend/ivas_sba_rendering.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib_rend/ivas_sba_rendering.c b/lib_rend/ivas_sba_rendering.c index dbcec392a5..03db2203c9 100644 --- a/lib_rend/ivas_sba_rendering.c +++ b/lib_rend/ivas_sba_rendering.c @@ -274,7 +274,11 @@ int16_t ivas_sba_remapTCs( if ( st_ivas->sba_mode != SBA_MODE_SPAR ) { +#ifndef SBA_ORDER_BITSTREAM ivas_sba_zero_vert_comp( sba_data, st_ivas->sba_order, st_ivas->sba_planar, output_frame ); +#else + ivas_sba_zero_vert_comp( sba_data, st_ivas->sba_analysis_order, st_ivas->sba_planar, output_frame ); +#endif } return ( nchan_remapped ); } -- GitLab From 43bd3cf68a160f3ed566aecab927bcd595779bc9 Mon Sep 17 00:00:00 2001 From: Kacper Sagnowski Date: Wed, 31 Aug 2022 11:47:42 +0200 Subject: [PATCH 014/101] Revert "Add leftover merge change" This reverts commit db80a309ef89c422fb9aaf8c9a70a05d36f0c222. --- lib_rend/ivas_sba_rendering.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/lib_rend/ivas_sba_rendering.c b/lib_rend/ivas_sba_rendering.c index 03db2203c9..dbcec392a5 100644 --- a/lib_rend/ivas_sba_rendering.c +++ b/lib_rend/ivas_sba_rendering.c @@ -274,11 +274,7 @@ int16_t ivas_sba_remapTCs( if ( st_ivas->sba_mode != SBA_MODE_SPAR ) { -#ifndef SBA_ORDER_BITSTREAM ivas_sba_zero_vert_comp( sba_data, st_ivas->sba_order, st_ivas->sba_planar, output_frame ); -#else - ivas_sba_zero_vert_comp( sba_data, st_ivas->sba_analysis_order, st_ivas->sba_planar, output_frame ); -#endif } return ( nchan_remapped ); } -- GitLab From c3694594fe90a5e5ee1f159c5a33d917d1b493e2 Mon Sep 17 00:00:00 2001 From: Kacper Sagnowski Date: Wed, 31 Aug 2022 13:21:13 +0200 Subject: [PATCH 015/101] Update external renderer Changes: - Add clipping of samples before float to int conversion - Minor improvements to command line parsing - Merge recent main --- apps/renderer.c | 40 +++++-- lib_com/bitstream.c | 18 ++++ lib_com/ivas_dirac_com.c | 8 ++ lib_com/ivas_prot.h | 18 ++-- lib_com/ivas_stereo_mdct_stereo_com.c | 4 - lib_com/options.h | 8 +- lib_dec/ivas_cpe_dec.c | 17 --- lib_dec/ivas_dirac_dec.c | 8 ++ lib_dec/ivas_init_dec.c | 30 ++++++ lib_dec/ivas_mct_dec_mct.c | 4 - lib_dec/ivas_sba_dec.c | 24 ++++- lib_dec/ivas_spar_decoder.c | 9 +- lib_dec/ivas_spar_md_dec.c | 6 +- lib_dec/ivas_stat_dec.h | 11 +- lib_dec/ivas_stereo_mdct_core_dec.c | 27 +---- lib_dec/ivas_stereo_mdct_stereo_dec.c | 4 - lib_dec/lib_dec.c | 4 + lib_enc/ivas_cpe_enc.c | 16 +-- lib_enc/ivas_mct_enc.c | 20 ++++ lib_enc/ivas_mdct_core_enc.c | 6 +- lib_enc/ivas_rom_enc.c | 2 + lib_enc/ivas_rom_enc.h | 2 + lib_enc/ivas_sba_enc.c | 18 +++- lib_enc/ivas_spar_encoder.c | 33 +++++- lib_enc/ivas_spar_md_enc.c | 53 +++++++-- lib_enc/ivas_stat_enc.h | 7 +- lib_enc/ivas_stereo_dmx_evs.c | 136 ++++++++++++++++++++++-- lib_enc/ivas_stereo_mdct_core_enc.c | 17 +-- lib_enc/ivas_stereo_switching_enc.c | 6 +- lib_enc/lib_enc.c | 15 ++- lib_rend/ivas_output_init.c | 6 +- lib_rend/ivas_sba_rendering.c | 4 + lib_rend/lib_rend.c | 73 +++++++++++-- lib_rend/lib_rend.h | 11 ++ scripts/cut_bs.py | 122 +++++++++++++++++++++ scripts/pyivastest/IvasScriptsCommon.py | 4 +- 36 files changed, 623 insertions(+), 168 deletions(-) mode change 100755 => 100644 lib_com/options.h mode change 100755 => 100644 lib_enc/ivas_cpe_enc.c mode change 100755 => 100644 lib_enc/ivas_stereo_mdct_core_enc.c create mode 100755 scripts/cut_bs.py diff --git a/apps/renderer.c b/apps/renderer.c index 5787cb143e..8197b05bd8 100644 --- a/apps/renderer.c +++ b/apps/renderer.c @@ -607,7 +607,19 @@ int32_t main( int32_t argc, char **argv ) fprintf( stdout, "\nRenderer delay: %-5u [samples] - Timescale: %5u\n", delayNumSamples_orig, delayTimeScale ); } - fprintf( stdout, "\n\nRendering of %d frames finished\n", frame ); + fprintf( stdout, "\n\nRendering of %d frames finished\n\n", frame ); + +#ifdef DEBUGGING + int32_t cnt_frames_limited, noClipping; + if ( ( cnt_frames_limited = IVAS_REND_GetCntFramesLimited( hIvasRend ) ) > 0 ) + { + fprintf( stdout, "Limiter applied in %d frames.\n\n", cnt_frames_limited ); + } + if ( ( noClipping = IVAS_REND_GetNoCLipping( hIvasRend ) ) > 0 ) + { + fprintf( stdout, "Clipping (saturation) detected: %d samples clipped!!!\n\n", noClipping ); + } +#endif /* === Close === */ count_free( inpInt16Buffer ); @@ -1170,6 +1182,7 @@ typedef enum CmdLnOptionId_neverDropLfe, CmdLnOptionId_noDelayCmp, CmdLnOptionId_quietModeEnabled, + CmdLnOptionId_inputMetadata, } CmdLnOptionId; static void parseOption( int32_t optionId, char **optionValues, int16_t numOptionValues, void *pOutputStruct ) @@ -1260,15 +1273,22 @@ static CmdlnArgs parseCmdlnArgs( int32_t argc, char **argv ) .match = "input_file", .matchShort = "i", .isRequired = 1, - .description = "Path to the input file", + .description = "Path to the input file (WAV, raw PCM or scene description file)", }, { .id = CmdLnOptionId_inputFormat, .match = "input_format", .matchShort = "if", .isRequired = 1, + // .description = "Audio format of input file (e.g. 5_1 or HOA3 or META)", /* TODO(sgi): Add additional flag for listing all available formats */ .description = "Format of input file\nIn case of a metadata format this should be followed by a list of metadata file paths or NULL", }, + // { /* TODO(sgi): move metadata file paths from input_format to this separate flag */ + // .id = CmdLnOptionId_inputMetadata, + // .match = "input_metadata", + // .matchShort = "im", + // .description = "Space-separated list of path to metadata files for ISM or MASA inputs", + // }, { .id = CmdLnOptionId_outputFile, .match = "output_file", @@ -1287,40 +1307,42 @@ static CmdlnArgs parseCmdlnArgs( int32_t argc, char **argv ) .id = CmdLnOptionId_sampleRate, .match = "sample_rate", .matchShort = "fs", - .isRequired = 1, - .description = "Input sampling rate in kHz", + .isRequired = 1, /* TODO(sgi): Shouldn't be required */ + .description = "Input sampling rate in kHz (16, 32, 48)", /* TODO(sgi): Add sampling rate to scene description files */ }, { .id = CmdLnOptionId_trajFile, .match = "trajectory_file", .matchShort = "tf", - .description = "Head rotation trajectory file", + .description = "Head rotation trajectory file for simulation of head tracking (only for BINAURAL and BINAURAL_ROOM outputs)", }, { .id = CmdLnOptionId_customHrtfFile, .match = "custom_hrtf", .matchShort = "hrtf", - .description = "Custom HRTF file for binaural rendering", + .description = "Custom HRTF file for binaural rendering (only for BINAURAL and BINAURAL_ROOM outputs)", }, { .id = CmdLnOptionId_renderConfigFile, .match = "render_config", .matchShort = "rc", - .description = "Renderer configuration file", + .description = "Binaural renderer configuration file (only for BINAURAL and BINAURAL_ROOM outputs)", }, { .id = CmdLnOptionId_noDiegeticPan, .match = "no_diegetic_pan", .matchShort = "ndp", - .description = "Panning mono no dietic sound to stereo -1<= pan <= 1\nleft or l or 1->left, right or r or -1->right, center or c or 0 ->middle", + .description = "Panning mono no diegetic sound to stereo -1<= pan <= 1\nleft or l or 1->left, right or r or -1->right, center or c or 0 ->middle\n(todo: implementation)", }, { .id = CmdLnOptionId_orientationTracking, .match = "tracking_type", .matchShort = "otr", - .description = "Head orientation tracking type: 'ref' or 'avg' (only for binaural rendering)", + .description = "Head orientation tracking type: 'ref' or 'avg' (only for BINAURAL and BINAURAL_ROOM) (todo: check implementation)", }, { + /* TODO(sgi): Replace with more configurable input, e.g. ask for a list of triplets: (gain, azimuth, elevation) to place LFE signal */ + /* rename to "lfeHandling" */ .id = CmdLnOptionId_neverDropLfe, .match = "neverDropLfe", .matchShort = "ndl", diff --git a/lib_com/bitstream.c b/lib_com/bitstream.c index 3a4ebc80cb..4e81fc9166 100755 --- a/lib_com/bitstream.c +++ b/lib_com/bitstream.c @@ -1975,11 +1975,29 @@ ivas_error preview_indices( } 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_SBA] == 1 ); +#ifndef SBA_ORDER_BITSTREAM st_ivas->sba_order = ( bit_stream[IVAS_FORMAT_SIGNALING_NBITS_SBA + 2] == 1 ); st_ivas->sba_order += 2 * ( bit_stream[IVAS_FORMAT_SIGNALING_NBITS_SBA + 1] == 1 ); +#else + st_ivas->hDecoderConfig->sba_order = ( bit_stream[IVAS_FORMAT_SIGNALING_NBITS_SBA + 2] == 1 ); + st_ivas->hDecoderConfig->sba_order += 2 * ( bit_stream[IVAS_FORMAT_SIGNALING_NBITS_SBA + 1] == 1 ); + st_ivas->sba_analysis_order = st_ivas->hDecoderConfig->sba_order; +#endif +#ifdef SBA_ORDER_BITSTREAM + /*Hard coding the the sba_oder as 1 as higher not supported below 256k bitrate*/ + if ( total_brate < IVAS_256k ) + { + st_ivas->sba_analysis_order = 1; + } +#endif +#ifdef SBA_ORDER_BITSTREAM + 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 ), st_ivas->sba_mode ); +#else ivas_sba_config( total_brate, st_ivas->sba_order, -1, &( st_ivas->nchan_transport ), st_ivas->sba_planar, &( st_ivas->nSCE ), &( st_ivas->nCPE ), &( st_ivas->element_mode_init ), st_ivas->sba_mode ); +#endif } } diff --git a/lib_com/ivas_dirac_com.c b/lib_com/ivas_dirac_com.c index 8cade5dee4..849e889739 100644 --- a/lib_com/ivas_dirac_com.c +++ b/lib_com/ivas_dirac_com.c @@ -82,7 +82,11 @@ ivas_error ivas_dirac_config( nCPE = &( (Encoder_Struct *) st_ivas )->nCPE; element_mode = &( (Encoder_Struct *) st_ivas )->hEncoderConfig->element_mode_init; nchan_transport = &( (Encoder_Struct *) st_ivas )->nchan_transport; +#ifndef SBA_ORDER_BITSTREAM sba_order = ( (Encoder_Struct *) st_ivas )->hEncoderConfig->sba_order; +#else + sba_order = ( (Encoder_Struct *) st_ivas )->sba_analysis_order; +#endif sba_planar = ( (Encoder_Struct *) st_ivas )->hEncoderConfig->sba_planar; ivas_total_brate = ( (Encoder_Struct *) st_ivas )->hEncoderConfig->ivas_total_brate; Fs = ( (Encoder_Struct *) st_ivas )->hEncoderConfig->input_Fs; @@ -107,7 +111,11 @@ ivas_error ivas_dirac_config( nCPE = &( (Decoder_Struct *) st_ivas )->nCPE; element_mode = &( (Decoder_Struct *) st_ivas )->element_mode_init; nchan_transport = &( (Decoder_Struct *) st_ivas )->nchan_transport; +#ifndef SBA_ORDER_BITSTREAM sba_order = ( (Decoder_Struct *) st_ivas )->sba_order; +#else + sba_order = ( (Decoder_Struct *) st_ivas )->sba_analysis_order; +#endif sba_planar = ( (Decoder_Struct *) st_ivas )->sba_planar; ivas_total_brate = ( (Decoder_Struct *) st_ivas )->hDecoderConfig->ivas_total_brate; Fs = ( (Decoder_Struct *) st_ivas )->hDecoderConfig->output_Fs; diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index cb94e2c1ac..3003b9f785 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -2155,9 +2155,7 @@ void stereo_mdct_core_dec( void splitAvailableBits( const int16_t total_bits, /* i : total available bits for TCX coding */ const int16_t split_ratio, /* i : split ratio */ -#ifdef LBR_SBA_CORE_CODING_TUNING const int16_t isSBAStereoMode, /* i : signal core coding for sba */ -#endif int16_t *bits_ch0, /* o : bits for channel 0 */ int16_t *bits_ch1 /* o : bits for channel 1 */ ); @@ -2175,9 +2173,7 @@ void parse_stereo_from_bitstream( STEREO_MDCT_DEC_DATA_HANDLE hStereoMdct, /* i/o: MDCT stereo decoder structure */ Decoder_State **sts, /* i/o: decoder state structure */ const int16_t mct_on, /* i : flag mct block (1) or stereo (0) */ -#ifdef LBR_SBA_CORE_CODING_TUNING const int16_t isSBAStereoMode, /* i: flag core coding for sba */ -#endif Decoder_State *st0, /* i/o: decoder state structure for Bstr */ int16_t ms_mask[NB_DIV][MAX_SFB] /* o : bandwise MS mask */ ); @@ -2513,10 +2509,8 @@ ivas_error stereo_memory_enc( const int16_t max_bwidth, /* i : maximum audio bandwidth */ float *tdm_last_ratio, /* o : TD stereo last ratio */ const IVAS_FORMAT ivas_format /* i : IVAS format */ -#ifdef LBR_SBA_CORE_CODING_TUNING , const int16_t nchan_transport /* i : number transport chans */ -#endif ); @@ -3013,11 +3007,7 @@ void ivas_dirac_param_est_enc( *----------------------------------------------------------------------------------*/ /*! r: SBA format mode */ -#ifdef LBR_SBA_CORE_CODING_TUNING SBA_MODE ivas_sba_mode_select( -#else -int16_t ivas_sba_mode_select( -#endif const int32_t ivas_total_brate /* i : IVAS total bitrate */ ); @@ -3876,6 +3866,10 @@ void ivas_spar_dec_upmixer( ivas_error ivas_spar_md_enc_open( ivas_spar_md_enc_state_t **hMdEnc, /* i/o: SPAR MD encoder handle */ const ENCODER_CONFIG_HANDLE hEncoderConfig /* i : configuration structure */ +#ifdef SBA_ORDER_BITSTREAM + , + int16_t sba_order +#endif ); void ivas_spar_md_enc_close( @@ -3888,6 +3882,10 @@ ivas_error ivas_spar_md_enc_process( ivas_spar_md_enc_in_buf_t *pIn_buf, BSTR_ENC_HANDLE hMetaData, /* i/o: MetaData handle */ const int16_t dtx_silence_mode +#ifdef SBA_ORDER_BITSTREAM + , + int16_t sba_order +#endif ); void ivas_compute_spar_params( diff --git a/lib_com/ivas_stereo_mdct_stereo_com.c b/lib_com/ivas_stereo_mdct_stereo_com.c index 1b8caa0c7c..73cd2fd579 100644 --- a/lib_com/ivas_stereo_mdct_stereo_com.c +++ b/lib_com/ivas_stereo_mdct_stereo_com.c @@ -46,9 +46,7 @@ void splitAvailableBits( const int16_t total_bits, /* i : total available bits for TCX coding */ const int16_t split_ratio, /* i : split ratio */ -#ifdef LBR_SBA_CORE_CODING_TUNING const int16_t isSBAStereoMode, /* i : signal core coding for sba */ -#endif int16_t *bits_ch0, /* o : bits for channel 0 */ int16_t *bits_ch1 /* o : bits for channel 1 */ ) @@ -56,13 +54,11 @@ void splitAvailableBits( assert( split_ratio >= 1 && split_ratio < SMDCT_BITRATE_RATIO_RANGE ); *bits_ch0 = split_ratio * total_bits / SMDCT_BITRATE_RATIO_RANGE; -#ifdef LBR_SBA_CORE_CODING_TUNING /* for SBA mode bias the distribution towards the W channel */ if ( split_ratio < 7 && isSBAStereoMode ) { *bits_ch0 += (int16_t) ( 0.2 * *bits_ch0 ); } -#endif *bits_ch1 = total_bits - *bits_ch0; return; diff --git a/lib_com/options.h b/lib_com/options.h old mode 100755 new mode 100644 index 62fb445552..054eca6526 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -147,15 +147,17 @@ /*#define FIX_I1_113*/ /* under review : MCT bit distribution optimization for SBA high bitrates*/ -#define LBR_SBA_CORE_CODING_TUNING /* Contribution "3 Core Coder Tuning for low bitrate SBA with 2 TCs" */ - #define EXT_RENDERER /* FhG: external renderer library and standalone application */ #define FIX_EFAP_MATH /* fix for EFAP: remove angle quantization and a bug in polygon lookup causing incorrect gains. minor tweak for ALLRAD. non-BE for modes using EFAP */ #define FIX_WRONG_NBANDS_IN_ITD_ESTIMATION /* Issue 85: fix incorrect setting of nbands in calc_mean_E_ratio() if bwidth is limited on commandline*/ #define FIX_I87 /* fix for issue 86: incorrect Ambisonics order set for head rotation in SBA */ -#define FIX_I81 /* Fix for issue 81: Initialize HR filter pointers */ +#define SBA_ORDER_BITSTREAM /* issue 76: Use input sba order for bitstream coding */ + +/* NTT switches */ +#define NTT_UPDATE_ITD_SW /* contribution 4: Update of ITD switch in stereo downmix for EVS */ +#define NTT_REMOVE_EPS_ROM /* contribution 4: Reduction of ROM size in stereo downmix for EVS */ /* ################## End DEVELOPMENT switches ######################### */ /* clang-format on */ diff --git a/lib_dec/ivas_cpe_dec.c b/lib_dec/ivas_cpe_dec.c index c75ece2bce..7223b38761 100644 --- a/lib_dec/ivas_cpe_dec.c +++ b/lib_dec/ivas_cpe_dec.c @@ -361,27 +361,10 @@ ivas_error ivas_cpe_dec( if ( hCPE->element_mode != IVAS_CPE_DFT || ( hCPE->nchan_out == 1 && hCPE->hStereoDft->hConfig->res_cod_mode == STEREO_DFT_RES_COD_OFF ) ) { -#ifndef LBR_SBA_CORE_CODING_TUNING - if ( st_ivas->renderer_type == RENDERER_MC_PARAMMC && ( st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_MONO || st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_STEREO ) ) - { - if ( ( error = ivas_core_dec( st_ivas, NULL, hCPE, st_ivas->hMCT, n_channels, output, outputHB, NULL, 0 ) ) != IVAS_ERR_OK ) - { - return error; - } - } - else - { - if ( ( error = ivas_core_dec( NULL, NULL, hCPE, st_ivas->hMCT, n_channels, output, outputHB, NULL, 0 ) ) != IVAS_ERR_OK ) - { - return error; - } - } -#else if ( ( error = ivas_core_dec( st_ivas, NULL, hCPE, st_ivas->hMCT, n_channels, output, outputHB, NULL, 0 ) ) != IVAS_ERR_OK ) { return error; } -#endif } if ( st_ivas->hMCT ) diff --git a/lib_dec/ivas_dirac_dec.c b/lib_dec/ivas_dirac_dec.c index a8022aaa5d..074f635133 100755 --- a/lib_dec/ivas_dirac_dec.c +++ b/lib_dec/ivas_dirac_dec.c @@ -186,7 +186,11 @@ ivas_error ivas_dirac_dec_config( nchan_transport_orig = st_ivas->nchan_transport; if ( st_ivas->ivas_format == SBA_FORMAT && st_ivas->sba_mode == SBA_MODE_SPAR && !( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) ) { +#ifdef SBA_ORDER_BITSTREAM + st_ivas->nchan_transport = ivas_sba_get_nchan_metadata( st_ivas->sba_analysis_order ); +#else st_ivas->nchan_transport = ivas_sba_get_nchan_metadata( st_ivas->sba_order ); +#endif } nchan_transport = st_ivas->nchan_transport; if ( st_ivas->ivas_format == MASA_FORMAT && ivas_total_brate < MASA_STEREO_MIN_BITRATE && ivas_total_brate > IVAS_SID_4k4 ) @@ -197,7 +201,11 @@ ivas_error ivas_dirac_dec_config( if ( flag_config == DIRAC_RECONFIGURE && st_ivas->ivas_format == SBA_FORMAT ) { int16_t tmp1, tmp2, tmp3; +#ifdef SBA_ORDER_BITSTREAM + ivas_sba_config( st_ivas->hDecoderConfig->last_ivas_total_brate, st_ivas->sba_analysis_order, -1, &nchan_transport_old, st_ivas->sba_planar, &tmp1, &tmp2, &tmp3, SBA_MODE_DIRAC ); +#else ivas_sba_config( st_ivas->hDecoderConfig->last_ivas_total_brate, st_ivas->sba_order, -1, &nchan_transport_old, st_ivas->sba_planar, &tmp1, &tmp2, &tmp3, SBA_MODE_DIRAC ); +#endif } /*-----------------------------------------------------------------* diff --git a/lib_dec/ivas_init_dec.c b/lib_dec/ivas_init_dec.c index a682cd3c58..b12aa28e40 100755 --- a/lib_dec/ivas_init_dec.c +++ b/lib_dec/ivas_init_dec.c @@ -119,8 +119,18 @@ ivas_error ivas_dec_setup( num_bits_read += SBA_PLANAR_BITS; /* read Ambisonic (SBA) order */ +#ifndef SBA_ORDER_BITSTREAM st_ivas->sba_order = st_ivas->bit_stream[num_bits_read + 1]; st_ivas->sba_order += 2 * st_ivas->bit_stream[num_bits_read]; +#else + st_ivas->hDecoderConfig->sba_order = st_ivas->bit_stream[num_bits_read + 1]; + st_ivas->hDecoderConfig->sba_order += 2 * st_ivas->bit_stream[num_bits_read]; + st_ivas->sba_analysis_order = st_ivas->hDecoderConfig->sba_order; + if ( ivas_total_brate < IVAS_256k ) + { + st_ivas->sba_analysis_order = 1; + } +#endif num_bits_read += SBA_ORDER_BITS; if ( st_ivas->ini_frame > 0 && ivas_total_brate != st_ivas->hDecoderConfig->last_ivas_total_brate && ivas_total_brate > IVAS_SID_4k4 ) { @@ -131,7 +141,11 @@ ivas_error ivas_dec_setup( } else { +#ifndef SBA_ORDER_BITSTREAM ivas_sba_config( ivas_total_brate, st_ivas->sba_order, -1, &( st_ivas->nchan_transport ), st_ivas->sba_planar, &st_ivas->nSCE, &st_ivas->nCPE, &st_ivas->element_mode_init, st_ivas->sba_mode ); +#else + 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, st_ivas->sba_mode ); +#endif } } else if ( st_ivas->ivas_format == MASA_FORMAT ) @@ -408,10 +422,17 @@ static ivas_error ivas_read_format( tc_mode_offset = (int16_t) ( ivas_total_brate / FRAMES_PER_SEC - 1 ); idx = st_ivas->bit_stream[tc_mode_offset]; // TBD: needs more work for HOA +#ifndef SBA_ORDER_BITSTREAM if ( st_ivas->sba_order == 0 ) { st_ivas->sba_order = 1; } +#else + if ( st_ivas->sba_analysis_order == 0 ) + { + st_ivas->sba_analysis_order = 1; + } +#endif if ( idx == 0 ) { st_ivas->sid_format = SID_SBA_1TC; @@ -852,8 +873,13 @@ ivas_error ivas_init_decoder( return error; } } +#ifndef SBA_ORDER_BITSTREAM if ( ( error = ivas_dirac_sba_config( st_ivas->hQMetaData, &st_ivas->nchan_transport, &st_ivas->nSCE, &st_ivas->nCPE, &st_ivas->element_mode_init, ivas_total_brate, st_ivas->sba_order, st_ivas->sba_planar, st_ivas->sba_mode, IVAS_MAX_NUM_BANDS - SPAR_DIRAC_SPLIT_START_BAND ) ) != IVAS_ERR_OK ) +#else + if ( ( error = ivas_dirac_sba_config( st_ivas->hQMetaData, &st_ivas->nchan_transport, &st_ivas->nSCE, &st_ivas->nCPE, &st_ivas->element_mode_init, ivas_total_brate, st_ivas->sba_analysis_order, st_ivas->sba_planar, + st_ivas->sba_mode, IVAS_MAX_NUM_BANDS - SPAR_DIRAC_SPLIT_START_BAND ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -887,7 +913,11 @@ ivas_error ivas_init_decoder( } else { +#ifndef SBA_ORDER_BITSTREAM if ( ( error = ivas_dirac_sba_config( st_ivas->hQMetaData, &st_ivas->nchan_transport, &st_ivas->nSCE, &st_ivas->nCPE, &st_ivas->element_mode_init, ivas_total_brate, st_ivas->sba_order, st_ivas->sba_planar, st_ivas->sba_mode, -1 ) ) != IVAS_ERR_OK ) +#else + if ( ( error = ivas_dirac_sba_config( st_ivas->hQMetaData, &st_ivas->nchan_transport, &st_ivas->nSCE, &st_ivas->nCPE, &st_ivas->element_mode_init, ivas_total_brate, st_ivas->sba_analysis_order, st_ivas->sba_planar, st_ivas->sba_mode, -1 ) ) != IVAS_ERR_OK ) +#endif { return error; } diff --git a/lib_dec/ivas_mct_dec_mct.c b/lib_dec/ivas_mct_dec_mct.c index 1d1ccb0a3a..00eff03dac 100644 --- a/lib_dec/ivas_mct_dec_mct.c +++ b/lib_dec/ivas_mct_dec_mct.c @@ -147,11 +147,7 @@ void ivas_mct_dec_mct( p_st[0] = sts[hBlock->ch1]; p_st[1] = sts[hBlock->ch2]; -#ifdef LBR_SBA_CORE_CODING_TUNING parse_stereo_from_bitstream( hBlock->hStereoMdct, p_st, 1, 0, sts[0], hBlock->mask ); -#else - parse_stereo_from_bitstream( hBlock->hStereoMdct, p_st, 1, sts[0], hBlock->mask ); -#endif } return; diff --git a/lib_dec/ivas_sba_dec.c b/lib_dec/ivas_sba_dec.c index b79c598801..4aaddd028b 100644 --- a/lib_dec/ivas_sba_dec.c +++ b/lib_dec/ivas_sba_dec.c @@ -90,8 +90,11 @@ ivas_error ivas_sba_dec_reconfigure( nCPE_old = st_ivas->nCPE; nchan_transport_old = st_ivas->nchan_transport; sba_dirac_stereo_flag_old = st_ivas->sba_dirac_stereo_flag; - +#ifndef SBA_ORDER_BITSTREAM ivas_sba_config( sba_total_brate, st_ivas->sba_order, -1, &nchan_transport, st_ivas->sba_planar, &st_ivas->nSCE, &st_ivas->nCPE, &st_ivas->element_mode_init, st_ivas->sba_mode ); +#else + ivas_sba_config( sba_total_brate, st_ivas->sba_analysis_order, -1, &nchan_transport, st_ivas->sba_planar, &st_ivas->nSCE, &st_ivas->nCPE, &st_ivas->element_mode_init, st_ivas->sba_mode ); +#endif st_ivas->nchan_transport = nchan_transport; /* renderer might have changed */ @@ -107,7 +110,11 @@ ivas_error ivas_sba_dec_reconfigure( if ( st_ivas->sba_mode != SBA_MODE_SPAR ) { st_ivas->sba_dirac_stereo_flag = ( st_ivas->nchan_transport == 1 && st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_STEREO ); +#ifndef SBA_ORDER_BITSTREAM if ( ( error = ivas_dirac_sba_config( st_ivas->hQMetaData, &st_ivas->nchan_transport, &st_ivas->nSCE, &st_ivas->nCPE, &st_ivas->element_mode_init, ivas_total_brate, st_ivas->sba_order, st_ivas->sba_planar, st_ivas->sba_mode, -1 ) ) != IVAS_ERR_OK ) +#else + if ( ( error = ivas_dirac_sba_config( st_ivas->hQMetaData, &st_ivas->nchan_transport, &st_ivas->nSCE, &st_ivas->nCPE, &st_ivas->element_mode_init, ivas_total_brate, st_ivas->sba_analysis_order, st_ivas->sba_planar, st_ivas->sba_mode, -1 ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -115,11 +122,19 @@ ivas_error ivas_sba_dec_reconfigure( else { int16_t sba_order_internal; +#ifndef SBA_ORDER_BITSTREAM sba_order_internal = min( st_ivas->sba_order, IVAS_MAX_SBA_ORDER ); +#else + sba_order_internal = min( st_ivas->sba_analysis_order, IVAS_MAX_SBA_ORDER ); +#endif ivas_spar_config( st_ivas->hDecoderConfig->ivas_total_brate, sba_order_internal, &st_ivas->nchan_transport, &st_ivas->nSCE, &st_ivas->nCPE, &st_ivas->hSpar->core_nominal_brate, st_ivas->sid_format ); - +#ifndef SBA_ORDER_BITSTREAM if ( ( error = ivas_dirac_sba_config( st_ivas->hQMetaData, &st_ivas->nchan_transport, &st_ivas->nSCE, &st_ivas->nCPE, &st_ivas->element_mode_init, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->sba_order, st_ivas->sba_planar, st_ivas->sba_mode, IVAS_MAX_NUM_BANDS - SPAR_DIRAC_SPLIT_START_BAND ) ) != IVAS_ERR_OK ) +#else + if ( ( error = ivas_dirac_sba_config( st_ivas->hQMetaData, &st_ivas->nchan_transport, &st_ivas->nSCE, &st_ivas->nCPE, &st_ivas->element_mode_init, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->sba_analysis_order, st_ivas->sba_planar, + st_ivas->sba_mode, IVAS_MAX_NUM_BANDS - SPAR_DIRAC_SPLIT_START_BAND ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -557,8 +572,11 @@ void ivas_sba_upmixer_renderer( int16_t nchan_internal; wmops_sub_start( "ivas_sba_upmixer_renderer" ); - +#ifndef SBA_ORDER_BITSTREAM nchan_internal = ivas_sba_get_nchan_metadata( st_ivas->sba_order ); +#else + nchan_internal = ivas_sba_get_nchan_metadata( st_ivas->sba_analysis_order ); +#endif nchan_out = st_ivas->hDecoderConfig->nchan_out; for ( ch = 0; ch < nchan_remapped; ch++ ) diff --git a/lib_dec/ivas_spar_decoder.c b/lib_dec/ivas_spar_decoder.c index 9842097187..cc625f2605 100755 --- a/lib_dec/ivas_spar_decoder.c +++ b/lib_dec/ivas_spar_decoder.c @@ -71,7 +71,11 @@ ivas_error ivas_spar_dec_open( int32_t output_Fs; error = IVAS_ERR_OK; +#ifndef SBA_ORDER_BITSTREAM sba_order_internal = min( st_ivas->sba_order, IVAS_MAX_SBA_ORDER ); +#else + sba_order_internal = min( st_ivas->sba_analysis_order, IVAS_MAX_SBA_ORDER ); +#endif num_channels_internal = ivas_sba_get_nchan_metadata( sba_order_internal ); /* SPAR decoder handle */ @@ -619,8 +623,11 @@ static void ivas_spar_dec_MD( /*---------------------------------------------------------------------* * Initialization *---------------------------------------------------------------------*/ - +#ifndef SBA_ORDER_BITSTREAM sba_order = min( st_ivas->sba_order, IVAS_MAX_SBA_ORDER ); +#else + sba_order = min( st_ivas->sba_analysis_order, IVAS_MAX_SBA_ORDER ); +#endif bfi = st_ivas->bfi; ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate; num_channels = ivas_sba_get_nchan_metadata( sba_order ); diff --git a/lib_dec/ivas_spar_md_dec.c b/lib_dec/ivas_spar_md_dec.c index 21c244292a..be1b3fcb10 100644 --- a/lib_dec/ivas_spar_md_dec.c +++ b/lib_dec/ivas_spar_md_dec.c @@ -2577,9 +2577,11 @@ void ivas_spar_to_dirac( int16_t pred_idx; int16_t *dirac_to_spar_md_bands; int16_t enc_param_start_band; - +#ifndef SBA_ORDER_BITSTREAM sba_order_internal = min( st_ivas->sba_order, IVAS_MAX_SBA_ORDER ); - +#else + sba_order_internal = min( st_ivas->sba_analysis_order, IVAS_MAX_SBA_ORDER ); +#endif start_band = 0; end_band = min( num_bands_out, SPAR_DIRAC_SPLIT_START_BAND ); diff --git a/lib_dec/ivas_stat_dec.h b/lib_dec/ivas_stat_dec.h index 8e4a18457a..29ae9867ca 100644 --- a/lib_dec/ivas_stat_dec.h +++ b/lib_dec/ivas_stat_dec.h @@ -325,9 +325,7 @@ typedef struct stereo_mdct_dec_data_structure int16_t noise_seeds_channels[CPE_CHANNELS]; int16_t noise_seed_common; #endif -#ifdef LBR_SBA_CORE_CODING_TUNING int16_t isSBAStereoMode; -#endif } STEREO_MDCT_DEC_DATA, *STEREO_MDCT_DEC_DATA_HANDLE; @@ -1856,7 +1854,9 @@ typedef struct decoder_config_structure int32_t output_Fs; /* output signal sampling frequency in Hz */ int16_t nchan_out; /* number of output audio channels */ AUDIO_CONFIG output_config; /* output audio configuration */ - +#ifdef SBA_ORDER_BITSTREAM + int16_t sba_order; +#endif int16_t Opt_LsCustom; /* indicates whether loudspeaker custom setup is used */ int16_t Opt_HRTF_binary; /* indicates whether HRTF binary file is used */ int16_t Opt_Headrotation; /* indicates whether head-rotation is used */ @@ -1929,8 +1929,11 @@ typedef struct Decoder_Struct ISM_MODE ism_mode; /* ISM format mode */ SBA_MODE sba_mode; /* SBA format mode */ MC_MODE mc_mode; /* MC format mode */ - +#ifdef SBA_ORDER_BITSTREAM + int16_t sba_analysis_order; /* Ambisonic (SBA) order */ +#else int16_t sba_order; /* Ambisonic (SBA) order */ +#endif int16_t sba_planar; /* Ambisonic (SBA) planar flag */ int16_t sba_dirac_stereo_flag; /* flag indicating stereo output for SBA DirAC modes with 1 TC */ diff --git a/lib_dec/ivas_stereo_mdct_core_dec.c b/lib_dec/ivas_stereo_mdct_core_dec.c index faf86eeb06..3d4c38f272 100644 --- a/lib_dec/ivas_stereo_mdct_core_dec.c +++ b/lib_dec/ivas_stereo_mdct_core_dec.c @@ -116,20 +116,12 @@ static void stereo_mdct_dec_stereo( sts = hCPE->hCoreCoder; -#ifdef LBR_SBA_CORE_CODING_TUNING parse_stereo_from_bitstream( hCPE->hStereoMdct, hCPE->hCoreCoder, 0, hCPE->hStereoMdct->isSBAStereoMode, hCPE->hCoreCoder[0], ms_mask ); -#else - parse_stereo_from_bitstream( hCPE->hStereoMdct, hCPE->hCoreCoder, 0, hCPE->hCoreCoder[0], ms_mask ); -#endif /*Split available bits between channels */ availableBits = sts[0]->bits_frame_channel + sts[1]->bits_frame_channel - sts[0]->next_bit_pos - sts[0]->core * ( NF_GAIN_BITS + SMDCT_MINIMUM_ARITH_BITS ) - sts[1]->core * ( NF_GAIN_BITS + SMDCT_MINIMUM_ARITH_BITS ); -#ifdef LBR_SBA_CORE_CODING_TUNING splitAvailableBits( availableBits, hCPE->hStereoMdct->split_ratio, hCPE->hStereoMdct->isSBAStereoMode, &sts[0]->bits_frame_channel, &sts[1]->bits_frame_channel ); -#else - splitAvailableBits( availableBits, hCPE->hStereoMdct->split_ratio, &sts[0]->bits_frame_channel, &sts[1]->bits_frame_channel ); -#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; @@ -225,14 +217,12 @@ void stereo_mdct_core_dec( initMdctStereoDecData( hCPE->hStereoMdct, sts[0]->igf, sts[0]->hIGFDec->igfData.igfInfo.grid, hCPE->element_brate, sts[0]->bwidth ); -#ifdef LBR_SBA_CORE_CODING_TUNING - hCPE->hStereoMdct->isSBAStereoMode = ( (st_ivas->ivas_format == SBA_FORMAT) && (st_ivas->nchan_transport == 2) ); + hCPE->hStereoMdct->isSBAStereoMode = ( ( st_ivas->ivas_format == SBA_FORMAT ) && ( st_ivas->nchan_transport == 2 ) ); /*to prevent unitialized values during condition checks for stereo IGF*/ if ( hCPE->hStereoMdct->isSBAStereoMode ) { set_s( hCPE->hStereoMdct->IGFStereoMode, -1, 2 ); } -#endif if ( !bfi ) { @@ -304,11 +294,7 @@ void stereo_mdct_core_dec( for ( k = 0; k < nSubframes[0]; k++ ) { - if ( ( hCPE->hStereoMdct->IGFStereoMode[k] != SMDCT_DUAL_MONO || hCPE->hStereoMdct->mdct_stereo_mode[k] != SMDCT_DUAL_MONO ) -#ifdef LBR_SBA_CORE_CODING_TUNING - && !hCPE->hStereoMdct->isSBAStereoMode -#endif - ) + if ( ( hCPE->hStereoMdct->IGFStereoMode[k] != SMDCT_DUAL_MONO || hCPE->hStereoMdct->mdct_stereo_mode[k] != SMDCT_DUAL_MONO ) && !hCPE->hStereoMdct->isSBAStereoMode ) { assert( ( sts[0]->core == sts[1]->core ) || ( hCPE->hStereoMdct->mdct_stereo_mode[0] == SMDCT_DUAL_MONO ) ); @@ -384,11 +370,7 @@ void stereo_mdct_core_dec( mvs2s( ms_mask[1], hCPE->hStereoMdct->prev_ms_mask[1], MAX_SFB ); } - if ( ( !bfi || !( sts[0]->core == ACELP_CORE && sts[1]->core == ACELP_CORE ) ) -#ifdef LBR_SBA_CORE_CODING_TUNING - && !hCPE->hStereoMdct->isSBAStereoMode -#endif - ) + 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 ) ) ); @@ -400,9 +382,6 @@ void stereo_mdct_core_dec( ivas_mdct_core_tns_ns( hCPE, 0, fUseTns, tnsData, x, Aq, 0 ); if ( -#ifndef LBR_SBA_CORE_CODING_TUNING - st_ivas != NULL && -#endif st_ivas->renderer_type == RENDERER_MC_PARAMMC && ( st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_MONO || st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_STEREO ) ) { ivas_ls_setup_conversion_process_mdct_param_mc( st_ivas, x ); diff --git a/lib_dec/ivas_stereo_mdct_stereo_dec.c b/lib_dec/ivas_stereo_mdct_stereo_dec.c index 05c9c12ae2..f797eaf289 100644 --- a/lib_dec/ivas_stereo_mdct_stereo_dec.c +++ b/lib_dec/ivas_stereo_mdct_stereo_dec.c @@ -57,9 +57,7 @@ void parse_stereo_from_bitstream( STEREO_MDCT_DEC_DATA_HANDLE hStereoMdct, /* i/o: MDCT stereo decoder structure */ Decoder_State **sts, /* i/o: decoder state structure */ const int16_t mct_on, /* i : flag mct block (1) or stereo (0)*/ -#ifdef LBR_SBA_CORE_CODING_TUNING const int16_t isSBAStereoMode, /* i : flag core coding for sba */ -#endif Decoder_State *st0, /* i/o: decoder state structure for Bstr*/ int16_t ms_mask[NB_DIV][MAX_SFB] /* o : bandwise MS mask */ ) @@ -69,9 +67,7 @@ void parse_stereo_from_bitstream( #ifdef DEBUGGING int16_t nbits_start = st0->next_bit_pos; #endif -#ifdef LBR_SBA_CORE_CODING_TUNING if ( !isSBAStereoMode ) -#endif { nSubframes = ( sts[0]->core == TCX_10_CORE || ( sts[0]->core != sts[1]->core ) ) ? NB_DIV : 1; sfbConf = ( sts[0]->core == TCX_20_CORE ) ? &hStereoMdct->stbParamsTCX20 : &hStereoMdct->stbParamsTCX10; diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index fd27442c37..c12a356146 100755 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -169,7 +169,11 @@ ivas_error IVAS_DEC_Open( hIvasDec->st_ivas->ini_frame = 0; hIvasDec->st_ivas->ini_active_frame = 0; hIvasDec->st_ivas->writeFECoffset = 0; +#ifndef SBA_ORDER_BITSTREAM hIvasDec->st_ivas->sba_order = 0; +#else + hIvasDec->st_ivas->sba_analysis_order = 0; +#endif hIvasDec->st_ivas->sba_planar = 0; /*initialize pointers*/ diff --git a/lib_enc/ivas_cpe_enc.c b/lib_enc/ivas_cpe_enc.c old mode 100755 new mode 100644 index 25cba61cc4..b543761491 --- a/lib_enc/ivas_cpe_enc.c +++ b/lib_enc/ivas_cpe_enc.c @@ -187,11 +187,7 @@ ivas_error ivas_cpe_enc( * dynamically allocate data structures depending on the actual stereo mode *----------------------------------------------------------------*/ -#ifdef LBR_SBA_CORE_CODING_TUNING if ( ( error = stereo_memory_enc( hCPE, input_Fs, max_bwidth, &tdm_last_ratio, ivas_format, st_ivas->nchan_transport ) ) != IVAS_ERR_OK ) -#else - if ( ( error = stereo_memory_enc( hCPE, input_Fs, max_bwidth, &tdm_last_ratio, ivas_format ) ) != IVAS_ERR_OK ) -#endif { return error; } @@ -323,9 +319,7 @@ ivas_error ivas_cpe_enc( hCPE->hStereoMdct->mdct_stereo_mode_cmdl = hEncoderConfig->stereo_mode_cmdl; #endif initMdctStereoEncData( hCPE->hStereoMdct, ivas_format, hCPE->element_mode, hCPE->element_brate, max_bwidth, 0, NULL, 0 ); -#ifdef LBR_SBA_CORE_CODING_TUNING - hCPE->hStereoMdct->isSBAStereoMode = ( (ivas_format == SBA_FORMAT) && (st_ivas->nchan_transport == 2) ); -#endif + hCPE->hStereoMdct->isSBAStereoMode = ( ( ivas_format == SBA_FORMAT ) && ( st_ivas->nchan_transport == 2 ) ); } } @@ -495,9 +489,7 @@ ivas_error ivas_cpe_enc( if ( sts[0]->bwidth != sts[0]->last_bwidth || ( ( hCPE->last_element_brate != hCPE->element_brate || hCPE->last_element_mode != hCPE->element_mode ) && sts[0]->bwidth != sts[0]->max_bwidth ) ) { initMdctStereoEncData( hCPE->hStereoMdct, ivas_format, hCPE->element_mode, hCPE->element_brate, sts[0]->bwidth, 0, NULL, 0 ); -#ifdef LBR_SBA_CORE_CODING_TUNING - hCPE->hStereoMdct->isSBAStereoMode = ( (ivas_format == SBA_FORMAT) && (st_ivas->nchan_transport == 2) ); -#endif + hCPE->hStereoMdct->isSBAStereoMode = ( ( ivas_format == SBA_FORMAT ) && ( st_ivas->nchan_transport == 2 ) ); if ( hCPE->element_brate <= MAX_MDCT_ITD_BRATE && ivas_format == STEREO_FORMAT ) { @@ -957,9 +949,7 @@ ivas_error create_cpe_enc( 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 ); -#ifdef LBR_SBA_CORE_CODING_TUNING - hCPE->hStereoMdct->isSBAStereoMode = ( (ivas_format == SBA_FORMAT) && (st_ivas->nchan_transport == 2) ); -#endif + hCPE->hStereoMdct->isSBAStereoMode = ( ( ivas_format == SBA_FORMAT ) && ( st_ivas->nchan_transport == 2 ) ); if ( hCPE->element_mode == IVAS_CPE_MDCT && element_brate <= MAX_MDCT_ITD_BRATE && ivas_format == STEREO_FORMAT ) { diff --git a/lib_enc/ivas_mct_enc.c b/lib_enc/ivas_mct_enc.c index 3f93bbce6b..20a2856654 100644 --- a/lib_enc/ivas_mct_enc.c +++ b/lib_enc/ivas_mct_enc.c @@ -195,13 +195,21 @@ ivas_error create_mct_enc( } else if ( ivas_format == SBA_FORMAT && st_ivas->hSpar ) { +#ifndef SBA_ORDER_BITSTREAM hMCT->nchan_out_woLFE = ivas_get_spar_num_TCs( ivas_total_brate, st_ivas->hEncoderConfig->sba_order ); +#else + hMCT->nchan_out_woLFE = ivas_get_spar_num_TCs( ivas_total_brate, st_ivas->sba_analysis_order ); +#endif hMCT->num_lfe = FALSE; } else if ( ivas_format == SBA_FORMAT && st_ivas->hDirAC ) { +#ifndef SBA_ORDER_BITSTREAM hMCT->nchan_out_woLFE = ivas_dirac_getNumTransportChannels( ivas_total_brate, st_ivas->hEncoderConfig->sba_order, st_ivas->hEncoderConfig->sba_planar ); +#else + hMCT->nchan_out_woLFE = ivas_dirac_getNumTransportChannels( ivas_total_brate, st_ivas->sba_analysis_order, st_ivas->hEncoderConfig->sba_planar ); +#endif hMCT->num_lfe = FALSE; } else if ( ivas_format == MC_FORMAT && st_ivas->mc_mode == MC_MODE_PARAMMC ) @@ -211,7 +219,11 @@ ivas_error create_mct_enc( } else if ( ivas_format == SBA_FORMAT ) { +#ifndef SBA_ORDER_BITSTREAM hMCT->nchan_out_woLFE = ivas_sba_get_nchan( st_ivas->hEncoderConfig->sba_order, st_ivas->hEncoderConfig->sba_planar ); +#else + hMCT->nchan_out_woLFE = ivas_sba_get_nchan( st_ivas->sba_analysis_order, st_ivas->hEncoderConfig->sba_planar ); +#endif hMCT->num_lfe = FALSE; } else @@ -339,12 +351,20 @@ ivas_error mct_enc_reconfigure( } else if ( ivas_format == SBA_FORMAT && st_ivas->hDirAC ) { +#ifndef SBA_ORDER_BITSTREAM hMCT->nchan_out_woLFE = ivas_dirac_getNumTransportChannels( ivas_total_brate, st_ivas->hEncoderConfig->sba_order, st_ivas->hEncoderConfig->sba_planar ); +#else + hMCT->nchan_out_woLFE = ivas_dirac_getNumTransportChannels( ivas_total_brate, st_ivas->sba_analysis_order, st_ivas->hEncoderConfig->sba_planar ); +#endif hMCT->num_lfe = FALSE; } else if ( ivas_format == SBA_FORMAT ) { +#ifndef SBA_ORDER_BITSTREAM hMCT->nchan_out_woLFE = ivas_sba_get_nchan( st_ivas->hEncoderConfig->sba_order, st_ivas->hEncoderConfig->sba_planar ); +#else + hMCT->nchan_out_woLFE = ivas_sba_get_nchan( st_ivas->sba_analysis_order, st_ivas->hEncoderConfig->sba_planar ); +#endif hMCT->num_lfe = FALSE; } else diff --git a/lib_enc/ivas_mdct_core_enc.c b/lib_enc/ivas_mdct_core_enc.c index ceea41bcac..4d9d1f2577 100644 --- a/lib_enc/ivas_mdct_core_enc.c +++ b/lib_enc/ivas_mdct_core_enc.c @@ -713,11 +713,7 @@ void ivas_mdct_core_whitening_enc( sts[0]->hTcxEnc->fUseTns[1] = 0; - if ( sts[0]->element_brate < IVAS_80k && sts[0]->core == sts[1]->core && sts[0]->element_mode == IVAS_CPE_MDCT && !mct_on -#ifdef LBR_SBA_CORE_CODING_TUNING - && !hCPE->hStereoMdct->isSBAStereoMode -#endif - ) + if ( sts[0]->element_brate < IVAS_80k && sts[0]->core == sts[1]->core && sts[0]->element_mode == IVAS_CPE_MDCT && !mct_on && !hCPE->hStereoMdct->isSBAStereoMode ) { int16_t nSampCore; int32_t totalRate; diff --git a/lib_enc/ivas_rom_enc.c b/lib_enc/ivas_rom_enc.c index 783085fb86..e8048b8f1a 100644 --- a/lib_enc/ivas_rom_enc.c +++ b/lib_enc/ivas_rom_enc.c @@ -534,6 +534,7 @@ const float ari_bit_estimate_s17_LC[RANGE_N_CONTEXT][RANGE_N_SYMBOLS] = * Stereo downmix to EVS ROM tables *----------------------------------------------------------------------------------*/ +#ifndef NTT_REMOVE_EPS_ROM const float Stereo_dmx_s_wnd_coef_eps_16k[L_FRAME16k * 3 / 4] = { 0.00000000f, 0.000385506690f, 0.000770864717f, 0.00115592557f, 0.00154054083f, 0.00192456215f, 0.00230784155f, 0.00269023119f, 0.00307158381f, 0.00345175178f, 0.00383058959f, 0.00420795102f, 0.00458368938f, 0.00495766103f, 0.00532972161f, 0.00569972629f, 0.00606753491f, 0.00643300405f, 0.00679599261f, 0.00715636183f, @@ -686,6 +687,7 @@ const float Stereo_dmx_s_wnd_coef_eps_48k[L_FRAME48k * 3 / 4] = { -0.00648899190f, -0.00649444433f, -0.00649961829f, -0.00650451379f, -0.00650913082f, -0.00651346892f, -0.00651752809f, -0.00652130833f, -0.00652480870f, -0.00652803015f, -0.00653097173f, -0.00653363345f, -0.00653601484f, -0.00653811684f, -0.00653993897f, -0.00654148031f, -0.00654274225f, -0.00654372340f, -0.00654442422f, -0.00654484471f }; +#endif const float Stereo_dmx_s_wnd_coef_16k[L_FRAME16k >> 4] = { 0.00154133327f, 0.0138150426f, 0.0380602330f, 0.0736799166f, 0.119797014f, 0.175276011f, 0.238750681f, 0.308658302f, 0.383277327f, 0.460770488f, diff --git a/lib_enc/ivas_rom_enc.h b/lib_enc/ivas_rom_enc.h index 7194264225..2a4f71b8b9 100644 --- a/lib_enc/ivas_rom_enc.h +++ b/lib_enc/ivas_rom_enc.h @@ -120,9 +120,11 @@ extern const uint16_t ECSQ_tab_vals[ECSQ_PARAM_COUNT - 1][1 + ECSQ_TAB_VALS_SIZE * Stereo downmix to EVS ROM tables *----------------------------------------------------------------------------------*/ +#ifndef NTT_REMOVE_EPS_ROM extern const float Stereo_dmx_s_wnd_coef_eps_16k[L_FRAME16k * 3 / 4]; extern const float Stereo_dmx_s_wnd_coef_eps_32k[L_FRAME32k * 3 / 4]; extern const float Stereo_dmx_s_wnd_coef_eps_48k[L_FRAME48k * 3 / 4]; +#endif extern const float Stereo_dmx_s_wnd_coef_16k[L_FRAME16k >> 4]; extern const float Stereo_dmx_s_wnd_coef_32k[L_FRAME32k >> 4]; extern const float Stereo_dmx_s_wnd_coef_48k[L_FRAME48k >> 4]; diff --git a/lib_enc/ivas_sba_enc.c b/lib_enc/ivas_sba_enc.c index acce4615af..b267cd2e66 100644 --- a/lib_enc/ivas_sba_enc.c +++ b/lib_enc/ivas_sba_enc.c @@ -62,12 +62,18 @@ void ivas_sba_getTCs( const int16_t input_frame /* i : frame length */ ) { +#ifndef SBA_ORDER_BITSTREAM ivas_sba_zero_vert_comp( sba_data, st_ivas->hEncoderConfig->sba_order, st_ivas->hEncoderConfig->sba_planar, input_frame ); - +#else + ivas_sba_zero_vert_comp( sba_data, st_ivas->sba_analysis_order, st_ivas->hEncoderConfig->sba_planar, input_frame ); +#endif if ( st_ivas->sba_mode == SBA_MODE_SPAR ) { +#ifndef SBA_ORDER_BITSTREAM st_ivas->nchan_transport = ivas_get_spar_num_TCs( st_ivas->hEncoderConfig->ivas_total_brate, st_ivas->hEncoderConfig->sba_order ); - +#else + st_ivas->nchan_transport = ivas_get_spar_num_TCs( st_ivas->hEncoderConfig->ivas_total_brate, st_ivas->sba_analysis_order ); +#endif if ( st_ivas->nchan_transport >= 3 ) { /*convert WYZX downmix to WYXZ*/ @@ -83,7 +89,11 @@ void ivas_sba_getTCs( } else { +#ifndef SBA_ORDER_BITSTREAM st_ivas->nchan_transport = ivas_dirac_getNumTransportChannels( st_ivas->hEncoderConfig->ivas_total_brate, st_ivas->hEncoderConfig->sba_order, st_ivas->hEncoderConfig->sba_planar ); +#else + st_ivas->nchan_transport = ivas_dirac_getNumTransportChannels( st_ivas->hEncoderConfig->ivas_total_brate, st_ivas->sba_analysis_order, st_ivas->hEncoderConfig->sba_planar ); +#endif ivas_sba_dmx_enc( sba_data, st_ivas->nchan_transport, input_frame ); } @@ -516,9 +526,7 @@ ivas_error ivas_sba_enc_reconfigure( } initMdctStereoEncData( st_ivas->hCPE[st_ivas->nCPE - 1]->hStereoMdct, st_ivas->hEncoderConfig->ivas_format, st_ivas->hCPE[st_ivas->nCPE - 1]->element_mode, st_ivas->hCPE[st_ivas->nCPE - 1]->element_brate, st_ivas->hEncoderConfig->max_bwidth, 0, NULL, 1 ); -#ifdef LBR_SBA_CORE_CODING_TUNING - st_ivas->hCPE[st_ivas->nCPE - 1]->hStereoMdct->isSBAStereoMode = ( (st_ivas->hEncoderConfig->ivas_format == SBA_FORMAT) && (st_ivas->nchan_transport == 2) ); -#endif + st_ivas->hCPE[st_ivas->nCPE - 1]->hStereoMdct->isSBAStereoMode = ( ( st_ivas->hEncoderConfig->ivas_format == SBA_FORMAT ) && ( st_ivas->nchan_transport == 2 ) ); } } } diff --git a/lib_enc/ivas_spar_encoder.c b/lib_enc/ivas_spar_encoder.c index ae9328404d..03e16833e3 100644 --- a/lib_enc/ivas_spar_encoder.c +++ b/lib_enc/ivas_spar_encoder.c @@ -79,8 +79,11 @@ ivas_error ivas_spar_enc_open( } input_Fs = hEncoderConfig->input_Fs; - +#ifndef SBA_ORDER_BITSTREAM sba_order_internal = min( hEncoderConfig->sba_order, IVAS_MAX_SBA_ORDER ); +#else + sba_order_internal = min( st_ivas->sba_analysis_order, IVAS_MAX_SBA_ORDER ); +#endif nchan_inp = ivas_sba_get_nchan_metadata( sba_order_internal ); assert( nchan_inp <= hEncoderConfig->nchan_inp ); ivas_total_brate = hEncoderConfig->ivas_total_brate; @@ -91,7 +94,11 @@ ivas_error ivas_spar_enc_open( // ivas_set_bitrate_config(&hSpar->hMdEnc->spar_md_cfg, table_idx); /* MD handle */ +#ifndef SBA_ORDER_BITSTREAM if ( ( error = ivas_spar_md_enc_open( &( hSpar->hMdEnc ), hEncoderConfig ) ) != IVAS_ERR_OK ) +#else + if ( ( error = ivas_spar_md_enc_open( &( hSpar->hMdEnc ), hEncoderConfig, sba_order_internal ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -142,9 +149,13 @@ ivas_error ivas_spar_enc_open( /*-----------------------------------------------------------------* * Configuration - set SPAR high-level parameters *-----------------------------------------------------------------*/ - +#ifdef SBA_ORDER_BITSTREAM + ivas_spar_config( hEncoderConfig->ivas_total_brate, min( st_ivas->sba_analysis_order, IVAS_MAX_SBA_ORDER ), + &st_ivas->nchan_transport, &st_ivas->nSCE, &st_ivas->nCPE, &hSpar->core_nominal_brate, -1 ); +#else ivas_spar_config( hEncoderConfig->ivas_total_brate, min( hEncoderConfig->sba_order, IVAS_MAX_SBA_ORDER ), &st_ivas->nchan_transport, &st_ivas->nSCE, &st_ivas->nCPE, &hSpar->core_nominal_brate, -1 ); +#endif if ( st_ivas->nchan_transport == 1 ) { @@ -302,7 +313,11 @@ ivas_error ivas_spar_enc( if ( hEncoderConfig->sba_planar ) { +#ifndef SBA_ORDER_BITSTREAM ivas_sba_zero_vert_comp( data_f, hEncoderConfig->sba_order, hEncoderConfig->sba_planar, input_frame ); +#else + ivas_sba_zero_vert_comp( data_f, st_ivas->sba_analysis_order, hEncoderConfig->sba_planar, input_frame ); +#endif } if ( ( error = ivas_spar_enc_process( st_ivas, hEncoderConfig, hMetaData, st_ivas->hSpar->front_vad_flag, data_f ) ) != IVAS_ERR_OK ) @@ -312,7 +327,11 @@ ivas_error ivas_spar_enc( if ( hEncoderConfig->sba_planar ) { +#ifndef SBA_ORDER_BITSTREAM ivas_sba_zero_vert_comp( data_f, hEncoderConfig->sba_order, hEncoderConfig->sba_planar, input_frame ); // TODO tmu: do we need a second call to this function ? +#else + ivas_sba_zero_vert_comp( data_f, st_ivas->sba_analysis_order, hEncoderConfig->sba_planar, input_frame ); // TODO tmu: do we need a second call to this function ? +#endif } *nb_bits_metadata = hMetaData->nb_bits_tot; @@ -438,7 +457,11 @@ static ivas_error ivas_spar_enc_process( num_del_samples = hSpar->hFbMixer->fb_cfg->fb_latency; input_frame = (int16_t) ( input_Fs / FRAMES_PER_SEC ); +#ifndef SBA_ORDER_BITSTREAM sba_order = min( hEncoderConfig->sba_order, IVAS_MAX_SBA_ORDER ); +#else + sba_order = min( st_ivas->sba_analysis_order, IVAS_MAX_SBA_ORDER ); +#endif nchan_inp = ivas_sba_get_nchan_metadata( sba_order ); assert( nchan_inp <= hEncoderConfig->nchan_inp ); @@ -677,9 +700,11 @@ static ivas_error ivas_spar_enc_process( md_in_buf.num_bands = min( md_in_buf.num_bands, SPAR_DIRAC_SPLIT_START_BAND ); md_in_buf.dtx_vad = dtx_vad; - +#ifndef SBA_ORDER_BITSTREAM ivas_spar_md_enc_process( hSpar->hMdEnc, hEncoderConfig, &md_in_buf, hMetaData, dtx_silence_mode ); - +#else + ivas_spar_md_enc_process( hSpar->hMdEnc, hEncoderConfig, &md_in_buf, hMetaData, dtx_silence_mode, sba_order ); +#endif if ( st_ivas->sba_mode == SBA_MODE_SPAR ) { float azi_dirac[IVAS_MAX_NUM_BANDS][MAX_PARAM_SPATIAL_SUBFRAMES]; diff --git a/lib_enc/ivas_spar_md_enc.c b/lib_enc/ivas_spar_md_enc.c index 39f8746004..dc7c3677dd 100644 --- a/lib_enc/ivas_spar_md_enc.c +++ b/lib_enc/ivas_spar_md_enc.c @@ -84,7 +84,12 @@ static void ivas_store_prior_coeffs( ivas_spar_md_enc_state_t *hMdEnc, const int static void ivas_write_parameter_bitstream( ivas_spar_md_enc_state_t *hMdEnc, const int16_t nB, const int16_t bands_bw, BSTR_ENC_HANDLE hMetaData, const int32_t ivas_total_brate, const int16_t dtx_silence_mode, const int16_t strat, const int16_t qsi, const int16_t planarCP ); -static ivas_error ivas_spar_md_enc_init( ivas_spar_md_enc_state_t *pState, const ENCODER_CONFIG_HANDLE hEncoderConfig ); +static ivas_error ivas_spar_md_enc_init( ivas_spar_md_enc_state_t *pState, const ENCODER_CONFIG_HANDLE hEncoderConfig +#ifdef SBA_ORDER_BITSTREAM + , + int16_t sba_order +#endif +); static void ivas_spar_quant_pred_coeffs_dtx( ivas_spar_md_t *pSpar_md, float **ppValues, const int16_t ndm, int16_t **ppIndex, const int16_t dim1, float **ppQuant ); @@ -108,22 +113,33 @@ static void ivas_quant_pred_coeffs_per_band( ivas_band_coeffs_t *pband_coeffs, i ivas_error ivas_spar_md_enc_open( ivas_spar_md_enc_state_t **hMdEnc_in, /* i/o: SPAR MD encoder handle */ const ENCODER_CONFIG_HANDLE hEncoderConfig /* i : configuration structure */ +#ifdef SBA_ORDER_BITSTREAM + , + int16_t sba_order +#endif ) { ivas_spar_md_enc_state_t *hMdEnc; ivas_error error; +#ifndef SBA_ORDER_BITSTREAM int16_t num_channels, i, j, order; +#else + int16_t num_channels, i, j; +#endif +#ifndef SBA_ORDER_BITSTREAM order = min( hEncoderConfig->sba_order, IVAS_MAX_SBA_ORDER ); - +#endif error = IVAS_ERR_OK; if ( ( hMdEnc = (ivas_spar_md_enc_state_t *) count_malloc( sizeof( ivas_spar_md_enc_state_t ) ) ) == NULL ) { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR MD encoder" ); } - +#ifndef SBA_ORDER_BITSTREAM num_channels = 2 * order + 2; - +#else + num_channels = 2 * sba_order + 2; +#endif if ( ( hMdEnc->spar_md.band_coeffs = (ivas_band_coeffs_t *) count_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" ); @@ -203,8 +219,11 @@ ivas_error ivas_spar_md_enc_open( } } } - +#ifndef SBA_ORDER_BITSTREAM if ( ( error = ivas_spar_md_enc_init( hMdEnc, hEncoderConfig ) ) != IVAS_ERR_OK ) +#else + if ( ( error = ivas_spar_md_enc_init( hMdEnc, hEncoderConfig, sba_order ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -310,16 +329,22 @@ void ivas_spar_md_enc_close( static ivas_error ivas_spar_md_enc_init( ivas_spar_md_enc_state_t *pState, /* o : MD encoder handle */ const ENCODER_CONFIG_HANDLE hEncoderConfig /* i : configuration structure */ +#ifdef SBA_ORDER_BITSTREAM + , + int16_t sba_order +#endif ) { float pFC[IVAS_MAX_NUM_BANDS]; int16_t table_idx; float PR_minmax[2]; +#ifndef SBA_ORDER_BITSTREAM int16_t sba_order; +#endif int16_t num_channels, i, j, k; - +#ifndef SBA_ORDER_BITSTREAM sba_order = min( hEncoderConfig->sba_order, IVAS_MAX_SBA_ORDER ); - +#endif num_channels = ivas_sba_get_nchan_metadata( sba_order ); table_idx = ivas_get_spar_table_idx( hEncoderConfig->ivas_total_brate, sba_order, SPAR_CONFIG_BW, NULL, NULL ); @@ -559,7 +584,12 @@ ivas_error ivas_spar_md_enc_process( const ENCODER_CONFIG_HANDLE hEncoderConfig, /* i : configuration structure */ ivas_spar_md_enc_in_buf_t *pIn_buf, BSTR_ENC_HANDLE hMetaData, /* i/o: MetaData handle */ - const int16_t dtx_silence_mode ) + const int16_t dtx_silence_mode +#ifdef SBA_ORDER_BITSTREAM + , + int16_t sba_order +#endif +) { float pred_coeffs_re[IVAS_SPAR_MAX_CH - 1][IVAS_MAX_NUM_BANDS]; float dm_fv_re[IVAS_SPAR_MAX_CH - 1][IVAS_MAX_NUM_BANDS]; @@ -568,7 +598,11 @@ ivas_error ivas_spar_md_enc_process( int16_t j, planarCP; int16_t num_bands = pIn_buf->num_bands; int16_t dtx_vad = pIn_buf->dtx_vad; +#ifndef SBA_ORDER_BITSTREAM int16_t active_w, nchan_transport, dmx_switch, strat, sba_order; +#else + int16_t active_w, nchan_transport, dmx_switch, strat; +#endif int16_t nB, bands_bw, packed_ok = 0; ivas_strats_t cs[MAX_CODING_STRATS]; int16_t code_strat; @@ -578,8 +612,9 @@ ivas_error ivas_spar_md_enc_process( float Wscale[IVAS_MAX_NUM_BANDS]; ivas_spar_md_enc_state_t *pState = hMdEnc; int16_t num_quant_strats = pState->spar_md_cfg.num_quant_strats; - +#ifndef SBA_ORDER_BITSTREAM sba_order = min( hEncoderConfig->sba_order, IVAS_MAX_SBA_ORDER ); +#endif num_ch = ivas_sba_get_nchan_metadata( sba_order ); active_w = pState->spar_md_cfg.active_w; nchan_transport = pState->spar_md_cfg.nchan_transport; diff --git a/lib_enc/ivas_stat_enc.h b/lib_enc/ivas_stat_enc.h index 170c03d997..58b6970d58 100644 --- a/lib_enc/ivas_stat_enc.h +++ b/lib_enc/ivas_stat_enc.h @@ -311,9 +311,7 @@ typedef struct stereo_mdct_enc_data_structure int16_t sw_uncorr; -#ifdef LBR_SBA_CORE_CODING_TUNING int16_t isSBAStereoMode; -#endif } STEREO_MDCT_ENC_DATA, *STEREO_MDCT_ENC_DATA_HANDLE; @@ -998,7 +996,6 @@ typedef struct encoder_config_structure int16_t element_mode_init; /* element mode used at initialization */ int16_t stereo_dmx_evs; /* flag to indicate that stereo downmix for EVS encoder */ - int16_t sba_order; /* Ambisonic (SBA) order */ int16_t sba_planar; /* Ambisonic (SBA) planar flag */ MC_LS_SETUP mc_input_setup; /* multichannel input ls setup */ @@ -1043,7 +1040,9 @@ typedef struct /* high-level encoder parameters */ int16_t nchan_transport; /* number of transport channels */ - +#ifdef SBA_ORDER_BITSTREAM + int16_t sba_analysis_order; /*Ambisonic(SBA) order*/ +#endif int16_t codec_mode; /* Mode1 or Mode2 of core codec */ int16_t last_codec_mode; /* previous frame Mode 1 or 2 */ diff --git a/lib_enc/ivas_stereo_dmx_evs.c b/lib_enc/ivas_stereo_dmx_evs.c index af3430766a..409b7b0d56 100644 --- a/lib_enc/ivas_stereo_dmx_evs.c +++ b/lib_enc/ivas_stereo_dmx_evs.c @@ -63,6 +63,8 @@ #define STEREO_DMX_EVS_DMX_EGY_FORGETTING 0.25f #define STEREO_DMX_EVS_CORR_FORGETTING 0.78f +#define Q_BAND 0.25f + /*-----------------------------------------------------------------------* * Local function prototypes *-----------------------------------------------------------------------*/ @@ -150,26 +152,34 @@ static void calc_poc( { int16_t i, n1, n2; int16_t n0, *itdLR; - const float *c, *s; +#ifndef NTT_REMOVE_EPS_ROM + const float *c; +#endif + const float *s; float *P; float tmp1, tmp2, Lr, Li, Rr, Ri, gamma, igamma, iN; float specPOr[L_FRAME48k], specPOi[L_FRAME48k]; float tmpPOC1[L_FRAME48k], tmpPOC2[L_FRAME48k]; float rfft_buf[L_FRAME48k]; int16_t step, bias; +#ifdef NTT_REMOVE_EPS_ROM + int16_t i_for; + int16_t cos_step, cos_max; + float eps_cos, eps_sin, EPS; +#endif /* Initialization */ iN = 1.0f / (float) input_frame; +#ifndef NTT_REMOVE_EPS_ROM c = hPOC->sin + ( input_frame >> 2 ); +#endif s = hPOC->sin; P = hPOC->P; n0 = input_frame / 2; itdLR = hPOC->itdLR; igamma = STEREO_DMX_EVS_POC_GAMMA * iN; gamma = 1.0f - igamma; - set_zero( tmpPOC1, L_FRAME48k ); - set_zero( tmpPOC2, L_FRAME48k ); if ( input_frame == L_FRAME16k ) { @@ -185,6 +195,65 @@ static void calc_poc( specPOr[0] = sign( specLr[0] ) * sign( specRr[0] ) * wnd[bias]; specPOi[0] = 0.0f; +#ifdef NTT_REMOVE_EPS_ROM + EPS = hPOC->eps; + + if ( input_frame == L_FRAME16k ) + { + cos_step = 4; + cos_max = input_frame; + } + else /* for 32 kHz & 48 kHz */ + { + cos_step = 2; + cos_max = n0; + } + + for ( i = 1; i < n0 / 2; i++ ) + { + Lr = specLr[i]; + Li = specLi[i]; + Rr = specRr[i]; + Ri = specRi[i]; + i_for = i * cos_step; + eps_cos = s[cos_max - i_for] * EPS; + eps_sin = s[i_for] * EPS; + Lr += ( specRr[i] * eps_cos + specRi[i] * eps_sin ); + Li += ( -specRr[i] * eps_sin + specRi[i] * eps_cos ); + Rr += ( specLr[i] * eps_cos + specLi[i] * eps_sin ); + Ri += ( -specLr[i] * eps_sin + specLi[i] * eps_cos ); + tmp1 = wnd[i * step + bias] * gamma / ( sqrtf( ( ( Lr * Lr + Li * Li ) ) * ( ( Rr * Rr + Ri * Ri ) ) ) + EPS ); + + specPOr[i] = ( Lr * Rr + Li * Ri ) * tmp1; + specPOi[i] = ( Lr * Ri - Li * Rr ) * tmp1; + + gamma -= igamma; + } + + for ( i = n0 >> 1; i < n0; i++ ) + { + Lr = specLr[i]; + Li = specLi[i]; + Rr = specRr[i]; + Ri = specRi[i]; + + i_for = ( n0 - i ) * cos_step; + eps_cos = s[cos_max - i_for] * EPS; + eps_sin = s[i_for] * EPS; + + Lr += ( -specRr[i] * eps_cos + specRi[i] * eps_sin ); + Li += ( -specRr[i] * eps_sin - specRi[i] * eps_cos ); + Rr += ( -specLr[i] * eps_cos + specLi[i] * eps_sin ); + Ri += ( -specLr[i] * eps_sin - specLi[i] * eps_cos ); + + tmp1 = wnd[i * step + bias] * gamma / ( sqrtf( ( ( Lr * Lr + Li * Li ) ) * ( ( Rr * Rr + Ri * Ri ) ) ) + EPS ); + + specPOr[i] = ( Lr * Rr + Li * Ri ) * tmp1; + specPOi[i] = ( Lr * Ri - Li * Rr ) * tmp1; + gamma -= igamma; + } + // end NTT_REMOVE_EPS_ROM +#else for ( i = 1; i < n0; i++ ) { Lr = specLr[i]; @@ -204,6 +273,8 @@ static void calc_poc( gamma -= igamma; } +#endif // end !NTT_REMOVE_EPS_ROM + specPOr[n0] = sign( specLr[i] ) * sign( specRr[i] ) * wnd[i * step + bias] * gamma; rfft_buf[0] = specPOr[0]; @@ -305,7 +376,7 @@ static float find_poc_peak( itd_cand[0] = itd_cand[1] = 0; P = hPOC->P; - for ( i = 1; i < hPOC->shift_limit; i++ ) + for ( i = 1; i < hPOC->shift_limit; i++ ) /*find peaks of POC P[] with positive and negative ITD */ { if ( P[Lh - i] > Q[0] ) { @@ -340,7 +411,7 @@ static float find_poc_peak( Q[n] = ( 1.0f - ( cQ[n] / ( peak_range * 2 + 1 ) + eps2 ) / ( Q[n] + eps2 ) ); Q[n] = max( Q[n], 0.0f ); - if ( on[n] ) + if ( on[n] ) /*if channel n was active (likely to be preceding) in the previous frame*/ { tmpf = ( 0.3f - 0.2f * (float) abs( itd_cand[n] ) / (float) hPOC->shift_limit ) * peakQ[n]; if ( Q[n] < tmpf ) @@ -357,7 +428,7 @@ static float find_poc_peak( peakQ[n] = max( peakQ[n], Q[n] ); } - else + else /*if channel n was not active (not likely to be preceding) in the previous frame*/ { tmpf = ( 0.75f - 0.2f * (float) abs( itd_cand[n] ) / (float) hPOC->shift_limit ); @@ -374,6 +445,7 @@ static float find_poc_peak( } } +#ifndef NTT_UPDATE_ITD_SW if ( on[0] && prev_off[0] ) { *itd = (float) itdLR[0]; @@ -386,8 +458,38 @@ static float find_poc_peak( { *itd = ( *itd > 0 ) ? (float) itdLR[0] : (float) itdLR[1]; } +#else + if ( ( on[0] && prev_off[0] ) && ( on[1] && prev_off[1] ) ) /*if both channels have newly detected as active (possibility of preceding), select channel by peakness Q[] of POC */ + { + *itd = ( Q[0] > Q[1] ) ? (float) itdLR[0] : (float) itdLR[1]; + } + else if ( ( on[0] && prev_off[0] ) && ( Q[0] > ( Q[1] - 0.1 ) ) ) /* if channel 0 becomes active, select channel 0*/ + { + *itd = (float) itdLR[0]; + } + else if ( ( on[1] && prev_off[1] ) && ( Q[1] > ( Q[0] - 0.1 ) ) ) /*if channel 1 becomes active, selsect channel 1*/ + { + *itd = (float) itdLR[1]; + } + else if ( Q[0] > ( Q[1] + Q_BAND ) ) /* if no status change, use Q[]*/ + { + *itd = (float) itdLR[0]; + } + else if ( Q[1] > ( Q[0] + Q_BAND ) ) /* if no status change, use Q[]*/ + { + *itd = (float) itdLR[1]; + } + else if ( *itd == 0.0 ) /*if no channels are likely to be preceding, follow the status of the previous frame*/ + { + *itd = 0; + } + else /*follow the status of the previous frame*/ + { + *itd = ( *itd > 0 ) ? (float) itdLR[0] : (float) itdLR[1]; + } +#endif - cconfidence = sqrtf( fabsf( Q[0] - Q[1] ) ); + cconfidence = sqrtf( fabsf( Q[0] - Q[1] ) ); /*higher value indicates higher confidence for one preceding channel*/ return hPOC->confidence = hPOC->confidence * STEREO_DMX_EVS_CORR_FORGETTING + cconfidence * ( 1.0f - STEREO_DMX_EVS_CORR_FORGETTING ); } @@ -766,6 +868,24 @@ ivas_error stereo_dmx_evs_init_encoder( } hStereoDmxEVS->hPOC->eps = 2.0f * EVS_PI / ( (float) input_frame ); +#ifdef NTT_REMOVE_EPS_ROM + if ( input_frame == L_FRAME16k ) + { + hStereoDmxEVS->hPOC->sin = dft_trigo_32k; + } + else if ( input_frame == L_FRAME32k ) + { + hStereoDmxEVS->hPOC->sin = dft_trigo_32k; + } + else if ( input_frame == L_FRAME48k ) + { + hStereoDmxEVS->hPOC->sin = dft_trigo_48k; + } + else + { + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "invalid frame length\n" ); + } +#else if ( input_frame == L_FRAME16k ) { hStereoDmxEVS->hPOC->sin = Stereo_dmx_s_wnd_coef_eps_16k; @@ -782,6 +902,8 @@ ivas_error stereo_dmx_evs_init_encoder( { return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "invalid frame length\n" ); } +#endif + hStereoDmxEVS->hPOC->confidence = 0.0f; *hStereoDmxEVS_out = hStereoDmxEVS; diff --git a/lib_enc/ivas_stereo_mdct_core_enc.c b/lib_enc/ivas_stereo_mdct_core_enc.c old mode 100755 new mode 100644 index 00a47e3706..c41df7b24e --- a/lib_enc/ivas_stereo_mdct_core_enc.c +++ b/lib_enc/ivas_stereo_mdct_core_enc.c @@ -253,9 +253,7 @@ void stereo_mdct_core_enc( /*--------------------------------------------------------------* * Stereo Processing *---------------------------------------------------------------*/ -#ifdef LBR_SBA_CORE_CODING_TUNING if ( !hStereoMdct->isSBAStereoMode ) -#endif { stereo_coder_tcx( hStereoMdct, sts, ms_mask, mdst_spectrum, inv_spectrum, inv_mdst_spectrum, 0 ); } @@ -350,11 +348,8 @@ void stereo_mdct_core_enc( for ( n = 0; n < nSubframes; n++ ) { if ( ( hStereoMdct->mdct_stereo_mode[n] != hStereoMdct->IGFStereoMode[n] || - hStereoMdct->mdct_stereo_mode[n] == SMDCT_BW_MS ) -#ifdef LBR_SBA_CORE_CODING_TUNING - && !hStereoMdct->isSBAStereoMode -#endif - ) + hStereoMdct->mdct_stereo_mode[n] == SMDCT_BW_MS ) && + !hStereoMdct->isSBAStereoMode ) { ProcessStereoIGF( hStereoMdct, sts, ms_mask, orig_spectrum, powerSpec, powerSpecMsInv, inv_spectrum, n, hCPE->hCoreCoder[0]->sp_aud_decision0, hCPE->hCoreCoder[0]->element_brate, 0 ); } @@ -402,18 +397,14 @@ void stereo_mdct_core_enc( /* correct side bits per channel*/ sts[0]->side_bits_frame_channel -= SMDCT_NBBITS_SPLIT_RATIO; -#ifdef LBR_SBA_CORE_CODING_TUNING if ( !hStereoMdct->isSBAStereoMode ) -#endif { stereo_bits = write_stereo_to_bitstream( hStereoMdct, sts, ms_mask, 0, hBstr ); } -#ifdef LBR_SBA_CORE_CODING_TUNING else { stereo_bits = 0; } -#endif /*--------------------------------------------------------------* * Split available bits between channels *---------------------------------------------------------------*/ @@ -429,11 +420,7 @@ void stereo_mdct_core_enc( nAvailBits -= meta_bits; nAvailBits -= SMDCT_NBBITS_SPLIT_RATIO; -#ifdef LBR_SBA_CORE_CODING_TUNING splitAvailableBits( nAvailBits, hStereoMdct->split_ratio, hStereoMdct->isSBAStereoMode, &sts[0]->bits_frame_channel, &sts[1]->bits_frame_channel ); -#else - splitAvailableBits( nAvailBits, hStereoMdct->split_ratio, &sts[0]->bits_frame_channel, &sts[1]->bits_frame_channel ); -#endif #ifdef DEBUG_MODE_MDCT dbgwrite( &nAvailBits, sizeof( int16_t ), 1, 1, "./res/nAvailBits" ); #endif diff --git a/lib_enc/ivas_stereo_switching_enc.c b/lib_enc/ivas_stereo_switching_enc.c index 8654299545..9075d73595 100644 --- a/lib_enc/ivas_stereo_switching_enc.c +++ b/lib_enc/ivas_stereo_switching_enc.c @@ -223,10 +223,8 @@ ivas_error stereo_memory_enc( const int16_t max_bwidth, /* i : maximum audio bandwidth */ float *tdm_last_ratio, /* o : TD stereo last ratio */ const IVAS_FORMAT ivas_format /* i : ivas format */ -#ifdef LBR_SBA_CORE_CODING_TUNING , const int16_t nchan_transport /* i : number transport chans */ -#endif ) { Encoder_State *st; @@ -540,9 +538,7 @@ ivas_error stereo_memory_enc( #endif initMdctStereoEncData( hCPE->hStereoMdct, ivas_format, hCPE->element_mode, hCPE->element_brate, hCPE->hCoreCoder[0]->max_bwidth, 0, NULL, 1 ); -#ifdef LBR_SBA_CORE_CODING_TUNING - hCPE->hStereoMdct->isSBAStereoMode = ( (ivas_format == SBA_FORMAT) && (nchan_transport == 2) ); -#endif + hCPE->hStereoMdct->isSBAStereoMode = ( ( ivas_format == SBA_FORMAT ) && ( nchan_transport == 2 ) ); if ( hCPE->element_mode == IVAS_CPE_MDCT && hCPE->element_brate <= MAX_MDCT_ITD_BRATE && ivas_format == STEREO_FORMAT ) { diff --git a/lib_enc/lib_enc.c b/lib_enc/lib_enc.c index 760ae0d353..b9d4dde032 100755 --- a/lib_enc/lib_enc.c +++ b/lib_enc/lib_enc.c @@ -460,10 +460,8 @@ ivas_error IVAS_ENC_ConfigureForAmbisonics( hEncoderConfig->element_mode_init = IVAS_SCE; /* Just needs to be something not mono, will be set later */ hEncoderConfig->sba_planar = isPlanar; hEncoderConfig->sba_order = order; - /* 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*/ - hEncoderConfig->Opt_AGC_ON = (int16_t) Opt_AGC_ON; hEncoderConfig->Opt_PCA_ON = (int16_t) Opt_PCA_ON; @@ -641,7 +639,9 @@ static ivas_error configureEncoder( st_ivas = hIvasEnc->st_ivas; hEncoderConfig = st_ivas->hEncoderConfig; - +#ifdef SBA_ORDER_BITSTREAM + st_ivas->sba_analysis_order = hEncoderConfig->sba_order; +#endif /*-----------------------------------------------------------------* * Bandwidth limitation *-----------------------------------------------------------------*/ @@ -776,7 +776,11 @@ static ivas_error configureEncoder( { /* set SBA order to 1 for bit rates below 256kbps for correct handling of input with higher order */ /* IVAS_fmToDo: needs more work in case of bitrate switching */ +#ifndef SBA_ORDER_BITSTREAM hEncoderConfig->sba_order = 1; +#else + st_ivas->sba_analysis_order = 1; +#endif } } else if ( hEncoderConfig->ivas_format == MASA_FORMAT ) @@ -882,8 +886,11 @@ static ivas_error configureEncoder( { return IVAS_ERROR( IVAS_ERR_NOT_SUPPORTED_OPTION, "AGC supported in SBA format at bitrates >= 24.4 kbps only." ); } - +#ifndef SBA_ORDER_BITSTREAM if ( hEncoderConfig->Opt_PCA_ON && !( hEncoderConfig->ivas_format == SBA_FORMAT && hEncoderConfig->ivas_total_brate == PCA_BRATE && hEncoderConfig->sba_order == 1 ) ) +#else + if ( hEncoderConfig->Opt_PCA_ON && !( hEncoderConfig->ivas_format == SBA_FORMAT && hEncoderConfig->ivas_total_brate == PCA_BRATE && st_ivas->sba_analysis_order == 1 ) ) +#endif { return IVAS_ERROR( IVAS_ERR_NOT_SUPPORTED_OPTION, "PCA supported at SBA FOA 256 kbps only." ); } diff --git a/lib_rend/ivas_output_init.c b/lib_rend/ivas_output_init.c index c21cbafda3..fcaa6f9442 100644 --- a/lib_rend/ivas_output_init.c +++ b/lib_rend/ivas_output_init.c @@ -263,7 +263,7 @@ void ivas_renderer_select( AUDIO_CONFIG output_config; AUDIO_CONFIG transport_config; - #ifdef FIX_I87 +#ifdef FIX_I87 int16_t nchan_internal; #endif @@ -361,7 +361,11 @@ void ivas_renderer_select( { #ifdef FIX_I87 +#ifdef SBA_ORDER_BITSTREAM + nchan_internal = ivas_sba_get_nchan_metadata( st_ivas->sba_analysis_order ); +#else nchan_internal = ivas_sba_get_nchan_metadata( st_ivas->sba_order ); +#endif if ( nchan_internal == 2 ) { st_ivas->hHeadTrackData->shd_rot_max_order = 1; diff --git a/lib_rend/ivas_sba_rendering.c b/lib_rend/ivas_sba_rendering.c index dbcec392a5..03db2203c9 100644 --- a/lib_rend/ivas_sba_rendering.c +++ b/lib_rend/ivas_sba_rendering.c @@ -274,7 +274,11 @@ int16_t ivas_sba_remapTCs( if ( st_ivas->sba_mode != SBA_MODE_SPAR ) { +#ifndef SBA_ORDER_BITSTREAM ivas_sba_zero_vert_comp( sba_data, st_ivas->sba_order, st_ivas->sba_planar, output_frame ); +#else + ivas_sba_zero_vert_comp( sba_data, st_ivas->sba_analysis_order, st_ivas->sba_planar, output_frame ); +#endif } return ( nchan_remapped ); } diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index b62ff9490b..ce35e8019d 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -98,6 +98,9 @@ struct IVAS_REND /* =========== limiter handle =========== */ IVAS_LIMITER_HANDLE hLimiter; +#ifdef DEBUGGING + int32_t numClipping; /* Counter of clipped output samples */ +#endif /* Ambisonics decoding matrix */ float *ambi_dec_mtx; @@ -272,7 +275,7 @@ static void getHoaDecVecForAmbiChnl( const float *decMtx, float *decCoeffs ); -static void ivas_limiter_renderer( +static int32_t ivas_limiter_renderer( 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 */ @@ -324,6 +327,9 @@ IVAS_REND_HANDLE IVAS_REND_Open() st->enableHeadRotation = 0; st->rendererConfigEnabled = 0; st->forceBinLfeLpf = 0; +#ifdef DEBUGGING + st->numClipping = 0; +#endif for ( i = 0; i < RENDERER_HEAD_POSITIONS_PER_FRAME; ++i ) { @@ -1011,6 +1017,9 @@ void IVAS_REND_Render( } /* Apply limiting in place */ +#ifdef DEBUGGING + st->numClipping += +#endif ivas_limiter_renderer( st->hLimiter, outAudio.data, @@ -1295,6 +1304,27 @@ ivas_error IVAS_REND_GetDelay( return IVAS_ERR_OK; } +#ifdef DEBUGGING +int32_t IVAS_REND_GetNoCLipping( + IVAS_REND_HANDLE st /* i : Renderer state */ +) +{ + return st->numClipping; +} + +int32_t IVAS_REND_GetCntFramesLimited( + IVAS_REND_HANDLE st /* i : Renderer state */ +) +{ + if (st->hLimiter == NULL) + { + return 0; + } + + return st->hLimiter->cnt_frames_limited; +} +#endif + /* ============================= Local functions ============================ */ static float *get_smpl_ptr( IVAS_REND_AudioBuffer buffer, uint32_t chnlIdx, uint32_t smplIdx ) { @@ -2355,8 +2385,17 @@ static void prepareLfeHandling( } /* Low-pass filter */ - ivas_lfe_lpf_select_filt_coeff( st->sampleRate, IVAS_FILTER_ORDER_4, &filtCoeff ); - ivas_filters_init( &st->lfeLpFilter, filtCoeff, IVAS_FILTER_ORDER_4 ); + /* TODO: More discussion needed on LFE filtering: + - introduces delay + - introduces phase shift + + Should we do any filtering? + */ + if (st->forceBinLfeLpf) + { + ivas_lfe_lpf_select_filt_coeff( st->sampleRate, IVAS_FILTER_ORDER_4, &filtCoeff ); + ivas_filters_init( &st->lfeLpFilter, filtCoeff, IVAS_FILTER_ORDER_4 ); + } #ifdef WMOPS wmops_sub_end(); @@ -3056,35 +3095,51 @@ void getHoaDecVecForAmbiChnl( * ivas_limiter_renderer() * * In-place saturation control for multichannel buffers with adaptive release time + * + * r: number of clipped output samples *-------------------------------------------------------------------*/ -static void ivas_limiter_renderer( +static int32_t ivas_limiter_renderer( 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 c; + int16_t i; float **channels; int16_t num_channels; + uint32_t numClipping = 0; /* return early if given bad parameters */ if ( hLimiter == NULL || output == NULL || output_frame <= 0 ) { - return; + return 0; } channels = hLimiter->channel_ptrs; num_channels = hLimiter->num_channels; - for ( c = 0; c < num_channels; ++c ) + for ( i = 0; i < num_channels; ++i ) { - channels[c] = output + c * output_frame; + channels[i] = output + i * output_frame; } limiter_process( hLimiter, output_frame, threshold, 0, NULL ); - return; + /* 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] > 1.0f || output[i] < -1.0f ) + { + ++numClipping; + } +#endif + + output[i] = min( max( -1.0f, output[i] ), 1.0f ); + } + + return numClipping; } static float dBToLin( const float gain_dB ) diff --git a/lib_rend/lib_rend.h b/lib_rend/lib_rend.h index 6c5ae79fa4..dfcf0ec57a 100644 --- a/lib_rend/lib_rend.h +++ b/lib_rend/lib_rend.h @@ -237,6 +237,17 @@ int16_t IVAS_REND_GetOutChannels( void IVAS_REND_Close( IVAS_REND_HANDLE* st /* i : Renderer state */ ); + +#ifdef DEBUGGING +int32_t IVAS_REND_GetNoCLipping( + IVAS_REND_HANDLE st /* i : Renderer state */ +); + +int32_t IVAS_REND_GetCntFramesLimited( + IVAS_REND_HANDLE st /* i : Renderer state */ +); +#endif + /* clang-format on */ #endif /* LIB_REND_H */ diff --git a/scripts/cut_bs.py b/scripts/cut_bs.py new file mode 100755 index 0000000000..261a66bc9f --- /dev/null +++ b/scripts/cut_bs.py @@ -0,0 +1,122 @@ +#!/usr/bin/env python3 + +""" + (C) 2022 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. +""" + +import struct +import argparse +import os.path +import sys + +SID_BITS = {35, 48, 88, 100} +SYNC_WORDS = {b"!k", b" k"} + + +def cut_bs(fp, fp_out, start_frame=0, start_with_sid=False): + # cut until start frame + fr_cnt = 0 + cut_cnt = 0 + for cur_frame in range(start_frame): + sync_word = fp.read(2) + if sync_word == b"": + return (fr_cnt, cut_cnt) + if sync_word not in SYNC_WORDS: + raise ValueError("Bad Sync word!") + n_bits = struct.unpack("h", fp.read(2))[0] + fp.read(n_bits * 2) + fr_cnt += 1 + cut_cnt += 1 + if start_with_sid: + found = False + while not found: + sync_word = fp.read(2) + if sync_word == b"": + return (fr_cnt, cut_cnt) + if sync_word not in SYNC_WORDS: + raise ValueError("Bad Sync word!") + n_bits_bs = fp.read(2) + n_bits = struct.unpack("h", n_bits_bs)[0] + if n_bits in SID_BITS: + found = True + fp_out.write(sync_word) + fp_out.write(n_bits_bs) + fp_out.write(fp.read(n_bits * 2)) + else: + fp.read(n_bits * 2) + cut_cnt += 1 + fr_cnt += 1 + + # transfer remaining frames + while True: + sync_word = fp.read(2) + if sync_word == b"": + break + if sync_word not in SYNC_WORDS: + raise ValueError("Bad Sync word!") + n_bits_bs = fp.read(2) + n_bits = struct.unpack("h", n_bits_bs)[0] + fp_out.write(sync_word) + fp_out.write(n_bits_bs) + fp_out.write(fp.read(n_bits * 2)) + fr_cnt += 1 + + return (fr_cnt, cut_cnt) + + +if __name__ == "__main__": + my_parser = argparse.ArgumentParser( + description="Cut frames from the beginning of a G.192 bit stream file" + ) + my_parser.add_argument( + "--sid", "-s", help="Cut until the first SID frame", action="store_true" + ) + my_parser.add_argument( + "--frame", "-f", type=int, help="Number of frames to cut.", default=0 + ) + my_parser.add_argument("bs_in", type=str, help="G.192 bit stream file name to cut") + my_parser.add_argument("bs_out", type=str, help="Cut G.192 bit stream file name") + my_args = my_parser.parse_args() + if not os.path.exists(os.path.realpath(my_args.bs_in)): + print(f"\nInput file {my_args.bs_in} does not exist!") + sys.exit(-1) + if not os.path.exists(os.path.realpath(my_args.bs_out)): + print(f"\nOutput file {my_args.bs_out} does not exist, creating it!") + else: + print(f"\nOutput file {my_args.bs_out} does exist, overwriting it!") + + with open(my_args.bs_in, "rb") as fp_in: + with open(my_args.bs_out, "wb") as fp_out: + fr_cnt, cut_cnt = cut_bs( + fp_in, fp_out, start_frame=my_args.frame, start_with_sid=my_args.sid + ) + + if my_args.sid and (fr_cnt == cut_cnt): + print("Warning! No SID frame found in bitstream!") + print(f"Cut {cut_cnt} of {fr_cnt} frames from {my_args.bs_in}") diff --git a/scripts/pyivastest/IvasScriptsCommon.py b/scripts/pyivastest/IvasScriptsCommon.py index 7e84efc215..45631566e9 100644 --- a/scripts/pyivastest/IvasScriptsCommon.py +++ b/scripts/pyivastest/IvasScriptsCommon.py @@ -596,7 +596,7 @@ def runner_setup(runner, args): if args["sidstart"]: sidstart_cmd = [ - os.path.join(constants.SCRIPTS_BASE_DIR, "tools", "cut_bs.py"), + os.path.join(constants.SCRIPTS_BASE_DIR, "cut_bs.py"), "--sid", "{in_file}", "{out_file}", @@ -686,7 +686,7 @@ def analyzer_setup(analyzer, args): if args["sidstart"]: sidstart_cmd = [ - os.path.join(constants.SCRIPTS_BASE_DIR, "tools", "cut_bs.py"), + os.path.join(constants.SCRIPTS_BASE_DIR, "cut_bs.py"), "--sid", "{in_file}", "{out_file}", -- GitLab From a94ea3b837207440cb977eb87b5d50026293a1bb Mon Sep 17 00:00:00 2001 From: Kacper Sagnowski Date: Thu, 1 Sep 2022 11:02:05 +0200 Subject: [PATCH 016/101] Switch to using float range INT16_MIN:INT16_MAX --- apps/renderer.c | 105 ++++++++++++++++++++++++++++++++------------ lib_rend/lib_rend.c | 4 +- 2 files changed, 78 insertions(+), 31 deletions(-) diff --git a/apps/renderer.c b/apps/renderer.c index 8197b05bd8..c8d1ee7bd6 100644 --- a/apps/renderer.c +++ b/apps/renderer.c @@ -293,6 +293,17 @@ static void convert_backslash( static void remove_cr( char *str ); +static void convertInputBuffer( const int16_t *intBuffer, + int32_t numIntSamplesPerChannel, /* Number of samples per channel in the int buffer */ + int32_t numFloatSamplesPerChannel, /* Per-channel length of the float buffer. If > numIntSamplesPerChannel, remaining samples will be set to 0. */ + int32_t numChannels, + float *floatBuffer ); + +static void convertOutputBuffer( const float *floatBuffer, + int32_t numSamplesPerChannel, + int32_t numChannels, + int16_t *intBuffer ); + /* ============================================================================ */ @@ -475,10 +486,8 @@ int32_t main( int32_t argc, char **argv ) while ( 1 ) { - int32_t chnl, smpl; int32_t num_in_channels; num_in_channels = inBuffer.config.numChannels; - i = 0; /* Read the input data */ if ( ( error = AudioFileReader_read( audioReader, inpInt16Buffer, inBufferSize, &numSamplesRead ) ) != IVAS_ERR_OK ) @@ -494,22 +503,7 @@ int32_t main( int32_t argc, char **argv ) } /* Convert from int to float and from interleaved to packed */ - for ( smpl = 0; smpl < frameSize_smpls; ++smpl ) - { - for ( chnl = 0; chnl < num_in_channels; ++chnl ) - { - if ( i < numSamplesRead ) - { - inFloatBuffer[chnl * frameSize_smpls + smpl] = (float) inpInt16Buffer[i] / INT16_MAX; - } - else - { - inFloatBuffer[chnl * frameSize_smpls + smpl] = 0.f; - } - - ++i; - } - } + convertInputBuffer( inpInt16Buffer, numSamplesRead, frameSize_smpls, num_in_channels, inFloatBuffer ); if ( masaReader != NULL ) { @@ -537,18 +531,10 @@ int32_t main( int32_t argc, char **argv ) int32_t num_out_channels; num_out_channels = outBuffer.config.numChannels; - i = 0; - /* Convert from float to int and from packed to interleaved */ - for ( smpl = 0; smpl < frameSize_smpls; ++smpl ) - { - for ( chnl = 0; chnl < num_out_channels; ++chnl ) - { - outInt16Buffer[i] = (int16_t) ( outFloatBuffer[chnl * frameSize_smpls + smpl] * INT16_MAX ); - - ++i; - } - } + /* 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, frameSize_smpls, num_out_channels, outInt16Buffer ); /* TODO tmu : delay compensation not finalized yet */ if ( delayNumSamples == -1 ) @@ -2064,3 +2050,64 @@ static void remove_cr( char *str ) 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, + int32_t numIntSamplesPerChannel, + int32_t numFloatSamplesPerChannel, + int32_t numChannels, + float *floatBuffer ) +{ + int32_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; + } + } +} + +/*--------------------------------------------------------------------------* + * 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, + int32_t numSamplesPerChannel, + int32_t numChannels, + int16_t *intBuffer ) +{ + int32_t chnl, smpl, i; + + i = 0; + + for ( smpl = 0; smpl < numSamplesPerChannel; ++smpl ) + { + for ( chnl = 0; chnl < numChannels; ++chnl ) + { + intBuffer[i] = (int16_t) roundf( floatBuffer[chnl * numSamplesPerChannel + smpl] ); + + ++i; + } + } +} diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index ce35e8019d..9658883460 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -46,7 +46,7 @@ #include -#define LIMITER_THRESHOLD 0.9988493699f /* -0.01 dBFS */ +#define LIMITER_THRESHOLD ( 0.9988493699f * INT16_MAX ) /* -0.01 dBFS */ /* Due to API of some rendering methods, the renderer has to use the decoder struct. Only struct members relevant for rendering will be initialized, therefore typedef as "dummy" decoder struct */ @@ -3136,7 +3136,7 @@ static int32_t ivas_limiter_renderer( } #endif - output[i] = min( max( -1.0f, output[i] ), 1.0f ); + output[i] = min( max( INT16_MIN, output[i] ), INT16_MAX ); } return numClipping; -- GitLab From 9d5d5c463b9273020ab812e6001cf84c1060eaa9 Mon Sep 17 00:00:00 2001 From: muxe6256 Date: Mon, 12 Sep 2022 17:51:23 +0200 Subject: [PATCH 017/101] make sure exe are copied to root and print command --- CMakeLists.txt | 2 ++ scripts/tests/test_renderer.py | 1 + 2 files changed, 3 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 806f1f3e2a..abcad632f4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -167,6 +167,8 @@ endif() add_executable(IVAS_rend apps/renderer.c) target_link_libraries(IVAS_rend lib_rend lib_util) +set (COPY_EXECUTABLES_TO_ROOT TRUE) + if(COPY_EXECUTABLES_TO_ROOT) # Optionally copy executables to root directory after build add_custom_command(TARGET IVAS_cod POST_BUILD VERBATIM COMMAND "${CMAKE_COMMAND}" -E copy "$" "${CMAKE_CURRENT_SOURCE_DIR}/") diff --git a/scripts/tests/test_renderer.py b/scripts/tests/test_renderer.py index c66a4747d6..88cc770c08 100644 --- a/scripts/tests/test_renderer.py +++ b/scripts/tests/test_renderer.py @@ -161,6 +161,7 @@ def run_renderer( cmd.extend(["-tf", str(trj_file)]) try: + print (' '.join(cmd)) sp.run(cmd, check=True, capture_output=True, text=True) except sp.CalledProcessError as e: pytest.fail( -- GitLab From b3e6e7ffb03d87f129cd3dacda1cb78d9f66d9d7 Mon Sep 17 00:00:00 2001 From: muxe6256 Date: Mon, 26 Sep 2022 14:08:05 +0200 Subject: [PATCH 018/101] correction lfe handling in MC to binaural case, bugs fix --- .gitignore | 7 +- CMakeLists.txt | 8 + apps/renderer.c | 31 +++- lib_com/ivas_cnst.h | 2 + lib_rend/ivas_limiter.c | 12 +- lib_rend/ivas_rom_rend.c | 14 +- lib_rend/ivas_rom_rend.h | 14 +- lib_rend/lib_rend.c | 155 ++++++++---------- lib_rend/lib_rend.h | 3 +- .../unit_tests/crend/ivas_crend_io_parse.h | 2 + .../unit_tests/crend/ivas_crend_unit_test.c | 4 + .../unit_tests/crend/ivas_crend_utest_utils.c | 76 ++++----- .../unit_tests/crend/ivas_dec_parse_io.h | 5 +- scripts/pyaudio3dtools/binauralrenderer.py | 42 +++-- scripts/pyaudio3dtools/spatialaudioconvert.py | 10 +- scripts/tests/constants.py | 53 ++++++ scripts/tests/data/dirac_12ch_48khz.wav | 3 + scripts/tests/test_renderer.py | 63 +++++++ 18 files changed, 325 insertions(+), 179 deletions(-) create mode 100644 scripts/tests/data/dirac_12ch_48khz.wav diff --git a/.gitignore b/.gitignore index 6b784623d5..16832d2879 100644 --- a/.gitignore +++ b/.gitignore @@ -4,18 +4,20 @@ IVAS_cod IVAS_dec IVAS_rend +IVAS_crend_unit_test obj/ *.a *.o *.P # default CMake -build/**/* +build*/**/* # Compiler output VS2017 IVAS_cod.exe IVAS_dec.exe IVAS_rend.exe +IVAS_crend_unit_test.exe *.user .vs/ Debug_*/ @@ -50,3 +52,6 @@ scripts/tests/ref/ __pycache__/ *.py[cod] *$py.class + +#history +.history/ diff --git a/CMakeLists.txt b/CMakeLists.txt index abcad632f4..9c917bd88e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -152,6 +152,13 @@ file(GLOB libUtilSrcs "lib_util/*.c") file(GLOB libUtilHeaders "lib_util/*.h") add_library(lib_util ${libUtilSrcs} ${libUtilHeaders}) +file(GLOB libCRendSrcs "scripts/ivas_pytests/tests/unit_tests/crend/*.c") +file(GLOB libCRendHeaders "scripts/ivas_pytests/tests/unit_tests/crend/*.h") +message(${libCRendSrcs}) +message(${libCRendHeaders}) +add_executable(IVAS_crend_unit_test ${libCRendSrcs} ${libCRendHeaders}) +target_link_libraries(IVAS_crend_unit_test lib_dec lib_rend lib_util lib_com lib_debug) + add_executable(IVAS_cod apps/encoder.c) target_link_libraries(IVAS_cod lib_enc lib_util) if(WIN32) @@ -174,4 +181,5 @@ if(COPY_EXECUTABLES_TO_ROOT) 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}/") + add_custom_command(TARGET IVAS_crend_unit_test POST_BUILD VERBATIM COMMAND "${CMAKE_COMMAND}" -E copy "$" "${CMAKE_CURRENT_SOURCE_DIR}/") endif() \ No newline at end of file diff --git a/apps/renderer.c b/apps/renderer.c index c8d1ee7bd6..5e1f042a70 100644 --- a/apps/renderer.c +++ b/apps/renderer.c @@ -165,6 +165,7 @@ typedef struct CmdlnArgs bool neverDropLfe; /* flag */ bool delayCompensationEnabled; /* flag */ bool quietModeEnabled; + bool lpLfeEnabled; } CmdlnArgs; static int8_t setInConfig( @@ -319,7 +320,7 @@ int32_t main( int32_t argc, char **argv ) AudioFileReader *audioReader = NULL; AudioFileWriter *audioWriter; int16_t inBufferSize; - int32_t outBufferSize; + int16_t outBufferSize; int16_t *inpInt16Buffer; float *inFloatBuffer; int16_t *outInt16Buffer; @@ -414,7 +415,7 @@ int32_t main( int32_t argc, char **argv ) } /* === Configure === */ - if ( ( error = IVAS_REND_Configure( hIvasRend, args.inConfig, args.outConfig, args.sampleRate, args.trajectoryFile[0] != '\0', args.renderConfigFile[0] != '\0' ) ) != IVAS_ERR_OK ) + if ( ( error = IVAS_REND_Configure( hIvasRend, args.inConfig, args.outConfig, args.sampleRate, args.trajectoryFile[0] != '\0', args.renderConfigFile[0] != '\0', args.lpLfeEnabled ) ) != IVAS_ERR_OK ) { exit( -1 ); } @@ -680,7 +681,7 @@ static int8_t setInConfig( AUDIO_CONFIG input_config, IVAS_REND_InputConfig *inC case AUDIO_CONFIG_ISM2: case AUDIO_CONFIG_ISM3: case AUDIO_CONFIG_ISM4: - inConfig->numAudioObjects = input_config - AUDIO_CONFIG_ISM1 + 1; /* TODO(sgi): Don't do arithemtic on enums, find a better way */ + inConfig->numAudioObjects = (uint16_t)input_config - (uint16_t)AUDIO_CONFIG_ISM1 + 1; /* TODO(sgi): Don't do arithemtic on enums, find a better way */ positionProvider->numObjects = inConfig->numAudioObjects; for ( i = 0; i < inConfig->numAudioObjects; ++i ) @@ -1144,6 +1145,7 @@ static CmdlnArgs defaultArgs( void ) args.neverDropLfe = false; args.delayCompensationEnabled = true; args.quietModeEnabled = false; + args.lpLfeEnabled = false; for ( size_t i = 0; i < RENDERER_MAX_ISM_INPUTS; i++ ) { @@ -1168,7 +1170,8 @@ typedef enum CmdLnOptionId_neverDropLfe, CmdLnOptionId_noDelayCmp, CmdLnOptionId_quietModeEnabled, - CmdLnOptionId_inputMetadata, + CmdLnOptionId_lpLfeEnabled, +// CmdLnOptionId_inputMetadata, } CmdLnOptionId; static void parseOption( int32_t optionId, char **optionValues, int16_t numOptionValues, void *pOutputStruct ) @@ -1245,6 +1248,10 @@ static void parseOption( int32_t optionId, char **optionValues, int16_t numOptio assert( numOptionValues == 0 ); args->quietModeEnabled = true; break; + case CmdLnOptionId_lpLfeEnabled: + assert( numOptionValues == 0 ); + args->lpLfeEnabled = true; + break; default: /* Unreachable */ break; @@ -1346,6 +1353,18 @@ static CmdlnArgs parseCmdlnArgs( int32_t argc, char **argv ) .matchShort = "q", .description = "[flag] Limit printouts to terminal", }, + { + .id = CmdLnOptionId_lpLfeEnabled, + .match = "lowpass_lfe", + .matchShort = "lp_lfe", + .description = "[flag] Apply lowpass filter to lfe", + }, + // { /* TODO(sgi): move metadata file paths from input_format to this separate flag */ + // .id = CmdLnOptionId_inputMetadata, + // .match = "input_metadata", + // .matchShort = "im", + // .description = "Space-separated list of path to metadata files for ISM or MASA inputs", + // }, }; CmdlnArgs parsedArgs = defaultArgs(); @@ -1529,7 +1548,7 @@ static void splitConfigFile( const char *mdfFilePath, fprintf( stderr, "Error reading metadata\n" ); exit( -1 ); } - *wavFileNameLength = strlen( wavFileName ); + *wavFileNameLength = (uint32_t)strlen( wavFileName ); mdlength = bufferlength - currentPositionIdxs; /* "+1" for null termination */ @@ -2013,7 +2032,7 @@ void parseConfigFile( char *path, char *audioFilePath, IVAS_REND_InputConfig *in static void convert_backslash( char *str ) { - int i, len; + size_t i, len; /* check that all backslashes are correct on the given platform */ len = strlen( str ); diff --git a/lib_com/ivas_cnst.h b/lib_com/ivas_cnst.h index 223f3fa490..daff91d365 100644 --- a/lib_com/ivas_cnst.h +++ b/lib_com/ivas_cnst.h @@ -196,6 +196,8 @@ typedef enum #define IVAS_MAX_SBA_ORDER 3 /* Maximum supported Ambisonics order */ +#define IVAS_LIMITER_THRESHOLD 32729 /* -0.01 dBFS */ +#define IVAS_LIMITER_ATTACK_SECONDS 0.005f /*----------------------------------------------------------------------------------* * IVAS Bitrates diff --git a/lib_rend/ivas_limiter.c b/lib_rend/ivas_limiter.c index e483318be8..c0ffd7aa4a 100644 --- a/lib_rend/ivas_limiter.c +++ b/lib_rend/ivas_limiter.c @@ -43,10 +43,6 @@ * Local constants *----------------------------------------------------------------------------------*/ -#define LIMITER_THRESHOLD 32729 /* -0.01 dBFS */ -#define LIMITER_ATTACK_SECONDS 0.005f - - /*-------------------------------------------------------------------* * detect_strong_saturations() * @@ -71,11 +67,11 @@ static int16_t detect_strong_saturations( *strong_saturation_cnt = 50; apply_strong_limiting = 1; } - else if ( max_val > 3 * LIMITER_THRESHOLD && *strong_saturation_cnt > 0 ) + else if ( max_val > 3 * IVAS_LIMITER_THRESHOLD && *strong_saturation_cnt > 0 ) { apply_strong_limiting = 1; } - else if ( max_val > 10 * LIMITER_THRESHOLD ) + else if ( max_val > 10 * IVAS_LIMITER_THRESHOLD ) { *strong_saturation_cnt += 20; *strong_saturation_cnt = min( *strong_saturation_cnt, 50 ); @@ -130,7 +126,7 @@ IVAS_LIMITER_HANDLE ivas_limiter_open( hLimiter->sampling_rate = sampling_rate; hLimiter->gain = 1.f; hLimiter->release_heuristic = 0.f; - hLimiter->attack_constant = powf( 0.01f, 1.0f / ( LIMITER_ATTACK_SECONDS * sampling_rate ) ); + 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; @@ -202,7 +198,7 @@ void ivas_limiter_dec( channels[c] = output[c]; } - limiter_process( hLimiter, output_frame, LIMITER_THRESHOLD, BER_detect, &hLimiter->strong_saturation_count ); + limiter_process( hLimiter, output_frame, IVAS_LIMITER_THRESHOLD, BER_detect, &hLimiter->strong_saturation_count ); return; } diff --git a/lib_rend/ivas_rom_rend.c b/lib_rend/ivas_rom_rend.c index dd252a9969..663c25f1cf 100644 --- a/lib_rend/ivas_rom_rend.c +++ b/lib_rend/ivas_rom_rend.c @@ -333,25 +333,25 @@ const float ivas_reverb_default_DSR[IVAS_REVERB_DEFAULT_N_BANDS] = /* CICP1 - Mono */ const float ls_azimuth_CICP1[1] = { 0.0f }; const float ls_elevation_CICP1[1] = { 0.0f }; -const uint32_t ls_LFE_last_idx_CICP1[1] = { 0 }; +const uint16_t ls_LFE_last_idx_CICP1[1] = { 0 }; /* CICP2 - Stereo */ -const uint32_t ls_LFE_last_idx_CICP2[2] = { 0, 1 }; +const uint16_t ls_LFE_last_idx_CICP2[2] = { 0, 1 }; /* CICP6 - 5.1 */ -const uint32_t ls_LFE_last_idx_CICP6[6] = { 0, 1, 2, 4, 5, 3 }; +const uint16_t ls_LFE_last_idx_CICP6[6] = { 0, 1, 2, 4, 5, 3 }; /* CICP12 - 7.1 */ -const uint32_t ls_LFE_last_idx_CICP12[8] = { 0, 1, 2, 4, 5, 6, 7, 3 }; +const uint16_t ls_LFE_last_idx_CICP12[8] = { 0, 1, 2, 4, 5, 6, 7, 3 }; /* CICP14 - 5.1.2 */ -const uint32_t ls_LFE_last_idx_CICP14[8] = { 0, 1, 2, 4, 5, 6, 7, 3 }; +const uint16_t ls_LFE_last_idx_CICP14[8] = { 0, 1, 2, 4, 5, 6, 7, 3 }; /* CICP16 - 5.1.4 */ -const uint32_t ls_LFE_last_idx_CICP16[10] = { 0, 1, 2, 4, 5, 6, 7, 8, 9, 3 }; +const uint16_t ls_LFE_last_idx_CICP16[10] = { 0, 1, 2, 4, 5, 6, 7, 8, 9, 3 }; /* CICP19 - 7.1.4 */ -const uint32_t ls_LFE_last_idx_CICP19[12] = { 0, 1, 2, 4, 5, 6, 7, 8, 9, 10, 11, 3 }; +const uint16_t ls_LFE_last_idx_CICP19[12] = { 0, 1, 2, 4, 5, 6, 7, 8, 9, 10, 11, 3 }; /*----------------------------------------------------------------------------------* * LS Renderer ROM tables diff --git a/lib_rend/ivas_rom_rend.h b/lib_rend/ivas_rom_rend.h index 166e417692..5e2cc14fa1 100644 --- a/lib_rend/ivas_rom_rend.h +++ b/lib_rend/ivas_rom_rend.h @@ -99,13 +99,13 @@ extern const float ivas_reverb_default_DSR[]; extern const float hoa_dec_mtx_CICP1[16]; extern const float ls_azimuth_CICP1[1]; extern const float ls_elevation_CICP1[1]; -extern const uint32_t ls_LFE_last_idx_CICP1[1]; -extern const uint32_t ls_LFE_last_idx_CICP2[2]; -extern const uint32_t ls_LFE_last_idx_CICP6[6]; -extern const uint32_t ls_LFE_last_idx_CICP12[8]; -extern const uint32_t ls_LFE_last_idx_CICP14[8]; -extern const uint32_t ls_LFE_last_idx_CICP16[10]; -extern const uint32_t ls_LFE_last_idx_CICP19[12]; +extern const uint16_t ls_LFE_last_idx_CICP1[1]; +extern const uint16_t ls_LFE_last_idx_CICP2[2]; +extern const uint16_t ls_LFE_last_idx_CICP6[6]; +extern const uint16_t ls_LFE_last_idx_CICP12[8]; +extern const uint16_t ls_LFE_last_idx_CICP14[8]; +extern const uint16_t ls_LFE_last_idx_CICP16[10]; +extern const uint16_t ls_LFE_last_idx_CICP19[12]; /*----------------------------------------------------------------------------------* * LS Configuration Converter ROM tables diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index 9658883460..52f74a05ae 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -46,7 +46,6 @@ #include -#define LIMITER_THRESHOLD ( 0.9988493699f * INT16_MAX ) /* -0.01 dBFS */ /* Due to API of some rendering methods, the renderer has to use the decoder struct. Only struct members relevant for rendering will be initialized, therefore typedef as "dummy" decoder struct */ @@ -257,12 +256,12 @@ static const float *getSpeakerAzimuths( static const float *getSpeakerElevations( IVAS_REND_SpeakerLayout layout ); -static const uint32_t *getReorderedChannelIndices( +static const uint16_t *getReorderedChannelIndices( IVAS_REND_SpeakerLayout layout ); -static int32_t reverseChannelIndexMapping( int32_t originalChannelIndex, - const uint32_t *channelReorderingMap, - uint32_t numNonLfeSpeakers ); +static int16_t reverseChannelIndexMapping( int16_t originalChannelIndex, + const uint16_t *channelReorderingMap, + uint16_t numNonLfeSpeakers ); static ivas_error getHoaRenderMtx( const IVAS_REND_OutputConfig outConfig, @@ -510,7 +509,8 @@ static ivas_error initDecoderDummyForObjToBinaural( DecoderDummy *decDummyObjBin decDummyObjBin->intern_config = AUDIO_CONFIG_7_1_4; ivas_output_init( &decDummyObjBin->hIntSetup, decDummyObjBin->intern_config ); - if ( ( error = ivas_crend_open( decDummyObjBin ) != IVAS_ERR_OK ) ) + error = ivas_crend_open( decDummyObjBin); + if ( error != IVAS_ERR_OK ) { return error; } @@ -603,7 +603,8 @@ ivas_error IVAS_REND_Configure( IVAS_REND_HANDLE st, const IVAS_REND_OutputConfig outConfig, uint32_t sampleRate, bool headRotationEnabled, - bool rendererConfigEnabled ) + bool rendererConfigEnabled, + bool lpLfeEnabled ) { uint32_t i; int32_t j; @@ -634,6 +635,7 @@ ivas_error IVAS_REND_Configure( IVAS_REND_HANDLE st, st->firstFrame = 1; st->inConfig = inConfig; st->outConfig = outConfig; + st->forceBinLfeLpf = lpLfeEnabled; /* Save total number of channels in ambisonics inputs */ st->numInChannelsAmbi = 0; @@ -1024,7 +1026,7 @@ void IVAS_REND_Render( st->hLimiter, outAudio.data, outAudio.config.bufferSize, - LIMITER_THRESHOLD ); + IVAS_LIMITER_THRESHOLD ); if ( st->firstFrame ) { @@ -1280,9 +1282,8 @@ ivas_error IVAS_REND_GetDelay( { if ( st->forceBinLfeLpf ) { - *nSamples = max( - NS2SA( st->sampleRate, (int32_t) ( (float) st->decDummyMcBin->binaural_latency_ns + 0.5f ) ), - NS2SA( st->sampleRate, ivas_lfe_lpf_delay[IVAS_FILTER_ORDER_4 - 3] * 1000000000L ) ); + *nSamples = + NS2SA( st->sampleRate, (int32_t) ( (float) st->decDummyMcBin->binaural_latency_ns + ivas_lfe_lpf_delay[IVAS_FILTER_ORDER_4 - 3] * 1000000000L ) ) ; } else { @@ -1435,13 +1436,13 @@ static void renderChannelsToAmbi( IVAS_REND_HANDLE st, const IVAS_REND_AudioBuffer inAudio, IVAS_REND_AudioBuffer outAudio ) { - const uint32_t *lfeLastIdxs; - uint32_t inMcChannelIdx; - uint32_t numNonLfeInChannels; - uint32_t numInChannels; - uint32_t mcIdx; - uint32_t inChIdx; - uint32_t lfeLastIdx_lsCustom[MAX_OUTPUT_CHANNELS]; + const uint16_t *lfeLastIdxs; + uint16_t inMcChannelIdx; + uint16_t numNonLfeInChannels; + uint16_t numInChannels; + uint16_t mcIdx; + uint16_t inChIdx; + uint16_t lfeLastIdx_lsCustom[MAX_OUTPUT_CHANNELS]; float gain_lin; #ifdef WMOPS @@ -1629,14 +1630,14 @@ static void renderChannelsToChannels( const IVAS_REND_AudioBuffer inAudio, IVAS_REND_AudioBuffer outAudio ) { - const uint32_t *lfeLastIdxs; - uint32_t inMcChannelIdx; - uint32_t numNonLfeInChannels; - uint32_t numInChannels; - uint32_t passThroughIdx; - uint32_t mcIdx; - uint32_t inChIdx; - uint32_t lfeLastIdx_lsCustom[MAX_OUTPUT_CHANNELS]; + const uint16_t *lfeLastIdxs; + uint16_t inMcChannelIdx; + uint16_t numNonLfeInChannels; + uint16_t numInChannels; + uint16_t passThroughIdx; + uint16_t mcIdx; + uint16_t inChIdx; + uint16_t lfeLastIdx_lsCustom[MAX_OUTPUT_CHANNELS]; float gain_lin; #ifdef WMOPS @@ -1902,13 +1903,11 @@ static void renderChannelsToBinaural( int16_t i; int16_t lfeChIdx; int16_t frameLength, subFrameLength; - int16_t binauralDelaySmp, lfeDelaySmp; - int16_t offset; + int16_t delaySmp; uint32_t mcIdx, inMcChannelIdx; int32_t numInChannels; float gain_lin; float tmpBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; - float tmpLfeBuffer[L_FRAME48k_EXT]; #ifdef WMOPS wmops_sub_start( "renderChannelsToBinaural" ); @@ -1952,47 +1951,27 @@ static void renderChannelsToBinaural( } /* TODO tmu : this is always disabled */ - if ( st->forceBinLfeLpf ) + if ( st->inConfig.multiChannelBuses[mcIdx].speakerLayout == IVAS_REND_SPEAKER_LAYOUT_CUSTOM ) { - if ( st->inConfig.multiChannelBuses[mcIdx].speakerLayout == IVAS_REND_SPEAKER_LAYOUT_CUSTOM ) - { - lfeChIdx = st->inConfig.inSetupCustom->lfe_idx[0]; - } - else - { - lfeChIdx = LFE_CHANNEL; - } - set_zero( tmpLfeBuffer, frameLength ); - mvr2r( tmpBuffer[lfeChIdx], tmpLfeBuffer, frameLength ); - - /* Low pass filtering */ - ivas_filter_process( &st->lfeLpFilter, tmpLfeBuffer, frameLength ); + lfeChIdx = st->inConfig.inSetupCustom->lfe_idx[0]; + } + else + { + lfeChIdx = LFE_CHANNEL; + } + if ( st->forceBinLfeLpf ) + { /* Delay adjustment */ - lfeDelaySmp = NS2SA( st->sampleRate, ivas_lfe_lpf_delay[IVAS_FILTER_ORDER_4 - 3] * 1000000000L ); - binauralDelaySmp = NS2SA( st->sampleRate, st->decDummyMcBin->binaural_latency_ns ); - - if ( lfeDelaySmp > binauralDelaySmp ) - { - /* delay binauralised signal */ - offset = lfeDelaySmp - binauralDelaySmp; - for ( i = 0; i < numInChannels; ++i ) - { - if ( i == lfeChIdx ) - { - continue; - } - delay_signal( tmpBuffer[i], frameLength, st->delayOffsetBuffer[i], offset ); - } - } - else if ( lfeDelaySmp < binauralDelaySmp ) + delaySmp = (int16_t) roundf( st->decDummyMcBin->hHrtf->latency_s * st->sampleRate ); + delay_signal( tmpBuffer[lfeChIdx], frameLength, st->delayOffsetBuffer[lfeChIdx], delaySmp); + /* Low pass filtering */ + ivas_filter_process( &st->lfeLpFilter, tmpBuffer[lfeChIdx], frameLength ); + delaySmp = NS2SA( st->sampleRate, ivas_lfe_lpf_delay[IVAS_FILTER_ORDER_4 - 3] * 1000000000L ); + for ( i = 0; i < outAudio.config.numChannels; i++ ) { - /* delay LFE signal */ - offset = binauralDelaySmp - lfeDelaySmp; - delay_signal( tmpLfeBuffer, frameLength, st->delayOffsetBuffer[lfeChIdx], offset ); + delay_signal( tmpBuffer[i], frameLength, st->delayOffsetBuffer[i], delaySmp); } - - mvr2r( tmpLfeBuffer, tmpBuffer[lfeChIdx], frameLength ); } ivas_binaural_add_LFE( st->decDummyMcBin, frameLength, tmpBuffer ); @@ -2404,9 +2383,9 @@ static void prepareLfeHandling( static void prepareMcPanGains( IVAS_REND_HANDLE st ) { - uint32_t mcIdx; - int32_t spkIdx; - int32_t numNonLfeChannelsIn; + uint16_t mcIdx; + uint16_t spkIdx; + uint16_t numNonLfeChannelsIn; const float *spkAzi; const float *spkEle; @@ -2475,7 +2454,7 @@ static void prepareMcPanGains( IVAS_REND_HANDLE st ) int16_t index; int16_t nchan_out; float value; - const uint32_t *lfeLastIdxMap; + const uint16_t *lfeLastIdxMap; const LS_CONVERSION_MATRIX *conversion_matrix; AUDIO_CONFIG input_config, output_config; IVAS_REND_SpeakerLayout spkLayoutIn; @@ -2577,23 +2556,23 @@ static void prepareMcPassthrough( IVAS_REND_HANDLE st ) /* Output config */ const float *outSpkAzi; const float *outSpkEle; - const uint32_t *lfeLastIdxs; - uint32_t numNonLfeOutChannels; - uint32_t numOutChannels; - uint32_t lfeLastIdx_lsCustom[MAX_OUTPUT_CHANNELS]; + const uint16_t *lfeLastIdxs; + uint16_t numNonLfeOutChannels; + uint16_t numOutChannels; + uint16_t lfeLastIdx_lsCustom[MAX_OUTPUT_CHANNELS]; /* Input config */ const float *inSpkAzi; const float *inSpkEle; - uint32_t numInChannels; - uint32_t numNonLfeInChannels; + uint16_t numInChannels; + uint16_t numNonLfeInChannels; /* Input channel index */ - uint32_t passThroughIdx; + uint16_t passThroughIdx; - uint32_t mcIdx; - uint32_t inChIdx; - uint32_t outChIdx; + uint16_t mcIdx; + uint16_t inChIdx; + uint16_t outChIdx; #ifdef WMOPS wmops_sub_start( "prepareMcPassthrough" ); @@ -2746,7 +2725,7 @@ static void getSpeakerGains( const IVAS_REND_HANDLE st, const float ele, float *const spkGains ) { - const uint32_t *lfeLastIdxs; + const uint16_t *lfeLastIdxs; int16_t numNonLfeOutChannels; int16_t noLfeIdx; IVAS_REND_SpeakerLayout speakerLayout; @@ -2933,7 +2912,7 @@ const float *getSpeakerElevations( IVAS_REND_SpeakerLayout layout ) return NULL; } -static const uint32_t *getReorderedChannelIndices( IVAS_REND_SpeakerLayout layout ) +static const uint16_t *getReorderedChannelIndices( IVAS_REND_SpeakerLayout layout ) { switch ( layout ) { @@ -2958,15 +2937,15 @@ static const uint32_t *getReorderedChannelIndices( IVAS_REND_SpeakerLayout layou return NULL; } -static int32_t reverseChannelIndexMapping( int32_t originalChannelIndex, const uint32_t *channelReorderingMap, uint32_t numNonLfeSpeakers ) +static int16_t reverseChannelIndexMapping( int16_t originalChannelIndex, const uint16_t *channelReorderingMap, uint16_t numNonLfeSpeakers ) { - int32_t i; + uint16_t i; - for ( i = 0; i < (int32_t) numNonLfeSpeakers; ++i ) + for ( i = 0; i < numNonLfeSpeakers; ++i ) { - if ( (int32_t) channelReorderingMap[i] == originalChannelIndex ) + if ( channelReorderingMap[i] == (uint16_t)originalChannelIndex ) { - return i; + return (int16_t)i; } } @@ -3043,7 +3022,7 @@ void getHoaDecVecForAmbiChnl( float *decCoeffs ) { - const uint32_t *lfeLastIdxs; + const uint16_t *lfeLastIdxs; int16_t numNonLfeChannels; int16_t nonLfeChIdx; @@ -3124,7 +3103,7 @@ static int32_t ivas_limiter_renderer( channels[i] = output + i * output_frame; } - limiter_process( hLimiter, output_frame, threshold, 0, NULL ); + limiter_process( hLimiter, output_frame, threshold, 0, &hLimiter->strong_saturation_count ); /* Apply clipping to buffer in case the limiter let through some samples > 1.0f */ for ( i = 0; i < output_frame * num_channels; ++i ) diff --git a/lib_rend/lib_rend.h b/lib_rend/lib_rend.h index dfcf0ec57a..191376f8be 100644 --- a/lib_rend/lib_rend.h +++ b/lib_rend/lib_rend.h @@ -184,7 +184,8 @@ ivas_error IVAS_REND_Configure( const IVAS_REND_OutputConfig outConfig, /* i : Output configuration */ uint32_t sampleRate, /* i : Processing sampling rate */ bool headRotationEnabled, /* i : enable head rotation for binaural output, ignored for other output formats */ - bool rendererConfigEnabled /* i : flag indicating if a renderer configuration file was supplied */ + bool rendererConfigEnabled, /* i : flag indicating if a renderer configuration file was supplied */ + bool lpLfeEnabled /* i : flag lowpass filter enabled */ ); void IVAS_REND_SetHeadRotation( diff --git a/scripts/ivas_pytests/tests/unit_tests/crend/ivas_crend_io_parse.h b/scripts/ivas_pytests/tests/unit_tests/crend/ivas_crend_io_parse.h index 21b59ad06f..53a4f452cc 100644 --- a/scripts/ivas_pytests/tests/unit_tests/crend/ivas_crend_io_parse.h +++ b/scripts/ivas_pytests/tests/unit_tests/crend/ivas_crend_io_parse.h @@ -46,6 +46,7 @@ #define IVAS_IN_FMT_510 "510" #define IVAS_IN_FMT_710 "710" #define IVAS_IN_FMT_512 "512" +#define IVAS_IN_FMT_514 "514" #define IVAS_IN_FMT_714 "714" #define IVAS_IN_FMT_FOA "HOA1S" @@ -60,6 +61,7 @@ typedef enum ivas_in_out_fmt_struct_t MULT_CH_5_1, MULT_CH_7_1, MULT_CH_5_1_2, + MULT_CH_5_1_4, MULT_CH_7_1_4, HOA_9, HOA_16, diff --git a/scripts/ivas_pytests/tests/unit_tests/crend/ivas_crend_unit_test.c b/scripts/ivas_pytests/tests/unit_tests/crend/ivas_crend_unit_test.c index b2a24534c0..0e32e634fe 100644 --- a/scripts/ivas_pytests/tests/unit_tests/crend/ivas_crend_unit_test.c +++ b/scripts/ivas_pytests/tests/unit_tests/crend/ivas_crend_unit_test.c @@ -416,6 +416,10 @@ static ivas_result_t ivas_crend_binaural_test( ivas_crend_io_params_t *pIo_param { test_case = "CREND_512_TO_BIN"; } + else if ( pIo_params->in_fmt == MULT_CH_5_1_4 ) + { + test_case = "CREND_514_TO_BIN"; + } else if ( pIo_params->in_fmt == MULT_CH_7_1_4 ) { test_case = "CREND_714_TO_BIN"; diff --git a/scripts/ivas_pytests/tests/unit_tests/crend/ivas_crend_utest_utils.c b/scripts/ivas_pytests/tests/unit_tests/crend/ivas_crend_utest_utils.c index d993405b11..00f00560e7 100644 --- a/scripts/ivas_pytests/tests/unit_tests/crend/ivas_crend_utest_utils.c +++ b/scripts/ivas_pytests/tests/unit_tests/crend/ivas_crend_utest_utils.c @@ -149,6 +149,8 @@ AUDIO_CONFIG ivas_crend_map_out_fmt( return AUDIO_CONFIG_7_1; case MULT_CH_5_1_2: return AUDIO_CONFIG_5_1_2; + case MULT_CH_5_1_4: + return AUDIO_CONFIG_5_1_4; case MULT_CH_7_1_4: return AUDIO_CONFIG_7_1_4; default: @@ -166,6 +168,7 @@ const char *ivas_crend_map_in_fmt( case MULT_CH_5_1: case MULT_CH_7_1: case MULT_CH_5_1_2: + case MULT_CH_5_1_4: case MULT_CH_7_1_4: return IVAS_IN_FMT_COMBINED; case FOA_4: @@ -213,6 +216,9 @@ int16_t ivas_get_num_channels( case MULT_CH_5_1_2: num_channels = 8; break; + case MULT_CH_5_1_4: + num_channels = 10; + break; case MULT_CH_7_1_4: num_channels = 12; break; @@ -561,7 +567,7 @@ ivas_result_t ivas_crend_parse_io_params( int argc, char **argv, ivas_crend_io_p else if ( strcmp( to_upper( argv[i] ), "-IFMT" ) == 0 ) { pIo_params->in_fmt = atoi( argv[++i] ); - if ( ( pIo_params->in_fmt != MONO_1 ) && ( pIo_params->in_fmt != STEREO_2 ) && ( pIo_params->in_fmt != BIN_2 ) && ( pIo_params->in_fmt != FOA_4 ) && ( pIo_params->in_fmt != HOA_9 ) && ( pIo_params->in_fmt != HOA_16 ) && ( pIo_params->in_fmt != MULT_CH_5_1 ) && ( pIo_params->in_fmt != MULT_CH_7_1 ) && ( pIo_params->in_fmt != MULT_CH_5_1_2 ) && ( pIo_params->in_fmt != MULT_CH_7_1_4 ) && ( pIo_params->in_fmt != OBA ) ) + if ( ( pIo_params->in_fmt != MONO_1 ) && ( pIo_params->in_fmt != STEREO_2 ) && ( pIo_params->in_fmt != BIN_2 ) && ( pIo_params->in_fmt != FOA_4 ) && ( pIo_params->in_fmt != HOA_9 ) && ( pIo_params->in_fmt != HOA_16 ) && ( pIo_params->in_fmt != MULT_CH_5_1 ) && ( pIo_params->in_fmt != MULT_CH_7_1 ) && ( pIo_params->in_fmt != MULT_CH_5_1_2 ) && ( pIo_params->in_fmt != MULT_CH_5_1_4 ) && ( pIo_params->in_fmt != MULT_CH_7_1_4 ) && ( pIo_params->in_fmt != OBA ) ) { fprintf( stderr, "Error: Invalid input format\n\n" ); ivas_crend_unit_test_usage(); @@ -575,7 +581,7 @@ ivas_result_t ivas_crend_parse_io_params( int argc, char **argv, ivas_crend_io_p else if ( strcmp( to_upper( argv[i] ), "-OFMT" ) == 0 ) { pIo_params->out_fmt = atoi( argv[++i] ); - if ( ( pIo_params->out_fmt != MONO_1 ) && ( pIo_params->out_fmt != STEREO_2 ) && ( pIo_params->out_fmt != BIN_2 ) && ( pIo_params->out_fmt != FOA_4 ) && ( pIo_params->out_fmt != HOA_9 ) && ( pIo_params->out_fmt != HOA_16 ) && ( pIo_params->out_fmt != MULT_CH_5_1 ) && ( pIo_params->out_fmt != MULT_CH_7_1 ) && ( pIo_params->out_fmt != MULT_CH_5_1_2 ) && ( pIo_params->out_fmt != MULT_CH_7_1_4 ) ) + if ( ( pIo_params->out_fmt != MONO_1 ) && ( pIo_params->out_fmt != STEREO_2 ) && ( pIo_params->out_fmt != BIN_2 ) && ( pIo_params->out_fmt != FOA_4 ) && ( pIo_params->out_fmt != HOA_9 ) && ( pIo_params->out_fmt != HOA_16 ) && ( pIo_params->out_fmt != MULT_CH_5_1 ) && ( pIo_params->out_fmt != MULT_CH_7_1 ) && ( pIo_params->out_fmt != MULT_CH_5_1_2 ) && ( pIo_params->out_fmt != MULT_CH_5_1_4 ) && ( pIo_params->out_fmt != MULT_CH_7_1_4 ) ) { fprintf( stderr, "Error: Invalid output format\n\n" ); ivas_crend_unit_test_usage(); @@ -875,7 +881,7 @@ static ivas_result_t ivas_wrapper_get_in_buf( ivas_crend_io_params_t *pIo_params #endif { ppPcm_in[i][j] = (float) tmp; - ppPcm_in[i][j] *= ( 1.0 / PCM16_TO_FLT_FAC ); + // ppPcm_in[i][j] *= ( 1.0 / PCM16_TO_FLT_FAC ); samples_read += 1; } else @@ -913,7 +919,7 @@ static ivas_result_t ivas_wrapper_get_in_buf( ivas_crend_io_params_t *pIo_params #endif { ppPcm_in[i][j] = (float) tmp; - ppPcm_in[i][j] *= ( 1.0 / PCM16_TO_FLT_FAC ); + // ppPcm_in[i][j] *= ( 1.0 / PCM16_TO_FLT_FAC ); samples_read += 1; } else @@ -999,6 +1005,7 @@ static void ivas_copy_io_params_to_dec_io_params( ivas_crend_io_params_t *pIo_pa case MULT_CH_5_1: case MULT_CH_7_1: case MULT_CH_5_1_2: + case MULT_CH_5_1_4: case MULT_CH_7_1_4: pDec_io_params->lfe_ch_idx = IVAS_DEFAULT_LFE_CH_IDX; break; @@ -1398,36 +1405,24 @@ ivas_result_t ivas_common_mixer_renderer( ivas_crend_io_params_t *pIo_params, fl return IVAS_IO_ERROR; } - if ( pIo_params->lfe_lp_enable ) { - int32_t idx = 0; - for ( i = 0; i < in_ch; i++ ) + /* ADD delay to make overall max(block_offset, 11.5)*/ + if ( st_ivas.hLFE->lfe_addl_delay > 0 ) { - if ( i != lfe_ch_idx ) - { - delay_signal( ppPcm_in[idx], frame_len, ppDelay_lines[idx], delay_lp ); - idx++; - } + delay_signal( ppPcm_in[lfe_ch_idx], frame_len, st_ivas.hLFE->lfe_delay_buf, st_ivas.hLFE->lfe_addl_delay ); } + ivas_filter_process( &st_ivas.hLFE->filter_state, ppPcm_in[lfe_ch_idx], frame_len ); } if ( pIo_params->test == FASTCONV_BIN_TEST ) { ivas_binaural_cldfb( &st_ivas, ppPcm_in ); - for ( i = 0; i < out_ch; i++ ) - { - mvr2r( ppPcm_in[i], ppPcm_out[i], frame_len ); - } } else if ( pIo_params->test == TD_BIN_TEST ) { ObjRenderIVASFrame( &st_ivas, ppPcm_in, frame_len ); - for ( i = 0; i < out_ch; i++ ) - { - mvr2r( ppPcm_in[i], ppPcm_out[i], frame_len ); - } } else if ( pIo_params->test == PARAM_BIN_TEST ) { @@ -1482,11 +1477,6 @@ ivas_result_t ivas_common_mixer_renderer( ivas_crend_io_params_t *pIo_params, fl cldfbSynthesis( &outSlotRePr, &outSlotImPr, &( ppPcm_in[ch][slot_idx * maxBand] ), maxBand, st_ivas.cldfbSynDec[ch] ); } } - - for ( i = 0; i < out_ch; i++ ) - { - mvr2r( ppPcm_in[i], ppPcm_out[i], frame_len ); - } } else @@ -1495,7 +1485,7 @@ ivas_result_t ivas_common_mixer_renderer( ivas_crend_io_params_t *pIo_params, fl { ivas_crend_mixer( ppPcm_in, ppPcm_out, in_ch, out_ch, mixer, frame_len ); } - else + else { ivas_crend_process( &st_ivas, ppPcm_in ); } @@ -1503,19 +1493,12 @@ ivas_result_t ivas_common_mixer_renderer( ivas_crend_io_params_t *pIo_params, fl if ( mixer == NULL ) { - if ( st_ivas.hLFE ) + if ( pIo_params->lfe_lp_enable ) { - /* if ( st_ivas.hLFE->filter_state.order > 0 ) - { - - ivas_filter_process( &st_ivas.hLFE->filter_state, ppPcm_in[lfe_ch_idx], frame_len ); - }*/ - - /* ADD delay to make overall max(block_offset, 11.5)*/ - if ( st_ivas.hLFE->lfe_addl_delay > 0 ) - { - delay_signal( ppPcm_in[lfe_ch_idx], frame_len, st_ivas.hLFE->lfe_delay_buf, st_ivas.hLFE->lfe_addl_delay ); - } + for ( i = 0; i < out_ch; i++ ) + { + delay_signal( ppPcm_in[i], frame_len, ppDelay_lines[i], delay_lp ); + } ivas_binaural_add_LFE( &st_ivas, frame_len, ppPcm_in ); } @@ -1525,7 +1508,7 @@ ivas_result_t ivas_common_mixer_renderer( ivas_crend_io_params_t *pIo_params, fl } if ( pIo_params->limiter_enable ) { - ivas_limiter_dec( st_ivas.hLimiter, ppPcm_out, out_ch, frame_len, FALSE ); + ivas_limiter_dec( st_ivas.hLimiter, ppPcm_out, out_ch, frame_len, 0 ); } } @@ -1540,7 +1523,8 @@ ivas_result_t ivas_common_mixer_renderer( ivas_crend_io_params_t *pIo_params, fl } for ( i = 0; i < out_ch; i++ ) { - float temp = roundf( ppPcm_out[i][j] * PCM16_TO_FLT_FAC ); +// float temp = roundf( ppPcm_out[i][j] * PCM16_TO_FLT_FAC ); + float temp; #ifdef _FIND_MAX_ valMaxLoc = ( ppPcm_out[i][j] > valMaxLoc ) ? ppPcm_out[i][j] : ( ppPcm_out[i][j] < -valMaxLoc ) ? -ppPcm_out[i][j] : valMaxLoc; @@ -1549,9 +1533,10 @@ ivas_result_t ivas_common_mixer_renderer( ivas_crend_io_params_t *pIo_params, fl valMax = valMaxLoc; valEner += ppPcm_out[i][j] * ppPcm_out[i][j]; #endif - pcm[i] = ( temp > MAX16B ) ? MAX16B : ( temp < MIN16B_FLT ) ? MIN16B - : (short) temp; - clip = max( clip, fabs( ppPcm_out[i][j] ) ); + temp = ( ppPcm_out[i][j] > MAX16B_FLT ) ? MAX16B_FLT : ( ppPcm_out[i][j] < MIN16B_FLT ) ? MIN16B_FLT + : ppPcm_out[i][j]; + pcm[i] = (short) roundf(temp); + clip = max( clip, fabsf( ppPcm_out[i][j] ) ); } @@ -1566,7 +1551,7 @@ ivas_result_t ivas_common_mixer_renderer( ivas_crend_io_params_t *pIo_params, fl if ( write_flag == 0 ) skipped_samples++; } - if ( clip > 1.0f ) + if ( clip > MAX16B_FLT ) { fprintf( stdout, "IVAS Common Renderer Clipped: max gain = %f\n", clip ); } @@ -1769,7 +1754,8 @@ ivas_result_t ivas_object_mixer_renderer( ivas_crend_io_params_t *pIo_params, in for ( i = 0; i < out_ch; i++ ) { - float temp = roundf( ppPcm_out[i][j] * PCM16_TO_FLT_FAC ); +// float temp = roundf( ppPcm_out[i][j] * PCM16_TO_FLT_FAC ); + float temp = roundf( ppPcm_out[i][j] ); #ifdef _FIND_MAX_ valMaxLoc = ( ppPcm_out[i][j] > valMaxLoc ) ? ppPcm_out[i][j] : ( ppPcm_out[i][j] < -valMaxLoc ) ? -ppPcm_out[i][j] diff --git a/scripts/ivas_pytests/tests/unit_tests/crend/ivas_dec_parse_io.h b/scripts/ivas_pytests/tests/unit_tests/crend/ivas_dec_parse_io.h index fe05a96f4f..65ed31c930 100644 --- a/scripts/ivas_pytests/tests/unit_tests/crend/ivas_dec_parse_io.h +++ b/scripts/ivas_pytests/tests/unit_tests/crend/ivas_dec_parse_io.h @@ -82,8 +82,9 @@ #define IVAS_IN_FMT_510 "510" #define IVAS_IN_FMT_710 "710" -#define IVAS_IN_FMT_512 "512" -#define IVAS_IN_FMT_714 "714" +#define IVAS_IN_FMT_512 "512" +#define IVAS_IN_FMT_514 "514" +#define IVAS_IN_FMT_714 "714" #define IVAS_IN_FMT_FOA "HOA1S" #define IVAS_IN_FMT_HOA_2 "HOA2S" #define IVAS_IN_FMT_HOA_3 "HOA3S" diff --git a/scripts/pyaudio3dtools/binauralrenderer.py b/scripts/pyaudio3dtools/binauralrenderer.py index 23f476a5fd..fd5501c782 100644 --- a/scripts/pyaudio3dtools/binauralrenderer.py +++ b/scripts/pyaudio3dtools/binauralrenderer.py @@ -88,7 +88,7 @@ def get_IR( in_format: spatialaudioformat.Format, out_format: spatialaudioformat.Format, dataset: str, -) -> Tuple[np.ndarray, np.ndarray]: +) -> Tuple[np.ndarray, np.ndarray, float]: """get_IR Parameters @@ -135,6 +135,8 @@ def get_IR( ) IR, SourcePosition = read_hrirs_from_mat("_".join([prefix, suffix])) + + latency_smp = float(np.min(np.argmax(np.sum(np.abs(IR),axis=(1)),axis=(0)))) if in_format.name.startswith("MONO"): IR = IR[:, :, :1] # use omni/W from SBA @@ -147,8 +149,8 @@ def get_IR( IR = np.zeros([IR_tmp.shape[0], IR_tmp.shape[1], in_format.nchannels]) ir_index = 0 - for i in range(tmpformat.nchannels): - for j in range(in_format.nchannels): + for j in range(in_format.nchannels): + for i in range(tmpformat.nchannels): if ( tmpformat.ls_azi[i] == in_format.ls_azi[j] and tmpformat.ls_ele[i] == in_format.ls_ele[j] @@ -157,7 +159,7 @@ def get_IR( IR[:, :, ir_index] = IR_tmp[:, :, i] ir_index += 1 - return IR, SourcePosition + return IR, SourcePosition, latency_smp def FindFilter(SourcePosition: np.ndarray, azi: float, ele: float) -> int: @@ -509,11 +511,11 @@ def binaural_render_LFE( raise NotImplementedError("Only 48 kHz supported at the moment!") # 3.5ms LP filter delay from IVAS ROM - filter_delay = int(3.5 * fs / 1000) + # filter_delay = int(3.5 * fs / 1000) # delay adjustment - lfe = np.roll(lfe, -filter_delay, axis=0) - lfe[-filter_delay:, :] = 0 + # lfe = np.roll(lfe, -filter_delay, axis=0) + # lfe[-filter_delay:, :] = 0 # apply gain lfe *= LFE_gain @@ -700,12 +702,23 @@ def binaural_rendering( y = audioarray.resample(x, fs, 48000) # get IR corresponding to the input and output formats - IR, SourcePosition = get_IR(in_format, out_format, dataset) - latency_smp = np.argmax(np.sum(np.abs(IR), axis=(1, 2))) + IR, SourcePosition,latency_smp = get_IR(in_format, out_format, dataset) + # latency_smp_test = float(np.argmax(np.sum(np.abs(IR), axis=(1, 2)))) + # if (out_format.name == 'BINAURAL_ROOM') and (data,axis=(1)set == 'orange53'): + # latency_smp = latency_smp - 7; + latency_ns = latency_smp / float(fs) * 1000000000.0 # prepare LFE signal to be added to output + lfe_delay = 0; + lfe_delay_ns = 0; if include_LFE and in_format.isloudspeaker: lfe = binaural_render_LFE(x, 48000, in_format.lfe_index, LFE_gain) + # 3.5ms LP filter delay from IVAS ROM + lfe_delay_ns = 0.0035 * 1000000000.0 + lfe_delay = round(lfe_delay_ns * fs / 1000000000.0) + lfe = np.roll(lfe, round(latency_smp), axis=0) + lfe[0:round(latency_smp), :] = 0 + # get binauralized signal based on format if in_format.name.startswith("CUSTOM_LS"): @@ -730,9 +743,12 @@ def binaural_rendering( f"{in_format.name} -> {out_format.name}: format conversion not implemented" ) - # HRTF delay compensation - y = np.roll(y, -latency_smp, axis=0) - y[-latency_smp:, :] = 0 + if include_LFE and in_format.isloudspeaker: + # HRTF delay compensation + # y = np.roll(y, -latency_smp, axis=0) + # y[-latency_smp:, :] = 0 + y = np.roll(y, lfe_delay, axis=0) + y[0:lfe_delay, :] = 0 # add LFE signal to output if include_LFE and in_format.isloudspeaker: @@ -741,4 +757,4 @@ def binaural_rendering( # resample back to original rate y = audioarray.resample(y, 48000, fs) - return y + return y,lfe_delay_ns + latency_ns diff --git a/scripts/pyaudio3dtools/spatialaudioconvert.py b/scripts/pyaudio3dtools/spatialaudioconvert.py index 28f9298924..4bab33a0ff 100644 --- a/scripts/pyaudio3dtools/spatialaudioconvert.py +++ b/scripts/pyaudio3dtools/spatialaudioconvert.py @@ -53,6 +53,8 @@ main_logger = logging.getLogger("__main__") logger = main_logger.getChild(__name__) logger.setLevel(logging.DEBUG) +def NS2SA( fs, x ): + return (int(int( fs / 100 ) * ( ( x ) / 100 ) / 100000 )) def spatial_audio_convert( in_file: str, @@ -239,6 +241,7 @@ def spatial_audio_convert( """ Spatial audio format conversion """ out_sig = in_sig + delay = 0 if (in_spfmt.name != out_spfmt.name) and not ( in_spfmt.isheadphones and out_spfmt.isheadphones ): @@ -248,7 +251,7 @@ def spatial_audio_convert( if out_spfmt.name.startswith("BINAURAL") and not in_spfmt.name.startswith( "MASA" ): - out_sig = binauralrenderer.binaural_rendering( + out_sig,delay_ns = binauralrenderer.binaural_rendering( in_sig, in_spfmt, out_spfmt, @@ -306,6 +309,11 @@ def spatial_audio_convert( ) out_sig *= scale_factor + + delay = NS2SA(out_fs, int(delay_ns)) + out_sig = np.roll(out_sig, -delay, axis=0) + out_sig[-delay:, :] = 0 + audiofile.writefile(out_file, out_sig, out_fs) return out_sig, out_fs diff --git a/scripts/tests/constants.py b/scripts/tests/constants.py index 7893bedd61..897d1aeee8 100644 --- a/scripts/tests/constants.py +++ b/scripts/tests/constants.py @@ -53,9 +53,30 @@ RENDERER_CMD = [ "48", # 10 -> input fs # "--no_delay_cmp", # "-ndl", + "-lp_lfe", "-q", ] +""" Renderer crend commandline template """ +RENDERER_CREND_CMD = [ + str(TESTS_DIR.parent.parent.joinpath("IVAS_crend_unit_test")), + "-test", + "1", + "-sr", + "48", + "-ifmt", + "", # 4 -> input format + "-ofmt", + "", # 8 -> output format + "-i", + "", # 2 -> input file + "-o", + "/dev/null", # 6 -> output file + "-lp_lfe", + "-limiter" + # "-no_delay_cmp" +] + """ Format to file mappings """ NCHAN_TO_FILE = { 1: TEST_VECTOR_DIR.joinpath("spectral_test_1ch_48kHz.wav"), @@ -68,6 +89,7 @@ NCHAN_TO_FILE = { 9: TEST_VECTOR_DIR.joinpath("spectral_test_9ch_48kHz.wav"), 10: TEST_VECTOR_DIR.joinpath("spectral_test_10ch_48kHz.wav"), 11: TEST_VECTOR_DIR.joinpath("spectral_test_11ch_48kHz.wav"), + # 12: TEST_VECTOR_DIR.joinpath("dirac_12ch_48kHz.wav"), 12: TEST_VECTOR_DIR.joinpath("spectral_test_12ch_48kHz.wav"), 15: TEST_VECTOR_DIR.joinpath("spectral_test_15ch_48kHz.wav"), 16: TEST_VECTOR_DIR.joinpath("spectral_test_16ch_48kHz.wav"), @@ -185,3 +207,34 @@ HR_TRAJECTORIES_TO_TEST = [ "full_circle_in_15s-Euler", "rotate_yaw_pitch_roll1", ] + + +def FORMAT_2_CREND_FORMAT( + in_fmt +) : + if in_fmt == "MONO": + return "0" + if in_fmt == "STEREO": + return "1" + if in_fmt == "BINAURAL": + return "2" + if in_fmt == "BINAURAL_ROOM": + return "2" + if in_fmt == "FOA": + return "3" + if in_fmt == "5_1": + return "4" + if in_fmt == "7_1": + return "5" + if in_fmt == "5_1_2": + return "6" + if in_fmt == "5_1_4": + return "7" + if in_fmt == "7_1_4": + return "8" + if in_fmt == "HOA2": + return "9" + if in_fmt == "HOA3": + return "10" + + return "" \ No newline at end of file diff --git a/scripts/tests/data/dirac_12ch_48khz.wav b/scripts/tests/data/dirac_12ch_48khz.wav new file mode 100644 index 0000000000..49a781a4b0 --- /dev/null +++ b/scripts/tests/data/dirac_12ch_48khz.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:880a478b7b6001dff4570e38a8a1928e0d78a78d223f49555e9023598e5ee4fb +size 13824068 diff --git a/scripts/tests/test_renderer.py b/scripts/tests/test_renderer.py index 88cc770c08..4f26e5b913 100644 --- a/scripts/tests/test_renderer.py +++ b/scripts/tests/test_renderer.py @@ -170,6 +170,59 @@ def run_renderer( return pyaudio3dtools.audiofile.readfile(out_file) +def run_renderer_crend( + in_fmt: str, + out_fmt: str, + metadata_input: Optional[str] = None, + in_meta_files: Optional[list] = None, + trj_file: Optional[str] = None, +) -> Tuple[np.ndarray, int]: + """CuT creation with standalone renderer""" + if trj_file is not None: + trj_name = f"_{trj_file.stem}" + else: + trj_name = "" + + if not isinstance(out_fmt, str): + out_name = f"{out_fmt.stem}" + else: + out_name = out_fmt + + if metadata_input is not None: + in_file = metadata_input + in_name = metadata_input.stem + elif not isinstance(in_fmt, str): + in_file = FORMAT_TO_FILE[in_fmt.stem] + in_name = in_fmt.stem + else: + in_file = FORMAT_TO_FILE[in_fmt] + in_name = in_fmt + + out_file = str(OUTPUT_PATH_CUT.joinpath(f"{in_name}_to_{out_name}{trj_name}_crend.wav")) + + cmd = RENDERER_CREND_CMD[:] + cmd[6] = FORMAT_2_CREND_FORMAT(str(in_fmt)) + cmd[8] = FORMAT_2_CREND_FORMAT(str(out_fmt)) + cmd[10] = str(in_file) + cmd[12] = str(out_file) + if (str(out_fmt)=="BINAURAL_ROOM"): + cmd.append("-BRIR") + + + # if in_meta_files is not None: + # cmd[5:5] = in_meta_files + + # if trj_file is not None: + # cmd.extend(["-tf", str(trj_file)]) + + try: + sp.run(cmd, check=True, capture_output=True, text=True) + except sp.CalledProcessError as e: + pytest.fail( + f"Command returned non-zero exit status ({e.returncode})!\n{' '.join(e.cmd)}\n{e.stderr}\n{e.stdout}\n{e.output}" + ) + + return pyaudio3dtools.audiofile.readfile(out_file) # fixture returns test information, enabling per-testcase SNR @pytest.fixture @@ -338,6 +391,16 @@ def test_multichannel_binaural_static(test_info, in_fmt, out_fmt): check_BE(test_info, ref, ref_fs, cut, cut_fs) +@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL) +@pytest.mark.parametrize("in_fmt", INPUT_FORMATS_MC[2:]) +def test_multichannel_binaural_static_vs_crend_unitest(test_info, in_fmt, out_fmt): + + cut, cut_fs = run_renderer(in_fmt, out_fmt) + + crend, crend_fs = run_renderer_crend(in_fmt, out_fmt) + + check_BE(test_info, cut, cut_fs, crend, crend_fs) + # Binaural rendering (head rotation) @pytest.mark.parametrize("trj_file", HR_TRAJECTORIES_TO_TEST) -- GitLab From b5803bdf2a1a6f12d97ff3e9708373cdd01b2257 Mon Sep 17 00:00:00 2001 From: Archit Tamarapu Date: Tue, 4 Oct 2022 18:19:13 +0200 Subject: [PATCH 019/101] Revert "Merge branch 'main' of forge.3gpp.org:ivas-codec-pc/ivas-codec into FhG/external-renderer" This reverts commit de89fb6c4ea9609b5b34d5d3daab5bd7cfe81478, reversing changes made to a94ea3b837207440cb977eb87b5d50026293a1bb. --- .gitignore | 3 - .gitlab-ci.yml | 344 ++------- apps/decoder.c | 8 +- apps/encoder.c | 2 +- ci/check_for_warnings.py | 2 +- ci/run_evs_be_test.py | 76 -- ci/run_scheduled_sanitizer_test.py | 130 ---- lib_com/bitstream.c | 53 +- lib_com/cnst.h | 3 +- lib_com/ivas_cnst.h | 42 +- lib_com/ivas_dirac_com.c | 48 +- lib_com/ivas_entropy_coder_common.c | 0 lib_com/ivas_fb_mixer.c | 4 +- lib_com/ivas_mdft_imdft.c | 0 lib_com/ivas_prot.h | 180 ++--- lib_com/ivas_rom_com.c | 34 +- lib_com/ivas_sba_config.c | 39 +- lib_com/ivas_sns_com.c | 4 +- lib_com/ivas_spar_com.c | 43 +- lib_com/ivas_spar_com_quant_util.c | 78 +- lib_com/ivas_stat_com.h | 4 +- lib_com/ivas_stereo_dft_com.c | 4 - lib_com/ivas_stereo_mdct_stereo_com.c | 2 +- lib_com/ivas_stereo_psychlpc_com.c | 5 +- lib_com/ivas_tools.c | 4 - lib_com/options.h | 23 +- lib_com/prot.h | 51 +- lib_debug/sba_debug.c | 0 lib_dec/acelp_core_dec.c | 12 +- lib_dec/acelp_core_switch_dec.c | 2 +- lib_dec/amr_wb_dec.c | 2 +- lib_dec/core_dec_init.c | 7 +- lib_dec/core_dec_switch.c | 6 +- lib_dec/core_switching_dec.c | 4 - lib_dec/dec_LPD.c | 4 +- lib_dec/dec_acelp_tcx_main.c | 2 +- lib_dec/dec_prm.c | 6 +- lib_dec/dec_tcx.c | 69 +- lib_dec/er_dec_tcx.c | 73 +- lib_dec/evs_dec.c | 2 +- lib_dec/fd_cng_dec.c | 94 ++- lib_dec/igf_dec.c | 54 -- lib_dec/init_dec.c | 6 +- lib_dec/ivas_core_dec.c | 21 +- lib_dec/ivas_cpe_dec.c | 50 +- lib_dec/ivas_dec.c | 17 +- lib_dec/ivas_dirac_dec.c | 87 +-- lib_dec/ivas_init_dec.c | 214 +++--- lib_dec/ivas_ism_metadata_dec.c | 8 - lib_dec/ivas_ism_param_dec.c | 8 - lib_dec/ivas_masa_dec.c | 32 - lib_dec/ivas_mc_param_dec.c | 2 +- lib_dec/ivas_mct_dec_mct.c | 4 - lib_dec/ivas_mdct_core_dec.c | 66 +- lib_dec/ivas_out_setup_conversion.c | 4 + lib_dec/ivas_qmetadata_dec.c | 35 +- lib_dec/ivas_sba_dec.c | 460 +---------- lib_dec/ivas_sce_dec.c | 14 +- lib_dec/ivas_spar_decoder.c | 48 +- lib_dec/ivas_spar_md_dec.c | 722 ++++++++++-------- lib_dec/ivas_stat_dec.h | 41 +- lib_dec/ivas_stereo_cng_dec.c | 20 - lib_dec/ivas_stereo_dft_dec.c | 40 - lib_dec/ivas_stereo_mdct_core_dec.c | 40 +- lib_dec/ivas_stereo_mdct_stereo_dec.c | 22 +- lib_dec/ivas_stereo_switching_dec.c | 32 +- lib_dec/ivas_tcx_core_dec.c | 12 +- lib_dec/lib_dec.c | 116 +-- lib_dec/stat_dec.h | 5 +- lib_dec/swb_tbe_dec.c | 11 +- lib_dec/tonalMDCTconcealment.c | 123 +-- lib_enc/bw_detect.c | 1 + lib_enc/enc_prm.c | 6 +- lib_enc/fd_cng_enc.c | 36 +- lib_enc/igf_enc.c | 6 +- lib_enc/ivas_agc_enc.c | 10 +- lib_enc/ivas_cpe_enc.c | 27 +- lib_enc/ivas_dirac_enc.c | 34 +- lib_enc/ivas_enc.c | 0 lib_enc/ivas_init_enc.c | 108 ++- lib_enc/ivas_ism_enc.c | 4 - lib_enc/ivas_masa_enc.c | 4 +- lib_enc/ivas_mcmasa_enc.c | 4 +- lib_enc/ivas_mct_core_enc.c | 0 lib_enc/ivas_mct_enc.c | 42 +- lib_enc/ivas_mct_enc_mct.c | 9 - lib_enc/ivas_mdct_core_enc.c | 6 +- lib_enc/ivas_qmetadata_enc.c | 59 +- lib_enc/ivas_rom_enc.c | 154 ++++ lib_enc/ivas_rom_enc.h | 5 + lib_enc/ivas_sba_enc.c | 43 +- lib_enc/ivas_sce_enc.c | 16 +- lib_enc/ivas_sns_enc.c | 2 +- lib_enc/ivas_spar_encoder.c | 66 +- lib_enc/ivas_spar_md_enc.c | 544 ++++++++----- lib_enc/ivas_stat_enc.h | 8 +- lib_enc/ivas_stereo_cng_enc.c | 9 - lib_enc/ivas_stereo_dft_enc.c | 16 +- lib_enc/ivas_stereo_dft_enc_itd.c | 15 + lib_enc/ivas_stereo_dmx_evs.c | 61 +- lib_enc/ivas_stereo_mdct_core_enc.c | 9 - lib_enc/ivas_stereo_switching_enc.c | 15 +- lib_enc/ivas_tcx_core_enc.c | 2 +- lib_enc/lib_enc.c | 244 +++--- lib_enc/tcx_utils_enc.c | 4 - lib_rend/ivas_crend.c | 14 - lib_rend/ivas_hrtf.c | 4 +- lib_rend/ivas_objectRenderer.c | 236 +----- lib_rend/ivas_objectRenderer_hrFilt.c | 44 +- lib_rend/ivas_objectRenderer_mix.c | 9 +- lib_rend/ivas_objectRenderer_sfx.c | 47 +- lib_rend/ivas_objectRenderer_sources.c | 12 +- lib_rend/ivas_output_init.c | 38 +- lib_rend/ivas_reverb.c | 7 - lib_util/hrtf_file_reader.c | 3 +- pytest.ini | 9 +- readme.txt | 2 +- scripts/IvasBuildAndRunChecks.py | 25 +- scripts/config/ci_linux.json | 2 +- scripts/config/self_test.prm | 8 - {tests => scripts/ivas_pytests}/conftest.py | 231 ++---- scripts/ivas_pytests/self_test_b.py | 273 +++++++ .../ivas_pytests/tests}/cmp_custom.py | 92 ++- .../ivas_pytests/tests}/cut_pcm.py | 6 +- scripts/ivas_pytests/tests/il2mm.py | 61 ++ scripts/ivas_pytests/tests/requirements.txt | 4 + .../system_tests/test_spar_foa_bs_dec_plc.py | 180 +++++ .../system_tests/test_spar_foa_bs_enc.py | 214 +++--- .../unit_tests/crend/ivas_crend_io_parse.h | 4 +- .../unit_tests/crend/ivas_dec_parse_io.h | 30 +- scripts/pyivastest/IvasModeRunner.py | 2 +- scripts/self_test.py | 20 +- scripts/tools/Darwin/networkSimulator_g192 | Bin 154584 -> 0 bytes scripts/tools/Win32/networkSimulator_g192.exe | 3 - tests/README.md | 173 ----- tests/create_short_testvectors.py | 66 -- tests/prepare_pytests.py | 132 ---- tests/requirements.txt | 4 - tests/run_pytests.py | 106 --- tests/test_param_file.py | 460 ----------- tests/test_sba_bs_dec_plc.py | 189 ----- tests/testconfig.py | 37 - 142 files changed, 2945 insertions(+), 5154 deletions(-) mode change 100644 => 100755 apps/encoder.c delete mode 100755 ci/run_evs_be_test.py delete mode 100644 ci/run_scheduled_sanitizer_test.py mode change 100644 => 100755 lib_com/bitstream.c mode change 100644 => 100755 lib_com/ivas_entropy_coder_common.c mode change 100644 => 100755 lib_com/ivas_mdft_imdft.c mode change 100644 => 100755 lib_com/ivas_spar_com.c mode change 100755 => 100644 lib_com/prot.h mode change 100644 => 100755 lib_debug/sba_debug.c mode change 100644 => 100755 lib_dec/acelp_core_dec.c mode change 100644 => 100755 lib_dec/evs_dec.c mode change 100644 => 100755 lib_dec/ivas_core_dec.c mode change 100644 => 100755 lib_dec/ivas_dirac_dec.c mode change 100644 => 100755 lib_dec/ivas_init_dec.c mode change 100644 => 100755 lib_dec/ivas_spar_decoder.c mode change 100644 => 100755 lib_dec/ivas_stereo_switching_dec.c mode change 100644 => 100755 lib_dec/lib_dec.c mode change 100644 => 100755 lib_dec/swb_tbe_dec.c mode change 100755 => 100644 lib_enc/igf_enc.c mode change 100644 => 100755 lib_enc/ivas_enc.c mode change 100644 => 100755 lib_enc/ivas_mct_core_enc.c mode change 100755 => 100644 lib_enc/ivas_mct_enc_mct.c mode change 100644 => 100755 lib_enc/ivas_stereo_dft_enc_itd.c mode change 100644 => 100755 lib_enc/lib_enc.c mode change 100755 => 100644 lib_enc/tcx_utils_enc.c rename {tests => scripts/ivas_pytests}/conftest.py (57%) create mode 100755 scripts/ivas_pytests/self_test_b.py rename {tests => scripts/ivas_pytests/tests}/cmp_custom.py (62%) mode change 100755 => 100644 rename {tests => scripts/ivas_pytests/tests}/cut_pcm.py (99%) create mode 100644 scripts/ivas_pytests/tests/il2mm.py create mode 100644 scripts/ivas_pytests/tests/requirements.txt create mode 100644 scripts/ivas_pytests/tests/system_tests/test_spar_foa_bs_dec_plc.py rename tests/test_sba_bs_enc.py => scripts/ivas_pytests/tests/system_tests/test_spar_foa_bs_enc.py (71%) delete mode 100755 scripts/tools/Darwin/networkSimulator_g192 delete mode 100755 scripts/tools/Win32/networkSimulator_g192.exe delete mode 100644 tests/README.md delete mode 100755 tests/create_short_testvectors.py delete mode 100755 tests/prepare_pytests.py delete mode 100644 tests/requirements.txt delete mode 100755 tests/run_pytests.py delete mode 100644 tests/test_param_file.py delete mode 100644 tests/test_sba_bs_dec_plc.py delete mode 100644 tests/testconfig.py diff --git a/.gitignore b/.gitignore index 23179ca444..6b784623d5 100644 --- a/.gitignore +++ b/.gitignore @@ -42,12 +42,9 @@ scripts/c-code_instrument/ scripts/ifdef_instrument.list scripts/ref/ scripts/test/ -scripts/out/ scripts/self_test_summary.txt scripts/tests/cut/ scripts/tests/ref/ -tests/dut -tests/ref # Python files that pop up when running scripts __pycache__/ diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 62ee3cfdc3..6e279c76b0 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,13 +1,6 @@ variables: TESTV_DIR: "/usr/local/testv" BUILD_OUTPUT: "build_output.txt" - EVS_BE_TEST_DIR: "/usr/local/be_2_evs_test" - SANITIZER_TESTS: "CLANG1 CLANG2" - OUT_FORMATS_CHANNEL_BASED: "stereo mono 5_1 5_1_2 5_1_4 7_1 7_1_4" - OUT_FORMATS_SCENE_BASED: "FOA HOA2 HOA3" - OUT_FORMATS_BINAURAL: "BINAURAL BINAURAL_ROOM" - EXIT_CODE_NON_BE: 123 - EXIT_CODE_FAIL: 1 # This sets when pipelines are created. Jobs have more specific rules to restrict them. @@ -20,6 +13,7 @@ workflow: - if: $CI_PIPELINE_SOURCE == 'push' && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH # Pushes to main - if: $CI_PIPELINE_SOURCE == 'schedule' && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH # Scheduled in main + stages: - maintenance - build @@ -57,8 +51,6 @@ stages: 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 - when: on_success .rules-merge-request: @@ -214,12 +206,6 @@ msan-on-merge-request-linux: - python3 scripts/self_test.py --create | tee test_output.txt - run_errors=$(cat test_output.txt | grep -ic "run errors") || true - if [ $run_errors != 0 ] ; then echo "Run errors in self_test.py with Clang memory-sanitizer"; exit 1; fi - artifacts: - name: "mr-$CI_MERGE_REQUEST_IID--sha-$CI_COMMIT_SHORT_SHA--stage-$CI_JOB_STAGE--results" - paths: - - scripts/ref/logs/ - - test_output.txt - expose_as: 'Msan selftest results' # code selftest testvectors with address-sanitizer binaries @@ -236,12 +222,6 @@ asan-on-merge-request-linux: - python3 scripts/self_test.py --create | tee test_output.txt - run_errors=$(cat test_output.txt | grep -ic "run errors") || true - if [ $run_errors != 0 ] ; then echo "Run errors in self_test.py with Clang address-sanitizer"; exit 1; fi - artifacts: - name: "mr-$CI_MERGE_REQUEST_IID--sha-$CI_COMMIT_SHORT_SHA--stage-$CI_JOB_STAGE--results" - paths: - - scripts/ref/logs/ - - test_output.txt - expose_as: 'Asan selftest results' # test external renderer executable external-renderer-make-pytest: @@ -281,7 +261,7 @@ external-renderer-cmake-msan-pytest: - python3 -m pytest scripts/tests/test_renderer.py -q --log-level ERROR -n auto # compare bit exactness between target and source branch -pytest-on-merge-request: +self-test-on-merge-request: extends: - .test-job-linux - .rules-merge-request @@ -323,53 +303,40 @@ pytest-on-merge-request: - mv IVAS_dec ../IVAS_dec_ref - cd .. - ### re-checkout the commit from the source branch to have up-to-date test scripts and test vectors (and actually everything) + ### re-checkout the commit from the source branch to have up-to-date self_test.py and scripts/testv (and actually everything) - git checkout $source_branch_commit_sha - # some helper variables - "|| true" to prevent failures from grep not finding anything - - evs_non_be_flag=$(echo $CI_MERGE_REQUEST_TITLE | grep -c --ignore-case "\[evs[ -]*non[ -]*be\]") || true - - non_be_flag=$(echo $CI_MERGE_REQUEST_TITLE | grep -c --ignore-case "\[non[ -]*be\]") || true - - expected_nonbe_1=0 - - expected_nonbe_2=0 - - fail_1=0 - - fail_2=0 - - ### prepare pytest - # create short test vectors - - python3 tests/create_short_testvectors.py - # rename test binaries back - - mv IVAS_cod_test IVAS_cod - - mv IVAS_dec_test IVAS_dec - # create references - - python3 -m pytest tests -v --update_ref 1 -m create_ref - - python3 -m pytest tests -v --update_ref 1 -m create_ref_part2 - - python3 -m pytest tests/test_param_file.py -v --update_ref 1 -m create_ref --param_file scripts/config/self_test_evs.prm - - ### run pytest - - exit_code=0 - - python3 -m pytest tests -v --junit-xml=report-junit.xml || exit_code=$? - - zero_errors=$(cat report-junit.xml | grep -c 'errors="0"') || true - - - if [ $zero_errors != 1 ]; then echo "Run errors in pytest"; fail_1=1; fi + ### run selftest + - ls -altr scripts/testv + - python3 ./scripts/self_test.py --encref IVAS_cod_ref --decref IVAS_dec_ref --enctest IVAS_cod_test --dectest IVAS_dec_test | tee test_output.txt - - if [ $exit_code -eq 1 ] && [ $non_be_flag == 0 ]; then echo "pytest run had failures without non-BE tag encountered"; fail_1=1; fi - - if [ $exit_code -eq 1 ] && [ $non_be_flag != 0 ]; then echo "pytest run had failures with non-BE tag encountered"; expected_nonbe_1=1; fi + ### analyse test output - ### run pytest for EVS cases - - exit_code=0 - - python3 -m pytest tests/test_param_file.py -v --param_file scripts/config/self_test_evs.prm --junit-xml=report-junit-evs.xml || exit_code=$? - - zero_errors=$(cat report-junit-evs.xml | grep -c 'errors="0"') || true + # some helper variables - "|| true" to prevent failures from grep not finding anything + - non_be_flag=$(echo $CI_MERGE_REQUEST_TITLE | grep -c --ignore-case "\[non[ -]*be\]") || true + - run_errors=$(cat test_output.txt | grep -c "test conditions had run errors") || true + - bitexact=$(cat test_output.txt | grep -c "All [0-9]* tests are bitexact") || true + - EXIT_CODE_NON_BE=123 + - EXIT_CODE_FAIL=1 - - if [ $zero_errors != 1 ]; then echo "Run errors in pytest for EVS"; fail_2=1; fi + - selftest_exit_code=0 - - if [ $exit_code -eq 1 ] && [ $evs_non_be_flag == 0 ]; then echo "Non-bitexact EVS cases without EVS-non-BE tag encountered"; fail_2=1; fi - - if [ $exit_code -eq 1 ] && [ $evs_non_be_flag != 0 ]; then echo "Non-bitexact EVS cases with EVS-non-BE tag encountered"; expected_nonbe_2=1; fi + # check for crashes during the test, if any happened, fail the test + - if [ $run_errors != 0 ] ; then echo "Run errors in self_test.py"; exit $EXIT_CODE_FAIL; fi - # Check results from both tests - - if [ $fail_1 -eq 1 ] || [ $fail_2 -eq 1 ]; then exit $EXIT_CODE_FAIL; fi - - if [ $expected_nonbe_1 -eq 1 ] || [ $expected_nonbe_2 -eq 1 ]; then exit $EXIT_CODE_NON_BE; fi - - exit 0 + # check for non bitexact output and store exit code to also always run the SBA pytest + - if [ $bitexact == 0 ] && [ $non_be_flag == 0 ] ; then echo "Non-bitexact cases without non-BE tag encountered"; selftest_exit_code=$EXIT_CODE_FAIL; fi + - if [ $bitexact == 0 ] && [ $non_be_flag != 0 ]; then echo "Non-bitexact cases with non-BE tag encountered"; selftest_exit_code=$EXIT_CODE_NON_BE; fi + ### run SBA pytest + - exit_code=0 + - python3 ./scripts/ivas_pytests/self_test_b.py --encref IVAS_cod_ref --decref IVAS_dec_ref --encdut IVAS_cod_test --decdut IVAS_dec_test || exit_code=$? + - if [ $exit_code -eq 1 ] && [ $non_be_flag == 0 ]; then echo "pytest run had failures and non-BE flag not present"; exit $EXIT_CODE_FAIL; fi + - zero_errors=$(cat report-junit.xml | grep -c 'errors="0"') || true + - if [ $exit_code -eq 1 ] && [ $zero_errors == 1 ]; then echo "pytest run had failures, but no errors and non-BE flag present"; exit $EXIT_CODE_NON_BE; fi + - if [ $exit_code -ne 0 ]; then echo "pytest run had errors"; exit $EXIT_CODE_FAIL; fi; + # return exit code from selftest if everything went well with the pytest run + - exit $selftest_exit_code allow_failure: exit_codes: - 123 @@ -377,47 +344,19 @@ pytest-on-merge-request: name: "mr-$CI_MERGE_REQUEST_IID--sha-$CI_COMMIT_SHORT_SHA--stage-$CI_JOB_STAGE--results" when: always paths: + - test_output.txt + - scripts/test/logs/ + - scripts/ref/logs/ - report-junit.xml - - report-junit-evs.xml - expose_as: 'pytest results' + expose_as: 'Self test results' reports: - junit: - - report-junit.xml - - report-junit-evs.xml + junit: report-junit.xml # --------------------------------------------------------------- # Test jobs for main branch # --------------------------------------------------------------- -# check bitexactness to EVS -be-2-evs-linux: - extends: - - .test-job-linux - - .rules-main-push - tags: - - be-2-evs-temp - stage: test - needs: [ "build-codec-linux-cmake" ] - timeout: "20 minutes" # To be revisited - script: - - *print-common-info - - - mkdir build - - cd build - - cmake .. - - make -j - - cd .. - - # copy over to never change the testvector dir - - cp -r $EVS_BE_TEST_DIR ./evs_be_test - - cp build/IVAS_cod ./evs_be_test/bin/EVS_cod - - cp build/IVAS_dec ./evs_be_test/bin/EVS_dec - - - cd evs_be_test - - python3 ../ci/run_evs_be_test.py - - codec-comparison-on-main-push: extends: - .test-job-linux @@ -460,26 +399,37 @@ codec-comparison-on-main-push: ### re-checkout the latest commit in the main branch - git checkout $latest_commit - # helper variable - "|| true" to prevent failures from grep not finding anything + ### run selftest + - ls -altr scripts/testv + - python3 ./scripts/self_test.py --encref IVAS_cod_ref --decref IVAS_dec_ref --enctest IVAS_cod_test --dectest IVAS_dec_test | tee test_output.txt + + ### analyse test output + + # some helper variables - "|| true" to prevent failures from grep not finding anything - non_be_flag=$(echo $CI_MERGE_REQUEST_TITLE | grep -c --ignore-case "\[non[ -]*be\]") || true + - run_errors=$(cat test_output.txt | grep -c "test conditions had run errors") || true + - bitexact=$(cat test_output.txt | grep -c "All [0-9]* tests are bitexact") || true + - EXIT_CODE_NON_BE=123 + - EXIT_CODE_FAIL=1 + + - selftest_exit_code=0 + + # check for crashes during the test, if any happened, fail the test + - if [ $run_errors != 0 ] ; then echo "Run errors in self_test.py"; exit $EXIT_CODE_FAIL; fi - ### prepare pytest - # create short test vectors - - python3 tests/create_short_testvectors.py - # rename test binaries back - - mv IVAS_cod_test IVAS_cod - - mv IVAS_dec_test IVAS_dec - # create references - - python3 -m pytest tests -v --update_ref 1 -m create_ref - - python3 -m pytest tests -v --update_ref 1 -m create_ref_part2 - - ### run pytest + # check for non bitexact output and store exit code to also always run the SBA pytest + - if [ $bitexact == 0 ] && [ $non_be_flag == 0 ] ; then echo "Non-bitexact cases without non-BE tag encountered"; selftest_exit_code=$EXIT_CODE_FAIL; fi + - if [ $bitexact == 0 ] && [ $non_be_flag != 0 ]; then echo "Non-bitexact cases with non-BE tag encountered"; selftest_exit_code=$EXIT_CODE_NON_BE; fi + + ### run SBA pytest - exit_code=0 - - python3 -m pytest tests -v --junit-xml=report-junit.xml || exit_code=$? + - python3 ./scripts/ivas_pytests/self_test_b.py --encref IVAS_cod_ref --decref IVAS_dec_ref --encdut IVAS_cod_test --decdut IVAS_dec_test || exit_code=$? - if [ $exit_code -eq 1 ] && [ $non_be_flag == 0 ]; then echo "pytest run had failures and non-BE flag not present"; exit $EXIT_CODE_FAIL; fi - zero_errors=$(cat report-junit.xml | grep -c 'errors="0"') || true - if [ $exit_code -eq 1 ] && [ $zero_errors == 1 ]; then echo "pytest run had failures, but no errors and non-BE flag present"; exit $EXIT_CODE_NON_BE; fi - if [ $exit_code -ne 0 ]; then echo "pytest run had errors"; exit $EXIT_CODE_FAIL; fi; + # return exit code from selftest if everything went well with the pytest run + - exit $selftest_exit_code allow_failure: exit_codes: - 123 @@ -487,186 +437,26 @@ codec-comparison-on-main-push: name: "main-push--sha-$CI_COMMIT_SHORT_SHA--stage-$CI_JOB_STAGE--results" when: always paths: + - test_output.txt + - scripts/test/logs/ + - scripts/ref/logs/ - report-junit.xml expose_as: 'Results of comparison to previous merge commit' reports: junit: report-junit.xml -# --------------------------------------------------------------- -# Scheduled jobs on main -# --------------------------------------------------------------- -.sanitizer-test-template: - extends: - - .test-job-linux-needs-testv-dir - stage: test - tags: - - sanitizer_test_main - artifacts: - name: "$CI_JOB_NAME--main--sha-$CI_COMMIT_SHORT_SHA" - when: always - paths: - - ep_015.g192 - -sanitizer-test-mono: - extends: .sanitizer-test-template - rules: - - if: $IS_SANITIZER_TEST_RUN - script: - - python3 ci/run_scheduled_sanitizer_test.py mono mono --tests $SANITIZER_TESTS - -sanitizer-test-stereo: - extends: .sanitizer-test-template - rules: - - if: $IS_SANITIZER_TEST_RUN - when: delayed - start_in: 20 minutes - script: - - python3 ci/run_scheduled_sanitizer_test.py stereo $OUT_FORMATS_CHANNEL_BASED --tests $SANITIZER_TESTS - -sanitizer-test-stereodmxevs: - extends: .sanitizer-test-template - rules: - - if: $IS_SANITIZER_TEST_RUN - when: delayed - start_in: 40 minutes - script: - - python3 ci/run_scheduled_sanitizer_test.py StereoDmxEvs mono --tests $SANITIZER_TESTS - -sanitizer-test-ism1: - extends: .sanitizer-test-template - rules: - - if: $IS_SANITIZER_TEST_RUN - when: delayed - start_in: 1 hour - script: - - python3 ci/run_scheduled_sanitizer_test.py ISM1 $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL EXT --tests $SANITIZER_TESTS - -sanitizer-test-ism2: - extends: .sanitizer-test-template - rules: - - if: $IS_SANITIZER_TEST_RUN - when: delayed - start_in: 1 hour 30 minutes - script: - - python3 ci/run_scheduled_sanitizer_test.py ISM2 $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL EXT --tests $SANITIZER_TESTS - -sanitizer-test-ism3: - extends: .sanitizer-test-template - rules: - - if: $IS_SANITIZER_TEST_RUN - when: delayed - start_in: 2 hours - script: - - python3 ci/run_scheduled_sanitizer_test.py ISM3 $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL EXT --tests $SANITIZER_TESTS - -sanitizer-test-ism4: - extends: .sanitizer-test-template - rules: - - if: $IS_SANITIZER_TEST_RUN - when: delayed - start_in: 2 hours 30 minutes - script: - - python3 ci/run_scheduled_sanitizer_test.py ISM4 $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL EXT --tests $SANITIZER_TESTS - -sanitizer-test-mc-5_1: - extends: .sanitizer-test-template - rules: - - if: $IS_SANITIZER_TEST_RUN - when: delayed - start_in: 3 hours - script: - - python3 ci/run_scheduled_sanitizer_test.py 5_1 $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL --tests $SANITIZER_TESTS - -sanitizer-test-mc-5_1_2: - extends: .sanitizer-test-template - rules: - - if: $IS_SANITIZER_TEST_RUN - when: delayed - start_in: 4 hours - script: - - python3 ci/run_scheduled_sanitizer_test.py 5_1_2 $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL --tests $SANITIZER_TESTS - -sanitizer-test-mc-5_1_4: - extends: .sanitizer-test-template - rules: - - if: $IS_SANITIZER_TEST_RUN - when: delayed - start_in: 5 hours - script: - - python3 ci/run_scheduled_sanitizer_test.py 5_1_4 $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL --tests $SANITIZER_TESTS - -sanitizer-test-mc-7_1: - extends: .sanitizer-test-template - rules: - - if: $IS_SANITIZER_TEST_RUN - when: delayed - start_in: 6 hours - script: - - python3 ci/run_scheduled_sanitizer_test.py 7_1 $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL --tests $SANITIZER_TESTS - -sanitizer-test-mc-7_1_4: - extends: .sanitizer-test-template - rules: - - if: $IS_SANITIZER_TEST_RUN - when: delayed - start_in: 7 hours - script: - - python3 ci/run_scheduled_sanitizer_test.py 7_1_4 $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL --tests $SANITIZER_TESTS - -sanitizer-test-masa: - extends: .sanitizer-test-template - rules: - - if: $IS_SANITIZER_TEST_RUN - when: delayed - start_in: 8 hours - script: - - python3 ci/run_scheduled_sanitizer_test.py MASA $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL EXT --tests $SANITIZER_TESTS - -sanitizer-test-sba: - extends: .sanitizer-test-template - rules: - - if: $IS_SANITIZER_TEST_RUN - when: delayed - start_in: 9 hours - script: - - python3 ci/run_scheduled_sanitizer_test.py SBA $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL --tests $SANITIZER_TESTS - -sanitizer-test-planarsba: - extends: .sanitizer-test-template - rules: - - if: $IS_SANITIZER_TEST_RUN - when: delayed - start_in: 10 hours - script: - - python3 ci/run_scheduled_sanitizer_test.py PlanarSBA $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL --tests $SANITIZER_TESTS - -# GCOV/LCOV coverage analysis of self_test suite -coverage-test-on-main-scheduled: - extends: - - .test-job-linux-needs-testv-dir - - .rules-main-scheduled - tags: - - coverage-test +sanitizer-test-on-main-scheduled: + extends: .test-job-linux-needs-testv-dir stage: test rules: - # only run in scheduled pipeline that passes this env vars - - if: $COVERAGE_TEST + # only run in scheduled pipeline that passes this env var + - if: $SANITIZER_TEST_IN_FMT script: - *print-common-info - - make GCOV=1 -j - - python3 tests/create_short_testvectors.py - - python3 -m pytest tests -v -n 0 --update_ref 1 -m create_ref --ref_encoder_path IVAS_cod --ref_decoder_path IVAS_dec - - python3 -m pytest tests -v -n 0 --update_ref 1 -m create_ref_part2 --ref_encoder_path IVAS_cod --ref_decoder_path IVAS_dec - - python3 -m pytest tests/test_param_file.py -v -n 0 --update_ref 1 -m create_ref --param_file scripts/config/self_test_evs.prm --ref_encoder_path IVAS_cod --ref_decoder_path IVAS_dec - - lcov -c -d obj -o coverage.info - - genhtml coverage.info -o coverage - artifacts: - name: "main-coverage-sha-$CI_COMMIT_SHORT_SHA" - when: always - paths: - - coverage.info - - coverage + - echo "Running scheduled sanitizer" + # - python3 ci/run_scheduled_sanitizer_test.py $SANITIZER_TEST_IN_FMT $SANITIZER_TEST_OUT_FMTS + # --------------------------------------------------------------- # Other jobs diff --git a/apps/decoder.c b/apps/decoder.c index 3b53540bc3..953df8d6b8 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -426,25 +426,25 @@ int main( /* sanity check */ if ( arg.outputFormat != IVAS_DEC_OUTPUT_BINAURAL_ROOM ) { - fprintf( stderr, "\nExternal Renderer Config is supported only when BINAURAL_ROOM is used as output. Exiting. \n\n" ); + fprintf( stderr, "\nExternal Renderer Config is supported only when BINAURAL_ROOM is used as output. Exiting. \n" ); goto cleanup; } if ( ( error = IVAS_DEC_GetRenderConfig( hIvasDec, &renderConfig ) ) != IVAS_ERR_OK ) { - fprintf( stderr, "\nIVAS_DEC_GetRenderConfig failed: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); + fprintf( stderr, "\nIVAS_DEC_GetRenderConfig failed: %s\n", IVAS_DEC_GetErrorMessage( error ) ); goto cleanup; } if ( RenderConfigReader_read( renderConfigReader, &renderConfig ) != IVAS_ERR_OK ) { - fprintf( stderr, "Failed to read renderer configuration from file %s\n\n", arg.renderConfigFilename ); + fprintf( stderr, "Failed to read renderer configuration from file %s\n", arg.renderConfigFilename ); goto cleanup; } if ( ( error = IVAS_DEC_FeedRenderConfig( hIvasDec, renderConfig ) ) != IVAS_ERR_OK ) { - fprintf( stderr, "\nIVAS_DEC_FeedRenderConfig failed: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); + fprintf( stderr, "\nIVAS_DEC_FeedRenderConfig failed: %s\n", IVAS_DEC_GetErrorMessage( error ) ); goto cleanup; } } diff --git a/apps/encoder.c b/apps/encoder.c old mode 100644 new mode 100755 index b1abc36d2f..47a6d42e30 --- a/apps/encoder.c +++ b/apps/encoder.c @@ -1618,7 +1618,7 @@ static void usage_enc( void ) fprintf( stdout, " where 0 = adaptive, 3-100 = fixed in number of frames,\n" ); fprintf( stdout, " default is deactivated\n" ); fprintf( stdout, "-dtx : Activate DTX mode with a SID update rate of 8 frames\n" ); - fprintf( stdout, " Note: DTX is currently supported in EVS, stereo, 1 ISm, \n" ); + fprintf( stdout, " Note: DTX is currently supported in EVS, DFT/TD stereo, 1 ISm, \n" ); fprintf( stdout, " SBA (up to 128kbps) and MASA (up to 128kbps)\n" ); fprintf( stdout, "-rf p o : Activate channel-aware mode for WB and SWB signal at 13.2kbps, \n" ); fprintf( stdout, " where FEC indicator, p: LO or HI, and FEC offset, o: 2, 3, 5, or 7 in number of frames.\n" ); diff --git a/ci/check_for_warnings.py b/ci/check_for_warnings.py index cc658b3d40..c9240e040a 100755 --- a/ci/check_for_warnings.py +++ b/ci/check_for_warnings.py @@ -3,7 +3,7 @@ import argparse import sys -SEARCH_FOR = "warning" +SEARCH_FOR = "warning:" RETURN_FOUND = 123 diff --git a/ci/run_evs_be_test.py b/ci/run_evs_be_test.py deleted file mode 100755 index 9fa64877f2..0000000000 --- a/ci/run_evs_be_test.py +++ /dev/null @@ -1,76 +0,0 @@ -#!/usr/bin/env python3 -import subprocess -import pathlib -import sys -import concurrent.futures -from threading import Lock - - -README_FILES_PARALLEL = [ - "Readme_AMRWB_IO_enc.txt", - "Readme_AMRWB_IO_dec.txt", - "Readme_EVS_enc.txt", - "Readme_EVS_dec.txt", -] -README_FILES_JBM = ["Readme_JBM_dec.txt"] -README_FILES = README_FILES_PARALLEL + README_FILES_JBM -BINARY_PATHS = ["./bin/EVS_cod", "./bin/EVS_dec"] -FOLDER_PATHS = ["testv"] -BIN_PATHS = BINARY_PATHS * 2 - -def main(): - - if not environment_is_correct(): - return 1 - - result_dict = dict() - # run first part in parallel - with concurrent.futures.ThreadPoolExecutor(max_workers=4) as executor: - executor.map( - run_file, README_FILES_PARALLEL, BIN_PATHS, [result_dict] * len(README_FILES_PARALLEL) - ) - - # JBM test can not run concurrently with the others - run_file(README_FILES_JBM[0], BINARY_PATHS[1], result_dict) - - return analyze_results(result_dict) - - -def analyze_results(result_dict): - ret = 0 - - for filename, ret_code in result_dict.items(): - if ret_code != 0: - print(f"========= Test for {filename} failed! See log below: ==========") - with open(filename.replace("Readme", "Log")) as f: - print(f.read()) - ret = 1 - - return ret - - -def run_file(filename: str, bin_path: str, result_dict: dict): - ret_code = subprocess.call(["bash", filename, bin_path]) - with Lock(): - result_dict[filename] = ret_code - - -def environment_is_correct(): - """ - Check that the folder with the test resources is set up correctly: - - all Readme files there - - EVS binaries available in bin/ - - testv and switchPaths folder exist - Content is not checked, though - """ - ret = True - - for path in README_FILES + BINARY_PATHS + FOLDER_PATHS: - if not pathlib.Path(path).exists(): - print(f"Environment setup is incorrect - {path} not found.") - ret = False - - return ret - - -if __name__ == "__main__": - sys.exit(main()) diff --git a/ci/run_scheduled_sanitizer_test.py b/ci/run_scheduled_sanitizer_test.py deleted file mode 100644 index 1ffaaf55a8..0000000000 --- a/ci/run_scheduled_sanitizer_test.py +++ /dev/null @@ -1,130 +0,0 @@ -#!/usr/bin/env python3 - -import argparse -import sys -import subprocess -import pathlib - - -DURATION = "120" -CFG = "ci_linux.json" -SUPPORTED_TESTS = ["CLANG1", "CLANG2", "CLANG3", "VALGRIND"] -EP_FILE = "ep_015.g192" -GENPATT_CMD = f"gen-patt -tailstat -fer -g192 -gamma 0 -rate 0.15 -tol 0.001 -reset -n {int(DURATION) * 50} {EP_FILE}" -EIDXOR_CMD = "eid-xor -vbr -fer {bitstream} {ep_file} {out_file}" -MC_MODES = ["5_1", "5_1_2", "5_1_4", "7_1", "7_1_4"] - -SCRIPT_DIR = pathlib.Path("./scripts").resolve() - - -def main(args): - in_format = args.in_format - out_formats = args.out_formats - tests = args.tests - run_fec = not args.skip_fec - - assert all([t in SUPPORTED_TESTS for t in tests]) - - modes = get_modes(in_format) - returncode = run_check(modes, out_formats, tests, run_fec=run_fec) - - sys.exit(returncode) - - -def get_modes(in_format: str) -> list: - - cmd = [ - SCRIPT_DIR.joinpath("runIvasCodec.py"), - "-C", - "MC" if in_format in MC_MODES else in_format, - "-l" - ] - list_process = subprocess.run(cmd, capture_output=True) - - output = list_process.stdout.decode("utf8") - - # correction for multichannel modes to avoid selecting some mono modes... - if in_format in MC_MODES: - in_format = "MC_" + in_format + "_b" - - mode_list = [m for m in output.splitlines() if in_format in m] - if "SBA" in in_format: - # rate switching not implemented yet - mode_list = [m for m in mode_list if not "_rs" in m] - - return mode_list - - -def run_check(modes: list, out_formats: list, tests: list, run_fec: bool = True): - - ### always run encoder and decoder with no frameloss - cmd_no_fec = [ - str(SCRIPT_DIR.joinpath("IvasBuildAndRunChecks.py")), - "-U", - DURATION, - "-p", - CFG, - "--checks", - *tests, - "-m", - *modes, - "--oc", - *out_formats, - ] - - print("======== Script command line WITHOUT plc: ========\n{}".format(" ".join(cmd_no_fec))) - - proc = subprocess.Popen(cmd_no_fec, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - for c in iter(lambda: proc.stdout.read(1), b""): - sys.stdout.buffer.write(c) - proc.wait() - - if proc.returncode not in [0, 101]: - raise IvasBuildAndRunFailed("Failed at first run (no PLC)") - - returncode_no_fec = proc.returncode - - if not run_fec: - return returncode_no_fec - - ### second run: decoder only with disturbed bitstream - - # generate error pattern - subprocess.call(GENPATT_CMD.split()) - - # cleanup to avoid script errors - # we want "logs" and "dec" subfolders to be empty -> delete and recreate them - cleanup_folders = ["logs", "dec"] - for t in tests: - for fol in cleanup_folders: - for fi in pathlib.Path(t).joinpath(fol).iterdir(): - fi.unlink() - - cmd_fec = cmd_no_fec + ["--decoder_only", "-f", EP_FILE] - print("======== Script command line WITH plc: ========\n{}".format(" ".join(cmd_no_fec))) - - proc = subprocess.Popen(cmd_fec, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - for c in iter(lambda: proc.stdout.read(1), b""): - sys.stdout.buffer.write(c) - proc.wait() - - returncode_fec = proc.returncode - - if returncode_fec not in [0, 101]: - raise IvasBuildAndRunFailed("failed at second run (PLC)") - - return 101 if 101 in [returncode_no_fec, returncode_fec] else 0 - - -class IvasBuildAndRunFailed(Exception): - pass - - -if __name__ == "__main__": - parser = argparse.ArgumentParser() - parser.add_argument("in_format", type=str) - parser.add_argument("out_formats", type=str, nargs="+") - parser.add_argument("--tests", type=str, nargs="+", default=["CLANG1", "CLANG2"]) - parser.add_argument("--skip_fec", action="store_true") - - sys.exit(main(parser.parse_args())) diff --git a/lib_com/bitstream.c b/lib_com/bitstream.c old mode 100644 new mode 100755 index 89ba17f84e..4e81fc9166 --- a/lib_com/bitstream.c +++ b/lib_com/bitstream.c @@ -1820,11 +1820,7 @@ ivas_error preview_indices( break; } } -#ifdef ALIGN_SID_SIZE - else if ( total_brate == IVAS_SID_5k2 ) -#else else if ( total_brate == IVAS_SID_4k4 ) -#endif { /* read SID format */ st_ivas->sid_format = 0; @@ -1888,7 +1884,6 @@ ivas_error preview_indices( return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Invalid value %c found in SID format field.", st_ivas->sid_format ); } } -#ifndef ALIGN_SID_SIZE else if ( total_brate == IVAS_SID_5k ) { /* SBA SID frame */ @@ -1897,7 +1892,6 @@ ivas_error preview_indices( st_ivas->sba_mode = SBA_MODE_SPAR; st_ivas->element_mode_init = IVAS_SCE; } -#endif /* only read element mode from active frames */ if ( is_DTXrate( total_brate ) == 0 ) @@ -1987,13 +1981,22 @@ ivas_error preview_indices( #ifndef SBA_ORDER_BITSTREAM st_ivas->sba_order = ( bit_stream[IVAS_FORMAT_SIGNALING_NBITS_SBA + 2] == 1 ); st_ivas->sba_order += 2 * ( bit_stream[IVAS_FORMAT_SIGNALING_NBITS_SBA + 1] == 1 ); - - st_ivas->sba_analysis_order = ivas_sba_get_analysis_order( total_brate, st_ivas->sba_order ); - -#ifdef HARMONIZE_SBA_NCHAN_TRANSPORT - 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 + st_ivas->hDecoderConfig->sba_order = ( bit_stream[IVAS_FORMAT_SIGNALING_NBITS_SBA + 2] == 1 ); + st_ivas->hDecoderConfig->sba_order += 2 * ( bit_stream[IVAS_FORMAT_SIGNALING_NBITS_SBA + 1] == 1 ); + st_ivas->sba_analysis_order = st_ivas->hDecoderConfig->sba_order; +#endif +#ifdef SBA_ORDER_BITSTREAM + /*Hard coding the the sba_oder as 1 as higher not supported below 256k bitrate*/ + if ( total_brate < IVAS_256k ) + { + st_ivas->sba_analysis_order = 1; + } +#endif +#ifdef SBA_ORDER_BITSTREAM 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 ), st_ivas->sba_mode ); +#else + ivas_sba_config( total_brate, st_ivas->sba_order, -1, &( st_ivas->nchan_transport ), st_ivas->sba_planar, &( st_ivas->nSCE ), &( st_ivas->nCPE ), &( st_ivas->element_mode_init ), st_ivas->sba_mode ); #endif } } @@ -2074,10 +2077,7 @@ ivas_error read_indices( } else if ( k == SIZE_IVAS_BRATE_TBL ) { -#ifdef ALIGN_SID_SIZE - return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Error, illegal bitrate (%d) in the G.192 frame ! Exiting ! \n", total_brate ); -#else - /*temp change for SPAR DTX*/ + /*temp change for spar DTX*/ if ( total_brate == IVAS_SID_5k ) { st_ivas->element_mode_init = -1; @@ -2086,7 +2086,6 @@ ivas_error read_indices( { return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Error, illegal bitrate (%d) in the G.192 frame ! Exiting ! \n", total_brate ); } -#endif } else { @@ -2131,7 +2130,7 @@ ivas_error read_indices( } else { - sid_upd_bad = 1; /* this frame type may happen in ETSI/3GPP CS cases, a corrupt SID frames */ + sid_upd_bad = 1; /* this frame type may happen in ETSI/3GPP CS cases , a corrupt sid frames */ } } @@ -2216,7 +2215,7 @@ ivas_error read_indices( /* total_brate= 0 */ } - /* handle bad/lost speech frame(and CS bad SID frame) in the decoders CNG synthesis settings pair (total_brate, bfi) */ + /* handle bad/lost speech frame(and CS bad sid frame) in the decoders CNG synthesis settings pair (total_brate, bfi) */ if ( ( ( *CNG != 0 ) && ( ( speech_bad != 0 ) || ( speech_lost != 0 ) ) ) || /* SP_BAD or SPEECH_LOST) --> stay in CNG */ ( sid_upd_bad != 0 ) ) /* SID_UPD_BAD --> start CNG */ { @@ -2335,7 +2334,7 @@ static Word32 read_indices_mime_handle_dtx( { if ( st->bfi ) { - sid_upd_bad = 1; /* corrupt sid_first, signaled as bad SID */ + sid_upd_bad = 1; /* corrupt sid_first, signaled as bad sid */ } else { @@ -2393,7 +2392,7 @@ static Word32 read_indices_mime_handle_dtx( } /* in CNG */ - /* handle bad speech frame(and bad SID frame) in the decoders CNG synthesis settings pair (total_brate, bfi) */ + /* handle bad speech frame(and bad sid frame) in the decoders CNG synthesis settings pair (total_brate, bfi) */ if ( ( *CNG != 0 && ( speech_bad || speech_lost || no_data ) ) || /* SP_BAD or SPEECH_LOST) --> stay in CNG */ sid_upd_bad ) /* SID_UPD_BAD --> start/stay CNG */ { @@ -2980,18 +2979,4 @@ void evs_dec_previewFrame( } -#ifdef ALIGN_SID_SIZE -void dtx_read_padding_bits( - DEC_CORE_HANDLE st, - int16_t num_bits ) -{ - /* TODO: temporary hack, need to decide what to do with core-coder bitrate */ - int32_t tmp; - tmp = st->total_brate; - st->total_brate = st->total_brate + num_bits * FRAMES_PER_SEC; - get_next_indice( st, num_bits ); - st->total_brate = tmp; -} -#endif - #undef WMC_TOOL_MAN diff --git a/lib_com/cnst.h b/lib_com/cnst.h index 40a4710579..8e4c7c9908 100644 --- a/lib_com/cnst.h +++ b/lib_com/cnst.h @@ -67,7 +67,8 @@ #define MAX16B_FLT 32767.0f #define MIN16B_FLT ( -32768.0f ) #define PCM16_TO_FLT_FAC 32768.0f -#define MDFT_NORM_SCALING ( 1.0f / PCM16_TO_FLT_FAC ) + + #define MAX_FRAME_COUNTER 200 #define MAX_BITS_PER_FRAME 10240 /* Bits per frame for max. bitrate 512kbps */ diff --git a/lib_com/ivas_cnst.h b/lib_com/ivas_cnst.h index 43b60566dc..223f3fa490 100644 --- a/lib_com/ivas_cnst.h +++ b/lib_com/ivas_cnst.h @@ -170,9 +170,7 @@ typedef enum #define HEAD_ROTATION_HOA_ORDER 3 /* HOA 3rd order */ #define MAX_CICP_CHANNELS 16 /* max channels for loudspeaker layouts (16 for custom layouts)*/ #define MAX_OUTPUT_CHANNELS 16 /* Maximum number of output channels (HOA 3rd order) */ -#ifndef FIX_CREND_CHANNELS #define IVAS_MAX_NUM_CH 16 /* == MAX_OUTPUT_CHANNELS */ -#endif #define FOA_CHANNELS 4 /* number of FOA channels */ @@ -202,12 +200,9 @@ typedef enum /*----------------------------------------------------------------------------------* * IVAS Bitrates *----------------------------------------------------------------------------------*/ -#ifdef ALIGN_SID_SIZE -#define IVAS_SID_5k2 5200 /* SID frame bitrate */ -#else + #define IVAS_SID_4k4 4400 /* SID frame bitrate */ #define IVAS_SID_5k 5000 /* SBA SID frame bitrate */ -#endif #define IVAS_13k2 13200 #define IVAS_16k4 16400 #define IVAS_24k4 24400 @@ -225,13 +220,8 @@ typedef enum #define IVAS_BRATE_MAX IVAS_512k -#ifdef ALIGN_SID_SIZE -#define SIZE_IVAS_BRATE_TBL 16 -#define IVAS_NUM_ACTIVE_BRATES (SIZE_IVAS_BRATE_TBL - 2) -#else #define SIZE_IVAS_BRATE_TBL 17 #define IVAS_NUM_ACTIVE_BRATES (SIZE_IVAS_BRATE_TBL - 3) -#endif /*----------------------------------------------------------------------------------* * IVAS modes : IVAS SCE, IVAS CPE modes (DFT, TD, MDCT stereo) @@ -812,25 +802,16 @@ enum fea_names #define MAX_MDCT_ITD_BRATE IVAS_64k #define SNS_LOW_BR_MODE -1 -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT #define SNS_NPTS 16 /* Number of downsampled SNS parameters */ -#define MDCT_ST_PLC_FADEOUT_MIN_NOISE_NRG 0.001f -#ifdef FADE_TO_ZERO_FOR_TOO_LONG_FRAMELOSS -#define MDCT_ST_PLC_FADEOUT_MAX_CONC_FRAME 2 * FRAMES_PER_SEC -#define MDCT_ST_PLC_FADEOUT_TO_ZERO_LEN 20 -#endif +#define MDCT_ST_PLC_FADEOUT_START_FRAME 3 typedef enum { EQUAL_CORES, TCX10_IN_0_TCX20_IN_1, TCX20_IN_0_TCX10_IN_1, } TONALMDCTCONC_NOISE_GEN_MODE; - -typedef enum { - ON_FIRST_LOST_FRAME, - ON_FIRST_GOOD_FRAME, -} TONALMDCTCONC_NOISE_SHAPE_WHITENING_MODE; #endif @@ -847,9 +828,6 @@ typedef enum { *----------------------------------------------------------------------------------*/ // VE: this should be renamed to e.g. N_SPATIAL_SUBFRAMES #define MAX_PARAM_SPATIAL_SUBFRAMES 4 /* Maximum number of subframes for parameteric spatial coding */ -#ifdef FIX_I106_TDREND_5MS -#define L_SPATIAL_SUBFR_48k (L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES) -#endif /*----------------------------------------------------------------------------------* @@ -858,7 +836,6 @@ typedef enum { #define SBA_PLANAR_BITS 1 #define SBA_ORDER_BITS 2 -#define SBA_MIN_BRATE_HOA IVAS_256k #define SBA_NHARM_HOA3 16 #define SBA_T_DESIGN_11_SIZE 70 @@ -874,15 +851,8 @@ typedef enum * DirAC Constants *----------------------------------------------------------------------------------*/ -#ifdef FIX_DIRAC_CHANNELS -#define DIRAC_MAX_ANA_CHANS FOA_CHANNELS /* Maximum number of channels for DirAC analysis */ -#else #define DIRAC_MAX_ANA_CHANS 4 /* Maximum number of channels for DirAC analysis */ -#endif - -#ifndef HARMONIZE_SBA_NCHAN_TRANSPORT #define DIRAC_MAX_TRANS_CHANS 8 /* Maximum number of transport channels for DirAC */ -#endif #define DIRAC_MIN_BITRATE_8_TRANS_CHAN IVAS_384k #define DIRAC_MIN_BITRATE_6_TRANS_CHAN IVAS_256k @@ -1036,9 +1006,9 @@ enum #define IVAS_DECORR_PARM_LOOKAHEAD_TAU 2e-3f #define IVAS_DECORR_PARM_APD_TAU 20e-3f -/* IVAS SBA PCA */ +/* IVAS PCA */ #define IVAS_PCA_NB_SUBR 20 /* 80 -> 0.25 ms, 40 -> 0.5 ms... */ -#define IVAS_PCA_COV_THRES 3e-5f +#define IVAS_PCA_COV_THRES 1e-9f #define IVAS_PCA_QUAT_EPS 1e-7f #define IVAS_PCA_QBITS 19 #define IVAS_PCA_N1 91 @@ -1169,7 +1139,7 @@ enum #define MASA_STEREO_MIN_BITRATE IVAS_24k4 #define MASA_BIT_REDUCT_PARAM 10 -#define MASA_MAXIMUM_TWO_DIR_BANDS 18 + typedef enum { MASA_STEREO_NOT_DEFINED, diff --git a/lib_com/ivas_dirac_com.c b/lib_com/ivas_dirac_com.c index fe344e6423..849e889739 100644 --- a/lib_com/ivas_dirac_com.c +++ b/lib_com/ivas_dirac_com.c @@ -60,11 +60,7 @@ ivas_error ivas_dirac_config( ) { IVAS_FORMAT ivas_format; -#ifdef HARMONIZE_SBA_NCHAN_TRANSPORT - int16_t sba_order; -#else int16_t sba_order, sba_planar; -#endif int16_t *nSCE, *nCPE, *element_mode, *nchan_transport; int32_t ivas_total_brate; DIRAC_CONFIG_DATA_HANDLE hConfig; @@ -86,10 +82,12 @@ ivas_error ivas_dirac_config( nCPE = &( (Encoder_Struct *) st_ivas )->nCPE; element_mode = &( (Encoder_Struct *) st_ivas )->hEncoderConfig->element_mode_init; nchan_transport = &( (Encoder_Struct *) st_ivas )->nchan_transport; +#ifndef SBA_ORDER_BITSTREAM + sba_order = ( (Encoder_Struct *) st_ivas )->hEncoderConfig->sba_order; +#else sba_order = ( (Encoder_Struct *) st_ivas )->sba_analysis_order; -#ifndef HARMONIZE_SBA_NCHAN_TRANSPORT - sba_planar = ( (Encoder_Struct *) st_ivas )->hEncoderConfig->sba_planar; #endif + sba_planar = ( (Encoder_Struct *) st_ivas )->hEncoderConfig->sba_planar; ivas_total_brate = ( (Encoder_Struct *) st_ivas )->hEncoderConfig->ivas_total_brate; Fs = ( (Encoder_Struct *) st_ivas )->hEncoderConfig->input_Fs; band_grouping = ( (Encoder_Struct *) st_ivas )->hDirAC->band_grouping; @@ -113,10 +111,12 @@ ivas_error ivas_dirac_config( nCPE = &( (Decoder_Struct *) st_ivas )->nCPE; element_mode = &( (Decoder_Struct *) st_ivas )->element_mode_init; nchan_transport = &( (Decoder_Struct *) st_ivas )->nchan_transport; +#ifndef SBA_ORDER_BITSTREAM + sba_order = ( (Decoder_Struct *) st_ivas )->sba_order; +#else sba_order = ( (Decoder_Struct *) st_ivas )->sba_analysis_order; -#ifndef HARMONIZE_SBA_NCHAN_TRANSPORT - sba_planar = ( (Decoder_Struct *) st_ivas )->sba_planar; #endif + sba_planar = ( (Decoder_Struct *) st_ivas )->sba_planar; ivas_total_brate = ( (Decoder_Struct *) st_ivas )->hDecoderConfig->ivas_total_brate; Fs = ( (Decoder_Struct *) st_ivas )->hDecoderConfig->output_Fs; band_grouping = ( (Decoder_Struct *) st_ivas )->hDirAC->band_grouping; @@ -150,12 +150,8 @@ ivas_error ivas_dirac_config( if ( ivas_format == SBA_FORMAT ) /* skip for MASA decoder */ { -#ifdef HARMONIZE_SBA_NCHAN_TRANSPORT - if ( ( error = ivas_dirac_sba_config( hQMetaData, nchan_transport, nSCE, nCPE, element_mode, ivas_total_brate, sba_order, sba_mode, hConfig->nbands - spar_dirac_split_band ) ) != IVAS_ERR_OK ) -#else if ( ( error = ivas_dirac_sba_config( hQMetaData, nchan_transport, nSCE, nCPE, element_mode, ivas_total_brate, sba_order, sba_planar, sba_mode, hConfig->nbands - spar_dirac_split_band ) ) != IVAS_ERR_OK ) -#endif { return error; } @@ -319,11 +315,9 @@ ivas_error ivas_dirac_sba_config( int16_t *element_mode, /* i/o: element mode of the core coder */ int32_t sba_total_brate, /* i : SBA total bitrate */ const int16_t sba_order, /* i : Ambisonic (SBA) order */ -#ifndef HARMONIZE_SBA_NCHAN_TRANSPORT - const int16_t sba_planar, /* i : SBA planar flag */ -#endif - const SBA_MODE sba_mode, /* i : SBA mode */ - const int16_t nbands /* i : number of frequency bands */ + const int16_t sba_planar, /* i : SBA planar flag */ + const SBA_MODE sba_mode, /* i : SBA mode */ + const int16_t nbands /* i : number of frequency bands */ ) { int16_t i; @@ -337,11 +331,7 @@ ivas_error ivas_dirac_sba_config( if ( sba_mode == SBA_MODE_SPAR ) { /*map the bitrate for SID frame*/ -#ifdef ALIGN_SID_SIZE - if ( sba_total_brate == IVAS_SID_5k2 ) -#else if ( sba_total_brate == IVAS_SID_5k ) -#endif { if ( *element_mode == IVAS_SCE ) { @@ -438,23 +428,11 @@ ivas_error ivas_dirac_sba_config( return error; } -#ifdef ALIGN_SID_SIZE - if ( sba_total_brate > IVAS_SID_5k2 ) -#else if ( sba_total_brate > IVAS_SID_4k4 ) -#endif { -#ifdef HARMONIZE_SBA_NCHAN_TRANSPORT - *nchan_transport = ivas_get_sba_num_TCs( sba_total_brate, sba_order ); -#else *nchan_transport = ivas_dirac_getNumTransportChannels( sba_total_brate, sba_order, sba_planar ); -#endif } -#ifdef ALIGN_SID_SIZE - else if ( sba_total_brate == IVAS_SID_5k2 ) -#else else if ( sba_total_brate == IVAS_SID_4k4 ) -#endif { switch ( *element_mode ) { @@ -593,7 +571,7 @@ ivas_error ivas_dirac_sba_config( return error; } -#ifndef HARMONIZE_SBA_NCHAN_TRANSPORT + /*------------------------------------------------------------------------- * ivas_dirac_getNumTransportChannels() * @@ -665,7 +643,7 @@ int16_t ivas_dirac_getNumTransportChannels( return num_channels; } -#endif + /*------------------------------------------------------------------------- * computeDirectionVectors() diff --git a/lib_com/ivas_entropy_coder_common.c b/lib_com/ivas_entropy_coder_common.c old mode 100644 new mode 100755 diff --git a/lib_com/ivas_fb_mixer.c b/lib_com/ivas_fb_mixer.c index 53ad90d01f..11746c64ef 100644 --- a/lib_com/ivas_fb_mixer.c +++ b/lib_com/ivas_fb_mixer.c @@ -1098,8 +1098,8 @@ static ivas_error ivas_filterbank_setup( for ( j = 0; j < IVAS_MAX_NUM_FB_BANDS; j++ ) { - pFb->fb_bin_to_band.p_short_stride_num_bins_per_band[j] = 0; /* aka num_active_bins per SPAR band */ - pFb->fb_bin_to_band.p_short_stride_start_bin_per_band[j] = 0; /* first considered bin index per SPAR band */ + pFb->fb_bin_to_band.p_short_stride_num_bins_per_band[j] = 0; /* aka num_active_bins per spar band */ + pFb->fb_bin_to_band.p_short_stride_start_bin_per_band[j] = 0; /* first considered bin index per spar band */ pFb->fb_bin_to_band.pp_short_stride_bin_to_band[j] = NULL; for ( i = 0; i < CLDFB_NO_CHANNELS_MAX; i++ ) { diff --git a/lib_com/ivas_mdft_imdft.c b/lib_com/ivas_mdft_imdft.c old mode 100644 new mode 100755 diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index b5bcfd5fb1..3003b9f785 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -238,10 +238,6 @@ uint32_t ivas_syn_output( int16_t *synth_out /* o : integer 16 bits synthesis signal */ ); -void ivas_initialize_handles_enc( - Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ -); - ivas_error ivas_init_encoder( Encoder_Struct *st_ivas, /* i/o: IVAS encoder structure */ Indice ind_list[][MAX_NUM_INDICES], /* i : indices list */ @@ -798,8 +794,8 @@ void ivas_param_ism_enc( ); void ivas_param_ism_enc_close( - DIRAC_ENC_HANDLE hDirAC, /* i/o: encoder DirAC handle */ - const int32_t input_Fs /* i : input sampling_rate */ + DIRAC_ENC_HANDLE hDirAC /* i/o: encoder DirAC handle */ + ,const int32_t input_Fs /* i : input sampling_rate */ ); void ivas_param_ism_stereo_dmx( @@ -1849,7 +1845,7 @@ void TNSAnalysisStereo( 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 */ 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) */ + const int16_t mct_on /* i : flag mct block (1) or stereo (0) */ ); void InternalTCXDecoder( @@ -1950,12 +1946,15 @@ void decoder_tcx_invQ( const int16_t **prm_sqQ, int16_t *nf_seed, const int16_t bfi, /* i : Bad frame indicator */ +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT + const int16_t isMCT, +#endif const int16_t frame_cnt /* i : frame counter in the super frame */ ); void decoder_tcx_noisefilling( Decoder_State *st, /* i/o: coder memory state */ -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT float concealment_noise[L_FRAME48k], #endif const float A[], /* i : coefficients NxAz[M+1] */ @@ -1970,7 +1969,7 @@ void decoder_tcx_noisefilling( const int16_t *prm_sqQ, int16_t nf_seed, const int16_t bfi, /* i : Bad frame indicator */ -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT const int16_t isMCT, #endif const int16_t frame_cnt /* i : frame counter in the super frame */ @@ -2014,7 +2013,7 @@ void decoder_tcx_imdct( const int16_t left_rect, float x[N_MAX], float xn_buf[], - const uint16_t kernelType, /* i : TCX transform kernel type */ + const uint16_t kernelType, /* i : TCX transform kernel type */ const int16_t fUseTns, /* i : flag that is set if TNS data is present */ float synth[], /* i/o: synth[-M..L_frame] */ float synthFB[], @@ -2055,12 +2054,7 @@ void decoder_tcx_IGF_stereo( const int16_t L_frame, /* i : frame length */ const int16_t left_rect, /* i : left part is rectangular */ const int16_t k, /* i : Subframe index */ -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE - const int16_t bfi, /* i : bad frame indicator */ - const int16_t is_mct /* i : flag to signal MCT or SMDCT */ -#else const int16_t bfi /* i : bad frame indicator */ -#endif ); void ms_processing( @@ -2093,12 +2087,7 @@ void IGFDecApplyStereo( const int16_t igfGridIdx, /* i : in case of CELP->TCX switching, use 1.25 framelength */ const int16_t *coreMsMask, const int16_t restrict_hopsize, -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE - const int16_t bfi, /* i : frame loss == 1, frame good == 0 */ - const int16_t bfi_apply_damping /* i : decoder element mode */ -#else const int16_t bfi /* i : frame loss == 1, frame good == 0 */ -#endif ); void IGFEncStereoEncoder( @@ -2166,7 +2155,7 @@ void stereo_mdct_core_dec( void splitAvailableBits( const int16_t total_bits, /* i : total available bits for TCX coding */ const int16_t split_ratio, /* i : split ratio */ - const int16_t isSBAStereoMode, /* i : signal core coding for SBA */ + const int16_t isSBAStereoMode, /* i : signal core coding for sba */ int16_t *bits_ch0, /* o : bits for channel 0 */ int16_t *bits_ch1 /* o : bits for channel 1 */ ); @@ -2184,7 +2173,7 @@ void parse_stereo_from_bitstream( STEREO_MDCT_DEC_DATA_HANDLE hStereoMdct, /* i/o: MDCT stereo decoder structure */ Decoder_State **sts, /* i/o: decoder state structure */ const int16_t mct_on, /* i : flag mct block (1) or stereo (0) */ - const int16_t isSBAStereoMode, /* i : flag core coding for SBA */ + const int16_t isSBAStereoMode, /* i: flag core coding for sba */ Decoder_State *st0, /* i/o: decoder state structure for Bstr */ int16_t ms_mask[NB_DIV][MAX_SFB] /* o : bandwise MS mask */ ); @@ -2519,7 +2508,8 @@ ivas_error stereo_memory_enc( const int32_t input_Fs, /* i : input sampling rate */ const int16_t max_bwidth, /* i : maximum audio bandwidth */ float *tdm_last_ratio, /* o : TD stereo last ratio */ - const IVAS_FORMAT ivas_format, /* i : IVAS format */ + const IVAS_FORMAT ivas_format /* i : IVAS format */ + , const int16_t nchan_transport /* i : number transport chans */ ); @@ -2778,12 +2768,8 @@ void reset_metadata_spatial( int32_t *total_brate, /* o : total bitrate */ const int32_t core_brate, /* i : core bitrate */ const int16_t nb_bits_metadata, /* i : number of meatdata bits */ -#ifndef ALIGN_SID_SIZE const SBA_MODE sba_mode, /* i : SBA mode */ const int16_t element_mode /* i : element mode */ -#else - const SBA_MODE sba_mode /* i : SBA mode */ -#endif ); /*! r: number of bits written */ @@ -3033,10 +3019,8 @@ void ivas_sba_config( const int16_t sba_planar, /* i : SBA planar flag */ int16_t *nSCE, /* o : number of SCEs */ int16_t *nCPE, /* o : number of CPEs */ - int16_t *element_mode /* o : element mode of the core coder */ -#ifndef HARMONIZE_SBA_NCHAN_TRANSPORT + int16_t *element_mode, /* o : element mode of the core coder */ const SBA_MODE sba_mode /* i : SBA mode */ -#endif ); ivas_error ivas_sba_dec_reconfigure( @@ -3049,23 +3033,15 @@ void ivas_init_dec_get_num_cldfb_instances( int16_t *numCldfbSyntheses /* o : number of CLDFB synthesis instances */ ); -/*! r: Ambisonic (SBA) order */ int16_t ivas_sba_get_order( const int16_t nb_channels, /* i : Number of ambisonic channels */ const int16_t sba_planar /* i : SBA planar flag */ ); -/*! r: Ambisonic (SBA) order used for analysis and coding */ -int16_t ivas_sba_get_analysis_order( - const int32_t ivas_total_brate, /* i : IVAS total bitrate */ - const int16_t sba_order /* i : Ambisonic (SBA) order */ -); - int16_t ivas_sba_get_order_transport( const int16_t nchan_transport /* i : Number of transport channels */ ); -/*!r: number of Ambisonic channels */ int16_t ivas_sba_get_nchan( const int16_t sba_order, /* i : Ambisonic (SBA) order */ const int16_t sba_planar /* i : SBA planar flag */ @@ -3185,21 +3161,18 @@ ivas_error ivas_dirac_sba_config( int16_t *element_mode, /* o : element mode of the core coder */ int32_t sba_total_brate, /* i : SBA total bitrate */ const int16_t sba_order, /* i : Ambisonic (SBA) order */ -#ifndef HARMONIZE_SBA_NCHAN_TRANSPORT const int16_t sba_planar, /* i : SBA planar flag */ -#endif const SBA_MODE sba_mode, /* i : SBA mode */ const int16_t nbands /* i : number of frequency bands */ ); -#ifndef HARMONIZE_SBA_NCHAN_TRANSPORT /*! r: number of IVAS transport channels */ int16_t ivas_dirac_getNumTransportChannels( const int32_t sba_total_brate, /* i : SBA total bitrate */ const int16_t sba_order, /* i : SBA order */ const int16_t sba_planar /* i : SBA Planar flag */ ); -#endif + ivas_error ivas_dirac_dec_open( Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ ); @@ -3392,8 +3365,8 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls( 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 */ DIRAC_DEC_HANDLE hDirAC, /* i/o: DirAC handle */ - float *reference_power_smooth, - float qualityBasedSmFactor + float *reference_power_smooth + , float qualityBasedSmFactor ); void ivas_dirac_dec_get_response( @@ -3744,13 +3717,13 @@ void ivas_spar_config( void ivas_sba_upmixer_renderer( Decoder_Struct *st_ivas, /* i/o: IVAS decoder struct */ float output[][L_FRAME48k], /* i/o: transport/output audio channels */ + const int16_t nchan_remapped, /* i : num channels after remapping of TCs */ const int16_t output_frame /* i : output frame length */ ); void ivas_sba_mix_matrix_determiner( - SPAR_DEC_HANDLE hSpar, /* i/o: SPAR decoder handle */ - float output[][L_FRAME48k], /* i/o: transport/output audio channels */ - const int16_t bfi, /* i : BFI flag */ + Decoder_Struct *st_ivas, /* i/o: IVAS decoder struct */ + float in_out[][L_FRAME48k], /* i/o: transport/output audio channels */ const int16_t nchan_remapped, /* i : num channels after remapping of TCs */ const int16_t output_frame /* i : output frame length */ ); @@ -3842,12 +3815,7 @@ int16_t ivas_get_spar_table_idx( int16_t *ind /* o : indice */ ); -#ifdef HARMONIZE_SBA_NCHAN_TRANSPORT -/*! r: number of transport channels */ -int16_t ivas_get_sba_num_TCs( -#else int16_t ivas_get_spar_num_TCs( -#endif const int32_t ivas_total_brate, /* i : IVAS total bitrate */ const int16_t sba_order /* i : IVAS SBA order */ ); @@ -3897,8 +3865,11 @@ void ivas_spar_dec_upmixer( /* MD module */ ivas_error ivas_spar_md_enc_open( ivas_spar_md_enc_state_t **hMdEnc, /* i/o: SPAR MD encoder handle */ - const ENCODER_CONFIG_HANDLE hEncoderConfig, /* i : configuration structure */ - const int16_t sba_order /* i : Ambisonic (SBA) order */ + const ENCODER_CONFIG_HANDLE hEncoderConfig /* i : configuration structure */ +#ifdef SBA_ORDER_BITSTREAM + , + int16_t sba_order +#endif ); void ivas_spar_md_enc_close( @@ -3910,8 +3881,11 @@ ivas_error ivas_spar_md_enc_process( const ENCODER_CONFIG_HANDLE hEncoderConfig, /* i : configuration structure */ ivas_spar_md_enc_in_buf_t *pIn_buf, BSTR_ENC_HANDLE hMetaData, /* i/o: MetaData handle */ - const int16_t dtx_silence_mode, - const int16_t sba_order /* i : Ambisonic (SBA) order */ + const int16_t dtx_silence_mode +#ifdef SBA_ORDER_BITSTREAM + , + int16_t sba_order +#endif ); void ivas_compute_spar_params( @@ -4268,17 +4242,17 @@ int16_t ivas_map_num_drct_r_to_idx( const int16_t num_quant_points_drct_r ); int16_t ivas_map_num_decd_r_to_idx( const int16_t num_quant_points_decd_r ); /* Quantization utilities */ -void ivas_quantise_real_values( - const float *values, - const int16_t q_levels, - const float min_value, - const float max_value, - int16_t *index, - float *quant, - const int16_t dim +void ivas_quantise_real_values( + float **values, + const int16_t q_levels, + const float min_value, + const float max_value, + int16_t **index, + float **quant, + const int16_t dim1, + const int16_t dim2 ); - void ivas_spar_get_uniform_quant_strat( ivas_spar_md_com_cfg *pSpar_md_com_cfg, const int16_t table_idx @@ -4450,10 +4424,10 @@ void ivas_masa_prerender( void ivas_spar_param_to_masa_param_mapping( Decoder_Struct *st_ivas, /* i/o: IVAS decoder struct */ - float inRe[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i : Input audio in CLDFB domain, real */ - float inIm[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i : Input audio in CLDFB domain, imag */ - const int16_t firstSubframe, /* i : First subframe to map */ - const int16_t nSubframes /* i : Number of subframes to map */ + float inRe[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i: Input audio in CLDFB domain, real */ + float inIm[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i: Input audio in CLDFB domain, imag */ + const int16_t firstSubframe, /* i: First subframe to map */ + const int16_t nSubframes /* i: Number of subframes to map */ ); @@ -4669,9 +4643,9 @@ void vbap_determine_gains( ); void v_sort_ind( - float *x, /* i/o: Vector to be sorted */ - int16_t *idx, /* o : Original index positions */ - const int16_t len /* i : vector length */ + float *x, /* i/o: Vector to be sorted */ + int16_t *idx, /* o : Original index positions */ + const int16_t len /* i : vector length */ ); /*----------------------------------------------------------------------------------* @@ -4706,7 +4680,7 @@ void ivas_lssetupconversion_process_param_mc( Decoder_Struct *st_ivas, /* i/o: LS setup conversion renderer handle */ float Cldfb_RealBuffer_InOut[MAX_CICP_CHANNELS][PARAM_MC_MAX_NSLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* i/o: LS signals */ float Cldfb_ImagBuffer_InOut[MAX_CICP_CHANNELS][PARAM_MC_MAX_NSLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* i/o: LS signals */ - int16_t channel_active[MAX_CICP_CHANNELS] /* i : bitmap indicating which output channels are active */ + int16_t channel_active[MAX_CICP_CHANNELS] /* i : bitmap indicating which output channels are active */ ); @@ -4912,7 +4886,8 @@ void ivas_HRTF_binary_close( TDREND_HRFILT_FiltSet_t **hHrtfTD /* i/o: TD renderer HRTF handle */ ); -void DefaultBSplineModel( +/*! r: TD Renderer result code. */ +ivas_error DefaultBSplineModel( TDREND_HRFILT_FiltSet_t *HrFiltSet_p, /* o : Loaded HR filter set */ const int32_t output_Fs /* i : Output sampling rate */ ); @@ -4925,7 +4900,7 @@ void ivas_td_binaural_close( BINAURAL_TD_OBJECT_RENDERER_HANDLE *hBinRendererTd /* i/o: TD binaural object renderer handle */ ); -void ObjRenderIVASFrame( +ivas_error ObjRenderIVASFrame( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ float output[][L_FRAME48k], /* i/o: SCE channels / Binaural synthesis */ const int16_t output_frame /* i : output frame length */ @@ -4966,50 +4941,46 @@ void TDREND_HRFILT_SetFiltSet( #endif ivas_error TDREND_REND_RenderSourceHRFilt( -#ifdef FIX_I106_TDREND_5MS - TDREND_SRC_t *Src_p, /* i/o: The source to be rendered */ -#else const TDREND_SRC_t *Src_p, /* i/o: The source to be rendered */ -#endif #ifdef TDREND_HRTF_TABLE_METHODS BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ #endif -#ifdef FIX_I106_TDREND_5MS - float output_buf[][L_SPATIAL_SUBFR_48k], /* o : Output buffer */ - const int16_t subframe_length, /* i : Subframe length in use */ -#else float output_buf[][L_FRAME48k], /* o : Output buffer */ const int16_t output_frame, /* i : Output frame length in use */ -#endif const int32_t output_Fs /* i : Output sample rate */ ); /* ----- Object renderer - sources ----- */ +/*! r: TD Renderer result code. */ ivas_error TDREND_MIX_SRC_SetPos( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ const int16_t SrcInd, /* i : Source index */ const float *Vec_p /* i : Position vector */ ); +/*! r: TD Renderer result code. */ ivas_error TDREND_MIX_SRC_SetDir( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ const int16_t SrcInd, /* i : Source index */ const float *Vec_p /* i : Direction vector */ ); +/*! r: TD Renderer result code. */ ivas_error TDREND_MIX_SRC_SetDirAtten( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ const int16_t SrcInd, /* i : Source index */ const TDREND_DirAtten_t *DirAtten_p /* i : Directional attenuation specifier */ ); +/*! r: TD Renderer result code. */ ivas_error TDREND_MIX_SRC_SetPlayState( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ const int16_t SrcInd, /* i : Source index */ const TDREND_PlayStatus_t PlayStatus /* i : Play state */ ); + void TDREND_SRC_REND_UpdateFiltersFromSpatialParams( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ TDREND_SRC_REND_t *SrcRend_p, /* i/o: Source object */ @@ -5017,6 +4988,7 @@ void TDREND_SRC_REND_UpdateFiltersFromSpatialParams( const int32_t output_Fs /* i : Output sample rate */ ); +/*! r: TD Renderer result code. */ ivas_error TDREND_SRC_Alloc( TDREND_SRC_t **Src_pp /* i/o: Source */ ); @@ -5070,6 +5042,7 @@ int16_t TDREND_SPATIAL_EvalOrthonormOrient( /* ----- Object renderer - mix ----- */ +/*! r: TD Renderer result code. */ ivas_error TDREND_MIX_AddSrc( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ int16_t *SrcInd, /* o : Source index */ @@ -5077,16 +5050,19 @@ ivas_error TDREND_MIX_AddSrc( const int32_t output_Fs /* i : Output sampling rate */ ); +/*! r: TD Renderer result code. */ ivas_error TDREND_MIX_SetDistAttenModel( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ const TDREND_DistAttenModel_t DistAttenModel /* i : Distance attenuation model */ ); -void TDREND_MIX_LIST_SetPos( +/*! r: TD Renderer result code. */ +ivas_error TDREND_MIX_LIST_SetPos( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ const float *Pos_p /* i : Listener's position */ ); +/*! r: TD Renderer result code. */ ivas_error TDREND_MIX_LIST_SetOrient( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ const float *FrontVec_p, /* i : Listener's orientation front vector */ @@ -5097,6 +5073,7 @@ void TDREND_MIX_Dealloc( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd /* i/o: TD renderer handle */ ); +/*! r: TD Renderer result code. */ ivas_error TDREND_MIX_Init( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ TDREND_HRFILT_FiltSet_t **hHrtfTD, /* i/o: HRTF data (initialized in case of NULL) */ @@ -5106,25 +5083,24 @@ ivas_error TDREND_MIX_Init( /* ----- Object renderer - sfx ----- */ +/*! r: TD Renderer result code. */ ivas_error TDREND_SFX_SpatBin_Initialize( SFX_SpatBin_t *SfxSpatBin_p, /* i/o: Spatial parameters handle */ const int32_t output_Fs /* i : Output sampling rate */ ); -void TDREND_SFX_SpatBin_SetParams( +/*! r: TD Renderer result code. */ +ivas_error TDREND_SFX_SpatBin_SetParams( SFX_SpatBin_t *SfxSpatBin_p, /* i/o: Spatial parameters struct to be updated */ const SFX_SpatBin_Params_t *NewParam_p, /* i : New parameters struct */ const int32_t output_Fs /* i : Output sample rate */ ); -void TDREND_SFX_SpatBin_Execute_Main( +/*! r: TD Renderer result code. */ +ivas_error TDREND_SFX_SpatBin_Execute_Main( SFX_SpatBin_t *SfxSpatBin_p, /* i/o: Spatial parameters handle */ const float *InBuffer_p, /* i : Input buffer */ -#ifdef FIX_I106_TDREND_5MS - const int16_t subframe_length, /* i : subframe length */ -#else const int16_t output_frame, /* i : frame length */ -#endif float *LeftOutBuffer_p, /* o : Rendered left channel */ float *RightOutBuffer_p, /* o : Rendered right channel */ int16_t *NoOfUsedInputSamples_p, /* o : Number of input samples actually used */ @@ -5473,7 +5449,7 @@ ivas_error ivas_orient_trk_GetTrackedOrientation( float *roll ); -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT void TonalMdctConceal_create_concealment_noise( float concealment_noise[L_FRAME48k], CPE_DEC_HANDLE hCPE, @@ -5482,21 +5458,9 @@ void TonalMdctConceal_create_concealment_noise( const int16_t idchan, const int16_t subframe_idx, const int16_t core, - const float crossfade_gain, + const int16_t crossfade_gain, const TONALMDCTCONC_NOISE_GEN_MODE noise_gen_mode ); - -void TonalMdctConceal_whiten_noise_shape( - Decoder_State *st, - const int16_t L_frame, - const TONALMDCTCONC_NOISE_SHAPE_WHITENING_MODE -); - -int16_t get_igf_startline( - Decoder_State *st, - int16_t L_frame, - int16_t L_frameTCX -); #endif float rand_triangular_signed( @@ -5504,10 +5468,4 @@ float rand_triangular_signed( /* clang-format on */ -#ifdef ALIGN_SID_SIZE -void dtx_read_padding_bits( - DEC_CORE_HANDLE st, - int16_t num_bits ); -#endif - #endif /* IVAS_PROT_H */ diff --git a/lib_com/ivas_rom_com.c b/lib_com/ivas_rom_com.c index 4a82259296..e2ba9b8233 100644 --- a/lib_com/ivas_rom_com.c +++ b/lib_com/ivas_rom_com.c @@ -49,11 +49,7 @@ const int32_t ivas_brate_tbl[SIZE_IVAS_BRATE_TBL] = { -#ifdef ALIGN_SID_SIZE - FRAME_NO_DATA, IVAS_SID_5k2, -#else FRAME_NO_DATA, IVAS_SID_4k4, IVAS_SID_5k, -#endif IVAS_13k2, IVAS_16k4, IVAS_24k4, IVAS_32k, IVAS_48k, IVAS_64k, IVAS_80k, IVAS_96k, IVAS_128k, IVAS_160k, IVAS_192k, IVAS_256k, IVAS_384k, IVAS_512k @@ -907,11 +903,11 @@ const ivas_spar_br_table_t ivas_spar_br_table_consts[IVAS_SPAR_BR_TABLE_LEN] = { /* When AGC is ON additional (AGC_BITS_PER_CH+1) bits may be taken from each core-coder channel so minimum core-coder bitrate per channel can be min core-coder bitrates as per the table - AGC_BITS_PER_CH */ - { 24400, 0, 1, FB, 24000, 1, WYXZ, 1, 0,{ { 16400, 14850, 24350 } }, + { 24400, 0, 1, FB, 24000, 1, WYXZ, 1, 0, + { { 16400, 14850, 24350 } }, { { 15, 1, 5, 1 },{ 15, 1, 3, 1 },{ 7, 1, 3, 1 } }, 0, 0, 0 }, - { 32000, 0, 1, FB, 24000, 1, WYXZ, 1, 0,{ { 24000, 20450, 31950 } }, - { { 21, 1, 5, 1 },{ 15, 1, 5, 1 },{ 15, 1, 3, 1 } }, 0, 0, 0 }, + { 32000, 0, 1, FB, 24000, 1, WYXZ, 1, 0,{{ 24000, 20450, 31950 }},{ { 21, 1, 5, 1 },{ 15, 1, 5, 1 },{ 15, 1, 3, 1 } }, 0, 0, 0 }, { 48000, 0, 1, FB, 24000, 2, WYXZ, 0, 0,{ { 24000, 21000, 31950 },{ 16000, 15000, 20400 } }, { { 15, 7, 5, 1 },{ 15, 7, 3, 1 },{ 7, 7, 3, 1 } }, 1, 0, 0 }, @@ -959,6 +955,8 @@ const ivas_spar_br_table_t ivas_spar_br_table_consts[IVAS_SPAR_BR_TABLE_LEN] = { 512000, 0, 3, FB, 24000, 4, WYXZ, 0, 0,{ { 128000, 128000, 128000 },{ 128000, 128000, 128000 },{ 127200, 122550, 128000 },{ 76300, 73550, 128000 } }, // not yet optimized { { 31, 11, 11, 1 },{ 1, 1, 1, 1 },{ 1, 1, 1, 1 } }, 1, 2, 0 }, + + }; const ivas_freq_models_t ivas_arith_pred_r_consts[TOTAL_PRED_QUANT_STRATS_ARITH] = @@ -1138,7 +1136,7 @@ const ivas_freq_models_t ivas_arith_pred_r_consts[TOTAL_PRED_QUANT_STRATS_ARITH] } }; -const ivas_freq_models_t ivas_arith_drct_r_consts[TOTAL_DRCT_QUANT_STRATS] = + const ivas_freq_models_t ivas_arith_drct_r_consts[TOTAL_DRCT_QUANT_STRATS] = { /* entry for 1 quantization points */ { @@ -1225,7 +1223,7 @@ const ivas_freq_models_t ivas_arith_drct_r_consts[TOTAL_DRCT_QUANT_STRATS] = } }; -const ivas_freq_models_t ivas_arith_decd_r_consts[TOTAL_DECD_QUANT_STRATS] = + const ivas_freq_models_t ivas_arith_decd_r_consts[TOTAL_DECD_QUANT_STRATS] = { /* entry for 1 quantization points */ { @@ -2735,7 +2733,7 @@ const uint8_t masa_twodir_bands[IVAS_NUM_ACTIVE_BRATES] = const uint8_t masa_twodir_bands_joined[IVAS_NUM_ACTIVE_BRATES] = { - 0, 0, 0, 0, 0, 2, 2, 3, 4, 6, 8, 9, 12, MASA_MAXIMUM_TWO_DIR_BANDS + 0, 0, 0, 0, 0, 2, 2, 3, 4, 6, 8, 9, 12, 18 }; @@ -3365,8 +3363,7 @@ const float ivas_mdft_coeff_cos_twid_960[IVAS_960_PT_LEN + 1] = 0.00654493796735196f, 0.00490871880799808f, 0.00327248650652671f, 0.00163624544362412f, 0.00000000000000000f }; - -const float ivas_mdft_coeff_cos_twid_640[IVAS_640_PT_LEN + 1] = +const float ivas_mdft_coeff_cos_twid_640[IVAS_640_PT_LEN +1] = { 1.00000000000000f, 0.999996988037278f, 0.999987952167257f, 0.999972892444367f, 0.999951808959328f, 0.999924701839145f, 0.999891571247108f, 0.999852417382795f, @@ -3527,10 +3524,9 @@ const float ivas_mdft_coeff_cos_twid_640[IVAS_640_PT_LEN + 1] = 0.0392598157590687f, 0.0368072229413588f, 0.0343544083996823f, 0.0319013869096110f, 0.0294481732479634f, 0.0269947821927155f, 0.0245412285229123f, 0.0220875270185784f, 0.0196336924606283f, 0.0171797396307788f, 0.0147256833114584f, 0.0122715382857199f, - 0.00981731933714973f, 0.00736304124977978f, 0.00490871880799808f, 0.00245436679646048f, - 0.00000000000000000f + 0.00981731933714973f, 0.00736304124977978f, 0.00490871880799808f, 0.00245436679646048f + ,0.00000000000000000f }; - const float ivas_mdft_coeff_cos_twid_320[IVAS_320_PT_LEN + 1] = { 1.00000000000000f, 0.999987952167257f, 0.999951808959328f, 0.999891571247108f, @@ -3612,10 +3608,9 @@ const float ivas_mdft_coeff_cos_twid_320[IVAS_320_PT_LEN + 1] = 0.0784590957278450f, 0.0735645635996675f, 0.0686682588843738f, 0.0637702995616845f, 0.0588708036511890f, 0.0539698892095020f, 0.0490676743274181f, 0.0441642771270675f, 0.0392598157590687f, 0.0343544083996823f, 0.0294481732479634f, 0.0245412285229123f, - 0.0196336924606283f, 0.0147256833114584f, 0.00981731933714973f, 0.00490871880799808f, - 0.0000000000000000f + 0.0196336924606283f, 0.0147256833114584f, 0.00981731933714973f, 0.00490871880799808f + ,0.0000000000000000f }; - const float ivas_mdft_coeff_cos_twid_240[IVAS_240_PT_LEN + 1] = { 1.0000000000f, 0.9999785817f, 0.9999143276f, 0.9998072405f, 0.9996573250f, 0.9994645875f, @@ -3690,7 +3685,6 @@ const float ivas_mdft_coeff_cos_twid_160[IVAS_160_PT_LEN + 1] = 0.0980171403f, 0.0882423705f, 0.0784590957f, 0.0686682589f, 0.0588708037f, 0.0490676743f, 0.0392598158f, 0.0294481732f, 0.0196336925f, 0.0098173193f, 0.000000000f }; - const float ivas_mdft_coeff_cos_twid_80[IVAS_80_PT_LEN + 1] = { 1.0000000000f, 0.9998072405f, 0.9992290362f, 0.9982656102f, 0.9969173337f, 0.9951847267f, @@ -3708,7 +3702,6 @@ const float ivas_mdft_coeff_cos_twid_80[IVAS_80_PT_LEN + 1] = 0.1564344650f, 0.1370123417f, 0.1175373975f, 0.0980171403f, 0.0784590957f, 0.0588708037f, 0.0392598158f, 0.0196336925f, 0.000000000f }; - const float ivas_mdft_coeff_cos_twid_40[IVAS_40_PT_LEN + 1] = { 1.0000000000f, 0.9992290362f, 0.9969173337f, 0.9930684570f, 0.9876883406f, 0.9807852804f, @@ -3719,7 +3712,6 @@ const float ivas_mdft_coeff_cos_twid_40[IVAS_40_PT_LEN + 1] = 0.3826834324f, 0.3461170571f, 0.3090169944f, 0.2714404499f, 0.2334453639f, 0.1950903220f, 0.1564344650f, 0.1175373975f, 0.0784590957f, 0.0392598158f, 0.000000000f }; - const float ivas_sin_twiddle_480[IVAS_480_PT_LEN >> 1] = { -0.000818122995607253f, -0.00736304124977957f, -0.0139076440957708f, -0.0204516511845773f, diff --git a/lib_com/ivas_sba_config.c b/lib_com/ivas_sba_config.c index 58cd80bc37..28a66df68f 100644 --- a/lib_com/ivas_sba_config.c +++ b/lib_com/ivas_sba_config.c @@ -87,11 +87,8 @@ void ivas_sba_config( const int16_t sba_planar, /* i : SBA Planar flag */ int16_t *nSCE, /* o : number of SCEs */ int16_t *nCPE, /* o : number of CPEs */ - int16_t *element_mode /* o : element mode of the core coder */ -#ifndef HARMONIZE_SBA_NCHAN_TRANSPORT - , - const SBA_MODE sba_mode /* i : SBA mode */ -#endif + int16_t *element_mode, /* o : element mode of the core coder */ + const SBA_MODE sba_mode /* i : SBA mode */ ) { if ( ( sba_order < 0 ) && ( nb_channels < 0 ) ) @@ -120,9 +117,6 @@ void ivas_sba_config( if ( nchan_transport != NULL ) { -#ifdef HARMONIZE_SBA_NCHAN_TRANSPORT - *nchan_transport = ivas_get_sba_num_TCs( sba_total_brate, sba_order ); -#else if ( sba_mode == SBA_MODE_SPAR ) { *nchan_transport = ivas_get_spar_num_TCs( sba_total_brate, sba_order ); @@ -131,7 +125,6 @@ void ivas_sba_config( { *nchan_transport = ivas_dirac_getNumTransportChannels( sba_total_brate, sba_order, sba_planar ); } -#endif } /* Configure core coder number of elements*/ @@ -165,7 +158,6 @@ void ivas_sba_config( * Get Ambisonic order from number of ambisonic channels *-------------------------------------------------------------------*/ -/*! r: Ambisonic (SBA) order */ int16_t ivas_sba_get_order( const int16_t nb_channels, /* i : Number of ambisonic channels */ const int16_t sba_planar /* i : SBA Planar flag */ @@ -190,32 +182,6 @@ int16_t ivas_sba_get_order( } -/*-------------------------------------------------------------------* - * ivas_sba_get_analysis_order() - * - * Get Ambisonic order used for analysis and coding - *-------------------------------------------------------------------*/ - -/*! r: Ambisonic (SBA) order used for analysis and coding */ -int16_t ivas_sba_get_analysis_order( - const int32_t ivas_total_brate, /* i : IVAS total bitrate */ - const int16_t sba_order /* i : Ambisonic (SBA) order */ -) -{ - int16_t sba_analysis_order; - - sba_analysis_order = sba_order; - - if ( ivas_total_brate < SBA_MIN_BRATE_HOA ) - { - /* Hard coding the sba_analysis_order as 1 as higher not supported below SBA_MIN_BRATE_HOA bitrate */ - sba_analysis_order = 1; - } - - return sba_analysis_order; -} - - /*-------------------------------------------------------------------* * ivas_sba_get_order_transport() * @@ -249,7 +215,6 @@ int16_t ivas_sba_get_order_transport( * Get number of Ambisonic channels *-------------------------------------------------------------------*/ -/*!r: number of Ambisonic channels */ int16_t ivas_sba_get_nchan( const int16_t sba_order, /* i : Ambisonic (SBA) order */ const int16_t sba_planar /* i : SBA planar flag */ diff --git a/lib_com/ivas_sns_com.c b/lib_com/ivas_sns_com.c index b1555a038b..51f5fcee64 100644 --- a/lib_com/ivas_sns_com.c +++ b/lib_com/ivas_sns_com.c @@ -37,7 +37,7 @@ #include "ivas_prot.h" #include "rom_com.h" #include -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT #include #endif #ifdef DEBUGGING @@ -45,7 +45,7 @@ #endif #include "wmops.h" -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT /*------------------------------------------------------------------- * sns_compute_scf() diff --git a/lib_com/ivas_spar_com.c b/lib_com/ivas_spar_com.c old mode 100644 new mode 100755 index ce4e742401..3c908c7980 --- a/lib_com/ivas_spar_com.c +++ b/lib_com/ivas_spar_com.c @@ -137,23 +137,23 @@ void ivas_get_twid_factors( float ivas_get_mdct_scaling_gain( const int16_t dct_len_by_2 ) { - float gain = 0.0f; + float result = 0.0f; switch ( dct_len_by_2 ) { case L_FRAME48k >> 2: { - gain = IVAS_MDCT_SCALING_GAIN_48k; + result = IVAS_MDCT_SCALING_GAIN_48k; break; } case L_FRAME32k >> 2: { - gain = IVAS_MDCT_SCALING_GAIN_32k; + result = IVAS_MDCT_SCALING_GAIN_32k; break; } case L_FRAME16k >> 2: { - gain = IVAS_MDCT_SCALING_GAIN_16k; + result = IVAS_MDCT_SCALING_GAIN_16k; break; } default: @@ -163,7 +163,7 @@ float ivas_get_mdct_scaling_gain( } } - return gain; + return result; } @@ -311,11 +311,7 @@ void ivas_spar_config( const int16_t sid_format /* i : IVAS format indicator from SID frame */ ) { -#ifdef ALIGN_SID_SIZE - if ( ivas_total_brate == IVAS_SID_5k2 ) -#else if ( ivas_total_brate == IVAS_SID_5k ) -#endif { if ( sid_format == SID_SBA_1TC ) { @@ -328,11 +324,7 @@ void ivas_spar_config( } else { -#ifdef HARMONIZE_SBA_NCHAN_TRANSPORT - *nchan_transport = ivas_get_sba_num_TCs( ivas_total_brate, sba_order ); -#else *nchan_transport = ivas_get_spar_num_TCs( ivas_total_brate, sba_order ); -#endif } *nCPE = ( *nchan_transport > 1 ) ? ( *nchan_transport + 1 ) >> 1 : 0; @@ -341,11 +333,7 @@ void ivas_spar_config( if ( *nchan_transport == 1 ) { /* map SPAR SID bitrate to SPAR active bitrate */ -#ifdef ALIGN_SID_SIZE - if ( ivas_total_brate == IVAS_SID_5k2 ) -#else if ( ivas_total_brate == IVAS_SID_5k ) -#endif { ivas_total_brate = IVAS_32k; } @@ -420,16 +408,6 @@ int16_t ivas_get_spar_table_idx( } -#ifdef HARMONIZE_SBA_NCHAN_TRANSPORT -/*-------------------------------------------------------------------* - * ivas_get_sba_num_TCs() - * - * Return number of TCs in SBA format - *-------------------------------------------------------------------*/ - -/*! r: number of transport channels */ -int16_t ivas_get_sba_num_TCs( -#else /*-------------------------------------------------------------------* * ivas_get_spar_num_TCs() * @@ -438,27 +416,16 @@ int16_t ivas_get_sba_num_TCs( /*! r: number of transport channels */ int16_t ivas_get_spar_num_TCs( -#endif const int32_t ivas_total_brate, /* i : IVAS total bitrate */ const int16_t sba_order /* i : Ambisonic (SBA) order */ ) { int16_t table_idx, nchan_transport; -#ifdef ALIGN_SID_SIZE - if ( ivas_total_brate == IVAS_SID_5k2 ) -#else if ( ivas_total_brate == IVAS_SID_5k ) -#endif { nchan_transport = 1; } -#ifdef HARMONIZE_SBA_NCHAN_TRANSPORT - else if ( ivas_sba_mode_select( ivas_total_brate ) == SBA_MODE_DIRAC ) - { - nchan_transport = 1; - } -#endif else { table_idx = ivas_get_spar_table_idx( ivas_total_brate, sba_order, SPAR_CONFIG_BW, NULL, NULL ); diff --git a/lib_com/ivas_spar_com_quant_util.c b/lib_com/ivas_spar_com_quant_util.c index c095e20107..9b0a936018 100644 --- a/lib_com/ivas_spar_com_quant_util.c +++ b/lib_com/ivas_spar_com_quant_util.c @@ -42,49 +42,90 @@ #include #include "wmops.h" +/*-----------------------------------------------------------------------------------------* + * Function ivas_limit_values() + * + * Limit values within given range + *-----------------------------------------------------------------------------------------*/ + +static void ivas_limit_values( + float **ppValues, + const float min_value, + const float max_value, + const int16_t dim1, + const int16_t dim2 ) +{ + int16_t i, j; + + for ( i = 0; i < dim1; i++ ) + { + for ( j = 0; j < dim2; j++ ) + { + ppValues[i][j] = max( min_value, min( ppValues[i][j], max_value ) ); + } + } + + return; +} + + /*-----------------------------------------------------------------------------------------* * Function ivas_quantise_real_values() * * Quantize real values *-----------------------------------------------------------------------------------------*/ + void ivas_quantise_real_values( - const float *values, + float **values, const int16_t q_levels, const float min_value, const float max_value, - int16_t *index, - float *quant, - const int16_t dim ) + int16_t **index, + float **quant, + const int16_t dim1, + const int16_t dim2 ) { - int16_t i; + int16_t i, j; float q_step, one_by_q_step; + if ( q_levels == 1 ) { - for ( i = 0; i < dim; i++ ) + for ( i = 0; i < dim1; i++ ) { - quant[i] = 0; - index[i] = 0; + for ( j = 0; j < dim2; j++ ) + { + quant[i][j] = 0; + index[i][j] = 0; + } } } else if ( q_levels && max_value != min_value ) { + ivas_limit_values( values, min_value, max_value, dim1, dim2 ); + q_step = ( max_value - min_value ) / ( q_levels - 1 ); one_by_q_step = ( q_levels - 1 ) / ( max_value - min_value ); - float val; - for ( i = 0; i < dim; i++ ) + + for ( i = 0; i < dim1; i++ ) { - val = max( min_value, min( values[i], max_value ) ); - index[i] = (int16_t) round( one_by_q_step * val ); - quant[i] = index[i] * q_step; + for ( j = 0; j < dim2; j++ ) + { + index[i][j] = (int16_t) round( one_by_q_step * values[i][j] ); + quant[i][j] = index[i][j] * q_step; + } } } else { - for ( i = 0; i < dim; i++ ) + for ( i = 0; i < dim1; i++ ) { - quant[i] = values[i]; + for ( j = 0; j < dim2; j++ ) + { + quant[i][j] = values[i][j]; + } } } + return; } @@ -218,7 +259,7 @@ void ivas_map_prior_coeffs_quant( /*-----------------------------------------------------------------------------------------* * Function ivas_spar_quant_dtx_init() * - * Init SPAR MD with minmax vals + * Init spar md with minmax vals *-----------------------------------------------------------------------------------------*/ void ivas_spar_quant_dtx_init( @@ -306,7 +347,7 @@ void ivas_copy_band_coeffs_idx_to_arr( /*-----------------------------------------------------------------------------------------* * Function ivas_clear_band_coeffs() * - * clear band coeffs array in SPAR MD + * clear band coeffs array in spar MD *-----------------------------------------------------------------------------------------*/ void ivas_clear_band_coeffs( @@ -333,7 +374,7 @@ void ivas_clear_band_coeffs( /*-----------------------------------------------------------------------------------------* * Function ivas_clear_band_coeff_idx() * - * clear band coeffs index array in SPAR MD + * clear band coeffs index array in spar MD *-----------------------------------------------------------------------------------------*/ void ivas_clear_band_coeff_idx( @@ -345,6 +386,7 @@ void ivas_clear_band_coeff_idx( for ( i = 0; i < num_bands; i++ ) { set_s( pband_coeff_idx[i].pred_index_re, 0, ( IVAS_SPAR_MAX_CH - 1 ) ); + set_s( pband_coeff_idx[i].drct_index_re, 0, IVAS_SPAR_MAX_C_COEFF ); set_s( pband_coeff_idx[i].decd_index_re, 0, ( IVAS_SPAR_MAX_CH - 1 ) ); } diff --git a/lib_com/ivas_stat_com.h b/lib_com/ivas_stat_com.h index e19d30dc71..8c54421f04 100644 --- a/lib_com/ivas_stat_com.h +++ b/lib_com/ivas_stat_com.h @@ -692,8 +692,8 @@ typedef struct ivas_fb_bin_to_band_data_t float *pFb_bin_to_band[IVAS_MAX_NUM_FB_BANDS]; const int16_t *pFb_start_bin_per_band; const int16_t *pFb_active_bins_per_band; - float pp_cldfb_weights_per_spar_band[CLDFB_NO_CHANNELS_MAX][IVAS_MAX_NUM_FB_BANDS]; /* weights for linear combination of parameters from different SPAR bands*/ - int16_t p_spar_start_bands[CLDFB_NO_CHANNELS_MAX]; /* the first SPAR band per CLFB band when the weight is > 0 */ + float pp_cldfb_weights_per_spar_band[CLDFB_NO_CHANNELS_MAX][IVAS_MAX_NUM_FB_BANDS]; /* weights for linear combination of parameters from different spar bands*/ + int16_t p_spar_start_bands[CLDFB_NO_CHANNELS_MAX]; /* the first spar band per CLFB band when the weight is > 0 */ int16_t p_cldfb_map_to_spar_band[CLDFB_NO_CHANNELS_MAX]; /* a direct mapping from CLDFB band to SPAR band */ int16_t p_short_stride_start_bin_per_band[IVAS_MAX_NUM_FB_BANDS]; int16_t p_short_stride_num_bins_per_band[IVAS_MAX_NUM_FB_BANDS]; diff --git a/lib_com/ivas_stereo_dft_com.c b/lib_com/ivas_stereo_dft_com.c index 7de3144f63..918fd27b35 100644 --- a/lib_com/ivas_stereo_dft_com.c +++ b/lib_com/ivas_stereo_dft_com.c @@ -82,11 +82,7 @@ void stereo_dft_config( hConfig->res_cod_mode = STEREO_DFT_RES_COD_OFF; } } -#ifdef ALIGN_SID_SIZE - else if ( brate == IVAS_SID_5k2 ) -#else else if ( brate == IVAS_SID_4k4 ) -#endif { *bits_frame_nominal = SID_2k40 / FRAMES_PER_SEC; if ( hConfig != NULL ) diff --git a/lib_com/ivas_stereo_mdct_stereo_com.c b/lib_com/ivas_stereo_mdct_stereo_com.c index cbb1423cd1..73cd2fd579 100644 --- a/lib_com/ivas_stereo_mdct_stereo_com.c +++ b/lib_com/ivas_stereo_mdct_stereo_com.c @@ -46,7 +46,7 @@ void splitAvailableBits( const int16_t total_bits, /* i : total available bits for TCX coding */ const int16_t split_ratio, /* i : split ratio */ - const int16_t isSBAStereoMode, /* i : signal core coding for SBA */ + const int16_t isSBAStereoMode, /* i : signal core coding for sba */ int16_t *bits_ch0, /* o : bits for channel 0 */ int16_t *bits_ch1 /* o : bits for channel 1 */ ) diff --git a/lib_com/ivas_stereo_psychlpc_com.c b/lib_com/ivas_stereo_psychlpc_com.c index 4ca10255a7..7093a91093 100644 --- a/lib_com/ivas_stereo_psychlpc_com.c +++ b/lib_com/ivas_stereo_psychlpc_com.c @@ -68,10 +68,11 @@ static void SpectrumWeighting_Init( * initialize a PsychoacousticParameters structure *-------------------------------------------------------------------*/ -#ifndef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifndef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT static #endif -ivas_error PsychoacousticParameters_Init( + ivas_error + PsychoacousticParameters_Init( const int32_t sr_core, /* i : sampling rate of core-coder */ const int16_t nBins, /* i : Number of bins (spectral lines) */ const int8_t nBands, /* i : Number of spectrum subbands */ diff --git a/lib_com/ivas_tools.c b/lib_com/ivas_tools.c index 6b0c0eb297..079af159bc 100644 --- a/lib_com/ivas_tools.c +++ b/lib_com/ivas_tools.c @@ -1172,12 +1172,8 @@ int16_t is_SIDrate( if ( ( ivas_total_brate == SID_1k75 ) || ( ivas_total_brate == SID_2k40 ) || -#ifdef ALIGN_SID_SIZE - ( ivas_total_brate == IVAS_SID_5k2 ) ) -#else ( ivas_total_brate == IVAS_SID_4k4 ) || ( ivas_total_brate == IVAS_SID_5k ) ) -#endif { sid_rate_flag = 1; } diff --git a/lib_com/options.h b/lib_com/options.h index e3ead5c21a..054eca6526 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -141,23 +141,24 @@ #endif #define DISABLE_ADAP_RES_COD_TMP /* temporary fix for IVAS-403, disables adaptive residual coding */ /*#define ITD_WINNER_GAIN_MODIFY */ /* ITD optimization - WORK IN PROGRESS */ + /*#define FIX_I4_OL_PITCH*/ /* fix open-loop pitch used for EVS core switching */ -#define MDCT_STEREO_PLC_FADE_2_BG_NOISE /* IVAS-185 fix bug in TCX-PLC fadeout for MDCT-Stereo and improve fadeout by fading to background noise instead of white noise */ -#define FADE_TO_ZERO_FOR_TOO_LONG_FRAMELOSS +/*#define FIX_IVAS_185_MDCT_ST_PLC_FADEOUT*/ /* IVAS-185 fix bug in TCX-PLC fadeout for MDCT-Stereo and improve fadeout by fading to background noise instead of white noise */ /*#define FIX_I1_113*/ /* under review : MCT bit distribution optimization for SBA high bitrates*/ -#define FIX_I106_TDREND_5MS /* Issue 106: 5 ms update rate in TD object renderer */ -#define ALIGN_SID_SIZE /* Issue 111: make all DTX modes use one SID frame bitrate (5.2 kbps) */ -#define FIX_135_MDCT_STEREO_MODE_UNINITIALIZED /* Issue 135: fix uninitialized value usage in SBA MDCT-Stereo core with PLC */ -#define FIX_CONTROLLABLE_SID_UPDATE_RATE /* Issue 117: fix controllable SID update rate mechanism */ -#define FIX_DIRAC_CHANNELS /* Issue 71: lower number of DirAC analysis channels */ -#define FIX_CREND_CHANNELS /* Issue 71: fix number of Crend channels */ -#define HARMONIZE_SBA_NCHAN_TRANSPORT /* harmonize setting of number of transport channels in SBA */ -#define DRAM_REDUCTION_MCT_IGF /* Issue 121: reduce dynamic RAM consumption in MCT IGF */ - #define EXT_RENDERER /* FhG: external renderer library and standalone application */ #define FIX_EFAP_MATH /* fix for EFAP: remove angle quantization and a bug in polygon lookup causing incorrect gains. minor tweak for ALLRAD. non-BE for modes using EFAP */ + +#define FIX_WRONG_NBANDS_IN_ITD_ESTIMATION /* Issue 85: fix incorrect setting of nbands in calc_mean_E_ratio() if bwidth is limited on commandline*/ + +#define FIX_I87 /* fix for issue 86: incorrect Ambisonics order set for head rotation in SBA */ +#define SBA_ORDER_BITSTREAM /* issue 76: Use input sba order for bitstream coding */ + +/* NTT switches */ +#define NTT_UPDATE_ITD_SW /* contribution 4: Update of ITD switch in stereo downmix for EVS */ +#define NTT_REMOVE_EPS_ROM /* contribution 4: Reduction of ROM size in stereo downmix for EVS */ + /* ################## End DEVELOPMENT switches ######################### */ /* clang-format on */ #endif diff --git a/lib_com/prot.h b/lib_com/prot.h old mode 100755 new mode 100644 index 86e9e172e3..d9b238bdf0 --- a/lib_com/prot.h +++ b/lib_com/prot.h @@ -2773,11 +2773,13 @@ void fb_tbe_enc( ); void fb_tbe_dec( - Decoder_State *st, /* i/o: decoder state structure */ - const float fb_exc[], /* i : FB excitation from the SWB part */ - float *hb_synth, /* i/o: high-band synthesis */ - float *fb_synth_ref, /* o : high-band synthesis 16-20 kHz */ - const int16_t output_frame /* i : output frame length */ + Decoder_State *st, /* i/o: decoder state structure */ + const float fb_exc[], /* i : FB excitation from the SWB part */ + float *hb_synth, /* i/o: high-band synthesis */ + float *fb_synth_ref /* o : high-band synthesis 16-20 kHz */ + , + const int16_t output_frame /* i: output frame length */ + ); void calc_tilt_bwe( @@ -5145,7 +5147,7 @@ void decod_amr_wb( ivas_error init_decoder( Decoder_State *st, /* o : Decoder static variables structure */ const int16_t idchan /* i : channel ID */ -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT , const MC_MODE mc_mode /* i : MC mode */ #endif @@ -6776,7 +6778,7 @@ void enc_acelp_tcx_main( void getTCXMode( Decoder_State *st, /* i/o: decoder memory state */ Decoder_State *st0 /* i : bitstream */ -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT , const int16_t MCT_flag #endif @@ -7181,7 +7183,7 @@ void WindowSignal( float out[], /* o : output windowed signal */ const int16_t truncate_aldo, /* i : nonzero to truncate long ALDO slope */ const int16_t fullband, /* i : fullband flag */ - const int16_t isLfe /* i : LFE flag */ + const int16_t isLfe /* i: LFE flag */ ); void HBAutocorrelation( @@ -7396,17 +7398,13 @@ void ProcessStereoIGF( Encoder_State *sts[CPE_CHANNELS], /* i : Encoder state */ int16_t ms_mask[2][MAX_SFB], /* i : bandwise MS mask */ float *pITFMDCTSpectrum[CPE_CHANNELS][2], /* i : MDCT spectrum fir ITF */ -#ifdef DRAM_REDUCTION_MCT_IGF - float *pPowerSpectrum[CPE_CHANNELS], /* i/o: MDCT^2 + MDST^2 spectrum, or estimate */ -#else float pPowerSpectrum[CPE_CHANNELS][N_MAX], /* i : MDCT^2 + MDST^2 spectrum, or estimate */ -#endif float *pPowerSpectrumMsInv[CPE_CHANNELS][2], /* i : inverse power spectrum */ float *inv_spectrum[CPE_CHANNELS][2], /* i : inverse spectrum */ const int16_t frameno, /* i : flag indicating index of current subframe*/ const int16_t sp_aud_decision0, /* i : sp_aud_decision0 */ const int32_t element_brate, /* i : element bitrate */ - const int16_t mct_on /* i : flag mct block (1) or stereo (0) */ + const int16_t mct_on /* i : flag mct block (1) or stereo (0) */ ); void AnalyzePowerSpectrum( @@ -7897,7 +7895,7 @@ void decoder_tcx_post( float *synthFB, float *A, const int16_t bfi -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT , const int16_t isMCT #endif @@ -7953,7 +7951,7 @@ void decoder_acelp( void writeTCXMode( Encoder_State *st, /* i/o: encoder state structure */ BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT const int16_t is_mct, #endif int16_t *nbits_start /* o : nbits start */ @@ -8144,7 +8142,7 @@ void con_tcx( const float coh, /* i : coherence of stereo signal */ int16_t *noise_seed, /* i/o: noise seed for stereo */ const int16_t only_left /* i : TD-PLC only in left channel */ -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT , const float *A_cng #endif @@ -8693,7 +8691,7 @@ void configureFdCngDec( void ApplyFdCng( float *timeDomainInput, -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT float *powerSpectrum, #endif float **realBuffer, /* i/o: Real part of the buffer */ @@ -8704,7 +8702,7 @@ void ApplyFdCng( void perform_noise_estimation_dec( const float *timeDomainInput, -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT float *power_spectrum, #endif HANDLE_FD_CNG_DEC hFdCngDec, /* i/o: FD_CNG structure */ @@ -9206,7 +9204,7 @@ void open_decoder_LPD( const int32_t last_total_brate, /* i : last total bitrate */ const int16_t bwidth, /* i : audio bandwidth */ const int16_t is_mct, /* i : MCT mode flag */ -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT const int16_t last_element_mode, #endif const int16_t is_init /* i : indicate call during initialization */ @@ -9249,9 +9247,9 @@ void mode_switch_decoder_LPD( const int32_t last_total_brate, /* i : last frame total bitrate */ const int16_t frame_size_index, /* i : index determining the frame size*/ const int16_t is_mct /* i : MCT mode flag */ -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT , - const int16_t last_element_mode /* i : last element mode */ + const int16_t last_element_mode #endif ); @@ -9533,7 +9531,7 @@ void TonalMDCTConceal_SaveFreqSignal( const uint16_t numSamples, const uint16_t nNewSamplesCore, const float *scaleFactors -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT , const int16_t infoIGFStartLine #endif @@ -9571,9 +9569,8 @@ void TonalMDCTConceal_InsertNoise( int16_t *pSeed, /*IN/OUT*/ const float tiltCompFactor, const float crossfadeGain, -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT const float concealment_noise[L_FRAME48k], - const float cngLevelBackgroundTrace_bfi, #endif const int16_t crossOverFreq ); @@ -9609,7 +9606,7 @@ void RefineTonalComponents( float floorPowerSpectrum, const PsychoacousticParameters *psychParamsCurrent ); -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT ivas_error PsychoacousticParameters_Init( const int32_t sr_core, /* i : sampling rate of core-coder */ const int16_t nBins, /* i : Number of bins (spectral lines) */ @@ -9798,11 +9795,7 @@ void IGFEncApplyStereo( const IGF_ENC_INSTANCE_HANDLE hIGFEnc[CPE_CHANNELS], /* i : instance handle of IGF Encoder */ const int16_t igfGridIdx, /* i : IGF grid index */ Encoder_State *sts[CPE_CHANNELS], /* i : Encoder state */ -#ifdef DRAM_REDUCTION_MCT_IGF - float *pPowerSpectrum[CPE_CHANNELS], /* i/o: MDCT^2 + MDST^2 spectrum, or estimate */ -#else float pPowerSpectrum[CPE_CHANNELS][N_MAX], /* i/o: MDCT^2 + MDST^2 spectrum, or estimate */ -#endif float *pPowerSpectrumMsInv[CPE_CHANNELS][2], /* i/o: inverse power spectrum */ float *inv_spectrum[CPE_CHANNELS][2], /* i : inverse spectrum */ const int16_t frameno, /* i : flag indicating index of current subframe */ diff --git a/lib_debug/sba_debug.c b/lib_debug/sba_debug.c old mode 100644 new mode 100755 diff --git a/lib_dec/acelp_core_dec.c b/lib_dec/acelp_core_dec.c old mode 100644 new mode 100755 index 684c12b57e..7951f10d54 --- a/lib_dec/acelp_core_dec.c +++ b/lib_dec/acelp_core_dec.c @@ -125,11 +125,7 @@ ivas_error acelp_core_dec( error = IVAS_ERR_OK; -#ifdef ALIGN_SID_SIZE - if ( st->element_mode == IVAS_CPE_MDCT && nchan_out == 1 && st->idchan == 1 && last_element_brate <= IVAS_SID_5k2 ) -#else if ( st->element_mode == IVAS_CPE_MDCT && nchan_out == 1 && st->idchan == 1 && last_element_brate <= IVAS_SID_4k4 ) -#endif { /* In MDCT-Stereo DTX with mono output, we can skip CNG for the second channel, except for the first inactive frame following an active period */ return error; @@ -160,7 +156,7 @@ ivas_error acelp_core_dec( st->hFdCngDec->hFdCngCom->sidNoiseEstLp[i] = STEREO_DFT_FD_FILT * st->hFdCngDec->hFdCngCom->sidNoiseEstLp[i] + ( 1 - STEREO_DFT_FD_FILT ) * st->hFdCngDec->hFdCngCom->sidNoiseEst[i]; } -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT ApplyFdCng( NULL, NULL, NULL, NULL, st, 0, 0 ); #else ApplyFdCng( NULL, NULL, NULL, st, 0, 0 ); @@ -534,7 +530,7 @@ ivas_error acelp_core_dec( { st->hFdCngDec->hFdCngCom->sidNoiseEstLp[i] = STEREO_DFT_FD_FILT * st->hFdCngDec->hFdCngCom->sidNoiseEstLp[i] + ( 1 - STEREO_DFT_FD_FILT ) * st->hFdCngDec->hFdCngCom->sidNoiseEst[i]; } -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT ApplyFdCng( syn, NULL, realBuffer, imagBuffer, st, 0, ( st->coder_type == AUDIO && !st->GSC_noisy_speech ) ); #else ApplyFdCng( syn, realBuffer, imagBuffer, st, 0, ( st->coder_type == AUDIO && !st->GSC_noisy_speech ) ); @@ -1123,7 +1119,7 @@ ivas_error acelp_core_dec( if ( st->element_mode != IVAS_CPE_TD ) { /*Noise estimate*/ -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT ApplyFdCng( syn, NULL, realBuffer, imagBuffer, st, 0, ( st->coder_type == AUDIO && !st->GSC_noisy_speech ) ); #else ApplyFdCng( syn, realBuffer, imagBuffer, st, 0, ( st->coder_type == AUDIO && !st->GSC_noisy_speech ) ); @@ -1192,7 +1188,7 @@ ivas_error acelp_core_dec( /*Noise estimate*/ if ( st->idchan == 0 && ( nchan_out == 2 || ( st->core_brate != FRAME_NO_DATA && st->core_brate != SID_2k40 ) ) ) { -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT ApplyFdCng( syn, NULL, realBuffer, imagBuffer, st, 0, ( st->coder_type == AUDIO && !st->GSC_noisy_speech ) ); #else ApplyFdCng( syn, realBuffer, imagBuffer, st, 0, ( st->coder_type == AUDIO && !st->GSC_noisy_speech ) ); diff --git a/lib_dec/acelp_core_switch_dec.c b/lib_dec/acelp_core_switch_dec.c index 98854527e6..9daac37b74 100644 --- a/lib_dec/acelp_core_switch_dec.c +++ b/lib_dec/acelp_core_switch_dec.c @@ -534,7 +534,7 @@ ivas_error acelp_core_switch_dec_bfi( /*-------------------------------------------------------------------* * decod_gen_voic_core_switch() * - * Decode excitation signal in the first ACELP->HQ switching frame + * Decode excitation signal in teh first ACELP->HQ switching frame *-------------------------------------------------------------------*/ static void decod_gen_voic_core_switch( diff --git a/lib_dec/amr_wb_dec.c b/lib_dec/amr_wb_dec.c index 907d90e9ab..c220c8201e 100644 --- a/lib_dec/amr_wb_dec.c +++ b/lib_dec/amr_wb_dec.c @@ -621,7 +621,7 @@ ivas_error amr_wb_dec( /*VAD only for non inactive frame*/ st->VAD = ( st->VAD && ( st->coder_type != INACTIVE ) ); -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT ApplyFdCng( syn, NULL, NULL, NULL, st, 0, 0 ); #else ApplyFdCng( syn, NULL, NULL, st, 0, 0 ); diff --git a/lib_dec/core_dec_init.c b/lib_dec/core_dec_init.c index bc8d95e24f..d2d94799ef 100644 --- a/lib_dec/core_dec_init.c +++ b/lib_dec/core_dec_init.c @@ -57,7 +57,7 @@ void open_decoder_LPD( const int32_t last_total_brate, const int16_t bwidth, const int16_t is_mct, /* i : MCT mode flag */ -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT const int16_t last_element_mode, #endif const int16_t is_init /* i : indicate call from init_decoder() to avoid double TC initialization */ @@ -552,8 +552,9 @@ void open_decoder_LPD( { st->hTcxDec->prev_widow_left_rect = 0; -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE - if ( is_init || is_mct || !( st->element_mode == IVAS_CPE_MDCT && st->element_mode == last_element_mode ) ) +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT + /* Todo: should be considered for other stereo modes as well */ + if ( is_init || !( st->element_mode == IVAS_CPE_MDCT && st->element_mode == last_element_mode ) ) { st->hTcxDec->CngLevelBackgroundTrace_bfi = PLC_MIN_CNG_LEV; st->hTcxDec->NoiseLevelIndex_bfi = PLC_MIN_STAT_BUFF_SIZE - 1; diff --git a/lib_dec/core_dec_switch.c b/lib_dec/core_dec_switch.c index c2084f3f12..637c185f32 100644 --- a/lib_dec/core_dec_switch.c +++ b/lib_dec/core_dec_switch.c @@ -57,9 +57,9 @@ void mode_switch_decoder_LPD( const int32_t last_total_brate, /* i : last frame total bitrate */ const int16_t frame_size_index, /* i : index determining the frame size*/ const int16_t is_mct /* i : MCT mode flag */ -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT , - const int16_t last_element_mode /* i : last element mode */ + const int16_t last_element_mode #endif ) { @@ -109,7 +109,7 @@ void mode_switch_decoder_LPD( if ( fscale != st->fscale || switchWB || bSwitchFromAmrwbIO || st->last_codec_mode == MODE1 || st->force_lpd_reset ) { -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT open_decoder_LPD( st, total_brate, last_total_brate, bwidth, is_mct, last_element_mode, 0 ); #else open_decoder_LPD( st, total_brate, last_total_brate, bwidth, is_mct, 0 ); diff --git a/lib_dec/core_switching_dec.c b/lib_dec/core_switching_dec.c index e8c74bc2ef..61537f76e3 100644 --- a/lib_dec/core_switching_dec.c +++ b/lib_dec/core_switching_dec.c @@ -1048,11 +1048,7 @@ void bw_switching_pre_proc( if ( st->element_mode > EVS_MONO ) { -#ifdef ALIGN_SID_SIZE - if ( st->core == ACELP_CORE && !( st->bfi == 1 && st->con_tcx == 1 ) && st->hBWE_FD != NULL && !( st->core_brate <= SID_2k40 && st->element_mode == IVAS_CPE_DFT && nchan_out == 2 ) && !( st->element_mode == IVAS_CPE_MDCT && nchan_out == 1 && st->idchan == 1 && last_element_brate <= IVAS_SID_5k2 ) ) -#else if ( st->core == ACELP_CORE && !( st->bfi == 1 && st->con_tcx == 1 ) && st->hBWE_FD != NULL && !( st->core_brate <= SID_2k40 && st->element_mode == IVAS_CPE_DFT && nchan_out == 2 ) && !( st->element_mode == IVAS_CPE_MDCT && nchan_out == 1 && st->idchan == 1 && last_element_brate <= IVAS_SID_4k4 ) ) -#endif { /* Calculate tilt of the ACELP core synthesis - needed in SWB BWE decoding */ calc_tilt_bwe( old_syn_12k8_16k, &st->tilt_wb, st->L_frame ); diff --git a/lib_dec/dec_LPD.c b/lib_dec/dec_LPD.c index a28630886e..422104ac43 100644 --- a/lib_dec/dec_LPD.c +++ b/lib_dec/dec_LPD.c @@ -478,7 +478,7 @@ void decoder_LPD( if ( bfi && st->last_core != ACELP_CORE ) { /* PLC: [TCX: TD PLC] */ -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT con_tcx( st, &synthFB[0], -1.f, NULL, 0, NULL ); #else con_tcx( st, &synthFB[0], -1.f, NULL, 0 ); @@ -650,7 +650,7 @@ void decoder_LPD( TonalMDCTConceal_SaveTimeSignal( st->hTonalMDCTConc, synthFB, L_frameTCX ); } -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT decoder_tcx_post( st, synth, synthFB, Aq, bfi, 0 ); #else decoder_tcx_post( st, synth, synthFB, Aq, bfi ); diff --git a/lib_dec/dec_acelp_tcx_main.c b/lib_dec/dec_acelp_tcx_main.c index 1ca75fff20..b1bfd3e225 100644 --- a/lib_dec/dec_acelp_tcx_main.c +++ b/lib_dec/dec_acelp_tcx_main.c @@ -198,7 +198,7 @@ static void decode_frame_type( st->rate_switching_init = 1; /* Reconf Core */ -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT mode_switch_decoder_LPD( st, st->bwidth, st->total_brate, st->last_total_brate, frame_size_index, 0, st->element_mode ); #else mode_switch_decoder_LPD( st, st->bwidth, st->total_brate, st->last_total_brate, frame_size_index, 0 ); diff --git a/lib_dec/dec_prm.c b/lib_dec/dec_prm.c index 925b561fd6..37c64f18a3 100644 --- a/lib_dec/dec_prm.c +++ b/lib_dec/dec_prm.c @@ -55,7 +55,7 @@ void getTCXMode( Decoder_State *st, /* i/o: decoder memory state */ Decoder_State *st0 /* i : bitstream */ -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT , const int16_t MCT_flag #endif @@ -94,7 +94,7 @@ void getTCXMode( } st->coder_type = INACTIVE; -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT if ( st->element_mode == IVAS_CPE_MDCT && !MCT_flag ) { st->VAD = get_next_indice( st0, 1 ); @@ -793,7 +793,7 @@ void dec_prm( *--------------------------------------------------------------------------------*/ /* Modes (ACE_GC, ACE_UC, TCX20, TCX10...) */ -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT getTCXMode( st, st, 0 /* <- MCT_flag */ ); #else getTCXMode( st, st ); diff --git a/lib_dec/dec_tcx.c b/lib_dec/dec_tcx.c index 502433517e..ae5faa4d73 100644 --- a/lib_dec/dec_tcx.c +++ b/lib_dec/dec_tcx.c @@ -98,9 +98,13 @@ void decoder_tcx( init_tcx_info( st, L_frame_glob, L_frameTCX_glob, frame_cnt, bfi, &tcx_offset, &tcx_offsetFB, &L_frame, &L_frameTCX, &left_rect, &L_spec ); +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT + decoder_tcx_invQ( st, prm, A, Aind, L_spec, L_frame, L_frameTCX, &x[0], &gainlpc2[0], &xn_buf[0], &fUseTns, &tnsData, &gain_tcx, &prm_sqQ, &nf_seed, bfi, 0, /* <- isMCT */ frame_cnt ); +#else decoder_tcx_invQ( st, prm, A, Aind, L_spec, L_frame, L_frameTCX, &x[0], &gainlpc2[0], &xn_buf[0], &fUseTns, &tnsData, &gain_tcx, &prm_sqQ, &nf_seed, bfi, frame_cnt ); +#endif -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT decoder_tcx_noisefilling( st, NULL, A, L_frameTCX_glob, L_spec, L_frame, L_frameTCX, &x[0], &gainlpc2[0], &tmp_concealment_method, gain_tcx, prm_sqQ, nf_seed, bfi, 0, frame_cnt ); #else decoder_tcx_noisefilling( st, A, L_frameTCX_glob, L_spec, L_frame, L_frameTCX, &x[0], &gainlpc2[0], &tmp_concealment_method, gain_tcx, prm_sqQ, nf_seed, bfi, frame_cnt ); @@ -129,7 +133,7 @@ void decoder_tcx_post( float *synthFB, float *A, const int16_t bfi -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT , const int16_t isMCT #endif @@ -184,7 +188,7 @@ void decoder_tcx_post( /* PLC: [TCX: Fade-out] * PLC: update or retrieve the background level */ -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT if ( bfi == 0 && st->tcxonly && ( st->element_mode != IVAS_CPE_MDCT || isMCT ) && st->clas_dec == UNVOICED_CLAS ) #else if ( bfi == 0 && st->tcxonly && st->clas_dec == UNVOICED_CLAS ) @@ -202,20 +206,6 @@ void decoder_tcx_post( if ( st->tcxonly ) { gainCNG = hTcxDec->CngLevelBackgroundTrace_bfi / ( level_syn + 0.01f ); -#ifdef FADE_TO_ZERO_FOR_TOO_LONG_FRAMELOSS - - if ( st->element_mode == IVAS_CPE_MDCT && ! isMCT ) - { - if ( st->nbLostCmpt > MDCT_ST_PLC_FADEOUT_MAX_CONC_FRAME + MDCT_ST_PLC_FADEOUT_TO_ZERO_LEN ) - { - gainCNG = 0.f; - } - else if ( st->nbLostCmpt > MDCT_ST_PLC_FADEOUT_MAX_CONC_FRAME ) - { - gainCNG *= 1.f - (float) ( st->nbLostCmpt - MDCT_ST_PLC_FADEOUT_MAX_CONC_FRAME ) / MDCT_ST_PLC_FADEOUT_TO_ZERO_LEN; - } - } -#endif } else { @@ -706,6 +696,9 @@ void decoder_tcx_invQ( const int16_t **prm_sqQ1, int16_t *nf_seed, const int16_t bfi, /* i : Bad frame indicator */ +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT + const int16_t isMCT, +#endif const int16_t frame_cnt /* i : frame counter in the super frame */ ) { @@ -920,7 +913,16 @@ void decoder_tcx_invQ( hTcxDec->damping = 1; } +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT + else if ( st->element_mode == IVAS_CPE_MDCT && st->nbLostCmpt >= MDCT_ST_PLC_FADEOUT_START_FRAME ) + { + *gain_tcx = hTcxDec->old_gaintcx_bfi; + hTcxDec->damping = Damping_fact( st->coder_type, st->nbLostCmpt - MDCT_ST_PLC_FADEOUT_START_FRAME, st->last_good, st->stab_fac, &( st->lp_gainp ), st->last_core ); + } + else if ( st->element_mode != IVAS_CPE_MDCT || !isMCT ) +#else else +#endif { *gain_tcx = hTcxDec->old_gaintcx_bfi; hTcxDec->damping = Damping_fact( st->coder_type, st->nbLostCmpt, st->last_good, st->stab_fac, &( st->lp_gainp ), st->last_core ); @@ -1077,7 +1079,7 @@ void decoder_tcx_invQ( void decoder_tcx_noisefilling( Decoder_State *st, /* i/o: coder memory state */ -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT float concealment_noise[L_FRAME48k], #endif const float A[], /* i : coefficients NxAz[M+1] */ @@ -1092,7 +1094,7 @@ void decoder_tcx_noisefilling( const int16_t *prm_sqQ, int16_t nf_seed, const int16_t bfi, /* i : Bad frame indicator */ -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT const int16_t isMCT, #endif const int16_t frame_cnt /* i : frame counter in the super frame*/ @@ -1118,9 +1120,6 @@ void decoder_tcx_noisefilling( *-----------------------------------------------------------------*/ /* Init lengths */ -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE - infoIGFStartLine = get_igf_startline( st, L_frame, L_frameTCX ); -#else if ( st->igf == 0 ) { if ( st->narrowBand == 0 ) @@ -1138,7 +1137,6 @@ void decoder_tcx_noisefilling( { infoIGFStartLine = min( st->hIGFDec->infoIGFStartLine, L_frameTCX ); } -#endif noiseFillingSize = L_spec; if ( st->igf ) @@ -1250,7 +1248,7 @@ void decoder_tcx_noisefilling( if ( !bfi && st->element_mode != IVAS_CPE_MDCT ) { -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT TonalMDCTConceal_SaveFreqSignal( st->hTonalMDCTConc, x, L_frameTCX, L_frame, gainlpc2, infoIGFStartLine ); #else TonalMDCTConceal_SaveFreqSignal( st->hTonalMDCTConc, x, L_frameTCX, L_frame, gainlpc2 ); @@ -1263,8 +1261,8 @@ void decoder_tcx_noisefilling( { /* set f to 1 to not fade out */ /* set f to 0 to immediately switch to white noise */ -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE - if ( st->tcxonly && ( st->element_mode != IVAS_CPE_MDCT || isMCT ) ) +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT + if ( st->tcxonly && st->element_mode != IVAS_CPE_MDCT ) #else if ( st->tcxonly ) #endif @@ -1306,14 +1304,14 @@ void decoder_tcx_noisefilling( noiseTiltFactor = 1.0f; tcxGetNoiseFillingTilt( A, L_frame, ( total_brate >= ACELP_13k20 && !st->rf_flag ), &noiseTiltFactor ); -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT if ( st->element_mode == IVAS_CPE_MDCT && !isMCT ) { - TonalMDCTConceal_InsertNoise( st->hTonalMDCTConc, x, st->tonal_mdct_plc_active, &st->seed_tcx_plc, noiseTiltFactor, f, concealment_noise, hTcxDec->CngLevelBackgroundTrace_bfi, infoIGFStartLine ); + TonalMDCTConceal_InsertNoise( st->hTonalMDCTConc, x, st->tonal_mdct_plc_active, &st->seed_tcx_plc, noiseTiltFactor, f, concealment_noise, infoIGFStartLine ); } else { - TonalMDCTConceal_InsertNoise( st->hTonalMDCTConc, x, st->tonal_mdct_plc_active, &st->seed_tcx_plc, noiseTiltFactor, f, NULL, hTcxDec->CngLevelBackgroundTrace_bfi, infoIGFStartLine ); + TonalMDCTConceal_InsertNoise( st->hTonalMDCTConc, x, st->tonal_mdct_plc_active, &st->seed_tcx_plc, noiseTiltFactor, f, NULL, infoIGFStartLine ); } #else TonalMDCTConceal_InsertNoise( st->hTonalMDCTConc, x, st->tonal_mdct_plc_active, &st->seed_tcx_plc, noiseTiltFactor, f, infoIGFStartLine ); @@ -1395,7 +1393,7 @@ void decoder_tcx_noiseshaping_igf( * Noise shaping in frequency domain (1/Wz) * *-----------------------------------------------------------*/ -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT if ( st->igf && ( !bfi || ( st->element_mode == IVAS_CPE_MDCT && st->prev_bfi ) ) ) #else if ( st->igf && !bfi ) @@ -1945,12 +1943,7 @@ void decoder_tcx_IGF_stereo( const int16_t L_frame, /* i : frame length */ const int16_t left_rect, /* i : left part is rectangular */ const int16_t k, /* i : Subframe index */ -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE - const int16_t bfi, /* i : bad frame indicator */ - const int16_t is_mct /* i : flag to signal MCT or SMDCT */ -#else - const int16_t bfi /* i : bad frame indicator */ -#endif + const int16_t bfi /* i : bad frame indicator */ ) { int16_t coreMsMask[N_MAX]; @@ -2003,11 +1996,7 @@ void decoder_tcx_IGF_stereo( igfGridIdx = ( sts[0]->last_core == ACELP_CORE || ( left_rect && bfi ) ) ? IGF_GRID_LB_TRAN : IGF_GRID_LB_NORM; } -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE - IGFDecApplyStereo( sts[0]->hIGFDec, sts[1]->hIGFDec, x[0][k], x[1][k], igfGridIdx, coreMsMask, hStereoMdct->IGFStereoMode[k] == SMDCT_BW_MS, bfi, is_mct ); -#else IGFDecApplyStereo( sts[0]->hIGFDec, sts[1]->hIGFDec, x[0][k], x[1][k], igfGridIdx, coreMsMask, hStereoMdct->IGFStereoMode[k] == SMDCT_BW_MS, bfi ); -#endif } return; diff --git a/lib_dec/er_dec_tcx.c b/lib_dec/er_dec_tcx.c index d72e88da5f..2fb4a8979a 100644 --- a/lib_dec/er_dec_tcx.c +++ b/lib_dec/er_dec_tcx.c @@ -34,8 +34,6 @@ EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 ====================================================================================*/ -#include "cnst.h" -#include "ivas_cnst.h" #include #include #include "options.h" @@ -54,12 +52,13 @@ *-----------------------------------------------------------------*/ void con_tcx( - Decoder_State *st, /* i/o: coder memory state */ - float synth[], /* i/o: synth[] */ + Decoder_State *st, /* i/o: coder memory state */ + float synth[] /* i/o: synth[] */ + , const float coh, /* i : coherence of stereo signal */ int16_t *noise_seed, /* i/o: noise seed for stereo */ const int16_t only_left /* i : TD-PLC only in left channel */ -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT , const float *A_cng #endif @@ -281,7 +280,19 @@ void con_tcx( st->bpf_gain_param = 0; /* PLC: calculate damping factor */ - alpha = Damping_fact( st->core_ext_mode, st->nbLostCmpt, st->last_good, st->stab_fac, &( st->lp_gainp ), ACELP_CORE ); +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT + alpha = 1.0f; + if ( st->element_mode == IVAS_CPE_MDCT && st->nbLostCmpt >= MDCT_ST_PLC_FADEOUT_START_FRAME ) + { + alpha = Damping_fact( st->core_ext_mode, st->nbLostCmpt - MDCT_ST_PLC_FADEOUT_START_FRAME, st->last_good, st->stab_fac, &( st->lp_gainp ), 0 ); + } + else if ( st->element_mode != IVAS_CPE_MDCT ) + { + alpha = Damping_fact( st->core_ext_mode, st->nbLostCmpt, st->last_good, st->stab_fac, &( st->lp_gainp ), 0 ); + } +#else + alpha = Damping_fact( st->core_ext_mode, st->nbLostCmpt, st->last_good, st->stab_fac, &( st->lp_gainp ), 0 ); +#endif if ( st->nbLostCmpt == 1 ) { @@ -340,7 +351,19 @@ void con_tcx( set_f( pitch_buf, (float) L_SUBFR, st->nb_subfr ); /* PLC: calculate damping factor */ - alpha = Damping_fact( st->core_ext_mode, st->nbLostCmpt, st->last_good, st->stab_fac, &( st->lp_gainp ), ACELP_CORE ); +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT + alpha = 1.0f; + if ( st->element_mode == IVAS_CPE_MDCT && st->nbLostCmpt >= MDCT_ST_PLC_FADEOUT_START_FRAME ) + { + alpha = Damping_fact( st->core_ext_mode, st->nbLostCmpt - MDCT_ST_PLC_FADEOUT_START_FRAME, st->last_good, st->stab_fac, &( st->lp_gainp ), 0 ); + } + else if ( st->element_mode != IVAS_CPE_MDCT ) + { + alpha = Damping_fact( st->core_ext_mode, st->nbLostCmpt, st->last_good, st->stab_fac, &( st->lp_gainp ), 0 ); + } +#else + alpha = Damping_fact( st->core_ext_mode, st->nbLostCmpt, st->last_good, st->stab_fac, &( st->lp_gainp ), 0 ); +#endif } /*-----------------------------------------------------------------* @@ -437,7 +460,7 @@ void con_tcx( /* PLC: [TCX: Fade-out] retrieve background level */ tmp = 1.0f; -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT if ( A_cng != NULL ) { gainSynthDeemph = getLevelSynDeemph( &( tmp ), A_cng, L_frame / 4, st->preemph_fac, 1 ) / 4.f; @@ -452,20 +475,6 @@ void con_tcx( if ( st->tcxonly ) { gainCNG = hTcxDec->CngLevelBackgroundTrace_bfi / gainSynthDeemph; - -#ifdef FADE_TO_ZERO_FOR_TOO_LONG_FRAMELOSS - if ( st->element_mode == IVAS_CPE_MDCT && A_cng != NULL ) - { - if ( st->nbLostCmpt > MDCT_ST_PLC_FADEOUT_MAX_CONC_FRAME + MDCT_ST_PLC_FADEOUT_TO_ZERO_LEN ) - { - gainCNG = 0.f; - } - else if ( st->nbLostCmpt > MDCT_ST_PLC_FADEOUT_MAX_CONC_FRAME ) - { - gainCNG *= 1.f - (float) ( st->nbLostCmpt - MDCT_ST_PLC_FADEOUT_MAX_CONC_FRAME ) / MDCT_ST_PLC_FADEOUT_TO_ZERO_LEN; - } - } -#endif } else { @@ -561,13 +570,26 @@ void con_tcx( mvr2r( buf, mem_syn, M ); -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT if ( A_cng != NULL ) { - if ( st->plcBackgroundNoiseUpdated && alpha != 1.0f ) + if ( ( st->nbLostCmpt == 1 && st->idchan == 0 ) || ( st->nbLostCmpt == 2 && st->idchan == 1 ) ) + { + float lsp_cng[M]; + + lpc_from_spectrum( st->hFdCngDec->hFdCngCom, st->hFdCngDec->hFdCngCom->startBand, st->hFdCngDec->hFdCngCom->stopFFTbin, 0.f ); + + a2lsp_stab( st->hFdCngDec->hFdCngCom->A_cng, lsp_cng, st->lspold_cng ); + mvr2r( lsp_cng, st->lspold_cng, M ); + } + + if ( alpha != 1.0f ) { - float lsp_local[M], lsp_fade[M], alpha_inv; + float lsp_local[M]; + float lsp_fade[M]; + float alpha_inv; + wmops_sub_start( "Fade LSPs" ); alpha_inv = 1.0f - alpha; a2lsp_stab( A_local, lsp_local, lsp_local ); @@ -578,6 +600,7 @@ void con_tcx( } lsp2a_stab( lsp_fade, A_local, M ); + wmops_sub_end(); } } #endif diff --git a/lib_dec/evs_dec.c b/lib_dec/evs_dec.c old mode 100644 new mode 100755 index e03b2ff2bc..b51ed8d6ea --- a/lib_dec/evs_dec.c +++ b/lib_dec/evs_dec.c @@ -676,7 +676,7 @@ ivas_error evs_dec( st->lp_noise = st->hFdCngDec->lp_noise; -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT ApplyFdCng( output, NULL, realBuffer, imagBuffer, st, concealWholeFrame, 0 ); #else ApplyFdCng( output, realBuffer, imagBuffer, st, concealWholeFrame, 0 ); diff --git a/lib_dec/fd_cng_dec.c b/lib_dec/fd_cng_dec.c index 85d82d953c..4f0e8574f0 100644 --- a/lib_dec/fd_cng_dec.c +++ b/lib_dec/fd_cng_dec.c @@ -368,7 +368,7 @@ void deleteFdCngDec( void ApplyFdCng( float *timeDomainInput, -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT float *powerSpectrum, #endif float **realBuffer, /* i/o: Real part of the buffer */ @@ -384,7 +384,7 @@ void ApplyFdCng( int16_t j, k; float factor; float lsp_cng[M]; -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT int16_t L_frame, last_L_frame; int32_t sr_core; @@ -419,7 +419,7 @@ void ApplyFdCng( /* set noise estimation inactive during concealment, as no update with noise generated by concealment should be performed. */ /* set noise estimation inactive when we have bit errors, as no update with noise generated by corrupt frame (biterror) should be performed. */ if ( concealWholeFrame == 0 && -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT ( timeDomainInput == NULL || ( *timeDomainInput( -FLT_MAX ) && *( timeDomainInput + hFdCngCom->frameSize - 1 ) < FLT_MAX && @@ -435,7 +435,7 @@ void ApplyFdCng( ( !st->BER_detect ) ) { /* Perform noise estimation at the decoder */ -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT perform_noise_estimation_dec( timeDomainInput, powerSpectrum, hFdCngDec, st->element_mode, st->bwidth, L_frame, last_L_frame, st->last_core_brate, st->VAD ); #else perform_noise_estimation_dec( timeDomainInput, hFdCngDec, st->element_mode, st->bwidth, st->L_frame, st->last_L_frame, st->last_core_brate, st->VAD ); @@ -471,7 +471,7 @@ void ApplyFdCng( } } -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT if ( st->element_mode == IVAS_CPE_MDCT && timeDomainInput == NULL ) { st->hTcxDec->CngLevelBackgroundTrace_bfi = sqrtf( sum_f( cngNoiseLevel, hFdCngCom->stopFFTbin - hFdCngCom->startBand ) / NORM_MDCT_FACTOR ); @@ -488,7 +488,7 @@ void ApplyFdCng( if ( hFdCngCom->active_frame_counter > 0 ) { /* Perform noise estimation in active frames in the decoder for downward updates */ -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT perform_noise_estimation_dec( timeDomainInput, powerSpectrum, hFdCngDec, st->element_mode, st->bwidth, L_frame, last_L_frame, st->last_core_brate, st->VAD ); #else perform_noise_estimation_dec( timeDomainInput, hFdCngDec, st->element_mode, st->bwidth, st->L_frame, st->last_L_frame, st->last_core_brate, st->VAD ); @@ -496,47 +496,65 @@ void ApplyFdCng( } } -#ifndef MDCT_STEREO_PLC_FADE_2_BG_NOISE if ( ( concealWholeFrame == 1 ) && ( st->nbLostCmpt == 1 ) && sum_f( cngNoiseLevel + hFdCngCom->startBand, hFdCngCom->stopFFTbin - hFdCngCom->startBand ) > 0.01f ) { +#ifndef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT /* update lsf cng estimate for concealment. Do that during concealment, in order to avoid addition clean channel complexity*/ lpc_from_spectrum( hFdCngCom, hFdCngCom->startBand, hFdCngCom->stopFFTbin, 0 ); #else - if ( ( concealWholeFrame == 1 ) && ( st->nbLostCmpt == 1 ) ) - { - /* update lsf cng estimate for concealment. Do that during concealment, in order to avoid addition clean channel complexity*/ - - /* always set psychParameters for MDCT-Stereo ... */ - if ( st->element_mode == IVAS_CPE_MDCT && st->hTonalMDCTConc != NULL ) + if ( st->element_mode == IVAS_CPE_MDCT && st->core != ACELP_CORE ) { - st->hTonalMDCTConc->psychParams = ( st->core == TCX_20_CORE ) ? &st->hTonalMDCTConc->psychParamsTCX20 : &st->hTonalMDCTConc->psychParamsTCX10; - } + float scf[SNS_NPTS]; + float scf_int[FDNS_NPTS]; + float whitenend_noise_shape[L_FRAME16k]; + int16_t inc, start_idx, stop_idx; + float *noiseLevelPtr; - /* ... but do actual computations only if sufficient energy in noise shape */ - if ( sum_f( cngNoiseLevel + hFdCngCom->startBand, hFdCngCom->stopFFTbin - hFdCngCom->startBand ) > 0.01f ) - { - if ( st->element_mode == IVAS_CPE_MDCT && st->core != ACELP_CORE ) + wmops_sub_start( "get scfs for bg" ); + + inc = ( st->core > TCX_20 ) ? 2 : 1; + start_idx = hFdCngCom->startBand / inc; + stop_idx = L_frame / inc; + noiseLevelPtr = cngNoiseLevel; + + set_zero( whitenend_noise_shape, start_idx ); + for ( j = start_idx; j < stop_idx; j++, noiseLevelPtr += inc ) { - TonalMdctConceal_whiten_noise_shape( st, L_frame, ON_FIRST_LOST_FRAME ); + whitenend_noise_shape[j] = *noiseLevelPtr; } - else if ( st->element_mode != IVAS_CPE_MDCT || st->core == ACELP_CORE ) + if ( st->core == TCX_20_CORE ) { - lpc_from_spectrum( hFdCngCom, hFdCngCom->startBand, hFdCngCom->stopFFTbin, 0.f ); - a2lsp_stab( hFdCngCom->A_cng, lsp_cng, st->lspold_cng ); - mvr2r( lsp_cng, st->lspold_cng, M ); - lsp2lsf( lsp_cng, st->lsf_cng, M, sr_core ); + st->hTonalMDCTConc->psychParams = &st->hTonalMDCTConc->psychParamsTCX20; } - st->plcBackgroundNoiseUpdated = 1; + else + { + st->hTonalMDCTConc->psychParams = &st->hTonalMDCTConc->psychParamsTCX10; + } + + sns_compute_scf( whitenend_noise_shape, st->hTonalMDCTConc->psychParams, L_frame, scf ); + sns_interpolate_scalefactors( scf_int, scf, ENC ); + sns_interpolate_scalefactors( st->hTonalMDCTConc->scaleFactorsBackground, scf, DEC ); + sns_shape_spectrum( whitenend_noise_shape, st->hTonalMDCTConc->psychParams, scf_int, L_frame ); + + mvr2r( whitenend_noise_shape + start_idx, cngNoiseLevel, stop_idx - start_idx ); + wmops_sub_end(); + } + else if ( st->element_mode != IVAS_CPE_MDCT ) + { + lpc_from_spectrum( hFdCngCom, hFdCngCom->startBand, hFdCngCom->stopFFTbin, 0.f ); + a2lsp_stab( hFdCngCom->A_cng, lsp_cng, st->lspold_cng ); + mvr2r( lsp_cng, st->lspold_cng, M ); + lsp2lsf( lsp_cng, st->lsf_cng, M, sr_core ); } #endif -#ifndef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifndef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT a2lsp_stab( hFdCngCom->A_cng, lsp_cng, st->lspold_cng ); mvr2r( lsp_cng, st->lspold_cng, M ); lsp2lsf( lsp_cng, st->lsf_cng, M, st->sr_core ); - st->plcBackgroundNoiseUpdated = 1; #endif + st->plcBackgroundNoiseUpdated = 1; } break; @@ -549,7 +567,7 @@ void ApplyFdCng( if ( st != NULL && st->cng_type == LP_CNG ) { /* Perform noise estimation on inactive phase at the decoder */ -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT perform_noise_estimation_dec( timeDomainInput, powerSpectrum, hFdCngDec, st->element_mode, st->bwidth, L_frame, last_L_frame, st->last_core_brate, st->VAD ); #else perform_noise_estimation_dec( timeDomainInput, hFdCngDec, st->element_mode, st->bwidth, st->L_frame, st->last_L_frame, st->last_core_brate, st->VAD ); @@ -564,7 +582,7 @@ void ApplyFdCng( /* This sets the new CNG levels until a SID update overwrites it */ mvr2r( hFdCngDec->bandNoiseShape, cngNoiseLevel, hFdCngCom->stopFFTbin - hFdCngCom->startBand ); /* This sets the new CNG levels until a SID update overwrites it */ -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT st->cngTDLevel = (float) sqrt( ( sum_f( cngNoiseLevel, hFdCngCom->stopFFTbin - hFdCngCom->startBand ) / 2 * hFdCngCom->fftlen ) / L_frame ); #else st->cngTDLevel = (float) sqrt( ( sum_f( cngNoiseLevel, hFdCngCom->stopFFTbin - hFdCngCom->startBand ) / 2 * hFdCngCom->fftlen ) / st->L_frame ); @@ -650,7 +668,7 @@ void ApplyFdCng( default: break; } -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT wmops_sub_end(); #endif @@ -667,7 +685,7 @@ void ApplyFdCng( void perform_noise_estimation_dec( const float *timeDomainInput, -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT float *power_spectrum, #endif HANDLE_FD_CNG_DEC hFdCngDec, /* i/o: FD_CNG structure containing all buffers and variables */ @@ -702,7 +720,7 @@ void perform_noise_estimation_dec( float temp, ftemp, delta; float wght; -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT if ( !( element_mode == IVAS_CPE_MDCT && power_spectrum != NULL ) ) { /* Perform STFT analysis */ @@ -944,7 +962,7 @@ void perform_noise_estimation_dec( } else { -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT if ( element_mode == IVAS_CPE_MDCT && power_spectrum != NULL ) { /* use power spectrum calculated in the MDCT-domain instead of calculating new power spectrum */ @@ -2081,10 +2099,6 @@ void FdCngDecodeMDCTStereoSID( msvq_dec( cdk_37bits_ivas, NULL, NULL, stages, N, FD_CNG_maxN_37bits, indices, ms_ptr[ch], NULL ); } -#ifdef ALIGN_SID_SIZE - dtx_read_padding_bits( sts[1], ( IVAS_SID_5k2 - 4400 ) / FRAMES_PER_SEC ); -#endif - if ( sts[0]->hFdCngDec->hFdCngCom->no_side_flag ) { set_zero( ms_ptr[1], NPART ); @@ -2108,11 +2122,7 @@ void FdCngDecodeMDCTStereoSID( lpc_from_spectrum( hFdCngCom, hFdCngCom->startBand, hFdCngCom->stopFFTbin, sts[ch]->preemph_fac ); } -#ifdef ALIGN_SID_SIZE - if ( hCPE->nchan_out == 1 && hCPE->last_element_brate <= IVAS_SID_5k2 ) -#else if ( hCPE->nchan_out == 1 && hCPE->last_element_brate <= IVAS_SID_4k4 ) -#endif { /* create proper M noise shape in channel zero after gains have been applied */ for ( p = 0; p < N; p++ ) diff --git a/lib_dec/igf_dec.c b/lib_dec/igf_dec.c index fecc8e96df..55e526d665 100644 --- a/lib_dec/igf_dec.c +++ b/lib_dec/igf_dec.c @@ -679,12 +679,7 @@ static void IGF_appl( float *pSpectralData, /* i/o: Q31 | MDCT spectrum */ const float *igf_spec, /* i : Q31 | prepared IGF spectrum */ float *virtualSpec, /* o : Q31 | virtual IGF spectrum, used for temp flattening */ -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE - int16_t *flag_sparse, /* o : Q0 | temp flattening indicator */ - const int16_t bfi_apply_damping /* i : flag to indicate if damping for lost frames should be applied */ -#else int16_t *flag_sparse /* o : Q0 | temp flattening indicator */ -#endif ) { H_IGF_GRID hGrid; @@ -860,11 +855,7 @@ static void IGF_appl( for ( sfb = start_sfb; sfb < stop_sfb; sfb++ ) { -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE - if ( bfi_apply_damping && hPrivateData->frameLossCounter > 0 ) -#else if ( hPrivateData->frameLossCounter > 0 ) -#endif { gain[sfb] = min( gain[sfb], 12.f ); @@ -1221,11 +1212,7 @@ void IGFDecApplyMono( /* apply IGF in three steps: */ IGF_prep( hPrivateData, igfGridIdx, hIGFDec->infoTCXNoise, igf_spec, hPrivateData->pSpecFlat, element_mode ); IGF_calc( hPrivateData, igfGridIdx, spectrum, igf_spec ); -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE - IGF_appl( hPrivateData, igfGridIdx, spectrum, igf_spec, hIGFDec->virtualSpec, hIGFDec->flag_sparse, 1 ); -#else IGF_appl( hPrivateData, igfGridIdx, spectrum, igf_spec, hIGFDec->virtualSpec, hIGFDec->flag_sparse ); -#endif } /* reset TCX noise indicator vector */ @@ -1251,12 +1238,7 @@ void IGFDecApplyStereo( const int16_t igfGridIdx, /* i : in case of CELP->TCX switching, use 1.25 framelength */ const int16_t *coreMsMask, const int16_t restrict_hopsize, -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE - const int16_t bfi, /* i : frame loss == 1, frame good == 0 */ - const int16_t bfi_apply_damping -#else const int16_t bfi /* i : frame loss == 1, frame good == 0 */ -#endif ) { IGF_DEC_PRIVATE_DATA_HANDLE hPrivateDataL, hPrivateDataR; @@ -1353,13 +1335,8 @@ void IGFDecApplyStereo( IGF_calc( hPrivateDataL, igfGridIdx, spectrumL, igf_specL ); IGF_calc( hPrivateDataR, igfGridIdx, spectrumR, igf_specR ); -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE - IGF_appl( hPrivateDataL, igfGridIdx, spectrumL, igf_specL, hIGFDecL->virtualSpec, hIGFDecL->flag_sparse, bfi_apply_damping ); - IGF_appl( hPrivateDataR, igfGridIdx, spectrumR, igf_specR, hIGFDecR->virtualSpec, hIGFDecR->flag_sparse, bfi_apply_damping ); -#else IGF_appl( hPrivateDataL, igfGridIdx, spectrumL, igf_specL, hIGFDecL->virtualSpec, hIGFDecL->flag_sparse ); IGF_appl( hPrivateDataR, igfGridIdx, spectrumR, igf_specR, hIGFDecR->virtualSpec, hIGFDecR->flag_sparse ); -#endif } /* reset TCX noise indicator vector */ @@ -1611,34 +1588,3 @@ void init_igf_dec( return; } - -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE -int16_t get_igf_startline( - Decoder_State *st, - int16_t L_frame, - int16_t L_frameTCX -) -{ - int16_t igf_startline; - - if ( st->igf == 0 ) - { - if ( st->narrowBand == 0 ) - { - /* minimum needed for output with sampling rates lower then the - nominal sampling rate */ - igf_startline = min( L_frameTCX, L_frame ); - } - else - { - igf_startline = L_frameTCX; - } - } - else - { - igf_startline = min( st->hIGFDec->infoIGFStartLine, L_frameTCX ); - } - - return igf_startline; -} -#endif diff --git a/lib_dec/init_dec.c b/lib_dec/init_dec.c index 2e31017eaa..40c65d9503 100644 --- a/lib_dec/init_dec.c +++ b/lib_dec/init_dec.c @@ -54,7 +54,7 @@ ivas_error init_decoder( Decoder_State *st, /* o : Decoder static variables structure */ const int16_t idchan /* i : channel ID */ -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT , const MC_MODE mc_mode /* i : MC mode */ #endif @@ -691,7 +691,7 @@ ivas_error init_decoder( st->enablePlcWaveadjust = 0; /* Init Core Decoder */ -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT open_decoder_LPD( st, st->total_brate, st->last_total_brate, st->bwidth, 0, st->element_mode, 1 ); #else open_decoder_LPD( st, st->total_brate, st->last_total_brate, st->bwidth, 0, 1 ); @@ -714,7 +714,7 @@ ivas_error init_decoder( * FD-CNG decoder *-----------------------------------------------------------------*/ -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT if ( ( st->element_mode == IVAS_CPE_MDCT || idchan == 0 ) && mc_mode != MC_MODE_MCT ) #else if ( idchan == 0 && st->element_mode != IVAS_CPE_MDCT ) diff --git a/lib_dec/ivas_core_dec.c b/lib_dec/ivas_core_dec.c old mode 100644 new mode 100755 index ad350f4e30..de87b4c557 --- a/lib_dec/ivas_core_dec.c +++ b/lib_dec/ivas_core_dec.c @@ -35,7 +35,7 @@ #ifdef DEBUGGING #include "debug.h" #endif -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT #include #endif #include @@ -183,7 +183,7 @@ ivas_error ivas_core_dec( st->flagGuidedAcelp = 0; } -#ifndef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifndef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT /* PLC: [TCX: Fade-out-recovery] - overlapping part needs to be attenuated for first good frame */ if ( !st->bfi && st->prev_bfi && ( st->last_core_bfi == TCX_20_CORE || st->last_core_bfi == TCX_10_CORE ) && st->element_mode != IVAS_CPE_MDCT ) { @@ -201,7 +201,7 @@ ivas_error ivas_core_dec( } #else /* PLC: [TCX: Fade-out-recovery] - overlapping part needs to be attenuated for first good frame */ - if ( !st->bfi && st->prev_bfi && ( st->last_core_bfi == TCX_20_CORE || st->last_core_bfi == TCX_10_CORE ) && hMCT == NULL ) + if ( !st->bfi && st->prev_bfi && ( st->last_core_bfi == TCX_20_CORE || st->last_core_bfi == TCX_10_CORE ) ) { float gain; if ( st->hPlcInfo != NULL ) @@ -428,21 +428,6 @@ ivas_error ivas_core_dec( { updateBuffersForDmxMdctStereo( hCPE, output_frame, output, synth ); } - -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE - if ( sts[0]->bfi == 0 && sts[0]->prev_bfi == 1 ) - { - /* On first good frame after frameloss undo the whitening of the bg noise shape */ - for ( n = 0; n < n_channels; ++n ) - { - if ( sts[n]->last_core_bfi != ACELP_CORE ) - { - TonalMdctConceal_whiten_noise_shape( sts[n], L_FRAME16k, ON_FIRST_GOOD_FRAME ); - } - } - } -#endif - } /*---------------------------------------------------------------------* diff --git a/lib_dec/ivas_cpe_dec.c b/lib_dec/ivas_cpe_dec.c index da0911ee5b..7223b38761 100644 --- a/lib_dec/ivas_cpe_dec.c +++ b/lib_dec/ivas_cpe_dec.c @@ -160,22 +160,14 @@ ivas_error ivas_cpe_dec( if ( hCPE->element_mode != IVAS_CPE_MDCT && ( hCPE->element_brate != hCPE->last_element_brate || hCPE->last_element_mode != hCPE->element_mode || sts[0]->ini_frame == 0 || ( ivas_total_brate != st_ivas->hDecoderConfig->last_ivas_total_brate ) ) ) { -#ifdef ALIGN_SID_SIZE - if ( st_ivas->hQMetaData != NULL && ivas_total_brate > IVAS_SID_5k2 ) -#else if ( st_ivas->hQMetaData != NULL && ivas_total_brate > IVAS_SID_4k4 ) -#endif { stereo_dft_config( hCPE->hStereoDft == NULL ? NULL : hCPE->hStereoDft->hConfig, st_ivas->hQMetaData->bits_frame_nominal * FRAMES_PER_SEC, &sts[0]->bits_frame_nominal, &sts[1]->bits_frame_nominal ); } else { /* Note: This only works for stereo operation. If DTX would be applied for multiple CPEs a different bitrate signaling is needed */ -#ifdef ALIGN_SID_SIZE - if ( ivas_total_brate <= IVAS_SID_5k2 ) -#else if ( ivas_total_brate <= IVAS_SID_4k4 ) -#endif { stereo_dft_config( hCPE->hStereoDft == NULL ? NULL : hCPE->hStereoDft->hConfig, ivas_total_brate, &sts[0]->bits_frame_nominal, &sts[1]->bits_frame_nominal ); } @@ -211,11 +203,7 @@ ivas_error ivas_cpe_dec( /* Update DFT Stereo memories */ stereo_dft_dec_update( hCPE->hStereoDft, output_frame, 0 ); -#ifdef ALIGN_SID_SIZE - if ( st_ivas->ivas_format == MASA_FORMAT && ivas_total_brate <= IVAS_SID_5k2 ) -#else if ( st_ivas->ivas_format == MASA_FORMAT && ivas_total_brate <= IVAS_SID_4k4 ) -#endif { if ( ivas_total_brate == FRAME_NO_DATA ) { @@ -232,21 +220,13 @@ ivas_error ivas_cpe_dec( nb_bits = (int16_t) ( ( hCPE->element_brate ) / FRAMES_PER_SEC - 0.8f * sts[0]->bits_frame_nominal ); sts[1]->bit_stream = sts[0]->bit_stream + ivas_total_brate / FRAMES_PER_SEC - 1 - nb_bits_metadata; -#ifdef ALIGN_SID_SIZE - if ( ivas_total_brate == IVAS_SID_5k2 ) -#else if ( ivas_total_brate == IVAS_SID_4k4 ) -#endif { nb_bits -= SID_FORMAT_NBITS; sts[1]->bit_stream -= SID_FORMAT_NBITS; } -#ifdef ALIGN_SID_SIZE - if ( st_ivas->ivas_format == MASA_FORMAT && ivas_total_brate < MASA_STEREO_MIN_BITRATE && ivas_total_brate > IVAS_SID_5k2 ) -#else if ( st_ivas->ivas_format == MASA_FORMAT && ivas_total_brate < MASA_STEREO_MIN_BITRATE && ivas_total_brate > IVAS_SID_4k4 ) -#endif { sts[0]->total_brate = hCPE->element_brate; /* Only mono downmix was transmitted in this case */ } @@ -286,11 +266,7 @@ ivas_error ivas_cpe_dec( /* this is just for initialization, the true values of "total_brate" and "bits_frame_channel" are set later */ for ( n = 0; n < n_channels; n++ ) { -#ifdef ALIGN_SID_SIZE - if ( ivas_total_brate == IVAS_SID_5k2 ) -#else if ( ivas_total_brate == IVAS_SID_4k4 || ivas_total_brate == IVAS_SID_5k ) -#endif { sts[n]->total_brate = SID_2k40; @@ -307,11 +283,7 @@ ivas_error ivas_cpe_dec( if ( !st_ivas->hMCT ) { -#ifdef ALIGN_SID_SIZE - if ( st_ivas->ivas_format == SBA_FORMAT && ivas_total_brate == IVAS_SID_5k2 ) -#else if ( st_ivas->ivas_format == SBA_FORMAT && ivas_total_brate == IVAS_SID_5k ) -#endif { for ( n = 0; n < n_channels; n++ ) { @@ -615,11 +587,7 @@ ivas_error create_cpe_dec( hCPE->nchan_out = min( CPE_CHANNELS, st_ivas->hDecoderConfig->nchan_out ); } -#ifdef ALIGN_SID_SIZE - if ( st_ivas->ivas_format == MASA_FORMAT && st_ivas->hDecoderConfig->ivas_total_brate < MASA_STEREO_MIN_BITRATE && st_ivas->hDecoderConfig->ivas_total_brate > IVAS_SID_5k2 ) -#else if ( st_ivas->ivas_format == MASA_FORMAT && st_ivas->hDecoderConfig->ivas_total_brate < MASA_STEREO_MIN_BITRATE && st_ivas->hDecoderConfig->ivas_total_brate > IVAS_SID_4k4 ) -#endif { hCPE->nchan_out = 1; } @@ -718,7 +686,7 @@ ivas_error create_cpe_dec( st->mct_chan_mode = MCT_CHAN_MODE_LFE; } -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT if ( ( error = init_decoder( st, n, st_ivas->mc_mode ) ) != IVAS_ERR_OK ) #else if ( ( error = init_decoder( st, n ) ) != IVAS_ERR_OK ) @@ -823,12 +791,6 @@ ivas_error create_cpe_dec( set_s( hCPE->hStereoMdct->prev_ms_mask[0], 0, MAX_SFB ); set_s( hCPE->hStereoMdct->prev_ms_mask[1], 0, MAX_SFB ); hCPE->hStereoMdct->lastCoh = 1.f; -#ifdef FIX_135_MDCT_STEREO_MODE_UNINITIALIZED - hCPE->hStereoMdct->mdct_stereo_mode[0] = SMDCT_DUAL_MONO; - hCPE->hStereoMdct->mdct_stereo_mode[1] = SMDCT_DUAL_MONO; - hCPE->hStereoMdct->IGFStereoMode[0] = -1; - hCPE->hStereoMdct->IGFStereoMode[1] = -1; -#endif } /*-----------------------------------------------------------------* @@ -961,11 +923,7 @@ static void read_stereo_mode_and_bwidth( * BFI or NO_DATA frame: Use stereo parameters from last (active) frame *-----------------------------------------------------------------*/ -#ifdef ALIGN_SID_SIZE - if ( st_ivas->bfi || st_ivas->hDecoderConfig->ivas_total_brate < IVAS_SID_5k2 ) -#else if ( st_ivas->bfi || st_ivas->hDecoderConfig->ivas_total_brate < IVAS_SID_4k4 ) -#endif { hCPE->element_mode = hCPE->last_element_mode; @@ -975,11 +933,7 @@ static void read_stereo_mode_and_bwidth( * SID frame: get element mode from SID side info *-----------------------------------------------------------------*/ -#ifdef ALIGN_SID_SIZE - else if ( st_ivas->hDecoderConfig->ivas_total_brate == IVAS_SID_5k2 ) -#else else if ( st_ivas->hDecoderConfig->ivas_total_brate == IVAS_SID_4k4 || st_ivas->hDecoderConfig->ivas_total_brate == IVAS_SID_5k ) -#endif { switch ( st_ivas->sid_format ) { @@ -997,7 +951,7 @@ static void read_stereo_mode_and_bwidth( hCPE->element_mode = IVAS_CPE_MDCT; break; case SID_SBA_1TC: - assert( "Forbidden value for SID format in CPE (SBA 1TC), should have already been adressed earlier" ); + assert( "Forbidden value for sid format in CPE (SBA 1TC), should have already been adressed earlier" ); break; case SID_MASA_1TC: hCPE->element_mode = IVAS_SCE; diff --git a/lib_dec/ivas_dec.c b/lib_dec/ivas_dec.c index 7d54047014..a103c9f45f 100644 --- a/lib_dec/ivas_dec.c +++ b/lib_dec/ivas_dec.c @@ -290,11 +290,8 @@ ivas_error ivas_dec( nchan_remapped = CPE_CHANNELS; ivas_sba_dirac_stereo_dec( st_ivas, output, output_frame ); } -#ifdef ALIGN_SID_SIZE - 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 ) ) ) -#else - else if ( st_ivas->ivas_format == MASA_FORMAT && ivas_total_brate < MASA_STEREO_MIN_BITRATE && ( ivas_total_brate > IVAS_SID_4k4 || ( ivas_total_brate <= IVAS_SID_4k4 && st_ivas->nCPE > 0 && st_ivas->hCPE[0]->nchan_out == 1 ) ) ) -#endif + else if ( st_ivas->ivas_format == MASA_FORMAT && ivas_total_brate < MASA_STEREO_MIN_BITRATE && + ( ivas_total_brate > IVAS_SID_4k4 || ( ivas_total_brate <= IVAS_SID_4k4 && st_ivas->nCPE > 0 && st_ivas->hCPE[0]->nchan_out == 1 ) ) ) { nchan_remapped = 1; /* Only one channel transported */ } @@ -312,7 +309,7 @@ ivas_error ivas_dec( if ( st_ivas->sba_mode == SBA_MODE_SPAR && ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) ) { - ivas_sba_mix_matrix_determiner( st_ivas->hSpar, output, st_ivas->bfi, nchan_remapped, output_frame ); + ivas_sba_mix_matrix_determiner( st_ivas, output, nchan_remapped, output_frame ); } } @@ -348,7 +345,7 @@ ivas_error ivas_dec( } else /* SBA_MODE_SPAR */ { - ivas_sba_upmixer_renderer( st_ivas, output, output_frame ); /* Note: ivas_sba_linear_renderer() or ivas_dirac_dec() are called internally */ + ivas_sba_upmixer_renderer( st_ivas, output, nchan_remapped, output_frame ); /* Note: ivas_sba_linear_renderer() or ivas_dirac_dec() are called internally */ } } else if ( st_ivas->ivas_format == MC_FORMAT ) @@ -574,11 +571,7 @@ ivas_error ivas_dec( st_ivas->ini_frame++; } -#ifdef ALIGN_SID_SIZE - 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 */ -#else - if ( st_ivas->ini_active_frame < MAX_FRAME_COUNTER && !( st_ivas->bfi && st_ivas->ini_frame == 0 ) && ivas_total_brate > IVAS_SID_4k4 ) /* needed in MASA decoder in case the first active frame is BFI, and there were SID-frames decoded before */ -#endif + if ( st_ivas->ini_active_frame < MAX_FRAME_COUNTER && !( st_ivas->bfi && st_ivas->ini_frame == 0 ) && ivas_total_brate > IVAS_SID_4k4 ) // VE: looks strange: ini_frame -> ini_frame_active ? { st_ivas->ini_active_frame++; } diff --git a/lib_dec/ivas_dirac_dec.c b/lib_dec/ivas_dirac_dec.c old mode 100644 new mode 100755 index ef4527ea8f..074f635133 --- a/lib_dec/ivas_dirac_dec.c +++ b/lib_dec/ivas_dirac_dec.c @@ -186,15 +186,14 @@ ivas_error ivas_dirac_dec_config( nchan_transport_orig = st_ivas->nchan_transport; if ( st_ivas->ivas_format == SBA_FORMAT && st_ivas->sba_mode == SBA_MODE_SPAR && !( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) ) { +#ifdef SBA_ORDER_BITSTREAM st_ivas->nchan_transport = ivas_sba_get_nchan_metadata( st_ivas->sba_analysis_order ); +#else + st_ivas->nchan_transport = ivas_sba_get_nchan_metadata( st_ivas->sba_order ); +#endif } - nchan_transport = st_ivas->nchan_transport; -#ifdef ALIGN_SID_SIZE - if ( st_ivas->ivas_format == MASA_FORMAT && ivas_total_brate < MASA_STEREO_MIN_BITRATE && ivas_total_brate > IVAS_SID_5k2 ) -#else if ( st_ivas->ivas_format == MASA_FORMAT && ivas_total_brate < MASA_STEREO_MIN_BITRATE && ivas_total_brate > IVAS_SID_4k4 ) -#endif { nchan_transport = 1; } @@ -202,10 +201,10 @@ ivas_error ivas_dirac_dec_config( if ( flag_config == DIRAC_RECONFIGURE && st_ivas->ivas_format == SBA_FORMAT ) { int16_t tmp1, tmp2, tmp3; -#ifdef HARMONIZE_SBA_NCHAN_TRANSPORT - ivas_sba_config( st_ivas->hDecoderConfig->last_ivas_total_brate, st_ivas->sba_analysis_order, -1, &nchan_transport_old, st_ivas->sba_planar, &tmp1, &tmp2, &tmp3 ); -#else +#ifdef SBA_ORDER_BITSTREAM ivas_sba_config( st_ivas->hDecoderConfig->last_ivas_total_brate, st_ivas->sba_analysis_order, -1, &nchan_transport_old, st_ivas->sba_planar, &tmp1, &tmp2, &tmp3, SBA_MODE_DIRAC ); +#else + ivas_sba_config( st_ivas->hDecoderConfig->last_ivas_total_brate, st_ivas->sba_order, -1, &nchan_transport_old, st_ivas->sba_planar, &tmp1, &tmp2, &tmp3, SBA_MODE_DIRAC ); #endif } @@ -764,6 +763,7 @@ ivas_error ivas_dirac_dec_config( mvs2s( DirAC_block_grouping, hDirAC->block_grouping, MAX_PARAM_SPATIAL_SUBFRAMES + 1 ); + if ( flag_config == DIRAC_OPEN ) { hDirAC->dirac_md_buffer_length = 0; @@ -1287,11 +1287,7 @@ void ivas_dirac_dec_read_BS( int16_t next_bit_pos_orig; *nb_bits = 0; -#ifdef ALIGN_SID_SIZE - if ( !st->bfi && ivas_total_brate > IVAS_SID_5k2 ) -#else if ( !st->bfi && ivas_total_brate > IVAS_SID_4k4 ) -#endif { next_bit_pos_orig = st->next_bit_pos; st->next_bit_pos = (int16_t) ( ivas_total_brate / FRAMES_PER_SEC - 1 ); @@ -1300,19 +1296,14 @@ void ivas_dirac_dec_read_BS( b = st->bit_stream[( st->next_bit_pos )--]; ( *nb_bits )++; -#ifndef ALIGN_SID_SIZE if ( sba_mode == SBA_MODE_SPAR ) { - if ( ivas_total_brate == IVAS_SID_5k ) { b = 1; } } else -#else - if ( sba_mode != SBA_MODE_SPAR ) -#endif { assert( ( b == 0 ) || ( hQMetaData->q_direction[0].cfg.start_band > 0 ) ); } @@ -1400,23 +1391,12 @@ void ivas_dirac_dec_read_BS( st->next_bit_pos = next_bit_pos_orig; } -#ifdef ALIGN_SID_SIZE - else if ( !st->bfi && ivas_total_brate == IVAS_SID_5k2 ) -#else else if ( !st->bfi && ivas_total_brate == IVAS_SID_4k4 ) -#endif { next_bit_pos_orig = st->next_bit_pos; /* subtract mode signaling bits, since bitstream was moved after mode reading */ st->next_bit_pos = (int16_t) ( ivas_total_brate / FRAMES_PER_SEC - 1 - SID_FORMAT_NBITS ); -#ifdef ALIGN_SID_SIZE - /* 1 bit flag for SPAR/DirAC, already read in read format function */ - b = st->bit_stream[( st->next_bit_pos )--]; - ( *nb_bits )++; - hQMetaData->sba_inactive_mode = 1; - orig_dirac_bands = hQMetaData->q_direction[0].cfg.nbands; -#endif /* if we start with a SID frame, we need to init the azi/ele arrays.*/ if ( st->ini_frame == 0 ) @@ -1431,39 +1411,8 @@ void ivas_dirac_dec_read_BS( } } -#ifdef ALIGN_SID_SIZE - *nb_bits += ivas_qmetadata_dec_sid_decode( hQMetaData, st->bit_stream, &( st->next_bit_pos ), 0, NULL, SBA_FORMAT, sba_mode ); - - if ( sba_mode == SBA_MODE_SPAR ) - { - for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) - { - hQMetaData->q_direction[0].band_data[orig_dirac_bands - 1].azimuth[i] = hQMetaData->q_direction[0].band_data[1].azimuth[0]; - hQMetaData->q_direction[0].band_data[orig_dirac_bands - 1].elevation[i] = hQMetaData->q_direction[0].band_data[1].elevation[0]; - hQMetaData->q_direction[0].band_data[orig_dirac_bands - 1].energy_ratio[i] = hQMetaData->q_direction[0].band_data[1].energy_ratio[0]; - } - for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) - { - for ( j = orig_dirac_bands - 2; j >= 0; j-- ) - { - hQMetaData->q_direction[0].band_data[j].azimuth[i] = hQMetaData->q_direction[0].band_data[0].azimuth[0]; - hQMetaData->q_direction[0].band_data[j].elevation[i] = hQMetaData->q_direction[0].band_data[0].elevation[0]; - hQMetaData->q_direction[0].band_data[j].energy_ratio[i] = hQMetaData->q_direction[0].band_data[0].energy_ratio[0]; - } - } - - hQMetaData->q_direction->cfg.nbands = orig_dirac_bands; - } - else - { - *nb_bits += SID_FORMAT_NBITS; - } -#else *nb_bits += ivas_qmetadata_dec_sid_decode( hQMetaData, st->bit_stream, &( st->next_bit_pos ), 0, NULL, SBA_FORMAT, SBA_MODE_DIRAC ); - *nb_bits += SID_FORMAT_NBITS; -#endif - st->next_bit_pos = next_bit_pos_orig; } @@ -1509,11 +1458,7 @@ void ivas_qmetadata_to_dirac( q_direction = &( hQMetaData->q_direction[0] ); hDirAC->numSimultaneousDirections = hQMetaData->no_directions; -#ifdef ALIGN_SID_SIZE - if ( hMasa != NULL && ivas_total_brate > IVAS_SID_5k2 ) -#else if ( hMasa != NULL && ivas_total_brate > IVAS_SID_4k4 ) -#endif { band_mapping = hMasa->data.band_mapping; @@ -1589,11 +1534,7 @@ void ivas_qmetadata_to_dirac( nbands = hDirAC->band_grouping[hDirAC->hConfig->nbands]; band_grouping = hDirAC->band_grouping; -#ifdef ALIGN_SID_SIZE - if ( ivas_total_brate <= IVAS_SID_5k2 && sba_mode != SBA_MODE_SPAR ) -#else if ( ivas_total_brate <= IVAS_SID_4k4 && sba_mode != SBA_MODE_SPAR ) -#endif { /* SID/zero-frame: 1 direction, 5 bands, nblocks re-generated out of SID decoder*/ start_band = 0; @@ -1689,11 +1630,7 @@ void ivas_qmetadata_to_dirac( ele = min( 90, ele ); ele = max( -90, ele ); -#ifdef ALIGN_SID_SIZE - if ( ivas_total_brate > IVAS_SID_5k2 && q_direction->coherence_band_data != NULL ) -#else if ( ivas_total_brate > IVAS_SID_4k4 && q_direction->coherence_band_data != NULL ) -#endif { hDirAC->spreadCoherence[tmp_write_idx_band][b] = q_direction->coherence_band_data[qBand_idx].spread_coherence[block] / 255.0f; } @@ -1702,11 +1639,7 @@ void ivas_qmetadata_to_dirac( hDirAC->spreadCoherence[tmp_write_idx_band][b] = 0.0f; } -#ifdef ALIGN_SID_SIZE - if ( ivas_total_brate > IVAS_SID_5k2 && q_direction->coherence_band_data != NULL ) -#else if ( ivas_total_brate > IVAS_SID_4k4 && q_direction->coherence_band_data != NULL ) -#endif { hDirAC->surroundingCoherence[tmp_write_idx_band][b] = hQMetaData->surcoh_band_data[qBand_idx].surround_coherence[0] / 255.0f; } @@ -1861,11 +1794,7 @@ void ivas_dirac_dec( #ifdef DEBUG_MODE_DIRAC { -#ifdef HARMONIZE_SBA_NCHAN_TRANSPORT - int16_t n, tmp[1 * L_FRAME48k]; -#else int16_t n, tmp[DIRAC_MAX_TRANS_CHANS * L_FRAME48k]; -#endif char file_name[50] = { 0 }; const int16_t output_frame = st_ivas->output_Fs / FRAMES_PER_SEC; diff --git a/lib_dec/ivas_init_dec.c b/lib_dec/ivas_init_dec.c old mode 100644 new mode 100755 index 9ee3993b76..b12aa28e40 --- a/lib_dec/ivas_init_dec.c +++ b/lib_dec/ivas_init_dec.c @@ -122,16 +122,17 @@ ivas_error ivas_dec_setup( #ifndef SBA_ORDER_BITSTREAM st_ivas->sba_order = st_ivas->bit_stream[num_bits_read + 1]; st_ivas->sba_order += 2 * st_ivas->bit_stream[num_bits_read]; - - /* 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 ); - - num_bits_read += SBA_ORDER_BITS; -#ifdef ALIGN_SID_SIZE - if ( st_ivas->ini_frame > 0 && ivas_total_brate != st_ivas->hDecoderConfig->last_ivas_total_brate && ivas_total_brate > IVAS_SID_5k2 ) #else - if ( st_ivas->ini_frame > 0 && ivas_total_brate != st_ivas->hDecoderConfig->last_ivas_total_brate && ivas_total_brate > IVAS_SID_4k4 ) + st_ivas->hDecoderConfig->sba_order = st_ivas->bit_stream[num_bits_read + 1]; + st_ivas->hDecoderConfig->sba_order += 2 * st_ivas->bit_stream[num_bits_read]; + st_ivas->sba_analysis_order = st_ivas->hDecoderConfig->sba_order; + if ( ivas_total_brate < IVAS_256k ) + { + st_ivas->sba_analysis_order = 1; + } #endif + num_bits_read += SBA_ORDER_BITS; + if ( st_ivas->ini_frame > 0 && ivas_total_brate != st_ivas->hDecoderConfig->last_ivas_total_brate && ivas_total_brate > IVAS_SID_4k4 ) { if ( ( error = ivas_sba_dec_reconfigure( st_ivas ) ) != IVAS_ERR_OK ) { @@ -140,8 +141,8 @@ ivas_error ivas_dec_setup( } else { -#ifdef HARMONIZE_SBA_NCHAN_TRANSPORT - 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 ); +#ifndef SBA_ORDER_BITSTREAM + ivas_sba_config( ivas_total_brate, st_ivas->sba_order, -1, &( st_ivas->nchan_transport ), st_ivas->sba_planar, &st_ivas->nSCE, &st_ivas->nCPE, &st_ivas->element_mode_init, st_ivas->sba_mode ); #else 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, st_ivas->sba_mode ); #endif @@ -163,11 +164,7 @@ ivas_error ivas_dec_setup( if ( st_ivas->ini_frame > 0 ) { /* reconfigure in case a change of operation mode is detected */ -#ifdef ALIGN_SID_SIZE - if ( ( ivas_total_brate > IVAS_SID_5k2 && ivas_total_brate != st_ivas->hDecoderConfig->last_ivas_total_brate ) || ( st_ivas->ini_active_frame == 0 ) ) -#else if ( ( ivas_total_brate > IVAS_SID_4k4 && ivas_total_brate != st_ivas->hDecoderConfig->last_ivas_total_brate ) || ( st_ivas->ini_active_frame == 0 ) ) -#endif { if ( st_ivas->ini_active_frame == 0 && ivas_total_brate != FRAME_NO_DATA && ivas_total_brate < MASA_STEREO_MIN_BITRATE && st_ivas->nCPE == 1 ) { @@ -226,11 +223,7 @@ ivas_error ivas_dec_setup( } } } -#ifdef ALIGN_SID_SIZE - else if ( ivas_total_brate == IVAS_SID_5k2 ) -#else else if ( ivas_total_brate == IVAS_SID_4k4 || ivas_total_brate == IVAS_SID_5k ) -#endif { switch ( st_ivas->sid_format ) { @@ -366,11 +359,7 @@ static ivas_error ivas_read_format( break; } } -#ifdef ALIGN_SID_SIZE - else if ( !st_ivas->bfi && ivas_total_brate == IVAS_SID_5k2 ) -#else else if ( !st_ivas->bfi && ivas_total_brate == IVAS_SID_4k4 ) -#endif { /* read IVAS format in SID frame */ idx = 0; @@ -423,44 +412,27 @@ static ivas_error ivas_read_format( return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Invalid value %c found in SID format field.", st_ivas->sid_format ); } -#ifdef ALIGN_SID_SIZE - if ( st_ivas->ivas_format == SBA_FORMAT ) - { - int16_t tc_mode_offset; - tc_mode_offset = (int16_t) ( ivas_total_brate / FRAMES_PER_SEC - 1 ); - idx = st_ivas->bit_stream[tc_mode_offset]; - // TBD: needs more work for HOA - if ( st_ivas->sba_analysis_order == 0 ) - { - st_ivas->sba_analysis_order = 1; - } - if ( idx == 1 ) - { - st_ivas->sba_mode = SBA_MODE_SPAR; - } - else - { - st_ivas->sba_mode = SBA_MODE_DIRAC; - } - } -#endif - /* reset bitstream handle to avoid BER detection after reading the 2400 kbps for ch0 */ st_ivas->bit_stream += ( *num_bits_read ); ( *num_bits_read ) = 0; } -#ifndef ALIGN_SID_SIZE else if ( !st_ivas->bfi && ivas_total_brate == IVAS_SID_5k ) { int16_t tc_mode_offset; tc_mode_offset = (int16_t) ( ivas_total_brate / FRAMES_PER_SEC - 1 ); idx = st_ivas->bit_stream[tc_mode_offset]; - // TBD: needs more work for HOA +#ifndef SBA_ORDER_BITSTREAM + if ( st_ivas->sba_order == 0 ) + { + st_ivas->sba_order = 1; + } +#else if ( st_ivas->sba_analysis_order == 0 ) { st_ivas->sba_analysis_order = 1; } +#endif if ( idx == 0 ) { st_ivas->sid_format = SID_SBA_1TC; @@ -476,7 +448,6 @@ static ivas_error ivas_read_format( st_ivas->element_mode_init = IVAS_CPE_MDCT; } } -#endif else { /* In SID/NO_DATA frames, use the previous frame IVAS format */ @@ -555,6 +526,29 @@ ivas_error ivas_init_decoder_front( error = IVAS_ERR_OK; +#ifdef DEBUGGING + st_ivas->noClipping = 0; +#endif + + /* Custom loudspeaker layout structure */ + st_ivas->hLsSetupCustom = NULL; + + /* TD renderer HRTF data structure */ + st_ivas->hHrtfTD = NULL; + + /* Head track data structure */ + st_ivas->hHeadTrackData = NULL; + + /* Renderer configuration structure */ + st_ivas->hRenderConfig = NULL; + + /* HRTF binauralization latency in ns */ + st_ivas->binaural_latency_ns = 0; + +#ifdef DEBUGGING + st_ivas->hDecoderConfig->force_rend = -1; +#endif + /*-----------------------------------------------------------------* * Resets *-----------------------------------------------------------------*/ @@ -567,16 +561,9 @@ ivas_error ivas_init_decoder_front( st_ivas->mc_mode = MC_MODE_NONE; st_ivas->sba_mode = SBA_MODE_NONE; - st_ivas->sba_dirac_stereo_flag = 0; - - /* HRTF binauralization latency in ns */ - st_ivas->binaural_latency_ns = 0; - -#ifdef DEBUGGING - st_ivas->noClipping = 0; + st_ivas->hLimiter = NULL; + st_ivas->hoa_dec_mtx = NULL; - st_ivas->hDecoderConfig->force_rend = -1; -#endif /*-------------------------------------------------------------------* * Allocate and initialize Custom loudspeaker layout handle @@ -723,6 +710,58 @@ ivas_error ivas_init_decoder( } } + /*-----------------------------------------------------------------* + * Dummy pointers to decoder handles + *-----------------------------------------------------------------*/ + + for ( i = 0; i < MAX_SCE; i++ ) + { + st_ivas->hSCE[i] = NULL; + } + + for ( i = 0; i < MAX_CPE; i++ ) + { + st_ivas->hCPE[i] = NULL; + } + + /* ISm metadata handles */ + for ( n = 0; n < MAX_NUM_OBJECTS; n++ ) + { + st_ivas->hIsmMetaData[n] = NULL; + } + + /* DirAC handle */ + st_ivas->hDirAC = NULL; + st_ivas->sba_dirac_stereo_flag = 0; + + /* SPAR handle */ + st_ivas->hSpar = NULL; + + /* MASA decoder structure */ + st_ivas->hMasa = NULL; + + /* Q metadata handle */ + st_ivas->hQMetaData = NULL; + + /* MCT handles */ + st_ivas->hMCT = NULL; + st_ivas->hParamMC = NULL; + + /* LFE handle */ + st_ivas->hLFE = NULL; + + /* renderers handles */ + st_ivas->hBinRenderer = NULL; /* fastconf binaural renderer */ + st_ivas->hDiracDecBin = NULL; /* parametric binaural renderer */ + st_ivas->hLsSetUpConversion = NULL; /* MC converter */ + st_ivas->hEFAPdata = NULL; /* EFAP handle */ + st_ivas->hVBAPdata = NULL; /* VBAP handle */ + st_ivas->hIsmRendererData = NULL; /* ISm renderer */ + st_ivas->hBinRendererTd = NULL; /* TD ISm binaural renderer */ + st_ivas->hMonoDmxRenderer = NULL; /* Mono downmix renderer */ + st_ivas->hHrtf = NULL; /* Crend hrtf data */ + st_ivas->hCrend = NULL; /* Crend renderer */ + /*-----------------------------------------------------------------* * Allocate and initalize SCE/CPE and other handles *-----------------------------------------------------------------*/ @@ -759,7 +798,6 @@ ivas_error ivas_init_decoder( { reset_indices_dec( st_ivas->hCPE[cpe_id]->hCoreCoder[n] ); } - /* init EFAP for custom LS output and set hTransSetup */ if ( output_config == AUDIO_CONFIG_LS_CUSTOM ) { @@ -806,10 +844,11 @@ ivas_error ivas_init_decoder( } else if ( st_ivas->ivas_format == SBA_FORMAT || st_ivas->ivas_format == MASA_FORMAT ) { - - if ( ( error = ivas_qmetadata_open( &( st_ivas->hQMetaData ) ) ) != IVAS_ERR_OK ) { - return error; + if ( ( error = ivas_qmetadata_open( &( st_ivas->hQMetaData ) ) ) != IVAS_ERR_OK ) + { + return error; + } } if ( st_ivas->ivas_format == MASA_FORMAT ) @@ -827,7 +866,6 @@ ivas_error ivas_init_decoder( { return error; } - if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_DEC && st_ivas->hOutSetup.is_loudspeaker_setup ) { if ( ( error = ivas_sba_get_hoa_dec_matrix( st_ivas->hOutSetup, &st_ivas->hoa_dec_mtx, st_ivas->hIntSetup.ambisonics_order ) ) != IVAS_ERR_OK ) @@ -835,10 +873,9 @@ ivas_error ivas_init_decoder( return error; } } - -#ifdef HARMONIZE_SBA_NCHAN_TRANSPORT - if ( ( error = ivas_dirac_sba_config( st_ivas->hQMetaData, &st_ivas->nchan_transport, &st_ivas->nSCE, &st_ivas->nCPE, &st_ivas->element_mode_init, ivas_total_brate, st_ivas->sba_analysis_order, st_ivas->sba_mode, IVAS_MAX_NUM_BANDS - SPAR_DIRAC_SPLIT_START_BAND ) ) != IVAS_ERR_OK ) - +#ifndef SBA_ORDER_BITSTREAM + if ( ( error = ivas_dirac_sba_config( st_ivas->hQMetaData, &st_ivas->nchan_transport, &st_ivas->nSCE, &st_ivas->nCPE, &st_ivas->element_mode_init, ivas_total_brate, st_ivas->sba_order, st_ivas->sba_planar, + st_ivas->sba_mode, IVAS_MAX_NUM_BANDS - SPAR_DIRAC_SPLIT_START_BAND ) ) != IVAS_ERR_OK ) #else if ( ( error = ivas_dirac_sba_config( st_ivas->hQMetaData, &st_ivas->nchan_transport, &st_ivas->nSCE, &st_ivas->nCPE, &st_ivas->element_mode_init, ivas_total_brate, st_ivas->sba_analysis_order, st_ivas->sba_planar, st_ivas->sba_mode, IVAS_MAX_NUM_BANDS - SPAR_DIRAC_SPLIT_START_BAND ) ) != IVAS_ERR_OK ) @@ -846,14 +883,12 @@ ivas_error ivas_init_decoder( { return error; } - if ( hDecoderConfig->output_config != AUDIO_CONFIG_FOA ) { if ( ( error = ivas_dirac_dec_open( st_ivas ) ) != IVAS_ERR_OK ) { return error; } - for ( k = 0; k < DIRAC_MAX_NBANDS; k++ ) { st_ivas->hSpar->dirac_to_spar_md_bands[k] = st_ivas->hDirAC->dirac_to_spar_md_bands[k]; @@ -866,14 +901,20 @@ ivas_error ivas_init_decoder( st_ivas->hSpar->enc_param_start_band = min( IVAS_MAX_NUM_BANDS, SPAR_DIRAC_SPLIT_START_BAND ); - ivas_dirac_config_bands( band_grouping, IVAS_MAX_NUM_BANDS, (int16_t) ( st_ivas->hDecoderConfig->output_Fs * INV_CLDFB_BANDWIDTH + 0.5f ), - st_ivas->hSpar->dirac_to_spar_md_bands, st_ivas->hQMetaData->useLowerBandRes, st_ivas->hSpar->enc_param_start_band, 0 ); + ivas_dirac_config_bands( + band_grouping, + IVAS_MAX_NUM_BANDS, + (int16_t) ( st_ivas->hDecoderConfig->output_Fs * INV_CLDFB_BANDWIDTH + 0.5f ), + st_ivas->hSpar->dirac_to_spar_md_bands, + st_ivas->hQMetaData->useLowerBandRes, + st_ivas->hSpar->enc_param_start_band, + 0 ); } } else { -#ifdef HARMONIZE_SBA_NCHAN_TRANSPORT - if ( ( error = ivas_dirac_sba_config( st_ivas->hQMetaData, &st_ivas->nchan_transport, &st_ivas->nSCE, &st_ivas->nCPE, &st_ivas->element_mode_init, ivas_total_brate, st_ivas->sba_analysis_order, st_ivas->sba_mode, -1 ) ) != IVAS_ERR_OK ) +#ifndef SBA_ORDER_BITSTREAM + if ( ( error = ivas_dirac_sba_config( st_ivas->hQMetaData, &st_ivas->nchan_transport, &st_ivas->nSCE, &st_ivas->nCPE, &st_ivas->element_mode_init, ivas_total_brate, st_ivas->sba_order, st_ivas->sba_planar, st_ivas->sba_mode, -1 ) ) != IVAS_ERR_OK ) #else if ( ( error = ivas_dirac_sba_config( st_ivas->hQMetaData, &st_ivas->nchan_transport, &st_ivas->nSCE, &st_ivas->nCPE, &st_ivas->element_mode_init, ivas_total_brate, st_ivas->sba_analysis_order, st_ivas->sba_planar, st_ivas->sba_mode, -1 ) ) != IVAS_ERR_OK ) #endif @@ -922,7 +963,6 @@ ivas_error ivas_init_decoder( { return error; } - reset_indices_dec( st_ivas->hSCE[sce_id]->hCoreCoder[0] ); } @@ -933,6 +973,7 @@ ivas_error ivas_init_decoder( return error; } + for ( n = 0; n < CPE_CHANNELS; n++ ) { reset_indices_dec( st_ivas->hCPE[cpe_id]->hCoreCoder[n] ); @@ -1003,6 +1044,7 @@ ivas_error ivas_init_decoder( return error; } + for ( n = 0; n < CPE_CHANNELS; n++ ) { reset_indices_dec( st_ivas->hCPE[cpe_id]->hCoreCoder[n] ); @@ -1024,12 +1066,12 @@ ivas_error ivas_init_decoder( return error; } } - if ( ( error = ivas_param_mc_dec_open( st_ivas ) ) != IVAS_ERR_OK ) { return error; } + for ( cpe_id = 0; cpe_id < st_ivas->nCPE; cpe_id++ ) { if ( ( error = create_cpe_dec( st_ivas, cpe_id, ivas_total_brate / ( st_ivas->nSCE + st_ivas->nCPE ) ) ) != IVAS_ERR_OK ) @@ -1037,6 +1079,7 @@ ivas_error ivas_init_decoder( return error; } + for ( n = 0; n < CPE_CHANNELS; n++ ) { reset_indices_dec( st_ivas->hCPE[cpe_id]->hCoreCoder[n] ); @@ -1065,6 +1108,7 @@ ivas_error ivas_init_decoder( return error; } + st_ivas->sba_dirac_stereo_flag = ( st_ivas->nchan_transport == 1 && output_config == AUDIO_CONFIG_STEREO ); if ( st_ivas->renderer_type != RENDERER_DISABLE && st_ivas->renderer_type != RENDERER_MCMASA_MONO_STEREO ) @@ -1105,7 +1149,6 @@ ivas_error ivas_init_decoder( return error; } } - reset_indices_dec( st_ivas->hSCE[sce_id]->hCoreCoder[0] ); } @@ -1114,7 +1157,6 @@ ivas_error ivas_init_decoder( if ( st_ivas->hOutSetup.separateChannelEnabled ) { st_ivas->element_mode_init = IVAS_CPE_MDCT; - if ( ( error = create_cpe_dec( st_ivas, cpe_id, ivas_total_brate - st_ivas->hSCE[0]->element_brate ) ) != IVAS_ERR_OK ) { return error; @@ -1123,13 +1165,11 @@ ivas_error ivas_init_decoder( else { st_ivas->element_mode_init = IVAS_CPE_MDCT; - if ( ( error = create_cpe_dec( st_ivas, cpe_id, ivas_total_brate / ( st_ivas->nSCE + st_ivas->nCPE ) ) ) != IVAS_ERR_OK ) { return error; } } - for ( n = 0; n < CPE_CHANNELS; n++ ) { reset_indices_dec( st_ivas->hCPE[cpe_id]->hCoreCoder[n] ); @@ -1217,7 +1257,6 @@ ivas_error ivas_init_decoder( { return error; } - if ( st_ivas->hRenderConfig->roomAcoustics.late_reverb_on ) { if ( ( st_ivas->hCrend = (CREND_HANDLE) count_malloc( sizeof( CREND_DATA ) ) ) == NULL ) @@ -1324,8 +1363,9 @@ ivas_error ivas_init_decoder( * Allocate and initialize limiter struct *-----------------------------------------------------------------*/ - st_ivas->hLimiter = ivas_limiter_open( hDecoderConfig->nchan_out, output_Fs ); - + { + st_ivas->hLimiter = ivas_limiter_open( hDecoderConfig->nchan_out, output_Fs ); + } return error; } @@ -1507,9 +1547,9 @@ void ivas_initialize_handles_dec( st_ivas->hCPE[i] = NULL; } - st_ivas->bit_stream = NULL; + st_ivas->nSCE = 0; + st_ivas->nCPE = 0; st_ivas->mem_hp20_out = NULL; - st_ivas->hLimiter = NULL; /* ISM metadata handles */ for ( i = 0; i < MAX_NUM_OBJECTS; i++ ) @@ -1518,6 +1558,7 @@ void ivas_initialize_handles_dec( } /* spatial coding handles */ + st_ivas->hIsmRendererData = NULL; st_ivas->hDirAC = NULL; st_ivas->hSpar = NULL; st_ivas->hMasa = NULL; @@ -1537,12 +1578,11 @@ void ivas_initialize_handles_dec( st_ivas->hMonoDmxRenderer = NULL; st_ivas->hCrend = NULL; st_ivas->hHrtf = NULL; - st_ivas->hoa_dec_mtx = NULL; st_ivas->hHeadTrackData = NULL; st_ivas->hHrtfTD = NULL; + st_ivas->hLimiter = NULL; st_ivas->hLsSetupCustom = NULL; - st_ivas->hRenderConfig = NULL; return; } @@ -1810,6 +1850,7 @@ void ivas_init_dec_get_num_cldfb_instances( { *numCldfbAnalyses = st_ivas->hSpar->hFbMixer->fb_cfg->num_in_chans; + if ( st_ivas->hOutSetup.is_loudspeaker_setup && st_ivas->renderer_type == RENDERER_DIRAC ) { *numCldfbSyntheses = st_ivas->hOutSetup.nchan_out_woLFE; @@ -2015,10 +2056,11 @@ static ivas_error doSanityChecks_IVAS( #endif #ifdef DEBUGGING - if ( ( st_ivas->hDecoderConfig->Opt_HRTF_binary || st_ivas->hDecoderConfig->force_rend == FORCE_TD_RENDERER ) && ( ( st_ivas->ivas_format != MC_FORMAT && st_ivas->ivas_format != ISM_FORMAT ) || output_config != AUDIO_CONFIG_BINAURAL || ( 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 ) ) ) + if ( ( st_ivas->hHrtfTD != NULL || st_ivas->hDecoderConfig->force_rend == FORCE_TD_RENDERER ) && ( ( st_ivas->ivas_format != MC_FORMAT && st_ivas->ivas_format != ISM_FORMAT ) || output_config != AUDIO_CONFIG_BINAURAL || ( 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 ) ) ) #else - if ( st_ivas->hDecoderConfig->Opt_HRTF_binary && ( ( st_ivas->ivas_format != MC_FORMAT && st_ivas->ivas_format != ISM_FORMAT ) || output_config != AUDIO_CONFIG_BINAURAL || ( st_ivas->ivas_format == ISM_FORMAT && st_ivas->ism_mode == ISM_MODE_PARAM ) ) ) + if ( st_ivas->hHrtfTD != NULL && ( ( st_ivas->ivas_format != MC_FORMAT && st_ivas->ivas_format != ISM_FORMAT ) || output_config != AUDIO_CONFIG_BINAURAL || ( st_ivas->ivas_format == ISM_FORMAT && st_ivas->ism_mode == ISM_MODE_PARAM ) ) ) #endif + { return IVAS_ERROR( IVAS_ERR_INVALID_OUTPUT_FORMAT, "Incorrect output configuration: Time Domain object renderer not supported in this configuration" ); } diff --git a/lib_dec/ivas_ism_metadata_dec.c b/lib_dec/ivas_ism_metadata_dec.c index dee9b6489f..9d940705f3 100644 --- a/lib_dec/ivas_ism_metadata_dec.c +++ b/lib_dec/ivas_ism_metadata_dec.c @@ -78,11 +78,7 @@ ivas_error ivas_ism_metadata_dec( wmops_sub_start( "ism_meta_dec" ); -#ifdef ALIGN_SID_SIZE - if ( ism_total_brate == IVAS_SID_5k2 || ism_total_brate == FRAME_NO_DATA ) -#else if ( ism_total_brate == IVAS_SID_4k4 || ism_total_brate == FRAME_NO_DATA ) -#endif { /* no metadata decoding in CNG */ for ( ch = 0; ch < *nchan_transport; ch++ ) @@ -91,11 +87,7 @@ ivas_error ivas_ism_metadata_dec( } /* set padding bits as metadata bits to keep later bitrate checks valid */ -#ifdef ALIGN_SID_SIZE - nb_bits_metadata[0] = ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC; -#else nb_bits_metadata[0] = ( IVAS_SID_4k4 - SID_2k40 ) / FRAMES_PER_SEC; -#endif #ifdef DEBUGGING /* sanity check */ diff --git a/lib_dec/ivas_ism_param_dec.c b/lib_dec/ivas_ism_param_dec.c index d394c3c729..108d406845 100644 --- a/lib_dec/ivas_ism_param_dec.c +++ b/lib_dec/ivas_ism_param_dec.c @@ -1027,11 +1027,7 @@ ivas_error ivas_ism_dec_config( /* store last frame ISM mode */ last_ism_mode = st_ivas->ism_mode; -#ifdef ALIGN_SID_SIZE - if ( !st_ivas->bfi && ivas_total_brate != IVAS_SID_5k2 && ivas_total_brate != FRAME_NO_DATA ) -#else if ( !st_ivas->bfi && ivas_total_brate != IVAS_SID_4k4 && ivas_total_brate != FRAME_NO_DATA ) -#endif { /* select ISM format mode */ st_ivas->ism_mode = ivas_ism_mode_select( num_obj, ivas_total_brate ); @@ -1056,11 +1052,7 @@ ivas_error ivas_ism_dec_config( } } } -#ifdef ALIGN_SID_SIZE - else if ( !st_ivas->bfi && ivas_total_brate == IVAS_SID_5k2 ) -#else else if ( !st_ivas->bfi && ivas_total_brate == IVAS_SID_4k4 ) -#endif { st_ivas->nchan_transport = num_obj; } diff --git a/lib_dec/ivas_masa_dec.c b/lib_dec/ivas_masa_dec.c index b4aa18f2a1..91b79a614e 100644 --- a/lib_dec/ivas_masa_dec.c +++ b/lib_dec/ivas_masa_dec.c @@ -115,11 +115,7 @@ ivas_error ivas_masa_decode( *nb_bits_read = 0; next_bit_pos_orig = st->next_bit_pos; -#ifdef ALIGN_SID_SIZE - if ( masa_brate == IVAS_SID_5k2 ) -#else if ( masa_brate == IVAS_SID_4k4 ) -#endif { st->next_bit_pos = (int16_t) ( ( masa_brate / FRAMES_PER_SEC ) - 1 - SID_FORMAT_NBITS ); } @@ -128,11 +124,7 @@ ivas_error ivas_masa_decode( st->next_bit_pos = (int16_t) ( ( masa_brate / FRAMES_PER_SEC ) - 1 ); } -#ifdef ALIGN_SID_SIZE - if ( !st->bfi && ivas_total_brate > IVAS_SID_5k2 ) -#else if ( !st->bfi && ivas_total_brate > IVAS_SID_4k4 ) -#endif { if ( !( ivas_format == MC_FORMAT && st_ivas->mc_mode == MC_MODE_MCMASA ) ) { @@ -224,11 +216,7 @@ ivas_error ivas_masa_decode( replicate_subframes( hQMetaData ); } } -#ifdef ALIGN_SID_SIZE - else if ( !st->bfi && ivas_format == MASA_FORMAT && ivas_total_brate == IVAS_SID_5k2 ) -#else else if ( !st->bfi && ivas_format == MASA_FORMAT && ivas_total_brate == IVAS_SID_4k4 ) -#endif { if ( hQMetaData->q_direction == NULL ) { @@ -241,11 +229,7 @@ ivas_error ivas_masa_decode( ivas_masa_set_elements( ivas_total_brate, st_ivas->mc_mode, st_ivas->nchan_transport, hQMetaData, &st_ivas->element_mode_init, &st_ivas->nSCE, &st_ivas->nCPE ); -#ifdef ALIGN_SID_SIZE - hQMetaData->metadata_max_bits = ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC; -#else hQMetaData->metadata_max_bits = ( IVAS_SID_4k4 - SID_2k40 ) / FRAMES_PER_SEC; -#endif if ( ( error = ivas_qmetadata_allocate_memory( hQMetaData, 5, 1, 0 ) ) != IVAS_ERR_OK ) { @@ -301,11 +285,7 @@ ivas_error ivas_masa_decode( { st_ivas->hCPE[0]->hStereoDft->hConfig->force_mono_transmission = ivas_total_brate < MASA_STEREO_MIN_BITRATE ? 1 : 0; -#ifdef ALIGN_SID_SIZE - if ( ivas_total_brate <= IVAS_SID_5k2 ) -#else if ( ivas_total_brate <= IVAS_SID_4k4 ) -#endif { st_ivas->hCPE[0]->hStereoDft->hConfig->force_mono_transmission = 0; } @@ -315,19 +295,11 @@ ivas_error ivas_masa_decode( { st_ivas->hCPE[0]->hCoreCoder[0]->masa_sid_format = 0; -#ifdef ALIGN_SID_SIZE - if ( st_ivas->hDecoderConfig->last_ivas_total_brate <= IVAS_SID_5k2 ) -#else if ( st_ivas->hDecoderConfig->last_ivas_total_brate <= IVAS_SID_4k4 ) -#endif { st_ivas->hCPE[0]->hCoreCoder[0]->masa_sid_format = 1; -#ifdef ALIGN_SID_SIZE - if ( ivas_total_brate >= IVAS_SID_5k2 ) -#else if ( ivas_total_brate >= IVAS_SID_4k4 ) -#endif { st_ivas->hCPE[0]->element_brate = ivas_total_brate; } @@ -507,11 +479,7 @@ void ivas_masa_prerender( const int16_t output_frame /* i : output frame length per channel */ ) { -#ifdef ALIGN_SID_SIZE - if ( st_ivas->ivas_format == MASA_FORMAT && st_ivas->nchan_transport == 2 && st_ivas->hDecoderConfig->ivas_total_brate < MASA_STEREO_MIN_BITRATE && st_ivas->hDecoderConfig->ivas_total_brate > IVAS_SID_5k2 ) -#else if ( st_ivas->ivas_format == MASA_FORMAT && st_ivas->nchan_transport == 2 && st_ivas->hDecoderConfig->ivas_total_brate < MASA_STEREO_MIN_BITRATE && st_ivas->hDecoderConfig->ivas_total_brate > IVAS_SID_4k4 ) -#endif { if ( st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_EXTERNAL ) { diff --git a/lib_dec/ivas_mc_param_dec.c b/lib_dec/ivas_mc_param_dec.c index 29e2ce4002..e1df8f2a7d 100644 --- a/lib_dec/ivas_mc_param_dec.c +++ b/lib_dec/ivas_mc_param_dec.c @@ -263,6 +263,7 @@ ivas_error ivas_param_mc_dec_open( return error; } + /* convert the ls conv dmx matrix into column order matrix format (nchan_out_cldfb x nchan_out) */ if ( hParamMC->synthesis_conf == PARAM_MC_SYNTH_LS_CONV_COV || hParamMC->synthesis_conf == PARAM_MC_SYNTH_MONO_STEREO ) { @@ -296,7 +297,6 @@ ivas_error ivas_param_mc_dec_open( matrix_product( hParamMC->ls_conv_dmx_matrix, nchan_out_cov, nchan_out_transport, 0, ivas_param_mc_conf[config_index].dmx_fac, nchan_out_transport, nchan_transport, 0, proto_matrix ); - if ( hParamMC->synthesis_conf == PARAM_MC_SYNTH_MONO_STEREO ) { proto_mtx_norm = 1.f; diff --git a/lib_dec/ivas_mct_dec_mct.c b/lib_dec/ivas_mct_dec_mct.c index ec19acb602..00eff03dac 100644 --- a/lib_dec/ivas_mct_dec_mct.c +++ b/lib_dec/ivas_mct_dec_mct.c @@ -283,11 +283,7 @@ void mctStereoIGF_dec( /* stereo IGF decoding */ assert( ( sts[0]->core == sts[1]->core ) || ( hMCT->hBlockData[b]->hStereoMdct->mdct_stereo_mode[0] == SMDCT_DUAL_MONO ) ); -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE - decoder_tcx_IGF_stereo( sts, hMCT->hBlockData[b]->hStereoMdct, hMCT->hBlockData[b]->mask, p_x, L_frame[0], left_rect[0], k, bfi, 1 /* <- is_mct */ ); -#else decoder_tcx_IGF_stereo( sts, hMCT->hBlockData[b]->hStereoMdct, hMCT->hBlockData[b]->mask, p_x, L_frame[0], left_rect[0], k, bfi ); -#endif } else { diff --git a/lib_dec/ivas_mdct_core_dec.c b/lib_dec/ivas_mdct_core_dec.c index d05024c565..ed5114c651 100644 --- a/lib_dec/ivas_mdct_core_dec.c +++ b/lib_dec/ivas_mdct_core_dec.c @@ -102,7 +102,7 @@ static void dec_prm_tcx_sidebits( int16_t p_param[NB_DIV], /* o : pointer to parameters for next round of bs reading*/ int16_t nTnsBitsTCX10[NB_DIV], /* o : number of TNS bits per TCX10 subframe */ Decoder_State *st0, /* i/o: core decoder state handle - for bitstream */ -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT const int16_t MCT_flag, #endif const int16_t ch /* i : channel */ @@ -134,7 +134,7 @@ static void dec_prm_tcx_sidebits( *--------------------------------------------------------------------------------*/ /* Modes (ACE_GC, ACE_UC, TCX20, TCX10...) */ -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT getTCXMode( st, st0, MCT_flag ); #else getTCXMode( st, st0 ); @@ -381,7 +381,7 @@ void ivas_mdct_dec_side_bits_frame_channel( tmp = 3; } -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT dec_prm_tcx_sidebits( param[ch], st, ( ( st->element_mode == IVAS_CPE_MDCT && !MCT_flag ) ? sts[0]->hTcxDec->tnsActive : NULL ), p_param[ch], nTnsBitsTCX10[ch], st0, MCT_flag, tmp ); #else dec_prm_tcx_sidebits( param[ch], st, ( ( st->element_mode == IVAS_CPE_MDCT && !MCT_flag ) ? sts[0]->hTcxDec->tnsActive : NULL ), p_param[ch], nTnsBitsTCX10[ch], st0, tmp ); @@ -481,7 +481,7 @@ void ivas_mdct_core_invQ( const int16_t *prm_sqQ; int16_t L_frameTCX_global[CPE_CHANNELS]; float tmp_ms_sig[CPE_CHANNELS][N_MAX]; -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT float concealment_noise[CPE_CHANNELS][L_FRAME48k]; TONALMDCTCONC_NOISE_GEN_MODE noise_gen_mode_bfi; #endif @@ -490,7 +490,7 @@ void ivas_mdct_core_invQ( sts = hCPE->hCoreCoder; bfi = sts[0]->bfi; -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT noise_gen_mode_bfi = -1; #endif @@ -514,7 +514,7 @@ void ivas_mdct_core_invQ( sts[0]->core, sts[1]->core, sts[0]->igf, L_frameTCX[0], 0, sts[0]->last_core, sts[1]->last_core, 1 ); } -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT if ( bfi ) { if ( sts[0]->core == sts[1]->core ) @@ -728,11 +728,15 @@ void ivas_mdct_core_invQ( } nf_seed = 0; +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT + decoder_tcx_invQ( st, prm[ch], Aq[ch], Aind[ch], L_spec[ch], L_frame[ch], L_frameTCX[ch], x[ch][k], NULL, xn_buf, &fUseTns[ch][k], &tnsData[ch][k], &gain_tcx, &prm_sqQ, &nf_seed, bfi, isMCT, k ); +#else decoder_tcx_invQ( st, prm[ch], Aq[ch], Aind[ch], L_spec[ch], L_frame[ch], L_frameTCX[ch], x[ch][k], NULL, xn_buf, &fUseTns[ch][k], &tnsData[ch][k], &gain_tcx, &prm_sqQ, &nf_seed, bfi, k ); +#endif mvr2r( x[ch][k], x_0[ch][k], L_frameTCX[ch] ); -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT if ( bfi && !isMCT ) { TonalMdctConceal_create_concealment_noise( concealment_noise[ch], hCPE, L_frameTCX[ch], L_frame[ch], ch, k, st->core, st->hTcxDec->cummulative_damping_tcx, noise_gen_mode_bfi ); @@ -857,7 +861,7 @@ void ivas_mdct_core_reconstruct( TonalMDCTConceal_SaveTimeSignal( st->hTonalMDCTConc, synthFB, L_frameTCX[ch] ); } -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT decoder_tcx_post( st, synth, synthFB, NULL, bfi, isMCT ); #else decoder_tcx_post( st, synth, synthFB, NULL, bfi ); @@ -869,7 +873,7 @@ void ivas_mdct_core_reconstruct( /* PLC: [TCX: TD PLC] */ if ( isMCT ) { -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT con_tcx( st, &synthFB[0], -1.f, NULL, 0, NULL ); #else con_tcx( st, &synthFB[0], -1.f, NULL, 0 ); @@ -877,7 +881,7 @@ void ivas_mdct_core_reconstruct( } else { -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT con_tcx( st, &synthFB[0], hCPE->hStereoMdct->lastCoh, &sts[0]->seed_acelp, ( sts[1]->core != ACELP_CORE ) ? 1 : 0, &st->hFdCngDec->hFdCngCom->A_cng[0] ); #else con_tcx( st, &synthFB[0], hCPE->hStereoMdct->lastCoh, &sts[0]->seed_acelp, ( sts[1]->core != ACELP_CORE ) ? 1 : 0 ); @@ -1060,14 +1064,34 @@ void ivas_mdct_core_tns_ns( { sns_interpolate_scalefactors( &sns_int_scf[0], &Aq[ch][k * M], DEC ); -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT if ( isMCT && st->hTonalMDCTConc != NULL && ( ( k + 1 ) == nSubframes[ch] ) ) #else if ( isMCT && st->hTonalMDCTConc != NULL ) #endif { -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE - TonalMDCTConceal_SaveFreqSignal( st->hTonalMDCTConc, x[ch][k], L_frameTCX[ch], L_frame[ch], &sns_int_scf[0], get_igf_startline( st, L_frame[ch], L_frameTCX[ch] ) ); +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT + int16_t infoIGFStartLine; + + if ( st->igf == 0 ) + { + if ( st->narrowBand == 0 ) + { + /* minimum needed for output with sampling rates lower then the + nominal sampling rate */ + infoIGFStartLine = min( L_frameTCX[ch], L_frame[ch] ); + } + else + { + infoIGFStartLine = L_frameTCX[ch]; + } + } + else + { + infoIGFStartLine = min( st->hIGFDec->infoIGFStartLine, L_frameTCX[ch] ); + } + + TonalMDCTConceal_SaveFreqSignal( st->hTonalMDCTConc, x[ch][k], L_frameTCX[ch], L_frame[ch], &sns_int_scf[0], infoIGFStartLine ); #else TonalMDCTConceal_SaveFreqSignal( st->hTonalMDCTConc, x[ch][k], L_frameTCX[ch], L_frame[ch], &sns_int_scf[0] ); #endif @@ -1077,18 +1101,17 @@ void ivas_mdct_core_tns_ns( { if ( st->hTonalMDCTConc != NULL ) { -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE - if ( !isMCT && st->hTcxDec->cummulative_damping_tcx != 1.f ) +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT + if ( st->hTcxDec->cummulative_damping_tcx != 1.f ) { - float *scf_last, *scf_bg; - float fade_in, fade_out; + float *scf_last; + float *scf_bg; + float fade_in; + float fade_out; scf_last = &st->hTonalMDCTConc->lastBlockData.scaleFactors[0]; scf_bg = &st->hTonalMDCTConc->scaleFactorsBackground[0]; - - st->hTonalMDCTConc->scf_fadeout *= 0.95f; - - fade_out = st->hTonalMDCTConc->scf_fadeout; + fade_out = st->hTcxDec->cummulative_damping_tcx; fade_in = 1 - fade_out; for ( int16_t i = 0; i < st->hTonalMDCTConc->nScaleFactors; i++ ) @@ -1098,7 +1121,6 @@ void ivas_mdct_core_tns_ns( } else { - st->hTonalMDCTConc->scf_fadeout = 1.0f; mvr2r( st->hTonalMDCTConc->lastBlockData.scaleFactors, &sns_int_scf[0], st->hTonalMDCTConc->nScaleFactors ); } #else diff --git a/lib_dec/ivas_out_setup_conversion.c b/lib_dec/ivas_out_setup_conversion.c index 9ed27e56c3..c8008fa129 100644 --- a/lib_dec/ivas_out_setup_conversion.c +++ b/lib_dec/ivas_out_setup_conversion.c @@ -312,6 +312,8 @@ ivas_error ivas_ls_setup_conversion_open( int32_t output_Fs; int16_t nchan_out; + wmops_sub_start( "LS_Renderer" ); + output_Fs = st_ivas->hDecoderConfig->output_Fs; nchan_out = st_ivas->hDecoderConfig->nchan_out; output_frame = (int16_t) ( output_Fs / FRAMES_PER_SEC ); @@ -1070,6 +1072,8 @@ void ivas_ls_setup_conversion_process_mdct_param_mc( } } + wmops_sub_end(); + return; } diff --git a/lib_dec/ivas_qmetadata_dec.c b/lib_dec/ivas_qmetadata_dec.c index 15f33799d6..628e4ca6b8 100644 --- a/lib_dec/ivas_qmetadata_dec.c +++ b/lib_dec/ivas_qmetadata_dec.c @@ -721,32 +721,17 @@ int16_t ivas_qmetadata_dec_sid_decode( { if ( sba_mode == SBA_MODE_SPAR ) { -#ifdef ALIGN_SID_SIZE - /* TODO: still use old sid frame size to keep bitexactness */ - metadata_sid_bits = (int16_t) ( 5000 /*IVAS_SID_5k2*/ - SID_2k40 ) / FRAMES_PER_SEC - ( SPAR_DTX_BANDS * 18 ) - 1; /* -1 for inactive mode header bit*/ -#else metadata_sid_bits = (int16_t) ( IVAS_SID_5k - SID_2k40 ) / FRAMES_PER_SEC - ( SPAR_DTX_BANDS * 18 ) - 1; /* -1 for inactive mode header bit*/ -#endif } else { /* keep 13.2 and 16.4 sid bitrate as 4.4 kbps for now*/ -#ifdef ALIGN_SID_SIZE - /* TODO: still use old sid frame size to keep bitexactness */ - metadata_sid_bits = ( 4400 /*IVAS_SID_5k2*/ - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS; -#else metadata_sid_bits = ( IVAS_SID_4k4 - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS; -#endif } } else { -#ifdef ALIGN_SID_SIZE - /* TODO: still use old sid frame size to keep bitexactness */ - metadata_sid_bits = ( 4400 /*IVAS_SID_5k2*/ - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS; -#else metadata_sid_bits = ( IVAS_SID_4k4 - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS; -#endif } start_index = *index; @@ -865,20 +850,6 @@ int16_t ivas_qmetadata_dec_sid_decode( } } } -#ifdef ALIGN_SID_SIZE - /* TODO: temporary hack to keep BE */ - if ( ivas_format == SBA_FORMAT ) - { - if ( sba_mode != SBA_MODE_SPAR ) - { - metadata_sid_bits = ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS - 1; /* -1 for spar/dirac indicator*/ - } - } - else - { - metadata_sid_bits = ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS; - } -#endif /*Read filling bits*/ while ( start_index - *index < metadata_sid_bits ) @@ -889,9 +860,9 @@ int16_t ivas_qmetadata_dec_sid_decode( #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 ); + 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++ ) { diff --git a/lib_dec/ivas_sba_dec.c b/lib_dec/ivas_sba_dec.c index 5ea87f3f02..4aaddd028b 100644 --- a/lib_dec/ivas_sba_dec.c +++ b/lib_dec/ivas_sba_dec.c @@ -45,430 +45,6 @@ #include "wmops.h" -/*-----------------------------------------------------------------------* - * Local function prototypes - *-----------------------------------------------------------------------*/ - -#ifndef HARMONIZE_SBA_NCHAN_TRANSPORT -static void ivas_sba_dmx_dec( float sba_data[][L_FRAME48k], const int16_t nchan_transport, const int16_t output_frame ); -#endif - -#ifdef DEBUG_MODE_DIRAC -static void debug_mode_dirac( float output[MAX_OUTPUT_CHANNELS][L_FRAME48k], const int16_t nchan_transport, const int16_t output_frame ); -#endif - - -/*-------------------------------------------------------------------------* - * ivas_mc2sba() - * - * MC signals transformed into SBA in TD domain - *-------------------------------------------------------------------------*/ - -void ivas_mc2sba( - IVAS_OUTPUT_SETUP hIntSetup, /* i : Format of decoder output */ - float buffer_td[][L_FRAME48k], /* i/o: MC signals (on input) and the HOA3 (on output) */ - const int16_t output_frame, /* i : output frame length per channel */ - const int16_t sba_order, /* i : Ambisonic (SBA) order */ - const float gain_lfe /* i : gain for LFE, 0 = ignore LFE */ -) -{ - int16_t i, j, k; - int16_t idx_lfe, idx_in; - float buffer_tmp[16][L_FRAME48k]; - float gains[16]; - int16_t azimuth, elevation; - int16_t sba_num_chans; - - assert( ( sba_order <= 3 ) && "Only order up to 3 is supported!" ); - - /* 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 ); - } - - /* HOA encoding*/ - idx_lfe = 0; - idx_in = 0; - for ( i = 0; i < hIntSetup.nchan_out_woLFE + hIntSetup.num_lfe; i++ ) - { - if ( ( hIntSetup.num_lfe > 0 ) && ( i == hIntSetup.index_lfe[idx_lfe] ) ) - { - if ( gain_lfe > 0.f ) - { - /* Add LFE to omni W with gain*/ - for ( k = 0; k < output_frame; k++ ) - { - buffer_tmp[0][k] += gain_lfe * buffer_td[i][k]; - } - } - - if ( idx_lfe < ( hIntSetup.num_lfe - 1 ) ) - { - idx_lfe++; - } - } - else - { - azimuth = (int16_t) ( hIntSetup.ls_azimuth[idx_in] ); - elevation = (int16_t) ( hIntSetup.ls_elevation[idx_in] ); - idx_in++; - - /* get HOA response for direction (ACN/SN3D)*/ - ivas_dirac_dec_get_response( - azimuth, - elevation, - gains, - sba_order ); - - for ( j = 0; j < sba_num_chans; j++ ) - { - for ( k = 0; k < output_frame; k++ ) - { - buffer_tmp[j][k] += gains[j] * buffer_td[i][k]; - } - } - } - } - - for ( j = 0; j < sba_num_chans; j++ ) - { - mvr2r( buffer_tmp[j], buffer_td[j], output_frame ); - } - - return; -} - - -/*-------------------------------------------------------------------------* - * ivas_sba2MC_cldfb() - * - * SBA signals transformed into MC in CLDFB domain - *-------------------------------------------------------------------------*/ - -void ivas_sba2mc_cldfb( - IVAS_OUTPUT_SETUP hInSetup, /* i : Format of input layout */ - float RealBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i/o: cldfb real part */ - float ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i/o: cldfb imag part */ - const int16_t nb_channels_out, /* i : nb of output channels */ - const int16_t nb_bands, /* i : nb of CLDFB bands to process */ - const float *hoa_dec_mtx /* i : HOA decoding mtx */ -) -{ - int16_t iBlock, iBand, n, m; - float realOut[16][MAX_PARAM_SPATIAL_SUBFRAMES * CLDFB_NO_CHANNELS_MAX], imagOut[16][MAX_PARAM_SPATIAL_SUBFRAMES * CLDFB_NO_CHANNELS_MAX]; - float g; - float *p_real, *p_imag, *p_realOut, *p_imagOut; - int16_t nb_channels_in; - - wmops_sub_start( "ivas_sba2mc_cldfb" ); - - nb_channels_in = hInSetup.nchan_out_woLFE; - assert( ( nb_channels_in == 16 ) && ( nb_channels_out == 11 ) && "ivas_sba2mc_cldfb; only HOA3 to CICP19 is for now supported!" ); - - for ( n = 0; n < nb_channels_out; n++ ) - { - set_zero( realOut[n], MAX_PARAM_SPATIAL_SUBFRAMES * nb_bands ); - set_zero( imagOut[n], MAX_PARAM_SPATIAL_SUBFRAMES * nb_bands ); - - for ( m = 0; m < nb_channels_in; m++ ) - { - g = hoa_dec_mtx[SBA_NHARM_HOA3 * n + m]; - p_realOut = realOut[n]; - p_imagOut = imagOut[n]; - for ( iBlock = 0; iBlock < MAX_PARAM_SPATIAL_SUBFRAMES; iBlock++ ) - { - p_real = RealBuffer[m][iBlock]; - p_imag = ImagBuffer[m][iBlock]; - for ( iBand = 0; iBand < nb_bands; iBand++ ) - { - *p_realOut = *p_realOut + g * *( p_real++ ); - *p_imagOut = *p_imagOut + g * *( p_imag++ ); - p_realOut++; - p_imagOut++; - } - } - } - } - - for ( n = 0; n < nb_channels_out; n++ ) - { - p_realOut = realOut[n]; - p_imagOut = imagOut[n]; - for ( iBlock = 0; iBlock < MAX_PARAM_SPATIAL_SUBFRAMES; iBlock++ ) - { - p_real = RealBuffer[n][iBlock]; - p_imag = ImagBuffer[n][iBlock]; - for ( iBand = 0; iBand < nb_bands; iBand++ ) - { - *( p_real++ ) = *p_realOut++; - *( p_imag++ ) = *p_imagOut++; - } - } - } - - wmops_sub_end(); - - return; -} - -/*-------------------------------------------------------------------* - * ivas_sba_remapTCs() - * - * Get TCs from Ambisonics signal in ACN - *-------------------------------------------------------------------*/ - -int16_t ivas_sba_remapTCs( - float sba_data[][L_FRAME48k], /* i/o: SBA signals */ - Decoder_Struct *st_ivas, /* i/o: decoder struct */ - const int16_t output_frame /* i : frame length */ -) -{ - 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 ( ( st_ivas->sba_mode != SBA_MODE_SPAR && st_ivas->sba_planar && nchan_remapped >= 3 ) || - ( ( st_ivas->sba_mode == SBA_MODE_SPAR ) && nchan_remapped == 3 ) ) - { - - nchan_remapped++; - if ( st_ivas->sba_mode != SBA_MODE_SPAR ) - { - assert( ( ( st_ivas->nchan_transport == 3 ) || ( st_ivas->nchan_transport == 5 ) || ( st_ivas->nchan_transport == 7 ) ) && "Number of channels must be odd for SBA planar!" ); - } - - if ( nchan_remapped == 4 ) - { - /*For planar A-format channel 2 and 3 are identical -> Z=0*/ - mvr2r( sba_data[2], sba_data[3], output_frame ); - } - } - -#ifdef HARMONIZE_SBA_NCHAN_TRANSPORT - if ( st_ivas->nchan_transport >= 3 ) - { - int16_t i = 0; - float temp; - - /*convert WYXZ downmix to WYZX*/ - for ( i = 0; i < output_frame; i++ ) - { - temp = sba_data[2][i]; - sba_data[2][i] = sba_data[3][i]; - sba_data[3][i] = temp; - if ( st_ivas->nchan_transport == 3 ) - { - sba_data[2][i] = 0; - } - } - } -#else - if ( st_ivas->sba_mode == SBA_MODE_SPAR ) - { - int16_t i = 0; - float temp; - - if ( st_ivas->nchan_transport >= 3 ) - { - /*convert WYXZ downmix to WYZX*/ - for ( i = 0; i < output_frame; i++ ) - { - temp = sba_data[2][i]; - sba_data[2][i] = sba_data[3][i]; - sba_data[3][i] = temp; - if ( st_ivas->nchan_transport == 3 ) - { - sba_data[2][i] = 0; - } - } - } - } - else - { -#ifdef HARMONIZE_SBA_NCHAN_TRANSPORT - /* do nothing; simply use omni */ -#else - ivas_sba_dmx_dec( sba_data, nchan_remapped, output_frame ); -#endif - } -#endif - - if ( st_ivas->sba_mode != SBA_MODE_SPAR ) - { - ivas_sba_zero_vert_comp( sba_data, st_ivas->sba_analysis_order, st_ivas->sba_planar, output_frame ); - } - - return ( nchan_remapped ); -} - - -#ifndef HARMONIZE_SBA_NCHAN_TRANSPORT -/*-------------------------------------------------------------------* - * ivas_sba_dmx_dec() - * - * - *-------------------------------------------------------------------*/ - -static void ivas_sba_dmx_dec( - float sba_data[][L_FRAME48k], /* i : SBA signals */ - const int16_t nchan_transport, /* i : number of transport channels */ - const int16_t output_frame /* i : frame length */ -) -{ - int16_t i; - float tmp_f[DIRAC_MAX_TRANS_CHANS]; - - if ( nchan_transport >= 7 ) - { - for ( i = 0; i < output_frame; i++ ) - { - tmp_f[0] = 0.506415f * sba_data[0][i] + 0.506415f * sba_data[1][i] + 0.506415f * sba_data[2][i] + 0.506415f * sba_data[3][i] + 0.506415f * sba_data[4][i] + 0.506415f * sba_data[5][i] + 0.506415f * sba_data[6][i]; - tmp_f[1] = -0.000000f * sba_data[0][i] + 0.531020f * sba_data[1][i] + 0.662171f * sba_data[2][i] + 0.294694f * sba_data[3][i] + -0.294694f * sba_data[4][i] + -0.662171f * sba_data[5][i] + -0.531020f * sba_data[6][i]; - tmp_f[2] = 0.679200f * sba_data[0][i] + 0.423475f * sba_data[1][i] + -0.151136f * sba_data[2][i] + -0.611938f * sba_data[3][i] + -0.611938f * sba_data[4][i] + -0.151136f * sba_data[5][i] + 0.423475f * sba_data[6][i]; - tmp_f[3] = 0.000000f * sba_data[0][i] + 0.833385f * sba_data[1][i] + -0.370891f * sba_data[2][i] + -0.668323f * sba_data[3][i] + 0.668323f * sba_data[4][i] + 0.370891f * sba_data[5][i] + -0.833385f * sba_data[6][i]; - tmp_f[4] = 0.854817f * sba_data[0][i] + -0.190215f * sba_data[1][i] + -0.770164f * sba_data[2][i] + 0.532970f * sba_data[3][i] + 0.532970f * sba_data[4][i] + -0.770164f * sba_data[5][i] + -0.190215f * sba_data[6][i]; - tmp_f[5] = 0.000000f * sba_data[0][i] + 0.691125f * sba_data[1][i] + -1.245365f * sba_data[2][i] + 1.552944f * sba_data[3][i] + -1.552944f * sba_data[4][i] + 1.245365f * sba_data[5][i] + -0.691125f * sba_data[6][i]; - tmp_f[6] = 1.592881f * sba_data[0][i] + -1.435137f * sba_data[1][i] + 0.993145f * sba_data[2][i] + -0.354449f * sba_data[3][i] + -0.354449f * sba_data[4][i] + 0.993145f * sba_data[5][i] + -1.435137f * sba_data[6][i]; - - sba_data[0][i] = tmp_f[0]; - sba_data[1][i] = tmp_f[1]; - sba_data[2][i] = sba_data[7][i]; - sba_data[3][i] = tmp_f[2]; - sba_data[4][i] = tmp_f[3]; - sba_data[8][i] = tmp_f[4]; - sba_data[9][i] = tmp_f[5]; - sba_data[15][i] = tmp_f[6]; - } - - return; - } - else if ( nchan_transport >= 5 ) - { - for ( i = 0; i < output_frame; i++ ) - { - tmp_f[0] = 0.708982f * sba_data[0][i] + 0.708982f * sba_data[1][i] + 0.708982f * sba_data[2][i] + 0.708982f * sba_data[3][i] + 0.708982f * sba_data[4][i]; - tmp_f[1] = 0.000000f * sba_data[0][i] + 1.005966f * sba_data[1][i] + 0.621721f * sba_data[2][i] + -0.621721f * sba_data[3][i] + -1.005966f * sba_data[4][i]; - tmp_f[2] = 1.057735f * sba_data[0][i] + 0.326858f * sba_data[1][i] + -0.855726f * sba_data[2][i] + -0.855726f * sba_data[3][i] + 0.326858f * sba_data[4][i]; - tmp_f[3] = 0.000000f * sba_data[0][i] + 1.079884f * sba_data[1][i] + -1.747289f * sba_data[2][i] + 1.747289f * sba_data[3][i] + -1.079884f * sba_data[4][i]; - tmp_f[4] = 1.837208f * sba_data[0][i] + -1.486333f * sba_data[1][i] + 0.567729f * sba_data[2][i] + 0.567729f * sba_data[3][i] + -1.486333f * sba_data[4][i]; - - sba_data[0][i] = tmp_f[0]; - sba_data[1][i] = tmp_f[1]; - sba_data[2][i] = sba_data[5][i]; - sba_data[3][i] = tmp_f[2]; - sba_data[4][i] = tmp_f[3]; - sba_data[8][i] = tmp_f[4]; - } - - return; - } - else if ( nchan_transport >= 3 ) - { - - /*A-format to ACN/SN3D*/ - for ( i = 0; i < output_frame; i++ ) - { - tmp_f[0] = 0.5f * ( sba_data[0][i] + sba_data[1][i] + sba_data[2][i] + sba_data[3][i] ); - tmp_f[1] = sba_data[0][i] - sba_data[1][i]; - tmp_f[2] = sba_data[2][i] - sba_data[3][i]; - tmp_f[3] = sba_data[0][i] + sba_data[1][i] - sba_data[2][i] - sba_data[3][i]; - - sba_data[0][i] = tmp_f[0]; - sba_data[1][i] = tmp_f[1]; - sba_data[2][i] = tmp_f[2]; - sba_data[3][i] = tmp_f[3]; - } - - return; - } - else if ( nchan_transport == 2 ) - { - /* do nothing for stereo DMX, upmix done in DirAC*/ - return; - } - else if ( nchan_transport == 1 ) - { - /* do nothing; simply use omni */ - return; - } - else - { - assert( 0 && "SBA: number of transport channels not supported." ); - } -} -#endif - -/*-------------------------------------------------------------------------* - * ivas_ism2sba() - * - * ISM transformed into SBA in TD domain. - *-------------------------------------------------------------------------*/ - -void ivas_ism2sba( - float buffer_td[][L_FRAME48k], /* i/o: TD signal buffers */ - ISM_RENDERER_HANDLE hIsmRendererData, /* i/o: renderer data */ - const ISM_METADATA_HANDLE hIsmMetaData[], /* i : object metadata */ - const int16_t num_objects, /* 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 < num_objects; i++ ) - { - azimuth = (int16_t) ( hIsmMetaData[i]->azimuth + 0.5f ); - elevation = (int16_t) ( 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++ ) - { - g2 = 0.f; - for ( k = 0; k < output_frame; k++ ) - { - g2 += 1.f / output_frame; - g1 = 1.0f - g2; - buffer_tmp[j][k] += ( g2 * gains[j] + g1 * hIsmRendererData->prev_gains[i][j] ) * buffer_td[i][k]; - } - 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; -} - - /*-------------------------------------------------------------------* * ivas_sba_dec_decoder() * @@ -509,15 +85,13 @@ ivas_error ivas_sba_dec_reconfigure( numCldfbAnalyses = 0; sba_total_brate = ivas_total_brate; + nSCE_old = st_ivas->nSCE; nCPE_old = st_ivas->nCPE; nchan_transport_old = st_ivas->nchan_transport; sba_dirac_stereo_flag_old = st_ivas->sba_dirac_stereo_flag; - - st_ivas->sba_analysis_order = ivas_sba_get_analysis_order( ivas_total_brate, st_ivas->sba_order ); - -#ifdef HARMONIZE_SBA_NCHAN_TRANSPORT - ivas_sba_config( sba_total_brate, st_ivas->sba_analysis_order, -1, &nchan_transport, st_ivas->sba_planar, &st_ivas->nSCE, &st_ivas->nCPE, &st_ivas->element_mode_init ); +#ifndef SBA_ORDER_BITSTREAM + ivas_sba_config( sba_total_brate, st_ivas->sba_order, -1, &nchan_transport, st_ivas->sba_planar, &st_ivas->nSCE, &st_ivas->nCPE, &st_ivas->element_mode_init, st_ivas->sba_mode ); #else ivas_sba_config( sba_total_brate, st_ivas->sba_analysis_order, -1, &nchan_transport, st_ivas->sba_planar, &st_ivas->nSCE, &st_ivas->nCPE, &st_ivas->element_mode_init, st_ivas->sba_mode ); #endif @@ -536,9 +110,8 @@ ivas_error ivas_sba_dec_reconfigure( if ( st_ivas->sba_mode != SBA_MODE_SPAR ) { st_ivas->sba_dirac_stereo_flag = ( st_ivas->nchan_transport == 1 && st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_STEREO ); - -#ifdef HARMONIZE_SBA_NCHAN_TRANSPORT - if ( ( error = ivas_dirac_sba_config( st_ivas->hQMetaData, &st_ivas->nchan_transport, &st_ivas->nSCE, &st_ivas->nCPE, &st_ivas->element_mode_init, ivas_total_brate, st_ivas->sba_analysis_order, st_ivas->sba_mode, -1 ) ) != IVAS_ERR_OK ) +#ifndef SBA_ORDER_BITSTREAM + if ( ( error = ivas_dirac_sba_config( st_ivas->hQMetaData, &st_ivas->nchan_transport, &st_ivas->nSCE, &st_ivas->nCPE, &st_ivas->element_mode_init, ivas_total_brate, st_ivas->sba_order, st_ivas->sba_planar, st_ivas->sba_mode, -1 ) ) != IVAS_ERR_OK ) #else if ( ( error = ivas_dirac_sba_config( st_ivas->hQMetaData, &st_ivas->nchan_transport, &st_ivas->nSCE, &st_ivas->nCPE, &st_ivas->element_mode_init, ivas_total_brate, st_ivas->sba_analysis_order, st_ivas->sba_planar, st_ivas->sba_mode, -1 ) ) != IVAS_ERR_OK ) #endif @@ -549,13 +122,15 @@ ivas_error ivas_sba_dec_reconfigure( else { int16_t sba_order_internal; - +#ifndef SBA_ORDER_BITSTREAM + sba_order_internal = min( st_ivas->sba_order, IVAS_MAX_SBA_ORDER ); +#else sba_order_internal = min( st_ivas->sba_analysis_order, IVAS_MAX_SBA_ORDER ); +#endif ivas_spar_config( st_ivas->hDecoderConfig->ivas_total_brate, sba_order_internal, &st_ivas->nchan_transport, &st_ivas->nSCE, &st_ivas->nCPE, &st_ivas->hSpar->core_nominal_brate, st_ivas->sid_format ); - -#ifdef HARMONIZE_SBA_NCHAN_TRANSPORT - if ( ( error = ivas_dirac_sba_config( st_ivas->hQMetaData, &st_ivas->nchan_transport, &st_ivas->nSCE, &st_ivas->nCPE, &st_ivas->element_mode_init, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->sba_analysis_order, st_ivas->sba_mode, IVAS_MAX_NUM_BANDS - SPAR_DIRAC_SPLIT_START_BAND ) ) != IVAS_ERR_OK ) - +#ifndef SBA_ORDER_BITSTREAM + if ( ( error = ivas_dirac_sba_config( st_ivas->hQMetaData, &st_ivas->nchan_transport, &st_ivas->nSCE, &st_ivas->nCPE, &st_ivas->element_mode_init, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->sba_order, st_ivas->sba_planar, + st_ivas->sba_mode, IVAS_MAX_NUM_BANDS - SPAR_DIRAC_SPLIT_START_BAND ) ) != IVAS_ERR_OK ) #else if ( ( error = ivas_dirac_sba_config( st_ivas->hQMetaData, &st_ivas->nchan_transport, &st_ivas->nSCE, &st_ivas->nCPE, &st_ivas->element_mode_init, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->sba_analysis_order, st_ivas->sba_planar, st_ivas->sba_mode, IVAS_MAX_NUM_BANDS - SPAR_DIRAC_SPLIT_START_BAND ) ) != IVAS_ERR_OK ) @@ -565,11 +140,8 @@ ivas_error ivas_sba_dec_reconfigure( } } -#ifdef ALIGN_SID_SIZE - if ( st_ivas->renderer_type != RENDERER_DISABLE && st_ivas->renderer_type != RENDERER_SBA_LINEAR_DEC && ( last_ivas_total_brate > IVAS_SID_5k2 || nchan_transport != nchan_transport_old ) && ( st_ivas->sba_mode != SBA_MODE_SPAR ) ) -#else - if ( st_ivas->renderer_type != RENDERER_DISABLE && st_ivas->renderer_type != RENDERER_SBA_LINEAR_DEC && ( last_ivas_total_brate > IVAS_SID_4k4 || nchan_transport != nchan_transport_old ) && ( st_ivas->sba_mode != SBA_MODE_SPAR ) ) -#endif + if ( st_ivas->renderer_type != RENDERER_DISABLE && st_ivas->renderer_type != RENDERER_SBA_LINEAR_DEC && + ( last_ivas_total_brate > IVAS_SID_4k4 || nchan_transport != nchan_transport_old ) && ( st_ivas->sba_mode != SBA_MODE_SPAR ) ) { if ( st_ivas->hDirAC != NULL ) { @@ -941,11 +513,7 @@ ivas_error ivas_sba_dec_reconfigure( } /* special case, if the decoder goes from 1TC DTX to 2TC active frame (in case the bitstream started with an SBA SID frame), allocate DTX memories */ -#ifdef ALIGN_SID_SIZE - if ( last_ivas_total_brate <= IVAS_SID_5k2 && st_ivas->nCPE >= 1 ) -#else if ( last_ivas_total_brate <= IVAS_SID_4k4 && st_ivas->nCPE >= 1 ) -#endif { if ( ( error = initMdctStereoDtxData( st_ivas->hCPE[0] ) ) != IVAS_ERR_OK ) { diff --git a/lib_dec/ivas_sce_dec.c b/lib_dec/ivas_sce_dec.c index b24d60505b..5b83a41f81 100644 --- a/lib_dec/ivas_sce_dec.c +++ b/lib_dec/ivas_sce_dec.c @@ -82,11 +82,7 @@ ivas_error ivas_sce_dec( *-----------------------------------------------------------------*/ /* set total_brate - needed in DTX */ -#ifdef ALIGN_SID_SIZE - if ( !st_ivas->bfi && ( ivas_total_brate == IVAS_SID_5k2 ) ) -#else if ( !st_ivas->bfi && ( ivas_total_brate == IVAS_SID_4k4 || ivas_total_brate == IVAS_SID_5k ) ) -#endif { st->total_brate = ivas_total_brate - nb_bits_metadata * FRAMES_PER_SEC; assert( st->total_brate == SID_2k40 && "SCE SID must be 2.4kbps!" ); @@ -95,11 +91,7 @@ ivas_error ivas_sce_dec( { st->total_brate = ivas_total_brate; } -#ifdef ALIGN_SID_SIZE - else if ( !st_ivas->bfi && ( last_ivas_total_brate <= SID_2k40 || last_ivas_total_brate == IVAS_SID_5k2 ) ) -#else else if ( !st_ivas->bfi && ( last_ivas_total_brate <= SID_2k40 || last_ivas_total_brate == IVAS_SID_4k4 ) ) -#endif { st->total_brate = hSCE->element_brate - nb_bits_metadata * FRAMES_PER_SEC; } @@ -169,11 +161,7 @@ ivas_error ivas_sce_dec( } /* set "total_brate" */ -#ifdef ALIGN_SID_SIZE - if ( !st_ivas->bfi && ( ivas_total_brate == IVAS_SID_5k2 ) ) -#else if ( !st_ivas->bfi && ( ivas_total_brate == IVAS_SID_4k4 || ivas_total_brate == IVAS_SID_5k ) ) -#endif { st->total_brate = ivas_total_brate - nb_bits_metadata * FRAMES_PER_SEC; } @@ -350,7 +338,7 @@ ivas_error create_sce_dec( st->total_brate = hSCE->element_brate; /* dummy initialization for getting right pointers initialization of input buffers in init_coder_ace_plus() */ st->mct_chan_mode = MCT_CHAN_MODE_REGULAR; -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT if ( ( error = init_decoder( st, 0, st_ivas->mc_mode ) ) != IVAS_ERR_OK ) #else if ( ( error = init_decoder( st, 0 ) ) != IVAS_ERR_OK ) diff --git a/lib_dec/ivas_spar_decoder.c b/lib_dec/ivas_spar_decoder.c old mode 100644 new mode 100755 index 2e48c11745..cc625f2605 --- a/lib_dec/ivas_spar_decoder.c +++ b/lib_dec/ivas_spar_decoder.c @@ -71,7 +71,11 @@ ivas_error ivas_spar_dec_open( int32_t output_Fs; error = IVAS_ERR_OK; +#ifndef SBA_ORDER_BITSTREAM + sba_order_internal = min( st_ivas->sba_order, IVAS_MAX_SBA_ORDER ); +#else sba_order_internal = min( st_ivas->sba_analysis_order, IVAS_MAX_SBA_ORDER ); +#endif num_channels_internal = ivas_sba_get_nchan_metadata( sba_order_internal ); /* SPAR decoder handle */ @@ -241,12 +245,6 @@ ivas_error ivas_spar_dec( next_bit_pos_orig = st0->next_bit_pos; last_bit_pos = (int16_t) ( ( hDecoderConfig->ivas_total_brate / FRAMES_PER_SEC ) - 1 ); -#ifdef ALIGN_SID_SIZE - if ( !st0->bfi && hDecoderConfig->ivas_total_brate == IVAS_SID_5k2 ) - { - last_bit_pos -= SID_FORMAT_NBITS; - } -#endif nb_bits_read_orig = *nb_bits_read; last_bit_pos -= nb_bits_read_orig; @@ -266,17 +264,6 @@ ivas_error ivas_spar_dec( st0->bit_stream = bit_stream_orig; st0->next_bit_pos = next_bit_pos_orig; -#ifdef ALIGN_SID_SIZE - if ( !st0->bfi && hDecoderConfig->ivas_total_brate == IVAS_SID_5k2 ) - { - int16_t zero_pad_bits; - *nb_bits_read += SID_FORMAT_NBITS; - zero_pad_bits = (int16_t) ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC - *nb_bits_read; - assert( zero_pad_bits <= 1 ); - *nb_bits_read += zero_pad_bits; - } -#endif - wmops_sub_end(); return error; @@ -636,8 +623,11 @@ static void ivas_spar_dec_MD( /*---------------------------------------------------------------------* * Initialization *---------------------------------------------------------------------*/ - +#ifndef SBA_ORDER_BITSTREAM + sba_order = min( st_ivas->sba_order, IVAS_MAX_SBA_ORDER ); +#else sba_order = min( st_ivas->sba_analysis_order, IVAS_MAX_SBA_ORDER ); +#endif bfi = st_ivas->bfi; ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate; num_channels = ivas_sba_get_nchan_metadata( sba_order ); @@ -645,11 +635,7 @@ static void ivas_spar_dec_MD( if ( ivas_total_brate > FRAME_NO_DATA && !bfi ) { -#ifdef ALIGN_SID_SIZE - if ( ivas_total_brate > IVAS_SID_5k2 ) -#else if ( ivas_total_brate > IVAS_SID_5k ) -#endif { ivas_parse_spar_header( hDecoderConfig->ivas_total_brate, sba_order, st0, &table_idx ); @@ -683,11 +669,7 @@ static void ivas_spar_dec_MD( * Read AGC bits *---------------------------------------------------------------------*/ -#ifdef ALIGN_SID_SIZE - if ( ivas_total_brate > IVAS_SID_5k2 && !bfi && hSpar->hMdDec->dtx_vad ) -#else if ( ivas_total_brate > IVAS_SID_5k && !bfi && hSpar->hMdDec->dtx_vad ) -#endif { hSpar->AGC_flag = get_next_indice( st0, 1 ); @@ -698,11 +680,7 @@ static void ivas_spar_dec_MD( * MD smoothing *---------------------------------------------------------------------*/ -#ifdef ALIGN_SID_SIZE - if ( st0->m_old_frame_type == ZERO_FRAME && ivas_total_brate == IVAS_SID_5k2 && st0->prev_bfi == 0 && hSpar->hMdDec->spar_md_cfg.nchan_transport == 1 ) -#else if ( st0->m_old_frame_type == ZERO_FRAME && ivas_total_brate == IVAS_SID_5k && st0->prev_bfi == 0 && hSpar->hMdDec->spar_md_cfg.nchan_transport == 1 ) -#endif { ivas_spar_setup_md_smoothing( hSpar->hMdDec, num_bands_out ); } @@ -994,8 +972,9 @@ void ivas_spar_dec_upmixer( /*---------------------------------------------------------------------* * PCA decoder *---------------------------------------------------------------------*/ + #ifdef DEBUG_SBA_AUDIO_DUMP - hSpar->pca_ingest_channels = num_in_ingest; + pState->pca_ingest_channels = num_in_ingest; #endif if ( hSpar->hPCA != NULL ) @@ -1007,7 +986,6 @@ void ivas_spar_dec_upmixer( #endif } - /*---------------------------------------------------------------------* * TD decorrelation *---------------------------------------------------------------------*/ @@ -1186,7 +1164,7 @@ void ivas_spar_dec_upmixer( } } #ifdef DEBUG_SBA_AUDIO_DUMP - hSpar->numOutChannels = outchannels; + pState->numOutChannels = outchannels; #endif } else @@ -1205,12 +1183,12 @@ void ivas_spar_dec_upmixer( } } #ifdef DEBUG_SBA_AUDIO_DUMP - hSpar->numOutChannels = numch_out_dirac; + pState->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()" ); + ivas_spar_dump_signal_wav( output_frame, NULL, output, pState->numOutChannels, spar_foa_dec_wav[3], "cldfbSynthesis()" ); #endif split_band = SPAR_DIRAC_SPLIT_START_BAND; diff --git a/lib_dec/ivas_spar_md_dec.c b/lib_dec/ivas_spar_md_dec.c index c0682c58a2..be1b3fcb10 100644 --- a/lib_dec/ivas_spar_md_dec.c +++ b/lib_dec/ivas_spar_md_dec.c @@ -63,11 +63,11 @@ static const int16_t ivas_spar_dec_plc_spatial_target[IVAS_SPAR_MAX_CH] = { 1, 0 * Static functions declaration *------------------------------------------------------------------------------------------*/ -static void ivas_get_spar_matrices( ivas_spar_md_dec_state_t *hMdDec, const int16_t num_bands_out, const int16_t n_ts, const int16_t bw, const int16_t dtx_vad, const int16_t nB, const int16_t sba_order ); +static void ivas_get_spar_matrices( ivas_spar_md_dec_state_t *pState, const int16_t num_bands_out, const int16_t n_ts, const int16_t bw, const int16_t dtx_vad, const int16_t nB, const int16_t sba_order ); -static void ivas_decode_arith_bs( ivas_spar_md_dec_state_t *hMdDec, Decoder_State *st, const uint16_t qsi, const int16_t nB, const int16_t bands_bw, int16_t *pDo_diff, const int16_t freq_diff, const int16_t planarCP ); +static void ivas_decode_arith_bs( ivas_spar_md_dec_state_t *pState, Decoder_State *st, const uint16_t qsi, const int16_t nB, const int16_t bands_bw, int16_t *pDo_diff, const int16_t freq_diff, const int16_t planarCP ); -static void ivas_decode_huffman_bs( ivas_spar_md_dec_state_t *hMdDec, Decoder_State *st, const uint16_t qsi, const int16_t nB, const int16_t bands_bw, const int16_t planarCP ); +static void ivas_decode_huffman_bs( ivas_spar_md_dec_state_t *pState, Decoder_State *st, const uint16_t qsi, const int16_t nB, const int16_t bands_bw, const int16_t planarCP ); static void ivas_fill_band_coeffs_idx( ivas_band_coeffs_ind_t *pBands_idx, const int16_t nB, int16_t *pSymbol_re, ivas_cell_dim_t *pCell_dims, ivas_coeffs_type_t coeff_type, const int16_t planarCP ); @@ -75,14 +75,16 @@ static void ivas_get_band_idx_from_differential( ivas_spar_md_t *pSpar_md, const static void ivas_mat_col_rearrange( float in_re[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], const int16_t order[IVAS_SPAR_MAX_CH], const int16_t i_ts, float ***mixer_mat, const int16_t bands, const int16_t num_ch ); -static void ivas_spar_dec_compute_ramp_down_post_matrix( ivas_spar_md_dec_state_t *hMdDec, const int16_t num_bands, const int16_t bfi ); +static void ivas_spar_dec_compute_ramp_down_post_matrix( ivas_spar_md_dec_state_t *pState, const int16_t num_bands, const int16_t bfi ); -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 sba_order ); +static void ivas_spar_md_fill_invalid_bands( ivas_spar_dec_matrices_t *pSpar_coeffs, ivas_spar_dec_matrices_t *pSpar_coeffs_prev, int16_t *valid_bands, int16_t *base_band_age, const int16_t num_bands, const int16_t sba_order ); -static ivas_error ivas_spar_set_dec_config( ivas_spar_md_dec_state_t *hMdDec, const int16_t nchan_transport, float *pFC ); +static ivas_error ivas_spar_set_dec_config( ivas_spar_md_dec_state_t *pState, 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 ); -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 ivas_error ivas_deindex_real_index( int16_t **index, const int16_t q_levels, const float min_value, const float max_value, float **quant, const int16_t num_ch, const int16_t 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 use_planar_coeff, const int16_t sba_inactive_mode ); @@ -424,7 +426,7 @@ void ivas_spar_md_dec_close( /*-----------------------------------------------------------------------------------------* * Function ivas_spar_md_dec_init() * - * SPAR MD decoder initialization + * Init call for md dec process *-----------------------------------------------------------------------------------------*/ ivas_error ivas_spar_md_dec_init( @@ -436,11 +438,12 @@ ivas_error ivas_spar_md_dec_init( int16_t i, j, k; int16_t nchan_transport; float pFC[IVAS_MAX_NUM_BANDS], PR_minmax[2]; + ivas_spar_md_dec_state_t *pState = hMdDec; - hMdDec->spar_md_cfg.gen_bs = 1; // VE2DB : always 1 - can it be removed? - ivas_spar_set_bitrate_config( &hMdDec->spar_md_cfg, hMdDec->table_idx, min( IVAS_MAX_NUM_BANDS, SPAR_DIRAC_SPLIT_START_BAND ) ); + pState->spar_md_cfg.gen_bs = 1; + ivas_spar_set_bitrate_config( &pState->spar_md_cfg, pState->table_idx, min( IVAS_MAX_NUM_BANDS, SPAR_DIRAC_SPLIT_START_BAND ) ); - nchan_transport = hMdDec->spar_md_cfg.nchan_transport; + nchan_transport = pState->spar_md_cfg.nchan_transport; /* get FB coefficients */ for ( i = 0; i < IVAS_MAX_NUM_BANDS; i++ ) @@ -448,28 +451,28 @@ ivas_error ivas_spar_md_dec_init( pFC[i] = ivas_fb_fcs_12band_1ms[i] * hDecoderConfig->output_Fs * 0.5f; } - ivas_spar_set_dec_config( hMdDec, nchan_transport, pFC ); + ivas_spar_set_dec_config( pState, nchan_transport, pFC ); - if ( nchan_transport != 2 && ( ( hMdDec->spar_md_cfg.remix_unmix_order == 2 ) || ( hMdDec->spar_md_cfg.remix_unmix_order == 1 ) ) ) + if ( nchan_transport != 2 && ( ( pState->spar_md_cfg.remix_unmix_order == 2 ) || ( pState->spar_md_cfg.remix_unmix_order == 1 ) ) ) { return IVAS_ERR_INTERNAL; } /* DTX quant init */ - PR_minmax[0] = hMdDec->spar_md_cfg.quant_strat[0].PR.min; - PR_minmax[1] = hMdDec->spar_md_cfg.quant_strat[0].PR.max; - ivas_spar_quant_dtx_init( &hMdDec->spar_md, PR_minmax ); + PR_minmax[0] = pState->spar_md_cfg.quant_strat[0].PR.min; + PR_minmax[1] = pState->spar_md_cfg.quant_strat[0].PR.max; + ivas_spar_quant_dtx_init( &pState->spar_md, PR_minmax ); - ivas_spar_arith_coeffs_com_init( &hMdDec->arith_coeffs, &hMdDec->spar_md_cfg, hMdDec->table_idx, DEC ); - ivas_spar_huff_coeffs_com_init( &hMdDec->huff_coeffs, &hMdDec->spar_md_cfg, hMdDec->table_idx, DEC ); + ivas_spar_arith_coeffs_com_init( &pState->arith_coeffs, &pState->spar_md_cfg, pState->table_idx, DEC ); + ivas_spar_huff_coeffs_com_init( &pState->huff_coeffs, &pState->spar_md_cfg, pState->table_idx, DEC ); - hMdDec->spar_md_cfg.prev_quant_idx = -1; + pState->spar_md_cfg.prev_quant_idx = -1; /* initialize PLC state */ - set_s( hMdDec->valid_bands, 0, IVAS_MAX_NUM_BANDS ); - set_s( hMdDec->base_band_age, 0, IVAS_MAX_NUM_BANDS ); - hMdDec->spar_plc_num_lost_frames = 0; - hMdDec->spar_plc_enable_fadeout_flag = 1; + set_s( pState->valid_bands, 0, IVAS_MAX_NUM_BANDS ); + set_s( pState->base_band_age, 0, IVAS_MAX_NUM_BANDS ); + pState->spar_plc_num_lost_frames = 0; + pState->spar_plc_enable_fadeout_flag = 1; for ( i = 0; i < num_channels; i++ ) { @@ -477,7 +480,7 @@ ivas_error ivas_spar_md_dec_init( { for ( k = 0; k < IVAS_MAX_NUM_BANDS; k++ ) { - hMdDec->spar_coeffs_prev.C_re[i][j][k] = 0; + pState->spar_coeffs_prev.C_re[i][j][k] = 0; } } } @@ -488,7 +491,7 @@ ivas_error ivas_spar_md_dec_init( { for ( k = 0; k < IVAS_MAX_NUM_BANDS; k++ ) { - hMdDec->spar_coeffs_prev.P_re[i][j][k] = 0; + pState->spar_coeffs_prev.P_re[i][j][k] = 0; } } } @@ -499,7 +502,7 @@ ivas_error ivas_spar_md_dec_init( { for ( k = 0; k < IVAS_MAX_NUM_BANDS; k++ ) { - hMdDec->spar_coeffs_tar.C_re[i][j][k] = 0; + pState->spar_coeffs_tar.C_re[i][j][k] = 0; } } } @@ -510,24 +513,24 @@ ivas_error ivas_spar_md_dec_init( { for ( k = 0; k < IVAS_MAX_NUM_BANDS; k++ ) { - hMdDec->spar_coeffs_tar.P_re[i][j][k] = 0; + pState->spar_coeffs_tar.P_re[i][j][k] = 0; } } } - hMdDec->dtx_md_smoothing_cntr = 1; + pState->dtx_md_smoothing_cntr = 1; - ivas_clear_band_coeffs( hMdDec->spar_md.band_coeffs, IVAS_MAX_NUM_BANDS ); - 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 ); + ivas_clear_band_coeffs( pState->spar_md.band_coeffs, IVAS_MAX_NUM_BANDS ); + ivas_clear_band_coeff_idx( pState->spar_md.band_coeffs_idx, IVAS_MAX_NUM_BANDS ); + ivas_clear_band_coeff_idx( pState->spar_md_prev.band_coeffs_idx, IVAS_MAX_NUM_BANDS ); + ivas_clear_band_coeff_idx( pState->spar_md_prev.band_coeffs_idx_mapped, IVAS_MAX_NUM_BANDS ); - hMdDec->spar_md.dtx_vad = 0; - hMdDec->spar_md.num_bands = min( IVAS_MAX_NUM_BANDS, SPAR_DIRAC_SPLIT_START_BAND ); - hMdDec->td_decorr_flag = 1; + pState->spar_md.dtx_vad = 0; + pState->spar_md.num_bands = min( IVAS_MAX_NUM_BANDS, SPAR_DIRAC_SPLIT_START_BAND ); + pState->td_decorr_flag = 1; - set_f( hMdDec->spar_md.en_ratio_slow, 0.0f, IVAS_MAX_NUM_BANDS ); - set_f( hMdDec->spar_md.ref_pow_slow, 0.0f, IVAS_MAX_NUM_BANDS ); + set_f( pState->spar_md.en_ratio_slow, 0.0f, IVAS_MAX_NUM_BANDS ); + set_f( pState->spar_md.ref_pow_slow, 0.0f, IVAS_MAX_NUM_BANDS ); return IVAS_ERR_OK; } @@ -536,11 +539,11 @@ ivas_error ivas_spar_md_dec_init( /*-----------------------------------------------------------------------------------------* * Function ivas_spar_set_dec_config() * - * Set configuration for SPAR MD decoder + * Set configuration for SPAR md dec *-----------------------------------------------------------------------------------------*/ static ivas_error ivas_spar_set_dec_config( - ivas_spar_md_dec_state_t *hMdDec, + ivas_spar_md_dec_state_t *pState, const int16_t nchan_transport, float *pFC ) { @@ -548,31 +551,31 @@ static ivas_error ivas_spar_set_dec_config( for ( i = 0; i < nchan_transport; i++ ) { - hMdDec->spar_md_cfg.max_freq_per_chan[i] = ivas_spar_br_table_consts[hMdDec->table_idx].fpcs; + pState->spar_md_cfg.max_freq_per_chan[i] = ivas_spar_br_table_consts[pState->table_idx].fpcs; } - nchan = ivas_sba_get_nchan_metadata( ivas_spar_br_table_consts[hMdDec->table_idx].sba_order ); + nchan = ivas_sba_get_nchan_metadata( ivas_spar_br_table_consts[pState->table_idx].sba_order ); switch ( nchan ) { case 4: /* FOA_CHANNELS */ - hMdDec->num_decorr = IVAS_TD_DECORR_OUT_3CH; + pState->num_decorr = IVAS_TD_DECORR_OUT_3CH; break; case 9: /* IVAS_HOA_2_CH */ // VE: is this relevant? - hMdDec->num_decorr = IVAS_TD_DECORR_OUT_5CH; + pState->num_decorr = IVAS_TD_DECORR_OUT_5CH; break; case 16: /* IVAS_HOA_3_CH */ // VE: is this relevant? - hMdDec->num_decorr = IVAS_TD_DECORR_OUT_12CH; + pState->num_decorr = IVAS_TD_DECORR_OUT_12CH; break; case 6: /* IVAS_HOA_2_CH */ - hMdDec->num_decorr = IVAS_TD_DECORR_OUT_2CH; + pState->num_decorr = IVAS_TD_DECORR_OUT_2CH; break; case 8: /* IVAS_HOA_3_CH */ - hMdDec->num_decorr = IVAS_TD_DECORR_OUT_4CH; + pState->num_decorr = IVAS_TD_DECORR_OUT_4CH; break; } - hMdDec->spar_md_cfg.num_umx_chs = nchan; + pState->spar_md_cfg.num_umx_chs = nchan; dmx_ch = 0; for ( i = 0; i < IVAS_MAX_NUM_BANDS; i++ ) @@ -580,17 +583,17 @@ static ivas_error ivas_spar_set_dec_config( dmx_ch = 0; for ( j = 0; j < nchan_transport; j++ ) { - if ( pFC[i] < hMdDec->spar_md_cfg.max_freq_per_chan[j] ) + if ( pFC[i] < pState->spar_md_cfg.max_freq_per_chan[j] ) { dmx_ch += 1; } } - hMdDec->spar_md_cfg.num_dmx_chans_per_band[i] = hMdDec->spar_md_cfg.nchan_transport; - hMdDec->spar_md_cfg.num_decorr_per_band[i] = nchan - hMdDec->spar_md_cfg.nchan_transport; + pState->spar_md_cfg.num_dmx_chans_per_band[i] = pState->spar_md_cfg.nchan_transport; + pState->spar_md_cfg.num_decorr_per_band[i] = nchan - pState->spar_md_cfg.nchan_transport; } - hMdDec->spar_md_cfg.nchan_transport = dmx_ch; + pState->spar_md_cfg.nchan_transport = dmx_ch; return IVAS_ERR_OK; } @@ -609,10 +612,8 @@ void ivas_spar_md_dec_process( const int16_t sba_order /* i : Ambisonic (SBA) order */ ) { - int16_t j, k, b, bw, dtx_vad, nB, i_ts; - ivas_spar_md_dec_state_t *hMdDec; - - hMdDec = st_ivas->hSpar->hMdDec; + int16_t j, b, bw, dtx_vad, nB, i_ts; + ivas_spar_md_dec_state_t *hMdDec = st_ivas->hSpar->hMdDec; ivas_spar_dec_parse_md_bs( hMdDec, st0, &nB, &bw, &dtx_vad, st_ivas->hDecoderConfig->ivas_total_brate, ivas_spar_br_table_consts[hMdDec->table_idx].usePlanarCoeff, st_ivas->hQMetaData->sba_inactive_mode ); @@ -665,8 +666,8 @@ void ivas_spar_md_dec_process( } #endif - /* SPAR to DirAC and DirAC to SPAR conversion */ // VE2DB: -> "DirAC to SPAR conversion" only? - if ( st_ivas->sba_mode == SBA_MODE_SPAR ) // VE2DB: this looks obsolete + /* SPAR to DirAC and DirAC to SPAR conversion */ + if ( st_ivas->sba_mode == SBA_MODE_SPAR ) { ivas_spar_to_dirac( st_ivas, hMdDec, dtx_vad, num_bands_out ); @@ -690,7 +691,7 @@ void ivas_spar_md_dec_process( for ( j = 0; j < IVAS_SPAR_MAX_CH - IVAS_SPAR_MAX_DMX_CHS; j++ ) { - for ( k = 0; k < IVAS_SPAR_MAX_DMX_CHS - 1; k++ ) + for ( int16_t k = 0; k < IVAS_SPAR_MAX_DMX_CHS - 1; k++ ) { hMdDec->spar_md.band_coeffs[b + i_ts * IVAS_MAX_NUM_BANDS].C_re[j][k] = hMdDec->spar_md.band_coeffs[b].C_re[j][k]; } @@ -735,7 +736,6 @@ void ivas_spar_md_dec_process( * * Smooth MD during no data frame during DTX *-----------------------------------------------------------------------------------------*/ - #ifdef SPAR_HOA_DBG /* NOTE: No changes here as DTX only operates below 160kbps */ #endif @@ -744,23 +744,26 @@ void ivas_spar_smooth_md_dtx( const int16_t num_bands_out /* i : number of output bands */ ) { - int16_t j, k, b, dmx_ch; + int16_t j, k, b; + int16_t dmx_ch; + ivas_spar_md_dec_state_t *pState = hMdDec; float ramp, tar, prev, new_val; - ramp = (float) hMdDec->dtx_md_smoothing_cntr / IVAS_DEFAULT_DTX_CNG_RAMP; + ramp = (float) pState->dtx_md_smoothing_cntr / IVAS_DEFAULT_DTX_CNG_RAMP; for ( b = 0; b < num_bands_out; b++ ) { - dmx_ch = hMdDec->spar_md_cfg.num_dmx_chans_per_band[b]; + dmx_ch = pState->spar_md_cfg.num_dmx_chans_per_band[b]; for ( j = 1; j < FOA_CHANNELS; j++ ) { for ( k = dmx_ch; k < FOA_CHANNELS; k++ ) + { - prev = hMdDec->spar_coeffs_prev.P_re[j][k][b]; - tar = hMdDec->spar_coeffs_tar.P_re[j][k][b]; + prev = pState->spar_coeffs_prev.P_re[j][k][b]; + tar = pState->spar_coeffs_tar.P_re[j][k][b]; new_val = prev + ( ramp * ( tar - prev ) ); - hMdDec->spar_coeffs.P_re[j][k][b] = new_val; + pState->spar_coeffs.P_re[j][k][b] = new_val; } } @@ -768,10 +771,10 @@ void ivas_spar_smooth_md_dtx( { for ( k = 0; k < dmx_ch; k++ ) { - prev = hMdDec->spar_coeffs_prev.C_re[j][k][b]; - tar = hMdDec->spar_coeffs_tar.C_re[j][k][b]; + prev = pState->spar_coeffs_prev.C_re[j][k][b]; + tar = pState->spar_coeffs_tar.C_re[j][k][b]; new_val = prev + ( ramp * ( tar - prev ) ); - hMdDec->spar_coeffs.C_re[j][k][b] = new_val; + pState->spar_coeffs.C_re[j][k][b] = new_val; } } } @@ -781,14 +784,14 @@ void ivas_spar_smooth_md_dtx( { for ( b = 0; b < num_bands_out; b++ ) { - dmx_ch = hMdDec->spar_md_cfg.num_dmx_chans_per_band[b]; + dmx_ch = pState->spar_md_cfg.num_dmx_chans_per_band[b]; for ( j = 1; j < FOA_CHANNELS; j++ ) { for ( k = dmx_ch; k < FOA_CHANNELS; k++ ) { - hMdDec->spar_coeffs.P_re[j][k][b + i_ts * IVAS_MAX_NUM_BANDS] = hMdDec->spar_coeffs.P_re[j][k][b]; + pState->spar_coeffs.P_re[j][k][b + i_ts * IVAS_MAX_NUM_BANDS] = pState->spar_coeffs.P_re[j][k][b]; } } @@ -796,13 +799,13 @@ void ivas_spar_smooth_md_dtx( { for ( k = 0; k < dmx_ch; k++ ) { - hMdDec->spar_coeffs.C_re[j][k][b + i_ts * IVAS_MAX_NUM_BANDS] = hMdDec->spar_coeffs.C_re[j][k][b]; + pState->spar_coeffs.C_re[j][k][b + i_ts * IVAS_MAX_NUM_BANDS] = pState->spar_coeffs.C_re[j][k][b]; } } } } - hMdDec->dtx_md_smoothing_cntr = min( hMdDec->dtx_md_smoothing_cntr + 1, IVAS_DEFAULT_DTX_CNG_RAMP ); + pState->dtx_md_smoothing_cntr = min( pState->dtx_md_smoothing_cntr + 1, IVAS_DEFAULT_DTX_CNG_RAMP ); return; } @@ -942,7 +945,7 @@ void ivas_spar_update_md_hist( *-----------------------------------------------------------------------------------------*/ static void ivas_get_spar_matrices( - ivas_spar_md_dec_state_t *hMdDec, + ivas_spar_md_dec_state_t *pState, const int16_t num_bands_out, const int16_t n_ts, const int16_t bw, @@ -950,15 +953,16 @@ static void ivas_get_spar_matrices( const int16_t nB, const int16_t sba_order ) { - int16_t numch_out, num_bands, dmx_ch, split_band; + int16_t numch_out, num_bands, dmx_ch; int16_t i, j, k, m, b, i_ts, active_w; const int16_t *order; float active_w_dm_fac, re; + int16_t split_band; numch_out = ivas_sba_get_nchan_metadata( sba_order ); num_bands = num_bands_out; - order = remix_order_set[hMdDec->spar_md_cfg.remix_unmix_order]; + order = remix_order_set[pState->spar_md_cfg.remix_unmix_order]; split_band = SPAR_DIRAC_SPLIT_START_BAND; if ( split_band >= IVAS_MAX_NUM_BANDS ) @@ -970,7 +974,7 @@ static void ivas_get_spar_matrices( { for ( b = 0; b < num_bands; b++ ) { - hMdDec->mixer_mat_prev[0][i][j][b] = hMdDec->mixer_mat[i][j][b]; + pState->mixer_mat_prev[0][i][j][b] = pState->mixer_mat[i][j][b]; } } } @@ -979,19 +983,19 @@ static void ivas_get_spar_matrices( #ifdef SPAR_HOA_DBG /*for (b = 0; b < BANDS_12; b++) { - for (i = 0; i < IVAS_SPAR_MAX_CH - 1; i++) + for (i = 0; i < IVAS_SPAR_MAX_CH - 1; i++) + { + pState->spar_md.band_coeffs[b].pred_re[i] = (float)(i + 1)/10; + for (j = 0; j < IVAS_SPAR_MAX_CH - 1; j++) { - hMdDec->spar_md.band_coeffs[b].pred_re[i] = (float)(i + 1)/10; - for (j = 0; j < IVAS_SPAR_MAX_CH - 1; j++) - { - hMdDec->spar_md.band_coeffs[b].C_re[i][j] = (float)(i + j * 20 + 1)/10; - hMdDec->spar_md.band_coeffs[b].P_re[i][j] = (float)(i + j * 20 + 1)/10; - } + pState->spar_md.band_coeffs[b].C_re[i][j] = (float)(i + j * 20 + 1)/10; + pState->spar_md.band_coeffs[b].P_re[i][j] = (float)(i + j * 20 + 1)/10; } + } }*/ #endif - active_w = hMdDec->spar_md_cfg.active_w; + active_w = pState->spar_md_cfg.active_w; active_w_dm_fac = ( dtx_vad == 0 ) ? IVAS_ACTIVEW_DM_F_SCALE_DTX : IVAS_ACTIVEW_DM_F_SCALE; for ( i_ts = 0; i_ts < n_ts; i_ts++ ) @@ -1000,8 +1004,8 @@ static void ivas_get_spar_matrices( { for ( j = 0; j < numch_out; j++ ) { - set_zero( &hMdDec->spar_coeffs.C_re[i][j][i_ts * IVAS_MAX_NUM_BANDS], IVAS_MAX_NUM_BANDS ); - set_zero( &hMdDec->spar_coeffs.P_re[i][j][i_ts * IVAS_MAX_NUM_BANDS], IVAS_MAX_NUM_BANDS ); + set_zero( &pState->spar_coeffs.C_re[i][j][i_ts * IVAS_MAX_NUM_BANDS], IVAS_MAX_NUM_BANDS ); + set_zero( &pState->spar_coeffs.P_re[i][j][i_ts * IVAS_MAX_NUM_BANDS], IVAS_MAX_NUM_BANDS ); } } @@ -1018,7 +1022,7 @@ static void ivas_get_spar_matrices( float tmp_C2_re[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH]; float tmp_dm_re[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH]; - dmx_ch = hMdDec->spar_md_cfg.num_dmx_chans_per_band[bw * b]; + dmx_ch = pState->spar_md_cfg.num_dmx_chans_per_band[bw * b]; for ( j = 0; j < numch_out; j++ ) { @@ -1033,14 +1037,14 @@ static void ivas_get_spar_matrices( for ( j = 1; j < numch_out; j++ ) { - tmp_C1_re[j][0] = hMdDec->spar_md.band_coeffs[b + i_ts * IVAS_MAX_NUM_BANDS].pred_re[j - 1]; + tmp_C1_re[j][0] = pState->spar_md.band_coeffs[b + i_ts * IVAS_MAX_NUM_BANDS].pred_re[j - 1]; } if ( active_w == 1 ) { for ( j = 1; j < numch_out; j++ ) { - tmp_C2_re[0][j] = active_w_dm_fac * -hMdDec->spar_md.band_coeffs[b + i_ts * IVAS_MAX_NUM_BANDS].pred_re[j - 1]; + tmp_C2_re[0][j] = active_w_dm_fac * -pState->spar_md.band_coeffs[b + i_ts * IVAS_MAX_NUM_BANDS].pred_re[j - 1]; } IVAS_RMULT_FLOAT( tmp_C2_re[0][1], tmp_C1_re[1][0], re ); @@ -1064,9 +1068,9 @@ static void ivas_get_spar_matrices( tmp_dm_re[3][0] = tmp_C1_re[3][0]; - if ( hMdDec->spar_md_cfg.remix_unmix_order != 3 ) + if ( pState->spar_md_cfg.remix_unmix_order != 3 ) { - ivas_mat_col_rearrange( tmp_dm_re, order, i_ts, hMdDec->mixer_mat, b, numch_out ); + ivas_mat_col_rearrange( tmp_dm_re, order, i_ts, pState->mixer_mat, b, numch_out ); } else { @@ -1074,24 +1078,24 @@ static void ivas_get_spar_matrices( for ( i = 0; i < FOA_CHANNELS; i++ ) { /* row 0 */ - hMdDec->mixer_mat[i][0][b + i_ts * IVAS_MAX_NUM_BANDS] = tmp_dm_re[i][0]; + pState->mixer_mat[i][0][b + i_ts * IVAS_MAX_NUM_BANDS] = tmp_dm_re[i][0]; /* row 1 */ - hMdDec->mixer_mat[i][1][b + i_ts * IVAS_MAX_NUM_BANDS] = tmp_dm_re[i][1]; + pState->mixer_mat[i][1][b + i_ts * IVAS_MAX_NUM_BANDS] = tmp_dm_re[i][1]; /* row 3 */ - hMdDec->mixer_mat[i][2][b + i_ts * IVAS_MAX_NUM_BANDS] = tmp_dm_re[i][1]; + pState->mixer_mat[i][2][b + i_ts * IVAS_MAX_NUM_BANDS] = tmp_dm_re[i][1]; /* row 4 */ - hMdDec->mixer_mat[i][3][b + i_ts * IVAS_MAX_NUM_BANDS] = tmp_dm_re[i][2]; + pState->mixer_mat[i][3][b + i_ts * IVAS_MAX_NUM_BANDS] = tmp_dm_re[i][2]; } } } else { - if ( hMdDec->spar_md_cfg.remix_unmix_order != 3 ) + if ( pState->spar_md_cfg.remix_unmix_order != 3 ) { - ivas_mat_col_rearrange( tmp_C1_re, order, i_ts, hMdDec->mixer_mat, b, numch_out ); + ivas_mat_col_rearrange( tmp_C1_re, order, i_ts, pState->mixer_mat, b, numch_out ); } else { @@ -1099,16 +1103,16 @@ static void ivas_get_spar_matrices( for ( i = 0; i < FOA_CHANNELS; i++ ) { /* row 0 */ - hMdDec->mixer_mat[i][0][b + i_ts * IVAS_MAX_NUM_BANDS] = tmp_C1_re[i][0]; + pState->mixer_mat[i][0][b + i_ts * IVAS_MAX_NUM_BANDS] = tmp_C1_re[i][0]; /* row 1 */ - hMdDec->mixer_mat[i][1][b + i_ts * IVAS_MAX_NUM_BANDS] = tmp_C1_re[i][1]; + pState->mixer_mat[i][1][b + i_ts * IVAS_MAX_NUM_BANDS] = tmp_C1_re[i][1]; /* row 3 */ - hMdDec->mixer_mat[i][2][b + i_ts * IVAS_MAX_NUM_BANDS] = tmp_C1_re[i][1]; + pState->mixer_mat[i][2][b + i_ts * IVAS_MAX_NUM_BANDS] = tmp_C1_re[i][1]; /* row 4 */ - hMdDec->mixer_mat[i][3][b + i_ts * IVAS_MAX_NUM_BANDS] = tmp_C1_re[i][2]; + pState->mixer_mat[i][3][b + i_ts * IVAS_MAX_NUM_BANDS] = tmp_C1_re[i][2]; } } } @@ -1138,28 +1142,28 @@ static void ivas_get_spar_matrices( { for ( k = 1; k < dmx_ch; k++ ) { - tmpC_re[j][k] = hMdDec->spar_md.band_coeffs[b + i_ts * IVAS_MAX_NUM_BANDS].C_re[j - dmx_ch][k - 1]; + tmpC_re[j][k] = pState->spar_md.band_coeffs[b + i_ts * IVAS_MAX_NUM_BANDS].C_re[j - dmx_ch][k - 1]; } } #ifdef SPAR_HOA_DBG /*fprintf(stdout, "C matrix1: %d x %d\n\n", numch_out, dmx_ch); for (j = 0; j < numch_out; j++) { - for (k = 0; k < dmx_ch; k++) - { - fprintf(stdout, "%f, ", tmpC_re[j][k]); - } - fprintf(stdout, "\n"); + for (k = 0; k < dmx_ch; k++) + { + fprintf(stdout, "%f, ", tmpC_re[j][k]); + } + fprintf(stdout, "\n"); } fprintf(stdout, "Mixer Mat: %d x %d\n\n", numch_out, numch_out); for ( j = 0; j < numch_out; j++) { - for (k = 0; k < numch_out; k++) - { - fprintf(stdout, "%f, ", hMdDec->mixer_mat[j][k][0][b]); - } - fprintf(stdout, "\n"); + for (k = 0; k < numch_out; k++) + { + fprintf(stdout, "%f, ", pState->mixer_mat[j][k][0][b]); + } + fprintf(stdout, "\n"); }*/ #endif @@ -1169,7 +1173,7 @@ static void ivas_get_spar_matrices( { if ( ( j - dmx_ch ) == ( k - dmx_ch ) ) { - tmpP_re[j][k] = hMdDec->spar_md.band_coeffs[b + i_ts * IVAS_MAX_NUM_BANDS].P_re[k - dmx_ch]; + tmpP_re[j][k] = pState->spar_md.band_coeffs[b + i_ts * IVAS_MAX_NUM_BANDS].P_re[k - dmx_ch]; } else { @@ -1180,26 +1184,26 @@ static void ivas_get_spar_matrices( #ifdef SPAR_HOA_DBG /*if (b == 0) { - fprintf(stdout, "tmp_P matrix: %d x %d\n\n", numch_out, dmx_ch); - for (j = 0; j < numch_out; j++) + fprintf(stdout, "tmp_P matrix: %d x %d\n\n", numch_out, dmx_ch); + for (j = 0; j < numch_out; j++) + { + for (k = 0; k < numch_out; k++) { - for (k = 0; k < numch_out; k++) - { - fprintf(stdout, "%f, ", tmpP_re[j][k]); - } - fprintf(stdout, "\n"); - + fprintf(stdout, "%f, ", tmpP_re[j][k]); } - fprintf(stdout, "Mixer Mat: %d x %d\n\n", numch_out, numch_out); - for (j = 0; j < numch_out; j++) - { - for (k = 0; k < numch_out; k++) - { - fprintf(stdout, "%f, ", hMdDec->mixer_mat[j][k][0][b]); - } - fprintf(stdout, "\n"); + fprintf(stdout, "\n"); + } + fprintf(stdout, "Mixer Mat: %d x %d\n\n", numch_out, numch_out); + for (j = 0; j < numch_out; j++) + { + for (k = 0; k < numch_out; k++) + { + fprintf(stdout, "%f, ", pState->mixer_mat[j][k][0][b]); } + fprintf(stdout, "\n"); + + } }*/ #endif for ( j = 1; j < numch_out; j++ ) @@ -1209,8 +1213,8 @@ static void ivas_get_spar_matrices( { for ( m = 0; m < numch_out; m++ ) { - IVAS_RMULT_FLOAT( hMdDec->mixer_mat[j][m][b + i_ts * IVAS_MAX_NUM_BANDS], tmpP_re[m][k], re ); - hMdDec->spar_coeffs.P_re[j][k][( b * bw ) + i_ts * IVAS_MAX_NUM_BANDS] += re; + IVAS_RMULT_FLOAT( pState->mixer_mat[j][m][b + i_ts * IVAS_MAX_NUM_BANDS], tmpP_re[m][k], re ); + pState->spar_coeffs.P_re[j][k][( b * bw ) + i_ts * IVAS_MAX_NUM_BANDS] += re; } } } @@ -1221,8 +1225,8 @@ static void ivas_get_spar_matrices( { for ( m = 0; m < numch_out; m++ ) { - IVAS_RMULT_FLOAT( hMdDec->mixer_mat[j][m][b + i_ts * IVAS_MAX_NUM_BANDS], tmpC_re[m][k], re ); - hMdDec->spar_coeffs.C_re[j][k][( b * bw ) + i_ts * IVAS_MAX_NUM_BANDS] += re; + IVAS_RMULT_FLOAT( pState->mixer_mat[j][m][b + i_ts * IVAS_MAX_NUM_BANDS], tmpC_re[m][k], re ); + pState->spar_coeffs.C_re[j][k][( b * bw ) + i_ts * IVAS_MAX_NUM_BANDS] += re; } } } @@ -1230,42 +1234,42 @@ static void ivas_get_spar_matrices( /*fprintf(stdout, "C matrix1: %d x %d\n\n", numch_out, dmx_ch); for (j = 0; j < numch_out; j++) { - for (k = 0; k < dmx_ch; k++) - { - fprintf(stdout, "%f, ", hMdDec->spar_coeffs.C_re[j][k][b]); - } - fprintf(stdout, "\n"); + for (k = 0; k < dmx_ch; k++) + { + fprintf(stdout, "%f, ", pState->spar_coeffs.C_re[j][k][b]); + } + fprintf(stdout, "\n"); }*/ #endif - hMdDec->spar_coeffs.C_re[0][0][( b * bw ) + i_ts * IVAS_MAX_NUM_BANDS] = - max( 0, hMdDec->spar_coeffs.C_re[0][0][( b * bw ) + i_ts * IVAS_MAX_NUM_BANDS] ); + pState->spar_coeffs.C_re[0][0][( b * bw ) + i_ts * IVAS_MAX_NUM_BANDS] = + max( 0, pState->spar_coeffs.C_re[0][0][( b * bw ) + i_ts * IVAS_MAX_NUM_BANDS] ); } } #ifdef SPAR_HOA_DBG /* for (b = 0; b < 1; b++) { - fprintf(stdout, "C matrix: %d x %d band %d\n\n", numch_out, dmx_ch, b); - for (j = 0; j < numch_out; j++) + fprintf(stdout, "C matrix: %d x %d band %d\n\n", numch_out, dmx_ch, b); + for (j = 0; j < numch_out; j++) + { + for (k = 0; k < numch_out; k++) { - for (k = 0; k < numch_out; k++) - { - fprintf(stdout, "%f, ", hMdDec->spar_coeffs.C_re[j][k][b]); - } - fprintf(stdout, "\n"); - + fprintf(stdout, "%f, ", pState->spar_coeffs.C_re[j][k][b]); } - fprintf(stdout, "\nP matrix: %d x %d\n\n", numch_out, numch_out); + fprintf(stdout, "\n"); - for (j = 0; j < numch_out; j++) - { - for (k = 0; k < numch_out; k++) - { - fprintf(stdout, "%f, ", hMdDec->spar_coeffs.P_re[j][k][b]); - } - fprintf(stdout, "\n"); + } + fprintf(stdout, "\nP matrix: %d x %d\n\n", numch_out, numch_out); + for (j = 0; j < numch_out; j++) + { + for (k = 0; k < numch_out; k++) + { + fprintf(stdout, "%f, ", pState->spar_coeffs.P_re[j][k][b]); } + fprintf(stdout, "\n"); + + } }*/ #endif @@ -1274,12 +1278,12 @@ static void ivas_get_spar_matrices( { for ( b = 0; b < num_bands_out; b = b + bw ) { - dmx_ch = hMdDec->spar_md_cfg.num_dmx_chans_per_band[b]; + dmx_ch = pState->spar_md_cfg.num_dmx_chans_per_band[b]; for ( j = 0; j < numch_out; j++ ) { for ( k = dmx_ch; k < numch_out; k++ ) { - hMdDec->spar_coeffs.P_re[j][k][( b + 1 ) + i_ts * IVAS_MAX_NUM_BANDS] = hMdDec->spar_coeffs.P_re[j][k][b + i_ts * IVAS_MAX_NUM_BANDS]; + pState->spar_coeffs.P_re[j][k][( b + 1 ) + i_ts * IVAS_MAX_NUM_BANDS] = pState->spar_coeffs.P_re[j][k][b + i_ts * IVAS_MAX_NUM_BANDS]; } } @@ -1287,7 +1291,7 @@ static void ivas_get_spar_matrices( { for ( k = 0; k < dmx_ch; k++ ) { - hMdDec->spar_coeffs.C_re[j][k][( b + 1 ) + i_ts * IVAS_MAX_NUM_BANDS] = hMdDec->spar_coeffs.C_re[j][k][b + i_ts * IVAS_MAX_NUM_BANDS]; + pState->spar_coeffs.C_re[j][k][( b + 1 ) + i_ts * IVAS_MAX_NUM_BANDS] = pState->spar_coeffs.C_re[j][k][b + i_ts * IVAS_MAX_NUM_BANDS]; } } } @@ -1341,14 +1345,14 @@ void ivas_spar_dec_gen_umx_mat( const int16_t bfi /* i : bad frame indicator */ ) { - int16_t i, j, b, i_ts, num_out_ch; - int16_t fb_ducking_flag = 0; // VE2DB: always 0 - can it be removed? - - num_out_ch = hMdDec->spar_md_cfg.num_umx_chs; + int16_t i, j, b, i_ts; + int16_t fb_ducking_flag = 0; + int16_t num_out_ch = hMdDec->spar_md_cfg.num_umx_chs; + ivas_spar_md_dec_state_t *pState = hMdDec; for ( i_ts = 0; i_ts < MAX_PARAM_SPATIAL_SUBFRAMES; i_ts++ ) { - if ( hMdDec->td_decorr_flag == 1 ) + if ( pState->td_decorr_flag == 1 ) { for ( i = 0; i < num_out_ch; i++ ) { @@ -1356,7 +1360,7 @@ void ivas_spar_dec_gen_umx_mat( { for ( b = 0; b < num_bands_out; b++ ) { - hMdDec->mixer_mat[i][j][b + i_ts * IVAS_MAX_NUM_BANDS] = hMdDec->spar_coeffs.C_re[i][j][b + i_ts * IVAS_MAX_NUM_BANDS]; + pState->mixer_mat[i][j][b + i_ts * IVAS_MAX_NUM_BANDS] = pState->spar_coeffs.C_re[i][j][b + i_ts * IVAS_MAX_NUM_BANDS]; } } } @@ -1367,7 +1371,7 @@ void ivas_spar_dec_gen_umx_mat( { for ( b = 0; b < num_bands_out; b++ ) { - hMdDec->mixer_mat[i][j][b + i_ts * IVAS_MAX_NUM_BANDS] = hMdDec->spar_coeffs.P_re[i][j][b + i_ts * IVAS_MAX_NUM_BANDS]; + pState->mixer_mat[i][j][b + i_ts * IVAS_MAX_NUM_BANDS] = pState->spar_coeffs.P_re[i][j][b + i_ts * IVAS_MAX_NUM_BANDS]; } } } @@ -1385,7 +1389,7 @@ void ivas_spar_dec_gen_umx_mat( { for ( b = 0; b < num_bands_out; b++ ) { - hMdDec->mixer_mat[i][j][b + i_ts * IVAS_MAX_NUM_BANDS] = hMdDec->spar_coeffs.C_re[i][j][b + i_ts * IVAS_MAX_NUM_BANDS]; + pState->mixer_mat[i][j][b + i_ts * IVAS_MAX_NUM_BANDS] = pState->spar_coeffs.C_re[i][j][b + i_ts * IVAS_MAX_NUM_BANDS]; } } } @@ -1395,20 +1399,20 @@ void ivas_spar_dec_gen_umx_mat( /* for ( b = 0; b < 1; b++) { - fprintf( stdout, "\n\nMixer Matrix band %d\n\n", b ); - for ( i = 0; i < num_out_ch; i++ ) + fprintf( stdout, "\n\nMixer Matrix band %d\n\n", b ); + for ( i = 0; i < num_out_ch; i++ ) + { + for ( j = 0; j < num_out_ch; j++ ) { - for ( j = 0; j < num_out_ch; j++ ) - { - fprintf( stdout, "%.2f,\t", hMdDec->mixer_mat[i][j][0][b] ); - } - fprintf( stdout, "\n" ); + fprintf( stdout, "%.2f,\t", pState->mixer_mat[i][j][0][b] ); } fprintf( stdout, "\n" ); + } + fprintf( stdout, "\n" ); }*/ #endif - ivas_spar_dec_compute_ramp_down_post_matrix( hMdDec, num_bands_out, bfi ); + ivas_spar_dec_compute_ramp_down_post_matrix( pState, num_bands_out, bfi ); return; } @@ -1417,7 +1421,7 @@ void ivas_spar_dec_gen_umx_mat( /*-----------------------------------------------------------------------------------------* * Function ivas_spar_dec_parse_md_bs() * - * Parse SPAR MD bitstream + * Parses SPAR MD bitstream *-----------------------------------------------------------------------------------------*/ static void ivas_spar_dec_parse_md_bs( @@ -1433,6 +1437,7 @@ static void ivas_spar_dec_parse_md_bs( int16_t i, j, k, num_bands; uint16_t qsi; ivas_quant_strat_t qs; + ivas_spar_md_dec_state_t *pState = hMdDec; int16_t strat, freq_diff, no_ec; int16_t do_diff[IVAS_MAX_NUM_BANDS]; int16_t planarCP = 0; @@ -1440,17 +1445,13 @@ static void ivas_spar_dec_parse_md_bs( *dtx_vad = 1; *bands_bw = 1; qsi = 0; - num_bands = hMdDec->spar_md.num_bands; + num_bands = pState->spar_md.num_bands; - if ( hMdDec->spar_md_cfg.gen_bs == 1 ) + if ( pState->spar_md_cfg.gen_bs == 1 ) { -#ifdef ALIGN_SID_SIZE - if ( ivas_total_brate > IVAS_SID_5k2 ) -#else if ( ivas_total_brate > IVAS_SID_5k ) -#endif { - if ( hMdDec->spar_md_cfg.quant_strat_bits > 0 ) + if ( pState->spar_md_cfg.quant_strat_bits > 0 ) { if ( ivas_total_brate >= BRATE_SPAR_Q_STRAT ) { @@ -1466,11 +1467,11 @@ static void ivas_spar_dec_parse_md_bs( if ( sba_inactive_mode == 1 ) { *dtx_vad = 0; - qsi = hMdDec->spar_md_cfg.quant_strat_bits + 1; + qsi = pState->spar_md_cfg.quant_strat_bits + 1; } else { - qsi = get_next_indice( st0, hMdDec->spar_md_cfg.quant_strat_bits ); + qsi = get_next_indice( st0, pState->spar_md_cfg.quant_strat_bits ); } } } @@ -1495,10 +1496,10 @@ static void ivas_spar_dec_parse_md_bs( { for ( j = 0; j < IVAS_SPAR_MAX_CH - 1; j++ ) { - hMdDec->spar_md.band_coeffs[i].pred_re[j] = 0; - hMdDec->spar_md.band_coeffs[i].P_re[j] = 0; + pState->spar_md.band_coeffs[i].pred_re[j] = 0; + pState->spar_md.band_coeffs[i].P_re[j] = 0; } - hMdDec->valid_bands[i] = 1; + pState->valid_bands[i] = 1; } for ( i = 0; i < num_bands; i++ ) { @@ -1506,31 +1507,31 @@ static void ivas_spar_dec_parse_md_bs( { for ( k = 0; k < ( IVAS_SPAR_MAX_DMX_CHS - 1 ); k++ ) { - hMdDec->spar_md.band_coeffs[i].C_re[j][k] = 0; + pState->spar_md.band_coeffs[i].C_re[j][k] = 0; } } } - 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 ); + ivas_parse_parameter_bitstream_dtx( &pState->spar_md, st0, *bands_bw, *nB, + pState->spar_md_cfg.num_dmx_chans_per_band, pState->spar_md_cfg.num_decorr_per_band ); { int16_t ndec, b, idx; for ( i = *nB - 1; i >= 0; i-- ) { - ndec = hMdDec->spar_md_cfg.num_decorr_per_band[( *bands_bw ) * i]; + ndec = pState->spar_md_cfg.num_decorr_per_band[( *bands_bw ) * i]; for ( b = *bands_bw - 1; b >= 0; b-- ) { idx = i * *bands_bw + 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]; + pState->spar_md.band_coeffs[idx].pred_re[j] = pState->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]; + pState->spar_md.band_coeffs[idx].P_re[j] = pState->spar_md.band_coeffs[i].P_re[j]; } - hMdDec->valid_bands[idx] = 1; + pState->valid_bands[idx] = 1; } } *nB = num_bands; @@ -1540,7 +1541,7 @@ static void ivas_spar_dec_parse_md_bs( return; } - qs = hMdDec->spar_md_cfg.quant_strat[qsi]; + qs = pState->spar_md_cfg.quant_strat[qsi]; if ( ( qsi == 2 ) && ( use_planar_coeff ) ) { planarCP = 1; @@ -1584,122 +1585,164 @@ static void ivas_spar_dec_parse_md_bs( do_diff[i] = ( ( ( i + 1 ) & 3 ) != strat - 4 ); } - ivas_map_prior_coeffs_quant( &hMdDec->spar_md_prev, &hMdDec->spar_md_cfg, qsi, *nB ); + ivas_map_prior_coeffs_quant( &pState->spar_md_prev, &pState->spar_md_cfg, qsi, *nB ); } #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; + pState->spar_md_cfg.prev_quant_idx = qsi; if ( no_ec == 0 ) { - ivas_decode_arith_bs( hMdDec, st0, qsi, *nB, *bands_bw, do_diff, freq_diff, planarCP ); + ivas_decode_arith_bs( pState, st0, qsi, *nB, *bands_bw, do_diff, freq_diff, planarCP ); } else { - ivas_decode_huffman_bs( hMdDec, st0, qsi, *nB, *bands_bw, planarCP ); + ivas_decode_huffman_bs( pState, st0, qsi, *nB, *bands_bw, planarCP ); } for ( i = 0; i < *nB; i++ ) { int16_t ii, jj; - int16_t ndec = hMdDec->spar_md_cfg.num_decorr_per_band[( *bands_bw ) * i]; - int16_t ndm = hMdDec->spar_md_cfg.num_dmx_chans_per_band[( *bands_bw ) * i]; - float quant[IVAS_SPAR_MAX_C_COEFF]; - ivas_deindex_real_index( hMdDec->spar_md.band_coeffs_idx[i].pred_index_re, qs.PR.q_levels[0], qs.PR.min, qs.PR.max, hMdDec->spar_md.band_coeffs[i].pred_re, ndm + ndec - 1 ); + int16_t *index_scratch[IVAS_SPAR_P_LOWERTRI]; + float *quant_scratch[IVAS_SPAR_P_LOWERTRI]; + int16_t ndec = pState->spar_md_cfg.num_decorr_per_band[( *bands_bw ) * i]; + int16_t ndm = pState->spar_md_cfg.num_dmx_chans_per_band[( *bands_bw ) * i]; + int16_t **index = (int16_t **) &index_scratch[0]; + float **quant = (float **) &quant_scratch[0]; + float coeff_decd[IVAS_SPAR_MAX_CH - 1]; + float coeff_decx_re[IVAS_SPAR_P_LOWERTRI]; + int16_t pred_index_re[IVAS_SPAR_MAX_CH - 1]; + int16_t drct_index_re[IVAS_SPAR_MAX_C_COEFF]; + int16_t decd_index_re[IVAS_SPAR_MAX_CH - 1]; + int16_t decx_index_re[IVAS_SPAR_P_LOWERTRI]; - j = 0; + for ( j = 0; j < ndm + ndec - 1; j++ ) + { + pred_index_re[j] = pState->spar_md.band_coeffs_idx[i].pred_index_re[j]; + } + for ( j = 0; j < ndec * ( ndm - 1 ); j++ ) + { + drct_index_re[j] = pState->spar_md.band_coeffs_idx[i].drct_index_re[j]; + } + for ( j = 0; j < ndec; j++ ) + { + decd_index_re[j] = pState->spar_md.band_coeffs_idx[i].decd_index_re[j]; + } + + index[0] = &pred_index_re[0]; + quant[0] = &pState->spar_md.band_coeffs[i].pred_re[0]; + + ivas_deindex_real_index( index, qs.PR.q_levels[0], qs.PR.min, qs.PR.max, quant, 1, ndm + ndec - 1 ); for ( ii = 0; ii < ndec; ii++ ) { for ( jj = 0; jj < ndm - 1; jj++ ) { - quant[j] = hMdDec->spar_md.band_coeffs[i].C_re[ii][jj]; - j++; + pState->spar_md.band_coeffs[i].C_re[ii][jj] = 0; } } - ivas_deindex_real_index( hMdDec->spar_md.band_coeffs_idx[i].drct_index_re, qs.C.q_levels[0], qs.C.min, qs.C.max, quant, ndec * ( ndm - 1 ) ); j = 0; for ( ii = 0; ii < ndec; ii++ ) { for ( jj = 0; jj < ndm - 1; jj++ ) { - hMdDec->spar_md.band_coeffs[i].C_re[ii][jj] = quant[j]; + index[j] = &drct_index_re[j]; + quant[j] = &pState->spar_md.band_coeffs[i].C_re[ii][jj]; j++; } } - ivas_deindex_real_index( hMdDec->spar_md.band_coeffs_idx[i].decd_index_re, qs.P_r.q_levels[0], qs.P_r.min, qs.P_r.max, hMdDec->spar_md.band_coeffs[i].P_re, ndm + ndec - 1 ); + ivas_deindex_real_index( index, qs.C.q_levels[0], qs.C.min, qs.C.max, quant, ndec * ( ndm - 1 ), 1 ); + + index[0] = &decd_index_re[0]; + quant[0] = &coeff_decd[0]; + ivas_deindex_real_index( index, qs.P_r.q_levels[0], qs.P_r.min, qs.P_r.max, quant, 1, ndm + ndec - 1 ); + + index[0] = &decx_index_re[0]; + quant[0] = &coeff_decx_re[0]; + ivas_deindex_real_index( index, qs.P_c.q_levels[0], qs.P_c.min, qs.P_c.max, quant, 1, ndec * ( ndec - 1 ) >> 2 ); + /* Store prior coefficient indices */ for ( j = 0; j < ndm + ndec - 1; j++ ) { - hMdDec->spar_md_prev.band_coeffs_idx[i].pred_index_re[j] = hMdDec->spar_md.band_coeffs_idx[i].pred_index_re[j]; + pState->spar_md_prev.band_coeffs_idx[i].pred_index_re[j] = pred_index_re[j]; } for ( j = 0; j < ndec * ( ndm - 1 ); j++ ) { - hMdDec->spar_md_prev.band_coeffs_idx[i].drct_index_re[j] = hMdDec->spar_md.band_coeffs_idx[i].drct_index_re[j]; + pState->spar_md_prev.band_coeffs_idx[i].drct_index_re[j] = drct_index_re[j]; + } + for ( j = 0; j < ndec; j++ ) + { + pState->spar_md_prev.band_coeffs_idx[i].decd_index_re[j] = decd_index_re[j]; + } + for ( k = 0; k < ndec; k++ ) + { + pState->spar_md.band_coeffs[i].P_re[k] = 0; } for ( j = 0; j < ndec; j++ ) { - hMdDec->spar_md_prev.band_coeffs_idx[i].decd_index_re[j] = hMdDec->spar_md.band_coeffs_idx[i].decd_index_re[j]; + /* Don't bother adding in the decx parameters */ + pState->spar_md.band_coeffs[i].P_re[j] = coeff_decd[j]; } - hMdDec->valid_bands[i] |= ( do_diff[i] == 0 ) ? 1 : 0; + + pState->valid_bands[i] |= ( do_diff[i] == 0 ) ? 1 : 0; } } else { - *dtx_vad = hMdDec->spar_md.dtx_vad; + *dtx_vad = pState->spar_md.dtx_vad; *nB = num_bands; *bands_bw = num_bands / *nB; for ( i = 0; i < *nB; i++ ) { - hMdDec->valid_bands[i] = 1; + pState->valid_bands[i] = 1; } } #ifdef SPAR_HOA_DBG int16_t b; b = 0; - /*if ( 0 ) + /* if (0) { for ( b = 0; b < *nB; b++ ) { - int16_t ndec = hMdDec->spar_md_cfg.num_decorr_per_band[( *bands_bw ) * b]; - int16_t ndm = hMdDec->spar_md_cfg.num_dmx_chans_per_band[( *bands_bw ) * b]; - fprintf( stdout, "\n\nMETADATA PR: band %d, qsi %d\n\n", b, qsi ); - for ( i = 0; i < ndm + ndec - 1; i++ ) + int16_t ndec = pState->spar_md_cfg.num_decorr_per_band[(*bands_bw) * b]; + int16_t ndm = pState->spar_md_cfg.num_dmx_chans_per_band[(*bands_bw) * b]; + fprintf(stdout, "\n\nMETADATA PR: band %d, qsi %d\n\n", b, qsi); + for (i = 0; i < ndm + ndec - 1; i++) { - fprintf( stdout, "i: %d -- %f\t %d\t %d\n", i, - hMdDec->spar_md.band_coeffs[b].pred_re[i], - hMdDec->spar_md_prev.band_coeffs_idx[b].pred_index_re[i], - hMdDec->spar_md.band_coeffs_idx[b].pred_index_re[i] ); + fprintf(stdout, "i: %d -- %f\t %d\t %d\n", i, + pState->spar_md.band_coeffs[b].pred_re[i], + pState->spar_md_prev.band_coeffs_idx[b].pred_index_re[i], + pState->spar_md.band_coeffs_idx[b].pred_index_re[i]); } - fprintf( stdout, "\n\n METADATA C: band %d\n\n", b ); + fprintf(stdout, "\n\n METADATA C: band %d\n\n", b); k = 0; - for ( i = 0; i < ndec; i++ ) + for (i = 0; i < ndec; i++) { - for ( j = 0; j < ( ndm - 1 ); j++ ) + for (j = 0; j < (ndm - 1); j++) { - fprintf( stdout, "i: %d -- %f\t %d\t %d\n", i, - hMdDec->spar_md.band_coeffs[b].C_re[i][j], - hMdDec->spar_md_prev.band_coeffs_idx[b].drct_index_re[k], - hMdDec->spar_md.band_coeffs_idx[b].drct_index_re[k] ); + fprintf(stdout, "i: %d -- %f\t %d\t %d\n", i, + pState->spar_md.band_coeffs[b].C_re[i][j], + pState->spar_md_prev.band_coeffs_idx[b].drct_index_re[k], + pState->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 < ndec; i++ ) + fprintf(stdout, "\n\n METADATA Pd: band %d\n\n", b); + for (i = 0; i < ndec; i++) { - fprintf( stdout, "i: %d -- %f\t %d\t %d\n", i, - hMdDec->spar_md.band_coeffs[b].P_re[i][i], - hMdDec->spar_md_prev.band_coeffs_idx[b].decd_index_re[i], - hMdDec->spar_md.band_coeffs_idx[b].decd_index_re[i] ); + fprintf(stdout, "i: %d -- %f\t %d\t %d\n", i, + pState->spar_md.band_coeffs[b].P_re[i][i], + pState->spar_md_prev.band_coeffs_idx[b].decd_index_re[i], + pState->spar_md.band_coeffs_idx[b].decd_index_re[i]); } - fprintf( stdout, "\n\n" ); - int16_t ndec = hMdDec->spar_md_cfg.num_decorr_per_band[( *bands_bw ) * b]; - int16_t ndm = hMdDec->spar_md_cfg.num_dmx_chans_per_band[( *bands_bw ) * b]; + fprintf(stdout, "\n\n"); + int16_t ndec = pState->spar_md_cfg.num_decorr_per_band[( *bands_bw ) * b]; + int16_t ndm = pState->spar_md_cfg.num_dmx_chans_per_band[( *bands_bw ) * b]; fprintf( stdout, "\n\n Metadata PR (15x1), C(15x15), P(15x15): band %d\n", b ); for ( i = 0; i < ndm + ndec - 1; i++ ) { - fprintf( stdout, "i: %d -- %.2f\t|\t", i, hMdDec->spar_md.band_coeffs[b].pred_re[i] ); + fprintf( stdout, "i: %d -- %.2f\t|\t", i, pState->spar_md.band_coeffs[b].pred_re[i] ); if ( i < ndec ) { if ( keep_planar[i] == 1 ) @@ -1712,12 +1755,12 @@ static void ivas_spar_dec_parse_md_bs( } for ( j = 0; j < ndm - 1; j++ ) { - fprintf( stdout, "%.2f\t", hMdDec->spar_md.band_coeffs[b].C_re[i][j] ); + fprintf( stdout, "%.2f\t", pState->spar_md.band_coeffs[b].C_re[i][j] ); } fprintf( stdout, "|\t" ); for ( j = 0; j < ndec; j++ ) { - fprintf( stdout, "%.2f\t", hMdDec->spar_md.band_coeffs[b].P_re[i][j] ); + fprintf( stdout, "%.2f\t", pState->spar_md.band_coeffs[b].P_re[i][j] ); } } fprintf( stdout, "\n" ); @@ -1734,11 +1777,11 @@ static void ivas_spar_dec_parse_md_bs( /*-----------------------------------------------------------------------------------------* * Function ivas_decode_arith_bs() * - * Decode bitstream with arith decoder + * decode bitstream with arith decoder *-----------------------------------------------------------------------------------------*/ static void ivas_decode_arith_bs( - ivas_spar_md_dec_state_t *hMdDec, + ivas_spar_md_dec_state_t *pState, Decoder_State *st0, /* i/o: decoder state structure - for bitstream handling*/ const uint16_t qsi, const int16_t nB, @@ -1758,8 +1801,8 @@ static void ivas_decode_arith_bs( for ( i = 0; i < nB; i++ ) { - ndm = hMdDec->spar_md_cfg.num_dmx_chans_per_band[bands_bw * i]; - ndec = hMdDec->spar_md_cfg.num_decorr_per_band[bands_bw * i]; + ndm = pState->spar_md_cfg.num_dmx_chans_per_band[bands_bw * i]; + ndec = pState->spar_md_cfg.num_decorr_per_band[bands_bw * i]; pred_cell_dims[i].dim1 = ndm + ndec - 1; pred_cell_dims[i].dim2 = 1; @@ -1782,17 +1825,17 @@ static void ivas_decode_arith_bs( if ( any_diff == 1 ) { - ivas_copy_band_coeffs_idx_to_arr( hMdDec->spar_md_prev.band_coeffs_idx_mapped, nB, symbol_arr_old_re, pred_cell_dims, PRED_COEFF, planarCP ); + ivas_copy_band_coeffs_idx_to_arr( pState->spar_md_prev.band_coeffs_idx_mapped, nB, symbol_arr_old_re, pred_cell_dims, PRED_COEFF, planarCP ); } - ivas_arith_decode_cmplx_cell_array( &hMdDec->arith_coeffs.pred_arith_re[qsi], &hMdDec->arith_coeffs.pred_arith_re_diff[qsi], + ivas_arith_decode_cmplx_cell_array( &pState->arith_coeffs.pred_arith_re[qsi], &pState->arith_coeffs.pred_arith_re_diff[qsi], st0, pred_cell_dims, pDo_diff, nB, symbol_arr_re, symbol_arr_old_re ); - ivas_fill_band_coeffs_idx( hMdDec->spar_md.band_coeffs_idx, nB, symbol_arr_re, pred_cell_dims, PRED_COEFF, planarCP ); + ivas_fill_band_coeffs_idx( pState->spar_md.band_coeffs_idx, nB, symbol_arr_re, pred_cell_dims, PRED_COEFF, planarCP ); if ( any_diff == 1 ) { - ivas_copy_band_coeffs_idx_to_arr( hMdDec->spar_md_prev.band_coeffs_idx_mapped, nB, symbol_arr_old_re, drct_cell_dims, DRCT_COEFF, planarCP ); + ivas_copy_band_coeffs_idx_to_arr( pState->spar_md_prev.band_coeffs_idx_mapped, nB, symbol_arr_old_re, drct_cell_dims, DRCT_COEFF, planarCP ); } if ( planarCP ) @@ -1803,14 +1846,14 @@ static void ivas_decode_arith_bs( } } - ivas_arith_decode_cmplx_cell_array( &hMdDec->arith_coeffs.drct_arith_re[qsi], &hMdDec->arith_coeffs.drct_arith_re_diff[qsi], + ivas_arith_decode_cmplx_cell_array( &pState->arith_coeffs.drct_arith_re[qsi], &pState->arith_coeffs.drct_arith_re_diff[qsi], st0, drct_cell_dims, pDo_diff, nB, symbol_arr_re, symbol_arr_old_re ); - ivas_fill_band_coeffs_idx( hMdDec->spar_md.band_coeffs_idx, nB, symbol_arr_re, drct_cell_dims, DRCT_COEFF, planarCP ); + ivas_fill_band_coeffs_idx( pState->spar_md.band_coeffs_idx, nB, symbol_arr_re, drct_cell_dims, DRCT_COEFF, planarCP ); if ( any_diff == 1 ) { - ivas_copy_band_coeffs_idx_to_arr( hMdDec->spar_md_prev.band_coeffs_idx_mapped, nB, symbol_arr_old_re, decd_cell_dims, DECD_COEFF, planarCP ); + ivas_copy_band_coeffs_idx_to_arr( pState->spar_md_prev.band_coeffs_idx_mapped, nB, symbol_arr_old_re, decd_cell_dims, DECD_COEFF, planarCP ); } if ( planarCP ) @@ -1821,27 +1864,27 @@ static void ivas_decode_arith_bs( } } - ivas_arith_decode_cmplx_cell_array( &hMdDec->arith_coeffs.decd_arith_re[qsi], &hMdDec->arith_coeffs.decd_arith_re_diff[qsi], + ivas_arith_decode_cmplx_cell_array( &pState->arith_coeffs.decd_arith_re[qsi], &pState->arith_coeffs.decd_arith_re_diff[qsi], st0, decd_cell_dims, pDo_diff, nB, symbol_arr_re, symbol_arr_old_re ); - ivas_fill_band_coeffs_idx( hMdDec->spar_md.band_coeffs_idx, nB, symbol_arr_re, decd_cell_dims, DECD_COEFF, planarCP ); + ivas_fill_band_coeffs_idx( pState->spar_md.band_coeffs_idx, nB, symbol_arr_re, decd_cell_dims, DECD_COEFF, planarCP ); if ( any_diff == 1 ) { - ivas_copy_band_coeffs_idx_to_arr( hMdDec->spar_md_prev.band_coeffs_idx_mapped, nB, symbol_arr_old_re, decx_cell_dims, DECX_COEFF, planarCP ); + ivas_copy_band_coeffs_idx_to_arr( pState->spar_md_prev.band_coeffs_idx_mapped, nB, symbol_arr_old_re, decx_cell_dims, DECX_COEFF, planarCP ); } - ivas_fill_band_coeffs_idx( hMdDec->spar_md.band_coeffs_idx, nB, symbol_arr_re, decx_cell_dims, DECX_COEFF, planarCP ); + ivas_fill_band_coeffs_idx( pState->spar_md.band_coeffs_idx, nB, symbol_arr_re, decx_cell_dims, DECX_COEFF, planarCP ); if ( freq_diff == 1 ) { #ifdef SPAR_HOA_DBG /* NOTE: This is currently unused code, and SPAR_HOA changes have not been made here. */ #endif - ivas_get_band_idx_from_differential( &hMdDec->spar_md, hMdDec->spar_md_cfg.quant_strat->PR.q_levels, 0, nB, PRED_COEFF ); - ivas_get_band_idx_from_differential( &hMdDec->spar_md, hMdDec->spar_md_cfg.quant_strat->C.q_levels, 0, nB, DRCT_COEFF ); - ivas_get_band_idx_from_differential( &hMdDec->spar_md, hMdDec->spar_md_cfg.quant_strat->P_r.q_levels, 1, nB, DECD_COEFF ); - ivas_get_band_idx_from_differential( &hMdDec->spar_md, hMdDec->spar_md_cfg.quant_strat->P_c.q_levels, 0, nB, DECX_COEFF ); + ivas_get_band_idx_from_differential( &pState->spar_md, pState->spar_md_cfg.quant_strat->PR.q_levels, 0, nB, PRED_COEFF ); + ivas_get_band_idx_from_differential( &pState->spar_md, pState->spar_md_cfg.quant_strat->C.q_levels, 0, nB, DRCT_COEFF ); + ivas_get_band_idx_from_differential( &pState->spar_md, pState->spar_md_cfg.quant_strat->P_r.q_levels, 1, nB, DECD_COEFF ); + ivas_get_band_idx_from_differential( &pState->spar_md, pState->spar_md_cfg.quant_strat->P_c.q_levels, 0, nB, DECX_COEFF ); } return; @@ -1853,7 +1896,6 @@ static void ivas_decode_arith_bs( * * *-----------------------------------------------------------------------------------------*/ - #ifdef SPAR_HOA_DBG /* NOTE: No changes here as frequency differential coding is unused. */ #endif @@ -2013,11 +2055,11 @@ static void ivas_fill_band_coeffs_idx( /*-----------------------------------------------------------------------------------------* * Function ivas_decode_huffman_bs() * - * Decode bitstream with huffman decoder + * decode bitstream with huffman decoder *-----------------------------------------------------------------------------------------*/ static void ivas_decode_huffman_bs( - ivas_spar_md_dec_state_t *hMdDec, + ivas_spar_md_dec_state_t *pState, Decoder_State *st0, /* i/o: decoder state structure - for bitstream handling*/ const uint16_t qsi, const int16_t nB, @@ -2031,8 +2073,8 @@ static void ivas_decode_huffman_bs( int16_t ndm, ndec; int16_t pred_dim, drct_dim, decd_dim; - ndm = hMdDec->spar_md_cfg.num_dmx_chans_per_band[bands_bw * i]; - ndec = hMdDec->spar_md_cfg.num_decorr_per_band[bands_bw * i]; + ndm = pState->spar_md_cfg.num_dmx_chans_per_band[bands_bw * i]; + ndec = pState->spar_md_cfg.num_decorr_per_band[bands_bw * i]; pred_dim = ndec + ndm - 1; drct_dim = ndec * ( ndm - 1 ); @@ -2040,20 +2082,20 @@ static void ivas_decode_huffman_bs( for ( j = 0; j < pred_dim; j++ ) { - ivas_huffman_decode( &hMdDec->huff_coeffs.pred_huff_re[qsi], st0, - &hMdDec->spar_md.band_coeffs_idx[i].pred_index_re[j] ); + ivas_huffman_decode( &pState->huff_coeffs.pred_huff_re[qsi], st0, + &pState->spar_md.band_coeffs_idx[i].pred_index_re[j] ); } for ( j = 0; j < drct_dim; j++ ) { if ( planarCP && !keep_planar[(int16_t) floor( j / ( ndm - 1 ) )] ) { - hMdDec->spar_md.band_coeffs_idx[i].drct_index_re[j] = 0; + pState->spar_md.band_coeffs_idx[i].drct_index_re[j] = 0; } else { - ivas_huffman_decode( &hMdDec->huff_coeffs.drct_huff_re[qsi], st0, - &hMdDec->spar_md.band_coeffs_idx[i].drct_index_re[j] ); + ivas_huffman_decode( &pState->huff_coeffs.drct_huff_re[qsi], st0, + &pState->spar_md.band_coeffs_idx[i].drct_index_re[j] ); } } @@ -2061,12 +2103,12 @@ static void ivas_decode_huffman_bs( { if ( planarCP && !keep_planar[j] ) { - hMdDec->spar_md.band_coeffs_idx[i].decd_index_re[j] = 0; + pState->spar_md.band_coeffs_idx[i].decd_index_re[j] = 0; } else { - ivas_huffman_decode( &hMdDec->huff_coeffs.decd_huff_re[qsi], st0, - &hMdDec->spar_md.band_coeffs_idx[i].decd_index_re[j] ); + ivas_huffman_decode( &pState->huff_coeffs.decd_huff_re[qsi], st0, + &pState->spar_md.band_coeffs_idx[i].decd_index_re[j] ); } } } @@ -2078,14 +2120,14 @@ static void ivas_decode_huffman_bs( /*-----------------------------------------------------------------------------------------* * Function ivas_spar_md_fill_invalid_bands() * - * Fill invalid bands in interpolation/extrapolation of valid bands + * fill invalid bands in interpolation/extrapolation of valid bands * when PLC is to be done with partial time differential coding *-----------------------------------------------------------------------------------------*/ 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 *valid_bands, int16_t *base_band_age, const int16_t num_bands, const int16_t sba_order /* i : SBA order */ @@ -2200,43 +2242,44 @@ static void ivas_spar_md_fill_invalid_bands( /*-----------------------------------------------------------------------------------------* - * Function ivas_spar_dec_compute_ramp_down_post_matrix() - * - * - *-----------------------------------------------------------------------------------------*/ +* Function ivas_spar_dec_compute_ramp_down_post_matrix() +* +* ivas_spar_dec_compute_ramp_down_post_matrix + +*-----------------------------------------------------------------------------------------*/ static void ivas_spar_dec_compute_ramp_down_post_matrix( - ivas_spar_md_dec_state_t *hMdDec, + ivas_spar_md_dec_state_t *pState, const int16_t num_bands_out, const int16_t bfi ) { int16_t num_in_ch, num_out_ch, i, j, b; - num_in_ch = hMdDec->spar_md_cfg.num_umx_chs; - num_out_ch = hMdDec->spar_md_cfg.num_umx_chs; + num_in_ch = pState->spar_md_cfg.num_umx_chs; + num_out_ch = pState->spar_md_cfg.num_umx_chs; if ( bfi == 0 ) { - hMdDec->spar_plc_num_lost_frames = 0; + pState->spar_plc_num_lost_frames = 0; } else { - if ( hMdDec->td_decorr_flag == 0 ) + if ( pState->td_decorr_flag == 0 ) { assert( 0 ); } - hMdDec->spar_plc_num_lost_frames += 1; - hMdDec->spar_plc_num_lost_frames = min( hMdDec->spar_plc_num_lost_frames, 100 ); + pState->spar_plc_num_lost_frames += 1; + pState->spar_plc_num_lost_frames = min( pState->spar_plc_num_lost_frames, 100 ); - if ( hMdDec->spar_plc_num_lost_frames > ivas_spar_dec_plc_num_frames_keep ) + if ( pState->spar_plc_num_lost_frames > ivas_spar_dec_plc_num_frames_keep ) { int16_t num_fade_frames; int16_t gain_dB; float gain; float post_matrix[IVAS_SPAR_MAX_CH]; - num_fade_frames = max( hMdDec->spar_plc_num_lost_frames - ivas_spar_dec_plc_num_frames_keep, 0 ); + num_fade_frames = max( pState->spar_plc_num_lost_frames - ivas_spar_dec_plc_num_frames_keep, 0 ); gain_dB = -min( num_fade_frames, ivas_spar_dec_plc_max_num_frames_ramp_down ) * ivas_spar_dec_plc_per_frame_ramp_down_gain_dB; gain = powf( 10, ( ( (float) gain_dB ) / 20 ) ); @@ -2255,7 +2298,7 @@ static void ivas_spar_dec_compute_ramp_down_post_matrix( { for ( b = 0; b < num_bands_out; b++ ) { - hMdDec->mixer_mat[i][j][b + i_ts * IVAS_MAX_NUM_BANDS] *= post_matrix[i]; + pState->mixer_mat[i][j][b + i_ts * IVAS_MAX_NUM_BANDS] *= post_matrix[i]; } } } @@ -2270,7 +2313,7 @@ static void ivas_spar_dec_compute_ramp_down_post_matrix( /*-----------------------------------------------------------------------------------------* * Function ivas_spar_unquant_dtx_indicies() * - * Unquantize SPAR MD DYX indices + * Unquantize spar md DYX indices *-----------------------------------------------------------------------------------------*/ #ifdef SPAR_HOA_DBG @@ -2284,28 +2327,35 @@ static void ivas_spar_unquant_dtx_indicies( { int16_t i, b; int16_t q_lvl; - float val; - int16_t idx; + float **ppVal, *pVal, val; + int16_t **ppIdx, *pIdx, idx; float pr_min_max[2]; pr_min_max[0] = pSpar_md->min_max[0]; pr_min_max[1] = pSpar_md->min_max[1]; + + ppVal = (float **) &pVal; + ppIdx = (int16_t **) &pIdx; + + ppVal[0] = (float *) &val; + ppIdx[0] = (int16_t *) &idx; + for ( b = 0; b < nB; b++ ) { for ( i = 0; i < FOA_CHANNELS - 1; i++ ) { q_lvl = dtx_pr_real_q_levels[ndm_per_band[bw * b] - 1][i]; - idx = pSpar_md->band_coeffs_idx[b].pred_index_re[i]; - ivas_deindex_real_index( &idx, q_lvl, pr_min_max[0], pr_min_max[1], &val, 1 ); - pSpar_md->band_coeffs[b].pred_re[i] = val; + ppIdx[0][0] = pSpar_md->band_coeffs_idx[b].pred_index_re[i]; + ivas_deindex_real_index( ppIdx, q_lvl, pr_min_max[0], pr_min_max[1], ppVal, 1, 1 ); + pSpar_md->band_coeffs[b].pred_re[i] = ppVal[0][0]; } for ( i = 0; i < FOA_CHANNELS - ndm_per_band[bw * b]; i++ ) { q_lvl = dtx_pd_real_q_levels[ndm_per_band[bw * b] - 1][i]; - idx = pSpar_md->band_coeffs_idx[b].decd_index_re[i]; - ivas_deindex_real_index( &idx, q_lvl, dtx_pd_real_min_max[0], dtx_pd_real_min_max[1], &val, 1 ); - pSpar_md->band_coeffs[b].P_re[i] = val; + ppIdx[0][0] = pSpar_md->band_coeffs_idx[b].decd_index_re[i]; + ivas_deindex_real_index( ppIdx, q_lvl, dtx_pd_real_min_max[0], dtx_pd_real_min_max[1], ppVal, 1, 1 ); + pSpar_md->band_coeffs[b].P_re[i] = ppVal[0][0]; } } @@ -2328,13 +2378,19 @@ static void ivas_parse_parameter_bitstream_dtx( int16_t *num_dec_per_band ) { int16_t i, j; - float val; - int16_t idx; + float **ppVal, *pVal, val; + int16_t **ppIdx, *pIdx, idx; float pr_min_max[2]; int16_t pr_q_lvls, pr, pd, pd_q_lvls, pr_pd_bits; int16_t pr_q_lvls1, pr_q_lvls2, pr_idx1, pr_idx2, pr_pr_bits; int16_t zero_pad_bits, sid_bits_len; sid_bits_len = st0->next_bit_pos; + ppVal = (float **) &pVal; + ppIdx = (int16_t **) &pIdx; + + ppVal[0] = (float *) &val; + ppIdx[0] = (int16_t *) &idx; + pr_min_max[0] = pSpar_md->min_max[0]; pr_min_max[1] = pSpar_md->min_max[1]; @@ -2374,13 +2430,16 @@ static void ivas_parse_parameter_bitstream_dtx( pr = (int16_t) floor( value / pd_q_lvls ); pd = value - pr * pd_q_lvls; - val = dtx_pd_real_min_max[0]; - ivas_quantise_real_values( &val, pd_q_lvls, dtx_pd_real_min_max[0], dtx_pd_real_min_max[1], &idx, &val, 1 ); - pd = pd + idx; - val = pr_min_max[0]; - ivas_quantise_real_values( &val, pr_q_lvls, pr_min_max[0], pr_min_max[1], &idx, &val, 1 ); - pr = pr + idx; + ppVal[0][0] = dtx_pd_real_min_max[0]; + ivas_quantise_real_values( ppVal, pd_q_lvls, dtx_pd_real_min_max[0], dtx_pd_real_min_max[1], ppIdx, ppVal, 1, 1 ); + + pd = pd + ppIdx[0][0]; + + ppVal[0][0] = pr_min_max[0]; + ivas_quantise_real_values( ppVal, pr_q_lvls, pr_min_max[0], pr_min_max[1], ppIdx, ppVal, 1, 1 ); + + pr = pr + ppIdx[0][0]; if ( ( j + 1 ) <= ndec ) { @@ -2400,15 +2459,17 @@ static void ivas_parse_parameter_bitstream_dtx( pr_idx2 = (int16_t) floor( value / pr_q_lvls1 ); pr_idx1 = value - pr_idx2 * pr_q_lvls1; - val = pr_min_max[0]; - ivas_quantise_real_values( &val, pr_q_lvls1, pr_min_max[0], pr_min_max[1], &idx, &val, 1 ); - pr_idx1 += idx; + ppVal[0][0] = pr_min_max[0]; + ivas_quantise_real_values( ppVal, pr_q_lvls1, pr_min_max[0], pr_min_max[1], ppIdx, ppVal, 1, 1 ); + + pr_idx1 += ppIdx[0][0]; - val = pr_min_max[0]; - ivas_quantise_real_values( &val, pr_q_lvls2, pr_min_max[0], pr_min_max[1], &idx, &val, 1 ); + ppVal[0][0] = pr_min_max[0]; + ivas_quantise_real_values( ppVal, pr_q_lvls2, pr_min_max[0], pr_min_max[1], ppIdx, ppVal, 1, 1 ); + + pr_idx2 += ppIdx[0][0]; - pr_idx2 += idx; pSpar_md->band_coeffs_idx[i].pred_index_re[pr_idx_1 - 1] = pr_idx1; pSpar_md->band_coeffs_idx[i].pred_index_re[pr_idx_2 - 1] = pr_idx2; } @@ -2433,18 +2494,19 @@ static void ivas_parse_parameter_bitstream_dtx( /*-----------------------------------------------------------------------------------------* * Function ivas_deindex_real_index() * - * Deindex real index + * deindex real index *-----------------------------------------------------------------------------------------*/ static ivas_error ivas_deindex_real_index( - const int16_t *index, + int16_t **index, const int16_t q_levels, const float min_value, const float max_value, - float *quant, - const int16_t dim ) + float **quant, + const int16_t num_ch, + const int16_t dim2 ) { - int16_t i; + int16_t i, j; float q_step; if ( q_levels == 0 ) @@ -2454,17 +2516,24 @@ static ivas_error ivas_deindex_real_index( if ( q_levels == 1 ) { - for ( i = 0; i < dim; i++ ) + for ( i = 0; i < num_ch; i++ ) { - quant[i] = 0; + for ( j = 0; j < dim2; j++ ) + { + quant[i][j] = 0; + } } } else { q_step = ( max_value - min_value ) / ( q_levels - 1 ); - for ( i = 0; i < dim; i++ ) + + for ( i = 0; i < num_ch; i++ ) { - quant[i] = index[i] * q_step; + for ( j = 0; j < dim2; j++ ) + { + quant[i][j] = index[i][j] * q_step; + } } } @@ -2508,8 +2577,11 @@ void ivas_spar_to_dirac( int16_t pred_idx; int16_t *dirac_to_spar_md_bands; int16_t enc_param_start_band; - +#ifndef SBA_ORDER_BITSTREAM + sba_order_internal = min( st_ivas->sba_order, IVAS_MAX_SBA_ORDER ); +#else sba_order_internal = min( st_ivas->sba_analysis_order, IVAS_MAX_SBA_ORDER ); +#endif start_band = 0; end_band = min( num_bands_out, SPAR_DIRAC_SPLIT_START_BAND ); diff --git a/lib_dec/ivas_stat_dec.h b/lib_dec/ivas_stat_dec.h index 020f0df5eb..29ae9867ca 100644 --- a/lib_dec/ivas_stat_dec.h +++ b/lib_dec/ivas_stat_dec.h @@ -254,7 +254,7 @@ typedef struct stereo_dec_cng int16_t xfade_length; /* number of frames to perform xfade */ int16_t nr_dft_frames; /* dft frame counter */ int16_t nr_corr_frames; /* correlation frame counter */ - int16_t nr_sid_frames; /* SID frame counter */ + int16_t nr_sid_frames; /* sid frame counter */ int16_t last_act_element_mode; /* Element mode of last active frame */ float olapBufferSynth22[FFTLEN]; /* overlap buffer for secondary channel CNA */ int16_t flag_cna_fade; /* flag enabling CNA fade out */ @@ -321,7 +321,7 @@ typedef struct stereo_mdct_dec_data_structure int16_t prev_ms_mask[NB_DIV][MAX_SFB]; float lastCoh; -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT int16_t noise_seeds_channels[CPE_CHANNELS]; int16_t noise_seed_common; #endif @@ -1630,36 +1630,19 @@ typedef struct ivas_binaural_td_rendering_struct typedef struct ivas_hrtfs_structure { -#ifdef FIX_CREND_CHANNELS - float *pOut_to_bin_re[MAX_TRANSPORT_CHANNELS][BINAURAL_CHANNELS]; - float *pOut_to_bin_im[MAX_TRANSPORT_CHANNELS][BINAURAL_CHANNELS]; -#else float *pOut_to_bin_re[IVAS_MAX_NUM_CH][BINAURAL_CHANNELS]; float *pOut_to_bin_im[IVAS_MAX_NUM_CH][BINAURAL_CHANNELS]; -#endif float *pOut_to_bin_diffuse_re[BINAURAL_CHANNELS]; float *pOut_to_bin_diffuse_im[BINAURAL_CHANNELS]; float latency_s; -#ifdef FIX_CREND_CHANNELS - uint16_t num_iterations[MAX_TRANSPORT_CHANNELS][BINAURAL_CHANNELS]; -#else uint16_t num_iterations[IVAS_MAX_NUM_CH][BINAURAL_CHANNELS]; -#endif uint16_t num_iterations_diffuse[BINAURAL_CHANNELS]; -#ifdef FIX_CREND_CHANNELS - uint16_t *pIndex_frequency_max[MAX_TRANSPORT_CHANNELS][BINAURAL_CHANNELS]; -#else uint16_t *pIndex_frequency_max[IVAS_MAX_NUM_CH][BINAURAL_CHANNELS]; -#endif uint16_t *pIndex_frequency_max_diffuse[BINAURAL_CHANNELS]; uint16_t index_frequency_max_diffuse; int16_t max_num_ir; int16_t max_num_iterations; -#ifdef FIX_CREND_CHANNELS - float inv_diffuse_weight[MAX_TRANSPORT_CHANNELS]; /* inverse diffuse weights array, access one inverse weight by pInvDiffuseWeight[channel] */ -#else float inv_diffuse_weight[IVAS_MAX_NUM_CH]; /* inverse diffuse weights array, access one inverse weight by pInvDiffuseWeight[channel] */ -#endif float gain_lfe; } HRTFS_DATA, *HRTFS_HANDLE; @@ -1800,13 +1783,8 @@ typedef struct ivas_orient_trk_state_t /* Crend structures */ typedef struct ivas_crend_state_t { -#ifdef FIX_CREND_CHANNELS - float *freq_buffer_re[MAX_TRANSPORT_CHANNELS]; - float *freq_buffer_im[MAX_TRANSPORT_CHANNELS]; -#else float *freq_buffer_re[IVAS_MAX_NUM_CH]; float *freq_buffer_im[IVAS_MAX_NUM_CH]; -#endif float *freq_buffer_re_diffuse; float *freq_buffer_im_diffuse; float *prev_out_buffer[BINAURAL_CHANNELS]; @@ -1876,10 +1854,13 @@ typedef struct decoder_config_structure int32_t output_Fs; /* output signal sampling frequency in Hz */ int16_t nchan_out; /* number of output audio channels */ AUDIO_CONFIG output_config; /* output audio configuration */ - int16_t Opt_LsCustom; /* indicates whether loudspeaker custom setup is used */ - int16_t Opt_HRTF_binary; /* indicates whether HRTF binary file is used */ - int16_t Opt_Headrotation; /* indicates whether head-rotation is used */ - int16_t orientation_tracking; /* indicates orientation tracking type */ +#ifdef SBA_ORDER_BITSTREAM + int16_t sba_order; +#endif + int16_t Opt_LsCustom; /* indicates whether loudspeaker custom setup is used */ + int16_t Opt_HRTF_binary; /* indicates whether HRTF binary file is used */ + int16_t Opt_Headrotation; /* indicates whether head-rotation is used */ + int16_t orientation_tracking; /* indicates orientation tracking type */ float no_diegetic_pan; int16_t Opt_AMR_WB; /* flag indicating AMR-WB IO mode */ @@ -1948,10 +1929,12 @@ typedef struct Decoder_Struct ISM_MODE ism_mode; /* ISM format mode */ SBA_MODE sba_mode; /* SBA format mode */ MC_MODE mc_mode; /* MC format mode */ +#ifdef SBA_ORDER_BITSTREAM + int16_t sba_analysis_order; /* Ambisonic (SBA) order */ +#else int16_t sba_order; /* Ambisonic (SBA) order */ #endif int16_t sba_planar; /* Ambisonic (SBA) planar flag */ - int16_t sba_analysis_order; /* Ambisonic (SBA) order used for analysis and coding */ int16_t sba_dirac_stereo_flag; /* flag indicating stereo output for SBA DirAC modes with 1 TC */ /* rendering modules */ diff --git a/lib_dec/ivas_stereo_cng_dec.c b/lib_dec/ivas_stereo_cng_dec.c index 491a88da3f..05e9222ddb 100644 --- a/lib_dec/ivas_stereo_cng_dec.c +++ b/lib_dec/ivas_stereo_cng_dec.c @@ -90,12 +90,7 @@ void stereo_dft_dec_sid_coh( int16_t bits_tmp; int16_t b; -#ifdef ALIGN_SID_SIZE - /* TODO: still use old number of bits to keep bitexactness in output */ - nr_of_sid_stereo_bits = ( 4400 /*IVAS_SID_5k2*/ - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS; -#else nr_of_sid_stereo_bits = ( IVAS_SID_4k4 - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS; -#endif /* If the coherence is not encoded due to lack of bits set alpha to zero which leads to that the coherence */ /* from the previous frame is used. */ @@ -178,9 +173,6 @@ void stereo_dft_dec_sid_coh( ( *nb_bits )++; } -#ifdef ALIGN_SID_SIZE - dtx_read_padding_bits( st, ( IVAS_SID_5k2 - 4400 ) / FRAMES_PER_SEC ); -#endif return; } @@ -661,17 +653,9 @@ void stereo_dtf_cng( hCPE->hStereoCng->nr_dft_frames++; } -#ifdef ALIGN_SID_SIZE - if ( ivas_total_brate <= IVAS_SID_5k2 ) -#else if ( ivas_total_brate <= IVAS_SID_4k4 ) -#endif { -#ifdef ALIGN_SID_SIZE - if ( hCPE->hStereoCng->nr_sid_frames < SID_INIT && ivas_total_brate == IVAS_SID_5k2 ) -#else if ( hCPE->hStereoCng->nr_sid_frames < SID_INIT && ivas_total_brate == IVAS_SID_4k4 ) -#endif { hCPE->hStereoCng->nr_sid_frames++; } @@ -723,11 +707,7 @@ void stereo_cng_dec_update( if ( hCPE->element_mode == IVAS_CPE_DFT ) { -#ifdef ALIGN_SID_SIZE - if ( ivas_total_brate == IVAS_SID_5k2 || ivas_total_brate == FRAME_NO_DATA ) -#else if ( ivas_total_brate == IVAS_SID_4k4 || ivas_total_brate == FRAME_NO_DATA ) -#endif { hCPE->hStereoCng->prev_sid_nodata = 1; } diff --git a/lib_dec/ivas_stereo_dft_dec.c b/lib_dec/ivas_stereo_dft_dec.c index b0db814511..074efaa1a2 100644 --- a/lib_dec/ivas_stereo_dft_dec.c +++ b/lib_dec/ivas_stereo_dft_dec.c @@ -1746,11 +1746,7 @@ void stereo_dft_dec_read_BS( * Initialization *-----------------------------------------------------------------*/ -#ifdef ALIGN_SID_SIZE - if ( ivas_total_brate == IVAS_SID_5k2 ) -#else if ( ivas_total_brate == IVAS_SID_4k4 ) -#endif { if ( ivas_format == MASA_FORMAT ) { @@ -1764,11 +1760,7 @@ void stereo_dft_dec_read_BS( hStereoDft->frame_nodata = 0; hStereoDft->frame_sid_nodata = 1; hStereoDft->frame_sid = 1; -#ifdef ALIGN_SID_SIZE - *nb_bits = ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS; -#else *nb_bits = ( IVAS_SID_4k4 - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS; -#endif } } else if ( ivas_total_brate == FRAME_NO_DATA ) @@ -1811,11 +1803,7 @@ void stereo_dft_dec_read_BS( k_offset = STEREO_DFT_OFFSET; N_div = STEREO_DFT_NBDIV; -#ifdef ALIGN_SID_SIZE - if ( ivas_total_brate > IVAS_SID_5k2 ) -#else if ( ivas_total_brate > IVAS_SID_4k4 ) -#endif { mvr2r( hStereoDft->side_gain + 2 * STEREO_DFT_BAND_MAX, sg_tmp, STEREO_DFT_BAND_MAX ); mvr2r( hStereoDft->res_pred_gain + 2 * STEREO_DFT_BAND_MAX, res_pred_gain_tmp, STEREO_DFT_BAND_MAX ); @@ -1905,11 +1893,7 @@ void stereo_dft_dec_read_BS( fprintf( pF, "ITD: %d ", hStereoDft->hConfig->itd_mode ); #endif -#ifdef ALIGN_SID_SIZE - if ( !( ivas_format == MASA_FORMAT && ivas_total_brate <= IVAS_SID_5k2 ) ) -#else if ( !( ivas_format == MASA_FORMAT && ivas_total_brate <= IVAS_SID_4k4 ) ) -#endif { /*------------------------------------------------------------------* * read Side gains @@ -1990,11 +1974,7 @@ void stereo_dft_dec_read_BS( #endif } } -#ifdef ALIGN_SID_SIZE - 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 ) ) -#else else if ( *nb_bits <= ( ( IVAS_SID_4k4 - SID_2k40 ) / FRAMES_PER_SEC - STEREO_DFT_ITD_MODE_NBITS - STEREO_DFT_SID_ITD_NBITS - 1 - SID_FORMAT_NBITS ) ) -#endif { itd_mode = get_next_indice( st, STEREO_DFT_ITD_MODE_NBITS ); ( *nb_bits ) += STEREO_DFT_ITD_MODE_NBITS; /*ITD mode flag: 1bit*/ @@ -2036,11 +2016,7 @@ void stereo_dft_dec_read_BS( stereo_dft_dequantize_ipd( &ind1_ipd[0], hStereoDft->gipd + ( k + k_offset ), 1, STEREO_DFT_GIPD_NBITS ); } } -#ifdef ALIGN_SID_SIZE - else if ( *nb_bits <= ( ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC - STEREO_DFT_FLAG_BITS - STEREO_DFT_SID_GIPD_NBITS - SID_FORMAT_NBITS ) ) -#else else if ( *nb_bits <= ( ( IVAS_SID_4k4 - SID_2k40 ) / FRAMES_PER_SEC - STEREO_DFT_FLAG_BITS - STEREO_DFT_SID_GIPD_NBITS - SID_FORMAT_NBITS ) ) -#endif { /* SID frame, only read IPD only if enough bits left in bitstream */ hStereoDft->no_ipd_flag = st->bit_stream[nb]; @@ -2201,11 +2177,7 @@ void stereo_dft_dec_read_BS( #endif } -#ifdef ALIGN_SID_SIZE - if ( !( ivas_format == MASA_FORMAT && ivas_total_brate <= IVAS_SID_5k2 ) ) -#else if ( !( ivas_format == MASA_FORMAT && ivas_total_brate <= IVAS_SID_4k4 ) ) -#endif { if ( hStereoDft->side_gain_flag_1 != 2 ) { @@ -2213,11 +2185,7 @@ void stereo_dft_dec_read_BS( } } -#ifdef ALIGN_SID_SIZE - if ( ivas_total_brate > IVAS_SID_5k2 ) -#else if ( ivas_total_brate > IVAS_SID_4k4 ) -#endif { hStereoDft->recovery_flg = stereo_dft_sg_recovery( hStereoDft ); @@ -2284,20 +2252,12 @@ void stereo_dft_dec_read_BS( #endif } -#ifdef ALIGN_SID_SIZE - if ( hStereoDft->frame_sid && !( ivas_format == MASA_FORMAT && ivas_total_brate <= IVAS_SID_5k2 ) ) -#else if ( hStereoDft->frame_sid && !( ivas_format == MASA_FORMAT && ivas_total_brate <= IVAS_SID_4k4 ) ) -#endif { stereo_dft_dec_sid_coh( st, hStereoDft->nbands, coh, nb_bits ); } -#ifdef ALIGN_SID_SIZE - if ( ivas_total_brate == IVAS_SID_5k2 && ivas_format != MASA_FORMAT ) -#else if ( ivas_total_brate == IVAS_SID_4k4 && ivas_format != MASA_FORMAT ) -#endif { *nb_bits = (int16_t) ( ( element_brate - SID_2k40 ) / FRAMES_PER_SEC ); /* => hCPE->hCoreCoder[0]->total_brate = SID_2k40; */ } diff --git a/lib_dec/ivas_stereo_mdct_core_dec.c b/lib_dec/ivas_stereo_mdct_core_dec.c index 5e850204a5..3d4c38f272 100644 --- a/lib_dec/ivas_stereo_mdct_core_dec.c +++ b/lib_dec/ivas_stereo_mdct_core_dec.c @@ -50,7 +50,7 @@ *-------------------------------------------------------------------------*/ static void apply_dmx_weights( CPE_DEC_HANDLE hCPE, float *x[CPE_CHANNELS][NB_DIV], int16_t transform_type_left[NB_DIV], int16_t transform_type_right[NB_DIV] ); -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT static void run_min_stats( Decoder_State **sts, float *x[CPE_CHANNELS][NB_DIV] ); #endif @@ -218,7 +218,6 @@ void stereo_mdct_core_dec( initMdctStereoDecData( hCPE->hStereoMdct, sts[0]->igf, sts[0]->hIGFDec->igfData.igfInfo.grid, hCPE->element_brate, sts[0]->bwidth ); hCPE->hStereoMdct->isSBAStereoMode = ( ( st_ivas->ivas_format == SBA_FORMAT ) && ( st_ivas->nchan_transport == 2 ) ); -#ifndef FIX_135_MDCT_STEREO_MODE_UNINITIALIZED /*to prevent unitialized values during condition checks for stereo IGF*/ if ( hCPE->hStereoMdct->isSBAStereoMode ) { @@ -300,11 +299,7 @@ void stereo_mdct_core_dec( assert( ( sts[0]->core == sts[1]->core ) || ( hCPE->hStereoMdct->mdct_stereo_mode[0] == SMDCT_DUAL_MONO ) ); /* stereo IGF decoding */ -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE - decoder_tcx_IGF_stereo( sts, hCPE->hStereoMdct, ms_mask, x, L_frame[0], left_rect[0], k, bfi, 0 /* <- is_mct */ ); -#else decoder_tcx_IGF_stereo( sts, hCPE->hStereoMdct, ms_mask, x, L_frame[0], left_rect[0], k, bfi ); -#endif } else { @@ -334,14 +329,34 @@ void stereo_mdct_core_dec( sns_interpolate_scalefactors( &sns_int_scf[0], &Aq[ch][k * M], DEC ); -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT if ( st->hTonalMDCTConc != NULL && ( ( k + 1 ) == nSubframes[ch] ) ) #else if ( st->hTonalMDCTConc != NULL ) #endif { -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE - TonalMDCTConceal_SaveFreqSignal( st->hTonalMDCTConc, x[ch][k], L_frameTCX[ch], L_frame[ch], &sns_int_scf[0], get_igf_startline( st, L_frame[ch], L_frameTCX[ch] ) ); +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT + int16_t infoIGFStartLine; + + if ( st->igf == 0 ) + { + if ( st->narrowBand == 0 ) + { + /* minimum needed for output with sampling rates lower then the + nominal sampling rate */ + infoIGFStartLine = min( L_frameTCX[ch], L_frame[ch] ); + } + else + { + infoIGFStartLine = L_frameTCX[ch]; + } + } + else + { + infoIGFStartLine = min( st->hIGFDec->infoIGFStartLine, L_frameTCX[ch] ); + } + + TonalMDCTConceal_SaveFreqSignal( st->hTonalMDCTConc, x[ch][k], L_frameTCX[ch], L_frame[ch], &sns_int_scf[0], infoIGFStartLine ); #else TonalMDCTConceal_SaveFreqSignal( st->hTonalMDCTConc, x[ch][k], L_frameTCX[ch], L_frame[ch], &sns_int_scf[0] ); #endif @@ -366,12 +381,13 @@ void stereo_mdct_core_dec( ivas_mdct_core_tns_ns( hCPE, 0, fUseTns, tnsData, x, Aq, 0 ); - if ( st_ivas->renderer_type == RENDERER_MC_PARAMMC && ( st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_MONO || st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_STEREO ) ) + if ( + st_ivas->renderer_type == RENDERER_MC_PARAMMC && ( st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_MONO || st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_STEREO ) ) { ivas_ls_setup_conversion_process_mdct_param_mc( st_ivas, x ); } -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT run_min_stats( sts, x ); #endif @@ -592,7 +608,7 @@ static void apply_dmx_weights( return; } -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT /*-------------------------------------------------------------------* * run_min_stats() * diff --git a/lib_dec/ivas_stereo_mdct_stereo_dec.c b/lib_dec/ivas_stereo_mdct_stereo_dec.c index 10b9688be2..f797eaf289 100644 --- a/lib_dec/ivas_stereo_mdct_stereo_dec.c +++ b/lib_dec/ivas_stereo_mdct_stereo_dec.c @@ -57,7 +57,7 @@ void parse_stereo_from_bitstream( STEREO_MDCT_DEC_DATA_HANDLE hStereoMdct, /* i/o: MDCT stereo decoder structure */ Decoder_State **sts, /* i/o: decoder state structure */ const int16_t mct_on, /* i : flag mct block (1) or stereo (0)*/ - const int16_t isSBAStereoMode, /* i : flag core coding for SBA */ + const int16_t isSBAStereoMode, /* i : flag core coding for sba */ Decoder_State *st0, /* i/o: decoder state structure for Bstr*/ int16_t ms_mask[NB_DIV][MAX_SFB] /* o : bandwise MS mask */ ) @@ -559,21 +559,13 @@ void updateBuffersForDmxMdctStereo( sts[1] = hCPE->hCoreCoder[1]; /* synch buffers for inactive frames, but not for transition frames */ -#ifdef ALIGN_SID_SIZE - if ( hCPE->last_element_brate <= IVAS_SID_5k2 ) -#else if ( hCPE->last_element_brate <= IVAS_SID_4k4 ) -#endif { mvr2r( output[0], output[1], output_frame ); mvr2r( synth[0], synth[1], output_frame ); } -#ifdef ALIGN_SID_SIZE - if ( hCPE->element_brate == IVAS_SID_5k2 && hCPE->last_element_brate > IVAS_SID_5k2 ) -#else if ( hCPE->element_brate == IVAS_SID_4k4 && hCPE->last_element_brate > IVAS_SID_4k4 ) -#endif { /* in the first SID frame after an active frame, create mid noise shape here, in SID frames that follow inactive frames, it is done directly in the SID decoding since the mid shape is being used in CNG then */ for ( int16_t p = 0; p < sts[0]->hFdCngDec->hFdCngCom->npart; p++ ) @@ -583,11 +575,7 @@ void updateBuffersForDmxMdctStereo( } /* for transition of active->inactive frame, apply passive downmix on buffers */ -#ifdef ALIGN_SID_SIZE - if ( hCPE->last_element_brate <= IVAS_SID_5k2 ) -#else if ( hCPE->last_element_brate <= IVAS_SID_4k4 ) -#endif { delta = 1; if ( output_frame == L_FRAME16k ) @@ -653,21 +641,13 @@ void applyDmxMdctStereo( fade = 1.f; dmx_len = output_frame; -#ifdef ALIGN_SID_SIZE - if ( hCPE->last_element_brate <= IVAS_SID_5k2 ) -#else if ( hCPE->last_element_brate <= IVAS_SID_4k4 ) -#endif { crossfade_len = NS2SA( hCPE->hCoreCoder[0]->output_Fs, IVAS_DEC_DELAY_NS - DELAY_CLDFB_NS ); step /= crossfade_len; } /* for first inactive CNG frame after active decoding we have to do a fade-OUT FROM the passive DMX */ -#ifdef ALIGN_SID_SIZE - else if ( hCPE->element_brate <= IVAS_SID_5k2 && hCPE->last_element_brate > IVAS_SID_5k2 ) -#else else if ( hCPE->element_brate <= IVAS_SID_4k4 && hCPE->last_element_brate > IVAS_SID_4k4 ) -#endif { crossfade_len = output_frame / 4; step /= -crossfade_len; diff --git a/lib_dec/ivas_stereo_switching_dec.c b/lib_dec/ivas_stereo_switching_dec.c old mode 100644 new mode 100755 index 2e32b8e85a..b2b7889569 --- a/lib_dec/ivas_stereo_switching_dec.c +++ b/lib_dec/ivas_stereo_switching_dec.c @@ -424,7 +424,7 @@ ivas_error stereo_memory_dec( if ( hCPE->last_element_mode == IVAS_CPE_MDCT ) { cpy_tcx_ltp_data( hCPE->hCoreCoder[1]->hTcxLtpDec, hCPE->hStereoDft->hTcxLtpDec, output_Fs ); -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT deleteFdCngDec( &hCPE->hCoreCoder[1]->hFdCngDec ); #endif } @@ -489,7 +489,7 @@ ivas_error stereo_memory_dec( /* deallocated TCX/IGF structures for second channel */ deallocate_CoreCoder_TCX( hCPE->hCoreCoder[1] ); -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT if ( hCPE->last_element_mode == IVAS_CPE_MDCT ) { deleteFdCngDec( &hCPE->hCoreCoder[1]->hFdCngDec ); @@ -675,7 +675,7 @@ ivas_error stereo_memory_dec( /* deallocate core-decoder substructures */ deallocate_CoreCoder( st ); -#ifndef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifndef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT /* deallocate FD_CNG substructure */ deleteFdCngDec( &st->hFdCngDec ); #endif @@ -702,7 +702,7 @@ ivas_error stereo_memory_dec( } } -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT /* allocate Fd-Cng structure for second channel */ if ( ( error = createFdCngDec( &st->hFdCngDec ) ) != IVAS_ERR_OK ) { @@ -832,11 +832,7 @@ ivas_error stereo_memory_dec( if ( ivas_format == STEREO_FORMAT && hCPE->element_mode == IVAS_CPE_MDCT ) { -#ifdef ALIGN_SID_SIZE - if ( hCPE->element_brate <= MAX_MDCT_ITD_BRATE && ivas_total_brate > IVAS_SID_5k2 ) -#else if ( hCPE->element_brate <= MAX_MDCT_ITD_BRATE && ivas_total_brate > IVAS_SID_4k4 ) -#endif { if ( hCPE->hStereoMdct->use_itd == 0 ) { @@ -856,21 +852,13 @@ ivas_error stereo_memory_dec( else { /* de-allocate TCA data structure */ -#ifdef ALIGN_SID_SIZE - if ( hCPE->hStereoMdct->use_itd == 1 && ivas_total_brate > IVAS_SID_5k2 && hCPE->hStereoTCA != NULL ) -#else if ( hCPE->hStereoMdct->use_itd == 1 && ivas_total_brate > IVAS_SID_4k4 && hCPE->hStereoTCA != NULL ) -#endif { count_free( hCPE->hStereoTCA ); hCPE->hStereoTCA = NULL; hCPE->hStereoMdct->use_itd = 0; } -#ifdef ALIGN_SID_SIZE - else if ( hCPE->hStereoMdct->use_itd == 1 && ivas_total_brate <= IVAS_SID_5k2 ) -#else else if ( hCPE->hStereoMdct->use_itd == 1 && ivas_total_brate <= IVAS_SID_4k4 ) -#endif { hCPE->hStereoMdct->itd = 0.0f; } @@ -1023,11 +1011,7 @@ void synchro_synthesis( if ( use_cldfb_for_last_dft ) { -#ifdef ALIGN_SID_SIZE - if ( hCPE->element_mode == IVAS_CPE_DFT && hCPE->last_element_mode == IVAS_CPE_TD && ( ivas_total_brate > IVAS_SID_5k2 || hCPE->nchan_out == 2 ) ) -#else if ( hCPE->element_mode == IVAS_CPE_DFT && hCPE->last_element_mode == IVAS_CPE_TD && ( ivas_total_brate > IVAS_SID_4k4 || hCPE->nchan_out == 2 ) ) -#endif { stereo_tca_scale_R_channel( hCPE, output[0], output_frame ); } @@ -1365,11 +1349,7 @@ void stereo_switching_dec( mvr2r( hCPE->input_mem[n], hCPE->output_mem[n], dft32ms_ovl ); } -#ifdef ALIGN_SID_SIZE - if ( ivas_total_brate > IVAS_SID_5k2 || n == 0 || hCPE->last_element_mode != IVAS_CPE_TD || hCPE->nchan_out == 1 ) -#else if ( ivas_total_brate > IVAS_SID_4k4 || n == 0 || hCPE->last_element_mode != IVAS_CPE_TD || hCPE->nchan_out == 1 ) -#endif { for ( i = 0; i < dft32ms_ovl; i++ ) { @@ -1443,11 +1423,7 @@ void stereo_switching_dec( /* no secondary channel in the previous frame -> memory resets */ if ( hCPE->element_mode > IVAS_CPE_DFT && hCPE->last_element_mode == IVAS_CPE_DFT ) { -#ifdef ALIGN_SID_SIZE - if ( hCPE->last_element_brate <= IVAS_SID_5k2 && hCPE->nchan_out == 2 ) -#else if ( hCPE->last_element_brate <= IVAS_SID_4k4 && hCPE->nchan_out == 2 ) -#endif { /* reset CLDFB memories */ cldfb_reset_memory( sts[0]->cldfbAna ); diff --git a/lib_dec/ivas_tcx_core_dec.c b/lib_dec/ivas_tcx_core_dec.c index e46c32ddbb..e3462f21bc 100644 --- a/lib_dec/ivas_tcx_core_dec.c +++ b/lib_dec/ivas_tcx_core_dec.c @@ -150,7 +150,7 @@ void stereo_tcx_init_dec( } /* Reconfigure Core */ -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT mode_switch_decoder_LPD( st, st->bwidth, st->bits_frame_nominal * FRAMES_PER_SEC, st->last_bits_frame_nominal * FRAMES_PER_SEC, frame_size_index, is_mct, last_element_mode ); #else mode_switch_decoder_LPD( st, st->bwidth, st->bits_frame_nominal * FRAMES_PER_SEC, st->last_bits_frame_nominal * FRAMES_PER_SEC, frame_size_index, is_mct ); @@ -457,7 +457,7 @@ void stereo_tcx_core_dec( } /* PLC: [TCX: TD PLC] */ -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT con_tcx( st, &synthFB[0], -1.f, NULL, 0, NULL ); #else con_tcx( st, &synthFB[0], -1.f, NULL, 0 ); @@ -589,7 +589,7 @@ void stereo_tcx_core_dec( TonalMDCTConceal_SaveTimeSignal( st->hTonalMDCTConc, synthFB, hTcxDec->L_frameTCX ); } -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT decoder_tcx_post( st, synth, synthFB, Aq, bfi, 0 ); #else decoder_tcx_post( st, synth, synthFB, Aq, bfi ); @@ -750,7 +750,7 @@ void stereo_tcx_core_dec( if ( st->element_mode != IVAS_CPE_TD ) { -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT ApplyFdCng( signal_out, NULL, NULL, NULL, st, st->bfi, 0 ); #else ApplyFdCng( signal_out, NULL, NULL, st, st->bfi, 0 ); @@ -779,7 +779,7 @@ void stereo_tcx_core_dec( if ( st->element_mode == IVAS_CPE_TD && st->idchan == 0 ) { -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT ApplyFdCng( signal_out, NULL, NULL, NULL, st, st->bfi, 0 ); #else ApplyFdCng( signal_out, NULL, NULL, st, st->bfi, 0 ); @@ -867,7 +867,7 @@ static void dec_prm_tcx( *--------------------------------------------------------------------------------*/ /* Modes (ACE_GC, ACE_UC, TCX20, TCX10...) */ -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT getTCXMode( st, st, 0 /* <- MCT_flag */ ); #else getTCXMode( st, st ); diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c old mode 100644 new mode 100755 index fa2bb2b763..c12a356146 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -110,17 +110,12 @@ ivas_error IVAS_DEC_Open( float no_diegetic_pan ) { IVAS_DEC_HANDLE hIvasDec; - Decoder_Struct *st_ivas; if ( phIvasDec == NULL ) { return IVAS_ERR_UNEXPECTED_NULL_POINTER; } - /*-----------------------------------------------------------------* - * Allocate and initialize IVAS application decoder handle - *-----------------------------------------------------------------*/ - if ( ( *phIvasDec = (IVAS_DEC_HANDLE) count_malloc( sizeof( struct IVAS_DEC ) ) ) == NULL ) { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for IVAS decoder handle" ); @@ -133,16 +128,6 @@ ivas_error IVAS_DEC_Open( hIvasDec->mode = mode; - hIvasDec->bitstreamformat = G192; - hIvasDec->Opt_VOIP = 0; - hIvasDec->amrwb_rfc4867_flag = -1; - hIvasDec->prev_ft_speech = 1; /* RXDTX handler previous frametype flag for G.192 format AMRWB SID_FIRST detection */ - hIvasDec->CNG = 0; /* RXDTX handler CNG = 1, no CNG = 0*/ - - /*-----------------------------------------------------------------* - * Initialize IVAS-codec decoder state - *-----------------------------------------------------------------*/ - if ( ( hIvasDec->st_ivas = (Decoder_Struct *) count_malloc( sizeof( Decoder_Struct ) ) ) == NULL ) { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for IVAS decoder structure" ); @@ -153,49 +138,50 @@ ivas_error IVAS_DEC_Open( return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for Decoder config structure" ); } - /*-----------------------------------------------------------------* - * Initialize IVAS-codec decoder state - *-----------------------------------------------------------------*/ - - st_ivas = hIvasDec->st_ivas; - - /* initialize Decoder Config. handle */ init_decoder_config( hIvasDec->st_ivas->hDecoderConfig, orientation_tracking, no_diegetic_pan ); - /* initialize pointers to handles to NULL */ - ivas_initialize_handles_dec( st_ivas ); + hIvasDec->bitstreamformat = G192; + hIvasDec->Opt_VOIP = 0; + hIvasDec->amrwb_rfc4867_flag = -1; + hIvasDec->prev_ft_speech = 1; /* RXDTX handeler previous frametype flag for G.192 format AMRWB SID_FIRST detection */ + hIvasDec->CNG = 0; /* RXDTX handler CNG = 1, no CNG = 0*/ - /* set high-level parameters */ if ( mode == IVAS_DEC_MODE_EVS ) { - st_ivas->codec_mode = 0; /* unknown before first frame */ - st_ivas->element_mode_init = EVS_MONO; - st_ivas->ivas_format = MONO_FORMAT; - st_ivas->transport_config = AUDIO_CONFIG_INVALID; - st_ivas->intern_config = AUDIO_CONFIG_INVALID; - st_ivas->writeFECoffset = 0; + /* EVS - do alloc etc. */ + hIvasDec->st_ivas->codec_mode = 0; /* unknown before first frame */ + hIvasDec->st_ivas->element_mode_init = EVS_MONO; + hIvasDec->st_ivas->ivas_format = MONO_FORMAT; + hIvasDec->st_ivas->transport_config = AUDIO_CONFIG_INVALID; + hIvasDec->st_ivas->intern_config = AUDIO_CONFIG_INVALID; + hIvasDec->st_ivas->writeFECoffset = 0; return IVAS_ERR_OK; } else if ( mode == IVAS_DEC_MODE_IVAS ) { - st_ivas->codec_mode = 0; /* unknown before first frame */ - st_ivas->element_mode_init = -1; - st_ivas->ivas_format = UNDEFINED_FORMAT; - st_ivas->transport_config = AUDIO_CONFIG_INVALID; - st_ivas->intern_config = AUDIO_CONFIG_INVALID; - st_ivas->renderer_type = RENDERER_DISABLE; - st_ivas->ini_frame = 0; - st_ivas->ini_active_frame = 0; - st_ivas->writeFECoffset = 0; + hIvasDec->st_ivas->codec_mode = 0; /* unknown before first frame */ + hIvasDec->st_ivas->element_mode_init = -1; + hIvasDec->st_ivas->ivas_format = UNDEFINED_FORMAT; + hIvasDec->st_ivas->transport_config = AUDIO_CONFIG_INVALID; + hIvasDec->st_ivas->intern_config = AUDIO_CONFIG_INVALID; + hIvasDec->st_ivas->renderer_type = RENDERER_DISABLE; + hIvasDec->st_ivas->ini_frame = 0; + hIvasDec->st_ivas->ini_active_frame = 0; + hIvasDec->st_ivas->writeFECoffset = 0; +#ifndef SBA_ORDER_BITSTREAM + hIvasDec->st_ivas->sba_order = 0; +#else + hIvasDec->st_ivas->sba_analysis_order = 0; +#endif + hIvasDec->st_ivas->sba_planar = 0; - st_ivas->ism_mode = ISM_MODE_NONE; - st_ivas->sba_mode = SBA_MODE_NONE; - st_ivas->mc_mode = MC_MODE_NONE; + /*initialize pointers*/ + ivas_initialize_handles_dec( hIvasDec->st_ivas ); - st_ivas->sba_order = 0; - st_ivas->sba_planar = 0; - st_ivas->sba_analysis_order = 0; + hIvasDec->st_ivas->ism_mode = ISM_MODE_NONE; + hIvasDec->st_ivas->sba_mode = SBA_MODE_NONE; + hIvasDec->st_ivas->mc_mode = MC_MODE_NONE; return IVAS_ERR_OK; } @@ -250,14 +236,38 @@ void IVAS_DEC_Close( if ( ( *phIvasDec )->hVoIP ) { IVAS_DEC_Close_VoIP( ( *phIvasDec )->hVoIP ); - ( *phIvasDec )->hVoIP = NULL; + count_free( ( *phIvasDec )->hVoIP ); } - if ( ( *phIvasDec )->st_ivas ) + if ( ( *phIvasDec )->isInitialized ) { - ivas_destroy_dec( ( *phIvasDec )->st_ivas ); - ( *phIvasDec )->st_ivas = NULL; + if ( ( *phIvasDec )->st_ivas ) + { + ivas_destroy_dec( ( *phIvasDec )->st_ivas ); + } } + else + { + if ( ( *phIvasDec )->st_ivas->hDecoderConfig != NULL ) + { + count_free( ( *phIvasDec )->st_ivas->hDecoderConfig ); + ( *phIvasDec )->st_ivas->hDecoderConfig = NULL; + } + + if ( ( *phIvasDec )->st_ivas->hHeadTrackData != NULL ) + { + count_free( ( *phIvasDec )->st_ivas->hHeadTrackData ); + ( *phIvasDec )->st_ivas->hHeadTrackData = NULL; + } + + ivas_render_config_close( &( ( *phIvasDec )->st_ivas->hRenderConfig ) ); + + ivas_HRTF_binary_close( &( *phIvasDec )->st_ivas->hHrtfTD ); + + count_free( ( *phIvasDec )->st_ivas ); + } + + ( *phIvasDec )->st_ivas = NULL; count_free( *phIvasDec ); *phIvasDec = NULL; @@ -1131,11 +1141,7 @@ static bool isSidFrame( { return true; /* EVS SID */ } -#ifdef ALIGN_SID_SIZE - else if ( size == IVAS_SID_5k2 / FRAMES_PER_SEC ) -#else else if ( size == IVAS_SID_4k4 / FRAMES_PER_SEC ) -#endif { return true; /* IVAS SID */ } @@ -1468,8 +1474,6 @@ static void IVAS_DEC_Close_VoIP( pcmdsp_fifo_destroy( &hVoIP->hFifoAfterTimeScaler ); - count_free( hVoIP ); - return; } diff --git a/lib_dec/stat_dec.h b/lib_dec/stat_dec.h index 0c7a836cb4..8fc8ec5282 100644 --- a/lib_dec/stat_dec.h +++ b/lib_dec/stat_dec.h @@ -204,16 +204,15 @@ typedef struct Float32 *secondLastPcmOut; float *secondLastPowerSpectrum; -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT float scaleFactorsBackground[FDNS_NPTS]; - float scf_fadeout; PsychoacousticParameters *psychParams; + /* could be stored only once, since the same for all channels (always at 16Khz fs) */ PsychoacousticParameters psychParamsTCX20; PsychoacousticParameters psychParamsTCX10; float last_block_nrg; float curr_noise_nrg; - float faded_signal_nrg; #endif float nFramesLost; diff --git a/lib_dec/swb_tbe_dec.c b/lib_dec/swb_tbe_dec.c old mode 100644 new mode 100755 index 2664aaa08d..03d9162e34 --- a/lib_dec/swb_tbe_dec.c +++ b/lib_dec/swb_tbe_dec.c @@ -1973,11 +1973,12 @@ static void dequantizeSHBparams( *-------------------------------------------------------------------*/ void fb_tbe_dec( - Decoder_State *st, /* i/o: decoder state structure */ - const float fb_exc[], /* i : FB excitation from the SWB part */ - float *hb_synth, /* o : high-band synthesis */ - float *fb_synth_ref, /* o : high-band synthesis 16-20 kHz */ - const int16_t output_frame /* i : output frame length */ + Decoder_State *st, /* i/o: decoder state structure */ + const float fb_exc[], /* i : FB excitation from the SWB part */ + float *hb_synth, /* o : high-band synthesis */ + float *fb_synth_ref /* o : high-band synthesis 16-20 kHz */ + , + const int16_t output_frame /* i: output frame length */ ) { int16_t i; diff --git a/lib_dec/tonalMDCTconcealment.c b/lib_dec/tonalMDCTconcealment.c index 776d28bcb5..b43f85b8f9 100644 --- a/lib_dec/tonalMDCTconcealment.c +++ b/lib_dec/tonalMDCTconcealment.c @@ -93,16 +93,14 @@ ivas_error TonalMDCTConceal_Init( hTonalMDCTConc->nSamplesCore = nSamplesCore; hTonalMDCTConc->nScaleFactors = nScaleFactors; -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT set_zero( hTonalMDCTConc->scaleFactorsBackground, FDNS_NPTS ); - hTonalMDCTConc->scf_fadeout = 1.0f; PsychoacousticParameters_Init( INT_FS_16k, L_FRAME16k, 64, 1, 1, &hTonalMDCTConc->psychParamsTCX20 ); PsychoacousticParameters_Init( INT_FS_16k, L_FRAME16k / 2, 64, 0, 1, &hTonalMDCTConc->psychParamsTCX10 ); hTonalMDCTConc->psychParams = NULL; hTonalMDCTConc->last_block_nrg = 0.0f; hTonalMDCTConc->curr_noise_nrg = 0.0f; - hTonalMDCTConc->faded_signal_nrg = 0.0f; #endif /* Offset the pointer to the end of buffer, so that pTCI is not destroyed when @@ -125,7 +123,7 @@ void TonalMDCTConceal_SaveFreqSignal( const uint16_t nNewSamples, const uint16_t nNewSamplesCore, const float *scaleFactors -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT , const int16_t infoIGFStartLine #endif @@ -170,7 +168,7 @@ void TonalMDCTConceal_SaveFreqSignal( if ( ( nNewSamples > 0 ) && ( nNewSamples <= 2 * L_FRAME_MAX ) ) { /* Store new data */ -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT int16_t i; hTonalMDCTConc->last_block_nrg = 0.0f; @@ -502,9 +500,8 @@ void TonalMDCTConceal_InsertNoise( int16_t *pSeed, const float tiltCompFactor, const float crossfadeGain, -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT const float concealment_noise[L_FRAME48k], - const float cngLevelBackgroundTrace_bfi, #endif const int16_t crossOverFreq ) { @@ -512,18 +509,11 @@ void TonalMDCTConceal_InsertNoise( float x, y; Word16 rnd; float g, nrgNoiseInLastFrame, nrgWhiteNoise, tiltFactor, tilt; -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE - float last_block_nrg_correct; -#endif wmops_sub_start( "InsertNoise" ); g = 1.0f - crossfadeGain; -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE - if ( !hTonalMDCTConc->lastBlockData.blockIsConcealed ) -#else if ( !hTonalMDCTConc->lastBlockData.blockIsConcealed ) -#endif { rnd = 1977; } @@ -532,15 +522,13 @@ void TonalMDCTConceal_InsertNoise( rnd = *pSeed; } -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT /* based on what is done in tcx_noise_filling() */ /* always initialize these to avoid compiler warnings */ tiltFactor = (float) pow( max( 0.375f, tiltCompFactor ), 1.0f / hTonalMDCTConc->lastBlockData.nSamples ); tilt = 1.0f; nrgNoiseInLastFrame = 0.0f; nrgWhiteNoise = 0.0f; - hTonalMDCTConc->faded_signal_nrg = 0.0f; - last_block_nrg_correct = 0.0f; #endif if ( !hTonalMDCTConc->lastBlockData.blockIsValid ) @@ -548,7 +536,7 @@ void TonalMDCTConceal_InsertNoise( /* may just become active if the very first frame is lost */ set_f( mdctSpectrum, 0.0f, hTonalMDCTConc->nSamples ); } -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT else if ( concealment_noise != NULL ) { if ( !tonalConcealmentActive ) @@ -576,7 +564,7 @@ void TonalMDCTConceal_InsertNoise( /* actual fadeout is done in this case */ else { - g *= (float) sqrt( cngLevelBackgroundTrace_bfi / hTonalMDCTConc->curr_noise_nrg ); + g *= (float) sqrt( hTonalMDCTConc->last_block_nrg / hTonalMDCTConc->curr_noise_nrg ); for ( i = 0; i < crossOverFreq; i++ ) { @@ -591,8 +579,6 @@ void TonalMDCTConceal_InsertNoise( { mdctSpectrum[i] = g * y - crossfadeGain * x; } - - hTonalMDCTConc->faded_signal_nrg += mdctSpectrum[i] * mdctSpectrum[i]; } for ( l = crossOverFreq; l < hTonalMDCTConc->lastBlockData.nSamples; l++ ) { @@ -613,11 +599,6 @@ void TonalMDCTConceal_InsertNoise( for ( l = hTonalMDCTConc->pTCI->lowerIndex[i]; l <= hTonalMDCTConc->pTCI->upperIndex[i]; l++ ) { mdctSpectrum[l] = 0; - if ( l < crossOverFreq ) - { - last_block_nrg_correct += hTonalMDCTConc->lastBlockData.spectralData[l] * hTonalMDCTConc->lastBlockData.spectralData[l]; - hTonalMDCTConc->curr_noise_nrg -= concealment_noise[l] * concealment_noise[l]; - } } } @@ -670,7 +651,7 @@ void TonalMDCTConceal_InsertNoise( /* actual fadeout is done in this case */ else { - g *= (float) sqrt( cngLevelBackgroundTrace_bfi / hTonalMDCTConc->curr_noise_nrg ); + g *= (float) sqrt( hTonalMDCTConc->last_block_nrg / hTonalMDCTConc->curr_noise_nrg ); for ( l = 0; l < hTonalMDCTConc->pTCI->lowerIndex[0]; l++ ) { @@ -685,7 +666,6 @@ void TonalMDCTConceal_InsertNoise( { mdctSpectrum[l] = g * y - crossfadeGain * x; } - hTonalMDCTConc->faded_signal_nrg += mdctSpectrum[l] * mdctSpectrum[l]; } for ( i = 1; i < hTonalMDCTConc->pTCI->numIndexes; i++ ) { @@ -702,7 +682,6 @@ void TonalMDCTConceal_InsertNoise( { mdctSpectrum[l] = g * y - crossfadeGain * x; } - hTonalMDCTConc->faded_signal_nrg += mdctSpectrum[l] * mdctSpectrum[l]; } } @@ -719,7 +698,6 @@ void TonalMDCTConceal_InsertNoise( { mdctSpectrum[l] = g * y - crossfadeGain * x; } - hTonalMDCTConc->faded_signal_nrg += mdctSpectrum[l] * mdctSpectrum[l]; } for ( l = crossOverFreq; l < hTonalMDCTConc->lastBlockData.nSamples; l++ ) @@ -728,19 +706,11 @@ void TonalMDCTConceal_InsertNoise( } } } - - if ( hTonalMDCTConc->faded_signal_nrg > 0.0f && hTonalMDCTConc->curr_noise_nrg > MDCT_ST_PLC_FADEOUT_MIN_NOISE_NRG ) - { - float nrg_corr_factor; - - nrg_corr_factor = sqrtf( ( hTonalMDCTConc->last_block_nrg - last_block_nrg_correct ) / hTonalMDCTConc->faded_signal_nrg ); - v_multc( mdctSpectrum, nrg_corr_factor, mdctSpectrum, crossOverFreq ); - } } #endif else { -#ifndef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifndef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT /* based on what is done in tcx_noise_filling() */ tiltFactor = (float) pow( max( 0.375f, tiltCompFactor ), 1.0f / hTonalMDCTConc->lastBlockData.nSamples ); tilt = 1.0f; @@ -992,7 +962,7 @@ void TonalMDCTConceal_SaveTimeSignal( return; } -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT void TonalMdctConceal_create_concealment_noise( float concealment_noise[L_FRAME48k], CPE_DEC_HANDLE hCPE, @@ -1001,7 +971,7 @@ void TonalMdctConceal_create_concealment_noise( const int16_t idchan, const int16_t subframe_idx, const int16_t core, - const float crossfade_gain, + const int16_t crossfade_gain, const TONALMDCTCONC_NOISE_GEN_MODE noise_gen_mode ) { STEREO_MDCT_DEC_DATA_HANDLE hStereoMdct; @@ -1079,6 +1049,7 @@ void TonalMdctConceal_create_concealment_noise( c_inv = sqrtf( 1 - hStereoMdct->lastCoh ); /* pre-compute the noise shape for later weighting of the noise spectra */ + /* TODO: optimize by intertwining with later loop */ cngNoiseLevelPtr = &hFdCngCom->cngNoiseLevel[0]; inc = ( st->core > TCX_20_CORE ) ? 2 : 1; start_idx = hFdCngCom->startBand / inc; @@ -1101,7 +1072,7 @@ void TonalMdctConceal_create_concealment_noise( } /* fill the noise vector */ - hTonalMDCTConc->curr_noise_nrg = MDCT_ST_PLC_FADEOUT_MIN_NOISE_NRG; + hTonalMDCTConc->curr_noise_nrg = 0.001f; if ( noise_gen_mode == EQUAL_CORES || ( ( noise_gen_mode == TCX20_IN_0_TCX10_IN_1 && idchan == 0 ) || ( noise_gen_mode == TCX10_IN_0_TCX20_IN_1 && idchan == 1 ) ) ) { /* current channel is TCX20 -> generate noise for "full-length" spectrum */ @@ -1129,14 +1100,6 @@ void TonalMdctConceal_create_concealment_noise( } } - if ( st->tonal_mdct_plc_active ) - { - for ( i = crossOverFreq; i < max( crossOverFreq, hTonalMDCTConc->pTCI->lowerIndex[hTonalMDCTConc->pTCI->numIndexes - 1] ); ++i ) - { - concealment_noise[i] *= 0.0f; - } - } - /* restore common seed - after finishing the first channel - after a first subframe if the current channel is TCX10 */ @@ -1145,68 +1108,8 @@ void TonalMdctConceal_create_concealment_noise( *rnd_c = save_rnd_c; } - st->seed_tcx_plc = *rnd; - wmops_sub_end(); return; } - -void TonalMdctConceal_whiten_noise_shape( - Decoder_State *st, - const int16_t L_frame, - const TONALMDCTCONC_NOISE_SHAPE_WHITENING_MODE whitening_mode -) -{ - int16_t inc, start_idx, stop_idx; - float *noiseLevelPtr, *scfs_bg, *scfs_for_shaping; - HANDLE_FD_CNG_COM hFdCngCom; - float whitenend_noise_shape[L_FRAME16k]; - float scfs_int[FDNS_NPTS]; - const PsychoacousticParameters *psychParams; - - wmops_sub_start( "apply_sns_on_noise_shape" ); - - scfs_bg = &st->hTonalMDCTConc->scaleFactorsBackground[0]; - psychParams = st->hTonalMDCTConc->psychParams; - hFdCngCom = st->hFdCngDec->hFdCngCom; - - inc = ( ( whitening_mode == ON_FIRST_LOST_FRAME ? st->core : st->last_core ) > TCX_20_CORE ) ? 2 : 1; - start_idx = hFdCngCom->startBand / inc; - stop_idx = L_frame / inc; - noiseLevelPtr = hFdCngCom->cngNoiseLevel; - - set_zero( whitenend_noise_shape, start_idx ); - for ( int16_t j = start_idx; j < stop_idx; j++, noiseLevelPtr += inc ) - { - whitenend_noise_shape[j] = *noiseLevelPtr; - } - - if ( whitening_mode == ON_FIRST_LOST_FRAME ) - { - float scf[SNS_NPTS]; - - sns_compute_scf( whitenend_noise_shape, psychParams, L_frame, scf ); - sns_interpolate_scalefactors( scfs_int, scf, ENC ); - sns_interpolate_scalefactors( scfs_bg, scf, DEC ); - scfs_for_shaping = &scfs_int[0]; - } - else /* whitening_mode == ON_FIRST_GOOD_FRAME */ - { - scfs_for_shaping = &scfs_bg[0]; - } - - if ( sum_f( scfs_for_shaping, FDNS_NPTS ) > 0.0f ) - { - sns_shape_spectrum( whitenend_noise_shape, psychParams, scfs_for_shaping, L_frame ); - mvr2r( whitenend_noise_shape + start_idx, hFdCngCom->cngNoiseLevel, stop_idx - start_idx ); - } - else - { - set_zero( hFdCngCom->cngNoiseLevel, stop_idx - start_idx ); - } - - wmops_sub_end(); -} - #endif diff --git a/lib_enc/bw_detect.c b/lib_enc/bw_detect.c index c2955f1f39..c1357a7f74 100644 --- a/lib_enc/bw_detect.c +++ b/lib_enc/bw_detect.c @@ -494,6 +494,7 @@ void bw_detect( st->input_bwidth = st->max_bwidth; } + if ( st->element_mode == EVS_MONO ) { set_bw( -1, -1, st, st->codec_mode ); diff --git a/lib_enc/enc_prm.c b/lib_enc/enc_prm.c index 33c9d6fc7b..062069ceee 100644 --- a/lib_enc/enc_prm.c +++ b/lib_enc/enc_prm.c @@ -55,7 +55,7 @@ void writeTCXMode( Encoder_State *st, /* i/o: encoder state structure */ BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT const int16_t is_mct, #endif int16_t *nbits_start /* o : nbits start */ @@ -88,7 +88,7 @@ void writeTCXMode( push_next_indice( hBstr, index, 2 ); -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT if ( st->element_mode == IVAS_CPE_MDCT && !is_mct ) { push_next_indice( hBstr, st->vad_flag, 1 ); @@ -792,7 +792,7 @@ void enc_prm( /* EVS header */ /* Modes (ACE_GC, ACE_UC, TCX20, TCX10...) */ -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT writeTCXMode( st, st->hBstr, 0, /* <- is_mct */ &nbits_start ); #else writeTCXMode( st, st->hBstr, &nbits_start ); diff --git a/lib_enc/fd_cng_enc.c b/lib_enc/fd_cng_enc.c index 2f98addc8d..c2dfb1969f 100644 --- a/lib_enc/fd_cng_enc.c +++ b/lib_enc/fd_cng_enc.c @@ -902,12 +902,6 @@ void stereoFdCngCoherence( sts[0]->core_brate = SID_2k40; sts[1]->core_brate = SID_2k40; } - -#ifdef FIX_CONTROLLABLE_SID_UPDATE_RATE - /* synchronize SID counters */ - sts[0]->hDtxEnc->cnt_SID = min( sts[0]->hDtxEnc->cnt_SID, sts[1]->hDtxEnc->cnt_SID ); - sts[1]->hDtxEnc->cnt_SID = sts[0]->hDtxEnc->cnt_SID; -#endif } pt_fftL = fft_buff[0]; @@ -1008,7 +1002,11 @@ void FdCngEncodeMDCTStereoSID( convertToMS( N, ms_ptr[0], ms_ptr[1], 0.5f ); } - side_energy = sum2_f( ms_ptr[1], N ); + side_energy = 0.0f; + for ( p = 0; p < N; p++ ) + { + side_energy += ms_ptr[1][p] * ms_ptr[1][p]; + } /* do not transmit side shape if initial noise shapes are very similar */ if ( side_energy <= 0.1f ) @@ -1130,11 +1128,6 @@ void FdCngEncodeMDCTStereoSID( push_indice( sts[ch]->hBstr, IND_ENERGY, gain_idx[ch], 7 ); } -#ifdef ALIGN_SID_SIZE - /* pad with zeros to reach common SID frame size */ - push_indice( sts[1]->hBstr, IND_ENERGY, 0, ( IVAS_SID_5k2 - 4400 ) / FRAMES_PER_SEC ); -#endif - return; } @@ -1188,11 +1181,18 @@ void FdCngEncodeDiracMDCTStereoSID( /* M/S transform on log envelopes */ convertToMS( NPART, ms_ptr[0], ms_ptr[1], 0.5f ); - E[0] = sum_f( ms_ptr[0], NPART ); - + E[0] = 0.0f; + for ( p = 0; p < NPART; p++ ) + { + E[0] += ms_ptr[0][p]; + } /* Quantize M noise shape */ /* Normalize MSVW input */ - gain[0] = sum_f( ms_ptr[0] + N_GAIN_MIN, N_GAIN_MAX - N_GAIN_MIN ); + gain[0] = 0.f; + for ( p = N_GAIN_MIN; p < N_GAIN_MAX; p++ ) + { + gain[0] += ms_ptr[0][p]; + } gain[0] /= (float) ( N_GAIN_MAX - N_GAIN_MIN ); for ( p = 0; p < N[0]; p++ ) @@ -1208,7 +1208,11 @@ void FdCngEncodeDiracMDCTStereoSID( set_zero( ms_ptr[1], NPART ); /* compute M gain */ - gain[0] = sum_f( ms_ptr[0], NPART ); + gain[0] = 0.f; + for ( p = 0; p < NPART; p++ ) + { + gain[0] += ms_ptr[0][p]; + } gain[0] = ( E[0] - gain[0] ) / (float) N[0]; apply_scale( &gain[0], sts[0]->hFdCngEnc->hFdCngCom->CngBandwidth, sts[0]->hDtxEnc->last_active_brate, scaleTableStereo, SIZE_SCALE_TABLE_STEREO ); diff --git a/lib_enc/igf_enc.c b/lib_enc/igf_enc.c old mode 100755 new mode 100644 index 7b658908b5..2cf98207bb --- a/lib_enc/igf_enc.c +++ b/lib_enc/igf_enc.c @@ -1852,17 +1852,13 @@ void IGFEncApplyStereo( const IGF_ENC_INSTANCE_HANDLE hIGFEnc[CPE_CHANNELS], /* i : instance handle of IGF Encoder */ const int16_t igfGridIdx, /* i : IGF grid index */ Encoder_State *sts[CPE_CHANNELS], /* i : Encoder state */ -#ifdef DRAM_REDUCTION_MCT_IGF - float *pPowerSpectrum[CPE_CHANNELS], /* i/o: MDCT^2 + MDST^2 spectrum, or estimate */ -#else float pPowerSpectrum[CPE_CHANNELS][N_MAX], /* i/o: MDCT^2 + MDST^2 spectrum, or estimate */ -#endif float *pPowerSpectrumMsInv[CPE_CHANNELS][2], /* i/o: inverse power spectrum */ float *inv_spectrum[CPE_CHANNELS][2], /* i : inverse spectrum */ const int16_t frameno, /* i : flag indicating index of current subfr. */ const int16_t sp_aud_decision0, /* i : sp_aud_decision0 */ const int32_t element_brate, /* i : element bitrate */ - const int16_t mct_on /* i : flag mct block (1) or stereo (0) */ + const int16_t mct_on /* i : flag mct block (1) or stereo (0) */ ) { float *pPowerSpectrumParameter[2]; /* If it is NULL it informs a function that specific handling is needed */ diff --git a/lib_enc/ivas_agc_enc.c b/lib_enc/ivas_agc_enc.c index 3ed7bb6d2f..493d1ac071 100644 --- a/lib_enc/ivas_agc_enc.c +++ b/lib_enc/ivas_agc_enc.c @@ -242,7 +242,7 @@ void ivas_agc_enc_process( if ( !isClipped ) { - if ( ( ppPcm_out[i][j] > ( 1.f - pState->minDelta ) * PCM16_TO_FLT_FAC ) || ( ppPcm_out[i][j] < MIN16B_FLT ) ) + if ( ( ppPcm_out[i][j] > ( 1.f - pState->minDelta ) ) || ( ppPcm_out[i][j] < -1.f ) ) { if ( j < offset ) { @@ -278,7 +278,7 @@ void ivas_agc_enc_process( maxGain = max( smoothedMaxAbsVal, MaxAbsVal ) * pState->gain_state[i].lastGain * 2.f; - if ( maxGain < ( 1.f - pState->minDelta ) * PCM16_TO_FLT_FAC ) + if ( maxGain < 1.f - pState->minDelta ) { pState->gain_state[i].gainExpVal = -1; } @@ -313,7 +313,7 @@ void ivas_agc_enc_process( { int16_t isCompensated = FALSE; pState->gain_data[i].gainException = FALSE; - pState->gain_state[i].gainExpVal = (int16_t) ceilf( -logf( actualMaxAbsVal * MDFT_NORM_SCALING ) / logf( pState->agc_com.winFunc[MaxAbsValIdx] ) ); + pState->gain_state[i].gainExpVal = (int16_t) ceilf( -logf( actualMaxAbsVal ) / logf( pState->agc_com.winFunc[MaxAbsValIdx] ) ); while ( !isCompensated ) { @@ -324,7 +324,7 @@ void ivas_agc_enc_process( { tmpSignal = ppPcm_out[i][idx] * powf( pState->agc_com.winFunc[idx], (float) pState->gain_state[i].gainExpVal ); - if ( ( tmpSignal > ( 1.f - pState->minDelta ) * PCM16_TO_FLT_FAC ) || ( tmpSignal < MIN16B_FLT ) ) + if ( ( tmpSignal > ( 1.f - pState->minDelta ) ) || ( tmpSignal < -1.f ) ) { isCompensated = FALSE; break; @@ -374,7 +374,7 @@ void ivas_agc_enc_process( } else { - pState->gain_state[i].gainExpVal = (int16_t) ( -floorf( -logf( ( actualMaxAbsVal + pState->minDelta ) * MDFT_NORM_SCALING ) * INV_LOG_2 ) ); + pState->gain_state[i].gainExpVal = (int16_t) ( -floorf( -logf( actualMaxAbsVal + pState->minDelta ) * INV_LOG_2 ) ); pState->gain_state[i].gainExpVal = min( gainExpValMaxRange, pState->gain_state[i].gainExpVal ); gain = powf( 2.0f, -1.0f * pState->gain_state[i].gainExpVal ); diff --git a/lib_enc/ivas_cpe_enc.c b/lib_enc/ivas_cpe_enc.c index 08c45af220..b543761491 100644 --- a/lib_enc/ivas_cpe_enc.c +++ b/lib_enc/ivas_cpe_enc.c @@ -115,6 +115,7 @@ ivas_error ivas_cpe_enc( input_Fs = hEncoderConfig->input_Fs; ivas_total_brate = hEncoderConfig->ivas_total_brate; + /*------------------------------------------------------------------* * Initialization - general *-----------------------------------------------------------------*/ @@ -343,6 +344,12 @@ ivas_error ivas_cpe_enc( 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() */ + if ( ( sts[0]->last_bwidth < max_bwidth ) || ( sts[0]->last_core_brate <= SID_2k40 ) ) /* IVAS_fmToDo: TBV - BWD output is not known here yet !!! */ + { + /* reconfigure in case of BW switching or if last frame was a SID/NO_DATA with coarse partitioning */ + hCPE->hStereoDft->nbands = stereo_dft_band_config( hCPE->hStereoDft->band_limits, hCPE->hStereoDft->hConfig->band_res, hCPE->hStereoDft->NFFT, ENC ); + } + /* Update DFT Stereo memories */ stereo_dft_enc_update( hCPE->hStereoDft, sts[0]->max_bwidth #ifdef DEBUG_MODE_DFT @@ -453,11 +460,7 @@ ivas_error ivas_cpe_enc( { if ( hCPE->element_mode == IVAS_CPE_DFT || hCPE->element_mode == IVAS_CPE_TD ) { -#ifdef ALIGN_SID_SIZE - reset_metadata_spatial( ivas_format, hCPE->hMetaData, hCPE->element_brate, &tmp, sts[0]->core_brate, nb_bits_metadata, st_ivas->sba_mode ); -#else reset_metadata_spatial( ivas_format, hCPE->hMetaData, hCPE->element_brate, &tmp, sts[0]->core_brate, nb_bits_metadata, st_ivas->sba_mode, hCPE->element_mode ); -#endif } } @@ -469,11 +472,7 @@ ivas_error ivas_cpe_enc( /* Reset metadata */ if ( sts[0]->cng_sba_flag || ( ivas_format == SBA_FORMAT && st_ivas->sba_mode == SBA_MODE_SPAR ) ) { -#ifdef ALIGN_SID_SIZE - reset_metadata_spatial( ivas_format, hCPE->hMetaData, hCPE->element_brate, &tmp, sts[0]->core_brate, nb_bits_metadata, st_ivas->sba_mode ); -#else reset_metadata_spatial( ivas_format, hCPE->hMetaData, hCPE->element_brate, &tmp, sts[0]->core_brate, nb_bits_metadata, st_ivas->sba_mode, hCPE->element_mode ); -#endif } } @@ -542,11 +541,7 @@ ivas_error ivas_cpe_enc( * Write IVAS format signaling in SID frames *----------------------------------------------------------------*/ -#ifdef ALIGN_SID_SIZE - if ( sts[0]->core_brate == SID_2k40 ) -#else if ( sts[0]->core_brate == SID_2k40 && ( ivas_format != SBA_FORMAT || st_ivas->sba_mode != SBA_MODE_SPAR ) ) -#endif { ivas_write_format_sid( ivas_format, hCPE->element_mode, sts[0]->hBstr ); } @@ -565,11 +560,7 @@ ivas_error ivas_cpe_enc( /* Reconfigure DFT Stereo for inactive frames */ if ( sts[0]->core_brate == SID_2k40 ) { -#ifdef ALIGN_SID_SIZE - stereo_dft_config( hCPE->hStereoDft->hConfig, IVAS_SID_5k2, &sts[0]->bits_frame_nominal, &sts[1]->bits_frame_nominal ); -#else stereo_dft_config( hCPE->hStereoDft->hConfig, IVAS_SID_4k4, &sts[0]->bits_frame_nominal, &sts[1]->bits_frame_nominal ); -#endif } else { @@ -613,11 +604,7 @@ ivas_error ivas_cpe_enc( if ( sts[0]->core_brate == FRAME_NO_DATA || sts[0]->core_brate == SID_2k40 ) { -#ifdef ALIGN_SID_SIZE - assert( ( nb_bits <= ( ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS ) ) && "Stereo DFT CNG: bit budget is violated" ); -#else assert( ( nb_bits <= ( ( IVAS_SID_4k4 - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS ) ) && "Stereo DFT CNG: bit budget is violated" ); -#endif } else { diff --git a/lib_enc/ivas_dirac_enc.c b/lib_enc/ivas_dirac_enc.c index 9d5893622d..557cb109ca 100644 --- a/lib_enc/ivas_dirac_enc.c +++ b/lib_enc/ivas_dirac_enc.c @@ -122,29 +122,19 @@ ivas_error ivas_dirac_enc_open( if ( st_ivas->sba_mode == SBA_MODE_DIRAC ) { hDirAC->num_samples_synchro_delay = NS2SA( input_Fs, IVAS_FB_ENC_DELAY_NS ); -#ifdef FIX_DIRAC_CHANNELS - for ( i = 0; i < DIRAC_MAX_ANA_CHANS; i++ ) -#else for ( i = 0; i < st_ivas->hEncoderConfig->nchan_inp; i++ ) -#endif { hDirAC->sba_synchro_buffer[i] = (float *) count_malloc( hDirAC->num_samples_synchro_delay * sizeof( float ) ); set_zero( hDirAC->sba_synchro_buffer[i], hDirAC->num_samples_synchro_delay ); } -#ifndef FIX_DIRAC_CHANNELS for ( ; i < IVAS_MAX_NUM_CH; i++ ) { hDirAC->sba_synchro_buffer[i] = NULL; } -#endif } else { -#ifdef FIX_DIRAC_CHANNELS - for ( i = 0; i < DIRAC_MAX_ANA_CHANS; i++ ) -#else for ( i = 0; i < IVAS_MAX_NUM_CH; i++ ) -#endif { hDirAC->sba_synchro_buffer[i] = NULL; } @@ -252,11 +242,7 @@ void ivas_dirac_enc_close( ivas_FB_mixer_close( &hDirAC->hFbMixer, input_Fs ); } -#ifdef FIX_DIRAC_CHANNELS - for ( i = 0; i < DIRAC_MAX_ANA_CHANS; i++ ) -#else for ( i = 0; i < IVAS_MAX_NUM_CH; i++ ) -#endif { if ( hDirAC->sba_synchro_buffer[i] != NULL ) { @@ -426,7 +412,9 @@ void ivas_dirac_enc( } /* encode SID parameters */ - ivas_qmetadata_enc_sid_encode( hMetaData, hQMetaData, -1, SBA_FORMAT, SBA_MODE_DIRAC ); + ivas_qmetadata_enc_sid_encode( hMetaData, hQMetaData, -1, + SBA_FORMAT, + SBA_MODE_DIRAC ); /* restore original metadata */ hDirAC->hConfig->nbands = nbands; @@ -441,12 +429,10 @@ void ivas_dirac_enc( } else { -#ifdef ALIGN_SID_SIZE - /*indicate whether SPAR or DiRAC mode*/ - push_next_indice( hMetaData, 0, 1 ); -#endif /* encode SID parameters */ - ivas_qmetadata_enc_sid_encode( hMetaData, hQMetaData, -1, SBA_FORMAT, SBA_MODE_DIRAC ); + ivas_qmetadata_enc_sid_encode( hMetaData, hQMetaData, -1, + SBA_FORMAT, + SBA_MODE_DIRAC ); } } } @@ -456,7 +442,6 @@ void ivas_dirac_enc( return; } - /*------------------------------------------------------------------------- * computeReferencePower_enc() * @@ -472,11 +457,7 @@ void ivas_dirac_enc_spar_delay_synchro( int16_t ch_idx; float tmp_buffer[L_FRAME48k]; -#ifdef FIX_DIRAC_CHANNELS - for ( ch_idx = 0; ch_idx < DIRAC_MAX_ANA_CHANS; ch_idx++ ) -#else for ( ch_idx = 0; ch_idx < st_ivas->hEncoderConfig->nchan_inp; ch_idx++ ) -#endif { mvr2r( data_f[ch_idx], tmp_buffer, input_frame ); mvr2r( st_ivas->hDirAC->sba_synchro_buffer[ch_idx], data_f[ch_idx], st_ivas->hDirAC->num_samples_synchro_delay ); @@ -487,7 +468,6 @@ void ivas_dirac_enc_spar_delay_synchro( return; } - /*------------------------------------------------------------------------- * computeReferencePower_enc() * @@ -527,13 +507,11 @@ void computeReferencePower_enc( return; } - /*------------------------------------------------------------------------- * ivas_dirac_param_est_enc() * * *------------------------------------------------------------------------*/ - void ivas_dirac_param_est_enc( DIRAC_ENC_HANDLE hDirAC, IVAS_QDIRECTION *q_direction, diff --git a/lib_enc/ivas_enc.c b/lib_enc/ivas_enc.c old mode 100644 new mode 100755 diff --git a/lib_enc/ivas_init_enc.c b/lib_enc/ivas_init_enc.c index e4db2ce2a1..21a7eb839f 100644 --- a/lib_enc/ivas_init_enc.c +++ b/lib_enc/ivas_init_enc.c @@ -233,22 +233,53 @@ void copy_encoder_config( st->force = st_ivas->hEncoderConfig->force; #endif st->element_mode = st_ivas->hEncoderConfig->element_mode_init; - return; } -/*------------------------------------------------------------------------- - * ivas_initialize_handles_enc() +/*-------------------------------------------------------------------* + * ivas_init_encoder() * - * NULL initialization of handles - *-------------------------------------------------------------------------*/ + * Initialize IVAS encoder state structure + *-------------------------------------------------------------------*/ -void ivas_initialize_handles_enc( - Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ +ivas_error ivas_init_encoder( + Encoder_Struct *st_ivas, /* i/o: IVAS encoder structure */ + Indice ind_list[][MAX_NUM_INDICES], /* o : bitstream indices */ + Indice ind_list_metadata[][MAX_BITS_METADATA] /* o : bitstream indices metadata */ ) { - int16_t i; + int16_t i, n; + int16_t sce_id, cpe_id; + IVAS_FORMAT ivas_format; + int32_t input_Fs, ivas_total_brate; + ENCODER_CONFIG_HANDLE hEncoderConfig; + ivas_error error; + + error = IVAS_ERR_OK; + + hEncoderConfig = st_ivas->hEncoderConfig; + ivas_format = hEncoderConfig->ivas_format; + input_Fs = hEncoderConfig->input_Fs; + ivas_total_brate = hEncoderConfig->ivas_total_brate; + + hEncoderConfig->last_ivas_total_brate = ivas_total_brate; + + if ( ivas_format != MONO_FORMAT ) + { + /* In IVAS, ensure that minimum coded bandwidth is WB */ + hEncoderConfig->max_bwidth = max( hEncoderConfig->max_bwidth, WB ); + } + + st_ivas->ism_mode = ISM_MODE_NONE; + st_ivas->mc_mode = MC_MODE_NONE; + st_ivas->sba_mode = SBA_MODE_NONE; + + /*-----------------------------------------------------------------* + * Dummy pointers to max. number of SCEs and CPEs + *-----------------------------------------------------------------*/ + + st_ivas->nchan_transport = -1; for ( i = 0; i < MAX_SCE; i++ ) { @@ -260,12 +291,10 @@ void ivas_initialize_handles_enc( st_ivas->hCPE[i] = NULL; } - st_ivas->mem_hp20_in = NULL; - /* ISm metadata handles */ - for ( i = 0; i < MAX_NUM_OBJECTS; i++ ) + for ( n = 0; n < MAX_NUM_OBJECTS; n++ ) { - st_ivas->hIsmMetaData[i] = NULL; + st_ivas->hIsmMetaData[n] = NULL; } /* Q Metadata handle */ @@ -295,50 +324,6 @@ void ivas_initialize_handles_enc( /* LFE handle */ st_ivas->hLFE = NULL; - return; -} - - -/*-------------------------------------------------------------------* - * ivas_init_encoder() - * - * Initialize IVAS encoder state structure - *-------------------------------------------------------------------*/ - -ivas_error ivas_init_encoder( - Encoder_Struct *st_ivas, /* i/o: IVAS encoder structure */ - Indice ind_list[][MAX_NUM_INDICES], /* o : bitstream indices */ - Indice ind_list_metadata[][MAX_BITS_METADATA] /* o : bitstream indices metadata */ -) -{ - int16_t i, n; - int16_t sce_id, cpe_id; - IVAS_FORMAT ivas_format; - int32_t input_Fs, ivas_total_brate; - ENCODER_CONFIG_HANDLE hEncoderConfig; - ivas_error error; - - error = IVAS_ERR_OK; - - hEncoderConfig = st_ivas->hEncoderConfig; - ivas_format = hEncoderConfig->ivas_format; - input_Fs = hEncoderConfig->input_Fs; - ivas_total_brate = hEncoderConfig->ivas_total_brate; - - hEncoderConfig->last_ivas_total_brate = ivas_total_brate; - - if ( ivas_format != MONO_FORMAT ) - { - /* In IVAS, ensure that minimum coded bandwidth is WB */ - hEncoderConfig->max_bwidth = max( hEncoderConfig->max_bwidth, WB ); - } - - st_ivas->ism_mode = ISM_MODE_NONE; - st_ivas->mc_mode = MC_MODE_NONE; - st_ivas->sba_mode = SBA_MODE_NONE; - - st_ivas->nchan_transport = -1; - /*-----------------------------------------------------------------* * Allocate and initialize SCE/CPE and other handles *-----------------------------------------------------------------*/ @@ -427,17 +412,17 @@ ivas_error ivas_init_encoder( } else if ( ivas_format == SBA_FORMAT || ivas_format == MASA_FORMAT ) { - if ( ( error = ivas_qmetadata_open( &( st_ivas->hQMetaData ) ) ) != IVAS_ERR_OK ) { - return error; + if ( ( error = ivas_qmetadata_open( &( st_ivas->hQMetaData ) ) ) != IVAS_ERR_OK ) + { + return error; + } } if ( ivas_format == SBA_FORMAT ) { st_ivas->sba_mode = ivas_sba_mode_select( ivas_total_brate ); - st_ivas->sba_analysis_order = ivas_sba_get_analysis_order( ivas_total_brate, st_ivas->hEncoderConfig->sba_order ); - if ( st_ivas->sba_mode == SBA_MODE_SPAR ) { if ( ( error = ivas_spar_enc_open( st_ivas ) ) != IVAS_ERR_OK ) @@ -596,7 +581,6 @@ ivas_error ivas_init_encoder( else if ( st_ivas->mc_mode == MC_MODE_MCMASA ) { ivas_mcmasa_setNumTransportChannels( &( st_ivas->nchan_transport ), &( hEncoderConfig->element_mode_init ), ivas_total_brate ); - if ( ( error = ivas_qmetadata_open( &( st_ivas->hQMetaData ) ) ) != IVAS_ERR_OK ) { return error; @@ -884,7 +868,7 @@ void ivas_destroy_enc( if ( st_ivas->hSCE[i] != NULL ) { destroy_sce_enc( st_ivas->hSCE[i] ); - st_ivas->hSCE[i] = NULL; + st_ivas->hSCE[0] = NULL; } } diff --git a/lib_enc/ivas_ism_enc.c b/lib_enc/ivas_ism_enc.c index 2433c01802..2653829d13 100644 --- a/lib_enc/ivas_ism_enc.c +++ b/lib_enc/ivas_ism_enc.c @@ -214,11 +214,7 @@ ivas_error ivas_ism_enc( ivas_write_format_sid( st_ivas->hEncoderConfig->ivas_format, IVAS_SCE, st->hBstr ); /* write unused bits */ -#ifdef ALIGN_SID_SIZE - nBits = ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS; -#else nBits = ( IVAS_SID_4k4 - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS; -#endif while ( nBits > 0 ) { i = min( nBits, 16 ); diff --git a/lib_enc/ivas_masa_enc.c b/lib_enc/ivas_masa_enc.c index c2649adc56..2e233bbc6d 100644 --- a/lib_enc/ivas_masa_enc.c +++ b/lib_enc/ivas_masa_enc.c @@ -350,7 +350,9 @@ void ivas_masa_encode( count_free( h_orig_metadata ); - ivas_qmetadata_enc_sid_encode( hMetaData, hQMetaData, masa_sid_descriptor, ivas_format, SBA_MODE_NONE ); + ivas_qmetadata_enc_sid_encode( hMetaData, hQMetaData, masa_sid_descriptor, + ivas_format, + SBA_MODE_NONE ); /* restore old values */ hMasa->config.numCodingBands = numCodingBands; diff --git a/lib_enc/ivas_mcmasa_enc.c b/lib_enc/ivas_mcmasa_enc.c index a281ec4760..595f758e51 100644 --- a/lib_enc/ivas_mcmasa_enc.c +++ b/lib_enc/ivas_mcmasa_enc.c @@ -70,7 +70,9 @@ static void ivas_mcmasa_dmx( MCMASA_ENC_HANDLE hMcMasa, float data_f[][L_FRAME48 static void compute_cov_mtx( float sr[MCMASA_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX], float si[MCMASA_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX], const int16_t freq, const int16_t N, CovarianceMatrix *COVls ); -static void computeIntensityVector_enc( const int16_t *band_grouping, float Cldfb_RealBuffer[DIRAC_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX], float Cldfb_ImagBuffer[DIRAC_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX], const int16_t enc_param_start_band, const int16_t num_frequency_bands, float intensity_real[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS] ); +static void computeIntensityVector_enc( const int16_t *band_grouping, float Cldfb_RealBuffer[DIRAC_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX], float Cldfb_ImagBuffer[DIRAC_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX], const int16_t enc_param_start_band, /* i: first band to process */ + const int16_t num_frequency_bands, + float intensity_real[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS] ); static void computeVerticalDiffuseness( float **buffer_intensity, const float *buffer_energy, const int16_t averaging_length, const int16_t num_freq_bands, float *diffuseness ); diff --git a/lib_enc/ivas_mct_core_enc.c b/lib_enc/ivas_mct_core_enc.c old mode 100644 new mode 100755 diff --git a/lib_enc/ivas_mct_enc.c b/lib_enc/ivas_mct_enc.c index 9aa5fe04c5..20a2856654 100644 --- a/lib_enc/ivas_mct_enc.c +++ b/lib_enc/ivas_mct_enc.c @@ -193,26 +193,25 @@ ivas_error create_mct_enc( hMCT->nchan_out_woLFE = st_ivas->hEncoderConfig->nchan_inp - 1; /* LFE channel is coded separately */ hMCT->num_lfe = TRUE; } -#ifdef HARMONIZE_SBA_NCHAN_TRANSPORT - else if ( ivas_format == SBA_FORMAT ) - { - hMCT->nchan_out_woLFE = ivas_get_sba_num_TCs( ivas_total_brate, st_ivas->sba_analysis_order ); - - hMCT->num_lfe = FALSE; - } -#else else if ( ivas_format == SBA_FORMAT && st_ivas->hSpar ) { +#ifndef SBA_ORDER_BITSTREAM + hMCT->nchan_out_woLFE = ivas_get_spar_num_TCs( ivas_total_brate, st_ivas->hEncoderConfig->sba_order ); +#else hMCT->nchan_out_woLFE = ivas_get_spar_num_TCs( ivas_total_brate, st_ivas->sba_analysis_order ); +#endif hMCT->num_lfe = FALSE; } else if ( ivas_format == SBA_FORMAT && st_ivas->hDirAC ) { +#ifndef SBA_ORDER_BITSTREAM + hMCT->nchan_out_woLFE = ivas_dirac_getNumTransportChannels( ivas_total_brate, st_ivas->hEncoderConfig->sba_order, st_ivas->hEncoderConfig->sba_planar ); +#else hMCT->nchan_out_woLFE = ivas_dirac_getNumTransportChannels( ivas_total_brate, st_ivas->sba_analysis_order, st_ivas->hEncoderConfig->sba_planar ); +#endif hMCT->num_lfe = FALSE; } -#endif else if ( ivas_format == MC_FORMAT && st_ivas->mc_mode == MC_MODE_PARAMMC ) { hMCT->nchan_out_woLFE = ivas_param_mc_getNumTransportChannels( ivas_total_brate, st_ivas->hEncoderConfig->mc_input_setup ); @@ -220,7 +219,11 @@ ivas_error create_mct_enc( } else if ( ivas_format == SBA_FORMAT ) { +#ifndef SBA_ORDER_BITSTREAM + hMCT->nchan_out_woLFE = ivas_sba_get_nchan( st_ivas->hEncoderConfig->sba_order, st_ivas->hEncoderConfig->sba_planar ); +#else hMCT->nchan_out_woLFE = ivas_sba_get_nchan( st_ivas->sba_analysis_order, st_ivas->hEncoderConfig->sba_planar ); +#endif hMCT->num_lfe = FALSE; } else @@ -346,29 +349,24 @@ ivas_error mct_enc_reconfigure( hMCT->nchan_out_woLFE = st_ivas->hEncoderConfig->nchan_inp - 1; /* LFE channel is coded separately */ hMCT->num_lfe = TRUE; } -#ifdef HARMONIZE_SBA_NCHAN_TRANSPORT - else if ( ivas_format == SBA_FORMAT && st_ivas->hDirAC ) // VE: this condition to be reviewed together with the following one - { - hMCT->nchan_out_woLFE = ivas_get_sba_num_TCs( ivas_total_brate, st_ivas->sba_analysis_order ); - hMCT->num_lfe = FALSE; - } - else if ( ivas_format == SBA_FORMAT ) - { - hMCT->nchan_out_woLFE = ivas_sba_get_nchan( st_ivas->sba_analysis_order, st_ivas->hEncoderConfig->sba_planar ); - hMCT->num_lfe = FALSE; - } -#else else if ( ivas_format == SBA_FORMAT && st_ivas->hDirAC ) { +#ifndef SBA_ORDER_BITSTREAM + hMCT->nchan_out_woLFE = ivas_dirac_getNumTransportChannels( ivas_total_brate, st_ivas->hEncoderConfig->sba_order, st_ivas->hEncoderConfig->sba_planar ); +#else hMCT->nchan_out_woLFE = ivas_dirac_getNumTransportChannels( ivas_total_brate, st_ivas->sba_analysis_order, st_ivas->hEncoderConfig->sba_planar ); +#endif hMCT->num_lfe = FALSE; } else if ( ivas_format == SBA_FORMAT ) { +#ifndef SBA_ORDER_BITSTREAM + hMCT->nchan_out_woLFE = ivas_sba_get_nchan( st_ivas->hEncoderConfig->sba_order, st_ivas->hEncoderConfig->sba_planar ); +#else hMCT->nchan_out_woLFE = ivas_sba_get_nchan( st_ivas->sba_analysis_order, st_ivas->hEncoderConfig->sba_planar ); +#endif hMCT->num_lfe = FALSE; } -#endif else { assert( !"IVAS format currently not supported for MCT" ); diff --git a/lib_enc/ivas_mct_enc_mct.c b/lib_enc/ivas_mct_enc_mct.c old mode 100755 new mode 100644 index 309a023fe7..62ff9be888 --- a/lib_enc/ivas_mct_enc_mct.c +++ b/lib_enc/ivas_mct_enc_mct.c @@ -834,11 +834,7 @@ void mctStereoIGF_enc( float *p_powerSpecMsInv[CPE_CHANNELS][NB_DIV]; float *p_inv_spectrum[CPE_CHANNELS][NB_DIV]; float *p_orig_spectrum[CPE_CHANNELS][NB_DIV]; -#ifdef DRAM_REDUCTION_MCT_IGF - float *p_powerSpec[NB_DIV]; -#else float p_powerSpec[NB_DIV][N_MAX]; -#endif int16_t singleChEle[MCT_MAX_CHANNELS]; L_subframeTCX = 0; /* to avoid compilation warning */ @@ -859,15 +855,10 @@ void mctStereoIGF_enc( p_st[0] = sts[ch1]; p_st[1] = sts[ch2]; -#ifdef DRAM_REDUCTION_MCT_IGF - p_powerSpec[0] = powerSpec[ch1]; - p_powerSpec[1] = powerSpec[ch2]; -#else mvr2r( powerSpec[ch1], p_powerSpec[0], L_FRAME48k ); set_f( &p_powerSpec[0][L_FRAME48k], 0.f, N_MAX - L_FRAME48k ); mvr2r( powerSpec[ch2], p_powerSpec[1], L_FRAME48k ); set_f( &p_powerSpec[1][L_FRAME48k], 0.f, N_MAX - L_FRAME48k ); -#endif /* Band-wise M/S for MDST */ nSubframes = p_st[0]->hTcxEnc->tcxMode == TCX_20 ? 1 : NB_DIV; diff --git a/lib_enc/ivas_mdct_core_enc.c b/lib_enc/ivas_mdct_core_enc.c index 0d2f5817d6..4d9d1f2577 100644 --- a/lib_enc/ivas_mdct_core_enc.c +++ b/lib_enc/ivas_mdct_core_enc.c @@ -63,7 +63,7 @@ static void enc_prm_pre_mdct( int16_t param[], /* i : parameters */ const int16_t *no_param_tns, /* i : number of TNS parameters per subframe */ int16_t p_param[2], /* o : pointer to parameters for next round of bs writing */ -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT const int16_t is_mct, #endif BSTR_ENC_HANDLE hBstr /* i/o: encoder bitstream handle */ @@ -80,7 +80,7 @@ static void enc_prm_pre_mdct( * Header *--------------------------------------------------------------------------------*/ -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT writeTCXMode( st, hBstr, is_mct, &nbits_start ); #else writeTCXMode( st, hBstr, &nbits_start ); @@ -1065,7 +1065,7 @@ void ivas_mdct_core_whitening_enc( continue; } -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT enc_prm_pre_mdct( st, param_core[ch], ( ( ( ch > 0 ) && ( sts[0]->hTcxEnc->fUseTns[0] + sts[0]->hTcxEnc->fUseTns[1] > 0 ) && !mct_on ) ? tnsSize[ch] : NULL ), p_param[ch], mct_on, hBstr ); #else enc_prm_pre_mdct( st, param_core[ch], ( ( ( ch > 0 ) && ( sts[0]->hTcxEnc->fUseTns[0] + sts[0]->hTcxEnc->fUseTns[1] > 0 ) && !mct_on ) ? tnsSize[ch] : NULL ), p_param[ch], hBstr ); diff --git a/lib_enc/ivas_qmetadata_enc.c b/lib_enc/ivas_qmetadata_enc.c index 6042c9e10a..f62b61e4ef 100644 --- a/lib_enc/ivas_qmetadata_enc.c +++ b/lib_enc/ivas_qmetadata_enc.c @@ -150,7 +150,7 @@ ivas_error ivas_qmetadata_enc_encode( int16_t diff_bits, bits_ec, next_ind_raw_flag; int16_t dfRatio_bits[MASA_MAXIMUM_CODING_SUBBANDS]; int16_t bits_surround_coh, no_TF; - int16_t dir2_bands[MASA_MAXIMUM_TWO_DIR_BANDS]; + int16_t dir2_bands[MASA_MAXIMUM_CODING_SUBBANDS / 2]; int16_t ind_order[MASA_MAXIMUM_CODING_SUBBANDS]; int16_t reduce_bits; ivas_error error; @@ -684,32 +684,17 @@ void ivas_qmetadata_enc_sid_encode( { if ( sba_mode == SBA_MODE_SPAR ) { -#ifdef ALIGN_SID_SIZE - /* TODO: still use old sid frame size to keep bitexactness */ - metadata_sid_bits = (int16_t) ( 5000 /*IVAS_SID_5k2*/ - SID_2k40 ) / FRAMES_PER_SEC - ( SPAR_DTX_BANDS * SPAR_SID_BITS_TAR_PER_BAND ) - 1; /* -1 for inactive mode header bit*/ -#else metadata_sid_bits = (int16_t) ( IVAS_SID_5k - SID_2k40 ) / FRAMES_PER_SEC - ( SPAR_DTX_BANDS * SPAR_SID_BITS_TAR_PER_BAND ) - 1; /* -1 for inactive mode header bit*/ -#endif } else { - /* keep 13.2 and 16.4 SID bitrate as 4.4 kbps for now*/ -#ifdef ALIGN_SID_SIZE - /* TODO: still use old sid frame size to keep bitexactness */ - metadata_sid_bits = ( 4400 /*IVAS_SID_5k2*/ - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS; -#else + /* keep 13.2 and 16.4 sid bitrate as 4.4 kbps for now*/ metadata_sid_bits = ( IVAS_SID_4k4 - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS; -#endif } } else { -#ifdef ALIGN_SID_SIZE - /* TODO: still use old sid frame size to keep bitexactness */ - metadata_sid_bits = ( 4400 /*IVAS_SID_5k2*/ - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS; -#else metadata_sid_bits = ( IVAS_SID_4k4 - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS; -#endif } #ifdef DEBUG_MODE_QMETADATA @@ -888,22 +873,6 @@ void ivas_qmetadata_enc_sid_encode( } #endif -#ifdef ALIGN_SID_SIZE - /* TODO: temporary to keep BE */ - if ( ivas_format == SBA_FORMAT ) - { - if ( sba_mode != SBA_MODE_SPAR ) - { - /* keep 13.2 and 16.4 SID bitrate as 4.4 kbps for now*/ - metadata_sid_bits = ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS - 1; /* -1 for spar/dirac indicator*/ - } - } - else - { - metadata_sid_bits = ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS; - } -#endif - /* fill bits*/ assert( ( hMetaData->nb_bits_tot - bit_pos_start ) <= metadata_sid_bits && "Too many written bits!" ); while ( ( hMetaData->nb_bits_tot - bit_pos_start ) < metadata_sid_bits ) @@ -927,18 +896,11 @@ void reset_metadata_spatial( int32_t *total_brate, /* o : total bitrate */ const int32_t core_brate, /* i : core bitrate */ const int16_t nb_bits_metadata, /* i : number of meatdata bits */ -#ifndef ALIGN_SID_SIZE - const SBA_MODE sba_mode, /* i : SBA mode */ - const int16_t element_mode /* i : element mode */ -#else - const SBA_MODE sba_mode /* i : SBA mode */ -#endif + const SBA_MODE sba_mode, /* i : SBA mode */ + const int16_t element_mode /* i : element mode */ ) { int16_t i, next_ind_sid, last_ind_sid; -#ifdef ALIGN_SID_SIZE - int16_t metadata_sid_bits; -#endif if ( core_brate == SID_2k40 || core_brate == FRAME_NO_DATA ) { @@ -947,14 +909,6 @@ void reset_metadata_spatial( if ( sba_mode == SBA_MODE_SPAR ) { assert( hMetaData->ind_list[0].nb_bits == 1 ); -#ifdef ALIGN_SID_SIZE - hMetaData->ind_list[0].value = 1; - metadata_sid_bits = (int16_t) ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS; - while ( hMetaData->nb_bits_tot < metadata_sid_bits ) - { - push_next_indice( hMetaData, 0, 1 ); /*fill bit*/ - } -#else if ( element_mode > IVAS_SCE ) { hMetaData->ind_list[0].value = 1; @@ -963,7 +917,6 @@ void reset_metadata_spatial( { hMetaData->ind_list[0].value = 0; } -#endif } else { @@ -993,11 +946,7 @@ void reset_metadata_spatial( hMetaData->ind_list[i].nb_bits = -1; } hMetaData->last_ind = hMetaData->next_ind; -#ifdef ALIGN_SID_SIZE - assert( ( hMetaData->nb_bits_tot == ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS ) && "Problem of SID metadata in SCE" ); -#else assert( ( hMetaData->nb_bits_tot == ( IVAS_SID_4k4 - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS ) && "Problem of SID metadata in SCE" ); -#endif } } else diff --git a/lib_enc/ivas_rom_enc.c b/lib_enc/ivas_rom_enc.c index ebc4ee6bc3..e8048b8f1a 100644 --- a/lib_enc/ivas_rom_enc.c +++ b/lib_enc/ivas_rom_enc.c @@ -534,6 +534,160 @@ const float ari_bit_estimate_s17_LC[RANGE_N_CONTEXT][RANGE_N_SYMBOLS] = * Stereo downmix to EVS ROM tables *----------------------------------------------------------------------------------*/ +#ifndef NTT_REMOVE_EPS_ROM +const float Stereo_dmx_s_wnd_coef_eps_16k[L_FRAME16k * 3 / 4] = { + 0.00000000f, 0.000385506690f, 0.000770864717f, 0.00115592557f, 0.00154054083f, 0.00192456215f, 0.00230784155f, 0.00269023119f, 0.00307158381f, 0.00345175178f, + 0.00383058959f, 0.00420795102f, 0.00458368938f, 0.00495766103f, 0.00532972161f, 0.00569972629f, 0.00606753491f, 0.00643300405f, 0.00679599261f, 0.00715636183f, + 0.00751397246f, 0.00786868576f, 0.00822036527f, 0.00856887549f, 0.00891408324f, 0.00925585348f, 0.00959405676f, 0.00992856082f, 0.0102592362f, 0.0105859563f, + 0.0109085962f, 0.0112270303f, 0.0115411365f, 0.0118507938f, 0.0121558821f, 0.0124562839f, 0.0127518829f, 0.0130425673f, 0.0133282226f, 0.0136087397f, + 0.0138840098f, 0.0141539266f, 0.0144183896f, 0.0146772927f, 0.0149305379f, 0.0151780248f, 0.0154196629f, 0.0156553555f, 0.0158850122f, 0.0161085464f, + 0.0163258687f, 0.0165368970f, 0.0167415515f, 0.0169397499f, 0.0171314199f, 0.0173164830f, 0.0174948741f, 0.0176665168f, 0.0178313497f, 0.0179893095f, + 0.0181403328f, 0.0182843637f, 0.0184213445f, 0.0185512230f, 0.0186739527f, 0.0187894795f, 0.0188977662f, 0.0189987645f, 0.0190924387f, 0.0191787537f, + 0.0192576759f, 0.0193291716f, 0.0193932168f, 0.0194497835f, 0.0194988549f, 0.0195404068f, 0.0195744261f, 0.0196008999f, 0.0196198169f, 0.0196311697f, + 0.0196349546f, 0.0196311697f, 0.0196198169f, 0.0196008999f, 0.0195744261f, 0.0195404068f, 0.0194988549f, 0.0194497835f, 0.0193932150f, 0.0193291716f, + 0.0192576740f, 0.0191787537f, 0.0190924387f, 0.0189987645f, 0.0188977644f, 0.0187894795f, 0.0186739508f, 0.0185512230f, 0.0184213426f, 0.0182843637f, + 0.0181403328f, 0.0179893095f, 0.0178313479f, 0.0176665168f, 0.0174948722f, 0.0173164830f, 0.0171314199f, 0.0169397499f, 0.0167415496f, 0.0165368970f, + 0.0163258687f, 0.0161085445f, 0.0158850104f, 0.0156553555f, 0.0154196629f, 0.0151780220f, 0.0149305360f, 0.0146772927f, 0.0144183887f, 0.0141539248f, + 0.0138840098f, 0.0136087388f, 0.0133282207f, 0.0130425654f, 0.0127518829f, 0.0124562830f, 0.0121558802f, 0.0118507929f, 0.0115411356f, 0.0112270294f, + 0.0109085953f, 0.0105859553f, 0.0102592343f, 0.00992855709f, 0.00959405396f, 0.00925585162f, 0.00891408045f, 0.00856887735f, 0.00822036248f, 0.00786868297f, + 0.00751396874f, 0.00715636322f, 0.00679598982f, 0.00643300032f, 0.00606753537f, 0.00569972722f, 0.00532971695f, 0.00495765638f, 0.00458368938f, 0.00420795055f, + 0.00383058493f, 0.00345175178f, 0.00307158334f, 0.00269023073f, 0.00230784062f, 0.00192456122f, 0.00154053967f, 0.00115592428f, 0.000770863262f, 0.000385505118f, + -1.71654224e-09f, -0.000385508552f, -0.000770866696f, -0.00115592312f, -0.00154053851f, -0.00192456460f, -0.00230784412f, -0.00269023376f, -0.00307158637f, -0.00345175504f, + -0.00383058819f, -0.00420794915f, -0.00458368799f, -0.00495766429f, -0.00532972487f, -0.00569973048f, -0.00606753910f, -0.00643300358f, -0.00679599261f, -0.00715636183f, + -0.00751397153f, -0.00786868948f, -0.00822036993f, -0.00856888015f, -0.00891408417f, -0.00925585441f, -0.00959405676f, -0.00992856082f, -0.0102592362f, -0.0105859619f, + -0.0109086009f, -0.0112270284f, -0.0115411393f, -0.0118507957f, -0.0121558839f, -0.0124562858f, -0.0127518848f, -0.0130425720f, -0.0133282207f, -0.0136087369f, + -0.0138840117f, -0.0141539304f, -0.0144183915f, -0.0146772945f, -0.0149305388f, -0.0151780248f, -0.0154196648f, -0.0156553555f, -0.0158850141f, -0.0161085445f, + -0.0163258705f, -0.0165369026f, -0.0167415477f, -0.0169397499f, -0.0171314217f, -0.0173164848f, -0.0174948759f, -0.0176665168f, -0.0178313479f, -0.0179893095f, + -0.0181403328f, -0.0182843637f, -0.0184213463f, -0.0185512248f, -0.0186739527f, -0.0187894795f, -0.0188977644f, -0.0189987663f, -0.0190924387f, -0.0191787556f, + -0.0192576759f, -0.0193291716f, -0.0193932150f, -0.0194497835f, -0.0194988549f, -0.0195404068f, -0.0195744261f, -0.0196008999f, -0.0196198169f, -0.0196311697f +}; + +const float Stereo_dmx_s_wnd_coef_eps_32k[L_FRAME32k * 3 / 4] = { + 0.00000000f, 9.63813145e-05f, 0.000192753345f, 0.000289106771f, 0.000385432359f, 0.000481720810f, 0.000577962783f, 0.000674149080f, 0.000770270417f, 0.000866317423f, + 0.000962281076f, 0.00105815195f, 0.00115392078f, 0.00124957843f, 0.00134511560f, 0.00144052308f, 0.00153579190f, 0.00163091265f, 0.00172587589f, 0.00182067312f, + 0.00191529479f, 0.00200973195f, 0.00210397551f, 0.00219801581f, 0.00229184469f, 0.00238545262f, 0.00247883052f, 0.00257196953f, 0.00266486080f, 0.00275749480f, + 0.00284986314f, 0.00294195698f, 0.00303376745f, 0.00312528526f, 0.00321650202f, 0.00330740865f, 0.00339799630f, 0.00348825660f, 0.00357818091f, 0.00366776017f, + 0.00375698623f, 0.00384584931f, 0.00393434288f, 0.00402245624f, 0.00411018264f, 0.00419751229f, 0.00428443775f, 0.00437095016f, 0.00445704162f, 0.00454270327f, + 0.00462792674f, 0.00471270457f, 0.00479702838f, 0.00488088885f, 0.00496428041f, 0.00504719233f, 0.00512961810f, 0.00521154935f, 0.00529297814f, 0.00537389703f, + 0.00545429811f, 0.00553417346f, 0.00561351515f, 0.00569231622f, 0.00577056827f, 0.00584826432f, 0.00592539692f, 0.00600195816f, 0.00607794104f, 0.00615333812f, + 0.00622814195f, 0.00630234554f, 0.00637594145f, 0.00644892361f, 0.00652128365f, 0.00659301504f, 0.00666411128f, 0.00673456443f, 0.00680436986f, 0.00687351823f, + 0.00694200490f, 0.00700982194f, 0.00707696332f, 0.00714342389f, 0.00720919482f, 0.00727427099f, 0.00733864633f, 0.00740231434f, 0.00746526895f, 0.00752750318f, + 0.00758901238f, 0.00764979096f, 0.00770983147f, 0.00776912877f, 0.00782767776f, 0.00788547192f, 0.00794250611f, 0.00799877476f, 0.00805427320f, 0.00810899399f, + 0.00816293433f, 0.00821608771f, 0.00826844852f, 0.00832001306f, 0.00837077573f, 0.00842073187f, 0.00846987497f, 0.00851820316f, 0.00856570993f, 0.00861239061f, + 0.00865824148f, 0.00870325882f, 0.00874743704f, 0.00879077055f, 0.00883325841f, 0.00887489505f, 0.00891567487f, 0.00895559601f, 0.00899465475f, 0.00903284643f, + 0.00907016639f, 0.00910661276f, 0.00914218184f, 0.00917686895f, 0.00921067223f, 0.00924358703f, 0.00927561149f, 0.00930674188f, 0.00933697633f, 0.00936630927f, + 0.00939473975f, 0.00942226499f, 0.00944888312f, 0.00947458949f, 0.00949938223f, 0.00952325948f, 0.00954621937f, 0.00956825912f, 0.00958937686f, 0.00960957073f, + 0.00962883793f, 0.00964717567f, 0.00966458581f, 0.00968106277f, 0.00969660841f, 0.00971121807f, 0.00972489174f, 0.00973762851f, 0.00974942744f, 0.00976028573f, + 0.00977020338f, 0.00977917947f, 0.00978721306f, 0.00979430322f, 0.00980044995f, 0.00980565138f, 0.00980990846f, 0.00981321931f, 0.00981558487f, 0.00981700420f, + 0.00981747732f, 0.00981700420f, 0.00981558487f, 0.00981321931f, 0.00980990846f, 0.00980565138f, 0.00980044995f, 0.00979430322f, 0.00978721306f, 0.00977917947f, + 0.00977020338f, 0.00976028573f, 0.00974942744f, 0.00973762851f, 0.00972489174f, 0.00971121807f, 0.00969660748f, 0.00968106277f, 0.00966458581f, 0.00964717567f, + 0.00962883700f, 0.00960956980f, 0.00958937686f, 0.00956825912f, 0.00954621937f, 0.00952325948f, 0.00949938223f, 0.00947458856f, 0.00944888219f, 0.00942226499f, + 0.00939473975f, 0.00936630927f, 0.00933697540f, 0.00930674188f, 0.00927561149f, 0.00924358703f, 0.00921067130f, 0.00917686801f, 0.00914218184f, 0.00910661276f, + 0.00907016639f, 0.00903284550f, 0.00899465475f, 0.00895559601f, 0.00891567394f, 0.00887489505f, 0.00883325841f, 0.00879077055f, 0.00874743611f, 0.00870325882f, + 0.00865824148f, 0.00861238968f, 0.00856570993f, 0.00851820316f, 0.00846987497f, 0.00842073094f, 0.00837077480f, 0.00832001306f, 0.00826844852f, 0.00821608678f, + 0.00816293433f, 0.00810899399f, 0.00805427227f, 0.00799877476f, 0.00794250518f, 0.00788547192f, 0.00782767776f, 0.00776912784f, 0.00770983147f, 0.00764979003f, + 0.00758901099f, 0.00752750272f, 0.00746526802f, 0.00740231294f, 0.00733864633f, 0.00727427006f, 0.00720919436f, 0.00714342296f, 0.00707696239f, 0.00700982334f, + 0.00694200490f, 0.00687351730f, 0.00680436939f, 0.00673456397f, 0.00666411035f, 0.00659301365f, 0.00652128272f, 0.00644892408f, 0.00637594145f, 0.00630234415f, + 0.00622814149f, 0.00615333673f, 0.00607794011f, 0.00600195862f, 0.00592539646f, 0.00584826525f, 0.00577056780f, 0.00569231436f, 0.00561351469f, 0.00553417206f, + 0.00545429764f, 0.00537389750f, 0.00529297767f, 0.00521154935f, 0.00512961717f, 0.00504719047f, 0.00496427855f, 0.00488088885f, 0.00479702698f, 0.00471270457f, + 0.00462792581f, 0.00454270281f, 0.00445704022f, 0.00437094783f, 0.00428443868f, 0.00419751182f, 0.00411018124f, 0.00402245624f, 0.00393434148f, 0.00384584907f, + 0.00375698437f, 0.00366775948f, 0.00357818161f, 0.00348825636f, 0.00339799491f, 0.00330740795f, 0.00321650016f, 0.00312528457f, 0.00303376769f, 0.00294195651f, + 0.00284986361f, 0.00275749387f, 0.00266485848f, 0.00257196836f, 0.00247882819f, 0.00238545146f, 0.00229184469f, 0.00219801464f, 0.00210397528f, 0.00200973079f, + 0.00191529247f, 0.00182067417f, 0.00172587589f, 0.00163091114f, 0.00153579167f, 0.00144052168f, 0.00134511536f, 0.00124957680f, 0.00115392031f, 0.00105815264f, + 0.000962280610f, 0.000866315851f, 0.000770269835f, 0.000674147333f, 0.000577962142f, 0.000481721276f, 0.000385431631f, 0.000289107207f, 0.000192752559f, 9.63793209e-05f, + -8.58271121e-10f, -9.63833809e-05f, -0.000192754276f, -0.000289106567f, -0.000385433348f, -0.000481720665f, -0.000577961560f, -0.000674149022f, -0.000770269253f, -0.000866317481f, + -0.000962282298f, -0.00105815206f, -0.00115392206f, -0.00124957855f, -0.00134511688f, -0.00144052564f, -0.00153579318f, -0.00163091510f, -0.00172587752f, -0.00182067591f, + -0.00191529409f, -0.00200973242f, -0.00210397458f, -0.00219801627f, -0.00229184399f, -0.00238545309f, -0.00247883215f, -0.00257196999f, -0.00266486243f, -0.00275749573f, + -0.00284986524f, -0.00294196024f, -0.00303376955f, -0.00312528410f, -0.00321650179f, -0.00330740749f, -0.00339799630f, -0.00348825776f, -0.00357818091f, -0.00366776134f, + -0.00375698577f, -0.00384585070f, -0.00393434474f, -0.00402245764f, -0.00411018496f, -0.00419751368f, -0.00428444007f, -0.00437094970f, -0.00445704209f, -0.00454270234f, + -0.00462792721f, -0.00471270364f, -0.00479702838f, -0.00488089072f, -0.00496428041f, -0.00504719326f, -0.00512961810f, -0.00521155121f, -0.00529298093f, -0.00537389843f, + -0.00545430044f, -0.00553417299f, -0.00561351422f, -0.00569231622f, -0.00577056967f, -0.00584826432f, -0.00592539785f, -0.00600195816f, -0.00607794197f, -0.00615333952f, + -0.00622814288f, -0.00630234741f, -0.00637594238f, -0.00644892501f, -0.00652128598f, -0.00659301504f, -0.00666411035f, -0.00673456537f, -0.00680436846f, -0.00687351823f, + -0.00694200583f, -0.00700982241f, -0.00707696518f, -0.00714342389f, -0.00720919576f, -0.00727427332f, -0.00733864726f, -0.00740231574f, -0.00746526942f, -0.00752750272f, + -0.00758901238f, -0.00764979143f, -0.00770983240f, -0.00776912784f, -0.00782767776f, -0.00788547192f, -0.00794250704f, -0.00799877662f, -0.00805427227f, -0.00810899492f, + -0.00816293526f, -0.00821608957f, -0.00826845132f, -0.00832001399f, -0.00837077387f, -0.00842073094f, -0.00846987497f, -0.00851820316f, -0.00856571086f, -0.00861239061f, + -0.00865824241f, -0.00870325882f, -0.00874743797f, -0.00879077241f, -0.00883325841f, -0.00887489505f, -0.00891567394f, -0.00895559601f, -0.00899465475f, -0.00903284643f, + -0.00907016639f, -0.00910661276f, -0.00914218184f, -0.00917686988f, -0.00921067316f, -0.00924358703f, -0.00927561242f, -0.00930674374f, -0.00933697633f, -0.00936631020f, + -0.00939473975f, -0.00942226499f, -0.00944888219f, -0.00947458949f, -0.00949938316f, -0.00952326041f, -0.00954621937f, -0.00956825912f, -0.00958937779f, -0.00960957073f, + -0.00962883793f, -0.00964717567f, -0.00966458581f, -0.00968106370f, -0.00969660748f, -0.00971121807f, -0.00972489174f, -0.00973762851f, -0.00974942744f, -0.00976028573f, + -0.00977020338f, -0.00977917947f, -0.00978721306f, -0.00979430322f, -0.00980044995f, -0.00980565138f, -0.00980990846f, -0.00981321931f, -0.00981558487f, -0.00981700420f +}; + +const float Stereo_dmx_s_wnd_coef_eps_48k[L_FRAME48k * 3 / 4] = { + 0.00000000f, 4.28365238e-05f, 8.56712068e-05f, 0.000128502230f, 0.000171327745f, 0.000214145897f, 0.000256954925f, 0.000299752894f, 0.000342538056f, 0.000385308522f, + 0.000428062514f, 0.000470798172f, 0.000513513631f, 0.000556207087f, 0.000598876737f, 0.000641520717f, 0.000684137223f, 0.000726724451f, 0.000769280537f, 0.000811803620f, + 0.000854292011f, 0.000896743732f, 0.000939157035f, 0.000981530058f, 0.00102386123f, 0.00106614840f, 0.00110838993f, 0.00115058408f, 0.00119272876f, 0.00123482244f, + 0.00127686327f, 0.00131884927f, 0.00136077893f, 0.00140265026f, 0.00144446141f, 0.00148621085f, 0.00152789650f, 0.00156951661f, 0.00161106954f, 0.00165255368f, + 0.00169396668f, 0.00173530739f, 0.00177657383f, 0.00181776390f, 0.00185887620f, 0.00189990876f, 0.00194086006f, 0.00198172848f, 0.00202251156f, 0.00206320849f, + 0.00210381625f, 0.00214433460f, 0.00218476099f, 0.00222509354f, 0.00226533110f, 0.00230547134f, 0.00234551285f, 0.00238545402f, 0.00242529274f, 0.00246502785f, + 0.00250465749f, 0.00254417956f, 0.00258359266f, 0.00262289518f, 0.00266208523f, 0.00270116120f, 0.00274012191f, 0.00277896458f, 0.00281768874f, 0.00285629183f, + 0.00289477292f, 0.00293312967f, 0.00297136116f, 0.00300946506f, 0.00304743997f, 0.00308528449f, 0.00312299700f, 0.00316057540f, 0.00319801876f, 0.00323532475f, + 0.00327249244f, 0.00330952019f, 0.00334640569f, 0.00338314800f, 0.00341974548f, 0.00345619628f, 0.00349249900f, 0.00352865248f, 0.00356465438f, 0.00360050355f, + 0.00363619882f, 0.00367173832f, 0.00370712043f, 0.00374234351f, 0.00377740664f, 0.00381230796f, 0.00384704559f, 0.00388161885f, 0.00391602563f, 0.00395026430f, + 0.00398433441f, 0.00401823362f, 0.00405196054f, 0.00408551423f, 0.00411889236f, 0.00415209495f, 0.00418511871f, 0.00421796367f, 0.00425062794f, 0.00428310968f, + 0.00431540888f, 0.00434752228f, 0.00437944988f, 0.00441118982f, 0.00444274070f, 0.00447410159f, 0.00450527016f, 0.00453624642f, 0.00456702849f, 0.00459761405f, + 0.00462800311f, 0.00465819426f, 0.00468818564f, 0.00471797585f, 0.00474756397f, 0.00477694906f, 0.00480613019f, 0.00483510410f, 0.00486387173f, 0.00489243073f, + 0.00492078019f, 0.00494891917f, 0.00497684581f, 0.00500455918f, 0.00503205787f, 0.00505934143f, 0.00508640893f, 0.00511325756f, 0.00513988733f, 0.00516629731f, + 0.00519248564f, 0.00521845184f, 0.00524419453f, 0.00526971230f, 0.00529500423f, 0.00532006938f, 0.00534490682f, 0.00536951516f, 0.00539389346f, 0.00541804079f, + 0.00544195622f, 0.00546563789f, 0.00548908627f, 0.00551229948f, 0.00553527568f, 0.00555801531f, 0.00558051746f, 0.00560277933f, 0.00562480185f, 0.00564658362f, + 0.00566812325f, 0.00568941981f, 0.00571047375f, 0.00573128136f, 0.00575184496f, 0.00577216130f, 0.00579223083f, 0.00581205217f, 0.00583162485f, 0.00585094700f, + 0.00587001862f, 0.00588883879f, 0.00590740750f, 0.00592572242f, 0.00594378356f, 0.00596159045f, 0.00597914122f, 0.00599643635f, 0.00601347443f, 0.00603025546f, + 0.00604677759f, 0.00606304128f, 0.00607904466f, 0.00609478820f, 0.00611026958f, 0.00612549018f, 0.00614044815f, 0.00615514303f, 0.00616957434f, 0.00618374115f, + 0.00619764347f, 0.00621127989f, 0.00622465089f, 0.00623775460f, 0.00625059102f, 0.00626316015f, 0.00627546059f, 0.00628749235f, 0.00629925495f, 0.00631074747f, + 0.00632196991f, 0.00633292133f, 0.00634360174f, 0.00635401066f, 0.00636414625f, 0.00637401035f, 0.00638360064f, 0.00639291806f, 0.00640196120f, 0.00641073054f, + 0.00641922513f, 0.00642744405f, 0.00643538870f, 0.00644305674f, 0.00645044958f, 0.00645756535f, 0.00646440545f, 0.00647096802f, 0.00647725351f, 0.00648326147f, + 0.00648899190f, 0.00649444386f, 0.00649961783f, 0.00650451379f, 0.00650913082f, 0.00651346892f, 0.00651752809f, 0.00652130833f, 0.00652480870f, 0.00652803015f, + 0.00653097173f, 0.00653363345f, 0.00653601484f, 0.00653811684f, 0.00653993897f, 0.00654148031f, 0.00654274225f, 0.00654372340f, 0.00654442422f, 0.00654484471f, + 0.00654498488f, 0.00654484471f, 0.00654442422f, 0.00654372340f, 0.00654274225f, 0.00654148031f, 0.00653993897f, 0.00653811684f, 0.00653601484f, 0.00653363345f, + 0.00653097173f, 0.00652802968f, 0.00652480870f, 0.00652130833f, 0.00651752809f, 0.00651346892f, 0.00650913082f, 0.00650451332f, 0.00649961783f, 0.00649444386f, + 0.00648899190f, 0.00648326147f, 0.00647725351f, 0.00647096802f, 0.00646440499f, 0.00645756535f, 0.00645044912f, 0.00644305674f, 0.00643538870f, 0.00642744405f, + 0.00641922466f, 0.00641073054f, 0.00640196120f, 0.00639291806f, 0.00638360064f, 0.00637400988f, 0.00636414625f, 0.00635401020f, 0.00634360174f, 0.00633292086f, + 0.00632196991f, 0.00631074747f, 0.00629925495f, 0.00628749235f, 0.00627546012f, 0.00626315968f, 0.00625059055f, 0.00623775413f, 0.00622465042f, 0.00621127989f, + 0.00619764347f, 0.00618374115f, 0.00616957434f, 0.00615514303f, 0.00614044769f, 0.00612549018f, 0.00611027004f, 0.00609478774f, 0.00607904419f, 0.00606304081f, + 0.00604677759f, 0.00603025500f, 0.00601347489f, 0.00599643635f, 0.00597914122f, 0.00596158998f, 0.00594378309f, 0.00592572149f, 0.00590740703f, 0.00588883879f, + 0.00587001862f, 0.00585094653f, 0.00583162392f, 0.00581205124f, 0.00579223037f, 0.00577216130f, 0.00575184496f, 0.00573128182f, 0.00571047282f, 0.00568941981f, + 0.00566812325f, 0.00564658316f, 0.00562480185f, 0.00560277933f, 0.00558051653f, 0.00555801531f, 0.00553527661f, 0.00551229948f, 0.00548908627f, 0.00546563789f, + 0.00544195622f, 0.00541804079f, 0.00539389299f, 0.00536951469f, 0.00534490682f, 0.00532006891f, 0.00529500330f, 0.00526971091f, 0.00524419360f, 0.00521845091f, + 0.00519248564f, 0.00516629778f, 0.00513988733f, 0.00511325756f, 0.00508640800f, 0.00505934190f, 0.00503205787f, 0.00500455871f, 0.00497684488f, 0.00494891871f, + 0.00492077926f, 0.00489242980f, 0.00486387173f, 0.00483510457f, 0.00480612973f, 0.00477694906f, 0.00474756444f, 0.00471797585f, 0.00468818471f, 0.00465819333f, + 0.00462800311f, 0.00459761359f, 0.00456702709f, 0.00453624595f, 0.00450526970f, 0.00447410066f, 0.00444273977f, 0.00441119028f, 0.00437944988f, 0.00434752181f, + 0.00431540795f, 0.00428310968f, 0.00425062748f, 0.00421796273f, 0.00418511871f, 0.00415209448f, 0.00411889143f, 0.00408551283f, 0.00405196007f, 0.00401823269f, + 0.00398433302f, 0.00395026430f, 0.00391602563f, 0.00388161885f, 0.00384704513f, 0.00381230796f, 0.00377740664f, 0.00374234305f, 0.00370711950f, 0.00367173809f, + 0.00363619835f, 0.00360050285f, 0.00356465275f, 0.00352865178f, 0.00349249784f, 0.00345619605f, 0.00341974595f, 0.00338314800f, 0.00334640522f, 0.00330951903f, + 0.00327249290f, 0.00323532452f, 0.00319801806f, 0.00316057424f, 0.00312299654f, 0.00308528380f, 0.00304743880f, 0.00300946319f, 0.00297135999f, 0.00293312967f, + 0.00289477245f, 0.00285629253f, 0.00281768874f, 0.00277896435f, 0.00274012075f, 0.00270116120f, 0.00266208476f, 0.00262289424f, 0.00258359103f, 0.00254417886f, + 0.00250465632f, 0.00246502645f, 0.00242529227f, 0.00238545449f, 0.00234551262f, 0.00230547064f, 0.00226533134f, 0.00222509331f, 0.00218476006f, 0.00214433344f, + 0.00210381625f, 0.00206320756f, 0.00202251016f, 0.00198172801f, 0.00194085937f, 0.00189990760f, 0.00185887585f, 0.00181776448f, 0.00177657383f, 0.00173530704f, + 0.00169396598f, 0.00165255368f, 0.00161106919f, 0.00156951568f, 0.00152789650f, 0.00148621027f, 0.00144446036f, 0.00140264863f, 0.00136077835f, 0.00131884834f, + 0.00127686316f, 0.00123482186f, 0.00119272911f, 0.00115058396f, 0.00110838923f, 0.00106614875f, 0.00102386111f, 0.000981529476f, 0.000939155812f, 0.000896743557f, + 0.000854291196f, 0.000811802340f, 0.000769278675f, 0.000726723636f, 0.000684137398f, 0.000641520426f, 0.000598877436f, 0.000556207204f, 0.000513513223f, 0.000470797240f, + 0.000428062631f, 0.000385308114f, 0.000342537096f, 0.000299751409f, 0.000256954430f, 0.000214144908f, 0.000171326188f, 0.000128500149f, 8.56717088e-05f, 4.28364874e-05f, + -5.72180747e-10f, -4.28360690e-05f, -8.56712868e-05f, -0.000128502856f, -0.000171328895f, -0.000214146057f, -0.000256955565f, -0.000299754087f, -0.000342539803f, -0.000385309249f, + -0.000428063737f, -0.000470799918f, -0.000513512816f, -0.000556206855f, -0.000598876970f, -0.000641521532f, -0.000684137049f, -0.000726724742f, -0.000769281352f, -0.000811805017f, + -0.000854292419f, -0.000896744605f, -0.000939158490f, -0.000981530524f, -0.00102386216f, -0.00106614991f, -0.00110839040f, -0.00115058350f, -0.00119272876f, -0.00123482291f, + -0.00127686432f, -0.00131884939f, -0.00136077951f, -0.00140265131f, -0.00144446141f, -0.00148621143f, -0.00152789755f, -0.00156951835f, -0.00161107024f, -0.00165255321f, + -0.00169396691f, -0.00173530797f, -0.00177657336f, -0.00181776413f, -0.00185887702f, -0.00189990853f, -0.00194086053f, -0.00198172918f, -0.00202251296f, -0.00206320873f, + -0.00210381718f, -0.00214433600f, -0.00218476262f, -0.00222509308f, -0.00226533087f, -0.00230547180f, -0.00234551216f, -0.00238545402f, -0.00242529344f, -0.00246502901f, + -0.00250465726f, -0.00254418002f, -0.00258359360f, -0.00262289657f, -0.00266208570f, -0.00270116236f, -0.00274012331f, -0.00277896388f, -0.00281768828f, -0.00285629206f, + -0.00289477338f, -0.00293312944f, -0.00297136139f, -0.00300946552f, -0.00304744113f, -0.00308528473f, -0.00312299770f, -0.00316057657f, -0.00319802039f, -0.00323532545f, + -0.00327249360f, -0.00330952019f, -0.00334640499f, -0.00338314800f, -0.00341974548f, -0.00345619721f, -0.00349249900f, -0.00352865248f, -0.00356465508f, -0.00360050471f, + -0.00363619928f, -0.00367173925f, -0.00370712159f, -0.00374234398f, -0.00377740758f, -0.00381230772f, -0.00384704629f, -0.00388161838f, -0.00391602563f, -0.00395026524f, + -0.00398433534f, -0.00401823409f, -0.00405196147f, -0.00408551469f, -0.00411889283f, -0.00415209495f, -0.00418511964f, -0.00421796506f, -0.00425062841f, -0.00428310968f, + -0.00431540888f, -0.00434752274f, -0.00437944988f, -0.00441119028f, -0.00444274163f, -0.00447410159f, -0.00450527063f, -0.00453624688f, -0.00456702895f, -0.00459761452f, + -0.00462800404f, -0.00465819519f, -0.00468818611f, -0.00471797585f, -0.00474756444f, -0.00477694953f, -0.00480612973f, -0.00483510410f, -0.00486387173f, -0.00489243167f, + -0.00492078019f, -0.00494891917f, -0.00497684628f, -0.00500456011f, -0.00503205974f, -0.00505934376f, -0.00508640893f, -0.00511325803f, -0.00513988826f, -0.00516629638f, + -0.00519248517f, -0.00521845184f, -0.00524419453f, -0.00526971230f, -0.00529500470f, -0.00532007031f, -0.00534490822f, -0.00536951516f, -0.00539389392f, -0.00541804126f, + -0.00544195529f, -0.00546563743f, -0.00548908627f, -0.00551229948f, -0.00553527614f, -0.00555801624f, -0.00558051793f, -0.00560278073f, -0.00562480185f, -0.00564658362f, + -0.00566812325f, -0.00568942074f, -0.00571047375f, -0.00573128276f, -0.00575184450f, -0.00577216130f, -0.00579223130f, -0.00581205264f, -0.00583162485f, -0.00585094653f, + -0.00587001862f, -0.00588883925f, -0.00590740610f, -0.00592572149f, -0.00594378309f, -0.00596158998f, -0.00597914122f, -0.00599643681f, -0.00601347489f, -0.00603025593f, + -0.00604677759f, -0.00606304081f, -0.00607904466f, -0.00609478820f, -0.00611027051f, -0.00612549065f, -0.00614044908f, -0.00615514303f, -0.00616957434f, -0.00618374161f, + -0.00619764347f, -0.00621128036f, -0.00622465089f, -0.00623775553f, -0.00625059241f, -0.00626316015f, -0.00627546106f, -0.00628749281f, -0.00629925542f, -0.00631074747f, + -0.00632197037f, -0.00633292180f, -0.00634360127f, -0.00635400973f, -0.00636414625f, -0.00637400988f, -0.00638360064f, -0.00639291806f, -0.00640196120f, -0.00641073007f, + -0.00641922466f, -0.00642744405f, -0.00643538870f, -0.00644305721f, -0.00645045005f, -0.00645756582f, -0.00646440592f, -0.00647096802f, -0.00647725351f, -0.00648326147f, + -0.00648899190f, -0.00649444433f, -0.00649961829f, -0.00650451379f, -0.00650913082f, -0.00651346892f, -0.00651752809f, -0.00652130833f, -0.00652480870f, -0.00652803015f, + -0.00653097173f, -0.00653363345f, -0.00653601484f, -0.00653811684f, -0.00653993897f, -0.00654148031f, -0.00654274225f, -0.00654372340f, -0.00654442422f, -0.00654484471f +}; +#endif const float Stereo_dmx_s_wnd_coef_16k[L_FRAME16k >> 4] = { 0.00154133327f, 0.0138150426f, 0.0380602330f, 0.0736799166f, 0.119797014f, 0.175276011f, 0.238750681f, 0.308658302f, 0.383277327f, 0.460770488f, diff --git a/lib_enc/ivas_rom_enc.h b/lib_enc/ivas_rom_enc.h index 8bcad95506..2a4f71b8b9 100644 --- a/lib_enc/ivas_rom_enc.h +++ b/lib_enc/ivas_rom_enc.h @@ -120,6 +120,11 @@ extern const uint16_t ECSQ_tab_vals[ECSQ_PARAM_COUNT - 1][1 + ECSQ_TAB_VALS_SIZE * Stereo downmix to EVS ROM tables *----------------------------------------------------------------------------------*/ +#ifndef NTT_REMOVE_EPS_ROM +extern const float Stereo_dmx_s_wnd_coef_eps_16k[L_FRAME16k * 3 / 4]; +extern const float Stereo_dmx_s_wnd_coef_eps_32k[L_FRAME32k * 3 / 4]; +extern const float Stereo_dmx_s_wnd_coef_eps_48k[L_FRAME48k * 3 / 4]; +#endif extern const float Stereo_dmx_s_wnd_coef_16k[L_FRAME16k >> 4]; extern const float Stereo_dmx_s_wnd_coef_32k[L_FRAME32k >> 4]; extern const float Stereo_dmx_s_wnd_coef_48k[L_FRAME48k >> 4]; diff --git a/lib_enc/ivas_sba_enc.c b/lib_enc/ivas_sba_enc.c index 40b502fd70..b267cd2e66 100644 --- a/lib_enc/ivas_sba_enc.c +++ b/lib_enc/ivas_sba_enc.c @@ -45,13 +45,10 @@ #endif #include "wmops.h" -#ifndef HARMONIZE_SBA_NCHAN_TRANSPORT /*-----------------------------------------------------------------------* * Local function prototypes *-----------------------------------------------------------------------*/ - static void ivas_sba_dmx_enc( float sba_data[][L_FRAME48k], const int16_t nchan_transport, const int16_t input_frame ); -#endif /*-------------------------------------------------------------------* * ivas_sba_getTCs() @@ -65,28 +62,18 @@ void ivas_sba_getTCs( const int16_t input_frame /* i : frame length */ ) { - ivas_sba_zero_vert_comp( sba_data, st_ivas->sba_analysis_order, st_ivas->hEncoderConfig->sba_planar, input_frame ); - -#ifdef HARMONIZE_SBA_NCHAN_TRANSPORT - st_ivas->nchan_transport = ivas_get_sba_num_TCs( st_ivas->hEncoderConfig->ivas_total_brate, st_ivas->sba_analysis_order ); - - if ( st_ivas->nchan_transport >= 3 ) - { - /*convert WYZX downmix to WYXZ*/ - int16_t i = 0; - float temp; - for ( i = 0; i < input_frame; i++ ) - { - temp = sba_data[2][i]; - sba_data[2][i] = sba_data[3][i]; - sba_data[3][i] = temp; - } - } - +#ifndef SBA_ORDER_BITSTREAM + ivas_sba_zero_vert_comp( sba_data, st_ivas->hEncoderConfig->sba_order, st_ivas->hEncoderConfig->sba_planar, input_frame ); #else + ivas_sba_zero_vert_comp( sba_data, st_ivas->sba_analysis_order, st_ivas->hEncoderConfig->sba_planar, input_frame ); +#endif if ( st_ivas->sba_mode == SBA_MODE_SPAR ) { +#ifndef SBA_ORDER_BITSTREAM + st_ivas->nchan_transport = ivas_get_spar_num_TCs( st_ivas->hEncoderConfig->ivas_total_brate, st_ivas->hEncoderConfig->sba_order ); +#else st_ivas->nchan_transport = ivas_get_spar_num_TCs( st_ivas->hEncoderConfig->ivas_total_brate, st_ivas->sba_analysis_order ); +#endif if ( st_ivas->nchan_transport >= 3 ) { /*convert WYZX downmix to WYXZ*/ @@ -102,14 +89,13 @@ void ivas_sba_getTCs( } else { - st_ivas->nchan_transport = ivas_dirac_getNumTransportChannels( st_ivas->hEncoderConfig->ivas_total_brate, st_ivas->sba_analysis_order, st_ivas->hEncoderConfig->sba_planar ); -#ifdef HARMONIZE_SBA_NCHAN_TRANSPORT - /* do nothing; simply use omni */ +#ifndef SBA_ORDER_BITSTREAM + st_ivas->nchan_transport = ivas_dirac_getNumTransportChannels( st_ivas->hEncoderConfig->ivas_total_brate, st_ivas->hEncoderConfig->sba_order, st_ivas->hEncoderConfig->sba_planar ); #else - ivas_sba_dmx_enc( sba_data, st_ivas->nchan_transport, input_frame ); + st_ivas->nchan_transport = ivas_dirac_getNumTransportChannels( st_ivas->hEncoderConfig->ivas_total_brate, st_ivas->sba_analysis_order, st_ivas->hEncoderConfig->sba_planar ); #endif + ivas_sba_dmx_enc( sba_data, st_ivas->nchan_transport, input_frame ); } -#endif #ifdef DEBUG_MODE_DIRAC for ( int16_t n = 0; n < st_ivas->nchan_transport; n++ ) @@ -130,7 +116,6 @@ void ivas_sba_getTCs( } -#ifndef HARMONIZE_SBA_NCHAN_TRANSPORT /*-------------------------------------------------------------------* * ivas_sba_dmx_enc() * @@ -229,7 +214,7 @@ static void ivas_sba_dmx_enc( return; } -#endif + /*-------------------------------------------------------------------* * ivas_sba_enc_reconfigure() @@ -264,8 +249,6 @@ ivas_error ivas_sba_enc_reconfigure( nSCE_old = st_ivas->nSCE; ind_list_metadata = NULL; - st_ivas->sba_analysis_order = ivas_sba_get_analysis_order( ivas_total_brate, st_ivas->hEncoderConfig->sba_order ); - ivas_dirac_enc_reconfigure( st_ivas ); ntransport = st_ivas->nchan_transport; diff --git a/lib_enc/ivas_sce_enc.c b/lib_enc/ivas_sce_enc.c index 4a4c24fa4e..942dd14c99 100644 --- a/lib_enc/ivas_sce_enc.c +++ b/lib_enc/ivas_sce_enc.c @@ -199,20 +199,14 @@ ivas_error ivas_sce_enc( * Reset metadata *----------------------------------------------------------------*/ -#ifdef ALIGN_SID_SIZE - reset_metadata_spatial( ivas_format, hSCE->hMetaData, hSCE->element_brate, &st->total_brate, st->core_brate, nb_bits_metadata, st_ivas->sba_mode ); -#else - reset_metadata_spatial( ivas_format, hSCE->hMetaData, hSCE->element_brate, &st->total_brate, st->core_brate, nb_bits_metadata, st_ivas->sba_mode, IVAS_SCE ); -#endif + reset_metadata_spatial( ivas_format, hSCE->hMetaData, hSCE->element_brate, &st->total_brate, st->core_brate, nb_bits_metadata, st_ivas->sba_mode, + IVAS_SCE ); /*----------------------------------------------------------------* * Write IVAS format signaling in SID frames *----------------------------------------------------------------*/ -#ifdef ALIGN_SID_SIZE - if ( st->core_brate == SID_2k40 ) -#else + if ( st->core_brate == SID_2k40 && ( ivas_format != SBA_FORMAT || st_ivas->sba_mode != SBA_MODE_SPAR ) ) -#endif { ivas_write_format_sid( ivas_format, IVAS_SCE, st->hBstr ); } @@ -238,11 +232,13 @@ ivas_error ivas_sce_enc( * Encoder *----------------------------------------------------------------*/ - if ( ( error = ivas_core_enc( hSCE, NULL, NULL, 1, old_inp_12k8, old_inp_16k, Etot, ener, A, Aw, epsP, lsp_new, lsp_mid, vad_hover_flag, attack_flag, realBuffer, imagBuffer, old_wsp, loc_harm, cor_map_sum, vad_flag_dtx, enerBuffer, fft_buff, 0, flag_16k_smc ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_core_enc( hSCE, NULL, NULL, 1, old_inp_12k8, old_inp_16k, Etot, ener, A, Aw, epsP, lsp_new, lsp_mid, vad_hover_flag, attack_flag, realBuffer, imagBuffer, old_wsp, loc_harm, cor_map_sum, vad_flag_dtx, enerBuffer, fft_buff, 0, + flag_16k_smc ) ) != IVAS_ERR_OK ) { return error; } + /*----------------------------------------------------------------* * Common updates *----------------------------------------------------------------*/ diff --git a/lib_enc/ivas_sns_enc.c b/lib_enc/ivas_sns_enc.c index 87019b8d91..1aeac19c57 100644 --- a/lib_enc/ivas_sns_enc.c +++ b/lib_enc/ivas_sns_enc.c @@ -43,7 +43,7 @@ #endif #include "wmops.h" -#ifndef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifndef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT #define SNS_NPTS 16 /* Number of downsampled SNS parameters */ /*------------------------------------------------------------------- diff --git a/lib_enc/ivas_spar_encoder.c b/lib_enc/ivas_spar_encoder.c index 727f4c04cd..03e16833e3 100644 --- a/lib_enc/ivas_spar_encoder.c +++ b/lib_enc/ivas_spar_encoder.c @@ -79,23 +79,26 @@ ivas_error ivas_spar_enc_open( } input_Fs = hEncoderConfig->input_Fs; +#ifndef SBA_ORDER_BITSTREAM + sba_order_internal = min( hEncoderConfig->sba_order, IVAS_MAX_SBA_ORDER ); +#else sba_order_internal = min( st_ivas->sba_analysis_order, IVAS_MAX_SBA_ORDER ); +#endif nchan_inp = ivas_sba_get_nchan_metadata( sba_order_internal ); assert( nchan_inp <= hEncoderConfig->nchan_inp ); ivas_total_brate = hEncoderConfig->ivas_total_brate; - -#ifdef HARMONIZE_SBA_NCHAN_TRANSPORT - nchan_transport = ivas_get_sba_num_TCs( hEncoderConfig->ivas_total_brate, sba_order_internal ); -#else nchan_transport = ivas_get_spar_num_TCs( hEncoderConfig->ivas_total_brate, sba_order_internal ); -#endif // bw = ivas_get_bw_idx_from_sample_rate(pCfg->input_Fs); table_idx = ivas_get_spar_table_idx( ivas_total_brate, sba_order_internal, SPAR_CONFIG_BW, NULL, NULL ); // ivas_set_bitrate_config(&hSpar->hMdEnc->spar_md_cfg, table_idx); /* MD handle */ +#ifndef SBA_ORDER_BITSTREAM + if ( ( error = ivas_spar_md_enc_open( &( hSpar->hMdEnc ), hEncoderConfig ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_spar_md_enc_open( &( hSpar->hMdEnc ), hEncoderConfig, sba_order_internal ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -146,9 +149,12 @@ ivas_error ivas_spar_enc_open( /*-----------------------------------------------------------------* * Configuration - set SPAR high-level parameters *-----------------------------------------------------------------*/ - +#ifdef SBA_ORDER_BITSTREAM ivas_spar_config( hEncoderConfig->ivas_total_brate, min( st_ivas->sba_analysis_order, IVAS_MAX_SBA_ORDER ), &st_ivas->nchan_transport, &st_ivas->nSCE, &st_ivas->nCPE, &hSpar->core_nominal_brate, -1 ); +#else + ivas_spar_config( hEncoderConfig->ivas_total_brate, min( hEncoderConfig->sba_order, IVAS_MAX_SBA_ORDER ), + &st_ivas->nchan_transport, &st_ivas->nSCE, &st_ivas->nCPE, &hSpar->core_nominal_brate, -1 ); #endif if ( st_ivas->nchan_transport == 1 ) @@ -284,6 +290,7 @@ ivas_error ivas_spar_enc( ) { ENCODER_CONFIG_HANDLE hEncoderConfig; + int16_t i, ch; ivas_error error; error = IVAS_ERR_OK; @@ -295,9 +302,22 @@ ivas_error ivas_spar_enc( return error; } + /* normalize input channels */ + for ( ch = 0; ch < hEncoderConfig->nchan_inp; ch++ ) + { + for ( i = 0; i < input_frame; i++ ) + { + data_f[ch][i] *= ( 1.0 / PCM16_TO_FLT_FAC ); + } + } + if ( hEncoderConfig->sba_planar ) { +#ifndef SBA_ORDER_BITSTREAM + ivas_sba_zero_vert_comp( data_f, hEncoderConfig->sba_order, hEncoderConfig->sba_planar, input_frame ); +#else ivas_sba_zero_vert_comp( data_f, st_ivas->sba_analysis_order, hEncoderConfig->sba_planar, input_frame ); +#endif } if ( ( error = ivas_spar_enc_process( st_ivas, hEncoderConfig, hMetaData, st_ivas->hSpar->front_vad_flag, data_f ) ) != IVAS_ERR_OK ) @@ -307,7 +327,11 @@ ivas_error ivas_spar_enc( if ( hEncoderConfig->sba_planar ) { +#ifndef SBA_ORDER_BITSTREAM + ivas_sba_zero_vert_comp( data_f, hEncoderConfig->sba_order, hEncoderConfig->sba_planar, input_frame ); // TODO tmu: do we need a second call to this function ? +#else ivas_sba_zero_vert_comp( data_f, st_ivas->sba_analysis_order, hEncoderConfig->sba_planar, input_frame ); // TODO tmu: do we need a second call to this function ? +#endif } *nb_bits_metadata = hMetaData->nb_bits_tot; @@ -433,7 +457,11 @@ static ivas_error ivas_spar_enc_process( num_del_samples = hSpar->hFbMixer->fb_cfg->fb_latency; input_frame = (int16_t) ( input_Fs / FRAMES_PER_SEC ); +#ifndef SBA_ORDER_BITSTREAM + sba_order = min( hEncoderConfig->sba_order, IVAS_MAX_SBA_ORDER ); +#else sba_order = min( st_ivas->sba_analysis_order, IVAS_MAX_SBA_ORDER ); +#endif nchan_inp = ivas_sba_get_nchan_metadata( sba_order ); assert( nchan_inp <= hEncoderConfig->nchan_inp ); @@ -533,7 +561,7 @@ static ivas_error ivas_spar_enc_process( set_zero( avg_dir, 3 ); energySum = 0.0f; - /* combine all DirAC bands except the last one, handle last band separately, last band covers BW above WB */ + /*combine all dirac bands except the last one, handle last band separately, last band covers BW above WB*/ for ( j = 0; j < orig_dirac_bands - 1; j++ ) { ivas_qmetadata_azimuth_elevation_to_direction_vector( hQMetaData->q_direction[0].band_data[j].azimuth[i], hQMetaData->q_direction[0].band_data[j].elevation[i], &dir[0] ); @@ -603,7 +631,7 @@ static ivas_error ivas_spar_enc_process( /* use just VAD function to get VAD flags */ dtx_vad = ( hEncoderConfig->Opt_DTX_ON == 1 ) ? front_vad_flag : 1; dtx_cov_flag = ( dtx_vad == 1 ) ? 0 : 1; - dtx_silence_mode = 0; // VE2DB: this variable is always 0 - please review or remove it + dtx_silence_mode = 0; bwidth = ivas_get_bw_idx_from_sample_rate( input_Fs ); bwidth = min( bwidth, hEncoderConfig->max_bwidth ); @@ -672,9 +700,12 @@ static ivas_error ivas_spar_enc_process( md_in_buf.num_bands = min( md_in_buf.num_bands, SPAR_DIRAC_SPLIT_START_BAND ); md_in_buf.dtx_vad = dtx_vad; +#ifndef SBA_ORDER_BITSTREAM + ivas_spar_md_enc_process( hSpar->hMdEnc, hEncoderConfig, &md_in_buf, hMetaData, dtx_silence_mode ); +#else ivas_spar_md_enc_process( hSpar->hMdEnc, hEncoderConfig, &md_in_buf, hMetaData, dtx_silence_mode, sba_order ); - - if ( st_ivas->sba_mode == SBA_MODE_SPAR ) // VE2DB: this looks obsolete +#endif + if ( st_ivas->sba_mode == SBA_MODE_SPAR ) { float azi_dirac[IVAS_MAX_NUM_BANDS][MAX_PARAM_SPATIAL_SUBFRAMES]; float ele_dirac[IVAS_MAX_NUM_BANDS][MAX_PARAM_SPATIAL_SUBFRAMES]; @@ -875,13 +906,16 @@ static ivas_error ivas_spar_enc_process( order = remix_order_set[hSpar->hMdEnc->spar_md_cfg.remix_unmix_order]; - for ( j = 0; j < nchan_transport; j++ ) - { - mvr2r( p_pcm_tmp[j], data_f[order[j]], input_frame ); - } - for ( ; j < IVAS_SPAR_MAX_DMX_CHS; j++ ) + for ( i = 0; i < input_frame; i++ ) { - set_f( data_f[order[j]], 0.0f, input_frame ); + for ( j = 0; j < nchan_transport; j++ ) + { + data_f[order[j]][i] = p_pcm_tmp[j][i] * PCM16_TO_FLT_FAC; + } + for ( ; j < IVAS_SPAR_MAX_DMX_CHS; j++ ) + { + data_f[order[j]][i] = 0; + } } wmops_sub_end(); diff --git a/lib_enc/ivas_spar_md_enc.c b/lib_enc/ivas_spar_md_enc.c index ed0d3f7e7e..dc7c3677dd 100644 --- a/lib_enc/ivas_spar_md_enc.c +++ b/lib_enc/ivas_spar_md_enc.c @@ -72,11 +72,11 @@ static void ivas_band_mixer( float *cov_re[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], static void ivas_get_band_differential_index( ivas_band_coeffs_ind_t *pBand_idx, const int16_t q_levels[2], const int16_t one_sided, const int16_t nB, const int16_t complex_cov, const int16_t dim, const ivas_coeffs_type_t coeff_type ); -static void ivas_get_huffman_coded_bs( ivas_spar_md_enc_state_t *hMdEnc, BSTR_ENC_HANDLE hMetaData, const int16_t nB, const int16_t qsi, const int16_t planarCP ); +static void ivas_get_huffman_coded_bs( ivas_spar_md_enc_state_t *pState, BSTR_ENC_HANDLE hMetaData, const int16_t nB, const int16_t qsi, const int16_t planarCP ); -static void ivas_get_arith_coded_bs( ivas_spar_md_enc_state_t *hMdEnc, BSTR_ENC_HANDLE hMetaData, const int16_t *pDo_diff, const int16_t bands_bw, const int16_t nB, const int16_t qsi, const int16_t planarCP ); +static void ivas_get_arith_coded_bs( ivas_spar_md_enc_state_t *pState, BSTR_ENC_HANDLE hMetaData, const int16_t *pDo_diff, const int16_t bands_bw, const int16_t nB, const int16_t qsi, const int16_t planarCP ); -static ivas_error ivas_spar_set_enc_config( ivas_spar_md_enc_state_t *hMdEnc, int16_t *max_freq_per_chan, const int16_t nchan_transport, float *pFC, const int16_t nchan_inp ); +static ivas_error ivas_spar_set_enc_config( ivas_spar_md_enc_state_t *pState, int16_t *max_freq_per_chan, const int16_t nchan_transport, float *pFC, const int16_t nchan_inp ); static void ivas_select_next_strat( ivas_strats_t prior_strat, ivas_strats_t cs[MAX_QUANT_STRATS], const int16_t dmx_switch, const int16_t dtx_vad ); @@ -84,9 +84,17 @@ static void ivas_store_prior_coeffs( ivas_spar_md_enc_state_t *hMdEnc, const int static void ivas_write_parameter_bitstream( ivas_spar_md_enc_state_t *hMdEnc, const int16_t nB, const int16_t bands_bw, BSTR_ENC_HANDLE hMetaData, const int32_t ivas_total_brate, const int16_t dtx_silence_mode, const int16_t strat, const int16_t qsi, const int16_t planarCP ); -static ivas_error ivas_spar_md_enc_init( ivas_spar_md_enc_state_t *hMdEnc, const ENCODER_CONFIG_HANDLE hEncoderConfig, const int16_t sba_order ); -static void ivas_spar_quant_pred_coeffs_dtx( ivas_spar_md_t *pSpar_md, const float *pValues, const int16_t ndm, int16_t *pIndex, const int16_t dim1, float *pQuant ); -static void ivas_quant_p_per_band_dtx( float *pP_mat, const int16_t num_dec, const int16_t num_dmx, int16_t *ppIdx_pd, float *pP_out, const int16_t num_ch ); +static ivas_error ivas_spar_md_enc_init( ivas_spar_md_enc_state_t *pState, const ENCODER_CONFIG_HANDLE hEncoderConfig +#ifdef SBA_ORDER_BITSTREAM + , + int16_t sba_order +#endif +); + +static void ivas_spar_quant_pred_coeffs_dtx( ivas_spar_md_t *pSpar_md, float **ppValues, const int16_t ndm, int16_t **ppIndex, const int16_t dim1, float **ppQuant ); + +static void ivas_quant_p_per_band_dtx( float **ppP_mat, const int16_t num_dec, const int16_t num_dmx, int16_t *ppIdx_pd, float **ppP_out, const int16_t num_ch ); + static void ivas_write_parameter_bitstream_dtx( ivas_spar_md_t *pSpar_md, BSTR_ENC_HANDLE hMetaData, int16_t *num_dmx, int16_t *num_dec, const int16_t num_bands ); static void ivas_quant_p_per_band( ivas_band_coeffs_t *pband_coeffs, ivas_band_coeffs_ind_t *pBand_coeffs_idx, ivas_quant_strat_t *pQs, const int16_t num_ch ); @@ -103,24 +111,35 @@ static void ivas_quant_pred_coeffs_per_band( ivas_band_coeffs_t *pband_coeffs, i *------------------------------------------------------------------------*/ ivas_error ivas_spar_md_enc_open( - ivas_spar_md_enc_state_t **hMdEnc_in, /* i/o: SPAR MD encoder handle */ - const ENCODER_CONFIG_HANDLE hEncoderConfig, /* i : configuration structure */ - const int16_t sba_order /* i : Ambisonic (SBA) order */ + ivas_spar_md_enc_state_t **hMdEnc_in, /* i/o: SPAR MD encoder handle */ + const ENCODER_CONFIG_HANDLE hEncoderConfig /* i : configuration structure */ +#ifdef SBA_ORDER_BITSTREAM + , + int16_t sba_order +#endif ) { ivas_spar_md_enc_state_t *hMdEnc; ivas_error error; +#ifndef SBA_ORDER_BITSTREAM + int16_t num_channels, i, j, order; +#else int16_t num_channels, i, j; - +#endif +#ifndef SBA_ORDER_BITSTREAM + order = min( hEncoderConfig->sba_order, IVAS_MAX_SBA_ORDER ); +#endif error = IVAS_ERR_OK; if ( ( hMdEnc = (ivas_spar_md_enc_state_t *) count_malloc( sizeof( ivas_spar_md_enc_state_t ) ) ) == NULL ) { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR MD encoder" ); } - +#ifndef SBA_ORDER_BITSTREAM + num_channels = 2 * order + 2; +#else num_channels = 2 * sba_order + 2; - +#endif if ( ( hMdEnc->spar_md.band_coeffs = (ivas_band_coeffs_t *) count_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" ); @@ -200,8 +219,11 @@ ivas_error ivas_spar_md_enc_open( } } } - +#ifndef SBA_ORDER_BITSTREAM + if ( ( error = ivas_spar_md_enc_init( hMdEnc, hEncoderConfig ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_spar_md_enc_init( hMdEnc, hEncoderConfig, sba_order ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -301,26 +323,34 @@ void ivas_spar_md_enc_close( /*-----------------------------------------------------------------------------------------* * Function ivas_spar_md_enc_init() * - * SPAR MD encoder initialization + * Init call for md gen process *-----------------------------------------------------------------------------------------*/ static ivas_error ivas_spar_md_enc_init( - ivas_spar_md_enc_state_t *hMdEnc, /* o : MD encoder handle */ - const ENCODER_CONFIG_HANDLE hEncoderConfig, /* i : configuration structure */ - const int16_t sba_order /* i : Ambisonic (SBA) order */ + ivas_spar_md_enc_state_t *pState, /* o : MD encoder handle */ + const ENCODER_CONFIG_HANDLE hEncoderConfig /* i : configuration structure */ +#ifdef SBA_ORDER_BITSTREAM + , + int16_t sba_order +#endif ) { float pFC[IVAS_MAX_NUM_BANDS]; int16_t table_idx; float PR_minmax[2]; +#ifndef SBA_ORDER_BITSTREAM + int16_t sba_order; +#endif int16_t num_channels, i, j, k; - +#ifndef SBA_ORDER_BITSTREAM + sba_order = min( hEncoderConfig->sba_order, IVAS_MAX_SBA_ORDER ); +#endif num_channels = ivas_sba_get_nchan_metadata( sba_order ); table_idx = ivas_get_spar_table_idx( hEncoderConfig->ivas_total_brate, sba_order, SPAR_CONFIG_BW, NULL, NULL ); - hMdEnc->spar_md_cfg.gen_bs = 1; - ivas_spar_set_bitrate_config( &hMdEnc->spar_md_cfg, table_idx, SPAR_DIRAC_SPLIT_START_BAND ); + pState->spar_md_cfg.gen_bs = 1; + ivas_spar_set_bitrate_config( &pState->spar_md_cfg, table_idx, SPAR_DIRAC_SPLIT_START_BAND ); /* get FB coefficients */ for ( i = 0; i < IVAS_MAX_NUM_BANDS; i++ ) @@ -328,39 +358,39 @@ static ivas_error ivas_spar_md_enc_init( pFC[i] = ivas_fb_fcs_12band_1ms[i] * hEncoderConfig->input_Fs * 0.5f; } - ivas_spar_set_enc_config( hMdEnc, hMdEnc->spar_md_cfg.max_freq_per_chan, hMdEnc->spar_md_cfg.nchan_transport, pFC, num_channels ); + ivas_spar_set_enc_config( pState, pState->spar_md_cfg.max_freq_per_chan, pState->spar_md_cfg.nchan_transport, pFC, num_channels ); /* - if(hMdEnc->spar_md_cfg.quant_strat[0].C.q_levels[0] == 0 || hMdEnc->spar_md_cfg.quant_strat[0].C.q_levels[1] == 0 - || hMdEnc->spar_md_cfg.quant_strat[0].PR.q_levels[0] == 0 || hMdEnc->spar_md_cfg.quant_strat[0].PR.q_levels[1] == 0 - || hMdEnc->spar_md_cfg.quant_strat[0].P_c.q_levels[0] == 0 || hMdEnc->spar_md_cfg.quant_strat[0].P_c.q_levels[1] == 0 - || hMdEnc->spar_md_cfg.quant_strat[0].P_r.q_levels[0] == 0 || hMdEnc->spar_md_cfg.quant_strat[0].P_r.q_levels[1] == 0) + if(pState->spar_md_cfg.quant_strat[0].C.q_levels[0] == 0 || pState->spar_md_cfg.quant_strat[0].C.q_levels[1] == 0 + || pState->spar_md_cfg.quant_strat[0].PR.q_levels[0] == 0 || pState->spar_md_cfg.quant_strat[0].PR.q_levels[1] == 0 + || pState->spar_md_cfg.quant_strat[0].P_c.q_levels[0] == 0 || pState->spar_md_cfg.quant_strat[0].P_c.q_levels[1] == 0 + || pState->spar_md_cfg.quant_strat[0].P_r.q_levels[0] == 0 || pState->spar_md_cfg.quant_strat[0].P_r.q_levels[1] == 0) { - hMdEnc->spar_md_cfg.gen_bs = 0; + pState->spar_md_cfg.gen_bs = 0; } - else if(0 != hMdEnc->spar_md_cfg.gen_bs) + else if(0 != pState->spar_md_cfg.gen_bs) { - hMdEnc->spar_md_cfg.quant_strat_bits = ivas_get_bits_to_encode(MAX_QUANT_STRATS); + pState->spar_md_cfg.quant_strat_bits = ivas_get_bits_to_encode(MAX_QUANT_STRATS); } */ - if ( hMdEnc->spar_md_cfg.nchan_transport != 2 && ( ( hMdEnc->spar_md_cfg.remix_unmix_order == 1 ) || ( hMdEnc->spar_md_cfg.remix_unmix_order == 2 ) ) ) + if ( pState->spar_md_cfg.nchan_transport != 2 && ( ( pState->spar_md_cfg.remix_unmix_order == 1 ) || ( pState->spar_md_cfg.remix_unmix_order == 2 ) ) ) { return IVAS_ERR_INTERNAL; } - ivas_spar_arith_coeffs_com_init( &hMdEnc->arith_coeffs, &hMdEnc->spar_md_cfg, table_idx, ENC ); - ivas_spar_huff_coeffs_com_init( &hMdEnc->huff_coeffs, NULL, table_idx, ENC ); + ivas_spar_arith_coeffs_com_init( &pState->arith_coeffs, &pState->spar_md_cfg, table_idx, ENC ); + ivas_spar_huff_coeffs_com_init( &pState->huff_coeffs, NULL, table_idx, ENC ); if ( hEncoderConfig->Opt_DTX_ON == 1 ) { /* DTX quant init */ - PR_minmax[0] = hMdEnc->spar_md_cfg.quant_strat[0].PR.min; - PR_minmax[1] = hMdEnc->spar_md_cfg.quant_strat[0].PR.max; - ivas_spar_quant_dtx_init( &hMdEnc->spar_md, PR_minmax ); + PR_minmax[0] = pState->spar_md_cfg.quant_strat[0].PR.min; + PR_minmax[1] = pState->spar_md_cfg.quant_strat[0].PR.max; + ivas_spar_quant_dtx_init( &pState->spar_md, PR_minmax ); } - hMdEnc->spar_md_cfg.prior_strat = START; - hMdEnc->spar_md_cfg.prev_quant_idx = -1; + pState->spar_md_cfg.prior_strat = START; + pState->spar_md_cfg.prev_quant_idx = -1; for ( i = 0; i < num_channels; i++ ) { @@ -368,7 +398,7 @@ static ivas_error ivas_spar_md_enc_init( { for ( k = 0; k < IVAS_MAX_NUM_BANDS; k++ ) { - hMdEnc->mixer_mat[i][j][k] = 0; + pState->mixer_mat[i][j][k] = 0; } } } @@ -379,16 +409,16 @@ static ivas_error ivas_spar_md_enc_init( { for ( k = 0; k < IVAS_MAX_NUM_BANDS; k++ ) { - hMdEnc->cov_real[i][j][k] = 0; - hMdEnc->cov_dtx_real[i][j][k] = 0; + pState->cov_real[i][j][k] = 0; + pState->cov_dtx_real[i][j][k] = 0; } } } - ivas_clear_band_coeffs( hMdEnc->spar_md.band_coeffs, IVAS_MAX_NUM_BANDS ); - ivas_clear_band_coeff_idx( hMdEnc->spar_md.band_coeffs_idx, IVAS_MAX_NUM_BANDS ); - ivas_clear_band_coeff_idx( hMdEnc->spar_md_prior.band_coeffs_idx, IVAS_MAX_NUM_BANDS ); - ivas_clear_band_coeff_idx( hMdEnc->spar_md_prior.band_coeffs_idx_mapped, IVAS_MAX_NUM_BANDS ); + ivas_clear_band_coeffs( pState->spar_md.band_coeffs, IVAS_MAX_NUM_BANDS ); + ivas_clear_band_coeff_idx( pState->spar_md.band_coeffs_idx, IVAS_MAX_NUM_BANDS ); + ivas_clear_band_coeff_idx( pState->spar_md_prior.band_coeffs_idx, IVAS_MAX_NUM_BANDS ); + ivas_clear_band_coeff_idx( pState->spar_md_prior.band_coeffs_idx_mapped, IVAS_MAX_NUM_BANDS ); return IVAS_ERR_OK; } @@ -397,11 +427,11 @@ static ivas_error ivas_spar_md_enc_init( /*-----------------------------------------------------------------------------------------* * Function ivas_spar_set_enc_config() * - * Set configuration for SPAR MD encoder + * Set configuration for SPAR MD gen *-----------------------------------------------------------------------------------------*/ static ivas_error ivas_spar_set_enc_config( - ivas_spar_md_enc_state_t *hMdEnc, + ivas_spar_md_enc_state_t *pState, int16_t *max_freq_per_chan, const int16_t nchan_transport, float *pFC, @@ -414,29 +444,29 @@ static ivas_error ivas_spar_set_enc_config( { if ( max_freq_per_chan != NULL ) { - hMdEnc->spar_md_cfg.max_freq_per_chan[i] = ( max_freq_per_chan[i] != 0 ) ? max_freq_per_chan[i] : max_freq_per_chan[0]; + pState->spar_md_cfg.max_freq_per_chan[i] = ( max_freq_per_chan[i] != 0 ) ? max_freq_per_chan[i] : max_freq_per_chan[0]; } else { - hMdEnc->spar_md_cfg.max_freq_per_chan[i] = IVAS_SPAR_FOA_DFLT_FREQ_PER_CHAN; + pState->spar_md_cfg.max_freq_per_chan[i] = IVAS_SPAR_FOA_DFLT_FREQ_PER_CHAN; } } - hMdEnc->num_umx_ch = nchan_inp; - hMdEnc->num_decorr = nchan_inp - 1; + pState->num_umx_ch = nchan_inp; + pState->num_decorr = nchan_inp - 1; for ( i = 0; i < IVAS_MAX_NUM_BANDS; i++ ) { tmp_dmx_ch = 0; for ( j = 0; j < nchan_transport; j++ ) { - if ( pFC[i] < hMdEnc->spar_md_cfg.max_freq_per_chan[j] ) + if ( pFC[i] < pState->spar_md_cfg.max_freq_per_chan[j] ) { tmp_dmx_ch += 1; } } - hMdEnc->spar_md_cfg.num_dmx_chans_per_band[i] = tmp_dmx_ch; - hMdEnc->spar_md_cfg.num_decorr_per_band[i] = hMdEnc->num_umx_ch - tmp_dmx_ch; + pState->spar_md_cfg.num_dmx_chans_per_band[i] = tmp_dmx_ch; + pState->spar_md_cfg.num_decorr_per_band[i] = pState->num_umx_ch - tmp_dmx_ch; } return IVAS_ERR_OK; @@ -553,19 +583,26 @@ ivas_error ivas_spar_md_enc_process( ivas_spar_md_enc_state_t *hMdEnc, /* i/o: SPAR MD encoder handle */ const ENCODER_CONFIG_HANDLE hEncoderConfig, /* i : configuration structure */ ivas_spar_md_enc_in_buf_t *pIn_buf, - BSTR_ENC_HANDLE hMetaData, /* i/o: MetaData handle */ - const int16_t dtx_silence_mode, - const int16_t sba_order /* i : Ambisonic (SBA) order */ + BSTR_ENC_HANDLE hMetaData, /* i/o: MetaData handle */ + const int16_t dtx_silence_mode +#ifdef SBA_ORDER_BITSTREAM + , + int16_t sba_order +#endif ) { float pred_coeffs_re[IVAS_SPAR_MAX_CH - 1][IVAS_MAX_NUM_BANDS]; float dm_fv_re[IVAS_SPAR_MAX_CH - 1][IVAS_MAX_NUM_BANDS]; - int16_t i, b, qsi, ndm, ndec, num_ch, num_quant_strats; + int16_t i, b, qsi, ndm, ndec, num_ch; int16_t j, planarCP; int16_t num_bands = pIn_buf->num_bands; int16_t dtx_vad = pIn_buf->dtx_vad; +#ifndef SBA_ORDER_BITSTREAM + int16_t active_w, nchan_transport, dmx_switch, strat, sba_order; +#else int16_t active_w, nchan_transport, dmx_switch, strat; +#endif int16_t nB, bands_bw, packed_ok = 0; ivas_strats_t cs[MAX_CODING_STRATS]; int16_t code_strat; @@ -573,11 +610,14 @@ ivas_error ivas_spar_md_enc_process( BSTR_ENC_DATA hMetaData_tmp; Indice ind_list_tmp[MAX_BITS_METADATA]; // IVAS_fmToDo: size to be optimized float Wscale[IVAS_MAX_NUM_BANDS]; - - num_quant_strats = hMdEnc->spar_md_cfg.num_quant_strats; + ivas_spar_md_enc_state_t *pState = hMdEnc; + int16_t num_quant_strats = pState->spar_md_cfg.num_quant_strats; +#ifndef SBA_ORDER_BITSTREAM + sba_order = min( hEncoderConfig->sba_order, IVAS_MAX_SBA_ORDER ); +#endif num_ch = ivas_sba_get_nchan_metadata( sba_order ); - active_w = hMdEnc->spar_md_cfg.active_w; - nchan_transport = hMdEnc->spar_md_cfg.nchan_transport; + active_w = pState->spar_md_cfg.active_w; + nchan_transport = pState->spar_md_cfg.nchan_transport; if ( hEncoderConfig->ivas_total_brate == BRATE_SPAR_Q_STRAT && sba_order == 1 ) { @@ -612,8 +652,8 @@ ivas_error ivas_spar_md_enc_process( bands_bw = 1; } - ivas_compute_spar_params( pIn_buf->cov_real, dm_fv_re, 0, hMdEnc->mixer_mat, 0, nB, dtx_vad, num_ch, - bands_bw, active_w, &hMdEnc->spar_md_cfg, &hMdEnc->spar_md, Wscale, 0 ); + ivas_compute_spar_params( pIn_buf->cov_real, dm_fv_re, 0, pState->mixer_mat, 0, nB, dtx_vad, num_ch, + bands_bw, active_w, &pState->spar_md_cfg, &pState->spar_md, Wscale, 0 ); for ( i = 0; i < num_ch; i++ ) { @@ -621,7 +661,7 @@ ivas_error ivas_spar_md_enc_process( { for ( b = 0; b < num_bands; b++ ) { - hMdEnc->mixer_mat_local[i][j][b] = hMdEnc->mixer_mat[i][j][b]; + hMdEnc->mixer_mat_local[i][j][b] = pState->mixer_mat[i][j][b]; } } } @@ -640,7 +680,7 @@ ivas_error ivas_spar_md_enc_process( #ifdef SPAR_HOA_DBG fprintf( stdout, "qsi = %d\n", qsi ); #endif - if ( qsi == 2 && ivas_spar_br_table_consts[hMdEnc->table_idx].usePlanarCoeff ) + if ( qsi == 2 && ivas_spar_br_table_consts[pState->table_idx].usePlanarCoeff ) { planarCP = 1; #ifdef SPAR_HOA_DBG @@ -656,18 +696,18 @@ ivas_error ivas_spar_md_enc_process( { for ( b = 0; b < num_bands; b++ ) { - ndm = hMdEnc->spar_md_cfg.num_dmx_chans_per_band[b * bands_bw]; + ndm = pState->spar_md_cfg.num_dmx_chans_per_band[b * bands_bw]; if ( ndm != num_ch ) { - ivas_calc_c_p_coeffs( &hMdEnc->spar_md, pIn_buf->cov_real, 0, hMdEnc->mixer_mat_local, num_ch, ndm, b, dtx_vad, 1, planarCP ); + ivas_calc_c_p_coeffs( &pState->spar_md, pIn_buf->cov_real, 0, hMdEnc->mixer_mat_local, num_ch, ndm, b, dtx_vad, 1, planarCP ); } } } for ( b = 0; b < num_bands; b++ ) { - ndm = hMdEnc->spar_md_cfg.num_dmx_chans_per_band[b * bands_bw]; - ndec = hMdEnc->spar_md_cfg.num_decorr_per_band[b * bands_bw]; + ndm = pState->spar_md_cfg.num_dmx_chans_per_band[b * bands_bw]; + ndec = pState->spar_md_cfg.num_decorr_per_band[b * bands_bw]; if ( dtx_vad == 1 ) { @@ -678,11 +718,11 @@ ivas_error ivas_spar_md_enc_process( for (i = 0; i < ndec; i++) { - for (j = 0; j < ndec; j++) - { - fprintf(stderr, "%f, ", hMdEnc->spar_md.band_coeffs[b].P_re[i][j]);//, hMdEnc->spar_md.band_coeffs[b].P_im[i][j]); - } - fprintf(stderr, "\n"); + for (j = 0; j < ndec; j++) + { + fprintf(stderr, "%f, ", hMdEnc->spar_md.band_coeffs[b].P_re[i][j]);//, hMdEnc->spar_md.band_coeffs[b].P_im[i][j]); + } + fprintf(stderr, "\n"); } fprintf(stderr, "\n\n"); */ #endif @@ -701,33 +741,56 @@ ivas_error ivas_spar_md_enc_process( /*fprintf(stderr, "\n\n Planar P coefficients: band %d\n", b); for (i = 0; i < ndec; i++) { - for (j = 0; j < ndec; j++) - { - fprintf(stderr, "%f, ", hMdEnc->spar_md.band_coeffs[b].P_re[i][j]); //, hMdEnc->spar_md.band_coeffs[b].C_im[i][j]); - } - fprintf(stderr, "\n"); + for (j = 0; j < ndec; j++) + { + fprintf(stderr, "%f, ", hMdEnc->spar_md.band_coeffs[b].P_re[i][j]); //, hMdEnc->spar_md.band_coeffs[b].C_im[i][j]); + } + fprintf(stderr, "\n"); } fprintf(stderr, "\n\n"); */ #endif } - ivas_quant_p_per_band( &hMdEnc->spar_md.band_coeffs[b], &hMdEnc->spar_md.band_coeffs_idx[b], &hMdEnc->spar_md_cfg.quant_strat[qsi], num_ch ); + ivas_quant_p_per_band( &pState->spar_md.band_coeffs[b], &pState->spar_md.band_coeffs_idx[b], &pState->spar_md_cfg.quant_strat[qsi], num_ch ); } - ivas_quant_pred_coeffs_per_band( &hMdEnc->spar_md.band_coeffs[b], &hMdEnc->spar_md.band_coeffs_idx[b], &hMdEnc->spar_md_cfg.quant_strat[qsi], num_ch ); + ivas_quant_pred_coeffs_per_band( &pState->spar_md.band_coeffs[b], &pState->spar_md.band_coeffs_idx[b], &pState->spar_md_cfg.quant_strat[qsi], num_ch ); } else { + float **ppPred_re, **ppPred_quant, *pPred_re, *pPred_quant; + int16_t **ppPred_idx, *pPred_re_idx; if ( ndm != num_ch ) { - ivas_quant_p_per_band_dtx( hMdEnc->spar_md.band_coeffs[b].P_re, ndec, ndm, &hMdEnc->spar_md.band_coeffs_idx[b].decd_index_re[0], hMdEnc->spar_md.band_coeffs[b].P_quant_re, num_ch ); + float *P_re[IVAS_SPAR_MAX_CH - 1], *P_re_quant[IVAS_SPAR_MAX_CH - 1]; + float **ppP_re = (float **) &P_re[0]; + float **ppP_re_quant = (float **) &P_re_quant[0]; + int16_t *ppP_idx = &pState->spar_md.band_coeffs_idx[b].decd_index_re[0]; + + for ( i = 0; i < ndec; i++ ) + { + ppP_re[i] = pState->spar_md.band_coeffs[b].P_re; + ppP_re_quant[i] = pState->spar_md.band_coeffs[b].P_quant_re; + } + + ivas_quant_p_per_band_dtx( ppP_re, ndec, ndm, ppP_idx, ppP_re_quant, num_ch ); } + + ppPred_idx = (int16_t **) &pPred_re_idx; + ppPred_re = (float **) &pPred_re; + ppPred_quant = (float **) &pPred_quant; + + ppPred_re[0] = pState->spar_md.band_coeffs[b].pred_re; + ppPred_idx[0] = pState->spar_md.band_coeffs_idx[b].pred_index_re; + ppPred_quant[0] = pState->spar_md.band_coeffs[b].pred_quant_re; + for ( i = 0; i < num_ch - 1; i++ ) { - hMdEnc->spar_md.band_coeffs[b].pred_quant_re[i] = 0; + pState->spar_md.band_coeffs[b].pred_quant_re[i] = 0; } - ivas_spar_quant_pred_coeffs_dtx( &hMdEnc->spar_md, hMdEnc->spar_md.band_coeffs[b].pred_re, ndm, hMdEnc->spar_md.band_coeffs_idx[b].pred_index_re, num_ch - 1, hMdEnc->spar_md.band_coeffs[b].pred_quant_re ); + + ivas_spar_quant_pred_coeffs_dtx( &pState->spar_md, ppPred_re, ndm, ppPred_idx, num_ch - 1, ppPred_quant ); } } @@ -735,35 +798,35 @@ ivas_error ivas_spar_md_enc_process( { for ( b = 0; b < num_bands; b++ ) { - pred_coeffs_re[i][b] = Wscale[b] * hMdEnc->spar_md.band_coeffs[b].pred_quant_re[i]; + pred_coeffs_re[i][b] = Wscale[b] * pState->spar_md.band_coeffs[b].pred_quant_re[i]; } } - ivas_create_fullr_dmx_mat( pred_coeffs_re, dm_fv_re, hMdEnc->mixer_mat, num_ch, 0, num_bands, active_w, &hMdEnc->spar_md_cfg ); + ivas_create_fullr_dmx_mat( pred_coeffs_re, dm_fv_re, pState->mixer_mat, num_ch, 0, num_bands, active_w, &pState->spar_md_cfg ); for ( b = 0; b < num_bands; b++ ) { - ndm = hMdEnc->spar_md_cfg.num_dmx_chans_per_band[b * bands_bw]; - ndec = hMdEnc->spar_md_cfg.num_decorr_per_band[b * bands_bw]; + ndm = pState->spar_md_cfg.num_dmx_chans_per_band[b * bands_bw]; + ndec = pState->spar_md_cfg.num_decorr_per_band[b * bands_bw]; for ( i = 0; i < num_ch; i++ ) { - hMdEnc->mixer_mat[0][i][b] *= Wscale[b]; + pState->mixer_mat[0][i][b] *= Wscale[b]; } if ( ( ndm != num_ch ) && ( ndm != 1 ) ) { - ivas_calc_c_p_coeffs( &hMdEnc->spar_md, pIn_buf->cov_real, 0, hMdEnc->mixer_mat, num_ch, ndm, b, dtx_vad, 0, planarCP ); + ivas_calc_c_p_coeffs( &pState->spar_md, pIn_buf->cov_real, 0, pState->mixer_mat, num_ch, ndm, b, dtx_vad, 0, planarCP ); #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"); + for (j = 0; j < ndm - 1; j++) + { + fprintf(stderr, "%f, ", pState->spar_md.band_coeffs[b].C_re[i][j]); + } + fprintf(stderr, "\n"); } fprintf(stderr, "\n\n"); */ #endif @@ -775,7 +838,7 @@ ivas_error ivas_spar_md_enc_process( { for ( j = 0; j < ndm - 1; j++ ) { - hMdEnc->spar_md.band_coeffs[b].C_re[i][j] = 0.0f; + pState->spar_md.band_coeffs[b].C_re[i][j] = 0.0f; } } } @@ -784,24 +847,24 @@ ivas_error ivas_spar_md_enc_process( 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]); // , hMdEnc->spar_md.band_coeffs[band_idx].C_im[i][j]); - } - fprintf(stderr, "\n"); + for (j = 0; j < ndm - 1; j++) + { + fprintf(stderr, "%f, ", pState->spar_md.band_coeffs[b].C_re[i][j]); // , pState->spar_md.band_coeffs[band_idx].C_im[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 ); + ivas_quant_c_per_band( &pState->spar_md.band_coeffs[b], &pState->spar_md.band_coeffs_idx[b], + &pState->spar_md_cfg.quant_strat[qsi], ndec, ndm ); #ifdef SPAR_HOA_DBG /*fprintf(stderr, "\n\n quantised C indexes: band %d\n", b); for (i = 0; i < ndec * (ndm-1); i++) { - fprintf(stderr, "%d, ", hMdEnc->spar_md.band_coeffs_idx[b].drct_index_re[i]); + fprintf(stderr, "%d, ", pState->spar_md.band_coeffs_idx[b].drct_index_re[i]); } fprintf(stderr, "\n\n");*/ #endif @@ -809,26 +872,26 @@ ivas_error ivas_spar_md_enc_process( } /* band limit downmix matrix */ - ivas_band_limit_dmx_matrix( hMdEnc, num_ch, num_bands, bands_bw ); + ivas_band_limit_dmx_matrix( pState, num_ch, num_bands, bands_bw ); /* band mixing */ if ( bands_bw > 1 ) { - ivas_band_mixing( hMdEnc, num_ch, num_bands, nchan_transport, pIn_buf->num_bands ); + ivas_band_mixing( pState, num_ch, num_bands, nchan_transport, pIn_buf->num_bands ); } - if ( hMdEnc->spar_md_cfg.gen_bs == 0 ) + if ( pState->spar_md_cfg.gen_bs == 0 ) { break; } if ( dtx_vad == 0 ) { - ivas_write_parameter_bitstream_dtx( &hMdEnc->spar_md, hMetaData, hMdEnc->spar_md_cfg.num_dmx_chans_per_band, hMdEnc->spar_md_cfg.num_decorr_per_band, num_bands ); + ivas_write_parameter_bitstream_dtx( &pState->spar_md, hMetaData, pState->spar_md_cfg.num_dmx_chans_per_band, pState->spar_md_cfg.num_decorr_per_band, num_bands ); break; } - ivas_select_next_strat( hMdEnc->spar_md_cfg.prior_strat, cs, dmx_switch, dtx_vad ); + ivas_select_next_strat( pState->spar_md_cfg.prior_strat, cs, dmx_switch, dtx_vad ); for ( i = 0; i < MAX_CODING_STRATS; i++ ) { @@ -837,13 +900,13 @@ ivas_error ivas_spar_md_enc_process( { reset_indices_enc( &hMetaData_tmp, MAX_BITS_METADATA ); - ivas_write_parameter_bitstream( hMdEnc, num_bands, bands_bw, &hMetaData_tmp, hEncoderConfig->ivas_total_brate, dtx_silence_mode, strat, qsi, planarCP ); + ivas_write_parameter_bitstream( pState, num_bands, bands_bw, &hMetaData_tmp, hEncoderConfig->ivas_total_brate, dtx_silence_mode, strat, qsi, planarCP ); if ( hMetaData->nb_bits_tot == bit_pos_start || hMetaData_tmp.nb_bits_tot < ( hMetaData->nb_bits_tot - bit_pos_start ) ) { write_metadata_buffer( &hMetaData_tmp, hMetaData, bit_pos_start, next_ind_start, last_ind_start ); code_strat = strat; } - if ( hMetaData->nb_bits_tot - bit_pos_start + ( ( ( hEncoderConfig->ivas_total_brate == IVAS_256k ) && ( sba_order == 1 ) ) ? 1 : 0 ) <= hMdEnc->spar_md_cfg.tgt_bits_per_blk ) + if ( hMetaData->nb_bits_tot - bit_pos_start + ( ( ( hEncoderConfig->ivas_total_brate == IVAS_256k ) && ( sba_order == 1 ) ) ? 1 : 0 ) <= pState->spar_md_cfg.tgt_bits_per_blk ) { packed_ok = 1; break; @@ -856,7 +919,7 @@ ivas_error ivas_spar_md_enc_process( break; } - if ( hMetaData->nb_bits_tot - bit_pos_start + ( ( ( hEncoderConfig->ivas_total_brate == IVAS_256k ) && ( sba_order == 1 ) ) ? 1 : 0 ) <= hMdEnc->spar_md_cfg.max_bits_per_blk ) + if ( hMetaData->nb_bits_tot - bit_pos_start + ( ( ( hEncoderConfig->ivas_total_brate == IVAS_256k ) && ( sba_order == 1 ) ) ? 1 : 0 ) <= pState->spar_md_cfg.max_bits_per_blk ) { break; } @@ -869,48 +932,48 @@ ivas_error ivas_spar_md_enc_process( #ifdef SPAR_HOA_DBG /*if ( strat >= 4 ) { - for ( b = 0; b < nB; b++ ) + 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++ ) { - 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" ); + fprintf( stdout, "i: %d -- %f\t %d\t %d\n", i, //pState->spar_md.band_coeffs[b].pred_re[i], + pState->spar_md.band_coeffs[b].pred_quant_re[i], + pState->spar_md_prior.band_coeffs_idx[b].pred_index_re[i], + pState->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, // pState->spar_md.band_coeffs[b].C_re[i][j], + pState->spar_md.band_coeffs[b].C_quant_re[i][j], + pState->spar_md_prior.band_coeffs_idx[b].drct_index_re[k], + pState->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, //pState->spar_md.band_coeffs[b].P_re[i][i], + pState->spar_md.band_coeffs[b].P_quant_re[i][i], + pState->spar_md_prior.band_coeffs_idx[b].decd_index_re[i], + pState->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]; + ndm = pState->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] ); + fprintf( stdout, "i: %d -- %.2f\t|\t", i, pState->spar_md.band_coeffs[b].pred_quant_re[i] ); if ( i < num_ch - ndm ) { if ( keep_planar[i] == 1 ) @@ -923,12 +986,12 @@ ivas_error ivas_spar_md_enc_process( } for ( j = 0; j < ndm - 1; j++ ) { - fprintf( stdout, "%.2f\t", hMdEnc->spar_md.band_coeffs[b].C_quant_re[i][j] ); + fprintf( stdout, "%.2f\t", pState->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, "%.2f\t", pState->spar_md.band_coeffs[b].P_quant_re[j] ); } } fprintf( stdout, "\n" ); @@ -965,7 +1028,7 @@ ivas_error ivas_spar_md_enc_process( ( 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 ); + dbgwrite( &pState->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; @@ -978,7 +1041,7 @@ ivas_error ivas_spar_md_enc_process( { for ( j = 0; j < ( ndm - 1 ); j++ ) { - dbgwrite( &hMdEnc->spar_md.band_coeffs[b].C_re[i][j], sizeof( float ), 1, 1, f_name ); + dbgwrite( &pState->spar_md.band_coeffs[b].C_re[i][j], sizeof( float ), 1, 1, f_name ); } } sprintf( f_name, "spar_band_P_coeffs.bin" ); @@ -990,7 +1053,7 @@ ivas_error ivas_spar_md_enc_process( ( 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 ); + dbgwrite( &pState->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; @@ -1001,7 +1064,7 @@ ivas_error ivas_spar_md_enc_process( ( 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 ); + dbgwrite( &pState->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; @@ -1014,7 +1077,7 @@ ivas_error ivas_spar_md_enc_process( { 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 ); + dbgwrite( &pState->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" ); @@ -1026,7 +1089,7 @@ ivas_error ivas_spar_md_enc_process( ( 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 ); + dbgwrite( &pState->spar_md.band_coeffs[b].P_quant_re[i], sizeof( float ), 1, 1, f_name ); } } } @@ -1039,13 +1102,13 @@ ivas_error ivas_spar_md_enc_process( fclose( fp ); #endif - if ( hMdEnc->spar_md_cfg.gen_bs == 1 ) + if ( pState->spar_md_cfg.gen_bs == 1 ) { - ivas_store_prior_coeffs( hMdEnc, num_bands, bands_bw, code_strat, dtx_vad, qsi ); + ivas_store_prior_coeffs( pState, num_bands, bands_bw, code_strat, dtx_vad, qsi ); } - hMdEnc->spar_md.dtx_vad = dtx_vad; - hMdEnc->spar_md.num_bands = num_bands; + pState->spar_md.dtx_vad = dtx_vad; + pState->spar_md.num_bands = num_bands; return IVAS_ERR_OK; } @@ -1339,7 +1402,7 @@ static void ivas_get_arith_coded_bs( #ifdef SPAR_HOA_DBG /*fprintf(stderr, "\n\n band_indexes:\n"); for (int16_t j = 1; j < drct_cell_dims[0].dim1 * drct_cell_dims[0].dim2; j++) - fprintf(stderr, "%d, ", hMdEnc->spar_md.band_coeffs_idx[0].drct_index_re[j]); + fprintf(stderr, "%d, ", hMdEnc->spar_md.band_coeffs_idx[0].drct_index_re[j]); fprintf(stderr, "\n\n"); */ #endif ivas_copy_band_coeffs_idx_to_arr( hMdEnc->spar_md.band_coeffs_idx, nB, symbol_arr_re, drct_cell_dims, DRCT_COEFF, planarCP ); @@ -1499,22 +1562,37 @@ static void ivas_store_prior_coeffs( static void ivas_spar_quant_pred_coeffs_dtx( ivas_spar_md_t *pSpar_md, - const float *pValues, + float **ppValues, const int16_t ndm, - int16_t *pIndex, + int16_t **ppIndex, const int16_t dim1, - float *pQuant ) + float **ppQuant ) { int16_t i; int16_t q_lvl; + float *pVal, val, **ppVal; + int16_t *pIdx, idx, **ppIdx; float pr_min_max[2]; + + ppVal = (float **) &pVal; + ppIdx = (int16_t **) &pIdx; + + ppVal[0] = (float *) &val; + ppIdx[0] = (int16_t *) &idx; + pr_min_max[0] = pSpar_md->min_max[0]; pr_min_max[1] = pSpar_md->min_max[1]; + for ( i = 0; i < dim1; i++ ) { q_lvl = dtx_pr_real_q_levels[ndm - 1][i]; - ivas_quantise_real_values( &pValues[i], q_lvl, pr_min_max[0], pr_min_max[1], &pIndex[i], &pQuant[i], 1 ); + ppVal[0][0] = ppValues[0][i]; + + ivas_quantise_real_values( ppVal, q_lvl, pr_min_max[0], pr_min_max[1], ppIdx, ppVal, 1, 1 ); + ppIndex[0][i] = ppIdx[0][0]; + ppQuant[0][i] = ppVal[0][0]; } + return; } @@ -1526,22 +1604,30 @@ static void ivas_spar_quant_pred_coeffs_dtx( *-----------------------------------------------------------------------------------------*/ static void ivas_quant_p_per_band_dtx( - float *pP_mat, + float **ppP_mat, const int16_t num_dec, const int16_t num_dmx, int16_t *ppIdx_pd, - float *pP_out, + float **ppP_out, const int16_t num_ch ) { int16_t i; + float **ppPd, *pPd, pd; + int16_t **ppIdx, *pIdx, idx; int16_t dim = num_ch - num_dmx; + + ppPd = (float **) &pPd; + ppIdx = (int16_t **) &pIdx; + ppPd[0] = (float *) &pd; + ppIdx[0] = (int16_t *) &idx; + if ( num_dec == num_ch - 1 ) { for ( i = 0; i < dim; i++ ) { - if ( pP_mat[i] < pr_boost_range[1] && pP_mat[i] > pr_boost_range[0] ) + if ( ppP_mat[i][i] < pr_boost_range[1] && ppP_mat[i][i] > pr_boost_range[0] ) { - pP_mat[i] = pr_boost_range[1]; + ppP_mat[i][i] = pr_boost_range[1]; } } } @@ -1550,13 +1636,21 @@ static void ivas_quant_p_per_band_dtx( { assert( !"Not Supported!" ); } + for ( i = 0; i < dim; i++ ) { - ivas_quantise_real_values( &pP_mat[i], dtx_pd_real_q_levels[num_ch - num_dec - 1][i], dtx_pd_real_min_max[0], dtx_pd_real_min_max[1], &ppIdx_pd[i], &pP_out[i], 1 ); + ppPd[0][0] = ppP_mat[i][i]; + + ivas_quantise_real_values( ppPd, dtx_pd_real_q_levels[num_ch - num_dec - 1][i], dtx_pd_real_min_max[0], dtx_pd_real_min_max[1], ppIdx, ppPd, 1, 1 ); + + ppP_out[i][i] = ppPd[0][0]; + ppIdx_pd[i] = ppIdx[0][0]; } + return; } + /*-----------------------------------------------------------------------------------------* * Function ivas_write_parameter_bitstream_dtx() * @@ -1571,11 +1665,18 @@ static void ivas_write_parameter_bitstream_dtx( const int16_t num_bands ) { int16_t i, j; - float val; - int16_t idx; + float **ppVal, *pVal, val; + int16_t **ppIdx, *pIdx, idx; float pr_min_max[2]; int16_t zero_pad_bits, sid_bits_len; sid_bits_len = hMetaData->nb_bits_tot; + + ppVal = (float **) &pVal; + ppIdx = (int16_t **) &pIdx; + + ppVal[0] = (float *) &val; + ppIdx[0] = (int16_t *) &idx; + pr_min_max[0] = pSpar_md->min_max[0]; pr_min_max[1] = pSpar_md->min_max[1]; @@ -1613,15 +1714,17 @@ static void ivas_write_parameter_bitstream_dtx( pd_q_lvls = dtx_pd_real_q_levels[ndm - 1][pd_idx_2 - 1]; pd = pSpar_md->band_coeffs_idx[i].decd_index_re[pd_idx_2 - 1]; } - val = dtx_pd_real_min_max[0]; - ivas_quantise_real_values( &val, pd_q_lvls, dtx_pd_real_min_max[0], dtx_pd_real_min_max[1], &idx, &val, 1 ); - pd -= idx; + ppVal[0][0] = dtx_pd_real_min_max[0]; + ivas_quantise_real_values( ppVal, pd_q_lvls, dtx_pd_real_min_max[0], dtx_pd_real_min_max[1], ppIdx, ppVal, 1, 1 ); + + pd -= ppIdx[0][0]; - val = pr_min_max[0]; - ivas_quantise_real_values( &val, pr_q_lvls, pr_min_max[0], pr_min_max[1], &idx, &val, 1 ); + ppVal[0][0] = pr_min_max[0]; + ivas_quantise_real_values( ppVal, pr_q_lvls, pr_min_max[0], pr_min_max[1], ppIdx, ppVal, 1, 1 ); + + pr -= ppIdx[0][0]; - pr -= idx; pr_pd_bits = ivas_get_bits_to_encode( pd_q_lvls * pr_q_lvls ); value = (uint16_t) ( pr * pd_q_lvls + pd ); @@ -1634,19 +1737,21 @@ static void ivas_write_parameter_bitstream_dtx( int16_t pr_idx1, pr_idx2, pr_pr_bits; pr_q_lvls1 = dtx_pr_real_q_levels[ndm - 1][pr_idx_1 - 1]; pr_q_lvls2 = dtx_pr_real_q_levels[ndm - 1][pr_idx_2 - 1]; - val = pr_min_max[0]; - ivas_quantise_real_values( &val, pr_q_lvls1, pr_min_max[0], pr_min_max[1], &idx, &val, 1 ); + + ppVal[0][0] = pr_min_max[0]; + ivas_quantise_real_values( ppVal, pr_q_lvls1, pr_min_max[0], pr_min_max[1], ppIdx, ppVal, 1, 1 ); pr_idx1 = pSpar_md->band_coeffs_idx[i].pred_index_re[pr_idx_1 - 1]; - pr_idx1 -= idx; + pr_idx1 -= ppIdx[0][0]; - val = pr_min_max[0]; - ivas_quantise_real_values( &val, pr_q_lvls2, pr_min_max[0], pr_min_max[1], &idx, &val, 1 ); + ppVal[0][0] = pr_min_max[0]; + ivas_quantise_real_values( ppVal, pr_q_lvls2, pr_min_max[0], pr_min_max[1], ppIdx, ppVal, 1, 1 ); pr_idx2 = pSpar_md->band_coeffs_idx[i].pred_index_re[pr_idx_2 - 1]; - pr_idx2 -= idx; + pr_idx2 -= ppIdx[0][0]; + value = (uint16_t) ( pr_idx2 * pr_q_lvls1 + pr_idx1 ); pr_pr_bits = ivas_get_bits_to_encode( pr_q_lvls1 * pr_q_lvls2 ); @@ -1683,7 +1788,18 @@ static void ivas_quant_pred_coeffs_per_band( ivas_quant_strat_t *pQs, const int16_t num_ch ) { - ivas_quantise_real_values( pband_coeffs->pred_re, pQs->PR.q_levels[0], pQs->PR.min, pQs->PR.max, pBand_coeffs_idx->pred_index_re, pband_coeffs->pred_quant_re, ( num_ch - 1 ) ); + float *pQuant_re, *pCoeff_re; + int16_t *pIdx_re; + float **ppPred_coeffs_re = (float **) &pCoeff_re; + float **ppPred_quant_re = (float **) &pQuant_re; + int16_t **ppPred_idx_re = (int16_t **) &pIdx_re; + + ppPred_idx_re[0] = &pBand_coeffs_idx->pred_index_re[0]; + ppPred_coeffs_re[0] = &pband_coeffs->pred_re[0]; + ppPred_quant_re[0] = &pband_coeffs->pred_quant_re[0]; + + ivas_quantise_real_values( ppPred_coeffs_re, pQs->PR.q_levels[0], pQs->PR.min, pQs->PR.max, ppPred_idx_re, ppPred_quant_re, 1, ( num_ch - 1 ) ); + return; } @@ -1704,6 +1820,17 @@ static void ivas_quant_c_per_band( int16_t i; int16_t j, k; float C_re[IVAS_SPAR_MAX_C_COEFF]; + float *pC_re[IVAS_SPAR_MAX_C_COEFF]; + int16_t *pIdx_re[IVAS_SPAR_MAX_C_COEFF]; + float **ppC_re = (float **) &pC_re[0]; + int16_t **ppIdx_re = (int16_t **) &pIdx_re[0]; + + for ( i = 0; i < ndec * ( ndm - 1 ); i++ ) + { + ppC_re[i] = &C_re[i]; + ppIdx_re[i] = &pBand_coeffs_idx->drct_index_re[i]; + } + k = 0; for ( i = 0; i < ndec; i++ ) { @@ -1713,16 +1840,19 @@ static void ivas_quant_c_per_band( k++; } } + #ifdef SPAR_HOA_DBG /*for (i = 0; i < ndec; i++) { - for (j = 0; j < ndm - 1; j++) - { - ppIdx_re[i][j] = 100; - } + for (j = 0; j < ndm - 1; j++) + { + ppIdx_re[i][j] = 100; + } }*/ #endif - ivas_quantise_real_values( C_re, pQs->C.q_levels[0], pQs->C.min, pQs->C.max, pBand_coeffs_idx->drct_index_re, C_re, ndec * ( ndm - 1 ) ); + + ivas_quantise_real_values( ppC_re, pQs->C.q_levels[0], pQs->C.min, pQs->C.max, ppIdx_re, ppC_re, ndec * ( ndm - 1 ), 1 ); + k = 0; for ( i = 0; i < ndec; i++ ) { @@ -1737,11 +1867,11 @@ static void ivas_quant_c_per_band( k = 0; for (i = 0; i < ndec; i++) { - for (j = 0; j < ndm - 1; j++) - { - fprintf(stderr, "%d,%d: %f, %f, %d\n", i, j, pband_coeffs->C_re[i][j], pband_coeffs->C_quant_re[i][j], pBand_coeffs_idx->drct_index_re[k]); - k++; - } + for (j = 0; j < ndm - 1; j++) + { + fprintf(stderr, "%d,%d: %f, %f, %d\n", i, j, pband_coeffs->C_re[i][j], pband_coeffs->C_quant_re[i][j], pBand_coeffs_idx->drct_index_re[k]); + k++; + } }*/ #endif @@ -1761,14 +1891,40 @@ static void ivas_quant_p_per_band( ivas_quant_strat_t *pQs, const int16_t num_ch ) { + float P_re_diag[IVAS_SPAR_MAX_CH - 1]; + int16_t i; + int16_t dim = num_ch - 1; + float *pP_diag[IVAS_SPAR_MAX_CH - 1]; + int16_t *pDecd_idx[IVAS_SPAR_MAX_CH - 1]; + float **ppP_diag = (float **) &pP_diag[0]; + int16_t **ppDecd_idx = (int16_t **) &pDecd_idx[0]; + + for ( i = 0; i < dim; i++ ) + { + ppP_diag[i] = &P_re_diag[i]; + ppDecd_idx[i] = &pBand_coeffs_idx->decd_index_re[i]; + } + + for ( i = 0; i < dim; i++ ) + { + P_re_diag[i] = pband_coeffs->P_re[i]; + } + #ifdef SPAR_HOA_DBG /*fprintf(stderr, "\n\n P_d:\n"); for (i = 0; i < dim; i++) { - fprintf(stderr, "%f, ", P_re_diag[i]); + fprintf(stderr, "%f, ", P_re_diag[i]); } fprintf(stderr, "\n\n");*/ #endif - ivas_quantise_real_values( pband_coeffs->P_re, pQs->P_r.q_levels[0], pQs->P_r.min, pQs->P_r.max, pBand_coeffs_idx->decd_index_re, pband_coeffs->P_quant_re, num_ch - 1 ); + + ivas_quantise_real_values( ppP_diag, pQs->P_r.q_levels[0], pQs->P_r.min, pQs->P_r.max, ppDecd_idx, ppP_diag, num_ch - 1, 1 ); + + for ( i = 0; i < dim; i++ ) + { + pband_coeffs->P_quant_re[i] = P_re_diag[i]; + } + return; } diff --git a/lib_enc/ivas_stat_enc.h b/lib_enc/ivas_stat_enc.h index 2169cac9bd..58b6970d58 100644 --- a/lib_enc/ivas_stat_enc.h +++ b/lib_enc/ivas_stat_enc.h @@ -571,11 +571,7 @@ typedef struct ivas_dirac_enc_data_structure PARAM_ISM_CONFIG_HANDLE hParamIsm; /* Parametric ISM handle */ IVAS_FB_MIXER_HANDLE hFbMixer; -#ifdef FIX_DIRAC_CHANNELS - float *sba_synchro_buffer[DIRAC_MAX_ANA_CHANS]; -#else float *sba_synchro_buffer[IVAS_MAX_NUM_CH]; // VE: all 16 buffers not needed ? -#endif int16_t num_samples_synchro_delay; /* DirAC parameter estimation */ @@ -1044,7 +1040,9 @@ typedef struct /* high-level encoder parameters */ int16_t nchan_transport; /* number of transport channels */ - int16_t sba_analysis_order; /* Ambisonic (SBA) order used for analysis and coding */ +#ifdef SBA_ORDER_BITSTREAM + int16_t sba_analysis_order; /*Ambisonic(SBA) order*/ +#endif int16_t codec_mode; /* Mode1 or Mode2 of core codec */ int16_t last_codec_mode; /* previous frame Mode 1 or 2 */ diff --git a/lib_enc/ivas_stereo_cng_enc.c b/lib_enc/ivas_stereo_cng_enc.c index 9176f9ad2f..860cdbe88f 100644 --- a/lib_enc/ivas_stereo_cng_enc.c +++ b/lib_enc/ivas_stereo_cng_enc.c @@ -148,12 +148,7 @@ void stereo_dft_enc_sid_coh( int16_t alpha_level; int16_t n; -#ifdef ALIGN_SID_SIZE - /* TODO: still use old number of bits to keep bitexactness in output */ - nr_of_sid_stereo_bits = ( 4400 /*IVAS_SID_5k2*/ - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS; -#else nr_of_sid_stereo_bits = ( IVAS_SID_4k4 - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS; -#endif zeropad = 0; /* Encode coherence vector. Find best fixed predictor by minimizing prediction error on input vector. @@ -308,10 +303,6 @@ void stereo_dft_enc_sid_coh( ( *nb_bits )++; } -#ifdef ALIGN_SID_SIZE - push_next_indice( hBstr, zeropad, ( IVAS_SID_5k2 - 4400 ) / FRAMES_PER_SEC ); -#endif - return; } diff --git a/lib_enc/ivas_stereo_dft_enc.c b/lib_enc/ivas_stereo_dft_enc.c index 402003be6c..b6a7e0685d 100644 --- a/lib_enc/ivas_stereo_dft_enc.c +++ b/lib_enc/ivas_stereo_dft_enc.c @@ -2317,11 +2317,7 @@ void stereo_dft_enc_write_BS( { stereo_dft_enc_sid_calc_coh( hStereoDft, hCPE->hStereoCng->coh_crossfade, &hCPE->hStereoCng->td_active, &hCPE->hStereoCng->first_SID, cohBand ); -#ifdef ALIGN_SID_SIZE - if ( *nb_bits <= ( ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS - STEREO_DFT_ITD_MODE_NBITS - STEREO_DFT_SID_ITD_NBITS - 1 ) ) -#else if ( *nb_bits <= ( ( IVAS_SID_4k4 - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS - STEREO_DFT_ITD_MODE_NBITS - STEREO_DFT_SID_ITD_NBITS - 1 ) ) -#endif { if ( hStereoDft->hItd->itd[k_offset] != 0 ) { @@ -2397,11 +2393,7 @@ void stereo_dft_enc_write_BS( nb += STEREO_DFT_GIPD_NBITS; } } -#ifdef ALIGN_SID_SIZE - else if ( *nb_bits <= ( ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS - STEREO_DFT_FLAG_BITS - STEREO_DFT_SID_GIPD_NBITS ) ) -#else else if ( *nb_bits <= ( ( IVAS_SID_4k4 - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS - STEREO_DFT_FLAG_BITS - STEREO_DFT_SID_GIPD_NBITS ) ) -#endif { push_indice( hBstr, IND_STEREO_DFT_NO_IPD_FLAG, hStereoDft->no_ipd_flag, STEREO_DFT_FLAG_BITS ); nb += STEREO_DFT_FLAG_BITS; /*IPD mode flag: 1bit*/ @@ -2951,11 +2943,7 @@ static void stereo_dft_enc_compute_prm( /* parameters for bred0 <= b < bpred1 are estimated from parameters of the remaining bands with ptrans0 <= b < btrans1. */ - bpred1 = ( hStereoDft->nbands > 10 ) ? STEREO_DFT_RES_PRED_BAND_MAX - 2 : hStereoDft->nbands; - if ( hStereoDft->band_res[k_offset] == STEREO_DFT_BAND_RES_LOW ) - { - bpred1 = min( bpred1, 6 ); - } + bpred1 = ( hStereoDft->nbands > 10 ) ? hStereoDft->nbands - 2 : hStereoDft->nbands; bpred0 = bpred1 - STEREO_DFT_RES_PRED_BAND_MIN_CONST; /* get estimate (currently the maximal index) */ @@ -2975,7 +2963,7 @@ static void stereo_dft_enc_compute_prm( if ( hStereoDft->reverb_flag && hStereoDft->nbands > 10 ) /*SWB and FB*/ { - for ( b = STEREO_DFT_RES_PRED_BAND_MAX - 1; b >= STEREO_DFT_RES_PRED_BAND_MAX - 2; b-- ) + for ( b = hStereoDft->nbands - 1; b >= hStereoDft->nbands - 2; b-- ) { hStereoDft->res_pred_index_EC[b - STEREO_DFT_RES_PRED_BAND_MIN_CONST] = hStereoDft->res_pred_index_EC[b]; } diff --git a/lib_enc/ivas_stereo_dft_enc_itd.c b/lib_enc/ivas_stereo_dft_enc_itd.c old mode 100644 new mode 100755 index 594137993e..fd39db32d3 --- a/lib_enc/ivas_stereo_dft_enc_itd.c +++ b/lib_enc/ivas_stereo_dft_enc_itd.c @@ -446,6 +446,9 @@ static float calc_mean_E_ratio( ITD_DATA_HANDLE hItd, int16_t nbands, int16_t band_limits[], +#ifndef FIX_WRONG_NBANDS_IN_ITD_ESTIMATION + const int16_t NFFT, +#endif const float sfm, const float nrg_L[STEREO_DFT_N_32k_ENC / 2], const float nrg_R[STEREO_DFT_N_32k_ENC / 2], @@ -466,7 +469,11 @@ static float calc_mean_E_ratio( grand_sum_xcorr_img = 0.0f; /*take bands up to 32kHz bandwidth as ITD is always calculated at 32kHz sampling rate*/ +#ifdef FIX_WRONG_NBANDS_IN_ITD_ESTIMATION nbands -= ( band_limits[nbands] > STEREO_DFT_N_32k_ENC / 2 ); +#else + nbands -= ( NFFT > STEREO_DFT_N_32k_ENC ); +#endif sum_Er = 0; for ( b = 0; b < nbands; b++ ) @@ -1237,7 +1244,11 @@ void stereo_dft_enc_compute_itd( /*calculate mean E ratio of main to background signal for cohSNR*/ if ( hCPE->element_mode == IVAS_CPE_DFT ) { +#ifdef FIX_WRONG_NBANDS_IN_ITD_ESTIMATION mEr = calc_mean_E_ratio( hItd, hStereoDft->nbands, hStereoDft->band_limits, sfm_L, pNrgL, pNrgR, &total_mEr ); +#else + mEr = calc_mean_E_ratio( hItd, hStereoDft->nbands, hStereoDft->band_limits, hStereoDft->NFFT, sfm_L, pNrgL, pNrgR, &total_mEr ); +#endif } else { @@ -1246,7 +1257,11 @@ void stereo_dft_enc_compute_itd( set_s( band_limits, 0, STEREO_DFT_BAND_MAX + 1 ); set_band_limits( &nbands, band_limits, hCPE->hStereoMdct->hDft_ana->NFFT ); +#ifdef FIX_WRONG_NBANDS_IN_ITD_ESTIMATION mEr = calc_mean_E_ratio( hItd, nbands, band_limits, sfm_L, pNrgL, pNrgR, &total_mEr ); +#else + mEr = calc_mean_E_ratio( hItd, nbands, band_limits, hCPE->hStereoMdct->hDft_ana->NFFT, sfm_L, pNrgL, pNrgR, &total_mEr ); +#endif } /*calculate total cohSNR for frame in dB*/ diff --git a/lib_enc/ivas_stereo_dmx_evs.c b/lib_enc/ivas_stereo_dmx_evs.c index 4e25a90633..409b7b0d56 100644 --- a/lib_enc/ivas_stereo_dmx_evs.c +++ b/lib_enc/ivas_stereo_dmx_evs.c @@ -152,6 +152,9 @@ static void calc_poc( { int16_t i, n1, n2; int16_t n0, *itdLR; +#ifndef NTT_REMOVE_EPS_ROM + const float *c; +#endif const float *s; float *P; float tmp1, tmp2, Lr, Li, Rr, Ri, gamma, igamma, iN; @@ -159,13 +162,18 @@ static void calc_poc( float tmpPOC1[L_FRAME48k], tmpPOC2[L_FRAME48k]; float rfft_buf[L_FRAME48k]; int16_t step, bias; +#ifdef NTT_REMOVE_EPS_ROM int16_t i_for; int16_t cos_step, cos_max; float eps_cos, eps_sin, EPS; +#endif /* Initialization */ iN = 1.0f / (float) input_frame; +#ifndef NTT_REMOVE_EPS_ROM + c = hPOC->sin + ( input_frame >> 2 ); +#endif s = hPOC->sin; P = hPOC->P; n0 = input_frame / 2; @@ -187,6 +195,7 @@ static void calc_poc( specPOr[0] = sign( specLr[0] ) * sign( specRr[0] ) * wnd[bias]; specPOi[0] = 0.0f; +#ifdef NTT_REMOVE_EPS_ROM EPS = hPOC->eps; if ( input_frame == L_FRAME16k ) @@ -243,6 +252,28 @@ static void calc_poc( specPOi[i] = ( Lr * Ri - Li * Rr ) * tmp1; gamma -= igamma; } + // end NTT_REMOVE_EPS_ROM +#else + for ( i = 1; i < n0; i++ ) + { + Lr = specLr[i]; + Li = specLi[i]; + Rr = specRr[i]; + Ri = specRi[i]; + + Lr += ( specRr[i] * c[i] + specRi[i] * s[i] ); + Li += ( -specRr[i] * s[i] + specRi[i] * c[i] ); + Rr += ( specLr[i] * c[i] + specLi[i] * s[i] ); + Ri += ( -specLr[i] * s[i] + specLi[i] * c[i] ); + + tmp1 = wnd[i * step + bias] * gamma / ( sqrtf( ( ( Lr * Lr + Li * Li ) ) * ( ( Rr * Rr + Ri * Ri ) ) ) + hPOC->eps ); + + specPOr[i] = ( Lr * Rr + Li * Ri ) * tmp1; + specPOi[i] = ( Lr * Ri - Li * Rr ) * tmp1; + + gamma -= igamma; + } +#endif // end !NTT_REMOVE_EPS_ROM specPOr[n0] = sign( specLr[i] ) * sign( specRr[i] ) * wnd[i * step + bias] * gamma; @@ -414,31 +445,16 @@ static float find_poc_peak( } } - if ( ( on[0] && prev_off[0] ) && ( on[1] && prev_off[1] ) ) /*if both channels have newly detected as active (possibility of preceding), select channel by peakness Q[] of POC */ - { - *itd = ( Q[0] > Q[1] ) ? (float) itdLR[0] : (float) itdLR[1]; - } - else if ( ( on[0] && prev_off[0] ) && ( Q[0] > ( Q[1] - 0.1 ) ) ) /* if channel 0 becomes active, select channel 0*/ - { - *itd = (float) itdLR[0]; - } - else if ( ( on[1] && prev_off[1] ) && ( Q[1] > ( Q[0] - 0.1 ) ) ) /*if channel 1 becomes active, selsect channel 1*/ - { - *itd = (float) itdLR[1]; - } - else if ( Q[0] > ( Q[1] + Q_BAND ) ) /* if no status change, use Q[]*/ +#ifndef NTT_UPDATE_ITD_SW + if ( on[0] && prev_off[0] ) { *itd = (float) itdLR[0]; } - else if ( Q[1] > ( Q[0] + Q_BAND ) ) /* if no status change, use Q[]*/ + else if ( on[1] && prev_off[1] ) { *itd = (float) itdLR[1]; } - else if ( *itd == 0.0 ) /*if no channels are likely to be preceding, follow the status of the previous frame*/ - { - *itd = 0; - } - else /*follow the status of the previous frame*/ + else { *itd = ( *itd > 0 ) ? (float) itdLR[0] : (float) itdLR[1]; } @@ -872,20 +888,21 @@ ivas_error stereo_dmx_evs_init_encoder( #else if ( input_frame == L_FRAME16k ) { - hStereoDmxEVS->hPOC->sin = dft_trigo_32k; + hStereoDmxEVS->hPOC->sin = Stereo_dmx_s_wnd_coef_eps_16k; } else if ( input_frame == L_FRAME32k ) { - hStereoDmxEVS->hPOC->sin = dft_trigo_32k; + hStereoDmxEVS->hPOC->sin = Stereo_dmx_s_wnd_coef_eps_32k; } else if ( input_frame == L_FRAME48k ) { - hStereoDmxEVS->hPOC->sin = dft_trigo_48k; + hStereoDmxEVS->hPOC->sin = Stereo_dmx_s_wnd_coef_eps_48k; } else { return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "invalid frame length\n" ); } +#endif hStereoDmxEVS->hPOC->confidence = 0.0f; diff --git a/lib_enc/ivas_stereo_mdct_core_enc.c b/lib_enc/ivas_stereo_mdct_core_enc.c index 664998967c..c41df7b24e 100644 --- a/lib_enc/ivas_stereo_mdct_core_enc.c +++ b/lib_enc/ivas_stereo_mdct_core_enc.c @@ -129,9 +129,6 @@ void stereo_mdct_core_enc( float *p_orig_spectrum_long[CPE_CHANNELS], orig_spectrum_long[CPE_CHANNELS][N_MAX]; /* MDCT output (L/R). */ float *orig_spectrum[CPE_CHANNELS][2]; /* Pointers to MDCT output for a short block (L/R) */ float powerSpec[CPE_CHANNELS][N_MAX]; -#ifdef DRAM_REDUCTION_MCT_IGF - float *p_powerSpec[CPE_CHANNELS]; -#endif float powerSpecMsInv_long[CPE_CHANNELS][N_MAX]; /* MS inv power spectrum, also inverse MDST spectrum */ float *powerSpecMsInv[CPE_CHANNELS][2]; float quantized_spectrum_long[CPE_CHANNELS][N_MAX]; /* quantized MDCT spectrum, inv ms mask mdst spectrum, scratch for MS spectra in the MS decision */ @@ -354,13 +351,7 @@ void stereo_mdct_core_enc( hStereoMdct->mdct_stereo_mode[n] == SMDCT_BW_MS ) && !hStereoMdct->isSBAStereoMode ) { -#ifdef DRAM_REDUCTION_MCT_IGF - p_powerSpec[0] = powerSpec[0]; - p_powerSpec[1] = powerSpec[1]; - ProcessStereoIGF( hStereoMdct, sts, ms_mask, orig_spectrum, p_powerSpec, powerSpecMsInv, inv_spectrum, n, hCPE->hCoreCoder[0]->sp_aud_decision0, hCPE->hCoreCoder[0]->element_brate, 0 ); -#else ProcessStereoIGF( hStereoMdct, sts, ms_mask, orig_spectrum, powerSpec, powerSpecMsInv, inv_spectrum, n, hCPE->hCoreCoder[0]->sp_aud_decision0, hCPE->hCoreCoder[0]->element_brate, 0 ); -#endif } else { diff --git a/lib_enc/ivas_stereo_switching_enc.c b/lib_enc/ivas_stereo_switching_enc.c index d0201784a6..9075d73595 100644 --- a/lib_enc/ivas_stereo_switching_enc.c +++ b/lib_enc/ivas_stereo_switching_enc.c @@ -218,12 +218,13 @@ static void deallocate_CoreCoder_enc( *-------------------------------------------------------------------*/ ivas_error stereo_memory_enc( - CPE_ENC_HANDLE hCPE, /* i : CPE encoder structure */ - const int32_t input_Fs, /* i : input sampling rate */ - const int16_t max_bwidth, /* i : maximum audio bandwidth */ - float *tdm_last_ratio, /* o : TD stereo last ratio */ - const IVAS_FORMAT ivas_format, /* i : ivas format */ - const int16_t nchan_transport /* i : number transport chans */ + CPE_ENC_HANDLE hCPE, /* i : CPE encoder structure */ + const int32_t input_Fs, /* i : input sampling rate */ + const int16_t max_bwidth, /* i : maximum audio bandwidth */ + float *tdm_last_ratio, /* o : TD stereo last ratio */ + const IVAS_FORMAT ivas_format /* i : ivas format */ + , + const int16_t nchan_transport /* i : number transport chans */ ) { Encoder_State *st; @@ -537,7 +538,7 @@ ivas_error stereo_memory_enc( #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 ); + hCPE->hStereoMdct->isSBAStereoMode = ( ( ivas_format == SBA_FORMAT ) && ( nchan_transport == 2 ) ); if ( hCPE->element_mode == IVAS_CPE_MDCT && hCPE->element_brate <= MAX_MDCT_ITD_BRATE && ivas_format == STEREO_FORMAT ) { diff --git a/lib_enc/ivas_tcx_core_enc.c b/lib_enc/ivas_tcx_core_enc.c index ce2d74ec9a..79bb2f04a7 100644 --- a/lib_enc/ivas_tcx_core_enc.c +++ b/lib_enc/ivas_tcx_core_enc.c @@ -268,7 +268,7 @@ void stereo_tcx_core_enc( *--------------------------------------------------------------------------------*/ /* TCX20/TCX10 and coder type */ -#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT writeTCXMode( st, hBstr, 0, /* <- is_mct */ &nbits_start ); #else writeTCXMode( st, hBstr, &nbits_start ); diff --git a/lib_enc/lib_enc.c b/lib_enc/lib_enc.c old mode 100644 new mode 100755 index f313a2bcc9..b9d4dde032 --- a/lib_enc/lib_enc.c +++ b/lib_enc/lib_enc.c @@ -54,6 +54,7 @@ struct IVAS_ENC Indice ind_list[MAX_NUM_DATA][MAX_NUM_INDICES]; /* list of indices */ Indice ind_list_metadata[MAX_NUM_METADATA][MAX_BITS_METADATA]; /* list of indices for metadata */ ENC_CORE_HANDLE hCoreCoder; + /* Some of these can be moved to Encoder_Struct, but for now leave them here to keep merging simpler */ bool isConfigured; #ifdef DEBUGGING bool cmd_stereo; @@ -62,8 +63,7 @@ struct IVAS_ENC int16_t Opt_RF_ON_loc; int16_t rf_fec_offset_loc; bool ismMetadataProvided[MAX_NUM_OBJECTS]; - bool maxBandwidthUser; /* Was a specific max bandwith selected by the user? */ - IVAS_ENC_BANDWIDTH newBandwidthApi; /* maximum encoded bandwidth, as set on API level */ + bool maxBandwidthUser; /* Was a specific max bandwith selected by the user? */ }; /*---------------------------------------------------------------------* @@ -77,7 +77,7 @@ static ivas_error setChannelAwareConfig( IVAS_ENC_HANDLE hIvasEnc, const IVAS_EN static int16_t getInputBufferSize( const Encoder_Struct *st_ivas ); static ivas_error doCommonConfigureChecks( IVAS_ENC_HANDLE hIvasEnc ); static ivas_error doCommonSetterChecks( IVAS_ENC_HANDLE hIvasEnc ); -static ivas_error sanitizeBandwidth( const IVAS_ENC_HANDLE hIvasEnc ); +static void updateBandwidthFromFs( 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 ); @@ -105,10 +105,6 @@ ivas_error IVAS_ENC_Open( return IVAS_ERR_UNEXPECTED_NULL_POINTER; } - /*-----------------------------------------------------------------* - * Allocate and initialize IVAS application encoder handle - *-----------------------------------------------------------------*/ - #ifdef BITSTREAM_INDICES_MEMORY if ( ( *phIvasEnc = (IVAS_ENC_HANDLE) dynamic_malloc( sizeof( struct IVAS_ENC ) ) ) == NULL ) #else @@ -118,14 +114,15 @@ ivas_error IVAS_ENC_Open( return IVAS_ERR_FAILED_ALLOC; } - ( *phIvasEnc )->hCoreCoder = NULL; - ( *phIvasEnc )->isConfigured = false; -#ifdef DEBUGGING - ( *phIvasEnc )->cmd_stereo = false; -#endif - ( *phIvasEnc )->switchingActive = false; - ( *phIvasEnc )->maxBandwidthUser = false; - resetIsmMetadataProvidedFlags( *phIvasEnc ); + if ( ( ( *phIvasEnc )->st_ivas = (Encoder_Struct *) count_malloc( sizeof( Encoder_Struct ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for IVAS encoder structure" ); + } + + if ( ( ( *phIvasEnc )->st_ivas->hEncoderConfig = (ENCODER_CONFIG_HANDLE) count_malloc( sizeof( ENCODER_CONFIG ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for Encoder config structure" ); + } /*-----------------------------------------------------------------* * Initialize indices @@ -150,36 +147,29 @@ ivas_error IVAS_ENC_Open( } /*-----------------------------------------------------------------* - * Allocate IVAS-codec encoder state - *-----------------------------------------------------------------*/ - - if ( ( ( *phIvasEnc )->st_ivas = (Encoder_Struct *) count_malloc( sizeof( Encoder_Struct ) ) ) == NULL ) - { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for IVAS encoder structure" ); - } - - if ( ( ( *phIvasEnc )->st_ivas->hEncoderConfig = (ENCODER_CONFIG_HANDLE) count_malloc( sizeof( ENCODER_CONFIG ) ) ) == NULL ) - { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for Encoder config structure" ); - } - - /*-----------------------------------------------------------------* - * Initialize IVAS-codec encoder state + * Initialize encoder state *-----------------------------------------------------------------*/ st_ivas = ( *phIvasEnc )->st_ivas; + st_ivas->hEncoderConfig->ivas_total_brate = ACELP_12k65; + st_ivas->hEncoderConfig->Opt_SC_VBR = 0; + st_ivas->hEncoderConfig->last_Opt_SC_VBR = 0; - /* initialize encoder Config. handle */ - init_encoder_config( st_ivas->hEncoderConfig ); - - /* initialize pointers to handles to NULL */ - ivas_initialize_handles_enc( st_ivas ); - - /* set high-level parameters */ st_ivas->mc_mode = MC_MODE_NONE; st_ivas->ism_mode = ISM_MODE_NONE; st_ivas->sba_mode = SBA_MODE_NONE; - st_ivas->sba_analysis_order = 0; + + init_encoder_config( st_ivas->hEncoderConfig ); + + ( *phIvasEnc )->hCoreCoder = NULL; + ( *phIvasEnc )->isConfigured = false; +#ifdef DEBUGGING + ( *phIvasEnc )->cmd_stereo = false; +#endif + ( *phIvasEnc )->switchingActive = false; + ( *phIvasEnc )->maxBandwidthUser = false; + resetIsmMetadataProvidedFlags( *phIvasEnc ); + return IVAS_ERR_OK; } @@ -782,7 +772,16 @@ static ivas_error configureEncoder( } else if ( hEncoderConfig->ivas_format == SBA_FORMAT ) { - /* nothing */ + if ( hEncoderConfig->ivas_total_brate < IVAS_256k ) + { + /* set SBA order to 1 for bit rates below 256kbps for correct handling of input with higher order */ + /* IVAS_fmToDo: needs more work in case of bitrate switching */ +#ifndef SBA_ORDER_BITSTREAM + hEncoderConfig->sba_order = 1; +#else + st_ivas->sba_analysis_order = 1; +#endif + } } else if ( hEncoderConfig->ivas_format == MASA_FORMAT ) { @@ -827,6 +826,8 @@ static ivas_error configureEncoder( hEncoderConfig->input_Fs = inputFs; + updateBandwidthFromFs( hEncoderConfig ); + /*-----------------------------------------------------------------* * Channel-aware mode *-----------------------------------------------------------------*/ @@ -854,7 +855,7 @@ static ivas_error configureEncoder( } } - if ( hEncoderConfig->ivas_total_brate == IVAS_13k2 && hEncoderConfig->Opt_RF_ON == 1 ) + if ( hEncoderConfig->ivas_total_brate == 13200 && hEncoderConfig->Opt_RF_ON == 1 ) { st_ivas->codec_mode = MODE2; } @@ -894,11 +895,6 @@ static ivas_error configureEncoder( return IVAS_ERROR( IVAS_ERR_NOT_SUPPORTED_OPTION, "PCA supported at SBA FOA 256 kbps only." ); } - if ( ( error = sanitizeBandwidth( hIvasEnc ) ) != IVAS_ERR_OK ) - { - return error; - } - /*-----------------------------------------------------------------* * Finalize initialization *-----------------------------------------------------------------*/ @@ -966,7 +962,7 @@ ivas_error IVAS_ENC_GetDelay( *---------------------------------------------------------------------*/ static int16_t getInputBufferSize( - const Encoder_Struct *st_ivas /* i : IVAS encoder handle */ + const Encoder_Struct *st_ivas /* i: IVAS encoder handle */ ) { return (int16_t) ( st_ivas->hEncoderConfig->input_Fs * st_ivas->hEncoderConfig->nchan_inp / FRAMES_PER_SEC ); @@ -1036,11 +1032,6 @@ ivas_error IVAS_ENC_EncodeFrameToSerial( return IVAS_ERR_INVALID_INPUT_BUFFER_SIZE; } - if ( ( error = sanitizeBandwidth( hIvasEnc ) ) != IVAS_ERR_OK ) - { - return error; - } - if ( hEncoderConfig->ivas_format == ISM_FORMAT ) { for ( i = 0; i < hEncoderConfig->nchan_inp; ++i ) @@ -1413,8 +1404,7 @@ static ivas_error printConfigInfo_enc( { Encoder_Struct *st_ivas; ENCODER_CONFIG_HANDLE hEncoderConfig; - int16_t newBandwidthApi; - ivas_error error; + char max_bwidth_string[4]; st_ivas = hIvasEnc->st_ivas; hEncoderConfig = st_ivas->hEncoderConfig; @@ -1555,9 +1545,20 @@ static ivas_error printConfigInfo_enc( * Print potential limitation of audio bandwidth *-----------------------------------------------------------------*/ - if ( ( error = bandwidthApiToInternal( hIvasEnc->newBandwidthApi, &newBandwidthApi ) ) != IVAS_ERR_OK ) + switch ( hEncoderConfig->max_bwidth ) { - return error; + case NB: + strncpy( max_bwidth_string, "NB\0", sizeof( max_bwidth_string ) ); + break; + case WB: + strncpy( max_bwidth_string, "WB\0", sizeof( max_bwidth_string ) ); + break; + case SWB: + strncpy( max_bwidth_string, "SWB\0", sizeof( max_bwidth_string ) ); + break; + case FB: + strncpy( max_bwidth_string, "FB\0", sizeof( max_bwidth_string ) ); + break; } if ( st_ivas->hEncoderConfig->Opt_SC_VBR && !hEncoderConfig->Opt_DTX_ON ) @@ -1565,30 +1566,33 @@ static ivas_error printConfigInfo_enc( return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "\nError: SC-VBR 5900 bps not supported without DTX\n\n" ); } + if ( hIvasEnc->maxBandwidthUser ) + { + fprintf( stdout, "\nBandwidth limited to %s.\n", max_bwidth_string ); + } + if ( hEncoderConfig->ivas_format == MONO_FORMAT ) { - if ( newBandwidthApi != hEncoderConfig->max_bwidth ) + if ( hEncoderConfig->max_bwidth == FB && hEncoderConfig->ivas_total_brate < ACELP_16k40 ) { - if ( newBandwidthApi == FB ) + fprintf( stdout, "\nFB coding not supported below %.2f kbps. ", ACELP_16k40 / 1000.f ); + if ( hEncoderConfig->ivas_total_brate < ACELP_9k60 ) { - fprintf( stdout, "\nFB coding not supported below %.2f kbps. ", ACELP_16k40 / 1000.f ); - if ( hEncoderConfig->max_bwidth == WB ) - { - fprintf( stdout, "Switching to WB.\n" ); - } - else - { - fprintf( stdout, "Switching to SWB.\n" ); - } + fprintf( stdout, "Switching to WB.\n" ); } - else if ( newBandwidthApi == SWB ) + else { - fprintf( stdout, "\nSWB coding not supported below %.2f kbps. Switching to WB.\n", ACELP_9k60 / 1000.f ); + fprintf( stdout, "Switching to SWB.\n" ); } } + if ( hEncoderConfig->max_bwidth == SWB && hEncoderConfig->ivas_total_brate < ACELP_9k60 ) + { + fprintf( stdout, "\nSWB coding not supported below %.2f kbps. Switching to WB.", ACELP_9k60 / 1000.f ); + } + /* in case of 8kHz input sampling or "-max_band NB", require the total bitrate to be below 24.40 kbps */ - if ( ( newBandwidthApi == NB || hEncoderConfig->input_Fs == 8000 ) && hEncoderConfig->ivas_total_brate > ACELP_24k40 ) + if ( ( hEncoderConfig->max_bwidth == NB || hEncoderConfig->input_Fs == 8000 ) && hEncoderConfig->ivas_total_brate > ACELP_24k40 ) { fprintf( stdout, "\nError: Unsupported mode NB %d bps, NB mode supports rates 5900-24400 bps\n\n", hEncoderConfig->ivas_total_brate ); return IVAS_ERR_INVALID_BITRATE; @@ -1596,7 +1600,7 @@ static ivas_error printConfigInfo_enc( } else { - if ( newBandwidthApi != hEncoderConfig->max_bwidth ) + if ( hEncoderConfig->max_bwidth == FB && hEncoderConfig->ivas_total_brate < MIN_BRATE_FB_STEREO ) { fprintf( stdout, "\nFB coding not supported below %.2f kbps. Switching to SWB.\n", MIN_BRATE_FB_STEREO / 1000.f ); } @@ -1808,97 +1812,29 @@ static ivas_error doCommonSetterChecks( /*---------------------------------------------------------------------* - * sanitizeBandwidth() + * updateBandwidthFromFs() * * *---------------------------------------------------------------------*/ -static ivas_error sanitizeBandwidth( - const IVAS_ENC_HANDLE hIvasEnc ) +static void updateBandwidthFromFs( + const ENCODER_CONFIG_HANDLE hEncoderConfig ) { - ENCODER_CONFIG_HANDLE hEncoderConfig; - int16_t max_bwidth_tmp; - - hEncoderConfig = hIvasEnc->st_ivas->hEncoderConfig; - - max_bwidth_tmp = hIvasEnc->newBandwidthApi; - /* Prevent st_ivas->max_bwidth from being higher than Fs/2 */ - if ( hEncoderConfig->input_Fs == 8000 && max_bwidth_tmp > NB ) - { - max_bwidth_tmp = NB; - } - else if ( hEncoderConfig->input_Fs == 16000 && max_bwidth_tmp > WB ) - { - max_bwidth_tmp = WB; - } - else if ( hEncoderConfig->input_Fs == 32000 && max_bwidth_tmp > SWB ) - { - max_bwidth_tmp = SWB; - } - - /* NB coding not supported in IVAS. Switching to WB. */ - if ( max_bwidth_tmp == NB && hEncoderConfig->ivas_format != UNDEFINED_FORMAT && hEncoderConfig->ivas_format != MONO_FORMAT ) - { - if ( hEncoderConfig->input_Fs >= 16000 ) - { - max_bwidth_tmp = WB; - } - else - { - return IVAS_ERR_INVALID_BITRATE; - } - } - - if ( hEncoderConfig->ivas_format == MONO_FORMAT ) + if ( hEncoderConfig->input_Fs == 8000 && hEncoderConfig->max_bwidth > NB ) { -#if 0 // IVAS_fmToDo: temporary disabled to keep EVS bit-exactness -> to be verified - if ( max_bwidth_tmp == FB && hEncoderConfig->ivas_total_brate < ACELP_16k40 ) - { - if ( hEncoderConfig->ivas_total_brate < ACELP_9k60 ) - { - max_bwidth_tmp = WB; - } - else - { - max_bwidth_tmp = SWB; - } - } - - if ( max_bwidth_tmp == SWB && hEncoderConfig->ivas_total_brate < ACELP_9k60 ) - { - max_bwidth_tmp = WB; - } - - /* in case of 8kHz input sampling or "-max_band NB", require the total bitrate to be below 24.40 kbps */ - if ( ( max_bwidth_tmp == NB || hEncoderConfig->input_Fs == 8000 ) && hEncoderConfig->ivas_total_brate > ACELP_24k40 ) - { - if ( hEncoderConfig->input_Fs >= 16000 ) - { - max_bwidth_tmp = WB; - } - else - { - return IVAS_ERR_INVALID_BITRATE; - } - } -#endif + hEncoderConfig->max_bwidth = NB; } - else + else if ( hEncoderConfig->input_Fs == 16000 && hEncoderConfig->max_bwidth > WB ) { - if ( max_bwidth_tmp == FB && hEncoderConfig->ivas_total_brate < MIN_BRATE_FB_STEREO ) - { - max_bwidth_tmp = SWB; - } + hEncoderConfig->max_bwidth = WB; } - - if ( hEncoderConfig->max_bwidth != max_bwidth_tmp ) + else if ( hEncoderConfig->input_Fs == 32000 && hEncoderConfig->max_bwidth > SWB ) { - hEncoderConfig->max_bwidth = max_bwidth_tmp; - hIvasEnc->switchingActive = true; + hEncoderConfig->max_bwidth = SWB; } - return IVAS_ERR_OK; + return; } @@ -1924,8 +1860,6 @@ static ivas_error setBandwidth( return error; } - hIvasEnc->newBandwidthApi = newBandwidth; - /* NB coding not supported in IVAS. Switching to WB. */ if ( newBandwidth == NB && hEncoderConfig->ivas_format != UNDEFINED_FORMAT && hEncoderConfig->ivas_format != MONO_FORMAT ) { @@ -1938,6 +1872,13 @@ static ivas_error setBandwidth( hIvasEnc->switchingActive = true; } + /* Limit bandwidth to half of sampling rate - only possible if + * sampling rate has already been set via configure function */ + if ( hIvasEnc->isConfigured ) + { + updateBandwidthFromFs( hIvasEnc->st_ivas->hEncoderConfig ); + } + return IVAS_ERR_OK; } @@ -2105,14 +2046,11 @@ static void init_encoder_config( ENCODER_CONFIG_HANDLE hEncoderConfig /* o : configuration structure */ ) { - hEncoderConfig->ivas_total_brate = ACELP_12k65; hEncoderConfig->max_bwidth = SWB; hEncoderConfig->input_Fs = 16000; hEncoderConfig->nchan_inp = 1; hEncoderConfig->element_mode_init = EVS_MONO; hEncoderConfig->ivas_format = UNDEFINED_FORMAT; - hEncoderConfig->Opt_SC_VBR = 0; - hEncoderConfig->last_Opt_SC_VBR = 0; hEncoderConfig->Opt_AMR_WB = 0; hEncoderConfig->Opt_DTX_ON = 0; hEncoderConfig->Opt_RF_ON = 0; diff --git a/lib_enc/tcx_utils_enc.c b/lib_enc/tcx_utils_enc.c old mode 100755 new mode 100644 index 9b272f0dee..ca88663355 --- a/lib_enc/tcx_utils_enc.c +++ b/lib_enc/tcx_utils_enc.c @@ -1509,11 +1509,7 @@ void ProcessStereoIGF( Encoder_State *sts[CPE_CHANNELS], /* i : Encoder state */ int16_t ms_mask[2][MAX_SFB], /* i : bandwise MS mask */ float *pITFMDCTSpectrum[CPE_CHANNELS][2], /* i : MDCT spectrum fir ITF */ -#ifdef DRAM_REDUCTION_MCT_IGF - float *pPowerSpectrum[CPE_CHANNELS], /* i/o: MDCT^2 + MDST^2 spectrum, or estimate */ -#else float pPowerSpectrum[CPE_CHANNELS][N_MAX], /* i : MDCT^2 + MDST^2 spectrum, or estimate */ -#endif float *pPowerSpectrumMsInv[CPE_CHANNELS][2], /* i : inverse power spectrum */ float *inv_spectrum[CPE_CHANNELS][2], /* i : inverse spectrum */ const int16_t frameno, /* i : flag indicating index of current subfr. */ diff --git a/lib_rend/ivas_crend.c b/lib_rend/ivas_crend.c index 785678535f..45a9e121ca 100644 --- a/lib_rend/ivas_crend.c +++ b/lib_rend/ivas_crend.c @@ -68,11 +68,7 @@ static ivas_error ivas_hrtf_init( hHrtf->gain_lfe = 0; hHrtf->index_frequency_max_diffuse = 0; -#ifdef FIX_CREND_CHANNELS - for ( i = 0; i < MAX_TRANSPORT_CHANNELS; i++ ) -#else for ( i = 0; i < IVAS_MAX_NUM_CH; i++ ) -#endif { hHrtf->inv_diffuse_weight[i] = 0; for ( j = 0; j < BINAURAL_CHANNELS; j++ ) @@ -677,11 +673,7 @@ ivas_error ivas_crend_open( hCrend->lfe_delay_line = NULL; -#ifdef FIX_CREND_CHANNELS - for ( i = 0; i < MAX_TRANSPORT_CHANNELS; i++ ) -#else for ( i = 0; i < IVAS_MAX_NUM_CH; i++ ) -#endif { hCrend->freq_buffer_re[i] = NULL; hCrend->freq_buffer_im[i] = NULL; @@ -832,11 +824,7 @@ ivas_error ivas_crend_close( { if ( st_ivas->renderer_type != RENDERER_BINAURAL_OBJECTS_TD ) { -#ifdef FIX_CREND_CHANNELS - for ( i = 0; i < MAX_TRANSPORT_CHANNELS; i++ ) -#else for ( i = 0; i < IVAS_MAX_NUM_CH; i++ ) -#endif { if ( st_ivas->hCrend->freq_buffer_re[i] != NULL ) { @@ -1135,7 +1123,5 @@ ivas_error ivas_crend_process( mvr2r( pcm_tmp[i], output[i], output_frame ); } - wmops_sub_end(); - return IVAS_ERR_OK; } diff --git a/lib_rend/ivas_hrtf.c b/lib_rend/ivas_hrtf.c index 7c4183b0e8..8b5f1ba217 100644 --- a/lib_rend/ivas_hrtf.c +++ b/lib_rend/ivas_hrtf.c @@ -74,7 +74,7 @@ void BSplineModelEvalAlloc( * Init default HRTF model --------------------------------------------------------------------*/ -void DefaultBSplineModel( +ivas_error DefaultBSplineModel( TDREND_HRFILT_FiltSet_t *HrFiltSet_p, /* o : Loaded HR filter set */ const int32_t output_Fs /* i : Output sampling rate */ ) @@ -215,7 +215,7 @@ void DefaultBSplineModel( HrFiltSet_p->FiltLength = HrFiltSet_p->ModelParams.K; BSplineModelEvalAlloc( &HrFiltSet_p->ModelParams, &HrFiltSet_p->ModelEval ); - return; + return IVAS_ERR_OK; } diff --git a/lib_rend/ivas_objectRenderer.c b/lib_rend/ivas_objectRenderer.c index b4c784edfa..153c6d7f2d 100644 --- a/lib_rend/ivas_objectRenderer.c +++ b/lib_rend/ivas_objectRenderer.c @@ -45,17 +45,8 @@ /*---------------------------------------------------------------------* * Local function prototypes *---------------------------------------------------------------------*/ - -#ifdef FIX_I106_TDREND_5MS -static ivas_error TDREND_GetMix( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, float output[][L_FRAME48k], const int16_t subframe_length, const int32_t output_Fs, const int16_t subframe_idx ); -#else static ivas_error TDREND_GetMix( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, float output[][L_FRAME48k], const int16_t output_frame, const int32_t output_Fs ); -#endif static void TDREND_Clear_Update_flags( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd ); -#ifdef FIX_I106_TDREND_5MS -static void TDREND_Update_listener_orientation( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, const int16_t headRotEnabled, const Quaternion *headPosition ); -static void TDREND_Update_object_positions( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, const int16_t numSources, const IVAS_FORMAT in_format, const ISM_METADATA_HANDLE *hIsmMetaData, float output[][L_FRAME48k] ); -#endif /*---------------------------------------------------------------------* * ivas_td_binaural_open() @@ -63,6 +54,7 @@ static void TDREND_Update_object_positions( BINAURAL_TD_OBJECT_RENDERER_HANDLE h * Open and initialize TD Object binaural renderer *---------------------------------------------------------------------*/ +/*! r: TD Renderer result code. */ ivas_error ivas_td_binaural_open( Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ ) @@ -227,13 +219,13 @@ void ivas_td_binaural_close( * and renders the current frame. *---------------------------------------------------------------------*/ -void ObjRenderIVASFrame( +/*! r: TD Renderer result code. */ +ivas_error ObjRenderIVASFrame( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ float output[][L_FRAME48k], /* i/o: SCE channels / Binaural synthesis */ const int16_t output_frame /* i : output frame length */ ) { -#ifndef FIX_I106_TDREND_5MS TDREND_DirAtten_t *DirAtten_p; int16_t nS; float Pos[3]; @@ -242,15 +234,9 @@ void ObjRenderIVASFrame( float UpVec[3]; float Rmat[3][3]; int16_t c_indx; -#else - int16_t subframe_length; -#endif int16_t subframe_idx; float reverb_signal[BINAURAL_CHANNELS][L_FRAME48k]; -#ifdef FIX_I106_TDREND_5MS - subframe_length = output_frame / MAX_PARAM_SPATIAL_SUBFRAMES; -#else DirAtten_p = st_ivas->hBinRendererTd->DirAtten_p; /* Update the listener's location/orientation */ @@ -328,16 +314,8 @@ void ObjRenderIVASFrame( TDREND_MIX_SRC_SetPlayState( st_ivas->hBinRendererTd, nS, TDREND_PLAYSTATUS_PLAYING ); } } -#endif if ( st_ivas->hRenderConfig != NULL ) /* Renderer Configuration not enabled in TD standalone renderer */ { - -#ifdef FIX_I106_TDREND_5MS - if ( st_ivas->hRenderConfig->roomAcoustics.late_reverb_on && ( st_ivas->ini_frame == 0 ) ) - { - ivas_reverb_open( &st_ivas->hCrend->hReverb, st_ivas->transport_config, NULL, st_ivas->hRenderConfig, st_ivas->hDecoderConfig->output_Fs ); - } -#else if ( st_ivas->hRenderConfig->roomAcoustics.late_reverb_on ) { if ( st_ivas->ini_frame == 0 ) @@ -349,33 +327,10 @@ void ObjRenderIVASFrame( ivas_reverb_process( st_ivas->hCrend->hReverb, st_ivas->transport_config, 0, output, reverb_signal, subframe_idx ); } } -#endif } -#ifdef FIX_I106_TDREND_5MS - /* Update object position(s) */ - TDREND_Update_object_positions( st_ivas->hBinRendererTd, st_ivas->nchan_transport, st_ivas->ivas_format, st_ivas->hIsmMetaData, output ); - - for ( subframe_idx = 0; subframe_idx < MAX_PARAM_SPATIAL_SUBFRAMES; subframe_idx++ ) - { - /* Update the listener's location/orientation */ - TDREND_Update_listener_orientation( st_ivas->hBinRendererTd, - st_ivas->hDecoderConfig->Opt_Headrotation, - ( st_ivas->hHeadTrackData != NULL ) ? &st_ivas->hHeadTrackData->Quaternions[subframe_idx] : NULL ); - - if ( ( st_ivas->hRenderConfig != NULL ) && ( st_ivas->hRenderConfig->roomAcoustics.late_reverb_on ) ) - { - ivas_reverb_process( st_ivas->hCrend->hReverb, st_ivas->transport_config, 0, output, reverb_signal, subframe_idx ); - } - - /* Render subframe */ - TDREND_GetMix( st_ivas->hBinRendererTd, output, subframe_length, st_ivas->hDecoderConfig->output_Fs, subframe_idx ); - } -#else /* Call the renderer */ TDREND_GetMix( st_ivas->hBinRendererTd, output, output_frame, st_ivas->hDecoderConfig->output_Fs ); -#endif - if ( st_ivas->hRenderConfig != NULL ) /* Renderer Configuration not enabled in TD standalone renderer */ { if ( st_ivas->hRenderConfig->roomAcoustics.late_reverb_on ) @@ -385,58 +340,36 @@ void ObjRenderIVASFrame( v_add( reverb_signal[1], output[1], output[1], output_frame ); } } - - return; + return IVAS_ERR_OK; } -#ifdef FIX_I106_TDREND_5MS -/*---------------------------------------------------------------------* - * TDREND_GetMix() - * - * Render one 5 ms subframe from the mixer - *---------------------------------------------------------------------*/ -#else /*---------------------------------------------------------------------* * TDREND_GetMix() * * Render one output frame from the mixer *---------------------------------------------------------------------*/ -#endif + +/*! r: TD Renderer result code. */ static ivas_error TDREND_GetMix( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ float output[][L_FRAME48k], /* i/o: ISm object synth / rendered output in 0,1 */ -#ifdef FIX_I106_TDREND_5MS - const int16_t subframe_length, /* i/o: subframe length */ - const int32_t output_Fs, /* i : Output sampling rate */ - const int16_t subframe_idx /* i : Subframe index to 5 ms subframe */ -#else - const int16_t output_frame, /* i/o: Output frame length */ - const int32_t output_Fs /* i : Output sampling rate */ -#endif + const int16_t output_frame, /* i/o: Output frame length */ + const int32_t output_Fs /* i : Output sampling rate */ ) { int16_t i; TDREND_SRC_t *Src_p; TDREND_SRC_SPATIAL_t *SrcSpatial_p; TDREND_SRC_REND_t *SrcRend_p; - ivas_error error; -#ifdef FIX_I106_TDREND_5MS - float output_buf[2][L_SPATIAL_SUBFR_48k]; /* Temp buffer for left/right rendered signal */ -#else + ivas_error result; float output_buf[2][L_FRAME48k]; /* Temp buffer for left/right rendered signal */ -#endif - error = IVAS_ERR_OK; -#ifdef FIX_I106_TDREND_5MS - /* Clear the output buffer to accumulate rendered sources */ - set_f( output_buf[0], 0.0f, subframe_length ); - set_f( output_buf[1], 0.0f, subframe_length ); -#else + result = IVAS_ERR_OK; + /* Zero out the output buffer since objects are accumulated. */ set_f( output_buf[0], 0.0f, output_frame ); set_f( output_buf[1], 0.0f, output_frame ); -#endif /* Create the mix */ /* Loop through the source list and render each source */ @@ -455,42 +388,23 @@ static ivas_error TDREND_GetMix( /* Render source if needed */ if ( ( SrcRend_p->InputAvailable == TRUE ) && ( SrcRend_p->PlayStatus == TDREND_PLAYSTATUS_PLAYING ) ) { -#ifdef FIX_I106_TDREND_5MS -#ifdef TDREND_HRTF_TABLE_METHODS - error = TDREND_REND_RenderSourceHRFilt( Src_p, hBinRendererTd, output_buf, subframe_length, output_Fs ); -#else - error = TDREND_REND_RenderSourceHRFilt( Src_p, output_buf, subframe_length, output_Fs ); -#endif -#else #ifdef TDREND_HRTF_TABLE_METHODS - error = TDREND_REND_RenderSourceHRFilt( Src_p, hBinRendererTd, output_buf, output_frame, output_Fs ); + result = TDREND_REND_RenderSourceHRFilt( Src_p, hBinRendererTd, output_buf, output_frame, output_Fs ); #else - error = TDREND_REND_RenderSourceHRFilt( Src_p, output_buf, output_frame, output_Fs ); -#endif + result = TDREND_REND_RenderSourceHRFilt( Src_p, output_buf, output_frame, output_Fs ); #endif } -#ifndef FIX_I106_TDREND_5MS SrcRend_p->InputAvailable = FALSE; -#endif } /* Populate output variable */ -#ifdef FIX_I106_TDREND_5MS - mvr2r( output_buf[0], output[0] + subframe_idx * subframe_length, subframe_length ); /* Left */ - mvr2r( output_buf[1], output[1] + subframe_idx * subframe_length, subframe_length ); /* Right */ -#else mvr2r( output_buf[0], output[0], output_frame ); /* Left */ mvr2r( output_buf[1], output[1], output_frame ); /* Right */ -#endif -#ifdef FIX_I106_TDREND_5MS - /* Clear the PoseUpdated and Source position update flags */ -#else - /* Clear the mixer update flags */ -#endif + /* Clear the mixer update flags */ TDREND_Clear_Update_flags( hBinRendererTd ); - return error; + return result; } @@ -507,129 +421,9 @@ static void TDREND_Clear_Update_flags( int16_t i; hBinRendererTd->Listener_p->PoseUpdated = FALSE; - for ( i = 0; i < hBinRendererTd->NumOfSrcs; i++ ) { hBinRendererTd->Sources[i]->SrcSpatial_p->Updated = FALSE; } - - return; -} - -#ifdef FIX_I106_TDREND_5MS -/*---------------------------------------------------------------------* - * TDREND_Update_object_positions() - * - * Update object position(s) - *---------------------------------------------------------------------*/ - -static void TDREND_Update_object_positions( - BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o : TD Renderer handle */ - const int16_t numSources, /* i : Number of sources to render */ - const IVAS_FORMAT in_format, /* i : Format of input sources */ - const ISM_METADATA_HANDLE *hIsmMetaData, /* i : Input metadata for ISM objects */ - float output[][L_FRAME48k] /* i/o: SCE/MC channels */ -) -{ - TDREND_DirAtten_t *DirAtten_p; - int16_t nS; - float Pos[3]; - float Dir[3]; - int16_t c_indx; - - DirAtten_p = hBinRendererTd->DirAtten_p; - - /* For each source, write the frame data to the source object*/ - c_indx = 0; - for ( nS = 0; nS < numSources; nS++ ) - { - if ( !( in_format == MC_FORMAT && nS == LFE_CHANNEL ) ) /* Skip LFE for MC */ - { - hBinRendererTd->Sources[c_indx]->InputFrame_p = output[nS]; - hBinRendererTd->Sources[c_indx]->SrcRend_p->InputAvailable = TRUE; - c_indx++; - } - - if ( in_format == ISM_FORMAT ) - { - - /* Update the source positions */ - /* Source position and direction */ - Pos[0] = cosf( hIsmMetaData[nS]->elevation * PI_OVER_180 ) * cosf( hIsmMetaData[nS]->azimuth * PI_OVER_180 ); - Pos[1] = cosf( hIsmMetaData[nS]->elevation * PI_OVER_180 ) * sinf( hIsmMetaData[nS]->azimuth * PI_OVER_180 ); - Pos[2] = sinf( hIsmMetaData[nS]->elevation * PI_OVER_180 ); - Dir[0] = 1.0f; - Dir[1] = 0.0f; - Dir[2] = 0.0f; - - /* Source directivity info */ - DirAtten_p->ConeInnerAngle = 360.0f; - DirAtten_p->ConeOuterAngle = 360.0f; - DirAtten_p->ConeOuterGain = 1.0f; - - TDREND_MIX_SRC_SetPos( hBinRendererTd, nS, Pos ); - TDREND_MIX_SRC_SetDirAtten( hBinRendererTd, nS, DirAtten_p ); - TDREND_MIX_SRC_SetPlayState( hBinRendererTd, nS, TDREND_PLAYSTATUS_PLAYING ); - - TDREND_MIX_SRC_SetDir( hBinRendererTd, nS, Dir ); - } - } - - return; -} - -/*---------------------------------------------------------------------* - * TDREND_Update_listener_orientation() - * - * Update listener orientation (s) - *---------------------------------------------------------------------*/ - -static void TDREND_Update_listener_orientation( - BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD Renderer handle */ - const int16_t headRotEnabled, /* i : Headrotation flag */ - const Quaternion *headPosition /* i : Head Position */ -) -{ - float Pos[3]; - float FrontVec[3]; - float UpVec[3]; - float Rmat[3][3]; - - /* Update the listener's location/orientation */ - /* Listener at the origin */ - Pos[0] = 0.0f; - Pos[1] = 0.0f; - Pos[2] = 0.0f; - - if ( headRotEnabled ) - { - /* Obtain head rotation matrix */ - QuatToRotMat( *headPosition, Rmat ); - /* Apply rotation matrix to looking vector [1;0;0] */ - FrontVec[0] = Rmat[0][0]; - FrontVec[1] = Rmat[0][1]; - FrontVec[2] = Rmat[0][2]; - /* Apply rotation matrix to up vector [0;0;1] */ - UpVec[0] = Rmat[2][0]; - UpVec[1] = Rmat[2][1]; - UpVec[2] = Rmat[2][2]; - } - else - { - /* Oriented with looking vector along the x axis */ - FrontVec[0] = 1.0f; - FrontVec[1] = 0.0f; - FrontVec[2] = 0.0f; - /* Oriented with up vector along the z axis */ - UpVec[0] = 0.0f; - UpVec[1] = 0.0f; - UpVec[2] = 1.0f; - } - - /* Set the listener position and orientation:*/ - TDREND_MIX_LIST_SetPos( hBinRendererTd, Pos ); - TDREND_MIX_LIST_SetOrient( hBinRendererTd, FrontVec, UpVec ); - return; } -#endif diff --git a/lib_rend/ivas_objectRenderer_hrFilt.c b/lib_rend/ivas_objectRenderer_hrFilt.c index eb69350d48..4ece382b4f 100644 --- a/lib_rend/ivas_objectRenderer_hrFilt.c +++ b/lib_rend/ivas_objectRenderer_hrFilt.c @@ -343,42 +343,24 @@ void TDREND_HRFILT_SetFiltSet( --------------------------------------------------------------------*/ ivas_error TDREND_REND_RenderSourceHRFilt( -#ifdef FIX_I106_TDREND_5MS - TDREND_SRC_t *Src_p, /* i/o: The source to be rendered */ -#else - const TDREND_SRC_t *Src_p, /* i/o: The source to be rendered */ -#endif + const TDREND_SRC_t *Src_p, /* i/o: The source to be rendered */ #ifdef TDREND_HRTF_TABLE_METHODS BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ #endif -#ifdef FIX_I106_TDREND_5MS - float output_buf[][L_SPATIAL_SUBFR_48k], /* o : Output buffer */ - const int16_t subframe_length, /* i : Subframe length in use */ -#else float output_buf[][L_FRAME48k], /* o : Output buffer */ const int16_t output_frame, /* i : Output frame length in use */ -#endif - - const int32_t output_Fs /* i : Output sample rate */ + const int32_t output_Fs /* i : Output sample rate */ ) { + ivas_error SFX_Result; TDREND_SRC_REND_t *SrcRend_p; -#ifdef FIX_I106_TDREND_5MS - const float *InFrame_nIC_p; -#else int16_t nS; float *InFrame_nIC_p; -#endif int16_t NoOfUsedInputSamples, NoOfDeliveredOutputSamples; -#ifdef FIX_I106_TDREND_5MS - float LeftOutputFrame[L_SPATIAL_SUBFR_48k]; - float RightOutputFrame[L_SPATIAL_SUBFR_48k]; -#else float LeftOutputFrame[L_FRAME48k]; float RightOutputFrame[L_FRAME48k]; float *LeftOutputFrame_p, *RightOutputFrame_p; float *LeftAccOutputFrame_p, *RightAccOutputFrame_p; -#endif /* Input channel rendering loop */ InFrame_nIC_p = Src_p->InputFrame_p; @@ -388,11 +370,9 @@ ivas_error TDREND_REND_RenderSourceHRFilt( /* SrcGain = Mix_p->Gain * ( *SrcRend_p->SrcGain_p ); */ /* SrcGain *= ( *SrcRend_p->DirGain_p ) * ( *SrcRend_p->DistGain_p ); */ -#ifdef FIX_I106_TDREND_5MS - TDREND_SFX_SpatBin_Execute_Main( SrcRend_p->SfxSpatBin_p, InFrame_nIC_p, subframe_length, LeftOutputFrame, RightOutputFrame, &NoOfUsedInputSamples, &NoOfDeliveredOutputSamples, output_Fs ); -#else - TDREND_SFX_SpatBin_Execute_Main( SrcRend_p->SfxSpatBin_p, InFrame_nIC_p, output_frame, LeftOutputFrame, RightOutputFrame, &NoOfUsedInputSamples, &NoOfDeliveredOutputSamples, output_Fs ); -#endif + SFX_Result = TDREND_SFX_SpatBin_Execute_Main( SrcRend_p->SfxSpatBin_p, InFrame_nIC_p, output_frame, + LeftOutputFrame, RightOutputFrame, + &NoOfUsedInputSamples, &NoOfDeliveredOutputSamples, output_Fs ); #ifdef TDREND_HRTF_TABLE_METHODS if ( hBinRendererTd->HrFiltSet_p->FilterMethod != TDREND_HRFILT_Method_BSplineModel ) @@ -402,27 +382,17 @@ ivas_error TDREND_REND_RenderSourceHRFilt( #endif /* Copy to accumulative output frame */ -#ifdef FIX_I106_TDREND_5MS - v_add( LeftOutputFrame, output_buf[0], output_buf[0], subframe_length ); - v_add( RightOutputFrame, output_buf[1], output_buf[1], subframe_length ); - - Src_p->InputFrame_p += subframe_length; /* Increment input pointer -- todo: should we remove this and input the current subframe instead? */ - -#else LeftOutputFrame_p = LeftOutputFrame; RightOutputFrame_p = RightOutputFrame; LeftAccOutputFrame_p = output_buf[0]; RightAccOutputFrame_p = output_buf[1]; - for ( nS = 0; nS < output_frame; nS++ ) { *LeftAccOutputFrame_p++ += *LeftOutputFrame_p++; *RightAccOutputFrame_p++ += *RightOutputFrame_p++; } -#endif - - return IVAS_ERR_OK; + return SFX_Result; } diff --git a/lib_rend/ivas_objectRenderer_mix.c b/lib_rend/ivas_objectRenderer_mix.c index df190b91b1..61553ca4fc 100644 --- a/lib_rend/ivas_objectRenderer_mix.c +++ b/lib_rend/ivas_objectRenderer_mix.c @@ -46,7 +46,8 @@ * Sets the listener's position in the specified mixer unit. --------------------------------------------------------------------*/ -void TDREND_MIX_LIST_SetPos( +/*! r: TD Renderer result code. */ +ivas_error TDREND_MIX_LIST_SetPos( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ const float *Pos_p /* i : Listener's position */ ) @@ -64,7 +65,7 @@ void TDREND_MIX_LIST_SetPos( Listener_p->PoseUpdated = TRUE; } - return; + return IVAS_ERR_OK; } @@ -74,6 +75,7 @@ void TDREND_MIX_LIST_SetPos( * Sets the listener's orientation vectors in the specified mixer unit. --------------------------------------------------------------------*/ +/*! r: TD Renderer result code. */ ivas_error TDREND_MIX_LIST_SetOrient( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ const float *FrontVec_p, /* i : Listener's orientation front vector */ @@ -191,6 +193,7 @@ void TDREND_MIX_Dealloc( * Initializes the mixer and sets HRTF --------------------------------------------------------------------*/ +/*! r: TD Renderer result code. */ ivas_error TDREND_MIX_Init( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ TDREND_HRFILT_FiltSet_t **hHrtfTD, /* i/o: HRTF data (initialized in case of NULL) */ @@ -253,6 +256,7 @@ ivas_error TDREND_MIX_Init( * Set the distance attenuation model of the mixer --------------------------------------------------------------------*/ +/*! r: TD Renderer result code. */ ivas_error TDREND_MIX_SetDistAttenModel( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ const TDREND_DistAttenModel_t DistAttenModel /* i : Distance attenuation model */ @@ -287,6 +291,7 @@ ivas_error TDREND_MIX_SetDistAttenModel( * Adds the specified input source unit to the specified mixer unit. --------------------------------------------------------------------*/ +/*! r: TD Renderer result code. */ ivas_error TDREND_MIX_AddSrc( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ int16_t *SrcInd, /* o : Source index */ diff --git a/lib_rend/ivas_objectRenderer_sfx.c b/lib_rend/ivas_objectRenderer_sfx.c index 08239e8565..45ac83a4ae 100644 --- a/lib_rend/ivas_objectRenderer_sfx.c +++ b/lib_rend/ivas_objectRenderer_sfx.c @@ -70,7 +70,7 @@ static void TDREND_FirFilterRev( float *OutputFrame_p, float *FirFilterRev_p, co #ifdef TDREND_HRTF_TABLE_METHODS static void TDREND_FirFilterRevInterp( float *OutputFrame_p, float *FirFilterRev_p, const int16_t FirFilterLength, float *InputFrame_p, const int16_t NumOfSamples, float *FilterStored ); #endif -static void TDREND_SFX_SpatBin_Clear( SFX_SpatBin_t *SfxSpatBin_p, const int32_t output_Fs ); +static ivas_error TDREND_SFX_SpatBin_Clear( SFX_SpatBin_t *SfxSpatBin_p, const int32_t output_Fs ); /*-------------------------------------------------------------------* @@ -352,7 +352,8 @@ static void TDREND_SFX_SpatBin_Resampling( * --------------------------------------------------------------------*/ -void TDREND_SFX_SpatBin_SetParams( +/*! r: TD Renderer result code. */ +ivas_error TDREND_SFX_SpatBin_SetParams( SFX_SpatBin_t *SfxSpatBin_p, /* i/o: Spatial parameters struct to be updated */ const SFX_SpatBin_Params_t *NewParam_p, /* i : New parameters struct */ const int32_t output_Fs /* i : Output sample rate */ @@ -396,7 +397,7 @@ void TDREND_SFX_SpatBin_SetParams( SfxSpatBin_p->OpMode = SFX_OFF; } - return; + return IVAS_ERR_OK; } @@ -553,7 +554,6 @@ static void TDREND_SFX_SpatBin_SetParamsInitializeOff( SfxSpatBin_p->NoOfLeftOldBufferSamples = SFX_SPAT_BIN_SINC_M - 1 + TDREND_MaxITD[i]; SfxSpatBin_p->NoOfRightOldBufferSamples = SFX_SPAT_BIN_SINC_M - 1 + TDREND_MaxITD[i]; SfxSpatBin_p->Left_Tf = 0.0; - return; } @@ -925,16 +925,14 @@ static void TDREND_SFX_SpatBin_UpdateParams( * TDREND_SFX_SpatBin_Execute_Main() * * The main rendering function that is called from the Audio Mixer. + * --------------------------------------------------------------------*/ -void TDREND_SFX_SpatBin_Execute_Main( - SFX_SpatBin_t *SfxSpatBin_p, /* i/o: Spatial parameters struct */ - const float *InBuffer_p, /* i : Input buffer */ -#ifdef FIX_I106_TDREND_5MS - const int16_t subframe_length, /* i : subframe length */ -#else - const int16_t output_frame, /* i : frame length */ -#endif +/*! r: TD Renderer result code. */ +ivas_error TDREND_SFX_SpatBin_Execute_Main( + SFX_SpatBin_t *SfxSpatBin_p, /* i/o: Spatial parameters struct */ + const float *InBuffer_p, /* i : Input buffer */ + const int16_t output_frame, /* i : frame length */ float *LeftOutBuffer_p, /* o : Rendered left channel */ float *RightOutBuffer_p, /* o : Rendered right channel */ int16_t *NoOfUsedInputSamples_p, /* o : Number of input samples actually used */ @@ -952,11 +950,7 @@ void TDREND_SFX_SpatBin_Execute_Main( /* Make sure the blocks are not longer than 6 msec. */ NoOfBlocks = 1; -#ifdef FIX_I106_TDREND_5MS - TempNoOfRequestedOutputSamples = subframe_length; -#else TempNoOfRequestedOutputSamples = output_frame; -#endif while ( TempNoOfRequestedOutputSamples > SfxSpatBin_p->MaxBlockLength ) { NoOfBlocks = NoOfBlocks << 1; @@ -970,11 +964,7 @@ void TDREND_SFX_SpatBin_Execute_Main( RightOutBufferPointer_p = RightOutBuffer_p; *NoOfUsedInputSamples_p = 0; *NoOfDeliveredOutputSamples_p = 0; -#ifdef FIX_I106_TDREND_5MS - TempNoOfInputSamples = subframe_length; -#else TempNoOfInputSamples = output_frame; -#endif for ( i = 0; i < NoOfBlocks; i++ ) { @@ -1003,17 +993,13 @@ void TDREND_SFX_SpatBin_Execute_Main( if ( i == NoOfBlocks - 2 ) { /* The last block should produce the remaining number of samples */ -#ifdef FIX_I106_TDREND_5MS - TempNoOfRequestedOutputSamples = subframe_length - *NoOfDeliveredOutputSamples_p; -#else TempNoOfRequestedOutputSamples = output_frame - *NoOfDeliveredOutputSamples_p; -#endif } *NoOfUsedInputSamples_p = *NoOfUsedInputSamples_p + TempNoOfUsedInputSamples; TempNoOfInputSamples = TempNoOfInputSamples - TempNoOfUsedInputSamples; } - return; + return IVAS_ERR_OK; } @@ -1196,7 +1182,7 @@ static void TDREND_SFX_SpatBin_Execute( } /* Update number of old samples */ - SfxSpatBin_p->NoOfRightOldBufferSamples = *NoOfUsedInputSamples_p - Ind; + SfxSpatBin_p->NoOfRightOldBufferSamples = *NoOfUsedInputSamples_p - (int16_t) Ind; return; } @@ -1209,6 +1195,7 @@ static void TDREND_SFX_SpatBin_Execute( * --------------------------------------------------------------------*/ +/*! r: TD Renderer result code. */ ivas_error TDREND_SFX_SpatBin_Initialize( SFX_SpatBin_t *SfxSpatBin_p, /* i/o: Spatial parameters struct */ const int32_t output_Fs /* i : Output sampling rate */ @@ -1291,21 +1278,19 @@ ivas_error TDREND_SFX_SpatBin_Initialize( * --------------------------------------------------------------------*/ -static void TDREND_SFX_SpatBin_Clear( +/*! r: TD Renderer result code. */ +static ivas_error TDREND_SFX_SpatBin_Clear( SFX_SpatBin_t *SfxSpatBin_p, /* i/o: Spatial parameters struct */ const int32_t output_Fs /* i : Output sample rate */ ) { int16_t i; int16_t MaxITD = TDREND_MaxITD[2]; - SfxSpatBin_p->OpMode = SFX_OFF; SfxSpatBin_p->TurningOffEffect = FALSE; SfxSpatBin_p->TurningOnEffect = FALSE; - /* Init during next SetParams-call */ SfxSpatBin_p->InitializeParams = TRUE; - /* Fill old buffers with zeros */ switch ( output_Fs ) { @@ -1331,7 +1316,7 @@ static void TDREND_SFX_SpatBin_Clear( SfxSpatBin_p->ResampledBufferRight[i] = 0.0f; } - return; + return IVAS_ERR_OK; } diff --git a/lib_rend/ivas_objectRenderer_sources.c b/lib_rend/ivas_objectRenderer_sources.c index a9e88602ca..b24708a195 100644 --- a/lib_rend/ivas_objectRenderer_sources.c +++ b/lib_rend/ivas_objectRenderer_sources.c @@ -55,13 +55,14 @@ static void TDREND_SRC_REND_Init( TDREND_SRC_REND_t *SrcRend_p, const int32_t ou /*-------------------------------------------------------------------* - * TDREND_MIX_SRC_SetPos() + * TDREND_MIX_SetSrcPos() * * Set source position --------------------------------------------------------------------*/ +/*! r: TD Renderer result code. */ ivas_error TDREND_MIX_SRC_SetPos( - BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ + BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ const int16_t SrcInd, /* i : Source index */ const float *Vec_p /* i : Position vector */ ) @@ -93,6 +94,7 @@ ivas_error TDREND_MIX_SRC_SetPos( * Set source direciton --------------------------------------------------------------------*/ +/*! r: TD Renderer result code. */ ivas_error TDREND_MIX_SRC_SetDir( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ const int16_t SrcInd, /* i : Source index */ @@ -127,6 +129,7 @@ ivas_error TDREND_MIX_SRC_SetDir( * Set directional attenuation for the mixer. --------------------------------------------------------------------*/ +/*! r: TD Renderer result code. */ ivas_error TDREND_MIX_SRC_SetDirAtten( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ const int16_t SrcInd, /* i : Source index */ @@ -143,7 +146,6 @@ ivas_error TDREND_MIX_SRC_SetDirAtten( SrcSpatial_p = hBinRendererTd->Sources[SrcInd]->SrcSpatial_p; TDREND_SRC_SPATIAL_SetDirAtten( SrcSpatial_p, DirAtten_p ); } - return IVAS_ERR_OK; } @@ -154,6 +156,7 @@ ivas_error TDREND_MIX_SRC_SetDirAtten( * Set play state for the source. --------------------------------------------------------------------*/ +/*! r: TD Renderer result code. */ ivas_error TDREND_MIX_SRC_SetPlayState( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ const int16_t SrcInd, /* i : Source index */ @@ -178,6 +181,7 @@ ivas_error TDREND_MIX_SRC_SetPlayState( * Renderer allocation --------------------------------------------------------------------*/ +/*! r: TD Renderer result code. */ static ivas_error TDREND_SRC_REND_Alloc( TDREND_SRC_REND_t **SrcRend_pp /* i/o: Source object */ ) @@ -437,6 +441,7 @@ void TDREND_SRC_REND_UpdateFiltersFromSpatialParams( * Allocatie spatial properties of a source. --------------------------------------------------------------------*/ +/*! r: TD Renderer result code. */ static ivas_error TDREND_SRC_SPATIAL_Alloc( TDREND_SRC_SPATIAL_t **SrcSpatial_pp /* i/o: Source spatial parameters */ ) @@ -646,6 +651,7 @@ static float TDREND_SRC_SPATIAL_GetDistGain( * Allocate a source. --------------------------------------------------------------------*/ +/*! r: TD Renderer result code. */ ivas_error TDREND_SRC_Alloc( TDREND_SRC_t **Src_pp /* i/o: Source */ ) diff --git a/lib_rend/ivas_output_init.c b/lib_rend/ivas_output_init.c index b7af932861..fcaa6f9442 100644 --- a/lib_rend/ivas_output_init.c +++ b/lib_rend/ivas_output_init.c @@ -263,7 +263,9 @@ void ivas_renderer_select( AUDIO_CONFIG output_config; AUDIO_CONFIG transport_config; +#ifdef FIX_I87 int16_t nchan_internal; +#endif renderer_type = &( st_ivas->renderer_type ); internal_config = &( st_ivas->intern_config ); @@ -358,7 +360,12 @@ void ivas_renderer_select( if ( st_ivas->hDecoderConfig->Opt_Headrotation ) { +#ifdef FIX_I87 +#ifdef SBA_ORDER_BITSTREAM nchan_internal = ivas_sba_get_nchan_metadata( st_ivas->sba_analysis_order ); +#else + nchan_internal = ivas_sba_get_nchan_metadata( st_ivas->sba_order ); +#endif if ( nchan_internal == 2 ) { st_ivas->hHeadTrackData->shd_rot_max_order = 1; @@ -375,6 +382,24 @@ void ivas_renderer_select( { st_ivas->hHeadTrackData->shd_rot_max_order = 3; } +#else + if ( st_ivas->nchan_transport == 2 ) + { + st_ivas->hHeadTrackData->shd_rot_max_order = 1; + } + else if ( st_ivas->nchan_transport == 4 || st_ivas->nchan_transport == 3 ) + { + st_ivas->hHeadTrackData->shd_rot_max_order = 0; + } + else if ( st_ivas->nchan_transport == 6 || st_ivas->nchan_transport == 5 ) + { + st_ivas->hHeadTrackData->shd_rot_max_order = 2; + } + else if ( st_ivas->nchan_transport == 8 || st_ivas->nchan_transport == 7 ) + { + st_ivas->hHeadTrackData->shd_rot_max_order = 3; + } +#endif } } else if ( st_ivas->ivas_format == MC_FORMAT ) @@ -511,14 +536,7 @@ void ivas_renderer_select( if ( st_ivas->ivas_format == SBA_FORMAT && st_ivas->sba_mode == SBA_MODE_SPAR && ( output_config != AUDIO_CONFIG_5_1 && output_config != AUDIO_CONFIG_5_1_2 && output_config != AUDIO_CONFIG_5_1_4 && output_config != AUDIO_CONFIG_7_1 && output_config != AUDIO_CONFIG_7_1_4 && output_config != AUDIO_CONFIG_LS_CUSTOM ) ) { - if ( output_config == AUDIO_CONFIG_HOA2 || output_config == AUDIO_CONFIG_FOA ) - { - *internal_config = output_config; - } - else - { - *internal_config = AUDIO_CONFIG_HOA3; - } + *internal_config = AUDIO_CONFIG_HOA3; st_ivas->renderer_type = RENDERER_SBA_LINEAR_DEC; } else if ( ( st_ivas->ivas_format == MASA_FORMAT && output_config == AUDIO_CONFIG_MONO && st_ivas->nchan_transport == 1 ) || @@ -526,11 +544,7 @@ void ivas_renderer_select( { *renderer_type = RENDERER_DISABLE; } -#ifdef ALIGN_SID_SIZE - else if ( ( st_ivas->ivas_format == MASA_FORMAT && output_config == AUDIO_CONFIG_MONO && st_ivas->hDecoderConfig->ivas_total_brate < MASA_STEREO_MIN_BITRATE && st_ivas->hDecoderConfig->ivas_total_brate > IVAS_SID_5k2 ) ) -#else else if ( ( st_ivas->ivas_format == MASA_FORMAT && output_config == AUDIO_CONFIG_MONO && st_ivas->hDecoderConfig->ivas_total_brate < MASA_STEREO_MIN_BITRATE && st_ivas->hDecoderConfig->ivas_total_brate > IVAS_SID_4k4 ) ) -#endif { *renderer_type = RENDERER_DISABLE; } diff --git a/lib_rend/ivas_reverb.c b/lib_rend/ivas_reverb.c index 9bee3214d7..7073169bcc 100644 --- a/lib_rend/ivas_reverb.c +++ b/lib_rend/ivas_reverb.c @@ -795,17 +795,10 @@ static void set_reverb_acoustic_data( { int16_t nr_out_ch, hrtf_idx, offset, iter_idx, bin_idx; float ln_1e6_inverted, delay_diff, exp_argument; -#ifdef FIX_CREND_CHANNELS - float *pHrtf_set_l_re[MAX_TRANSPORT_CHANNELS]; - float *pHrtf_set_l_im[MAX_TRANSPORT_CHANNELS]; - float *pHrtf_set_r_re[MAX_TRANSPORT_CHANNELS]; - float *pHrtf_set_r_im[MAX_TRANSPORT_CHANNELS]; -#else float *pHrtf_set_l_re[IVAS_MAX_NUM_CH]; float *pHrtf_set_l_im[IVAS_MAX_NUM_CH]; float *pHrtf_set_r_re[IVAS_MAX_NUM_CH]; float *pHrtf_set_r_im[IVAS_MAX_NUM_CH]; -#endif /* use crend hrtf filters */ if ( hHrtf != NULL ) diff --git a/lib_util/hrtf_file_reader.c b/lib_util/hrtf_file_reader.c index 92b0058436..1dc481c84e 100644 --- a/lib_util/hrtf_file_reader.c +++ b/lib_util/hrtf_file_reader.c @@ -165,7 +165,6 @@ static void LoadBSplineBinaryITD( modelITD->W = (const float *) modelITD->W_dyn; modelITD->azimBsShape = (const float *) modelITD->azimBsShape_dyn; modelITD->elevBsShape = (const float *) modelITD->elevBsShape_dyn; - return; } @@ -311,7 +310,7 @@ static ivas_error LoadBSplineBinary( * * Load HRTF model or table from file --------------------------------------------------------------------*/ - +/*! r: TD Renderer result code. */ static ivas_error TDREND_MIX_LoadHRTF( FILE *f_hrtf, /* i/o: File pointer to HRTF file */ IVAS_DEC_HRTF_HANDLE HrFiltSet_p /* o : Loaded HR filter set */ diff --git a/pytest.ini b/pytest.ini index c4ed77a9f6..9d9a3bbf8e 100644 --- a/pytest.ini +++ b/pytest.ini @@ -1,13 +1,8 @@ # pytest.ini # note: per convention, this file is placed in the root directory of the repository [pytest] -addopts = -ra --tb=short --basetemp=./tmp -n auto -# Write captured system-out log messages to JUnit report. -junit_logging = system-out -# Do not capture log information for passing tests to JUnit report. -junit_log_passing_tests = False -junit_duration_report = call -junit_family = xunit1 +addopts = -ra --tb=short --basetemp=./tmp -v +junit_family=xunit1 log_file_level = DEBUG log_format = %(asctime)s %(levelname)s %(message)s log_date_format = %Y-%m-%d %H:%M:%S diff --git a/readme.txt b/readme.txt index 86e223b32c..4d4de5864a 100644 --- a/readme.txt +++ b/readme.txt @@ -195,7 +195,7 @@ EVS mono is default, for IVAS choose one of the following: -stereo, -ism, -sba, where 0 = adaptive, 3-100 = fixed in number of frames, default is deactivated -dtx : Activate DTX mode with a SID update rate of 8 frames - Note: DTX is currently supported in EVS, stereo, 1 ISm, + Note: DTX is currently supported in EVS, DFT/TD stereo, 1 ISm, SBA (up to 128kbps) and MASA (up to 128kbps) -rf p o : Activate channel-aware mode for WB and SWB signal at 13.2kbps, where FEC indicator, p: LO or HI, and FEC offset, o: 2, 3, 5, or 7 in number of frames. diff --git a/scripts/IvasBuildAndRunChecks.py b/scripts/IvasBuildAndRunChecks.py index 1cf4a868db..fe1953a603 100755 --- a/scripts/IvasBuildAndRunChecks.py +++ b/scripts/IvasBuildAndRunChecks.py @@ -36,9 +36,7 @@ import sys from pyivastest.IvasSvnBuilder import * from pyivastest import IvasScriptsCommon import pyivastest.constants as constants - - -RET_CODE_FAILURE = 101 +from pyivastest import ivas_svn class IvasBuildAndRunChecks(IvasScriptsCommon.IvasScript): @@ -171,10 +169,14 @@ class IvasBuildAndRunChecks(IvasScriptsCommon.IvasScript): for check in checks: br.run(check) if self.args["create_html_output"]: - cmd = ["git", "rev-parse", "HEAD"] - commit_hash = subprocess.run(cmd, capture_output=True).stdout.decode("utf8") + revision = ivas_svn.get_local_svn_info(self.args["srcdir"], self.logger) + if revision is None: + print("Could not get revision from local copy") + revision = -1 + else: + revision = revision["commit_revision"] br.build_and_run_dict[check]["analyzer"].write_html_file( - check, self.args["create_html_output"], commit_hash + check, self.args["create_html_output"], revision ) for r in br.build_and_run_dict[check]["runner"].results: self.logger.console(r[0]) @@ -193,16 +195,7 @@ class IvasBuildAndRunChecks(IvasScriptsCommon.IvasScript): self.args["create_complexity_tables"] ) - for check in checks: - runner = br.build_and_run_dict[check]["runner"] - failed_encs = runner.failed_modes["enc"] - failed_decs = runner.failed_modes["dec"] - if len(failed_encs) > 0 or len(failed_decs) > 0: - return RET_CODE_FAILURE - else: - return 0 - if __name__ == "__main__": script = IvasBuildAndRunChecks() - sys.exit(script.run()) + script.run() diff --git a/scripts/config/ci_linux.json b/scripts/config/ci_linux.json index 6279d3f89d..23aee75ba7 100644 --- a/scripts/config/ci_linux.json +++ b/scripts/config/ci_linux.json @@ -1,6 +1,6 @@ { "afspPath": "not_needed", - "utilPath": "/tools", + "utilPath": "not_needed", "inpaths": { "MONO": "/usr/local/testv/test_mono.wav", "STEREO": "/usr/local/testv/test_stereo.wav", diff --git a/scripts/config/self_test.prm b/scripts/config/self_test.prm index 721e93a457..ffafdb3776 100644 --- a/scripts/config/self_test.prm +++ b/scripts/config/self_test.prm @@ -276,14 +276,6 @@ ../IVAS_cod -ism 1 testv/stvISM1.csv 13200 48 testv/stv1ISM48s.pcm bit ../IVAS_dec MONO 48 bit testv/stv1ISM48s.pcm_13200_48-48_MONO.tst -// 1 ISm with metadata at 13.2 kbps, 48 kHz in, 48 kHz out, DTX on, BINAURAL out, random FEC at 5% -../IVAS_cod -dtx -ism 1 testv/stvISM1.csv 13200 48 testv/stv48n.pcm bit -../IVAS_dec -fec 5 BINAURAL 48 bit testv/stv48n.pcm_13200_48-48_DTX_FEC5_BINAURAL.tst - -// 1 ISm with metadata at 32 kbps, 32 kHz in, 32 kHz out, DTX on, MONO out -../IVAS_cod -dtx -ism 1 testv/stvISM1.csv 32000 32 testv/stv32n.pcm bit -../IVAS_dec MONO 32 bit testv/stv32n.pcm_32000_32-32_DTX_MONO.tst - // 2 ISm with metadata at 16.4 kbps, 48 kHz in, 48 kHz out, STEREO out ../IVAS_cod -ism 2 testv/stvISM1.csv testv/stvISM2.csv 16400 48 testv/stv2ISM48s.pcm bit ../IVAS_dec STEREO 48 bit testv/stv2ISM48s.pcm_16400_48-48_STEREO.tst diff --git a/tests/conftest.py b/scripts/ivas_pytests/conftest.py similarity index 57% rename from tests/conftest.py rename to scripts/ivas_pytests/conftest.py index da1c26e54a..2cc74689af 100644 --- a/tests/conftest.py +++ b/scripts/ivas_pytests/conftest.py @@ -1,37 +1,31 @@ -__copyright__ = \ """ -(C) 2022 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. -""" - -__doc__ = \ -""" -Pytest customization (configuration and fixtures) for the IVAS codec test suite. + (C) 2022 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. """ import logging @@ -41,7 +35,7 @@ from subprocess import run import textwrap from typing import Optional import os -import testconfig + import pytest logger = logging.getLogger(__name__) @@ -60,104 +54,75 @@ def log_dbg_msg(message): @pytest.fixture(scope="session", autouse=True) def rootdir(request): - """ - Return root directory for tests. - """ return str(request.config.rootdir) def pytest_addoption(parser): - parser.addoption( - "--update_ref", - action="store", - help="""Indicate whether references shall be updated. - 0: Only DUT processing, no reference generation, references need to be present. - 1: Only reference generation (unconditionally), no DUT processing. - 2: DUT processing, references are generated when not present (not supported by all tests). - """, - default="0", - ) + parser.addoption("--update_ref", action="store", default="0") + parser.addoption("--p4_CL", action="store") + parser.addoption("--p4cmd_active", action="store", default="0") parser.addoption( "--dut_encoder_path", action="store", - help="If specified, use given binary as DUT encoder.", + help="If specified, use given binary as DUT encoder." ) parser.addoption( "--dut_decoder_path", action="store", - help="If specified, use given binary as DUT decoder.", + help="If specified, use given binary as DUT decoder." ) parser.addoption( "--ref_encoder_path", action="store", - help="If specified, use given binary as REF encoder.", + help="If specified, use given binary as REF encoder." ) parser.addoption( "--ref_decoder_path", action="store", - help="If specified, use given binary as REF decoder.", + help="If specified, use given binary as REF decoder." ) + # TODO: rename to test_vector_path parser.addoption( - "--test_vector_path", + "--data_system_tests_path", action="store", - help="If specified, use given directory as base directory for test vector files.", + help="If specified, use given directory as base data directory for system tests." ) parser.addoption( "--reference_path", action="store", - help="If specified, use given directory as base directory for reference files.", + help="If specified, use given directory as base directory for reference files." ) parser.addoption( "--dut_base_path", action="store", - help="If specified, use given directory as base data directory for dut files.", - ) - - parser.addoption( - "--param_file", - action="store", - help="If specified, use given param file in test_param_file.", - ) - - parser.addoption( - "--keep_files", - action="store_true", - help="By default, the DUT output files of successful tests are deleted." - " Use --keep_files to prevent these deletions.", + help="If specified, use given directory as base data directory for dut files." ) @pytest.fixture(scope="session", autouse=True) def update_ref(request): - """ - Return indication whether references shall be updated. - 0: Only DUT processing, no reference generation. - 1: Only reference generation (unconditionally), no DUT processing. - 2: DUT processing, references are generated when not present. - """ return int(request.config.getoption("--update_ref")) -@pytest.fixture(scope="session") -def keep_files(request) -> bool: - """ - Return indication to not delete DUT output files. - """ - return request.config.option.keep_files +@pytest.fixture(scope="session", autouse=True) +def p4_CL(request): + return request.config.option.p4_CL + + +@pytest.fixture(scope="session", autouse=True) +def p4cmd_active(request): + return int(request.config.getoption("--p4cmd_active")) @pytest.fixture(scope="session") -def dut_encoder_path(request) -> str: - """ - Return path of DUT encoder binary. - """ +def dut_encoder_path(request) -> Path: if request.config.option.dut_encoder_path: return request.config.option.dut_encoder_path @@ -165,16 +130,15 @@ def dut_encoder_path(request) -> str: system = platform.system() if system == "Windows": - path = here.joinpath("../IVAS_cod.exe") + path = here.joinpath("../../IVAS_cod.exe") elif system in ["Darwin", "Linux"]: - path = here.joinpath("../IVAS_cod") + path = here.joinpath("../../IVAS_cod") else: raise ValueError(f'Wrong system "{system}"!') path = str(path.resolve()) - if not os.path.isfile(path): - pytest.exit(f"\nDUT encoder binary {path} not found!\n!") + assert os.path.isfile(path) return path @@ -199,7 +163,6 @@ class EncoderFrontend: agc_op: Optional[int] = None, bypass_mode: Optional[int] = None, quiet_mode: Optional[bool] = True, - add_option_list: Optional[list] = None, ) -> None: command = [self._path] @@ -222,9 +185,6 @@ class EncoderFrontend: if quiet_mode: command.extend(["-q"]) - if add_option_list is not None: - command.extend(add_option_list) - # add mandatory parameters command += [ str(bitrate), @@ -261,9 +221,6 @@ class EncoderFrontend: @pytest.fixture(scope="function") def dut_encoder_frontend(dut_encoder_path) -> EncoderFrontend: - """ - Return a :class:`conftest.EncoderFrontend` instance as DUT for the test session. - """ encoder = EncoderFrontend(dut_encoder_path, "DUT") yield encoder @@ -272,40 +229,34 @@ def dut_encoder_frontend(dut_encoder_path) -> EncoderFrontend: @pytest.fixture(scope="session") -def ref_encoder_path(request) -> str: - """ - Return path of REF encoder binary. - """ +def ref_encoder_path(request) -> Path: if request.config.option.ref_encoder_path: return request.config.option.ref_encoder_path - if request.config.option.update_ref == "0": + update_ref = int(request.config.getoption("--update_ref")) + if not update_ref: return None - # assume specifically named encoder when update_ref is selected, but no ref_encoder_path is specified + # assume default encoder when update_ref is selected, but no ref_encoder_path is specified here = Path(__file__).parent.resolve() system = platform.system() if system == "Windows": - path = here.joinpath("../IVAS_cod_ref.exe") + path = here.joinpath("../../IVAS_cod.exe") elif system in ["Darwin", "Linux"]: - path = here.joinpath("../IVAS_cod_ref") + path = here.joinpath("../../IVAS_cod") else: raise ValueError(f'Wrong system "{system}"!') path = str(path.resolve()) - if not os.path.isfile(path): - pytest.exit(f"\nREF encoder binary {path} not found!\n!") + assert os.path.isfile(path) return path @pytest.fixture(scope="session") -def dut_decoder_path(request) -> str: - """ - Return path of DUT decoder binary. - """ +def dut_decoder_path(request) -> Path: if request.config.option.dut_decoder_path: return request.config.option.dut_decoder_path @@ -313,16 +264,15 @@ def dut_decoder_path(request) -> str: system = platform.system() if system == "Windows": - path = here.joinpath("../IVAS_dec.exe") + path = here.joinpath("../../IVAS_dec.exe") elif system in ["Darwin", "Linux"]: - path = here.joinpath("../IVAS_dec") + path = here.joinpath("../../IVAS_dec") else: raise ValueError(f'Wrong system "{system}"!') path = str(path.resolve()) - if not os.path.isfile(path): - pytest.exit(f"\nDUT decoder binary {path} not found!\n!") + assert os.path.isfile(path) return path @@ -343,7 +293,6 @@ class DecoderFrontend: output_path: Path, quiet_mode: Optional[bool] = True, plc_file: Optional[Path] = None, - add_option_list: Optional[list] = None, ) -> None: command = [self._path] @@ -354,14 +303,9 @@ class DecoderFrontend: if plc_file is not None: command.extend(["-fec", str(plc_file)]) - if add_option_list is not None: - command.extend(add_option_list) - # add mandatory parameters - # output_config is mandatory for IVAS; EVS does not have this parameter, indicated by "" - if output_config != "": - command += [output_config] command += [ + output_config, str(output_sampling_rate), str(input_bitstream_path), str(output_path), @@ -395,9 +339,6 @@ class DecoderFrontend: @pytest.fixture(scope="function") def dut_decoder_frontend(dut_decoder_path) -> DecoderFrontend: - """ - Return a :class:`conftest.DecoderFrontend` instance as DUT for the test session. - """ decoder = DecoderFrontend(dut_decoder_path, "DUT") yield decoder @@ -406,46 +347,40 @@ def dut_decoder_frontend(dut_decoder_path) -> DecoderFrontend: @pytest.fixture(scope="session") -def ref_decoder_path(request) -> str: - """ - Return path of REF decoder binary. - """ +def ref_decoder_path(request) -> Path: if request.config.option.ref_decoder_path: return request.config.option.ref_decoder_path - if request.config.option.update_ref == "0": + update_ref = int(request.config.getoption("--update_ref")) + if not update_ref: return None - # assume specifically named decoder when update_ref is selected, but no ref_decoder_path is specified + # assume default decoder when update_ref is selected, but no ref_decoder_path is specified here = Path(__file__).parent.resolve() system = platform.system() if system == "Windows": - path = here.joinpath("../IVAS_dec_ref.exe") + path = here.joinpath("../../IVAS_dec.exe") elif system in ["Darwin", "Linux"]: - path = here.joinpath("../IVAS_dec_ref") + path = here.joinpath("../../IVAS_dec") else: raise ValueError(f'Wrong system "{system}"!') path = str(path.resolve()) - if not os.path.isfile(path): - pytest.exit(f"\nREF decoder binary {path} not found!\n!") + assert os.path.isfile(path) return path @pytest.fixture(scope="session") -def test_vector_path(request) -> str: - """ - Return base directory of test vector files. - """ - if request.config.option.test_vector_path: - return request.config.option.test_vector_path +def data_system_tests_path(request) -> Path: + if request.config.option.data_system_tests_path: + return request.config.option.data_system_tests_path here = Path(__file__).parent.resolve() - path = here.joinpath("../scripts/testv") + path = here.joinpath("testv") path = str(path.resolve()) @@ -453,10 +388,7 @@ def test_vector_path(request) -> str: @pytest.fixture(scope="session") -def reference_path(request) -> str: - """ - Return base directory of reference files. - """ +def reference_path(request) -> Path: if request.config.option.reference_path: return request.config.option.reference_path @@ -466,18 +398,11 @@ def reference_path(request) -> str: path = str(path.resolve()) - if request.config.option.update_ref == "0": - if not os.path.isdir(path): - pytest.exit(f"\nREF path {path} not found!\nPlease generate the references, first!\n!") - return path @pytest.fixture(scope="session") -def dut_base_path(request) -> str: - """ - Return base data directory for dut files. - """ +def dut_base_path(request) -> Path: if request.config.option.dut_base_path: return request.config.option.dut_base_path @@ -500,5 +425,3 @@ def pytest_configure(config): config.addinivalue_line( "markers", "create_ref_part2: reference creation test that depends on create_ref references" ) - if config.option.param_file: - testconfig.PARAM_FILE = config.option.param_file diff --git a/scripts/ivas_pytests/self_test_b.py b/scripts/ivas_pytests/self_test_b.py new file mode 100755 index 0000000000..941739435e --- /dev/null +++ b/scripts/ivas_pytests/self_test_b.py @@ -0,0 +1,273 @@ +#!/usr/bin/env python3 + +""" + (C) 2022 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. +""" + +""" +Script to run the pytest tests. + +Step 1: Set the stage for the pytest run. + +Step 2: Run pytest. +""" + +import os +import sys +import argparse +import subprocess +import platform +from pathlib import Path + +sys.path.append('scripts/ivas_pytests/tests/') +from cut_pcm import cut_samples + +BIN_EXT = ".exe" if platform.system() == "Windows" else "" +HERE = Path(__file__).parent.resolve() +DEFAULT_ENCODER_DUT = str(HERE.joinpath(f"../../IVAS_cod{BIN_EXT}").resolve()) +DEFAULT_DECODER_DUT = str(HERE.joinpath(f"../../IVAS_dec{BIN_EXT}").resolve()) +DEFAULT_ENCODER_REF = str(HERE.joinpath(f"../../IVAS_cod_ref{BIN_EXT}").resolve()) +DEFAULT_DECODER_REF = str(HERE.joinpath(f"../../IVAS_dec_ref{BIN_EXT}").resolve()) +CREND_UNITTEST_REF = str(HERE.joinpath(f"tests/unit_tests/crend/IVAS_crend_unit_test_ref{BIN_EXT}").resolve()) +TEST_VECTOR_DIR = str(HERE.joinpath("../testv").resolve()) +REFERENCE_DIR = str(HERE.joinpath("ref").resolve()) +DUT_BASE_DIR = str(HERE.joinpath("dut").resolve()) + + +def build_enc_and_dec(src_dir): + """ + Build the encoder and decoder binaries. + """ + if platform.system() == "Windows": + olddir = os.getcwd() + os.chdir(src_dir) + os.chdir("Workspace_msvc") + command = ["MSBuild.exe", "Workspace_msvc.sln", "/t:Clean", "/p:configuration=Release", "/p:Platform=Win32"] + subprocess.run(command, check=True) + command = ["MSBuild.exe", "Workspace_msvc.sln", "/property:configuration=Release", "/p:Platform=Win32"] + subprocess.run(command, check=True) + os.chdir(olddir) + else: + command = ["make", "-C", src_dir, "clean"] + subprocess.run(command, check=True) + command = ["make", "-C", src_dir] + subprocess.run(command, check=True) + + +def build_crend_unittest(src_dir): + """ + Build the crend unit test binary. + """ + crend_dir = f"{src_dir}/scripts/ivas_pytests/tests/unit_tests/crend" + if platform.system() == "Windows": + olddir = os.getcwd() + os.chdir(crend_dir) + # command = ["MSBuild.exe", "ivas_crend_unit_test.sln", "/t:Clean", "/p:configuration=Release", "/p:Platform=Win32"] + # subprocess.run(command, check=True) + command = ["MSBuild.exe", "ivas_crend_unit_test.sln", "/property:configuration=Release", "/p:Platform=Win32"] + subprocess.run(command, check=True) + os.chdir(olddir) + else: + # command = ["make", "-C", src_dir, "clean"] + # subprocess.run(command, check=True) + command = ["make", "-C", src_dir, "IVAS_crend_unit_test"] + subprocess.run(command, check=True) + + +def build_dut_binaries(): + """ + Build the DUT binaries. + """ + print("Building the DUT binaries") + dut_src_dir = str(HERE.joinpath("../..").resolve()) + build_enc_and_dec(dut_src_dir) + build_crend_unittest(dut_src_dir) + + +def create_short_testvectors(): + """ + Create short (5sec) testvectors. + """ + print("Creating short (5sec) testvectors") + num_channels = "4" # currently only FOA + cut_from = "0.0" + cut_len = "5.0" + for fs in ['48', '32', '16']: + in_file = f"{TEST_VECTOR_DIR}/stvFOA{fs}c.pcm" + cut_gain = "1.0" + cut_file = f"{TEST_VECTOR_DIR}/stvFOA{fs}c_cut.pcm" + cut_samples(in_file, cut_file, num_channels, fs + "000", cut_from, cut_len, cut_gain) + cut_gain = "16.0" + cut_file = f"{TEST_VECTOR_DIR}/stvFOA{fs}c_cut_{cut_gain}.pcm" + cut_samples(in_file, cut_file, num_channels, fs + "000", cut_from, cut_len, cut_gain) + + +def main(argv): + # check for python >= 3.7 + if sys.version_info[0] < 3 or sys.version_info[1] < 7: + sys.exit("This script is written for Python >= 3.7. Found: " + platform.python_version()) + + parser = argparse.ArgumentParser(formatter_class=argparse.RawTextHelpFormatter) + parser.add_argument( + "--create_only", + action="store_true", + default=False, + help="Create references when needed, but don't run the tests" + ) + parser.add_argument( + "--numprocesses", + action="store", + default="auto", + help="Number of processes to use in pytest (default: auto)", + ) + parser.add_argument("--encref", help=f"REF encoder binary (default:{DEFAULT_ENCODER_REF})") + parser.add_argument("--decref", help=f"REF decoder binary (default:{DEFAULT_DECODER_REF})") + parser.add_argument("--encdut", help=f"DUT encoder binary (default:{DEFAULT_ENCODER_DUT})") + parser.add_argument("--decdut", help=f"DUT decoder binary (default:{DEFAULT_DECODER_DUT})") + + args = parser.parse_args(argv[1:]) + + # check for DUT binaries + if args.encdut: + encdut_path = os.path.realpath(args.encdut) + if not os.path.exists(encdut_path): + sys.exit(f"DUT encoder binary {encdut_path} does not exist.") + else: + encdut_path = DEFAULT_ENCODER_DUT + if args.decdut: + decdut_path = os.path.realpath(args.decdut) + if not os.path.exists(decdut_path): + sys.exit(f"DUT encoder binary {decdut_path} does not exist.") + else: + decdut_path = DEFAULT_DECODER_DUT + if not os.path.exists(encdut_path) or not os.path.exists(decdut_path): + build_dut_binaries() + + if not os.path.exists(REFERENCE_DIR): + # check for REF binaries + if args.encref: + encref_path = os.path.realpath(args.encref) + if not os.path.exists(encref_path): + sys.exit(f"REF encoder binary {encref_path} does not exist.") + else: + encref_path = DEFAULT_ENCODER_REF + if args.decref: + decref_path = os.path.realpath(args.decref) + if not os.path.exists(decref_path): + sys.exit(f"REF encoder binary {decref_path} does not exist.") + else: + decref_path = DEFAULT_DECODER_REF + if not os.path.exists(encref_path) or not os.path.exists(decref_path): + sys.exit("Reference binaries do not exist.") + + # check for test vectors + if not os.path.exists(TEST_VECTOR_DIR): + sys.exit(f"Test vector directory {TEST_VECTOR_DIR} does not exist.") + + # check for references + if os.path.exists(REFERENCE_DIR): + print(f"Using existing references directory {REFERENCE_DIR}") + else: + # create references + print(f"Creating references within the references directory {REFERENCE_DIR}") + create_short_testvectors() + if platform.system() == "Windows": + base_cmd = ["pytest"] + else: + base_cmd = ["python3", "-m", "pytest"] + base_cmd += [ + "scripts/ivas_pytests/tests", + "-n", + args.numprocesses, + "--update_ref", + "1", + "-v", + "--data_system_tests_path", + TEST_VECTOR_DIR, + "--reference_path", + REFERENCE_DIR, + "--dut_base_path", + DUT_BASE_DIR, + "--ref_encoder_path", + encref_path, + "--ref_decoder_path", + decref_path, + "--dut_encoder_path", + encdut_path, + "--dut_decoder_path", + decdut_path, + ] + # work-around in unit tests via environment variable + # TESTVECTOR_PATH_REL_GROUPB: to specify the test vector directory relative to ivas_pytests folder + # TESTVECTOR_PATH_REL_TRUNK: to specify the test vector directory relative to trunk + my_env = os.environ.copy() + my_env["TESTVECTOR_PATH_REL_GROUPB"] = "testv/" + my_env["TESTVECTOR_PATH_REL_TRUNK"] = "/scripts/ivas_pytests/testv/" # leading "/" is important + my_env["CREND_UNIT_TEST_BIN"] = CREND_UNITTEST_REF + print("pytest command line to be executed from project root folder:") + print(" ".join(base_cmd + ["-m", "create_ref"])) + subprocess.run(base_cmd + ["-m", "create_ref"], check=False, env=my_env) + print("pytest command line to be executed from project root folder:") + print(" ".join(base_cmd + ["-m", "create_ref_part2"])) + subprocess.run(base_cmd + ["-m", "create_ref_part2"], check=False, env=my_env) + + if args.create_only: + return + + # run pytest + if platform.system() == "Windows": + cmd = ["pytest"] + else: + cmd = ["python3", "-m", "pytest"] + cmd += [ + "scripts/ivas_pytests/tests", + "-n", + args.numprocesses, + "-v", + "--data_system_tests_path", + TEST_VECTOR_DIR, + "--reference_path", + REFERENCE_DIR, + "--dut_base_path", + DUT_BASE_DIR, + "--dut_encoder_path", + encdut_path, + "--dut_decoder_path", + decdut_path, + "--junit-xml=report-junit.xml", + ] + # print pytest commandline + print("pytest command line to be executed from project root folder:") + print(" ".join(cmd)) + result = subprocess.run(cmd, check=False) + return result.returncode + + +if __name__ == "__main__": + sys.exit(main(sys.argv)) diff --git a/tests/cmp_custom.py b/scripts/ivas_pytests/tests/cmp_custom.py old mode 100755 new mode 100644 similarity index 62% rename from tests/cmp_custom.py rename to scripts/ivas_pytests/tests/cmp_custom.py index ab22bc0ceb..e52d6df46c --- a/tests/cmp_custom.py +++ b/scripts/ivas_pytests/tests/cmp_custom.py @@ -1,37 +1,35 @@ #!/usr/bin/env python3 -__copyright__ = \ """ -(C) 2022 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. + (C) 2022 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. """ -__doc__ = \ """ Script to compare samples in 2 PCM files. @@ -89,7 +87,7 @@ class CompareSamples: self.file_1.seek(0) self.file_2.seek(0) - def print_summary(self) -> (int, str): + def print_summary(self): """ Print the summary of the comparison. """ @@ -105,18 +103,19 @@ class CompareSamples: if not self.diff_present: print("Comparison success") print("") - return 0, "Comparison success" - - # comparison failed - print( - f"First unmatched diff ==> {self.first_diff}", - f"at sample num {self.first_diff_sample_num}", - ) - diff_msg = f"MAXIMUM ABS DIFF ==> {self.max_diff} at sample num {self.max_diff_sample_num}" - print(diff_msg) - print("Comparison failed") - print("") - return 1, f"Comparison failed, {diff_msg}" + return 0 + else: + print( + f"First unmatched diff ==> {self.first_diff}", + f"at sample num {self.first_diff_sample_num}", + ) + print( + f"MAXIMUM ABS DIFF ==> {self.max_diff} at sample num {self.max_diff_sample_num}" + ) + print("Comparison failed") + print("") + return 1 + return 1 def compare_next_sample(self): """ @@ -147,7 +146,7 @@ class CompareSamples: def usage(): print(__doc__) - return 1, "" + return 1 def cmp_custom( @@ -156,7 +155,7 @@ def cmp_custom( sample_size_in_bytes_str, tolerance_str, end_samples_to_skip_str="0", -) -> (int, str): +): """ Function to compare the samples in 2 PCM files. """ @@ -190,11 +189,10 @@ def cmp_custom( return cmp_samples.print_summary() -def main(argv) -> int: +def main(argv): if len(argv) < 5: return usage() - retval, _reason = cmp_custom(*argv[1:]) - return retval + return cmp_custom(*argv[1:]) if __name__ == "__main__": diff --git a/tests/cut_pcm.py b/scripts/ivas_pytests/tests/cut_pcm.py similarity index 99% rename from tests/cut_pcm.py rename to scripts/ivas_pytests/tests/cut_pcm.py index 938cb6fc43..62af257a73 100755 --- a/tests/cut_pcm.py +++ b/scripts/ivas_pytests/tests/cut_pcm.py @@ -1,7 +1,6 @@ #!/usr/bin/env python3 -__copyright__ = \ -""" +__license__ = """ (C) 2022 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, @@ -31,8 +30,7 @@ accordance with the laws of the Federal Republic of Germany excluding its confli the United Nations Convention on Contracts on the International Sales of Goods. """ -__doc__ = \ -""" +__doc__ = """ Script to cut samples from a 16-bit PCM file. USAGE : cut_pcm.py in_file_pcm out_file_pcm num_channels sample_rate start duration [gain] diff --git a/scripts/ivas_pytests/tests/il2mm.py b/scripts/ivas_pytests/tests/il2mm.py new file mode 100644 index 0000000000..eb09593bdb --- /dev/null +++ b/scripts/ivas_pytests/tests/il2mm.py @@ -0,0 +1,61 @@ +""" + (C) 2022 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. +""" + +import os + + +def il2mm(file_in, num_ch, b_delete=True): + """ + Convert interleaved input file to multiple mono output files. + """ + num_bytes_per_sample = 2 + num_bytes_per_frame = num_bytes_per_sample * num_ch + num_bytes_per_channel = os.path.getsize(file_in) / num_ch + + with open(file_in, "rb") as fid_in: + out_path = os.path.splitext(file_in)[0] + for chan in range(num_ch): + file_out = out_path + str(chan + 1) + "ch.raw" + with open(file_out, "wb") as fid_out: + bytes_written = 0 + offset = chan * num_bytes_per_sample + fid_in.seek(offset, 0) + while bytes_written < num_bytes_per_channel: + data = fid_in.read(num_bytes_per_sample) + fid_in.seek(num_bytes_per_frame - num_bytes_per_sample, 1) + written = fid_out.write(bytes(data)) + assert ( + written == num_bytes_per_sample + ), f"Error writing data: {written} != {num_bytes_per_sample}" + bytes_written += num_bytes_per_sample + + # delete interleaved input file + if b_delete: + os.remove(file_in) diff --git a/scripts/ivas_pytests/tests/requirements.txt b/scripts/ivas_pytests/tests/requirements.txt new file mode 100644 index 0000000000..764694dfc0 --- /dev/null +++ b/scripts/ivas_pytests/tests/requirements.txt @@ -0,0 +1,4 @@ +pytest==5.3.5 +pytest-xdist==1.31.0 +scipy==1.5.2 +numpy==1.19.2 diff --git a/scripts/ivas_pytests/tests/system_tests/test_spar_foa_bs_dec_plc.py b/scripts/ivas_pytests/tests/system_tests/test_spar_foa_bs_dec_plc.py new file mode 100644 index 0000000000..fa17fd1d80 --- /dev/null +++ b/scripts/ivas_pytests/tests/system_tests/test_spar_foa_bs_dec_plc.py @@ -0,0 +1,180 @@ +""" + (C) 2022 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. +""" + +import os +import pytest +import shutil +import errno +import sys + +sys.path.append('scripts/ivas_pytests/') +sys.path.append('scripts/ivas_pytests/tests/') +from il2mm import il2mm +from cmp_custom import cmp_custom +from conftest import EncoderFrontend, DecoderFrontend + +#params +tag_list = ['stvFOA'] +plc_patterns = ['PLperc12mblen5', 'PLperc40mblen50', 'PLperc42mblen2'] +dtx_set = ['0', '1'] +ivas_br_list = ['32000', '64000', '96000', '256000'] +sampling_rate_list = ['48', '32', '16'] +agc_list = [0, 1] + +ch_count_foa = 4 +AbsTol = '3' + + +def check_and_makedir(dir_path): + if not os.path.exists(dir_path): + try: + os.makedirs(dir_path) + except OSError as e: + if e.errno != errno.EEXIST: + raise # raises the error again + + +# assumption: +# - the needed reference bitstreams are created by test_spar_foa_enc_system +# -> reference bitstreams are not any longer created as part of this test +# -> the parameters of this test (except additional parameter plc_pattern) need to be a subset of the parameters in test_spar_foa_enc_system +# -> the reference generation for this test (reference decoder output) needs to be done after completion of test_spar_foa_enc_system +# -> therefore the marker create_ref_part2 +@pytest.mark.create_ref_part2 +@pytest.mark.parametrize("ivas_br", ivas_br_list) +@pytest.mark.parametrize("dtx", dtx_set) +@pytest.mark.parametrize("tag", tag_list) +@pytest.mark.parametrize("plc_pattern", plc_patterns) +@pytest.mark.parametrize("fs", sampling_rate_list) +@pytest.mark.parametrize("agc", agc_list) +def test_spar_foa_plc_system( + dut_decoder_frontend: DecoderFrontend, + data_system_tests_path, + reference_path, + dut_base_path, + ref_decoder_path, + update_ref, + ivas_br, + dtx, + tag, + plc_pattern, + fs, + agc +): + tag = tag + fs + 'c' + + #dec + spar_foa_dec_plc(dut_decoder_frontend, data_system_tests_path, reference_path, dut_base_path, ref_decoder_path, tag, ch_count_foa, fs, ivas_br, dtx, plc_pattern, update_ref, agc) + + +######################################################### +############ test function ############################## +def spar_foa_dec_plc( + decoder_frontend, + test_vector_path, + reference_path, + dut_base_path, + ref_decoder_path, + tag, + ch_count, + sampling_rate, + ivas_br, + dtx, + plc_pattern, + update_ref, + agc +): + + ######### run cmd ##################################### + + tag_out = f"{tag}_ivasbr{ivas_br[:-3]}k_DTX{dtx}" + if agc == 1: + tag_out += '_AGC1' + plc_tag_out = f"{tag_out}_{plc_pattern}" + + dut_out_dir = f"{dut_base_path}/spar_foa_bs/raw/{plc_tag_out}" + ref_out_dir = f"{reference_path}/spar_foa_bs/raw/{plc_tag_out}" + + check_and_makedir(dut_out_dir) + check_and_makedir(ref_out_dir) + + plc_file = f"{test_vector_path}/{plc_pattern}.g192" + ref_in_pkt = f"{reference_path}/spar_foa_bs/pkt/{tag_out}.pkt" + ref_in_pkt_dutenc = f"{reference_path}/spar_foa_bs/pkt/{tag_out}_dutenc.pkt" + + if ref_decoder_path: + ref_decoder = DecoderFrontend(ref_decoder_path, "REF") + + # call REF decoder + ref_decoder.run( + "FOA", + sampling_rate, + ref_in_pkt, + f"{ref_out_dir}/out.raw", + plc_file=plc_file, + ) + + # convert REF interleaved to multi-mono + il2mm(f"{ref_out_dir}/out.raw", ch_count) + + if update_ref == 0: + # call DUT decoder + decoder_frontend.run( + "FOA", + sampling_rate, + ref_in_pkt_dutenc, + f"{dut_out_dir}/out.raw", + plc_file=plc_file, + ) + + il2mm(f"{dut_out_dir}/out.raw", ch_count) + + ######### compare cmd ##################################### + + end_skip_samples = '0' + + test_fail = False + for count in range(ch_count): + ch_id = str(count + 1) + + if cmp_custom( + f"{dut_out_dir}/out{ch_id}ch.raw", + f"{ref_out_dir}/out{ch_id}ch.raw", + "2", + AbsTol, + end_skip_samples + ) != 0: + test_fail = True + + ##File removal## + shutil.rmtree(dut_out_dir, ignore_errors=True) + + ##report failure + assert not test_fail diff --git a/tests/test_sba_bs_enc.py b/scripts/ivas_pytests/tests/system_tests/test_spar_foa_bs_enc.py similarity index 71% rename from tests/test_sba_bs_enc.py rename to scripts/ivas_pytests/tests/system_tests/test_spar_foa_bs_enc.py index 95cfea1d19..df5d018ce5 100644 --- a/tests/test_sba_bs_enc.py +++ b/scripts/ivas_pytests/tests/system_tests/test_spar_foa_bs_enc.py @@ -1,44 +1,47 @@ -__copyright__ = \ """ -(C) 2022 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. + (C) 2022 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. """ -__doc__ = \ """ Test file to run C encoder and decoder code. The outputs are compared with C generated references. """ import os -import errno import pytest +import errno +import shutil +import sys +sys.path.append('scripts/ivas_pytests/') +sys.path.append('scripts/ivas_pytests/tests/') +from il2mm import il2mm from cmp_custom import cmp_custom from cut_pcm import cut_samples from conftest import EncoderFrontend, DecoderFrontend @@ -64,6 +67,7 @@ agc_list = [0, 1] sample_rate_bw_idx_list = [('48', 'SWB'), ('48', 'WB'), ('32', 'WB')] AbsTol = '4' +ch_count_foa = 4 def check_and_makedir(dir_path): @@ -82,16 +86,15 @@ def check_and_makedir(dir_path): def test_bypass_enc( dut_encoder_frontend: EncoderFrontend, dut_decoder_frontend: DecoderFrontend, - test_vector_path, + data_system_tests_path, reference_path, dut_base_path, ref_encoder_path, ref_decoder_path, update_ref, - keep_files, tag, fs, - bypass, + bypass ): if update_ref == 1 and bypass == 1: pytest.skip() @@ -105,9 +108,9 @@ def test_bypass_enc( output_config = "FOA" # enc - sba_enc( + spar_foa_enc( dut_encoder_frontend, - test_vector_path, + data_system_tests_path, ref_encoder_path, reference_path, dut_base_path, @@ -123,12 +126,13 @@ def test_bypass_enc( ) # dec - sba_dec( + spar_foa_dec( dut_decoder_frontend, ref_decoder_path, reference_path, dut_base_path, tag, + ch_count_foa, fs, ivas_br, dtx, @@ -136,8 +140,7 @@ def test_bypass_enc( bypass, agc, output_config, - update_ref, - keep_files, + update_ref ) @@ -147,21 +150,20 @@ def test_bypass_enc( @pytest.mark.parametrize("tag", tag_list) @pytest.mark.parametrize("fs", sample_rate_list) @pytest.mark.parametrize("agc", agc_list) -def test_sba_enc_system( +def test_spar_foa_enc_system( dut_encoder_frontend: EncoderFrontend, dut_decoder_frontend: DecoderFrontend, - test_vector_path, + data_system_tests_path, reference_path, dut_base_path, ref_encoder_path, ref_decoder_path, update_ref, - keep_files, ivas_br, dtx, tag, fs, - agc, + agc ): tag = tag + fs + 'c' max_bw = "FB" @@ -170,14 +172,13 @@ def test_sba_enc_system( output_config = "FOA" if agc == 1: cut_gain = "16.0" - elif dtx == '1': - cut_gain = ".004" else: - cut_gain = "1.0" + cut_gain = "1.0" + # enc - sba_enc( + spar_foa_enc( dut_encoder_frontend, - test_vector_path, + data_system_tests_path, ref_encoder_path, reference_path, dut_base_path, @@ -195,12 +196,13 @@ def test_sba_enc_system( ) # dec - sba_dec( + spar_foa_dec( dut_decoder_frontend, ref_decoder_path, reference_path, dut_base_path, tag, + ch_count_foa, fs, ivas_br, dtx, @@ -208,8 +210,7 @@ def test_sba_enc_system( bypass, agc, output_config, - update_ref, - keep_files, + update_ref ) @pytest.mark.create_ref @@ -218,15 +219,14 @@ def test_sba_enc_system( def test_spar_hoa2_enc_system( dut_encoder_frontend: EncoderFrontend, dut_decoder_frontend: DecoderFrontend, - test_vector_path, + data_system_tests_path, reference_path, dut_base_path, ref_encoder_path, ref_decoder_path, update_ref, - keep_files, ivas_br, - tag, + tag ): fs = '48' dtx = '0' @@ -239,9 +239,9 @@ def test_spar_hoa2_enc_system( output_config = "HOA2" # enc - sba_enc( + spar_foa_enc( dut_encoder_frontend, - test_vector_path, + data_system_tests_path, ref_encoder_path, reference_path, dut_base_path, @@ -258,12 +258,13 @@ def test_spar_hoa2_enc_system( ) # dec - sba_dec( + spar_foa_dec( dut_decoder_frontend, ref_decoder_path, reference_path, dut_base_path, tag, + ch_count_foa, fs, ivas_br, dtx, @@ -271,8 +272,7 @@ def test_spar_hoa2_enc_system( bypass, agc, output_config, - update_ref, - keep_files, + update_ref ) @pytest.mark.create_ref @@ -281,15 +281,14 @@ def test_spar_hoa2_enc_system( def test_spar_hoa3_enc_system( dut_encoder_frontend: EncoderFrontend, dut_decoder_frontend: DecoderFrontend, - test_vector_path, + data_system_tests_path, reference_path, dut_base_path, ref_encoder_path, ref_decoder_path, update_ref, - keep_files, ivas_br, - tag, + tag ): fs = '48' dtx = '0' @@ -302,9 +301,9 @@ def test_spar_hoa3_enc_system( output_config = "HOA3" # enc - sba_enc( + spar_foa_enc( dut_encoder_frontend, - test_vector_path, + data_system_tests_path, ref_encoder_path, reference_path, dut_base_path, @@ -321,12 +320,13 @@ def test_spar_hoa3_enc_system( ) # dec - sba_dec( + spar_foa_dec( dut_decoder_frontend, ref_decoder_path, reference_path, dut_base_path, tag, + ch_count_foa, fs, ivas_br, dtx, @@ -334,8 +334,7 @@ def test_spar_hoa3_enc_system( bypass, agc, output_config, - update_ref, - keep_files, + update_ref ) @pytest.mark.create_ref @@ -343,20 +342,19 @@ def test_spar_hoa3_enc_system( @pytest.mark.parametrize("dtx", dtx_set) @pytest.mark.parametrize("tag", tag_list_bw_force) @pytest.mark.parametrize("sample_rate_bw_idx", sample_rate_bw_idx_list) -def test_sba_enc_BWforce_system( +def test_spar_foa_enc_BWforce_system( dut_encoder_frontend: EncoderFrontend, dut_decoder_frontend: DecoderFrontend, - test_vector_path, + data_system_tests_path, reference_path, dut_base_path, ref_encoder_path, ref_decoder_path, update_ref, - keep_files, ivas_br, dtx, tag, - sample_rate_bw_idx, + sample_rate_bw_idx ): fs = sample_rate_bw_idx[0] bw = sample_rate_bw_idx[1] @@ -367,9 +365,9 @@ def test_sba_enc_BWforce_system( output_config = "FOA" # enc - sba_enc( + spar_foa_enc( dut_encoder_frontend, - test_vector_path, + data_system_tests_path, ref_encoder_path, reference_path, dut_base_path, @@ -385,12 +383,13 @@ def test_sba_enc_BWforce_system( ) # dec - sba_dec( + spar_foa_dec( dut_decoder_frontend, ref_decoder_path, reference_path, dut_base_path, tag, + ch_count_foa, fs, ivas_br, dtx, @@ -398,14 +397,13 @@ def test_sba_enc_BWforce_system( bypass, agc, output_config, - update_ref, - keep_files, + update_ref ) ######################################################### ############ test function ############################## -def sba_enc( +def spar_foa_enc( encoder_frontend, test_vector_path, ref_encoder_path, @@ -426,8 +424,8 @@ def sba_enc( ): ######### run cmd ##################################### - dut_out_dir = f"{dut_base_path}/sba_bs/pkt" - ref_out_dir = f"{reference_path}/sba_bs/pkt" + dut_out_dir = f"{dut_base_path}/spar_foa_bs/pkt" + ref_out_dir = f"{reference_path}/spar_foa_bs/pkt" check_and_makedir(dut_out_dir) check_and_makedir(ref_out_dir) @@ -514,12 +512,13 @@ def sba_enc( ) -def sba_dec( +def spar_foa_dec( decoder_frontend, ref_decoder_path, reference_path, dut_base_path, tag, + ch_count, sampling_rate, ivas_br, dtx, @@ -528,7 +527,7 @@ def sba_dec( agc, output_config, update_ref, - keep_files, + keep_files=False ): ######### run cmd ##################################### @@ -550,14 +549,11 @@ def sba_dec( # to avoid conflicting names in case of parallel test execution, differentiate all cases long_tag_ext = f"_AGC{agc}_pca{bypass}" - dut_out_dir = f"{dut_base_path}/sba_bs/raw" - ref_out_dir = f"{reference_path}/sba_bs/raw" + dut_out_dir = f"{dut_base_path}/spar_foa_bs/raw/{tag_out}{long_tag_ext}" + ref_out_dir = f"{reference_path}/spar_foa_bs/raw/{tag_out}{short_tag_ext}" - dut_in_pkt = f"{dut_base_path}/sba_bs/pkt/{tag_out}{long_tag_ext}.pkt" - ref_in_pkt = f"{reference_path}/sba_bs/pkt/{tag_out}{short_tag_ext}.pkt" - - dut_out_raw = f"{dut_out_dir}/{tag_out}{long_tag_ext}.raw" - ref_out_raw = f"{ref_out_dir}/{tag_out}{short_tag_ext}.raw" + dut_in_pkt = f"{dut_base_path}/spar_foa_bs/pkt/{tag_out}{long_tag_ext}.pkt" + ref_in_pkt = f"{reference_path}/spar_foa_bs/pkt/{tag_out}{short_tag_ext}.pkt" check_and_makedir(dut_out_dir) check_and_makedir(ref_out_dir) @@ -570,34 +566,48 @@ def sba_dec( output_config, sampling_rate, ref_in_pkt, - ref_out_raw, + f"{ref_out_dir}/out.raw", ) + # convert REF interleaved to multi-mono + il2mm(f"{ref_out_dir}/out.raw", ch_count, b_delete=not keep_files) + if update_ref == 0: # call DUT decoder decoder_frontend.run( output_config, sampling_rate, dut_in_pkt, - dut_out_raw, + f"{dut_out_dir}/out.raw", ) + il2mm(f"{dut_out_dir}/out.raw", ch_count, b_delete=not keep_files) + ######### compare cmd ##################################### end_skip_samples = '0' - cmp_result, reason = cmp_custom( - dut_out_raw, - ref_out_raw, - "2", - AbsTol, - end_skip_samples - ) - - # report compare result - assert cmp_result == 0, reason - - # remove DUT output files when test result is OK (to save disk space) + test_fail = False + for count in range(ch_count): + ch_id = str(count + 1) + + # TEST + fsize1 = os.path.getsize(f"{dut_out_dir}/out{ch_id}ch.raw") + fsize2 = os.path.getsize(f"{ref_out_dir}/out{ch_id}ch.raw") + print(f"Want to compare {dut_out_dir}/out{ch_id}ch.raw ({fsize1} bytes) with {ref_out_dir}/out{ch_id}ch.raw ({fsize2} bytes)") + if cmp_custom( + f"{dut_out_dir}/out{ch_id}ch.raw", + f"{ref_out_dir}/out{ch_id}ch.raw", + "2", + AbsTol, + end_skip_samples + ) != 0: + test_fail = True + + ##File removal## if not keep_files: os.remove(dut_in_pkt) - os.remove(dut_out_raw) + shutil.rmtree(dut_out_dir, ignore_errors=True) + + ##report failure + assert not test_fail diff --git a/scripts/ivas_pytests/tests/unit_tests/crend/ivas_crend_io_parse.h b/scripts/ivas_pytests/tests/unit_tests/crend/ivas_crend_io_parse.h index abc8b1e463..21b59ad06f 100644 --- a/scripts/ivas_pytests/tests/unit_tests/crend/ivas_crend_io_parse.h +++ b/scripts/ivas_pytests/tests/unit_tests/crend/ivas_crend_io_parse.h @@ -49,8 +49,6 @@ #define IVAS_IN_FMT_714 "714" #define IVAS_IN_FMT_FOA "HOA1S" -#define IVAS_MAX_NUM_CH 16 - #define IVAS_MAX_PATH_LEN ( 2000 ) typedef enum ivas_in_out_fmt_struct_t @@ -67,7 +65,7 @@ typedef enum ivas_in_out_fmt_struct_t HOA_16, OBA, } ivas_in_out_fmt_t, - IVAS_IN_OUT_FMT_CONFIG; + IVAS_IN_OUT_FMT_CONFIG; #define CREND_MAND_ARGS 6 /* Tests */ diff --git a/scripts/ivas_pytests/tests/unit_tests/crend/ivas_dec_parse_io.h b/scripts/ivas_pytests/tests/unit_tests/crend/ivas_dec_parse_io.h index ed4071d8ca..fe05a96f4f 100644 --- a/scripts/ivas_pytests/tests/unit_tests/crend/ivas_dec_parse_io.h +++ b/scripts/ivas_pytests/tests/unit_tests/crend/ivas_dec_parse_io.h @@ -54,14 +54,14 @@ #define IVAS_IN_FMT_COMBINED "Combined" #define IVAS_IN_FMT_HOA_3 "HOA3S" -#define MAX_PCM_OUT_FILES ( IVAS_MAX_NUM_CH ) +#define MAX_PCM_OUT_FILES ( IVAS_MAX_NUM_CH ) #define REQ_DEC_CMD_LINE_PARAMS ( 7 ) #define IVAS_MAX_PATH_LEN ( 2000 ) #define IVAS_EXT_ADD_DELAY_MS ( 2 ) -#define MAX_OUT_FILE_LEN ( 1000 ) -#define MAX_CH_IDX_TAG_LEN ( 10 ) +#define MAX_OUT_FILE_LEN ( 1000 ) +#define MAX_CH_IDX_TAG_LEN ( 10 ) /*------------------------------------------------------------------------------------------* * Global variables @@ -73,24 +73,22 @@ /* IVAS decoder output formats */ #define IVAS_NO_RENDERER ( -1 ) /* no renderer required */ -#define IVAS_DEFAULT_QUIET_MODE ( 0 ) +#define IVAS_DEFAULT_QUIET_MODE ( 0 ) #define IVAS_DEFAULT_NO_DELAY_COMP_MODE ( 0 ) -#define IVAS_DEFAULT_BS_FORMAT ( IVAS_G192 ) -#define IVAS_DEFAULT_FMT ( IVAS_NO_RENDERER ) -#define IVAS_DEFAULT_LFE_CH_IDX ( 3 ) /* ch count starting from 0 */ -#define IVAS_DEFAULT_AGC ( 0 ) - -#define IVAS_IN_FMT_510 "510" -#define IVAS_IN_FMT_710 "710" -#define IVAS_IN_FMT_512 "512" -#define IVAS_IN_FMT_714 "714" -#define IVAS_IN_FMT_FOA "HOA1S" +#define IVAS_DEFAULT_BS_FORMAT ( IVAS_G192 ) +#define IVAS_DEFAULT_FMT ( IVAS_NO_RENDERER ) +#define IVAS_DEFAULT_LFE_CH_IDX ( 3 ) /* ch count starting from 0 */ +#define IVAS_DEFAULT_AGC ( 0 ) + +#define IVAS_IN_FMT_510 "510" +#define IVAS_IN_FMT_710 "710" +#define IVAS_IN_FMT_512 "512" +#define IVAS_IN_FMT_714 "714" +#define IVAS_IN_FMT_FOA "HOA1S" #define IVAS_IN_FMT_HOA_2 "HOA2S" #define IVAS_IN_FMT_HOA_3 "HOA3S" #define IVAS_IN_FMT_HOA_4 "HOA4S" -#define IVAS_MAX_NUM_CH 16 - /*------------------------------------------------------------------------------------------* * Structure definitions *------------------------------------------------------------------------------------------*/ diff --git a/scripts/pyivastest/IvasModeRunner.py b/scripts/pyivastest/IvasModeRunner.py index 63bf58cb59..246e8139ad 100644 --- a/scripts/pyivastest/IvasModeRunner.py +++ b/scripts/pyivastest/IvasModeRunner.py @@ -638,7 +638,7 @@ class IvasModeRunner(IvasModeCollector.IvasModeCollector): self.lock.acquire() os.remove(pcm_name_lock) # os.remove(pcm_name_res_tmp) - if do_limit_duration and cut_len_samples < in_len: + if do_limit_duration: os.remove(pcm_name_cpy_tmp) self.logger.info( "PCM file {} successfully created!".format(pcm_name) diff --git a/scripts/self_test.py b/scripts/self_test.py index 05c6944ddd..0f7b8b3697 100755 --- a/scripts/self_test.py +++ b/scripts/self_test.py @@ -75,17 +75,15 @@ MODES = { "-MASA": {"1": "MASA1TC", "2": "MASA2TC"}, } SNR_ID_SET = {"SNR", "SegSNR", "WSegSNR"} -TOOLS_DIR_WIN = os.path.realpath( - os.path.join(constants.SCRIPTS_BASE_DIR, "tools", "Win32") -) -TOOLS_DIR_LINUX = os.path.realpath( - os.path.join(constants.SCRIPTS_BASE_DIR, "tools", "Linux") -) if platform.system() == "Windows": - TOOLS_DIR = TOOLS_DIR_WIN + TOOLS_DIR = os.path.realpath( + os.path.join(constants.SCRIPTS_BASE_DIR, "tools", "Win32") + ) elif platform.system() == "Linux": - TOOLS_DIR = TOOLS_DIR_LINUX + TOOLS_DIR = os.path.realpath( + os.path.join(constants.SCRIPTS_BASE_DIR, "tools", "Linux") + ) elif platform.system() == "Darwin": if platform.uname().machine.endswith("64"): TOOLS_DIR = os.path.realpath( @@ -990,13 +988,7 @@ class SelfTest(IvasScriptsCommon.IvasScript): proc_cmd = mode[1].pop(0).split() if proc_cmd[0] == "networkSimulator_g192": suffix = "nws" - proc_cmd[0] = os.path.join(TOOLS_DIR, proc_cmd[0]) - if suffix == "nws" and TOOLS_DIR == TOOLS_DIR_LINUX: - # use wine - proc_cmd[0] = os.path.join(TOOLS_DIR_WIN, "networkSimulator_g192.exe") - proc_cmd = ["wine"] + proc_cmd - proc_cmd = [ "{in_file}" if x == in_file else self.test_for_file(x) for x in proc_cmd ] diff --git a/scripts/tools/Darwin/networkSimulator_g192 b/scripts/tools/Darwin/networkSimulator_g192 deleted file mode 100755 index ba96e89897224de381218eadd10096c693ef566e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 154584 zcmX^A>+L^w1_nlE1_lNu1_lN}1_p)-HU@^)21N!CkYr$B@L*tIh>s6&ba#z%4e|$x zqGCo=E><4MoC+q8IU%kQA*f0q`XMAj2Eu1$U|;}YcBn*rd`W6W36ukN7pi#&Oc)qI zI^%ak)PVRb5GI6VVQ7FbAY^=eaY<=XF@%G~JcSPs^Ui?`Wnf@{@nIS`pyshb1t8|d zXQbv7q!wW@@54ukc|B0`KzvZRL$xz7K+S{kl2Z#x;!6^f;^R^MTk{!W z-V3NFL3|YRUxQsOi7((Q>4d=nrWzU{P(H|b5C)ko0M?(LkMJcZ9b-3d0?arDMh1|67#Ea2 zd|@20dFbJWYTg6}i2Dkl&I0j~%|kK@%tZAkSO`KmK+J*r(*bHA7Jq^?#K-3(#ur!S zCgtbE7nBq+#K(i&1(JbcsCgNnfB^|Pp!yS(Pvb%2P#hnhl2`(Ze6YV!&C76txQ_#> z9>gc)Pe^&>f#BFO@;=DIgr%GzyRWdjJ$ChL_$QNJ_idZF)%b3fLINT3<{up z-N49jfQ5nKK?@^;0WSlCz$8Y702T&@glUWn2|SRpQG$VifnzBnLp&1$!-}(v37#JAdGeWQ~0|SE$69a=YR2&=i;}j#q8Y~igAh$3uFz_%iFzA;S7wP9@ zCh4bC=A=N?N;5DpfZX8}f6CIr&cJ!9^UI7!g$wzNp!z_5WaH;z0AUat5|)WfS_}*f zpmYp1hCzdYp#fyh1ACYVga+9Q3Kx(ZIEoqDm_eZjcS}xYQnI$To}pe!Wlm-i*qs(o zH-XeMrZBRis}HU$E=kSRbAoCCTciec&w)jZ3=T{T44P0r!%{{DSXuxp93@6WU^E0q zLtr!nMnhmU1V%$(Gz3ONU^E0qLtr!nMnhmU1V%$(Gz3ONU^E0qLtr!nMnhmU1V%$( zGz3ONU^E0qLtr!nMnhmU1V%$(Gz3ONU^E0qLtr!nMnhmU1V%$(Gz3ONU^E0qLtr!n zhD8X3dUQVZ=&b$W(OLSzqucdIH-|^J>j!HN{z-=#9x?K7I~033O^;u`1?*XVc?Pih z#y1O?7#KXdS@TYVC68dsqDZ|KFo?>jDtfy%o&s-Mi!O|Npx{E7D(lWCSU0 z1qpa`JG}7d-NOoEzsO`}VCZOV{`>#`OOP#HVCD)&{#MYwrI%5l4OHE%JYbtFJi4bs z%r$*}h=IZIWXFjYYI_(Mz#5OWZvXrLKg03Xj=%r^gVyf9WCz*U**f9x|Nos+dqB>D zxaS2M3j@PT9Y&}|4~VEo@76hg|Nnn+a~A`HM`vpV%t0RAV73P+XgptdFrM(}JpSSe zC;&QJ3y>6n*dEP482DR2i}5|W_kseVyA@<+XKM@C_N^f51qUSYGUC&HwxVKYyzk14s#ot-{E^?SMz)5m0Q$9tH=pNB3S(aK2F4$-uzR?a_JM zqjPEkDAbIZ85myF>;j1*5=`0zaC&Ke697wNouO|)$;_kkphx4u72xL67Ex5+2>97d$%oJem(UcyzXb)ixg!@aSee08-O@fWxD^_JT)e=?Ra{ zV;Gs?yz|tH9XmiSa@_&-zUvNf9JdC6W61RaB3bMMZTSMFjT0~#s=+}fwDciYY)6o6J}s|3EJZ1(R?HT9@4DWk25fMz&(2Gh2;*Y zTVZaw;K2&^Pv`L$YtiItAG~PT4vGzM9EEOpF^Q3Z0UjR$;P~jS{qbV869WSzo|}&d z#2$vmmjPV9+X<2^K^s~;x>-ezgR))cDUVLq7apCV4_?YMFfhD0W(N+V4<5a>A71Qq z0&^hJpd9Vd?fSr@+xLY>r|S)m&J!Npp*K95j~K)rhLtDHZxq1xLCYYIZVwKR&O_iB z0@>pG;6*FQ%x>QY9@ZTEEkfX+2bEW~FJ8=cVqkd5i!5U43<|X)3JCK-HV5RHyOFyD%^WywC!f)ybmr;`=rR2AF#sJUVMXcyyM&@aV4n z;L&RuzmI|8g&A0->jRJG+6N5$t*T&8vwk`X$~YDt-Ju|bmirhOHZZ&p+|Iyo%=JIR z%UDDq=X%Zq6oQ?{_klJV?E;mMFWzqhdE^HJw6IlTWMJUm?t0EvF`I#bzXh~~)uWqr z0@Q|HQ&x!So3}wt{||CPuj>U5R!|9#Y5W9;@r-bzT;WE&+zWPS2F$1}3}CBo*b1mK zF!1+5JtqoL&%ZtNhDWdID~KKwm>$qhRQ~O*H#!e`9DK;=(Ru!bGswbDP_A^n0M>-$ z;}=ZZ7#LhY>RmbydRU%-J8HubNC@_tE`wNbc`MX^pv3LbUHihLxAejbP-wi|`VUlM z*FJbL7ovu-%k@7j`#8iNhQ%MD^c)%lvJzW*&JIFP&z!-aI6_X(jc+c10v?e>UU>AH zO6_G}cp*E^t`+Ut>pdj#eJkXN8Cm|6g;xIu321+iWn z+YAcA1E3)E==D8-O-BY?2ZYs{@c;k+7rmPq7(9A;9rl631`;kv&YT(n*92j;27ok0 zfHZZ3Lef(p&86FsBh97Lb)QGC?>?Bt$YyxJ&49349YAJ?AerIO4Qc{h@aPT_aN*zX z#o+?-SScvXc7hD@=-g@nHshQ}cQ1t1Y5+3h!X^fWZr3}_2N*kD@4P$!YTt_#V5s5EwLjSSd$<@F7@BK;u=Drb z2j$3a)|3NK&$@o_=oawkHNCbI?B9lsAaPz-u(YK|uj#*?3=EyE6951I-@x!92_mZw zm*w3Bk`;l-xevkzqlg+@gJP=t9i0oOotP5C{10wrs14t9^ zdbn&HSe6AMdu9XJ)Bpef|Nrs_D@Y~CQw|*9y1yID768?fpdN!qw}S+@eus!FfZB8r z@d}L>*&7%bI$h6z1F97q6<}2r1}_3ZGOY|C8$flq;ek#F2NclVU}mT5iRRifjQmZI zpgzOI-=+=;>Yw0DW6>RY#-rEtCnT69k(}%ba&oWh25`Tw}<0#H%)@&XIEd|lBQy5!|05WBawR0oAt$BP#l3W+69kZQ_-EEmRiS&7p&`{&O`IdJ!X*d+6Iqa zQx1^Y121l`gR1oC-3uzEUgUxLNuan$JKmc1|NnmmhU4IJ3nX;BH3lpK5(AY^5U~)b zSa&Ok)p^jPx3{&o<01uAlpA7shF`)Kp zH`v;=&Q=>xsoV=HGqb0HOcr6h*x3sz$+~+%+|F}g1O9=$)Y%Fu=(>AB&TBr%*a>EI z_k!HW?0cf~WakNw-r5Zwovk-Oj^YM8YAcBC(b;+dRK0h8Fgyt=0{4P>-@ikYUwd(Y znSr63qqEoK|NsBZdqE@ve@`p}%oE+dXACcW|H!}oVCS)3mTlc&b)CmL&-b!y?`#DZ zoRDDk=mi(3FE+sYfl8nh4T*kO&?kcul^LjN25SW+LXYm+hHkL$`M39i0>lMU9=mjd z%XE)!u*dng7jPVW$L!Jhpwqyk*ED211B0vKC6|s1FaE57MlZNo3JLk<1B`~3zL%b9 z{>8xG3fhR?ycZO143JiK8Z`Wy4=|>6f};Wv>)oxO5Cs+fU;uxD~JiMBtX4Qk8W0--Jrw>OS|j0LDQ}$%*n@H!G$j@AA)=Ky{(``3d!CF zKyi5<68##W+NygmSm+HzNC6@Qk=Y97^@=jQ|Ns9*Hxo2aJi1G7zyg2TH&FiF4|8r; zD~Jiozo5bk>{GP7RL%g(1~Tx(4`RU+{|1oToI!ov?p_cZocPVb=?1J0lK7p#3M^hE zt%f=XY)^M9NC`NUL5!CR|NsAw8Wu1&8^Kc(c-%x7l%znVlNDSXE~E|@0v(qCO5QI_ zKtfOj8(ye^c%TgZ5_FzHx9cB|#v`CAF!r!VckPN7>MP-$nW-y4o-_OW|36ZF-TVg8 zzdRidZoLYCYF8Hq$oLVm{OlVMR}CW8k=o(WYR-Fzk_^9lD?uO@+#Gq(2q>m>B{eP=S*he-X^#y6mz4cwWX zp)WukYmeU2A1`}py~@i<2WxuFf`yuuiY`=*ua@yy(96g_R@uD;I ziAOhh6bm#qcEh9d*bBC0(7*?mCZN9Ti_E2npg!@U`u+d^hygo9`xz9w$RnPyFE76P z{~sa`OaCA>Aa}Svc(LUjv<(FwDCs=@!W7~%1+dFLz=lXVkH3%sNp#nKc=2!v$Q=l~ z!Q&yQ?R^f9ZrF%x?90ag2>TJ`3+MnD4`>QNlrNC*2Dz`BcP6Nd*L+aGqZ5=8Kn>Ox zua>||P>k7;>0cr^cH z@aXitz~90N7OlPT!W5(vnr$E+uYK@h4#-A#uo93-6Coynnwj7L>-NZinsfqg(uo(Z zL7HIJgOYvN5?FM@qVvOxS&Koz2(AS~54>3O7CAbh{g>u93E;v66duQ2KY&eauBZTw z+aKU>xeRgD0nkvEM|VMmM>p>>Q17tQ_l8F=s6iWgfSpvJ$1`u{>FsC8cZ;Dw4L1H((uAv_=>Ut9wj*LnO!#1c@)05Y`N z?YaYO3^;W|jq&JqJ>YTNp#tn;aB7q=ywrIO?Ag){9^IiE{$B*U0c`342?mCj;K~ow zR{)nw%|{Zzb=HL!#fuQZwBkkUoB#h2=?zPIo`M+IcYOc~`qahXpvO$lJ|GEDdKLuR zfGs^Yzk!S|!s{dsun$}x{0}q$jka{U-g)s@3KYV=4?H>>K?PaYM9_F`!z0Fy(DxqQ zJ3&G(K1hLvYC+{}M+(G_YmQ$iQHD05p^X8dJFL(Rt3J z^VEw6QrJYfq#+i60~^A~-vTzbV*)4xL&BW_qyT1XE9j6wkK?WnK=K~F;6c>~FZO^+f^JY7?1o3DV}S?6RgfOO z>kW_QiUJP)CNxJvBMZfm1uss`hdUCgfbpd?%oo^`9mshe%|{%-gH4brPH_Fx_~rqq zG2Z#Zr<=EX9Rq`JH>Xdh?+=g8t)Nc0N9R;fcebgm`pL-SH1Jvj!@gUQ~g7+zJx$=-vTR{$jZVsCRS)q@%kREYVz9!NA{Q z0vcV~3leAG?*}*4oA-jOX5eoHomc144K)Q+ocs?o02iN-u!2~B{1~X)_#y*TF7|^v z+aM>m9_Vb{0&-7_E^L&e8!XWLf|0*P16_;>l3u`bS;xU0WKhO^3F@~&xZr^iP>eyi zpdrJTSX}W)oPpsbCn#KD&aS9vhIkG%cMNh+A2_~}TR}ed;9uVg@~cN@>jF?e40QM! zBop?6`5;Glbc5x(r-D1`-FrcO5m2K?dmeNI5{omULC$CbrweH4RaCrSm?*)zJ zg7lk>U%kWHZE{{u85(F!)L8;&71jUet+!f(JaT;Q@;X zuso>Mc@7d0VROK0z{bH`aonR58qOAAS=OVgK#DNJ88m|7(Rc(Dnz4sp?3)b^XQbs0 z4v_vt;~UVaj~?Bubx>o#0Sz7^^XP^QLO_~R;Bj&OR(|kkKnZj-;AJOxhzTs`(G1S< z(D}9(c_JWZfn~ZoKu4N3KNJ8DepN&A322xd)c9B?3R2e#;hy*CYy}Nuyx0H{1+l?H z3ZP!ui_0?+N$^PR{32W51&s(?o9x6Nc==-vuqS{_4oCa9Qr`3T@s>x<_zp-Bn1@;jtNvQ7Avp#d2A#)W6oaE45}u%9r4=-s|DqNm3Sxt&IeI}k z^5s;JWe_L9s*DmLQ1F5?8!X%c13bD5Jv=l&d2~(%X=?^&JqG^1Xpqgx&@nC(Hpm^_tsu1?{Ob>TFhg=9WRUgcH;~a#mvtV0u@9mR;zv+A z1&^|KKtw@oa5~+CqzRh5x&s_Mx;;ERI`={gQjbnZg$f-yPK6kOFc>sm`(i&t6vPI* z5~8_xD>zo5HF7t!7U>1o5uFEpy1{kW3u9qW0D?wQ;R!F$1DvWgKY1i?1xsjt@?ZuB zB{W1KF^kkl1XoC~bX`^9p$(2NkIr*DKqhu2QaG zI;?4l$VHt+0Un)29*CCae?E9z9&ZE{C!mZBZp|KVg_TC#V3tQW?2Q7T(e2v-svD*Yg8EXRRR{Xuq~O}&(d+vTG$q@32o!LjCUxU6 z22sk z!9tK)7&d(fYN&X8{|TP8I_?UZ*az?6gPtQT1Vpo+5d zqKCHc1JL3!(29kF4;ehVq4o7KP|u=#D#RLiC+#(oe>K1s!VCq~X)l(7g&^gw=0UL0 zouGMXh%4Gbvdo}GIiUx@ankKs;n8^;>ue=ms}CJi4cXRCshAeBsIi@*l)?mHZ40 z{QE3ke4hjk>6e$l zbc3Wl96Y)M0>DZ%KY1`-^yu^eDF%tcdzFVgI>EEr{H>scb34GjlTL7EdJ)XHiFPnL8}1=Z~y zoxR|isdFo+I(Xp#DsE6B98_Pt&;$vCJjLu-;L!~>$)g)G=h6)^rWFxz- z^XOzz@#uA(;L+)#!tp|t9~AdXnroLZL#Cy`;RP}j)b4<}y7Tx89xiAwbsm4=zzaz@ z`zC-ipLy92NxBojNgNckkV)W9UIqpau(NyNRTAjPZMYR+rJ#D~MI1;e$X2irsE7B$ z8zcnQ?K{Dv8&czRL;Hn?Uet0ToU@S!;v9XbbKr$BxI}&_4sjj0SZISPWq~LKyQK5@ zi~FEB1eJ`IC-_^%7+^I(Xa}Om=ivmc!8p_D3R<$@(Rc(@Fe5LB0QYAh<4+$tOF?Td zKX^dP>j(TTpCE1k4{#NMECUrjAiuiac=3rF2SULqLiC~p)2$<|Gr=R`wITQ_|b=C6MPJ)^EkvN38+nH`jE`H^uiEq z#-$E{?$S4%rGLPS1i?Z7VtpUjNuYTx@H#}qm>p!ir}51LkYhV*(SvLOw2I4v81V84 zXm+u?cEO8Yu+^>$KxMonC`opLN>?bKA6%f`=mv$~oEJuYpm3SfdF+J%)K>{0%eo<$4Bh;fh- zeFr#0Ld=f=ncwXT(%=DFJ(UCDPXNVo%PUApy8zy11&z@`je4O3Q3=)A@xlng?*O&D zIzfw(AQni2g+niRfGk0-R~CVS$lCP+e+#&kpxq0OgO`njJc{ zk~2HVr>+a24PbZ~w!ovaw!s6GX2Eszi`g6?bx;pND*p_qkWaU#1GvOv4om>erF(RP zTZ%s2U}YYiQ$ba>4`|`(L7!gN9k8w)q+mJ$DVXN)f}DNCquY0fM|bD~a7F|#OL(CK zwgt=v1tz2|90i5OO^MF(}Z% zL-T@1r|Sxj?n(!b?$8w;-LMYWhaOM|%yk9S;7X{$=Ru=VV3VpLCN1#jF5Lk(4IB;N z8XhvR@Zv2S$S#yhzw^+G>5vxD0)!q=JK)6!NQnbUVc=B{FV2GXgX?EdI)jZSoO>~a z2Re=V;!zjGzo23PoV~#W*sCpD{vu|jK(2fMUVGem{DmkBB>$|2XaX%Ymh>W`7OkJ0^B{WFFZOy>*0^T0EL7{Zz;&4 z3m%<^zn)^W8 zL!j$QL9;2oH(r3oDm=Pt!E=)AhxR^We5TXcXv$M<*jB%#nQ$i$7|c2aiusI2?ZgZeoI?6goeLX`g`M zfzD%)IlI~)FF==qK;}3h^;7d3$owWKJ%aoPPGc8dOn`b1v@{>oF9V02>xmcOzDu|7 z3D5*+bL|TT{uUijaCX;TcmWy#1}&-Vu6^P1jis{QfeSsU0E0UY@cVP7|7u-gK*=o&=_ zl6|1C0p*QO-v{7D0-!}6ogM;^eFz>BpjkAJP7ejF_JQI9rXLi(5WNN-ogNxc{TARU z16X=N&L7<%50!p+0bWZ3&eg~%43@t^}ZOSa^UgbAhPA79Ii~ zy{-^F-Jp3E#DH1_$W@S3g~;#CZxjp!-j0NF5j{z1rVV3XegYCof{mqIO1JAEJcfcDaW-3(1X-M$ZeK+|#E7SL({v=Zch zfCi+@PlIjY1NR3I_Tx_fV6z=0u({6z(w_hY$OjK-9wXL04*1;z3PX750S_;Tec<&x z$V0NAb;$g!vl0EG7vSa?c+%D64``o;?+f^Vi6OYia|O+fz5oyNfjW`khG3y=-=mf3b2hB?RUhwI3J>df${qcR_(On8@19jJ4@ac9v;nVGVz^6M_ zz@s}>!l&ENqqBAgs4d;?yThkbM#ZBuMg_FmdxKAB=nBXGVG172M-rkPzKb^HdI!nKRs)26b zFCN_i5+2DvJs5v^bOzu`-vXdL0JVQQYk$0GY5+AAe{>#uk*_$${P3QgHYj<4Dim-T zSqSMDbyp^MG=gs7VgQHE@fYuY{Qv(Fbk!6{uLndaBqMZJ7N9CU3{r|TMuFs(6=1ix zet_f-P{5&v54a?UlsBMy6)8ZV^%Z*j8NlNYEjvNf(=9(p;K&c4@)cY&f%X&ne(+%S z0JR-JZiUnjNbw2U2n*^pxqf(Y5Y*D|W@Q5PlUc!`1PX9)I~BYd5mYx}mKUJ%7aVrJ zA3Q+weF7fco*ba9C*46WJUV#}&*$75TBy;-9U;rej=O^Td5|sRkaiV{2-p{(#eLx321t*e@2hvj^KL>J&rqqI$aDN#~s0!?}3)>fGqJi?g$$40f|GGX+Z<6`DKGg zr|*FmcR>R+oyeP^J6$2Wem_HGHh?=3;B|YTor9empq<$s$D1IRMKUmW9B=vovI$iD z9B%>*Pk?wH$D2TxOhTF9_<<<60TO~RLA%00Jdfi|;FZr1QP9*qRCEW3hKPd7L=ey8 zcoS%$0+hJ`L_-wJKrlg}3F3JiZ-Rxj$ML2H(CiaLZ3Th}yG_#LcvA*K6tprPYC;4; zGyuW$Krlg5YEZQn2vN|eEmRaVYy)K~AQVU-m;wkUXwCqn_IML0gFslI1_+3CtO>O8 zjp0}mXk8n_u_n;cFUb5>=d~BhKx0E7RUW;db;h8*&MRIxg35#L+7%tH%U@VmLD!&l zxh{wINI<~@UM}8Udg4Vg!id@nFH}E)j(%{R0gHXm;L;3_&JIwS1=8~3RVCCwk8aS& z6L=oth5V=g|5X@0x_wVT7BoVtnod{HLgtrtpwNe~!6vMLnE+eNcLGwRfmej?0$tAN z(Rm!U9JKjJ0eIc#i5JRnZD9X)*S>g>Q30CI1h2*ko$#XS5b}yyaQhfkKKIuC@PICO z0VOO@;{j3(B6lDl^$nyi0%~wT`0)Gkkje7!}BKptyv{H@|V{tOd1mnjifAf1>kX^9yV68tC>bpg8Mg zl?SIJ-wPheA{`!#hyFkE=w)qb0`>M?f4uw(QS%1Ie+uE>gYmCI_!nUOqY(aK7=J5- zzYWG;3gJsPK+T^D;m?H0w?g=`^-%dz2)_m)_8-v9sq=OOXm{rmqPS-;=^|NoKo%c1G7L(`9JFF9ntIV976_P7Az^?xDc#3#wu}&%L+^+ARXEWHI-5!0NjfpjCdb423g2gU+_`P-uS0 z3R+(^6@CH)IKOw+g2p-#;|ra&KOk!hPIz>lLhb=W>vvdw0=2uKmHhD+pp^^gB?MeO zsC$X1?|W-+>;jeIpjA_yt_NOh2c;pa{67HN5(Zi|xe#P+cP(TS{}zxO z=**Aa+5;Zlr3*lAR$vBYg4!35=3ng$P%Fv@WFTaGcESsLh=Lg&-K7&i8bC7*P}hQY zwXlG975A2ct$eYv7*?h9)*g7l44PAb?JM%=bluSzy2S$|@d~z73~EyCju+`g2!D6H zsN4hIY=lUk9?0?ANz`~PXgm)Rzu@*bq>Kg653B|iC*W2#B7H%|Gq9@%-MbDMBSBUV z&L7}92%g>^K@3Jo@X+)ID!;pt#_!SjaR1f*cyStT48lH;dQe>f_6xKR18T{Ex)`1u z9-W|VcThHHcMf;ZW{c<~pU z+(FYokkSjX_#D0efZRU-#Q}H>8oo!DC{G_6K-E z`U*@2I)?*ppMX2DAj{6Z*aDO9JpN+GFVNTo=zJU38!w_k`4&16)DKbg!K2%O13cQ$ z$q1e-OFstI@B&oI>;|i;eeog)G|>$1q#*(Tn*Nc~cQ-^CxCiY5-+u}T577BX;QZEk z{KaHYKInA)@ZuJP0o!u<;zi^eaN8C#JpwMfx)~rj6jb8EX3{eA85m&W@o@V=eY@i? zK#g~3%>e7Kf$|3=|AX6zr5|2Q2Bi!f@d-;0AoqHMoCj8i$gjxu!OMpvh(avo!wb-E zWl)Ylga@d60nHbFfaOn=@B*bL@Sybn|Nrd?)Q7~BmoT&HvF2~ku+|I69vRS79e7wn z^Mc30A573dgl89Q;SKjcp7|)`@FK>&kno3;XWgLIH*~(n|Mma>@ZJ%$007Nh5}L0; zIu8vtehx0%!H1%OS~DJ zJCDB*2T%0+Vw=QTsAG1}qr3D6 zxFYs_@FE?;C)joJ33|0<3bglNmi@%xRM&*YWlQKY!I@nR}SAGkz8WM*Xl85kaL>_klY zf(jXMqX;yk75V|R?)TtNCQ!x%O~*kBOCwLs6P^bjF!?YZ^XN440FOTRLCQ? zY*0i(qYs;Zq3(zD&!LG*5VWKYZ+it{AJi@a>qS861={`qm%|spD?>oXL0CHq@V9^) zg`o93XF*vGB-|Y+;L&{Ok4I-9GAKX`PPzQF50Q2OXB{eVsIig9>*ALJfLc@HrUv3?I*e-xHJ5%z=CzjzEf)didu zP}fty(i=!UsEvLQqD}x~{S?6$DFaZK z8dREs&QR&ZGCt)GQGj!N3UnGC=oB8v_!M&@^7xc6sGo~%eCikG_|)-ugugpp+*~;% z$EU!13m~-syu`&(AAs^dYW)CBzqLPJ+y+$zU}F&N0g!r7UIXW4PniUWOk=x5?eYI3|z;)cwqou4DJeE zyZ|~#o$z?oK9~+r(typEfyb*ORDH zjPa`Q&7e>NEn`0Rf*Wj5?TZ(SKn!qQg=peJ(*wNx2c>t2GPL>u5+0zsr5ltVI*-3d z2Ggz|UTD1o4-p{7t5)6w3lJEu+8G0?Bq8I4aQh+Y6*RpLZ7ae050Ls3WIuQtGdLa* z`4L$^qzBY_`~~=cbV#a)M>vXqi5qX?NAB{V=!dl*iCRw$9&3Q7r4Lxgmsp^lhC3IQ zKC$|b`1+Y({wIDsDE1*ZZYdcLl7bjP#CQ;k2P2m8Ac!caEl%_CpnOQ%8`LL9>yIJI zS9p7A5kfIM0wL*zxbdJ(IQ0`V9%KT_h0tOFy#E3`EeDQyP>TX|!$Be_$AZ`7AA13w zbVe%-knA;BoK)3uycYpt8~-R>3+|A!fLEZw2T9PzKNcWNqR03L3)b-u79z$! zK=I|#dF}-_!3fWpTOy1|I)H+}`Ot{=x$^un1|%!RiM@`HgM<47NWFoW2i&HWa|> zzZY|EfT}R)no<8}pms87*)QXZW{3o+8T;ae8C=4V!=v#aq+RZN;zb-p5okrh36I{= z2OhnlH(r3xt^!Y_!`f@;+wtw*kc;wXu>_X6f%VRG* zz--X*te_^p>xmbTt^J^s=6c|T6sX#VIuAPDh*=(h!V@&c1zL-MwLOb-ycJr0h`ay= zC8&HlnJl>rmVN;* zh;DdvmR@*a`v@dldjouCaOa^HYhQt@Uhv&M*z0@9`Mu!dK_N*B-dIC!{~*F2>}C%R z(55c%N(#^nleOy${uan#sfb51PFJU1k7EhmIVOVQ}o@dmy(EpWX{W*J7=?iWJ8Apo#%hI(0I>m<*AC zr1vnm1ZsNEgD65x@8Cr#&;$kRzk$jdr1T1EuR-RiVe|QD`*RWD3vSnC6`7UTY9bCZTT7O9W^t=+Z-UQ^d=7S%Q z)AK>FI3zu%{=}7@ANtTLJum$A|No0Smyp63a!4yE-!Q&743U7OXYhOsIH9Aa=XnrC zsOcG_{KnE>qk8&oc>qctkn{~Y@)CR$D5R%$;zc;9;SNjR;8W9~*$rBLBiAROG6B{< z(+3&adHjVrsEh%{AddbSq<*EWyayM|kn$eOcn#)!FSvaMnx%Dp@xmOzdGNvu#K{Dm zoeY}2dH|U@1SPy1FZe-H5YJtBQ8eTKe-F623kY>5UOWdo25k6&7r#IpxH>`|pB|8E z$iy#l`HwY!CtN^EdzZmw5PJUhg}C^|izQ$NXnNQX(*A(t?_Q8~pl&+&Zoxw@!0Ivb zH>iFFwM{`~BXqAV&ic38;srSUKq@n=?IZAt6=Zpk`KaTapz;zno`qxm)69KfbH4wB zj8fq$kKp5P#JBIjJ#b>(2PyBsi|8R*u-4zW^Q$!|VxS`ei1|f?|KaXWf+z$H{=lt( zjOTd3+Lxd>0_Q)x?Sq-H+}L~&R8PEsq=yqP3PC5jf^+$?7pCy}Q1te}M0aA!Q-pts z>(7AH)1rUC?9prD0PZ8aV0sL#A~4q~?sWro5U{t;u+_Kt(knc^s4>6z4xFh$>rGvE zytoJ+X#$rj8=&W>)Z$wI4$c~&sSwcm_ZyIu13LK~Y5hCMec%aWFyR53Esu9W%(Ja{ zQP@X#e$f}?K-l{CgvluLi;l?ii!LBJP!)hQzjy$m0A>CA8*m37?8yl)?n4ydoL`gx zw}4^m-{-m@&o3?p%}ZdLU+lu1UrcvK_`BmpWiKt~7qOp@11aA@`4?2iLh}r`KL$Qi z2wEb;$_Je34|IPis6+>sM2PwWq#kZIsEvqwelRl>ynTdb^MipL9-RT8Yb*pjIz3?P z<3a9&m0Kjt_nmMAt&{^TUUEfWpFSHT1)A@x0S$nVzdk+oGN@TZjrqP{P+A6;^N8s# zr2aYD`b0!}0EG*y!ZrSfDi|6C^x9^KIb#(|P;_`1};m`gAKu8yeKm{@~GD`r^gTz2IgM zf%(3Z4xln0wZ8~5pKkMcs~~`jD)V`e_AM-rgO>tA`ml`$p;ZB7{j@G<=Kwf6fVZKL zvwr&3QAqHD*H6cS#t<>rPs2+Ql=-sEQ0Tpr7a&cJ4KL<_3M0e-zB&##65liAO8!2)RNfSSJ3ncI^PKrp2uGl;ZqMuudw(4=V91*8Dzb*2)JMY zotSd$#SYMBVa)k4$hLh*mrNBDP-vM4;eTlPi7}oIvL9qOq{~9y`etuX4G)_7u{_8R zTi+bx!NBms3FL#!T5y!^1C=Z|g;Q2R5{|?fghmP!V7DV6s)7~2jalhq0AZygQeg%$6}i`x&Rt10*?%!#XtJ^ zGp_UsN~@si3HSO}TW}i~wAT*WjRl|V^TG`rprD(jRpFYY0dO zq-a2jF8Fu`BELi3gB%~-;PtF{`=6lx3}pNf+Lpt+-V@S)gZ6(wV;JBIyFo`YUGP9% z&uR;jT&V>AhyKJON3+@bmm3P5>nV=&+X$_4&zH9^yrAUE#qoC$?H|Wff4<3-4u3x+ZIj{5h3pUWgInW6koserUzJbKM_d*UA zKjzU5z8Cxd1^C`N@CaLP?T;5{K?-|8-DU8N6fgFI_}zO!$B~03MbCk}JP*`jhh2Kv z4?Vr=2Y5>zDBeJc476(*H1gA3df)|zDFegHERY^hlLR@&L4yrDJV4f#ffnU;x`NK) zec%B)!?+)M!`d;AUeK-e=RG>XhnTS=muXxw!@=WB*>#z zoS(4_<5bICfPSDS!>)b)XfwktSTp_(D8wt@~A23<73 z1JVD(19~Gf#A5KhBH+XUzF7yfu+*m;yh{>n9Qf2=(1>yOUeGnpK9Cz%e7dKCPRaM^ z1YiE-1G-}md}oPI=Os_jZb9fR-7G2|-K`%$V~yaG?c0sO_n(4J`~ja()9~V^A$&9j ze6iSz7uBfeWgzyy*Zz3XZ3xc0DCI4vya5F!uJutMc~JcU%Gh9apauoBOnTt~DxDxJ zj$z|1@cClU891)sLz=+n34?BPMdW;N^Bj5IL7EZS`z;XVAIy!Q5Cr9O(D_8Z7hZs_ zLIag>pj-}JUkAEn7PQ;;#Ea#ic^6QA1|6mm1uE>p1v7j;66Al>@peRg2M!OgMX>$? zs1b^7YbB!o>#POsRYB(e@My06A;3TV0Qejd@MHl>`HpCBfcC$GCh{OvJ*51F*QemJ zANPC$C=Nk4O@h}KfDM4?$K}87+8>af3aAi-6xZOI95llKKDe#+!;6gu$VU!A%!9cH zVjpDh3;z9)5dT5dzc{E5OQR6;pzZ^m*VK6M1*kOW1fR$NOK)&_ockLQ{Y%i81v@XO zNCd430NtSoq91s4JAigyya1gw@!~n;DuW-OWAHi!J-P!pJUT&V8i15I3V`>Z9DykL zfI|s5ZNt+~^Bc(dY9RlC(kH0q>Mi~7qMrw;rQr@Q(!kqX9=uoxvI2a8YUzg;DacB} zMI)%T0gX(6My$Vqi-+Sc^gvobD>OiNwSXrzPCz{d+VBNBTLM%c?Ev2dEyM%5BYg#9 zhwpa&R&X;1abhW`(%k_%)cr*b)Z{538Z;K&dCa5Rb;bV+9j@EET(`q(Sa6R5bU$-8 zNMYyk7mGoa1L!)OPS*u5!a#!H1O1`57DGohL7U40AOR{2x}+~26t|#5S5gtWXS|Sr z=$--FGXWbDh3kF*zVG4Xd5{sH>cInid>0~rLHd)>_BE&>1RbD+HnnGfECcVo1RXAZ z0?Kg;hh{h0952$K-Q4P_DvYw*x4d|#g@Dg*7 z6`&*nZ9jpJHE%uO0l6-VzXfy(EhHmC@6H3?xd=Kg1WlBQzXfzc-%C}{sXf_{))eSE zUQopas>@y+2K5X(kH7d0I^P0xH7@in9WL-Ll1?uUNWyUvc&W<_zBmNbRDldcfsfOF z@dz9%pgZqDC-h7ORctRnr%Hh;KTw?jZe@Y*ym?^`waXtwgAzaV0y=vTA9}+JC|!YX z&G~(7*%OaBwT{#V=47uk$$gJ_*BEai;zwWl3`(BcnLnU0AvBgub|fDi(sgc-5j872XiJ!%A*szGY^990RfqU?o3c~ z7~C@a4_apcS}y>1CP)~IGrU>O`t*uxycKfdYS=l@-~Cw7IM8isO{Y0 z(G9wr$F%{v@pJ~XeKy0RySBrl8+1k2p%PJK&w-;3kz%cQ2?p^@1H@8z@JB z8o3Y$LYk;xw}S5>gt`ILc7(e4g-18^=Ekj{`?oy0r$XA7;0r8Y7=R3IJOawk;O5zm z7gic*%`?v;%=t1zdjgdCq210SfOfV%cvyqh zx2eG5$J+G+HKIfI;i4qjt`ECK~o3p7+7ym$nf z3xb5oh8I&Ic5EQVnc(FA1XK=yLd65NI0ajK4s<>)s4W7nM-cT@;~P-6^gx`)ji^eX z^#VAmn`K;O_%p^$XgB3gY!UA+q!daO{J7u&$t{FX#*x@UicZ z&W@{q2dEX?4LTq#bO-20trux(3=A*Nf=UWd#kzqJUKE3m4gepD0BJm|gw!z)K#>nA zok6$nzK8*>!vlw6E9jcV7d{|<_g)Yibb4Jk_;y94R03{@fQ|w|#MDf%$-Xx{8V`aF zwg>G}cv%c-C~SDK2XrMGsGGYP#DIjr1^(Vi5IxK8WAF7sLkjQyjkj|Nk-&GO}<3#U~3u z)1RPo{XoSr=z6#pS3pGtD5-bCO0XBOt9pBDH@vtCTg?c)6|j3NxX|i6^x~^B$XDQ- z2jLeMfiCj_75&f-wd)FK`@^Ff`6iwh4WQ5iT_gtzc5Tr0O|77&1^9?7P&tj#MFw|u zAr1uJ2-giZ67RkC zWz_x|a(fum|7r*C3Iip&~y3fcLY48Km ze@Bo1bkOiExLt!P4~k##{LzaSAs{8-v1`ya-xn`jKzztq!r)RItQ*$fYJ3Ae`UV#5 zpeO}R>4T~rP&ZrSFVZnT-`x z-x)8afKqAa@fT+gkgV#JjV~4QeV(jY4LydPX; zcDeS$>uAsk;b616Ye8i}!wbGY|Nq1LNT6%)u=PA{yl@A1?ObWj%xt*3t>1tEBB8+-rl#tTNI%j1xe!OJh8A!Lx- z7@!PjMg8IdsJ;g`fWTWc8jpZdHMkeC;>8zfL@xr=8F|5+1{&mr%dF_P`I0=D!?K?brLr=W$e*gbJQnRiN)Z74h89I;=)fPX~^zma5oy%vYhcE2{cOCdHlsJ@X9MZdF926?LT2*8hXQ{@esIh z?+gX?$WMSTnFQab(+Y}N&wn zgIZ{y*5eCvklmm_hu$`=4&p;+U_b>8xHpU?^T6{;CMbb}T4A7|fF{^SpsiG$$6rYO zfCa7q{7z_W+5W_f0MKwkZ|#d0>OcPfe+lX_f`$MgIcdiWr_cZYzXZ)0gSR?BTnlPM zzNmy+wDCK#MIb5cIpf5O=b$73%8&cL!zOV-j)#?$H(qA{1xGQcnD78a`7uzj49gFY zLByg157Q`o@q;TR~m=<1ZXRkqRD2MtBHTUqaev zAiLn}gTUQ9h%ev^0HFRstAF9`IY=`LVLGfn1y!UVvvJP{fyYu|;S=o9_y%-Eg-5rm zfUDsp*UroE(~&`^H+O$a*0oO}(WLUL=1(@^29+X+W=?g{tWU_oQFE0qrI2JpMuj+~EWH8q^KPQj)=a z9R=!teIea08q~w7|XDg)ZwiQhEf@kYrd}c$~e#4`8 zFQ}vRf)Ak&>_(4n*cctiaUR{^F*+Ye2hFD&(uM2>kB0hmPX%=qeY)pDMtUFnbVf_~ zbOsCfbWa62$)|fRs0ZuQ8O`C-DeTedtnflt6zT#*+)B+heslD)`8Du_Wr79?GZvfxX z3-V(YI3<9_%o#uj{(1C*mKK0c?Fa3eUGO3sybl<}2Tc?$KpNVCE|CGvD_wZ03QEBs z<9346FUi1)p z;zcWHmZ=jwUIM?v1k{#*xi7(^GxUc?r|$HMiSebd@odnFnH&5q|3G$unjN5) z>C*Q|E(Z-4f|DX>;S3~wp8#DO^+F#satOLx^Ospa|H3 z6anD2Kd5c82&AO*_={VhJPis8&@~#pAVE;~2K(qZNZ+e>|Np~Asvo?VgV4R=g+E01 z3Svf)A%zF1H8vAu;1^IT0;hcB>KZye()b2+HI+xVtAS5%sDe*#EU0+^itZoa= zjpqa4nHk805vc7CTISRM8Vu?L4YGNF=GPZ^bc6R^9e~^r?z_RK+jWLdx9@@%+K@Qv z@aPPk@bW&$@ZQ=BFHAw>*`QLii`3!>XXmJuV@;3Os5L()b5#-0>GGpzc~X zsEZ4(NnbnxiFZSnJz!^Xb8O*6p4*TK#>Jr;(=cNgU7g_>p4O56VQP+cykU>UI}<~ zf{wceos9~@r9WN}R9_33M1ajL;aBhA(HZ)|qZ70?8g$`j?TZ(OK~V#_TIRxwZD0;) zSClVk6%9C9z1RpA1SOl&6QBqJug3>xxMMF|K}~E>lM=kJ29bne?OC+>FVKLh?+*`6 z)HUZ1Jeq4CFz~m5hUmbh4QS3jGxPzZzX(2dub&S*gZRQD(-$JlcmmSMMX4{K?ORy; z6}~6PiEK>Tk$-*`R_B zG?%3X(hu2s2CXzfYgE<1shTVt<-{NK(zi8C_#hoTmaX_;PaI}yzl}U z4jQEfMQ|rH`Jv9=!tL__olXN8V}q=qgVcv`c?XWz!&u@U)V2e;5#l$nKheq)(Eg?e zpgt@{;(#nDy6{37c~CSMly!S+AG~-ADxo@$zjzAjJb~8=xbAqd0wf3?fWuL6K6s%D zY864$Z+HP};l7*<5&?~Wg65LJ*Uo`5H3)}-S^xpa`3shi5eXMmtw7E<=ne(ltp$$( zaQYx!J+$ltr6W+O1-%^x6z0gm3(N2DvK8c9(861g`X8Wsi%_Ejt{zsl!p#Ty4$;0r z-_HRl4?q<(=t5=4nloWgh=WJ9kzItE9uB?$-2n;@3wU_|F%RNLP^H;h`s0N%=&%DE z=E3jhf;a)xBm^ZVaQC40#6D09{KaEXk^r@HK@9;=W6|gtQj-g`AQ0N#gw_5#JV5u0 zbeHaUu>!PUxzqIr=;A^Ka6t`j8`Q3VnA{05c>`$P5` z@uCH0GE&16)cXdtIzYW|km?4HZpeCQkM7Wh7XnZn;0aUM_GUx~L-Ic){2+k=nGN{x zq8T*g1PK*z27?sFF!iAO*dXdbl2c@^AY0r~6z)Mv;G3qkG%xgQk# zpvE7_KP#Xuz73!j-wRiWp+CS2kvc$zfzl~xX`nU82HZ;nK}9UM*^4}X2N~~18Ds)A z&_NvoowFbZgNLCXfX9iXAp)TFk2kRIfDo68(!#vtpE=Pd-Q_W8NB!nKD6lg3uBNm zz2F8fxRLr8B#yU{+6^%WRQZD|g{|P)`Soc~0D`A$zyrP3U?zVrWQY>v4v4+Uj}Uj< z-|)}|s{#cBXyHOTC{8=U4R83G0`*B>6R0b@jVhu7br`Vo?U5rrQ(54?B{ z8T$io_Jb@KcRldp8blDZ6&2L41^ zfSdsIWVaJCY8XX3Yb&_lNw-B3ry;ONj)%W049yVqzRZb1CthD(h5x4fJr+r=>R63 zz@!V9bOVzfVA2ar`hZD4Fc|Kq3Ybg-lNn$# z3ryyK$viMw049q9K!X83y|RS?3=EFJ|5ZEr7#JpGfUeGY`RxDy{~0l$jc<2AEKm#S zruolHCVl34yL|-2!6ygIKFTtX>dn0f==P#F_?Ty#cX$KrBwsB5+W9 zBSQzo0+sU_{vZ};*f0Y$<@+)Pq;4TdEDFQ|?OS{anrF_q1rl=uiG2aFY(Oj_&|roU zh@}N$fdWTQc1Tp(5nhy@zH&u9d(K>HOkCV*IP{{8=-F(1SN zttZb|3u1x#4;gzwEYSMQjME_25slui(0mS+WVl4x)SU>|Vb3iQ6T^TPY zfmli)u?`T+5X7nju^d6Hl7IjI|DUbOD8mrMz!2oJk&$5^BTpX-;}ymoj2jsldYET0 zGQjSf|36!kQGp?lfgw=7iHTt*BTpX_!yZPPSxgKInS7d<8Q(G~BB_;R6c7-0U{Ka$ zUxW>%DaE&==G7G~-mWzz9Ss2c82*2WB_{hOCn~!lP=U(Pl91M$i zd0w+H?B(U0%))Simvc5B<4s-(28NGd<}Y3YxOEI5KS(hYGB6bKPGw}6!^ruMk?|ZO z=Tt_9>x{+-Weopk%Q6a?2xKz2m@qI@@XTanY+*#WjDg|*e?|@g9%BX>QwE0rvlSU7 zE87-t480tZ}0AvR*BS#cd8e@zCl9(x@E<+XrL)K)LORNk{tep2)85Xm0USef< z%F4Nmjj@@H?-DD+95xVpDI47R|7Y`p9B;%ZqlRRbAS3rTM)}oDj8mBm;KE?Pi8J^x zF!%`6F~n#xFtjpqE@ouxLk;WLVEA$G~uwk@Gbp<26)uyo?-L zyuOU)NcR3`k1@hL0ro>UM)dftf>zNpKGI6e9WBknA!?d1>;XkVl+-A4L%$(E|g_3-Q{DRax zg_P8s#7c$4ycC7hqN4mFg@U5|w9K4TD+SeJE(V0!g2bZYR9uP`bQM5)6jE~wN-7~b zi;|EugDrB`Gqf~P$jmD!Em26yEGaH2N=?j#DE7=NOU%hk!IUg7%Fjzza0h8DuFOkT zD9NX<)8$WMdn13AG;AvrNGFTX^gC^a!fA+0DeH&vlHvnrK~ z!41sLELJGV&sWGvEJ{zc0?XK{l58RuLpg@;f>REuFT0QD7AVM$S9a;ice*cZhCsYL;a$=RtT3eov#X~n4}v0MxaFnv}E zaDXFjL5jigfTUDG0pfbFI3j)^@tT*In+nndaSO683~z%xqySS7b~Lhb1+WOR=izG6 zy=JA5SDKrYS_Fz;a6A?(6r>g@6hQo~VW^{EqzQHtH~^3>DbC1DE76Apj6x>P6b_Pt z8my6$nwD6aQ(~oHpvlD$nwMHpkeXbQnu5;>RtlhmQ;wd>Asz&U0wifGLlU89igi&* zL2zoJUp|NtQfyt6To#g3S9E953t zWagIUDioI%6yz6y{0vgZz@V7z7hGZ-A8%-Al9X7SnH-;)2FbCW$$r7{hK9)*iAC`x zMTwau#h%HouCA^OF!ja|^`Ia~Dow+w9Ne6eVPIfjW?*0doyY(x#6WvanZP9(sDZ`6 zsK~&?n8CovaKMCt0dxi{XkD}dcn3Lz|G|WTq2@CKgMv8&!;;So3I&S zd|_ZHNMm4l0-`e*7=CppSup;~N7*K|ce7 z&Nl{zgeeRRAs~7#14G6)28Mun3=B0OdLaYDgl`NC3QHImmVnf+WMJ3mje+69Y6b?D?+gq98yFaLzB4cwY-eC__|Cu}u#}h6Yv!mIs$AwiOXaf2ZPgMbkO;|5~}1_KiY z#siiNOb%8Ij2CPem;!7W7!TMpFbFs^Fa|g?Ff4FpU^H-HU?^~7U`%jlU=Z+NU=Z+R zVEo|2z!2cez*rE(z;GdmfpI}N1A{^Y1LK4U28IU_42%p>3=A7UIGTZRK|BKkLjnWi zf(!-*g-iy<37HHG4?uJd1A{^?17kuy1H*@W2F48~3=9sX42&B|yEes3+tqhC}tqcqdZ43+xIvE%Rx)>M&x)>NQbTcpr z^e`|w^fNFxOlDx*FpGiV!z>2IhB*uj4f7co7A#_5WLUz$?691Hk&%Hh5R&8(Rs-p!5Z(IJ$jER--Us_P}TqNhA*Fs2UKr=MThw5E~i4fZAUG zbswl40QpD3527A4wgTc`2!!wpLLl^mPza4|7Kr^J3RQeT0xJJPB7_ff*B%`10+}_6 zM?+vV1V%$(Gz3ONU^E0qLtr!nMnhmU1V%$(Gz3ONU^E0qLtr!nMnhmU1V%$(Gz3ON zU^E0qLtr!nMnhmU1V%$(Gz3ONU^E0qLtr!nMnhmU1V%$(Gz3ONU^E0qLtr!nMnhmU z1V%$(Gz3ONU^E0qLtr!nMnhmU1V%$(Gz3ONU^E0qLtr!nMnhmU1V%$(Gz11N1TKAo z>djRc62b~`QqCw|QfM_|Wd_z7&e?cCE4k&=o3Q#&A2g1JqRcG)T z!f&_>p*OsQ(4cc8K;{PAf$$S@p)}N-4@D3@===}>e(9|{;z zOfZGm4Y4|@G!2LCrln~)`Q;!NtRPFjSw(SrYDu1JKynU4!waZO{*!A|K`F>6Z;)9M z zGFOI%2@uDHc%mmmhK3cW?guG>djRU#Fh4_s`1s_Cio~SMGD9PS`1s$%!DDV8eJAWY&JA1$&ZH=*OdjSu9JSyCgV5HI5j`bwG6K*pkgH+ zqzuh6BXE8-Fpf{k&(AS5ijOZTDou?qOUx++MM)8=myP1%i}JyRT6%JdC%Dpyk1sDu zEQrr6NiFgWK#px!S6A1N_+V2gVkj;^2|eTZ_?-Om)S~#L{L;J>&!7Oeq#$o({lUiZ zu9!A}Qw^91F^CU#1fd}B5X1P8cvRmT!(Ez_npQ%BQ!$JwE=f$vNsTYgFDfC;m9DO3 z5I2UzgZyC%3L;R-hgH$Rj`6OBrYV_eX{kl2dC94ebQa(j>=JKi0FD5NNDhXRN(%~T z7jTdQHZ3zJ6?feZs@{rH6I0@I^HV^{1T|)fGQkLxa576$$v46zzaTZwHNZPL3oU?% zvELM2lA-4r6L_jA%1qB7DcLj#pag>5un z0hxiER-9T?l9``JS+Zt8^R#)qODeR0Pjybr$w@6TGLMf>$&XKg3&&?9=B0qL6R5}! zD9c5SI!psB!TOUEb8=h*&b#)DPjfa+NZt)?8 z@xkuII}B?H4+;X1V^IBX7VqjBYyq>$5^R$rR-4jOOX5pXa|`l|5{oM1lS)B_DN3UQ zza{e0*_1PG$*I&@XG{ovzTl^31%H_@LC{(%e*r2@J&?kZ~YrCkRx^L;6zS&T)Kler|4lo~KWep{pxM z4m?&6k33)mYSb_k3!s={2I_U?q*`Vq7RRS0Ca0EwlD|Pbcwk}zL$L%_#ihlm*c4kp z6bF|W8s_AuXC}vkhpC*6Kus}_`*$$H6o9)v(6mNisLBZ9>H}oxEh=^m$^=<_164DT zgC5RMs~?c1+Xbro028vOp~3BJ=o;i5Y!DA}+zD(7Amcs^#V=4K;Ugg?nR%Hd;C2r~ z@dxZmOp|j`6N_B4Kvw)fQ9^K}1m^SxW|-6A!#U2N;fe_i#T^i-;1bJ{)S}$Xyu^~! zGLTI>z~b@A6^Ze%_FjByMRIBZs7(n{Z~&noDK$MaFFrZ3Bsl{la{?g)YSqP;=A~8? zq$Zc7rhsHGAY@bXKx1Q2T{jToX+^22sFpoINP=?%$e7 z$p@#HA0Q5FP=lekfknt6J}oV$v>5Ev4lozg%K&Md0Ol1GW#*Nnf%r4Pd{8e4#9IL6 zfphQ*FsC>*H5(+g0nW<@ad&{ZC8;?%VD14hx4bB`1g!N0h?@%zRFL8eU~Xz|azQ1C zdjrY^wRJ)K2T*=-Y6)lrhB2Ojm4PXqK`=KlGmqf{69ZFjMto{TYI12wYJ5g&B50sS zGm1f%2{hi!V#r`;#ITvskKrm)2t%_t1Cx1jer`cxQ7U}ErWmb9ZWzz7j?onCR%A8M zVjEU*A$Q_YM_<7Gc2{sYahi#l;Xoz>1Ct3T1YJ^d5-T0^Qd~g;-T_7VpprkpJ2?o= z*^bS52mIaMW*h2$(XnqSX9{(XLY~my2 zUS!pMd@L**nwc0Fm(!qPB@iGhV>0hqk748(r00z@9T2O=*#U}9ik zF<@9HI6$5J7SRFk*>{N!((b${0~0x8H~$3VF%{2jPPl40FZdbN3AY#2J`~ z9h~?i4(&4IZwRG=t=de2Xg)x=tGS%OFlZc4DQTxeopU}1UD%)-EMAk$z2 z%LHbHf&_&IMu7v&2_IMu6chwD@F_q*!UQG*0|f2q-i#8VDE|I2afN7&s^x7z8MQj0;du2vB&yXduwQ z7+|1a5MUtifKkDqfl8z(61X^}ts0k8uM3Lw@`U<}y6C?Jqv-~h5m z!N33%Bn?ak4U7xe6%-5{3=#w!KtTd_JIGND%nk+y4IBmsm=!*72!NG4K!QlYp@D4y zn}C9VLIEhC53ng1d|-5Vz_@_%0Mh|x0|SGC0s#ewfCr2Y1_ln`csDQrDKt4_^7~~im7!E-Bv!HwjD~S3{Q1t>f5dH@!KfxZt*A|1AKLN^5 zhVnN+`Q=dl1t`B8$`^2l=-&$E8$kKbq5J?SUrroiegTvp0_9JD^4p;N4N(3DDE|VK ze-Fz40Oc!6K+Fs9fY@IIS`Ao?pMA>pY2 z<*$eGFF^Tkq5Ka}zOocVeSkMaefjV z!f%A~F9bsPm!SND5C~sY2BQB#D1;vi<$s8R@Ml5!3lbpw>rnoML3Vv5cLI6em|6d0m{D$M7|Oo@ z|3!!|442XFvp?n7@|2dQ&0OgA)Li86v`R-8u2PnS*%2&vQn0E-uH-Pdv zl_2^PpnQ8Me*%=>0OenR^7ldc3|SEK?m+nlP(F_`#JmP5UkA$H0Ok8Y`5&PC8Yo{N z8)DvkDBl6fKLO4qs`~y(FfC|LE2T;BRlrNA2F|QcPH-PfjL-`3%{wpYd1C+0( z3Nh~jl%ELYe}M95LirBRdzG%j_|SWsK12BpP`kP%6|;y7eM*O8j$>S0m{$NfSC877-HXi zC|{ri!ru<%8$kK2nh^aBP`;HWME`|yi26tT6p9bX%K>4?z`~)apTnnOq0hDh8 z|{xK-u0m^?0KmZ^3Vn!q6QKN^Q27l| z{(Go=0QCMXbpwe02~d8D0aSk@#Qqsjd4VPf{}hyO0Oh}c@)MwZbwh}G4N!gpl)nMW zZ-Md;K>1Ig{0C4zhY>_SLo>uaS14Zr%I|^l4WRtJP`(3{{~gM2fbxxuA?9s>^7Ekl z3sC+tDE|SJf6W-;e}fi?{d^`6{S2)Tems0S z0m^TM@*UbB=AVP|1E72nGl=>LP<|qmzW~Z#1La?U@-IR82JH~@en9yXpnNHFh=`XTONw}+@Nm;m8>LHQG){C0atcrAePuR!H5 zK>1n@5d91jA^NkRd;=(d3Y6~v<==3Cm=^%$D>_2>1yFvTBgDK7Q2tXW{{fUQ;{=fx zm;|ve0m?Uk^4B;)%yWS9ze42`pnPLzh&%)IUcq8#hiGg7@(xhG zC6pfk7Ef{0mUNOAtiA z!2*c>=}^7{l>Y(BPk{1yf+6Y)pnS7nNO&%Q@-v|F3JW3T&4cm-p!`Qr{sSmqBm`m} z!y<@!KPbNe%HIv;Z-DYOLLuq}7DLpxL-__!{z@p{0m{D}3UOZnlrI_v(f1CP5dQ=$hv+{DmA?SxD@Q@}e}MAipnQQ95cPARd;=)|43zHx zM8mj&Rl%Jji z(a*3BV*cVJh<*bo|07gB0LnK>hRA<_@+*@e`VFA>?;eE88*G4>$CLt*-vH(NK=~J- z{7Fzg!$yeuzfiscl&_Nt(eD7|mqGanQ2vQjhH1k8$kI=c@X^xP`*Eu-vH$= zgYpkR`4^%54^X~BK19F3E{ORaP`(3{KOM?X*awln59K#N`FsTs{R^OcODO*Wl-~j6 z3+#vJ{|)6kK>2xvQ2kK;HYk4sl>Z0H{{ZDD7eUlB9DtbD4dp99`S+oG2Pog97@|G_ z$}fQO8=(9nQ2qoc{|}UZ0m|1bf#_#|-m{$vQ=ohYDE|PIp8(}Qhw%?X+$&rP zF>e8sZvf?Afbvg5`3%r|yZ=D>A5KE_Ta-ccH=Kj;YoYuJQ2tgZ{{WQ#0Lp&=<*SrK z^edc)==X>61EBmID8B&8XRUy!-vH%DK=}`#{MAr?zy*kTU!eR1DBrpgqJIID-wEY! zfby?G`46Ccjw*Z_rA11SF*l%D|QbF@IzPk{1$q5K0-em#``0Lotl<$r+kjani4 z6<$E>>w@wfpnTCbh4XF&NpUm^Cd zf%09T`~y&a1eAXT$}fQOUqJa&p!`2j{vIe_pc~@93sAlal>Y$Aw}A4$K>0pUKF2qR zdlI009Vov9$`66^JD~gwD1Q!=UjyZDfbu6m`A4AqB~bniD1Qf({|3rG1LZUHK-~WT z$`^t1S-wNurvc^bK>0RMz5|pW0Of~3`6*C-29#d`<<~&@Jy8Ab46GR@g+?t<}fuR68|LnuSzyRVOFoD=t z0_6ul=d1TY`5&P2EQ}!a4GaO$_OmmTp8y?Ss)h15K*!hDL-`HR`6AGoO@77(h63n( z6AKg6yaI^*`cS?Clpg@)2SDeu3ZeW9Q1hli`3Io$A^V|xgVzxA*q9;aH$dx~WGH_F zw0v3tI0zl)ifwS0Xlzn4aSGMPn;E^{sVM=DhSG7-~+M08_F+u1>s+W z@&!&o_*rZa{STn+p#xAp19bfJKa{TkKqVxhX)Y(eNaBb zeF$HT6Cy9L6T(k}@*SYb6^MKZ7exI5X#FnA4dFXL`&-RWegJel@(q-~06O2| z&BMUJ&)LB60-7G{q5J?Se+!7u*1)g_n%-YP`8`m+EHB7D0njD^aQZg{^BEW(K-WK* z^Mc(8O4eXC?hrmGtAP3KX#90({HtjE_h@_$KCt<4^K8-hMQHrxX#Bfqdh zQ_=WW(D>W}sQR7I_%UewA~gOiH2yX;{v|X%lOU>nVrYCVG`IH@$Jy~GE58%vP=vNa!d>i@=Od2pBWh#zA!Q{dl_`T9W^Rk%8eSBLl-PMh1r8j0_Ba85tPCI$u`CI$vx zCI$vRP+i5uz#zcHz#z!Pz#zoLz@Wp#0NxWN%*4PT!omgCY|H!yiTl20bPQ24f}$1`{R*1`8$z21`gRHZU+SfUz|b1A`3{1A{FS z1A{jc1A{LU1A`yb-Z&-(hS9JmJ?s@2;^U(Xsk6@wWD+s^>f+<0jHt7X4P+AKo9aL( z(V^{kBV}U;7VSiCAi<&&%T68SO(Y;4kUe??PjJGg6m|0w9+l`jpKvRM?y#Cg~Qy&RvR+j|zeB0wi+R9f}@e_w<1@!M7fg zU=dso@fKm8DH0DpZzMh*^(Z4y974MgpaPQQLyVC0L(kK}dVCQUW!Mfb0x83OWD!&b z^U!UG1PO;2fzI0|Srh1}9g;PHP8}ju6XcvEBwa)vkOV)-n{=(nXLysP8*ywm>Dp0_ z>?U11_*^K`wSiAnLTH1gT=+>)7&71^pb(QK%kx5h`4U2wW@tGBKI$$$J}L!t$as8w6zE)W5LKQF z3Z1<2T(r}}<3Z;`V?E{zDuaB!7gPxSU@xdJ;zTc~0NPPrP*KPkUh(nR4k|}Eqa1vs z7m5hv)N-&8;ff%53xG;`Jhh!XZH9}k^>ud-*A}b3NAF$)h z38uBY64x@4G$fb#f)2n$8A@_>D=Tw_ngbb8gSGXrG>R+>N{ch%lM<7&U4y()9E(Sj zX=-jkNhOLEhQtL5w7db`CXkmN4^Cn5GwHw{M|Cis<|2y2gAL=sx}gmfn9~WhZB3v@ z)`Q}fM6H<>uHdZZV`vob9~@ksSm2pgVrW(Zat4Z+u@NLxQ9XtwCcvllfn0*B5>F7| z&_T%8aBXN_#$yw5KoRXcSP=Q4>cHZ4xJon^VNr_PC4{_5qGK!}0FCO}hgv5S(Ch}CMGnwLVBMram{LW>qW zv5!Lsme@g4No=72Z3m;*h$Iy$F#iy1CyrW}NIRjrp73P4o4-+z=Hf@&;=AGX$ASko}kfm#DzYt$R#szZZs*b%mdvWM5EW?^Y+d_hT(r+IvQv74ulYk*rO zlP%}FguEs8Hr%gjqm z^$Z4`P#+Nz4>{jBJwHDszNjoQC%z~(4RRp{vQO~3#=IysClz#~5Tt1YDPaxqYC+Fx zcojPv(bu;=CZLuk=xqAT09eqwy1M#~y?bZ9M-SK?E1Qgc1w!Q+!@;OdiP;OgoO zaZMT64kRNG?f@lXgiG)_#S|8@Nao;niW^d7`D7ZxofB*lkKr1k0@gGwv#1!>-iIV= z+_uAf1P=()`1tfxRNVx!1hkTc6&`rAglSP~acT)D_alW3QNA)OPEF27YnkBo7S=$; z;x!*j_+TKYm!`sw5at05Je5*nNz16DvG(AU+E=jt@3QHXAAns|7r1=LM=6hUo-)G<(XM8|wV zK}iv+6~t;aEdXDZhhi;eYBhkgCsp(`p*#uK7P8XX& zt~7u+*gHAcG#=b*h7E`i9ZIR777#RqA&J4qI5#uTGZ!OUKm!7&i;Ob!kX#cKYzhiU z^Y|dt+7)U#Qnt#?B`RCx=DLEjRW53_BHE+rNu{|3&}JUgD@5x}MM{Q{Kq6Xe0j9M$ zL(n+C6q*9T5sE7aiM882J|1Fw4pNywaHI@hvU>6*{qr%q%^%BqtxW=Z0{+v!Sc6U$8;E zX?%QMVhJ?&LE{weLuVtLiik@sps>tM%ubEZO(`xZ0#%fdRDdfilTpJ9o=nhF5lla! zIUy5p4-%!Oft!g%4iP-bWxgQ>@geb^pn+vjYC|1vMs=p4aeO?|B(W!!Q6kIuc*rC| z0ZNGu8~MVb1JZ(oUZ@qHpO+e+SOPM`(<{gubbUmbOM!m~aL~mhTSO^Qk0lioR|!{rv)@88Eg!#Rv~HD z&{K00U`0hM#zzb=(K@j5l^qt7)w`;^q@i;6(HRJXCqh8y<(6i3^aU* z32V@>6IyVCvXOaaUP)?tQDRO!STZrM#4`zeBa|zS$UwSxH_H_{0$p9p0>vy26I8u8@iXB@K`s!0^#dXqkq`1W=e3r6%X+=7I*oQKAI>I=C#* zU<69oxw<+Vy5^#_(GbZIR21MzjYe2fqaiVt!V@52?^z@#79=KTqRp~FdV83SUJ}wG zV$FS!H!M3sokK*?jWw?un&g${rWR!;$LD0`g08L4aRv2RQPKiYWfJJxarjNr1ab(v z<5A)l;YpP0j@a@XHA_H42T}*+A`iGhMyW{36Gos__?bz`1qJcwfd>69LvD0@N-=G=p40 zgO{KIMf71*VyXZOXqB7_F55{iuF&!wG^7!3gEYTE^*C}3Kuic>qyT8>VodbD`|;IUe4%_!Wg1OI0uWLK#>d*Hl%a_8)OJd!Q=|5FCin@ z!N!6u@b&Vpu6ZTJMWD_l=vq*4OA>tTaIjH4sKpJse;J~%xX9Qr zvpBw_D6=dxF(;=Id_^*(=?T)1nUs_23BIlwqTIC%I`IT*j0RhR7C8h3TcWhzO+eT3 zdIo@souCl-z%;aQ!WYOU@$reUK+a1ohb*Om&P?FZ2U@|MnOByWlbHgFp2VCS_^sE) z&{!gDxv?RV<;nSZC7J1^`K866fGA1K%u6kD4e&0544ns?LcB}ZP?MCzl0>KzAn6=F z%a=vW)E?@50Wsw^yr~Saj;Qu0bR{WrNkU}13~}{4xc&;rf|MfAfFa6q^hOE^?gnM{ zlvK!d+R&cAYXD^Mgkn>0=P(0TSCj=1#8mUmeqy0YEX)z!!_9_JXB329?oP+MGGkq1gZi}sA-!J}QqpxQCW8~A!A>t^R|eE6W(xDc*Yz|u#7nnlkBhuD10D-`1Fh2An=G7*)ane z!$E1VfTv-~2$gtPqYkM|gM}y32pJ?lfL1pVGfDu5T1gx5}_(V zEijDk7Ss{g(kN;+ff|Cd_CPfOYAmjN0yT_;AV!aA(oMjq_hCk0Yj!~0kLoE%PC=#JT!O?L&HyIp17gReprMOq9_}K6n5r9;++jl~ zkfqls!w)3XASR@aR)Je-pyG|X<5l2hU9e@mt1Dyxim34_gmR?uD&zQIM-U1Mc7zPz zKqA@)I$i~h4p28B1in-gT3!$n^u&x_LG1vA60~?jbaKFl#E>$Ig~u@BMzhR7dzFIC zAb~-=Pw|XuL7ha**cNmU4H5?=Rao#QEg5>r8S8?3$`xf$1T^O#5NrhPe?o(gB#)rC zK*;b9sHg)EE|n&iz{kK)*T<6NBwXg49KM)GF0c**R(U5?pEIf@$tOlX9Dj`V= zR*Yd;?}4_;5WO8uSO;kC32B8FXctOueja!ajVrq0*t~+x21B$~B`8uYK%0)z5=(PR z;xqFyOX5os(;>5k=uJ&xEkSQ^kzxs=LyK1zD1NZDoJg9;M6EQkkUB!nMxecHhS)*| zd$P?!j}bfx1HH6G8y3Y9ZKUhKRw@&=2Wwe{JpK>!6*Rk{1|X!Jg`P6eY$ZV_w&aFS zJJr)RKFcUc<2W0_sNo5Up#^|ae-nBG0PAr3<+}E zOC&4+K=u-7lmp4PkbI1P6#%k!ymL%MEd@X}4Xb0&5*n#l3o#2$aB3gfDcEuX_8OhU z>X%BB{K#%aTE0MdrXN`&Hcz5fd4yVYs3strjnx0aQsiQcZzF5Pnhc1Y@g{5#dS4dD zWG%@F4LUhQ#N0PQH)2m|=u_JSjlt1U05vKxR)7#R45OEfBixWGD14~{Z^=Q)>@>1R zV2O~ZDQXmrq|H+!YsH#+QF9ff%EZ}lK{El_a3l|5%TPI6(5%TUlH7544r@L624 z0|cXjfSE+Cf`sU7U>F|{K2RgG1hi`hbxa-9v@I`6ECBBi@lh(SEc{t^?& z5q`+2ItS!Z@HXurZ{*W)P)>S7*5DT$Z)6%DUzA!>T9g-GlA2qPUzAu>3C%H}UGLy& zTD0S#vD%y%?22gnLPH7p%s5i4g&rpdnl4A0rX<@J@WwqX;h_XPYE*;Hb4^8A8HLri zpmpq^9p%&tXZVqlkhV26{0LFF9F)2jbodC$Y95Ni97`+J$H*8* zsfOPzKA=--F}AS9m*#DRJ?-< z3UUq$Hja071s@g++Q*!O^PFH5yG`Tci&IO`qdzwQB`xBtWU%=KUa>&RYgoea!v+GRXW%ZRKp<^Fmw#Y2=kx})N%;Cq&gY3 zPl!=3k(4&EpE{1>MyRFW_5t?J7H9=3a=}VY8pKxPqc{Un4!Y)oB8WI=kW#**_rgih zi=*97PAH(ZQ6S|rY7!v3Re~?^VQGn=+G-geUr>~v3_5rjIp;&t9`P}Pr{REh$f%Eb zVoF(JUUDjE#Vo#38+6=ePzd<=ep65f8TmLs&?qcs?-VJe`dFl77MBod4al1qR$%S_ z27@;uAlqXGxiy*y&xFLI9?Aht17=03WvNBQso;J-$d9OXA*ct9*4M|>0rCKz7yvbL zK!-mex!WQ>J~OW@wWtJijDHg9q-rpzG2?9L3fpf1aVWGgfl~Zp*bAg27L*nbcq|Vzyoa(Er?|*GvpBvuF&C0bjG(s)fcIJ>ZWI8IK*09e7+Ij4 z4U?Q-P#K?CT%4H>K9j~X*c`qu$29=Nft=zW06Og4DL&W&vb6;2RnX#u(mY(FFRqBA zVsNNO%}Hp!D=s47R8U(A;w#qxP+UM<|H=(30S69Da!+1=WfI?9(uy9 zhoC!=je+39=}E7)k%3s4C89An@X zOB55d7-R@ae~w@V0qKD5w1Y$!zDgQxovx2%d_2vnchJz1Sy5tMN`7v9Vlt@70qSUfM?n^^s@U=>?qxcBA7N37X zLsY1yA-7k+H6vP1NlYB*2ALt~q`vr~#Ju#>V#+*k06OhEJwHA@IR#WEgv19Mf)G-Y z!r9FRWgUF8Q{b+qyR&nAY6a+w#P|}>X^4gl=psfKBIXz(hGrN-My41-#+Zg18)K@% zG|L#%Mq>*Mjiv?|LS~pY8X8z)C^Iy~^rRscKN%XCVCu!CYW(#jKzJ% z=9n>VY=OmI3oPbYV1|LQC1zNeU3DFb+J-d@6P0l20G5}X`=oh_!yJ;X#AzThsg8w#7 Ski)^3JQoyYmL-;?G5`Q4*EXvF diff --git a/scripts/tools/Win32/networkSimulator_g192.exe b/scripts/tools/Win32/networkSimulator_g192.exe deleted file mode 100755 index c17aff5249..0000000000 --- a/scripts/tools/Win32/networkSimulator_g192.exe +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b81ea0575fb6b40f48c22b59f90820774054e82708750f9350cf9c0ec2674231 -size 578574 diff --git a/tests/README.md b/tests/README.md deleted file mode 100644 index 6ba72e4ace..0000000000 --- a/tests/README.md +++ /dev/null @@ -1,173 +0,0 @@ -# IVAS tests - -The IVAS tests are using the [pytest](https://docs.pytest.org/) framework. - -## Installing test dependencies - -To use the `pytest` framework, you will need a few Python packages (in addition to Python itself). -As with other Python packages, there are different possibilities to install those packages. -Please chose the option that works best for you. - -`Note`: -The installation of Python is not described, here. -In the following, it is assumed that `Python >= 3.7` is already installed / present. - -### Global install - -```bash -pip install -r tests/requirements.txt -``` - -### User install - -```bash -pip install --user -r tests/requirements.txt -``` - -### Virtual environment install - -```bash -# set up virtual environment -python3 -m venv VENV_NAME -# change to virtual environment -source VENV_NAME/bin/activate -# install required packages -pip install -r tests/requirements.txt -``` - -## Preparing the tests - -`Note:` -Currently, shortened test vectors are used to speed up the testing. -Those shortened test vectors, some with gain adjustment, need to be created, once. - -```bash -# create shortened test vectors -python3 tests/create_short_testvectors.py -``` - -The tests rely on references which need to be generated upfront using reference binaries. -When the reference binaries are named `IVAS_cod_ref(.exe)` and `IVAS_dec_ref(.exe)`, pytest will find and use them. -When the reference binaries are named differently, you need to specify them via the `--ref_encoder_path` and `--ref_decoder_path` options. - -The tests will use the binaries `IVAS_cod(.exe)` and `IVAS_dec(.exe)` for testing. Please make sure that the binaries have been built before running the tests. -When different test binaries are to be used, they can be specified via the `--dut_encoder_path` and `--dut_decoder_path` options. -(DUT: Device Under Test) - -```bash -# create references -# the following binaries need to be present: -# - IVAS_cod(.exe) -# - IVAS_dec(.exe) -# - IVAS_cod_ref(.exe) -# - IVAS_dec_ref(.exe) -# pytest command lines to be executed from project root folder: -pytest tests --update_ref 1 -m create_ref -pytest tests --update_ref 1 -m create_ref_part2 -``` - -## Running the tests - -To run all tests from the tests folder: - -```bash -# pytest command line to be executed from project root folder: -pytest tests -``` - -## Re-running some tests - -When there are test failures, you may want to run, after having fixed the code, only those test cases which had failures. This can be achieved using the `--last-failed` option. - -```bash -# rerun only the tests that failed at the last run -pytest tests --last-failed -``` - -To run a specific test case, you can e.g. pick a test case from the `short test summary info` and use that test case as an argument to `pytest`. E.g. - -```bash -# run a specific test case -pytest tests/test_sba_bs_dec_plc.py::test_sba_plc_system[0-48-PLperc12mblen5-stvFOA-0-32000] -``` - -More ways to select which tests to run: - -```bash -# run all tests within a module -pytest tests/test_sba_bs_dec_plc.py -# run a specific test from a module -pytest tests/test_sba_bs_dec_plc.py::test_sba_plc_system -``` - -## Some pytest hints - -When there a many test failures, you can use the `-x` (or `--exitfirst`) option to stop testing on the first failure. - -Commonly used options like `-n auto` are added to addopts within the [pytest] section in `pytest.ini`. This saves some typing when calling `pytest`. - -The `-v` (or `--verbose`) option is helpful to see what is going on. - -## Custom options - -`Note:` -The custom options are listed as part of the pytest help `pytest -h`. - -```text ---update_ref=UPDATE_REF Indicate whether references shall be updated. - 0: Only DUT processing, no reference generation, references need to be present. - 1: Only reference generation (unconditionally), no DUT processing. - 2: DUT processing, references are generated when not present (not supported by all tests). ---dut_encoder_path=DUT_ENCODER_PATH If specified, use given binary as DUT encoder. ---dut_decoder_path=DUT_DECODER_PATH If specified, use given binary as DUT decoder. ---ref_encoder_path=REF_ENCODER_PATH If specified, use given binary as REF encoder. ---ref_decoder_path=REF_DECODER_PATH If specified, use given binary as REF decoder. ---test_vector_path=TEST_VECTOR_PATH If specified, use given directory as base directory for test vector files. ---reference_path=REFERENCE_PATH If specified, use given directory as base directory for reference files. ---dut_base_path=DUT_BASE_PATH If specified, use given directory as base data directory for dut files. ---param_file=PARAM_FILE If specified, use given param file in test_param_file. ---keep_files By default, the DUT output files of successful tests are deleted. - Use --keep_files to prevent these deletions. -``` - -## Helper scripts - -To help with running the tests during development, two scripts are available in the `tests` folder: - -- prepare_pytests.py -- run_pytests.py - -The envisioned development workflow is: - -```bash -# 1. create a new git branch and switch to the branch -git checkout -b new_branch - -# 2. build the REF binaries (here: example for Linux) -make -j - -# 3. use the binaries to generate the references for future tests -# assumption: you want to test your development against the start of the development -tests/prepare_pytests.py -# Note: the script will use the binaries IVAS_cod and IVAS_dec in case IVAS_cod_ref and IVAS_dec_ref are not present - -# 3a. (optional) store REF binaries in case you want to re-run the reference generation at a later stage -cp IVAS_cod IVAS_cod_ref -cp IVAS_dec IVAS_dec_ref - -# 4. do the development changes -edit ... - -# 5. build the DUT binaries (here: example for Linux) -make -j - -# 6. run the tests -tests/run_pytests.py - -# 7. depending on the test result -# - either go back to 4. -# - or commit and push your changes -``` - -Both scripts allow to restrict the reference generation or the testing to test_param_file tests -with a custom `.prm` file via the `--param_file` option. diff --git a/tests/create_short_testvectors.py b/tests/create_short_testvectors.py deleted file mode 100755 index 56c41d49b8..0000000000 --- a/tests/create_short_testvectors.py +++ /dev/null @@ -1,66 +0,0 @@ -#!/usr/bin/env python3 - -__copyright__ = \ -""" -(C) 2022 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. -""" - -__doc__ = \ -""" -Create short (5sec) testvectors. -""" - -import sys -from pathlib import Path -from cut_pcm import cut_samples - -HERE = Path(__file__).parent.resolve() -TEST_VECTOR_DIR = str(HERE.joinpath("../scripts/testv").resolve()) - -NUM_CHANNELS = "4" # currently only FOA -CUT_FROM = "0.0" -CUT_LEN = "5.0" - - -def create_short_testvectors(): - for fs in ['48', '32', '16']: - in_file = f"{TEST_VECTOR_DIR}/stvFOA{fs}c.pcm" - cut_gain = "1.0" - cut_file = f"{TEST_VECTOR_DIR}/stvFOA{fs}c_cut.pcm" - cut_samples(in_file, cut_file, NUM_CHANNELS, fs + "000", CUT_FROM, CUT_LEN, cut_gain) - cut_gain = "16.0" - cut_file = f"{TEST_VECTOR_DIR}/stvFOA{fs}c_cut_{cut_gain}.pcm" - cut_samples(in_file, cut_file, NUM_CHANNELS, fs + "000", CUT_FROM, CUT_LEN, cut_gain) - cut_gain = ".004" - cut_file = f"{TEST_VECTOR_DIR}/stvFOA{fs}c_cut_{cut_gain}.pcm" - cut_samples(in_file, cut_file, NUM_CHANNELS, fs + "000", CUT_FROM, CUT_LEN, cut_gain) - - -if __name__ == "__main__": - sys.exit(create_short_testvectors()) diff --git a/tests/prepare_pytests.py b/tests/prepare_pytests.py deleted file mode 100755 index d1f7495f07..0000000000 --- a/tests/prepare_pytests.py +++ /dev/null @@ -1,132 +0,0 @@ -#!/usr/bin/env python3 - -__copyright__ = """ -(C) 2022 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. -""" - -__doc__ = """ -Script to prepare the pytest tests. -""" - -import os -import sys -import argparse -import subprocess -import platform - -from pathlib import Path -from create_short_testvectors import create_short_testvectors - -BIN_EXT = ".exe" if platform.system() == "Windows" else "" -HERE = Path(__file__).parent.resolve() -DEFAULT_ENCODER_DUT = str(HERE.joinpath(f"../IVAS_cod{BIN_EXT}").resolve()) -DEFAULT_DECODER_DUT = str(HERE.joinpath(f"../IVAS_dec{BIN_EXT}").resolve()) -DEFAULT_ENCODER_REF = str(HERE.joinpath(f"../IVAS_cod_ref{BIN_EXT}").resolve()) -DEFAULT_DECODER_REF = str(HERE.joinpath(f"../IVAS_dec_ref{BIN_EXT}").resolve()) -REFERENCE_DIR = str(HERE.joinpath("ref").resolve()) - - -def main(argv): - """ - Prepare the pytest tests. - """ - # check for python >= 3.7 - if sys.version_info[0] < 3 or sys.version_info[1] < 7: - sys.exit("This script is written for Python >= 3.7. Found: " + platform.python_version()) - - parser = argparse.ArgumentParser(formatter_class=argparse.RawTextHelpFormatter) - parser.add_argument( - "--numprocesses", - action="store", - default="auto", - help="Number of processes to use in pytest (default: auto)", - ) - parser.add_argument( - "--param_file", - action="store", - help="Restrict reference generation to test_param_file with specified param file.", - ) - - args = parser.parse_args(argv[1:]) - - use_dut_binaries = False - - # check for existing references - if os.path.exists(REFERENCE_DIR): - sys.exit( - f"Found existing references directory {REFERENCE_DIR}.\n" - "Please delete this directory if you want the references to be recreated." - ) - - # check for DUT binaries - if not os.path.exists(DEFAULT_ENCODER_DUT) or not os.path.exists(DEFAULT_DECODER_DUT): - sys.exit( - f"Need DUT binaries {DEFAULT_ENCODER_DUT} and {DEFAULT_DECODER_DUT}.\n" - "Please create the binaries." - ) - - # check for REF binaries - if not os.path.exists(DEFAULT_ENCODER_REF) or not os.path.exists(DEFAULT_DECODER_REF): - print(f"REF binaries {DEFAULT_ENCODER_REF} and {DEFAULT_DECODER_REF} not found.") - print("DUT binaries will be used for reference generation.") - use_dut_binaries = True - - # create references - print(f"Creating references within the references directory {REFERENCE_DIR}.") - create_short_testvectors() - if platform.system() == "Windows": - base_cmd = ["pytest"] - else: - base_cmd = ["python3", "-m", "pytest"] - if args.param_file: - base_cmd += ["tests/test_param_file.py", "--param_file", args.param_file] - else: - base_cmd += ["tests"] - base_cmd += [ - "-n", - args.numprocesses, - "--update_ref", - "1", - ] - if use_dut_binaries: - base_cmd += [ - "--ref_encoder_path", - DEFAULT_ENCODER_DUT, - "--ref_decoder_path", - DEFAULT_DECODER_DUT, - ] - - result = subprocess.run(base_cmd + ["-m", "create_ref"], check=False) - if not args.param_file: - result = subprocess.run(base_cmd + ["-m", "create_ref_part2"], check=False) - return result.returncode - - -if __name__ == "__main__": - sys.exit(main(sys.argv)) diff --git a/tests/requirements.txt b/tests/requirements.txt deleted file mode 100644 index 2eb090f4fb..0000000000 --- a/tests/requirements.txt +++ /dev/null @@ -1,4 +0,0 @@ -pytest>=5.3.5 -pytest-xdist>=1.31.0 -scipy>=1.5.2 -numpy>=1.19.2 diff --git a/tests/run_pytests.py b/tests/run_pytests.py deleted file mode 100755 index 1fc6614762..0000000000 --- a/tests/run_pytests.py +++ /dev/null @@ -1,106 +0,0 @@ -#!/usr/bin/env python3 - -__copyright__ = """ -(C) 2022 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. -""" - -__doc__ = """ -Script to run the pytest tests. - -Test prerequisites are checked for and check failures are reported. -When prerequisites are met, the pytest test is executed. -""" - -import os -import sys -import argparse -import subprocess -import platform -from pathlib import Path - -BIN_EXT = ".exe" if platform.system() == "Windows" else "" -HERE = Path(__file__).parent.resolve() -DEFAULT_ENCODER_DUT = str(HERE.joinpath(f"../IVAS_cod{BIN_EXT}").resolve()) -DEFAULT_DECODER_DUT = str(HERE.joinpath(f"../IVAS_dec{BIN_EXT}").resolve()) -REFERENCE_DIR = str(HERE.joinpath("ref").resolve()) - - -def main(argv): - """ - Run the pytest tests. - """ - # check for python >= 3.7 - if sys.version_info[0] < 3 or sys.version_info[1] < 7: - sys.exit("This script is written for Python >= 3.7. Found: " + platform.python_version()) - - parser = argparse.ArgumentParser(formatter_class=argparse.RawTextHelpFormatter) - parser.add_argument( - "--numprocesses", - action="store", - default="auto", - help="Number of processes to use in pytest (default: auto)", - ) - parser.add_argument( - "--param_file", - action="store", - help="Restrict test run to test_param_file with specified param file.", - ) - - args = parser.parse_args(argv[1:]) - - # check for references - if not os.path.exists(REFERENCE_DIR): - sys.exit( - f"References directory {REFERENCE_DIR} not found.\nPlease create the references." - ) - - # check for DUT binaries - if not os.path.exists(DEFAULT_ENCODER_DUT) or not os.path.exists(DEFAULT_DECODER_DUT): - sys.exit( - f"Need DUT binaries {DEFAULT_ENCODER_DUT} and {DEFAULT_DECODER_DUT}.\n" - "Please create the binaries." - ) - - # run pytest - if platform.system() == "Windows": - cmd = ["pytest"] - else: - cmd = ["python3", "-m", "pytest"] - if args.param_file: - cmd += ["tests/test_param_file.py", "--param_file", args.param_file] - else: - cmd += ["tests"] - cmd += ["-n", args.numprocesses] - - result = subprocess.run(cmd, check=False) - return result.returncode - - -if __name__ == "__main__": - sys.exit(main(sys.argv)) diff --git a/tests/test_param_file.py b/tests/test_param_file.py deleted file mode 100644 index 730acd5c00..0000000000 --- a/tests/test_param_file.py +++ /dev/null @@ -1,460 +0,0 @@ -__copyright__ = \ -""" -(C) 2022 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. -""" - -__doc__ = \ -""" -Execute tests specified via a parameter file. -""" - -import os -import errno -import platform -from subprocess import run -import pytest -from cmp_custom import cmp_custom -from conftest import EncoderFrontend, DecoderFrontend -from testconfig import PARAM_FILE - - -VALID_DEC_OUTPUT_CONF = [ - "MONO", - "STEREO", - "5_1", - "7_1", - "5_1_2", - "5_1_4", - "7_1_4", - "FOA", - "HOA2", - "HOA3", - "BINAURAL", - "BINAURAL_ROOM", - "EXT", -] - -param_file_test_dict = {} -with open(PARAM_FILE, "r", encoding="UTF-8") as fp: - data = fp.read() - blocks = data.split("\n\n") - for block in blocks: - tag = "" - enc_opts = "" - dec_opts = "" - sim_opts = "" - for line in block.split("\n"): - if line.startswith("// "): - tag = line[3:] - if line.startswith("../IVAS_cod "): - enc_opts = line[12:] - if line.startswith("../IVAS_dec "): - dec_opts = line[12:] - if line.startswith("networkSimulator_g192 "): - sim_opts = line[22:] - if tag == "" or enc_opts == "" or dec_opts == "": - # no complete parameter set - continue - if tag in param_file_test_dict: - print("non-unique tag found - ignoring new entry") - continue - param_file_test_dict[tag] = (enc_opts, dec_opts, sim_opts) - - -def check_and_makedir(dir_path): - if not os.path.exists(dir_path): - try: - os.makedirs(dir_path) - except OSError as e: - if e.errno != errno.EEXIST: - raise # raises the error again - - -def convert_test_string_to_tag(test_string): - """ - Convert a test string (i.e. the test tag from the parameter file) to a tag string. - Example: - in: "DFT stereo at 13.2 kbps, 16kHz in, 16kHz out, DTX on, random FEC at 5%" - out: "DFT_stereo_at_13_2_kbps_16kHz_in_16kHz_out_DTX_on_random_FEC_at_5_" - """ - # replace certain characters by "_" or remove them - tag_str = "" - replace_chars = " %.-()" - remove_chars = "," - for char in test_string: - if char in replace_chars: - tag_str += "_" - elif char not in remove_chars: - tag_str += char - # replace double underscore by single one - tag_str = "_".join(tag_str.split("__")) - return tag_str - - -@pytest.mark.create_ref -@pytest.mark.parametrize("test_tag", list(param_file_test_dict.keys())) -def test_param_file_tests( - dut_encoder_frontend: EncoderFrontend, - dut_decoder_frontend: DecoderFrontend, - ref_encoder_path, - ref_decoder_path, - reference_path, - dut_base_path, - test_vector_path, - update_ref, - rootdir, - keep_files, - test_tag, -): - enc_opts, dec_opts, sim_opts = param_file_test_dict[test_tag] - - tag_str = convert_test_string_to_tag(test_tag) - - # evaluate encoder options - enc_split = enc_opts.split() - assert len(enc_split) >= 4 - - # replace "testv/" by test vector path - enc_split = [ - x.replace("testv", f"{test_vector_path}", 1) if x.startswith("testv/") else x - for x in enc_split - ] - - bitstream_file = enc_split.pop() - testv_file = enc_split.pop() - sampling_rate = int(enc_split.pop()) - bitrate = enc_split.pop() - - # bitrate can be a filename: remove leading "../" - if bitrate.startswith("../"): - bitrate = bitrate[3:] - - testv_base = testv_file.split("/")[-1] - if testv_base.endswith(".pcm"): - testv_base = testv_base[:-4] - - assert bitstream_file == "bit" - # in the parameter file, only "bit" is used as bitstream file name - # -> construct bitstream filename - bitstream_file = f"{testv_base}_{tag_str}.192" - - encode( - dut_encoder_frontend, - ref_encoder_path, - reference_path, - dut_base_path, - bitrate, - sampling_rate, - testv_file, - bitstream_file, - enc_split, - update_ref, - ) - - # check for networkSimulator_g192 command line - if sim_opts != "": - sim_split = sim_opts.split() - assert len(sim_split) == 6, "networkSimulator_g192 binary expects 6 parameters" - # [sim_profile, sim_input, sim_output, sim_trace, sim_nFPP, sim_offset] = sim_split - if sim_split[0].startswith(("../")): - # remove leading "../" - sim_split[0] = sim_split[0][3:] - assert sim_split[1] == "bit" - # in the parameter file, only "bit" is used as bitstream file name - # -> re-use bitstream filename from encoder call - sim_split[1] = bitstream_file - assert sim_split[2] == "netsimoutput" - # in the parameter file, only "netsimoutput" is used as netsim output file name - # -> construct netsim output file name - netsim_outfile = f"{testv_base}_{tag_str}.netsimout" - sim_split[2] = netsim_outfile - assert sim_split[3] == "tracefile_sim" - # in the parameter file, only "tracefile_sim" is used as trace output file name - # -> construct trace output file name - netsim_trace_outfile = f"{testv_base}_{tag_str}.netsimtrace" - sim_split[3] = netsim_trace_outfile - simulate( - reference_path, - dut_base_path, - sim_split, - update_ref, - rootdir, - ) - - # evaluate decoder options - dec_split = dec_opts.split() - assert len(dec_split) >= 3 - - # replace "testv/" by test vector path - dec_split = [ - x.replace("testv", f"{test_vector_path}", 1) if x.startswith("testv/") else x - for x in dec_split - ] - # remove leading "../" - dec_split = [x[3:] if x.startswith("../") else x for x in dec_split] - - output_file = dec_split.pop() - bitstream_file_dec = dec_split.pop() - sampling_rate = int(dec_split.pop()) - if len(dec_split) > 0: - output_config = dec_split.pop() - if output_config.upper() not in VALID_DEC_OUTPUT_CONF: - if not output_config.endswith(".txt"): - # must be EVS tests with additional parameters - put param back - dec_split.append(output_config) - output_config = "" - else: - output_config = "" - - output_config_name = output_config - if "/" in output_config: - # the output config is a file - output_config_name = os.path.splitext(os.path.basename(output_config))[0] - - tracefile_dec = "" - if sim_opts != "": - assert bitstream_file_dec == "netsimoutput" - # in the parameter file, only "netsimoutput" is used as bitstream file name - # -> re-use netsim_outfile - bitstream_file = netsim_outfile - tracefile_dec = f"{testv_base}_{tag_str}.dectrace" - else: - assert bitstream_file_dec == "bit" - # in the parameter file, only "bit" is used as bitstream file name - # -> re-use bitstream filename from encoder call - - # the output file is not the real output filename - # -> construct output filename - if output_config != "": - output_file = f"{testv_base}_{tag_str}.dec.{output_config_name}.pcm" - else: - # EVS decoder command lines do not have an output_config: use "MONO" in the output filename - output_file = f"{testv_base}_{tag_str}.dec.MONO.pcm" - - decode( - dut_decoder_frontend, - ref_decoder_path, - reference_path, - dut_base_path, - output_config, - sampling_rate, - bitstream_file, - output_file, - dec_split, - update_ref, - tracefile_dec, - ) - - # compare - if update_ref in [0, 2]: - compare( - f"{dut_base_path}/param_file/dec/{output_file}", - f"{reference_path}/param_file/dec/{output_file}", - ) - - # remove DUT output files when test result is OK (to save disk space) - if not keep_files: - os.remove(f"{dut_base_path}/param_file/enc/{bitstream_file}") - os.remove(f"{dut_base_path}/param_file/dec/{output_file}") - if sim_opts != "": - os.remove(f"{dut_base_path}/param_file/enc/{testv_base}_{tag_str}.192") - os.remove(f"{dut_base_path}/param_file/enc/{netsim_trace_outfile}") - os.remove(f"{dut_base_path}/param_file/dec/{tracefile_dec}") - - -def encode( - encoder_frontend, - ref_encoder_path, - reference_path, - dut_base_path, - bitrate, - sampling_rate, - testv_file, - bitstream_file, - enc_opts_list, - update_ref, -): - """ - Call REF and/or DUT encoder. - """ - # directories - dut_out_dir = f"{dut_base_path}/param_file/enc" - ref_out_dir = f"{reference_path}/param_file/enc" - - ref_out_file = f"{ref_out_dir}/{bitstream_file}" - dut_out_file = f"{dut_out_dir}/{bitstream_file}" - - if update_ref == 1 or update_ref == 2 and not os.path.exists(ref_out_file): - check_and_makedir(ref_out_dir) - # call REF encoder - assert ref_encoder_path - ref_encoder = EncoderFrontend(ref_encoder_path, "REF") - ref_encoder.run( - bitrate, - sampling_rate, - testv_file, - ref_out_file, - add_option_list=enc_opts_list, - ) - - if update_ref in [0, 2]: - check_and_makedir(dut_out_dir) - # call DUT encoder - encoder_frontend.run( - bitrate, - sampling_rate, - testv_file, - dut_out_file, - add_option_list=enc_opts_list, - ) - - -def simulate( - reference_path, - dut_base_path, - sim_opts_list, - update_ref, - rootdir, -): - """ - Call network simulator on REF and/or DUT encoder output. - """ - # directories - dut_out_dir = f"{dut_base_path}/param_file/enc" - ref_out_dir = f"{reference_path}/param_file/enc" - - netsim_infile = sim_opts_list[1] - netsim_outfile = sim_opts_list[2] - netsim_tracefile = sim_opts_list[3] - ref_out_file = f"{ref_out_dir}/{netsim_outfile}" - - if platform.system() == "Windows": - netsim = [os.path.join(rootdir, "scripts", "tools", "Win32", "networkSimulator_g192.exe")] - elif platform.system() == "Linux": - # there is no Linux binary available -> use the Win32 binary via wine - netsim = [ - "wine", - os.path.join(rootdir, "scripts", "tools", "Win32", "networkSimulator_g192.exe"), - ] - elif platform.system() == "Darwin": - netsim = [os.path.join(rootdir, "scripts", "tools", "Darwin", "networkSimulator_g192")] - - if update_ref == 1 or update_ref == 2 and not os.path.exists(ref_out_file): - # call network simulator on REF encoder output - cmd_opts = sim_opts_list - cmd_opts[1] = f"{ref_out_dir}/{netsim_infile}" - cmd_opts[2] = f"{ref_out_dir}/{netsim_outfile}" # ref_out_file - cmd_opts[3] = f"{ref_out_dir}/{netsim_tracefile}" - run(netsim + cmd_opts, check=False) - - if update_ref in [0, 2]: - # call network simulator on DUT encoder output - cmd_opts = sim_opts_list - cmd_opts[1] = f"{dut_out_dir}/{netsim_infile}" - cmd_opts[2] = f"{dut_out_dir}/{netsim_outfile}" # dut_out_file - cmd_opts[3] = f"{dut_out_dir}/{netsim_tracefile}" - run(netsim + cmd_opts, check=False) - - -def decode( - decoder_frontend, - ref_decoder_path, - reference_path, - dut_base_path, - output_config, - sampling_rate, - bitstream_file, - output_file, - dec_opts_list, - update_ref, - tracefile_dec, -): - """ - Call REF and/or DUT decoder. - """ - # directories - dut_out_dir = f"{dut_base_path}/param_file/dec" - ref_out_dir = f"{reference_path}/param_file/dec" - - dut_in_file = f"{dut_base_path}/param_file/enc/{bitstream_file}" - ref_in_file = f"{reference_path}/param_file/enc/{bitstream_file}" - dut_out_file = f"{dut_out_dir}/{output_file}" - ref_out_file = f"{ref_out_dir}/{output_file}" - - if update_ref == 1 or update_ref == 2 and not os.path.exists(ref_out_file): - check_and_makedir(ref_out_dir) - add_option_list = dec_opts_list - if tracefile_dec != "": - add_option_list = [ - x if x != "tracefile_dec" else f"{ref_out_dir}/{tracefile_dec}" - for x in dec_opts_list - ] - # call REF decoder - assert ref_decoder_path - ref_decoder = DecoderFrontend(ref_decoder_path, "REF") - ref_decoder.run( - output_config, - sampling_rate, - ref_in_file, - ref_out_file, - add_option_list=add_option_list, - ) - - if update_ref in [0, 2]: - check_and_makedir(dut_out_dir) - add_option_list = dec_opts_list - if tracefile_dec != "": - add_option_list = [ - x if x != "tracefile_dec" else f"{dut_out_dir}/{tracefile_dec}" - for x in dec_opts_list - ] - # call DUT decoder - decoder_frontend.run( - output_config, - sampling_rate, - dut_in_file, - dut_out_file, - add_option_list=add_option_list, - ) - - -def compare( - pcm_file_1, - pcm_file_2, -): - """ - Compare two PCM files. - Currently, both PCM files are treated like mono files. - This is just fine when checking for bit-exactness. - More advanced comparisons are possible and might come with a future update. - """ - sample_size = "2" # 16-bit samples - tolerance = "0" # zero tolerance for BE testing - cmp_result, reason = cmp_custom(pcm_file_1, pcm_file_2, sample_size, tolerance) - assert cmp_result == 0, reason diff --git a/tests/test_sba_bs_dec_plc.py b/tests/test_sba_bs_dec_plc.py deleted file mode 100644 index 58be07ec33..0000000000 --- a/tests/test_sba_bs_dec_plc.py +++ /dev/null @@ -1,189 +0,0 @@ -__copyright__ = \ -""" -(C) 2022 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. -""" - -__doc__ = \ -""" -Execute SBA decoder tests using different PLC patterns. -""" - -import os -import errno -import pytest - -from cmp_custom import cmp_custom -from conftest import DecoderFrontend - -#params -tag_list = ['stvFOA'] -plc_patterns = ['PLperc12mblen5', 'PLperc40mblen50', 'PLperc42mblen2'] -dtx_set = ['0', '1'] -ivas_br_list = ['32000', '64000', '96000', '256000'] -sampling_rate_list = ['48', '32', '16'] -agc_list = [0, 1] - -AbsTol = '3' - - -def check_and_makedir(dir_path): - if not os.path.exists(dir_path): - try: - os.makedirs(dir_path) - except OSError as e: - if e.errno != errno.EEXIST: - raise # raises the error again - - -# assumption: -# - the needed reference bitstreams are created by test_sba_enc_system -# -> reference bitstreams are not any longer created as part of this test -# -> the parameters of this test (except additional parameter plc_pattern) need to be a subset of the parameters in test_sba_enc_system -# -> the reference generation for this test (reference decoder output) needs to be done after completion of test_sba_enc_system -# -> therefore the marker create_ref_part2 -@pytest.mark.create_ref_part2 -@pytest.mark.parametrize("ivas_br", ivas_br_list) -@pytest.mark.parametrize("dtx", dtx_set) -@pytest.mark.parametrize("tag", tag_list) -@pytest.mark.parametrize("plc_pattern", plc_patterns) -@pytest.mark.parametrize("fs", sampling_rate_list) -@pytest.mark.parametrize("agc", agc_list) -def test_sba_plc_system( - dut_decoder_frontend: DecoderFrontend, - test_vector_path, - reference_path, - dut_base_path, - ref_decoder_path, - update_ref, - keep_files, - ivas_br, - dtx, - tag, - plc_pattern, - fs, - agc -): - tag = tag + fs + 'c' - - #dec - sba_dec_plc( - dut_decoder_frontend, - test_vector_path, - reference_path, - dut_base_path, - ref_decoder_path, - tag, - fs, - ivas_br, - dtx, - plc_pattern, - update_ref, - agc, - keep_files, - ) - - -######################################################### -############ test function ############################## -def sba_dec_plc( - decoder_frontend, - test_vector_path, - reference_path, - dut_base_path, - ref_decoder_path, - tag, - sampling_rate, - ivas_br, - dtx, - plc_pattern, - update_ref, - agc, - keep_files, -): - - ######### run cmd ##################################### - - tag_out = f"{tag}_ivasbr{ivas_br[:-3]}k_DTX{dtx}" - if agc == 1: - tag_out += '_AGC1' - plc_tag_out = f"{tag_out}_{plc_pattern}" - - dut_out_dir = f"{dut_base_path}/sba_bs/raw" - ref_out_dir = f"{reference_path}/sba_bs/raw" - - check_and_makedir(dut_out_dir) - check_and_makedir(ref_out_dir) - - plc_file = f"{test_vector_path}/{plc_pattern}.g192" - ref_in_pkt = f"{reference_path}/sba_bs/pkt/{tag_out}.pkt" - ref_in_pkt_dutenc = f"{reference_path}/sba_bs/pkt/{tag_out}_dutenc.pkt" - - dut_out_raw = f"{dut_out_dir}/{plc_tag_out}.raw" - ref_out_raw = f"{ref_out_dir}/{plc_tag_out}.raw" - - if ref_decoder_path: - ref_decoder = DecoderFrontend(ref_decoder_path, "REF") - - # call REF decoder - ref_decoder.run( - "FOA", - sampling_rate, - ref_in_pkt, - ref_out_raw, - plc_file=plc_file, - ) - - if update_ref == 0: - # call DUT decoder - decoder_frontend.run( - "FOA", - sampling_rate, - ref_in_pkt_dutenc, - dut_out_raw, - plc_file=plc_file, - ) - - ######### compare cmd ##################################### - - end_skip_samples = '0' - - cmp_result, reason = cmp_custom( - dut_out_raw, - ref_out_raw, - "2", - AbsTol, - end_skip_samples - ) - - # report compare result - assert cmp_result == 0, reason - - # remove DUT output files when test result is OK (to save disk space) - if not keep_files: - os.remove(dut_out_raw) diff --git a/tests/testconfig.py b/tests/testconfig.py deleted file mode 100644 index f4827a004f..0000000000 --- a/tests/testconfig.py +++ /dev/null @@ -1,37 +0,0 @@ -__copyright__ = \ -""" -(C) 2022 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. -""" - -__doc__ = \ -""" -To configure test modules. -""" - -PARAM_FILE = "scripts/config/self_test.prm" -- GitLab From 157959e89cd04594ed408c1fb737cf6324de94c9 Mon Sep 17 00:00:00 2001 From: Archit Tamarapu Date: Tue, 4 Oct 2022 19:00:30 +0200 Subject: [PATCH 020/101] manually fix merge, pipeline failures can be ignored until v2 is merged in --- apps/decoder.c | 9 +- apps/encoder.c | 2 +- ci/check_for_warnings.py | 2 +- ci/disable_ram_counting.py | 0 ci/run_evs_be_test.py | 76 +++ ci/run_scheduled_sanitizer_test.py | 130 +++++ lib_com/bitstream.c | 55 +- lib_com/cnst.h | 3 +- lib_com/ivas_cnst.h | 42 +- lib_com/ivas_dirac_com.c | 48 +- lib_com/ivas_fb_mixer.c | 4 +- lib_com/ivas_prot.h | 180 +++--- lib_com/ivas_rom_com.c | 34 +- lib_com/ivas_sba_config.c | 39 +- lib_com/ivas_sns_com.c | 4 +- lib_com/ivas_spar_com.c | 43 +- lib_com/ivas_spar_com_quant_util.c | 78 +-- lib_com/ivas_stat_com.h | 4 +- lib_com/ivas_stereo_dft_com.c | 4 + lib_com/ivas_stereo_mdct_stereo_com.c | 2 +- lib_com/ivas_stereo_psychlpc_com.c | 5 +- lib_com/ivas_tools.c | 4 + lib_com/options.h | 23 +- lib_com/prot.h | 51 +- lib_dec/acelp_core_dec.c | 12 +- lib_dec/acelp_core_switch_dec.c | 2 +- lib_dec/amr_wb_dec.c | 2 +- lib_dec/core_dec_init.c | 7 +- lib_dec/core_dec_switch.c | 6 +- lib_dec/core_switching_dec.c | 4 + lib_dec/dec_LPD.c | 4 +- lib_dec/dec_acelp_tcx_main.c | 2 +- lib_dec/dec_prm.c | 6 +- lib_dec/dec_tcx.c | 69 ++- lib_dec/er_dec_tcx.c | 73 +-- lib_dec/evs_dec.c | 2 +- lib_dec/fd_cng_dec.c | 94 ++-- lib_dec/igf_dec.c | 54 ++ lib_dec/init_dec.c | 6 +- lib_dec/ivas_core_dec.c | 21 +- lib_dec/ivas_cpe_dec.c | 50 +- lib_dec/ivas_dec.c | 17 +- lib_dec/ivas_dirac_dec.c | 87 ++- lib_dec/ivas_init_dec.c | 216 +++----- lib_dec/ivas_ism_metadata_dec.c | 8 + lib_dec/ivas_ism_param_dec.c | 8 + lib_dec/ivas_masa_dec.c | 32 ++ lib_dec/ivas_mc_param_dec.c | 2 +- lib_dec/ivas_mct_dec_mct.c | 4 + lib_dec/ivas_mdct_core_dec.c | 66 +-- lib_dec/ivas_out_setup_conversion.c | 4 - lib_dec/ivas_qmetadata_dec.c | 35 +- lib_dec/ivas_sba_dec.c | 93 ++-- lib_dec/ivas_sce_dec.c | 14 +- lib_dec/ivas_spar_decoder.c | 48 +- lib_dec/ivas_spar_md_dec.c | 722 +++++++++++-------------- lib_dec/ivas_stat_dec.h | 42 +- lib_dec/ivas_stereo_cng_dec.c | 20 + lib_dec/ivas_stereo_dft_dec.c | 40 ++ lib_dec/ivas_stereo_mdct_core_dec.c | 41 +- lib_dec/ivas_stereo_mdct_stereo_dec.c | 22 +- lib_dec/ivas_stereo_switching_dec.c | 32 +- lib_dec/ivas_tcx_core_dec.c | 12 +- lib_dec/lib_dec.c | 116 ++-- lib_dec/stat_dec.h | 5 +- lib_dec/swb_tbe_dec.c | 11 +- lib_dec/tonalMDCTconcealment.c | 123 ++++- lib_enc/bw_detect.c | 1 - lib_enc/enc_prm.c | 6 +- lib_enc/fd_cng_enc.c | 36 +- lib_enc/igf_enc.c | 6 +- lib_enc/ivas_agc_enc.c | 10 +- lib_enc/ivas_cpe_enc.c | 27 +- lib_enc/ivas_dirac_enc.c | 34 +- lib_enc/ivas_init_enc.c | 108 ++-- lib_enc/ivas_ism_enc.c | 4 + lib_enc/ivas_masa_enc.c | 4 +- lib_enc/ivas_mcmasa_enc.c | 4 +- lib_enc/ivas_mct_enc.c | 42 +- lib_enc/ivas_mct_enc_mct.c | 9 + lib_enc/ivas_mdct_core_enc.c | 6 +- lib_enc/ivas_qmetadata_enc.c | 59 +- lib_enc/ivas_rom_enc.c | 154 ------ lib_enc/ivas_rom_enc.h | 5 - lib_enc/ivas_sba_enc.c | 43 +- lib_enc/ivas_sce_enc.c | 16 +- lib_enc/ivas_sns_enc.c | 2 +- lib_enc/ivas_spar_encoder.c | 67 +-- lib_enc/ivas_spar_md_enc.c | 544 +++++++------------ lib_enc/ivas_stat_enc.h | 8 +- lib_enc/ivas_stereo_cng_enc.c | 9 + lib_enc/ivas_stereo_dft_enc.c | 16 +- lib_enc/ivas_stereo_dft_enc_itd.c | 15 - lib_enc/ivas_stereo_dmx_evs.c | 65 --- lib_enc/ivas_stereo_mdct_core_enc.c | 9 + lib_enc/ivas_stereo_switching_enc.c | 15 +- lib_enc/ivas_tcx_core_enc.c | 2 +- lib_enc/lib_enc.c | 253 +++++---- lib_enc/tcx_utils_enc.c | 4 + lib_rend/ivas_crend.c | 14 + lib_rend/ivas_hrtf.c | 4 +- lib_rend/ivas_objectRenderer.c | 236 +++++++- lib_rend/ivas_objectRenderer_hrFilt.c | 44 +- lib_rend/ivas_objectRenderer_mix.c | 9 +- lib_rend/ivas_objectRenderer_sfx.c | 47 +- lib_rend/ivas_objectRenderer_sources.c | 12 +- lib_rend/ivas_output_init.c | 38 +- lib_rend/ivas_reverb.c | 7 + lib_rend/ivas_sba_rendering.c | 46 +- lib_util/hrtf_file_reader.c | 3 +- 110 files changed, 2933 insertions(+), 2186 deletions(-) mode change 100644 => 100755 ci/disable_ram_counting.py create mode 100755 ci/run_evs_be_test.py create mode 100755 ci/run_scheduled_sanitizer_test.py diff --git a/apps/decoder.c b/apps/decoder.c index 953df8d6b8..968dc79ec2 100644 --- a/apps/decoder.c +++ b/apps/decoder.c @@ -158,6 +158,7 @@ static void print_mem_dec( size_t SRAM_size ) fprintf( stdout, "PROM size (common): %d words (or instructions)\n", PROM_Size_lib_com ); fprintf( stdout, "Stack size (decoder): %ld words in %s() in frame #%d\n", ( ( ptr_base_stack - ptr_max_stack ) * sizeof( int16_t ) ) / sizeof( float ), location_max_stack, wc_frame ); fprintf( stdout, "Table ROM size (decoder): %ld words\n", ( Const_Data_Size_rom_dec() + Const_Data_Size_ivas_rom_dec() ) / sizeof( float ) ); + fprintf( stdout, "Table ROM size (binaural renderer): %ld words\n", ( Const_Data_Size_ivas_rom_binauralRen() + Const_Data_Size_ivas_rom_TdBinauralR() + Const_Data_Size_ivas_rom_binaural_cr() ) / sizeof( float ) ); fprintf( stdout, "Table ROM size (common): %ld words\n", ( Const_Data_Size_rom_com() + Const_Data_Size_ivas_rom_com() ) / sizeof( float ) ); #ifdef RAM_COUNTING_TOOL fprintf( stdout, "Static RAM size (decoder): %ld words\n\n", SRAM_size ); @@ -426,25 +427,25 @@ int main( /* sanity check */ if ( arg.outputFormat != IVAS_DEC_OUTPUT_BINAURAL_ROOM ) { - fprintf( stderr, "\nExternal Renderer Config is supported only when BINAURAL_ROOM is used as output. Exiting. \n" ); + fprintf( stderr, "\nExternal Renderer Config is supported only when BINAURAL_ROOM is used as output. Exiting. \n\n" ); goto cleanup; } if ( ( error = IVAS_DEC_GetRenderConfig( hIvasDec, &renderConfig ) ) != IVAS_ERR_OK ) { - fprintf( stderr, "\nIVAS_DEC_GetRenderConfig failed: %s\n", IVAS_DEC_GetErrorMessage( error ) ); + fprintf( stderr, "\nIVAS_DEC_GetRenderConfig failed: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); goto cleanup; } if ( RenderConfigReader_read( renderConfigReader, &renderConfig ) != IVAS_ERR_OK ) { - fprintf( stderr, "Failed to read renderer configuration from file %s\n", arg.renderConfigFilename ); + fprintf( stderr, "Failed to read renderer configuration from file %s\n\n", arg.renderConfigFilename ); goto cleanup; } if ( ( error = IVAS_DEC_FeedRenderConfig( hIvasDec, renderConfig ) ) != IVAS_ERR_OK ) { - fprintf( stderr, "\nIVAS_DEC_FeedRenderConfig failed: %s\n", IVAS_DEC_GetErrorMessage( error ) ); + fprintf( stderr, "\nIVAS_DEC_FeedRenderConfig failed: %s\n\n", IVAS_DEC_GetErrorMessage( error ) ); goto cleanup; } } diff --git a/apps/encoder.c b/apps/encoder.c index 47a6d42e30..b1abc36d2f 100755 --- a/apps/encoder.c +++ b/apps/encoder.c @@ -1618,7 +1618,7 @@ static void usage_enc( void ) fprintf( stdout, " where 0 = adaptive, 3-100 = fixed in number of frames,\n" ); fprintf( stdout, " default is deactivated\n" ); fprintf( stdout, "-dtx : Activate DTX mode with a SID update rate of 8 frames\n" ); - fprintf( stdout, " Note: DTX is currently supported in EVS, DFT/TD stereo, 1 ISm, \n" ); + fprintf( stdout, " Note: DTX is currently supported in EVS, stereo, 1 ISm, \n" ); fprintf( stdout, " SBA (up to 128kbps) and MASA (up to 128kbps)\n" ); fprintf( stdout, "-rf p o : Activate channel-aware mode for WB and SWB signal at 13.2kbps, \n" ); fprintf( stdout, " where FEC indicator, p: LO or HI, and FEC offset, o: 2, 3, 5, or 7 in number of frames.\n" ); diff --git a/ci/check_for_warnings.py b/ci/check_for_warnings.py index c9240e040a..cc658b3d40 100755 --- a/ci/check_for_warnings.py +++ b/ci/check_for_warnings.py @@ -3,7 +3,7 @@ import argparse import sys -SEARCH_FOR = "warning:" +SEARCH_FOR = "warning" RETURN_FOUND = 123 diff --git a/ci/disable_ram_counting.py b/ci/disable_ram_counting.py old mode 100644 new mode 100755 diff --git a/ci/run_evs_be_test.py b/ci/run_evs_be_test.py new file mode 100755 index 0000000000..9fa64877f2 --- /dev/null +++ b/ci/run_evs_be_test.py @@ -0,0 +1,76 @@ +#!/usr/bin/env python3 +import subprocess +import pathlib +import sys +import concurrent.futures +from threading import Lock + + +README_FILES_PARALLEL = [ + "Readme_AMRWB_IO_enc.txt", + "Readme_AMRWB_IO_dec.txt", + "Readme_EVS_enc.txt", + "Readme_EVS_dec.txt", +] +README_FILES_JBM = ["Readme_JBM_dec.txt"] +README_FILES = README_FILES_PARALLEL + README_FILES_JBM +BINARY_PATHS = ["./bin/EVS_cod", "./bin/EVS_dec"] +FOLDER_PATHS = ["testv"] +BIN_PATHS = BINARY_PATHS * 2 + +def main(): + + if not environment_is_correct(): + return 1 + + result_dict = dict() + # run first part in parallel + with concurrent.futures.ThreadPoolExecutor(max_workers=4) as executor: + executor.map( + run_file, README_FILES_PARALLEL, BIN_PATHS, [result_dict] * len(README_FILES_PARALLEL) + ) + + # JBM test can not run concurrently with the others + run_file(README_FILES_JBM[0], BINARY_PATHS[1], result_dict) + + return analyze_results(result_dict) + + +def analyze_results(result_dict): + ret = 0 + + for filename, ret_code in result_dict.items(): + if ret_code != 0: + print(f"========= Test for {filename} failed! See log below: ==========") + with open(filename.replace("Readme", "Log")) as f: + print(f.read()) + ret = 1 + + return ret + + +def run_file(filename: str, bin_path: str, result_dict: dict): + ret_code = subprocess.call(["bash", filename, bin_path]) + with Lock(): + result_dict[filename] = ret_code + + +def environment_is_correct(): + """ + Check that the folder with the test resources is set up correctly: + - all Readme files there + - EVS binaries available in bin/ + - testv and switchPaths folder exist - Content is not checked, though + """ + ret = True + + for path in README_FILES + BINARY_PATHS + FOLDER_PATHS: + if not pathlib.Path(path).exists(): + print(f"Environment setup is incorrect - {path} not found.") + ret = False + + return ret + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/ci/run_scheduled_sanitizer_test.py b/ci/run_scheduled_sanitizer_test.py new file mode 100755 index 0000000000..1ffaaf55a8 --- /dev/null +++ b/ci/run_scheduled_sanitizer_test.py @@ -0,0 +1,130 @@ +#!/usr/bin/env python3 + +import argparse +import sys +import subprocess +import pathlib + + +DURATION = "120" +CFG = "ci_linux.json" +SUPPORTED_TESTS = ["CLANG1", "CLANG2", "CLANG3", "VALGRIND"] +EP_FILE = "ep_015.g192" +GENPATT_CMD = f"gen-patt -tailstat -fer -g192 -gamma 0 -rate 0.15 -tol 0.001 -reset -n {int(DURATION) * 50} {EP_FILE}" +EIDXOR_CMD = "eid-xor -vbr -fer {bitstream} {ep_file} {out_file}" +MC_MODES = ["5_1", "5_1_2", "5_1_4", "7_1", "7_1_4"] + +SCRIPT_DIR = pathlib.Path("./scripts").resolve() + + +def main(args): + in_format = args.in_format + out_formats = args.out_formats + tests = args.tests + run_fec = not args.skip_fec + + assert all([t in SUPPORTED_TESTS for t in tests]) + + modes = get_modes(in_format) + returncode = run_check(modes, out_formats, tests, run_fec=run_fec) + + sys.exit(returncode) + + +def get_modes(in_format: str) -> list: + + cmd = [ + SCRIPT_DIR.joinpath("runIvasCodec.py"), + "-C", + "MC" if in_format in MC_MODES else in_format, + "-l" + ] + list_process = subprocess.run(cmd, capture_output=True) + + output = list_process.stdout.decode("utf8") + + # correction for multichannel modes to avoid selecting some mono modes... + if in_format in MC_MODES: + in_format = "MC_" + in_format + "_b" + + mode_list = [m for m in output.splitlines() if in_format in m] + if "SBA" in in_format: + # rate switching not implemented yet + mode_list = [m for m in mode_list if not "_rs" in m] + + return mode_list + + +def run_check(modes: list, out_formats: list, tests: list, run_fec: bool = True): + + ### always run encoder and decoder with no frameloss + cmd_no_fec = [ + str(SCRIPT_DIR.joinpath("IvasBuildAndRunChecks.py")), + "-U", + DURATION, + "-p", + CFG, + "--checks", + *tests, + "-m", + *modes, + "--oc", + *out_formats, + ] + + print("======== Script command line WITHOUT plc: ========\n{}".format(" ".join(cmd_no_fec))) + + proc = subprocess.Popen(cmd_no_fec, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + for c in iter(lambda: proc.stdout.read(1), b""): + sys.stdout.buffer.write(c) + proc.wait() + + if proc.returncode not in [0, 101]: + raise IvasBuildAndRunFailed("Failed at first run (no PLC)") + + returncode_no_fec = proc.returncode + + if not run_fec: + return returncode_no_fec + + ### second run: decoder only with disturbed bitstream + + # generate error pattern + subprocess.call(GENPATT_CMD.split()) + + # cleanup to avoid script errors + # we want "logs" and "dec" subfolders to be empty -> delete and recreate them + cleanup_folders = ["logs", "dec"] + for t in tests: + for fol in cleanup_folders: + for fi in pathlib.Path(t).joinpath(fol).iterdir(): + fi.unlink() + + cmd_fec = cmd_no_fec + ["--decoder_only", "-f", EP_FILE] + print("======== Script command line WITH plc: ========\n{}".format(" ".join(cmd_no_fec))) + + proc = subprocess.Popen(cmd_fec, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + for c in iter(lambda: proc.stdout.read(1), b""): + sys.stdout.buffer.write(c) + proc.wait() + + returncode_fec = proc.returncode + + if returncode_fec not in [0, 101]: + raise IvasBuildAndRunFailed("failed at second run (PLC)") + + return 101 if 101 in [returncode_no_fec, returncode_fec] else 0 + + +class IvasBuildAndRunFailed(Exception): + pass + + +if __name__ == "__main__": + parser = argparse.ArgumentParser() + parser.add_argument("in_format", type=str) + parser.add_argument("out_formats", type=str, nargs="+") + parser.add_argument("--tests", type=str, nargs="+", default=["CLANG1", "CLANG2"]) + parser.add_argument("--skip_fec", action="store_true") + + sys.exit(main(parser.parse_args())) diff --git a/lib_com/bitstream.c b/lib_com/bitstream.c index 4e81fc9166..9ee771fb6b 100755 --- a/lib_com/bitstream.c +++ b/lib_com/bitstream.c @@ -1820,7 +1820,11 @@ ivas_error preview_indices( break; } } +#ifdef ALIGN_SID_SIZE + else if ( total_brate == IVAS_SID_5k2 ) +#else else if ( total_brate == IVAS_SID_4k4 ) +#endif { /* read SID format */ st_ivas->sid_format = 0; @@ -1884,6 +1888,7 @@ ivas_error preview_indices( return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Invalid value %c found in SID format field.", st_ivas->sid_format ); } } +#ifndef ALIGN_SID_SIZE else if ( total_brate == IVAS_SID_5k ) { /* SBA SID frame */ @@ -1892,6 +1897,7 @@ ivas_error preview_indices( st_ivas->sba_mode = SBA_MODE_SPAR; st_ivas->element_mode_init = IVAS_SCE; } +#endif /* only read element mode from active frames */ if ( is_DTXrate( total_brate ) == 0 ) @@ -1975,28 +1981,17 @@ ivas_error preview_indices( } 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_SBA] == 1 ); -#ifndef SBA_ORDER_BITSTREAM st_ivas->sba_order = ( bit_stream[IVAS_FORMAT_SIGNALING_NBITS_SBA + 2] == 1 ); st_ivas->sba_order += 2 * ( bit_stream[IVAS_FORMAT_SIGNALING_NBITS_SBA + 1] == 1 ); + + st_ivas->sba_analysis_order = ivas_sba_get_analysis_order( total_brate, st_ivas->sba_order ); + +#ifdef HARMONIZE_SBA_NCHAN_TRANSPORT + 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 - st_ivas->hDecoderConfig->sba_order = ( bit_stream[IVAS_FORMAT_SIGNALING_NBITS_SBA + 2] == 1 ); - st_ivas->hDecoderConfig->sba_order += 2 * ( bit_stream[IVAS_FORMAT_SIGNALING_NBITS_SBA + 1] == 1 ); - st_ivas->sba_analysis_order = st_ivas->hDecoderConfig->sba_order; -#endif -#ifdef SBA_ORDER_BITSTREAM - /*Hard coding the the sba_oder as 1 as higher not supported below 256k bitrate*/ - if ( total_brate < IVAS_256k ) - { - st_ivas->sba_analysis_order = 1; - } -#endif -#ifdef SBA_ORDER_BITSTREAM 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 ), st_ivas->sba_mode ); -#else - ivas_sba_config( total_brate, st_ivas->sba_order, -1, &( st_ivas->nchan_transport ), st_ivas->sba_planar, &( st_ivas->nSCE ), &( st_ivas->nCPE ), &( st_ivas->element_mode_init ), st_ivas->sba_mode ); #endif } } @@ -2077,7 +2072,10 @@ ivas_error read_indices( } else if ( k == SIZE_IVAS_BRATE_TBL ) { - /*temp change for spar DTX*/ +#ifdef ALIGN_SID_SIZE + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Error, illegal bitrate (%d) in the G.192 frame ! Exiting ! \n", total_brate ); +#else + /*temp change for SPAR DTX*/ if ( total_brate == IVAS_SID_5k ) { st_ivas->element_mode_init = -1; @@ -2086,6 +2084,7 @@ ivas_error read_indices( { return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Error, illegal bitrate (%d) in the G.192 frame ! Exiting ! \n", total_brate ); } +#endif } else { @@ -2130,7 +2129,7 @@ ivas_error read_indices( } else { - sid_upd_bad = 1; /* this frame type may happen in ETSI/3GPP CS cases , a corrupt sid frames */ + sid_upd_bad = 1; /* this frame type may happen in ETSI/3GPP CS cases, a corrupt SID frames */ } } @@ -2215,7 +2214,7 @@ ivas_error read_indices( /* total_brate= 0 */ } - /* handle bad/lost speech frame(and CS bad sid frame) in the decoders CNG synthesis settings pair (total_brate, bfi) */ + /* handle bad/lost speech frame(and CS bad SID frame) in the decoders CNG synthesis settings pair (total_brate, bfi) */ if ( ( ( *CNG != 0 ) && ( ( speech_bad != 0 ) || ( speech_lost != 0 ) ) ) || /* SP_BAD or SPEECH_LOST) --> stay in CNG */ ( sid_upd_bad != 0 ) ) /* SID_UPD_BAD --> start CNG */ { @@ -2334,7 +2333,7 @@ static Word32 read_indices_mime_handle_dtx( { if ( st->bfi ) { - sid_upd_bad = 1; /* corrupt sid_first, signaled as bad sid */ + sid_upd_bad = 1; /* corrupt sid_first, signaled as bad SID */ } else { @@ -2392,7 +2391,7 @@ static Word32 read_indices_mime_handle_dtx( } /* in CNG */ - /* handle bad speech frame(and bad sid frame) in the decoders CNG synthesis settings pair (total_brate, bfi) */ + /* handle bad speech frame(and bad SID frame) in the decoders CNG synthesis settings pair (total_brate, bfi) */ if ( ( *CNG != 0 && ( speech_bad || speech_lost || no_data ) ) || /* SP_BAD or SPEECH_LOST) --> stay in CNG */ sid_upd_bad ) /* SID_UPD_BAD --> start/stay CNG */ { @@ -2979,4 +2978,18 @@ void evs_dec_previewFrame( } +#ifdef ALIGN_SID_SIZE +void dtx_read_padding_bits( + DEC_CORE_HANDLE st, + int16_t num_bits ) +{ + /* TODO: temporary hack, need to decide what to do with core-coder bitrate */ + int32_t tmp; + tmp = st->total_brate; + st->total_brate = st->total_brate + num_bits * FRAMES_PER_SEC; + get_next_indice( st, num_bits ); + st->total_brate = tmp; +} +#endif + #undef WMC_TOOL_MAN diff --git a/lib_com/cnst.h b/lib_com/cnst.h index 8e4c7c9908..40a4710579 100644 --- a/lib_com/cnst.h +++ b/lib_com/cnst.h @@ -67,8 +67,7 @@ #define MAX16B_FLT 32767.0f #define MIN16B_FLT ( -32768.0f ) #define PCM16_TO_FLT_FAC 32768.0f - - +#define MDFT_NORM_SCALING ( 1.0f / PCM16_TO_FLT_FAC ) #define MAX_FRAME_COUNTER 200 #define MAX_BITS_PER_FRAME 10240 /* Bits per frame for max. bitrate 512kbps */ diff --git a/lib_com/ivas_cnst.h b/lib_com/ivas_cnst.h index 223f3fa490..43b60566dc 100644 --- a/lib_com/ivas_cnst.h +++ b/lib_com/ivas_cnst.h @@ -170,7 +170,9 @@ typedef enum #define HEAD_ROTATION_HOA_ORDER 3 /* HOA 3rd order */ #define MAX_CICP_CHANNELS 16 /* max channels for loudspeaker layouts (16 for custom layouts)*/ #define MAX_OUTPUT_CHANNELS 16 /* Maximum number of output channels (HOA 3rd order) */ +#ifndef FIX_CREND_CHANNELS #define IVAS_MAX_NUM_CH 16 /* == MAX_OUTPUT_CHANNELS */ +#endif #define FOA_CHANNELS 4 /* number of FOA channels */ @@ -200,9 +202,12 @@ typedef enum /*----------------------------------------------------------------------------------* * IVAS Bitrates *----------------------------------------------------------------------------------*/ - +#ifdef ALIGN_SID_SIZE +#define IVAS_SID_5k2 5200 /* SID frame bitrate */ +#else #define IVAS_SID_4k4 4400 /* SID frame bitrate */ #define IVAS_SID_5k 5000 /* SBA SID frame bitrate */ +#endif #define IVAS_13k2 13200 #define IVAS_16k4 16400 #define IVAS_24k4 24400 @@ -220,8 +225,13 @@ typedef enum #define IVAS_BRATE_MAX IVAS_512k +#ifdef ALIGN_SID_SIZE +#define SIZE_IVAS_BRATE_TBL 16 +#define IVAS_NUM_ACTIVE_BRATES (SIZE_IVAS_BRATE_TBL - 2) +#else #define SIZE_IVAS_BRATE_TBL 17 #define IVAS_NUM_ACTIVE_BRATES (SIZE_IVAS_BRATE_TBL - 3) +#endif /*----------------------------------------------------------------------------------* * IVAS modes : IVAS SCE, IVAS CPE modes (DFT, TD, MDCT stereo) @@ -802,16 +812,25 @@ enum fea_names #define MAX_MDCT_ITD_BRATE IVAS_64k #define SNS_LOW_BR_MODE -1 -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE #define SNS_NPTS 16 /* Number of downsampled SNS parameters */ -#define MDCT_ST_PLC_FADEOUT_START_FRAME 3 +#define MDCT_ST_PLC_FADEOUT_MIN_NOISE_NRG 0.001f +#ifdef FADE_TO_ZERO_FOR_TOO_LONG_FRAMELOSS +#define MDCT_ST_PLC_FADEOUT_MAX_CONC_FRAME 2 * FRAMES_PER_SEC +#define MDCT_ST_PLC_FADEOUT_TO_ZERO_LEN 20 +#endif typedef enum { EQUAL_CORES, TCX10_IN_0_TCX20_IN_1, TCX20_IN_0_TCX10_IN_1, } TONALMDCTCONC_NOISE_GEN_MODE; + +typedef enum { + ON_FIRST_LOST_FRAME, + ON_FIRST_GOOD_FRAME, +} TONALMDCTCONC_NOISE_SHAPE_WHITENING_MODE; #endif @@ -828,6 +847,9 @@ typedef enum { *----------------------------------------------------------------------------------*/ // VE: this should be renamed to e.g. N_SPATIAL_SUBFRAMES #define MAX_PARAM_SPATIAL_SUBFRAMES 4 /* Maximum number of subframes for parameteric spatial coding */ +#ifdef FIX_I106_TDREND_5MS +#define L_SPATIAL_SUBFR_48k (L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES) +#endif /*----------------------------------------------------------------------------------* @@ -836,6 +858,7 @@ typedef enum { #define SBA_PLANAR_BITS 1 #define SBA_ORDER_BITS 2 +#define SBA_MIN_BRATE_HOA IVAS_256k #define SBA_NHARM_HOA3 16 #define SBA_T_DESIGN_11_SIZE 70 @@ -851,8 +874,15 @@ typedef enum * DirAC Constants *----------------------------------------------------------------------------------*/ +#ifdef FIX_DIRAC_CHANNELS +#define DIRAC_MAX_ANA_CHANS FOA_CHANNELS /* Maximum number of channels for DirAC analysis */ +#else #define DIRAC_MAX_ANA_CHANS 4 /* Maximum number of channels for DirAC analysis */ +#endif + +#ifndef HARMONIZE_SBA_NCHAN_TRANSPORT #define DIRAC_MAX_TRANS_CHANS 8 /* Maximum number of transport channels for DirAC */ +#endif #define DIRAC_MIN_BITRATE_8_TRANS_CHAN IVAS_384k #define DIRAC_MIN_BITRATE_6_TRANS_CHAN IVAS_256k @@ -1006,9 +1036,9 @@ enum #define IVAS_DECORR_PARM_LOOKAHEAD_TAU 2e-3f #define IVAS_DECORR_PARM_APD_TAU 20e-3f -/* IVAS PCA */ +/* IVAS SBA PCA */ #define IVAS_PCA_NB_SUBR 20 /* 80 -> 0.25 ms, 40 -> 0.5 ms... */ -#define IVAS_PCA_COV_THRES 1e-9f +#define IVAS_PCA_COV_THRES 3e-5f #define IVAS_PCA_QUAT_EPS 1e-7f #define IVAS_PCA_QBITS 19 #define IVAS_PCA_N1 91 @@ -1139,7 +1169,7 @@ enum #define MASA_STEREO_MIN_BITRATE IVAS_24k4 #define MASA_BIT_REDUCT_PARAM 10 - +#define MASA_MAXIMUM_TWO_DIR_BANDS 18 typedef enum { MASA_STEREO_NOT_DEFINED, diff --git a/lib_com/ivas_dirac_com.c b/lib_com/ivas_dirac_com.c index 849e889739..fe344e6423 100644 --- a/lib_com/ivas_dirac_com.c +++ b/lib_com/ivas_dirac_com.c @@ -60,7 +60,11 @@ ivas_error ivas_dirac_config( ) { IVAS_FORMAT ivas_format; +#ifdef HARMONIZE_SBA_NCHAN_TRANSPORT + int16_t sba_order; +#else int16_t sba_order, sba_planar; +#endif int16_t *nSCE, *nCPE, *element_mode, *nchan_transport; int32_t ivas_total_brate; DIRAC_CONFIG_DATA_HANDLE hConfig; @@ -82,12 +86,10 @@ ivas_error ivas_dirac_config( nCPE = &( (Encoder_Struct *) st_ivas )->nCPE; element_mode = &( (Encoder_Struct *) st_ivas )->hEncoderConfig->element_mode_init; nchan_transport = &( (Encoder_Struct *) st_ivas )->nchan_transport; -#ifndef SBA_ORDER_BITSTREAM - sba_order = ( (Encoder_Struct *) st_ivas )->hEncoderConfig->sba_order; -#else sba_order = ( (Encoder_Struct *) st_ivas )->sba_analysis_order; -#endif +#ifndef HARMONIZE_SBA_NCHAN_TRANSPORT sba_planar = ( (Encoder_Struct *) st_ivas )->hEncoderConfig->sba_planar; +#endif ivas_total_brate = ( (Encoder_Struct *) st_ivas )->hEncoderConfig->ivas_total_brate; Fs = ( (Encoder_Struct *) st_ivas )->hEncoderConfig->input_Fs; band_grouping = ( (Encoder_Struct *) st_ivas )->hDirAC->band_grouping; @@ -111,12 +113,10 @@ ivas_error ivas_dirac_config( nCPE = &( (Decoder_Struct *) st_ivas )->nCPE; element_mode = &( (Decoder_Struct *) st_ivas )->element_mode_init; nchan_transport = &( (Decoder_Struct *) st_ivas )->nchan_transport; -#ifndef SBA_ORDER_BITSTREAM - sba_order = ( (Decoder_Struct *) st_ivas )->sba_order; -#else sba_order = ( (Decoder_Struct *) st_ivas )->sba_analysis_order; -#endif +#ifndef HARMONIZE_SBA_NCHAN_TRANSPORT sba_planar = ( (Decoder_Struct *) st_ivas )->sba_planar; +#endif ivas_total_brate = ( (Decoder_Struct *) st_ivas )->hDecoderConfig->ivas_total_brate; Fs = ( (Decoder_Struct *) st_ivas )->hDecoderConfig->output_Fs; band_grouping = ( (Decoder_Struct *) st_ivas )->hDirAC->band_grouping; @@ -150,8 +150,12 @@ ivas_error ivas_dirac_config( if ( ivas_format == SBA_FORMAT ) /* skip for MASA decoder */ { +#ifdef HARMONIZE_SBA_NCHAN_TRANSPORT + if ( ( error = ivas_dirac_sba_config( hQMetaData, nchan_transport, nSCE, nCPE, element_mode, ivas_total_brate, sba_order, sba_mode, hConfig->nbands - spar_dirac_split_band ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_dirac_sba_config( hQMetaData, nchan_transport, nSCE, nCPE, element_mode, ivas_total_brate, sba_order, sba_planar, sba_mode, hConfig->nbands - spar_dirac_split_band ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -315,9 +319,11 @@ ivas_error ivas_dirac_sba_config( int16_t *element_mode, /* i/o: element mode of the core coder */ int32_t sba_total_brate, /* i : SBA total bitrate */ const int16_t sba_order, /* i : Ambisonic (SBA) order */ - const int16_t sba_planar, /* i : SBA planar flag */ - const SBA_MODE sba_mode, /* i : SBA mode */ - const int16_t nbands /* i : number of frequency bands */ +#ifndef HARMONIZE_SBA_NCHAN_TRANSPORT + const int16_t sba_planar, /* i : SBA planar flag */ +#endif + const SBA_MODE sba_mode, /* i : SBA mode */ + const int16_t nbands /* i : number of frequency bands */ ) { int16_t i; @@ -331,7 +337,11 @@ ivas_error ivas_dirac_sba_config( if ( sba_mode == SBA_MODE_SPAR ) { /*map the bitrate for SID frame*/ +#ifdef ALIGN_SID_SIZE + if ( sba_total_brate == IVAS_SID_5k2 ) +#else if ( sba_total_brate == IVAS_SID_5k ) +#endif { if ( *element_mode == IVAS_SCE ) { @@ -428,11 +438,23 @@ ivas_error ivas_dirac_sba_config( return error; } +#ifdef ALIGN_SID_SIZE + if ( sba_total_brate > IVAS_SID_5k2 ) +#else if ( sba_total_brate > IVAS_SID_4k4 ) +#endif { +#ifdef HARMONIZE_SBA_NCHAN_TRANSPORT + *nchan_transport = ivas_get_sba_num_TCs( sba_total_brate, sba_order ); +#else *nchan_transport = ivas_dirac_getNumTransportChannels( sba_total_brate, sba_order, sba_planar ); +#endif } +#ifdef ALIGN_SID_SIZE + else if ( sba_total_brate == IVAS_SID_5k2 ) +#else else if ( sba_total_brate == IVAS_SID_4k4 ) +#endif { switch ( *element_mode ) { @@ -571,7 +593,7 @@ ivas_error ivas_dirac_sba_config( return error; } - +#ifndef HARMONIZE_SBA_NCHAN_TRANSPORT /*------------------------------------------------------------------------- * ivas_dirac_getNumTransportChannels() * @@ -643,7 +665,7 @@ int16_t ivas_dirac_getNumTransportChannels( return num_channels; } - +#endif /*------------------------------------------------------------------------- * computeDirectionVectors() diff --git a/lib_com/ivas_fb_mixer.c b/lib_com/ivas_fb_mixer.c index 11746c64ef..53ad90d01f 100644 --- a/lib_com/ivas_fb_mixer.c +++ b/lib_com/ivas_fb_mixer.c @@ -1098,8 +1098,8 @@ static ivas_error ivas_filterbank_setup( for ( j = 0; j < IVAS_MAX_NUM_FB_BANDS; j++ ) { - pFb->fb_bin_to_band.p_short_stride_num_bins_per_band[j] = 0; /* aka num_active_bins per spar band */ - pFb->fb_bin_to_band.p_short_stride_start_bin_per_band[j] = 0; /* first considered bin index per spar band */ + pFb->fb_bin_to_band.p_short_stride_num_bins_per_band[j] = 0; /* aka num_active_bins per SPAR band */ + pFb->fb_bin_to_band.p_short_stride_start_bin_per_band[j] = 0; /* first considered bin index per SPAR band */ pFb->fb_bin_to_band.pp_short_stride_bin_to_band[j] = NULL; for ( i = 0; i < CLDFB_NO_CHANNELS_MAX; i++ ) { diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index 3003b9f785..b5bcfd5fb1 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -238,6 +238,10 @@ uint32_t ivas_syn_output( int16_t *synth_out /* o : integer 16 bits synthesis signal */ ); +void ivas_initialize_handles_enc( + Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ +); + ivas_error ivas_init_encoder( Encoder_Struct *st_ivas, /* i/o: IVAS encoder structure */ Indice ind_list[][MAX_NUM_INDICES], /* i : indices list */ @@ -794,8 +798,8 @@ void ivas_param_ism_enc( ); void ivas_param_ism_enc_close( - DIRAC_ENC_HANDLE hDirAC /* i/o: encoder DirAC handle */ - ,const int32_t input_Fs /* i : input sampling_rate */ + DIRAC_ENC_HANDLE hDirAC, /* i/o: encoder DirAC handle */ + const int32_t input_Fs /* i : input sampling_rate */ ); void ivas_param_ism_stereo_dmx( @@ -1845,7 +1849,7 @@ void TNSAnalysisStereo( 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 */ 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) */ + const int16_t mct_on /* i : flag mct block (1) or stereo (0) */ ); void InternalTCXDecoder( @@ -1946,15 +1950,12 @@ void decoder_tcx_invQ( const int16_t **prm_sqQ, int16_t *nf_seed, const int16_t bfi, /* i : Bad frame indicator */ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT - const int16_t isMCT, -#endif const int16_t frame_cnt /* i : frame counter in the super frame */ ); void decoder_tcx_noisefilling( Decoder_State *st, /* i/o: coder memory state */ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE float concealment_noise[L_FRAME48k], #endif const float A[], /* i : coefficients NxAz[M+1] */ @@ -1969,7 +1970,7 @@ void decoder_tcx_noisefilling( const int16_t *prm_sqQ, int16_t nf_seed, const int16_t bfi, /* i : Bad frame indicator */ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE const int16_t isMCT, #endif const int16_t frame_cnt /* i : frame counter in the super frame */ @@ -2013,7 +2014,7 @@ void decoder_tcx_imdct( const int16_t left_rect, float x[N_MAX], float xn_buf[], - const uint16_t kernelType, /* i : TCX transform kernel type */ + const uint16_t kernelType, /* i : TCX transform kernel type */ const int16_t fUseTns, /* i : flag that is set if TNS data is present */ float synth[], /* i/o: synth[-M..L_frame] */ float synthFB[], @@ -2054,7 +2055,12 @@ void decoder_tcx_IGF_stereo( const int16_t L_frame, /* i : frame length */ const int16_t left_rect, /* i : left part is rectangular */ const int16_t k, /* i : Subframe index */ +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE + const int16_t bfi, /* i : bad frame indicator */ + const int16_t is_mct /* i : flag to signal MCT or SMDCT */ +#else const int16_t bfi /* i : bad frame indicator */ +#endif ); void ms_processing( @@ -2087,7 +2093,12 @@ void IGFDecApplyStereo( const int16_t igfGridIdx, /* i : in case of CELP->TCX switching, use 1.25 framelength */ const int16_t *coreMsMask, const int16_t restrict_hopsize, +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE + const int16_t bfi, /* i : frame loss == 1, frame good == 0 */ + const int16_t bfi_apply_damping /* i : decoder element mode */ +#else const int16_t bfi /* i : frame loss == 1, frame good == 0 */ +#endif ); void IGFEncStereoEncoder( @@ -2155,7 +2166,7 @@ void stereo_mdct_core_dec( void splitAvailableBits( const int16_t total_bits, /* i : total available bits for TCX coding */ const int16_t split_ratio, /* i : split ratio */ - const int16_t isSBAStereoMode, /* i : signal core coding for sba */ + const int16_t isSBAStereoMode, /* i : signal core coding for SBA */ int16_t *bits_ch0, /* o : bits for channel 0 */ int16_t *bits_ch1 /* o : bits for channel 1 */ ); @@ -2173,7 +2184,7 @@ void parse_stereo_from_bitstream( STEREO_MDCT_DEC_DATA_HANDLE hStereoMdct, /* i/o: MDCT stereo decoder structure */ Decoder_State **sts, /* i/o: decoder state structure */ const int16_t mct_on, /* i : flag mct block (1) or stereo (0) */ - const int16_t isSBAStereoMode, /* i: flag core coding for sba */ + const int16_t isSBAStereoMode, /* i : flag core coding for SBA */ Decoder_State *st0, /* i/o: decoder state structure for Bstr */ int16_t ms_mask[NB_DIV][MAX_SFB] /* o : bandwise MS mask */ ); @@ -2508,8 +2519,7 @@ ivas_error stereo_memory_enc( const int32_t input_Fs, /* i : input sampling rate */ const int16_t max_bwidth, /* i : maximum audio bandwidth */ float *tdm_last_ratio, /* o : TD stereo last ratio */ - const IVAS_FORMAT ivas_format /* i : IVAS format */ - , + const IVAS_FORMAT ivas_format, /* i : IVAS format */ const int16_t nchan_transport /* i : number transport chans */ ); @@ -2768,8 +2778,12 @@ void reset_metadata_spatial( int32_t *total_brate, /* o : total bitrate */ const int32_t core_brate, /* i : core bitrate */ const int16_t nb_bits_metadata, /* i : number of meatdata bits */ +#ifndef ALIGN_SID_SIZE const SBA_MODE sba_mode, /* i : SBA mode */ const int16_t element_mode /* i : element mode */ +#else + const SBA_MODE sba_mode /* i : SBA mode */ +#endif ); /*! r: number of bits written */ @@ -3019,8 +3033,10 @@ void ivas_sba_config( const int16_t sba_planar, /* i : SBA planar flag */ int16_t *nSCE, /* o : number of SCEs */ int16_t *nCPE, /* o : number of CPEs */ - int16_t *element_mode, /* o : element mode of the core coder */ + int16_t *element_mode /* o : element mode of the core coder */ +#ifndef HARMONIZE_SBA_NCHAN_TRANSPORT const SBA_MODE sba_mode /* i : SBA mode */ +#endif ); ivas_error ivas_sba_dec_reconfigure( @@ -3033,15 +3049,23 @@ void ivas_init_dec_get_num_cldfb_instances( int16_t *numCldfbSyntheses /* o : number of CLDFB synthesis instances */ ); +/*! r: Ambisonic (SBA) order */ int16_t ivas_sba_get_order( const int16_t nb_channels, /* i : Number of ambisonic channels */ const int16_t sba_planar /* i : SBA planar flag */ ); +/*! r: Ambisonic (SBA) order used for analysis and coding */ +int16_t ivas_sba_get_analysis_order( + const int32_t ivas_total_brate, /* i : IVAS total bitrate */ + const int16_t sba_order /* i : Ambisonic (SBA) order */ +); + int16_t ivas_sba_get_order_transport( const int16_t nchan_transport /* i : Number of transport channels */ ); +/*!r: number of Ambisonic channels */ int16_t ivas_sba_get_nchan( const int16_t sba_order, /* i : Ambisonic (SBA) order */ const int16_t sba_planar /* i : SBA planar flag */ @@ -3161,18 +3185,21 @@ ivas_error ivas_dirac_sba_config( int16_t *element_mode, /* o : element mode of the core coder */ int32_t sba_total_brate, /* i : SBA total bitrate */ const int16_t sba_order, /* i : Ambisonic (SBA) order */ +#ifndef HARMONIZE_SBA_NCHAN_TRANSPORT const int16_t sba_planar, /* i : SBA planar flag */ +#endif const SBA_MODE sba_mode, /* i : SBA mode */ const int16_t nbands /* i : number of frequency bands */ ); +#ifndef HARMONIZE_SBA_NCHAN_TRANSPORT /*! r: number of IVAS transport channels */ int16_t ivas_dirac_getNumTransportChannels( const int32_t sba_total_brate, /* i : SBA total bitrate */ const int16_t sba_order, /* i : SBA order */ const int16_t sba_planar /* i : SBA Planar flag */ ); - +#endif ivas_error ivas_dirac_dec_open( Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ ); @@ -3365,8 +3392,8 @@ void ivas_dirac_dec_output_synthesis_process_subframe_psd_ls( 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 */ DIRAC_DEC_HANDLE hDirAC, /* i/o: DirAC handle */ - float *reference_power_smooth - , float qualityBasedSmFactor + float *reference_power_smooth, + float qualityBasedSmFactor ); void ivas_dirac_dec_get_response( @@ -3717,13 +3744,13 @@ void ivas_spar_config( void ivas_sba_upmixer_renderer( Decoder_Struct *st_ivas, /* i/o: IVAS decoder struct */ float output[][L_FRAME48k], /* i/o: transport/output audio channels */ - const int16_t nchan_remapped, /* i : num channels after remapping of TCs */ const int16_t output_frame /* i : output frame length */ ); void ivas_sba_mix_matrix_determiner( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder struct */ - float in_out[][L_FRAME48k], /* i/o: transport/output audio channels */ + SPAR_DEC_HANDLE hSpar, /* i/o: SPAR decoder handle */ + float output[][L_FRAME48k], /* i/o: transport/output audio channels */ + const int16_t bfi, /* i : BFI flag */ const int16_t nchan_remapped, /* i : num channels after remapping of TCs */ const int16_t output_frame /* i : output frame length */ ); @@ -3815,7 +3842,12 @@ int16_t ivas_get_spar_table_idx( int16_t *ind /* o : indice */ ); +#ifdef HARMONIZE_SBA_NCHAN_TRANSPORT +/*! r: number of transport channels */ +int16_t ivas_get_sba_num_TCs( +#else int16_t ivas_get_spar_num_TCs( +#endif const int32_t ivas_total_brate, /* i : IVAS total bitrate */ const int16_t sba_order /* i : IVAS SBA order */ ); @@ -3865,11 +3897,8 @@ void ivas_spar_dec_upmixer( /* MD module */ ivas_error ivas_spar_md_enc_open( ivas_spar_md_enc_state_t **hMdEnc, /* i/o: SPAR MD encoder handle */ - const ENCODER_CONFIG_HANDLE hEncoderConfig /* i : configuration structure */ -#ifdef SBA_ORDER_BITSTREAM - , - int16_t sba_order -#endif + const ENCODER_CONFIG_HANDLE hEncoderConfig, /* i : configuration structure */ + const int16_t sba_order /* i : Ambisonic (SBA) order */ ); void ivas_spar_md_enc_close( @@ -3881,11 +3910,8 @@ ivas_error ivas_spar_md_enc_process( const ENCODER_CONFIG_HANDLE hEncoderConfig, /* i : configuration structure */ ivas_spar_md_enc_in_buf_t *pIn_buf, BSTR_ENC_HANDLE hMetaData, /* i/o: MetaData handle */ - const int16_t dtx_silence_mode -#ifdef SBA_ORDER_BITSTREAM - , - int16_t sba_order -#endif + const int16_t dtx_silence_mode, + const int16_t sba_order /* i : Ambisonic (SBA) order */ ); void ivas_compute_spar_params( @@ -4242,17 +4268,17 @@ int16_t ivas_map_num_drct_r_to_idx( const int16_t num_quant_points_drct_r ); int16_t ivas_map_num_decd_r_to_idx( const int16_t num_quant_points_decd_r ); /* Quantization utilities */ -void ivas_quantise_real_values( - float **values, - const int16_t q_levels, - const float min_value, - const float max_value, - int16_t **index, - float **quant, - const int16_t dim1, - const int16_t dim2 +void ivas_quantise_real_values( + const float *values, + const int16_t q_levels, + const float min_value, + const float max_value, + int16_t *index, + float *quant, + const int16_t dim ); + void ivas_spar_get_uniform_quant_strat( ivas_spar_md_com_cfg *pSpar_md_com_cfg, const int16_t table_idx @@ -4424,10 +4450,10 @@ void ivas_masa_prerender( void ivas_spar_param_to_masa_param_mapping( Decoder_Struct *st_ivas, /* i/o: IVAS decoder struct */ - float inRe[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i: Input audio in CLDFB domain, real */ - float inIm[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i: Input audio in CLDFB domain, imag */ - const int16_t firstSubframe, /* i: First subframe to map */ - const int16_t nSubframes /* i: Number of subframes to map */ + float inRe[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i : Input audio in CLDFB domain, real */ + float inIm[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* i : Input audio in CLDFB domain, imag */ + const int16_t firstSubframe, /* i : First subframe to map */ + const int16_t nSubframes /* i : Number of subframes to map */ ); @@ -4643,9 +4669,9 @@ void vbap_determine_gains( ); void v_sort_ind( - float *x, /* i/o: Vector to be sorted */ - int16_t *idx, /* o : Original index positions */ - const int16_t len /* i : vector length */ + float *x, /* i/o: Vector to be sorted */ + int16_t *idx, /* o : Original index positions */ + const int16_t len /* i : vector length */ ); /*----------------------------------------------------------------------------------* @@ -4680,7 +4706,7 @@ void ivas_lssetupconversion_process_param_mc( Decoder_Struct *st_ivas, /* i/o: LS setup conversion renderer handle */ float Cldfb_RealBuffer_InOut[MAX_CICP_CHANNELS][PARAM_MC_MAX_NSLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* i/o: LS signals */ float Cldfb_ImagBuffer_InOut[MAX_CICP_CHANNELS][PARAM_MC_MAX_NSLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], /* i/o: LS signals */ - int16_t channel_active[MAX_CICP_CHANNELS] /* i : bitmap indicating which output channels are active */ + int16_t channel_active[MAX_CICP_CHANNELS] /* i : bitmap indicating which output channels are active */ ); @@ -4886,8 +4912,7 @@ void ivas_HRTF_binary_close( TDREND_HRFILT_FiltSet_t **hHrtfTD /* i/o: TD renderer HRTF handle */ ); -/*! r: TD Renderer result code. */ -ivas_error DefaultBSplineModel( +void DefaultBSplineModel( TDREND_HRFILT_FiltSet_t *HrFiltSet_p, /* o : Loaded HR filter set */ const int32_t output_Fs /* i : Output sampling rate */ ); @@ -4900,7 +4925,7 @@ void ivas_td_binaural_close( BINAURAL_TD_OBJECT_RENDERER_HANDLE *hBinRendererTd /* i/o: TD binaural object renderer handle */ ); -ivas_error ObjRenderIVASFrame( +void ObjRenderIVASFrame( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ float output[][L_FRAME48k], /* i/o: SCE channels / Binaural synthesis */ const int16_t output_frame /* i : output frame length */ @@ -4941,46 +4966,50 @@ void TDREND_HRFILT_SetFiltSet( #endif ivas_error TDREND_REND_RenderSourceHRFilt( +#ifdef FIX_I106_TDREND_5MS + TDREND_SRC_t *Src_p, /* i/o: The source to be rendered */ +#else const TDREND_SRC_t *Src_p, /* i/o: The source to be rendered */ +#endif #ifdef TDREND_HRTF_TABLE_METHODS BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ #endif +#ifdef FIX_I106_TDREND_5MS + float output_buf[][L_SPATIAL_SUBFR_48k], /* o : Output buffer */ + const int16_t subframe_length, /* i : Subframe length in use */ +#else float output_buf[][L_FRAME48k], /* o : Output buffer */ const int16_t output_frame, /* i : Output frame length in use */ +#endif const int32_t output_Fs /* i : Output sample rate */ ); /* ----- Object renderer - sources ----- */ -/*! r: TD Renderer result code. */ ivas_error TDREND_MIX_SRC_SetPos( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ const int16_t SrcInd, /* i : Source index */ const float *Vec_p /* i : Position vector */ ); -/*! r: TD Renderer result code. */ ivas_error TDREND_MIX_SRC_SetDir( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ const int16_t SrcInd, /* i : Source index */ const float *Vec_p /* i : Direction vector */ ); -/*! r: TD Renderer result code. */ ivas_error TDREND_MIX_SRC_SetDirAtten( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ const int16_t SrcInd, /* i : Source index */ const TDREND_DirAtten_t *DirAtten_p /* i : Directional attenuation specifier */ ); -/*! r: TD Renderer result code. */ ivas_error TDREND_MIX_SRC_SetPlayState( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ const int16_t SrcInd, /* i : Source index */ const TDREND_PlayStatus_t PlayStatus /* i : Play state */ ); - void TDREND_SRC_REND_UpdateFiltersFromSpatialParams( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ TDREND_SRC_REND_t *SrcRend_p, /* i/o: Source object */ @@ -4988,7 +5017,6 @@ void TDREND_SRC_REND_UpdateFiltersFromSpatialParams( const int32_t output_Fs /* i : Output sample rate */ ); -/*! r: TD Renderer result code. */ ivas_error TDREND_SRC_Alloc( TDREND_SRC_t **Src_pp /* i/o: Source */ ); @@ -5042,7 +5070,6 @@ int16_t TDREND_SPATIAL_EvalOrthonormOrient( /* ----- Object renderer - mix ----- */ -/*! r: TD Renderer result code. */ ivas_error TDREND_MIX_AddSrc( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ int16_t *SrcInd, /* o : Source index */ @@ -5050,19 +5077,16 @@ ivas_error TDREND_MIX_AddSrc( const int32_t output_Fs /* i : Output sampling rate */ ); -/*! r: TD Renderer result code. */ ivas_error TDREND_MIX_SetDistAttenModel( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ const TDREND_DistAttenModel_t DistAttenModel /* i : Distance attenuation model */ ); -/*! r: TD Renderer result code. */ -ivas_error TDREND_MIX_LIST_SetPos( +void TDREND_MIX_LIST_SetPos( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ const float *Pos_p /* i : Listener's position */ ); -/*! r: TD Renderer result code. */ ivas_error TDREND_MIX_LIST_SetOrient( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ const float *FrontVec_p, /* i : Listener's orientation front vector */ @@ -5073,7 +5097,6 @@ void TDREND_MIX_Dealloc( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd /* i/o: TD renderer handle */ ); -/*! r: TD Renderer result code. */ ivas_error TDREND_MIX_Init( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ TDREND_HRFILT_FiltSet_t **hHrtfTD, /* i/o: HRTF data (initialized in case of NULL) */ @@ -5083,24 +5106,25 @@ ivas_error TDREND_MIX_Init( /* ----- Object renderer - sfx ----- */ -/*! r: TD Renderer result code. */ ivas_error TDREND_SFX_SpatBin_Initialize( SFX_SpatBin_t *SfxSpatBin_p, /* i/o: Spatial parameters handle */ const int32_t output_Fs /* i : Output sampling rate */ ); -/*! r: TD Renderer result code. */ -ivas_error TDREND_SFX_SpatBin_SetParams( +void TDREND_SFX_SpatBin_SetParams( SFX_SpatBin_t *SfxSpatBin_p, /* i/o: Spatial parameters struct to be updated */ const SFX_SpatBin_Params_t *NewParam_p, /* i : New parameters struct */ const int32_t output_Fs /* i : Output sample rate */ ); -/*! r: TD Renderer result code. */ -ivas_error TDREND_SFX_SpatBin_Execute_Main( +void TDREND_SFX_SpatBin_Execute_Main( SFX_SpatBin_t *SfxSpatBin_p, /* i/o: Spatial parameters handle */ const float *InBuffer_p, /* i : Input buffer */ +#ifdef FIX_I106_TDREND_5MS + const int16_t subframe_length, /* i : subframe length */ +#else const int16_t output_frame, /* i : frame length */ +#endif float *LeftOutBuffer_p, /* o : Rendered left channel */ float *RightOutBuffer_p, /* o : Rendered right channel */ int16_t *NoOfUsedInputSamples_p, /* o : Number of input samples actually used */ @@ -5449,7 +5473,7 @@ ivas_error ivas_orient_trk_GetTrackedOrientation( float *roll ); -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE void TonalMdctConceal_create_concealment_noise( float concealment_noise[L_FRAME48k], CPE_DEC_HANDLE hCPE, @@ -5458,9 +5482,21 @@ void TonalMdctConceal_create_concealment_noise( const int16_t idchan, const int16_t subframe_idx, const int16_t core, - const int16_t crossfade_gain, + const float crossfade_gain, const TONALMDCTCONC_NOISE_GEN_MODE noise_gen_mode ); + +void TonalMdctConceal_whiten_noise_shape( + Decoder_State *st, + const int16_t L_frame, + const TONALMDCTCONC_NOISE_SHAPE_WHITENING_MODE +); + +int16_t get_igf_startline( + Decoder_State *st, + int16_t L_frame, + int16_t L_frameTCX +); #endif float rand_triangular_signed( @@ -5468,4 +5504,10 @@ float rand_triangular_signed( /* clang-format on */ +#ifdef ALIGN_SID_SIZE +void dtx_read_padding_bits( + DEC_CORE_HANDLE st, + int16_t num_bits ); +#endif + #endif /* IVAS_PROT_H */ diff --git a/lib_com/ivas_rom_com.c b/lib_com/ivas_rom_com.c index e2ba9b8233..4a82259296 100644 --- a/lib_com/ivas_rom_com.c +++ b/lib_com/ivas_rom_com.c @@ -49,7 +49,11 @@ const int32_t ivas_brate_tbl[SIZE_IVAS_BRATE_TBL] = { +#ifdef ALIGN_SID_SIZE + FRAME_NO_DATA, IVAS_SID_5k2, +#else FRAME_NO_DATA, IVAS_SID_4k4, IVAS_SID_5k, +#endif IVAS_13k2, IVAS_16k4, IVAS_24k4, IVAS_32k, IVAS_48k, IVAS_64k, IVAS_80k, IVAS_96k, IVAS_128k, IVAS_160k, IVAS_192k, IVAS_256k, IVAS_384k, IVAS_512k @@ -903,11 +907,11 @@ const ivas_spar_br_table_t ivas_spar_br_table_consts[IVAS_SPAR_BR_TABLE_LEN] = { /* When AGC is ON additional (AGC_BITS_PER_CH+1) bits may be taken from each core-coder channel so minimum core-coder bitrate per channel can be min core-coder bitrates as per the table - AGC_BITS_PER_CH */ - { 24400, 0, 1, FB, 24000, 1, WYXZ, 1, 0, - { { 16400, 14850, 24350 } }, + { 24400, 0, 1, FB, 24000, 1, WYXZ, 1, 0,{ { 16400, 14850, 24350 } }, { { 15, 1, 5, 1 },{ 15, 1, 3, 1 },{ 7, 1, 3, 1 } }, 0, 0, 0 }, - { 32000, 0, 1, FB, 24000, 1, WYXZ, 1, 0,{{ 24000, 20450, 31950 }},{ { 21, 1, 5, 1 },{ 15, 1, 5, 1 },{ 15, 1, 3, 1 } }, 0, 0, 0 }, + { 32000, 0, 1, FB, 24000, 1, WYXZ, 1, 0,{ { 24000, 20450, 31950 } }, + { { 21, 1, 5, 1 },{ 15, 1, 5, 1 },{ 15, 1, 3, 1 } }, 0, 0, 0 }, { 48000, 0, 1, FB, 24000, 2, WYXZ, 0, 0,{ { 24000, 21000, 31950 },{ 16000, 15000, 20400 } }, { { 15, 7, 5, 1 },{ 15, 7, 3, 1 },{ 7, 7, 3, 1 } }, 1, 0, 0 }, @@ -955,8 +959,6 @@ const ivas_spar_br_table_t ivas_spar_br_table_consts[IVAS_SPAR_BR_TABLE_LEN] = { 512000, 0, 3, FB, 24000, 4, WYXZ, 0, 0,{ { 128000, 128000, 128000 },{ 128000, 128000, 128000 },{ 127200, 122550, 128000 },{ 76300, 73550, 128000 } }, // not yet optimized { { 31, 11, 11, 1 },{ 1, 1, 1, 1 },{ 1, 1, 1, 1 } }, 1, 2, 0 }, - - }; const ivas_freq_models_t ivas_arith_pred_r_consts[TOTAL_PRED_QUANT_STRATS_ARITH] = @@ -1136,7 +1138,7 @@ const ivas_freq_models_t ivas_arith_pred_r_consts[TOTAL_PRED_QUANT_STRATS_ARITH] } }; - const ivas_freq_models_t ivas_arith_drct_r_consts[TOTAL_DRCT_QUANT_STRATS] = +const ivas_freq_models_t ivas_arith_drct_r_consts[TOTAL_DRCT_QUANT_STRATS] = { /* entry for 1 quantization points */ { @@ -1223,7 +1225,7 @@ const ivas_freq_models_t ivas_arith_pred_r_consts[TOTAL_PRED_QUANT_STRATS_ARITH] } }; - const ivas_freq_models_t ivas_arith_decd_r_consts[TOTAL_DECD_QUANT_STRATS] = +const ivas_freq_models_t ivas_arith_decd_r_consts[TOTAL_DECD_QUANT_STRATS] = { /* entry for 1 quantization points */ { @@ -2733,7 +2735,7 @@ const uint8_t masa_twodir_bands[IVAS_NUM_ACTIVE_BRATES] = const uint8_t masa_twodir_bands_joined[IVAS_NUM_ACTIVE_BRATES] = { - 0, 0, 0, 0, 0, 2, 2, 3, 4, 6, 8, 9, 12, 18 + 0, 0, 0, 0, 0, 2, 2, 3, 4, 6, 8, 9, 12, MASA_MAXIMUM_TWO_DIR_BANDS }; @@ -3363,7 +3365,8 @@ const float ivas_mdft_coeff_cos_twid_960[IVAS_960_PT_LEN + 1] = 0.00654493796735196f, 0.00490871880799808f, 0.00327248650652671f, 0.00163624544362412f, 0.00000000000000000f }; -const float ivas_mdft_coeff_cos_twid_640[IVAS_640_PT_LEN +1] = + +const float ivas_mdft_coeff_cos_twid_640[IVAS_640_PT_LEN + 1] = { 1.00000000000000f, 0.999996988037278f, 0.999987952167257f, 0.999972892444367f, 0.999951808959328f, 0.999924701839145f, 0.999891571247108f, 0.999852417382795f, @@ -3524,9 +3527,10 @@ const float ivas_mdft_coeff_cos_twid_640[IVAS_640_PT_LEN +1] = 0.0392598157590687f, 0.0368072229413588f, 0.0343544083996823f, 0.0319013869096110f, 0.0294481732479634f, 0.0269947821927155f, 0.0245412285229123f, 0.0220875270185784f, 0.0196336924606283f, 0.0171797396307788f, 0.0147256833114584f, 0.0122715382857199f, - 0.00981731933714973f, 0.00736304124977978f, 0.00490871880799808f, 0.00245436679646048f - ,0.00000000000000000f + 0.00981731933714973f, 0.00736304124977978f, 0.00490871880799808f, 0.00245436679646048f, + 0.00000000000000000f }; + const float ivas_mdft_coeff_cos_twid_320[IVAS_320_PT_LEN + 1] = { 1.00000000000000f, 0.999987952167257f, 0.999951808959328f, 0.999891571247108f, @@ -3608,9 +3612,10 @@ const float ivas_mdft_coeff_cos_twid_320[IVAS_320_PT_LEN + 1] = 0.0784590957278450f, 0.0735645635996675f, 0.0686682588843738f, 0.0637702995616845f, 0.0588708036511890f, 0.0539698892095020f, 0.0490676743274181f, 0.0441642771270675f, 0.0392598157590687f, 0.0343544083996823f, 0.0294481732479634f, 0.0245412285229123f, - 0.0196336924606283f, 0.0147256833114584f, 0.00981731933714973f, 0.00490871880799808f - ,0.0000000000000000f + 0.0196336924606283f, 0.0147256833114584f, 0.00981731933714973f, 0.00490871880799808f, + 0.0000000000000000f }; + const float ivas_mdft_coeff_cos_twid_240[IVAS_240_PT_LEN + 1] = { 1.0000000000f, 0.9999785817f, 0.9999143276f, 0.9998072405f, 0.9996573250f, 0.9994645875f, @@ -3685,6 +3690,7 @@ const float ivas_mdft_coeff_cos_twid_160[IVAS_160_PT_LEN + 1] = 0.0980171403f, 0.0882423705f, 0.0784590957f, 0.0686682589f, 0.0588708037f, 0.0490676743f, 0.0392598158f, 0.0294481732f, 0.0196336925f, 0.0098173193f, 0.000000000f }; + const float ivas_mdft_coeff_cos_twid_80[IVAS_80_PT_LEN + 1] = { 1.0000000000f, 0.9998072405f, 0.9992290362f, 0.9982656102f, 0.9969173337f, 0.9951847267f, @@ -3702,6 +3708,7 @@ const float ivas_mdft_coeff_cos_twid_80[IVAS_80_PT_LEN + 1] = 0.1564344650f, 0.1370123417f, 0.1175373975f, 0.0980171403f, 0.0784590957f, 0.0588708037f, 0.0392598158f, 0.0196336925f, 0.000000000f }; + const float ivas_mdft_coeff_cos_twid_40[IVAS_40_PT_LEN + 1] = { 1.0000000000f, 0.9992290362f, 0.9969173337f, 0.9930684570f, 0.9876883406f, 0.9807852804f, @@ -3712,6 +3719,7 @@ const float ivas_mdft_coeff_cos_twid_40[IVAS_40_PT_LEN + 1] = 0.3826834324f, 0.3461170571f, 0.3090169944f, 0.2714404499f, 0.2334453639f, 0.1950903220f, 0.1564344650f, 0.1175373975f, 0.0784590957f, 0.0392598158f, 0.000000000f }; + const float ivas_sin_twiddle_480[IVAS_480_PT_LEN >> 1] = { -0.000818122995607253f, -0.00736304124977957f, -0.0139076440957708f, -0.0204516511845773f, diff --git a/lib_com/ivas_sba_config.c b/lib_com/ivas_sba_config.c index 28a66df68f..58cd80bc37 100644 --- a/lib_com/ivas_sba_config.c +++ b/lib_com/ivas_sba_config.c @@ -87,8 +87,11 @@ void ivas_sba_config( const int16_t sba_planar, /* i : SBA Planar flag */ int16_t *nSCE, /* o : number of SCEs */ int16_t *nCPE, /* o : number of CPEs */ - int16_t *element_mode, /* o : element mode of the core coder */ - const SBA_MODE sba_mode /* i : SBA mode */ + int16_t *element_mode /* o : element mode of the core coder */ +#ifndef HARMONIZE_SBA_NCHAN_TRANSPORT + , + const SBA_MODE sba_mode /* i : SBA mode */ +#endif ) { if ( ( sba_order < 0 ) && ( nb_channels < 0 ) ) @@ -117,6 +120,9 @@ void ivas_sba_config( if ( nchan_transport != NULL ) { +#ifdef HARMONIZE_SBA_NCHAN_TRANSPORT + *nchan_transport = ivas_get_sba_num_TCs( sba_total_brate, sba_order ); +#else if ( sba_mode == SBA_MODE_SPAR ) { *nchan_transport = ivas_get_spar_num_TCs( sba_total_brate, sba_order ); @@ -125,6 +131,7 @@ void ivas_sba_config( { *nchan_transport = ivas_dirac_getNumTransportChannels( sba_total_brate, sba_order, sba_planar ); } +#endif } /* Configure core coder number of elements*/ @@ -158,6 +165,7 @@ void ivas_sba_config( * Get Ambisonic order from number of ambisonic channels *-------------------------------------------------------------------*/ +/*! r: Ambisonic (SBA) order */ int16_t ivas_sba_get_order( const int16_t nb_channels, /* i : Number of ambisonic channels */ const int16_t sba_planar /* i : SBA Planar flag */ @@ -182,6 +190,32 @@ int16_t ivas_sba_get_order( } +/*-------------------------------------------------------------------* + * ivas_sba_get_analysis_order() + * + * Get Ambisonic order used for analysis and coding + *-------------------------------------------------------------------*/ + +/*! r: Ambisonic (SBA) order used for analysis and coding */ +int16_t ivas_sba_get_analysis_order( + const int32_t ivas_total_brate, /* i : IVAS total bitrate */ + const int16_t sba_order /* i : Ambisonic (SBA) order */ +) +{ + int16_t sba_analysis_order; + + sba_analysis_order = sba_order; + + if ( ivas_total_brate < SBA_MIN_BRATE_HOA ) + { + /* Hard coding the sba_analysis_order as 1 as higher not supported below SBA_MIN_BRATE_HOA bitrate */ + sba_analysis_order = 1; + } + + return sba_analysis_order; +} + + /*-------------------------------------------------------------------* * ivas_sba_get_order_transport() * @@ -215,6 +249,7 @@ int16_t ivas_sba_get_order_transport( * Get number of Ambisonic channels *-------------------------------------------------------------------*/ +/*!r: number of Ambisonic channels */ int16_t ivas_sba_get_nchan( const int16_t sba_order, /* i : Ambisonic (SBA) order */ const int16_t sba_planar /* i : SBA planar flag */ diff --git a/lib_com/ivas_sns_com.c b/lib_com/ivas_sns_com.c index 51f5fcee64..b1555a038b 100644 --- a/lib_com/ivas_sns_com.c +++ b/lib_com/ivas_sns_com.c @@ -37,7 +37,7 @@ #include "ivas_prot.h" #include "rom_com.h" #include -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE #include #endif #ifdef DEBUGGING @@ -45,7 +45,7 @@ #endif #include "wmops.h" -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE /*------------------------------------------------------------------- * sns_compute_scf() diff --git a/lib_com/ivas_spar_com.c b/lib_com/ivas_spar_com.c index 3c908c7980..ce4e742401 100755 --- a/lib_com/ivas_spar_com.c +++ b/lib_com/ivas_spar_com.c @@ -137,23 +137,23 @@ void ivas_get_twid_factors( float ivas_get_mdct_scaling_gain( const int16_t dct_len_by_2 ) { - float result = 0.0f; + float gain = 0.0f; switch ( dct_len_by_2 ) { case L_FRAME48k >> 2: { - result = IVAS_MDCT_SCALING_GAIN_48k; + gain = IVAS_MDCT_SCALING_GAIN_48k; break; } case L_FRAME32k >> 2: { - result = IVAS_MDCT_SCALING_GAIN_32k; + gain = IVAS_MDCT_SCALING_GAIN_32k; break; } case L_FRAME16k >> 2: { - result = IVAS_MDCT_SCALING_GAIN_16k; + gain = IVAS_MDCT_SCALING_GAIN_16k; break; } default: @@ -163,7 +163,7 @@ float ivas_get_mdct_scaling_gain( } } - return result; + return gain; } @@ -311,7 +311,11 @@ void ivas_spar_config( const int16_t sid_format /* i : IVAS format indicator from SID frame */ ) { +#ifdef ALIGN_SID_SIZE + if ( ivas_total_brate == IVAS_SID_5k2 ) +#else if ( ivas_total_brate == IVAS_SID_5k ) +#endif { if ( sid_format == SID_SBA_1TC ) { @@ -324,7 +328,11 @@ void ivas_spar_config( } else { +#ifdef HARMONIZE_SBA_NCHAN_TRANSPORT + *nchan_transport = ivas_get_sba_num_TCs( ivas_total_brate, sba_order ); +#else *nchan_transport = ivas_get_spar_num_TCs( ivas_total_brate, sba_order ); +#endif } *nCPE = ( *nchan_transport > 1 ) ? ( *nchan_transport + 1 ) >> 1 : 0; @@ -333,7 +341,11 @@ void ivas_spar_config( if ( *nchan_transport == 1 ) { /* map SPAR SID bitrate to SPAR active bitrate */ +#ifdef ALIGN_SID_SIZE + if ( ivas_total_brate == IVAS_SID_5k2 ) +#else if ( ivas_total_brate == IVAS_SID_5k ) +#endif { ivas_total_brate = IVAS_32k; } @@ -408,6 +420,16 @@ int16_t ivas_get_spar_table_idx( } +#ifdef HARMONIZE_SBA_NCHAN_TRANSPORT +/*-------------------------------------------------------------------* + * ivas_get_sba_num_TCs() + * + * Return number of TCs in SBA format + *-------------------------------------------------------------------*/ + +/*! r: number of transport channels */ +int16_t ivas_get_sba_num_TCs( +#else /*-------------------------------------------------------------------* * ivas_get_spar_num_TCs() * @@ -416,16 +438,27 @@ int16_t ivas_get_spar_table_idx( /*! r: number of transport channels */ int16_t ivas_get_spar_num_TCs( +#endif const int32_t ivas_total_brate, /* i : IVAS total bitrate */ const int16_t sba_order /* i : Ambisonic (SBA) order */ ) { int16_t table_idx, nchan_transport; +#ifdef ALIGN_SID_SIZE + if ( ivas_total_brate == IVAS_SID_5k2 ) +#else if ( ivas_total_brate == IVAS_SID_5k ) +#endif { nchan_transport = 1; } +#ifdef HARMONIZE_SBA_NCHAN_TRANSPORT + else if ( ivas_sba_mode_select( ivas_total_brate ) == SBA_MODE_DIRAC ) + { + nchan_transport = 1; + } +#endif else { table_idx = ivas_get_spar_table_idx( ivas_total_brate, sba_order, SPAR_CONFIG_BW, NULL, NULL ); diff --git a/lib_com/ivas_spar_com_quant_util.c b/lib_com/ivas_spar_com_quant_util.c index 9b0a936018..c095e20107 100644 --- a/lib_com/ivas_spar_com_quant_util.c +++ b/lib_com/ivas_spar_com_quant_util.c @@ -42,90 +42,49 @@ #include #include "wmops.h" -/*-----------------------------------------------------------------------------------------* - * Function ivas_limit_values() - * - * Limit values within given range - *-----------------------------------------------------------------------------------------*/ - -static void ivas_limit_values( - float **ppValues, - const float min_value, - const float max_value, - const int16_t dim1, - const int16_t dim2 ) -{ - int16_t i, j; - - for ( i = 0; i < dim1; i++ ) - { - for ( j = 0; j < dim2; j++ ) - { - ppValues[i][j] = max( min_value, min( ppValues[i][j], max_value ) ); - } - } - - return; -} - - /*-----------------------------------------------------------------------------------------* * Function ivas_quantise_real_values() * * Quantize real values *-----------------------------------------------------------------------------------------*/ - void ivas_quantise_real_values( - float **values, + const float *values, const int16_t q_levels, const float min_value, const float max_value, - int16_t **index, - float **quant, - const int16_t dim1, - const int16_t dim2 ) + int16_t *index, + float *quant, + const int16_t dim ) { - int16_t i, j; + int16_t i; float q_step, one_by_q_step; - if ( q_levels == 1 ) { - for ( i = 0; i < dim1; i++ ) + for ( i = 0; i < dim; i++ ) { - for ( j = 0; j < dim2; j++ ) - { - quant[i][j] = 0; - index[i][j] = 0; - } + quant[i] = 0; + index[i] = 0; } } else if ( q_levels && max_value != min_value ) { - ivas_limit_values( values, min_value, max_value, dim1, dim2 ); - q_step = ( max_value - min_value ) / ( q_levels - 1 ); one_by_q_step = ( q_levels - 1 ) / ( max_value - min_value ); - - for ( i = 0; i < dim1; i++ ) + float val; + for ( i = 0; i < dim; i++ ) { - for ( j = 0; j < dim2; j++ ) - { - index[i][j] = (int16_t) round( one_by_q_step * values[i][j] ); - quant[i][j] = index[i][j] * q_step; - } + val = max( min_value, min( values[i], max_value ) ); + index[i] = (int16_t) round( one_by_q_step * val ); + quant[i] = index[i] * q_step; } } else { - for ( i = 0; i < dim1; i++ ) + for ( i = 0; i < dim; i++ ) { - for ( j = 0; j < dim2; j++ ) - { - quant[i][j] = values[i][j]; - } + quant[i] = values[i]; } } - return; } @@ -259,7 +218,7 @@ void ivas_map_prior_coeffs_quant( /*-----------------------------------------------------------------------------------------* * Function ivas_spar_quant_dtx_init() * - * Init spar md with minmax vals + * Init SPAR MD with minmax vals *-----------------------------------------------------------------------------------------*/ void ivas_spar_quant_dtx_init( @@ -347,7 +306,7 @@ void ivas_copy_band_coeffs_idx_to_arr( /*-----------------------------------------------------------------------------------------* * Function ivas_clear_band_coeffs() * - * clear band coeffs array in spar MD + * clear band coeffs array in SPAR MD *-----------------------------------------------------------------------------------------*/ void ivas_clear_band_coeffs( @@ -374,7 +333,7 @@ void ivas_clear_band_coeffs( /*-----------------------------------------------------------------------------------------* * Function ivas_clear_band_coeff_idx() * - * clear band coeffs index array in spar MD + * clear band coeffs index array in SPAR MD *-----------------------------------------------------------------------------------------*/ void ivas_clear_band_coeff_idx( @@ -386,7 +345,6 @@ void ivas_clear_band_coeff_idx( for ( i = 0; i < num_bands; i++ ) { set_s( pband_coeff_idx[i].pred_index_re, 0, ( IVAS_SPAR_MAX_CH - 1 ) ); - set_s( pband_coeff_idx[i].drct_index_re, 0, IVAS_SPAR_MAX_C_COEFF ); set_s( pband_coeff_idx[i].decd_index_re, 0, ( IVAS_SPAR_MAX_CH - 1 ) ); } diff --git a/lib_com/ivas_stat_com.h b/lib_com/ivas_stat_com.h index 8c54421f04..e19d30dc71 100644 --- a/lib_com/ivas_stat_com.h +++ b/lib_com/ivas_stat_com.h @@ -692,8 +692,8 @@ typedef struct ivas_fb_bin_to_band_data_t float *pFb_bin_to_band[IVAS_MAX_NUM_FB_BANDS]; const int16_t *pFb_start_bin_per_band; const int16_t *pFb_active_bins_per_band; - float pp_cldfb_weights_per_spar_band[CLDFB_NO_CHANNELS_MAX][IVAS_MAX_NUM_FB_BANDS]; /* weights for linear combination of parameters from different spar bands*/ - int16_t p_spar_start_bands[CLDFB_NO_CHANNELS_MAX]; /* the first spar band per CLFB band when the weight is > 0 */ + float pp_cldfb_weights_per_spar_band[CLDFB_NO_CHANNELS_MAX][IVAS_MAX_NUM_FB_BANDS]; /* weights for linear combination of parameters from different SPAR bands*/ + int16_t p_spar_start_bands[CLDFB_NO_CHANNELS_MAX]; /* the first SPAR band per CLFB band when the weight is > 0 */ int16_t p_cldfb_map_to_spar_band[CLDFB_NO_CHANNELS_MAX]; /* a direct mapping from CLDFB band to SPAR band */ int16_t p_short_stride_start_bin_per_band[IVAS_MAX_NUM_FB_BANDS]; int16_t p_short_stride_num_bins_per_band[IVAS_MAX_NUM_FB_BANDS]; diff --git a/lib_com/ivas_stereo_dft_com.c b/lib_com/ivas_stereo_dft_com.c index 918fd27b35..7de3144f63 100644 --- a/lib_com/ivas_stereo_dft_com.c +++ b/lib_com/ivas_stereo_dft_com.c @@ -82,7 +82,11 @@ void stereo_dft_config( hConfig->res_cod_mode = STEREO_DFT_RES_COD_OFF; } } +#ifdef ALIGN_SID_SIZE + else if ( brate == IVAS_SID_5k2 ) +#else else if ( brate == IVAS_SID_4k4 ) +#endif { *bits_frame_nominal = SID_2k40 / FRAMES_PER_SEC; if ( hConfig != NULL ) diff --git a/lib_com/ivas_stereo_mdct_stereo_com.c b/lib_com/ivas_stereo_mdct_stereo_com.c index 73cd2fd579..cbb1423cd1 100644 --- a/lib_com/ivas_stereo_mdct_stereo_com.c +++ b/lib_com/ivas_stereo_mdct_stereo_com.c @@ -46,7 +46,7 @@ void splitAvailableBits( const int16_t total_bits, /* i : total available bits for TCX coding */ const int16_t split_ratio, /* i : split ratio */ - const int16_t isSBAStereoMode, /* i : signal core coding for sba */ + const int16_t isSBAStereoMode, /* i : signal core coding for SBA */ int16_t *bits_ch0, /* o : bits for channel 0 */ int16_t *bits_ch1 /* o : bits for channel 1 */ ) diff --git a/lib_com/ivas_stereo_psychlpc_com.c b/lib_com/ivas_stereo_psychlpc_com.c index 7093a91093..4ca10255a7 100644 --- a/lib_com/ivas_stereo_psychlpc_com.c +++ b/lib_com/ivas_stereo_psychlpc_com.c @@ -68,11 +68,10 @@ static void SpectrumWeighting_Init( * initialize a PsychoacousticParameters structure *-------------------------------------------------------------------*/ -#ifndef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifndef MDCT_STEREO_PLC_FADE_2_BG_NOISE static #endif - ivas_error - PsychoacousticParameters_Init( +ivas_error PsychoacousticParameters_Init( const int32_t sr_core, /* i : sampling rate of core-coder */ const int16_t nBins, /* i : Number of bins (spectral lines) */ const int8_t nBands, /* i : Number of spectrum subbands */ diff --git a/lib_com/ivas_tools.c b/lib_com/ivas_tools.c index 079af159bc..6b0c0eb297 100644 --- a/lib_com/ivas_tools.c +++ b/lib_com/ivas_tools.c @@ -1172,8 +1172,12 @@ int16_t is_SIDrate( if ( ( ivas_total_brate == SID_1k75 ) || ( ivas_total_brate == SID_2k40 ) || +#ifdef ALIGN_SID_SIZE + ( ivas_total_brate == IVAS_SID_5k2 ) ) +#else ( ivas_total_brate == IVAS_SID_4k4 ) || ( ivas_total_brate == IVAS_SID_5k ) ) +#endif { sid_rate_flag = 1; } diff --git a/lib_com/options.h b/lib_com/options.h index 054eca6526..e3ead5c21a 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -141,24 +141,23 @@ #endif #define DISABLE_ADAP_RES_COD_TMP /* temporary fix for IVAS-403, disables adaptive residual coding */ /*#define ITD_WINNER_GAIN_MODIFY */ /* ITD optimization - WORK IN PROGRESS */ - /*#define FIX_I4_OL_PITCH*/ /* fix open-loop pitch used for EVS core switching */ -/*#define FIX_IVAS_185_MDCT_ST_PLC_FADEOUT*/ /* IVAS-185 fix bug in TCX-PLC fadeout for MDCT-Stereo and improve fadeout by fading to background noise instead of white noise */ +#define MDCT_STEREO_PLC_FADE_2_BG_NOISE /* IVAS-185 fix bug in TCX-PLC fadeout for MDCT-Stereo and improve fadeout by fading to background noise instead of white noise */ +#define FADE_TO_ZERO_FOR_TOO_LONG_FRAMELOSS /*#define FIX_I1_113*/ /* under review : MCT bit distribution optimization for SBA high bitrates*/ +#define FIX_I106_TDREND_5MS /* Issue 106: 5 ms update rate in TD object renderer */ +#define ALIGN_SID_SIZE /* Issue 111: make all DTX modes use one SID frame bitrate (5.2 kbps) */ +#define FIX_135_MDCT_STEREO_MODE_UNINITIALIZED /* Issue 135: fix uninitialized value usage in SBA MDCT-Stereo core with PLC */ +#define FIX_CONTROLLABLE_SID_UPDATE_RATE /* Issue 117: fix controllable SID update rate mechanism */ +#define FIX_DIRAC_CHANNELS /* Issue 71: lower number of DirAC analysis channels */ +#define FIX_CREND_CHANNELS /* Issue 71: fix number of Crend channels */ +#define HARMONIZE_SBA_NCHAN_TRANSPORT /* harmonize setting of number of transport channels in SBA */ +#define DRAM_REDUCTION_MCT_IGF /* Issue 121: reduce dynamic RAM consumption in MCT IGF */ + #define EXT_RENDERER /* FhG: external renderer library and standalone application */ #define FIX_EFAP_MATH /* fix for EFAP: remove angle quantization and a bug in polygon lookup causing incorrect gains. minor tweak for ALLRAD. non-BE for modes using EFAP */ - -#define FIX_WRONG_NBANDS_IN_ITD_ESTIMATION /* Issue 85: fix incorrect setting of nbands in calc_mean_E_ratio() if bwidth is limited on commandline*/ - -#define FIX_I87 /* fix for issue 86: incorrect Ambisonics order set for head rotation in SBA */ -#define SBA_ORDER_BITSTREAM /* issue 76: Use input sba order for bitstream coding */ - -/* NTT switches */ -#define NTT_UPDATE_ITD_SW /* contribution 4: Update of ITD switch in stereo downmix for EVS */ -#define NTT_REMOVE_EPS_ROM /* contribution 4: Reduction of ROM size in stereo downmix for EVS */ - /* ################## End DEVELOPMENT switches ######################### */ /* clang-format on */ #endif diff --git a/lib_com/prot.h b/lib_com/prot.h index d9b238bdf0..86e9e172e3 100644 --- a/lib_com/prot.h +++ b/lib_com/prot.h @@ -2773,13 +2773,11 @@ void fb_tbe_enc( ); void fb_tbe_dec( - Decoder_State *st, /* i/o: decoder state structure */ - const float fb_exc[], /* i : FB excitation from the SWB part */ - float *hb_synth, /* i/o: high-band synthesis */ - float *fb_synth_ref /* o : high-band synthesis 16-20 kHz */ - , - const int16_t output_frame /* i: output frame length */ - + Decoder_State *st, /* i/o: decoder state structure */ + const float fb_exc[], /* i : FB excitation from the SWB part */ + float *hb_synth, /* i/o: high-band synthesis */ + float *fb_synth_ref, /* o : high-band synthesis 16-20 kHz */ + const int16_t output_frame /* i : output frame length */ ); void calc_tilt_bwe( @@ -5147,7 +5145,7 @@ void decod_amr_wb( ivas_error init_decoder( Decoder_State *st, /* o : Decoder static variables structure */ const int16_t idchan /* i : channel ID */ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE , const MC_MODE mc_mode /* i : MC mode */ #endif @@ -6778,7 +6776,7 @@ void enc_acelp_tcx_main( void getTCXMode( Decoder_State *st, /* i/o: decoder memory state */ Decoder_State *st0 /* i : bitstream */ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE , const int16_t MCT_flag #endif @@ -7183,7 +7181,7 @@ void WindowSignal( float out[], /* o : output windowed signal */ const int16_t truncate_aldo, /* i : nonzero to truncate long ALDO slope */ const int16_t fullband, /* i : fullband flag */ - const int16_t isLfe /* i: LFE flag */ + const int16_t isLfe /* i : LFE flag */ ); void HBAutocorrelation( @@ -7398,13 +7396,17 @@ void ProcessStereoIGF( Encoder_State *sts[CPE_CHANNELS], /* i : Encoder state */ int16_t ms_mask[2][MAX_SFB], /* i : bandwise MS mask */ float *pITFMDCTSpectrum[CPE_CHANNELS][2], /* i : MDCT spectrum fir ITF */ +#ifdef DRAM_REDUCTION_MCT_IGF + float *pPowerSpectrum[CPE_CHANNELS], /* i/o: MDCT^2 + MDST^2 spectrum, or estimate */ +#else float pPowerSpectrum[CPE_CHANNELS][N_MAX], /* i : MDCT^2 + MDST^2 spectrum, or estimate */ +#endif float *pPowerSpectrumMsInv[CPE_CHANNELS][2], /* i : inverse power spectrum */ float *inv_spectrum[CPE_CHANNELS][2], /* i : inverse spectrum */ const int16_t frameno, /* i : flag indicating index of current subframe*/ const int16_t sp_aud_decision0, /* i : sp_aud_decision0 */ const int32_t element_brate, /* i : element bitrate */ - const int16_t mct_on /* i : flag mct block (1) or stereo (0) */ + const int16_t mct_on /* i : flag mct block (1) or stereo (0) */ ); void AnalyzePowerSpectrum( @@ -7895,7 +7897,7 @@ void decoder_tcx_post( float *synthFB, float *A, const int16_t bfi -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE , const int16_t isMCT #endif @@ -7951,7 +7953,7 @@ void decoder_acelp( void writeTCXMode( Encoder_State *st, /* i/o: encoder state structure */ BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE const int16_t is_mct, #endif int16_t *nbits_start /* o : nbits start */ @@ -8142,7 +8144,7 @@ void con_tcx( const float coh, /* i : coherence of stereo signal */ int16_t *noise_seed, /* i/o: noise seed for stereo */ const int16_t only_left /* i : TD-PLC only in left channel */ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE , const float *A_cng #endif @@ -8691,7 +8693,7 @@ void configureFdCngDec( void ApplyFdCng( float *timeDomainInput, -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE float *powerSpectrum, #endif float **realBuffer, /* i/o: Real part of the buffer */ @@ -8702,7 +8704,7 @@ void ApplyFdCng( void perform_noise_estimation_dec( const float *timeDomainInput, -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE float *power_spectrum, #endif HANDLE_FD_CNG_DEC hFdCngDec, /* i/o: FD_CNG structure */ @@ -9204,7 +9206,7 @@ void open_decoder_LPD( const int32_t last_total_brate, /* i : last total bitrate */ const int16_t bwidth, /* i : audio bandwidth */ const int16_t is_mct, /* i : MCT mode flag */ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE const int16_t last_element_mode, #endif const int16_t is_init /* i : indicate call during initialization */ @@ -9247,9 +9249,9 @@ void mode_switch_decoder_LPD( const int32_t last_total_brate, /* i : last frame total bitrate */ const int16_t frame_size_index, /* i : index determining the frame size*/ const int16_t is_mct /* i : MCT mode flag */ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE , - const int16_t last_element_mode + const int16_t last_element_mode /* i : last element mode */ #endif ); @@ -9531,7 +9533,7 @@ void TonalMDCTConceal_SaveFreqSignal( const uint16_t numSamples, const uint16_t nNewSamplesCore, const float *scaleFactors -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE , const int16_t infoIGFStartLine #endif @@ -9569,8 +9571,9 @@ void TonalMDCTConceal_InsertNoise( int16_t *pSeed, /*IN/OUT*/ const float tiltCompFactor, const float crossfadeGain, -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE const float concealment_noise[L_FRAME48k], + const float cngLevelBackgroundTrace_bfi, #endif const int16_t crossOverFreq ); @@ -9606,7 +9609,7 @@ void RefineTonalComponents( float floorPowerSpectrum, const PsychoacousticParameters *psychParamsCurrent ); -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE ivas_error PsychoacousticParameters_Init( const int32_t sr_core, /* i : sampling rate of core-coder */ const int16_t nBins, /* i : Number of bins (spectral lines) */ @@ -9795,7 +9798,11 @@ void IGFEncApplyStereo( const IGF_ENC_INSTANCE_HANDLE hIGFEnc[CPE_CHANNELS], /* i : instance handle of IGF Encoder */ const int16_t igfGridIdx, /* i : IGF grid index */ Encoder_State *sts[CPE_CHANNELS], /* i : Encoder state */ +#ifdef DRAM_REDUCTION_MCT_IGF + float *pPowerSpectrum[CPE_CHANNELS], /* i/o: MDCT^2 + MDST^2 spectrum, or estimate */ +#else float pPowerSpectrum[CPE_CHANNELS][N_MAX], /* i/o: MDCT^2 + MDST^2 spectrum, or estimate */ +#endif float *pPowerSpectrumMsInv[CPE_CHANNELS][2], /* i/o: inverse power spectrum */ float *inv_spectrum[CPE_CHANNELS][2], /* i : inverse spectrum */ const int16_t frameno, /* i : flag indicating index of current subframe */ diff --git a/lib_dec/acelp_core_dec.c b/lib_dec/acelp_core_dec.c index 7951f10d54..684c12b57e 100755 --- a/lib_dec/acelp_core_dec.c +++ b/lib_dec/acelp_core_dec.c @@ -125,7 +125,11 @@ ivas_error acelp_core_dec( error = IVAS_ERR_OK; +#ifdef ALIGN_SID_SIZE + if ( st->element_mode == IVAS_CPE_MDCT && nchan_out == 1 && st->idchan == 1 && last_element_brate <= IVAS_SID_5k2 ) +#else if ( st->element_mode == IVAS_CPE_MDCT && nchan_out == 1 && st->idchan == 1 && last_element_brate <= IVAS_SID_4k4 ) +#endif { /* In MDCT-Stereo DTX with mono output, we can skip CNG for the second channel, except for the first inactive frame following an active period */ return error; @@ -156,7 +160,7 @@ ivas_error acelp_core_dec( st->hFdCngDec->hFdCngCom->sidNoiseEstLp[i] = STEREO_DFT_FD_FILT * st->hFdCngDec->hFdCngCom->sidNoiseEstLp[i] + ( 1 - STEREO_DFT_FD_FILT ) * st->hFdCngDec->hFdCngCom->sidNoiseEst[i]; } -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE ApplyFdCng( NULL, NULL, NULL, NULL, st, 0, 0 ); #else ApplyFdCng( NULL, NULL, NULL, st, 0, 0 ); @@ -530,7 +534,7 @@ ivas_error acelp_core_dec( { st->hFdCngDec->hFdCngCom->sidNoiseEstLp[i] = STEREO_DFT_FD_FILT * st->hFdCngDec->hFdCngCom->sidNoiseEstLp[i] + ( 1 - STEREO_DFT_FD_FILT ) * st->hFdCngDec->hFdCngCom->sidNoiseEst[i]; } -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE ApplyFdCng( syn, NULL, realBuffer, imagBuffer, st, 0, ( st->coder_type == AUDIO && !st->GSC_noisy_speech ) ); #else ApplyFdCng( syn, realBuffer, imagBuffer, st, 0, ( st->coder_type == AUDIO && !st->GSC_noisy_speech ) ); @@ -1119,7 +1123,7 @@ ivas_error acelp_core_dec( if ( st->element_mode != IVAS_CPE_TD ) { /*Noise estimate*/ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE ApplyFdCng( syn, NULL, realBuffer, imagBuffer, st, 0, ( st->coder_type == AUDIO && !st->GSC_noisy_speech ) ); #else ApplyFdCng( syn, realBuffer, imagBuffer, st, 0, ( st->coder_type == AUDIO && !st->GSC_noisy_speech ) ); @@ -1188,7 +1192,7 @@ ivas_error acelp_core_dec( /*Noise estimate*/ if ( st->idchan == 0 && ( nchan_out == 2 || ( st->core_brate != FRAME_NO_DATA && st->core_brate != SID_2k40 ) ) ) { -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE ApplyFdCng( syn, NULL, realBuffer, imagBuffer, st, 0, ( st->coder_type == AUDIO && !st->GSC_noisy_speech ) ); #else ApplyFdCng( syn, realBuffer, imagBuffer, st, 0, ( st->coder_type == AUDIO && !st->GSC_noisy_speech ) ); diff --git a/lib_dec/acelp_core_switch_dec.c b/lib_dec/acelp_core_switch_dec.c index 9daac37b74..98854527e6 100644 --- a/lib_dec/acelp_core_switch_dec.c +++ b/lib_dec/acelp_core_switch_dec.c @@ -534,7 +534,7 @@ ivas_error acelp_core_switch_dec_bfi( /*-------------------------------------------------------------------* * decod_gen_voic_core_switch() * - * Decode excitation signal in teh first ACELP->HQ switching frame + * Decode excitation signal in the first ACELP->HQ switching frame *-------------------------------------------------------------------*/ static void decod_gen_voic_core_switch( diff --git a/lib_dec/amr_wb_dec.c b/lib_dec/amr_wb_dec.c index c220c8201e..907d90e9ab 100644 --- a/lib_dec/amr_wb_dec.c +++ b/lib_dec/amr_wb_dec.c @@ -621,7 +621,7 @@ ivas_error amr_wb_dec( /*VAD only for non inactive frame*/ st->VAD = ( st->VAD && ( st->coder_type != INACTIVE ) ); -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE ApplyFdCng( syn, NULL, NULL, NULL, st, 0, 0 ); #else ApplyFdCng( syn, NULL, NULL, st, 0, 0 ); diff --git a/lib_dec/core_dec_init.c b/lib_dec/core_dec_init.c index d2d94799ef..bc8d95e24f 100644 --- a/lib_dec/core_dec_init.c +++ b/lib_dec/core_dec_init.c @@ -57,7 +57,7 @@ void open_decoder_LPD( const int32_t last_total_brate, const int16_t bwidth, const int16_t is_mct, /* i : MCT mode flag */ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE const int16_t last_element_mode, #endif const int16_t is_init /* i : indicate call from init_decoder() to avoid double TC initialization */ @@ -552,9 +552,8 @@ void open_decoder_LPD( { st->hTcxDec->prev_widow_left_rect = 0; -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT - /* Todo: should be considered for other stereo modes as well */ - if ( is_init || !( st->element_mode == IVAS_CPE_MDCT && st->element_mode == last_element_mode ) ) +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE + if ( is_init || is_mct || !( st->element_mode == IVAS_CPE_MDCT && st->element_mode == last_element_mode ) ) { st->hTcxDec->CngLevelBackgroundTrace_bfi = PLC_MIN_CNG_LEV; st->hTcxDec->NoiseLevelIndex_bfi = PLC_MIN_STAT_BUFF_SIZE - 1; diff --git a/lib_dec/core_dec_switch.c b/lib_dec/core_dec_switch.c index 637c185f32..c2084f3f12 100644 --- a/lib_dec/core_dec_switch.c +++ b/lib_dec/core_dec_switch.c @@ -57,9 +57,9 @@ void mode_switch_decoder_LPD( const int32_t last_total_brate, /* i : last frame total bitrate */ const int16_t frame_size_index, /* i : index determining the frame size*/ const int16_t is_mct /* i : MCT mode flag */ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE , - const int16_t last_element_mode + const int16_t last_element_mode /* i : last element mode */ #endif ) { @@ -109,7 +109,7 @@ void mode_switch_decoder_LPD( if ( fscale != st->fscale || switchWB || bSwitchFromAmrwbIO || st->last_codec_mode == MODE1 || st->force_lpd_reset ) { -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE open_decoder_LPD( st, total_brate, last_total_brate, bwidth, is_mct, last_element_mode, 0 ); #else open_decoder_LPD( st, total_brate, last_total_brate, bwidth, is_mct, 0 ); diff --git a/lib_dec/core_switching_dec.c b/lib_dec/core_switching_dec.c index 61537f76e3..e8c74bc2ef 100644 --- a/lib_dec/core_switching_dec.c +++ b/lib_dec/core_switching_dec.c @@ -1048,7 +1048,11 @@ void bw_switching_pre_proc( if ( st->element_mode > EVS_MONO ) { +#ifdef ALIGN_SID_SIZE + if ( st->core == ACELP_CORE && !( st->bfi == 1 && st->con_tcx == 1 ) && st->hBWE_FD != NULL && !( st->core_brate <= SID_2k40 && st->element_mode == IVAS_CPE_DFT && nchan_out == 2 ) && !( st->element_mode == IVAS_CPE_MDCT && nchan_out == 1 && st->idchan == 1 && last_element_brate <= IVAS_SID_5k2 ) ) +#else if ( st->core == ACELP_CORE && !( st->bfi == 1 && st->con_tcx == 1 ) && st->hBWE_FD != NULL && !( st->core_brate <= SID_2k40 && st->element_mode == IVAS_CPE_DFT && nchan_out == 2 ) && !( st->element_mode == IVAS_CPE_MDCT && nchan_out == 1 && st->idchan == 1 && last_element_brate <= IVAS_SID_4k4 ) ) +#endif { /* Calculate tilt of the ACELP core synthesis - needed in SWB BWE decoding */ calc_tilt_bwe( old_syn_12k8_16k, &st->tilt_wb, st->L_frame ); diff --git a/lib_dec/dec_LPD.c b/lib_dec/dec_LPD.c index 422104ac43..a28630886e 100644 --- a/lib_dec/dec_LPD.c +++ b/lib_dec/dec_LPD.c @@ -478,7 +478,7 @@ void decoder_LPD( if ( bfi && st->last_core != ACELP_CORE ) { /* PLC: [TCX: TD PLC] */ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE con_tcx( st, &synthFB[0], -1.f, NULL, 0, NULL ); #else con_tcx( st, &synthFB[0], -1.f, NULL, 0 ); @@ -650,7 +650,7 @@ void decoder_LPD( TonalMDCTConceal_SaveTimeSignal( st->hTonalMDCTConc, synthFB, L_frameTCX ); } -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE decoder_tcx_post( st, synth, synthFB, Aq, bfi, 0 ); #else decoder_tcx_post( st, synth, synthFB, Aq, bfi ); diff --git a/lib_dec/dec_acelp_tcx_main.c b/lib_dec/dec_acelp_tcx_main.c index b1bfd3e225..1ca75fff20 100644 --- a/lib_dec/dec_acelp_tcx_main.c +++ b/lib_dec/dec_acelp_tcx_main.c @@ -198,7 +198,7 @@ static void decode_frame_type( st->rate_switching_init = 1; /* Reconf Core */ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE mode_switch_decoder_LPD( st, st->bwidth, st->total_brate, st->last_total_brate, frame_size_index, 0, st->element_mode ); #else mode_switch_decoder_LPD( st, st->bwidth, st->total_brate, st->last_total_brate, frame_size_index, 0 ); diff --git a/lib_dec/dec_prm.c b/lib_dec/dec_prm.c index 37c64f18a3..925b561fd6 100644 --- a/lib_dec/dec_prm.c +++ b/lib_dec/dec_prm.c @@ -55,7 +55,7 @@ void getTCXMode( Decoder_State *st, /* i/o: decoder memory state */ Decoder_State *st0 /* i : bitstream */ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE , const int16_t MCT_flag #endif @@ -94,7 +94,7 @@ void getTCXMode( } st->coder_type = INACTIVE; -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE if ( st->element_mode == IVAS_CPE_MDCT && !MCT_flag ) { st->VAD = get_next_indice( st0, 1 ); @@ -793,7 +793,7 @@ void dec_prm( *--------------------------------------------------------------------------------*/ /* Modes (ACE_GC, ACE_UC, TCX20, TCX10...) */ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE getTCXMode( st, st, 0 /* <- MCT_flag */ ); #else getTCXMode( st, st ); diff --git a/lib_dec/dec_tcx.c b/lib_dec/dec_tcx.c index ae5faa4d73..502433517e 100644 --- a/lib_dec/dec_tcx.c +++ b/lib_dec/dec_tcx.c @@ -98,13 +98,9 @@ void decoder_tcx( init_tcx_info( st, L_frame_glob, L_frameTCX_glob, frame_cnt, bfi, &tcx_offset, &tcx_offsetFB, &L_frame, &L_frameTCX, &left_rect, &L_spec ); -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT - decoder_tcx_invQ( st, prm, A, Aind, L_spec, L_frame, L_frameTCX, &x[0], &gainlpc2[0], &xn_buf[0], &fUseTns, &tnsData, &gain_tcx, &prm_sqQ, &nf_seed, bfi, 0, /* <- isMCT */ frame_cnt ); -#else decoder_tcx_invQ( st, prm, A, Aind, L_spec, L_frame, L_frameTCX, &x[0], &gainlpc2[0], &xn_buf[0], &fUseTns, &tnsData, &gain_tcx, &prm_sqQ, &nf_seed, bfi, frame_cnt ); -#endif -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE decoder_tcx_noisefilling( st, NULL, A, L_frameTCX_glob, L_spec, L_frame, L_frameTCX, &x[0], &gainlpc2[0], &tmp_concealment_method, gain_tcx, prm_sqQ, nf_seed, bfi, 0, frame_cnt ); #else decoder_tcx_noisefilling( st, A, L_frameTCX_glob, L_spec, L_frame, L_frameTCX, &x[0], &gainlpc2[0], &tmp_concealment_method, gain_tcx, prm_sqQ, nf_seed, bfi, frame_cnt ); @@ -133,7 +129,7 @@ void decoder_tcx_post( float *synthFB, float *A, const int16_t bfi -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE , const int16_t isMCT #endif @@ -188,7 +184,7 @@ void decoder_tcx_post( /* PLC: [TCX: Fade-out] * PLC: update or retrieve the background level */ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE if ( bfi == 0 && st->tcxonly && ( st->element_mode != IVAS_CPE_MDCT || isMCT ) && st->clas_dec == UNVOICED_CLAS ) #else if ( bfi == 0 && st->tcxonly && st->clas_dec == UNVOICED_CLAS ) @@ -206,6 +202,20 @@ void decoder_tcx_post( if ( st->tcxonly ) { gainCNG = hTcxDec->CngLevelBackgroundTrace_bfi / ( level_syn + 0.01f ); +#ifdef FADE_TO_ZERO_FOR_TOO_LONG_FRAMELOSS + + if ( st->element_mode == IVAS_CPE_MDCT && ! isMCT ) + { + if ( st->nbLostCmpt > MDCT_ST_PLC_FADEOUT_MAX_CONC_FRAME + MDCT_ST_PLC_FADEOUT_TO_ZERO_LEN ) + { + gainCNG = 0.f; + } + else if ( st->nbLostCmpt > MDCT_ST_PLC_FADEOUT_MAX_CONC_FRAME ) + { + gainCNG *= 1.f - (float) ( st->nbLostCmpt - MDCT_ST_PLC_FADEOUT_MAX_CONC_FRAME ) / MDCT_ST_PLC_FADEOUT_TO_ZERO_LEN; + } + } +#endif } else { @@ -696,9 +706,6 @@ void decoder_tcx_invQ( const int16_t **prm_sqQ1, int16_t *nf_seed, const int16_t bfi, /* i : Bad frame indicator */ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT - const int16_t isMCT, -#endif const int16_t frame_cnt /* i : frame counter in the super frame */ ) { @@ -913,16 +920,7 @@ void decoder_tcx_invQ( hTcxDec->damping = 1; } -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT - else if ( st->element_mode == IVAS_CPE_MDCT && st->nbLostCmpt >= MDCT_ST_PLC_FADEOUT_START_FRAME ) - { - *gain_tcx = hTcxDec->old_gaintcx_bfi; - hTcxDec->damping = Damping_fact( st->coder_type, st->nbLostCmpt - MDCT_ST_PLC_FADEOUT_START_FRAME, st->last_good, st->stab_fac, &( st->lp_gainp ), st->last_core ); - } - else if ( st->element_mode != IVAS_CPE_MDCT || !isMCT ) -#else else -#endif { *gain_tcx = hTcxDec->old_gaintcx_bfi; hTcxDec->damping = Damping_fact( st->coder_type, st->nbLostCmpt, st->last_good, st->stab_fac, &( st->lp_gainp ), st->last_core ); @@ -1079,7 +1077,7 @@ void decoder_tcx_invQ( void decoder_tcx_noisefilling( Decoder_State *st, /* i/o: coder memory state */ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE float concealment_noise[L_FRAME48k], #endif const float A[], /* i : coefficients NxAz[M+1] */ @@ -1094,7 +1092,7 @@ void decoder_tcx_noisefilling( const int16_t *prm_sqQ, int16_t nf_seed, const int16_t bfi, /* i : Bad frame indicator */ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE const int16_t isMCT, #endif const int16_t frame_cnt /* i : frame counter in the super frame*/ @@ -1120,6 +1118,9 @@ void decoder_tcx_noisefilling( *-----------------------------------------------------------------*/ /* Init lengths */ +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE + infoIGFStartLine = get_igf_startline( st, L_frame, L_frameTCX ); +#else if ( st->igf == 0 ) { if ( st->narrowBand == 0 ) @@ -1137,6 +1138,7 @@ void decoder_tcx_noisefilling( { infoIGFStartLine = min( st->hIGFDec->infoIGFStartLine, L_frameTCX ); } +#endif noiseFillingSize = L_spec; if ( st->igf ) @@ -1248,7 +1250,7 @@ void decoder_tcx_noisefilling( if ( !bfi && st->element_mode != IVAS_CPE_MDCT ) { -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE TonalMDCTConceal_SaveFreqSignal( st->hTonalMDCTConc, x, L_frameTCX, L_frame, gainlpc2, infoIGFStartLine ); #else TonalMDCTConceal_SaveFreqSignal( st->hTonalMDCTConc, x, L_frameTCX, L_frame, gainlpc2 ); @@ -1261,8 +1263,8 @@ void decoder_tcx_noisefilling( { /* set f to 1 to not fade out */ /* set f to 0 to immediately switch to white noise */ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT - if ( st->tcxonly && st->element_mode != IVAS_CPE_MDCT ) +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE + if ( st->tcxonly && ( st->element_mode != IVAS_CPE_MDCT || isMCT ) ) #else if ( st->tcxonly ) #endif @@ -1304,14 +1306,14 @@ void decoder_tcx_noisefilling( noiseTiltFactor = 1.0f; tcxGetNoiseFillingTilt( A, L_frame, ( total_brate >= ACELP_13k20 && !st->rf_flag ), &noiseTiltFactor ); -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE if ( st->element_mode == IVAS_CPE_MDCT && !isMCT ) { - TonalMDCTConceal_InsertNoise( st->hTonalMDCTConc, x, st->tonal_mdct_plc_active, &st->seed_tcx_plc, noiseTiltFactor, f, concealment_noise, infoIGFStartLine ); + TonalMDCTConceal_InsertNoise( st->hTonalMDCTConc, x, st->tonal_mdct_plc_active, &st->seed_tcx_plc, noiseTiltFactor, f, concealment_noise, hTcxDec->CngLevelBackgroundTrace_bfi, infoIGFStartLine ); } else { - TonalMDCTConceal_InsertNoise( st->hTonalMDCTConc, x, st->tonal_mdct_plc_active, &st->seed_tcx_plc, noiseTiltFactor, f, NULL, infoIGFStartLine ); + TonalMDCTConceal_InsertNoise( st->hTonalMDCTConc, x, st->tonal_mdct_plc_active, &st->seed_tcx_plc, noiseTiltFactor, f, NULL, hTcxDec->CngLevelBackgroundTrace_bfi, infoIGFStartLine ); } #else TonalMDCTConceal_InsertNoise( st->hTonalMDCTConc, x, st->tonal_mdct_plc_active, &st->seed_tcx_plc, noiseTiltFactor, f, infoIGFStartLine ); @@ -1393,7 +1395,7 @@ void decoder_tcx_noiseshaping_igf( * Noise shaping in frequency domain (1/Wz) * *-----------------------------------------------------------*/ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE if ( st->igf && ( !bfi || ( st->element_mode == IVAS_CPE_MDCT && st->prev_bfi ) ) ) #else if ( st->igf && !bfi ) @@ -1943,7 +1945,12 @@ void decoder_tcx_IGF_stereo( const int16_t L_frame, /* i : frame length */ const int16_t left_rect, /* i : left part is rectangular */ const int16_t k, /* i : Subframe index */ - const int16_t bfi /* i : bad frame indicator */ +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE + const int16_t bfi, /* i : bad frame indicator */ + const int16_t is_mct /* i : flag to signal MCT or SMDCT */ +#else + const int16_t bfi /* i : bad frame indicator */ +#endif ) { int16_t coreMsMask[N_MAX]; @@ -1996,7 +2003,11 @@ void decoder_tcx_IGF_stereo( igfGridIdx = ( sts[0]->last_core == ACELP_CORE || ( left_rect && bfi ) ) ? IGF_GRID_LB_TRAN : IGF_GRID_LB_NORM; } +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE + IGFDecApplyStereo( sts[0]->hIGFDec, sts[1]->hIGFDec, x[0][k], x[1][k], igfGridIdx, coreMsMask, hStereoMdct->IGFStereoMode[k] == SMDCT_BW_MS, bfi, is_mct ); +#else IGFDecApplyStereo( sts[0]->hIGFDec, sts[1]->hIGFDec, x[0][k], x[1][k], igfGridIdx, coreMsMask, hStereoMdct->IGFStereoMode[k] == SMDCT_BW_MS, bfi ); +#endif } return; diff --git a/lib_dec/er_dec_tcx.c b/lib_dec/er_dec_tcx.c index 2fb4a8979a..d72e88da5f 100644 --- a/lib_dec/er_dec_tcx.c +++ b/lib_dec/er_dec_tcx.c @@ -34,6 +34,8 @@ EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0 ====================================================================================*/ +#include "cnst.h" +#include "ivas_cnst.h" #include #include #include "options.h" @@ -52,13 +54,12 @@ *-----------------------------------------------------------------*/ void con_tcx( - Decoder_State *st, /* i/o: coder memory state */ - float synth[] /* i/o: synth[] */ - , + Decoder_State *st, /* i/o: coder memory state */ + float synth[], /* i/o: synth[] */ const float coh, /* i : coherence of stereo signal */ int16_t *noise_seed, /* i/o: noise seed for stereo */ const int16_t only_left /* i : TD-PLC only in left channel */ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE , const float *A_cng #endif @@ -280,19 +281,7 @@ void con_tcx( st->bpf_gain_param = 0; /* PLC: calculate damping factor */ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT - alpha = 1.0f; - if ( st->element_mode == IVAS_CPE_MDCT && st->nbLostCmpt >= MDCT_ST_PLC_FADEOUT_START_FRAME ) - { - alpha = Damping_fact( st->core_ext_mode, st->nbLostCmpt - MDCT_ST_PLC_FADEOUT_START_FRAME, st->last_good, st->stab_fac, &( st->lp_gainp ), 0 ); - } - else if ( st->element_mode != IVAS_CPE_MDCT ) - { - alpha = Damping_fact( st->core_ext_mode, st->nbLostCmpt, st->last_good, st->stab_fac, &( st->lp_gainp ), 0 ); - } -#else - alpha = Damping_fact( st->core_ext_mode, st->nbLostCmpt, st->last_good, st->stab_fac, &( st->lp_gainp ), 0 ); -#endif + alpha = Damping_fact( st->core_ext_mode, st->nbLostCmpt, st->last_good, st->stab_fac, &( st->lp_gainp ), ACELP_CORE ); if ( st->nbLostCmpt == 1 ) { @@ -351,19 +340,7 @@ void con_tcx( set_f( pitch_buf, (float) L_SUBFR, st->nb_subfr ); /* PLC: calculate damping factor */ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT - alpha = 1.0f; - if ( st->element_mode == IVAS_CPE_MDCT && st->nbLostCmpt >= MDCT_ST_PLC_FADEOUT_START_FRAME ) - { - alpha = Damping_fact( st->core_ext_mode, st->nbLostCmpt - MDCT_ST_PLC_FADEOUT_START_FRAME, st->last_good, st->stab_fac, &( st->lp_gainp ), 0 ); - } - else if ( st->element_mode != IVAS_CPE_MDCT ) - { - alpha = Damping_fact( st->core_ext_mode, st->nbLostCmpt, st->last_good, st->stab_fac, &( st->lp_gainp ), 0 ); - } -#else - alpha = Damping_fact( st->core_ext_mode, st->nbLostCmpt, st->last_good, st->stab_fac, &( st->lp_gainp ), 0 ); -#endif + alpha = Damping_fact( st->core_ext_mode, st->nbLostCmpt, st->last_good, st->stab_fac, &( st->lp_gainp ), ACELP_CORE ); } /*-----------------------------------------------------------------* @@ -460,7 +437,7 @@ void con_tcx( /* PLC: [TCX: Fade-out] retrieve background level */ tmp = 1.0f; -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE if ( A_cng != NULL ) { gainSynthDeemph = getLevelSynDeemph( &( tmp ), A_cng, L_frame / 4, st->preemph_fac, 1 ) / 4.f; @@ -475,6 +452,20 @@ void con_tcx( if ( st->tcxonly ) { gainCNG = hTcxDec->CngLevelBackgroundTrace_bfi / gainSynthDeemph; + +#ifdef FADE_TO_ZERO_FOR_TOO_LONG_FRAMELOSS + if ( st->element_mode == IVAS_CPE_MDCT && A_cng != NULL ) + { + if ( st->nbLostCmpt > MDCT_ST_PLC_FADEOUT_MAX_CONC_FRAME + MDCT_ST_PLC_FADEOUT_TO_ZERO_LEN ) + { + gainCNG = 0.f; + } + else if ( st->nbLostCmpt > MDCT_ST_PLC_FADEOUT_MAX_CONC_FRAME ) + { + gainCNG *= 1.f - (float) ( st->nbLostCmpt - MDCT_ST_PLC_FADEOUT_MAX_CONC_FRAME ) / MDCT_ST_PLC_FADEOUT_TO_ZERO_LEN; + } + } +#endif } else { @@ -570,26 +561,13 @@ void con_tcx( mvr2r( buf, mem_syn, M ); -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE if ( A_cng != NULL ) { - if ( ( st->nbLostCmpt == 1 && st->idchan == 0 ) || ( st->nbLostCmpt == 2 && st->idchan == 1 ) ) - { - float lsp_cng[M]; - - lpc_from_spectrum( st->hFdCngDec->hFdCngCom, st->hFdCngDec->hFdCngCom->startBand, st->hFdCngDec->hFdCngCom->stopFFTbin, 0.f ); - - a2lsp_stab( st->hFdCngDec->hFdCngCom->A_cng, lsp_cng, st->lspold_cng ); - mvr2r( lsp_cng, st->lspold_cng, M ); - } - - if ( alpha != 1.0f ) + if ( st->plcBackgroundNoiseUpdated && alpha != 1.0f ) { - float lsp_local[M]; - float lsp_fade[M]; - float alpha_inv; + float lsp_local[M], lsp_fade[M], alpha_inv; - wmops_sub_start( "Fade LSPs" ); alpha_inv = 1.0f - alpha; a2lsp_stab( A_local, lsp_local, lsp_local ); @@ -600,7 +578,6 @@ void con_tcx( } lsp2a_stab( lsp_fade, A_local, M ); - wmops_sub_end(); } } #endif diff --git a/lib_dec/evs_dec.c b/lib_dec/evs_dec.c index b51ed8d6ea..e03b2ff2bc 100755 --- a/lib_dec/evs_dec.c +++ b/lib_dec/evs_dec.c @@ -676,7 +676,7 @@ ivas_error evs_dec( st->lp_noise = st->hFdCngDec->lp_noise; -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE ApplyFdCng( output, NULL, realBuffer, imagBuffer, st, concealWholeFrame, 0 ); #else ApplyFdCng( output, realBuffer, imagBuffer, st, concealWholeFrame, 0 ); diff --git a/lib_dec/fd_cng_dec.c b/lib_dec/fd_cng_dec.c index 4f0e8574f0..85d82d953c 100644 --- a/lib_dec/fd_cng_dec.c +++ b/lib_dec/fd_cng_dec.c @@ -368,7 +368,7 @@ void deleteFdCngDec( void ApplyFdCng( float *timeDomainInput, -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE float *powerSpectrum, #endif float **realBuffer, /* i/o: Real part of the buffer */ @@ -384,7 +384,7 @@ void ApplyFdCng( int16_t j, k; float factor; float lsp_cng[M]; -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE int16_t L_frame, last_L_frame; int32_t sr_core; @@ -419,7 +419,7 @@ void ApplyFdCng( /* set noise estimation inactive during concealment, as no update with noise generated by concealment should be performed. */ /* set noise estimation inactive when we have bit errors, as no update with noise generated by corrupt frame (biterror) should be performed. */ if ( concealWholeFrame == 0 && -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE ( timeDomainInput == NULL || ( *timeDomainInput( -FLT_MAX ) && *( timeDomainInput + hFdCngCom->frameSize - 1 ) < FLT_MAX && @@ -435,7 +435,7 @@ void ApplyFdCng( ( !st->BER_detect ) ) { /* Perform noise estimation at the decoder */ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE perform_noise_estimation_dec( timeDomainInput, powerSpectrum, hFdCngDec, st->element_mode, st->bwidth, L_frame, last_L_frame, st->last_core_brate, st->VAD ); #else perform_noise_estimation_dec( timeDomainInput, hFdCngDec, st->element_mode, st->bwidth, st->L_frame, st->last_L_frame, st->last_core_brate, st->VAD ); @@ -471,7 +471,7 @@ void ApplyFdCng( } } -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE if ( st->element_mode == IVAS_CPE_MDCT && timeDomainInput == NULL ) { st->hTcxDec->CngLevelBackgroundTrace_bfi = sqrtf( sum_f( cngNoiseLevel, hFdCngCom->stopFFTbin - hFdCngCom->startBand ) / NORM_MDCT_FACTOR ); @@ -488,7 +488,7 @@ void ApplyFdCng( if ( hFdCngCom->active_frame_counter > 0 ) { /* Perform noise estimation in active frames in the decoder for downward updates */ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE perform_noise_estimation_dec( timeDomainInput, powerSpectrum, hFdCngDec, st->element_mode, st->bwidth, L_frame, last_L_frame, st->last_core_brate, st->VAD ); #else perform_noise_estimation_dec( timeDomainInput, hFdCngDec, st->element_mode, st->bwidth, st->L_frame, st->last_L_frame, st->last_core_brate, st->VAD ); @@ -496,65 +496,47 @@ void ApplyFdCng( } } +#ifndef MDCT_STEREO_PLC_FADE_2_BG_NOISE if ( ( concealWholeFrame == 1 ) && ( st->nbLostCmpt == 1 ) && sum_f( cngNoiseLevel + hFdCngCom->startBand, hFdCngCom->stopFFTbin - hFdCngCom->startBand ) > 0.01f ) { -#ifndef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT /* update lsf cng estimate for concealment. Do that during concealment, in order to avoid addition clean channel complexity*/ lpc_from_spectrum( hFdCngCom, hFdCngCom->startBand, hFdCngCom->stopFFTbin, 0 ); #else - if ( st->element_mode == IVAS_CPE_MDCT && st->core != ACELP_CORE ) - { - float scf[SNS_NPTS]; - float scf_int[FDNS_NPTS]; - float whitenend_noise_shape[L_FRAME16k]; - int16_t inc, start_idx, stop_idx; - float *noiseLevelPtr; - - wmops_sub_start( "get scfs for bg" ); + if ( ( concealWholeFrame == 1 ) && ( st->nbLostCmpt == 1 ) ) + { + /* update lsf cng estimate for concealment. Do that during concealment, in order to avoid addition clean channel complexity*/ - inc = ( st->core > TCX_20 ) ? 2 : 1; - start_idx = hFdCngCom->startBand / inc; - stop_idx = L_frame / inc; - noiseLevelPtr = cngNoiseLevel; + /* always set psychParameters for MDCT-Stereo ... */ + if ( st->element_mode == IVAS_CPE_MDCT && st->hTonalMDCTConc != NULL ) + { + st->hTonalMDCTConc->psychParams = ( st->core == TCX_20_CORE ) ? &st->hTonalMDCTConc->psychParamsTCX20 : &st->hTonalMDCTConc->psychParamsTCX10; + } - set_zero( whitenend_noise_shape, start_idx ); - for ( j = start_idx; j < stop_idx; j++, noiseLevelPtr += inc ) - { - whitenend_noise_shape[j] = *noiseLevelPtr; - } - if ( st->core == TCX_20_CORE ) + /* ... but do actual computations only if sufficient energy in noise shape */ + if ( sum_f( cngNoiseLevel + hFdCngCom->startBand, hFdCngCom->stopFFTbin - hFdCngCom->startBand ) > 0.01f ) + { + if ( st->element_mode == IVAS_CPE_MDCT && st->core != ACELP_CORE ) { - st->hTonalMDCTConc->psychParams = &st->hTonalMDCTConc->psychParamsTCX20; + TonalMdctConceal_whiten_noise_shape( st, L_frame, ON_FIRST_LOST_FRAME ); } - else + else if ( st->element_mode != IVAS_CPE_MDCT || st->core == ACELP_CORE ) { - st->hTonalMDCTConc->psychParams = &st->hTonalMDCTConc->psychParamsTCX10; + lpc_from_spectrum( hFdCngCom, hFdCngCom->startBand, hFdCngCom->stopFFTbin, 0.f ); + a2lsp_stab( hFdCngCom->A_cng, lsp_cng, st->lspold_cng ); + mvr2r( lsp_cng, st->lspold_cng, M ); + lsp2lsf( lsp_cng, st->lsf_cng, M, sr_core ); } - - sns_compute_scf( whitenend_noise_shape, st->hTonalMDCTConc->psychParams, L_frame, scf ); - sns_interpolate_scalefactors( scf_int, scf, ENC ); - sns_interpolate_scalefactors( st->hTonalMDCTConc->scaleFactorsBackground, scf, DEC ); - sns_shape_spectrum( whitenend_noise_shape, st->hTonalMDCTConc->psychParams, scf_int, L_frame ); - - mvr2r( whitenend_noise_shape + start_idx, cngNoiseLevel, stop_idx - start_idx ); - wmops_sub_end(); - } - else if ( st->element_mode != IVAS_CPE_MDCT ) - { - lpc_from_spectrum( hFdCngCom, hFdCngCom->startBand, hFdCngCom->stopFFTbin, 0.f ); - a2lsp_stab( hFdCngCom->A_cng, lsp_cng, st->lspold_cng ); - mvr2r( lsp_cng, st->lspold_cng, M ); - lsp2lsf( lsp_cng, st->lsf_cng, M, sr_core ); + st->plcBackgroundNoiseUpdated = 1; } #endif +#ifndef MDCT_STEREO_PLC_FADE_2_BG_NOISE -#ifndef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT a2lsp_stab( hFdCngCom->A_cng, lsp_cng, st->lspold_cng ); mvr2r( lsp_cng, st->lspold_cng, M ); lsp2lsf( lsp_cng, st->lsf_cng, M, st->sr_core ); -#endif st->plcBackgroundNoiseUpdated = 1; +#endif } break; @@ -567,7 +549,7 @@ void ApplyFdCng( if ( st != NULL && st->cng_type == LP_CNG ) { /* Perform noise estimation on inactive phase at the decoder */ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE perform_noise_estimation_dec( timeDomainInput, powerSpectrum, hFdCngDec, st->element_mode, st->bwidth, L_frame, last_L_frame, st->last_core_brate, st->VAD ); #else perform_noise_estimation_dec( timeDomainInput, hFdCngDec, st->element_mode, st->bwidth, st->L_frame, st->last_L_frame, st->last_core_brate, st->VAD ); @@ -582,7 +564,7 @@ void ApplyFdCng( /* This sets the new CNG levels until a SID update overwrites it */ mvr2r( hFdCngDec->bandNoiseShape, cngNoiseLevel, hFdCngCom->stopFFTbin - hFdCngCom->startBand ); /* This sets the new CNG levels until a SID update overwrites it */ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE st->cngTDLevel = (float) sqrt( ( sum_f( cngNoiseLevel, hFdCngCom->stopFFTbin - hFdCngCom->startBand ) / 2 * hFdCngCom->fftlen ) / L_frame ); #else st->cngTDLevel = (float) sqrt( ( sum_f( cngNoiseLevel, hFdCngCom->stopFFTbin - hFdCngCom->startBand ) / 2 * hFdCngCom->fftlen ) / st->L_frame ); @@ -668,7 +650,7 @@ void ApplyFdCng( default: break; } -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE wmops_sub_end(); #endif @@ -685,7 +667,7 @@ void ApplyFdCng( void perform_noise_estimation_dec( const float *timeDomainInput, -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE float *power_spectrum, #endif HANDLE_FD_CNG_DEC hFdCngDec, /* i/o: FD_CNG structure containing all buffers and variables */ @@ -720,7 +702,7 @@ void perform_noise_estimation_dec( float temp, ftemp, delta; float wght; -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE if ( !( element_mode == IVAS_CPE_MDCT && power_spectrum != NULL ) ) { /* Perform STFT analysis */ @@ -962,7 +944,7 @@ void perform_noise_estimation_dec( } else { -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE if ( element_mode == IVAS_CPE_MDCT && power_spectrum != NULL ) { /* use power spectrum calculated in the MDCT-domain instead of calculating new power spectrum */ @@ -2099,6 +2081,10 @@ void FdCngDecodeMDCTStereoSID( msvq_dec( cdk_37bits_ivas, NULL, NULL, stages, N, FD_CNG_maxN_37bits, indices, ms_ptr[ch], NULL ); } +#ifdef ALIGN_SID_SIZE + dtx_read_padding_bits( sts[1], ( IVAS_SID_5k2 - 4400 ) / FRAMES_PER_SEC ); +#endif + if ( sts[0]->hFdCngDec->hFdCngCom->no_side_flag ) { set_zero( ms_ptr[1], NPART ); @@ -2122,7 +2108,11 @@ void FdCngDecodeMDCTStereoSID( lpc_from_spectrum( hFdCngCom, hFdCngCom->startBand, hFdCngCom->stopFFTbin, sts[ch]->preemph_fac ); } +#ifdef ALIGN_SID_SIZE + if ( hCPE->nchan_out == 1 && hCPE->last_element_brate <= IVAS_SID_5k2 ) +#else if ( hCPE->nchan_out == 1 && hCPE->last_element_brate <= IVAS_SID_4k4 ) +#endif { /* create proper M noise shape in channel zero after gains have been applied */ for ( p = 0; p < N; p++ ) diff --git a/lib_dec/igf_dec.c b/lib_dec/igf_dec.c index 55e526d665..fecc8e96df 100644 --- a/lib_dec/igf_dec.c +++ b/lib_dec/igf_dec.c @@ -679,7 +679,12 @@ static void IGF_appl( float *pSpectralData, /* i/o: Q31 | MDCT spectrum */ const float *igf_spec, /* i : Q31 | prepared IGF spectrum */ float *virtualSpec, /* o : Q31 | virtual IGF spectrum, used for temp flattening */ +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE + int16_t *flag_sparse, /* o : Q0 | temp flattening indicator */ + const int16_t bfi_apply_damping /* i : flag to indicate if damping for lost frames should be applied */ +#else int16_t *flag_sparse /* o : Q0 | temp flattening indicator */ +#endif ) { H_IGF_GRID hGrid; @@ -855,7 +860,11 @@ static void IGF_appl( for ( sfb = start_sfb; sfb < stop_sfb; sfb++ ) { +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE + if ( bfi_apply_damping && hPrivateData->frameLossCounter > 0 ) +#else if ( hPrivateData->frameLossCounter > 0 ) +#endif { gain[sfb] = min( gain[sfb], 12.f ); @@ -1212,7 +1221,11 @@ void IGFDecApplyMono( /* apply IGF in three steps: */ IGF_prep( hPrivateData, igfGridIdx, hIGFDec->infoTCXNoise, igf_spec, hPrivateData->pSpecFlat, element_mode ); IGF_calc( hPrivateData, igfGridIdx, spectrum, igf_spec ); +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE + IGF_appl( hPrivateData, igfGridIdx, spectrum, igf_spec, hIGFDec->virtualSpec, hIGFDec->flag_sparse, 1 ); +#else IGF_appl( hPrivateData, igfGridIdx, spectrum, igf_spec, hIGFDec->virtualSpec, hIGFDec->flag_sparse ); +#endif } /* reset TCX noise indicator vector */ @@ -1238,7 +1251,12 @@ void IGFDecApplyStereo( const int16_t igfGridIdx, /* i : in case of CELP->TCX switching, use 1.25 framelength */ const int16_t *coreMsMask, const int16_t restrict_hopsize, +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE + const int16_t bfi, /* i : frame loss == 1, frame good == 0 */ + const int16_t bfi_apply_damping +#else const int16_t bfi /* i : frame loss == 1, frame good == 0 */ +#endif ) { IGF_DEC_PRIVATE_DATA_HANDLE hPrivateDataL, hPrivateDataR; @@ -1335,8 +1353,13 @@ void IGFDecApplyStereo( IGF_calc( hPrivateDataL, igfGridIdx, spectrumL, igf_specL ); IGF_calc( hPrivateDataR, igfGridIdx, spectrumR, igf_specR ); +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE + IGF_appl( hPrivateDataL, igfGridIdx, spectrumL, igf_specL, hIGFDecL->virtualSpec, hIGFDecL->flag_sparse, bfi_apply_damping ); + IGF_appl( hPrivateDataR, igfGridIdx, spectrumR, igf_specR, hIGFDecR->virtualSpec, hIGFDecR->flag_sparse, bfi_apply_damping ); +#else IGF_appl( hPrivateDataL, igfGridIdx, spectrumL, igf_specL, hIGFDecL->virtualSpec, hIGFDecL->flag_sparse ); IGF_appl( hPrivateDataR, igfGridIdx, spectrumR, igf_specR, hIGFDecR->virtualSpec, hIGFDecR->flag_sparse ); +#endif } /* reset TCX noise indicator vector */ @@ -1588,3 +1611,34 @@ void init_igf_dec( return; } + +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE +int16_t get_igf_startline( + Decoder_State *st, + int16_t L_frame, + int16_t L_frameTCX +) +{ + int16_t igf_startline; + + if ( st->igf == 0 ) + { + if ( st->narrowBand == 0 ) + { + /* minimum needed for output with sampling rates lower then the + nominal sampling rate */ + igf_startline = min( L_frameTCX, L_frame ); + } + else + { + igf_startline = L_frameTCX; + } + } + else + { + igf_startline = min( st->hIGFDec->infoIGFStartLine, L_frameTCX ); + } + + return igf_startline; +} +#endif diff --git a/lib_dec/init_dec.c b/lib_dec/init_dec.c index 40c65d9503..2e31017eaa 100644 --- a/lib_dec/init_dec.c +++ b/lib_dec/init_dec.c @@ -54,7 +54,7 @@ ivas_error init_decoder( Decoder_State *st, /* o : Decoder static variables structure */ const int16_t idchan /* i : channel ID */ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE , const MC_MODE mc_mode /* i : MC mode */ #endif @@ -691,7 +691,7 @@ ivas_error init_decoder( st->enablePlcWaveadjust = 0; /* Init Core Decoder */ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE open_decoder_LPD( st, st->total_brate, st->last_total_brate, st->bwidth, 0, st->element_mode, 1 ); #else open_decoder_LPD( st, st->total_brate, st->last_total_brate, st->bwidth, 0, 1 ); @@ -714,7 +714,7 @@ ivas_error init_decoder( * FD-CNG decoder *-----------------------------------------------------------------*/ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE if ( ( st->element_mode == IVAS_CPE_MDCT || idchan == 0 ) && mc_mode != MC_MODE_MCT ) #else if ( idchan == 0 && st->element_mode != IVAS_CPE_MDCT ) diff --git a/lib_dec/ivas_core_dec.c b/lib_dec/ivas_core_dec.c index de87b4c557..ad350f4e30 100755 --- a/lib_dec/ivas_core_dec.c +++ b/lib_dec/ivas_core_dec.c @@ -35,7 +35,7 @@ #ifdef DEBUGGING #include "debug.h" #endif -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE #include #endif #include @@ -183,7 +183,7 @@ ivas_error ivas_core_dec( st->flagGuidedAcelp = 0; } -#ifndef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifndef MDCT_STEREO_PLC_FADE_2_BG_NOISE /* PLC: [TCX: Fade-out-recovery] - overlapping part needs to be attenuated for first good frame */ if ( !st->bfi && st->prev_bfi && ( st->last_core_bfi == TCX_20_CORE || st->last_core_bfi == TCX_10_CORE ) && st->element_mode != IVAS_CPE_MDCT ) { @@ -201,7 +201,7 @@ ivas_error ivas_core_dec( } #else /* PLC: [TCX: Fade-out-recovery] - overlapping part needs to be attenuated for first good frame */ - if ( !st->bfi && st->prev_bfi && ( st->last_core_bfi == TCX_20_CORE || st->last_core_bfi == TCX_10_CORE ) ) + if ( !st->bfi && st->prev_bfi && ( st->last_core_bfi == TCX_20_CORE || st->last_core_bfi == TCX_10_CORE ) && hMCT == NULL ) { float gain; if ( st->hPlcInfo != NULL ) @@ -428,6 +428,21 @@ ivas_error ivas_core_dec( { updateBuffersForDmxMdctStereo( hCPE, output_frame, output, synth ); } + +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE + if ( sts[0]->bfi == 0 && sts[0]->prev_bfi == 1 ) + { + /* On first good frame after frameloss undo the whitening of the bg noise shape */ + for ( n = 0; n < n_channels; ++n ) + { + if ( sts[n]->last_core_bfi != ACELP_CORE ) + { + TonalMdctConceal_whiten_noise_shape( sts[n], L_FRAME16k, ON_FIRST_GOOD_FRAME ); + } + } + } +#endif + } /*---------------------------------------------------------------------* diff --git a/lib_dec/ivas_cpe_dec.c b/lib_dec/ivas_cpe_dec.c index 7223b38761..da0911ee5b 100644 --- a/lib_dec/ivas_cpe_dec.c +++ b/lib_dec/ivas_cpe_dec.c @@ -160,14 +160,22 @@ ivas_error ivas_cpe_dec( if ( hCPE->element_mode != IVAS_CPE_MDCT && ( hCPE->element_brate != hCPE->last_element_brate || hCPE->last_element_mode != hCPE->element_mode || sts[0]->ini_frame == 0 || ( ivas_total_brate != st_ivas->hDecoderConfig->last_ivas_total_brate ) ) ) { +#ifdef ALIGN_SID_SIZE + if ( st_ivas->hQMetaData != NULL && ivas_total_brate > IVAS_SID_5k2 ) +#else if ( st_ivas->hQMetaData != NULL && ivas_total_brate > IVAS_SID_4k4 ) +#endif { stereo_dft_config( hCPE->hStereoDft == NULL ? NULL : hCPE->hStereoDft->hConfig, st_ivas->hQMetaData->bits_frame_nominal * FRAMES_PER_SEC, &sts[0]->bits_frame_nominal, &sts[1]->bits_frame_nominal ); } else { /* Note: This only works for stereo operation. If DTX would be applied for multiple CPEs a different bitrate signaling is needed */ +#ifdef ALIGN_SID_SIZE + if ( ivas_total_brate <= IVAS_SID_5k2 ) +#else if ( ivas_total_brate <= IVAS_SID_4k4 ) +#endif { stereo_dft_config( hCPE->hStereoDft == NULL ? NULL : hCPE->hStereoDft->hConfig, ivas_total_brate, &sts[0]->bits_frame_nominal, &sts[1]->bits_frame_nominal ); } @@ -203,7 +211,11 @@ ivas_error ivas_cpe_dec( /* Update DFT Stereo memories */ stereo_dft_dec_update( hCPE->hStereoDft, output_frame, 0 ); +#ifdef ALIGN_SID_SIZE + if ( st_ivas->ivas_format == MASA_FORMAT && ivas_total_brate <= IVAS_SID_5k2 ) +#else if ( st_ivas->ivas_format == MASA_FORMAT && ivas_total_brate <= IVAS_SID_4k4 ) +#endif { if ( ivas_total_brate == FRAME_NO_DATA ) { @@ -220,13 +232,21 @@ ivas_error ivas_cpe_dec( nb_bits = (int16_t) ( ( hCPE->element_brate ) / FRAMES_PER_SEC - 0.8f * sts[0]->bits_frame_nominal ); sts[1]->bit_stream = sts[0]->bit_stream + ivas_total_brate / FRAMES_PER_SEC - 1 - nb_bits_metadata; +#ifdef ALIGN_SID_SIZE + if ( ivas_total_brate == IVAS_SID_5k2 ) +#else if ( ivas_total_brate == IVAS_SID_4k4 ) +#endif { nb_bits -= SID_FORMAT_NBITS; sts[1]->bit_stream -= SID_FORMAT_NBITS; } +#ifdef ALIGN_SID_SIZE + if ( st_ivas->ivas_format == MASA_FORMAT && ivas_total_brate < MASA_STEREO_MIN_BITRATE && ivas_total_brate > IVAS_SID_5k2 ) +#else if ( st_ivas->ivas_format == MASA_FORMAT && ivas_total_brate < MASA_STEREO_MIN_BITRATE && ivas_total_brate > IVAS_SID_4k4 ) +#endif { sts[0]->total_brate = hCPE->element_brate; /* Only mono downmix was transmitted in this case */ } @@ -266,7 +286,11 @@ ivas_error ivas_cpe_dec( /* this is just for initialization, the true values of "total_brate" and "bits_frame_channel" are set later */ for ( n = 0; n < n_channels; n++ ) { +#ifdef ALIGN_SID_SIZE + if ( ivas_total_brate == IVAS_SID_5k2 ) +#else if ( ivas_total_brate == IVAS_SID_4k4 || ivas_total_brate == IVAS_SID_5k ) +#endif { sts[n]->total_brate = SID_2k40; @@ -283,7 +307,11 @@ ivas_error ivas_cpe_dec( if ( !st_ivas->hMCT ) { +#ifdef ALIGN_SID_SIZE + if ( st_ivas->ivas_format == SBA_FORMAT && ivas_total_brate == IVAS_SID_5k2 ) +#else if ( st_ivas->ivas_format == SBA_FORMAT && ivas_total_brate == IVAS_SID_5k ) +#endif { for ( n = 0; n < n_channels; n++ ) { @@ -587,7 +615,11 @@ ivas_error create_cpe_dec( hCPE->nchan_out = min( CPE_CHANNELS, st_ivas->hDecoderConfig->nchan_out ); } +#ifdef ALIGN_SID_SIZE + if ( st_ivas->ivas_format == MASA_FORMAT && st_ivas->hDecoderConfig->ivas_total_brate < MASA_STEREO_MIN_BITRATE && st_ivas->hDecoderConfig->ivas_total_brate > IVAS_SID_5k2 ) +#else if ( st_ivas->ivas_format == MASA_FORMAT && st_ivas->hDecoderConfig->ivas_total_brate < MASA_STEREO_MIN_BITRATE && st_ivas->hDecoderConfig->ivas_total_brate > IVAS_SID_4k4 ) +#endif { hCPE->nchan_out = 1; } @@ -686,7 +718,7 @@ ivas_error create_cpe_dec( st->mct_chan_mode = MCT_CHAN_MODE_LFE; } -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE if ( ( error = init_decoder( st, n, st_ivas->mc_mode ) ) != IVAS_ERR_OK ) #else if ( ( error = init_decoder( st, n ) ) != IVAS_ERR_OK ) @@ -791,6 +823,12 @@ ivas_error create_cpe_dec( set_s( hCPE->hStereoMdct->prev_ms_mask[0], 0, MAX_SFB ); set_s( hCPE->hStereoMdct->prev_ms_mask[1], 0, MAX_SFB ); hCPE->hStereoMdct->lastCoh = 1.f; +#ifdef FIX_135_MDCT_STEREO_MODE_UNINITIALIZED + hCPE->hStereoMdct->mdct_stereo_mode[0] = SMDCT_DUAL_MONO; + hCPE->hStereoMdct->mdct_stereo_mode[1] = SMDCT_DUAL_MONO; + hCPE->hStereoMdct->IGFStereoMode[0] = -1; + hCPE->hStereoMdct->IGFStereoMode[1] = -1; +#endif } /*-----------------------------------------------------------------* @@ -923,7 +961,11 @@ static void read_stereo_mode_and_bwidth( * BFI or NO_DATA frame: Use stereo parameters from last (active) frame *-----------------------------------------------------------------*/ +#ifdef ALIGN_SID_SIZE + if ( st_ivas->bfi || st_ivas->hDecoderConfig->ivas_total_brate < IVAS_SID_5k2 ) +#else if ( st_ivas->bfi || st_ivas->hDecoderConfig->ivas_total_brate < IVAS_SID_4k4 ) +#endif { hCPE->element_mode = hCPE->last_element_mode; @@ -933,7 +975,11 @@ static void read_stereo_mode_and_bwidth( * SID frame: get element mode from SID side info *-----------------------------------------------------------------*/ +#ifdef ALIGN_SID_SIZE + else if ( st_ivas->hDecoderConfig->ivas_total_brate == IVAS_SID_5k2 ) +#else else if ( st_ivas->hDecoderConfig->ivas_total_brate == IVAS_SID_4k4 || st_ivas->hDecoderConfig->ivas_total_brate == IVAS_SID_5k ) +#endif { switch ( st_ivas->sid_format ) { @@ -951,7 +997,7 @@ static void read_stereo_mode_and_bwidth( hCPE->element_mode = IVAS_CPE_MDCT; break; case SID_SBA_1TC: - assert( "Forbidden value for sid format in CPE (SBA 1TC), should have already been adressed earlier" ); + assert( "Forbidden value for SID format in CPE (SBA 1TC), should have already been adressed earlier" ); break; case SID_MASA_1TC: hCPE->element_mode = IVAS_SCE; diff --git a/lib_dec/ivas_dec.c b/lib_dec/ivas_dec.c index a103c9f45f..7d54047014 100644 --- a/lib_dec/ivas_dec.c +++ b/lib_dec/ivas_dec.c @@ -290,8 +290,11 @@ ivas_error ivas_dec( nchan_remapped = CPE_CHANNELS; ivas_sba_dirac_stereo_dec( st_ivas, output, output_frame ); } - else if ( st_ivas->ivas_format == MASA_FORMAT && ivas_total_brate < MASA_STEREO_MIN_BITRATE && - ( ivas_total_brate > IVAS_SID_4k4 || ( ivas_total_brate <= IVAS_SID_4k4 && st_ivas->nCPE > 0 && st_ivas->hCPE[0]->nchan_out == 1 ) ) ) +#ifdef ALIGN_SID_SIZE + 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 ) ) ) +#else + else if ( st_ivas->ivas_format == MASA_FORMAT && ivas_total_brate < MASA_STEREO_MIN_BITRATE && ( ivas_total_brate > IVAS_SID_4k4 || ( ivas_total_brate <= IVAS_SID_4k4 && st_ivas->nCPE > 0 && st_ivas->hCPE[0]->nchan_out == 1 ) ) ) +#endif { nchan_remapped = 1; /* Only one channel transported */ } @@ -309,7 +312,7 @@ ivas_error ivas_dec( if ( st_ivas->sba_mode == SBA_MODE_SPAR && ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) ) { - ivas_sba_mix_matrix_determiner( st_ivas, output, nchan_remapped, output_frame ); + ivas_sba_mix_matrix_determiner( st_ivas->hSpar, output, st_ivas->bfi, nchan_remapped, output_frame ); } } @@ -345,7 +348,7 @@ ivas_error ivas_dec( } else /* SBA_MODE_SPAR */ { - ivas_sba_upmixer_renderer( st_ivas, output, nchan_remapped, output_frame ); /* Note: ivas_sba_linear_renderer() or ivas_dirac_dec() are called internally */ + ivas_sba_upmixer_renderer( st_ivas, output, output_frame ); /* Note: ivas_sba_linear_renderer() or ivas_dirac_dec() are called internally */ } } else if ( st_ivas->ivas_format == MC_FORMAT ) @@ -571,7 +574,11 @@ ivas_error ivas_dec( 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_4k4 ) // VE: looks strange: ini_frame -> ini_frame_active ? +#ifdef ALIGN_SID_SIZE + 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 */ +#else + if ( st_ivas->ini_active_frame < MAX_FRAME_COUNTER && !( st_ivas->bfi && st_ivas->ini_frame == 0 ) && ivas_total_brate > IVAS_SID_4k4 ) /* needed in MASA decoder in case the first active frame is BFI, and there were SID-frames decoded before */ +#endif { st_ivas->ini_active_frame++; } diff --git a/lib_dec/ivas_dirac_dec.c b/lib_dec/ivas_dirac_dec.c index 074f635133..ef4527ea8f 100755 --- a/lib_dec/ivas_dirac_dec.c +++ b/lib_dec/ivas_dirac_dec.c @@ -186,14 +186,15 @@ ivas_error ivas_dirac_dec_config( nchan_transport_orig = st_ivas->nchan_transport; if ( st_ivas->ivas_format == SBA_FORMAT && st_ivas->sba_mode == SBA_MODE_SPAR && !( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) ) { -#ifdef SBA_ORDER_BITSTREAM st_ivas->nchan_transport = ivas_sba_get_nchan_metadata( st_ivas->sba_analysis_order ); -#else - st_ivas->nchan_transport = ivas_sba_get_nchan_metadata( st_ivas->sba_order ); -#endif } + nchan_transport = st_ivas->nchan_transport; +#ifdef ALIGN_SID_SIZE + if ( st_ivas->ivas_format == MASA_FORMAT && ivas_total_brate < MASA_STEREO_MIN_BITRATE && ivas_total_brate > IVAS_SID_5k2 ) +#else if ( st_ivas->ivas_format == MASA_FORMAT && ivas_total_brate < MASA_STEREO_MIN_BITRATE && ivas_total_brate > IVAS_SID_4k4 ) +#endif { nchan_transport = 1; } @@ -201,10 +202,10 @@ ivas_error ivas_dirac_dec_config( if ( flag_config == DIRAC_RECONFIGURE && st_ivas->ivas_format == SBA_FORMAT ) { int16_t tmp1, tmp2, tmp3; -#ifdef SBA_ORDER_BITSTREAM - ivas_sba_config( st_ivas->hDecoderConfig->last_ivas_total_brate, st_ivas->sba_analysis_order, -1, &nchan_transport_old, st_ivas->sba_planar, &tmp1, &tmp2, &tmp3, SBA_MODE_DIRAC ); +#ifdef HARMONIZE_SBA_NCHAN_TRANSPORT + ivas_sba_config( st_ivas->hDecoderConfig->last_ivas_total_brate, st_ivas->sba_analysis_order, -1, &nchan_transport_old, st_ivas->sba_planar, &tmp1, &tmp2, &tmp3 ); #else - ivas_sba_config( st_ivas->hDecoderConfig->last_ivas_total_brate, st_ivas->sba_order, -1, &nchan_transport_old, st_ivas->sba_planar, &tmp1, &tmp2, &tmp3, SBA_MODE_DIRAC ); + ivas_sba_config( st_ivas->hDecoderConfig->last_ivas_total_brate, st_ivas->sba_analysis_order, -1, &nchan_transport_old, st_ivas->sba_planar, &tmp1, &tmp2, &tmp3, SBA_MODE_DIRAC ); #endif } @@ -763,7 +764,6 @@ ivas_error ivas_dirac_dec_config( mvs2s( DirAC_block_grouping, hDirAC->block_grouping, MAX_PARAM_SPATIAL_SUBFRAMES + 1 ); - if ( flag_config == DIRAC_OPEN ) { hDirAC->dirac_md_buffer_length = 0; @@ -1287,7 +1287,11 @@ void ivas_dirac_dec_read_BS( int16_t next_bit_pos_orig; *nb_bits = 0; +#ifdef ALIGN_SID_SIZE + if ( !st->bfi && ivas_total_brate > IVAS_SID_5k2 ) +#else if ( !st->bfi && ivas_total_brate > IVAS_SID_4k4 ) +#endif { next_bit_pos_orig = st->next_bit_pos; st->next_bit_pos = (int16_t) ( ivas_total_brate / FRAMES_PER_SEC - 1 ); @@ -1296,14 +1300,19 @@ void ivas_dirac_dec_read_BS( b = st->bit_stream[( st->next_bit_pos )--]; ( *nb_bits )++; +#ifndef ALIGN_SID_SIZE if ( sba_mode == SBA_MODE_SPAR ) { + if ( ivas_total_brate == IVAS_SID_5k ) { b = 1; } } else +#else + if ( sba_mode != SBA_MODE_SPAR ) +#endif { assert( ( b == 0 ) || ( hQMetaData->q_direction[0].cfg.start_band > 0 ) ); } @@ -1391,12 +1400,23 @@ void ivas_dirac_dec_read_BS( st->next_bit_pos = next_bit_pos_orig; } +#ifdef ALIGN_SID_SIZE + else if ( !st->bfi && ivas_total_brate == IVAS_SID_5k2 ) +#else else if ( !st->bfi && ivas_total_brate == IVAS_SID_4k4 ) +#endif { next_bit_pos_orig = st->next_bit_pos; /* subtract mode signaling bits, since bitstream was moved after mode reading */ st->next_bit_pos = (int16_t) ( ivas_total_brate / FRAMES_PER_SEC - 1 - SID_FORMAT_NBITS ); +#ifdef ALIGN_SID_SIZE + /* 1 bit flag for SPAR/DirAC, already read in read format function */ + b = st->bit_stream[( st->next_bit_pos )--]; + ( *nb_bits )++; + hQMetaData->sba_inactive_mode = 1; + orig_dirac_bands = hQMetaData->q_direction[0].cfg.nbands; +#endif /* if we start with a SID frame, we need to init the azi/ele arrays.*/ if ( st->ini_frame == 0 ) @@ -1411,8 +1431,39 @@ void ivas_dirac_dec_read_BS( } } +#ifdef ALIGN_SID_SIZE + *nb_bits += ivas_qmetadata_dec_sid_decode( hQMetaData, st->bit_stream, &( st->next_bit_pos ), 0, NULL, SBA_FORMAT, sba_mode ); + + if ( sba_mode == SBA_MODE_SPAR ) + { + for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) + { + hQMetaData->q_direction[0].band_data[orig_dirac_bands - 1].azimuth[i] = hQMetaData->q_direction[0].band_data[1].azimuth[0]; + hQMetaData->q_direction[0].band_data[orig_dirac_bands - 1].elevation[i] = hQMetaData->q_direction[0].band_data[1].elevation[0]; + hQMetaData->q_direction[0].band_data[orig_dirac_bands - 1].energy_ratio[i] = hQMetaData->q_direction[0].band_data[1].energy_ratio[0]; + } + for ( i = 0; i < MAX_PARAM_SPATIAL_SUBFRAMES; i++ ) + { + for ( j = orig_dirac_bands - 2; j >= 0; j-- ) + { + hQMetaData->q_direction[0].band_data[j].azimuth[i] = hQMetaData->q_direction[0].band_data[0].azimuth[0]; + hQMetaData->q_direction[0].band_data[j].elevation[i] = hQMetaData->q_direction[0].band_data[0].elevation[0]; + hQMetaData->q_direction[0].band_data[j].energy_ratio[i] = hQMetaData->q_direction[0].band_data[0].energy_ratio[0]; + } + } + + hQMetaData->q_direction->cfg.nbands = orig_dirac_bands; + } + else + { + *nb_bits += SID_FORMAT_NBITS; + } +#else *nb_bits += ivas_qmetadata_dec_sid_decode( hQMetaData, st->bit_stream, &( st->next_bit_pos ), 0, NULL, SBA_FORMAT, SBA_MODE_DIRAC ); + *nb_bits += SID_FORMAT_NBITS; +#endif + st->next_bit_pos = next_bit_pos_orig; } @@ -1458,7 +1509,11 @@ void ivas_qmetadata_to_dirac( q_direction = &( hQMetaData->q_direction[0] ); hDirAC->numSimultaneousDirections = hQMetaData->no_directions; +#ifdef ALIGN_SID_SIZE + if ( hMasa != NULL && ivas_total_brate > IVAS_SID_5k2 ) +#else if ( hMasa != NULL && ivas_total_brate > IVAS_SID_4k4 ) +#endif { band_mapping = hMasa->data.band_mapping; @@ -1534,7 +1589,11 @@ void ivas_qmetadata_to_dirac( nbands = hDirAC->band_grouping[hDirAC->hConfig->nbands]; band_grouping = hDirAC->band_grouping; +#ifdef ALIGN_SID_SIZE + if ( ivas_total_brate <= IVAS_SID_5k2 && sba_mode != SBA_MODE_SPAR ) +#else if ( ivas_total_brate <= IVAS_SID_4k4 && sba_mode != SBA_MODE_SPAR ) +#endif { /* SID/zero-frame: 1 direction, 5 bands, nblocks re-generated out of SID decoder*/ start_band = 0; @@ -1630,7 +1689,11 @@ void ivas_qmetadata_to_dirac( ele = min( 90, ele ); ele = max( -90, ele ); +#ifdef ALIGN_SID_SIZE + if ( ivas_total_brate > IVAS_SID_5k2 && q_direction->coherence_band_data != NULL ) +#else if ( ivas_total_brate > IVAS_SID_4k4 && q_direction->coherence_band_data != NULL ) +#endif { hDirAC->spreadCoherence[tmp_write_idx_band][b] = q_direction->coherence_band_data[qBand_idx].spread_coherence[block] / 255.0f; } @@ -1639,7 +1702,11 @@ void ivas_qmetadata_to_dirac( hDirAC->spreadCoherence[tmp_write_idx_band][b] = 0.0f; } +#ifdef ALIGN_SID_SIZE + if ( ivas_total_brate > IVAS_SID_5k2 && q_direction->coherence_band_data != NULL ) +#else if ( ivas_total_brate > IVAS_SID_4k4 && q_direction->coherence_band_data != NULL ) +#endif { hDirAC->surroundingCoherence[tmp_write_idx_band][b] = hQMetaData->surcoh_band_data[qBand_idx].surround_coherence[0] / 255.0f; } @@ -1794,7 +1861,11 @@ void ivas_dirac_dec( #ifdef DEBUG_MODE_DIRAC { +#ifdef HARMONIZE_SBA_NCHAN_TRANSPORT + int16_t n, tmp[1 * L_FRAME48k]; +#else int16_t n, tmp[DIRAC_MAX_TRANS_CHANS * L_FRAME48k]; +#endif char file_name[50] = { 0 }; const int16_t output_frame = st_ivas->output_Fs / FRAMES_PER_SEC; diff --git a/lib_dec/ivas_init_dec.c b/lib_dec/ivas_init_dec.c index b12aa28e40..f084b25b9b 100755 --- a/lib_dec/ivas_init_dec.c +++ b/lib_dec/ivas_init_dec.c @@ -119,20 +119,18 @@ ivas_error ivas_dec_setup( num_bits_read += SBA_PLANAR_BITS; /* read Ambisonic (SBA) order */ -#ifndef SBA_ORDER_BITSTREAM st_ivas->sba_order = st_ivas->bit_stream[num_bits_read + 1]; st_ivas->sba_order += 2 * st_ivas->bit_stream[num_bits_read]; -#else - st_ivas->hDecoderConfig->sba_order = st_ivas->bit_stream[num_bits_read + 1]; - st_ivas->hDecoderConfig->sba_order += 2 * st_ivas->bit_stream[num_bits_read]; - st_ivas->sba_analysis_order = st_ivas->hDecoderConfig->sba_order; - if ( ivas_total_brate < IVAS_256k ) - { - st_ivas->sba_analysis_order = 1; - } -#endif + + /* 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 ); + num_bits_read += SBA_ORDER_BITS; +#ifdef ALIGN_SID_SIZE + if ( st_ivas->ini_frame > 0 && ivas_total_brate != st_ivas->hDecoderConfig->last_ivas_total_brate && ivas_total_brate > IVAS_SID_5k2 ) +#else if ( st_ivas->ini_frame > 0 && ivas_total_brate != st_ivas->hDecoderConfig->last_ivas_total_brate && ivas_total_brate > IVAS_SID_4k4 ) +#endif { if ( ( error = ivas_sba_dec_reconfigure( st_ivas ) ) != IVAS_ERR_OK ) { @@ -141,8 +139,8 @@ ivas_error ivas_dec_setup( } else { -#ifndef SBA_ORDER_BITSTREAM - ivas_sba_config( ivas_total_brate, st_ivas->sba_order, -1, &( st_ivas->nchan_transport ), st_ivas->sba_planar, &st_ivas->nSCE, &st_ivas->nCPE, &st_ivas->element_mode_init, st_ivas->sba_mode ); +#ifdef HARMONIZE_SBA_NCHAN_TRANSPORT + 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 ); #else 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, st_ivas->sba_mode ); #endif @@ -164,7 +162,11 @@ ivas_error ivas_dec_setup( if ( st_ivas->ini_frame > 0 ) { /* reconfigure in case a change of operation mode is detected */ +#ifdef ALIGN_SID_SIZE + if ( ( ivas_total_brate > IVAS_SID_5k2 && ivas_total_brate != st_ivas->hDecoderConfig->last_ivas_total_brate ) || ( st_ivas->ini_active_frame == 0 ) ) +#else if ( ( ivas_total_brate > IVAS_SID_4k4 && ivas_total_brate != st_ivas->hDecoderConfig->last_ivas_total_brate ) || ( st_ivas->ini_active_frame == 0 ) ) +#endif { if ( st_ivas->ini_active_frame == 0 && ivas_total_brate != FRAME_NO_DATA && ivas_total_brate < MASA_STEREO_MIN_BITRATE && st_ivas->nCPE == 1 ) { @@ -223,7 +225,11 @@ ivas_error ivas_dec_setup( } } } +#ifdef ALIGN_SID_SIZE + else if ( ivas_total_brate == IVAS_SID_5k2 ) +#else else if ( ivas_total_brate == IVAS_SID_4k4 || ivas_total_brate == IVAS_SID_5k ) +#endif { switch ( st_ivas->sid_format ) { @@ -359,7 +365,11 @@ static ivas_error ivas_read_format( break; } } +#ifdef ALIGN_SID_SIZE + else if ( !st_ivas->bfi && ivas_total_brate == IVAS_SID_5k2 ) +#else else if ( !st_ivas->bfi && ivas_total_brate == IVAS_SID_4k4 ) +#endif { /* read IVAS format in SID frame */ idx = 0; @@ -412,27 +422,45 @@ static ivas_error ivas_read_format( return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Invalid value %c found in SID format field.", st_ivas->sid_format ); } +#ifdef ALIGN_SID_SIZE + if ( st_ivas->ivas_format == SBA_FORMAT ) + { + int16_t tc_mode_offset; + tc_mode_offset = (int16_t) ( ivas_total_brate / FRAMES_PER_SEC - 1 ); + idx = st_ivas->bit_stream[tc_mode_offset]; + // TBD: needs more work for HOA + if ( st_ivas->sba_analysis_order == 0 ) + { + st_ivas->sba_analysis_order = 1; + } + if ( idx == 1 ) + { + st_ivas->sba_mode = SBA_MODE_SPAR; + } + else + { + st_ivas->sba_mode = SBA_MODE_DIRAC; + } + } +#endif + /* reset bitstream handle to avoid BER detection after reading the 2400 kbps for ch0 */ st_ivas->bit_stream += ( *num_bits_read ); ( *num_bits_read ) = 0; } +#ifndef ALIGN_SID_SIZE else if ( !st_ivas->bfi && ivas_total_brate == IVAS_SID_5k ) { int16_t tc_mode_offset; tc_mode_offset = (int16_t) ( ivas_total_brate / FRAMES_PER_SEC - 1 ); idx = st_ivas->bit_stream[tc_mode_offset]; + // TBD: needs more work for HOA -#ifndef SBA_ORDER_BITSTREAM - if ( st_ivas->sba_order == 0 ) - { - st_ivas->sba_order = 1; - } -#else if ( st_ivas->sba_analysis_order == 0 ) { st_ivas->sba_analysis_order = 1; } -#endif + if ( idx == 0 ) { st_ivas->sid_format = SID_SBA_1TC; @@ -448,6 +476,7 @@ static ivas_error ivas_read_format( st_ivas->element_mode_init = IVAS_CPE_MDCT; } } +#endif else { /* In SID/NO_DATA frames, use the previous frame IVAS format */ @@ -526,29 +555,6 @@ ivas_error ivas_init_decoder_front( error = IVAS_ERR_OK; -#ifdef DEBUGGING - st_ivas->noClipping = 0; -#endif - - /* Custom loudspeaker layout structure */ - st_ivas->hLsSetupCustom = NULL; - - /* TD renderer HRTF data structure */ - st_ivas->hHrtfTD = NULL; - - /* Head track data structure */ - st_ivas->hHeadTrackData = NULL; - - /* Renderer configuration structure */ - st_ivas->hRenderConfig = NULL; - - /* HRTF binauralization latency in ns */ - st_ivas->binaural_latency_ns = 0; - -#ifdef DEBUGGING - st_ivas->hDecoderConfig->force_rend = -1; -#endif - /*-----------------------------------------------------------------* * Resets *-----------------------------------------------------------------*/ @@ -561,9 +567,16 @@ ivas_error ivas_init_decoder_front( st_ivas->mc_mode = MC_MODE_NONE; st_ivas->sba_mode = SBA_MODE_NONE; - st_ivas->hLimiter = NULL; - st_ivas->hoa_dec_mtx = NULL; + st_ivas->sba_dirac_stereo_flag = 0; + /* 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 @@ -710,58 +723,6 @@ ivas_error ivas_init_decoder( } } - /*-----------------------------------------------------------------* - * Dummy pointers to decoder handles - *-----------------------------------------------------------------*/ - - for ( i = 0; i < MAX_SCE; i++ ) - { - st_ivas->hSCE[i] = NULL; - } - - for ( i = 0; i < MAX_CPE; i++ ) - { - st_ivas->hCPE[i] = NULL; - } - - /* ISm metadata handles */ - for ( n = 0; n < MAX_NUM_OBJECTS; n++ ) - { - st_ivas->hIsmMetaData[n] = NULL; - } - - /* DirAC handle */ - st_ivas->hDirAC = NULL; - st_ivas->sba_dirac_stereo_flag = 0; - - /* SPAR handle */ - st_ivas->hSpar = NULL; - - /* MASA decoder structure */ - st_ivas->hMasa = NULL; - - /* Q metadata handle */ - st_ivas->hQMetaData = NULL; - - /* MCT handles */ - st_ivas->hMCT = NULL; - st_ivas->hParamMC = NULL; - - /* LFE handle */ - st_ivas->hLFE = NULL; - - /* renderers handles */ - st_ivas->hBinRenderer = NULL; /* fastconf binaural renderer */ - st_ivas->hDiracDecBin = NULL; /* parametric binaural renderer */ - st_ivas->hLsSetUpConversion = NULL; /* MC converter */ - st_ivas->hEFAPdata = NULL; /* EFAP handle */ - st_ivas->hVBAPdata = NULL; /* VBAP handle */ - st_ivas->hIsmRendererData = NULL; /* ISm renderer */ - st_ivas->hBinRendererTd = NULL; /* TD ISm binaural renderer */ - st_ivas->hMonoDmxRenderer = NULL; /* Mono downmix renderer */ - st_ivas->hHrtf = NULL; /* Crend hrtf data */ - st_ivas->hCrend = NULL; /* Crend renderer */ - /*-----------------------------------------------------------------* * Allocate and initalize SCE/CPE and other handles *-----------------------------------------------------------------*/ @@ -798,6 +759,7 @@ ivas_error ivas_init_decoder( { reset_indices_dec( st_ivas->hCPE[cpe_id]->hCoreCoder[n] ); } + /* init EFAP for custom LS output and set hTransSetup */ if ( output_config == AUDIO_CONFIG_LS_CUSTOM ) { @@ -844,11 +806,10 @@ ivas_error ivas_init_decoder( } else if ( st_ivas->ivas_format == SBA_FORMAT || st_ivas->ivas_format == MASA_FORMAT ) { + + if ( ( error = ivas_qmetadata_open( &( st_ivas->hQMetaData ) ) ) != IVAS_ERR_OK ) { - if ( ( error = ivas_qmetadata_open( &( st_ivas->hQMetaData ) ) ) != IVAS_ERR_OK ) - { - return error; - } + return error; } if ( st_ivas->ivas_format == MASA_FORMAT ) @@ -866,6 +827,7 @@ ivas_error ivas_init_decoder( { return error; } + if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_DEC && st_ivas->hOutSetup.is_loudspeaker_setup ) { if ( ( error = ivas_sba_get_hoa_dec_matrix( st_ivas->hOutSetup, &st_ivas->hoa_dec_mtx, st_ivas->hIntSetup.ambisonics_order ) ) != IVAS_ERR_OK ) @@ -873,9 +835,10 @@ ivas_error ivas_init_decoder( return error; } } -#ifndef SBA_ORDER_BITSTREAM - if ( ( error = ivas_dirac_sba_config( st_ivas->hQMetaData, &st_ivas->nchan_transport, &st_ivas->nSCE, &st_ivas->nCPE, &st_ivas->element_mode_init, ivas_total_brate, st_ivas->sba_order, st_ivas->sba_planar, - st_ivas->sba_mode, IVAS_MAX_NUM_BANDS - SPAR_DIRAC_SPLIT_START_BAND ) ) != IVAS_ERR_OK ) + +#ifdef HARMONIZE_SBA_NCHAN_TRANSPORT + if ( ( error = ivas_dirac_sba_config( st_ivas->hQMetaData, &st_ivas->nchan_transport, &st_ivas->nSCE, &st_ivas->nCPE, &st_ivas->element_mode_init, ivas_total_brate, st_ivas->sba_analysis_order, st_ivas->sba_mode, IVAS_MAX_NUM_BANDS - SPAR_DIRAC_SPLIT_START_BAND ) ) != IVAS_ERR_OK ) + #else if ( ( error = ivas_dirac_sba_config( st_ivas->hQMetaData, &st_ivas->nchan_transport, &st_ivas->nSCE, &st_ivas->nCPE, &st_ivas->element_mode_init, ivas_total_brate, st_ivas->sba_analysis_order, st_ivas->sba_planar, st_ivas->sba_mode, IVAS_MAX_NUM_BANDS - SPAR_DIRAC_SPLIT_START_BAND ) ) != IVAS_ERR_OK ) @@ -883,12 +846,14 @@ ivas_error ivas_init_decoder( { return error; } + if ( hDecoderConfig->output_config != AUDIO_CONFIG_FOA ) { if ( ( error = ivas_dirac_dec_open( st_ivas ) ) != IVAS_ERR_OK ) { return error; } + for ( k = 0; k < DIRAC_MAX_NBANDS; k++ ) { st_ivas->hSpar->dirac_to_spar_md_bands[k] = st_ivas->hDirAC->dirac_to_spar_md_bands[k]; @@ -901,20 +866,14 @@ ivas_error ivas_init_decoder( st_ivas->hSpar->enc_param_start_band = min( IVAS_MAX_NUM_BANDS, SPAR_DIRAC_SPLIT_START_BAND ); - ivas_dirac_config_bands( - band_grouping, - IVAS_MAX_NUM_BANDS, - (int16_t) ( st_ivas->hDecoderConfig->output_Fs * INV_CLDFB_BANDWIDTH + 0.5f ), - st_ivas->hSpar->dirac_to_spar_md_bands, - st_ivas->hQMetaData->useLowerBandRes, - st_ivas->hSpar->enc_param_start_band, - 0 ); + ivas_dirac_config_bands( band_grouping, IVAS_MAX_NUM_BANDS, (int16_t) ( st_ivas->hDecoderConfig->output_Fs * INV_CLDFB_BANDWIDTH + 0.5f ), + st_ivas->hSpar->dirac_to_spar_md_bands, st_ivas->hQMetaData->useLowerBandRes, st_ivas->hSpar->enc_param_start_band, 0 ); } } else { -#ifndef SBA_ORDER_BITSTREAM - if ( ( error = ivas_dirac_sba_config( st_ivas->hQMetaData, &st_ivas->nchan_transport, &st_ivas->nSCE, &st_ivas->nCPE, &st_ivas->element_mode_init, ivas_total_brate, st_ivas->sba_order, st_ivas->sba_planar, st_ivas->sba_mode, -1 ) ) != IVAS_ERR_OK ) +#ifdef HARMONIZE_SBA_NCHAN_TRANSPORT + if ( ( error = ivas_dirac_sba_config( st_ivas->hQMetaData, &st_ivas->nchan_transport, &st_ivas->nSCE, &st_ivas->nCPE, &st_ivas->element_mode_init, ivas_total_brate, st_ivas->sba_analysis_order, st_ivas->sba_mode, -1 ) ) != IVAS_ERR_OK ) #else if ( ( error = ivas_dirac_sba_config( st_ivas->hQMetaData, &st_ivas->nchan_transport, &st_ivas->nSCE, &st_ivas->nCPE, &st_ivas->element_mode_init, ivas_total_brate, st_ivas->sba_analysis_order, st_ivas->sba_planar, st_ivas->sba_mode, -1 ) ) != IVAS_ERR_OK ) #endif @@ -963,6 +922,7 @@ ivas_error ivas_init_decoder( { return error; } + reset_indices_dec( st_ivas->hSCE[sce_id]->hCoreCoder[0] ); } @@ -973,7 +933,6 @@ ivas_error ivas_init_decoder( return error; } - for ( n = 0; n < CPE_CHANNELS; n++ ) { reset_indices_dec( st_ivas->hCPE[cpe_id]->hCoreCoder[n] ); @@ -1044,7 +1003,6 @@ ivas_error ivas_init_decoder( return error; } - for ( n = 0; n < CPE_CHANNELS; n++ ) { reset_indices_dec( st_ivas->hCPE[cpe_id]->hCoreCoder[n] ); @@ -1066,12 +1024,12 @@ ivas_error ivas_init_decoder( return error; } } + if ( ( error = ivas_param_mc_dec_open( st_ivas ) ) != IVAS_ERR_OK ) { return error; } - for ( cpe_id = 0; cpe_id < st_ivas->nCPE; cpe_id++ ) { if ( ( error = create_cpe_dec( st_ivas, cpe_id, ivas_total_brate / ( st_ivas->nSCE + st_ivas->nCPE ) ) ) != IVAS_ERR_OK ) @@ -1079,7 +1037,6 @@ ivas_error ivas_init_decoder( return error; } - for ( n = 0; n < CPE_CHANNELS; n++ ) { reset_indices_dec( st_ivas->hCPE[cpe_id]->hCoreCoder[n] ); @@ -1108,7 +1065,6 @@ ivas_error ivas_init_decoder( return error; } - st_ivas->sba_dirac_stereo_flag = ( st_ivas->nchan_transport == 1 && output_config == AUDIO_CONFIG_STEREO ); if ( st_ivas->renderer_type != RENDERER_DISABLE && st_ivas->renderer_type != RENDERER_MCMASA_MONO_STEREO ) @@ -1149,6 +1105,7 @@ ivas_error ivas_init_decoder( return error; } } + reset_indices_dec( st_ivas->hSCE[sce_id]->hCoreCoder[0] ); } @@ -1157,6 +1114,7 @@ ivas_error ivas_init_decoder( if ( st_ivas->hOutSetup.separateChannelEnabled ) { st_ivas->element_mode_init = IVAS_CPE_MDCT; + if ( ( error = create_cpe_dec( st_ivas, cpe_id, ivas_total_brate - st_ivas->hSCE[0]->element_brate ) ) != IVAS_ERR_OK ) { return error; @@ -1165,11 +1123,13 @@ ivas_error ivas_init_decoder( else { st_ivas->element_mode_init = IVAS_CPE_MDCT; + if ( ( error = create_cpe_dec( st_ivas, cpe_id, ivas_total_brate / ( st_ivas->nSCE + st_ivas->nCPE ) ) ) != IVAS_ERR_OK ) { return error; } } + for ( n = 0; n < CPE_CHANNELS; n++ ) { reset_indices_dec( st_ivas->hCPE[cpe_id]->hCoreCoder[n] ); @@ -1257,6 +1217,7 @@ ivas_error ivas_init_decoder( { return error; } + if ( st_ivas->hRenderConfig->roomAcoustics.late_reverb_on ) { if ( ( st_ivas->hCrend = (CREND_HANDLE) count_malloc( sizeof( CREND_DATA ) ) ) == NULL ) @@ -1363,9 +1324,8 @@ ivas_error ivas_init_decoder( * Allocate and initialize limiter struct *-----------------------------------------------------------------*/ - { - st_ivas->hLimiter = ivas_limiter_open( hDecoderConfig->nchan_out, output_Fs ); - } + st_ivas->hLimiter = ivas_limiter_open( hDecoderConfig->nchan_out, output_Fs ); + return error; } @@ -1547,9 +1507,9 @@ void ivas_initialize_handles_dec( st_ivas->hCPE[i] = NULL; } - st_ivas->nSCE = 0; - st_ivas->nCPE = 0; + st_ivas->bit_stream = NULL; st_ivas->mem_hp20_out = NULL; + st_ivas->hLimiter = NULL; /* ISM metadata handles */ for ( i = 0; i < MAX_NUM_OBJECTS; i++ ) @@ -1558,7 +1518,6 @@ void ivas_initialize_handles_dec( } /* spatial coding handles */ - st_ivas->hIsmRendererData = NULL; st_ivas->hDirAC = NULL; st_ivas->hSpar = NULL; st_ivas->hMasa = NULL; @@ -1578,11 +1537,12 @@ void ivas_initialize_handles_dec( st_ivas->hMonoDmxRenderer = NULL; st_ivas->hCrend = NULL; st_ivas->hHrtf = NULL; + st_ivas->hoa_dec_mtx = NULL; st_ivas->hHeadTrackData = NULL; st_ivas->hHrtfTD = NULL; - st_ivas->hLimiter = NULL; st_ivas->hLsSetupCustom = NULL; + st_ivas->hRenderConfig = NULL; return; } @@ -1850,7 +1810,6 @@ void ivas_init_dec_get_num_cldfb_instances( { *numCldfbAnalyses = st_ivas->hSpar->hFbMixer->fb_cfg->num_in_chans; - if ( st_ivas->hOutSetup.is_loudspeaker_setup && st_ivas->renderer_type == RENDERER_DIRAC ) { *numCldfbSyntheses = st_ivas->hOutSetup.nchan_out_woLFE; @@ -2056,11 +2015,10 @@ static ivas_error doSanityChecks_IVAS( #endif #ifdef DEBUGGING - if ( ( st_ivas->hHrtfTD != NULL || st_ivas->hDecoderConfig->force_rend == FORCE_TD_RENDERER ) && ( ( st_ivas->ivas_format != MC_FORMAT && st_ivas->ivas_format != ISM_FORMAT ) || output_config != AUDIO_CONFIG_BINAURAL || ( 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 ) ) ) + if ( ( st_ivas->hDecoderConfig->Opt_HRTF_binary || st_ivas->hDecoderConfig->force_rend == FORCE_TD_RENDERER ) && ( ( st_ivas->ivas_format != MC_FORMAT && st_ivas->ivas_format != ISM_FORMAT ) || output_config != AUDIO_CONFIG_BINAURAL || ( 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 ) ) ) #else - if ( st_ivas->hHrtfTD != NULL && ( ( st_ivas->ivas_format != MC_FORMAT && st_ivas->ivas_format != ISM_FORMAT ) || output_config != AUDIO_CONFIG_BINAURAL || ( st_ivas->ivas_format == ISM_FORMAT && st_ivas->ism_mode == ISM_MODE_PARAM ) ) ) + if ( st_ivas->hDecoderConfig->Opt_HRTF_binary && ( ( st_ivas->ivas_format != MC_FORMAT && st_ivas->ivas_format != ISM_FORMAT ) || output_config != AUDIO_CONFIG_BINAURAL || ( st_ivas->ivas_format == ISM_FORMAT && st_ivas->ism_mode == ISM_MODE_PARAM ) ) ) #endif - { return IVAS_ERROR( IVAS_ERR_INVALID_OUTPUT_FORMAT, "Incorrect output configuration: Time Domain object renderer not supported in this configuration" ); } diff --git a/lib_dec/ivas_ism_metadata_dec.c b/lib_dec/ivas_ism_metadata_dec.c index 9d940705f3..dee9b6489f 100644 --- a/lib_dec/ivas_ism_metadata_dec.c +++ b/lib_dec/ivas_ism_metadata_dec.c @@ -78,7 +78,11 @@ ivas_error ivas_ism_metadata_dec( wmops_sub_start( "ism_meta_dec" ); +#ifdef ALIGN_SID_SIZE + if ( ism_total_brate == IVAS_SID_5k2 || ism_total_brate == FRAME_NO_DATA ) +#else if ( ism_total_brate == IVAS_SID_4k4 || ism_total_brate == FRAME_NO_DATA ) +#endif { /* no metadata decoding in CNG */ for ( ch = 0; ch < *nchan_transport; ch++ ) @@ -87,7 +91,11 @@ ivas_error ivas_ism_metadata_dec( } /* set padding bits as metadata bits to keep later bitrate checks valid */ +#ifdef ALIGN_SID_SIZE + nb_bits_metadata[0] = ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC; +#else nb_bits_metadata[0] = ( IVAS_SID_4k4 - SID_2k40 ) / FRAMES_PER_SEC; +#endif #ifdef DEBUGGING /* sanity check */ diff --git a/lib_dec/ivas_ism_param_dec.c b/lib_dec/ivas_ism_param_dec.c index 108d406845..d394c3c729 100644 --- a/lib_dec/ivas_ism_param_dec.c +++ b/lib_dec/ivas_ism_param_dec.c @@ -1027,7 +1027,11 @@ ivas_error ivas_ism_dec_config( /* store last frame ISM mode */ last_ism_mode = st_ivas->ism_mode; +#ifdef ALIGN_SID_SIZE + if ( !st_ivas->bfi && ivas_total_brate != IVAS_SID_5k2 && ivas_total_brate != FRAME_NO_DATA ) +#else if ( !st_ivas->bfi && ivas_total_brate != IVAS_SID_4k4 && ivas_total_brate != FRAME_NO_DATA ) +#endif { /* select ISM format mode */ st_ivas->ism_mode = ivas_ism_mode_select( num_obj, ivas_total_brate ); @@ -1052,7 +1056,11 @@ ivas_error ivas_ism_dec_config( } } } +#ifdef ALIGN_SID_SIZE + else if ( !st_ivas->bfi && ivas_total_brate == IVAS_SID_5k2 ) +#else else if ( !st_ivas->bfi && ivas_total_brate == IVAS_SID_4k4 ) +#endif { st_ivas->nchan_transport = num_obj; } diff --git a/lib_dec/ivas_masa_dec.c b/lib_dec/ivas_masa_dec.c index 91b79a614e..b4aa18f2a1 100644 --- a/lib_dec/ivas_masa_dec.c +++ b/lib_dec/ivas_masa_dec.c @@ -115,7 +115,11 @@ ivas_error ivas_masa_decode( *nb_bits_read = 0; next_bit_pos_orig = st->next_bit_pos; +#ifdef ALIGN_SID_SIZE + if ( masa_brate == IVAS_SID_5k2 ) +#else if ( masa_brate == IVAS_SID_4k4 ) +#endif { st->next_bit_pos = (int16_t) ( ( masa_brate / FRAMES_PER_SEC ) - 1 - SID_FORMAT_NBITS ); } @@ -124,7 +128,11 @@ ivas_error ivas_masa_decode( st->next_bit_pos = (int16_t) ( ( masa_brate / FRAMES_PER_SEC ) - 1 ); } +#ifdef ALIGN_SID_SIZE + if ( !st->bfi && ivas_total_brate > IVAS_SID_5k2 ) +#else if ( !st->bfi && ivas_total_brate > IVAS_SID_4k4 ) +#endif { if ( !( ivas_format == MC_FORMAT && st_ivas->mc_mode == MC_MODE_MCMASA ) ) { @@ -216,7 +224,11 @@ ivas_error ivas_masa_decode( replicate_subframes( hQMetaData ); } } +#ifdef ALIGN_SID_SIZE + else if ( !st->bfi && ivas_format == MASA_FORMAT && ivas_total_brate == IVAS_SID_5k2 ) +#else else if ( !st->bfi && ivas_format == MASA_FORMAT && ivas_total_brate == IVAS_SID_4k4 ) +#endif { if ( hQMetaData->q_direction == NULL ) { @@ -229,7 +241,11 @@ ivas_error ivas_masa_decode( ivas_masa_set_elements( ivas_total_brate, st_ivas->mc_mode, st_ivas->nchan_transport, hQMetaData, &st_ivas->element_mode_init, &st_ivas->nSCE, &st_ivas->nCPE ); +#ifdef ALIGN_SID_SIZE + hQMetaData->metadata_max_bits = ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC; +#else hQMetaData->metadata_max_bits = ( IVAS_SID_4k4 - SID_2k40 ) / FRAMES_PER_SEC; +#endif if ( ( error = ivas_qmetadata_allocate_memory( hQMetaData, 5, 1, 0 ) ) != IVAS_ERR_OK ) { @@ -285,7 +301,11 @@ ivas_error ivas_masa_decode( { st_ivas->hCPE[0]->hStereoDft->hConfig->force_mono_transmission = ivas_total_brate < MASA_STEREO_MIN_BITRATE ? 1 : 0; +#ifdef ALIGN_SID_SIZE + if ( ivas_total_brate <= IVAS_SID_5k2 ) +#else if ( ivas_total_brate <= IVAS_SID_4k4 ) +#endif { st_ivas->hCPE[0]->hStereoDft->hConfig->force_mono_transmission = 0; } @@ -295,11 +315,19 @@ ivas_error ivas_masa_decode( { st_ivas->hCPE[0]->hCoreCoder[0]->masa_sid_format = 0; +#ifdef ALIGN_SID_SIZE + if ( st_ivas->hDecoderConfig->last_ivas_total_brate <= IVAS_SID_5k2 ) +#else if ( st_ivas->hDecoderConfig->last_ivas_total_brate <= IVAS_SID_4k4 ) +#endif { st_ivas->hCPE[0]->hCoreCoder[0]->masa_sid_format = 1; +#ifdef ALIGN_SID_SIZE + if ( ivas_total_brate >= IVAS_SID_5k2 ) +#else if ( ivas_total_brate >= IVAS_SID_4k4 ) +#endif { st_ivas->hCPE[0]->element_brate = ivas_total_brate; } @@ -479,7 +507,11 @@ void ivas_masa_prerender( const int16_t output_frame /* i : output frame length per channel */ ) { +#ifdef ALIGN_SID_SIZE + if ( st_ivas->ivas_format == MASA_FORMAT && st_ivas->nchan_transport == 2 && st_ivas->hDecoderConfig->ivas_total_brate < MASA_STEREO_MIN_BITRATE && st_ivas->hDecoderConfig->ivas_total_brate > IVAS_SID_5k2 ) +#else if ( st_ivas->ivas_format == MASA_FORMAT && st_ivas->nchan_transport == 2 && st_ivas->hDecoderConfig->ivas_total_brate < MASA_STEREO_MIN_BITRATE && st_ivas->hDecoderConfig->ivas_total_brate > IVAS_SID_4k4 ) +#endif { if ( st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_EXTERNAL ) { diff --git a/lib_dec/ivas_mc_param_dec.c b/lib_dec/ivas_mc_param_dec.c index e1df8f2a7d..29e2ce4002 100644 --- a/lib_dec/ivas_mc_param_dec.c +++ b/lib_dec/ivas_mc_param_dec.c @@ -263,7 +263,6 @@ ivas_error ivas_param_mc_dec_open( return error; } - /* convert the ls conv dmx matrix into column order matrix format (nchan_out_cldfb x nchan_out) */ if ( hParamMC->synthesis_conf == PARAM_MC_SYNTH_LS_CONV_COV || hParamMC->synthesis_conf == PARAM_MC_SYNTH_MONO_STEREO ) { @@ -297,6 +296,7 @@ ivas_error ivas_param_mc_dec_open( matrix_product( hParamMC->ls_conv_dmx_matrix, nchan_out_cov, nchan_out_transport, 0, ivas_param_mc_conf[config_index].dmx_fac, nchan_out_transport, nchan_transport, 0, proto_matrix ); + if ( hParamMC->synthesis_conf == PARAM_MC_SYNTH_MONO_STEREO ) { proto_mtx_norm = 1.f; diff --git a/lib_dec/ivas_mct_dec_mct.c b/lib_dec/ivas_mct_dec_mct.c index 00eff03dac..ec19acb602 100644 --- a/lib_dec/ivas_mct_dec_mct.c +++ b/lib_dec/ivas_mct_dec_mct.c @@ -283,7 +283,11 @@ void mctStereoIGF_dec( /* stereo IGF decoding */ assert( ( sts[0]->core == sts[1]->core ) || ( hMCT->hBlockData[b]->hStereoMdct->mdct_stereo_mode[0] == SMDCT_DUAL_MONO ) ); +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE + decoder_tcx_IGF_stereo( sts, hMCT->hBlockData[b]->hStereoMdct, hMCT->hBlockData[b]->mask, p_x, L_frame[0], left_rect[0], k, bfi, 1 /* <- is_mct */ ); +#else decoder_tcx_IGF_stereo( sts, hMCT->hBlockData[b]->hStereoMdct, hMCT->hBlockData[b]->mask, p_x, L_frame[0], left_rect[0], k, bfi ); +#endif } else { diff --git a/lib_dec/ivas_mdct_core_dec.c b/lib_dec/ivas_mdct_core_dec.c index ed5114c651..d05024c565 100644 --- a/lib_dec/ivas_mdct_core_dec.c +++ b/lib_dec/ivas_mdct_core_dec.c @@ -102,7 +102,7 @@ static void dec_prm_tcx_sidebits( int16_t p_param[NB_DIV], /* o : pointer to parameters for next round of bs reading*/ int16_t nTnsBitsTCX10[NB_DIV], /* o : number of TNS bits per TCX10 subframe */ Decoder_State *st0, /* i/o: core decoder state handle - for bitstream */ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE const int16_t MCT_flag, #endif const int16_t ch /* i : channel */ @@ -134,7 +134,7 @@ static void dec_prm_tcx_sidebits( *--------------------------------------------------------------------------------*/ /* Modes (ACE_GC, ACE_UC, TCX20, TCX10...) */ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE getTCXMode( st, st0, MCT_flag ); #else getTCXMode( st, st0 ); @@ -381,7 +381,7 @@ void ivas_mdct_dec_side_bits_frame_channel( tmp = 3; } -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE dec_prm_tcx_sidebits( param[ch], st, ( ( st->element_mode == IVAS_CPE_MDCT && !MCT_flag ) ? sts[0]->hTcxDec->tnsActive : NULL ), p_param[ch], nTnsBitsTCX10[ch], st0, MCT_flag, tmp ); #else dec_prm_tcx_sidebits( param[ch], st, ( ( st->element_mode == IVAS_CPE_MDCT && !MCT_flag ) ? sts[0]->hTcxDec->tnsActive : NULL ), p_param[ch], nTnsBitsTCX10[ch], st0, tmp ); @@ -481,7 +481,7 @@ void ivas_mdct_core_invQ( const int16_t *prm_sqQ; int16_t L_frameTCX_global[CPE_CHANNELS]; float tmp_ms_sig[CPE_CHANNELS][N_MAX]; -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE float concealment_noise[CPE_CHANNELS][L_FRAME48k]; TONALMDCTCONC_NOISE_GEN_MODE noise_gen_mode_bfi; #endif @@ -490,7 +490,7 @@ void ivas_mdct_core_invQ( sts = hCPE->hCoreCoder; bfi = sts[0]->bfi; -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE noise_gen_mode_bfi = -1; #endif @@ -514,7 +514,7 @@ void ivas_mdct_core_invQ( sts[0]->core, sts[1]->core, sts[0]->igf, L_frameTCX[0], 0, sts[0]->last_core, sts[1]->last_core, 1 ); } -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE if ( bfi ) { if ( sts[0]->core == sts[1]->core ) @@ -728,15 +728,11 @@ void ivas_mdct_core_invQ( } nf_seed = 0; -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT - decoder_tcx_invQ( st, prm[ch], Aq[ch], Aind[ch], L_spec[ch], L_frame[ch], L_frameTCX[ch], x[ch][k], NULL, xn_buf, &fUseTns[ch][k], &tnsData[ch][k], &gain_tcx, &prm_sqQ, &nf_seed, bfi, isMCT, k ); -#else decoder_tcx_invQ( st, prm[ch], Aq[ch], Aind[ch], L_spec[ch], L_frame[ch], L_frameTCX[ch], x[ch][k], NULL, xn_buf, &fUseTns[ch][k], &tnsData[ch][k], &gain_tcx, &prm_sqQ, &nf_seed, bfi, k ); -#endif mvr2r( x[ch][k], x_0[ch][k], L_frameTCX[ch] ); -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE if ( bfi && !isMCT ) { TonalMdctConceal_create_concealment_noise( concealment_noise[ch], hCPE, L_frameTCX[ch], L_frame[ch], ch, k, st->core, st->hTcxDec->cummulative_damping_tcx, noise_gen_mode_bfi ); @@ -861,7 +857,7 @@ void ivas_mdct_core_reconstruct( TonalMDCTConceal_SaveTimeSignal( st->hTonalMDCTConc, synthFB, L_frameTCX[ch] ); } -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE decoder_tcx_post( st, synth, synthFB, NULL, bfi, isMCT ); #else decoder_tcx_post( st, synth, synthFB, NULL, bfi ); @@ -873,7 +869,7 @@ void ivas_mdct_core_reconstruct( /* PLC: [TCX: TD PLC] */ if ( isMCT ) { -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE con_tcx( st, &synthFB[0], -1.f, NULL, 0, NULL ); #else con_tcx( st, &synthFB[0], -1.f, NULL, 0 ); @@ -881,7 +877,7 @@ void ivas_mdct_core_reconstruct( } else { -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE con_tcx( st, &synthFB[0], hCPE->hStereoMdct->lastCoh, &sts[0]->seed_acelp, ( sts[1]->core != ACELP_CORE ) ? 1 : 0, &st->hFdCngDec->hFdCngCom->A_cng[0] ); #else con_tcx( st, &synthFB[0], hCPE->hStereoMdct->lastCoh, &sts[0]->seed_acelp, ( sts[1]->core != ACELP_CORE ) ? 1 : 0 ); @@ -1064,34 +1060,14 @@ void ivas_mdct_core_tns_ns( { sns_interpolate_scalefactors( &sns_int_scf[0], &Aq[ch][k * M], DEC ); -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE if ( isMCT && st->hTonalMDCTConc != NULL && ( ( k + 1 ) == nSubframes[ch] ) ) #else if ( isMCT && st->hTonalMDCTConc != NULL ) #endif { -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT - int16_t infoIGFStartLine; - - if ( st->igf == 0 ) - { - if ( st->narrowBand == 0 ) - { - /* minimum needed for output with sampling rates lower then the - nominal sampling rate */ - infoIGFStartLine = min( L_frameTCX[ch], L_frame[ch] ); - } - else - { - infoIGFStartLine = L_frameTCX[ch]; - } - } - else - { - infoIGFStartLine = min( st->hIGFDec->infoIGFStartLine, L_frameTCX[ch] ); - } - - TonalMDCTConceal_SaveFreqSignal( st->hTonalMDCTConc, x[ch][k], L_frameTCX[ch], L_frame[ch], &sns_int_scf[0], infoIGFStartLine ); +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE + TonalMDCTConceal_SaveFreqSignal( st->hTonalMDCTConc, x[ch][k], L_frameTCX[ch], L_frame[ch], &sns_int_scf[0], get_igf_startline( st, L_frame[ch], L_frameTCX[ch] ) ); #else TonalMDCTConceal_SaveFreqSignal( st->hTonalMDCTConc, x[ch][k], L_frameTCX[ch], L_frame[ch], &sns_int_scf[0] ); #endif @@ -1101,17 +1077,18 @@ void ivas_mdct_core_tns_ns( { if ( st->hTonalMDCTConc != NULL ) { -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT - if ( st->hTcxDec->cummulative_damping_tcx != 1.f ) +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE + if ( !isMCT && st->hTcxDec->cummulative_damping_tcx != 1.f ) { - float *scf_last; - float *scf_bg; - float fade_in; - float fade_out; + float *scf_last, *scf_bg; + float fade_in, fade_out; scf_last = &st->hTonalMDCTConc->lastBlockData.scaleFactors[0]; scf_bg = &st->hTonalMDCTConc->scaleFactorsBackground[0]; - fade_out = st->hTcxDec->cummulative_damping_tcx; + + st->hTonalMDCTConc->scf_fadeout *= 0.95f; + + fade_out = st->hTonalMDCTConc->scf_fadeout; fade_in = 1 - fade_out; for ( int16_t i = 0; i < st->hTonalMDCTConc->nScaleFactors; i++ ) @@ -1121,6 +1098,7 @@ void ivas_mdct_core_tns_ns( } else { + st->hTonalMDCTConc->scf_fadeout = 1.0f; mvr2r( st->hTonalMDCTConc->lastBlockData.scaleFactors, &sns_int_scf[0], st->hTonalMDCTConc->nScaleFactors ); } #else diff --git a/lib_dec/ivas_out_setup_conversion.c b/lib_dec/ivas_out_setup_conversion.c index c8008fa129..9ed27e56c3 100644 --- a/lib_dec/ivas_out_setup_conversion.c +++ b/lib_dec/ivas_out_setup_conversion.c @@ -312,8 +312,6 @@ ivas_error ivas_ls_setup_conversion_open( int32_t output_Fs; int16_t nchan_out; - wmops_sub_start( "LS_Renderer" ); - output_Fs = st_ivas->hDecoderConfig->output_Fs; nchan_out = st_ivas->hDecoderConfig->nchan_out; output_frame = (int16_t) ( output_Fs / FRAMES_PER_SEC ); @@ -1072,8 +1070,6 @@ void ivas_ls_setup_conversion_process_mdct_param_mc( } } - wmops_sub_end(); - return; } diff --git a/lib_dec/ivas_qmetadata_dec.c b/lib_dec/ivas_qmetadata_dec.c index 628e4ca6b8..15f33799d6 100644 --- a/lib_dec/ivas_qmetadata_dec.c +++ b/lib_dec/ivas_qmetadata_dec.c @@ -721,17 +721,32 @@ int16_t ivas_qmetadata_dec_sid_decode( { if ( sba_mode == SBA_MODE_SPAR ) { +#ifdef ALIGN_SID_SIZE + /* TODO: still use old sid frame size to keep bitexactness */ + metadata_sid_bits = (int16_t) ( 5000 /*IVAS_SID_5k2*/ - SID_2k40 ) / FRAMES_PER_SEC - ( SPAR_DTX_BANDS * 18 ) - 1; /* -1 for inactive mode header bit*/ +#else metadata_sid_bits = (int16_t) ( IVAS_SID_5k - SID_2k40 ) / FRAMES_PER_SEC - ( SPAR_DTX_BANDS * 18 ) - 1; /* -1 for inactive mode header bit*/ +#endif } else { /* keep 13.2 and 16.4 sid bitrate as 4.4 kbps for now*/ +#ifdef ALIGN_SID_SIZE + /* TODO: still use old sid frame size to keep bitexactness */ + metadata_sid_bits = ( 4400 /*IVAS_SID_5k2*/ - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS; +#else metadata_sid_bits = ( IVAS_SID_4k4 - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS; +#endif } } else { +#ifdef ALIGN_SID_SIZE + /* TODO: still use old sid frame size to keep bitexactness */ + metadata_sid_bits = ( 4400 /*IVAS_SID_5k2*/ - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS; +#else metadata_sid_bits = ( IVAS_SID_4k4 - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS; +#endif } start_index = *index; @@ -850,6 +865,20 @@ int16_t ivas_qmetadata_dec_sid_decode( } } } +#ifdef ALIGN_SID_SIZE + /* TODO: temporary hack to keep BE */ + if ( ivas_format == SBA_FORMAT ) + { + if ( sba_mode != SBA_MODE_SPAR ) + { + metadata_sid_bits = ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS - 1; /* -1 for spar/dirac indicator*/ + } + } + else + { + metadata_sid_bits = ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS; + } +#endif /*Read filling bits*/ while ( start_index - *index < metadata_sid_bits ) @@ -860,9 +889,9 @@ int16_t ivas_qmetadata_dec_sid_decode( #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 ); + 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++ ) { diff --git a/lib_dec/ivas_sba_dec.c b/lib_dec/ivas_sba_dec.c index 4aaddd028b..6d91bd23f4 100644 --- a/lib_dec/ivas_sba_dec.c +++ b/lib_dec/ivas_sba_dec.c @@ -85,13 +85,15 @@ ivas_error ivas_sba_dec_reconfigure( numCldfbAnalyses = 0; sba_total_brate = ivas_total_brate; - nSCE_old = st_ivas->nSCE; nCPE_old = st_ivas->nCPE; nchan_transport_old = st_ivas->nchan_transport; sba_dirac_stereo_flag_old = st_ivas->sba_dirac_stereo_flag; -#ifndef SBA_ORDER_BITSTREAM - ivas_sba_config( sba_total_brate, st_ivas->sba_order, -1, &nchan_transport, st_ivas->sba_planar, &st_ivas->nSCE, &st_ivas->nCPE, &st_ivas->element_mode_init, st_ivas->sba_mode ); + + st_ivas->sba_analysis_order = ivas_sba_get_analysis_order( ivas_total_brate, st_ivas->sba_order ); + +#ifdef HARMONIZE_SBA_NCHAN_TRANSPORT + ivas_sba_config( sba_total_brate, st_ivas->sba_analysis_order, -1, &nchan_transport, st_ivas->sba_planar, &st_ivas->nSCE, &st_ivas->nCPE, &st_ivas->element_mode_init ); #else ivas_sba_config( sba_total_brate, st_ivas->sba_analysis_order, -1, &nchan_transport, st_ivas->sba_planar, &st_ivas->nSCE, &st_ivas->nCPE, &st_ivas->element_mode_init, st_ivas->sba_mode ); #endif @@ -110,8 +112,9 @@ ivas_error ivas_sba_dec_reconfigure( if ( st_ivas->sba_mode != SBA_MODE_SPAR ) { st_ivas->sba_dirac_stereo_flag = ( st_ivas->nchan_transport == 1 && st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_STEREO ); -#ifndef SBA_ORDER_BITSTREAM - if ( ( error = ivas_dirac_sba_config( st_ivas->hQMetaData, &st_ivas->nchan_transport, &st_ivas->nSCE, &st_ivas->nCPE, &st_ivas->element_mode_init, ivas_total_brate, st_ivas->sba_order, st_ivas->sba_planar, st_ivas->sba_mode, -1 ) ) != IVAS_ERR_OK ) + +#ifdef HARMONIZE_SBA_NCHAN_TRANSPORT + if ( ( error = ivas_dirac_sba_config( st_ivas->hQMetaData, &st_ivas->nchan_transport, &st_ivas->nSCE, &st_ivas->nCPE, &st_ivas->element_mode_init, ivas_total_brate, st_ivas->sba_analysis_order, st_ivas->sba_mode, -1 ) ) != IVAS_ERR_OK ) #else if ( ( error = ivas_dirac_sba_config( st_ivas->hQMetaData, &st_ivas->nchan_transport, &st_ivas->nSCE, &st_ivas->nCPE, &st_ivas->element_mode_init, ivas_total_brate, st_ivas->sba_analysis_order, st_ivas->sba_planar, st_ivas->sba_mode, -1 ) ) != IVAS_ERR_OK ) #endif @@ -122,15 +125,13 @@ ivas_error ivas_sba_dec_reconfigure( else { int16_t sba_order_internal; -#ifndef SBA_ORDER_BITSTREAM - sba_order_internal = min( st_ivas->sba_order, IVAS_MAX_SBA_ORDER ); -#else + sba_order_internal = min( st_ivas->sba_analysis_order, IVAS_MAX_SBA_ORDER ); -#endif ivas_spar_config( st_ivas->hDecoderConfig->ivas_total_brate, sba_order_internal, &st_ivas->nchan_transport, &st_ivas->nSCE, &st_ivas->nCPE, &st_ivas->hSpar->core_nominal_brate, st_ivas->sid_format ); -#ifndef SBA_ORDER_BITSTREAM - if ( ( error = ivas_dirac_sba_config( st_ivas->hQMetaData, &st_ivas->nchan_transport, &st_ivas->nSCE, &st_ivas->nCPE, &st_ivas->element_mode_init, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->sba_order, st_ivas->sba_planar, - st_ivas->sba_mode, IVAS_MAX_NUM_BANDS - SPAR_DIRAC_SPLIT_START_BAND ) ) != IVAS_ERR_OK ) + +#ifdef HARMONIZE_SBA_NCHAN_TRANSPORT + if ( ( error = ivas_dirac_sba_config( st_ivas->hQMetaData, &st_ivas->nchan_transport, &st_ivas->nSCE, &st_ivas->nCPE, &st_ivas->element_mode_init, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->sba_analysis_order, st_ivas->sba_mode, IVAS_MAX_NUM_BANDS - SPAR_DIRAC_SPLIT_START_BAND ) ) != IVAS_ERR_OK ) + #else if ( ( error = ivas_dirac_sba_config( st_ivas->hQMetaData, &st_ivas->nchan_transport, &st_ivas->nSCE, &st_ivas->nCPE, &st_ivas->element_mode_init, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->sba_analysis_order, st_ivas->sba_planar, st_ivas->sba_mode, IVAS_MAX_NUM_BANDS - SPAR_DIRAC_SPLIT_START_BAND ) ) != IVAS_ERR_OK ) @@ -140,8 +141,11 @@ ivas_error ivas_sba_dec_reconfigure( } } - if ( st_ivas->renderer_type != RENDERER_DISABLE && st_ivas->renderer_type != RENDERER_SBA_LINEAR_DEC && - ( last_ivas_total_brate > IVAS_SID_4k4 || nchan_transport != nchan_transport_old ) && ( st_ivas->sba_mode != SBA_MODE_SPAR ) ) +#ifdef ALIGN_SID_SIZE + if ( st_ivas->renderer_type != RENDERER_DISABLE && st_ivas->renderer_type != RENDERER_SBA_LINEAR_DEC && ( last_ivas_total_brate > IVAS_SID_5k2 || nchan_transport != nchan_transport_old ) && ( st_ivas->sba_mode != SBA_MODE_SPAR ) ) +#else + if ( st_ivas->renderer_type != RENDERER_DISABLE && st_ivas->renderer_type != RENDERER_SBA_LINEAR_DEC && ( last_ivas_total_brate > IVAS_SID_4k4 || nchan_transport != nchan_transport_old ) && ( st_ivas->sba_mode != SBA_MODE_SPAR ) ) +#endif { if ( st_ivas->hDirAC != NULL ) { @@ -513,7 +517,11 @@ ivas_error ivas_sba_dec_reconfigure( } /* special case, if the decoder goes from 1TC DTX to 2TC active frame (in case the bitstream started with an SBA SID frame), allocate DTX memories */ +#ifdef ALIGN_SID_SIZE + if ( last_ivas_total_brate <= IVAS_SID_5k2 && st_ivas->nCPE >= 1 ) +#else if ( last_ivas_total_brate <= IVAS_SID_4k4 && st_ivas->nCPE >= 1 ) +#endif { if ( ( error = initMdctStereoDtxData( st_ivas->hCPE[0] ) ) != IVAS_ERR_OK ) { @@ -557,47 +565,21 @@ ivas_error ivas_sba_dec_reconfigure( /*-------------------------------------------------------------------* * ivas_sba_upmixer_renderer() * - * SBA upmix rendering + * SBA upmix & rendering *-------------------------------------------------------------------*/ void ivas_sba_upmixer_renderer( Decoder_Struct *st_ivas, /* i/o: IVAS decoder struct */ float output[][L_FRAME48k], /* i/o: transport/output audio channels */ - const int16_t nchan_remapped, /* i : num channels after remapping of TCs */ const int16_t output_frame /* i : output frame length */ ) { - int16_t i, ch, nchan_out; + int16_t i, nchan_internal; float temp; - int16_t nchan_internal; wmops_sub_start( "ivas_sba_upmixer_renderer" ); -#ifndef SBA_ORDER_BITSTREAM - nchan_internal = ivas_sba_get_nchan_metadata( st_ivas->sba_order ); -#else - nchan_internal = ivas_sba_get_nchan_metadata( st_ivas->sba_analysis_order ); -#endif - nchan_out = st_ivas->hDecoderConfig->nchan_out; - for ( ch = 0; ch < nchan_remapped; ch++ ) - { - for ( i = 0; i < output_frame; i++ ) - { - temp = output[ch][i]; - temp = floorf( temp + 0.5f ); - - if ( temp > MAX16B_FLT ) - { - temp = MAX16B_FLT; - } - else if ( temp < ( -1.0f * PCM16_TO_FLT_FAC ) ) - { - temp = ( -1.0f * PCM16_TO_FLT_FAC ); - } - temp *= ( 1.0f / PCM16_TO_FLT_FAC ); - output[ch][i] = temp; - } - } + nchan_internal = ivas_sba_get_nchan_metadata( st_ivas->sba_analysis_order ); if ( st_ivas->nchan_transport >= 3 ) { @@ -618,21 +600,12 @@ void ivas_sba_upmixer_renderer( ivas_sba_linear_renderer( output, output_frame, st_ivas->hIntSetup.nchan_out_woLFE, st_ivas->hDecoderConfig->output_config, st_ivas->hOutSetup, st_ivas->hoa_dec_mtx ); } - for ( ch = 0; ch < nchan_out; ch++ ) - { - for ( i = 0; i < output_frame; i++ ) - { - output[ch][i] = output[ch][i] * PCM16_TO_FLT_FAC; - } - } - wmops_sub_end(); return; } - /*-------------------------------------------------------------------* * ivas_sba_mix_matrix_determiner() * @@ -640,15 +613,15 @@ void ivas_sba_upmixer_renderer( *-------------------------------------------------------------------*/ void ivas_sba_mix_matrix_determiner( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder struct */ + SPAR_DEC_HANDLE hSpar, /* i/o: SPAR decoder handle */ float output[][L_FRAME48k], /* i/o: transport/output audio channels */ + const int16_t bfi, /* i : BFI flag */ const int16_t nchan_remapped, /* i : num channels after remapping of TCs */ const int16_t output_frame /* i : output frame length */ ) { int16_t i, ch; float temp; - SPAR_DEC_HANDLE pState; int16_t num_bands_out, nchan_transport, nchan_out; /* Convert numeric range */ @@ -673,10 +646,9 @@ void ivas_sba_mix_matrix_determiner( } /* AGC */ - pState = st_ivas->hSpar; - nchan_transport = pState->hMdDec->spar_md_cfg.nchan_transport; + nchan_transport = hSpar->hMdDec->spar_md_cfg.nchan_transport; nchan_out = nchan_transport; - ivas_agc_dec_process( pState->hAgcDec, output, output, nchan_transport, output_frame ); + ivas_agc_dec_process( hSpar->hAgcDec, output, output, nchan_transport, output_frame ); /* Convert numeric range back */ for ( ch = 0; ch < nchan_out; ch++ ) @@ -688,16 +660,13 @@ void ivas_sba_mix_matrix_determiner( } /* Mixing matrix determiner */ - num_bands_out = pState->hFbMixer->pFb->filterbank_num_bands; - ivas_spar_dec_gen_umx_mat( pState->hMdDec, nchan_transport, num_bands_out, st_ivas->bfi ); - - wmops_sub_end(); + num_bands_out = hSpar->hFbMixer->pFb->filterbank_num_bands; + ivas_spar_dec_gen_umx_mat( hSpar->hMdDec, nchan_transport, num_bands_out, bfi ); return; } - /*-------------------------------------------------------------------* * ivas_sba_prototype_renderer() * diff --git a/lib_dec/ivas_sce_dec.c b/lib_dec/ivas_sce_dec.c index 5b83a41f81..b24d60505b 100644 --- a/lib_dec/ivas_sce_dec.c +++ b/lib_dec/ivas_sce_dec.c @@ -82,7 +82,11 @@ ivas_error ivas_sce_dec( *-----------------------------------------------------------------*/ /* set total_brate - needed in DTX */ +#ifdef ALIGN_SID_SIZE + if ( !st_ivas->bfi && ( ivas_total_brate == IVAS_SID_5k2 ) ) +#else if ( !st_ivas->bfi && ( ivas_total_brate == IVAS_SID_4k4 || ivas_total_brate == IVAS_SID_5k ) ) +#endif { st->total_brate = ivas_total_brate - nb_bits_metadata * FRAMES_PER_SEC; assert( st->total_brate == SID_2k40 && "SCE SID must be 2.4kbps!" ); @@ -91,7 +95,11 @@ ivas_error ivas_sce_dec( { st->total_brate = ivas_total_brate; } +#ifdef ALIGN_SID_SIZE + else if ( !st_ivas->bfi && ( last_ivas_total_brate <= SID_2k40 || last_ivas_total_brate == IVAS_SID_5k2 ) ) +#else else if ( !st_ivas->bfi && ( last_ivas_total_brate <= SID_2k40 || last_ivas_total_brate == IVAS_SID_4k4 ) ) +#endif { st->total_brate = hSCE->element_brate - nb_bits_metadata * FRAMES_PER_SEC; } @@ -161,7 +169,11 @@ ivas_error ivas_sce_dec( } /* set "total_brate" */ +#ifdef ALIGN_SID_SIZE + if ( !st_ivas->bfi && ( ivas_total_brate == IVAS_SID_5k2 ) ) +#else if ( !st_ivas->bfi && ( ivas_total_brate == IVAS_SID_4k4 || ivas_total_brate == IVAS_SID_5k ) ) +#endif { st->total_brate = ivas_total_brate - nb_bits_metadata * FRAMES_PER_SEC; } @@ -338,7 +350,7 @@ ivas_error create_sce_dec( st->total_brate = hSCE->element_brate; /* dummy initialization for getting right pointers initialization of input buffers in init_coder_ace_plus() */ st->mct_chan_mode = MCT_CHAN_MODE_REGULAR; -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE if ( ( error = init_decoder( st, 0, st_ivas->mc_mode ) ) != IVAS_ERR_OK ) #else if ( ( error = init_decoder( st, 0 ) ) != IVAS_ERR_OK ) diff --git a/lib_dec/ivas_spar_decoder.c b/lib_dec/ivas_spar_decoder.c index cc625f2605..2e48c11745 100755 --- a/lib_dec/ivas_spar_decoder.c +++ b/lib_dec/ivas_spar_decoder.c @@ -71,11 +71,7 @@ ivas_error ivas_spar_dec_open( int32_t output_Fs; error = IVAS_ERR_OK; -#ifndef SBA_ORDER_BITSTREAM - sba_order_internal = min( st_ivas->sba_order, IVAS_MAX_SBA_ORDER ); -#else sba_order_internal = min( st_ivas->sba_analysis_order, IVAS_MAX_SBA_ORDER ); -#endif num_channels_internal = ivas_sba_get_nchan_metadata( sba_order_internal ); /* SPAR decoder handle */ @@ -245,6 +241,12 @@ ivas_error ivas_spar_dec( next_bit_pos_orig = st0->next_bit_pos; last_bit_pos = (int16_t) ( ( hDecoderConfig->ivas_total_brate / FRAMES_PER_SEC ) - 1 ); +#ifdef ALIGN_SID_SIZE + if ( !st0->bfi && hDecoderConfig->ivas_total_brate == IVAS_SID_5k2 ) + { + last_bit_pos -= SID_FORMAT_NBITS; + } +#endif nb_bits_read_orig = *nb_bits_read; last_bit_pos -= nb_bits_read_orig; @@ -264,6 +266,17 @@ ivas_error ivas_spar_dec( st0->bit_stream = bit_stream_orig; st0->next_bit_pos = next_bit_pos_orig; +#ifdef ALIGN_SID_SIZE + if ( !st0->bfi && hDecoderConfig->ivas_total_brate == IVAS_SID_5k2 ) + { + int16_t zero_pad_bits; + *nb_bits_read += SID_FORMAT_NBITS; + zero_pad_bits = (int16_t) ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC - *nb_bits_read; + assert( zero_pad_bits <= 1 ); + *nb_bits_read += zero_pad_bits; + } +#endif + wmops_sub_end(); return error; @@ -623,11 +636,8 @@ static void ivas_spar_dec_MD( /*---------------------------------------------------------------------* * Initialization *---------------------------------------------------------------------*/ -#ifndef SBA_ORDER_BITSTREAM - sba_order = min( st_ivas->sba_order, IVAS_MAX_SBA_ORDER ); -#else + sba_order = min( st_ivas->sba_analysis_order, IVAS_MAX_SBA_ORDER ); -#endif bfi = st_ivas->bfi; ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate; num_channels = ivas_sba_get_nchan_metadata( sba_order ); @@ -635,7 +645,11 @@ static void ivas_spar_dec_MD( if ( ivas_total_brate > FRAME_NO_DATA && !bfi ) { +#ifdef ALIGN_SID_SIZE + if ( ivas_total_brate > IVAS_SID_5k2 ) +#else if ( ivas_total_brate > IVAS_SID_5k ) +#endif { ivas_parse_spar_header( hDecoderConfig->ivas_total_brate, sba_order, st0, &table_idx ); @@ -669,7 +683,11 @@ static void ivas_spar_dec_MD( * Read AGC bits *---------------------------------------------------------------------*/ +#ifdef ALIGN_SID_SIZE + if ( ivas_total_brate > IVAS_SID_5k2 && !bfi && hSpar->hMdDec->dtx_vad ) +#else if ( ivas_total_brate > IVAS_SID_5k && !bfi && hSpar->hMdDec->dtx_vad ) +#endif { hSpar->AGC_flag = get_next_indice( st0, 1 ); @@ -680,7 +698,11 @@ static void ivas_spar_dec_MD( * MD smoothing *---------------------------------------------------------------------*/ +#ifdef ALIGN_SID_SIZE + if ( st0->m_old_frame_type == ZERO_FRAME && ivas_total_brate == IVAS_SID_5k2 && st0->prev_bfi == 0 && hSpar->hMdDec->spar_md_cfg.nchan_transport == 1 ) +#else if ( st0->m_old_frame_type == ZERO_FRAME && ivas_total_brate == IVAS_SID_5k && st0->prev_bfi == 0 && hSpar->hMdDec->spar_md_cfg.nchan_transport == 1 ) +#endif { ivas_spar_setup_md_smoothing( hSpar->hMdDec, num_bands_out ); } @@ -972,9 +994,8 @@ void ivas_spar_dec_upmixer( /*---------------------------------------------------------------------* * PCA decoder *---------------------------------------------------------------------*/ - #ifdef DEBUG_SBA_AUDIO_DUMP - pState->pca_ingest_channels = num_in_ingest; + hSpar->pca_ingest_channels = num_in_ingest; #endif if ( hSpar->hPCA != NULL ) @@ -986,6 +1007,7 @@ void ivas_spar_dec_upmixer( #endif } + /*---------------------------------------------------------------------* * TD decorrelation *---------------------------------------------------------------------*/ @@ -1164,7 +1186,7 @@ void ivas_spar_dec_upmixer( } } #ifdef DEBUG_SBA_AUDIO_DUMP - pState->numOutChannels = outchannels; + hSpar->numOutChannels = outchannels; #endif } else @@ -1183,12 +1205,12 @@ void ivas_spar_dec_upmixer( } } #ifdef DEBUG_SBA_AUDIO_DUMP - pState->numOutChannels = numch_out_dirac; + 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, pState->numOutChannels, spar_foa_dec_wav[3], "cldfbSynthesis()" ); + ivas_spar_dump_signal_wav( output_frame, NULL, output, hSpar->numOutChannels, spar_foa_dec_wav[3], "cldfbSynthesis()" ); #endif split_band = SPAR_DIRAC_SPLIT_START_BAND; diff --git a/lib_dec/ivas_spar_md_dec.c b/lib_dec/ivas_spar_md_dec.c index be1b3fcb10..c0682c58a2 100644 --- a/lib_dec/ivas_spar_md_dec.c +++ b/lib_dec/ivas_spar_md_dec.c @@ -63,11 +63,11 @@ static const int16_t ivas_spar_dec_plc_spatial_target[IVAS_SPAR_MAX_CH] = { 1, 0 * Static functions declaration *------------------------------------------------------------------------------------------*/ -static void ivas_get_spar_matrices( ivas_spar_md_dec_state_t *pState, const int16_t num_bands_out, const int16_t n_ts, const int16_t bw, const int16_t dtx_vad, const int16_t nB, const int16_t sba_order ); +static void ivas_get_spar_matrices( ivas_spar_md_dec_state_t *hMdDec, const int16_t num_bands_out, const int16_t n_ts, const int16_t bw, const int16_t dtx_vad, const int16_t nB, const int16_t sba_order ); -static void ivas_decode_arith_bs( ivas_spar_md_dec_state_t *pState, Decoder_State *st, const uint16_t qsi, const int16_t nB, const int16_t bands_bw, int16_t *pDo_diff, const int16_t freq_diff, const int16_t planarCP ); +static void ivas_decode_arith_bs( ivas_spar_md_dec_state_t *hMdDec, Decoder_State *st, const uint16_t qsi, const int16_t nB, const int16_t bands_bw, int16_t *pDo_diff, const int16_t freq_diff, const int16_t planarCP ); -static void ivas_decode_huffman_bs( ivas_spar_md_dec_state_t *pState, Decoder_State *st, const uint16_t qsi, const int16_t nB, const int16_t bands_bw, const int16_t planarCP ); +static void ivas_decode_huffman_bs( ivas_spar_md_dec_state_t *hMdDec, Decoder_State *st, const uint16_t qsi, const int16_t nB, const int16_t bands_bw, const int16_t planarCP ); static void ivas_fill_band_coeffs_idx( ivas_band_coeffs_ind_t *pBands_idx, const int16_t nB, int16_t *pSymbol_re, ivas_cell_dim_t *pCell_dims, ivas_coeffs_type_t coeff_type, const int16_t planarCP ); @@ -75,16 +75,14 @@ static void ivas_get_band_idx_from_differential( ivas_spar_md_t *pSpar_md, const static void ivas_mat_col_rearrange( float in_re[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], const int16_t order[IVAS_SPAR_MAX_CH], const int16_t i_ts, float ***mixer_mat, const int16_t bands, const int16_t num_ch ); -static void ivas_spar_dec_compute_ramp_down_post_matrix( ivas_spar_md_dec_state_t *pState, const int16_t num_bands, const int16_t bfi ); +static void ivas_spar_dec_compute_ramp_down_post_matrix( ivas_spar_md_dec_state_t *hMdDec, const int16_t num_bands, const int16_t bfi ); -static void ivas_spar_md_fill_invalid_bands( ivas_spar_dec_matrices_t *pSpar_coeffs, ivas_spar_dec_matrices_t *pSpar_coeffs_prev, int16_t *valid_bands, int16_t *base_band_age, const int16_t num_bands, const int16_t sba_order ); +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 sba_order ); -static ivas_error ivas_spar_set_dec_config( ivas_spar_md_dec_state_t *pState, const int16_t nchan_transport, float *pFC ); +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 ); - -static ivas_error ivas_deindex_real_index( int16_t **index, const int16_t q_levels, const float min_value, const float max_value, float **quant, const int16_t num_ch, const int16_t dim2 ); - +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 use_planar_coeff, const int16_t sba_inactive_mode ); @@ -426,7 +424,7 @@ void ivas_spar_md_dec_close( /*-----------------------------------------------------------------------------------------* * Function ivas_spar_md_dec_init() * - * Init call for md dec process + * SPAR MD decoder initialization *-----------------------------------------------------------------------------------------*/ ivas_error ivas_spar_md_dec_init( @@ -438,12 +436,11 @@ ivas_error ivas_spar_md_dec_init( int16_t i, j, k; int16_t nchan_transport; float pFC[IVAS_MAX_NUM_BANDS], PR_minmax[2]; - ivas_spar_md_dec_state_t *pState = hMdDec; - pState->spar_md_cfg.gen_bs = 1; - ivas_spar_set_bitrate_config( &pState->spar_md_cfg, pState->table_idx, min( IVAS_MAX_NUM_BANDS, SPAR_DIRAC_SPLIT_START_BAND ) ); + hMdDec->spar_md_cfg.gen_bs = 1; // VE2DB : always 1 - can it be removed? + ivas_spar_set_bitrate_config( &hMdDec->spar_md_cfg, hMdDec->table_idx, min( IVAS_MAX_NUM_BANDS, SPAR_DIRAC_SPLIT_START_BAND ) ); - nchan_transport = pState->spar_md_cfg.nchan_transport; + nchan_transport = hMdDec->spar_md_cfg.nchan_transport; /* get FB coefficients */ for ( i = 0; i < IVAS_MAX_NUM_BANDS; i++ ) @@ -451,28 +448,28 @@ ivas_error ivas_spar_md_dec_init( pFC[i] = ivas_fb_fcs_12band_1ms[i] * hDecoderConfig->output_Fs * 0.5f; } - ivas_spar_set_dec_config( pState, nchan_transport, pFC ); + ivas_spar_set_dec_config( hMdDec, nchan_transport, pFC ); - if ( nchan_transport != 2 && ( ( pState->spar_md_cfg.remix_unmix_order == 2 ) || ( pState->spar_md_cfg.remix_unmix_order == 1 ) ) ) + if ( nchan_transport != 2 && ( ( hMdDec->spar_md_cfg.remix_unmix_order == 2 ) || ( hMdDec->spar_md_cfg.remix_unmix_order == 1 ) ) ) { return IVAS_ERR_INTERNAL; } /* DTX quant init */ - PR_minmax[0] = pState->spar_md_cfg.quant_strat[0].PR.min; - PR_minmax[1] = pState->spar_md_cfg.quant_strat[0].PR.max; - ivas_spar_quant_dtx_init( &pState->spar_md, PR_minmax ); + PR_minmax[0] = hMdDec->spar_md_cfg.quant_strat[0].PR.min; + PR_minmax[1] = hMdDec->spar_md_cfg.quant_strat[0].PR.max; + ivas_spar_quant_dtx_init( &hMdDec->spar_md, PR_minmax ); - ivas_spar_arith_coeffs_com_init( &pState->arith_coeffs, &pState->spar_md_cfg, pState->table_idx, DEC ); - ivas_spar_huff_coeffs_com_init( &pState->huff_coeffs, &pState->spar_md_cfg, pState->table_idx, DEC ); + ivas_spar_arith_coeffs_com_init( &hMdDec->arith_coeffs, &hMdDec->spar_md_cfg, hMdDec->table_idx, DEC ); + ivas_spar_huff_coeffs_com_init( &hMdDec->huff_coeffs, &hMdDec->spar_md_cfg, hMdDec->table_idx, DEC ); - pState->spar_md_cfg.prev_quant_idx = -1; + hMdDec->spar_md_cfg.prev_quant_idx = -1; /* initialize PLC state */ - set_s( pState->valid_bands, 0, IVAS_MAX_NUM_BANDS ); - set_s( pState->base_band_age, 0, IVAS_MAX_NUM_BANDS ); - pState->spar_plc_num_lost_frames = 0; - pState->spar_plc_enable_fadeout_flag = 1; + set_s( hMdDec->valid_bands, 0, IVAS_MAX_NUM_BANDS ); + set_s( hMdDec->base_band_age, 0, IVAS_MAX_NUM_BANDS ); + hMdDec->spar_plc_num_lost_frames = 0; + hMdDec->spar_plc_enable_fadeout_flag = 1; for ( i = 0; i < num_channels; i++ ) { @@ -480,7 +477,7 @@ ivas_error ivas_spar_md_dec_init( { for ( k = 0; k < IVAS_MAX_NUM_BANDS; k++ ) { - pState->spar_coeffs_prev.C_re[i][j][k] = 0; + hMdDec->spar_coeffs_prev.C_re[i][j][k] = 0; } } } @@ -491,7 +488,7 @@ ivas_error ivas_spar_md_dec_init( { for ( k = 0; k < IVAS_MAX_NUM_BANDS; k++ ) { - pState->spar_coeffs_prev.P_re[i][j][k] = 0; + hMdDec->spar_coeffs_prev.P_re[i][j][k] = 0; } } } @@ -502,7 +499,7 @@ ivas_error ivas_spar_md_dec_init( { for ( k = 0; k < IVAS_MAX_NUM_BANDS; k++ ) { - pState->spar_coeffs_tar.C_re[i][j][k] = 0; + hMdDec->spar_coeffs_tar.C_re[i][j][k] = 0; } } } @@ -513,24 +510,24 @@ ivas_error ivas_spar_md_dec_init( { for ( k = 0; k < IVAS_MAX_NUM_BANDS; k++ ) { - pState->spar_coeffs_tar.P_re[i][j][k] = 0; + hMdDec->spar_coeffs_tar.P_re[i][j][k] = 0; } } } - pState->dtx_md_smoothing_cntr = 1; + hMdDec->dtx_md_smoothing_cntr = 1; - ivas_clear_band_coeffs( pState->spar_md.band_coeffs, IVAS_MAX_NUM_BANDS ); - ivas_clear_band_coeff_idx( pState->spar_md.band_coeffs_idx, IVAS_MAX_NUM_BANDS ); - ivas_clear_band_coeff_idx( pState->spar_md_prev.band_coeffs_idx, IVAS_MAX_NUM_BANDS ); - ivas_clear_band_coeff_idx( pState->spar_md_prev.band_coeffs_idx_mapped, IVAS_MAX_NUM_BANDS ); + ivas_clear_band_coeffs( hMdDec->spar_md.band_coeffs, IVAS_MAX_NUM_BANDS ); + 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 ); - pState->spar_md.dtx_vad = 0; - pState->spar_md.num_bands = min( IVAS_MAX_NUM_BANDS, SPAR_DIRAC_SPLIT_START_BAND ); - pState->td_decorr_flag = 1; + hMdDec->spar_md.dtx_vad = 0; + hMdDec->spar_md.num_bands = min( IVAS_MAX_NUM_BANDS, SPAR_DIRAC_SPLIT_START_BAND ); + hMdDec->td_decorr_flag = 1; - set_f( pState->spar_md.en_ratio_slow, 0.0f, IVAS_MAX_NUM_BANDS ); - set_f( pState->spar_md.ref_pow_slow, 0.0f, IVAS_MAX_NUM_BANDS ); + set_f( hMdDec->spar_md.en_ratio_slow, 0.0f, IVAS_MAX_NUM_BANDS ); + set_f( hMdDec->spar_md.ref_pow_slow, 0.0f, IVAS_MAX_NUM_BANDS ); return IVAS_ERR_OK; } @@ -539,11 +536,11 @@ ivas_error ivas_spar_md_dec_init( /*-----------------------------------------------------------------------------------------* * Function ivas_spar_set_dec_config() * - * Set configuration for SPAR md dec + * Set configuration for SPAR MD decoder *-----------------------------------------------------------------------------------------*/ static ivas_error ivas_spar_set_dec_config( - ivas_spar_md_dec_state_t *pState, + ivas_spar_md_dec_state_t *hMdDec, const int16_t nchan_transport, float *pFC ) { @@ -551,31 +548,31 @@ static ivas_error ivas_spar_set_dec_config( for ( i = 0; i < nchan_transport; i++ ) { - pState->spar_md_cfg.max_freq_per_chan[i] = ivas_spar_br_table_consts[pState->table_idx].fpcs; + hMdDec->spar_md_cfg.max_freq_per_chan[i] = ivas_spar_br_table_consts[hMdDec->table_idx].fpcs; } - nchan = ivas_sba_get_nchan_metadata( ivas_spar_br_table_consts[pState->table_idx].sba_order ); + nchan = ivas_sba_get_nchan_metadata( ivas_spar_br_table_consts[hMdDec->table_idx].sba_order ); switch ( nchan ) { case 4: /* FOA_CHANNELS */ - pState->num_decorr = IVAS_TD_DECORR_OUT_3CH; + hMdDec->num_decorr = IVAS_TD_DECORR_OUT_3CH; break; case 9: /* IVAS_HOA_2_CH */ // VE: is this relevant? - pState->num_decorr = IVAS_TD_DECORR_OUT_5CH; + hMdDec->num_decorr = IVAS_TD_DECORR_OUT_5CH; break; case 16: /* IVAS_HOA_3_CH */ // VE: is this relevant? - pState->num_decorr = IVAS_TD_DECORR_OUT_12CH; + hMdDec->num_decorr = IVAS_TD_DECORR_OUT_12CH; break; case 6: /* IVAS_HOA_2_CH */ - pState->num_decorr = IVAS_TD_DECORR_OUT_2CH; + hMdDec->num_decorr = IVAS_TD_DECORR_OUT_2CH; break; case 8: /* IVAS_HOA_3_CH */ - pState->num_decorr = IVAS_TD_DECORR_OUT_4CH; + hMdDec->num_decorr = IVAS_TD_DECORR_OUT_4CH; break; } - pState->spar_md_cfg.num_umx_chs = nchan; + hMdDec->spar_md_cfg.num_umx_chs = nchan; dmx_ch = 0; for ( i = 0; i < IVAS_MAX_NUM_BANDS; i++ ) @@ -583,17 +580,17 @@ static ivas_error ivas_spar_set_dec_config( dmx_ch = 0; for ( j = 0; j < nchan_transport; j++ ) { - if ( pFC[i] < pState->spar_md_cfg.max_freq_per_chan[j] ) + if ( pFC[i] < hMdDec->spar_md_cfg.max_freq_per_chan[j] ) { dmx_ch += 1; } } - pState->spar_md_cfg.num_dmx_chans_per_band[i] = pState->spar_md_cfg.nchan_transport; - pState->spar_md_cfg.num_decorr_per_band[i] = nchan - pState->spar_md_cfg.nchan_transport; + hMdDec->spar_md_cfg.num_dmx_chans_per_band[i] = hMdDec->spar_md_cfg.nchan_transport; + hMdDec->spar_md_cfg.num_decorr_per_band[i] = nchan - hMdDec->spar_md_cfg.nchan_transport; } - pState->spar_md_cfg.nchan_transport = dmx_ch; + hMdDec->spar_md_cfg.nchan_transport = dmx_ch; return IVAS_ERR_OK; } @@ -612,8 +609,10 @@ void ivas_spar_md_dec_process( const int16_t sba_order /* i : Ambisonic (SBA) order */ ) { - int16_t j, b, bw, dtx_vad, nB, i_ts; - ivas_spar_md_dec_state_t *hMdDec = st_ivas->hSpar->hMdDec; + int16_t j, k, b, bw, dtx_vad, nB, i_ts; + ivas_spar_md_dec_state_t *hMdDec; + + hMdDec = st_ivas->hSpar->hMdDec; ivas_spar_dec_parse_md_bs( hMdDec, st0, &nB, &bw, &dtx_vad, st_ivas->hDecoderConfig->ivas_total_brate, ivas_spar_br_table_consts[hMdDec->table_idx].usePlanarCoeff, st_ivas->hQMetaData->sba_inactive_mode ); @@ -666,8 +665,8 @@ void ivas_spar_md_dec_process( } #endif - /* SPAR to DirAC and DirAC to SPAR conversion */ - if ( st_ivas->sba_mode == SBA_MODE_SPAR ) + /* SPAR to DirAC and DirAC to SPAR conversion */ // VE2DB: -> "DirAC to SPAR conversion" only? + if ( st_ivas->sba_mode == SBA_MODE_SPAR ) // VE2DB: this looks obsolete { ivas_spar_to_dirac( st_ivas, hMdDec, dtx_vad, num_bands_out ); @@ -691,7 +690,7 @@ void ivas_spar_md_dec_process( for ( j = 0; j < IVAS_SPAR_MAX_CH - IVAS_SPAR_MAX_DMX_CHS; j++ ) { - for ( int16_t k = 0; k < IVAS_SPAR_MAX_DMX_CHS - 1; k++ ) + for ( k = 0; k < IVAS_SPAR_MAX_DMX_CHS - 1; k++ ) { hMdDec->spar_md.band_coeffs[b + i_ts * IVAS_MAX_NUM_BANDS].C_re[j][k] = hMdDec->spar_md.band_coeffs[b].C_re[j][k]; } @@ -736,6 +735,7 @@ void ivas_spar_md_dec_process( * * Smooth MD during no data frame during DTX *-----------------------------------------------------------------------------------------*/ + #ifdef SPAR_HOA_DBG /* NOTE: No changes here as DTX only operates below 160kbps */ #endif @@ -744,26 +744,23 @@ void ivas_spar_smooth_md_dtx( const int16_t num_bands_out /* i : number of output bands */ ) { - int16_t j, k, b; - int16_t dmx_ch; - ivas_spar_md_dec_state_t *pState = hMdDec; + int16_t j, k, b, dmx_ch; float ramp, tar, prev, new_val; - ramp = (float) pState->dtx_md_smoothing_cntr / IVAS_DEFAULT_DTX_CNG_RAMP; + ramp = (float) hMdDec->dtx_md_smoothing_cntr / IVAS_DEFAULT_DTX_CNG_RAMP; for ( b = 0; b < num_bands_out; b++ ) { - dmx_ch = pState->spar_md_cfg.num_dmx_chans_per_band[b]; + dmx_ch = hMdDec->spar_md_cfg.num_dmx_chans_per_band[b]; for ( j = 1; j < FOA_CHANNELS; j++ ) { for ( k = dmx_ch; k < FOA_CHANNELS; k++ ) - { - prev = pState->spar_coeffs_prev.P_re[j][k][b]; - tar = pState->spar_coeffs_tar.P_re[j][k][b]; + prev = hMdDec->spar_coeffs_prev.P_re[j][k][b]; + tar = hMdDec->spar_coeffs_tar.P_re[j][k][b]; new_val = prev + ( ramp * ( tar - prev ) ); - pState->spar_coeffs.P_re[j][k][b] = new_val; + hMdDec->spar_coeffs.P_re[j][k][b] = new_val; } } @@ -771,10 +768,10 @@ void ivas_spar_smooth_md_dtx( { for ( k = 0; k < dmx_ch; k++ ) { - prev = pState->spar_coeffs_prev.C_re[j][k][b]; - tar = pState->spar_coeffs_tar.C_re[j][k][b]; + prev = hMdDec->spar_coeffs_prev.C_re[j][k][b]; + tar = hMdDec->spar_coeffs_tar.C_re[j][k][b]; new_val = prev + ( ramp * ( tar - prev ) ); - pState->spar_coeffs.C_re[j][k][b] = new_val; + hMdDec->spar_coeffs.C_re[j][k][b] = new_val; } } } @@ -784,14 +781,14 @@ void ivas_spar_smooth_md_dtx( { for ( b = 0; b < num_bands_out; b++ ) { - dmx_ch = pState->spar_md_cfg.num_dmx_chans_per_band[b]; + dmx_ch = hMdDec->spar_md_cfg.num_dmx_chans_per_band[b]; for ( j = 1; j < FOA_CHANNELS; j++ ) { for ( k = dmx_ch; k < FOA_CHANNELS; k++ ) { - pState->spar_coeffs.P_re[j][k][b + i_ts * IVAS_MAX_NUM_BANDS] = pState->spar_coeffs.P_re[j][k][b]; + hMdDec->spar_coeffs.P_re[j][k][b + i_ts * IVAS_MAX_NUM_BANDS] = hMdDec->spar_coeffs.P_re[j][k][b]; } } @@ -799,13 +796,13 @@ void ivas_spar_smooth_md_dtx( { for ( k = 0; k < dmx_ch; k++ ) { - pState->spar_coeffs.C_re[j][k][b + i_ts * IVAS_MAX_NUM_BANDS] = pState->spar_coeffs.C_re[j][k][b]; + hMdDec->spar_coeffs.C_re[j][k][b + i_ts * IVAS_MAX_NUM_BANDS] = hMdDec->spar_coeffs.C_re[j][k][b]; } } } } - pState->dtx_md_smoothing_cntr = min( pState->dtx_md_smoothing_cntr + 1, IVAS_DEFAULT_DTX_CNG_RAMP ); + hMdDec->dtx_md_smoothing_cntr = min( hMdDec->dtx_md_smoothing_cntr + 1, IVAS_DEFAULT_DTX_CNG_RAMP ); return; } @@ -945,7 +942,7 @@ void ivas_spar_update_md_hist( *-----------------------------------------------------------------------------------------*/ static void ivas_get_spar_matrices( - ivas_spar_md_dec_state_t *pState, + ivas_spar_md_dec_state_t *hMdDec, const int16_t num_bands_out, const int16_t n_ts, const int16_t bw, @@ -953,16 +950,15 @@ static void ivas_get_spar_matrices( const int16_t nB, const int16_t sba_order ) { - int16_t numch_out, num_bands, dmx_ch; + int16_t numch_out, num_bands, dmx_ch, split_band; int16_t i, j, k, m, b, i_ts, active_w; const int16_t *order; float active_w_dm_fac, re; - int16_t split_band; numch_out = ivas_sba_get_nchan_metadata( sba_order ); num_bands = num_bands_out; - order = remix_order_set[pState->spar_md_cfg.remix_unmix_order]; + order = remix_order_set[hMdDec->spar_md_cfg.remix_unmix_order]; split_band = SPAR_DIRAC_SPLIT_START_BAND; if ( split_band >= IVAS_MAX_NUM_BANDS ) @@ -974,7 +970,7 @@ static void ivas_get_spar_matrices( { for ( b = 0; b < num_bands; b++ ) { - pState->mixer_mat_prev[0][i][j][b] = pState->mixer_mat[i][j][b]; + hMdDec->mixer_mat_prev[0][i][j][b] = hMdDec->mixer_mat[i][j][b]; } } } @@ -983,19 +979,19 @@ static void ivas_get_spar_matrices( #ifdef SPAR_HOA_DBG /*for (b = 0; b < BANDS_12; b++) { - for (i = 0; i < IVAS_SPAR_MAX_CH - 1; i++) - { - pState->spar_md.band_coeffs[b].pred_re[i] = (float)(i + 1)/10; - for (j = 0; j < IVAS_SPAR_MAX_CH - 1; j++) + for (i = 0; i < IVAS_SPAR_MAX_CH - 1; i++) { - pState->spar_md.band_coeffs[b].C_re[i][j] = (float)(i + j * 20 + 1)/10; - pState->spar_md.band_coeffs[b].P_re[i][j] = (float)(i + j * 20 + 1)/10; + hMdDec->spar_md.band_coeffs[b].pred_re[i] = (float)(i + 1)/10; + for (j = 0; j < IVAS_SPAR_MAX_CH - 1; j++) + { + hMdDec->spar_md.band_coeffs[b].C_re[i][j] = (float)(i + j * 20 + 1)/10; + hMdDec->spar_md.band_coeffs[b].P_re[i][j] = (float)(i + j * 20 + 1)/10; + } } - } }*/ #endif - active_w = pState->spar_md_cfg.active_w; + active_w = hMdDec->spar_md_cfg.active_w; active_w_dm_fac = ( dtx_vad == 0 ) ? IVAS_ACTIVEW_DM_F_SCALE_DTX : IVAS_ACTIVEW_DM_F_SCALE; for ( i_ts = 0; i_ts < n_ts; i_ts++ ) @@ -1004,8 +1000,8 @@ static void ivas_get_spar_matrices( { for ( j = 0; j < numch_out; j++ ) { - set_zero( &pState->spar_coeffs.C_re[i][j][i_ts * IVAS_MAX_NUM_BANDS], IVAS_MAX_NUM_BANDS ); - set_zero( &pState->spar_coeffs.P_re[i][j][i_ts * IVAS_MAX_NUM_BANDS], IVAS_MAX_NUM_BANDS ); + set_zero( &hMdDec->spar_coeffs.C_re[i][j][i_ts * IVAS_MAX_NUM_BANDS], IVAS_MAX_NUM_BANDS ); + set_zero( &hMdDec->spar_coeffs.P_re[i][j][i_ts * IVAS_MAX_NUM_BANDS], IVAS_MAX_NUM_BANDS ); } } @@ -1022,7 +1018,7 @@ static void ivas_get_spar_matrices( float tmp_C2_re[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH]; float tmp_dm_re[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH]; - dmx_ch = pState->spar_md_cfg.num_dmx_chans_per_band[bw * b]; + dmx_ch = hMdDec->spar_md_cfg.num_dmx_chans_per_band[bw * b]; for ( j = 0; j < numch_out; j++ ) { @@ -1037,14 +1033,14 @@ static void ivas_get_spar_matrices( for ( j = 1; j < numch_out; j++ ) { - tmp_C1_re[j][0] = pState->spar_md.band_coeffs[b + i_ts * IVAS_MAX_NUM_BANDS].pred_re[j - 1]; + tmp_C1_re[j][0] = hMdDec->spar_md.band_coeffs[b + i_ts * IVAS_MAX_NUM_BANDS].pred_re[j - 1]; } if ( active_w == 1 ) { for ( j = 1; j < numch_out; j++ ) { - tmp_C2_re[0][j] = active_w_dm_fac * -pState->spar_md.band_coeffs[b + i_ts * IVAS_MAX_NUM_BANDS].pred_re[j - 1]; + tmp_C2_re[0][j] = active_w_dm_fac * -hMdDec->spar_md.band_coeffs[b + i_ts * IVAS_MAX_NUM_BANDS].pred_re[j - 1]; } IVAS_RMULT_FLOAT( tmp_C2_re[0][1], tmp_C1_re[1][0], re ); @@ -1068,9 +1064,9 @@ static void ivas_get_spar_matrices( tmp_dm_re[3][0] = tmp_C1_re[3][0]; - if ( pState->spar_md_cfg.remix_unmix_order != 3 ) + if ( hMdDec->spar_md_cfg.remix_unmix_order != 3 ) { - ivas_mat_col_rearrange( tmp_dm_re, order, i_ts, pState->mixer_mat, b, numch_out ); + ivas_mat_col_rearrange( tmp_dm_re, order, i_ts, hMdDec->mixer_mat, b, numch_out ); } else { @@ -1078,24 +1074,24 @@ static void ivas_get_spar_matrices( for ( i = 0; i < FOA_CHANNELS; i++ ) { /* row 0 */ - pState->mixer_mat[i][0][b + i_ts * IVAS_MAX_NUM_BANDS] = tmp_dm_re[i][0]; + hMdDec->mixer_mat[i][0][b + i_ts * IVAS_MAX_NUM_BANDS] = tmp_dm_re[i][0]; /* row 1 */ - pState->mixer_mat[i][1][b + i_ts * IVAS_MAX_NUM_BANDS] = tmp_dm_re[i][1]; + hMdDec->mixer_mat[i][1][b + i_ts * IVAS_MAX_NUM_BANDS] = tmp_dm_re[i][1]; /* row 3 */ - pState->mixer_mat[i][2][b + i_ts * IVAS_MAX_NUM_BANDS] = tmp_dm_re[i][1]; + hMdDec->mixer_mat[i][2][b + i_ts * IVAS_MAX_NUM_BANDS] = tmp_dm_re[i][1]; /* row 4 */ - pState->mixer_mat[i][3][b + i_ts * IVAS_MAX_NUM_BANDS] = tmp_dm_re[i][2]; + hMdDec->mixer_mat[i][3][b + i_ts * IVAS_MAX_NUM_BANDS] = tmp_dm_re[i][2]; } } } else { - if ( pState->spar_md_cfg.remix_unmix_order != 3 ) + if ( hMdDec->spar_md_cfg.remix_unmix_order != 3 ) { - ivas_mat_col_rearrange( tmp_C1_re, order, i_ts, pState->mixer_mat, b, numch_out ); + ivas_mat_col_rearrange( tmp_C1_re, order, i_ts, hMdDec->mixer_mat, b, numch_out ); } else { @@ -1103,16 +1099,16 @@ static void ivas_get_spar_matrices( for ( i = 0; i < FOA_CHANNELS; i++ ) { /* row 0 */ - pState->mixer_mat[i][0][b + i_ts * IVAS_MAX_NUM_BANDS] = tmp_C1_re[i][0]; + hMdDec->mixer_mat[i][0][b + i_ts * IVAS_MAX_NUM_BANDS] = tmp_C1_re[i][0]; /* row 1 */ - pState->mixer_mat[i][1][b + i_ts * IVAS_MAX_NUM_BANDS] = tmp_C1_re[i][1]; + hMdDec->mixer_mat[i][1][b + i_ts * IVAS_MAX_NUM_BANDS] = tmp_C1_re[i][1]; /* row 3 */ - pState->mixer_mat[i][2][b + i_ts * IVAS_MAX_NUM_BANDS] = tmp_C1_re[i][1]; + hMdDec->mixer_mat[i][2][b + i_ts * IVAS_MAX_NUM_BANDS] = tmp_C1_re[i][1]; /* row 4 */ - pState->mixer_mat[i][3][b + i_ts * IVAS_MAX_NUM_BANDS] = tmp_C1_re[i][2]; + hMdDec->mixer_mat[i][3][b + i_ts * IVAS_MAX_NUM_BANDS] = tmp_C1_re[i][2]; } } } @@ -1142,28 +1138,28 @@ static void ivas_get_spar_matrices( { for ( k = 1; k < dmx_ch; k++ ) { - tmpC_re[j][k] = pState->spar_md.band_coeffs[b + i_ts * IVAS_MAX_NUM_BANDS].C_re[j - dmx_ch][k - 1]; + tmpC_re[j][k] = hMdDec->spar_md.band_coeffs[b + i_ts * IVAS_MAX_NUM_BANDS].C_re[j - dmx_ch][k - 1]; } } #ifdef SPAR_HOA_DBG /*fprintf(stdout, "C matrix1: %d x %d\n\n", numch_out, dmx_ch); for (j = 0; j < numch_out; j++) { - for (k = 0; k < dmx_ch; k++) - { - fprintf(stdout, "%f, ", tmpC_re[j][k]); - } - fprintf(stdout, "\n"); + for (k = 0; k < dmx_ch; k++) + { + fprintf(stdout, "%f, ", tmpC_re[j][k]); + } + fprintf(stdout, "\n"); } fprintf(stdout, "Mixer Mat: %d x %d\n\n", numch_out, numch_out); for ( j = 0; j < numch_out; j++) { - for (k = 0; k < numch_out; k++) - { - fprintf(stdout, "%f, ", pState->mixer_mat[j][k][0][b]); - } - fprintf(stdout, "\n"); + for (k = 0; k < numch_out; k++) + { + fprintf(stdout, "%f, ", hMdDec->mixer_mat[j][k][0][b]); + } + fprintf(stdout, "\n"); }*/ #endif @@ -1173,7 +1169,7 @@ static void ivas_get_spar_matrices( { if ( ( j - dmx_ch ) == ( k - dmx_ch ) ) { - tmpP_re[j][k] = pState->spar_md.band_coeffs[b + i_ts * IVAS_MAX_NUM_BANDS].P_re[k - dmx_ch]; + tmpP_re[j][k] = hMdDec->spar_md.band_coeffs[b + i_ts * IVAS_MAX_NUM_BANDS].P_re[k - dmx_ch]; } else { @@ -1184,26 +1180,26 @@ static void ivas_get_spar_matrices( #ifdef SPAR_HOA_DBG /*if (b == 0) { - fprintf(stdout, "tmp_P matrix: %d x %d\n\n", numch_out, dmx_ch); - for (j = 0; j < numch_out; j++) - { - for (k = 0; k < numch_out; k++) + fprintf(stdout, "tmp_P matrix: %d x %d\n\n", numch_out, dmx_ch); + for (j = 0; j < numch_out; j++) { - fprintf(stdout, "%f, ", tmpP_re[j][k]); - } - fprintf(stdout, "\n"); + for (k = 0; k < numch_out; k++) + { + fprintf(stdout, "%f, ", tmpP_re[j][k]); + } + fprintf(stdout, "\n"); - } - fprintf(stdout, "Mixer Mat: %d x %d\n\n", numch_out, numch_out); - for (j = 0; j < numch_out; j++) - { - for (k = 0; k < numch_out; k++) - { - fprintf(stdout, "%f, ", pState->mixer_mat[j][k][0][b]); } - fprintf(stdout, "\n"); + fprintf(stdout, "Mixer Mat: %d x %d\n\n", numch_out, numch_out); + for (j = 0; j < numch_out; j++) + { + for (k = 0; k < numch_out; k++) + { + fprintf(stdout, "%f, ", hMdDec->mixer_mat[j][k][0][b]); + } + fprintf(stdout, "\n"); - } + } }*/ #endif for ( j = 1; j < numch_out; j++ ) @@ -1213,8 +1209,8 @@ static void ivas_get_spar_matrices( { for ( m = 0; m < numch_out; m++ ) { - IVAS_RMULT_FLOAT( pState->mixer_mat[j][m][b + i_ts * IVAS_MAX_NUM_BANDS], tmpP_re[m][k], re ); - pState->spar_coeffs.P_re[j][k][( b * bw ) + i_ts * IVAS_MAX_NUM_BANDS] += re; + IVAS_RMULT_FLOAT( hMdDec->mixer_mat[j][m][b + i_ts * IVAS_MAX_NUM_BANDS], tmpP_re[m][k], re ); + hMdDec->spar_coeffs.P_re[j][k][( b * bw ) + i_ts * IVAS_MAX_NUM_BANDS] += re; } } } @@ -1225,8 +1221,8 @@ static void ivas_get_spar_matrices( { for ( m = 0; m < numch_out; m++ ) { - IVAS_RMULT_FLOAT( pState->mixer_mat[j][m][b + i_ts * IVAS_MAX_NUM_BANDS], tmpC_re[m][k], re ); - pState->spar_coeffs.C_re[j][k][( b * bw ) + i_ts * IVAS_MAX_NUM_BANDS] += re; + IVAS_RMULT_FLOAT( hMdDec->mixer_mat[j][m][b + i_ts * IVAS_MAX_NUM_BANDS], tmpC_re[m][k], re ); + hMdDec->spar_coeffs.C_re[j][k][( b * bw ) + i_ts * IVAS_MAX_NUM_BANDS] += re; } } } @@ -1234,42 +1230,42 @@ static void ivas_get_spar_matrices( /*fprintf(stdout, "C matrix1: %d x %d\n\n", numch_out, dmx_ch); for (j = 0; j < numch_out; j++) { - for (k = 0; k < dmx_ch; k++) - { - fprintf(stdout, "%f, ", pState->spar_coeffs.C_re[j][k][b]); - } - fprintf(stdout, "\n"); + for (k = 0; k < dmx_ch; k++) + { + fprintf(stdout, "%f, ", hMdDec->spar_coeffs.C_re[j][k][b]); + } + fprintf(stdout, "\n"); }*/ #endif - pState->spar_coeffs.C_re[0][0][( b * bw ) + i_ts * IVAS_MAX_NUM_BANDS] = - max( 0, pState->spar_coeffs.C_re[0][0][( b * bw ) + i_ts * IVAS_MAX_NUM_BANDS] ); + hMdDec->spar_coeffs.C_re[0][0][( b * bw ) + i_ts * IVAS_MAX_NUM_BANDS] = + max( 0, hMdDec->spar_coeffs.C_re[0][0][( b * bw ) + i_ts * IVAS_MAX_NUM_BANDS] ); } } #ifdef SPAR_HOA_DBG /* for (b = 0; b < 1; b++) { - fprintf(stdout, "C matrix: %d x %d band %d\n\n", numch_out, dmx_ch, b); - for (j = 0; j < numch_out; j++) - { - for (k = 0; k < numch_out; k++) + fprintf(stdout, "C matrix: %d x %d band %d\n\n", numch_out, dmx_ch, b); + for (j = 0; j < numch_out; j++) { - fprintf(stdout, "%f, ", pState->spar_coeffs.C_re[j][k][b]); - } - fprintf(stdout, "\n"); + for (k = 0; k < numch_out; k++) + { + fprintf(stdout, "%f, ", hMdDec->spar_coeffs.C_re[j][k][b]); + } + fprintf(stdout, "\n"); - } - fprintf(stdout, "\nP matrix: %d x %d\n\n", numch_out, numch_out); + } + fprintf(stdout, "\nP matrix: %d x %d\n\n", numch_out, numch_out); - for (j = 0; j < numch_out; j++) - { - for (k = 0; k < numch_out; k++) + for (j = 0; j < numch_out; j++) { - fprintf(stdout, "%f, ", pState->spar_coeffs.P_re[j][k][b]); - } - fprintf(stdout, "\n"); + for (k = 0; k < numch_out; k++) + { + fprintf(stdout, "%f, ", hMdDec->spar_coeffs.P_re[j][k][b]); + } + fprintf(stdout, "\n"); - } + } }*/ #endif @@ -1278,12 +1274,12 @@ static void ivas_get_spar_matrices( { for ( b = 0; b < num_bands_out; b = b + bw ) { - dmx_ch = pState->spar_md_cfg.num_dmx_chans_per_band[b]; + dmx_ch = hMdDec->spar_md_cfg.num_dmx_chans_per_band[b]; for ( j = 0; j < numch_out; j++ ) { for ( k = dmx_ch; k < numch_out; k++ ) { - pState->spar_coeffs.P_re[j][k][( b + 1 ) + i_ts * IVAS_MAX_NUM_BANDS] = pState->spar_coeffs.P_re[j][k][b + i_ts * IVAS_MAX_NUM_BANDS]; + hMdDec->spar_coeffs.P_re[j][k][( b + 1 ) + i_ts * IVAS_MAX_NUM_BANDS] = hMdDec->spar_coeffs.P_re[j][k][b + i_ts * IVAS_MAX_NUM_BANDS]; } } @@ -1291,7 +1287,7 @@ static void ivas_get_spar_matrices( { for ( k = 0; k < dmx_ch; k++ ) { - pState->spar_coeffs.C_re[j][k][( b + 1 ) + i_ts * IVAS_MAX_NUM_BANDS] = pState->spar_coeffs.C_re[j][k][b + i_ts * IVAS_MAX_NUM_BANDS]; + hMdDec->spar_coeffs.C_re[j][k][( b + 1 ) + i_ts * IVAS_MAX_NUM_BANDS] = hMdDec->spar_coeffs.C_re[j][k][b + i_ts * IVAS_MAX_NUM_BANDS]; } } } @@ -1345,14 +1341,14 @@ void ivas_spar_dec_gen_umx_mat( const int16_t bfi /* i : bad frame indicator */ ) { - int16_t i, j, b, i_ts; - int16_t fb_ducking_flag = 0; - int16_t num_out_ch = hMdDec->spar_md_cfg.num_umx_chs; - ivas_spar_md_dec_state_t *pState = hMdDec; + int16_t i, j, b, i_ts, num_out_ch; + int16_t fb_ducking_flag = 0; // VE2DB: always 0 - can it be removed? + + num_out_ch = hMdDec->spar_md_cfg.num_umx_chs; for ( i_ts = 0; i_ts < MAX_PARAM_SPATIAL_SUBFRAMES; i_ts++ ) { - if ( pState->td_decorr_flag == 1 ) + if ( hMdDec->td_decorr_flag == 1 ) { for ( i = 0; i < num_out_ch; i++ ) { @@ -1360,7 +1356,7 @@ void ivas_spar_dec_gen_umx_mat( { for ( b = 0; b < num_bands_out; b++ ) { - pState->mixer_mat[i][j][b + i_ts * IVAS_MAX_NUM_BANDS] = pState->spar_coeffs.C_re[i][j][b + i_ts * IVAS_MAX_NUM_BANDS]; + hMdDec->mixer_mat[i][j][b + i_ts * IVAS_MAX_NUM_BANDS] = hMdDec->spar_coeffs.C_re[i][j][b + i_ts * IVAS_MAX_NUM_BANDS]; } } } @@ -1371,7 +1367,7 @@ void ivas_spar_dec_gen_umx_mat( { for ( b = 0; b < num_bands_out; b++ ) { - pState->mixer_mat[i][j][b + i_ts * IVAS_MAX_NUM_BANDS] = pState->spar_coeffs.P_re[i][j][b + i_ts * IVAS_MAX_NUM_BANDS]; + hMdDec->mixer_mat[i][j][b + i_ts * IVAS_MAX_NUM_BANDS] = hMdDec->spar_coeffs.P_re[i][j][b + i_ts * IVAS_MAX_NUM_BANDS]; } } } @@ -1389,7 +1385,7 @@ void ivas_spar_dec_gen_umx_mat( { for ( b = 0; b < num_bands_out; b++ ) { - pState->mixer_mat[i][j][b + i_ts * IVAS_MAX_NUM_BANDS] = pState->spar_coeffs.C_re[i][j][b + i_ts * IVAS_MAX_NUM_BANDS]; + hMdDec->mixer_mat[i][j][b + i_ts * IVAS_MAX_NUM_BANDS] = hMdDec->spar_coeffs.C_re[i][j][b + i_ts * IVAS_MAX_NUM_BANDS]; } } } @@ -1399,20 +1395,20 @@ void ivas_spar_dec_gen_umx_mat( /* for ( b = 0; b < 1; b++) { - fprintf( stdout, "\n\nMixer Matrix band %d\n\n", b ); - for ( i = 0; i < num_out_ch; i++ ) - { - for ( j = 0; j < num_out_ch; j++ ) + fprintf( stdout, "\n\nMixer Matrix band %d\n\n", b ); + for ( i = 0; i < num_out_ch; i++ ) { - fprintf( stdout, "%.2f,\t", pState->mixer_mat[i][j][0][b] ); + for ( j = 0; j < num_out_ch; j++ ) + { + fprintf( stdout, "%.2f,\t", hMdDec->mixer_mat[i][j][0][b] ); + } + fprintf( stdout, "\n" ); } fprintf( stdout, "\n" ); - } - fprintf( stdout, "\n" ); }*/ #endif - ivas_spar_dec_compute_ramp_down_post_matrix( pState, num_bands_out, bfi ); + ivas_spar_dec_compute_ramp_down_post_matrix( hMdDec, num_bands_out, bfi ); return; } @@ -1421,7 +1417,7 @@ void ivas_spar_dec_gen_umx_mat( /*-----------------------------------------------------------------------------------------* * Function ivas_spar_dec_parse_md_bs() * - * Parses SPAR MD bitstream + * Parse SPAR MD bitstream *-----------------------------------------------------------------------------------------*/ static void ivas_spar_dec_parse_md_bs( @@ -1437,7 +1433,6 @@ static void ivas_spar_dec_parse_md_bs( int16_t i, j, k, num_bands; uint16_t qsi; ivas_quant_strat_t qs; - ivas_spar_md_dec_state_t *pState = hMdDec; int16_t strat, freq_diff, no_ec; int16_t do_diff[IVAS_MAX_NUM_BANDS]; int16_t planarCP = 0; @@ -1445,13 +1440,17 @@ static void ivas_spar_dec_parse_md_bs( *dtx_vad = 1; *bands_bw = 1; qsi = 0; - num_bands = pState->spar_md.num_bands; + num_bands = hMdDec->spar_md.num_bands; - if ( pState->spar_md_cfg.gen_bs == 1 ) + if ( hMdDec->spar_md_cfg.gen_bs == 1 ) { +#ifdef ALIGN_SID_SIZE + if ( ivas_total_brate > IVAS_SID_5k2 ) +#else if ( ivas_total_brate > IVAS_SID_5k ) +#endif { - if ( pState->spar_md_cfg.quant_strat_bits > 0 ) + if ( hMdDec->spar_md_cfg.quant_strat_bits > 0 ) { if ( ivas_total_brate >= BRATE_SPAR_Q_STRAT ) { @@ -1467,11 +1466,11 @@ static void ivas_spar_dec_parse_md_bs( if ( sba_inactive_mode == 1 ) { *dtx_vad = 0; - qsi = pState->spar_md_cfg.quant_strat_bits + 1; + qsi = hMdDec->spar_md_cfg.quant_strat_bits + 1; } else { - qsi = get_next_indice( st0, pState->spar_md_cfg.quant_strat_bits ); + qsi = get_next_indice( st0, hMdDec->spar_md_cfg.quant_strat_bits ); } } } @@ -1496,10 +1495,10 @@ static void ivas_spar_dec_parse_md_bs( { for ( j = 0; j < IVAS_SPAR_MAX_CH - 1; j++ ) { - pState->spar_md.band_coeffs[i].pred_re[j] = 0; - pState->spar_md.band_coeffs[i].P_re[j] = 0; + hMdDec->spar_md.band_coeffs[i].pred_re[j] = 0; + hMdDec->spar_md.band_coeffs[i].P_re[j] = 0; } - pState->valid_bands[i] = 1; + hMdDec->valid_bands[i] = 1; } for ( i = 0; i < num_bands; i++ ) { @@ -1507,31 +1506,31 @@ static void ivas_spar_dec_parse_md_bs( { for ( k = 0; k < ( IVAS_SPAR_MAX_DMX_CHS - 1 ); k++ ) { - pState->spar_md.band_coeffs[i].C_re[j][k] = 0; + hMdDec->spar_md.band_coeffs[i].C_re[j][k] = 0; } } } - ivas_parse_parameter_bitstream_dtx( &pState->spar_md, st0, *bands_bw, *nB, - pState->spar_md_cfg.num_dmx_chans_per_band, pState->spar_md_cfg.num_decorr_per_band ); + 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 ); { int16_t ndec, b, idx; for ( i = *nB - 1; i >= 0; i-- ) { - ndec = pState->spar_md_cfg.num_decorr_per_band[( *bands_bw ) * i]; + ndec = hMdDec->spar_md_cfg.num_decorr_per_band[( *bands_bw ) * i]; for ( b = *bands_bw - 1; b >= 0; b-- ) { idx = i * *bands_bw + b; for ( j = 0; j < FOA_CHANNELS - 1; j++ ) { - pState->spar_md.band_coeffs[idx].pred_re[j] = pState->spar_md.band_coeffs[i].pred_re[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++ ) { - pState->spar_md.band_coeffs[idx].P_re[j] = pState->spar_md.band_coeffs[i].P_re[j]; + hMdDec->spar_md.band_coeffs[idx].P_re[j] = hMdDec->spar_md.band_coeffs[i].P_re[j]; } - pState->valid_bands[idx] = 1; + hMdDec->valid_bands[idx] = 1; } } *nB = num_bands; @@ -1541,7 +1540,7 @@ static void ivas_spar_dec_parse_md_bs( return; } - qs = pState->spar_md_cfg.quant_strat[qsi]; + qs = hMdDec->spar_md_cfg.quant_strat[qsi]; if ( ( qsi == 2 ) && ( use_planar_coeff ) ) { planarCP = 1; @@ -1585,164 +1584,122 @@ static void ivas_spar_dec_parse_md_bs( do_diff[i] = ( ( ( i + 1 ) & 3 ) != strat - 4 ); } - ivas_map_prior_coeffs_quant( &pState->spar_md_prev, &pState->spar_md_cfg, qsi, *nB ); + ivas_map_prior_coeffs_quant( &hMdDec->spar_md_prev, &hMdDec->spar_md_cfg, qsi, *nB ); } #ifdef SPAR_HOA_DBG fprintf( stdout, "\n\n no_ec = %d, strat = %d\n", no_ec, strat ); #endif - pState->spar_md_cfg.prev_quant_idx = qsi; + hMdDec->spar_md_cfg.prev_quant_idx = qsi; if ( no_ec == 0 ) { - ivas_decode_arith_bs( pState, st0, qsi, *nB, *bands_bw, do_diff, freq_diff, planarCP ); + ivas_decode_arith_bs( hMdDec, st0, qsi, *nB, *bands_bw, do_diff, freq_diff, planarCP ); } else { - ivas_decode_huffman_bs( pState, st0, qsi, *nB, *bands_bw, planarCP ); + ivas_decode_huffman_bs( hMdDec, st0, qsi, *nB, *bands_bw, planarCP ); } for ( i = 0; i < *nB; i++ ) { int16_t ii, jj; - int16_t *index_scratch[IVAS_SPAR_P_LOWERTRI]; - float *quant_scratch[IVAS_SPAR_P_LOWERTRI]; - int16_t ndec = pState->spar_md_cfg.num_decorr_per_band[( *bands_bw ) * i]; - int16_t ndm = pState->spar_md_cfg.num_dmx_chans_per_band[( *bands_bw ) * i]; - int16_t **index = (int16_t **) &index_scratch[0]; - float **quant = (float **) &quant_scratch[0]; - float coeff_decd[IVAS_SPAR_MAX_CH - 1]; - float coeff_decx_re[IVAS_SPAR_P_LOWERTRI]; - int16_t pred_index_re[IVAS_SPAR_MAX_CH - 1]; - int16_t drct_index_re[IVAS_SPAR_MAX_C_COEFF]; - int16_t decd_index_re[IVAS_SPAR_MAX_CH - 1]; - int16_t decx_index_re[IVAS_SPAR_P_LOWERTRI]; + int16_t ndec = hMdDec->spar_md_cfg.num_decorr_per_band[( *bands_bw ) * i]; + int16_t ndm = hMdDec->spar_md_cfg.num_dmx_chans_per_band[( *bands_bw ) * i]; + float quant[IVAS_SPAR_MAX_C_COEFF]; + ivas_deindex_real_index( hMdDec->spar_md.band_coeffs_idx[i].pred_index_re, qs.PR.q_levels[0], qs.PR.min, qs.PR.max, hMdDec->spar_md.band_coeffs[i].pred_re, ndm + ndec - 1 ); - for ( j = 0; j < ndm + ndec - 1; j++ ) - { - pred_index_re[j] = pState->spar_md.band_coeffs_idx[i].pred_index_re[j]; - } - for ( j = 0; j < ndec * ( ndm - 1 ); j++ ) - { - drct_index_re[j] = pState->spar_md.band_coeffs_idx[i].drct_index_re[j]; - } - for ( j = 0; j < ndec; j++ ) - { - decd_index_re[j] = pState->spar_md.band_coeffs_idx[i].decd_index_re[j]; - } - - index[0] = &pred_index_re[0]; - quant[0] = &pState->spar_md.band_coeffs[i].pred_re[0]; - - ivas_deindex_real_index( index, qs.PR.q_levels[0], qs.PR.min, qs.PR.max, quant, 1, ndm + ndec - 1 ); + j = 0; for ( ii = 0; ii < ndec; ii++ ) { for ( jj = 0; jj < ndm - 1; jj++ ) { - pState->spar_md.band_coeffs[i].C_re[ii][jj] = 0; + quant[j] = hMdDec->spar_md.band_coeffs[i].C_re[ii][jj]; + j++; } } + ivas_deindex_real_index( hMdDec->spar_md.band_coeffs_idx[i].drct_index_re, qs.C.q_levels[0], qs.C.min, qs.C.max, quant, ndec * ( ndm - 1 ) ); j = 0; for ( ii = 0; ii < ndec; ii++ ) { for ( jj = 0; jj < ndm - 1; jj++ ) { - index[j] = &drct_index_re[j]; - quant[j] = &pState->spar_md.band_coeffs[i].C_re[ii][jj]; + hMdDec->spar_md.band_coeffs[i].C_re[ii][jj] = quant[j]; j++; } } - ivas_deindex_real_index( index, qs.C.q_levels[0], qs.C.min, qs.C.max, quant, ndec * ( ndm - 1 ), 1 ); - - index[0] = &decd_index_re[0]; - quant[0] = &coeff_decd[0]; - ivas_deindex_real_index( index, qs.P_r.q_levels[0], qs.P_r.min, qs.P_r.max, quant, 1, ndm + ndec - 1 ); - - index[0] = &decx_index_re[0]; - quant[0] = &coeff_decx_re[0]; - ivas_deindex_real_index( index, qs.P_c.q_levels[0], qs.P_c.min, qs.P_c.max, quant, 1, ndec * ( ndec - 1 ) >> 2 ); - + ivas_deindex_real_index( hMdDec->spar_md.band_coeffs_idx[i].decd_index_re, qs.P_r.q_levels[0], qs.P_r.min, qs.P_r.max, hMdDec->spar_md.band_coeffs[i].P_re, ndm + ndec - 1 ); /* Store prior coefficient indices */ for ( j = 0; j < ndm + ndec - 1; j++ ) { - pState->spar_md_prev.band_coeffs_idx[i].pred_index_re[j] = pred_index_re[j]; + hMdDec->spar_md_prev.band_coeffs_idx[i].pred_index_re[j] = hMdDec->spar_md.band_coeffs_idx[i].pred_index_re[j]; } for ( j = 0; j < ndec * ( ndm - 1 ); j++ ) { - pState->spar_md_prev.band_coeffs_idx[i].drct_index_re[j] = drct_index_re[j]; - } - for ( j = 0; j < ndec; j++ ) - { - pState->spar_md_prev.band_coeffs_idx[i].decd_index_re[j] = decd_index_re[j]; - } - for ( k = 0; k < ndec; k++ ) - { - pState->spar_md.band_coeffs[i].P_re[k] = 0; + hMdDec->spar_md_prev.band_coeffs_idx[i].drct_index_re[j] = hMdDec->spar_md.band_coeffs_idx[i].drct_index_re[j]; } for ( j = 0; j < ndec; j++ ) { - /* Don't bother adding in the decx parameters */ - pState->spar_md.band_coeffs[i].P_re[j] = coeff_decd[j]; + hMdDec->spar_md_prev.band_coeffs_idx[i].decd_index_re[j] = hMdDec->spar_md.band_coeffs_idx[i].decd_index_re[j]; } - - pState->valid_bands[i] |= ( do_diff[i] == 0 ) ? 1 : 0; + hMdDec->valid_bands[i] |= ( do_diff[i] == 0 ) ? 1 : 0; } } else { - *dtx_vad = pState->spar_md.dtx_vad; + *dtx_vad = hMdDec->spar_md.dtx_vad; *nB = num_bands; *bands_bw = num_bands / *nB; for ( i = 0; i < *nB; i++ ) { - pState->valid_bands[i] = 1; + hMdDec->valid_bands[i] = 1; } } #ifdef SPAR_HOA_DBG int16_t b; b = 0; - /* if (0) + /*if ( 0 ) { for ( b = 0; b < *nB; b++ ) { - int16_t ndec = pState->spar_md_cfg.num_decorr_per_band[(*bands_bw) * b]; - int16_t ndm = pState->spar_md_cfg.num_dmx_chans_per_band[(*bands_bw) * b]; - fprintf(stdout, "\n\nMETADATA PR: band %d, qsi %d\n\n", b, qsi); - for (i = 0; i < ndm + ndec - 1; i++) + int16_t ndec = hMdDec->spar_md_cfg.num_decorr_per_band[( *bands_bw ) * b]; + int16_t ndm = hMdDec->spar_md_cfg.num_dmx_chans_per_band[( *bands_bw ) * b]; + fprintf( stdout, "\n\nMETADATA PR: band %d, qsi %d\n\n", b, qsi ); + for ( i = 0; i < ndm + ndec - 1; i++ ) { - fprintf(stdout, "i: %d -- %f\t %d\t %d\n", i, - pState->spar_md.band_coeffs[b].pred_re[i], - pState->spar_md_prev.band_coeffs_idx[b].pred_index_re[i], - pState->spar_md.band_coeffs_idx[b].pred_index_re[i]); + fprintf( stdout, "i: %d -- %f\t %d\t %d\n", i, + hMdDec->spar_md.band_coeffs[b].pred_re[i], + hMdDec->spar_md_prev.band_coeffs_idx[b].pred_index_re[i], + hMdDec->spar_md.band_coeffs_idx[b].pred_index_re[i] ); } - fprintf(stdout, "\n\n METADATA C: band %d\n\n", b); + fprintf( stdout, "\n\n METADATA C: band %d\n\n", b ); k = 0; - for (i = 0; i < ndec; i++) + for ( i = 0; i < ndec; i++ ) { - for (j = 0; j < (ndm - 1); j++) + for ( j = 0; j < ( ndm - 1 ); j++ ) { - fprintf(stdout, "i: %d -- %f\t %d\t %d\n", i, - pState->spar_md.band_coeffs[b].C_re[i][j], - pState->spar_md_prev.band_coeffs_idx[b].drct_index_re[k], - pState->spar_md.band_coeffs_idx[b].drct_index_re[k]); + fprintf( stdout, "i: %d -- %f\t %d\t %d\n", i, + hMdDec->spar_md.band_coeffs[b].C_re[i][j], + hMdDec->spar_md_prev.band_coeffs_idx[b].drct_index_re[k], + hMdDec->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 < ndec; i++) + fprintf( stdout, "\n\n METADATA Pd: band %d\n\n", b ); + for ( i = 0; i < ndec; i++ ) { - fprintf(stdout, "i: %d -- %f\t %d\t %d\n", i, - pState->spar_md.band_coeffs[b].P_re[i][i], - pState->spar_md_prev.band_coeffs_idx[b].decd_index_re[i], - pState->spar_md.band_coeffs_idx[b].decd_index_re[i]); + fprintf( stdout, "i: %d -- %f\t %d\t %d\n", i, + hMdDec->spar_md.band_coeffs[b].P_re[i][i], + hMdDec->spar_md_prev.band_coeffs_idx[b].decd_index_re[i], + hMdDec->spar_md.band_coeffs_idx[b].decd_index_re[i] ); } - fprintf(stdout, "\n\n"); - int16_t ndec = pState->spar_md_cfg.num_decorr_per_band[( *bands_bw ) * b]; - int16_t ndm = pState->spar_md_cfg.num_dmx_chans_per_band[( *bands_bw ) * b]; + fprintf( stdout, "\n\n" ); + int16_t ndec = hMdDec->spar_md_cfg.num_decorr_per_band[( *bands_bw ) * b]; + int16_t ndm = hMdDec->spar_md_cfg.num_dmx_chans_per_band[( *bands_bw ) * b]; fprintf( stdout, "\n\n Metadata PR (15x1), C(15x15), P(15x15): band %d\n", b ); for ( i = 0; i < ndm + ndec - 1; i++ ) { - fprintf( stdout, "i: %d -- %.2f\t|\t", i, pState->spar_md.band_coeffs[b].pred_re[i] ); + fprintf( stdout, "i: %d -- %.2f\t|\t", i, hMdDec->spar_md.band_coeffs[b].pred_re[i] ); if ( i < ndec ) { if ( keep_planar[i] == 1 ) @@ -1755,12 +1712,12 @@ static void ivas_spar_dec_parse_md_bs( } for ( j = 0; j < ndm - 1; j++ ) { - fprintf( stdout, "%.2f\t", pState->spar_md.band_coeffs[b].C_re[i][j] ); + fprintf( stdout, "%.2f\t", hMdDec->spar_md.band_coeffs[b].C_re[i][j] ); } fprintf( stdout, "|\t" ); for ( j = 0; j < ndec; j++ ) { - fprintf( stdout, "%.2f\t", pState->spar_md.band_coeffs[b].P_re[i][j] ); + fprintf( stdout, "%.2f\t", hMdDec->spar_md.band_coeffs[b].P_re[i][j] ); } } fprintf( stdout, "\n" ); @@ -1777,11 +1734,11 @@ static void ivas_spar_dec_parse_md_bs( /*-----------------------------------------------------------------------------------------* * Function ivas_decode_arith_bs() * - * decode bitstream with arith decoder + * Decode bitstream with arith decoder *-----------------------------------------------------------------------------------------*/ static void ivas_decode_arith_bs( - ivas_spar_md_dec_state_t *pState, + ivas_spar_md_dec_state_t *hMdDec, Decoder_State *st0, /* i/o: decoder state structure - for bitstream handling*/ const uint16_t qsi, const int16_t nB, @@ -1801,8 +1758,8 @@ static void ivas_decode_arith_bs( for ( i = 0; i < nB; i++ ) { - ndm = pState->spar_md_cfg.num_dmx_chans_per_band[bands_bw * i]; - ndec = pState->spar_md_cfg.num_decorr_per_band[bands_bw * i]; + ndm = hMdDec->spar_md_cfg.num_dmx_chans_per_band[bands_bw * i]; + ndec = hMdDec->spar_md_cfg.num_decorr_per_band[bands_bw * i]; pred_cell_dims[i].dim1 = ndm + ndec - 1; pred_cell_dims[i].dim2 = 1; @@ -1825,17 +1782,17 @@ static void ivas_decode_arith_bs( if ( any_diff == 1 ) { - ivas_copy_band_coeffs_idx_to_arr( pState->spar_md_prev.band_coeffs_idx_mapped, nB, symbol_arr_old_re, pred_cell_dims, PRED_COEFF, planarCP ); + ivas_copy_band_coeffs_idx_to_arr( hMdDec->spar_md_prev.band_coeffs_idx_mapped, nB, symbol_arr_old_re, pred_cell_dims, PRED_COEFF, planarCP ); } - ivas_arith_decode_cmplx_cell_array( &pState->arith_coeffs.pred_arith_re[qsi], &pState->arith_coeffs.pred_arith_re_diff[qsi], + ivas_arith_decode_cmplx_cell_array( &hMdDec->arith_coeffs.pred_arith_re[qsi], &hMdDec->arith_coeffs.pred_arith_re_diff[qsi], st0, pred_cell_dims, pDo_diff, nB, symbol_arr_re, symbol_arr_old_re ); - ivas_fill_band_coeffs_idx( pState->spar_md.band_coeffs_idx, nB, symbol_arr_re, pred_cell_dims, PRED_COEFF, planarCP ); + ivas_fill_band_coeffs_idx( hMdDec->spar_md.band_coeffs_idx, nB, symbol_arr_re, pred_cell_dims, PRED_COEFF, planarCP ); if ( any_diff == 1 ) { - ivas_copy_band_coeffs_idx_to_arr( pState->spar_md_prev.band_coeffs_idx_mapped, nB, symbol_arr_old_re, drct_cell_dims, DRCT_COEFF, planarCP ); + ivas_copy_band_coeffs_idx_to_arr( hMdDec->spar_md_prev.band_coeffs_idx_mapped, nB, symbol_arr_old_re, drct_cell_dims, DRCT_COEFF, planarCP ); } if ( planarCP ) @@ -1846,14 +1803,14 @@ static void ivas_decode_arith_bs( } } - ivas_arith_decode_cmplx_cell_array( &pState->arith_coeffs.drct_arith_re[qsi], &pState->arith_coeffs.drct_arith_re_diff[qsi], + ivas_arith_decode_cmplx_cell_array( &hMdDec->arith_coeffs.drct_arith_re[qsi], &hMdDec->arith_coeffs.drct_arith_re_diff[qsi], st0, drct_cell_dims, pDo_diff, nB, symbol_arr_re, symbol_arr_old_re ); - ivas_fill_band_coeffs_idx( pState->spar_md.band_coeffs_idx, nB, symbol_arr_re, drct_cell_dims, DRCT_COEFF, planarCP ); + ivas_fill_band_coeffs_idx( hMdDec->spar_md.band_coeffs_idx, nB, symbol_arr_re, drct_cell_dims, DRCT_COEFF, planarCP ); if ( any_diff == 1 ) { - ivas_copy_band_coeffs_idx_to_arr( pState->spar_md_prev.band_coeffs_idx_mapped, nB, symbol_arr_old_re, decd_cell_dims, DECD_COEFF, planarCP ); + ivas_copy_band_coeffs_idx_to_arr( hMdDec->spar_md_prev.band_coeffs_idx_mapped, nB, symbol_arr_old_re, decd_cell_dims, DECD_COEFF, planarCP ); } if ( planarCP ) @@ -1864,27 +1821,27 @@ static void ivas_decode_arith_bs( } } - ivas_arith_decode_cmplx_cell_array( &pState->arith_coeffs.decd_arith_re[qsi], &pState->arith_coeffs.decd_arith_re_diff[qsi], + ivas_arith_decode_cmplx_cell_array( &hMdDec->arith_coeffs.decd_arith_re[qsi], &hMdDec->arith_coeffs.decd_arith_re_diff[qsi], st0, decd_cell_dims, pDo_diff, nB, symbol_arr_re, symbol_arr_old_re ); - ivas_fill_band_coeffs_idx( pState->spar_md.band_coeffs_idx, nB, symbol_arr_re, decd_cell_dims, DECD_COEFF, planarCP ); + ivas_fill_band_coeffs_idx( hMdDec->spar_md.band_coeffs_idx, nB, symbol_arr_re, decd_cell_dims, DECD_COEFF, planarCP ); if ( any_diff == 1 ) { - ivas_copy_band_coeffs_idx_to_arr( pState->spar_md_prev.band_coeffs_idx_mapped, nB, symbol_arr_old_re, decx_cell_dims, DECX_COEFF, planarCP ); + ivas_copy_band_coeffs_idx_to_arr( hMdDec->spar_md_prev.band_coeffs_idx_mapped, nB, symbol_arr_old_re, decx_cell_dims, DECX_COEFF, planarCP ); } - ivas_fill_band_coeffs_idx( pState->spar_md.band_coeffs_idx, nB, symbol_arr_re, decx_cell_dims, DECX_COEFF, planarCP ); + ivas_fill_band_coeffs_idx( hMdDec->spar_md.band_coeffs_idx, nB, symbol_arr_re, decx_cell_dims, DECX_COEFF, planarCP ); if ( freq_diff == 1 ) { #ifdef SPAR_HOA_DBG /* NOTE: This is currently unused code, and SPAR_HOA changes have not been made here. */ #endif - ivas_get_band_idx_from_differential( &pState->spar_md, pState->spar_md_cfg.quant_strat->PR.q_levels, 0, nB, PRED_COEFF ); - ivas_get_band_idx_from_differential( &pState->spar_md, pState->spar_md_cfg.quant_strat->C.q_levels, 0, nB, DRCT_COEFF ); - ivas_get_band_idx_from_differential( &pState->spar_md, pState->spar_md_cfg.quant_strat->P_r.q_levels, 1, nB, DECD_COEFF ); - ivas_get_band_idx_from_differential( &pState->spar_md, pState->spar_md_cfg.quant_strat->P_c.q_levels, 0, nB, DECX_COEFF ); + ivas_get_band_idx_from_differential( &hMdDec->spar_md, hMdDec->spar_md_cfg.quant_strat->PR.q_levels, 0, nB, PRED_COEFF ); + ivas_get_band_idx_from_differential( &hMdDec->spar_md, hMdDec->spar_md_cfg.quant_strat->C.q_levels, 0, nB, DRCT_COEFF ); + ivas_get_band_idx_from_differential( &hMdDec->spar_md, hMdDec->spar_md_cfg.quant_strat->P_r.q_levels, 1, nB, DECD_COEFF ); + ivas_get_band_idx_from_differential( &hMdDec->spar_md, hMdDec->spar_md_cfg.quant_strat->P_c.q_levels, 0, nB, DECX_COEFF ); } return; @@ -1896,6 +1853,7 @@ static void ivas_decode_arith_bs( * * *-----------------------------------------------------------------------------------------*/ + #ifdef SPAR_HOA_DBG /* NOTE: No changes here as frequency differential coding is unused. */ #endif @@ -2055,11 +2013,11 @@ static void ivas_fill_band_coeffs_idx( /*-----------------------------------------------------------------------------------------* * Function ivas_decode_huffman_bs() * - * decode bitstream with huffman decoder + * Decode bitstream with huffman decoder *-----------------------------------------------------------------------------------------*/ static void ivas_decode_huffman_bs( - ivas_spar_md_dec_state_t *pState, + ivas_spar_md_dec_state_t *hMdDec, Decoder_State *st0, /* i/o: decoder state structure - for bitstream handling*/ const uint16_t qsi, const int16_t nB, @@ -2073,8 +2031,8 @@ static void ivas_decode_huffman_bs( int16_t ndm, ndec; int16_t pred_dim, drct_dim, decd_dim; - ndm = pState->spar_md_cfg.num_dmx_chans_per_band[bands_bw * i]; - ndec = pState->spar_md_cfg.num_decorr_per_band[bands_bw * i]; + ndm = hMdDec->spar_md_cfg.num_dmx_chans_per_band[bands_bw * i]; + ndec = hMdDec->spar_md_cfg.num_decorr_per_band[bands_bw * i]; pred_dim = ndec + ndm - 1; drct_dim = ndec * ( ndm - 1 ); @@ -2082,20 +2040,20 @@ static void ivas_decode_huffman_bs( for ( j = 0; j < pred_dim; j++ ) { - ivas_huffman_decode( &pState->huff_coeffs.pred_huff_re[qsi], st0, - &pState->spar_md.band_coeffs_idx[i].pred_index_re[j] ); + ivas_huffman_decode( &hMdDec->huff_coeffs.pred_huff_re[qsi], st0, + &hMdDec->spar_md.band_coeffs_idx[i].pred_index_re[j] ); } for ( j = 0; j < drct_dim; j++ ) { if ( planarCP && !keep_planar[(int16_t) floor( j / ( ndm - 1 ) )] ) { - pState->spar_md.band_coeffs_idx[i].drct_index_re[j] = 0; + hMdDec->spar_md.band_coeffs_idx[i].drct_index_re[j] = 0; } else { - ivas_huffman_decode( &pState->huff_coeffs.drct_huff_re[qsi], st0, - &pState->spar_md.band_coeffs_idx[i].drct_index_re[j] ); + ivas_huffman_decode( &hMdDec->huff_coeffs.drct_huff_re[qsi], st0, + &hMdDec->spar_md.band_coeffs_idx[i].drct_index_re[j] ); } } @@ -2103,12 +2061,12 @@ static void ivas_decode_huffman_bs( { if ( planarCP && !keep_planar[j] ) { - pState->spar_md.band_coeffs_idx[i].decd_index_re[j] = 0; + hMdDec->spar_md.band_coeffs_idx[i].decd_index_re[j] = 0; } else { - ivas_huffman_decode( &pState->huff_coeffs.decd_huff_re[qsi], st0, - &pState->spar_md.band_coeffs_idx[i].decd_index_re[j] ); + ivas_huffman_decode( &hMdDec->huff_coeffs.decd_huff_re[qsi], st0, + &hMdDec->spar_md.band_coeffs_idx[i].decd_index_re[j] ); } } } @@ -2120,14 +2078,14 @@ static void ivas_decode_huffman_bs( /*-----------------------------------------------------------------------------------------* * Function ivas_spar_md_fill_invalid_bands() * - * fill invalid bands in interpolation/extrapolation of valid bands + * Fill invalid bands in interpolation/extrapolation of valid bands * when PLC is to be done with partial time differential coding *-----------------------------------------------------------------------------------------*/ static void ivas_spar_md_fill_invalid_bands( ivas_spar_dec_matrices_t *pSpar_coeffs, ivas_spar_dec_matrices_t *pSpar_coeffs_prev, - int16_t *valid_bands, + const int16_t *valid_bands, int16_t *base_band_age, const int16_t num_bands, const int16_t sba_order /* i : SBA order */ @@ -2242,44 +2200,43 @@ static void ivas_spar_md_fill_invalid_bands( /*-----------------------------------------------------------------------------------------* -* Function ivas_spar_dec_compute_ramp_down_post_matrix() -* -* ivas_spar_dec_compute_ramp_down_post_matrix - -*-----------------------------------------------------------------------------------------*/ + * Function ivas_spar_dec_compute_ramp_down_post_matrix() + * + * + *-----------------------------------------------------------------------------------------*/ static void ivas_spar_dec_compute_ramp_down_post_matrix( - ivas_spar_md_dec_state_t *pState, + ivas_spar_md_dec_state_t *hMdDec, const int16_t num_bands_out, const int16_t bfi ) { int16_t num_in_ch, num_out_ch, i, j, b; - num_in_ch = pState->spar_md_cfg.num_umx_chs; - num_out_ch = pState->spar_md_cfg.num_umx_chs; + num_in_ch = hMdDec->spar_md_cfg.num_umx_chs; + num_out_ch = hMdDec->spar_md_cfg.num_umx_chs; if ( bfi == 0 ) { - pState->spar_plc_num_lost_frames = 0; + hMdDec->spar_plc_num_lost_frames = 0; } else { - if ( pState->td_decorr_flag == 0 ) + if ( hMdDec->td_decorr_flag == 0 ) { assert( 0 ); } - pState->spar_plc_num_lost_frames += 1; - pState->spar_plc_num_lost_frames = min( pState->spar_plc_num_lost_frames, 100 ); + hMdDec->spar_plc_num_lost_frames += 1; + hMdDec->spar_plc_num_lost_frames = min( hMdDec->spar_plc_num_lost_frames, 100 ); - if ( pState->spar_plc_num_lost_frames > ivas_spar_dec_plc_num_frames_keep ) + if ( hMdDec->spar_plc_num_lost_frames > ivas_spar_dec_plc_num_frames_keep ) { int16_t num_fade_frames; int16_t gain_dB; float gain; float post_matrix[IVAS_SPAR_MAX_CH]; - num_fade_frames = max( pState->spar_plc_num_lost_frames - ivas_spar_dec_plc_num_frames_keep, 0 ); + num_fade_frames = max( hMdDec->spar_plc_num_lost_frames - ivas_spar_dec_plc_num_frames_keep, 0 ); gain_dB = -min( num_fade_frames, ivas_spar_dec_plc_max_num_frames_ramp_down ) * ivas_spar_dec_plc_per_frame_ramp_down_gain_dB; gain = powf( 10, ( ( (float) gain_dB ) / 20 ) ); @@ -2298,7 +2255,7 @@ static void ivas_spar_dec_compute_ramp_down_post_matrix( { for ( b = 0; b < num_bands_out; b++ ) { - pState->mixer_mat[i][j][b + i_ts * IVAS_MAX_NUM_BANDS] *= post_matrix[i]; + hMdDec->mixer_mat[i][j][b + i_ts * IVAS_MAX_NUM_BANDS] *= post_matrix[i]; } } } @@ -2313,7 +2270,7 @@ static void ivas_spar_dec_compute_ramp_down_post_matrix( /*-----------------------------------------------------------------------------------------* * Function ivas_spar_unquant_dtx_indicies() * - * Unquantize spar md DYX indices + * Unquantize SPAR MD DYX indices *-----------------------------------------------------------------------------------------*/ #ifdef SPAR_HOA_DBG @@ -2327,35 +2284,28 @@ static void ivas_spar_unquant_dtx_indicies( { int16_t i, b; int16_t q_lvl; - float **ppVal, *pVal, val; - int16_t **ppIdx, *pIdx, idx; + float val; + int16_t idx; float pr_min_max[2]; pr_min_max[0] = pSpar_md->min_max[0]; pr_min_max[1] = pSpar_md->min_max[1]; - - ppVal = (float **) &pVal; - ppIdx = (int16_t **) &pIdx; - - ppVal[0] = (float *) &val; - ppIdx[0] = (int16_t *) &idx; - for ( b = 0; b < nB; b++ ) { for ( i = 0; i < FOA_CHANNELS - 1; i++ ) { q_lvl = dtx_pr_real_q_levels[ndm_per_band[bw * b] - 1][i]; - ppIdx[0][0] = pSpar_md->band_coeffs_idx[b].pred_index_re[i]; - ivas_deindex_real_index( ppIdx, q_lvl, pr_min_max[0], pr_min_max[1], ppVal, 1, 1 ); - pSpar_md->band_coeffs[b].pred_re[i] = ppVal[0][0]; + idx = pSpar_md->band_coeffs_idx[b].pred_index_re[i]; + ivas_deindex_real_index( &idx, q_lvl, pr_min_max[0], pr_min_max[1], &val, 1 ); + pSpar_md->band_coeffs[b].pred_re[i] = val; } for ( i = 0; i < FOA_CHANNELS - ndm_per_band[bw * b]; i++ ) { q_lvl = dtx_pd_real_q_levels[ndm_per_band[bw * b] - 1][i]; - ppIdx[0][0] = pSpar_md->band_coeffs_idx[b].decd_index_re[i]; - ivas_deindex_real_index( ppIdx, q_lvl, dtx_pd_real_min_max[0], dtx_pd_real_min_max[1], ppVal, 1, 1 ); - pSpar_md->band_coeffs[b].P_re[i] = ppVal[0][0]; + idx = pSpar_md->band_coeffs_idx[b].decd_index_re[i]; + ivas_deindex_real_index( &idx, q_lvl, dtx_pd_real_min_max[0], dtx_pd_real_min_max[1], &val, 1 ); + pSpar_md->band_coeffs[b].P_re[i] = val; } } @@ -2378,19 +2328,13 @@ static void ivas_parse_parameter_bitstream_dtx( int16_t *num_dec_per_band ) { int16_t i, j; - float **ppVal, *pVal, val; - int16_t **ppIdx, *pIdx, idx; + float val; + int16_t idx; float pr_min_max[2]; int16_t pr_q_lvls, pr, pd, pd_q_lvls, pr_pd_bits; int16_t pr_q_lvls1, pr_q_lvls2, pr_idx1, pr_idx2, pr_pr_bits; int16_t zero_pad_bits, sid_bits_len; sid_bits_len = st0->next_bit_pos; - ppVal = (float **) &pVal; - ppIdx = (int16_t **) &pIdx; - - ppVal[0] = (float *) &val; - ppIdx[0] = (int16_t *) &idx; - pr_min_max[0] = pSpar_md->min_max[0]; pr_min_max[1] = pSpar_md->min_max[1]; @@ -2430,16 +2374,13 @@ static void ivas_parse_parameter_bitstream_dtx( pr = (int16_t) floor( value / pd_q_lvls ); pd = value - pr * pd_q_lvls; + val = dtx_pd_real_min_max[0]; + ivas_quantise_real_values( &val, pd_q_lvls, dtx_pd_real_min_max[0], dtx_pd_real_min_max[1], &idx, &val, 1 ); + pd = pd + idx; - ppVal[0][0] = dtx_pd_real_min_max[0]; - ivas_quantise_real_values( ppVal, pd_q_lvls, dtx_pd_real_min_max[0], dtx_pd_real_min_max[1], ppIdx, ppVal, 1, 1 ); - - pd = pd + ppIdx[0][0]; - - ppVal[0][0] = pr_min_max[0]; - ivas_quantise_real_values( ppVal, pr_q_lvls, pr_min_max[0], pr_min_max[1], ppIdx, ppVal, 1, 1 ); - - pr = pr + ppIdx[0][0]; + val = pr_min_max[0]; + ivas_quantise_real_values( &val, pr_q_lvls, pr_min_max[0], pr_min_max[1], &idx, &val, 1 ); + pr = pr + idx; if ( ( j + 1 ) <= ndec ) { @@ -2459,17 +2400,15 @@ static void ivas_parse_parameter_bitstream_dtx( pr_idx2 = (int16_t) floor( value / pr_q_lvls1 ); pr_idx1 = value - pr_idx2 * pr_q_lvls1; + val = pr_min_max[0]; + ivas_quantise_real_values( &val, pr_q_lvls1, pr_min_max[0], pr_min_max[1], &idx, &val, 1 ); - ppVal[0][0] = pr_min_max[0]; - ivas_quantise_real_values( ppVal, pr_q_lvls1, pr_min_max[0], pr_min_max[1], ppIdx, ppVal, 1, 1 ); - - pr_idx1 += ppIdx[0][0]; + pr_idx1 += idx; - ppVal[0][0] = pr_min_max[0]; - ivas_quantise_real_values( ppVal, pr_q_lvls2, pr_min_max[0], pr_min_max[1], ppIdx, ppVal, 1, 1 ); - - pr_idx2 += ppIdx[0][0]; + val = pr_min_max[0]; + ivas_quantise_real_values( &val, pr_q_lvls2, pr_min_max[0], pr_min_max[1], &idx, &val, 1 ); + pr_idx2 += idx; pSpar_md->band_coeffs_idx[i].pred_index_re[pr_idx_1 - 1] = pr_idx1; pSpar_md->band_coeffs_idx[i].pred_index_re[pr_idx_2 - 1] = pr_idx2; } @@ -2494,19 +2433,18 @@ static void ivas_parse_parameter_bitstream_dtx( /*-----------------------------------------------------------------------------------------* * Function ivas_deindex_real_index() * - * deindex real index + * Deindex real index *-----------------------------------------------------------------------------------------*/ static ivas_error ivas_deindex_real_index( - int16_t **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, - const int16_t dim2 ) + float *quant, + const int16_t dim ) { - int16_t i, j; + int16_t i; float q_step; if ( q_levels == 0 ) @@ -2516,24 +2454,17 @@ static ivas_error ivas_deindex_real_index( if ( q_levels == 1 ) { - for ( i = 0; i < num_ch; i++ ) + for ( i = 0; i < dim; i++ ) { - for ( j = 0; j < dim2; j++ ) - { - quant[i][j] = 0; - } + quant[i] = 0; } } else { q_step = ( max_value - min_value ) / ( q_levels - 1 ); - - for ( i = 0; i < num_ch; i++ ) + for ( i = 0; i < dim; i++ ) { - for ( j = 0; j < dim2; j++ ) - { - quant[i][j] = index[i][j] * q_step; - } + quant[i] = index[i] * q_step; } } @@ -2577,11 +2508,8 @@ void ivas_spar_to_dirac( int16_t pred_idx; int16_t *dirac_to_spar_md_bands; int16_t enc_param_start_band; -#ifndef SBA_ORDER_BITSTREAM - sba_order_internal = min( st_ivas->sba_order, IVAS_MAX_SBA_ORDER ); -#else + sba_order_internal = min( st_ivas->sba_analysis_order, IVAS_MAX_SBA_ORDER ); -#endif start_band = 0; end_band = min( num_bands_out, SPAR_DIRAC_SPLIT_START_BAND ); diff --git a/lib_dec/ivas_stat_dec.h b/lib_dec/ivas_stat_dec.h index 29ae9867ca..f653dcc010 100644 --- a/lib_dec/ivas_stat_dec.h +++ b/lib_dec/ivas_stat_dec.h @@ -254,7 +254,7 @@ typedef struct stereo_dec_cng int16_t xfade_length; /* number of frames to perform xfade */ int16_t nr_dft_frames; /* dft frame counter */ int16_t nr_corr_frames; /* correlation frame counter */ - int16_t nr_sid_frames; /* sid frame counter */ + int16_t nr_sid_frames; /* SID frame counter */ int16_t last_act_element_mode; /* Element mode of last active frame */ float olapBufferSynth22[FFTLEN]; /* overlap buffer for secondary channel CNA */ int16_t flag_cna_fade; /* flag enabling CNA fade out */ @@ -321,7 +321,7 @@ typedef struct stereo_mdct_dec_data_structure int16_t prev_ms_mask[NB_DIV][MAX_SFB]; float lastCoh; -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE int16_t noise_seeds_channels[CPE_CHANNELS]; int16_t noise_seed_common; #endif @@ -1630,19 +1630,36 @@ typedef struct ivas_binaural_td_rendering_struct typedef struct ivas_hrtfs_structure { +#ifdef FIX_CREND_CHANNELS + float *pOut_to_bin_re[MAX_TRANSPORT_CHANNELS][BINAURAL_CHANNELS]; + float *pOut_to_bin_im[MAX_TRANSPORT_CHANNELS][BINAURAL_CHANNELS]; +#else float *pOut_to_bin_re[IVAS_MAX_NUM_CH][BINAURAL_CHANNELS]; float *pOut_to_bin_im[IVAS_MAX_NUM_CH][BINAURAL_CHANNELS]; +#endif float *pOut_to_bin_diffuse_re[BINAURAL_CHANNELS]; float *pOut_to_bin_diffuse_im[BINAURAL_CHANNELS]; float latency_s; +#ifdef FIX_CREND_CHANNELS + uint16_t num_iterations[MAX_TRANSPORT_CHANNELS][BINAURAL_CHANNELS]; +#else uint16_t num_iterations[IVAS_MAX_NUM_CH][BINAURAL_CHANNELS]; +#endif uint16_t num_iterations_diffuse[BINAURAL_CHANNELS]; +#ifdef FIX_CREND_CHANNELS + uint16_t *pIndex_frequency_max[MAX_TRANSPORT_CHANNELS][BINAURAL_CHANNELS]; +#else uint16_t *pIndex_frequency_max[IVAS_MAX_NUM_CH][BINAURAL_CHANNELS]; +#endif uint16_t *pIndex_frequency_max_diffuse[BINAURAL_CHANNELS]; uint16_t index_frequency_max_diffuse; int16_t max_num_ir; int16_t max_num_iterations; +#ifdef FIX_CREND_CHANNELS + float inv_diffuse_weight[MAX_TRANSPORT_CHANNELS]; /* inverse diffuse weights array, access one inverse weight by pInvDiffuseWeight[channel] */ +#else float inv_diffuse_weight[IVAS_MAX_NUM_CH]; /* inverse diffuse weights array, access one inverse weight by pInvDiffuseWeight[channel] */ +#endif float gain_lfe; } HRTFS_DATA, *HRTFS_HANDLE; @@ -1783,8 +1800,13 @@ typedef struct ivas_orient_trk_state_t /* Crend structures */ typedef struct ivas_crend_state_t { +#ifdef FIX_CREND_CHANNELS + float *freq_buffer_re[MAX_TRANSPORT_CHANNELS]; + float *freq_buffer_im[MAX_TRANSPORT_CHANNELS]; +#else float *freq_buffer_re[IVAS_MAX_NUM_CH]; float *freq_buffer_im[IVAS_MAX_NUM_CH]; +#endif float *freq_buffer_re_diffuse; float *freq_buffer_im_diffuse; float *prev_out_buffer[BINAURAL_CHANNELS]; @@ -1854,13 +1876,10 @@ typedef struct decoder_config_structure int32_t output_Fs; /* output signal sampling frequency in Hz */ int16_t nchan_out; /* number of output audio channels */ AUDIO_CONFIG output_config; /* output audio configuration */ -#ifdef SBA_ORDER_BITSTREAM - int16_t sba_order; -#endif - int16_t Opt_LsCustom; /* indicates whether loudspeaker custom setup is used */ - int16_t Opt_HRTF_binary; /* indicates whether HRTF binary file is used */ - int16_t Opt_Headrotation; /* indicates whether head-rotation is used */ - int16_t orientation_tracking; /* indicates orientation tracking type */ + int16_t Opt_LsCustom; /* indicates whether loudspeaker custom setup is used */ + int16_t Opt_HRTF_binary; /* indicates whether HRTF binary file is used */ + int16_t Opt_Headrotation; /* indicates whether head-rotation is used */ + int16_t orientation_tracking; /* indicates orientation tracking type */ float no_diegetic_pan; int16_t Opt_AMR_WB; /* flag indicating AMR-WB IO mode */ @@ -1929,12 +1948,9 @@ typedef struct Decoder_Struct ISM_MODE ism_mode; /* ISM format mode */ SBA_MODE sba_mode; /* SBA format mode */ MC_MODE mc_mode; /* MC format mode */ -#ifdef SBA_ORDER_BITSTREAM - int16_t sba_analysis_order; /* Ambisonic (SBA) order */ -#else int16_t sba_order; /* Ambisonic (SBA) order */ -#endif int16_t sba_planar; /* Ambisonic (SBA) planar flag */ + int16_t sba_analysis_order; /* Ambisonic (SBA) order used for analysis and coding */ int16_t sba_dirac_stereo_flag; /* flag indicating stereo output for SBA DirAC modes with 1 TC */ /* rendering modules */ diff --git a/lib_dec/ivas_stereo_cng_dec.c b/lib_dec/ivas_stereo_cng_dec.c index 05e9222ddb..491a88da3f 100644 --- a/lib_dec/ivas_stereo_cng_dec.c +++ b/lib_dec/ivas_stereo_cng_dec.c @@ -90,7 +90,12 @@ void stereo_dft_dec_sid_coh( int16_t bits_tmp; int16_t b; +#ifdef ALIGN_SID_SIZE + /* TODO: still use old number of bits to keep bitexactness in output */ + nr_of_sid_stereo_bits = ( 4400 /*IVAS_SID_5k2*/ - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS; +#else nr_of_sid_stereo_bits = ( IVAS_SID_4k4 - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS; +#endif /* If the coherence is not encoded due to lack of bits set alpha to zero which leads to that the coherence */ /* from the previous frame is used. */ @@ -173,6 +178,9 @@ void stereo_dft_dec_sid_coh( ( *nb_bits )++; } +#ifdef ALIGN_SID_SIZE + dtx_read_padding_bits( st, ( IVAS_SID_5k2 - 4400 ) / FRAMES_PER_SEC ); +#endif return; } @@ -653,9 +661,17 @@ void stereo_dtf_cng( hCPE->hStereoCng->nr_dft_frames++; } +#ifdef ALIGN_SID_SIZE + if ( ivas_total_brate <= IVAS_SID_5k2 ) +#else if ( ivas_total_brate <= IVAS_SID_4k4 ) +#endif { +#ifdef ALIGN_SID_SIZE + if ( hCPE->hStereoCng->nr_sid_frames < SID_INIT && ivas_total_brate == IVAS_SID_5k2 ) +#else if ( hCPE->hStereoCng->nr_sid_frames < SID_INIT && ivas_total_brate == IVAS_SID_4k4 ) +#endif { hCPE->hStereoCng->nr_sid_frames++; } @@ -707,7 +723,11 @@ void stereo_cng_dec_update( if ( hCPE->element_mode == IVAS_CPE_DFT ) { +#ifdef ALIGN_SID_SIZE + if ( ivas_total_brate == IVAS_SID_5k2 || ivas_total_brate == FRAME_NO_DATA ) +#else if ( ivas_total_brate == IVAS_SID_4k4 || ivas_total_brate == FRAME_NO_DATA ) +#endif { hCPE->hStereoCng->prev_sid_nodata = 1; } diff --git a/lib_dec/ivas_stereo_dft_dec.c b/lib_dec/ivas_stereo_dft_dec.c index 074efaa1a2..b0db814511 100644 --- a/lib_dec/ivas_stereo_dft_dec.c +++ b/lib_dec/ivas_stereo_dft_dec.c @@ -1746,7 +1746,11 @@ void stereo_dft_dec_read_BS( * Initialization *-----------------------------------------------------------------*/ +#ifdef ALIGN_SID_SIZE + if ( ivas_total_brate == IVAS_SID_5k2 ) +#else if ( ivas_total_brate == IVAS_SID_4k4 ) +#endif { if ( ivas_format == MASA_FORMAT ) { @@ -1760,7 +1764,11 @@ void stereo_dft_dec_read_BS( hStereoDft->frame_nodata = 0; hStereoDft->frame_sid_nodata = 1; hStereoDft->frame_sid = 1; +#ifdef ALIGN_SID_SIZE + *nb_bits = ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS; +#else *nb_bits = ( IVAS_SID_4k4 - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS; +#endif } } else if ( ivas_total_brate == FRAME_NO_DATA ) @@ -1803,7 +1811,11 @@ void stereo_dft_dec_read_BS( k_offset = STEREO_DFT_OFFSET; N_div = STEREO_DFT_NBDIV; +#ifdef ALIGN_SID_SIZE + if ( ivas_total_brate > IVAS_SID_5k2 ) +#else if ( ivas_total_brate > IVAS_SID_4k4 ) +#endif { mvr2r( hStereoDft->side_gain + 2 * STEREO_DFT_BAND_MAX, sg_tmp, STEREO_DFT_BAND_MAX ); mvr2r( hStereoDft->res_pred_gain + 2 * STEREO_DFT_BAND_MAX, res_pred_gain_tmp, STEREO_DFT_BAND_MAX ); @@ -1893,7 +1905,11 @@ void stereo_dft_dec_read_BS( fprintf( pF, "ITD: %d ", hStereoDft->hConfig->itd_mode ); #endif +#ifdef ALIGN_SID_SIZE + if ( !( ivas_format == MASA_FORMAT && ivas_total_brate <= IVAS_SID_5k2 ) ) +#else if ( !( ivas_format == MASA_FORMAT && ivas_total_brate <= IVAS_SID_4k4 ) ) +#endif { /*------------------------------------------------------------------* * read Side gains @@ -1974,7 +1990,11 @@ void stereo_dft_dec_read_BS( #endif } } +#ifdef ALIGN_SID_SIZE + 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 ) ) +#else else if ( *nb_bits <= ( ( IVAS_SID_4k4 - SID_2k40 ) / FRAMES_PER_SEC - STEREO_DFT_ITD_MODE_NBITS - STEREO_DFT_SID_ITD_NBITS - 1 - SID_FORMAT_NBITS ) ) +#endif { itd_mode = get_next_indice( st, STEREO_DFT_ITD_MODE_NBITS ); ( *nb_bits ) += STEREO_DFT_ITD_MODE_NBITS; /*ITD mode flag: 1bit*/ @@ -2016,7 +2036,11 @@ void stereo_dft_dec_read_BS( stereo_dft_dequantize_ipd( &ind1_ipd[0], hStereoDft->gipd + ( k + k_offset ), 1, STEREO_DFT_GIPD_NBITS ); } } +#ifdef ALIGN_SID_SIZE + else if ( *nb_bits <= ( ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC - STEREO_DFT_FLAG_BITS - STEREO_DFT_SID_GIPD_NBITS - SID_FORMAT_NBITS ) ) +#else else if ( *nb_bits <= ( ( IVAS_SID_4k4 - SID_2k40 ) / FRAMES_PER_SEC - STEREO_DFT_FLAG_BITS - STEREO_DFT_SID_GIPD_NBITS - SID_FORMAT_NBITS ) ) +#endif { /* SID frame, only read IPD only if enough bits left in bitstream */ hStereoDft->no_ipd_flag = st->bit_stream[nb]; @@ -2177,7 +2201,11 @@ void stereo_dft_dec_read_BS( #endif } +#ifdef ALIGN_SID_SIZE + if ( !( ivas_format == MASA_FORMAT && ivas_total_brate <= IVAS_SID_5k2 ) ) +#else if ( !( ivas_format == MASA_FORMAT && ivas_total_brate <= IVAS_SID_4k4 ) ) +#endif { if ( hStereoDft->side_gain_flag_1 != 2 ) { @@ -2185,7 +2213,11 @@ void stereo_dft_dec_read_BS( } } +#ifdef ALIGN_SID_SIZE + if ( ivas_total_brate > IVAS_SID_5k2 ) +#else if ( ivas_total_brate > IVAS_SID_4k4 ) +#endif { hStereoDft->recovery_flg = stereo_dft_sg_recovery( hStereoDft ); @@ -2252,12 +2284,20 @@ void stereo_dft_dec_read_BS( #endif } +#ifdef ALIGN_SID_SIZE + if ( hStereoDft->frame_sid && !( ivas_format == MASA_FORMAT && ivas_total_brate <= IVAS_SID_5k2 ) ) +#else if ( hStereoDft->frame_sid && !( ivas_format == MASA_FORMAT && ivas_total_brate <= IVAS_SID_4k4 ) ) +#endif { stereo_dft_dec_sid_coh( st, hStereoDft->nbands, coh, nb_bits ); } +#ifdef ALIGN_SID_SIZE + if ( ivas_total_brate == IVAS_SID_5k2 && ivas_format != MASA_FORMAT ) +#else if ( ivas_total_brate == IVAS_SID_4k4 && ivas_format != MASA_FORMAT ) +#endif { *nb_bits = (int16_t) ( ( element_brate - SID_2k40 ) / FRAMES_PER_SEC ); /* => hCPE->hCoreCoder[0]->total_brate = SID_2k40; */ } diff --git a/lib_dec/ivas_stereo_mdct_core_dec.c b/lib_dec/ivas_stereo_mdct_core_dec.c index 3d4c38f272..beb121a1fc 100644 --- a/lib_dec/ivas_stereo_mdct_core_dec.c +++ b/lib_dec/ivas_stereo_mdct_core_dec.c @@ -50,7 +50,7 @@ *-------------------------------------------------------------------------*/ static void apply_dmx_weights( CPE_DEC_HANDLE hCPE, float *x[CPE_CHANNELS][NB_DIV], int16_t transform_type_left[NB_DIV], int16_t transform_type_right[NB_DIV] ); -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE static void run_min_stats( Decoder_State **sts, float *x[CPE_CHANNELS][NB_DIV] ); #endif @@ -218,11 +218,13 @@ void stereo_mdct_core_dec( initMdctStereoDecData( hCPE->hStereoMdct, sts[0]->igf, sts[0]->hIGFDec->igfData.igfInfo.grid, hCPE->element_brate, sts[0]->bwidth ); hCPE->hStereoMdct->isSBAStereoMode = ( ( st_ivas->ivas_format == SBA_FORMAT ) && ( st_ivas->nchan_transport == 2 ) ); +#ifndef FIX_135_MDCT_STEREO_MODE_UNINITIALIZED /*to prevent unitialized values during condition checks for stereo IGF*/ if ( hCPE->hStereoMdct->isSBAStereoMode ) { set_s( hCPE->hStereoMdct->IGFStereoMode, -1, 2 ); } +#endif if ( !bfi ) { @@ -299,7 +301,11 @@ void stereo_mdct_core_dec( assert( ( sts[0]->core == sts[1]->core ) || ( hCPE->hStereoMdct->mdct_stereo_mode[0] == SMDCT_DUAL_MONO ) ); /* stereo IGF decoding */ +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE + decoder_tcx_IGF_stereo( sts, hCPE->hStereoMdct, ms_mask, x, L_frame[0], left_rect[0], k, bfi, 0 /* <- is_mct */ ); +#else decoder_tcx_IGF_stereo( sts, hCPE->hStereoMdct, ms_mask, x, L_frame[0], left_rect[0], k, bfi ); +#endif } else { @@ -329,34 +335,14 @@ void stereo_mdct_core_dec( sns_interpolate_scalefactors( &sns_int_scf[0], &Aq[ch][k * M], DEC ); -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE if ( st->hTonalMDCTConc != NULL && ( ( k + 1 ) == nSubframes[ch] ) ) #else if ( st->hTonalMDCTConc != NULL ) #endif { -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT - int16_t infoIGFStartLine; - - if ( st->igf == 0 ) - { - if ( st->narrowBand == 0 ) - { - /* minimum needed for output with sampling rates lower then the - nominal sampling rate */ - infoIGFStartLine = min( L_frameTCX[ch], L_frame[ch] ); - } - else - { - infoIGFStartLine = L_frameTCX[ch]; - } - } - else - { - infoIGFStartLine = min( st->hIGFDec->infoIGFStartLine, L_frameTCX[ch] ); - } - - TonalMDCTConceal_SaveFreqSignal( st->hTonalMDCTConc, x[ch][k], L_frameTCX[ch], L_frame[ch], &sns_int_scf[0], infoIGFStartLine ); +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE + TonalMDCTConceal_SaveFreqSignal( st->hTonalMDCTConc, x[ch][k], L_frameTCX[ch], L_frame[ch], &sns_int_scf[0], get_igf_startline( st, L_frame[ch], L_frameTCX[ch] ) ); #else TonalMDCTConceal_SaveFreqSignal( st->hTonalMDCTConc, x[ch][k], L_frameTCX[ch], L_frame[ch], &sns_int_scf[0] ); #endif @@ -381,13 +367,12 @@ void stereo_mdct_core_dec( ivas_mdct_core_tns_ns( hCPE, 0, fUseTns, tnsData, x, Aq, 0 ); - if ( - st_ivas->renderer_type == RENDERER_MC_PARAMMC && ( st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_MONO || st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_STEREO ) ) + if ( st_ivas->renderer_type == RENDERER_MC_PARAMMC && ( st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_MONO || st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_STEREO ) ) { ivas_ls_setup_conversion_process_mdct_param_mc( st_ivas, x ); } -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE run_min_stats( sts, x ); #endif @@ -608,7 +593,7 @@ static void apply_dmx_weights( return; } -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE /*-------------------------------------------------------------------* * run_min_stats() * diff --git a/lib_dec/ivas_stereo_mdct_stereo_dec.c b/lib_dec/ivas_stereo_mdct_stereo_dec.c index f797eaf289..10b9688be2 100644 --- a/lib_dec/ivas_stereo_mdct_stereo_dec.c +++ b/lib_dec/ivas_stereo_mdct_stereo_dec.c @@ -57,7 +57,7 @@ void parse_stereo_from_bitstream( STEREO_MDCT_DEC_DATA_HANDLE hStereoMdct, /* i/o: MDCT stereo decoder structure */ Decoder_State **sts, /* i/o: decoder state structure */ const int16_t mct_on, /* i : flag mct block (1) or stereo (0)*/ - const int16_t isSBAStereoMode, /* i : flag core coding for sba */ + const int16_t isSBAStereoMode, /* i : flag core coding for SBA */ Decoder_State *st0, /* i/o: decoder state structure for Bstr*/ int16_t ms_mask[NB_DIV][MAX_SFB] /* o : bandwise MS mask */ ) @@ -559,13 +559,21 @@ void updateBuffersForDmxMdctStereo( sts[1] = hCPE->hCoreCoder[1]; /* synch buffers for inactive frames, but not for transition frames */ +#ifdef ALIGN_SID_SIZE + if ( hCPE->last_element_brate <= IVAS_SID_5k2 ) +#else if ( hCPE->last_element_brate <= IVAS_SID_4k4 ) +#endif { mvr2r( output[0], output[1], output_frame ); mvr2r( synth[0], synth[1], output_frame ); } +#ifdef ALIGN_SID_SIZE + if ( hCPE->element_brate == IVAS_SID_5k2 && hCPE->last_element_brate > IVAS_SID_5k2 ) +#else if ( hCPE->element_brate == IVAS_SID_4k4 && hCPE->last_element_brate > IVAS_SID_4k4 ) +#endif { /* in the first SID frame after an active frame, create mid noise shape here, in SID frames that follow inactive frames, it is done directly in the SID decoding since the mid shape is being used in CNG then */ for ( int16_t p = 0; p < sts[0]->hFdCngDec->hFdCngCom->npart; p++ ) @@ -575,7 +583,11 @@ void updateBuffersForDmxMdctStereo( } /* for transition of active->inactive frame, apply passive downmix on buffers */ +#ifdef ALIGN_SID_SIZE + if ( hCPE->last_element_brate <= IVAS_SID_5k2 ) +#else if ( hCPE->last_element_brate <= IVAS_SID_4k4 ) +#endif { delta = 1; if ( output_frame == L_FRAME16k ) @@ -641,13 +653,21 @@ void applyDmxMdctStereo( fade = 1.f; dmx_len = output_frame; +#ifdef ALIGN_SID_SIZE + if ( hCPE->last_element_brate <= IVAS_SID_5k2 ) +#else if ( hCPE->last_element_brate <= IVAS_SID_4k4 ) +#endif { crossfade_len = NS2SA( hCPE->hCoreCoder[0]->output_Fs, IVAS_DEC_DELAY_NS - DELAY_CLDFB_NS ); step /= crossfade_len; } /* for first inactive CNG frame after active decoding we have to do a fade-OUT FROM the passive DMX */ +#ifdef ALIGN_SID_SIZE + else if ( hCPE->element_brate <= IVAS_SID_5k2 && hCPE->last_element_brate > IVAS_SID_5k2 ) +#else else if ( hCPE->element_brate <= IVAS_SID_4k4 && hCPE->last_element_brate > IVAS_SID_4k4 ) +#endif { crossfade_len = output_frame / 4; step /= -crossfade_len; diff --git a/lib_dec/ivas_stereo_switching_dec.c b/lib_dec/ivas_stereo_switching_dec.c index b2b7889569..2e32b8e85a 100755 --- a/lib_dec/ivas_stereo_switching_dec.c +++ b/lib_dec/ivas_stereo_switching_dec.c @@ -424,7 +424,7 @@ ivas_error stereo_memory_dec( if ( hCPE->last_element_mode == IVAS_CPE_MDCT ) { cpy_tcx_ltp_data( hCPE->hCoreCoder[1]->hTcxLtpDec, hCPE->hStereoDft->hTcxLtpDec, output_Fs ); -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE deleteFdCngDec( &hCPE->hCoreCoder[1]->hFdCngDec ); #endif } @@ -489,7 +489,7 @@ ivas_error stereo_memory_dec( /* deallocated TCX/IGF structures for second channel */ deallocate_CoreCoder_TCX( hCPE->hCoreCoder[1] ); -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE if ( hCPE->last_element_mode == IVAS_CPE_MDCT ) { deleteFdCngDec( &hCPE->hCoreCoder[1]->hFdCngDec ); @@ -675,7 +675,7 @@ ivas_error stereo_memory_dec( /* deallocate core-decoder substructures */ deallocate_CoreCoder( st ); -#ifndef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifndef MDCT_STEREO_PLC_FADE_2_BG_NOISE /* deallocate FD_CNG substructure */ deleteFdCngDec( &st->hFdCngDec ); #endif @@ -702,7 +702,7 @@ ivas_error stereo_memory_dec( } } -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE /* allocate Fd-Cng structure for second channel */ if ( ( error = createFdCngDec( &st->hFdCngDec ) ) != IVAS_ERR_OK ) { @@ -832,7 +832,11 @@ ivas_error stereo_memory_dec( if ( ivas_format == STEREO_FORMAT && hCPE->element_mode == IVAS_CPE_MDCT ) { +#ifdef ALIGN_SID_SIZE + if ( hCPE->element_brate <= MAX_MDCT_ITD_BRATE && ivas_total_brate > IVAS_SID_5k2 ) +#else if ( hCPE->element_brate <= MAX_MDCT_ITD_BRATE && ivas_total_brate > IVAS_SID_4k4 ) +#endif { if ( hCPE->hStereoMdct->use_itd == 0 ) { @@ -852,13 +856,21 @@ ivas_error stereo_memory_dec( else { /* de-allocate TCA data structure */ +#ifdef ALIGN_SID_SIZE + if ( hCPE->hStereoMdct->use_itd == 1 && ivas_total_brate > IVAS_SID_5k2 && hCPE->hStereoTCA != NULL ) +#else if ( hCPE->hStereoMdct->use_itd == 1 && ivas_total_brate > IVAS_SID_4k4 && hCPE->hStereoTCA != NULL ) +#endif { count_free( hCPE->hStereoTCA ); hCPE->hStereoTCA = NULL; hCPE->hStereoMdct->use_itd = 0; } +#ifdef ALIGN_SID_SIZE + else if ( hCPE->hStereoMdct->use_itd == 1 && ivas_total_brate <= IVAS_SID_5k2 ) +#else else if ( hCPE->hStereoMdct->use_itd == 1 && ivas_total_brate <= IVAS_SID_4k4 ) +#endif { hCPE->hStereoMdct->itd = 0.0f; } @@ -1011,7 +1023,11 @@ void synchro_synthesis( if ( use_cldfb_for_last_dft ) { +#ifdef ALIGN_SID_SIZE + if ( hCPE->element_mode == IVAS_CPE_DFT && hCPE->last_element_mode == IVAS_CPE_TD && ( ivas_total_brate > IVAS_SID_5k2 || hCPE->nchan_out == 2 ) ) +#else if ( hCPE->element_mode == IVAS_CPE_DFT && hCPE->last_element_mode == IVAS_CPE_TD && ( ivas_total_brate > IVAS_SID_4k4 || hCPE->nchan_out == 2 ) ) +#endif { stereo_tca_scale_R_channel( hCPE, output[0], output_frame ); } @@ -1349,7 +1365,11 @@ void stereo_switching_dec( mvr2r( hCPE->input_mem[n], hCPE->output_mem[n], dft32ms_ovl ); } +#ifdef ALIGN_SID_SIZE + if ( ivas_total_brate > IVAS_SID_5k2 || n == 0 || hCPE->last_element_mode != IVAS_CPE_TD || hCPE->nchan_out == 1 ) +#else if ( ivas_total_brate > IVAS_SID_4k4 || n == 0 || hCPE->last_element_mode != IVAS_CPE_TD || hCPE->nchan_out == 1 ) +#endif { for ( i = 0; i < dft32ms_ovl; i++ ) { @@ -1423,7 +1443,11 @@ void stereo_switching_dec( /* no secondary channel in the previous frame -> memory resets */ if ( hCPE->element_mode > IVAS_CPE_DFT && hCPE->last_element_mode == IVAS_CPE_DFT ) { +#ifdef ALIGN_SID_SIZE + if ( hCPE->last_element_brate <= IVAS_SID_5k2 && hCPE->nchan_out == 2 ) +#else if ( hCPE->last_element_brate <= IVAS_SID_4k4 && hCPE->nchan_out == 2 ) +#endif { /* reset CLDFB memories */ cldfb_reset_memory( sts[0]->cldfbAna ); diff --git a/lib_dec/ivas_tcx_core_dec.c b/lib_dec/ivas_tcx_core_dec.c index e3462f21bc..e46c32ddbb 100644 --- a/lib_dec/ivas_tcx_core_dec.c +++ b/lib_dec/ivas_tcx_core_dec.c @@ -150,7 +150,7 @@ void stereo_tcx_init_dec( } /* Reconfigure Core */ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE mode_switch_decoder_LPD( st, st->bwidth, st->bits_frame_nominal * FRAMES_PER_SEC, st->last_bits_frame_nominal * FRAMES_PER_SEC, frame_size_index, is_mct, last_element_mode ); #else mode_switch_decoder_LPD( st, st->bwidth, st->bits_frame_nominal * FRAMES_PER_SEC, st->last_bits_frame_nominal * FRAMES_PER_SEC, frame_size_index, is_mct ); @@ -457,7 +457,7 @@ void stereo_tcx_core_dec( } /* PLC: [TCX: TD PLC] */ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE con_tcx( st, &synthFB[0], -1.f, NULL, 0, NULL ); #else con_tcx( st, &synthFB[0], -1.f, NULL, 0 ); @@ -589,7 +589,7 @@ void stereo_tcx_core_dec( TonalMDCTConceal_SaveTimeSignal( st->hTonalMDCTConc, synthFB, hTcxDec->L_frameTCX ); } -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE decoder_tcx_post( st, synth, synthFB, Aq, bfi, 0 ); #else decoder_tcx_post( st, synth, synthFB, Aq, bfi ); @@ -750,7 +750,7 @@ void stereo_tcx_core_dec( if ( st->element_mode != IVAS_CPE_TD ) { -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE ApplyFdCng( signal_out, NULL, NULL, NULL, st, st->bfi, 0 ); #else ApplyFdCng( signal_out, NULL, NULL, st, st->bfi, 0 ); @@ -779,7 +779,7 @@ void stereo_tcx_core_dec( if ( st->element_mode == IVAS_CPE_TD && st->idchan == 0 ) { -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE ApplyFdCng( signal_out, NULL, NULL, NULL, st, st->bfi, 0 ); #else ApplyFdCng( signal_out, NULL, NULL, st, st->bfi, 0 ); @@ -867,7 +867,7 @@ static void dec_prm_tcx( *--------------------------------------------------------------------------------*/ /* Modes (ACE_GC, ACE_UC, TCX20, TCX10...) */ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE getTCXMode( st, st, 0 /* <- MCT_flag */ ); #else getTCXMode( st, st ); diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index c12a356146..fa2bb2b763 100755 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -110,12 +110,17 @@ ivas_error IVAS_DEC_Open( float no_diegetic_pan ) { IVAS_DEC_HANDLE hIvasDec; + Decoder_Struct *st_ivas; if ( phIvasDec == NULL ) { return IVAS_ERR_UNEXPECTED_NULL_POINTER; } + /*-----------------------------------------------------------------* + * Allocate and initialize IVAS application decoder handle + *-----------------------------------------------------------------*/ + if ( ( *phIvasDec = (IVAS_DEC_HANDLE) count_malloc( sizeof( struct IVAS_DEC ) ) ) == NULL ) { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for IVAS decoder handle" ); @@ -128,6 +133,16 @@ ivas_error IVAS_DEC_Open( hIvasDec->mode = mode; + hIvasDec->bitstreamformat = G192; + hIvasDec->Opt_VOIP = 0; + hIvasDec->amrwb_rfc4867_flag = -1; + hIvasDec->prev_ft_speech = 1; /* RXDTX handler previous frametype flag for G.192 format AMRWB SID_FIRST detection */ + hIvasDec->CNG = 0; /* RXDTX handler CNG = 1, no CNG = 0*/ + + /*-----------------------------------------------------------------* + * Initialize IVAS-codec decoder state + *-----------------------------------------------------------------*/ + if ( ( hIvasDec->st_ivas = (Decoder_Struct *) count_malloc( sizeof( Decoder_Struct ) ) ) == NULL ) { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for IVAS decoder structure" ); @@ -138,50 +153,49 @@ ivas_error IVAS_DEC_Open( return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for Decoder config structure" ); } + /*-----------------------------------------------------------------* + * Initialize IVAS-codec decoder state + *-----------------------------------------------------------------*/ + + st_ivas = hIvasDec->st_ivas; + + /* initialize Decoder Config. handle */ init_decoder_config( hIvasDec->st_ivas->hDecoderConfig, orientation_tracking, no_diegetic_pan ); - hIvasDec->bitstreamformat = G192; - hIvasDec->Opt_VOIP = 0; - hIvasDec->amrwb_rfc4867_flag = -1; - hIvasDec->prev_ft_speech = 1; /* RXDTX handeler previous frametype flag for G.192 format AMRWB SID_FIRST detection */ - hIvasDec->CNG = 0; /* RXDTX handler CNG = 1, no CNG = 0*/ + /* initialize pointers to handles to NULL */ + ivas_initialize_handles_dec( st_ivas ); + /* set high-level parameters */ if ( mode == IVAS_DEC_MODE_EVS ) { - /* EVS - do alloc etc. */ - hIvasDec->st_ivas->codec_mode = 0; /* unknown before first frame */ - hIvasDec->st_ivas->element_mode_init = EVS_MONO; - hIvasDec->st_ivas->ivas_format = MONO_FORMAT; - hIvasDec->st_ivas->transport_config = AUDIO_CONFIG_INVALID; - hIvasDec->st_ivas->intern_config = AUDIO_CONFIG_INVALID; - hIvasDec->st_ivas->writeFECoffset = 0; + st_ivas->codec_mode = 0; /* unknown before first frame */ + st_ivas->element_mode_init = EVS_MONO; + st_ivas->ivas_format = MONO_FORMAT; + st_ivas->transport_config = AUDIO_CONFIG_INVALID; + st_ivas->intern_config = AUDIO_CONFIG_INVALID; + st_ivas->writeFECoffset = 0; return IVAS_ERR_OK; } else if ( mode == IVAS_DEC_MODE_IVAS ) { - hIvasDec->st_ivas->codec_mode = 0; /* unknown before first frame */ - hIvasDec->st_ivas->element_mode_init = -1; - hIvasDec->st_ivas->ivas_format = UNDEFINED_FORMAT; - hIvasDec->st_ivas->transport_config = AUDIO_CONFIG_INVALID; - hIvasDec->st_ivas->intern_config = AUDIO_CONFIG_INVALID; - hIvasDec->st_ivas->renderer_type = RENDERER_DISABLE; - hIvasDec->st_ivas->ini_frame = 0; - hIvasDec->st_ivas->ini_active_frame = 0; - hIvasDec->st_ivas->writeFECoffset = 0; -#ifndef SBA_ORDER_BITSTREAM - hIvasDec->st_ivas->sba_order = 0; -#else - hIvasDec->st_ivas->sba_analysis_order = 0; -#endif - hIvasDec->st_ivas->sba_planar = 0; + st_ivas->codec_mode = 0; /* unknown before first frame */ + st_ivas->element_mode_init = -1; + st_ivas->ivas_format = UNDEFINED_FORMAT; + st_ivas->transport_config = AUDIO_CONFIG_INVALID; + st_ivas->intern_config = AUDIO_CONFIG_INVALID; + st_ivas->renderer_type = RENDERER_DISABLE; + st_ivas->ini_frame = 0; + st_ivas->ini_active_frame = 0; + st_ivas->writeFECoffset = 0; - /*initialize pointers*/ - ivas_initialize_handles_dec( hIvasDec->st_ivas ); + st_ivas->ism_mode = ISM_MODE_NONE; + st_ivas->sba_mode = SBA_MODE_NONE; + st_ivas->mc_mode = MC_MODE_NONE; - hIvasDec->st_ivas->ism_mode = ISM_MODE_NONE; - hIvasDec->st_ivas->sba_mode = SBA_MODE_NONE; - hIvasDec->st_ivas->mc_mode = MC_MODE_NONE; + st_ivas->sba_order = 0; + st_ivas->sba_planar = 0; + st_ivas->sba_analysis_order = 0; return IVAS_ERR_OK; } @@ -236,38 +250,14 @@ void IVAS_DEC_Close( if ( ( *phIvasDec )->hVoIP ) { IVAS_DEC_Close_VoIP( ( *phIvasDec )->hVoIP ); - count_free( ( *phIvasDec )->hVoIP ); + ( *phIvasDec )->hVoIP = NULL; } - if ( ( *phIvasDec )->isInitialized ) + if ( ( *phIvasDec )->st_ivas ) { - if ( ( *phIvasDec )->st_ivas ) - { - ivas_destroy_dec( ( *phIvasDec )->st_ivas ); - } + ivas_destroy_dec( ( *phIvasDec )->st_ivas ); + ( *phIvasDec )->st_ivas = NULL; } - else - { - if ( ( *phIvasDec )->st_ivas->hDecoderConfig != NULL ) - { - count_free( ( *phIvasDec )->st_ivas->hDecoderConfig ); - ( *phIvasDec )->st_ivas->hDecoderConfig = NULL; - } - - if ( ( *phIvasDec )->st_ivas->hHeadTrackData != NULL ) - { - count_free( ( *phIvasDec )->st_ivas->hHeadTrackData ); - ( *phIvasDec )->st_ivas->hHeadTrackData = NULL; - } - - ivas_render_config_close( &( ( *phIvasDec )->st_ivas->hRenderConfig ) ); - - ivas_HRTF_binary_close( &( *phIvasDec )->st_ivas->hHrtfTD ); - - count_free( ( *phIvasDec )->st_ivas ); - } - - ( *phIvasDec )->st_ivas = NULL; count_free( *phIvasDec ); *phIvasDec = NULL; @@ -1141,7 +1131,11 @@ static bool isSidFrame( { return true; /* EVS SID */ } +#ifdef ALIGN_SID_SIZE + else if ( size == IVAS_SID_5k2 / FRAMES_PER_SEC ) +#else else if ( size == IVAS_SID_4k4 / FRAMES_PER_SEC ) +#endif { return true; /* IVAS SID */ } @@ -1474,6 +1468,8 @@ static void IVAS_DEC_Close_VoIP( pcmdsp_fifo_destroy( &hVoIP->hFifoAfterTimeScaler ); + count_free( hVoIP ); + return; } diff --git a/lib_dec/stat_dec.h b/lib_dec/stat_dec.h index 8fc8ec5282..0c7a836cb4 100644 --- a/lib_dec/stat_dec.h +++ b/lib_dec/stat_dec.h @@ -204,15 +204,16 @@ typedef struct Float32 *secondLastPcmOut; float *secondLastPowerSpectrum; -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE float scaleFactorsBackground[FDNS_NPTS]; + float scf_fadeout; PsychoacousticParameters *psychParams; - /* could be stored only once, since the same for all channels (always at 16Khz fs) */ PsychoacousticParameters psychParamsTCX20; PsychoacousticParameters psychParamsTCX10; float last_block_nrg; float curr_noise_nrg; + float faded_signal_nrg; #endif float nFramesLost; diff --git a/lib_dec/swb_tbe_dec.c b/lib_dec/swb_tbe_dec.c index 03d9162e34..2664aaa08d 100755 --- a/lib_dec/swb_tbe_dec.c +++ b/lib_dec/swb_tbe_dec.c @@ -1973,12 +1973,11 @@ static void dequantizeSHBparams( *-------------------------------------------------------------------*/ void fb_tbe_dec( - Decoder_State *st, /* i/o: decoder state structure */ - const float fb_exc[], /* i : FB excitation from the SWB part */ - float *hb_synth, /* o : high-band synthesis */ - float *fb_synth_ref /* o : high-band synthesis 16-20 kHz */ - , - const int16_t output_frame /* i: output frame length */ + Decoder_State *st, /* i/o: decoder state structure */ + const float fb_exc[], /* i : FB excitation from the SWB part */ + float *hb_synth, /* o : high-band synthesis */ + float *fb_synth_ref, /* o : high-band synthesis 16-20 kHz */ + const int16_t output_frame /* i : output frame length */ ) { int16_t i; diff --git a/lib_dec/tonalMDCTconcealment.c b/lib_dec/tonalMDCTconcealment.c index b43f85b8f9..776d28bcb5 100644 --- a/lib_dec/tonalMDCTconcealment.c +++ b/lib_dec/tonalMDCTconcealment.c @@ -93,14 +93,16 @@ ivas_error TonalMDCTConceal_Init( hTonalMDCTConc->nSamplesCore = nSamplesCore; hTonalMDCTConc->nScaleFactors = nScaleFactors; -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE set_zero( hTonalMDCTConc->scaleFactorsBackground, FDNS_NPTS ); + hTonalMDCTConc->scf_fadeout = 1.0f; PsychoacousticParameters_Init( INT_FS_16k, L_FRAME16k, 64, 1, 1, &hTonalMDCTConc->psychParamsTCX20 ); PsychoacousticParameters_Init( INT_FS_16k, L_FRAME16k / 2, 64, 0, 1, &hTonalMDCTConc->psychParamsTCX10 ); hTonalMDCTConc->psychParams = NULL; hTonalMDCTConc->last_block_nrg = 0.0f; hTonalMDCTConc->curr_noise_nrg = 0.0f; + hTonalMDCTConc->faded_signal_nrg = 0.0f; #endif /* Offset the pointer to the end of buffer, so that pTCI is not destroyed when @@ -123,7 +125,7 @@ void TonalMDCTConceal_SaveFreqSignal( const uint16_t nNewSamples, const uint16_t nNewSamplesCore, const float *scaleFactors -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE , const int16_t infoIGFStartLine #endif @@ -168,7 +170,7 @@ void TonalMDCTConceal_SaveFreqSignal( if ( ( nNewSamples > 0 ) && ( nNewSamples <= 2 * L_FRAME_MAX ) ) { /* Store new data */ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE int16_t i; hTonalMDCTConc->last_block_nrg = 0.0f; @@ -500,8 +502,9 @@ void TonalMDCTConceal_InsertNoise( int16_t *pSeed, const float tiltCompFactor, const float crossfadeGain, -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE const float concealment_noise[L_FRAME48k], + const float cngLevelBackgroundTrace_bfi, #endif const int16_t crossOverFreq ) { @@ -509,11 +512,18 @@ void TonalMDCTConceal_InsertNoise( float x, y; Word16 rnd; float g, nrgNoiseInLastFrame, nrgWhiteNoise, tiltFactor, tilt; +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE + float last_block_nrg_correct; +#endif wmops_sub_start( "InsertNoise" ); g = 1.0f - crossfadeGain; +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE + if ( !hTonalMDCTConc->lastBlockData.blockIsConcealed ) +#else if ( !hTonalMDCTConc->lastBlockData.blockIsConcealed ) +#endif { rnd = 1977; } @@ -522,13 +532,15 @@ void TonalMDCTConceal_InsertNoise( rnd = *pSeed; } -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE /* based on what is done in tcx_noise_filling() */ /* always initialize these to avoid compiler warnings */ tiltFactor = (float) pow( max( 0.375f, tiltCompFactor ), 1.0f / hTonalMDCTConc->lastBlockData.nSamples ); tilt = 1.0f; nrgNoiseInLastFrame = 0.0f; nrgWhiteNoise = 0.0f; + hTonalMDCTConc->faded_signal_nrg = 0.0f; + last_block_nrg_correct = 0.0f; #endif if ( !hTonalMDCTConc->lastBlockData.blockIsValid ) @@ -536,7 +548,7 @@ void TonalMDCTConceal_InsertNoise( /* may just become active if the very first frame is lost */ set_f( mdctSpectrum, 0.0f, hTonalMDCTConc->nSamples ); } -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE else if ( concealment_noise != NULL ) { if ( !tonalConcealmentActive ) @@ -564,7 +576,7 @@ void TonalMDCTConceal_InsertNoise( /* actual fadeout is done in this case */ else { - g *= (float) sqrt( hTonalMDCTConc->last_block_nrg / hTonalMDCTConc->curr_noise_nrg ); + g *= (float) sqrt( cngLevelBackgroundTrace_bfi / hTonalMDCTConc->curr_noise_nrg ); for ( i = 0; i < crossOverFreq; i++ ) { @@ -579,6 +591,8 @@ void TonalMDCTConceal_InsertNoise( { mdctSpectrum[i] = g * y - crossfadeGain * x; } + + hTonalMDCTConc->faded_signal_nrg += mdctSpectrum[i] * mdctSpectrum[i]; } for ( l = crossOverFreq; l < hTonalMDCTConc->lastBlockData.nSamples; l++ ) { @@ -599,6 +613,11 @@ void TonalMDCTConceal_InsertNoise( for ( l = hTonalMDCTConc->pTCI->lowerIndex[i]; l <= hTonalMDCTConc->pTCI->upperIndex[i]; l++ ) { mdctSpectrum[l] = 0; + if ( l < crossOverFreq ) + { + last_block_nrg_correct += hTonalMDCTConc->lastBlockData.spectralData[l] * hTonalMDCTConc->lastBlockData.spectralData[l]; + hTonalMDCTConc->curr_noise_nrg -= concealment_noise[l] * concealment_noise[l]; + } } } @@ -651,7 +670,7 @@ void TonalMDCTConceal_InsertNoise( /* actual fadeout is done in this case */ else { - g *= (float) sqrt( hTonalMDCTConc->last_block_nrg / hTonalMDCTConc->curr_noise_nrg ); + g *= (float) sqrt( cngLevelBackgroundTrace_bfi / hTonalMDCTConc->curr_noise_nrg ); for ( l = 0; l < hTonalMDCTConc->pTCI->lowerIndex[0]; l++ ) { @@ -666,6 +685,7 @@ void TonalMDCTConceal_InsertNoise( { mdctSpectrum[l] = g * y - crossfadeGain * x; } + hTonalMDCTConc->faded_signal_nrg += mdctSpectrum[l] * mdctSpectrum[l]; } for ( i = 1; i < hTonalMDCTConc->pTCI->numIndexes; i++ ) { @@ -682,6 +702,7 @@ void TonalMDCTConceal_InsertNoise( { mdctSpectrum[l] = g * y - crossfadeGain * x; } + hTonalMDCTConc->faded_signal_nrg += mdctSpectrum[l] * mdctSpectrum[l]; } } @@ -698,6 +719,7 @@ void TonalMDCTConceal_InsertNoise( { mdctSpectrum[l] = g * y - crossfadeGain * x; } + hTonalMDCTConc->faded_signal_nrg += mdctSpectrum[l] * mdctSpectrum[l]; } for ( l = crossOverFreq; l < hTonalMDCTConc->lastBlockData.nSamples; l++ ) @@ -706,11 +728,19 @@ void TonalMDCTConceal_InsertNoise( } } } + + if ( hTonalMDCTConc->faded_signal_nrg > 0.0f && hTonalMDCTConc->curr_noise_nrg > MDCT_ST_PLC_FADEOUT_MIN_NOISE_NRG ) + { + float nrg_corr_factor; + + nrg_corr_factor = sqrtf( ( hTonalMDCTConc->last_block_nrg - last_block_nrg_correct ) / hTonalMDCTConc->faded_signal_nrg ); + v_multc( mdctSpectrum, nrg_corr_factor, mdctSpectrum, crossOverFreq ); + } } #endif else { -#ifndef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifndef MDCT_STEREO_PLC_FADE_2_BG_NOISE /* based on what is done in tcx_noise_filling() */ tiltFactor = (float) pow( max( 0.375f, tiltCompFactor ), 1.0f / hTonalMDCTConc->lastBlockData.nSamples ); tilt = 1.0f; @@ -962,7 +992,7 @@ void TonalMDCTConceal_SaveTimeSignal( return; } -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE void TonalMdctConceal_create_concealment_noise( float concealment_noise[L_FRAME48k], CPE_DEC_HANDLE hCPE, @@ -971,7 +1001,7 @@ void TonalMdctConceal_create_concealment_noise( const int16_t idchan, const int16_t subframe_idx, const int16_t core, - const int16_t crossfade_gain, + const float crossfade_gain, const TONALMDCTCONC_NOISE_GEN_MODE noise_gen_mode ) { STEREO_MDCT_DEC_DATA_HANDLE hStereoMdct; @@ -1049,7 +1079,6 @@ void TonalMdctConceal_create_concealment_noise( c_inv = sqrtf( 1 - hStereoMdct->lastCoh ); /* pre-compute the noise shape for later weighting of the noise spectra */ - /* TODO: optimize by intertwining with later loop */ cngNoiseLevelPtr = &hFdCngCom->cngNoiseLevel[0]; inc = ( st->core > TCX_20_CORE ) ? 2 : 1; start_idx = hFdCngCom->startBand / inc; @@ -1072,7 +1101,7 @@ void TonalMdctConceal_create_concealment_noise( } /* fill the noise vector */ - hTonalMDCTConc->curr_noise_nrg = 0.001f; + hTonalMDCTConc->curr_noise_nrg = MDCT_ST_PLC_FADEOUT_MIN_NOISE_NRG; if ( noise_gen_mode == EQUAL_CORES || ( ( noise_gen_mode == TCX20_IN_0_TCX10_IN_1 && idchan == 0 ) || ( noise_gen_mode == TCX10_IN_0_TCX20_IN_1 && idchan == 1 ) ) ) { /* current channel is TCX20 -> generate noise for "full-length" spectrum */ @@ -1100,6 +1129,14 @@ void TonalMdctConceal_create_concealment_noise( } } + if ( st->tonal_mdct_plc_active ) + { + for ( i = crossOverFreq; i < max( crossOverFreq, hTonalMDCTConc->pTCI->lowerIndex[hTonalMDCTConc->pTCI->numIndexes - 1] ); ++i ) + { + concealment_noise[i] *= 0.0f; + } + } + /* restore common seed - after finishing the first channel - after a first subframe if the current channel is TCX10 */ @@ -1108,8 +1145,68 @@ void TonalMdctConceal_create_concealment_noise( *rnd_c = save_rnd_c; } + st->seed_tcx_plc = *rnd; + wmops_sub_end(); return; } + +void TonalMdctConceal_whiten_noise_shape( + Decoder_State *st, + const int16_t L_frame, + const TONALMDCTCONC_NOISE_SHAPE_WHITENING_MODE whitening_mode +) +{ + int16_t inc, start_idx, stop_idx; + float *noiseLevelPtr, *scfs_bg, *scfs_for_shaping; + HANDLE_FD_CNG_COM hFdCngCom; + float whitenend_noise_shape[L_FRAME16k]; + float scfs_int[FDNS_NPTS]; + const PsychoacousticParameters *psychParams; + + wmops_sub_start( "apply_sns_on_noise_shape" ); + + scfs_bg = &st->hTonalMDCTConc->scaleFactorsBackground[0]; + psychParams = st->hTonalMDCTConc->psychParams; + hFdCngCom = st->hFdCngDec->hFdCngCom; + + inc = ( ( whitening_mode == ON_FIRST_LOST_FRAME ? st->core : st->last_core ) > TCX_20_CORE ) ? 2 : 1; + start_idx = hFdCngCom->startBand / inc; + stop_idx = L_frame / inc; + noiseLevelPtr = hFdCngCom->cngNoiseLevel; + + set_zero( whitenend_noise_shape, start_idx ); + for ( int16_t j = start_idx; j < stop_idx; j++, noiseLevelPtr += inc ) + { + whitenend_noise_shape[j] = *noiseLevelPtr; + } + + if ( whitening_mode == ON_FIRST_LOST_FRAME ) + { + float scf[SNS_NPTS]; + + sns_compute_scf( whitenend_noise_shape, psychParams, L_frame, scf ); + sns_interpolate_scalefactors( scfs_int, scf, ENC ); + sns_interpolate_scalefactors( scfs_bg, scf, DEC ); + scfs_for_shaping = &scfs_int[0]; + } + else /* whitening_mode == ON_FIRST_GOOD_FRAME */ + { + scfs_for_shaping = &scfs_bg[0]; + } + + if ( sum_f( scfs_for_shaping, FDNS_NPTS ) > 0.0f ) + { + sns_shape_spectrum( whitenend_noise_shape, psychParams, scfs_for_shaping, L_frame ); + mvr2r( whitenend_noise_shape + start_idx, hFdCngCom->cngNoiseLevel, stop_idx - start_idx ); + } + else + { + set_zero( hFdCngCom->cngNoiseLevel, stop_idx - start_idx ); + } + + wmops_sub_end(); +} + #endif diff --git a/lib_enc/bw_detect.c b/lib_enc/bw_detect.c index c1357a7f74..c2955f1f39 100644 --- a/lib_enc/bw_detect.c +++ b/lib_enc/bw_detect.c @@ -494,7 +494,6 @@ void bw_detect( st->input_bwidth = st->max_bwidth; } - if ( st->element_mode == EVS_MONO ) { set_bw( -1, -1, st, st->codec_mode ); diff --git a/lib_enc/enc_prm.c b/lib_enc/enc_prm.c index 062069ceee..33c9d6fc7b 100644 --- a/lib_enc/enc_prm.c +++ b/lib_enc/enc_prm.c @@ -55,7 +55,7 @@ void writeTCXMode( Encoder_State *st, /* i/o: encoder state structure */ BSTR_ENC_HANDLE hBstr, /* i/o: bitstream handle */ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE const int16_t is_mct, #endif int16_t *nbits_start /* o : nbits start */ @@ -88,7 +88,7 @@ void writeTCXMode( push_next_indice( hBstr, index, 2 ); -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE if ( st->element_mode == IVAS_CPE_MDCT && !is_mct ) { push_next_indice( hBstr, st->vad_flag, 1 ); @@ -792,7 +792,7 @@ void enc_prm( /* EVS header */ /* Modes (ACE_GC, ACE_UC, TCX20, TCX10...) */ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE writeTCXMode( st, st->hBstr, 0, /* <- is_mct */ &nbits_start ); #else writeTCXMode( st, st->hBstr, &nbits_start ); diff --git a/lib_enc/fd_cng_enc.c b/lib_enc/fd_cng_enc.c index c2dfb1969f..2f98addc8d 100644 --- a/lib_enc/fd_cng_enc.c +++ b/lib_enc/fd_cng_enc.c @@ -902,6 +902,12 @@ void stereoFdCngCoherence( sts[0]->core_brate = SID_2k40; sts[1]->core_brate = SID_2k40; } + +#ifdef FIX_CONTROLLABLE_SID_UPDATE_RATE + /* synchronize SID counters */ + sts[0]->hDtxEnc->cnt_SID = min( sts[0]->hDtxEnc->cnt_SID, sts[1]->hDtxEnc->cnt_SID ); + sts[1]->hDtxEnc->cnt_SID = sts[0]->hDtxEnc->cnt_SID; +#endif } pt_fftL = fft_buff[0]; @@ -1002,11 +1008,7 @@ void FdCngEncodeMDCTStereoSID( convertToMS( N, ms_ptr[0], ms_ptr[1], 0.5f ); } - side_energy = 0.0f; - for ( p = 0; p < N; p++ ) - { - side_energy += ms_ptr[1][p] * ms_ptr[1][p]; - } + side_energy = sum2_f( ms_ptr[1], N ); /* do not transmit side shape if initial noise shapes are very similar */ if ( side_energy <= 0.1f ) @@ -1128,6 +1130,11 @@ void FdCngEncodeMDCTStereoSID( push_indice( sts[ch]->hBstr, IND_ENERGY, gain_idx[ch], 7 ); } +#ifdef ALIGN_SID_SIZE + /* pad with zeros to reach common SID frame size */ + push_indice( sts[1]->hBstr, IND_ENERGY, 0, ( IVAS_SID_5k2 - 4400 ) / FRAMES_PER_SEC ); +#endif + return; } @@ -1181,18 +1188,11 @@ void FdCngEncodeDiracMDCTStereoSID( /* M/S transform on log envelopes */ convertToMS( NPART, ms_ptr[0], ms_ptr[1], 0.5f ); - E[0] = 0.0f; - for ( p = 0; p < NPART; p++ ) - { - E[0] += ms_ptr[0][p]; - } + E[0] = sum_f( ms_ptr[0], NPART ); + /* Quantize M noise shape */ /* Normalize MSVW input */ - gain[0] = 0.f; - for ( p = N_GAIN_MIN; p < N_GAIN_MAX; p++ ) - { - gain[0] += ms_ptr[0][p]; - } + gain[0] = sum_f( ms_ptr[0] + N_GAIN_MIN, N_GAIN_MAX - N_GAIN_MIN ); gain[0] /= (float) ( N_GAIN_MAX - N_GAIN_MIN ); for ( p = 0; p < N[0]; p++ ) @@ -1208,11 +1208,7 @@ void FdCngEncodeDiracMDCTStereoSID( set_zero( ms_ptr[1], NPART ); /* compute M gain */ - gain[0] = 0.f; - for ( p = 0; p < NPART; p++ ) - { - gain[0] += ms_ptr[0][p]; - } + gain[0] = sum_f( ms_ptr[0], NPART ); gain[0] = ( E[0] - gain[0] ) / (float) N[0]; apply_scale( &gain[0], sts[0]->hFdCngEnc->hFdCngCom->CngBandwidth, sts[0]->hDtxEnc->last_active_brate, scaleTableStereo, SIZE_SCALE_TABLE_STEREO ); diff --git a/lib_enc/igf_enc.c b/lib_enc/igf_enc.c index 2cf98207bb..7b658908b5 100644 --- a/lib_enc/igf_enc.c +++ b/lib_enc/igf_enc.c @@ -1852,13 +1852,17 @@ void IGFEncApplyStereo( const IGF_ENC_INSTANCE_HANDLE hIGFEnc[CPE_CHANNELS], /* i : instance handle of IGF Encoder */ const int16_t igfGridIdx, /* i : IGF grid index */ Encoder_State *sts[CPE_CHANNELS], /* i : Encoder state */ +#ifdef DRAM_REDUCTION_MCT_IGF + float *pPowerSpectrum[CPE_CHANNELS], /* i/o: MDCT^2 + MDST^2 spectrum, or estimate */ +#else float pPowerSpectrum[CPE_CHANNELS][N_MAX], /* i/o: MDCT^2 + MDST^2 spectrum, or estimate */ +#endif float *pPowerSpectrumMsInv[CPE_CHANNELS][2], /* i/o: inverse power spectrum */ float *inv_spectrum[CPE_CHANNELS][2], /* i : inverse spectrum */ const int16_t frameno, /* i : flag indicating index of current subfr. */ const int16_t sp_aud_decision0, /* i : sp_aud_decision0 */ const int32_t element_brate, /* i : element bitrate */ - const int16_t mct_on /* i : flag mct block (1) or stereo (0) */ + const int16_t mct_on /* i : flag mct block (1) or stereo (0) */ ) { float *pPowerSpectrumParameter[2]; /* If it is NULL it informs a function that specific handling is needed */ diff --git a/lib_enc/ivas_agc_enc.c b/lib_enc/ivas_agc_enc.c index 493d1ac071..3ed7bb6d2f 100644 --- a/lib_enc/ivas_agc_enc.c +++ b/lib_enc/ivas_agc_enc.c @@ -242,7 +242,7 @@ void ivas_agc_enc_process( if ( !isClipped ) { - if ( ( ppPcm_out[i][j] > ( 1.f - pState->minDelta ) ) || ( ppPcm_out[i][j] < -1.f ) ) + if ( ( ppPcm_out[i][j] > ( 1.f - pState->minDelta ) * PCM16_TO_FLT_FAC ) || ( ppPcm_out[i][j] < MIN16B_FLT ) ) { if ( j < offset ) { @@ -278,7 +278,7 @@ void ivas_agc_enc_process( maxGain = max( smoothedMaxAbsVal, MaxAbsVal ) * pState->gain_state[i].lastGain * 2.f; - if ( maxGain < 1.f - pState->minDelta ) + if ( maxGain < ( 1.f - pState->minDelta ) * PCM16_TO_FLT_FAC ) { pState->gain_state[i].gainExpVal = -1; } @@ -313,7 +313,7 @@ void ivas_agc_enc_process( { int16_t isCompensated = FALSE; pState->gain_data[i].gainException = FALSE; - pState->gain_state[i].gainExpVal = (int16_t) ceilf( -logf( actualMaxAbsVal ) / logf( pState->agc_com.winFunc[MaxAbsValIdx] ) ); + pState->gain_state[i].gainExpVal = (int16_t) ceilf( -logf( actualMaxAbsVal * MDFT_NORM_SCALING ) / logf( pState->agc_com.winFunc[MaxAbsValIdx] ) ); while ( !isCompensated ) { @@ -324,7 +324,7 @@ void ivas_agc_enc_process( { tmpSignal = ppPcm_out[i][idx] * powf( pState->agc_com.winFunc[idx], (float) pState->gain_state[i].gainExpVal ); - if ( ( tmpSignal > ( 1.f - pState->minDelta ) ) || ( tmpSignal < -1.f ) ) + if ( ( tmpSignal > ( 1.f - pState->minDelta ) * PCM16_TO_FLT_FAC ) || ( tmpSignal < MIN16B_FLT ) ) { isCompensated = FALSE; break; @@ -374,7 +374,7 @@ void ivas_agc_enc_process( } else { - pState->gain_state[i].gainExpVal = (int16_t) ( -floorf( -logf( actualMaxAbsVal + pState->minDelta ) * INV_LOG_2 ) ); + pState->gain_state[i].gainExpVal = (int16_t) ( -floorf( -logf( ( actualMaxAbsVal + pState->minDelta ) * MDFT_NORM_SCALING ) * INV_LOG_2 ) ); pState->gain_state[i].gainExpVal = min( gainExpValMaxRange, pState->gain_state[i].gainExpVal ); gain = powf( 2.0f, -1.0f * pState->gain_state[i].gainExpVal ); diff --git a/lib_enc/ivas_cpe_enc.c b/lib_enc/ivas_cpe_enc.c index b543761491..08c45af220 100644 --- a/lib_enc/ivas_cpe_enc.c +++ b/lib_enc/ivas_cpe_enc.c @@ -115,7 +115,6 @@ ivas_error ivas_cpe_enc( input_Fs = hEncoderConfig->input_Fs; ivas_total_brate = hEncoderConfig->ivas_total_brate; - /*------------------------------------------------------------------* * Initialization - general *-----------------------------------------------------------------*/ @@ -344,12 +343,6 @@ ivas_error ivas_cpe_enc( 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() */ - if ( ( sts[0]->last_bwidth < max_bwidth ) || ( sts[0]->last_core_brate <= SID_2k40 ) ) /* IVAS_fmToDo: TBV - BWD output is not known here yet !!! */ - { - /* reconfigure in case of BW switching or if last frame was a SID/NO_DATA with coarse partitioning */ - hCPE->hStereoDft->nbands = stereo_dft_band_config( hCPE->hStereoDft->band_limits, hCPE->hStereoDft->hConfig->band_res, hCPE->hStereoDft->NFFT, ENC ); - } - /* Update DFT Stereo memories */ stereo_dft_enc_update( hCPE->hStereoDft, sts[0]->max_bwidth #ifdef DEBUG_MODE_DFT @@ -460,7 +453,11 @@ ivas_error ivas_cpe_enc( { if ( hCPE->element_mode == IVAS_CPE_DFT || hCPE->element_mode == IVAS_CPE_TD ) { +#ifdef ALIGN_SID_SIZE + reset_metadata_spatial( ivas_format, hCPE->hMetaData, hCPE->element_brate, &tmp, sts[0]->core_brate, nb_bits_metadata, st_ivas->sba_mode ); +#else reset_metadata_spatial( ivas_format, hCPE->hMetaData, hCPE->element_brate, &tmp, sts[0]->core_brate, nb_bits_metadata, st_ivas->sba_mode, hCPE->element_mode ); +#endif } } @@ -472,7 +469,11 @@ ivas_error ivas_cpe_enc( /* Reset metadata */ if ( sts[0]->cng_sba_flag || ( ivas_format == SBA_FORMAT && st_ivas->sba_mode == SBA_MODE_SPAR ) ) { +#ifdef ALIGN_SID_SIZE + reset_metadata_spatial( ivas_format, hCPE->hMetaData, hCPE->element_brate, &tmp, sts[0]->core_brate, nb_bits_metadata, st_ivas->sba_mode ); +#else reset_metadata_spatial( ivas_format, hCPE->hMetaData, hCPE->element_brate, &tmp, sts[0]->core_brate, nb_bits_metadata, st_ivas->sba_mode, hCPE->element_mode ); +#endif } } @@ -541,7 +542,11 @@ ivas_error ivas_cpe_enc( * Write IVAS format signaling in SID frames *----------------------------------------------------------------*/ +#ifdef ALIGN_SID_SIZE + if ( sts[0]->core_brate == SID_2k40 ) +#else if ( sts[0]->core_brate == SID_2k40 && ( ivas_format != SBA_FORMAT || st_ivas->sba_mode != SBA_MODE_SPAR ) ) +#endif { ivas_write_format_sid( ivas_format, hCPE->element_mode, sts[0]->hBstr ); } @@ -560,7 +565,11 @@ ivas_error ivas_cpe_enc( /* Reconfigure DFT Stereo for inactive frames */ if ( sts[0]->core_brate == SID_2k40 ) { +#ifdef ALIGN_SID_SIZE + stereo_dft_config( hCPE->hStereoDft->hConfig, IVAS_SID_5k2, &sts[0]->bits_frame_nominal, &sts[1]->bits_frame_nominal ); +#else stereo_dft_config( hCPE->hStereoDft->hConfig, IVAS_SID_4k4, &sts[0]->bits_frame_nominal, &sts[1]->bits_frame_nominal ); +#endif } else { @@ -604,7 +613,11 @@ ivas_error ivas_cpe_enc( if ( sts[0]->core_brate == FRAME_NO_DATA || sts[0]->core_brate == SID_2k40 ) { +#ifdef ALIGN_SID_SIZE + assert( ( nb_bits <= ( ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS ) ) && "Stereo DFT CNG: bit budget is violated" ); +#else assert( ( nb_bits <= ( ( IVAS_SID_4k4 - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS ) ) && "Stereo DFT CNG: bit budget is violated" ); +#endif } else { diff --git a/lib_enc/ivas_dirac_enc.c b/lib_enc/ivas_dirac_enc.c index 557cb109ca..9d5893622d 100644 --- a/lib_enc/ivas_dirac_enc.c +++ b/lib_enc/ivas_dirac_enc.c @@ -122,19 +122,29 @@ ivas_error ivas_dirac_enc_open( if ( st_ivas->sba_mode == SBA_MODE_DIRAC ) { hDirAC->num_samples_synchro_delay = NS2SA( input_Fs, IVAS_FB_ENC_DELAY_NS ); +#ifdef FIX_DIRAC_CHANNELS + for ( i = 0; i < DIRAC_MAX_ANA_CHANS; i++ ) +#else for ( i = 0; i < st_ivas->hEncoderConfig->nchan_inp; i++ ) +#endif { hDirAC->sba_synchro_buffer[i] = (float *) count_malloc( hDirAC->num_samples_synchro_delay * sizeof( float ) ); set_zero( hDirAC->sba_synchro_buffer[i], hDirAC->num_samples_synchro_delay ); } +#ifndef FIX_DIRAC_CHANNELS for ( ; i < IVAS_MAX_NUM_CH; i++ ) { hDirAC->sba_synchro_buffer[i] = NULL; } +#endif } else { +#ifdef FIX_DIRAC_CHANNELS + for ( i = 0; i < DIRAC_MAX_ANA_CHANS; i++ ) +#else for ( i = 0; i < IVAS_MAX_NUM_CH; i++ ) +#endif { hDirAC->sba_synchro_buffer[i] = NULL; } @@ -242,7 +252,11 @@ void ivas_dirac_enc_close( ivas_FB_mixer_close( &hDirAC->hFbMixer, input_Fs ); } +#ifdef FIX_DIRAC_CHANNELS + for ( i = 0; i < DIRAC_MAX_ANA_CHANS; i++ ) +#else for ( i = 0; i < IVAS_MAX_NUM_CH; i++ ) +#endif { if ( hDirAC->sba_synchro_buffer[i] != NULL ) { @@ -412,9 +426,7 @@ void ivas_dirac_enc( } /* encode SID parameters */ - ivas_qmetadata_enc_sid_encode( hMetaData, hQMetaData, -1, - SBA_FORMAT, - SBA_MODE_DIRAC ); + ivas_qmetadata_enc_sid_encode( hMetaData, hQMetaData, -1, SBA_FORMAT, SBA_MODE_DIRAC ); /* restore original metadata */ hDirAC->hConfig->nbands = nbands; @@ -429,10 +441,12 @@ void ivas_dirac_enc( } else { +#ifdef ALIGN_SID_SIZE + /*indicate whether SPAR or DiRAC mode*/ + push_next_indice( hMetaData, 0, 1 ); +#endif /* encode SID parameters */ - ivas_qmetadata_enc_sid_encode( hMetaData, hQMetaData, -1, - SBA_FORMAT, - SBA_MODE_DIRAC ); + ivas_qmetadata_enc_sid_encode( hMetaData, hQMetaData, -1, SBA_FORMAT, SBA_MODE_DIRAC ); } } } @@ -442,6 +456,7 @@ void ivas_dirac_enc( return; } + /*------------------------------------------------------------------------- * computeReferencePower_enc() * @@ -457,7 +472,11 @@ void ivas_dirac_enc_spar_delay_synchro( int16_t ch_idx; float tmp_buffer[L_FRAME48k]; +#ifdef FIX_DIRAC_CHANNELS + for ( ch_idx = 0; ch_idx < DIRAC_MAX_ANA_CHANS; ch_idx++ ) +#else for ( ch_idx = 0; ch_idx < st_ivas->hEncoderConfig->nchan_inp; ch_idx++ ) +#endif { mvr2r( data_f[ch_idx], tmp_buffer, input_frame ); mvr2r( st_ivas->hDirAC->sba_synchro_buffer[ch_idx], data_f[ch_idx], st_ivas->hDirAC->num_samples_synchro_delay ); @@ -468,6 +487,7 @@ void ivas_dirac_enc_spar_delay_synchro( return; } + /*------------------------------------------------------------------------- * computeReferencePower_enc() * @@ -507,11 +527,13 @@ void computeReferencePower_enc( return; } + /*------------------------------------------------------------------------- * ivas_dirac_param_est_enc() * * *------------------------------------------------------------------------*/ + void ivas_dirac_param_est_enc( DIRAC_ENC_HANDLE hDirAC, IVAS_QDIRECTION *q_direction, diff --git a/lib_enc/ivas_init_enc.c b/lib_enc/ivas_init_enc.c index 21a7eb839f..e4db2ce2a1 100644 --- a/lib_enc/ivas_init_enc.c +++ b/lib_enc/ivas_init_enc.c @@ -233,53 +233,22 @@ void copy_encoder_config( st->force = st_ivas->hEncoderConfig->force; #endif st->element_mode = st_ivas->hEncoderConfig->element_mode_init; + return; } -/*-------------------------------------------------------------------* - * ivas_init_encoder() +/*------------------------------------------------------------------------- + * ivas_initialize_handles_enc() * - * Initialize IVAS encoder state structure - *-------------------------------------------------------------------*/ + * NULL initialization of handles + *-------------------------------------------------------------------------*/ -ivas_error ivas_init_encoder( - Encoder_Struct *st_ivas, /* i/o: IVAS encoder structure */ - Indice ind_list[][MAX_NUM_INDICES], /* o : bitstream indices */ - Indice ind_list_metadata[][MAX_BITS_METADATA] /* o : bitstream indices metadata */ +void ivas_initialize_handles_enc( + Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ ) { - int16_t i, n; - int16_t sce_id, cpe_id; - IVAS_FORMAT ivas_format; - int32_t input_Fs, ivas_total_brate; - ENCODER_CONFIG_HANDLE hEncoderConfig; - ivas_error error; - - error = IVAS_ERR_OK; - - hEncoderConfig = st_ivas->hEncoderConfig; - ivas_format = hEncoderConfig->ivas_format; - input_Fs = hEncoderConfig->input_Fs; - ivas_total_brate = hEncoderConfig->ivas_total_brate; - - hEncoderConfig->last_ivas_total_brate = ivas_total_brate; - - if ( ivas_format != MONO_FORMAT ) - { - /* In IVAS, ensure that minimum coded bandwidth is WB */ - hEncoderConfig->max_bwidth = max( hEncoderConfig->max_bwidth, WB ); - } - - st_ivas->ism_mode = ISM_MODE_NONE; - st_ivas->mc_mode = MC_MODE_NONE; - st_ivas->sba_mode = SBA_MODE_NONE; - - /*-----------------------------------------------------------------* - * Dummy pointers to max. number of SCEs and CPEs - *-----------------------------------------------------------------*/ - - st_ivas->nchan_transport = -1; + int16_t i; for ( i = 0; i < MAX_SCE; i++ ) { @@ -291,10 +260,12 @@ ivas_error ivas_init_encoder( st_ivas->hCPE[i] = NULL; } + st_ivas->mem_hp20_in = NULL; + /* ISm metadata handles */ - for ( n = 0; n < MAX_NUM_OBJECTS; n++ ) + for ( i = 0; i < MAX_NUM_OBJECTS; i++ ) { - st_ivas->hIsmMetaData[n] = NULL; + st_ivas->hIsmMetaData[i] = NULL; } /* Q Metadata handle */ @@ -324,6 +295,50 @@ ivas_error ivas_init_encoder( /* LFE handle */ st_ivas->hLFE = NULL; + return; +} + + +/*-------------------------------------------------------------------* + * ivas_init_encoder() + * + * Initialize IVAS encoder state structure + *-------------------------------------------------------------------*/ + +ivas_error ivas_init_encoder( + Encoder_Struct *st_ivas, /* i/o: IVAS encoder structure */ + Indice ind_list[][MAX_NUM_INDICES], /* o : bitstream indices */ + Indice ind_list_metadata[][MAX_BITS_METADATA] /* o : bitstream indices metadata */ +) +{ + int16_t i, n; + int16_t sce_id, cpe_id; + IVAS_FORMAT ivas_format; + int32_t input_Fs, ivas_total_brate; + ENCODER_CONFIG_HANDLE hEncoderConfig; + ivas_error error; + + error = IVAS_ERR_OK; + + hEncoderConfig = st_ivas->hEncoderConfig; + ivas_format = hEncoderConfig->ivas_format; + input_Fs = hEncoderConfig->input_Fs; + ivas_total_brate = hEncoderConfig->ivas_total_brate; + + hEncoderConfig->last_ivas_total_brate = ivas_total_brate; + + if ( ivas_format != MONO_FORMAT ) + { + /* In IVAS, ensure that minimum coded bandwidth is WB */ + hEncoderConfig->max_bwidth = max( hEncoderConfig->max_bwidth, WB ); + } + + st_ivas->ism_mode = ISM_MODE_NONE; + st_ivas->mc_mode = MC_MODE_NONE; + st_ivas->sba_mode = SBA_MODE_NONE; + + st_ivas->nchan_transport = -1; + /*-----------------------------------------------------------------* * Allocate and initialize SCE/CPE and other handles *-----------------------------------------------------------------*/ @@ -412,17 +427,17 @@ ivas_error ivas_init_encoder( } else if ( ivas_format == SBA_FORMAT || ivas_format == MASA_FORMAT ) { + if ( ( error = ivas_qmetadata_open( &( st_ivas->hQMetaData ) ) ) != IVAS_ERR_OK ) { - if ( ( error = ivas_qmetadata_open( &( st_ivas->hQMetaData ) ) ) != IVAS_ERR_OK ) - { - return error; - } + return error; } if ( ivas_format == SBA_FORMAT ) { st_ivas->sba_mode = ivas_sba_mode_select( ivas_total_brate ); + st_ivas->sba_analysis_order = ivas_sba_get_analysis_order( ivas_total_brate, st_ivas->hEncoderConfig->sba_order ); + if ( st_ivas->sba_mode == SBA_MODE_SPAR ) { if ( ( error = ivas_spar_enc_open( st_ivas ) ) != IVAS_ERR_OK ) @@ -581,6 +596,7 @@ ivas_error ivas_init_encoder( else if ( st_ivas->mc_mode == MC_MODE_MCMASA ) { ivas_mcmasa_setNumTransportChannels( &( st_ivas->nchan_transport ), &( hEncoderConfig->element_mode_init ), ivas_total_brate ); + if ( ( error = ivas_qmetadata_open( &( st_ivas->hQMetaData ) ) ) != IVAS_ERR_OK ) { return error; @@ -868,7 +884,7 @@ void ivas_destroy_enc( if ( st_ivas->hSCE[i] != NULL ) { destroy_sce_enc( st_ivas->hSCE[i] ); - st_ivas->hSCE[0] = NULL; + st_ivas->hSCE[i] = NULL; } } diff --git a/lib_enc/ivas_ism_enc.c b/lib_enc/ivas_ism_enc.c index 2653829d13..2433c01802 100644 --- a/lib_enc/ivas_ism_enc.c +++ b/lib_enc/ivas_ism_enc.c @@ -214,7 +214,11 @@ ivas_error ivas_ism_enc( ivas_write_format_sid( st_ivas->hEncoderConfig->ivas_format, IVAS_SCE, st->hBstr ); /* write unused bits */ +#ifdef ALIGN_SID_SIZE + nBits = ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS; +#else nBits = ( IVAS_SID_4k4 - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS; +#endif while ( nBits > 0 ) { i = min( nBits, 16 ); diff --git a/lib_enc/ivas_masa_enc.c b/lib_enc/ivas_masa_enc.c index 2e233bbc6d..c2649adc56 100644 --- a/lib_enc/ivas_masa_enc.c +++ b/lib_enc/ivas_masa_enc.c @@ -350,9 +350,7 @@ void ivas_masa_encode( count_free( h_orig_metadata ); - ivas_qmetadata_enc_sid_encode( hMetaData, hQMetaData, masa_sid_descriptor, - ivas_format, - SBA_MODE_NONE ); + ivas_qmetadata_enc_sid_encode( hMetaData, hQMetaData, masa_sid_descriptor, ivas_format, SBA_MODE_NONE ); /* restore old values */ hMasa->config.numCodingBands = numCodingBands; diff --git a/lib_enc/ivas_mcmasa_enc.c b/lib_enc/ivas_mcmasa_enc.c index 595f758e51..a281ec4760 100644 --- a/lib_enc/ivas_mcmasa_enc.c +++ b/lib_enc/ivas_mcmasa_enc.c @@ -70,9 +70,7 @@ static void ivas_mcmasa_dmx( MCMASA_ENC_HANDLE hMcMasa, float data_f[][L_FRAME48 static void compute_cov_mtx( float sr[MCMASA_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX], float si[MCMASA_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX], const int16_t freq, const int16_t N, CovarianceMatrix *COVls ); -static void computeIntensityVector_enc( const int16_t *band_grouping, float Cldfb_RealBuffer[DIRAC_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX], float Cldfb_ImagBuffer[DIRAC_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX], const int16_t enc_param_start_band, /* i: first band to process */ - const int16_t num_frequency_bands, - float intensity_real[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS] ); +static void computeIntensityVector_enc( const int16_t *band_grouping, float Cldfb_RealBuffer[DIRAC_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX], float Cldfb_ImagBuffer[DIRAC_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX], const int16_t enc_param_start_band, const int16_t num_frequency_bands, float intensity_real[DIRAC_NUM_DIMS][MASA_FREQUENCY_BANDS] ); static void computeVerticalDiffuseness( float **buffer_intensity, const float *buffer_energy, const int16_t averaging_length, const int16_t num_freq_bands, float *diffuseness ); diff --git a/lib_enc/ivas_mct_enc.c b/lib_enc/ivas_mct_enc.c index 20a2856654..9aa5fe04c5 100644 --- a/lib_enc/ivas_mct_enc.c +++ b/lib_enc/ivas_mct_enc.c @@ -193,25 +193,26 @@ ivas_error create_mct_enc( hMCT->nchan_out_woLFE = st_ivas->hEncoderConfig->nchan_inp - 1; /* LFE channel is coded separately */ hMCT->num_lfe = TRUE; } - else if ( ivas_format == SBA_FORMAT && st_ivas->hSpar ) +#ifdef HARMONIZE_SBA_NCHAN_TRANSPORT + else if ( ivas_format == SBA_FORMAT ) { -#ifndef SBA_ORDER_BITSTREAM - hMCT->nchan_out_woLFE = ivas_get_spar_num_TCs( ivas_total_brate, st_ivas->hEncoderConfig->sba_order ); + hMCT->nchan_out_woLFE = ivas_get_sba_num_TCs( ivas_total_brate, st_ivas->sba_analysis_order ); + + hMCT->num_lfe = FALSE; + } #else + else if ( ivas_format == SBA_FORMAT && st_ivas->hSpar ) + { hMCT->nchan_out_woLFE = ivas_get_spar_num_TCs( ivas_total_brate, st_ivas->sba_analysis_order ); -#endif hMCT->num_lfe = FALSE; } else if ( ivas_format == SBA_FORMAT && st_ivas->hDirAC ) { -#ifndef SBA_ORDER_BITSTREAM - hMCT->nchan_out_woLFE = ivas_dirac_getNumTransportChannels( ivas_total_brate, st_ivas->hEncoderConfig->sba_order, st_ivas->hEncoderConfig->sba_planar ); -#else hMCT->nchan_out_woLFE = ivas_dirac_getNumTransportChannels( ivas_total_brate, st_ivas->sba_analysis_order, st_ivas->hEncoderConfig->sba_planar ); -#endif hMCT->num_lfe = FALSE; } +#endif else if ( ivas_format == MC_FORMAT && st_ivas->mc_mode == MC_MODE_PARAMMC ) { hMCT->nchan_out_woLFE = ivas_param_mc_getNumTransportChannels( ivas_total_brate, st_ivas->hEncoderConfig->mc_input_setup ); @@ -219,11 +220,7 @@ ivas_error create_mct_enc( } else if ( ivas_format == SBA_FORMAT ) { -#ifndef SBA_ORDER_BITSTREAM - hMCT->nchan_out_woLFE = ivas_sba_get_nchan( st_ivas->hEncoderConfig->sba_order, st_ivas->hEncoderConfig->sba_planar ); -#else hMCT->nchan_out_woLFE = ivas_sba_get_nchan( st_ivas->sba_analysis_order, st_ivas->hEncoderConfig->sba_planar ); -#endif hMCT->num_lfe = FALSE; } else @@ -349,24 +346,29 @@ ivas_error mct_enc_reconfigure( hMCT->nchan_out_woLFE = st_ivas->hEncoderConfig->nchan_inp - 1; /* LFE channel is coded separately */ hMCT->num_lfe = TRUE; } - else if ( ivas_format == SBA_FORMAT && st_ivas->hDirAC ) +#ifdef HARMONIZE_SBA_NCHAN_TRANSPORT + else if ( ivas_format == SBA_FORMAT && st_ivas->hDirAC ) // VE: this condition to be reviewed together with the following one { -#ifndef SBA_ORDER_BITSTREAM - hMCT->nchan_out_woLFE = ivas_dirac_getNumTransportChannels( ivas_total_brate, st_ivas->hEncoderConfig->sba_order, st_ivas->hEncoderConfig->sba_planar ); + hMCT->nchan_out_woLFE = ivas_get_sba_num_TCs( ivas_total_brate, st_ivas->sba_analysis_order ); + hMCT->num_lfe = FALSE; + } + else if ( ivas_format == SBA_FORMAT ) + { + hMCT->nchan_out_woLFE = ivas_sba_get_nchan( st_ivas->sba_analysis_order, st_ivas->hEncoderConfig->sba_planar ); + hMCT->num_lfe = FALSE; + } #else + else if ( ivas_format == SBA_FORMAT && st_ivas->hDirAC ) + { hMCT->nchan_out_woLFE = ivas_dirac_getNumTransportChannels( ivas_total_brate, st_ivas->sba_analysis_order, st_ivas->hEncoderConfig->sba_planar ); -#endif hMCT->num_lfe = FALSE; } else if ( ivas_format == SBA_FORMAT ) { -#ifndef SBA_ORDER_BITSTREAM - hMCT->nchan_out_woLFE = ivas_sba_get_nchan( st_ivas->hEncoderConfig->sba_order, st_ivas->hEncoderConfig->sba_planar ); -#else hMCT->nchan_out_woLFE = ivas_sba_get_nchan( st_ivas->sba_analysis_order, st_ivas->hEncoderConfig->sba_planar ); -#endif hMCT->num_lfe = FALSE; } +#endif else { assert( !"IVAS format currently not supported for MCT" ); diff --git a/lib_enc/ivas_mct_enc_mct.c b/lib_enc/ivas_mct_enc_mct.c index 62ff9be888..309a023fe7 100644 --- a/lib_enc/ivas_mct_enc_mct.c +++ b/lib_enc/ivas_mct_enc_mct.c @@ -834,7 +834,11 @@ void mctStereoIGF_enc( float *p_powerSpecMsInv[CPE_CHANNELS][NB_DIV]; float *p_inv_spectrum[CPE_CHANNELS][NB_DIV]; float *p_orig_spectrum[CPE_CHANNELS][NB_DIV]; +#ifdef DRAM_REDUCTION_MCT_IGF + float *p_powerSpec[NB_DIV]; +#else float p_powerSpec[NB_DIV][N_MAX]; +#endif int16_t singleChEle[MCT_MAX_CHANNELS]; L_subframeTCX = 0; /* to avoid compilation warning */ @@ -855,10 +859,15 @@ void mctStereoIGF_enc( p_st[0] = sts[ch1]; p_st[1] = sts[ch2]; +#ifdef DRAM_REDUCTION_MCT_IGF + p_powerSpec[0] = powerSpec[ch1]; + p_powerSpec[1] = powerSpec[ch2]; +#else mvr2r( powerSpec[ch1], p_powerSpec[0], L_FRAME48k ); set_f( &p_powerSpec[0][L_FRAME48k], 0.f, N_MAX - L_FRAME48k ); mvr2r( powerSpec[ch2], p_powerSpec[1], L_FRAME48k ); set_f( &p_powerSpec[1][L_FRAME48k], 0.f, N_MAX - L_FRAME48k ); +#endif /* Band-wise M/S for MDST */ nSubframes = p_st[0]->hTcxEnc->tcxMode == TCX_20 ? 1 : NB_DIV; diff --git a/lib_enc/ivas_mdct_core_enc.c b/lib_enc/ivas_mdct_core_enc.c index 4d9d1f2577..0d2f5817d6 100644 --- a/lib_enc/ivas_mdct_core_enc.c +++ b/lib_enc/ivas_mdct_core_enc.c @@ -63,7 +63,7 @@ static void enc_prm_pre_mdct( int16_t param[], /* i : parameters */ const int16_t *no_param_tns, /* i : number of TNS parameters per subframe */ int16_t p_param[2], /* o : pointer to parameters for next round of bs writing */ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE const int16_t is_mct, #endif BSTR_ENC_HANDLE hBstr /* i/o: encoder bitstream handle */ @@ -80,7 +80,7 @@ static void enc_prm_pre_mdct( * Header *--------------------------------------------------------------------------------*/ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE writeTCXMode( st, hBstr, is_mct, &nbits_start ); #else writeTCXMode( st, hBstr, &nbits_start ); @@ -1065,7 +1065,7 @@ void ivas_mdct_core_whitening_enc( continue; } -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE enc_prm_pre_mdct( st, param_core[ch], ( ( ( ch > 0 ) && ( sts[0]->hTcxEnc->fUseTns[0] + sts[0]->hTcxEnc->fUseTns[1] > 0 ) && !mct_on ) ? tnsSize[ch] : NULL ), p_param[ch], mct_on, hBstr ); #else enc_prm_pre_mdct( st, param_core[ch], ( ( ( ch > 0 ) && ( sts[0]->hTcxEnc->fUseTns[0] + sts[0]->hTcxEnc->fUseTns[1] > 0 ) && !mct_on ) ? tnsSize[ch] : NULL ), p_param[ch], hBstr ); diff --git a/lib_enc/ivas_qmetadata_enc.c b/lib_enc/ivas_qmetadata_enc.c index f62b61e4ef..6042c9e10a 100644 --- a/lib_enc/ivas_qmetadata_enc.c +++ b/lib_enc/ivas_qmetadata_enc.c @@ -150,7 +150,7 @@ ivas_error ivas_qmetadata_enc_encode( int16_t diff_bits, bits_ec, next_ind_raw_flag; int16_t dfRatio_bits[MASA_MAXIMUM_CODING_SUBBANDS]; int16_t bits_surround_coh, no_TF; - int16_t dir2_bands[MASA_MAXIMUM_CODING_SUBBANDS / 2]; + int16_t dir2_bands[MASA_MAXIMUM_TWO_DIR_BANDS]; int16_t ind_order[MASA_MAXIMUM_CODING_SUBBANDS]; int16_t reduce_bits; ivas_error error; @@ -684,17 +684,32 @@ void ivas_qmetadata_enc_sid_encode( { if ( sba_mode == SBA_MODE_SPAR ) { +#ifdef ALIGN_SID_SIZE + /* TODO: still use old sid frame size to keep bitexactness */ + metadata_sid_bits = (int16_t) ( 5000 /*IVAS_SID_5k2*/ - SID_2k40 ) / FRAMES_PER_SEC - ( SPAR_DTX_BANDS * SPAR_SID_BITS_TAR_PER_BAND ) - 1; /* -1 for inactive mode header bit*/ +#else metadata_sid_bits = (int16_t) ( IVAS_SID_5k - SID_2k40 ) / FRAMES_PER_SEC - ( SPAR_DTX_BANDS * SPAR_SID_BITS_TAR_PER_BAND ) - 1; /* -1 for inactive mode header bit*/ +#endif } else { - /* keep 13.2 and 16.4 sid bitrate as 4.4 kbps for now*/ + /* keep 13.2 and 16.4 SID bitrate as 4.4 kbps for now*/ +#ifdef ALIGN_SID_SIZE + /* TODO: still use old sid frame size to keep bitexactness */ + metadata_sid_bits = ( 4400 /*IVAS_SID_5k2*/ - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS; +#else metadata_sid_bits = ( IVAS_SID_4k4 - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS; +#endif } } else { +#ifdef ALIGN_SID_SIZE + /* TODO: still use old sid frame size to keep bitexactness */ + metadata_sid_bits = ( 4400 /*IVAS_SID_5k2*/ - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS; +#else metadata_sid_bits = ( IVAS_SID_4k4 - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS; +#endif } #ifdef DEBUG_MODE_QMETADATA @@ -873,6 +888,22 @@ void ivas_qmetadata_enc_sid_encode( } #endif +#ifdef ALIGN_SID_SIZE + /* TODO: temporary to keep BE */ + if ( ivas_format == SBA_FORMAT ) + { + if ( sba_mode != SBA_MODE_SPAR ) + { + /* keep 13.2 and 16.4 SID bitrate as 4.4 kbps for now*/ + metadata_sid_bits = ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS - 1; /* -1 for spar/dirac indicator*/ + } + } + else + { + metadata_sid_bits = ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS; + } +#endif + /* fill bits*/ assert( ( hMetaData->nb_bits_tot - bit_pos_start ) <= metadata_sid_bits && "Too many written bits!" ); while ( ( hMetaData->nb_bits_tot - bit_pos_start ) < metadata_sid_bits ) @@ -896,11 +927,18 @@ void reset_metadata_spatial( int32_t *total_brate, /* o : total bitrate */ const int32_t core_brate, /* i : core bitrate */ const int16_t nb_bits_metadata, /* i : number of meatdata bits */ - const SBA_MODE sba_mode, /* i : SBA mode */ - const int16_t element_mode /* i : element mode */ +#ifndef ALIGN_SID_SIZE + const SBA_MODE sba_mode, /* i : SBA mode */ + const int16_t element_mode /* i : element mode */ +#else + const SBA_MODE sba_mode /* i : SBA mode */ +#endif ) { int16_t i, next_ind_sid, last_ind_sid; +#ifdef ALIGN_SID_SIZE + int16_t metadata_sid_bits; +#endif if ( core_brate == SID_2k40 || core_brate == FRAME_NO_DATA ) { @@ -909,6 +947,14 @@ void reset_metadata_spatial( if ( sba_mode == SBA_MODE_SPAR ) { assert( hMetaData->ind_list[0].nb_bits == 1 ); +#ifdef ALIGN_SID_SIZE + hMetaData->ind_list[0].value = 1; + metadata_sid_bits = (int16_t) ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS; + while ( hMetaData->nb_bits_tot < metadata_sid_bits ) + { + push_next_indice( hMetaData, 0, 1 ); /*fill bit*/ + } +#else if ( element_mode > IVAS_SCE ) { hMetaData->ind_list[0].value = 1; @@ -917,6 +963,7 @@ void reset_metadata_spatial( { hMetaData->ind_list[0].value = 0; } +#endif } else { @@ -946,7 +993,11 @@ void reset_metadata_spatial( hMetaData->ind_list[i].nb_bits = -1; } hMetaData->last_ind = hMetaData->next_ind; +#ifdef ALIGN_SID_SIZE + assert( ( hMetaData->nb_bits_tot == ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS ) && "Problem of SID metadata in SCE" ); +#else assert( ( hMetaData->nb_bits_tot == ( IVAS_SID_4k4 - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS ) && "Problem of SID metadata in SCE" ); +#endif } } else diff --git a/lib_enc/ivas_rom_enc.c b/lib_enc/ivas_rom_enc.c index e8048b8f1a..ebc4ee6bc3 100644 --- a/lib_enc/ivas_rom_enc.c +++ b/lib_enc/ivas_rom_enc.c @@ -534,160 +534,6 @@ const float ari_bit_estimate_s17_LC[RANGE_N_CONTEXT][RANGE_N_SYMBOLS] = * Stereo downmix to EVS ROM tables *----------------------------------------------------------------------------------*/ -#ifndef NTT_REMOVE_EPS_ROM -const float Stereo_dmx_s_wnd_coef_eps_16k[L_FRAME16k * 3 / 4] = { - 0.00000000f, 0.000385506690f, 0.000770864717f, 0.00115592557f, 0.00154054083f, 0.00192456215f, 0.00230784155f, 0.00269023119f, 0.00307158381f, 0.00345175178f, - 0.00383058959f, 0.00420795102f, 0.00458368938f, 0.00495766103f, 0.00532972161f, 0.00569972629f, 0.00606753491f, 0.00643300405f, 0.00679599261f, 0.00715636183f, - 0.00751397246f, 0.00786868576f, 0.00822036527f, 0.00856887549f, 0.00891408324f, 0.00925585348f, 0.00959405676f, 0.00992856082f, 0.0102592362f, 0.0105859563f, - 0.0109085962f, 0.0112270303f, 0.0115411365f, 0.0118507938f, 0.0121558821f, 0.0124562839f, 0.0127518829f, 0.0130425673f, 0.0133282226f, 0.0136087397f, - 0.0138840098f, 0.0141539266f, 0.0144183896f, 0.0146772927f, 0.0149305379f, 0.0151780248f, 0.0154196629f, 0.0156553555f, 0.0158850122f, 0.0161085464f, - 0.0163258687f, 0.0165368970f, 0.0167415515f, 0.0169397499f, 0.0171314199f, 0.0173164830f, 0.0174948741f, 0.0176665168f, 0.0178313497f, 0.0179893095f, - 0.0181403328f, 0.0182843637f, 0.0184213445f, 0.0185512230f, 0.0186739527f, 0.0187894795f, 0.0188977662f, 0.0189987645f, 0.0190924387f, 0.0191787537f, - 0.0192576759f, 0.0193291716f, 0.0193932168f, 0.0194497835f, 0.0194988549f, 0.0195404068f, 0.0195744261f, 0.0196008999f, 0.0196198169f, 0.0196311697f, - 0.0196349546f, 0.0196311697f, 0.0196198169f, 0.0196008999f, 0.0195744261f, 0.0195404068f, 0.0194988549f, 0.0194497835f, 0.0193932150f, 0.0193291716f, - 0.0192576740f, 0.0191787537f, 0.0190924387f, 0.0189987645f, 0.0188977644f, 0.0187894795f, 0.0186739508f, 0.0185512230f, 0.0184213426f, 0.0182843637f, - 0.0181403328f, 0.0179893095f, 0.0178313479f, 0.0176665168f, 0.0174948722f, 0.0173164830f, 0.0171314199f, 0.0169397499f, 0.0167415496f, 0.0165368970f, - 0.0163258687f, 0.0161085445f, 0.0158850104f, 0.0156553555f, 0.0154196629f, 0.0151780220f, 0.0149305360f, 0.0146772927f, 0.0144183887f, 0.0141539248f, - 0.0138840098f, 0.0136087388f, 0.0133282207f, 0.0130425654f, 0.0127518829f, 0.0124562830f, 0.0121558802f, 0.0118507929f, 0.0115411356f, 0.0112270294f, - 0.0109085953f, 0.0105859553f, 0.0102592343f, 0.00992855709f, 0.00959405396f, 0.00925585162f, 0.00891408045f, 0.00856887735f, 0.00822036248f, 0.00786868297f, - 0.00751396874f, 0.00715636322f, 0.00679598982f, 0.00643300032f, 0.00606753537f, 0.00569972722f, 0.00532971695f, 0.00495765638f, 0.00458368938f, 0.00420795055f, - 0.00383058493f, 0.00345175178f, 0.00307158334f, 0.00269023073f, 0.00230784062f, 0.00192456122f, 0.00154053967f, 0.00115592428f, 0.000770863262f, 0.000385505118f, - -1.71654224e-09f, -0.000385508552f, -0.000770866696f, -0.00115592312f, -0.00154053851f, -0.00192456460f, -0.00230784412f, -0.00269023376f, -0.00307158637f, -0.00345175504f, - -0.00383058819f, -0.00420794915f, -0.00458368799f, -0.00495766429f, -0.00532972487f, -0.00569973048f, -0.00606753910f, -0.00643300358f, -0.00679599261f, -0.00715636183f, - -0.00751397153f, -0.00786868948f, -0.00822036993f, -0.00856888015f, -0.00891408417f, -0.00925585441f, -0.00959405676f, -0.00992856082f, -0.0102592362f, -0.0105859619f, - -0.0109086009f, -0.0112270284f, -0.0115411393f, -0.0118507957f, -0.0121558839f, -0.0124562858f, -0.0127518848f, -0.0130425720f, -0.0133282207f, -0.0136087369f, - -0.0138840117f, -0.0141539304f, -0.0144183915f, -0.0146772945f, -0.0149305388f, -0.0151780248f, -0.0154196648f, -0.0156553555f, -0.0158850141f, -0.0161085445f, - -0.0163258705f, -0.0165369026f, -0.0167415477f, -0.0169397499f, -0.0171314217f, -0.0173164848f, -0.0174948759f, -0.0176665168f, -0.0178313479f, -0.0179893095f, - -0.0181403328f, -0.0182843637f, -0.0184213463f, -0.0185512248f, -0.0186739527f, -0.0187894795f, -0.0188977644f, -0.0189987663f, -0.0190924387f, -0.0191787556f, - -0.0192576759f, -0.0193291716f, -0.0193932150f, -0.0194497835f, -0.0194988549f, -0.0195404068f, -0.0195744261f, -0.0196008999f, -0.0196198169f, -0.0196311697f -}; - -const float Stereo_dmx_s_wnd_coef_eps_32k[L_FRAME32k * 3 / 4] = { - 0.00000000f, 9.63813145e-05f, 0.000192753345f, 0.000289106771f, 0.000385432359f, 0.000481720810f, 0.000577962783f, 0.000674149080f, 0.000770270417f, 0.000866317423f, - 0.000962281076f, 0.00105815195f, 0.00115392078f, 0.00124957843f, 0.00134511560f, 0.00144052308f, 0.00153579190f, 0.00163091265f, 0.00172587589f, 0.00182067312f, - 0.00191529479f, 0.00200973195f, 0.00210397551f, 0.00219801581f, 0.00229184469f, 0.00238545262f, 0.00247883052f, 0.00257196953f, 0.00266486080f, 0.00275749480f, - 0.00284986314f, 0.00294195698f, 0.00303376745f, 0.00312528526f, 0.00321650202f, 0.00330740865f, 0.00339799630f, 0.00348825660f, 0.00357818091f, 0.00366776017f, - 0.00375698623f, 0.00384584931f, 0.00393434288f, 0.00402245624f, 0.00411018264f, 0.00419751229f, 0.00428443775f, 0.00437095016f, 0.00445704162f, 0.00454270327f, - 0.00462792674f, 0.00471270457f, 0.00479702838f, 0.00488088885f, 0.00496428041f, 0.00504719233f, 0.00512961810f, 0.00521154935f, 0.00529297814f, 0.00537389703f, - 0.00545429811f, 0.00553417346f, 0.00561351515f, 0.00569231622f, 0.00577056827f, 0.00584826432f, 0.00592539692f, 0.00600195816f, 0.00607794104f, 0.00615333812f, - 0.00622814195f, 0.00630234554f, 0.00637594145f, 0.00644892361f, 0.00652128365f, 0.00659301504f, 0.00666411128f, 0.00673456443f, 0.00680436986f, 0.00687351823f, - 0.00694200490f, 0.00700982194f, 0.00707696332f, 0.00714342389f, 0.00720919482f, 0.00727427099f, 0.00733864633f, 0.00740231434f, 0.00746526895f, 0.00752750318f, - 0.00758901238f, 0.00764979096f, 0.00770983147f, 0.00776912877f, 0.00782767776f, 0.00788547192f, 0.00794250611f, 0.00799877476f, 0.00805427320f, 0.00810899399f, - 0.00816293433f, 0.00821608771f, 0.00826844852f, 0.00832001306f, 0.00837077573f, 0.00842073187f, 0.00846987497f, 0.00851820316f, 0.00856570993f, 0.00861239061f, - 0.00865824148f, 0.00870325882f, 0.00874743704f, 0.00879077055f, 0.00883325841f, 0.00887489505f, 0.00891567487f, 0.00895559601f, 0.00899465475f, 0.00903284643f, - 0.00907016639f, 0.00910661276f, 0.00914218184f, 0.00917686895f, 0.00921067223f, 0.00924358703f, 0.00927561149f, 0.00930674188f, 0.00933697633f, 0.00936630927f, - 0.00939473975f, 0.00942226499f, 0.00944888312f, 0.00947458949f, 0.00949938223f, 0.00952325948f, 0.00954621937f, 0.00956825912f, 0.00958937686f, 0.00960957073f, - 0.00962883793f, 0.00964717567f, 0.00966458581f, 0.00968106277f, 0.00969660841f, 0.00971121807f, 0.00972489174f, 0.00973762851f, 0.00974942744f, 0.00976028573f, - 0.00977020338f, 0.00977917947f, 0.00978721306f, 0.00979430322f, 0.00980044995f, 0.00980565138f, 0.00980990846f, 0.00981321931f, 0.00981558487f, 0.00981700420f, - 0.00981747732f, 0.00981700420f, 0.00981558487f, 0.00981321931f, 0.00980990846f, 0.00980565138f, 0.00980044995f, 0.00979430322f, 0.00978721306f, 0.00977917947f, - 0.00977020338f, 0.00976028573f, 0.00974942744f, 0.00973762851f, 0.00972489174f, 0.00971121807f, 0.00969660748f, 0.00968106277f, 0.00966458581f, 0.00964717567f, - 0.00962883700f, 0.00960956980f, 0.00958937686f, 0.00956825912f, 0.00954621937f, 0.00952325948f, 0.00949938223f, 0.00947458856f, 0.00944888219f, 0.00942226499f, - 0.00939473975f, 0.00936630927f, 0.00933697540f, 0.00930674188f, 0.00927561149f, 0.00924358703f, 0.00921067130f, 0.00917686801f, 0.00914218184f, 0.00910661276f, - 0.00907016639f, 0.00903284550f, 0.00899465475f, 0.00895559601f, 0.00891567394f, 0.00887489505f, 0.00883325841f, 0.00879077055f, 0.00874743611f, 0.00870325882f, - 0.00865824148f, 0.00861238968f, 0.00856570993f, 0.00851820316f, 0.00846987497f, 0.00842073094f, 0.00837077480f, 0.00832001306f, 0.00826844852f, 0.00821608678f, - 0.00816293433f, 0.00810899399f, 0.00805427227f, 0.00799877476f, 0.00794250518f, 0.00788547192f, 0.00782767776f, 0.00776912784f, 0.00770983147f, 0.00764979003f, - 0.00758901099f, 0.00752750272f, 0.00746526802f, 0.00740231294f, 0.00733864633f, 0.00727427006f, 0.00720919436f, 0.00714342296f, 0.00707696239f, 0.00700982334f, - 0.00694200490f, 0.00687351730f, 0.00680436939f, 0.00673456397f, 0.00666411035f, 0.00659301365f, 0.00652128272f, 0.00644892408f, 0.00637594145f, 0.00630234415f, - 0.00622814149f, 0.00615333673f, 0.00607794011f, 0.00600195862f, 0.00592539646f, 0.00584826525f, 0.00577056780f, 0.00569231436f, 0.00561351469f, 0.00553417206f, - 0.00545429764f, 0.00537389750f, 0.00529297767f, 0.00521154935f, 0.00512961717f, 0.00504719047f, 0.00496427855f, 0.00488088885f, 0.00479702698f, 0.00471270457f, - 0.00462792581f, 0.00454270281f, 0.00445704022f, 0.00437094783f, 0.00428443868f, 0.00419751182f, 0.00411018124f, 0.00402245624f, 0.00393434148f, 0.00384584907f, - 0.00375698437f, 0.00366775948f, 0.00357818161f, 0.00348825636f, 0.00339799491f, 0.00330740795f, 0.00321650016f, 0.00312528457f, 0.00303376769f, 0.00294195651f, - 0.00284986361f, 0.00275749387f, 0.00266485848f, 0.00257196836f, 0.00247882819f, 0.00238545146f, 0.00229184469f, 0.00219801464f, 0.00210397528f, 0.00200973079f, - 0.00191529247f, 0.00182067417f, 0.00172587589f, 0.00163091114f, 0.00153579167f, 0.00144052168f, 0.00134511536f, 0.00124957680f, 0.00115392031f, 0.00105815264f, - 0.000962280610f, 0.000866315851f, 0.000770269835f, 0.000674147333f, 0.000577962142f, 0.000481721276f, 0.000385431631f, 0.000289107207f, 0.000192752559f, 9.63793209e-05f, - -8.58271121e-10f, -9.63833809e-05f, -0.000192754276f, -0.000289106567f, -0.000385433348f, -0.000481720665f, -0.000577961560f, -0.000674149022f, -0.000770269253f, -0.000866317481f, - -0.000962282298f, -0.00105815206f, -0.00115392206f, -0.00124957855f, -0.00134511688f, -0.00144052564f, -0.00153579318f, -0.00163091510f, -0.00172587752f, -0.00182067591f, - -0.00191529409f, -0.00200973242f, -0.00210397458f, -0.00219801627f, -0.00229184399f, -0.00238545309f, -0.00247883215f, -0.00257196999f, -0.00266486243f, -0.00275749573f, - -0.00284986524f, -0.00294196024f, -0.00303376955f, -0.00312528410f, -0.00321650179f, -0.00330740749f, -0.00339799630f, -0.00348825776f, -0.00357818091f, -0.00366776134f, - -0.00375698577f, -0.00384585070f, -0.00393434474f, -0.00402245764f, -0.00411018496f, -0.00419751368f, -0.00428444007f, -0.00437094970f, -0.00445704209f, -0.00454270234f, - -0.00462792721f, -0.00471270364f, -0.00479702838f, -0.00488089072f, -0.00496428041f, -0.00504719326f, -0.00512961810f, -0.00521155121f, -0.00529298093f, -0.00537389843f, - -0.00545430044f, -0.00553417299f, -0.00561351422f, -0.00569231622f, -0.00577056967f, -0.00584826432f, -0.00592539785f, -0.00600195816f, -0.00607794197f, -0.00615333952f, - -0.00622814288f, -0.00630234741f, -0.00637594238f, -0.00644892501f, -0.00652128598f, -0.00659301504f, -0.00666411035f, -0.00673456537f, -0.00680436846f, -0.00687351823f, - -0.00694200583f, -0.00700982241f, -0.00707696518f, -0.00714342389f, -0.00720919576f, -0.00727427332f, -0.00733864726f, -0.00740231574f, -0.00746526942f, -0.00752750272f, - -0.00758901238f, -0.00764979143f, -0.00770983240f, -0.00776912784f, -0.00782767776f, -0.00788547192f, -0.00794250704f, -0.00799877662f, -0.00805427227f, -0.00810899492f, - -0.00816293526f, -0.00821608957f, -0.00826845132f, -0.00832001399f, -0.00837077387f, -0.00842073094f, -0.00846987497f, -0.00851820316f, -0.00856571086f, -0.00861239061f, - -0.00865824241f, -0.00870325882f, -0.00874743797f, -0.00879077241f, -0.00883325841f, -0.00887489505f, -0.00891567394f, -0.00895559601f, -0.00899465475f, -0.00903284643f, - -0.00907016639f, -0.00910661276f, -0.00914218184f, -0.00917686988f, -0.00921067316f, -0.00924358703f, -0.00927561242f, -0.00930674374f, -0.00933697633f, -0.00936631020f, - -0.00939473975f, -0.00942226499f, -0.00944888219f, -0.00947458949f, -0.00949938316f, -0.00952326041f, -0.00954621937f, -0.00956825912f, -0.00958937779f, -0.00960957073f, - -0.00962883793f, -0.00964717567f, -0.00966458581f, -0.00968106370f, -0.00969660748f, -0.00971121807f, -0.00972489174f, -0.00973762851f, -0.00974942744f, -0.00976028573f, - -0.00977020338f, -0.00977917947f, -0.00978721306f, -0.00979430322f, -0.00980044995f, -0.00980565138f, -0.00980990846f, -0.00981321931f, -0.00981558487f, -0.00981700420f -}; - -const float Stereo_dmx_s_wnd_coef_eps_48k[L_FRAME48k * 3 / 4] = { - 0.00000000f, 4.28365238e-05f, 8.56712068e-05f, 0.000128502230f, 0.000171327745f, 0.000214145897f, 0.000256954925f, 0.000299752894f, 0.000342538056f, 0.000385308522f, - 0.000428062514f, 0.000470798172f, 0.000513513631f, 0.000556207087f, 0.000598876737f, 0.000641520717f, 0.000684137223f, 0.000726724451f, 0.000769280537f, 0.000811803620f, - 0.000854292011f, 0.000896743732f, 0.000939157035f, 0.000981530058f, 0.00102386123f, 0.00106614840f, 0.00110838993f, 0.00115058408f, 0.00119272876f, 0.00123482244f, - 0.00127686327f, 0.00131884927f, 0.00136077893f, 0.00140265026f, 0.00144446141f, 0.00148621085f, 0.00152789650f, 0.00156951661f, 0.00161106954f, 0.00165255368f, - 0.00169396668f, 0.00173530739f, 0.00177657383f, 0.00181776390f, 0.00185887620f, 0.00189990876f, 0.00194086006f, 0.00198172848f, 0.00202251156f, 0.00206320849f, - 0.00210381625f, 0.00214433460f, 0.00218476099f, 0.00222509354f, 0.00226533110f, 0.00230547134f, 0.00234551285f, 0.00238545402f, 0.00242529274f, 0.00246502785f, - 0.00250465749f, 0.00254417956f, 0.00258359266f, 0.00262289518f, 0.00266208523f, 0.00270116120f, 0.00274012191f, 0.00277896458f, 0.00281768874f, 0.00285629183f, - 0.00289477292f, 0.00293312967f, 0.00297136116f, 0.00300946506f, 0.00304743997f, 0.00308528449f, 0.00312299700f, 0.00316057540f, 0.00319801876f, 0.00323532475f, - 0.00327249244f, 0.00330952019f, 0.00334640569f, 0.00338314800f, 0.00341974548f, 0.00345619628f, 0.00349249900f, 0.00352865248f, 0.00356465438f, 0.00360050355f, - 0.00363619882f, 0.00367173832f, 0.00370712043f, 0.00374234351f, 0.00377740664f, 0.00381230796f, 0.00384704559f, 0.00388161885f, 0.00391602563f, 0.00395026430f, - 0.00398433441f, 0.00401823362f, 0.00405196054f, 0.00408551423f, 0.00411889236f, 0.00415209495f, 0.00418511871f, 0.00421796367f, 0.00425062794f, 0.00428310968f, - 0.00431540888f, 0.00434752228f, 0.00437944988f, 0.00441118982f, 0.00444274070f, 0.00447410159f, 0.00450527016f, 0.00453624642f, 0.00456702849f, 0.00459761405f, - 0.00462800311f, 0.00465819426f, 0.00468818564f, 0.00471797585f, 0.00474756397f, 0.00477694906f, 0.00480613019f, 0.00483510410f, 0.00486387173f, 0.00489243073f, - 0.00492078019f, 0.00494891917f, 0.00497684581f, 0.00500455918f, 0.00503205787f, 0.00505934143f, 0.00508640893f, 0.00511325756f, 0.00513988733f, 0.00516629731f, - 0.00519248564f, 0.00521845184f, 0.00524419453f, 0.00526971230f, 0.00529500423f, 0.00532006938f, 0.00534490682f, 0.00536951516f, 0.00539389346f, 0.00541804079f, - 0.00544195622f, 0.00546563789f, 0.00548908627f, 0.00551229948f, 0.00553527568f, 0.00555801531f, 0.00558051746f, 0.00560277933f, 0.00562480185f, 0.00564658362f, - 0.00566812325f, 0.00568941981f, 0.00571047375f, 0.00573128136f, 0.00575184496f, 0.00577216130f, 0.00579223083f, 0.00581205217f, 0.00583162485f, 0.00585094700f, - 0.00587001862f, 0.00588883879f, 0.00590740750f, 0.00592572242f, 0.00594378356f, 0.00596159045f, 0.00597914122f, 0.00599643635f, 0.00601347443f, 0.00603025546f, - 0.00604677759f, 0.00606304128f, 0.00607904466f, 0.00609478820f, 0.00611026958f, 0.00612549018f, 0.00614044815f, 0.00615514303f, 0.00616957434f, 0.00618374115f, - 0.00619764347f, 0.00621127989f, 0.00622465089f, 0.00623775460f, 0.00625059102f, 0.00626316015f, 0.00627546059f, 0.00628749235f, 0.00629925495f, 0.00631074747f, - 0.00632196991f, 0.00633292133f, 0.00634360174f, 0.00635401066f, 0.00636414625f, 0.00637401035f, 0.00638360064f, 0.00639291806f, 0.00640196120f, 0.00641073054f, - 0.00641922513f, 0.00642744405f, 0.00643538870f, 0.00644305674f, 0.00645044958f, 0.00645756535f, 0.00646440545f, 0.00647096802f, 0.00647725351f, 0.00648326147f, - 0.00648899190f, 0.00649444386f, 0.00649961783f, 0.00650451379f, 0.00650913082f, 0.00651346892f, 0.00651752809f, 0.00652130833f, 0.00652480870f, 0.00652803015f, - 0.00653097173f, 0.00653363345f, 0.00653601484f, 0.00653811684f, 0.00653993897f, 0.00654148031f, 0.00654274225f, 0.00654372340f, 0.00654442422f, 0.00654484471f, - 0.00654498488f, 0.00654484471f, 0.00654442422f, 0.00654372340f, 0.00654274225f, 0.00654148031f, 0.00653993897f, 0.00653811684f, 0.00653601484f, 0.00653363345f, - 0.00653097173f, 0.00652802968f, 0.00652480870f, 0.00652130833f, 0.00651752809f, 0.00651346892f, 0.00650913082f, 0.00650451332f, 0.00649961783f, 0.00649444386f, - 0.00648899190f, 0.00648326147f, 0.00647725351f, 0.00647096802f, 0.00646440499f, 0.00645756535f, 0.00645044912f, 0.00644305674f, 0.00643538870f, 0.00642744405f, - 0.00641922466f, 0.00641073054f, 0.00640196120f, 0.00639291806f, 0.00638360064f, 0.00637400988f, 0.00636414625f, 0.00635401020f, 0.00634360174f, 0.00633292086f, - 0.00632196991f, 0.00631074747f, 0.00629925495f, 0.00628749235f, 0.00627546012f, 0.00626315968f, 0.00625059055f, 0.00623775413f, 0.00622465042f, 0.00621127989f, - 0.00619764347f, 0.00618374115f, 0.00616957434f, 0.00615514303f, 0.00614044769f, 0.00612549018f, 0.00611027004f, 0.00609478774f, 0.00607904419f, 0.00606304081f, - 0.00604677759f, 0.00603025500f, 0.00601347489f, 0.00599643635f, 0.00597914122f, 0.00596158998f, 0.00594378309f, 0.00592572149f, 0.00590740703f, 0.00588883879f, - 0.00587001862f, 0.00585094653f, 0.00583162392f, 0.00581205124f, 0.00579223037f, 0.00577216130f, 0.00575184496f, 0.00573128182f, 0.00571047282f, 0.00568941981f, - 0.00566812325f, 0.00564658316f, 0.00562480185f, 0.00560277933f, 0.00558051653f, 0.00555801531f, 0.00553527661f, 0.00551229948f, 0.00548908627f, 0.00546563789f, - 0.00544195622f, 0.00541804079f, 0.00539389299f, 0.00536951469f, 0.00534490682f, 0.00532006891f, 0.00529500330f, 0.00526971091f, 0.00524419360f, 0.00521845091f, - 0.00519248564f, 0.00516629778f, 0.00513988733f, 0.00511325756f, 0.00508640800f, 0.00505934190f, 0.00503205787f, 0.00500455871f, 0.00497684488f, 0.00494891871f, - 0.00492077926f, 0.00489242980f, 0.00486387173f, 0.00483510457f, 0.00480612973f, 0.00477694906f, 0.00474756444f, 0.00471797585f, 0.00468818471f, 0.00465819333f, - 0.00462800311f, 0.00459761359f, 0.00456702709f, 0.00453624595f, 0.00450526970f, 0.00447410066f, 0.00444273977f, 0.00441119028f, 0.00437944988f, 0.00434752181f, - 0.00431540795f, 0.00428310968f, 0.00425062748f, 0.00421796273f, 0.00418511871f, 0.00415209448f, 0.00411889143f, 0.00408551283f, 0.00405196007f, 0.00401823269f, - 0.00398433302f, 0.00395026430f, 0.00391602563f, 0.00388161885f, 0.00384704513f, 0.00381230796f, 0.00377740664f, 0.00374234305f, 0.00370711950f, 0.00367173809f, - 0.00363619835f, 0.00360050285f, 0.00356465275f, 0.00352865178f, 0.00349249784f, 0.00345619605f, 0.00341974595f, 0.00338314800f, 0.00334640522f, 0.00330951903f, - 0.00327249290f, 0.00323532452f, 0.00319801806f, 0.00316057424f, 0.00312299654f, 0.00308528380f, 0.00304743880f, 0.00300946319f, 0.00297135999f, 0.00293312967f, - 0.00289477245f, 0.00285629253f, 0.00281768874f, 0.00277896435f, 0.00274012075f, 0.00270116120f, 0.00266208476f, 0.00262289424f, 0.00258359103f, 0.00254417886f, - 0.00250465632f, 0.00246502645f, 0.00242529227f, 0.00238545449f, 0.00234551262f, 0.00230547064f, 0.00226533134f, 0.00222509331f, 0.00218476006f, 0.00214433344f, - 0.00210381625f, 0.00206320756f, 0.00202251016f, 0.00198172801f, 0.00194085937f, 0.00189990760f, 0.00185887585f, 0.00181776448f, 0.00177657383f, 0.00173530704f, - 0.00169396598f, 0.00165255368f, 0.00161106919f, 0.00156951568f, 0.00152789650f, 0.00148621027f, 0.00144446036f, 0.00140264863f, 0.00136077835f, 0.00131884834f, - 0.00127686316f, 0.00123482186f, 0.00119272911f, 0.00115058396f, 0.00110838923f, 0.00106614875f, 0.00102386111f, 0.000981529476f, 0.000939155812f, 0.000896743557f, - 0.000854291196f, 0.000811802340f, 0.000769278675f, 0.000726723636f, 0.000684137398f, 0.000641520426f, 0.000598877436f, 0.000556207204f, 0.000513513223f, 0.000470797240f, - 0.000428062631f, 0.000385308114f, 0.000342537096f, 0.000299751409f, 0.000256954430f, 0.000214144908f, 0.000171326188f, 0.000128500149f, 8.56717088e-05f, 4.28364874e-05f, - -5.72180747e-10f, -4.28360690e-05f, -8.56712868e-05f, -0.000128502856f, -0.000171328895f, -0.000214146057f, -0.000256955565f, -0.000299754087f, -0.000342539803f, -0.000385309249f, - -0.000428063737f, -0.000470799918f, -0.000513512816f, -0.000556206855f, -0.000598876970f, -0.000641521532f, -0.000684137049f, -0.000726724742f, -0.000769281352f, -0.000811805017f, - -0.000854292419f, -0.000896744605f, -0.000939158490f, -0.000981530524f, -0.00102386216f, -0.00106614991f, -0.00110839040f, -0.00115058350f, -0.00119272876f, -0.00123482291f, - -0.00127686432f, -0.00131884939f, -0.00136077951f, -0.00140265131f, -0.00144446141f, -0.00148621143f, -0.00152789755f, -0.00156951835f, -0.00161107024f, -0.00165255321f, - -0.00169396691f, -0.00173530797f, -0.00177657336f, -0.00181776413f, -0.00185887702f, -0.00189990853f, -0.00194086053f, -0.00198172918f, -0.00202251296f, -0.00206320873f, - -0.00210381718f, -0.00214433600f, -0.00218476262f, -0.00222509308f, -0.00226533087f, -0.00230547180f, -0.00234551216f, -0.00238545402f, -0.00242529344f, -0.00246502901f, - -0.00250465726f, -0.00254418002f, -0.00258359360f, -0.00262289657f, -0.00266208570f, -0.00270116236f, -0.00274012331f, -0.00277896388f, -0.00281768828f, -0.00285629206f, - -0.00289477338f, -0.00293312944f, -0.00297136139f, -0.00300946552f, -0.00304744113f, -0.00308528473f, -0.00312299770f, -0.00316057657f, -0.00319802039f, -0.00323532545f, - -0.00327249360f, -0.00330952019f, -0.00334640499f, -0.00338314800f, -0.00341974548f, -0.00345619721f, -0.00349249900f, -0.00352865248f, -0.00356465508f, -0.00360050471f, - -0.00363619928f, -0.00367173925f, -0.00370712159f, -0.00374234398f, -0.00377740758f, -0.00381230772f, -0.00384704629f, -0.00388161838f, -0.00391602563f, -0.00395026524f, - -0.00398433534f, -0.00401823409f, -0.00405196147f, -0.00408551469f, -0.00411889283f, -0.00415209495f, -0.00418511964f, -0.00421796506f, -0.00425062841f, -0.00428310968f, - -0.00431540888f, -0.00434752274f, -0.00437944988f, -0.00441119028f, -0.00444274163f, -0.00447410159f, -0.00450527063f, -0.00453624688f, -0.00456702895f, -0.00459761452f, - -0.00462800404f, -0.00465819519f, -0.00468818611f, -0.00471797585f, -0.00474756444f, -0.00477694953f, -0.00480612973f, -0.00483510410f, -0.00486387173f, -0.00489243167f, - -0.00492078019f, -0.00494891917f, -0.00497684628f, -0.00500456011f, -0.00503205974f, -0.00505934376f, -0.00508640893f, -0.00511325803f, -0.00513988826f, -0.00516629638f, - -0.00519248517f, -0.00521845184f, -0.00524419453f, -0.00526971230f, -0.00529500470f, -0.00532007031f, -0.00534490822f, -0.00536951516f, -0.00539389392f, -0.00541804126f, - -0.00544195529f, -0.00546563743f, -0.00548908627f, -0.00551229948f, -0.00553527614f, -0.00555801624f, -0.00558051793f, -0.00560278073f, -0.00562480185f, -0.00564658362f, - -0.00566812325f, -0.00568942074f, -0.00571047375f, -0.00573128276f, -0.00575184450f, -0.00577216130f, -0.00579223130f, -0.00581205264f, -0.00583162485f, -0.00585094653f, - -0.00587001862f, -0.00588883925f, -0.00590740610f, -0.00592572149f, -0.00594378309f, -0.00596158998f, -0.00597914122f, -0.00599643681f, -0.00601347489f, -0.00603025593f, - -0.00604677759f, -0.00606304081f, -0.00607904466f, -0.00609478820f, -0.00611027051f, -0.00612549065f, -0.00614044908f, -0.00615514303f, -0.00616957434f, -0.00618374161f, - -0.00619764347f, -0.00621128036f, -0.00622465089f, -0.00623775553f, -0.00625059241f, -0.00626316015f, -0.00627546106f, -0.00628749281f, -0.00629925542f, -0.00631074747f, - -0.00632197037f, -0.00633292180f, -0.00634360127f, -0.00635400973f, -0.00636414625f, -0.00637400988f, -0.00638360064f, -0.00639291806f, -0.00640196120f, -0.00641073007f, - -0.00641922466f, -0.00642744405f, -0.00643538870f, -0.00644305721f, -0.00645045005f, -0.00645756582f, -0.00646440592f, -0.00647096802f, -0.00647725351f, -0.00648326147f, - -0.00648899190f, -0.00649444433f, -0.00649961829f, -0.00650451379f, -0.00650913082f, -0.00651346892f, -0.00651752809f, -0.00652130833f, -0.00652480870f, -0.00652803015f, - -0.00653097173f, -0.00653363345f, -0.00653601484f, -0.00653811684f, -0.00653993897f, -0.00654148031f, -0.00654274225f, -0.00654372340f, -0.00654442422f, -0.00654484471f -}; -#endif const float Stereo_dmx_s_wnd_coef_16k[L_FRAME16k >> 4] = { 0.00154133327f, 0.0138150426f, 0.0380602330f, 0.0736799166f, 0.119797014f, 0.175276011f, 0.238750681f, 0.308658302f, 0.383277327f, 0.460770488f, diff --git a/lib_enc/ivas_rom_enc.h b/lib_enc/ivas_rom_enc.h index 2a4f71b8b9..8bcad95506 100644 --- a/lib_enc/ivas_rom_enc.h +++ b/lib_enc/ivas_rom_enc.h @@ -120,11 +120,6 @@ extern const uint16_t ECSQ_tab_vals[ECSQ_PARAM_COUNT - 1][1 + ECSQ_TAB_VALS_SIZE * Stereo downmix to EVS ROM tables *----------------------------------------------------------------------------------*/ -#ifndef NTT_REMOVE_EPS_ROM -extern const float Stereo_dmx_s_wnd_coef_eps_16k[L_FRAME16k * 3 / 4]; -extern const float Stereo_dmx_s_wnd_coef_eps_32k[L_FRAME32k * 3 / 4]; -extern const float Stereo_dmx_s_wnd_coef_eps_48k[L_FRAME48k * 3 / 4]; -#endif extern const float Stereo_dmx_s_wnd_coef_16k[L_FRAME16k >> 4]; extern const float Stereo_dmx_s_wnd_coef_32k[L_FRAME32k >> 4]; extern const float Stereo_dmx_s_wnd_coef_48k[L_FRAME48k >> 4]; diff --git a/lib_enc/ivas_sba_enc.c b/lib_enc/ivas_sba_enc.c index b267cd2e66..40b502fd70 100644 --- a/lib_enc/ivas_sba_enc.c +++ b/lib_enc/ivas_sba_enc.c @@ -45,10 +45,13 @@ #endif #include "wmops.h" +#ifndef HARMONIZE_SBA_NCHAN_TRANSPORT /*-----------------------------------------------------------------------* * Local function prototypes *-----------------------------------------------------------------------*/ + static void ivas_sba_dmx_enc( float sba_data[][L_FRAME48k], const int16_t nchan_transport, const int16_t input_frame ); +#endif /*-------------------------------------------------------------------* * ivas_sba_getTCs() @@ -62,18 +65,28 @@ void ivas_sba_getTCs( const int16_t input_frame /* i : frame length */ ) { -#ifndef SBA_ORDER_BITSTREAM - ivas_sba_zero_vert_comp( sba_data, st_ivas->hEncoderConfig->sba_order, st_ivas->hEncoderConfig->sba_planar, input_frame ); -#else ivas_sba_zero_vert_comp( sba_data, st_ivas->sba_analysis_order, st_ivas->hEncoderConfig->sba_planar, input_frame ); -#endif - if ( st_ivas->sba_mode == SBA_MODE_SPAR ) + +#ifdef HARMONIZE_SBA_NCHAN_TRANSPORT + st_ivas->nchan_transport = ivas_get_sba_num_TCs( st_ivas->hEncoderConfig->ivas_total_brate, st_ivas->sba_analysis_order ); + + if ( st_ivas->nchan_transport >= 3 ) { -#ifndef SBA_ORDER_BITSTREAM - st_ivas->nchan_transport = ivas_get_spar_num_TCs( st_ivas->hEncoderConfig->ivas_total_brate, st_ivas->hEncoderConfig->sba_order ); + /*convert WYZX downmix to WYXZ*/ + int16_t i = 0; + float temp; + for ( i = 0; i < input_frame; i++ ) + { + temp = sba_data[2][i]; + sba_data[2][i] = sba_data[3][i]; + sba_data[3][i] = temp; + } + } + #else + if ( st_ivas->sba_mode == SBA_MODE_SPAR ) + { st_ivas->nchan_transport = ivas_get_spar_num_TCs( st_ivas->hEncoderConfig->ivas_total_brate, st_ivas->sba_analysis_order ); -#endif if ( st_ivas->nchan_transport >= 3 ) { /*convert WYZX downmix to WYXZ*/ @@ -89,13 +102,14 @@ void ivas_sba_getTCs( } else { -#ifndef SBA_ORDER_BITSTREAM - st_ivas->nchan_transport = ivas_dirac_getNumTransportChannels( st_ivas->hEncoderConfig->ivas_total_brate, st_ivas->hEncoderConfig->sba_order, st_ivas->hEncoderConfig->sba_planar ); -#else st_ivas->nchan_transport = ivas_dirac_getNumTransportChannels( st_ivas->hEncoderConfig->ivas_total_brate, st_ivas->sba_analysis_order, st_ivas->hEncoderConfig->sba_planar ); -#endif +#ifdef HARMONIZE_SBA_NCHAN_TRANSPORT + /* do nothing; simply use omni */ +#else ivas_sba_dmx_enc( sba_data, st_ivas->nchan_transport, input_frame ); +#endif } +#endif #ifdef DEBUG_MODE_DIRAC for ( int16_t n = 0; n < st_ivas->nchan_transport; n++ ) @@ -116,6 +130,7 @@ void ivas_sba_getTCs( } +#ifndef HARMONIZE_SBA_NCHAN_TRANSPORT /*-------------------------------------------------------------------* * ivas_sba_dmx_enc() * @@ -214,7 +229,7 @@ static void ivas_sba_dmx_enc( return; } - +#endif /*-------------------------------------------------------------------* * ivas_sba_enc_reconfigure() @@ -249,6 +264,8 @@ ivas_error ivas_sba_enc_reconfigure( nSCE_old = st_ivas->nSCE; ind_list_metadata = NULL; + st_ivas->sba_analysis_order = ivas_sba_get_analysis_order( ivas_total_brate, st_ivas->hEncoderConfig->sba_order ); + ivas_dirac_enc_reconfigure( st_ivas ); ntransport = st_ivas->nchan_transport; diff --git a/lib_enc/ivas_sce_enc.c b/lib_enc/ivas_sce_enc.c index 942dd14c99..4a4c24fa4e 100644 --- a/lib_enc/ivas_sce_enc.c +++ b/lib_enc/ivas_sce_enc.c @@ -199,14 +199,20 @@ ivas_error ivas_sce_enc( * Reset metadata *----------------------------------------------------------------*/ - reset_metadata_spatial( ivas_format, hSCE->hMetaData, hSCE->element_brate, &st->total_brate, st->core_brate, nb_bits_metadata, st_ivas->sba_mode, - IVAS_SCE ); +#ifdef ALIGN_SID_SIZE + reset_metadata_spatial( ivas_format, hSCE->hMetaData, hSCE->element_brate, &st->total_brate, st->core_brate, nb_bits_metadata, st_ivas->sba_mode ); +#else + reset_metadata_spatial( ivas_format, hSCE->hMetaData, hSCE->element_brate, &st->total_brate, st->core_brate, nb_bits_metadata, st_ivas->sba_mode, IVAS_SCE ); +#endif /*----------------------------------------------------------------* * Write IVAS format signaling in SID frames *----------------------------------------------------------------*/ - +#ifdef ALIGN_SID_SIZE + if ( st->core_brate == SID_2k40 ) +#else if ( st->core_brate == SID_2k40 && ( ivas_format != SBA_FORMAT || st_ivas->sba_mode != SBA_MODE_SPAR ) ) +#endif { ivas_write_format_sid( ivas_format, IVAS_SCE, st->hBstr ); } @@ -232,13 +238,11 @@ ivas_error ivas_sce_enc( * Encoder *----------------------------------------------------------------*/ - if ( ( error = ivas_core_enc( hSCE, NULL, NULL, 1, old_inp_12k8, old_inp_16k, Etot, ener, A, Aw, epsP, lsp_new, lsp_mid, vad_hover_flag, attack_flag, realBuffer, imagBuffer, old_wsp, loc_harm, cor_map_sum, vad_flag_dtx, enerBuffer, fft_buff, 0, - flag_16k_smc ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_core_enc( hSCE, NULL, NULL, 1, old_inp_12k8, old_inp_16k, Etot, ener, A, Aw, epsP, lsp_new, lsp_mid, vad_hover_flag, attack_flag, realBuffer, imagBuffer, old_wsp, loc_harm, cor_map_sum, vad_flag_dtx, enerBuffer, fft_buff, 0, flag_16k_smc ) ) != IVAS_ERR_OK ) { return error; } - /*----------------------------------------------------------------* * Common updates *----------------------------------------------------------------*/ diff --git a/lib_enc/ivas_sns_enc.c b/lib_enc/ivas_sns_enc.c index 1aeac19c57..87019b8d91 100644 --- a/lib_enc/ivas_sns_enc.c +++ b/lib_enc/ivas_sns_enc.c @@ -43,7 +43,7 @@ #endif #include "wmops.h" -#ifndef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifndef MDCT_STEREO_PLC_FADE_2_BG_NOISE #define SNS_NPTS 16 /* Number of downsampled SNS parameters */ /*------------------------------------------------------------------- diff --git a/lib_enc/ivas_spar_encoder.c b/lib_enc/ivas_spar_encoder.c index 03e16833e3..14f9f08a54 100644 --- a/lib_enc/ivas_spar_encoder.c +++ b/lib_enc/ivas_spar_encoder.c @@ -79,26 +79,23 @@ ivas_error ivas_spar_enc_open( } input_Fs = hEncoderConfig->input_Fs; -#ifndef SBA_ORDER_BITSTREAM - sba_order_internal = min( hEncoderConfig->sba_order, IVAS_MAX_SBA_ORDER ); -#else sba_order_internal = min( st_ivas->sba_analysis_order, IVAS_MAX_SBA_ORDER ); -#endif nchan_inp = ivas_sba_get_nchan_metadata( sba_order_internal ); assert( nchan_inp <= hEncoderConfig->nchan_inp ); ivas_total_brate = hEncoderConfig->ivas_total_brate; + +#ifdef HARMONIZE_SBA_NCHAN_TRANSPORT + nchan_transport = ivas_get_sba_num_TCs( hEncoderConfig->ivas_total_brate, sba_order_internal ); +#else nchan_transport = ivas_get_spar_num_TCs( hEncoderConfig->ivas_total_brate, sba_order_internal ); +#endif // bw = ivas_get_bw_idx_from_sample_rate(pCfg->input_Fs); table_idx = ivas_get_spar_table_idx( ivas_total_brate, sba_order_internal, SPAR_CONFIG_BW, NULL, NULL ); // ivas_set_bitrate_config(&hSpar->hMdEnc->spar_md_cfg, table_idx); /* MD handle */ -#ifndef SBA_ORDER_BITSTREAM - if ( ( error = ivas_spar_md_enc_open( &( hSpar->hMdEnc ), hEncoderConfig ) ) != IVAS_ERR_OK ) -#else if ( ( error = ivas_spar_md_enc_open( &( hSpar->hMdEnc ), hEncoderConfig, sba_order_internal ) ) != IVAS_ERR_OK ) -#endif { return error; } @@ -149,13 +146,9 @@ ivas_error ivas_spar_enc_open( /*-----------------------------------------------------------------* * Configuration - set SPAR high-level parameters *-----------------------------------------------------------------*/ -#ifdef SBA_ORDER_BITSTREAM + ivas_spar_config( hEncoderConfig->ivas_total_brate, min( st_ivas->sba_analysis_order, IVAS_MAX_SBA_ORDER ), &st_ivas->nchan_transport, &st_ivas->nSCE, &st_ivas->nCPE, &hSpar->core_nominal_brate, -1 ); -#else - ivas_spar_config( hEncoderConfig->ivas_total_brate, min( hEncoderConfig->sba_order, IVAS_MAX_SBA_ORDER ), - &st_ivas->nchan_transport, &st_ivas->nSCE, &st_ivas->nCPE, &hSpar->core_nominal_brate, -1 ); -#endif if ( st_ivas->nchan_transport == 1 ) { @@ -290,7 +283,6 @@ ivas_error ivas_spar_enc( ) { ENCODER_CONFIG_HANDLE hEncoderConfig; - int16_t i, ch; ivas_error error; error = IVAS_ERR_OK; @@ -302,22 +294,9 @@ ivas_error ivas_spar_enc( return error; } - /* normalize input channels */ - for ( ch = 0; ch < hEncoderConfig->nchan_inp; ch++ ) - { - for ( i = 0; i < input_frame; i++ ) - { - data_f[ch][i] *= ( 1.0 / PCM16_TO_FLT_FAC ); - } - } - if ( hEncoderConfig->sba_planar ) { -#ifndef SBA_ORDER_BITSTREAM - ivas_sba_zero_vert_comp( data_f, hEncoderConfig->sba_order, hEncoderConfig->sba_planar, input_frame ); -#else ivas_sba_zero_vert_comp( data_f, st_ivas->sba_analysis_order, hEncoderConfig->sba_planar, input_frame ); -#endif } if ( ( error = ivas_spar_enc_process( st_ivas, hEncoderConfig, hMetaData, st_ivas->hSpar->front_vad_flag, data_f ) ) != IVAS_ERR_OK ) @@ -327,11 +306,7 @@ ivas_error ivas_spar_enc( if ( hEncoderConfig->sba_planar ) { -#ifndef SBA_ORDER_BITSTREAM - ivas_sba_zero_vert_comp( data_f, hEncoderConfig->sba_order, hEncoderConfig->sba_planar, input_frame ); // TODO tmu: do we need a second call to this function ? -#else ivas_sba_zero_vert_comp( data_f, st_ivas->sba_analysis_order, hEncoderConfig->sba_planar, input_frame ); // TODO tmu: do we need a second call to this function ? -#endif } *nb_bits_metadata = hMetaData->nb_bits_tot; @@ -457,11 +432,7 @@ static ivas_error ivas_spar_enc_process( num_del_samples = hSpar->hFbMixer->fb_cfg->fb_latency; input_frame = (int16_t) ( input_Fs / FRAMES_PER_SEC ); -#ifndef SBA_ORDER_BITSTREAM - sba_order = min( hEncoderConfig->sba_order, IVAS_MAX_SBA_ORDER ); -#else sba_order = min( st_ivas->sba_analysis_order, IVAS_MAX_SBA_ORDER ); -#endif nchan_inp = ivas_sba_get_nchan_metadata( sba_order ); assert( nchan_inp <= hEncoderConfig->nchan_inp ); @@ -561,7 +532,7 @@ static ivas_error ivas_spar_enc_process( set_zero( avg_dir, 3 ); energySum = 0.0f; - /*combine all dirac bands except the last one, handle last band separately, last band covers BW above WB*/ + /* combine all DirAC bands except the last one, handle last band separately, last band covers BW above WB */ for ( j = 0; j < orig_dirac_bands - 1; j++ ) { ivas_qmetadata_azimuth_elevation_to_direction_vector( hQMetaData->q_direction[0].band_data[j].azimuth[i], hQMetaData->q_direction[0].band_data[j].elevation[i], &dir[0] ); @@ -631,7 +602,7 @@ static ivas_error ivas_spar_enc_process( /* use just VAD function to get VAD flags */ dtx_vad = ( hEncoderConfig->Opt_DTX_ON == 1 ) ? front_vad_flag : 1; dtx_cov_flag = ( dtx_vad == 1 ) ? 0 : 1; - dtx_silence_mode = 0; + dtx_silence_mode = 0; // VE2DB: this variable is always 0 - please review or remove it bwidth = ivas_get_bw_idx_from_sample_rate( input_Fs ); bwidth = min( bwidth, hEncoderConfig->max_bwidth ); @@ -700,12 +671,9 @@ static ivas_error ivas_spar_enc_process( md_in_buf.num_bands = min( md_in_buf.num_bands, SPAR_DIRAC_SPLIT_START_BAND ); md_in_buf.dtx_vad = dtx_vad; -#ifndef SBA_ORDER_BITSTREAM - ivas_spar_md_enc_process( hSpar->hMdEnc, hEncoderConfig, &md_in_buf, hMetaData, dtx_silence_mode ); -#else ivas_spar_md_enc_process( hSpar->hMdEnc, hEncoderConfig, &md_in_buf, hMetaData, dtx_silence_mode, sba_order ); -#endif - if ( st_ivas->sba_mode == SBA_MODE_SPAR ) + + if ( st_ivas->sba_mode == SBA_MODE_SPAR ) // VE2DB: this looks obsolete { float azi_dirac[IVAS_MAX_NUM_BANDS][MAX_PARAM_SPATIAL_SUBFRAMES]; float ele_dirac[IVAS_MAX_NUM_BANDS][MAX_PARAM_SPATIAL_SUBFRAMES]; @@ -906,16 +874,13 @@ static ivas_error ivas_spar_enc_process( order = remix_order_set[hSpar->hMdEnc->spar_md_cfg.remix_unmix_order]; - for ( i = 0; i < input_frame; i++ ) + for ( j = 0; j < nchan_transport; j++ ) { - for ( j = 0; j < nchan_transport; j++ ) - { - data_f[order[j]][i] = p_pcm_tmp[j][i] * PCM16_TO_FLT_FAC; - } - for ( ; j < IVAS_SPAR_MAX_DMX_CHS; j++ ) - { - data_f[order[j]][i] = 0; - } + mvr2r( p_pcm_tmp[j], data_f[order[j]], input_frame ); + } + for ( ; j < IVAS_SPAR_MAX_DMX_CHS; j++ ) + { + set_f( data_f[order[j]], 0.0f, input_frame ); } wmops_sub_end(); diff --git a/lib_enc/ivas_spar_md_enc.c b/lib_enc/ivas_spar_md_enc.c index dc7c3677dd..ed0d3f7e7e 100644 --- a/lib_enc/ivas_spar_md_enc.c +++ b/lib_enc/ivas_spar_md_enc.c @@ -72,11 +72,11 @@ static void ivas_band_mixer( float *cov_re[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], static void ivas_get_band_differential_index( ivas_band_coeffs_ind_t *pBand_idx, const int16_t q_levels[2], const int16_t one_sided, const int16_t nB, const int16_t complex_cov, const int16_t dim, const ivas_coeffs_type_t coeff_type ); -static void ivas_get_huffman_coded_bs( ivas_spar_md_enc_state_t *pState, BSTR_ENC_HANDLE hMetaData, const int16_t nB, const int16_t qsi, const int16_t planarCP ); +static void ivas_get_huffman_coded_bs( ivas_spar_md_enc_state_t *hMdEnc, BSTR_ENC_HANDLE hMetaData, const int16_t nB, const int16_t qsi, const int16_t planarCP ); -static void ivas_get_arith_coded_bs( ivas_spar_md_enc_state_t *pState, BSTR_ENC_HANDLE hMetaData, const int16_t *pDo_diff, const int16_t bands_bw, const int16_t nB, const int16_t qsi, const int16_t planarCP ); +static void ivas_get_arith_coded_bs( ivas_spar_md_enc_state_t *hMdEnc, BSTR_ENC_HANDLE hMetaData, const int16_t *pDo_diff, const int16_t bands_bw, const int16_t nB, const int16_t qsi, const int16_t planarCP ); -static ivas_error ivas_spar_set_enc_config( ivas_spar_md_enc_state_t *pState, int16_t *max_freq_per_chan, const int16_t nchan_transport, float *pFC, const int16_t nchan_inp ); +static ivas_error ivas_spar_set_enc_config( ivas_spar_md_enc_state_t *hMdEnc, int16_t *max_freq_per_chan, const int16_t nchan_transport, float *pFC, const int16_t nchan_inp ); static void ivas_select_next_strat( ivas_strats_t prior_strat, ivas_strats_t cs[MAX_QUANT_STRATS], const int16_t dmx_switch, const int16_t dtx_vad ); @@ -84,17 +84,9 @@ static void ivas_store_prior_coeffs( ivas_spar_md_enc_state_t *hMdEnc, const int static void ivas_write_parameter_bitstream( ivas_spar_md_enc_state_t *hMdEnc, const int16_t nB, const int16_t bands_bw, BSTR_ENC_HANDLE hMetaData, const int32_t ivas_total_brate, const int16_t dtx_silence_mode, const int16_t strat, const int16_t qsi, const int16_t planarCP ); -static ivas_error ivas_spar_md_enc_init( ivas_spar_md_enc_state_t *pState, const ENCODER_CONFIG_HANDLE hEncoderConfig -#ifdef SBA_ORDER_BITSTREAM - , - int16_t sba_order -#endif -); - -static void ivas_spar_quant_pred_coeffs_dtx( ivas_spar_md_t *pSpar_md, float **ppValues, const int16_t ndm, int16_t **ppIndex, const int16_t dim1, float **ppQuant ); - -static void ivas_quant_p_per_band_dtx( float **ppP_mat, const int16_t num_dec, const int16_t num_dmx, int16_t *ppIdx_pd, float **ppP_out, const int16_t num_ch ); - +static ivas_error ivas_spar_md_enc_init( ivas_spar_md_enc_state_t *hMdEnc, const ENCODER_CONFIG_HANDLE hEncoderConfig, const int16_t sba_order ); +static void ivas_spar_quant_pred_coeffs_dtx( ivas_spar_md_t *pSpar_md, const float *pValues, const int16_t ndm, int16_t *pIndex, const int16_t dim1, float *pQuant ); +static void ivas_quant_p_per_band_dtx( float *pP_mat, const int16_t num_dec, const int16_t num_dmx, int16_t *ppIdx_pd, float *pP_out, const int16_t num_ch ); static void ivas_write_parameter_bitstream_dtx( ivas_spar_md_t *pSpar_md, BSTR_ENC_HANDLE hMetaData, int16_t *num_dmx, int16_t *num_dec, const int16_t num_bands ); static void ivas_quant_p_per_band( ivas_band_coeffs_t *pband_coeffs, ivas_band_coeffs_ind_t *pBand_coeffs_idx, ivas_quant_strat_t *pQs, const int16_t num_ch ); @@ -111,35 +103,24 @@ static void ivas_quant_pred_coeffs_per_band( ivas_band_coeffs_t *pband_coeffs, i *------------------------------------------------------------------------*/ ivas_error ivas_spar_md_enc_open( - ivas_spar_md_enc_state_t **hMdEnc_in, /* i/o: SPAR MD encoder handle */ - const ENCODER_CONFIG_HANDLE hEncoderConfig /* i : configuration structure */ -#ifdef SBA_ORDER_BITSTREAM - , - int16_t sba_order -#endif + ivas_spar_md_enc_state_t **hMdEnc_in, /* i/o: SPAR MD encoder handle */ + const ENCODER_CONFIG_HANDLE hEncoderConfig, /* i : configuration structure */ + const int16_t sba_order /* i : Ambisonic (SBA) order */ ) { ivas_spar_md_enc_state_t *hMdEnc; ivas_error error; -#ifndef SBA_ORDER_BITSTREAM - int16_t num_channels, i, j, order; -#else int16_t num_channels, i, j; -#endif -#ifndef SBA_ORDER_BITSTREAM - order = min( hEncoderConfig->sba_order, IVAS_MAX_SBA_ORDER ); -#endif + error = IVAS_ERR_OK; if ( ( hMdEnc = (ivas_spar_md_enc_state_t *) count_malloc( sizeof( ivas_spar_md_enc_state_t ) ) ) == NULL ) { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR MD encoder" ); } -#ifndef SBA_ORDER_BITSTREAM - num_channels = 2 * order + 2; -#else + num_channels = 2 * sba_order + 2; -#endif + if ( ( hMdEnc->spar_md.band_coeffs = (ivas_band_coeffs_t *) count_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" ); @@ -219,11 +200,8 @@ ivas_error ivas_spar_md_enc_open( } } } -#ifndef SBA_ORDER_BITSTREAM - if ( ( error = ivas_spar_md_enc_init( hMdEnc, hEncoderConfig ) ) != IVAS_ERR_OK ) -#else + if ( ( error = ivas_spar_md_enc_init( hMdEnc, hEncoderConfig, sba_order ) ) != IVAS_ERR_OK ) -#endif { return error; } @@ -323,34 +301,26 @@ void ivas_spar_md_enc_close( /*-----------------------------------------------------------------------------------------* * Function ivas_spar_md_enc_init() * - * Init call for md gen process + * SPAR MD encoder initialization *-----------------------------------------------------------------------------------------*/ static ivas_error ivas_spar_md_enc_init( - ivas_spar_md_enc_state_t *pState, /* o : MD encoder handle */ - const ENCODER_CONFIG_HANDLE hEncoderConfig /* i : configuration structure */ -#ifdef SBA_ORDER_BITSTREAM - , - int16_t sba_order -#endif + ivas_spar_md_enc_state_t *hMdEnc, /* o : MD encoder handle */ + const ENCODER_CONFIG_HANDLE hEncoderConfig, /* i : configuration structure */ + const int16_t sba_order /* i : Ambisonic (SBA) order */ ) { float pFC[IVAS_MAX_NUM_BANDS]; int16_t table_idx; float PR_minmax[2]; -#ifndef SBA_ORDER_BITSTREAM - int16_t sba_order; -#endif int16_t num_channels, i, j, k; -#ifndef SBA_ORDER_BITSTREAM - sba_order = min( hEncoderConfig->sba_order, IVAS_MAX_SBA_ORDER ); -#endif + num_channels = ivas_sba_get_nchan_metadata( sba_order ); table_idx = ivas_get_spar_table_idx( hEncoderConfig->ivas_total_brate, sba_order, SPAR_CONFIG_BW, NULL, NULL ); - pState->spar_md_cfg.gen_bs = 1; - ivas_spar_set_bitrate_config( &pState->spar_md_cfg, table_idx, SPAR_DIRAC_SPLIT_START_BAND ); + hMdEnc->spar_md_cfg.gen_bs = 1; + ivas_spar_set_bitrate_config( &hMdEnc->spar_md_cfg, table_idx, SPAR_DIRAC_SPLIT_START_BAND ); /* get FB coefficients */ for ( i = 0; i < IVAS_MAX_NUM_BANDS; i++ ) @@ -358,39 +328,39 @@ static ivas_error ivas_spar_md_enc_init( pFC[i] = ivas_fb_fcs_12band_1ms[i] * hEncoderConfig->input_Fs * 0.5f; } - ivas_spar_set_enc_config( pState, pState->spar_md_cfg.max_freq_per_chan, pState->spar_md_cfg.nchan_transport, pFC, num_channels ); + ivas_spar_set_enc_config( hMdEnc, hMdEnc->spar_md_cfg.max_freq_per_chan, hMdEnc->spar_md_cfg.nchan_transport, pFC, num_channels ); /* - if(pState->spar_md_cfg.quant_strat[0].C.q_levels[0] == 0 || pState->spar_md_cfg.quant_strat[0].C.q_levels[1] == 0 - || pState->spar_md_cfg.quant_strat[0].PR.q_levels[0] == 0 || pState->spar_md_cfg.quant_strat[0].PR.q_levels[1] == 0 - || pState->spar_md_cfg.quant_strat[0].P_c.q_levels[0] == 0 || pState->spar_md_cfg.quant_strat[0].P_c.q_levels[1] == 0 - || pState->spar_md_cfg.quant_strat[0].P_r.q_levels[0] == 0 || pState->spar_md_cfg.quant_strat[0].P_r.q_levels[1] == 0) + if(hMdEnc->spar_md_cfg.quant_strat[0].C.q_levels[0] == 0 || hMdEnc->spar_md_cfg.quant_strat[0].C.q_levels[1] == 0 + || hMdEnc->spar_md_cfg.quant_strat[0].PR.q_levels[0] == 0 || hMdEnc->spar_md_cfg.quant_strat[0].PR.q_levels[1] == 0 + || hMdEnc->spar_md_cfg.quant_strat[0].P_c.q_levels[0] == 0 || hMdEnc->spar_md_cfg.quant_strat[0].P_c.q_levels[1] == 0 + || hMdEnc->spar_md_cfg.quant_strat[0].P_r.q_levels[0] == 0 || hMdEnc->spar_md_cfg.quant_strat[0].P_r.q_levels[1] == 0) { - pState->spar_md_cfg.gen_bs = 0; + hMdEnc->spar_md_cfg.gen_bs = 0; } - else if(0 != pState->spar_md_cfg.gen_bs) + else if(0 != hMdEnc->spar_md_cfg.gen_bs) { - pState->spar_md_cfg.quant_strat_bits = ivas_get_bits_to_encode(MAX_QUANT_STRATS); + hMdEnc->spar_md_cfg.quant_strat_bits = ivas_get_bits_to_encode(MAX_QUANT_STRATS); } */ - if ( pState->spar_md_cfg.nchan_transport != 2 && ( ( pState->spar_md_cfg.remix_unmix_order == 1 ) || ( pState->spar_md_cfg.remix_unmix_order == 2 ) ) ) + if ( hMdEnc->spar_md_cfg.nchan_transport != 2 && ( ( hMdEnc->spar_md_cfg.remix_unmix_order == 1 ) || ( hMdEnc->spar_md_cfg.remix_unmix_order == 2 ) ) ) { return IVAS_ERR_INTERNAL; } - ivas_spar_arith_coeffs_com_init( &pState->arith_coeffs, &pState->spar_md_cfg, table_idx, ENC ); - ivas_spar_huff_coeffs_com_init( &pState->huff_coeffs, NULL, table_idx, ENC ); + ivas_spar_arith_coeffs_com_init( &hMdEnc->arith_coeffs, &hMdEnc->spar_md_cfg, table_idx, ENC ); + ivas_spar_huff_coeffs_com_init( &hMdEnc->huff_coeffs, NULL, table_idx, ENC ); if ( hEncoderConfig->Opt_DTX_ON == 1 ) { /* DTX quant init */ - PR_minmax[0] = pState->spar_md_cfg.quant_strat[0].PR.min; - PR_minmax[1] = pState->spar_md_cfg.quant_strat[0].PR.max; - ivas_spar_quant_dtx_init( &pState->spar_md, PR_minmax ); + PR_minmax[0] = hMdEnc->spar_md_cfg.quant_strat[0].PR.min; + PR_minmax[1] = hMdEnc->spar_md_cfg.quant_strat[0].PR.max; + ivas_spar_quant_dtx_init( &hMdEnc->spar_md, PR_minmax ); } - pState->spar_md_cfg.prior_strat = START; - pState->spar_md_cfg.prev_quant_idx = -1; + hMdEnc->spar_md_cfg.prior_strat = START; + hMdEnc->spar_md_cfg.prev_quant_idx = -1; for ( i = 0; i < num_channels; i++ ) { @@ -398,7 +368,7 @@ static ivas_error ivas_spar_md_enc_init( { for ( k = 0; k < IVAS_MAX_NUM_BANDS; k++ ) { - pState->mixer_mat[i][j][k] = 0; + hMdEnc->mixer_mat[i][j][k] = 0; } } } @@ -409,16 +379,16 @@ static ivas_error ivas_spar_md_enc_init( { for ( k = 0; k < IVAS_MAX_NUM_BANDS; k++ ) { - pState->cov_real[i][j][k] = 0; - pState->cov_dtx_real[i][j][k] = 0; + hMdEnc->cov_real[i][j][k] = 0; + hMdEnc->cov_dtx_real[i][j][k] = 0; } } } - ivas_clear_band_coeffs( pState->spar_md.band_coeffs, IVAS_MAX_NUM_BANDS ); - ivas_clear_band_coeff_idx( pState->spar_md.band_coeffs_idx, IVAS_MAX_NUM_BANDS ); - ivas_clear_band_coeff_idx( pState->spar_md_prior.band_coeffs_idx, IVAS_MAX_NUM_BANDS ); - ivas_clear_band_coeff_idx( pState->spar_md_prior.band_coeffs_idx_mapped, IVAS_MAX_NUM_BANDS ); + ivas_clear_band_coeffs( hMdEnc->spar_md.band_coeffs, IVAS_MAX_NUM_BANDS ); + ivas_clear_band_coeff_idx( hMdEnc->spar_md.band_coeffs_idx, IVAS_MAX_NUM_BANDS ); + ivas_clear_band_coeff_idx( hMdEnc->spar_md_prior.band_coeffs_idx, IVAS_MAX_NUM_BANDS ); + ivas_clear_band_coeff_idx( hMdEnc->spar_md_prior.band_coeffs_idx_mapped, IVAS_MAX_NUM_BANDS ); return IVAS_ERR_OK; } @@ -427,11 +397,11 @@ static ivas_error ivas_spar_md_enc_init( /*-----------------------------------------------------------------------------------------* * Function ivas_spar_set_enc_config() * - * Set configuration for SPAR MD gen + * Set configuration for SPAR MD encoder *-----------------------------------------------------------------------------------------*/ static ivas_error ivas_spar_set_enc_config( - ivas_spar_md_enc_state_t *pState, + ivas_spar_md_enc_state_t *hMdEnc, int16_t *max_freq_per_chan, const int16_t nchan_transport, float *pFC, @@ -444,29 +414,29 @@ static ivas_error ivas_spar_set_enc_config( { if ( max_freq_per_chan != NULL ) { - pState->spar_md_cfg.max_freq_per_chan[i] = ( max_freq_per_chan[i] != 0 ) ? max_freq_per_chan[i] : max_freq_per_chan[0]; + hMdEnc->spar_md_cfg.max_freq_per_chan[i] = ( max_freq_per_chan[i] != 0 ) ? max_freq_per_chan[i] : max_freq_per_chan[0]; } else { - pState->spar_md_cfg.max_freq_per_chan[i] = IVAS_SPAR_FOA_DFLT_FREQ_PER_CHAN; + hMdEnc->spar_md_cfg.max_freq_per_chan[i] = IVAS_SPAR_FOA_DFLT_FREQ_PER_CHAN; } } - pState->num_umx_ch = nchan_inp; - pState->num_decorr = nchan_inp - 1; + hMdEnc->num_umx_ch = nchan_inp; + hMdEnc->num_decorr = nchan_inp - 1; for ( i = 0; i < IVAS_MAX_NUM_BANDS; i++ ) { tmp_dmx_ch = 0; for ( j = 0; j < nchan_transport; j++ ) { - if ( pFC[i] < pState->spar_md_cfg.max_freq_per_chan[j] ) + if ( pFC[i] < hMdEnc->spar_md_cfg.max_freq_per_chan[j] ) { tmp_dmx_ch += 1; } } - pState->spar_md_cfg.num_dmx_chans_per_band[i] = tmp_dmx_ch; - pState->spar_md_cfg.num_decorr_per_band[i] = pState->num_umx_ch - tmp_dmx_ch; + hMdEnc->spar_md_cfg.num_dmx_chans_per_band[i] = tmp_dmx_ch; + hMdEnc->spar_md_cfg.num_decorr_per_band[i] = hMdEnc->num_umx_ch - tmp_dmx_ch; } return IVAS_ERR_OK; @@ -583,26 +553,19 @@ ivas_error ivas_spar_md_enc_process( ivas_spar_md_enc_state_t *hMdEnc, /* i/o: SPAR MD encoder handle */ const ENCODER_CONFIG_HANDLE hEncoderConfig, /* i : configuration structure */ ivas_spar_md_enc_in_buf_t *pIn_buf, - BSTR_ENC_HANDLE hMetaData, /* i/o: MetaData handle */ - const int16_t dtx_silence_mode -#ifdef SBA_ORDER_BITSTREAM - , - int16_t sba_order -#endif + BSTR_ENC_HANDLE hMetaData, /* i/o: MetaData handle */ + const int16_t dtx_silence_mode, + const int16_t sba_order /* i : Ambisonic (SBA) order */ ) { float pred_coeffs_re[IVAS_SPAR_MAX_CH - 1][IVAS_MAX_NUM_BANDS]; float dm_fv_re[IVAS_SPAR_MAX_CH - 1][IVAS_MAX_NUM_BANDS]; - int16_t i, b, qsi, ndm, ndec, num_ch; + int16_t i, b, qsi, ndm, ndec, num_ch, num_quant_strats; int16_t j, planarCP; int16_t num_bands = pIn_buf->num_bands; int16_t dtx_vad = pIn_buf->dtx_vad; -#ifndef SBA_ORDER_BITSTREAM - int16_t active_w, nchan_transport, dmx_switch, strat, sba_order; -#else int16_t active_w, nchan_transport, dmx_switch, strat; -#endif int16_t nB, bands_bw, packed_ok = 0; ivas_strats_t cs[MAX_CODING_STRATS]; int16_t code_strat; @@ -610,14 +573,11 @@ ivas_error ivas_spar_md_enc_process( BSTR_ENC_DATA hMetaData_tmp; Indice ind_list_tmp[MAX_BITS_METADATA]; // IVAS_fmToDo: size to be optimized float Wscale[IVAS_MAX_NUM_BANDS]; - ivas_spar_md_enc_state_t *pState = hMdEnc; - int16_t num_quant_strats = pState->spar_md_cfg.num_quant_strats; -#ifndef SBA_ORDER_BITSTREAM - sba_order = min( hEncoderConfig->sba_order, IVAS_MAX_SBA_ORDER ); -#endif + + num_quant_strats = hMdEnc->spar_md_cfg.num_quant_strats; num_ch = ivas_sba_get_nchan_metadata( sba_order ); - active_w = pState->spar_md_cfg.active_w; - nchan_transport = pState->spar_md_cfg.nchan_transport; + active_w = hMdEnc->spar_md_cfg.active_w; + nchan_transport = hMdEnc->spar_md_cfg.nchan_transport; if ( hEncoderConfig->ivas_total_brate == BRATE_SPAR_Q_STRAT && sba_order == 1 ) { @@ -652,8 +612,8 @@ ivas_error ivas_spar_md_enc_process( bands_bw = 1; } - ivas_compute_spar_params( pIn_buf->cov_real, dm_fv_re, 0, pState->mixer_mat, 0, nB, dtx_vad, num_ch, - bands_bw, active_w, &pState->spar_md_cfg, &pState->spar_md, Wscale, 0 ); + ivas_compute_spar_params( pIn_buf->cov_real, dm_fv_re, 0, hMdEnc->mixer_mat, 0, nB, dtx_vad, num_ch, + bands_bw, active_w, &hMdEnc->spar_md_cfg, &hMdEnc->spar_md, Wscale, 0 ); for ( i = 0; i < num_ch; i++ ) { @@ -661,7 +621,7 @@ ivas_error ivas_spar_md_enc_process( { for ( b = 0; b < num_bands; b++ ) { - hMdEnc->mixer_mat_local[i][j][b] = pState->mixer_mat[i][j][b]; + hMdEnc->mixer_mat_local[i][j][b] = hMdEnc->mixer_mat[i][j][b]; } } } @@ -680,7 +640,7 @@ ivas_error ivas_spar_md_enc_process( #ifdef SPAR_HOA_DBG fprintf( stdout, "qsi = %d\n", qsi ); #endif - if ( qsi == 2 && ivas_spar_br_table_consts[pState->table_idx].usePlanarCoeff ) + if ( qsi == 2 && ivas_spar_br_table_consts[hMdEnc->table_idx].usePlanarCoeff ) { planarCP = 1; #ifdef SPAR_HOA_DBG @@ -696,18 +656,18 @@ ivas_error ivas_spar_md_enc_process( { for ( b = 0; b < num_bands; b++ ) { - ndm = pState->spar_md_cfg.num_dmx_chans_per_band[b * bands_bw]; + ndm = hMdEnc->spar_md_cfg.num_dmx_chans_per_band[b * bands_bw]; if ( ndm != num_ch ) { - ivas_calc_c_p_coeffs( &pState->spar_md, pIn_buf->cov_real, 0, hMdEnc->mixer_mat_local, num_ch, ndm, b, dtx_vad, 1, planarCP ); + ivas_calc_c_p_coeffs( &hMdEnc->spar_md, pIn_buf->cov_real, 0, hMdEnc->mixer_mat_local, num_ch, ndm, b, dtx_vad, 1, planarCP ); } } } for ( b = 0; b < num_bands; b++ ) { - ndm = pState->spar_md_cfg.num_dmx_chans_per_band[b * bands_bw]; - ndec = pState->spar_md_cfg.num_decorr_per_band[b * bands_bw]; + ndm = hMdEnc->spar_md_cfg.num_dmx_chans_per_band[b * bands_bw]; + ndec = hMdEnc->spar_md_cfg.num_decorr_per_band[b * bands_bw]; if ( dtx_vad == 1 ) { @@ -718,11 +678,11 @@ ivas_error ivas_spar_md_enc_process( for (i = 0; i < ndec; i++) { - for (j = 0; j < ndec; j++) - { - fprintf(stderr, "%f, ", hMdEnc->spar_md.band_coeffs[b].P_re[i][j]);//, hMdEnc->spar_md.band_coeffs[b].P_im[i][j]); - } - fprintf(stderr, "\n"); + for (j = 0; j < ndec; j++) + { + fprintf(stderr, "%f, ", hMdEnc->spar_md.band_coeffs[b].P_re[i][j]);//, hMdEnc->spar_md.band_coeffs[b].P_im[i][j]); + } + fprintf(stderr, "\n"); } fprintf(stderr, "\n\n"); */ #endif @@ -741,56 +701,33 @@ ivas_error ivas_spar_md_enc_process( /*fprintf(stderr, "\n\n Planar P coefficients: band %d\n", b); for (i = 0; i < ndec; i++) { - for (j = 0; j < ndec; j++) - { - fprintf(stderr, "%f, ", hMdEnc->spar_md.band_coeffs[b].P_re[i][j]); //, hMdEnc->spar_md.band_coeffs[b].C_im[i][j]); - } - fprintf(stderr, "\n"); + for (j = 0; j < ndec; j++) + { + fprintf(stderr, "%f, ", hMdEnc->spar_md.band_coeffs[b].P_re[i][j]); //, hMdEnc->spar_md.band_coeffs[b].C_im[i][j]); + } + fprintf(stderr, "\n"); } fprintf(stderr, "\n\n"); */ #endif } - ivas_quant_p_per_band( &pState->spar_md.band_coeffs[b], &pState->spar_md.band_coeffs_idx[b], &pState->spar_md_cfg.quant_strat[qsi], num_ch ); + ivas_quant_p_per_band( &hMdEnc->spar_md.band_coeffs[b], &hMdEnc->spar_md.band_coeffs_idx[b], &hMdEnc->spar_md_cfg.quant_strat[qsi], num_ch ); } - ivas_quant_pred_coeffs_per_band( &pState->spar_md.band_coeffs[b], &pState->spar_md.band_coeffs_idx[b], &pState->spar_md_cfg.quant_strat[qsi], num_ch ); + ivas_quant_pred_coeffs_per_band( &hMdEnc->spar_md.band_coeffs[b], &hMdEnc->spar_md.band_coeffs_idx[b], &hMdEnc->spar_md_cfg.quant_strat[qsi], num_ch ); } else { - float **ppPred_re, **ppPred_quant, *pPred_re, *pPred_quant; - int16_t **ppPred_idx, *pPred_re_idx; if ( ndm != num_ch ) { - float *P_re[IVAS_SPAR_MAX_CH - 1], *P_re_quant[IVAS_SPAR_MAX_CH - 1]; - float **ppP_re = (float **) &P_re[0]; - float **ppP_re_quant = (float **) &P_re_quant[0]; - int16_t *ppP_idx = &pState->spar_md.band_coeffs_idx[b].decd_index_re[0]; - - for ( i = 0; i < ndec; i++ ) - { - ppP_re[i] = pState->spar_md.band_coeffs[b].P_re; - ppP_re_quant[i] = pState->spar_md.band_coeffs[b].P_quant_re; - } - - ivas_quant_p_per_band_dtx( ppP_re, ndec, ndm, ppP_idx, ppP_re_quant, num_ch ); + ivas_quant_p_per_band_dtx( hMdEnc->spar_md.band_coeffs[b].P_re, ndec, ndm, &hMdEnc->spar_md.band_coeffs_idx[b].decd_index_re[0], hMdEnc->spar_md.band_coeffs[b].P_quant_re, num_ch ); } - - ppPred_idx = (int16_t **) &pPred_re_idx; - ppPred_re = (float **) &pPred_re; - ppPred_quant = (float **) &pPred_quant; - - ppPred_re[0] = pState->spar_md.band_coeffs[b].pred_re; - ppPred_idx[0] = pState->spar_md.band_coeffs_idx[b].pred_index_re; - ppPred_quant[0] = pState->spar_md.band_coeffs[b].pred_quant_re; - for ( i = 0; i < num_ch - 1; i++ ) { - pState->spar_md.band_coeffs[b].pred_quant_re[i] = 0; + hMdEnc->spar_md.band_coeffs[b].pred_quant_re[i] = 0; } - - ivas_spar_quant_pred_coeffs_dtx( &pState->spar_md, ppPred_re, ndm, ppPred_idx, num_ch - 1, ppPred_quant ); + ivas_spar_quant_pred_coeffs_dtx( &hMdEnc->spar_md, hMdEnc->spar_md.band_coeffs[b].pred_re, ndm, hMdEnc->spar_md.band_coeffs_idx[b].pred_index_re, num_ch - 1, hMdEnc->spar_md.band_coeffs[b].pred_quant_re ); } } @@ -798,35 +735,35 @@ ivas_error ivas_spar_md_enc_process( { for ( b = 0; b < num_bands; b++ ) { - pred_coeffs_re[i][b] = Wscale[b] * pState->spar_md.band_coeffs[b].pred_quant_re[i]; + pred_coeffs_re[i][b] = Wscale[b] * hMdEnc->spar_md.band_coeffs[b].pred_quant_re[i]; } } - ivas_create_fullr_dmx_mat( pred_coeffs_re, dm_fv_re, pState->mixer_mat, num_ch, 0, num_bands, active_w, &pState->spar_md_cfg ); + ivas_create_fullr_dmx_mat( pred_coeffs_re, dm_fv_re, hMdEnc->mixer_mat, num_ch, 0, num_bands, active_w, &hMdEnc->spar_md_cfg ); for ( b = 0; b < num_bands; b++ ) { - ndm = pState->spar_md_cfg.num_dmx_chans_per_band[b * bands_bw]; - ndec = pState->spar_md_cfg.num_decorr_per_band[b * bands_bw]; + ndm = hMdEnc->spar_md_cfg.num_dmx_chans_per_band[b * bands_bw]; + ndec = hMdEnc->spar_md_cfg.num_decorr_per_band[b * bands_bw]; for ( i = 0; i < num_ch; i++ ) { - pState->mixer_mat[0][i][b] *= Wscale[b]; + hMdEnc->mixer_mat[0][i][b] *= Wscale[b]; } if ( ( ndm != num_ch ) && ( ndm != 1 ) ) { - ivas_calc_c_p_coeffs( &pState->spar_md, pIn_buf->cov_real, 0, pState->mixer_mat, num_ch, ndm, b, dtx_vad, 0, planarCP ); + ivas_calc_c_p_coeffs( &hMdEnc->spar_md, pIn_buf->cov_real, 0, hMdEnc->mixer_mat, num_ch, ndm, b, dtx_vad, 0, planarCP ); #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, ", pState->spar_md.band_coeffs[b].C_re[i][j]); - } - fprintf(stderr, "\n"); + 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 @@ -838,7 +775,7 @@ ivas_error ivas_spar_md_enc_process( { for ( j = 0; j < ndm - 1; j++ ) { - pState->spar_md.band_coeffs[b].C_re[i][j] = 0.0f; + hMdEnc->spar_md.band_coeffs[b].C_re[i][j] = 0.0f; } } } @@ -847,24 +784,24 @@ ivas_error ivas_spar_md_enc_process( for (i = 0; i < num_ch - ndm; i++) { - for (j = 0; j < ndm - 1; j++) - { - fprintf(stderr, "%f, ", pState->spar_md.band_coeffs[b].C_re[i][j]); // , pState->spar_md.band_coeffs[band_idx].C_im[i][j]); - } - fprintf(stderr, "\n"); + for (j = 0; j < ndm - 1; j++) + { + fprintf(stderr, "%f, ", hMdEnc->spar_md.band_coeffs[b].C_re[i][j]); // , hMdEnc->spar_md.band_coeffs[band_idx].C_im[i][j]); + } + fprintf(stderr, "\n"); } fprintf(stderr, "\n\n"); */ #endif } - ivas_quant_c_per_band( &pState->spar_md.band_coeffs[b], &pState->spar_md.band_coeffs_idx[b], - &pState->spar_md_cfg.quant_strat[qsi], ndec, ndm ); + 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 ); #ifdef SPAR_HOA_DBG /*fprintf(stderr, "\n\n quantised C indexes: band %d\n", b); for (i = 0; i < ndec * (ndm-1); i++) { - fprintf(stderr, "%d, ", pState->spar_md.band_coeffs_idx[b].drct_index_re[i]); + fprintf(stderr, "%d, ", hMdEnc->spar_md.band_coeffs_idx[b].drct_index_re[i]); } fprintf(stderr, "\n\n");*/ #endif @@ -872,26 +809,26 @@ ivas_error ivas_spar_md_enc_process( } /* band limit downmix matrix */ - ivas_band_limit_dmx_matrix( pState, num_ch, num_bands, bands_bw ); + ivas_band_limit_dmx_matrix( hMdEnc, num_ch, num_bands, bands_bw ); /* band mixing */ if ( bands_bw > 1 ) { - ivas_band_mixing( pState, num_ch, num_bands, nchan_transport, pIn_buf->num_bands ); + ivas_band_mixing( hMdEnc, num_ch, num_bands, nchan_transport, pIn_buf->num_bands ); } - if ( pState->spar_md_cfg.gen_bs == 0 ) + if ( hMdEnc->spar_md_cfg.gen_bs == 0 ) { break; } if ( dtx_vad == 0 ) { - ivas_write_parameter_bitstream_dtx( &pState->spar_md, hMetaData, pState->spar_md_cfg.num_dmx_chans_per_band, pState->spar_md_cfg.num_decorr_per_band, num_bands ); + ivas_write_parameter_bitstream_dtx( &hMdEnc->spar_md, hMetaData, hMdEnc->spar_md_cfg.num_dmx_chans_per_band, hMdEnc->spar_md_cfg.num_decorr_per_band, num_bands ); break; } - ivas_select_next_strat( pState->spar_md_cfg.prior_strat, cs, dmx_switch, dtx_vad ); + ivas_select_next_strat( hMdEnc->spar_md_cfg.prior_strat, cs, dmx_switch, dtx_vad ); for ( i = 0; i < MAX_CODING_STRATS; i++ ) { @@ -900,13 +837,13 @@ ivas_error ivas_spar_md_enc_process( { reset_indices_enc( &hMetaData_tmp, MAX_BITS_METADATA ); - ivas_write_parameter_bitstream( pState, num_bands, bands_bw, &hMetaData_tmp, hEncoderConfig->ivas_total_brate, dtx_silence_mode, strat, qsi, planarCP ); + ivas_write_parameter_bitstream( hMdEnc, num_bands, bands_bw, &hMetaData_tmp, hEncoderConfig->ivas_total_brate, dtx_silence_mode, strat, qsi, planarCP ); if ( hMetaData->nb_bits_tot == bit_pos_start || hMetaData_tmp.nb_bits_tot < ( hMetaData->nb_bits_tot - bit_pos_start ) ) { write_metadata_buffer( &hMetaData_tmp, hMetaData, bit_pos_start, next_ind_start, last_ind_start ); code_strat = strat; } - if ( hMetaData->nb_bits_tot - bit_pos_start + ( ( ( hEncoderConfig->ivas_total_brate == IVAS_256k ) && ( sba_order == 1 ) ) ? 1 : 0 ) <= pState->spar_md_cfg.tgt_bits_per_blk ) + if ( hMetaData->nb_bits_tot - bit_pos_start + ( ( ( hEncoderConfig->ivas_total_brate == IVAS_256k ) && ( sba_order == 1 ) ) ? 1 : 0 ) <= hMdEnc->spar_md_cfg.tgt_bits_per_blk ) { packed_ok = 1; break; @@ -919,7 +856,7 @@ ivas_error ivas_spar_md_enc_process( break; } - if ( hMetaData->nb_bits_tot - bit_pos_start + ( ( ( hEncoderConfig->ivas_total_brate == IVAS_256k ) && ( sba_order == 1 ) ) ? 1 : 0 ) <= pState->spar_md_cfg.max_bits_per_blk ) + if ( hMetaData->nb_bits_tot - bit_pos_start + ( ( ( hEncoderConfig->ivas_total_brate == IVAS_256k ) && ( sba_order == 1 ) ) ? 1 : 0 ) <= hMdEnc->spar_md_cfg.max_bits_per_blk ) { break; } @@ -932,48 +869,48 @@ ivas_error ivas_spar_md_enc_process( #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, //pState->spar_md.band_coeffs[b].pred_re[i], - pState->spar_md.band_coeffs[b].pred_quant_re[i], - pState->spar_md_prior.band_coeffs_idx[b].pred_index_re[i], - pState->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, // pState->spar_md.band_coeffs[b].C_re[i][j], - pState->spar_md.band_coeffs[b].C_quant_re[i][j], - pState->spar_md_prior.band_coeffs_idx[b].drct_index_re[k], - pState->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++ ) + for ( b = 0; b < nB; b++ ) { - fprintf( stdout, "i: %d -- %f\t %d\t %d\n", i, //pState->spar_md.band_coeffs[b].P_re[i][i], - pState->spar_md.band_coeffs[b].P_quant_re[i][i], - pState->spar_md_prior.band_coeffs_idx[b].decd_index_re[i], - pState->spar_md.band_coeffs_idx[b].decd_index_re[i] ); + 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" ); } - fprintf( stdout, "\n\n" ); - } }*/ b = 0; - ndm = pState->spar_md_cfg.num_dmx_chans_per_band[b * bands_bw]; + 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, pState->spar_md.band_coeffs[b].pred_quant_re[i] ); + fprintf( stdout, "i: %d -- %.2f\t|\t", i, hMdEnc->spar_md.band_coeffs[b].pred_quant_re[i] ); if ( i < num_ch - ndm ) { if ( keep_planar[i] == 1 ) @@ -986,12 +923,12 @@ ivas_error ivas_spar_md_enc_process( } for ( j = 0; j < ndm - 1; j++ ) { - fprintf( stdout, "%.2f\t", pState->spar_md.band_coeffs[b].C_quant_re[i][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", pState->spar_md.band_coeffs[b].P_quant_re[j] ); + fprintf( stdout, "%.2f\t", hMdEnc->spar_md.band_coeffs[b].P_quant_re[j] ); } } fprintf( stdout, "\n" ); @@ -1028,7 +965,7 @@ ivas_error ivas_spar_md_enc_process( ( b == 0 && frame == 0 ) ? dbgwrite( &byte_size, sizeof( byte_size ), 1, 1, f_name ) : false; for ( i = 0; i < num_ch - 1; i++ ) { - dbgwrite( &pState->spar_md.band_coeffs[b].pred_re[i], sizeof( float ), 1, 1, f_name ); + 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; @@ -1041,7 +978,7 @@ ivas_error ivas_spar_md_enc_process( { for ( j = 0; j < ( ndm - 1 ); j++ ) { - dbgwrite( &pState->spar_md.band_coeffs[b].C_re[i][j], sizeof( float ), 1, 1, f_name ); + 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" ); @@ -1053,7 +990,7 @@ ivas_error ivas_spar_md_enc_process( ( b == 0 && frame == 0 ) ? dbgwrite( &byte_size, sizeof( byte_size ), 1, 1, f_name ) : false; for ( i = 0; i < num_ch - ndm; i++ ) { - dbgwrite( &pState->spar_md.band_coeffs[b].P_re[i], sizeof( float ), 1, 1, f_name ); + 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; @@ -1064,7 +1001,7 @@ ivas_error ivas_spar_md_enc_process( ( b == 0 && frame == 0 ) ? dbgwrite( &byte_size, sizeof( byte_size ), 1, 1, f_name ) : false; for ( i = 0; i < num_ch - 1; i++ ) { - dbgwrite( &pState->spar_md.band_coeffs[b].pred_quant_re[i], sizeof( float ), 1, 1, f_name ); + 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; @@ -1077,7 +1014,7 @@ ivas_error ivas_spar_md_enc_process( { for ( j = 0; j < ( ndm - 1 ); j++ ) { - dbgwrite( &pState->spar_md.band_coeffs[b].C_quant_re[i][j], sizeof( float ), 1, 1, f_name ); + 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" ); @@ -1089,7 +1026,7 @@ ivas_error ivas_spar_md_enc_process( ( b == 0 && frame == 0 ) ? dbgwrite( &byte_size, sizeof( byte_size ), 1, 1, f_name ) : false; for ( i = 0; i < num_ch - ndm; i++ ) { - dbgwrite( &pState->spar_md.band_coeffs[b].P_quant_re[i], sizeof( float ), 1, 1, f_name ); + dbgwrite( &hMdEnc->spar_md.band_coeffs[b].P_quant_re[i], sizeof( float ), 1, 1, f_name ); } } } @@ -1102,13 +1039,13 @@ ivas_error ivas_spar_md_enc_process( fclose( fp ); #endif - if ( pState->spar_md_cfg.gen_bs == 1 ) + if ( hMdEnc->spar_md_cfg.gen_bs == 1 ) { - ivas_store_prior_coeffs( pState, num_bands, bands_bw, code_strat, dtx_vad, qsi ); + ivas_store_prior_coeffs( hMdEnc, num_bands, bands_bw, code_strat, dtx_vad, qsi ); } - pState->spar_md.dtx_vad = dtx_vad; - pState->spar_md.num_bands = num_bands; + hMdEnc->spar_md.dtx_vad = dtx_vad; + hMdEnc->spar_md.num_bands = num_bands; return IVAS_ERR_OK; } @@ -1402,7 +1339,7 @@ static void ivas_get_arith_coded_bs( #ifdef SPAR_HOA_DBG /*fprintf(stderr, "\n\n band_indexes:\n"); for (int16_t j = 1; j < drct_cell_dims[0].dim1 * drct_cell_dims[0].dim2; j++) - fprintf(stderr, "%d, ", hMdEnc->spar_md.band_coeffs_idx[0].drct_index_re[j]); + fprintf(stderr, "%d, ", hMdEnc->spar_md.band_coeffs_idx[0].drct_index_re[j]); fprintf(stderr, "\n\n"); */ #endif ivas_copy_band_coeffs_idx_to_arr( hMdEnc->spar_md.band_coeffs_idx, nB, symbol_arr_re, drct_cell_dims, DRCT_COEFF, planarCP ); @@ -1562,37 +1499,22 @@ static void ivas_store_prior_coeffs( static void ivas_spar_quant_pred_coeffs_dtx( ivas_spar_md_t *pSpar_md, - float **ppValues, + const float *pValues, const int16_t ndm, - int16_t **ppIndex, + int16_t *pIndex, const int16_t dim1, - float **ppQuant ) + float *pQuant ) { int16_t i; int16_t q_lvl; - float *pVal, val, **ppVal; - int16_t *pIdx, idx, **ppIdx; float pr_min_max[2]; - - ppVal = (float **) &pVal; - ppIdx = (int16_t **) &pIdx; - - ppVal[0] = (float *) &val; - ppIdx[0] = (int16_t *) &idx; - pr_min_max[0] = pSpar_md->min_max[0]; pr_min_max[1] = pSpar_md->min_max[1]; - for ( i = 0; i < dim1; i++ ) { q_lvl = dtx_pr_real_q_levels[ndm - 1][i]; - ppVal[0][0] = ppValues[0][i]; - - ivas_quantise_real_values( ppVal, q_lvl, pr_min_max[0], pr_min_max[1], ppIdx, ppVal, 1, 1 ); - ppIndex[0][i] = ppIdx[0][0]; - ppQuant[0][i] = ppVal[0][0]; + ivas_quantise_real_values( &pValues[i], q_lvl, pr_min_max[0], pr_min_max[1], &pIndex[i], &pQuant[i], 1 ); } - return; } @@ -1604,30 +1526,22 @@ static void ivas_spar_quant_pred_coeffs_dtx( *-----------------------------------------------------------------------------------------*/ static void ivas_quant_p_per_band_dtx( - float **ppP_mat, + float *pP_mat, const int16_t num_dec, const int16_t num_dmx, int16_t *ppIdx_pd, - float **ppP_out, + float *pP_out, const int16_t num_ch ) { int16_t i; - float **ppPd, *pPd, pd; - int16_t **ppIdx, *pIdx, idx; int16_t dim = num_ch - num_dmx; - - ppPd = (float **) &pPd; - ppIdx = (int16_t **) &pIdx; - ppPd[0] = (float *) &pd; - ppIdx[0] = (int16_t *) &idx; - if ( num_dec == num_ch - 1 ) { for ( i = 0; i < dim; i++ ) { - if ( ppP_mat[i][i] < pr_boost_range[1] && ppP_mat[i][i] > pr_boost_range[0] ) + if ( pP_mat[i] < pr_boost_range[1] && pP_mat[i] > pr_boost_range[0] ) { - ppP_mat[i][i] = pr_boost_range[1]; + pP_mat[i] = pr_boost_range[1]; } } } @@ -1636,21 +1550,13 @@ static void ivas_quant_p_per_band_dtx( { assert( !"Not Supported!" ); } - for ( i = 0; i < dim; i++ ) { - ppPd[0][0] = ppP_mat[i][i]; - - ivas_quantise_real_values( ppPd, dtx_pd_real_q_levels[num_ch - num_dec - 1][i], dtx_pd_real_min_max[0], dtx_pd_real_min_max[1], ppIdx, ppPd, 1, 1 ); - - ppP_out[i][i] = ppPd[0][0]; - ppIdx_pd[i] = ppIdx[0][0]; + ivas_quantise_real_values( &pP_mat[i], dtx_pd_real_q_levels[num_ch - num_dec - 1][i], dtx_pd_real_min_max[0], dtx_pd_real_min_max[1], &ppIdx_pd[i], &pP_out[i], 1 ); } - return; } - /*-----------------------------------------------------------------------------------------* * Function ivas_write_parameter_bitstream_dtx() * @@ -1665,18 +1571,11 @@ static void ivas_write_parameter_bitstream_dtx( const int16_t num_bands ) { int16_t i, j; - float **ppVal, *pVal, val; - int16_t **ppIdx, *pIdx, idx; + float val; + int16_t idx; float pr_min_max[2]; int16_t zero_pad_bits, sid_bits_len; sid_bits_len = hMetaData->nb_bits_tot; - - ppVal = (float **) &pVal; - ppIdx = (int16_t **) &pIdx; - - ppVal[0] = (float *) &val; - ppIdx[0] = (int16_t *) &idx; - pr_min_max[0] = pSpar_md->min_max[0]; pr_min_max[1] = pSpar_md->min_max[1]; @@ -1714,17 +1613,15 @@ static void ivas_write_parameter_bitstream_dtx( pd_q_lvls = dtx_pd_real_q_levels[ndm - 1][pd_idx_2 - 1]; pd = pSpar_md->band_coeffs_idx[i].decd_index_re[pd_idx_2 - 1]; } + val = dtx_pd_real_min_max[0]; + ivas_quantise_real_values( &val, pd_q_lvls, dtx_pd_real_min_max[0], dtx_pd_real_min_max[1], &idx, &val, 1 ); - ppVal[0][0] = dtx_pd_real_min_max[0]; - ivas_quantise_real_values( ppVal, pd_q_lvls, dtx_pd_real_min_max[0], dtx_pd_real_min_max[1], ppIdx, ppVal, 1, 1 ); - - pd -= ppIdx[0][0]; + pd -= idx; - ppVal[0][0] = pr_min_max[0]; - ivas_quantise_real_values( ppVal, pr_q_lvls, pr_min_max[0], pr_min_max[1], ppIdx, ppVal, 1, 1 ); - - pr -= ppIdx[0][0]; + val = pr_min_max[0]; + ivas_quantise_real_values( &val, pr_q_lvls, pr_min_max[0], pr_min_max[1], &idx, &val, 1 ); + pr -= idx; pr_pd_bits = ivas_get_bits_to_encode( pd_q_lvls * pr_q_lvls ); value = (uint16_t) ( pr * pd_q_lvls + pd ); @@ -1737,21 +1634,19 @@ static void ivas_write_parameter_bitstream_dtx( int16_t pr_idx1, pr_idx2, pr_pr_bits; pr_q_lvls1 = dtx_pr_real_q_levels[ndm - 1][pr_idx_1 - 1]; pr_q_lvls2 = dtx_pr_real_q_levels[ndm - 1][pr_idx_2 - 1]; - - ppVal[0][0] = pr_min_max[0]; - ivas_quantise_real_values( ppVal, pr_q_lvls1, pr_min_max[0], pr_min_max[1], ppIdx, ppVal, 1, 1 ); + val = pr_min_max[0]; + ivas_quantise_real_values( &val, pr_q_lvls1, pr_min_max[0], pr_min_max[1], &idx, &val, 1 ); pr_idx1 = pSpar_md->band_coeffs_idx[i].pred_index_re[pr_idx_1 - 1]; - pr_idx1 -= ppIdx[0][0]; + pr_idx1 -= idx; - ppVal[0][0] = pr_min_max[0]; - ivas_quantise_real_values( ppVal, pr_q_lvls2, pr_min_max[0], pr_min_max[1], ppIdx, ppVal, 1, 1 ); + val = pr_min_max[0]; + ivas_quantise_real_values( &val, pr_q_lvls2, pr_min_max[0], pr_min_max[1], &idx, &val, 1 ); pr_idx2 = pSpar_md->band_coeffs_idx[i].pred_index_re[pr_idx_2 - 1]; - pr_idx2 -= ppIdx[0][0]; - + pr_idx2 -= idx; value = (uint16_t) ( pr_idx2 * pr_q_lvls1 + pr_idx1 ); pr_pr_bits = ivas_get_bits_to_encode( pr_q_lvls1 * pr_q_lvls2 ); @@ -1788,18 +1683,7 @@ static void ivas_quant_pred_coeffs_per_band( ivas_quant_strat_t *pQs, const int16_t num_ch ) { - float *pQuant_re, *pCoeff_re; - int16_t *pIdx_re; - float **ppPred_coeffs_re = (float **) &pCoeff_re; - float **ppPred_quant_re = (float **) &pQuant_re; - int16_t **ppPred_idx_re = (int16_t **) &pIdx_re; - - ppPred_idx_re[0] = &pBand_coeffs_idx->pred_index_re[0]; - ppPred_coeffs_re[0] = &pband_coeffs->pred_re[0]; - ppPred_quant_re[0] = &pband_coeffs->pred_quant_re[0]; - - ivas_quantise_real_values( ppPred_coeffs_re, pQs->PR.q_levels[0], pQs->PR.min, pQs->PR.max, ppPred_idx_re, ppPred_quant_re, 1, ( num_ch - 1 ) ); - + ivas_quantise_real_values( pband_coeffs->pred_re, pQs->PR.q_levels[0], pQs->PR.min, pQs->PR.max, pBand_coeffs_idx->pred_index_re, pband_coeffs->pred_quant_re, ( num_ch - 1 ) ); return; } @@ -1820,17 +1704,6 @@ static void ivas_quant_c_per_band( int16_t i; int16_t j, k; float C_re[IVAS_SPAR_MAX_C_COEFF]; - float *pC_re[IVAS_SPAR_MAX_C_COEFF]; - int16_t *pIdx_re[IVAS_SPAR_MAX_C_COEFF]; - float **ppC_re = (float **) &pC_re[0]; - int16_t **ppIdx_re = (int16_t **) &pIdx_re[0]; - - for ( i = 0; i < ndec * ( ndm - 1 ); i++ ) - { - ppC_re[i] = &C_re[i]; - ppIdx_re[i] = &pBand_coeffs_idx->drct_index_re[i]; - } - k = 0; for ( i = 0; i < ndec; i++ ) { @@ -1840,19 +1713,16 @@ static void ivas_quant_c_per_band( k++; } } - #ifdef SPAR_HOA_DBG /*for (i = 0; i < ndec; i++) { - for (j = 0; j < ndm - 1; j++) - { - ppIdx_re[i][j] = 100; - } + for (j = 0; j < ndm - 1; j++) + { + ppIdx_re[i][j] = 100; + } }*/ #endif - - ivas_quantise_real_values( ppC_re, pQs->C.q_levels[0], pQs->C.min, pQs->C.max, ppIdx_re, ppC_re, ndec * ( ndm - 1 ), 1 ); - + ivas_quantise_real_values( C_re, pQs->C.q_levels[0], pQs->C.min, pQs->C.max, pBand_coeffs_idx->drct_index_re, C_re, ndec * ( ndm - 1 ) ); k = 0; for ( i = 0; i < ndec; i++ ) { @@ -1867,11 +1737,11 @@ static void ivas_quant_c_per_band( k = 0; for (i = 0; i < ndec; i++) { - for (j = 0; j < ndm - 1; j++) - { - fprintf(stderr, "%d,%d: %f, %f, %d\n", i, j, pband_coeffs->C_re[i][j], pband_coeffs->C_quant_re[i][j], pBand_coeffs_idx->drct_index_re[k]); - k++; - } + for (j = 0; j < ndm - 1; j++) + { + fprintf(stderr, "%d,%d: %f, %f, %d\n", i, j, pband_coeffs->C_re[i][j], pband_coeffs->C_quant_re[i][j], pBand_coeffs_idx->drct_index_re[k]); + k++; + } }*/ #endif @@ -1891,40 +1761,14 @@ static void ivas_quant_p_per_band( ivas_quant_strat_t *pQs, const int16_t num_ch ) { - float P_re_diag[IVAS_SPAR_MAX_CH - 1]; - int16_t i; - int16_t dim = num_ch - 1; - float *pP_diag[IVAS_SPAR_MAX_CH - 1]; - int16_t *pDecd_idx[IVAS_SPAR_MAX_CH - 1]; - float **ppP_diag = (float **) &pP_diag[0]; - int16_t **ppDecd_idx = (int16_t **) &pDecd_idx[0]; - - for ( i = 0; i < dim; i++ ) - { - ppP_diag[i] = &P_re_diag[i]; - ppDecd_idx[i] = &pBand_coeffs_idx->decd_index_re[i]; - } - - for ( i = 0; i < dim; i++ ) - { - P_re_diag[i] = pband_coeffs->P_re[i]; - } - #ifdef SPAR_HOA_DBG /*fprintf(stderr, "\n\n P_d:\n"); for (i = 0; i < dim; i++) { - fprintf(stderr, "%f, ", P_re_diag[i]); + fprintf(stderr, "%f, ", P_re_diag[i]); } fprintf(stderr, "\n\n");*/ #endif - - ivas_quantise_real_values( ppP_diag, pQs->P_r.q_levels[0], pQs->P_r.min, pQs->P_r.max, ppDecd_idx, ppP_diag, num_ch - 1, 1 ); - - for ( i = 0; i < dim; i++ ) - { - pband_coeffs->P_quant_re[i] = P_re_diag[i]; - } - + ivas_quantise_real_values( pband_coeffs->P_re, pQs->P_r.q_levels[0], pQs->P_r.min, pQs->P_r.max, pBand_coeffs_idx->decd_index_re, pband_coeffs->P_quant_re, num_ch - 1 ); return; } diff --git a/lib_enc/ivas_stat_enc.h b/lib_enc/ivas_stat_enc.h index 58b6970d58..2169cac9bd 100644 --- a/lib_enc/ivas_stat_enc.h +++ b/lib_enc/ivas_stat_enc.h @@ -571,7 +571,11 @@ typedef struct ivas_dirac_enc_data_structure PARAM_ISM_CONFIG_HANDLE hParamIsm; /* Parametric ISM handle */ IVAS_FB_MIXER_HANDLE hFbMixer; +#ifdef FIX_DIRAC_CHANNELS + float *sba_synchro_buffer[DIRAC_MAX_ANA_CHANS]; +#else float *sba_synchro_buffer[IVAS_MAX_NUM_CH]; // VE: all 16 buffers not needed ? +#endif int16_t num_samples_synchro_delay; /* DirAC parameter estimation */ @@ -1040,9 +1044,7 @@ typedef struct /* high-level encoder parameters */ int16_t nchan_transport; /* number of transport channels */ -#ifdef SBA_ORDER_BITSTREAM - int16_t sba_analysis_order; /*Ambisonic(SBA) order*/ -#endif + int16_t sba_analysis_order; /* Ambisonic (SBA) order used for analysis and coding */ int16_t codec_mode; /* Mode1 or Mode2 of core codec */ int16_t last_codec_mode; /* previous frame Mode 1 or 2 */ diff --git a/lib_enc/ivas_stereo_cng_enc.c b/lib_enc/ivas_stereo_cng_enc.c index 860cdbe88f..9176f9ad2f 100644 --- a/lib_enc/ivas_stereo_cng_enc.c +++ b/lib_enc/ivas_stereo_cng_enc.c @@ -148,7 +148,12 @@ void stereo_dft_enc_sid_coh( int16_t alpha_level; int16_t n; +#ifdef ALIGN_SID_SIZE + /* TODO: still use old number of bits to keep bitexactness in output */ + nr_of_sid_stereo_bits = ( 4400 /*IVAS_SID_5k2*/ - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS; +#else nr_of_sid_stereo_bits = ( IVAS_SID_4k4 - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS; +#endif zeropad = 0; /* Encode coherence vector. Find best fixed predictor by minimizing prediction error on input vector. @@ -303,6 +308,10 @@ void stereo_dft_enc_sid_coh( ( *nb_bits )++; } +#ifdef ALIGN_SID_SIZE + push_next_indice( hBstr, zeropad, ( IVAS_SID_5k2 - 4400 ) / FRAMES_PER_SEC ); +#endif + return; } diff --git a/lib_enc/ivas_stereo_dft_enc.c b/lib_enc/ivas_stereo_dft_enc.c index b6a7e0685d..402003be6c 100644 --- a/lib_enc/ivas_stereo_dft_enc.c +++ b/lib_enc/ivas_stereo_dft_enc.c @@ -2317,7 +2317,11 @@ void stereo_dft_enc_write_BS( { stereo_dft_enc_sid_calc_coh( hStereoDft, hCPE->hStereoCng->coh_crossfade, &hCPE->hStereoCng->td_active, &hCPE->hStereoCng->first_SID, cohBand ); +#ifdef ALIGN_SID_SIZE + if ( *nb_bits <= ( ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS - STEREO_DFT_ITD_MODE_NBITS - STEREO_DFT_SID_ITD_NBITS - 1 ) ) +#else if ( *nb_bits <= ( ( IVAS_SID_4k4 - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS - STEREO_DFT_ITD_MODE_NBITS - STEREO_DFT_SID_ITD_NBITS - 1 ) ) +#endif { if ( hStereoDft->hItd->itd[k_offset] != 0 ) { @@ -2393,7 +2397,11 @@ void stereo_dft_enc_write_BS( nb += STEREO_DFT_GIPD_NBITS; } } +#ifdef ALIGN_SID_SIZE + else if ( *nb_bits <= ( ( IVAS_SID_5k2 - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS - STEREO_DFT_FLAG_BITS - STEREO_DFT_SID_GIPD_NBITS ) ) +#else else if ( *nb_bits <= ( ( IVAS_SID_4k4 - SID_2k40 ) / FRAMES_PER_SEC - SID_FORMAT_NBITS - STEREO_DFT_FLAG_BITS - STEREO_DFT_SID_GIPD_NBITS ) ) +#endif { push_indice( hBstr, IND_STEREO_DFT_NO_IPD_FLAG, hStereoDft->no_ipd_flag, STEREO_DFT_FLAG_BITS ); nb += STEREO_DFT_FLAG_BITS; /*IPD mode flag: 1bit*/ @@ -2943,7 +2951,11 @@ static void stereo_dft_enc_compute_prm( /* parameters for bred0 <= b < bpred1 are estimated from parameters of the remaining bands with ptrans0 <= b < btrans1. */ - bpred1 = ( hStereoDft->nbands > 10 ) ? hStereoDft->nbands - 2 : hStereoDft->nbands; + bpred1 = ( hStereoDft->nbands > 10 ) ? STEREO_DFT_RES_PRED_BAND_MAX - 2 : hStereoDft->nbands; + if ( hStereoDft->band_res[k_offset] == STEREO_DFT_BAND_RES_LOW ) + { + bpred1 = min( bpred1, 6 ); + } bpred0 = bpred1 - STEREO_DFT_RES_PRED_BAND_MIN_CONST; /* get estimate (currently the maximal index) */ @@ -2963,7 +2975,7 @@ static void stereo_dft_enc_compute_prm( if ( hStereoDft->reverb_flag && hStereoDft->nbands > 10 ) /*SWB and FB*/ { - for ( b = hStereoDft->nbands - 1; b >= hStereoDft->nbands - 2; b-- ) + for ( b = STEREO_DFT_RES_PRED_BAND_MAX - 1; b >= STEREO_DFT_RES_PRED_BAND_MAX - 2; b-- ) { hStereoDft->res_pred_index_EC[b - STEREO_DFT_RES_PRED_BAND_MIN_CONST] = hStereoDft->res_pred_index_EC[b]; } diff --git a/lib_enc/ivas_stereo_dft_enc_itd.c b/lib_enc/ivas_stereo_dft_enc_itd.c index fd39db32d3..594137993e 100755 --- a/lib_enc/ivas_stereo_dft_enc_itd.c +++ b/lib_enc/ivas_stereo_dft_enc_itd.c @@ -446,9 +446,6 @@ static float calc_mean_E_ratio( ITD_DATA_HANDLE hItd, int16_t nbands, int16_t band_limits[], -#ifndef FIX_WRONG_NBANDS_IN_ITD_ESTIMATION - const int16_t NFFT, -#endif const float sfm, const float nrg_L[STEREO_DFT_N_32k_ENC / 2], const float nrg_R[STEREO_DFT_N_32k_ENC / 2], @@ -469,11 +466,7 @@ static float calc_mean_E_ratio( grand_sum_xcorr_img = 0.0f; /*take bands up to 32kHz bandwidth as ITD is always calculated at 32kHz sampling rate*/ -#ifdef FIX_WRONG_NBANDS_IN_ITD_ESTIMATION nbands -= ( band_limits[nbands] > STEREO_DFT_N_32k_ENC / 2 ); -#else - nbands -= ( NFFT > STEREO_DFT_N_32k_ENC ); -#endif sum_Er = 0; for ( b = 0; b < nbands; b++ ) @@ -1244,11 +1237,7 @@ void stereo_dft_enc_compute_itd( /*calculate mean E ratio of main to background signal for cohSNR*/ if ( hCPE->element_mode == IVAS_CPE_DFT ) { -#ifdef FIX_WRONG_NBANDS_IN_ITD_ESTIMATION mEr = calc_mean_E_ratio( hItd, hStereoDft->nbands, hStereoDft->band_limits, sfm_L, pNrgL, pNrgR, &total_mEr ); -#else - mEr = calc_mean_E_ratio( hItd, hStereoDft->nbands, hStereoDft->band_limits, hStereoDft->NFFT, sfm_L, pNrgL, pNrgR, &total_mEr ); -#endif } else { @@ -1257,11 +1246,7 @@ void stereo_dft_enc_compute_itd( set_s( band_limits, 0, STEREO_DFT_BAND_MAX + 1 ); set_band_limits( &nbands, band_limits, hCPE->hStereoMdct->hDft_ana->NFFT ); -#ifdef FIX_WRONG_NBANDS_IN_ITD_ESTIMATION mEr = calc_mean_E_ratio( hItd, nbands, band_limits, sfm_L, pNrgL, pNrgR, &total_mEr ); -#else - mEr = calc_mean_E_ratio( hItd, nbands, band_limits, hCPE->hStereoMdct->hDft_ana->NFFT, sfm_L, pNrgL, pNrgR, &total_mEr ); -#endif } /*calculate total cohSNR for frame in dB*/ diff --git a/lib_enc/ivas_stereo_dmx_evs.c b/lib_enc/ivas_stereo_dmx_evs.c index 409b7b0d56..a6773bc64c 100644 --- a/lib_enc/ivas_stereo_dmx_evs.c +++ b/lib_enc/ivas_stereo_dmx_evs.c @@ -152,9 +152,6 @@ static void calc_poc( { int16_t i, n1, n2; int16_t n0, *itdLR; -#ifndef NTT_REMOVE_EPS_ROM - const float *c; -#endif const float *s; float *P; float tmp1, tmp2, Lr, Li, Rr, Ri, gamma, igamma, iN; @@ -162,18 +159,13 @@ static void calc_poc( float tmpPOC1[L_FRAME48k], tmpPOC2[L_FRAME48k]; float rfft_buf[L_FRAME48k]; int16_t step, bias; -#ifdef NTT_REMOVE_EPS_ROM int16_t i_for; int16_t cos_step, cos_max; float eps_cos, eps_sin, EPS; -#endif /* Initialization */ iN = 1.0f / (float) input_frame; -#ifndef NTT_REMOVE_EPS_ROM - c = hPOC->sin + ( input_frame >> 2 ); -#endif s = hPOC->sin; P = hPOC->P; n0 = input_frame / 2; @@ -195,7 +187,6 @@ static void calc_poc( specPOr[0] = sign( specLr[0] ) * sign( specRr[0] ) * wnd[bias]; specPOi[0] = 0.0f; -#ifdef NTT_REMOVE_EPS_ROM EPS = hPOC->eps; if ( input_frame == L_FRAME16k ) @@ -252,28 +243,6 @@ static void calc_poc( specPOi[i] = ( Lr * Ri - Li * Rr ) * tmp1; gamma -= igamma; } - // end NTT_REMOVE_EPS_ROM -#else - for ( i = 1; i < n0; i++ ) - { - Lr = specLr[i]; - Li = specLi[i]; - Rr = specRr[i]; - Ri = specRi[i]; - - Lr += ( specRr[i] * c[i] + specRi[i] * s[i] ); - Li += ( -specRr[i] * s[i] + specRi[i] * c[i] ); - Rr += ( specLr[i] * c[i] + specLi[i] * s[i] ); - Ri += ( -specLr[i] * s[i] + specLi[i] * c[i] ); - - tmp1 = wnd[i * step + bias] * gamma / ( sqrtf( ( ( Lr * Lr + Li * Li ) ) * ( ( Rr * Rr + Ri * Ri ) ) ) + hPOC->eps ); - - specPOr[i] = ( Lr * Rr + Li * Ri ) * tmp1; - specPOi[i] = ( Lr * Ri - Li * Rr ) * tmp1; - - gamma -= igamma; - } -#endif // end !NTT_REMOVE_EPS_ROM specPOr[n0] = sign( specLr[i] ) * sign( specRr[i] ) * wnd[i * step + bias] * gamma; @@ -445,20 +414,6 @@ static float find_poc_peak( } } -#ifndef NTT_UPDATE_ITD_SW - if ( on[0] && prev_off[0] ) - { - *itd = (float) itdLR[0]; - } - else if ( on[1] && prev_off[1] ) - { - *itd = (float) itdLR[1]; - } - else - { - *itd = ( *itd > 0 ) ? (float) itdLR[0] : (float) itdLR[1]; - } -#else if ( ( on[0] && prev_off[0] ) && ( on[1] && prev_off[1] ) ) /*if both channels have newly detected as active (possibility of preceding), select channel by peakness Q[] of POC */ { *itd = ( Q[0] > Q[1] ) ? (float) itdLR[0] : (float) itdLR[1]; @@ -487,7 +442,6 @@ static float find_poc_peak( { *itd = ( *itd > 0 ) ? (float) itdLR[0] : (float) itdLR[1]; } -#endif cconfidence = sqrtf( fabsf( Q[0] - Q[1] ) ); /*higher value indicates higher confidence for one preceding channel*/ @@ -868,7 +822,6 @@ ivas_error stereo_dmx_evs_init_encoder( } hStereoDmxEVS->hPOC->eps = 2.0f * EVS_PI / ( (float) input_frame ); -#ifdef NTT_REMOVE_EPS_ROM if ( input_frame == L_FRAME16k ) { hStereoDmxEVS->hPOC->sin = dft_trigo_32k; @@ -885,24 +838,6 @@ ivas_error stereo_dmx_evs_init_encoder( { return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "invalid frame length\n" ); } -#else - if ( input_frame == L_FRAME16k ) - { - hStereoDmxEVS->hPOC->sin = Stereo_dmx_s_wnd_coef_eps_16k; - } - else if ( input_frame == L_FRAME32k ) - { - hStereoDmxEVS->hPOC->sin = Stereo_dmx_s_wnd_coef_eps_32k; - } - else if ( input_frame == L_FRAME48k ) - { - hStereoDmxEVS->hPOC->sin = Stereo_dmx_s_wnd_coef_eps_48k; - } - else - { - return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "invalid frame length\n" ); - } -#endif hStereoDmxEVS->hPOC->confidence = 0.0f; diff --git a/lib_enc/ivas_stereo_mdct_core_enc.c b/lib_enc/ivas_stereo_mdct_core_enc.c index c41df7b24e..664998967c 100644 --- a/lib_enc/ivas_stereo_mdct_core_enc.c +++ b/lib_enc/ivas_stereo_mdct_core_enc.c @@ -129,6 +129,9 @@ void stereo_mdct_core_enc( float *p_orig_spectrum_long[CPE_CHANNELS], orig_spectrum_long[CPE_CHANNELS][N_MAX]; /* MDCT output (L/R). */ float *orig_spectrum[CPE_CHANNELS][2]; /* Pointers to MDCT output for a short block (L/R) */ float powerSpec[CPE_CHANNELS][N_MAX]; +#ifdef DRAM_REDUCTION_MCT_IGF + float *p_powerSpec[CPE_CHANNELS]; +#endif float powerSpecMsInv_long[CPE_CHANNELS][N_MAX]; /* MS inv power spectrum, also inverse MDST spectrum */ float *powerSpecMsInv[CPE_CHANNELS][2]; float quantized_spectrum_long[CPE_CHANNELS][N_MAX]; /* quantized MDCT spectrum, inv ms mask mdst spectrum, scratch for MS spectra in the MS decision */ @@ -351,7 +354,13 @@ void stereo_mdct_core_enc( hStereoMdct->mdct_stereo_mode[n] == SMDCT_BW_MS ) && !hStereoMdct->isSBAStereoMode ) { +#ifdef DRAM_REDUCTION_MCT_IGF + p_powerSpec[0] = powerSpec[0]; + p_powerSpec[1] = powerSpec[1]; + ProcessStereoIGF( hStereoMdct, sts, ms_mask, orig_spectrum, p_powerSpec, powerSpecMsInv, inv_spectrum, n, hCPE->hCoreCoder[0]->sp_aud_decision0, hCPE->hCoreCoder[0]->element_brate, 0 ); +#else ProcessStereoIGF( hStereoMdct, sts, ms_mask, orig_spectrum, powerSpec, powerSpecMsInv, inv_spectrum, n, hCPE->hCoreCoder[0]->sp_aud_decision0, hCPE->hCoreCoder[0]->element_brate, 0 ); +#endif } else { diff --git a/lib_enc/ivas_stereo_switching_enc.c b/lib_enc/ivas_stereo_switching_enc.c index 9075d73595..d0201784a6 100644 --- a/lib_enc/ivas_stereo_switching_enc.c +++ b/lib_enc/ivas_stereo_switching_enc.c @@ -218,13 +218,12 @@ static void deallocate_CoreCoder_enc( *-------------------------------------------------------------------*/ ivas_error stereo_memory_enc( - CPE_ENC_HANDLE hCPE, /* i : CPE encoder structure */ - const int32_t input_Fs, /* i : input sampling rate */ - const int16_t max_bwidth, /* i : maximum audio bandwidth */ - float *tdm_last_ratio, /* o : TD stereo last ratio */ - const IVAS_FORMAT ivas_format /* i : ivas format */ - , - const int16_t nchan_transport /* i : number transport chans */ + CPE_ENC_HANDLE hCPE, /* i : CPE encoder structure */ + const int32_t input_Fs, /* i : input sampling rate */ + const int16_t max_bwidth, /* i : maximum audio bandwidth */ + float *tdm_last_ratio, /* o : TD stereo last ratio */ + const IVAS_FORMAT ivas_format, /* i : ivas format */ + const int16_t nchan_transport /* i : number transport chans */ ) { Encoder_State *st; @@ -538,7 +537,7 @@ ivas_error stereo_memory_enc( #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 ) ); + hCPE->hStereoMdct->isSBAStereoMode = ( ivas_format == SBA_FORMAT && nchan_transport == 2 ); if ( hCPE->element_mode == IVAS_CPE_MDCT && hCPE->element_brate <= MAX_MDCT_ITD_BRATE && ivas_format == STEREO_FORMAT ) { diff --git a/lib_enc/ivas_tcx_core_enc.c b/lib_enc/ivas_tcx_core_enc.c index 79bb2f04a7..ce2d74ec9a 100644 --- a/lib_enc/ivas_tcx_core_enc.c +++ b/lib_enc/ivas_tcx_core_enc.c @@ -268,7 +268,7 @@ void stereo_tcx_core_enc( *--------------------------------------------------------------------------------*/ /* TCX20/TCX10 and coder type */ -#ifdef FIX_IVAS_185_MDCT_ST_PLC_FADEOUT +#ifdef MDCT_STEREO_PLC_FADE_2_BG_NOISE writeTCXMode( st, hBstr, 0, /* <- is_mct */ &nbits_start ); #else writeTCXMode( st, hBstr, &nbits_start ); diff --git a/lib_enc/lib_enc.c b/lib_enc/lib_enc.c index b9d4dde032..0525c7c1db 100755 --- a/lib_enc/lib_enc.c +++ b/lib_enc/lib_enc.c @@ -54,7 +54,6 @@ struct IVAS_ENC Indice ind_list[MAX_NUM_DATA][MAX_NUM_INDICES]; /* list of indices */ Indice ind_list_metadata[MAX_NUM_METADATA][MAX_BITS_METADATA]; /* list of indices for metadata */ ENC_CORE_HANDLE hCoreCoder; - /* Some of these can be moved to Encoder_Struct, but for now leave them here to keep merging simpler */ bool isConfigured; #ifdef DEBUGGING bool cmd_stereo; @@ -63,7 +62,8 @@ struct IVAS_ENC int16_t Opt_RF_ON_loc; int16_t rf_fec_offset_loc; bool ismMetadataProvided[MAX_NUM_OBJECTS]; - bool maxBandwidthUser; /* Was a specific max bandwith selected by the user? */ + bool maxBandwidthUser; /* Was a specific max bandwith selected by the user? */ + IVAS_ENC_BANDWIDTH newBandwidthApi; /* maximum encoded bandwidth, as set on API level */ }; /*---------------------------------------------------------------------* @@ -77,7 +77,7 @@ static ivas_error setChannelAwareConfig( IVAS_ENC_HANDLE hIvasEnc, const IVAS_EN static int16_t getInputBufferSize( const Encoder_Struct *st_ivas ); static ivas_error doCommonConfigureChecks( IVAS_ENC_HANDLE hIvasEnc ); static ivas_error doCommonSetterChecks( IVAS_ENC_HANDLE hIvasEnc ); -static void updateBandwidthFromFs( const ENCODER_CONFIG_HANDLE hEncoderConfig ); +static ivas_error sanitizeBandwidth( const IVAS_ENC_HANDLE hIvasEnc ); 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 ); @@ -105,6 +105,10 @@ ivas_error IVAS_ENC_Open( return IVAS_ERR_UNEXPECTED_NULL_POINTER; } + /*-----------------------------------------------------------------* + * Allocate and initialize IVAS application encoder handle + *-----------------------------------------------------------------*/ + #ifdef BITSTREAM_INDICES_MEMORY if ( ( *phIvasEnc = (IVAS_ENC_HANDLE) dynamic_malloc( sizeof( struct IVAS_ENC ) ) ) == NULL ) #else @@ -114,15 +118,14 @@ ivas_error IVAS_ENC_Open( return IVAS_ERR_FAILED_ALLOC; } - if ( ( ( *phIvasEnc )->st_ivas = (Encoder_Struct *) count_malloc( sizeof( Encoder_Struct ) ) ) == NULL ) - { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for IVAS encoder structure" ); - } - - if ( ( ( *phIvasEnc )->st_ivas->hEncoderConfig = (ENCODER_CONFIG_HANDLE) count_malloc( sizeof( ENCODER_CONFIG ) ) ) == NULL ) - { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for Encoder config structure" ); - } + ( *phIvasEnc )->hCoreCoder = NULL; + ( *phIvasEnc )->isConfigured = false; +#ifdef DEBUGGING + ( *phIvasEnc )->cmd_stereo = false; +#endif + ( *phIvasEnc )->switchingActive = false; + ( *phIvasEnc )->maxBandwidthUser = false; + resetIsmMetadataProvidedFlags( *phIvasEnc ); /*-----------------------------------------------------------------* * Initialize indices @@ -147,29 +150,36 @@ ivas_error IVAS_ENC_Open( } /*-----------------------------------------------------------------* - * Initialize encoder state + * Allocate IVAS-codec encoder state *-----------------------------------------------------------------*/ - st_ivas = ( *phIvasEnc )->st_ivas; - st_ivas->hEncoderConfig->ivas_total_brate = ACELP_12k65; - st_ivas->hEncoderConfig->Opt_SC_VBR = 0; - st_ivas->hEncoderConfig->last_Opt_SC_VBR = 0; + if ( ( ( *phIvasEnc )->st_ivas = (Encoder_Struct *) count_malloc( sizeof( Encoder_Struct ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for IVAS encoder structure" ); + } - st_ivas->mc_mode = MC_MODE_NONE; - st_ivas->ism_mode = ISM_MODE_NONE; - st_ivas->sba_mode = SBA_MODE_NONE; + if ( ( ( *phIvasEnc )->st_ivas->hEncoderConfig = (ENCODER_CONFIG_HANDLE) count_malloc( sizeof( ENCODER_CONFIG ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for Encoder config structure" ); + } + + /*-----------------------------------------------------------------* + * Initialize IVAS-codec encoder state + *-----------------------------------------------------------------*/ + st_ivas = ( *phIvasEnc )->st_ivas; + + /* initialize encoder Config. handle */ init_encoder_config( st_ivas->hEncoderConfig ); - ( *phIvasEnc )->hCoreCoder = NULL; - ( *phIvasEnc )->isConfigured = false; -#ifdef DEBUGGING - ( *phIvasEnc )->cmd_stereo = false; -#endif - ( *phIvasEnc )->switchingActive = false; - ( *phIvasEnc )->maxBandwidthUser = false; - resetIsmMetadataProvidedFlags( *phIvasEnc ); + /* initialize pointers to handles to NULL */ + ivas_initialize_handles_enc( st_ivas ); + /* set high-level parameters */ + st_ivas->mc_mode = MC_MODE_NONE; + st_ivas->ism_mode = ISM_MODE_NONE; + st_ivas->sba_mode = SBA_MODE_NONE; + st_ivas->sba_analysis_order = 0; return IVAS_ERR_OK; } @@ -639,9 +649,7 @@ static ivas_error configureEncoder( st_ivas = hIvasEnc->st_ivas; hEncoderConfig = st_ivas->hEncoderConfig; -#ifdef SBA_ORDER_BITSTREAM - st_ivas->sba_analysis_order = hEncoderConfig->sba_order; -#endif + /*-----------------------------------------------------------------* * Bandwidth limitation *-----------------------------------------------------------------*/ @@ -772,16 +780,7 @@ static ivas_error configureEncoder( } else if ( hEncoderConfig->ivas_format == SBA_FORMAT ) { - if ( hEncoderConfig->ivas_total_brate < IVAS_256k ) - { - /* set SBA order to 1 for bit rates below 256kbps for correct handling of input with higher order */ - /* IVAS_fmToDo: needs more work in case of bitrate switching */ -#ifndef SBA_ORDER_BITSTREAM - hEncoderConfig->sba_order = 1; -#else - st_ivas->sba_analysis_order = 1; -#endif - } + /* nothing */ } else if ( hEncoderConfig->ivas_format == MASA_FORMAT ) { @@ -826,8 +825,6 @@ static ivas_error configureEncoder( hEncoderConfig->input_Fs = inputFs; - updateBandwidthFromFs( hEncoderConfig ); - /*-----------------------------------------------------------------* * Channel-aware mode *-----------------------------------------------------------------*/ @@ -855,7 +852,7 @@ static ivas_error configureEncoder( } } - if ( hEncoderConfig->ivas_total_brate == 13200 && hEncoderConfig->Opt_RF_ON == 1 ) + if ( hEncoderConfig->ivas_total_brate == IVAS_13k2 && hEncoderConfig->Opt_RF_ON == 1 ) { st_ivas->codec_mode = MODE2; } @@ -886,15 +883,17 @@ static ivas_error configureEncoder( { return IVAS_ERROR( IVAS_ERR_NOT_SUPPORTED_OPTION, "AGC supported in SBA format at bitrates >= 24.4 kbps only." ); } -#ifndef SBA_ORDER_BITSTREAM + if ( hEncoderConfig->Opt_PCA_ON && !( hEncoderConfig->ivas_format == SBA_FORMAT && hEncoderConfig->ivas_total_brate == PCA_BRATE && hEncoderConfig->sba_order == 1 ) ) -#else - if ( hEncoderConfig->Opt_PCA_ON && !( hEncoderConfig->ivas_format == SBA_FORMAT && hEncoderConfig->ivas_total_brate == PCA_BRATE && st_ivas->sba_analysis_order == 1 ) ) -#endif { return IVAS_ERROR( IVAS_ERR_NOT_SUPPORTED_OPTION, "PCA supported at SBA FOA 256 kbps only." ); } + if ( ( error = sanitizeBandwidth( hIvasEnc ) ) != IVAS_ERR_OK ) + { + return error; + } + /*-----------------------------------------------------------------* * Finalize initialization *-----------------------------------------------------------------*/ @@ -962,7 +961,7 @@ ivas_error IVAS_ENC_GetDelay( *---------------------------------------------------------------------*/ static int16_t getInputBufferSize( - const Encoder_Struct *st_ivas /* i: IVAS encoder handle */ + const Encoder_Struct *st_ivas /* i : IVAS encoder handle */ ) { return (int16_t) ( st_ivas->hEncoderConfig->input_Fs * st_ivas->hEncoderConfig->nchan_inp / FRAMES_PER_SEC ); @@ -1032,6 +1031,11 @@ ivas_error IVAS_ENC_EncodeFrameToSerial( return IVAS_ERR_INVALID_INPUT_BUFFER_SIZE; } + if ( ( error = sanitizeBandwidth( hIvasEnc ) ) != IVAS_ERR_OK ) + { + return error; + } + if ( hEncoderConfig->ivas_format == ISM_FORMAT ) { for ( i = 0; i < hEncoderConfig->nchan_inp; ++i ) @@ -1404,7 +1408,8 @@ static ivas_error printConfigInfo_enc( { Encoder_Struct *st_ivas; ENCODER_CONFIG_HANDLE hEncoderConfig; - char max_bwidth_string[4]; + int16_t newBandwidthApi; + ivas_error error; st_ivas = hIvasEnc->st_ivas; hEncoderConfig = st_ivas->hEncoderConfig; @@ -1545,20 +1550,9 @@ static ivas_error printConfigInfo_enc( * Print potential limitation of audio bandwidth *-----------------------------------------------------------------*/ - switch ( hEncoderConfig->max_bwidth ) + if ( ( error = bandwidthApiToInternal( hIvasEnc->newBandwidthApi, &newBandwidthApi ) ) != IVAS_ERR_OK ) { - case NB: - strncpy( max_bwidth_string, "NB\0", sizeof( max_bwidth_string ) ); - break; - case WB: - strncpy( max_bwidth_string, "WB\0", sizeof( max_bwidth_string ) ); - break; - case SWB: - strncpy( max_bwidth_string, "SWB\0", sizeof( max_bwidth_string ) ); - break; - case FB: - strncpy( max_bwidth_string, "FB\0", sizeof( max_bwidth_string ) ); - break; + return error; } if ( st_ivas->hEncoderConfig->Opt_SC_VBR && !hEncoderConfig->Opt_DTX_ON ) @@ -1566,33 +1560,30 @@ static ivas_error printConfigInfo_enc( return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "\nError: SC-VBR 5900 bps not supported without DTX\n\n" ); } - if ( hIvasEnc->maxBandwidthUser ) - { - fprintf( stdout, "\nBandwidth limited to %s.\n", max_bwidth_string ); - } - if ( hEncoderConfig->ivas_format == MONO_FORMAT ) { - if ( hEncoderConfig->max_bwidth == FB && hEncoderConfig->ivas_total_brate < ACELP_16k40 ) + if ( newBandwidthApi != hEncoderConfig->max_bwidth ) { - fprintf( stdout, "\nFB coding not supported below %.2f kbps. ", ACELP_16k40 / 1000.f ); - if ( hEncoderConfig->ivas_total_brate < ACELP_9k60 ) + if ( newBandwidthApi == FB ) { - fprintf( stdout, "Switching to WB.\n" ); + fprintf( stdout, "\nFB coding not supported below %.2f kbps. ", ACELP_16k40 / 1000.f ); + if ( hEncoderConfig->max_bwidth == WB ) + { + fprintf( stdout, "Switching to WB.\n" ); + } + else + { + fprintf( stdout, "Switching to SWB.\n" ); + } } - else + else if ( newBandwidthApi == SWB ) { - fprintf( stdout, "Switching to SWB.\n" ); + fprintf( stdout, "\nSWB coding not supported below %.2f kbps. Switching to WB.\n", ACELP_9k60 / 1000.f ); } } - if ( hEncoderConfig->max_bwidth == SWB && hEncoderConfig->ivas_total_brate < ACELP_9k60 ) - { - fprintf( stdout, "\nSWB coding not supported below %.2f kbps. Switching to WB.", ACELP_9k60 / 1000.f ); - } - /* in case of 8kHz input sampling or "-max_band NB", require the total bitrate to be below 24.40 kbps */ - if ( ( hEncoderConfig->max_bwidth == NB || hEncoderConfig->input_Fs == 8000 ) && hEncoderConfig->ivas_total_brate > ACELP_24k40 ) + if ( ( newBandwidthApi == NB || hEncoderConfig->input_Fs == 8000 ) && hEncoderConfig->ivas_total_brate > ACELP_24k40 ) { fprintf( stdout, "\nError: Unsupported mode NB %d bps, NB mode supports rates 5900-24400 bps\n\n", hEncoderConfig->ivas_total_brate ); return IVAS_ERR_INVALID_BITRATE; @@ -1600,7 +1591,7 @@ static ivas_error printConfigInfo_enc( } else { - if ( hEncoderConfig->max_bwidth == FB && hEncoderConfig->ivas_total_brate < MIN_BRATE_FB_STEREO ) + if ( newBandwidthApi != hEncoderConfig->max_bwidth ) { fprintf( stdout, "\nFB coding not supported below %.2f kbps. Switching to SWB.\n", MIN_BRATE_FB_STEREO / 1000.f ); } @@ -1812,29 +1803,97 @@ static ivas_error doCommonSetterChecks( /*---------------------------------------------------------------------* - * updateBandwidthFromFs() + * sanitizeBandwidth() * * *---------------------------------------------------------------------*/ -static void updateBandwidthFromFs( - const ENCODER_CONFIG_HANDLE hEncoderConfig ) +static ivas_error sanitizeBandwidth( + const IVAS_ENC_HANDLE hIvasEnc ) { + ENCODER_CONFIG_HANDLE hEncoderConfig; + int16_t max_bwidth_tmp; + + hEncoderConfig = hIvasEnc->st_ivas->hEncoderConfig; + + max_bwidth_tmp = hIvasEnc->newBandwidthApi; + /* Prevent st_ivas->max_bwidth from being higher than Fs/2 */ - if ( hEncoderConfig->input_Fs == 8000 && hEncoderConfig->max_bwidth > NB ) + if ( hEncoderConfig->input_Fs == 8000 && max_bwidth_tmp > NB ) { - hEncoderConfig->max_bwidth = NB; + max_bwidth_tmp = NB; } - else if ( hEncoderConfig->input_Fs == 16000 && hEncoderConfig->max_bwidth > WB ) + else if ( hEncoderConfig->input_Fs == 16000 && max_bwidth_tmp > WB ) { - hEncoderConfig->max_bwidth = WB; + max_bwidth_tmp = WB; } - else if ( hEncoderConfig->input_Fs == 32000 && hEncoderConfig->max_bwidth > SWB ) + else if ( hEncoderConfig->input_Fs == 32000 && max_bwidth_tmp > SWB ) { - hEncoderConfig->max_bwidth = SWB; + max_bwidth_tmp = SWB; } - return; + /* NB coding not supported in IVAS. Switching to WB. */ + if ( max_bwidth_tmp == NB && hEncoderConfig->ivas_format != UNDEFINED_FORMAT && hEncoderConfig->ivas_format != MONO_FORMAT ) + { + if ( hEncoderConfig->input_Fs >= 16000 ) + { + max_bwidth_tmp = WB; + } + else + { + return IVAS_ERR_INVALID_BITRATE; + } + } + + if ( hEncoderConfig->ivas_format == MONO_FORMAT ) + { +#if 0 // IVAS_fmToDo: temporary disabled to keep EVS bit-exactness -> to be verified + if ( max_bwidth_tmp == FB && hEncoderConfig->ivas_total_brate < ACELP_16k40 ) + { + if ( hEncoderConfig->ivas_total_brate < ACELP_9k60 ) + { + max_bwidth_tmp = WB; + } + else + { + max_bwidth_tmp = SWB; + } + } + + if ( max_bwidth_tmp == SWB && hEncoderConfig->ivas_total_brate < ACELP_9k60 ) + { + max_bwidth_tmp = WB; + } + + /* in case of 8kHz input sampling or "-max_band NB", require the total bitrate to be below 24.40 kbps */ + if ( ( max_bwidth_tmp == NB || hEncoderConfig->input_Fs == 8000 ) && hEncoderConfig->ivas_total_brate > ACELP_24k40 ) + { + if ( hEncoderConfig->input_Fs >= 16000 ) + { + max_bwidth_tmp = WB; + } + else + { + return IVAS_ERR_INVALID_BITRATE; + } + } +#endif + } + else + { + if ( max_bwidth_tmp == FB && hEncoderConfig->ivas_total_brate < MIN_BRATE_FB_STEREO ) + { + max_bwidth_tmp = SWB; + } + } + + if ( hEncoderConfig->max_bwidth != max_bwidth_tmp ) + { + hEncoderConfig->max_bwidth = max_bwidth_tmp; + hIvasEnc->switchingActive = true; + } + + return IVAS_ERR_OK; } @@ -1860,6 +1919,8 @@ static ivas_error setBandwidth( return error; } + hIvasEnc->newBandwidthApi = newBandwidth; + /* NB coding not supported in IVAS. Switching to WB. */ if ( newBandwidth == NB && hEncoderConfig->ivas_format != UNDEFINED_FORMAT && hEncoderConfig->ivas_format != MONO_FORMAT ) { @@ -1872,13 +1933,6 @@ static ivas_error setBandwidth( hIvasEnc->switchingActive = true; } - /* Limit bandwidth to half of sampling rate - only possible if - * sampling rate has already been set via configure function */ - if ( hIvasEnc->isConfigured ) - { - updateBandwidthFromFs( hIvasEnc->st_ivas->hEncoderConfig ); - } - return IVAS_ERR_OK; } @@ -2046,11 +2100,14 @@ static void init_encoder_config( ENCODER_CONFIG_HANDLE hEncoderConfig /* o : configuration structure */ ) { + hEncoderConfig->ivas_total_brate = ACELP_12k65; hEncoderConfig->max_bwidth = SWB; hEncoderConfig->input_Fs = 16000; hEncoderConfig->nchan_inp = 1; hEncoderConfig->element_mode_init = EVS_MONO; hEncoderConfig->ivas_format = UNDEFINED_FORMAT; + hEncoderConfig->Opt_SC_VBR = 0; + hEncoderConfig->last_Opt_SC_VBR = 0; hEncoderConfig->Opt_AMR_WB = 0; hEncoderConfig->Opt_DTX_ON = 0; hEncoderConfig->Opt_RF_ON = 0; diff --git a/lib_enc/tcx_utils_enc.c b/lib_enc/tcx_utils_enc.c index ca88663355..9b272f0dee 100644 --- a/lib_enc/tcx_utils_enc.c +++ b/lib_enc/tcx_utils_enc.c @@ -1509,7 +1509,11 @@ void ProcessStereoIGF( Encoder_State *sts[CPE_CHANNELS], /* i : Encoder state */ int16_t ms_mask[2][MAX_SFB], /* i : bandwise MS mask */ float *pITFMDCTSpectrum[CPE_CHANNELS][2], /* i : MDCT spectrum fir ITF */ +#ifdef DRAM_REDUCTION_MCT_IGF + float *pPowerSpectrum[CPE_CHANNELS], /* i/o: MDCT^2 + MDST^2 spectrum, or estimate */ +#else float pPowerSpectrum[CPE_CHANNELS][N_MAX], /* i : MDCT^2 + MDST^2 spectrum, or estimate */ +#endif float *pPowerSpectrumMsInv[CPE_CHANNELS][2], /* i : inverse power spectrum */ float *inv_spectrum[CPE_CHANNELS][2], /* i : inverse spectrum */ const int16_t frameno, /* i : flag indicating index of current subfr. */ diff --git a/lib_rend/ivas_crend.c b/lib_rend/ivas_crend.c index 45a9e121ca..785678535f 100644 --- a/lib_rend/ivas_crend.c +++ b/lib_rend/ivas_crend.c @@ -68,7 +68,11 @@ static ivas_error ivas_hrtf_init( hHrtf->gain_lfe = 0; hHrtf->index_frequency_max_diffuse = 0; +#ifdef FIX_CREND_CHANNELS + for ( i = 0; i < MAX_TRANSPORT_CHANNELS; i++ ) +#else for ( i = 0; i < IVAS_MAX_NUM_CH; i++ ) +#endif { hHrtf->inv_diffuse_weight[i] = 0; for ( j = 0; j < BINAURAL_CHANNELS; j++ ) @@ -673,7 +677,11 @@ ivas_error ivas_crend_open( hCrend->lfe_delay_line = NULL; +#ifdef FIX_CREND_CHANNELS + for ( i = 0; i < MAX_TRANSPORT_CHANNELS; i++ ) +#else for ( i = 0; i < IVAS_MAX_NUM_CH; i++ ) +#endif { hCrend->freq_buffer_re[i] = NULL; hCrend->freq_buffer_im[i] = NULL; @@ -824,7 +832,11 @@ ivas_error ivas_crend_close( { if ( st_ivas->renderer_type != RENDERER_BINAURAL_OBJECTS_TD ) { +#ifdef FIX_CREND_CHANNELS + for ( i = 0; i < MAX_TRANSPORT_CHANNELS; i++ ) +#else for ( i = 0; i < IVAS_MAX_NUM_CH; i++ ) +#endif { if ( st_ivas->hCrend->freq_buffer_re[i] != NULL ) { @@ -1123,5 +1135,7 @@ ivas_error ivas_crend_process( mvr2r( pcm_tmp[i], output[i], output_frame ); } + wmops_sub_end(); + return IVAS_ERR_OK; } diff --git a/lib_rend/ivas_hrtf.c b/lib_rend/ivas_hrtf.c index 8b5f1ba217..7c4183b0e8 100644 --- a/lib_rend/ivas_hrtf.c +++ b/lib_rend/ivas_hrtf.c @@ -74,7 +74,7 @@ void BSplineModelEvalAlloc( * Init default HRTF model --------------------------------------------------------------------*/ -ivas_error DefaultBSplineModel( +void DefaultBSplineModel( TDREND_HRFILT_FiltSet_t *HrFiltSet_p, /* o : Loaded HR filter set */ const int32_t output_Fs /* i : Output sampling rate */ ) @@ -215,7 +215,7 @@ ivas_error DefaultBSplineModel( HrFiltSet_p->FiltLength = HrFiltSet_p->ModelParams.K; BSplineModelEvalAlloc( &HrFiltSet_p->ModelParams, &HrFiltSet_p->ModelEval ); - return IVAS_ERR_OK; + return; } diff --git a/lib_rend/ivas_objectRenderer.c b/lib_rend/ivas_objectRenderer.c index 153c6d7f2d..b4c784edfa 100644 --- a/lib_rend/ivas_objectRenderer.c +++ b/lib_rend/ivas_objectRenderer.c @@ -45,8 +45,17 @@ /*---------------------------------------------------------------------* * Local function prototypes *---------------------------------------------------------------------*/ + +#ifdef FIX_I106_TDREND_5MS +static ivas_error TDREND_GetMix( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, float output[][L_FRAME48k], const int16_t subframe_length, const int32_t output_Fs, const int16_t subframe_idx ); +#else static ivas_error TDREND_GetMix( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, float output[][L_FRAME48k], const int16_t output_frame, const int32_t output_Fs ); +#endif static void TDREND_Clear_Update_flags( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd ); +#ifdef FIX_I106_TDREND_5MS +static void TDREND_Update_listener_orientation( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, const int16_t headRotEnabled, const Quaternion *headPosition ); +static void TDREND_Update_object_positions( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, const int16_t numSources, const IVAS_FORMAT in_format, const ISM_METADATA_HANDLE *hIsmMetaData, float output[][L_FRAME48k] ); +#endif /*---------------------------------------------------------------------* * ivas_td_binaural_open() @@ -54,7 +63,6 @@ static void TDREND_Clear_Update_flags( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRe * Open and initialize TD Object binaural renderer *---------------------------------------------------------------------*/ -/*! r: TD Renderer result code. */ ivas_error ivas_td_binaural_open( Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ ) @@ -219,13 +227,13 @@ void ivas_td_binaural_close( * and renders the current frame. *---------------------------------------------------------------------*/ -/*! r: TD Renderer result code. */ -ivas_error ObjRenderIVASFrame( +void ObjRenderIVASFrame( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ float output[][L_FRAME48k], /* i/o: SCE channels / Binaural synthesis */ const int16_t output_frame /* i : output frame length */ ) { +#ifndef FIX_I106_TDREND_5MS TDREND_DirAtten_t *DirAtten_p; int16_t nS; float Pos[3]; @@ -234,9 +242,15 @@ ivas_error ObjRenderIVASFrame( float UpVec[3]; float Rmat[3][3]; int16_t c_indx; +#else + int16_t subframe_length; +#endif int16_t subframe_idx; float reverb_signal[BINAURAL_CHANNELS][L_FRAME48k]; +#ifdef FIX_I106_TDREND_5MS + subframe_length = output_frame / MAX_PARAM_SPATIAL_SUBFRAMES; +#else DirAtten_p = st_ivas->hBinRendererTd->DirAtten_p; /* Update the listener's location/orientation */ @@ -314,8 +328,16 @@ ivas_error ObjRenderIVASFrame( TDREND_MIX_SRC_SetPlayState( st_ivas->hBinRendererTd, nS, TDREND_PLAYSTATUS_PLAYING ); } } +#endif if ( st_ivas->hRenderConfig != NULL ) /* Renderer Configuration not enabled in TD standalone renderer */ { + +#ifdef FIX_I106_TDREND_5MS + if ( st_ivas->hRenderConfig->roomAcoustics.late_reverb_on && ( st_ivas->ini_frame == 0 ) ) + { + ivas_reverb_open( &st_ivas->hCrend->hReverb, st_ivas->transport_config, NULL, st_ivas->hRenderConfig, st_ivas->hDecoderConfig->output_Fs ); + } +#else if ( st_ivas->hRenderConfig->roomAcoustics.late_reverb_on ) { if ( st_ivas->ini_frame == 0 ) @@ -327,10 +349,33 @@ ivas_error ObjRenderIVASFrame( ivas_reverb_process( st_ivas->hCrend->hReverb, st_ivas->transport_config, 0, output, reverb_signal, subframe_idx ); } } +#endif } +#ifdef FIX_I106_TDREND_5MS + /* Update object position(s) */ + TDREND_Update_object_positions( st_ivas->hBinRendererTd, st_ivas->nchan_transport, st_ivas->ivas_format, st_ivas->hIsmMetaData, output ); + + for ( subframe_idx = 0; subframe_idx < MAX_PARAM_SPATIAL_SUBFRAMES; subframe_idx++ ) + { + /* Update the listener's location/orientation */ + TDREND_Update_listener_orientation( st_ivas->hBinRendererTd, + st_ivas->hDecoderConfig->Opt_Headrotation, + ( st_ivas->hHeadTrackData != NULL ) ? &st_ivas->hHeadTrackData->Quaternions[subframe_idx] : NULL ); + + if ( ( st_ivas->hRenderConfig != NULL ) && ( st_ivas->hRenderConfig->roomAcoustics.late_reverb_on ) ) + { + ivas_reverb_process( st_ivas->hCrend->hReverb, st_ivas->transport_config, 0, output, reverb_signal, subframe_idx ); + } + + /* Render subframe */ + TDREND_GetMix( st_ivas->hBinRendererTd, output, subframe_length, st_ivas->hDecoderConfig->output_Fs, subframe_idx ); + } +#else /* Call the renderer */ TDREND_GetMix( st_ivas->hBinRendererTd, output, output_frame, st_ivas->hDecoderConfig->output_Fs ); +#endif + if ( st_ivas->hRenderConfig != NULL ) /* Renderer Configuration not enabled in TD standalone renderer */ { if ( st_ivas->hRenderConfig->roomAcoustics.late_reverb_on ) @@ -340,36 +385,58 @@ ivas_error ObjRenderIVASFrame( v_add( reverb_signal[1], output[1], output[1], output_frame ); } } - return IVAS_ERR_OK; + + return; } +#ifdef FIX_I106_TDREND_5MS +/*---------------------------------------------------------------------* + * TDREND_GetMix() + * + * Render one 5 ms subframe from the mixer + *---------------------------------------------------------------------*/ +#else /*---------------------------------------------------------------------* * TDREND_GetMix() * * Render one output frame from the mixer *---------------------------------------------------------------------*/ - -/*! r: TD Renderer result code. */ +#endif static ivas_error TDREND_GetMix( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ float output[][L_FRAME48k], /* i/o: ISm object synth / rendered output in 0,1 */ - const int16_t output_frame, /* i/o: Output frame length */ - const int32_t output_Fs /* i : Output sampling rate */ +#ifdef FIX_I106_TDREND_5MS + const int16_t subframe_length, /* i/o: subframe length */ + const int32_t output_Fs, /* i : Output sampling rate */ + const int16_t subframe_idx /* i : Subframe index to 5 ms subframe */ +#else + const int16_t output_frame, /* i/o: Output frame length */ + const int32_t output_Fs /* i : Output sampling rate */ +#endif ) { int16_t i; TDREND_SRC_t *Src_p; TDREND_SRC_SPATIAL_t *SrcSpatial_p; TDREND_SRC_REND_t *SrcRend_p; - ivas_error result; + ivas_error error; +#ifdef FIX_I106_TDREND_5MS + float output_buf[2][L_SPATIAL_SUBFR_48k]; /* Temp buffer for left/right rendered signal */ +#else float output_buf[2][L_FRAME48k]; /* Temp buffer for left/right rendered signal */ +#endif + error = IVAS_ERR_OK; - result = IVAS_ERR_OK; - +#ifdef FIX_I106_TDREND_5MS + /* Clear the output buffer to accumulate rendered sources */ + set_f( output_buf[0], 0.0f, subframe_length ); + set_f( output_buf[1], 0.0f, subframe_length ); +#else /* Zero out the output buffer since objects are accumulated. */ set_f( output_buf[0], 0.0f, output_frame ); set_f( output_buf[1], 0.0f, output_frame ); +#endif /* Create the mix */ /* Loop through the source list and render each source */ @@ -388,23 +455,42 @@ static ivas_error TDREND_GetMix( /* Render source if needed */ if ( ( SrcRend_p->InputAvailable == TRUE ) && ( SrcRend_p->PlayStatus == TDREND_PLAYSTATUS_PLAYING ) ) { +#ifdef FIX_I106_TDREND_5MS +#ifdef TDREND_HRTF_TABLE_METHODS + error = TDREND_REND_RenderSourceHRFilt( Src_p, hBinRendererTd, output_buf, subframe_length, output_Fs ); +#else + error = TDREND_REND_RenderSourceHRFilt( Src_p, output_buf, subframe_length, output_Fs ); +#endif +#else #ifdef TDREND_HRTF_TABLE_METHODS - result = TDREND_REND_RenderSourceHRFilt( Src_p, hBinRendererTd, output_buf, output_frame, output_Fs ); + error = TDREND_REND_RenderSourceHRFilt( Src_p, hBinRendererTd, output_buf, output_frame, output_Fs ); #else - result = TDREND_REND_RenderSourceHRFilt( Src_p, output_buf, output_frame, output_Fs ); + error = TDREND_REND_RenderSourceHRFilt( Src_p, output_buf, output_frame, output_Fs ); +#endif #endif } +#ifndef FIX_I106_TDREND_5MS SrcRend_p->InputAvailable = FALSE; +#endif } /* Populate output variable */ +#ifdef FIX_I106_TDREND_5MS + mvr2r( output_buf[0], output[0] + subframe_idx * subframe_length, subframe_length ); /* Left */ + mvr2r( output_buf[1], output[1] + subframe_idx * subframe_length, subframe_length ); /* Right */ +#else mvr2r( output_buf[0], output[0], output_frame ); /* Left */ mvr2r( output_buf[1], output[1], output_frame ); /* Right */ +#endif - /* Clear the mixer update flags */ +#ifdef FIX_I106_TDREND_5MS + /* Clear the PoseUpdated and Source position update flags */ +#else + /* Clear the mixer update flags */ +#endif TDREND_Clear_Update_flags( hBinRendererTd ); - return result; + return error; } @@ -421,9 +507,129 @@ static void TDREND_Clear_Update_flags( int16_t i; hBinRendererTd->Listener_p->PoseUpdated = FALSE; + for ( i = 0; i < hBinRendererTd->NumOfSrcs; i++ ) { hBinRendererTd->Sources[i]->SrcSpatial_p->Updated = FALSE; } + + return; +} + +#ifdef FIX_I106_TDREND_5MS +/*---------------------------------------------------------------------* + * TDREND_Update_object_positions() + * + * Update object position(s) + *---------------------------------------------------------------------*/ + +static void TDREND_Update_object_positions( + BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o : TD Renderer handle */ + const int16_t numSources, /* i : Number of sources to render */ + const IVAS_FORMAT in_format, /* i : Format of input sources */ + const ISM_METADATA_HANDLE *hIsmMetaData, /* i : Input metadata for ISM objects */ + float output[][L_FRAME48k] /* i/o: SCE/MC channels */ +) +{ + TDREND_DirAtten_t *DirAtten_p; + int16_t nS; + float Pos[3]; + float Dir[3]; + int16_t c_indx; + + DirAtten_p = hBinRendererTd->DirAtten_p; + + /* For each source, write the frame data to the source object*/ + c_indx = 0; + for ( nS = 0; nS < numSources; nS++ ) + { + if ( !( in_format == MC_FORMAT && nS == LFE_CHANNEL ) ) /* Skip LFE for MC */ + { + hBinRendererTd->Sources[c_indx]->InputFrame_p = output[nS]; + hBinRendererTd->Sources[c_indx]->SrcRend_p->InputAvailable = TRUE; + c_indx++; + } + + if ( in_format == ISM_FORMAT ) + { + + /* Update the source positions */ + /* Source position and direction */ + Pos[0] = cosf( hIsmMetaData[nS]->elevation * PI_OVER_180 ) * cosf( hIsmMetaData[nS]->azimuth * PI_OVER_180 ); + Pos[1] = cosf( hIsmMetaData[nS]->elevation * PI_OVER_180 ) * sinf( hIsmMetaData[nS]->azimuth * PI_OVER_180 ); + Pos[2] = sinf( hIsmMetaData[nS]->elevation * PI_OVER_180 ); + Dir[0] = 1.0f; + Dir[1] = 0.0f; + Dir[2] = 0.0f; + + /* Source directivity info */ + DirAtten_p->ConeInnerAngle = 360.0f; + DirAtten_p->ConeOuterAngle = 360.0f; + DirAtten_p->ConeOuterGain = 1.0f; + + TDREND_MIX_SRC_SetPos( hBinRendererTd, nS, Pos ); + TDREND_MIX_SRC_SetDirAtten( hBinRendererTd, nS, DirAtten_p ); + TDREND_MIX_SRC_SetPlayState( hBinRendererTd, nS, TDREND_PLAYSTATUS_PLAYING ); + + TDREND_MIX_SRC_SetDir( hBinRendererTd, nS, Dir ); + } + } + + return; +} + +/*---------------------------------------------------------------------* + * TDREND_Update_listener_orientation() + * + * Update listener orientation (s) + *---------------------------------------------------------------------*/ + +static void TDREND_Update_listener_orientation( + BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD Renderer handle */ + const int16_t headRotEnabled, /* i : Headrotation flag */ + const Quaternion *headPosition /* i : Head Position */ +) +{ + float Pos[3]; + float FrontVec[3]; + float UpVec[3]; + float Rmat[3][3]; + + /* Update the listener's location/orientation */ + /* Listener at the origin */ + Pos[0] = 0.0f; + Pos[1] = 0.0f; + Pos[2] = 0.0f; + + if ( headRotEnabled ) + { + /* Obtain head rotation matrix */ + QuatToRotMat( *headPosition, Rmat ); + /* Apply rotation matrix to looking vector [1;0;0] */ + FrontVec[0] = Rmat[0][0]; + FrontVec[1] = Rmat[0][1]; + FrontVec[2] = Rmat[0][2]; + /* Apply rotation matrix to up vector [0;0;1] */ + UpVec[0] = Rmat[2][0]; + UpVec[1] = Rmat[2][1]; + UpVec[2] = Rmat[2][2]; + } + else + { + /* Oriented with looking vector along the x axis */ + FrontVec[0] = 1.0f; + FrontVec[1] = 0.0f; + FrontVec[2] = 0.0f; + /* Oriented with up vector along the z axis */ + UpVec[0] = 0.0f; + UpVec[1] = 0.0f; + UpVec[2] = 1.0f; + } + + /* Set the listener position and orientation:*/ + TDREND_MIX_LIST_SetPos( hBinRendererTd, Pos ); + TDREND_MIX_LIST_SetOrient( hBinRendererTd, FrontVec, UpVec ); + return; } +#endif diff --git a/lib_rend/ivas_objectRenderer_hrFilt.c b/lib_rend/ivas_objectRenderer_hrFilt.c index 4ece382b4f..eb69350d48 100644 --- a/lib_rend/ivas_objectRenderer_hrFilt.c +++ b/lib_rend/ivas_objectRenderer_hrFilt.c @@ -343,24 +343,42 @@ void TDREND_HRFILT_SetFiltSet( --------------------------------------------------------------------*/ ivas_error TDREND_REND_RenderSourceHRFilt( - const TDREND_SRC_t *Src_p, /* i/o: The source to be rendered */ +#ifdef FIX_I106_TDREND_5MS + TDREND_SRC_t *Src_p, /* i/o: The source to be rendered */ +#else + const TDREND_SRC_t *Src_p, /* i/o: The source to be rendered */ +#endif #ifdef TDREND_HRTF_TABLE_METHODS BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ #endif +#ifdef FIX_I106_TDREND_5MS + float output_buf[][L_SPATIAL_SUBFR_48k], /* o : Output buffer */ + const int16_t subframe_length, /* i : Subframe length in use */ +#else float output_buf[][L_FRAME48k], /* o : Output buffer */ const int16_t output_frame, /* i : Output frame length in use */ - const int32_t output_Fs /* i : Output sample rate */ +#endif + + const int32_t output_Fs /* i : Output sample rate */ ) { - ivas_error SFX_Result; TDREND_SRC_REND_t *SrcRend_p; +#ifdef FIX_I106_TDREND_5MS + const float *InFrame_nIC_p; +#else int16_t nS; float *InFrame_nIC_p; +#endif int16_t NoOfUsedInputSamples, NoOfDeliveredOutputSamples; +#ifdef FIX_I106_TDREND_5MS + float LeftOutputFrame[L_SPATIAL_SUBFR_48k]; + float RightOutputFrame[L_SPATIAL_SUBFR_48k]; +#else float LeftOutputFrame[L_FRAME48k]; float RightOutputFrame[L_FRAME48k]; float *LeftOutputFrame_p, *RightOutputFrame_p; float *LeftAccOutputFrame_p, *RightAccOutputFrame_p; +#endif /* Input channel rendering loop */ InFrame_nIC_p = Src_p->InputFrame_p; @@ -370,9 +388,11 @@ ivas_error TDREND_REND_RenderSourceHRFilt( /* SrcGain = Mix_p->Gain * ( *SrcRend_p->SrcGain_p ); */ /* SrcGain *= ( *SrcRend_p->DirGain_p ) * ( *SrcRend_p->DistGain_p ); */ - SFX_Result = TDREND_SFX_SpatBin_Execute_Main( SrcRend_p->SfxSpatBin_p, InFrame_nIC_p, output_frame, - LeftOutputFrame, RightOutputFrame, - &NoOfUsedInputSamples, &NoOfDeliveredOutputSamples, output_Fs ); +#ifdef FIX_I106_TDREND_5MS + TDREND_SFX_SpatBin_Execute_Main( SrcRend_p->SfxSpatBin_p, InFrame_nIC_p, subframe_length, LeftOutputFrame, RightOutputFrame, &NoOfUsedInputSamples, &NoOfDeliveredOutputSamples, output_Fs ); +#else + TDREND_SFX_SpatBin_Execute_Main( SrcRend_p->SfxSpatBin_p, InFrame_nIC_p, output_frame, LeftOutputFrame, RightOutputFrame, &NoOfUsedInputSamples, &NoOfDeliveredOutputSamples, output_Fs ); +#endif #ifdef TDREND_HRTF_TABLE_METHODS if ( hBinRendererTd->HrFiltSet_p->FilterMethod != TDREND_HRFILT_Method_BSplineModel ) @@ -382,17 +402,27 @@ ivas_error TDREND_REND_RenderSourceHRFilt( #endif /* Copy to accumulative output frame */ +#ifdef FIX_I106_TDREND_5MS + v_add( LeftOutputFrame, output_buf[0], output_buf[0], subframe_length ); + v_add( RightOutputFrame, output_buf[1], output_buf[1], subframe_length ); + + Src_p->InputFrame_p += subframe_length; /* Increment input pointer -- todo: should we remove this and input the current subframe instead? */ + +#else LeftOutputFrame_p = LeftOutputFrame; RightOutputFrame_p = RightOutputFrame; LeftAccOutputFrame_p = output_buf[0]; RightAccOutputFrame_p = output_buf[1]; + for ( nS = 0; nS < output_frame; nS++ ) { *LeftAccOutputFrame_p++ += *LeftOutputFrame_p++; *RightAccOutputFrame_p++ += *RightOutputFrame_p++; } +#endif + - return SFX_Result; + return IVAS_ERR_OK; } diff --git a/lib_rend/ivas_objectRenderer_mix.c b/lib_rend/ivas_objectRenderer_mix.c index 61553ca4fc..df190b91b1 100644 --- a/lib_rend/ivas_objectRenderer_mix.c +++ b/lib_rend/ivas_objectRenderer_mix.c @@ -46,8 +46,7 @@ * Sets the listener's position in the specified mixer unit. --------------------------------------------------------------------*/ -/*! r: TD Renderer result code. */ -ivas_error TDREND_MIX_LIST_SetPos( +void TDREND_MIX_LIST_SetPos( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ const float *Pos_p /* i : Listener's position */ ) @@ -65,7 +64,7 @@ ivas_error TDREND_MIX_LIST_SetPos( Listener_p->PoseUpdated = TRUE; } - return IVAS_ERR_OK; + return; } @@ -75,7 +74,6 @@ ivas_error TDREND_MIX_LIST_SetPos( * Sets the listener's orientation vectors in the specified mixer unit. --------------------------------------------------------------------*/ -/*! r: TD Renderer result code. */ ivas_error TDREND_MIX_LIST_SetOrient( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ const float *FrontVec_p, /* i : Listener's orientation front vector */ @@ -193,7 +191,6 @@ void TDREND_MIX_Dealloc( * Initializes the mixer and sets HRTF --------------------------------------------------------------------*/ -/*! r: TD Renderer result code. */ ivas_error TDREND_MIX_Init( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ TDREND_HRFILT_FiltSet_t **hHrtfTD, /* i/o: HRTF data (initialized in case of NULL) */ @@ -256,7 +253,6 @@ ivas_error TDREND_MIX_Init( * Set the distance attenuation model of the mixer --------------------------------------------------------------------*/ -/*! r: TD Renderer result code. */ ivas_error TDREND_MIX_SetDistAttenModel( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ const TDREND_DistAttenModel_t DistAttenModel /* i : Distance attenuation model */ @@ -291,7 +287,6 @@ ivas_error TDREND_MIX_SetDistAttenModel( * Adds the specified input source unit to the specified mixer unit. --------------------------------------------------------------------*/ -/*! r: TD Renderer result code. */ ivas_error TDREND_MIX_AddSrc( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ int16_t *SrcInd, /* o : Source index */ diff --git a/lib_rend/ivas_objectRenderer_sfx.c b/lib_rend/ivas_objectRenderer_sfx.c index 45ac83a4ae..08239e8565 100644 --- a/lib_rend/ivas_objectRenderer_sfx.c +++ b/lib_rend/ivas_objectRenderer_sfx.c @@ -70,7 +70,7 @@ static void TDREND_FirFilterRev( float *OutputFrame_p, float *FirFilterRev_p, co #ifdef TDREND_HRTF_TABLE_METHODS static void TDREND_FirFilterRevInterp( float *OutputFrame_p, float *FirFilterRev_p, const int16_t FirFilterLength, float *InputFrame_p, const int16_t NumOfSamples, float *FilterStored ); #endif -static ivas_error TDREND_SFX_SpatBin_Clear( SFX_SpatBin_t *SfxSpatBin_p, const int32_t output_Fs ); +static void TDREND_SFX_SpatBin_Clear( SFX_SpatBin_t *SfxSpatBin_p, const int32_t output_Fs ); /*-------------------------------------------------------------------* @@ -352,8 +352,7 @@ static void TDREND_SFX_SpatBin_Resampling( * --------------------------------------------------------------------*/ -/*! r: TD Renderer result code. */ -ivas_error TDREND_SFX_SpatBin_SetParams( +void TDREND_SFX_SpatBin_SetParams( SFX_SpatBin_t *SfxSpatBin_p, /* i/o: Spatial parameters struct to be updated */ const SFX_SpatBin_Params_t *NewParam_p, /* i : New parameters struct */ const int32_t output_Fs /* i : Output sample rate */ @@ -397,7 +396,7 @@ ivas_error TDREND_SFX_SpatBin_SetParams( SfxSpatBin_p->OpMode = SFX_OFF; } - return IVAS_ERR_OK; + return; } @@ -554,6 +553,7 @@ static void TDREND_SFX_SpatBin_SetParamsInitializeOff( SfxSpatBin_p->NoOfLeftOldBufferSamples = SFX_SPAT_BIN_SINC_M - 1 + TDREND_MaxITD[i]; SfxSpatBin_p->NoOfRightOldBufferSamples = SFX_SPAT_BIN_SINC_M - 1 + TDREND_MaxITD[i]; SfxSpatBin_p->Left_Tf = 0.0; + return; } @@ -925,14 +925,16 @@ static void TDREND_SFX_SpatBin_UpdateParams( * TDREND_SFX_SpatBin_Execute_Main() * * The main rendering function that is called from the Audio Mixer. - * --------------------------------------------------------------------*/ -/*! r: TD Renderer result code. */ -ivas_error TDREND_SFX_SpatBin_Execute_Main( - SFX_SpatBin_t *SfxSpatBin_p, /* i/o: Spatial parameters struct */ - const float *InBuffer_p, /* i : Input buffer */ - const int16_t output_frame, /* i : frame length */ +void TDREND_SFX_SpatBin_Execute_Main( + SFX_SpatBin_t *SfxSpatBin_p, /* i/o: Spatial parameters struct */ + const float *InBuffer_p, /* i : Input buffer */ +#ifdef FIX_I106_TDREND_5MS + const int16_t subframe_length, /* i : subframe length */ +#else + const int16_t output_frame, /* i : frame length */ +#endif float *LeftOutBuffer_p, /* o : Rendered left channel */ float *RightOutBuffer_p, /* o : Rendered right channel */ int16_t *NoOfUsedInputSamples_p, /* o : Number of input samples actually used */ @@ -950,7 +952,11 @@ ivas_error TDREND_SFX_SpatBin_Execute_Main( /* Make sure the blocks are not longer than 6 msec. */ NoOfBlocks = 1; +#ifdef FIX_I106_TDREND_5MS + TempNoOfRequestedOutputSamples = subframe_length; +#else TempNoOfRequestedOutputSamples = output_frame; +#endif while ( TempNoOfRequestedOutputSamples > SfxSpatBin_p->MaxBlockLength ) { NoOfBlocks = NoOfBlocks << 1; @@ -964,7 +970,11 @@ ivas_error TDREND_SFX_SpatBin_Execute_Main( RightOutBufferPointer_p = RightOutBuffer_p; *NoOfUsedInputSamples_p = 0; *NoOfDeliveredOutputSamples_p = 0; +#ifdef FIX_I106_TDREND_5MS + TempNoOfInputSamples = subframe_length; +#else TempNoOfInputSamples = output_frame; +#endif for ( i = 0; i < NoOfBlocks; i++ ) { @@ -993,13 +1003,17 @@ ivas_error TDREND_SFX_SpatBin_Execute_Main( if ( i == NoOfBlocks - 2 ) { /* The last block should produce the remaining number of samples */ +#ifdef FIX_I106_TDREND_5MS + TempNoOfRequestedOutputSamples = subframe_length - *NoOfDeliveredOutputSamples_p; +#else TempNoOfRequestedOutputSamples = output_frame - *NoOfDeliveredOutputSamples_p; +#endif } *NoOfUsedInputSamples_p = *NoOfUsedInputSamples_p + TempNoOfUsedInputSamples; TempNoOfInputSamples = TempNoOfInputSamples - TempNoOfUsedInputSamples; } - return IVAS_ERR_OK; + return; } @@ -1182,7 +1196,7 @@ static void TDREND_SFX_SpatBin_Execute( } /* Update number of old samples */ - SfxSpatBin_p->NoOfRightOldBufferSamples = *NoOfUsedInputSamples_p - (int16_t) Ind; + SfxSpatBin_p->NoOfRightOldBufferSamples = *NoOfUsedInputSamples_p - Ind; return; } @@ -1195,7 +1209,6 @@ static void TDREND_SFX_SpatBin_Execute( * --------------------------------------------------------------------*/ -/*! r: TD Renderer result code. */ ivas_error TDREND_SFX_SpatBin_Initialize( SFX_SpatBin_t *SfxSpatBin_p, /* i/o: Spatial parameters struct */ const int32_t output_Fs /* i : Output sampling rate */ @@ -1278,19 +1291,21 @@ ivas_error TDREND_SFX_SpatBin_Initialize( * --------------------------------------------------------------------*/ -/*! r: TD Renderer result code. */ -static ivas_error TDREND_SFX_SpatBin_Clear( +static void TDREND_SFX_SpatBin_Clear( SFX_SpatBin_t *SfxSpatBin_p, /* i/o: Spatial parameters struct */ const int32_t output_Fs /* i : Output sample rate */ ) { int16_t i; int16_t MaxITD = TDREND_MaxITD[2]; + SfxSpatBin_p->OpMode = SFX_OFF; SfxSpatBin_p->TurningOffEffect = FALSE; SfxSpatBin_p->TurningOnEffect = FALSE; + /* Init during next SetParams-call */ SfxSpatBin_p->InitializeParams = TRUE; + /* Fill old buffers with zeros */ switch ( output_Fs ) { @@ -1316,7 +1331,7 @@ static ivas_error TDREND_SFX_SpatBin_Clear( SfxSpatBin_p->ResampledBufferRight[i] = 0.0f; } - return IVAS_ERR_OK; + return; } diff --git a/lib_rend/ivas_objectRenderer_sources.c b/lib_rend/ivas_objectRenderer_sources.c index b24708a195..a9e88602ca 100644 --- a/lib_rend/ivas_objectRenderer_sources.c +++ b/lib_rend/ivas_objectRenderer_sources.c @@ -55,14 +55,13 @@ static void TDREND_SRC_REND_Init( TDREND_SRC_REND_t *SrcRend_p, const int32_t ou /*-------------------------------------------------------------------* - * TDREND_MIX_SetSrcPos() + * TDREND_MIX_SRC_SetPos() * * Set source position --------------------------------------------------------------------*/ -/*! r: TD Renderer result code. */ ivas_error TDREND_MIX_SRC_SetPos( - BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ + BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ const int16_t SrcInd, /* i : Source index */ const float *Vec_p /* i : Position vector */ ) @@ -94,7 +93,6 @@ ivas_error TDREND_MIX_SRC_SetPos( * Set source direciton --------------------------------------------------------------------*/ -/*! r: TD Renderer result code. */ ivas_error TDREND_MIX_SRC_SetDir( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ const int16_t SrcInd, /* i : Source index */ @@ -129,7 +127,6 @@ ivas_error TDREND_MIX_SRC_SetDir( * Set directional attenuation for the mixer. --------------------------------------------------------------------*/ -/*! r: TD Renderer result code. */ ivas_error TDREND_MIX_SRC_SetDirAtten( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ const int16_t SrcInd, /* i : Source index */ @@ -146,6 +143,7 @@ ivas_error TDREND_MIX_SRC_SetDirAtten( SrcSpatial_p = hBinRendererTd->Sources[SrcInd]->SrcSpatial_p; TDREND_SRC_SPATIAL_SetDirAtten( SrcSpatial_p, DirAtten_p ); } + return IVAS_ERR_OK; } @@ -156,7 +154,6 @@ ivas_error TDREND_MIX_SRC_SetDirAtten( * Set play state for the source. --------------------------------------------------------------------*/ -/*! r: TD Renderer result code. */ ivas_error TDREND_MIX_SRC_SetPlayState( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ const int16_t SrcInd, /* i : Source index */ @@ -181,7 +178,6 @@ ivas_error TDREND_MIX_SRC_SetPlayState( * Renderer allocation --------------------------------------------------------------------*/ -/*! r: TD Renderer result code. */ static ivas_error TDREND_SRC_REND_Alloc( TDREND_SRC_REND_t **SrcRend_pp /* i/o: Source object */ ) @@ -441,7 +437,6 @@ void TDREND_SRC_REND_UpdateFiltersFromSpatialParams( * Allocatie spatial properties of a source. --------------------------------------------------------------------*/ -/*! r: TD Renderer result code. */ static ivas_error TDREND_SRC_SPATIAL_Alloc( TDREND_SRC_SPATIAL_t **SrcSpatial_pp /* i/o: Source spatial parameters */ ) @@ -651,7 +646,6 @@ static float TDREND_SRC_SPATIAL_GetDistGain( * Allocate a source. --------------------------------------------------------------------*/ -/*! r: TD Renderer result code. */ ivas_error TDREND_SRC_Alloc( TDREND_SRC_t **Src_pp /* i/o: Source */ ) diff --git a/lib_rend/ivas_output_init.c b/lib_rend/ivas_output_init.c index fcaa6f9442..b7af932861 100644 --- a/lib_rend/ivas_output_init.c +++ b/lib_rend/ivas_output_init.c @@ -263,9 +263,7 @@ void ivas_renderer_select( AUDIO_CONFIG output_config; AUDIO_CONFIG transport_config; -#ifdef FIX_I87 int16_t nchan_internal; -#endif renderer_type = &( st_ivas->renderer_type ); internal_config = &( st_ivas->intern_config ); @@ -360,12 +358,7 @@ void ivas_renderer_select( if ( st_ivas->hDecoderConfig->Opt_Headrotation ) { -#ifdef FIX_I87 -#ifdef SBA_ORDER_BITSTREAM nchan_internal = ivas_sba_get_nchan_metadata( st_ivas->sba_analysis_order ); -#else - nchan_internal = ivas_sba_get_nchan_metadata( st_ivas->sba_order ); -#endif if ( nchan_internal == 2 ) { st_ivas->hHeadTrackData->shd_rot_max_order = 1; @@ -382,24 +375,6 @@ void ivas_renderer_select( { st_ivas->hHeadTrackData->shd_rot_max_order = 3; } -#else - if ( st_ivas->nchan_transport == 2 ) - { - st_ivas->hHeadTrackData->shd_rot_max_order = 1; - } - else if ( st_ivas->nchan_transport == 4 || st_ivas->nchan_transport == 3 ) - { - st_ivas->hHeadTrackData->shd_rot_max_order = 0; - } - else if ( st_ivas->nchan_transport == 6 || st_ivas->nchan_transport == 5 ) - { - st_ivas->hHeadTrackData->shd_rot_max_order = 2; - } - else if ( st_ivas->nchan_transport == 8 || st_ivas->nchan_transport == 7 ) - { - st_ivas->hHeadTrackData->shd_rot_max_order = 3; - } -#endif } } else if ( st_ivas->ivas_format == MC_FORMAT ) @@ -536,7 +511,14 @@ void ivas_renderer_select( if ( st_ivas->ivas_format == SBA_FORMAT && st_ivas->sba_mode == SBA_MODE_SPAR && ( output_config != AUDIO_CONFIG_5_1 && output_config != AUDIO_CONFIG_5_1_2 && output_config != AUDIO_CONFIG_5_1_4 && output_config != AUDIO_CONFIG_7_1 && output_config != AUDIO_CONFIG_7_1_4 && output_config != AUDIO_CONFIG_LS_CUSTOM ) ) { - *internal_config = AUDIO_CONFIG_HOA3; + if ( output_config == AUDIO_CONFIG_HOA2 || output_config == AUDIO_CONFIG_FOA ) + { + *internal_config = output_config; + } + else + { + *internal_config = AUDIO_CONFIG_HOA3; + } st_ivas->renderer_type = RENDERER_SBA_LINEAR_DEC; } else if ( ( st_ivas->ivas_format == MASA_FORMAT && output_config == AUDIO_CONFIG_MONO && st_ivas->nchan_transport == 1 ) || @@ -544,7 +526,11 @@ void ivas_renderer_select( { *renderer_type = RENDERER_DISABLE; } +#ifdef ALIGN_SID_SIZE + else if ( ( st_ivas->ivas_format == MASA_FORMAT && output_config == AUDIO_CONFIG_MONO && st_ivas->hDecoderConfig->ivas_total_brate < MASA_STEREO_MIN_BITRATE && st_ivas->hDecoderConfig->ivas_total_brate > IVAS_SID_5k2 ) ) +#else else if ( ( st_ivas->ivas_format == MASA_FORMAT && output_config == AUDIO_CONFIG_MONO && st_ivas->hDecoderConfig->ivas_total_brate < MASA_STEREO_MIN_BITRATE && st_ivas->hDecoderConfig->ivas_total_brate > IVAS_SID_4k4 ) ) +#endif { *renderer_type = RENDERER_DISABLE; } diff --git a/lib_rend/ivas_reverb.c b/lib_rend/ivas_reverb.c index 7073169bcc..9bee3214d7 100644 --- a/lib_rend/ivas_reverb.c +++ b/lib_rend/ivas_reverb.c @@ -795,10 +795,17 @@ static void set_reverb_acoustic_data( { int16_t nr_out_ch, hrtf_idx, offset, iter_idx, bin_idx; float ln_1e6_inverted, delay_diff, exp_argument; +#ifdef FIX_CREND_CHANNELS + float *pHrtf_set_l_re[MAX_TRANSPORT_CHANNELS]; + float *pHrtf_set_l_im[MAX_TRANSPORT_CHANNELS]; + float *pHrtf_set_r_re[MAX_TRANSPORT_CHANNELS]; + float *pHrtf_set_r_im[MAX_TRANSPORT_CHANNELS]; +#else float *pHrtf_set_l_re[IVAS_MAX_NUM_CH]; float *pHrtf_set_l_im[IVAS_MAX_NUM_CH]; float *pHrtf_set_r_re[IVAS_MAX_NUM_CH]; float *pHrtf_set_r_im[IVAS_MAX_NUM_CH]; +#endif /* use crend hrtf filters */ if ( hHrtf != NULL ) diff --git a/lib_rend/ivas_sba_rendering.c b/lib_rend/ivas_sba_rendering.c index 03db2203c9..f8790c16e3 100644 --- a/lib_rend/ivas_sba_rendering.c +++ b/lib_rend/ivas_sba_rendering.c @@ -47,9 +47,11 @@ *-----------------------------------------------------------------------*/ #ifndef EXT_RENDERER -static void ivas_sba_mtx_mult( float output_f[][L_FRAME48k], const int16_t output_frame, const int16_t nchan_in, IVAS_OUTPUT_SETUP output_setup, const float *mtx_hoa_decoder ); +static void ivas_sba_mtx_mult( float output_f[][L_FRAME48k], const int16_t output_frame, const int16_t nchan_in, const IVAS_OUTPUT_SETUP output_setup, const float *mtx_hoa_decoder ); #endif +#ifndef HARMONIZE_SBA_NCHAN_TRANSPORT static void ivas_sba_dmx_dec( float sba_data[][L_FRAME48k], const int16_t nchan_transport, const int16_t output_frame ); +#endif #ifdef DEBUG_MODE_DIRAC static void debug_mode_dirac( float output[MAX_OUTPUT_CHANNELS][L_FRAME48k], const int16_t nchan_transport, const int16_t output_frame ); @@ -247,6 +249,25 @@ int16_t ivas_sba_remapTCs( } } +#ifdef HARMONIZE_SBA_NCHAN_TRANSPORT + if ( st_ivas->nchan_transport >= 3 ) + { + int16_t i = 0; + float temp; + + /*convert WYXZ downmix to WYZX*/ + for ( i = 0; i < output_frame; i++ ) + { + temp = sba_data[2][i]; + sba_data[2][i] = sba_data[3][i]; + sba_data[3][i] = temp; + if ( st_ivas->nchan_transport == 3 ) + { + sba_data[2][i] = 0; + } + } + } +#else if ( st_ivas->sba_mode == SBA_MODE_SPAR ) { int16_t i = 0; @@ -269,21 +290,24 @@ int16_t ivas_sba_remapTCs( } else { +#ifdef HARMONIZE_SBA_NCHAN_TRANSPORT + /* do nothing; simply use omni */ +#else ivas_sba_dmx_dec( sba_data, nchan_remapped, output_frame ); +#endif } +#endif if ( st_ivas->sba_mode != SBA_MODE_SPAR ) { -#ifndef SBA_ORDER_BITSTREAM - ivas_sba_zero_vert_comp( sba_data, st_ivas->sba_order, st_ivas->sba_planar, output_frame ); -#else ivas_sba_zero_vert_comp( sba_data, st_ivas->sba_analysis_order, st_ivas->sba_planar, output_frame ); -#endif } + return ( nchan_remapped ); } +#ifndef HARMONIZE_SBA_NCHAN_TRANSPORT /*-------------------------------------------------------------------* * ivas_sba_dmx_dec() * @@ -377,7 +401,7 @@ static void ivas_sba_dmx_dec( assert( 0 && "SBA: number of transport channels not supported." ); } } - +#endif /*-------------------------------------------------------------------------* * ivas_ism2sba() @@ -541,11 +565,11 @@ void ivas_sba_mtx_mult( #else static void ivas_sba_mtx_mult( #endif - float output_f[][L_FRAME48k], /* i/o: synthesized core-coder transport channels/DirAC output */ - const int16_t output_frame, /* i : output frame length per channel */ - const int16_t nchan_in, /* i : Number of ambisonic channels */ - IVAS_OUTPUT_SETUP output_setup, /* i : Output configuration */ - const float *mtx_hoa_decoder /* o : HOA decoding mtx */ + float output_f[][L_FRAME48k], /* i/o: synthesized core-coder transport channels/DirAC output */ + const int16_t output_frame, /* i : output frame length per channel */ + const int16_t nchan_in, /* i : Number of ambisonic channels */ + const IVAS_OUTPUT_SETUP output_setup, /* i : Output configuration */ + const float *mtx_hoa_decoder /* i : HOA decoding mtx */ ) { int16_t i, k, ch_idx; diff --git a/lib_util/hrtf_file_reader.c b/lib_util/hrtf_file_reader.c index 1dc481c84e..92b0058436 100644 --- a/lib_util/hrtf_file_reader.c +++ b/lib_util/hrtf_file_reader.c @@ -165,6 +165,7 @@ static void LoadBSplineBinaryITD( modelITD->W = (const float *) modelITD->W_dyn; modelITD->azimBsShape = (const float *) modelITD->azimBsShape_dyn; modelITD->elevBsShape = (const float *) modelITD->elevBsShape_dyn; + return; } @@ -310,7 +311,7 @@ static ivas_error LoadBSplineBinary( * * Load HRTF model or table from file --------------------------------------------------------------------*/ -/*! r: TD Renderer result code. */ + static ivas_error TDREND_MIX_LoadHRTF( FILE *f_hrtf, /* i/o: File pointer to HRTF file */ IVAS_DEC_HRTF_HANDLE HrFiltSet_p /* o : Loaded HR filter set */ -- GitLab From 2bbf2bfa2185c443af86e1681639e8c9005582ee Mon Sep 17 00:00:00 2001 From: Archit Tamarapu Date: Tue, 4 Oct 2022 19:35:43 +0200 Subject: [PATCH 021/101] External Renderer APIv2 update --- .gitignore | 6 + apps/renderer.c | 1246 ++-- lib_com/common_api_types.h | 6 +- lib_com/ivas_cnst.h | 14 +- lib_com/ivas_error.h | 45 +- lib_com/ivas_prot.h | 18 +- lib_com/options.h | 3 +- lib_dec/ivas_sba_dec.c | 7 +- lib_dec/ivas_stat_dec.h | 9 + lib_enc/ivas_stereo_mdct_core_enc.c | 0 lib_enc/lib_enc.c | 4 +- lib_rend/ivas_crend.c | 853 ++- lib_rend/ivas_lib_rend_internal.h | 87 + lib_rend/ivas_ls_custom_dec.c | 4 +- lib_rend/ivas_objectRenderer.c | 303 +- lib_rend/ivas_rom_rend.c | 81 +- lib_rend/ivas_rom_rend.h | 2 +- lib_rend/ivas_rotation.c | 23 +- lib_rend/ivas_sba_rendering.c | 8 +- lib_rend/ivas_stat_rend.h | 8 + lib_rend/lib_rend.c | 5603 ++++++++++------- lib_rend/lib_rend.h | 300 +- lib_util/cmdln_parser.h | 3 +- lib_util/ls_custom_file_reader.c | 2 +- scripts/pyaudio3dtools/audiofile.py | 27 +- scripts/pyaudio3dtools/binauralrenderer.py | 121 +- scripts/pyaudio3dtools/spatialaudioconvert.py | 4 + scripts/pyaudio3dtools/spatialaudioformat.py | 2 +- scripts/pyaudio3dtools/spatialmetadata.py | 1 + scripts/pyprocessing/prepost_processing.py | 3 +- scripts/tests/compare_audio.py | 28 + scripts/tests/constants.py | 18 +- scripts/tests/data/mixed_scene_simple.txt | 12 + scripts/tests/test_renderer.py | 285 +- 34 files changed, 5816 insertions(+), 3320 deletions(-) mode change 100644 => 100755 lib_com/options.h mode change 100644 => 100755 lib_enc/ivas_stereo_mdct_core_enc.c create mode 100644 lib_rend/ivas_lib_rend_internal.h mode change 100644 => 100755 lib_rend/ivas_sba_rendering.c create mode 100644 scripts/tests/data/mixed_scene_simple.txt diff --git a/.gitignore b/.gitignore index 6b784623d5..e719f5b008 100644 --- a/.gitignore +++ b/.gitignore @@ -36,6 +36,7 @@ scripts/td_object_renderer/object_renderer_standalone/renderer_standalone.exe # General/scripts .DS_Store .vscode +.cache *.log *.bak scripts/c-code_instrument/ @@ -45,8 +46,13 @@ scripts/test/ scripts/self_test_summary.txt scripts/tests/cut/ scripts/tests/ref/ +tests/dut +tests/ref # Python files that pop up when running scripts __pycache__/ *.py[cod] *$py.class + +# clangd +.cache/ diff --git a/apps/renderer.c b/apps/renderer.c index c8d1ee7bd6..3369dfcee2 100644 --- a/apps/renderer.c +++ b/apps/renderer.c @@ -33,21 +33,20 @@ #include "options.h" #include "audio_file_reader.h" #include "audio_file_writer.h" -#include "cmdln_parser.h" #include "cmdl_tools.h" +#include "cmdln_parser.h" #include "common_api_types.h" #include "head_rotation_file_reader.h" #include "hrtf_file_reader.h" #include "ism_file_reader.h" #include "lib_rend.h" #include "ls_custom_file_reader.h" -#include "render_config_reader.h" #include "masa_file_reader.h" -#include "ivas_stat_dec.h" #include "prot.h" +#include "render_config_reader.h" #ifdef WMOPS -#include "wmops.h" #include "PROM_Size_lib_rend.h" +#include "wmops.h" #endif #ifdef RAM_COUNTING_TOOL #include "mem_count.h" @@ -127,7 +126,7 @@ static void print_mem_renderer(size_t SRAM_size) /* clang-format on */ #endif -typedef struct IsmPositionProvider +typedef struct { uint32_t frameCounter; uint16_t numObjects; @@ -139,72 +138,76 @@ typedef struct IsmPositionProvider uint16_t durationCounters[RENDERER_MAX_ISM_INPUTS]; /* Number of frames spent at current position */ } IsmPositionProvider; -typedef enum InputFormat +typedef struct +{ + IVAS_REND_AudioConfig audioConfig; + int32_t inputChannelIndex; + float gain_dB; +} RendererInput; + +typedef struct +{ + IVAS_REND_AudioObjectPosition positions[RENDERER_MAX_ISM_INPUTS]; + int16_t numObjects; +} ObjectPositionBuffer; + +typedef struct +{ + RendererInput audioObjects[RENDERER_MAX_ISM_INPUTS]; + uint16_t numAudioObjects; + RendererInput multiChannelBuses[RENDERER_MAX_MC_INPUTS]; + uint16_t numMultiChannelBuses; + RendererInput ambisonicsBuses[RENDERER_MAX_SBA_INPUTS]; + uint16_t numAmbisonicsBuses; + IVAS_CUSTOM_LS_DATA inSetupCustom; + RendererInput masaBus; /* Support one MASA input for now. Multiple inputs will be easier to implement after API rework. */ + uint16_t numMasaBuses; /* Keep for framework consistency for now. Again - this will not be necessary after API rework */ +} InputConfig; + +typedef struct { - INPUT_FORMAT_NONE = 0, - INPUT_FORMAT_SBA, - INPUT_FORMAT_ISM, - INPUT_FORMAT_MC -} InputFormat; + IVAS_REND_AudioConfig audioConfig; + IVAS_CUSTOM_LS_DATA outSetupCustom; +} OutputConfig; typedef struct CmdlnArgs { char inputFilePath[FILENAME_MAX]; char outputFilePath[FILENAME_MAX]; int32_t sampleRate; - AUDIO_CONFIG inputFormat; - IVAS_REND_InputConfig inConfig; - IVAS_REND_OutputConfig outConfig; - uint8_t numAudioObjects; + InputConfig inConfig; + OutputConfig outConfig; char metaDataFiles[RENDERER_MAX_ISM_INPUTS][FILENAME_MAX]; char trajectoryFile[FILENAME_MAX]; char customHrtfFile[FILENAME_MAX]; char renderConfigFile[FILENAME_MAX]; int8_t orientationTracking; float noDiegeticPan; - bool neverDropLfe; /* flag */ - bool delayCompensationEnabled; /* flag */ + bool delayCompensationEnabled; bool quietModeEnabled; + bool sceneDescriptionInput; + float inputGainGlobal; } CmdlnArgs; -static int8_t setInConfig( - AUDIO_CONFIG input_config, - IVAS_REND_InputConfig *inConfig, - IsmPositionProvider *positionProvider ); - -static IVAS_REND_Ambisonics ambisonicsOrderToEnum( +static IVAS_REND_AudioConfig ambisonicsOrderToEnum( int32_t order ); -static IVAS_REND_Ambisonics audioCfgToAmbiEnum( - AUDIO_CONFIG cfg ); - -static IVAS_REND_MasaTc audioCfgToMasaEnum( - AUDIO_CONFIG cfg ); - -static IVAS_REND_SpeakerLayout speakerLayoutCicpToEnum( +static IVAS_REND_AudioConfig speakerLayoutCicpToEnum( int32_t cicpIndex ); -static IVAS_REND_SpeakerLayout audioCfgToMcEnum( - AUDIO_CONFIG cfg ); - -static int8_t parseInFormat( - char **optionValues, - CmdlnArgs *args ); - -static int8_t parseOutConfig( - char *configString, - IVAS_REND_OutputConfig *outConfig ); +static bool parseInConfig( char **optionValues, + CmdlnArgs *args ); static void parseConfigFile( char *path, char *audioFilePath, - IVAS_REND_InputConfig *inConfig, + InputConfig *inConfig, IsmPositionProvider *positionProvider, char *masaMetadataFilePath ); -static void parseCustomLayoutFile( +static ivas_error parseCustomLayoutFile( char *filePath, - IVAS_LSSETUP_CUSTOM_HANDLE *hLsSetupCustom ); + IVAS_CUSTOM_LS_DATA *pLsSetupCustom ); static CmdlnArgs parseCmdlnArgs( int32_t argc, @@ -215,19 +218,19 @@ static IsmPositionProvider *IsmPositionProvider_open( static void IsmPositionProvider_getNextFrame( IsmPositionProvider *positionProvider, - IVAS_REND_AudioObjectMetadataBuffer *objectMetadataBuffer ); + ObjectPositionBuffer *objectMetadataBuffer ); static void IsmPositionProvider_close( IsmPositionProvider *positionProvider ); static void readFromShorthandMetadata( IsmPositionProvider *positionProvider, - IVAS_REND_AudioObjectMetadataBuffer *objectMetadataBuffer, + ObjectPositionBuffer *objectMetadataBuffer, uint32_t objIdx ); void getMetadataFromFileReader( IsmFileReader *ismReader, - IVAS_REND_AudioObjectMetadataBuffer *objectMetadataBuffer, + ObjectPositionBuffer *objectMetadataBuffer, uint32_t objIdx ); static void splitConfigFile( @@ -253,6 +256,10 @@ static int8_t parseUint32( const char *line, uint32_t *ret ); +static int8_t parseInt32( + const char *line, + int32_t *ret ); + static void parseObjectPosition( char *line, IVAS_REND_AudioObjectPosition *position, @@ -261,29 +268,29 @@ static void parseObjectPosition( static void parseIsm( char *line, char *inDir, - IVAS_REND_InputConfig *inConfig, + InputConfig *inConfig, IsmPositionProvider *positionProvider, int32_t idx ); static void parseSba( char *line, - IVAS_REND_InputConfig *inConfig, + InputConfig *inConfig, int32_t idx ); static void parseMc( char *line, - IVAS_REND_InputConfig *inConfig, + InputConfig *inConfig, int32_t idx ); static void parseMasa( char *line, - IVAS_REND_InputConfig *inConfig, + InputConfig *inConfig, char *masaMetadataFilePath ); static void parseMetadata( char *metadataString, char *inDir, - IVAS_REND_InputConfig *inConfig, + InputConfig *inConfig, IsmPositionProvider *positionProvider, char *masaMetadataFilePath ); @@ -293,6 +300,12 @@ static void convert_backslash( static void remove_cr( char *str ); +static void clearString( char *str ); + +static void printSupportedAudioConfigs( void ); + +static IVAS_REND_AudioConfig parseAudioConfig( const char *configString ); + static void convertInputBuffer( const int16_t *intBuffer, int32_t numIntSamplesPerChannel, /* Number of samples per channel in the int buffer */ int32_t numFloatSamplesPerChannel, /* Per-channel length of the float buffer. If > numIntSamplesPerChannel, remaining samples will be set to 0. */ @@ -304,6 +317,84 @@ static void convertOutputBuffer( const float *floatBuffer, int32_t numChannels, int16_t *intBuffer ); +static IVAS_REND_ReadOnlyAudioBuffer getReadOnlySubBuffer( IVAS_REND_AudioBuffer buffer, int32_t chBeginIdx, int32_t numChannels ) +{ + IVAS_REND_ReadOnlyAudioBuffer subBuffer; + + subBuffer.config = buffer.config; + subBuffer.config.numChannels = numChannels; + subBuffer.data = buffer.data + subBuffer.config.numSamplesPerChannel * chBeginIdx; + + return subBuffer; +} + +static int32_t getTotalNumInChannels( IVAS_REND_HANDLE hIvasRend, + IVAS_REND_InputId mcIds[RENDERER_MAX_MC_INPUTS], + IVAS_REND_InputId ismIds[RENDERER_MAX_ISM_INPUTS], + IVAS_REND_InputId sbaIds[RENDERER_MAX_SBA_INPUTS] ) +{ + int32_t totalNumInChannels = 0; + ivas_error error; + + for ( int32_t i = 0; i < RENDERER_MAX_MC_INPUTS; ++i ) + { + if ( mcIds[i] == 0 ) + { + /* Skip inactive inputs */ + continue; + } + + int32_t numInputChannels; + if ( ( error = IVAS_REND_GetInputNumChannels( hIvasRend, mcIds[i], &numInputChannels ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + totalNumInChannels += numInputChannels; + } + + for ( int32_t i = 0; i < RENDERER_MAX_ISM_INPUTS; ++i ) + { + if ( ismIds[i] == 0 ) + { + /* Skip inactive inputs */ + continue; + } + + int32_t numInputChannels; + if ( ( error = IVAS_REND_GetInputNumChannels( hIvasRend, ismIds[i], &numInputChannels ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + totalNumInChannels += numInputChannels; + } + + for ( int32_t i = 0; i < RENDERER_MAX_SBA_INPUTS; ++i ) + { + if ( sbaIds[i] == 0 ) + { + /* Skip inactive inputs */ + continue; + } + + int32_t numInputChannels; + if ( ( error = IVAS_REND_GetInputNumChannels( hIvasRend, sbaIds[i], &numInputChannels ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + totalNumInChannels += numInputChannels; + } + + return totalNumInChannels; +} + +static float dBToLin( float gain_dB ) +{ + return powf( 10.0f, gain_dB / 20.0f ); +} + /* ============================================================================ */ @@ -331,7 +422,7 @@ int32_t main( int32_t argc, char **argv ) int16_t delayNumSamples_orig = 0; int16_t zeroPad = 0; int32_t delayTimeScale = 0; - int16_t i; + int32_t i; ivas_error error = IVAS_ERR_OK; #ifdef WMOPS size_t SRAM_size; @@ -349,11 +440,9 @@ int32_t main( int32_t argc, char **argv ) CmdlnArgs args = parseCmdlnArgs( argc, argv ); const int16_t frameSize_smpls = (int16_t) ( 20 * args.sampleRate / 1000 ); - /* === Open === */ - hIvasRend = IVAS_REND_Open(); positionProvider = IsmPositionProvider_open(); - masaMetadataFilePath[0] = '\0'; + clearString( masaMetadataFilePath ); convert_backslash( args.inputFilePath ); convert_backslash( args.outputFilePath ); @@ -374,64 +463,113 @@ int32_t main( int32_t argc, char **argv ) RenderConfigReader_open( args.renderConfigFile, &renderConfigReader ); } - /* === Parse === */ - if ( args.inputFormat == AUDIO_CONFIG_INVALID || args.inputFormat == AUDIO_CONFIG_META ) + if ( args.sceneDescriptionInput ) { - /* Only parse config file if input config is none */ + /* With scene description input, inputFilePath is the path to the scene description file. Parse it. */ parseConfigFile( args.inputFilePath, audioFilePath, &args.inConfig, positionProvider, masaMetadataFilePath ); } else { - /* If input config is set, input file path is the input audio file, not config file */ - strncpy( audioFilePath, args.inputFilePath, FILENAME_MAX ); + /* With single-format input, inputFilePath is the path to input audio file. */ + strncpy( audioFilePath, args.inputFilePath, FILENAME_MAX - 1 ); - /* Initialize inConfig - this will be overwritten when applying forced parameters, - * but not initializing here causes a compiler warning on msvc */ - args.inConfig.numAmbisonicsBuses = 0; - args.inConfig.numMultiChannelBuses = 0; - args.inConfig.numAudioObjects = args.numAudioObjects; + /* Set up reading metadata files */ + positionProvider->numObjects = args.inConfig.numAudioObjects; + for ( i = 0; i < positionProvider->numObjects; ++i ) + { + positionProvider->ismReaders[i] = IsmFileReader_open( args.metaDataFiles[i] ); + } } - /* === Apply forced parameters === */ if ( AudioFileReader_open( &audioReader, audioFilePath, args.sampleRate ) != IVAS_ERR_OK ) { fprintf( stderr, "Error opening file: %s\n", audioFilePath ); exit( -1 ); } - if ( args.inputFormat != AUDIO_CONFIG_INVALID ) + IVAS_REND_InputId mcIds[RENDERER_MAX_MC_INPUTS] = { 0 }; + IVAS_REND_InputId ismIds[RENDERER_MAX_ISM_INPUTS] = { 0 }; + IVAS_REND_InputId sbaIds[RENDERER_MAX_SBA_INPUTS] = { 0 }; + + if ( ( error = IVAS_REND_Open( &hIvasRend, args.sampleRate, args.outConfig.audioConfig ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error opening renderer handle: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + + /* Set up output custom layout configuration */ + if ( args.outConfig.audioConfig == IVAS_REND_AUDIO_CONFIG_LS_CUSTOM ) { - for ( i = 0; i < args.numAudioObjects; i++ ) + if ( ( error = IVAS_REND_ConfigureCustomOutputLoudspeakerLayout( hIvasRend, args.outConfig.outSetupCustom ) ) != IVAS_ERR_OK ) { - positionProvider->ismReaders[i] = IsmFileReader_open( args.metaDataFiles[i] ); + return error; } + } - if ( setInConfig( args.inputFormat, &args.inConfig, positionProvider ) != 0 ) + for ( int32_t i = 0; i < args.inConfig.numMultiChannelBuses; ++i ) + { + if ( ( error = IVAS_REND_AddInput( hIvasRend, args.inConfig.multiChannelBuses[i].audioConfig, &mcIds[i] ) ) != IVAS_ERR_OK ) { - fprintf( stderr, "File cannot be used: %s\n", audioFilePath ); + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); exit( -1 ); } + + if ( ( error = IVAS_REND_SetInputGain( hIvasRend, mcIds[i], args.inputGainGlobal * dBToLin( args.inConfig.multiChannelBuses[i].gain_dB ) ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + + /* TODO(sgi): Command line only supports one custom LS input for now, extend */ + if ( args.inConfig.multiChannelBuses[i].audioConfig == IVAS_REND_AUDIO_CONFIG_LS_CUSTOM ) + { + if ( ( error = IVAS_REND_ConfigureCustomInputLoudspeakerLayout( hIvasRend, mcIds[i], args.inConfig.inSetupCustom ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + /* TODO(sgi): Test custom LFE routing here */ } - /* === Configure === */ - if ( ( error = IVAS_REND_Configure( hIvasRend, args.inConfig, args.outConfig, args.sampleRate, args.trajectoryFile[0] != '\0', args.renderConfigFile[0] != '\0' ) ) != IVAS_ERR_OK ) + for ( int32_t i = 0; i < args.inConfig.numAudioObjects; ++i ) { - exit( -1 ); + if ( ( error = IVAS_REND_AddInput( hIvasRend, IVAS_REND_AUDIO_CONFIG_OBJECT, &ismIds[i] ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + + if ( ( error = IVAS_REND_SetInputGain( hIvasRend, ismIds[i], args.inputGainGlobal * dBToLin( args.inConfig.audioObjects[i].gain_dB ) ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } } - if ( args.neverDropLfe ) + for ( int32_t i = 0; i < args.inConfig.numAmbisonicsBuses; ++i ) { - IVAS_REND_SetNeverDropLfe( hIvasRend, 1 ); + if ( ( error = IVAS_REND_AddInput( hIvasRend, args.inConfig.ambisonicsBuses[i].audioConfig, &sbaIds[i] ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + + if ( ( error = IVAS_REND_SetInputGain( hIvasRend, sbaIds[i], args.inputGainGlobal * dBToLin( args.inConfig.ambisonicsBuses[i].gain_dB ) ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } } + const int32_t totalNumInChannels = getTotalNumInChannels( hIvasRend, mcIds, ismIds, sbaIds ); if ( AudioFileReader_getNumChannels( audioReader ) != 0 /* If input file is raw PCM, audio reader has no info about number of channels */ - && IVAS_REND_GetInChannels( hIvasRend ) != AudioFileReader_getNumChannels( audioReader ) ) + && totalNumInChannels != AudioFileReader_getNumChannels( audioReader ) ) { fprintf( stderr, "Number of channels in input file does not match selected configuration\n" ); exit( -1 ); } - /* === Process === */ MasaFileReader *masaReader = NULL; IVAS_MASA_METADATA_HANDLE hMasaMetadata = NULL; @@ -447,27 +585,31 @@ int32_t main( int32_t argc, char **argv ) hMasaMetadata = MasaFileReader_getMetadataHandle( masaReader ); } - if ( AudioFileWriter_open( &audioWriter, args.outputFilePath, args.sampleRate, IVAS_REND_GetOutChannels( hIvasRend ) ) != IVAS_ERR_OK ) + int32_t numOutChannels; + if ( ( error = IVAS_REND_NumOutChannels( hIvasRend, &numOutChannels ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + 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 * IVAS_REND_GetInChannels( hIvasRend ); - outBufferSize = frameSize_smpls * IVAS_REND_GetOutChannels( hIvasRend ); - inpInt16Buffer = count_calloc( inBufferSize, sizeof( int16_t ) ); - inFloatBuffer = count_calloc( inBufferSize, sizeof( float ) ); - outInt16Buffer = count_calloc( outBufferSize, sizeof( int16_t ) ); - outFloatBuffer = count_calloc( outBufferSize, sizeof( float ) ); + inBufferSize = frameSize_smpls * totalNumInChannels; + outBufferSize = frameSize_smpls * numOutChannels; + inpInt16Buffer = count_malloc( inBufferSize * sizeof( int16_t ) ); + inFloatBuffer = count_malloc( inBufferSize * sizeof( float ) ); + outInt16Buffer = count_malloc( outBufferSize * sizeof( int16_t ) ); + outFloatBuffer = count_malloc( outBufferSize * sizeof( float ) ); - inBuffer.config.sampleRate = args.sampleRate; - inBuffer.config.bufferSize = frameSize_smpls; - inBuffer.config.numChannels = IVAS_REND_GetInChannels( hIvasRend ); + inBuffer.config.numSamplesPerChannel = frameSize_smpls; + inBuffer.config.numChannels = totalNumInChannels; inBuffer.data = inFloatBuffer; - outBuffer.config.sampleRate = args.sampleRate; - outBuffer.config.bufferSize = frameSize_smpls; - outBuffer.config.numChannels = IVAS_REND_GetOutChannels( hIvasRend ); + outBuffer.config.numSamplesPerChannel = frameSize_smpls; + outBuffer.config.numChannels = numOutChannels; outBuffer.data = outFloatBuffer; #ifdef WMOPS @@ -508,15 +650,12 @@ int32_t main( int32_t argc, char **argv ) if ( masaReader != NULL ) { MasaFileReader_readNextFrame( masaReader ); - - if ( ( error = IVAS_REND_FeedMasaMetadata( hIvasRend, hMasaMetadata ) ) != IVAS_ERR_OK ) - { - fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); - exit( -1 ); - } + /* TODO: Feed MASA metadata here once MASA inputs are supported. + For now avoid unused var warning */ + (void) hMasaMetadata; } - IVAS_REND_AudioObjectMetadataBuffer mtdBuffer; + ObjectPositionBuffer mtdBuffer; IsmPositionProvider_getNextFrame( positionProvider, &mtdBuffer ); /* Read from head rotation trajectory file if specified */ @@ -526,8 +665,63 @@ int32_t main( int32_t argc, char **argv ) HeadRotationFileReading( headRotReader, quatBuffer, frame ); IVAS_REND_SetHeadRotation( hIvasRend, quatBuffer ); } + else + { + IVAS_REND_SetHeadRotation( hIvasRend, NULL ); + } - IVAS_REND_Render( hIvasRend, inBuffer, mtdBuffer, outBuffer ); + for ( int32_t i = 0; i < args.inConfig.numMultiChannelBuses; ++i ) + { + int32_t numChannels; + if ( ( error = IVAS_REND_GetInputNumChannels( hIvasRend, mcIds[i], &numChannels ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + IVAS_REND_ReadOnlyAudioBuffer tmpBuffer = getReadOnlySubBuffer( inBuffer, args.inConfig.multiChannelBuses[i].inputChannelIndex, numChannels ); + + if ( ( error = IVAS_REND_FeedInputAudio( hIvasRend, mcIds[i], tmpBuffer ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + } + + for ( int32_t i = 0; i < args.inConfig.numAudioObjects; ++i ) + { + IVAS_REND_ReadOnlyAudioBuffer tmpBuffer = getReadOnlySubBuffer( inBuffer, args.inConfig.audioObjects[i].inputChannelIndex, 1 ); + + if ( ( error = IVAS_REND_FeedInputAudio( hIvasRend, ismIds[i], tmpBuffer ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + + if ( ( error = IVAS_REND_FeedInputObjectMetadata( hIvasRend, ismIds[i], mtdBuffer.positions[i] ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + } + + for ( int32_t i = 0; i < args.inConfig.numAmbisonicsBuses; ++i ) + { + int32_t numChannels; + if ( ( error = IVAS_REND_GetInputNumChannels( hIvasRend, sbaIds[i], &numChannels ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + IVAS_REND_ReadOnlyAudioBuffer tmpBuffer = getReadOnlySubBuffer( inBuffer, args.inConfig.ambisonicsBuses[i].inputChannelIndex, numChannels ); + + if ( ( error = IVAS_REND_FeedInputAudio( hIvasRend, sbaIds[i], tmpBuffer ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); + exit( -1 ); + } + } + + IVAS_REND_GetSamples( hIvasRend, outBuffer ); int32_t num_out_channels; num_out_channels = outBuffer.config.numChannels; @@ -536,7 +730,6 @@ int32_t main( int32_t argc, char **argv ) * Values in outFloatBuffer are guaranteed to be within range INT16_MIN:INT16_MAX */ convertOutputBuffer( outFloatBuffer, frameSize_smpls, num_out_channels, outInt16Buffer ); - /* TODO tmu : delay compensation not finalized yet */ if ( delayNumSamples == -1 ) { if ( args.delayCompensationEnabled ) @@ -635,426 +828,156 @@ int32_t main( int32_t argc, char **argv ) return 0; } -static int8_t setInConfig( AUDIO_CONFIG input_config, IVAS_REND_InputConfig *inConfig, IsmPositionProvider *positionProvider ) -{ - int8_t success; /* flag */ - int16_t i; - - success = 1; - - if ( input_config == AUDIO_CONFIG_META ) - { - /* inConfig already set from metadata file, return early */ - return 0; - } - - inConfig->numAudioObjects = 0; - inConfig->numAmbisonicsBuses = 0; - inConfig->numMultiChannelBuses = 0; - inConfig->numMasaBuses = 0; - - switch ( input_config ) - { - case AUDIO_CONFIG_MONO: - case AUDIO_CONFIG_STEREO: - case AUDIO_CONFIG_5_1: - case AUDIO_CONFIG_7_1: - case AUDIO_CONFIG_5_1_2: - case AUDIO_CONFIG_5_1_4: - case AUDIO_CONFIG_7_1_4: - case AUDIO_CONFIG_LS_CUSTOM: - inConfig->numMultiChannelBuses = 1; - inConfig->multiChannelBuses[0].speakerLayout = audioCfgToMcEnum( input_config ); - inConfig->multiChannelBuses[0].inputChannelIndex = 0; - inConfig->multiChannelBuses[0].gain_dB = 0; - break; - case AUDIO_CONFIG_FOA: - case AUDIO_CONFIG_HOA2: - case AUDIO_CONFIG_HOA3: - inConfig->numAmbisonicsBuses = 1; - inConfig->ambisonicsBuses[0].ambisonicsConfig = audioCfgToAmbiEnum( input_config ); - inConfig->ambisonicsBuses[0].inputChannelIndex = 0; - inConfig->ambisonicsBuses[0].gain_dB = 0; - break; - case AUDIO_CONFIG_ISM1: - case AUDIO_CONFIG_ISM2: - case AUDIO_CONFIG_ISM3: - case AUDIO_CONFIG_ISM4: - inConfig->numAudioObjects = input_config - AUDIO_CONFIG_ISM1 + 1; /* TODO(sgi): Don't do arithemtic on enums, find a better way */ - positionProvider->numObjects = inConfig->numAudioObjects; - - for ( i = 0; i < inConfig->numAudioObjects; ++i ) - { - inConfig->audioObjects[i].inputChannelIndex = i; - inConfig->audioObjects[i].gain_dB = 0; - - positionProvider->numPositions[i] = 1; - positionProvider->positions[i] = count_malloc( sizeof( IVAS_REND_AudioObjectPosition ) ); - IVAS_REND_AudioObjectPosition position; - - /* Spread objects starting from 0, then -/+ 30, then -/+ 60 etc. */ - position.azimuth = (float) ( ( i + 1 ) / 2 ) * 30 * ( i % 2 == 0 ? -1 : 1 ); - position.elevation = 0.0f; - positionProvider->positions[i][0] = position; - - positionProvider->positionDurations[i] = count_malloc( sizeof( uint16_t ) ); - positionProvider->positionDurations[i][0] = 1; - } - break; - case AUDIO_CONFIG_MASA1: - case AUDIO_CONFIG_MASA2: - inConfig->numMasaBuses = 1; - inConfig->masaBus.numTc = audioCfgToMasaEnum( input_config ); - inConfig->masaBus.inputChannelIndex = 0; - inConfig->masaBus.gain_dB = 0; - break; - default: - success = 0; - fprintf( stderr, "Invalid or bad config\n" ); - } - - return success ? 0 : -1; -} - -static IVAS_REND_Ambisonics ambisonicsOrderToEnum( int32_t order ) +static IVAS_REND_AudioConfig ambisonicsOrderToEnum( int32_t order ) { switch ( order ) { - case 0: - return IVAS_REND_AMBISONICS_MONO; case 1: - return IVAS_REND_AMBISONICS_FOA; + return IVAS_REND_AUDIO_CONFIG_FOA; case 2: - return IVAS_REND_AMBISONICS_SOA; + return IVAS_REND_AUDIO_CONFIG_HOA2; case 3: - return IVAS_REND_AMBISONICS_TOA; + return IVAS_REND_AUDIO_CONFIG_HOA3; } - return IVAS_REND_AMBISONICS_NONE; + return IVAS_REND_AUDIO_CONFIG_UNKNOWN; } -static IVAS_REND_Ambisonics audioCfgToAmbiEnum( AUDIO_CONFIG cfg ) +static bool parseInConfig( char **optionValues, CmdlnArgs *args ) { - if ( cfg == AUDIO_CONFIG_MONO ) - { - return IVAS_REND_AMBISONICS_MONO; - } - else if ( cfg == AUDIO_CONFIG_FOA ) - { - return IVAS_REND_AMBISONICS_FOA; - } - else if ( cfg == AUDIO_CONFIG_HOA2 ) - { - return IVAS_REND_AMBISONICS_SOA; - } - else if ( cfg == AUDIO_CONFIG_HOA3 ) - { - return IVAS_REND_AMBISONICS_TOA; - } - - return IVAS_REND_AMBISONICS_NONE; -} - -static IVAS_REND_BinauralFormat audioCfgToBinauralEnum( AUDIO_CONFIG cfg ) -{ - if ( cfg == AUDIO_CONFIG_BINAURAL ) - { - return IVAS_REND_BINAURAL_DIRECT; - } - else if ( cfg == AUDIO_CONFIG_BINAURAL_ROOM ) - { - return IVAS_REND_BINAURAL_ROOM; - } - - return IVAS_REND_BINAURAL_NONE; -} + InputConfig inConfig; + char charBuf[FILENAME_MAX]; + + /* Initialize input config struct */ + inConfig.numAudioObjects = 0; + inConfig.numAmbisonicsBuses = 0; + inConfig.numMultiChannelBuses = 0; + inConfig.numMasaBuses = 0; + + /* First check if input is being set to scene description file - this is not covered by parseAudioConfig(). */ + strncpy( charBuf, optionValues[0], sizeof( charBuf ) - 1 ); + to_upper( charBuf ); + if ( strcmp( charBuf, "META" ) == 0 ) + { + args->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 IVAS_REND_AudioConfig enum. */ + IVAS_REND_AudioConfig audioConfig = parseAudioConfig( optionValues[0] ); + switch ( audioConfig ) + { + case IVAS_REND_AUDIO_CONFIG_MONO: + case IVAS_REND_AUDIO_CONFIG_STEREO: + case IVAS_REND_AUDIO_CONFIG_5_1: + case IVAS_REND_AUDIO_CONFIG_7_1: + case IVAS_REND_AUDIO_CONFIG_5_1_2: + case IVAS_REND_AUDIO_CONFIG_5_1_4: + case IVAS_REND_AUDIO_CONFIG_7_1_4: + inConfig.numMultiChannelBuses = 1; + inConfig.multiChannelBuses[0].audioConfig = audioConfig; + inConfig.multiChannelBuses[0].inputChannelIndex = 0; + inConfig.multiChannelBuses[0].gain_dB = 0.0f; + break; + case IVAS_REND_AUDIO_CONFIG_FOA: + case IVAS_REND_AUDIO_CONFIG_HOA2: + case IVAS_REND_AUDIO_CONFIG_HOA3: + inConfig.numAmbisonicsBuses = 1; + inConfig.ambisonicsBuses[0].audioConfig = audioConfig; + inConfig.ambisonicsBuses[0].inputChannelIndex = 0; + inConfig.ambisonicsBuses[0].gain_dB = 0.0f; + break; + case IVAS_REND_AUDIO_CONFIG_MASA1: + case IVAS_REND_AUDIO_CONFIG_MASA2: + inConfig.numMasaBuses = 1; + inConfig.masaBus.audioConfig = audioConfig; + inConfig.masaBus.inputChannelIndex = 0; + inConfig.masaBus.gain_dB = 0.0f; + break; + case IVAS_REND_AUDIO_CONFIG_OBJECT: + /* If input format is objects, parse the characters after "ISM" to get number of objects */ + { + char *ptr = NULL; + inConfig.numAudioObjects = strtol( optionValues[0] + 3, &ptr, 10 ); + if ( ptr == NULL || *ptr != '\0' ) + { + /* Failed to parse string as a number */ + fprintf( stderr, "Cannot parse string \"%s\" as a valid input format", optionValues[0] ); + return false; + } + if ( inConfig.numAudioObjects > RENDERER_MAX_ISM_INPUTS ) + { + fprintf( stderr, "Too many objects at input. Max %d supported.", RENDERER_MAX_ISM_INPUTS ); + return false; + } + for ( int32_t i = 0; i < inConfig.numAudioObjects; ++i ) + { + inConfig.audioObjects[i].audioConfig = audioConfig; + inConfig.audioObjects[i].inputChannelIndex = i; + inConfig.audioObjects[i].gain_dB = 0.0f; + } + } + break; + case IVAS_REND_AUDIO_CONFIG_UNKNOWN: + /* This case will be reached if parsing string to IVAS_REND_AudioConfig enum fails. + * Try to use the given string as a path to a custom loudspeaker layout file. */ + { + ivas_error error = parseCustomLayoutFile( optionValues[0], &inConfig.inSetupCustom ); -static IVAS_REND_MasaTc audioCfgToMasaEnum( AUDIO_CONFIG cfg ) -{ - switch ( cfg ) - { - case AUDIO_CONFIG_MASA1: - return IVAS_REND_MASA_TC_1; - case AUDIO_CONFIG_MASA2: - return IVAS_REND_MASA_TC_2; + if ( error == IVAS_ERR_FAILED_FILE_OPEN ) + { + /* Failed to open with given string - most likely wasn't a file path */ + fprintf( stderr, "Unsupported input format: %s\n", optionValues[0] ); + return false; + } + if ( error != IVAS_ERR_OK ) + { + fprintf( stderr, "Error while reading custom loudspeaker layout file %s\n", optionValues[0] ); + return false; + } + inConfig.numMultiChannelBuses = 1; + inConfig.multiChannelBuses[0].audioConfig = IVAS_REND_AUDIO_CONFIG_LS_CUSTOM; + inConfig.multiChannelBuses[0].inputChannelIndex = 0; + inConfig.multiChannelBuses[0].gain_dB = 0.0f; + } + break; default: + /* Default case covers formats that are defined in the IVAS_REND_AudioConfig enum, + * but cannot be used at input, e.g. BINAURAL */ + fprintf( stderr, "Unsupported input format: %s\n", optionValues[0] ); + return false; break; } + args->inConfig = inConfig; - return IVAS_REND_MASA_TC_NONE; -} -static IVAS_REND_SpeakerLayout speakerLayoutCicpToEnum( int32_t cicpIndex ) -{ - switch ( cicpIndex ) - { - case 0: - return IVAS_REND_SPEAKER_LAYOUT_CUSTOM; - case 1: - return IVAS_REND_SPEAKER_LAYOUT_MONO; - case 2: - return IVAS_REND_SPEAKER_LAYOUT_STEREO; - case 6: - return IVAS_REND_SPEAKER_LAYOUT_5_1; - case 12: - return IVAS_REND_SPEAKER_LAYOUT_7_1; - case 14: - return IVAS_REND_SPEAKER_LAYOUT_5_1_2; - case 16: - return IVAS_REND_SPEAKER_LAYOUT_5_1_4; - case 19: - return IVAS_REND_SPEAKER_LAYOUT_7_1_4; - } - - return IVAS_REND_SPEAKER_LAYOUT_NONE; + return true; } -static IVAS_REND_SpeakerLayout audioCfgToMcEnum( AUDIO_CONFIG cfg ) +static bool parseInMetadata( char **optionValues, int32_t numValues, CmdlnArgs *args ) { - if ( cfg == AUDIO_CONFIG_LS_CUSTOM ) - { - return IVAS_REND_SPEAKER_LAYOUT_CUSTOM; - } - else if ( cfg == AUDIO_CONFIG_MONO ) - { - return IVAS_REND_SPEAKER_LAYOUT_MONO; - } - else if ( cfg == AUDIO_CONFIG_STEREO ) - { - return IVAS_REND_SPEAKER_LAYOUT_STEREO; - } - else if ( cfg == AUDIO_CONFIG_5_1 ) - { - return IVAS_REND_SPEAKER_LAYOUT_5_1; - } - else if ( cfg == AUDIO_CONFIG_7_1 ) - { - return IVAS_REND_SPEAKER_LAYOUT_7_1; - } - else if ( cfg == AUDIO_CONFIG_5_1_2 ) - { - return IVAS_REND_SPEAKER_LAYOUT_5_1_2; - } - else if ( cfg == AUDIO_CONFIG_5_1_4 ) - { - return IVAS_REND_SPEAKER_LAYOUT_5_1_4; - } - else if ( cfg == AUDIO_CONFIG_7_1_4 ) - { - return IVAS_REND_SPEAKER_LAYOUT_7_1_4; - } + char charBuf[FILENAME_MAX]; - return IVAS_REND_SPEAKER_LAYOUT_NONE; -} - -static AUDIO_CONFIG parseStrToAudioCfg( char *config_str ) -{ - char format[14]; - uint8_t numObjects; - - format[13] = '\0'; - strncpy( format, config_str, 13 ); - to_upper( format ); - - if ( ( strcmp( format, "MONO" ) == 0 ) || ( strcmp( format, "HOA0" ) == 0 ) || ( strcmp( format, "SBA0" ) == 0 ) ) + for ( int32_t i = 0; i < numValues; ++i ) { - return AUDIO_CONFIG_MONO; - } - else if ( ( strcmp( format, "STEREO" ) == 0 ) || ( strcmp( format, "CICP2" ) == 0 ) ) - { - return AUDIO_CONFIG_STEREO; - } - else if ( ( strcmp( format, "FOA" ) == 0 ) || ( strcmp( format, "SBA1" ) == 0 ) ) - { - return AUDIO_CONFIG_FOA; - } - else if ( ( strcmp( format, "HOA2" ) == 0 ) || ( strcmp( format, "SBA2" ) == 0 ) ) - { - return AUDIO_CONFIG_HOA2; - } - else if ( ( strcmp( format, "HOA3" ) == 0 ) || ( strcmp( format, "SBA3" ) == 0 ) ) - { - return AUDIO_CONFIG_HOA3; - } - else if ( ( strcmp( format, "5_1" ) == 0 ) || ( strcmp( format, "CICP6" ) == 0 ) ) - { - return AUDIO_CONFIG_5_1; - } - else if ( ( strcmp( format, "7_1" ) == 0 ) || ( strcmp( format, "CICP12" ) == 0 ) ) - { - return AUDIO_CONFIG_7_1; - } - else if ( ( strcmp( format, "5_1_2" ) == 0 ) || ( strcmp( format, "CICP14" ) == 0 ) ) - { - return AUDIO_CONFIG_5_1_2; - } - else if ( ( strcmp( format, "5_1_4" ) == 0 ) || ( strcmp( format, "CICP16" ) == 0 ) ) - { - return AUDIO_CONFIG_5_1_4; - } - else if ( ( strcmp( format, "7_1_4" ) == 0 ) || ( strcmp( format, "CICP19" ) == 0 ) ) - { - return AUDIO_CONFIG_7_1_4; - } - else if ( strncmp( format, "ISM", 3 ) == 0 ) - { - parseUint8( &format[3], &numObjects ); - return AUDIO_CONFIG_ISM1 + numObjects - 1; /* TODO(sgi): Don't do arithemtic on enums, find a better way */ - } - else if ( strncmp( format, "MASA", 4 ) == 0 ) - { - switch ( format[4] ) - { - case '1': - return AUDIO_CONFIG_MASA1; - case '2': - return AUDIO_CONFIG_MASA2; - default: - return AUDIO_CONFIG_INVALID; - } - } - else if ( strncmp( format, "META", 4 ) == 0 ) - { - return AUDIO_CONFIG_META; - } - else if ( strncmp( format, "EXT", 3 ) == 0 ) - { - return AUDIO_CONFIG_EXTERNAL; - } - else if ( strcmp( format, "BINAURAL_ROOM" ) == 0 ) - { - return AUDIO_CONFIG_BINAURAL_ROOM; - } - else if ( strcmp( format, "BINAURAL" ) == 0 ) - { - return AUDIO_CONFIG_BINAURAL; - } - else - { - /* check extension to see if it is a custom loudspeaker layout file */ - if ( strcmp( strrchr( config_str, '.' ), ".txt" ) == 0 ) - { - return AUDIO_CONFIG_LS_CUSTOM; - } - else - { - return AUDIO_CONFIG_INVALID; - } - } -} - -static int8_t parseInFormat( char **optionValues, CmdlnArgs *args ) -{ - int8_t success; /* flag */ - success = 1; - - args->inputFormat = parseStrToAudioCfg( optionValues[0] ); - switch ( args->inputFormat ) - { - case AUDIO_CONFIG_LS_CUSTOM: - args->numAudioObjects = 0; - parseCustomLayoutFile( optionValues[0], &args->inConfig.inSetupCustom ); - break; - case AUDIO_CONFIG_ISM1: - case AUDIO_CONFIG_MASA1: - args->numAudioObjects = 1; - break; - case AUDIO_CONFIG_ISM2: - case AUDIO_CONFIG_MASA2: - args->numAudioObjects = 2; - break; - case AUDIO_CONFIG_ISM3: - args->numAudioObjects = 3; - break; - case AUDIO_CONFIG_ISM4: - args->numAudioObjects = 4; - break; - case AUDIO_CONFIG_BINAURAL: - case AUDIO_CONFIG_BINAURAL_ROOM: - fprintf( stderr, "BINAURAL input is not supported!\n" ); - success = 0; - break; - case AUDIO_CONFIG_EXTERNAL: - fprintf( stderr, "No rendering possible for EXT format!\n" ); - success = 0; - break; - default: - args->numAudioObjects = 0; - } + strncpy( charBuf, optionValues[i], sizeof( charBuf ) - 1 ); + to_upper( charBuf ); - for ( int16_t i = 0; i < args->numAudioObjects; i++ ) - { - if ( ( strcmp( optionValues[i + 1], "NULL" ) == 0 ) || ( strcmp( optionValues[i + 1], "null" ) == 0 ) ) + if ( ( strcmp( charBuf, "NULL" ) == 0 ) ) { - args->metaDataFiles[i][0] = '\0'; + /* TODO(sgi): Test setting mtd file to NULL. Will default positions be provided? Seems that crash is likely in this case. */ + clearString( args->metaDataFiles[i] ); } else { - strcpy( args->metaDataFiles[i], optionValues[i + 1] ); + strncpy( args->metaDataFiles[i], optionValues[i], FILENAME_MAX - 1 ); convert_backslash( args->metaDataFiles[i] ); } } - return success ? 0 : -1; -} - -static int8_t parseOutConfig( char *configString, IVAS_REND_OutputConfig *outConfig ) -{ - int8_t success; /* flag */ - success = 1; - - AUDIO_CONFIG outCfg; - - outCfg = parseStrToAudioCfg( configString ); - switch ( outCfg ) - { - case AUDIO_CONFIG_MONO: - case AUDIO_CONFIG_STEREO: - case AUDIO_CONFIG_5_1: - case AUDIO_CONFIG_7_1: - case AUDIO_CONFIG_5_1_2: - case AUDIO_CONFIG_5_1_4: - case AUDIO_CONFIG_7_1_4: - outConfig->speakerLayout = audioCfgToMcEnum( outCfg ); - break; - case AUDIO_CONFIG_LS_CUSTOM: - outConfig->speakerLayout = IVAS_REND_SPEAKER_LAYOUT_CUSTOM; - parseCustomLayoutFile( configString, &outConfig->outSetupCustom ); - break; - case AUDIO_CONFIG_FOA: - case AUDIO_CONFIG_HOA2: - case AUDIO_CONFIG_HOA3: - outConfig->ambisonics = audioCfgToAmbiEnum( outCfg ); - break; - case AUDIO_CONFIG_BINAURAL: - case AUDIO_CONFIG_BINAURAL_ROOM: - outConfig->binauralFormat = audioCfgToBinauralEnum( outCfg ); - break; - case AUDIO_CONFIG_META: - /* handled by parseConfigFile() */ - break; - case AUDIO_CONFIG_ISM1: - case AUDIO_CONFIG_ISM2: - case AUDIO_CONFIG_ISM3: - case AUDIO_CONFIG_ISM4: - fprintf( stderr, "ISM is not a valid output format!\n" ); - success = 0; - break; - case AUDIO_CONFIG_MASA1: - case AUDIO_CONFIG_MASA2: - fprintf( stderr, "MASA is not a valid output format!\n" ); - success = 0; - break; - case AUDIO_CONFIG_EXTERNAL: - fprintf( stderr, "No rendering possible for EXT format!\n" ); - success = 0; - break; - default: - success = 0; - fprintf( stderr, "Invalid or bad config\n" ); - } - - return success ? 0 : -1; + return true; } static int8_t parseDiegeticPan( char *value, float *noDiegeticPan ) @@ -1112,42 +1035,116 @@ static int8_t parseOrientationTracking( char *value, int8_t *tracking_type ) return success ? 0 : -1; } +static IVAS_REND_AudioConfig parseAudioConfig( const char *configString ) +{ + char charBuf[14]; + charBuf[13] = '\0'; + + strncpy( charBuf, configString, sizeof( charBuf ) - 1 ); + to_upper( charBuf ); + + if ( ( strcmp( charBuf, "MONO" ) == 0 ) || ( strcmp( charBuf, "HOA0" ) == 0 ) || ( strcmp( charBuf, "SBA0" ) == 0 ) ) + { + return IVAS_REND_AUDIO_CONFIG_MONO; + } + if ( ( strcmp( charBuf, "STEREO" ) == 0 ) || ( strcmp( charBuf, "CICP2" ) == 0 ) ) + { + return IVAS_REND_AUDIO_CONFIG_STEREO; + } + if ( ( strcmp( charBuf, "FOA" ) == 0 ) || ( strcmp( charBuf, "SBA1" ) == 0 ) ) + { + return IVAS_REND_AUDIO_CONFIG_FOA; + } + if ( ( strcmp( charBuf, "HOA2" ) == 0 ) || ( strcmp( charBuf, "SBA2" ) == 0 ) ) + { + return IVAS_REND_AUDIO_CONFIG_HOA2; + } + if ( ( strcmp( charBuf, "HOA3" ) == 0 ) || ( strcmp( charBuf, "SBA3" ) == 0 ) ) + { + return IVAS_REND_AUDIO_CONFIG_HOA3; + } + if ( ( strcmp( charBuf, "5_1" ) == 0 ) || ( strcmp( charBuf, "CICP6" ) == 0 ) ) + { + return IVAS_REND_AUDIO_CONFIG_5_1; + } + if ( ( strcmp( charBuf, "7_1" ) == 0 ) || ( strcmp( charBuf, "CICP12" ) == 0 ) ) + { + return IVAS_REND_AUDIO_CONFIG_7_1; + } + if ( ( strcmp( charBuf, "5_1_2" ) == 0 ) || ( strcmp( charBuf, "CICP14" ) == 0 ) ) + { + return IVAS_REND_AUDIO_CONFIG_5_1_2; + } + if ( ( strcmp( charBuf, "5_1_4" ) == 0 ) || ( strcmp( charBuf, "CICP16" ) == 0 ) ) + { + return IVAS_REND_AUDIO_CONFIG_5_1_4; + } + if ( ( strcmp( charBuf, "7_1_4" ) == 0 ) || ( strcmp( charBuf, "CICP19" ) == 0 ) ) + { + return IVAS_REND_AUDIO_CONFIG_7_1_4; + } + if ( strncmp( charBuf, "ISM", 3 ) == 0 ) + { + return IVAS_REND_AUDIO_CONFIG_OBJECT; + } + if ( strncmp( charBuf, "MASA", 4 ) == 0 ) + { + switch ( charBuf[4] ) + { + case '1': + return IVAS_REND_AUDIO_CONFIG_MASA1; + case '2': + return IVAS_REND_AUDIO_CONFIG_MASA2; + default: + return IVAS_REND_AUDIO_CONFIG_UNKNOWN; + } + } + if ( strcmp( charBuf, "BINAURAL_ROOM" ) == 0 ) + { + return IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM; + } + if ( strcmp( charBuf, "BINAURAL" ) == 0 ) + { + return IVAS_REND_AUDIO_CONFIG_BINAURAL; + } + + return IVAS_REND_AUDIO_CONFIG_UNKNOWN; +} + static CmdlnArgs defaultArgs( void ) { CmdlnArgs args; - args.inputFilePath[0] = '\0'; - args.outputFilePath[0] = '\0'; + clearString( args.inputFilePath ); + clearString( args.outputFilePath ); args.sampleRate = -1; - args.inConfig.inSetupCustom = NULL; + args.inConfig.inSetupCustom.num_spk = 0; + args.inConfig.inSetupCustom.num_lfe = 0; args.inConfig.numAudioObjects = 0; args.inConfig.numAmbisonicsBuses = 0; args.inConfig.numMultiChannelBuses = 0; args.inConfig.numMasaBuses = 0; - args.outConfig.ambisonics = IVAS_REND_AMBISONICS_NONE; - args.outConfig.speakerLayout = IVAS_REND_SPEAKER_LAYOUT_NONE; - args.outConfig.outSetupCustom = NULL; - - args.outConfig.binauralFormat = IVAS_REND_BINAURAL_NONE; + args.outConfig.audioConfig = IVAS_REND_AUDIO_CONFIG_UNKNOWN; + args.outConfig.outSetupCustom.num_spk = 0; + args.outConfig.outSetupCustom.num_lfe = 0; args.orientationTracking = IVAS_ORIENT_TRK_REF; - args.trajectoryFile[0] = '\0'; - args.customHrtfFile[0] = '\0'; - args.renderConfigFile[0] = '\0'; - - args.numAudioObjects = 0; + clearString( args.trajectoryFile ); + clearString( args.customHrtfFile ); + clearString( args.renderConfigFile ); args.noDiegeticPan = 0; - args.neverDropLfe = false; args.delayCompensationEnabled = true; args.quietModeEnabled = false; + args.sceneDescriptionInput = false; + args.inputGainGlobal = 1.0f; for ( size_t i = 0; i < RENDERER_MAX_ISM_INPUTS; i++ ) { - args.metaDataFiles[i][0] = '\0'; + clearString( args.metaDataFiles[i] ); } return args; @@ -1165,40 +1162,69 @@ typedef enum CmdLnOptionId_renderConfigFile, CmdLnOptionId_noDiegeticPan, CmdLnOptionId_orientationTracking, - CmdLnOptionId_neverDropLfe, + CmdLnOptionId_customLfeRouting, CmdLnOptionId_noDelayCmp, CmdLnOptionId_quietModeEnabled, CmdLnOptionId_inputMetadata, + CmdLnOptionId_listFormats, + CmdLnOptionId_inputGain, } CmdLnOptionId; static void parseOption( int32_t optionId, char **optionValues, int16_t numOptionValues, void *pOutputStruct ) { + ivas_error error; CmdlnArgs *args = pOutputStruct; + /* TODO(sgi): Parsing currently depends on order in which the options are given by the user. + * This causes a lot of errors and is unmaintainable for options that depend on each other. + * + * Solution: save all option values here as strings, parse strings afterwards once all values are known. + */ + switch ( optionId ) { + case CmdLnOptionId_listFormats: + /* TODO tmu2sgi : only works when -i is specified too */ + assert( numOptionValues == 0 ); + printSupportedAudioConfigs(); + exit( 0 ); case CmdLnOptionId_inputFile: assert( numOptionValues == 1 ); - strncpy( args->inputFilePath, optionValues[0], FILENAME_MAX ); + strncpy( args->inputFilePath, optionValues[0], FILENAME_MAX - 1 ); break; case CmdLnOptionId_inputFormat: - assert( numOptionValues <= RENDERER_MAX_ISM_INPUTS + 1 ); - if ( parseInFormat( optionValues, args ) != 0 ) + assert( numOptionValues == 1 ); + if ( !parseInConfig( optionValues, args ) ) { - fprintf( stderr, "Unknown input or bad config: %s\n", optionValues[0] ); + fprintf( stderr, "Error while parsing input format option\n" ); + exit( -1 ); + } + break; + case CmdLnOptionId_inputMetadata: + assert( numOptionValues <= RENDERER_MAX_ISM_INPUTS ); + if ( !parseInMetadata( optionValues, numOptionValues, args ) ) + { + fprintf( stderr, "Error while parsing input metadata option\n" ); exit( -1 ); } break; case CmdLnOptionId_outputFile: assert( numOptionValues == 1 ); - strncpy( args->outputFilePath, optionValues[0], FILENAME_MAX ); + strncpy( args->outputFilePath, optionValues[0], FILENAME_MAX - 1 ); break; case CmdLnOptionId_outputFormat: assert( numOptionValues == 1 ); - if ( parseOutConfig( optionValues[0], &args->outConfig ) != 0 ) + args->outConfig.audioConfig = parseAudioConfig( optionValues[0] ); + /* If the string provided is not recognized as a valid output config, + * it's expected to be a path to a custom loudspeaker layout description file. */ + if ( args->outConfig.audioConfig == IVAS_REND_AUDIO_CONFIG_UNKNOWN ) { - fprintf( stderr, "Unknown output or bad config: %s\n", optionValues[0] ); - exit( -1 ); + args->outConfig.audioConfig = IVAS_REND_AUDIO_CONFIG_LS_CUSTOM; + if ( ( error = parseCustomLayoutFile( optionValues[0], &args->outConfig.outSetupCustom ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Error while parsing output format option\n" ); + exit( -1 ); + } } break; case CmdLnOptionId_sampleRate: @@ -1207,15 +1233,15 @@ static void parseOption( int32_t optionId, char **optionValues, int16_t numOptio break; case CmdLnOptionId_trajFile: assert( numOptionValues == 1 ); - strncpy( args->trajectoryFile, optionValues[0], FILENAME_MAX ); + strncpy( args->trajectoryFile, optionValues[0], FILENAME_MAX - 1 ); break; case CmdLnOptionId_customHrtfFile: assert( numOptionValues == 1 ); - strncpy( args->customHrtfFile, optionValues[0], FILENAME_MAX ); + strncpy( args->customHrtfFile, optionValues[0], FILENAME_MAX - 1 ); break; case CmdLnOptionId_renderConfigFile: assert( numOptionValues == 1 ); - strncpy( args->renderConfigFile, optionValues[0], FILENAME_MAX ); + strncpy( args->renderConfigFile, optionValues[0], FILENAME_MAX - 1 ); break; case CmdLnOptionId_noDiegeticPan: assert( numOptionValues == 1 ); @@ -1233,9 +1259,8 @@ static void parseOption( int32_t optionId, char **optionValues, int16_t numOptio exit( -1 ); } break; - case CmdLnOptionId_neverDropLfe: - assert( numOptionValues == 0 ); - args->neverDropLfe = true; + case CmdLnOptionId_customLfeRouting: + assert( 0 && "Not yet implemented in CLI" ); break; case CmdLnOptionId_noDelayCmp: assert( numOptionValues == 0 ); @@ -1245,55 +1270,60 @@ static void parseOption( int32_t optionId, char **optionValues, int16_t numOptio assert( numOptionValues == 0 ); args->quietModeEnabled = true; break; + case CmdLnOptionId_inputGain: + assert( numOptionValues == 1 ); + args->inputGainGlobal = atof( optionValues[0] ); /* TODO(sgi): atof doesn't detect if string doesn't represent a number, just returns zero */ + break; default: - /* Unreachable */ + assert( 0 && "This should be unreachable - all command line options should be explicitly handled." ); break; } } static CmdlnArgs parseCmdlnArgs( int32_t argc, char **argv ) { + /* TODO tmu2sgi: "requiredness" depends on the order things are parsed in */ CmdLnParser_Option optionsToMatch[] = { { .id = CmdLnOptionId_inputFile, .match = "input_file", .matchShort = "i", - .isRequired = 1, + .isRequired = true, .description = "Path to the input file (WAV, raw PCM or scene description file)", }, { .id = CmdLnOptionId_inputFormat, .match = "input_format", .matchShort = "if", - .isRequired = 1, - // .description = "Audio format of input file (e.g. 5_1 or HOA3 or META)", /* TODO(sgi): Add additional flag for listing all available formats */ - .description = "Format of input file\nIn case of a metadata format this should be followed by a list of metadata file paths or NULL", + .isRequired = true, + .description = "Audio format of input file (e.g. 5_1 or HOA3 or META, use -l for a list)", + }, + { + /* TODO tmu2sgi : make required dependent on -if? */ + .id = CmdLnOptionId_inputMetadata, + .match = "input_metadata", + .matchShort = "im", + .description = "Space-separated list of path to metadata files for ISM or MASA inputs", }, - // { /* TODO(sgi): move metadata file paths from input_format to this separate flag */ - // .id = CmdLnOptionId_inputMetadata, - // .match = "input_metadata", - // .matchShort = "im", - // .description = "Space-separated list of path to metadata files for ISM or MASA inputs", - // }, { .id = CmdLnOptionId_outputFile, .match = "output_file", .matchShort = "o", - .isRequired = 1, + .isRequired = true, .description = "Path to the output file", }, { .id = CmdLnOptionId_outputFormat, .match = "output_format", .matchShort = "of", - .isRequired = 1, + .isRequired = true, .description = "Output format to render.\nAlternatively, can be a custom loudspeaker layout file", }, { .id = CmdLnOptionId_sampleRate, .match = "sample_rate", .matchShort = "fs", - .isRequired = 1, /* TODO(sgi): Shouldn't be required */ + .isRequired = true, /* TODO(sgi): Shouldn't be required */ .description = "Input sampling rate in kHz (16, 32, 48)", /* TODO(sgi): Add sampling rate to scene description files */ }, { @@ -1329,7 +1359,7 @@ static CmdlnArgs parseCmdlnArgs( int32_t argc, char **argv ) { /* TODO(sgi): Replace with more configurable input, e.g. ask for a list of triplets: (gain, azimuth, elevation) to place LFE signal */ /* rename to "lfeHandling" */ - .id = CmdLnOptionId_neverDropLfe, + .id = CmdLnOptionId_customLfeRouting, .match = "neverDropLfe", .matchShort = "ndl", .description = "[flag] If set, renderer tries to render LFE into other channels in an optimal way when rendering to configs w/o LFE", @@ -1346,6 +1376,18 @@ static CmdlnArgs parseCmdlnArgs( int32_t argc, char **argv ) .matchShort = "q", .description = "[flag] Limit printouts to terminal", }, + { + .id = CmdLnOptionId_inputGain, + .match = "gain", + .matchShort = "g", + .description = "Input gain (linear, not in dB) to be applied to input audio file", + }, + { + .id = CmdLnOptionId_listFormats, + .match = "list", + .matchShort = "l", + .description = "List supported audio formats", + }, }; CmdlnArgs parsedArgs = defaultArgs(); @@ -1384,7 +1426,7 @@ IsmPositionProvider *IsmPositionProvider_open( void ) void getMetadataFromFileReader( IsmFileReader *ismReader, - IVAS_REND_AudioObjectMetadataBuffer *objectMetadataBuffer, + ObjectPositionBuffer *objectMetadataBuffer, uint32_t objIdx ) { IVAS_ISM_METADATA ismMetadata; @@ -1401,7 +1443,7 @@ void getMetadataFromFileReader( } void readFromShorthandMetadata( IsmPositionProvider *positionProvider, - IVAS_REND_AudioObjectMetadataBuffer *objectMetadataBuffer, + ObjectPositionBuffer *objectMetadataBuffer, uint32_t objIdx ) { uint32_t preUpdatePositionIdx; @@ -1424,7 +1466,7 @@ void readFromShorthandMetadata( IsmPositionProvider *positionProvider, void IsmPositionProvider_getNextFrame( IsmPositionProvider *positionProvider, - IVAS_REND_AudioObjectMetadataBuffer *objectMetadataBuffer ) + ObjectPositionBuffer *objectMetadataBuffer ) { uint32_t objIdx; @@ -1559,7 +1601,7 @@ static char *readNextMetadataChunkFrom( char *start_char, char *line, const char if ( token == NULL ) { /* Clear `line` from previous contents and return NULL */ - line[0] = '\0'; + clearString( line ); return NULL; } @@ -1614,6 +1656,20 @@ static int8_t parseUint32( const char *line, uint32_t *ret ) return 0; } +static int8_t parseInt32( const char *line, int32_t *ret ) +{ + char *ptr; + ptr = NULL; + + *ret = strtol( line, &ptr, 10 ); + if ( ptr == NULL || *ptr != '\0' ) + { + return -1; + } + + return 0; +} + static void parseOptionalInputValues( char *line, float *gain_dB ) @@ -1693,7 +1749,7 @@ static void parseObjectPosition( char *line, static void parseIsm( char *line, char *inDir, - IVAS_REND_InputConfig *inConfig, + InputConfig *inConfig, IsmPositionProvider *positionProvider, int32_t idx ) { @@ -1701,7 +1757,7 @@ static void parseIsm( uint32_t i; readNextMetadataChunk( line, "\n" ); - parseUint16( line, &inConfig->audioObjects[idx].inputChannelIndex ); + parseInt32( line, &inConfig->audioObjects[idx].inputChannelIndex ); --inConfig->audioObjects[idx].inputChannelIndex; /* Convert from 1-indexing */ readNextMetadataChunk( line, "\n" ); @@ -1710,8 +1766,8 @@ static void parseIsm( if ( parseUint32( line, &numberOfObjectPositionsToRead ) == 0 ) { positionProvider->numPositions[idx] = numberOfObjectPositionsToRead; - positionProvider->positions[idx] = count_calloc( numberOfObjectPositionsToRead, sizeof( IVAS_REND_AudioObjectPosition ) ); - positionProvider->positionDurations[idx] = count_calloc( numberOfObjectPositionsToRead, sizeof( uint16_t ) ); + positionProvider->positions[idx] = count_malloc( numberOfObjectPositionsToRead * sizeof( IVAS_REND_AudioObjectPosition ) ); + positionProvider->positionDurations[idx] = count_malloc( numberOfObjectPositionsToRead * sizeof( uint16_t ) ); for ( i = 0; i < numberOfObjectPositionsToRead; ++i ) { @@ -1736,42 +1792,40 @@ static void parseIsm( } static void parseSba( char *line, - IVAS_REND_InputConfig *inConfig, + InputConfig *inConfig, int32_t idx ) { uint8_t ambiOrder; readNextMetadataChunk( line, "\n" ); - parseUint8( line, &inConfig->ambisonicsBuses[idx].inputChannelIndex ); + parseInt32( line, &inConfig->ambisonicsBuses[idx].inputChannelIndex ); --inConfig->ambisonicsBuses[idx].inputChannelIndex; /* Convert from 1-indexing */ readNextMetadataChunk( line, "\n" ); parseUint8( line, &ambiOrder ); - inConfig->ambisonicsBuses[idx].ambisonicsConfig = ambisonicsOrderToEnum( ambiOrder ); + inConfig->ambisonicsBuses[idx].audioConfig = ambisonicsOrderToEnum( ambiOrder ); /* Read optional values */ parseOptionalInputValues( line, &inConfig->ambisonicsBuses[idx].gain_dB ); } static void parseMc( char *line, - IVAS_REND_InputConfig *inConfig, + InputConfig *inConfig, int32_t idx ) { - AUDIO_CONFIG cfg; - readNextMetadataChunk( line, "\n" ); - parseUint8( line, &inConfig->multiChannelBuses[idx].inputChannelIndex ); + parseInt32( line, &inConfig->multiChannelBuses[idx].inputChannelIndex ); --inConfig->multiChannelBuses[idx].inputChannelIndex; /* Convert from 1-indexing */ readNextMetadataChunk( line, "\n" ); - cfg = parseStrToAudioCfg( line ); - if ( cfg == AUDIO_CONFIG_LS_CUSTOM ) + IVAS_REND_AudioConfig cfg = parseAudioConfig( line ); + if ( cfg == IVAS_REND_AUDIO_CONFIG_LS_CUSTOM ) { parseCustomLayoutFile( line, &inConfig->inSetupCustom ); } else { - inConfig->multiChannelBuses[idx].speakerLayout = audioCfgToMcEnum( cfg ); + inConfig->multiChannelBuses[idx].audioConfig = cfg; } /* Read optional values */ @@ -1780,13 +1834,11 @@ static void parseMc( char *line, static void parseMasa( char *line, - IVAS_REND_InputConfig *inConfig, + InputConfig *inConfig, char *masaMetadataFilePath ) { - AUDIO_CONFIG cfg; - readNextMetadataChunk( line, "\n" ); - parseUint8( line, &inConfig->masaBus.inputChannelIndex ); + parseInt32( line, &inConfig->masaBus.inputChannelIndex ); --inConfig->masaBus.inputChannelIndex; /* Convert from 1-indexing */ readNextMetadataChunk( line, "\n" ); @@ -1798,8 +1850,7 @@ static void parseMasa( sprintf( line, "MASA%c", numTcs ); } - cfg = parseStrToAudioCfg( line ); - inConfig->masaBus.numTc = audioCfgToMasaEnum( cfg ); + inConfig->masaBus.audioConfig = parseAudioConfig( line ); readNextMetadataChunk( line, "\n" ); strcpy( masaMetadataFilePath, line ); @@ -1808,49 +1859,41 @@ static void parseMasa( parseOptionalInputValues( line, &inConfig->masaBus.gain_dB ); } -static void parseCustomLayoutFile( +static ivas_error parseCustomLayoutFile( char *filePath, - IVAS_LSSETUP_CUSTOM_HANDLE *hLsSetupCustom ) + IVAS_CUSTOM_LS_DATA *pLsSetupCustom ) { - int16_t i, is_planar; - LsCustomFileReader *hLsCustomReader = NULL; IVAS_CUSTOM_LS_DATA hLsCustomData; + ivas_error error; - IVAS_REND_OpenCustomLayout( hLsSetupCustom ); - CustomLsReader_open( filePath, &hLsCustomReader ); - if ( CustomLsFileReading( hLsCustomReader, &hLsCustomData ) != LS_CUSTOM_FILEREADER_NO_ERROR ) + if ( ( error = CustomLsReader_open( filePath, &hLsCustomReader ) ) != IVAS_ERR_OK ) { - fprintf( stderr, "Error while reading custom loudspeaker layout file\n" ); - exit( -1 ); + return error; } - ( *hLsSetupCustom )->num_spk = hLsCustomData.num_spk; - mvr2r( hLsCustomData.azimuth, ( *hLsSetupCustom )->ls_azimuth, hLsCustomData.num_spk ); - mvr2r( hLsCustomData.elevation, ( *hLsSetupCustom )->ls_elevation, hLsCustomData.num_spk ); - - /* Set planar flag */ - is_planar = 1; - for ( i = 0; i < hLsCustomData.num_spk; i++ ) + if ( CustomLsFileReading( hLsCustomReader, &hLsCustomData ) != LS_CUSTOM_FILEREADER_NO_ERROR ) { - if ( is_planar && ( *hLsSetupCustom )->ls_elevation[i] != 0.0f ) - { - is_planar = 0; - } + return error; } - ( *hLsSetupCustom )->is_planar_setup = is_planar; + + pLsSetupCustom->num_spk = hLsCustomData.num_spk; + mvr2r( hLsCustomData.azimuth, pLsSetupCustom->azimuth, hLsCustomData.num_spk ); + mvr2r( hLsCustomData.elevation, pLsSetupCustom->elevation, hLsCustomData.num_spk ); /* Loudspeaker LFE */ - ( *hLsSetupCustom )->num_lfe = hLsCustomData.num_lfe; - mvs2s( hLsCustomData.lfe_idx, ( *hLsSetupCustom )->lfe_idx, hLsCustomData.num_lfe ); + pLsSetupCustom->num_lfe = hLsCustomData.num_lfe; + mvs2s( hLsCustomData.lfe_idx, pLsSetupCustom->lfe_idx, hLsCustomData.num_lfe ); CustomLsReader_close( &hLsCustomReader ); + + return IVAS_ERR_OK; } static void parseMetadata( char *metadataString, char *inDir, - IVAS_REND_InputConfig *inConfig, + InputConfig *inConfig, IsmPositionProvider *positionProvider, char *masaMetadataFilePath ) { @@ -1965,7 +2008,7 @@ static void parseMetadata( } } -void parseConfigFile( char *path, char *audioFilePath, IVAS_REND_InputConfig *inConfig, IsmPositionProvider *positionProvider, char *masaMetadataFilePath ) +static void parseConfigFile( char *path, char *audioFilePath, InputConfig *inConfig, IsmPositionProvider *positionProvider, char *masaMetadataFilePath ) { uint32_t inAudioFilePathLen; char inAudioFilePath[FILENAME_MAX]; @@ -1975,7 +2018,7 @@ void parseConfigFile( char *path, char *audioFilePath, IVAS_REND_InputConfig *in char inDir[FILENAME_MAX]; char *lastSlash = NULL; - inMasaFilePath[0] = '\0'; + clearString( inMasaFilePath ); inAudioFilePathLen = FILENAME_MAX; mtdStrLen = RENDERER_MAX_METADATA_LENGTH; splitConfigFile( path, @@ -2011,6 +2054,34 @@ void parseConfigFile( char *path, char *audioFilePath, IVAS_REND_InputConfig *in } } +static void printSupportedAudioConfigs() +{ + uint32_t i; + const char *supportedFormats[] = { + "MONO", + "STEREO", + "5_1", + "5_1_2", + "5_1_4", + "7_1", + "7_1_4", + "Path to Custom Loudspeaker .txt file", + "FOA", + "HOA2", + "HOA3", + "ISMx (input only)", + "MASAx (input only)", + "BINAURAL (output only)", + "BINAURAL_ROOM (output only)", + }; + + fprintf( stdout, "Supported audio formats:\n" ); + for ( i = 0; i < sizeof( supportedFormats ) / sizeof( *supportedFormats ); i++ ) + { + fprintf( stdout, "%s\n", supportedFormats[i] ); + } +} + static void convert_backslash( char *str ) { int i, len; @@ -2032,8 +2103,6 @@ static void convert_backslash( char *str ) } #endif } - - return; } static void remove_cr( char *str ) @@ -2047,8 +2116,11 @@ static void remove_cr( char *str ) strcpy( pos, pos + 1 ); pos = strchr( pos, '\r' ); } +} - return; +static void clearString( char *str ) +{ + str[0] = '\0'; } /*--------------------------------------------------------------------------* diff --git a/lib_com/common_api_types.h b/lib_com/common_api_types.h index c27b7bc628..85ff059120 100644 --- a/lib_com/common_api_types.h +++ b/lib_com/common_api_types.h @@ -47,6 +47,9 @@ #define IVAS_MAX_NUM_OBJECTS 4 #define IVAS_MAX_OUTPUT_CHANNELS 16 #define IVAS_CLDFB_NO_CHANNELS_MAX ( 60 ) +#ifdef EXT_RENDERER +#define IVAS_MAX_INPUT_LFE_CHANNELS 4 +#endif /*----------------------------------------------------------------------------------* * Common API structures @@ -76,7 +79,7 @@ typedef struct _IVAS_ISM_METADATA float gainFactor; } IVAS_ISM_METADATA; -typedef struct _IVAS_QUATERNION +typedef struct { float w, x, y, z; @@ -124,7 +127,6 @@ typedef struct _IVAS_LS_CUSTOM_LAYOUT float elevation[IVAS_MAX_OUTPUT_CHANNELS]; int16_t num_lfe; int16_t lfe_idx[IVAS_MAX_OUTPUT_CHANNELS]; - } IVAS_CUSTOM_LS_DATA; typedef struct ivas_LS_setup_custom *IVAS_LSSETUP_CUSTOM_HANDLE; diff --git a/lib_com/ivas_cnst.h b/lib_com/ivas_cnst.h index 43b60566dc..2d466e829d 100644 --- a/lib_com/ivas_cnst.h +++ b/lib_com/ivas_cnst.h @@ -110,7 +110,6 @@ typedef enum #ifdef EXT_RENDERER /* TODO tmu : temporary, or use something like IVAS_ENC input format */ AUDIO_CONFIG_MASA1, /* MASA1 */ AUDIO_CONFIG_MASA2, /* MASA2 */ - AUDIO_CONFIG_META, /* scene description */ #endif AUDIO_CONFIG_EXTERNAL /* external renderer */ @@ -1183,11 +1182,7 @@ typedef enum *----------------------------------------------------------------------------------*/ #define MC_LS_SETUP_BITS 3 /* number of bits for writing the MC LS configuration */ -#ifdef EXT_RENDERER -#define LS_SETUP_CONVERSION_NUM_MAPPINGS 37 /* number of mappings for LS setup conversion */ -#else #define LS_SETUP_CONVERSION_NUM_MAPPINGS 35 /* number of mappings for LS setup conversion */ -#endif typedef enum { @@ -1393,12 +1388,21 @@ typedef enum #define BINAURAL_COHERENCE_DIFFERENCE_BINS 9 /* Number of bins for direction-dependent diffuse-field binaural coherence */ +#ifdef EXT_RENDERER +#define HEADROT_ORDER 3 +#define HEADROT_SHMAT_DIM ( ( HEADROT_ORDER + 1 ) * ( HEADROT_ORDER + 1 ) ) +#define HEADROT_SHMAT_DIM2 ( HEADROT_SHMAT_DIM * HEADROT_SHMAT_DIM ) +#endif /*----------------------------------------------------------------------------------* * TD Binaural Object renderer *----------------------------------------------------------------------------------*/ +#ifdef EXT_RENDERER +#define MAX_NUM_TDREND_CHANNELS 16 /* max. number of channels in TD renderer (objects or loudspeaker channels) */ +#else #define MAX_NUM_TDREND_CHANNELS 11 /* max. number of channels in TD renderer (objects or loudspeaker channels) */ +#endif #define SFX_SPAT_BIN_MAX_NO_OF_OUTPUT_SAMPLES 288 /* 288 = 6 msec @ 48 kHz. */ #define HRTF_MODEL_N_SECTIONS 3 /* No. sections used in approximate evaluation of model */ diff --git a/lib_com/ivas_error.h b/lib_com/ivas_error.h index 58c45ee5ee..8168a6c6d6 100644 --- a/lib_com/ivas_error.h +++ b/lib_com/ivas_error.h @@ -59,7 +59,7 @@ typedef enum IVAS_ERR_INVALID_CICP_INDEX, IVAS_ERR_INVALID_BITRATE, IVAS_ERR_INVALID_MASA_CONFIG, - IVAS_ERR_TOO_MANY_OBJECT_INPUTS, + IVAS_ERR_TOO_MANY_INPUTS, IVAS_ERR_INDEX_OUT_OF_BOUNDS, IVAS_ERR_RECONFIGURE_NOT_SUPPORTED, IVAS_ERR_INVALID_FEC_CONFIG, @@ -86,6 +86,13 @@ typedef enum IVAS_ERR_FILE_READER_TIMESTAMP_MISMATCH, IVAS_ERR_ISM_FILE_READER_INVALID_METADATA_FORMAT, IVAS_ERR_INVALID_MASA_FORMAT_METADATA_FILE, +#ifdef EXT_RENDERER + IVAS_ERR_NUM_CHANNELS_UNKNOWN, + IVAS_ERR_INVALID_CUSTOM_LS_LAYOUT, + IVAS_ERR_INVALID_INPUT_ID, + IVAS_ERR_WRONG_NUM_CHANNELS, + IVAS_ERR_INVALID_BUFFER_SIZE, +#endif /*----------------------------------------* * input data errors * @@ -125,17 +132,6 @@ typedef enum static inline const char *ivas_error_to_string( ivas_error error_code ) { - /* For error categories that are likely to still have many changes to - * specific error codes, return one string per category */ - if ( ( error_code & 0xF000 ) == 0x1000 ) - { - return "API error"; - } - if ( ( error_code & 0xF000 ) == 0x2000 ) - { - return "data error"; - } - /* For categories that are unlikely to change, use more specific strings */ switch ( error_code ) { @@ -147,6 +143,20 @@ static inline const char *ivas_error_to_string( ivas_error error_code ) return "Internal error"; case IVAS_ERR_INTERNAL_FATAL: return "Internal fatal error"; +#ifdef EXT_RENDERER + case IVAS_ERR_INVALID_SAMPLING_RATE: + return "Invalid sampling rate"; + case IVAS_ERR_INVALID_OUTPUT_FORMAT: + return "Invalid output format"; + case IVAS_ERR_INVALID_CUSTOM_LS_LAYOUT: + return "Invalid custom loudspeaker layout"; + case IVAS_ERR_INVALID_INPUT_ID: + return "Invalid input ID"; + case IVAS_ERR_WRONG_NUM_CHANNELS: + return "Wrong number of channels"; + case IVAS_ERR_INVALID_BUFFER_SIZE: + return "Invalid buffer size"; +#endif case IVAS_ERR_FAILED_FILE_OPEN: return "File open error"; case IVAS_ERR_FAILED_FILE_WRITE: @@ -161,6 +171,17 @@ static inline const char *ivas_error_to_string( ivas_error error_code ) break; } + /* For error categories that are likely to still have many changes to + * specific error codes, return one string per category */ + if ( ( error_code & 0xF000 ) == 0x1000 ) + { + return "API error"; + } + if ( ( error_code & 0xF000 ) == 0x2000 ) + { + return "data error"; + } + return "Unknown error"; } diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index b5bcfd5fb1..d5dd9de613 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -4505,17 +4505,33 @@ void ivas_binaural_add_LFE( ); void QuatToRotMat( +#ifdef EXT_RENDERER + const IVAS_QUATERNION quat, /* i : quaternion describing the rotation */ +#else const Quaternion quat, /* i : quaternion describing the rotation */ +#endif float Rmat[3][3] /* o : real-space rotation matrix for this rotation */ ); void Quat2Euler( +#ifdef EXT_RENDERER + const IVAS_QUATERNION quat, /* i : quaternion describing the rotation */ +#else const Quaternion quat, /* i : quaternion describing the rotation */ +#endif float *yaw, /* o : yaw */ float *pitch, /* o : pitch */ float *roll /* o : roll */ ); +#ifdef EXT_RENDERER +void SHrotmatgen( + float SHrotmat[SBA_NHARM_HOA3][SBA_NHARM_HOA3], /* o : SHD rotation matrix */ + float Rmat[3][3], /* i : real-space rotation matrix */ + const int16_t order /* i : ambisonics order */ +); +#endif + void rotateAziEle( float azi_in, /* i : output elevation */ float ele_in, /* i : input elevation */ @@ -4724,7 +4740,7 @@ ivas_error ivas_ls_custom_output_init( void ivas_ls_custom_setup( IVAS_OUTPUT_SETUP_HANDLE hOutSetup, /* o : IVAS output setup handle */ - const LSSETUP_CUSTOM_HANDLE hLsSetupCustom /* i : Custom loudspeaker setup handle */ + const LSSETUP_CUSTOM_STRUCT *hLsSetupCustom /* i : Custom loudspeaker setup handle */ ); diff --git a/lib_com/options.h b/lib_com/options.h old mode 100644 new mode 100755 index e3ead5c21a..f19a2579e6 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -146,7 +146,7 @@ #define FADE_TO_ZERO_FOR_TOO_LONG_FRAMELOSS /*#define FIX_I1_113*/ /* under review : MCT bit distribution optimization for SBA high bitrates*/ -#define FIX_I106_TDREND_5MS /* Issue 106: 5 ms update rate in TD object renderer */ +// #define FIX_I106_TDREND_5MS /* Issue 106: 5 ms update rate in TD object renderer */ #define ALIGN_SID_SIZE /* Issue 111: make all DTX modes use one SID frame bitrate (5.2 kbps) */ #define FIX_135_MDCT_STEREO_MODE_UNINITIALIZED /* Issue 135: fix uninitialized value usage in SBA MDCT-Stereo core with PLC */ #define FIX_CONTROLLABLE_SID_UPDATE_RATE /* Issue 117: fix controllable SID update rate mechanism */ @@ -155,7 +155,6 @@ #define HARMONIZE_SBA_NCHAN_TRANSPORT /* harmonize setting of number of transport channels in SBA */ #define DRAM_REDUCTION_MCT_IGF /* Issue 121: reduce dynamic RAM consumption in MCT IGF */ - #define EXT_RENDERER /* FhG: external renderer library and standalone application */ #define FIX_EFAP_MATH /* fix for EFAP: remove angle quantization and a bug in polygon lookup causing incorrect gains. minor tweak for ALLRAD. non-BE for modes using EFAP */ /* ################## End DEVELOPMENT switches ######################### */ diff --git a/lib_dec/ivas_sba_dec.c b/lib_dec/ivas_sba_dec.c index 6d91bd23f4..40f0e361f0 100644 --- a/lib_dec/ivas_sba_dec.c +++ b/lib_dec/ivas_sba_dec.c @@ -562,6 +562,7 @@ ivas_error ivas_sba_dec_reconfigure( return error; } + /*-------------------------------------------------------------------* * ivas_sba_upmixer_renderer() * @@ -569,9 +570,9 @@ ivas_error ivas_sba_dec_reconfigure( *-------------------------------------------------------------------*/ void ivas_sba_upmixer_renderer( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder struct */ - float output[][L_FRAME48k], /* i/o: transport/output audio channels */ - const int16_t output_frame /* i : output frame length */ + Decoder_Struct *st_ivas, /* i/o: IVAS decoder struct */ + float output[][L_FRAME48k], /* i/o: transport/output audio channels */ + const int16_t output_frame /* i : output frame length */ ) { int16_t i, nchan_internal; diff --git a/lib_dec/ivas_stat_dec.h b/lib_dec/ivas_stat_dec.h index f653dcc010..d2d430bf55 100644 --- a/lib_dec/ivas_stat_dec.h +++ b/lib_dec/ivas_stat_dec.h @@ -40,6 +40,9 @@ #include "ivas_cnst.h" #include "ivas_stat_com.h" #include "ivas_stat_rend.h" +#ifdef EXT_RENDERER +#include "common_api_types.h" +#endif /*----------------------------------------------------------------------------------* @@ -1293,17 +1296,23 @@ typedef struct ivas_binaural_rendering_struct * Head tracking data structure *----------------------------------------------------------------------------------*/ +#ifdef EXT_RENDERER /* Quaternion type for head orientation */ typedef struct Quaternion_struct { float w, x, y, z; } Quaternion; +#endif typedef struct ivas_binaural_head_track_struct { int16_t num_quaternions; +#ifdef EXT_RENDERER + IVAS_QUATERNION Quaternions[MAX_PARAM_SPATIAL_SUBFRAMES]; +#else Quaternion Quaternions[MAX_PARAM_SPATIAL_SUBFRAMES]; +#endif float Rmat[3][3]; float Rmat_prev[3][3]; diff --git a/lib_enc/ivas_stereo_mdct_core_enc.c b/lib_enc/ivas_stereo_mdct_core_enc.c old mode 100644 new mode 100755 diff --git a/lib_enc/lib_enc.c b/lib_enc/lib_enc.c index 0525c7c1db..e8df931141 100755 --- a/lib_enc/lib_enc.c +++ b/lib_enc/lib_enc.c @@ -374,7 +374,7 @@ ivas_error IVAS_ENC_ConfigureForObjects( if ( numObjects > MAX_NUM_OBJECTS ) { - return IVAS_ERR_TOO_MANY_OBJECT_INPUTS; + return IVAS_ERR_TOO_MANY_INPUTS; } st_ivas = hIvasEnc->st_ivas; @@ -1356,7 +1356,7 @@ const char *IVAS_ENC_GetErrorMessage( return "invalid bitrate"; case IVAS_ERR_INVALID_MASA_CONFIG: return "invalid MASA config"; - case IVAS_ERR_TOO_MANY_OBJECT_INPUTS: + case IVAS_ERR_TOO_MANY_INPUTS: return "too many object inputs provided"; case IVAS_ERR_INDEX_OUT_OF_BOUNDS: return "index out of bounds"; diff --git a/lib_rend/ivas_crend.c b/lib_rend/ivas_crend.c index 785678535f..555a183605 100644 --- a/lib_rend/ivas_crend.c +++ b/lib_rend/ivas_crend.c @@ -31,14 +31,18 @@ *******************************************************************************************************/ #include +#include #include "options.h" #include "prot.h" #include "ivas_prot.h" #include "ivas_cnst.h" #include "ivas_rom_rend.h" #include "ivas_stat_dec.h" -#include #include "ivas_rom_binaural_crend_head.h" +#ifdef EXT_RENDERER +#include "lib_rend.h" +#include "ivas_lib_rend_internal.h" +#endif #ifdef DEBUGGING #include "debug.h" #endif @@ -1139,3 +1143,850 @@ ivas_error ivas_crend_process( return IVAS_ERR_OK; } + +#ifdef EXT_RENDERER + +/*------------------------------------------------------------------------- + * ivas_rend_openCrend() + * + * Allocate and initialize crend renderer handle + *------------------------------------------------------------------------*/ + +ivas_error ivas_rend_openCrend( + CREND_WRAPPER *pCrend, + IVAS_REND_AudioConfig inConfig, + IVAS_REND_AudioConfig outConfig, + int32_t output_Fs ) +{ + /* TODO tmu : Based on ivas_crend_open() - could be harmonized / refactored */ + int16_t i, subframe_length; + int16_t max_total_ir_len; + HRTFS_HANDLE hHrtf; + CREND_HANDLE hCrend; + ivas_error error; + + error = IVAS_ERR_OK; + subframe_length = (int16_t) ( output_Fs / FRAMES_PER_SEC ) / MAX_PARAM_SPATIAL_SUBFRAMES; + + if ( pCrend->hHrtfCrend == NULL ) + { + if ( ( error = ivas_rend_initCrend( pCrend, inConfig, outConfig, output_Fs ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + if ( ( hCrend = (CREND_HANDLE) count_malloc( sizeof( CREND_DATA ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for renderer handle" ); + } + + hCrend->lfe_delay_line = NULL; + +#ifdef FIX_CREND_CHANNELS + for ( i = 0; i < MAX_TRANSPORT_CHANNELS; i++ ) +#else + for ( i = 0; i < IVAS_MAX_NUM_CH; i++ ) +#endif + { + hCrend->freq_buffer_re[i] = NULL; + hCrend->freq_buffer_im[i] = NULL; + } + + for ( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + hCrend->prev_out_buffer[i] = NULL; + } + + hCrend->freq_buffer_re_diffuse = NULL; + hCrend->freq_buffer_im_diffuse = NULL; + hCrend->hReverb = NULL; + hCrend->delay_line_rw_index = 0; + hCrend->diffuse_delay_line_rw_index = 0; + hCrend->hTrack = NULL; + hCrend->m_fYaw = 0; + hCrend->m_fPitch = 0; + hCrend->m_fRoll = 0; + + hHrtf = pCrend->hHrtfCrend; + + if ( hHrtf != NULL ) + { + max_total_ir_len = hHrtf->max_num_iterations * subframe_length; + + for ( i = 0; i < hHrtf->max_num_ir; i++ ) + { + if ( ( hCrend->freq_buffer_re[i] = (float *) count_malloc( sizeof( float ) * max_total_ir_len ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Crend" ); + } + set_zero( hCrend->freq_buffer_re[i], max_total_ir_len ); + + if ( ( hCrend->freq_buffer_im[i] = (float *) count_malloc( sizeof( float ) * max_total_ir_len ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Crend" ); + } + set_zero( hCrend->freq_buffer_im[i], max_total_ir_len ); + } + + for ( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + if ( ( hCrend->prev_out_buffer[i] = (float *) count_malloc( sizeof( float ) * subframe_length ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Crend" ); + } + set_zero( hCrend->prev_out_buffer[i], subframe_length ); + } + + max_total_ir_len = hHrtf->num_iterations_diffuse[0] * subframe_length; + + if ( max_total_ir_len > 0 ) + { + if ( ( hCrend->freq_buffer_re_diffuse = (float *) count_malloc( sizeof( float ) * max_total_ir_len ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Crend" ); + } + set_zero( hCrend->freq_buffer_re_diffuse, max_total_ir_len ); + + if ( ( hCrend->freq_buffer_im_diffuse = (float *) count_malloc( sizeof( float ) * max_total_ir_len ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Crend" ); + } + set_zero( hCrend->freq_buffer_im_diffuse, max_total_ir_len ); + } + else + { + hCrend->freq_buffer_re_diffuse = NULL; + hCrend->freq_buffer_im_diffuse = NULL; + } + + max_total_ir_len = (int16_t) ( hHrtf->latency_s * output_Fs + 0.5f ) + subframe_length; + if ( max_total_ir_len > 0 ) + { + if ( ( hCrend->lfe_delay_line = (float *) count_malloc( sizeof( float ) * max_total_ir_len ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Crend" ); + } + set_zero( hCrend->lfe_delay_line, max_total_ir_len ); + } + else + { + hCrend->lfe_delay_line = NULL; + } + + if ( false ) /* TODO tmu : check renderer headrotation flag */ + { + if ( ( hCrend->hTrack = (ivas_orient_trk_state_t *) count_malloc( sizeof( ivas_orient_trk_state_t ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Orientation tracking" ); + } + + ivas_orient_trk_Init( hCrend->hTrack ); + } + else + { + hCrend->hTrack = NULL; + } + + /* TODO tmu : implement renderConfig */ + // if ( ( ( st_ivas->hRenderConfig != NULL ) && st_ivas->hRenderConfig->roomAcoustics.late_reverb_on ) ) + // { + // if ( ( error = ivas_reverb_open( &( hCrend->hReverb ), st_ivas->intern_config, hHrtf, st_ivas->hRenderConfig, st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK ) + // { + // return error; + // } + // } + // else + { + hCrend->hReverb = NULL; + } + + pCrend->binaural_latency_ns = (int32_t) ( pCrend->hHrtfCrend->latency_s * 1000000000.f ); + } + + pCrend->hCrend = hCrend; + return IVAS_ERR_OK; +} + +/*------------------------------------------------------------------------- + * initCrend_from_rom() + * + * Allocate and initialize crend renderer handle + *------------------------------------------------------------------------*/ + +ivas_error ivas_rend_initCrend( + CREND_WRAPPER *pCrend, + IVAS_REND_AudioConfig inConfig, + IVAS_REND_AudioConfig outConfig, + int32_t output_Fs ) +{ + int16_t i, j, tmp; + int32_t nchan_in; + bool use_brir; + IVAS_REND_AudioConfigType inConfigType; + HRTFS_HANDLE hHrtf; + ivas_error error; + + inConfigType = getAudioConfigType( inConfig ); + hHrtf = pCrend->hHrtfCrend; + + /* Do all error checks up front so that the nested if later is easier */ + if ( inConfigType != IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED && inConfigType != IVAS_REND_AUDIO_CONFIG_TYPE_AMBISONICS ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Encountered unsupported input config in Crend" ); + } + if ( outConfig != IVAS_REND_AUDIO_CONFIG_BINAURAL && outConfig != IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Encountered unsupported output type in Crend" ); + } + if ( hHrtf == NULL ) + { + if ( ivas_hrtf_open( &hHrtf ) != IVAS_ERR_OK ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Could not allocate memory for HRTF handle" ); + } + } + + /* set BRIR flag */ + use_brir = false; + /* TODO tmu : pass down render config handle */ + // if ((pCrend->hRenderConfig != NULL && pCrend->hRenderConfig->roomAcoustics.use_brir) || outConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM ) + if ( outConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM ) + { + use_brir = true; + } + + + if ( ( error = getAudioConfigNumChannels( inConfig, &nchan_in ) ) != IVAS_ERR_OK ) + { + return error; + } + hHrtf->max_num_ir = nchan_in; + + if ( hHrtf->max_num_ir <= 0 ) + { + return IVAS_ERR_INTERNAL_FATAL; + } + + + if ( inConfigType == IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED ) + { + hHrtf->max_num_ir -= 1; /* subtract LFE */ + hHrtf->gain_lfe = GAIN_LFE; + + if ( output_Fs == 48000 ) + { + if ( use_brir ) + { + hHrtf->latency_s = CRendBin_Combined_BRIR_latency_s_48kHz; + hHrtf->max_num_iterations = CRendBin_Combined_BRIR_max_num_iterations_48kHz; + hHrtf->index_frequency_max_diffuse = CRendBin_Combined_BRIR_index_frequency_max_diffuse_48kHz; + } + else + { + hHrtf->latency_s = CRendBin_Combined_HRIR_latency_s_48kHz; + hHrtf->max_num_iterations = CRendBin_Combined_HRIR_max_num_iterations_48kHz; + hHrtf->index_frequency_max_diffuse = CRendBin_Combined_HRIR_index_frequency_max_diffuse_48kHz; + } + + for ( j = 0; j < BINAURAL_CHANNELS; j++ ) + { + if ( use_brir ) + { + hHrtf->num_iterations_diffuse[j] = CRendBin_Combined_BRIR_num_iterations_diffuse_48kHz[j]; + hHrtf->pIndex_frequency_max_diffuse[j] = CRendBin_Combined_BRIR_pIndex_frequency_max_diffuse_48kHz[j]; + hHrtf->pOut_to_bin_diffuse_re[j] = CRendBin_Combined_BRIR_coeff_diffuse_re_48kHz[j]; + hHrtf->pOut_to_bin_diffuse_im[j] = CRendBin_Combined_BRIR_coeff_diffuse_im_48kHz[j]; + } + else + { + hHrtf->num_iterations_diffuse[j] = CRendBin_Combined_HRIR_num_iterations_diffuse_48kHz[j]; + hHrtf->pIndex_frequency_max_diffuse[j] = CRendBin_Combined_HRIR_pIndex_frequency_max_diffuse_48kHz[j]; + hHrtf->pOut_to_bin_diffuse_re[j] = CRendBin_Combined_HRIR_coeff_diffuse_re_48kHz[j]; + hHrtf->pOut_to_bin_diffuse_im[j] = CRendBin_Combined_HRIR_coeff_diffuse_im_48kHz[j]; + } + } + } + else if ( output_Fs == 32000 ) + { + if ( use_brir ) + { + hHrtf->latency_s = CRendBin_Combined_BRIR_latency_s_32kHz; + hHrtf->max_num_iterations = CRendBin_Combined_BRIR_max_num_iterations_32kHz; + hHrtf->index_frequency_max_diffuse = CRendBin_Combined_BRIR_index_frequency_max_diffuse_32kHz; + } + else + { + hHrtf->latency_s = CRendBin_Combined_HRIR_latency_s_32kHz; + hHrtf->max_num_iterations = CRendBin_Combined_HRIR_max_num_iterations_32kHz; + hHrtf->index_frequency_max_diffuse = CRendBin_Combined_HRIR_index_frequency_max_diffuse_32kHz; + } + + for ( j = 0; j < BINAURAL_CHANNELS; j++ ) + { + if ( use_brir ) + { + hHrtf->num_iterations_diffuse[j] = CRendBin_Combined_BRIR_num_iterations_diffuse_32kHz[j]; + hHrtf->pIndex_frequency_max_diffuse[j] = CRendBin_Combined_BRIR_pIndex_frequency_max_diffuse_32kHz[j]; + hHrtf->pOut_to_bin_diffuse_re[j] = CRendBin_Combined_BRIR_coeff_diffuse_re_32kHz[j]; + hHrtf->pOut_to_bin_diffuse_im[j] = CRendBin_Combined_BRIR_coeff_diffuse_im_32kHz[j]; + } + else + { + hHrtf->num_iterations_diffuse[j] = CRendBin_Combined_HRIR_num_iterations_diffuse_32kHz[j]; + hHrtf->pIndex_frequency_max_diffuse[j] = CRendBin_Combined_HRIR_pIndex_frequency_max_diffuse_32kHz[j]; + hHrtf->pOut_to_bin_diffuse_re[j] = CRendBin_Combined_HRIR_coeff_diffuse_re_32kHz[j]; + hHrtf->pOut_to_bin_diffuse_im[j] = CRendBin_Combined_HRIR_coeff_diffuse_im_32kHz[j]; + } + } + } + else if ( output_Fs == 16000 ) + { + if ( use_brir ) + { + hHrtf->latency_s = CRendBin_Combined_BRIR_latency_s_16kHz; + hHrtf->max_num_iterations = CRendBin_Combined_BRIR_max_num_iterations_16kHz; + hHrtf->index_frequency_max_diffuse = CRendBin_Combined_BRIR_index_frequency_max_diffuse_16kHz; + } + else + { + hHrtf->latency_s = CRendBin_Combined_HRIR_latency_s_16kHz; + hHrtf->max_num_iterations = CRendBin_Combined_HRIR_max_num_iterations_16kHz; + hHrtf->index_frequency_max_diffuse = CRendBin_Combined_HRIR_index_frequency_max_diffuse_16kHz; + } + + for ( j = 0; j < BINAURAL_CHANNELS; j++ ) + { + if ( use_brir ) + { + hHrtf->num_iterations_diffuse[j] = CRendBin_Combined_BRIR_num_iterations_diffuse_16kHz[j]; + hHrtf->pIndex_frequency_max_diffuse[j] = CRendBin_Combined_BRIR_pIndex_frequency_max_diffuse_16kHz[j]; + hHrtf->pOut_to_bin_diffuse_re[j] = CRendBin_Combined_BRIR_coeff_diffuse_re_16kHz[j]; + hHrtf->pOut_to_bin_diffuse_im[j] = CRendBin_Combined_BRIR_coeff_diffuse_im_16kHz[j]; + } + else + { + hHrtf->num_iterations_diffuse[j] = CRendBin_Combined_HRIR_num_iterations_diffuse_16kHz[j]; + hHrtf->pIndex_frequency_max_diffuse[j] = CRendBin_Combined_HRIR_pIndex_frequency_max_diffuse_16kHz[j]; + hHrtf->pOut_to_bin_diffuse_re[j] = CRendBin_Combined_HRIR_coeff_diffuse_re_16kHz[j]; + hHrtf->pOut_to_bin_diffuse_im[j] = CRendBin_Combined_HRIR_coeff_diffuse_im_16kHz[j]; + } + } + } + else + { + return IVAS_ERROR( IVAS_ERR_INVALID_SAMPLING_RATE, "Encountered Unsupported sampling rate in Crend" ); + } + + for ( i = 0; i < hHrtf->max_num_ir; i++ ) + { + if ( inConfig == IVAS_REND_AUDIO_CONFIG_5_1 ) + { + tmp = channelIndex_CICP6[i]; + } + else if ( inConfig == IVAS_REND_AUDIO_CONFIG_7_1 ) + { + tmp = channelIndex_CICP12[i]; + } + else if ( inConfig == IVAS_REND_AUDIO_CONFIG_5_1_2 ) + { + tmp = channelIndex_CICP14[i]; + } + else if ( inConfig == IVAS_REND_AUDIO_CONFIG_5_1_4 ) + { + tmp = channelIndex_CICP16[i]; + } + else if ( inConfig == IVAS_REND_AUDIO_CONFIG_7_1_4 ) + { + tmp = channelIndex_CICP19[i]; + } + else + { + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Error: Channel configuration not specified!\n\n" ); + } + + if ( output_Fs == 48000 ) + { + if ( use_brir ) + { + hHrtf->inv_diffuse_weight[i] = CRendBin_Combined_BRIR_inv_diffuse_weight_48kHz[tmp]; + } + else + { + hHrtf->inv_diffuse_weight[i] = CRendBin_Combined_HRIR_inv_diffuse_weight_48kHz[tmp]; + } + + for ( j = 0; j < BINAURAL_CHANNELS; j++ ) + { + if ( use_brir ) + { + hHrtf->num_iterations[i][j] = CRendBin_Combined_BRIR_num_iterations_48kHz[tmp][j]; + hHrtf->pIndex_frequency_max[i][j] = CRendBin_Combined_BRIR_pIndex_frequency_max_48kHz[tmp][j]; + hHrtf->pOut_to_bin_re[i][j] = CRendBin_Combined_BRIR_coeff_re_48kHz[tmp][j]; + hHrtf->pOut_to_bin_im[i][j] = CRendBin_Combined_BRIR_coeff_im_48kHz[tmp][j]; + } + else + { + hHrtf->num_iterations[i][j] = CRendBin_Combined_HRIR_num_iterations_48kHz[tmp][j]; + hHrtf->pIndex_frequency_max[i][j] = CRendBin_Combined_HRIR_pIndex_frequency_max_48kHz[tmp][j]; + hHrtf->pOut_to_bin_re[i][j] = CRendBin_Combined_HRIR_coeff_re_48kHz[tmp][j]; + hHrtf->pOut_to_bin_im[i][j] = CRendBin_Combined_HRIR_coeff_im_48kHz[tmp][j]; + } + } + } + else if ( output_Fs == 32000 ) + { + if ( use_brir ) + { + hHrtf->inv_diffuse_weight[i] = CRendBin_Combined_BRIR_inv_diffuse_weight_32kHz[tmp]; + } + else + { + hHrtf->inv_diffuse_weight[i] = CRendBin_Combined_HRIR_inv_diffuse_weight_32kHz[tmp]; + } + + for ( j = 0; j < BINAURAL_CHANNELS; j++ ) + { + if ( use_brir ) + { + hHrtf->num_iterations[i][j] = CRendBin_Combined_BRIR_num_iterations_32kHz[tmp][j]; + hHrtf->pIndex_frequency_max[i][j] = CRendBin_Combined_BRIR_pIndex_frequency_max_32kHz[tmp][j]; + hHrtf->pOut_to_bin_re[i][j] = CRendBin_Combined_BRIR_coeff_re_32kHz[tmp][j]; + hHrtf->pOut_to_bin_im[i][j] = CRendBin_Combined_BRIR_coeff_im_32kHz[tmp][j]; + } + else + { + hHrtf->num_iterations[i][j] = CRendBin_Combined_HRIR_num_iterations_32kHz[tmp][j]; + hHrtf->pIndex_frequency_max[i][j] = CRendBin_Combined_HRIR_pIndex_frequency_max_32kHz[tmp][j]; + hHrtf->pOut_to_bin_re[i][j] = CRendBin_Combined_HRIR_coeff_re_32kHz[tmp][j]; + hHrtf->pOut_to_bin_im[i][j] = CRendBin_Combined_HRIR_coeff_im_32kHz[tmp][j]; + } + } + } + else if ( output_Fs == 16000 ) + { + if ( use_brir ) + { + hHrtf->inv_diffuse_weight[i] = CRendBin_Combined_BRIR_inv_diffuse_weight_16kHz[tmp]; + } + else + { + hHrtf->inv_diffuse_weight[i] = CRendBin_Combined_HRIR_inv_diffuse_weight_16kHz[tmp]; + } + + for ( j = 0; j < BINAURAL_CHANNELS; j++ ) + { + if ( use_brir ) + { + hHrtf->num_iterations[i][j] = CRendBin_Combined_BRIR_num_iterations_16kHz[tmp][j]; + hHrtf->pIndex_frequency_max[i][j] = CRendBin_Combined_BRIR_pIndex_frequency_max_16kHz[tmp][j]; + hHrtf->pOut_to_bin_re[i][j] = CRendBin_Combined_BRIR_coeff_re_16kHz[tmp][j]; + hHrtf->pOut_to_bin_im[i][j] = CRendBin_Combined_BRIR_coeff_im_16kHz[tmp][j]; + } + else + { + hHrtf->num_iterations[i][j] = CRendBin_Combined_HRIR_num_iterations_16kHz[tmp][j]; + hHrtf->pIndex_frequency_max[i][j] = CRendBin_Combined_HRIR_pIndex_frequency_max_16kHz[tmp][j]; + hHrtf->pOut_to_bin_re[i][j] = CRendBin_Combined_HRIR_coeff_re_16kHz[tmp][j]; + hHrtf->pOut_to_bin_im[i][j] = CRendBin_Combined_HRIR_coeff_im_16kHz[tmp][j]; + } + } + } + else + { + return IVAS_ERROR( IVAS_ERR_INVALID_SAMPLING_RATE, "Encountered Unsupported sampling rate in Crend" ); + } + } + } + else if ( inConfigType == IVAS_REND_AUDIO_CONFIG_TYPE_AMBISONICS ) + { + if ( output_Fs == 48000 ) + { + hHrtf->latency_s = CRendBin_HOA3_HRIR_latency_s_48kHz; + hHrtf->max_num_iterations = CRendBin_HOA3_HRIR_max_num_iterations_48kHz; + hHrtf->index_frequency_max_diffuse = CRendBin_HOA3_HRIR_index_frequency_max_diffuse_48kHz; + + for ( i = 0; i < hHrtf->max_num_ir; i++ ) + { + hHrtf->inv_diffuse_weight[i] = CRendBin_HOA3_HRIR_inv_diffuse_weight_48kHz[i]; + + for ( j = 0; j < BINAURAL_CHANNELS; j++ ) + { + hHrtf->num_iterations[i][j] = CRendBin_HOA3_HRIR_num_iterations_48kHz[i][j]; + hHrtf->pIndex_frequency_max[i][j] = CRendBin_HOA3_HRIR_pIndex_frequency_max_48kHz[i][j]; + hHrtf->pOut_to_bin_re[i][j] = CRendBin_HOA3_HRIR_coeff_re_48kHz[i][j]; + hHrtf->pOut_to_bin_im[i][j] = CRendBin_HOA3_HRIR_coeff_im_48kHz[i][j]; + } + } + for ( j = 0; j < BINAURAL_CHANNELS; j++ ) + { + hHrtf->num_iterations_diffuse[j] = CRendBin_HOA3_HRIR_num_iterations_diffuse_48kHz[j]; + hHrtf->pIndex_frequency_max_diffuse[j] = CRendBin_HOA3_HRIR_pIndex_frequency_max_diffuse_48kHz[j]; + hHrtf->pOut_to_bin_diffuse_re[j] = CRendBin_HOA3_HRIR_coeff_diffuse_re_48kHz[j]; + hHrtf->pOut_to_bin_diffuse_im[j] = CRendBin_HOA3_HRIR_coeff_diffuse_im_48kHz[j]; + } + } + else if ( output_Fs == 32000 ) + { + hHrtf->latency_s = CRendBin_HOA3_HRIR_latency_s_32kHz; + hHrtf->max_num_iterations = CRendBin_HOA3_HRIR_max_num_iterations_32kHz; + hHrtf->index_frequency_max_diffuse = CRendBin_HOA3_HRIR_index_frequency_max_diffuse_32kHz; + + for ( i = 0; i < hHrtf->max_num_ir; i++ ) + { + hHrtf->inv_diffuse_weight[i] = CRendBin_HOA3_HRIR_inv_diffuse_weight_32kHz[i]; + + for ( j = 0; j < BINAURAL_CHANNELS; j++ ) + { + hHrtf->num_iterations[i][j] = CRendBin_HOA3_HRIR_num_iterations_32kHz[i][j]; + hHrtf->pIndex_frequency_max[i][j] = CRendBin_HOA3_HRIR_pIndex_frequency_max_32kHz[i][j]; + hHrtf->pOut_to_bin_re[i][j] = CRendBin_HOA3_HRIR_coeff_re_32kHz[i][j]; + hHrtf->pOut_to_bin_im[i][j] = CRendBin_HOA3_HRIR_coeff_im_32kHz[i][j]; + } + } + + for ( j = 0; j < BINAURAL_CHANNELS; j++ ) + { + hHrtf->num_iterations_diffuse[j] = CRendBin_HOA3_HRIR_num_iterations_diffuse_32kHz[j]; + hHrtf->pIndex_frequency_max_diffuse[j] = CRendBin_HOA3_HRIR_pIndex_frequency_max_diffuse_32kHz[j]; + hHrtf->pOut_to_bin_diffuse_re[j] = CRendBin_HOA3_HRIR_coeff_diffuse_re_32kHz[j]; + hHrtf->pOut_to_bin_diffuse_im[j] = CRendBin_HOA3_HRIR_coeff_diffuse_im_32kHz[j]; + } + } + else if ( output_Fs == 16000 ) + { + hHrtf->latency_s = CRendBin_HOA3_HRIR_latency_s_16kHz; + hHrtf->max_num_iterations = CRendBin_HOA3_HRIR_max_num_iterations_16kHz; + hHrtf->index_frequency_max_diffuse = CRendBin_HOA3_HRIR_index_frequency_max_diffuse_16kHz; + + for ( i = 0; i < hHrtf->max_num_ir; i++ ) + { + hHrtf->inv_diffuse_weight[i] = CRendBin_HOA3_HRIR_inv_diffuse_weight_16kHz[i]; + + for ( j = 0; j < BINAURAL_CHANNELS; j++ ) + { + hHrtf->num_iterations[i][j] = CRendBin_HOA3_HRIR_num_iterations_16kHz[i][j]; + hHrtf->pIndex_frequency_max[i][j] = CRendBin_HOA3_HRIR_pIndex_frequency_max_16kHz[i][j]; + hHrtf->pOut_to_bin_re[i][j] = CRendBin_HOA3_HRIR_coeff_re_16kHz[i][j]; + hHrtf->pOut_to_bin_im[i][j] = CRendBin_HOA3_HRIR_coeff_im_16kHz[i][j]; + } + } + + for ( j = 0; j < BINAURAL_CHANNELS; j++ ) + { + hHrtf->num_iterations_diffuse[j] = CRendBin_HOA3_HRIR_num_iterations_diffuse_16kHz[j]; + hHrtf->pIndex_frequency_max_diffuse[j] = CRendBin_HOA3_HRIR_pIndex_frequency_max_diffuse_16kHz[j]; + hHrtf->pOut_to_bin_diffuse_re[j] = CRendBin_HOA3_HRIR_coeff_diffuse_re_16kHz[j]; + hHrtf->pOut_to_bin_diffuse_im[j] = CRendBin_HOA3_HRIR_coeff_diffuse_im_16kHz[j]; + } + } + else + { + return IVAS_ERROR( IVAS_ERR_INVALID_SAMPLING_RATE, "Encountered Unsupported sampling rate in Crend" ); + } + } + + else + { + return IVAS_ERROR( IVAS_ERR_INTERNAL, "Unsupported renderer type in Crend" ); + } + + pCrend->hHrtfCrend = hHrtf; + + return IVAS_ERR_OK; +} + +/*------------------------------------------------------------------------- + * ivas_crend_close() + * + * Deallocate Crend renderer handle + *------------------------------------------------------------------------*/ + +ivas_error ivas_rend_closeCrend( + CREND_WRAPPER *pCrend ) +{ + int16_t i; + + if ( pCrend->hHrtfCrend != NULL ) + { + ivas_hrtf_close( &pCrend->hHrtfCrend ); + } + + if ( pCrend->hCrend != NULL ) + { + +#ifdef FIX_CREND_CHANNELS + for ( i = 0; i < MAX_TRANSPORT_CHANNELS; i++ ) +#else + for ( i = 0; i < IVAS_MAX_NUM_CH; i++ ) +#endif + { + if ( pCrend->hCrend->freq_buffer_re[i] != NULL ) + { + count_free( pCrend->hCrend->freq_buffer_re[i] ); + pCrend->hCrend->freq_buffer_re[i] = NULL; + } + if ( pCrend->hCrend->freq_buffer_im[i] != NULL ) + { + count_free( pCrend->hCrend->freq_buffer_im[i] ); + pCrend->hCrend->freq_buffer_im[i] = NULL; + } + } + + for ( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + if ( pCrend->hCrend->prev_out_buffer[i] != NULL ) + { + count_free( pCrend->hCrend->prev_out_buffer[i] ); + pCrend->hCrend->prev_out_buffer[i] = NULL; + } + } + + if ( pCrend->hCrend->lfe_delay_line != NULL ) + { + count_free( pCrend->hCrend->lfe_delay_line ); + pCrend->hCrend->lfe_delay_line = NULL; + } + + if ( pCrend->hCrend->freq_buffer_re_diffuse != NULL ) + { + count_free( pCrend->hCrend->freq_buffer_re_diffuse ); + pCrend->hCrend->freq_buffer_re_diffuse = NULL; + } + + if ( pCrend->hCrend->freq_buffer_im_diffuse != NULL ) + { + count_free( pCrend->hCrend->freq_buffer_im_diffuse ); + pCrend->hCrend->freq_buffer_im_diffuse = NULL; + } + + if ( pCrend->hCrend->hTrack != NULL ) + { + count_free( pCrend->hCrend->hTrack ); + pCrend->hCrend->hTrack = NULL; + } + + ivas_reverb_close( &pCrend->hCrend->hReverb ); + + count_free( pCrend->hCrend ); + pCrend->hCrend = NULL; + } + + return IVAS_ERR_OK; +} + +/*-----------------------------------------------------------------------------------------* + * Function ivas_crend_process() + * + * Process call for IVAS Crend renderer + *-----------------------------------------------------------------------------------------*/ + +ivas_error ivas_rend_crendProcess( + const CREND_WRAPPER *pCrend, + IVAS_REND_AudioConfig inConfig, + IVAS_REND_AudioConfig outConfig, + float output[][L_FRAME48k], /* i/o: input/output audio channels */ + int32_t output_Fs ) +{ + int16_t i, subframe_idx, output_frame; + int32_t nchan_out; + float pcm_tmp[MAX_TRANSPORT_CHANNELS][L_FRAME48k]; + AUDIO_CONFIG in_config; + IVAS_REND_AudioConfigType inConfigType; + ivas_error error; + + wmops_sub_start( "ivas_crend_process" ); + + in_config = getIvasAudioConfigFromRendAudioConfig( inConfig ); + inConfigType = getAudioConfigType( inConfig ); + getAudioConfigNumChannels( outConfig, &nchan_out ); + output_frame = (int16_t) ( output_Fs / FRAMES_PER_SEC ); + + for ( subframe_idx = 0; subframe_idx < MAX_PARAM_SPATIAL_SUBFRAMES; subframe_idx++ ) + { + if ( ( inConfigType == IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED ) || ( inConfigType == IVAS_REND_AUDIO_CONFIG_TYPE_AMBISONICS ) ) + { + if ( ( error = ivas_rend_crendConvolver( pCrend, inConfig, outConfig, output, pcm_tmp, output_Fs, subframe_idx ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( pCrend->hCrend->hReverb != NULL ) + { + if ( ( error = ivas_reverb_process( pCrend->hCrend->hReverb, in_config, 1, output, pcm_tmp, subframe_idx ) ) != IVAS_ERR_OK ) + { + return error; + } + } + } + else + { + return IVAS_ERR_INVALID_INPUT_FORMAT; + } + } + + /* move to output */ + for ( i = 0; i < nchan_out; i++ ) + { + mvr2r( pcm_tmp[i], output[i], output_frame ); + } + + return IVAS_ERR_OK; +} + +/*-----------------------------------------------------------------------------------------* + * Function ivas_crend_convolver() + * + * Convolver block + *-----------------------------------------------------------------------------------------*/ + +ivas_error ivas_rend_crendConvolver( + const CREND_WRAPPER *pCrend, + IVAS_REND_AudioConfig inConfig, + IVAS_REND_AudioConfig outConfig, + float pcm_in[][L_FRAME48k], + float pcm_out[][L_FRAME48k], + int32_t output_Fs, + const int16_t i_ts ) +{ + int16_t i, j, k, m; + int16_t subframe_length, idx_in; + int16_t lfe_idx_in; + int16_t offset, offset_in, offset_diffuse; + int32_t nchan_in, nchan_out; + float *pIn; + float *pFreq_buf_re; + float *pFreq_buf_im; + float *pFreq_filt_re; + float *pFreq_filt_im; + float pOut[L_FRAME48k * 2]; + float tmp_out_re[L_FRAME48k], tmp_out_im[L_FRAME48k]; + + getAudioConfigNumChannels( inConfig, &nchan_in ); + getAudioConfigNumChannels( outConfig, &nchan_out ); + + subframe_length = (int16_t) ( output_Fs / FRAMES_PER_SEC ) / MAX_PARAM_SPATIAL_SUBFRAMES; + + lfe_idx_in = -1; + if ( getAudioConfigType( inConfig ) == IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED ) + { + if ( inConfig != IVAS_REND_AUDIO_CONFIG_LS_CUSTOM ) + { + lfe_idx_in = LFE_CHANNEL; + } + else + { + assert( 0 && "Custom LS not supported in CRend" ); + } + } + + offset = pCrend->hCrend->delay_line_rw_index * subframe_length; /* subframe_length * ( pCrend->hHrtfCrend->max_num_iterations - 1 ); */ + offset_diffuse = pCrend->hCrend->diffuse_delay_line_rw_index * subframe_length; /* subframe_length *( pCrend->hHrtfCrend->num_iterations_diffuse[0] - 1 ); */ + + if ( pCrend->hHrtfCrend->num_iterations_diffuse[0] > 0 ) + { + set_zero( &pCrend->hCrend->freq_buffer_re_diffuse[offset_diffuse], subframe_length ); + set_zero( &pCrend->hCrend->freq_buffer_im_diffuse[offset_diffuse], subframe_length ); + } + + i = 0; + for ( idx_in = 0; idx_in < nchan_in; idx_in++ ) + { + pIn = &pcm_in[idx_in][i_ts * subframe_length]; + if ( idx_in != lfe_idx_in ) + { + if ( pCrend->hHrtfCrend->num_iterations_diffuse[0] > 0 ) + { + pFreq_buf_re = &pCrend->hCrend->freq_buffer_re_diffuse[offset_diffuse]; + pFreq_buf_im = &pCrend->hCrend->freq_buffer_im_diffuse[offset_diffuse]; + pFreq_filt_re = &pCrend->hCrend->freq_buffer_re[i][offset]; + pFreq_filt_im = &pCrend->hCrend->freq_buffer_im[i][offset]; + + for ( k = 0; k < pCrend->hHrtfCrend->index_frequency_max_diffuse; k++ ) + { + pFreq_buf_re[k] += pFreq_filt_re[k] * pCrend->hHrtfCrend->inv_diffuse_weight[i]; + pFreq_buf_im[k] += pFreq_filt_im[k] * pCrend->hHrtfCrend->inv_diffuse_weight[i]; + } + } + + pFreq_buf_re = &pCrend->hCrend->freq_buffer_re[i][offset]; + pFreq_buf_im = &pCrend->hCrend->freq_buffer_im[i][offset]; + + ivas_mdft( pIn, pFreq_buf_re, pFreq_buf_im, subframe_length, subframe_length ); + i++; + } + } + + for ( j = 0; j < nchan_out; j++ ) + { + set_zero( tmp_out_re, subframe_length ); + set_zero( tmp_out_im, subframe_length ); + + i = 0; + for ( idx_in = 0; idx_in < nchan_in; idx_in++ ) + { + if ( idx_in != lfe_idx_in ) + { + offset = 0; + for ( m = 0; m < pCrend->hHrtfCrend->num_iterations[i][j]; m++ ) + { + offset_in = ( pCrend->hCrend->delay_line_rw_index + pCrend->hHrtfCrend->max_num_iterations - pCrend->hHrtfCrend->num_iterations[i][j] + m + 1 ); + offset_in = offset_in % ( pCrend->hHrtfCrend->max_num_iterations ); + offset_in = offset_in * subframe_length; + pFreq_buf_re = &pCrend->hCrend->freq_buffer_re[i][offset_in]; + pFreq_buf_im = &pCrend->hCrend->freq_buffer_im[i][offset_in]; + pFreq_filt_re = &pCrend->hHrtfCrend->pOut_to_bin_re[i][j][offset]; + pFreq_filt_im = &pCrend->hHrtfCrend->pOut_to_bin_im[i][j][offset]; + + for ( k = 0; k < pCrend->hHrtfCrend->pIndex_frequency_max[i][j][m]; k++ ) + { + tmp_out_re[k] += pFreq_buf_re[k] * pFreq_filt_re[k] - pFreq_buf_im[k] * pFreq_filt_im[k]; + tmp_out_im[k] += pFreq_buf_re[k] * pFreq_filt_im[k] + pFreq_buf_im[k] * pFreq_filt_re[k]; + } + offset = offset + k; + } + i++; + } + } + + offset = 0; + for ( m = 0; m < pCrend->hHrtfCrend->num_iterations_diffuse[j]; m++ ) + { + offset_diffuse = ( pCrend->hCrend->diffuse_delay_line_rw_index + m + 1 ); + offset_diffuse = offset_diffuse % pCrend->hHrtfCrend->num_iterations_diffuse[0]; + offset_diffuse = offset_diffuse * subframe_length; + pFreq_buf_re = &pCrend->hCrend->freq_buffer_re_diffuse[offset_diffuse]; + pFreq_buf_im = &pCrend->hCrend->freq_buffer_im_diffuse[offset_diffuse]; + pFreq_filt_re = &pCrend->hHrtfCrend->pOut_to_bin_diffuse_re[j][offset]; + pFreq_filt_im = &pCrend->hHrtfCrend->pOut_to_bin_diffuse_im[j][offset]; + + for ( k = 0; k < pCrend->hHrtfCrend->pIndex_frequency_max_diffuse[j][m]; k++ ) + { + tmp_out_re[k] += pFreq_buf_re[k] * pFreq_filt_re[k] - pFreq_buf_im[k] * pFreq_filt_im[k]; + tmp_out_im[k] += pFreq_buf_re[k] * pFreq_filt_im[k] + pFreq_buf_im[k] * pFreq_filt_re[k]; + } + offset = offset + k; + } + + ivas_imdft( tmp_out_re, tmp_out_im, pOut, subframe_length ); + + pFreq_buf_re = &pcm_out[j][i_ts * subframe_length]; + for ( k = 0; k < subframe_length; k++ ) + { + pFreq_buf_re[k] = pOut[k] + pCrend->hCrend->prev_out_buffer[j][k]; + pCrend->hCrend->prev_out_buffer[j][k] = pOut[k + subframe_length]; + } + } + + pCrend->hCrend->delay_line_rw_index++; + pCrend->hCrend->delay_line_rw_index = pCrend->hCrend->delay_line_rw_index % ( pCrend->hHrtfCrend->max_num_iterations ); + if ( pCrend->hHrtfCrend->num_iterations_diffuse[0] > 0 ) + { + pCrend->hCrend->diffuse_delay_line_rw_index++; + pCrend->hCrend->diffuse_delay_line_rw_index = pCrend->hCrend->diffuse_delay_line_rw_index % ( pCrend->hHrtfCrend->num_iterations_diffuse[0] ); + } + + return IVAS_ERR_OK; +} + +#endif diff --git a/lib_rend/ivas_lib_rend_internal.h b/lib_rend/ivas_lib_rend_internal.h new file mode 100644 index 0000000000..e82348484f --- /dev/null +++ b/lib_rend/ivas_lib_rend_internal.h @@ -0,0 +1,87 @@ +#include "ivas_error.h" +#include "lib_rend.h" +#include "ivas_stat_dec.h" + +#ifndef IVAS_LIB_REND_INTERNALS_H +#define IVAS_LIB_REND_INTERNALS_H + +typedef struct +{ + int8_t headRotEnabled; + IVAS_QUATERNION headPositions[RENDERER_HEAD_POSITIONS_PER_FRAME]; + float crossfade[L_FRAME48k / RENDERER_HEAD_POSITIONS_PER_FRAME]; +} IVAS_REND_HeadRotData; + +typedef struct +{ + int32_t binaural_latency_ns; + BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd; + TDREND_HRFILT_FiltSet_t *hHrtfTD; +} TDREND_WRAPPER; + +typedef struct +{ + int32_t binaural_latency_ns; + CREND_HANDLE hCrend; + HRTFS_HANDLE hHrtfCrend; +} CREND_WRAPPER; + +IVAS_REND_AudioConfigType getAudioConfigType( + IVAS_REND_AudioConfig config ); + +ivas_error getAudioConfigNumChannels( + IVAS_REND_AudioConfig config, + int32_t *numChannels ); + +AUDIO_CONFIG getIvasAudioConfigFromRendAudioConfig( + IVAS_REND_AudioConfig config ); + +ivas_error ivas_rend_openCrend( + CREND_WRAPPER *pCrend, + IVAS_REND_AudioConfig inConfig, + IVAS_REND_AudioConfig outConfig, + int32_t output_Fs ); + +ivas_error ivas_rend_initCrend( + CREND_WRAPPER *pCrend, + IVAS_REND_AudioConfig inConfig, + IVAS_REND_AudioConfig outConfig, + int32_t output_Fs ); + +ivas_error ivas_rend_closeCrend( + CREND_WRAPPER *pCrend ); + +ivas_error ivas_rend_crendProcess( + const CREND_WRAPPER *pCrend, + IVAS_REND_AudioConfig inConfig, + IVAS_REND_AudioConfig outConfig, + float output[][L_FRAME48k], /* i/o: input/output audio channels */ + int32_t output_Fs ); + +ivas_error ivas_rend_crendConvolver( + const CREND_WRAPPER *pCrend, + IVAS_REND_AudioConfig inConfig, + IVAS_REND_AudioConfig outConfig, + float pcm_in[][L_FRAME48k], + float pcm_out[][L_FRAME48k], + int32_t output_Fs, + const int16_t i_ts ); + +ivas_error ivas_rend_TDObjRenderFrame( + const TDREND_WRAPPER *pTDRend, /* i : TD Renderer wrapper structure */ + const IVAS_REND_AudioConfig inConfig, /* i : Input audio configuration */ + const LSSETUP_CUSTOM_STRUCT *customLsInput, /* i : Input custom loudspeaker layout */ + const IVAS_REND_HeadRotData *headRotData, /* i : Input head positions */ + const IVAS_REND_AudioObjectPosition *currentPos, /* i : Object position */ + const int16_t output_frame, /* i : output frame length */ + const int32_t output_Fs, /* i : output sampling rate */ + float output[][L_FRAME48k] /* i/o: SCE channels / Binaural synthesis */ +); + +ivas_error ivas_rend_TDObjRendOpen( + TDREND_WRAPPER *pTDRend, + IVAS_REND_AudioConfig inConfig, + LSSETUP_CUSTOM_STRUCT *customLsInput, + int32_t outFs ); + +#endif diff --git a/lib_rend/ivas_ls_custom_dec.c b/lib_rend/ivas_ls_custom_dec.c index 1d61ba0641..28bd8c1dd8 100644 --- a/lib_rend/ivas_ls_custom_dec.c +++ b/lib_rend/ivas_ls_custom_dec.c @@ -79,8 +79,8 @@ ivas_error ivas_ls_custom_open( *-------------------------------------------------------------------------*/ void ivas_ls_custom_setup( - IVAS_OUTPUT_SETUP_HANDLE hOutSetup, /* o : IVAS output setup handle */ - const LSSETUP_CUSTOM_HANDLE hLsSetupCustom /* i : Custom loudspeaker setup handle */ + IVAS_OUTPUT_SETUP_HANDLE hOutSetup, /* o : IVAS output setup handle */ + const LSSETUP_CUSTOM_STRUCT *hLsSetupCustom /* i : Custom loudspeaker setup handle */ ) { hOutSetup->output_config = AUDIO_CONFIG_LS_CUSTOM; diff --git a/lib_rend/ivas_objectRenderer.c b/lib_rend/ivas_objectRenderer.c index b4c784edfa..4a297aba55 100644 --- a/lib_rend/ivas_objectRenderer.c +++ b/lib_rend/ivas_objectRenderer.c @@ -31,12 +31,16 @@ *******************************************************************************************************/ #include +#include #include "options.h" #include "prot.h" #include "ivas_prot.h" -#include #include "wmops.h" #include "ivas_rom_com.h" +#ifdef EXT_RENDERER +#include "lib_rend.h" +#include "ivas_lib_rend_internal.h" +#endif #ifdef DEBUGGING #include "debug.h" #endif @@ -259,8 +263,8 @@ void ObjRenderIVASFrame( Pos[1] = 0.0f; Pos[2] = 0.0f; - if ( - st_ivas->hHeadTrackData != NULL + if ( + st_ivas->hHeadTrackData != NULL #ifdef EXT_RENDERER && st_ivas->hDecoderConfig->Opt_Headrotation #endif @@ -633,3 +637,296 @@ static void TDREND_Update_listener_orientation( return; } #endif + +#ifdef EXT_RENDERER + +ivas_error ivas_rend_TDObjRendOpen( + TDREND_WRAPPER *pTDRend, + IVAS_REND_AudioConfig inConfig, + LSSETUP_CUSTOM_STRUCT *customLsInput, + int32_t outFs ) +{ + /* TODO tmu : Based on ivas_td_binaural_open() - could be harmonized / refactored + - review error handling + - review hHrtfTD init + */ + BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd; + TDREND_PosType_t PosType; + int16_t nS; + int16_t SrcInd[MAX_NUM_TDREND_CHANNELS]; + const float *ls_azimuth, *ls_elevation; + float Pos[3]; + float Dir[3]; + TDREND_DirAtten_t *DirAtten_p; + int32_t nchan_rend; + ivas_error error; + + error = IVAS_ERR_OK; + + if ( ( hBinRendererTd = count_malloc( sizeof( BINAURAL_TD_OBJECT_RENDERER ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD renderer\n" ) ); + } + if ( ( hBinRendererTd->TdRend_MixSpatSpec_p = count_malloc( sizeof( TDREND_MixSpatSpec_t ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD renderer\n" ) ); + } + if ( ( hBinRendererTd->DirAtten_p = count_malloc( sizeof( TDREND_DirAtten_t ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD renderer\n" ) ); + } + if ( ( hBinRendererTd->Listener_p = count_malloc( sizeof( TDREND_MIX_Listener_t ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for TD renderer\n" ) ); + } + + if ( inConfig != IVAS_REND_AUDIO_CONFIG_LS_CUSTOM ) + { + getAudioConfigNumChannels( inConfig, &nchan_rend ); + if ( getAudioConfigType( inConfig ) == IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED ) + { + nchan_rend--; /* Skip LFE channel -- added to the others */ + } + } + else + { + nchan_rend = customLsInput->num_spk; + } + + hBinRendererTd->NumOfSrcs = 0; + hBinRendererTd->MaxSrcInd = -1; + + /* Mixer spatial setup */ + hBinRendererTd->TdRend_MixSpatSpec_p->UseCommonDistAttenModel = TRUE; + hBinRendererTd->TdRend_MixSpatSpec_p->DistAttenModel = 0; /* 0=Turned off, else use TDREND_DIST_ATTEN_MODEL_INV_DIST_CLAMPED */ + + TDREND_MIX_Init( hBinRendererTd, &pTDRend->hHrtfTD, hBinRendererTd->TdRend_MixSpatSpec_p, outFs ); + + /* Set the attenuation (or can set MixSpatSpec.DistAttenModel above) */ + TDREND_MIX_SetDistAttenModel( hBinRendererTd, TDREND_DIST_ATTEN_MODEL_INV_DIST_CLAMPED ); + + /* Add sources to module and mixer, headphones */ + PosType = TDREND_POSTYPE_ABSOLUTE; /* or TDREND_POSTYPE_RELATIVE_TO_LISTENER */ + + for ( nS = 0; nS < nchan_rend; nS++ ) + { + if ( ( error = TDREND_MIX_AddSrc( hBinRendererTd, &SrcInd[nS], PosType, outFs ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + if ( getAudioConfigType( inConfig ) == IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED ) + { + switch ( inConfig ) + { + case IVAS_REND_AUDIO_CONFIG_5_1: + ls_azimuth = ls_azimuth_CICP6; + ls_elevation = ls_elevation_CICP6; + break; + case IVAS_REND_AUDIO_CONFIG_7_1: + ls_azimuth = ls_azimuth_CICP12; + ls_elevation = ls_elevation_CICP12; + break; + case IVAS_REND_AUDIO_CONFIG_5_1_2: + ls_azimuth = ls_azimuth_CICP14; + ls_elevation = ls_elevation_CICP14; + break; + case IVAS_REND_AUDIO_CONFIG_5_1_4: + ls_azimuth = ls_azimuth_CICP16; + ls_elevation = ls_elevation_CICP16; + break; + case IVAS_REND_AUDIO_CONFIG_7_1_4: + ls_azimuth = ls_azimuth_CICP19; + ls_elevation = ls_elevation_CICP19; + break; + case IVAS_REND_AUDIO_CONFIG_LS_CUSTOM: + ls_azimuth = customLsInput->ls_azimuth; + ls_elevation = customLsInput->ls_elevation; + break; + default: + ls_azimuth = NULL; + ls_elevation = NULL; + } + + DirAtten_p = hBinRendererTd->DirAtten_p; + + for ( nS = 0; nS < nchan_rend; nS++ ) + { + /* Set source positions according to loudspeaker layout */ + Pos[0] = cosf( ls_elevation[nS] * PI_OVER_180 ) * cosf( ls_azimuth[nS] * PI_OVER_180 ); + Pos[1] = cosf( ls_elevation[nS] * PI_OVER_180 ) * sinf( ls_azimuth[nS] * PI_OVER_180 ); + Pos[2] = sinf( ls_elevation[nS] * PI_OVER_180 ); + Dir[0] = 1.0f; + Dir[1] = 0.0f; + Dir[2] = 0.0f; + + /* Source directivity info */ + DirAtten_p->ConeInnerAngle = 360.0f; + DirAtten_p->ConeOuterAngle = 360.0f; + DirAtten_p->ConeOuterGain = 1.0f; + + TDREND_MIX_SRC_SetPos( hBinRendererTd, nS, Pos ); + TDREND_MIX_SRC_SetDir( hBinRendererTd, nS, Dir ); + TDREND_MIX_SRC_SetPlayState( hBinRendererTd, nS, TDREND_PLAYSTATUS_PLAYING ); + TDREND_MIX_SRC_SetDirAtten( hBinRendererTd, nS, DirAtten_p ); + } + } + + pTDRend->hBinRendererTd = hBinRendererTd; + + pTDRend->binaural_latency_ns = (int32_t) ( BINAURAL_TD_LATENCY_S * 1000000000.f ); + + + return IVAS_ERR_OK; +} + +/*---------------------------------------------------------------------* + * ObjRenderIVASFrame() + * + * Receives the current frames for the object streams, updates metadata + * and renders the current frame. + *---------------------------------------------------------------------*/ + +/*! r: TD Renderer result code. */ +ivas_error ivas_rend_TDObjRenderFrame( + const TDREND_WRAPPER *pTDRend, /* i : TD Renderer wrapper structure */ + const IVAS_REND_AudioConfig inConfig, /* i : Input audio configuration */ + const LSSETUP_CUSTOM_STRUCT *customLsInput, /* i : Input custom loudspeaker layout */ + const IVAS_REND_HeadRotData *headRotData, /* i : Input head positions */ + const IVAS_REND_AudioObjectPosition *currentPos, /* i : Object position */ + const int16_t output_frame, /* i : output frame length */ + const int32_t output_Fs, /* i : output sampling rate */ + float output[][L_FRAME48k] /* i/o: SCE channels / Binaural synthesis */ +) +{ + TDREND_DirAtten_t *DirAtten_p; + int16_t nS; + int16_t lfe_idx; + int16_t c_indx; + int32_t nchan_in; + float Pos[3]; + float Dir[3]; + float FrontVec[3]; + float UpVec[3]; + float Rmat[3][3]; + /* TODO tmu : pass down renderer config struct */ + // float reverb_signal[BINAURAL_CHANNELS][L_FRAME48k]; + IVAS_REND_AudioConfigType inConfigType; + + inConfigType = getAudioConfigType( inConfig ); + if ( inConfig != IVAS_REND_AUDIO_CONFIG_LS_CUSTOM ) + { + lfe_idx = LFE_CHANNEL; + getAudioConfigNumChannels( inConfig, &nchan_in ); + } + else + { + lfe_idx = ( customLsInput->num_lfe > 0 ) ? customLsInput->lfe_idx[0] : -1; + nchan_in = customLsInput->num_spk + customLsInput->num_lfe; + } + + DirAtten_p = pTDRend->hBinRendererTd->DirAtten_p; + + /* Update the listener's location/orientation */ + /* Listener at the origin */ + Pos[0] = 0.0f; + Pos[1] = 0.0f; + Pos[2] = 0.0f; + + if ( headRotData->headRotEnabled ) + { + /* Obtain head rotation matrix */ + QuatToRotMat( headRotData->headPositions[0], Rmat ); + /* Apply rotation matrix to looking vector [1;0;0] */ + FrontVec[0] = Rmat[0][0]; + FrontVec[1] = Rmat[0][1]; + FrontVec[2] = Rmat[0][2]; + /* Apply rotation matrix to up vector [0;0;1] */ + UpVec[0] = Rmat[2][0]; + UpVec[1] = Rmat[2][1]; + UpVec[2] = Rmat[2][2]; + } + else + { + /* Oriented with looking vector along the x axis */ + FrontVec[0] = 1.0f; + FrontVec[1] = 0.0f; + FrontVec[2] = 0.0f; + /* Oriented with up vector along the z axis */ + UpVec[0] = 0.0f; + UpVec[1] = 0.0f; + UpVec[2] = 1.0f; + } + + /* Set the listener position and orientation:*/ + TDREND_MIX_LIST_SetPos( pTDRend->hBinRendererTd, Pos ); + TDREND_MIX_LIST_SetOrient( pTDRend->hBinRendererTd, FrontVec, UpVec ); + + /* For each source, write the frame data to the source object*/ + c_indx = 0; + for ( nS = 0; nS < nchan_in; nS++ ) + { + if ( !( inConfigType == IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED && nS == lfe_idx ) ) /* Skip LFE for MC */ + { + pTDRend->hBinRendererTd->Sources[c_indx]->InputFrame_p = output[nS]; + pTDRend->hBinRendererTd->Sources[c_indx]->SrcRend_p->InputAvailable = TRUE; + c_indx++; + } + + if ( inConfigType == IVAS_REND_AUDIO_CONFIG_TYPE_OBJECT_BASED ) + { + /* Update the source positions */ + /* Source position and direction */ + /* TODO tmu : currently will only work for one object at a time */ + Pos[0] = cosf( currentPos->elevation * PI_OVER_180 ) * cosf( currentPos->azimuth * PI_OVER_180 ); + Pos[1] = cosf( currentPos->elevation * PI_OVER_180 ) * sinf( currentPos->azimuth * PI_OVER_180 ); + Pos[2] = sinf( currentPos->elevation * PI_OVER_180 ); + Dir[0] = 1.0f; + Dir[1] = 0.0f; + Dir[2] = 0.0f; + + /* Source directivity info */ + DirAtten_p->ConeInnerAngle = 360.0f; + DirAtten_p->ConeOuterAngle = 360.0f; + DirAtten_p->ConeOuterGain = 1.0f; + + TDREND_MIX_SRC_SetPos( pTDRend->hBinRendererTd, nS, Pos ); + TDREND_MIX_SRC_SetDir( pTDRend->hBinRendererTd, nS, Dir ); + TDREND_MIX_SRC_SetDirAtten( pTDRend->hBinRendererTd, nS, DirAtten_p ); + TDREND_MIX_SRC_SetPlayState( pTDRend->hBinRendererTd, nS, TDREND_PLAYSTATUS_PLAYING ); + } + } + + /* TODO tmu : pass down renderer config struct */ + // if ( pTDRend->hRenderConfig != NULL ) /* Renderer Configuration not enabled in TD standalone renderer */ + // { + // if ( pTDRend->hRenderConfig->roomAcoustics.late_reverb_on ) + // { + // if ( pTDRend->ini_frame == 0 ) + // { + // ivas_reverb_open( &pTDRend->hCrend->hReverb, pTDRend->transport_config, NULL, pTDRend->hRenderConfig, pTDRend->hDecoderConfig->output_Fs ); + // } + // for ( subframe_idx = 0; subframe_idx < 4; subframe_idx++ ) + // { + // ivas_reverb_process( pTDRend->hCrend->hReverb, pTDRend->transport_config, 0, output, reverb_signal, subframe_idx ); + // } + // } + // } + + /* Call the renderer */ + TDREND_GetMix( pTDRend->hBinRendererTd, output, output_frame, output_Fs ); + + /* TODO tmu : pass down renderer config struct */ + // if ( pTDRend->hRenderConfig != NULL ) /* Renderer Configuration not enabled in TD standalone renderer */ + // { + // if ( pTDRend->hRenderConfig->roomAcoustics.late_reverb_on ) + // { + // /* add reverb to rendered signals */ + // v_add( reverb_signal[0], output[0], output[0], output_frame ); + // v_add( reverb_signal[1], output[1], output[1], output_frame ); + // } + // } + return IVAS_ERR_OK; +} +#endif diff --git a/lib_rend/ivas_rom_rend.c b/lib_rend/ivas_rom_rend.c index dd252a9969..100dded459 100644 --- a/lib_rend/ivas_rom_rend.c +++ b/lib_rend/ivas_rom_rend.c @@ -408,8 +408,13 @@ const float ls_conversion_cicpX_stereo[12][2] = const LS_CONVERSION_MATRIX ls_conversion_cicp12_cicp6[] = { +#ifdef EXT_RENDERER + /* First row indicates the number of non-zero elements and the number of matrix columns */ + {8, 6.0f}, +#else /* First row indicates the number of non-zero elements */ {8, 0.0f}, +#endif /* Index of non-zero element, value of non-zero element*/ {0, 1.000000000f}, {7, 1.000000000f}, @@ -423,8 +428,13 @@ const LS_CONVERSION_MATRIX ls_conversion_cicp12_cicp6[] = const LS_CONVERSION_MATRIX ls_conversion_cicp14_cicp6[] = { +#ifdef EXT_RENDERER + /* First row indicates the number of non-zero elements and the number of matrix columns */ + {8, 6.0f}, +#else /* First row indicates the number of non-zero elements */ {8, 0.0f}, +#endif /* Index of non-zero element, value of non-zero element*/ {0, 1.000000000f}, {7, 1.000000000f}, @@ -438,8 +448,13 @@ const LS_CONVERSION_MATRIX ls_conversion_cicp14_cicp6[] = const LS_CONVERSION_MATRIX ls_conversion_cicp14_cicp12[] = { +#ifdef EXT_RENDERER + /* First row indicates the number of non-zero elements and the number of matrix columns */ + {8, 8.0f}, +#else /* First row indicates the number of non-zero elements */ {8, 0.0f}, +#endif /* Index of non-zero element, value of non-zero element*/ {0, 1.000000000f}, {9, 1.000000000f}, @@ -453,8 +468,13 @@ const LS_CONVERSION_MATRIX ls_conversion_cicp14_cicp12[] = const LS_CONVERSION_MATRIX ls_conversion_cicp16_cicp6[] = { +#ifdef EXT_RENDERER + /* First row indicates the number of non-zero elements and the number of matrix columns */ + {10, 6.0f}, +#else /* First row indicates the number of non-zero elements */ {10, 0.0f}, +#endif /* Index of non-zero element, value of non-zero element*/ {0, 1.000000000f}, {7, 1.000000000f}, @@ -470,8 +490,13 @@ const LS_CONVERSION_MATRIX ls_conversion_cicp16_cicp6[] = const LS_CONVERSION_MATRIX ls_conversion_cicp16_cicp12[] = { +#ifdef EXT_RENDERER + /* First row indicates the number of non-zero elements and the number of matrix columns */ + {10, 8.0f}, +#else /* First row indicates the number of non-zero elements */ {10, 0.0f}, +#endif /* Index of non-zero element, value of non-zero element*/ {0, 1.000000000f}, {9, 1.000000000f}, @@ -488,8 +513,13 @@ const LS_CONVERSION_MATRIX ls_conversion_cicp16_cicp12[] = const LS_CONVERSION_MATRIX ls_conversion_cicp16_cicp14[] = { +#ifdef EXT_RENDERER + /* First row indicates the number of non-zero elements and the number of matrix columns */ + {10, 8.0f}, +#else /* First row indicates the number of non-zero elements */ {10, 0.0f}, +#endif /* Index of non-zero element, value of non-zero element*/ {0, 1.000000000f}, {9, 1.000000000f}, @@ -505,8 +535,13 @@ const LS_CONVERSION_MATRIX ls_conversion_cicp16_cicp14[] = const LS_CONVERSION_MATRIX ls_conversion_cicp19_cicp6[] = { +#ifdef EXT_RENDERER + /* First row indicates the number of non-zero elements and the number of matrix columns */ + {14, 6.0f}, +#else /* First row indicates the number of non-zero elements */ {14, 0.0f}, +#endif /* Index of non-zero element, value of non-zero element*/ {0, 1.000000000f}, {7, 1.000000000f}, @@ -526,8 +561,13 @@ const LS_CONVERSION_MATRIX ls_conversion_cicp19_cicp6[] = const LS_CONVERSION_MATRIX ls_conversion_cicp19_cicp12[] = { +#ifdef EXT_RENDERER + /* First row indicates the number of non-zero elements and the number of matrix columns */ + {14, 8.0f}, +#else /* First row indicates the number of non-zero elements */ {14, 0.0f}, +#endif /* Index of non-zero element, value of non-zero element*/ {0, 1.000000000f}, {9, 1.000000000f}, @@ -547,8 +587,13 @@ const LS_CONVERSION_MATRIX ls_conversion_cicp19_cicp12[] = const LS_CONVERSION_MATRIX ls_conversion_cicp19_cicp14[] = { +#ifdef EXT_RENDERER + /* First row indicates the number of non-zero elements and the number of matrix columns */ + {14, 8.0f}, +#else /* First row indicates the number of non-zero elements */ {14, 0.0f}, +#endif /* Index of non-zero element, value of non-zero element*/ {0, 1.000000000f}, {9, 1.000000000f}, @@ -568,8 +613,13 @@ const LS_CONVERSION_MATRIX ls_conversion_cicp19_cicp14[] = const LS_CONVERSION_MATRIX ls_conversion_cicp19_cicp16[] = { +#ifdef EXT_RENDERER + /* First row indicates the number of non-zero elements and the number of matrix columns */ + {14, 10.0f}, +#else /* First row indicates the number of non-zero elements */ {14, 0.0f}, +#endif /* Index of non-zero element, value of non-zero element*/ {0, 1.000000000f}, {11, 1.000000000f}, @@ -590,8 +640,13 @@ const LS_CONVERSION_MATRIX ls_conversion_cicp19_cicp16[] = /* Upmix matrices */ const LS_CONVERSION_MATRIX ls_conversion_cicp12_cicp14[] = { +#ifdef EXT_RENDERER + /* First row indicates the number of non-zero elements and the number of matrix columns */ + {8, 8.0f}, +#else /* First row indicates the number of non-zero elements */ {8, 0.0f}, +#endif /* Index of non-zero element, value of non-zero element*/ {0, 1.0f}, {9, 1.0f}, @@ -605,8 +660,13 @@ const LS_CONVERSION_MATRIX ls_conversion_cicp12_cicp14[] = const LS_CONVERSION_MATRIX ls_conversion_cicp12_cicp16[] = { +#ifdef EXT_RENDERER + /* First row indicates the number of non-zero elements and the number of matrix columns */ + {8, 10.0f}, +#else /* First row indicates the number of non-zero elements */ {8, 0.0f}, +#endif /* Index of non-zero element, value of non-zero element*/ {0, 1.0f}, {11, 1.0f}, @@ -620,8 +680,13 @@ const LS_CONVERSION_MATRIX ls_conversion_cicp12_cicp16[] = const LS_CONVERSION_MATRIX ls_conversion_cicp12_cicp19[] = { +#ifdef EXT_RENDERER + /* First row indicates the number of non-zero elements and the number of matrix columns */ + {8, 12.0f}, +#else /* First row indicates the number of non-zero elements */ {8, 0.0f}, +#endif /* Index of non-zero element, value of non-zero element*/ {0, 1.0f}, {13, 1.0f}, @@ -635,8 +700,13 @@ const LS_CONVERSION_MATRIX ls_conversion_cicp12_cicp19[] = const LS_CONVERSION_MATRIX ls_conversion_cicp14_cicp19[] = { +#ifdef EXT_RENDERER + /* First row indicates the number of non-zero elements and the number of matrix columns */ + {8, 12.0f}, +#else /* First row indicates the number of non-zero elements */ {8, 0.0f}, +#endif /* Index of non-zero element, value of non-zero element*/ {0, 1.0f}, {13, 1.0f}, @@ -650,8 +720,13 @@ const LS_CONVERSION_MATRIX ls_conversion_cicp14_cicp19[] = const LS_CONVERSION_MATRIX ls_conversion_cicp16_cicp19[] = { +#ifdef EXT_RENDERER + /* First row indicates the number of non-zero elements and the number of matrix columns */ + {10, 12.0f}, +#else /* First row indicates the number of non-zero elements */ {10, 0.0f}, +#endif /* Index of non-zero element, value of non-zero element*/ {0, 1.0f}, {13, 1.0f}, @@ -673,9 +748,6 @@ const LS_CONVERSION_MATRIX ls_conversion_cicp16_cicp19[] = const LS_CONVERSION_MAPPING ls_conversion_mapping[LS_SETUP_CONVERSION_NUM_MAPPINGS] = { /* Dowmix mappings - NULL is a special case for MONO / STEREO downmix */ -#ifdef EXT_RENDERER - {AUDIO_CONFIG_STEREO, AUDIO_CONFIG_MONO, NULL}, -#endif {AUDIO_CONFIG_5_1, AUDIO_CONFIG_MONO, NULL}, {AUDIO_CONFIG_7_1, AUDIO_CONFIG_MONO, NULL}, {AUDIO_CONFIG_5_1_2, AUDIO_CONFIG_MONO, NULL}, @@ -703,9 +775,6 @@ const LS_CONVERSION_MAPPING ls_conversion_mapping[LS_SETUP_CONVERSION_NUM_MAPPIN {AUDIO_CONFIG_7_1_4, AUDIO_CONFIG_5_1_4, ls_conversion_cicp19_cicp16}, /* Upmix mappings - NULL implies a 1:1 upmix */ -#ifdef EXT_RENDERER - {AUDIO_CONFIG_MONO, AUDIO_CONFIG_STEREO, NULL}, -#endif {AUDIO_CONFIG_STEREO, AUDIO_CONFIG_5_1, NULL}, {AUDIO_CONFIG_STEREO, AUDIO_CONFIG_7_1, NULL}, {AUDIO_CONFIG_STEREO, AUDIO_CONFIG_5_1_2, NULL}, diff --git a/lib_rend/ivas_rom_rend.h b/lib_rend/ivas_rom_rend.h index 166e417692..aaf7fa7113 100644 --- a/lib_rend/ivas_rom_rend.h +++ b/lib_rend/ivas_rom_rend.h @@ -33,8 +33,8 @@ #ifndef IVAS_ROM_REND_H #define IVAS_ROM_REND_H -#include #include "options.h" +#include #ifdef DEBUGGING #include "debug.h" #endif diff --git a/lib_rend/ivas_rotation.c b/lib_rend/ivas_rotation.c index 49c937844c..372930616f 100644 --- a/lib_rend/ivas_rotation.c +++ b/lib_rend/ivas_rotation.c @@ -45,7 +45,7 @@ #endif #include "wmops.h" - +#ifndef EXT_RENDERER /*-----------------------------------------------------------------------* * Local Constants *-----------------------------------------------------------------------*/ @@ -54,13 +54,12 @@ #define HEADROT_SHMAT_DIM ( HEADROT_ORDER + 1 ) * ( HEADROT_ORDER + 1 ) #define HEADROT_SHMAT_DIM2 HEADROT_SHMAT_DIM *HEADROT_SHMAT_DIM - /*-----------------------------------------------------------------------* * Local Function prototypes *-----------------------------------------------------------------------*/ static void SHrotmatgen( float SHrotmat[HEADROT_SHMAT_DIM][HEADROT_SHMAT_DIM], float Rmat[3][3], const int16_t order ); - +#endif /*-----------------------------------------------------------------------* * ivas_headTrack_open() @@ -104,8 +103,12 @@ ivas_error ivas_headTrack_open( *---------------------------------------------------------------------------------*/ void QuatToRotMat( +#ifdef EXT_RENDERER + const IVAS_QUATERNION quat, /* i : quaternion describing the rotation */ +#else const Quaternion quat, /* i : quaternion describing the rotation */ - float Rmat[3][3] /* o : real-space rotation matrix for this rotation */ +#endif + float Rmat[3][3] /* o : real-space rotation matrix for this rotation */ ) { float s1, s2, s3, c1, c2, c3; @@ -173,10 +176,14 @@ void QuatToRotMat( *------------------------------------------------------------------------*/ void Quat2Euler( +#ifdef EXT_RENDERER + const IVAS_QUATERNION quat, /* i : quaternion describing the rotation */ +#else const Quaternion quat, /* i : quaternion describing the rotation */ - float *yaw, /* o : yaw */ - float *pitch, /* o : pitch */ - float *roll /* o : roll */ +#endif + float *yaw, /* o : yaw */ + float *pitch, /* o : pitch */ + float *roll /* o : roll */ ) { if ( quat.w != -3.0 ) @@ -927,7 +934,7 @@ static float SHrot_w( } } -static void SHrotmatgen( + void SHrotmatgen( float SHrotmat[HEADROT_SHMAT_DIM][HEADROT_SHMAT_DIM], /* o : rotation matrix in SHD */ float Rmat[3][3], /* i : real-space rotation matrix */ const int16_t order /* i : ambisonics order */ diff --git a/lib_rend/ivas_sba_rendering.c b/lib_rend/ivas_sba_rendering.c old mode 100644 new mode 100755 index f8790c16e3..ad098109b1 --- a/lib_rend/ivas_sba_rendering.c +++ b/lib_rend/ivas_sba_rendering.c @@ -153,7 +153,7 @@ void ivas_sba2mc_cldfb( float ImagBuffer[][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX], /* i/o: cldfb imag part */ const int16_t nb_channels_out, /* i : nb of output channels */ const int16_t nb_bands, /* i : nb of CLDFB bands to process */ - const float *hoa_dec_mtx /* i : hoa decoding mtx */ + const float *hoa_dec_mtx /* i : HOA decoding mtx */ ) { int16_t iBlock, iBand, n, m; @@ -239,7 +239,7 @@ int16_t ivas_sba_remapTCs( nchan_remapped++; if ( st_ivas->sba_mode != SBA_MODE_SPAR ) { - assert( ( ( st_ivas->nchan_transport == 3 ) || ( st_ivas->nchan_transport == 5 ) || ( st_ivas->nchan_transport == 7 ) ) && "Number of channels must be odd for sba planar!" ); + assert( ( ( st_ivas->nchan_transport == 3 ) || ( st_ivas->nchan_transport == 5 ) || ( st_ivas->nchan_transport == 7 ) ) && "Number of channels must be odd for SBA planar!" ); } if ( nchan_remapped == 4 ) @@ -468,6 +468,8 @@ void ivas_ism2sba( return; } + + /*-------------------------------------------------------------------* * ivas_sba_linear_renderer() * @@ -480,7 +482,7 @@ ivas_error ivas_sba_linear_renderer( const int16_t nchan_in, /* i : number of input ambisonics channels */ const AUDIO_CONFIG output_config, /* i : output audio configuration */ const IVAS_OUTPUT_SETUP output_setup, /* i : output format setup */ - const float hoa_dec_mtx[] /* i : hoa decoding mtx */ + const float hoa_dec_mtx[] /* i : HOA decoding mtx */ ) { int16_t i; diff --git a/lib_rend/ivas_stat_rend.h b/lib_rend/ivas_stat_rend.h index 7c4841a08a..21b5e3be29 100644 --- a/lib_rend/ivas_stat_rend.h +++ b/lib_rend/ivas_stat_rend.h @@ -36,6 +36,7 @@ #include #include "ivas_cnst.h" +#define MAX_SPEAKERS 12 /* Max number of speakers (including LFE) in a channel-based config */ /*----------------------------------------------------------------------------------* * Loudspeaker Configuration Conversion structure @@ -90,4 +91,11 @@ typedef struct ivas_LS_setup_custom } LSSETUP_CUSTOM_STRUCT, *LSSETUP_CUSTOM_HANDLE; +/* Channel types in a channel-based config */ +typedef enum { + CHANNEL_TYPE_UNUSED = 0, + CHANNEL_TYPE_SPEAKER, + CHANNEL_TYPE_LFE +} ChannelType; + #endif /* IVAS_STAT_REND_H */ diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index 9658883460..2499b34a39 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -31,3160 +31,3973 @@ *******************************************************************************************************/ #include "options.h" +#include "ivas_cnst.h" #include "lib_rend.h" #include "ivas_prot.h" #include "ivas_rom_com.h" #include "ivas_rom_dec.h" #include "ivas_rom_rend.h" +#include "ivas_lib_rend_internal.h" #include "prot.h" #include "wmops.h" #include #include +#include #include #include #include +/* 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 ) + +/* Maximum buffer length (total) in samples. */ +#define MAX_BUFFER_LENGTH ( MAX_BUFFER_LENGTH_PER_CHANNEL * MAX_INPUT_CHANNELS ) + +/* Frame size required when rendering to binaural */ +#define BINAURAL_RENDERING_FRAME_SIZE_MS 20 #define LIMITER_THRESHOLD ( 0.9988493699f * INT16_MAX ) /* -0.01 dBFS */ -/* Due to API of some rendering methods, the renderer has to use the decoder struct. - Only struct members relevant for rendering will be initialized, therefore typedef as "dummy" decoder struct */ -typedef Decoder_Struct DecoderDummy; +typedef float pan_vector[MAX_OUTPUT_CHANNELS]; +typedef float pan_matrix[MAX_INPUT_CHANNELS][MAX_OUTPUT_CHANNELS]; +typedef float rotation_gains[MAX_INPUT_CHANNELS][MAX_INPUT_CHANNELS]; +typedef float rotation_matrix[3][3]; + +/* EFAP wrapper to simplify writing panning gains to a vector that includes LFE channels */ +typedef struct +{ + EFAP_HANDLE hEfap; + IVAS_REND_AudioConfig 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 IVAS_REND_AudioConfig *pOutConfig; + const LSSETUP_CUSTOM_STRUCT *pCustomLsOut; + const EFAP_WRAPPER *pEfapOutWrapper; + const IVAS_REND_HeadRotData *pHeadRotData; +} rendering_context; + +/* Common base for input structs */ +typedef struct +{ + IVAS_REND_AudioConfig inConfig; + IVAS_REND_InputId id; + IVAS_REND_AudioBuffer inputBuffer; + float bufferData[MAX_BUFFER_LENGTH]; + 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; + IVAS_REND_AudioObjectPosition currentPos; + IVAS_REND_AudioObjectPosition previousPos; + TDREND_WRAPPER tdRendWrapper; + CREND_WRAPPER crendWrapper; + rotation_matrix rot_mat_prev; +} input_ism; + +typedef struct +{ + input_base base; + + /* Full panning matrix. 1st index is input channel, 2nd index is output channel. + All LFE channels should be included, both for inputs and outputs */ + pan_matrix panGains; + + LSSETUP_CUSTOM_STRUCT customLsInput; + EFAP_WRAPPER efapInWrapper; + TDREND_WRAPPER tdRendWrapper; + CREND_WRAPPER crendWrapper; + rotation_gains rot_gains_prev; + IVAS_REND_LfeRouting lfeRouting; +} input_mc; + +typedef struct +{ + input_base base; + pan_matrix hoaDecMtx; + CREND_WRAPPER crendWrapper; + rotation_gains rot_gains_prev; +} input_sba; struct IVAS_REND { - int32_t sampleRate; + 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]; - int8_t isConfigured; /* flag */ - int8_t firstFrame; /* flag */ + IVAS_REND_AudioConfig outputConfig; + EFAP_WRAPPER efapOutWrapper; + IVAS_LSSETUP_CUSTOM_STRUCT customLsOut; + IVAS_REND_HeadRotData headRotData; +}; - /* I/O */ - IVAS_REND_InputConfig inConfig; - IVAS_REND_OutputConfig outConfig; +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 */ +); - /* =========== Panning =========== */ - EFAP_HANDLE efapRenderer; +static IVAS_QUATERNION quaternionInit( void ) +{ + IVAS_QUATERNION q; + q.w = 1.0f; + q.x = q.y = q.z = 0.0f; + return q; +} - IVAS_REND_ObjPanInfo *objPanInfo; /* size: [numInObjects] */ +static float *getSmplPtr( IVAS_REND_AudioBuffer buffer, uint32_t chnlIdx, uint32_t smplIdx ) +{ + return buffer.data + chnlIdx * buffer.config.numSamplesPerChannel + smplIdx; +} - float ***speakerPanGains; /* size: [numInMc][numSpeakers][numOutChannels] */ +static void copyBufferTo2dArray( const IVAS_REND_AudioBuffer buffer, float array[MAX_OUTPUT_CHANNELS][L_FRAME48k] ) +{ + uint32_t smplIdx; + uint32_t chnlIdx; + const float *readPtr; - float *tmpGainBuffer; /* size: [numOutChannels] */ - float *noLfePanBuffer; /* size: [numOutChannels] */ - float *crossfade; /* size: [frameSize] */ - /* =============================== */ + readPtr = buffer.data; - /* Helpers */ - int16_t numOutChannels; /* Total number of output channels */ - int16_t numInChannels; /* Total number of input channels */ - int16_t numInChannelsObj; /* Total number of input channels of object inputs */ - int16_t numInChannelsAmbi; /* Total number of input channels of ambisonics inputs */ - int16_t numInChannelsMc; /* Total number of input channels of multichannel inputs */ - int16_t numInChannelsMasa; /* Total number of input channels of MASA inputs */ - float delayOffsetBuffer[MAX_OUTPUT_CHANNELS][NS2SA( 48000, IVAS_FB_DEC_DELAY_NS )]; /* Buffer for delay compensation */ + for ( chnlIdx = 0; chnlIdx < (uint32_t) buffer.config.numChannels; ++chnlIdx ) + { + for ( smplIdx = 0; smplIdx < (uint32_t) buffer.config.numSamplesPerChannel; ++smplIdx ) + { + array[chnlIdx][smplIdx] = *readPtr++; + } + } +} - /* For each channel of MC inputs mcPassThrough contains the corresponding - * output channel index if a passthrough is possible, otherwise contains -1 */ - int32_t *mcPassthrough; /* size: [numInChannelsMc] */ +static void accumulate2dArrayToBuffer( float array[MAX_OUTPUT_CHANNELS][L_FRAME48k], IVAS_REND_AudioBuffer *buffer ) +{ + int32_t smplIdx, chnlIdx; + float *writePtr; - /* =========== LFE Handling =========== */ - /* Do not drop LFE when rendering to a layout that does not have - * an LFE channel - render LFE into other channels*/ - int8_t neverDropLfe; /* flag */ - int8_t forceBinLfeLpf; /* flag : force low-pass filtering for LFE channel in binaural rendering */ - float *lfePanGains; - ivas_filters_process_state_t lfeLpFilter; + writePtr = buffer->data; + for ( chnlIdx = 0; chnlIdx < buffer->config.numChannels; ++chnlIdx ) + { + for ( smplIdx = 0; smplIdx < buffer->config.numSamplesPerChannel; ++smplIdx ) + { + *writePtr++ += array[chnlIdx][smplIdx]; + } + } +} - /* =========== limiter handle =========== */ - IVAS_LIMITER_HANDLE hLimiter; +/*-------------------------------------------------------------------* + * limitRendererOutput() + * + * In-place saturation control for multichannel buffers with adaptive release time + * + * 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 - int32_t numClipping; /* Counter of clipped output samples */ + if ( output[i] < INT16_MIN || output[i] > INT16_MAX ) + { + ++numClipping; + } #endif - /* Ambisonics decoding matrix */ - float *ambi_dec_mtx; + output[i] = min( max( INT16_MIN, output[i] ), INT16_MAX ); + } - /* =========== MASA rendering handles/structs =========== */ - MASA_METADATA_FRAME masaMetadata; /* TODO @ Nokia: add more MASA related handles here if needed */ + return numClipping; +} - /* Dummy decoders for binaural rendering */ - DecoderDummy *decDummyAmbiBin; - DecoderDummy *decDummyObjBin; - DecoderDummy *decDummyMcBin; - DecoderDummy *decDummyMasaBin; +static AUDIO_CONFIG rendAudioConfigToIvasAudioConfig( IVAS_REND_AudioConfig rendConfig ) +{ + switch ( rendConfig ) + { + case IVAS_REND_AUDIO_CONFIG_MONO: + return AUDIO_CONFIG_MONO; + case IVAS_REND_AUDIO_CONFIG_STEREO: + return AUDIO_CONFIG_STEREO; + case IVAS_REND_AUDIO_CONFIG_5_1: + return AUDIO_CONFIG_5_1; + case IVAS_REND_AUDIO_CONFIG_7_1: + return AUDIO_CONFIG_7_1; + case IVAS_REND_AUDIO_CONFIG_5_1_2: + return AUDIO_CONFIG_5_1_2; + case IVAS_REND_AUDIO_CONFIG_5_1_4: + return AUDIO_CONFIG_5_1_4; + case IVAS_REND_AUDIO_CONFIG_7_1_4: + return AUDIO_CONFIG_7_1_4; + case IVAS_REND_AUDIO_CONFIG_LS_CUSTOM: + return AUDIO_CONFIG_LS_CUSTOM; + case IVAS_REND_AUDIO_CONFIG_FOA: + return AUDIO_CONFIG_FOA; + case IVAS_REND_AUDIO_CONFIG_HOA2: + return AUDIO_CONFIG_HOA2; + case IVAS_REND_AUDIO_CONFIG_HOA3: + return AUDIO_CONFIG_HOA3; + case IVAS_REND_AUDIO_CONFIG_OBJECT: + return AUDIO_CONFIG_OBA; + case IVAS_REND_AUDIO_CONFIG_BINAURAL: + return AUDIO_CONFIG_BINAURAL; + case IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM: + return AUDIO_CONFIG_BINAURAL_ROOM; + case IVAS_REND_AUDIO_CONFIG_MASA1: + return AUDIO_CONFIG_MASA1; + case IVAS_REND_AUDIO_CONFIG_MASA2: + return AUDIO_CONFIG_MASA2; + default: + break; + } - /* Head rotation data */ - int8_t enableHeadRotation; /* head rotation flag */ - IVAS_QUATERNION headRotationData[RENDERER_HEAD_POSITIONS_PER_FRAME]; + return AUDIO_CONFIG_INVALID; +} - /* Configurable rendering */ - int8_t rendererConfigEnabled; -}; +static ivas_error validateOutputAudioConfig( IVAS_REND_AudioConfig outConfig ) +{ + switch ( outConfig ) + { + case IVAS_REND_AUDIO_CONFIG_MONO: + case IVAS_REND_AUDIO_CONFIG_STEREO: + case IVAS_REND_AUDIO_CONFIG_5_1: + case IVAS_REND_AUDIO_CONFIG_7_1: + case IVAS_REND_AUDIO_CONFIG_5_1_2: + case IVAS_REND_AUDIO_CONFIG_5_1_4: + case IVAS_REND_AUDIO_CONFIG_7_1_4: + case IVAS_REND_AUDIO_CONFIG_LS_CUSTOM: + case IVAS_REND_AUDIO_CONFIG_FOA: + case IVAS_REND_AUDIO_CONFIG_HOA2: + case IVAS_REND_AUDIO_CONFIG_HOA3: + case IVAS_REND_AUDIO_CONFIG_BINAURAL: + case IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM: + return IVAS_ERR_OK; + default: + break; + } -/*---------------------------------------------------------------------* - * Prototypes - *---------------------------------------------------------------------*/ -/* clang-off */ -static void renderAmbiToAmbi( - const IVAS_REND_HANDLE st, - const IVAS_REND_AudioBuffer inAudio, - IVAS_REND_AudioBuffer outAudio ); + return IVAS_ERR_INVALID_OUTPUT_FORMAT; +} -static void renderChannelsToAmbi( - IVAS_REND_HANDLE st, - const IVAS_REND_AudioBuffer inAudio, - IVAS_REND_AudioBuffer outAudio ); +IVAS_REND_AudioConfigType getAudioConfigType( IVAS_REND_AudioConfig config ) +{ + /* By definition, config type is the second byte (from LSB) of IVAS_REND_AudioConfig enum. */ + return ( config & 0xFF00 ) >> 8; +} -static void renderObjectsToAmbi( - IVAS_REND_HANDLE st, - const IVAS_REND_AudioBuffer inAudio, - const IVAS_REND_AudioObjectMetadataBuffer metadataBuffer, - IVAS_REND_AudioBuffer outAudio ); +static ivas_error validateOutputSampleRate( int32_t sampleRate, IVAS_REND_AudioConfig outConfig ) +{ + if ( getAudioConfigType( outConfig ) != IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL ) + { + /* If no binaural rendering, any sampling rate is supported */ + return IVAS_ERR_OK; + } -static void renderMasaToAmbi( - IVAS_REND_HANDLE st, - const IVAS_REND_AudioBuffer inAudio, - IVAS_REND_AudioBuffer outAudio ); + /* 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; + } -static void renderAmbiToChannels( - const IVAS_REND_HANDLE st, - const IVAS_REND_AudioBuffer inAudio, - IVAS_REND_AudioBuffer outAudio ); + return IVAS_ERR_INVALID_SAMPLING_RATE; +} -static void renderChannelsToChannels( - const IVAS_REND_HANDLE st, - const IVAS_REND_AudioBuffer inAudio, - IVAS_REND_AudioBuffer outAudio ); +ivas_error getAudioConfigNumChannels( IVAS_REND_AudioConfig config, int32_t *numChannels ) +{ + switch ( config ) + { + case IVAS_REND_AUDIO_CONFIG_MONO: + case IVAS_REND_AUDIO_CONFIG_OBJECT: + *numChannels = 1; + break; + case IVAS_REND_AUDIO_CONFIG_STEREO: + case IVAS_REND_AUDIO_CONFIG_BINAURAL: + case IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM: + *numChannels = 2; + break; + case IVAS_REND_AUDIO_CONFIG_FOA: + *numChannels = 4; + break; + case IVAS_REND_AUDIO_CONFIG_5_1: + *numChannels = 6; + break; + case IVAS_REND_AUDIO_CONFIG_7_1: + case IVAS_REND_AUDIO_CONFIG_5_1_2: + *numChannels = 8; + break; + case IVAS_REND_AUDIO_CONFIG_HOA2: + *numChannels = 9; + break; + case IVAS_REND_AUDIO_CONFIG_5_1_4: + *numChannels = 10; + break; + case IVAS_REND_AUDIO_CONFIG_7_1_4: + *numChannels = 12; + break; + case IVAS_REND_AUDIO_CONFIG_HOA3: + *numChannels = 16; + break; + default: + return IVAS_ERR_NUM_CHANNELS_UNKNOWN; + } -static void renderObjectsToChannels( - IVAS_REND_HANDLE st, - const IVAS_REND_AudioBuffer inAudio, - const IVAS_REND_AudioObjectMetadataBuffer metadataBuffer, - IVAS_REND_AudioBuffer outAudio ); + return IVAS_ERR_OK; +} -static void renderMasaToChannels( - IVAS_REND_HANDLE st, - const IVAS_REND_AudioBuffer inAudio, - IVAS_REND_AudioBuffer outAudio ); +AUDIO_CONFIG getIvasAudioConfigFromRendAudioConfig( IVAS_REND_AudioConfig config ) +{ + switch ( config ) + { + case IVAS_REND_AUDIO_CONFIG_MONO: + return AUDIO_CONFIG_MONO; + case IVAS_REND_AUDIO_CONFIG_STEREO: + return AUDIO_CONFIG_STEREO; + case IVAS_REND_AUDIO_CONFIG_BINAURAL: + return AUDIO_CONFIG_BINAURAL; + case IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM: + return AUDIO_CONFIG_BINAURAL_ROOM; + case IVAS_REND_AUDIO_CONFIG_5_1: + return AUDIO_CONFIG_5_1; + case IVAS_REND_AUDIO_CONFIG_7_1: + return AUDIO_CONFIG_7_1; + case IVAS_REND_AUDIO_CONFIG_5_1_2: + return AUDIO_CONFIG_5_1_2; + case IVAS_REND_AUDIO_CONFIG_5_1_4: + return AUDIO_CONFIG_5_1_4; + case IVAS_REND_AUDIO_CONFIG_7_1_4: + return AUDIO_CONFIG_7_1_4; + case IVAS_REND_AUDIO_CONFIG_FOA: + return AUDIO_CONFIG_FOA; + case IVAS_REND_AUDIO_CONFIG_HOA2: + return AUDIO_CONFIG_HOA2; + case IVAS_REND_AUDIO_CONFIG_HOA3: + return AUDIO_CONFIG_HOA3; + default: + return AUDIO_CONFIG_INVALID; + } -static void renderAmbiToBinaural( - const IVAS_REND_HANDLE st, - const IVAS_REND_AudioBuffer inAudio, - IVAS_REND_AudioBuffer outAudio ); + return AUDIO_CONFIG_INVALID; +} -static void renderChannelsToBinaural( - const IVAS_REND_HANDLE st, - const IVAS_REND_AudioBuffer inAudio, - IVAS_REND_AudioBuffer outAudio ); +static ivas_error initLimiter( IVAS_LIMITER_HANDLE *phLimiter, int32_t numChannels, int32_t sampleRate ) +{ + /* If re-initializing with unchanged values, return early */ + if ( *phLimiter != NULL && + ( *phLimiter )->num_channels == numChannels && + ( *phLimiter )->sampling_rate == sampleRate ) + { + return IVAS_ERR_OK; + } -static void renderObjectsToBinaural( - IVAS_REND_HANDLE st, - const IVAS_REND_AudioBuffer inAudio, - const IVAS_REND_AudioObjectMetadataBuffer metadataBuffer, - IVAS_REND_AudioBuffer outAudio ); + /* Support re-init: close if already allocated */ + if ( *phLimiter != NULL ) + { + ivas_limiter_close( phLimiter ); + } -static void renderMasaToBinaural( - IVAS_REND_HANDLE st, - const IVAS_REND_AudioBuffer inAudio, - IVAS_REND_AudioBuffer outAudio ); + *phLimiter = ivas_limiter_open( (int16_t) numChannels, sampleRate ); + if ( *phLimiter == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Failed to open limiter" ); + } -static void renderSingleObjectToAmbi( - IVAS_REND_HANDLE st, - const IVAS_REND_AudioBuffer inAudio, - const uint32_t itemChnlIdx, /* Index of the item within input audio buffer */ - IVAS_REND_ObjPanInfo *prevPanInfo, - const IVAS_REND_AudioObjectPosition curFrmPos, - const float gain_lin, - IVAS_REND_AudioBuffer outAudio ); - -static void renderSingleObjectToChannels( - IVAS_REND_HANDLE st, - const IVAS_REND_AudioBuffer inAudio, - const uint32_t itemChnlIdx, /* Index of the item within input audio buffer */ - IVAS_REND_ObjPanInfo *prevPanInfo, - const IVAS_REND_AudioObjectPosition curFrmPos, - const float gain_lin, - IVAS_REND_AudioBuffer outAudio ); - -/* Multiply a single channel by a vector of gains and add result to corresponding output channels */ -static void applyChannelGainsAndAddToOutput( - const IVAS_REND_AudioBuffer inAudio, - const uint32_t itemChnlIdx, /* Index of the item within input audio buffer */ - const float *const gainsCurrent, /* Vector of gains for current frame, corresponding to output channels */ - const float *const gainsPrev, /* Vector of previously applied gains, used for interpolation. Set to NULL for no interpolation */ - const float gain_lin, /* Additional linear gain to be applied when mixing with output buffer */ - const float *const crossfade, - IVAS_REND_AudioBuffer outAudio ); + return IVAS_ERR_OK; +} + +static LSSETUP_CUSTOM_STRUCT defaultCustomLs( void ) +{ + LSSETUP_CUSTOM_STRUCT ls; + + /* Set mono by default. This simplifies initialization, + since output config is never in an undefined state. */ + ls.is_planar_setup = 1; + ls.num_spk = 1; + set_zero( ls.ls_azimuth, MAX_OUTPUT_CHANNELS ); + set_zero( ls.ls_elevation, MAX_OUTPUT_CHANNELS ); + ls.num_lfe = 0; + set_s( ls.lfe_idx, 0, MAX_OUTPUT_CHANNELS ); + ls.separate_ch_found = 0; + set_f( ls.separate_ch_gains, 0, MAX_OUTPUT_CHANNELS ); + + return ls; +} -static void prepareMcPanGains( - IVAS_REND_HANDLE st ); +static ivas_error getSpeakerAzimuths( IVAS_REND_AudioConfig config, const float **azimuths ) +{ + switch ( config ) + { + case IVAS_REND_AUDIO_CONFIG_MONO: + *azimuths = ls_azimuth_CICP1; + break; + case IVAS_REND_AUDIO_CONFIG_STEREO: + *azimuths = ls_azimuth_CICP2; + break; + case IVAS_REND_AUDIO_CONFIG_5_1: + *azimuths = ls_azimuth_CICP6; + break; + case IVAS_REND_AUDIO_CONFIG_7_1: + *azimuths = ls_azimuth_CICP12; + break; + case IVAS_REND_AUDIO_CONFIG_5_1_2: + *azimuths = ls_azimuth_CICP14; + break; + case IVAS_REND_AUDIO_CONFIG_5_1_4: + *azimuths = ls_azimuth_CICP16; + break; + case IVAS_REND_AUDIO_CONFIG_7_1_4: + *azimuths = ls_azimuth_CICP19; + break; + default: + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Unexpected audio config" ); + } -static void prepareLfeHandling( - IVAS_REND_HANDLE st ); + return IVAS_ERR_OK; +} -static void prepareMcPassthrough( - IVAS_REND_HANDLE st ); +static ivas_error getSpeakerElevations( IVAS_REND_AudioConfig config, const float **elevations ) +{ + switch ( config ) + { + case IVAS_REND_AUDIO_CONFIG_MONO: + *elevations = ls_elevation_CICP1; + break; + case IVAS_REND_AUDIO_CONFIG_STEREO: + *elevations = ls_elevation_CICP2; + break; + case IVAS_REND_AUDIO_CONFIG_5_1: + *elevations = ls_elevation_CICP6; + break; + case IVAS_REND_AUDIO_CONFIG_7_1: + *elevations = ls_elevation_CICP12; + break; + case IVAS_REND_AUDIO_CONFIG_5_1_2: + *elevations = ls_elevation_CICP14; + break; + case IVAS_REND_AUDIO_CONFIG_5_1_4: + *elevations = ls_elevation_CICP16; + break; + case IVAS_REND_AUDIO_CONFIG_7_1_4: + *elevations = ls_elevation_CICP19; + break; + default: + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Unexpected audio config" ); + } -static void passthroughChannel( - const IVAS_REND_AudioBuffer inAudio, - const uint32_t srcChnlIdx, - const uint32_t dstChnlIdx, - const float gain_lin, - IVAS_REND_AudioBuffer outAudio ); + return IVAS_ERR_OK; +} -static void getSpeakerGains( - const IVAS_REND_HANDLE st, - const float azi, - const float ele, - float *const spkGains ); +static ivas_error getAmbisonicsOrder( IVAS_REND_AudioConfig config, int16_t *order ) +{ + switch ( config ) + { + case IVAS_REND_AUDIO_CONFIG_FOA: + *order = 1; + break; + case IVAS_REND_AUDIO_CONFIG_HOA2: + *order = 2; + break; + case IVAS_REND_AUDIO_CONFIG_HOA3: + *order = 3; + break; + default: + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Unsupported audio config" ); + } -static int16_t getNumChannelsAmbisonics( - IVAS_REND_Ambisonics ambisonics ); + return IVAS_ERR_OK; +} -static int16_t getAmbisonicsOrder( - IVAS_REND_Ambisonics ambisonics ); +static ivas_error getNumNonLfeChannelsInSpeakerLayout( IVAS_REND_AudioConfig config, int16_t *numNonLfeChannels ) +{ + switch ( config ) + { + case IVAS_REND_AUDIO_CONFIG_MONO: + *numNonLfeChannels = 1; + break; + case IVAS_REND_AUDIO_CONFIG_STEREO: + *numNonLfeChannels = 2; + break; + case IVAS_REND_AUDIO_CONFIG_5_1: + *numNonLfeChannels = 5; + break; + case IVAS_REND_AUDIO_CONFIG_5_1_2: + case IVAS_REND_AUDIO_CONFIG_7_1: + *numNonLfeChannels = 7; + break; + case IVAS_REND_AUDIO_CONFIG_5_1_4: + *numNonLfeChannels = 9; + break; + case IVAS_REND_AUDIO_CONFIG_7_1_4: + *numNonLfeChannels = 11; + break; + default: + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Unexpected audio config" ); + } -static int16_t getNumChannelsInSpeakerLayout( - IVAS_REND_SpeakerLayout layout ); + return IVAS_ERR_OK; +} -static int16_t getNumNonLfeChannelsInSpeakerLayout( - IVAS_REND_SpeakerLayout layout ); +static ivas_error getMcConfigValues( + IVAS_REND_AudioConfig inConfig, + LSSETUP_CUSTOM_STRUCT inCustomLs, + const float **azimuth, + const float **elevation, + int32_t *lfe_idx, + int32_t *is_planar ) +{ + int16_t i; -static const float *getSpeakerAzimuths( - IVAS_REND_SpeakerLayout layout ); + *lfe_idx = -1; + *is_planar = 1; + switch ( inConfig ) + { + case IVAS_REND_AUDIO_CONFIG_LS_CUSTOM: + *azimuth = (const float *) &inCustomLs.ls_azimuth; + *elevation = (const float *) &inCustomLs.ls_elevation; + if ( inCustomLs.num_lfe > 0 ) + { + *lfe_idx = inCustomLs.lfe_idx[0]; + } + for ( i = 0; i < inCustomLs.num_spk; i++ ) + { + if ( inCustomLs.ls_elevation[i] != 0 ) + { + *is_planar = 0; + break; + } + } + break; + case IVAS_REND_AUDIO_CONFIG_MONO: + case IVAS_REND_AUDIO_CONFIG_STEREO: + getSpeakerAzimuths( inConfig, azimuth ); + getSpeakerElevations( inConfig, elevation ); + break; + case IVAS_REND_AUDIO_CONFIG_5_1: + case IVAS_REND_AUDIO_CONFIG_7_1: + case IVAS_REND_AUDIO_CONFIG_5_1_2: + case IVAS_REND_AUDIO_CONFIG_5_1_4: + case IVAS_REND_AUDIO_CONFIG_7_1_4: + getSpeakerAzimuths( inConfig, azimuth ); + getSpeakerElevations( inConfig, elevation ); + *lfe_idx = LFE_CHANNEL; + *is_planar = ( inConfig == IVAS_REND_AUDIO_CONFIG_5_1 || inConfig == IVAS_REND_AUDIO_CONFIG_7_1 ) ? 1 : 0; + break; + default: + assert( !"Invalid speaker config" ); + return IVAS_ERR_WRONG_PARAMS; + } -static const float *getSpeakerElevations( - IVAS_REND_SpeakerLayout layout ); + return IVAS_ERR_OK; +} -static const uint32_t *getReorderedChannelIndices( - IVAS_REND_SpeakerLayout layout ); +static ivas_error initEfap( EFAP_WRAPPER *pEfapWrapper, IVAS_REND_AudioConfig outConfig, const LSSETUP_CUSTOM_STRUCT *pCustomLsOut ) +{ + ivas_error error; + const float *azimuths; + const float *elevations; + int16_t numNonLfeChannels; -static int32_t reverseChannelIndexMapping( int32_t originalChannelIndex, - const uint32_t *channelReorderingMap, - uint32_t numNonLfeSpeakers ); + if ( outConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM ) + { + pEfapWrapper->speakerConfig = IVAS_REND_AUDIO_CONFIG_7_1_4; + } + else + { + pEfapWrapper->speakerConfig = outConfig; + } + pEfapWrapper->pCustomLsSetup = pCustomLsOut; -static ivas_error getHoaRenderMtx( - const IVAS_REND_OutputConfig outConfig, - float **decMtx, - uint32_t ambiOrder ); + /* If re-initializing, free existing EFAP handle. */ + if ( pEfapWrapper->hEfap != NULL ) + { + efap_free_data( &pEfapWrapper->hEfap ); + } -static void getHoaDecVecForAmbiChnl( - uint32_t ambiChnnlIdx, - const IVAS_REND_OutputConfig outConfig, - const float *decMtx, - float *decCoeffs ); + /* Only initialize EFAP handle if output config is channel-based */ + if ( getAudioConfigType( pEfapWrapper->speakerConfig ) != IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED ) + { + pEfapWrapper->hEfap = NULL; + return IVAS_ERR_OK; + } -static int32_t ivas_limiter_renderer( - 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 */ -); + if ( outConfig == IVAS_REND_AUDIO_CONFIG_LS_CUSTOM ) + { + if ( ( error = efap_init_data( &pEfapWrapper->hEfap, + pCustomLsOut->ls_azimuth, + pCustomLsOut->ls_elevation, + pCustomLsOut->num_spk, + EFAP_MODE_EFAP ) ) != IVAS_ERR_OK ) + { + return error; + } + } + else + { + if ( ( error = getSpeakerAzimuths( pEfapWrapper->speakerConfig, &azimuths ) ) != IVAS_ERR_OK ) + { + return error; + } + if ( ( error = getSpeakerElevations( pEfapWrapper->speakerConfig, &elevations ) ) != IVAS_ERR_OK ) + { + return error; + } + if ( ( error = getNumNonLfeChannelsInSpeakerLayout( pEfapWrapper->speakerConfig, &numNonLfeChannels ) ) != IVAS_ERR_OK ) + { + return error; + } + if ( ( error = efap_init_data( &pEfapWrapper->hEfap, + azimuths, + elevations, + numNonLfeChannels, + EFAP_MODE_EFAP ) ) != IVAS_ERR_OK ) + { + return error; + } + } -static float dBToLin( const float gain_dB ); + return IVAS_ERR_OK; +} -static AUDIO_CONFIG mapRendLayoutToAudioConfig( - IVAS_REND_SpeakerLayout speakerLayout ); +static ivas_error getEfapGains( EFAP_WRAPPER efapWrapper, + const float azi, + const float ele, + pan_vector panGains ) +{ + pan_vector tmpPanGains; /* tmp pan gain buffer without LFE channels */ + float *readPtr; + int32_t i; + int16_t lfeCount; + int32_t numChannels; + ivas_error error; -static AUDIO_CONFIG mapRendAmbisonicsToAudioConfig( - IVAS_REND_Ambisonics ambisonics ); + /* EFAP returns an array of gains only for non-LFE speakers */ + efap_determine_gains( efapWrapper.hEfap, tmpPanGains, azi, ele, EFAP_MODE_EFAP ); -/* clang-on */ -/* ========================================================================== */ + /* Now copy to buffer that includes LFE channels */ + if ( efapWrapper.speakerConfig == IVAS_REND_AUDIO_CONFIG_LS_CUSTOM ) + { + numChannels = efapWrapper.pCustomLsSetup->num_spk + efapWrapper.pCustomLsSetup->num_lfe; + readPtr = tmpPanGains; -static IVAS_QUATERNION quaternionInit( void ) + for ( i = 0, lfeCount = 0; i < numChannels; ++i ) + { + if ( lfeCount < efapWrapper.pCustomLsSetup->num_lfe && i == efapWrapper.pCustomLsSetup->lfe_idx[lfeCount] ) + { + panGains[i] = 0.0f; + ++lfeCount; + } + else + { + panGains[i] = *readPtr; + ++readPtr; + } + } + } + else + { + if ( ( error = getAudioConfigNumChannels( efapWrapper.speakerConfig, &numChannels ) ) != IVAS_ERR_OK ) + { + return error; + } + + readPtr = tmpPanGains; + + for ( i = 0; i < numChannels; ++i ) + { + if ( i == LFE_CHANNEL ) + { + panGains[i] = 0.0f; + } + else + { + panGains[i] = *readPtr; + ++readPtr; + } + } + } + + return IVAS_ERR_OK; +} + +static void initHeadRotation( + IVAS_REND_HANDLE hIvasRend ) { - IVAS_QUATERNION q; - q.w = 1.0f; - q.x = q.y = q.z = 0.0f; - return q; + int16_t i, crossfade_len; + float tmp; + + /* Head rotation is enabled by default */ + hIvasRend->headRotData.headRotEnabled = 1; + + /* Initialize 5ms crossfade */ + crossfade_len = L_FRAME48k / RENDERER_HEAD_POSITIONS_PER_FRAME; + 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 < RENDERER_HEAD_POSITIONS_PER_FRAME; ++i ) + { + hIvasRend->headRotData.headPositions[i] = quaternionInit(); + } } -IVAS_REND_HANDLE IVAS_REND_Open() +static void initRotMatrix( rotation_matrix rot_mat ) { int16_t i; - IVAS_REND_HANDLE st; - - st = (IVAS_REND_HANDLE) count_malloc( sizeof( struct IVAS_REND ) ); - st->isConfigured = 0; - st->efapRenderer = NULL; - - st->objPanInfo = NULL; - st->speakerPanGains = NULL; - st->tmpGainBuffer = NULL; - st->noLfePanBuffer = NULL; - st->crossfade = NULL; - st->mcPassthrough = NULL; - st->neverDropLfe = 0; - st->lfePanGains = NULL; - st->hLimiter = NULL; - st->ambi_dec_mtx = NULL; - st->decDummyAmbiBin = NULL; - st->decDummyMcBin = NULL; - st->decDummyObjBin = NULL; - st->decDummyMasaBin = NULL; - st->enableHeadRotation = 0; - st->rendererConfigEnabled = 0; - st->forceBinLfeLpf = 0; -#ifdef DEBUGGING - st->numClipping = 0; -#endif + /* Initialize rotation matrices */ + for ( i = 0; i < 3; i++ ) + { + set_zero( rot_mat[i], 3 ); + rot_mat[i][i] = 1.f; + } +} - for ( i = 0; i < RENDERER_HEAD_POSITIONS_PER_FRAME; ++i ) + +static void initRotGains( rotation_gains rot_gains ) +{ + int16_t i; + /* Set gains to passthrough */ + for ( i = 0; i < MAX_INPUT_CHANNELS; i++ ) + { + set_zero( rot_gains[i], MAX_INPUT_CHANNELS ); + rot_gains[i][i] = 1.f; + } +} + +static void initRendInputBase( input_base *inputBase, IVAS_REND_AudioConfig inConfig, IVAS_REND_InputId id, rendering_context rendCtx ) +{ + 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 = inputBase->bufferData; + + set_zero( inputBase->bufferData, MAX_BUFFER_LENGTH ); +} + +static IVAS_REND_AudioObjectPosition defaultObjectPosition( void ) +{ + IVAS_REND_AudioObjectPosition pos; + + pos.azimuth = 0.0f; + pos.elevation = 0.0f; + + return pos; +} + +static rendering_context getRendCtx( IVAS_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.pCustomLsOut = &hIvasRend->customLsOut; + ctx.pEfapOutWrapper = &hIvasRend->efapOutWrapper; + ctx.pHeadRotData = &hIvasRend->headRotData; + + return ctx; +} + +static TDREND_WRAPPER defaultTdRendWrapper( void ) +{ + TDREND_WRAPPER w; + + w.binaural_latency_ns = 0; + w.hBinRendererTd = NULL; + w.hHrtfTD = NULL; + + return w; +} + +static CREND_WRAPPER defaultCrendWrapper( void ) +{ + CREND_WRAPPER w; + + w.hCrend = NULL; + w.hHrtfCrend = NULL; + w.binaural_latency_ns = 0; + + return w; +} + +static ivas_error setRendInputActiveIsm( + void *input, + IVAS_REND_AudioConfig inConfig, + IVAS_REND_InputId id ) +{ + ivas_error error; + rendering_context rendCtx; + IVAS_REND_AudioConfig outConfig; + input_ism *inputIsm; + + inputIsm = (input_ism *) input; + rendCtx = inputIsm->base.ctx; + outConfig = *rendCtx.pOutConfig; + + initRendInputBase( &inputIsm->base, inConfig, id, rendCtx ); + + inputIsm->currentPos = defaultObjectPosition(); + inputIsm->previousPos = defaultObjectPosition(); + inputIsm->crendWrapper = defaultCrendWrapper(); + inputIsm->tdRendWrapper = defaultTdRendWrapper(); + initRotMatrix( inputIsm->rot_mat_prev ); + + error = IVAS_ERR_OK; + if ( outConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL ) + { + error = ivas_rend_TDObjRendOpen( &inputIsm->tdRendWrapper, + inConfig, + NULL, + *rendCtx.pOutSampleRate ); + } + else if ( outConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM ) + { + error = ivas_rend_openCrend( &inputIsm->crendWrapper, + IVAS_REND_AUDIO_CONFIG_7_1_4, + outConfig, + *rendCtx.pOutSampleRate ); + } + if ( error != IVAS_ERR_OK ) + { + return error; + } + + return IVAS_ERR_OK; +} + +static void clearInputIsm( input_ism *inputIsm ) +{ + rendering_context rendCtx; + + rendCtx = inputIsm->base.ctx; + + initRendInputBase( &inputIsm->base, IVAS_REND_AUDIO_CONFIG_UNKNOWN, 0, rendCtx ); + + /* Free input's internal handles */ + if ( inputIsm->crendWrapper.hCrend != NULL ) { - st->headRotationData[i] = quaternionInit(); + ivas_rend_closeCrend( &inputIsm->crendWrapper ); } + if ( inputIsm->tdRendWrapper.hBinRendererTd != NULL ) + { + ivas_td_binaural_close( &inputIsm->tdRendWrapper.hBinRendererTd ); + inputIsm->tdRendWrapper.hHrtfTD = NULL; + } +} + +static void copyLsConversionMatrixToPanMatrix( const LS_CONVERSION_MATRIX *lsConvMatrix, pan_matrix panMatrix ) +{ + int32_t i; + int32_t inCh, outCh; + int32_t numNonZeroGains; + int32_t numColumns; + + /* Index 0 is special and describes the following values */ + numNonZeroGains = lsConvMatrix[0].index; + numColumns = (int32_t) lsConvMatrix[0].value; + + for ( i = 1; i < numNonZeroGains + 1; ++i ) + { + inCh = lsConvMatrix[i].index / numColumns; + outCh = lsConvMatrix[i].index % numColumns; + + panMatrix[inCh][outCh] = lsConvMatrix[i].value; + } +} + +static void setZeroPanMatrix( pan_matrix panMatrix ) +{ + int32_t i; + + for ( i = 0; i < MAX_INPUT_CHANNELS; ++i ) + { + set_zero( panMatrix[i], MAX_OUTPUT_CHANNELS ); + } +} + +/* Note: this only sets non-zero elements, call setZeroPanMatrix() to init first. */ +static void fillIdentityPanMatrix( pan_matrix panMatrix ) +{ + int32_t i; - for ( i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) + for ( i = 0; i < min( MAX_INPUT_CHANNELS, MAX_OUTPUT_CHANNELS ); ++i ) { - set_zero( st->delayOffsetBuffer[i], L_FRAME48k ); + panMatrix[i][i] = 1.0f; } +} + +static ivas_error initMcPanGainsWithIdentMatrix( input_mc *inputMc ) +{ + fillIdentityPanMatrix( inputMc->panGains ); - return st; + return IVAS_ERR_OK; } -static DecoderDummy *allocDecoderDummy( int32_t sampleRate, int16_t numOutChannels, const uint8_t enableHeadRotation, const uint8_t enableRenderConfig ) +static ivas_error initMcPanGainsWithConversionMapping( input_mc *inputMc, IVAS_REND_AudioConfig outConfig ) +{ + AUDIO_CONFIG ivasConfigIn, ivasConfigOut; + int32_t i; + + ivasConfigIn = rendAudioConfigToIvasAudioConfig( inputMc->base.inConfig ); + ivasConfigOut = rendAudioConfigToIvasAudioConfig( outConfig ); + + /* Find conversion mapping for current I/O config pair. + * Stay with default panning matrix if conversion_matrix is NULL */ + for ( i = 0; i < LS_SETUP_CONVERSION_NUM_MAPPINGS; ++i ) + { + if ( ls_conversion_mapping[i].input_config == ivasConfigIn && + ls_conversion_mapping[i].output_config == ivasConfigOut ) + { + /* Mapping found with valid matrix - copy */ + if ( ls_conversion_mapping[i].conversion_matrix != NULL ) + { + copyLsConversionMatrixToPanMatrix( ls_conversion_mapping[i].conversion_matrix, inputMc->panGains ); + } + /* Mapping found with NULL matrix - use identity matrix */ + else + { + fillIdentityPanMatrix( inputMc->panGains ); + } + + return IVAS_ERR_OK; + } + } + + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Missing multichannel conversion mapping" ); +} + +static ivas_error initMcPanGainsWithEfap( input_mc *inputMc, IVAS_REND_AudioConfig outConfig ) { int16_t i; - DecoderDummy *decDummy; + int16_t numNonLfeInChannels; + int16_t inLfeChIdx, outChIdx; + const float *spkAzi, *spkEle; + ivas_error error; + + if ( inputMc->base.inConfig != IVAS_REND_AUDIO_CONFIG_LS_CUSTOM ) + { + if ( ( error = getNumNonLfeChannelsInSpeakerLayout( inputMc->base.inConfig, &numNonLfeInChannels ) ) != IVAS_ERR_OK ) + { + return error; + } + if ( ( error = getSpeakerAzimuths( inputMc->base.inConfig, &spkAzi ) ) != IVAS_ERR_OK ) + { + return error; + } + if ( ( error = getSpeakerElevations( inputMc->base.inConfig, &spkEle ) ) != IVAS_ERR_OK ) + { + return error; + } + + inLfeChIdx = LFE_CHANNEL; + } + else + { + numNonLfeInChannels = inputMc->customLsInput.num_spk; + spkAzi = inputMc->customLsInput.ls_azimuth; + spkEle = inputMc->customLsInput.ls_elevation; + inLfeChIdx = -1; + if ( inputMc->customLsInput.num_lfe > 0 ) + { + inLfeChIdx = inputMc->customLsInput.lfe_idx[0]; + } + } + + for ( i = 0, outChIdx = 0; i < numNonLfeInChannels; ++i, ++outChIdx ) + { + if ( i == inLfeChIdx ) + { + ++outChIdx; + } + + if ( ( error = getEfapGains( *inputMc->base.ctx.pEfapOutWrapper, + spkAzi[i], + spkEle[i], + inputMc->panGains[outChIdx] ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + if ( outConfig != IVAS_REND_AUDIO_CONFIG_LS_CUSTOM && inLfeChIdx >= 0 ) + { + inputMc->panGains[inLfeChIdx][LFE_CHANNEL] = 1; + } + else if ( inputMc->base.ctx.pCustomLsOut->num_lfe > 0 && inLfeChIdx >= 0 ) + { + inputMc->panGains[inLfeChIdx][inputMc->base.ctx.pCustomLsOut->lfe_idx[0]] = 1; + } + + return IVAS_ERR_OK; +} + +static ivas_error getRendInputNumChannels( const void *rendInput, int32_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 + */ + + ivas_error error; + const input_base *pInputBase; + const input_mc *pInputMc; + + pInputBase = (const input_base *) rendInput; + + if ( pInputBase->inConfig == IVAS_REND_AUDIO_CONFIG_LS_CUSTOM ) + { + pInputMc = (const input_mc *) rendInput; + *numInChannels = pInputMc->customLsInput.num_spk + pInputMc->customLsInput.num_lfe; + } + else + { + if ( ( error = getAudioConfigNumChannels( pInputBase->inConfig, numInChannels ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + return IVAS_ERR_OK; +} + +static ivas_error initMcPanGainsWithMonoOut( input_mc *inputMc ) +{ + int32_t i; + int32_t numInChannels; + ivas_error error; + + if ( ( error = getRendInputNumChannels( inputMc, &numInChannels ) ) != IVAS_ERR_OK ) + { + return error; + } + + for ( i = 0; i < numInChannels; ++i ) + { + /* It's OK to also set gain 1 for LFE input channels here. + * Correct LFE handling will be applied within updateMcPanGains() */ + inputMc->panGains[i][0] = 1.f; + } + + return IVAS_ERR_OK; +} + +static ivas_error initMcPanGainsWithStereoLookup( input_mc *inputMc ) +{ + int32_t readIdx; + int32_t writeIdx; + bool skipSideSpeakers; + int32_t numInChannels; + ivas_error error; + + /* Special case - MONO input. + * Use gains for center CICP speaker and return early. */ + if ( inputMc->base.inConfig == IVAS_REND_AUDIO_CONFIG_MONO ) + { + inputMc->panGains[0][0] = ls_conversion_cicpX_stereo[2][0]; + inputMc->panGains[0][1] = ls_conversion_cicpX_stereo[2][1]; + return IVAS_ERR_OK; + } + + /* ls_conversion_cicpX_stereo contains gains for side speakers. + * These should be skipped with 5.1+X inputs. */ + skipSideSpeakers = false; + if ( inputMc->base.inConfig == IVAS_REND_AUDIO_CONFIG_5_1_2 || inputMc->base.inConfig == IVAS_REND_AUDIO_CONFIG_5_1_4 ) + { + skipSideSpeakers = true; + } + + if ( ( error = getRendInputNumChannels( inputMc, &numInChannels ) ) != IVAS_ERR_OK ) + { + return error; + } + for ( readIdx = 0, writeIdx = 0; writeIdx < numInChannels; ++readIdx, ++writeIdx ) + { + if ( skipSideSpeakers && readIdx == 4 ) + { + /* Skip gains for side speakers in lookup table */ + readIdx += 2; + } + + inputMc->panGains[writeIdx][0] = ls_conversion_cicpX_stereo[readIdx][0]; + inputMc->panGains[writeIdx][1] = ls_conversion_cicpX_stereo[readIdx][1]; + } + + return IVAS_ERR_OK; +} + +/* Returns 1 (true) if configs A and B are equal, otherwise returns 0 (false). + * If both configs are custom LS layouts, layout details are compared to determine equality. */ +static bool configsAreEqual( + IVAS_REND_AudioConfig configA, + LSSETUP_CUSTOM_STRUCT customLsA, + IVAS_REND_AudioConfig configB, + LSSETUP_CUSTOM_STRUCT customLsB ) +{ + int32_t i; + + /* Both input and output are custom LS - compare structs */ + if ( configA == IVAS_REND_AUDIO_CONFIG_LS_CUSTOM && configB == IVAS_REND_AUDIO_CONFIG_LS_CUSTOM ) + { + if ( customLsA.num_spk != customLsB.num_spk ) + { + return false; + } + if ( customLsA.num_lfe != customLsB.num_lfe ) + { + return false; + } + if ( customLsA.is_planar_setup != customLsB.is_planar_setup ) + { + return false; + } + for ( i = 0; i < customLsA.num_spk; ++i ) + { + /* Compare to nearest degree (hence the int cast) */ + if ( (int16_t) customLsA.ls_azimuth[i] != (int16_t) customLsB.ls_azimuth[i] || + (int16_t) customLsA.ls_elevation[i] != (int16_t) customLsB.ls_elevation[i] ) + { + return false; + } + } + for ( i = 0; i < customLsA.num_lfe; ++i ) + { + if ( customLsA.lfe_idx[i] != customLsB.lfe_idx[i] ) + { + return false; + } + } + + return true; + } + + /* Otherwise it's enough to compare config enums */ + return configA == configB; +} + +static ivas_error updateMcPanGainsForMcOut( input_mc *inputMc, IVAS_REND_AudioConfig outConfig ) +{ + ivas_error error; - decDummy = count_malloc( sizeof( DecoderDummy ) ); - decDummy->hDecoderConfig = count_malloc( sizeof( DECODER_CONFIG ) ); - decDummy->hDecoderConfig->output_Fs = sampleRate; - decDummy->hDecoderConfig->nchan_out = numOutChannels; - decDummy->hDecoderConfig->Opt_Headrotation = 0; + /* "if" conditions below realize the following mapping: - decDummy->hBinRenderer = NULL; - decDummy->hEFAPdata = NULL; - decDummy->hHrtf = NULL; - decDummy->hHrtfTD = NULL; + If in == out, use identity matrix, otherwise follow the table: + +-----------+----------+---------------+-----------+--------------------+ + | in\out | MONO | STEREO | custom LS | other | + +-----------+----------+---------------+-----------+--------------------+ + | MONO | mono out | EFAP | EFAP | EFAP | + | custom LS | mono out | EFAP | EFAP | EFAP | + | other | mono out | stereo lookup | EFAP | conversion mapping | + +-----------+----------+---------------+-----------+--------------------+ + */ - if ( enableHeadRotation ) + if ( configsAreEqual( inputMc->base.inConfig, + inputMc->customLsInput, + outConfig, + *inputMc->base.ctx.pCustomLsOut ) ) { - decDummy->hHeadTrackData = count_malloc( sizeof( HEAD_TRACK_DATA ) ); - /* Initialise Rmat_prev to I, Rmat will be computed later */ - for ( i = 0; i < 3; i++ ) - { - set_zero( decDummy->hHeadTrackData->Rmat_prev[i], 3 ); - decDummy->hHeadTrackData->Rmat_prev[i][i] = 1.0f; - } - - decDummy->hHeadTrackData->num_quaternions = 0; - decDummy->hHeadTrackData->lrSwitchInterpVal = 0.0f; - decDummy->hHeadTrackData->lrSwitchedCurrent = 0; - decDummy->hHeadTrackData->lrSwitchedNext = 0; + error = initMcPanGainsWithIdentMatrix( inputMc ); } - else + else if ( outConfig == IVAS_REND_AUDIO_CONFIG_LS_CUSTOM || + inputMc->base.inConfig == IVAS_REND_AUDIO_CONFIG_MONO || + inputMc->base.inConfig == IVAS_REND_AUDIO_CONFIG_LS_CUSTOM ) { - decDummy->hHeadTrackData = NULL; + error = initMcPanGainsWithEfap( inputMc, outConfig ); } - - if ( enableRenderConfig ) + else if ( outConfig == IVAS_REND_AUDIO_CONFIG_MONO ) { - ivas_render_config_open( &decDummy->hRenderConfig ); - decDummy->hRenderConfig->roomAcoustics.late_reverb_on = 0; - decDummy->hRenderConfig->roomAcoustics.use_brir = 0; + error = initMcPanGainsWithMonoOut( inputMc ); } - else + else if ( outConfig == IVAS_REND_AUDIO_CONFIG_STEREO ) { - decDummy->hRenderConfig = NULL; + error = initMcPanGainsWithStereoLookup( inputMc ); + } + else /* default */ + { + error = initMcPanGainsWithConversionMapping( inputMc, outConfig ); } - - decDummy->renderer_type = RENDERER_DISABLE; - - return decDummy; -} - -static ivas_error initDecoderDummyForMasaToAmbi( DecoderDummy *decDummyMasaAmbi, IVAS_REND_InputConfig inConfig ) -{ - ivas_error error; - error = IVAS_ERR_OK; - - /* TODO @ Nokia: set relevant members of decDummy */ - (void) decDummyMasaAmbi; - (void) inConfig; return error; } -static ivas_error initDecoderDummyForMasaToChannels( DecoderDummy *decDummyMasaChannels, IVAS_REND_InputConfig inConfig ) +static ivas_error updateMcPanGainsForAmbiOut( input_mc *inputMc, IVAS_REND_AudioConfig outConfig ) { + int16_t ch_in, ch_out, lfeIdx; + int16_t numNonLfeInChannels, outAmbiOrder; + const float *spkAzi, *spkEle; ivas_error error; - error = IVAS_ERR_OK; - /* TODO @ Nokia: set relevant members of decDummy */ - (void) decDummyMasaChannels; - (void) inConfig; + if ( ( error = getAmbisonicsOrder( outConfig, &outAmbiOrder ) ) != IVAS_ERR_OK ) + { + return error; + } - return error; -} + if ( inputMc->base.inConfig != IVAS_REND_AUDIO_CONFIG_LS_CUSTOM ) + { + if ( ( error = getNumNonLfeChannelsInSpeakerLayout( inputMc->base.inConfig, &numNonLfeInChannels ) ) != IVAS_ERR_OK ) + { + return error; + } + if ( ( error = getSpeakerAzimuths( inputMc->base.inConfig, &spkAzi ) ) != IVAS_ERR_OK ) + { + return error; + } + if ( ( error = getSpeakerElevations( inputMc->base.inConfig, &spkEle ) ) != IVAS_ERR_OK ) + { + return error; + } -static ivas_error initDecoderDummyForMasaToBinaural( DecoderDummy *decDummyMasaBin, IVAS_REND_InputConfig inConfig ) -{ - ivas_error error; - error = IVAS_ERR_OK; + for ( ch_in = 0, ch_out = 0; ch_in < numNonLfeInChannels; ++ch_in, ++ch_out ) + { + if ( ch_in == LFE_CHANNEL ) + { + ++ch_out; + } + ivas_dirac_dec_get_response( (int16_t) spkAzi[ch_in], + (int16_t) spkEle[ch_in], + inputMc->panGains[ch_out], + outAmbiOrder ); + } + } + else + { + numNonLfeInChannels = inputMc->customLsInput.num_spk; + spkAzi = inputMc->customLsInput.ls_azimuth; + spkEle = inputMc->customLsInput.ls_elevation; + + for ( ch_in = 0, ch_out = 0; ch_in < numNonLfeInChannels; ++ch_in, ++ch_out ) + { + for ( lfeIdx = 0; lfeIdx < inputMc->customLsInput.num_lfe; ++lfeIdx ) + { + if ( inputMc->customLsInput.lfe_idx[lfeIdx] == ch_in ) + { + ++ch_out; + break; + } + } - /* TODO @ Nokia: set relevant members of decDummy */ - (void) decDummyMasaBin; - (void) inConfig; + ivas_dirac_dec_get_response( (int16_t) spkAzi[ch_in], + (int16_t) spkEle[ch_in], + inputMc->panGains[ch_out], + outAmbiOrder ); + } + } - return error; + return IVAS_ERR_OK; } -static ivas_error initDecoderDummyForAmbiToBinaural( DecoderDummy *decDummyAmbiBin, IVAS_REND_InputConfig inConfig, IVAS_REND_BinauralFormat binauralFormat ) +static ivas_error updateMcPanGains( input_mc *inputMc, IVAS_REND_AudioConfig outConfig ) { + int32_t i; ivas_error error; - assert( inConfig.numAmbisonicsBuses == 1 && "For now only 1 ambisonics input is supported" ); - - error = IVAS_ERR_OK; - decDummyAmbiBin->ivas_format = SBA_FORMAT; - decDummyAmbiBin->renderer_type = binauralFormat == IVAS_REND_BINAURAL_ROOM ? RENDERER_BINAURAL_MIXER_CONV_ROOM : RENDERER_BINAURAL_MIXER_CONV; - decDummyAmbiBin->intern_config = decDummyAmbiBin->transport_config = mapRendAmbisonicsToAudioConfig( inConfig.ambisonicsBuses[0].ambisonicsConfig ); + /* Reset to all zeros - some functions below only write non-zero elements. */ + setZeroPanMatrix( inputMc->panGains ); - /* BINAURAL_ROOM requires intermediate rendering to 7_1_4 */ - if ( binauralFormat == IVAS_REND_BINAURAL_ROOM ) + error = IVAS_ERR_OK; + switch ( getAudioConfigType( outConfig ) ) + { + case IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED: + error = updateMcPanGainsForMcOut( inputMc, outConfig ); + break; + case IVAS_REND_AUDIO_CONFIG_TYPE_AMBISONICS: + error = updateMcPanGainsForAmbiOut( inputMc, outConfig ); + break; + case IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL: + switch ( outConfig ) + { + case IVAS_REND_AUDIO_CONFIG_BINAURAL: + break; /* Do nothing */ + case IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM: + /* Prepare rendering to intermediate format */ + error = updateMcPanGainsForMcOut( inputMc, IVAS_REND_AUDIO_CONFIG_7_1_4 ); + break; + default: + return IVAS_ERR_INVALID_OUTPUT_FORMAT; + } + break; + default: + return IVAS_ERR_INVALID_OUTPUT_FORMAT; + } + /* Check error here to keep switch statement more compact */ + if ( error != IVAS_ERR_OK ) { - decDummyAmbiBin->intern_config = AUDIO_CONFIG_7_1_4; + return error; } - ivas_output_init( &decDummyAmbiBin->hIntSetup, decDummyAmbiBin->intern_config ); - ivas_output_init( &decDummyAmbiBin->hTransSetup, decDummyAmbiBin->transport_config ); - - if ( ( error = ivas_crend_open( decDummyAmbiBin ) ) != IVAS_ERR_OK ) + /* Copy LFE routing to pan gains array */ + if ( inputMc->base.inConfig == IVAS_REND_AUDIO_CONFIG_LS_CUSTOM ) { - return error; + for ( i = 0; i < inputMc->customLsInput.num_lfe; ++i ) + { + mvr2r( inputMc->lfeRouting.lfeOutputGains[i], inputMc->panGains[inputMc->customLsInput.lfe_idx[i]], IVAS_MAX_OUTPUT_CHANNELS ); + } + } + else + { + /* For code simplicity, always copy LFE gains. If config has no LFE, gains will be zero anyway. */ + mvr2r( inputMc->lfeRouting.lfeOutputGains[0], inputMc->panGains[LFE_CHANNEL], IVAS_MAX_OUTPUT_CHANNELS ); } - return error; + return IVAS_ERR_OK; } #ifndef FIX_I81 -/* Fixes initialization issues in TD renderer. Should get fixed properly soon. +/* Fixes initialization issues in TD renderer. Fix to be merged with branch. See issue: https://forge.3gpp.org/rep/ivas-codec-pc/ivas-codec/-/issues/81 */ -static void tmpFixBuggyTdBinRendInit(BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd) +static void tmpFixBuggyTdBinRendInit( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd ) { int32_t i, j; - for (i=0; i < hBinRendererTd->NumOfSrcs; ++i) + for ( i = 0; i < hBinRendererTd->NumOfSrcs; ++i ) { - for (j=0; j < SPAT_BIN_MAX_INPUT_CHANNELS; ++j) + for ( j = 0; j < SPAT_BIN_MAX_INPUT_CHANNELS; ++j ) { hBinRendererTd->Sources[i]->SrcRend_p->SfxSpatBin_p[j].LeftFilter_p = NULL; hBinRendererTd->Sources[i]->SrcRend_p->SfxSpatBin_p[j].LeftFilterIncr_p = NULL; hBinRendererTd->Sources[i]->SrcRend_p->SfxSpatBin_p[j].RightFilter_p = NULL; hBinRendererTd->Sources[i]->SrcRend_p->SfxSpatBin_p[j].RightFilterIncr_p = NULL; - } + } } } #endif -static ivas_error initDecoderDummyForObjToBinaural( DecoderDummy *decDummyObjBin, IVAS_REND_InputConfig inConfig, IVAS_REND_BinauralFormat binauralFormat ) +static ivas_error initMcBinauralRendering( + input_mc *inputMc, + IVAS_REND_AudioConfig inConfig, + IVAS_REND_AudioConfig outConfig ) { ivas_error error; - int32_t n; - - assert( inConfig.numAudioObjects <= MAX_NUM_OBJECTS && "IVAS decoder is used for binaural rendering, which limits number of objects" ); - - error = IVAS_ERR_OK; - - decDummyObjBin->ivas_format = ISM_FORMAT; - decDummyObjBin->nSCE = inConfig.numAudioObjects; - decDummyObjBin->nchan_transport = inConfig.numAudioObjects; + int32_t outSampleRate; - for ( n = 0; n < inConfig.numAudioObjects; ++n ) + /* check if re-initialization */ + if ( inputMc->tdRendWrapper.hBinRendererTd != NULL ) { - decDummyObjBin->hIsmMetaData[n] = count_malloc( sizeof( ISM_METADATA_FRAME ) ); + ivas_td_binaural_close( &inputMc->tdRendWrapper.hBinRendererTd ); + inputMc->tdRendWrapper.hHrtfTD = NULL; } - for ( n = inConfig.numAudioObjects; n < MAX_NUM_OBJECTS; ++n ) + if ( inputMc->crendWrapper.hCrend != NULL ) { - decDummyObjBin->hIsmMetaData[n] = NULL; + ivas_rend_closeCrend( &inputMc->crendWrapper ); } - /* BINAURAL_ROOM requires intermediate rendering to 7_1_4 */ - if ( binauralFormat == IVAS_REND_BINAURAL_ROOM ) - { - decDummyObjBin->hBinRendererTd = NULL; - decDummyObjBin->renderer_type = RENDERER_BINAURAL_MIXER_CONV_ROOM; - decDummyObjBin->intern_config = AUDIO_CONFIG_7_1_4; - ivas_output_init( &decDummyObjBin->hIntSetup, decDummyObjBin->intern_config ); + outSampleRate = *inputMc->base.ctx.pOutSampleRate; + + /* TODO tmu : needs review allocate both renderers; needed if headrotation is toggled so the renderer can be switched */ + // bool initTDRend; + // initTDRend = false; + // if ( outConfig != IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM ) + // { + // if ( inConfig == IVAS_REND_AUDIO_CONFIG_LS_CUSTOM ) + // { + // initTDRend = true; + // } + // else if ( ( inConfig == IVAS_REND_AUDIO_CONFIG_5_1 || inConfig == IVAS_REND_AUDIO_CONFIG_7_1 ) && + // ( inputMc->base.ctx.pHeadRotData->headRotEnabled ) ) + // { + // initTDRend = true; + // } + // } - if ( ( error = ivas_crend_open( decDummyObjBin ) != IVAS_ERR_OK ) ) + // if ( initTDRend ) + { + if ( ( error = ivas_rend_TDObjRendOpen( &inputMc->tdRendWrapper, + inConfig, + &inputMc->customLsInput, + outSampleRate ) ) != IVAS_ERR_OK ) { return error; } +#ifndef FIX_I81 + tmpFixBuggyTdBinRendInit( inputMc->tdRendWrapper.hBinRendererTd ); +#endif } - else + { - decDummyObjBin->hCrend = NULL; - decDummyObjBin->renderer_type = RENDERER_BINAURAL_OBJECTS_TD; - if ( ( error = ivas_td_binaural_open( decDummyObjBin ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_rend_openCrend( &inputMc->crendWrapper, + ( inConfig == IVAS_REND_AUDIO_CONFIG_LS_CUSTOM ) ? IVAS_REND_AUDIO_CONFIG_7_1_4 : inConfig, + outConfig, + outSampleRate ) ) != IVAS_ERR_OK ) { return error; } -#ifndef FIX_I81 - tmpFixBuggyTdBinRendInit(decDummyObjBin->hBinRendererTd); -#endif } return error; } -static ivas_error initDecoderDummyForMcToBinaural( DecoderDummy *decDummyMcBin, IVAS_REND_InputConfig inConfig, IVAS_REND_BinauralFormat binauralFormat, const uint8_t enableHeadRotation ) +static IVAS_REND_LfeRouting defaultLfeRouting( + IVAS_REND_AudioConfig inConfig, + LSSETUP_CUSTOM_STRUCT customLsIn, + IVAS_REND_AudioConfig outConfig, + LSSETUP_CUSTOM_STRUCT customLsOut ) { - ivas_error error; - IVAS_REND_SpeakerLayout spkLayout; - - assert( inConfig.numMultiChannelBuses == 1 && "For now supporting one multichannel input" ); - - error = IVAS_ERR_OK; - - decDummyMcBin->ivas_format = MC_FORMAT; - decDummyMcBin->mc_mode = MC_MODE_MCT; - - spkLayout = inConfig.multiChannelBuses[0].speakerLayout; - decDummyMcBin->intern_config = decDummyMcBin->transport_config = mapRendLayoutToAudioConfig( spkLayout ); + int32_t i; + IVAS_REND_LfeRouting routing; - if ( spkLayout == IVAS_REND_SPEAKER_LAYOUT_CUSTOM ) - { - decDummyMcBin->nchan_transport = inConfig.inSetupCustom->num_spk + inConfig.inSetupCustom->num_lfe; + /* Set all output gains to zero, then route each input LFE consecutively to the next available output LFE. */ - ivas_ls_custom_setup( &decDummyMcBin->hIntSetup, inConfig.inSetupCustom ); - ivas_ls_custom_setup( &decDummyMcBin->hTransSetup, inConfig.inSetupCustom ); - } - else + for ( i = 0; i < IVAS_MAX_INPUT_LFE_CHANNELS; ++i ) { - decDummyMcBin->nchan_transport = getNumChannelsInSpeakerLayout( spkLayout ); - - ivas_output_init( &decDummyMcBin->hIntSetup, decDummyMcBin->intern_config ); - ivas_output_init( &decDummyMcBin->hTransSetup, decDummyMcBin->transport_config ); + set_zero( routing.lfeOutputGains[i], IVAS_MAX_OUTPUT_CHANNELS ); } - - if ( enableHeadRotation && ( ( error = efap_init_data( &decDummyMcBin->hEFAPdata, decDummyMcBin->hTransSetup.ls_azimuth, decDummyMcBin->hTransSetup.ls_elevation, decDummyMcBin->hTransSetup.nchan_out_woLFE, EFAP_MODE_EFAP ) ) != IVAS_ERR_OK ) ) + switch ( inConfig ) { - return error; + case IVAS_REND_AUDIO_CONFIG_5_1: + case IVAS_REND_AUDIO_CONFIG_5_1_2: + case IVAS_REND_AUDIO_CONFIG_5_1_4: + case IVAS_REND_AUDIO_CONFIG_7_1: + case IVAS_REND_AUDIO_CONFIG_7_1_4: + routing.numLfeChannels = 1; + break; + case IVAS_REND_AUDIO_CONFIG_LS_CUSTOM: + routing.numLfeChannels = customLsIn.num_lfe; + break; + default: + routing.numLfeChannels = 0; } - /* Use TD binaural renderer only for HRIRs for Custom LS or 5_1 and 7_1 with headrotation */ - if ( ( binauralFormat != IVAS_REND_BINAURAL_ROOM ) && - ( ( spkLayout == IVAS_REND_SPEAKER_LAYOUT_CUSTOM ) || - ( enableHeadRotation && ( spkLayout == IVAS_REND_SPEAKER_LAYOUT_5_1 || spkLayout == IVAS_REND_SPEAKER_LAYOUT_7_1 ) ) ) ) - { - - decDummyMcBin->renderer_type = RENDERER_BINAURAL_OBJECTS_TD; - decDummyMcBin->hCrend = NULL; - if ( ( error = ivas_td_binaural_open( decDummyMcBin ) ) != IVAS_ERR_OK ) - { - return error; - } - } - else + switch ( outConfig ) { - /* TODO tmu : rendering custom layouts to BINAURAL_ROOM needs implementation */ - if ( spkLayout == IVAS_REND_SPEAKER_LAYOUT_CUSTOM && binauralFormat == IVAS_REND_BINAURAL_ROOM ) - { - fprintf( stderr, "Warning! BINAURAL_ROOM output not supported for custom loudspeaker input! Overriding to BINAURAL.\n" ); - } - decDummyMcBin->renderer_type = binauralFormat == IVAS_REND_BINAURAL_ROOM ? RENDERER_BINAURAL_MIXER_CONV_ROOM : RENDERER_BINAURAL_MIXER_CONV; - decDummyMcBin->hBinRendererTd = NULL; - if ( ( error = ivas_crend_open( decDummyMcBin ) ) != IVAS_ERR_OK ) - { - return error; - } + case IVAS_REND_AUDIO_CONFIG_5_1: + case IVAS_REND_AUDIO_CONFIG_5_1_2: + case IVAS_REND_AUDIO_CONFIG_5_1_4: + case IVAS_REND_AUDIO_CONFIG_7_1: + case IVAS_REND_AUDIO_CONFIG_7_1_4: + routing.lfeOutputGains[0][LFE_CHANNEL] = 1.0f; + break; + case IVAS_REND_AUDIO_CONFIG_LS_CUSTOM: + for ( i = 0; i < routing.numLfeChannels && i < customLsOut.num_lfe; ++i ) + { + routing.lfeOutputGains[i][customLsOut.lfe_idx[i]] = 1.0f; + } + break; + default: + /* Do nothing */ + break; } - return error; + return routing; } -ivas_error IVAS_REND_Configure( IVAS_REND_HANDLE st, - const IVAS_REND_InputConfig inConfig, - const IVAS_REND_OutputConfig outConfig, - uint32_t sampleRate, - bool headRotationEnabled, - bool rendererConfigEnabled ) +static ivas_error setRendInputActiveMc( + void *input, + IVAS_REND_AudioConfig inConfig, + IVAS_REND_InputId id ) { - uint32_t i; - int32_t j; ivas_error error; - uint8_t numActiveOutputs; - int32_t frameSize_smpls; - - error = IVAS_ERR_OK; + rendering_context rendCtx; + IVAS_REND_AudioConfig outConfig; + input_mc *inputMc; - /* ============================= Error checks ============================= */ - assert( st != NULL && "Can't configure renderer - pointer is NULL" ); - assert( !st->isConfigured && "Re-configuring a renderer is not supported" ); - assert( !( inConfig.numAudioObjects == 0 && - inConfig.numMultiChannelBuses == 0 && - inConfig.numAmbisonicsBuses == 0 && - inConfig.numMasaBuses == 0 ) && - "At least one input must be active" ); + inputMc = (input_mc *) input; + rendCtx = inputMc->base.ctx; + outConfig = *rendCtx.pOutConfig; - numActiveOutputs = - ( outConfig.ambisonics == IVAS_REND_AMBISONICS_NONE ? 0 : 1 ) + - ( outConfig.speakerLayout == IVAS_REND_SPEAKER_LAYOUT_NONE ? 0 : 1 ) + - ( outConfig.binauralFormat == IVAS_REND_BINAURAL_NONE ? 0 : 1 ); - assert( numActiveOutputs == 1 && "Only one output must be selected" ); + initRendInputBase( &inputMc->base, inConfig, id, rendCtx ); + setZeroPanMatrix( inputMc->panGains ); + inputMc->customLsInput = defaultCustomLs(); + inputMc->tdRendWrapper = defaultTdRendWrapper(); + inputMc->crendWrapper = defaultCrendWrapper(); + initRotGains( inputMc->rot_gains_prev ); + inputMc->lfeRouting = defaultLfeRouting( inConfig, + inputMc->customLsInput, + outConfig, + *inputMc->base.ctx.pCustomLsOut ); - /* ========================== Store useful values ========================= */ - st->sampleRate = sampleRate; - st->isConfigured = 1; - st->firstFrame = 1; - st->inConfig = inConfig; - st->outConfig = outConfig; - - /* Save total number of channels in ambisonics inputs */ - st->numInChannelsAmbi = 0; - for ( i = 0; i < inConfig.numAmbisonicsBuses; ++i ) + if ( outConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL || outConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM ) { - st->numInChannelsAmbi += getNumChannelsAmbisonics( inConfig.ambisonicsBuses[i].ambisonicsConfig ); + if ( ( error = initMcBinauralRendering( inputMc, inConfig, outConfig ) ) != IVAS_ERR_OK ) + { + return error; + } } - /* Save total number of channels in MC input */ - st->numInChannelsMc = 0; - for ( i = 0; i < inConfig.numMultiChannelBuses; ++i ) + if ( ( error = updateMcPanGains( inputMc, outConfig ) ) != IVAS_ERR_OK ) { - if ( inConfig.multiChannelBuses[i].speakerLayout == IVAS_REND_SPEAKER_LAYOUT_CUSTOM ) - { - st->numInChannelsMc += inConfig.inSetupCustom->num_spk + inConfig.inSetupCustom->num_lfe; - } - else - { - st->numInChannelsMc += getNumChannelsInSpeakerLayout( inConfig.multiChannelBuses[i].speakerLayout ); - } + return error; } + return IVAS_ERR_OK; +} - /* Save total number of channels of audio object inputs */ - st->numInChannelsObj = st->inConfig.numAudioObjects; +static void clearInputMc( input_mc *inputMc ) +{ + rendering_context rendCtx; - /* Save total number of channels of MASA inputs */ - st->numInChannelsMasa = st->inConfig.numMasaBuses == 1 ? (int16_t) st->inConfig.masaBus.numTc : 0; + rendCtx = inputMc->base.ctx; - /* Save total number of input channels */ - st->numInChannels = st->numInChannelsObj + st->numInChannelsAmbi + st->numInChannelsMc + st->numInChannelsMasa; + initRendInputBase( &inputMc->base, IVAS_REND_AUDIO_CONFIG_UNKNOWN, 0, rendCtx ); - if ( st->outConfig.ambisonics != IVAS_REND_AMBISONICS_NONE ) + /* Free input's internal handles */ + if ( inputMc->efapInWrapper.hEfap != NULL ) { - /* Save number of output channels */ - st->numOutChannels = getNumChannelsAmbisonics( st->outConfig.ambisonics ); + efap_free_data( &inputMc->efapInWrapper.hEfap ); } - else if ( st->outConfig.binauralFormat != IVAS_REND_BINAURAL_NONE ) + if ( inputMc->crendWrapper.hCrend != NULL ) { - st->numOutChannels = 2; + ivas_rend_closeCrend( &inputMc->crendWrapper ); } - - /* ============================ Prepare panning and ambisonics =========================== */ - if ( st->outConfig.speakerLayout != IVAS_REND_SPEAKER_LAYOUT_NONE ) + if ( inputMc->tdRendWrapper.hBinRendererTd != NULL ) { - if ( st->outConfig.speakerLayout == IVAS_REND_SPEAKER_LAYOUT_CUSTOM ) - { - /* Save number of output channels */ - st->numOutChannels = st->outConfig.outSetupCustom->num_spk + st->outConfig.outSetupCustom->num_lfe; - - /* Open and initialize EFAP struct */ - if ( ( error = efap_init_data( &st->efapRenderer, st->outConfig.outSetupCustom->ls_azimuth, st->outConfig.outSetupCustom->ls_elevation, st->outConfig.outSetupCustom->num_spk, EFAP_MODE_EFAP ) ) != IVAS_ERR_OK ) - { - return error; - } - } - else - { - /* Save number of output channels */ - st->numOutChannels = getNumChannelsInSpeakerLayout( st->outConfig.speakerLayout ); - - /* Open and initialize EFAP struct */ - if ( ( error = efap_init_data( &st->efapRenderer, getSpeakerAzimuths( st->outConfig.speakerLayout ), getSpeakerElevations( st->outConfig.speakerLayout ), getNumNonLfeChannelsInSpeakerLayout( st->outConfig.speakerLayout ), EFAP_MODE_EFAP ) ) != IVAS_ERR_OK ) - { - return error; - } - } - - - assert( st->efapRenderer != NULL && "Could not init EFAP" ); - - /* Compute Ambisonics to loudspeaker decoding matrix */ - if ( ( error = getHoaRenderMtx( st->outConfig, &st->ambi_dec_mtx, 3 ) ) != IVAS_ERR_OK ) - { - return error; - } + ivas_td_binaural_close( &inputMc->tdRendWrapper.hBinRendererTd ); + inputMc->tdRendWrapper.hHrtfTD = NULL; } +} - /* Allocate temporary pan/enc buffer to avoid allocations during rendering */ - if ( st->outConfig.binauralFormat == IVAS_REND_BINAURAL_ROOM ) +static ivas_error initSbaPanGainsForMcOut( + input_sba *inputSba, + IVAS_REND_AudioConfig outConfig, + const LSSETUP_CUSTOM_STRUCT *outSetupCustom ) +{ + int16_t ambiOrderIn; + int16_t chInIdx, chOutIdx; + float *tmpDecMtx, *readPtr; + IVAS_OUTPUT_SETUP hOutSetup; + ivas_error error; + + if ( ( error = getAmbisonicsOrder( inputSba->base.inConfig, &ambiOrderIn ) ) != IVAS_ERR_OK ) { - st->tmpGainBuffer = count_calloc( getNumChannelsInSpeakerLayout( IVAS_REND_SPEAKER_LAYOUT_7_1_4 ), sizeof( float ) ); - st->noLfePanBuffer = count_calloc( getNumNonLfeChannelsInSpeakerLayout( IVAS_REND_SPEAKER_LAYOUT_7_1_4 ), sizeof( float ) ); + return error; } - else if ( st->outConfig.binauralFormat == IVAS_REND_BINAURAL_NONE ) + + if ( getAudioConfigType( outConfig ) != IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED ) { - st->tmpGainBuffer = count_calloc( st->numOutChannels, sizeof( float ) ); + assert( !"Invalid configuration" ); + return IVAS_ERR_WRONG_PARAMS; } - /* Allocate temporary buffer for panning gains with lfe omitted */ - if ( st->outConfig.speakerLayout != IVAS_REND_SPEAKER_LAYOUT_NONE ) - { - if ( st->outConfig.speakerLayout == IVAS_REND_SPEAKER_LAYOUT_CUSTOM ) - { - st->noLfePanBuffer = count_calloc( st->outConfig.outSetupCustom->num_spk, sizeof( float ) ); - } - else - { - st->noLfePanBuffer = count_calloc( getNumNonLfeChannelsInSpeakerLayout( st->outConfig.speakerLayout ), sizeof( float ) ); - } + switch ( outConfig ) + { + case IVAS_REND_AUDIO_CONFIG_MONO: + hOutSetup.ls_azimuth = ls_azimuth_CICP1; + hOutSetup.ls_elevation = ls_elevation_CICP1; + ivas_output_init( &hOutSetup, rendAudioConfigToIvasAudioConfig( outConfig ) ); + break; + case IVAS_REND_AUDIO_CONFIG_STEREO: + case IVAS_REND_AUDIO_CONFIG_5_1: + case IVAS_REND_AUDIO_CONFIG_7_1: + case IVAS_REND_AUDIO_CONFIG_5_1_2: + case IVAS_REND_AUDIO_CONFIG_5_1_4: + case IVAS_REND_AUDIO_CONFIG_7_1_4: + ivas_output_init( &hOutSetup, rendAudioConfigToIvasAudioConfig( outConfig ) ); + break; + case IVAS_REND_AUDIO_CONFIG_LS_CUSTOM: + ivas_ls_custom_setup( &hOutSetup, outSetupCustom ); + break; + default: + assert( !"Invalid speaker config" ); + return IVAS_ERR_WRONG_PARAMS; } - /* Create lookup tables for panning/encoding speaker signals */ - if ( st->inConfig.numMultiChannelBuses != 0 ) + /* obtain and copy over HOA decoding matrix */ + tmpDecMtx = NULL; + if ( ( error = ivas_sba_get_hoa_dec_matrix( hOutSetup, &tmpDecMtx, ambiOrderIn ) ) != IVAS_ERR_OK ) { - prepareMcPanGains( st ); - prepareLfeHandling( st ); + return error; } - /* Allocate structs for interpolation of object pan/enc gains between frames */ - if ( st->inConfig.numAudioObjects != 0 ) + readPtr = &tmpDecMtx[0]; + for ( chOutIdx = 0; chOutIdx < hOutSetup.nchan_out_woLFE + hOutSetup.num_lfe; ++chOutIdx ) { - st->objPanInfo = count_calloc( st->inConfig.numAudioObjects, sizeof( IVAS_REND_ObjPanInfo ) ); - - for ( i = 0; i < st->inConfig.numAudioObjects; ++i ) + for ( chInIdx = 0; chInIdx < SBA_NHARM_HOA3; ++chInIdx ) { - if ( st->outConfig.binauralFormat == IVAS_REND_BINAURAL_ROOM ) - { - st->objPanInfo[i].panGains = count_calloc( getNumChannelsInSpeakerLayout( IVAS_REND_SPEAKER_LAYOUT_7_1_4 ), sizeof( float ) ); - } - else if ( st->outConfig.binauralFormat == IVAS_REND_BINAURAL_NONE ) + if ( hOutSetup.num_lfe > 0 && chOutIdx == hOutSetup.index_lfe[0] ) { - st->objPanInfo[i].panGains = count_calloc( st->numOutChannels, sizeof( float ) ); + continue; /* nothing to be rendered to LFE */ } + inputSba->hoaDecMtx[chInIdx][chOutIdx] = *readPtr++; } } - /* Prepare MASA processing */ - if ( st->inConfig.numMasaBuses != 0 ) + count_free( tmpDecMtx ); + + return IVAS_ERR_OK; +} + +static ivas_error initSbaPanGainsForSbaOut( input_sba *inputSba, IVAS_REND_AudioConfig outConfig ) +{ + ivas_error error; + error = IVAS_ERR_OK; + + if ( getAudioConfigType( outConfig ) != IVAS_REND_AUDIO_CONFIG_TYPE_AMBISONICS ) { - st->decDummyMasaBin = allocDecoderDummy( st->sampleRate, st->numOutChannels, st->enableHeadRotation, st->rendererConfigEnabled ); + assert( !"Invalid configuration" ); + return IVAS_ERR_WRONG_PARAMS; + } - /* TODO @ Nokia: initialize decoder dummy for MASA rendering depending on output config. - Feel free to clean this up if some other structure works better. */ - if ( st->outConfig.ambisonics != IVAS_REND_AMBISONICS_NONE ) - { - if ( ( error = initDecoderDummyForMasaToAmbi( st->decDummyMasaBin, st->inConfig ) ) != IVAS_ERR_OK ) - { - return error; - } - } - else if ( st->outConfig.speakerLayout != IVAS_REND_SPEAKER_LAYOUT_NONE ) - { - if ( ( error = initDecoderDummyForMasaToChannels( st->decDummyMasaBin, st->inConfig ) ) != IVAS_ERR_OK ) - { - return error; - } - } - else if ( st->outConfig.binauralFormat != IVAS_REND_BINAURAL_NONE ) - { - if ( ( error = initDecoderDummyForMasaToBinaural( st->decDummyMasaBin, st->inConfig ) ) != IVAS_ERR_OK ) + fillIdentityPanMatrix( inputSba->hoaDecMtx ); + + return error; +} + +static ivas_error updateSbaPanGains( input_sba *inputSba, IVAS_REND_AudioConfig outConfig ) +{ + ivas_error error; + IVAS_REND_AudioConfig inConfig; + rendering_context rendCtx; + + /* Reset to all zeros - some functions below only write non-zero elements. */ + setZeroPanMatrix( inputSba->hoaDecMtx ); + + inConfig = inputSba->base.inConfig; + rendCtx = inputSba->base.ctx; + + switch ( getAudioConfigType( outConfig ) ) + { + case IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED: + error = initSbaPanGainsForMcOut( inputSba, outConfig, inputSba->base.ctx.pCustomLsOut ); + break; + case IVAS_REND_AUDIO_CONFIG_TYPE_AMBISONICS: + error = initSbaPanGainsForSbaOut( inputSba, outConfig ); + break; + case IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL: + switch ( outConfig ) { - return error; + case IVAS_REND_AUDIO_CONFIG_BINAURAL: + error = ivas_rend_openCrend( &inputSba->crendWrapper, + inConfig, + outConfig, + *rendCtx.pOutSampleRate ); + break; + case IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM: + if ( ( error = initSbaPanGainsForMcOut( inputSba, IVAS_REND_AUDIO_CONFIG_7_1_4, NULL ) ) != IVAS_ERR_OK ) + { + return error; + } + error = ivas_rend_openCrend( &inputSba->crendWrapper, + IVAS_REND_AUDIO_CONFIG_7_1_4, + outConfig, + *rendCtx.pOutSampleRate ); + break; + default: + return IVAS_ERR_INVALID_OUTPUT_FORMAT; } - } + break; + default: + return IVAS_ERR_INVALID_OUTPUT_FORMAT; + } + /* Check error here to keep switch statement more compact */ + if ( error != IVAS_ERR_OK ) + { + return error; } - /* Prepare binaural rendering if enabled */ - if ( st->outConfig.binauralFormat != IVAS_REND_BINAURAL_NONE ) + return IVAS_ERR_OK; +} + +static ivas_error setRendInputActiveSba( + void *input, + IVAS_REND_AudioConfig inConfig, + IVAS_REND_InputId id ) +{ + ivas_error error; + rendering_context rendCtx; + IVAS_REND_AudioConfig outConfig; + input_sba *inputSba; + + inputSba = (input_sba *) input; + rendCtx = inputSba->base.ctx; + outConfig = *rendCtx.pOutConfig; + + initRendInputBase( &inputSba->base, inConfig, id, rendCtx ); + setZeroPanMatrix( inputSba->hoaDecMtx ); + inputSba->crendWrapper = defaultCrendWrapper(); + initRotGains( inputSba->rot_gains_prev ); + + if ( ( error = updateSbaPanGains( inputSba, outConfig ) ) != IVAS_ERR_OK ) { - if ( headRotationEnabled ) - { - st->enableHeadRotation = 1; - } + return error; + } - if ( rendererConfigEnabled ) - { - st->rendererConfigEnabled = 1; - } + return error; +} +static void clearInputSba( input_sba *inputSba ) +{ + rendering_context rendCtx; - if ( st->inConfig.numAmbisonicsBuses != 0 ) - { - st->decDummyAmbiBin = allocDecoderDummy( st->sampleRate, st->numOutChannels, st->enableHeadRotation, st->rendererConfigEnabled ); - if ( ( error = initDecoderDummyForAmbiToBinaural( st->decDummyAmbiBin, st->inConfig, st->outConfig.binauralFormat ) ) != IVAS_ERR_OK ) - { - return error; - } + rendCtx = inputSba->base.ctx; - /* init ALLRAD for intermediate rendering to 7_1_4 for BINAURAL_ROOM */ - if ( st->outConfig.binauralFormat == IVAS_REND_BINAURAL_ROOM ) - { - if ( ( error = getHoaRenderMtx( st->outConfig, &st->ambi_dec_mtx, 3 ) ) != IVAS_ERR_OK ) - { - return error; - } - } - } + initRendInputBase( &inputSba->base, IVAS_REND_AUDIO_CONFIG_UNKNOWN, 0, rendCtx ); - if ( st->inConfig.numAudioObjects != 0 ) - { - st->decDummyObjBin = allocDecoderDummy( st->sampleRate, st->numOutChannels, st->enableHeadRotation, st->rendererConfigEnabled ); - if ( ( error = initDecoderDummyForObjToBinaural( st->decDummyObjBin, st->inConfig, st->outConfig.binauralFormat ) ) != IVAS_ERR_OK ) - { - return error; - } + /* Free input's internal handles */ + if ( inputSba->crendWrapper.hCrend != NULL ) + { + ivas_rend_closeCrend( &inputSba->crendWrapper ); + } +} - /* init EFAP for intermediate rendering to 7_1_4 for BINAURAL_ROOM */ - if ( st->outConfig.binauralFormat == IVAS_REND_BINAURAL_ROOM ) - { - if ( ( error = efap_init_data( &st->efapRenderer, getSpeakerAzimuths( IVAS_REND_SPEAKER_LAYOUT_7_1_4 ), getSpeakerElevations( IVAS_REND_SPEAKER_LAYOUT_7_1_4 ), getNumNonLfeChannelsInSpeakerLayout( IVAS_REND_SPEAKER_LAYOUT_7_1_4 ), EFAP_MODE_EFAP ) ) != IVAS_ERR_OK ) - { - return error; - } - } - } +ivas_error IVAS_REND_Open( + IVAS_REND_HANDLE *phIvasRend, + int32_t outputSampleRate, + IVAS_REND_AudioConfig outConfig ) +{ + int16_t i; + IVAS_REND_HANDLE hIvasRend; + ivas_error error; + int32_t numOutChannels; - if ( st->inConfig.numMultiChannelBuses != 0 ) - { - st->decDummyMcBin = allocDecoderDummy( st->sampleRate, st->numOutChannels, st->enableHeadRotation, st->rendererConfigEnabled ); - if ( ( error = initDecoderDummyForMcToBinaural( st->decDummyMcBin, st->inConfig, st->outConfig.binauralFormat, st->enableHeadRotation ) ) != IVAS_ERR_OK ) - { - return error; - } + /*-----------------------------------------------------------------* + * Validate function arguments + *-----------------------------------------------------------------*/ + + if ( phIvasRend == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + if ( ( error = validateOutputAudioConfig( outConfig ) ) != IVAS_ERR_OK ) + { + return error; + } + if ( ( error = validateOutputSampleRate( outputSampleRate, outConfig ) ) != IVAS_ERR_OK ) + { + return error; + } - /* init EFAP for BINAURAL_ROOM via 7_1_4 */ - if ( st->outConfig.binauralFormat == IVAS_REND_BINAURAL_ROOM ) - { - if ( ( error = efap_init_data( &st->efapRenderer, getSpeakerAzimuths( IVAS_REND_SPEAKER_LAYOUT_7_1_4 ), getSpeakerElevations( IVAS_REND_SPEAKER_LAYOUT_7_1_4 ), getNumNonLfeChannelsInSpeakerLayout( IVAS_REND_SPEAKER_LAYOUT_7_1_4 ), EFAP_MODE_EFAP ) ) != IVAS_ERR_OK ) - { - return error; - } - } - } + *phIvasRend = (IVAS_REND_HANDLE) count_malloc( sizeof( struct IVAS_REND ) ); + if ( *phIvasRend == NULL ) + { + return IVAS_ERR_FAILED_ALLOC; } - /* =========================== Prepare crossfades ========================= */ - frameSize_smpls = sampleRate / FRAMES_PER_SEC; - st->crossfade = count_calloc( frameSize_smpls, sizeof( float ) ); + hIvasRend = *phIvasRend; + hIvasRend->sampleRateOut = outputSampleRate; + hIvasRend->outputConfig = outConfig; + hIvasRend->customLsOut = defaultCustomLs(); + hIvasRend->hLimiter = NULL; + hIvasRend->efapOutWrapper.hEfap = NULL; + hIvasRend->efapOutWrapper.pCustomLsSetup = NULL; +#ifdef DEBUGGING + hIvasRend->numClipping = 0; +#endif - for ( j = 0; j < frameSize_smpls; ++j ) + /* Initialize limiter */ + if ( ( error = IVAS_REND_NumOutChannels( hIvasRend, &numOutChannels ) ) != IVAS_ERR_OK ) { - st->crossfade[j] = (float) j / ( frameSize_smpls - 1 ); + return error; } + initLimiter( &hIvasRend->hLimiter, numOutChannels, outputSampleRate ); - /* ========================= Prepare optimizations ======================== */ - /* Make note of possible processing shortcuts in cases where input and output - * config is the same or similar. This only needs to be done for MC I/O, since - * Ambisonics I/O can always be passed through and objects can never be passed - * through */ - if ( st->inConfig.numMultiChannelBuses > 0 && st->outConfig.speakerLayout != IVAS_REND_SPEAKER_LAYOUT_NONE ) + /* Initialize headrotation data */ + initHeadRotation( hIvasRend ); + + /* Initialize EFAP */ + initEfap( &hIvasRend->efapOutWrapper, outConfig, &hIvasRend->customLsOut ); + + /* Initialize inputs */ + for ( i = 0; i < RENDERER_MAX_ISM_INPUTS; ++i ) { - prepareMcPassthrough( st ); + initRendInputBase( &hIvasRend->inputsIsm[i].base, + IVAS_REND_AUDIO_CONFIG_UNKNOWN, + 0, + getRendCtx( hIvasRend ) ); + hIvasRend->inputsIsm[i].crendWrapper.hCrend = NULL; + hIvasRend->inputsIsm[i].tdRendWrapper.hBinRendererTd = NULL; + } + for ( i = 0; i < RENDERER_MAX_MC_INPUTS; ++i ) + { + initRendInputBase( &hIvasRend->inputsMc[i].base, + IVAS_REND_AUDIO_CONFIG_UNKNOWN, + 0, + getRendCtx( hIvasRend ) ); + hIvasRend->inputsMc[i].efapInWrapper.hEfap = NULL; + hIvasRend->inputsMc[i].crendWrapper.hCrend = NULL; + hIvasRend->inputsMc[i].tdRendWrapper.hBinRendererTd = NULL; + } + for ( i = 0; i < RENDERER_MAX_SBA_INPUTS; ++i ) + { + initRendInputBase( &hIvasRend->inputsSba[i].base, + IVAS_REND_AUDIO_CONFIG_UNKNOWN, + 0, + getRendCtx( hIvasRend ) ); + hIvasRend->inputsSba[i].crendWrapper.hCrend = NULL; } - /* ============================ Configure limiter =========================== */ - st->hLimiter = ivas_limiter_open( st->numOutChannels, st->sampleRate ); - - return error; + return IVAS_ERR_OK; } -void IVAS_REND_SetHeadRotation( - IVAS_REND_HANDLE st, - const IVAS_QUATERNION headRot[RENDERER_HEAD_POSITIONS_PER_FRAME] ) +static LSSETUP_CUSTOM_STRUCT makeCustomLsSetup( IVAS_CUSTOM_LS_DATA rendCustomLsLayout ) { int16_t i; + LSSETUP_CUSTOM_STRUCT customLs; - assert( st != NULL ); + /* Copy layout description */ + customLs.num_spk = rendCustomLsLayout.num_spk; + mvr2r( rendCustomLsLayout.azimuth, customLs.ls_azimuth, rendCustomLsLayout.num_spk ); + mvr2r( rendCustomLsLayout.elevation, customLs.ls_elevation, rendCustomLsLayout.num_spk ); - for ( i = 0; i < RENDERER_HEAD_POSITIONS_PER_FRAME; ++i ) + customLs.is_planar_setup = 1; + for ( i = 0; i < rendCustomLsLayout.num_spk; ++i ) { - st->headRotationData[i] = headRot[i]; + if ( fabsf( rendCustomLsLayout.elevation[i] ) > EPSILON ) + { + customLs.is_planar_setup = 0; + break; + } } + + customLs.num_lfe = rendCustomLsLayout.num_lfe; + mvs2s( rendCustomLsLayout.lfe_idx, customLs.lfe_idx, rendCustomLsLayout.num_lfe ); + + return customLs; } -ivas_error IVAS_REND_FeedMasaMetadata( - IVAS_REND_HANDLE st, - IVAS_MASA_METADATA_HANDLE hMasaMetadata ) +static ivas_error validateCustomLsLayout( IVAS_CUSTOM_LS_DATA layout ) { - if ( !st->isConfigured ) + int32_t i; + + /* Negative number of speakers or LFEs makes no sense */ + if ( layout.num_spk < 0 || layout.num_lfe < 0 ) { - return IVAS_ERR_NOT_CONFIGURED; + return IVAS_ERR_INVALID_CUSTOM_LS_LAYOUT; } - - if ( st->inConfig.numMasaBuses == 0 ) + /* There must be at least one speaker or LFE in the layout */ + if ( layout.num_spk + layout.num_lfe <= 0 ) { - return IVAS_ERR_METADATA_NOT_EXPECTED; + return IVAS_ERR_INVALID_CUSTOM_LS_LAYOUT; + } + /* LFE indices must be positive */ + for ( i = 0; i < layout.num_lfe; ++i ) + { + if ( layout.lfe_idx[i] < 0 ) + { + return IVAS_ERR_INVALID_CUSTOM_LS_LAYOUT; + } } - - st->masaMetadata = *hMasaMetadata; return IVAS_ERR_OK; } -void IVAS_REND_Render( - IVAS_REND_HANDLE st, - const IVAS_REND_AudioBuffer inAudio, - const IVAS_REND_AudioObjectMetadataBuffer metadataBuffer, - IVAS_REND_AudioBuffer outAudio ) +ivas_error IVAS_REND_ConfigureCustomOutputLoudspeakerLayout( + IVAS_REND_HANDLE hIvasRend, + IVAS_CUSTOM_LS_DATA layout ) { -#ifdef WMOPS - wmops_sub_start( "IVAS_REND_Render" ); -#endif + int32_t numOutChannels; + ivas_error error; + int32_t i; + input_mc *inputMc; + input_sba *inputSba; - /* ============================= Error checks ============================= */ - assert( st != NULL && "Can't render - renderer pointer is NULL" ); - assert( st->isConfigured && "Can't render - renderer pointer is not configured" ); - assert( inAudio.config.sampleRate == outAudio.config.sampleRate && "Input and output sample rate must be the same" ); - assert( inAudio.config.bufferSize == outAudio.config.bufferSize && "Input and output frame size must be the same" ); - assert( inAudio.config.numChannels == st->numInChannels && "Number of input channels does not match between renderer and input config" ); - assert( outAudio.config.numChannels == st->numOutChannels && "Number of input channels does not match between renderer and input config" ); - assert( inAudio.config.sampleRate != 0 && "Invalid sample rate" ); - assert( inAudio.config.bufferSize != 0 && "Invalid frame size" ); - assert( inAudio.data != NULL && "Can't render - input buffer is empty" ); - - /* ========================== Actual processing =========================== */ - /* Clear output buffer */ - set_zero( outAudio.data, outAudio.config.numChannels * outAudio.config.bufferSize ); + /*-----------------------------------------------------------------* + * Validate function arguments + *-----------------------------------------------------------------*/ - /* Render target format: Ambisonics */ - if ( st->outConfig.ambisonics != IVAS_REND_AMBISONICS_NONE ) + if ( hIvasRend == NULL ) { - if ( st->inConfig.numAmbisonicsBuses != 0 ) - { - renderAmbiToAmbi( st, inAudio, outAudio ); - } + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + if ( hIvasRend->outputConfig != IVAS_REND_AUDIO_CONFIG_LS_CUSTOM ) + { + /* Specifying details of custom speaker layout only makes sense if output config is set to custom speaker layout */ + return IVAS_ERR_INVALID_OUTPUT_FORMAT; + } + if ( ( error = validateCustomLsLayout( layout ) ) != IVAS_ERR_OK ) + { + return error; + } - if ( st->inConfig.numMultiChannelBuses != 0 ) - { - renderChannelsToAmbi( st, inAudio, outAudio ); - } + hIvasRend->customLsOut = makeCustomLsSetup( layout ); - if ( st->inConfig.numAudioObjects != 0 ) - { - renderObjectsToAmbi( st, inAudio, metadataBuffer, outAudio ); - } + /* Re-initialize limiter - number of output channels may have changed */ + if ( ( error = IVAS_REND_NumOutChannels( hIvasRend, &numOutChannels ) ) != IVAS_ERR_OK ) + { + return error; + } + initLimiter( &hIvasRend->hLimiter, + numOutChannels, + hIvasRend->sampleRateOut ); - if ( st->inConfig.numMasaBuses != 0 ) - { - renderMasaToAmbi( st, inAudio, outAudio ); - } - } /* Render target format: multichannel */ - else if ( st->outConfig.speakerLayout != IVAS_REND_SPEAKER_LAYOUT_NONE ) + /* Re-initialize EFAP - output layout has changed or has been fully defined for the first time */ + initEfap( &hIvasRend->efapOutWrapper, + hIvasRend->outputConfig, + &hIvasRend->customLsOut ); + + /* Re-initialize panning gains for each active MC input, This includes re-initializing + * LFE handling for the new output layout, which means custom LFE handling is overwritten, + * if previously set for any MC input. */ + for ( i = 0; i < RENDERER_MAX_MC_INPUTS; ++i ) { - if ( st->inConfig.numAmbisonicsBuses != 0 ) + inputMc = &hIvasRend->inputsMc[i]; + if ( inputMc->base.inConfig == IVAS_REND_AUDIO_CONFIG_UNKNOWN ) { - renderAmbiToChannels( st, inAudio, outAudio ); + /* Input inactive, skip. */ + continue; } - - if ( st->inConfig.numMultiChannelBuses != 0 ) + inputMc->lfeRouting = defaultLfeRouting( inputMc->base.inConfig, + inputMc->customLsInput, + hIvasRend->outputConfig, + *inputMc->base.ctx.pCustomLsOut ); + if ( ( error = updateMcPanGains( inputMc, hIvasRend->outputConfig ) ) != IVAS_ERR_OK ) { - renderChannelsToChannels( st, inAudio, outAudio ); + return error; } + } - if ( st->inConfig.numAudioObjects != 0 ) + /* Re-initialize panning gains for each active SBA input */ + for ( i = 0; i < RENDERER_MAX_SBA_INPUTS; ++i ) + { + inputSba = &hIvasRend->inputsSba[i]; + if ( inputSba->base.inConfig == IVAS_REND_AUDIO_CONFIG_UNKNOWN ) { - renderObjectsToChannels( st, inAudio, metadataBuffer, outAudio ); + /* Input inactive, skip. */ + continue; } - - if ( st->inConfig.numMasaBuses != 0 ) + if ( ( error = updateSbaPanGains( inputSba, hIvasRend->outputConfig ) ) != IVAS_ERR_OK ) { - renderMasaToChannels( st, inAudio, outAudio ); + return error; } - } /* Render target format: binaural */ - else if ( st->outConfig.binauralFormat != IVAS_REND_BINAURAL_NONE ) - { - /* Rendering to binaural using dummy IVAS decoders */ - assert( inAudio.config.bufferSize == st->sampleRate / FRAMES_PER_SEC && "Using IVAS components requires frame size of 20 ms" ); - assert( inAudio.config.numChannels <= MAX_OUTPUT_CHANNELS && "Max 16 input channels supported" ); - assert( outAudio.config.numChannels == 2 && "2 output channels expected for rendering to binaural" ); + } - if ( st->inConfig.numAmbisonicsBuses != 0 ) - { - renderAmbiToBinaural( st, inAudio, outAudio ); - } + return IVAS_ERR_OK; +} - if ( st->inConfig.numMultiChannelBuses != 0 ) - { - renderChannelsToBinaural( st, inAudio, outAudio ); - } +ivas_error IVAS_REND_NumOutChannels( + IVAS_REND_CONST_HANDLE hIvasRend, + int32_t *numOutChannels ) +{ + ivas_error error; - if ( st->inConfig.numAudioObjects != 0 ) - { - renderObjectsToBinaural( st, inAudio, metadataBuffer, outAudio ); - } + /*-----------------------------------------------------------------* + * Validate function arguments + *-----------------------------------------------------------------*/ - if ( st->inConfig.numMasaBuses != 0 ) - { - renderMasaToBinaural( st, inAudio, outAudio ); - } + if ( hIvasRend == NULL || numOutChannels == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; } - /* Apply limiting in place */ -#ifdef DEBUGGING - st->numClipping += -#endif - ivas_limiter_renderer( - st->hLimiter, - outAudio.data, - outAudio.config.bufferSize, - LIMITER_THRESHOLD ); - - if ( st->firstFrame ) + /* Handle special cases where additional info is needed from the renderer, otherwise use getAudioConfigNumChannels() */ + switch ( hIvasRend->outputConfig ) + { + case IVAS_REND_AUDIO_CONFIG_LS_CUSTOM: + *numOutChannels = hIvasRend->customLsOut.num_spk + hIvasRend->customLsOut.num_lfe; + error = IVAS_ERR_OK; + break; + default: + error = getAudioConfigNumChannels( hIvasRend->outputConfig, numOutChannels ); + break; + } + if ( error != IVAS_ERR_OK ) { - st->firstFrame = 0; + return error; } -#ifdef WMOPS - wmops_sub_end(); -#endif + return IVAS_ERR_OK; } -void IVAS_REND_OpenCustomLayout( - IVAS_LSSETUP_CUSTOM_HANDLE *outSetupCustom ) +static IVAS_REND_InputId makeInputId( IVAS_REND_AudioConfig config, int32_t inputIndex ) { - ivas_ls_custom_open( outSetupCustom ); + /* 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 getAudioConfigType( config ) << 8 | ( inputIndex + 1 ); } -void IVAS_REND_SetNeverDropLfe( - IVAS_REND_HANDLE st, - int8_t neverDropLfe ) +static ivas_error getInputById( IVAS_REND_HANDLE hIvasRend, IVAS_REND_InputId inputId, void **ppInput ) { - st->neverDropLfe = neverDropLfe; -} + int32_t inputIndex; + IVAS_REND_AudioConfigType configType; + input_base *pInputBase; -int16_t IVAS_REND_GetInChannels( - IVAS_REND_HANDLE st ) -{ - assert( st != NULL && "Can't get number of input channels - renderer pointer is NULL" ); - if ( st ) + /* Reverse makeInputId() */ + inputIndex = ( inputId & 0xFF ) - 1; + configType = ( inputId & 0xFF00 ) >> 8; + + /* Validate values derived from input ID */ + if ( inputIndex < 0 ) { - return st->numInChannels; + return IVAS_ERR_INVALID_INPUT_ID; + } + switch ( configType ) + { + case IVAS_REND_AUDIO_CONFIG_TYPE_OBJECT_BASED: + if ( inputIndex > RENDERER_MAX_ISM_INPUTS ) + { + return IVAS_ERR_INVALID_INPUT_ID; + } + pInputBase = &hIvasRend->inputsIsm[inputIndex].base; + break; + case IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED: + if ( inputIndex > RENDERER_MAX_MC_INPUTS ) + { + return IVAS_ERR_INVALID_INPUT_ID; + } + pInputBase = &hIvasRend->inputsMc[inputIndex].base; + break; + case IVAS_REND_AUDIO_CONFIG_TYPE_AMBISONICS: + if ( inputIndex > RENDERER_MAX_SBA_INPUTS ) + { + return IVAS_ERR_INVALID_INPUT_ID; + } + pInputBase = &hIvasRend->inputsSba[inputIndex].base; + break; + default: + return IVAS_ERR_INVALID_INPUT_ID; } - return 0; -} -int16_t IVAS_REND_GetOutChannels( - IVAS_REND_HANDLE st ) -{ - assert( st != NULL && "Can't get number of output channels - renderer pointer is NULL" ); - if ( st ) + /* Ensure input ID matches and that input is active */ + if ( pInputBase->id != inputId || pInputBase->inConfig == IVAS_REND_AUDIO_CONFIG_UNKNOWN ) { - return st->numOutChannels; + return IVAS_ERR_INVALID_INPUT_ID; } - return 0; + + /* Validation done, set value via output parameter */ + *ppInput = pInputBase; + + return IVAS_ERR_OK; } -void IVAS_REND_Close( IVAS_REND_HANDLE *st ) +/* Unfortunately code duplication here is the only way to avoid warnings about const casting */ +static ivas_error getConstInputById( IVAS_REND_CONST_HANDLE hIvasRend, IVAS_REND_InputId inputId, const void **ppInput ) { - uint32_t i; - uint32_t j; - uint32_t numNonLfeChannels; - IVAS_REND_HANDLE hIvasRend; - - if ( st == NULL || *st == NULL ) - { - return; - } - hIvasRend = *st; + int32_t inputIndex; + IVAS_REND_AudioConfigType configType; + const input_base *pInputBase; - if ( hIvasRend->efapRenderer != NULL ) - { - efap_free_data( &hIvasRend->efapRenderer ); - } + /* Reverse makeInputId() */ + inputIndex = ( inputId & 0xFF ) - 1; + configType = ( inputId & 0xFF00 ) >> 8; - if ( hIvasRend->objPanInfo != NULL ) + /* Validate values derived from input ID */ + if ( inputIndex < 0 ) { - for ( i = 0; i < hIvasRend->inConfig.numAudioObjects; ++i ) - { - if ( hIvasRend->objPanInfo[i].panGains != NULL ) - { - count_free( hIvasRend->objPanInfo[i].panGains ); - } - } - - count_free( hIvasRend->objPanInfo ); + return IVAS_ERR_INVALID_INPUT_ID; } - - if ( hIvasRend->speakerPanGains != NULL ) + switch ( configType ) { - for ( i = 0; i < hIvasRend->inConfig.numMultiChannelBuses; ++i ) - { - if ( hIvasRend->inConfig.multiChannelBuses[i].speakerLayout == IVAS_REND_SPEAKER_LAYOUT_CUSTOM ) + case IVAS_REND_AUDIO_CONFIG_TYPE_OBJECT_BASED: + if ( inputIndex > RENDERER_MAX_ISM_INPUTS ) { - numNonLfeChannels = hIvasRend->inConfig.inSetupCustom->num_spk; + return IVAS_ERR_INVALID_INPUT_ID; } - else + pInputBase = &hIvasRend->inputsIsm[inputIndex].base; + break; + case IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED: + if ( inputIndex > RENDERER_MAX_MC_INPUTS ) { - numNonLfeChannels = getNumNonLfeChannelsInSpeakerLayout( hIvasRend->inConfig.multiChannelBuses[i].speakerLayout ); + return IVAS_ERR_INVALID_INPUT_ID; } - - for ( j = 0; j < numNonLfeChannels; ++j ) + pInputBase = &hIvasRend->inputsMc[inputIndex].base; + break; + case IVAS_REND_AUDIO_CONFIG_TYPE_AMBISONICS: + if ( inputIndex > RENDERER_MAX_SBA_INPUTS ) { - count_free( hIvasRend->speakerPanGains[i][j] ); + return IVAS_ERR_INVALID_INPUT_ID; } - - count_free( hIvasRend->speakerPanGains[i] ); - } - - count_free( hIvasRend->speakerPanGains ); + pInputBase = &hIvasRend->inputsSba[inputIndex].base; + break; + default: + return IVAS_ERR_INVALID_INPUT_ID; } - if ( hIvasRend->inConfig.inSetupCustom != NULL ) + /* Ensure input ID matches and that input is active */ + if ( pInputBase->id != inputId || pInputBase->inConfig == IVAS_REND_AUDIO_CONFIG_UNKNOWN ) { - count_free( hIvasRend->inConfig.inSetupCustom ); - hIvasRend->inConfig.inSetupCustom = NULL; + return IVAS_ERR_INVALID_INPUT_ID; } - if ( hIvasRend->outConfig.outSetupCustom != NULL ) + /* Validation done, set value via output parameter */ + *ppInput = pInputBase; + + return IVAS_ERR_OK; +} + +static ivas_error findFreeInputSlot( + const void *inputs, + int32_t inputStructSize, + 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). + 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 ) { - count_free( hIvasRend->outConfig.outSetupCustom ); - hIvasRend->outConfig.outSetupCustom = NULL; + pInputBase = (const input_base *) pByte; + + if ( pInputBase->inConfig == IVAS_REND_AUDIO_CONFIG_UNKNOWN ) + { + *inputIndex = i; + canAddInput = true; + break; + } } - if ( hIvasRend->tmpGainBuffer != NULL ) + if ( !canAddInput ) { - count_free( hIvasRend->tmpGainBuffer ); + return IVAS_ERR_TOO_MANY_INPUTS; } - if ( hIvasRend->noLfePanBuffer != NULL ) + return IVAS_ERR_OK; +} + +ivas_error IVAS_REND_AddInput( + IVAS_REND_HANDLE hIvasRend, + IVAS_REND_AudioConfig inConfig, + IVAS_REND_InputId *inputId ) +{ + ivas_error error; + int32_t maxNumInputsOfType; + void *inputsArray; + int32_t inputStructSize; + ivas_error ( *activateInput )( void *, IVAS_REND_AudioConfig, IVAS_REND_InputId ); + int32_t inputIndex; + + /*-----------------------------------------------------------------* + * Validate function arguments + *-----------------------------------------------------------------*/ + + if ( hIvasRend == NULL || inputId == NULL ) { - count_free( hIvasRend->noLfePanBuffer ); + return IVAS_ERR_UNEXPECTED_NULL_POINTER; } - if ( hIvasRend->crossfade != NULL ) - { - count_free( hIvasRend->crossfade ); + switch ( getAudioConfigType( inConfig ) ) + { + case IVAS_REND_AUDIO_CONFIG_TYPE_OBJECT_BASED: + maxNumInputsOfType = RENDERER_MAX_ISM_INPUTS; + inputsArray = hIvasRend->inputsIsm; + inputStructSize = sizeof( *hIvasRend->inputsIsm ); + activateInput = setRendInputActiveIsm; + break; + case IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED: + maxNumInputsOfType = RENDERER_MAX_MC_INPUTS; + inputsArray = hIvasRend->inputsMc; + inputStructSize = sizeof( *hIvasRend->inputsMc ); + activateInput = setRendInputActiveMc; + break; + case IVAS_REND_AUDIO_CONFIG_TYPE_AMBISONICS: + maxNumInputsOfType = RENDERER_MAX_SBA_INPUTS; + inputsArray = hIvasRend->inputsSba; + inputStructSize = sizeof( *hIvasRend->inputsSba ); + activateInput = setRendInputActiveSba; + break; + default: + return IVAS_ERR_INVALID_INPUT_FORMAT; } - if ( hIvasRend->mcPassthrough != NULL ) + /* Find first free input in array corresponding to input type */ + if ( ( error = findFreeInputSlot( inputsArray, + inputStructSize, + maxNumInputsOfType, + &inputIndex ) ) != IVAS_ERR_OK ) { - count_free( hIvasRend->mcPassthrough ); + return error; } - if ( hIvasRend->lfePanGains ) + *inputId = makeInputId( inConfig, inputIndex ); + + if ( ( error = activateInput( (uint8_t *) inputsArray + inputStructSize * inputIndex, + inConfig, + *inputId ) ) != IVAS_ERR_OK ) { - count_free( hIvasRend->lfePanGains ); + return error; } - if ( hIvasRend->ambi_dec_mtx != NULL ) + return IVAS_ERR_OK; +} + +ivas_error IVAS_REND_ConfigureCustomInputLoudspeakerLayout( + IVAS_REND_HANDLE hIvasRend, + IVAS_REND_InputId inputId, + IVAS_CUSTOM_LS_DATA layout ) +{ + input_mc *inputMc; + ivas_error error; + + /*-----------------------------------------------------------------* + * Validate function arguments + *-----------------------------------------------------------------*/ + + if ( hIvasRend == NULL ) { - count_free( hIvasRend->ambi_dec_mtx ); + return IVAS_ERR_UNEXPECTED_NULL_POINTER; } - - if ( hIvasRend->decDummyAmbiBin != NULL ) + if ( ( error = validateCustomLsLayout( layout ) ) != IVAS_ERR_OK ) { - ivas_crend_close( hIvasRend->decDummyAmbiBin ); - ivas_render_config_close( &hIvasRend->decDummyAmbiBin->hRenderConfig ); - count_free( hIvasRend->decDummyAmbiBin->hDecoderConfig ); - if ( hIvasRend->enableHeadRotation ) - { - count_free( hIvasRend->decDummyAmbiBin->hHeadTrackData ); - } - count_free( hIvasRend->decDummyAmbiBin ); + return error; } - - if ( hIvasRend->decDummyMcBin != NULL ) + if ( ( error = getInputById( hIvasRend, inputId, (void **) &inputMc ) ) != IVAS_ERR_OK ) { - if ( hIvasRend->decDummyMcBin->hEFAPdata != NULL ) - { - efap_free_data( &hIvasRend->decDummyMcBin->hEFAPdata ); - } - ivas_crend_close( hIvasRend->decDummyMcBin ); - ivas_td_binaural_close( &hIvasRend->decDummyMcBin->hBinRendererTd ); - ivas_render_config_close( &hIvasRend->decDummyMcBin->hRenderConfig ); - count_free( hIvasRend->decDummyMcBin->hDecoderConfig ); - if ( hIvasRend->enableHeadRotation ) - { - count_free( hIvasRend->decDummyMcBin->hHeadTrackData ); - } - if ( hIvasRend->decDummyMcBin->hEFAPdata ) - { - efap_free_data( &hIvasRend->decDummyMcBin->hEFAPdata ); - } - count_free( hIvasRend->decDummyMcBin ); + return error; } - - if ( hIvasRend->decDummyObjBin != NULL ) + if ( inputMc->base.inConfig != IVAS_REND_AUDIO_CONFIG_LS_CUSTOM ) { - ivas_crend_close( hIvasRend->decDummyObjBin ); - ivas_td_binaural_close( &hIvasRend->decDummyObjBin->hBinRendererTd ); - ivas_render_config_close( &hIvasRend->decDummyObjBin->hRenderConfig ); - count_free( hIvasRend->decDummyObjBin->hDecoderConfig ); + /* Specifying details of custom speaker layout only makes sense if input config is set to custom speaker layout */ + return IVAS_ERR_INVALID_INPUT_FORMAT; + } - if ( hIvasRend->enableHeadRotation ) - { - count_free( hIvasRend->decDummyObjBin->hHeadTrackData ); - } + /* Re-initialize panning gains for the MC input, This includes re-initializing LFE handling + * for the new input layout, which means custom LFE handling is overwritten, if previously + * set for the MC input. */ + inputMc->customLsInput = makeCustomLsSetup( layout ); - for ( i = 0; i < hIvasRend->inConfig.numAudioObjects; ++i ) - { - count_free( hIvasRend->decDummyObjBin->hIsmMetaData[i] ); - } + inputMc->lfeRouting = defaultLfeRouting( inputMc->base.inConfig, + inputMc->customLsInput, + hIvasRend->outputConfig, + *inputMc->base.ctx.pCustomLsOut ); - count_free( hIvasRend->decDummyObjBin ); - } + initEfap( &inputMc->efapInWrapper, inputMc->base.inConfig, &inputMc->customLsInput ); - if ( hIvasRend->decDummyMasaBin != NULL ) + if ( hIvasRend->outputConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL || hIvasRend->outputConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM ) { - ivas_render_config_close( &hIvasRend->decDummyMasaBin->hRenderConfig ); - count_free( hIvasRend->decDummyMasaBin->hDecoderConfig ); - - if ( hIvasRend->enableHeadRotation ) + if ( ( error = initMcBinauralRendering( inputMc, inputMc->base.inConfig, hIvasRend->outputConfig ) ) != IVAS_ERR_OK ) { - count_free( hIvasRend->decDummyMasaBin->hHeadTrackData ); + return error; } - - /* TODO @ Nokia: free any other memory allocated in the dummy decoder */ - - count_free( hIvasRend->decDummyMasaBin ); + } + if ( ( error = updateMcPanGains( inputMc, hIvasRend->outputConfig ) ) != IVAS_ERR_OK ) + { + return error; } - ivas_limiter_close( &hIvasRend->hLimiter ); - - count_free( hIvasRend ); - *st = NULL; + return IVAS_ERR_OK; } -ivas_error IVAS_REND_GetDelay( - IVAS_REND_HANDLE st, /* 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 */ +ivas_error IVAS_REND_SetInputGain( + IVAS_REND_HANDLE hIvasRend, + IVAS_REND_InputId inputId, + float gain /* linear gain, not in dB */ ) { + input_base *inputBase; + ivas_error error; - if ( st == NULL ) - { - return IVAS_ERR_UNEXPECTED_NULL_POINTER; - } + /*-----------------------------------------------------------------* + * Validate function arguments + *-----------------------------------------------------------------*/ - if ( st->outConfig.binauralFormat != IVAS_REND_BINAURAL_NONE ) + if ( hIvasRend == NULL ) { - if ( ( st->decDummyAmbiBin != NULL && st->decDummyAmbiBin->renderer_type == RENDERER_BINAURAL_OBJECTS_TD ) || - ( st->decDummyObjBin != NULL && st->decDummyObjBin->renderer_type == RENDERER_BINAURAL_OBJECTS_TD ) || - ( st->decDummyMcBin != NULL && st->decDummyMcBin->renderer_type == RENDERER_BINAURAL_OBJECTS_TD ) ) - { - *nSamples = NS2SA( st->sampleRate, (int32_t) ( (float) IVAS_FB_DEC_DELAY_NS + 0.5f ) ); - } - else if ( ( st->decDummyAmbiBin != NULL ) && - ( ( st->decDummyAmbiBin->renderer_type == RENDERER_BINAURAL_MIXER_CONV ) || - ( st->decDummyAmbiBin->renderer_type == RENDERER_BINAURAL_MIXER_CONV_ROOM ) ) ) - { - *nSamples = NS2SA( st->sampleRate, (int32_t) ( (float) st->decDummyAmbiBin->binaural_latency_ns + 0.5f ) ); - } - else if ( ( st->decDummyObjBin != NULL ) && - ( ( st->decDummyObjBin->renderer_type == RENDERER_BINAURAL_MIXER_CONV ) || - ( st->decDummyObjBin->renderer_type == RENDERER_BINAURAL_MIXER_CONV_ROOM ) ) ) - { - *nSamples = NS2SA( st->sampleRate, (int32_t) ( (float) st->decDummyObjBin->binaural_latency_ns + 0.5f ) ); - } - else if ( ( st->decDummyMcBin != NULL ) && - ( ( st->decDummyMcBin->renderer_type == RENDERER_BINAURAL_MIXER_CONV ) || - ( st->decDummyMcBin->renderer_type == RENDERER_BINAURAL_MIXER_CONV_ROOM ) ) ) - { - if ( st->forceBinLfeLpf ) - { - *nSamples = max( - NS2SA( st->sampleRate, (int32_t) ( (float) st->decDummyMcBin->binaural_latency_ns + 0.5f ) ), - NS2SA( st->sampleRate, ivas_lfe_lpf_delay[IVAS_FILTER_ORDER_4 - 3] * 1000000000L ) ); - } - else - { - *nSamples = NS2SA( st->sampleRate, (int32_t) ( (float) st->decDummyMcBin->binaural_latency_ns + 0.5f ) ); - } - } - else - { - *nSamples = 0; - } + return IVAS_ERR_UNEXPECTED_NULL_POINTER; } - else + if ( ( error = getInputById( hIvasRend, inputId, (void **) &inputBase ) ) != IVAS_ERR_OK ) { - *nSamples = 0; + return error; } - *timeScale = st->sampleRate; + inputBase->gain = gain; return IVAS_ERR_OK; } -#ifdef DEBUGGING -int32_t IVAS_REND_GetNoCLipping( - IVAS_REND_HANDLE st /* i : Renderer state */ -) -{ - return st->numClipping; -} - -int32_t IVAS_REND_GetCntFramesLimited( - IVAS_REND_HANDLE st /* i : Renderer state */ -) +static int32_t getNumLfeChannels( input_mc *inputMc ) { - if (st->hLimiter == NULL) + switch ( inputMc->base.inConfig ) { - return 0; + case IVAS_REND_AUDIO_CONFIG_5_1: + case IVAS_REND_AUDIO_CONFIG_7_1: + case IVAS_REND_AUDIO_CONFIG_5_1_2: + case IVAS_REND_AUDIO_CONFIG_5_1_4: + case IVAS_REND_AUDIO_CONFIG_7_1_4: + return 1; + case IVAS_REND_AUDIO_CONFIG_LS_CUSTOM: + return inputMc->customLsInput.num_lfe; + default: + break; } - - return st->hLimiter->cnt_frames_limited; -} -#endif -/* ============================= Local functions ============================ */ -static float *get_smpl_ptr( IVAS_REND_AudioBuffer buffer, uint32_t chnlIdx, uint32_t smplIdx ) -{ - return buffer.data + chnlIdx * buffer.config.bufferSize + smplIdx; + return 0; } -static void applyGainToBuffer( const IVAS_REND_AudioBuffer buffer, const uint32_t bufChIdx, float gain_lin ) +ivas_error IVAS_REND_SetInputLfeRouting( + IVAS_REND_HANDLE hIvasRend, + IVAS_REND_InputId inputId, + IVAS_REND_LfeRouting lfeRouting ) { - int32_t smplIdx, chnlIdx; - float *smplPtr; + input_base *pInputBase; + input_mc *pInputMc; + ivas_error error; - /* TODO(sgi): Fix channel indexing - provide range of channels to be modified */ - /* Return early for now, this function is buggy */ - return; + /*-----------------------------------------------------------------* + * Validate function arguments + *-----------------------------------------------------------------*/ - smplPtr = buffer.data + bufChIdx; - for ( chnlIdx = 0; chnlIdx < buffer.config.numChannels; ++chnlIdx ) + if ( hIvasRend == NULL ) { - for ( smplIdx = 0; smplIdx < buffer.config.bufferSize; ++smplIdx ) - { - *smplPtr++ *= gain_lin; - } + return IVAS_ERR_UNEXPECTED_NULL_POINTER; } -} - -static void copyBufferTo2dArray( const IVAS_REND_AudioBuffer buffer, const uint32_t chInIdx, const uint32_t numCh, float array[MAX_OUTPUT_CHANNELS][L_FRAME48k] ) -{ - int32_t smplIdx; - uint32_t chnlIdx; - const float *readPtr; - - readPtr = buffer.data + chInIdx * buffer.config.bufferSize; - for ( chnlIdx = 0; chnlIdx < numCh; ++chnlIdx ) + if ( ( error = getInputById( hIvasRend, inputId, (void **) &pInputBase ) ) != IVAS_ERR_OK ) { - for ( smplIdx = 0; smplIdx < buffer.config.bufferSize; ++smplIdx ) - { - array[chnlIdx][smplIdx] = *readPtr++; - } + return error; } -} + if ( getAudioConfigType( pInputBase->inConfig ) != IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED ) + { + /* Custom LFE routing only makes sense with channel-based input */ + return IVAS_ERR_INVALID_INPUT_FORMAT; + } + pInputMc = (input_mc *) pInputBase; -static void copy2dArrayToBuffer( float array[MAX_OUTPUT_CHANNELS][L_FRAME48k], IVAS_REND_AudioBuffer *buffer, const uint32_t chOutIdx, const uint32_t numCh ) -{ - int32_t smplIdx; - uint32_t chnlIdx; - float *writePtr; + if ( getNumLfeChannels( pInputMc ) != lfeRouting.numLfeChannels ) + { + return IVAS_ERR_WRONG_NUM_CHANNELS; + } - writePtr = buffer->data + chOutIdx * buffer->config.bufferSize; - for ( chnlIdx = 0; chnlIdx < numCh; ++chnlIdx ) + pInputMc->lfeRouting = lfeRouting; + if ( ( error = updateMcPanGains( pInputMc, hIvasRend->outputConfig ) ) != IVAS_ERR_OK ) { - for ( smplIdx = 0; smplIdx < buffer->config.bufferSize; ++smplIdx ) - { - *writePtr++ = array[chnlIdx][smplIdx]; - } + return error; } + + return IVAS_ERR_OK; } -static void renderAmbiToAmbi( const IVAS_REND_HANDLE st, - const IVAS_REND_AudioBuffer inAudio, - IVAS_REND_AudioBuffer outAudio ) +ivas_error IVAS_REND_RemoveInput( + IVAS_REND_HANDLE hIvasRend, + IVAS_REND_InputId inputId ) { - float *inSmpl; - float *outSmpl; - int16_t lastChannelIdx; - int16_t smplIdx; - int16_t chnlIdx; - uint32_t inAmbiChannelIdx; - uint32_t ambiIdx; - float gain_lin; + ivas_error error; + input_base *inputBase; + /*-----------------------------------------------------------------* + * Validate function arguments + *-----------------------------------------------------------------*/ -#ifdef WMOPS - wmops_sub_start( "renderAmbiToAmbi" ); -#endif + if ( hIvasRend == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + if ( ( error = getInputById( hIvasRend, inputId, (void **) &inputBase ) ) != IVAS_ERR_OK ) + { + return error; + } - /* Iterate over given Ambisonics inputs */ - for ( ambiIdx = 0; ambiIdx < st->inConfig.numAmbisonicsBuses; ++ambiIdx ) + switch ( getAudioConfigType( inputBase->inConfig ) ) { - inAmbiChannelIdx = st->inConfig.ambisonicsBuses[ambiIdx].inputChannelIndex; + case IVAS_REND_AUDIO_CONFIG_TYPE_OBJECT_BASED: + clearInputIsm( (input_ism *) inputBase ); + break; + case IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED: + clearInputMc( (input_mc *) inputBase ); + break; + case IVAS_REND_AUDIO_CONFIG_TYPE_AMBISONICS: + clearInputSba( (input_sba *) inputBase ); + break; + default: + return IVAS_ERR_INVALID_INPUT_FORMAT; + } - /* Find out how many channels to process */ - lastChannelIdx = min( getNumChannelsAmbisonics( st->inConfig.ambisonicsBuses[ambiIdx].ambisonicsConfig ), st->numOutChannels ) - 1; + return IVAS_ERR_OK; +} - gain_lin = dBToLin( st->inConfig.ambisonicsBuses[ambiIdx].gain_dB ); +ivas_error IVAS_REND_GetInputNumChannels( + IVAS_REND_CONST_HANDLE hIvasRend, + IVAS_REND_InputId inputId, + int32_t *numChannels ) +{ + ivas_error error; + const input_base *pInput; - /* Passthrough channels */ - for ( chnlIdx = 0; chnlIdx <= lastChannelIdx; ++chnlIdx ) - { - inSmpl = get_smpl_ptr( inAudio, chnlIdx + inAmbiChannelIdx, 0 ); - outSmpl = get_smpl_ptr( outAudio, chnlIdx, 0 ); + /*-----------------------------------------------------------------* + * Validate function arguments + *-----------------------------------------------------------------*/ - for ( smplIdx = 0; smplIdx < inAudio.config.bufferSize; ++smplIdx ) - { - *outSmpl += *inSmpl * gain_lin; + if ( hIvasRend == NULL || numChannels == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } - ++inSmpl; - ++outSmpl; - } - } + if ( ( error = getConstInputById( hIvasRend, inputId, (const void **) &pInput ) ) != IVAS_ERR_OK ) + { + return error; + } + if ( ( error = getRendInputNumChannels( pInput, numChannels ) ) != IVAS_ERR_OK ) + { + return error; } -#ifdef WMOPS - wmops_sub_end(); -#endif + return IVAS_ERR_OK; } -static void renderChannelsToAmbi( IVAS_REND_HANDLE st, - const IVAS_REND_AudioBuffer inAudio, - IVAS_REND_AudioBuffer outAudio ) +ivas_error IVAS_REND_GetDelay( + IVAS_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 */ +) { - const uint32_t *lfeLastIdxs; - uint32_t inMcChannelIdx; - uint32_t numNonLfeInChannels; - uint32_t numInChannels; - uint32_t mcIdx; - uint32_t inChIdx; - uint32_t lfeLastIdx_lsCustom[MAX_OUTPUT_CHANNELS]; - float gain_lin; + /* TODO tmu : this function only returns the maximum delay across all inputs + * Ideally each input has its own delay buffer and everything is aligned (binaural and LFE filtering delays are nonuniform) + */ + int16_t i; + int32_t latency_ns; -#ifdef WMOPS - wmops_sub_start( "renderChannelsToAmbi" ); -#endif + /*-----------------------------------------------------------------* + * Validate function arguments + *-----------------------------------------------------------------*/ - /* Iterate over given MC inputs */ - for ( mcIdx = 0; mcIdx < st->inConfig.numMultiChannelBuses; ++mcIdx ) + if ( hIvasRend == NULL || nSamples == NULL || timeScale == NULL ) { - /* Get channel idx of current MC input within the multitrack buffer */ - inMcChannelIdx = st->inConfig.multiChannelBuses[mcIdx].inputChannelIndex; - - /* Number of input speakers */ - if ( st->inConfig.multiChannelBuses[mcIdx].speakerLayout == IVAS_REND_SPEAKER_LAYOUT_CUSTOM ) - { - numInChannels = st->inConfig.inSetupCustom->num_spk + st->inConfig.inSetupCustom->num_lfe; - numNonLfeInChannels = st->inConfig.inSetupCustom->num_spk; - - /* Reordered indices for custom loudspeaker input */ - if ( st->inConfig.inSetupCustom->num_lfe > 0 ) - { - lfeLastIdx_lsCustom[numNonLfeInChannels] = st->inConfig.inSetupCustom->lfe_idx[0]; - } + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } - for ( inChIdx = 0; inChIdx < numNonLfeInChannels; ++inChIdx ) - { - ( ( st->inConfig.inSetupCustom->num_lfe > 0 ) && ( (int16_t) inChIdx >= st->inConfig.inSetupCustom->lfe_idx[0] ) ) ? ( lfeLastIdx_lsCustom[inChIdx] = inChIdx + 1 ) : ( lfeLastIdx_lsCustom[inChIdx] = inChIdx ); - } + *timeScale = hIvasRend->sampleRateOut; + *nSamples = 0; - lfeLastIdxs = &lfeLastIdx_lsCustom[0]; - } - else + /* Compute the maximum delay across all inputs */ + for ( i = 0; i < RENDERER_MAX_ISM_INPUTS; i++ ) + { + if ( hIvasRend->inputsIsm[i].base.inConfig != IVAS_REND_AUDIO_CONFIG_UNKNOWN ) { - numInChannels = getNumChannelsInSpeakerLayout( st->inConfig.multiChannelBuses[mcIdx].speakerLayout ); - numNonLfeInChannels = getNumNonLfeChannelsInSpeakerLayout( st->inConfig.multiChannelBuses[mcIdx].speakerLayout ); - - lfeLastIdxs = getReorderedChannelIndices( st->inConfig.multiChannelBuses[mcIdx].speakerLayout ); + latency_ns = max( hIvasRend->inputsIsm[i].crendWrapper.binaural_latency_ns, + hIvasRend->inputsIsm[i].tdRendWrapper.binaural_latency_ns ); + *nSamples = max( *nSamples, NS2SA( *timeScale, latency_ns ) ); } + } - gain_lin = dBToLin( st->inConfig.multiChannelBuses[mcIdx].gain_dB ); - - /* Iterate over channels */ - for ( inChIdx = 0; inChIdx < numNonLfeInChannels; ++inChIdx ) + for ( i = 0; i < RENDERER_MAX_MC_INPUTS; i++ ) + { + if ( hIvasRend->inputsMc[i].base.inConfig != IVAS_REND_AUDIO_CONFIG_UNKNOWN ) { - applyChannelGainsAndAddToOutput( inAudio, - inMcChannelIdx + lfeLastIdxs[inChIdx], - st->speakerPanGains[mcIdx][inChIdx], - NULL, - gain_lin, - st->crossfade, - outAudio ); + latency_ns = max( hIvasRend->inputsMc[i].crendWrapper.binaural_latency_ns, + hIvasRend->inputsMc[i].tdRendWrapper.binaural_latency_ns ); + *nSamples = max( *nSamples, NS2SA( *timeScale, latency_ns ) ); } + } - if ( st->neverDropLfe ) + for ( i = 0; i < RENDERER_MAX_SBA_INPUTS; i++ ) + { + if ( hIvasRend->inputsSba[i].base.inConfig != IVAS_REND_AUDIO_CONFIG_UNKNOWN ) { - /* Render LFE channels into the scene */ - for ( ; inChIdx < numInChannels; ++inChIdx ) - { - applyChannelGainsAndAddToOutput( inAudio, - inMcChannelIdx + lfeLastIdxs[inChIdx], - st->lfePanGains, - NULL, - gain_lin, - st->crossfade, - outAudio ); - } + latency_ns = hIvasRend->inputsSba[i].crendWrapper.binaural_latency_ns; + *nSamples = max( *nSamples, NS2SA( *timeScale, latency_ns ) ); } } -#ifdef WMOPS - wmops_sub_end(); -#endif + return IVAS_ERR_OK; } -static void renderObjectsToAmbi( - IVAS_REND_HANDLE st, - const IVAS_REND_AudioBuffer inAudio, - const IVAS_REND_AudioObjectMetadataBuffer metadataBuffer, - IVAS_REND_AudioBuffer outAudio ) +ivas_error IVAS_REND_FeedInputAudio( + IVAS_REND_HANDLE hIvasRend, + IVAS_REND_InputId inputId, + IVAS_REND_ReadOnlyAudioBuffer inputAudio ) { - const IVAS_REND_AudioObject *curObj; - uint32_t objIdx; - IVAS_REND_AudioObjectPosition pos; - float gain_lin; - -#ifdef WMOPS - wmops_sub_start( "renderObjectsToAmbi" ); -#endif + ivas_error error; + input_base *inputBase; + int32_t numInputChannels; - assert( st->inConfig.numAudioObjects == metadataBuffer.numObjects && "Metadata provided for a different number of objects than found in input" ); + /*-----------------------------------------------------------------* + * Validate function arguments + *-----------------------------------------------------------------*/ - /* Iterate over given audio objects */ - for ( objIdx = 0; objIdx < st->inConfig.numAudioObjects; ++objIdx ) + if ( hIvasRend == NULL || inputAudio.data == NULL ) { - /* Get pointer to current object and its metadata */ - curObj = &st->inConfig.audioObjects[objIdx]; - pos = metadataBuffer.positions[objIdx]; - gain_lin = dBToLin( st->inConfig.audioObjects[objIdx].gain_dB ); + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + if ( inputAudio.config.numSamplesPerChannel <= 0 || MAX_BUFFER_LENGTH_PER_CHANNEL < inputAudio.config.numSamplesPerChannel ) + { + return IVAS_ERR_INVALID_BUFFER_SIZE; + } + if ( inputAudio.config.numChannels <= 0 || MAX_INPUT_CHANNELS < inputAudio.config.numChannels ) + { + return IVAS_ERR_WRONG_NUM_CHANNELS; + } + if ( getAudioConfigType( hIvasRend->outputConfig ) == IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL && + inputAudio.config.numSamplesPerChannel * 1000 != BINAURAL_RENDERING_FRAME_SIZE_MS * hIvasRend->sampleRateOut ) + { + /* Binaural rendering requires specific frame size */ + return IVAS_ERR_INVALID_BUFFER_SIZE; + } - /* Render to ambisonics */ - renderSingleObjectToAmbi( - st, - inAudio, - curObj->inputChannelIndex, - &st->objPanInfo[objIdx], - pos, - gain_lin, - outAudio ); + if ( ( error = getInputById( hIvasRend, inputId, (void **) &inputBase ) ) != IVAS_ERR_OK ) + { + return error; + } + if ( ( error = getRendInputNumChannels( inputBase, &numInputChannels ) ) != IVAS_ERR_OK ) + { + return error; + } + if ( numInputChannels != inputAudio.config.numChannels ) + { + return IVAS_ERR_WRONG_NUM_CHANNELS; } -#ifdef WMOPS - wmops_sub_end(); -#endif + inputBase->inputBuffer.config = inputAudio.config; + + mvr2r( inputAudio.data, + inputBase->inputBuffer.data, + inputAudio.config.numSamplesPerChannel * inputAudio.config.numChannels ); + + inputBase->numNewSamplesPerChannel = inputAudio.config.numSamplesPerChannel; + + return IVAS_ERR_OK; } -static void renderMasaToAmbi( - IVAS_REND_HANDLE st, - const IVAS_REND_AudioBuffer inAudio, - IVAS_REND_AudioBuffer outAudio ) +ivas_error IVAS_REND_FeedInputObjectMetadata( + IVAS_REND_HANDLE hIvasRend, + IVAS_REND_InputId inputId, + IVAS_REND_AudioObjectPosition objectPosition ) { - uint32_t inMasaChannelIdx; - float gain_lin; - float tmpBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; + input_base *inputBase; + input_ism *inputIsm; + ivas_error error; - inMasaChannelIdx = st->inConfig.masaBus.inputChannelIndex; - gain_lin = dBToLin( st->inConfig.masaBus.gain_dB ); + /*-----------------------------------------------------------------* + * Validate function arguments + *-----------------------------------------------------------------*/ - applyGainToBuffer( inAudio, inMasaChannelIdx, gain_lin ); - copyBufferTo2dArray( inAudio, inMasaChannelIdx, st->numInChannelsMasa, tmpBuffer ); + if ( hIvasRend == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + if ( ( error = getInputById( hIvasRend, inputId, (void **) &inputBase ) ) != IVAS_ERR_OK ) + { + return error; + } + if ( inputBase->inConfig != IVAS_REND_AUDIO_CONFIG_OBJECT ) + { + /* Object metadata should only be fed for object inputs */ + return IVAS_ERR_METADATA_NOT_EXPECTED; + } - /* TODO @ Nokia: Process audio in-place in tmpBuffer. MASA metadata for current frame already available in st->masaMetadata. */ - memset( tmpBuffer, 0, sizeof( tmpBuffer ) ); + inputIsm = (input_ism *) inputBase; + inputIsm->previousPos = inputIsm->currentPos; + inputIsm->currentPos = objectPosition; - copy2dArrayToBuffer( tmpBuffer, &outAudio, 0, st->numOutChannels ); + return IVAS_ERR_OK; } -static void renderAmbiToChannels( const IVAS_REND_HANDLE st, - const IVAS_REND_AudioBuffer inAudio, - IVAS_REND_AudioBuffer outAudio ) +ivas_error IVAS_REND_SetHeadRotation( + IVAS_REND_HANDLE hIvasRend, + const IVAS_QUATERNION headRot[RENDERER_HEAD_POSITIONS_PER_FRAME] ) { - uint32_t inAmbiChannelIdx; - uint32_t ambiIdx; - uint32_t numInAmbiChnls; - uint32_t ambiChnIdx; - float gain_lin; + int16_t i; -#ifdef WMOPS - wmops_sub_start( "renderAmbiToChannels" ); -#endif + /*-----------------------------------------------------------------* + * Validate function arguments + *-----------------------------------------------------------------*/ - /* Iterate over all given ambisonics inputs */ - for ( ambiIdx = 0; ambiIdx < st->inConfig.numAmbisonicsBuses; ++ambiIdx ) + if ( hIvasRend == NULL ) { - inAmbiChannelIdx = st->inConfig.ambisonicsBuses[ambiIdx].inputChannelIndex; - - /* Number of input channels */ - numInAmbiChnls = getNumChannelsAmbisonics( st->inConfig.ambisonicsBuses[ambiIdx].ambisonicsConfig ); - - gain_lin = dBToLin( st->inConfig.multiChannelBuses[ambiIdx].gain_dB ); + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + if ( getAudioConfigType( hIvasRend->outputConfig ) != IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL ) + { + /* Head rotation can be set only with binaural output */ + return IVAS_ERR_METADATA_NOT_EXPECTED; + } - /* Render each ambisonics channel */ - for ( ambiChnIdx = 0; ambiChnIdx < numInAmbiChnls; ++ambiChnIdx ) + if ( headRot == NULL ) + { + hIvasRend->headRotData.headRotEnabled = 0; + } + else + { + hIvasRend->headRotData.headRotEnabled = 1; + for ( i = 0; i < RENDERER_HEAD_POSITIONS_PER_FRAME; ++i ) { - /* Write decoding gains to temp buffer */ - getHoaDecVecForAmbiChnl( ambiChnIdx, st->outConfig, st->ambi_dec_mtx, st->tmpGainBuffer ); - - /* Apply decoding gains and add to output */ - applyChannelGainsAndAddToOutput( inAudio, - inAmbiChannelIdx + ambiChnIdx, - st->tmpGainBuffer, - NULL, - gain_lin, - st->crossfade, - outAudio ); + hIvasRend->headRotData.headPositions[i] = headRot[i]; } } -#ifdef WMOPS - wmops_sub_end(); -#endif + return IVAS_ERR_OK; } -static void renderChannelsToChannels( - const IVAS_REND_HANDLE st, +/* Take one channel from input buffer and copy it to each channel + in output buffer, with different gain applied per output channel. + This function takes 2 gain vectors - one for the beginning and one + for the end of the buffer. Gain values are lineraly interpolated + for all samples in between. */ +static void renderBufferChannelLerp( const IVAS_REND_AudioBuffer inAudio, + const int32_t inChannelIdx, + const float *const gainsCurrent, + const float *const gainsPrev, IVAS_REND_AudioBuffer outAudio ) { - const uint32_t *lfeLastIdxs; - uint32_t inMcChannelIdx; - uint32_t numNonLfeInChannels; - uint32_t numInChannels; - uint32_t passThroughIdx; - uint32_t mcIdx; - uint32_t inChIdx; - uint32_t lfeLastIdx_lsCustom[MAX_OUTPUT_CHANNELS]; - float gain_lin; - -#ifdef WMOPS - wmops_sub_start( "renderChannelsToChannels" ); -#endif + const float *inSmpl; + float *outSmpl; + float fadeIn; + float fadeOut; + int32_t i; + const float *lastInSmpl; + int16_t outChnlIdx; + float currentGain; + float previousGain; - passThroughIdx = 0; + /* Pointer to behind last input sample */ + lastInSmpl = getSmplPtr( inAudio, inChannelIdx, inAudio.config.numSamplesPerChannel ); - /* Iterate over given MC inputs */ - for ( mcIdx = 0; mcIdx < st->inConfig.numMultiChannelBuses; ++mcIdx ) + for ( outChnlIdx = 0; outChnlIdx < outAudio.config.numChannels; ++outChnlIdx ) { - /* Get channel idx of current MC input within the multitrack buffer */ - inMcChannelIdx = st->inConfig.multiChannelBuses[mcIdx].inputChannelIndex; + currentGain = gainsCurrent[outChnlIdx]; + previousGain = gainsPrev == NULL ? 0.f : gainsPrev[outChnlIdx]; - if ( st->inConfig.multiChannelBuses[mcIdx].speakerLayout == IVAS_REND_SPEAKER_LAYOUT_CUSTOM ) + /* Process current output channel only if applying non-zero gains */ + if ( fabsf( currentGain ) > EPSILON || ( gainsPrev != NULL && fabsf( previousGain ) > EPSILON ) ) { - /* Number of non-LFE input channels */ - numNonLfeInChannels = st->inConfig.inSetupCustom->num_spk; - - /* Number of all input channels */ - numInChannels = st->inConfig.inSetupCustom->num_spk + st->inConfig.inSetupCustom->num_lfe; + /* Reset input pointer to the beginning of input channel */ + inSmpl = getSmplPtr( inAudio, inChannelIdx, 0 ); - /* Reordered indices for custom loudspeaker input */ - if ( st->inConfig.inSetupCustom->num_lfe > 0 ) - { - lfeLastIdx_lsCustom[numNonLfeInChannels] = st->inConfig.inSetupCustom->lfe_idx[0]; - } + /* Set output pointer to first output channel sample */ + outSmpl = getSmplPtr( outAudio, outChnlIdx, 0 ); - for ( inChIdx = 0; inChIdx < numNonLfeInChannels; ++inChIdx ) + if ( gainsPrev == NULL || fabsf( previousGain - currentGain ) <= EPSILON ) { - ( ( st->inConfig.inSetupCustom->num_lfe > 0 ) && ( (int16_t) inChIdx >= st->inConfig.inSetupCustom->lfe_idx[0] ) ) ? ( lfeLastIdx_lsCustom[inChIdx] = inChIdx + 1 ) : ( lfeLastIdx_lsCustom[inChIdx] = inChIdx ); - } - - lfeLastIdxs = &lfeLastIdx_lsCustom[0]; - } - else - { - /* Number of non-LFE input channels */ - numNonLfeInChannels = getNumNonLfeChannelsInSpeakerLayout( st->inConfig.multiChannelBuses[mcIdx].speakerLayout ); - - /* Number of all input channels */ - numInChannels = getNumChannelsInSpeakerLayout( st->inConfig.multiChannelBuses[mcIdx].speakerLayout ); - - lfeLastIdxs = getReorderedChannelIndices( st->inConfig.multiChannelBuses[mcIdx].speakerLayout ); - } - - - gain_lin = dBToLin( st->inConfig.multiChannelBuses[mcIdx].gain_dB ); + /* If no interpolation from previous frame, apply current gain */ + do + { + *outSmpl += currentGain * ( *inSmpl ); + ++outSmpl; + ++inSmpl; - /* Iterate over non-LFE channels */ - for ( inChIdx = 0; inChIdx < numNonLfeInChannels; ++inChIdx ) - { - if ( st->mcPassthrough[passThroughIdx] == -1 ) - { - applyChannelGainsAndAddToOutput( inAudio, - inMcChannelIdx + lfeLastIdxs[inChIdx], - st->speakerPanGains[mcIdx][inChIdx], - NULL, - gain_lin, - st->crossfade, - outAudio ); + } while ( inSmpl != lastInSmpl ); } else { - passthroughChannel( inAudio, - inMcChannelIdx + lfeLastIdxs[inChIdx], - st->mcPassthrough[passThroughIdx], - gain_lin, - outAudio ); - } - - ++passThroughIdx; - } + i = 0; - /* Iterate over LFE channels */ - for ( ; inChIdx < numInChannels; ++inChIdx ) - { - /* Pass through if possible */ - if ( st->mcPassthrough[passThroughIdx] != -1 ) - { - passthroughChannel( inAudio, - inMcChannelIdx + lfeLastIdxs[inChIdx], - st->mcPassthrough[passThroughIdx], - gain_lin, - outAudio ); - } - else - { - if ( st->neverDropLfe ) + /* Otherwise use weighted average between previous and current gain */ + do { - applyChannelGainsAndAddToOutput( inAudio, - inMcChannelIdx + lfeLastIdxs[inChIdx], - st->lfePanGains, - NULL, - gain_lin, - st->crossfade, - outAudio ); - } - } + /* TODO(sgi): This is calculated for each output channel - can be optimised */ + fadeIn = (float) i / ( outAudio.config.numSamplesPerChannel - 1 ); + fadeOut = 1.0f - fadeIn; - ++passThroughIdx; + *outSmpl += ( fadeIn * currentGain + fadeOut * previousGain ) * ( *inSmpl ); + ++outSmpl; + ++inSmpl; + ++i; + } while ( inSmpl != lastInSmpl ); + } } } - -#ifdef WMOPS - wmops_sub_end(); -#endif } -static void renderObjectsToChannels( - IVAS_REND_HANDLE st, +/* Take one channel from input buffer and copy it to each channel + in output buffer, with different gain applied per output channel */ +static void renderBufferChannel( const IVAS_REND_AudioBuffer inAudio, - const IVAS_REND_AudioObjectMetadataBuffer metadataBuffer, + const int32_t inChannelIdx, + const float *const outputGains, IVAS_REND_AudioBuffer outAudio ) { - const IVAS_REND_AudioObject *curObj; - uint32_t objIdx; - IVAS_REND_AudioObjectPosition pos; - float gain_lin; - -#ifdef WMOPS - wmops_sub_start( "renderObjectsToChannels" ); -#endif - - assert( st->inConfig.numAudioObjects == metadataBuffer.numObjects && "Metadata provided for a different number of objects than found in input" ); - - /* Iterate over given audio objects */ - for ( objIdx = 0; objIdx < st->inConfig.numAudioObjects; ++objIdx ) - { - /* Get pointer to current object and its metadata */ - curObj = &st->inConfig.audioObjects[objIdx]; - pos = metadataBuffer.positions[objIdx]; - gain_lin = dBToLin( st->inConfig.audioObjects[objIdx].gain_dB ); - - /* Render to MC */ - renderSingleObjectToChannels( - st, - inAudio, - curObj->inputChannelIndex, - &st->objPanInfo[objIdx], - pos, - gain_lin, - outAudio ); - } - -#ifdef WMOPS - wmops_sub_end(); -#endif + renderBufferChannelLerp( inAudio, inChannelIdx, outputGains, NULL, outAudio ); } -static void copyHeadRotToDecDummy( const IVAS_QUATERNION *headRot, DecoderDummy *decDummy ) +static ivas_error rotateFrameMc( + IVAS_REND_AudioBuffer inAudio, /* i : Input Audio buffer */ + IVAS_REND_AudioConfig inConfig, /* i : Input Audio config */ + LSSETUP_CUSTOM_STRUCT inCustomLs, /* i : Input Custom LS setup */ + const IVAS_REND_HeadRotData *headRotData, /* i : Head rotation data */ + rotation_gains gains_prev, /* i/o: Previous frame rotation gains */ + const EFAP_HANDLE hEFAPdata, /* i : EFAP structure */ + IVAS_REND_AudioBuffer outAudio /* o : Output Audio buffer */ +) { int16_t i; + int16_t subframe_idx, subframe_len; - assert( decDummy != NULL && decDummy->hHeadTrackData != NULL ); + int16_t azimuth, elevation; + int32_t is_planar_setup, lfe_idx; + int32_t nchan; + int32_t ch_in, ch_out; + int32_t ch_in_woLFE, ch_out_woLFE; - for ( i = 0; i < RENDERER_HEAD_POSITIONS_PER_FRAME; ++i ) + float *readPtr, *writePtr; + const float *ls_azimuth, *ls_elevation; + rotation_matrix Rmat; + rotation_gains gains; + float tmp_gains[MAX_INPUT_CHANNELS]; + + if ( inConfig != IVAS_REND_AUDIO_CONFIG_LS_CUSTOM ) { - decDummy->hHeadTrackData->Quaternions[i].w = headRot[i].w; - decDummy->hHeadTrackData->Quaternions[i].x = headRot[i].x; - decDummy->hHeadTrackData->Quaternions[i].y = headRot[i].y; - decDummy->hHeadTrackData->Quaternions[i].z = headRot[i].z; + getAudioConfigNumChannels( inConfig, &nchan ); + } + else + { + nchan = inCustomLs.num_spk + inCustomLs.num_lfe; } - decDummy->hHeadTrackData->num_quaternions = 0; - - /* Make sure head rotation is not performed in the renderer(s) */ - decDummy->hDecoderConfig->Opt_Headrotation = 0; -} - -static void renderMasaToChannels( - IVAS_REND_HANDLE st, - const IVAS_REND_AudioBuffer inAudio, - IVAS_REND_AudioBuffer outAudio ) -{ - uint32_t inMasaChannelIdx; - float gain_lin; - float tmpBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; - - inMasaChannelIdx = st->inConfig.masaBus.inputChannelIndex; - gain_lin = dBToLin( st->inConfig.masaBus.gain_dB ); - - applyGainToBuffer( inAudio, inMasaChannelIdx, gain_lin ); - copyBufferTo2dArray( inAudio, inMasaChannelIdx, st->numInChannelsMasa, tmpBuffer ); - - /* TODO @ Nokia: Process audio in-place in tmpBuffer. MASA metadata for current frame already available in st->masaMetadata. */ - memset( tmpBuffer, 0, sizeof( tmpBuffer ) ); - - copy2dArrayToBuffer( tmpBuffer, &outAudio, 0, st->numOutChannels ); -} - -static void renderAmbiToBinaural( - const IVAS_REND_HANDLE st, - const IVAS_REND_AudioBuffer inAudio, - IVAS_REND_AudioBuffer outAudio ) -{ - int16_t i; - int16_t subFrameLength; - uint32_t ambiIdx; - uint32_t inAmbiChannelIdx; - float tmpBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; - float gain_lin; - int32_t numInChannels; - -#ifdef WMOPS - wmops_sub_start( "renderAmbiToBinaural" ); -#endif + getMcConfigValues( inConfig, + inCustomLs, + &ls_azimuth, + &ls_elevation, + &lfe_idx, + &is_planar_setup ); - subFrameLength = (int16_t) ( st->sampleRate / FRAMES_PER_SEC / RENDERER_HEAD_POSITIONS_PER_FRAME ); - if ( st->enableHeadRotation ) + /* initialize gains to passthrough */ + for ( ch_in = 0; ch_in < nchan; ch_in++ ) { - copyHeadRotToDecDummy( st->headRotationData, st->decDummyAmbiBin ); + set_zero( gains[ch_in], nchan ); + gains[ch_in][ch_in] = 1.f; } - for ( ambiIdx = 0; ambiIdx < st->inConfig.numAmbisonicsBuses; ++ambiIdx ) + /* subframe loop */ + subframe_len = inAudio.config.numSamplesPerChannel / RENDERER_HEAD_POSITIONS_PER_FRAME; + for ( subframe_idx = 0; subframe_idx < RENDERER_HEAD_POSITIONS_PER_FRAME; subframe_idx++ ) { - inAmbiChannelIdx = st->inConfig.ambisonicsBuses[ambiIdx].inputChannelIndex; - gain_lin = dBToLin( st->inConfig.ambisonicsBuses[ambiIdx].gain_dB ); - numInChannels = getNumChannelsAmbisonics( st->inConfig.ambisonicsBuses[ambiIdx].ambisonicsConfig ); - - applyGainToBuffer( inAudio, inAmbiChannelIdx, gain_lin ); - copyBufferTo2dArray( inAudio, inAmbiChannelIdx, numInChannels, tmpBuffer ); + /* Get next quaternion and calculate rotation matrix */ + QuatToRotMat( headRotData->headPositions[subframe_idx], Rmat ); - if ( st->outConfig.binauralFormat == IVAS_REND_BINAURAL_ROOM ) + for ( ch_in = 0; ch_in < nchan; ch_in++ ) { - /* Convert SBA to 7_1_4 for BINAURAL_ROOM */ - ivas_sba_mtx_mult( tmpBuffer, inAudio.config.bufferSize, getNumChannelsAmbisonics( st->inConfig.ambisonicsBuses[ambiIdx].ambisonicsConfig ), st->decDummyAmbiBin->hIntSetup, st->ambi_dec_mtx ); + /* skip LFE */ + if ( ch_in == lfe_idx ) + { + continue; + } - if ( st->enableHeadRotation ) + /* input channel index without LFE */ + ch_in_woLFE = ( ( lfe_idx > 0 ) && ( ch_in >= lfe_idx ) ) ? ch_in - 1 : ch_in; + + /* gains for current subframe rotation */ + rotateAziEle( ls_azimuth[ch_in_woLFE], + ls_elevation[ch_in_woLFE], + &azimuth, + &elevation, + Rmat, + is_planar_setup ); + + if ( hEFAPdata != NULL && ( ls_azimuth[ch_in_woLFE] != azimuth || ls_elevation[ch_in_woLFE] != elevation ) ) { - for ( i = 0; i < RENDERER_HEAD_POSITIONS_PER_FRAME; i++ ) + efap_determine_gains( hEFAPdata, + tmp_gains, + azimuth, + elevation, + EFAP_MODE_EFAP ); + + for ( ch_out = 0; ch_out < nchan; ch_out++ ) { - rotateFrame_sd( st->decDummyAmbiBin->hHeadTrackData, tmpBuffer, subFrameLength, st->decDummyAmbiBin->hIntSetup, st->decDummyAmbiBin->hEFAPdata, i ); + /* skip LFE */ + if ( ch_out == lfe_idx ) + { + continue; + } + + /* output channel index without LFE */ + ch_out_woLFE = ( ( lfe_idx > 0 ) && ( ch_out >= lfe_idx ) ) ? ch_out - 1 : ch_out; + + gains[ch_in][ch_out] = tmp_gains[ch_out_woLFE]; } } } - else /* IVAS_REND_BINAURAL_DIRECT */ + + /* apply panning gains by mtx multiplication */ + for ( ch_out = 0; ch_out < nchan; ch_out++ ) { - if ( st->enableHeadRotation ) + for ( ch_in = 0; ch_in < nchan; ch_in++ ) { - for ( i = 0; i < RENDERER_HEAD_POSITIONS_PER_FRAME; i++ ) + writePtr = getSmplPtr( outAudio, ch_out, subframe_idx * subframe_len ); + readPtr = getSmplPtr( inAudio, ch_in, subframe_idx * subframe_len ); + /* crossfade with previous rotation gains */ + for ( i = 0; i < subframe_len; i++ ) { - rotateFrame_shd( st->decDummyAmbiBin->hHeadTrackData, tmpBuffer, subFrameLength, st->decDummyAmbiBin->hTransSetup, i ); + *writePtr++ += + ( *readPtr ) * ( ( 1 - headRotData->crossfade[i] ) * gains_prev[ch_in][ch_out] ) + + ( *readPtr ) * ( headRotData->crossfade[i] * gains[ch_in][ch_out] ); + readPtr++; } } } - ivas_crend_process( st->decDummyAmbiBin, tmpBuffer ); - - copy2dArrayToBuffer( tmpBuffer, &outAudio, 0, st->numOutChannels ); + /* move gains to gains_prev */ + for ( i = 0; i < nchan; i++ ) + { + mvr2r( gains[i], gains_prev[i], nchan ); + } } -#ifdef WMOPS - wmops_sub_end(); -#endif + return IVAS_ERR_OK; } -static void renderChannelsToBinaural( - const IVAS_REND_HANDLE st, - const IVAS_REND_AudioBuffer inAudio, - IVAS_REND_AudioBuffer outAudio ) +static ivas_error rotateFrameSba( + IVAS_REND_AudioBuffer inAudio, /* i : Input Audio buffer */ + IVAS_REND_AudioConfig inConfig, /* i : Input Audio config */ + const IVAS_REND_HeadRotData *headRotData, /* i : Head rotation data */ + rotation_gains gains_prev, /* i/o: Previous frame rotation gains */ + IVAS_REND_AudioBuffer outAudio /* o : Output Audio buffer */ +) { - int16_t i; - int16_t lfeChIdx; - int16_t frameLength, subFrameLength; - int16_t binauralDelaySmp, lfeDelaySmp; - int16_t offset; - uint32_t mcIdx, inMcChannelIdx; - int32_t numInChannels; - float gain_lin; - float tmpBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; - float tmpLfeBuffer[L_FRAME48k_EXT]; + int16_t i, l, n, m; + int16_t m1, m2; + int16_t shd_rot_max_order; + int16_t subframe_idx, subframe_len; -#ifdef WMOPS - wmops_sub_start( "renderChannelsToBinaural" ); -#endif + float *readPtr, *writePtr; + rotation_matrix Rmat; + float tmpRot[2 * HEADROT_ORDER + 1]; + rotation_gains gains; - frameLength = (int16_t) ( st->sampleRate / FRAMES_PER_SEC ); - subFrameLength = (int16_t) ( frameLength / RENDERER_HEAD_POSITIONS_PER_FRAME ); - if ( st->enableHeadRotation ) - { - copyHeadRotToDecDummy( st->headRotationData, st->decDummyMcBin ); - } + getAmbisonicsOrder( inConfig, &shd_rot_max_order ); - for ( mcIdx = 0; mcIdx < st->inConfig.numMultiChannelBuses; ++mcIdx ) + /* subframe loop */ + subframe_len = inAudio.config.numSamplesPerChannel / RENDERER_HEAD_POSITIONS_PER_FRAME; + for ( subframe_idx = 0; subframe_idx < RENDERER_HEAD_POSITIONS_PER_FRAME; subframe_idx++ ) { - inMcChannelIdx = st->inConfig.multiChannelBuses[mcIdx].inputChannelIndex; - gain_lin = dBToLin( st->inConfig.multiChannelBuses[mcIdx].gain_dB ); - numInChannels = getNumChannelsInSpeakerLayout( st->inConfig.multiChannelBuses[mcIdx].speakerLayout ); - - applyGainToBuffer( inAudio, inMcChannelIdx, gain_lin ); - copyBufferTo2dArray( inAudio, inMcChannelIdx, numInChannels, tmpBuffer ); - - /* Rotation in spatial domain */ - if ( st->enableHeadRotation ) + /* initialize rotation matrices with zeros */ + for ( i = 0; i < HEADROT_SHMAT_DIM; i++ ) { - for ( i = 0; i < RENDERER_HEAD_POSITIONS_PER_FRAME; i++ ) - { - rotateFrame_sd( st->decDummyMcBin->hHeadTrackData, tmpBuffer, subFrameLength, st->decDummyMcBin->hTransSetup, st->decDummyMcBin->hEFAPdata, i ); - } - } - - /* TD object renderer initialised only for 7_1 and 5_1 with headrotation or custom layout input */ - if ( ( st->outConfig.binauralFormat != IVAS_REND_BINAURAL_ROOM ) && ( ( st->inConfig.multiChannelBuses[mcIdx].speakerLayout == IVAS_REND_SPEAKER_LAYOUT_CUSTOM ) || - ( st->decDummyMcBin->hBinRendererTd != NULL && st->enableHeadRotation ) ) ) - { - ObjRenderIVASFrame( st->decDummyMcBin, tmpBuffer, inAudio.config.bufferSize ); - /* TODO tmu : needs delay compensation otherwise LFE is added out of alignment */ - } - else - { - ivas_crend_process( st->decDummyMcBin, tmpBuffer ); + set_zero( gains[i], HEADROT_SHMAT_DIM ); } - /* TODO tmu : this is always disabled */ - if ( st->forceBinLfeLpf ) - { - if ( st->inConfig.multiChannelBuses[mcIdx].speakerLayout == IVAS_REND_SPEAKER_LAYOUT_CUSTOM ) - { - lfeChIdx = st->inConfig.inSetupCustom->lfe_idx[0]; - } - else - { - lfeChIdx = LFE_CHANNEL; - } - set_zero( tmpLfeBuffer, frameLength ); - mvr2r( tmpBuffer[lfeChIdx], tmpLfeBuffer, frameLength ); + /* Get next quaternion and calculate rotation matrix */ + QuatToRotMat( headRotData->headPositions[subframe_idx], Rmat ); - /* Low pass filtering */ - ivas_filter_process( &st->lfeLpFilter, tmpLfeBuffer, frameLength ); + /* calculate ambisonics rotation matrices for the previous and current frames */ + SHrotmatgen( gains, Rmat, shd_rot_max_order ); - /* Delay adjustment */ - lfeDelaySmp = NS2SA( st->sampleRate, ivas_lfe_lpf_delay[IVAS_FILTER_ORDER_4 - 3] * 1000000000L ); - binauralDelaySmp = NS2SA( st->sampleRate, st->decDummyMcBin->binaural_latency_ns ); + for ( i = 0; i < subframe_len; i++ ) + { + /* As the rotation matrix becomes block diagonal in a SH basis, we can*/ + /* apply each angular-momentum block individually to save complexity. */ - if ( lfeDelaySmp > binauralDelaySmp ) + /* loop over l blocks */ + m1 = 1; + m2 = 4; + for ( l = 1; l <= shd_rot_max_order; l++ ) { - /* delay binauralised signal */ - offset = lfeDelaySmp - binauralDelaySmp; - for ( i = 0; i < numInChannels; ++i ) + /* compute mtx-vector product for this l */ + for ( n = m1; n < m2; n++ ) { - if ( i == lfeChIdx ) + tmpRot[n - m1] = 0.f; + + for ( m = m1; m < m2; m++ ) { - continue; + readPtr = getSmplPtr( inAudio, m, subframe_idx * subframe_len + i ); + /* crossfade with previous rotation gains */ + tmpRot[n - m1] += headRotData->crossfade[i] * gains[n][m] * ( *readPtr ) + + ( 1 - headRotData->crossfade[i] ) * gains_prev[n][m] * ( *readPtr ); } - delay_signal( tmpBuffer[i], frameLength, st->delayOffsetBuffer[i], offset ); } } - else if ( lfeDelaySmp < binauralDelaySmp ) + /* write back the result */ + for ( n = m1; n < m2; n++ ) { - /* delay LFE signal */ - offset = binauralDelaySmp - lfeDelaySmp; - delay_signal( tmpLfeBuffer, frameLength, st->delayOffsetBuffer[lfeChIdx], offset ); + writePtr = getSmplPtr( outAudio, n, subframe_idx * subframe_len + i ); + ( *writePtr ) = tmpRot[n - m1]; } - - mvr2r( tmpLfeBuffer, tmpBuffer[lfeChIdx], frameLength ); + m1 = m2; + m2 += 2 * ( l + 1 ) + 1; } - ivas_binaural_add_LFE( st->decDummyMcBin, frameLength, tmpBuffer ); + /*unoptimized code for reference (full matrix multiplication)*/ + // for ( n = 0; n < nchan; n++ ) + // { + // tmpRot[n] = 0.f; + // + // for ( m = 0; m < nchan; m++ ) + // { + // tmpRot[n] += SHrotmat[n][m] * output[m][i]; + // } + // } + // for ( n = 0; n < nchan; n++ ) + // { + // output[n][i] = tmpRot[n]; + // } - copy2dArrayToBuffer( tmpBuffer, &outAudio, 0, st->numOutChannels ); + /* move SHrotmat to SHrotmat_prev */ + for ( i = 0; i < HEADROT_SHMAT_DIM; i++ ) + { + mvr2r( gains[i], gains_prev[i], HEADROT_SHMAT_DIM ); + } } -#ifdef WMOPS - wmops_sub_end(); -#endif + return IVAS_ERR_OK; } -static void renderObjectsToBinaural( - IVAS_REND_HANDLE st, - const IVAS_REND_AudioBuffer inAudio, - const IVAS_REND_AudioObjectMetadataBuffer metadataBuffer, +static ivas_error renderIsmToBinaural( + const input_ism *ismInput, IVAS_REND_AudioBuffer outAudio ) { - int16_t objIdx; - int16_t tmpAzi, tmpEle; - int16_t chInIdx, smplIdx; - float tmpBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; - float tmpBuffer2[MAX_OUTPUT_CHANNELS][L_FRAME48k]; - float gain_lin; - float fadeIn, fadeOut; - float *swapPtr; - uint32_t inIsmIdx; - -#ifdef WMOPS - wmops_sub_start( "renderObjectsToBinaural" ); -#endif - for ( chInIdx = 0; chInIdx < MAX_OUTPUT_CHANNELS; ++chInIdx ) - { - set_zero( tmpBuffer[chInIdx], L_FRAME48k ); - set_zero( tmpBuffer2[chInIdx], L_FRAME48k ); - } + float tmpTDRendBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; - assert( st->inConfig.numAudioObjects == metadataBuffer.numObjects && "Metadata provided for a different number of objects than found in input" ); - if ( st->enableHeadRotation ) - { - copyHeadRotToDecDummy( st->headRotationData, st->decDummyObjBin ); - } + ivas_error error; + + copyBufferTo2dArray( ismInput->base.inputBuffer, tmpTDRendBuffer ); - /* Iterate over given audio objects */ - for ( objIdx = 0; objIdx < metadataBuffer.numObjects; ++objIdx ) + /* TODO tmu : missing: interpolation between positions, 5ms rendering */ + if ( ( error = ivas_rend_TDObjRenderFrame( &ismInput->tdRendWrapper, + ismInput->base.inConfig, + NULL, + ismInput->base.ctx.pHeadRotData, + &ismInput->currentPos, + outAudio.config.numSamplesPerChannel, + *ismInput->base.ctx.pOutSampleRate, + tmpTDRendBuffer ) ) != IVAS_ERR_OK ) { - /* Apply head rotation directly to object positions */ - if ( st->enableHeadRotation ) - { - /* save original positions */ - tmpAzi = (int16_t) metadataBuffer.positions[objIdx].azimuth; - tmpEle = (int16_t) metadataBuffer.positions[objIdx].elevation; + return error; + } - /* apply rotation */ - QuatToRotMat( st->decDummyObjBin->hHeadTrackData->Quaternions[0], st->decDummyObjBin->hHeadTrackData->Rmat ); - rotateAziEle( - metadataBuffer.positions[objIdx].azimuth, - metadataBuffer.positions[objIdx].elevation, - &tmpAzi, - &tmpEle, - st->decDummyObjBin->hHeadTrackData->Rmat, - 0 ); + accumulate2dArrayToBuffer( tmpTDRendBuffer, &outAudio ); - /* set rotated positions in decoder dummy */ - st->decDummyObjBin->hIsmMetaData[objIdx]->azimuth = (float) tmpAzi; - st->decDummyObjBin->hIsmMetaData[objIdx]->elevation = (float) tmpEle; - } - else - { - st->decDummyObjBin->hIsmMetaData[objIdx]->azimuth = metadataBuffer.positions[objIdx].azimuth; - st->decDummyObjBin->hIsmMetaData[objIdx]->elevation = metadataBuffer.positions[objIdx].elevation; - } + return IVAS_ERR_OK; +} - inIsmIdx = st->inConfig.audioObjects[objIdx].inputChannelIndex; +static ivas_error renderIsmToBinauralRoom( + input_ism *ismInput, + IVAS_REND_AudioBuffer outAudio ) +{ + int16_t i; + int16_t azi_rot, ele_rot; + int16_t subframe_idx, subframe_len; + int32_t tmp; + rotation_matrix Rmat; + float tmpCrendBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; + IVAS_QUATERNION quat; - gain_lin = dBToLin( st->inConfig.audioObjects[objIdx].gain_dB ); - applyGainToBuffer( inAudio, objIdx, gain_lin ); + ivas_error error; + pan_vector currentPanGains; + pan_vector previousPanGains; + IVAS_REND_AudioBuffer tmpMcBuffer; + IVAS_REND_AudioObjectPosition rotatedPos; + const IVAS_REND_HeadRotData *headRotData; - /* Copy input audio to tmp buffer for processing */ - copyBufferTo2dArray( inAudio, inIsmIdx, 1, &tmpBuffer[objIdx] ); - } + headRotData = ismInput->base.ctx.pHeadRotData; + rotatedPos = defaultObjectPosition(); - if ( st->outConfig.binauralFormat == IVAS_REND_BINAURAL_ROOM ) + if ( headRotData->headRotEnabled ) { - for ( objIdx = 0; objIdx < metadataBuffer.numObjects; ++objIdx ) + subframe_len = ismInput->base.inputBuffer.config.numSamplesPerChannel / RENDERER_HEAD_POSITIONS_PER_FRAME; + // for ( subframe_idx = 0; subframe_idx < RENDERER_HEAD_POSITIONS_PER_FRAME; subframe_idx++ ) + for ( subframe_idx = 0; subframe_idx < 1; subframe_idx++ ) { - /* Convert ISM to 7_1_4 for BINAURAL_ROOM */ - /* TODO tmu : subframe rotation can be enabled here */ - getSpeakerGains( st, st->decDummyObjBin->hIsmMetaData[objIdx]->azimuth, st->decDummyObjBin->hIsmMetaData[objIdx]->elevation, st->tmpGainBuffer ); - - for ( chInIdx = 0; chInIdx < getNumChannelsInSpeakerLayout( IVAS_REND_SPEAKER_LAYOUT_7_1_4 ); ++chInIdx ) - { - if ( fabsf( st->tmpGainBuffer[chInIdx] ) > 0.0f || fabsf( st->objPanInfo[objIdx].panGains[chInIdx] ) > 0.0f ) - { - for ( smplIdx = 0; smplIdx < inAudio.config.bufferSize; ++smplIdx ) - { - fadeIn = st->crossfade[smplIdx]; - fadeOut = 1.0f - fadeIn; - tmpBuffer2[chInIdx][smplIdx] += ( fadeIn * st->tmpGainBuffer[chInIdx] + fadeOut * st->objPanInfo[objIdx].panGains[chInIdx] ) * tmpBuffer[objIdx][smplIdx]; - } - } - } + quat.w = headRotData->headPositions[subframe_idx].w; + quat.x = headRotData->headPositions[subframe_idx].x; + quat.y = headRotData->headPositions[subframe_idx].y; + quat.z = headRotData->headPositions[subframe_idx].z; - /* move old gains to st->objPanInfo */ - swapPtr = st->objPanInfo[objIdx].panGains; - st->objPanInfo[objIdx].panGains = st->tmpGainBuffer; - st->tmpGainBuffer = swapPtr; + QuatToRotMat( quat, Rmat ); } + (void) subframe_len; // avoid warning + } - /* render from buffer with 7_1_4 format */ - ivas_crend_process( st->decDummyObjBin, tmpBuffer2 ); - copy2dArrayToBuffer( tmpBuffer2, &outAudio, 0, st->numOutChannels ); + /* TODO tmu : missing: interpolation between positions, 5ms rendering */ + /* TODO(sgi): Possible optimization: less processing needed if position didn't change */ + /* TODO tmu2sgi: needs a lot of cleanup, we could also add rot_gains_prev to ismInput and use that */ + /* previous position gains */ + if ( headRotData->headRotEnabled ) + { + rotateAziEle( ismInput->previousPos.azimuth, + ismInput->previousPos.elevation, + &azi_rot, + &ele_rot, + ismInput->rot_mat_prev, + 0 ); + rotatedPos.azimuth = (float) azi_rot; + rotatedPos.elevation = (float) ele_rot; } - else /* IVAS_REND_BINAURAL_DIRECT */ + if ( ( error = getEfapGains( *ismInput->base.ctx.pEfapOutWrapper, + ( headRotData->headRotEnabled ) ? rotatedPos.azimuth : ismInput->previousPos.azimuth, + ( headRotData->headRotEnabled ) ? rotatedPos.elevation : ismInput->previousPos.elevation, + previousPanGains ) ) != IVAS_ERR_OK ) { - ObjRenderIVASFrame( st->decDummyObjBin, tmpBuffer, inAudio.config.bufferSize ); - copy2dArrayToBuffer( tmpBuffer, &outAudio, 0, st->numOutChannels ); + return error; } -#ifdef WMOPS - wmops_sub_end(); -#endif -} -static void renderMasaToBinaural( - IVAS_REND_HANDLE st, - const IVAS_REND_AudioBuffer inAudio, - IVAS_REND_AudioBuffer outAudio ) -{ - uint32_t inMasaChannelIdx; - float gain_lin; - float tmpBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; + /* current position gains */ + if ( headRotData->headRotEnabled ) + { + rotateAziEle( ismInput->currentPos.azimuth, + ismInput->currentPos.elevation, + &azi_rot, + &ele_rot, + Rmat, + 0 ); + rotatedPos.azimuth = (float) azi_rot; + rotatedPos.elevation = (float) ele_rot; + } + if ( ( error = getEfapGains( *ismInput->base.ctx.pEfapOutWrapper, + ( headRotData->headRotEnabled ) ? rotatedPos.azimuth : ismInput->currentPos.azimuth, + ( headRotData->headRotEnabled ) ? rotatedPos.elevation : ismInput->currentPos.elevation, + currentPanGains ) ) != IVAS_ERR_OK ) + { + return error; + } - inMasaChannelIdx = st->inConfig.masaBus.inputChannelIndex; - gain_lin = dBToLin( st->inConfig.masaBus.gain_dB ); + for ( i = 0; i < 3; i++ ) + { + mvr2r( Rmat[i], ismInput->rot_mat_prev[i], 3 ); + } + + /* intermediate rendering to 7_1_4 */ + tmpMcBuffer = ismInput->base.inputBuffer; + getAudioConfigNumChannels( IVAS_REND_AUDIO_CONFIG_7_1_4, &tmp ); + tmpMcBuffer.config.numChannels = tmp; + tmpMcBuffer.data = count_malloc( tmpMcBuffer.config.numSamplesPerChannel * tmpMcBuffer.config.numChannels * sizeof( float ) ); + set_zero( tmpMcBuffer.data, tmpMcBuffer.config.numSamplesPerChannel * tmpMcBuffer.config.numChannels ); + + renderBufferChannelLerp( ismInput->base.inputBuffer, + 0, + currentPanGains, + previousPanGains, + tmpMcBuffer ); - applyGainToBuffer( inAudio, inMasaChannelIdx, gain_lin ); - copyBufferTo2dArray( inAudio, inMasaChannelIdx, st->numInChannelsMasa, tmpBuffer ); + copyBufferTo2dArray( tmpMcBuffer, tmpCrendBuffer ); - /* TODO @ Nokia: Process audio in-place in tmpBuffer. MASA metadata for current frame already available in st->masaMetadata. */ - memset( tmpBuffer, 0, sizeof( tmpBuffer ) ); + ivas_rend_crendProcess( &ismInput->crendWrapper, + IVAS_REND_AUDIO_CONFIG_7_1_4, + IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM, + tmpCrendBuffer, + *ismInput->base.ctx.pOutSampleRate ); - copy2dArrayToBuffer( tmpBuffer, &outAudio, 0, st->numOutChannels ); + accumulate2dArrayToBuffer( tmpCrendBuffer, &outAudio ); + + count_free( tmpMcBuffer.data ); + + return IVAS_ERR_OK; } -static void renderSingleObjectToAmbi( - IVAS_REND_HANDLE st, - const IVAS_REND_AudioBuffer inAudio, - const uint32_t itemChnlIdx, - IVAS_REND_ObjPanInfo *prevPanInfo, - const IVAS_REND_AudioObjectPosition curFrmPos, - const float gain_lin, +static ivas_error renderIsmToMc( + const input_ism *ismInput, IVAS_REND_AudioBuffer outAudio ) { - float *swapPtr; - -#ifdef WMOPS - wmops_sub_start( "renderSingleObjectToAmbi" ); -#endif + pan_vector currentPanGains; + pan_vector previousPanGains; + ivas_error error; - /* Update panning gains if position changed */ - if ( prevPanInfo->position.azimuth != curFrmPos.azimuth || - prevPanInfo->position.elevation != curFrmPos.elevation || - st->firstFrame ) - { - /* Write current panning gains to tmpBuffer */ - ivas_dirac_dec_get_response( (int16_t) curFrmPos.azimuth, - (int16_t) curFrmPos.elevation, - st->tmpGainBuffer, - getAmbisonicsOrder( st->outConfig.ambisonics ) ); - - prevPanInfo->position.azimuth = curFrmPos.azimuth; - prevPanInfo->position.elevation = curFrmPos.elevation; - - applyChannelGainsAndAddToOutput( inAudio, - itemChnlIdx, - st->tmpGainBuffer, - st->firstFrame ? NULL : prevPanInfo->panGains, - gain_lin, - st->crossfade, - outAudio ); - - /* Save current gains as most recently applied gains */ - swapPtr = prevPanInfo->panGains; - prevPanInfo->panGains = st->tmpGainBuffer; - st->tmpGainBuffer = swapPtr; - } - /* Otherwise use most recent gains and no interpolation */ - else + /* TODO(sgi): Possible optimization: less processing needed if position didn't change */ + if ( ( error = getEfapGains( *ismInput->base.ctx.pEfapOutWrapper, + ismInput->currentPos.azimuth, + ismInput->currentPos.elevation, + currentPanGains ) ) != IVAS_ERR_OK ) { - applyChannelGainsAndAddToOutput( inAudio, - itemChnlIdx, - prevPanInfo->panGains, - NULL, - gain_lin, - st->crossfade, - outAudio ); + return error; + } + if ( ( error = getEfapGains( *ismInput->base.ctx.pEfapOutWrapper, + ismInput->previousPos.azimuth, + ismInput->previousPos.elevation, + previousPanGains ) ) != IVAS_ERR_OK ) + { + return error; } -#ifdef WMOPS - wmops_sub_end(); -#endif + /* Assume num channels in audio buffer to be 1. + * This should have been validated in IVAS_REND_FeedInputAudio() */ + renderBufferChannelLerp( ismInput->base.inputBuffer, + 0, + currentPanGains, + previousPanGains, + outAudio ); + + return IVAS_ERR_OK; } -static void renderSingleObjectToChannels( - IVAS_REND_HANDLE st, - const IVAS_REND_AudioBuffer inAudio, - const uint32_t itemChnlIdx, - IVAS_REND_ObjPanInfo *prevPanInfo, - const IVAS_REND_AudioObjectPosition curFrmPos, - const float gain_lin, +static ivas_error renderIsmToSba( + const input_ism *ismInput, + IVAS_REND_AudioConfig outConfig, IVAS_REND_AudioBuffer outAudio ) { - float *swapPtr; + int16_t ambiOrderOut; + int32_t numOutChannels; + pan_vector currentPanGains; + pan_vector previousPanGains; + ivas_error error; + error = IVAS_ERR_OK; -#ifdef WMOPS - wmops_sub_start( "renderSingleObjectToChannels" ); -#endif + if ( ( error = getAudioConfigNumChannels( outConfig, &numOutChannels ) ) != IVAS_ERR_OK ) + { + return error; + } + if ( ( error = getAmbisonicsOrder( outConfig, &ambiOrderOut ) ) != IVAS_ERR_OK ) + { + return error; + } - /* Update panning gains if position changed */ - if ( prevPanInfo->position.azimuth != curFrmPos.azimuth || - prevPanInfo->position.elevation != curFrmPos.elevation || - st->firstFrame ) - { - /* Write current panning gains to tmpBuffer */ - getSpeakerGains( st, curFrmPos.azimuth, curFrmPos.elevation, st->tmpGainBuffer ); - prevPanInfo->position.azimuth = curFrmPos.azimuth; - prevPanInfo->position.elevation = curFrmPos.elevation; - - applyChannelGainsAndAddToOutput( inAudio, - itemChnlIdx, - st->tmpGainBuffer, - st->firstFrame ? NULL : prevPanInfo->panGains, - gain_lin, - st->crossfade, - outAudio ); - - /* Save current gains as most recently applied gains */ - swapPtr = prevPanInfo->panGains; - prevPanInfo->panGains = st->tmpGainBuffer; - st->tmpGainBuffer = swapPtr; - } - /* Otherwise use most recent gains and no interpolation */ + ivas_dirac_dec_get_response( ismInput->previousPos.azimuth, + ismInput->previousPos.elevation, + previousPanGains, + ambiOrderOut ); + + if ( ( ismInput->currentPos.azimuth == ismInput->previousPos.azimuth ) && + ( ismInput->currentPos.elevation == ismInput->previousPos.elevation ) ) + { + mvr2r( previousPanGains, currentPanGains, MAX_OUTPUT_CHANNELS ); + } else { - applyChannelGainsAndAddToOutput( inAudio, - itemChnlIdx, - prevPanInfo->panGains, - NULL, - gain_lin, - st->crossfade, - outAudio ); + ivas_dirac_dec_get_response( ismInput->currentPos.azimuth, + ismInput->currentPos.elevation, + currentPanGains, + ambiOrderOut ); } -#ifdef WMOPS - wmops_sub_end(); -#endif + /* Assume num channels in audio buffer to be 1. + * This should have been validated in IVAS_REND_FeedInputAudio() */ + renderBufferChannelLerp( ismInput->base.inputBuffer, + 0, + currentPanGains, + previousPanGains, + outAudio ); + + return error; } -static void applyChannelGainsAndAddToOutput( - const IVAS_REND_AudioBuffer inAudio, - const uint32_t itemChnlIdx, - const float *const gainsCurrent, - const float *const gainsPrev, - const float gain_lin, - const float *const crossfade, +static ivas_error renderInputIsm( + input_ism *ismInput, + IVAS_REND_AudioConfig outConfig, IVAS_REND_AudioBuffer outAudio ) { - float *inSmpl; - float *outSmpl; - const float *fadeIn; - const float *fadeOut; - const float *lastInSmpl; - int16_t outChnlIdx; - float currentGain; - float previousGain; - -#ifdef WMOPS - wmops_sub_start( "applyChannelGainsAndAddToOutput" ); -#endif - + ivas_error error; + IVAS_REND_AudioBuffer inAudio; - /* Pointer to behind last input sample */ - lastInSmpl = get_smpl_ptr( inAudio, itemChnlIdx, inAudio.config.bufferSize ); + inAudio = ismInput->base.inputBuffer; - for ( outChnlIdx = 0; outChnlIdx < outAudio.config.numChannels; ++outChnlIdx ) + if ( ismInput->base.numNewSamplesPerChannel != outAudio.config.numSamplesPerChannel ) { -#ifdef WMOPS - wmops_sub_start( "applyChannelGainsAndAddToOutput_chnl_loop" ); -#endif - currentGain = gainsCurrent[outChnlIdx] * gain_lin; - previousGain = gainsPrev == NULL ? 0.f : gainsPrev[outChnlIdx] * gain_lin; - - /* Process current output channel only if applying non-zero gains */ - if ( fabsf( currentGain ) > EPSILON || ( gainsPrev != NULL && fabsf( previousGain ) > EPSILON ) ) - { - /* Reset crossfade pointers */ - fadeIn = crossfade; - fadeOut = &crossfade[inAudio.config.bufferSize - 1]; - - /* Reset input pointer to the beginning of input channel */ - inSmpl = get_smpl_ptr( inAudio, itemChnlIdx, 0 ); + /* Mismatch between the number of input samples vs number of requested output samples - currently not allowed */ + return IVAS_ERR_INVALID_BUFFER_SIZE; + } + ismInput->base.numNewSamplesPerChannel = 0; - /* Set output pointer to first output channel sample */ - outSmpl = get_smpl_ptr( outAudio, outChnlIdx, 0 ); + /* Apply input gain to new audio */ + v_multc( inAudio.data, + ismInput->base.gain, + inAudio.data, + inAudio.config.numSamplesPerChannel * inAudio.config.numChannels ); - if ( gainsPrev == NULL || fabsf( previousGain - currentGain ) <= EPSILON ) - { -#ifdef WMOPS - wmops_sub_start( "applyChannelGainsAndAddToOutput_smpl_loop_no_intrpl" ); -#endif - /* If no interpolation from previous frame, apply current gain */ - do - { - *outSmpl += currentGain * ( *inSmpl ); - ++outSmpl; - ++inSmpl; - } while ( inSmpl != lastInSmpl ); -#ifdef WMOPS - wmops_sub_end(); -#endif - } - else + switch ( getAudioConfigType( outConfig ) ) + { + case IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED: + error = renderIsmToMc( ismInput, outAudio ); + break; + case IVAS_REND_AUDIO_CONFIG_TYPE_AMBISONICS: + error = renderIsmToSba( ismInput, outConfig, outAudio ); + break; + case IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL: + switch ( outConfig ) { -#ifdef WMOPS - wmops_sub_start( "applyChannelGainsAndAddToOutput_smpl_loop_intrpl" ); -#endif - /* Otherwise use weighted average between previous and current gain */ - do - { - *outSmpl += ( ( *fadeIn ) * currentGain + ( *fadeOut ) * previousGain ) * ( *inSmpl ); - ++outSmpl; - ++inSmpl; - - ++fadeIn; - --fadeOut; - } while ( inSmpl != lastInSmpl ); -#ifdef WMOPS - wmops_sub_end(); -#endif + case IVAS_REND_AUDIO_CONFIG_BINAURAL: + error = renderIsmToBinaural( ismInput, outAudio ); + break; + case IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM: + error = renderIsmToBinauralRoom( ismInput, outAudio ); + break; + default: + return IVAS_ERR_INVALID_OUTPUT_FORMAT; } - } - -#ifdef WMOPS - wmops_sub_end(); -#endif + break; + default: + return IVAS_ERR_INVALID_OUTPUT_FORMAT; + } + /* Check error here to keep switch statement more compact */ + if ( error != IVAS_ERR_OK ) + { + return error; } -#ifdef WMOPS - wmops_sub_end(); -#endif + return IVAS_ERR_OK; } -static void prepareLfeHandling( - IVAS_REND_HANDLE st ) +static ivas_error renderActiveInputsIsm( + IVAS_REND_HANDLE hIvasRend, + IVAS_REND_AudioBuffer outAudio ) { - const float *filtCoeff; -#ifdef WMOPS - wmops_sub_start( "prepareLfeHandling" ); -#endif - /* Panning gains */ - st->lfePanGains = count_calloc( st->numOutChannels, sizeof( float ) ); + int32_t i; + input_ism *pCurrentInput; + ivas_error error; - if ( st->outConfig.ambisonics != IVAS_REND_AMBISONICS_NONE ) - { - /* TODO tmu : LFE in ambisonics disabled for now */ - /* Pan LFE to south pole (experimental) */ - // ivas_dirac_dec_get_response( 0, - // -90, - // st->lfePanGains, - // getAmbisonicsOrder( st->outConfig.ambisonics ) ); - } - else + for ( i = 0, pCurrentInput = hIvasRend->inputsIsm; i < RENDERER_MAX_ISM_INPUTS; ++i, ++pCurrentInput ) { - set_zero( st->lfePanGains, st->numOutChannels ); - - /* Pan LFE to L and R with -3dB gain */ - if ( st->numOutChannels > 1 ) + if ( pCurrentInput->base.inConfig == IVAS_REND_AUDIO_CONFIG_UNKNOWN ) { - /* TODO tmu : not guaranteed to be L and R for custom layouts without LFE! */ - st->lfePanGains[0] = sqrtf( 0.5f ); - st->lfePanGains[1] = sqrtf( 0.5f ); + /* Skip inactive inputs */ + continue; } - else + if ( ( error = renderInputIsm( pCurrentInput, + hIvasRend->outputConfig, + outAudio ) ) != IVAS_ERR_OK ) { - /* Put LFE in center channel */ - st->lfePanGains[0] = 1.f; + return error; } } - /* Low-pass filter */ - /* TODO: More discussion needed on LFE filtering: - - introduces delay - - introduces phase shift - - Should we do any filtering? - */ - if (st->forceBinLfeLpf) - { - ivas_lfe_lpf_select_filt_coeff( st->sampleRate, IVAS_FILTER_ORDER_4, &filtCoeff ); - ivas_filters_init( &st->lfeLpFilter, filtCoeff, IVAS_FILTER_ORDER_4 ); - } - -#ifdef WMOPS - wmops_sub_end(); -#endif + return IVAS_ERR_OK; } -static void prepareMcPanGains( IVAS_REND_HANDLE st ) +static ivas_error renderLfeToBinaural( + const input_mc *mcInput, + IVAS_REND_AudioBuffer outAudio ) { - uint32_t mcIdx; - int32_t spkIdx; - int32_t numNonLfeChannelsIn; - const float *spkAzi; - const float *spkEle; + int16_t i; + int16_t lfe_idx; + float gain; + float *readPtr, *writePtr; -#ifdef WMOPS - wmops_sub_start( "prepareMcPanGains" ); -#endif - /* No gains required for binaural output */ - if ( ( st->outConfig.binauralFormat != IVAS_REND_BINAURAL_NONE ) && - ( st->outConfig.ambisonics == IVAS_REND_AMBISONICS_NONE || st->outConfig.speakerLayout == IVAS_REND_SPEAKER_LAYOUT_NONE ) ) - { - st->speakerPanGains = NULL; - return; - } + assert( ( outAudio.config.numChannels == 2 ) && "Must be binaural output" ); - st->speakerPanGains = count_calloc( st->inConfig.numMultiChannelBuses, sizeof( float ** ) ); + gain = GAIN_LFE; - for ( mcIdx = 0; mcIdx < st->inConfig.numMultiChannelBuses; ++mcIdx ) + if ( mcInput->base.inConfig != IVAS_REND_AUDIO_CONFIG_LS_CUSTOM ) { - if ( st->inConfig.multiChannelBuses[mcIdx].speakerLayout == IVAS_REND_SPEAKER_LAYOUT_CUSTOM ) - { - numNonLfeChannelsIn = st->inConfig.inSetupCustom->num_spk; - spkAzi = st->inConfig.inSetupCustom->ls_azimuth; - spkEle = st->inConfig.inSetupCustom->ls_elevation; - } - else - { - numNonLfeChannelsIn = getNumNonLfeChannelsInSpeakerLayout( st->inConfig.multiChannelBuses[mcIdx].speakerLayout ); - spkAzi = getSpeakerAzimuths( st->inConfig.multiChannelBuses[mcIdx].speakerLayout ); - spkEle = getSpeakerElevations( st->inConfig.multiChannelBuses[mcIdx].speakerLayout ); - } - - st->speakerPanGains[mcIdx] = count_calloc( numNonLfeChannelsIn, sizeof( float * ) ); - + lfe_idx = LFE_CHANNEL; + } + else if ( mcInput->customLsInput.num_lfe > 0 ) + { + lfe_idx = mcInput->customLsInput.lfe_idx[0]; + } + else + { + /* no LFE to render */ + return IVAS_ERR_OK; + } - if ( st->outConfig.ambisonics != IVAS_REND_AMBISONICS_NONE ) - { - for ( spkIdx = 0; spkIdx < numNonLfeChannelsIn; ++spkIdx ) - { - st->speakerPanGains[mcIdx][spkIdx] = count_calloc( st->numOutChannels, sizeof( float ) ); - ivas_dirac_dec_get_response( (int16_t) spkAzi[spkIdx], - (int16_t) spkEle[spkIdx], - st->speakerPanGains[mcIdx][spkIdx], - getAmbisonicsOrder( st->outConfig.ambisonics ) ); - } - } - else if ( st->outConfig.speakerLayout != IVAS_REND_SPEAKER_LAYOUT_NONE ) - { - /* Custom loudspeaker layout gains */ - for ( spkIdx = 0; spkIdx < numNonLfeChannelsIn; ++spkIdx ) - { - st->speakerPanGains[mcIdx][spkIdx] = count_calloc( st->numOutChannels, sizeof( float ) ); - if ( - ( st->inConfig.multiChannelBuses[mcIdx].speakerLayout == IVAS_REND_SPEAKER_LAYOUT_CUSTOM ) || - ( st->outConfig.speakerLayout == IVAS_REND_SPEAKER_LAYOUT_CUSTOM ) ) - { - getSpeakerGains( st, spkAzi[spkIdx], spkEle[spkIdx], st->speakerPanGains[mcIdx][spkIdx] ); - } - } + /* Copy LFE to left and right ears */ + readPtr = getSmplPtr( mcInput->base.inputBuffer, lfe_idx, 0 ); + writePtr = getSmplPtr( outAudio, 0, 0 ); + for ( i = 0; i < mcInput->base.inputBuffer.config.numSamplesPerChannel; i++ ) + { + *writePtr++ += gain * ( *readPtr++ ); + } - /* Table lookup for loudspeaker layout gains */ - if ( ( st->inConfig.multiChannelBuses[mcIdx].speakerLayout != IVAS_REND_SPEAKER_LAYOUT_CUSTOM ) && - ( st->outConfig.speakerLayout != IVAS_REND_SPEAKER_LAYOUT_CUSTOM ) ) - { - int16_t i, k; - int16_t ch_in, ch_out; - int16_t index; - int16_t nchan_out; - float value; - const uint32_t *lfeLastIdxMap; - const LS_CONVERSION_MATRIX *conversion_matrix; - AUDIO_CONFIG input_config, output_config; - IVAS_REND_SpeakerLayout spkLayoutIn; - - conversion_matrix = NULL; - spkLayoutIn = st->inConfig.multiChannelBuses[mcIdx].speakerLayout; - - input_config = mapRendLayoutToAudioConfig( spkLayoutIn ); - output_config = mapRendLayoutToAudioConfig( st->outConfig.speakerLayout ); - nchan_out = audioCfg2channels( output_config ); - lfeLastIdxMap = getReorderedChannelIndices( spkLayoutIn ); - - /* Search the table for a mapping */ - for ( i = 0; i < LS_SETUP_CONVERSION_NUM_MAPPINGS; i++ ) - { - if ( ( input_config == ls_conversion_mapping[i].input_config ) && ( output_config == ls_conversion_mapping[i].output_config ) ) - { - /* Special handling for MONO and STEREO downmix */ - if ( output_config == AUDIO_CONFIG_MONO || output_config == AUDIO_CONFIG_STEREO ) - { - for ( spkIdx = 0; spkIdx < numNonLfeChannelsIn; spkIdx++ ) - { - k = lfeLastIdxMap[spkIdx]; - - /* Skip two rows in the matrix for 5.1.x formats */ - if ( spkIdx >= 5 && ( input_config == AUDIO_CONFIG_5_1_2 || input_config == AUDIO_CONFIG_5_1_4 ) ) - { - k += 2; - } - - for ( ch_out = 0; ch_out < nchan_out; ch_out++ ) - { - if ( output_config == AUDIO_CONFIG_MONO ) - { - st->speakerPanGains[mcIdx][spkIdx][ch_out] = ls_conversion_cicpX_mono[k][ch_out]; - } - else - { - if ( input_config == AUDIO_CONFIG_MONO ) - { - st->speakerPanGains[mcIdx][spkIdx][ch_out] = ls_conversion_cicpX_stereo[k + 2][ch_out]; - } - else - { - st->speakerPanGains[mcIdx][spkIdx][ch_out] = ls_conversion_cicpX_stereo[k][ch_out]; - } - } - } - } - } - else - { - conversion_matrix = ls_conversion_mapping[i].conversion_matrix; - - /* If a mapping is defined with a NULL matrix, 1:1 upmix of input channels */ - if ( conversion_matrix == NULL ) - { - for ( spkIdx = 0; spkIdx < numNonLfeChannelsIn; spkIdx++ ) - { - ch_out = lfeLastIdxMap[spkIdx]; - st->speakerPanGains[mcIdx][spkIdx][ch_out] = 1.0f; - } - } - else - { - for ( k = 1; k < ( conversion_matrix[0].index + 1 ); k++ ) - { - index = conversion_matrix[k].index; - value = conversion_matrix[k].value; - - /* Second dimension of speakerPanGains (ch_in here) is the input channel index with LFE channels skipped. - Use lfeLastIdxMap to do a reverse lookup over non-LFE channels. - reverseChannelIndexMapping will return -1 for LFE channels - those should be skipped */ - ch_in = reverseChannelIndexMapping( index / nchan_out, lfeLastIdxMap, numNonLfeChannelsIn ); - if ( ch_in < 0 ) - { - continue; - } - - ch_out = index % nchan_out; - - st->speakerPanGains[mcIdx][ch_in][ch_out] = value; - } - } - } - } - } - } - } + readPtr = getSmplPtr( mcInput->base.inputBuffer, lfe_idx, 0 ); + writePtr = getSmplPtr( outAudio, 1, 0 ); + for ( i = 0; i < mcInput->base.inputBuffer.config.numSamplesPerChannel; i++ ) + { + *writePtr++ += gain * ( *readPtr++ ); } -#ifdef WMOPS - wmops_sub_end(); -#endif + return IVAS_ERR_OK; } -static void prepareMcPassthrough( IVAS_REND_HANDLE st ) +static ivas_error renderMcToBinaural( + input_mc *mcInput, + IVAS_REND_AudioConfig outConfig, + IVAS_REND_AudioBuffer outAudio ) { - /* Output config */ - const float *outSpkAzi; - const float *outSpkEle; - const uint32_t *lfeLastIdxs; - uint32_t numNonLfeOutChannels; - uint32_t numOutChannels; - uint32_t lfeLastIdx_lsCustom[MAX_OUTPUT_CHANNELS]; + int8_t headRotEnabled; + float tmpRendBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; + IVAS_REND_AudioConfig inConfig; - /* Input config */ - const float *inSpkAzi; - const float *inSpkEle; - uint32_t numInChannels; - uint32_t numNonLfeInChannels; - - /* Input channel index */ - uint32_t passThroughIdx; - - uint32_t mcIdx; - uint32_t inChIdx; - uint32_t outChIdx; - -#ifdef WMOPS - wmops_sub_start( "prepareMcPassthrough" ); -#endif - - st->mcPassthrough = count_calloc( st->numInChannelsMc, sizeof( int32_t ) ); + ivas_error error; + IVAS_REND_AudioBuffer tmpRotBuffer; + headRotEnabled = mcInput->base.ctx.pHeadRotData->headRotEnabled; + inConfig = mcInput->base.inConfig; - if ( st->outConfig.speakerLayout == IVAS_REND_SPEAKER_LAYOUT_CUSTOM ) + if ( ( inConfig == IVAS_REND_AUDIO_CONFIG_LS_CUSTOM ) || + ( headRotEnabled && ( inConfig == IVAS_REND_AUDIO_CONFIG_5_1 || inConfig == IVAS_REND_AUDIO_CONFIG_7_1 ) ) ) { - /* Number of non-LFE output channels */ - numNonLfeOutChannels = st->outConfig.outSetupCustom->num_spk; - - /* Number of output channels */ - numOutChannels = st->outConfig.outSetupCustom->num_spk + st->outConfig.outSetupCustom->num_lfe; - - /* Output speaker coordinates */ - outSpkAzi = st->outConfig.outSetupCustom->ls_azimuth; - outSpkEle = st->outConfig.outSetupCustom->ls_elevation; + copyBufferTo2dArray( mcInput->base.inputBuffer, tmpRendBuffer ); - /* num_spk + num_lfe must be <= MAX_OUTPUT_CHANNELS for custom loudspeaker layouts */ - if ( st->outConfig.outSetupCustom->num_lfe > 0 ) + if ( ( error = ivas_rend_TDObjRenderFrame( &mcInput->tdRendWrapper, + mcInput->base.inConfig, + &mcInput->customLsInput, + mcInput->base.ctx.pHeadRotData, + NULL, + mcInput->base.inputBuffer.config.numSamplesPerChannel, + *mcInput->base.ctx.pOutSampleRate, + tmpRendBuffer ) ) != IVAS_ERR_OK ) { - lfeLastIdx_lsCustom[numNonLfeOutChannels] = st->outConfig.outSetupCustom->lfe_idx[0]; - } - - for ( outChIdx = 0; outChIdx < numNonLfeOutChannels; ++outChIdx ) - { - ( ( st->outConfig.outSetupCustom->num_lfe > 0 ) && ( (int16_t) outChIdx >= st->outConfig.outSetupCustom->lfe_idx[0] ) ) ? ( lfeLastIdx_lsCustom[outChIdx] = outChIdx + 1 ) : ( lfeLastIdx_lsCustom[outChIdx] = outChIdx ); + return error; } - - lfeLastIdxs = &lfeLastIdx_lsCustom[0]; } else { - /* Number of non-LFE output channels */ - numNonLfeOutChannels = getNumNonLfeChannelsInSpeakerLayout( st->outConfig.speakerLayout ); - - /* Number of output channels */ - numOutChannels = getNumChannelsInSpeakerLayout( st->outConfig.speakerLayout ); - - /* Output speaker coordinates */ - outSpkAzi = getSpeakerAzimuths( st->outConfig.speakerLayout ); - outSpkEle = getSpeakerElevations( st->outConfig.speakerLayout ); - - lfeLastIdxs = getReorderedChannelIndices( st->outConfig.speakerLayout ); - } - - passThroughIdx = 0; - for ( mcIdx = 0; mcIdx < st->inConfig.numMultiChannelBuses; ++mcIdx ) - { - if ( st->inConfig.multiChannelBuses[mcIdx].speakerLayout == IVAS_REND_SPEAKER_LAYOUT_CUSTOM ) + /* apply rotation */ + if ( headRotEnabled ) { - /* Number of non-LFE input channels for current MC input */ - numNonLfeInChannels = st->inConfig.inSetupCustom->num_spk; + tmpRotBuffer = mcInput->base.inputBuffer; + tmpRotBuffer.data = count_malloc( tmpRotBuffer.config.numSamplesPerChannel * tmpRotBuffer.config.numChannels * sizeof( float ) ); + set_zero( tmpRotBuffer.data, tmpRotBuffer.config.numSamplesPerChannel * tmpRotBuffer.config.numChannels ); - /* Number of input channels for current MC input */ - numInChannels = st->inConfig.inSetupCustom->num_spk + st->inConfig.inSetupCustom->num_lfe; + rotateFrameMc( mcInput->base.inputBuffer, + mcInput->base.inConfig, + mcInput->customLsInput, + mcInput->base.ctx.pHeadRotData, + mcInput->rot_gains_prev, + mcInput->efapInWrapper.hEfap, + tmpRotBuffer ); - /* Input speaker coordinates */ - inSpkAzi = st->inConfig.inSetupCustom->ls_azimuth; - inSpkEle = st->inConfig.inSetupCustom->ls_elevation; + copyBufferTo2dArray( tmpRotBuffer, tmpRendBuffer ); + count_free( tmpRotBuffer.data ); } else { - /* Number of non-LFE input channels for current MC input */ - numNonLfeInChannels = getNumNonLfeChannelsInSpeakerLayout( st->inConfig.multiChannelBuses[mcIdx].speakerLayout ); - - /* Number of input channels for current MC input */ - numInChannels = getNumChannelsInSpeakerLayout( st->inConfig.multiChannelBuses[mcIdx].speakerLayout ); - - /* Input speaker coordinates */ - inSpkAzi = getSpeakerAzimuths( st->inConfig.multiChannelBuses[mcIdx].speakerLayout ); - inSpkEle = getSpeakerElevations( st->inConfig.multiChannelBuses[mcIdx].speakerLayout ); + copyBufferTo2dArray( mcInput->base.inputBuffer, tmpRendBuffer ); } - /* Check if passthrough is possible, save I/O mapping */ - for ( inChIdx = 0; inChIdx < numNonLfeInChannels; ++inChIdx ) + /* call CREND */ + if ( ( error = ivas_rend_crendProcess( &mcInput->crendWrapper, + mcInput->base.inConfig, + outConfig, + tmpRendBuffer, + *mcInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) { - st->mcPassthrough[passThroughIdx] = -1; - - for ( outChIdx = 0; outChIdx < numNonLfeOutChannels; ++outChIdx ) - { - if ( inSpkAzi[inChIdx] == outSpkAzi[outChIdx] && - inSpkEle[inChIdx] == outSpkEle[outChIdx] ) - { - st->mcPassthrough[passThroughIdx] = lfeLastIdxs[outChIdx]; - break; - } - } - - ++passThroughIdx; + return error; } + } - /* Setup LFE passthrough, save I/O mapping */ - outChIdx = numNonLfeOutChannels; - for ( ; inChIdx < numInChannels; ++inChIdx ) - { - if ( outChIdx < numOutChannels ) - { - st->mcPassthrough[passThroughIdx] = lfeLastIdxs[outChIdx]; - } - else - { - st->mcPassthrough[passThroughIdx] = -1; - } + accumulate2dArrayToBuffer( tmpRendBuffer, &outAudio ); - ++outChIdx; - ++passThroughIdx; - } - } + /* TODO tmu : needs delay compensation */ + renderLfeToBinaural( mcInput, outAudio ); -#ifdef WMOPS - wmops_sub_end(); -#endif + + return IVAS_ERR_OK; } -static void passthroughChannel( const IVAS_REND_AudioBuffer inAudio, - const uint32_t srcChnlIdx, - const uint32_t dstChnlIdx, - const float gain_lin, - IVAS_REND_AudioBuffer outAudio ) +static ivas_error renderMcToBinauralRoom( + input_mc *mcInput, + IVAS_REND_AudioConfig outConfig, + IVAS_REND_AudioBuffer outAudio ) { - float *inSmpl; - float *outSmpl; - int16_t smplIdx; + float tmpCrendBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; -#ifdef WMOPS - wmops_sub_start( "passthroughChannel" ); -#endif + ivas_error error; + IVAS_REND_AudioBuffer tmpRotBuffer; + + /* apply rotation */ + if ( mcInput->base.ctx.pHeadRotData->headRotEnabled ) + { + tmpRotBuffer = mcInput->base.inputBuffer; + tmpRotBuffer.data = count_malloc( tmpRotBuffer.config.numSamplesPerChannel * tmpRotBuffer.config.numChannels * sizeof( float ) ); + set_zero( tmpRotBuffer.data, tmpRotBuffer.config.numSamplesPerChannel * tmpRotBuffer.config.numChannels ); + + rotateFrameMc( mcInput->base.inputBuffer, + mcInput->base.inConfig, + mcInput->customLsInput, + mcInput->base.ctx.pHeadRotData, + mcInput->rot_gains_prev, + mcInput->efapInWrapper.hEfap, + tmpRotBuffer ); + + copyBufferTo2dArray( tmpRotBuffer, tmpCrendBuffer ); + count_free( tmpRotBuffer.data ); + } + else + { + copyBufferTo2dArray( mcInput->base.inputBuffer, tmpCrendBuffer ); + } + + /* call CREND */ + if ( ( error = ivas_rend_crendProcess( &mcInput->crendWrapper, + mcInput->base.inConfig, + outConfig, + tmpCrendBuffer, + *mcInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) + { + return error; + } - inSmpl = get_smpl_ptr( inAudio, srcChnlIdx, 0 ); - outSmpl = get_smpl_ptr( outAudio, dstChnlIdx, 0 ); + accumulate2dArrayToBuffer( tmpCrendBuffer, &outAudio ); - for ( smplIdx = 0; smplIdx < inAudio.config.bufferSize; ++smplIdx ) - { - *outSmpl += *inSmpl * gain_lin; - ++outSmpl; - ++inSmpl; - } + /* TODO tmu : needs delay compensation */ + renderLfeToBinaural( mcInput, outAudio ); -#ifdef WMOPS - wmops_sub_end(); -#endif + return IVAS_ERR_OK; } -static void getSpeakerGains( const IVAS_REND_HANDLE st, - const float azi, - const float ele, - float *const spkGains ) +static ivas_error renderMcCustomLsToBinauralRoom( + input_mc *mcInput, + IVAS_REND_AudioConfig outConfig, + IVAS_REND_AudioBuffer outAudio ) { - const uint32_t *lfeLastIdxs; - int16_t numNonLfeOutChannels; - int16_t noLfeIdx; - IVAS_REND_SpeakerLayout speakerLayout; + int8_t headRotEnabled; + int16_t i; + int32_t tmp; + float tmpCrendBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; -#ifdef WMOPS - wmops_sub_start( "getSpeakerGains" ); -#endif + ivas_error error; + IVAS_REND_AudioBuffer tmpRotBuffer; + IVAS_REND_AudioBuffer tmpMcBuffer; - /* EFAP returns an array of gains only for non-LFE speakers */ - efap_determine_gains( st->efapRenderer, st->noLfePanBuffer, azi, ele, EFAP_MODE_EFAP ); + headRotEnabled = mcInput->base.ctx.pHeadRotData->headRotEnabled; - if ( st->outConfig.binauralFormat == IVAS_REND_BINAURAL_ROOM ) + /* apply rotation */ + if ( headRotEnabled ) { - speakerLayout = IVAS_REND_SPEAKER_LAYOUT_7_1_4; + tmpRotBuffer = mcInput->base.inputBuffer; + tmpRotBuffer.data = count_malloc( tmpRotBuffer.config.numSamplesPerChannel * tmpRotBuffer.config.numChannels * sizeof( float ) ); + set_zero( tmpRotBuffer.data, tmpRotBuffer.config.numSamplesPerChannel * tmpRotBuffer.config.numChannels ); + + rotateFrameMc( mcInput->base.inputBuffer, + mcInput->base.inConfig, + mcInput->customLsInput, + mcInput->base.ctx.pHeadRotData, + mcInput->rot_gains_prev, + mcInput->efapInWrapper.hEfap, + tmpRotBuffer ); } - else + + /* intermediate conversion to 7_1_4 */ + tmpMcBuffer = mcInput->base.inputBuffer; + getAudioConfigNumChannels( IVAS_REND_AUDIO_CONFIG_7_1_4, &tmp ); + tmpMcBuffer.config.numChannels = tmp; + tmpMcBuffer.data = count_malloc( tmpMcBuffer.config.numSamplesPerChannel * tmpMcBuffer.config.numChannels * sizeof( float ) ); + set_zero( tmpMcBuffer.data, tmpMcBuffer.config.numSamplesPerChannel * tmpMcBuffer.config.numChannels ); + + for ( i = 0; i < mcInput->base.inputBuffer.config.numChannels; i++ ) { - speakerLayout = st->outConfig.speakerLayout; + renderBufferChannel( ( headRotEnabled ) ? tmpRotBuffer : mcInput->base.inputBuffer, + i, + mcInput->panGains[i], + tmpMcBuffer ); } + copyBufferTo2dArray( tmpMcBuffer, tmpCrendBuffer ); - if ( speakerLayout == IVAS_REND_SPEAKER_LAYOUT_CUSTOM ) + /* call CREND */ + if ( ( error = ivas_rend_crendProcess( &mcInput->crendWrapper, + IVAS_REND_AUDIO_CONFIG_7_1_4, + outConfig, + tmpCrendBuffer, + *mcInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) { - uint32_t lfeIdx; + return error; + } - numNonLfeOutChannels = st->outConfig.outSetupCustom->num_spk; + accumulate2dArrayToBuffer( tmpCrendBuffer, &outAudio ); - /* Clear speaker gains - not all elements will be overwritten below */ - set_zero( spkGains, numNonLfeOutChannels + st->outConfig.outSetupCustom->num_lfe ); + /* TODO tmu : needs delay compensation */ + renderLfeToBinaural( mcInput, outAudio ); - /* Copy to gain array where LFE channel(s) are included */ - for ( lfeIdx = 0, noLfeIdx = 0; noLfeIdx < numNonLfeOutChannels; lfeIdx++, noLfeIdx++ ) - { - if ( noLfeIdx == st->outConfig.outSetupCustom->lfe_idx[0] ) - { - lfeIdx++; - } - spkGains[lfeIdx] = st->noLfePanBuffer[noLfeIdx]; - } - } - else + if ( headRotEnabled ) { - numNonLfeOutChannels = getNumNonLfeChannelsInSpeakerLayout( speakerLayout ); - lfeLastIdxs = getReorderedChannelIndices( speakerLayout ); - - /* Clear speaker gains - not all elements will be overwritten below */ - set_zero( spkGains, getNumChannelsInSpeakerLayout( speakerLayout ) ); - - /* Copy to gain array where LFE channel(s) are included */ - for ( noLfeIdx = 0; noLfeIdx < numNonLfeOutChannels; ++noLfeIdx ) - { - spkGains[lfeLastIdxs[noLfeIdx]] = st->noLfePanBuffer[noLfeIdx]; - } + count_free( tmpRotBuffer.data ); } + count_free( tmpMcBuffer.data ); -#ifdef WMOPS - wmops_sub_end(); -#endif + return IVAS_ERR_OK; } -int16_t getNumChannelsAmbisonics( IVAS_REND_Ambisonics ambisonics ) +static ivas_error renderMcToMc( + const input_mc *mcInput, + IVAS_REND_AudioBuffer outAudio ) { - switch ( ambisonics ) + int32_t i; + IVAS_REND_AudioBuffer inAudio; + + inAudio = mcInput->base.inputBuffer; + + for ( i = 0; i < inAudio.config.numChannels; ++i ) { - case IVAS_REND_AMBISONICS_NONE: - return 0; - case IVAS_REND_AMBISONICS_MONO: - return 1; - case IVAS_REND_AMBISONICS_FOA: - return 4; - case IVAS_REND_AMBISONICS_SOA: - return 9; - case IVAS_REND_AMBISONICS_TOA: - return 16; - default: - assert( !"Invalid ambisonics config" ); + renderBufferChannel( inAudio, i, mcInput->panGains[i], outAudio ); } - return 0; + return IVAS_ERR_OK; } -static int16_t getAmbisonicsOrder( IVAS_REND_Ambisonics ambisonics ) +static ivas_error renderMcToSba( + const input_mc *mcInput, + IVAS_REND_AudioBuffer outAudio ) { - assert( ambisonics != IVAS_REND_AMBISONICS_NONE && "Invalid ambisonics config" ); - return ambisonics; /* Enum values map to ambisonics order */ -} + int32_t i; + IVAS_REND_AudioBuffer inAudio; -int16_t getNumChannelsInSpeakerLayout( IVAS_REND_SpeakerLayout layout ) -{ - switch ( layout ) + inAudio = mcInput->base.inputBuffer; + + for ( i = 0; i < inAudio.config.numChannels; ++i ) { - case IVAS_REND_SPEAKER_LAYOUT_NONE: - return 0; - case IVAS_REND_SPEAKER_LAYOUT_MONO: - return 1; - case IVAS_REND_SPEAKER_LAYOUT_STEREO: - return 2; - case IVAS_REND_SPEAKER_LAYOUT_5_1: - return 6; - case IVAS_REND_SPEAKER_LAYOUT_5_1_2: - case IVAS_REND_SPEAKER_LAYOUT_7_1: - return 8; - case IVAS_REND_SPEAKER_LAYOUT_5_1_4: - return 10; - case IVAS_REND_SPEAKER_LAYOUT_7_1_4: - return 12; - default: - assert( !"Invalid speaker layout" ); + renderBufferChannel( inAudio, i, mcInput->panGains[i], outAudio ); } - return 0; + return IVAS_ERR_OK; } -int16_t getNumNonLfeChannelsInSpeakerLayout( IVAS_REND_SpeakerLayout layout ) +static ivas_error renderInputMc( + input_mc *mcInput, + IVAS_REND_AudioConfig outConfig, + IVAS_REND_AudioBuffer outAudio ) { - switch ( layout ) + ivas_error error; + IVAS_REND_AudioBuffer inAudio; + + inAudio = mcInput->base.inputBuffer; + + if ( mcInput->base.numNewSamplesPerChannel != outAudio.config.numSamplesPerChannel ) { - case IVAS_REND_SPEAKER_LAYOUT_MONO: - return 1; - case IVAS_REND_SPEAKER_LAYOUT_STEREO: - return 2; - case IVAS_REND_SPEAKER_LAYOUT_5_1: - return 5; - case IVAS_REND_SPEAKER_LAYOUT_5_1_2: - case IVAS_REND_SPEAKER_LAYOUT_7_1: - return 7; - case IVAS_REND_SPEAKER_LAYOUT_5_1_4: - return 9; - case IVAS_REND_SPEAKER_LAYOUT_7_1_4: - return 11; - default: - assert( !"Invalid speaker layout" ); + /* Mismatch between the number of input samples vs number of requested output samples - currently not allowed */ + return IVAS_ERR_INVALID_BUFFER_SIZE; } + mcInput->base.numNewSamplesPerChannel = 0; - return 0; -} + /* Apply input gain to new audio */ + v_multc( inAudio.data, + mcInput->base.gain, + inAudio.data, + inAudio.config.numSamplesPerChannel * inAudio.config.numChannels ); -const float *getSpeakerAzimuths( IVAS_REND_SpeakerLayout layout ) -{ - switch ( layout ) - { - case IVAS_REND_SPEAKER_LAYOUT_MONO: - return ls_azimuth_CICP1; - case IVAS_REND_SPEAKER_LAYOUT_STEREO: - return ls_azimuth_CICP2; - case IVAS_REND_SPEAKER_LAYOUT_5_1: - return ls_azimuth_CICP6; - case IVAS_REND_SPEAKER_LAYOUT_7_1: - return ls_azimuth_CICP12; - case IVAS_REND_SPEAKER_LAYOUT_5_1_2: - return ls_azimuth_CICP14; - case IVAS_REND_SPEAKER_LAYOUT_5_1_4: - return ls_azimuth_CICP16; - case IVAS_REND_SPEAKER_LAYOUT_7_1_4: - return ls_azimuth_CICP19; + switch ( getAudioConfigType( outConfig ) ) + { + case IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED: + error = renderMcToMc( mcInput, outAudio ); + break; + case IVAS_REND_AUDIO_CONFIG_TYPE_AMBISONICS: + error = renderMcToSba( mcInput, outAudio ); + break; + case IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL: + switch ( outConfig ) + { + case IVAS_REND_AUDIO_CONFIG_BINAURAL: + error = renderMcToBinaural( mcInput, outConfig, outAudio ); + break; + case IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM: + if ( mcInput->base.inConfig == IVAS_REND_AUDIO_CONFIG_LS_CUSTOM ) + { + error = renderMcCustomLsToBinauralRoom( mcInput, outConfig, outAudio ); + } + else + { + error = renderMcToBinauralRoom( mcInput, outConfig, outAudio ); + } + break; + default: + return IVAS_ERR_INVALID_OUTPUT_FORMAT; + } + break; default: - assert( !"Invalid speaker layout" ); + return IVAS_ERR_INVALID_OUTPUT_FORMAT; + } + /* Check error here to keep switch statement more compact */ + if ( error != IVAS_ERR_OK ) + { + return error; } - return NULL; + return IVAS_ERR_OK; } -const float *getSpeakerElevations( IVAS_REND_SpeakerLayout layout ) +static ivas_error renderActiveInputsMc( + IVAS_REND_HANDLE hIvasRend, + IVAS_REND_AudioBuffer outAudio ) { - switch ( layout ) + int32_t i; + input_mc *pCurrentInput; + ivas_error error; + + for ( i = 0, pCurrentInput = hIvasRend->inputsMc; i < RENDERER_MAX_MC_INPUTS; ++i, ++pCurrentInput ) { - case IVAS_REND_SPEAKER_LAYOUT_MONO: - return ls_elevation_CICP1; - case IVAS_REND_SPEAKER_LAYOUT_STEREO: - return ls_elevation_CICP2; - case IVAS_REND_SPEAKER_LAYOUT_5_1: - return ls_elevation_CICP6; - case IVAS_REND_SPEAKER_LAYOUT_7_1: - return ls_elevation_CICP12; - case IVAS_REND_SPEAKER_LAYOUT_5_1_2: - return ls_elevation_CICP14; - case IVAS_REND_SPEAKER_LAYOUT_5_1_4: - return ls_elevation_CICP16; - case IVAS_REND_SPEAKER_LAYOUT_7_1_4: - return ls_elevation_CICP19; - default: - assert( !"Invalid speaker layout" ); + if ( pCurrentInput->base.inConfig == IVAS_REND_AUDIO_CONFIG_UNKNOWN ) + { + /* Skip inactive inputs */ + continue; + } + if ( ( error = renderInputMc( pCurrentInput, + hIvasRend->outputConfig, + outAudio ) ) != IVAS_ERR_OK ) + { + return error; + } } - return NULL; + return IVAS_ERR_OK; } -static const uint32_t *getReorderedChannelIndices( IVAS_REND_SpeakerLayout layout ) +static ivas_error renderSbaToMc( + const input_sba *sbaInput, + IVAS_REND_AudioBuffer outAudio ) { - switch ( layout ) + int32_t i; + IVAS_REND_AudioBuffer inAudio; + + inAudio = sbaInput->base.inputBuffer; + + for ( i = 0; i < inAudio.config.numChannels; ++i ) { - case IVAS_REND_SPEAKER_LAYOUT_MONO: - return ls_LFE_last_idx_CICP1; - case IVAS_REND_SPEAKER_LAYOUT_STEREO: - return ls_LFE_last_idx_CICP2; - case IVAS_REND_SPEAKER_LAYOUT_5_1: - return ls_LFE_last_idx_CICP6; - case IVAS_REND_SPEAKER_LAYOUT_7_1: - return ls_LFE_last_idx_CICP12; - case IVAS_REND_SPEAKER_LAYOUT_5_1_2: - return ls_LFE_last_idx_CICP14; - case IVAS_REND_SPEAKER_LAYOUT_5_1_4: - return ls_LFE_last_idx_CICP16; - case IVAS_REND_SPEAKER_LAYOUT_7_1_4: - return ls_LFE_last_idx_CICP19; - default: - assert( !"Invalid speaker layout" ); + renderBufferChannel( inAudio, i, sbaInput->hoaDecMtx[i], outAudio ); } - return NULL; + return IVAS_ERR_OK; } -static int32_t reverseChannelIndexMapping( int32_t originalChannelIndex, const uint32_t *channelReorderingMap, uint32_t numNonLfeSpeakers ) +static ivas_error renderSbaToSba( + const input_sba *sbaInput, + IVAS_REND_AudioBuffer outAudio ) { int32_t i; + IVAS_REND_AudioBuffer inAudio; + + inAudio = sbaInput->base.inputBuffer; - for ( i = 0; i < (int32_t) numNonLfeSpeakers; ++i ) + for ( i = 0; i < inAudio.config.numChannels; ++i ) { - if ( (int32_t) channelReorderingMap[i] == originalChannelIndex ) - { - return i; - } + renderBufferChannel( inAudio, i, sbaInput->hoaDecMtx[i], outAudio ); } - return -1; + return IVAS_ERR_OK; } -static ivas_error getHoaRenderMtx( - const IVAS_REND_OutputConfig outConfig, - float **decMtx, - uint32_t ambiOrder ) +static ivas_error renderSbaToBinaural( + input_sba *sbaInput, + IVAS_REND_AudioConfig outConfig, + IVAS_REND_AudioBuffer outAudio ) { - IVAS_OUTPUT_SETUP hOutSetup; + float tmpCrendBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; + ivas_error error; + IVAS_REND_AudioBuffer tmpRotBuffer; - error = IVAS_ERR_OK; + /* apply rotation */ + if ( sbaInput->base.ctx.pHeadRotData->headRotEnabled ) + { + tmpRotBuffer = sbaInput->base.inputBuffer; + tmpRotBuffer.data = count_malloc( tmpRotBuffer.config.numSamplesPerChannel * tmpRotBuffer.config.numChannels * sizeof( float ) ); + /* copy input for in-place rotation */ + mvr2r( sbaInput->base.inputBuffer.data, tmpRotBuffer.data, + tmpRotBuffer.config.numChannels * tmpRotBuffer.config.numSamplesPerChannel ); -#ifdef WMOPS - wmops_sub_start( "getHoaRenderMtx" ); -#endif + rotateFrameSba( sbaInput->base.inputBuffer, + sbaInput->base.inConfig, + sbaInput->base.ctx.pHeadRotData, + sbaInput->rot_gains_prev, + tmpRotBuffer ); - if ( outConfig.binauralFormat == IVAS_REND_BINAURAL_NONE ) - { - switch ( outConfig.speakerLayout ) - { - case IVAS_REND_SPEAKER_LAYOUT_MONO: - hOutSetup.ls_azimuth = ls_azimuth_CICP1; - hOutSetup.ls_elevation = ls_elevation_CICP1; - ivas_output_init( &hOutSetup, mapRendLayoutToAudioConfig( outConfig.speakerLayout ) ); - break; - case IVAS_REND_SPEAKER_LAYOUT_STEREO: - case IVAS_REND_SPEAKER_LAYOUT_5_1: - case IVAS_REND_SPEAKER_LAYOUT_7_1: - case IVAS_REND_SPEAKER_LAYOUT_5_1_2: - case IVAS_REND_SPEAKER_LAYOUT_5_1_4: - case IVAS_REND_SPEAKER_LAYOUT_7_1_4: - ivas_output_init( &hOutSetup, mapRendLayoutToAudioConfig( outConfig.speakerLayout ) ); - break; - case IVAS_REND_SPEAKER_LAYOUT_CUSTOM: - ivas_ls_custom_setup( &hOutSetup, outConfig.outSetupCustom ); - break; - default: - assert( !"Invalid speaker config" ); - return IVAS_ERR_WRONG_PARAMS; - } - } - /* intermediate rendering to 7_1_4 for BINAURAL_ROOM */ - else if ( outConfig.binauralFormat == IVAS_REND_BINAURAL_ROOM ) - { - ivas_output_init( &hOutSetup, AUDIO_CONFIG_7_1_4 ); + copyBufferTo2dArray( tmpRotBuffer, tmpCrendBuffer ); + count_free( tmpRotBuffer.data ); } else { - assert( !"Invalid configuration" ); - return IVAS_ERR_WRONG_PARAMS; + copyBufferTo2dArray( sbaInput->base.inputBuffer, tmpCrendBuffer ); } - if ( ( error = ivas_sba_get_hoa_dec_matrix( hOutSetup, decMtx, (int16_t) ambiOrder ) ) != IVAS_ERR_OK ) + /* call CREND */ + if ( ( error = ivas_rend_crendProcess( &sbaInput->crendWrapper, + sbaInput->base.inConfig, + outConfig, + tmpCrendBuffer, + *sbaInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) { return error; } + accumulate2dArrayToBuffer( tmpCrendBuffer, &outAudio ); -#ifdef WMOPS - wmops_sub_end(); -#endif - - return error; + return IVAS_ERR_OK; } -void getHoaDecVecForAmbiChnl( - uint32_t ambiChnnlIdx, - const IVAS_REND_OutputConfig outConfig, - const float *decMtx, - float *decCoeffs ) +static ivas_error renderSbaToBinauralRoom( + input_sba *sbaInput, + IVAS_REND_AudioConfig outConfig, + IVAS_REND_AudioBuffer outAudio ) { + int8_t headRotEnabled; + int16_t i; + int32_t tmp; + float tmpCrendBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; - const uint32_t *lfeLastIdxs; - int16_t numNonLfeChannels; - int16_t nonLfeChIdx; + ivas_error error; + IVAS_REND_AudioBuffer tmpRotBuffer; + IVAS_REND_AudioBuffer tmpMcBuffer; -#ifdef WMOPS - wmops_sub_start( "getHoaDecVecForAmbiChnl" ); -#endif + headRotEnabled = sbaInput->base.ctx.pHeadRotData->headRotEnabled; + + /* apply rotation */ + if ( headRotEnabled ) + { + tmpRotBuffer = sbaInput->base.inputBuffer; + tmpRotBuffer.data = count_malloc( tmpRotBuffer.config.numSamplesPerChannel * tmpRotBuffer.config.numChannels * sizeof( float ) ); + /* copy input for in-place rotation */ + mvr2r( sbaInput->base.inputBuffer.data, tmpRotBuffer.data, + tmpRotBuffer.config.numChannels * tmpRotBuffer.config.numSamplesPerChannel ); + + rotateFrameSba( sbaInput->base.inputBuffer, + sbaInput->base.inConfig, + sbaInput->base.ctx.pHeadRotData, + sbaInput->rot_gains_prev, + tmpRotBuffer ); + } + /* intermediate rendering to 7_1_4 */ + tmpMcBuffer = sbaInput->base.inputBuffer; + getAudioConfigNumChannels( IVAS_REND_AUDIO_CONFIG_7_1_4, &tmp ); + tmpMcBuffer.config.numChannels = tmp; + tmpMcBuffer.data = count_malloc( tmpMcBuffer.config.numSamplesPerChannel * tmpMcBuffer.config.numChannels * sizeof( float ) ); + set_zero( tmpMcBuffer.data, + tmpMcBuffer.config.numChannels * tmpMcBuffer.config.numSamplesPerChannel ); - if ( outConfig.speakerLayout == IVAS_REND_SPEAKER_LAYOUT_CUSTOM ) + for ( i = 0; i < sbaInput->base.inputBuffer.config.numChannels; i++ ) { - uint32_t lfeIdx; + renderBufferChannel( ( headRotEnabled ) ? tmpRotBuffer : sbaInput->base.inputBuffer, + i, + sbaInput->hoaDecMtx[i], + tmpMcBuffer ); + } - numNonLfeChannels = outConfig.outSetupCustom->num_spk; + copyBufferTo2dArray( tmpMcBuffer, tmpCrendBuffer ); - /* Clear speaker gains - not all elements will be overwritten below */ - set_zero( decCoeffs, numNonLfeChannels + outConfig.outSetupCustom->num_lfe ); + /* call CREND */ + if ( ( error = ivas_rend_crendProcess( &sbaInput->crendWrapper, + IVAS_REND_AUDIO_CONFIG_7_1_4, + outConfig, + tmpCrendBuffer, + *sbaInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) + { + return error; + } - /* Copy to gain array where LFE channel(s) are included */ - for ( lfeIdx = 0, nonLfeChIdx = 0; nonLfeChIdx < numNonLfeChannels; lfeIdx++, nonLfeChIdx++ ) - { - if ( nonLfeChIdx == outConfig.outSetupCustom->lfe_idx[0] ) + accumulate2dArrayToBuffer( tmpCrendBuffer, &outAudio ); + + if ( headRotEnabled ) + { + count_free( tmpRotBuffer.data ); + } + count_free( tmpMcBuffer.data ); + + return IVAS_ERR_OK; +} + +static ivas_error renderInputSba( + input_sba *sbaInput, + IVAS_REND_AudioConfig outConfig, + IVAS_REND_AudioBuffer outAudio ) +{ + ivas_error error; + IVAS_REND_AudioBuffer inAudio; + + inAudio = sbaInput->base.inputBuffer; + + if ( sbaInput->base.numNewSamplesPerChannel != outAudio.config.numSamplesPerChannel ) + { + /* Mismatch between the number of input samples vs number of requested output samples - currently not allowed */ + return IVAS_ERR_INVALID_BUFFER_SIZE; + } + sbaInput->base.numNewSamplesPerChannel = 0; + + /* Apply input gain to new audio */ + v_multc( inAudio.data, + sbaInput->base.gain, + inAudio.data, + inAudio.config.numSamplesPerChannel * inAudio.config.numChannels ); + + switch ( getAudioConfigType( outConfig ) ) + { + case IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED: + error = renderSbaToMc( sbaInput, outAudio ); + break; + case IVAS_REND_AUDIO_CONFIG_TYPE_AMBISONICS: + error = renderSbaToSba( sbaInput, outAudio ); + break; + case IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL: + switch ( outConfig ) { - lfeIdx++; + case IVAS_REND_AUDIO_CONFIG_BINAURAL: + error = renderSbaToBinaural( sbaInput, outConfig, outAudio ); + break; + case IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM: + error = renderSbaToBinauralRoom( sbaInput, outConfig, outAudio ); + break; + default: + return IVAS_ERR_INVALID_OUTPUT_FORMAT; } - decCoeffs[lfeIdx] = decMtx[16 * nonLfeChIdx + ambiChnnlIdx]; - } + break; + default: + return IVAS_ERR_INVALID_OUTPUT_FORMAT; } - else + /* Check error here to keep switch statement more compact */ + if ( error != IVAS_ERR_OK ) { - numNonLfeChannels = getNumNonLfeChannelsInSpeakerLayout( outConfig.speakerLayout ); + return error; + } - lfeLastIdxs = getReorderedChannelIndices( outConfig.speakerLayout ); + return IVAS_ERR_OK; +} - /* Clear decoding coefficients - not all elements will be overwritten below */ - set_zero( decCoeffs, getNumChannelsInSpeakerLayout( outConfig.speakerLayout ) ); +static ivas_error renderActiveInputsSba( + IVAS_REND_HANDLE hIvasRend, + IVAS_REND_AudioBuffer outAudio ) +{ + int32_t i; + input_sba *pCurrentInput; + ivas_error error; - for ( nonLfeChIdx = 0; nonLfeChIdx < numNonLfeChannels; ++nonLfeChIdx ) + for ( i = 0, pCurrentInput = hIvasRend->inputsSba; i < RENDERER_MAX_SBA_INPUTS; ++i, ++pCurrentInput ) + { + if ( pCurrentInput->base.inConfig == IVAS_REND_AUDIO_CONFIG_UNKNOWN ) + { + /* Skip inactive inputs */ + continue; + } + if ( ( error = renderInputSba( pCurrentInput, + hIvasRend->outputConfig, + outAudio ) ) != IVAS_ERR_OK ) { - decCoeffs[lfeLastIdxs[nonLfeChIdx]] = decMtx[16 * nonLfeChIdx + ambiChnnlIdx]; + return error; } } -#ifdef WMOPS - wmops_sub_end(); -#endif + return IVAS_ERR_OK; } -/*-------------------------------------------------------------------* - * ivas_limiter_renderer() - * - * In-place saturation control for multichannel buffers with adaptive release time - * - * r: number of clipped output samples - *-------------------------------------------------------------------*/ -static int32_t ivas_limiter_renderer( - 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 */ -) +ivas_error IVAS_REND_GetSamples( + IVAS_REND_HANDLE hIvasRend, + IVAS_REND_AudioBuffer outAudio ) { - int16_t i; - float **channels; - int16_t num_channels; - uint32_t numClipping = 0; + ivas_error error; + int32_t numOutChannels; - /* return early if given bad parameters */ - if ( hLimiter == NULL || output == NULL || output_frame <= 0 ) + /*-----------------------------------------------------------------* + * Validate function arguments + *-----------------------------------------------------------------*/ + + if ( hIvasRend == NULL || outAudio.data == NULL ) { - return 0; + return IVAS_ERR_UNEXPECTED_NULL_POINTER; } - - channels = hLimiter->channel_ptrs; - num_channels = hLimiter->num_channels; - - for ( i = 0; i < num_channels; ++i ) + if ( outAudio.config.numSamplesPerChannel <= 0 || MAX_BUFFER_LENGTH_PER_CHANNEL < outAudio.config.numSamplesPerChannel ) { - channels[i] = output + i * output_frame; + return IVAS_ERR_INVALID_BUFFER_SIZE; + } + if ( outAudio.config.numChannels <= 0 || MAX_OUTPUT_CHANNELS < outAudio.config.numChannels ) + { + return IVAS_ERR_WRONG_NUM_CHANNELS; + } + if ( getAudioConfigType( hIvasRend->outputConfig ) == IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL && + outAudio.config.numSamplesPerChannel * 1000 != BINAURAL_RENDERING_FRAME_SIZE_MS * hIvasRend->sampleRateOut ) + { + /* Binaural rendering requires specific frame size */ + return IVAS_ERR_INVALID_BUFFER_SIZE; + } + if ( ( error = IVAS_REND_NumOutChannels( hIvasRend, &numOutChannels ) ) != IVAS_ERR_OK ) + { + return error; + } + if ( numOutChannels != outAudio.config.numChannels ) + { + return IVAS_ERR_WRONG_NUM_CHANNELS; } - limiter_process( hLimiter, output_frame, threshold, 0, NULL ); + /* Clear output buffer */ + set_zero( outAudio.data, outAudio.config.numChannels * outAudio.config.numSamplesPerChannel ); - /* Apply clipping to buffer in case the limiter let through some samples > 1.0f */ - for ( i = 0; i < output_frame * num_channels; ++i ) + if ( ( error = renderActiveInputsIsm( hIvasRend, outAudio ) ) != IVAS_ERR_OK ) + { + return error; + } + if ( ( error = renderActiveInputsMc( hIvasRend, outAudio ) ) != IVAS_ERR_OK ) + { + return error; + } + if ( ( error = renderActiveInputsSba( hIvasRend, outAudio ) ) != IVAS_ERR_OK ) { + return error; + } + #ifdef DEBUGGING - if ( output[i] > 1.0f || output[i] < -1.0f ) - { - ++numClipping; - } + hIvasRend->numClipping += #endif + limitRendererOutput( hIvasRend->hLimiter, outAudio.data, outAudio.config.numSamplesPerChannel, LIMITER_THRESHOLD ); - output[i] = min( max( INT16_MIN, output[i] ), INT16_MAX ); - } - - return numClipping; + return IVAS_ERR_OK; } -static float dBToLin( const float gain_dB ) +void IVAS_REND_Close( IVAS_REND_HANDLE *phIvasRend ) { - return powf( 10.f, gain_dB / 20.f ); -} + uint32_t i; + IVAS_REND_HANDLE hIvasRend; -static AUDIO_CONFIG mapRendLayoutToAudioConfig( IVAS_REND_SpeakerLayout speakerLayout ) -{ - switch ( speakerLayout ) + /*-----------------------------------------------------------------* + * Validate function arguments + *-----------------------------------------------------------------*/ + + if ( phIvasRend == NULL || *phIvasRend == NULL ) { - case IVAS_REND_SPEAKER_LAYOUT_MONO: - return AUDIO_CONFIG_MONO; - case IVAS_REND_SPEAKER_LAYOUT_STEREO: - return AUDIO_CONFIG_STEREO; - case IVAS_REND_SPEAKER_LAYOUT_5_1: - return AUDIO_CONFIG_5_1; - case IVAS_REND_SPEAKER_LAYOUT_7_1: - return AUDIO_CONFIG_7_1; - case IVAS_REND_SPEAKER_LAYOUT_5_1_2: - return AUDIO_CONFIG_5_1_2; - case IVAS_REND_SPEAKER_LAYOUT_5_1_4: - return AUDIO_CONFIG_5_1_4; - case IVAS_REND_SPEAKER_LAYOUT_7_1_4: - return AUDIO_CONFIG_7_1_4; - case IVAS_REND_SPEAKER_LAYOUT_CUSTOM: - return AUDIO_CONFIG_LS_CUSTOM; - case IVAS_REND_SPEAKER_LAYOUT_NONE: - default: - return AUDIO_CONFIG_INVALID; + return; + } + hIvasRend = *phIvasRend; + + if ( hIvasRend->efapOutWrapper.hEfap != NULL ) + { + efap_free_data( &hIvasRend->efapOutWrapper.hEfap ); + } + + /* clear inputs */ + for ( i = 0; i < RENDERER_MAX_ISM_INPUTS; ++i ) + { + clearInputIsm( &hIvasRend->inputsIsm[i] ); + } + for ( i = 0; i < RENDERER_MAX_MC_INPUTS; ++i ) + { + clearInputMc( &hIvasRend->inputsMc[i] ); } + for ( i = 0; i < RENDERER_MAX_SBA_INPUTS; ++i ) + { + clearInputSba( &hIvasRend->inputsSba[i] ); + } + + ivas_limiter_close( &hIvasRend->hLimiter ); + + count_free( hIvasRend ); + *phIvasRend = NULL; +} + +#ifdef DEBUGGING +int32_t IVAS_REND_GetNoCLipping( + IVAS_REND_CONST_HANDLE hIvasRend ) +{ + return hIvasRend->numClipping; } -static AUDIO_CONFIG mapRendAmbisonicsToAudioConfig( IVAS_REND_Ambisonics ambisonics ) +int32_t IVAS_REND_GetCntFramesLimited( + IVAS_REND_CONST_HANDLE hIvasRend ) { - switch ( ambisonics ) + if ( hIvasRend->hLimiter == NULL ) { - case IVAS_REND_AMBISONICS_FOA: - return AUDIO_CONFIG_FOA; - case IVAS_REND_AMBISONICS_SOA: - return AUDIO_CONFIG_HOA2; - case IVAS_REND_AMBISONICS_TOA: - return AUDIO_CONFIG_HOA3; - case IVAS_REND_AMBISONICS_NONE: - default: - return AUDIO_CONFIG_INVALID; + return 0; } + + return hIvasRend->hLimiter->cnt_frames_limited; } +#endif diff --git a/lib_rend/lib_rend.h b/lib_rend/lib_rend.h index dfcf0ec57a..3be9ad9964 100644 --- a/lib_rend/lib_rend.h +++ b/lib_rend/lib_rend.h @@ -33,9 +33,9 @@ #ifndef LIB_REND_H #define LIB_REND_H +#include #include #include -#include #include "options.h" #include "common_api_types.h" @@ -48,203 +48,215 @@ #define RENDERER_HEAD_POSITIONS_PER_FRAME 4 -typedef enum IVAS_REND_Ambisonics -{ - IVAS_REND_AMBISONICS_NONE = -1, - IVAS_REND_AMBISONICS_MONO = 0, - IVAS_REND_AMBISONICS_FOA = 1, - IVAS_REND_AMBISONICS_SOA = 2, - IVAS_REND_AMBISONICS_TOA = 3 -} IVAS_REND_Ambisonics; /* Numerical value corresponds to Ambisonics order */ - -typedef enum IVAS_REND_SpeakerLayout +typedef struct { - IVAS_REND_SPEAKER_LAYOUT_NONE = -1, - IVAS_REND_SPEAKER_LAYOUT_CUSTOM = 0, - IVAS_REND_SPEAKER_LAYOUT_MONO = 1, - IVAS_REND_SPEAKER_LAYOUT_STEREO = 2, - IVAS_REND_SPEAKER_LAYOUT_5_1 = 6, - IVAS_REND_SPEAKER_LAYOUT_5_1_2 = 14, - IVAS_REND_SPEAKER_LAYOUT_5_1_4 = 16, - IVAS_REND_SPEAKER_LAYOUT_7_1 = 12, - IVAS_REND_SPEAKER_LAYOUT_7_1_4 = 19 -} IVAS_REND_SpeakerLayout; /* Numerical value corresponds to CICP index */ - -typedef enum IVAS_REND_BinauralFormat + int16_t numSamplesPerChannel; + int16_t numChannels; +} IVAS_REND_AudioBufferConfig; + +typedef struct { - IVAS_REND_BINAURAL_NONE = -1, - IVAS_REND_BINAURAL_DIRECT = 0, - IVAS_REND_BINAURAL_ROOM = 2 -} IVAS_REND_BinauralFormat; + IVAS_REND_AudioBufferConfig config; + float *data; +} IVAS_REND_AudioBuffer; -typedef enum IVAS_REND_MasaTc +typedef struct { - IVAS_REND_MASA_TC_NONE = -1, - IVAS_REND_MASA_TC_1 = 1, - IVAS_REND_MASA_TC_2 = 2, -} IVAS_REND_MasaTc; /* Numerical value corresponds to number of transport channels */ + IVAS_REND_AudioBufferConfig config; + const float *data; +} IVAS_REND_ReadOnlyAudioBuffer; -typedef struct IVAS_REND_AudioObjectPosition +typedef struct { float azimuth; float elevation; } IVAS_REND_AudioObjectPosition; -typedef struct IVAS_REND_AudioObjectMetadataBuffer -{ - IVAS_REND_AudioObjectPosition positions[RENDERER_MAX_ISM_INPUTS]; - int16_t numObjects; -} IVAS_REND_AudioObjectMetadataBuffer; +typedef struct IVAS_REND *IVAS_REND_HANDLE; +typedef struct IVAS_REND const *IVAS_REND_CONST_HANDLE; -typedef struct IVAS_REND_AudioObject +typedef enum { - uint16_t inputChannelIndex; - float gain_dB; -} IVAS_REND_AudioObject; - -typedef struct IVAS_REND_ObjPanInfo + IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED = 0, + IVAS_REND_AUDIO_CONFIG_TYPE_AMBISONICS, + IVAS_REND_AUDIO_CONFIG_TYPE_OBJECT_BASED, + IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL, + IVAS_REND_AUDIO_CONFIG_TYPE_MASA, + IVAS_REND_AUDIO_CONFIG_TYPE_UNKNOWN, +} IVAS_REND_AudioConfigType; + +/* TODO(sgi): Harmonize with AUDIO_CONFIG */ +/* + Note: numerical values carry specific information here. + + MSB LSB + -------------------------------------------------------------------------------- + ... unused (assumed all 0) ... | config type (1 byte) | config variant (1 byte) | + -------------------------------------------------------------------------------- + + Where "config type" is the general type from the following list: + - unknown + - channel-based + - ambisonics + - object-based + - binaural + - MASA + + Config variants are concrete configs of each type. + */ +typedef enum { - IVAS_REND_AudioObjectPosition position; - float *panGains; -} IVAS_REND_ObjPanInfo; + IVAS_REND_AUDIO_CONFIG_MONO = IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED << 8 | 0, + IVAS_REND_AUDIO_CONFIG_STEREO = IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED << 8 | 1, + IVAS_REND_AUDIO_CONFIG_5_1 = IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED << 8 | 2, + IVAS_REND_AUDIO_CONFIG_7_1 = IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED << 8 | 3, + IVAS_REND_AUDIO_CONFIG_5_1_2 = IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED << 8 | 4, + IVAS_REND_AUDIO_CONFIG_5_1_4 = IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED << 8 | 5, + IVAS_REND_AUDIO_CONFIG_7_1_4 = IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED << 8 | 6, + IVAS_REND_AUDIO_CONFIG_LS_CUSTOM = IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED << 8 | 255, -typedef struct IVAS_REND_AmbisonicsBus -{ - IVAS_REND_Ambisonics ambisonicsConfig; - uint8_t inputChannelIndex; - float gain_dB; -} IVAS_REND_AmbisonicsBus; + IVAS_REND_AUDIO_CONFIG_FOA = IVAS_REND_AUDIO_CONFIG_TYPE_AMBISONICS << 8 | 0, + IVAS_REND_AUDIO_CONFIG_HOA2 = IVAS_REND_AUDIO_CONFIG_TYPE_AMBISONICS << 8 | 1, + IVAS_REND_AUDIO_CONFIG_HOA3 = IVAS_REND_AUDIO_CONFIG_TYPE_AMBISONICS << 8 | 2, -typedef struct IVAS_REND_MultiChannelBus -{ - IVAS_REND_SpeakerLayout speakerLayout; - uint8_t inputChannelIndex; - float gain_dB; -} IVAS_REND_MultiChannelBus; + IVAS_REND_AUDIO_CONFIG_OBJECT = IVAS_REND_AUDIO_CONFIG_TYPE_OBJECT_BASED << 8 | 0, -typedef struct IVAS_REND_MasaBus -{ - IVAS_REND_MasaTc numTc; - uint8_t inputChannelIndex; - float gain_dB; -} IVAS_REND_MasaBus; + IVAS_REND_AUDIO_CONFIG_BINAURAL = IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL << 8 | 0, + IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM = IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL << 8 | 1, -typedef struct IVAS_REND_AudioBufferConfig -{ - int32_t sampleRate; - int16_t bufferSize; - int16_t numChannels; -} IVAS_REND_AudioBufferConfig; + IVAS_REND_AUDIO_CONFIG_MASA1 = IVAS_REND_AUDIO_CONFIG_TYPE_MASA << 8 | 0, + IVAS_REND_AUDIO_CONFIG_MASA2 = IVAS_REND_AUDIO_CONFIG_TYPE_MASA << 8 | 1, -typedef struct IVAS_REND_AudioBuffer -{ - IVAS_REND_AudioBufferConfig config; - float *data; -} IVAS_REND_AudioBuffer; + IVAS_REND_AUDIO_CONFIG_UNKNOWN = IVAS_REND_AUDIO_CONFIG_TYPE_UNKNOWN << 8 | 0, +} IVAS_REND_AudioConfig; -typedef struct IVAS_REND_InputConfig -{ - IVAS_REND_AudioObject audioObjects[RENDERER_MAX_ISM_INPUTS]; - uint16_t numAudioObjects; - IVAS_REND_MultiChannelBus multiChannelBuses[RENDERER_MAX_MC_INPUTS]; - uint16_t numMultiChannelBuses; - IVAS_REND_AmbisonicsBus ambisonicsBuses[RENDERER_MAX_SBA_INPUTS]; - uint16_t numAmbisonicsBuses; - IVAS_LSSETUP_CUSTOM_HANDLE inSetupCustom; - IVAS_REND_MasaBus masaBus; /* Support one MASA input for now. Multiple inputs will be easier to implement after API rework. */ - uint16_t numMasaBuses; /* Keep for framework consistency for now. Again - this will not be necessary after API rework */ -} IVAS_REND_InputConfig; - -typedef struct IVAS_REND_OutputConfig -{ - IVAS_REND_SpeakerLayout speakerLayout; - IVAS_REND_Ambisonics ambisonics; - IVAS_REND_BinauralFormat binauralFormat; - IVAS_LSSETUP_CUSTOM_HANDLE outSetupCustom; -} IVAS_REND_OutputConfig; +typedef uint32_t IVAS_REND_InputId; -typedef struct IVAS_REND *IVAS_REND_HANDLE; +typedef struct +{ + int32_t numLfeChannels; + float lfeOutputGains[IVAS_MAX_INPUT_LFE_CHANNELS][IVAS_MAX_OUTPUT_CHANNELS]; +} IVAS_REND_LfeRouting; /* clang-format off */ /*----------------------------------------------------------------------------------* * Function prototypes *----------------------------------------------------------------------------------*/ -/*! Creates a renderer state. - * r: pointer to opened renderer */ -IVAS_REND_HANDLE IVAS_REND_Open( /* TODO(sgi): Return ivas_error type */ - void +/* Functions to be called before rendering */ + +ivas_error IVAS_REND_Open( + IVAS_REND_HANDLE *phIvasRend, /* i/o: Pointer to renderer handle */ + int32_t outputSampleRate, /* i : output sampling rate */ + IVAS_REND_AudioConfig outConfig /* i : output audio config */ +); + +/* Note: this will reset custom LFE routings set for any MC input */ +ivas_error IVAS_REND_ConfigureCustomOutputLoudspeakerLayout( + IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + IVAS_CUSTOM_LS_DATA layout /* i : custom loudspeaker layout for renderer output */ +); + +/* Support for custom HRTFs will be added in the future. */ +/* Note: this affects output delay */ +ivas_error IVAS_REND_SetCustomHrtf( + IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + void* TODO +); + +/* Functions to be called before/during rendering */ + +ivas_error IVAS_REND_NumOutChannels( + IVAS_REND_CONST_HANDLE hIvasRend, /* i : Renderer handle */ + int32_t *numOutChannels /* o : number of output channels */ +); + +ivas_error IVAS_REND_AddInput( + IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + IVAS_REND_AudioConfig inConfig, /* i : audio config for a new input */ + IVAS_REND_InputId *inputId /* o : ID of the new input */ +); + +/* Note: this will reset any custom LFE routing set for the input */ +ivas_error IVAS_REND_ConfigureCustomInputLoudspeakerLayout( + IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + IVAS_REND_InputId inputId, /* i : ID of the input */ + IVAS_CUSTOM_LS_DATA layout /* i : custom loudspeaker layout for input */ ); -/* TODO(sgi): Use hIvasRend as name for handle arg */ -/*! Configures the renderer - needs to be called after IVAS_REND_Open(). */ -ivas_error IVAS_REND_Configure( - IVAS_REND_HANDLE st, /* i : Renderer state */ - const IVAS_REND_InputConfig inConfig, /* i : Input configuration */ - const IVAS_REND_OutputConfig outConfig, /* i : Output configuration */ - uint32_t sampleRate, /* i : Processing sampling rate */ - bool headRotationEnabled, /* i : enable head rotation for binaural output, ignored for other output formats */ - bool rendererConfigEnabled /* i : flag indicating if a renderer configuration file was supplied */ +ivas_error IVAS_REND_SetInputGain( + IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + IVAS_REND_InputId inputId, /* i : ID of the input */ + float gain /* i : linear gain (not in dB) */ ); -void IVAS_REND_SetHeadRotation( - IVAS_REND_HANDLE st, - const IVAS_QUATERNION headRot[RENDERER_HEAD_POSITIONS_PER_FRAME] +ivas_error IVAS_REND_SetInputLfeRouting( + IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + IVAS_REND_InputId inputId, /* i : ID of the input */ + IVAS_REND_LfeRouting lfeRouting /* i : custom LFE routing struct */ ); -ivas_error IVAS_REND_FeedMasaMetadata( - IVAS_REND_HANDLE st, - IVAS_MASA_METADATA_HANDLE hMasaMetadata +ivas_error IVAS_REND_RemoveInput( + IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + IVAS_REND_InputId inputId /* i : ID of the input */ ); -/*! Renders one frame of audio samples */ -void IVAS_REND_Render( - IVAS_REND_HANDLE st, /* i : Renderer state */ - const IVAS_REND_AudioBuffer inAudio, /* i : Buffer with pointer to input samples and associated info */ - const IVAS_REND_AudioObjectMetadataBuffer metadataBuffer, /* i : Buffer with object metadata for current frame */ - IVAS_REND_AudioBuffer outAudio /* o : Buffer with pointer to output samples and associated info */ +ivas_error IVAS_REND_GetInputNumChannels( + IVAS_REND_CONST_HANDLE hIvasRend, /* i : Renderer handle */ + IVAS_REND_InputId inputId, /* i : ID of the input */ + int32_t *numChannels /* o : number of channels of the input */ ); -/*! Returns the delay depending on which renderer was used */ ivas_error IVAS_REND_GetDelay( - IVAS_REND_HANDLE st, /* 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 */ + IVAS_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 */ ); -/*! Allocate memory for custom loudspeaker layout */ -void IVAS_REND_OpenCustomLayout( - IVAS_LSSETUP_CUSTOM_HANDLE *outSetupCustom ); +/* Functions to be called during rendering */ -/*! Enable/disable experimental LFE handling */ -void IVAS_REND_SetNeverDropLfe( - IVAS_REND_HANDLE st, /* i : Renderer state */ - int8_t neverDropLfe /* i : If 0, LFE channel will be dropped when rendering to configs w/o LFE. - If 1, tries to render LFE into other channels in an optimal way when rendering to configs w/o LFE. */ +ivas_error IVAS_REND_FeedInputAudio( + IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + IVAS_REND_InputId inputId, /* i : ID of the input */ + IVAS_REND_ReadOnlyAudioBuffer inputAudio /* i : buffer with input audio */ ); -/*! Get number of input channels based on InputConfig */ -int16_t IVAS_REND_GetInChannels( - IVAS_REND_HANDLE st /* i : Renderer state */ +ivas_error IVAS_REND_FeedInputObjectMetadata( + IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + IVAS_REND_InputId inputId, /* i : ID of the input */ + IVAS_REND_AudioObjectPosition objectPosition /* i : object position struct */ ); -/*! Get number of output channels based on OutputConfig */ -int16_t IVAS_REND_GetOutChannels( - IVAS_REND_HANDLE st /* i : Renderer state */ +/* Support for MASA input will be added in the future. */ +ivas_error IVAS_REND_FeedInputMasaMetadata( + IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + IVAS_REND_InputId inputId, /* i : ID of the input */ + void* TODO ); -/*! Destructs the renderer state and frees memory */ +ivas_error IVAS_REND_SetHeadRotation( + IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + const IVAS_QUATERNION headRot[RENDERER_HEAD_POSITIONS_PER_FRAME] /* i : head positions for next rendering call */ +); + +ivas_error IVAS_REND_GetSamples( + IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ + IVAS_REND_AudioBuffer outAudio /* i/o: buffer for output audio */ +); + +/* Functions to be called after rendering */ + void IVAS_REND_Close( - IVAS_REND_HANDLE* st /* i : Renderer state */ + IVAS_REND_HANDLE* phIvasRend /* i/o: Pointer to renderer handle */ ); #ifdef DEBUGGING int32_t IVAS_REND_GetNoCLipping( - IVAS_REND_HANDLE st /* i : Renderer state */ + IVAS_REND_CONST_HANDLE hIvasRend /* i : Renderer handle */ ); int32_t IVAS_REND_GetCntFramesLimited( - IVAS_REND_HANDLE st /* i : Renderer state */ + IVAS_REND_CONST_HANDLE hIvasRend /* i : Renderer handle */ ); #endif diff --git a/lib_util/cmdln_parser.h b/lib_util/cmdln_parser.h index 692072df63..a50defcdbb 100644 --- a/lib_util/cmdln_parser.h +++ b/lib_util/cmdln_parser.h @@ -34,6 +34,7 @@ #define CMDLN_PARSER_H #include +#include #include "options.h" @@ -42,7 +43,7 @@ typedef struct int32_t id; const char *match; const char *matchShort; - int8_t isRequired; + bool isRequired; const char *description; } CmdLnParser_Option; diff --git a/lib_util/ls_custom_file_reader.c b/lib_util/ls_custom_file_reader.c index c961374c20..1713f55af4 100644 --- a/lib_util/ls_custom_file_reader.c +++ b/lib_util/ls_custom_file_reader.c @@ -314,7 +314,7 @@ LS_CUSTOM_FILEREADER_ERROR CustomLsFileReading( } } - /* parse LFE indicies; skip if blank line */ + /* parse LFE indices; skip if blank line */ if ( ( fgets( line, 200, hLsCustomReader->file ) != NULL ) && ( strcmp( line, "\n" ) != 0 ) && ( strcmp( line, "\r\n" ) != 0 ) ) { for ( tok = strtok( line, "," ); tok && *tok; tok = strtok( NULL, ",\n" ) ) diff --git a/scripts/pyaudio3dtools/audiofile.py b/scripts/pyaudio3dtools/audiofile.py index b03b472ae9..46bb452082 100644 --- a/scripts/pyaudio3dtools/audiofile.py +++ b/scripts/pyaudio3dtools/audiofile.py @@ -35,7 +35,6 @@ import platform import shutil import struct import subprocess as sp -import warnings from importlib import import_module from tempfile import TemporaryDirectory from typing import Optional, Tuple @@ -74,18 +73,6 @@ def readfile( if file_extension == ".wav": fs, data = wav.read(filename) - if data.dtype == np.int32: - data = np.interp( - data, - (np.iinfo(np.int32).min, np.iinfo(np.int32).max), - (np.iinfo(np.int16).min, np.iinfo(np.int16).max), - ) - elif data.dtype == np.float32: - data = np.interp( - data, - (-1, 1), - (np.iinfo(np.int16).min, np.iinfo(np.int16).max), - ) x = np.array(data, dtype=outdtype) file_len = x.shape[0] if x.ndim == 1: @@ -120,11 +107,9 @@ def writefile(filename: str, x: np.ndarray, fs: int = 48000) -> None: """ _, file_extension = os.path.splitext(os.path.basename(filename)) - clipped_samples = np.sum( - np.logical_or(x < np.iinfo(np.int16).min, x > np.iinfo(np.int16).max) - ) + clipped_samples = np.sum(np.logical_or(x < np.iinfo(np.int16).min, x > np.iinfo(np.int16).max)) if clipped_samples > 0: - warnings.warn(f" Warning: {clipped_samples} samples clipped") + print(" Warning: %i samples clipped"%clipped_samples) x = np.clip(x, np.iinfo(np.int16).min, np.iinfo(np.int16).max) if file_extension == ".wav": @@ -504,6 +489,7 @@ def loudnessinfo( in_sig: np.ndarray, in_fs: Optional[int] = 48000, in_format: Optional[str] = "MONO", + in_ls_layout_file: Optional[str] = None, output_loudness: Optional[int] = -26, loudness_tool: Optional[str] = "bs1770demo", use_rms: Optional[bool] = False, @@ -538,10 +524,13 @@ def loudnessinfo( else: null_file = "/dev/null" + # check for binary if shutil.which(loudness_tool) is None: raise FileNotFoundError(f"The binary {loudness_tool} was not found in path!") - in_spfmt = spatialaudioformat.Format(in_format=in_format) + in_spfmt = spatialaudioformat.Format( + in_format=in_format, ls_layout_file=in_ls_layout_file + ) if not (in_spfmt.isheadphones or in_spfmt.isloudspeaker or in_spfmt.ambi_order > 1): raise NotImplementedError( @@ -554,7 +543,7 @@ def loudnessinfo( ) with TemporaryDirectory() as tmp_dir: - tmp_file = os.path.join(tmp_dir, "tmp_loudness.pcm") + tmp_file = os.path.join(tmp_dir, "tmp.pcm") if "bs1770demo" in loudness_tool: """ diff --git a/scripts/pyaudio3dtools/binauralrenderer.py b/scripts/pyaudio3dtools/binauralrenderer.py index 23f476a5fd..520305c7bf 100644 --- a/scripts/pyaudio3dtools/binauralrenderer.py +++ b/scripts/pyaudio3dtools/binauralrenderer.py @@ -41,7 +41,7 @@ import scipy.io as sio import scipy.signal as sig from pyaudio3dtools.rotation import rotateHOA, rotateISM, rotateMC -from pyaudio3dtools import audioarray, spatialaudioformat +from pyaudio3dtools import audioarray, spatialaudioformat, spatialaudioconvert from pyaudio3dtools.constants import * main_logger = logging.getLogger("__main__") @@ -85,17 +85,17 @@ def read_hrirs_from_mat( def get_IR( - in_format: spatialaudioformat.Format, - out_format: spatialaudioformat.Format, + in_spfmt: spatialaudioformat.Format, + out_spfmt: spatialaudioformat.Format, dataset: str, ) -> Tuple[np.ndarray, np.ndarray]: """get_IR Parameters ---------- - in_format: spatialaudioformat + in_spfmt: spatialaudioformat input spatial audio format - out_format: spatialaudioformat + out_spfmt: spatialaudioformat output spatial audio format dataset: str name of the HRIRs or BRIRs dataset @@ -109,7 +109,7 @@ def get_IR( """ # override for BRIRs, currently only one option - if out_format.name == "BINAURAL_ROOM": + if out_spfmt.name == "BINAURAL_ROOM": dataset = "mozart_iis" # dataset file prefix @@ -123,37 +123,37 @@ def get_IR( raise ValueError(f"Unsupported dataset '{dataset}' for HRIRs") # dataset file suffix - if in_format.name.startswith("ISM") or in_format.name.startswith("CUSTOM_LS"): + if in_spfmt.name.startswith("ISM") or in_spfmt.altname.startswith("CUSTOM_LS"): suffix = "full.mat" - elif in_format.isloudspeaker and in_format.nchannels > 1: + elif in_spfmt.isloudspeaker and in_spfmt.nchannels > 1: suffix = "combined.mat" - elif in_format.ambi_order > 0 or in_format.name.upper() == "MONO": + elif in_spfmt.ambi_order > 0 or in_spfmt.name.upper() == "MONO": suffix = "SBA3.mat" else: raise ValueError( - f"Unsupported format '{in_format.name}' for dataset '{dataset}' for HRIRs" + f"Unsupported format '{in_spfmt.name}' for dataset '{dataset}' for HRIRs" ) IR, SourcePosition = read_hrirs_from_mat("_".join([prefix, suffix])) - if in_format.name.startswith("MONO"): + if in_spfmt.name.startswith("MONO"): IR = IR[:, :, :1] # use omni/W from SBA - elif in_format.name.startswith("STEREO"): + elif in_spfmt.name.startswith("STEREO"): IR = IR[:, :, :2] # use L and R channels - elif in_format.isloudspeaker and not in_format.name.startswith("CUSTOM_LS"): + elif in_spfmt.isloudspeaker and not in_spfmt.altname.startswith("CUSTOM_LS"): # extract positions from the combined file - tmpformat = spatialaudioformat.Format("COMBINED") + tmp_spfmt = spatialaudioformat.Format("COMBINED") IR_tmp = IR.copy() - IR = np.zeros([IR_tmp.shape[0], IR_tmp.shape[1], in_format.nchannels]) + IR = np.zeros([IR_tmp.shape[0], IR_tmp.shape[1], in_spfmt.nchannels]) ir_index = 0 - for i in range(tmpformat.nchannels): - for j in range(in_format.nchannels): + for i in range(tmp_spfmt.nchannels): + for j in range(in_spfmt.nchannels): if ( - tmpformat.ls_azi[i] == in_format.ls_azi[j] - and tmpformat.ls_ele[i] == in_format.ls_ele[j] + tmp_spfmt.ls_azi[i] == in_spfmt.ls_azi[j] + and tmp_spfmt.ls_ele[i] == in_spfmt.ls_ele[j] ): - if j != in_format.lfe_index[0]: + if j != in_spfmt.lfe_index[0]: IR[:, :, ir_index] = IR_tmp[:, :, i] ir_index += 1 @@ -502,6 +502,8 @@ def binaural_render_LFE( if lfe.shape[1] > 1: lfe = np.sum(lfe, axis=1) + # TODO tmu - disabled temporarily here, disabled in C + """ # 120 Hz low-pass filtering for LFE using IVAS filter coefficients if fs == 48000: lfe = sig.sosfilt(IVAS_LPF_4_BUTTER_48K_SOS, lfe, axis=0) @@ -515,6 +517,7 @@ def binaural_render_LFE( lfe = np.roll(lfe, -filter_delay, axis=0) lfe[-filter_delay:, :] = 0 + """ # apply gain lfe *= LFE_gain @@ -530,20 +533,31 @@ def binaural_render_LFE( def render_custom_ls_binaural( x: np.ndarray, fs: int, - in_format: spatialaudioformat.Format, + in_spfmt: spatialaudioformat.Format, + out_spfmt: spatialaudioformat.Format, IR: np.ndarray, SourcePosition: np.ndarray, trajectory: np.ndarray, ) -> np.ndarray: - ls_azi_all = in_format.ls_azi - ls_ele_all = in_format.ls_ele - lfe_index_all = in_format.lfe_index - - logger.info(" Processing channels on custom LS layout") - logger.info("azi: {}".format(ls_azi_all)) - logger.info("ele: {}".format(ls_ele_all)) - logger.info("lfe_index: {}".format(lfe_index_all)) + ls_azi_all = in_spfmt.ls_azi + ls_ele_all = in_spfmt.ls_ele + lfe_index_all = in_spfmt.lfe_index + + logger.info(" Processing channels on custom LS layout") + azis = ", ".join([f"{a:7.2f}" for a in ls_azi_all]) + eles = ", ".join([f"{e:7.2f}" for e in ls_ele_all]) + logger.info(f" azi: {azis}") + logger.info(f" ele: {eles}") + logger.info(f" lfe_index: {lfe_index_all}") + + if out_spfmt.name == "BINAURAL_ROOM": + tmp_spfmt = spatialaudioformat.Format("7_1_4") + x = spatialaudioconvert.convert_mc(x, in_spfmt, tmp_spfmt) + ls_azi_all = tmp_spfmt.ls_azi + ls_ele_all = tmp_spfmt.ls_ele + lfe_index_all = tmp_spfmt.lfe_index + logger.info(f" {in_spfmt.name} -> {tmp_spfmt.name} -> {out_spfmt.name}") frame_len = (IVAS_FRAME_LEN_MS // 4) * (fs // 1000) sig_len = x.shape[0] @@ -564,8 +578,7 @@ def render_custom_ls_binaural( ls_azi = np.repeat(ls_azi_all[i_ls], N_frames) ls_ele = np.repeat(ls_ele_all[i_ls], N_frames) - if trajectory is not None: - azi, ele = rotateISM(ls_azi, ls_ele, trajectory=trajectory) + azi, ele = rotateISM(ls_azi, ls_ele, trajectory=trajectory) y += binaural_fftconv_framewise( x[:, i_chan], @@ -601,7 +614,7 @@ def render_ism_binaural( [pos["azimuth"], pos["elevation"]] for _ in range(pos["use_for_frames"]) ) pos_data = np.array(pos_data) - pos_data = np.tile(pos_data, (4, 1)) + pos_data = np.repeat(pos_data, 4, axis=0) # extract positions only according to the audio duration pos_data = pos_data[:N_frames, :] @@ -625,7 +638,7 @@ def render_ism_binaural( def render_masa_binaural( x: np.ndarray, fs: int, - in_format: spatialaudioformat.Format, + in_spfmt: spatialaudioformat.Format, IR: np.ndarray, SourcePosition: np.ndarray, trajectory: np.ndarray, @@ -638,19 +651,19 @@ def render_masa_binaural( def render_ambi_ls_binaural( x: np.ndarray, fs: int, - in_format: spatialaudioformat.Format, + in_spfmt: spatialaudioformat.Format, IR: np.ndarray, trajectory: np.ndarray, ) -> np.ndarray: y = x[:] if trajectory is not None: - if in_format.ambi_order > 0: + if in_spfmt.ambi_order > 0: y = rotateHOA(y, trajectory) - if in_format.isloudspeaker: - y = rotateMC(y, trajectory, in_format) + if in_spfmt.isloudspeaker: + y = rotateMC(y, trajectory, in_spfmt) - y = binaural_fftconv(y, IR, in_format.nchannels, in_format.lfe_index) + y = binaural_fftconv(y, IR, in_spfmt.nchannels, in_spfmt.lfe_index) return y @@ -660,8 +673,8 @@ def render_ambi_ls_binaural( def binaural_rendering( x: np.ndarray, - in_format: spatialaudioformat.Format, - out_format: spatialaudioformat.Format, + in_spfmt: spatialaudioformat.Format, + out_spfmt: spatialaudioformat.Format, dataset: str = "orange53", fs: int = 48000, trajectory: str = None, @@ -675,7 +688,7 @@ def binaural_rendering( ---------- x: np array input multi-channel array - in_format_name: str + in_spfmt_name: str name of input spatial format dataset: str name of the HRIRs or BRIRs dataset @@ -700,17 +713,19 @@ def binaural_rendering( y = audioarray.resample(x, fs, 48000) # get IR corresponding to the input and output formats - IR, SourcePosition = get_IR(in_format, out_format, dataset) + IR, SourcePosition = get_IR(in_spfmt, out_spfmt, dataset) latency_smp = np.argmax(np.sum(np.abs(IR), axis=(1, 2))) # prepare LFE signal to be added to output - if include_LFE and in_format.isloudspeaker: - lfe = binaural_render_LFE(x, 48000, in_format.lfe_index, LFE_gain) + if include_LFE and in_spfmt.isloudspeaker and in_spfmt.lfe_index: + lfe = binaural_render_LFE(x, 48000, in_spfmt.lfe_index, LFE_gain) # get binauralized signal based on format - if in_format.name.startswith("CUSTOM_LS"): - y = render_custom_ls_binaural(x, fs, in_format, IR, SourcePosition, trajectory) - elif in_format.name.startswith("ISM"): + if in_spfmt.altname.startswith("CUSTOM_LS"): + y = render_custom_ls_binaural( + x, fs, in_spfmt, out_spfmt, IR, SourcePosition, trajectory + ) + elif in_spfmt.name.startswith("ISM"): if not in_pos: raise ValueError("ISM metadata empty!") y = render_ism_binaural( @@ -721,13 +736,13 @@ def binaural_rendering( trajectory, in_pos, ) - elif in_format.name.startswith("MASA"): - y = render_masa_binaural(x, fs, in_format, IR, SourcePosition, trajectory) - elif in_format.ambi_order > 0 or in_format.isloudspeaker: - y = render_ambi_ls_binaural(x, fs, in_format, IR, trajectory) + elif in_spfmt.name.startswith("MASA"): + y = render_masa_binaural(x, fs, in_spfmt, IR, SourcePosition, trajectory) + elif in_spfmt.ambi_order > 0 or in_spfmt.isloudspeaker: + y = render_ambi_ls_binaural(x, fs, in_spfmt, IR, trajectory) else: raise NotImplementedError( - f"{in_format.name} -> {out_format.name}: format conversion not implemented" + f"{in_spfmt.name} -> {out_spfmt.name}: format conversion not implemented" ) # HRTF delay compensation @@ -735,7 +750,7 @@ def binaural_rendering( y[-latency_smp:, :] = 0 # add LFE signal to output - if include_LFE and in_format.isloudspeaker: + if include_LFE and in_spfmt.isloudspeaker and in_spfmt.lfe_index: y += lfe # resample back to original rate diff --git a/scripts/pyaudio3dtools/spatialaudioconvert.py b/scripts/pyaudio3dtools/spatialaudioconvert.py index 28f9298924..2dc1fc0737 100644 --- a/scripts/pyaudio3dtools/spatialaudioconvert.py +++ b/scripts/pyaudio3dtools/spatialaudioconvert.py @@ -357,11 +357,15 @@ def convert_mc( if i not in in_spfmt.lfe_index ] ) + # TODO tmu : implement configurable LFE handling # pass-through for LFE MC2LS = np.insert(MC2LS, in_spfmt.lfe_index, 0, axis=0) MC2LS = np.insert(MC2LS, out_spfmt.lfe_index, 0, axis=1) MC2LS[in_spfmt.lfe_index, out_spfmt.lfe_index] = 1 + # TODO tmu temporarily disable LFE rendering to MONO/STEREO + if out_spfmt.name == "MONO" or out_spfmt.name == "STEREO": + MC2LS[in_spfmt.lfe_index, :] = 0 return in_sig @ MC2LS # MC -> HOA elif out_spfmt.ambi_order > 0: diff --git a/scripts/pyaudio3dtools/spatialaudioformat.py b/scripts/pyaudio3dtools/spatialaudioformat.py index 9125d80b64..40f08800c4 100644 --- a/scripts/pyaudio3dtools/spatialaudioformat.py +++ b/scripts/pyaudio3dtools/spatialaudioformat.py @@ -199,7 +199,7 @@ _format_configs = { "ls_azi": None, "ls_ele": None, "lfe_index": None, - "altname": "custom_ls", + "altname": "CUSTOM_LS", "config_file": "layout.txt", }, # ambisonics diff --git a/scripts/pyaudio3dtools/spatialmetadata.py b/scripts/pyaudio3dtools/spatialmetadata.py index 4bbb4b95fe..4d7029482b 100644 --- a/scripts/pyaudio3dtools/spatialmetadata.py +++ b/scripts/pyaudio3dtools/spatialmetadata.py @@ -424,6 +424,7 @@ def read_gain_value(file_handle: TextIO) -> float: file_handle.seek(original_pos) return 1 + ################################################## # Helper functions for ISM IVAS metadata ################################################## diff --git a/scripts/pyprocessing/prepost_processing.py b/scripts/pyprocessing/prepost_processing.py index dee95b77a6..a2c014b6a9 100644 --- a/scripts/pyprocessing/prepost_processing.py +++ b/scripts/pyprocessing/prepost_processing.py @@ -161,7 +161,8 @@ class PostProcessing(Processing): out_sig, fs = audiofile.readfile(output_path) bin_sig = binauralrenderer.binaural_rendering( out_sig, - self.out_spfmt.name, + self.out_spfmt, + spatialaudioformat.Format("BINAURAL"), fs=fs, include_LFE=self.bin_rend_include_LFE, LFE_gain=self.bin_rend_LFE_gain, diff --git a/scripts/tests/compare_audio.py b/scripts/tests/compare_audio.py index 56f35735fc..915cc432e9 100644 --- a/scripts/tests/compare_audio.py +++ b/scripts/tests/compare_audio.py @@ -1,3 +1,31 @@ +#!/usr/bin/env python3 + +""" + (C) 2022 Baseline Development Group 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 Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The Baseline Development Group 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 Corporation, Qualcomm Technologies, Inc., and VoiceAge Corporation retain full ownership + rights in their respective contributions in the software. No license of any kind, including but not + limited to patent license, of any foregoing parties is hereby granted by implication, estoppel or + otherwise. + + 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/or 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. +""" + import warnings from typing import Tuple diff --git a/scripts/tests/constants.py b/scripts/tests/constants.py index 7893bedd61..dcf8bbe3a9 100644 --- a/scripts/tests/constants.py +++ b/scripts/tests/constants.py @@ -56,6 +56,18 @@ RENDERER_CMD = [ "-q", ] +""" Renderer commandline template """ +TDRENDERER_CMD = [ + str( + TESTS_DIR.parent.joinpath("td_object_renderer") + .joinpath("object_renderer_standalone") + .joinpath("renderer_standalone") + ), + "48", + "", # 4 -> input file + "", # 5 -> output file +] + """ Format to file mappings """ NCHAN_TO_FILE = { 1: TEST_VECTOR_DIR.joinpath("spectral_test_1ch_48kHz.wav"), @@ -163,7 +175,7 @@ CUSTOM_LS_TO_TEST = [ ] """ Mixed scene ( metadata ) rendering """ -METADATA_SCENES_TO_TEST = ["mixed_scene"] +METADATA_SCENES_TO_TEST = ["mixed_scene", "mixed_scene_simple"] METADATA_SCENES_TO_TEST_NO_BE = ["masa_scene"] """ Binaural rendering """ @@ -181,7 +193,7 @@ INPUT_FORMATS_BINAURAL.extend( OUTPUT_FORMATS_BINAURAL = ["BINAURAL", "BINAURAL_ROOM"] HR_TRAJECTORIES_TO_TEST = [ # "const000", - # "full_circle_in_15s", - "full_circle_in_15s-Euler", + "full_circle_in_15s", + # "full_circle_in_15s-Euler", "rotate_yaw_pitch_roll1", ] diff --git a/scripts/tests/data/mixed_scene_simple.txt b/scripts/tests/data/mixed_scene_simple.txt new file mode 100644 index 0000000000..85d38b8e93 --- /dev/null +++ b/scripts/tests/data/mixed_scene_simple.txt @@ -0,0 +1,12 @@ +spectral_test_4ch_48kHz.wav +3 +ISM +1 +ism_0a_0e.csv +ISM +2 +1 +1,-30,0 +MC +3 +STEREO diff --git a/scripts/tests/test_renderer.py b/scripts/tests/test_renderer.py index c66a4747d6..db7fb5fd54 100644 --- a/scripts/tests/test_renderer.py +++ b/scripts/tests/test_renderer.py @@ -27,7 +27,8 @@ """ import subprocess as sp -from pathlib import PurePath +from pathlib import Path +from tempfile import TemporaryDirectory from typing import Optional, Tuple import numpy as np @@ -155,7 +156,7 @@ def run_renderer( cmd[8] = str(out_fmt) if in_meta_files is not None: - cmd[5:5] = in_meta_files + cmd[5:5] = ["-im", *in_meta_files] if trj_file is not None: cmd.extend(["-tf", str(trj_file)]) @@ -170,6 +171,72 @@ def run_renderer( return pyaudio3dtools.audiofile.readfile(out_file) +def run_td_standalone( + in_fmt: str, + out_fmt: str, + metadata_input: Optional[str] = None, + in_meta_files: Optional[list] = None, + trj_file: Optional[str] = None, +): + """CuT creation with TD Object renderer""" + if trj_file is not None: + trj_name = f"_{trj_file.stem}" + else: + trj_name = "" + + if not isinstance(out_fmt, str): + out_name = f"{out_fmt.stem}" + else: + out_name = out_fmt + + if metadata_input is not None: + in_file = metadata_input + in_name = metadata_input.stem + elif not isinstance(in_fmt, str): + in_file = FORMAT_TO_FILE[in_fmt.stem] + in_name = in_fmt.stem + else: + in_file = FORMAT_TO_FILE[in_fmt] + in_name = in_fmt + + out_file = str(OUTPUT_PATH_CUT.joinpath(f"{in_name}_to_{out_name}{trj_name}.pcm")) + + in_spfmt = pyaudio3dtools.spatialaudioformat.Format(in_fmt) + + with TemporaryDirectory() as tmp_dir: + # write PCM tmp file + tmp_dir = Path(tmp_dir) + in_file_pcm = tmp_dir.joinpath(in_file.stem + ".pcm") + + in_sig, _ = pyaudio3dtools.audiofile.readfile(in_file) + pyaudio3dtools.audiofile.writefile(in_file_pcm, in_sig) + + cmd = TDRENDERER_CMD[:] + cmd[2] = str(in_file_pcm) + cmd[3] = str(out_file) + + if in_spfmt.isloudspeaker: + cmd[1:1] = ["-mc", in_spfmt.name] + else: + cmd[1:1] = str(in_spfmt.nchannels) + if in_meta_files is not None: + cmd[2:2] = in_meta_files + else: + cmd[2:2] = ["NULL"] * in_spfmt.nchannels + + if trj_file is not None: + cmd[1:1] = ["-T", str(trj_file)] + + try: + sp.run(cmd, check=True, capture_output=True, text=True) + except sp.CalledProcessError as e: + pytest.fail( + f"Command returned non-zero exit status ({e.returncode})!\n{' '.join(e.cmd)}\n{e.stderr}\n{e.stdout}\n{e.output}" + ) + + return pyaudio3dtools.audiofile.readfile(out_file, nchannels=2) + + # fixture returns test information, enabling per-testcase SNR @pytest.fixture def test_info(request): @@ -258,21 +325,22 @@ def test_ism(test_info, in_fmt, out_fmt): check_BE(test_info, ref, ref_fs, cut, cut_fs) -@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS) -@pytest.mark.parametrize("in_fmt", INPUT_FORMATS_MASA) -def test_masa(test_info, in_fmt, out_fmt): - # TODO: implement MASA in Python, compare BE - # ref, ref_fs = run_pyscripts( - # in_fmt, out_fmt, in_meta_files=FORMAT_TO_METADATA_FILES[in_fmt] - # ) +# MASA inputs not supported yet +# @pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS) +# @pytest.mark.parametrize("in_fmt", INPUT_FORMATS_MASA) +# def test_masa(test_info, in_fmt, out_fmt): +# # TODO: implement MASA in Python, compare BE +# # ref, ref_fs = run_pyscripts( +# # in_fmt, out_fmt, in_meta_files=FORMAT_TO_METADATA_FILES[in_fmt] +# # ) - cut, cut_fs = run_renderer( - in_fmt, - out_fmt, - in_meta_files=FORMAT_TO_METADATA_FILES[in_fmt], - ) +# cut, cut_fs = run_renderer( +# in_fmt, +# out_fmt, +# in_meta_files=FORMAT_TO_METADATA_FILES[in_fmt], +# ) - # check_BE(test_info, ref, ref_fs, cut, cut_fs) +# # check_BE(test_info, ref, ref_fs, cut, cut_fs) @pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS) @@ -291,15 +359,16 @@ def test_metadata(test_info, in_fmt, out_fmt): check_BE(test_info, ref, ref_fs, cut, cut_fs) -@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS) -@pytest.mark.parametrize("in_fmt", METADATA_SCENES_TO_TEST_NO_BE) -def test_metadata_masa(test_info, in_fmt, out_fmt): - # TODO: unify with test_metadata once Python supports MASA - cut, cut_fs = run_renderer( - "META", - out_fmt, - metadata_input=TEST_VECTOR_DIR.joinpath(f"{in_fmt}.txt"), - ) +# MASA inputs not supported yet +# @pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS) +# @pytest.mark.parametrize("in_fmt", METADATA_SCENES_TO_TEST_NO_BE) +# def test_metadata_masa(test_info, in_fmt, out_fmt): +# # TODO: unify with test_metadata once Python supports MASA +# cut, cut_fs = run_renderer( +# "META", +# out_fmt, +# metadata_input=TEST_VECTOR_DIR.joinpath(f"{in_fmt}.txt"), +# ) # Binaural rendering (static) @@ -323,6 +392,10 @@ def test_ism_binaural_static(test_info, in_fmt, out_fmt): ref, ref_fs = run_pyscripts(in_fmt, out_fmt, in_meta_files=in_meta_files) + # if out_fmt == "BINAURAL": + # cut, cut_fs = run_td_standalone(in_fmt, out_fmt, in_meta_files=in_meta_files) + # else: + # cut, cut_fs = run_renderer(in_fmt, out_fmt, in_meta_files=in_meta_files) cut, cut_fs = run_renderer(in_fmt, out_fmt, in_meta_files=in_meta_files) check_BE(test_info, ref, ref_fs, cut, cut_fs) @@ -374,6 +447,21 @@ def test_ism_binaural_headrotation(test_info, in_fmt, out_fmt, trj_file): in_meta_files=in_meta_files, ) + # if out_fmt == "BINAURAL": + # cut, cut_fs = run_td_standalone( + # in_fmt, + # out_fmt, + # trj_file=HR_TRAJECTORY_DIR.joinpath(f"{trj_file}.csv"), + # in_meta_files=in_meta_files, + # ) + # else: + # cut, cut_fs = run_renderer( + # in_fmt, + # out_fmt, + # trj_file=HR_TRAJECTORY_DIR.joinpath(f"{trj_file}.csv"), + # in_meta_files=in_meta_files, + # ) + cut, cut_fs = run_renderer( in_fmt, out_fmt, @@ -394,6 +482,19 @@ def test_multichannel_binaural_headrotation(test_info, in_fmt, out_fmt, trj_file trj_file=HR_TRAJECTORY_DIR.joinpath(f"{trj_file}.csv"), ) + # if (in_fmt == "5_1" or in_fmt == "7_1") and out_fmt == "BINAURAL": + # cut, cut_fs = run_td_standalone( + # in_fmt, + # out_fmt, + # trj_file=HR_TRAJECTORY_DIR.joinpath(f"{trj_file}.csv"), + # ) + # else: + # cut, cut_fs = run_renderer( + # in_fmt, + # out_fmt, + # trj_file=HR_TRAJECTORY_DIR.joinpath(f"{trj_file}.csv"), + # ) + cut, cut_fs = run_renderer( in_fmt, out_fmt, @@ -403,17 +504,83 @@ def test_multichannel_binaural_headrotation(test_info, in_fmt, out_fmt, trj_file check_BE(test_info, ref, ref_fs, cut, cut_fs) +@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL) +@pytest.mark.parametrize("in_layout", CUSTOM_LS_TO_TEST) +def test_custom_ls_input_binaural(test_info, in_layout, out_fmt): + ref, ref_fs = run_pyscripts( + CUSTOM_LAYOUT_DIR.joinpath(f"{in_layout}.txt"), + out_fmt, + ) + + cut, cut_fs = run_renderer(CUSTOM_LAYOUT_DIR.joinpath(f"{in_layout}.txt"), out_fmt) + + check_BE(test_info, ref, ref_fs, cut, cut_fs) + + +@pytest.mark.parametrize("trj_file", HR_TRAJECTORIES_TO_TEST) +@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL) +@pytest.mark.parametrize("in_layout", CUSTOM_LS_TO_TEST) +def test_custom_ls_input_binaural_headrotation(test_info, in_layout, out_fmt, trj_file): + ref, ref_fs = run_pyscripts( + CUSTOM_LAYOUT_DIR.joinpath(f"{in_layout}.txt"), + out_fmt, + trj_file=HR_TRAJECTORY_DIR.joinpath(f"{trj_file}.csv"), + ) + + cut, cut_fs = run_renderer( + CUSTOM_LAYOUT_DIR.joinpath(f"{in_layout}.txt"), + out_fmt, + trj_file=HR_TRAJECTORY_DIR.joinpath(f"{trj_file}.csv"), + ) + + check_BE(test_info, ref, ref_fs, cut, cut_fs) + + # per-testcase passing SNR pass_snr = { - "test_ambisonics_binaural_headrotation[FOA-BINAURAL_ROOM-full_circle_in_15s-Euler]": 0.6, + "test_ambisonics_binaural_headrotation[FOA-BINAURAL_ROOM-full_circle_in_15s]": 0.6, "test_ambisonics_binaural_headrotation[FOA-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 0.1, - "test_ambisonics_binaural_headrotation[HOA2-BINAURAL_ROOM-full_circle_in_15s-Euler]": 0.4, + "test_ambisonics_binaural_headrotation[HOA2-BINAURAL-full_circle_in_15s]": 18, + "test_ambisonics_binaural_headrotation[HOA2-BINAURAL-rotate_yaw_pitch_roll1]": 4, + "test_ambisonics_binaural_headrotation[HOA2-BINAURAL_ROOM-full_circle_in_15s]": 0.4, "test_ambisonics_binaural_headrotation[HOA2-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 0.04, - "test_ambisonics_binaural_headrotation[HOA3-BINAURAL_ROOM-full_circle_in_15s-Euler]": 0.4, + "test_ambisonics_binaural_headrotation[HOA3-BINAURAL-full_circle_in_15s]": 15, + "test_ambisonics_binaural_headrotation[HOA3-BINAURAL-rotate_yaw_pitch_roll1]": 3, + "test_ambisonics_binaural_headrotation[HOA3-BINAURAL_ROOM-full_circle_in_15s]": 0.4, "test_ambisonics_binaural_headrotation[HOA3-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 0.05, "test_ambisonics_binaural_static[FOA-BINAURAL_ROOM]": 0.6, "test_ambisonics_binaural_static[HOA2-BINAURAL_ROOM]": 0.5, "test_ambisonics_binaural_static[HOA3-BINAURAL_ROOM]": 0.1, + "test_custom_ls_input_binaural[4d4-BINAURAL]": 0.2, + "test_custom_ls_input_binaural[custom1-BINAURAL]": 0.2, + "test_custom_ls_input_binaural[itu_4+5+1-BINAURAL]": 0, + "test_custom_ls_input_binaural[t_design_4-BINAURAL]": 0, + "test_custom_ls_input_binaural_headrotation[4d4-BINAURAL-full_circle_in_15s]": 0.1, + "test_custom_ls_input_binaural_headrotation[t_design_4-BINAURAL-full_circle_in_15s]": 0.1, + "test_custom_ls_input_binaural[16ch_8+4+4-BINAURAL]": 0, + "test_custom_ls_input_binaural_headrotation[itu_4+5+1-BINAURAL-rotate_yaw_pitch_roll1]": 0, + "test_custom_ls_input_binaural_headrotation[custom1-BINAURAL-full_circle_in_15s]": 0.1, + "test_custom_ls_input_binaural_headrotation[custom1-BINAURAL-rotate_yaw_pitch_roll1]": 0, + "test_custom_ls_input_binaural[4d4-BINAURAL_ROOM]": 0, + "test_custom_ls_input_binaural[custom1-BINAURAL_ROOM]": 0, + "test_custom_ls_input_binaural[t_design_4-BINAURAL_ROOM]": 0, + "test_custom_ls_input_binaural[itu_4+5+1-BINAURAL_ROOM]": 3.9, + "test_custom_ls_input_binaural_headrotation[t_design_4-BINAURAL-rotate_yaw_pitch_roll1]": 0, + "test_custom_ls_input_binaural_headrotation[4d4-BINAURAL-rotate_yaw_pitch_roll1]": 0, + "test_custom_ls_input_binaural_headrotation[4d4-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 0, + "test_custom_ls_input_binaural_headrotation[4d4-BINAURAL_ROOM-full_circle_in_15s]": 0, + "test_custom_ls_input_binaural_headrotation[t_design_4-BINAURAL_ROOM-full_circle_in_15s]": 0, + "test_custom_ls_input_binaural_headrotation[16ch_8+4+4-BINAURAL-full_circle_in_15s]": 0, + "test_custom_ls_input_binaural_headrotation[16ch_8+4+4-BINAURAL-rotate_yaw_pitch_roll1]": 1, + "test_custom_ls_input_binaural_headrotation[itu_4+5+1-BINAURAL-full_circle_in_15s]": 0, + "test_custom_ls_input_binaural_headrotation[custom1-BINAURAL_ROOM-full_circle_in_15s]": 0, + "test_custom_ls_input_binaural[16ch_8+4+4-BINAURAL_ROOM]": 0.2, + "test_custom_ls_input_binaural_headrotation[t_design_4-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 0, + "test_custom_ls_input_binaural_headrotation[itu_4+5+1-BINAURAL_ROOM-full_circle_in_15s]": 4, + "test_custom_ls_input_binaural_headrotation[itu_4+5+1-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 4, + "test_custom_ls_input_binaural_headrotation[custom1-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 0, + "test_custom_ls_input_binaural_headrotation[16ch_8+4+4-BINAURAL_ROOM-full_circle_in_15s]": 0, + "test_custom_ls_input_binaural_headrotation[16ch_8+4+4-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 0, "test_ism[ISM1-FOA]": 45, "test_ism[ISM1-HOA2]": 41, "test_ism[ISM1-HOA3]": 38, @@ -426,21 +593,21 @@ pass_snr = { "test_ism[ISM4-FOA]": 45, "test_ism[ISM4-HOA2]": 41, "test_ism[ISM4-HOA3]": 38, - "test_ism_binaural_headrotation[ISM1-BINAURAL-full_circle_in_15s-Euler]": 0, + "test_ism_binaural_headrotation[ISM1-BINAURAL-full_circle_in_15s]": 0, "test_ism_binaural_headrotation[ISM1-BINAURAL-rotate_yaw_pitch_roll1]": 0, - "test_ism_binaural_headrotation[ISM1-BINAURAL_ROOM-full_circle_in_15s-Euler]": 7, + "test_ism_binaural_headrotation[ISM1-BINAURAL_ROOM-full_circle_in_15s]": 6.7, "test_ism_binaural_headrotation[ISM1-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 2, - "test_ism_binaural_headrotation[ISM2-BINAURAL-full_circle_in_15s-Euler]": 0.34, + "test_ism_binaural_headrotation[ISM2-BINAURAL-full_circle_in_15s]": 0.1, "test_ism_binaural_headrotation[ISM2-BINAURAL-rotate_yaw_pitch_roll1]": 0, - "test_ism_binaural_headrotation[ISM2-BINAURAL_ROOM-full_circle_in_15s-Euler]": 4, + "test_ism_binaural_headrotation[ISM2-BINAURAL_ROOM-full_circle_in_15s]": 4, "test_ism_binaural_headrotation[ISM2-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 1, - "test_ism_binaural_headrotation[ISM3-BINAURAL-full_circle_in_15s-Euler]": 0, + "test_ism_binaural_headrotation[ISM3-BINAURAL-full_circle_in_15s]": 0, "test_ism_binaural_headrotation[ISM3-BINAURAL-rotate_yaw_pitch_roll1]": 0, - "test_ism_binaural_headrotation[ISM3-BINAURAL_ROOM-full_circle_in_15s-Euler]": 4, + "test_ism_binaural_headrotation[ISM3-BINAURAL_ROOM-full_circle_in_15s]": 4, "test_ism_binaural_headrotation[ISM3-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 1, - "test_ism_binaural_headrotation[ISM4-BINAURAL-full_circle_in_15s-Euler]": 0, + "test_ism_binaural_headrotation[ISM4-BINAURAL-full_circle_in_15s]": 0, "test_ism_binaural_headrotation[ISM4-BINAURAL-rotate_yaw_pitch_roll1]": 0, - "test_ism_binaural_headrotation[ISM4-BINAURAL_ROOM-full_circle_in_15s-Euler]": 4, + "test_ism_binaural_headrotation[ISM4-BINAURAL_ROOM-full_circle_in_15s]": 3.9, "test_ism_binaural_headrotation[ISM4-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 1, "test_ism_binaural_static[ISM1-BINAURAL]": 0.00, "test_ism_binaural_static[ISM1-BINAURAL_ROOM]": 18, @@ -453,44 +620,34 @@ pass_snr = { "test_metadata[mixed_scene-5_1_4]": 11, "test_metadata[mixed_scene-MONO]": 13, "test_metadata[mixed_scene-STEREO]": 12, - "test_multichannel[5_1-MONO]": 11, - "test_multichannel[5_1-STEREO]": 10, - "test_multichannel[5_1_2-MONO]": 13, - "test_multichannel[5_1_2-STEREO]": 12, - "test_multichannel[5_1_4-MONO]": 14, - "test_multichannel[5_1_4-STEREO]": 13, - "test_multichannel[7_1-MONO]": 13, - "test_multichannel[7_1-STEREO]": 12, - "test_multichannel[7_1_4-MONO]": 13, - "test_multichannel[7_1_4-STEREO]": 12, - "test_multichannel_binaural_headrotation[5_1-BINAURAL-full_circle_in_15s-Euler]": 0, + "test_multichannel_binaural_headrotation[5_1-BINAURAL-full_circle_in_15s]": 0, "test_multichannel_binaural_headrotation[5_1-BINAURAL-rotate_yaw_pitch_roll1]": 0, - "test_multichannel_binaural_headrotation[5_1-BINAURAL_ROOM-full_circle_in_15s-Euler]": 0, + "test_multichannel_binaural_headrotation[5_1-BINAURAL_ROOM-full_circle_in_15s]": 0, "test_multichannel_binaural_headrotation[5_1-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 0, - "test_multichannel_binaural_headrotation[5_1_2-BINAURAL-full_circle_in_15s-Euler]": 4, - "test_multichannel_binaural_headrotation[5_1_2-BINAURAL-rotate_yaw_pitch_roll1]": 6, - "test_multichannel_binaural_headrotation[5_1_2-BINAURAL_ROOM-full_circle_in_15s-Euler]": 0, + "test_multichannel_binaural_headrotation[5_1_2-BINAURAL-full_circle_in_15s]": 3, + "test_multichannel_binaural_headrotation[5_1_2-BINAURAL-rotate_yaw_pitch_roll1]": 0.7, + "test_multichannel_binaural_headrotation[5_1_2-BINAURAL_ROOM-full_circle_in_15s]": 0, "test_multichannel_binaural_headrotation[5_1_2-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 1, - "test_multichannel_binaural_headrotation[5_1_4-BINAURAL-full_circle_in_15s-Euler]": 5, - "test_multichannel_binaural_headrotation[5_1_4-BINAURAL-rotate_yaw_pitch_roll1]": 6, - "test_multichannel_binaural_headrotation[5_1_4-BINAURAL_ROOM-full_circle_in_15s-Euler]": 0, + "test_multichannel_binaural_headrotation[5_1_4-BINAURAL-full_circle_in_15s]": 3.1, + "test_multichannel_binaural_headrotation[5_1_4-BINAURAL-rotate_yaw_pitch_roll1]": 0.7, + "test_multichannel_binaural_headrotation[5_1_4-BINAURAL_ROOM-full_circle_in_15s]": 0, "test_multichannel_binaural_headrotation[5_1_4-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 1, - "test_multichannel_binaural_headrotation[7_1-BINAURAL-full_circle_in_15s-Euler]": 0, + "test_multichannel_binaural_headrotation[7_1-BINAURAL-full_circle_in_15s]": 0, "test_multichannel_binaural_headrotation[7_1-BINAURAL-rotate_yaw_pitch_roll1]": 0, - "test_multichannel_binaural_headrotation[7_1-BINAURAL_ROOM-full_circle_in_15s-Euler]": 0, + "test_multichannel_binaural_headrotation[7_1-BINAURAL_ROOM-full_circle_in_15s]": 0, "test_multichannel_binaural_headrotation[7_1-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 0, - "test_multichannel_binaural_headrotation[7_1_4-BINAURAL-full_circle_in_15s-Euler]": 4, - "test_multichannel_binaural_headrotation[7_1_4-BINAURAL-rotate_yaw_pitch_roll1]": 5, - "test_multichannel_binaural_headrotation[7_1_4-BINAURAL_ROOM-full_circle_in_15s-Euler]": 0, + "test_multichannel_binaural_headrotation[7_1_4-BINAURAL-full_circle_in_15s]": 2, + "test_multichannel_binaural_headrotation[7_1_4-BINAURAL-rotate_yaw_pitch_roll1]": 0.7, + "test_multichannel_binaural_headrotation[7_1_4-BINAURAL_ROOM-full_circle_in_15s]": 0, "test_multichannel_binaural_headrotation[7_1_4-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 1, - "test_multichannel_binaural_static[5_1-BINAURAL]": 8, + "test_multichannel_binaural_static[5_1-BINAURAL]": 6, "test_multichannel_binaural_static[5_1-BINAURAL_ROOM]": 1, - "test_multichannel_binaural_static[5_1_2-BINAURAL]": 9, + "test_multichannel_binaural_static[5_1_2-BINAURAL]": 7.5, "test_multichannel_binaural_static[5_1_2-BINAURAL_ROOM]": 1, - "test_multichannel_binaural_static[5_1_4-BINAURAL]": 10, - "test_multichannel_binaural_static[5_1_4-BINAURAL_ROOM]": 2, - "test_multichannel_binaural_static[7_1-BINAURAL]": 7, + "test_multichannel_binaural_static[5_1_4-BINAURAL]": 7, + "test_multichannel_binaural_static[5_1_4-BINAURAL_ROOM]": 1, + "test_multichannel_binaural_static[7_1-BINAURAL]": 6, "test_multichannel_binaural_static[7_1-BINAURAL_ROOM]": 1, - "test_multichannel_binaural_static[7_1_4-BINAURAL]": 9, + "test_multichannel_binaural_static[7_1_4-BINAURAL]": 7, "test_multichannel_binaural_static[7_1_4-BINAURAL_ROOM]": 1, } -- GitLab From a3713adec6964b20b92e9e6485193495520191d1 Mon Sep 17 00:00:00 2001 From: Archit Tamarapu Date: Wed, 5 Oct 2022 10:11:27 +0200 Subject: [PATCH 022/101] disable FIX_CREND_CHANNELS temporarily - breaks HOA3 rendering --- lib_com/options.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_com/options.h b/lib_com/options.h index f19a2579e6..9fed9bb7d3 100755 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -151,7 +151,7 @@ #define FIX_135_MDCT_STEREO_MODE_UNINITIALIZED /* Issue 135: fix uninitialized value usage in SBA MDCT-Stereo core with PLC */ #define FIX_CONTROLLABLE_SID_UPDATE_RATE /* Issue 117: fix controllable SID update rate mechanism */ #define FIX_DIRAC_CHANNELS /* Issue 71: lower number of DirAC analysis channels */ -#define FIX_CREND_CHANNELS /* Issue 71: fix number of Crend channels */ +// #define FIX_CREND_CHANNELS /* Issue 71: fix number of Crend channels */ #define HARMONIZE_SBA_NCHAN_TRANSPORT /* harmonize setting of number of transport channels in SBA */ #define DRAM_REDUCTION_MCT_IGF /* Issue 121: reduce dynamic RAM consumption in MCT IGF */ -- GitLab From 64ab8c9916ab62b7b29c27ae440fd4b9b9f04e17 Mon Sep 17 00:00:00 2001 From: Archit Tamarapu Date: Wed, 5 Oct 2022 10:25:13 +0200 Subject: [PATCH 023/101] disable FIX_CREND_CHANNELS temporarily - breaks HOA3 rendering --- lib_com/options.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_com/options.h b/lib_com/options.h index e3ead5c21a..fbcdce0c47 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -151,7 +151,7 @@ #define FIX_135_MDCT_STEREO_MODE_UNINITIALIZED /* Issue 135: fix uninitialized value usage in SBA MDCT-Stereo core with PLC */ #define FIX_CONTROLLABLE_SID_UPDATE_RATE /* Issue 117: fix controllable SID update rate mechanism */ #define FIX_DIRAC_CHANNELS /* Issue 71: lower number of DirAC analysis channels */ -#define FIX_CREND_CHANNELS /* Issue 71: fix number of Crend channels */ +// #define FIX_CREND_CHANNELS /* Issue 71: fix number of Crend channels */ #define HARMONIZE_SBA_NCHAN_TRANSPORT /* harmonize setting of number of transport channels in SBA */ #define DRAM_REDUCTION_MCT_IGF /* Issue 121: reduce dynamic RAM consumption in MCT IGF */ -- GitLab From 28019a179d732178d4ff1d6a5280cae68ff6cea6 Mon Sep 17 00:00:00 2001 From: Archit Tamarapu Date: Thu, 6 Oct 2022 12:12:21 +0200 Subject: [PATCH 024/101] fix instrumented build by temporarily wrapping problematic function calls with WMC_TOOL_MAN --- lib_rend/lib_rend.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index 2499b34a39..b31ffafac5 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -3492,10 +3492,12 @@ static ivas_error renderMcCustomLsToBinauralRoom( for ( i = 0; i < mcInput->base.inputBuffer.config.numChannels; i++ ) { +#define WMC_TOOL_MAN renderBufferChannel( ( headRotEnabled ) ? tmpRotBuffer : mcInput->base.inputBuffer, i, mcInput->panGains[i], tmpMcBuffer ); +#undef WMC_TOOL_MAN } copyBufferTo2dArray( tmpMcBuffer, tmpCrendBuffer ); @@ -3770,10 +3772,12 @@ static ivas_error renderSbaToBinauralRoom( for ( i = 0; i < sbaInput->base.inputBuffer.config.numChannels; i++ ) { +#define WMC_TOOL_MAN renderBufferChannel( ( headRotEnabled ) ? tmpRotBuffer : sbaInput->base.inputBuffer, i, sbaInput->hoaDecMtx[i], tmpMcBuffer ); +#undef WMC_TOOL_MAN } copyBufferTo2dArray( tmpMcBuffer, tmpCrendBuffer ); -- GitLab From 911a6908590074bf4dba61f925a5f2cf21ec8209 Mon Sep 17 00:00:00 2001 From: Kacper Sagnowski Date: Thu, 6 Oct 2022 13:34:42 +0200 Subject: [PATCH 025/101] Manually sync files to state on main --- .gitlab-ci-custom.yml | 2 +- .gitlab-ci.yml | 314 +++++++++++++++++++++++++++++------ readme.txt | 2 +- scripts/config/ci_linux.json | 2 +- scripts/config/self_test.prm | 8 + 5 files changed, 273 insertions(+), 55 deletions(-) diff --git a/.gitlab-ci-custom.yml b/.gitlab-ci-custom.yml index d39886c69c..86c1f487e0 100644 --- a/.gitlab-ci-custom.yml +++ b/.gitlab-ci-custom.yml @@ -1,4 +1,4 @@ include: - project: $CUSTOM_CI_PROJECT - ref: external-renderer-ci + ref: $CUSTOM_CI_REF file: $CUSTOM_CI_FILE diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 0c1e02f0ca..21c856850a 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,6 +1,13 @@ variables: TESTV_DIR: "/usr/local/testv" BUILD_OUTPUT: "build_output.txt" + EVS_BE_TEST_DIR: "/usr/local/be_2_evs_test" + SANITIZER_TESTS: "CLANG1 CLANG2" + OUT_FORMATS_CHANNEL_BASED: "stereo mono 5_1 5_1_2 5_1_4 7_1 7_1_4" + OUT_FORMATS_SCENE_BASED: "FOA HOA2 HOA3" + OUT_FORMATS_BINAURAL: "BINAURAL BINAURAL_ROOM" + EXIT_CODE_NON_BE: 123 + EXIT_CODE_FAIL: 1 # This sets when pipelines are created. Jobs have more specific rules to restrict them. @@ -13,7 +20,6 @@ workflow: - if: $CI_PIPELINE_SOURCE == 'push' && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH # Pushes to main - if: $CI_PIPELINE_SOURCE == 'schedule' && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH # Scheduled in main - stages: - maintenance - build @@ -51,6 +57,8 @@ stages: 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 - when: on_success .rules-merge-request: @@ -206,6 +214,12 @@ msan-on-merge-request-linux: - python3 scripts/self_test.py --create | tee test_output.txt - run_errors=$(cat test_output.txt | grep -ic "run errors") || true - if [ $run_errors != 0 ] ; then echo "Run errors in self_test.py with Clang memory-sanitizer"; exit 1; fi + artifacts: + name: "mr-$CI_MERGE_REQUEST_IID--sha-$CI_COMMIT_SHORT_SHA--stage-$CI_JOB_STAGE--results" + paths: + - scripts/ref/logs/ + - test_output.txt + expose_as: 'Msan selftest results' # code selftest testvectors with address-sanitizer binaries @@ -222,6 +236,12 @@ asan-on-merge-request-linux: - python3 scripts/self_test.py --create | tee test_output.txt - run_errors=$(cat test_output.txt | grep -ic "run errors") || true - if [ $run_errors != 0 ] ; then echo "Run errors in self_test.py with Clang address-sanitizer"; exit 1; fi + artifacts: + name: "mr-$CI_MERGE_REQUEST_IID--sha-$CI_COMMIT_SHORT_SHA--stage-$CI_JOB_STAGE--results" + paths: + - scripts/ref/logs/ + - test_output.txt + expose_as: 'Asan selftest results' # test external renderer executable external-renderer-make-pytest: @@ -261,7 +281,7 @@ external-renderer-cmake-msan-pytest: - python3 -m pytest scripts/tests/test_renderer.py -q --log-level ERROR -n auto # compare bit exactness between target and source branch -self-test-on-merge-request: +pytest-on-merge-request: extends: - .test-job-linux - .rules-merge-request @@ -303,40 +323,53 @@ self-test-on-merge-request: - mv IVAS_dec ../IVAS_dec_ref - cd .. - ### re-checkout the commit from the source branch to have up-to-date self_test.py and scripts/testv (and actually everything) + ### re-checkout the commit from the source branch to have up-to-date test scripts and test vectors (and actually everything) - git checkout $source_branch_commit_sha - ### run selftest - - ls -altr scripts/testv - - python3 ./scripts/self_test.py --encref IVAS_cod_ref --decref IVAS_dec_ref --enctest IVAS_cod_test --dectest IVAS_dec_test | tee test_output.txt - - ### analyse test output - # some helper variables - "|| true" to prevent failures from grep not finding anything + - evs_non_be_flag=$(echo $CI_MERGE_REQUEST_TITLE | grep -c --ignore-case "\[evs[ -]*non[ -]*be\]") || true - non_be_flag=$(echo $CI_MERGE_REQUEST_TITLE | grep -c --ignore-case "\[non[ -]*be\]") || true - - run_errors=$(cat test_output.txt | grep -c "test conditions had run errors") || true - - bitexact=$(cat test_output.txt | grep -c "All [0-9]* tests are bitexact") || true - - EXIT_CODE_NON_BE=123 - - EXIT_CODE_FAIL=1 + - expected_nonbe_1=0 + - expected_nonbe_2=0 + - fail_1=0 + - fail_2=0 - - selftest_exit_code=0 + ### prepare pytest + # create short test vectors + - python3 tests/create_short_testvectors.py + # rename test binaries back + - mv IVAS_cod_test IVAS_cod + - mv IVAS_dec_test IVAS_dec + # create references + - python3 -m pytest tests -v --update_ref 1 -m create_ref + - python3 -m pytest tests -v --update_ref 1 -m create_ref_part2 + - python3 -m pytest tests/test_param_file.py -v --update_ref 1 -m create_ref --param_file scripts/config/self_test_evs.prm + + ### run pytest + - exit_code=0 + - python3 -m pytest tests -v --junit-xml=report-junit.xml || exit_code=$? + - zero_errors=$(cat report-junit.xml | grep -c 'errors="0"') || true - # check for crashes during the test, if any happened, fail the test - - if [ $run_errors != 0 ] ; then echo "Run errors in self_test.py"; exit $EXIT_CODE_FAIL; fi + - if [ $zero_errors != 1 ]; then echo "Run errors in pytest"; fail_1=1; fi - # check for non bitexact output and store exit code to also always run the SBA pytest - - if [ $bitexact == 0 ] && [ $non_be_flag == 0 ] ; then echo "Non-bitexact cases without non-BE tag encountered"; selftest_exit_code=$EXIT_CODE_FAIL; fi - - if [ $bitexact == 0 ] && [ $non_be_flag != 0 ]; then echo "Non-bitexact cases with non-BE tag encountered"; selftest_exit_code=$EXIT_CODE_NON_BE; fi + - if [ $exit_code -eq 1 ] && [ $non_be_flag == 0 ]; then echo "pytest run had failures without non-BE tag encountered"; fail_1=1; fi + - if [ $exit_code -eq 1 ] && [ $non_be_flag != 0 ]; then echo "pytest run had failures with non-BE tag encountered"; expected_nonbe_1=1; fi - ### run SBA pytest + ### run pytest for EVS cases - exit_code=0 - - python3 ./scripts/ivas_pytests/self_test_b.py --encref IVAS_cod_ref --decref IVAS_dec_ref --encdut IVAS_cod_test --decdut IVAS_dec_test || exit_code=$? - - if [ $exit_code -eq 1 ] && [ $non_be_flag == 0 ]; then echo "pytest run had failures and non-BE flag not present"; exit $EXIT_CODE_FAIL; fi - - zero_errors=$(cat report-junit.xml | grep -c 'errors="0"') || true - - if [ $exit_code -eq 1 ] && [ $zero_errors == 1 ]; then echo "pytest run had failures, but no errors and non-BE flag present"; exit $EXIT_CODE_NON_BE; fi - - if [ $exit_code -ne 0 ]; then echo "pytest run had errors"; exit $EXIT_CODE_FAIL; fi; - # return exit code from selftest if everything went well with the pytest run - - exit $selftest_exit_code + - python3 -m pytest tests/test_param_file.py -v --param_file scripts/config/self_test_evs.prm --junit-xml=report-junit-evs.xml || exit_code=$? + - zero_errors=$(cat report-junit-evs.xml | grep -c 'errors="0"') || true + + - if [ $zero_errors != 1 ]; then echo "Run errors in pytest for EVS"; fail_2=1; fi + + - if [ $exit_code -eq 1 ] && [ $evs_non_be_flag == 0 ]; then echo "Non-bitexact EVS cases without EVS-non-BE tag encountered"; fail_2=1; fi + - if [ $exit_code -eq 1 ] && [ $evs_non_be_flag != 0 ]; then echo "Non-bitexact EVS cases with EVS-non-BE tag encountered"; expected_nonbe_2=1; fi + + # Check results from both tests + - if [ $fail_1 -eq 1 ] || [ $fail_2 -eq 1 ]; then exit $EXIT_CODE_FAIL; fi + - if [ $expected_nonbe_1 -eq 1 ] || [ $expected_nonbe_2 -eq 1 ]; then exit $EXIT_CODE_NON_BE; fi + - exit 0 + allow_failure: exit_codes: - 123 @@ -344,19 +377,47 @@ self-test-on-merge-request: name: "mr-$CI_MERGE_REQUEST_IID--sha-$CI_COMMIT_SHORT_SHA--stage-$CI_JOB_STAGE--results" when: always paths: - - test_output.txt - - scripts/test/logs/ - - scripts/ref/logs/ - report-junit.xml - expose_as: 'Self test results' + - report-junit-evs.xml + expose_as: 'pytest results' reports: - junit: report-junit.xml + junit: + - report-junit.xml + - report-junit-evs.xml # --------------------------------------------------------------- # Test jobs for main branch # --------------------------------------------------------------- +# check bitexactness to EVS +be-2-evs-linux: + extends: + - .test-job-linux + - .rules-main-push + tags: + - be-2-evs-temp + stage: test + needs: [ "build-codec-linux-cmake" ] + timeout: "20 minutes" # To be revisited + script: + - *print-common-info + + - mkdir build + - cd build + - cmake .. + - make -j + - cd .. + + # copy over to never change the testvector dir + - cp -r $EVS_BE_TEST_DIR ./evs_be_test + - cp build/IVAS_cod ./evs_be_test/bin/EVS_cod + - cp build/IVAS_dec ./evs_be_test/bin/EVS_dec + + - cd evs_be_test + - python3 ../ci/run_evs_be_test.py + + codec-comparison-on-main-push: extends: - .test-job-linux @@ -402,24 +463,23 @@ codec-comparison-on-main-push: # helper variable - "|| true" to prevent failures from grep not finding anything - non_be_flag=$(echo $CI_COMMIT_MESSAGE | grep -c --ignore-case "\[non[ -]*be\]") || true - - selftest_exit_code=0 - - # check for crashes during the test, if any happened, fail the test - - if [ $run_errors != 0 ] ; then echo "Run errors in self_test.py"; exit $EXIT_CODE_FAIL; fi - - # check for non bitexact output and store exit code to also always run the SBA pytest - - if [ $bitexact == 0 ] && [ $non_be_flag == 0 ] ; then echo "Non-bitexact cases without non-BE tag encountered"; selftest_exit_code=$EXIT_CODE_FAIL; fi - - if [ $bitexact == 0 ] && [ $non_be_flag != 0 ]; then echo "Non-bitexact cases with non-BE tag encountered"; selftest_exit_code=$EXIT_CODE_NON_BE; fi - - ### run SBA pytest + ### prepare pytest + # create short test vectors + - python3 tests/create_short_testvectors.py + # rename test binaries back + - mv IVAS_cod_test IVAS_cod + - mv IVAS_dec_test IVAS_dec + # create references + - python3 -m pytest tests -v --update_ref 1 -m create_ref + - python3 -m pytest tests -v --update_ref 1 -m create_ref_part2 + + ### run pytest - exit_code=0 - - python3 ./scripts/ivas_pytests/self_test_b.py --encref IVAS_cod_ref --decref IVAS_dec_ref --encdut IVAS_cod_test --decdut IVAS_dec_test || exit_code=$? + - python3 -m pytest tests -v --junit-xml=report-junit.xml || exit_code=$? - if [ $exit_code -eq 1 ] && [ $non_be_flag == 0 ]; then echo "pytest run had failures and non-BE flag not present"; exit $EXIT_CODE_FAIL; fi - zero_errors=$(cat report-junit.xml | grep -c 'errors="0"') || true - if [ $exit_code -eq 1 ] && [ $zero_errors == 1 ]; then echo "pytest run had failures, but no errors and non-BE flag present"; exit $EXIT_CODE_NON_BE; fi - if [ $exit_code -ne 0 ]; then echo "pytest run had errors"; exit $EXIT_CODE_FAIL; fi; - # return exit code from selftest if everything went well with the pytest run - - exit $selftest_exit_code allow_failure: exit_codes: - 123 @@ -427,21 +487,171 @@ codec-comparison-on-main-push: name: "main-push--sha-$CI_COMMIT_SHORT_SHA--stage-$CI_JOB_STAGE--results" when: always paths: - - test_output.txt - - scripts/test/logs/ - - scripts/ref/logs/ - report-junit.xml expose_as: 'Results of comparison to previous merge commit' reports: junit: report-junit.xml -sanitizer-test-on-main-scheduled: - extends: .test-job-linux-needs-testv-dir +# --------------------------------------------------------------- +# Scheduled jobs on main +# --------------------------------------------------------------- +.sanitizer-test-template: + extends: + - .test-job-linux-needs-testv-dir + stage: test + tags: + - sanitizer_test_main + artifacts: + name: "$CI_JOB_NAME--main--sha-$CI_COMMIT_SHORT_SHA" + when: always + paths: + - ep_015.g192 + +sanitizer-test-mono: + extends: .sanitizer-test-template + rules: + - if: $IS_SANITIZER_TEST_RUN + script: + - python3 ci/run_scheduled_sanitizer_test.py mono mono --tests $SANITIZER_TESTS + +sanitizer-test-stereo: + extends: .sanitizer-test-template + rules: + - if: $IS_SANITIZER_TEST_RUN + when: delayed + start_in: 20 minutes + script: + - python3 ci/run_scheduled_sanitizer_test.py stereo $OUT_FORMATS_CHANNEL_BASED --tests $SANITIZER_TESTS + +sanitizer-test-stereodmxevs: + extends: .sanitizer-test-template + rules: + - if: $IS_SANITIZER_TEST_RUN + when: delayed + start_in: 40 minutes + script: + - python3 ci/run_scheduled_sanitizer_test.py StereoDmxEvs mono --tests $SANITIZER_TESTS + +sanitizer-test-ism1: + extends: .sanitizer-test-template + rules: + - if: $IS_SANITIZER_TEST_RUN + when: delayed + start_in: 1 hour + script: + - python3 ci/run_scheduled_sanitizer_test.py ISM1 $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL EXT --tests $SANITIZER_TESTS + +sanitizer-test-ism2: + extends: .sanitizer-test-template + rules: + - if: $IS_SANITIZER_TEST_RUN + when: delayed + start_in: 1 hour 30 minutes + script: + - python3 ci/run_scheduled_sanitizer_test.py ISM2 $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL EXT --tests $SANITIZER_TESTS + +sanitizer-test-ism3: + extends: .sanitizer-test-template + rules: + - if: $IS_SANITIZER_TEST_RUN + when: delayed + start_in: 2 hours + script: + - python3 ci/run_scheduled_sanitizer_test.py ISM3 $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL EXT --tests $SANITIZER_TESTS + +sanitizer-test-ism4: + extends: .sanitizer-test-template + rules: + - if: $IS_SANITIZER_TEST_RUN + when: delayed + start_in: 2 hours 30 minutes + script: + - python3 ci/run_scheduled_sanitizer_test.py ISM4 $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL EXT --tests $SANITIZER_TESTS + +sanitizer-test-mc-5_1: + extends: .sanitizer-test-template + rules: + - if: $IS_SANITIZER_TEST_RUN + when: delayed + start_in: 3 hours + script: + - python3 ci/run_scheduled_sanitizer_test.py 5_1 $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL --tests $SANITIZER_TESTS + +sanitizer-test-mc-5_1_2: + extends: .sanitizer-test-template + rules: + - if: $IS_SANITIZER_TEST_RUN + when: delayed + start_in: 4 hours + script: + - python3 ci/run_scheduled_sanitizer_test.py 5_1_2 $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL --tests $SANITIZER_TESTS + +sanitizer-test-mc-5_1_4: + extends: .sanitizer-test-template + rules: + - if: $IS_SANITIZER_TEST_RUN + when: delayed + start_in: 5 hours + script: + - python3 ci/run_scheduled_sanitizer_test.py 5_1_4 $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL --tests $SANITIZER_TESTS + +sanitizer-test-mc-7_1: + extends: .sanitizer-test-template + rules: + - if: $IS_SANITIZER_TEST_RUN + when: delayed + start_in: 6 hours + script: + - python3 ci/run_scheduled_sanitizer_test.py 7_1 $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL --tests $SANITIZER_TESTS + +sanitizer-test-mc-7_1_4: + extends: .sanitizer-test-template + rules: + - if: $IS_SANITIZER_TEST_RUN + when: delayed + start_in: 7 hours + script: + - python3 ci/run_scheduled_sanitizer_test.py 7_1_4 $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL --tests $SANITIZER_TESTS + +sanitizer-test-masa: + extends: .sanitizer-test-template + rules: + - if: $IS_SANITIZER_TEST_RUN + when: delayed + start_in: 8 hours + script: + - python3 ci/run_scheduled_sanitizer_test.py MASA $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL EXT --tests $SANITIZER_TESTS + +sanitizer-test-sba: + extends: .sanitizer-test-template + rules: + - if: $IS_SANITIZER_TEST_RUN + when: delayed + start_in: 9 hours + script: + - python3 ci/run_scheduled_sanitizer_test.py SBA $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL --tests $SANITIZER_TESTS + +sanitizer-test-planarsba: + extends: .sanitizer-test-template + rules: + - if: $IS_SANITIZER_TEST_RUN + when: delayed + start_in: 10 hours + script: + - python3 ci/run_scheduled_sanitizer_test.py PlanarSBA $OUT_FORMATS_CHANNEL_BASED $OUT_FORMATS_SCENE_BASED $OUT_FORMATS_BINAURAL --tests $SANITIZER_TESTS + +# GCOV/LCOV coverage analysis of self_test suite +coverage-test-on-main-scheduled: + extends: + - .test-job-linux-needs-testv-dir + - .rules-main-scheduled + tags: + - coverage-test stage: test rules: - # only run in scheduled pipeline that passes this env var - - if: $SANITIZER_TEST_IN_FMT + # only run in scheduled pipeline that passes this env vars + - if: $COVERAGE_TEST script: - *print-common-info - make GCOV=1 -j diff --git a/readme.txt b/readme.txt index 4d4de5864a..86e223b32c 100644 --- a/readme.txt +++ b/readme.txt @@ -195,7 +195,7 @@ EVS mono is default, for IVAS choose one of the following: -stereo, -ism, -sba, where 0 = adaptive, 3-100 = fixed in number of frames, default is deactivated -dtx : Activate DTX mode with a SID update rate of 8 frames - Note: DTX is currently supported in EVS, DFT/TD stereo, 1 ISm, + Note: DTX is currently supported in EVS, stereo, 1 ISm, SBA (up to 128kbps) and MASA (up to 128kbps) -rf p o : Activate channel-aware mode for WB and SWB signal at 13.2kbps, where FEC indicator, p: LO or HI, and FEC offset, o: 2, 3, 5, or 7 in number of frames. diff --git a/scripts/config/ci_linux.json b/scripts/config/ci_linux.json index 23aee75ba7..6279d3f89d 100644 --- a/scripts/config/ci_linux.json +++ b/scripts/config/ci_linux.json @@ -1,6 +1,6 @@ { "afspPath": "not_needed", - "utilPath": "not_needed", + "utilPath": "/tools", "inpaths": { "MONO": "/usr/local/testv/test_mono.wav", "STEREO": "/usr/local/testv/test_stereo.wav", diff --git a/scripts/config/self_test.prm b/scripts/config/self_test.prm index ffafdb3776..721e93a457 100644 --- a/scripts/config/self_test.prm +++ b/scripts/config/self_test.prm @@ -276,6 +276,14 @@ ../IVAS_cod -ism 1 testv/stvISM1.csv 13200 48 testv/stv1ISM48s.pcm bit ../IVAS_dec MONO 48 bit testv/stv1ISM48s.pcm_13200_48-48_MONO.tst +// 1 ISm with metadata at 13.2 kbps, 48 kHz in, 48 kHz out, DTX on, BINAURAL out, random FEC at 5% +../IVAS_cod -dtx -ism 1 testv/stvISM1.csv 13200 48 testv/stv48n.pcm bit +../IVAS_dec -fec 5 BINAURAL 48 bit testv/stv48n.pcm_13200_48-48_DTX_FEC5_BINAURAL.tst + +// 1 ISm with metadata at 32 kbps, 32 kHz in, 32 kHz out, DTX on, MONO out +../IVAS_cod -dtx -ism 1 testv/stvISM1.csv 32000 32 testv/stv32n.pcm bit +../IVAS_dec MONO 32 bit testv/stv32n.pcm_32000_32-32_DTX_MONO.tst + // 2 ISm with metadata at 16.4 kbps, 48 kHz in, 48 kHz out, STEREO out ../IVAS_cod -ism 2 testv/stvISM1.csv testv/stvISM2.csv 16400 48 testv/stv2ISM48s.pcm bit ../IVAS_dec STEREO 48 bit testv/stv2ISM48s.pcm_16400_48-48_STEREO.tst -- GitLab From 0fdc666dd57aa99e50a50a066559237a824b3cfc Mon Sep 17 00:00:00 2001 From: Kacper Sagnowski Date: Thu, 6 Oct 2022 13:35:37 +0200 Subject: [PATCH 026/101] Fix non-text differences w.r.t. main --- apps/encoder.c | 0 ci/run_scheduled_sanitizer_test.py | 0 lib_com/bitstream.c | 0 lib_com/ivas_entropy_coder_common.c | 0 lib_com/ivas_mdft_imdft.c | 0 lib_com/ivas_spar_com.c | 0 lib_com/prot.h | 0 lib_debug/sba_debug.c | 0 lib_dec/acelp_core_dec.c | 0 lib_dec/evs_dec.c | 0 lib_dec/ivas_core_dec.c | 0 lib_dec/ivas_dirac_dec.c | 0 lib_dec/ivas_init_dec.c | 0 lib_dec/ivas_spar_decoder.c | 0 lib_dec/ivas_stereo_switching_dec.c | 0 lib_dec/lib_dec.c | 0 lib_dec/swb_tbe_dec.c | 0 lib_enc/igf_enc.c | 0 lib_enc/ivas_enc.c | 0 lib_enc/ivas_mct_core_enc.c | 0 lib_enc/ivas_mct_enc_mct.c | 0 lib_enc/ivas_stereo_dft_enc_itd.c | 0 lib_enc/tcx_utils_enc.c | 0 scripts/pyaudio3dtools/audiofile.py | 0 24 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 apps/encoder.c mode change 100755 => 100644 ci/run_scheduled_sanitizer_test.py mode change 100755 => 100644 lib_com/bitstream.c mode change 100755 => 100644 lib_com/ivas_entropy_coder_common.c mode change 100755 => 100644 lib_com/ivas_mdft_imdft.c mode change 100755 => 100644 lib_com/ivas_spar_com.c mode change 100644 => 100755 lib_com/prot.h mode change 100755 => 100644 lib_debug/sba_debug.c mode change 100755 => 100644 lib_dec/acelp_core_dec.c mode change 100755 => 100644 lib_dec/evs_dec.c mode change 100755 => 100644 lib_dec/ivas_core_dec.c mode change 100755 => 100644 lib_dec/ivas_dirac_dec.c mode change 100755 => 100644 lib_dec/ivas_init_dec.c mode change 100755 => 100644 lib_dec/ivas_spar_decoder.c mode change 100755 => 100644 lib_dec/ivas_stereo_switching_dec.c mode change 100755 => 100644 lib_dec/lib_dec.c mode change 100755 => 100644 lib_dec/swb_tbe_dec.c mode change 100644 => 100755 lib_enc/igf_enc.c mode change 100755 => 100644 lib_enc/ivas_enc.c mode change 100755 => 100644 lib_enc/ivas_mct_core_enc.c mode change 100644 => 100755 lib_enc/ivas_mct_enc_mct.c mode change 100755 => 100644 lib_enc/ivas_stereo_dft_enc_itd.c mode change 100644 => 100755 lib_enc/tcx_utils_enc.c mode change 100644 => 100755 scripts/pyaudio3dtools/audiofile.py diff --git a/apps/encoder.c b/apps/encoder.c old mode 100755 new mode 100644 diff --git a/ci/run_scheduled_sanitizer_test.py b/ci/run_scheduled_sanitizer_test.py old mode 100755 new mode 100644 diff --git a/lib_com/bitstream.c b/lib_com/bitstream.c old mode 100755 new mode 100644 diff --git a/lib_com/ivas_entropy_coder_common.c b/lib_com/ivas_entropy_coder_common.c old mode 100755 new mode 100644 diff --git a/lib_com/ivas_mdft_imdft.c b/lib_com/ivas_mdft_imdft.c old mode 100755 new mode 100644 diff --git a/lib_com/ivas_spar_com.c b/lib_com/ivas_spar_com.c old mode 100755 new mode 100644 diff --git a/lib_com/prot.h b/lib_com/prot.h old mode 100644 new mode 100755 diff --git a/lib_debug/sba_debug.c b/lib_debug/sba_debug.c old mode 100755 new mode 100644 diff --git a/lib_dec/acelp_core_dec.c b/lib_dec/acelp_core_dec.c old mode 100755 new mode 100644 diff --git a/lib_dec/evs_dec.c b/lib_dec/evs_dec.c old mode 100755 new mode 100644 diff --git a/lib_dec/ivas_core_dec.c b/lib_dec/ivas_core_dec.c old mode 100755 new mode 100644 diff --git a/lib_dec/ivas_dirac_dec.c b/lib_dec/ivas_dirac_dec.c old mode 100755 new mode 100644 diff --git a/lib_dec/ivas_init_dec.c b/lib_dec/ivas_init_dec.c old mode 100755 new mode 100644 diff --git a/lib_dec/ivas_spar_decoder.c b/lib_dec/ivas_spar_decoder.c old mode 100755 new mode 100644 diff --git a/lib_dec/ivas_stereo_switching_dec.c b/lib_dec/ivas_stereo_switching_dec.c old mode 100755 new mode 100644 diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c old mode 100755 new mode 100644 diff --git a/lib_dec/swb_tbe_dec.c b/lib_dec/swb_tbe_dec.c old mode 100755 new mode 100644 diff --git a/lib_enc/igf_enc.c b/lib_enc/igf_enc.c old mode 100644 new mode 100755 diff --git a/lib_enc/ivas_enc.c b/lib_enc/ivas_enc.c old mode 100755 new mode 100644 diff --git a/lib_enc/ivas_mct_core_enc.c b/lib_enc/ivas_mct_core_enc.c old mode 100755 new mode 100644 diff --git a/lib_enc/ivas_mct_enc_mct.c b/lib_enc/ivas_mct_enc_mct.c old mode 100644 new mode 100755 diff --git a/lib_enc/ivas_stereo_dft_enc_itd.c b/lib_enc/ivas_stereo_dft_enc_itd.c old mode 100755 new mode 100644 diff --git a/lib_enc/tcx_utils_enc.c b/lib_enc/tcx_utils_enc.c old mode 100644 new mode 100755 diff --git a/scripts/pyaudio3dtools/audiofile.py b/scripts/pyaudio3dtools/audiofile.py old mode 100644 new mode 100755 -- GitLab From d08164cb81d4f029c77c32baced7ab7007307980 Mon Sep 17 00:00:00 2001 From: Archit Tamarapu Date: Thu, 6 Oct 2022 13:56:19 +0200 Subject: [PATCH 027/101] re-enable FIX_CREND_CHANNELS now that a fix was applied --- lib_com/options.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_com/options.h b/lib_com/options.h index 50c5117ce2..b6f4b44ea2 100755 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -151,7 +151,7 @@ #define FIX_135_MDCT_STEREO_MODE_UNINITIALIZED /* Issue 135: fix uninitialized value usage in SBA MDCT-Stereo core with PLC */ #define FIX_CONTROLLABLE_SID_UPDATE_RATE /* Issue 117: fix controllable SID update rate mechanism */ #define FIX_DIRAC_CHANNELS /* Issue 71: lower number of DirAC analysis channels */ -// #define FIX_CREND_CHANNELS /* Issue 71: fix number of Crend channels */ +#define FIX_CREND_CHANNELS /* Issue 71: fix number of Crend channels */ #define HARMONIZE_SBA_NCHAN_TRANSPORT /* harmonize setting of number of transport channels in SBA */ #define DRAM_REDUCTION_MCT_IGF /* Issue 121: reduce dynamic RAM consumption in MCT IGF */ #define FIX_I13_TCX_TNS_ISSUE /* Issue 13: Fix reported artifacts. Bug in TNS with TCX5 */ -- GitLab From eed8fa6b0f43e47e62df727763839ee4c0488317 Mon Sep 17 00:00:00 2001 From: Kacper Sagnowski Date: Thu, 6 Oct 2022 14:19:18 +0200 Subject: [PATCH 028/101] Another round of manual sync from main --- .gitignore | 4 +- pytest.ini | 9 +- scripts/IvasBuildAndRunChecks.py | 25 +- scripts/ivas_pytests/self_test_b.py | 273 ----------- scripts/ivas_pytests/tests/il2mm.py | 61 --- scripts/ivas_pytests/tests/requirements.txt | 4 - .../system_tests/test_spar_foa_bs_dec_plc.py | 180 ------- .../unit_tests/crend/ivas_crend_io_parse.h | 4 +- .../crend/ivas_crend_unit_test.vcxproj | 5 +- .../unit_tests/crend/ivas_dec_parse_io.h | 30 +- scripts/pyivastest/IvasModeRunner.py | 2 +- scripts/self_test.py | 20 +- scripts/tools/Darwin/networkSimulator_g192 | Bin 0 -> 154584 bytes scripts/tools/Win32/networkSimulator_g192.exe | 3 + tests/README.md | 173 +++++++ .../tests => tests}/cmp_custom.py | 92 ++-- {scripts/ivas_pytests => tests}/conftest.py | 231 ++++++--- tests/create_short_testvectors.py | 66 +++ .../ivas_pytests/tests => tests}/cut_pcm.py | 6 +- tests/requirements.txt | 4 + tests/run_pytests.py | 106 ++++ tests/test_param_file.py | 460 ++++++++++++++++++ tests/test_sba_bs_dec_plc.py | 189 +++++++ .../test_sba_bs_enc.py | 214 ++++---- tests/testconfig.py | 37 ++ 25 files changed, 1404 insertions(+), 794 deletions(-) delete mode 100755 scripts/ivas_pytests/self_test_b.py delete mode 100644 scripts/ivas_pytests/tests/il2mm.py delete mode 100644 scripts/ivas_pytests/tests/requirements.txt delete mode 100644 scripts/ivas_pytests/tests/system_tests/test_spar_foa_bs_dec_plc.py mode change 100644 => 100755 scripts/pyivastest/IvasModeRunner.py create mode 100755 scripts/tools/Darwin/networkSimulator_g192 create mode 100755 scripts/tools/Win32/networkSimulator_g192.exe create mode 100644 tests/README.md rename {scripts/ivas_pytests/tests => tests}/cmp_custom.py (62%) mode change 100644 => 100755 rename {scripts/ivas_pytests => tests}/conftest.py (57%) create mode 100755 tests/create_short_testvectors.py rename {scripts/ivas_pytests/tests => tests}/cut_pcm.py (99%) create mode 100644 tests/requirements.txt create mode 100755 tests/run_pytests.py create mode 100644 tests/test_param_file.py create mode 100644 tests/test_sba_bs_dec_plc.py rename scripts/ivas_pytests/tests/system_tests/test_spar_foa_bs_enc.py => tests/test_sba_bs_enc.py (71%) create mode 100644 tests/testconfig.py diff --git a/.gitignore b/.gitignore index e719f5b008..1ec17a4b20 100644 --- a/.gitignore +++ b/.gitignore @@ -43,6 +43,7 @@ scripts/c-code_instrument/ scripts/ifdef_instrument.list scripts/ref/ scripts/test/ +scripts/out/ scripts/self_test_summary.txt scripts/tests/cut/ scripts/tests/ref/ @@ -53,6 +54,3 @@ tests/ref __pycache__/ *.py[cod] *$py.class - -# clangd -.cache/ diff --git a/pytest.ini b/pytest.ini index 9d9a3bbf8e..4e8666cb52 100644 --- a/pytest.ini +++ b/pytest.ini @@ -1,8 +1,13 @@ # pytest.ini # note: per convention, this file is placed in the root directory of the repository [pytest] -addopts = -ra --tb=short --basetemp=./tmp -v -junit_family=xunit1 +addopts = -ra --tb=short --basetemp=./tmp -n auto -v +# Write captured system-out log messages to JUnit report. +junit_logging = system-out +# Do not capture log information for passing tests to JUnit report. +junit_log_passing_tests = False +junit_duration_report = call +junit_family = xunit1 log_file_level = DEBUG log_format = %(asctime)s %(levelname)s %(message)s log_date_format = %Y-%m-%d %H:%M:%S diff --git a/scripts/IvasBuildAndRunChecks.py b/scripts/IvasBuildAndRunChecks.py index fe1953a603..1cf4a868db 100755 --- a/scripts/IvasBuildAndRunChecks.py +++ b/scripts/IvasBuildAndRunChecks.py @@ -36,7 +36,9 @@ import sys from pyivastest.IvasSvnBuilder import * from pyivastest import IvasScriptsCommon import pyivastest.constants as constants -from pyivastest import ivas_svn + + +RET_CODE_FAILURE = 101 class IvasBuildAndRunChecks(IvasScriptsCommon.IvasScript): @@ -169,14 +171,10 @@ class IvasBuildAndRunChecks(IvasScriptsCommon.IvasScript): for check in checks: br.run(check) if self.args["create_html_output"]: - revision = ivas_svn.get_local_svn_info(self.args["srcdir"], self.logger) - if revision is None: - print("Could not get revision from local copy") - revision = -1 - else: - revision = revision["commit_revision"] + cmd = ["git", "rev-parse", "HEAD"] + commit_hash = subprocess.run(cmd, capture_output=True).stdout.decode("utf8") br.build_and_run_dict[check]["analyzer"].write_html_file( - check, self.args["create_html_output"], revision + check, self.args["create_html_output"], commit_hash ) for r in br.build_and_run_dict[check]["runner"].results: self.logger.console(r[0]) @@ -195,7 +193,16 @@ class IvasBuildAndRunChecks(IvasScriptsCommon.IvasScript): self.args["create_complexity_tables"] ) + for check in checks: + runner = br.build_and_run_dict[check]["runner"] + failed_encs = runner.failed_modes["enc"] + failed_decs = runner.failed_modes["dec"] + if len(failed_encs) > 0 or len(failed_decs) > 0: + return RET_CODE_FAILURE + else: + return 0 + if __name__ == "__main__": script = IvasBuildAndRunChecks() - script.run() + sys.exit(script.run()) diff --git a/scripts/ivas_pytests/self_test_b.py b/scripts/ivas_pytests/self_test_b.py deleted file mode 100755 index 941739435e..0000000000 --- a/scripts/ivas_pytests/self_test_b.py +++ /dev/null @@ -1,273 +0,0 @@ -#!/usr/bin/env python3 - -""" - (C) 2022 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. -""" - -""" -Script to run the pytest tests. - -Step 1: Set the stage for the pytest run. - -Step 2: Run pytest. -""" - -import os -import sys -import argparse -import subprocess -import platform -from pathlib import Path - -sys.path.append('scripts/ivas_pytests/tests/') -from cut_pcm import cut_samples - -BIN_EXT = ".exe" if platform.system() == "Windows" else "" -HERE = Path(__file__).parent.resolve() -DEFAULT_ENCODER_DUT = str(HERE.joinpath(f"../../IVAS_cod{BIN_EXT}").resolve()) -DEFAULT_DECODER_DUT = str(HERE.joinpath(f"../../IVAS_dec{BIN_EXT}").resolve()) -DEFAULT_ENCODER_REF = str(HERE.joinpath(f"../../IVAS_cod_ref{BIN_EXT}").resolve()) -DEFAULT_DECODER_REF = str(HERE.joinpath(f"../../IVAS_dec_ref{BIN_EXT}").resolve()) -CREND_UNITTEST_REF = str(HERE.joinpath(f"tests/unit_tests/crend/IVAS_crend_unit_test_ref{BIN_EXT}").resolve()) -TEST_VECTOR_DIR = str(HERE.joinpath("../testv").resolve()) -REFERENCE_DIR = str(HERE.joinpath("ref").resolve()) -DUT_BASE_DIR = str(HERE.joinpath("dut").resolve()) - - -def build_enc_and_dec(src_dir): - """ - Build the encoder and decoder binaries. - """ - if platform.system() == "Windows": - olddir = os.getcwd() - os.chdir(src_dir) - os.chdir("Workspace_msvc") - command = ["MSBuild.exe", "Workspace_msvc.sln", "/t:Clean", "/p:configuration=Release", "/p:Platform=Win32"] - subprocess.run(command, check=True) - command = ["MSBuild.exe", "Workspace_msvc.sln", "/property:configuration=Release", "/p:Platform=Win32"] - subprocess.run(command, check=True) - os.chdir(olddir) - else: - command = ["make", "-C", src_dir, "clean"] - subprocess.run(command, check=True) - command = ["make", "-C", src_dir] - subprocess.run(command, check=True) - - -def build_crend_unittest(src_dir): - """ - Build the crend unit test binary. - """ - crend_dir = f"{src_dir}/scripts/ivas_pytests/tests/unit_tests/crend" - if platform.system() == "Windows": - olddir = os.getcwd() - os.chdir(crend_dir) - # command = ["MSBuild.exe", "ivas_crend_unit_test.sln", "/t:Clean", "/p:configuration=Release", "/p:Platform=Win32"] - # subprocess.run(command, check=True) - command = ["MSBuild.exe", "ivas_crend_unit_test.sln", "/property:configuration=Release", "/p:Platform=Win32"] - subprocess.run(command, check=True) - os.chdir(olddir) - else: - # command = ["make", "-C", src_dir, "clean"] - # subprocess.run(command, check=True) - command = ["make", "-C", src_dir, "IVAS_crend_unit_test"] - subprocess.run(command, check=True) - - -def build_dut_binaries(): - """ - Build the DUT binaries. - """ - print("Building the DUT binaries") - dut_src_dir = str(HERE.joinpath("../..").resolve()) - build_enc_and_dec(dut_src_dir) - build_crend_unittest(dut_src_dir) - - -def create_short_testvectors(): - """ - Create short (5sec) testvectors. - """ - print("Creating short (5sec) testvectors") - num_channels = "4" # currently only FOA - cut_from = "0.0" - cut_len = "5.0" - for fs in ['48', '32', '16']: - in_file = f"{TEST_VECTOR_DIR}/stvFOA{fs}c.pcm" - cut_gain = "1.0" - cut_file = f"{TEST_VECTOR_DIR}/stvFOA{fs}c_cut.pcm" - cut_samples(in_file, cut_file, num_channels, fs + "000", cut_from, cut_len, cut_gain) - cut_gain = "16.0" - cut_file = f"{TEST_VECTOR_DIR}/stvFOA{fs}c_cut_{cut_gain}.pcm" - cut_samples(in_file, cut_file, num_channels, fs + "000", cut_from, cut_len, cut_gain) - - -def main(argv): - # check for python >= 3.7 - if sys.version_info[0] < 3 or sys.version_info[1] < 7: - sys.exit("This script is written for Python >= 3.7. Found: " + platform.python_version()) - - parser = argparse.ArgumentParser(formatter_class=argparse.RawTextHelpFormatter) - parser.add_argument( - "--create_only", - action="store_true", - default=False, - help="Create references when needed, but don't run the tests" - ) - parser.add_argument( - "--numprocesses", - action="store", - default="auto", - help="Number of processes to use in pytest (default: auto)", - ) - parser.add_argument("--encref", help=f"REF encoder binary (default:{DEFAULT_ENCODER_REF})") - parser.add_argument("--decref", help=f"REF decoder binary (default:{DEFAULT_DECODER_REF})") - parser.add_argument("--encdut", help=f"DUT encoder binary (default:{DEFAULT_ENCODER_DUT})") - parser.add_argument("--decdut", help=f"DUT decoder binary (default:{DEFAULT_DECODER_DUT})") - - args = parser.parse_args(argv[1:]) - - # check for DUT binaries - if args.encdut: - encdut_path = os.path.realpath(args.encdut) - if not os.path.exists(encdut_path): - sys.exit(f"DUT encoder binary {encdut_path} does not exist.") - else: - encdut_path = DEFAULT_ENCODER_DUT - if args.decdut: - decdut_path = os.path.realpath(args.decdut) - if not os.path.exists(decdut_path): - sys.exit(f"DUT encoder binary {decdut_path} does not exist.") - else: - decdut_path = DEFAULT_DECODER_DUT - if not os.path.exists(encdut_path) or not os.path.exists(decdut_path): - build_dut_binaries() - - if not os.path.exists(REFERENCE_DIR): - # check for REF binaries - if args.encref: - encref_path = os.path.realpath(args.encref) - if not os.path.exists(encref_path): - sys.exit(f"REF encoder binary {encref_path} does not exist.") - else: - encref_path = DEFAULT_ENCODER_REF - if args.decref: - decref_path = os.path.realpath(args.decref) - if not os.path.exists(decref_path): - sys.exit(f"REF encoder binary {decref_path} does not exist.") - else: - decref_path = DEFAULT_DECODER_REF - if not os.path.exists(encref_path) or not os.path.exists(decref_path): - sys.exit("Reference binaries do not exist.") - - # check for test vectors - if not os.path.exists(TEST_VECTOR_DIR): - sys.exit(f"Test vector directory {TEST_VECTOR_DIR} does not exist.") - - # check for references - if os.path.exists(REFERENCE_DIR): - print(f"Using existing references directory {REFERENCE_DIR}") - else: - # create references - print(f"Creating references within the references directory {REFERENCE_DIR}") - create_short_testvectors() - if platform.system() == "Windows": - base_cmd = ["pytest"] - else: - base_cmd = ["python3", "-m", "pytest"] - base_cmd += [ - "scripts/ivas_pytests/tests", - "-n", - args.numprocesses, - "--update_ref", - "1", - "-v", - "--data_system_tests_path", - TEST_VECTOR_DIR, - "--reference_path", - REFERENCE_DIR, - "--dut_base_path", - DUT_BASE_DIR, - "--ref_encoder_path", - encref_path, - "--ref_decoder_path", - decref_path, - "--dut_encoder_path", - encdut_path, - "--dut_decoder_path", - decdut_path, - ] - # work-around in unit tests via environment variable - # TESTVECTOR_PATH_REL_GROUPB: to specify the test vector directory relative to ivas_pytests folder - # TESTVECTOR_PATH_REL_TRUNK: to specify the test vector directory relative to trunk - my_env = os.environ.copy() - my_env["TESTVECTOR_PATH_REL_GROUPB"] = "testv/" - my_env["TESTVECTOR_PATH_REL_TRUNK"] = "/scripts/ivas_pytests/testv/" # leading "/" is important - my_env["CREND_UNIT_TEST_BIN"] = CREND_UNITTEST_REF - print("pytest command line to be executed from project root folder:") - print(" ".join(base_cmd + ["-m", "create_ref"])) - subprocess.run(base_cmd + ["-m", "create_ref"], check=False, env=my_env) - print("pytest command line to be executed from project root folder:") - print(" ".join(base_cmd + ["-m", "create_ref_part2"])) - subprocess.run(base_cmd + ["-m", "create_ref_part2"], check=False, env=my_env) - - if args.create_only: - return - - # run pytest - if platform.system() == "Windows": - cmd = ["pytest"] - else: - cmd = ["python3", "-m", "pytest"] - cmd += [ - "scripts/ivas_pytests/tests", - "-n", - args.numprocesses, - "-v", - "--data_system_tests_path", - TEST_VECTOR_DIR, - "--reference_path", - REFERENCE_DIR, - "--dut_base_path", - DUT_BASE_DIR, - "--dut_encoder_path", - encdut_path, - "--dut_decoder_path", - decdut_path, - "--junit-xml=report-junit.xml", - ] - # print pytest commandline - print("pytest command line to be executed from project root folder:") - print(" ".join(cmd)) - result = subprocess.run(cmd, check=False) - return result.returncode - - -if __name__ == "__main__": - sys.exit(main(sys.argv)) diff --git a/scripts/ivas_pytests/tests/il2mm.py b/scripts/ivas_pytests/tests/il2mm.py deleted file mode 100644 index eb09593bdb..0000000000 --- a/scripts/ivas_pytests/tests/il2mm.py +++ /dev/null @@ -1,61 +0,0 @@ -""" - (C) 2022 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. -""" - -import os - - -def il2mm(file_in, num_ch, b_delete=True): - """ - Convert interleaved input file to multiple mono output files. - """ - num_bytes_per_sample = 2 - num_bytes_per_frame = num_bytes_per_sample * num_ch - num_bytes_per_channel = os.path.getsize(file_in) / num_ch - - with open(file_in, "rb") as fid_in: - out_path = os.path.splitext(file_in)[0] - for chan in range(num_ch): - file_out = out_path + str(chan + 1) + "ch.raw" - with open(file_out, "wb") as fid_out: - bytes_written = 0 - offset = chan * num_bytes_per_sample - fid_in.seek(offset, 0) - while bytes_written < num_bytes_per_channel: - data = fid_in.read(num_bytes_per_sample) - fid_in.seek(num_bytes_per_frame - num_bytes_per_sample, 1) - written = fid_out.write(bytes(data)) - assert ( - written == num_bytes_per_sample - ), f"Error writing data: {written} != {num_bytes_per_sample}" - bytes_written += num_bytes_per_sample - - # delete interleaved input file - if b_delete: - os.remove(file_in) diff --git a/scripts/ivas_pytests/tests/requirements.txt b/scripts/ivas_pytests/tests/requirements.txt deleted file mode 100644 index 764694dfc0..0000000000 --- a/scripts/ivas_pytests/tests/requirements.txt +++ /dev/null @@ -1,4 +0,0 @@ -pytest==5.3.5 -pytest-xdist==1.31.0 -scipy==1.5.2 -numpy==1.19.2 diff --git a/scripts/ivas_pytests/tests/system_tests/test_spar_foa_bs_dec_plc.py b/scripts/ivas_pytests/tests/system_tests/test_spar_foa_bs_dec_plc.py deleted file mode 100644 index fa17fd1d80..0000000000 --- a/scripts/ivas_pytests/tests/system_tests/test_spar_foa_bs_dec_plc.py +++ /dev/null @@ -1,180 +0,0 @@ -""" - (C) 2022 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. -""" - -import os -import pytest -import shutil -import errno -import sys - -sys.path.append('scripts/ivas_pytests/') -sys.path.append('scripts/ivas_pytests/tests/') -from il2mm import il2mm -from cmp_custom import cmp_custom -from conftest import EncoderFrontend, DecoderFrontend - -#params -tag_list = ['stvFOA'] -plc_patterns = ['PLperc12mblen5', 'PLperc40mblen50', 'PLperc42mblen2'] -dtx_set = ['0', '1'] -ivas_br_list = ['32000', '64000', '96000', '256000'] -sampling_rate_list = ['48', '32', '16'] -agc_list = [0, 1] - -ch_count_foa = 4 -AbsTol = '3' - - -def check_and_makedir(dir_path): - if not os.path.exists(dir_path): - try: - os.makedirs(dir_path) - except OSError as e: - if e.errno != errno.EEXIST: - raise # raises the error again - - -# assumption: -# - the needed reference bitstreams are created by test_spar_foa_enc_system -# -> reference bitstreams are not any longer created as part of this test -# -> the parameters of this test (except additional parameter plc_pattern) need to be a subset of the parameters in test_spar_foa_enc_system -# -> the reference generation for this test (reference decoder output) needs to be done after completion of test_spar_foa_enc_system -# -> therefore the marker create_ref_part2 -@pytest.mark.create_ref_part2 -@pytest.mark.parametrize("ivas_br", ivas_br_list) -@pytest.mark.parametrize("dtx", dtx_set) -@pytest.mark.parametrize("tag", tag_list) -@pytest.mark.parametrize("plc_pattern", plc_patterns) -@pytest.mark.parametrize("fs", sampling_rate_list) -@pytest.mark.parametrize("agc", agc_list) -def test_spar_foa_plc_system( - dut_decoder_frontend: DecoderFrontend, - data_system_tests_path, - reference_path, - dut_base_path, - ref_decoder_path, - update_ref, - ivas_br, - dtx, - tag, - plc_pattern, - fs, - agc -): - tag = tag + fs + 'c' - - #dec - spar_foa_dec_plc(dut_decoder_frontend, data_system_tests_path, reference_path, dut_base_path, ref_decoder_path, tag, ch_count_foa, fs, ivas_br, dtx, plc_pattern, update_ref, agc) - - -######################################################### -############ test function ############################## -def spar_foa_dec_plc( - decoder_frontend, - test_vector_path, - reference_path, - dut_base_path, - ref_decoder_path, - tag, - ch_count, - sampling_rate, - ivas_br, - dtx, - plc_pattern, - update_ref, - agc -): - - ######### run cmd ##################################### - - tag_out = f"{tag}_ivasbr{ivas_br[:-3]}k_DTX{dtx}" - if agc == 1: - tag_out += '_AGC1' - plc_tag_out = f"{tag_out}_{plc_pattern}" - - dut_out_dir = f"{dut_base_path}/spar_foa_bs/raw/{plc_tag_out}" - ref_out_dir = f"{reference_path}/spar_foa_bs/raw/{plc_tag_out}" - - check_and_makedir(dut_out_dir) - check_and_makedir(ref_out_dir) - - plc_file = f"{test_vector_path}/{plc_pattern}.g192" - ref_in_pkt = f"{reference_path}/spar_foa_bs/pkt/{tag_out}.pkt" - ref_in_pkt_dutenc = f"{reference_path}/spar_foa_bs/pkt/{tag_out}_dutenc.pkt" - - if ref_decoder_path: - ref_decoder = DecoderFrontend(ref_decoder_path, "REF") - - # call REF decoder - ref_decoder.run( - "FOA", - sampling_rate, - ref_in_pkt, - f"{ref_out_dir}/out.raw", - plc_file=plc_file, - ) - - # convert REF interleaved to multi-mono - il2mm(f"{ref_out_dir}/out.raw", ch_count) - - if update_ref == 0: - # call DUT decoder - decoder_frontend.run( - "FOA", - sampling_rate, - ref_in_pkt_dutenc, - f"{dut_out_dir}/out.raw", - plc_file=plc_file, - ) - - il2mm(f"{dut_out_dir}/out.raw", ch_count) - - ######### compare cmd ##################################### - - end_skip_samples = '0' - - test_fail = False - for count in range(ch_count): - ch_id = str(count + 1) - - if cmp_custom( - f"{dut_out_dir}/out{ch_id}ch.raw", - f"{ref_out_dir}/out{ch_id}ch.raw", - "2", - AbsTol, - end_skip_samples - ) != 0: - test_fail = True - - ##File removal## - shutil.rmtree(dut_out_dir, ignore_errors=True) - - ##report failure - assert not test_fail diff --git a/scripts/ivas_pytests/tests/unit_tests/crend/ivas_crend_io_parse.h b/scripts/ivas_pytests/tests/unit_tests/crend/ivas_crend_io_parse.h index 21b59ad06f..abc8b1e463 100644 --- a/scripts/ivas_pytests/tests/unit_tests/crend/ivas_crend_io_parse.h +++ b/scripts/ivas_pytests/tests/unit_tests/crend/ivas_crend_io_parse.h @@ -49,6 +49,8 @@ #define IVAS_IN_FMT_714 "714" #define IVAS_IN_FMT_FOA "HOA1S" +#define IVAS_MAX_NUM_CH 16 + #define IVAS_MAX_PATH_LEN ( 2000 ) typedef enum ivas_in_out_fmt_struct_t @@ -65,7 +67,7 @@ typedef enum ivas_in_out_fmt_struct_t HOA_16, OBA, } ivas_in_out_fmt_t, - IVAS_IN_OUT_FMT_CONFIG; + IVAS_IN_OUT_FMT_CONFIG; #define CREND_MAND_ARGS 6 /* Tests */ diff --git a/scripts/ivas_pytests/tests/unit_tests/crend/ivas_crend_unit_test.vcxproj b/scripts/ivas_pytests/tests/unit_tests/crend/ivas_crend_unit_test.vcxproj index 5061b8e414..3d8e7ab07f 100644 --- a/scripts/ivas_pytests/tests/unit_tests/crend/ivas_crend_unit_test.vcxproj +++ b/scripts/ivas_pytests/tests/unit_tests/crend/ivas_crend_unit_test.vcxproj @@ -17,9 +17,6 @@ {e822ddaf-0f5f-4cd0-a694-38ae69de74d3} - - {12B4C8A5-1E06-4E30-B443-D1F916F52B47} - {2fa8f384-0775-f3b7-f8c3-85209222fc70} @@ -100,7 +97,7 @@ Neither false false - ..\..\..\..\..\lib_util;..\..\..\..\..\lib_dec;..\..\..\..\..\lib_rend;..\..\..\..\..\lib_com;..\..\..\..\..\lib_enc;..\..\..\..\..\lib_debug;..\..\..\..\..\lib_util;%(AdditionalIncludeDirectories) + ..\..\..\..\..\lib_util;..\..\..\..\..\lib_dec;..\..\..\..\..\lib_com;..\..\..\..\..\lib_enc;..\..\..\..\..\lib_debug;..\..\..\..\..\lib_util;%(AdditionalIncludeDirectories) UNIT_TEST_CREND_TD_BINAURAL;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) true diff --git a/scripts/ivas_pytests/tests/unit_tests/crend/ivas_dec_parse_io.h b/scripts/ivas_pytests/tests/unit_tests/crend/ivas_dec_parse_io.h index fe05a96f4f..ed4071d8ca 100644 --- a/scripts/ivas_pytests/tests/unit_tests/crend/ivas_dec_parse_io.h +++ b/scripts/ivas_pytests/tests/unit_tests/crend/ivas_dec_parse_io.h @@ -54,14 +54,14 @@ #define IVAS_IN_FMT_COMBINED "Combined" #define IVAS_IN_FMT_HOA_3 "HOA3S" -#define MAX_PCM_OUT_FILES ( IVAS_MAX_NUM_CH ) +#define MAX_PCM_OUT_FILES ( IVAS_MAX_NUM_CH ) #define REQ_DEC_CMD_LINE_PARAMS ( 7 ) #define IVAS_MAX_PATH_LEN ( 2000 ) #define IVAS_EXT_ADD_DELAY_MS ( 2 ) -#define MAX_OUT_FILE_LEN ( 1000 ) -#define MAX_CH_IDX_TAG_LEN ( 10 ) +#define MAX_OUT_FILE_LEN ( 1000 ) +#define MAX_CH_IDX_TAG_LEN ( 10 ) /*------------------------------------------------------------------------------------------* * Global variables @@ -73,22 +73,24 @@ /* IVAS decoder output formats */ #define IVAS_NO_RENDERER ( -1 ) /* no renderer required */ -#define IVAS_DEFAULT_QUIET_MODE ( 0 ) +#define IVAS_DEFAULT_QUIET_MODE ( 0 ) #define IVAS_DEFAULT_NO_DELAY_COMP_MODE ( 0 ) -#define IVAS_DEFAULT_BS_FORMAT ( IVAS_G192 ) -#define IVAS_DEFAULT_FMT ( IVAS_NO_RENDERER ) -#define IVAS_DEFAULT_LFE_CH_IDX ( 3 ) /* ch count starting from 0 */ -#define IVAS_DEFAULT_AGC ( 0 ) - -#define IVAS_IN_FMT_510 "510" -#define IVAS_IN_FMT_710 "710" -#define IVAS_IN_FMT_512 "512" -#define IVAS_IN_FMT_714 "714" -#define IVAS_IN_FMT_FOA "HOA1S" +#define IVAS_DEFAULT_BS_FORMAT ( IVAS_G192 ) +#define IVAS_DEFAULT_FMT ( IVAS_NO_RENDERER ) +#define IVAS_DEFAULT_LFE_CH_IDX ( 3 ) /* ch count starting from 0 */ +#define IVAS_DEFAULT_AGC ( 0 ) + +#define IVAS_IN_FMT_510 "510" +#define IVAS_IN_FMT_710 "710" +#define IVAS_IN_FMT_512 "512" +#define IVAS_IN_FMT_714 "714" +#define IVAS_IN_FMT_FOA "HOA1S" #define IVAS_IN_FMT_HOA_2 "HOA2S" #define IVAS_IN_FMT_HOA_3 "HOA3S" #define IVAS_IN_FMT_HOA_4 "HOA4S" +#define IVAS_MAX_NUM_CH 16 + /*------------------------------------------------------------------------------------------* * Structure definitions *------------------------------------------------------------------------------------------*/ diff --git a/scripts/pyivastest/IvasModeRunner.py b/scripts/pyivastest/IvasModeRunner.py old mode 100644 new mode 100755 index 246e8139ad..63bf58cb59 --- a/scripts/pyivastest/IvasModeRunner.py +++ b/scripts/pyivastest/IvasModeRunner.py @@ -638,7 +638,7 @@ class IvasModeRunner(IvasModeCollector.IvasModeCollector): self.lock.acquire() os.remove(pcm_name_lock) # os.remove(pcm_name_res_tmp) - if do_limit_duration: + if do_limit_duration and cut_len_samples < in_len: os.remove(pcm_name_cpy_tmp) self.logger.info( "PCM file {} successfully created!".format(pcm_name) diff --git a/scripts/self_test.py b/scripts/self_test.py index 0f7b8b3697..05c6944ddd 100755 --- a/scripts/self_test.py +++ b/scripts/self_test.py @@ -75,15 +75,17 @@ MODES = { "-MASA": {"1": "MASA1TC", "2": "MASA2TC"}, } SNR_ID_SET = {"SNR", "SegSNR", "WSegSNR"} +TOOLS_DIR_WIN = os.path.realpath( + os.path.join(constants.SCRIPTS_BASE_DIR, "tools", "Win32") +) +TOOLS_DIR_LINUX = os.path.realpath( + os.path.join(constants.SCRIPTS_BASE_DIR, "tools", "Linux") +) if platform.system() == "Windows": - TOOLS_DIR = os.path.realpath( - os.path.join(constants.SCRIPTS_BASE_DIR, "tools", "Win32") - ) + TOOLS_DIR = TOOLS_DIR_WIN elif platform.system() == "Linux": - TOOLS_DIR = os.path.realpath( - os.path.join(constants.SCRIPTS_BASE_DIR, "tools", "Linux") - ) + TOOLS_DIR = TOOLS_DIR_LINUX elif platform.system() == "Darwin": if platform.uname().machine.endswith("64"): TOOLS_DIR = os.path.realpath( @@ -988,7 +990,13 @@ class SelfTest(IvasScriptsCommon.IvasScript): proc_cmd = mode[1].pop(0).split() if proc_cmd[0] == "networkSimulator_g192": suffix = "nws" + proc_cmd[0] = os.path.join(TOOLS_DIR, proc_cmd[0]) + if suffix == "nws" and TOOLS_DIR == TOOLS_DIR_LINUX: + # use wine + proc_cmd[0] = os.path.join(TOOLS_DIR_WIN, "networkSimulator_g192.exe") + proc_cmd = ["wine"] + proc_cmd + proc_cmd = [ "{in_file}" if x == in_file else self.test_for_file(x) for x in proc_cmd ] diff --git a/scripts/tools/Darwin/networkSimulator_g192 b/scripts/tools/Darwin/networkSimulator_g192 new file mode 100755 index 0000000000000000000000000000000000000000..ba96e89897224de381218eadd10096c693ef566e GIT binary patch literal 154584 zcmX^A>+L^w1_nlE1_lNu1_lN}1_p)-HU@^)21N!CkYr$B@L*tIh>s6&ba#z%4e|$x zqGCo=E><4MoC+q8IU%kQA*f0q`XMAj2Eu1$U|;}YcBn*rd`W6W36ukN7pi#&Oc)qI zI^%ak)PVRb5GI6VVQ7FbAY^=eaY<=XF@%G~JcSPs^Ui?`Wnf@{@nIS`pyshb1t8|d zXQbv7q!wW@@54ukc|B0`KzvZRL$xz7K+S{kl2Z#x;!6^f;^R^MTk{!W z-V3NFL3|YRUxQsOi7((Q>4d=nrWzU{P(H|b5C)ko0M?(LkMJcZ9b-3d0?arDMh1|67#Ea2 zd|@20dFbJWYTg6}i2Dkl&I0j~%|kK@%tZAkSO`KmK+J*r(*bHA7Jq^?#K-3(#ur!S zCgtbE7nBq+#K(i&1(JbcsCgNnfB^|Pp!yS(Pvb%2P#hnhl2`(Ze6YV!&C76txQ_#> z9>gc)Pe^&>f#BFO@;=DIgr%GzyRWdjJ$ChL_$QNJ_idZF)%b3fLINT3<{up z-N49jfQ5nKK?@^;0WSlCz$8Y702T&@glUWn2|SRpQG$VifnzBnLp&1$!-}(v37#JAdGeWQ~0|SE$69a=YR2&=i;}j#q8Y~igAh$3uFz_%iFzA;S7wP9@ zCh4bC=A=N?N;5DpfZX8}f6CIr&cJ!9^UI7!g$wzNp!z_5WaH;z0AUat5|)WfS_}*f zpmYp1hCzdYp#fyh1ACYVga+9Q3Kx(ZIEoqDm_eZjcS}xYQnI$To}pe!Wlm-i*qs(o zH-XeMrZBRis}HU$E=kSRbAoCCTciec&w)jZ3=T{T44P0r!%{{DSXuxp93@6WU^E0q zLtr!nMnhmU1V%$(Gz3ONU^E0qLtr!nMnhmU1V%$(Gz3ONU^E0qLtr!nMnhmU1V%$( zGz3ONU^E0qLtr!nMnhmU1V%$(Gz3ONU^E0qLtr!nMnhmU1V%$(Gz3ONU^E0qLtr!n zhD8X3dUQVZ=&b$W(OLSzqucdIH-|^J>j!HN{z-=#9x?K7I~033O^;u`1?*XVc?Pih z#y1O?7#KXdS@TYVC68dsqDZ|KFo?>jDtfy%o&s-Mi!O|Npx{E7D(lWCSU0 z1qpa`JG}7d-NOoEzsO`}VCZOV{`>#`OOP#HVCD)&{#MYwrI%5l4OHE%JYbtFJi4bs z%r$*}h=IZIWXFjYYI_(Mz#5OWZvXrLKg03Xj=%r^gVyf9WCz*U**f9x|Nos+dqB>D zxaS2M3j@PT9Y&}|4~VEo@76hg|Nnn+a~A`HM`vpV%t0RAV73P+XgptdFrM(}JpSSe zC;&QJ3y>6n*dEP482DR2i}5|W_kseVyA@<+XKM@C_N^f51qUSYGUC&HwxVKYyzk14s#ot-{E^?SMz)5m0Q$9tH=pNB3S(aK2F4$-uzR?a_JM zqjPEkDAbIZ85myF>;j1*5=`0zaC&Ke697wNouO|)$;_kkphx4u72xL67Ex5+2>97d$%oJem(UcyzXb)ixg!@aSee08-O@fWxD^_JT)e=?Ra{ zV;Gs?yz|tH9XmiSa@_&-zUvNf9JdC6W61RaB3bMMZTSMFjT0~#s=+}fwDciYY)6o6J}s|3EJZ1(R?HT9@4DWk25fMz&(2Gh2;*Y zTVZaw;K2&^Pv`L$YtiItAG~PT4vGzM9EEOpF^Q3Z0UjR$;P~jS{qbV869WSzo|}&d z#2$vmmjPV9+X<2^K^s~;x>-ezgR))cDUVLq7apCV4_?YMFfhD0W(N+V4<5a>A71Qq z0&^hJpd9Vd?fSr@+xLY>r|S)m&J!Npp*K95j~K)rhLtDHZxq1xLCYYIZVwKR&O_iB z0@>pG;6*FQ%x>QY9@ZTEEkfX+2bEW~FJ8=cVqkd5i!5U43<|X)3JCK-HV5RHyOFyD%^WywC!f)ybmr;`=rR2AF#sJUVMXcyyM&@aV4n z;L&RuzmI|8g&A0->jRJG+6N5$t*T&8vwk`X$~YDt-Ju|bmirhOHZZ&p+|Iyo%=JIR z%UDDq=X%Zq6oQ?{_klJV?E;mMFWzqhdE^HJw6IlTWMJUm?t0EvF`I#bzXh~~)uWqr z0@Q|HQ&x!So3}wt{||CPuj>U5R!|9#Y5W9;@r-bzT;WE&+zWPS2F$1}3}CBo*b1mK zF!1+5JtqoL&%ZtNhDWdID~KKwm>$qhRQ~O*H#!e`9DK;=(Ru!bGswbDP_A^n0M>-$ z;}=ZZ7#LhY>RmbydRU%-J8HubNC@_tE`wNbc`MX^pv3LbUHihLxAejbP-wi|`VUlM z*FJbL7ovu-%k@7j`#8iNhQ%MD^c)%lvJzW*&JIFP&z!-aI6_X(jc+c10v?e>UU>AH zO6_G}cp*E^t`+Ut>pdj#eJkXN8Cm|6g;xIu321+iWn z+YAcA1E3)E==D8-O-BY?2ZYs{@c;k+7rmPq7(9A;9rl631`;kv&YT(n*92j;27ok0 zfHZZ3Lef(p&86FsBh97Lb)QGC?>?Bt$YyxJ&49349YAJ?AerIO4Qc{h@aPT_aN*zX z#o+?-SScvXc7hD@=-g@nHshQ}cQ1t1Y5+3h!X^fWZr3}_2N*kD@4P$!YTt_#V5s5EwLjSSd$<@F7@BK;u=Drb z2j$3a)|3NK&$@o_=oawkHNCbI?B9lsAaPz-u(YK|uj#*?3=EyE6951I-@x!92_mZw zm*w3Bk`;l-xevkzqlg+@gJP=t9i0oOotP5C{10wrs14t9^ zdbn&HSe6AMdu9XJ)Bpef|Nrs_D@Y~CQw|*9y1yID768?fpdN!qw}S+@eus!FfZB8r z@d}L>*&7%bI$h6z1F97q6<}2r1}_3ZGOY|C8$flq;ek#F2NclVU}mT5iRRifjQmZI zpgzOI-=+=;>Yw0DW6>RY#-rEtCnT69k(}%ba&oWh25`Tw}<0#H%)@&XIEd|lBQy5!|05WBawR0oAt$BP#l3W+69kZQ_-EEmRiS&7p&`{&O`IdJ!X*d+6Iqa zQx1^Y121l`gR1oC-3uzEUgUxLNuan$JKmc1|NnmmhU4IJ3nX;BH3lpK5(AY^5U~)b zSa&Ok)p^jPx3{&o<01uAlpA7shF`)Kp zH`v;=&Q=>xsoV=HGqb0HOcr6h*x3sz$+~+%+|F}g1O9=$)Y%Fu=(>AB&TBr%*a>EI z_k!HW?0cf~WakNw-r5Zwovk-Oj^YM8YAcBC(b;+dRK0h8Fgyt=0{4P>-@ikYUwd(Y znSr63qqEoK|NsBZdqE@ve@`p}%oE+dXACcW|H!}oVCS)3mTlc&b)CmL&-b!y?`#DZ zoRDDk=mi(3FE+sYfl8nh4T*kO&?kcul^LjN25SW+LXYm+hHkL$`M39i0>lMU9=mjd z%XE)!u*dng7jPVW$L!Jhpwqyk*ED211B0vKC6|s1FaE57MlZNo3JLk<1B`~3zL%b9 z{>8xG3fhR?ycZO143JiK8Z`Wy4=|>6f};Wv>)oxO5Cs+fU;uxD~JiMBtX4Qk8W0--Jrw>OS|j0LDQ}$%*n@H!G$j@AA)=Ky{(``3d!CF zKyi5<68##W+NygmSm+HzNC6@Qk=Y97^@=jQ|Ns9*Hxo2aJi1G7zyg2TH&FiF4|8r; zD~Jiozo5bk>{GP7RL%g(1~Tx(4`RU+{|1oToI!ov?p_cZocPVb=?1J0lK7p#3M^hE zt%f=XY)^M9NC`NUL5!CR|NsAw8Wu1&8^Kc(c-%x7l%znVlNDSXE~E|@0v(qCO5QI_ zKtfOj8(ye^c%TgZ5_FzHx9cB|#v`CAF!r!VckPN7>MP-$nW-y4o-_OW|36ZF-TVg8 zzdRidZoLYCYF8Hq$oLVm{OlVMR}CW8k=o(WYR-Fzk_^9lD?uO@+#Gq(2q>m>B{eP=S*he-X^#y6mz4cwWX zp)WukYmeU2A1`}py~@i<2WxuFf`yuuiY`=*ua@yy(96g_R@uD;I ziAOhh6bm#qcEh9d*bBC0(7*?mCZN9Ti_E2npg!@U`u+d^hygo9`xz9w$RnPyFE76P z{~sa`OaCA>Aa}Svc(LUjv<(FwDCs=@!W7~%1+dFLz=lXVkH3%sNp#nKc=2!v$Q=l~ z!Q&yQ?R^f9ZrF%x?90ag2>TJ`3+MnD4`>QNlrNC*2Dz`BcP6Nd*L+aGqZ5=8Kn>Ox zua>||P>k7;>0cr^cH z@aXitz~90N7OlPT!W5(vnr$E+uYK@h4#-A#uo93-6Coynnwj7L>-NZinsfqg(uo(Z zL7HIJgOYvN5?FM@qVvOxS&Koz2(AS~54>3O7CAbh{g>u93E;v66duQ2KY&eauBZTw z+aKU>xeRgD0nkvEM|VMmM>p>>Q17tQ_l8F=s6iWgfSpvJ$1`u{>FsC8cZ;Dw4L1H((uAv_=>Ut9wj*LnO!#1c@)05Y`N z?YaYO3^;W|jq&JqJ>YTNp#tn;aB7q=ywrIO?Ag){9^IiE{$B*U0c`342?mCj;K~ow zR{)nw%|{Zzb=HL!#fuQZwBkkUoB#h2=?zPIo`M+IcYOc~`qahXpvO$lJ|GEDdKLuR zfGs^Yzk!S|!s{dsun$}x{0}q$jka{U-g)s@3KYV=4?H>>K?PaYM9_F`!z0Fy(DxqQ zJ3&G(K1hLvYC+{}M+(G_YmQ$iQHD05p^X8dJFL(Rt3J z^VEw6QrJYfq#+i60~^A~-vTzbV*)4xL&BW_qyT1XE9j6wkK?WnK=K~F;6c>~FZO^+f^JY7?1o3DV}S?6RgfOO z>kW_QiUJP)CNxJvBMZfm1uss`hdUCgfbpd?%oo^`9mshe%|{%-gH4brPH_Fx_~rqq zG2Z#Zr<=EX9Rq`JH>Xdh?+=g8t)Nc0N9R;fcebgm`pL-SH1Jvj!@gUQ~g7+zJx$=-vTR{$jZVsCRS)q@%kREYVz9!NA{Q z0vcV~3leAG?*}*4oA-jOX5eoHomc144K)Q+ocs?o02iN-u!2~B{1~X)_#y*TF7|^v z+aM>m9_Vb{0&-7_E^L&e8!XWLf|0*P16_;>l3u`bS;xU0WKhO^3F@~&xZr^iP>eyi zpdrJTSX}W)oPpsbCn#KD&aS9vhIkG%cMNh+A2_~}TR}ed;9uVg@~cN@>jF?e40QM! zBop?6`5;Glbc5x(r-D1`-FrcO5m2K?dmeNI5{omULC$CbrweH4RaCrSm?*)zJ zg7lk>U%kWHZE{{u85(F!)L8;&71jUet+!f(JaT;Q@;X zuso>Mc@7d0VROK0z{bH`aonR58qOAAS=OVgK#DNJ88m|7(Rc(Dnz4sp?3)b^XQbs0 z4v_vt;~UVaj~?Bubx>o#0Sz7^^XP^QLO_~R;Bj&OR(|kkKnZj-;AJOxhzTs`(G1S< z(D}9(c_JWZfn~ZoKu4N3KNJ8DepN&A322xd)c9B?3R2e#;hy*CYy}Nuyx0H{1+l?H z3ZP!ui_0?+N$^PR{32W51&s(?o9x6Nc==-vuqS{_4oCa9Qr`3T@s>x<_zp-Bn1@;jtNvQ7Avp#d2A#)W6oaE45}u%9r4=-s|DqNm3Sxt&IeI}k z^5s;JWe_L9s*DmLQ1F5?8!X%c13bD5Jv=l&d2~(%X=?^&JqG^1Xpqgx&@nC(Hpm^_tsu1?{Ob>TFhg=9WRUgcH;~a#mvtV0u@9mR;zv+A z1&^|KKtw@oa5~+CqzRh5x&s_Mx;;ERI`={gQjbnZg$f-yPK6kOFc>sm`(i&t6vPI* z5~8_xD>zo5HF7t!7U>1o5uFEpy1{kW3u9qW0D?wQ;R!F$1DvWgKY1i?1xsjt@?ZuB zB{W1KF^kkl1XoC~bX`^9p$(2NkIr*DKqhu2QaG zI;?4l$VHt+0Un)29*CCae?E9z9&ZE{C!mZBZp|KVg_TC#V3tQW?2Q7T(e2v-svD*Yg8EXRRR{Xuq~O}&(d+vTG$q@32o!LjCUxU6 z22sk z!9tK)7&d(fYN&X8{|TP8I_?UZ*az?6gPtQT1Vpo+5d zqKCHc1JL3!(29kF4;ehVq4o7KP|u=#D#RLiC+#(oe>K1s!VCq~X)l(7g&^gw=0UL0 zouGMXh%4Gbvdo}GIiUx@ankKs;n8^;>ue=ms}CJi4cXRCshAeBsIi@*l)?mHZ40 z{QE3ke4hjk>6e$l zbc3Wl96Y)M0>DZ%KY1`-^yu^eDF%tcdzFVgI>EEr{H>scb34GjlTL7EdJ)XHiFPnL8}1=Z~y zoxR|isdFo+I(Xp#DsE6B98_Pt&;$vCJjLu-;L!~>$)g)G=h6)^rWFxz- z^XOzz@#uA(;L+)#!tp|t9~AdXnroLZL#Cy`;RP}j)b4<}y7Tx89xiAwbsm4=zzaz@ z`zC-ipLy92NxBojNgNckkV)W9UIqpau(NyNRTAjPZMYR+rJ#D~MI1;e$X2irsE7B$ z8zcnQ?K{Dv8&czRL;Hn?Uet0ToU@S!;v9XbbKr$BxI}&_4sjj0SZISPWq~LKyQK5@ zi~FEB1eJ`IC-_^%7+^I(Xa}Om=ivmc!8p_D3R<$@(Rc(@Fe5LB0QYAh<4+$tOF?Td zKX^dP>j(TTpCE1k4{#NMECUrjAiuiac=3rF2SULqLiC~p)2$<|Gr=R`wITQ_|b=C6MPJ)^EkvN38+nH`jE`H^uiEq z#-$E{?$S4%rGLPS1i?Z7VtpUjNuYTx@H#}qm>p!ir}51LkYhV*(SvLOw2I4v81V84 zXm+u?cEO8Yu+^>$KxMonC`opLN>?bKA6%f`=mv$~oEJuYpm3SfdF+J%)K>{0%eo<$4Bh;fh- zeFr#0Ld=f=ncwXT(%=DFJ(UCDPXNVo%PUApy8zy11&z@`je4O3Q3=)A@xlng?*O&D zIzfw(AQni2g+niRfGk0-R~CVS$lCP+e+#&kpxq0OgO`njJc{ zk~2HVr>+a24PbZ~w!ovaw!s6GX2Eszi`g6?bx;pND*p_qkWaU#1GvOv4om>erF(RP zTZ%s2U}YYiQ$ba>4`|`(L7!gN9k8w)q+mJ$DVXN)f}DNCquY0fM|bD~a7F|#OL(CK zwgt=v1tz2|90i5OO^MF(}Z% zL-T@1r|Sxj?n(!b?$8w;-LMYWhaOM|%yk9S;7X{$=Ru=VV3VpLCN1#jF5Lk(4IB;N z8XhvR@Zv2S$S#yhzw^+G>5vxD0)!q=JK)6!NQnbUVc=B{FV2GXgX?EdI)jZSoO>~a z2Re=V;!zjGzo23PoV~#W*sCpD{vu|jK(2fMUVGem{DmkBB>$|2XaX%Ymh>W`7OkJ0^B{WFFZOy>*0^T0EL7{Zz;&4 z3m%<^zn)^W8 zL!j$QL9;2oH(r3oDm=Pt!E=)AhxR^We5TXcXv$M<*jB%#nQ$i$7|c2aiusI2?ZgZeoI?6goeLX`g`M zfzD%)IlI~)FF==qK;}3h^;7d3$owWKJ%aoPPGc8dOn`b1v@{>oF9V02>xmcOzDu|7 z3D5*+bL|TT{uUijaCX;TcmWy#1}&-Vu6^P1jis{QfeSsU0E0UY@cVP7|7u-gK*=o&=_ zl6|1C0p*QO-v{7D0-!}6ogM;^eFz>BpjkAJP7ejF_JQI9rXLi(5WNN-ogNxc{TARU z16X=N&L7<%50!p+0bWZ3&eg~%43@t^}ZOSa^UgbAhPA79Ii~ zy{-^F-Jp3E#DH1_$W@S3g~;#CZxjp!-j0NF5j{z1rVV3XegYCof{mqIO1JAEJcfcDaW-3(1X-M$ZeK+|#E7SL({v=Zch zfCi+@PlIjY1NR3I_Tx_fV6z=0u({6z(w_hY$OjK-9wXL04*1;z3PX750S_;Tec<&x z$V0NAb;$g!vl0EG7vSa?c+%D64``o;?+f^Vi6OYia|O+fz5oyNfjW`khG3y=-=mf3b2hB?RUhwI3J>df${qcR_(On8@19jJ4@ac9v;nVGVz^6M_ zz@s}>!l&ENqqBAgs4d;?yThkbM#ZBuMg_FmdxKAB=nBXGVG172M-rkPzKb^HdI!nKRs)26b zFCN_i5+2DvJs5v^bOzu`-vXdL0JVQQYk$0GY5+AAe{>#uk*_$${P3QgHYj<4Dim-T zSqSMDbyp^MG=gs7VgQHE@fYuY{Qv(Fbk!6{uLndaBqMZJ7N9CU3{r|TMuFs(6=1ix zet_f-P{5&v54a?UlsBMy6)8ZV^%Z*j8NlNYEjvNf(=9(p;K&c4@)cY&f%X&ne(+%S z0JR-JZiUnjNbw2U2n*^pxqf(Y5Y*D|W@Q5PlUc!`1PX9)I~BYd5mYx}mKUJ%7aVrJ zA3Q+weF7fco*ba9C*46WJUV#}&*$75TBy;-9U;rej=O^Td5|sRkaiV{2-p{(#eLx321t*e@2hvj^KL>J&rqqI$aDN#~s0!?}3)>fGqJi?g$$40f|GGX+Z<6`DKGg zr|*FmcR>R+oyeP^J6$2Wem_HGHh?=3;B|YTor9empq<$s$D1IRMKUmW9B=vovI$iD z9B%>*Pk?wH$D2TxOhTF9_<<<60TO~RLA%00Jdfi|;FZr1QP9*qRCEW3hKPd7L=ey8 zcoS%$0+hJ`L_-wJKrlg}3F3JiZ-Rxj$ML2H(CiaLZ3Th}yG_#LcvA*K6tprPYC;4; zGyuW$Krlg5YEZQn2vN|eEmRaVYy)K~AQVU-m;wkUXwCqn_IML0gFslI1_+3CtO>O8 zjp0}mXk8n_u_n;cFUb5>=d~BhKx0E7RUW;db;h8*&MRIxg35#L+7%tH%U@VmLD!&l zxh{wINI<~@UM}8Udg4Vg!id@nFH}E)j(%{R0gHXm;L;3_&JIwS1=8~3RVCCwk8aS& z6L=oth5V=g|5X@0x_wVT7BoVtnod{HLgtrtpwNe~!6vMLnE+eNcLGwRfmej?0$tAN z(Rm!U9JKjJ0eIc#i5JRnZD9X)*S>g>Q30CI1h2*ko$#XS5b}yyaQhfkKKIuC@PICO z0VOO@;{j3(B6lDl^$nyi0%~wT`0)Gkkje7!}BKptyv{H@|V{tOd1mnjifAf1>kX^9yV68tC>bpg8Mg zl?SIJ-wPheA{`!#hyFkE=w)qb0`>M?f4uw(QS%1Ie+uE>gYmCI_!nUOqY(aK7=J5- zzYWG;3gJsPK+T^D;m?H0w?g=`^-%dz2)_m)_8-v9sq=OOXm{rmqPS-;=^|NoKo%c1G7L(`9JFF9ntIV976_P7Az^?xDc#3#wu}&%L+^+ARXEWHI-5!0NjfpjCdb423g2gU+_`P-uS0 z3R+(^6@CH)IKOw+g2p-#;|ra&KOk!hPIz>lLhb=W>vvdw0=2uKmHhD+pp^^gB?MeO zsC$X1?|W-+>;jeIpjA_yt_NOh2c;pa{67HN5(Zi|xe#P+cP(TS{}zxO z=**Aa+5;Zlr3*lAR$vBYg4!35=3ng$P%Fv@WFTaGcESsLh=Lg&-K7&i8bC7*P}hQY zwXlG975A2ct$eYv7*?h9)*g7l44PAb?JM%=bluSzy2S$|@d~z73~EyCju+`g2!D6H zsN4hIY=lUk9?0?ANz`~PXgm)Rzu@*bq>Kg653B|iC*W2#B7H%|Gq9@%-MbDMBSBUV z&L7}92%g>^K@3Jo@X+)ID!;pt#_!SjaR1f*cyStT48lH;dQe>f_6xKR18T{Ex)`1u z9-W|VcThHHcMf;ZW{c<~pU z+(FYokkSjX_#D0efZRU-#Q}H>8oo!DC{G_6K-E z`U*@2I)?*ppMX2DAj{6Z*aDO9JpN+GFVNTo=zJU38!w_k`4&16)DKbg!K2%O13cQ$ z$q1e-OFstI@B&oI>;|i;eeog)G|>$1q#*(Tn*Nc~cQ-^CxCiY5-+u}T577BX;QZEk z{KaHYKInA)@ZuJP0o!u<;zi^eaN8C#JpwMfx)~rj6jb8EX3{eA85m&W@o@V=eY@i? zK#g~3%>e7Kf$|3=|AX6zr5|2Q2Bi!f@d-;0AoqHMoCj8i$gjxu!OMpvh(avo!wb-E zWl)Ylga@d60nHbFfaOn=@B*bL@Sybn|Nrd?)Q7~BmoT&HvF2~ku+|I69vRS79e7wn z^Mc30A573dgl89Q;SKjcp7|)`@FK>&kno3;XWgLIH*~(n|Mma>@ZJ%$007Nh5}L0; zIu8vtehx0%!H1%OS~DJ zJCDB*2T%0+Vw=QTsAG1}qr3D6 zxFYs_@FE?;C)joJ33|0<3bglNmi@%xRM&*YWlQKY!I@nR}SAGkz8WM*Xl85kaL>_klY zf(jXMqX;yk75V|R?)TtNCQ!x%O~*kBOCwLs6P^bjF!?YZ^XN440FOTRLCQ? zY*0i(qYs;Zq3(zD&!LG*5VWKYZ+it{AJi@a>qS861={`qm%|spD?>oXL0CHq@V9^) zg`o93XF*vGB-|Y+;L&{Ok4I-9GAKX`PPzQF50Q2OXB{eVsIig9>*ALJfLc@HrUv3?I*e-xHJ5%z=CzjzEf)didu zP}fty(i=!UsEvLQqD}x~{S?6$DFaZK z8dREs&QR&ZGCt)GQGj!N3UnGC=oB8v_!M&@^7xc6sGo~%eCikG_|)-ugugpp+*~;% z$EU!13m~-syu`&(AAs^dYW)CBzqLPJ+y+$zU}F&N0g!r7UIXW4PniUWOk=x5?eYI3|z;)cwqou4DJeE zyZ|~#o$z?oK9~+r(typEfyb*ORDH zjPa`Q&7e>NEn`0Rf*Wj5?TZ(SKn!qQg=peJ(*wNx2c>t2GPL>u5+0zsr5ltVI*-3d z2Ggz|UTD1o4-p{7t5)6w3lJEu+8G0?Bq8I4aQh+Y6*RpLZ7ae050Ls3WIuQtGdLa* z`4L$^qzBY_`~~=cbV#a)M>vXqi5qX?NAB{V=!dl*iCRw$9&3Q7r4Lxgmsp^lhC3IQ zKC$|b`1+Y({wIDsDE1*ZZYdcLl7bjP#CQ;k2P2m8Ac!caEl%_CpnOQ%8`LL9>yIJI zS9p7A5kfIM0wL*zxbdJ(IQ0`V9%KT_h0tOFy#E3`EeDQyP>TX|!$Be_$AZ`7AA13w zbVe%-knA;BoK)3uycYpt8~-R>3+|A!fLEZw2T9PzKNcWNqR03L3)b-u79z$! zK=I|#dF}-_!3fWpTOy1|I)H+}`Ot{=x$^un1|%!RiM@`HgM<47NWFoW2i&HWa|> zzZY|EfT}R)no<8}pms87*)QXZW{3o+8T;ae8C=4V!=v#aq+RZN;zb-p5okrh36I{= z2OhnlH(r3xt^!Y_!`f@;+wtw*kc;wXu>_X6f%VRG* zz--X*te_^p>xmbTt^J^s=6c|T6sX#VIuAPDh*=(h!V@&c1zL-MwLOb-ycJr0h`ay= zC8&HlnJl>rmVN;* zh;DdvmR@*a`v@dldjouCaOa^HYhQt@Uhv&M*z0@9`Mu!dK_N*B-dIC!{~*F2>}C%R z(55c%N(#^nleOy${uan#sfb51PFJU1k7EhmIVOVQ}o@dmy(EpWX{W*J7=?iWJ8Apo#%hI(0I>m<*AC zr1vnm1ZsNEgD65x@8Cr#&;$kRzk$jdr1T1EuR-RiVe|QD`*RWD3vSnC6`7UTY9bCZTT7O9W^t=+Z-UQ^d=7S%Q z)AK>FI3zu%{=}7@ANtTLJum$A|No0Smyp63a!4yE-!Q&743U7OXYhOsIH9Aa=XnrC zsOcG_{KnE>qk8&oc>qctkn{~Y@)CR$D5R%$;zc;9;SNjR;8W9~*$rBLBiAROG6B{< z(+3&adHjVrsEh%{AddbSq<*EWyayM|kn$eOcn#)!FSvaMnx%Dp@xmOzdGNvu#K{Dm zoeY}2dH|U@1SPy1FZe-H5YJtBQ8eTKe-F623kY>5UOWdo25k6&7r#IpxH>`|pB|8E z$iy#l`HwY!CtN^EdzZmw5PJUhg}C^|izQ$NXnNQX(*A(t?_Q8~pl&+&Zoxw@!0Ivb zH>iFFwM{`~BXqAV&ic38;srSUKq@n=?IZAt6=Zpk`KaTapz;zno`qxm)69KfbH4wB zj8fq$kKp5P#JBIjJ#b>(2PyBsi|8R*u-4zW^Q$!|VxS`ei1|f?|KaXWf+z$H{=lt( zjOTd3+Lxd>0_Q)x?Sq-H+}L~&R8PEsq=yqP3PC5jf^+$?7pCy}Q1te}M0aA!Q-pts z>(7AH)1rUC?9prD0PZ8aV0sL#A~4q~?sWro5U{t;u+_Kt(knc^s4>6z4xFh$>rGvE zytoJ+X#$rj8=&W>)Z$wI4$c~&sSwcm_ZyIu13LK~Y5hCMec%aWFyR53Esu9W%(Ja{ zQP@X#e$f}?K-l{CgvluLi;l?ii!LBJP!)hQzjy$m0A>CA8*m37?8yl)?n4ydoL`gx zw}4^m-{-m@&o3?p%}ZdLU+lu1UrcvK_`BmpWiKt~7qOp@11aA@`4?2iLh}r`KL$Qi z2wEb;$_Je34|IPis6+>sM2PwWq#kZIsEvqwelRl>ynTdb^MipL9-RT8Yb*pjIz3?P z<3a9&m0Kjt_nmMAt&{^TUUEfWpFSHT1)A@x0S$nVzdk+oGN@TZjrqP{P+A6;^N8s# zr2aYD`b0!}0EG*y!ZrSfDi|6C^x9^KIb#(|P;_`1};m`gAKu8yeKm{@~GD`r^gTz2IgM zf%(3Z4xln0wZ8~5pKkMcs~~`jD)V`e_AM-rgO>tA`ml`$p;ZB7{j@G<=Kwf6fVZKL zvwr&3QAqHD*H6cS#t<>rPs2+Ql=-sEQ0Tpr7a&cJ4KL<_3M0e-zB&##65liAO8!2)RNfSSJ3ncI^PKrp2uGl;ZqMuudw(4=V91*8Dzb*2)JMY zotSd$#SYMBVa)k4$hLh*mrNBDP-vM4;eTlPi7}oIvL9qOq{~9y`etuX4G)_7u{_8R zTi+bx!NBms3FL#!T5y!^1C=Z|g;Q2R5{|?fghmP!V7DV6s)7~2jalhq0AZygQeg%$6}i`x&Rt10*?%!#XtJ^ zGp_UsN~@si3HSO}TW}i~wAT*WjRl|V^TG`rprD(jRpFYY0dO zq-a2jF8Fu`BELi3gB%~-;PtF{`=6lx3}pNf+Lpt+-V@S)gZ6(wV;JBIyFo`YUGP9% z&uR;jT&V>AhyKJON3+@bmm3P5>nV=&+X$_4&zH9^yrAUE#qoC$?H|Wff4<3-4u3x+ZIj{5h3pUWgInW6koserUzJbKM_d*UA zKjzU5z8Cxd1^C`N@CaLP?T;5{K?-|8-DU8N6fgFI_}zO!$B~03MbCk}JP*`jhh2Kv z4?Vr=2Y5>zDBeJc476(*H1gA3df)|zDFegHERY^hlLR@&L4yrDJV4f#ffnU;x`NK) zec%B)!?+)M!`d;AUeK-e=RG>XhnTS=muXxw!@=WB*>#z zoS(4_<5bICfPSDS!>)b)XfwktSTp_(D8wt@~A23<73 z1JVD(19~Gf#A5KhBH+XUzF7yfu+*m;yh{>n9Qf2=(1>yOUeGnpK9Cz%e7dKCPRaM^ z1YiE-1G-}md}oPI=Os_jZb9fR-7G2|-K`%$V~yaG?c0sO_n(4J`~ja()9~V^A$&9j ze6iSz7uBfeWgzyy*Zz3XZ3xc0DCI4vya5F!uJutMc~JcU%Gh9apauoBOnTt~DxDxJ zj$z|1@cClU891)sLz=+n34?BPMdW;N^Bj5IL7EZS`z;XVAIy!Q5Cr9O(D_8Z7hZs_ zLIag>pj-}JUkAEn7PQ;;#Ea#ic^6QA1|6mm1uE>p1v7j;66Al>@peRg2M!OgMX>$? zs1b^7YbB!o>#POsRYB(e@My06A;3TV0Qejd@MHl>`HpCBfcC$GCh{OvJ*51F*QemJ zANPC$C=Nk4O@h}KfDM4?$K}87+8>af3aAi-6xZOI95llKKDe#+!;6gu$VU!A%!9cH zVjpDh3;z9)5dT5dzc{E5OQR6;pzZ^m*VK6M1*kOW1fR$NOK)&_ockLQ{Y%i81v@XO zNCd430NtSoq91s4JAigyya1gw@!~n;DuW-OWAHi!J-P!pJUT&V8i15I3V`>Z9DykL zfI|s5ZNt+~^Bc(dY9RlC(kH0q>Mi~7qMrw;rQr@Q(!kqX9=uoxvI2a8YUzg;DacB} zMI)%T0gX(6My$Vqi-+Sc^gvobD>OiNwSXrzPCz{d+VBNBTLM%c?Ev2dEyM%5BYg#9 zhwpa&R&X;1abhW`(%k_%)cr*b)Z{538Z;K&dCa5Rb;bV+9j@EET(`q(Sa6R5bU$-8 zNMYyk7mGoa1L!)OPS*u5!a#!H1O1`57DGohL7U40AOR{2x}+~26t|#5S5gtWXS|Sr z=$--FGXWbDh3kF*zVG4Xd5{sH>cInid>0~rLHd)>_BE&>1RbD+HnnGfECcVo1RXAZ z0?Kg;hh{h0952$K-Q4P_DvYw*x4d|#g@Dg*7 z6`&*nZ9jpJHE%uO0l6-VzXfy(EhHmC@6H3?xd=Kg1WlBQzXfzc-%C}{sXf_{))eSE zUQopas>@y+2K5X(kH7d0I^P0xH7@in9WL-Ll1?uUNWyUvc&W<_zBmNbRDldcfsfOF z@dz9%pgZqDC-h7ORctRnr%Hh;KTw?jZe@Y*ym?^`waXtwgAzaV0y=vTA9}+JC|!YX z&G~(7*%OaBwT{#V=47uk$$gJ_*BEai;zwWl3`(BcnLnU0AvBgub|fDi(sgc-5j872XiJ!%A*szGY^990RfqU?o3c~ z7~C@a4_apcS}y>1CP)~IGrU>O`t*uxycKfdYS=l@-~Cw7IM8isO{Y0 z(G9wr$F%{v@pJ~XeKy0RySBrl8+1k2p%PJK&w-;3kz%cQ2?p^@1H@8z@JB z8o3Y$LYk;xw}S5>gt`ILc7(e4g-18^=Ekj{`?oy0r$XA7;0r8Y7=R3IJOawk;O5zm z7gic*%`?v;%=t1zdjgdCq210SfOfV%cvyqh zx2eG5$J+G+HKIfI;i4qjt`ECK~o3p7+7ym$nf z3xb5oh8I&Ic5EQVnc(FA1XK=yLd65NI0ajK4s<>)s4W7nM-cT@;~P-6^gx`)ji^eX z^#VAmn`K;O_%p^$XgB3gY!UA+q!daO{J7u&$t{FX#*x@UicZ z&W@{q2dEX?4LTq#bO-20trux(3=A*Nf=UWd#kzqJUKE3m4gepD0BJm|gw!z)K#>nA zok6$nzK8*>!vlw6E9jcV7d{|<_g)Yibb4Jk_;y94R03{@fQ|w|#MDf%$-Xx{8V`aF zwg>G}cv%c-C~SDK2XrMGsGGYP#DIjr1^(Vi5IxK8WAF7sLkjQyjkj|Nk-&GO}<3#U~3u z)1RPo{XoSr=z6#pS3pGtD5-bCO0XBOt9pBDH@vtCTg?c)6|j3NxX|i6^x~^B$XDQ- z2jLeMfiCj_75&f-wd)FK`@^Ff`6iwh4WQ5iT_gtzc5Tr0O|77&1^9?7P&tj#MFw|u zAr1uJ2-giZ67RkC zWz_x|a(fum|7r*C3Iip&~y3fcLY48Km ze@Bo1bkOiExLt!P4~k##{LzaSAs{8-v1`ya-xn`jKzztq!r)RItQ*$fYJ3Ae`UV#5 zpeO}R>4T~rP&ZrSFVZnT-`x z-x)8afKqAa@fT+gkgV#JjV~4QeV(jY4LydPX; zcDeS$>uAsk;b616Ye8i}!wbGY|Nq1LNT6%)u=PA{yl@A1?ObWj%xt*3t>1tEBB8+-rl#tTNI%j1xe!OJh8A!Lx- z7@!PjMg8IdsJ;g`fWTWc8jpZdHMkeC;>8zfL@xr=8F|5+1{&mr%dF_P`I0=D!?K?brLr=W$e*gbJQnRiN)Z74h89I;=)fPX~^zma5oy%vYhcE2{cOCdHlsJ@X9MZdF926?LT2*8hXQ{@esIh z?+gX?$WMSTnFQab(+Y}N&wn zgIZ{y*5eCvklmm_hu$`=4&p;+U_b>8xHpU?^T6{;CMbb}T4A7|fF{^SpsiG$$6rYO zfCa7q{7z_W+5W_f0MKwkZ|#d0>OcPfe+lX_f`$MgIcdiWr_cZYzXZ)0gSR?BTnlPM zzNmy+wDCK#MIb5cIpf5O=b$73%8&cL!zOV-j)#?$H(qA{1xGQcnD78a`7uzj49gFY zLByg157Q`o@q;TR~m=<1ZXRkqRD2MtBHTUqaev zAiLn}gTUQ9h%ev^0HFRstAF9`IY=`LVLGfn1y!UVvvJP{fyYu|;S=o9_y%-Eg-5rm zfUDsp*UroE(~&`^H+O$a*0oO}(WLUL=1(@^29+X+W=?g{tWU_oQFE0qrI2JpMuj+~EWH8q^KPQj)=a z9R=!teIea08q~w7|XDg)ZwiQhEf@kYrd}c$~e#4`8 zFQ}vRf)Ak&>_(4n*cctiaUR{^F*+Ye2hFD&(uM2>kB0hmPX%=qeY)pDMtUFnbVf_~ zbOsCfbWa62$)|fRs0ZuQ8O`C-DeTedtnflt6zT#*+)B+heslD)`8Du_Wr79?GZvfxX z3-V(YI3<9_%o#uj{(1C*mKK0c?Fa3eUGO3sybl<}2Tc?$KpNVCE|CGvD_wZ03QEBs z<9346FUi1)p z;zcWHmZ=jwUIM?v1k{#*xi7(^GxUc?r|$HMiSebd@odnFnH&5q|3G$unjN5) z>C*Q|E(Z-4f|DX>;S3~wp8#DO^+F#satOLx^Ospa|H3 z6anD2Kd5c82&AO*_={VhJPis8&@~#pAVE;~2K(qZNZ+e>|Np~Asvo?VgV4R=g+E01 z3Svf)A%zF1H8vAu;1^IT0;hcB>KZye()b2+HI+xVtAS5%sDe*#EU0+^itZoa= zjpqa4nHk805vc7CTISRM8Vu?L4YGNF=GPZ^bc6R^9e~^r?z_RK+jWLdx9@@%+K@Qv z@aPPk@bW&$@ZQ=BFHAw>*`QLii`3!>XXmJuV@;3Os5L()b5#-0>GGpzc~X zsEZ4(NnbnxiFZSnJz!^Xb8O*6p4*TK#>Jr;(=cNgU7g_>p4O56VQP+cykU>UI}<~ zf{wceos9~@r9WN}R9_33M1ajL;aBhA(HZ)|qZ70?8g$`j?TZ(OK~V#_TIRxwZD0;) zSClVk6%9C9z1RpA1SOl&6QBqJug3>xxMMF|K}~E>lM=kJ29bne?OC+>FVKLh?+*`6 z)HUZ1Jeq4CFz~m5hUmbh4QS3jGxPzZzX(2dub&S*gZRQD(-$JlcmmSMMX4{K?ORy; z6}~6PiEK>Tk$-*`R_B zG?%3X(hu2s2CXzfYgE<1shTVt<-{NK(zi8C_#hoTmaX_;PaI}yzl}U z4jQEfMQ|rH`Jv9=!tL__olXN8V}q=qgVcv`c?XWz!&u@U)V2e;5#l$nKheq)(Eg?e zpgt@{;(#nDy6{37c~CSMly!S+AG~-ADxo@$zjzAjJb~8=xbAqd0wf3?fWuL6K6s%D zY864$Z+HP};l7*<5&?~Wg65LJ*Uo`5H3)}-S^xpa`3shi5eXMmtw7E<=ne(ltp$$( zaQYx!J+$ltr6W+O1-%^x6z0gm3(N2DvK8c9(861g`X8Wsi%_Ejt{zsl!p#Ty4$;0r z-_HRl4?q<(=t5=4nloWgh=WJ9kzItE9uB?$-2n;@3wU_|F%RNLP^H;h`s0N%=&%DE z=E3jhf;a)xBm^ZVaQC40#6D09{KaEXk^r@HK@9;=W6|gtQj-g`AQ0N#gw_5#JV5u0 zbeHaUu>!PUxzqIr=;A^Ka6t`j8`Q3VnA{05c>`$P5` z@uCH0GE&16)cXdtIzYW|km?4HZpeCQkM7Wh7XnZn;0aUM_GUx~L-Ic){2+k=nGN{x zq8T*g1PK*z27?sFF!iAO*dXdbl2c@^AY0r~6z)Mv;G3qkG%xgQk# zpvE7_KP#Xuz73!j-wRiWp+CS2kvc$zfzl~xX`nU82HZ;nK}9UM*^4}X2N~~18Ds)A z&_NvoowFbZgNLCXfX9iXAp)TFk2kRIfDo68(!#vtpE=Pd-Q_W8NB!nKD6lg3uBNm zz2F8fxRLr8B#yU{+6^%WRQZD|g{|P)`Soc~0D`A$zyrP3U?zVrWQY>v4v4+Uj}Uj< z-|)}|s{#cBXyHOTC{8=U4R83G0`*B>6R0b@jVhu7br`Vo?U5rrQ(54?B{ z8T$io_Jb@KcRldp8blDZ6&2L41^ zfSdsIWVaJCY8XX3Yb&_lNw-B3ry;ONj)%W049yVqzRZb1CthD(h5x4fJr+r=>R63 zz@!V9bOVzfVA2ar`hZD4Fc|Kq3Ybg-lNn$# z3ryyK$viMw049q9K!X83y|RS?3=EFJ|5ZEr7#JpGfUeGY`RxDy{~0l$jc<2AEKm#S zruolHCVl34yL|-2!6ygIKFTtX>dn0f==P#F_?Ty#cX$KrBwsB5+W9 zBSQzo0+sU_{vZ};*f0Y$<@+)Pq;4TdEDFQ|?OS{anrF_q1rl=uiG2aFY(Oj_&|roU zh@}N$fdWTQc1Tp(5nhy@zH&u9d(K>HOkCV*IP{{8=-F(1SN zttZb|3u1x#4;gzwEYSMQjME_25slui(0mS+WVl4x)SU>|Vb3iQ6T^TPY zfmli)u?`T+5X7nju^d6Hl7IjI|DUbOD8mrMz!2oJk&$5^BTpX-;}ymoj2jsldYET0 zGQjSf|36!kQGp?lfgw=7iHTt*BTpX_!yZPPSxgKInS7d<8Q(G~BB_;R6c7-0U{Ka$ zUxW>%DaE&==G7G~-mWzz9Ss2c82*2WB_{hOCn~!lP=U(Pl91M$i zd0w+H?B(U0%))Simvc5B<4s-(28NGd<}Y3YxOEI5KS(hYGB6bKPGw}6!^ruMk?|ZO z=Tt_9>x{+-Weopk%Q6a?2xKz2m@qI@@XTanY+*#WjDg|*e?|@g9%BX>QwE0rvlSU7 zE87-t480tZ}0AvR*BS#cd8e@zCl9(x@E<+XrL)K)LORNk{tep2)85Xm0USef< z%F4Nmjj@@H?-DD+95xVpDI47R|7Y`p9B;%ZqlRRbAS3rTM)}oDj8mBm;KE?Pi8J^x zF!%`6F~n#xFtjpqE@ouxLk;WLVEA$G~uwk@Gbp<26)uyo?-L zyuOU)NcR3`k1@hL0ro>UM)dftf>zNpKGI6e9WBknA!?d1>;XkVl+-A4L%$(E|g_3-Q{DRax zg_P8s#7c$4ycC7hqN4mFg@U5|w9K4TD+SeJE(V0!g2bZYR9uP`bQM5)6jE~wN-7~b zi;|EugDrB`Gqf~P$jmD!Em26yEGaH2N=?j#DE7=NOU%hk!IUg7%Fjzza0h8DuFOkT zD9NX<)8$WMdn13AG;AvrNGFTX^gC^a!fA+0DeH&vlHvnrK~ z!41sLELJGV&sWGvEJ{zc0?XK{l58RuLpg@;f>REuFT0QD7AVM$S9a;ice*cZhCsYL;a$=RtT3eov#X~n4}v0MxaFnv}E zaDXFjL5jigfTUDG0pfbFI3j)^@tT*In+nndaSO683~z%xqySS7b~Lhb1+WOR=izG6 zy=JA5SDKrYS_Fz;a6A?(6r>g@6hQo~VW^{EqzQHtH~^3>DbC1DE76Apj6x>P6b_Pt z8my6$nwD6aQ(~oHpvlD$nwMHpkeXbQnu5;>RtlhmQ;wd>Asz&U0wifGLlU89igi&* zL2zoJUp|NtQfyt6To#g3S9E953t zWagIUDioI%6yz6y{0vgZz@V7z7hGZ-A8%-Al9X7SnH-;)2FbCW$$r7{hK9)*iAC`x zMTwau#h%HouCA^OF!ja|^`Ia~Dow+w9Ne6eVPIfjW?*0doyY(x#6WvanZP9(sDZ`6 zsK~&?n8CovaKMCt0dxi{XkD}dcn3Lz|G|WTq2@CKgMv8&!;;So3I&S zd|_ZHNMm4l0-`e*7=CppSup;~N7*K|ce7 z&Nl{zgeeRRAs~7#14G6)28Mun3=B0OdLaYDgl`NC3QHImmVnf+WMJ3mje+69Y6b?D?+gq98yFaLzB4cwY-eC__|Cu}u#}h6Yv!mIs$AwiOXaf2ZPgMbkO;|5~}1_KiY z#siiNOb%8Ij2CPem;!7W7!TMpFbFs^Fa|g?Ff4FpU^H-HU?^~7U`%jlU=Z+NU=Z+R zVEo|2z!2cez*rE(z;GdmfpI}N1A{^Y1LK4U28IU_42%p>3=A7UIGTZRK|BKkLjnWi zf(!-*g-iy<37HHG4?uJd1A{^?17kuy1H*@W2F48~3=9sX42&B|yEes3+tqhC}tqcqdZ43+xIvE%Rx)>M&x)>NQbTcpr z^e`|w^fNFxOlDx*FpGiV!z>2IhB*uj4f7co7A#_5WLUz$?691Hk&%Hh5R&8(Rs-p!5Z(IJ$jER--Us_P}TqNhA*Fs2UKr=MThw5E~i4fZAUG zbswl40QpD3527A4wgTc`2!!wpLLl^mPza4|7Kr^J3RQeT0xJJPB7_ff*B%`10+}_6 zM?+vV1V%$(Gz3ONU^E0qLtr!nMnhmU1V%$(Gz3ONU^E0qLtr!nMnhmU1V%$(Gz3ON zU^E0qLtr!nMnhmU1V%$(Gz3ONU^E0qLtr!nMnhmU1V%$(Gz3ONU^E0qLtr!nMnhmU z1V%$(Gz3ONU^E0qLtr!nMnhmU1V%$(Gz3ONU^E0qLtr!nMnhmU1V%$(Gz11N1TKAo z>djRc62b~`QqCw|QfM_|Wd_z7&e?cCE4k&=o3Q#&A2g1JqRcG)T z!f&_>p*OsQ(4cc8K;{PAf$$S@p)}N-4@D3@===}>e(9|{;z zOfZGm4Y4|@G!2LCrln~)`Q;!NtRPFjSw(SrYDu1JKynU4!waZO{*!A|K`F>6Z;)9M z zGFOI%2@uDHc%mmmhK3cW?guG>djRU#Fh4_s`1s_Cio~SMGD9PS`1s$%!DDV8eJAWY&JA1$&ZH=*OdjSu9JSyCgV5HI5j`bwG6K*pkgH+ zqzuh6BXE8-Fpf{k&(AS5ijOZTDou?qOUx++MM)8=myP1%i}JyRT6%JdC%Dpyk1sDu zEQrr6NiFgWK#px!S6A1N_+V2gVkj;^2|eTZ_?-Om)S~#L{L;J>&!7Oeq#$o({lUiZ zu9!A}Qw^91F^CU#1fd}B5X1P8cvRmT!(Ez_npQ%BQ!$JwE=f$vNsTYgFDfC;m9DO3 z5I2UzgZyC%3L;R-hgH$Rj`6OBrYV_eX{kl2dC94ebQa(j>=JKi0FD5NNDhXRN(%~T z7jTdQHZ3zJ6?feZs@{rH6I0@I^HV^{1T|)fGQkLxa576$$v46zzaTZwHNZPL3oU?% zvELM2lA-4r6L_jA%1qB7DcLj#pag>5un z0hxiER-9T?l9``JS+Zt8^R#)qODeR0Pjybr$w@6TGLMf>$&XKg3&&?9=B0qL6R5}! zD9c5SI!psB!TOUEb8=h*&b#)DPjfa+NZt)?8 z@xkuII}B?H4+;X1V^IBX7VqjBYyq>$5^R$rR-4jOOX5pXa|`l|5{oM1lS)B_DN3UQ zza{e0*_1PG$*I&@XG{ovzTl^31%H_@LC{(%e*r2@J&?kZ~YrCkRx^L;6zS&T)Kler|4lo~KWep{pxM z4m?&6k33)mYSb_k3!s={2I_U?q*`Vq7RRS0Ca0EwlD|Pbcwk}zL$L%_#ihlm*c4kp z6bF|W8s_AuXC}vkhpC*6Kus}_`*$$H6o9)v(6mNisLBZ9>H}oxEh=^m$^=<_164DT zgC5RMs~?c1+Xbro028vOp~3BJ=o;i5Y!DA}+zD(7Amcs^#V=4K;Ugg?nR%Hd;C2r~ z@dxZmOp|j`6N_B4Kvw)fQ9^K}1m^SxW|-6A!#U2N;fe_i#T^i-;1bJ{)S}$Xyu^~! zGLTI>z~b@A6^Ze%_FjByMRIBZs7(n{Z~&noDK$MaFFrZ3Bsl{la{?g)YSqP;=A~8? zq$Zc7rhsHGAY@bXKx1Q2T{jToX+^22sFpoINP=?%$e7 z$p@#HA0Q5FP=lekfknt6J}oV$v>5Ev4lozg%K&Md0Ol1GW#*Nnf%r4Pd{8e4#9IL6 zfphQ*FsC>*H5(+g0nW<@ad&{ZC8;?%VD14hx4bB`1g!N0h?@%zRFL8eU~Xz|azQ1C zdjrY^wRJ)K2T*=-Y6)lrhB2Ojm4PXqK`=KlGmqf{69ZFjMto{TYI12wYJ5g&B50sS zGm1f%2{hi!V#r`;#ITvskKrm)2t%_t1Cx1jer`cxQ7U}ErWmb9ZWzz7j?onCR%A8M zVjEU*A$Q_YM_<7Gc2{sYahi#l;Xoz>1Ct3T1YJ^d5-T0^Qd~g;-T_7VpprkpJ2?o= z*^bS52mIaMW*h2$(XnqSX9{(XLY~my2 zUS!pMd@L**nwc0Fm(!qPB@iGhV>0hqk748(r00z@9T2O=*#U}9ik zF<@9HI6$5J7SRFk*>{N!((b${0~0x8H~$3VF%{2jPPl40FZdbN3AY#2J`~ z9h~?i4(&4IZwRG=t=de2Xg)x=tGS%OFlZc4DQTxeopU}1UD%)-EMAk$z2 z%LHbHf&_&IMu7v&2_IMu6chwD@F_q*!UQG*0|f2q-i#8VDE|I2afN7&s^x7z8MQj0;du2vB&yXduwQ z7+|1a5MUtifKkDqfl8z(61X^}ts0k8uM3Lw@`U<}y6C?Jqv-~h5m z!N33%Bn?ak4U7xe6%-5{3=#w!KtTd_JIGND%nk+y4IBmsm=!*72!NG4K!QlYp@D4y zn}C9VLIEhC53ng1d|-5Vz_@_%0Mh|x0|SGC0s#ewfCr2Y1_ln`csDQrDKt4_^7~~im7!E-Bv!HwjD~S3{Q1t>f5dH@!KfxZt*A|1AKLN^5 zhVnN+`Q=dl1t`B8$`^2l=-&$E8$kKbq5J?SUrroiegTvp0_9JD^4p;N4N(3DDE|VK ze-Fz40Oc!6K+Fs9fY@IIS`Ao?pMA>pY2 z<*$eGFF^Tkq5Ka}zOocVeSkMaefjV z!f%A~F9bsPm!SND5C~sY2BQB#D1;vi<$s8R@Ml5!3lbpw>rnoML3Vv5cLI6em|6d0m{D$M7|Oo@ z|3!!|442XFvp?n7@|2dQ&0OgA)Li86v`R-8u2PnS*%2&vQn0E-uH-Pdv zl_2^PpnQ8Me*%=>0OenR^7ldc3|SEK?m+nlP(F_`#JmP5UkA$H0Ok8Y`5&PC8Yo{N z8)DvkDBl6fKLO4qs`~y(FfC|LE2T;BRlrNA2F|QcPH-PfjL-`3%{wpYd1C+0( z3Nh~jl%ELYe}M95LirBRdzG%j_|SWsK12BpP`kP%6|;y7eM*O8j$>S0m{$NfSC877-HXi zC|{ri!ru<%8$kK2nh^aBP`;HWME`|yi26tT6p9bX%K>4?z`~)apTnnOq0hDh8 z|{xK-u0m^?0KmZ^3Vn!q6QKN^Q27l| z{(Go=0QCMXbpwe02~d8D0aSk@#Qqsjd4VPf{}hyO0Oh}c@)MwZbwh}G4N!gpl)nMW zZ-Md;K>1Ig{0C4zhY>_SLo>uaS14Zr%I|^l4WRtJP`(3{{~gM2fbxxuA?9s>^7Ekl z3sC+tDE|SJf6W-;e}fi?{d^`6{S2)Tems0S z0m^TM@*UbB=AVP|1E72nGl=>LP<|qmzW~Z#1La?U@-IR82JH~@en9yXpnNHFh=`XTONw}+@Nm;m8>LHQG){C0atcrAePuR!H5 zK>1n@5d91jA^NkRd;=(d3Y6~v<==3Cm=^%$D>_2>1yFvTBgDK7Q2tXW{{fUQ;{=fx zm;|ve0m?Uk^4B;)%yWS9ze42`pnPLzh&%)IUcq8#hiGg7@(xhG zC6pfk7Ef{0mUNOAtiA z!2*c>=}^7{l>Y(BPk{1yf+6Y)pnS7nNO&%Q@-v|F3JW3T&4cm-p!`Qr{sSmqBm`m} z!y<@!KPbNe%HIv;Z-DYOLLuq}7DLpxL-__!{z@p{0m{D}3UOZnlrI_v(f1CP5dQ=$hv+{DmA?SxD@Q@}e}MAipnQQ95cPARd;=)|43zHx zM8mj&Rl%Jji z(a*3BV*cVJh<*bo|07gB0LnK>hRA<_@+*@e`VFA>?;eE88*G4>$CLt*-vH(NK=~J- z{7Fzg!$yeuzfiscl&_Nt(eD7|mqGanQ2vQjhH1k8$kI=c@X^xP`*Eu-vH$= zgYpkR`4^%54^X~BK19F3E{ORaP`(3{KOM?X*awln59K#N`FsTs{R^OcODO*Wl-~j6 z3+#vJ{|)6kK>2xvQ2kK;HYk4sl>Z0H{{ZDD7eUlB9DtbD4dp99`S+oG2Pog97@|G_ z$}fQO8=(9nQ2qoc{|}UZ0m|1bf#_#|-m{$vQ=ohYDE|PIp8(}Qhw%?X+$&rP zF>e8sZvf?Afbvg5`3%r|yZ=D>A5KE_Ta-ccH=Kj;YoYuJQ2tgZ{{WQ#0Lp&=<*SrK z^edc)==X>61EBmID8B&8XRUy!-vH%DK=}`#{MAr?zy*kTU!eR1DBrpgqJIID-wEY! zfby?G`46Ccjw*Z_rA11SF*l%D|QbF@IzPk{1$q5K0-em#``0Lotl<$r+kjani4 z6<$E>>w@wfpnTCbh4XF&NpUm^Cd zf%09T`~y&a1eAXT$}fQOUqJa&p!`2j{vIe_pc~@93sAlal>Y$Aw}A4$K>0pUKF2qR zdlI009Vov9$`66^JD~gwD1Q!=UjyZDfbu6m`A4AqB~bniD1Qf({|3rG1LZUHK-~WT z$`^t1S-wNurvc^bK>0RMz5|pW0Of~3`6*C-29#d`<<~&@Jy8Ab46GR@g+?t<}fuR68|LnuSzyRVOFoD=t z0_6ul=d1TY`5&P2EQ}!a4GaO$_OmmTp8y?Ss)h15K*!hDL-`HR`6AGoO@77(h63n( z6AKg6yaI^*`cS?Clpg@)2SDeu3ZeW9Q1hli`3Io$A^V|xgVzxA*q9;aH$dx~WGH_F zw0v3tI0zl)ifwS0Xlzn4aSGMPn;E^{sVM=DhSG7-~+M08_F+u1>s+W z@&!&o_*rZa{STn+p#xAp19bfJKa{TkKqVxhX)Y(eNaBb zeF$HT6Cy9L6T(k}@*SYb6^MKZ7exI5X#FnA4dFXL`&-RWegJel@(q-~06O2| z&BMUJ&)LB60-7G{q5J?Se+!7u*1)g_n%-YP`8`m+EHB7D0njD^aQZg{^BEW(K-WK* z^Mc(8O4eXC?hrmGtAP3KX#90({HtjE_h@_$KCt<4^K8-hMQHrxX#Bfqdh zQ_=WW(D>W}sQR7I_%UewA~gOiH2yX;{v|X%lOU>nVrYCVG`IH@$Jy~GE58%vP=vNa!d>i@=Od2pBWh#zA!Q{dl_`T9W^Rk%8eSBLl-PMh1r8j0_Ba85tPCI$u`CI$vx zCI$vRP+i5uz#zcHz#z!Pz#zoLz@Wp#0NxWN%*4PT!omgCY|H!yiTl20bPQ24f}$1`{R*1`8$z21`gRHZU+SfUz|b1A`3{1A{FS z1A{jc1A{LU1A`yb-Z&-(hS9JmJ?s@2;^U(Xsk6@wWD+s^>f+<0jHt7X4P+AKo9aL( z(V^{kBV}U;7VSiCAi<&&%T68SO(Y;4kUe??PjJGg6m|0w9+l`jpKvRM?y#Cg~Qy&RvR+j|zeB0wi+R9f}@e_w<1@!M7fg zU=dso@fKm8DH0DpZzMh*^(Z4y974MgpaPQQLyVC0L(kK}dVCQUW!Mfb0x83OWD!&b z^U!UG1PO;2fzI0|Srh1}9g;PHP8}ju6XcvEBwa)vkOV)-n{=(nXLysP8*ywm>Dp0_ z>?U11_*^K`wSiAnLTH1gT=+>)7&71^pb(QK%kx5h`4U2wW@tGBKI$$$J}L!t$as8w6zE)W5LKQF z3Z1<2T(r}}<3Z;`V?E{zDuaB!7gPxSU@xdJ;zTc~0NPPrP*KPkUh(nR4k|}Eqa1vs z7m5hv)N-&8;ff%53xG;`Jhh!XZH9}k^>ud-*A}b3NAF$)h z38uBY64x@4G$fb#f)2n$8A@_>D=Tw_ngbb8gSGXrG>R+>N{ch%lM<7&U4y()9E(Sj zX=-jkNhOLEhQtL5w7db`CXkmN4^Cn5GwHw{M|Cis<|2y2gAL=sx}gmfn9~WhZB3v@ z)`Q}fM6H<>uHdZZV`vob9~@ksSm2pgVrW(Zat4Z+u@NLxQ9XtwCcvllfn0*B5>F7| z&_T%8aBXN_#$yw5KoRXcSP=Q4>cHZ4xJon^VNr_PC4{_5qGK!}0FCO}hgv5S(Ch}CMGnwLVBMram{LW>qW zv5!Lsme@g4No=72Z3m;*h$Iy$F#iy1CyrW}NIRjrp73P4o4-+z=Hf@&;=AGX$ASko}kfm#DzYt$R#szZZs*b%mdvWM5EW?^Y+d_hT(r+IvQv74ulYk*rO zlP%}FguEs8Hr%gjqm z^$Z4`P#+Nz4>{jBJwHDszNjoQC%z~(4RRp{vQO~3#=IysClz#~5Tt1YDPaxqYC+Fx zcojPv(bu;=CZLuk=xqAT09eqwy1M#~y?bZ9M-SK?E1Qgc1w!Q+!@;OdiP;OgoO zaZMT64kRNG?f@lXgiG)_#S|8@Nao;niW^d7`D7ZxofB*lkKr1k0@gGwv#1!>-iIV= z+_uAf1P=()`1tfxRNVx!1hkTc6&`rAglSP~acT)D_alW3QNA)OPEF27YnkBo7S=$; z;x!*j_+TKYm!`sw5at05Je5*nNz16DvG(AU+E=jt@3QHXAAns|7r1=LM=6hUo-)G<(XM8|wV zK}iv+6~t;aEdXDZhhi;eYBhkgCsp(`p*#uK7P8XX& zt~7u+*gHAcG#=b*h7E`i9ZIR777#RqA&J4qI5#uTGZ!OUKm!7&i;Ob!kX#cKYzhiU z^Y|dt+7)U#Qnt#?B`RCx=DLEjRW53_BHE+rNu{|3&}JUgD@5x}MM{Q{Kq6Xe0j9M$ zL(n+C6q*9T5sE7aiM882J|1Fw4pNywaHI@hvU>6*{qr%q%^%BqtxW=Z0{+v!Sc6U$8;E zX?%QMVhJ?&LE{weLuVtLiik@sps>tM%ubEZO(`xZ0#%fdRDdfilTpJ9o=nhF5lla! zIUy5p4-%!Oft!g%4iP-bWxgQ>@geb^pn+vjYC|1vMs=p4aeO?|B(W!!Q6kIuc*rC| z0ZNGu8~MVb1JZ(oUZ@qHpO+e+SOPM`(<{gubbUmbOM!m~aL~mhTSO^Qk0lioR|!{rv)@88Eg!#Rv~HD z&{K00U`0hM#zzb=(K@j5l^qt7)w`;^q@i;6(HRJXCqh8y<(6i3^aU* z32V@>6IyVCvXOaaUP)?tQDRO!STZrM#4`zeBa|zS$UwSxH_H_{0$p9p0>vy26I8u8@iXB@K`s!0^#dXqkq`1W=e3r6%X+=7I*oQKAI>I=C#* zU<69oxw<+Vy5^#_(GbZIR21MzjYe2fqaiVt!V@52?^z@#79=KTqRp~FdV83SUJ}wG zV$FS!H!M3sokK*?jWw?un&g${rWR!;$LD0`g08L4aRv2RQPKiYWfJJxarjNr1ab(v z<5A)l;YpP0j@a@XHA_H42T}*+A`iGhMyW{36Gos__?bz`1qJcwfd>69LvD0@N-=G=p40 zgO{KIMf71*VyXZOXqB7_F55{iuF&!wG^7!3gEYTE^*C}3Kuic>qyT8>VodbD`|;IUe4%_!Wg1OI0uWLK#>d*Hl%a_8)OJd!Q=|5FCin@ z!N!6u@b&Vpu6ZTJMWD_l=vq*4OA>tTaIjH4sKpJse;J~%xX9Qr zvpBw_D6=dxF(;=Id_^*(=?T)1nUs_23BIlwqTIC%I`IT*j0RhR7C8h3TcWhzO+eT3 zdIo@souCl-z%;aQ!WYOU@$reUK+a1ohb*Om&P?FZ2U@|MnOByWlbHgFp2VCS_^sE) z&{!gDxv?RV<;nSZC7J1^`K866fGA1K%u6kD4e&0544ns?LcB}ZP?MCzl0>KzAn6=F z%a=vW)E?@50Wsw^yr~Saj;Qu0bR{WrNkU}13~}{4xc&;rf|MfAfFa6q^hOE^?gnM{ zlvK!d+R&cAYXD^Mgkn>0=P(0TSCj=1#8mUmeqy0YEX)z!!_9_JXB329?oP+MGGkq1gZi}sA-!J}QqpxQCW8~A!A>t^R|eE6W(xDc*Yz|u#7nnlkBhuD10D-`1Fh2An=G7*)ane z!$E1VfTv-~2$gtPqYkM|gM}y32pJ?lfL1pVGfDu5T1gx5}_(V zEijDk7Ss{g(kN;+ff|Cd_CPfOYAmjN0yT_;AV!aA(oMjq_hCk0Yj!~0kLoE%PC=#JT!O?L&HyIp17gReprMOq9_}K6n5r9;++jl~ zkfqls!w)3XASR@aR)Je-pyG|X<5l2hU9e@mt1Dyxim34_gmR?uD&zQIM-U1Mc7zPz zKqA@)I$i~h4p28B1in-gT3!$n^u&x_LG1vA60~?jbaKFl#E>$Ig~u@BMzhR7dzFIC zAb~-=Pw|XuL7ha**cNmU4H5?=Rao#QEg5>r8S8?3$`xf$1T^O#5NrhPe?o(gB#)rC zK*;b9sHg)EE|n&iz{kK)*T<6NBwXg49KM)GF0c**R(U5?pEIf@$tOlX9Dj`V= zR*Yd;?}4_;5WO8uSO;kC32B8FXctOueja!ajVrq0*t~+x21B$~B`8uYK%0)z5=(PR z;xqFyOX5os(;>5k=uJ&xEkSQ^kzxs=LyK1zD1NZDoJg9;M6EQkkUB!nMxecHhS)*| zd$P?!j}bfx1HH6G8y3Y9ZKUhKRw@&=2Wwe{JpK>!6*Rk{1|X!Jg`P6eY$ZV_w&aFS zJJr)RKFcUc<2W0_sNo5Up#^|ae-nBG0PAr3<+}E zOC&4+K=u-7lmp4PkbI1P6#%k!ymL%MEd@X}4Xb0&5*n#l3o#2$aB3gfDcEuX_8OhU z>X%BB{K#%aTE0MdrXN`&Hcz5fd4yVYs3strjnx0aQsiQcZzF5Pnhc1Y@g{5#dS4dD zWG%@F4LUhQ#N0PQH)2m|=u_JSjlt1U05vKxR)7#R45OEfBixWGD14~{Z^=Q)>@>1R zV2O~ZDQXmrq|H+!YsH#+QF9ff%EZ}lK{El_a3l|5%TPI6(5%TUlH7544r@L624 z0|cXjfSE+Cf`sU7U>F|{K2RgG1hi`hbxa-9v@I`6ECBBi@lh(SEc{t^?& z5q`+2ItS!Z@HXurZ{*W)P)>S7*5DT$Z)6%DUzA!>T9g-GlA2qPUzAu>3C%H}UGLy& zTD0S#vD%y%?22gnLPH7p%s5i4g&rpdnl4A0rX<@J@WwqX;h_XPYE*;Hb4^8A8HLri zpmpq^9p%&tXZVqlkhV26{0LFF9F)2jbodC$Y95Ni97`+J$H*8* zsfOPzKA=--F}AS9m*#DRJ?-< z3UUq$Hja071s@g++Q*!O^PFH5yG`Tci&IO`qdzwQB`xBtWU%=KUa>&RYgoea!v+GRXW%ZRKp<^Fmw#Y2=kx})N%;Cq&gY3 zPl!=3k(4&EpE{1>MyRFW_5t?J7H9=3a=}VY8pKxPqc{Un4!Y)oB8WI=kW#**_rgih zi=*97PAH(ZQ6S|rY7!v3Re~?^VQGn=+G-geUr>~v3_5rjIp;&t9`P}Pr{REh$f%Eb zVoF(JUUDjE#Vo#38+6=ePzd<=ep65f8TmLs&?qcs?-VJe`dFl77MBod4al1qR$%S_ z27@;uAlqXGxiy*y&xFLI9?Aht17=03WvNBQso;J-$d9OXA*ct9*4M|>0rCKz7yvbL zK!-mex!WQ>J~OW@wWtJijDHg9q-rpzG2?9L3fpf1aVWGgfl~Zp*bAg27L*nbcq|Vzyoa(Er?|*GvpBvuF&C0bjG(s)fcIJ>ZWI8IK*09e7+Ij4 z4U?Q-P#K?CT%4H>K9j~X*c`qu$29=Nft=zW06Og4DL&W&vb6;2RnX#u(mY(FFRqBA zVsNNO%}Hp!D=s47R8U(A;w#qxP+UM<|H=(30S69Da!+1=WfI?9(uy9 zhoC!=je+39=}E7)k%3s4C89An@X zOB55d7-R@ae~w@V0qKD5w1Y$!zDgQxovx2%d_2vnchJz1Sy5tMN`7v9Vlt@70qSUfM?n^^s@U=>?qxcBA7N37X zLsY1yA-7k+H6vP1NlYB*2ALt~q`vr~#Ju#>V#+*k06OhEJwHA@IR#WEgv19Mf)G-Y z!r9FRWgUF8Q{b+qyR&nAY6a+w#P|}>X^4gl=psfKBIXz(hGrN-My41-#+Zg18)K@% zG|L#%Mq>*Mjiv?|LS~pY8X8z)C^Iy~^rRscKN%XCVCu!CYW(#jKzJ% z=9n>VY=OmI3oPbYV1|LQC1zNeU3DFb+J-d@6P0l20G5}X`=oh_!yJ;X#AzThsg8w#7 Ski)^3JQoyYmL-;?G5`Q4*EXvF literal 0 HcmV?d00001 diff --git a/scripts/tools/Win32/networkSimulator_g192.exe b/scripts/tools/Win32/networkSimulator_g192.exe new file mode 100755 index 0000000000..c17aff5249 --- /dev/null +++ b/scripts/tools/Win32/networkSimulator_g192.exe @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b81ea0575fb6b40f48c22b59f90820774054e82708750f9350cf9c0ec2674231 +size 578574 diff --git a/tests/README.md b/tests/README.md new file mode 100644 index 0000000000..6ba72e4ace --- /dev/null +++ b/tests/README.md @@ -0,0 +1,173 @@ +# IVAS tests + +The IVAS tests are using the [pytest](https://docs.pytest.org/) framework. + +## Installing test dependencies + +To use the `pytest` framework, you will need a few Python packages (in addition to Python itself). +As with other Python packages, there are different possibilities to install those packages. +Please chose the option that works best for you. + +`Note`: +The installation of Python is not described, here. +In the following, it is assumed that `Python >= 3.7` is already installed / present. + +### Global install + +```bash +pip install -r tests/requirements.txt +``` + +### User install + +```bash +pip install --user -r tests/requirements.txt +``` + +### Virtual environment install + +```bash +# set up virtual environment +python3 -m venv VENV_NAME +# change to virtual environment +source VENV_NAME/bin/activate +# install required packages +pip install -r tests/requirements.txt +``` + +## Preparing the tests + +`Note:` +Currently, shortened test vectors are used to speed up the testing. +Those shortened test vectors, some with gain adjustment, need to be created, once. + +```bash +# create shortened test vectors +python3 tests/create_short_testvectors.py +``` + +The tests rely on references which need to be generated upfront using reference binaries. +When the reference binaries are named `IVAS_cod_ref(.exe)` and `IVAS_dec_ref(.exe)`, pytest will find and use them. +When the reference binaries are named differently, you need to specify them via the `--ref_encoder_path` and `--ref_decoder_path` options. + +The tests will use the binaries `IVAS_cod(.exe)` and `IVAS_dec(.exe)` for testing. Please make sure that the binaries have been built before running the tests. +When different test binaries are to be used, they can be specified via the `--dut_encoder_path` and `--dut_decoder_path` options. +(DUT: Device Under Test) + +```bash +# create references +# the following binaries need to be present: +# - IVAS_cod(.exe) +# - IVAS_dec(.exe) +# - IVAS_cod_ref(.exe) +# - IVAS_dec_ref(.exe) +# pytest command lines to be executed from project root folder: +pytest tests --update_ref 1 -m create_ref +pytest tests --update_ref 1 -m create_ref_part2 +``` + +## Running the tests + +To run all tests from the tests folder: + +```bash +# pytest command line to be executed from project root folder: +pytest tests +``` + +## Re-running some tests + +When there are test failures, you may want to run, after having fixed the code, only those test cases which had failures. This can be achieved using the `--last-failed` option. + +```bash +# rerun only the tests that failed at the last run +pytest tests --last-failed +``` + +To run a specific test case, you can e.g. pick a test case from the `short test summary info` and use that test case as an argument to `pytest`. E.g. + +```bash +# run a specific test case +pytest tests/test_sba_bs_dec_plc.py::test_sba_plc_system[0-48-PLperc12mblen5-stvFOA-0-32000] +``` + +More ways to select which tests to run: + +```bash +# run all tests within a module +pytest tests/test_sba_bs_dec_plc.py +# run a specific test from a module +pytest tests/test_sba_bs_dec_plc.py::test_sba_plc_system +``` + +## Some pytest hints + +When there a many test failures, you can use the `-x` (or `--exitfirst`) option to stop testing on the first failure. + +Commonly used options like `-n auto` are added to addopts within the [pytest] section in `pytest.ini`. This saves some typing when calling `pytest`. + +The `-v` (or `--verbose`) option is helpful to see what is going on. + +## Custom options + +`Note:` +The custom options are listed as part of the pytest help `pytest -h`. + +```text +--update_ref=UPDATE_REF Indicate whether references shall be updated. + 0: Only DUT processing, no reference generation, references need to be present. + 1: Only reference generation (unconditionally), no DUT processing. + 2: DUT processing, references are generated when not present (not supported by all tests). +--dut_encoder_path=DUT_ENCODER_PATH If specified, use given binary as DUT encoder. +--dut_decoder_path=DUT_DECODER_PATH If specified, use given binary as DUT decoder. +--ref_encoder_path=REF_ENCODER_PATH If specified, use given binary as REF encoder. +--ref_decoder_path=REF_DECODER_PATH If specified, use given binary as REF decoder. +--test_vector_path=TEST_VECTOR_PATH If specified, use given directory as base directory for test vector files. +--reference_path=REFERENCE_PATH If specified, use given directory as base directory for reference files. +--dut_base_path=DUT_BASE_PATH If specified, use given directory as base data directory for dut files. +--param_file=PARAM_FILE If specified, use given param file in test_param_file. +--keep_files By default, the DUT output files of successful tests are deleted. + Use --keep_files to prevent these deletions. +``` + +## Helper scripts + +To help with running the tests during development, two scripts are available in the `tests` folder: + +- prepare_pytests.py +- run_pytests.py + +The envisioned development workflow is: + +```bash +# 1. create a new git branch and switch to the branch +git checkout -b new_branch + +# 2. build the REF binaries (here: example for Linux) +make -j + +# 3. use the binaries to generate the references for future tests +# assumption: you want to test your development against the start of the development +tests/prepare_pytests.py +# Note: the script will use the binaries IVAS_cod and IVAS_dec in case IVAS_cod_ref and IVAS_dec_ref are not present + +# 3a. (optional) store REF binaries in case you want to re-run the reference generation at a later stage +cp IVAS_cod IVAS_cod_ref +cp IVAS_dec IVAS_dec_ref + +# 4. do the development changes +edit ... + +# 5. build the DUT binaries (here: example for Linux) +make -j + +# 6. run the tests +tests/run_pytests.py + +# 7. depending on the test result +# - either go back to 4. +# - or commit and push your changes +``` + +Both scripts allow to restrict the reference generation or the testing to test_param_file tests +with a custom `.prm` file via the `--param_file` option. diff --git a/scripts/ivas_pytests/tests/cmp_custom.py b/tests/cmp_custom.py old mode 100644 new mode 100755 similarity index 62% rename from scripts/ivas_pytests/tests/cmp_custom.py rename to tests/cmp_custom.py index e52d6df46c..ab22bc0ceb --- a/scripts/ivas_pytests/tests/cmp_custom.py +++ b/tests/cmp_custom.py @@ -1,35 +1,37 @@ #!/usr/bin/env python3 +__copyright__ = \ """ - (C) 2022 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. +(C) 2022 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. """ +__doc__ = \ """ Script to compare samples in 2 PCM files. @@ -87,7 +89,7 @@ class CompareSamples: self.file_1.seek(0) self.file_2.seek(0) - def print_summary(self): + def print_summary(self) -> (int, str): """ Print the summary of the comparison. """ @@ -103,19 +105,18 @@ class CompareSamples: if not self.diff_present: print("Comparison success") print("") - return 0 - else: - print( - f"First unmatched diff ==> {self.first_diff}", - f"at sample num {self.first_diff_sample_num}", - ) - print( - f"MAXIMUM ABS DIFF ==> {self.max_diff} at sample num {self.max_diff_sample_num}" - ) - print("Comparison failed") - print("") - return 1 - return 1 + return 0, "Comparison success" + + # comparison failed + print( + f"First unmatched diff ==> {self.first_diff}", + f"at sample num {self.first_diff_sample_num}", + ) + diff_msg = f"MAXIMUM ABS DIFF ==> {self.max_diff} at sample num {self.max_diff_sample_num}" + print(diff_msg) + print("Comparison failed") + print("") + return 1, f"Comparison failed, {diff_msg}" def compare_next_sample(self): """ @@ -146,7 +147,7 @@ class CompareSamples: def usage(): print(__doc__) - return 1 + return 1, "" def cmp_custom( @@ -155,7 +156,7 @@ def cmp_custom( sample_size_in_bytes_str, tolerance_str, end_samples_to_skip_str="0", -): +) -> (int, str): """ Function to compare the samples in 2 PCM files. """ @@ -189,10 +190,11 @@ def cmp_custom( return cmp_samples.print_summary() -def main(argv): +def main(argv) -> int: if len(argv) < 5: return usage() - return cmp_custom(*argv[1:]) + retval, _reason = cmp_custom(*argv[1:]) + return retval if __name__ == "__main__": diff --git a/scripts/ivas_pytests/conftest.py b/tests/conftest.py similarity index 57% rename from scripts/ivas_pytests/conftest.py rename to tests/conftest.py index 2cc74689af..da1c26e54a 100644 --- a/scripts/ivas_pytests/conftest.py +++ b/tests/conftest.py @@ -1,31 +1,37 @@ +__copyright__ = \ """ - (C) 2022 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. +(C) 2022 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. +""" + +__doc__ = \ +""" +Pytest customization (configuration and fixtures) for the IVAS codec test suite. """ import logging @@ -35,7 +41,7 @@ from subprocess import run import textwrap from typing import Optional import os - +import testconfig import pytest logger = logging.getLogger(__name__) @@ -54,75 +60,104 @@ def log_dbg_msg(message): @pytest.fixture(scope="session", autouse=True) def rootdir(request): + """ + Return root directory for tests. + """ return str(request.config.rootdir) def pytest_addoption(parser): - parser.addoption("--update_ref", action="store", default="0") - parser.addoption("--p4_CL", action="store") - parser.addoption("--p4cmd_active", action="store", default="0") + parser.addoption( + "--update_ref", + action="store", + help="""Indicate whether references shall be updated. + 0: Only DUT processing, no reference generation, references need to be present. + 1: Only reference generation (unconditionally), no DUT processing. + 2: DUT processing, references are generated when not present (not supported by all tests). + """, + default="0", + ) parser.addoption( "--dut_encoder_path", action="store", - help="If specified, use given binary as DUT encoder." + help="If specified, use given binary as DUT encoder.", ) parser.addoption( "--dut_decoder_path", action="store", - help="If specified, use given binary as DUT decoder." + help="If specified, use given binary as DUT decoder.", ) parser.addoption( "--ref_encoder_path", action="store", - help="If specified, use given binary as REF encoder." + help="If specified, use given binary as REF encoder.", ) parser.addoption( "--ref_decoder_path", action="store", - help="If specified, use given binary as REF decoder." + help="If specified, use given binary as REF decoder.", ) - # TODO: rename to test_vector_path parser.addoption( - "--data_system_tests_path", + "--test_vector_path", action="store", - help="If specified, use given directory as base data directory for system tests." + help="If specified, use given directory as base directory for test vector files.", ) parser.addoption( "--reference_path", action="store", - help="If specified, use given directory as base directory for reference files." + help="If specified, use given directory as base directory for reference files.", ) parser.addoption( "--dut_base_path", action="store", - help="If specified, use given directory as base data directory for dut files." + help="If specified, use given directory as base data directory for dut files.", ) + parser.addoption( + "--param_file", + action="store", + help="If specified, use given param file in test_param_file.", + ) -@pytest.fixture(scope="session", autouse=True) -def update_ref(request): - return int(request.config.getoption("--update_ref")) + parser.addoption( + "--keep_files", + action="store_true", + help="By default, the DUT output files of successful tests are deleted." + " Use --keep_files to prevent these deletions.", + ) @pytest.fixture(scope="session", autouse=True) -def p4_CL(request): - return request.config.option.p4_CL +def update_ref(request): + """ + Return indication whether references shall be updated. + 0: Only DUT processing, no reference generation. + 1: Only reference generation (unconditionally), no DUT processing. + 2: DUT processing, references are generated when not present. + """ + return int(request.config.getoption("--update_ref")) -@pytest.fixture(scope="session", autouse=True) -def p4cmd_active(request): - return int(request.config.getoption("--p4cmd_active")) +@pytest.fixture(scope="session") +def keep_files(request) -> bool: + """ + Return indication to not delete DUT output files. + """ + return request.config.option.keep_files @pytest.fixture(scope="session") -def dut_encoder_path(request) -> Path: +def dut_encoder_path(request) -> str: + """ + Return path of DUT encoder binary. + """ if request.config.option.dut_encoder_path: return request.config.option.dut_encoder_path @@ -130,15 +165,16 @@ def dut_encoder_path(request) -> Path: system = platform.system() if system == "Windows": - path = here.joinpath("../../IVAS_cod.exe") + path = here.joinpath("../IVAS_cod.exe") elif system in ["Darwin", "Linux"]: - path = here.joinpath("../../IVAS_cod") + path = here.joinpath("../IVAS_cod") else: raise ValueError(f'Wrong system "{system}"!') path = str(path.resolve()) - assert os.path.isfile(path) + if not os.path.isfile(path): + pytest.exit(f"\nDUT encoder binary {path} not found!\n!") return path @@ -163,6 +199,7 @@ class EncoderFrontend: agc_op: Optional[int] = None, bypass_mode: Optional[int] = None, quiet_mode: Optional[bool] = True, + add_option_list: Optional[list] = None, ) -> None: command = [self._path] @@ -185,6 +222,9 @@ class EncoderFrontend: if quiet_mode: command.extend(["-q"]) + if add_option_list is not None: + command.extend(add_option_list) + # add mandatory parameters command += [ str(bitrate), @@ -221,6 +261,9 @@ class EncoderFrontend: @pytest.fixture(scope="function") def dut_encoder_frontend(dut_encoder_path) -> EncoderFrontend: + """ + Return a :class:`conftest.EncoderFrontend` instance as DUT for the test session. + """ encoder = EncoderFrontend(dut_encoder_path, "DUT") yield encoder @@ -229,34 +272,40 @@ def dut_encoder_frontend(dut_encoder_path) -> EncoderFrontend: @pytest.fixture(scope="session") -def ref_encoder_path(request) -> Path: +def ref_encoder_path(request) -> str: + """ + Return path of REF encoder binary. + """ if request.config.option.ref_encoder_path: return request.config.option.ref_encoder_path - update_ref = int(request.config.getoption("--update_ref")) - if not update_ref: + if request.config.option.update_ref == "0": return None - # assume default encoder when update_ref is selected, but no ref_encoder_path is specified + # assume specifically named encoder when update_ref is selected, but no ref_encoder_path is specified here = Path(__file__).parent.resolve() system = platform.system() if system == "Windows": - path = here.joinpath("../../IVAS_cod.exe") + path = here.joinpath("../IVAS_cod_ref.exe") elif system in ["Darwin", "Linux"]: - path = here.joinpath("../../IVAS_cod") + path = here.joinpath("../IVAS_cod_ref") else: raise ValueError(f'Wrong system "{system}"!') path = str(path.resolve()) - assert os.path.isfile(path) + if not os.path.isfile(path): + pytest.exit(f"\nREF encoder binary {path} not found!\n!") return path @pytest.fixture(scope="session") -def dut_decoder_path(request) -> Path: +def dut_decoder_path(request) -> str: + """ + Return path of DUT decoder binary. + """ if request.config.option.dut_decoder_path: return request.config.option.dut_decoder_path @@ -264,15 +313,16 @@ def dut_decoder_path(request) -> Path: system = platform.system() if system == "Windows": - path = here.joinpath("../../IVAS_dec.exe") + path = here.joinpath("../IVAS_dec.exe") elif system in ["Darwin", "Linux"]: - path = here.joinpath("../../IVAS_dec") + path = here.joinpath("../IVAS_dec") else: raise ValueError(f'Wrong system "{system}"!') path = str(path.resolve()) - assert os.path.isfile(path) + if not os.path.isfile(path): + pytest.exit(f"\nDUT decoder binary {path} not found!\n!") return path @@ -293,6 +343,7 @@ class DecoderFrontend: output_path: Path, quiet_mode: Optional[bool] = True, plc_file: Optional[Path] = None, + add_option_list: Optional[list] = None, ) -> None: command = [self._path] @@ -303,9 +354,14 @@ class DecoderFrontend: if plc_file is not None: command.extend(["-fec", str(plc_file)]) + if add_option_list is not None: + command.extend(add_option_list) + # add mandatory parameters + # output_config is mandatory for IVAS; EVS does not have this parameter, indicated by "" + if output_config != "": + command += [output_config] command += [ - output_config, str(output_sampling_rate), str(input_bitstream_path), str(output_path), @@ -339,6 +395,9 @@ class DecoderFrontend: @pytest.fixture(scope="function") def dut_decoder_frontend(dut_decoder_path) -> DecoderFrontend: + """ + Return a :class:`conftest.DecoderFrontend` instance as DUT for the test session. + """ decoder = DecoderFrontend(dut_decoder_path, "DUT") yield decoder @@ -347,40 +406,46 @@ def dut_decoder_frontend(dut_decoder_path) -> DecoderFrontend: @pytest.fixture(scope="session") -def ref_decoder_path(request) -> Path: +def ref_decoder_path(request) -> str: + """ + Return path of REF decoder binary. + """ if request.config.option.ref_decoder_path: return request.config.option.ref_decoder_path - update_ref = int(request.config.getoption("--update_ref")) - if not update_ref: + if request.config.option.update_ref == "0": return None - # assume default decoder when update_ref is selected, but no ref_decoder_path is specified + # assume specifically named decoder when update_ref is selected, but no ref_decoder_path is specified here = Path(__file__).parent.resolve() system = platform.system() if system == "Windows": - path = here.joinpath("../../IVAS_dec.exe") + path = here.joinpath("../IVAS_dec_ref.exe") elif system in ["Darwin", "Linux"]: - path = here.joinpath("../../IVAS_dec") + path = here.joinpath("../IVAS_dec_ref") else: raise ValueError(f'Wrong system "{system}"!') path = str(path.resolve()) - assert os.path.isfile(path) + if not os.path.isfile(path): + pytest.exit(f"\nREF decoder binary {path} not found!\n!") return path @pytest.fixture(scope="session") -def data_system_tests_path(request) -> Path: - if request.config.option.data_system_tests_path: - return request.config.option.data_system_tests_path +def test_vector_path(request) -> str: + """ + Return base directory of test vector files. + """ + if request.config.option.test_vector_path: + return request.config.option.test_vector_path here = Path(__file__).parent.resolve() - path = here.joinpath("testv") + path = here.joinpath("../scripts/testv") path = str(path.resolve()) @@ -388,7 +453,10 @@ def data_system_tests_path(request) -> Path: @pytest.fixture(scope="session") -def reference_path(request) -> Path: +def reference_path(request) -> str: + """ + Return base directory of reference files. + """ if request.config.option.reference_path: return request.config.option.reference_path @@ -398,11 +466,18 @@ def reference_path(request) -> Path: path = str(path.resolve()) + if request.config.option.update_ref == "0": + if not os.path.isdir(path): + pytest.exit(f"\nREF path {path} not found!\nPlease generate the references, first!\n!") + return path @pytest.fixture(scope="session") -def dut_base_path(request) -> Path: +def dut_base_path(request) -> str: + """ + Return base data directory for dut files. + """ if request.config.option.dut_base_path: return request.config.option.dut_base_path @@ -425,3 +500,5 @@ def pytest_configure(config): config.addinivalue_line( "markers", "create_ref_part2: reference creation test that depends on create_ref references" ) + if config.option.param_file: + testconfig.PARAM_FILE = config.option.param_file diff --git a/tests/create_short_testvectors.py b/tests/create_short_testvectors.py new file mode 100755 index 0000000000..56c41d49b8 --- /dev/null +++ b/tests/create_short_testvectors.py @@ -0,0 +1,66 @@ +#!/usr/bin/env python3 + +__copyright__ = \ +""" +(C) 2022 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. +""" + +__doc__ = \ +""" +Create short (5sec) testvectors. +""" + +import sys +from pathlib import Path +from cut_pcm import cut_samples + +HERE = Path(__file__).parent.resolve() +TEST_VECTOR_DIR = str(HERE.joinpath("../scripts/testv").resolve()) + +NUM_CHANNELS = "4" # currently only FOA +CUT_FROM = "0.0" +CUT_LEN = "5.0" + + +def create_short_testvectors(): + for fs in ['48', '32', '16']: + in_file = f"{TEST_VECTOR_DIR}/stvFOA{fs}c.pcm" + cut_gain = "1.0" + cut_file = f"{TEST_VECTOR_DIR}/stvFOA{fs}c_cut.pcm" + cut_samples(in_file, cut_file, NUM_CHANNELS, fs + "000", CUT_FROM, CUT_LEN, cut_gain) + cut_gain = "16.0" + cut_file = f"{TEST_VECTOR_DIR}/stvFOA{fs}c_cut_{cut_gain}.pcm" + cut_samples(in_file, cut_file, NUM_CHANNELS, fs + "000", CUT_FROM, CUT_LEN, cut_gain) + cut_gain = ".004" + cut_file = f"{TEST_VECTOR_DIR}/stvFOA{fs}c_cut_{cut_gain}.pcm" + cut_samples(in_file, cut_file, NUM_CHANNELS, fs + "000", CUT_FROM, CUT_LEN, cut_gain) + + +if __name__ == "__main__": + sys.exit(create_short_testvectors()) diff --git a/scripts/ivas_pytests/tests/cut_pcm.py b/tests/cut_pcm.py similarity index 99% rename from scripts/ivas_pytests/tests/cut_pcm.py rename to tests/cut_pcm.py index 62af257a73..938cb6fc43 100755 --- a/scripts/ivas_pytests/tests/cut_pcm.py +++ b/tests/cut_pcm.py @@ -1,6 +1,7 @@ #!/usr/bin/env python3 -__license__ = """ +__copyright__ = \ +""" (C) 2022 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, @@ -30,7 +31,8 @@ accordance with the laws of the Federal Republic of Germany excluding its confli the United Nations Convention on Contracts on the International Sales of Goods. """ -__doc__ = """ +__doc__ = \ +""" Script to cut samples from a 16-bit PCM file. USAGE : cut_pcm.py in_file_pcm out_file_pcm num_channels sample_rate start duration [gain] diff --git a/tests/requirements.txt b/tests/requirements.txt new file mode 100644 index 0000000000..2eb090f4fb --- /dev/null +++ b/tests/requirements.txt @@ -0,0 +1,4 @@ +pytest>=5.3.5 +pytest-xdist>=1.31.0 +scipy>=1.5.2 +numpy>=1.19.2 diff --git a/tests/run_pytests.py b/tests/run_pytests.py new file mode 100755 index 0000000000..1fc6614762 --- /dev/null +++ b/tests/run_pytests.py @@ -0,0 +1,106 @@ +#!/usr/bin/env python3 + +__copyright__ = """ +(C) 2022 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. +""" + +__doc__ = """ +Script to run the pytest tests. + +Test prerequisites are checked for and check failures are reported. +When prerequisites are met, the pytest test is executed. +""" + +import os +import sys +import argparse +import subprocess +import platform +from pathlib import Path + +BIN_EXT = ".exe" if platform.system() == "Windows" else "" +HERE = Path(__file__).parent.resolve() +DEFAULT_ENCODER_DUT = str(HERE.joinpath(f"../IVAS_cod{BIN_EXT}").resolve()) +DEFAULT_DECODER_DUT = str(HERE.joinpath(f"../IVAS_dec{BIN_EXT}").resolve()) +REFERENCE_DIR = str(HERE.joinpath("ref").resolve()) + + +def main(argv): + """ + Run the pytest tests. + """ + # check for python >= 3.7 + if sys.version_info[0] < 3 or sys.version_info[1] < 7: + sys.exit("This script is written for Python >= 3.7. Found: " + platform.python_version()) + + parser = argparse.ArgumentParser(formatter_class=argparse.RawTextHelpFormatter) + parser.add_argument( + "--numprocesses", + action="store", + default="auto", + help="Number of processes to use in pytest (default: auto)", + ) + parser.add_argument( + "--param_file", + action="store", + help="Restrict test run to test_param_file with specified param file.", + ) + + args = parser.parse_args(argv[1:]) + + # check for references + if not os.path.exists(REFERENCE_DIR): + sys.exit( + f"References directory {REFERENCE_DIR} not found.\nPlease create the references." + ) + + # check for DUT binaries + if not os.path.exists(DEFAULT_ENCODER_DUT) or not os.path.exists(DEFAULT_DECODER_DUT): + sys.exit( + f"Need DUT binaries {DEFAULT_ENCODER_DUT} and {DEFAULT_DECODER_DUT}.\n" + "Please create the binaries." + ) + + # run pytest + if platform.system() == "Windows": + cmd = ["pytest"] + else: + cmd = ["python3", "-m", "pytest"] + if args.param_file: + cmd += ["tests/test_param_file.py", "--param_file", args.param_file] + else: + cmd += ["tests"] + cmd += ["-n", args.numprocesses] + + result = subprocess.run(cmd, check=False) + return result.returncode + + +if __name__ == "__main__": + sys.exit(main(sys.argv)) diff --git a/tests/test_param_file.py b/tests/test_param_file.py new file mode 100644 index 0000000000..730acd5c00 --- /dev/null +++ b/tests/test_param_file.py @@ -0,0 +1,460 @@ +__copyright__ = \ +""" +(C) 2022 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. +""" + +__doc__ = \ +""" +Execute tests specified via a parameter file. +""" + +import os +import errno +import platform +from subprocess import run +import pytest +from cmp_custom import cmp_custom +from conftest import EncoderFrontend, DecoderFrontend +from testconfig import PARAM_FILE + + +VALID_DEC_OUTPUT_CONF = [ + "MONO", + "STEREO", + "5_1", + "7_1", + "5_1_2", + "5_1_4", + "7_1_4", + "FOA", + "HOA2", + "HOA3", + "BINAURAL", + "BINAURAL_ROOM", + "EXT", +] + +param_file_test_dict = {} +with open(PARAM_FILE, "r", encoding="UTF-8") as fp: + data = fp.read() + blocks = data.split("\n\n") + for block in blocks: + tag = "" + enc_opts = "" + dec_opts = "" + sim_opts = "" + for line in block.split("\n"): + if line.startswith("// "): + tag = line[3:] + if line.startswith("../IVAS_cod "): + enc_opts = line[12:] + if line.startswith("../IVAS_dec "): + dec_opts = line[12:] + if line.startswith("networkSimulator_g192 "): + sim_opts = line[22:] + if tag == "" or enc_opts == "" or dec_opts == "": + # no complete parameter set + continue + if tag in param_file_test_dict: + print("non-unique tag found - ignoring new entry") + continue + param_file_test_dict[tag] = (enc_opts, dec_opts, sim_opts) + + +def check_and_makedir(dir_path): + if not os.path.exists(dir_path): + try: + os.makedirs(dir_path) + except OSError as e: + if e.errno != errno.EEXIST: + raise # raises the error again + + +def convert_test_string_to_tag(test_string): + """ + Convert a test string (i.e. the test tag from the parameter file) to a tag string. + Example: + in: "DFT stereo at 13.2 kbps, 16kHz in, 16kHz out, DTX on, random FEC at 5%" + out: "DFT_stereo_at_13_2_kbps_16kHz_in_16kHz_out_DTX_on_random_FEC_at_5_" + """ + # replace certain characters by "_" or remove them + tag_str = "" + replace_chars = " %.-()" + remove_chars = "," + for char in test_string: + if char in replace_chars: + tag_str += "_" + elif char not in remove_chars: + tag_str += char + # replace double underscore by single one + tag_str = "_".join(tag_str.split("__")) + return tag_str + + +@pytest.mark.create_ref +@pytest.mark.parametrize("test_tag", list(param_file_test_dict.keys())) +def test_param_file_tests( + dut_encoder_frontend: EncoderFrontend, + dut_decoder_frontend: DecoderFrontend, + ref_encoder_path, + ref_decoder_path, + reference_path, + dut_base_path, + test_vector_path, + update_ref, + rootdir, + keep_files, + test_tag, +): + enc_opts, dec_opts, sim_opts = param_file_test_dict[test_tag] + + tag_str = convert_test_string_to_tag(test_tag) + + # evaluate encoder options + enc_split = enc_opts.split() + assert len(enc_split) >= 4 + + # replace "testv/" by test vector path + enc_split = [ + x.replace("testv", f"{test_vector_path}", 1) if x.startswith("testv/") else x + for x in enc_split + ] + + bitstream_file = enc_split.pop() + testv_file = enc_split.pop() + sampling_rate = int(enc_split.pop()) + bitrate = enc_split.pop() + + # bitrate can be a filename: remove leading "../" + if bitrate.startswith("../"): + bitrate = bitrate[3:] + + testv_base = testv_file.split("/")[-1] + if testv_base.endswith(".pcm"): + testv_base = testv_base[:-4] + + assert bitstream_file == "bit" + # in the parameter file, only "bit" is used as bitstream file name + # -> construct bitstream filename + bitstream_file = f"{testv_base}_{tag_str}.192" + + encode( + dut_encoder_frontend, + ref_encoder_path, + reference_path, + dut_base_path, + bitrate, + sampling_rate, + testv_file, + bitstream_file, + enc_split, + update_ref, + ) + + # check for networkSimulator_g192 command line + if sim_opts != "": + sim_split = sim_opts.split() + assert len(sim_split) == 6, "networkSimulator_g192 binary expects 6 parameters" + # [sim_profile, sim_input, sim_output, sim_trace, sim_nFPP, sim_offset] = sim_split + if sim_split[0].startswith(("../")): + # remove leading "../" + sim_split[0] = sim_split[0][3:] + assert sim_split[1] == "bit" + # in the parameter file, only "bit" is used as bitstream file name + # -> re-use bitstream filename from encoder call + sim_split[1] = bitstream_file + assert sim_split[2] == "netsimoutput" + # in the parameter file, only "netsimoutput" is used as netsim output file name + # -> construct netsim output file name + netsim_outfile = f"{testv_base}_{tag_str}.netsimout" + sim_split[2] = netsim_outfile + assert sim_split[3] == "tracefile_sim" + # in the parameter file, only "tracefile_sim" is used as trace output file name + # -> construct trace output file name + netsim_trace_outfile = f"{testv_base}_{tag_str}.netsimtrace" + sim_split[3] = netsim_trace_outfile + simulate( + reference_path, + dut_base_path, + sim_split, + update_ref, + rootdir, + ) + + # evaluate decoder options + dec_split = dec_opts.split() + assert len(dec_split) >= 3 + + # replace "testv/" by test vector path + dec_split = [ + x.replace("testv", f"{test_vector_path}", 1) if x.startswith("testv/") else x + for x in dec_split + ] + # remove leading "../" + dec_split = [x[3:] if x.startswith("../") else x for x in dec_split] + + output_file = dec_split.pop() + bitstream_file_dec = dec_split.pop() + sampling_rate = int(dec_split.pop()) + if len(dec_split) > 0: + output_config = dec_split.pop() + if output_config.upper() not in VALID_DEC_OUTPUT_CONF: + if not output_config.endswith(".txt"): + # must be EVS tests with additional parameters - put param back + dec_split.append(output_config) + output_config = "" + else: + output_config = "" + + output_config_name = output_config + if "/" in output_config: + # the output config is a file + output_config_name = os.path.splitext(os.path.basename(output_config))[0] + + tracefile_dec = "" + if sim_opts != "": + assert bitstream_file_dec == "netsimoutput" + # in the parameter file, only "netsimoutput" is used as bitstream file name + # -> re-use netsim_outfile + bitstream_file = netsim_outfile + tracefile_dec = f"{testv_base}_{tag_str}.dectrace" + else: + assert bitstream_file_dec == "bit" + # in the parameter file, only "bit" is used as bitstream file name + # -> re-use bitstream filename from encoder call + + # the output file is not the real output filename + # -> construct output filename + if output_config != "": + output_file = f"{testv_base}_{tag_str}.dec.{output_config_name}.pcm" + else: + # EVS decoder command lines do not have an output_config: use "MONO" in the output filename + output_file = f"{testv_base}_{tag_str}.dec.MONO.pcm" + + decode( + dut_decoder_frontend, + ref_decoder_path, + reference_path, + dut_base_path, + output_config, + sampling_rate, + bitstream_file, + output_file, + dec_split, + update_ref, + tracefile_dec, + ) + + # compare + if update_ref in [0, 2]: + compare( + f"{dut_base_path}/param_file/dec/{output_file}", + f"{reference_path}/param_file/dec/{output_file}", + ) + + # remove DUT output files when test result is OK (to save disk space) + if not keep_files: + os.remove(f"{dut_base_path}/param_file/enc/{bitstream_file}") + os.remove(f"{dut_base_path}/param_file/dec/{output_file}") + if sim_opts != "": + os.remove(f"{dut_base_path}/param_file/enc/{testv_base}_{tag_str}.192") + os.remove(f"{dut_base_path}/param_file/enc/{netsim_trace_outfile}") + os.remove(f"{dut_base_path}/param_file/dec/{tracefile_dec}") + + +def encode( + encoder_frontend, + ref_encoder_path, + reference_path, + dut_base_path, + bitrate, + sampling_rate, + testv_file, + bitstream_file, + enc_opts_list, + update_ref, +): + """ + Call REF and/or DUT encoder. + """ + # directories + dut_out_dir = f"{dut_base_path}/param_file/enc" + ref_out_dir = f"{reference_path}/param_file/enc" + + ref_out_file = f"{ref_out_dir}/{bitstream_file}" + dut_out_file = f"{dut_out_dir}/{bitstream_file}" + + if update_ref == 1 or update_ref == 2 and not os.path.exists(ref_out_file): + check_and_makedir(ref_out_dir) + # call REF encoder + assert ref_encoder_path + ref_encoder = EncoderFrontend(ref_encoder_path, "REF") + ref_encoder.run( + bitrate, + sampling_rate, + testv_file, + ref_out_file, + add_option_list=enc_opts_list, + ) + + if update_ref in [0, 2]: + check_and_makedir(dut_out_dir) + # call DUT encoder + encoder_frontend.run( + bitrate, + sampling_rate, + testv_file, + dut_out_file, + add_option_list=enc_opts_list, + ) + + +def simulate( + reference_path, + dut_base_path, + sim_opts_list, + update_ref, + rootdir, +): + """ + Call network simulator on REF and/or DUT encoder output. + """ + # directories + dut_out_dir = f"{dut_base_path}/param_file/enc" + ref_out_dir = f"{reference_path}/param_file/enc" + + netsim_infile = sim_opts_list[1] + netsim_outfile = sim_opts_list[2] + netsim_tracefile = sim_opts_list[3] + ref_out_file = f"{ref_out_dir}/{netsim_outfile}" + + if platform.system() == "Windows": + netsim = [os.path.join(rootdir, "scripts", "tools", "Win32", "networkSimulator_g192.exe")] + elif platform.system() == "Linux": + # there is no Linux binary available -> use the Win32 binary via wine + netsim = [ + "wine", + os.path.join(rootdir, "scripts", "tools", "Win32", "networkSimulator_g192.exe"), + ] + elif platform.system() == "Darwin": + netsim = [os.path.join(rootdir, "scripts", "tools", "Darwin", "networkSimulator_g192")] + + if update_ref == 1 or update_ref == 2 and not os.path.exists(ref_out_file): + # call network simulator on REF encoder output + cmd_opts = sim_opts_list + cmd_opts[1] = f"{ref_out_dir}/{netsim_infile}" + cmd_opts[2] = f"{ref_out_dir}/{netsim_outfile}" # ref_out_file + cmd_opts[3] = f"{ref_out_dir}/{netsim_tracefile}" + run(netsim + cmd_opts, check=False) + + if update_ref in [0, 2]: + # call network simulator on DUT encoder output + cmd_opts = sim_opts_list + cmd_opts[1] = f"{dut_out_dir}/{netsim_infile}" + cmd_opts[2] = f"{dut_out_dir}/{netsim_outfile}" # dut_out_file + cmd_opts[3] = f"{dut_out_dir}/{netsim_tracefile}" + run(netsim + cmd_opts, check=False) + + +def decode( + decoder_frontend, + ref_decoder_path, + reference_path, + dut_base_path, + output_config, + sampling_rate, + bitstream_file, + output_file, + dec_opts_list, + update_ref, + tracefile_dec, +): + """ + Call REF and/or DUT decoder. + """ + # directories + dut_out_dir = f"{dut_base_path}/param_file/dec" + ref_out_dir = f"{reference_path}/param_file/dec" + + dut_in_file = f"{dut_base_path}/param_file/enc/{bitstream_file}" + ref_in_file = f"{reference_path}/param_file/enc/{bitstream_file}" + dut_out_file = f"{dut_out_dir}/{output_file}" + ref_out_file = f"{ref_out_dir}/{output_file}" + + if update_ref == 1 or update_ref == 2 and not os.path.exists(ref_out_file): + check_and_makedir(ref_out_dir) + add_option_list = dec_opts_list + if tracefile_dec != "": + add_option_list = [ + x if x != "tracefile_dec" else f"{ref_out_dir}/{tracefile_dec}" + for x in dec_opts_list + ] + # call REF decoder + assert ref_decoder_path + ref_decoder = DecoderFrontend(ref_decoder_path, "REF") + ref_decoder.run( + output_config, + sampling_rate, + ref_in_file, + ref_out_file, + add_option_list=add_option_list, + ) + + if update_ref in [0, 2]: + check_and_makedir(dut_out_dir) + add_option_list = dec_opts_list + if tracefile_dec != "": + add_option_list = [ + x if x != "tracefile_dec" else f"{dut_out_dir}/{tracefile_dec}" + for x in dec_opts_list + ] + # call DUT decoder + decoder_frontend.run( + output_config, + sampling_rate, + dut_in_file, + dut_out_file, + add_option_list=add_option_list, + ) + + +def compare( + pcm_file_1, + pcm_file_2, +): + """ + Compare two PCM files. + Currently, both PCM files are treated like mono files. + This is just fine when checking for bit-exactness. + More advanced comparisons are possible and might come with a future update. + """ + sample_size = "2" # 16-bit samples + tolerance = "0" # zero tolerance for BE testing + cmp_result, reason = cmp_custom(pcm_file_1, pcm_file_2, sample_size, tolerance) + assert cmp_result == 0, reason diff --git a/tests/test_sba_bs_dec_plc.py b/tests/test_sba_bs_dec_plc.py new file mode 100644 index 0000000000..58be07ec33 --- /dev/null +++ b/tests/test_sba_bs_dec_plc.py @@ -0,0 +1,189 @@ +__copyright__ = \ +""" +(C) 2022 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. +""" + +__doc__ = \ +""" +Execute SBA decoder tests using different PLC patterns. +""" + +import os +import errno +import pytest + +from cmp_custom import cmp_custom +from conftest import DecoderFrontend + +#params +tag_list = ['stvFOA'] +plc_patterns = ['PLperc12mblen5', 'PLperc40mblen50', 'PLperc42mblen2'] +dtx_set = ['0', '1'] +ivas_br_list = ['32000', '64000', '96000', '256000'] +sampling_rate_list = ['48', '32', '16'] +agc_list = [0, 1] + +AbsTol = '3' + + +def check_and_makedir(dir_path): + if not os.path.exists(dir_path): + try: + os.makedirs(dir_path) + except OSError as e: + if e.errno != errno.EEXIST: + raise # raises the error again + + +# assumption: +# - the needed reference bitstreams are created by test_sba_enc_system +# -> reference bitstreams are not any longer created as part of this test +# -> the parameters of this test (except additional parameter plc_pattern) need to be a subset of the parameters in test_sba_enc_system +# -> the reference generation for this test (reference decoder output) needs to be done after completion of test_sba_enc_system +# -> therefore the marker create_ref_part2 +@pytest.mark.create_ref_part2 +@pytest.mark.parametrize("ivas_br", ivas_br_list) +@pytest.mark.parametrize("dtx", dtx_set) +@pytest.mark.parametrize("tag", tag_list) +@pytest.mark.parametrize("plc_pattern", plc_patterns) +@pytest.mark.parametrize("fs", sampling_rate_list) +@pytest.mark.parametrize("agc", agc_list) +def test_sba_plc_system( + dut_decoder_frontend: DecoderFrontend, + test_vector_path, + reference_path, + dut_base_path, + ref_decoder_path, + update_ref, + keep_files, + ivas_br, + dtx, + tag, + plc_pattern, + fs, + agc +): + tag = tag + fs + 'c' + + #dec + sba_dec_plc( + dut_decoder_frontend, + test_vector_path, + reference_path, + dut_base_path, + ref_decoder_path, + tag, + fs, + ivas_br, + dtx, + plc_pattern, + update_ref, + agc, + keep_files, + ) + + +######################################################### +############ test function ############################## +def sba_dec_plc( + decoder_frontend, + test_vector_path, + reference_path, + dut_base_path, + ref_decoder_path, + tag, + sampling_rate, + ivas_br, + dtx, + plc_pattern, + update_ref, + agc, + keep_files, +): + + ######### run cmd ##################################### + + tag_out = f"{tag}_ivasbr{ivas_br[:-3]}k_DTX{dtx}" + if agc == 1: + tag_out += '_AGC1' + plc_tag_out = f"{tag_out}_{plc_pattern}" + + dut_out_dir = f"{dut_base_path}/sba_bs/raw" + ref_out_dir = f"{reference_path}/sba_bs/raw" + + check_and_makedir(dut_out_dir) + check_and_makedir(ref_out_dir) + + plc_file = f"{test_vector_path}/{plc_pattern}.g192" + ref_in_pkt = f"{reference_path}/sba_bs/pkt/{tag_out}.pkt" + ref_in_pkt_dutenc = f"{reference_path}/sba_bs/pkt/{tag_out}_dutenc.pkt" + + dut_out_raw = f"{dut_out_dir}/{plc_tag_out}.raw" + ref_out_raw = f"{ref_out_dir}/{plc_tag_out}.raw" + + if ref_decoder_path: + ref_decoder = DecoderFrontend(ref_decoder_path, "REF") + + # call REF decoder + ref_decoder.run( + "FOA", + sampling_rate, + ref_in_pkt, + ref_out_raw, + plc_file=plc_file, + ) + + if update_ref == 0: + # call DUT decoder + decoder_frontend.run( + "FOA", + sampling_rate, + ref_in_pkt_dutenc, + dut_out_raw, + plc_file=plc_file, + ) + + ######### compare cmd ##################################### + + end_skip_samples = '0' + + cmp_result, reason = cmp_custom( + dut_out_raw, + ref_out_raw, + "2", + AbsTol, + end_skip_samples + ) + + # report compare result + assert cmp_result == 0, reason + + # remove DUT output files when test result is OK (to save disk space) + if not keep_files: + os.remove(dut_out_raw) diff --git a/scripts/ivas_pytests/tests/system_tests/test_spar_foa_bs_enc.py b/tests/test_sba_bs_enc.py similarity index 71% rename from scripts/ivas_pytests/tests/system_tests/test_spar_foa_bs_enc.py rename to tests/test_sba_bs_enc.py index df5d018ce5..95cfea1d19 100644 --- a/scripts/ivas_pytests/tests/system_tests/test_spar_foa_bs_enc.py +++ b/tests/test_sba_bs_enc.py @@ -1,47 +1,44 @@ +__copyright__ = \ """ - (C) 2022 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. +(C) 2022 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. """ +__doc__ = \ """ Test file to run C encoder and decoder code. The outputs are compared with C generated references. """ import os -import pytest import errno -import shutil -import sys +import pytest -sys.path.append('scripts/ivas_pytests/') -sys.path.append('scripts/ivas_pytests/tests/') -from il2mm import il2mm from cmp_custom import cmp_custom from cut_pcm import cut_samples from conftest import EncoderFrontend, DecoderFrontend @@ -67,7 +64,6 @@ agc_list = [0, 1] sample_rate_bw_idx_list = [('48', 'SWB'), ('48', 'WB'), ('32', 'WB')] AbsTol = '4' -ch_count_foa = 4 def check_and_makedir(dir_path): @@ -86,15 +82,16 @@ def check_and_makedir(dir_path): def test_bypass_enc( dut_encoder_frontend: EncoderFrontend, dut_decoder_frontend: DecoderFrontend, - data_system_tests_path, + test_vector_path, reference_path, dut_base_path, ref_encoder_path, ref_decoder_path, update_ref, + keep_files, tag, fs, - bypass + bypass, ): if update_ref == 1 and bypass == 1: pytest.skip() @@ -108,9 +105,9 @@ def test_bypass_enc( output_config = "FOA" # enc - spar_foa_enc( + sba_enc( dut_encoder_frontend, - data_system_tests_path, + test_vector_path, ref_encoder_path, reference_path, dut_base_path, @@ -126,13 +123,12 @@ def test_bypass_enc( ) # dec - spar_foa_dec( + sba_dec( dut_decoder_frontend, ref_decoder_path, reference_path, dut_base_path, tag, - ch_count_foa, fs, ivas_br, dtx, @@ -140,7 +136,8 @@ def test_bypass_enc( bypass, agc, output_config, - update_ref + update_ref, + keep_files, ) @@ -150,20 +147,21 @@ def test_bypass_enc( @pytest.mark.parametrize("tag", tag_list) @pytest.mark.parametrize("fs", sample_rate_list) @pytest.mark.parametrize("agc", agc_list) -def test_spar_foa_enc_system( +def test_sba_enc_system( dut_encoder_frontend: EncoderFrontend, dut_decoder_frontend: DecoderFrontend, - data_system_tests_path, + test_vector_path, reference_path, dut_base_path, ref_encoder_path, ref_decoder_path, update_ref, + keep_files, ivas_br, dtx, tag, fs, - agc + agc, ): tag = tag + fs + 'c' max_bw = "FB" @@ -172,13 +170,14 @@ def test_spar_foa_enc_system( output_config = "FOA" if agc == 1: cut_gain = "16.0" + elif dtx == '1': + cut_gain = ".004" else: - cut_gain = "1.0" - + cut_gain = "1.0" # enc - spar_foa_enc( + sba_enc( dut_encoder_frontend, - data_system_tests_path, + test_vector_path, ref_encoder_path, reference_path, dut_base_path, @@ -196,13 +195,12 @@ def test_spar_foa_enc_system( ) # dec - spar_foa_dec( + sba_dec( dut_decoder_frontend, ref_decoder_path, reference_path, dut_base_path, tag, - ch_count_foa, fs, ivas_br, dtx, @@ -210,7 +208,8 @@ def test_spar_foa_enc_system( bypass, agc, output_config, - update_ref + update_ref, + keep_files, ) @pytest.mark.create_ref @@ -219,14 +218,15 @@ def test_spar_foa_enc_system( def test_spar_hoa2_enc_system( dut_encoder_frontend: EncoderFrontend, dut_decoder_frontend: DecoderFrontend, - data_system_tests_path, + test_vector_path, reference_path, dut_base_path, ref_encoder_path, ref_decoder_path, update_ref, + keep_files, ivas_br, - tag + tag, ): fs = '48' dtx = '0' @@ -239,9 +239,9 @@ def test_spar_hoa2_enc_system( output_config = "HOA2" # enc - spar_foa_enc( + sba_enc( dut_encoder_frontend, - data_system_tests_path, + test_vector_path, ref_encoder_path, reference_path, dut_base_path, @@ -258,13 +258,12 @@ def test_spar_hoa2_enc_system( ) # dec - spar_foa_dec( + sba_dec( dut_decoder_frontend, ref_decoder_path, reference_path, dut_base_path, tag, - ch_count_foa, fs, ivas_br, dtx, @@ -272,7 +271,8 @@ def test_spar_hoa2_enc_system( bypass, agc, output_config, - update_ref + update_ref, + keep_files, ) @pytest.mark.create_ref @@ -281,14 +281,15 @@ def test_spar_hoa2_enc_system( def test_spar_hoa3_enc_system( dut_encoder_frontend: EncoderFrontend, dut_decoder_frontend: DecoderFrontend, - data_system_tests_path, + test_vector_path, reference_path, dut_base_path, ref_encoder_path, ref_decoder_path, update_ref, + keep_files, ivas_br, - tag + tag, ): fs = '48' dtx = '0' @@ -301,9 +302,9 @@ def test_spar_hoa3_enc_system( output_config = "HOA3" # enc - spar_foa_enc( + sba_enc( dut_encoder_frontend, - data_system_tests_path, + test_vector_path, ref_encoder_path, reference_path, dut_base_path, @@ -320,13 +321,12 @@ def test_spar_hoa3_enc_system( ) # dec - spar_foa_dec( + sba_dec( dut_decoder_frontend, ref_decoder_path, reference_path, dut_base_path, tag, - ch_count_foa, fs, ivas_br, dtx, @@ -334,7 +334,8 @@ def test_spar_hoa3_enc_system( bypass, agc, output_config, - update_ref + update_ref, + keep_files, ) @pytest.mark.create_ref @@ -342,19 +343,20 @@ def test_spar_hoa3_enc_system( @pytest.mark.parametrize("dtx", dtx_set) @pytest.mark.parametrize("tag", tag_list_bw_force) @pytest.mark.parametrize("sample_rate_bw_idx", sample_rate_bw_idx_list) -def test_spar_foa_enc_BWforce_system( +def test_sba_enc_BWforce_system( dut_encoder_frontend: EncoderFrontend, dut_decoder_frontend: DecoderFrontend, - data_system_tests_path, + test_vector_path, reference_path, dut_base_path, ref_encoder_path, ref_decoder_path, update_ref, + keep_files, ivas_br, dtx, tag, - sample_rate_bw_idx + sample_rate_bw_idx, ): fs = sample_rate_bw_idx[0] bw = sample_rate_bw_idx[1] @@ -365,9 +367,9 @@ def test_spar_foa_enc_BWforce_system( output_config = "FOA" # enc - spar_foa_enc( + sba_enc( dut_encoder_frontend, - data_system_tests_path, + test_vector_path, ref_encoder_path, reference_path, dut_base_path, @@ -383,13 +385,12 @@ def test_spar_foa_enc_BWforce_system( ) # dec - spar_foa_dec( + sba_dec( dut_decoder_frontend, ref_decoder_path, reference_path, dut_base_path, tag, - ch_count_foa, fs, ivas_br, dtx, @@ -397,13 +398,14 @@ def test_spar_foa_enc_BWforce_system( bypass, agc, output_config, - update_ref + update_ref, + keep_files, ) ######################################################### ############ test function ############################## -def spar_foa_enc( +def sba_enc( encoder_frontend, test_vector_path, ref_encoder_path, @@ -424,8 +426,8 @@ def spar_foa_enc( ): ######### run cmd ##################################### - dut_out_dir = f"{dut_base_path}/spar_foa_bs/pkt" - ref_out_dir = f"{reference_path}/spar_foa_bs/pkt" + dut_out_dir = f"{dut_base_path}/sba_bs/pkt" + ref_out_dir = f"{reference_path}/sba_bs/pkt" check_and_makedir(dut_out_dir) check_and_makedir(ref_out_dir) @@ -512,13 +514,12 @@ def spar_foa_enc( ) -def spar_foa_dec( +def sba_dec( decoder_frontend, ref_decoder_path, reference_path, dut_base_path, tag, - ch_count, sampling_rate, ivas_br, dtx, @@ -527,7 +528,7 @@ def spar_foa_dec( agc, output_config, update_ref, - keep_files=False + keep_files, ): ######### run cmd ##################################### @@ -549,11 +550,14 @@ def spar_foa_dec( # to avoid conflicting names in case of parallel test execution, differentiate all cases long_tag_ext = f"_AGC{agc}_pca{bypass}" - dut_out_dir = f"{dut_base_path}/spar_foa_bs/raw/{tag_out}{long_tag_ext}" - ref_out_dir = f"{reference_path}/spar_foa_bs/raw/{tag_out}{short_tag_ext}" + dut_out_dir = f"{dut_base_path}/sba_bs/raw" + ref_out_dir = f"{reference_path}/sba_bs/raw" - dut_in_pkt = f"{dut_base_path}/spar_foa_bs/pkt/{tag_out}{long_tag_ext}.pkt" - ref_in_pkt = f"{reference_path}/spar_foa_bs/pkt/{tag_out}{short_tag_ext}.pkt" + dut_in_pkt = f"{dut_base_path}/sba_bs/pkt/{tag_out}{long_tag_ext}.pkt" + ref_in_pkt = f"{reference_path}/sba_bs/pkt/{tag_out}{short_tag_ext}.pkt" + + dut_out_raw = f"{dut_out_dir}/{tag_out}{long_tag_ext}.raw" + ref_out_raw = f"{ref_out_dir}/{tag_out}{short_tag_ext}.raw" check_and_makedir(dut_out_dir) check_and_makedir(ref_out_dir) @@ -566,48 +570,34 @@ def spar_foa_dec( output_config, sampling_rate, ref_in_pkt, - f"{ref_out_dir}/out.raw", + ref_out_raw, ) - # convert REF interleaved to multi-mono - il2mm(f"{ref_out_dir}/out.raw", ch_count, b_delete=not keep_files) - if update_ref == 0: # call DUT decoder decoder_frontend.run( output_config, sampling_rate, dut_in_pkt, - f"{dut_out_dir}/out.raw", + dut_out_raw, ) - il2mm(f"{dut_out_dir}/out.raw", ch_count, b_delete=not keep_files) - ######### compare cmd ##################################### end_skip_samples = '0' - test_fail = False - for count in range(ch_count): - ch_id = str(count + 1) - - # TEST - fsize1 = os.path.getsize(f"{dut_out_dir}/out{ch_id}ch.raw") - fsize2 = os.path.getsize(f"{ref_out_dir}/out{ch_id}ch.raw") - print(f"Want to compare {dut_out_dir}/out{ch_id}ch.raw ({fsize1} bytes) with {ref_out_dir}/out{ch_id}ch.raw ({fsize2} bytes)") - if cmp_custom( - f"{dut_out_dir}/out{ch_id}ch.raw", - f"{ref_out_dir}/out{ch_id}ch.raw", - "2", - AbsTol, - end_skip_samples - ) != 0: - test_fail = True - - ##File removal## + cmp_result, reason = cmp_custom( + dut_out_raw, + ref_out_raw, + "2", + AbsTol, + end_skip_samples + ) + + # report compare result + assert cmp_result == 0, reason + + # remove DUT output files when test result is OK (to save disk space) if not keep_files: os.remove(dut_in_pkt) - shutil.rmtree(dut_out_dir, ignore_errors=True) - - ##report failure - assert not test_fail + os.remove(dut_out_raw) diff --git a/tests/testconfig.py b/tests/testconfig.py new file mode 100644 index 0000000000..f4827a004f --- /dev/null +++ b/tests/testconfig.py @@ -0,0 +1,37 @@ +__copyright__ = \ +""" +(C) 2022 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. +""" + +__doc__ = \ +""" +To configure test modules. +""" + +PARAM_FILE = "scripts/config/self_test.prm" -- GitLab From b8d4159c78dfcf24f70767397a4393b2dc74475f Mon Sep 17 00:00:00 2001 From: Archit Tamarapu Date: Fri, 7 Oct 2022 15:15:36 +0200 Subject: [PATCH 029/101] add fixes to enable FIX_I106_TDREND_5MS --- lib_com/options.h | 2 +- lib_rend/ivas_objectRenderer.c | 150 ++++++++++++++++++++++++++------- 2 files changed, 122 insertions(+), 30 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index b6f4b44ea2..832ffb11b7 100755 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -146,7 +146,7 @@ #define FADE_TO_ZERO_FOR_TOO_LONG_FRAMELOSS /*#define FIX_I1_113*/ /* under review : MCT bit distribution optimization for SBA high bitrates*/ -// #define FIX_I106_TDREND_5MS /* Issue 106: 5 ms update rate in TD object renderer */ +#define FIX_I106_TDREND_5MS /* Issue 106: 5 ms update rate in TD object renderer */ #define ALIGN_SID_SIZE /* Issue 111: make all DTX modes use one SID frame bitrate (5.2 kbps) */ #define FIX_135_MDCT_STEREO_MODE_UNINITIALIZED /* Issue 135: fix uninitialized value usage in SBA MDCT-Stereo core with PLC */ #define FIX_CONTROLLABLE_SID_UPDATE_RATE /* Issue 117: fix controllable SID update rate mechanism */ diff --git a/lib_rend/ivas_objectRenderer.c b/lib_rend/ivas_objectRenderer.c index 4a297aba55..21c734af4d 100644 --- a/lib_rend/ivas_objectRenderer.c +++ b/lib_rend/ivas_objectRenderer.c @@ -57,8 +57,22 @@ static ivas_error TDREND_GetMix( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRenderer #endif static void TDREND_Clear_Update_flags( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd ); #ifdef FIX_I106_TDREND_5MS -static void TDREND_Update_listener_orientation( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, const int16_t headRotEnabled, const Quaternion *headPosition ); -static void TDREND_Update_object_positions( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, const int16_t numSources, const IVAS_FORMAT in_format, const ISM_METADATA_HANDLE *hIsmMetaData, float output[][L_FRAME48k] ); +static void TDREND_Update_listener_orientation( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, + const int16_t headRotEnabled, +#ifdef EXT_RENDERER + const IVAS_QUATERNION *headPosition +#else + const Quaternion *headPosition +#endif +); +static void TDREND_Update_object_positions( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, + const int16_t numSources, +#ifdef EXT_RENDERER + const int16_t lfe_idx, +#endif + const IVAS_FORMAT in_format, + const ISM_METADATA_HANDLE *hIsmMetaData, + float output[][L_FRAME48k] ); #endif /*---------------------------------------------------------------------* @@ -357,8 +371,12 @@ void ObjRenderIVASFrame( } #ifdef FIX_I106_TDREND_5MS - /* Update object position(s) */ +/* Update object position(s) */ +#ifdef EXT_RENDERER + TDREND_Update_object_positions( st_ivas->hBinRendererTd, st_ivas->nchan_transport, LFE_CHANNEL, st_ivas->ivas_format, st_ivas->hIsmMetaData, output ); +#else TDREND_Update_object_positions( st_ivas->hBinRendererTd, st_ivas->nchan_transport, st_ivas->ivas_format, st_ivas->hIsmMetaData, output ); +#endif for ( subframe_idx = 0; subframe_idx < MAX_PARAM_SPATIAL_SUBFRAMES; subframe_idx++ ) { @@ -530,9 +548,12 @@ static void TDREND_Clear_Update_flags( static void TDREND_Update_object_positions( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o : TD Renderer handle */ const int16_t numSources, /* i : Number of sources to render */ - const IVAS_FORMAT in_format, /* i : Format of input sources */ - const ISM_METADATA_HANDLE *hIsmMetaData, /* i : Input metadata for ISM objects */ - float output[][L_FRAME48k] /* i/o: SCE/MC channels */ +#ifdef EXT_RENDERER + const int16_t lfe_idx, /* i : Input LFE index */ +#endif + const IVAS_FORMAT in_format, /* i : Format of input sources */ + const ISM_METADATA_HANDLE *hIsmMetaData, /* i : Input metadata for ISM objects */ + float output[][L_FRAME48k] /* i/o: SCE/MC channels */ ) { TDREND_DirAtten_t *DirAtten_p; @@ -547,7 +568,11 @@ static void TDREND_Update_object_positions( c_indx = 0; for ( nS = 0; nS < numSources; nS++ ) { +#ifdef EXT_RENDERER + if ( !( in_format == MC_FORMAT && nS == lfe_idx ) ) /* Skip LFE for MC */ +#else if ( !( in_format == MC_FORMAT && nS == LFE_CHANNEL ) ) /* Skip LFE for MC */ +#endif { hBinRendererTd->Sources[c_indx]->InputFrame_p = output[nS]; hBinRendererTd->Sources[c_indx]->SrcRend_p->InputAvailable = TRUE; @@ -591,7 +616,11 @@ static void TDREND_Update_object_positions( static void TDREND_Update_listener_orientation( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD Renderer handle */ const int16_t headRotEnabled, /* i : Headrotation flag */ - const Quaternion *headPosition /* i : Head Position */ +#ifdef EXT_RENDERER + const IVAS_QUATERNION *headPosition /* i : Head Position */ +#else + const Quaternion *headPosition /* i : Head Position */ +#endif ) { float Pos[3]; @@ -800,32 +829,54 @@ ivas_error ivas_rend_TDObjRenderFrame( float output[][L_FRAME48k] /* i/o: SCE channels / Binaural synthesis */ ) { +#ifndef FIX_I106_TDREND_5MS TDREND_DirAtten_t *DirAtten_p; int16_t nS; - int16_t lfe_idx; - int16_t c_indx; - int32_t nchan_in; float Pos[3]; float Dir[3]; float FrontVec[3]; float UpVec[3]; float Rmat[3][3]; + int16_t c_indx; +#else + int16_t subframe_length; + int16_t subframe_idx; + ISM_METADATA_HANDLE hIsmMetaData[1]; +#endif + int16_t lfe_idx; + int32_t num_src; /* TODO tmu : pass down renderer config struct */ // float reverb_signal[BINAURAL_CHANNELS][L_FRAME48k]; + IVAS_FORMAT ivas_format; IVAS_REND_AudioConfigType inConfigType; inConfigType = getAudioConfigType( inConfig ); - if ( inConfig != IVAS_REND_AUDIO_CONFIG_LS_CUSTOM ) + lfe_idx = LFE_CHANNEL; + if ( inConfigType == IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED ) { - lfe_idx = LFE_CHANNEL; - getAudioConfigNumChannels( inConfig, &nchan_in ); + ivas_format = MC_FORMAT; + if ( inConfig != IVAS_REND_AUDIO_CONFIG_LS_CUSTOM ) + { + getAudioConfigNumChannels( inConfig, &num_src ); + } + else + { + lfe_idx = ( customLsInput->num_lfe > 0 ) ? customLsInput->lfe_idx[0] : -1; + num_src = customLsInput->num_spk + customLsInput->num_lfe; + } } else { - lfe_idx = ( customLsInput->num_lfe > 0 ) ? customLsInput->lfe_idx[0] : -1; - nchan_in = customLsInput->num_spk + customLsInput->num_lfe; + ivas_format = ISM_FORMAT; + num_src = 1; + hIsmMetaData[0] = count_malloc( sizeof( ISM_METADATA_FRAME ) ); + hIsmMetaData[0]->azimuth = currentPos->azimuth; + hIsmMetaData[0]->elevation = currentPos->elevation; } +#ifdef FIX_I106_TDREND_5MS + subframe_length = output_frame / MAX_PARAM_SPATIAL_SUBFRAMES; +#else DirAtten_p = pTDRend->hBinRendererTd->DirAtten_p; /* Update the listener's location/orientation */ @@ -865,7 +916,7 @@ ivas_error ivas_rend_TDObjRenderFrame( /* For each source, write the frame data to the source object*/ c_indx = 0; - for ( nS = 0; nS < nchan_in; nS++ ) + for ( nS = 0; nS < num_src; nS++ ) { if ( !( inConfigType == IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED && nS == lfe_idx ) ) /* Skip LFE for MC */ { @@ -897,25 +948,66 @@ ivas_error ivas_rend_TDObjRenderFrame( TDREND_MIX_SRC_SetPlayState( pTDRend->hBinRendererTd, nS, TDREND_PLAYSTATUS_PLAYING ); } } +#endif - /* TODO tmu : pass down renderer config struct */ - // if ( pTDRend->hRenderConfig != NULL ) /* Renderer Configuration not enabled in TD standalone renderer */ + /* TODO tmu : pass down renderer config struct and decide what to do about ini_frame ? */ + // if ( hRenderConfig != NULL ) /* Renderer Configuration not enabled in TD standalone renderer */ // { - // if ( pTDRend->hRenderConfig->roomAcoustics.late_reverb_on ) - // { - // if ( pTDRend->ini_frame == 0 ) - // { - // ivas_reverb_open( &pTDRend->hCrend->hReverb, pTDRend->transport_config, NULL, pTDRend->hRenderConfig, pTDRend->hDecoderConfig->output_Fs ); - // } - // for ( subframe_idx = 0; subframe_idx < 4; subframe_idx++ ) - // { - // ivas_reverb_process( pTDRend->hCrend->hReverb, pTDRend->transport_config, 0, output, reverb_signal, subframe_idx ); - // } - // } +#ifdef FIX_I106_TDREND_5MS +// if ( hRenderConfig->roomAcoustics.late_reverb_on && ( st_ivas->ini_frame == 0 ) ) +// { +// ivas_reverb_open( &pTDRend->hCrend->hReverb, pTDRend->transport_config, NULL, pTDRend->hRenderConfig, pTDRend->hDecoderConfig->output_Fs ); +// } +#else +// if ( pTDRend->hRenderConfig->roomAcoustics.late_reverb_on ) +// { +// if ( pTDRend->ini_frame == 0 ) +// { +// ivas_reverb_open( &pTDRend->hCrend->hReverb, pTDRend->transport_config, NULL, pTDRend->hRenderConfig, pTDRend->hDecoderConfig->output_Fs ); +// } +// for ( subframe_idx = 0; subframe_idx < 4; subframe_idx++ ) +// { +// ivas_reverb_process( pTDRend->hCrend->hReverb, pTDRend->transport_config, 0, output, reverb_signal, subframe_idx ); +// } +// } +#endif // } +#ifdef FIX_I106_TDREND_5MS + /* Update object position(s) */ + TDREND_Update_object_positions( pTDRend->hBinRendererTd, + num_src, + lfe_idx, + ivas_format, + hIsmMetaData, + output ); + + /* TODO tmu : needs a refactor / better approach */ + if ( ivas_format == ISM_FORMAT ) + { + count_free( hIsmMetaData[0] ); + } + + for ( subframe_idx = 0; subframe_idx < MAX_PARAM_SPATIAL_SUBFRAMES; subframe_idx++ ) + { + /* Update the listener's location/orientation */ + TDREND_Update_listener_orientation( pTDRend->hBinRendererTd, + headRotData->headRotEnabled, + ( headRotData != NULL ) ? &headRotData->headPositions[subframe_idx] : NULL ); + + /* TODO tmu : pass down renderer config struct */ + // if ( ( hRenderConfig != NULL ) && ( hRenderConfig->roomAcoustics.late_reverb_on ) ) + // { + // ivas_reverb_process( hCrend->hReverb, transport_config, 0, output, reverb_signal, subframe_idx ); + // } + + /* Render subframe */ + TDREND_GetMix( pTDRend->hBinRendererTd, output, subframe_length, output_Fs, subframe_idx ); + } +#else /* Call the renderer */ TDREND_GetMix( pTDRend->hBinRendererTd, output, output_frame, output_Fs ); +#endif /* TODO tmu : pass down renderer config struct */ // if ( pTDRend->hRenderConfig != NULL ) /* Renderer Configuration not enabled in TD standalone renderer */ -- GitLab From 7d0a06768b3a5103cc6f8b2e15c76878f68c9f13 Mon Sep 17 00:00:00 2001 From: Archit Tamarapu Date: Fri, 7 Oct 2022 15:15:36 +0200 Subject: [PATCH 030/101] add fixes to enable FIX_I106_TDREND_5MS --- lib_com/options.h | 2 +- lib_rend/ivas_objectRenderer.c | 150 ++++++++++++++++++++++++++------- scripts/tests/test_renderer.py | 6 +- 3 files changed, 125 insertions(+), 33 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index b6f4b44ea2..832ffb11b7 100755 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -146,7 +146,7 @@ #define FADE_TO_ZERO_FOR_TOO_LONG_FRAMELOSS /*#define FIX_I1_113*/ /* under review : MCT bit distribution optimization for SBA high bitrates*/ -// #define FIX_I106_TDREND_5MS /* Issue 106: 5 ms update rate in TD object renderer */ +#define FIX_I106_TDREND_5MS /* Issue 106: 5 ms update rate in TD object renderer */ #define ALIGN_SID_SIZE /* Issue 111: make all DTX modes use one SID frame bitrate (5.2 kbps) */ #define FIX_135_MDCT_STEREO_MODE_UNINITIALIZED /* Issue 135: fix uninitialized value usage in SBA MDCT-Stereo core with PLC */ #define FIX_CONTROLLABLE_SID_UPDATE_RATE /* Issue 117: fix controllable SID update rate mechanism */ diff --git a/lib_rend/ivas_objectRenderer.c b/lib_rend/ivas_objectRenderer.c index 4a297aba55..21c734af4d 100644 --- a/lib_rend/ivas_objectRenderer.c +++ b/lib_rend/ivas_objectRenderer.c @@ -57,8 +57,22 @@ static ivas_error TDREND_GetMix( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRenderer #endif static void TDREND_Clear_Update_flags( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd ); #ifdef FIX_I106_TDREND_5MS -static void TDREND_Update_listener_orientation( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, const int16_t headRotEnabled, const Quaternion *headPosition ); -static void TDREND_Update_object_positions( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, const int16_t numSources, const IVAS_FORMAT in_format, const ISM_METADATA_HANDLE *hIsmMetaData, float output[][L_FRAME48k] ); +static void TDREND_Update_listener_orientation( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, + const int16_t headRotEnabled, +#ifdef EXT_RENDERER + const IVAS_QUATERNION *headPosition +#else + const Quaternion *headPosition +#endif +); +static void TDREND_Update_object_positions( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, + const int16_t numSources, +#ifdef EXT_RENDERER + const int16_t lfe_idx, +#endif + const IVAS_FORMAT in_format, + const ISM_METADATA_HANDLE *hIsmMetaData, + float output[][L_FRAME48k] ); #endif /*---------------------------------------------------------------------* @@ -357,8 +371,12 @@ void ObjRenderIVASFrame( } #ifdef FIX_I106_TDREND_5MS - /* Update object position(s) */ +/* Update object position(s) */ +#ifdef EXT_RENDERER + TDREND_Update_object_positions( st_ivas->hBinRendererTd, st_ivas->nchan_transport, LFE_CHANNEL, st_ivas->ivas_format, st_ivas->hIsmMetaData, output ); +#else TDREND_Update_object_positions( st_ivas->hBinRendererTd, st_ivas->nchan_transport, st_ivas->ivas_format, st_ivas->hIsmMetaData, output ); +#endif for ( subframe_idx = 0; subframe_idx < MAX_PARAM_SPATIAL_SUBFRAMES; subframe_idx++ ) { @@ -530,9 +548,12 @@ static void TDREND_Clear_Update_flags( static void TDREND_Update_object_positions( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o : TD Renderer handle */ const int16_t numSources, /* i : Number of sources to render */ - const IVAS_FORMAT in_format, /* i : Format of input sources */ - const ISM_METADATA_HANDLE *hIsmMetaData, /* i : Input metadata for ISM objects */ - float output[][L_FRAME48k] /* i/o: SCE/MC channels */ +#ifdef EXT_RENDERER + const int16_t lfe_idx, /* i : Input LFE index */ +#endif + const IVAS_FORMAT in_format, /* i : Format of input sources */ + const ISM_METADATA_HANDLE *hIsmMetaData, /* i : Input metadata for ISM objects */ + float output[][L_FRAME48k] /* i/o: SCE/MC channels */ ) { TDREND_DirAtten_t *DirAtten_p; @@ -547,7 +568,11 @@ static void TDREND_Update_object_positions( c_indx = 0; for ( nS = 0; nS < numSources; nS++ ) { +#ifdef EXT_RENDERER + if ( !( in_format == MC_FORMAT && nS == lfe_idx ) ) /* Skip LFE for MC */ +#else if ( !( in_format == MC_FORMAT && nS == LFE_CHANNEL ) ) /* Skip LFE for MC */ +#endif { hBinRendererTd->Sources[c_indx]->InputFrame_p = output[nS]; hBinRendererTd->Sources[c_indx]->SrcRend_p->InputAvailable = TRUE; @@ -591,7 +616,11 @@ static void TDREND_Update_object_positions( static void TDREND_Update_listener_orientation( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD Renderer handle */ const int16_t headRotEnabled, /* i : Headrotation flag */ - const Quaternion *headPosition /* i : Head Position */ +#ifdef EXT_RENDERER + const IVAS_QUATERNION *headPosition /* i : Head Position */ +#else + const Quaternion *headPosition /* i : Head Position */ +#endif ) { float Pos[3]; @@ -800,32 +829,54 @@ ivas_error ivas_rend_TDObjRenderFrame( float output[][L_FRAME48k] /* i/o: SCE channels / Binaural synthesis */ ) { +#ifndef FIX_I106_TDREND_5MS TDREND_DirAtten_t *DirAtten_p; int16_t nS; - int16_t lfe_idx; - int16_t c_indx; - int32_t nchan_in; float Pos[3]; float Dir[3]; float FrontVec[3]; float UpVec[3]; float Rmat[3][3]; + int16_t c_indx; +#else + int16_t subframe_length; + int16_t subframe_idx; + ISM_METADATA_HANDLE hIsmMetaData[1]; +#endif + int16_t lfe_idx; + int32_t num_src; /* TODO tmu : pass down renderer config struct */ // float reverb_signal[BINAURAL_CHANNELS][L_FRAME48k]; + IVAS_FORMAT ivas_format; IVAS_REND_AudioConfigType inConfigType; inConfigType = getAudioConfigType( inConfig ); - if ( inConfig != IVAS_REND_AUDIO_CONFIG_LS_CUSTOM ) + lfe_idx = LFE_CHANNEL; + if ( inConfigType == IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED ) { - lfe_idx = LFE_CHANNEL; - getAudioConfigNumChannels( inConfig, &nchan_in ); + ivas_format = MC_FORMAT; + if ( inConfig != IVAS_REND_AUDIO_CONFIG_LS_CUSTOM ) + { + getAudioConfigNumChannels( inConfig, &num_src ); + } + else + { + lfe_idx = ( customLsInput->num_lfe > 0 ) ? customLsInput->lfe_idx[0] : -1; + num_src = customLsInput->num_spk + customLsInput->num_lfe; + } } else { - lfe_idx = ( customLsInput->num_lfe > 0 ) ? customLsInput->lfe_idx[0] : -1; - nchan_in = customLsInput->num_spk + customLsInput->num_lfe; + ivas_format = ISM_FORMAT; + num_src = 1; + hIsmMetaData[0] = count_malloc( sizeof( ISM_METADATA_FRAME ) ); + hIsmMetaData[0]->azimuth = currentPos->azimuth; + hIsmMetaData[0]->elevation = currentPos->elevation; } +#ifdef FIX_I106_TDREND_5MS + subframe_length = output_frame / MAX_PARAM_SPATIAL_SUBFRAMES; +#else DirAtten_p = pTDRend->hBinRendererTd->DirAtten_p; /* Update the listener's location/orientation */ @@ -865,7 +916,7 @@ ivas_error ivas_rend_TDObjRenderFrame( /* For each source, write the frame data to the source object*/ c_indx = 0; - for ( nS = 0; nS < nchan_in; nS++ ) + for ( nS = 0; nS < num_src; nS++ ) { if ( !( inConfigType == IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED && nS == lfe_idx ) ) /* Skip LFE for MC */ { @@ -897,25 +948,66 @@ ivas_error ivas_rend_TDObjRenderFrame( TDREND_MIX_SRC_SetPlayState( pTDRend->hBinRendererTd, nS, TDREND_PLAYSTATUS_PLAYING ); } } +#endif - /* TODO tmu : pass down renderer config struct */ - // if ( pTDRend->hRenderConfig != NULL ) /* Renderer Configuration not enabled in TD standalone renderer */ + /* TODO tmu : pass down renderer config struct and decide what to do about ini_frame ? */ + // if ( hRenderConfig != NULL ) /* Renderer Configuration not enabled in TD standalone renderer */ // { - // if ( pTDRend->hRenderConfig->roomAcoustics.late_reverb_on ) - // { - // if ( pTDRend->ini_frame == 0 ) - // { - // ivas_reverb_open( &pTDRend->hCrend->hReverb, pTDRend->transport_config, NULL, pTDRend->hRenderConfig, pTDRend->hDecoderConfig->output_Fs ); - // } - // for ( subframe_idx = 0; subframe_idx < 4; subframe_idx++ ) - // { - // ivas_reverb_process( pTDRend->hCrend->hReverb, pTDRend->transport_config, 0, output, reverb_signal, subframe_idx ); - // } - // } +#ifdef FIX_I106_TDREND_5MS +// if ( hRenderConfig->roomAcoustics.late_reverb_on && ( st_ivas->ini_frame == 0 ) ) +// { +// ivas_reverb_open( &pTDRend->hCrend->hReverb, pTDRend->transport_config, NULL, pTDRend->hRenderConfig, pTDRend->hDecoderConfig->output_Fs ); +// } +#else +// if ( pTDRend->hRenderConfig->roomAcoustics.late_reverb_on ) +// { +// if ( pTDRend->ini_frame == 0 ) +// { +// ivas_reverb_open( &pTDRend->hCrend->hReverb, pTDRend->transport_config, NULL, pTDRend->hRenderConfig, pTDRend->hDecoderConfig->output_Fs ); +// } +// for ( subframe_idx = 0; subframe_idx < 4; subframe_idx++ ) +// { +// ivas_reverb_process( pTDRend->hCrend->hReverb, pTDRend->transport_config, 0, output, reverb_signal, subframe_idx ); +// } +// } +#endif // } +#ifdef FIX_I106_TDREND_5MS + /* Update object position(s) */ + TDREND_Update_object_positions( pTDRend->hBinRendererTd, + num_src, + lfe_idx, + ivas_format, + hIsmMetaData, + output ); + + /* TODO tmu : needs a refactor / better approach */ + if ( ivas_format == ISM_FORMAT ) + { + count_free( hIsmMetaData[0] ); + } + + for ( subframe_idx = 0; subframe_idx < MAX_PARAM_SPATIAL_SUBFRAMES; subframe_idx++ ) + { + /* Update the listener's location/orientation */ + TDREND_Update_listener_orientation( pTDRend->hBinRendererTd, + headRotData->headRotEnabled, + ( headRotData != NULL ) ? &headRotData->headPositions[subframe_idx] : NULL ); + + /* TODO tmu : pass down renderer config struct */ + // if ( ( hRenderConfig != NULL ) && ( hRenderConfig->roomAcoustics.late_reverb_on ) ) + // { + // ivas_reverb_process( hCrend->hReverb, transport_config, 0, output, reverb_signal, subframe_idx ); + // } + + /* Render subframe */ + TDREND_GetMix( pTDRend->hBinRendererTd, output, subframe_length, output_Fs, subframe_idx ); + } +#else /* Call the renderer */ TDREND_GetMix( pTDRend->hBinRendererTd, output, output_frame, output_Fs ); +#endif /* TODO tmu : pass down renderer config struct */ // if ( pTDRend->hRenderConfig != NULL ) /* Renderer Configuration not enabled in TD standalone renderer */ diff --git a/scripts/tests/test_renderer.py b/scripts/tests/test_renderer.py index db7fb5fd54..ef304e9461 100644 --- a/scripts/tests/test_renderer.py +++ b/scripts/tests/test_renderer.py @@ -559,7 +559,7 @@ pass_snr = { "test_custom_ls_input_binaural_headrotation[t_design_4-BINAURAL-full_circle_in_15s]": 0.1, "test_custom_ls_input_binaural[16ch_8+4+4-BINAURAL]": 0, "test_custom_ls_input_binaural_headrotation[itu_4+5+1-BINAURAL-rotate_yaw_pitch_roll1]": 0, - "test_custom_ls_input_binaural_headrotation[custom1-BINAURAL-full_circle_in_15s]": 0.1, + "test_custom_ls_input_binaural_headrotation[custom1-BINAURAL-full_circle_in_15s]": 0, "test_custom_ls_input_binaural_headrotation[custom1-BINAURAL-rotate_yaw_pitch_roll1]": 0, "test_custom_ls_input_binaural[4d4-BINAURAL_ROOM]": 0, "test_custom_ls_input_binaural[custom1-BINAURAL_ROOM]": 0, @@ -571,7 +571,7 @@ pass_snr = { "test_custom_ls_input_binaural_headrotation[4d4-BINAURAL_ROOM-full_circle_in_15s]": 0, "test_custom_ls_input_binaural_headrotation[t_design_4-BINAURAL_ROOM-full_circle_in_15s]": 0, "test_custom_ls_input_binaural_headrotation[16ch_8+4+4-BINAURAL-full_circle_in_15s]": 0, - "test_custom_ls_input_binaural_headrotation[16ch_8+4+4-BINAURAL-rotate_yaw_pitch_roll1]": 1, + "test_custom_ls_input_binaural_headrotation[16ch_8+4+4-BINAURAL-rotate_yaw_pitch_roll1]": 0, "test_custom_ls_input_binaural_headrotation[itu_4+5+1-BINAURAL-full_circle_in_15s]": 0, "test_custom_ls_input_binaural_headrotation[custom1-BINAURAL_ROOM-full_circle_in_15s]": 0, "test_custom_ls_input_binaural[16ch_8+4+4-BINAURAL_ROOM]": 0.2, @@ -597,7 +597,7 @@ pass_snr = { "test_ism_binaural_headrotation[ISM1-BINAURAL-rotate_yaw_pitch_roll1]": 0, "test_ism_binaural_headrotation[ISM1-BINAURAL_ROOM-full_circle_in_15s]": 6.7, "test_ism_binaural_headrotation[ISM1-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 2, - "test_ism_binaural_headrotation[ISM2-BINAURAL-full_circle_in_15s]": 0.1, + "test_ism_binaural_headrotation[ISM2-BINAURAL-full_circle_in_15s]": 0, "test_ism_binaural_headrotation[ISM2-BINAURAL-rotate_yaw_pitch_roll1]": 0, "test_ism_binaural_headrotation[ISM2-BINAURAL_ROOM-full_circle_in_15s]": 4, "test_ism_binaural_headrotation[ISM2-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 1, -- GitLab From 00e939e1642cc97689a5bc4900d6bdaf3a21c6f6 Mon Sep 17 00:00:00 2001 From: Archit Tamarapu Date: Fri, 7 Oct 2022 15:23:32 +0200 Subject: [PATCH 031/101] preemptively accept FIX_I106_TDREND_5MS to reduce merge conflicts --- lib_com/ivas_cnst.h | 2 - lib_com/ivas_prot.h | 13 -- lib_com/options.h | 1 - lib_rend/ivas_objectRenderer.c | 265 -------------------------- lib_rend/ivas_objectRenderer_hrFilt.c | 38 ---- lib_rend/ivas_objectRenderer_sfx.c | 16 -- 6 files changed, 335 deletions(-) diff --git a/lib_com/ivas_cnst.h b/lib_com/ivas_cnst.h index 2d466e829d..db7cde066e 100644 --- a/lib_com/ivas_cnst.h +++ b/lib_com/ivas_cnst.h @@ -846,9 +846,7 @@ typedef enum { *----------------------------------------------------------------------------------*/ // VE: this should be renamed to e.g. N_SPATIAL_SUBFRAMES #define MAX_PARAM_SPATIAL_SUBFRAMES 4 /* Maximum number of subframes for parameteric spatial coding */ -#ifdef FIX_I106_TDREND_5MS #define L_SPATIAL_SUBFR_48k (L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES) -#endif /*----------------------------------------------------------------------------------* diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index ffdf80d266..390ca333c8 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -4986,21 +4986,12 @@ void TDREND_HRFILT_SetFiltSet( #endif ivas_error TDREND_REND_RenderSourceHRFilt( -#ifdef FIX_I106_TDREND_5MS TDREND_SRC_t *Src_p, /* i/o: The source to be rendered */ -#else - const TDREND_SRC_t *Src_p, /* i/o: The source to be rendered */ -#endif #ifdef TDREND_HRTF_TABLE_METHODS BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ #endif -#ifdef FIX_I106_TDREND_5MS float output_buf[][L_SPATIAL_SUBFR_48k], /* o : Output buffer */ const int16_t subframe_length, /* i : Subframe length in use */ -#else - float output_buf[][L_FRAME48k], /* o : Output buffer */ - const int16_t output_frame, /* i : Output frame length in use */ -#endif const int32_t output_Fs /* i : Output sample rate */ ); @@ -5140,11 +5131,7 @@ void TDREND_SFX_SpatBin_SetParams( void TDREND_SFX_SpatBin_Execute_Main( SFX_SpatBin_t *SfxSpatBin_p, /* i/o: Spatial parameters handle */ const float *InBuffer_p, /* i : Input buffer */ -#ifdef FIX_I106_TDREND_5MS const int16_t subframe_length, /* i : subframe length */ -#else - const int16_t output_frame, /* i : frame length */ -#endif float *LeftOutBuffer_p, /* o : Rendered left channel */ float *RightOutBuffer_p, /* o : Rendered right channel */ int16_t *NoOfUsedInputSamples_p, /* o : Number of input samples actually used */ diff --git a/lib_com/options.h b/lib_com/options.h index 832ffb11b7..6e0fb1c6ba 100755 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -146,7 +146,6 @@ #define FADE_TO_ZERO_FOR_TOO_LONG_FRAMELOSS /*#define FIX_I1_113*/ /* under review : MCT bit distribution optimization for SBA high bitrates*/ -#define FIX_I106_TDREND_5MS /* Issue 106: 5 ms update rate in TD object renderer */ #define ALIGN_SID_SIZE /* Issue 111: make all DTX modes use one SID frame bitrate (5.2 kbps) */ #define FIX_135_MDCT_STEREO_MODE_UNINITIALIZED /* Issue 135: fix uninitialized value usage in SBA MDCT-Stereo core with PLC */ #define FIX_CONTROLLABLE_SID_UPDATE_RATE /* Issue 117: fix controllable SID update rate mechanism */ diff --git a/lib_rend/ivas_objectRenderer.c b/lib_rend/ivas_objectRenderer.c index 21c734af4d..6a2b6ad962 100644 --- a/lib_rend/ivas_objectRenderer.c +++ b/lib_rend/ivas_objectRenderer.c @@ -50,13 +50,8 @@ * Local function prototypes *---------------------------------------------------------------------*/ -#ifdef FIX_I106_TDREND_5MS static ivas_error TDREND_GetMix( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, float output[][L_FRAME48k], const int16_t subframe_length, const int32_t output_Fs, const int16_t subframe_idx ); -#else -static ivas_error TDREND_GetMix( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, float output[][L_FRAME48k], const int16_t output_frame, const int32_t output_Fs ); -#endif static void TDREND_Clear_Update_flags( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd ); -#ifdef FIX_I106_TDREND_5MS static void TDREND_Update_listener_orientation( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, const int16_t headRotEnabled, #ifdef EXT_RENDERER @@ -73,7 +68,6 @@ static void TDREND_Update_object_positions( BINAURAL_TD_OBJECT_RENDERER_HANDLE h const IVAS_FORMAT in_format, const ISM_METADATA_HANDLE *hIsmMetaData, float output[][L_FRAME48k] ); -#endif /*---------------------------------------------------------------------* * ivas_td_binaural_open() @@ -251,126 +245,20 @@ void ObjRenderIVASFrame( const int16_t output_frame /* i : output frame length */ ) { -#ifndef FIX_I106_TDREND_5MS - TDREND_DirAtten_t *DirAtten_p; - int16_t nS; - float Pos[3]; - float Dir[3]; - float FrontVec[3]; - float UpVec[3]; - float Rmat[3][3]; - int16_t c_indx; -#else int16_t subframe_length; -#endif int16_t subframe_idx; float reverb_signal[BINAURAL_CHANNELS][L_FRAME48k]; -#ifdef FIX_I106_TDREND_5MS subframe_length = output_frame / MAX_PARAM_SPATIAL_SUBFRAMES; -#else - DirAtten_p = st_ivas->hBinRendererTd->DirAtten_p; - - /* Update the listener's location/orientation */ - /* Listener at the origin */ - Pos[0] = 0.0f; - Pos[1] = 0.0f; - Pos[2] = 0.0f; - - if ( - st_ivas->hHeadTrackData != NULL -#ifdef EXT_RENDERER - && st_ivas->hDecoderConfig->Opt_Headrotation -#endif - ) - - { - /* Obtain head rotation matrix */ - QuatToRotMat( st_ivas->hHeadTrackData->Quaternions[0], Rmat ); - /* Apply rotation matrix to looking vector [1;0;0] */ - FrontVec[0] = Rmat[0][0]; - FrontVec[1] = Rmat[0][1]; - FrontVec[2] = Rmat[0][2]; - /* Apply rotation matrix to up vector [0;0;1] */ - UpVec[0] = Rmat[2][0]; - UpVec[1] = Rmat[2][1]; - UpVec[2] = Rmat[2][2]; - } - else - { - /* Oriented with looking vector along the x axis */ - FrontVec[0] = 1.0f; - FrontVec[1] = 0.0f; - FrontVec[2] = 0.0f; - /* Oriented with up vector along the z axis */ - UpVec[0] = 0.0f; - UpVec[1] = 0.0f; - UpVec[2] = 1.0f; - } - - /* Set the listener position and orientation:*/ - TDREND_MIX_LIST_SetPos( st_ivas->hBinRendererTd, Pos ); - TDREND_MIX_LIST_SetOrient( st_ivas->hBinRendererTd, FrontVec, UpVec ); - - /* For each source, write the frame data to the source object*/ - c_indx = 0; - for ( nS = 0; nS < st_ivas->nchan_transport; nS++ ) - { - if ( !( st_ivas->ivas_format == MC_FORMAT && nS == LFE_CHANNEL ) ) /* Skip LFE for MC */ - { - st_ivas->hBinRendererTd->Sources[c_indx]->InputFrame_p = output[nS]; - st_ivas->hBinRendererTd->Sources[c_indx]->SrcRend_p->InputAvailable = TRUE; - c_indx++; - } - - if ( st_ivas->ivas_format == ISM_FORMAT ) - { - - /* Update the source positions */ - /* Source position and direction */ - Pos[0] = cosf( st_ivas->hIsmMetaData[nS]->elevation * PI_OVER_180 ) * cosf( st_ivas->hIsmMetaData[nS]->azimuth * PI_OVER_180 ); - Pos[1] = cosf( st_ivas->hIsmMetaData[nS]->elevation * PI_OVER_180 ) * sinf( st_ivas->hIsmMetaData[nS]->azimuth * PI_OVER_180 ); - Pos[2] = sinf( st_ivas->hIsmMetaData[nS]->elevation * PI_OVER_180 ); - Dir[0] = 1.0f; - Dir[1] = 0.0f; - Dir[2] = 0.0f; - - /* Source directivity info */ - DirAtten_p->ConeInnerAngle = 360.0f; - DirAtten_p->ConeOuterAngle = 360.0f; - DirAtten_p->ConeOuterGain = 1.0f; - - TDREND_MIX_SRC_SetPos( st_ivas->hBinRendererTd, nS, Pos ); - TDREND_MIX_SRC_SetDir( st_ivas->hBinRendererTd, nS, Dir ); - TDREND_MIX_SRC_SetDirAtten( st_ivas->hBinRendererTd, nS, DirAtten_p ); - TDREND_MIX_SRC_SetPlayState( st_ivas->hBinRendererTd, nS, TDREND_PLAYSTATUS_PLAYING ); - } - } -#endif if ( st_ivas->hRenderConfig != NULL ) /* Renderer Configuration not enabled in TD standalone renderer */ { -#ifdef FIX_I106_TDREND_5MS if ( st_ivas->hRenderConfig->roomAcoustics.late_reverb_on && ( st_ivas->ini_frame == 0 ) ) { ivas_reverb_open( &st_ivas->hCrend->hReverb, st_ivas->transport_config, NULL, st_ivas->hRenderConfig, st_ivas->hDecoderConfig->output_Fs ); } -#else - if ( st_ivas->hRenderConfig->roomAcoustics.late_reverb_on ) - { - if ( st_ivas->ini_frame == 0 ) - { - ivas_reverb_open( &st_ivas->hCrend->hReverb, st_ivas->transport_config, NULL, st_ivas->hRenderConfig, st_ivas->hDecoderConfig->output_Fs ); - } - for ( subframe_idx = 0; subframe_idx < 4; subframe_idx++ ) - { - ivas_reverb_process( st_ivas->hCrend->hReverb, st_ivas->transport_config, 0, output, reverb_signal, subframe_idx ); - } - } -#endif } -#ifdef FIX_I106_TDREND_5MS /* Update object position(s) */ #ifdef EXT_RENDERER TDREND_Update_object_positions( st_ivas->hBinRendererTd, st_ivas->nchan_transport, LFE_CHANNEL, st_ivas->ivas_format, st_ivas->hIsmMetaData, output ); @@ -393,10 +281,6 @@ void ObjRenderIVASFrame( /* Render subframe */ TDREND_GetMix( st_ivas->hBinRendererTd, output, subframe_length, st_ivas->hDecoderConfig->output_Fs, subframe_idx ); } -#else - /* Call the renderer */ - TDREND_GetMix( st_ivas->hBinRendererTd, output, output_frame, st_ivas->hDecoderConfig->output_Fs ); -#endif if ( st_ivas->hRenderConfig != NULL ) /* Renderer Configuration not enabled in TD standalone renderer */ { @@ -412,30 +296,17 @@ void ObjRenderIVASFrame( } -#ifdef FIX_I106_TDREND_5MS /*---------------------------------------------------------------------* * TDREND_GetMix() * * Render one 5 ms subframe from the mixer *---------------------------------------------------------------------*/ -#else -/*---------------------------------------------------------------------* - * TDREND_GetMix() - * - * Render one output frame from the mixer - *---------------------------------------------------------------------*/ -#endif static ivas_error TDREND_GetMix( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ float output[][L_FRAME48k], /* i/o: ISm object synth / rendered output in 0,1 */ -#ifdef FIX_I106_TDREND_5MS const int16_t subframe_length, /* i/o: subframe length */ const int32_t output_Fs, /* i : Output sampling rate */ const int16_t subframe_idx /* i : Subframe index to 5 ms subframe */ -#else - const int16_t output_frame, /* i/o: Output frame length */ - const int32_t output_Fs /* i : Output sampling rate */ -#endif ) { int16_t i; @@ -443,22 +314,12 @@ static ivas_error TDREND_GetMix( TDREND_SRC_SPATIAL_t *SrcSpatial_p; TDREND_SRC_REND_t *SrcRend_p; ivas_error error; -#ifdef FIX_I106_TDREND_5MS float output_buf[2][L_SPATIAL_SUBFR_48k]; /* Temp buffer for left/right rendered signal */ -#else - float output_buf[2][L_FRAME48k]; /* Temp buffer for left/right rendered signal */ -#endif error = IVAS_ERR_OK; -#ifdef FIX_I106_TDREND_5MS /* Clear the output buffer to accumulate rendered sources */ set_f( output_buf[0], 0.0f, subframe_length ); set_f( output_buf[1], 0.0f, subframe_length ); -#else - /* Zero out the output buffer since objects are accumulated. */ - set_f( output_buf[0], 0.0f, output_frame ); - set_f( output_buf[1], 0.0f, output_frame ); -#endif /* Create the mix */ /* Loop through the source list and render each source */ @@ -477,39 +338,19 @@ static ivas_error TDREND_GetMix( /* Render source if needed */ if ( ( SrcRend_p->InputAvailable == TRUE ) && ( SrcRend_p->PlayStatus == TDREND_PLAYSTATUS_PLAYING ) ) { -#ifdef FIX_I106_TDREND_5MS #ifdef TDREND_HRTF_TABLE_METHODS error = TDREND_REND_RenderSourceHRFilt( Src_p, hBinRendererTd, output_buf, subframe_length, output_Fs ); #else error = TDREND_REND_RenderSourceHRFilt( Src_p, output_buf, subframe_length, output_Fs ); -#endif -#else -#ifdef TDREND_HRTF_TABLE_METHODS - error = TDREND_REND_RenderSourceHRFilt( Src_p, hBinRendererTd, output_buf, output_frame, output_Fs ); -#else - error = TDREND_REND_RenderSourceHRFilt( Src_p, output_buf, output_frame, output_Fs ); -#endif #endif } -#ifndef FIX_I106_TDREND_5MS - SrcRend_p->InputAvailable = FALSE; -#endif } /* Populate output variable */ -#ifdef FIX_I106_TDREND_5MS mvr2r( output_buf[0], output[0] + subframe_idx * subframe_length, subframe_length ); /* Left */ mvr2r( output_buf[1], output[1] + subframe_idx * subframe_length, subframe_length ); /* Right */ -#else - mvr2r( output_buf[0], output[0], output_frame ); /* Left */ - mvr2r( output_buf[1], output[1], output_frame ); /* Right */ -#endif -#ifdef FIX_I106_TDREND_5MS /* Clear the PoseUpdated and Source position update flags */ -#else - /* Clear the mixer update flags */ -#endif TDREND_Clear_Update_flags( hBinRendererTd ); return error; @@ -538,7 +379,6 @@ static void TDREND_Clear_Update_flags( return; } -#ifdef FIX_I106_TDREND_5MS /*---------------------------------------------------------------------* * TDREND_Update_object_positions() * @@ -665,7 +505,6 @@ static void TDREND_Update_listener_orientation( return; } -#endif #ifdef EXT_RENDERER @@ -829,20 +668,9 @@ ivas_error ivas_rend_TDObjRenderFrame( float output[][L_FRAME48k] /* i/o: SCE channels / Binaural synthesis */ ) { -#ifndef FIX_I106_TDREND_5MS - TDREND_DirAtten_t *DirAtten_p; - int16_t nS; - float Pos[3]; - float Dir[3]; - float FrontVec[3]; - float UpVec[3]; - float Rmat[3][3]; - int16_t c_indx; -#else int16_t subframe_length; int16_t subframe_idx; ISM_METADATA_HANDLE hIsmMetaData[1]; -#endif int16_t lfe_idx; int32_t num_src; /* TODO tmu : pass down renderer config struct */ @@ -874,106 +702,17 @@ ivas_error ivas_rend_TDObjRenderFrame( hIsmMetaData[0]->elevation = currentPos->elevation; } -#ifdef FIX_I106_TDREND_5MS subframe_length = output_frame / MAX_PARAM_SPATIAL_SUBFRAMES; -#else - DirAtten_p = pTDRend->hBinRendererTd->DirAtten_p; - - /* Update the listener's location/orientation */ - /* Listener at the origin */ - Pos[0] = 0.0f; - Pos[1] = 0.0f; - Pos[2] = 0.0f; - - if ( headRotData->headRotEnabled ) - { - /* Obtain head rotation matrix */ - QuatToRotMat( headRotData->headPositions[0], Rmat ); - /* Apply rotation matrix to looking vector [1;0;0] */ - FrontVec[0] = Rmat[0][0]; - FrontVec[1] = Rmat[0][1]; - FrontVec[2] = Rmat[0][2]; - /* Apply rotation matrix to up vector [0;0;1] */ - UpVec[0] = Rmat[2][0]; - UpVec[1] = Rmat[2][1]; - UpVec[2] = Rmat[2][2]; - } - else - { - /* Oriented with looking vector along the x axis */ - FrontVec[0] = 1.0f; - FrontVec[1] = 0.0f; - FrontVec[2] = 0.0f; - /* Oriented with up vector along the z axis */ - UpVec[0] = 0.0f; - UpVec[1] = 0.0f; - UpVec[2] = 1.0f; - } - - /* Set the listener position and orientation:*/ - TDREND_MIX_LIST_SetPos( pTDRend->hBinRendererTd, Pos ); - TDREND_MIX_LIST_SetOrient( pTDRend->hBinRendererTd, FrontVec, UpVec ); - - /* For each source, write the frame data to the source object*/ - c_indx = 0; - for ( nS = 0; nS < num_src; nS++ ) - { - if ( !( inConfigType == IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED && nS == lfe_idx ) ) /* Skip LFE for MC */ - { - pTDRend->hBinRendererTd->Sources[c_indx]->InputFrame_p = output[nS]; - pTDRend->hBinRendererTd->Sources[c_indx]->SrcRend_p->InputAvailable = TRUE; - c_indx++; - } - - if ( inConfigType == IVAS_REND_AUDIO_CONFIG_TYPE_OBJECT_BASED ) - { - /* Update the source positions */ - /* Source position and direction */ - /* TODO tmu : currently will only work for one object at a time */ - Pos[0] = cosf( currentPos->elevation * PI_OVER_180 ) * cosf( currentPos->azimuth * PI_OVER_180 ); - Pos[1] = cosf( currentPos->elevation * PI_OVER_180 ) * sinf( currentPos->azimuth * PI_OVER_180 ); - Pos[2] = sinf( currentPos->elevation * PI_OVER_180 ); - Dir[0] = 1.0f; - Dir[1] = 0.0f; - Dir[2] = 0.0f; - - /* Source directivity info */ - DirAtten_p->ConeInnerAngle = 360.0f; - DirAtten_p->ConeOuterAngle = 360.0f; - DirAtten_p->ConeOuterGain = 1.0f; - - TDREND_MIX_SRC_SetPos( pTDRend->hBinRendererTd, nS, Pos ); - TDREND_MIX_SRC_SetDir( pTDRend->hBinRendererTd, nS, Dir ); - TDREND_MIX_SRC_SetDirAtten( pTDRend->hBinRendererTd, nS, DirAtten_p ); - TDREND_MIX_SRC_SetPlayState( pTDRend->hBinRendererTd, nS, TDREND_PLAYSTATUS_PLAYING ); - } - } -#endif /* TODO tmu : pass down renderer config struct and decide what to do about ini_frame ? */ // if ( hRenderConfig != NULL ) /* Renderer Configuration not enabled in TD standalone renderer */ // { -#ifdef FIX_I106_TDREND_5MS // if ( hRenderConfig->roomAcoustics.late_reverb_on && ( st_ivas->ini_frame == 0 ) ) // { // ivas_reverb_open( &pTDRend->hCrend->hReverb, pTDRend->transport_config, NULL, pTDRend->hRenderConfig, pTDRend->hDecoderConfig->output_Fs ); // } -#else -// if ( pTDRend->hRenderConfig->roomAcoustics.late_reverb_on ) -// { -// if ( pTDRend->ini_frame == 0 ) -// { -// ivas_reverb_open( &pTDRend->hCrend->hReverb, pTDRend->transport_config, NULL, pTDRend->hRenderConfig, pTDRend->hDecoderConfig->output_Fs ); -// } -// for ( subframe_idx = 0; subframe_idx < 4; subframe_idx++ ) -// { -// ivas_reverb_process( pTDRend->hCrend->hReverb, pTDRend->transport_config, 0, output, reverb_signal, subframe_idx ); -// } -// } -#endif // } -#ifdef FIX_I106_TDREND_5MS /* Update object position(s) */ TDREND_Update_object_positions( pTDRend->hBinRendererTd, num_src, @@ -1004,10 +743,6 @@ ivas_error ivas_rend_TDObjRenderFrame( /* Render subframe */ TDREND_GetMix( pTDRend->hBinRendererTd, output, subframe_length, output_Fs, subframe_idx ); } -#else - /* Call the renderer */ - TDREND_GetMix( pTDRend->hBinRendererTd, output, output_frame, output_Fs ); -#endif /* TODO tmu : pass down renderer config struct */ // if ( pTDRend->hRenderConfig != NULL ) /* Renderer Configuration not enabled in TD standalone renderer */ diff --git a/lib_rend/ivas_objectRenderer_hrFilt.c b/lib_rend/ivas_objectRenderer_hrFilt.c index eb69350d48..9587f34bb9 100644 --- a/lib_rend/ivas_objectRenderer_hrFilt.c +++ b/lib_rend/ivas_objectRenderer_hrFilt.c @@ -343,42 +343,21 @@ void TDREND_HRFILT_SetFiltSet( --------------------------------------------------------------------*/ ivas_error TDREND_REND_RenderSourceHRFilt( -#ifdef FIX_I106_TDREND_5MS TDREND_SRC_t *Src_p, /* i/o: The source to be rendered */ -#else - const TDREND_SRC_t *Src_p, /* i/o: The source to be rendered */ -#endif #ifdef TDREND_HRTF_TABLE_METHODS BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, /* i/o: TD renderer handle */ #endif -#ifdef FIX_I106_TDREND_5MS float output_buf[][L_SPATIAL_SUBFR_48k], /* o : Output buffer */ const int16_t subframe_length, /* i : Subframe length in use */ -#else - float output_buf[][L_FRAME48k], /* o : Output buffer */ - const int16_t output_frame, /* i : Output frame length in use */ -#endif const int32_t output_Fs /* i : Output sample rate */ ) { TDREND_SRC_REND_t *SrcRend_p; -#ifdef FIX_I106_TDREND_5MS const float *InFrame_nIC_p; -#else - int16_t nS; - float *InFrame_nIC_p; -#endif int16_t NoOfUsedInputSamples, NoOfDeliveredOutputSamples; -#ifdef FIX_I106_TDREND_5MS float LeftOutputFrame[L_SPATIAL_SUBFR_48k]; float RightOutputFrame[L_SPATIAL_SUBFR_48k]; -#else - float LeftOutputFrame[L_FRAME48k]; - float RightOutputFrame[L_FRAME48k]; - float *LeftOutputFrame_p, *RightOutputFrame_p; - float *LeftAccOutputFrame_p, *RightAccOutputFrame_p; -#endif /* Input channel rendering loop */ InFrame_nIC_p = Src_p->InputFrame_p; @@ -388,11 +367,7 @@ ivas_error TDREND_REND_RenderSourceHRFilt( /* SrcGain = Mix_p->Gain * ( *SrcRend_p->SrcGain_p ); */ /* SrcGain *= ( *SrcRend_p->DirGain_p ) * ( *SrcRend_p->DistGain_p ); */ -#ifdef FIX_I106_TDREND_5MS TDREND_SFX_SpatBin_Execute_Main( SrcRend_p->SfxSpatBin_p, InFrame_nIC_p, subframe_length, LeftOutputFrame, RightOutputFrame, &NoOfUsedInputSamples, &NoOfDeliveredOutputSamples, output_Fs ); -#else - TDREND_SFX_SpatBin_Execute_Main( SrcRend_p->SfxSpatBin_p, InFrame_nIC_p, output_frame, LeftOutputFrame, RightOutputFrame, &NoOfUsedInputSamples, &NoOfDeliveredOutputSamples, output_Fs ); -#endif #ifdef TDREND_HRTF_TABLE_METHODS if ( hBinRendererTd->HrFiltSet_p->FilterMethod != TDREND_HRFILT_Method_BSplineModel ) @@ -402,24 +377,11 @@ ivas_error TDREND_REND_RenderSourceHRFilt( #endif /* Copy to accumulative output frame */ -#ifdef FIX_I106_TDREND_5MS v_add( LeftOutputFrame, output_buf[0], output_buf[0], subframe_length ); v_add( RightOutputFrame, output_buf[1], output_buf[1], subframe_length ); Src_p->InputFrame_p += subframe_length; /* Increment input pointer -- todo: should we remove this and input the current subframe instead? */ -#else - LeftOutputFrame_p = LeftOutputFrame; - RightOutputFrame_p = RightOutputFrame; - LeftAccOutputFrame_p = output_buf[0]; - RightAccOutputFrame_p = output_buf[1]; - - for ( nS = 0; nS < output_frame; nS++ ) - { - *LeftAccOutputFrame_p++ += *LeftOutputFrame_p++; - *RightAccOutputFrame_p++ += *RightOutputFrame_p++; - } -#endif return IVAS_ERR_OK; diff --git a/lib_rend/ivas_objectRenderer_sfx.c b/lib_rend/ivas_objectRenderer_sfx.c index 08239e8565..5dadf8ff6a 100644 --- a/lib_rend/ivas_objectRenderer_sfx.c +++ b/lib_rend/ivas_objectRenderer_sfx.c @@ -930,11 +930,7 @@ static void TDREND_SFX_SpatBin_UpdateParams( void TDREND_SFX_SpatBin_Execute_Main( SFX_SpatBin_t *SfxSpatBin_p, /* i/o: Spatial parameters struct */ const float *InBuffer_p, /* i : Input buffer */ -#ifdef FIX_I106_TDREND_5MS const int16_t subframe_length, /* i : subframe length */ -#else - const int16_t output_frame, /* i : frame length */ -#endif float *LeftOutBuffer_p, /* o : Rendered left channel */ float *RightOutBuffer_p, /* o : Rendered right channel */ int16_t *NoOfUsedInputSamples_p, /* o : Number of input samples actually used */ @@ -952,11 +948,7 @@ void TDREND_SFX_SpatBin_Execute_Main( /* Make sure the blocks are not longer than 6 msec. */ NoOfBlocks = 1; -#ifdef FIX_I106_TDREND_5MS TempNoOfRequestedOutputSamples = subframe_length; -#else - TempNoOfRequestedOutputSamples = output_frame; -#endif while ( TempNoOfRequestedOutputSamples > SfxSpatBin_p->MaxBlockLength ) { NoOfBlocks = NoOfBlocks << 1; @@ -970,11 +962,7 @@ void TDREND_SFX_SpatBin_Execute_Main( RightOutBufferPointer_p = RightOutBuffer_p; *NoOfUsedInputSamples_p = 0; *NoOfDeliveredOutputSamples_p = 0; -#ifdef FIX_I106_TDREND_5MS TempNoOfInputSamples = subframe_length; -#else - TempNoOfInputSamples = output_frame; -#endif for ( i = 0; i < NoOfBlocks; i++ ) { @@ -1003,11 +991,7 @@ void TDREND_SFX_SpatBin_Execute_Main( if ( i == NoOfBlocks - 2 ) { /* The last block should produce the remaining number of samples */ -#ifdef FIX_I106_TDREND_5MS TempNoOfRequestedOutputSamples = subframe_length - *NoOfDeliveredOutputSamples_p; -#else - TempNoOfRequestedOutputSamples = output_frame - *NoOfDeliveredOutputSamples_p; -#endif } *NoOfUsedInputSamples_p = *NoOfUsedInputSamples_p + TempNoOfUsedInputSamples; TempNoOfInputSamples = TempNoOfInputSamples - TempNoOfUsedInputSamples; -- GitLab From 6ca53293676c887873aff94369855a4c737902d9 Mon Sep 17 00:00:00 2001 From: Archit Tamarapu Date: Fri, 7 Oct 2022 15:40:15 +0200 Subject: [PATCH 032/101] manually accept FIX_CREND_CHANNELS for lib_rend --- lib_rend/ivas_crend.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/lib_rend/ivas_crend.c b/lib_rend/ivas_crend.c index fcd7b90582..f94c221711 100644 --- a/lib_rend/ivas_crend.c +++ b/lib_rend/ivas_crend.c @@ -1171,11 +1171,7 @@ ivas_error ivas_rend_openCrend( hCrend->lfe_delay_line = NULL; -#ifdef FIX_CREND_CHANNELS for ( i = 0; i < MAX_TRANSPORT_CHANNELS; i++ ) -#else - for ( i = 0; i < IVAS_MAX_NUM_CH; i++ ) -#endif { hCrend->freq_buffer_re[i] = NULL; hCrend->freq_buffer_im[i] = NULL; @@ -1703,11 +1699,7 @@ ivas_error ivas_rend_closeCrend( if ( pCrend->hCrend != NULL ) { -#ifdef FIX_CREND_CHANNELS for ( i = 0; i < MAX_TRANSPORT_CHANNELS; i++ ) -#else - for ( i = 0; i < IVAS_MAX_NUM_CH; i++ ) -#endif { if ( pCrend->hCrend->freq_buffer_re[i] != NULL ) { -- GitLab From d1732bcd0be9febf6b8898fb83b83da199913070 Mon Sep 17 00:00:00 2001 From: Archit Tamarapu Date: Fri, 7 Oct 2022 16:34:54 +0200 Subject: [PATCH 033/101] update leftover MAX_TRANSPORT_CHANNELS, reduce the size of a binaural tmp buffer --- lib_rend/ivas_crend.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/lib_rend/ivas_crend.c b/lib_rend/ivas_crend.c index f94c221711..bec08cbbaf 100644 --- a/lib_rend/ivas_crend.c +++ b/lib_rend/ivas_crend.c @@ -1037,7 +1037,11 @@ ivas_error ivas_crend_process( { int16_t i, nchan_out, output_frame; int16_t subframe_len, subframe_idx; +#ifdef EXT_RENDERER + float pcm_tmp[BINAURAL_CHANNELS][L_FRAME48k]; +#else float pcm_tmp[MAX_TRANSPORT_CHANNELS][L_FRAME48k]; +#endif AUDIO_CONFIG intern_config; ivas_error error; @@ -1171,7 +1175,7 @@ ivas_error ivas_rend_openCrend( hCrend->lfe_delay_line = NULL; - for ( i = 0; i < MAX_TRANSPORT_CHANNELS; i++ ) + for ( i = 0; i < MAX_INTERN_CHANNELS; i++ ) { hCrend->freq_buffer_re[i] = NULL; hCrend->freq_buffer_im[i] = NULL; @@ -1699,7 +1703,7 @@ ivas_error ivas_rend_closeCrend( if ( pCrend->hCrend != NULL ) { - for ( i = 0; i < MAX_TRANSPORT_CHANNELS; i++ ) + for ( i = 0; i < MAX_INTERN_CHANNELS; i++ ) { if ( pCrend->hCrend->freq_buffer_re[i] != NULL ) { @@ -1770,7 +1774,7 @@ ivas_error ivas_rend_crendProcess( { int16_t i, subframe_idx, output_frame; int32_t nchan_out; - float pcm_tmp[MAX_TRANSPORT_CHANNELS][L_FRAME48k]; + float pcm_tmp[BINAURAL_CHANNELS][L_FRAME48k]; AUDIO_CONFIG in_config; IVAS_REND_AudioConfigType inConfigType; ivas_error error; -- GitLab From 8734f88fd6157180dc25230f45085be17f04710d Mon Sep 17 00:00:00 2001 From: Kacper Sagnowski Date: Fri, 14 Oct 2022 10:38:45 +0200 Subject: [PATCH 034/101] Fix Visual Studio warnings --- apps/renderer.c | 43 +++++++++++++------------------------------ lib_com/ivas_prot.h | 2 +- 2 files changed, 14 insertions(+), 31 deletions(-) diff --git a/apps/renderer.c b/apps/renderer.c index 3369dfcee2..dc31bf3a64 100644 --- a/apps/renderer.c +++ b/apps/renderer.c @@ -192,9 +192,6 @@ typedef struct CmdlnArgs static IVAS_REND_AudioConfig ambisonicsOrderToEnum( int32_t order ); -static IVAS_REND_AudioConfig speakerLayoutCicpToEnum( - int32_t cicpIndex ); - static bool parseInConfig( char **optionValues, CmdlnArgs *args ); @@ -322,7 +319,7 @@ static IVAS_REND_ReadOnlyAudioBuffer getReadOnlySubBuffer( IVAS_REND_AudioBuffer IVAS_REND_ReadOnlyAudioBuffer subBuffer; subBuffer.config = buffer.config; - subBuffer.config.numChannels = numChannels; + subBuffer.config.numChannels = (int16_t) numChannels; subBuffer.data = buffer.data + subBuffer.config.numSamplesPerChannel * chBeginIdx; return subBuffer; @@ -409,7 +406,7 @@ int32_t main( int32_t argc, char **argv ) char masaMetadataFilePath[FILENAME_MAX]; AudioFileReader *audioReader = NULL; AudioFileWriter *audioWriter; - int16_t inBufferSize; + int32_t inBufferSize; int32_t outBufferSize; int16_t *inpInt16Buffer; float *inFloatBuffer; @@ -422,7 +419,6 @@ int32_t main( int32_t argc, char **argv ) int16_t delayNumSamples_orig = 0; int16_t zeroPad = 0; int32_t delayTimeScale = 0; - int32_t i; ivas_error error = IVAS_ERR_OK; #ifdef WMOPS size_t SRAM_size; @@ -438,7 +434,7 @@ int32_t main( int32_t argc, char **argv ) #endif CmdlnArgs args = parseCmdlnArgs( argc, argv ); - const int16_t frameSize_smpls = (int16_t) ( 20 * args.sampleRate / 1000 ); + const int32_t frameSize_smpls = 20 * args.sampleRate / 1000; positionProvider = IsmPositionProvider_open(); @@ -475,7 +471,7 @@ int32_t main( int32_t argc, char **argv ) /* Set up reading metadata files */ positionProvider->numObjects = args.inConfig.numAudioObjects; - for ( i = 0; i < positionProvider->numObjects; ++i ) + for ( int32_t i = 0; i < positionProvider->numObjects; ++i ) { positionProvider->ismReaders[i] = IsmFileReader_open( args.metaDataFiles[i] ); } @@ -604,12 +600,12 @@ int32_t main( int32_t argc, char **argv ) outInt16Buffer = count_malloc( outBufferSize * sizeof( int16_t ) ); outFloatBuffer = count_malloc( outBufferSize * sizeof( float ) ); - inBuffer.config.numSamplesPerChannel = frameSize_smpls; - inBuffer.config.numChannels = totalNumInChannels; + inBuffer.config.numSamplesPerChannel = (int16_t) frameSize_smpls; + inBuffer.config.numChannels = (int16_t) totalNumInChannels; inBuffer.data = inFloatBuffer; - outBuffer.config.numSamplesPerChannel = frameSize_smpls; - outBuffer.config.numChannels = numOutChannels; + outBuffer.config.numSamplesPerChannel = (int16_t) frameSize_smpls; + outBuffer.config.numChannels = (int16_t) numOutChannels; outBuffer.data = outFloatBuffer; #ifdef WMOPS @@ -632,7 +628,7 @@ int32_t main( int32_t argc, char **argv ) num_in_channels = inBuffer.config.numChannels; /* Read the input data */ - if ( ( error = AudioFileReader_read( audioReader, inpInt16Buffer, inBufferSize, &numSamplesRead ) ) != IVAS_ERR_OK ) + if ( ( error = AudioFileReader_read( audioReader, inpInt16Buffer, (int16_t) inBufferSize, &numSamplesRead ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nError reading from file %s\n", audioFilePath ); exit( -1 ); @@ -759,7 +755,7 @@ int32_t main( int32_t argc, char **argv ) } else { - delayNumSamples -= outBufferSize; + delayNumSamples -= (int16_t) outBufferSize; } frame++; @@ -900,7 +896,7 @@ static bool parseInConfig( char **optionValues, CmdlnArgs *args ) /* If input format is objects, parse the characters after "ISM" to get number of objects */ { char *ptr = NULL; - inConfig.numAudioObjects = strtol( optionValues[0] + 3, &ptr, 10 ); + inConfig.numAudioObjects = (uint16_t) strtol( optionValues[0] + 3, &ptr, 10 ); if ( ptr == NULL || *ptr != '\0' ) { /* Failed to parse string as a number */ @@ -1177,7 +1173,7 @@ static void parseOption( int32_t optionId, char **optionValues, int16_t numOptio /* TODO(sgi): Parsing currently depends on order in which the options are given by the user. * This causes a lot of errors and is unmaintainable for options that depend on each other. - * + * * Solution: save all option values here as strings, parse strings afterwards once all values are known. */ @@ -1272,7 +1268,7 @@ static void parseOption( int32_t optionId, char **optionValues, int16_t numOptio break; case CmdLnOptionId_inputGain: assert( numOptionValues == 1 ); - args->inputGainGlobal = atof( optionValues[0] ); /* TODO(sgi): atof doesn't detect if string doesn't represent a number, just returns zero */ + args->inputGainGlobal = (float) atof( optionValues[0] ); /* TODO(sgi): atof doesn't detect if string doesn't represent a number, just returns zero */ break; default: assert( 0 && "This should be unreachable - all command line options should be explicitly handled." ); @@ -1629,19 +1625,6 @@ static void parseUint8( const char *line, uint8_t *ret ) } } -static void parseUint16( const char *line, uint16_t *ret ) -{ - char *ptr; - ptr = NULL; - - *ret = (uint16_t) strtol( line, &ptr, 10 ); - if ( ptr == NULL || *ptr != '\0' ) - { - fprintf( stderr, "Cannot parse string \"%s\" as an integer value\n", line ); - exit( -1 ); - } -} - static int8_t parseUint32( const char *line, uint32_t *ret ) { char *ptr; diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index 6cada9b306..45458582e4 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -3128,7 +3128,7 @@ void ivas_sba_mtx_mult( float output_f[][L_FRAME48k], /* i/o: synthesized core-corder transport channels/DirAC output */ const int16_t output_frame, /* i : frame length per channel */ const int16_t nchan_in, /* i : Number of ambisonic channels */ - IVAS_OUTPUT_SETUP output_setup, /* i : Output configuration */ + const IVAS_OUTPUT_SETUP output_setup, /* i : Output configuration */ const float *mtx_hoa_decoder /* o : HOA decoding matrix */ ); #endif -- GitLab From 43c38ed7b71effd9405c438931fde21c00a7df64 Mon Sep 17 00:00:00 2001 From: Kacper Sagnowski Date: Wed, 12 Oct 2022 12:14:48 +0200 Subject: [PATCH 035/101] Fix feature switch --- lib_dec/ivas_stat_dec.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_dec/ivas_stat_dec.h b/lib_dec/ivas_stat_dec.h index 2284f9d09d..766b5d386d 100644 --- a/lib_dec/ivas_stat_dec.h +++ b/lib_dec/ivas_stat_dec.h @@ -1296,7 +1296,7 @@ typedef struct ivas_binaural_rendering_struct * Head tracking data structure *----------------------------------------------------------------------------------*/ -#ifdef EXT_RENDERER +#ifndef EXT_RENDERER /* Quaternion type for head orientation */ typedef struct Quaternion_struct { -- GitLab From b900e1f58fb6d2bd078a97ec1c6e8cb571255762 Mon Sep 17 00:00:00 2001 From: Kacper Sagnowski Date: Tue, 18 Oct 2022 10:18:13 +0200 Subject: [PATCH 036/101] Fix problems with command line interface Fixes include: - fix for broken `-l` flag - sampling rate flag no longer required when using wav files - improved handling of required CLI arguments - fix for issues with input metadata flag --- apps/encoder.c | 10 +- apps/renderer.c | 753 +++++++++++++++++-------------- lib_util/audio_file_reader.c | 22 +- lib_util/audio_file_reader.h | 6 +- lib_util/cmdln_parser.c | 34 +- lib_util/cmdln_parser.h | 5 +- lib_util/ls_custom_file_reader.c | 2 +- lib_util/ls_custom_file_reader.h | 2 +- 8 files changed, 460 insertions(+), 374 deletions(-) diff --git a/apps/encoder.c b/apps/encoder.c index b1abc36d2f..20074e4d49 100644 --- a/apps/encoder.c +++ b/apps/encoder.c @@ -262,12 +262,18 @@ int main( /*------------------------------------------------------------------------------------------* * Open input audio file *------------------------------------------------------------------------------------------*/ - - if ( AudioFileReader_open( &audioReader, arg.inputWavFilename, arg.inputFs ) != IVAS_ERR_OK ) + int32_t inFileSampleRate = 0; + if ( AudioFileReader_open( &audioReader, arg.inputWavFilename, &inFileSampleRate ) != IVAS_ERR_OK ) { fprintf( stderr, "\nCan't open %s\n\n", arg.inputWavFilename ); goto cleanup; } + if ( inFileSampleRate != 0 && /* inFileSampleRate will remain zero if input file is raw PCM */ + inFileSampleRate != arg.inputFs ) + { + fprintf( stderr, "Sampling rate mismatch: %d Hz requested, but %d Hz found in file %s\n", arg.inputFs, inFileSampleRate, arg.inputWavFilename ); + goto cleanup; + } /*------------------------------------------------------------------------------------------* * Open output bitstream file diff --git a/apps/renderer.c b/apps/renderer.c index dc31bf3a64..17bd22fdd7 100644 --- a/apps/renderer.c +++ b/apps/renderer.c @@ -79,6 +79,7 @@ #define max( x, y ) ( ( x ) > ( y ) ? ( x ) : ( y ) ) #endif +#define RENDERER_MAX_CLI_ARG_LENGTH ( FILENAME_MAX ) #define RENDERER_MAX_METADATA_LENGTH 8192 #define RENDERER_MAX_METADATA_LINE_LENGTH 1024 @@ -160,8 +161,8 @@ typedef struct RendererInput ambisonicsBuses[RENDERER_MAX_SBA_INPUTS]; uint16_t numAmbisonicsBuses; IVAS_CUSTOM_LS_DATA inSetupCustom; - RendererInput masaBus; /* Support one MASA input for now. Multiple inputs will be easier to implement after API rework. */ - uint16_t numMasaBuses; /* Keep for framework consistency for now. Again - this will not be necessary after API rework */ + RendererInput masaBuses[RENDERER_MAX_MASA_INPUTS]; + uint16_t numMasaBuses; } InputConfig; typedef struct @@ -170,40 +171,162 @@ typedef struct IVAS_CUSTOM_LS_DATA outSetupCustom; } OutputConfig; -typedef struct CmdlnArgs +typedef struct { - char inputFilePath[FILENAME_MAX]; - char outputFilePath[FILENAME_MAX]; + char executableName[RENDERER_MAX_CLI_ARG_LENGTH]; + char inputFilePath[RENDERER_MAX_CLI_ARG_LENGTH]; + char outputFilePath[RENDERER_MAX_CLI_ARG_LENGTH]; int32_t sampleRate; InputConfig inConfig; OutputConfig outConfig; - char metaDataFiles[RENDERER_MAX_ISM_INPUTS][FILENAME_MAX]; - char trajectoryFile[FILENAME_MAX]; - char customHrtfFile[FILENAME_MAX]; - char renderConfigFile[FILENAME_MAX]; + char inMetadataFilePaths[RENDERER_MAX_ISM_INPUTS][RENDERER_MAX_CLI_ARG_LENGTH]; + int32_t numInMetadataFiles; + char headRotationFilePath[RENDERER_MAX_CLI_ARG_LENGTH]; + char customHrtfFilePath[RENDERER_MAX_CLI_ARG_LENGTH]; + char renderConfigFilePath[RENDERER_MAX_CLI_ARG_LENGTH]; int8_t orientationTracking; float noDiegeticPan; bool delayCompensationEnabled; bool quietModeEnabled; bool sceneDescriptionInput; - float inputGainGlobal; + float inputGainGlobal; /* Linear gain (not in dB) */ } CmdlnArgs; +typedef enum +{ + CmdLnOptionId_inputFile = 1, + CmdLnOptionId_inputFormat, + CmdLnOptionId_outputFile, + CmdLnOptionId_outputFormat, + CmdLnOptionId_sampleRate, + CmdLnOptionId_trajFile, + CmdLnOptionId_customHrtfFile, + CmdLnOptionId_renderConfigFile, + CmdLnOptionId_noDiegeticPan, + CmdLnOptionId_orientationTracking, + CmdLnOptionId_customLfeRouting, + CmdLnOptionId_noDelayCmp, + CmdLnOptionId_quietModeEnabled, + CmdLnOptionId_inputMetadata, + CmdLnOptionId_listFormats, + CmdLnOptionId_inputGain, +} 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. 5_1 or HOA3 or META, use -l for a list)", + }, + { + .id = CmdLnOptionId_inputMetadata, + .match = "input_metadata", + .matchShort = "im", + .description = "Space-separated list of path to metadata files for ISM or MASA inputs", + }, + { + .id = CmdLnOptionId_outputFile, + .match = "output_file", + .matchShort = "o", + .description = "Path to the output file", + }, + { + .id = CmdLnOptionId_outputFormat, + .match = "output_format", + .matchShort = "of", + .description = "Output format to render.\nAlternatively, can be a custom loudspeaker layout file", + }, + { + .id = CmdLnOptionId_sampleRate, + .match = "sample_rate", + .matchShort = "fs", + .description = "Input sampling rate in kHz (16, 32, 48) - required only with raw PCM inputs", /* TODO(sgi): Add sampling rate to scene description files */ + }, + { + .id = CmdLnOptionId_trajFile, + .match = "trajectory_file", + .matchShort = "tf", + .description = "Head rotation trajectory file for simulation of head tracking (only for BINAURAL and BINAURAL_ROOM outputs)", + }, + { + .id = CmdLnOptionId_customHrtfFile, + .match = "custom_hrtf", + .matchShort = "hrtf", + .description = "Custom HRTF file for binaural rendering (only for BINAURAL and BINAURAL_ROOM outputs)", + }, + { + .id = CmdLnOptionId_renderConfigFile, + .match = "render_config", + .matchShort = "rc", + .description = "Binaural renderer configuration file (only for BINAURAL and BINAURAL_ROOM outputs)", + }, + { + .id = CmdLnOptionId_noDiegeticPan, + .match = "no_diegetic_pan", + .matchShort = "ndp", + .description = "Panning mono no diegetic sound to stereo -1<= pan <= 1\nleft or l or 1->left, right or r or -1->right, center or c or 0 ->middle\n(todo: implementation)", + }, + { + .id = CmdLnOptionId_orientationTracking, + .match = "tracking_type", + .matchShort = "otr", + .description = "Head orientation tracking type: 'ref' or 'avg' (only for BINAURAL and BINAURAL_ROOM) (todo: check implementation)", + }, + { + /* TODO(sgi): Replace with more configurable input, e.g. ask for a list of triplets: (gain, azimuth, elevation) to place LFE signal */ + /* rename to "lfeHandling" */ + .id = CmdLnOptionId_customLfeRouting, + .match = "neverDropLfe", + .matchShort = "ndl", + .description = "[flag] If set, renderer tries to render LFE into other channels in an optimal way when rendering to configs w/o LFE", + }, + { + .id = CmdLnOptionId_noDelayCmp, + .match = "no_delay_cmp", + .matchShort = "ndc", + .description = "[flag] Turn off delay compensation", + }, + { + .id = CmdLnOptionId_quietModeEnabled, + .match = "quiet", + .matchShort = "q", + .description = "[flag] Limit printouts to terminal", + }, + { + .id = CmdLnOptionId_inputGain, + .match = "gain", + .matchShort = "g", + .description = "Input gain (linear, not in dB) to be applied to input audio file", + }, + { + .id = CmdLnOptionId_listFormats, + .match = "list", + .matchShort = "l", + .description = "List supported audio formats", + }, +}; + +static const int32_t numCliOptions = sizeof( cliOptions ) / sizeof( CmdLnParser_Option ); + static IVAS_REND_AudioConfig ambisonicsOrderToEnum( int32_t order ); -static bool parseInConfig( char **optionValues, - CmdlnArgs *args ); - -static void parseConfigFile( +static void parseSceneDescriptionFile( char *path, char *audioFilePath, InputConfig *inConfig, IsmPositionProvider *positionProvider, - char *masaMetadataFilePath ); + MasaFileReader** masaReaders ); static ivas_error parseCustomLayoutFile( - char *filePath, + const char *filePath, IVAS_CUSTOM_LS_DATA *pLsSetupCustom ); static CmdlnArgs parseCmdlnArgs( @@ -262,34 +385,12 @@ static void parseObjectPosition( IVAS_REND_AudioObjectPosition *position, uint16_t *positionDuration ); -static void parseIsm( - char *line, - char *inDir, - InputConfig *inConfig, - IsmPositionProvider *positionProvider, - int32_t idx ); - -static void parseSba( - char *line, - InputConfig *inConfig, - int32_t idx ); - -static void parseMc( - char *line, - InputConfig *inConfig, - int32_t idx ); - -static void parseMasa( - char *line, - InputConfig *inConfig, - char *masaMetadataFilePath ); - static void parseMetadata( char *metadataString, char *inDir, InputConfig *inConfig, IsmPositionProvider *positionProvider, - char *masaMetadataFilePath ); + MasaFileReader** masaReaders ); static void convert_backslash( char *str ); @@ -299,6 +400,8 @@ static void remove_cr( static void clearString( char *str ); +static bool isEmptyString( const char *str ); + static void printSupportedAudioConfigs( void ); static IVAS_REND_AudioConfig parseAudioConfig( const char *configString ); @@ -387,6 +490,54 @@ static int32_t getTotalNumInChannels( IVAS_REND_HANDLE hIvasRend, return totalNumInChannels; } +static void setupWithSingleFormatInput( CmdlnArgs args, char *audioFilePath, IsmPositionProvider *positionProvider, MasaFileReader **masaReaders ) +{ + /* With single-format input, inputFilePath is the path to input audio file. */ + strncpy( audioFilePath, args.inputFilePath, FILENAME_MAX - 1 ); + + /* Depending on input format, prepare metadata reading for ISM or MASA */ + if ( args.inConfig.numMasaBuses != 0 ) + { + if ( args.inConfig.numMasaBuses != args.numInMetadataFiles ) + { + fprintf( stderr, "Error: all MASA inputs must have a corresponding metadata file" ); + exit( -1 ); + } + + for ( int32_t i = 0; i < args.numInMetadataFiles; ++i ) + { + masaReaders[i] = MasaFileReader_open( args.inMetadataFilePaths[i] ); + if ( masaReaders[i] == NULL ) + { + fprintf( stderr, "Could not open MASA metadata file %s\n", args.inMetadataFilePaths[i] ); + exit( -1 ); + } + } + } + else if ( args.inConfig.numAudioObjects != 0 ) + { + positionProvider->numObjects = args.inConfig.numAudioObjects; + for ( int32_t i = 0; i < positionProvider->numObjects; ++i ) + { + /* It is allowed on CLI to have no metadata for an ISM input - skip opening if string is empty or contains "NULL" */ + char charBuf[FILENAME_MAX]; + strncpy( charBuf, args.inMetadataFilePaths[i], min( FILENAME_MAX, RENDERER_MAX_CLI_ARG_LENGTH ) - 1 ); + to_upper( charBuf ); + if ( isEmptyString( args.inMetadataFilePaths[i] ) || strncmp( charBuf, "NULL", 4 ) == 0 ) + { + continue; + } + + positionProvider->ismReaders[i] = IsmFileReader_open( args.inMetadataFilePaths[i] ); + if ( positionProvider->ismReaders[i] == NULL ) + { + fprintf( stderr, "Could not open object metadata file %s\n", args.inMetadataFilePaths[i] ); + exit( -1 ); + } + } + } +} + static float dBToLin( float gain_dB ) { return powf( 10.0f, gain_dB / 20.0f ); @@ -402,8 +553,9 @@ int32_t main( int32_t argc, char **argv ) hrtfFileReader *hrtfFileReader = NULL; IsmPositionProvider *positionProvider; RenderConfigReader *renderConfigReader = NULL; + MasaFileReader *masaReaders[RENDERER_MAX_MASA_INPUTS]; + IVAS_MASA_METADATA_HANDLE hMasaMetadata[RENDERER_MAX_MASA_INPUTS]; char audioFilePath[FILENAME_MAX]; - char masaMetadataFilePath[FILENAME_MAX]; AudioFileReader *audioReader = NULL; AudioFileWriter *audioWriter; int32_t inBufferSize; @@ -433,55 +585,68 @@ int32_t main( int32_t argc, char **argv ) mem_count_init( 0, USE_32BITS ); #endif + for ( int32_t i = 0; i < RENDERER_MAX_MASA_INPUTS; ++i ) + { + masaReaders[i] = NULL; + hMasaMetadata[i] = NULL; + } + CmdlnArgs args = parseCmdlnArgs( argc, argv ); - const int32_t frameSize_smpls = 20 * args.sampleRate / 1000; positionProvider = IsmPositionProvider_open(); - clearString( masaMetadataFilePath ); - convert_backslash( args.inputFilePath ); convert_backslash( args.outputFilePath ); - convert_backslash( args.trajectoryFile ); + convert_backslash( args.headRotationFilePath ); - if ( args.trajectoryFile[0] != '\0' ) + if ( !isEmptyString( args.headRotationFilePath ) ) { - HeadRotationFileReader_open( args.trajectoryFile, &headRotReader ); + HeadRotationFileReader_open( args.headRotationFilePath, &headRotReader ); } - if ( args.customHrtfFile[0] != '\0' ) + if ( !isEmptyString( args.customHrtfFilePath ) ) { - hrtfFileReader_open( args.customHrtfFile, &hrtfFileReader ); + hrtfFileReader_open( args.customHrtfFilePath, &hrtfFileReader ); } - if ( args.renderConfigFile[0] != '\0' ) + if ( !isEmptyString( args.renderConfigFilePath ) ) { - RenderConfigReader_open( args.renderConfigFile, &renderConfigReader ); + RenderConfigReader_open( args.renderConfigFilePath, &renderConfigReader ); } + /* Initialize main input files, i.e. audio and metadata */ if ( args.sceneDescriptionInput ) { /* With scene description input, inputFilePath is the path to the scene description file. Parse it. */ - parseConfigFile( args.inputFilePath, audioFilePath, &args.inConfig, positionProvider, masaMetadataFilePath ); + parseSceneDescriptionFile( args.inputFilePath, audioFilePath, &args.inConfig, positionProvider, masaReaders ); } else { - /* With single-format input, inputFilePath is the path to input audio file. */ - strncpy( audioFilePath, args.inputFilePath, FILENAME_MAX - 1 ); - - /* Set up reading metadata files */ - positionProvider->numObjects = args.inConfig.numAudioObjects; - for ( int32_t i = 0; i < positionProvider->numObjects; ++i ) - { - positionProvider->ismReaders[i] = IsmFileReader_open( args.metaDataFiles[i] ); - } + /* With single-format input, all information is given on command line. */ + setupWithSingleFormatInput( args, audioFilePath, positionProvider, masaReaders ); } - if ( AudioFileReader_open( &audioReader, audioFilePath, args.sampleRate ) != IVAS_ERR_OK ) + int32_t inFileSampleRate = 0; + if ( AudioFileReader_open( &audioReader, audioFilePath, &inFileSampleRate ) != IVAS_ERR_OK ) { fprintf( stderr, "Error opening file: %s\n", audioFilePath ); exit( -1 ); } + if ( args.sampleRate == 0 && inFileSampleRate == 0 ) + { + fprintf( stderr, "Sampling rate must be specified on command line when using raw PCM input\n" ); + exit( -1 ); + } + if ( args.sampleRate != 0 && inFileSampleRate != 0 && args.sampleRate != inFileSampleRate ) + { + fprintf( stderr, "Sampling rate mismatch: %d Hz requested, but %d Hz found in file %s\n", args.sampleRate, inFileSampleRate, args.inputFilePath ); + exit( -1 ); + } + if ( args.sampleRate == 0 ) + { + args.sampleRate = inFileSampleRate; + } + const int32_t frameSize_smpls = 20 * args.sampleRate / 1000; IVAS_REND_InputId mcIds[RENDERER_MAX_MC_INPUTS] = { 0 }; IVAS_REND_InputId ismIds[RENDERER_MAX_ISM_INPUTS] = { 0 }; @@ -566,19 +731,12 @@ int32_t main( int32_t argc, char **argv ) exit( -1 ); } - MasaFileReader *masaReader = NULL; - IVAS_MASA_METADATA_HANDLE hMasaMetadata = NULL; - - if ( masaMetadataFilePath[0] != '\0' ) + for ( int32_t i = 0; i < args.inConfig.numMasaBuses; ++i ) { - masaReader = MasaFileReader_open( masaMetadataFilePath ); - if ( masaReader == NULL ) + if ( masaReaders[i] != NULL ) { - fprintf( stderr, "Could not open MASA metadata file %s\n", masaMetadataFilePath ); - exit( -1 ); + hMasaMetadata[i] = MasaFileReader_getMetadataHandle( masaReaders[i] ); } - - hMasaMetadata = MasaFileReader_getMetadataHandle( masaReader ); } int32_t numOutChannels; @@ -643,12 +801,15 @@ int32_t main( int32_t argc, char **argv ) /* Convert from int to float and from interleaved to packed */ convertInputBuffer( inpInt16Buffer, numSamplesRead, frameSize_smpls, num_in_channels, inFloatBuffer ); - if ( masaReader != NULL ) + for ( int32_t i = 0; i < RENDERER_MAX_MASA_INPUTS; ++i ) { - MasaFileReader_readNextFrame( masaReader ); - /* TODO: Feed MASA metadata here once MASA inputs are supported. - For now avoid unused var warning */ - (void) hMasaMetadata; + if ( masaReaders[i] != NULL ) + { + MasaFileReader_readNextFrame( masaReaders[i] ); + /* TODO: Feed MASA metadata here once MASA inputs are supported. + For now avoid unused var warning */ + (void) hMasaMetadata; + } } ObjectPositionBuffer mtdBuffer; @@ -801,7 +962,10 @@ int32_t main( int32_t argc, char **argv ) count_free( inFloatBuffer ); count_free( outInt16Buffer ); count_free( outFloatBuffer ); - MasaFileReader_close( &masaReader ); + for ( int32_t i = 0; i < RENDERER_MAX_MASA_INPUTS; ++i ) + { + MasaFileReader_close( &masaReaders[i] ); + } AudioFileReader_close( &audioReader ); AudioFileWriter_close( &audioWriter ); HeadRotationFileReader_close( &headRotReader ); @@ -839,30 +1003,29 @@ static IVAS_REND_AudioConfig ambisonicsOrderToEnum( int32_t order ) return IVAS_REND_AUDIO_CONFIG_UNKNOWN; } -static bool parseInConfig( char **optionValues, CmdlnArgs *args ) +static bool parseInConfig( const char *inFormatStr, InputConfig *inConfig, bool *sceneDescriptionInput ) { - InputConfig inConfig; char charBuf[FILENAME_MAX]; /* Initialize input config struct */ - inConfig.numAudioObjects = 0; - inConfig.numAmbisonicsBuses = 0; - inConfig.numMultiChannelBuses = 0; - inConfig.numMasaBuses = 0; + inConfig->numAudioObjects = 0; + inConfig->numAmbisonicsBuses = 0; + inConfig->numMultiChannelBuses = 0; + inConfig->numMasaBuses = 0; /* First check if input is being set to scene description file - this is not covered by parseAudioConfig(). */ - strncpy( charBuf, optionValues[0], sizeof( charBuf ) - 1 ); + strncpy( charBuf, inFormatStr, sizeof( charBuf ) - 1 ); to_upper( charBuf ); if ( strcmp( charBuf, "META" ) == 0 ) { - args->sceneDescriptionInput = true; + *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 IVAS_REND_AudioConfig enum. */ - IVAS_REND_AudioConfig audioConfig = parseAudioConfig( optionValues[0] ); + IVAS_REND_AudioConfig audioConfig = parseAudioConfig( inFormatStr ); switch ( audioConfig ) { case IVAS_REND_AUDIO_CONFIG_MONO: @@ -872,47 +1035,47 @@ static bool parseInConfig( char **optionValues, CmdlnArgs *args ) case IVAS_REND_AUDIO_CONFIG_5_1_2: case IVAS_REND_AUDIO_CONFIG_5_1_4: case IVAS_REND_AUDIO_CONFIG_7_1_4: - inConfig.numMultiChannelBuses = 1; - inConfig.multiChannelBuses[0].audioConfig = audioConfig; - inConfig.multiChannelBuses[0].inputChannelIndex = 0; - inConfig.multiChannelBuses[0].gain_dB = 0.0f; + inConfig->numMultiChannelBuses = 1; + inConfig->multiChannelBuses[0].audioConfig = audioConfig; + inConfig->multiChannelBuses[0].inputChannelIndex = 0; + inConfig->multiChannelBuses[0].gain_dB = 0.0f; break; case IVAS_REND_AUDIO_CONFIG_FOA: case IVAS_REND_AUDIO_CONFIG_HOA2: case IVAS_REND_AUDIO_CONFIG_HOA3: - inConfig.numAmbisonicsBuses = 1; - inConfig.ambisonicsBuses[0].audioConfig = audioConfig; - inConfig.ambisonicsBuses[0].inputChannelIndex = 0; - inConfig.ambisonicsBuses[0].gain_dB = 0.0f; + inConfig->numAmbisonicsBuses = 1; + inConfig->ambisonicsBuses[0].audioConfig = audioConfig; + inConfig->ambisonicsBuses[0].inputChannelIndex = 0; + inConfig->ambisonicsBuses[0].gain_dB = 0.0f; break; case IVAS_REND_AUDIO_CONFIG_MASA1: case IVAS_REND_AUDIO_CONFIG_MASA2: - inConfig.numMasaBuses = 1; - inConfig.masaBus.audioConfig = audioConfig; - inConfig.masaBus.inputChannelIndex = 0; - inConfig.masaBus.gain_dB = 0.0f; + inConfig->numMasaBuses = 1; + inConfig->masaBuses[0].audioConfig = audioConfig; + inConfig->masaBuses[0].inputChannelIndex = 0; + inConfig->masaBuses[0].gain_dB = 0.0f; break; case IVAS_REND_AUDIO_CONFIG_OBJECT: /* If input format is objects, parse the characters after "ISM" to get number of objects */ { char *ptr = NULL; - inConfig.numAudioObjects = (uint16_t) strtol( optionValues[0] + 3, &ptr, 10 ); + inConfig->numAudioObjects = (uint16_t) strtol( inFormatStr + 3, &ptr, 10 ); if ( ptr == NULL || *ptr != '\0' ) { /* Failed to parse string as a number */ - fprintf( stderr, "Cannot parse string \"%s\" as a valid input format", optionValues[0] ); + fprintf( stderr, "Cannot parse string \"%s\" as a valid input format", inFormatStr ); return false; } - if ( inConfig.numAudioObjects > RENDERER_MAX_ISM_INPUTS ) + if ( inConfig->numAudioObjects > RENDERER_MAX_ISM_INPUTS ) { fprintf( stderr, "Too many objects at input. Max %d supported.", RENDERER_MAX_ISM_INPUTS ); return false; } - for ( int32_t i = 0; i < inConfig.numAudioObjects; ++i ) + for ( int32_t i = 0; i < inConfig->numAudioObjects; ++i ) { - inConfig.audioObjects[i].audioConfig = audioConfig; - inConfig.audioObjects[i].inputChannelIndex = i; - inConfig.audioObjects[i].gain_dB = 0.0f; + inConfig->audioObjects[i].audioConfig = audioConfig; + inConfig->audioObjects[i].inputChannelIndex = i; + inConfig->audioObjects[i].gain_dB = 0.0f; } } break; @@ -920,56 +1083,49 @@ static bool parseInConfig( char **optionValues, CmdlnArgs *args ) /* This case will be reached if parsing string to IVAS_REND_AudioConfig enum fails. * Try to use the given string as a path to a custom loudspeaker layout file. */ { - ivas_error error = parseCustomLayoutFile( optionValues[0], &inConfig.inSetupCustom ); + ivas_error error = parseCustomLayoutFile( inFormatStr, &inConfig->inSetupCustom ); if ( error == IVAS_ERR_FAILED_FILE_OPEN ) { /* Failed to open with given string - most likely wasn't a file path */ - fprintf( stderr, "Unsupported input format: %s\n", optionValues[0] ); + fprintf( stderr, "Unsupported input format: %s\n", inFormatStr ); return false; } if ( error != IVAS_ERR_OK ) { - fprintf( stderr, "Error while reading custom loudspeaker layout file %s\n", optionValues[0] ); + fprintf( stderr, "Error while reading custom loudspeaker layout file %s\n", inFormatStr ); return false; } - inConfig.numMultiChannelBuses = 1; - inConfig.multiChannelBuses[0].audioConfig = IVAS_REND_AUDIO_CONFIG_LS_CUSTOM; - inConfig.multiChannelBuses[0].inputChannelIndex = 0; - inConfig.multiChannelBuses[0].gain_dB = 0.0f; + inConfig->numMultiChannelBuses = 1; + inConfig->multiChannelBuses[0].audioConfig = IVAS_REND_AUDIO_CONFIG_LS_CUSTOM; + inConfig->multiChannelBuses[0].inputChannelIndex = 0; + inConfig->multiChannelBuses[0].gain_dB = 0.0f; } break; default: /* Default case covers formats that are defined in the IVAS_REND_AudioConfig enum, * but cannot be used at input, e.g. BINAURAL */ - fprintf( stderr, "Unsupported input format: %s\n", optionValues[0] ); + fprintf( stderr, "Unsupported input format: %s\n", inFormatStr ); return false; - break; } - args->inConfig = inConfig; - return true; } -static bool parseInMetadata( char **optionValues, int32_t numValues, CmdlnArgs *args ) +static bool parseOutConfig( const char *outputFormatStr, OutputConfig *outConfig ) { - char charBuf[FILENAME_MAX]; + ivas_error error; - for ( int32_t i = 0; i < numValues; ++i ) + outConfig->audioConfig = parseAudioConfig( outputFormatStr ); + /* If the string provided is not recognized as a valid output config, + * it's expected to be a path to a custom loudspeaker layout description file. */ + if ( outConfig->audioConfig == IVAS_REND_AUDIO_CONFIG_UNKNOWN ) { - strncpy( charBuf, optionValues[i], sizeof( charBuf ) - 1 ); - to_upper( charBuf ); - - if ( ( strcmp( charBuf, "NULL" ) == 0 ) ) - { - /* TODO(sgi): Test setting mtd file to NULL. Will default positions be provided? Seems that crash is likely in this case. */ - clearString( args->metaDataFiles[i] ); - } - else + outConfig->audioConfig = IVAS_REND_AUDIO_CONFIG_LS_CUSTOM; + if ( ( error = parseCustomLayoutFile( outputFormatStr, &outConfig->outSetupCustom ) ) != IVAS_ERR_OK ) { - strncpy( args->metaDataFiles[i], optionValues[i], FILENAME_MAX - 1 ); - convert_backslash( args->metaDataFiles[i] ); + fprintf( stderr, "Error while parsing output format option\n" ); + return false; } } @@ -1107,13 +1263,72 @@ static IVAS_REND_AudioConfig parseAudioConfig( const char *configString ) return IVAS_REND_AUDIO_CONFIG_UNKNOWN; } -static CmdlnArgs defaultArgs( void ) +static CmdLnParser_Option findOptionById( int32_t id ) +{ + + for ( int32_t i = 0; i < numCliOptions; ++i ) + { + if ( cliOptions[i].id == id ) + { + return cliOptions[i]; + } + } + + /* Return first option if ID not matched */ + return cliOptions[0]; +} + +static bool checkRequiredArgs( CmdlnArgs args ) +{ + 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.numAudioObjects != 0 || + args.inConfig.numAmbisonicsBuses != 0 || + args.inConfig.numMultiChannelBuses != 0 || + args.inConfig.numMasaBuses != 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.outConfig.audioConfig == IVAS_REND_AUDIO_CONFIG_UNKNOWN ) + { + tmpOption = findOptionById( CmdLnOptionId_outputFormat ); + 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, RENDERER_MAX_CLI_ARG_LENGTH ); clearString( args.inputFilePath ); clearString( args.outputFilePath ); - args.sampleRate = -1; + args.sampleRate = 0; args.inConfig.inSetupCustom.num_spk = 0; args.inConfig.inSetupCustom.num_lfe = 0; @@ -1126,118 +1341,87 @@ static CmdlnArgs defaultArgs( void ) args.outConfig.outSetupCustom.num_spk = 0; args.outConfig.outSetupCustom.num_lfe = 0; - args.orientationTracking = IVAS_ORIENT_TRK_REF; - clearString( args.trajectoryFile ); - clearString( args.customHrtfFile ); - clearString( args.renderConfigFile ); + for ( int32_t i = 0; i < RENDERER_MAX_ISM_INPUTS; ++i ) + { + clearString( args.inMetadataFilePaths[i] ); + } + args.numInMetadataFiles = 0; - args.noDiegeticPan = 0; + clearString( args.headRotationFilePath ); + clearString( args.customHrtfFilePath ); + clearString( args.renderConfigFilePath ); + + args.orientationTracking = IVAS_ORIENT_TRK_REF; + args.noDiegeticPan = 0.0f; args.delayCompensationEnabled = true; args.quietModeEnabled = false; args.sceneDescriptionInput = false; args.inputGainGlobal = 1.0f; - for ( size_t i = 0; i < RENDERER_MAX_ISM_INPUTS; i++ ) - { - clearString( args.metaDataFiles[i] ); - } - return args; } -typedef enum -{ - CmdLnOptionId_inputFile = 1, - CmdLnOptionId_inputFormat, - CmdLnOptionId_outputFile, - CmdLnOptionId_outputFormat, - CmdLnOptionId_sampleRate, - CmdLnOptionId_trajFile, - CmdLnOptionId_customHrtfFile, - CmdLnOptionId_renderConfigFile, - CmdLnOptionId_noDiegeticPan, - CmdLnOptionId_orientationTracking, - CmdLnOptionId_customLfeRouting, - CmdLnOptionId_noDelayCmp, - CmdLnOptionId_quietModeEnabled, - CmdLnOptionId_inputMetadata, - CmdLnOptionId_listFormats, - CmdLnOptionId_inputGain, -} CmdLnOptionId; - static void parseOption( int32_t optionId, char **optionValues, int16_t numOptionValues, void *pOutputStruct ) { - ivas_error error; CmdlnArgs *args = pOutputStruct; - /* TODO(sgi): Parsing currently depends on order in which the options are given by the user. - * This causes a lot of errors and is unmaintainable for options that depend on each other. - * - * Solution: save all option values here as strings, parse strings afterwards once all values are known. - */ - switch ( optionId ) { case CmdLnOptionId_listFormats: - /* TODO tmu2sgi : only works when -i is specified too */ assert( numOptionValues == 0 ); printSupportedAudioConfigs(); exit( 0 ); case CmdLnOptionId_inputFile: assert( numOptionValues == 1 ); - strncpy( args->inputFilePath, optionValues[0], FILENAME_MAX - 1 ); + strncpy( args->inputFilePath, optionValues[0], RENDERER_MAX_CLI_ARG_LENGTH - 1 ); break; case CmdLnOptionId_inputFormat: assert( numOptionValues == 1 ); - if ( !parseInConfig( optionValues, args ) ) + if ( !parseInConfig( optionValues[0], &args->inConfig, &args->sceneDescriptionInput ) ) { - fprintf( stderr, "Error while parsing input format option\n" ); - exit( -1 ); + exit( -1 ); /* Error printout handled by failing function */ } break; case CmdLnOptionId_inputMetadata: assert( numOptionValues <= RENDERER_MAX_ISM_INPUTS ); - if ( !parseInMetadata( optionValues, numOptionValues, args ) ) + for ( int32_t i = 0; i < numOptionValues; ++i ) { - fprintf( stderr, "Error while parsing input metadata option\n" ); - exit( -1 ); + strncpy( args->inMetadataFilePaths[i], optionValues[i], RENDERER_MAX_CLI_ARG_LENGTH - 1 ); } + args->numInMetadataFiles = numOptionValues; break; case CmdLnOptionId_outputFile: assert( numOptionValues == 1 ); - strncpy( args->outputFilePath, optionValues[0], FILENAME_MAX - 1 ); + strncpy( args->outputFilePath, optionValues[0], RENDERER_MAX_CLI_ARG_LENGTH - 1 ); break; case CmdLnOptionId_outputFormat: assert( numOptionValues == 1 ); - args->outConfig.audioConfig = parseAudioConfig( optionValues[0] ); - /* If the string provided is not recognized as a valid output config, - * it's expected to be a path to a custom loudspeaker layout description file. */ - if ( args->outConfig.audioConfig == IVAS_REND_AUDIO_CONFIG_UNKNOWN ) + if ( !parseOutConfig( optionValues[0], &args->outConfig ) ) { - args->outConfig.audioConfig = IVAS_REND_AUDIO_CONFIG_LS_CUSTOM; - if ( ( error = parseCustomLayoutFile( optionValues[0], &args->outConfig.outSetupCustom ) ) != IVAS_ERR_OK ) - { - fprintf( stderr, "Error while parsing output format option\n" ); - exit( -1 ); - } + exit( -1 ); /* Error printout handled by failing function */ } break; case CmdLnOptionId_sampleRate: assert( numOptionValues == 1 ); - args->sampleRate = (int32_t) ( strtof( optionValues[0], NULL ) * 1000 ); + 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->trajectoryFile, optionValues[0], FILENAME_MAX - 1 ); + strncpy( args->headRotationFilePath, optionValues[0], RENDERER_MAX_CLI_ARG_LENGTH - 1 ); break; case CmdLnOptionId_customHrtfFile: assert( numOptionValues == 1 ); - strncpy( args->customHrtfFile, optionValues[0], FILENAME_MAX - 1 ); + strncpy( args->customHrtfFilePath, optionValues[0], RENDERER_MAX_CLI_ARG_LENGTH - 1 ); break; case CmdLnOptionId_renderConfigFile: assert( numOptionValues == 1 ); - strncpy( args->renderConfigFile, optionValues[0], FILENAME_MAX - 1 ); + strncpy( args->renderConfigFilePath, optionValues[0], RENDERER_MAX_CLI_ARG_LENGTH - 1 ); break; case CmdLnOptionId_noDiegeticPan: assert( numOptionValues == 1 ); @@ -1268,7 +1452,12 @@ static void parseOption( int32_t optionId, char **optionValues, int16_t numOptio break; case CmdLnOptionId_inputGain: assert( numOptionValues == 1 ); - args->inputGainGlobal = (float) atof( optionValues[0] ); /* TODO(sgi): atof doesn't detect if string doesn't represent a number, just returns zero */ + args->inputGainGlobal = strtof( optionValues[0], NULL ); + if ( args->inputGainGlobal == 0.0f ) + { + fprintf( stderr, "Invalid input gain specified\n" ); + exit( -1 ); + } break; default: assert( 0 && "This should be unreachable - all command line options should be explicitly handled." ); @@ -1278,124 +1467,19 @@ static void parseOption( int32_t optionId, char **optionValues, int16_t numOptio static CmdlnArgs parseCmdlnArgs( int32_t argc, char **argv ) { - /* TODO tmu2sgi: "requiredness" depends on the order things are parsed in */ - CmdLnParser_Option optionsToMatch[] = { - { - .id = CmdLnOptionId_inputFile, - .match = "input_file", - .matchShort = "i", - .isRequired = true, - .description = "Path to the input file (WAV, raw PCM or scene description file)", - }, - { - .id = CmdLnOptionId_inputFormat, - .match = "input_format", - .matchShort = "if", - .isRequired = true, - .description = "Audio format of input file (e.g. 5_1 or HOA3 or META, use -l for a list)", - }, - { - /* TODO tmu2sgi : make required dependent on -if? */ - .id = CmdLnOptionId_inputMetadata, - .match = "input_metadata", - .matchShort = "im", - .description = "Space-separated list of path to metadata files for ISM or MASA inputs", - }, - { - .id = CmdLnOptionId_outputFile, - .match = "output_file", - .matchShort = "o", - .isRequired = true, - .description = "Path to the output file", - }, - { - .id = CmdLnOptionId_outputFormat, - .match = "output_format", - .matchShort = "of", - .isRequired = true, - .description = "Output format to render.\nAlternatively, can be a custom loudspeaker layout file", - }, - { - .id = CmdLnOptionId_sampleRate, - .match = "sample_rate", - .matchShort = "fs", - .isRequired = true, /* TODO(sgi): Shouldn't be required */ - .description = "Input sampling rate in kHz (16, 32, 48)", /* TODO(sgi): Add sampling rate to scene description files */ - }, - { - .id = CmdLnOptionId_trajFile, - .match = "trajectory_file", - .matchShort = "tf", - .description = "Head rotation trajectory file for simulation of head tracking (only for BINAURAL and BINAURAL_ROOM outputs)", - }, - { - .id = CmdLnOptionId_customHrtfFile, - .match = "custom_hrtf", - .matchShort = "hrtf", - .description = "Custom HRTF file for binaural rendering (only for BINAURAL and BINAURAL_ROOM outputs)", - }, - { - .id = CmdLnOptionId_renderConfigFile, - .match = "render_config", - .matchShort = "rc", - .description = "Binaural renderer configuration file (only for BINAURAL and BINAURAL_ROOM outputs)", - }, - { - .id = CmdLnOptionId_noDiegeticPan, - .match = "no_diegetic_pan", - .matchShort = "ndp", - .description = "Panning mono no diegetic sound to stereo -1<= pan <= 1\nleft or l or 1->left, right or r or -1->right, center or c or 0 ->middle\n(todo: implementation)", - }, - { - .id = CmdLnOptionId_orientationTracking, - .match = "tracking_type", - .matchShort = "otr", - .description = "Head orientation tracking type: 'ref' or 'avg' (only for BINAURAL and BINAURAL_ROOM) (todo: check implementation)", - }, - { - /* TODO(sgi): Replace with more configurable input, e.g. ask for a list of triplets: (gain, azimuth, elevation) to place LFE signal */ - /* rename to "lfeHandling" */ - .id = CmdLnOptionId_customLfeRouting, - .match = "neverDropLfe", - .matchShort = "ndl", - .description = "[flag] If set, renderer tries to render LFE into other channels in an optimal way when rendering to configs w/o LFE", - }, - { - .id = CmdLnOptionId_noDelayCmp, - .match = "no_delay_cmp", - .matchShort = "ndc", - .description = "[flag] Turn off delay compensation", - }, - { - .id = CmdLnOptionId_quietModeEnabled, - .match = "quiet", - .matchShort = "q", - .description = "[flag] Limit printouts to terminal", - }, - { - .id = CmdLnOptionId_inputGain, - .match = "gain", - .matchShort = "g", - .description = "Input gain (linear, not in dB) to be applied to input audio file", - }, - { - .id = CmdLnOptionId_listFormats, - .match = "list", - .matchShort = "l", - .description = "List supported audio formats", - }, - }; + CmdlnArgs args = defaultArgs( argv[0] ); - CmdlnArgs parsedArgs = defaultArgs(); - int32_t numOptions = sizeof( optionsToMatch ) / sizeof( CmdLnParser_Option ); + if ( CmdLnParser_parseArgs( argc, argv, cliOptions, numCliOptions, &args, parseOption ) != 0 ) + { + exit( -1 ); /* Error printout handled by failing function */ + } - if ( CmdLnParser_parseArgs( argc, argv, optionsToMatch, numOptions, &parsedArgs, parseOption ) != 0 ) + if ( !checkRequiredArgs( args ) ) { - /* Error printout handled internally by CmdLnParser_parseArgs() */ - exit( -1 ); + exit( -1 ); /* Error printout handled by failing function */ } - return parsedArgs; + return args; } @@ -1760,12 +1844,12 @@ static void parseIsm( else /* If not a number, it is a relative path from main metadata file to a metadata file */ { char fullpath[FILENAME_MAX]; - *fullpath = '\0'; + fullpath[0] = '\0'; strncat( fullpath, inDir, strlen( inDir ) ); strncat( fullpath, line, sizeof( fullpath ) - strlen( fullpath ) - 1 ); if ( ( positionProvider->ismReaders[idx] = IsmFileReader_open( fullpath ) ) == NULL ) { - fprintf( stderr, "Error: ISM input metadata file %s could not be opened\n", line ); + fprintf( stderr, "Error: ISM input metadata file %s could not be opened\n", fullpath ); exit( -1 ); } } @@ -1817,12 +1901,14 @@ static void parseMc( char *line, static void parseMasa( char *line, + char *inDir, InputConfig *inConfig, - char *masaMetadataFilePath ) + MasaFileReader **masaReaders, + int32_t idx ) { readNextMetadataChunk( line, "\n" ); - parseInt32( line, &inConfig->masaBus.inputChannelIndex ); - --inConfig->masaBus.inputChannelIndex; /* Convert from 1-indexing */ + parseInt32( line, &inConfig->masaBuses[idx].inputChannelIndex ); + --inConfig->masaBuses[idx].inputChannelIndex; /* Convert from 1-indexing */ readNextMetadataChunk( line, "\n" ); @@ -1833,17 +1919,27 @@ static void parseMasa( sprintf( line, "MASA%c", numTcs ); } - inConfig->masaBus.audioConfig = parseAudioConfig( line ); + inConfig->masaBuses[idx].audioConfig = parseAudioConfig( line ); readNextMetadataChunk( line, "\n" ); - strcpy( masaMetadataFilePath, line ); + + char fullpath[FILENAME_MAX]; + fullpath[0] = '\0'; + strncat( fullpath, inDir, strlen( inDir ) ); + strncat( fullpath, line, sizeof( fullpath ) - strlen( fullpath ) - 1 ); + + if ( ( masaReaders[idx] = MasaFileReader_open( fullpath ) ) == NULL ) + { + fprintf( stderr, "Error: MASA metadata file %s could not be opened\n", fullpath ); + exit( -1 ); + } /* Read optional values */ - parseOptionalInputValues( line, &inConfig->masaBus.gain_dB ); + parseOptionalInputValues( line, &inConfig->masaBuses[idx].gain_dB ); } static ivas_error parseCustomLayoutFile( - char *filePath, + const char *filePath, IVAS_CUSTOM_LS_DATA *pLsSetupCustom ) { LsCustomFileReader *hLsCustomReader = NULL; @@ -1878,7 +1974,7 @@ static void parseMetadata( char *inDir, InputConfig *inConfig, IsmPositionProvider *positionProvider, - char *masaMetadataFilePath ) + MasaFileReader** masaReaders ) { char line[RENDERER_MAX_METADATA_LINE_LENGTH]; char *delimiter; @@ -1960,9 +2056,9 @@ static void parseMetadata( fprintf( stderr, "Metadata exceeds the supported number of MASA inputs\n" ); exit( -1 ); } - parseMasa( line, inConfig, masaMetadataFilePath ); + parseMasa( line, inDir, inConfig, masaReaders, counterMasaInputs - 1 ); } - else if ( line[0] == '\0' ) + else if ( isEmptyString(line) ) { fprintf( stderr, "Metadata string too short - expected %d inputs, found %d.\n", totalNumberOfAudioObjects, num_parsed_inputs ); exit( -1 ); @@ -1991,17 +2087,15 @@ static void parseMetadata( } } -static void parseConfigFile( char *path, char *audioFilePath, InputConfig *inConfig, IsmPositionProvider *positionProvider, char *masaMetadataFilePath ) +static void parseSceneDescriptionFile( char *path, char *audioFilePath, InputConfig *inConfig, IsmPositionProvider *positionProvider, MasaFileReader** masaReaders ) { uint32_t inAudioFilePathLen; char inAudioFilePath[FILENAME_MAX]; - char inMasaFilePath[FILENAME_MAX]; uint32_t mtdStrLen; char mtdStr[RENDERER_MAX_METADATA_LENGTH]; char inDir[FILENAME_MAX]; char *lastSlash = NULL; - clearString( inMasaFilePath ); inAudioFilePathLen = FILENAME_MAX; mtdStrLen = RENDERER_MAX_METADATA_LENGTH; splitConfigFile( path, @@ -2015,7 +2109,7 @@ static void parseConfigFile( char *path, char *audioFilePath, InputConfig *inCon /* Trim config file path to get path to the dir containing it */ lastSlash = strrchr( path, SEP_FOLDER ); - *inDir = '\0'; + inDir[0] = '\0'; if ( lastSlash != NULL ) { strncat( inDir, path, ( lastSlash - path + 1 ) ); @@ -2026,15 +2120,7 @@ static void parseConfigFile( char *path, char *audioFilePath, InputConfig *inCon strcpy( audioFilePath, inDir ); strncat( audioFilePath, inAudioFilePath, inAudioFilePathLen ); - parseMetadata( mtdStr, inDir, inConfig, positionProvider, inMasaFilePath ); - - /* Append MASA file path (relative to config file location) - * to config file location path to get full absolute path */ - if ( inMasaFilePath[0] != '\0' ) - { - strcpy( masaMetadataFilePath, inDir ); - strcat( masaMetadataFilePath, inMasaFilePath ); - } + parseMetadata( mtdStr, inDir, inConfig, positionProvider, masaReaders ); } static void printSupportedAudioConfigs() @@ -2106,6 +2192,11 @@ static void clearString( char *str ) str[0] = '\0'; } +static bool isEmptyString( const char *str ) +{ + return str[0] == '\0'; +} + /*--------------------------------------------------------------------------* * convertInputBuffer() * diff --git a/lib_util/audio_file_reader.c b/lib_util/audio_file_reader.c index d391735a94..d2c38cbb17 100644 --- a/lib_util/audio_file_reader.c +++ b/lib_util/audio_file_reader.c @@ -32,6 +32,7 @@ #include "audio_file_reader.h" #include "tinywavein_c.h" +#include #include #include "wmops.h" @@ -54,12 +55,13 @@ static int8_t AudioFileReader_open_raw( static int8_t AudioFileReader_open_wav( AudioFileReader *self, const char *fileName, - uint32_t expSampleRate ) + int32_t *sampleRate ) { - uint32_t sampleRate, samplesInFile; + uint32_t sampleRate_, samplesInFile; int16_t bps; - self->wavFile = OpenWav( fileName, &sampleRate, &self->numChannels, &samplesInFile, &bps ); + self->wavFile = OpenWav( fileName, &sampleRate_, &self->numChannels, &samplesInFile, &bps ); + *sampleRate = sampleRate_; if ( !self->wavFile ) { @@ -67,21 +69,15 @@ static int8_t AudioFileReader_open_wav( return -1; } - if ( sampleRate != expSampleRate ) - { - fprintf( stderr, "Input wav file has unexpected samplerate (should be %d): %s\n", expSampleRate, fileName ); - return -1; - } - return 0; } /*! r: AudioFileReader handle */ ivas_error AudioFileReader_open( - AudioFileReader **audioReader, /* o : AudioFileReader handle */ - const char *fileName, /* i : path to wav/raw pcm file */ - uint32_t expSampleRate /* i : expected sample rate */ + AudioFileReader **audioReader, /* o : AudioFileReader handle */ + const char *fileName, /* i : path to wav/raw pcm file */ + int32_t *sampleRate /* o : sample rate of wav file, unused with pcm */ ) { AudioFileReader *self; @@ -108,7 +104,7 @@ ivas_error AudioFileReader_open( if ( fileNameLen > wavSuffixLen && strncmp( fileName + fileNameLen - wavSuffixLen, wavSuffix, wavSuffixLen ) == 0 ) { - retCode = AudioFileReader_open_wav( self, fileName, expSampleRate ); + retCode = AudioFileReader_open_wav( self, fileName, sampleRate ); } else { diff --git a/lib_util/audio_file_reader.h b/lib_util/audio_file_reader.h index d878e3cab4..0fc9b1f4a1 100644 --- a/lib_util/audio_file_reader.h +++ b/lib_util/audio_file_reader.h @@ -42,9 +42,9 @@ typedef struct AudioFileReader AudioFileReader; /* clang-format off */ ivas_error AudioFileReader_open( - AudioFileReader **audioReader, /* o : AudioFileReader handle */ - const char *fileName, /* i : path to wav/raw pcm file */ - uint32_t expSampleRate /* i : expected sample rate */ + AudioFileReader **audioReader, /* o : AudioFileReader handle */ + const char *fileName, /* i : path to wav/raw pcm file */ + int32_t *sampleRate /* o : sample rate of wav file, unused with pcm */ ); /*! r: number of read samples */ diff --git a/lib_util/cmdln_parser.c b/lib_util/cmdln_parser.c index 323ed3fee6..1904f880be 100644 --- a/lib_util/cmdln_parser.c +++ b/lib_util/cmdln_parser.c @@ -208,9 +208,8 @@ static int16_t parseOpts( int32_t argc, } /* If current argument is a recognized option or no more arguments left, parse current option into output struct*/ - if ( nextOpt != NULL || argIdx + 1 == argc ) + if ( nextOpt != NULL ) { - /* currOpt will be NULL when first nextOpt matches */ if ( currOpt != NULL ) { parseOption( currOpt->props.id, &argv[currOptIdx + 1], numValues, pOutputStruct ); @@ -225,21 +224,11 @@ static int16_t parseOpts( int32_t argc, } } - return 0; -} - -static int16_t validateOpts( const Option *opts, - int32_t numOpts ) -{ - for ( int32_t i = 0; i < numOpts; ++i ) + /* Parse last option */ + if ( currOpt != NULL ) { - const Option *currOpt = &opts[i]; - - if ( currOpt->props.isRequired && !currOpt->hasBeenParsed ) - { - fprintf( stderr, "Error: option --%s (-%s) is required, but was not provided\n", currOpt->props.match, currOpt->props.matchShort ); - return -1; - } + parseOption( currOpt->props.id, &argv[currOptIdx + 1], numValues, pOutputStruct ); + currOpt->hasBeenParsed = 1; } return 0; @@ -361,15 +350,16 @@ int16_t CmdLnParser_parseArgs( int32_t argc, goto fail; } - /* Validate parsed options */ - if ( validateOpts( opts, numOptions ) != 0 ) - { - goto fail; - } - return 0; fail: printUsage( argv[0], optionProps, numOptions ); return -1; } + +void CmdLnParser_printUsage( char *executableName, + const CmdLnParser_Option *options, + int32_t numOptions ) +{ + printUsage( executableName, options, numOptions ); +} diff --git a/lib_util/cmdln_parser.h b/lib_util/cmdln_parser.h index a50defcdbb..8fecc70d9e 100644 --- a/lib_util/cmdln_parser.h +++ b/lib_util/cmdln_parser.h @@ -43,7 +43,6 @@ typedef struct int32_t id; const char *match; const char *matchShort; - bool isRequired; const char *description; } CmdLnParser_Option; @@ -61,4 +60,8 @@ int16_t CmdLnParser_parseArgs( int32_t argc, void *pOutputStruct, CmdLnParser_FnPtr_ParseOption parseOption ); +void CmdLnParser_printUsage( char *executableName, + const CmdLnParser_Option *options, + int32_t numOptions ); + #endif /* CMDLN_PARSER_H */ diff --git a/lib_util/ls_custom_file_reader.c b/lib_util/ls_custom_file_reader.c index 1713f55af4..58d78de068 100644 --- a/lib_util/ls_custom_file_reader.c +++ b/lib_util/ls_custom_file_reader.c @@ -52,7 +52,7 @@ struct LsCustomFileReader *-----------------------------------------------------------------------*/ ivas_error CustomLsReader_open( - char *LsFilePath, /* i : LS custom layout file name */ + const char *LsFilePath, /* i : LS custom layout file name */ LsCustomFileReader **hLsCustomReader /* o : HeadRotFileReader handle */ ) { diff --git a/lib_util/ls_custom_file_reader.h b/lib_util/ls_custom_file_reader.h index 3f9e0d56d3..e35c06ea88 100644 --- a/lib_util/ls_custom_file_reader.h +++ b/lib_util/ls_custom_file_reader.h @@ -65,7 +65,7 @@ typedef enum _LS_CUSTOM_FILEREADER_ERROR *-----------------------------------------------------------------------*/ ivas_error CustomLsReader_open( - char *LsFilePath, /* i : LS custom layout file name */ + const char *LsFilePath, /* i : LS custom layout file name */ LsCustomFileReader **hLsCustomReader /* o : HeadRotFileReader handle */ ); -- GitLab From fbbe2a201c83314c7b9848f5627feb120c29f5d2 Mon Sep 17 00:00:00 2001 From: Kacper Sagnowski Date: Tue, 18 Oct 2022 10:28:09 +0200 Subject: [PATCH 037/101] Include missing change from last commit --- apps/renderer.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/apps/renderer.c b/apps/renderer.c index 17bd22fdd7..6b229bd66f 100644 --- a/apps/renderer.c +++ b/apps/renderer.c @@ -1263,31 +1263,30 @@ static IVAS_REND_AudioConfig parseAudioConfig( const char *configString ) return IVAS_REND_AUDIO_CONFIG_UNKNOWN; } -static CmdLnParser_Option findOptionById( int32_t id ) +static const CmdLnParser_Option* findOptionById( int32_t id ) { for ( int32_t i = 0; i < numCliOptions; ++i ) { if ( cliOptions[i].id == id ) { - return cliOptions[i]; + return &cliOptions[i]; } } - /* Return first option if ID not matched */ - return cliOptions[0]; + return NULL; } static bool checkRequiredArgs( CmdlnArgs args ) { - CmdLnParser_Option tmpOption; + 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 ); + fprintf( stderr, "Missing required argument: %s (%s)\n", tmpOption->match, tmpOption->matchShort ); missingRequiredArg = true; } const bool singleInputSpecified = args.inConfig.numAudioObjects != 0 || @@ -1298,19 +1297,19 @@ static bool checkRequiredArgs( CmdlnArgs args ) { /* 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 ); + 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 ); + fprintf( stderr, "Missing required argument: %s (%s)\n", tmpOption->match, tmpOption->matchShort ); missingRequiredArg = true; } if ( args.outConfig.audioConfig == IVAS_REND_AUDIO_CONFIG_UNKNOWN ) { tmpOption = findOptionById( CmdLnOptionId_outputFormat ); - fprintf( stderr, "Missing required argument: %s (%s)\n", tmpOption.match, tmpOption.matchShort ); + fprintf( stderr, "Missing required argument: %s (%s)\n", tmpOption->match, tmpOption->matchShort ); missingRequiredArg = true; } if ( missingRequiredArg ) -- GitLab From d5f00f39299d3b3c1e23d48b58a144ad9a8d899a Mon Sep 17 00:00:00 2001 From: Kacper Sagnowski Date: Tue, 18 Oct 2022 10:29:45 +0200 Subject: [PATCH 038/101] Minor whitespace fix --- apps/renderer.c | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/renderer.c b/apps/renderer.c index 6b229bd66f..08dd6f4e0d 100644 --- a/apps/renderer.c +++ b/apps/renderer.c @@ -1265,7 +1265,6 @@ static IVAS_REND_AudioConfig parseAudioConfig( const char *configString ) static const CmdLnParser_Option* findOptionById( int32_t id ) { - for ( int32_t i = 0; i < numCliOptions; ++i ) { if ( cliOptions[i].id == id ) -- GitLab From 7f5f77b11358cb0228f8c1716a6ce0a050cd672e Mon Sep 17 00:00:00 2001 From: Archit Tamarapu Date: Wed, 19 Oct 2022 18:42:27 +0200 Subject: [PATCH 039/101] remove WMC_TOOL_MAN and fix instrumented build --- lib_rend/lib_rend.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index b31ffafac5..78522b1a83 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -1963,13 +1963,13 @@ ivas_error IVAS_REND_ConfigureCustomOutputLoudspeakerLayout( return error; } initLimiter( &hIvasRend->hLimiter, - numOutChannels, - hIvasRend->sampleRateOut ); + numOutChannels, + hIvasRend->sampleRateOut ); /* Re-initialize EFAP - output layout has changed or has been fully defined for the first time */ initEfap( &hIvasRend->efapOutWrapper, - hIvasRend->outputConfig, - &hIvasRend->customLsOut ); + hIvasRend->outputConfig, + &hIvasRend->customLsOut ); /* Re-initialize panning gains for each active MC input, This includes re-initializing * LFE handling for the new output layout, which means custom LFE handling is overwritten, @@ -2249,9 +2249,9 @@ ivas_error IVAS_REND_AddInput( /* Find first free input in array corresponding to input type */ if ( ( error = findFreeInputSlot( inputsArray, - inputStructSize, - maxNumInputsOfType, - &inputIndex ) ) != IVAS_ERR_OK ) + inputStructSize, + maxNumInputsOfType, + &inputIndex ) ) != IVAS_ERR_OK ) { return error; } @@ -3464,6 +3464,7 @@ static ivas_error renderMcCustomLsToBinauralRoom( ivas_error error; IVAS_REND_AudioBuffer tmpRotBuffer; IVAS_REND_AudioBuffer tmpMcBuffer; + IVAS_REND_AudioBuffer *tmpBufPtr; headRotEnabled = mcInput->base.ctx.pHeadRotData->headRotEnabled; @@ -3490,14 +3491,13 @@ static ivas_error renderMcCustomLsToBinauralRoom( tmpMcBuffer.data = count_malloc( tmpMcBuffer.config.numSamplesPerChannel * tmpMcBuffer.config.numChannels * sizeof( float ) ); set_zero( tmpMcBuffer.data, tmpMcBuffer.config.numSamplesPerChannel * tmpMcBuffer.config.numChannels ); + tmpBufPtr = ( headRotEnabled ) ? &tmpRotBuffer : &mcInput->base.inputBuffer; for ( i = 0; i < mcInput->base.inputBuffer.config.numChannels; i++ ) { -#define WMC_TOOL_MAN - renderBufferChannel( ( headRotEnabled ) ? tmpRotBuffer : mcInput->base.inputBuffer, + renderBufferChannel( *tmpBufPtr, i, mcInput->panGains[i], tmpMcBuffer ); -#undef WMC_TOOL_MAN } copyBufferTo2dArray( tmpMcBuffer, tmpCrendBuffer ); @@ -3743,6 +3743,7 @@ static ivas_error renderSbaToBinauralRoom( ivas_error error; IVAS_REND_AudioBuffer tmpRotBuffer; IVAS_REND_AudioBuffer tmpMcBuffer; + IVAS_REND_AudioBuffer *tmpBufPtr; headRotEnabled = sbaInput->base.ctx.pHeadRotData->headRotEnabled; @@ -3770,14 +3771,13 @@ static ivas_error renderSbaToBinauralRoom( set_zero( tmpMcBuffer.data, tmpMcBuffer.config.numChannels * tmpMcBuffer.config.numSamplesPerChannel ); + tmpBufPtr = ( headRotEnabled ) ? &tmpRotBuffer : &sbaInput->base.inputBuffer; for ( i = 0; i < sbaInput->base.inputBuffer.config.numChannels; i++ ) { -#define WMC_TOOL_MAN - renderBufferChannel( ( headRotEnabled ) ? tmpRotBuffer : sbaInput->base.inputBuffer, + renderBufferChannel( *tmpBufPtr, i, sbaInput->hoaDecMtx[i], tmpMcBuffer ); -#undef WMC_TOOL_MAN } copyBufferTo2dArray( tmpMcBuffer, tmpCrendBuffer ); -- GitLab From a815f3b736cb48bdc19890498cbb19b7c1adfd81 Mon Sep 17 00:00:00 2001 From: Remco Stoutjesdijk Date: Fri, 21 Oct 2022 00:04:40 +0200 Subject: [PATCH 040/101] added get/feed renderconfig --- apps/renderer.c | 50 +++++++++++++++++++++++++-- lib_rend/lib_rend.c | 82 +++++++++++++++++++++++++++++++++++++++++++++ lib_rend/lib_rend.h | 10 ++++++ 3 files changed, 139 insertions(+), 3 deletions(-) diff --git a/apps/renderer.c b/apps/renderer.c index 3369dfcee2..66c0a01d07 100644 --- a/apps/renderer.c +++ b/apps/renderer.c @@ -40,10 +40,10 @@ #include "hrtf_file_reader.h" #include "ism_file_reader.h" #include "lib_rend.h" +#include "render_config_reader.h" #include "ls_custom_file_reader.h" #include "masa_file_reader.h" #include "prot.h" -#include "render_config_reader.h" #ifdef WMOPS #include "PROM_Size_lib_rend.h" #include "wmops.h" @@ -460,8 +460,11 @@ int32_t main( int32_t argc, char **argv ) if ( args.renderConfigFile[0] != '\0' ) { - RenderConfigReader_open( args.renderConfigFile, &renderConfigReader ); - } + if ( ( error = RenderConfigReader_open( args.renderConfigFile, &renderConfigReader ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nError: Can't open Renderer configuration file %s \n\n", args.renderConfigFile ); + exit( -1 ); + } } if ( args.sceneDescriptionInput ) { @@ -585,6 +588,47 @@ int32_t main( int32_t argc, char **argv ) hMasaMetadata = MasaFileReader_getMetadataHandle( masaReader ); } + if ( args.renderConfigFile[0] != '\0' ) + { + IVAS_RENDER_CONFIG_DATA renderConfig; + + /* sanity check */ +/* if ( args.outConfig.audioConfig != IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM ) + { + fprintf( stderr, "\nExternal Renderer Config is supported only when BINAURAL_ROOM is used as output. Exiting. \n" ); + exit( -1 ); // goto cleanup; + } + + if ( ( error = ivas_render_config_open( &hIvasRend->hRendererConfig ) ) != IVAS_ERR_OK ) + { + ivas_render_config_open(&renderConfig); + return error; + } + + if ( ivas_render_config_init_from_rom( &st->hRendererConfig, st->rendererConfigEnabled ) != IVAS_ERR_OK ) + { + return IVAS_ERR_INTERNAL_FATAL; + } +*/ + if ( ( error = IVAS_REND_GetRenderConfig( hIvasRend, &renderConfig ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nIVAS_DEC_GetRenderConfig failed\n" ); + exit( -1 ); // goto cleanup; + } + + if ( RenderConfigReader_read( renderConfigReader, &renderConfig ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Failed to read renderer configuration from file %s\n", args.renderConfigFile ); + exit( -1 ); // goto cleanup; + } + + if ( ( error = IVAS_REND_FeedRenderConfig( hIvasRend, renderConfig ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nIVAS_DEC_FeedRenderConfig failed\n" ); + exit( -1 ); // goto cleanup; + } + } + int32_t numOutChannels; if ( ( error = IVAS_REND_NumOutChannels( hIvasRend, &numOutChannels ) ) != IVAS_ERR_OK ) { diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index b31ffafac5..5fb320e01a 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -152,6 +152,7 @@ struct IVAS_REND EFAP_WRAPPER efapOutWrapper; IVAS_LSSETUP_CUSTOM_STRUCT customLsOut; IVAS_REND_HeadRotData headRotData; + RENDER_CONFIG_DATA *hRendererConfig; /* Renderer config pointer */ }; static int32_t limitRendererOutput( @@ -2627,6 +2628,87 @@ ivas_error IVAS_REND_FeedInputObjectMetadata( return IVAS_ERR_OK; } + +int16_t IVAS_REND_GetRenderConfig( + IVAS_REND_HANDLE hIvasRend, /* i/o: IVAS decoder handle */ + const IVAS_RENDER_CONFIG_HANDLE hRCout /* o : Render configuration handle */ +) +{ + RENDER_CONFIG_HANDLE hRCin; + + if ( hIvasRend == NULL || hIvasRend->hRendererConfig == NULL || hRCout == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + hRCin = hIvasRend->hRendererConfig; +#ifdef DEBUGGING + switch ( hRCin->renderer_type_override ) + { + case RENDER_TYPE_OVERRIDE_CREND: + hRCout->renderer_type_override = IVAS_RENDER_TYPE_OVERRIDE_CREND; + break; + case 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->room_acoustics.override = hRCin->roomAcoustics.override; + hRCout->room_acoustics.use_brir = hRCin->roomAcoustics.use_brir; + hRCout->room_acoustics.late_reverb_on = hRCin->roomAcoustics.late_reverb_on; + hRCout->room_acoustics.nBands = hRCin->roomAcoustics.nBands; + hRCout->room_acoustics.acousticPreDelay = hRCin->roomAcoustics.acousticPreDelay; + hRCout->room_acoustics.inputPreDelay = hRCin->roomAcoustics.inputPreDelay; + + mvr2r( hRCin->roomAcoustics.pFc_input, hRCout->room_acoustics.pFc_input, CLDFB_NO_CHANNELS_MAX ); + mvr2r( hRCin->roomAcoustics.pAcoustic_rt60, hRCout->room_acoustics.pAcoustic_rt60, CLDFB_NO_CHANNELS_MAX ); + mvr2r( hRCin->roomAcoustics.pAcoustic_dsr, hRCout->room_acoustics.pAcoustic_dsr, CLDFB_NO_CHANNELS_MAX ); + + return IVAS_ERR_OK; +} + + +int16_t IVAS_REND_FeedRenderConfig( + IVAS_REND_HANDLE hIvasRend, /* i/o: IVAS decoder handle */ + const IVAS_RENDER_CONFIG_DATA renderConfig /* i : Render configuration struct */ +) +{ + RENDER_CONFIG_HANDLE hRenderConfig; + + if ( hIvasRend == NULL || hIvasRend->hRendererConfig == NULL ) + { + return IVAS_ERR_UNEXPECTED_NULL_POINTER; + } + + hRenderConfig = hIvasRend->hRendererConfig; +#ifdef DEBUGGING + hRenderConfig->renderer_type_override = RENDER_TYPE_OVERRIDE_NONE; + if ( renderConfig.renderer_type_override == IVAS_RENDER_TYPE_OVERRIDE_FASTCONV ) + { + hRenderConfig->renderer_type_override = RENDER_TYPE_OVERRIDE_FASTCONV; + } + if ( renderConfig.renderer_type_override == IVAS_RENDER_TYPE_OVERRIDE_CREND ) + { + hRenderConfig->renderer_type_override = RENDER_TYPE_OVERRIDE_CREND; + } +#endif + hRenderConfig->roomAcoustics.override = renderConfig.room_acoustics.override; + hRenderConfig->roomAcoustics.use_brir = renderConfig.room_acoustics.use_brir; + hRenderConfig->roomAcoustics.late_reverb_on = renderConfig.room_acoustics.late_reverb_on; + hRenderConfig->roomAcoustics.nBands = renderConfig.room_acoustics.nBands; + hRenderConfig->roomAcoustics.acousticPreDelay = renderConfig.room_acoustics.acousticPreDelay; + hRenderConfig->roomAcoustics.inputPreDelay = renderConfig.room_acoustics.inputPreDelay; + mvr2r( renderConfig.room_acoustics.pFc_input, hRenderConfig->roomAcoustics.pFc_input, CLDFB_NO_CHANNELS_MAX ); + mvr2r( renderConfig.room_acoustics.pAcoustic_rt60, hRenderConfig->roomAcoustics.pAcoustic_rt60, CLDFB_NO_CHANNELS_MAX ); + mvr2r( renderConfig.room_acoustics.pAcoustic_dsr, hRenderConfig->roomAcoustics.pAcoustic_dsr, CLDFB_NO_CHANNELS_MAX ); + + return IVAS_ERR_OK; +} + + ivas_error IVAS_REND_SetHeadRotation( IVAS_REND_HANDLE hIvasRend, const IVAS_QUATERNION headRot[RENDERER_HEAD_POSITIONS_PER_FRAME] ) diff --git a/lib_rend/lib_rend.h b/lib_rend/lib_rend.h index 3be9ad9964..6093228adc 100644 --- a/lib_rend/lib_rend.h +++ b/lib_rend/lib_rend.h @@ -234,6 +234,16 @@ ivas_error IVAS_REND_FeedInputMasaMetadata( void* TODO ); +int16_t IVAS_REND_GetRenderConfig( + IVAS_REND_HANDLE hIvasRend, /* i/o: IVAS decoder handle */ + const IVAS_RENDER_CONFIG_HANDLE hRCout /* o : Render configuration handle */ +); + +int16_t IVAS_REND_FeedRenderConfig( + IVAS_REND_HANDLE hIvasRend, /* i/o: IVAS decoder handle */ + const IVAS_RENDER_CONFIG_DATA renderConfig /* i : Render configuration struct */ +); + ivas_error IVAS_REND_SetHeadRotation( IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ const IVAS_QUATERNION headRot[RENDERER_HEAD_POSITIONS_PER_FRAME] /* i : head positions for next rendering call */ -- GitLab From fea97932aed2b5654bcbabee1b99d21391e05938 Mon Sep 17 00:00:00 2001 From: Archit Tamarapu Date: Fri, 21 Oct 2022 14:24:29 +0200 Subject: [PATCH 041/101] cherry-pick commit b3e6e7ffb03d87f129cd3dacda1cb78d9f66d9d7 "correction lfe handling in MC to binaural case, bugs fix" manual merge of some files --- .gitignore | 7 +- CMakeLists.txt | 6 ++ apps/renderer.c | 18 ++--- lib_com/ivas_cnst.h | 2 + lib_rend/ivas_limiter.c | 16 +--- lib_rend/lib_rend.c | 1 - .../unit_tests/crend/ivas_crend_io_parse.h | 2 + .../unit_tests/crend/ivas_crend_unit_test.c | 4 + .../unit_tests/crend/ivas_crend_utest_utils.c | 76 ++++++++----------- .../unit_tests/crend/ivas_dec_parse_io.h | 1 + scripts/pyaudio3dtools/binauralrenderer.py | 52 +++++++++---- scripts/tests/constants.py | 41 +++++++++- scripts/tests/data/dirac_12ch_48khz.wav | 3 + scripts/tests/test_renderer.py | 69 ++++++++++++++++- 14 files changed, 211 insertions(+), 87 deletions(-) create mode 100644 scripts/tests/data/dirac_12ch_48khz.wav diff --git a/.gitignore b/.gitignore index 1ec17a4b20..55a113e4bb 100644 --- a/.gitignore +++ b/.gitignore @@ -4,18 +4,20 @@ IVAS_cod IVAS_dec IVAS_rend +IVAS_crend_unit_test obj/ *.a *.o *.P # default CMake -build/**/* +build*/**/* # Compiler output VS2017 IVAS_cod.exe IVAS_dec.exe IVAS_rend.exe +IVAS_crend_unit_test.exe *.user .vs/ Debug_*/ @@ -54,3 +56,6 @@ tests/ref __pycache__/ *.py[cod] *$py.class + +#history +.history/ diff --git a/CMakeLists.txt b/CMakeLists.txt index 806f1f3e2a..d0dccdee5d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -152,6 +152,11 @@ file(GLOB libUtilSrcs "lib_util/*.c") file(GLOB libUtilHeaders "lib_util/*.h") add_library(lib_util ${libUtilSrcs} ${libUtilHeaders}) +file(GLOB libCRendSrcs "scripts/ivas_pytests/tests/unit_tests/crend/*.c") +file(GLOB libCRendHeaders "scripts/ivas_pytests/tests/unit_tests/crend/*.h") +add_executable(IVAS_crend_unit_test ${libCRendSrcs} ${libCRendHeaders}) +target_link_libraries(IVAS_crend_unit_test lib_dec lib_rend lib_util lib_com lib_debug) + add_executable(IVAS_cod apps/encoder.c) target_link_libraries(IVAS_cod lib_enc lib_util) if(WIN32) @@ -172,4 +177,5 @@ if(COPY_EXECUTABLES_TO_ROOT) 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}/") + add_custom_command(TARGET IVAS_crend_unit_test POST_BUILD VERBATIM COMMAND "${CMAKE_COMMAND}" -E copy "$" "${CMAKE_CURRENT_SOURCE_DIR}/") endif() \ No newline at end of file diff --git a/apps/renderer.c b/apps/renderer.c index 08dd6f4e0d..5eb517740b 100644 --- a/apps/renderer.c +++ b/apps/renderer.c @@ -323,7 +323,7 @@ static void parseSceneDescriptionFile( char *audioFilePath, InputConfig *inConfig, IsmPositionProvider *positionProvider, - MasaFileReader** masaReaders ); + MasaFileReader **masaReaders ); static ivas_error parseCustomLayoutFile( const char *filePath, @@ -390,7 +390,7 @@ static void parseMetadata( char *inDir, InputConfig *inConfig, IsmPositionProvider *positionProvider, - MasaFileReader** masaReaders ); + MasaFileReader **masaReaders ); static void convert_backslash( char *str ); @@ -1263,7 +1263,7 @@ static IVAS_REND_AudioConfig parseAudioConfig( const char *configString ) return IVAS_REND_AUDIO_CONFIG_UNKNOWN; } -static const CmdLnParser_Option* findOptionById( int32_t id ) +static const CmdLnParser_Option *findOptionById( int32_t id ) { for ( int32_t i = 0; i < numCliOptions; ++i ) { @@ -1278,7 +1278,7 @@ static const CmdLnParser_Option* findOptionById( int32_t id ) static bool checkRequiredArgs( CmdlnArgs args ) { - const CmdLnParser_Option* tmpOption; + const CmdLnParser_Option *tmpOption; /* Check required arguments */ bool missingRequiredArg = false; @@ -1649,7 +1649,7 @@ static void splitConfigFile( const char *mdfFilePath, fprintf( stderr, "Error reading metadata\n" ); exit( -1 ); } - *wavFileNameLength = strlen( wavFileName ); + *wavFileNameLength = (uint32_t) strlen( wavFileName ); mdlength = bufferlength - currentPositionIdxs; /* "+1" for null termination */ @@ -1972,7 +1972,7 @@ static void parseMetadata( char *inDir, InputConfig *inConfig, IsmPositionProvider *positionProvider, - MasaFileReader** masaReaders ) + MasaFileReader **masaReaders ) { char line[RENDERER_MAX_METADATA_LINE_LENGTH]; char *delimiter; @@ -2056,7 +2056,7 @@ static void parseMetadata( } parseMasa( line, inDir, inConfig, masaReaders, counterMasaInputs - 1 ); } - else if ( isEmptyString(line) ) + else if ( isEmptyString( line ) ) { fprintf( stderr, "Metadata string too short - expected %d inputs, found %d.\n", totalNumberOfAudioObjects, num_parsed_inputs ); exit( -1 ); @@ -2085,7 +2085,7 @@ static void parseMetadata( } } -static void parseSceneDescriptionFile( char *path, char *audioFilePath, InputConfig *inConfig, IsmPositionProvider *positionProvider, MasaFileReader** masaReaders ) +static void parseSceneDescriptionFile( char *path, char *audioFilePath, InputConfig *inConfig, IsmPositionProvider *positionProvider, MasaFileReader **masaReaders ) { uint32_t inAudioFilePathLen; char inAudioFilePath[FILENAME_MAX]; @@ -2151,7 +2151,7 @@ static void printSupportedAudioConfigs() static void convert_backslash( char *str ) { - int i, len; + int32_t i, len; /* check that all backslashes are correct on the given platform */ len = strlen( str ); diff --git a/lib_com/ivas_cnst.h b/lib_com/ivas_cnst.h index 00e1fb0d89..f522f809e9 100644 --- a/lib_com/ivas_cnst.h +++ b/lib_com/ivas_cnst.h @@ -193,6 +193,8 @@ typedef enum #define IVAS_MAX_SBA_ORDER 3 /* Maximum supported Ambisonics order */ +#define IVAS_LIMITER_THRESHOLD 32729 /* -0.01 dBFS */ +#define IVAS_LIMITER_ATTACK_SECONDS 0.005f /*----------------------------------------------------------------------------------* * IVAS Bitrates diff --git a/lib_rend/ivas_limiter.c b/lib_rend/ivas_limiter.c index e483318be8..25fad180b9 100644 --- a/lib_rend/ivas_limiter.c +++ b/lib_rend/ivas_limiter.c @@ -39,14 +39,6 @@ #include "wmops.h" #include -/*----------------------------------------------------------------------------------* - * Local constants - *----------------------------------------------------------------------------------*/ - -#define LIMITER_THRESHOLD 32729 /* -0.01 dBFS */ -#define LIMITER_ATTACK_SECONDS 0.005f - - /*-------------------------------------------------------------------* * detect_strong_saturations() * @@ -71,11 +63,11 @@ static int16_t detect_strong_saturations( *strong_saturation_cnt = 50; apply_strong_limiting = 1; } - else if ( max_val > 3 * LIMITER_THRESHOLD && *strong_saturation_cnt > 0 ) + else if ( max_val > 3 * IVAS_LIMITER_THRESHOLD && *strong_saturation_cnt > 0 ) { apply_strong_limiting = 1; } - else if ( max_val > 10 * LIMITER_THRESHOLD ) + else if ( max_val > 10 * IVAS_LIMITER_THRESHOLD ) { *strong_saturation_cnt += 20; *strong_saturation_cnt = min( *strong_saturation_cnt, 50 ); @@ -130,7 +122,7 @@ IVAS_LIMITER_HANDLE ivas_limiter_open( hLimiter->sampling_rate = sampling_rate; hLimiter->gain = 1.f; hLimiter->release_heuristic = 0.f; - hLimiter->attack_constant = powf( 0.01f, 1.0f / ( LIMITER_ATTACK_SECONDS * sampling_rate ) ); + 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; @@ -202,7 +194,7 @@ void ivas_limiter_dec( channels[c] = output[c]; } - limiter_process( hLimiter, output_frame, LIMITER_THRESHOLD, BER_detect, &hLimiter->strong_saturation_count ); + limiter_process( hLimiter, output_frame, IVAS_LIMITER_THRESHOLD, BER_detect, &hLimiter->strong_saturation_count ); return; } diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index 78522b1a83..55dff84a52 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -58,7 +58,6 @@ /* Frame size required when rendering to binaural */ #define BINAURAL_RENDERING_FRAME_SIZE_MS 20 -#define LIMITER_THRESHOLD ( 0.9988493699f * INT16_MAX ) /* -0.01 dBFS */ typedef float pan_vector[MAX_OUTPUT_CHANNELS]; typedef float pan_matrix[MAX_INPUT_CHANNELS][MAX_OUTPUT_CHANNELS]; diff --git a/scripts/ivas_pytests/tests/unit_tests/crend/ivas_crend_io_parse.h b/scripts/ivas_pytests/tests/unit_tests/crend/ivas_crend_io_parse.h index abc8b1e463..bc719cd4a6 100644 --- a/scripts/ivas_pytests/tests/unit_tests/crend/ivas_crend_io_parse.h +++ b/scripts/ivas_pytests/tests/unit_tests/crend/ivas_crend_io_parse.h @@ -46,6 +46,7 @@ #define IVAS_IN_FMT_510 "510" #define IVAS_IN_FMT_710 "710" #define IVAS_IN_FMT_512 "512" +#define IVAS_IN_FMT_514 "514" #define IVAS_IN_FMT_714 "714" #define IVAS_IN_FMT_FOA "HOA1S" @@ -62,6 +63,7 @@ typedef enum ivas_in_out_fmt_struct_t MULT_CH_5_1, MULT_CH_7_1, MULT_CH_5_1_2, + MULT_CH_5_1_4, MULT_CH_7_1_4, HOA_9, HOA_16, diff --git a/scripts/ivas_pytests/tests/unit_tests/crend/ivas_crend_unit_test.c b/scripts/ivas_pytests/tests/unit_tests/crend/ivas_crend_unit_test.c index b2a24534c0..0e32e634fe 100644 --- a/scripts/ivas_pytests/tests/unit_tests/crend/ivas_crend_unit_test.c +++ b/scripts/ivas_pytests/tests/unit_tests/crend/ivas_crend_unit_test.c @@ -416,6 +416,10 @@ static ivas_result_t ivas_crend_binaural_test( ivas_crend_io_params_t *pIo_param { test_case = "CREND_512_TO_BIN"; } + else if ( pIo_params->in_fmt == MULT_CH_5_1_4 ) + { + test_case = "CREND_514_TO_BIN"; + } else if ( pIo_params->in_fmt == MULT_CH_7_1_4 ) { test_case = "CREND_714_TO_BIN"; diff --git a/scripts/ivas_pytests/tests/unit_tests/crend/ivas_crend_utest_utils.c b/scripts/ivas_pytests/tests/unit_tests/crend/ivas_crend_utest_utils.c index d993405b11..00f00560e7 100644 --- a/scripts/ivas_pytests/tests/unit_tests/crend/ivas_crend_utest_utils.c +++ b/scripts/ivas_pytests/tests/unit_tests/crend/ivas_crend_utest_utils.c @@ -149,6 +149,8 @@ AUDIO_CONFIG ivas_crend_map_out_fmt( return AUDIO_CONFIG_7_1; case MULT_CH_5_1_2: return AUDIO_CONFIG_5_1_2; + case MULT_CH_5_1_4: + return AUDIO_CONFIG_5_1_4; case MULT_CH_7_1_4: return AUDIO_CONFIG_7_1_4; default: @@ -166,6 +168,7 @@ const char *ivas_crend_map_in_fmt( case MULT_CH_5_1: case MULT_CH_7_1: case MULT_CH_5_1_2: + case MULT_CH_5_1_4: case MULT_CH_7_1_4: return IVAS_IN_FMT_COMBINED; case FOA_4: @@ -213,6 +216,9 @@ int16_t ivas_get_num_channels( case MULT_CH_5_1_2: num_channels = 8; break; + case MULT_CH_5_1_4: + num_channels = 10; + break; case MULT_CH_7_1_4: num_channels = 12; break; @@ -561,7 +567,7 @@ ivas_result_t ivas_crend_parse_io_params( int argc, char **argv, ivas_crend_io_p else if ( strcmp( to_upper( argv[i] ), "-IFMT" ) == 0 ) { pIo_params->in_fmt = atoi( argv[++i] ); - if ( ( pIo_params->in_fmt != MONO_1 ) && ( pIo_params->in_fmt != STEREO_2 ) && ( pIo_params->in_fmt != BIN_2 ) && ( pIo_params->in_fmt != FOA_4 ) && ( pIo_params->in_fmt != HOA_9 ) && ( pIo_params->in_fmt != HOA_16 ) && ( pIo_params->in_fmt != MULT_CH_5_1 ) && ( pIo_params->in_fmt != MULT_CH_7_1 ) && ( pIo_params->in_fmt != MULT_CH_5_1_2 ) && ( pIo_params->in_fmt != MULT_CH_7_1_4 ) && ( pIo_params->in_fmt != OBA ) ) + if ( ( pIo_params->in_fmt != MONO_1 ) && ( pIo_params->in_fmt != STEREO_2 ) && ( pIo_params->in_fmt != BIN_2 ) && ( pIo_params->in_fmt != FOA_4 ) && ( pIo_params->in_fmt != HOA_9 ) && ( pIo_params->in_fmt != HOA_16 ) && ( pIo_params->in_fmt != MULT_CH_5_1 ) && ( pIo_params->in_fmt != MULT_CH_7_1 ) && ( pIo_params->in_fmt != MULT_CH_5_1_2 ) && ( pIo_params->in_fmt != MULT_CH_5_1_4 ) && ( pIo_params->in_fmt != MULT_CH_7_1_4 ) && ( pIo_params->in_fmt != OBA ) ) { fprintf( stderr, "Error: Invalid input format\n\n" ); ivas_crend_unit_test_usage(); @@ -575,7 +581,7 @@ ivas_result_t ivas_crend_parse_io_params( int argc, char **argv, ivas_crend_io_p else if ( strcmp( to_upper( argv[i] ), "-OFMT" ) == 0 ) { pIo_params->out_fmt = atoi( argv[++i] ); - if ( ( pIo_params->out_fmt != MONO_1 ) && ( pIo_params->out_fmt != STEREO_2 ) && ( pIo_params->out_fmt != BIN_2 ) && ( pIo_params->out_fmt != FOA_4 ) && ( pIo_params->out_fmt != HOA_9 ) && ( pIo_params->out_fmt != HOA_16 ) && ( pIo_params->out_fmt != MULT_CH_5_1 ) && ( pIo_params->out_fmt != MULT_CH_7_1 ) && ( pIo_params->out_fmt != MULT_CH_5_1_2 ) && ( pIo_params->out_fmt != MULT_CH_7_1_4 ) ) + if ( ( pIo_params->out_fmt != MONO_1 ) && ( pIo_params->out_fmt != STEREO_2 ) && ( pIo_params->out_fmt != BIN_2 ) && ( pIo_params->out_fmt != FOA_4 ) && ( pIo_params->out_fmt != HOA_9 ) && ( pIo_params->out_fmt != HOA_16 ) && ( pIo_params->out_fmt != MULT_CH_5_1 ) && ( pIo_params->out_fmt != MULT_CH_7_1 ) && ( pIo_params->out_fmt != MULT_CH_5_1_2 ) && ( pIo_params->out_fmt != MULT_CH_5_1_4 ) && ( pIo_params->out_fmt != MULT_CH_7_1_4 ) ) { fprintf( stderr, "Error: Invalid output format\n\n" ); ivas_crend_unit_test_usage(); @@ -875,7 +881,7 @@ static ivas_result_t ivas_wrapper_get_in_buf( ivas_crend_io_params_t *pIo_params #endif { ppPcm_in[i][j] = (float) tmp; - ppPcm_in[i][j] *= ( 1.0 / PCM16_TO_FLT_FAC ); + // ppPcm_in[i][j] *= ( 1.0 / PCM16_TO_FLT_FAC ); samples_read += 1; } else @@ -913,7 +919,7 @@ static ivas_result_t ivas_wrapper_get_in_buf( ivas_crend_io_params_t *pIo_params #endif { ppPcm_in[i][j] = (float) tmp; - ppPcm_in[i][j] *= ( 1.0 / PCM16_TO_FLT_FAC ); + // ppPcm_in[i][j] *= ( 1.0 / PCM16_TO_FLT_FAC ); samples_read += 1; } else @@ -999,6 +1005,7 @@ static void ivas_copy_io_params_to_dec_io_params( ivas_crend_io_params_t *pIo_pa case MULT_CH_5_1: case MULT_CH_7_1: case MULT_CH_5_1_2: + case MULT_CH_5_1_4: case MULT_CH_7_1_4: pDec_io_params->lfe_ch_idx = IVAS_DEFAULT_LFE_CH_IDX; break; @@ -1398,36 +1405,24 @@ ivas_result_t ivas_common_mixer_renderer( ivas_crend_io_params_t *pIo_params, fl return IVAS_IO_ERROR; } - if ( pIo_params->lfe_lp_enable ) { - int32_t idx = 0; - for ( i = 0; i < in_ch; i++ ) + /* ADD delay to make overall max(block_offset, 11.5)*/ + if ( st_ivas.hLFE->lfe_addl_delay > 0 ) { - if ( i != lfe_ch_idx ) - { - delay_signal( ppPcm_in[idx], frame_len, ppDelay_lines[idx], delay_lp ); - idx++; - } + delay_signal( ppPcm_in[lfe_ch_idx], frame_len, st_ivas.hLFE->lfe_delay_buf, st_ivas.hLFE->lfe_addl_delay ); } + ivas_filter_process( &st_ivas.hLFE->filter_state, ppPcm_in[lfe_ch_idx], frame_len ); } if ( pIo_params->test == FASTCONV_BIN_TEST ) { ivas_binaural_cldfb( &st_ivas, ppPcm_in ); - for ( i = 0; i < out_ch; i++ ) - { - mvr2r( ppPcm_in[i], ppPcm_out[i], frame_len ); - } } else if ( pIo_params->test == TD_BIN_TEST ) { ObjRenderIVASFrame( &st_ivas, ppPcm_in, frame_len ); - for ( i = 0; i < out_ch; i++ ) - { - mvr2r( ppPcm_in[i], ppPcm_out[i], frame_len ); - } } else if ( pIo_params->test == PARAM_BIN_TEST ) { @@ -1482,11 +1477,6 @@ ivas_result_t ivas_common_mixer_renderer( ivas_crend_io_params_t *pIo_params, fl cldfbSynthesis( &outSlotRePr, &outSlotImPr, &( ppPcm_in[ch][slot_idx * maxBand] ), maxBand, st_ivas.cldfbSynDec[ch] ); } } - - for ( i = 0; i < out_ch; i++ ) - { - mvr2r( ppPcm_in[i], ppPcm_out[i], frame_len ); - } } else @@ -1495,7 +1485,7 @@ ivas_result_t ivas_common_mixer_renderer( ivas_crend_io_params_t *pIo_params, fl { ivas_crend_mixer( ppPcm_in, ppPcm_out, in_ch, out_ch, mixer, frame_len ); } - else + else { ivas_crend_process( &st_ivas, ppPcm_in ); } @@ -1503,19 +1493,12 @@ ivas_result_t ivas_common_mixer_renderer( ivas_crend_io_params_t *pIo_params, fl if ( mixer == NULL ) { - if ( st_ivas.hLFE ) + if ( pIo_params->lfe_lp_enable ) { - /* if ( st_ivas.hLFE->filter_state.order > 0 ) - { - - ivas_filter_process( &st_ivas.hLFE->filter_state, ppPcm_in[lfe_ch_idx], frame_len ); - }*/ - - /* ADD delay to make overall max(block_offset, 11.5)*/ - if ( st_ivas.hLFE->lfe_addl_delay > 0 ) - { - delay_signal( ppPcm_in[lfe_ch_idx], frame_len, st_ivas.hLFE->lfe_delay_buf, st_ivas.hLFE->lfe_addl_delay ); - } + for ( i = 0; i < out_ch; i++ ) + { + delay_signal( ppPcm_in[i], frame_len, ppDelay_lines[i], delay_lp ); + } ivas_binaural_add_LFE( &st_ivas, frame_len, ppPcm_in ); } @@ -1525,7 +1508,7 @@ ivas_result_t ivas_common_mixer_renderer( ivas_crend_io_params_t *pIo_params, fl } if ( pIo_params->limiter_enable ) { - ivas_limiter_dec( st_ivas.hLimiter, ppPcm_out, out_ch, frame_len, FALSE ); + ivas_limiter_dec( st_ivas.hLimiter, ppPcm_out, out_ch, frame_len, 0 ); } } @@ -1540,7 +1523,8 @@ ivas_result_t ivas_common_mixer_renderer( ivas_crend_io_params_t *pIo_params, fl } for ( i = 0; i < out_ch; i++ ) { - float temp = roundf( ppPcm_out[i][j] * PCM16_TO_FLT_FAC ); +// float temp = roundf( ppPcm_out[i][j] * PCM16_TO_FLT_FAC ); + float temp; #ifdef _FIND_MAX_ valMaxLoc = ( ppPcm_out[i][j] > valMaxLoc ) ? ppPcm_out[i][j] : ( ppPcm_out[i][j] < -valMaxLoc ) ? -ppPcm_out[i][j] : valMaxLoc; @@ -1549,9 +1533,10 @@ ivas_result_t ivas_common_mixer_renderer( ivas_crend_io_params_t *pIo_params, fl valMax = valMaxLoc; valEner += ppPcm_out[i][j] * ppPcm_out[i][j]; #endif - pcm[i] = ( temp > MAX16B ) ? MAX16B : ( temp < MIN16B_FLT ) ? MIN16B - : (short) temp; - clip = max( clip, fabs( ppPcm_out[i][j] ) ); + temp = ( ppPcm_out[i][j] > MAX16B_FLT ) ? MAX16B_FLT : ( ppPcm_out[i][j] < MIN16B_FLT ) ? MIN16B_FLT + : ppPcm_out[i][j]; + pcm[i] = (short) roundf(temp); + clip = max( clip, fabsf( ppPcm_out[i][j] ) ); } @@ -1566,7 +1551,7 @@ ivas_result_t ivas_common_mixer_renderer( ivas_crend_io_params_t *pIo_params, fl if ( write_flag == 0 ) skipped_samples++; } - if ( clip > 1.0f ) + if ( clip > MAX16B_FLT ) { fprintf( stdout, "IVAS Common Renderer Clipped: max gain = %f\n", clip ); } @@ -1769,7 +1754,8 @@ ivas_result_t ivas_object_mixer_renderer( ivas_crend_io_params_t *pIo_params, in for ( i = 0; i < out_ch; i++ ) { - float temp = roundf( ppPcm_out[i][j] * PCM16_TO_FLT_FAC ); +// float temp = roundf( ppPcm_out[i][j] * PCM16_TO_FLT_FAC ); + float temp = roundf( ppPcm_out[i][j] ); #ifdef _FIND_MAX_ valMaxLoc = ( ppPcm_out[i][j] > valMaxLoc ) ? ppPcm_out[i][j] : ( ppPcm_out[i][j] < -valMaxLoc ) ? -ppPcm_out[i][j] diff --git a/scripts/ivas_pytests/tests/unit_tests/crend/ivas_dec_parse_io.h b/scripts/ivas_pytests/tests/unit_tests/crend/ivas_dec_parse_io.h index ed4071d8ca..97962a785b 100644 --- a/scripts/ivas_pytests/tests/unit_tests/crend/ivas_dec_parse_io.h +++ b/scripts/ivas_pytests/tests/unit_tests/crend/ivas_dec_parse_io.h @@ -83,6 +83,7 @@ #define IVAS_IN_FMT_510 "510" #define IVAS_IN_FMT_710 "710" #define IVAS_IN_FMT_512 "512" +#define IVAS_IN_FMT_514 "514" #define IVAS_IN_FMT_714 "714" #define IVAS_IN_FMT_FOA "HOA1S" #define IVAS_IN_FMT_HOA_2 "HOA2S" diff --git a/scripts/pyaudio3dtools/binauralrenderer.py b/scripts/pyaudio3dtools/binauralrenderer.py index 520305c7bf..e9b8f88778 100644 --- a/scripts/pyaudio3dtools/binauralrenderer.py +++ b/scripts/pyaudio3dtools/binauralrenderer.py @@ -51,6 +51,10 @@ logger.setLevel(logging.DEBUG) """" Helper functions """ +def NS2SA(fs, x): + return int(int(fs / 100) * ((x) / 100) / 100000) + + def read_hrirs_from_mat( hrirs_path: str = "/HRIRs_mat/ORANGE_HRIR_53_48000_combined.mat", ) -> np.ndarray: @@ -88,7 +92,7 @@ def get_IR( in_spfmt: spatialaudioformat.Format, out_spfmt: spatialaudioformat.Format, dataset: str, -) -> Tuple[np.ndarray, np.ndarray]: +) -> Tuple[np.ndarray, np.ndarray, float]: """get_IR Parameters @@ -136,6 +140,8 @@ def get_IR( IR, SourcePosition = read_hrirs_from_mat("_".join([prefix, suffix])) + latency_smp = float(np.min(np.argmax(np.sum(np.abs(IR), axis=(1)), axis=(0)))) + if in_spfmt.name.startswith("MONO"): IR = IR[:, :, :1] # use omni/W from SBA elif in_spfmt.name.startswith("STEREO"): @@ -157,7 +163,7 @@ def get_IR( IR[:, :, ir_index] = IR_tmp[:, :, i] ir_index += 1 - return IR, SourcePosition + return IR, SourcePosition, latency_smp def FindFilter(SourcePosition: np.ndarray, azi: float, ele: float) -> int: @@ -494,7 +500,12 @@ def binaural_render_LFE( fs: int = 48000, lfe_index: list = [3], LFE_gain: float = 10 ** (5.5 / 20), + latency_smp: int = 0, ) -> np.ndarray: + """ + Extract LFE from the given input and render + it binaurally, accounting for delay of the + """ lfe = x[:, lfe_index].copy() @@ -503,6 +514,7 @@ def binaural_render_LFE( lfe = np.sum(lfe, axis=1) # TODO tmu - disabled temporarily here, disabled in C + lfe_delay_ns = 0 """ # 120 Hz low-pass filtering for LFE using IVAS filter coefficients if fs == 48000: @@ -511,20 +523,21 @@ def binaural_render_LFE( raise NotImplementedError("Only 48 kHz supported at the moment!") # 3.5ms LP filter delay from IVAS ROM - filter_delay = int(3.5 * fs / 1000) - - # delay adjustment - lfe = np.roll(lfe, -filter_delay, axis=0) - lfe[-filter_delay:, :] = 0 + lfe_delay_ns = 0.0035 * 1e9 + lfe_delay_smp = round(lfe_delay_ns * fs / 1e9) + # Delay LFE by the same amount as the HRTF delay + lfe = np.roll(lfe, round(latency_smp), axis=0) + lfe[0 : round(latency_smp), :] = 0 """ + # apply gain lfe *= LFE_gain # duplicate for each binaural channel lfe = np.hstack([lfe, lfe]) - return lfe + return lfe, lfe_delay_ns """ Format specific wrapper functions """ @@ -711,14 +724,18 @@ def binaural_rendering( # resample to 48 kHz y = audioarray.resample(x, fs, 48000) + delay_total_ns = 0 # get IR corresponding to the input and output formats - IR, SourcePosition = get_IR(in_spfmt, out_spfmt, dataset) - latency_smp = np.argmax(np.sum(np.abs(IR), axis=(1, 2))) + IR, SourcePosition, latency_smp = get_IR(in_spfmt, out_spfmt, dataset) + delay_total_ns += latency_smp / float(fs) * 1e9 # prepare LFE signal to be added to output if include_LFE and in_spfmt.isloudspeaker and in_spfmt.lfe_index: - lfe = binaural_render_LFE(x, 48000, in_spfmt.lfe_index, LFE_gain) + lfe, lfe_delay_ns = binaural_render_LFE( + x, 48000, in_spfmt.lfe_index, LFE_gain, latency_smp + ) + delay_total_ns += lfe_delay_ns # get binauralized signal based on format if in_spfmt.altname.startswith("CUSTOM_LS"): @@ -745,14 +762,19 @@ def binaural_rendering( f"{in_spfmt.name} -> {out_spfmt.name}: format conversion not implemented" ) - # HRTF delay compensation - y = np.roll(y, -latency_smp, axis=0) - y[-latency_smp:, :] = 0 - # add LFE signal to output if include_LFE and in_spfmt.isloudspeaker and in_spfmt.lfe_index: + # delay the binauralized signal by the LFE delay + lfe_delay_smp = NS2SA(fs, int(lfe_delay_ns)) + y = np.roll(y, lfe_delay_smp, axis=0) + y[0:lfe_delay_smp, :] = 0 y += lfe + # delay compensation + delay_total_smp = NS2SA(fs, delay_total_ns) + y = np.roll(y, -delay_total_smp, axis=0) + y[-delay_total_smp:, :] = 0 + # resample back to original rate y = audioarray.resample(y, 48000, fs) diff --git a/scripts/tests/constants.py b/scripts/tests/constants.py index dcf8bbe3a9..3203d15ccd 100644 --- a/scripts/tests/constants.py +++ b/scripts/tests/constants.py @@ -56,7 +56,7 @@ RENDERER_CMD = [ "-q", ] -""" Renderer commandline template """ +""" TD Object Renderer commandline template """ TDRENDERER_CMD = [ str( TESTS_DIR.parent.joinpath("td_object_renderer") @@ -68,6 +68,26 @@ TDRENDERER_CMD = [ "", # 5 -> output file ] +""" CREND commandline template """ +RENDERER_CREND_CMD = [ + str(TESTS_DIR.parent.parent.joinpath("IVAS_crend_unit_test")), + "-test", + "1", + "-sr", + "48", + "-ifmt", + "", # 4 -> input format + "-ofmt", + "", # 8 -> output format + "-i", + "", # 2 -> input file + "-o", + "/dev/null", # 6 -> output file + "-lp_lfe", + "-limiter" + # "-no_delay_cmp" +] + """ Format to file mappings """ NCHAN_TO_FILE = { 1: TEST_VECTOR_DIR.joinpath("spectral_test_1ch_48kHz.wav"), @@ -141,6 +161,21 @@ FORMAT_TO_METADATA_FILES = { "MASA2": [str(TEST_VECTOR_DIR.joinpath("stv_IVASMASAQ_2dir2TC.met"))], } +FORMAT_TO_CREND_FORMAT = { + "MONO": "0", + "STEREO": "1", + "BINAURAL": "2", + "BINAURAL_ROOM": "2", + "FOA": "3", + "5_1": "4", + "7_1": "5", + "5_1_2": "6", + "5_1_4": "7", + "7_1_4": "8", + "HOA2": "9", + "HOA3": "10", +} + """ Input formats """ INPUT_FORMATS_AMBI = ["FOA", "HOA2", "HOA3"] INPUT_FORMATS_MC = ["MONO", "STEREO", "5_1", "5_1_2", "5_1_4", "7_1", "7_1_4"] @@ -180,7 +215,7 @@ METADATA_SCENES_TO_TEST_NO_BE = ["masa_scene"] """ Binaural rendering """ INPUT_FORMATS_BINAURAL = OUTPUT_FORMATS[2:] -INPUT_FORMATS_BINAURAL.extend( +INPUT_FORMATS_BINAURAL.extend( [ "ISM1", "ISM2", @@ -189,7 +224,7 @@ INPUT_FORMATS_BINAURAL.extend( # "MASA1", # "MASA2", ] - ) +) OUTPUT_FORMATS_BINAURAL = ["BINAURAL", "BINAURAL_ROOM"] HR_TRAJECTORIES_TO_TEST = [ # "const000", diff --git a/scripts/tests/data/dirac_12ch_48khz.wav b/scripts/tests/data/dirac_12ch_48khz.wav new file mode 100644 index 0000000000..49a781a4b0 --- /dev/null +++ b/scripts/tests/data/dirac_12ch_48khz.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:880a478b7b6001dff4570e38a8a1928e0d78a78d223f49555e9023598e5ee4fb +size 13824068 diff --git a/scripts/tests/test_renderer.py b/scripts/tests/test_renderer.py index ef304e9461..a076b1d72e 100644 --- a/scripts/tests/test_renderer.py +++ b/scripts/tests/test_renderer.py @@ -171,6 +171,62 @@ def run_renderer( return pyaudio3dtools.audiofile.readfile(out_file) +def run_crend_unittest( + in_fmt: str, + out_fmt: str, + metadata_input: Optional[str] = None, + in_meta_files: Optional[list] = None, + trj_file: Optional[str] = None, +) -> Tuple[np.ndarray, int]: + """CuT creation with standalone renderer""" + if trj_file is not None: + trj_name = f"_{trj_file.stem}" + else: + trj_name = "" + + if not isinstance(out_fmt, str): + out_name = f"{out_fmt.stem}" + else: + out_name = out_fmt + + if metadata_input is not None: + in_file = metadata_input + in_name = metadata_input.stem + elif not isinstance(in_fmt, str): + in_file = FORMAT_TO_FILE[in_fmt.stem] + in_name = in_fmt.stem + else: + in_file = FORMAT_TO_FILE[in_fmt] + in_name = in_fmt + + out_file = str( + OUTPUT_PATH_CUT.joinpath(f"{in_name}_to_{out_name}{trj_name}_crend.wav") + ) + + cmd = RENDERER_CREND_CMD[:] + cmd[6] = FORMAT_TO_CREND_FORMAT(str(in_fmt)) + cmd[8] = FORMAT_TO_CREND_FORMAT(str(out_fmt)) + cmd[10] = str(in_file) + cmd[12] = str(out_file) + if str(out_fmt) == "BINAURAL_ROOM": + cmd.append("-BRIR") + + # if in_meta_files is not None: + # cmd[5:5] = in_meta_files + + # if trj_file is not None: + # cmd.extend(["-tf", str(trj_file)]) + + try: + sp.run(cmd, check=True, capture_output=True, text=True) + except sp.CalledProcessError as e: + pytest.fail( + f"Command returned non-zero exit status ({e.returncode})!\n{' '.join(e.cmd)}\n{e.stderr}\n{e.stdout}\n{e.output}" + ) + + return pyaudio3dtools.audiofile.readfile(out_file) + + def run_td_standalone( in_fmt: str, out_fmt: str, @@ -411,6 +467,17 @@ def test_multichannel_binaural_static(test_info, in_fmt, out_fmt): check_BE(test_info, ref, ref_fs, cut, cut_fs) +@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL) +@pytest.mark.parametrize("in_fmt", INPUT_FORMATS_MC[2:]) +def test_multichannel_binaural_static_vs_crend_unitest(test_info, in_fmt, out_fmt): + + cut, cut_fs = run_renderer(in_fmt, out_fmt) + + crend, crend_fs = run_crend_unittest(in_fmt, out_fmt) + + check_BE(test_info, cut, cut_fs, crend, crend_fs) + + # Binaural rendering (head rotation) @pytest.mark.parametrize("trj_file", HR_TRAJECTORIES_TO_TEST) @pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL) @@ -461,7 +528,7 @@ def test_ism_binaural_headrotation(test_info, in_fmt, out_fmt, trj_file): # trj_file=HR_TRAJECTORY_DIR.joinpath(f"{trj_file}.csv"), # in_meta_files=in_meta_files, # ) - + cut, cut_fs = run_renderer( in_fmt, out_fmt, -- GitLab From 58798395fdcd83c7349127b178d1eb984201341d Mon Sep 17 00:00:00 2001 From: Archit Tamarapu Date: Fri, 21 Oct 2022 14:49:37 +0200 Subject: [PATCH 042/101] [fix] MSVC warnings and a compiler error --- lib_rend/ivas_crend.c | 2 +- lib_rend/ivas_objectRenderer.c | 2 +- lib_rend/lib_rend.c | 28 +++++++++++++--------------- 3 files changed, 15 insertions(+), 17 deletions(-) diff --git a/lib_rend/ivas_crend.c b/lib_rend/ivas_crend.c index bec08cbbaf..0a5b28cb98 100644 --- a/lib_rend/ivas_crend.c +++ b/lib_rend/ivas_crend.c @@ -1349,7 +1349,7 @@ ivas_error ivas_rend_initCrend( { return error; } - hHrtf->max_num_ir = nchan_in; + hHrtf->max_num_ir = (int16_t) nchan_in; if ( hHrtf->max_num_ir <= 0 ) { diff --git a/lib_rend/ivas_objectRenderer.c b/lib_rend/ivas_objectRenderer.c index ebccd562ee..e4f0706193 100644 --- a/lib_rend/ivas_objectRenderer.c +++ b/lib_rend/ivas_objectRenderer.c @@ -715,7 +715,7 @@ ivas_error ivas_rend_TDObjRenderFrame( /* Update object position(s) */ TDREND_Update_object_positions( pTDRend->hBinRendererTd, - num_src, + (int16_t) num_src, lfe_idx, ivas_format, hIsmMetaData, diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index 55dff84a52..6ff1a683c3 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -424,8 +424,6 @@ AUDIO_CONFIG getIvasAudioConfigFromRendAudioConfig( IVAS_REND_AudioConfig config default: return AUDIO_CONFIG_INVALID; } - - return AUDIO_CONFIG_INVALID; } static ivas_error initLimiter( IVAS_LIMITER_HANDLE *phLimiter, int32_t numChannels, int32_t sampleRate ) @@ -2788,7 +2786,7 @@ static ivas_error rotateFrameMc( /* initialize gains to passthrough */ for ( ch_in = 0; ch_in < nchan; ch_in++ ) { - set_zero( gains[ch_in], nchan ); + set_zero( gains[ch_in], (int16_t) nchan ); gains[ch_in][ch_in] = 1.f; } @@ -2816,7 +2814,7 @@ static ivas_error rotateFrameMc( &azimuth, &elevation, Rmat, - is_planar_setup ); + (int16_t) is_planar_setup ); if ( hEFAPdata != NULL && ( ls_azimuth[ch_in_woLFE] != azimuth || ls_elevation[ch_in_woLFE] != elevation ) ) { @@ -2863,7 +2861,7 @@ static ivas_error rotateFrameMc( /* move gains to gains_prev */ for ( i = 0; i < nchan; i++ ) { - mvr2r( gains[i], gains_prev[i], nchan ); + mvr2r( gains[i], gains_prev[i], (int16_t) nchan ); } } @@ -3083,7 +3081,7 @@ static ivas_error renderIsmToBinauralRoom( /* intermediate rendering to 7_1_4 */ tmpMcBuffer = ismInput->base.inputBuffer; getAudioConfigNumChannels( IVAS_REND_AUDIO_CONFIG_7_1_4, &tmp ); - tmpMcBuffer.config.numChannels = tmp; + tmpMcBuffer.config.numChannels = (int16_t) tmp; tmpMcBuffer.data = count_malloc( tmpMcBuffer.config.numSamplesPerChannel * tmpMcBuffer.config.numChannels * sizeof( float ) ); set_zero( tmpMcBuffer.data, tmpMcBuffer.config.numSamplesPerChannel * tmpMcBuffer.config.numChannels ); @@ -3164,10 +3162,10 @@ static ivas_error renderIsmToSba( return error; } - ivas_dirac_dec_get_response( ismInput->previousPos.azimuth, - ismInput->previousPos.elevation, + ivas_dirac_dec_get_response( (int16_t) ismInput->previousPos.azimuth, + (int16_t) ismInput->previousPos.elevation, previousPanGains, - ambiOrderOut ); + (int16_t) ambiOrderOut ); if ( ( ismInput->currentPos.azimuth == ismInput->previousPos.azimuth ) && ( ismInput->currentPos.elevation == ismInput->previousPos.elevation ) ) @@ -3176,10 +3174,10 @@ static ivas_error renderIsmToSba( } else { - ivas_dirac_dec_get_response( ismInput->currentPos.azimuth, - ismInput->currentPos.elevation, + ivas_dirac_dec_get_response( (int16_t) ismInput->currentPos.azimuth, + (int16_t) ismInput->currentPos.elevation, currentPanGains, - ambiOrderOut ); + (int16_t) ambiOrderOut ); } /* Assume num channels in audio buffer to be 1. @@ -3486,7 +3484,7 @@ static ivas_error renderMcCustomLsToBinauralRoom( /* intermediate conversion to 7_1_4 */ tmpMcBuffer = mcInput->base.inputBuffer; getAudioConfigNumChannels( IVAS_REND_AUDIO_CONFIG_7_1_4, &tmp ); - tmpMcBuffer.config.numChannels = tmp; + tmpMcBuffer.config.numChannels = (int16_t) tmp; tmpMcBuffer.data = count_malloc( tmpMcBuffer.config.numSamplesPerChannel * tmpMcBuffer.config.numChannels * sizeof( float ) ); set_zero( tmpMcBuffer.data, tmpMcBuffer.config.numSamplesPerChannel * tmpMcBuffer.config.numChannels ); @@ -3765,7 +3763,7 @@ static ivas_error renderSbaToBinauralRoom( /* intermediate rendering to 7_1_4 */ tmpMcBuffer = sbaInput->base.inputBuffer; getAudioConfigNumChannels( IVAS_REND_AUDIO_CONFIG_7_1_4, &tmp ); - tmpMcBuffer.config.numChannels = tmp; + tmpMcBuffer.config.numChannels = (int16_t) tmp; tmpMcBuffer.data = count_malloc( tmpMcBuffer.config.numSamplesPerChannel * tmpMcBuffer.config.numChannels * sizeof( float ) ); set_zero( tmpMcBuffer.data, tmpMcBuffer.config.numChannels * tmpMcBuffer.config.numSamplesPerChannel ); @@ -3941,7 +3939,7 @@ ivas_error IVAS_REND_GetSamples( #ifdef DEBUGGING hIvasRend->numClipping += #endif - limitRendererOutput( hIvasRend->hLimiter, outAudio.data, outAudio.config.numSamplesPerChannel, LIMITER_THRESHOLD ); + limitRendererOutput( hIvasRend->hLimiter, outAudio.data, outAudio.config.numSamplesPerChannel, IVAS_LIMITER_THRESHOLD ); return IVAS_ERR_OK; } -- GitLab From 0e02fd9205d324e3f54a87d1d787c466af8ae207 Mon Sep 17 00:00:00 2001 From: Remco Stoutjesdijk Date: Sun, 23 Oct 2022 02:41:40 +0200 Subject: [PATCH 043/101] added render config open and init from rom --- apps/renderer.c | 19 +++++++------------ lib_rend/lib_rend.c | 31 +++++++++++++++++++++++++++++++ lib_rend/lib_rend.h | 6 ++++++ 3 files changed, 44 insertions(+), 12 deletions(-) diff --git a/apps/renderer.c b/apps/renderer.c index 66c0a01d07..186ca87c6c 100644 --- a/apps/renderer.c +++ b/apps/renderer.c @@ -588,28 +588,23 @@ int32_t main( int32_t argc, char **argv ) hMasaMetadata = MasaFileReader_getMetadataHandle( masaReader ); } + /* === Configure === */ + if ( ( error = IVAS_REND_ConfigureConfig( hIvasRend, args.trajectoryFile[0] != '\0', args.renderConfigFile[0] != '\0' ) ) != IVAS_ERR_OK ) + { + exit( -1 ); + } + if ( args.renderConfigFile[0] != '\0' ) { IVAS_RENDER_CONFIG_DATA renderConfig; /* sanity check */ -/* if ( args.outConfig.audioConfig != IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM ) + if ( args.outConfig.audioConfig != IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM ) { fprintf( stderr, "\nExternal Renderer Config is supported only when BINAURAL_ROOM is used as output. Exiting. \n" ); exit( -1 ); // goto cleanup; } - if ( ( error = ivas_render_config_open( &hIvasRend->hRendererConfig ) ) != IVAS_ERR_OK ) - { - ivas_render_config_open(&renderConfig); - return error; - } - - if ( ivas_render_config_init_from_rom( &st->hRendererConfig, st->rendererConfigEnabled ) != IVAS_ERR_OK ) - { - return IVAS_ERR_INTERNAL_FATAL; - } -*/ if ( ( error = IVAS_REND_GetRenderConfig( hIvasRend, &renderConfig ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nIVAS_DEC_GetRenderConfig failed\n" ); diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index 5fb320e01a..2caca428fb 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -151,7 +151,11 @@ struct IVAS_REND IVAS_REND_AudioConfig outputConfig; EFAP_WRAPPER efapOutWrapper; IVAS_LSSETUP_CUSTOM_STRUCT customLsOut; + + int8_t enableHeadRotation; /* head rotation flag */ IVAS_REND_HeadRotData headRotData; + + int8_t rendererConfigEnabled; RENDER_CONFIG_DATA *hRendererConfig; /* Renderer config pointer */ }; @@ -2628,6 +2632,33 @@ ivas_error IVAS_REND_FeedInputObjectMetadata( return IVAS_ERR_OK; } +ivas_error IVAS_REND_ConfigureConfig( IVAS_REND_HANDLE st, + bool headRotationEnabled, + bool rendererConfigEnabled ) +{ + ivas_error error; + + if ( headRotationEnabled ) + { + st->enableHeadRotation = 1; + } + + if ( rendererConfigEnabled ) + { + st->rendererConfigEnabled = 1; + } + + if ( ( error = ivas_render_config_open( &( st->hRendererConfig ) ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( ivas_render_config_init_from_rom( &st->hRendererConfig, st->rendererConfigEnabled ) != IVAS_ERR_OK ) + { + return IVAS_ERR_INTERNAL_FATAL; + } + +} int16_t IVAS_REND_GetRenderConfig( IVAS_REND_HANDLE hIvasRend, /* i/o: IVAS decoder handle */ diff --git a/lib_rend/lib_rend.h b/lib_rend/lib_rend.h index 6093228adc..75d580e1c0 100644 --- a/lib_rend/lib_rend.h +++ b/lib_rend/lib_rend.h @@ -234,6 +234,12 @@ ivas_error IVAS_REND_FeedInputMasaMetadata( void* TODO ); +ivas_error IVAS_REND_ConfigureConfig( + IVAS_REND_HANDLE st, /* i/o: Renderer handle */ + bool headRotationEnabled, /* i : enable head rotation for binaural output, ignored for other output formats */ + bool rendererConfigEnabled /* i : flag indicating if a renderer configuration file was supplied */ +); + int16_t IVAS_REND_GetRenderConfig( IVAS_REND_HANDLE hIvasRend, /* i/o: IVAS decoder handle */ const IVAS_RENDER_CONFIG_HANDLE hRCout /* o : Render configuration handle */ -- GitLab From a51b2d3560e5c1ad587c68294a54a33fca3cb310 Mon Sep 17 00:00:00 2001 From: Remco Stoutjesdijk Date: Sun, 23 Oct 2022 03:12:51 +0200 Subject: [PATCH 044/101] return value --- lib_rend/lib_rend.c | 1 + 1 file changed, 1 insertion(+) diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index 2caca428fb..3405cbb548 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -2658,6 +2658,7 @@ ivas_error IVAS_REND_ConfigureConfig( IVAS_REND_HANDLE st, return IVAS_ERR_INTERNAL_FATAL; } + return IVAS_ERR_OK; } int16_t IVAS_REND_GetRenderConfig( -- GitLab From 891e871270c481b7f3b2c61b1ef30766ac8d4809 Mon Sep 17 00:00:00 2001 From: Remco Stoutjesdijk Date: Sun, 23 Oct 2022 03:56:48 +0200 Subject: [PATCH 045/101] added deallocation --- apps/renderer.c | 3 ++- lib_rend/lib_rend.c | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/apps/renderer.c b/apps/renderer.c index 186ca87c6c..b6d51ce43c 100644 --- a/apps/renderer.c +++ b/apps/renderer.c @@ -464,7 +464,8 @@ int32_t main( int32_t argc, char **argv ) { fprintf( stderr, "\nError: Can't open Renderer configuration file %s \n\n", args.renderConfigFile ); exit( -1 ); - } } + } + } if ( args.sceneDescriptionInput ) { diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index 3405cbb548..98fe8fdb1f 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -4095,6 +4095,10 @@ void IVAS_REND_Close( IVAS_REND_HANDLE *phIvasRend ) clearInputSba( &hIvasRend->inputsSba[i] ); } + /* clear Config. Renderer */ + ivas_render_config_close( &( hIvasRend->hRendererConfig ) ); + + ivas_limiter_close( &hIvasRend->hLimiter ); count_free( hIvasRend ); -- GitLab From 9f8be23a864443ce52c599623b66bb0c281d8902 Mon Sep 17 00:00:00 2001 From: Archit Tamarapu Date: Tue, 25 Oct 2022 14:30:42 +0200 Subject: [PATCH 046/101] [fix] CMake Build --- CMakeLists.txt | 4 ++-- .../unit_tests/crend/ivas_crend_unit_test.c | 16 ++++++++-------- .../unit_tests/crend/ivas_crend_utest_utils.c | 4 ++-- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d0dccdee5d..0751f32401 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -155,7 +155,7 @@ add_library(lib_util ${libUtilSrcs} ${libUtilHeaders}) file(GLOB libCRendSrcs "scripts/ivas_pytests/tests/unit_tests/crend/*.c") file(GLOB libCRendHeaders "scripts/ivas_pytests/tests/unit_tests/crend/*.h") add_executable(IVAS_crend_unit_test ${libCRendSrcs} ${libCRendHeaders}) -target_link_libraries(IVAS_crend_unit_test lib_dec lib_rend lib_util lib_com lib_debug) +target_link_libraries(IVAS_crend_unit_test lib_rend lib_dec lib_util lib_com lib_debug) add_executable(IVAS_cod apps/encoder.c) target_link_libraries(IVAS_cod lib_enc lib_util) @@ -178,4 +178,4 @@ if(COPY_EXECUTABLES_TO_ROOT) 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}/") add_custom_command(TARGET IVAS_crend_unit_test POST_BUILD VERBATIM COMMAND "${CMAKE_COMMAND}" -E copy "$" "${CMAKE_CURRENT_SOURCE_DIR}/") -endif() \ No newline at end of file +endif() diff --git a/scripts/ivas_pytests/tests/unit_tests/crend/ivas_crend_unit_test.c b/scripts/ivas_pytests/tests/unit_tests/crend/ivas_crend_unit_test.c index 0e32e634fe..baa953bc7d 100644 --- a/scripts/ivas_pytests/tests/unit_tests/crend/ivas_crend_unit_test.c +++ b/scripts/ivas_pytests/tests/unit_tests/crend/ivas_crend_unit_test.c @@ -200,14 +200,14 @@ static ivas_result_t ivas_crend_reverb_test( ivas_crend_io_params_t *pIo_params #else AudioFileWriter_close( &pIo_params->fOut ); AudioFileReader *fOut; - AudioFileReader_open( &fOut , pIo_params->out_path, pIo_params->sample_rate); + AudioFileReader_open( &fOut , pIo_params->out_path, &pIo_params->sample_rate); int16_t numRead; /* Compare */ if ( pIo_params->fRef ) { AudioFileReader_close( &pIo_params->fRef ); AudioFileReader *fRef; - AudioFileReader_open( &fRef, pIo_params->ref_path, pIo_params->sample_rate ); + AudioFileReader_open( &fRef, pIo_params->ref_path, &pIo_params->sample_rate ); if ( test != FAIL ) { @@ -337,8 +337,8 @@ static ivas_result_t ivas_crend_proximity_test( ivas_crend_io_params_t *pIo_para AudioFileReader_close( &pIo_params->fRef ); AudioFileWriter_close( &pIo_params->fOut ); AudioFileReader *fRef, *fOut; - AudioFileReader_open( &fOut, pIo_params->out_path, pIo_params->sample_rate ); - AudioFileReader_open( &fRef, pIo_params->ref_path, pIo_params->sample_rate ); + AudioFileReader_open( &fOut, pIo_params->out_path, &pIo_params->sample_rate ); + AudioFileReader_open( &fRef, pIo_params->ref_path, &pIo_params->sample_rate ); while ( 1 ) { acc_0f = 0.0f; @@ -500,8 +500,8 @@ static ivas_result_t ivas_crend_binaural_test( ivas_crend_io_params_t *pIo_param AudioFileReader_close( &pIo_params->fRef ); AudioFileWriter_close( &pIo_params->fOut ); AudioFileReader *fRef, *fOut; - AudioFileReader_open( &fOut, pIo_params->out_path, pIo_params->sample_rate ); - AudioFileReader_open( &fRef, pIo_params->ref_path, pIo_params->sample_rate ); + AudioFileReader_open( &fOut, pIo_params->out_path, &pIo_params->sample_rate ); + AudioFileReader_open( &fRef, pIo_params->ref_path, &pIo_params->sample_rate ); skip_samples = (int32_t) ( pIo_params->latency_s * pIo_params->sample_rate ); /* skip intial samples based on latency */ @@ -630,8 +630,8 @@ static ivas_result_t ivas_crend_no_diegetic_test( ivas_crend_io_params_t *pIo_pa AudioFileReader_close( &pIo_params->fRef ); AudioFileWriter_close( &pIo_params->fOut ); AudioFileReader *fRef, *fOut; - AudioFileReader_open( &fOut, pIo_params->out_path, pIo_params->sample_rate ); - AudioFileReader_open( &fRef, pIo_params->ref_path, pIo_params->sample_rate ); + AudioFileReader_open( &fOut, pIo_params->out_path, &pIo_params->sample_rate ); + AudioFileReader_open( &fRef, pIo_params->ref_path, &pIo_params->sample_rate ); if ( fRef ) { diff --git a/scripts/ivas_pytests/tests/unit_tests/crend/ivas_crend_utest_utils.c b/scripts/ivas_pytests/tests/unit_tests/crend/ivas_crend_utest_utils.c index 00f00560e7..8535ed27a3 100644 --- a/scripts/ivas_pytests/tests/unit_tests/crend/ivas_crend_utest_utils.c +++ b/scripts/ivas_pytests/tests/unit_tests/crend/ivas_crend_utest_utils.c @@ -452,7 +452,7 @@ void ivas_open_files_crend( ivas_crend_io_params_t *pIo_params ) #ifdef USE_PCM_OUT if ( ( pIo_params->fIn[0] = fopen( pIo_params->in_path, "rb" ) ) == NULL ) #else - if ( AudioFileReader_open( &pIo_params->fIn[0] , pIo_params->in_path, pIo_params->sample_rate ) != IVAS_ERR_OK ) + if ( AudioFileReader_open( &pIo_params->fIn[0] , pIo_params->in_path, &pIo_params->sample_rate ) != IVAS_ERR_OK ) #endif { fprintf( stderr, "Error: Input audio file %s could not be opened\n\n", pIo_params->in_path ); @@ -464,7 +464,7 @@ void ivas_open_files_crend( ivas_crend_io_params_t *pIo_params ) #ifdef USE_PCM_OUT if ( ( strlen( pIo_params->ref_path ) > 0 ) && ( ( pIo_params->fRef = fopen( pIo_params->ref_path, "rb" ) ) == NULL ) ) #else - if ( ( strlen( pIo_params->ref_path ) > 0 ) && ( AudioFileReader_open( &pIo_params->fRef, pIo_params->ref_path, pIo_params->sample_rate ) != IVAS_ERR_OK ) ) + if ( ( strlen( pIo_params->ref_path ) > 0 ) && ( AudioFileReader_open( &pIo_params->fRef, pIo_params->ref_path, &pIo_params->sample_rate ) != IVAS_ERR_OK ) ) #endif { fprintf( stderr, "Error: Reference audio file %s could not be opened\n\n", pIo_params->ref_path ); -- GitLab From d267a03c41aaf97ea72f6519228dab65fe8077ac Mon Sep 17 00:00:00 2001 From: Remco Stoutjesdijk Date: Wed, 26 Oct 2022 01:11:10 +0200 Subject: [PATCH 047/101] fix compiler warnings --- lib_util/render_config_reader.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib_util/render_config_reader.c b/lib_util/render_config_reader.c index 58e0eee286..27eed3bf14 100644 --- a/lib_util/render_config_reader.c +++ b/lib_util/render_config_reader.c @@ -419,7 +419,7 @@ ivas_error RenderConfigReader_read( while ( sscanf( pParams + params_idx, "%64[^=]=%[^;];", item, pValue ) == 2 ) { hRenderConfig->room_acoustics.override = true; - params_idx += strlen( item ) + strlen( pValue ) + 2; + params_idx += (int32_t) ( strlen( item ) + strlen( pValue ) + 2 ); #ifdef DEBUGGING fprintf( stderr, " PARAM: %s -> %s\n", item, pValue ); #endif @@ -506,7 +506,7 @@ ivas_error RenderConfigReader_read( pValue = (char *) calloc( strlen( pParams ), sizeof( char ) ); while ( sscanf( pParams + params_idx, "%64[^=]=%[^;];", item, pValue ) == 2 ) { - params_idx += strlen( item ) + strlen( pValue ) + 2; + params_idx += (int32_t) ( strlen( item ) + strlen( pValue ) + 2 ); fprintf( stderr, " PARAM: %s -> %s\n", item, pValue ); if ( strcmp( item, "RENDERER" ) == 0 ) { -- GitLab From 20f874574095d2e4c64cbca2f26e1848d4cc14fb Mon Sep 17 00:00:00 2001 From: Archit Tamarapu Date: Wed, 26 Oct 2022 13:10:44 +0200 Subject: [PATCH 048/101] [fix] IVAS_crend_unit_test tests and pipeline - Bug in delay compensation for binauralrenderer.py when zero delay - Modify -lfe_lpf flag to affect only whether the LFE is filtered; always add it by default. - Update SNR thresholds - Update usage printout for IVAS_crend_unit_test - Apply clang-format --- .../unit_tests/crend/ivas_crend_utest_utils.c | 99 +++++++++---------- scripts/pyaudio3dtools/binauralrenderer.py | 3 +- scripts/tests/constants.py | 6 +- scripts/tests/test_renderer.py | 58 ++++++----- 4 files changed, 86 insertions(+), 80 deletions(-) diff --git a/scripts/ivas_pytests/tests/unit_tests/crend/ivas_crend_utest_utils.c b/scripts/ivas_pytests/tests/unit_tests/crend/ivas_crend_utest_utils.c index 8535ed27a3..42d9795219 100644 --- a/scripts/ivas_pytests/tests/unit_tests/crend/ivas_crend_utest_utils.c +++ b/scripts/ivas_pytests/tests/unit_tests/crend/ivas_crend_utest_utils.c @@ -64,7 +64,6 @@ #include "render_config_reader.h" - static ivas_result_t ivas_dec_default_io_params( ivas_dec_io_params_t *pIO_params ) { memset( pIO_params, 0, sizeof( ivas_dec_io_params_t ) ); @@ -103,7 +102,7 @@ static ivas_error ivas_hrtf_init( hHrtf->max_num_iterations = 0; hHrtf->gain_lfe = 0; hHrtf->index_frequency_max_diffuse = 0; - + for ( i = 0; i < IVAS_MAX_NUM_CH; i++ ) { hHrtf->inv_diffuse_weight[i] = 0; @@ -285,9 +284,9 @@ static void ivas_crend_unit_test_usage( void ) fprintf( stdout, "\nOptional arguments:\n" ); fprintf( stdout, "---------------------\n" ); fprintf( stdout, "-ifmt : Input format index\n" ); - fprintf( stdout, " (0 - MONO, 1 - STEREO, 2 - BINAURAL, 3 - FOA, 4 - 5.1, 5 - 7.1, 6 - 5.1.2, 7 - 7.1.4, 8 - HOA2, 9 - HOA3)\n" ); + fprintf( stdout, " (0 - MONO, 1 - STEREO, 2 - BINAURAL, 3 - FOA, 4 - 5.1, 5 - 7.1, 6 - 5.1.2, 7 - 5.1.4, 8 - 7.1.4, 9 - HOA2, 10 - HOA3)\n" ); fprintf( stdout, "-ofmt : Output format index\n" ); - fprintf( stdout, " (0 - MONO, 1 - STEREO, 2 - BINAURAL, 3 - FOA, 4 - 5.1, 5 - 7.1, 6 - 5.1.2, 7 - 7.1.4, 8 - HOA2, 9 - HOA3)\n" ); + fprintf( stdout, " (0 - MONO, 1 - STEREO, 2 - BINAURAL, 3 - FOA, 4 - 5.1, 5 - 7.1, 6 - 5.1.2, 7 - 5.1.4, 8 - 7.1.4, 9 - HOA2, 10 - HOA3)\n" ); fprintf( stdout, "-i : Input path/file\n" ); fprintf( stdout, "-o : Output file\n" ); fprintf( stdout, "-r : Reference path/file\n" ); @@ -452,7 +451,7 @@ void ivas_open_files_crend( ivas_crend_io_params_t *pIo_params ) #ifdef USE_PCM_OUT if ( ( pIo_params->fIn[0] = fopen( pIo_params->in_path, "rb" ) ) == NULL ) #else - if ( AudioFileReader_open( &pIo_params->fIn[0] , pIo_params->in_path, &pIo_params->sample_rate ) != IVAS_ERR_OK ) + if ( AudioFileReader_open( &pIo_params->fIn[0], pIo_params->in_path, &pIo_params->sample_rate ) != IVAS_ERR_OK ) #endif { fprintf( stderr, "Error: Input audio file %s could not be opened\n\n", pIo_params->in_path ); @@ -867,7 +866,7 @@ static ivas_result_t ivas_wrapper_get_in_buf( ivas_crend_io_params_t *pIo_params int16_t tmp, read = 0; num_in_ch = ivas_get_num_channels( pIo_params->in_fmt ); - if ( pIo_params->test == CREND_BIN_TEST || pIo_params->test == FASTCONV_BIN_TEST || pIo_params->test == PARAM_BIN_TEST || pIo_params->test == TD_BIN_TEST || pIo_params->test == CREND_ACOUSTIC_PROXIMITY) + if ( pIo_params->test == CREND_BIN_TEST || pIo_params->test == FASTCONV_BIN_TEST || pIo_params->test == PARAM_BIN_TEST || pIo_params->test == TD_BIN_TEST || pIo_params->test == CREND_ACOUSTIC_PROXIMITY ) { /* Read in PCM */ for ( j = 0; j < input_frame_len; j++ ) @@ -877,11 +876,11 @@ static ivas_result_t ivas_wrapper_get_in_buf( ivas_crend_io_params_t *pIo_params #ifdef USE_PCM_OUT if ( ( read = (int16_t) fread( &tmp, sizeof( int16_t ), 1, pIo_params->fIn[0] ) ) > 0 ) #else - if ( (AudioFileReader_read( pIo_params->fIn[0], &tmp, 1, &read ) == IVAS_ERR_OK) && (read > 0) ) + if ( ( AudioFileReader_read( pIo_params->fIn[0], &tmp, 1, &read ) == IVAS_ERR_OK ) && ( read > 0 ) ) #endif { ppPcm_in[i][j] = (float) tmp; - // ppPcm_in[i][j] *= ( 1.0 / PCM16_TO_FLT_FAC ); + // ppPcm_in[i][j] *= ( 1.0 / PCM16_TO_FLT_FAC ); samples_read += 1; } else @@ -917,9 +916,9 @@ static ivas_result_t ivas_wrapper_get_in_buf( ivas_crend_io_params_t *pIo_params #else if ( ( AudioFileReader_read( pIo_params->fIn[i], &tmp, 1, &read ) == IVAS_ERR_OK ) && ( read > 0 ) ) #endif - { + { ppPcm_in[i][j] = (float) tmp; - // ppPcm_in[i][j] *= ( 1.0 / PCM16_TO_FLT_FAC ); + // ppPcm_in[i][j] *= ( 1.0 / PCM16_TO_FLT_FAC ); samples_read += 1; } else @@ -949,14 +948,14 @@ static ivas_result_t ivas_wrapper_get_in_buf( ivas_crend_io_params_t *pIo_params *---------------------------------------------------------------------*/ static ivas_result_t ivas_feed_head_track_data( - Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ + Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ IVAS_QUATERNION *orientation /* i : head-tracking data */ ) { HEAD_TRACK_DATA_HANDLE hHeadTrackData; int16_t i; - + hHeadTrackData = st_ivas->hHeadTrackData; if ( hHeadTrackData == NULL ) @@ -1116,7 +1115,7 @@ ivas_result_t ivas_common_mixer_renderer( ivas_crend_io_params_t *pIo_params, fl { st_ivas.ivas_format = SBA_FORMAT; } - + if ( ( pIo_params->out_fmt == BIN_2 ) && ( pIo_params->in_fmt != pIo_params->out_fmt ) ) { if ( pIo_params->test == FASTCONV_BIN_TEST ) @@ -1131,8 +1130,8 @@ ivas_result_t ivas_common_mixer_renderer( ivas_crend_io_params_t *pIo_params, fl { st_ivas.renderer_type = RENDERER_BINAURAL_FASTCONV; st_ivas.hOutSetup.output_config = st_ivas.hDecoderConfig->output_config = AUDIO_CONFIG_BINAURAL; - if (st_ivas.ivas_format == MC_FORMAT) - pIo_params->latency_s = ( (float) frame_len ) / (float) dec_io_params.out_sample_rate + FASTCONV_HRIR_latency_s ; + if ( st_ivas.ivas_format == MC_FORMAT ) + pIo_params->latency_s = ( (float) frame_len ) / (float) dec_io_params.out_sample_rate + FASTCONV_HRIR_latency_s; else pIo_params->latency_s = ( (float) frame_len ) / (float) dec_io_params.out_sample_rate + FASTCONV_HOA3_latency_s; } @@ -1144,7 +1143,7 @@ ivas_result_t ivas_common_mixer_renderer( ivas_crend_io_params_t *pIo_params, fl fprintf( stderr, "TD Renderer configuration wrong input format\n" ); exit( -1 ); } - + if ( st_ivas.hRenderConfig->roomAcoustics.use_brir ) { st_ivas.renderer_type = RENDERER_BINAURAL_OBJECTS_TD; @@ -1171,7 +1170,7 @@ ivas_result_t ivas_common_mixer_renderer( ivas_crend_io_params_t *pIo_params, fl } pIo_params->latency_s = ( (float) frame_len ) / (float) dec_io_params.out_sample_rate; } - else if( pIo_params->test == CREND_BIN_TEST ) + else if ( pIo_params->test == CREND_BIN_TEST ) { if ( st_ivas.hRenderConfig->roomAcoustics.use_brir ) { @@ -1212,11 +1211,10 @@ ivas_result_t ivas_common_mixer_renderer( ivas_crend_io_params_t *pIo_params, fl { return error; } - if ( ( error = HeadRotationFileReader_open( pIo_params->csv_path , &headRotReader ) ) != IVAS_ERR_OK ) + if ( ( error = HeadRotationFileReader_open( pIo_params->csv_path, &headRotReader ) ) != IVAS_ERR_OK ) { return error; } - } st_ivas.nchan_transport = audioCfg2channels( st_ivas.transport_config ); @@ -1266,8 +1264,8 @@ ivas_result_t ivas_common_mixer_renderer( ivas_crend_io_params_t *pIo_params, fl { if ( ( pIo_params->in_fmt != FOA_4 ) && ( pIo_params->in_fmt != HOA_9 ) && ( pIo_params->in_fmt != HOA_16 ) ) { - fprintf( stderr, "PARAM renderer configuration wrong format, must be FOA or HOA up to order 3\n" ); - exit( -1 ); + fprintf( stderr, "PARAM renderer configuration wrong format, must be FOA or HOA up to order 3\n" ); + exit( -1 ); } ivas_output_init( &st_ivas.hIntSetup, st_ivas.transport_config ); @@ -1310,7 +1308,7 @@ ivas_result_t ivas_common_mixer_renderer( ivas_crend_io_params_t *pIo_params, fl if ( pIo_params->test == CREND_BIN_TEST ) { - pIo_params->latency_s = st_ivas.hHrtf->latency_s; + pIo_params->latency_s = st_ivas.hHrtf->latency_s; } if ( st_ivas.ivas_format == MC_FORMAT ) { @@ -1360,7 +1358,7 @@ ivas_result_t ivas_common_mixer_renderer( ivas_crend_io_params_t *pIo_params, fl delay_lp = 0; } } - + if ( pIo_params->limiter_enable ) { st_ivas.hLimiter = ivas_limiter_open( out_ch, pIo_params->sample_rate ); @@ -1387,20 +1385,20 @@ ivas_result_t ivas_common_mixer_renderer( ivas_crend_io_params_t *pIo_params, fl { skip_samples = NS2SA( pIo_params->sample_rate, (int32_t) ( pIo_params->latency_s * 1000000000.f ) ); } - fprintf( stdout, "IVAS Common Renderer skip samples = %d\n", (int)skip_samples ); + fprintf( stdout, "IVAS Common Renderer skip samples = %d\n", (int) skip_samples ); frame_len = frame_len << 2; - int32_t frame_dec=0; - IVAS_QUATERNION Quaternions[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES] = {0}; + int32_t frame_dec = 0; + IVAS_QUATERNION Quaternions[IVAS_MAX_PARAM_SPATIAL_SUBFRAMES] = { 0 }; /* process loop */ - while ( ( ( result = ivas_wrapper_get_in_buf( pIo_params, ppPcm_in ) ) == IVAS_SUCCESS ) && ( (st_ivas.hDecoderConfig->Opt_Headrotation == 0) || ( (st_ivas.hDecoderConfig->Opt_Headrotation == 1) && (HeadRotationFileReading( headRotReader, Quaternions, frame_dec ) == IVAS_ERR_OK ) ) ) ) + while ( ( ( result = ivas_wrapper_get_in_buf( pIo_params, ppPcm_in ) ) == IVAS_SUCCESS ) && ( ( st_ivas.hDecoderConfig->Opt_Headrotation == 0 ) || ( ( st_ivas.hDecoderConfig->Opt_Headrotation == 1 ) && ( HeadRotationFileReading( headRotReader, Quaternions, frame_dec ) == IVAS_ERR_OK ) ) ) ) { int16_t pcm[MAX_OUTPUT_CHANNELS]; frame_dec++; result = IVAS_SUCCESS; - if ( ( st_ivas.hDecoderConfig->Opt_Headrotation == 1 ) && (ivas_feed_head_track_data( &st_ivas, Quaternions ) != IVAS_SUCCESS )) + if ( ( st_ivas.hDecoderConfig->Opt_Headrotation == 1 ) && ( ivas_feed_head_track_data( &st_ivas, Quaternions ) != IVAS_SUCCESS ) ) { return IVAS_IO_ERROR; } @@ -1419,7 +1417,7 @@ ivas_result_t ivas_common_mixer_renderer( ivas_crend_io_params_t *pIo_params, fl if ( pIo_params->test == FASTCONV_BIN_TEST ) { ivas_binaural_cldfb( &st_ivas, ppPcm_in ); - } + } else if ( pIo_params->test == TD_BIN_TEST ) { ObjRenderIVASFrame( &st_ivas, ppPcm_in, frame_len ); @@ -1436,7 +1434,7 @@ ivas_result_t ivas_common_mixer_renderer( ivas_crend_io_params_t *pIo_params, fl /* Implement a 5 msec loops */ maxBand = (int16_t) ( ( CLDFB_NO_CHANNELS_MAX * st_ivas.hDecoderConfig->output_Fs ) / 48000 ); - for ( slot_idx = 0; slot_idx < (int16_t)CLDFB_NO_COL_MAX; slot_idx++ ) + for ( slot_idx = 0; slot_idx < (int16_t) CLDFB_NO_COL_MAX; slot_idx++ ) { for ( ch = 0; ch < in_ch; ch++ ) @@ -1448,7 +1446,7 @@ ivas_result_t ivas_common_mixer_renderer( ivas_crend_io_params_t *pIo_params, fl } } - for ( slot_idx = 0; slot_idx < (int16_t)CLDFB_NO_COL_MAX ; slot_idx++ ) + for ( slot_idx = 0; slot_idx < (int16_t) CLDFB_NO_COL_MAX; slot_idx++ ) { /* Implement binaural rendering */ for ( ch = 0; ch < BINAURAL_CHANNELS; ch++ ) @@ -1465,7 +1463,7 @@ ivas_result_t ivas_common_mixer_renderer( ivas_crend_io_params_t *pIo_params, fl { filterTapsRealPtr = hrtfShCoeffsRe[ch][chIdx]; filterTapsImagPtr = hrtfShCoeffsIm[ch][chIdx]; - + for ( bandIdx = 0; bandIdx < maxBand; bandIdx++ ) { RealBuffer[bandIdx] += gain * ( Cldfb_RealBuffer[chIdx][slot_idx][bandIdx] * filterTapsRealPtr[bandIdx] ) - ( Cldfb_ImagBuffer[chIdx][slot_idx][bandIdx] * filterTapsImagPtr[bandIdx] ); @@ -1477,7 +1475,6 @@ ivas_result_t ivas_common_mixer_renderer( ivas_crend_io_params_t *pIo_params, fl cldfbSynthesis( &outSlotRePr, &outSlotImPr, &( ppPcm_in[ch][slot_idx * maxBand] ), maxBand, st_ivas.cldfbSynDec[ch] ); } } - } else { @@ -1485,23 +1482,24 @@ ivas_result_t ivas_common_mixer_renderer( ivas_crend_io_params_t *pIo_params, fl { ivas_crend_mixer( ppPcm_in, ppPcm_out, in_ch, out_ch, mixer, frame_len ); } - else + else { ivas_crend_process( &st_ivas, ppPcm_in ); } } - + if ( mixer == NULL ) { - if ( pIo_params->lfe_lp_enable ) - { - for ( i = 0; i < out_ch; i++ ) + if ( pIo_params->lfe_lp_enable ) { - delay_signal( ppPcm_in[i], frame_len, ppDelay_lines[i], delay_lp ); + for ( i = 0; i < out_ch; i++ ) + { + delay_signal( ppPcm_in[i], frame_len, ppDelay_lines[i], delay_lp ); + } } - ivas_binaural_add_LFE( &st_ivas, frame_len, ppPcm_in ); - } + ivas_binaural_add_LFE( &st_ivas, frame_len, ppPcm_in ); + for ( i = 0; i < out_ch; i++ ) { mvr2r( ppPcm_in[i], ppPcm_out[i], frame_len ); @@ -1523,7 +1521,7 @@ ivas_result_t ivas_common_mixer_renderer( ivas_crend_io_params_t *pIo_params, fl } for ( i = 0; i < out_ch; i++ ) { -// float temp = roundf( ppPcm_out[i][j] * PCM16_TO_FLT_FAC ); + // float temp = roundf( ppPcm_out[i][j] * PCM16_TO_FLT_FAC ); float temp; #ifdef _FIND_MAX_ valMaxLoc = ( ppPcm_out[i][j] > valMaxLoc ) ? ppPcm_out[i][j] : ( ppPcm_out[i][j] < -valMaxLoc ) ? -ppPcm_out[i][j] @@ -1534,15 +1532,13 @@ ivas_result_t ivas_common_mixer_renderer( ivas_crend_io_params_t *pIo_params, fl valEner += ppPcm_out[i][j] * ppPcm_out[i][j]; #endif temp = ( ppPcm_out[i][j] > MAX16B_FLT ) ? MAX16B_FLT : ( ppPcm_out[i][j] < MIN16B_FLT ) ? MIN16B_FLT - : ppPcm_out[i][j]; - pcm[i] = (short) roundf(temp); + : ppPcm_out[i][j]; + pcm[i] = (short) roundf( temp ); clip = max( clip, fabsf( ppPcm_out[i][j] ) ); - - } if ( write_flag == 1 ) { -#ifdef USE_PCM_OUT +#ifdef USE_PCM_OUT fwrite( pcm, sizeof( int16_t ), out_ch, pIo_params->fOut ); #else AudioFileWriter_write( pIo_params->fOut, pcm, out_ch ); @@ -1558,10 +1554,9 @@ ivas_result_t ivas_common_mixer_renderer( ivas_crend_io_params_t *pIo_params, fl fprintf( stdout, "Processed frame: %ld\r", (long) frame_count ); frame_count++; - } - int16_t pcm[MAX_OUTPUT_CHANNELS] = {0}; + int16_t pcm[MAX_OUTPUT_CHANNELS] = { 0 }; while ( skipped_samples > 0 ) { AudioFileWriter_write( pIo_params->fOut, pcm, out_ch ); @@ -1579,7 +1574,7 @@ ivas_result_t ivas_common_mixer_renderer( ivas_crend_io_params_t *pIo_params, fl ivas_lfe_dec_close( st_ivas.hLFE ); } - if ( st_ivas.hDirAC != NULL ) + if ( st_ivas.hDirAC != NULL ) ivas_dirac_dec_close( st_ivas.hDirAC ); if ( st_ivas.hBinRenderer != NULL ) ivas_binRenderer_close( &st_ivas.hBinRenderer ); @@ -1754,7 +1749,7 @@ ivas_result_t ivas_object_mixer_renderer( ivas_crend_io_params_t *pIo_params, in for ( i = 0; i < out_ch; i++ ) { -// float temp = roundf( ppPcm_out[i][j] * PCM16_TO_FLT_FAC ); + // float temp = roundf( ppPcm_out[i][j] * PCM16_TO_FLT_FAC ); float temp = roundf( ppPcm_out[i][j] ); #ifdef _FIND_MAX_ @@ -1771,7 +1766,7 @@ ivas_result_t ivas_object_mixer_renderer( ivas_crend_io_params_t *pIo_params, in #ifdef USE_PCM_OUT pcm = ( temp > MAX16B_FLT ) ? MAX16B : ( temp < MIN16B_FLT ) ? MIN16B - : (short) temp; + : (short) temp; fwrite( &pcm, sizeof( int16_t ), 1, pIo_params->fOut ); #else pcm[i] = ( temp > MAX16B_FLT ) ? MAX16B : ( temp < MIN16B_FLT ) ? MIN16B diff --git a/scripts/pyaudio3dtools/binauralrenderer.py b/scripts/pyaudio3dtools/binauralrenderer.py index e9b8f88778..d5004c06f3 100644 --- a/scripts/pyaudio3dtools/binauralrenderer.py +++ b/scripts/pyaudio3dtools/binauralrenderer.py @@ -773,7 +773,8 @@ def binaural_rendering( # delay compensation delay_total_smp = NS2SA(fs, delay_total_ns) y = np.roll(y, -delay_total_smp, axis=0) - y[-delay_total_smp:, :] = 0 + if delay_total_smp > 0: + y[-delay_total_smp:, :] = 0 # resample back to original rate y = audioarray.resample(y, 48000, fs) diff --git a/scripts/tests/constants.py b/scripts/tests/constants.py index 3203d15ccd..639a7792ec 100644 --- a/scripts/tests/constants.py +++ b/scripts/tests/constants.py @@ -70,7 +70,7 @@ TDRENDERER_CMD = [ """ CREND commandline template """ RENDERER_CREND_CMD = [ - str(TESTS_DIR.parent.parent.joinpath("IVAS_crend_unit_test")), + str(TESTS_DIR.parent.parent.joinpath("build/IVAS_crend_unit_test")), "-test", "1", "-sr", @@ -83,8 +83,8 @@ RENDERER_CREND_CMD = [ "", # 2 -> input file "-o", "/dev/null", # 6 -> output file - "-lp_lfe", - "-limiter" + # "-lp_lfe", + # "-limiter" # "-no_delay_cmp" ] diff --git a/scripts/tests/test_renderer.py b/scripts/tests/test_renderer.py index a076b1d72e..c13b16fc3f 100644 --- a/scripts/tests/test_renderer.py +++ b/scripts/tests/test_renderer.py @@ -68,7 +68,7 @@ def check_BE( if not np.allclose(ref, cut, rtol=0, atol=2) and max_diff > 2: if snr >= snr_min: pytest.xfail( - f"xfailed with minimum SNR {snr_min} vs {snr:3.2f}dB, Gain CuT: {gain_b:1.3f}, Max Diff = {int(max_diff)}" + f"Expected failure with minimum SNR {snr_min} vs {snr:3.2f}dB, Gain CuT: {gain_b:1.3f}, Max Diff = {int(max_diff)}" ) else: pytest.fail( @@ -204,8 +204,8 @@ def run_crend_unittest( ) cmd = RENDERER_CREND_CMD[:] - cmd[6] = FORMAT_TO_CREND_FORMAT(str(in_fmt)) - cmd[8] = FORMAT_TO_CREND_FORMAT(str(out_fmt)) + cmd[6] = FORMAT_TO_CREND_FORMAT[str(in_fmt)] + cmd[8] = FORMAT_TO_CREND_FORMAT[str(out_fmt)] cmd[10] = str(in_file) cmd[12] = str(out_file) if str(out_fmt) == "BINAURAL_ROOM": @@ -469,7 +469,7 @@ def test_multichannel_binaural_static(test_info, in_fmt, out_fmt): @pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL) @pytest.mark.parametrize("in_fmt", INPUT_FORMATS_MC[2:]) -def test_multichannel_binaural_static_vs_crend_unitest(test_info, in_fmt, out_fmt): +def test_multichannel_binaural_static_vs_crend_unittest(test_info, in_fmt, out_fmt): cut, cut_fs = run_renderer(in_fmt, out_fmt) @@ -618,36 +618,36 @@ pass_snr = { "test_ambisonics_binaural_static[FOA-BINAURAL_ROOM]": 0.6, "test_ambisonics_binaural_static[HOA2-BINAURAL_ROOM]": 0.5, "test_ambisonics_binaural_static[HOA3-BINAURAL_ROOM]": 0.1, + "test_custom_ls_input_binaural[16ch_8+4+4-BINAURAL]": 0, + "test_custom_ls_input_binaural[16ch_8+4+4-BINAURAL_ROOM]": 0, "test_custom_ls_input_binaural[4d4-BINAURAL]": 0.2, + "test_custom_ls_input_binaural[4d4-BINAURAL_ROOM]": 0, "test_custom_ls_input_binaural[custom1-BINAURAL]": 0.2, + "test_custom_ls_input_binaural[custom1-BINAURAL_ROOM]": 0, "test_custom_ls_input_binaural[itu_4+5+1-BINAURAL]": 0, + "test_custom_ls_input_binaural[itu_4+5+1-BINAURAL_ROOM]": 3, "test_custom_ls_input_binaural[t_design_4-BINAURAL]": 0, + "test_custom_ls_input_binaural[t_design_4-BINAURAL_ROOM]": 0, + "test_custom_ls_input_binaural_headrotation[16ch_8+4+4-BINAURAL-full_circle_in_15s]": 0, + "test_custom_ls_input_binaural_headrotation[16ch_8+4+4-BINAURAL-rotate_yaw_pitch_roll1]": 0, + "test_custom_ls_input_binaural_headrotation[16ch_8+4+4-BINAURAL_ROOM-full_circle_in_15s]": 0, + "test_custom_ls_input_binaural_headrotation[16ch_8+4+4-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 0, "test_custom_ls_input_binaural_headrotation[4d4-BINAURAL-full_circle_in_15s]": 0.1, - "test_custom_ls_input_binaural_headrotation[t_design_4-BINAURAL-full_circle_in_15s]": 0.1, - "test_custom_ls_input_binaural[16ch_8+4+4-BINAURAL]": 0, - "test_custom_ls_input_binaural_headrotation[itu_4+5+1-BINAURAL-rotate_yaw_pitch_roll1]": 0, + "test_custom_ls_input_binaural_headrotation[4d4-BINAURAL-rotate_yaw_pitch_roll1]": 0, + "test_custom_ls_input_binaural_headrotation[4d4-BINAURAL_ROOM-full_circle_in_15s]": 0, + "test_custom_ls_input_binaural_headrotation[4d4-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 0, "test_custom_ls_input_binaural_headrotation[custom1-BINAURAL-full_circle_in_15s]": 0, "test_custom_ls_input_binaural_headrotation[custom1-BINAURAL-rotate_yaw_pitch_roll1]": 0, - "test_custom_ls_input_binaural[4d4-BINAURAL_ROOM]": 0, - "test_custom_ls_input_binaural[custom1-BINAURAL_ROOM]": 0, - "test_custom_ls_input_binaural[t_design_4-BINAURAL_ROOM]": 0, - "test_custom_ls_input_binaural[itu_4+5+1-BINAURAL_ROOM]": 3.9, + "test_custom_ls_input_binaural_headrotation[custom1-BINAURAL_ROOM-full_circle_in_15s]": 0, + "test_custom_ls_input_binaural_headrotation[custom1-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 0, + "test_custom_ls_input_binaural_headrotation[itu_4+5+1-BINAURAL-full_circle_in_15s]": 0, + "test_custom_ls_input_binaural_headrotation[itu_4+5+1-BINAURAL-rotate_yaw_pitch_roll1]": 0, + "test_custom_ls_input_binaural_headrotation[itu_4+5+1-BINAURAL_ROOM-full_circle_in_15s]": 3, + "test_custom_ls_input_binaural_headrotation[itu_4+5+1-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 3, + "test_custom_ls_input_binaural_headrotation[t_design_4-BINAURAL-full_circle_in_15s]": 0.1, "test_custom_ls_input_binaural_headrotation[t_design_4-BINAURAL-rotate_yaw_pitch_roll1]": 0, - "test_custom_ls_input_binaural_headrotation[4d4-BINAURAL-rotate_yaw_pitch_roll1]": 0, - "test_custom_ls_input_binaural_headrotation[4d4-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 0, - "test_custom_ls_input_binaural_headrotation[4d4-BINAURAL_ROOM-full_circle_in_15s]": 0, "test_custom_ls_input_binaural_headrotation[t_design_4-BINAURAL_ROOM-full_circle_in_15s]": 0, - "test_custom_ls_input_binaural_headrotation[16ch_8+4+4-BINAURAL-full_circle_in_15s]": 0, - "test_custom_ls_input_binaural_headrotation[16ch_8+4+4-BINAURAL-rotate_yaw_pitch_roll1]": 0, - "test_custom_ls_input_binaural_headrotation[itu_4+5+1-BINAURAL-full_circle_in_15s]": 0, - "test_custom_ls_input_binaural_headrotation[custom1-BINAURAL_ROOM-full_circle_in_15s]": 0, - "test_custom_ls_input_binaural[16ch_8+4+4-BINAURAL_ROOM]": 0.2, "test_custom_ls_input_binaural_headrotation[t_design_4-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 0, - "test_custom_ls_input_binaural_headrotation[itu_4+5+1-BINAURAL_ROOM-full_circle_in_15s]": 4, - "test_custom_ls_input_binaural_headrotation[itu_4+5+1-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 4, - "test_custom_ls_input_binaural_headrotation[custom1-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 0, - "test_custom_ls_input_binaural_headrotation[16ch_8+4+4-BINAURAL_ROOM-full_circle_in_15s]": 0, - "test_custom_ls_input_binaural_headrotation[16ch_8+4+4-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 0, "test_ism[ISM1-FOA]": 45, "test_ism[ISM1-HOA2]": 41, "test_ism[ISM1-HOA3]": 38, @@ -717,4 +717,14 @@ pass_snr = { "test_multichannel_binaural_static[7_1-BINAURAL_ROOM]": 1, "test_multichannel_binaural_static[7_1_4-BINAURAL]": 7, "test_multichannel_binaural_static[7_1_4-BINAURAL_ROOM]": 1, + "test_multichannel_binaural_static_vs_crend_unittest[5_1-BINAURAL]": 23, + "test_multichannel_binaural_static_vs_crend_unittest[5_1-BINAURAL_ROOM]": 38, + "test_multichannel_binaural_static_vs_crend_unittest[5_1_2-BINAURAL]": 24, + "test_multichannel_binaural_static_vs_crend_unittest[5_1_2-BINAURAL_ROOM]": 37, + "test_multichannel_binaural_static_vs_crend_unittest[5_1_4-BINAURAL]": 23, + "test_multichannel_binaural_static_vs_crend_unittest[5_1_4-BINAURAL_ROOM]": 36, + "test_multichannel_binaural_static_vs_crend_unittest[7_1-BINAURAL]": 24, + "test_multichannel_binaural_static_vs_crend_unittest[7_1-BINAURAL_ROOM]": 37, + "test_multichannel_binaural_static_vs_crend_unittest[7_1_4-BINAURAL]": 23, + "test_multichannel_binaural_static_vs_crend_unittest[7_1_4-BINAURAL_ROOM]": 36, } -- GitLab From cfc0a4434942946f1af5df47a0365452798514a0 Mon Sep 17 00:00:00 2001 From: Archit Tamarapu Date: Wed, 26 Oct 2022 13:43:02 +0200 Subject: [PATCH 049/101] [fix] IVAS_crend_unit_test binary location --- .gitlab-ci.yml | 1 + scripts/tests/constants.py | 8 +++++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 08847375e2..989db6f25b 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -272,6 +272,7 @@ external-renderer-make-pytest: stage: test script: - make -j IVAS_rend + - make -j unittests - python3 -m pytest scripts/tests/test_renderer.py -q --log-level ERROR -n auto # test external renderer executable with cmake + asan diff --git a/scripts/tests/constants.py b/scripts/tests/constants.py index 639a7792ec..2836c9998e 100644 --- a/scripts/tests/constants.py +++ b/scripts/tests/constants.py @@ -32,8 +32,10 @@ from pathlib import PurePath TESTS_DIR = PurePath(__file__).parent TEST_VECTOR_DIR = TESTS_DIR.joinpath("data") -OUTPUT_PATH_REF = TESTS_DIR.joinpath("ref") -OUTPUT_PATH_CUT = TESTS_DIR.joinpath("cut") +# OUTPUT_PATH_REF = TESTS_DIR.joinpath("ref") +# OUTPUT_PATH_CUT = TESTS_DIR.joinpath("cut") +OUTPUT_PATH_REF = TESTS_DIR.joinpath("/home/amm-er/tmu/external_renderer/ref") +OUTPUT_PATH_CUT = TESTS_DIR.joinpath("/home/amm-er/tmu/external_renderer/cut") CUSTOM_LAYOUT_DIR = TEST_VECTOR_DIR.parent.parent.joinpath("ls_layouts") HR_TRAJECTORY_DIR = TEST_VECTOR_DIR.parent.parent.joinpath("trajectories") @@ -70,7 +72,7 @@ TDRENDERER_CMD = [ """ CREND commandline template """ RENDERER_CREND_CMD = [ - str(TESTS_DIR.parent.parent.joinpath("build/IVAS_crend_unit_test")), + str(TESTS_DIR.parent.parent.joinpath("IVAS_crend_unit_test")), "-test", "1", "-sr", -- GitLab From 761861313e4045a0fa79cf9bd825ec6b2f17d316 Mon Sep 17 00:00:00 2001 From: Archit Tamarapu Date: Wed, 26 Oct 2022 13:47:53 +0200 Subject: [PATCH 050/101] "revert accidental change to output directories" --- scripts/tests/constants.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/scripts/tests/constants.py b/scripts/tests/constants.py index 2836c9998e..8c5de89dc1 100644 --- a/scripts/tests/constants.py +++ b/scripts/tests/constants.py @@ -32,10 +32,8 @@ from pathlib import PurePath TESTS_DIR = PurePath(__file__).parent TEST_VECTOR_DIR = TESTS_DIR.joinpath("data") -# OUTPUT_PATH_REF = TESTS_DIR.joinpath("ref") -# OUTPUT_PATH_CUT = TESTS_DIR.joinpath("cut") -OUTPUT_PATH_REF = TESTS_DIR.joinpath("/home/amm-er/tmu/external_renderer/ref") -OUTPUT_PATH_CUT = TESTS_DIR.joinpath("/home/amm-er/tmu/external_renderer/cut") +OUTPUT_PATH_REF = TESTS_DIR.joinpath("ref") +OUTPUT_PATH_CUT = TESTS_DIR.joinpath("cut") CUSTOM_LAYOUT_DIR = TEST_VECTOR_DIR.parent.parent.joinpath("ls_layouts") HR_TRAJECTORY_DIR = TEST_VECTOR_DIR.parent.parent.joinpath("trajectories") -- GitLab From 222d97a9a6e4c50227dc551d8e025e83bf6d63f4 Mon Sep 17 00:00:00 2001 From: Archit Tamarapu Date: Wed, 26 Oct 2022 14:06:30 +0200 Subject: [PATCH 051/101] disable CREND unit test cases until fixed --- scripts/tests/test_renderer.py | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/tests/test_renderer.py b/scripts/tests/test_renderer.py index c13b16fc3f..5c535e688b 100644 --- a/scripts/tests/test_renderer.py +++ b/scripts/tests/test_renderer.py @@ -467,6 +467,7 @@ def test_multichannel_binaural_static(test_info, in_fmt, out_fmt): check_BE(test_info, ref, ref_fs, cut, cut_fs) +@pytest.mark.skip("Skip CREND unit test comparison until ASAN issues and copying binaries is fixed") @pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL) @pytest.mark.parametrize("in_fmt", INPUT_FORMATS_MC[2:]) def test_multichannel_binaural_static_vs_crend_unittest(test_info, in_fmt, out_fmt): -- GitLab From 526f81065262b1b83b5eb71f041942e10ef77091 Mon Sep 17 00:00:00 2001 From: Archit Tamarapu Date: Wed, 26 Oct 2022 16:55:43 +0200 Subject: [PATCH 052/101] [tests] move renderer tests to tests/renderer in the root directory - update CMakeLists.txt to copy IVAS_crend_unit_test to the same location as `make unittests` does - update .gitlab-ci.yml accordingly - update paths in the corresponding renderer pytest scripts --- .gitignore | 4 ++-- .gitlab-ci.yml | 4 ++-- CMakeLists.txt | 4 ++-- {scripts/tests => tests/renderer}/__init__.py | 0 {scripts/tests => tests/renderer}/compare_audio.py | 5 +++++ {scripts/tests => tests/renderer}/constants.py | 13 +++++++------ {scripts/tests => tests/renderer}/cut/.gitignore | 0 .../renderer}/data/IVAS_ISM_metadata_-30_0.csv | 0 .../renderer}/data/IVAS_ISM_metadata_0_0.csv | 0 .../renderer}/data/IVAS_ISM_metadata_30_0.csv | 0 .../renderer}/data/IVAS_ISM_metadata_circle.csv | 0 .../renderer}/data/ism1_ivas_mtdt_config.txt | 0 .../renderer}/data/ism1_shorthand_config.txt | 0 .../renderer}/data/ism2_ivas_mtdt_config.txt | 0 .../renderer}/data/ism2_shorthand_config.txt | 0 .../renderer}/data/ism3_ivas_mtdt_config.txt | 0 .../renderer}/data/ism3_shorthand_config.txt | 0 .../renderer}/data/ism4_ivas_mtdt_config.txt | 0 .../renderer}/data/ism4_shorthand_config.txt | 0 .../tests => tests/renderer}/data/ism_-90a_0e.csv | 0 .../tests => tests/renderer}/data/ism_0a_0e.csv | 0 .../tests => tests/renderer}/data/ism_180a_0e.csv | 0 .../tests => tests/renderer}/data/ism_90a_0e.csv | 0 .../tests => tests/renderer}/data/masa_scene.txt | 0 .../renderer}/data/mixed_ivas_mtdt_config.txt | 0 .../renderer}/data/mixed_ivas_mtdt_gain_config.txt | 0 .../tests => tests/renderer}/data/mixed_scene.txt | 0 .../renderer}/data/mixed_scene_simple.txt | 0 .../renderer}/data/mixed_shorthand_config.txt | 0 .../renderer}/data/mixed_shorthand_gain_config.txt | 0 .../data/mixed_shorthand_limiter_config.txt | 0 .../renderer}/data/pink_noise_10ch_48kHz.wav | 0 .../renderer}/data/pink_noise_11ch_48kHz.wav | 0 .../renderer}/data/pink_noise_12ch_48kHz.wav | 0 .../renderer}/data/pink_noise_13ch_48kHz.wav | 0 .../renderer}/data/pink_noise_14ch_48kHz.wav | 0 .../renderer}/data/pink_noise_15ch_48kHz.wav | 0 .../renderer}/data/pink_noise_16ch_48kHz.wav | 0 .../renderer}/data/pink_noise_1ch_48kHz.wav | 0 .../renderer}/data/pink_noise_2ch_48kHz.wav | 0 .../renderer}/data/pink_noise_3ch_48kHz.wav | 0 .../renderer}/data/pink_noise_4ch_48kHz.wav | 0 .../renderer}/data/pink_noise_5ch_48kHz.wav | 0 .../renderer}/data/pink_noise_6ch_48kHz.wav | 0 .../renderer}/data/pink_noise_7ch_48kHz.wav | 0 .../renderer}/data/pink_noise_8ch_48kHz.wav | 0 .../renderer}/data/pink_noise_9ch_48kHz.wav | 0 .../data/renderer_config_format_readme.txt | 0 .../renderer}/data/spectral_test_10ch_48kHz.wav | 0 .../renderer}/data/spectral_test_11ch_48kHz.wav | 0 .../renderer}/data/spectral_test_12ch_48kHz.wav | 0 .../renderer}/data/spectral_test_15ch_48kHz.wav | 0 .../renderer}/data/spectral_test_16ch_48kHz.wav | 0 .../renderer}/data/spectral_test_1ch_48kHz.wav | 0 .../renderer}/data/spectral_test_2ch_48kHz.wav | 0 .../renderer}/data/spectral_test_3ch_48kHz.wav | 0 .../renderer}/data/spectral_test_4ch_48kHz.wav | 0 .../renderer}/data/spectral_test_5ch_48kHz.wav | 0 .../renderer}/data/spectral_test_6ch_48kHz.wav | 0 .../renderer}/data/spectral_test_8ch_48kHz.wav | 0 .../renderer}/data/spectral_test_9ch_48kHz.wav | 0 .../renderer}/data/spectral_test_ism1.txt | 0 .../renderer}/data/spectral_test_ism2.txt | 0 .../renderer}/data/spectral_test_ism3.txt | 0 .../renderer}/data/spectral_test_ism4.txt | 0 {scripts/tests => tests/renderer}/data/stvISM1.csv | 0 {scripts/tests => tests/renderer}/data/stvISM2.csv | 0 {scripts/tests => tests/renderer}/data/stvISM3.csv | 0 {scripts/tests => tests/renderer}/data/stvISM4.csv | 0 .../renderer}/data/stv_IVASMASA_1dir1TC.met | 0 .../renderer}/data/stv_IVASMASA_1dir1TC.pcm | 0 .../renderer}/data/stv_IVASMASA_1dir2TC.met | 0 .../renderer}/data/stv_IVASMASA_1dir2TC.pcm | 0 .../renderer}/data/stv_IVASMASA_2dir1TC.met | 0 .../renderer}/data/stv_IVASMASA_2dir1TC.pcm | 0 .../renderer}/data/stv_IVASMASA_2dir2TC.met | 0 .../renderer}/data/stv_IVASMASA_2dir2TC.pcm | 0 {scripts/tests => tests/renderer}/ref/.gitignore | 0 {scripts/tests => tests/renderer}/test_renderer.py | 11 ++++++++--- 79 files changed, 26 insertions(+), 15 deletions(-) rename {scripts/tests => tests/renderer}/__init__.py (100%) rename {scripts/tests => tests/renderer}/compare_audio.py (98%) rename {scripts/tests => tests/renderer}/constants.py (95%) rename {scripts/tests => tests/renderer}/cut/.gitignore (100%) rename {scripts/tests => tests/renderer}/data/IVAS_ISM_metadata_-30_0.csv (100%) rename {scripts/tests => tests/renderer}/data/IVAS_ISM_metadata_0_0.csv (100%) rename {scripts/tests => tests/renderer}/data/IVAS_ISM_metadata_30_0.csv (100%) rename {scripts/tests => tests/renderer}/data/IVAS_ISM_metadata_circle.csv (100%) rename {scripts/tests => tests/renderer}/data/ism1_ivas_mtdt_config.txt (100%) rename {scripts/tests => tests/renderer}/data/ism1_shorthand_config.txt (100%) rename {scripts/tests => tests/renderer}/data/ism2_ivas_mtdt_config.txt (100%) rename {scripts/tests => tests/renderer}/data/ism2_shorthand_config.txt (100%) rename {scripts/tests => tests/renderer}/data/ism3_ivas_mtdt_config.txt (100%) rename {scripts/tests => tests/renderer}/data/ism3_shorthand_config.txt (100%) rename {scripts/tests => tests/renderer}/data/ism4_ivas_mtdt_config.txt (100%) rename {scripts/tests => tests/renderer}/data/ism4_shorthand_config.txt (100%) rename {scripts/tests => tests/renderer}/data/ism_-90a_0e.csv (100%) rename {scripts/tests => tests/renderer}/data/ism_0a_0e.csv (100%) rename {scripts/tests => tests/renderer}/data/ism_180a_0e.csv (100%) rename {scripts/tests => tests/renderer}/data/ism_90a_0e.csv (100%) rename {scripts/tests => tests/renderer}/data/masa_scene.txt (100%) rename {scripts/tests => tests/renderer}/data/mixed_ivas_mtdt_config.txt (100%) rename {scripts/tests => tests/renderer}/data/mixed_ivas_mtdt_gain_config.txt (100%) rename {scripts/tests => tests/renderer}/data/mixed_scene.txt (100%) rename {scripts/tests => tests/renderer}/data/mixed_scene_simple.txt (100%) rename {scripts/tests => tests/renderer}/data/mixed_shorthand_config.txt (100%) rename {scripts/tests => tests/renderer}/data/mixed_shorthand_gain_config.txt (100%) rename {scripts/tests => tests/renderer}/data/mixed_shorthand_limiter_config.txt (100%) rename {scripts/tests => tests/renderer}/data/pink_noise_10ch_48kHz.wav (100%) rename {scripts/tests => tests/renderer}/data/pink_noise_11ch_48kHz.wav (100%) rename {scripts/tests => tests/renderer}/data/pink_noise_12ch_48kHz.wav (100%) rename {scripts/tests => tests/renderer}/data/pink_noise_13ch_48kHz.wav (100%) rename {scripts/tests => tests/renderer}/data/pink_noise_14ch_48kHz.wav (100%) rename {scripts/tests => tests/renderer}/data/pink_noise_15ch_48kHz.wav (100%) rename {scripts/tests => tests/renderer}/data/pink_noise_16ch_48kHz.wav (100%) rename {scripts/tests => tests/renderer}/data/pink_noise_1ch_48kHz.wav (100%) rename {scripts/tests => tests/renderer}/data/pink_noise_2ch_48kHz.wav (100%) rename {scripts/tests => tests/renderer}/data/pink_noise_3ch_48kHz.wav (100%) rename {scripts/tests => tests/renderer}/data/pink_noise_4ch_48kHz.wav (100%) rename {scripts/tests => tests/renderer}/data/pink_noise_5ch_48kHz.wav (100%) rename {scripts/tests => tests/renderer}/data/pink_noise_6ch_48kHz.wav (100%) rename {scripts/tests => tests/renderer}/data/pink_noise_7ch_48kHz.wav (100%) rename {scripts/tests => tests/renderer}/data/pink_noise_8ch_48kHz.wav (100%) rename {scripts/tests => tests/renderer}/data/pink_noise_9ch_48kHz.wav (100%) rename {scripts/tests => tests/renderer}/data/renderer_config_format_readme.txt (100%) rename {scripts/tests => tests/renderer}/data/spectral_test_10ch_48kHz.wav (100%) rename {scripts/tests => tests/renderer}/data/spectral_test_11ch_48kHz.wav (100%) rename {scripts/tests => tests/renderer}/data/spectral_test_12ch_48kHz.wav (100%) rename {scripts/tests => tests/renderer}/data/spectral_test_15ch_48kHz.wav (100%) rename {scripts/tests => tests/renderer}/data/spectral_test_16ch_48kHz.wav (100%) rename {scripts/tests => tests/renderer}/data/spectral_test_1ch_48kHz.wav (100%) rename {scripts/tests => tests/renderer}/data/spectral_test_2ch_48kHz.wav (100%) rename {scripts/tests => tests/renderer}/data/spectral_test_3ch_48kHz.wav (100%) rename {scripts/tests => tests/renderer}/data/spectral_test_4ch_48kHz.wav (100%) rename {scripts/tests => tests/renderer}/data/spectral_test_5ch_48kHz.wav (100%) rename {scripts/tests => tests/renderer}/data/spectral_test_6ch_48kHz.wav (100%) rename {scripts/tests => tests/renderer}/data/spectral_test_8ch_48kHz.wav (100%) rename {scripts/tests => tests/renderer}/data/spectral_test_9ch_48kHz.wav (100%) rename {scripts/tests => tests/renderer}/data/spectral_test_ism1.txt (100%) rename {scripts/tests => tests/renderer}/data/spectral_test_ism2.txt (100%) rename {scripts/tests => tests/renderer}/data/spectral_test_ism3.txt (100%) rename {scripts/tests => tests/renderer}/data/spectral_test_ism4.txt (100%) rename {scripts/tests => tests/renderer}/data/stvISM1.csv (100%) rename {scripts/tests => tests/renderer}/data/stvISM2.csv (100%) rename {scripts/tests => tests/renderer}/data/stvISM3.csv (100%) rename {scripts/tests => tests/renderer}/data/stvISM4.csv (100%) rename {scripts/tests => tests/renderer}/data/stv_IVASMASA_1dir1TC.met (100%) rename {scripts/tests => tests/renderer}/data/stv_IVASMASA_1dir1TC.pcm (100%) rename {scripts/tests => tests/renderer}/data/stv_IVASMASA_1dir2TC.met (100%) rename {scripts/tests => tests/renderer}/data/stv_IVASMASA_1dir2TC.pcm (100%) rename {scripts/tests => tests/renderer}/data/stv_IVASMASA_2dir1TC.met (100%) rename {scripts/tests => tests/renderer}/data/stv_IVASMASA_2dir1TC.pcm (100%) rename {scripts/tests => tests/renderer}/data/stv_IVASMASA_2dir2TC.met (100%) rename {scripts/tests => tests/renderer}/data/stv_IVASMASA_2dir2TC.pcm (100%) rename {scripts/tests => tests/renderer}/ref/.gitignore (100%) rename {scripts/tests => tests/renderer}/test_renderer.py (99%) diff --git a/.gitignore b/.gitignore index 55a113e4bb..591570d7d1 100644 --- a/.gitignore +++ b/.gitignore @@ -47,8 +47,8 @@ scripts/ref/ scripts/test/ scripts/out/ scripts/self_test_summary.txt -scripts/tests/cut/ -scripts/tests/ref/ +tests/renderer/cut +tests/renderer/ref tests/dut tests/ref diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index bc7b9ade46..a3e6fbc120 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -330,7 +330,7 @@ external-renderer-cmake-asan-pytest: stage: test script: - python3 ci/disable_ram_counting.py - - cmake -B cmake-build -G "Unix Makefiles" -DCLANG=asan -DCOPY_EXECUTABLES_TO_ROOT=true + - cmake -B cmake-build -G "Unix Makefiles" -DCLANG=asan -DCOPY_EXECUTABLES_FROM_BUILD_DIR=true - cmake --build cmake-build -- -j - python3 -m pytest scripts/tests/test_renderer.py -q --log-level ERROR -n auto @@ -343,7 +343,7 @@ external-renderer-cmake-msan-pytest: stage: test script: - python3 ci/disable_ram_counting.py - - cmake -B cmake-build -G "Unix Makefiles" -DCLANG=msan -DCOPY_EXECUTABLES_TO_ROOT=true + - cmake -B cmake-build -G "Unix Makefiles" -DCLANG=msan -DCOPY_EXECUTABLES_FROM_BUILD_DIR=true - cmake --build cmake-build -- -j - python3 -m pytest scripts/tests/test_renderer.py -q --log-level ERROR -n auto diff --git a/CMakeLists.txt b/CMakeLists.txt index 0751f32401..8e9237dcd8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -172,10 +172,10 @@ endif() add_executable(IVAS_rend apps/renderer.c) target_link_libraries(IVAS_rend lib_rend lib_util) -if(COPY_EXECUTABLES_TO_ROOT) +if(COPY_EXECUTABLES_FROM_BUILD_DIR) # Optionally copy executables to root directory after build 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}/") - add_custom_command(TARGET IVAS_crend_unit_test POST_BUILD VERBATIM COMMAND "${CMAKE_COMMAND}" -E copy "$" "${CMAKE_CURRENT_SOURCE_DIR}/") + add_custom_command(TARGET IVAS_crend_unit_test POST_BUILD VERBATIM COMMAND "${CMAKE_COMMAND}" -E copy "$" "${CMAKE_CURRENT_SOURCE_DIR}/scripts/ivas_pytests/tests/unit_tests/crend/") endif() diff --git a/scripts/tests/__init__.py b/tests/renderer/__init__.py similarity index 100% rename from scripts/tests/__init__.py rename to tests/renderer/__init__.py diff --git a/scripts/tests/compare_audio.py b/tests/renderer/compare_audio.py similarity index 98% rename from scripts/tests/compare_audio.py rename to tests/renderer/compare_audio.py index 915cc432e9..e7bd34f6df 100644 --- a/scripts/tests/compare_audio.py +++ b/tests/renderer/compare_audio.py @@ -26,10 +26,15 @@ the United Nations Convention on Contracts on the International Sales of Goods. """ +import sys import warnings from typing import Tuple import numpy as np + +from .constants import SCRIPTS_DIR + +sys.path.append(str(SCRIPTS_DIR)) from pyaudio3dtools.audioarray import getdelay diff --git a/scripts/tests/constants.py b/tests/renderer/constants.py similarity index 95% rename from scripts/tests/constants.py rename to tests/renderer/constants.py index 8c5de89dc1..4ecb5f503c 100644 --- a/scripts/tests/constants.py +++ b/tests/renderer/constants.py @@ -26,17 +26,18 @@ the United Nations Convention on Contracts on the International Sales of Goods. """ -from pathlib import PurePath +from pathlib import Path """ Set up paths """ -TESTS_DIR = PurePath(__file__).parent +TESTS_DIR = Path(__file__).parent +SCRIPTS_DIR = TESTS_DIR.parents[1].joinpath("scripts").resolve() TEST_VECTOR_DIR = TESTS_DIR.joinpath("data") OUTPUT_PATH_REF = TESTS_DIR.joinpath("ref") OUTPUT_PATH_CUT = TESTS_DIR.joinpath("cut") -CUSTOM_LAYOUT_DIR = TEST_VECTOR_DIR.parent.parent.joinpath("ls_layouts") -HR_TRAJECTORY_DIR = TEST_VECTOR_DIR.parent.parent.joinpath("trajectories") +CUSTOM_LAYOUT_DIR = SCRIPTS_DIR.joinpath("ls_layouts") +HR_TRAJECTORY_DIR = SCRIPTS_DIR.joinpath("trajectories") """ Renderer commandline template """ RENDERER_CMD = [ @@ -70,7 +71,7 @@ TDRENDERER_CMD = [ """ CREND commandline template """ RENDERER_CREND_CMD = [ - str(TESTS_DIR.parent.parent.joinpath("IVAS_crend_unit_test")), + str(SCRIPTS_DIR.joinpath("ivas_pytests/tests/unit_tests/crend/IVAS_crend_unit_test")), "-test", "1", "-sr", @@ -84,7 +85,7 @@ RENDERER_CREND_CMD = [ "-o", "/dev/null", # 6 -> output file # "-lp_lfe", - # "-limiter" + "-limiter" # "-no_delay_cmp" ] diff --git a/scripts/tests/cut/.gitignore b/tests/renderer/cut/.gitignore similarity index 100% rename from scripts/tests/cut/.gitignore rename to tests/renderer/cut/.gitignore diff --git a/scripts/tests/data/IVAS_ISM_metadata_-30_0.csv b/tests/renderer/data/IVAS_ISM_metadata_-30_0.csv similarity index 100% rename from scripts/tests/data/IVAS_ISM_metadata_-30_0.csv rename to tests/renderer/data/IVAS_ISM_metadata_-30_0.csv diff --git a/scripts/tests/data/IVAS_ISM_metadata_0_0.csv b/tests/renderer/data/IVAS_ISM_metadata_0_0.csv similarity index 100% rename from scripts/tests/data/IVAS_ISM_metadata_0_0.csv rename to tests/renderer/data/IVAS_ISM_metadata_0_0.csv diff --git a/scripts/tests/data/IVAS_ISM_metadata_30_0.csv b/tests/renderer/data/IVAS_ISM_metadata_30_0.csv similarity index 100% rename from scripts/tests/data/IVAS_ISM_metadata_30_0.csv rename to tests/renderer/data/IVAS_ISM_metadata_30_0.csv diff --git a/scripts/tests/data/IVAS_ISM_metadata_circle.csv b/tests/renderer/data/IVAS_ISM_metadata_circle.csv similarity index 100% rename from scripts/tests/data/IVAS_ISM_metadata_circle.csv rename to tests/renderer/data/IVAS_ISM_metadata_circle.csv diff --git a/scripts/tests/data/ism1_ivas_mtdt_config.txt b/tests/renderer/data/ism1_ivas_mtdt_config.txt similarity index 100% rename from scripts/tests/data/ism1_ivas_mtdt_config.txt rename to tests/renderer/data/ism1_ivas_mtdt_config.txt diff --git a/scripts/tests/data/ism1_shorthand_config.txt b/tests/renderer/data/ism1_shorthand_config.txt similarity index 100% rename from scripts/tests/data/ism1_shorthand_config.txt rename to tests/renderer/data/ism1_shorthand_config.txt diff --git a/scripts/tests/data/ism2_ivas_mtdt_config.txt b/tests/renderer/data/ism2_ivas_mtdt_config.txt similarity index 100% rename from scripts/tests/data/ism2_ivas_mtdt_config.txt rename to tests/renderer/data/ism2_ivas_mtdt_config.txt diff --git a/scripts/tests/data/ism2_shorthand_config.txt b/tests/renderer/data/ism2_shorthand_config.txt similarity index 100% rename from scripts/tests/data/ism2_shorthand_config.txt rename to tests/renderer/data/ism2_shorthand_config.txt diff --git a/scripts/tests/data/ism3_ivas_mtdt_config.txt b/tests/renderer/data/ism3_ivas_mtdt_config.txt similarity index 100% rename from scripts/tests/data/ism3_ivas_mtdt_config.txt rename to tests/renderer/data/ism3_ivas_mtdt_config.txt diff --git a/scripts/tests/data/ism3_shorthand_config.txt b/tests/renderer/data/ism3_shorthand_config.txt similarity index 100% rename from scripts/tests/data/ism3_shorthand_config.txt rename to tests/renderer/data/ism3_shorthand_config.txt diff --git a/scripts/tests/data/ism4_ivas_mtdt_config.txt b/tests/renderer/data/ism4_ivas_mtdt_config.txt similarity index 100% rename from scripts/tests/data/ism4_ivas_mtdt_config.txt rename to tests/renderer/data/ism4_ivas_mtdt_config.txt diff --git a/scripts/tests/data/ism4_shorthand_config.txt b/tests/renderer/data/ism4_shorthand_config.txt similarity index 100% rename from scripts/tests/data/ism4_shorthand_config.txt rename to tests/renderer/data/ism4_shorthand_config.txt diff --git a/scripts/tests/data/ism_-90a_0e.csv b/tests/renderer/data/ism_-90a_0e.csv similarity index 100% rename from scripts/tests/data/ism_-90a_0e.csv rename to tests/renderer/data/ism_-90a_0e.csv diff --git a/scripts/tests/data/ism_0a_0e.csv b/tests/renderer/data/ism_0a_0e.csv similarity index 100% rename from scripts/tests/data/ism_0a_0e.csv rename to tests/renderer/data/ism_0a_0e.csv diff --git a/scripts/tests/data/ism_180a_0e.csv b/tests/renderer/data/ism_180a_0e.csv similarity index 100% rename from scripts/tests/data/ism_180a_0e.csv rename to tests/renderer/data/ism_180a_0e.csv diff --git a/scripts/tests/data/ism_90a_0e.csv b/tests/renderer/data/ism_90a_0e.csv similarity index 100% rename from scripts/tests/data/ism_90a_0e.csv rename to tests/renderer/data/ism_90a_0e.csv diff --git a/scripts/tests/data/masa_scene.txt b/tests/renderer/data/masa_scene.txt similarity index 100% rename from scripts/tests/data/masa_scene.txt rename to tests/renderer/data/masa_scene.txt diff --git a/scripts/tests/data/mixed_ivas_mtdt_config.txt b/tests/renderer/data/mixed_ivas_mtdt_config.txt similarity index 100% rename from scripts/tests/data/mixed_ivas_mtdt_config.txt rename to tests/renderer/data/mixed_ivas_mtdt_config.txt diff --git a/scripts/tests/data/mixed_ivas_mtdt_gain_config.txt b/tests/renderer/data/mixed_ivas_mtdt_gain_config.txt similarity index 100% rename from scripts/tests/data/mixed_ivas_mtdt_gain_config.txt rename to tests/renderer/data/mixed_ivas_mtdt_gain_config.txt diff --git a/scripts/tests/data/mixed_scene.txt b/tests/renderer/data/mixed_scene.txt similarity index 100% rename from scripts/tests/data/mixed_scene.txt rename to tests/renderer/data/mixed_scene.txt diff --git a/scripts/tests/data/mixed_scene_simple.txt b/tests/renderer/data/mixed_scene_simple.txt similarity index 100% rename from scripts/tests/data/mixed_scene_simple.txt rename to tests/renderer/data/mixed_scene_simple.txt diff --git a/scripts/tests/data/mixed_shorthand_config.txt b/tests/renderer/data/mixed_shorthand_config.txt similarity index 100% rename from scripts/tests/data/mixed_shorthand_config.txt rename to tests/renderer/data/mixed_shorthand_config.txt diff --git a/scripts/tests/data/mixed_shorthand_gain_config.txt b/tests/renderer/data/mixed_shorthand_gain_config.txt similarity index 100% rename from scripts/tests/data/mixed_shorthand_gain_config.txt rename to tests/renderer/data/mixed_shorthand_gain_config.txt diff --git a/scripts/tests/data/mixed_shorthand_limiter_config.txt b/tests/renderer/data/mixed_shorthand_limiter_config.txt similarity index 100% rename from scripts/tests/data/mixed_shorthand_limiter_config.txt rename to tests/renderer/data/mixed_shorthand_limiter_config.txt diff --git a/scripts/tests/data/pink_noise_10ch_48kHz.wav b/tests/renderer/data/pink_noise_10ch_48kHz.wav similarity index 100% rename from scripts/tests/data/pink_noise_10ch_48kHz.wav rename to tests/renderer/data/pink_noise_10ch_48kHz.wav diff --git a/scripts/tests/data/pink_noise_11ch_48kHz.wav b/tests/renderer/data/pink_noise_11ch_48kHz.wav similarity index 100% rename from scripts/tests/data/pink_noise_11ch_48kHz.wav rename to tests/renderer/data/pink_noise_11ch_48kHz.wav diff --git a/scripts/tests/data/pink_noise_12ch_48kHz.wav b/tests/renderer/data/pink_noise_12ch_48kHz.wav similarity index 100% rename from scripts/tests/data/pink_noise_12ch_48kHz.wav rename to tests/renderer/data/pink_noise_12ch_48kHz.wav diff --git a/scripts/tests/data/pink_noise_13ch_48kHz.wav b/tests/renderer/data/pink_noise_13ch_48kHz.wav similarity index 100% rename from scripts/tests/data/pink_noise_13ch_48kHz.wav rename to tests/renderer/data/pink_noise_13ch_48kHz.wav diff --git a/scripts/tests/data/pink_noise_14ch_48kHz.wav b/tests/renderer/data/pink_noise_14ch_48kHz.wav similarity index 100% rename from scripts/tests/data/pink_noise_14ch_48kHz.wav rename to tests/renderer/data/pink_noise_14ch_48kHz.wav diff --git a/scripts/tests/data/pink_noise_15ch_48kHz.wav b/tests/renderer/data/pink_noise_15ch_48kHz.wav similarity index 100% rename from scripts/tests/data/pink_noise_15ch_48kHz.wav rename to tests/renderer/data/pink_noise_15ch_48kHz.wav diff --git a/scripts/tests/data/pink_noise_16ch_48kHz.wav b/tests/renderer/data/pink_noise_16ch_48kHz.wav similarity index 100% rename from scripts/tests/data/pink_noise_16ch_48kHz.wav rename to tests/renderer/data/pink_noise_16ch_48kHz.wav diff --git a/scripts/tests/data/pink_noise_1ch_48kHz.wav b/tests/renderer/data/pink_noise_1ch_48kHz.wav similarity index 100% rename from scripts/tests/data/pink_noise_1ch_48kHz.wav rename to tests/renderer/data/pink_noise_1ch_48kHz.wav diff --git a/scripts/tests/data/pink_noise_2ch_48kHz.wav b/tests/renderer/data/pink_noise_2ch_48kHz.wav similarity index 100% rename from scripts/tests/data/pink_noise_2ch_48kHz.wav rename to tests/renderer/data/pink_noise_2ch_48kHz.wav diff --git a/scripts/tests/data/pink_noise_3ch_48kHz.wav b/tests/renderer/data/pink_noise_3ch_48kHz.wav similarity index 100% rename from scripts/tests/data/pink_noise_3ch_48kHz.wav rename to tests/renderer/data/pink_noise_3ch_48kHz.wav diff --git a/scripts/tests/data/pink_noise_4ch_48kHz.wav b/tests/renderer/data/pink_noise_4ch_48kHz.wav similarity index 100% rename from scripts/tests/data/pink_noise_4ch_48kHz.wav rename to tests/renderer/data/pink_noise_4ch_48kHz.wav diff --git a/scripts/tests/data/pink_noise_5ch_48kHz.wav b/tests/renderer/data/pink_noise_5ch_48kHz.wav similarity index 100% rename from scripts/tests/data/pink_noise_5ch_48kHz.wav rename to tests/renderer/data/pink_noise_5ch_48kHz.wav diff --git a/scripts/tests/data/pink_noise_6ch_48kHz.wav b/tests/renderer/data/pink_noise_6ch_48kHz.wav similarity index 100% rename from scripts/tests/data/pink_noise_6ch_48kHz.wav rename to tests/renderer/data/pink_noise_6ch_48kHz.wav diff --git a/scripts/tests/data/pink_noise_7ch_48kHz.wav b/tests/renderer/data/pink_noise_7ch_48kHz.wav similarity index 100% rename from scripts/tests/data/pink_noise_7ch_48kHz.wav rename to tests/renderer/data/pink_noise_7ch_48kHz.wav diff --git a/scripts/tests/data/pink_noise_8ch_48kHz.wav b/tests/renderer/data/pink_noise_8ch_48kHz.wav similarity index 100% rename from scripts/tests/data/pink_noise_8ch_48kHz.wav rename to tests/renderer/data/pink_noise_8ch_48kHz.wav diff --git a/scripts/tests/data/pink_noise_9ch_48kHz.wav b/tests/renderer/data/pink_noise_9ch_48kHz.wav similarity index 100% rename from scripts/tests/data/pink_noise_9ch_48kHz.wav rename to tests/renderer/data/pink_noise_9ch_48kHz.wav diff --git a/scripts/tests/data/renderer_config_format_readme.txt b/tests/renderer/data/renderer_config_format_readme.txt similarity index 100% rename from scripts/tests/data/renderer_config_format_readme.txt rename to tests/renderer/data/renderer_config_format_readme.txt diff --git a/scripts/tests/data/spectral_test_10ch_48kHz.wav b/tests/renderer/data/spectral_test_10ch_48kHz.wav similarity index 100% rename from scripts/tests/data/spectral_test_10ch_48kHz.wav rename to tests/renderer/data/spectral_test_10ch_48kHz.wav diff --git a/scripts/tests/data/spectral_test_11ch_48kHz.wav b/tests/renderer/data/spectral_test_11ch_48kHz.wav similarity index 100% rename from scripts/tests/data/spectral_test_11ch_48kHz.wav rename to tests/renderer/data/spectral_test_11ch_48kHz.wav diff --git a/scripts/tests/data/spectral_test_12ch_48kHz.wav b/tests/renderer/data/spectral_test_12ch_48kHz.wav similarity index 100% rename from scripts/tests/data/spectral_test_12ch_48kHz.wav rename to tests/renderer/data/spectral_test_12ch_48kHz.wav diff --git a/scripts/tests/data/spectral_test_15ch_48kHz.wav b/tests/renderer/data/spectral_test_15ch_48kHz.wav similarity index 100% rename from scripts/tests/data/spectral_test_15ch_48kHz.wav rename to tests/renderer/data/spectral_test_15ch_48kHz.wav diff --git a/scripts/tests/data/spectral_test_16ch_48kHz.wav b/tests/renderer/data/spectral_test_16ch_48kHz.wav similarity index 100% rename from scripts/tests/data/spectral_test_16ch_48kHz.wav rename to tests/renderer/data/spectral_test_16ch_48kHz.wav diff --git a/scripts/tests/data/spectral_test_1ch_48kHz.wav b/tests/renderer/data/spectral_test_1ch_48kHz.wav similarity index 100% rename from scripts/tests/data/spectral_test_1ch_48kHz.wav rename to tests/renderer/data/spectral_test_1ch_48kHz.wav diff --git a/scripts/tests/data/spectral_test_2ch_48kHz.wav b/tests/renderer/data/spectral_test_2ch_48kHz.wav similarity index 100% rename from scripts/tests/data/spectral_test_2ch_48kHz.wav rename to tests/renderer/data/spectral_test_2ch_48kHz.wav diff --git a/scripts/tests/data/spectral_test_3ch_48kHz.wav b/tests/renderer/data/spectral_test_3ch_48kHz.wav similarity index 100% rename from scripts/tests/data/spectral_test_3ch_48kHz.wav rename to tests/renderer/data/spectral_test_3ch_48kHz.wav diff --git a/scripts/tests/data/spectral_test_4ch_48kHz.wav b/tests/renderer/data/spectral_test_4ch_48kHz.wav similarity index 100% rename from scripts/tests/data/spectral_test_4ch_48kHz.wav rename to tests/renderer/data/spectral_test_4ch_48kHz.wav diff --git a/scripts/tests/data/spectral_test_5ch_48kHz.wav b/tests/renderer/data/spectral_test_5ch_48kHz.wav similarity index 100% rename from scripts/tests/data/spectral_test_5ch_48kHz.wav rename to tests/renderer/data/spectral_test_5ch_48kHz.wav diff --git a/scripts/tests/data/spectral_test_6ch_48kHz.wav b/tests/renderer/data/spectral_test_6ch_48kHz.wav similarity index 100% rename from scripts/tests/data/spectral_test_6ch_48kHz.wav rename to tests/renderer/data/spectral_test_6ch_48kHz.wav diff --git a/scripts/tests/data/spectral_test_8ch_48kHz.wav b/tests/renderer/data/spectral_test_8ch_48kHz.wav similarity index 100% rename from scripts/tests/data/spectral_test_8ch_48kHz.wav rename to tests/renderer/data/spectral_test_8ch_48kHz.wav diff --git a/scripts/tests/data/spectral_test_9ch_48kHz.wav b/tests/renderer/data/spectral_test_9ch_48kHz.wav similarity index 100% rename from scripts/tests/data/spectral_test_9ch_48kHz.wav rename to tests/renderer/data/spectral_test_9ch_48kHz.wav diff --git a/scripts/tests/data/spectral_test_ism1.txt b/tests/renderer/data/spectral_test_ism1.txt similarity index 100% rename from scripts/tests/data/spectral_test_ism1.txt rename to tests/renderer/data/spectral_test_ism1.txt diff --git a/scripts/tests/data/spectral_test_ism2.txt b/tests/renderer/data/spectral_test_ism2.txt similarity index 100% rename from scripts/tests/data/spectral_test_ism2.txt rename to tests/renderer/data/spectral_test_ism2.txt diff --git a/scripts/tests/data/spectral_test_ism3.txt b/tests/renderer/data/spectral_test_ism3.txt similarity index 100% rename from scripts/tests/data/spectral_test_ism3.txt rename to tests/renderer/data/spectral_test_ism3.txt diff --git a/scripts/tests/data/spectral_test_ism4.txt b/tests/renderer/data/spectral_test_ism4.txt similarity index 100% rename from scripts/tests/data/spectral_test_ism4.txt rename to tests/renderer/data/spectral_test_ism4.txt diff --git a/scripts/tests/data/stvISM1.csv b/tests/renderer/data/stvISM1.csv similarity index 100% rename from scripts/tests/data/stvISM1.csv rename to tests/renderer/data/stvISM1.csv diff --git a/scripts/tests/data/stvISM2.csv b/tests/renderer/data/stvISM2.csv similarity index 100% rename from scripts/tests/data/stvISM2.csv rename to tests/renderer/data/stvISM2.csv diff --git a/scripts/tests/data/stvISM3.csv b/tests/renderer/data/stvISM3.csv similarity index 100% rename from scripts/tests/data/stvISM3.csv rename to tests/renderer/data/stvISM3.csv diff --git a/scripts/tests/data/stvISM4.csv b/tests/renderer/data/stvISM4.csv similarity index 100% rename from scripts/tests/data/stvISM4.csv rename to tests/renderer/data/stvISM4.csv diff --git a/scripts/tests/data/stv_IVASMASA_1dir1TC.met b/tests/renderer/data/stv_IVASMASA_1dir1TC.met similarity index 100% rename from scripts/tests/data/stv_IVASMASA_1dir1TC.met rename to tests/renderer/data/stv_IVASMASA_1dir1TC.met diff --git a/scripts/tests/data/stv_IVASMASA_1dir1TC.pcm b/tests/renderer/data/stv_IVASMASA_1dir1TC.pcm similarity index 100% rename from scripts/tests/data/stv_IVASMASA_1dir1TC.pcm rename to tests/renderer/data/stv_IVASMASA_1dir1TC.pcm diff --git a/scripts/tests/data/stv_IVASMASA_1dir2TC.met b/tests/renderer/data/stv_IVASMASA_1dir2TC.met similarity index 100% rename from scripts/tests/data/stv_IVASMASA_1dir2TC.met rename to tests/renderer/data/stv_IVASMASA_1dir2TC.met diff --git a/scripts/tests/data/stv_IVASMASA_1dir2TC.pcm b/tests/renderer/data/stv_IVASMASA_1dir2TC.pcm similarity index 100% rename from scripts/tests/data/stv_IVASMASA_1dir2TC.pcm rename to tests/renderer/data/stv_IVASMASA_1dir2TC.pcm diff --git a/scripts/tests/data/stv_IVASMASA_2dir1TC.met b/tests/renderer/data/stv_IVASMASA_2dir1TC.met similarity index 100% rename from scripts/tests/data/stv_IVASMASA_2dir1TC.met rename to tests/renderer/data/stv_IVASMASA_2dir1TC.met diff --git a/scripts/tests/data/stv_IVASMASA_2dir1TC.pcm b/tests/renderer/data/stv_IVASMASA_2dir1TC.pcm similarity index 100% rename from scripts/tests/data/stv_IVASMASA_2dir1TC.pcm rename to tests/renderer/data/stv_IVASMASA_2dir1TC.pcm diff --git a/scripts/tests/data/stv_IVASMASA_2dir2TC.met b/tests/renderer/data/stv_IVASMASA_2dir2TC.met similarity index 100% rename from scripts/tests/data/stv_IVASMASA_2dir2TC.met rename to tests/renderer/data/stv_IVASMASA_2dir2TC.met diff --git a/scripts/tests/data/stv_IVASMASA_2dir2TC.pcm b/tests/renderer/data/stv_IVASMASA_2dir2TC.pcm similarity index 100% rename from scripts/tests/data/stv_IVASMASA_2dir2TC.pcm rename to tests/renderer/data/stv_IVASMASA_2dir2TC.pcm diff --git a/scripts/tests/ref/.gitignore b/tests/renderer/ref/.gitignore similarity index 100% rename from scripts/tests/ref/.gitignore rename to tests/renderer/ref/.gitignore diff --git a/scripts/tests/test_renderer.py b/tests/renderer/test_renderer.py similarity index 99% rename from scripts/tests/test_renderer.py rename to tests/renderer/test_renderer.py index 5c535e688b..e7a02408ce 100644 --- a/scripts/tests/test_renderer.py +++ b/tests/renderer/test_renderer.py @@ -27,17 +27,20 @@ """ import subprocess as sp +import sys from pathlib import Path from tempfile import TemporaryDirectory from typing import Optional, Tuple import numpy as np -import pyaudio3dtools import pytest from .compare_audio import compare_audio_arrays from .constants import * +sys.path.append(SCRIPTS_DIR) +import pyaudio3dtools + def check_BE( test_info, @@ -97,7 +100,7 @@ def run_pyscripts( if metadata_input is not None: in_file = metadata_input in_name = metadata_input.stem - elif isinstance(in_fmt, PurePath): + elif isinstance(in_fmt, Path): in_file = FORMAT_TO_FILE[in_fmt.stem] in_name = in_fmt.stem else: @@ -467,7 +470,9 @@ def test_multichannel_binaural_static(test_info, in_fmt, out_fmt): check_BE(test_info, ref, ref_fs, cut, cut_fs) -@pytest.mark.skip("Skip CREND unit test comparison until ASAN issues and copying binaries is fixed") +@pytest.mark.skip( + "Skip CREND unit test comparison until ASAN issues and copying binaries is fixed" +) @pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL) @pytest.mark.parametrize("in_fmt", INPUT_FORMATS_MC[2:]) def test_multichannel_binaural_static_vs_crend_unittest(test_info, in_fmt, out_fmt): -- GitLab From 0633f4a8ca3e546d0f9fd2aa5cfe34cd7cb87c6a Mon Sep 17 00:00:00 2001 From: Archit Tamarapu Date: Wed, 26 Oct 2022 17:02:09 +0200 Subject: [PATCH 053/101] update CI - report all test results and update filepath --- .gitlab-ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index a3e6fbc120..a98fefea44 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -319,7 +319,7 @@ external-renderer-make-pytest: script: - make -j IVAS_rend - make -j unittests - - python3 -m pytest scripts/tests/test_renderer.py -q --log-level ERROR -n auto + - python3 -m pytest tests/renderer/test_renderer.py -q --log-level ERROR -n auto -rA # test external renderer executable with cmake + asan external-renderer-cmake-asan-pytest: @@ -332,7 +332,7 @@ external-renderer-cmake-asan-pytest: - python3 ci/disable_ram_counting.py - cmake -B cmake-build -G "Unix Makefiles" -DCLANG=asan -DCOPY_EXECUTABLES_FROM_BUILD_DIR=true - cmake --build cmake-build -- -j - - python3 -m pytest scripts/tests/test_renderer.py -q --log-level ERROR -n auto + - python3 -m pytest tests/renderer/test_renderer.py -q --log-level ERROR -n auto -rA # test external renderer executable with cmake + msan external-renderer-cmake-msan-pytest: @@ -345,7 +345,7 @@ external-renderer-cmake-msan-pytest: - python3 ci/disable_ram_counting.py - cmake -B cmake-build -G "Unix Makefiles" -DCLANG=msan -DCOPY_EXECUTABLES_FROM_BUILD_DIR=true - cmake --build cmake-build -- -j - - python3 -m pytest scripts/tests/test_renderer.py -q --log-level ERROR -n auto + - python3 -m pytest tests/renderer/test_renderer.py -q --log-level ERROR -n auto -rA # compare bit exactness between target and source branch ivas-pytest-on-merge-request: -- GitLab From 5912615af749cbf27e7920637ea71994c1723fc8 Mon Sep 17 00:00:00 2001 From: Archit Tamarapu Date: Thu, 27 Oct 2022 10:38:42 +0200 Subject: [PATCH 054/101] [tests] Enable testing against TD Object Renderer Standalone - Fix crash by correctly setting Opt_Headrotation in renderer_standalone.c - Instead of testing against pyaudio3dtools as reference, generate it with TD Standalone instead for corresponding paths --- .../renderer_standalone.c | 5 ++ tests/renderer/constants.py | 2 +- tests/renderer/test_renderer.py | 89 ++++++++----------- 3 files changed, 45 insertions(+), 51 deletions(-) diff --git a/scripts/td_object_renderer/object_renderer_standalone/object_renderer_standalone/renderer_standalone.c b/scripts/td_object_renderer/object_renderer_standalone/object_renderer_standalone/renderer_standalone.c index 8afcd73603..3c98b8d688 100644 --- a/scripts/td_object_renderer/object_renderer_standalone/object_renderer_standalone/renderer_standalone.c +++ b/scripts/td_object_renderer/object_renderer_standalone/object_renderer_standalone/renderer_standalone.c @@ -310,12 +310,17 @@ int main( int argc, char *argv[] ) if ( f_quat_traj != NULL ) { + st_ivas->hDecoderConfig->Opt_Headrotation = 1; if ( ( st_ivas->hHeadTrackData = (HEAD_TRACK_DATA_HANDLE) count_malloc( sizeof( HEAD_TRACK_DATA ) ) ) == NULL ) { fprintf( stderr, "Can not allocate memory for head-tracking\n" ); exit( -1 ); } } + else + { + st_ivas->hDecoderConfig->Opt_Headrotation = 0; + } /* Init limiter */ st_ivas->hLimiter = ivas_limiter_open( nChannels, st_ivas->hDecoderConfig->output_Fs ); diff --git a/tests/renderer/constants.py b/tests/renderer/constants.py index 4ecb5f503c..b5d5cf3502 100644 --- a/tests/renderer/constants.py +++ b/tests/renderer/constants.py @@ -60,7 +60,7 @@ RENDERER_CMD = [ """ TD Object Renderer commandline template """ TDRENDERER_CMD = [ str( - TESTS_DIR.parent.joinpath("td_object_renderer") + SCRIPTS_DIR.joinpath("td_object_renderer") .joinpath("object_renderer_standalone") .joinpath("renderer_standalone") ), diff --git a/tests/renderer/test_renderer.py b/tests/renderer/test_renderer.py index e7a02408ce..e09dc37222 100644 --- a/tests/renderer/test_renderer.py +++ b/tests/renderer/test_renderer.py @@ -67,6 +67,10 @@ def check_BE( else: snr_min = np.inf + # TODO temporary fix to pad TD Object Renderer Standalone output + if ref.shape != cut.shape: + ref = np.pad(ref, [(0, cut.shape[0] - ref.shape[0]), (0, 0)]) + # check max_diff as well, since compare_audio_arrays will try to adjust for small delay differences if not np.allclose(ref, cut, rtol=0, atol=2) and max_diff > 2: if snr >= snr_min: @@ -203,7 +207,7 @@ def run_crend_unittest( in_name = in_fmt out_file = str( - OUTPUT_PATH_CUT.joinpath(f"{in_name}_to_{out_name}{trj_name}_crend.wav") + OUTPUT_PATH_REF.joinpath(f"{in_name}_to_{out_name}{trj_name}_crend.wav") ) cmd = RENDERER_CREND_CMD[:] @@ -258,7 +262,7 @@ def run_td_standalone( in_file = FORMAT_TO_FILE[in_fmt] in_name = in_fmt - out_file = str(OUTPUT_PATH_CUT.joinpath(f"{in_name}_to_{out_name}{trj_name}.pcm")) + out_file = str(OUTPUT_PATH_REF.joinpath(f"{in_name}_to_{out_name}{trj_name}.pcm")) in_spfmt = pyaudio3dtools.spatialaudioformat.Format(in_fmt) @@ -449,12 +453,11 @@ def test_ism_binaural_static(test_info, in_fmt, out_fmt): except: in_meta_files = None - ref, ref_fs = run_pyscripts(in_fmt, out_fmt, in_meta_files=in_meta_files) + if out_fmt == "BINAURAL": + ref, ref_fs = run_td_standalone(in_fmt, out_fmt, in_meta_files=in_meta_files) + else: + ref, ref_fs = run_pyscripts(in_fmt, out_fmt, in_meta_files=in_meta_files) - # if out_fmt == "BINAURAL": - # cut, cut_fs = run_td_standalone(in_fmt, out_fmt, in_meta_files=in_meta_files) - # else: - # cut, cut_fs = run_renderer(in_fmt, out_fmt, in_meta_files=in_meta_files) cut, cut_fs = run_renderer(in_fmt, out_fmt, in_meta_files=in_meta_files) check_BE(test_info, ref, ref_fs, cut, cut_fs) @@ -470,17 +473,15 @@ def test_multichannel_binaural_static(test_info, in_fmt, out_fmt): check_BE(test_info, ref, ref_fs, cut, cut_fs) -@pytest.mark.skip( - "Skip CREND unit test comparison until ASAN issues and copying binaries is fixed" -) +@pytest.mark.skip("Skip CREND unit test comparison until ASAN issues are fixed") @pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL) @pytest.mark.parametrize("in_fmt", INPUT_FORMATS_MC[2:]) def test_multichannel_binaural_static_vs_crend_unittest(test_info, in_fmt, out_fmt): - cut, cut_fs = run_renderer(in_fmt, out_fmt) - crend, crend_fs = run_crend_unittest(in_fmt, out_fmt) + cut, cut_fs = run_renderer(in_fmt, out_fmt) + check_BE(test_info, cut, cut_fs, crend, crend_fs) @@ -513,27 +514,20 @@ def test_ism_binaural_headrotation(test_info, in_fmt, out_fmt, trj_file): except: in_meta_files = None - ref, ref_fs = run_pyscripts( - in_fmt, - out_fmt, - trj_file=HR_TRAJECTORY_DIR.joinpath(f"{trj_file}.csv"), - in_meta_files=in_meta_files, - ) - - # if out_fmt == "BINAURAL": - # cut, cut_fs = run_td_standalone( - # in_fmt, - # out_fmt, - # trj_file=HR_TRAJECTORY_DIR.joinpath(f"{trj_file}.csv"), - # in_meta_files=in_meta_files, - # ) - # else: - # cut, cut_fs = run_renderer( - # in_fmt, - # out_fmt, - # trj_file=HR_TRAJECTORY_DIR.joinpath(f"{trj_file}.csv"), - # in_meta_files=in_meta_files, - # ) + if out_fmt == "BINAURAL": + ref, ref_fs = run_td_standalone( + in_fmt, + out_fmt, + trj_file=HR_TRAJECTORY_DIR.joinpath(f"{trj_file}.csv"), + in_meta_files=in_meta_files, + ) + else: + ref, ref_fs = run_pyscripts( + in_fmt, + out_fmt, + trj_file=HR_TRAJECTORY_DIR.joinpath(f"{trj_file}.csv"), + in_meta_files=in_meta_files, + ) cut, cut_fs = run_renderer( in_fmt, @@ -549,24 +543,19 @@ def test_ism_binaural_headrotation(test_info, in_fmt, out_fmt, trj_file): @pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL) @pytest.mark.parametrize("in_fmt", INPUT_FORMATS_MC[2:]) def test_multichannel_binaural_headrotation(test_info, in_fmt, out_fmt, trj_file): - ref, ref_fs = run_pyscripts( - in_fmt, - out_fmt, - trj_file=HR_TRAJECTORY_DIR.joinpath(f"{trj_file}.csv"), - ) - # if (in_fmt == "5_1" or in_fmt == "7_1") and out_fmt == "BINAURAL": - # cut, cut_fs = run_td_standalone( - # in_fmt, - # out_fmt, - # trj_file=HR_TRAJECTORY_DIR.joinpath(f"{trj_file}.csv"), - # ) - # else: - # cut, cut_fs = run_renderer( - # in_fmt, - # out_fmt, - # trj_file=HR_TRAJECTORY_DIR.joinpath(f"{trj_file}.csv"), - # ) + if (in_fmt == "5_1" or in_fmt == "7_1") and out_fmt == "BINAURAL": + ref, ref_fs = run_td_standalone( + in_fmt, + out_fmt, + trj_file=HR_TRAJECTORY_DIR.joinpath(f"{trj_file}.csv"), + ) + else: + ref, ref_fs = run_pyscripts( + in_fmt, + out_fmt, + trj_file=HR_TRAJECTORY_DIR.joinpath(f"{trj_file}.csv"), + ) cut, cut_fs = run_renderer( in_fmt, -- GitLab From 78314c3efa03ff73c7b47f8e236fb4abfa2539c5 Mon Sep 17 00:00:00 2001 From: Archit Tamarapu Date: Thu, 27 Oct 2022 11:08:22 +0200 Subject: [PATCH 055/101] remove masaRenderer related files to avoid clutter --- scripts/deco.bin | 3 --- scripts/eigen_to_foa_cldfb_domain_filters.bin | 3 --- scripts/eigen_to_hoa2_cldfb_domain_filters.bin | 3 --- scripts/hrir.bin | 0 scripts/sector_filters.bin | 3 --- scripts/vbap_51_table.bin | 3 --- scripts/vbap_714_table.bin | 3 --- scripts/vbap_bin_table.bin | 3 --- 8 files changed, 21 deletions(-) delete mode 100644 scripts/deco.bin delete mode 100644 scripts/eigen_to_foa_cldfb_domain_filters.bin delete mode 100644 scripts/eigen_to_hoa2_cldfb_domain_filters.bin delete mode 100644 scripts/hrir.bin delete mode 100644 scripts/sector_filters.bin delete mode 100644 scripts/vbap_51_table.bin delete mode 100644 scripts/vbap_714_table.bin delete mode 100644 scripts/vbap_bin_table.bin diff --git a/scripts/deco.bin b/scripts/deco.bin deleted file mode 100644 index 3ea11b0fad..0000000000 --- a/scripts/deco.bin +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c24505426ee0d7f5eb019af6d918647eebb363dd96a45ae50be65a4aa2f809c0 -size 229376 diff --git a/scripts/eigen_to_foa_cldfb_domain_filters.bin b/scripts/eigen_to_foa_cldfb_domain_filters.bin deleted file mode 100644 index 3a9d67c0c7..0000000000 --- a/scripts/eigen_to_foa_cldfb_domain_filters.bin +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:3c3ebc3d9e031d2d640a32639132771da974874686a378fb323645b9dbb553fe -size 61440 diff --git a/scripts/eigen_to_hoa2_cldfb_domain_filters.bin b/scripts/eigen_to_hoa2_cldfb_domain_filters.bin deleted file mode 100644 index 4c586da3d5..0000000000 --- a/scripts/eigen_to_hoa2_cldfb_domain_filters.bin +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c9097ecbf3b26b814abe141edadc701f1ffec5a141f2becc746926d6d32a7e58 -size 138240 diff --git a/scripts/hrir.bin b/scripts/hrir.bin deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/scripts/sector_filters.bin b/scripts/sector_filters.bin deleted file mode 100644 index 88adf401ba..0000000000 --- a/scripts/sector_filters.bin +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c4ff3f7d925b868aa98e366318c1bb2530ad9738ff53a187dafa5dcebcf3ec68 -size 288 diff --git a/scripts/vbap_51_table.bin b/scripts/vbap_51_table.bin deleted file mode 100644 index 2477f1194a..0000000000 --- a/scripts/vbap_51_table.bin +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d5182e9d0d86d47871e34d8a2821ebef94d8f25d08c51cd0bd618d66a59e4fab -size 3620 diff --git a/scripts/vbap_714_table.bin b/scripts/vbap_714_table.bin deleted file mode 100644 index 1541c1fdee..0000000000 --- a/scripts/vbap_714_table.bin +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ac34d9a81d62ac12094aab948047650017019377059fdf425614ef9f345954f7 -size 294668 diff --git a/scripts/vbap_bin_table.bin b/scripts/vbap_bin_table.bin deleted file mode 100644 index 1bf371c9c5..0000000000 --- a/scripts/vbap_bin_table.bin +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ab7bfe8d1c01359213362e8dcce21f42b50c07ed7f7a4a8ff972f516283df027 -size 428608 -- GitLab From 934afe5f99736cb0bd45dc9c6174dbe4719c2b64 Mon Sep 17 00:00:00 2001 From: Kacper Sagnowski Date: Thu, 27 Oct 2022 11:56:01 +0200 Subject: [PATCH 056/101] Add standalone TD renderer to CMake build --- CMakeLists.txt | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8e9237dcd8..006940791d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -152,11 +152,14 @@ file(GLOB libUtilSrcs "lib_util/*.c") file(GLOB libUtilHeaders "lib_util/*.h") add_library(lib_util ${libUtilSrcs} ${libUtilHeaders}) -file(GLOB libCRendSrcs "scripts/ivas_pytests/tests/unit_tests/crend/*.c") -file(GLOB libCRendHeaders "scripts/ivas_pytests/tests/unit_tests/crend/*.h") -add_executable(IVAS_crend_unit_test ${libCRendSrcs} ${libCRendHeaders}) +file(GLOB unitTestCRendSrcs "scripts/ivas_pytests/tests/unit_tests/crend/*.c") +file(GLOB unitTestCRendHeaders "scripts/ivas_pytests/tests/unit_tests/crend/*.h") +add_executable(IVAS_crend_unit_test ${unitTestCRendSrcs} ${unitTestCRendHeaders}) target_link_libraries(IVAS_crend_unit_test lib_rend lib_dec lib_util lib_com lib_debug) +add_executable(renderer_standalone "scripts/td_object_renderer/object_renderer_standalone/object_renderer_standalone/renderer_standalone.c") +target_link_libraries(renderer_standalone lib_rend lib_dec lib_util lib_com lib_debug) + add_executable(IVAS_cod apps/encoder.c) target_link_libraries(IVAS_cod lib_enc lib_util) if(WIN32) @@ -173,9 +176,10 @@ add_executable(IVAS_rend apps/renderer.c) target_link_libraries(IVAS_rend lib_rend lib_util) if(COPY_EXECUTABLES_FROM_BUILD_DIR) - # Optionally copy executables to root directory after build + # 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}/") add_custom_command(TARGET IVAS_crend_unit_test POST_BUILD VERBATIM COMMAND "${CMAKE_COMMAND}" -E copy "$" "${CMAKE_CURRENT_SOURCE_DIR}/scripts/ivas_pytests/tests/unit_tests/crend/") + add_custom_command(TARGET renderer_standalone POST_BUILD VERBATIM COMMAND "${CMAKE_COMMAND}" -E copy "$" "${CMAKE_CURRENT_SOURCE_DIR}/scripts/td_object_renderer/object_renderer_standalone/") endif() -- GitLab From 76b5671da7644b59f6bceac809e8fcbd9d52281c Mon Sep 17 00:00:00 2001 From: Kacper Sagnowski Date: Thu, 27 Oct 2022 12:23:05 +0200 Subject: [PATCH 057/101] Add missing build of standalone TD renderer in ext renderer Make job --- .gitlab-ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index a98fefea44..df216642fe 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -319,6 +319,7 @@ external-renderer-make-pytest: script: - make -j IVAS_rend - make -j unittests + - make -j --directory scripts/td_object_renderer/object_renderer_standalone - python3 -m pytest tests/renderer/test_renderer.py -q --log-level ERROR -n auto -rA # test external renderer executable with cmake + asan -- GitLab From af202945e86b23266b862c747e48d999bc61dc05 Mon Sep 17 00:00:00 2001 From: Remco Stoutjesdijk Date: Thu, 27 Oct 2022 12:48:10 +0200 Subject: [PATCH 058/101] interim commit to check changes on FhG branch --- lib_rend/ivas_crend.c | 20 +++++++++++--------- lib_rend/ivas_lib_rend_internal.h | 2 ++ lib_rend/lib_rend.c | 2 ++ 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/lib_rend/ivas_crend.c b/lib_rend/ivas_crend.c index bec08cbbaf..defdbae74b 100644 --- a/lib_rend/ivas_crend.c +++ b/lib_rend/ivas_crend.c @@ -30,6 +30,7 @@ *******************************************************************************************************/ +#include "common_api_types.h" #include #include #include "options.h" @@ -1148,6 +1149,7 @@ ivas_error ivas_rend_openCrend( CREND_WRAPPER *pCrend, IVAS_REND_AudioConfig inConfig, IVAS_REND_AudioConfig outConfig, + //IVAS_RENDER_CONFIG_HANDLE hRendererConfig, int32_t output_Fs ) { /* TODO tmu : Based on ivas_crend_open() - could be harmonized / refactored */ @@ -1277,14 +1279,14 @@ ivas_error ivas_rend_openCrend( } /* TODO tmu : implement renderConfig */ - // if ( ( ( st_ivas->hRenderConfig != NULL ) && st_ivas->hRenderConfig->roomAcoustics.late_reverb_on ) ) - // { - // if ( ( error = ivas_reverb_open( &( hCrend->hReverb ), st_ivas->intern_config, hHrtf, st_ivas->hRenderConfig, st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK ) - // { - // return error; - // } - // } - // else + //if ( ( ( hRendererConfig != NULL ) && hRendererConfig->room_acoustics.late_reverb_on ) ) + //{ + // //if ( ( error = ivas_reverb_open( &( hCrend->hReverb ), st_ivas->intern_config, hHrtf, st_ivas->hRenderConfig, st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK ) + // { + // return error; + // } + //} + //else { hCrend->hReverb = NULL; } @@ -1760,7 +1762,7 @@ ivas_error ivas_rend_closeCrend( } /*-----------------------------------------------------------------------------------------* - * Function ivas_crend_process() + * Function ivas_rend_crend_process() * * Process call for IVAS Crend renderer *-----------------------------------------------------------------------------------------*/ diff --git a/lib_rend/ivas_lib_rend_internal.h b/lib_rend/ivas_lib_rend_internal.h index e82348484f..339131c811 100644 --- a/lib_rend/ivas_lib_rend_internal.h +++ b/lib_rend/ivas_lib_rend_internal.h @@ -1,3 +1,4 @@ +#include "common_api_types.h" #include "ivas_error.h" #include "lib_rend.h" #include "ivas_stat_dec.h" @@ -40,6 +41,7 @@ ivas_error ivas_rend_openCrend( CREND_WRAPPER *pCrend, IVAS_REND_AudioConfig inConfig, IVAS_REND_AudioConfig outConfig, +// IVAS_RENDER_CONFIG_HANDLE hRendererConfig, int32_t output_Fs ); ivas_error ivas_rend_initCrend( diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index 98fe8fdb1f..6a803b1cd1 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -148,6 +148,7 @@ struct IVAS_REND input_mc inputsMc[RENDERER_MAX_MC_INPUTS]; input_sba inputsSba[RENDERER_MAX_SBA_INPUTS]; + IVAS_REND_AudioConfig inputConfig; IVAS_REND_AudioConfig outputConfig; EFAP_WRAPPER efapOutWrapper; IVAS_LSSETUP_CUSTOM_STRUCT customLsOut; @@ -3751,6 +3752,7 @@ static ivas_error renderActiveInputsMc( /* Skip inactive inputs */ continue; } + if ( ( error = renderInputMc( pCurrentInput, hIvasRend->outputConfig, outAudio ) ) != IVAS_ERR_OK ) -- GitLab From 910d40c3732f4e2a927d2f1722c9ec1e8372dbd1 Mon Sep 17 00:00:00 2001 From: Archit Tamarapu Date: Thu, 27 Oct 2022 13:51:36 +0200 Subject: [PATCH 059/101] add wmops_sub_start/end() to rendering functions --- lib_rend/lib_rend.c | 62 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index 6ff1a683c3..d6da36371d 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -2767,6 +2767,8 @@ static ivas_error rotateFrameMc( rotation_gains gains; float tmp_gains[MAX_INPUT_CHANNELS]; + wmops_sub_start("rotateFrameMc"); + if ( inConfig != IVAS_REND_AUDIO_CONFIG_LS_CUSTOM ) { getAudioConfigNumChannels( inConfig, &nchan ); @@ -2865,6 +2867,8 @@ static ivas_error rotateFrameMc( } } + wmops_sub_end(); + return IVAS_ERR_OK; } @@ -2886,6 +2890,8 @@ static ivas_error rotateFrameSba( float tmpRot[2 * HEADROT_ORDER + 1]; rotation_gains gains; + wmops_sub_start("rotateFrameSba"); + getAmbisonicsOrder( inConfig, &shd_rot_max_order ); /* subframe loop */ @@ -2960,6 +2966,7 @@ static ivas_error rotateFrameSba( } } + wmops_sub_end(); return IVAS_ERR_OK; } @@ -2972,6 +2979,8 @@ static ivas_error renderIsmToBinaural( ivas_error error; + wmops_sub_start("renderIsmToBinaural"); + copyBufferTo2dArray( ismInput->base.inputBuffer, tmpTDRendBuffer ); /* TODO tmu : missing: interpolation between positions, 5ms rendering */ @@ -2989,6 +2998,8 @@ static ivas_error renderIsmToBinaural( accumulate2dArrayToBuffer( tmpTDRendBuffer, &outAudio ); + wmops_sub_end(); + return IVAS_ERR_OK; } @@ -3011,6 +3022,8 @@ static ivas_error renderIsmToBinauralRoom( IVAS_REND_AudioObjectPosition rotatedPos; const IVAS_REND_HeadRotData *headRotData; + wmops_sub_start("renderIsmToBinauralRoom"); + headRotData = ismInput->base.ctx.pHeadRotData; rotatedPos = defaultObjectPosition(); @@ -3103,6 +3116,8 @@ static ivas_error renderIsmToBinauralRoom( count_free( tmpMcBuffer.data ); + wmops_sub_end(); + return IVAS_ERR_OK; } @@ -3114,6 +3129,8 @@ static ivas_error renderIsmToMc( pan_vector previousPanGains; ivas_error error; + wmops_sub_start("renderIsmToMc"); + /* TODO(sgi): Possible optimization: less processing needed if position didn't change */ if ( ( error = getEfapGains( *ismInput->base.ctx.pEfapOutWrapper, ismInput->currentPos.azimuth, @@ -3138,6 +3155,8 @@ static ivas_error renderIsmToMc( previousPanGains, outAudio ); + wmops_sub_end(); + return IVAS_ERR_OK; } @@ -3153,6 +3172,8 @@ static ivas_error renderIsmToSba( ivas_error error; error = IVAS_ERR_OK; + wmops_sub_start("renderIsmToSba"); + if ( ( error = getAudioConfigNumChannels( outConfig, &numOutChannels ) ) != IVAS_ERR_OK ) { return error; @@ -3188,6 +3209,8 @@ static ivas_error renderIsmToSba( previousPanGains, outAudio ); + wmops_sub_end(); + return error; } @@ -3285,6 +3308,8 @@ static ivas_error renderLfeToBinaural( assert( ( outAudio.config.numChannels == 2 ) && "Must be binaural output" ); + wmops_sub_start("renderLfeToBinaural"); + gain = GAIN_LFE; if ( mcInput->base.inConfig != IVAS_REND_AUDIO_CONFIG_LS_CUSTOM ) @@ -3316,6 +3341,8 @@ static ivas_error renderLfeToBinaural( *writePtr++ += gain * ( *readPtr++ ); } + wmops_sub_end(); + return IVAS_ERR_OK; } @@ -3331,6 +3358,8 @@ static ivas_error renderMcToBinaural( ivas_error error; IVAS_REND_AudioBuffer tmpRotBuffer; + wmops_sub_start("renderMcToBinaural"); + headRotEnabled = mcInput->base.ctx.pHeadRotData->headRotEnabled; inConfig = mcInput->base.inConfig; @@ -3392,6 +3421,7 @@ static ivas_error renderMcToBinaural( /* TODO tmu : needs delay compensation */ renderLfeToBinaural( mcInput, outAudio ); + wmops_sub_end(); return IVAS_ERR_OK; } @@ -3406,6 +3436,8 @@ static ivas_error renderMcToBinauralRoom( ivas_error error; IVAS_REND_AudioBuffer tmpRotBuffer; + wmops_sub_start("renderMcToBinauralRoom"); + /* apply rotation */ if ( mcInput->base.ctx.pHeadRotData->headRotEnabled ) { @@ -3445,6 +3477,8 @@ static ivas_error renderMcToBinauralRoom( /* TODO tmu : needs delay compensation */ renderLfeToBinaural( mcInput, outAudio ); + wmops_sub_end(); + return IVAS_ERR_OK; } @@ -3463,6 +3497,8 @@ static ivas_error renderMcCustomLsToBinauralRoom( IVAS_REND_AudioBuffer tmpMcBuffer; IVAS_REND_AudioBuffer *tmpBufPtr; + wmops_sub_start("renderMcCustomLsToBinauralRoom"); + headRotEnabled = mcInput->base.ctx.pHeadRotData->headRotEnabled; /* apply rotation */ @@ -3519,6 +3555,8 @@ static ivas_error renderMcCustomLsToBinauralRoom( } count_free( tmpMcBuffer.data ); + wmops_sub_end(); + return IVAS_ERR_OK; } @@ -3529,6 +3567,8 @@ static ivas_error renderMcToMc( int32_t i; IVAS_REND_AudioBuffer inAudio; + wmops_sub_start("renderMcToMc"); + inAudio = mcInput->base.inputBuffer; for ( i = 0; i < inAudio.config.numChannels; ++i ) @@ -3536,6 +3576,8 @@ static ivas_error renderMcToMc( renderBufferChannel( inAudio, i, mcInput->panGains[i], outAudio ); } + wmops_sub_end(); + return IVAS_ERR_OK; } @@ -3546,6 +3588,8 @@ static ivas_error renderMcToSba( int32_t i; IVAS_REND_AudioBuffer inAudio; + wmops_sub_start("renderMcToSba"); + inAudio = mcInput->base.inputBuffer; for ( i = 0; i < inAudio.config.numChannels; ++i ) @@ -3553,6 +3597,8 @@ static ivas_error renderMcToSba( renderBufferChannel( inAudio, i, mcInput->panGains[i], outAudio ); } + wmops_sub_end(); + return IVAS_ERR_OK; } @@ -3652,6 +3698,8 @@ static ivas_error renderSbaToMc( int32_t i; IVAS_REND_AudioBuffer inAudio; + wmops_sub_start("renderSbaToMc"); + inAudio = sbaInput->base.inputBuffer; for ( i = 0; i < inAudio.config.numChannels; ++i ) @@ -3659,6 +3707,8 @@ static ivas_error renderSbaToMc( renderBufferChannel( inAudio, i, sbaInput->hoaDecMtx[i], outAudio ); } + wmops_sub_end(); + return IVAS_ERR_OK; } @@ -3669,6 +3719,8 @@ static ivas_error renderSbaToSba( int32_t i; IVAS_REND_AudioBuffer inAudio; + wmops_sub_start("renderSbaToSba"); + inAudio = sbaInput->base.inputBuffer; for ( i = 0; i < inAudio.config.numChannels; ++i ) @@ -3676,6 +3728,8 @@ static ivas_error renderSbaToSba( renderBufferChannel( inAudio, i, sbaInput->hoaDecMtx[i], outAudio ); } + wmops_sub_end(); + return IVAS_ERR_OK; } @@ -3689,6 +3743,8 @@ static ivas_error renderSbaToBinaural( ivas_error error; IVAS_REND_AudioBuffer tmpRotBuffer; + wmops_sub_start("renderSbaToBinaural"); + /* apply rotation */ if ( sbaInput->base.ctx.pHeadRotData->headRotEnabled ) { @@ -3724,6 +3780,8 @@ static ivas_error renderSbaToBinaural( accumulate2dArrayToBuffer( tmpCrendBuffer, &outAudio ); + wmops_sub_end(); + return IVAS_ERR_OK; } @@ -3742,6 +3800,8 @@ static ivas_error renderSbaToBinauralRoom( IVAS_REND_AudioBuffer tmpMcBuffer; IVAS_REND_AudioBuffer *tmpBufPtr; + wmops_sub_start("renderSbaToBinauralRoom"); + headRotEnabled = sbaInput->base.ctx.pHeadRotData->headRotEnabled; /* apply rotation */ @@ -3797,6 +3857,8 @@ static ivas_error renderSbaToBinauralRoom( } count_free( tmpMcBuffer.data ); + wmops_sub_end(); + return IVAS_ERR_OK; } -- GitLab From 7182b13c9dd4650967d6d21c0a17e0e58573503c Mon Sep 17 00:00:00 2001 From: Remco Stoutjesdijk Date: Fri, 28 Oct 2022 01:09:44 +0200 Subject: [PATCH 060/101] wired up renderconfig to ivas_rend_openCrend and children --- apps/renderer.c | 72 +++++++++++++++---------------- lib_dec/ivas_stat_dec.h | 1 - lib_rend/ivas_crend.c | 31 +++++++------ lib_rend/ivas_lib_rend_internal.h | 3 +- lib_rend/lib_rend.c | 31 ++++++++----- 5 files changed, 75 insertions(+), 63 deletions(-) diff --git a/apps/renderer.c b/apps/renderer.c index b6d51ce43c..22311cfa96 100644 --- a/apps/renderer.c +++ b/apps/renderer.c @@ -501,6 +501,42 @@ int32_t main( int32_t argc, char **argv ) exit( -1 ); } + /* === Configure === */ + if ( ( error = IVAS_REND_ConfigureConfig( hIvasRend, args.trajectoryFile[0] != '\0', args.renderConfigFile[0] != '\0' ) ) != IVAS_ERR_OK ) + { + exit( -1 ); + } + + if ( args.renderConfigFile[0] != '\0' ) + { + IVAS_RENDER_CONFIG_DATA renderConfig; + + /* sanity check */ + if ( args.outConfig.audioConfig != IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM ) + { + fprintf( stderr, "\nExternal Renderer Config is supported only when BINAURAL_ROOM is used as output. Exiting. \n" ); + exit( -1 ); // goto cleanup; + } + + if ( ( error = IVAS_REND_GetRenderConfig( hIvasRend, &renderConfig ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nIVAS_DEC_GetRenderConfig failed\n" ); + exit( -1 ); // goto cleanup; + } + + if ( RenderConfigReader_read( renderConfigReader, &renderConfig ) != IVAS_ERR_OK ) + { + fprintf( stderr, "Failed to read renderer configuration from file %s\n", args.renderConfigFile ); + exit( -1 ); // goto cleanup; + } + + if ( ( error = IVAS_REND_FeedRenderConfig( hIvasRend, renderConfig ) ) != IVAS_ERR_OK ) + { + fprintf( stderr, "\nIVAS_DEC_FeedRenderConfig failed\n" ); + exit( -1 ); // goto cleanup; + } + } + /* Set up output custom layout configuration */ if ( args.outConfig.audioConfig == IVAS_REND_AUDIO_CONFIG_LS_CUSTOM ) { @@ -589,42 +625,6 @@ int32_t main( int32_t argc, char **argv ) hMasaMetadata = MasaFileReader_getMetadataHandle( masaReader ); } - /* === Configure === */ - if ( ( error = IVAS_REND_ConfigureConfig( hIvasRend, args.trajectoryFile[0] != '\0', args.renderConfigFile[0] != '\0' ) ) != IVAS_ERR_OK ) - { - exit( -1 ); - } - - if ( args.renderConfigFile[0] != '\0' ) - { - IVAS_RENDER_CONFIG_DATA renderConfig; - - /* sanity check */ - if ( args.outConfig.audioConfig != IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM ) - { - fprintf( stderr, "\nExternal Renderer Config is supported only when BINAURAL_ROOM is used as output. Exiting. \n" ); - exit( -1 ); // goto cleanup; - } - - if ( ( error = IVAS_REND_GetRenderConfig( hIvasRend, &renderConfig ) ) != IVAS_ERR_OK ) - { - fprintf( stderr, "\nIVAS_DEC_GetRenderConfig failed\n" ); - exit( -1 ); // goto cleanup; - } - - if ( RenderConfigReader_read( renderConfigReader, &renderConfig ) != IVAS_ERR_OK ) - { - fprintf( stderr, "Failed to read renderer configuration from file %s\n", args.renderConfigFile ); - exit( -1 ); // goto cleanup; - } - - if ( ( error = IVAS_REND_FeedRenderConfig( hIvasRend, renderConfig ) ) != IVAS_ERR_OK ) - { - fprintf( stderr, "\nIVAS_DEC_FeedRenderConfig failed\n" ); - exit( -1 ); // goto cleanup; - } - } - int32_t numOutChannels; if ( ( error = IVAS_REND_NumOutChannels( hIvasRend, &numOutChannels ) ) != IVAS_ERR_OK ) { diff --git a/lib_dec/ivas_stat_dec.h b/lib_dec/ivas_stat_dec.h index 2284f9d09d..42354c201d 100644 --- a/lib_dec/ivas_stat_dec.h +++ b/lib_dec/ivas_stat_dec.h @@ -1658,7 +1658,6 @@ typedef struct ivas_hrtfs_structure /* Reverberator structures */ - typedef struct ivas_roomAcoustics_t { int16_t override; diff --git a/lib_rend/ivas_crend.c b/lib_rend/ivas_crend.c index defdbae74b..924997f008 100644 --- a/lib_rend/ivas_crend.c +++ b/lib_rend/ivas_crend.c @@ -1149,7 +1149,7 @@ ivas_error ivas_rend_openCrend( CREND_WRAPPER *pCrend, IVAS_REND_AudioConfig inConfig, IVAS_REND_AudioConfig outConfig, - //IVAS_RENDER_CONFIG_HANDLE hRendererConfig, + RENDER_CONFIG_DATA *hRend, int32_t output_Fs ) { /* TODO tmu : Based on ivas_crend_open() - could be harmonized / refactored */ @@ -1164,7 +1164,7 @@ ivas_error ivas_rend_openCrend( if ( pCrend->hHrtfCrend == NULL ) { - if ( ( error = ivas_rend_initCrend( pCrend, inConfig, outConfig, output_Fs ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_rend_initCrend( pCrend, inConfig, outConfig, hRend, output_Fs ) ) != IVAS_ERR_OK ) { return error; } @@ -1278,15 +1278,19 @@ ivas_error ivas_rend_openCrend( hCrend->hTrack = NULL; } - /* TODO tmu : implement renderConfig */ - //if ( ( ( hRendererConfig != NULL ) && hRendererConfig->room_acoustics.late_reverb_on ) ) - //{ - // //if ( ( error = ivas_reverb_open( &( hCrend->hReverb ), st_ivas->intern_config, hHrtf, st_ivas->hRenderConfig, st_ivas->hDecoderConfig->output_Fs ) ) != IVAS_ERR_OK ) - // { - // return error; - // } - //} - //else + if ( ( hRend != NULL ) && (hRend->roomAcoustics.late_reverb_on ) ) + { + if ( ( error = ivas_reverb_open( &(hCrend->hReverb), + getIvasAudioConfigFromRendAudioConfig( inConfig ), + pCrend->hHrtfCrend, + hRend, + output_Fs + ) ) != IVAS_ERR_OK ) + { + return error; + } + } + else { hCrend->hReverb = NULL; } @@ -1308,6 +1312,7 @@ ivas_error ivas_rend_initCrend( CREND_WRAPPER *pCrend, IVAS_REND_AudioConfig inConfig, IVAS_REND_AudioConfig outConfig, + RENDER_CONFIG_DATA *hRend, int32_t output_Fs ) { int16_t i, j, tmp; @@ -1339,9 +1344,7 @@ ivas_error ivas_rend_initCrend( /* set BRIR flag */ use_brir = false; - /* TODO tmu : pass down render config handle */ - // if ((pCrend->hRenderConfig != NULL && pCrend->hRenderConfig->roomAcoustics.use_brir) || outConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM ) - if ( outConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM ) + if ( (hRend != NULL && hRend->roomAcoustics.use_brir ) || outConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM ) { use_brir = true; } diff --git a/lib_rend/ivas_lib_rend_internal.h b/lib_rend/ivas_lib_rend_internal.h index 339131c811..0628e4d4b0 100644 --- a/lib_rend/ivas_lib_rend_internal.h +++ b/lib_rend/ivas_lib_rend_internal.h @@ -41,13 +41,14 @@ ivas_error ivas_rend_openCrend( CREND_WRAPPER *pCrend, IVAS_REND_AudioConfig inConfig, IVAS_REND_AudioConfig outConfig, -// IVAS_RENDER_CONFIG_HANDLE hRendererConfig, + RENDER_CONFIG_DATA *hRend, int32_t output_Fs ); ivas_error ivas_rend_initCrend( CREND_WRAPPER *pCrend, IVAS_REND_AudioConfig inConfig, IVAS_REND_AudioConfig outConfig, + RENDER_CONFIG_DATA *hRend, int32_t output_Fs ); ivas_error ivas_rend_closeCrend( diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index 6a803b1cd1..1da589469f 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -887,7 +887,8 @@ static CREND_WRAPPER defaultCrendWrapper( void ) static ivas_error setRendInputActiveIsm( void *input, IVAS_REND_AudioConfig inConfig, - IVAS_REND_InputId id ) + IVAS_REND_InputId id, + RENDER_CONFIG_DATA *hRend ) { ivas_error error; rendering_context rendCtx; @@ -919,6 +920,7 @@ static ivas_error setRendInputActiveIsm( error = ivas_rend_openCrend( &inputIsm->crendWrapper, IVAS_REND_AUDIO_CONFIG_7_1_4, outConfig, + hRend, *rendCtx.pOutSampleRate ); } if ( error != IVAS_ERR_OK ) @@ -1428,7 +1430,8 @@ static void tmpFixBuggyTdBinRendInit( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRen static ivas_error initMcBinauralRendering( input_mc *inputMc, IVAS_REND_AudioConfig inConfig, - IVAS_REND_AudioConfig outConfig ) + IVAS_REND_AudioConfig outConfig, + RENDER_CONFIG_DATA *hRend ) { ivas_error error; int32_t outSampleRate; @@ -1480,6 +1483,7 @@ static ivas_error initMcBinauralRendering( if ( ( error = ivas_rend_openCrend( &inputMc->crendWrapper, ( inConfig == IVAS_REND_AUDIO_CONFIG_LS_CUSTOM ) ? IVAS_REND_AUDIO_CONFIG_7_1_4 : inConfig, outConfig, + hRend, outSampleRate ) ) != IVAS_ERR_OK ) { return error; @@ -1547,7 +1551,8 @@ static IVAS_REND_LfeRouting defaultLfeRouting( static ivas_error setRendInputActiveMc( void *input, IVAS_REND_AudioConfig inConfig, - IVAS_REND_InputId id ) + IVAS_REND_InputId id, + RENDER_CONFIG_DATA *hRend ) { ivas_error error; rendering_context rendCtx; @@ -1571,7 +1576,7 @@ static ivas_error setRendInputActiveMc( if ( outConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL || outConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM ) { - if ( ( error = initMcBinauralRendering( inputMc, inConfig, outConfig ) ) != IVAS_ERR_OK ) + if ( ( error = initMcBinauralRendering( inputMc, inConfig, outConfig, hRend ) ) != IVAS_ERR_OK ) { return error; } @@ -1695,7 +1700,7 @@ static ivas_error initSbaPanGainsForSbaOut( input_sba *inputSba, IVAS_REND_Audio return error; } -static ivas_error updateSbaPanGains( input_sba *inputSba, IVAS_REND_AudioConfig outConfig ) +static ivas_error updateSbaPanGains( input_sba *inputSba, IVAS_REND_AudioConfig outConfig, RENDER_CONFIG_DATA *hRend ) { ivas_error error; IVAS_REND_AudioConfig inConfig; @@ -1722,6 +1727,7 @@ static ivas_error updateSbaPanGains( input_sba *inputSba, IVAS_REND_AudioConfig error = ivas_rend_openCrend( &inputSba->crendWrapper, inConfig, outConfig, + hRend, *rendCtx.pOutSampleRate ); break; case IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM: @@ -1732,6 +1738,7 @@ static ivas_error updateSbaPanGains( input_sba *inputSba, IVAS_REND_AudioConfig error = ivas_rend_openCrend( &inputSba->crendWrapper, IVAS_REND_AUDIO_CONFIG_7_1_4, outConfig, + hRend, *rendCtx.pOutSampleRate ); break; default: @@ -1753,7 +1760,8 @@ static ivas_error updateSbaPanGains( input_sba *inputSba, IVAS_REND_AudioConfig static ivas_error setRendInputActiveSba( void *input, IVAS_REND_AudioConfig inConfig, - IVAS_REND_InputId id ) + IVAS_REND_InputId id, + RENDER_CONFIG_DATA *hRend ) { ivas_error error; rendering_context rendCtx; @@ -1769,7 +1777,7 @@ static ivas_error setRendInputActiveSba( inputSba->crendWrapper = defaultCrendWrapper(); initRotGains( inputSba->rot_gains_prev ); - if ( ( error = updateSbaPanGains( inputSba, outConfig ) ) != IVAS_ERR_OK ) + if ( ( error = updateSbaPanGains( inputSba, outConfig, hRend ) ) != IVAS_ERR_OK ) { return error; } @@ -2007,7 +2015,7 @@ ivas_error IVAS_REND_ConfigureCustomOutputLoudspeakerLayout( /* Input inactive, skip. */ continue; } - if ( ( error = updateSbaPanGains( inputSba, hIvasRend->outputConfig ) ) != IVAS_ERR_OK ) + if ( ( error = updateSbaPanGains( inputSba, hIvasRend->outputConfig, hIvasRend->hRendererConfig ) ) != IVAS_ERR_OK ) { return error; } @@ -2217,7 +2225,7 @@ ivas_error IVAS_REND_AddInput( int32_t maxNumInputsOfType; void *inputsArray; int32_t inputStructSize; - ivas_error ( *activateInput )( void *, IVAS_REND_AudioConfig, IVAS_REND_InputId ); + ivas_error ( *activateInput )( void *, IVAS_REND_AudioConfig, IVAS_REND_InputId, RENDER_CONFIG_DATA * ); int32_t inputIndex; /*-----------------------------------------------------------------* @@ -2266,7 +2274,8 @@ ivas_error IVAS_REND_AddInput( if ( ( error = activateInput( (uint8_t *) inputsArray + inputStructSize * inputIndex, inConfig, - *inputId ) ) != IVAS_ERR_OK ) + *inputId, + hIvasRend->hRendererConfig ) ) != IVAS_ERR_OK ) { return error; } @@ -2318,7 +2327,7 @@ ivas_error IVAS_REND_ConfigureCustomInputLoudspeakerLayout( if ( hIvasRend->outputConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL || hIvasRend->outputConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM ) { - if ( ( error = initMcBinauralRendering( inputMc, inputMc->base.inConfig, hIvasRend->outputConfig ) ) != IVAS_ERR_OK ) + if ( ( error = initMcBinauralRendering( inputMc, inputMc->base.inConfig, hIvasRend->outputConfig, hIvasRend->hRendererConfig ) ) != IVAS_ERR_OK ) { return error; } -- GitLab From 90c91a25789679ded398af249f615ce2efbc4637 Mon Sep 17 00:00:00 2001 From: Kacper Sagnowski Date: Fri, 28 Oct 2022 14:12:16 +0200 Subject: [PATCH 061/101] Add float dump for testing external vs internal rendering --- CMakeLists.txt | 3 +++ apps/renderer.c | 19 +++++++++++++++++++ lib_com/ivas_tools.c | 10 ++++++++++ 3 files changed, 32 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 006940791d..75dabe1d22 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -108,6 +108,9 @@ if(WMOPS) add_definitions("-DWMOPS=1") endif() +if(DEC_TO_REND_FLOAT_DUMP) + add_compile_definitions(DEC_TO_REND_FLOAT_DUMP) +endif() project(stereo-evs) set_property(GLOBAL PROPERTY USE_FOLDERS ON) # make Visual Studio projects look nicer diff --git a/apps/renderer.c b/apps/renderer.c index 5eb517740b..3fe9fcd89b 100644 --- a/apps/renderer.c +++ b/apps/renderer.c @@ -31,6 +31,7 @@ *******************************************************************************************************/ #include "options.h" +#include "debug.h" #include "audio_file_reader.h" #include "audio_file_writer.h" #include "cmdl_tools.h" @@ -750,6 +751,10 @@ int32_t main( int32_t argc, char **argv ) fprintf( stderr, "Failed to open file: %s\n", args.outputFilePath ); exit( -1 ); } +#ifdef DEC_TO_REND_FLOAT_DUMP + printf( "Warning: Renderer executable built with DEC_TO_REND_FLOAT_DUMP enabled!\n" ); + printf( " Float dump file (./float_out.wav) will be forced as input.\n" ); +#endif inBufferSize = frameSize_smpls * totalNumInChannels; outBufferSize = frameSize_smpls * numOutChannels; @@ -800,6 +805,20 @@ int32_t main( int32_t argc, char **argv ) /* Convert from int to float and from interleaved to packed */ convertInputBuffer( inpInt16Buffer, numSamplesRead, frameSize_smpls, num_in_channels, inFloatBuffer ); +#ifdef DEC_TO_REND_FLOAT_DUMP + /* Overwrite from dump file */ + float tmp[960 * 16]; + dbgread( tmp, sizeof( float ), numSamplesRead, "./float_out.raw" ); + + /* Conversion from interleaved to packed still necessary */ + for ( int32_t i = 0; i < numSamplesRead / num_in_channels; ++i ) + { + for ( int32_t c = 0; c < num_in_channels; ++c ) + { + inFloatBuffer[c * frameSize_smpls + i] = tmp[i * num_in_channels + c]; + } + } +#endif for ( int32_t i = 0; i < RENDERER_MAX_MASA_INPUTS; ++i ) { diff --git a/lib_com/ivas_tools.c b/lib_com/ivas_tools.c index 3c941ccc77..b8fbaa833f 100644 --- a/lib_com/ivas_tools.c +++ b/lib_com/ivas_tools.c @@ -144,6 +144,16 @@ uint32_t ivas_syn_output( } } +#ifdef DEC_TO_REND_FLOAT_DUMP + for ( i = 0; i < output_frame; ++i ) + { + for ( n = 0; n < n_channels; ++n ) + { + dbgwrite( &synth[n][i], sizeof( float ), 1, 1, "./float_out.raw" ); + } + } +#endif + return noClipping; } -- GitLab From 9ebeea99b817aeafac55cc440dc7839bd073b9d4 Mon Sep 17 00:00:00 2001 From: Archit Tamarapu Date: Fri, 28 Oct 2022 14:52:02 +0200 Subject: [PATCH 062/101] allow compiling the external renderer with EXT_RENDERER undefined --- apps/renderer.c | 10 ++++++++++ lib_rend/ivas_lib_rend_internal.h | 2 ++ lib_rend/lib_rend.c | 2 ++ lib_rend/lib_rend.h | 3 +++ 4 files changed, 17 insertions(+) diff --git a/apps/renderer.c b/apps/renderer.c index 3fe9fcd89b..95f18e993c 100644 --- a/apps/renderer.c +++ b/apps/renderer.c @@ -60,6 +60,7 @@ #include #include +#ifdef EXT_RENDERER #ifndef count_malloc #ifdef RAM_COUNTING_TOOL #define count_malloc( n1 ) MALLOC_FCT_CALL( n1 ) @@ -2274,3 +2275,12 @@ static void convertOutputBuffer( const float *floatBuffer, } } } +#else +int32_t main( int32_t argc, char **argv ) +{ + (void) argc; + (void) argv; + fprintf( stderr, "Enable EXT_RENDERER in options.h to use the external renderer.\n" ); + return 0; +} +#endif diff --git a/lib_rend/ivas_lib_rend_internal.h b/lib_rend/ivas_lib_rend_internal.h index e82348484f..9edfcc46a9 100644 --- a/lib_rend/ivas_lib_rend_internal.h +++ b/lib_rend/ivas_lib_rend_internal.h @@ -5,6 +5,7 @@ #ifndef IVAS_LIB_REND_INTERNALS_H #define IVAS_LIB_REND_INTERNALS_H +#ifdef EXT_RENDERER typedef struct { int8_t headRotEnabled; @@ -85,3 +86,4 @@ ivas_error ivas_rend_TDObjRendOpen( int32_t outFs ); #endif +#endif diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index d6da36371d..2cb50d4507 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -48,6 +48,7 @@ #include #include +#ifdef EXT_RENDERER /* 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 ) @@ -4064,3 +4065,4 @@ int32_t IVAS_REND_GetCntFramesLimited( return hIvasRend->hLimiter->cnt_frames_limited; } #endif +#endif diff --git a/lib_rend/lib_rend.h b/lib_rend/lib_rend.h index 3be9ad9964..b9aad11e84 100644 --- a/lib_rend/lib_rend.h +++ b/lib_rend/lib_rend.h @@ -41,6 +41,8 @@ #include "common_api_types.h" #include "ivas_error.h" +#ifdef EXT_RENDERER + #define RENDERER_MAX_ISM_INPUTS 4 #define RENDERER_MAX_MC_INPUTS 1 #define RENDERER_MAX_SBA_INPUTS 1 @@ -263,3 +265,4 @@ int32_t IVAS_REND_GetCntFramesLimited( /* clang-format on */ #endif /* LIB_REND_H */ +#endif -- GitLab From c989e5df084115413d4cbbebdccef5383bd1a8c1 Mon Sep 17 00:00:00 2001 From: Remco Stoutjesdijk Date: Wed, 2 Nov 2022 15:30:19 +0100 Subject: [PATCH 063/101] remove redundant dependencies --- lib_rend/ivas_crend.c | 1 - lib_rend/ivas_lib_rend_internal.h | 1 - 2 files changed, 2 deletions(-) diff --git a/lib_rend/ivas_crend.c b/lib_rend/ivas_crend.c index 0f27efc55c..c87a61e44f 100644 --- a/lib_rend/ivas_crend.c +++ b/lib_rend/ivas_crend.c @@ -30,7 +30,6 @@ *******************************************************************************************************/ -#include "common_api_types.h" #include #include #include "options.h" diff --git a/lib_rend/ivas_lib_rend_internal.h b/lib_rend/ivas_lib_rend_internal.h index fb53d22a59..117d492d17 100644 --- a/lib_rend/ivas_lib_rend_internal.h +++ b/lib_rend/ivas_lib_rend_internal.h @@ -1,4 +1,3 @@ -#include "common_api_types.h" #include "ivas_error.h" #include "lib_rend.h" #include "ivas_stat_dec.h" -- GitLab From af9e776a708c36752c82ff08feabbc23b1705875 Mon Sep 17 00:00:00 2001 From: Remco Stoutjesdijk Date: Wed, 2 Nov 2022 22:33:33 +0100 Subject: [PATCH 064/101] added lib_rend_internal.h to MSVC project and added IVAS header --- Workspace_msvc/lib_rend.vcxproj | 1 + 1 file changed, 1 insertion(+) diff --git a/Workspace_msvc/lib_rend.vcxproj b/Workspace_msvc/lib_rend.vcxproj index e87baf5605..c3a1268694 100644 --- a/Workspace_msvc/lib_rend.vcxproj +++ b/Workspace_msvc/lib_rend.vcxproj @@ -229,6 +229,7 @@ + -- GitLab From c671ada28040bf84fcd42075662c50f60309192c Mon Sep 17 00:00:00 2001 From: Remco Stoutjesdijk Date: Wed, 2 Nov 2022 22:37:32 +0100 Subject: [PATCH 065/101] rename ConfigureConfig to InitConfig --- apps/renderer.c | 2 +- lib_rend/ivas_lib_rend_internal.h | 32 +++++++++++++++++++++++++++++++ lib_rend/lib_rend.c | 2 +- lib_rend/lib_rend.h | 2 +- 4 files changed, 35 insertions(+), 3 deletions(-) diff --git a/apps/renderer.c b/apps/renderer.c index 88a8aa88a4..e4d6bf36d0 100644 --- a/apps/renderer.c +++ b/apps/renderer.c @@ -665,7 +665,7 @@ int32_t main( int32_t argc, char **argv ) } /* === Configure === */ - if ( ( error = IVAS_REND_ConfigureConfig( hIvasRend, headRotReader != NULL, args.renderConfigFilePath[0] != '\0' ) ) != IVAS_ERR_OK ) + if ( ( error = IVAS_REND_InitConfig( hIvasRend, headRotReader != NULL, args.renderConfigFilePath[0] != '\0' ) ) != IVAS_ERR_OK ) { exit( -1 ); } diff --git a/lib_rend/ivas_lib_rend_internal.h b/lib_rend/ivas_lib_rend_internal.h index 117d492d17..773b75309b 100644 --- a/lib_rend/ivas_lib_rend_internal.h +++ b/lib_rend/ivas_lib_rend_internal.h @@ -1,3 +1,35 @@ +/****************************************************************************************************** + + (C) 2022 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_error.h" #include "lib_rend.h" #include "ivas_stat_dec.h" diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index e6ac1967ae..eea5a0c7ea 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -2640,7 +2640,7 @@ ivas_error IVAS_REND_FeedInputObjectMetadata( return IVAS_ERR_OK; } -ivas_error IVAS_REND_ConfigureConfig( IVAS_REND_HANDLE st, +ivas_error IVAS_REND_InitConfig( IVAS_REND_HANDLE st, bool headRotationEnabled, bool rendererConfigEnabled ) { diff --git a/lib_rend/lib_rend.h b/lib_rend/lib_rend.h index 7e3d07c0fd..924bc0e6fe 100644 --- a/lib_rend/lib_rend.h +++ b/lib_rend/lib_rend.h @@ -236,7 +236,7 @@ ivas_error IVAS_REND_FeedInputMasaMetadata( void* TODO ); -ivas_error IVAS_REND_ConfigureConfig( +ivas_error IVAS_REND_InitConfig( IVAS_REND_HANDLE st, /* i/o: Renderer handle */ bool headRotationEnabled, /* i : enable head rotation for binaural output, ignored for other output formats */ bool rendererConfigEnabled /* i : flag indicating if a renderer configuration file was supplied */ -- GitLab From 7a1aa576f8f9b55b914da57bb6264e508e4611d6 Mon Sep 17 00:00:00 2001 From: Remco Stoutjesdijk Date: Wed, 2 Nov 2022 22:41:25 +0100 Subject: [PATCH 066/101] renamed hRend to hRendCfg --- lib_rend/ivas_crend.c | 12 ++++++------ lib_rend/lib_rend.c | 22 +++++++++++----------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/lib_rend/ivas_crend.c b/lib_rend/ivas_crend.c index c87a61e44f..ae910b1f25 100644 --- a/lib_rend/ivas_crend.c +++ b/lib_rend/ivas_crend.c @@ -1148,7 +1148,7 @@ ivas_error ivas_rend_openCrend( CREND_WRAPPER *pCrend, IVAS_REND_AudioConfig inConfig, IVAS_REND_AudioConfig outConfig, - RENDER_CONFIG_DATA *hRend, + RENDER_CONFIG_DATA *hRendCfg, int32_t output_Fs ) { /* TODO tmu : Based on ivas_crend_open() - could be harmonized / refactored */ @@ -1163,7 +1163,7 @@ ivas_error ivas_rend_openCrend( if ( pCrend->hHrtfCrend == NULL ) { - if ( ( error = ivas_rend_initCrend( pCrend, inConfig, outConfig, hRend, output_Fs ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_rend_initCrend( pCrend, inConfig, outConfig, hRendCfg, output_Fs ) ) != IVAS_ERR_OK ) { return error; } @@ -1277,12 +1277,12 @@ ivas_error ivas_rend_openCrend( hCrend->hTrack = NULL; } - if ( ( hRend != NULL ) && (hRend->roomAcoustics.late_reverb_on ) ) + if ( ( hRendCfg != NULL ) && (hRendCfg->roomAcoustics.late_reverb_on ) ) { if ( ( error = ivas_reverb_open( &(hCrend->hReverb), getIvasAudioConfigFromRendAudioConfig( inConfig ), pCrend->hHrtfCrend, - hRend, + hRendCfg, output_Fs ) ) != IVAS_ERR_OK ) { @@ -1311,7 +1311,7 @@ ivas_error ivas_rend_initCrend( CREND_WRAPPER *pCrend, IVAS_REND_AudioConfig inConfig, IVAS_REND_AudioConfig outConfig, - RENDER_CONFIG_DATA *hRend, + RENDER_CONFIG_DATA *hRendCfg, int32_t output_Fs ) { int16_t i, j, tmp; @@ -1343,7 +1343,7 @@ ivas_error ivas_rend_initCrend( /* set BRIR flag */ use_brir = false; - if ( (hRend != NULL && hRend->roomAcoustics.use_brir ) || outConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM ) + if ( (hRendCfg != NULL && hRendCfg->roomAcoustics.use_brir ) || outConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM ) { use_brir = true; } diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index eea5a0c7ea..3a3fb1658b 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -886,7 +886,7 @@ static ivas_error setRendInputActiveIsm( void *input, IVAS_REND_AudioConfig inConfig, IVAS_REND_InputId id, - RENDER_CONFIG_DATA *hRend ) + RENDER_CONFIG_DATA *hRendCfg ) { ivas_error error; rendering_context rendCtx; @@ -918,7 +918,7 @@ static ivas_error setRendInputActiveIsm( error = ivas_rend_openCrend( &inputIsm->crendWrapper, IVAS_REND_AUDIO_CONFIG_7_1_4, outConfig, - hRend, + hRendCfg, *rendCtx.pOutSampleRate ); } if ( error != IVAS_ERR_OK ) @@ -1429,7 +1429,7 @@ static ivas_error initMcBinauralRendering( input_mc *inputMc, IVAS_REND_AudioConfig inConfig, IVAS_REND_AudioConfig outConfig, - RENDER_CONFIG_DATA *hRend ) + RENDER_CONFIG_DATA *hRendCfg ) { ivas_error error; int32_t outSampleRate; @@ -1481,7 +1481,7 @@ static ivas_error initMcBinauralRendering( if ( ( error = ivas_rend_openCrend( &inputMc->crendWrapper, ( inConfig == IVAS_REND_AUDIO_CONFIG_LS_CUSTOM ) ? IVAS_REND_AUDIO_CONFIG_7_1_4 : inConfig, outConfig, - hRend, + hRendCfg, outSampleRate ) ) != IVAS_ERR_OK ) { return error; @@ -1550,7 +1550,7 @@ static ivas_error setRendInputActiveMc( void *input, IVAS_REND_AudioConfig inConfig, IVAS_REND_InputId id, - RENDER_CONFIG_DATA *hRend ) + RENDER_CONFIG_DATA *hRendCfg ) { ivas_error error; rendering_context rendCtx; @@ -1574,7 +1574,7 @@ static ivas_error setRendInputActiveMc( if ( outConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL || outConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM ) { - if ( ( error = initMcBinauralRendering( inputMc, inConfig, outConfig, hRend ) ) != IVAS_ERR_OK ) + if ( ( error = initMcBinauralRendering( inputMc, inConfig, outConfig, hRendCfg ) ) != IVAS_ERR_OK ) { return error; } @@ -1698,7 +1698,7 @@ static ivas_error initSbaPanGainsForSbaOut( input_sba *inputSba, IVAS_REND_Audio return error; } -static ivas_error updateSbaPanGains( input_sba *inputSba, IVAS_REND_AudioConfig outConfig, RENDER_CONFIG_DATA *hRend ) +static ivas_error updateSbaPanGains( input_sba *inputSba, IVAS_REND_AudioConfig outConfig, RENDER_CONFIG_DATA *hRendCfg ) { ivas_error error; IVAS_REND_AudioConfig inConfig; @@ -1725,7 +1725,7 @@ static ivas_error updateSbaPanGains( input_sba *inputSba, IVAS_REND_AudioConfig error = ivas_rend_openCrend( &inputSba->crendWrapper, inConfig, outConfig, - hRend, + hRendCfg, *rendCtx.pOutSampleRate ); break; case IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM: @@ -1736,7 +1736,7 @@ static ivas_error updateSbaPanGains( input_sba *inputSba, IVAS_REND_AudioConfig error = ivas_rend_openCrend( &inputSba->crendWrapper, IVAS_REND_AUDIO_CONFIG_7_1_4, outConfig, - hRend, + hRendCfg, *rendCtx.pOutSampleRate ); break; default: @@ -1759,7 +1759,7 @@ static ivas_error setRendInputActiveSba( void *input, IVAS_REND_AudioConfig inConfig, IVAS_REND_InputId id, - RENDER_CONFIG_DATA *hRend ) + RENDER_CONFIG_DATA *hRendCfg ) { ivas_error error; rendering_context rendCtx; @@ -1775,7 +1775,7 @@ static ivas_error setRendInputActiveSba( inputSba->crendWrapper = defaultCrendWrapper(); initRotGains( inputSba->rot_gains_prev ); - if ( ( error = updateSbaPanGains( inputSba, outConfig, hRend ) ) != IVAS_ERR_OK ) + if ( ( error = updateSbaPanGains( inputSba, outConfig, hRendCfg ) ) != IVAS_ERR_OK ) { return error; } -- GitLab From e8691f0132194a3a1d4b1354aa06c205c3182d80 Mon Sep 17 00:00:00 2001 From: Remco Stoutjesdijk Date: Wed, 2 Nov 2022 22:45:05 +0100 Subject: [PATCH 067/101] cosmetics --- apps/renderer.c | 8 ++++---- lib_rend/lib_rend.c | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/renderer.c b/apps/renderer.c index e4d6bf36d0..5345c938ca 100644 --- a/apps/renderer.c +++ b/apps/renderer.c @@ -678,25 +678,25 @@ int32_t main( int32_t argc, char **argv ) if ( args.outConfig.audioConfig != IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM ) { fprintf( stderr, "\nExternal Renderer Config is supported only when BINAURAL_ROOM is used as output. Exiting. \n" ); - exit( -1 ); // goto cleanup; + exit( -1 ); } if ( ( error = IVAS_REND_GetRenderConfig( hIvasRend, &renderConfig ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nIVAS_DEC_GetRenderConfig failed\n" ); - exit( -1 ); // goto cleanup; + exit( -1 ); } if ( RenderConfigReader_read( renderConfigReader, &renderConfig ) != IVAS_ERR_OK ) { fprintf( stderr, "Failed to read renderer configuration from file %s\n", args.renderConfigFilePath ); - exit( -1 ); // goto cleanup; + exit( -1 ); } if ( ( error = IVAS_REND_FeedRenderConfig( hIvasRend, renderConfig ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nIVAS_DEC_FeedRenderConfig failed\n" ); - exit( -1 ); // goto cleanup; + exit( -1 ); } } diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index 3a3fb1658b..aa3fb2599f 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -2670,7 +2670,7 @@ ivas_error IVAS_REND_InitConfig( IVAS_REND_HANDLE st, } int16_t IVAS_REND_GetRenderConfig( - IVAS_REND_HANDLE hIvasRend, /* i/o: IVAS decoder handle */ + IVAS_REND_HANDLE hIvasRend, /* i/o: IVAS decoder handle */ const IVAS_RENDER_CONFIG_HANDLE hRCout /* o : Render configuration handle */ ) { @@ -2712,7 +2712,7 @@ int16_t IVAS_REND_GetRenderConfig( int16_t IVAS_REND_FeedRenderConfig( - IVAS_REND_HANDLE hIvasRend, /* i/o: IVAS decoder handle */ + IVAS_REND_HANDLE hIvasRend, /* i/o: IVAS decoder handle */ const IVAS_RENDER_CONFIG_DATA renderConfig /* i : Render configuration struct */ ) { -- GitLab From b45c0e3f9794495ceff6b34585dee4dd4a499eaf Mon Sep 17 00:00:00 2001 From: Remco Stoutjesdijk Date: Wed, 2 Nov 2022 22:47:51 +0100 Subject: [PATCH 068/101] pacifying compiler --- apps/renderer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/renderer.c b/apps/renderer.c index 5345c938ca..05de0db262 100644 --- a/apps/renderer.c +++ b/apps/renderer.c @@ -2214,7 +2214,7 @@ static void convert_backslash( char *str ) int32_t i, len; /* check that all backslashes are correct on the given platform */ - len = strlen( str ); + len = (int32_t) strlen( str ); for ( i = 0; i < len; i++ ) { -- GitLab From 55450bd3fde3a6f9823563c28b5bf619fefa7161 Mon Sep 17 00:00:00 2001 From: Kacper Sagnowski Date: Thu, 3 Nov 2022 13:07:57 +0100 Subject: [PATCH 069/101] Fix missing renderer executable in ivas-pytest-on-merge-request job --- .gitlab-ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index df216642fe..8f2a0704b8 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -53,6 +53,7 @@ stages: - make -j - mv IVAS_cod ../IVAS_cod_test - mv IVAS_dec ../IVAS_dec_test + - mv IVAS_rend .. - cd .. - rm -rf build/* -- GitLab From 116dd54e11897add626c6523e868386f3b03350f Mon Sep 17 00:00:00 2001 From: Archit Tamarapu Date: Fri, 4 Nov 2022 10:27:38 +0100 Subject: [PATCH 070/101] [tests] simplify pytest functions and cleanup, add tests vs internal (decoder) renderer --- .gitlab-ci.yml | 108 ++-- tests/renderer/constants.py | 326 +++++++++- tests/renderer/test_renderer.py | 719 ++++----------------- tests/renderer/test_renderer_vs_decoder.py | 128 ++++ tests/renderer/utils.py | 439 +++++++++++++ 5 files changed, 1046 insertions(+), 674 deletions(-) create mode 100644 tests/renderer/test_renderer_vs_decoder.py create mode 100644 tests/renderer/utils.py diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index df216642fe..aa3893bdd0 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -9,7 +9,6 @@ variables: EXIT_CODE_NON_BE: 123 EXIT_CODE_FAIL: 1 - # This sets when pipelines are created. Jobs have more specific rules to restrict them. workflow: rules: @@ -44,8 +43,8 @@ stages: .get-previous-merge-commit-sha: &get-previous-merge-commit-sha - previous_merge_commit=$(git --no-pager log --merges HEAD~1 -n 1 --pretty=format:%H) -.merge_request_comparison_setup: &merge_request_comparison_setup - ### build test binaries, initial clean for paranoia reasons +.merge_request_comparison_setup: + &merge_request_comparison_setup ### build test binaries, initial clean for paranoia reasons - make clean - mkdir build - cd build @@ -86,10 +85,10 @@ stages: - git checkout $source_branch_commit_sha .merge-request-comparison-check: &merge-request-comparison-check - - 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 + - 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 # --------------------------------------------------------------- # Job templates @@ -125,7 +124,6 @@ stages: rules: - if: $CI_PIPELINE_SOURCE == 'schedule' && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH - # templates to define stages and platforms .test-job-linux: tags: @@ -137,7 +135,6 @@ stages: tags: - ivas-linux - # template for test jobs on linux that need the TESTV_DIR .test-job-linux-needs-testv-dir: extends: .test-job-linux @@ -153,7 +150,6 @@ stages: exit_codes: - 123 - # --------------------------------------------------------------- # Validation jobs # --------------------------------------------------------------- @@ -172,13 +168,12 @@ check-if-branch-is-up-to-date-with-main: - echo $commits_behind_count - if [ $commits_behind_count -eq 0 ]; then exit 0; else exit 1; fi; - # --------------------------------------------------------------- # Build jobs # --------------------------------------------------------------- build-codec-linux-make: - extends: + extends: - .build-job-with-check-for-warnings - .rules-basis script: @@ -188,7 +183,7 @@ build-codec-linux-make: - ci/check_for_warnings.py $BUILD_OUTPUT || exit $? build-unittests-linux: - extends: + extends: - .build-job-with-check-for-warnings - .rules-basis script: @@ -198,7 +193,7 @@ build-unittests-linux: - ci/check_for_warnings.py $BUILD_OUTPUT || exit $? build-td-object-renderer-standalone-linux: - extends: + extends: - .build-job-with-check-for-warnings - .rules-basis script: @@ -208,7 +203,7 @@ build-td-object-renderer-standalone-linux: - ci/check_for_warnings.py $BUILD_OUTPUT || exit $? build-codec-linux-cmake: - extends: + extends: - .build-job-with-check-for-warnings - .rules-basis script: @@ -222,7 +217,7 @@ build-codec-linux-cmake: - ci/check_for_warnings.py $BUILD_OUTPUT || exit $? build-codec-instrumented-linux: - extends: + extends: - .build-job-linux - .rules-basis script: @@ -231,26 +226,25 @@ build-codec-instrumented-linux: # make sure that the codec builds with msan, asan and usan build-codec-sanitizers-linux: - extends: + extends: - .build-job-linux - .rules-basis script: - *print-common-info - bash ci/build_codec_sanitizers_linux.sh - # --------------------------------------------------------------- # Test jobs for merge requests # --------------------------------------------------------------- # test that runs all modes with 1s input signals codec-smoke-test: - extends: + extends: - .test-job-linux-needs-testv-dir - .rules-merge-request timeout: "5 minutes" stage: test - needs: [ "build-codec-linux-cmake" ] + needs: ["build-codec-linux-cmake"] script: - *print-common-info - bash ci/smoke_test.sh @@ -263,16 +257,15 @@ codec-smoke-test: - out/logs/ - smoke_test_output.txt - smoke_test_output_plc.txt - expose_as: 'Smoke test results' - + expose_as: "Smoke test results" # code selftest testvectors with memory-sanitizer binaries msan-on-merge-request-linux: - extends: + extends: - .test-job-linux - .rules-merge-request stage: test - needs: [ "build-codec-sanitizers-linux" ] + needs: ["build-codec-sanitizers-linux"] script: - *print-common-info - make clean @@ -285,16 +278,15 @@ msan-on-merge-request-linux: paths: - scripts/ref/logs/ - test_output.txt - expose_as: 'Msan selftest results' - + expose_as: "Msan selftest results" # code selftest testvectors with address-sanitizer binaries asan-on-merge-request-linux: - extends: + extends: - .test-job-linux - .rules-merge-request stage: test - needs: [ "build-codec-sanitizers-linux" ] + needs: ["build-codec-sanitizers-linux"] script: - *print-common-info - make clean @@ -307,54 +299,66 @@ asan-on-merge-request-linux: paths: - scripts/ref/logs/ - test_output.txt - expose_as: 'Asan selftest results' + expose_as: "Asan selftest results" # test external renderer executable external-renderer-make-pytest: extends: - .test-job-linux - .rules-merge-request - needs: [ "build-codec-linux-make" ] + needs: ["build-codec-linux-make"] stage: test script: - make -j IVAS_rend - make -j unittests - make -j --directory scripts/td_object_renderer/object_renderer_standalone - - python3 -m pytest tests/renderer/test_renderer.py -q --log-level ERROR -n auto -rA + - python3 -m pytest -q --log-level ERROR -n auto -rA tests/renderer/test_renderer.py # test external renderer executable with cmake + asan external-renderer-cmake-asan-pytest: extends: - .test-job-linux - .rules-merge-request - needs: [ "build-codec-linux-cmake" ] + needs: ["build-codec-linux-cmake"] stage: test script: - python3 ci/disable_ram_counting.py - cmake -B cmake-build -G "Unix Makefiles" -DCLANG=asan -DCOPY_EXECUTABLES_FROM_BUILD_DIR=true - cmake --build cmake-build -- -j - - python3 -m pytest tests/renderer/test_renderer.py -q --log-level ERROR -n auto -rA + - python3 -m pytest -q --log-level ERROR -n auto -rA tests/renderer/test_renderer.py # test external renderer executable with cmake + msan external-renderer-cmake-msan-pytest: extends: - .test-job-linux - .rules-merge-request - needs: [ "build-codec-linux-cmake" ] + needs: ["build-codec-linux-cmake"] stage: test script: - python3 ci/disable_ram_counting.py - cmake -B cmake-build -G "Unix Makefiles" -DCLANG=msan -DCOPY_EXECUTABLES_FROM_BUILD_DIR=true - cmake --build cmake-build -- -j - - python3 -m pytest tests/renderer/test_renderer.py -q --log-level ERROR -n auto -rA + - python3 -m pytest -q --log-level ERROR -n auto -rA tests/renderer/test_renderer.py + +# test external renderer executable with cmake vs decoder renderer +external-renderer-make-vs-decoder-pytest: + extends: + - .test-job-linux + - .rules-merge-request + needs: ["build-codec-linux-cmake"] + stage: test + script: + - cmake -B cmake-build -G "Unix Makefiles" -DCLANG=msan -DCOPY_EXECUTABLES_FROM_BUILD_DIR=true -DDEC_TO_REND_FLOAT_DUMP + - cmake --build cmake-build -- -j + - python3 -m pytest -q --log-level ERROR -n 1 -rA tests/renderer/test_renderer_vs_decoder.py # compare bit exactness between target and source branch ivas-pytest-on-merge-request: - extends: + extends: - .test-job-linux - .rules-merge-request stage: compare - needs: [ "build-codec-linux-cmake", "codec-smoke-test" ] + needs: ["build-codec-linux-cmake", "codec-smoke-test"] timeout: "10 minutes" script: - *print-common-info @@ -385,17 +389,17 @@ ivas-pytest-on-merge-request: when: always paths: - report-junit.xml - expose_as: 'pytest ivas results' + expose_as: "pytest ivas results" reports: junit: - report-junit.xml evs-pytest-on-merge-request: - extends: + extends: - .test-job-linux - .rules-merge-request stage: compare - needs: [ "build-codec-linux-cmake", "codec-smoke-test" ] + needs: ["build-codec-linux-cmake", "codec-smoke-test"] timeout: "10 minutes" script: - *print-common-info @@ -423,12 +427,11 @@ evs-pytest-on-merge-request: when: always paths: - report-junit-evs.xml - expose_as: 'pytest evs results' + expose_as: "pytest evs results" reports: junit: - report-junit-evs.xml - # --------------------------------------------------------------- # Test jobs for main branch # --------------------------------------------------------------- @@ -441,7 +444,7 @@ be-2-evs-linux: tags: - be-2-evs-temp stage: test - needs: [ "build-codec-linux-cmake" ] + needs: ["build-codec-linux-cmake"] timeout: "20 minutes" # To be revisited script: - *print-common-info @@ -460,13 +463,12 @@ be-2-evs-linux: - cd evs_be_test - python3 ../ci/run_evs_be_test.py - codec-comparison-on-main-push: extends: - .test-job-linux - .rules-main-push stage: compare - needs: [ "build-codec-linux-cmake" ] + needs: ["build-codec-linux-cmake"] timeout: "30 minutes" # To be revisited script: - *print-common-info @@ -476,7 +478,7 @@ codec-comparison-on-main-push: - git --no-pager diff --stat $previous_merge_commit..$latest_commit # Rest is more or less placeholder adapted from MR self test. This should be replaced with more complex tests. - + ### build test binaries, initial clean for paranoia reasons - make clean - mkdir build @@ -531,11 +533,10 @@ codec-comparison-on-main-push: when: always paths: - report-junit.xml - expose_as: 'Results of comparison to previous merge commit' + expose_as: "Results of comparison to previous merge commit" reports: junit: report-junit.xml - # --------------------------------------------------------------- # Scheduled jobs on main # --------------------------------------------------------------- @@ -688,15 +689,15 @@ sanitizer-test-planarsba: # GCOV/LCOV coverage analysis of self_test suite coverage-test-on-main-scheduled: - extends: + extends: - .test-job-linux-needs-testv-dir - - .rules-main-scheduled + - .rules-main-scheduled tags: - coverage-test stage: test rules: # only run in scheduled pipeline that passes this env vars - - if: $COVERAGE_TEST + - if: $COVERAGE_TEST script: - *print-common-info - make GCOV=1 -j @@ -725,10 +726,10 @@ pull-from-3gpp-forge: script: # Set up git LFS for mirroring (see: https://github.com/git-lfs/git-lfs/issues/1762) - git lfs install --skip-smudge --local - + # Check out mirror branch - by default the runner checks out by commit hash, which results in detached head state - git checkout $CI_COMMIT_BRANCH - + # Pull commits from upstream - git remote add upstream https://forge.3gpp.org/rep/ivas-codec-pc/ivas-codec.git - git pull --ff-only --tags upstream $MIRROR_SOURCE_BRANCH @@ -736,4 +737,3 @@ pull-from-3gpp-forge: # Push to mirror, include tags. Option `-o ci.skip` tells GitLab to skip CI for the pushed commits (assumed already tested upstream) - git push --tags -o ci.skip "https://${GITLAB_USER_LOGIN}:${MIRROR_ACCESS_TOKEN}@${CI_REPOSITORY_URL#*@}" "HEAD:${CI_COMMIT_BRANCH}" - diff --git a/tests/renderer/constants.py b/tests/renderer/constants.py index b5d5cf3502..d76be35089 100644 --- a/tests/renderer/constants.py +++ b/tests/renderer/constants.py @@ -35,9 +35,33 @@ TEST_VECTOR_DIR = TESTS_DIR.joinpath("data") OUTPUT_PATH_REF = TESTS_DIR.joinpath("ref") OUTPUT_PATH_CUT = TESTS_DIR.joinpath("cut") +OUTPUT_PATH_REF = TESTS_DIR.joinpath("/home/amm-er/tmu/external_renderer/ref") +OUTPUT_PATH_CUT = TESTS_DIR.joinpath("/home/amm-er/tmu/external_renderer/cut") CUSTOM_LAYOUT_DIR = SCRIPTS_DIR.joinpath("ls_layouts") HR_TRAJECTORY_DIR = SCRIPTS_DIR.joinpath("trajectories") +TESTV_DIR = SCRIPTS_DIR.joinpath("testv") + +""" Encoder commandline template """ +IVAS_COD_CMD = [ + str(TESTS_DIR.parent.parent.joinpath("IVAS_cod")), + "", # 1 -> mode + "", # 2 -> options for mode + "", # 3 -> bitrate + "48", # 4 -> input fs + "", # 5 -> input file + "", # 6 -> bitstream file +] + +""" Decoder commandline template """ +IVAS_DEC_CMD = [ + str(TESTS_DIR.parent.parent.joinpath("IVAS_dec")), + "-no_delay_cmp", + "", # 2 -> output format, + "48", # 3 -> output fs + "", # 4 -> bitstream file + "", # 5 -> output file +] """ Renderer commandline template """ RENDERER_CMD = [ @@ -52,7 +76,7 @@ RENDERER_CMD = [ "", # 8 -> output format "-fs", "48", # 10 -> input fs - # "--no_delay_cmp", + "--no_delay_cmp", # "-ndl", "-q", ] @@ -71,7 +95,9 @@ TDRENDERER_CMD = [ """ CREND commandline template """ RENDERER_CREND_CMD = [ - str(SCRIPTS_DIR.joinpath("ivas_pytests/tests/unit_tests/crend/IVAS_crend_unit_test")), + str( + SCRIPTS_DIR.joinpath("ivas_pytests/tests/unit_tests/crend/IVAS_crend_unit_test") + ), "-test", "1", "-sr", @@ -162,6 +188,40 @@ FORMAT_TO_METADATA_FILES = { "MASA2": [str(TEST_VECTOR_DIR.joinpath("stv_IVASMASAQ_2dir2TC.met"))], } +FORMAT_TO_IVAS = { + "MONO": ["", ""], + "STEREO": ["-stereo", ""], + "FOA": ["-sba", "1"], + "HOA2": ["-sba", "2"], + "HOA3": ["-sba", "3"], + "5_1": ["-mc", "5_1"], + "7_1": ["-mc", "7_1"], + "5_1_2": ["-mc", "5_1_2"], + "5_1_4": ["-mc", "5_1_4"], + "7_1_4": ["-mc", "7_1_4"], + "ISM1": ["-ism", "1"], + "ISM2": ["-ism", "2"], + "ISM3": ["-ism", "3"], + "ISM4": ["-ism", "4"], +} + +FORMAT_TO_IVAS_BR = { + "MONO": "128000", + "STEREO": "256000", + "FOA": "512000", + "HOA2": "512000", + "HOA3": "512000", + "5_1": "512000", + "7_1": "512000", + "5_1_2": "512000", + "5_1_4": "512000", + "7_1_4": "512000", + "ISM1": "256000", + "ISM2": "256000", + "ISM3": "256000", + "ISM4": "256000", +} + FORMAT_TO_CREND_FORMAT = { "MONO": "0", "STEREO": "1", @@ -199,14 +259,9 @@ OUTPUT_FORMATS = [ """ Custom loudspeaker input/output """ CUSTOM_LS_TO_TEST = [ - # "cicp1", - # "cicp2", "t_design_4", - # "4d0", "4d4", "itu_4+5+1", - "custom1", - # "cicp20", "16ch_8+4+4", ] @@ -215,21 +270,252 @@ METADATA_SCENES_TO_TEST = ["mixed_scene", "mixed_scene_simple"] METADATA_SCENES_TO_TEST_NO_BE = ["masa_scene"] """ Binaural rendering """ -INPUT_FORMATS_BINAURAL = OUTPUT_FORMATS[2:] -INPUT_FORMATS_BINAURAL.extend( - [ - "ISM1", - "ISM2", - "ISM3", - "ISM4", - # "MASA1", - # "MASA2", - ] -) OUTPUT_FORMATS_BINAURAL = ["BINAURAL", "BINAURAL_ROOM"] HR_TRAJECTORIES_TO_TEST = [ - # "const000", "full_circle_in_15s", - # "full_circle_in_15s-Euler", "rotate_yaw_pitch_roll1", ] + +""" Per-testcase xfail SNR thresholds (dB) """ +pass_snr = { + #################################################################### + # + # External Renderer vs Standalone and pyaudio3dtools renderers tests + # + #################################################################### + # Crend used internally, comparison to pyaudio3dtools has bad SNR + # Crend unit test does not support Quaternion files + "test_ambisonics_binaural_headrotation[FOA-BINAURAL_ROOM-full_circle_in_15s]": 0, + "test_ambisonics_binaural_headrotation[FOA-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 0, + "test_ambisonics_binaural_headrotation[HOA2-BINAURAL-full_circle_in_15s]": 18, + "test_ambisonics_binaural_headrotation[HOA2-BINAURAL_ROOM-full_circle_in_15s]": 0, + "test_ambisonics_binaural_headrotation[HOA2-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 0, + "test_ambisonics_binaural_headrotation[HOA2-BINAURAL-rotate_yaw_pitch_roll1]": 4, + "test_ambisonics_binaural_headrotation[HOA3-BINAURAL-full_circle_in_15s]": 15, + "test_ambisonics_binaural_headrotation[HOA3-BINAURAL_ROOM-full_circle_in_15s]": 0, + "test_ambisonics_binaural_headrotation[HOA3-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 0, + "test_ambisonics_binaural_headrotation[HOA3-BINAURAL-rotate_yaw_pitch_roll1]": 3, + # TODO needs debugging + "test_ambisonics_binaural_static[FOA-BINAURAL_ROOM]": 0, + "test_ambisonics_binaural_static[HOA2-BINAURAL_ROOM]": 0, + "test_ambisonics_binaural_static[HOA3-BINAURAL_ROOM]": 0, + # TD Object Renderer used internally, comparison to pyaudio3dtools has bad SNR + # TD Object Renderer standalone does not support custom LS + "test_custom_ls_input_binaural[16ch_8+4+4-BINAURAL]": 0, + "test_custom_ls_input_binaural[16ch_8+4+4-BINAURAL_ROOM]": 0, + "test_custom_ls_input_binaural[4d4-BINAURAL]": 0, + "test_custom_ls_input_binaural[4d4-BINAURAL_ROOM]": 0, + "test_custom_ls_input_binaural_headrotation[16ch_8+4+4-BINAURAL-full_circle_in_15s]": 0, + "test_custom_ls_input_binaural_headrotation[16ch_8+4+4-BINAURAL_ROOM-full_circle_in_15s]": 0, + "test_custom_ls_input_binaural_headrotation[16ch_8+4+4-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 0, + "test_custom_ls_input_binaural_headrotation[16ch_8+4+4-BINAURAL-rotate_yaw_pitch_roll1]": 0, + "test_custom_ls_input_binaural_headrotation[4d4-BINAURAL-full_circle_in_15s]": 0, + "test_custom_ls_input_binaural_headrotation[4d4-BINAURAL_ROOM-full_circle_in_15s]": 0, + "test_custom_ls_input_binaural_headrotation[4d4-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 0, + "test_custom_ls_input_binaural_headrotation[4d4-BINAURAL-rotate_yaw_pitch_roll1]": 0, + "test_custom_ls_input_binaural_headrotation[itu_4+5+1-BINAURAL-full_circle_in_15s]": 0, + "test_custom_ls_input_binaural_headrotation[itu_4+5+1-BINAURAL_ROOM-full_circle_in_15s]": 3, + "test_custom_ls_input_binaural_headrotation[itu_4+5+1-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 3, + "test_custom_ls_input_binaural_headrotation[itu_4+5+1-BINAURAL-rotate_yaw_pitch_roll1]": 0, + "test_custom_ls_input_binaural_headrotation[t_design_4-BINAURAL-full_circle_in_15s]": 0, + "test_custom_ls_input_binaural_headrotation[t_design_4-BINAURAL_ROOM-full_circle_in_15s]": 0, + "test_custom_ls_input_binaural_headrotation[t_design_4-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 0, + "test_custom_ls_input_binaural_headrotation[t_design_4-BINAURAL-rotate_yaw_pitch_roll1]": 0, + "test_custom_ls_input_binaural[itu_4+5+1-BINAURAL]": 0, + "test_custom_ls_input_binaural[itu_4+5+1-BINAURAL_ROOM]": 3, + "test_custom_ls_input_binaural[t_design_4-BINAURAL]": 0, + "test_custom_ls_input_binaural[t_design_4-BINAURAL_ROOM]": 0, + # Crend used internally, comparison to pyaudio3dtools has bad SNR + # Crend unit test does not support ISM rendering or Quaternion files + "test_ism_binaural_headrotation[ISM1-BINAURAL_ROOM-full_circle_in_15s]": 9, + "test_ism_binaural_headrotation[ISM1-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 4, + "test_ism_binaural_headrotation[ISM2-BINAURAL_ROOM-full_circle_in_15s]": 10, + "test_ism_binaural_headrotation[ISM2-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 3, + "test_ism_binaural_headrotation[ISM2-BINAURAL-rotate_yaw_pitch_roll1]": 24, + "test_ism_binaural_headrotation[ISM3-BINAURAL_ROOM-full_circle_in_15s]": 10, + "test_ism_binaural_headrotation[ISM3-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 4, + "test_ism_binaural_headrotation[ISM3-BINAURAL-rotate_yaw_pitch_roll1]": 24, + "test_ism_binaural_headrotation[ISM4-BINAURAL_ROOM-full_circle_in_15s]": 10, + "test_ism_binaural_headrotation[ISM4-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 4, + "test_ism_binaural_headrotation[ISM4-BINAURAL-rotate_yaw_pitch_roll1]": 24, + "test_ism_binaural_static[ISM1-BINAURAL_ROOM]": 23, + "test_ism_binaural_static[ISM2-BINAURAL_ROOM]": 21, + "test_ism_binaural_static[ISM3-BINAURAL_ROOM]": 21, + "test_ism_binaural_static[ISM4-BINAURAL_ROOM]": 21, + # TODO needs debugging, minor differences could be due to crossfades or metadata position casts + "test_ism[ISM1-5_1_2]": 48, + "test_ism[ISM1-5_1_4]": 48, + "test_ism[ISM1-5_1]": 48, + "test_ism[ISM1-7_1_4]": 46, + "test_ism[ISM1-7_1]": 45, + "test_ism[ISM1-FOA]": 44, + "test_ism[ISM1-HOA2]": 40, + "test_ism[ISM1-HOA3]": 37, + "test_ism[ISM1-STEREO]": 54, + "test_ism[ISM2-5_1_2]": 46, + "test_ism[ISM2-5_1_4]": 45, + "test_ism[ISM2-5_1]": 47, + "test_ism[ISM2-7_1_4]": 43, + "test_ism[ISM2-7_1]": 45, + "test_ism[ISM2-FOA]": 41, + "test_ism[ISM2-HOA2]": 37, + "test_ism[ISM2-HOA3]": 34, + "test_ism[ISM2-STEREO]": 55, + "test_ism[ISM3-5_1_2]": 44, + "test_ism[ISM3-5_1_4]": 43, + "test_ism[ISM3-5_1]": 45, + "test_ism[ISM3-7_1_4]": 42, + "test_ism[ISM3-7_1]": 44, + "test_ism[ISM3-FOA]": 39, + "test_ism[ISM3-HOA2]": 36, + "test_ism[ISM3-HOA3]": 33, + "test_ism[ISM3-STEREO]": 54, + "test_ism[ISM4-5_1_2]": 44, + "test_ism[ISM4-5_1_4]": 44, + "test_ism[ISM4-5_1]": 46, + "test_ism[ISM4-7_1_4]": 43, + "test_ism[ISM4-7_1]": 44, + "test_ism[ISM4-FOA]": 40, + "test_ism[ISM4-HOA2]": 36, + "test_ism[ISM4-HOA3]": 33, + "test_ism[ISM4-STEREO]": 57, + # Crend used internally, comparison to pyaudio3dtools has bad SNR + # Crend unit test does not support Quaternion files + "test_multichannel_binaural_headrotation[5_1_2-BINAURAL-full_circle_in_15s]": 8, + "test_multichannel_binaural_headrotation[5_1_2-BINAURAL_ROOM-full_circle_in_15s]": 2, + "test_multichannel_binaural_headrotation[5_1_2-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 2, + "test_multichannel_binaural_headrotation[5_1_2-BINAURAL-rotate_yaw_pitch_roll1]": 1, + "test_multichannel_binaural_headrotation[5_1_4-BINAURAL-full_circle_in_15s]": 8, + "test_multichannel_binaural_headrotation[5_1_4-BINAURAL_ROOM-full_circle_in_15s]": 2, + "test_multichannel_binaural_headrotation[5_1_4-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 2, + "test_multichannel_binaural_headrotation[5_1_4-BINAURAL-rotate_yaw_pitch_roll1]": 1, + "test_multichannel_binaural_headrotation[5_1-BINAURAL-full_circle_in_15s]": 7, + "test_multichannel_binaural_headrotation[5_1-BINAURAL_ROOM-full_circle_in_15s]": 3, + "test_multichannel_binaural_headrotation[5_1-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 3, + "test_multichannel_binaural_headrotation[5_1-BINAURAL-rotate_yaw_pitch_roll1]": 6, + "test_multichannel_binaural_headrotation[7_1_4-BINAURAL-full_circle_in_15s]": 7, + "test_multichannel_binaural_headrotation[7_1_4-BINAURAL_ROOM-full_circle_in_15s]": 2, + "test_multichannel_binaural_headrotation[7_1_4-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 2, + "test_multichannel_binaural_headrotation[7_1_4-BINAURAL-rotate_yaw_pitch_roll1]": 1, + "test_multichannel_binaural_headrotation[7_1-BINAURAL-full_circle_in_15s]": 8, + "test_multichannel_binaural_headrotation[7_1-BINAURAL_ROOM-full_circle_in_15s]": 2, + "test_multichannel_binaural_headrotation[7_1-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 2, + "test_multichannel_binaural_headrotation[7_1-BINAURAL-rotate_yaw_pitch_roll1]": 8, + ##################################### + # + # External vs Internal Renderer tests + # + ##################################### + # TODO conversion to 7_1_4 might be different (as indicated by next section of tests), needs debugging + "test_ism_binaural_headrotation_vs_decoder[ISM1-BINAURAL_ROOM-full_circle_in_15s]": 15, + "test_ism_binaural_headrotation_vs_decoder[ISM1-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 15, + "test_ism_binaural_headrotation_vs_decoder[ISM2-BINAURAL_ROOM-full_circle_in_15s]": 12, + "test_ism_binaural_headrotation_vs_decoder[ISM2-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 13, + "test_ism_binaural_headrotation_vs_decoder[ISM2-BINAURAL-rotate_yaw_pitch_roll1]": 84, + "test_ism_binaural_headrotation_vs_decoder[ISM3-BINAURAL_ROOM-full_circle_in_15s]": 12, + "test_ism_binaural_headrotation_vs_decoder[ISM3-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 13, + "test_ism_binaural_headrotation_vs_decoder[ISM3-BINAURAL-rotate_yaw_pitch_roll1]": 78, + "test_ism_binaural_headrotation_vs_decoder[ISM4-BINAURAL_ROOM-full_circle_in_15s]": 12, + "test_ism_binaural_headrotation_vs_decoder[ISM4-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 13, + "test_ism_binaural_headrotation_vs_decoder[ISM4-BINAURAL-rotate_yaw_pitch_roll1]": 85, + "test_ism_binaural_static_vs_decoder[ISM1-BINAURAL_ROOM]": 15, + "test_ism_binaural_static_vs_decoder[ISM2-BINAURAL_ROOM]": 12, + "test_ism_binaural_static_vs_decoder[ISM3-BINAURAL_ROOM]": 12, + "test_ism_binaural_static_vs_decoder[ISM4-BINAURAL_ROOM]": 12, + # TODO loudspeaker and ambisonics rendering could be due to crossfades or metadata position rounding + "test_ism_vs_decoder[ISM1-5_1_2]": 26, + "test_ism_vs_decoder[ISM1-5_1]": 26, + "test_ism_vs_decoder[ISM1-5_1_4]": 26, + "test_ism_vs_decoder[ISM1-7_1]": 26, + "test_ism_vs_decoder[ISM1-7_1_4]": 26, + "test_ism_vs_decoder[ISM1-FOA]": 27, + "test_ism_vs_decoder[ISM1-HOA2]": 26, + "test_ism_vs_decoder[ISM1-HOA3]": 26, + "test_ism_vs_decoder[ISM1-STEREO]": 8, + "test_ism_vs_decoder[ISM2-5_1_2]": 32, + "test_ism_vs_decoder[ISM2-5_1_4]": 31, + "test_ism_vs_decoder[ISM2-5_1]": 6, + "test_ism_vs_decoder[ISM2-7_1_4]": 31, + "test_ism_vs_decoder[ISM2-7_1]": 5, + "test_ism_vs_decoder[ISM2-FOA]": 32, + "test_ism_vs_decoder[ISM2-HOA2]": 31, + "test_ism_vs_decoder[ISM2-HOA3]": 30, + "test_ism_vs_decoder[ISM2-STEREO]": 17, + "test_ism_vs_decoder[ISM3-5_1_2]": 32, + "test_ism_vs_decoder[ISM3-5_1_4]": 32, + "test_ism_vs_decoder[ISM3-5_1]": 8, + "test_ism_vs_decoder[ISM3-7_1_4]": 31, + "test_ism_vs_decoder[ISM3-7_1]": 7, + "test_ism_vs_decoder[ISM3-FOA]": 32, + "test_ism_vs_decoder[ISM3-HOA2]": 32, + "test_ism_vs_decoder[ISM3-HOA3]": 30, + "test_ism_vs_decoder[ISM3-MONO]": 77, + "test_ism_vs_decoder[ISM3-STEREO]": 14, + "test_ism_vs_decoder[ISM4-5_1_2]": 31, + "test_ism_vs_decoder[ISM4-5_1_4]": 31, + "test_ism_vs_decoder[ISM4-5_1]": 8, + "test_ism_vs_decoder[ISM4-7_1_4]": 30, + "test_ism_vs_decoder[ISM4-7_1]": 7, + "test_ism_vs_decoder[ISM4-FOA]": 31, + "test_ism_vs_decoder[ISM4-HOA2]": 31, + "test_ism_vs_decoder[ISM4-HOA3]": 30, + "test_ism_vs_decoder[ISM4-MONO]": 77, + "test_ism_vs_decoder[ISM4-STEREO]": 14, + # TODO needs debugging + "test_multichannel_binaural_headrotation_vs_decoder[5_1_2-BINAURAL-full_circle_in_15s]": 4, + "test_multichannel_binaural_headrotation_vs_decoder[5_1_2-BINAURAL_ROOM-full_circle_in_15s]": 6, + "test_multichannel_binaural_headrotation_vs_decoder[5_1_2-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 0, + "test_multichannel_binaural_headrotation_vs_decoder[5_1_2-BINAURAL-rotate_yaw_pitch_roll1]": 0, + "test_multichannel_binaural_headrotation_vs_decoder[5_1_4-BINAURAL-full_circle_in_15s]": 4, + "test_multichannel_binaural_headrotation_vs_decoder[5_1_4-BINAURAL_ROOM-full_circle_in_15s]": 7, + "test_multichannel_binaural_headrotation_vs_decoder[5_1_4-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 0, + "test_multichannel_binaural_headrotation_vs_decoder[5_1_4-BINAURAL-rotate_yaw_pitch_roll1]": 0, + "test_multichannel_binaural_headrotation_vs_decoder[5_1-BINAURAL_ROOM-full_circle_in_15s]": 5, + "test_multichannel_binaural_headrotation_vs_decoder[5_1-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 0, + "test_multichannel_binaural_headrotation_vs_decoder[7_1_4-BINAURAL-full_circle_in_15s]": 4, + "test_multichannel_binaural_headrotation_vs_decoder[7_1_4-BINAURAL_ROOM-full_circle_in_15s]": 5, + "test_multichannel_binaural_headrotation_vs_decoder[7_1_4-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 0, + "test_multichannel_binaural_headrotation_vs_decoder[7_1_4-BINAURAL-rotate_yaw_pitch_roll1]": 0, + "test_multichannel_binaural_headrotation_vs_decoder[7_1-BINAURAL_ROOM-full_circle_in_15s]": 5, + "test_multichannel_binaural_headrotation_vs_decoder[7_1-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 0, + # TODO needs debugging + "test_multichannel_binaural_static_vs_decoder[5_1_2-BINAURAL_ROOM]": 18, + "test_multichannel_binaural_static_vs_decoder[5_1_4-BINAURAL_ROOM]": 18, + "test_multichannel_binaural_static_vs_decoder[5_1-BINAURAL_ROOM]": 18, + "test_multichannel_binaural_static_vs_decoder[7_1_4-BINAURAL_ROOM]": 18, + "test_multichannel_binaural_static_vs_decoder[7_1-BINAURAL_ROOM]": 19, + # TODO Mono downmix significantly different, needs a fix + "test_multichannel_vs_decoder[5_1_2-MONO]": 1, + "test_multichannel_vs_decoder[5_1_4-MONO]": 1, + "test_multichannel_vs_decoder[5_1-MONO]": 1, + "test_multichannel_vs_decoder[7_1_4-MONO]": 1, + "test_multichannel_vs_decoder[7_1-MONO]": 1, + "test_multichannel_vs_decoder[STEREO-MONO]": 17, + # TODO Stereo downmix differs slightly, needs debugging + "test_multichannel_vs_decoder[5_1_2-STEREO]": 44, + "test_multichannel_vs_decoder[5_1_4-STEREO]": 48, + "test_multichannel_vs_decoder[5_1-STEREO]": 48, + "test_multichannel_vs_decoder[7_1_4-STEREO]": 46, + "test_multichannel_vs_decoder[7_1-STEREO]": 44, + # TODO minor differences, needs debugging + "test_multichannel_vs_decoder[5_1_2-5_1_4]": 63, + "test_multichannel_vs_decoder[5_1_2-5_1]": 63, + "test_multichannel_vs_decoder[5_1_2-7_1_4]": 63, + "test_multichannel_vs_decoder[5_1_2-7_1]": 63, + "test_multichannel_vs_decoder[5_1_4-5_1_2]": 63, + "test_multichannel_vs_decoder[5_1_4-5_1]": 62, + "test_multichannel_vs_decoder[5_1_4-7_1_4]": 61, + "test_multichannel_vs_decoder[5_1_4-7_1]": 62, + "test_multichannel_vs_decoder[5_1-5_1_2]": 62, + "test_multichannel_vs_decoder[5_1-5_1_4]": 62, + "test_multichannel_vs_decoder[5_1-7_1_4]": 62, + "test_multichannel_vs_decoder[5_1-7_1]": 62, + "test_multichannel_vs_decoder[7_1_4-5_1_2]": 63, + "test_multichannel_vs_decoder[7_1_4-5_1_4]": 63, + "test_multichannel_vs_decoder[7_1_4-5_1]": 63, + "test_multichannel_vs_decoder[7_1_4-7_1]": 62, + "test_multichannel_vs_decoder[7_1-5_1_2]": 63, + "test_multichannel_vs_decoder[7_1-5_1_4]": 63, + "test_multichannel_vs_decoder[7_1-5_1]": 63, + "test_multichannel_vs_decoder[7_1-7_1_4]": 63, +} diff --git a/tests/renderer/test_renderer.py b/tests/renderer/test_renderer.py index e09dc37222..87af209318 100644 --- a/tests/renderer/test_renderer.py +++ b/tests/renderer/test_renderer.py @@ -26,424 +26,89 @@ the United Nations Convention on Contracts on the International Sales of Goods. """ -import subprocess as sp -import sys -from pathlib import Path -from tempfile import TemporaryDirectory -from typing import Optional, Tuple -import numpy as np import pytest +from .utils import * -from .compare_audio import compare_audio_arrays -from .constants import * -sys.path.append(SCRIPTS_DIR) -import pyaudio3dtools +""" Ambisonics """ -def check_BE( - test_info, - ref: np.ndarray, - ref_fs: int, - cut: np.ndarray, - cut_fs: int, -): - - if ref is None or np.array_equal(ref, np.zeros_like(ref)): - pytest.fail("REF signal does not exist or is zero!") - - if cut is None or np.array_equal(cut, np.zeros_like(cut)): - pytest.fail("CuT signal does not exist or is zero!") - - snr, gain_b, max_diff = compare_audio_arrays(ref, ref_fs, cut, cut_fs) - - if np.isnan(snr) or gain_b == 0: - pytest.fail("Invalid comparison result, check your signals!") - - # try to get a minimum SNR from the config - if test_info.node.name in pass_snr: - snr_min = pass_snr.get(test_info.node.name) - else: - snr_min = np.inf - - # TODO temporary fix to pad TD Object Renderer Standalone output - if ref.shape != cut.shape: - ref = np.pad(ref, [(0, cut.shape[0] - ref.shape[0]), (0, 0)]) - - # check max_diff as well, since compare_audio_arrays will try to adjust for small delay differences - if not np.allclose(ref, cut, rtol=0, atol=2) and max_diff > 2: - if snr >= snr_min: - pytest.xfail( - f"Expected failure with minimum SNR {snr_min} vs {snr:3.2f}dB, Gain CuT: {gain_b:1.3f}, Max Diff = {int(max_diff)}" - ) - else: - pytest.fail( - f"CuT not BE to REF! SNR : {snr:3.2f} dB, Gain CuT: {gain_b:1.3f}, Max Diff = {int(max_diff)}" - ) - - -def run_pyscripts( - in_fmt, - out_fmt, - metadata_input: Optional[str] = None, - in_meta_files: Optional[list] = None, - trj_file: Optional[str] = None, -) -> Tuple[np.ndarray, int]: - """Reference rendering with pyaudio3dtools""" - if trj_file is not None: - trj_name = f"_{trj_file.stem}" - else: - trj_name = "" - - if not isinstance(out_fmt, str): - out_name = f"{out_fmt.stem}" - else: - out_name = out_fmt - - if metadata_input is not None: - in_file = metadata_input - in_name = metadata_input.stem - elif isinstance(in_fmt, Path): - in_file = FORMAT_TO_FILE[in_fmt.stem] - in_name = in_fmt.stem - else: - in_file = FORMAT_TO_FILE[in_fmt] - in_name = in_fmt - - out_file = str(OUTPUT_PATH_REF.joinpath(f"{in_name}_to_{out_name}{trj_name}.wav")) - - pyaudio3dtools.spatialaudioconvert.spatial_audio_convert( - in_file, - out_file, - in_format=in_fmt, - out_format=out_fmt, - in_meta_files=in_meta_files, - trajectory=trj_file, - limit_output=True, - ) - - return pyaudio3dtools.audiofile.readfile(out_file) - - -def run_renderer( - in_fmt: str, - out_fmt: str, - metadata_input: Optional[str] = None, - in_meta_files: Optional[list] = None, - trj_file: Optional[str] = None, -) -> Tuple[np.ndarray, int]: - """CuT creation with standalone renderer""" - if trj_file is not None: - trj_name = f"_{trj_file.stem}" - else: - trj_name = "" - - if not isinstance(out_fmt, str): - out_name = f"{out_fmt.stem}" - else: - out_name = out_fmt - - if metadata_input is not None: - in_file = metadata_input - in_name = metadata_input.stem - elif not isinstance(in_fmt, str): - in_file = FORMAT_TO_FILE[in_fmt.stem] - in_name = in_fmt.stem - else: - in_file = FORMAT_TO_FILE[in_fmt] - in_name = in_fmt - - out_file = str(OUTPUT_PATH_CUT.joinpath(f"{in_name}_to_{out_name}{trj_name}.wav")) - - cmd = RENDERER_CMD[:] - cmd[2] = str(in_file) - cmd[4] = str(in_fmt) - cmd[6] = str(out_file) - cmd[8] = str(out_fmt) - - if in_meta_files is not None: - cmd[5:5] = ["-im", *in_meta_files] - - if trj_file is not None: - cmd.extend(["-tf", str(trj_file)]) - - try: - sp.run(cmd, check=True, capture_output=True, text=True) - except sp.CalledProcessError as e: - pytest.fail( - f"Command returned non-zero exit status ({e.returncode})!\n{' '.join(e.cmd)}\n{e.stderr}\n{e.stdout}\n{e.output}" - ) - - return pyaudio3dtools.audiofile.readfile(out_file) - - -def run_crend_unittest( - in_fmt: str, - out_fmt: str, - metadata_input: Optional[str] = None, - in_meta_files: Optional[list] = None, - trj_file: Optional[str] = None, -) -> Tuple[np.ndarray, int]: - """CuT creation with standalone renderer""" - if trj_file is not None: - trj_name = f"_{trj_file.stem}" - else: - trj_name = "" - - if not isinstance(out_fmt, str): - out_name = f"{out_fmt.stem}" - else: - out_name = out_fmt - - if metadata_input is not None: - in_file = metadata_input - in_name = metadata_input.stem - elif not isinstance(in_fmt, str): - in_file = FORMAT_TO_FILE[in_fmt.stem] - in_name = in_fmt.stem - else: - in_file = FORMAT_TO_FILE[in_fmt] - in_name = in_fmt - - out_file = str( - OUTPUT_PATH_REF.joinpath(f"{in_name}_to_{out_name}{trj_name}_crend.wav") - ) - - cmd = RENDERER_CREND_CMD[:] - cmd[6] = FORMAT_TO_CREND_FORMAT[str(in_fmt)] - cmd[8] = FORMAT_TO_CREND_FORMAT[str(out_fmt)] - cmd[10] = str(in_file) - cmd[12] = str(out_file) - if str(out_fmt) == "BINAURAL_ROOM": - cmd.append("-BRIR") - - # if in_meta_files is not None: - # cmd[5:5] = in_meta_files - - # if trj_file is not None: - # cmd.extend(["-tf", str(trj_file)]) - - try: - sp.run(cmd, check=True, capture_output=True, text=True) - except sp.CalledProcessError as e: - pytest.fail( - f"Command returned non-zero exit status ({e.returncode})!\n{' '.join(e.cmd)}\n{e.stderr}\n{e.stdout}\n{e.output}" - ) - - return pyaudio3dtools.audiofile.readfile(out_file) - - -def run_td_standalone( - in_fmt: str, - out_fmt: str, - metadata_input: Optional[str] = None, - in_meta_files: Optional[list] = None, - trj_file: Optional[str] = None, -): - """CuT creation with TD Object renderer""" - if trj_file is not None: - trj_name = f"_{trj_file.stem}" - else: - trj_name = "" - - if not isinstance(out_fmt, str): - out_name = f"{out_fmt.stem}" - else: - out_name = out_fmt - - if metadata_input is not None: - in_file = metadata_input - in_name = metadata_input.stem - elif not isinstance(in_fmt, str): - in_file = FORMAT_TO_FILE[in_fmt.stem] - in_name = in_fmt.stem - else: - in_file = FORMAT_TO_FILE[in_fmt] - in_name = in_fmt - - out_file = str(OUTPUT_PATH_REF.joinpath(f"{in_name}_to_{out_name}{trj_name}.pcm")) - - in_spfmt = pyaudio3dtools.spatialaudioformat.Format(in_fmt) - - with TemporaryDirectory() as tmp_dir: - # write PCM tmp file - tmp_dir = Path(tmp_dir) - in_file_pcm = tmp_dir.joinpath(in_file.stem + ".pcm") - - in_sig, _ = pyaudio3dtools.audiofile.readfile(in_file) - pyaudio3dtools.audiofile.writefile(in_file_pcm, in_sig) - - cmd = TDRENDERER_CMD[:] - cmd[2] = str(in_file_pcm) - cmd[3] = str(out_file) - - if in_spfmt.isloudspeaker: - cmd[1:1] = ["-mc", in_spfmt.name] - else: - cmd[1:1] = str(in_spfmt.nchannels) - if in_meta_files is not None: - cmd[2:2] = in_meta_files - else: - cmd[2:2] = ["NULL"] * in_spfmt.nchannels - - if trj_file is not None: - cmd[1:1] = ["-T", str(trj_file)] - - try: - sp.run(cmd, check=True, capture_output=True, text=True) - except sp.CalledProcessError as e: - pytest.fail( - f"Command returned non-zero exit status ({e.returncode})!\n{' '.join(e.cmd)}\n{e.stderr}\n{e.stdout}\n{e.output}" - ) - - return pyaudio3dtools.audiofile.readfile(out_file, nchannels=2) - - -# fixture returns test information, enabling per-testcase SNR -@pytest.fixture -def test_info(request): - return request - - -# Ambisonics / loudspeaker based input formats @pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS) @pytest.mark.parametrize("in_fmt", INPUT_FORMATS_AMBI) def test_ambisonics(test_info, in_fmt, out_fmt): - ref, ref_fs = run_pyscripts(in_fmt, out_fmt) + compare_renderer_vs_pyscripts(test_info, in_fmt, out_fmt) - cut, cut_fs = run_renderer(in_fmt, out_fmt) - check_BE(test_info, ref, ref_fs, cut, cut_fs) +@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL) +@pytest.mark.parametrize("in_fmt", INPUT_FORMATS_AMBI) +def test_ambisonics_binaural_static(test_info, in_fmt, out_fmt): + compare_renderer_vs_crend_unit_test(test_info, in_fmt, out_fmt) -@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS) -@pytest.mark.parametrize("in_fmt", INPUT_FORMATS_MC) -def test_multichannel(test_info, in_fmt, out_fmt): - ref, ref_fs = run_pyscripts(in_fmt, out_fmt) +@pytest.mark.parametrize("trj_file", HR_TRAJECTORIES_TO_TEST) +@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL) +@pytest.mark.parametrize("in_fmt", INPUT_FORMATS_AMBI) +def test_ambisonics_binaural_headrotation(test_info, in_fmt, out_fmt, trj_file): + compare_renderer_vs_pyscripts( + test_info, + in_fmt, + out_fmt, + trj_file=HR_TRAJECTORY_DIR.joinpath(f"{trj_file}.csv"), + ) - cut, cut_fs = run_renderer(in_fmt, out_fmt) - if out_fmt in ["MONO", "STEREO"]: - check_BE(test_info, ref, ref_fs, cut, cut_fs) - else: - check_BE(test_info, ref, ref_fs, cut, cut_fs) +""" Multichannel """ @pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS) -@pytest.mark.parametrize("in_layout", CUSTOM_LS_TO_TEST) -def test_custom_ls_input(test_info, in_layout, out_fmt): - ref, ref_fs = run_pyscripts( - CUSTOM_LAYOUT_DIR.joinpath(f"{in_layout}.txt"), - out_fmt, - ) - - cut, cut_fs = run_renderer(CUSTOM_LAYOUT_DIR.joinpath(f"{in_layout}.txt"), out_fmt) - - check_BE(test_info, ref, ref_fs, cut, cut_fs) +@pytest.mark.parametrize("in_fmt", INPUT_FORMATS_MC) +def test_multichannel(test_info, in_fmt, out_fmt): + compare_renderer_vs_pyscripts(test_info, in_fmt, out_fmt) -@pytest.mark.parametrize("out_fmt", CUSTOM_LS_TO_TEST) -@pytest.mark.parametrize("in_fmt", OUTPUT_FORMATS) -def test_custom_ls_output(test_info, in_fmt, out_fmt): - ref, ref_fs = run_pyscripts( - in_fmt, - CUSTOM_LAYOUT_DIR.joinpath(f"{out_fmt}.txt"), - ) +@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL) +@pytest.mark.parametrize("in_fmt", INPUT_FORMATS_MC) +def test_multichannel_binaural_static(test_info, in_fmt, out_fmt): + if in_fmt in ["MONO", "STEREO"]: + pytest.skip("MONO or STEREO to Binaural rendering unsupported") - cut, cut_fs = run_renderer(in_fmt, CUSTOM_LAYOUT_DIR.joinpath(f"{out_fmt}.txt")) + compare_renderer_vs_crend_unit_test(test_info, in_fmt, out_fmt) - check_BE(test_info, ref, ref_fs, cut, cut_fs) +@pytest.mark.parametrize("trj_file", HR_TRAJECTORIES_TO_TEST) +@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL) +@pytest.mark.parametrize("in_fmt", INPUT_FORMATS_MC) +def test_multichannel_binaural_headrotation(test_info, in_fmt, out_fmt, trj_file): + if in_fmt in ["MONO", "STEREO"]: + pytest.skip("MONO or STEREO to Binaural rendering unsupported") -@pytest.mark.parametrize("out_fmt", CUSTOM_LS_TO_TEST) -@pytest.mark.parametrize("in_fmt", CUSTOM_LS_TO_TEST) -def test_custom_ls_input_output(test_info, in_fmt, out_fmt): - ref, ref_fs = run_pyscripts( - CUSTOM_LAYOUT_DIR.joinpath(f"{in_fmt}.txt"), - CUSTOM_LAYOUT_DIR.joinpath(f"{out_fmt}.txt"), - ) + if (in_fmt == "5_1" or in_fmt == "7_1") and out_fmt == "BINAURAL": + compare_renderer_vs_td_standalone( + test_info, + in_fmt, + out_fmt, + trj_file=HR_TRAJECTORY_DIR.joinpath(f"{trj_file}.csv"), + ) + else: + compare_renderer_vs_pyscripts( + test_info, + in_fmt, + out_fmt, + trj_file=HR_TRAJECTORY_DIR.joinpath(f"{trj_file}.csv"), + ) - cut, cut_fs = run_renderer( - CUSTOM_LAYOUT_DIR.joinpath(f"{in_fmt}.txt"), - CUSTOM_LAYOUT_DIR.joinpath(f"{out_fmt}.txt"), - ) - check_BE(test_info, ref, ref_fs, cut, cut_fs) +""" ISM """ -# Metadata / parametric input formats @pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS) @pytest.mark.parametrize("in_fmt", INPUT_FORMATS_ISM) def test_ism(test_info, in_fmt, out_fmt): - ref, ref_fs = run_pyscripts( - in_fmt, out_fmt, in_meta_files=FORMAT_TO_METADATA_FILES[in_fmt] - ) - cut, cut_fs = run_renderer( - in_fmt, - out_fmt, - in_meta_files=FORMAT_TO_METADATA_FILES[in_fmt], + compare_renderer_vs_pyscripts( + test_info, in_fmt, out_fmt, in_meta_files=FORMAT_TO_METADATA_FILES[in_fmt] ) - check_BE(test_info, ref, ref_fs, cut, cut_fs) - - -# MASA inputs not supported yet -# @pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS) -# @pytest.mark.parametrize("in_fmt", INPUT_FORMATS_MASA) -# def test_masa(test_info, in_fmt, out_fmt): -# # TODO: implement MASA in Python, compare BE -# # ref, ref_fs = run_pyscripts( -# # in_fmt, out_fmt, in_meta_files=FORMAT_TO_METADATA_FILES[in_fmt] -# # ) - -# cut, cut_fs = run_renderer( -# in_fmt, -# out_fmt, -# in_meta_files=FORMAT_TO_METADATA_FILES[in_fmt], -# ) - -# # check_BE(test_info, ref, ref_fs, cut, cut_fs) - - -@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS) -@pytest.mark.parametrize("in_fmt", METADATA_SCENES_TO_TEST) -def test_metadata(test_info, in_fmt, out_fmt): - ref, ref_fs = run_pyscripts( - "META", out_fmt, metadata_input=TEST_VECTOR_DIR.joinpath(f"{in_fmt}.txt") - ) - - cut, cut_fs = run_renderer( - "META", - out_fmt, - metadata_input=TEST_VECTOR_DIR.joinpath(f"{in_fmt}.txt"), - ) - - check_BE(test_info, ref, ref_fs, cut, cut_fs) - - -# MASA inputs not supported yet -# @pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS) -# @pytest.mark.parametrize("in_fmt", METADATA_SCENES_TO_TEST_NO_BE) -# def test_metadata_masa(test_info, in_fmt, out_fmt): -# # TODO: unify with test_metadata once Python supports MASA -# cut, cut_fs = run_renderer( -# "META", -# out_fmt, -# metadata_input=TEST_VECTOR_DIR.joinpath(f"{in_fmt}.txt"), -# ) - - -# Binaural rendering (static) -@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL) -@pytest.mark.parametrize("in_fmt", INPUT_FORMATS_AMBI) -def test_ambisonics_binaural_static(test_info, in_fmt, out_fmt): - ref, ref_fs = run_pyscripts(in_fmt, out_fmt) - - cut, cut_fs = run_renderer(in_fmt, out_fmt) - - check_BE(test_info, ref, ref_fs, cut, cut_fs) - @pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL) @pytest.mark.parametrize("in_fmt", INPUT_FORMATS_ISM) @@ -454,55 +119,13 @@ def test_ism_binaural_static(test_info, in_fmt, out_fmt): in_meta_files = None if out_fmt == "BINAURAL": - ref, ref_fs = run_td_standalone(in_fmt, out_fmt, in_meta_files=in_meta_files) + compare_renderer_vs_td_standalone( + test_info, in_fmt, out_fmt, in_meta_files=in_meta_files + ) else: - ref, ref_fs = run_pyscripts(in_fmt, out_fmt, in_meta_files=in_meta_files) - - cut, cut_fs = run_renderer(in_fmt, out_fmt, in_meta_files=in_meta_files) - - check_BE(test_info, ref, ref_fs, cut, cut_fs) - - -@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL) -@pytest.mark.parametrize("in_fmt", INPUT_FORMATS_MC[2:]) -def test_multichannel_binaural_static(test_info, in_fmt, out_fmt): - ref, ref_fs = run_pyscripts(in_fmt, out_fmt) - - cut, cut_fs = run_renderer(in_fmt, out_fmt) - - check_BE(test_info, ref, ref_fs, cut, cut_fs) - - -@pytest.mark.skip("Skip CREND unit test comparison until ASAN issues are fixed") -@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL) -@pytest.mark.parametrize("in_fmt", INPUT_FORMATS_MC[2:]) -def test_multichannel_binaural_static_vs_crend_unittest(test_info, in_fmt, out_fmt): - - crend, crend_fs = run_crend_unittest(in_fmt, out_fmt) - - cut, cut_fs = run_renderer(in_fmt, out_fmt) - - check_BE(test_info, cut, cut_fs, crend, crend_fs) - - -# Binaural rendering (head rotation) -@pytest.mark.parametrize("trj_file", HR_TRAJECTORIES_TO_TEST) -@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL) -@pytest.mark.parametrize("in_fmt", INPUT_FORMATS_AMBI) -def test_ambisonics_binaural_headrotation(test_info, in_fmt, out_fmt, trj_file): - ref, ref_fs = run_pyscripts( - in_fmt, - out_fmt, - trj_file=HR_TRAJECTORY_DIR.joinpath(f"{trj_file}.csv"), - ) - - cut, cut_fs = run_renderer( - in_fmt, - out_fmt, - trj_file=HR_TRAJECTORY_DIR.joinpath(f"{trj_file}.csv"), - ) - - check_BE(test_info, ref, ref_fs, cut, cut_fs) + compare_renderer_vs_pyscripts( + test_info, in_fmt, out_fmt, in_meta_files=in_meta_files + ) @pytest.mark.parametrize("trj_file", HR_TRAJECTORIES_TO_TEST) @@ -515,211 +138,107 @@ def test_ism_binaural_headrotation(test_info, in_fmt, out_fmt, trj_file): in_meta_files = None if out_fmt == "BINAURAL": - ref, ref_fs = run_td_standalone( + compare_renderer_vs_td_standalone( + test_info, in_fmt, out_fmt, trj_file=HR_TRAJECTORY_DIR.joinpath(f"{trj_file}.csv"), in_meta_files=in_meta_files, ) else: - ref, ref_fs = run_pyscripts( + compare_renderer_vs_pyscripts( + test_info, in_fmt, out_fmt, trj_file=HR_TRAJECTORY_DIR.joinpath(f"{trj_file}.csv"), in_meta_files=in_meta_files, ) - cut, cut_fs = run_renderer( - in_fmt, - out_fmt, - trj_file=HR_TRAJECTORY_DIR.joinpath(f"{trj_file}.csv"), - in_meta_files=in_meta_files, - ) - check_BE(test_info, ref, ref_fs, cut, cut_fs) +""" MASA """ +# # MASA inputs not supported yet +# @pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS) +# @pytest.mark.parametrize("in_fmt", INPUT_FORMATS_MASA) +# def test_masa(test_info, in_fmt, out_fmt): +# # TODO: implement MASA in Python, compare BE +# compare_renderer_vs_pyscripts( test_info, in_fmt, out_fmt, in_meta_files=FORMAT_TO_METADATA_FILES[in_fmt] +# ) -@pytest.mark.parametrize("trj_file", HR_TRAJECTORIES_TO_TEST) -@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL) -@pytest.mark.parametrize("in_fmt", INPUT_FORMATS_MC[2:]) -def test_multichannel_binaural_headrotation(test_info, in_fmt, out_fmt, trj_file): +# MASA inputs not supported yet +# @pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS) +# @pytest.mark.parametrize("in_fmt", METADATA_SCENES_TO_TEST_NO_BE) +# def test_metadata_masa(test_info, in_fmt, out_fmt): +# # TODO: unify with test_metadata once Python supports MASA +# cut, cut_fs = run_renderer( +# "META", +# out_fmt, +# metadata_input=TEST_VECTOR_DIR.joinpath(f"{in_fmt}.txt"), +# ) + + +""" Custom loudspeaker layouts """ - if (in_fmt == "5_1" or in_fmt == "7_1") and out_fmt == "BINAURAL": - ref, ref_fs = run_td_standalone( - in_fmt, - out_fmt, - trj_file=HR_TRAJECTORY_DIR.joinpath(f"{trj_file}.csv"), - ) - else: - ref, ref_fs = run_pyscripts( - in_fmt, - out_fmt, - trj_file=HR_TRAJECTORY_DIR.joinpath(f"{trj_file}.csv"), - ) - cut, cut_fs = run_renderer( +@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS) +@pytest.mark.parametrize("in_layout", CUSTOM_LS_TO_TEST) +def test_custom_ls_input(test_info, in_layout, out_fmt): + compare_renderer_vs_pyscripts( + test_info, CUSTOM_LAYOUT_DIR.joinpath(f"{in_layout}.txt"), out_fmt + ) + + +@pytest.mark.parametrize("out_fmt", CUSTOM_LS_TO_TEST) +@pytest.mark.parametrize("in_fmt", OUTPUT_FORMATS) +def test_custom_ls_output(test_info, in_fmt, out_fmt): + compare_renderer_vs_pyscripts( + test_info, in_fmt, - out_fmt, - trj_file=HR_TRAJECTORY_DIR.joinpath(f"{trj_file}.csv"), + CUSTOM_LAYOUT_DIR.joinpath(f"{out_fmt}.txt"), ) - check_BE(test_info, ref, ref_fs, cut, cut_fs) + +@pytest.mark.parametrize("out_fmt", CUSTOM_LS_TO_TEST) +@pytest.mark.parametrize("in_fmt", CUSTOM_LS_TO_TEST) +def test_custom_ls_input_output(test_info, in_fmt, out_fmt): + compare_renderer_vs_pyscripts( + test_info, + CUSTOM_LAYOUT_DIR.joinpath(f"{in_fmt}.txt"), + CUSTOM_LAYOUT_DIR.joinpath(f"{out_fmt}.txt"), + ) @pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL) @pytest.mark.parametrize("in_layout", CUSTOM_LS_TO_TEST) def test_custom_ls_input_binaural(test_info, in_layout, out_fmt): - ref, ref_fs = run_pyscripts( + compare_renderer_vs_pyscripts( + test_info, CUSTOM_LAYOUT_DIR.joinpath(f"{in_layout}.txt"), out_fmt, ) - cut, cut_fs = run_renderer(CUSTOM_LAYOUT_DIR.joinpath(f"{in_layout}.txt"), out_fmt) - - check_BE(test_info, ref, ref_fs, cut, cut_fs) - @pytest.mark.parametrize("trj_file", HR_TRAJECTORIES_TO_TEST) @pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL) @pytest.mark.parametrize("in_layout", CUSTOM_LS_TO_TEST) def test_custom_ls_input_binaural_headrotation(test_info, in_layout, out_fmt, trj_file): - ref, ref_fs = run_pyscripts( + compare_renderer_vs_pyscripts( + test_info, CUSTOM_LAYOUT_DIR.joinpath(f"{in_layout}.txt"), out_fmt, trj_file=HR_TRAJECTORY_DIR.joinpath(f"{trj_file}.csv"), ) - cut, cut_fs = run_renderer( - CUSTOM_LAYOUT_DIR.joinpath(f"{in_layout}.txt"), + +""" Metadata / scene description input """ + + +@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS) +@pytest.mark.parametrize("in_fmt", METADATA_SCENES_TO_TEST) +def test_metadata(test_info, in_fmt, out_fmt): + compare_renderer_vs_pyscripts( + test_info, + "META", out_fmt, - trj_file=HR_TRAJECTORY_DIR.joinpath(f"{trj_file}.csv"), + metadata_input=TEST_VECTOR_DIR.joinpath(f"{in_fmt}.txt"), ) - - check_BE(test_info, ref, ref_fs, cut, cut_fs) - - -# per-testcase passing SNR -pass_snr = { - "test_ambisonics_binaural_headrotation[FOA-BINAURAL_ROOM-full_circle_in_15s]": 0.6, - "test_ambisonics_binaural_headrotation[FOA-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 0.1, - "test_ambisonics_binaural_headrotation[HOA2-BINAURAL-full_circle_in_15s]": 18, - "test_ambisonics_binaural_headrotation[HOA2-BINAURAL-rotate_yaw_pitch_roll1]": 4, - "test_ambisonics_binaural_headrotation[HOA2-BINAURAL_ROOM-full_circle_in_15s]": 0.4, - "test_ambisonics_binaural_headrotation[HOA2-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 0.04, - "test_ambisonics_binaural_headrotation[HOA3-BINAURAL-full_circle_in_15s]": 15, - "test_ambisonics_binaural_headrotation[HOA3-BINAURAL-rotate_yaw_pitch_roll1]": 3, - "test_ambisonics_binaural_headrotation[HOA3-BINAURAL_ROOM-full_circle_in_15s]": 0.4, - "test_ambisonics_binaural_headrotation[HOA3-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 0.05, - "test_ambisonics_binaural_static[FOA-BINAURAL_ROOM]": 0.6, - "test_ambisonics_binaural_static[HOA2-BINAURAL_ROOM]": 0.5, - "test_ambisonics_binaural_static[HOA3-BINAURAL_ROOM]": 0.1, - "test_custom_ls_input_binaural[16ch_8+4+4-BINAURAL]": 0, - "test_custom_ls_input_binaural[16ch_8+4+4-BINAURAL_ROOM]": 0, - "test_custom_ls_input_binaural[4d4-BINAURAL]": 0.2, - "test_custom_ls_input_binaural[4d4-BINAURAL_ROOM]": 0, - "test_custom_ls_input_binaural[custom1-BINAURAL]": 0.2, - "test_custom_ls_input_binaural[custom1-BINAURAL_ROOM]": 0, - "test_custom_ls_input_binaural[itu_4+5+1-BINAURAL]": 0, - "test_custom_ls_input_binaural[itu_4+5+1-BINAURAL_ROOM]": 3, - "test_custom_ls_input_binaural[t_design_4-BINAURAL]": 0, - "test_custom_ls_input_binaural[t_design_4-BINAURAL_ROOM]": 0, - "test_custom_ls_input_binaural_headrotation[16ch_8+4+4-BINAURAL-full_circle_in_15s]": 0, - "test_custom_ls_input_binaural_headrotation[16ch_8+4+4-BINAURAL-rotate_yaw_pitch_roll1]": 0, - "test_custom_ls_input_binaural_headrotation[16ch_8+4+4-BINAURAL_ROOM-full_circle_in_15s]": 0, - "test_custom_ls_input_binaural_headrotation[16ch_8+4+4-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 0, - "test_custom_ls_input_binaural_headrotation[4d4-BINAURAL-full_circle_in_15s]": 0.1, - "test_custom_ls_input_binaural_headrotation[4d4-BINAURAL-rotate_yaw_pitch_roll1]": 0, - "test_custom_ls_input_binaural_headrotation[4d4-BINAURAL_ROOM-full_circle_in_15s]": 0, - "test_custom_ls_input_binaural_headrotation[4d4-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 0, - "test_custom_ls_input_binaural_headrotation[custom1-BINAURAL-full_circle_in_15s]": 0, - "test_custom_ls_input_binaural_headrotation[custom1-BINAURAL-rotate_yaw_pitch_roll1]": 0, - "test_custom_ls_input_binaural_headrotation[custom1-BINAURAL_ROOM-full_circle_in_15s]": 0, - "test_custom_ls_input_binaural_headrotation[custom1-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 0, - "test_custom_ls_input_binaural_headrotation[itu_4+5+1-BINAURAL-full_circle_in_15s]": 0, - "test_custom_ls_input_binaural_headrotation[itu_4+5+1-BINAURAL-rotate_yaw_pitch_roll1]": 0, - "test_custom_ls_input_binaural_headrotation[itu_4+5+1-BINAURAL_ROOM-full_circle_in_15s]": 3, - "test_custom_ls_input_binaural_headrotation[itu_4+5+1-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 3, - "test_custom_ls_input_binaural_headrotation[t_design_4-BINAURAL-full_circle_in_15s]": 0.1, - "test_custom_ls_input_binaural_headrotation[t_design_4-BINAURAL-rotate_yaw_pitch_roll1]": 0, - "test_custom_ls_input_binaural_headrotation[t_design_4-BINAURAL_ROOM-full_circle_in_15s]": 0, - "test_custom_ls_input_binaural_headrotation[t_design_4-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 0, - "test_ism[ISM1-FOA]": 45, - "test_ism[ISM1-HOA2]": 41, - "test_ism[ISM1-HOA3]": 38, - "test_ism[ISM2-FOA]": 45, - "test_ism[ISM2-HOA2]": 41, - "test_ism[ISM2-HOA3]": 38, - "test_ism[ISM3-FOA]": 45, - "test_ism[ISM3-HOA2]": 41, - "test_ism[ISM3-HOA3]": 38, - "test_ism[ISM4-FOA]": 45, - "test_ism[ISM4-HOA2]": 41, - "test_ism[ISM4-HOA3]": 38, - "test_ism_binaural_headrotation[ISM1-BINAURAL-full_circle_in_15s]": 0, - "test_ism_binaural_headrotation[ISM1-BINAURAL-rotate_yaw_pitch_roll1]": 0, - "test_ism_binaural_headrotation[ISM1-BINAURAL_ROOM-full_circle_in_15s]": 6.7, - "test_ism_binaural_headrotation[ISM1-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 2, - "test_ism_binaural_headrotation[ISM2-BINAURAL-full_circle_in_15s]": 0, - "test_ism_binaural_headrotation[ISM2-BINAURAL-rotate_yaw_pitch_roll1]": 0, - "test_ism_binaural_headrotation[ISM2-BINAURAL_ROOM-full_circle_in_15s]": 4, - "test_ism_binaural_headrotation[ISM2-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 1, - "test_ism_binaural_headrotation[ISM3-BINAURAL-full_circle_in_15s]": 0, - "test_ism_binaural_headrotation[ISM3-BINAURAL-rotate_yaw_pitch_roll1]": 0, - "test_ism_binaural_headrotation[ISM3-BINAURAL_ROOM-full_circle_in_15s]": 4, - "test_ism_binaural_headrotation[ISM3-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 1, - "test_ism_binaural_headrotation[ISM4-BINAURAL-full_circle_in_15s]": 0, - "test_ism_binaural_headrotation[ISM4-BINAURAL-rotate_yaw_pitch_roll1]": 0, - "test_ism_binaural_headrotation[ISM4-BINAURAL_ROOM-full_circle_in_15s]": 3.9, - "test_ism_binaural_headrotation[ISM4-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 1, - "test_ism_binaural_static[ISM1-BINAURAL]": 0.00, - "test_ism_binaural_static[ISM1-BINAURAL_ROOM]": 18, - "test_ism_binaural_static[ISM2-BINAURAL]": 0, - "test_ism_binaural_static[ISM2-BINAURAL_ROOM]": 19, - "test_ism_binaural_static[ISM3-BINAURAL]": 0, - "test_ism_binaural_static[ISM3-BINAURAL_ROOM]": 19, - "test_ism_binaural_static[ISM4-BINAURAL]": 0, - "test_ism_binaural_static[ISM4-BINAURAL_ROOM]": 19, - "test_metadata[mixed_scene-5_1_4]": 11, - "test_metadata[mixed_scene-MONO]": 13, - "test_metadata[mixed_scene-STEREO]": 12, - "test_multichannel_binaural_headrotation[5_1-BINAURAL-full_circle_in_15s]": 0, - "test_multichannel_binaural_headrotation[5_1-BINAURAL-rotate_yaw_pitch_roll1]": 0, - "test_multichannel_binaural_headrotation[5_1-BINAURAL_ROOM-full_circle_in_15s]": 0, - "test_multichannel_binaural_headrotation[5_1-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 0, - "test_multichannel_binaural_headrotation[5_1_2-BINAURAL-full_circle_in_15s]": 3, - "test_multichannel_binaural_headrotation[5_1_2-BINAURAL-rotate_yaw_pitch_roll1]": 0.7, - "test_multichannel_binaural_headrotation[5_1_2-BINAURAL_ROOM-full_circle_in_15s]": 0, - "test_multichannel_binaural_headrotation[5_1_2-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 1, - "test_multichannel_binaural_headrotation[5_1_4-BINAURAL-full_circle_in_15s]": 3.1, - "test_multichannel_binaural_headrotation[5_1_4-BINAURAL-rotate_yaw_pitch_roll1]": 0.7, - "test_multichannel_binaural_headrotation[5_1_4-BINAURAL_ROOM-full_circle_in_15s]": 0, - "test_multichannel_binaural_headrotation[5_1_4-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 1, - "test_multichannel_binaural_headrotation[7_1-BINAURAL-full_circle_in_15s]": 0, - "test_multichannel_binaural_headrotation[7_1-BINAURAL-rotate_yaw_pitch_roll1]": 0, - "test_multichannel_binaural_headrotation[7_1-BINAURAL_ROOM-full_circle_in_15s]": 0, - "test_multichannel_binaural_headrotation[7_1-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 0, - "test_multichannel_binaural_headrotation[7_1_4-BINAURAL-full_circle_in_15s]": 2, - "test_multichannel_binaural_headrotation[7_1_4-BINAURAL-rotate_yaw_pitch_roll1]": 0.7, - "test_multichannel_binaural_headrotation[7_1_4-BINAURAL_ROOM-full_circle_in_15s]": 0, - "test_multichannel_binaural_headrotation[7_1_4-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 1, - "test_multichannel_binaural_static[5_1-BINAURAL]": 6, - "test_multichannel_binaural_static[5_1-BINAURAL_ROOM]": 1, - "test_multichannel_binaural_static[5_1_2-BINAURAL]": 7.5, - "test_multichannel_binaural_static[5_1_2-BINAURAL_ROOM]": 1, - "test_multichannel_binaural_static[5_1_4-BINAURAL]": 7, - "test_multichannel_binaural_static[5_1_4-BINAURAL_ROOM]": 1, - "test_multichannel_binaural_static[7_1-BINAURAL]": 6, - "test_multichannel_binaural_static[7_1-BINAURAL_ROOM]": 1, - "test_multichannel_binaural_static[7_1_4-BINAURAL]": 7, - "test_multichannel_binaural_static[7_1_4-BINAURAL_ROOM]": 1, - "test_multichannel_binaural_static_vs_crend_unittest[5_1-BINAURAL]": 23, - "test_multichannel_binaural_static_vs_crend_unittest[5_1-BINAURAL_ROOM]": 38, - "test_multichannel_binaural_static_vs_crend_unittest[5_1_2-BINAURAL]": 24, - "test_multichannel_binaural_static_vs_crend_unittest[5_1_2-BINAURAL_ROOM]": 37, - "test_multichannel_binaural_static_vs_crend_unittest[5_1_4-BINAURAL]": 23, - "test_multichannel_binaural_static_vs_crend_unittest[5_1_4-BINAURAL_ROOM]": 36, - "test_multichannel_binaural_static_vs_crend_unittest[7_1-BINAURAL]": 24, - "test_multichannel_binaural_static_vs_crend_unittest[7_1-BINAURAL_ROOM]": 37, - "test_multichannel_binaural_static_vs_crend_unittest[7_1_4-BINAURAL]": 23, - "test_multichannel_binaural_static_vs_crend_unittest[7_1_4-BINAURAL_ROOM]": 36, -} diff --git a/tests/renderer/test_renderer_vs_decoder.py b/tests/renderer/test_renderer_vs_decoder.py new file mode 100644 index 0000000000..cd88580d9b --- /dev/null +++ b/tests/renderer/test_renderer_vs_decoder.py @@ -0,0 +1,128 @@ +#!/usr/bin/env python3 + +""" + (C) 2022 Baseline Development Group 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 Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The Baseline Development Group 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 Corporation, Qualcomm Technologies, Inc., and VoiceAge Corporation retain full ownership + rights in their respective contributions in the software. No license of any kind, including but not + limited to patent license, of any foregoing parties is hereby granted by implication, estoppel or + otherwise. + + 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/or 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. +""" + +from .utils import * + +""" Ambisonics """ + + +@pytest.mark.skip("Ambisonics comparison requires CLDFB interface") +@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS) +@pytest.mark.parametrize("in_fmt", INPUT_FORMATS_AMBI) +def test_ambisonics_vs_decoder(test_info, in_fmt, out_fmt): + compare_renderer_vs_decoder(test_info, in_fmt, out_fmt) + + +@pytest.mark.skip("Ambisonics comparison requires CLDFB interface") +@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL) +@pytest.mark.parametrize("in_fmt", INPUT_FORMATS_AMBI) +def test_ambisonics_binaural_static_vs_decoder(test_info, in_fmt, out_fmt): + compare_renderer_vs_decoder(test_info, in_fmt, out_fmt) + + +@pytest.mark.skip("Ambisonics comparison requires CLDFB interface") +@pytest.mark.parametrize("trj_file", HR_TRAJECTORIES_TO_TEST) +@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL) +@pytest.mark.parametrize("in_fmt", INPUT_FORMATS_AMBI) +def test_ambisonics_binaural_headrotation_vs_decoder( + test_info, in_fmt, out_fmt, trj_file +): + compare_renderer_vs_decoder( + test_info, + in_fmt, + out_fmt, + trj_file=HR_TRAJECTORY_DIR.joinpath(f"{trj_file}.csv"), + ) + + +""" Multichannel """ + + +@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS) +@pytest.mark.parametrize("in_fmt", INPUT_FORMATS_MC) +def test_multichannel_vs_decoder(test_info, in_fmt, out_fmt): + if in_fmt == "MONO": + pytest.skip("(EVS) Mono decoder rendering unsupported") + + if in_fmt == "STEREO" and out_fmt in ["FOA", "HOA2", "HOA3"]: + pytest.skip("Stereo to Ambisonics rendering unsupported in the decoder") + + compare_renderer_vs_decoder(test_info, in_fmt, out_fmt) + + +@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL) +@pytest.mark.parametrize("in_fmt", INPUT_FORMATS_MC) +def test_multichannel_binaural_static_vs_decoder(test_info, in_fmt, out_fmt): + if in_fmt in ["MONO", "STEREO"]: + pytest.skip("MONO or STEREO to Binaural rendering unsupported") + + compare_renderer_vs_decoder(test_info, in_fmt, out_fmt) + + +@pytest.mark.parametrize("trj_file", HR_TRAJECTORIES_TO_TEST) +@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL) +@pytest.mark.parametrize("in_fmt", INPUT_FORMATS_MC) +def test_multichannel_binaural_headrotation_vs_decoder( + test_info, in_fmt, out_fmt, trj_file +): + if in_fmt in ["MONO", "STEREO"]: + pytest.skip("MONO or STEREO to Binaural rendering unsupported") + + compare_renderer_vs_decoder( + test_info, + in_fmt, + out_fmt, + trj_file=HR_TRAJECTORY_DIR.joinpath(f"{trj_file}.csv"), + ) + + +""" ISM """ + + +@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS) +@pytest.mark.parametrize("in_fmt", INPUT_FORMATS_ISM) +def test_ism_vs_decoder(test_info, in_fmt, out_fmt): + compare_renderer_vs_decoder(test_info, in_fmt, out_fmt) + + +@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL) +@pytest.mark.parametrize("in_fmt", INPUT_FORMATS_ISM) +def test_ism_binaural_static_vs_decoder(test_info, in_fmt, out_fmt): + compare_renderer_vs_decoder(test_info, in_fmt, out_fmt) + + +@pytest.mark.parametrize("trj_file", HR_TRAJECTORIES_TO_TEST) +@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL) +@pytest.mark.parametrize("in_fmt", INPUT_FORMATS_ISM) +def test_ism_binaural_headrotation_vs_decoder(test_info, in_fmt, out_fmt, trj_file): + compare_renderer_vs_decoder( + test_info, + in_fmt, + out_fmt, + trj_file=HR_TRAJECTORY_DIR.joinpath(f"{trj_file}.csv"), + ) diff --git a/tests/renderer/utils.py b/tests/renderer/utils.py new file mode 100644 index 0000000000..92d017c43a --- /dev/null +++ b/tests/renderer/utils.py @@ -0,0 +1,439 @@ +#!/usr/bin/env python3 + +""" + (C) 2022 Baseline Development Group 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 Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The Baseline Development Group 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 Corporation, Qualcomm Technologies, Inc., and VoiceAge Corporation retain full ownership + rights in their respective contributions in the software. No license of any kind, including but not + limited to patent license, of any foregoing parties is hereby granted by implication, estoppel or + otherwise. + + 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/or 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. +""" + +import subprocess as sp +import sys +from pathlib import Path +from tempfile import TemporaryDirectory +from typing import Optional, Tuple + +import numpy as np +import pytest + + +from .compare_audio import compare_audio_arrays +from .constants import * + +sys.path.append(SCRIPTS_DIR) +import pyaudio3dtools + +# fixture returns test information, enabling per-testcase SNR +@pytest.fixture +def test_info(request): + return request + + +def run_cmd(cmd): + try: + sp.run(cmd, check=True, capture_output=True, text=True) + except sp.CalledProcessError as e: + raise SystemError( + f"Command returned non-zero exit status ({e.returncode}): {' '.join(e.cmd)}\n{e.stderr}\n{e.stdout}" + ) + + +def check_BE( + test_info, + ref: np.ndarray, + ref_fs: int, + cut: np.ndarray, + cut_fs: int, +): + + if ref is None or np.array_equal(ref, np.zeros_like(ref)): + pytest.fail("REF signal does not exist or is zero!") + + if cut is None or np.array_equal(cut, np.zeros_like(cut)): + pytest.fail("CuT signal does not exist or is zero!") + + snr, gain_b, max_diff = compare_audio_arrays(ref, ref_fs, cut, cut_fs) + + if np.isnan(snr) or gain_b == 0: + pytest.fail("Invalid comparison result, check your signals!") + + # try to get a minimum SNR from the config + if test_info.node.name in pass_snr: + snr_min = pass_snr.get(test_info.node.name) + else: + snr_min = np.inf + + # TODO temporary fix to pad TD Object Renderer Standalone output + if ref.shape != cut.shape: + ref = np.pad(ref, [(0, cut.shape[0] - ref.shape[0]), (0, 0)]) + + # check max_diff as well, since compare_audio_arrays will try to adjust for small delay differences + if not np.allclose(ref, cut, rtol=0, atol=2) and max_diff > 2: + if snr >= snr_min: + pytest.xfail( + f"Expected failure with minimum SNR {snr_min} vs {snr:3.2f}dB, Gain CuT: {gain_b:1.3f}, Max Diff = {int(max_diff)}" + ) + else: + pytest.fail( + f"CuT not BE to REF! SNR : {snr:3.2f} dB, Gain CuT: {gain_b:1.3f}, Max Diff = {int(max_diff)}" + ) + + +def run_enc( + in_fmt: str, + bit_file: str, + in_meta_files: Optional[list] = None, +) -> None: + + cmd = IVAS_COD_CMD[:] + cmd[1] = FORMAT_TO_IVAS[in_fmt][0] + cmd[2] = FORMAT_TO_IVAS[in_fmt][1] + cmd[3] = FORMAT_TO_IVAS_BR[in_fmt] + cmd[5] = str(FORMAT_TO_FILE[in_fmt]) + cmd[6] = bit_file + + if in_meta_files is not None: + cmd[3:3] = [*in_meta_files] + + if in_fmt == "MONO": + cmd.pop(1) + cmd.pop(1) + elif in_fmt == "STEREO": + cmd.pop(2) + + run_cmd(cmd) + + +def run_dec( + bit_file: str, + out_file: str, + out_fmt: str, + trj_file: Optional[str] = None, +) -> Tuple[np.ndarray, int]: + + cmd = IVAS_DEC_CMD[:] + cmd[2] = out_fmt + cmd[4] = bit_file + cmd[5] = out_file + + if trj_file is not None and out_fmt in ["BINAURAL", "BINAURAL_ROOM"]: + cmd[1:1] = ["-T", str(trj_file)] + + run_cmd(cmd) + + return pyaudio3dtools.audiofile.readfile(out_file) + + +def run_renderer( + in_fmt: str, + out_fmt: str, + metadata_input: Optional[str] = None, + in_meta_files: Optional[list] = None, + trj_file: Optional[str] = None, +) -> Tuple[np.ndarray, int]: + """CuT creation with standalone renderer""" + if trj_file is not None: + trj_name = f"_{trj_file.stem}" + else: + trj_name = "" + + if not isinstance(out_fmt, str): + out_name = f"{out_fmt.stem}" + else: + out_name = out_fmt + + if metadata_input is not None: + in_file = metadata_input + in_name = metadata_input.stem + elif not isinstance(in_fmt, str): + in_file = FORMAT_TO_FILE[in_fmt.stem] + in_name = in_fmt.stem + else: + in_file = FORMAT_TO_FILE[in_fmt] + in_name = in_fmt + + out_file = str(OUTPUT_PATH_CUT.joinpath(f"{in_name}_to_{out_name}{trj_name}.wav")) + + cmd = RENDERER_CMD[:] + cmd[2] = str(in_file) + cmd[4] = str(in_fmt) + cmd[6] = str(out_file) + cmd[8] = str(out_fmt) + + if in_meta_files is not None: + cmd[5:5] = ["-im", *in_meta_files] + + if trj_file is not None: + cmd.extend(["-tf", str(trj_file)]) + + run_cmd(cmd) + + return pyaudio3dtools.audiofile.readfile(out_file) + + +def run_renderer_ext( + in_file: str, + in_fmt: str, + out_fmt: str, + in_meta_files: Optional[list] = None, + trj_file: Optional[str] = None, +) -> Tuple[np.ndarray, int]: + """Run renderer with decoder float dump""" + if trj_file is not None: + trj_name = f"_{trj_file.stem}" + else: + trj_name = "" + + if not isinstance(out_fmt, str): + out_name = f"{out_fmt.stem}" + else: + out_name = out_fmt + + in_name = in_fmt + + out_file = str(OUTPUT_PATH_CUT.joinpath(f"{in_name}_to_{out_name}{trj_name}.wav")) + + cmd = RENDERER_CMD[:] + cmd[2] = str(in_file) + cmd[4] = str(in_fmt) + cmd[6] = str(out_file) + cmd[8] = str(out_fmt) + + if in_meta_files is not None: + cmd[5:5] = ["-im", *in_meta_files] + + if trj_file is not None: + cmd.extend(["-tf", str(trj_file)]) + + run_cmd(cmd) + + return pyaudio3dtools.audiofile.readfile(out_file) + + +def run_crend_unittest( + in_fmt: str, + out_fmt: str, + metadata_input: Optional[str] = None, + in_meta_files: Optional[list] = None, + trj_file: Optional[str] = None, +) -> Tuple[np.ndarray, int]: + """CuT creation with standalone renderer""" + if trj_file is not None: + trj_name = f"_{trj_file.stem}" + else: + trj_name = "" + + if not isinstance(out_fmt, str): + out_name = f"{out_fmt.stem}" + else: + out_name = out_fmt + + if metadata_input is not None: + in_file = metadata_input + in_name = metadata_input.stem + elif not isinstance(in_fmt, str): + in_file = FORMAT_TO_FILE[in_fmt.stem] + in_name = in_fmt.stem + else: + in_file = FORMAT_TO_FILE[in_fmt] + in_name = in_fmt + + out_file = str( + OUTPUT_PATH_REF.joinpath(f"{in_name}_to_{out_name}{trj_name}_crend.wav") + ) + + cmd = RENDERER_CREND_CMD[:] + cmd[6] = FORMAT_TO_CREND_FORMAT[str(in_fmt)] + cmd[8] = FORMAT_TO_CREND_FORMAT[str(out_fmt)] + cmd[10] = str(in_file) + cmd[12] = str(out_file) + if str(out_fmt) == "BINAURAL_ROOM": + cmd.append("-brir") + + if trj_file is not None: + cmd.extend(["-t", str(trj_file)]) + cmd.extend(["-otr", "REF"]) + + run_cmd(cmd) + + return pyaudio3dtools.audiofile.readfile(out_file) + + +def run_td_standalone( + in_fmt: str, + out_fmt: str, + metadata_input: Optional[str] = None, + in_meta_files: Optional[list] = None, + trj_file: Optional[str] = None, +): + """CuT creation with TD Object renderer""" + if trj_file is not None: + trj_name = f"_{trj_file.stem}" + else: + trj_name = "" + + if not isinstance(out_fmt, str): + out_name = f"{out_fmt.stem}" + else: + out_name = out_fmt + + if metadata_input is not None: + in_file = metadata_input + in_name = metadata_input.stem + elif not isinstance(in_fmt, str): + in_file = FORMAT_TO_FILE[in_fmt.stem] + in_name = in_fmt.stem + else: + in_file = FORMAT_TO_FILE[in_fmt] + in_name = in_fmt + + out_file = str(OUTPUT_PATH_REF.joinpath(f"{in_name}_to_{out_name}{trj_name}.pcm")) + + in_spfmt = pyaudio3dtools.spatialaudioformat.Format(in_fmt) + + with TemporaryDirectory() as tmp_dir: + # write PCM tmp file + tmp_dir = Path(tmp_dir) + in_file_pcm = tmp_dir.joinpath(in_file.stem + ".pcm") + + in_sig, _ = pyaudio3dtools.audiofile.readfile(in_file) + pyaudio3dtools.audiofile.writefile(in_file_pcm, in_sig) + + cmd = TDRENDERER_CMD[:] + cmd[2] = str(in_file_pcm) + cmd[3] = str(out_file) + + if in_spfmt.isloudspeaker: + cmd[1:1] = ["-mc", in_spfmt.name] + else: + cmd[1:1] = str(in_spfmt.nchannels) + if in_meta_files is not None: + cmd[2:2] = in_meta_files + else: + cmd[2:2] = ["NULL"] * in_spfmt.nchannels + + if trj_file is not None: + cmd[1:1] = ["-T", str(trj_file)] + + run_cmd(cmd) + + return pyaudio3dtools.audiofile.readfile(out_file, nchannels=2) + + +def run_pyscripts( + in_fmt, + out_fmt, + metadata_input: Optional[str] = None, + in_meta_files: Optional[list] = None, + trj_file: Optional[str] = None, +) -> Tuple[np.ndarray, int]: + """Reference rendering with pyaudio3dtools""" + if trj_file is not None: + trj_name = f"_{trj_file.stem}" + else: + trj_name = "" + + if not isinstance(out_fmt, str): + out_name = f"{out_fmt.stem}" + else: + out_name = out_fmt + + if metadata_input is not None: + in_file = metadata_input + in_name = metadata_input.stem + elif isinstance(in_fmt, Path): + in_file = FORMAT_TO_FILE[in_fmt.stem] + in_name = in_fmt.stem + else: + in_file = FORMAT_TO_FILE[in_fmt] + in_name = in_fmt + + out_file = str(OUTPUT_PATH_REF.joinpath(f"{in_name}_to_{out_name}{trj_name}.wav")) + + pyaudio3dtools.spatialaudioconvert.spatial_audio_convert( + in_file, + out_file, + in_format=in_fmt, + out_format=out_fmt, + in_meta_files=in_meta_files, + trajectory=trj_file, + limit_output=True, + ) + + return pyaudio3dtools.audiofile.readfile(out_file) + + +def compare_renderer_vs_pyscripts(test_info, in_fmt, out_fmt, **kwargs): + ref, ref_fs = run_pyscripts(in_fmt, out_fmt, **kwargs) + cut, cut_fs = run_renderer(in_fmt, out_fmt, **kwargs) + check_BE(test_info, ref, ref_fs, cut, cut_fs) + + +def compare_renderer_vs_crend_unit_test(test_info, in_fmt, out_fmt, **kwargs): + ref, ref_fs = run_crend_unittest(in_fmt, out_fmt, **kwargs) + cut, cut_fs = run_renderer(in_fmt, out_fmt, **kwargs) + check_BE(test_info, ref, ref_fs, cut, cut_fs) + + +def compare_renderer_vs_td_standalone(test_info, in_fmt, out_fmt, **kwargs): + ref, ref_fs = run_td_standalone(in_fmt, out_fmt, **kwargs) + cut, cut_fs = run_renderer(in_fmt, out_fmt, **kwargs) + check_BE(test_info, ref, ref_fs, cut, cut_fs) + + +def compare_renderer_vs_decoder(test_info, in_fmt, out_fmt, **kwargs): + with TemporaryDirectory() as tmp_dir: + tmp_dir = Path(tmp_dir) + + in_meta_files = None + bit_file = str(tmp_dir.joinpath(f"{in_fmt}_to_{out_fmt}.192")) + out_file_decoder = str(OUTPUT_PATH_REF.joinpath(f"{in_fmt}_to_{out_fmt}.wav")) + + # Ref: cod -> dec (out_fmt) + if in_fmt in FORMAT_TO_METADATA_FILES.keys(): + in_meta_files = FORMAT_TO_METADATA_FILES[in_fmt] + + # encoder + run_enc(in_fmt, bit_file, in_meta_files=in_meta_files) + # decoder renderer + ref, ref_fs = run_dec(bit_file, out_file_decoder, out_fmt, **kwargs) + + # CuT cod -> dec (in_fmt) -> rend + if in_fmt in FORMAT_TO_METADATA_FILES.keys(): + tmp_fmt = "EXT" + in_meta_files = [ + str(tmp_dir.joinpath(f"{in_fmt}_to_EXT.wav.{n}.csv")) + for n in range(int(in_fmt[3])) + ] + else: + tmp_fmt = in_fmt + + out_file_ext = str(tmp_dir.joinpath(f"{in_fmt}_to_{tmp_fmt}.wav")) + + # passthrough decoder + run_dec(bit_file, out_file_ext, tmp_fmt, **kwargs) + # external renderer + cut, cut_fs = run_renderer_ext( + out_file_ext, in_fmt, out_fmt, in_meta_files=in_meta_files, **kwargs + ) + + check_BE(test_info, ref, ref_fs, cut, cut_fs) -- GitLab From 90fe5a24a19403f72a813c67555b9f67137bf1a9 Mon Sep 17 00:00:00 2001 From: Archit Tamarapu Date: Fri, 4 Nov 2022 10:58:25 +0100 Subject: [PATCH 071/101] ci updates --- .gitlab-ci.yml | 4 ++-- tests/renderer/constants.py | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 5f840839ea..73927a1ccf 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -342,14 +342,14 @@ external-renderer-cmake-msan-pytest: - python3 -m pytest -q --log-level ERROR -n auto -rA tests/renderer/test_renderer.py # test external renderer executable with cmake vs decoder renderer -external-renderer-make-vs-decoder-pytest: +external-renderer-cmake-vs-decoder-pytest: extends: - .test-job-linux - .rules-merge-request needs: ["build-codec-linux-cmake"] stage: test script: - - cmake -B cmake-build -G "Unix Makefiles" -DCLANG=msan -DCOPY_EXECUTABLES_FROM_BUILD_DIR=true -DDEC_TO_REND_FLOAT_DUMP + - cmake -B cmake-build -G "Unix Makefiles" -DCOPY_EXECUTABLES_FROM_BUILD_DIR=true -DDEC_TO_REND_FLOAT_DUMP - cmake --build cmake-build -- -j - python3 -m pytest -q --log-level ERROR -n 1 -rA tests/renderer/test_renderer_vs_decoder.py diff --git a/tests/renderer/constants.py b/tests/renderer/constants.py index d76be35089..8c36d7b539 100644 --- a/tests/renderer/constants.py +++ b/tests/renderer/constants.py @@ -35,8 +35,6 @@ TEST_VECTOR_DIR = TESTS_DIR.joinpath("data") OUTPUT_PATH_REF = TESTS_DIR.joinpath("ref") OUTPUT_PATH_CUT = TESTS_DIR.joinpath("cut") -OUTPUT_PATH_REF = TESTS_DIR.joinpath("/home/amm-er/tmu/external_renderer/ref") -OUTPUT_PATH_CUT = TESTS_DIR.joinpath("/home/amm-er/tmu/external_renderer/cut") CUSTOM_LAYOUT_DIR = SCRIPTS_DIR.joinpath("ls_layouts") HR_TRAJECTORY_DIR = SCRIPTS_DIR.joinpath("trajectories") -- GitLab From 1fba23eaec4ca34b700c1eea455460cc64712915 Mon Sep 17 00:00:00 2001 From: Archit Tamarapu Date: Fri, 4 Nov 2022 11:18:31 +0100 Subject: [PATCH 072/101] ci updates --- .gitlab-ci.yml | 2 +- .../tests/unit_tests/crend/ivas_crend_utest_utils.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 73927a1ccf..30c822bd26 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -349,7 +349,7 @@ external-renderer-cmake-vs-decoder-pytest: needs: ["build-codec-linux-cmake"] stage: test script: - - cmake -B cmake-build -G "Unix Makefiles" -DCOPY_EXECUTABLES_FROM_BUILD_DIR=true -DDEC_TO_REND_FLOAT_DUMP + - cmake -B cmake-build -G "Unix Makefiles" -DCOPY_EXECUTABLES_FROM_BUILD_DIR=true -DDEC_TO_REND_FLOAT_DUMP=true - cmake --build cmake-build -- -j - python3 -m pytest -q --log-level ERROR -n 1 -rA tests/renderer/test_renderer_vs_decoder.py diff --git a/scripts/ivas_pytests/tests/unit_tests/crend/ivas_crend_utest_utils.c b/scripts/ivas_pytests/tests/unit_tests/crend/ivas_crend_utest_utils.c index 42d9795219..de9212443e 100644 --- a/scripts/ivas_pytests/tests/unit_tests/crend/ivas_crend_utest_utils.c +++ b/scripts/ivas_pytests/tests/unit_tests/crend/ivas_crend_utest_utils.c @@ -1591,7 +1591,7 @@ ivas_result_t ivas_common_mixer_renderer( ivas_crend_io_params_t *pIo_params, fl count_free( ppDelay_lines[i] ); } } - if ( st_ivas.hRenderConfig->roomAcoustics.late_reverb_on ) + if ( st_ivas.hRenderConfig != NULL ) { ivas_render_config_close( &st_ivas.hRenderConfig ); } -- GitLab From 1fb4c6eae406aab14357b3f52409a9e15089b5ce Mon Sep 17 00:00:00 2001 From: Archit Tamarapu Date: Fri, 4 Nov 2022 11:51:35 +0100 Subject: [PATCH 073/101] fix linker error and warnings in crend_unit_test --- CMakeLists.txt | 1 + .../unit_tests/crend/ivas_crend_utest_utils.c | 14 ++++++++++---- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 75dabe1d22..a048f400a6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -135,6 +135,7 @@ 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) file(GLOB libEncSrcs "lib_enc/*.c") file(GLOB libEncHeaders "lib_enc/*.h") diff --git a/scripts/ivas_pytests/tests/unit_tests/crend/ivas_crend_utest_utils.c b/scripts/ivas_pytests/tests/unit_tests/crend/ivas_crend_utest_utils.c index de9212443e..43853e041f 100644 --- a/scripts/ivas_pytests/tests/unit_tests/crend/ivas_crend_utest_utils.c +++ b/scripts/ivas_pytests/tests/unit_tests/crend/ivas_crend_utest_utils.c @@ -1209,11 +1209,11 @@ ivas_result_t ivas_common_mixer_renderer( ivas_crend_io_params_t *pIo_params, fl { if ( ( error = ivas_headTrack_open( &( st_ivas.hHeadTrackData ) ) ) != IVAS_ERR_OK ) { - return error; + return IVAS_FAILED; } if ( ( error = HeadRotationFileReader_open( pIo_params->csv_path, &headRotReader ) ) != IVAS_ERR_OK ) { - return error; + return IVAS_FAILED; } } @@ -1327,7 +1327,10 @@ ivas_result_t ivas_common_mixer_renderer( ivas_crend_io_params_t *pIo_params, fl { if ( ( st_ivas.hLFE->lfe_delay_buf = (float *) count_malloc( st_ivas.hLFE->lfe_addl_delay * sizeof( float ) ) ) == NULL ) { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LFE additional delay buffer\n" ) ); + if ( ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LFE additional delay buffer\n" ) ) != IVAS_ERR_OK ) + { + return IVAS_FAILED; + } } set_zero( (float *) st_ivas.hLFE->lfe_delay_buf, st_ivas.hLFE->lfe_addl_delay ); } @@ -1345,7 +1348,10 @@ ivas_result_t ivas_common_mixer_renderer( ivas_crend_io_params_t *pIo_params, fl { if ( ( ppDelay_lines[i] = (float *) count_malloc( delay_lp * sizeof( float ) ) ) == NULL ) { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LFE additional delay buffer\n" ) ); + if ( ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LFE additional delay buffer\n" ) ) != IVAS_ERR_OK ) + { + return IVAS_FAILED; + } } set_zero( (float *) ppDelay_lines[i], delay_lp ); } -- GitLab From 5822c79e1a03dd3365a068daaf4471d175836801 Mon Sep 17 00:00:00 2001 From: Archit Tamarapu Date: Fri, 4 Nov 2022 14:15:51 +0100 Subject: [PATCH 074/101] update xfail thresholds with comments --- .../unit_tests/crend/ivas_crend_utest_utils.c | 12 +-- tests/renderer/constants.py | 90 ++++++++++--------- tests/renderer/test_renderer.py | 4 +- tests/renderer/utils.py | 8 +- 4 files changed, 59 insertions(+), 55 deletions(-) diff --git a/scripts/ivas_pytests/tests/unit_tests/crend/ivas_crend_utest_utils.c b/scripts/ivas_pytests/tests/unit_tests/crend/ivas_crend_utest_utils.c index 43853e041f..6ef4a55fd1 100644 --- a/scripts/ivas_pytests/tests/unit_tests/crend/ivas_crend_utest_utils.c +++ b/scripts/ivas_pytests/tests/unit_tests/crend/ivas_crend_utest_utils.c @@ -1327,10 +1327,8 @@ ivas_result_t ivas_common_mixer_renderer( ivas_crend_io_params_t *pIo_params, fl { if ( ( st_ivas.hLFE->lfe_delay_buf = (float *) count_malloc( st_ivas.hLFE->lfe_addl_delay * sizeof( float ) ) ) == NULL ) { - if ( ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LFE additional delay buffer\n" ) ) != IVAS_ERR_OK ) - { - return IVAS_FAILED; - } + fprintf( stderr, "Can not allocate memory for LFE additional delay buffer\n" ); + return IVAS_FAILED; } set_zero( (float *) st_ivas.hLFE->lfe_delay_buf, st_ivas.hLFE->lfe_addl_delay ); } @@ -1348,10 +1346,8 @@ ivas_result_t ivas_common_mixer_renderer( ivas_crend_io_params_t *pIo_params, fl { if ( ( ppDelay_lines[i] = (float *) count_malloc( delay_lp * sizeof( float ) ) ) == NULL ) { - if ( ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for LFE additional delay buffer\n" ) ) != IVAS_ERR_OK ) - { - return IVAS_FAILED; - } + fprintf( stderr, "Can not allocate memory for LFE additional delay buffer\n" ); + return IVAS_FAILED; } set_zero( (float *) ppDelay_lines[i], delay_lp ); } diff --git a/tests/renderer/constants.py b/tests/renderer/constants.py index 8c36d7b539..d1b2ee202d 100644 --- a/tests/renderer/constants.py +++ b/tests/renderer/constants.py @@ -92,7 +92,7 @@ TDRENDERER_CMD = [ ] """ CREND commandline template """ -RENDERER_CREND_CMD = [ +CREND_CMD = [ str( SCRIPTS_DIR.joinpath("ivas_pytests/tests/unit_tests/crend/IVAS_crend_unit_test") ), @@ -109,7 +109,7 @@ RENDERER_CREND_CMD = [ "-o", "/dev/null", # 6 -> output file # "-lp_lfe", - "-limiter" + # "-limiter" # "-no_delay_cmp" ] @@ -281,19 +281,18 @@ pass_snr = { # External Renderer vs Standalone and pyaudio3dtools renderers tests # #################################################################### - # Crend used internally, comparison to pyaudio3dtools has bad SNR - # Crend unit test does not support Quaternion files + # TODO needs debugging + "test_ambisonics_binaural_headrotation[HOA2-BINAURAL-full_circle_in_15s]": 18, + "test_ambisonics_binaural_headrotation[HOA3-BINAURAL-full_circle_in_15s]": 15, + # Crend unit test does not support SHD BRIRs "test_ambisonics_binaural_headrotation[FOA-BINAURAL_ROOM-full_circle_in_15s]": 0, "test_ambisonics_binaural_headrotation[FOA-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 0, - "test_ambisonics_binaural_headrotation[HOA2-BINAURAL-full_circle_in_15s]": 18, "test_ambisonics_binaural_headrotation[HOA2-BINAURAL_ROOM-full_circle_in_15s]": 0, "test_ambisonics_binaural_headrotation[HOA2-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 0, "test_ambisonics_binaural_headrotation[HOA2-BINAURAL-rotate_yaw_pitch_roll1]": 4, - "test_ambisonics_binaural_headrotation[HOA3-BINAURAL-full_circle_in_15s]": 15, "test_ambisonics_binaural_headrotation[HOA3-BINAURAL_ROOM-full_circle_in_15s]": 0, "test_ambisonics_binaural_headrotation[HOA3-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 0, "test_ambisonics_binaural_headrotation[HOA3-BINAURAL-rotate_yaw_pitch_roll1]": 3, - # TODO needs debugging "test_ambisonics_binaural_static[FOA-BINAURAL_ROOM]": 0, "test_ambisonics_binaural_static[HOA2-BINAURAL_ROOM]": 0, "test_ambisonics_binaural_static[HOA3-BINAURAL_ROOM]": 0, @@ -324,7 +323,8 @@ pass_snr = { "test_custom_ls_input_binaural[t_design_4-BINAURAL]": 0, "test_custom_ls_input_binaural[t_design_4-BINAURAL_ROOM]": 0, # Crend used internally, comparison to pyaudio3dtools has bad SNR - # Crend unit test does not support ISM rendering or Quaternion files + # Crend unit test does not support ISM rendering + # 5ms rendering still TODO in renderer "test_ism_binaural_headrotation[ISM1-BINAURAL_ROOM-full_circle_in_15s]": 9, "test_ism_binaural_headrotation[ISM1-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 4, "test_ism_binaural_headrotation[ISM2-BINAURAL_ROOM-full_circle_in_15s]": 10, @@ -340,7 +340,7 @@ pass_snr = { "test_ism_binaural_static[ISM2-BINAURAL_ROOM]": 21, "test_ism_binaural_static[ISM3-BINAURAL_ROOM]": 21, "test_ism_binaural_static[ISM4-BINAURAL_ROOM]": 21, - # TODO needs debugging, minor differences could be due to crossfades or metadata position casts + # TODO needs debugging, minor differences could be due to crossfades or metadata position rounding "test_ism[ISM1-5_1_2]": 48, "test_ism[ISM1-5_1_4]": 48, "test_ism[ISM1-5_1]": 48, @@ -377,28 +377,35 @@ pass_snr = { "test_ism[ISM4-HOA2]": 36, "test_ism[ISM4-HOA3]": 33, "test_ism[ISM4-STEREO]": 57, - # Crend used internally, comparison to pyaudio3dtools has bad SNR - # Crend unit test does not support Quaternion files - "test_multichannel_binaural_headrotation[5_1_2-BINAURAL-full_circle_in_15s]": 8, - "test_multichannel_binaural_headrotation[5_1_2-BINAURAL_ROOM-full_circle_in_15s]": 2, - "test_multichannel_binaural_headrotation[5_1_2-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 2, - "test_multichannel_binaural_headrotation[5_1_2-BINAURAL-rotate_yaw_pitch_roll1]": 1, - "test_multichannel_binaural_headrotation[5_1_4-BINAURAL-full_circle_in_15s]": 8, - "test_multichannel_binaural_headrotation[5_1_4-BINAURAL_ROOM-full_circle_in_15s]": 2, - "test_multichannel_binaural_headrotation[5_1_4-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 2, - "test_multichannel_binaural_headrotation[5_1_4-BINAURAL-rotate_yaw_pitch_roll1]": 1, + # bitexact except for delay alignment of LFE signal (Issue 59) "test_multichannel_binaural_headrotation[5_1-BINAURAL-full_circle_in_15s]": 7, - "test_multichannel_binaural_headrotation[5_1-BINAURAL_ROOM-full_circle_in_15s]": 3, - "test_multichannel_binaural_headrotation[5_1-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 3, "test_multichannel_binaural_headrotation[5_1-BINAURAL-rotate_yaw_pitch_roll1]": 6, - "test_multichannel_binaural_headrotation[7_1_4-BINAURAL-full_circle_in_15s]": 7, - "test_multichannel_binaural_headrotation[7_1_4-BINAURAL_ROOM-full_circle_in_15s]": 2, - "test_multichannel_binaural_headrotation[7_1_4-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 2, - "test_multichannel_binaural_headrotation[7_1_4-BINAURAL-rotate_yaw_pitch_roll1]": 1, "test_multichannel_binaural_headrotation[7_1-BINAURAL-full_circle_in_15s]": 8, - "test_multichannel_binaural_headrotation[7_1-BINAURAL_ROOM-full_circle_in_15s]": 2, - "test_multichannel_binaural_headrotation[7_1-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 2, "test_multichannel_binaural_headrotation[7_1-BINAURAL-rotate_yaw_pitch_roll1]": 8, + # TODO minor differences, needs debugging + "test_multichannel_binaural_headrotation[5_1_2-BINAURAL-full_circle_in_15s]": 30, + "test_multichannel_binaural_headrotation[5_1_2-BINAURAL-rotate_yaw_pitch_roll1]": 30, + "test_multichannel_binaural_headrotation[5_1_4-BINAURAL-full_circle_in_15s]": 29, + "test_multichannel_binaural_headrotation[5_1_4-BINAURAL-rotate_yaw_pitch_roll1]": 29, + "test_multichannel_binaural_headrotation[7_1_4-BINAURAL-full_circle_in_15s]": 30, + "test_multichannel_binaural_headrotation[7_1_4-BINAURAL-rotate_yaw_pitch_roll1]": 30, + # headrotation may be applied differently + "test_multichannel_binaural_headrotation[5_1-BINAURAL_ROOM-full_circle_in_15s]": 10, + "test_multichannel_binaural_headrotation[5_1-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 4, + "test_multichannel_binaural_headrotation[5_1_2-BINAURAL_ROOM-full_circle_in_15s]": 11, + "test_multichannel_binaural_headrotation[5_1_2-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 3, + "test_multichannel_binaural_headrotation[5_1_4-BINAURAL_ROOM-full_circle_in_15s]": 12, + "test_multichannel_binaural_headrotation[5_1_4-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 3, + "test_multichannel_binaural_headrotation[7_1-BINAURAL_ROOM-full_circle_in_15s]": 10, + "test_multichannel_binaural_headrotation[7_1-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 3, + "test_multichannel_binaural_headrotation[7_1_4-BINAURAL_ROOM-full_circle_in_15s]": 10, + "test_multichannel_binaural_headrotation[7_1_4-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 3, + # TODO minor differences, needs debugging (same as headrotation case) + "test_multichannel_binaural_static[5_1_2-BINAURAL]": 30, + "test_multichannel_binaural_static[5_1_4-BINAURAL]": 29, + "test_multichannel_binaural_static[5_1-BINAURAL]": 27, + "test_multichannel_binaural_static[7_1-BINAURAL]": 30, + "test_multichannel_binaural_static[7_1_4-BINAURAL]": 30, ##################################### # # External vs Internal Renderer tests @@ -420,45 +427,46 @@ pass_snr = { "test_ism_binaural_static_vs_decoder[ISM2-BINAURAL_ROOM]": 12, "test_ism_binaural_static_vs_decoder[ISM3-BINAURAL_ROOM]": 12, "test_ism_binaural_static_vs_decoder[ISM4-BINAURAL_ROOM]": 12, + # TODO ISM to stereo panning is done via EFAP in the renderer and tangent law in decoder, harmonize + "test_ism_vs_decoder[ISM1-STEREO]": 8, + "test_ism_vs_decoder[ISM2-STEREO]": 17, + "test_ism_vs_decoder[ISM3-STEREO]": 14, + "test_ism_vs_decoder[ISM4-STEREO]": 14, # TODO loudspeaker and ambisonics rendering could be due to crossfades or metadata position rounding "test_ism_vs_decoder[ISM1-5_1_2]": 26, "test_ism_vs_decoder[ISM1-5_1]": 26, "test_ism_vs_decoder[ISM1-5_1_4]": 26, "test_ism_vs_decoder[ISM1-7_1]": 26, "test_ism_vs_decoder[ISM1-7_1_4]": 26, - "test_ism_vs_decoder[ISM1-FOA]": 27, + "test_ism_vs_decoder[ISM1-FOA]": 26, "test_ism_vs_decoder[ISM1-HOA2]": 26, "test_ism_vs_decoder[ISM1-HOA3]": 26, - "test_ism_vs_decoder[ISM1-STEREO]": 8, - "test_ism_vs_decoder[ISM2-5_1_2]": 32, + "test_ism_vs_decoder[ISM2-5_1_2]": 31, "test_ism_vs_decoder[ISM2-5_1_4]": 31, "test_ism_vs_decoder[ISM2-5_1]": 6, "test_ism_vs_decoder[ISM2-7_1_4]": 31, "test_ism_vs_decoder[ISM2-7_1]": 5, - "test_ism_vs_decoder[ISM2-FOA]": 32, - "test_ism_vs_decoder[ISM2-HOA2]": 31, - "test_ism_vs_decoder[ISM2-HOA3]": 30, - "test_ism_vs_decoder[ISM2-STEREO]": 17, + "test_ism_vs_decoder[ISM2-FOA]": 31, + "test_ism_vs_decoder[ISM2-HOA2]": 30, + "test_ism_vs_decoder[ISM2-HOA3]": 29, "test_ism_vs_decoder[ISM3-5_1_2]": 32, "test_ism_vs_decoder[ISM3-5_1_4]": 32, "test_ism_vs_decoder[ISM3-5_1]": 8, "test_ism_vs_decoder[ISM3-7_1_4]": 31, "test_ism_vs_decoder[ISM3-7_1]": 7, "test_ism_vs_decoder[ISM3-FOA]": 32, - "test_ism_vs_decoder[ISM3-HOA2]": 32, - "test_ism_vs_decoder[ISM3-HOA3]": 30, + "test_ism_vs_decoder[ISM3-HOA2]": 31, + "test_ism_vs_decoder[ISM3-HOA3]": 29, "test_ism_vs_decoder[ISM3-MONO]": 77, - "test_ism_vs_decoder[ISM3-STEREO]": 14, "test_ism_vs_decoder[ISM4-5_1_2]": 31, - "test_ism_vs_decoder[ISM4-5_1_4]": 31, + "test_ism_vs_decoder[ISM4-5_1_4]": 30, "test_ism_vs_decoder[ISM4-5_1]": 8, "test_ism_vs_decoder[ISM4-7_1_4]": 30, "test_ism_vs_decoder[ISM4-7_1]": 7, "test_ism_vs_decoder[ISM4-FOA]": 31, - "test_ism_vs_decoder[ISM4-HOA2]": 31, - "test_ism_vs_decoder[ISM4-HOA3]": 30, + "test_ism_vs_decoder[ISM4-HOA2]": 30, + "test_ism_vs_decoder[ISM4-HOA3]": 29, "test_ism_vs_decoder[ISM4-MONO]": 77, - "test_ism_vs_decoder[ISM4-STEREO]": 14, # TODO needs debugging "test_multichannel_binaural_headrotation_vs_decoder[5_1_2-BINAURAL-full_circle_in_15s]": 4, "test_multichannel_binaural_headrotation_vs_decoder[5_1_2-BINAURAL_ROOM-full_circle_in_15s]": 6, diff --git a/tests/renderer/test_renderer.py b/tests/renderer/test_renderer.py index 87af209318..9660910afc 100644 --- a/tests/renderer/test_renderer.py +++ b/tests/renderer/test_renderer.py @@ -50,7 +50,7 @@ def test_ambisonics_binaural_static(test_info, in_fmt, out_fmt): @pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL) @pytest.mark.parametrize("in_fmt", INPUT_FORMATS_AMBI) def test_ambisonics_binaural_headrotation(test_info, in_fmt, out_fmt, trj_file): - compare_renderer_vs_pyscripts( + compare_renderer_vs_crend_unit_test( test_info, in_fmt, out_fmt, @@ -91,7 +91,7 @@ def test_multichannel_binaural_headrotation(test_info, in_fmt, out_fmt, trj_file trj_file=HR_TRAJECTORY_DIR.joinpath(f"{trj_file}.csv"), ) else: - compare_renderer_vs_pyscripts( + compare_renderer_vs_crend_unit_test( test_info, in_fmt, out_fmt, diff --git a/tests/renderer/utils.py b/tests/renderer/utils.py index 92d017c43a..89ffbe0f6d 100644 --- a/tests/renderer/utils.py +++ b/tests/renderer/utils.py @@ -258,15 +258,15 @@ def run_crend_unittest( in_name = in_fmt out_file = str( - OUTPUT_PATH_REF.joinpath(f"{in_name}_to_{out_name}{trj_name}_crend.wav") + OUTPUT_PATH_REF.joinpath(f"{in_name}_to_{out_name}{trj_name}.wav") ) - cmd = RENDERER_CREND_CMD[:] + cmd = CREND_CMD[:] cmd[6] = FORMAT_TO_CREND_FORMAT[str(in_fmt)] cmd[8] = FORMAT_TO_CREND_FORMAT[str(out_fmt)] cmd[10] = str(in_file) cmd[12] = str(out_file) - if str(out_fmt) == "BINAURAL_ROOM": + if out_fmt == "BINAURAL_ROOM": cmd.append("-brir") if trj_file is not None: @@ -422,7 +422,7 @@ def compare_renderer_vs_decoder(test_info, in_fmt, out_fmt, **kwargs): tmp_fmt = "EXT" in_meta_files = [ str(tmp_dir.joinpath(f"{in_fmt}_to_EXT.wav.{n}.csv")) - for n in range(int(in_fmt[3])) + for n in range(int(in_fmt[-1])) ] else: tmp_fmt = in_fmt -- GitLab From 12d26b0b994d3745713d772d1ed494449b27f59a Mon Sep 17 00:00:00 2001 From: Archit Tamarapu Date: Fri, 4 Nov 2022 14:24:56 +0100 Subject: [PATCH 075/101] fix memory leak in crend unit test (and pipeline) --- .../tests/unit_tests/crend/ivas_crend_utest_utils.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/ivas_pytests/tests/unit_tests/crend/ivas_crend_utest_utils.c b/scripts/ivas_pytests/tests/unit_tests/crend/ivas_crend_utest_utils.c index 6ef4a55fd1..be5e483927 100644 --- a/scripts/ivas_pytests/tests/unit_tests/crend/ivas_crend_utest_utils.c +++ b/scripts/ivas_pytests/tests/unit_tests/crend/ivas_crend_utest_utils.c @@ -1585,6 +1585,8 @@ ivas_result_t ivas_common_mixer_renderer( ivas_crend_io_params_t *pIo_params, fl ivas_td_binaural_close( &st_ivas.hBinRendererTd ); if ( st_ivas.hLimiter != NULL ) ivas_limiter_close( &st_ivas.hLimiter ); + if ( st_ivas.hEFAPdata != NULL ) + efap_free_data( &st_ivas.hEFAPdata ); if ( pIo_params->lfe_lp_enable ) { -- GitLab From 76b5a7a0e82f5b45f14cc011199cf7b21709fb8b Mon Sep 17 00:00:00 2001 From: Archit Tamarapu Date: Fri, 4 Nov 2022 16:02:38 +0100 Subject: [PATCH 076/101] fix merge changes - update TD Object Renderer file reading - clean up tests/renderer/data directory --- scripts/pyaudio3dtools/rotation.py | 4 +- .../renderer_standalone.c | 31 +- tests/renderer/constants.py | 24 +- .../renderer/data/IVAS_ISM_metadata_-30_0.csv | 50 - tests/renderer/data/IVAS_ISM_metadata_0_0.csv | 50 - .../renderer/data/IVAS_ISM_metadata_30_0.csv | 50 - .../data/IVAS_ISM_metadata_circle.csv | 50 - tests/renderer/data/ism_-90a_0e.csv | 750 --------- tests/renderer/data/ism_180a_0e.csv | 750 --------- tests/renderer/data/ism_90a_0e.csv | 750 --------- tests/renderer/data/pink_noise_10ch_48kHz.wav | 3 - tests/renderer/data/pink_noise_11ch_48kHz.wav | 3 - tests/renderer/data/pink_noise_12ch_48kHz.wav | 3 - tests/renderer/data/pink_noise_13ch_48kHz.wav | 3 - tests/renderer/data/pink_noise_14ch_48kHz.wav | 3 - tests/renderer/data/pink_noise_15ch_48kHz.wav | 3 - tests/renderer/data/pink_noise_16ch_48kHz.wav | 3 - tests/renderer/data/pink_noise_1ch_48kHz.wav | 3 - tests/renderer/data/pink_noise_2ch_48kHz.wav | 3 - tests/renderer/data/pink_noise_3ch_48kHz.wav | 3 - tests/renderer/data/pink_noise_4ch_48kHz.wav | 3 - tests/renderer/data/pink_noise_5ch_48kHz.wav | 3 - tests/renderer/data/pink_noise_6ch_48kHz.wav | 3 - tests/renderer/data/pink_noise_7ch_48kHz.wav | 3 - tests/renderer/data/pink_noise_8ch_48kHz.wav | 3 - tests/renderer/data/pink_noise_9ch_48kHz.wav | 3 - tests/renderer/data/spectral_test_ism1.txt | 5 - tests/renderer/data/spectral_test_ism2.txt | 8 - tests/renderer/data/spectral_test_ism3.txt | 11 - tests/renderer/data/spectral_test_ism4.txt | 14 - tests/renderer/data/stvISM1.csv | 1500 ----------------- tests/renderer/data/stvISM2.csv | 1500 ----------------- tests/renderer/data/stvISM3.csv | 1500 ----------------- tests/renderer/data/stvISM4.csv | 1500 ----------------- tests/renderer/data/stv_IVASMASA_1dir1TC.met | 3 - tests/renderer/data/stv_IVASMASA_1dir1TC.pcm | 3 - tests/renderer/data/stv_IVASMASA_1dir2TC.met | 3 - tests/renderer/data/stv_IVASMASA_1dir2TC.pcm | 3 - tests/renderer/data/stv_IVASMASA_2dir1TC.met | 3 - tests/renderer/data/stv_IVASMASA_2dir1TC.pcm | 3 - tests/renderer/data/stv_IVASMASA_2dir2TC.met | 3 - tests/renderer/data/stv_IVASMASA_2dir2TC.pcm | 3 - tests/renderer/utils.py | 6 +- 43 files changed, 42 insertions(+), 8583 deletions(-) delete mode 100644 tests/renderer/data/IVAS_ISM_metadata_-30_0.csv delete mode 100644 tests/renderer/data/IVAS_ISM_metadata_0_0.csv delete mode 100644 tests/renderer/data/IVAS_ISM_metadata_30_0.csv delete mode 100644 tests/renderer/data/IVAS_ISM_metadata_circle.csv delete mode 100644 tests/renderer/data/ism_-90a_0e.csv delete mode 100644 tests/renderer/data/ism_180a_0e.csv delete mode 100644 tests/renderer/data/ism_90a_0e.csv delete mode 100644 tests/renderer/data/pink_noise_10ch_48kHz.wav delete mode 100644 tests/renderer/data/pink_noise_11ch_48kHz.wav delete mode 100644 tests/renderer/data/pink_noise_12ch_48kHz.wav delete mode 100644 tests/renderer/data/pink_noise_13ch_48kHz.wav delete mode 100644 tests/renderer/data/pink_noise_14ch_48kHz.wav delete mode 100644 tests/renderer/data/pink_noise_15ch_48kHz.wav delete mode 100644 tests/renderer/data/pink_noise_16ch_48kHz.wav delete mode 100644 tests/renderer/data/pink_noise_1ch_48kHz.wav delete mode 100644 tests/renderer/data/pink_noise_2ch_48kHz.wav delete mode 100644 tests/renderer/data/pink_noise_3ch_48kHz.wav delete mode 100644 tests/renderer/data/pink_noise_4ch_48kHz.wav delete mode 100644 tests/renderer/data/pink_noise_5ch_48kHz.wav delete mode 100644 tests/renderer/data/pink_noise_6ch_48kHz.wav delete mode 100644 tests/renderer/data/pink_noise_7ch_48kHz.wav delete mode 100644 tests/renderer/data/pink_noise_8ch_48kHz.wav delete mode 100644 tests/renderer/data/pink_noise_9ch_48kHz.wav delete mode 100644 tests/renderer/data/spectral_test_ism1.txt delete mode 100644 tests/renderer/data/spectral_test_ism2.txt delete mode 100644 tests/renderer/data/spectral_test_ism3.txt delete mode 100644 tests/renderer/data/spectral_test_ism4.txt delete mode 100644 tests/renderer/data/stvISM1.csv delete mode 100644 tests/renderer/data/stvISM2.csv delete mode 100644 tests/renderer/data/stvISM3.csv delete mode 100644 tests/renderer/data/stvISM4.csv delete mode 100644 tests/renderer/data/stv_IVASMASA_1dir1TC.met delete mode 100644 tests/renderer/data/stv_IVASMASA_1dir1TC.pcm delete mode 100644 tests/renderer/data/stv_IVASMASA_1dir2TC.met delete mode 100644 tests/renderer/data/stv_IVASMASA_1dir2TC.pcm delete mode 100644 tests/renderer/data/stv_IVASMASA_2dir1TC.met delete mode 100644 tests/renderer/data/stv_IVASMASA_2dir1TC.pcm delete mode 100644 tests/renderer/data/stv_IVASMASA_2dir2TC.met delete mode 100644 tests/renderer/data/stv_IVASMASA_2dir2TC.pcm diff --git a/scripts/pyaudio3dtools/rotation.py b/scripts/pyaudio3dtools/rotation.py index ccdf0fc5f5..09f90a9ccf 100644 --- a/scripts/pyaudio3dtools/rotation.py +++ b/scripts/pyaudio3dtools/rotation.py @@ -273,7 +273,7 @@ def rotateISM( ele_rot = np.zeros([N_frames]) for i_frame in range(N_frames): - q = trj_data[i_frame % trj_frames, 1:] + q = trj_data[i_frame % trj_frames, :] azi_rot[i_frame], ele_rot[i_frame] = rotateAziEle( azi[i_frame], ele[i_frame], Quat2RotMat(q) ) @@ -324,7 +324,7 @@ def rotateMC(x: np.ndarray, trajectory: str, layout: spatialaudioformat) -> np.n start = i_frame * frame_len end = (i_frame + 1) * frame_len - q = trj_data[i_frame % trj_frames, 1:] + q = trj_data[i_frame % trj_frames, :] rotated_pos = np.array( [ diff --git a/scripts/td_object_renderer/object_renderer_standalone/object_renderer_standalone/renderer_standalone.c b/scripts/td_object_renderer/object_renderer_standalone/object_renderer_standalone/renderer_standalone.c index 3c98b8d688..414d8e07f7 100644 --- a/scripts/td_object_renderer/object_renderer_standalone/object_renderer_standalone/renderer_standalone.c +++ b/scripts/td_object_renderer/object_renderer_standalone/object_renderer_standalone/renderer_standalone.c @@ -51,8 +51,12 @@ * Constants *------------------------------------------------------------------------------------------*/ -#define META_LINE_LENGTH 200 /* max number of characters at one line of metadata input/output file */ -#define NUM_ISM_METADATA_PER_LINE 5 /* Number of ISM metadata per line in a metadata file */ +#define META_LINE_LENGTH 200 /* max number of characters at one line of metadata input/output file */ +#ifdef FIX_I173_I174 +#define NUM_ISM_METADATA_PER_LINE 4 /* Number of ISM metadata per line in a metadata file */ +#else +#define NUM_ISM_METADATA_PER_LINE 5 /* Number of ISM metadata per line in a metadata file */ +#endif /*---------------------------------------------------------------------* * Local function prototypes @@ -109,7 +113,7 @@ int32_t frame = 0; /* Counter of frames */ /*------------------------------------------------------------------------------------------* * Standalone Renderer program * - * + * *------------------------------------------------------------------------------------------*/ int main( int argc, char *argv[] ) { @@ -126,7 +130,9 @@ int main( int argc, char *argv[] ) FILE *f_input; FILE *f_output; FILE *f_quat_traj; +#ifndef FIX_I173_I174 int32_t tmp; +#endif float x, y, z, w; FILE *f_metadata[MAX_NUM_OBJECTS]; Decoder_Struct st_ivas_static; @@ -282,7 +288,7 @@ int main( int argc, char *argv[] ) /* Fs and 20ms frame length */ st_ivas->hDecoderConfig->output_Fs = atoi( argv[i] ) * 1000; - nFrameLength = ( ( int16_t )( st_ivas->hDecoderConfig->output_Fs / 1000 ) ) * 20; /* 20 ms frame */ + nFrameLength = ( (int16_t) ( st_ivas->hDecoderConfig->output_Fs / 1000 ) ) * 20; /* 20 ms frame */ i++; /* Input, n-channel audio */ @@ -395,7 +401,11 @@ int main( int argc, char *argv[] ) { for ( i = 0; i < 4; i++ ) /* MAX_PARAM_SPATIAL_SUBFRAMES = 4 */ { +#ifdef FIX_I173_I174 + if ( 4 == fscanf( f_quat_traj, "%f,%f,%f,%f", &w, &x, &y, &z ) ) +#else if ( 5 == fscanf( f_quat_traj, "%d,%f,%f,%f,%f", &tmp, &w, &x, &y, &z ) ) +#endif { st_ivas->hHeadTrackData->num_quaternions = -1; @@ -433,7 +443,7 @@ int main( int argc, char *argv[] ) /* Trim first frame to compensate for delay */ if ( nFrameCount == 0 ) { - offset = ( int16_t )( st_ivas->hDecoderConfig->output_Fs / 200 ); /* 240 samples for 48kHz etc */ + offset = (int16_t) ( st_ivas->hDecoderConfig->output_Fs / 200 ); /* 240 samples for 48kHz etc */ } else { @@ -445,7 +455,7 @@ int main( int argc, char *argv[] ) { for ( nS = 0; nS < NumLdspks; nS++ ) { - MixFrameWav[n * NumLdspks + nS] = ( int16_t )( output[nS][n + offset] + 0.5f * sign( output[nS][n + offset] ) ); + MixFrameWav[n * NumLdspks + nS] = (int16_t) ( output[nS][n + offset] + 0.5f * sign( output[nS][n + offset] ) ); } } fwrite( MixFrameWav, sizeof( int16_t ), ( currFrameLength - offset ) * NumLdspks, f_output ); @@ -543,7 +553,9 @@ static void readMetadata( float meta_prm[NUM_ISM_METADATA_PER_LINE]; char *char_ptr; int16_t j; +#ifndef FIX_I173_I174 int32_t time_stamp; +#endif if ( fgets( char_buff, META_LINE_LENGTH, file ) == NULL ) { @@ -552,6 +564,7 @@ static void readMetadata( } char_ptr = strtok( char_buff, "," ); +#ifndef FIX_I173_I174 time_stamp = (int32_t) atoi( char_ptr ); if ( time_stamp != frame ) @@ -559,12 +572,18 @@ static void readMetadata( fprintf( stderr, "\n!!!Error: Wrong time-stamp while reading ISM metadata input file. Exiting!!!\n\n" ); exit( -1 ); } +#endif j = 0; while ( char_ptr != NULL && j < NUM_ISM_METADATA_PER_LINE ) { +#ifndef FIX_I173_I174 + meta_prm[j++] = (float) atof( char_ptr ); + char_ptr = strtok( NULL, "," ); +#else char_ptr = strtok( NULL, "," ); meta_prm[j++] = (float) atof( char_ptr ); +#endif } hIsmMetaData->azimuth = meta_prm[0]; diff --git a/tests/renderer/constants.py b/tests/renderer/constants.py index d1b2ee202d..ff2e008438 100644 --- a/tests/renderer/constants.py +++ b/tests/renderer/constants.py @@ -166,24 +166,24 @@ FORMAT_TO_FILE = { } FORMAT_TO_METADATA_FILES = { - "ISM1": [str(TEST_VECTOR_DIR.joinpath("stvISM1.csv"))], + "ISM1": [str(TESTV_DIR.joinpath("stvISM1.csv"))], "ISM2": [ - str(TEST_VECTOR_DIR.joinpath("stvISM1.csv")), - str(TEST_VECTOR_DIR.joinpath("stvISM2.csv")), + str(TESTV_DIR.joinpath("stvISM1.csv")), + str(TESTV_DIR.joinpath("stvISM2.csv")), ], "ISM3": [ - str(TEST_VECTOR_DIR.joinpath("stvISM1.csv")), - str(TEST_VECTOR_DIR.joinpath("stvISM2.csv")), - str(TEST_VECTOR_DIR.joinpath("stvISM3.csv")), + str(TESTV_DIR.joinpath("stvISM1.csv")), + str(TESTV_DIR.joinpath("stvISM2.csv")), + str(TESTV_DIR.joinpath("stvISM3.csv")), ], "ISM4": [ - str(TEST_VECTOR_DIR.joinpath("stvISM1.csv")), - str(TEST_VECTOR_DIR.joinpath("stvISM2.csv")), - str(TEST_VECTOR_DIR.joinpath("stvISM3.csv")), - str(TEST_VECTOR_DIR.joinpath("stvISM4.csv")), + str(TESTV_DIR.joinpath("stvISM1.csv")), + str(TESTV_DIR.joinpath("stvISM2.csv")), + str(TESTV_DIR.joinpath("stvISM3.csv")), + str(TESTV_DIR.joinpath("stvISM4.csv")), ], - "MASA1": [str(TEST_VECTOR_DIR.joinpath("stv_IVASMASAQ_1dir1TC.met"))], - "MASA2": [str(TEST_VECTOR_DIR.joinpath("stv_IVASMASAQ_2dir2TC.met"))], + "MASA1": [str(TESTV_DIR.joinpath("stv_IVASMASAQ_1dir1TC.met"))], + "MASA2": [str(TESTV_DIR.joinpath("stv_IVASMASAQ_2dir2TC.met"))], } FORMAT_TO_IVAS = { diff --git a/tests/renderer/data/IVAS_ISM_metadata_-30_0.csv b/tests/renderer/data/IVAS_ISM_metadata_-30_0.csv deleted file mode 100644 index c3f47f7220..0000000000 --- a/tests/renderer/data/IVAS_ISM_metadata_-30_0.csv +++ /dev/null @@ -1,50 +0,0 @@ --030.00,+00.00,01.00,000.00,1.00 --030.00,+00.00,01.00,000.00,1.00 --030.00,+00.00,01.00,000.00,1.00 --030.00,+00.00,01.00,000.00,1.00 --030.00,+00.00,01.00,000.00,1.00 --030.00,+00.00,01.00,000.00,1.00 --030.00,+00.00,01.00,000.00,1.00 --030.00,+00.00,01.00,000.00,1.00 --030.00,+00.00,01.00,000.00,1.00 --030.00,+00.00,01.00,000.00,1.00 --030.00,+00.00,01.00,000.00,1.00 --030.00,+00.00,01.00,000.00,1.00 --030.00,+00.00,01.00,000.00,1.00 --030.00,+00.00,01.00,000.00,1.00 --030.00,+00.00,01.00,000.00,1.00 --030.00,+00.00,01.00,000.00,1.00 --030.00,+00.00,01.00,000.00,1.00 --030.00,+00.00,01.00,000.00,1.00 --030.00,+00.00,01.00,000.00,1.00 --030.00,+00.00,01.00,000.00,1.00 --030.00,+00.00,01.00,000.00,1.00 --030.00,+00.00,01.00,000.00,1.00 --030.00,+00.00,01.00,000.00,1.00 --030.00,+00.00,01.00,000.00,1.00 --030.00,+00.00,01.00,000.00,1.00 --030.00,+00.00,01.00,000.00,1.00 --030.00,+00.00,01.00,000.00,1.00 --030.00,+00.00,01.00,000.00,1.00 --030.00,+00.00,01.00,000.00,1.00 --030.00,+00.00,01.00,000.00,1.00 --030.00,+00.00,01.00,000.00,1.00 --030.00,+00.00,01.00,000.00,1.00 --030.00,+00.00,01.00,000.00,1.00 --030.00,+00.00,01.00,000.00,1.00 --030.00,+00.00,01.00,000.00,1.00 --030.00,+00.00,01.00,000.00,1.00 --030.00,+00.00,01.00,000.00,1.00 --030.00,+00.00,01.00,000.00,1.00 --030.00,+00.00,01.00,000.00,1.00 --030.00,+00.00,01.00,000.00,1.00 --030.00,+00.00,01.00,000.00,1.00 --030.00,+00.00,01.00,000.00,1.00 --030.00,+00.00,01.00,000.00,1.00 --030.00,+00.00,01.00,000.00,1.00 --030.00,+00.00,01.00,000.00,1.00 --030.00,+00.00,01.00,000.00,1.00 --030.00,+00.00,01.00,000.00,1.00 --030.00,+00.00,01.00,000.00,1.00 --030.00,+00.00,01.00,000.00,1.00 --030.00,+00.00,01.00,000.00,1.00 diff --git a/tests/renderer/data/IVAS_ISM_metadata_0_0.csv b/tests/renderer/data/IVAS_ISM_metadata_0_0.csv deleted file mode 100644 index 887782fd4e..0000000000 --- a/tests/renderer/data/IVAS_ISM_metadata_0_0.csv +++ /dev/null @@ -1,50 +0,0 @@ -+000.00,+00.00,01.00,000.00,1.00 -+000.00,+00.00,01.00,000.00,1.00 -+000.00,+00.00,01.00,000.00,1.00 -+000.00,+00.00,01.00,000.00,1.00 -+000.00,+00.00,01.00,000.00,1.00 -+000.00,+00.00,01.00,000.00,1.00 -+000.00,+00.00,01.00,000.00,1.00 -+000.00,+00.00,01.00,000.00,1.00 -+000.00,+00.00,01.00,000.00,1.00 -+000.00,+00.00,01.00,000.00,1.00 -+000.00,+00.00,01.00,000.00,1.00 -+000.00,+00.00,01.00,000.00,1.00 -+000.00,+00.00,01.00,000.00,1.00 -+000.00,+00.00,01.00,000.00,1.00 -+000.00,+00.00,01.00,000.00,1.00 -+000.00,+00.00,01.00,000.00,1.00 -+000.00,+00.00,01.00,000.00,1.00 -+000.00,+00.00,01.00,000.00,1.00 -+000.00,+00.00,01.00,000.00,1.00 -+000.00,+00.00,01.00,000.00,1.00 -+000.00,+00.00,01.00,000.00,1.00 -+000.00,+00.00,01.00,000.00,1.00 -+000.00,+00.00,01.00,000.00,1.00 -+000.00,+00.00,01.00,000.00,1.00 -+000.00,+00.00,01.00,000.00,1.00 -+000.00,+00.00,01.00,000.00,1.00 -+000.00,+00.00,01.00,000.00,1.00 -+000.00,+00.00,01.00,000.00,1.00 -+000.00,+00.00,01.00,000.00,1.00 -+000.00,+00.00,01.00,000.00,1.00 -+000.00,+00.00,01.00,000.00,1.00 -+000.00,+00.00,01.00,000.00,1.00 -+000.00,+00.00,01.00,000.00,1.00 -+000.00,+00.00,01.00,000.00,1.00 -+000.00,+00.00,01.00,000.00,1.00 -+000.00,+00.00,01.00,000.00,1.00 -+000.00,+00.00,01.00,000.00,1.00 -+000.00,+00.00,01.00,000.00,1.00 -+000.00,+00.00,01.00,000.00,1.00 -+000.00,+00.00,01.00,000.00,1.00 -+000.00,+00.00,01.00,000.00,1.00 -+000.00,+00.00,01.00,000.00,1.00 -+000.00,+00.00,01.00,000.00,1.00 -+000.00,+00.00,01.00,000.00,1.00 -+000.00,+00.00,01.00,000.00,1.00 -+000.00,+00.00,01.00,000.00,1.00 -+000.00,+00.00,01.00,000.00,1.00 -+000.00,+00.00,01.00,000.00,1.00 -+000.00,+00.00,01.00,000.00,1.00 -+000.00,+00.00,01.00,000.00,1.00 diff --git a/tests/renderer/data/IVAS_ISM_metadata_30_0.csv b/tests/renderer/data/IVAS_ISM_metadata_30_0.csv deleted file mode 100644 index 8ed2a4df12..0000000000 --- a/tests/renderer/data/IVAS_ISM_metadata_30_0.csv +++ /dev/null @@ -1,50 +0,0 @@ -+030.00,+00.00,01.00,000.00,1.00 -+030.00,+00.00,01.00,000.00,1.00 -+030.00,+00.00,01.00,000.00,1.00 -+030.00,+00.00,01.00,000.00,1.00 -+030.00,+00.00,01.00,000.00,1.00 -+030.00,+00.00,01.00,000.00,1.00 -+030.00,+00.00,01.00,000.00,1.00 -+030.00,+00.00,01.00,000.00,1.00 -+030.00,+00.00,01.00,000.00,1.00 -+030.00,+00.00,01.00,000.00,1.00 -+030.00,+00.00,01.00,000.00,1.00 -+030.00,+00.00,01.00,000.00,1.00 -+030.00,+00.00,01.00,000.00,1.00 -+030.00,+00.00,01.00,000.00,1.00 -+030.00,+00.00,01.00,000.00,1.00 -+030.00,+00.00,01.00,000.00,1.00 -+030.00,+00.00,01.00,000.00,1.00 -+030.00,+00.00,01.00,000.00,1.00 -+030.00,+00.00,01.00,000.00,1.00 -+030.00,+00.00,01.00,000.00,1.00 -+030.00,+00.00,01.00,000.00,1.00 -+030.00,+00.00,01.00,000.00,1.00 -+030.00,+00.00,01.00,000.00,1.00 -+030.00,+00.00,01.00,000.00,1.00 -+030.00,+00.00,01.00,000.00,1.00 -+030.00,+00.00,01.00,000.00,1.00 -+030.00,+00.00,01.00,000.00,1.00 -+030.00,+00.00,01.00,000.00,1.00 -+030.00,+00.00,01.00,000.00,1.00 -+030.00,+00.00,01.00,000.00,1.00 -+030.00,+00.00,01.00,000.00,1.00 -+030.00,+00.00,01.00,000.00,1.00 -+030.00,+00.00,01.00,000.00,1.00 -+030.00,+00.00,01.00,000.00,1.00 -+030.00,+00.00,01.00,000.00,1.00 -+030.00,+00.00,01.00,000.00,1.00 -+030.00,+00.00,01.00,000.00,1.00 -+030.00,+00.00,01.00,000.00,1.00 -+030.00,+00.00,01.00,000.00,1.00 -+030.00,+00.00,01.00,000.00,1.00 -+030.00,+00.00,01.00,000.00,1.00 -+030.00,+00.00,01.00,000.00,1.00 -+030.00,+00.00,01.00,000.00,1.00 -+030.00,+00.00,01.00,000.00,1.00 -+030.00,+00.00,01.00,000.00,1.00 -+030.00,+00.00,01.00,000.00,1.00 -+030.00,+00.00,01.00,000.00,1.00 -+030.00,+00.00,01.00,000.00,1.00 -+030.00,+00.00,01.00,000.00,1.00 -+030.00,+00.00,01.00,000.00,1.00 diff --git a/tests/renderer/data/IVAS_ISM_metadata_circle.csv b/tests/renderer/data/IVAS_ISM_metadata_circle.csv deleted file mode 100644 index 9323b776fe..0000000000 --- a/tests/renderer/data/IVAS_ISM_metadata_circle.csv +++ /dev/null @@ -1,50 +0,0 @@ -+000.00,+00.00,01.00,000.00,1.00 -+007.00,+00.00,01.00,000.00,1.00 -+014.00,+00.00,01.00,000.00,1.00 -+022.00,+00.00,01.00,000.00,1.00 -+029.00,+00.00,01.00,000.00,1.00 -+036.00,+00.00,01.00,000.00,1.00 -+043.00,+00.00,01.00,000.00,1.00 -+050.00,+00.00,01.00,000.00,1.00 -+058.00,+00.00,01.00,000.00,1.00 -+065.00,+00.00,01.00,000.00,1.00 -+072.00,+00.00,01.00,000.00,1.00 -+079.00,+00.00,01.00,000.00,1.00 -+086.00,+00.00,01.00,000.00,1.00 -+094.00,+00.00,01.00,000.00,1.00 -+101.00,+00.00,01.00,000.00,1.00 -+108.00,+00.00,01.00,000.00,1.00 -+115.00,+00.00,01.00,000.00,1.00 -+122.00,+00.00,01.00,000.00,1.00 -+130.00,+00.00,01.00,000.00,1.00 -+137.00,+00.00,01.00,000.00,1.00 -+144.00,+00.00,01.00,000.00,1.00 -+151.00,+00.00,01.00,000.00,1.00 -+158.00,+00.00,01.00,000.00,1.00 -+166.00,+00.00,01.00,000.00,1.00 -+173.00,+00.00,01.00,000.00,1.00 -+180.00,+00.00,01.00,000.00,1.00 -+187.00,+00.00,01.00,000.00,1.00 -+194.00,+00.00,01.00,000.00,1.00 -+202.00,+00.00,01.00,000.00,1.00 -+209.00,+00.00,01.00,000.00,1.00 -+216.00,+00.00,01.00,000.00,1.00 -+223.00,+00.00,01.00,000.00,1.00 -+230.00,+00.00,01.00,000.00,1.00 -+238.00,+00.00,01.00,000.00,1.00 -+245.00,+00.00,01.00,000.00,1.00 -+252.00,+00.00,01.00,000.00,1.00 -+259.00,+00.00,01.00,000.00,1.00 -+266.00,+00.00,01.00,000.00,1.00 -+274.00,+00.00,01.00,000.00,1.00 -+281.00,+00.00,01.00,000.00,1.00 -+288.00,+00.00,01.00,000.00,1.00 -+295.00,+00.00,01.00,000.00,1.00 -+302.00,+00.00,01.00,000.00,1.00 -+310.00,+00.00,01.00,000.00,1.00 -+317.00,+00.00,01.00,000.00,1.00 -+324.00,+00.00,01.00,000.00,1.00 -+331.00,+00.00,01.00,000.00,1.00 -+338.00,+00.00,01.00,000.00,1.00 -+346.00,+00.00,01.00,000.00,1.00 -+353.00,+00.00,01.00,000.00,1.00 diff --git a/tests/renderer/data/ism_-90a_0e.csv b/tests/renderer/data/ism_-90a_0e.csv deleted file mode 100644 index 766ba1023f..0000000000 --- a/tests/renderer/data/ism_-90a_0e.csv +++ /dev/null @@ -1,750 +0,0 @@ -0,-90,0,1,0,1 -1,-90,0,1,0,1 -2,-90,0,1,0,1 -3,-90,0,1,0,1 -4,-90,0,1,0,1 -5,-90,0,1,0,1 -6,-90,0,1,0,1 -7,-90,0,1,0,1 -8,-90,0,1,0,1 -9,-90,0,1,0,1 -10,-90,0,1,0,1 -11,-90,0,1,0,1 -12,-90,0,1,0,1 -13,-90,0,1,0,1 -14,-90,0,1,0,1 -15,-90,0,1,0,1 -16,-90,0,1,0,1 -17,-90,0,1,0,1 -18,-90,0,1,0,1 -19,-90,0,1,0,1 -20,-90,0,1,0,1 -21,-90,0,1,0,1 -22,-90,0,1,0,1 -23,-90,0,1,0,1 -24,-90,0,1,0,1 -25,-90,0,1,0,1 -26,-90,0,1,0,1 -27,-90,0,1,0,1 -28,-90,0,1,0,1 -29,-90,0,1,0,1 -30,-90,0,1,0,1 -31,-90,0,1,0,1 -32,-90,0,1,0,1 -33,-90,0,1,0,1 -34,-90,0,1,0,1 -35,-90,0,1,0,1 -36,-90,0,1,0,1 -37,-90,0,1,0,1 -38,-90,0,1,0,1 -39,-90,0,1,0,1 -40,-90,0,1,0,1 -41,-90,0,1,0,1 -42,-90,0,1,0,1 -43,-90,0,1,0,1 -44,-90,0,1,0,1 -45,-90,0,1,0,1 -46,-90,0,1,0,1 -47,-90,0,1,0,1 -48,-90,0,1,0,1 -49,-90,0,1,0,1 -50,-90,0,1,0,1 -51,-90,0,1,0,1 -52,-90,0,1,0,1 -53,-90,0,1,0,1 -54,-90,0,1,0,1 -55,-90,0,1,0,1 -56,-90,0,1,0,1 -57,-90,0,1,0,1 -58,-90,0,1,0,1 -59,-90,0,1,0,1 -60,-90,0,1,0,1 -61,-90,0,1,0,1 -62,-90,0,1,0,1 -63,-90,0,1,0,1 -64,-90,0,1,0,1 -65,-90,0,1,0,1 -66,-90,0,1,0,1 -67,-90,0,1,0,1 -68,-90,0,1,0,1 -69,-90,0,1,0,1 -70,-90,0,1,0,1 -71,-90,0,1,0,1 -72,-90,0,1,0,1 -73,-90,0,1,0,1 -74,-90,0,1,0,1 -75,-90,0,1,0,1 -76,-90,0,1,0,1 -77,-90,0,1,0,1 -78,-90,0,1,0,1 -79,-90,0,1,0,1 -80,-90,0,1,0,1 -81,-90,0,1,0,1 -82,-90,0,1,0,1 -83,-90,0,1,0,1 -84,-90,0,1,0,1 -85,-90,0,1,0,1 -86,-90,0,1,0,1 -87,-90,0,1,0,1 -88,-90,0,1,0,1 -89,-90,0,1,0,1 -90,-90,0,1,0,1 -91,-90,0,1,0,1 -92,-90,0,1,0,1 -93,-90,0,1,0,1 -94,-90,0,1,0,1 -95,-90,0,1,0,1 -96,-90,0,1,0,1 -97,-90,0,1,0,1 -98,-90,0,1,0,1 -99,-90,0,1,0,1 -100,-90,0,1,0,1 -101,-90,0,1,0,1 -102,-90,0,1,0,1 -103,-90,0,1,0,1 -104,-90,0,1,0,1 -105,-90,0,1,0,1 -106,-90,0,1,0,1 -107,-90,0,1,0,1 -108,-90,0,1,0,1 -109,-90,0,1,0,1 -110,-90,0,1,0,1 -111,-90,0,1,0,1 -112,-90,0,1,0,1 -113,-90,0,1,0,1 -114,-90,0,1,0,1 -115,-90,0,1,0,1 -116,-90,0,1,0,1 -117,-90,0,1,0,1 -118,-90,0,1,0,1 -119,-90,0,1,0,1 -120,-90,0,1,0,1 -121,-90,0,1,0,1 -122,-90,0,1,0,1 -123,-90,0,1,0,1 -124,-90,0,1,0,1 -125,-90,0,1,0,1 -126,-90,0,1,0,1 -127,-90,0,1,0,1 -128,-90,0,1,0,1 -129,-90,0,1,0,1 -130,-90,0,1,0,1 -131,-90,0,1,0,1 -132,-90,0,1,0,1 -133,-90,0,1,0,1 -134,-90,0,1,0,1 -135,-90,0,1,0,1 -136,-90,0,1,0,1 -137,-90,0,1,0,1 -138,-90,0,1,0,1 -139,-90,0,1,0,1 -140,-90,0,1,0,1 -141,-90,0,1,0,1 -142,-90,0,1,0,1 -143,-90,0,1,0,1 -144,-90,0,1,0,1 -145,-90,0,1,0,1 -146,-90,0,1,0,1 -147,-90,0,1,0,1 -148,-90,0,1,0,1 -149,-90,0,1,0,1 -150,-90,0,1,0,1 -151,-90,0,1,0,1 -152,-90,0,1,0,1 -153,-90,0,1,0,1 -154,-90,0,1,0,1 -155,-90,0,1,0,1 -156,-90,0,1,0,1 -157,-90,0,1,0,1 -158,-90,0,1,0,1 -159,-90,0,1,0,1 -160,-90,0,1,0,1 -161,-90,0,1,0,1 -162,-90,0,1,0,1 -163,-90,0,1,0,1 -164,-90,0,1,0,1 -165,-90,0,1,0,1 -166,-90,0,1,0,1 -167,-90,0,1,0,1 -168,-90,0,1,0,1 -169,-90,0,1,0,1 -170,-90,0,1,0,1 -171,-90,0,1,0,1 -172,-90,0,1,0,1 -173,-90,0,1,0,1 -174,-90,0,1,0,1 -175,-90,0,1,0,1 -176,-90,0,1,0,1 -177,-90,0,1,0,1 -178,-90,0,1,0,1 -179,-90,0,1,0,1 -180,-90,0,1,0,1 -181,-90,0,1,0,1 -182,-90,0,1,0,1 -183,-90,0,1,0,1 -184,-90,0,1,0,1 -185,-90,0,1,0,1 -186,-90,0,1,0,1 -187,-90,0,1,0,1 -188,-90,0,1,0,1 -189,-90,0,1,0,1 -190,-90,0,1,0,1 -191,-90,0,1,0,1 -192,-90,0,1,0,1 -193,-90,0,1,0,1 -194,-90,0,1,0,1 -195,-90,0,1,0,1 -196,-90,0,1,0,1 -197,-90,0,1,0,1 -198,-90,0,1,0,1 -199,-90,0,1,0,1 -200,-90,0,1,0,1 -201,-90,0,1,0,1 -202,-90,0,1,0,1 -203,-90,0,1,0,1 -204,-90,0,1,0,1 -205,-90,0,1,0,1 -206,-90,0,1,0,1 -207,-90,0,1,0,1 -208,-90,0,1,0,1 -209,-90,0,1,0,1 -210,-90,0,1,0,1 -211,-90,0,1,0,1 -212,-90,0,1,0,1 -213,-90,0,1,0,1 -214,-90,0,1,0,1 -215,-90,0,1,0,1 -216,-90,0,1,0,1 -217,-90,0,1,0,1 -218,-90,0,1,0,1 -219,-90,0,1,0,1 -220,-90,0,1,0,1 -221,-90,0,1,0,1 -222,-90,0,1,0,1 -223,-90,0,1,0,1 -224,-90,0,1,0,1 -225,-90,0,1,0,1 -226,-90,0,1,0,1 -227,-90,0,1,0,1 -228,-90,0,1,0,1 -229,-90,0,1,0,1 -230,-90,0,1,0,1 -231,-90,0,1,0,1 -232,-90,0,1,0,1 -233,-90,0,1,0,1 -234,-90,0,1,0,1 -235,-90,0,1,0,1 -236,-90,0,1,0,1 -237,-90,0,1,0,1 -238,-90,0,1,0,1 -239,-90,0,1,0,1 -240,-90,0,1,0,1 -241,-90,0,1,0,1 -242,-90,0,1,0,1 -243,-90,0,1,0,1 -244,-90,0,1,0,1 -245,-90,0,1,0,1 -246,-90,0,1,0,1 -247,-90,0,1,0,1 -248,-90,0,1,0,1 -249,-90,0,1,0,1 -250,-90,0,1,0,1 -251,-90,0,1,0,1 -252,-90,0,1,0,1 -253,-90,0,1,0,1 -254,-90,0,1,0,1 -255,-90,0,1,0,1 -256,-90,0,1,0,1 -257,-90,0,1,0,1 -258,-90,0,1,0,1 -259,-90,0,1,0,1 -260,-90,0,1,0,1 -261,-90,0,1,0,1 -262,-90,0,1,0,1 -263,-90,0,1,0,1 -264,-90,0,1,0,1 -265,-90,0,1,0,1 -266,-90,0,1,0,1 -267,-90,0,1,0,1 -268,-90,0,1,0,1 -269,-90,0,1,0,1 -270,-90,0,1,0,1 -271,-90,0,1,0,1 -272,-90,0,1,0,1 -273,-90,0,1,0,1 -274,-90,0,1,0,1 -275,-90,0,1,0,1 -276,-90,0,1,0,1 -277,-90,0,1,0,1 -278,-90,0,1,0,1 -279,-90,0,1,0,1 -280,-90,0,1,0,1 -281,-90,0,1,0,1 -282,-90,0,1,0,1 -283,-90,0,1,0,1 -284,-90,0,1,0,1 -285,-90,0,1,0,1 -286,-90,0,1,0,1 -287,-90,0,1,0,1 -288,-90,0,1,0,1 -289,-90,0,1,0,1 -290,-90,0,1,0,1 -291,-90,0,1,0,1 -292,-90,0,1,0,1 -293,-90,0,1,0,1 -294,-90,0,1,0,1 -295,-90,0,1,0,1 -296,-90,0,1,0,1 -297,-90,0,1,0,1 -298,-90,0,1,0,1 -299,-90,0,1,0,1 -300,-90,0,1,0,1 -301,-90,0,1,0,1 -302,-90,0,1,0,1 -303,-90,0,1,0,1 -304,-90,0,1,0,1 -305,-90,0,1,0,1 -306,-90,0,1,0,1 -307,-90,0,1,0,1 -308,-90,0,1,0,1 -309,-90,0,1,0,1 -310,-90,0,1,0,1 -311,-90,0,1,0,1 -312,-90,0,1,0,1 -313,-90,0,1,0,1 -314,-90,0,1,0,1 -315,-90,0,1,0,1 -316,-90,0,1,0,1 -317,-90,0,1,0,1 -318,-90,0,1,0,1 -319,-90,0,1,0,1 -320,-90,0,1,0,1 -321,-90,0,1,0,1 -322,-90,0,1,0,1 -323,-90,0,1,0,1 -324,-90,0,1,0,1 -325,-90,0,1,0,1 -326,-90,0,1,0,1 -327,-90,0,1,0,1 -328,-90,0,1,0,1 -329,-90,0,1,0,1 -330,-90,0,1,0,1 -331,-90,0,1,0,1 -332,-90,0,1,0,1 -333,-90,0,1,0,1 -334,-90,0,1,0,1 -335,-90,0,1,0,1 -336,-90,0,1,0,1 -337,-90,0,1,0,1 -338,-90,0,1,0,1 -339,-90,0,1,0,1 -340,-90,0,1,0,1 -341,-90,0,1,0,1 -342,-90,0,1,0,1 -343,-90,0,1,0,1 -344,-90,0,1,0,1 -345,-90,0,1,0,1 -346,-90,0,1,0,1 -347,-90,0,1,0,1 -348,-90,0,1,0,1 -349,-90,0,1,0,1 -350,-90,0,1,0,1 -351,-90,0,1,0,1 -352,-90,0,1,0,1 -353,-90,0,1,0,1 -354,-90,0,1,0,1 -355,-90,0,1,0,1 -356,-90,0,1,0,1 -357,-90,0,1,0,1 -358,-90,0,1,0,1 -359,-90,0,1,0,1 -360,-90,0,1,0,1 -361,-90,0,1,0,1 -362,-90,0,1,0,1 -363,-90,0,1,0,1 -364,-90,0,1,0,1 -365,-90,0,1,0,1 -366,-90,0,1,0,1 -367,-90,0,1,0,1 -368,-90,0,1,0,1 -369,-90,0,1,0,1 -370,-90,0,1,0,1 -371,-90,0,1,0,1 -372,-90,0,1,0,1 -373,-90,0,1,0,1 -374,-90,0,1,0,1 -375,-90,0,1,0,1 -376,-90,0,1,0,1 -377,-90,0,1,0,1 -378,-90,0,1,0,1 -379,-90,0,1,0,1 -380,-90,0,1,0,1 -381,-90,0,1,0,1 -382,-90,0,1,0,1 -383,-90,0,1,0,1 -384,-90,0,1,0,1 -385,-90,0,1,0,1 -386,-90,0,1,0,1 -387,-90,0,1,0,1 -388,-90,0,1,0,1 -389,-90,0,1,0,1 -390,-90,0,1,0,1 -391,-90,0,1,0,1 -392,-90,0,1,0,1 -393,-90,0,1,0,1 -394,-90,0,1,0,1 -395,-90,0,1,0,1 -396,-90,0,1,0,1 -397,-90,0,1,0,1 -398,-90,0,1,0,1 -399,-90,0,1,0,1 -400,-90,0,1,0,1 -401,-90,0,1,0,1 -402,-90,0,1,0,1 -403,-90,0,1,0,1 -404,-90,0,1,0,1 -405,-90,0,1,0,1 -406,-90,0,1,0,1 -407,-90,0,1,0,1 -408,-90,0,1,0,1 -409,-90,0,1,0,1 -410,-90,0,1,0,1 -411,-90,0,1,0,1 -412,-90,0,1,0,1 -413,-90,0,1,0,1 -414,-90,0,1,0,1 -415,-90,0,1,0,1 -416,-90,0,1,0,1 -417,-90,0,1,0,1 -418,-90,0,1,0,1 -419,-90,0,1,0,1 -420,-90,0,1,0,1 -421,-90,0,1,0,1 -422,-90,0,1,0,1 -423,-90,0,1,0,1 -424,-90,0,1,0,1 -425,-90,0,1,0,1 -426,-90,0,1,0,1 -427,-90,0,1,0,1 -428,-90,0,1,0,1 -429,-90,0,1,0,1 -430,-90,0,1,0,1 -431,-90,0,1,0,1 -432,-90,0,1,0,1 -433,-90,0,1,0,1 -434,-90,0,1,0,1 -435,-90,0,1,0,1 -436,-90,0,1,0,1 -437,-90,0,1,0,1 -438,-90,0,1,0,1 -439,-90,0,1,0,1 -440,-90,0,1,0,1 -441,-90,0,1,0,1 -442,-90,0,1,0,1 -443,-90,0,1,0,1 -444,-90,0,1,0,1 -445,-90,0,1,0,1 -446,-90,0,1,0,1 -447,-90,0,1,0,1 -448,-90,0,1,0,1 -449,-90,0,1,0,1 -450,-90,0,1,0,1 -451,-90,0,1,0,1 -452,-90,0,1,0,1 -453,-90,0,1,0,1 -454,-90,0,1,0,1 -455,-90,0,1,0,1 -456,-90,0,1,0,1 -457,-90,0,1,0,1 -458,-90,0,1,0,1 -459,-90,0,1,0,1 -460,-90,0,1,0,1 -461,-90,0,1,0,1 -462,-90,0,1,0,1 -463,-90,0,1,0,1 -464,-90,0,1,0,1 -465,-90,0,1,0,1 -466,-90,0,1,0,1 -467,-90,0,1,0,1 -468,-90,0,1,0,1 -469,-90,0,1,0,1 -470,-90,0,1,0,1 -471,-90,0,1,0,1 -472,-90,0,1,0,1 -473,-90,0,1,0,1 -474,-90,0,1,0,1 -475,-90,0,1,0,1 -476,-90,0,1,0,1 -477,-90,0,1,0,1 -478,-90,0,1,0,1 -479,-90,0,1,0,1 -480,-90,0,1,0,1 -481,-90,0,1,0,1 -482,-90,0,1,0,1 -483,-90,0,1,0,1 -484,-90,0,1,0,1 -485,-90,0,1,0,1 -486,-90,0,1,0,1 -487,-90,0,1,0,1 -488,-90,0,1,0,1 -489,-90,0,1,0,1 -490,-90,0,1,0,1 -491,-90,0,1,0,1 -492,-90,0,1,0,1 -493,-90,0,1,0,1 -494,-90,0,1,0,1 -495,-90,0,1,0,1 -496,-90,0,1,0,1 -497,-90,0,1,0,1 -498,-90,0,1,0,1 -499,-90,0,1,0,1 -500,-90,0,1,0,1 -501,-90,0,1,0,1 -502,-90,0,1,0,1 -503,-90,0,1,0,1 -504,-90,0,1,0,1 -505,-90,0,1,0,1 -506,-90,0,1,0,1 -507,-90,0,1,0,1 -508,-90,0,1,0,1 -509,-90,0,1,0,1 -510,-90,0,1,0,1 -511,-90,0,1,0,1 -512,-90,0,1,0,1 -513,-90,0,1,0,1 -514,-90,0,1,0,1 -515,-90,0,1,0,1 -516,-90,0,1,0,1 -517,-90,0,1,0,1 -518,-90,0,1,0,1 -519,-90,0,1,0,1 -520,-90,0,1,0,1 -521,-90,0,1,0,1 -522,-90,0,1,0,1 -523,-90,0,1,0,1 -524,-90,0,1,0,1 -525,-90,0,1,0,1 -526,-90,0,1,0,1 -527,-90,0,1,0,1 -528,-90,0,1,0,1 -529,-90,0,1,0,1 -530,-90,0,1,0,1 -531,-90,0,1,0,1 -532,-90,0,1,0,1 -533,-90,0,1,0,1 -534,-90,0,1,0,1 -535,-90,0,1,0,1 -536,-90,0,1,0,1 -537,-90,0,1,0,1 -538,-90,0,1,0,1 -539,-90,0,1,0,1 -540,-90,0,1,0,1 -541,-90,0,1,0,1 -542,-90,0,1,0,1 -543,-90,0,1,0,1 -544,-90,0,1,0,1 -545,-90,0,1,0,1 -546,-90,0,1,0,1 -547,-90,0,1,0,1 -548,-90,0,1,0,1 -549,-90,0,1,0,1 -550,-90,0,1,0,1 -551,-90,0,1,0,1 -552,-90,0,1,0,1 -553,-90,0,1,0,1 -554,-90,0,1,0,1 -555,-90,0,1,0,1 -556,-90,0,1,0,1 -557,-90,0,1,0,1 -558,-90,0,1,0,1 -559,-90,0,1,0,1 -560,-90,0,1,0,1 -561,-90,0,1,0,1 -562,-90,0,1,0,1 -563,-90,0,1,0,1 -564,-90,0,1,0,1 -565,-90,0,1,0,1 -566,-90,0,1,0,1 -567,-90,0,1,0,1 -568,-90,0,1,0,1 -569,-90,0,1,0,1 -570,-90,0,1,0,1 -571,-90,0,1,0,1 -572,-90,0,1,0,1 -573,-90,0,1,0,1 -574,-90,0,1,0,1 -575,-90,0,1,0,1 -576,-90,0,1,0,1 -577,-90,0,1,0,1 -578,-90,0,1,0,1 -579,-90,0,1,0,1 -580,-90,0,1,0,1 -581,-90,0,1,0,1 -582,-90,0,1,0,1 -583,-90,0,1,0,1 -584,-90,0,1,0,1 -585,-90,0,1,0,1 -586,-90,0,1,0,1 -587,-90,0,1,0,1 -588,-90,0,1,0,1 -589,-90,0,1,0,1 -590,-90,0,1,0,1 -591,-90,0,1,0,1 -592,-90,0,1,0,1 -593,-90,0,1,0,1 -594,-90,0,1,0,1 -595,-90,0,1,0,1 -596,-90,0,1,0,1 -597,-90,0,1,0,1 -598,-90,0,1,0,1 -599,-90,0,1,0,1 -600,-90,0,1,0,1 -601,-90,0,1,0,1 -602,-90,0,1,0,1 -603,-90,0,1,0,1 -604,-90,0,1,0,1 -605,-90,0,1,0,1 -606,-90,0,1,0,1 -607,-90,0,1,0,1 -608,-90,0,1,0,1 -609,-90,0,1,0,1 -610,-90,0,1,0,1 -611,-90,0,1,0,1 -612,-90,0,1,0,1 -613,-90,0,1,0,1 -614,-90,0,1,0,1 -615,-90,0,1,0,1 -616,-90,0,1,0,1 -617,-90,0,1,0,1 -618,-90,0,1,0,1 -619,-90,0,1,0,1 -620,-90,0,1,0,1 -621,-90,0,1,0,1 -622,-90,0,1,0,1 -623,-90,0,1,0,1 -624,-90,0,1,0,1 -625,-90,0,1,0,1 -626,-90,0,1,0,1 -627,-90,0,1,0,1 -628,-90,0,1,0,1 -629,-90,0,1,0,1 -630,-90,0,1,0,1 -631,-90,0,1,0,1 -632,-90,0,1,0,1 -633,-90,0,1,0,1 -634,-90,0,1,0,1 -635,-90,0,1,0,1 -636,-90,0,1,0,1 -637,-90,0,1,0,1 -638,-90,0,1,0,1 -639,-90,0,1,0,1 -640,-90,0,1,0,1 -641,-90,0,1,0,1 -642,-90,0,1,0,1 -643,-90,0,1,0,1 -644,-90,0,1,0,1 -645,-90,0,1,0,1 -646,-90,0,1,0,1 -647,-90,0,1,0,1 -648,-90,0,1,0,1 -649,-90,0,1,0,1 -650,-90,0,1,0,1 -651,-90,0,1,0,1 -652,-90,0,1,0,1 -653,-90,0,1,0,1 -654,-90,0,1,0,1 -655,-90,0,1,0,1 -656,-90,0,1,0,1 -657,-90,0,1,0,1 -658,-90,0,1,0,1 -659,-90,0,1,0,1 -660,-90,0,1,0,1 -661,-90,0,1,0,1 -662,-90,0,1,0,1 -663,-90,0,1,0,1 -664,-90,0,1,0,1 -665,-90,0,1,0,1 -666,-90,0,1,0,1 -667,-90,0,1,0,1 -668,-90,0,1,0,1 -669,-90,0,1,0,1 -670,-90,0,1,0,1 -671,-90,0,1,0,1 -672,-90,0,1,0,1 -673,-90,0,1,0,1 -674,-90,0,1,0,1 -675,-90,0,1,0,1 -676,-90,0,1,0,1 -677,-90,0,1,0,1 -678,-90,0,1,0,1 -679,-90,0,1,0,1 -680,-90,0,1,0,1 -681,-90,0,1,0,1 -682,-90,0,1,0,1 -683,-90,0,1,0,1 -684,-90,0,1,0,1 -685,-90,0,1,0,1 -686,-90,0,1,0,1 -687,-90,0,1,0,1 -688,-90,0,1,0,1 -689,-90,0,1,0,1 -690,-90,0,1,0,1 -691,-90,0,1,0,1 -692,-90,0,1,0,1 -693,-90,0,1,0,1 -694,-90,0,1,0,1 -695,-90,0,1,0,1 -696,-90,0,1,0,1 -697,-90,0,1,0,1 -698,-90,0,1,0,1 -699,-90,0,1,0,1 -700,-90,0,1,0,1 -701,-90,0,1,0,1 -702,-90,0,1,0,1 -703,-90,0,1,0,1 -704,-90,0,1,0,1 -705,-90,0,1,0,1 -706,-90,0,1,0,1 -707,-90,0,1,0,1 -708,-90,0,1,0,1 -709,-90,0,1,0,1 -710,-90,0,1,0,1 -711,-90,0,1,0,1 -712,-90,0,1,0,1 -713,-90,0,1,0,1 -714,-90,0,1,0,1 -715,-90,0,1,0,1 -716,-90,0,1,0,1 -717,-90,0,1,0,1 -718,-90,0,1,0,1 -719,-90,0,1,0,1 -720,-90,0,1,0,1 -721,-90,0,1,0,1 -722,-90,0,1,0,1 -723,-90,0,1,0,1 -724,-90,0,1,0,1 -725,-90,0,1,0,1 -726,-90,0,1,0,1 -727,-90,0,1,0,1 -728,-90,0,1,0,1 -729,-90,0,1,0,1 -730,-90,0,1,0,1 -731,-90,0,1,0,1 -732,-90,0,1,0,1 -733,-90,0,1,0,1 -734,-90,0,1,0,1 -735,-90,0,1,0,1 -736,-90,0,1,0,1 -737,-90,0,1,0,1 -738,-90,0,1,0,1 -739,-90,0,1,0,1 -740,-90,0,1,0,1 -741,-90,0,1,0,1 -742,-90,0,1,0,1 -743,-90,0,1,0,1 -744,-90,0,1,0,1 -745,-90,0,1,0,1 -746,-90,0,1,0,1 -747,-90,0,1,0,1 -748,-90,0,1,0,1 -749,-90,0,1,0,1 diff --git a/tests/renderer/data/ism_180a_0e.csv b/tests/renderer/data/ism_180a_0e.csv deleted file mode 100644 index 2db0f1a477..0000000000 --- a/tests/renderer/data/ism_180a_0e.csv +++ /dev/null @@ -1,750 +0,0 @@ -0,180,0,1,0,1 -1,180,0,1,0,1 -2,180,0,1,0,1 -3,180,0,1,0,1 -4,180,0,1,0,1 -5,180,0,1,0,1 -6,180,0,1,0,1 -7,180,0,1,0,1 -8,180,0,1,0,1 -9,180,0,1,0,1 -10,180,0,1,0,1 -11,180,0,1,0,1 -12,180,0,1,0,1 -13,180,0,1,0,1 -14,180,0,1,0,1 -15,180,0,1,0,1 -16,180,0,1,0,1 -17,180,0,1,0,1 -18,180,0,1,0,1 -19,180,0,1,0,1 -20,180,0,1,0,1 -21,180,0,1,0,1 -22,180,0,1,0,1 -23,180,0,1,0,1 -24,180,0,1,0,1 -25,180,0,1,0,1 -26,180,0,1,0,1 -27,180,0,1,0,1 -28,180,0,1,0,1 -29,180,0,1,0,1 -30,180,0,1,0,1 -31,180,0,1,0,1 -32,180,0,1,0,1 -33,180,0,1,0,1 -34,180,0,1,0,1 -35,180,0,1,0,1 -36,180,0,1,0,1 -37,180,0,1,0,1 -38,180,0,1,0,1 -39,180,0,1,0,1 -40,180,0,1,0,1 -41,180,0,1,0,1 -42,180,0,1,0,1 -43,180,0,1,0,1 -44,180,0,1,0,1 -45,180,0,1,0,1 -46,180,0,1,0,1 -47,180,0,1,0,1 -48,180,0,1,0,1 -49,180,0,1,0,1 -50,180,0,1,0,1 -51,180,0,1,0,1 -52,180,0,1,0,1 -53,180,0,1,0,1 -54,180,0,1,0,1 -55,180,0,1,0,1 -56,180,0,1,0,1 -57,180,0,1,0,1 -58,180,0,1,0,1 -59,180,0,1,0,1 -60,180,0,1,0,1 -61,180,0,1,0,1 -62,180,0,1,0,1 -63,180,0,1,0,1 -64,180,0,1,0,1 -65,180,0,1,0,1 -66,180,0,1,0,1 -67,180,0,1,0,1 -68,180,0,1,0,1 -69,180,0,1,0,1 -70,180,0,1,0,1 -71,180,0,1,0,1 -72,180,0,1,0,1 -73,180,0,1,0,1 -74,180,0,1,0,1 -75,180,0,1,0,1 -76,180,0,1,0,1 -77,180,0,1,0,1 -78,180,0,1,0,1 -79,180,0,1,0,1 -80,180,0,1,0,1 -81,180,0,1,0,1 -82,180,0,1,0,1 -83,180,0,1,0,1 -84,180,0,1,0,1 -85,180,0,1,0,1 -86,180,0,1,0,1 -87,180,0,1,0,1 -88,180,0,1,0,1 -89,180,0,1,0,1 -90,180,0,1,0,1 -91,180,0,1,0,1 -92,180,0,1,0,1 -93,180,0,1,0,1 -94,180,0,1,0,1 -95,180,0,1,0,1 -96,180,0,1,0,1 -97,180,0,1,0,1 -98,180,0,1,0,1 -99,180,0,1,0,1 -100,180,0,1,0,1 -101,180,0,1,0,1 -102,180,0,1,0,1 -103,180,0,1,0,1 -104,180,0,1,0,1 -105,180,0,1,0,1 -106,180,0,1,0,1 -107,180,0,1,0,1 -108,180,0,1,0,1 -109,180,0,1,0,1 -110,180,0,1,0,1 -111,180,0,1,0,1 -112,180,0,1,0,1 -113,180,0,1,0,1 -114,180,0,1,0,1 -115,180,0,1,0,1 -116,180,0,1,0,1 -117,180,0,1,0,1 -118,180,0,1,0,1 -119,180,0,1,0,1 -120,180,0,1,0,1 -121,180,0,1,0,1 -122,180,0,1,0,1 -123,180,0,1,0,1 -124,180,0,1,0,1 -125,180,0,1,0,1 -126,180,0,1,0,1 -127,180,0,1,0,1 -128,180,0,1,0,1 -129,180,0,1,0,1 -130,180,0,1,0,1 -131,180,0,1,0,1 -132,180,0,1,0,1 -133,180,0,1,0,1 -134,180,0,1,0,1 -135,180,0,1,0,1 -136,180,0,1,0,1 -137,180,0,1,0,1 -138,180,0,1,0,1 -139,180,0,1,0,1 -140,180,0,1,0,1 -141,180,0,1,0,1 -142,180,0,1,0,1 -143,180,0,1,0,1 -144,180,0,1,0,1 -145,180,0,1,0,1 -146,180,0,1,0,1 -147,180,0,1,0,1 -148,180,0,1,0,1 -149,180,0,1,0,1 -150,180,0,1,0,1 -151,180,0,1,0,1 -152,180,0,1,0,1 -153,180,0,1,0,1 -154,180,0,1,0,1 -155,180,0,1,0,1 -156,180,0,1,0,1 -157,180,0,1,0,1 -158,180,0,1,0,1 -159,180,0,1,0,1 -160,180,0,1,0,1 -161,180,0,1,0,1 -162,180,0,1,0,1 -163,180,0,1,0,1 -164,180,0,1,0,1 -165,180,0,1,0,1 -166,180,0,1,0,1 -167,180,0,1,0,1 -168,180,0,1,0,1 -169,180,0,1,0,1 -170,180,0,1,0,1 -171,180,0,1,0,1 -172,180,0,1,0,1 -173,180,0,1,0,1 -174,180,0,1,0,1 -175,180,0,1,0,1 -176,180,0,1,0,1 -177,180,0,1,0,1 -178,180,0,1,0,1 -179,180,0,1,0,1 -180,180,0,1,0,1 -181,180,0,1,0,1 -182,180,0,1,0,1 -183,180,0,1,0,1 -184,180,0,1,0,1 -185,180,0,1,0,1 -186,180,0,1,0,1 -187,180,0,1,0,1 -188,180,0,1,0,1 -189,180,0,1,0,1 -190,180,0,1,0,1 -191,180,0,1,0,1 -192,180,0,1,0,1 -193,180,0,1,0,1 -194,180,0,1,0,1 -195,180,0,1,0,1 -196,180,0,1,0,1 -197,180,0,1,0,1 -198,180,0,1,0,1 -199,180,0,1,0,1 -200,180,0,1,0,1 -201,180,0,1,0,1 -202,180,0,1,0,1 -203,180,0,1,0,1 -204,180,0,1,0,1 -205,180,0,1,0,1 -206,180,0,1,0,1 -207,180,0,1,0,1 -208,180,0,1,0,1 -209,180,0,1,0,1 -210,180,0,1,0,1 -211,180,0,1,0,1 -212,180,0,1,0,1 -213,180,0,1,0,1 -214,180,0,1,0,1 -215,180,0,1,0,1 -216,180,0,1,0,1 -217,180,0,1,0,1 -218,180,0,1,0,1 -219,180,0,1,0,1 -220,180,0,1,0,1 -221,180,0,1,0,1 -222,180,0,1,0,1 -223,180,0,1,0,1 -224,180,0,1,0,1 -225,180,0,1,0,1 -226,180,0,1,0,1 -227,180,0,1,0,1 -228,180,0,1,0,1 -229,180,0,1,0,1 -230,180,0,1,0,1 -231,180,0,1,0,1 -232,180,0,1,0,1 -233,180,0,1,0,1 -234,180,0,1,0,1 -235,180,0,1,0,1 -236,180,0,1,0,1 -237,180,0,1,0,1 -238,180,0,1,0,1 -239,180,0,1,0,1 -240,180,0,1,0,1 -241,180,0,1,0,1 -242,180,0,1,0,1 -243,180,0,1,0,1 -244,180,0,1,0,1 -245,180,0,1,0,1 -246,180,0,1,0,1 -247,180,0,1,0,1 -248,180,0,1,0,1 -249,180,0,1,0,1 -250,180,0,1,0,1 -251,180,0,1,0,1 -252,180,0,1,0,1 -253,180,0,1,0,1 -254,180,0,1,0,1 -255,180,0,1,0,1 -256,180,0,1,0,1 -257,180,0,1,0,1 -258,180,0,1,0,1 -259,180,0,1,0,1 -260,180,0,1,0,1 -261,180,0,1,0,1 -262,180,0,1,0,1 -263,180,0,1,0,1 -264,180,0,1,0,1 -265,180,0,1,0,1 -266,180,0,1,0,1 -267,180,0,1,0,1 -268,180,0,1,0,1 -269,180,0,1,0,1 -270,180,0,1,0,1 -271,180,0,1,0,1 -272,180,0,1,0,1 -273,180,0,1,0,1 -274,180,0,1,0,1 -275,180,0,1,0,1 -276,180,0,1,0,1 -277,180,0,1,0,1 -278,180,0,1,0,1 -279,180,0,1,0,1 -280,180,0,1,0,1 -281,180,0,1,0,1 -282,180,0,1,0,1 -283,180,0,1,0,1 -284,180,0,1,0,1 -285,180,0,1,0,1 -286,180,0,1,0,1 -287,180,0,1,0,1 -288,180,0,1,0,1 -289,180,0,1,0,1 -290,180,0,1,0,1 -291,180,0,1,0,1 -292,180,0,1,0,1 -293,180,0,1,0,1 -294,180,0,1,0,1 -295,180,0,1,0,1 -296,180,0,1,0,1 -297,180,0,1,0,1 -298,180,0,1,0,1 -299,180,0,1,0,1 -300,180,0,1,0,1 -301,180,0,1,0,1 -302,180,0,1,0,1 -303,180,0,1,0,1 -304,180,0,1,0,1 -305,180,0,1,0,1 -306,180,0,1,0,1 -307,180,0,1,0,1 -308,180,0,1,0,1 -309,180,0,1,0,1 -310,180,0,1,0,1 -311,180,0,1,0,1 -312,180,0,1,0,1 -313,180,0,1,0,1 -314,180,0,1,0,1 -315,180,0,1,0,1 -316,180,0,1,0,1 -317,180,0,1,0,1 -318,180,0,1,0,1 -319,180,0,1,0,1 -320,180,0,1,0,1 -321,180,0,1,0,1 -322,180,0,1,0,1 -323,180,0,1,0,1 -324,180,0,1,0,1 -325,180,0,1,0,1 -326,180,0,1,0,1 -327,180,0,1,0,1 -328,180,0,1,0,1 -329,180,0,1,0,1 -330,180,0,1,0,1 -331,180,0,1,0,1 -332,180,0,1,0,1 -333,180,0,1,0,1 -334,180,0,1,0,1 -335,180,0,1,0,1 -336,180,0,1,0,1 -337,180,0,1,0,1 -338,180,0,1,0,1 -339,180,0,1,0,1 -340,180,0,1,0,1 -341,180,0,1,0,1 -342,180,0,1,0,1 -343,180,0,1,0,1 -344,180,0,1,0,1 -345,180,0,1,0,1 -346,180,0,1,0,1 -347,180,0,1,0,1 -348,180,0,1,0,1 -349,180,0,1,0,1 -350,180,0,1,0,1 -351,180,0,1,0,1 -352,180,0,1,0,1 -353,180,0,1,0,1 -354,180,0,1,0,1 -355,180,0,1,0,1 -356,180,0,1,0,1 -357,180,0,1,0,1 -358,180,0,1,0,1 -359,180,0,1,0,1 -360,180,0,1,0,1 -361,180,0,1,0,1 -362,180,0,1,0,1 -363,180,0,1,0,1 -364,180,0,1,0,1 -365,180,0,1,0,1 -366,180,0,1,0,1 -367,180,0,1,0,1 -368,180,0,1,0,1 -369,180,0,1,0,1 -370,180,0,1,0,1 -371,180,0,1,0,1 -372,180,0,1,0,1 -373,180,0,1,0,1 -374,180,0,1,0,1 -375,180,0,1,0,1 -376,180,0,1,0,1 -377,180,0,1,0,1 -378,180,0,1,0,1 -379,180,0,1,0,1 -380,180,0,1,0,1 -381,180,0,1,0,1 -382,180,0,1,0,1 -383,180,0,1,0,1 -384,180,0,1,0,1 -385,180,0,1,0,1 -386,180,0,1,0,1 -387,180,0,1,0,1 -388,180,0,1,0,1 -389,180,0,1,0,1 -390,180,0,1,0,1 -391,180,0,1,0,1 -392,180,0,1,0,1 -393,180,0,1,0,1 -394,180,0,1,0,1 -395,180,0,1,0,1 -396,180,0,1,0,1 -397,180,0,1,0,1 -398,180,0,1,0,1 -399,180,0,1,0,1 -400,180,0,1,0,1 -401,180,0,1,0,1 -402,180,0,1,0,1 -403,180,0,1,0,1 -404,180,0,1,0,1 -405,180,0,1,0,1 -406,180,0,1,0,1 -407,180,0,1,0,1 -408,180,0,1,0,1 -409,180,0,1,0,1 -410,180,0,1,0,1 -411,180,0,1,0,1 -412,180,0,1,0,1 -413,180,0,1,0,1 -414,180,0,1,0,1 -415,180,0,1,0,1 -416,180,0,1,0,1 -417,180,0,1,0,1 -418,180,0,1,0,1 -419,180,0,1,0,1 -420,180,0,1,0,1 -421,180,0,1,0,1 -422,180,0,1,0,1 -423,180,0,1,0,1 -424,180,0,1,0,1 -425,180,0,1,0,1 -426,180,0,1,0,1 -427,180,0,1,0,1 -428,180,0,1,0,1 -429,180,0,1,0,1 -430,180,0,1,0,1 -431,180,0,1,0,1 -432,180,0,1,0,1 -433,180,0,1,0,1 -434,180,0,1,0,1 -435,180,0,1,0,1 -436,180,0,1,0,1 -437,180,0,1,0,1 -438,180,0,1,0,1 -439,180,0,1,0,1 -440,180,0,1,0,1 -441,180,0,1,0,1 -442,180,0,1,0,1 -443,180,0,1,0,1 -444,180,0,1,0,1 -445,180,0,1,0,1 -446,180,0,1,0,1 -447,180,0,1,0,1 -448,180,0,1,0,1 -449,180,0,1,0,1 -450,180,0,1,0,1 -451,180,0,1,0,1 -452,180,0,1,0,1 -453,180,0,1,0,1 -454,180,0,1,0,1 -455,180,0,1,0,1 -456,180,0,1,0,1 -457,180,0,1,0,1 -458,180,0,1,0,1 -459,180,0,1,0,1 -460,180,0,1,0,1 -461,180,0,1,0,1 -462,180,0,1,0,1 -463,180,0,1,0,1 -464,180,0,1,0,1 -465,180,0,1,0,1 -466,180,0,1,0,1 -467,180,0,1,0,1 -468,180,0,1,0,1 -469,180,0,1,0,1 -470,180,0,1,0,1 -471,180,0,1,0,1 -472,180,0,1,0,1 -473,180,0,1,0,1 -474,180,0,1,0,1 -475,180,0,1,0,1 -476,180,0,1,0,1 -477,180,0,1,0,1 -478,180,0,1,0,1 -479,180,0,1,0,1 -480,180,0,1,0,1 -481,180,0,1,0,1 -482,180,0,1,0,1 -483,180,0,1,0,1 -484,180,0,1,0,1 -485,180,0,1,0,1 -486,180,0,1,0,1 -487,180,0,1,0,1 -488,180,0,1,0,1 -489,180,0,1,0,1 -490,180,0,1,0,1 -491,180,0,1,0,1 -492,180,0,1,0,1 -493,180,0,1,0,1 -494,180,0,1,0,1 -495,180,0,1,0,1 -496,180,0,1,0,1 -497,180,0,1,0,1 -498,180,0,1,0,1 -499,180,0,1,0,1 -500,180,0,1,0,1 -501,180,0,1,0,1 -502,180,0,1,0,1 -503,180,0,1,0,1 -504,180,0,1,0,1 -505,180,0,1,0,1 -506,180,0,1,0,1 -507,180,0,1,0,1 -508,180,0,1,0,1 -509,180,0,1,0,1 -510,180,0,1,0,1 -511,180,0,1,0,1 -512,180,0,1,0,1 -513,180,0,1,0,1 -514,180,0,1,0,1 -515,180,0,1,0,1 -516,180,0,1,0,1 -517,180,0,1,0,1 -518,180,0,1,0,1 -519,180,0,1,0,1 -520,180,0,1,0,1 -521,180,0,1,0,1 -522,180,0,1,0,1 -523,180,0,1,0,1 -524,180,0,1,0,1 -525,180,0,1,0,1 -526,180,0,1,0,1 -527,180,0,1,0,1 -528,180,0,1,0,1 -529,180,0,1,0,1 -530,180,0,1,0,1 -531,180,0,1,0,1 -532,180,0,1,0,1 -533,180,0,1,0,1 -534,180,0,1,0,1 -535,180,0,1,0,1 -536,180,0,1,0,1 -537,180,0,1,0,1 -538,180,0,1,0,1 -539,180,0,1,0,1 -540,180,0,1,0,1 -541,180,0,1,0,1 -542,180,0,1,0,1 -543,180,0,1,0,1 -544,180,0,1,0,1 -545,180,0,1,0,1 -546,180,0,1,0,1 -547,180,0,1,0,1 -548,180,0,1,0,1 -549,180,0,1,0,1 -550,180,0,1,0,1 -551,180,0,1,0,1 -552,180,0,1,0,1 -553,180,0,1,0,1 -554,180,0,1,0,1 -555,180,0,1,0,1 -556,180,0,1,0,1 -557,180,0,1,0,1 -558,180,0,1,0,1 -559,180,0,1,0,1 -560,180,0,1,0,1 -561,180,0,1,0,1 -562,180,0,1,0,1 -563,180,0,1,0,1 -564,180,0,1,0,1 -565,180,0,1,0,1 -566,180,0,1,0,1 -567,180,0,1,0,1 -568,180,0,1,0,1 -569,180,0,1,0,1 -570,180,0,1,0,1 -571,180,0,1,0,1 -572,180,0,1,0,1 -573,180,0,1,0,1 -574,180,0,1,0,1 -575,180,0,1,0,1 -576,180,0,1,0,1 -577,180,0,1,0,1 -578,180,0,1,0,1 -579,180,0,1,0,1 -580,180,0,1,0,1 -581,180,0,1,0,1 -582,180,0,1,0,1 -583,180,0,1,0,1 -584,180,0,1,0,1 -585,180,0,1,0,1 -586,180,0,1,0,1 -587,180,0,1,0,1 -588,180,0,1,0,1 -589,180,0,1,0,1 -590,180,0,1,0,1 -591,180,0,1,0,1 -592,180,0,1,0,1 -593,180,0,1,0,1 -594,180,0,1,0,1 -595,180,0,1,0,1 -596,180,0,1,0,1 -597,180,0,1,0,1 -598,180,0,1,0,1 -599,180,0,1,0,1 -600,180,0,1,0,1 -601,180,0,1,0,1 -602,180,0,1,0,1 -603,180,0,1,0,1 -604,180,0,1,0,1 -605,180,0,1,0,1 -606,180,0,1,0,1 -607,180,0,1,0,1 -608,180,0,1,0,1 -609,180,0,1,0,1 -610,180,0,1,0,1 -611,180,0,1,0,1 -612,180,0,1,0,1 -613,180,0,1,0,1 -614,180,0,1,0,1 -615,180,0,1,0,1 -616,180,0,1,0,1 -617,180,0,1,0,1 -618,180,0,1,0,1 -619,180,0,1,0,1 -620,180,0,1,0,1 -621,180,0,1,0,1 -622,180,0,1,0,1 -623,180,0,1,0,1 -624,180,0,1,0,1 -625,180,0,1,0,1 -626,180,0,1,0,1 -627,180,0,1,0,1 -628,180,0,1,0,1 -629,180,0,1,0,1 -630,180,0,1,0,1 -631,180,0,1,0,1 -632,180,0,1,0,1 -633,180,0,1,0,1 -634,180,0,1,0,1 -635,180,0,1,0,1 -636,180,0,1,0,1 -637,180,0,1,0,1 -638,180,0,1,0,1 -639,180,0,1,0,1 -640,180,0,1,0,1 -641,180,0,1,0,1 -642,180,0,1,0,1 -643,180,0,1,0,1 -644,180,0,1,0,1 -645,180,0,1,0,1 -646,180,0,1,0,1 -647,180,0,1,0,1 -648,180,0,1,0,1 -649,180,0,1,0,1 -650,180,0,1,0,1 -651,180,0,1,0,1 -652,180,0,1,0,1 -653,180,0,1,0,1 -654,180,0,1,0,1 -655,180,0,1,0,1 -656,180,0,1,0,1 -657,180,0,1,0,1 -658,180,0,1,0,1 -659,180,0,1,0,1 -660,180,0,1,0,1 -661,180,0,1,0,1 -662,180,0,1,0,1 -663,180,0,1,0,1 -664,180,0,1,0,1 -665,180,0,1,0,1 -666,180,0,1,0,1 -667,180,0,1,0,1 -668,180,0,1,0,1 -669,180,0,1,0,1 -670,180,0,1,0,1 -671,180,0,1,0,1 -672,180,0,1,0,1 -673,180,0,1,0,1 -674,180,0,1,0,1 -675,180,0,1,0,1 -676,180,0,1,0,1 -677,180,0,1,0,1 -678,180,0,1,0,1 -679,180,0,1,0,1 -680,180,0,1,0,1 -681,180,0,1,0,1 -682,180,0,1,0,1 -683,180,0,1,0,1 -684,180,0,1,0,1 -685,180,0,1,0,1 -686,180,0,1,0,1 -687,180,0,1,0,1 -688,180,0,1,0,1 -689,180,0,1,0,1 -690,180,0,1,0,1 -691,180,0,1,0,1 -692,180,0,1,0,1 -693,180,0,1,0,1 -694,180,0,1,0,1 -695,180,0,1,0,1 -696,180,0,1,0,1 -697,180,0,1,0,1 -698,180,0,1,0,1 -699,180,0,1,0,1 -700,180,0,1,0,1 -701,180,0,1,0,1 -702,180,0,1,0,1 -703,180,0,1,0,1 -704,180,0,1,0,1 -705,180,0,1,0,1 -706,180,0,1,0,1 -707,180,0,1,0,1 -708,180,0,1,0,1 -709,180,0,1,0,1 -710,180,0,1,0,1 -711,180,0,1,0,1 -712,180,0,1,0,1 -713,180,0,1,0,1 -714,180,0,1,0,1 -715,180,0,1,0,1 -716,180,0,1,0,1 -717,180,0,1,0,1 -718,180,0,1,0,1 -719,180,0,1,0,1 -720,180,0,1,0,1 -721,180,0,1,0,1 -722,180,0,1,0,1 -723,180,0,1,0,1 -724,180,0,1,0,1 -725,180,0,1,0,1 -726,180,0,1,0,1 -727,180,0,1,0,1 -728,180,0,1,0,1 -729,180,0,1,0,1 -730,180,0,1,0,1 -731,180,0,1,0,1 -732,180,0,1,0,1 -733,180,0,1,0,1 -734,180,0,1,0,1 -735,180,0,1,0,1 -736,180,0,1,0,1 -737,180,0,1,0,1 -738,180,0,1,0,1 -739,180,0,1,0,1 -740,180,0,1,0,1 -741,180,0,1,0,1 -742,180,0,1,0,1 -743,180,0,1,0,1 -744,180,0,1,0,1 -745,180,0,1,0,1 -746,180,0,1,0,1 -747,180,0,1,0,1 -748,180,0,1,0,1 -749,180,0,1,0,1 diff --git a/tests/renderer/data/ism_90a_0e.csv b/tests/renderer/data/ism_90a_0e.csv deleted file mode 100644 index bcd91364fe..0000000000 --- a/tests/renderer/data/ism_90a_0e.csv +++ /dev/null @@ -1,750 +0,0 @@ -0,90,0,1,0,1 -1,90,0,1,0,1 -2,90,0,1,0,1 -3,90,0,1,0,1 -4,90,0,1,0,1 -5,90,0,1,0,1 -6,90,0,1,0,1 -7,90,0,1,0,1 -8,90,0,1,0,1 -9,90,0,1,0,1 -10,90,0,1,0,1 -11,90,0,1,0,1 -12,90,0,1,0,1 -13,90,0,1,0,1 -14,90,0,1,0,1 -15,90,0,1,0,1 -16,90,0,1,0,1 -17,90,0,1,0,1 -18,90,0,1,0,1 -19,90,0,1,0,1 -20,90,0,1,0,1 -21,90,0,1,0,1 -22,90,0,1,0,1 -23,90,0,1,0,1 -24,90,0,1,0,1 -25,90,0,1,0,1 -26,90,0,1,0,1 -27,90,0,1,0,1 -28,90,0,1,0,1 -29,90,0,1,0,1 -30,90,0,1,0,1 -31,90,0,1,0,1 -32,90,0,1,0,1 -33,90,0,1,0,1 -34,90,0,1,0,1 -35,90,0,1,0,1 -36,90,0,1,0,1 -37,90,0,1,0,1 -38,90,0,1,0,1 -39,90,0,1,0,1 -40,90,0,1,0,1 -41,90,0,1,0,1 -42,90,0,1,0,1 -43,90,0,1,0,1 -44,90,0,1,0,1 -45,90,0,1,0,1 -46,90,0,1,0,1 -47,90,0,1,0,1 -48,90,0,1,0,1 -49,90,0,1,0,1 -50,90,0,1,0,1 -51,90,0,1,0,1 -52,90,0,1,0,1 -53,90,0,1,0,1 -54,90,0,1,0,1 -55,90,0,1,0,1 -56,90,0,1,0,1 -57,90,0,1,0,1 -58,90,0,1,0,1 -59,90,0,1,0,1 -60,90,0,1,0,1 -61,90,0,1,0,1 -62,90,0,1,0,1 -63,90,0,1,0,1 -64,90,0,1,0,1 -65,90,0,1,0,1 -66,90,0,1,0,1 -67,90,0,1,0,1 -68,90,0,1,0,1 -69,90,0,1,0,1 -70,90,0,1,0,1 -71,90,0,1,0,1 -72,90,0,1,0,1 -73,90,0,1,0,1 -74,90,0,1,0,1 -75,90,0,1,0,1 -76,90,0,1,0,1 -77,90,0,1,0,1 -78,90,0,1,0,1 -79,90,0,1,0,1 -80,90,0,1,0,1 -81,90,0,1,0,1 -82,90,0,1,0,1 -83,90,0,1,0,1 -84,90,0,1,0,1 -85,90,0,1,0,1 -86,90,0,1,0,1 -87,90,0,1,0,1 -88,90,0,1,0,1 -89,90,0,1,0,1 -90,90,0,1,0,1 -91,90,0,1,0,1 -92,90,0,1,0,1 -93,90,0,1,0,1 -94,90,0,1,0,1 -95,90,0,1,0,1 -96,90,0,1,0,1 -97,90,0,1,0,1 -98,90,0,1,0,1 -99,90,0,1,0,1 -100,90,0,1,0,1 -101,90,0,1,0,1 -102,90,0,1,0,1 -103,90,0,1,0,1 -104,90,0,1,0,1 -105,90,0,1,0,1 -106,90,0,1,0,1 -107,90,0,1,0,1 -108,90,0,1,0,1 -109,90,0,1,0,1 -110,90,0,1,0,1 -111,90,0,1,0,1 -112,90,0,1,0,1 -113,90,0,1,0,1 -114,90,0,1,0,1 -115,90,0,1,0,1 -116,90,0,1,0,1 -117,90,0,1,0,1 -118,90,0,1,0,1 -119,90,0,1,0,1 -120,90,0,1,0,1 -121,90,0,1,0,1 -122,90,0,1,0,1 -123,90,0,1,0,1 -124,90,0,1,0,1 -125,90,0,1,0,1 -126,90,0,1,0,1 -127,90,0,1,0,1 -128,90,0,1,0,1 -129,90,0,1,0,1 -130,90,0,1,0,1 -131,90,0,1,0,1 -132,90,0,1,0,1 -133,90,0,1,0,1 -134,90,0,1,0,1 -135,90,0,1,0,1 -136,90,0,1,0,1 -137,90,0,1,0,1 -138,90,0,1,0,1 -139,90,0,1,0,1 -140,90,0,1,0,1 -141,90,0,1,0,1 -142,90,0,1,0,1 -143,90,0,1,0,1 -144,90,0,1,0,1 -145,90,0,1,0,1 -146,90,0,1,0,1 -147,90,0,1,0,1 -148,90,0,1,0,1 -149,90,0,1,0,1 -150,90,0,1,0,1 -151,90,0,1,0,1 -152,90,0,1,0,1 -153,90,0,1,0,1 -154,90,0,1,0,1 -155,90,0,1,0,1 -156,90,0,1,0,1 -157,90,0,1,0,1 -158,90,0,1,0,1 -159,90,0,1,0,1 -160,90,0,1,0,1 -161,90,0,1,0,1 -162,90,0,1,0,1 -163,90,0,1,0,1 -164,90,0,1,0,1 -165,90,0,1,0,1 -166,90,0,1,0,1 -167,90,0,1,0,1 -168,90,0,1,0,1 -169,90,0,1,0,1 -170,90,0,1,0,1 -171,90,0,1,0,1 -172,90,0,1,0,1 -173,90,0,1,0,1 -174,90,0,1,0,1 -175,90,0,1,0,1 -176,90,0,1,0,1 -177,90,0,1,0,1 -178,90,0,1,0,1 -179,90,0,1,0,1 -180,90,0,1,0,1 -181,90,0,1,0,1 -182,90,0,1,0,1 -183,90,0,1,0,1 -184,90,0,1,0,1 -185,90,0,1,0,1 -186,90,0,1,0,1 -187,90,0,1,0,1 -188,90,0,1,0,1 -189,90,0,1,0,1 -190,90,0,1,0,1 -191,90,0,1,0,1 -192,90,0,1,0,1 -193,90,0,1,0,1 -194,90,0,1,0,1 -195,90,0,1,0,1 -196,90,0,1,0,1 -197,90,0,1,0,1 -198,90,0,1,0,1 -199,90,0,1,0,1 -200,90,0,1,0,1 -201,90,0,1,0,1 -202,90,0,1,0,1 -203,90,0,1,0,1 -204,90,0,1,0,1 -205,90,0,1,0,1 -206,90,0,1,0,1 -207,90,0,1,0,1 -208,90,0,1,0,1 -209,90,0,1,0,1 -210,90,0,1,0,1 -211,90,0,1,0,1 -212,90,0,1,0,1 -213,90,0,1,0,1 -214,90,0,1,0,1 -215,90,0,1,0,1 -216,90,0,1,0,1 -217,90,0,1,0,1 -218,90,0,1,0,1 -219,90,0,1,0,1 -220,90,0,1,0,1 -221,90,0,1,0,1 -222,90,0,1,0,1 -223,90,0,1,0,1 -224,90,0,1,0,1 -225,90,0,1,0,1 -226,90,0,1,0,1 -227,90,0,1,0,1 -228,90,0,1,0,1 -229,90,0,1,0,1 -230,90,0,1,0,1 -231,90,0,1,0,1 -232,90,0,1,0,1 -233,90,0,1,0,1 -234,90,0,1,0,1 -235,90,0,1,0,1 -236,90,0,1,0,1 -237,90,0,1,0,1 -238,90,0,1,0,1 -239,90,0,1,0,1 -240,90,0,1,0,1 -241,90,0,1,0,1 -242,90,0,1,0,1 -243,90,0,1,0,1 -244,90,0,1,0,1 -245,90,0,1,0,1 -246,90,0,1,0,1 -247,90,0,1,0,1 -248,90,0,1,0,1 -249,90,0,1,0,1 -250,90,0,1,0,1 -251,90,0,1,0,1 -252,90,0,1,0,1 -253,90,0,1,0,1 -254,90,0,1,0,1 -255,90,0,1,0,1 -256,90,0,1,0,1 -257,90,0,1,0,1 -258,90,0,1,0,1 -259,90,0,1,0,1 -260,90,0,1,0,1 -261,90,0,1,0,1 -262,90,0,1,0,1 -263,90,0,1,0,1 -264,90,0,1,0,1 -265,90,0,1,0,1 -266,90,0,1,0,1 -267,90,0,1,0,1 -268,90,0,1,0,1 -269,90,0,1,0,1 -270,90,0,1,0,1 -271,90,0,1,0,1 -272,90,0,1,0,1 -273,90,0,1,0,1 -274,90,0,1,0,1 -275,90,0,1,0,1 -276,90,0,1,0,1 -277,90,0,1,0,1 -278,90,0,1,0,1 -279,90,0,1,0,1 -280,90,0,1,0,1 -281,90,0,1,0,1 -282,90,0,1,0,1 -283,90,0,1,0,1 -284,90,0,1,0,1 -285,90,0,1,0,1 -286,90,0,1,0,1 -287,90,0,1,0,1 -288,90,0,1,0,1 -289,90,0,1,0,1 -290,90,0,1,0,1 -291,90,0,1,0,1 -292,90,0,1,0,1 -293,90,0,1,0,1 -294,90,0,1,0,1 -295,90,0,1,0,1 -296,90,0,1,0,1 -297,90,0,1,0,1 -298,90,0,1,0,1 -299,90,0,1,0,1 -300,90,0,1,0,1 -301,90,0,1,0,1 -302,90,0,1,0,1 -303,90,0,1,0,1 -304,90,0,1,0,1 -305,90,0,1,0,1 -306,90,0,1,0,1 -307,90,0,1,0,1 -308,90,0,1,0,1 -309,90,0,1,0,1 -310,90,0,1,0,1 -311,90,0,1,0,1 -312,90,0,1,0,1 -313,90,0,1,0,1 -314,90,0,1,0,1 -315,90,0,1,0,1 -316,90,0,1,0,1 -317,90,0,1,0,1 -318,90,0,1,0,1 -319,90,0,1,0,1 -320,90,0,1,0,1 -321,90,0,1,0,1 -322,90,0,1,0,1 -323,90,0,1,0,1 -324,90,0,1,0,1 -325,90,0,1,0,1 -326,90,0,1,0,1 -327,90,0,1,0,1 -328,90,0,1,0,1 -329,90,0,1,0,1 -330,90,0,1,0,1 -331,90,0,1,0,1 -332,90,0,1,0,1 -333,90,0,1,0,1 -334,90,0,1,0,1 -335,90,0,1,0,1 -336,90,0,1,0,1 -337,90,0,1,0,1 -338,90,0,1,0,1 -339,90,0,1,0,1 -340,90,0,1,0,1 -341,90,0,1,0,1 -342,90,0,1,0,1 -343,90,0,1,0,1 -344,90,0,1,0,1 -345,90,0,1,0,1 -346,90,0,1,0,1 -347,90,0,1,0,1 -348,90,0,1,0,1 -349,90,0,1,0,1 -350,90,0,1,0,1 -351,90,0,1,0,1 -352,90,0,1,0,1 -353,90,0,1,0,1 -354,90,0,1,0,1 -355,90,0,1,0,1 -356,90,0,1,0,1 -357,90,0,1,0,1 -358,90,0,1,0,1 -359,90,0,1,0,1 -360,90,0,1,0,1 -361,90,0,1,0,1 -362,90,0,1,0,1 -363,90,0,1,0,1 -364,90,0,1,0,1 -365,90,0,1,0,1 -366,90,0,1,0,1 -367,90,0,1,0,1 -368,90,0,1,0,1 -369,90,0,1,0,1 -370,90,0,1,0,1 -371,90,0,1,0,1 -372,90,0,1,0,1 -373,90,0,1,0,1 -374,90,0,1,0,1 -375,90,0,1,0,1 -376,90,0,1,0,1 -377,90,0,1,0,1 -378,90,0,1,0,1 -379,90,0,1,0,1 -380,90,0,1,0,1 -381,90,0,1,0,1 -382,90,0,1,0,1 -383,90,0,1,0,1 -384,90,0,1,0,1 -385,90,0,1,0,1 -386,90,0,1,0,1 -387,90,0,1,0,1 -388,90,0,1,0,1 -389,90,0,1,0,1 -390,90,0,1,0,1 -391,90,0,1,0,1 -392,90,0,1,0,1 -393,90,0,1,0,1 -394,90,0,1,0,1 -395,90,0,1,0,1 -396,90,0,1,0,1 -397,90,0,1,0,1 -398,90,0,1,0,1 -399,90,0,1,0,1 -400,90,0,1,0,1 -401,90,0,1,0,1 -402,90,0,1,0,1 -403,90,0,1,0,1 -404,90,0,1,0,1 -405,90,0,1,0,1 -406,90,0,1,0,1 -407,90,0,1,0,1 -408,90,0,1,0,1 -409,90,0,1,0,1 -410,90,0,1,0,1 -411,90,0,1,0,1 -412,90,0,1,0,1 -413,90,0,1,0,1 -414,90,0,1,0,1 -415,90,0,1,0,1 -416,90,0,1,0,1 -417,90,0,1,0,1 -418,90,0,1,0,1 -419,90,0,1,0,1 -420,90,0,1,0,1 -421,90,0,1,0,1 -422,90,0,1,0,1 -423,90,0,1,0,1 -424,90,0,1,0,1 -425,90,0,1,0,1 -426,90,0,1,0,1 -427,90,0,1,0,1 -428,90,0,1,0,1 -429,90,0,1,0,1 -430,90,0,1,0,1 -431,90,0,1,0,1 -432,90,0,1,0,1 -433,90,0,1,0,1 -434,90,0,1,0,1 -435,90,0,1,0,1 -436,90,0,1,0,1 -437,90,0,1,0,1 -438,90,0,1,0,1 -439,90,0,1,0,1 -440,90,0,1,0,1 -441,90,0,1,0,1 -442,90,0,1,0,1 -443,90,0,1,0,1 -444,90,0,1,0,1 -445,90,0,1,0,1 -446,90,0,1,0,1 -447,90,0,1,0,1 -448,90,0,1,0,1 -449,90,0,1,0,1 -450,90,0,1,0,1 -451,90,0,1,0,1 -452,90,0,1,0,1 -453,90,0,1,0,1 -454,90,0,1,0,1 -455,90,0,1,0,1 -456,90,0,1,0,1 -457,90,0,1,0,1 -458,90,0,1,0,1 -459,90,0,1,0,1 -460,90,0,1,0,1 -461,90,0,1,0,1 -462,90,0,1,0,1 -463,90,0,1,0,1 -464,90,0,1,0,1 -465,90,0,1,0,1 -466,90,0,1,0,1 -467,90,0,1,0,1 -468,90,0,1,0,1 -469,90,0,1,0,1 -470,90,0,1,0,1 -471,90,0,1,0,1 -472,90,0,1,0,1 -473,90,0,1,0,1 -474,90,0,1,0,1 -475,90,0,1,0,1 -476,90,0,1,0,1 -477,90,0,1,0,1 -478,90,0,1,0,1 -479,90,0,1,0,1 -480,90,0,1,0,1 -481,90,0,1,0,1 -482,90,0,1,0,1 -483,90,0,1,0,1 -484,90,0,1,0,1 -485,90,0,1,0,1 -486,90,0,1,0,1 -487,90,0,1,0,1 -488,90,0,1,0,1 -489,90,0,1,0,1 -490,90,0,1,0,1 -491,90,0,1,0,1 -492,90,0,1,0,1 -493,90,0,1,0,1 -494,90,0,1,0,1 -495,90,0,1,0,1 -496,90,0,1,0,1 -497,90,0,1,0,1 -498,90,0,1,0,1 -499,90,0,1,0,1 -500,90,0,1,0,1 -501,90,0,1,0,1 -502,90,0,1,0,1 -503,90,0,1,0,1 -504,90,0,1,0,1 -505,90,0,1,0,1 -506,90,0,1,0,1 -507,90,0,1,0,1 -508,90,0,1,0,1 -509,90,0,1,0,1 -510,90,0,1,0,1 -511,90,0,1,0,1 -512,90,0,1,0,1 -513,90,0,1,0,1 -514,90,0,1,0,1 -515,90,0,1,0,1 -516,90,0,1,0,1 -517,90,0,1,0,1 -518,90,0,1,0,1 -519,90,0,1,0,1 -520,90,0,1,0,1 -521,90,0,1,0,1 -522,90,0,1,0,1 -523,90,0,1,0,1 -524,90,0,1,0,1 -525,90,0,1,0,1 -526,90,0,1,0,1 -527,90,0,1,0,1 -528,90,0,1,0,1 -529,90,0,1,0,1 -530,90,0,1,0,1 -531,90,0,1,0,1 -532,90,0,1,0,1 -533,90,0,1,0,1 -534,90,0,1,0,1 -535,90,0,1,0,1 -536,90,0,1,0,1 -537,90,0,1,0,1 -538,90,0,1,0,1 -539,90,0,1,0,1 -540,90,0,1,0,1 -541,90,0,1,0,1 -542,90,0,1,0,1 -543,90,0,1,0,1 -544,90,0,1,0,1 -545,90,0,1,0,1 -546,90,0,1,0,1 -547,90,0,1,0,1 -548,90,0,1,0,1 -549,90,0,1,0,1 -550,90,0,1,0,1 -551,90,0,1,0,1 -552,90,0,1,0,1 -553,90,0,1,0,1 -554,90,0,1,0,1 -555,90,0,1,0,1 -556,90,0,1,0,1 -557,90,0,1,0,1 -558,90,0,1,0,1 -559,90,0,1,0,1 -560,90,0,1,0,1 -561,90,0,1,0,1 -562,90,0,1,0,1 -563,90,0,1,0,1 -564,90,0,1,0,1 -565,90,0,1,0,1 -566,90,0,1,0,1 -567,90,0,1,0,1 -568,90,0,1,0,1 -569,90,0,1,0,1 -570,90,0,1,0,1 -571,90,0,1,0,1 -572,90,0,1,0,1 -573,90,0,1,0,1 -574,90,0,1,0,1 -575,90,0,1,0,1 -576,90,0,1,0,1 -577,90,0,1,0,1 -578,90,0,1,0,1 -579,90,0,1,0,1 -580,90,0,1,0,1 -581,90,0,1,0,1 -582,90,0,1,0,1 -583,90,0,1,0,1 -584,90,0,1,0,1 -585,90,0,1,0,1 -586,90,0,1,0,1 -587,90,0,1,0,1 -588,90,0,1,0,1 -589,90,0,1,0,1 -590,90,0,1,0,1 -591,90,0,1,0,1 -592,90,0,1,0,1 -593,90,0,1,0,1 -594,90,0,1,0,1 -595,90,0,1,0,1 -596,90,0,1,0,1 -597,90,0,1,0,1 -598,90,0,1,0,1 -599,90,0,1,0,1 -600,90,0,1,0,1 -601,90,0,1,0,1 -602,90,0,1,0,1 -603,90,0,1,0,1 -604,90,0,1,0,1 -605,90,0,1,0,1 -606,90,0,1,0,1 -607,90,0,1,0,1 -608,90,0,1,0,1 -609,90,0,1,0,1 -610,90,0,1,0,1 -611,90,0,1,0,1 -612,90,0,1,0,1 -613,90,0,1,0,1 -614,90,0,1,0,1 -615,90,0,1,0,1 -616,90,0,1,0,1 -617,90,0,1,0,1 -618,90,0,1,0,1 -619,90,0,1,0,1 -620,90,0,1,0,1 -621,90,0,1,0,1 -622,90,0,1,0,1 -623,90,0,1,0,1 -624,90,0,1,0,1 -625,90,0,1,0,1 -626,90,0,1,0,1 -627,90,0,1,0,1 -628,90,0,1,0,1 -629,90,0,1,0,1 -630,90,0,1,0,1 -631,90,0,1,0,1 -632,90,0,1,0,1 -633,90,0,1,0,1 -634,90,0,1,0,1 -635,90,0,1,0,1 -636,90,0,1,0,1 -637,90,0,1,0,1 -638,90,0,1,0,1 -639,90,0,1,0,1 -640,90,0,1,0,1 -641,90,0,1,0,1 -642,90,0,1,0,1 -643,90,0,1,0,1 -644,90,0,1,0,1 -645,90,0,1,0,1 -646,90,0,1,0,1 -647,90,0,1,0,1 -648,90,0,1,0,1 -649,90,0,1,0,1 -650,90,0,1,0,1 -651,90,0,1,0,1 -652,90,0,1,0,1 -653,90,0,1,0,1 -654,90,0,1,0,1 -655,90,0,1,0,1 -656,90,0,1,0,1 -657,90,0,1,0,1 -658,90,0,1,0,1 -659,90,0,1,0,1 -660,90,0,1,0,1 -661,90,0,1,0,1 -662,90,0,1,0,1 -663,90,0,1,0,1 -664,90,0,1,0,1 -665,90,0,1,0,1 -666,90,0,1,0,1 -667,90,0,1,0,1 -668,90,0,1,0,1 -669,90,0,1,0,1 -670,90,0,1,0,1 -671,90,0,1,0,1 -672,90,0,1,0,1 -673,90,0,1,0,1 -674,90,0,1,0,1 -675,90,0,1,0,1 -676,90,0,1,0,1 -677,90,0,1,0,1 -678,90,0,1,0,1 -679,90,0,1,0,1 -680,90,0,1,0,1 -681,90,0,1,0,1 -682,90,0,1,0,1 -683,90,0,1,0,1 -684,90,0,1,0,1 -685,90,0,1,0,1 -686,90,0,1,0,1 -687,90,0,1,0,1 -688,90,0,1,0,1 -689,90,0,1,0,1 -690,90,0,1,0,1 -691,90,0,1,0,1 -692,90,0,1,0,1 -693,90,0,1,0,1 -694,90,0,1,0,1 -695,90,0,1,0,1 -696,90,0,1,0,1 -697,90,0,1,0,1 -698,90,0,1,0,1 -699,90,0,1,0,1 -700,90,0,1,0,1 -701,90,0,1,0,1 -702,90,0,1,0,1 -703,90,0,1,0,1 -704,90,0,1,0,1 -705,90,0,1,0,1 -706,90,0,1,0,1 -707,90,0,1,0,1 -708,90,0,1,0,1 -709,90,0,1,0,1 -710,90,0,1,0,1 -711,90,0,1,0,1 -712,90,0,1,0,1 -713,90,0,1,0,1 -714,90,0,1,0,1 -715,90,0,1,0,1 -716,90,0,1,0,1 -717,90,0,1,0,1 -718,90,0,1,0,1 -719,90,0,1,0,1 -720,90,0,1,0,1 -721,90,0,1,0,1 -722,90,0,1,0,1 -723,90,0,1,0,1 -724,90,0,1,0,1 -725,90,0,1,0,1 -726,90,0,1,0,1 -727,90,0,1,0,1 -728,90,0,1,0,1 -729,90,0,1,0,1 -730,90,0,1,0,1 -731,90,0,1,0,1 -732,90,0,1,0,1 -733,90,0,1,0,1 -734,90,0,1,0,1 -735,90,0,1,0,1 -736,90,0,1,0,1 -737,90,0,1,0,1 -738,90,0,1,0,1 -739,90,0,1,0,1 -740,90,0,1,0,1 -741,90,0,1,0,1 -742,90,0,1,0,1 -743,90,0,1,0,1 -744,90,0,1,0,1 -745,90,0,1,0,1 -746,90,0,1,0,1 -747,90,0,1,0,1 -748,90,0,1,0,1 -749,90,0,1,0,1 diff --git a/tests/renderer/data/pink_noise_10ch_48kHz.wav b/tests/renderer/data/pink_noise_10ch_48kHz.wav deleted file mode 100644 index d62a4a2e45..0000000000 --- a/tests/renderer/data/pink_noise_10ch_48kHz.wav +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d91e0bde3e5efd507b50ab9635504918936f406be5655a33859ecc7cce8e6578 -size 960044 diff --git a/tests/renderer/data/pink_noise_11ch_48kHz.wav b/tests/renderer/data/pink_noise_11ch_48kHz.wav deleted file mode 100644 index 1d6de74f3c..0000000000 --- a/tests/renderer/data/pink_noise_11ch_48kHz.wav +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:91c84157cb13d5c61493f907e4b38302d1e838a04610e708186e67a066ebb0c2 -size 1056044 diff --git a/tests/renderer/data/pink_noise_12ch_48kHz.wav b/tests/renderer/data/pink_noise_12ch_48kHz.wav deleted file mode 100644 index a6ec8c67ae..0000000000 --- a/tests/renderer/data/pink_noise_12ch_48kHz.wav +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:90ea167b7228a7ec54658bf4d0d61814fbe288bf4e7bd5a72a6ab3ef691f2008 -size 1152044 diff --git a/tests/renderer/data/pink_noise_13ch_48kHz.wav b/tests/renderer/data/pink_noise_13ch_48kHz.wav deleted file mode 100644 index 222397e8e1..0000000000 --- a/tests/renderer/data/pink_noise_13ch_48kHz.wav +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:6b3afeddf57940780add178ff098515940556752758f87ac160386ff7125071e -size 1248044 diff --git a/tests/renderer/data/pink_noise_14ch_48kHz.wav b/tests/renderer/data/pink_noise_14ch_48kHz.wav deleted file mode 100644 index 098b57d3dd..0000000000 --- a/tests/renderer/data/pink_noise_14ch_48kHz.wav +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c542f1421067546614e47b17715c89d5e705f904faf41bdbd1d439e0abd9e1e0 -size 1344044 diff --git a/tests/renderer/data/pink_noise_15ch_48kHz.wav b/tests/renderer/data/pink_noise_15ch_48kHz.wav deleted file mode 100644 index f059f92c69..0000000000 --- a/tests/renderer/data/pink_noise_15ch_48kHz.wav +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:9becb4e4c271590ead4c898992e593baaf4678887f67153e91a8de87c7b5c3ca -size 1440044 diff --git a/tests/renderer/data/pink_noise_16ch_48kHz.wav b/tests/renderer/data/pink_noise_16ch_48kHz.wav deleted file mode 100644 index 3ee7f71d89..0000000000 --- a/tests/renderer/data/pink_noise_16ch_48kHz.wav +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:90027b3f8b8514bafb2e1dee80a77fc200bafcf45219852b3b7bd97ca60369c2 -size 1536044 diff --git a/tests/renderer/data/pink_noise_1ch_48kHz.wav b/tests/renderer/data/pink_noise_1ch_48kHz.wav deleted file mode 100644 index 5ed1fe6292..0000000000 --- a/tests/renderer/data/pink_noise_1ch_48kHz.wav +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:54ee3a0aa4cbb5295a33fe0637a1854900d2b14813911c7316193cab53b609dc -size 96044 diff --git a/tests/renderer/data/pink_noise_2ch_48kHz.wav b/tests/renderer/data/pink_noise_2ch_48kHz.wav deleted file mode 100644 index 0e0e43f682..0000000000 --- a/tests/renderer/data/pink_noise_2ch_48kHz.wav +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ce34623cf87d56cf5d695e79388d1229f74ba266e0977c18cdf03df174675e3d -size 192044 diff --git a/tests/renderer/data/pink_noise_3ch_48kHz.wav b/tests/renderer/data/pink_noise_3ch_48kHz.wav deleted file mode 100644 index a9ae37feb4..0000000000 --- a/tests/renderer/data/pink_noise_3ch_48kHz.wav +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:de99e669d4300cd94d3f4966f96ba0f2ca85c40c7cc6cfeb8d09058050ab0909 -size 288044 diff --git a/tests/renderer/data/pink_noise_4ch_48kHz.wav b/tests/renderer/data/pink_noise_4ch_48kHz.wav deleted file mode 100644 index 7881c149f0..0000000000 --- a/tests/renderer/data/pink_noise_4ch_48kHz.wav +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a9310f2e04af7f544f70dfd7360b93c9bafff7e35d9c919e003b27ed549974d8 -size 384044 diff --git a/tests/renderer/data/pink_noise_5ch_48kHz.wav b/tests/renderer/data/pink_noise_5ch_48kHz.wav deleted file mode 100644 index f99dc847d9..0000000000 --- a/tests/renderer/data/pink_noise_5ch_48kHz.wav +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:be89b959d794e780a04956637d3a6f0128452e54153ad7f54e516b2596b52589 -size 480044 diff --git a/tests/renderer/data/pink_noise_6ch_48kHz.wav b/tests/renderer/data/pink_noise_6ch_48kHz.wav deleted file mode 100644 index deaea297fe..0000000000 --- a/tests/renderer/data/pink_noise_6ch_48kHz.wav +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c6bfe70996dee2eb3bad563eed9bfaf6824449cbec165d666670de2641660b6d -size 576044 diff --git a/tests/renderer/data/pink_noise_7ch_48kHz.wav b/tests/renderer/data/pink_noise_7ch_48kHz.wav deleted file mode 100644 index 70a4cf75da..0000000000 --- a/tests/renderer/data/pink_noise_7ch_48kHz.wav +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:9e582f2584abdce32381f1f1366c73171f71a08334751c3c6114ec2f49945b2c -size 672044 diff --git a/tests/renderer/data/pink_noise_8ch_48kHz.wav b/tests/renderer/data/pink_noise_8ch_48kHz.wav deleted file mode 100644 index 3b42c83e48..0000000000 --- a/tests/renderer/data/pink_noise_8ch_48kHz.wav +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:418a1cc37dec9dc9a51efd208afe7b6843787e3ed64c86fa69c5780cfb5d3c18 -size 768044 diff --git a/tests/renderer/data/pink_noise_9ch_48kHz.wav b/tests/renderer/data/pink_noise_9ch_48kHz.wav deleted file mode 100644 index 6c5859184d..0000000000 --- a/tests/renderer/data/pink_noise_9ch_48kHz.wav +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d1ef5804949cabfb17ce103010ff33c6229e5c6e28d2cd93c7c8c6060a894023 -size 864044 diff --git a/tests/renderer/data/spectral_test_ism1.txt b/tests/renderer/data/spectral_test_ism1.txt deleted file mode 100644 index 84b3b25268..0000000000 --- a/tests/renderer/data/spectral_test_ism1.txt +++ /dev/null @@ -1,5 +0,0 @@ -spectral_test_1ch_48kHz.wav -1 -ISM -1 -stvISM1.csv diff --git a/tests/renderer/data/spectral_test_ism2.txt b/tests/renderer/data/spectral_test_ism2.txt deleted file mode 100644 index 18f3e7a24c..0000000000 --- a/tests/renderer/data/spectral_test_ism2.txt +++ /dev/null @@ -1,8 +0,0 @@ -spectral_test_2ch_48kHz.wav -2 -ISM -1 -stvISM1.csv -ISM -2 -stvISM2.csv diff --git a/tests/renderer/data/spectral_test_ism3.txt b/tests/renderer/data/spectral_test_ism3.txt deleted file mode 100644 index c25d0d0dff..0000000000 --- a/tests/renderer/data/spectral_test_ism3.txt +++ /dev/null @@ -1,11 +0,0 @@ -spectral_test_3ch_48kHz.wav -3 -ISM -1 -stvISM1.csv -ISM -2 -stvISM2.csv -ISM -3 -stvISM3.csv diff --git a/tests/renderer/data/spectral_test_ism4.txt b/tests/renderer/data/spectral_test_ism4.txt deleted file mode 100644 index f4a95d1e09..0000000000 --- a/tests/renderer/data/spectral_test_ism4.txt +++ /dev/null @@ -1,14 +0,0 @@ -spectral_test_4ch_48kHz.wav -4 -ISM -1 -stvISM1.csv -ISM -2 -stvISM2.csv -ISM -3 -stvISM3.csv -ISM -4 -stvISM4.csv diff --git a/tests/renderer/data/stvISM1.csv b/tests/renderer/data/stvISM1.csv deleted file mode 100644 index 574c537028..0000000000 --- a/tests/renderer/data/stvISM1.csv +++ /dev/null @@ -1,1500 +0,0 @@ -0,0.00,0.00,1.00,0.00,1.00 -1,4.80,0.00,1.00,0.00,1.00 -2,9.60,0.00,1.00,0.00,1.00 -3,14.40,0.00,1.00,0.00,1.00 -4,19.20,0.00,1.00,0.00,1.00 -5,24.00,0.00,1.00,0.00,1.00 -6,28.80,0.00,1.00,0.00,1.00 -7,33.60,0.00,1.00,0.00,1.00 -8,38.40,0.00,1.00,0.00,1.00 -9,43.20,0.00,1.00,0.00,1.00 -10,48.00,0.00,1.00,0.00,1.00 -11,52.80,0.00,1.00,0.00,1.00 -12,57.60,0.00,1.00,0.00,1.00 -13,62.40,0.00,1.00,0.00,1.00 -14,67.20,0.00,1.00,0.00,1.00 -15,72.00,0.00,1.00,0.00,1.00 -16,76.80,0.00,1.00,0.00,1.00 -17,81.60,0.00,1.00,0.00,1.00 -18,86.40,0.00,1.00,0.00,1.00 -19,91.20,0.00,1.00,0.00,1.00 -20,96.00,0.00,1.00,0.00,1.00 -21,100.80,0.00,1.00,0.00,1.00 -22,105.60,0.00,1.00,0.00,1.00 -23,110.40,0.00,1.00,0.00,1.00 -24,115.20,0.00,1.00,0.00,1.00 -25,120.00,0.00,1.00,0.00,1.00 -26,124.80,0.00,1.00,0.00,1.00 -27,129.60,0.00,1.00,0.00,1.00 -28,134.40,0.00,1.00,0.00,1.00 -29,139.20,0.00,1.00,0.00,1.00 -30,144.00,0.00,1.00,0.00,1.00 -31,148.80,0.00,1.00,0.00,1.00 -32,153.60,0.00,1.00,0.00,1.00 -33,158.40,0.00,1.00,0.00,1.00 -34,163.20,0.00,1.00,0.00,1.00 -35,168.00,0.00,1.00,0.00,1.00 -36,172.80,0.00,1.00,0.00,1.00 -37,177.60,0.00,1.00,0.00,1.00 -38,-177.60,0.00,1.00,0.00,1.00 -39,-172.80,0.00,1.00,0.00,1.00 -40,-168.00,0.00,1.00,0.00,1.00 -41,-163.20,0.00,1.00,0.00,1.00 -42,-158.40,0.00,1.00,0.00,1.00 -43,-153.60,0.00,1.00,0.00,1.00 -44,-148.80,0.00,1.00,0.00,1.00 -45,-144.00,0.00,1.00,0.00,1.00 -46,-139.20,0.00,1.00,0.00,1.00 -47,-134.40,0.00,1.00,0.00,1.00 -48,-129.60,0.00,1.00,0.00,1.00 -49,-124.80,0.00,1.00,0.00,1.00 -50,-120.00,0.00,1.00,0.00,1.00 -51,-115.20,0.00,1.00,0.00,1.00 -52,-110.40,0.00,1.00,0.00,1.00 -53,-105.60,0.00,1.00,0.00,1.00 -54,-100.80,0.00,1.00,0.00,1.00 -55,-96.00,0.00,1.00,0.00,1.00 -56,-91.20,0.00,1.00,0.00,1.00 -57,-86.40,0.00,1.00,0.00,1.00 -58,-81.60,0.00,1.00,0.00,1.00 -59,-76.80,0.00,1.00,0.00,1.00 -60,-72.00,0.00,1.00,0.00,1.00 -61,-67.20,0.00,1.00,0.00,1.00 -62,-62.40,0.00,1.00,0.00,1.00 -63,-57.60,0.00,1.00,0.00,1.00 -64,-52.80,0.00,1.00,0.00,1.00 -65,-48.00,0.00,1.00,0.00,1.00 -66,-43.20,0.00,1.00,0.00,1.00 -67,-38.40,0.00,1.00,0.00,1.00 -68,-33.60,0.00,1.00,0.00,1.00 -69,-28.80,0.00,1.00,0.00,1.00 -70,-24.00,0.00,1.00,0.00,1.00 -71,-19.20,0.00,1.00,0.00,1.00 -72,-14.40,0.00,1.00,0.00,1.00 -73,-9.60,0.00,1.00,0.00,1.00 -74,-4.80,0.00,1.00,0.00,1.00 -75,0.00,0.00,1.00,0.00,1.00 -76,4.80,-0.00,1.00,0.00,1.00 -77,9.60,-0.00,1.00,0.00,1.00 -78,14.40,-0.00,1.00,0.00,1.00 -79,19.20,-0.00,1.00,0.00,1.00 -80,24.00,-0.00,1.00,0.00,1.00 -81,28.80,-0.00,1.00,0.00,1.00 -82,33.60,-4.80,1.00,0.00,1.00 -83,38.40,-4.80,1.00,0.00,1.00 -84,43.20,-4.80,1.00,0.00,1.00 -85,48.00,-4.80,1.00,0.00,1.00 -86,52.80,-4.80,1.00,0.00,1.00 -87,57.60,-4.80,1.00,0.00,1.00 -88,62.40,-4.80,1.00,0.00,1.00 -89,67.20,-4.80,1.00,0.00,1.00 -90,72.00,-4.80,1.00,0.00,1.00 -91,76.80,-4.80,1.00,0.00,1.00 -92,81.60,-4.80,1.00,0.00,1.00 -93,86.40,-4.80,1.00,0.00,1.00 -94,91.20,-4.80,1.00,0.00,1.00 -95,96.00,-4.80,1.00,0.00,1.00 -96,100.80,-4.80,1.00,0.00,1.00 -97,105.60,-4.80,1.00,0.00,1.00 -98,110.40,-4.80,1.00,0.00,1.00 -99,115.20,-4.80,1.00,0.00,1.00 -100,120.00,-4.80,1.00,0.00,1.00 -101,124.80,-4.80,1.00,0.00,1.00 -102,129.60,-4.80,1.00,0.00,1.00 -103,134.40,-4.80,1.00,0.00,1.00 -104,139.20,-4.80,1.00,0.00,1.00 -105,144.00,-4.80,1.00,0.00,1.00 -106,148.80,-4.80,1.00,0.00,1.00 -107,153.60,-0.00,1.00,0.00,1.00 -108,158.40,-0.00,1.00,0.00,1.00 -109,163.20,-0.00,1.00,0.00,1.00 -110,168.00,-0.00,1.00,0.00,1.00 -111,172.80,-0.00,1.00,0.00,1.00 -112,177.60,-0.00,1.00,0.00,1.00 -113,-177.60,0.00,1.00,0.00,1.00 -114,-172.80,0.00,1.00,0.00,1.00 -115,-168.00,0.00,1.00,0.00,1.00 -116,-163.20,0.00,1.00,0.00,1.00 -117,-158.40,0.00,1.00,0.00,1.00 -118,-153.60,0.00,1.00,0.00,1.00 -119,-148.80,4.80,1.00,0.00,1.00 -120,-144.00,4.80,1.00,0.00,1.00 -121,-139.20,4.80,1.00,0.00,1.00 -122,-134.40,4.80,1.00,0.00,1.00 -123,-129.60,4.80,1.00,0.00,1.00 -124,-124.80,4.80,1.00,0.00,1.00 -125,-120.00,4.80,1.00,0.00,1.00 -126,-115.20,4.80,1.00,0.00,1.00 -127,-110.40,4.80,1.00,0.00,1.00 -128,-105.60,4.80,1.00,0.00,1.00 -129,-100.80,4.80,1.00,0.00,1.00 -130,-96.00,4.80,1.00,0.00,1.00 -131,-91.20,4.80,1.00,0.00,1.00 -132,-86.40,4.80,1.00,0.00,1.00 -133,-81.60,4.80,1.00,0.00,1.00 -134,-76.80,4.80,1.00,0.00,1.00 -135,-72.00,4.80,1.00,0.00,1.00 -136,-67.20,4.80,1.00,0.00,1.00 -137,-62.40,4.80,1.00,0.00,1.00 -138,-57.60,4.80,1.00,0.00,1.00 -139,-52.80,4.80,1.00,0.00,1.00 -140,-48.00,4.80,1.00,0.00,1.00 -141,-43.20,4.80,1.00,0.00,1.00 -142,-38.40,4.80,1.00,0.00,1.00 -143,-33.60,4.80,1.00,0.00,1.00 -144,-28.80,0.00,1.00,0.00,1.00 -145,-24.00,0.00,1.00,0.00,1.00 -146,-19.20,0.00,1.00,0.00,1.00 -147,-14.40,0.00,1.00,0.00,1.00 -148,-9.60,0.00,1.00,0.00,1.00 -149,-4.80,0.00,1.00,0.00,1.00 -150,0.00,0.00,1.00,0.00,1.00 -151,4.80,-0.00,1.00,0.00,1.00 -152,9.60,-0.00,1.00,0.00,1.00 -153,14.40,-0.00,1.00,0.00,1.00 -154,19.20,-4.80,1.00,0.00,1.00 -155,24.00,-4.80,1.00,0.00,1.00 -156,28.80,-4.80,1.00,0.00,1.00 -157,33.60,-4.80,1.00,0.00,1.00 -158,38.40,-4.80,1.00,0.00,1.00 -159,43.20,-4.80,1.00,0.00,1.00 -160,48.00,-4.80,1.00,0.00,1.00 -161,52.80,-9.60,1.00,0.00,1.00 -162,57.60,-9.60,1.00,0.00,1.00 -163,62.40,-9.60,1.00,0.00,1.00 -164,67.20,-9.60,1.00,0.00,1.00 -165,72.00,-9.60,1.00,0.00,1.00 -166,76.80,-9.60,1.00,0.00,1.00 -167,81.60,-9.60,1.00,0.00,1.00 -168,86.40,-9.60,1.00,0.00,1.00 -169,91.20,-9.60,1.00,0.00,1.00 -170,96.00,-9.60,1.00,0.00,1.00 -171,100.80,-9.60,1.00,0.00,1.00 -172,105.60,-9.60,1.00,0.00,1.00 -173,110.40,-9.60,1.00,0.00,1.00 -174,115.20,-9.60,1.00,0.00,1.00 -175,120.00,-9.60,1.00,0.00,1.00 -176,124.80,-9.60,1.00,0.00,1.00 -177,129.60,-9.60,1.00,0.00,1.00 -178,134.40,-4.80,1.00,0.00,1.00 -179,139.20,-4.80,1.00,0.00,1.00 -180,144.00,-4.80,1.00,0.00,1.00 -181,148.80,-4.80,1.00,0.00,1.00 -182,153.60,-4.80,1.00,0.00,1.00 -183,158.40,-4.80,1.00,0.00,1.00 -184,163.20,-4.80,1.00,0.00,1.00 -185,168.00,-0.00,1.00,0.00,1.00 -186,172.80,-0.00,1.00,0.00,1.00 -187,177.60,-0.00,1.00,0.00,1.00 -188,-177.60,0.00,1.00,0.00,1.00 -189,-172.80,0.00,1.00,0.00,1.00 -190,-168.00,0.00,1.00,0.00,1.00 -191,-163.20,4.80,1.00,0.00,1.00 -192,-158.40,4.80,1.00,0.00,1.00 -193,-153.60,4.80,1.00,0.00,1.00 -194,-148.80,4.80,1.00,0.00,1.00 -195,-144.00,4.80,1.00,0.00,1.00 -196,-139.20,4.80,1.00,0.00,1.00 -197,-134.40,4.80,1.00,0.00,1.00 -198,-129.60,9.60,1.00,0.00,1.00 -199,-124.80,9.60,1.00,0.00,1.00 -200,-120.00,9.60,1.00,0.00,1.00 -201,-115.20,9.60,1.00,0.00,1.00 -202,-110.40,9.60,1.00,0.00,1.00 -203,-105.60,9.60,1.00,0.00,1.00 -204,-100.80,9.60,1.00,0.00,1.00 -205,-96.00,9.60,1.00,0.00,1.00 -206,-91.20,9.60,1.00,0.00,1.00 -207,-86.40,9.60,1.00,0.00,1.00 -208,-81.60,9.60,1.00,0.00,1.00 -209,-76.80,9.60,1.00,0.00,1.00 -210,-72.00,9.60,1.00,0.00,1.00 -211,-67.20,9.60,1.00,0.00,1.00 -212,-62.40,9.60,1.00,0.00,1.00 -213,-57.60,9.60,1.00,0.00,1.00 -214,-52.80,9.60,1.00,0.00,1.00 -215,-48.00,4.80,1.00,0.00,1.00 -216,-43.20,4.80,1.00,0.00,1.00 -217,-38.40,4.80,1.00,0.00,1.00 -218,-33.60,4.80,1.00,0.00,1.00 -219,-28.80,4.80,1.00,0.00,1.00 -220,-24.00,4.80,1.00,0.00,1.00 -221,-19.20,4.80,1.00,0.00,1.00 -222,-14.40,0.00,1.00,0.00,1.00 -223,-9.60,0.00,1.00,0.00,1.00 -224,-4.80,0.00,1.00,0.00,1.00 -225,0.00,0.00,1.00,0.00,1.00 -226,4.80,-0.00,1.00,0.00,1.00 -227,9.60,-0.00,1.00,0.00,1.00 -228,14.40,-4.80,1.00,0.00,1.00 -229,19.20,-4.80,1.00,0.00,1.00 -230,24.00,-4.80,1.00,0.00,1.00 -231,28.80,-4.80,1.00,0.00,1.00 -232,33.60,-9.60,1.00,0.00,1.00 -233,38.40,-9.60,1.00,0.00,1.00 -234,43.20,-9.60,1.00,0.00,1.00 -235,48.00,-9.60,1.00,0.00,1.00 -236,52.80,-9.60,1.00,0.00,1.00 -237,57.60,-14.40,1.00,0.00,1.00 -238,62.40,-14.40,1.00,0.00,1.00 -239,67.20,-14.40,1.00,0.00,1.00 -240,72.00,-14.40,1.00,0.00,1.00 -241,76.80,-14.40,1.00,0.00,1.00 -242,81.60,-14.40,1.00,0.00,1.00 -243,86.40,-14.40,1.00,0.00,1.00 -244,91.20,-14.40,1.00,0.00,1.00 -245,96.00,-14.40,1.00,0.00,1.00 -246,100.80,-14.40,1.00,0.00,1.00 -247,105.60,-14.40,1.00,0.00,1.00 -248,110.40,-14.40,1.00,0.00,1.00 -249,115.20,-14.40,1.00,0.00,1.00 -250,120.00,-14.40,1.00,0.00,1.00 -251,124.80,-9.60,1.00,0.00,1.00 -252,129.60,-9.60,1.00,0.00,1.00 -253,134.40,-9.60,1.00,0.00,1.00 -254,139.20,-9.60,1.00,0.00,1.00 -255,144.00,-9.60,1.00,0.00,1.00 -256,148.80,-9.60,1.00,0.00,1.00 -257,153.60,-4.80,1.00,0.00,1.00 -258,158.40,-4.80,1.00,0.00,1.00 -259,163.20,-4.80,1.00,0.00,1.00 -260,168.00,-4.80,1.00,0.00,1.00 -261,172.80,-0.00,1.00,0.00,1.00 -262,177.60,-0.00,1.00,0.00,1.00 -263,-177.60,0.00,1.00,0.00,1.00 -264,-172.80,0.00,1.00,0.00,1.00 -265,-168.00,4.80,1.00,0.00,1.00 -266,-163.20,4.80,1.00,0.00,1.00 -267,-158.40,4.80,1.00,0.00,1.00 -268,-153.60,4.80,1.00,0.00,1.00 -269,-148.80,9.60,1.00,0.00,1.00 -270,-144.00,9.60,1.00,0.00,1.00 -271,-139.20,9.60,1.00,0.00,1.00 -272,-134.40,9.60,1.00,0.00,1.00 -273,-129.60,9.60,1.00,0.00,1.00 -274,-124.80,9.60,1.00,0.00,1.00 -275,-120.00,14.40,1.00,0.00,1.00 -276,-115.20,14.40,1.00,0.00,1.00 -277,-110.40,14.40,1.00,0.00,1.00 -278,-105.60,14.40,1.00,0.00,1.00 -279,-100.80,14.40,1.00,0.00,1.00 -280,-96.00,14.40,1.00,0.00,1.00 -281,-91.20,14.40,1.00,0.00,1.00 -282,-86.40,14.40,1.00,0.00,1.00 -283,-81.60,14.40,1.00,0.00,1.00 -284,-76.80,14.40,1.00,0.00,1.00 -285,-72.00,14.40,1.00,0.00,1.00 -286,-67.20,14.40,1.00,0.00,1.00 -287,-62.40,14.40,1.00,0.00,1.00 -288,-57.60,14.40,1.00,0.00,1.00 -289,-52.80,9.60,1.00,0.00,1.00 -290,-48.00,9.60,1.00,0.00,1.00 -291,-43.20,9.60,1.00,0.00,1.00 -292,-38.40,9.60,1.00,0.00,1.00 -293,-33.60,9.60,1.00,0.00,1.00 -294,-28.80,4.80,1.00,0.00,1.00 -295,-24.00,4.80,1.00,0.00,1.00 -296,-19.20,4.80,1.00,0.00,1.00 -297,-14.40,4.80,1.00,0.00,1.00 -298,-9.60,0.00,1.00,0.00,1.00 -299,-4.80,0.00,1.00,0.00,1.00 -300,0.00,0.00,1.00,0.00,1.00 -301,4.80,-0.00,1.00,0.00,1.00 -302,9.60,-4.80,1.00,0.00,1.00 -303,14.40,-4.80,1.00,0.00,1.00 -304,19.20,-4.80,1.00,0.00,1.00 -305,24.00,-9.60,1.00,0.00,1.00 -306,28.80,-9.60,1.00,0.00,1.00 -307,33.60,-9.60,1.00,0.00,1.00 -308,38.40,-9.60,1.00,0.00,1.00 -309,43.20,-14.40,1.00,0.00,1.00 -310,48.00,-14.40,1.00,0.00,1.00 -311,52.80,-14.40,1.00,0.00,1.00 -312,57.60,-14.40,1.00,0.00,1.00 -313,62.40,-19.20,1.00,0.00,1.00 -314,67.20,-19.20,1.00,0.00,1.00 -315,72.00,-19.20,1.00,0.00,1.00 -316,76.80,-19.20,1.00,0.00,1.00 -317,81.60,-19.20,1.00,0.00,1.00 -318,86.40,-19.20,1.00,0.00,1.00 -319,91.20,-19.20,1.00,0.00,1.00 -320,96.00,-19.20,1.00,0.00,1.00 -321,100.80,-19.20,1.00,0.00,1.00 -322,105.60,-19.20,1.00,0.00,1.00 -323,110.40,-19.20,1.00,0.00,1.00 -324,115.20,-19.20,1.00,0.00,1.00 -325,120.00,-14.40,1.00,0.00,1.00 -326,124.80,-14.40,1.00,0.00,1.00 -327,129.60,-14.40,1.00,0.00,1.00 -328,134.40,-14.40,1.00,0.00,1.00 -329,139.20,-14.40,1.00,0.00,1.00 -330,144.00,-9.60,1.00,0.00,1.00 -331,148.80,-9.60,1.00,0.00,1.00 -332,153.60,-9.60,1.00,0.00,1.00 -333,158.40,-4.80,1.00,0.00,1.00 -334,163.20,-4.80,1.00,0.00,1.00 -335,168.00,-4.80,1.00,0.00,1.00 -336,172.80,-0.00,1.00,0.00,1.00 -337,177.60,-0.00,1.00,0.00,1.00 -338,-177.60,0.00,1.00,0.00,1.00 -339,-172.80,0.00,1.00,0.00,1.00 -340,-168.00,4.80,1.00,0.00,1.00 -341,-163.20,4.80,1.00,0.00,1.00 -342,-158.40,4.80,1.00,0.00,1.00 -343,-153.60,9.60,1.00,0.00,1.00 -344,-148.80,9.60,1.00,0.00,1.00 -345,-144.00,9.60,1.00,0.00,1.00 -346,-139.20,14.40,1.00,0.00,1.00 -347,-134.40,14.40,1.00,0.00,1.00 -348,-129.60,14.40,1.00,0.00,1.00 -349,-124.80,14.40,1.00,0.00,1.00 -350,-120.00,14.40,1.00,0.00,1.00 -351,-115.20,19.20,1.00,0.00,1.00 -352,-110.40,19.20,1.00,0.00,1.00 -353,-105.60,19.20,1.00,0.00,1.00 -354,-100.80,19.20,1.00,0.00,1.00 -355,-96.00,19.20,1.00,0.00,1.00 -356,-91.20,19.20,1.00,0.00,1.00 -357,-86.40,19.20,1.00,0.00,1.00 -358,-81.60,19.20,1.00,0.00,1.00 -359,-76.80,19.20,1.00,0.00,1.00 -360,-72.00,19.20,1.00,0.00,1.00 -361,-67.20,19.20,1.00,0.00,1.00 -362,-62.40,19.20,1.00,0.00,1.00 -363,-57.60,14.40,1.00,0.00,1.00 -364,-52.80,14.40,1.00,0.00,1.00 -365,-48.00,14.40,1.00,0.00,1.00 -366,-43.20,14.40,1.00,0.00,1.00 -367,-38.40,9.60,1.00,0.00,1.00 -368,-33.60,9.60,1.00,0.00,1.00 -369,-28.80,9.60,1.00,0.00,1.00 -370,-24.00,9.60,1.00,0.00,1.00 -371,-19.20,4.80,1.00,0.00,1.00 -372,-14.40,4.80,1.00,0.00,1.00 -373,-9.60,4.80,1.00,0.00,1.00 -374,-4.80,0.00,1.00,0.00,1.00 -375,0.00,0.00,1.00,0.00,1.00 -376,4.80,-0.00,1.00,0.00,1.00 -377,9.60,-4.80,1.00,0.00,1.00 -378,14.40,-4.80,1.00,0.00,1.00 -379,19.20,-9.60,1.00,0.00,1.00 -380,24.00,-9.60,1.00,0.00,1.00 -381,28.80,-9.60,1.00,0.00,1.00 -382,33.60,-14.40,1.00,0.00,1.00 -383,33.60,-14.40,1.00,0.00,1.00 -384,38.40,-14.40,1.00,0.00,1.00 -385,43.20,-19.20,1.00,0.00,1.00 -386,48.00,-19.20,1.00,0.00,1.00 -387,57.60,-19.20,1.00,0.00,1.00 -388,62.40,-19.20,1.00,0.00,1.00 -389,67.20,-24.00,1.00,0.00,1.00 -390,72.00,-24.00,1.00,0.00,1.00 -391,76.80,-24.00,1.00,0.00,1.00 -392,81.60,-24.00,1.00,0.00,1.00 -393,86.40,-24.00,1.00,0.00,1.00 -394,91.20,-24.00,1.00,0.00,1.00 -395,96.00,-24.00,1.00,0.00,1.00 -396,100.80,-24.00,1.00,0.00,1.00 -397,105.60,-24.00,1.00,0.00,1.00 -398,110.40,-24.00,1.00,0.00,1.00 -399,115.20,-19.20,1.00,0.00,1.00 -400,120.00,-19.20,1.00,0.00,1.00 -401,129.60,-19.20,1.00,0.00,1.00 -402,134.40,-19.20,1.00,0.00,1.00 -403,139.20,-19.20,1.00,0.00,1.00 -404,144.00,-14.40,1.00,0.00,1.00 -405,148.80,-14.40,1.00,0.00,1.00 -406,148.80,-14.40,1.00,0.00,1.00 -407,153.60,-9.60,1.00,0.00,1.00 -408,158.40,-9.60,1.00,0.00,1.00 -409,163.20,-4.80,1.00,0.00,1.00 -410,168.00,-4.80,1.00,0.00,1.00 -411,172.80,-4.80,1.00,0.00,1.00 -412,177.60,-0.00,1.00,0.00,1.00 -413,-177.60,0.00,1.00,0.00,1.00 -414,-172.80,4.80,1.00,0.00,1.00 -415,-168.00,4.80,1.00,0.00,1.00 -416,-163.20,4.80,1.00,0.00,1.00 -417,-158.40,9.60,1.00,0.00,1.00 -418,-153.60,9.60,1.00,0.00,1.00 -419,-148.80,14.40,1.00,0.00,1.00 -420,-148.80,14.40,1.00,0.00,1.00 -421,-144.00,14.40,1.00,0.00,1.00 -422,-139.20,19.20,1.00,0.00,1.00 -423,-134.40,19.20,1.00,0.00,1.00 -424,-129.60,19.20,1.00,0.00,1.00 -425,-120.00,19.20,1.00,0.00,1.00 -426,-115.20,19.20,1.00,0.00,1.00 -427,-110.40,24.00,1.00,0.00,1.00 -428,-105.60,24.00,1.00,0.00,1.00 -429,-100.80,24.00,1.00,0.00,1.00 -430,-96.00,24.00,1.00,0.00,1.00 -431,-91.20,24.00,1.00,0.00,1.00 -432,-86.40,24.00,1.00,0.00,1.00 -433,-81.60,24.00,1.00,0.00,1.00 -434,-76.80,24.00,1.00,0.00,1.00 -435,-72.00,24.00,1.00,0.00,1.00 -436,-67.20,24.00,1.00,0.00,1.00 -437,-62.40,19.20,1.00,0.00,1.00 -438,-57.60,19.20,1.00,0.00,1.00 -439,-48.00,19.20,1.00,0.00,1.00 -440,-43.20,19.20,1.00,0.00,1.00 -441,-38.40,14.40,1.00,0.00,1.00 -442,-33.60,14.40,1.00,0.00,1.00 -443,-33.60,14.40,1.00,0.00,1.00 -444,-28.80,9.60,1.00,0.00,1.00 -445,-24.00,9.60,1.00,0.00,1.00 -446,-19.20,9.60,1.00,0.00,1.00 -447,-14.40,4.80,1.00,0.00,1.00 -448,-9.60,4.80,1.00,0.00,1.00 -449,-4.80,0.00,1.00,0.00,1.00 -450,0.00,0.00,1.00,0.00,1.00 -451,4.80,-0.00,1.00,0.00,1.00 -452,9.60,-4.80,1.00,0.00,1.00 -453,14.40,-4.80,1.00,0.00,1.00 -454,19.20,-9.60,1.00,0.00,1.00 -455,19.20,-9.60,1.00,0.00,1.00 -456,24.00,-14.40,1.00,0.00,1.00 -457,28.80,-14.40,1.00,0.00,1.00 -458,33.60,-19.20,1.00,0.00,1.00 -459,38.40,-19.20,1.00,0.00,1.00 -460,43.20,-19.20,1.00,0.00,1.00 -461,48.00,-24.00,1.00,0.00,1.00 -462,52.80,-24.00,1.00,0.00,1.00 -463,57.60,-24.00,1.00,0.00,1.00 -464,62.40,-24.00,1.00,0.00,1.00 -465,72.00,-28.80,1.00,0.00,1.00 -466,76.80,-28.80,1.00,0.00,1.00 -467,81.60,-28.80,1.00,0.00,1.00 -468,86.40,-28.80,1.00,0.00,1.00 -469,91.20,-28.80,1.00,0.00,1.00 -470,96.00,-28.80,1.00,0.00,1.00 -471,100.80,-28.80,1.00,0.00,1.00 -472,105.60,-28.80,1.00,0.00,1.00 -473,115.20,-28.80,1.00,0.00,1.00 -474,120.00,-24.00,1.00,0.00,1.00 -475,124.80,-24.00,1.00,0.00,1.00 -476,129.60,-24.00,1.00,0.00,1.00 -477,134.40,-24.00,1.00,0.00,1.00 -478,139.20,-19.20,1.00,0.00,1.00 -479,144.00,-19.20,1.00,0.00,1.00 -480,148.80,-14.40,1.00,0.00,1.00 -481,153.60,-14.40,1.00,0.00,1.00 -482,158.40,-14.40,1.00,0.00,1.00 -483,163.20,-9.60,1.00,0.00,1.00 -484,163.20,-9.60,1.00,0.00,1.00 -485,168.00,-4.80,1.00,0.00,1.00 -486,172.80,-4.80,1.00,0.00,1.00 -487,177.60,-0.00,1.00,0.00,1.00 -488,-177.60,0.00,1.00,0.00,1.00 -489,-172.80,4.80,1.00,0.00,1.00 -490,-168.00,4.80,1.00,0.00,1.00 -491,-163.20,9.60,1.00,0.00,1.00 -492,-163.20,9.60,1.00,0.00,1.00 -493,-158.40,14.40,1.00,0.00,1.00 -494,-153.60,14.40,1.00,0.00,1.00 -495,-148.80,14.40,1.00,0.00,1.00 -496,-144.00,19.20,1.00,0.00,1.00 -497,-139.20,19.20,1.00,0.00,1.00 -498,-134.40,24.00,1.00,0.00,1.00 -499,-129.60,24.00,1.00,0.00,1.00 -500,-124.80,24.00,1.00,0.00,1.00 -501,-120.00,24.00,1.00,0.00,1.00 -502,-115.20,28.80,1.00,0.00,1.00 -503,-105.60,28.80,1.00,0.00,1.00 -504,-100.80,28.80,1.00,0.00,1.00 -505,-96.00,28.80,1.00,0.00,1.00 -506,-91.20,28.80,1.00,0.00,1.00 -507,-86.40,28.80,1.00,0.00,1.00 -508,-81.60,28.80,1.00,0.00,1.00 -509,-76.80,28.80,1.00,0.00,1.00 -510,-72.00,28.80,1.00,0.00,1.00 -511,-62.40,24.00,1.00,0.00,1.00 -512,-57.60,24.00,1.00,0.00,1.00 -513,-52.80,24.00,1.00,0.00,1.00 -514,-48.00,24.00,1.00,0.00,1.00 -515,-43.20,19.20,1.00,0.00,1.00 -516,-38.40,19.20,1.00,0.00,1.00 -517,-33.60,19.20,1.00,0.00,1.00 -518,-28.80,14.40,1.00,0.00,1.00 -519,-24.00,14.40,1.00,0.00,1.00 -520,-19.20,9.60,1.00,0.00,1.00 -521,-19.20,9.60,1.00,0.00,1.00 -522,-14.40,4.80,1.00,0.00,1.00 -523,-9.60,4.80,1.00,0.00,1.00 -524,-4.80,0.00,1.00,0.00,1.00 -525,0.00,0.00,1.00,0.00,1.00 -526,4.80,-4.80,1.00,0.00,1.00 -527,9.60,-4.80,1.00,0.00,1.00 -528,14.40,-9.60,1.00,0.00,1.00 -529,14.40,-9.60,1.00,0.00,1.00 -530,19.20,-14.40,1.00,0.00,1.00 -531,24.00,-14.40,1.00,0.00,1.00 -532,28.80,-19.20,1.00,0.00,1.00 -533,33.60,-19.20,1.00,0.00,1.00 -534,38.40,-24.00,1.00,0.00,1.00 -535,43.20,-24.00,1.00,0.00,1.00 -536,48.00,-24.00,1.00,0.00,1.00 -537,52.80,-28.80,1.00,0.00,1.00 -538,57.60,-28.80,1.00,0.00,1.00 -539,62.40,-28.80,1.00,0.00,1.00 -540,67.20,-33.60,1.00,0.00,1.00 -541,72.00,-33.60,1.00,0.00,1.00 -542,81.60,-33.60,1.00,0.00,1.00 -543,86.40,-33.60,1.00,0.00,1.00 -544,91.20,-33.60,1.00,0.00,1.00 -545,96.00,-33.60,1.00,0.00,1.00 -546,100.80,-33.60,1.00,0.00,1.00 -547,110.40,-33.60,1.00,0.00,1.00 -548,115.20,-33.60,1.00,0.00,1.00 -549,120.00,-28.80,1.00,0.00,1.00 -550,124.80,-28.80,1.00,0.00,1.00 -551,129.60,-28.80,1.00,0.00,1.00 -552,134.40,-24.00,1.00,0.00,1.00 -553,139.20,-24.00,1.00,0.00,1.00 -554,144.00,-19.20,1.00,0.00,1.00 -555,148.80,-19.20,1.00,0.00,1.00 -556,153.60,-14.40,1.00,0.00,1.00 -557,158.40,-14.40,1.00,0.00,1.00 -558,163.20,-9.60,1.00,0.00,1.00 -559,168.00,-9.60,1.00,0.00,1.00 -560,168.00,-4.80,1.00,0.00,1.00 -561,172.80,-4.80,1.00,0.00,1.00 -562,177.60,-0.00,1.00,0.00,1.00 -563,-177.60,0.00,1.00,0.00,1.00 -564,-172.80,4.80,1.00,0.00,1.00 -565,-168.00,4.80,1.00,0.00,1.00 -566,-168.00,9.60,1.00,0.00,1.00 -567,-163.20,9.60,1.00,0.00,1.00 -568,-158.40,14.40,1.00,0.00,1.00 -569,-153.60,14.40,1.00,0.00,1.00 -570,-148.80,19.20,1.00,0.00,1.00 -571,-144.00,19.20,1.00,0.00,1.00 -572,-139.20,24.00,1.00,0.00,1.00 -573,-134.40,24.00,1.00,0.00,1.00 -574,-129.60,28.80,1.00,0.00,1.00 -575,-124.80,28.80,1.00,0.00,1.00 -576,-120.00,28.80,1.00,0.00,1.00 -577,-115.20,33.60,1.00,0.00,1.00 -578,-110.40,33.60,1.00,0.00,1.00 -579,-100.80,33.60,1.00,0.00,1.00 -580,-96.00,33.60,1.00,0.00,1.00 -581,-91.20,33.60,1.00,0.00,1.00 -582,-86.40,33.60,1.00,0.00,1.00 -583,-81.60,33.60,1.00,0.00,1.00 -584,-72.00,33.60,1.00,0.00,1.00 -585,-67.20,33.60,1.00,0.00,1.00 -586,-62.40,28.80,1.00,0.00,1.00 -587,-57.60,28.80,1.00,0.00,1.00 -588,-52.80,28.80,1.00,0.00,1.00 -589,-48.00,24.00,1.00,0.00,1.00 -590,-43.20,24.00,1.00,0.00,1.00 -591,-38.40,24.00,1.00,0.00,1.00 -592,-33.60,19.20,1.00,0.00,1.00 -593,-28.80,19.20,1.00,0.00,1.00 -594,-24.00,14.40,1.00,0.00,1.00 -595,-19.20,14.40,1.00,0.00,1.00 -596,-14.40,9.60,1.00,0.00,1.00 -597,-14.40,9.60,1.00,0.00,1.00 -598,-9.60,4.80,1.00,0.00,1.00 -599,-4.80,4.80,1.00,0.00,1.00 -600,0.00,0.00,1.00,0.00,1.00 -601,4.80,-4.80,1.00,0.00,1.00 -602,9.60,-4.80,1.00,0.00,1.00 -603,9.60,-9.60,1.00,0.00,1.00 -604,14.40,-9.60,1.00,0.00,1.00 -605,19.20,-14.40,1.00,0.00,1.00 -606,24.00,-19.20,1.00,0.00,1.00 -607,28.80,-19.20,1.00,0.00,1.00 -608,33.60,-24.00,1.00,0.00,1.00 -609,38.40,-24.00,1.00,0.00,1.00 -610,43.20,-28.80,1.00,0.00,1.00 -611,48.00,-28.80,1.00,0.00,1.00 -612,52.80,-33.60,1.00,0.00,1.00 -613,57.60,-33.60,1.00,0.00,1.00 -614,62.40,-33.60,1.00,0.00,1.00 -615,67.20,-38.40,1.00,0.00,1.00 -616,72.00,-38.40,1.00,0.00,1.00 -617,81.60,-38.40,1.00,0.00,1.00 -618,86.40,-38.40,1.00,0.00,1.00 -619,91.20,-38.40,1.00,0.00,1.00 -620,96.00,-38.40,1.00,0.00,1.00 -621,105.60,-38.40,1.00,0.00,1.00 -622,110.40,-38.40,1.00,0.00,1.00 -623,115.20,-33.60,1.00,0.00,1.00 -624,120.00,-33.60,1.00,0.00,1.00 -625,124.80,-33.60,1.00,0.00,1.00 -626,129.60,-28.80,1.00,0.00,1.00 -627,134.40,-28.80,1.00,0.00,1.00 -628,139.20,-24.00,1.00,0.00,1.00 -629,144.00,-24.00,1.00,0.00,1.00 -630,148.80,-19.20,1.00,0.00,1.00 -631,153.60,-19.20,1.00,0.00,1.00 -632,158.40,-14.40,1.00,0.00,1.00 -633,163.20,-14.40,1.00,0.00,1.00 -634,168.00,-9.60,1.00,0.00,1.00 -635,172.80,-9.60,1.00,0.00,1.00 -636,172.80,-4.80,1.00,0.00,1.00 -637,177.60,-0.00,1.00,0.00,1.00 -638,-177.60,0.00,1.00,0.00,1.00 -639,-172.80,4.80,1.00,0.00,1.00 -640,-172.80,9.60,1.00,0.00,1.00 -641,-168.00,9.60,1.00,0.00,1.00 -642,-163.20,14.40,1.00,0.00,1.00 -643,-158.40,14.40,1.00,0.00,1.00 -644,-153.60,19.20,1.00,0.00,1.00 -645,-148.80,19.20,1.00,0.00,1.00 -646,-144.00,24.00,1.00,0.00,1.00 -647,-139.20,24.00,1.00,0.00,1.00 -648,-134.40,28.80,1.00,0.00,1.00 -649,-129.60,28.80,1.00,0.00,1.00 -650,-124.80,33.60,1.00,0.00,1.00 -651,-120.00,33.60,1.00,0.00,1.00 -652,-115.20,33.60,1.00,0.00,1.00 -653,-110.40,38.40,1.00,0.00,1.00 -654,-105.60,38.40,1.00,0.00,1.00 -655,-96.00,38.40,1.00,0.00,1.00 -656,-91.20,38.40,1.00,0.00,1.00 -657,-86.40,38.40,1.00,0.00,1.00 -658,-81.60,38.40,1.00,0.00,1.00 -659,-72.00,38.40,1.00,0.00,1.00 -660,-67.20,38.40,1.00,0.00,1.00 -661,-62.40,33.60,1.00,0.00,1.00 -662,-57.60,33.60,1.00,0.00,1.00 -663,-52.80,33.60,1.00,0.00,1.00 -664,-48.00,28.80,1.00,0.00,1.00 -665,-43.20,28.80,1.00,0.00,1.00 -666,-38.40,24.00,1.00,0.00,1.00 -667,-33.60,24.00,1.00,0.00,1.00 -668,-28.80,19.20,1.00,0.00,1.00 -669,-24.00,19.20,1.00,0.00,1.00 -670,-19.20,14.40,1.00,0.00,1.00 -671,-14.40,9.60,1.00,0.00,1.00 -672,-9.60,9.60,1.00,0.00,1.00 -673,-9.60,4.80,1.00,0.00,1.00 -674,-4.80,4.80,1.00,0.00,1.00 -675,0.00,0.00,1.00,0.00,1.00 -676,4.80,-4.80,1.00,0.00,1.00 -677,4.80,-4.80,1.00,0.00,1.00 -678,9.60,-9.60,1.00,0.00,1.00 -679,14.40,-14.40,1.00,0.00,1.00 -680,19.20,-14.40,1.00,0.00,1.00 -681,24.00,-19.20,1.00,0.00,1.00 -682,24.00,-24.00,1.00,0.00,1.00 -683,28.80,-24.00,1.00,0.00,1.00 -684,33.60,-28.80,1.00,0.00,1.00 -685,38.40,-28.80,1.00,0.00,1.00 -686,43.20,-33.60,1.00,0.00,1.00 -687,48.00,-33.60,1.00,0.00,1.00 -688,52.80,-38.40,1.00,0.00,1.00 -689,62.40,-38.40,1.00,0.00,1.00 -690,67.20,-38.40,1.00,0.00,1.00 -691,72.00,-43.20,1.00,0.00,1.00 -692,76.80,-43.20,1.00,0.00,1.00 -693,86.40,-43.20,1.00,0.00,1.00 -694,91.20,-43.20,1.00,0.00,1.00 -695,96.00,-43.20,1.00,0.00,1.00 -696,105.60,-43.20,1.00,0.00,1.00 -697,110.40,-43.20,1.00,0.00,1.00 -698,115.20,-38.40,1.00,0.00,1.00 -699,124.80,-38.40,1.00,0.00,1.00 -700,129.60,-38.40,1.00,0.00,1.00 -701,134.40,-33.60,1.00,0.00,1.00 -702,139.20,-33.60,1.00,0.00,1.00 -703,144.00,-28.80,1.00,0.00,1.00 -704,148.80,-28.80,1.00,0.00,1.00 -705,153.60,-24.00,1.00,0.00,1.00 -706,158.40,-19.20,1.00,0.00,1.00 -707,158.40,-19.20,1.00,0.00,1.00 -708,163.20,-14.40,1.00,0.00,1.00 -709,168.00,-9.60,1.00,0.00,1.00 -710,172.80,-9.60,1.00,0.00,1.00 -711,172.80,-4.80,1.00,0.00,1.00 -712,177.60,-0.00,1.00,0.00,1.00 -713,-177.60,0.00,1.00,0.00,1.00 -714,-172.80,4.80,1.00,0.00,1.00 -715,-172.80,9.60,1.00,0.00,1.00 -716,-168.00,9.60,1.00,0.00,1.00 -717,-163.20,14.40,1.00,0.00,1.00 -718,-158.40,19.20,1.00,0.00,1.00 -719,-158.40,19.20,1.00,0.00,1.00 -720,-153.60,24.00,1.00,0.00,1.00 -721,-148.80,28.80,1.00,0.00,1.00 -722,-144.00,28.80,1.00,0.00,1.00 -723,-139.20,33.60,1.00,0.00,1.00 -724,-134.40,33.60,1.00,0.00,1.00 -725,-129.60,38.40,1.00,0.00,1.00 -726,-124.80,38.40,1.00,0.00,1.00 -727,-115.20,38.40,1.00,0.00,1.00 -728,-110.40,43.20,1.00,0.00,1.00 -729,-105.60,43.20,1.00,0.00,1.00 -730,-96.00,43.20,1.00,0.00,1.00 -731,-91.20,43.20,1.00,0.00,1.00 -732,-86.40,43.20,1.00,0.00,1.00 -733,-76.80,43.20,1.00,0.00,1.00 -734,-72.00,43.20,1.00,0.00,1.00 -735,-67.20,38.40,1.00,0.00,1.00 -736,-62.40,38.40,1.00,0.00,1.00 -737,-52.80,38.40,1.00,0.00,1.00 -738,-48.00,33.60,1.00,0.00,1.00 -739,-43.20,33.60,1.00,0.00,1.00 -740,-38.40,28.80,1.00,0.00,1.00 -741,-33.60,28.80,1.00,0.00,1.00 -742,-28.80,24.00,1.00,0.00,1.00 -743,-24.00,24.00,1.00,0.00,1.00 -744,-24.00,19.20,1.00,0.00,1.00 -745,-19.20,14.40,1.00,0.00,1.00 -746,-14.40,14.40,1.00,0.00,1.00 -747,-9.60,9.60,1.00,0.00,1.00 -748,-4.80,4.80,1.00,0.00,1.00 -749,-4.80,4.80,1.00,0.00,1.00 -750,0.00,0.00,1.00,0.00,1.00 -751,4.80,-4.80,1.00,0.00,1.00 -752,4.80,-4.80,1.00,0.00,1.00 -753,9.60,-9.60,1.00,0.00,1.00 -754,14.40,-14.40,1.00,0.00,1.00 -755,14.40,-19.20,1.00,0.00,1.00 -756,19.20,-19.20,1.00,0.00,1.00 -757,24.00,-24.00,1.00,0.00,1.00 -758,28.80,-28.80,1.00,0.00,1.00 -759,33.60,-28.80,1.00,0.00,1.00 -760,38.40,-33.60,1.00,0.00,1.00 -761,43.20,-38.40,1.00,0.00,1.00 -762,48.00,-38.40,1.00,0.00,1.00 -763,52.80,-43.20,1.00,0.00,1.00 -764,57.60,-43.20,1.00,0.00,1.00 -765,62.40,-43.20,1.00,0.00,1.00 -766,72.00,-48.00,1.00,0.00,1.00 -767,76.80,-48.00,1.00,0.00,1.00 -768,86.40,-48.00,1.00,0.00,1.00 -769,91.20,-48.00,1.00,0.00,1.00 -770,100.80,-48.00,1.00,0.00,1.00 -771,105.60,-48.00,1.00,0.00,1.00 -772,110.40,-48.00,1.00,0.00,1.00 -773,120.00,-43.20,1.00,0.00,1.00 -774,124.80,-43.20,1.00,0.00,1.00 -775,129.60,-38.40,1.00,0.00,1.00 -776,134.40,-38.40,1.00,0.00,1.00 -777,139.20,-33.60,1.00,0.00,1.00 -778,144.00,-33.60,1.00,0.00,1.00 -779,148.80,-28.80,1.00,0.00,1.00 -780,153.60,-24.00,1.00,0.00,1.00 -781,158.40,-24.00,1.00,0.00,1.00 -782,163.20,-19.20,1.00,0.00,1.00 -783,163.20,-14.40,1.00,0.00,1.00 -784,168.00,-14.40,1.00,0.00,1.00 -785,172.80,-9.60,1.00,0.00,1.00 -786,172.80,-4.80,1.00,0.00,1.00 -787,177.60,-0.00,1.00,0.00,1.00 -788,-177.60,0.00,1.00,0.00,1.00 -789,-172.80,4.80,1.00,0.00,1.00 -790,-172.80,9.60,1.00,0.00,1.00 -791,-168.00,14.40,1.00,0.00,1.00 -792,-163.20,14.40,1.00,0.00,1.00 -793,-163.20,19.20,1.00,0.00,1.00 -794,-158.40,24.00,1.00,0.00,1.00 -795,-153.60,24.00,1.00,0.00,1.00 -796,-148.80,28.80,1.00,0.00,1.00 -797,-144.00,33.60,1.00,0.00,1.00 -798,-139.20,33.60,1.00,0.00,1.00 -799,-134.40,38.40,1.00,0.00,1.00 -800,-129.60,38.40,1.00,0.00,1.00 -801,-124.80,43.20,1.00,0.00,1.00 -802,-120.00,43.20,1.00,0.00,1.00 -803,-110.40,48.00,1.00,0.00,1.00 -804,-105.60,48.00,1.00,0.00,1.00 -805,-100.80,48.00,1.00,0.00,1.00 -806,-91.20,48.00,1.00,0.00,1.00 -807,-86.40,48.00,1.00,0.00,1.00 -808,-76.80,48.00,1.00,0.00,1.00 -809,-72.00,48.00,1.00,0.00,1.00 -810,-62.40,43.20,1.00,0.00,1.00 -811,-57.60,43.20,1.00,0.00,1.00 -812,-52.80,43.20,1.00,0.00,1.00 -813,-48.00,38.40,1.00,0.00,1.00 -814,-43.20,38.40,1.00,0.00,1.00 -815,-38.40,33.60,1.00,0.00,1.00 -816,-33.60,28.80,1.00,0.00,1.00 -817,-28.80,28.80,1.00,0.00,1.00 -818,-24.00,24.00,1.00,0.00,1.00 -819,-19.20,19.20,1.00,0.00,1.00 -820,-14.40,19.20,1.00,0.00,1.00 -821,-14.40,14.40,1.00,0.00,1.00 -822,-9.60,9.60,1.00,0.00,1.00 -823,-4.80,4.80,1.00,0.00,1.00 -824,-4.80,4.80,1.00,0.00,1.00 -825,0.00,0.00,1.00,0.00,1.00 -826,4.80,-4.80,1.00,0.00,1.00 -827,4.80,-9.60,1.00,0.00,1.00 -828,9.60,-9.60,1.00,0.00,1.00 -829,9.60,-14.40,1.00,0.00,1.00 -830,14.40,-19.20,1.00,0.00,1.00 -831,19.20,-24.00,1.00,0.00,1.00 -832,24.00,-24.00,1.00,0.00,1.00 -833,24.00,-28.80,1.00,0.00,1.00 -834,28.80,-33.60,1.00,0.00,1.00 -835,33.60,-38.40,1.00,0.00,1.00 -836,38.40,-38.40,1.00,0.00,1.00 -837,43.20,-43.20,1.00,0.00,1.00 -838,48.00,-43.20,1.00,0.00,1.00 -839,52.80,-48.00,1.00,0.00,1.00 -840,62.40,-48.00,1.00,0.00,1.00 -841,67.20,-52.80,1.00,0.00,1.00 -842,76.80,-52.80,1.00,0.00,1.00 -843,86.40,-52.80,1.00,0.00,1.00 -844,91.20,-52.80,1.00,0.00,1.00 -845,100.80,-52.80,1.00,0.00,1.00 -846,105.60,-52.80,1.00,0.00,1.00 -847,115.20,-48.00,1.00,0.00,1.00 -848,120.00,-48.00,1.00,0.00,1.00 -849,129.60,-48.00,1.00,0.00,1.00 -850,134.40,-43.20,1.00,0.00,1.00 -851,139.20,-43.20,1.00,0.00,1.00 -852,144.00,-38.40,1.00,0.00,1.00 -853,148.80,-33.60,1.00,0.00,1.00 -854,153.60,-33.60,1.00,0.00,1.00 -855,158.40,-28.80,1.00,0.00,1.00 -856,158.40,-24.00,1.00,0.00,1.00 -857,163.20,-19.20,1.00,0.00,1.00 -858,168.00,-19.20,1.00,0.00,1.00 -859,168.00,-14.40,1.00,0.00,1.00 -860,172.80,-9.60,1.00,0.00,1.00 -861,177.60,-4.80,1.00,0.00,1.00 -862,177.60,-0.00,1.00,0.00,1.00 -863,-177.60,0.00,1.00,0.00,1.00 -864,-177.60,4.80,1.00,0.00,1.00 -865,-172.80,9.60,1.00,0.00,1.00 -866,-168.00,14.40,1.00,0.00,1.00 -867,-168.00,19.20,1.00,0.00,1.00 -868,-163.20,19.20,1.00,0.00,1.00 -869,-158.40,24.00,1.00,0.00,1.00 -870,-158.40,28.80,1.00,0.00,1.00 -871,-153.60,33.60,1.00,0.00,1.00 -872,-148.80,33.60,1.00,0.00,1.00 -873,-144.00,38.40,1.00,0.00,1.00 -874,-139.20,43.20,1.00,0.00,1.00 -875,-134.40,43.20,1.00,0.00,1.00 -876,-129.60,48.00,1.00,0.00,1.00 -877,-120.00,48.00,1.00,0.00,1.00 -878,-115.20,48.00,1.00,0.00,1.00 -879,-105.60,52.80,1.00,0.00,1.00 -880,-100.80,52.80,1.00,0.00,1.00 -881,-91.20,52.80,1.00,0.00,1.00 -882,-86.40,52.80,1.00,0.00,1.00 -883,-76.80,52.80,1.00,0.00,1.00 -884,-67.20,52.80,1.00,0.00,1.00 -885,-62.40,48.00,1.00,0.00,1.00 -886,-52.80,48.00,1.00,0.00,1.00 -887,-48.00,43.20,1.00,0.00,1.00 -888,-43.20,43.20,1.00,0.00,1.00 -889,-38.40,38.40,1.00,0.00,1.00 -890,-33.60,38.40,1.00,0.00,1.00 -891,-28.80,33.60,1.00,0.00,1.00 -892,-24.00,28.80,1.00,0.00,1.00 -893,-24.00,24.00,1.00,0.00,1.00 -894,-19.20,24.00,1.00,0.00,1.00 -895,-14.40,19.20,1.00,0.00,1.00 -896,-9.60,14.40,1.00,0.00,1.00 -897,-9.60,9.60,1.00,0.00,1.00 -898,-4.80,9.60,1.00,0.00,1.00 -899,-4.80,4.80,1.00,0.00,1.00 -900,0.00,0.00,1.00,0.00,1.00 -901,4.80,-4.80,1.00,0.00,1.00 -902,4.80,-9.60,1.00,0.00,1.00 -903,9.60,-14.40,1.00,0.00,1.00 -904,9.60,-14.40,1.00,0.00,1.00 -905,14.40,-19.20,1.00,0.00,1.00 -906,14.40,-24.00,1.00,0.00,1.00 -907,19.20,-28.80,1.00,0.00,1.00 -908,24.00,-33.60,1.00,0.00,1.00 -909,28.80,-33.60,1.00,0.00,1.00 -910,28.80,-38.40,1.00,0.00,1.00 -911,33.60,-43.20,1.00,0.00,1.00 -912,38.40,-43.20,1.00,0.00,1.00 -913,48.00,-48.00,1.00,0.00,1.00 -914,52.80,-52.80,1.00,0.00,1.00 -915,57.60,-52.80,1.00,0.00,1.00 -916,67.20,-57.60,1.00,0.00,1.00 -917,76.80,-57.60,1.00,0.00,1.00 -918,81.60,-57.60,1.00,0.00,1.00 -919,91.20,-57.60,1.00,0.00,1.00 -920,100.80,-57.60,1.00,0.00,1.00 -921,110.40,-57.60,1.00,0.00,1.00 -922,115.20,-52.80,1.00,0.00,1.00 -923,124.80,-52.80,1.00,0.00,1.00 -924,129.60,-48.00,1.00,0.00,1.00 -925,139.20,-48.00,1.00,0.00,1.00 -926,144.00,-43.20,1.00,0.00,1.00 -927,148.80,-38.40,1.00,0.00,1.00 -928,153.60,-38.40,1.00,0.00,1.00 -929,153.60,-33.60,1.00,0.00,1.00 -930,158.40,-28.80,1.00,0.00,1.00 -931,163.20,-24.00,1.00,0.00,1.00 -932,163.20,-24.00,1.00,0.00,1.00 -933,168.00,-19.20,1.00,0.00,1.00 -934,172.80,-14.40,1.00,0.00,1.00 -935,172.80,-9.60,1.00,0.00,1.00 -936,177.60,-4.80,1.00,0.00,1.00 -937,177.60,-0.00,1.00,0.00,1.00 -938,-177.60,0.00,1.00,0.00,1.00 -939,-177.60,4.80,1.00,0.00,1.00 -940,-172.80,9.60,1.00,0.00,1.00 -941,-172.80,14.40,1.00,0.00,1.00 -942,-168.00,19.20,1.00,0.00,1.00 -943,-163.20,24.00,1.00,0.00,1.00 -944,-163.20,24.00,1.00,0.00,1.00 -945,-158.40,28.80,1.00,0.00,1.00 -946,-153.60,33.60,1.00,0.00,1.00 -947,-153.60,38.40,1.00,0.00,1.00 -948,-148.80,38.40,1.00,0.00,1.00 -949,-144.00,43.20,1.00,0.00,1.00 -950,-139.20,48.00,1.00,0.00,1.00 -951,-129.60,48.00,1.00,0.00,1.00 -952,-124.80,52.80,1.00,0.00,1.00 -953,-115.20,52.80,1.00,0.00,1.00 -954,-110.40,57.60,1.00,0.00,1.00 -955,-100.80,57.60,1.00,0.00,1.00 -956,-91.20,57.60,1.00,0.00,1.00 -957,-81.60,57.60,1.00,0.00,1.00 -958,-76.80,57.60,1.00,0.00,1.00 -959,-67.20,57.60,1.00,0.00,1.00 -960,-57.60,52.80,1.00,0.00,1.00 -961,-52.80,52.80,1.00,0.00,1.00 -962,-48.00,48.00,1.00,0.00,1.00 -963,-38.40,43.20,1.00,0.00,1.00 -964,-33.60,43.20,1.00,0.00,1.00 -965,-28.80,38.40,1.00,0.00,1.00 -966,-28.80,33.60,1.00,0.00,1.00 -967,-24.00,33.60,1.00,0.00,1.00 -968,-19.20,28.80,1.00,0.00,1.00 -969,-14.40,24.00,1.00,0.00,1.00 -970,-14.40,19.20,1.00,0.00,1.00 -971,-9.60,14.40,1.00,0.00,1.00 -972,-9.60,14.40,1.00,0.00,1.00 -973,-4.80,9.60,1.00,0.00,1.00 -974,-4.80,4.80,1.00,0.00,1.00 -975,0.00,0.00,1.00,0.00,1.00 -976,0.00,-4.80,1.00,0.00,1.00 -977,4.80,-9.60,1.00,0.00,1.00 -978,4.80,-14.40,1.00,0.00,1.00 -979,9.60,-19.20,1.00,0.00,1.00 -980,9.60,-19.20,1.00,0.00,1.00 -981,14.40,-24.00,1.00,0.00,1.00 -982,19.20,-28.80,1.00,0.00,1.00 -983,19.20,-33.60,1.00,0.00,1.00 -984,24.00,-38.40,1.00,0.00,1.00 -985,28.80,-43.20,1.00,0.00,1.00 -986,33.60,-43.20,1.00,0.00,1.00 -987,38.40,-48.00,1.00,0.00,1.00 -988,43.20,-52.80,1.00,0.00,1.00 -989,48.00,-52.80,1.00,0.00,1.00 -990,52.80,-57.60,1.00,0.00,1.00 -991,62.40,-57.60,1.00,0.00,1.00 -992,72.00,-62.40,1.00,0.00,1.00 -993,81.60,-62.40,1.00,0.00,1.00 -994,91.20,-62.40,1.00,0.00,1.00 -995,100.80,-62.40,1.00,0.00,1.00 -996,110.40,-62.40,1.00,0.00,1.00 -997,120.00,-57.60,1.00,0.00,1.00 -998,129.60,-57.60,1.00,0.00,1.00 -999,134.40,-52.80,1.00,0.00,1.00 -1000,139.20,-48.00,1.00,0.00,1.00 -1001,144.00,-48.00,1.00,0.00,1.00 -1002,148.80,-43.20,1.00,0.00,1.00 -1003,153.60,-38.40,1.00,0.00,1.00 -1004,158.40,-33.60,1.00,0.00,1.00 -1005,163.20,-33.60,1.00,0.00,1.00 -1006,163.20,-28.80,1.00,0.00,1.00 -1007,168.00,-24.00,1.00,0.00,1.00 -1008,168.00,-19.20,1.00,0.00,1.00 -1009,172.80,-14.40,1.00,0.00,1.00 -1010,172.80,-9.60,1.00,0.00,1.00 -1011,177.60,-4.80,1.00,0.00,1.00 -1012,177.60,-0.00,1.00,0.00,1.00 -1013,-177.60,0.00,1.00,0.00,1.00 -1014,-177.60,4.80,1.00,0.00,1.00 -1015,-172.80,9.60,1.00,0.00,1.00 -1016,-172.80,14.40,1.00,0.00,1.00 -1017,-168.00,19.20,1.00,0.00,1.00 -1018,-168.00,24.00,1.00,0.00,1.00 -1019,-163.20,28.80,1.00,0.00,1.00 -1020,-163.20,33.60,1.00,0.00,1.00 -1021,-158.40,33.60,1.00,0.00,1.00 -1022,-153.60,38.40,1.00,0.00,1.00 -1023,-148.80,43.20,1.00,0.00,1.00 -1024,-144.00,48.00,1.00,0.00,1.00 -1025,-139.20,48.00,1.00,0.00,1.00 -1026,-134.40,52.80,1.00,0.00,1.00 -1027,-129.60,57.60,1.00,0.00,1.00 -1028,-120.00,57.60,1.00,0.00,1.00 -1029,-110.40,62.40,1.00,0.00,1.00 -1030,-100.80,62.40,1.00,0.00,1.00 -1031,-91.20,62.40,1.00,0.00,1.00 -1032,-81.60,62.40,1.00,0.00,1.00 -1033,-72.00,62.40,1.00,0.00,1.00 -1034,-62.40,57.60,1.00,0.00,1.00 -1035,-52.80,57.60,1.00,0.00,1.00 -1036,-48.00,52.80,1.00,0.00,1.00 -1037,-43.20,52.80,1.00,0.00,1.00 -1038,-38.40,48.00,1.00,0.00,1.00 -1039,-33.60,43.20,1.00,0.00,1.00 -1040,-28.80,43.20,1.00,0.00,1.00 -1041,-24.00,38.40,1.00,0.00,1.00 -1042,-19.20,33.60,1.00,0.00,1.00 -1043,-19.20,28.80,1.00,0.00,1.00 -1044,-14.40,24.00,1.00,0.00,1.00 -1045,-9.60,19.20,1.00,0.00,1.00 -1046,-9.60,19.20,1.00,0.00,1.00 -1047,-4.80,14.40,1.00,0.00,1.00 -1048,-4.80,9.60,1.00,0.00,1.00 -1049,-0.00,4.80,1.00,0.00,1.00 -1050,0.00,0.00,1.00,0.00,1.00 -1051,0.00,-4.80,1.00,0.00,1.00 -1052,4.80,-9.60,1.00,0.00,1.00 -1053,4.80,-14.40,1.00,0.00,1.00 -1054,9.60,-19.20,1.00,0.00,1.00 -1055,9.60,-24.00,1.00,0.00,1.00 -1056,14.40,-24.00,1.00,0.00,1.00 -1057,14.40,-28.80,1.00,0.00,1.00 -1058,19.20,-33.60,1.00,0.00,1.00 -1059,19.20,-38.40,1.00,0.00,1.00 -1060,24.00,-43.20,1.00,0.00,1.00 -1061,28.80,-48.00,1.00,0.00,1.00 -1062,33.60,-52.80,1.00,0.00,1.00 -1063,38.40,-52.80,1.00,0.00,1.00 -1064,43.20,-57.60,1.00,0.00,1.00 -1065,48.00,-62.40,1.00,0.00,1.00 -1066,57.60,-62.40,1.00,0.00,1.00 -1067,67.20,-67.20,1.00,0.00,1.00 -1068,81.60,-67.20,1.00,0.00,1.00 -1069,91.20,-67.20,1.00,0.00,1.00 -1070,105.60,-67.20,1.00,0.00,1.00 -1071,115.20,-67.20,1.00,0.00,1.00 -1072,124.80,-62.40,1.00,0.00,1.00 -1073,134.40,-57.60,1.00,0.00,1.00 -1074,139.20,-57.60,1.00,0.00,1.00 -1075,144.00,-52.80,1.00,0.00,1.00 -1076,148.80,-48.00,1.00,0.00,1.00 -1077,153.60,-43.20,1.00,0.00,1.00 -1078,158.40,-43.20,1.00,0.00,1.00 -1079,163.20,-38.40,1.00,0.00,1.00 -1080,163.20,-33.60,1.00,0.00,1.00 -1081,168.00,-28.80,1.00,0.00,1.00 -1082,168.00,-24.00,1.00,0.00,1.00 -1083,172.80,-19.20,1.00,0.00,1.00 -1084,172.80,-14.40,1.00,0.00,1.00 -1085,177.60,-9.60,1.00,0.00,1.00 -1086,177.60,-4.80,1.00,0.00,1.00 -1087,177.60,-0.00,1.00,0.00,1.00 -1088,-177.60,0.00,1.00,0.00,1.00 -1089,-177.60,4.80,1.00,0.00,1.00 -1090,-177.60,9.60,1.00,0.00,1.00 -1091,-172.80,14.40,1.00,0.00,1.00 -1092,-172.80,19.20,1.00,0.00,1.00 -1093,-168.00,24.00,1.00,0.00,1.00 -1094,-168.00,28.80,1.00,0.00,1.00 -1095,-163.20,33.60,1.00,0.00,1.00 -1096,-163.20,38.40,1.00,0.00,1.00 -1097,-158.40,43.20,1.00,0.00,1.00 -1098,-153.60,43.20,1.00,0.00,1.00 -1099,-148.80,48.00,1.00,0.00,1.00 -1100,-144.00,52.80,1.00,0.00,1.00 -1101,-139.20,57.60,1.00,0.00,1.00 -1102,-134.40,57.60,1.00,0.00,1.00 -1103,-124.80,62.40,1.00,0.00,1.00 -1104,-115.20,67.20,1.00,0.00,1.00 -1105,-105.60,67.20,1.00,0.00,1.00 -1106,-91.20,67.20,1.00,0.00,1.00 -1107,-81.60,67.20,1.00,0.00,1.00 -1108,-67.20,67.20,1.00,0.00,1.00 -1109,-57.60,62.40,1.00,0.00,1.00 -1110,-48.00,62.40,1.00,0.00,1.00 -1111,-43.20,57.60,1.00,0.00,1.00 -1112,-38.40,52.80,1.00,0.00,1.00 -1113,-33.60,52.80,1.00,0.00,1.00 -1114,-28.80,48.00,1.00,0.00,1.00 -1115,-24.00,43.20,1.00,0.00,1.00 -1116,-19.20,38.40,1.00,0.00,1.00 -1117,-19.20,33.60,1.00,0.00,1.00 -1118,-14.40,28.80,1.00,0.00,1.00 -1119,-14.40,24.00,1.00,0.00,1.00 -1120,-9.60,24.00,1.00,0.00,1.00 -1121,-9.60,19.20,1.00,0.00,1.00 -1122,-4.80,14.40,1.00,0.00,1.00 -1123,-4.80,9.60,1.00,0.00,1.00 -1124,-0.00,4.80,1.00,0.00,1.00 -1125,0.00,0.00,1.00,0.00,1.00 -1126,0.00,-4.80,1.00,0.00,1.00 -1127,4.80,-9.60,1.00,0.00,1.00 -1128,4.80,-14.40,1.00,0.00,1.00 -1129,4.80,-19.20,1.00,0.00,1.00 -1130,9.60,-24.00,1.00,0.00,1.00 -1131,9.60,-28.80,1.00,0.00,1.00 -1132,9.60,-33.60,1.00,0.00,1.00 -1133,14.40,-38.40,1.00,0.00,1.00 -1134,14.40,-38.40,1.00,0.00,1.00 -1135,19.20,-43.20,1.00,0.00,1.00 -1136,24.00,-48.00,1.00,0.00,1.00 -1137,24.00,-52.80,1.00,0.00,1.00 -1138,28.80,-57.60,1.00,0.00,1.00 -1139,38.40,-62.40,1.00,0.00,1.00 -1140,43.20,-62.40,1.00,0.00,1.00 -1141,52.80,-67.20,1.00,0.00,1.00 -1142,62.40,-72.00,1.00,0.00,1.00 -1143,76.80,-72.00,1.00,0.00,1.00 -1144,96.00,-72.00,1.00,0.00,1.00 -1145,110.40,-72.00,1.00,0.00,1.00 -1146,120.00,-67.20,1.00,0.00,1.00 -1147,134.40,-67.20,1.00,0.00,1.00 -1148,139.20,-62.40,1.00,0.00,1.00 -1149,148.80,-57.60,1.00,0.00,1.00 -1150,153.60,-57.60,1.00,0.00,1.00 -1151,158.40,-52.80,1.00,0.00,1.00 -1152,158.40,-48.00,1.00,0.00,1.00 -1153,163.20,-43.20,1.00,0.00,1.00 -1154,163.20,-38.40,1.00,0.00,1.00 -1155,168.00,-33.60,1.00,0.00,1.00 -1156,168.00,-28.80,1.00,0.00,1.00 -1157,172.80,-24.00,1.00,0.00,1.00 -1158,172.80,-19.20,1.00,0.00,1.00 -1159,172.80,-14.40,1.00,0.00,1.00 -1160,177.60,-9.60,1.00,0.00,1.00 -1161,177.60,-4.80,1.00,0.00,1.00 -1162,177.60,-0.00,1.00,0.00,1.00 -1163,-177.60,0.00,1.00,0.00,1.00 -1164,-177.60,4.80,1.00,0.00,1.00 -1165,-177.60,9.60,1.00,0.00,1.00 -1166,-172.80,14.40,1.00,0.00,1.00 -1167,-172.80,19.20,1.00,0.00,1.00 -1168,-172.80,24.00,1.00,0.00,1.00 -1169,-168.00,28.80,1.00,0.00,1.00 -1170,-168.00,33.60,1.00,0.00,1.00 -1171,-163.20,38.40,1.00,0.00,1.00 -1172,-163.20,43.20,1.00,0.00,1.00 -1173,-158.40,48.00,1.00,0.00,1.00 -1174,-158.40,52.80,1.00,0.00,1.00 -1175,-153.60,57.60,1.00,0.00,1.00 -1176,-148.80,57.60,1.00,0.00,1.00 -1177,-139.20,62.40,1.00,0.00,1.00 -1178,-134.40,67.20,1.00,0.00,1.00 -1179,-120.00,67.20,1.00,0.00,1.00 -1180,-110.40,72.00,1.00,0.00,1.00 -1181,-96.00,72.00,1.00,0.00,1.00 -1182,-76.80,72.00,1.00,0.00,1.00 -1183,-62.40,72.00,1.00,0.00,1.00 -1184,-52.80,67.20,1.00,0.00,1.00 -1185,-43.20,62.40,1.00,0.00,1.00 -1186,-38.40,62.40,1.00,0.00,1.00 -1187,-28.80,57.60,1.00,0.00,1.00 -1188,-24.00,52.80,1.00,0.00,1.00 -1189,-24.00,48.00,1.00,0.00,1.00 -1190,-19.20,43.20,1.00,0.00,1.00 -1191,-14.40,38.40,1.00,0.00,1.00 -1192,-14.40,38.40,1.00,0.00,1.00 -1193,-9.60,33.60,1.00,0.00,1.00 -1194,-9.60,28.80,1.00,0.00,1.00 -1195,-9.60,24.00,1.00,0.00,1.00 -1196,-4.80,19.20,1.00,0.00,1.00 -1197,-4.80,14.40,1.00,0.00,1.00 -1198,-4.80,9.60,1.00,0.00,1.00 -1199,-0.00,4.80,1.00,0.00,1.00 -1200,0.00,0.00,1.00,0.00,1.00 -1201,0.00,-4.80,1.00,0.00,1.00 -1202,0.00,-9.60,1.00,0.00,1.00 -1203,4.80,-14.40,1.00,0.00,1.00 -1204,4.80,-19.20,1.00,0.00,1.00 -1205,4.80,-24.00,1.00,0.00,1.00 -1206,4.80,-28.80,1.00,0.00,1.00 -1207,9.60,-33.60,1.00,0.00,1.00 -1208,9.60,-38.40,1.00,0.00,1.00 -1209,14.40,-43.20,1.00,0.00,1.00 -1210,14.40,-48.00,1.00,0.00,1.00 -1211,14.40,-52.80,1.00,0.00,1.00 -1212,19.20,-57.60,1.00,0.00,1.00 -1213,24.00,-57.60,1.00,0.00,1.00 -1214,28.80,-62.40,1.00,0.00,1.00 -1215,33.60,-67.20,1.00,0.00,1.00 -1216,43.20,-72.00,1.00,0.00,1.00 -1217,57.60,-72.00,1.00,0.00,1.00 -1218,76.80,-76.80,1.00,0.00,1.00 -1219,96.00,-76.80,1.00,0.00,1.00 -1220,115.20,-76.80,1.00,0.00,1.00 -1221,129.60,-72.00,1.00,0.00,1.00 -1222,139.20,-72.00,1.00,0.00,1.00 -1223,148.80,-67.20,1.00,0.00,1.00 -1224,153.60,-62.40,1.00,0.00,1.00 -1225,158.40,-57.60,1.00,0.00,1.00 -1226,163.20,-52.80,1.00,0.00,1.00 -1227,163.20,-48.00,1.00,0.00,1.00 -1228,168.00,-43.20,1.00,0.00,1.00 -1229,168.00,-38.40,1.00,0.00,1.00 -1230,172.80,-33.60,1.00,0.00,1.00 -1231,172.80,-28.80,1.00,0.00,1.00 -1232,172.80,-24.00,1.00,0.00,1.00 -1233,172.80,-19.20,1.00,0.00,1.00 -1234,177.60,-14.40,1.00,0.00,1.00 -1235,177.60,-9.60,1.00,0.00,1.00 -1236,177.60,-4.80,1.00,0.00,1.00 -1237,177.60,-0.00,1.00,0.00,1.00 -1238,-177.60,0.00,1.00,0.00,1.00 -1239,-177.60,4.80,1.00,0.00,1.00 -1240,-177.60,9.60,1.00,0.00,1.00 -1241,-177.60,14.40,1.00,0.00,1.00 -1242,-172.80,19.20,1.00,0.00,1.00 -1243,-172.80,24.00,1.00,0.00,1.00 -1244,-172.80,28.80,1.00,0.00,1.00 -1245,-172.80,33.60,1.00,0.00,1.00 -1246,-168.00,38.40,1.00,0.00,1.00 -1247,-168.00,43.20,1.00,0.00,1.00 -1248,-163.20,48.00,1.00,0.00,1.00 -1249,-163.20,52.80,1.00,0.00,1.00 -1250,-158.40,57.60,1.00,0.00,1.00 -1251,-153.60,62.40,1.00,0.00,1.00 -1252,-148.80,67.20,1.00,0.00,1.00 -1253,-139.20,72.00,1.00,0.00,1.00 -1254,-129.60,72.00,1.00,0.00,1.00 -1255,-115.20,76.80,1.00,0.00,1.00 -1256,-96.00,76.80,1.00,0.00,1.00 -1257,-76.80,76.80,1.00,0.00,1.00 -1258,-57.60,72.00,1.00,0.00,1.00 -1259,-43.20,72.00,1.00,0.00,1.00 -1260,-33.60,67.20,1.00,0.00,1.00 -1261,-28.80,62.40,1.00,0.00,1.00 -1262,-24.00,57.60,1.00,0.00,1.00 -1263,-19.20,57.60,1.00,0.00,1.00 -1264,-14.40,52.80,1.00,0.00,1.00 -1265,-14.40,48.00,1.00,0.00,1.00 -1266,-14.40,43.20,1.00,0.00,1.00 -1267,-9.60,38.40,1.00,0.00,1.00 -1268,-9.60,33.60,1.00,0.00,1.00 -1269,-4.80,28.80,1.00,0.00,1.00 -1270,-4.80,24.00,1.00,0.00,1.00 -1271,-4.80,19.20,1.00,0.00,1.00 -1272,-4.80,14.40,1.00,0.00,1.00 -1273,-0.00,9.60,1.00,0.00,1.00 -1274,-0.00,4.80,1.00,0.00,1.00 -1275,0.00,0.00,1.00,0.00,1.00 -1276,0.00,-4.80,1.00,0.00,1.00 -1277,0.00,-9.60,1.00,0.00,1.00 -1278,0.00,-14.40,1.00,0.00,1.00 -1279,4.80,-19.20,1.00,0.00,1.00 -1280,4.80,-24.00,1.00,0.00,1.00 -1281,4.80,-28.80,1.00,0.00,1.00 -1282,4.80,-33.60,1.00,0.00,1.00 -1283,4.80,-38.40,1.00,0.00,1.00 -1284,9.60,-43.20,1.00,0.00,1.00 -1285,9.60,-48.00,1.00,0.00,1.00 -1286,9.60,-52.80,1.00,0.00,1.00 -1287,14.40,-57.60,1.00,0.00,1.00 -1288,14.40,-62.40,1.00,0.00,1.00 -1289,19.20,-67.20,1.00,0.00,1.00 -1290,24.00,-72.00,1.00,0.00,1.00 -1291,33.60,-72.00,1.00,0.00,1.00 -1292,43.20,-76.80,1.00,0.00,1.00 -1293,67.20,-81.60,1.00,0.00,1.00 -1294,96.00,-81.60,1.00,0.00,1.00 -1295,124.80,-81.60,1.00,0.00,1.00 -1296,144.00,-76.80,1.00,0.00,1.00 -1297,153.60,-72.00,1.00,0.00,1.00 -1298,158.40,-67.20,1.00,0.00,1.00 -1299,163.20,-62.40,1.00,0.00,1.00 -1300,168.00,-57.60,1.00,0.00,1.00 -1301,168.00,-52.80,1.00,0.00,1.00 -1302,168.00,-48.00,1.00,0.00,1.00 -1303,172.80,-43.20,1.00,0.00,1.00 -1304,172.80,-38.40,1.00,0.00,1.00 -1305,172.80,-33.60,1.00,0.00,1.00 -1306,172.80,-28.80,1.00,0.00,1.00 -1307,177.60,-24.00,1.00,0.00,1.00 -1308,177.60,-19.20,1.00,0.00,1.00 -1309,177.60,-14.40,1.00,0.00,1.00 -1310,177.60,-9.60,1.00,0.00,1.00 -1311,177.60,-4.80,1.00,0.00,1.00 -1312,177.60,-0.00,1.00,0.00,1.00 -1313,-177.60,0.00,1.00,0.00,1.00 -1314,-177.60,4.80,1.00,0.00,1.00 -1315,-177.60,9.60,1.00,0.00,1.00 -1316,-177.60,14.40,1.00,0.00,1.00 -1317,-177.60,19.20,1.00,0.00,1.00 -1318,-177.60,24.00,1.00,0.00,1.00 -1319,-172.80,28.80,1.00,0.00,1.00 -1320,-172.80,33.60,1.00,0.00,1.00 -1321,-172.80,38.40,1.00,0.00,1.00 -1322,-172.80,43.20,1.00,0.00,1.00 -1323,-168.00,48.00,1.00,0.00,1.00 -1324,-168.00,52.80,1.00,0.00,1.00 -1325,-168.00,57.60,1.00,0.00,1.00 -1326,-163.20,62.40,1.00,0.00,1.00 -1327,-158.40,67.20,1.00,0.00,1.00 -1328,-153.60,72.00,1.00,0.00,1.00 -1329,-144.00,76.80,1.00,0.00,1.00 -1330,-124.80,81.60,1.00,0.00,1.00 -1331,-96.00,81.60,1.00,0.00,1.00 -1332,-67.20,81.60,1.00,0.00,1.00 -1333,-43.20,76.80,1.00,0.00,1.00 -1334,-33.60,72.00,1.00,0.00,1.00 -1335,-24.00,72.00,1.00,0.00,1.00 -1336,-19.20,67.20,1.00,0.00,1.00 -1337,-14.40,62.40,1.00,0.00,1.00 -1338,-14.40,57.60,1.00,0.00,1.00 -1339,-9.60,52.80,1.00,0.00,1.00 -1340,-9.60,48.00,1.00,0.00,1.00 -1341,-9.60,43.20,1.00,0.00,1.00 -1342,-4.80,38.40,1.00,0.00,1.00 -1343,-4.80,33.60,1.00,0.00,1.00 -1344,-4.80,28.80,1.00,0.00,1.00 -1345,-4.80,24.00,1.00,0.00,1.00 -1346,-4.80,19.20,1.00,0.00,1.00 -1347,-0.00,14.40,1.00,0.00,1.00 -1348,-0.00,9.60,1.00,0.00,1.00 -1349,-0.00,4.80,1.00,0.00,1.00 -1350,0.00,0.00,1.00,0.00,1.00 -1351,0.00,-4.80,1.00,0.00,1.00 -1352,0.00,-9.60,1.00,0.00,1.00 -1353,0.00,-14.40,1.00,0.00,1.00 -1354,0.00,-19.20,1.00,0.00,1.00 -1355,0.00,-24.00,1.00,0.00,1.00 -1356,0.00,-28.80,1.00,0.00,1.00 -1357,0.00,-33.60,1.00,0.00,1.00 -1358,4.80,-38.40,1.00,0.00,1.00 -1359,4.80,-43.20,1.00,0.00,1.00 -1360,4.80,-48.00,1.00,0.00,1.00 -1361,4.80,-52.80,1.00,0.00,1.00 -1362,4.80,-57.60,1.00,0.00,1.00 -1363,4.80,-62.40,1.00,0.00,1.00 -1364,9.60,-67.20,1.00,0.00,1.00 -1365,9.60,-72.00,1.00,0.00,1.00 -1366,14.40,-76.80,1.00,0.00,1.00 -1367,24.00,-81.60,1.00,0.00,1.00 -1368,43.20,-86.40,1.00,0.00,1.00 -1369,110.40,-86.40,1.00,0.00,1.00 -1370,148.80,-81.60,1.00,0.00,1.00 -1371,163.20,-76.80,1.00,0.00,1.00 -1372,168.00,-72.00,1.00,0.00,1.00 -1373,172.80,-67.20,1.00,0.00,1.00 -1374,172.80,-62.40,1.00,0.00,1.00 -1375,172.80,-57.60,1.00,0.00,1.00 -1376,172.80,-52.80,1.00,0.00,1.00 -1377,177.60,-48.00,1.00,0.00,1.00 -1378,177.60,-43.20,1.00,0.00,1.00 -1379,177.60,-38.40,1.00,0.00,1.00 -1380,177.60,-33.60,1.00,0.00,1.00 -1381,177.60,-28.80,1.00,0.00,1.00 -1382,177.60,-24.00,1.00,0.00,1.00 -1383,177.60,-19.20,1.00,0.00,1.00 -1384,177.60,-14.40,1.00,0.00,1.00 -1385,177.60,-9.60,1.00,0.00,1.00 -1386,177.60,-4.80,1.00,0.00,1.00 -1387,177.60,-0.00,1.00,0.00,1.00 -1388,-177.60,0.00,1.00,0.00,1.00 -1389,-177.60,4.80,1.00,0.00,1.00 -1390,-177.60,9.60,1.00,0.00,1.00 -1391,-177.60,14.40,1.00,0.00,1.00 -1392,-177.60,19.20,1.00,0.00,1.00 -1393,-177.60,24.00,1.00,0.00,1.00 -1394,-177.60,28.80,1.00,0.00,1.00 -1395,-177.60,33.60,1.00,0.00,1.00 -1396,-177.60,38.40,1.00,0.00,1.00 -1397,-177.60,43.20,1.00,0.00,1.00 -1398,-177.60,48.00,1.00,0.00,1.00 -1399,-172.80,52.80,1.00,0.00,1.00 -1400,-172.80,57.60,1.00,0.00,1.00 -1401,-172.80,62.40,1.00,0.00,1.00 -1402,-172.80,67.20,1.00,0.00,1.00 -1403,-168.00,72.00,1.00,0.00,1.00 -1404,-163.20,76.80,1.00,0.00,1.00 -1405,-148.80,81.60,1.00,0.00,1.00 -1406,-110.40,86.40,1.00,0.00,1.00 -1407,-43.20,86.40,1.00,0.00,1.00 -1408,-24.00,81.60,1.00,0.00,1.00 -1409,-14.40,76.80,1.00,0.00,1.00 -1410,-9.60,72.00,1.00,0.00,1.00 -1411,-9.60,67.20,1.00,0.00,1.00 -1412,-4.80,62.40,1.00,0.00,1.00 -1413,-4.80,57.60,1.00,0.00,1.00 -1414,-4.80,52.80,1.00,0.00,1.00 -1415,-4.80,48.00,1.00,0.00,1.00 -1416,-4.80,43.20,1.00,0.00,1.00 -1417,-4.80,38.40,1.00,0.00,1.00 -1418,-0.00,33.60,1.00,0.00,1.00 -1419,-0.00,28.80,1.00,0.00,1.00 -1420,-0.00,24.00,1.00,0.00,1.00 -1421,-0.00,19.20,1.00,0.00,1.00 -1422,-0.00,14.40,1.00,0.00,1.00 -1423,-0.00,9.60,1.00,0.00,1.00 -1424,-0.00,4.80,1.00,0.00,1.00 -1425,-0.00,0.00,1.00,0.00,1.00 -1426,-0.00,-4.80,1.00,0.00,1.00 -1427,-0.00,-9.60,1.00,0.00,1.00 -1428,-0.00,-14.40,1.00,0.00,1.00 -1429,-0.00,-19.20,1.00,0.00,1.00 -1430,-0.00,-24.00,1.00,0.00,1.00 -1431,-0.00,-28.80,1.00,0.00,1.00 -1432,-0.00,-33.60,1.00,0.00,1.00 -1433,-0.00,-38.40,1.00,0.00,1.00 -1434,-0.00,-43.20,1.00,0.00,1.00 -1435,-0.00,-48.00,1.00,0.00,1.00 -1436,-0.00,-52.80,1.00,0.00,1.00 -1437,-0.00,-57.60,1.00,0.00,1.00 -1438,-0.00,-62.40,1.00,0.00,1.00 -1439,-4.80,-67.20,1.00,0.00,1.00 -1440,-4.80,-72.00,1.00,0.00,1.00 -1441,-4.80,-76.80,1.00,0.00,1.00 -1442,-9.60,-81.60,1.00,0.00,1.00 -1443,-19.20,-86.40,1.00,0.00,1.00 -1444,-134.40,-86.40,1.00,0.00,1.00 -1445,-168.00,-81.60,1.00,0.00,1.00 -1446,-172.80,-76.80,1.00,0.00,1.00 -1447,-177.60,-72.00,1.00,0.00,1.00 -1448,-177.60,-67.20,1.00,0.00,1.00 -1449,-177.60,-62.40,1.00,0.00,1.00 -1450,-177.60,-57.60,1.00,0.00,1.00 -1451,-177.60,-52.80,1.00,0.00,1.00 -1452,-177.60,-48.00,1.00,0.00,1.00 -1453,-177.60,-43.20,1.00,0.00,1.00 -1454,-177.60,-38.40,1.00,0.00,1.00 -1455,-177.60,-33.60,1.00,0.00,1.00 -1456,-177.60,-28.80,1.00,0.00,1.00 -1457,-177.60,-24.00,1.00,0.00,1.00 -1458,-177.60,-19.20,1.00,0.00,1.00 -1459,-177.60,-14.40,1.00,0.00,1.00 -1460,-177.60,-9.60,1.00,0.00,1.00 -1461,-177.60,-4.80,1.00,0.00,1.00 -1462,-177.60,-0.00,1.00,0.00,1.00 -1463,177.60,0.00,1.00,0.00,1.00 -1464,177.60,4.80,1.00,0.00,1.00 -1465,177.60,9.60,1.00,0.00,1.00 -1466,177.60,14.40,1.00,0.00,1.00 -1467,177.60,19.20,1.00,0.00,1.00 -1468,177.60,24.00,1.00,0.00,1.00 -1469,177.60,28.80,1.00,0.00,1.00 -1470,177.60,33.60,1.00,0.00,1.00 -1471,177.60,38.40,1.00,0.00,1.00 -1472,177.60,43.20,1.00,0.00,1.00 -1473,177.60,48.00,1.00,0.00,1.00 -1474,177.60,52.80,1.00,0.00,1.00 -1475,177.60,57.60,1.00,0.00,1.00 -1476,177.60,62.40,1.00,0.00,1.00 -1477,177.60,67.20,1.00,0.00,1.00 -1478,177.60,72.00,1.00,0.00,1.00 -1479,172.80,76.80,1.00,0.00,1.00 -1480,168.00,81.60,1.00,0.00,1.00 -1481,134.40,86.40,1.00,0.00,1.00 -1482,19.20,86.40,1.00,0.00,1.00 -1483,9.60,81.60,1.00,0.00,1.00 -1484,4.80,76.80,1.00,0.00,1.00 -1485,4.80,72.00,1.00,0.00,1.00 -1486,4.80,67.20,1.00,0.00,1.00 -1487,0.00,62.40,1.00,0.00,1.00 -1488,0.00,57.60,1.00,0.00,1.00 -1489,0.00,52.80,1.00,0.00,1.00 -1490,0.00,48.00,1.00,0.00,1.00 -1491,0.00,43.20,1.00,0.00,1.00 -1492,0.00,38.40,1.00,0.00,1.00 -1493,0.00,33.60,1.00,0.00,1.00 -1494,0.00,28.80,1.00,0.00,1.00 -1495,0.00,24.00,1.00,0.00,1.00 -1496,0.00,19.20,1.00,0.00,1.00 -1497,0.00,14.40,1.00,0.00,1.00 -1498,0.00,9.60,1.00,0.00,1.00 -1499,0.00,4.80,1.00,0.00,1.00 diff --git a/tests/renderer/data/stvISM2.csv b/tests/renderer/data/stvISM2.csv deleted file mode 100644 index 9fd14fdf63..0000000000 --- a/tests/renderer/data/stvISM2.csv +++ /dev/null @@ -1,1500 +0,0 @@ -0,0.00,4.80,1.00,0.00,1.00 -1,0.00,9.60,1.00,0.00,1.00 -2,0.00,14.40,1.00,0.00,1.00 -3,0.00,19.20,1.00,0.00,1.00 -4,0.00,24.00,1.00,0.00,1.00 -5,0.00,28.80,1.00,0.00,1.00 -6,0.00,33.60,1.00,0.00,1.00 -7,0.00,38.40,1.00,0.00,1.00 -8,0.00,43.20,1.00,0.00,1.00 -9,0.00,48.00,1.00,0.00,1.00 -10,0.00,52.80,1.00,0.00,1.00 -11,0.00,57.60,1.00,0.00,1.00 -12,0.00,62.40,1.00,0.00,1.00 -13,4.80,67.20,1.00,0.00,1.00 -14,4.80,72.00,1.00,0.00,1.00 -15,4.80,76.80,1.00,0.00,1.00 -16,9.60,81.60,1.00,0.00,1.00 -17,19.20,86.40,1.00,0.00,1.00 -18,134.40,86.40,1.00,0.00,1.00 -19,168.00,81.60,1.00,0.00,1.00 -20,172.80,76.80,1.00,0.00,1.00 -21,177.60,72.00,1.00,0.00,1.00 -22,177.60,67.20,1.00,0.00,1.00 -23,177.60,62.40,1.00,0.00,1.00 -24,177.60,57.60,1.00,0.00,1.00 -25,177.60,52.80,1.00,0.00,1.00 -26,177.60,48.00,1.00,0.00,1.00 -27,177.60,43.20,1.00,0.00,1.00 -28,177.60,38.40,1.00,0.00,1.00 -29,177.60,33.60,1.00,0.00,1.00 -30,177.60,28.80,1.00,0.00,1.00 -31,177.60,24.00,1.00,0.00,1.00 -32,177.60,19.20,1.00,0.00,1.00 -33,177.60,14.40,1.00,0.00,1.00 -34,177.60,9.60,1.00,0.00,1.00 -35,177.60,4.80,1.00,0.00,1.00 -36,177.60,0.00,1.00,0.00,1.00 -37,-177.60,-0.00,1.00,0.00,1.00 -38,-177.60,-4.80,1.00,0.00,1.00 -39,-177.60,-9.60,1.00,0.00,1.00 -40,-177.60,-14.40,1.00,0.00,1.00 -41,-177.60,-19.20,1.00,0.00,1.00 -42,-177.60,-24.00,1.00,0.00,1.00 -43,-177.60,-28.80,1.00,0.00,1.00 -44,-177.60,-33.60,1.00,0.00,1.00 -45,-177.60,-38.40,1.00,0.00,1.00 -46,-177.60,-43.20,1.00,0.00,1.00 -47,-177.60,-48.00,1.00,0.00,1.00 -48,-177.60,-52.80,1.00,0.00,1.00 -49,-177.60,-57.60,1.00,0.00,1.00 -50,-177.60,-62.40,1.00,0.00,1.00 -51,-177.60,-67.20,1.00,0.00,1.00 -52,-177.60,-72.00,1.00,0.00,1.00 -53,-172.80,-76.80,1.00,0.00,1.00 -54,-168.00,-81.60,1.00,0.00,1.00 -55,-134.40,-86.40,1.00,0.00,1.00 -56,-19.20,-86.40,1.00,0.00,1.00 -57,-9.60,-81.60,1.00,0.00,1.00 -58,-4.80,-76.80,1.00,0.00,1.00 -59,-4.80,-72.00,1.00,0.00,1.00 -60,-4.80,-67.20,1.00,0.00,1.00 -61,-0.00,-62.40,1.00,0.00,1.00 -62,-0.00,-57.60,1.00,0.00,1.00 -63,-0.00,-52.80,1.00,0.00,1.00 -64,-0.00,-48.00,1.00,0.00,1.00 -65,-0.00,-43.20,1.00,0.00,1.00 -66,-0.00,-38.40,1.00,0.00,1.00 -67,-0.00,-33.60,1.00,0.00,1.00 -68,-0.00,-28.80,1.00,0.00,1.00 -69,-0.00,-24.00,1.00,0.00,1.00 -70,-0.00,-19.20,1.00,0.00,1.00 -71,-0.00,-14.40,1.00,0.00,1.00 -72,-0.00,-9.60,1.00,0.00,1.00 -73,-0.00,-4.80,1.00,0.00,1.00 -74,-0.00,0.00,1.00,0.00,1.00 -75,-0.00,4.80,1.00,0.00,1.00 -76,-0.00,9.60,1.00,0.00,1.00 -77,-0.00,14.40,1.00,0.00,1.00 -78,-0.00,19.20,1.00,0.00,1.00 -79,-0.00,24.00,1.00,0.00,1.00 -80,-0.00,28.80,1.00,0.00,1.00 -81,-0.00,33.60,1.00,0.00,1.00 -82,-4.80,38.40,1.00,0.00,1.00 -83,-4.80,43.20,1.00,0.00,1.00 -84,-4.80,48.00,1.00,0.00,1.00 -85,-4.80,52.80,1.00,0.00,1.00 -86,-4.80,57.60,1.00,0.00,1.00 -87,-4.80,62.40,1.00,0.00,1.00 -88,-9.60,67.20,1.00,0.00,1.00 -89,-9.60,72.00,1.00,0.00,1.00 -90,-14.40,76.80,1.00,0.00,1.00 -91,-24.00,81.60,1.00,0.00,1.00 -92,-43.20,86.40,1.00,0.00,1.00 -93,-110.40,86.40,1.00,0.00,1.00 -94,-148.80,81.60,1.00,0.00,1.00 -95,-163.20,76.80,1.00,0.00,1.00 -96,-168.00,72.00,1.00,0.00,1.00 -97,-172.80,67.20,1.00,0.00,1.00 -98,-172.80,62.40,1.00,0.00,1.00 -99,-172.80,57.60,1.00,0.00,1.00 -100,-172.80,52.80,1.00,0.00,1.00 -101,-177.60,48.00,1.00,0.00,1.00 -102,-177.60,43.20,1.00,0.00,1.00 -103,-177.60,38.40,1.00,0.00,1.00 -104,-177.60,33.60,1.00,0.00,1.00 -105,-177.60,28.80,1.00,0.00,1.00 -106,-177.60,24.00,1.00,0.00,1.00 -107,-177.60,19.20,1.00,0.00,1.00 -108,-177.60,14.40,1.00,0.00,1.00 -109,-177.60,9.60,1.00,0.00,1.00 -110,-177.60,4.80,1.00,0.00,1.00 -111,-177.60,0.00,1.00,0.00,1.00 -112,177.60,-0.00,1.00,0.00,1.00 -113,177.60,-4.80,1.00,0.00,1.00 -114,177.60,-9.60,1.00,0.00,1.00 -115,177.60,-14.40,1.00,0.00,1.00 -116,177.60,-19.20,1.00,0.00,1.00 -117,177.60,-24.00,1.00,0.00,1.00 -118,177.60,-28.80,1.00,0.00,1.00 -119,177.60,-33.60,1.00,0.00,1.00 -120,177.60,-38.40,1.00,0.00,1.00 -121,177.60,-43.20,1.00,0.00,1.00 -122,177.60,-48.00,1.00,0.00,1.00 -123,172.80,-52.80,1.00,0.00,1.00 -124,172.80,-57.60,1.00,0.00,1.00 -125,172.80,-62.40,1.00,0.00,1.00 -126,172.80,-67.20,1.00,0.00,1.00 -127,168.00,-72.00,1.00,0.00,1.00 -128,163.20,-76.80,1.00,0.00,1.00 -129,148.80,-81.60,1.00,0.00,1.00 -130,110.40,-86.40,1.00,0.00,1.00 -131,43.20,-86.40,1.00,0.00,1.00 -132,24.00,-81.60,1.00,0.00,1.00 -133,14.40,-76.80,1.00,0.00,1.00 -134,9.60,-72.00,1.00,0.00,1.00 -135,9.60,-67.20,1.00,0.00,1.00 -136,4.80,-62.40,1.00,0.00,1.00 -137,4.80,-57.60,1.00,0.00,1.00 -138,4.80,-52.80,1.00,0.00,1.00 -139,4.80,-48.00,1.00,0.00,1.00 -140,4.80,-43.20,1.00,0.00,1.00 -141,4.80,-38.40,1.00,0.00,1.00 -142,0.00,-33.60,1.00,0.00,1.00 -143,0.00,-28.80,1.00,0.00,1.00 -144,0.00,-24.00,1.00,0.00,1.00 -145,0.00,-19.20,1.00,0.00,1.00 -146,0.00,-14.40,1.00,0.00,1.00 -147,0.00,-9.60,1.00,0.00,1.00 -148,0.00,-4.80,1.00,0.00,1.00 -149,0.00,0.00,1.00,0.00,1.00 -150,-0.00,4.80,1.00,0.00,1.00 -151,-0.00,9.60,1.00,0.00,1.00 -152,-0.00,14.40,1.00,0.00,1.00 -153,-4.80,19.20,1.00,0.00,1.00 -154,-4.80,24.00,1.00,0.00,1.00 -155,-4.80,28.80,1.00,0.00,1.00 -156,-4.80,33.60,1.00,0.00,1.00 -157,-4.80,38.40,1.00,0.00,1.00 -158,-9.60,43.20,1.00,0.00,1.00 -159,-9.60,48.00,1.00,0.00,1.00 -160,-9.60,52.80,1.00,0.00,1.00 -161,-14.40,57.60,1.00,0.00,1.00 -162,-14.40,62.40,1.00,0.00,1.00 -163,-19.20,67.20,1.00,0.00,1.00 -164,-24.00,72.00,1.00,0.00,1.00 -165,-33.60,72.00,1.00,0.00,1.00 -166,-43.20,76.80,1.00,0.00,1.00 -167,-67.20,81.60,1.00,0.00,1.00 -168,-96.00,81.60,1.00,0.00,1.00 -169,-124.80,81.60,1.00,0.00,1.00 -170,-144.00,76.80,1.00,0.00,1.00 -171,-153.60,72.00,1.00,0.00,1.00 -172,-158.40,67.20,1.00,0.00,1.00 -173,-163.20,62.40,1.00,0.00,1.00 -174,-168.00,57.60,1.00,0.00,1.00 -175,-168.00,52.80,1.00,0.00,1.00 -176,-168.00,48.00,1.00,0.00,1.00 -177,-172.80,43.20,1.00,0.00,1.00 -178,-172.80,38.40,1.00,0.00,1.00 -179,-172.80,33.60,1.00,0.00,1.00 -180,-172.80,28.80,1.00,0.00,1.00 -181,-177.60,24.00,1.00,0.00,1.00 -182,-177.60,19.20,1.00,0.00,1.00 -183,-177.60,14.40,1.00,0.00,1.00 -184,-177.60,9.60,1.00,0.00,1.00 -185,-177.60,4.80,1.00,0.00,1.00 -186,-177.60,0.00,1.00,0.00,1.00 -187,177.60,-0.00,1.00,0.00,1.00 -188,177.60,-4.80,1.00,0.00,1.00 -189,177.60,-9.60,1.00,0.00,1.00 -190,177.60,-14.40,1.00,0.00,1.00 -191,177.60,-19.20,1.00,0.00,1.00 -192,177.60,-24.00,1.00,0.00,1.00 -193,172.80,-28.80,1.00,0.00,1.00 -194,172.80,-33.60,1.00,0.00,1.00 -195,172.80,-38.40,1.00,0.00,1.00 -196,172.80,-43.20,1.00,0.00,1.00 -197,168.00,-48.00,1.00,0.00,1.00 -198,168.00,-52.80,1.00,0.00,1.00 -199,168.00,-57.60,1.00,0.00,1.00 -200,163.20,-62.40,1.00,0.00,1.00 -201,158.40,-67.20,1.00,0.00,1.00 -202,153.60,-72.00,1.00,0.00,1.00 -203,144.00,-76.80,1.00,0.00,1.00 -204,124.80,-81.60,1.00,0.00,1.00 -205,96.00,-81.60,1.00,0.00,1.00 -206,67.20,-81.60,1.00,0.00,1.00 -207,43.20,-76.80,1.00,0.00,1.00 -208,33.60,-72.00,1.00,0.00,1.00 -209,24.00,-72.00,1.00,0.00,1.00 -210,19.20,-67.20,1.00,0.00,1.00 -211,14.40,-62.40,1.00,0.00,1.00 -212,14.40,-57.60,1.00,0.00,1.00 -213,9.60,-52.80,1.00,0.00,1.00 -214,9.60,-48.00,1.00,0.00,1.00 -215,9.60,-43.20,1.00,0.00,1.00 -216,4.80,-38.40,1.00,0.00,1.00 -217,4.80,-33.60,1.00,0.00,1.00 -218,4.80,-28.80,1.00,0.00,1.00 -219,4.80,-24.00,1.00,0.00,1.00 -220,4.80,-19.20,1.00,0.00,1.00 -221,0.00,-14.40,1.00,0.00,1.00 -222,0.00,-9.60,1.00,0.00,1.00 -223,0.00,-4.80,1.00,0.00,1.00 -224,0.00,0.00,1.00,0.00,1.00 -225,-0.00,4.80,1.00,0.00,1.00 -226,-0.00,9.60,1.00,0.00,1.00 -227,-4.80,14.40,1.00,0.00,1.00 -228,-4.80,19.20,1.00,0.00,1.00 -229,-4.80,24.00,1.00,0.00,1.00 -230,-4.80,28.80,1.00,0.00,1.00 -231,-9.60,33.60,1.00,0.00,1.00 -232,-9.60,38.40,1.00,0.00,1.00 -233,-14.40,43.20,1.00,0.00,1.00 -234,-14.40,48.00,1.00,0.00,1.00 -235,-14.40,52.80,1.00,0.00,1.00 -236,-19.20,57.60,1.00,0.00,1.00 -237,-24.00,57.60,1.00,0.00,1.00 -238,-28.80,62.40,1.00,0.00,1.00 -239,-33.60,67.20,1.00,0.00,1.00 -240,-43.20,72.00,1.00,0.00,1.00 -241,-57.60,72.00,1.00,0.00,1.00 -242,-76.80,76.80,1.00,0.00,1.00 -243,-96.00,76.80,1.00,0.00,1.00 -244,-115.20,76.80,1.00,0.00,1.00 -245,-129.60,72.00,1.00,0.00,1.00 -246,-139.20,72.00,1.00,0.00,1.00 -247,-148.80,67.20,1.00,0.00,1.00 -248,-153.60,62.40,1.00,0.00,1.00 -249,-158.40,57.60,1.00,0.00,1.00 -250,-163.20,52.80,1.00,0.00,1.00 -251,-163.20,48.00,1.00,0.00,1.00 -252,-168.00,43.20,1.00,0.00,1.00 -253,-168.00,38.40,1.00,0.00,1.00 -254,-172.80,33.60,1.00,0.00,1.00 -255,-172.80,28.80,1.00,0.00,1.00 -256,-172.80,24.00,1.00,0.00,1.00 -257,-172.80,19.20,1.00,0.00,1.00 -258,-177.60,14.40,1.00,0.00,1.00 -259,-177.60,9.60,1.00,0.00,1.00 -260,-177.60,4.80,1.00,0.00,1.00 -261,-177.60,0.00,1.00,0.00,1.00 -262,177.60,-0.00,1.00,0.00,1.00 -263,177.60,-4.80,1.00,0.00,1.00 -264,177.60,-9.60,1.00,0.00,1.00 -265,177.60,-14.40,1.00,0.00,1.00 -266,172.80,-19.20,1.00,0.00,1.00 -267,172.80,-24.00,1.00,0.00,1.00 -268,172.80,-28.80,1.00,0.00,1.00 -269,172.80,-33.60,1.00,0.00,1.00 -270,168.00,-38.40,1.00,0.00,1.00 -271,168.00,-43.20,1.00,0.00,1.00 -272,163.20,-48.00,1.00,0.00,1.00 -273,163.20,-52.80,1.00,0.00,1.00 -274,158.40,-57.60,1.00,0.00,1.00 -275,153.60,-62.40,1.00,0.00,1.00 -276,148.80,-67.20,1.00,0.00,1.00 -277,139.20,-72.00,1.00,0.00,1.00 -278,129.60,-72.00,1.00,0.00,1.00 -279,115.20,-76.80,1.00,0.00,1.00 -280,96.00,-76.80,1.00,0.00,1.00 -281,76.80,-76.80,1.00,0.00,1.00 -282,57.60,-72.00,1.00,0.00,1.00 -283,43.20,-72.00,1.00,0.00,1.00 -284,33.60,-67.20,1.00,0.00,1.00 -285,28.80,-62.40,1.00,0.00,1.00 -286,24.00,-57.60,1.00,0.00,1.00 -287,19.20,-57.60,1.00,0.00,1.00 -288,14.40,-52.80,1.00,0.00,1.00 -289,14.40,-48.00,1.00,0.00,1.00 -290,14.40,-43.20,1.00,0.00,1.00 -291,9.60,-38.40,1.00,0.00,1.00 -292,9.60,-33.60,1.00,0.00,1.00 -293,4.80,-28.80,1.00,0.00,1.00 -294,4.80,-24.00,1.00,0.00,1.00 -295,4.80,-19.20,1.00,0.00,1.00 -296,4.80,-14.40,1.00,0.00,1.00 -297,0.00,-9.60,1.00,0.00,1.00 -298,0.00,-4.80,1.00,0.00,1.00 -299,0.00,0.00,1.00,0.00,1.00 -300,-0.00,4.80,1.00,0.00,1.00 -301,-4.80,9.60,1.00,0.00,1.00 -302,-4.80,14.40,1.00,0.00,1.00 -303,-4.80,19.20,1.00,0.00,1.00 -304,-9.60,24.00,1.00,0.00,1.00 -305,-9.60,28.80,1.00,0.00,1.00 -306,-9.60,33.60,1.00,0.00,1.00 -307,-14.40,38.40,1.00,0.00,1.00 -308,-14.40,38.40,1.00,0.00,1.00 -309,-19.20,43.20,1.00,0.00,1.00 -310,-24.00,48.00,1.00,0.00,1.00 -311,-24.00,52.80,1.00,0.00,1.00 -312,-28.80,57.60,1.00,0.00,1.00 -313,-38.40,62.40,1.00,0.00,1.00 -314,-43.20,62.40,1.00,0.00,1.00 -315,-52.80,67.20,1.00,0.00,1.00 -316,-62.40,72.00,1.00,0.00,1.00 -317,-76.80,72.00,1.00,0.00,1.00 -318,-96.00,72.00,1.00,0.00,1.00 -319,-110.40,72.00,1.00,0.00,1.00 -320,-120.00,67.20,1.00,0.00,1.00 -321,-134.40,67.20,1.00,0.00,1.00 -322,-139.20,62.40,1.00,0.00,1.00 -323,-148.80,57.60,1.00,0.00,1.00 -324,-153.60,57.60,1.00,0.00,1.00 -325,-158.40,52.80,1.00,0.00,1.00 -326,-158.40,48.00,1.00,0.00,1.00 -327,-163.20,43.20,1.00,0.00,1.00 -328,-163.20,38.40,1.00,0.00,1.00 -329,-168.00,33.60,1.00,0.00,1.00 -330,-168.00,28.80,1.00,0.00,1.00 -331,-172.80,24.00,1.00,0.00,1.00 -332,-172.80,19.20,1.00,0.00,1.00 -333,-172.80,14.40,1.00,0.00,1.00 -334,-177.60,9.60,1.00,0.00,1.00 -335,-177.60,4.80,1.00,0.00,1.00 -336,-177.60,0.00,1.00,0.00,1.00 -337,177.60,-0.00,1.00,0.00,1.00 -338,177.60,-4.80,1.00,0.00,1.00 -339,177.60,-9.60,1.00,0.00,1.00 -340,172.80,-14.40,1.00,0.00,1.00 -341,172.80,-19.20,1.00,0.00,1.00 -342,172.80,-24.00,1.00,0.00,1.00 -343,168.00,-28.80,1.00,0.00,1.00 -344,168.00,-33.60,1.00,0.00,1.00 -345,163.20,-38.40,1.00,0.00,1.00 -346,163.20,-43.20,1.00,0.00,1.00 -347,158.40,-48.00,1.00,0.00,1.00 -348,158.40,-52.80,1.00,0.00,1.00 -349,153.60,-57.60,1.00,0.00,1.00 -350,148.80,-57.60,1.00,0.00,1.00 -351,139.20,-62.40,1.00,0.00,1.00 -352,134.40,-67.20,1.00,0.00,1.00 -353,120.00,-67.20,1.00,0.00,1.00 -354,110.40,-72.00,1.00,0.00,1.00 -355,96.00,-72.00,1.00,0.00,1.00 -356,76.80,-72.00,1.00,0.00,1.00 -357,62.40,-72.00,1.00,0.00,1.00 -358,52.80,-67.20,1.00,0.00,1.00 -359,43.20,-62.40,1.00,0.00,1.00 -360,38.40,-62.40,1.00,0.00,1.00 -361,28.80,-57.60,1.00,0.00,1.00 -362,24.00,-52.80,1.00,0.00,1.00 -363,24.00,-48.00,1.00,0.00,1.00 -364,19.20,-43.20,1.00,0.00,1.00 -365,14.40,-38.40,1.00,0.00,1.00 -366,14.40,-38.40,1.00,0.00,1.00 -367,9.60,-33.60,1.00,0.00,1.00 -368,9.60,-28.80,1.00,0.00,1.00 -369,9.60,-24.00,1.00,0.00,1.00 -370,4.80,-19.20,1.00,0.00,1.00 -371,4.80,-14.40,1.00,0.00,1.00 -372,4.80,-9.60,1.00,0.00,1.00 -373,0.00,-4.80,1.00,0.00,1.00 -374,0.00,0.00,1.00,0.00,1.00 -375,-0.00,4.80,1.00,0.00,1.00 -376,-4.80,9.60,1.00,0.00,1.00 -377,-4.80,14.40,1.00,0.00,1.00 -378,-9.60,19.20,1.00,0.00,1.00 -379,-9.60,24.00,1.00,0.00,1.00 -380,-14.40,24.00,1.00,0.00,1.00 -381,-14.40,28.80,1.00,0.00,1.00 -382,-19.20,33.60,1.00,0.00,1.00 -383,-19.20,38.40,1.00,0.00,1.00 -384,-24.00,43.20,1.00,0.00,1.00 -385,-28.80,48.00,1.00,0.00,1.00 -386,-33.60,52.80,1.00,0.00,1.00 -387,-38.40,52.80,1.00,0.00,1.00 -388,-43.20,57.60,1.00,0.00,1.00 -389,-48.00,62.40,1.00,0.00,1.00 -390,-57.60,62.40,1.00,0.00,1.00 -391,-67.20,67.20,1.00,0.00,1.00 -392,-81.60,67.20,1.00,0.00,1.00 -393,-91.20,67.20,1.00,0.00,1.00 -394,-105.60,67.20,1.00,0.00,1.00 -395,-115.20,67.20,1.00,0.00,1.00 -396,-124.80,62.40,1.00,0.00,1.00 -397,-134.40,57.60,1.00,0.00,1.00 -398,-139.20,57.60,1.00,0.00,1.00 -399,-144.00,52.80,1.00,0.00,1.00 -400,-148.80,48.00,1.00,0.00,1.00 -401,-153.60,43.20,1.00,0.00,1.00 -402,-158.40,43.20,1.00,0.00,1.00 -403,-163.20,38.40,1.00,0.00,1.00 -404,-163.20,33.60,1.00,0.00,1.00 -405,-168.00,28.80,1.00,0.00,1.00 -406,-168.00,24.00,1.00,0.00,1.00 -407,-172.80,19.20,1.00,0.00,1.00 -408,-172.80,14.40,1.00,0.00,1.00 -409,-177.60,9.60,1.00,0.00,1.00 -410,-177.60,4.80,1.00,0.00,1.00 -411,-177.60,0.00,1.00,0.00,1.00 -412,177.60,-0.00,1.00,0.00,1.00 -413,177.60,-4.80,1.00,0.00,1.00 -414,177.60,-9.60,1.00,0.00,1.00 -415,172.80,-14.40,1.00,0.00,1.00 -416,172.80,-19.20,1.00,0.00,1.00 -417,168.00,-24.00,1.00,0.00,1.00 -418,168.00,-28.80,1.00,0.00,1.00 -419,163.20,-33.60,1.00,0.00,1.00 -420,163.20,-38.40,1.00,0.00,1.00 -421,158.40,-43.20,1.00,0.00,1.00 -422,153.60,-43.20,1.00,0.00,1.00 -423,148.80,-48.00,1.00,0.00,1.00 -424,144.00,-52.80,1.00,0.00,1.00 -425,139.20,-57.60,1.00,0.00,1.00 -426,134.40,-57.60,1.00,0.00,1.00 -427,124.80,-62.40,1.00,0.00,1.00 -428,115.20,-67.20,1.00,0.00,1.00 -429,105.60,-67.20,1.00,0.00,1.00 -430,91.20,-67.20,1.00,0.00,1.00 -431,81.60,-67.20,1.00,0.00,1.00 -432,67.20,-67.20,1.00,0.00,1.00 -433,57.60,-62.40,1.00,0.00,1.00 -434,48.00,-62.40,1.00,0.00,1.00 -435,43.20,-57.60,1.00,0.00,1.00 -436,38.40,-52.80,1.00,0.00,1.00 -437,33.60,-52.80,1.00,0.00,1.00 -438,28.80,-48.00,1.00,0.00,1.00 -439,24.00,-43.20,1.00,0.00,1.00 -440,19.20,-38.40,1.00,0.00,1.00 -441,19.20,-33.60,1.00,0.00,1.00 -442,14.40,-28.80,1.00,0.00,1.00 -443,14.40,-24.00,1.00,0.00,1.00 -444,9.60,-24.00,1.00,0.00,1.00 -445,9.60,-19.20,1.00,0.00,1.00 -446,4.80,-14.40,1.00,0.00,1.00 -447,4.80,-9.60,1.00,0.00,1.00 -448,0.00,-4.80,1.00,0.00,1.00 -449,0.00,0.00,1.00,0.00,1.00 -450,-0.00,4.80,1.00,0.00,1.00 -451,-4.80,9.60,1.00,0.00,1.00 -452,-4.80,14.40,1.00,0.00,1.00 -453,-9.60,19.20,1.00,0.00,1.00 -454,-9.60,19.20,1.00,0.00,1.00 -455,-14.40,24.00,1.00,0.00,1.00 -456,-19.20,28.80,1.00,0.00,1.00 -457,-19.20,33.60,1.00,0.00,1.00 -458,-24.00,38.40,1.00,0.00,1.00 -459,-28.80,43.20,1.00,0.00,1.00 -460,-33.60,43.20,1.00,0.00,1.00 -461,-38.40,48.00,1.00,0.00,1.00 -462,-43.20,52.80,1.00,0.00,1.00 -463,-48.00,52.80,1.00,0.00,1.00 -464,-52.80,57.60,1.00,0.00,1.00 -465,-62.40,57.60,1.00,0.00,1.00 -466,-72.00,62.40,1.00,0.00,1.00 -467,-81.60,62.40,1.00,0.00,1.00 -468,-91.20,62.40,1.00,0.00,1.00 -469,-100.80,62.40,1.00,0.00,1.00 -470,-110.40,62.40,1.00,0.00,1.00 -471,-120.00,57.60,1.00,0.00,1.00 -472,-129.60,57.60,1.00,0.00,1.00 -473,-134.40,52.80,1.00,0.00,1.00 -474,-139.20,48.00,1.00,0.00,1.00 -475,-144.00,48.00,1.00,0.00,1.00 -476,-148.80,43.20,1.00,0.00,1.00 -477,-153.60,38.40,1.00,0.00,1.00 -478,-158.40,33.60,1.00,0.00,1.00 -479,-163.20,33.60,1.00,0.00,1.00 -480,-163.20,28.80,1.00,0.00,1.00 -481,-168.00,24.00,1.00,0.00,1.00 -482,-168.00,19.20,1.00,0.00,1.00 -483,-172.80,14.40,1.00,0.00,1.00 -484,-172.80,9.60,1.00,0.00,1.00 -485,-177.60,4.80,1.00,0.00,1.00 -486,-177.60,0.00,1.00,0.00,1.00 -487,177.60,-0.00,1.00,0.00,1.00 -488,177.60,-4.80,1.00,0.00,1.00 -489,172.80,-9.60,1.00,0.00,1.00 -490,172.80,-14.40,1.00,0.00,1.00 -491,168.00,-19.20,1.00,0.00,1.00 -492,168.00,-24.00,1.00,0.00,1.00 -493,163.20,-28.80,1.00,0.00,1.00 -494,163.20,-33.60,1.00,0.00,1.00 -495,158.40,-33.60,1.00,0.00,1.00 -496,153.60,-38.40,1.00,0.00,1.00 -497,148.80,-43.20,1.00,0.00,1.00 -498,144.00,-48.00,1.00,0.00,1.00 -499,139.20,-48.00,1.00,0.00,1.00 -500,134.40,-52.80,1.00,0.00,1.00 -501,129.60,-57.60,1.00,0.00,1.00 -502,120.00,-57.60,1.00,0.00,1.00 -503,110.40,-62.40,1.00,0.00,1.00 -504,100.80,-62.40,1.00,0.00,1.00 -505,91.20,-62.40,1.00,0.00,1.00 -506,81.60,-62.40,1.00,0.00,1.00 -507,72.00,-62.40,1.00,0.00,1.00 -508,62.40,-57.60,1.00,0.00,1.00 -509,52.80,-57.60,1.00,0.00,1.00 -510,48.00,-52.80,1.00,0.00,1.00 -511,43.20,-52.80,1.00,0.00,1.00 -512,38.40,-48.00,1.00,0.00,1.00 -513,33.60,-43.20,1.00,0.00,1.00 -514,28.80,-43.20,1.00,0.00,1.00 -515,24.00,-38.40,1.00,0.00,1.00 -516,19.20,-33.60,1.00,0.00,1.00 -517,19.20,-28.80,1.00,0.00,1.00 -518,14.40,-24.00,1.00,0.00,1.00 -519,9.60,-19.20,1.00,0.00,1.00 -520,9.60,-19.20,1.00,0.00,1.00 -521,4.80,-14.40,1.00,0.00,1.00 -522,4.80,-9.60,1.00,0.00,1.00 -523,0.00,-4.80,1.00,0.00,1.00 -524,0.00,0.00,1.00,0.00,1.00 -525,-4.80,4.80,1.00,0.00,1.00 -526,-4.80,9.60,1.00,0.00,1.00 -527,-9.60,14.40,1.00,0.00,1.00 -528,-9.60,14.40,1.00,0.00,1.00 -529,-14.40,19.20,1.00,0.00,1.00 -530,-14.40,24.00,1.00,0.00,1.00 -531,-19.20,28.80,1.00,0.00,1.00 -532,-24.00,33.60,1.00,0.00,1.00 -533,-28.80,33.60,1.00,0.00,1.00 -534,-28.80,38.40,1.00,0.00,1.00 -535,-33.60,43.20,1.00,0.00,1.00 -536,-38.40,43.20,1.00,0.00,1.00 -537,-48.00,48.00,1.00,0.00,1.00 -538,-52.80,52.80,1.00,0.00,1.00 -539,-57.60,52.80,1.00,0.00,1.00 -540,-67.20,57.60,1.00,0.00,1.00 -541,-76.80,57.60,1.00,0.00,1.00 -542,-81.60,57.60,1.00,0.00,1.00 -543,-91.20,57.60,1.00,0.00,1.00 -544,-100.80,57.60,1.00,0.00,1.00 -545,-110.40,57.60,1.00,0.00,1.00 -546,-115.20,52.80,1.00,0.00,1.00 -547,-124.80,52.80,1.00,0.00,1.00 -548,-129.60,48.00,1.00,0.00,1.00 -549,-139.20,48.00,1.00,0.00,1.00 -550,-144.00,43.20,1.00,0.00,1.00 -551,-148.80,38.40,1.00,0.00,1.00 -552,-153.60,38.40,1.00,0.00,1.00 -553,-153.60,33.60,1.00,0.00,1.00 -554,-158.40,28.80,1.00,0.00,1.00 -555,-163.20,24.00,1.00,0.00,1.00 -556,-163.20,24.00,1.00,0.00,1.00 -557,-168.00,19.20,1.00,0.00,1.00 -558,-172.80,14.40,1.00,0.00,1.00 -559,-172.80,9.60,1.00,0.00,1.00 -560,-177.60,4.80,1.00,0.00,1.00 -561,-177.60,0.00,1.00,0.00,1.00 -562,177.60,-0.00,1.00,0.00,1.00 -563,177.60,-4.80,1.00,0.00,1.00 -564,172.80,-9.60,1.00,0.00,1.00 -565,172.80,-14.40,1.00,0.00,1.00 -566,168.00,-19.20,1.00,0.00,1.00 -567,163.20,-24.00,1.00,0.00,1.00 -568,163.20,-24.00,1.00,0.00,1.00 -569,158.40,-28.80,1.00,0.00,1.00 -570,153.60,-33.60,1.00,0.00,1.00 -571,153.60,-38.40,1.00,0.00,1.00 -572,148.80,-38.40,1.00,0.00,1.00 -573,144.00,-43.20,1.00,0.00,1.00 -574,139.20,-48.00,1.00,0.00,1.00 -575,129.60,-48.00,1.00,0.00,1.00 -576,124.80,-52.80,1.00,0.00,1.00 -577,115.20,-52.80,1.00,0.00,1.00 -578,110.40,-57.60,1.00,0.00,1.00 -579,100.80,-57.60,1.00,0.00,1.00 -580,91.20,-57.60,1.00,0.00,1.00 -581,81.60,-57.60,1.00,0.00,1.00 -582,76.80,-57.60,1.00,0.00,1.00 -583,67.20,-57.60,1.00,0.00,1.00 -584,57.60,-52.80,1.00,0.00,1.00 -585,52.80,-52.80,1.00,0.00,1.00 -586,48.00,-48.00,1.00,0.00,1.00 -587,38.40,-43.20,1.00,0.00,1.00 -588,33.60,-43.20,1.00,0.00,1.00 -589,28.80,-38.40,1.00,0.00,1.00 -590,28.80,-33.60,1.00,0.00,1.00 -591,24.00,-33.60,1.00,0.00,1.00 -592,19.20,-28.80,1.00,0.00,1.00 -593,14.40,-24.00,1.00,0.00,1.00 -594,14.40,-19.20,1.00,0.00,1.00 -595,9.60,-14.40,1.00,0.00,1.00 -596,9.60,-14.40,1.00,0.00,1.00 -597,4.80,-9.60,1.00,0.00,1.00 -598,4.80,-4.80,1.00,0.00,1.00 -599,0.00,0.00,1.00,0.00,1.00 -600,-4.80,4.80,1.00,0.00,1.00 -601,-4.80,9.60,1.00,0.00,1.00 -602,-9.60,9.60,1.00,0.00,1.00 -603,-9.60,14.40,1.00,0.00,1.00 -604,-14.40,19.20,1.00,0.00,1.00 -605,-19.20,24.00,1.00,0.00,1.00 -606,-24.00,24.00,1.00,0.00,1.00 -607,-24.00,28.80,1.00,0.00,1.00 -608,-28.80,33.60,1.00,0.00,1.00 -609,-33.60,38.40,1.00,0.00,1.00 -610,-38.40,38.40,1.00,0.00,1.00 -611,-43.20,43.20,1.00,0.00,1.00 -612,-48.00,43.20,1.00,0.00,1.00 -613,-52.80,48.00,1.00,0.00,1.00 -614,-62.40,48.00,1.00,0.00,1.00 -615,-67.20,52.80,1.00,0.00,1.00 -616,-76.80,52.80,1.00,0.00,1.00 -617,-86.40,52.80,1.00,0.00,1.00 -618,-91.20,52.80,1.00,0.00,1.00 -619,-100.80,52.80,1.00,0.00,1.00 -620,-105.60,52.80,1.00,0.00,1.00 -621,-115.20,48.00,1.00,0.00,1.00 -622,-120.00,48.00,1.00,0.00,1.00 -623,-129.60,48.00,1.00,0.00,1.00 -624,-134.40,43.20,1.00,0.00,1.00 -625,-139.20,43.20,1.00,0.00,1.00 -626,-144.00,38.40,1.00,0.00,1.00 -627,-148.80,33.60,1.00,0.00,1.00 -628,-153.60,33.60,1.00,0.00,1.00 -629,-158.40,28.80,1.00,0.00,1.00 -630,-158.40,24.00,1.00,0.00,1.00 -631,-163.20,19.20,1.00,0.00,1.00 -632,-168.00,19.20,1.00,0.00,1.00 -633,-168.00,14.40,1.00,0.00,1.00 -634,-172.80,9.60,1.00,0.00,1.00 -635,-177.60,4.80,1.00,0.00,1.00 -636,-177.60,0.00,1.00,0.00,1.00 -637,177.60,-0.00,1.00,0.00,1.00 -638,177.60,-4.80,1.00,0.00,1.00 -639,172.80,-9.60,1.00,0.00,1.00 -640,168.00,-14.40,1.00,0.00,1.00 -641,168.00,-19.20,1.00,0.00,1.00 -642,163.20,-19.20,1.00,0.00,1.00 -643,158.40,-24.00,1.00,0.00,1.00 -644,158.40,-28.80,1.00,0.00,1.00 -645,153.60,-33.60,1.00,0.00,1.00 -646,148.80,-33.60,1.00,0.00,1.00 -647,144.00,-38.40,1.00,0.00,1.00 -648,139.20,-43.20,1.00,0.00,1.00 -649,134.40,-43.20,1.00,0.00,1.00 -650,129.60,-48.00,1.00,0.00,1.00 -651,120.00,-48.00,1.00,0.00,1.00 -652,115.20,-48.00,1.00,0.00,1.00 -653,105.60,-52.80,1.00,0.00,1.00 -654,100.80,-52.80,1.00,0.00,1.00 -655,91.20,-52.80,1.00,0.00,1.00 -656,86.40,-52.80,1.00,0.00,1.00 -657,76.80,-52.80,1.00,0.00,1.00 -658,67.20,-52.80,1.00,0.00,1.00 -659,62.40,-48.00,1.00,0.00,1.00 -660,52.80,-48.00,1.00,0.00,1.00 -661,48.00,-43.20,1.00,0.00,1.00 -662,43.20,-43.20,1.00,0.00,1.00 -663,38.40,-38.40,1.00,0.00,1.00 -664,33.60,-38.40,1.00,0.00,1.00 -665,28.80,-33.60,1.00,0.00,1.00 -666,24.00,-28.80,1.00,0.00,1.00 -667,24.00,-24.00,1.00,0.00,1.00 -668,19.20,-24.00,1.00,0.00,1.00 -669,14.40,-19.20,1.00,0.00,1.00 -670,9.60,-14.40,1.00,0.00,1.00 -671,9.60,-9.60,1.00,0.00,1.00 -672,4.80,-9.60,1.00,0.00,1.00 -673,4.80,-4.80,1.00,0.00,1.00 -674,0.00,0.00,1.00,0.00,1.00 -675,-4.80,4.80,1.00,0.00,1.00 -676,-4.80,4.80,1.00,0.00,1.00 -677,-9.60,9.60,1.00,0.00,1.00 -678,-14.40,14.40,1.00,0.00,1.00 -679,-14.40,19.20,1.00,0.00,1.00 -680,-19.20,19.20,1.00,0.00,1.00 -681,-24.00,24.00,1.00,0.00,1.00 -682,-28.80,28.80,1.00,0.00,1.00 -683,-33.60,28.80,1.00,0.00,1.00 -684,-38.40,33.60,1.00,0.00,1.00 -685,-43.20,38.40,1.00,0.00,1.00 -686,-48.00,38.40,1.00,0.00,1.00 -687,-52.80,43.20,1.00,0.00,1.00 -688,-57.60,43.20,1.00,0.00,1.00 -689,-62.40,43.20,1.00,0.00,1.00 -690,-72.00,48.00,1.00,0.00,1.00 -691,-76.80,48.00,1.00,0.00,1.00 -692,-86.40,48.00,1.00,0.00,1.00 -693,-91.20,48.00,1.00,0.00,1.00 -694,-100.80,48.00,1.00,0.00,1.00 -695,-105.60,48.00,1.00,0.00,1.00 -696,-110.40,48.00,1.00,0.00,1.00 -697,-120.00,43.20,1.00,0.00,1.00 -698,-124.80,43.20,1.00,0.00,1.00 -699,-129.60,38.40,1.00,0.00,1.00 -700,-134.40,38.40,1.00,0.00,1.00 -701,-139.20,33.60,1.00,0.00,1.00 -702,-144.00,33.60,1.00,0.00,1.00 -703,-148.80,28.80,1.00,0.00,1.00 -704,-153.60,24.00,1.00,0.00,1.00 -705,-158.40,24.00,1.00,0.00,1.00 -706,-163.20,19.20,1.00,0.00,1.00 -707,-163.20,14.40,1.00,0.00,1.00 -708,-168.00,14.40,1.00,0.00,1.00 -709,-172.80,9.60,1.00,0.00,1.00 -710,-172.80,4.80,1.00,0.00,1.00 -711,-177.60,0.00,1.00,0.00,1.00 -712,177.60,-0.00,1.00,0.00,1.00 -713,172.80,-4.80,1.00,0.00,1.00 -714,172.80,-9.60,1.00,0.00,1.00 -715,168.00,-14.40,1.00,0.00,1.00 -716,163.20,-14.40,1.00,0.00,1.00 -717,163.20,-19.20,1.00,0.00,1.00 -718,158.40,-24.00,1.00,0.00,1.00 -719,153.60,-24.00,1.00,0.00,1.00 -720,148.80,-28.80,1.00,0.00,1.00 -721,144.00,-33.60,1.00,0.00,1.00 -722,139.20,-33.60,1.00,0.00,1.00 -723,134.40,-38.40,1.00,0.00,1.00 -724,129.60,-38.40,1.00,0.00,1.00 -725,124.80,-43.20,1.00,0.00,1.00 -726,120.00,-43.20,1.00,0.00,1.00 -727,110.40,-48.00,1.00,0.00,1.00 -728,105.60,-48.00,1.00,0.00,1.00 -729,100.80,-48.00,1.00,0.00,1.00 -730,91.20,-48.00,1.00,0.00,1.00 -731,86.40,-48.00,1.00,0.00,1.00 -732,76.80,-48.00,1.00,0.00,1.00 -733,72.00,-48.00,1.00,0.00,1.00 -734,62.40,-43.20,1.00,0.00,1.00 -735,57.60,-43.20,1.00,0.00,1.00 -736,52.80,-43.20,1.00,0.00,1.00 -737,48.00,-38.40,1.00,0.00,1.00 -738,43.20,-38.40,1.00,0.00,1.00 -739,38.40,-33.60,1.00,0.00,1.00 -740,33.60,-28.80,1.00,0.00,1.00 -741,28.80,-28.80,1.00,0.00,1.00 -742,24.00,-24.00,1.00,0.00,1.00 -743,19.20,-19.20,1.00,0.00,1.00 -744,14.40,-19.20,1.00,0.00,1.00 -745,14.40,-14.40,1.00,0.00,1.00 -746,9.60,-9.60,1.00,0.00,1.00 -747,4.80,-4.80,1.00,0.00,1.00 -748,4.80,-4.80,1.00,0.00,1.00 -749,0.00,0.00,1.00,0.00,1.00 -750,-4.80,4.80,1.00,0.00,1.00 -751,-4.80,4.80,1.00,0.00,1.00 -752,-9.60,9.60,1.00,0.00,1.00 -753,-14.40,14.40,1.00,0.00,1.00 -754,-19.20,14.40,1.00,0.00,1.00 -755,-24.00,19.20,1.00,0.00,1.00 -756,-24.00,24.00,1.00,0.00,1.00 -757,-28.80,24.00,1.00,0.00,1.00 -758,-33.60,28.80,1.00,0.00,1.00 -759,-38.40,28.80,1.00,0.00,1.00 -760,-43.20,33.60,1.00,0.00,1.00 -761,-48.00,33.60,1.00,0.00,1.00 -762,-52.80,38.40,1.00,0.00,1.00 -763,-62.40,38.40,1.00,0.00,1.00 -764,-67.20,38.40,1.00,0.00,1.00 -765,-72.00,43.20,1.00,0.00,1.00 -766,-76.80,43.20,1.00,0.00,1.00 -767,-86.40,43.20,1.00,0.00,1.00 -768,-91.20,43.20,1.00,0.00,1.00 -769,-96.00,43.20,1.00,0.00,1.00 -770,-105.60,43.20,1.00,0.00,1.00 -771,-110.40,43.20,1.00,0.00,1.00 -772,-115.20,38.40,1.00,0.00,1.00 -773,-124.80,38.40,1.00,0.00,1.00 -774,-129.60,38.40,1.00,0.00,1.00 -775,-134.40,33.60,1.00,0.00,1.00 -776,-139.20,33.60,1.00,0.00,1.00 -777,-144.00,28.80,1.00,0.00,1.00 -778,-148.80,28.80,1.00,0.00,1.00 -779,-153.60,24.00,1.00,0.00,1.00 -780,-158.40,19.20,1.00,0.00,1.00 -781,-158.40,19.20,1.00,0.00,1.00 -782,-163.20,14.40,1.00,0.00,1.00 -783,-168.00,9.60,1.00,0.00,1.00 -784,-172.80,9.60,1.00,0.00,1.00 -785,-172.80,4.80,1.00,0.00,1.00 -786,-177.60,0.00,1.00,0.00,1.00 -787,177.60,-0.00,1.00,0.00,1.00 -788,172.80,-4.80,1.00,0.00,1.00 -789,172.80,-9.60,1.00,0.00,1.00 -790,168.00,-9.60,1.00,0.00,1.00 -791,163.20,-14.40,1.00,0.00,1.00 -792,158.40,-19.20,1.00,0.00,1.00 -793,158.40,-19.20,1.00,0.00,1.00 -794,153.60,-24.00,1.00,0.00,1.00 -795,148.80,-28.80,1.00,0.00,1.00 -796,144.00,-28.80,1.00,0.00,1.00 -797,139.20,-33.60,1.00,0.00,1.00 -798,134.40,-33.60,1.00,0.00,1.00 -799,129.60,-38.40,1.00,0.00,1.00 -800,124.80,-38.40,1.00,0.00,1.00 -801,115.20,-38.40,1.00,0.00,1.00 -802,110.40,-43.20,1.00,0.00,1.00 -803,105.60,-43.20,1.00,0.00,1.00 -804,96.00,-43.20,1.00,0.00,1.00 -805,91.20,-43.20,1.00,0.00,1.00 -806,86.40,-43.20,1.00,0.00,1.00 -807,76.80,-43.20,1.00,0.00,1.00 -808,72.00,-43.20,1.00,0.00,1.00 -809,67.20,-38.40,1.00,0.00,1.00 -810,62.40,-38.40,1.00,0.00,1.00 -811,52.80,-38.40,1.00,0.00,1.00 -812,48.00,-33.60,1.00,0.00,1.00 -813,43.20,-33.60,1.00,0.00,1.00 -814,38.40,-28.80,1.00,0.00,1.00 -815,33.60,-28.80,1.00,0.00,1.00 -816,28.80,-24.00,1.00,0.00,1.00 -817,24.00,-24.00,1.00,0.00,1.00 -818,24.00,-19.20,1.00,0.00,1.00 -819,19.20,-14.40,1.00,0.00,1.00 -820,14.40,-14.40,1.00,0.00,1.00 -821,9.60,-9.60,1.00,0.00,1.00 -822,4.80,-4.80,1.00,0.00,1.00 -823,4.80,-4.80,1.00,0.00,1.00 -824,0.00,0.00,1.00,0.00,1.00 -825,-4.80,4.80,1.00,0.00,1.00 -826,-9.60,4.80,1.00,0.00,1.00 -827,-9.60,9.60,1.00,0.00,1.00 -828,-14.40,9.60,1.00,0.00,1.00 -829,-19.20,14.40,1.00,0.00,1.00 -830,-24.00,19.20,1.00,0.00,1.00 -831,-28.80,19.20,1.00,0.00,1.00 -832,-33.60,24.00,1.00,0.00,1.00 -833,-38.40,24.00,1.00,0.00,1.00 -834,-43.20,28.80,1.00,0.00,1.00 -835,-48.00,28.80,1.00,0.00,1.00 -836,-52.80,33.60,1.00,0.00,1.00 -837,-57.60,33.60,1.00,0.00,1.00 -838,-62.40,33.60,1.00,0.00,1.00 -839,-67.20,38.40,1.00,0.00,1.00 -840,-72.00,38.40,1.00,0.00,1.00 -841,-81.60,38.40,1.00,0.00,1.00 -842,-86.40,38.40,1.00,0.00,1.00 -843,-91.20,38.40,1.00,0.00,1.00 -844,-96.00,38.40,1.00,0.00,1.00 -845,-105.60,38.40,1.00,0.00,1.00 -846,-110.40,38.40,1.00,0.00,1.00 -847,-115.20,33.60,1.00,0.00,1.00 -848,-120.00,33.60,1.00,0.00,1.00 -849,-124.80,33.60,1.00,0.00,1.00 -850,-129.60,28.80,1.00,0.00,1.00 -851,-134.40,28.80,1.00,0.00,1.00 -852,-139.20,24.00,1.00,0.00,1.00 -853,-144.00,24.00,1.00,0.00,1.00 -854,-148.80,19.20,1.00,0.00,1.00 -855,-153.60,19.20,1.00,0.00,1.00 -856,-158.40,14.40,1.00,0.00,1.00 -857,-163.20,14.40,1.00,0.00,1.00 -858,-168.00,9.60,1.00,0.00,1.00 -859,-172.80,9.60,1.00,0.00,1.00 -860,-172.80,4.80,1.00,0.00,1.00 -861,-177.60,0.00,1.00,0.00,1.00 -862,177.60,-0.00,1.00,0.00,1.00 -863,172.80,-4.80,1.00,0.00,1.00 -864,172.80,-9.60,1.00,0.00,1.00 -865,168.00,-9.60,1.00,0.00,1.00 -866,163.20,-14.40,1.00,0.00,1.00 -867,158.40,-14.40,1.00,0.00,1.00 -868,153.60,-19.20,1.00,0.00,1.00 -869,148.80,-19.20,1.00,0.00,1.00 -870,144.00,-24.00,1.00,0.00,1.00 -871,139.20,-24.00,1.00,0.00,1.00 -872,134.40,-28.80,1.00,0.00,1.00 -873,129.60,-28.80,1.00,0.00,1.00 -874,124.80,-33.60,1.00,0.00,1.00 -875,120.00,-33.60,1.00,0.00,1.00 -876,115.20,-33.60,1.00,0.00,1.00 -877,110.40,-38.40,1.00,0.00,1.00 -878,105.60,-38.40,1.00,0.00,1.00 -879,96.00,-38.40,1.00,0.00,1.00 -880,91.20,-38.40,1.00,0.00,1.00 -881,86.40,-38.40,1.00,0.00,1.00 -882,81.60,-38.40,1.00,0.00,1.00 -883,72.00,-38.40,1.00,0.00,1.00 -884,67.20,-38.40,1.00,0.00,1.00 -885,62.40,-33.60,1.00,0.00,1.00 -886,57.60,-33.60,1.00,0.00,1.00 -887,52.80,-33.60,1.00,0.00,1.00 -888,48.00,-28.80,1.00,0.00,1.00 -889,43.20,-28.80,1.00,0.00,1.00 -890,38.40,-24.00,1.00,0.00,1.00 -891,33.60,-24.00,1.00,0.00,1.00 -892,28.80,-19.20,1.00,0.00,1.00 -893,24.00,-19.20,1.00,0.00,1.00 -894,19.20,-14.40,1.00,0.00,1.00 -895,14.40,-9.60,1.00,0.00,1.00 -896,9.60,-9.60,1.00,0.00,1.00 -897,9.60,-4.80,1.00,0.00,1.00 -898,4.80,-4.80,1.00,0.00,1.00 -899,0.00,0.00,1.00,0.00,1.00 -900,-4.80,4.80,1.00,0.00,1.00 -901,-9.60,4.80,1.00,0.00,1.00 -902,-14.40,9.60,1.00,0.00,1.00 -903,-14.40,9.60,1.00,0.00,1.00 -904,-19.20,14.40,1.00,0.00,1.00 -905,-24.00,14.40,1.00,0.00,1.00 -906,-28.80,19.20,1.00,0.00,1.00 -907,-33.60,19.20,1.00,0.00,1.00 -908,-38.40,24.00,1.00,0.00,1.00 -909,-43.20,24.00,1.00,0.00,1.00 -910,-48.00,24.00,1.00,0.00,1.00 -911,-52.80,28.80,1.00,0.00,1.00 -912,-57.60,28.80,1.00,0.00,1.00 -913,-62.40,28.80,1.00,0.00,1.00 -914,-67.20,33.60,1.00,0.00,1.00 -915,-72.00,33.60,1.00,0.00,1.00 -916,-81.60,33.60,1.00,0.00,1.00 -917,-86.40,33.60,1.00,0.00,1.00 -918,-91.20,33.60,1.00,0.00,1.00 -919,-96.00,33.60,1.00,0.00,1.00 -920,-100.80,33.60,1.00,0.00,1.00 -921,-110.40,33.60,1.00,0.00,1.00 -922,-115.20,33.60,1.00,0.00,1.00 -923,-120.00,28.80,1.00,0.00,1.00 -924,-124.80,28.80,1.00,0.00,1.00 -925,-129.60,28.80,1.00,0.00,1.00 -926,-134.40,24.00,1.00,0.00,1.00 -927,-139.20,24.00,1.00,0.00,1.00 -928,-144.00,19.20,1.00,0.00,1.00 -929,-148.80,19.20,1.00,0.00,1.00 -930,-153.60,14.40,1.00,0.00,1.00 -931,-158.40,14.40,1.00,0.00,1.00 -932,-163.20,9.60,1.00,0.00,1.00 -933,-168.00,9.60,1.00,0.00,1.00 -934,-168.00,4.80,1.00,0.00,1.00 -935,-172.80,4.80,1.00,0.00,1.00 -936,-177.60,0.00,1.00,0.00,1.00 -937,177.60,-0.00,1.00,0.00,1.00 -938,172.80,-4.80,1.00,0.00,1.00 -939,168.00,-4.80,1.00,0.00,1.00 -940,168.00,-9.60,1.00,0.00,1.00 -941,163.20,-9.60,1.00,0.00,1.00 -942,158.40,-14.40,1.00,0.00,1.00 -943,153.60,-14.40,1.00,0.00,1.00 -944,148.80,-19.20,1.00,0.00,1.00 -945,144.00,-19.20,1.00,0.00,1.00 -946,139.20,-24.00,1.00,0.00,1.00 -947,134.40,-24.00,1.00,0.00,1.00 -948,129.60,-28.80,1.00,0.00,1.00 -949,124.80,-28.80,1.00,0.00,1.00 -950,120.00,-28.80,1.00,0.00,1.00 -951,115.20,-33.60,1.00,0.00,1.00 -952,110.40,-33.60,1.00,0.00,1.00 -953,100.80,-33.60,1.00,0.00,1.00 -954,96.00,-33.60,1.00,0.00,1.00 -955,91.20,-33.60,1.00,0.00,1.00 -956,86.40,-33.60,1.00,0.00,1.00 -957,81.60,-33.60,1.00,0.00,1.00 -958,72.00,-33.60,1.00,0.00,1.00 -959,67.20,-33.60,1.00,0.00,1.00 -960,62.40,-28.80,1.00,0.00,1.00 -961,57.60,-28.80,1.00,0.00,1.00 -962,52.80,-28.80,1.00,0.00,1.00 -963,48.00,-24.00,1.00,0.00,1.00 -964,43.20,-24.00,1.00,0.00,1.00 -965,38.40,-24.00,1.00,0.00,1.00 -966,33.60,-19.20,1.00,0.00,1.00 -967,28.80,-19.20,1.00,0.00,1.00 -968,24.00,-14.40,1.00,0.00,1.00 -969,19.20,-14.40,1.00,0.00,1.00 -970,14.40,-9.60,1.00,0.00,1.00 -971,14.40,-9.60,1.00,0.00,1.00 -972,9.60,-4.80,1.00,0.00,1.00 -973,4.80,-4.80,1.00,0.00,1.00 -974,0.00,0.00,1.00,0.00,1.00 -975,-4.80,0.00,1.00,0.00,1.00 -976,-9.60,4.80,1.00,0.00,1.00 -977,-14.40,4.80,1.00,0.00,1.00 -978,-19.20,9.60,1.00,0.00,1.00 -979,-19.20,9.60,1.00,0.00,1.00 -980,-24.00,14.40,1.00,0.00,1.00 -981,-28.80,14.40,1.00,0.00,1.00 -982,-33.60,19.20,1.00,0.00,1.00 -983,-38.40,19.20,1.00,0.00,1.00 -984,-43.20,19.20,1.00,0.00,1.00 -985,-48.00,24.00,1.00,0.00,1.00 -986,-52.80,24.00,1.00,0.00,1.00 -987,-57.60,24.00,1.00,0.00,1.00 -988,-62.40,24.00,1.00,0.00,1.00 -989,-72.00,28.80,1.00,0.00,1.00 -990,-76.80,28.80,1.00,0.00,1.00 -991,-81.60,28.80,1.00,0.00,1.00 -992,-86.40,28.80,1.00,0.00,1.00 -993,-91.20,28.80,1.00,0.00,1.00 -994,-96.00,28.80,1.00,0.00,1.00 -995,-100.80,28.80,1.00,0.00,1.00 -996,-105.60,28.80,1.00,0.00,1.00 -997,-115.20,28.80,1.00,0.00,1.00 -998,-120.00,24.00,1.00,0.00,1.00 -999,-124.80,24.00,1.00,0.00,1.00 -1000,-129.60,24.00,1.00,0.00,1.00 -1001,-134.40,24.00,1.00,0.00,1.00 -1002,-139.20,19.20,1.00,0.00,1.00 -1003,-144.00,19.20,1.00,0.00,1.00 -1004,-148.80,14.40,1.00,0.00,1.00 -1005,-153.60,14.40,1.00,0.00,1.00 -1006,-158.40,14.40,1.00,0.00,1.00 -1007,-163.20,9.60,1.00,0.00,1.00 -1008,-163.20,9.60,1.00,0.00,1.00 -1009,-168.00,4.80,1.00,0.00,1.00 -1010,-172.80,4.80,1.00,0.00,1.00 -1011,-177.60,0.00,1.00,0.00,1.00 -1012,177.60,-0.00,1.00,0.00,1.00 -1013,172.80,-4.80,1.00,0.00,1.00 -1014,168.00,-4.80,1.00,0.00,1.00 -1015,163.20,-9.60,1.00,0.00,1.00 -1016,163.20,-9.60,1.00,0.00,1.00 -1017,158.40,-14.40,1.00,0.00,1.00 -1018,153.60,-14.40,1.00,0.00,1.00 -1019,148.80,-14.40,1.00,0.00,1.00 -1020,144.00,-19.20,1.00,0.00,1.00 -1021,139.20,-19.20,1.00,0.00,1.00 -1022,134.40,-24.00,1.00,0.00,1.00 -1023,129.60,-24.00,1.00,0.00,1.00 -1024,124.80,-24.00,1.00,0.00,1.00 -1025,120.00,-24.00,1.00,0.00,1.00 -1026,115.20,-28.80,1.00,0.00,1.00 -1027,105.60,-28.80,1.00,0.00,1.00 -1028,100.80,-28.80,1.00,0.00,1.00 -1029,96.00,-28.80,1.00,0.00,1.00 -1030,91.20,-28.80,1.00,0.00,1.00 -1031,86.40,-28.80,1.00,0.00,1.00 -1032,81.60,-28.80,1.00,0.00,1.00 -1033,76.80,-28.80,1.00,0.00,1.00 -1034,72.00,-28.80,1.00,0.00,1.00 -1035,62.40,-24.00,1.00,0.00,1.00 -1036,57.60,-24.00,1.00,0.00,1.00 -1037,52.80,-24.00,1.00,0.00,1.00 -1038,48.00,-24.00,1.00,0.00,1.00 -1039,43.20,-19.20,1.00,0.00,1.00 -1040,38.40,-19.20,1.00,0.00,1.00 -1041,33.60,-19.20,1.00,0.00,1.00 -1042,28.80,-14.40,1.00,0.00,1.00 -1043,24.00,-14.40,1.00,0.00,1.00 -1044,19.20,-9.60,1.00,0.00,1.00 -1045,19.20,-9.60,1.00,0.00,1.00 -1046,14.40,-4.80,1.00,0.00,1.00 -1047,9.60,-4.80,1.00,0.00,1.00 -1048,4.80,-0.00,1.00,0.00,1.00 -1049,0.00,0.00,1.00,0.00,1.00 -1050,-4.80,0.00,1.00,0.00,1.00 -1051,-9.60,4.80,1.00,0.00,1.00 -1052,-14.40,4.80,1.00,0.00,1.00 -1053,-19.20,9.60,1.00,0.00,1.00 -1054,-24.00,9.60,1.00,0.00,1.00 -1055,-28.80,9.60,1.00,0.00,1.00 -1056,-33.60,14.40,1.00,0.00,1.00 -1057,-33.60,14.40,1.00,0.00,1.00 -1058,-38.40,14.40,1.00,0.00,1.00 -1059,-43.20,19.20,1.00,0.00,1.00 -1060,-48.00,19.20,1.00,0.00,1.00 -1061,-57.60,19.20,1.00,0.00,1.00 -1062,-62.40,19.20,1.00,0.00,1.00 -1063,-67.20,24.00,1.00,0.00,1.00 -1064,-72.00,24.00,1.00,0.00,1.00 -1065,-76.80,24.00,1.00,0.00,1.00 -1066,-81.60,24.00,1.00,0.00,1.00 -1067,-86.40,24.00,1.00,0.00,1.00 -1068,-91.20,24.00,1.00,0.00,1.00 -1069,-96.00,24.00,1.00,0.00,1.00 -1070,-100.80,24.00,1.00,0.00,1.00 -1071,-105.60,24.00,1.00,0.00,1.00 -1072,-110.40,24.00,1.00,0.00,1.00 -1073,-115.20,19.20,1.00,0.00,1.00 -1074,-120.00,19.20,1.00,0.00,1.00 -1075,-129.60,19.20,1.00,0.00,1.00 -1076,-134.40,19.20,1.00,0.00,1.00 -1077,-139.20,19.20,1.00,0.00,1.00 -1078,-144.00,14.40,1.00,0.00,1.00 -1079,-148.80,14.40,1.00,0.00,1.00 -1080,-148.80,14.40,1.00,0.00,1.00 -1081,-153.60,9.60,1.00,0.00,1.00 -1082,-158.40,9.60,1.00,0.00,1.00 -1083,-163.20,4.80,1.00,0.00,1.00 -1084,-168.00,4.80,1.00,0.00,1.00 -1085,-172.80,4.80,1.00,0.00,1.00 -1086,-177.60,0.00,1.00,0.00,1.00 -1087,177.60,-0.00,1.00,0.00,1.00 -1088,172.80,-4.80,1.00,0.00,1.00 -1089,168.00,-4.80,1.00,0.00,1.00 -1090,163.20,-4.80,1.00,0.00,1.00 -1091,158.40,-9.60,1.00,0.00,1.00 -1092,153.60,-9.60,1.00,0.00,1.00 -1093,148.80,-14.40,1.00,0.00,1.00 -1094,148.80,-14.40,1.00,0.00,1.00 -1095,144.00,-14.40,1.00,0.00,1.00 -1096,139.20,-19.20,1.00,0.00,1.00 -1097,134.40,-19.20,1.00,0.00,1.00 -1098,129.60,-19.20,1.00,0.00,1.00 -1099,120.00,-19.20,1.00,0.00,1.00 -1100,115.20,-19.20,1.00,0.00,1.00 -1101,110.40,-24.00,1.00,0.00,1.00 -1102,105.60,-24.00,1.00,0.00,1.00 -1103,100.80,-24.00,1.00,0.00,1.00 -1104,96.00,-24.00,1.00,0.00,1.00 -1105,91.20,-24.00,1.00,0.00,1.00 -1106,86.40,-24.00,1.00,0.00,1.00 -1107,81.60,-24.00,1.00,0.00,1.00 -1108,76.80,-24.00,1.00,0.00,1.00 -1109,72.00,-24.00,1.00,0.00,1.00 -1110,67.20,-24.00,1.00,0.00,1.00 -1111,62.40,-19.20,1.00,0.00,1.00 -1112,57.60,-19.20,1.00,0.00,1.00 -1113,48.00,-19.20,1.00,0.00,1.00 -1114,43.20,-19.20,1.00,0.00,1.00 -1115,38.40,-14.40,1.00,0.00,1.00 -1116,33.60,-14.40,1.00,0.00,1.00 -1117,33.60,-14.40,1.00,0.00,1.00 -1118,28.80,-9.60,1.00,0.00,1.00 -1119,24.00,-9.60,1.00,0.00,1.00 -1120,19.20,-9.60,1.00,0.00,1.00 -1121,14.40,-4.80,1.00,0.00,1.00 -1122,9.60,-4.80,1.00,0.00,1.00 -1123,4.80,-0.00,1.00,0.00,1.00 -1124,0.00,0.00,1.00,0.00,1.00 -1125,-4.80,0.00,1.00,0.00,1.00 -1126,-9.60,4.80,1.00,0.00,1.00 -1127,-14.40,4.80,1.00,0.00,1.00 -1128,-19.20,4.80,1.00,0.00,1.00 -1129,-24.00,9.60,1.00,0.00,1.00 -1130,-28.80,9.60,1.00,0.00,1.00 -1131,-33.60,9.60,1.00,0.00,1.00 -1132,-38.40,9.60,1.00,0.00,1.00 -1133,-43.20,14.40,1.00,0.00,1.00 -1134,-48.00,14.40,1.00,0.00,1.00 -1135,-52.80,14.40,1.00,0.00,1.00 -1136,-57.60,14.40,1.00,0.00,1.00 -1137,-62.40,19.20,1.00,0.00,1.00 -1138,-67.20,19.20,1.00,0.00,1.00 -1139,-72.00,19.20,1.00,0.00,1.00 -1140,-76.80,19.20,1.00,0.00,1.00 -1141,-81.60,19.20,1.00,0.00,1.00 -1142,-86.40,19.20,1.00,0.00,1.00 -1143,-91.20,19.20,1.00,0.00,1.00 -1144,-96.00,19.20,1.00,0.00,1.00 -1145,-100.80,19.20,1.00,0.00,1.00 -1146,-105.60,19.20,1.00,0.00,1.00 -1147,-110.40,19.20,1.00,0.00,1.00 -1148,-115.20,19.20,1.00,0.00,1.00 -1149,-120.00,14.40,1.00,0.00,1.00 -1150,-124.80,14.40,1.00,0.00,1.00 -1151,-129.60,14.40,1.00,0.00,1.00 -1152,-134.40,14.40,1.00,0.00,1.00 -1153,-139.20,14.40,1.00,0.00,1.00 -1154,-144.00,9.60,1.00,0.00,1.00 -1155,-148.80,9.60,1.00,0.00,1.00 -1156,-153.60,9.60,1.00,0.00,1.00 -1157,-158.40,4.80,1.00,0.00,1.00 -1158,-163.20,4.80,1.00,0.00,1.00 -1159,-168.00,4.80,1.00,0.00,1.00 -1160,-172.80,0.00,1.00,0.00,1.00 -1161,-177.60,0.00,1.00,0.00,1.00 -1162,177.60,-0.00,1.00,0.00,1.00 -1163,172.80,-0.00,1.00,0.00,1.00 -1164,168.00,-4.80,1.00,0.00,1.00 -1165,163.20,-4.80,1.00,0.00,1.00 -1166,158.40,-4.80,1.00,0.00,1.00 -1167,153.60,-9.60,1.00,0.00,1.00 -1168,148.80,-9.60,1.00,0.00,1.00 -1169,144.00,-9.60,1.00,0.00,1.00 -1170,139.20,-14.40,1.00,0.00,1.00 -1171,134.40,-14.40,1.00,0.00,1.00 -1172,129.60,-14.40,1.00,0.00,1.00 -1173,124.80,-14.40,1.00,0.00,1.00 -1174,120.00,-14.40,1.00,0.00,1.00 -1175,115.20,-19.20,1.00,0.00,1.00 -1176,110.40,-19.20,1.00,0.00,1.00 -1177,105.60,-19.20,1.00,0.00,1.00 -1178,100.80,-19.20,1.00,0.00,1.00 -1179,96.00,-19.20,1.00,0.00,1.00 -1180,91.20,-19.20,1.00,0.00,1.00 -1181,86.40,-19.20,1.00,0.00,1.00 -1182,81.60,-19.20,1.00,0.00,1.00 -1183,76.80,-19.20,1.00,0.00,1.00 -1184,72.00,-19.20,1.00,0.00,1.00 -1185,67.20,-19.20,1.00,0.00,1.00 -1186,62.40,-19.20,1.00,0.00,1.00 -1187,57.60,-14.40,1.00,0.00,1.00 -1188,52.80,-14.40,1.00,0.00,1.00 -1189,48.00,-14.40,1.00,0.00,1.00 -1190,43.20,-14.40,1.00,0.00,1.00 -1191,38.40,-9.60,1.00,0.00,1.00 -1192,33.60,-9.60,1.00,0.00,1.00 -1193,28.80,-9.60,1.00,0.00,1.00 -1194,24.00,-9.60,1.00,0.00,1.00 -1195,19.20,-4.80,1.00,0.00,1.00 -1196,14.40,-4.80,1.00,0.00,1.00 -1197,9.60,-4.80,1.00,0.00,1.00 -1198,4.80,-0.00,1.00,0.00,1.00 -1199,0.00,0.00,1.00,0.00,1.00 -1200,-4.80,0.00,1.00,0.00,1.00 -1201,-9.60,0.00,1.00,0.00,1.00 -1202,-14.40,4.80,1.00,0.00,1.00 -1203,-19.20,4.80,1.00,0.00,1.00 -1204,-24.00,4.80,1.00,0.00,1.00 -1205,-28.80,4.80,1.00,0.00,1.00 -1206,-33.60,9.60,1.00,0.00,1.00 -1207,-38.40,9.60,1.00,0.00,1.00 -1208,-43.20,9.60,1.00,0.00,1.00 -1209,-48.00,9.60,1.00,0.00,1.00 -1210,-52.80,9.60,1.00,0.00,1.00 -1211,-57.60,14.40,1.00,0.00,1.00 -1212,-62.40,14.40,1.00,0.00,1.00 -1213,-67.20,14.40,1.00,0.00,1.00 -1214,-72.00,14.40,1.00,0.00,1.00 -1215,-76.80,14.40,1.00,0.00,1.00 -1216,-81.60,14.40,1.00,0.00,1.00 -1217,-86.40,14.40,1.00,0.00,1.00 -1218,-91.20,14.40,1.00,0.00,1.00 -1219,-96.00,14.40,1.00,0.00,1.00 -1220,-100.80,14.40,1.00,0.00,1.00 -1221,-105.60,14.40,1.00,0.00,1.00 -1222,-110.40,14.40,1.00,0.00,1.00 -1223,-115.20,14.40,1.00,0.00,1.00 -1224,-120.00,14.40,1.00,0.00,1.00 -1225,-124.80,9.60,1.00,0.00,1.00 -1226,-129.60,9.60,1.00,0.00,1.00 -1227,-134.40,9.60,1.00,0.00,1.00 -1228,-139.20,9.60,1.00,0.00,1.00 -1229,-144.00,9.60,1.00,0.00,1.00 -1230,-148.80,9.60,1.00,0.00,1.00 -1231,-153.60,4.80,1.00,0.00,1.00 -1232,-158.40,4.80,1.00,0.00,1.00 -1233,-163.20,4.80,1.00,0.00,1.00 -1234,-168.00,4.80,1.00,0.00,1.00 -1235,-172.80,0.00,1.00,0.00,1.00 -1236,-177.60,0.00,1.00,0.00,1.00 -1237,177.60,-0.00,1.00,0.00,1.00 -1238,172.80,-0.00,1.00,0.00,1.00 -1239,168.00,-4.80,1.00,0.00,1.00 -1240,163.20,-4.80,1.00,0.00,1.00 -1241,158.40,-4.80,1.00,0.00,1.00 -1242,153.60,-4.80,1.00,0.00,1.00 -1243,148.80,-9.60,1.00,0.00,1.00 -1244,144.00,-9.60,1.00,0.00,1.00 -1245,139.20,-9.60,1.00,0.00,1.00 -1246,134.40,-9.60,1.00,0.00,1.00 -1247,129.60,-9.60,1.00,0.00,1.00 -1248,124.80,-9.60,1.00,0.00,1.00 -1249,120.00,-14.40,1.00,0.00,1.00 -1250,115.20,-14.40,1.00,0.00,1.00 -1251,110.40,-14.40,1.00,0.00,1.00 -1252,105.60,-14.40,1.00,0.00,1.00 -1253,100.80,-14.40,1.00,0.00,1.00 -1254,96.00,-14.40,1.00,0.00,1.00 -1255,91.20,-14.40,1.00,0.00,1.00 -1256,86.40,-14.40,1.00,0.00,1.00 -1257,81.60,-14.40,1.00,0.00,1.00 -1258,76.80,-14.40,1.00,0.00,1.00 -1259,72.00,-14.40,1.00,0.00,1.00 -1260,67.20,-14.40,1.00,0.00,1.00 -1261,62.40,-14.40,1.00,0.00,1.00 -1262,57.60,-14.40,1.00,0.00,1.00 -1263,52.80,-9.60,1.00,0.00,1.00 -1264,48.00,-9.60,1.00,0.00,1.00 -1265,43.20,-9.60,1.00,0.00,1.00 -1266,38.40,-9.60,1.00,0.00,1.00 -1267,33.60,-9.60,1.00,0.00,1.00 -1268,28.80,-4.80,1.00,0.00,1.00 -1269,24.00,-4.80,1.00,0.00,1.00 -1270,19.20,-4.80,1.00,0.00,1.00 -1271,14.40,-4.80,1.00,0.00,1.00 -1272,9.60,-0.00,1.00,0.00,1.00 -1273,4.80,-0.00,1.00,0.00,1.00 -1274,0.00,0.00,1.00,0.00,1.00 -1275,-4.80,0.00,1.00,0.00,1.00 -1276,-9.60,0.00,1.00,0.00,1.00 -1277,-14.40,0.00,1.00,0.00,1.00 -1278,-19.20,4.80,1.00,0.00,1.00 -1279,-24.00,4.80,1.00,0.00,1.00 -1280,-28.80,4.80,1.00,0.00,1.00 -1281,-33.60,4.80,1.00,0.00,1.00 -1282,-38.40,4.80,1.00,0.00,1.00 -1283,-43.20,4.80,1.00,0.00,1.00 -1284,-48.00,4.80,1.00,0.00,1.00 -1285,-52.80,9.60,1.00,0.00,1.00 -1286,-57.60,9.60,1.00,0.00,1.00 -1287,-62.40,9.60,1.00,0.00,1.00 -1288,-67.20,9.60,1.00,0.00,1.00 -1289,-72.00,9.60,1.00,0.00,1.00 -1290,-76.80,9.60,1.00,0.00,1.00 -1291,-81.60,9.60,1.00,0.00,1.00 -1292,-86.40,9.60,1.00,0.00,1.00 -1293,-91.20,9.60,1.00,0.00,1.00 -1294,-96.00,9.60,1.00,0.00,1.00 -1295,-100.80,9.60,1.00,0.00,1.00 -1296,-105.60,9.60,1.00,0.00,1.00 -1297,-110.40,9.60,1.00,0.00,1.00 -1298,-115.20,9.60,1.00,0.00,1.00 -1299,-120.00,9.60,1.00,0.00,1.00 -1300,-124.80,9.60,1.00,0.00,1.00 -1301,-129.60,9.60,1.00,0.00,1.00 -1302,-134.40,4.80,1.00,0.00,1.00 -1303,-139.20,4.80,1.00,0.00,1.00 -1304,-144.00,4.80,1.00,0.00,1.00 -1305,-148.80,4.80,1.00,0.00,1.00 -1306,-153.60,4.80,1.00,0.00,1.00 -1307,-158.40,4.80,1.00,0.00,1.00 -1308,-163.20,4.80,1.00,0.00,1.00 -1309,-168.00,0.00,1.00,0.00,1.00 -1310,-172.80,0.00,1.00,0.00,1.00 -1311,-177.60,0.00,1.00,0.00,1.00 -1312,177.60,-0.00,1.00,0.00,1.00 -1313,172.80,-0.00,1.00,0.00,1.00 -1314,168.00,-0.00,1.00,0.00,1.00 -1315,163.20,-4.80,1.00,0.00,1.00 -1316,158.40,-4.80,1.00,0.00,1.00 -1317,153.60,-4.80,1.00,0.00,1.00 -1318,148.80,-4.80,1.00,0.00,1.00 -1319,144.00,-4.80,1.00,0.00,1.00 -1320,139.20,-4.80,1.00,0.00,1.00 -1321,134.40,-4.80,1.00,0.00,1.00 -1322,129.60,-9.60,1.00,0.00,1.00 -1323,124.80,-9.60,1.00,0.00,1.00 -1324,120.00,-9.60,1.00,0.00,1.00 -1325,115.20,-9.60,1.00,0.00,1.00 -1326,110.40,-9.60,1.00,0.00,1.00 -1327,105.60,-9.60,1.00,0.00,1.00 -1328,100.80,-9.60,1.00,0.00,1.00 -1329,96.00,-9.60,1.00,0.00,1.00 -1330,91.20,-9.60,1.00,0.00,1.00 -1331,86.40,-9.60,1.00,0.00,1.00 -1332,81.60,-9.60,1.00,0.00,1.00 -1333,76.80,-9.60,1.00,0.00,1.00 -1334,72.00,-9.60,1.00,0.00,1.00 -1335,67.20,-9.60,1.00,0.00,1.00 -1336,62.40,-9.60,1.00,0.00,1.00 -1337,57.60,-9.60,1.00,0.00,1.00 -1338,52.80,-9.60,1.00,0.00,1.00 -1339,48.00,-4.80,1.00,0.00,1.00 -1340,43.20,-4.80,1.00,0.00,1.00 -1341,38.40,-4.80,1.00,0.00,1.00 -1342,33.60,-4.80,1.00,0.00,1.00 -1343,28.80,-4.80,1.00,0.00,1.00 -1344,24.00,-4.80,1.00,0.00,1.00 -1345,19.20,-4.80,1.00,0.00,1.00 -1346,14.40,-0.00,1.00,0.00,1.00 -1347,9.60,-0.00,1.00,0.00,1.00 -1348,4.80,-0.00,1.00,0.00,1.00 -1349,0.00,0.00,1.00,0.00,1.00 -1350,-4.80,0.00,1.00,0.00,1.00 -1351,-9.60,0.00,1.00,0.00,1.00 -1352,-14.40,0.00,1.00,0.00,1.00 -1353,-19.20,0.00,1.00,0.00,1.00 -1354,-24.00,0.00,1.00,0.00,1.00 -1355,-28.80,0.00,1.00,0.00,1.00 -1356,-33.60,4.80,1.00,0.00,1.00 -1357,-38.40,4.80,1.00,0.00,1.00 -1358,-43.20,4.80,1.00,0.00,1.00 -1359,-48.00,4.80,1.00,0.00,1.00 -1360,-52.80,4.80,1.00,0.00,1.00 -1361,-57.60,4.80,1.00,0.00,1.00 -1362,-62.40,4.80,1.00,0.00,1.00 -1363,-67.20,4.80,1.00,0.00,1.00 -1364,-72.00,4.80,1.00,0.00,1.00 -1365,-76.80,4.80,1.00,0.00,1.00 -1366,-81.60,4.80,1.00,0.00,1.00 -1367,-86.40,4.80,1.00,0.00,1.00 -1368,-91.20,4.80,1.00,0.00,1.00 -1369,-96.00,4.80,1.00,0.00,1.00 -1370,-100.80,4.80,1.00,0.00,1.00 -1371,-105.60,4.80,1.00,0.00,1.00 -1372,-110.40,4.80,1.00,0.00,1.00 -1373,-115.20,4.80,1.00,0.00,1.00 -1374,-120.00,4.80,1.00,0.00,1.00 -1375,-124.80,4.80,1.00,0.00,1.00 -1376,-129.60,4.80,1.00,0.00,1.00 -1377,-134.40,4.80,1.00,0.00,1.00 -1378,-139.20,4.80,1.00,0.00,1.00 -1379,-144.00,4.80,1.00,0.00,1.00 -1380,-148.80,4.80,1.00,0.00,1.00 -1381,-153.60,0.00,1.00,0.00,1.00 -1382,-158.40,0.00,1.00,0.00,1.00 -1383,-163.20,0.00,1.00,0.00,1.00 -1384,-168.00,0.00,1.00,0.00,1.00 -1385,-172.80,0.00,1.00,0.00,1.00 -1386,-177.60,0.00,1.00,0.00,1.00 -1387,177.60,-0.00,1.00,0.00,1.00 -1388,172.80,-0.00,1.00,0.00,1.00 -1389,168.00,-0.00,1.00,0.00,1.00 -1390,163.20,-0.00,1.00,0.00,1.00 -1391,158.40,-0.00,1.00,0.00,1.00 -1392,153.60,-0.00,1.00,0.00,1.00 -1393,148.80,-4.80,1.00,0.00,1.00 -1394,144.00,-4.80,1.00,0.00,1.00 -1395,139.20,-4.80,1.00,0.00,1.00 -1396,134.40,-4.80,1.00,0.00,1.00 -1397,129.60,-4.80,1.00,0.00,1.00 -1398,124.80,-4.80,1.00,0.00,1.00 -1399,120.00,-4.80,1.00,0.00,1.00 -1400,115.20,-4.80,1.00,0.00,1.00 -1401,110.40,-4.80,1.00,0.00,1.00 -1402,105.60,-4.80,1.00,0.00,1.00 -1403,100.80,-4.80,1.00,0.00,1.00 -1404,96.00,-4.80,1.00,0.00,1.00 -1405,91.20,-4.80,1.00,0.00,1.00 -1406,86.40,-4.80,1.00,0.00,1.00 -1407,81.60,-4.80,1.00,0.00,1.00 -1408,76.80,-4.80,1.00,0.00,1.00 -1409,72.00,-4.80,1.00,0.00,1.00 -1410,67.20,-4.80,1.00,0.00,1.00 -1411,62.40,-4.80,1.00,0.00,1.00 -1412,57.60,-4.80,1.00,0.00,1.00 -1413,52.80,-4.80,1.00,0.00,1.00 -1414,48.00,-4.80,1.00,0.00,1.00 -1415,43.20,-4.80,1.00,0.00,1.00 -1416,38.40,-4.80,1.00,0.00,1.00 -1417,33.60,-4.80,1.00,0.00,1.00 -1418,28.80,-0.00,1.00,0.00,1.00 -1419,24.00,-0.00,1.00,0.00,1.00 -1420,19.20,-0.00,1.00,0.00,1.00 -1421,14.40,-0.00,1.00,0.00,1.00 -1422,9.60,-0.00,1.00,0.00,1.00 -1423,4.80,-0.00,1.00,0.00,1.00 -1424,0.00,0.00,1.00,0.00,1.00 -1425,-4.80,0.00,1.00,0.00,1.00 -1426,-9.60,0.00,1.00,0.00,1.00 -1427,-14.40,0.00,1.00,0.00,1.00 -1428,-19.20,0.00,1.00,0.00,1.00 -1429,-24.00,0.00,1.00,0.00,1.00 -1430,-28.80,0.00,1.00,0.00,1.00 -1431,-33.60,0.00,1.00,0.00,1.00 -1432,-38.40,0.00,1.00,0.00,1.00 -1433,-43.20,0.00,1.00,0.00,1.00 -1434,-48.00,0.00,1.00,0.00,1.00 -1435,-52.80,0.00,1.00,0.00,1.00 -1436,-57.60,0.00,1.00,0.00,1.00 -1437,-62.40,0.00,1.00,0.00,1.00 -1438,-67.20,0.00,1.00,0.00,1.00 -1439,-72.00,0.00,1.00,0.00,1.00 -1440,-76.80,0.00,1.00,0.00,1.00 -1441,-81.60,0.00,1.00,0.00,1.00 -1442,-86.40,0.00,1.00,0.00,1.00 -1443,-91.20,0.00,1.00,0.00,1.00 -1444,-96.00,0.00,1.00,0.00,1.00 -1445,-100.80,0.00,1.00,0.00,1.00 -1446,-105.60,0.00,1.00,0.00,1.00 -1447,-110.40,0.00,1.00,0.00,1.00 -1448,-115.20,0.00,1.00,0.00,1.00 -1449,-120.00,0.00,1.00,0.00,1.00 -1450,-124.80,0.00,1.00,0.00,1.00 -1451,-129.60,0.00,1.00,0.00,1.00 -1452,-134.40,0.00,1.00,0.00,1.00 -1453,-139.20,0.00,1.00,0.00,1.00 -1454,-144.00,0.00,1.00,0.00,1.00 -1455,-148.80,0.00,1.00,0.00,1.00 -1456,-153.60,0.00,1.00,0.00,1.00 -1457,-158.40,0.00,1.00,0.00,1.00 -1458,-163.20,0.00,1.00,0.00,1.00 -1459,-168.00,0.00,1.00,0.00,1.00 -1460,-172.80,0.00,1.00,0.00,1.00 -1461,-177.60,0.00,1.00,0.00,1.00 -1462,177.60,0.00,1.00,0.00,1.00 -1463,172.80,0.00,1.00,0.00,1.00 -1464,168.00,0.00,1.00,0.00,1.00 -1465,163.20,0.00,1.00,0.00,1.00 -1466,158.40,0.00,1.00,0.00,1.00 -1467,153.60,0.00,1.00,0.00,1.00 -1468,148.80,0.00,1.00,0.00,1.00 -1469,144.00,0.00,1.00,0.00,1.00 -1470,139.20,0.00,1.00,0.00,1.00 -1471,134.40,0.00,1.00,0.00,1.00 -1472,129.60,0.00,1.00,0.00,1.00 -1473,124.80,0.00,1.00,0.00,1.00 -1474,120.00,0.00,1.00,0.00,1.00 -1475,115.20,0.00,1.00,0.00,1.00 -1476,110.40,0.00,1.00,0.00,1.00 -1477,105.60,0.00,1.00,0.00,1.00 -1478,100.80,0.00,1.00,0.00,1.00 -1479,96.00,0.00,1.00,0.00,1.00 -1480,91.20,0.00,1.00,0.00,1.00 -1481,86.40,0.00,1.00,0.00,1.00 -1482,81.60,0.00,1.00,0.00,1.00 -1483,76.80,0.00,1.00,0.00,1.00 -1484,72.00,0.00,1.00,0.00,1.00 -1485,67.20,0.00,1.00,0.00,1.00 -1486,62.40,0.00,1.00,0.00,1.00 -1487,57.60,0.00,1.00,0.00,1.00 -1488,52.80,0.00,1.00,0.00,1.00 -1489,48.00,0.00,1.00,0.00,1.00 -1490,43.20,0.00,1.00,0.00,1.00 -1491,38.40,0.00,1.00,0.00,1.00 -1492,33.60,0.00,1.00,0.00,1.00 -1493,28.80,0.00,1.00,0.00,1.00 -1494,24.00,0.00,1.00,0.00,1.00 -1495,19.20,0.00,1.00,0.00,1.00 -1496,14.40,0.00,1.00,0.00,1.00 -1497,9.60,0.00,1.00,0.00,1.00 -1498,4.80,0.00,1.00,0.00,1.00 -1499,0.00,0.00,1.00,0.00,1.00 diff --git a/tests/renderer/data/stvISM3.csv b/tests/renderer/data/stvISM3.csv deleted file mode 100644 index 6b57caab12..0000000000 --- a/tests/renderer/data/stvISM3.csv +++ /dev/null @@ -1,1500 +0,0 @@ -0,0.00,0.00,1.00,0.00,1.00 -1,-177.60,-4.80,1.00,0.00,1.00 -2,4.80,4.80,1.00,0.00,1.00 -3,-168.00,-9.60,1.00,0.00,1.00 -4,14.40,14.40,1.00,0.00,1.00 -5,-163.20,-14.40,1.00,0.00,1.00 -6,19.20,19.20,1.00,0.00,1.00 -7,-153.60,-24.00,1.00,0.00,1.00 -8,28.80,24.00,1.00,0.00,1.00 -9,-148.80,-28.80,1.00,0.00,1.00 -10,38.40,33.60,1.00,0.00,1.00 -11,-139.20,-33.60,1.00,0.00,1.00 -12,48.00,38.40,1.00,0.00,1.00 -13,-124.80,-38.40,1.00,0.00,1.00 -14,57.60,38.40,1.00,0.00,1.00 -15,-115.20,-43.20,1.00,0.00,1.00 -16,72.00,43.20,1.00,0.00,1.00 -17,-100.80,-43.20,1.00,0.00,1.00 -18,86.40,43.20,1.00,0.00,1.00 -19,-86.40,-43.20,1.00,0.00,1.00 -20,100.80,43.20,1.00,0.00,1.00 -21,-76.80,-43.20,1.00,0.00,1.00 -22,110.40,43.20,1.00,0.00,1.00 -23,-62.40,-43.20,1.00,0.00,1.00 -24,124.80,38.40,1.00,0.00,1.00 -25,-52.80,-38.40,1.00,0.00,1.00 -26,134.40,33.60,1.00,0.00,1.00 -27,-38.40,-33.60,1.00,0.00,1.00 -28,144.00,28.80,1.00,0.00,1.00 -29,-33.60,-28.80,1.00,0.00,1.00 -30,153.60,24.00,1.00,0.00,1.00 -31,-24.00,-19.20,1.00,0.00,1.00 -32,158.40,19.20,1.00,0.00,1.00 -33,-14.40,-14.40,1.00,0.00,1.00 -34,168.00,9.60,1.00,0.00,1.00 -35,-9.60,-9.60,1.00,0.00,1.00 -36,172.80,4.80,1.00,0.00,1.00 -37,-0.00,-0.00,1.00,0.00,1.00 -38,-177.60,-0.00,1.00,0.00,1.00 -39,4.80,4.80,1.00,0.00,1.00 -40,-172.80,-9.60,1.00,0.00,1.00 -41,14.40,9.60,1.00,0.00,1.00 -42,-163.20,-14.40,1.00,0.00,1.00 -43,19.20,19.20,1.00,0.00,1.00 -44,-158.40,-19.20,1.00,0.00,1.00 -45,28.80,24.00,1.00,0.00,1.00 -46,-148.80,-28.80,1.00,0.00,1.00 -47,33.60,28.80,1.00,0.00,1.00 -48,-139.20,-33.60,1.00,0.00,1.00 -49,43.20,33.60,1.00,0.00,1.00 -50,-129.60,-38.40,1.00,0.00,1.00 -51,57.60,38.40,1.00,0.00,1.00 -52,-120.00,-43.20,1.00,0.00,1.00 -53,67.20,43.20,1.00,0.00,1.00 -54,-105.60,-43.20,1.00,0.00,1.00 -55,81.60,43.20,1.00,0.00,1.00 -56,-91.20,-43.20,1.00,0.00,1.00 -57,96.00,43.20,1.00,0.00,1.00 -58,-76.80,-43.20,1.00,0.00,1.00 -59,110.40,43.20,1.00,0.00,1.00 -60,-67.20,-43.20,1.00,0.00,1.00 -61,120.00,38.40,1.00,0.00,1.00 -62,-52.80,-38.40,1.00,0.00,1.00 -63,129.60,38.40,1.00,0.00,1.00 -64,-43.20,-33.60,1.00,0.00,1.00 -65,144.00,33.60,1.00,0.00,1.00 -66,-33.60,-28.80,1.00,0.00,1.00 -67,148.80,24.00,1.00,0.00,1.00 -68,-24.00,-24.00,1.00,0.00,1.00 -69,158.40,19.20,1.00,0.00,1.00 -70,-19.20,-14.40,1.00,0.00,1.00 -71,168.00,14.40,1.00,0.00,1.00 -72,-9.60,-9.60,1.00,0.00,1.00 -73,172.80,4.80,1.00,0.00,1.00 -74,-4.80,-4.80,1.00,0.00,1.00 -75,0.00,0.00,1.00,0.00,1.00 -76,-177.60,-4.80,1.00,0.00,1.00 -77,9.60,4.80,1.00,0.00,1.00 -78,-168.00,-9.60,1.00,0.00,1.00 -79,14.40,14.40,1.00,0.00,1.00 -80,-163.20,-14.40,1.00,0.00,1.00 -81,24.00,19.20,1.00,0.00,1.00 -82,-153.60,-19.20,1.00,0.00,1.00 -83,28.80,24.00,1.00,0.00,1.00 -84,-144.00,-24.00,1.00,0.00,1.00 -85,38.40,28.80,1.00,0.00,1.00 -86,-134.40,-28.80,1.00,0.00,1.00 -87,48.00,33.60,1.00,0.00,1.00 -88,-124.80,-33.60,1.00,0.00,1.00 -89,62.40,38.40,1.00,0.00,1.00 -90,-115.20,-38.40,1.00,0.00,1.00 -91,72.00,38.40,1.00,0.00,1.00 -92,-100.80,-38.40,1.00,0.00,1.00 -93,86.40,38.40,1.00,0.00,1.00 -94,-86.40,-38.40,1.00,0.00,1.00 -95,96.00,38.40,1.00,0.00,1.00 -96,-76.80,-38.40,1.00,0.00,1.00 -97,110.40,38.40,1.00,0.00,1.00 -98,-62.40,-38.40,1.00,0.00,1.00 -99,120.00,33.60,1.00,0.00,1.00 -100,-52.80,-33.60,1.00,0.00,1.00 -101,134.40,33.60,1.00,0.00,1.00 -102,-43.20,-28.80,1.00,0.00,1.00 -103,144.00,28.80,1.00,0.00,1.00 -104,-33.60,-24.00,1.00,0.00,1.00 -105,148.80,24.00,1.00,0.00,1.00 -106,-24.00,-19.20,1.00,0.00,1.00 -107,158.40,14.40,1.00,0.00,1.00 -108,-19.20,-14.40,1.00,0.00,1.00 -109,168.00,9.60,1.00,0.00,1.00 -110,-9.60,-9.60,1.00,0.00,1.00 -111,172.80,4.80,1.00,0.00,1.00 -112,-0.00,-0.00,1.00,0.00,1.00 -113,-177.60,-0.00,1.00,0.00,1.00 -114,4.80,4.80,1.00,0.00,1.00 -115,-172.80,-9.60,1.00,0.00,1.00 -116,14.40,9.60,1.00,0.00,1.00 -117,-163.20,-14.40,1.00,0.00,1.00 -118,19.20,14.40,1.00,0.00,1.00 -119,-153.60,-19.20,1.00,0.00,1.00 -120,28.80,24.00,1.00,0.00,1.00 -121,-148.80,-24.00,1.00,0.00,1.00 -122,38.40,28.80,1.00,0.00,1.00 -123,-139.20,-28.80,1.00,0.00,1.00 -124,48.00,33.60,1.00,0.00,1.00 -125,-124.80,-33.60,1.00,0.00,1.00 -126,57.60,33.60,1.00,0.00,1.00 -127,-115.20,-38.40,1.00,0.00,1.00 -128,72.00,38.40,1.00,0.00,1.00 -129,-105.60,-38.40,1.00,0.00,1.00 -130,81.60,38.40,1.00,0.00,1.00 -131,-91.20,-38.40,1.00,0.00,1.00 -132,96.00,38.40,1.00,0.00,1.00 -133,-76.80,-38.40,1.00,0.00,1.00 -134,105.60,38.40,1.00,0.00,1.00 -135,-67.20,-38.40,1.00,0.00,1.00 -136,120.00,38.40,1.00,0.00,1.00 -137,-57.60,-33.60,1.00,0.00,1.00 -138,129.60,33.60,1.00,0.00,1.00 -139,-43.20,-28.80,1.00,0.00,1.00 -140,139.20,28.80,1.00,0.00,1.00 -141,-33.60,-24.00,1.00,0.00,1.00 -142,148.80,24.00,1.00,0.00,1.00 -143,-28.80,-19.20,1.00,0.00,1.00 -144,158.40,19.20,1.00,0.00,1.00 -145,-19.20,-14.40,1.00,0.00,1.00 -146,163.20,14.40,1.00,0.00,1.00 -147,-9.60,-9.60,1.00,0.00,1.00 -148,172.80,4.80,1.00,0.00,1.00 -149,-4.80,-4.80,1.00,0.00,1.00 -150,0.00,0.00,1.00,0.00,1.00 -151,-177.60,-4.80,1.00,0.00,1.00 -152,9.60,4.80,1.00,0.00,1.00 -153,-168.00,-9.60,1.00,0.00,1.00 -154,14.40,9.60,1.00,0.00,1.00 -155,-158.40,-14.40,1.00,0.00,1.00 -156,24.00,14.40,1.00,0.00,1.00 -157,-153.60,-19.20,1.00,0.00,1.00 -158,33.60,19.20,1.00,0.00,1.00 -159,-144.00,-24.00,1.00,0.00,1.00 -160,43.20,24.00,1.00,0.00,1.00 -161,-134.40,-28.80,1.00,0.00,1.00 -162,52.80,28.80,1.00,0.00,1.00 -163,-124.80,-28.80,1.00,0.00,1.00 -164,62.40,33.60,1.00,0.00,1.00 -165,-110.40,-33.60,1.00,0.00,1.00 -166,72.00,33.60,1.00,0.00,1.00 -167,-100.80,-33.60,1.00,0.00,1.00 -168,86.40,33.60,1.00,0.00,1.00 -169,-86.40,-33.60,1.00,0.00,1.00 -170,96.00,33.60,1.00,0.00,1.00 -171,-76.80,-33.60,1.00,0.00,1.00 -172,110.40,33.60,1.00,0.00,1.00 -173,-67.20,-33.60,1.00,0.00,1.00 -174,120.00,33.60,1.00,0.00,1.00 -175,-52.80,-28.80,1.00,0.00,1.00 -176,129.60,28.80,1.00,0.00,1.00 -177,-43.20,-28.80,1.00,0.00,1.00 -178,139.20,24.00,1.00,0.00,1.00 -179,-33.60,-24.00,1.00,0.00,1.00 -180,148.80,19.20,1.00,0.00,1.00 -181,-24.00,-19.20,1.00,0.00,1.00 -182,158.40,14.40,1.00,0.00,1.00 -183,-19.20,-14.40,1.00,0.00,1.00 -184,168.00,9.60,1.00,0.00,1.00 -185,-9.60,-4.80,1.00,0.00,1.00 -186,172.80,4.80,1.00,0.00,1.00 -187,-0.00,-0.00,1.00,0.00,1.00 -188,-177.60,-0.00,1.00,0.00,1.00 -189,4.80,4.80,1.00,0.00,1.00 -190,-168.00,-4.80,1.00,0.00,1.00 -191,14.40,9.60,1.00,0.00,1.00 -192,-163.20,-14.40,1.00,0.00,1.00 -193,24.00,14.40,1.00,0.00,1.00 -194,-153.60,-19.20,1.00,0.00,1.00 -195,28.80,19.20,1.00,0.00,1.00 -196,-144.00,-24.00,1.00,0.00,1.00 -197,38.40,24.00,1.00,0.00,1.00 -198,-134.40,-28.80,1.00,0.00,1.00 -199,48.00,28.80,1.00,0.00,1.00 -200,-124.80,-28.80,1.00,0.00,1.00 -201,62.40,33.60,1.00,0.00,1.00 -202,-115.20,-33.60,1.00,0.00,1.00 -203,72.00,33.60,1.00,0.00,1.00 -204,-100.80,-33.60,1.00,0.00,1.00 -205,81.60,33.60,1.00,0.00,1.00 -206,-91.20,-33.60,1.00,0.00,1.00 -207,96.00,33.60,1.00,0.00,1.00 -208,-81.60,-33.60,1.00,0.00,1.00 -209,105.60,33.60,1.00,0.00,1.00 -210,-67.20,-33.60,1.00,0.00,1.00 -211,115.20,33.60,1.00,0.00,1.00 -212,-57.60,-28.80,1.00,0.00,1.00 -213,129.60,28.80,1.00,0.00,1.00 -214,-48.00,-28.80,1.00,0.00,1.00 -215,139.20,24.00,1.00,0.00,1.00 -216,-38.40,-24.00,1.00,0.00,1.00 -217,148.80,19.20,1.00,0.00,1.00 -218,-28.80,-19.20,1.00,0.00,1.00 -219,153.60,14.40,1.00,0.00,1.00 -220,-19.20,-14.40,1.00,0.00,1.00 -221,163.20,9.60,1.00,0.00,1.00 -222,-9.60,-9.60,1.00,0.00,1.00 -223,172.80,4.80,1.00,0.00,1.00 -224,-4.80,-4.80,1.00,0.00,1.00 -225,0.00,0.00,1.00,0.00,1.00 -226,-177.60,-4.80,1.00,0.00,1.00 -227,9.60,4.80,1.00,0.00,1.00 -228,-168.00,-9.60,1.00,0.00,1.00 -229,14.40,9.60,1.00,0.00,1.00 -230,-158.40,-9.60,1.00,0.00,1.00 -231,24.00,14.40,1.00,0.00,1.00 -232,-148.80,-14.40,1.00,0.00,1.00 -233,33.60,19.20,1.00,0.00,1.00 -234,-139.20,-19.20,1.00,0.00,1.00 -235,43.20,24.00,1.00,0.00,1.00 -236,-129.60,-24.00,1.00,0.00,1.00 -237,52.80,24.00,1.00,0.00,1.00 -238,-120.00,-28.80,1.00,0.00,1.00 -239,62.40,28.80,1.00,0.00,1.00 -240,-110.40,-28.80,1.00,0.00,1.00 -241,76.80,28.80,1.00,0.00,1.00 -242,-100.80,-28.80,1.00,0.00,1.00 -243,86.40,28.80,1.00,0.00,1.00 -244,-86.40,-28.80,1.00,0.00,1.00 -245,96.00,28.80,1.00,0.00,1.00 -246,-76.80,-28.80,1.00,0.00,1.00 -247,105.60,28.80,1.00,0.00,1.00 -248,-67.20,-28.80,1.00,0.00,1.00 -249,120.00,28.80,1.00,0.00,1.00 -250,-57.60,-24.00,1.00,0.00,1.00 -251,129.60,24.00,1.00,0.00,1.00 -252,-48.00,-24.00,1.00,0.00,1.00 -253,139.20,19.20,1.00,0.00,1.00 -254,-38.40,-19.20,1.00,0.00,1.00 -255,148.80,19.20,1.00,0.00,1.00 -256,-28.80,-14.40,1.00,0.00,1.00 -257,158.40,14.40,1.00,0.00,1.00 -258,-19.20,-9.60,1.00,0.00,1.00 -259,163.20,9.60,1.00,0.00,1.00 -260,-9.60,-4.80,1.00,0.00,1.00 -261,172.80,4.80,1.00,0.00,1.00 -262,-0.00,-0.00,1.00,0.00,1.00 -263,-177.60,-0.00,1.00,0.00,1.00 -264,4.80,4.80,1.00,0.00,1.00 -265,-168.00,-4.80,1.00,0.00,1.00 -266,14.40,9.60,1.00,0.00,1.00 -267,-163.20,-9.60,1.00,0.00,1.00 -268,24.00,14.40,1.00,0.00,1.00 -269,-153.60,-14.40,1.00,0.00,1.00 -270,33.60,19.20,1.00,0.00,1.00 -271,-144.00,-19.20,1.00,0.00,1.00 -272,43.20,19.20,1.00,0.00,1.00 -273,-134.40,-24.00,1.00,0.00,1.00 -274,52.80,24.00,1.00,0.00,1.00 -275,-124.80,-24.00,1.00,0.00,1.00 -276,62.40,28.80,1.00,0.00,1.00 -277,-115.20,-28.80,1.00,0.00,1.00 -278,72.00,28.80,1.00,0.00,1.00 -279,-100.80,-28.80,1.00,0.00,1.00 -280,81.60,28.80,1.00,0.00,1.00 -281,-91.20,-28.80,1.00,0.00,1.00 -282,96.00,28.80,1.00,0.00,1.00 -283,-81.60,-28.80,1.00,0.00,1.00 -284,105.60,28.80,1.00,0.00,1.00 -285,-67.20,-28.80,1.00,0.00,1.00 -286,115.20,28.80,1.00,0.00,1.00 -287,-57.60,-28.80,1.00,0.00,1.00 -288,124.80,24.00,1.00,0.00,1.00 -289,-48.00,-24.00,1.00,0.00,1.00 -290,134.40,24.00,1.00,0.00,1.00 -291,-38.40,-19.20,1.00,0.00,1.00 -292,144.00,19.20,1.00,0.00,1.00 -293,-28.80,-14.40,1.00,0.00,1.00 -294,153.60,14.40,1.00,0.00,1.00 -295,-19.20,-9.60,1.00,0.00,1.00 -296,163.20,9.60,1.00,0.00,1.00 -297,-14.40,-9.60,1.00,0.00,1.00 -298,172.80,4.80,1.00,0.00,1.00 -299,-4.80,-4.80,1.00,0.00,1.00 -300,0.00,0.00,1.00,0.00,1.00 -301,-177.60,-0.00,1.00,0.00,1.00 -302,9.60,4.80,1.00,0.00,1.00 -303,-168.00,-4.80,1.00,0.00,1.00 -304,19.20,9.60,1.00,0.00,1.00 -305,-158.40,-9.60,1.00,0.00,1.00 -306,24.00,14.40,1.00,0.00,1.00 -307,-148.80,-14.40,1.00,0.00,1.00 -308,33.60,14.40,1.00,0.00,1.00 -309,-139.20,-19.20,1.00,0.00,1.00 -310,43.20,19.20,1.00,0.00,1.00 -311,-129.60,-19.20,1.00,0.00,1.00 -312,52.80,19.20,1.00,0.00,1.00 -313,-120.00,-24.00,1.00,0.00,1.00 -314,67.20,24.00,1.00,0.00,1.00 -315,-110.40,-24.00,1.00,0.00,1.00 -316,76.80,24.00,1.00,0.00,1.00 -317,-100.80,-24.00,1.00,0.00,1.00 -318,86.40,24.00,1.00,0.00,1.00 -319,-86.40,-24.00,1.00,0.00,1.00 -320,96.00,24.00,1.00,0.00,1.00 -321,-76.80,-24.00,1.00,0.00,1.00 -322,105.60,24.00,1.00,0.00,1.00 -323,-67.20,-24.00,1.00,0.00,1.00 -324,115.20,24.00,1.00,0.00,1.00 -325,-57.60,-24.00,1.00,0.00,1.00 -326,129.60,19.20,1.00,0.00,1.00 -327,-48.00,-19.20,1.00,0.00,1.00 -328,139.20,19.20,1.00,0.00,1.00 -329,-38.40,-14.40,1.00,0.00,1.00 -330,148.80,14.40,1.00,0.00,1.00 -331,-28.80,-14.40,1.00,0.00,1.00 -332,153.60,9.60,1.00,0.00,1.00 -333,-19.20,-9.60,1.00,0.00,1.00 -334,163.20,9.60,1.00,0.00,1.00 -335,-9.60,-4.80,1.00,0.00,1.00 -336,172.80,4.80,1.00,0.00,1.00 -337,-0.00,-0.00,1.00,0.00,1.00 -338,-177.60,-0.00,1.00,0.00,1.00 -339,4.80,4.80,1.00,0.00,1.00 -340,-168.00,-4.80,1.00,0.00,1.00 -341,14.40,9.60,1.00,0.00,1.00 -342,-158.40,-9.60,1.00,0.00,1.00 -343,24.00,9.60,1.00,0.00,1.00 -344,-153.60,-14.40,1.00,0.00,1.00 -345,33.60,14.40,1.00,0.00,1.00 -346,-144.00,-14.40,1.00,0.00,1.00 -347,43.20,19.20,1.00,0.00,1.00 -348,-134.40,-19.20,1.00,0.00,1.00 -349,52.80,19.20,1.00,0.00,1.00 -350,-124.80,-24.00,1.00,0.00,1.00 -351,62.40,24.00,1.00,0.00,1.00 -352,-110.40,-24.00,1.00,0.00,1.00 -353,72.00,24.00,1.00,0.00,1.00 -354,-100.80,-24.00,1.00,0.00,1.00 -355,81.60,24.00,1.00,0.00,1.00 -356,-91.20,-24.00,1.00,0.00,1.00 -357,96.00,24.00,1.00,0.00,1.00 -358,-81.60,-24.00,1.00,0.00,1.00 -359,105.60,24.00,1.00,0.00,1.00 -360,-72.00,-24.00,1.00,0.00,1.00 -361,115.20,24.00,1.00,0.00,1.00 -362,-57.60,-24.00,1.00,0.00,1.00 -363,124.80,19.20,1.00,0.00,1.00 -364,-48.00,-19.20,1.00,0.00,1.00 -365,134.40,19.20,1.00,0.00,1.00 -366,-38.40,-19.20,1.00,0.00,1.00 -367,144.00,14.40,1.00,0.00,1.00 -368,-28.80,-14.40,1.00,0.00,1.00 -369,153.60,14.40,1.00,0.00,1.00 -370,-24.00,-9.60,1.00,0.00,1.00 -371,163.20,9.60,1.00,0.00,1.00 -372,-14.40,-4.80,1.00,0.00,1.00 -373,172.80,4.80,1.00,0.00,1.00 -374,-4.80,-0.00,1.00,0.00,1.00 -375,0.00,0.00,1.00,0.00,1.00 -376,-177.60,-0.00,1.00,0.00,1.00 -377,9.60,4.80,1.00,0.00,1.00 -378,-168.00,-4.80,1.00,0.00,1.00 -379,19.20,4.80,1.00,0.00,1.00 -380,-158.40,-9.60,1.00,0.00,1.00 -381,28.80,9.60,1.00,0.00,1.00 -382,-148.80,-9.60,1.00,0.00,1.00 -383,38.40,14.40,1.00,0.00,1.00 -384,-139.20,-14.40,1.00,0.00,1.00 -385,48.00,14.40,1.00,0.00,1.00 -386,-129.60,-14.40,1.00,0.00,1.00 -387,57.60,19.20,1.00,0.00,1.00 -388,-120.00,-19.20,1.00,0.00,1.00 -389,67.20,19.20,1.00,0.00,1.00 -390,-110.40,-19.20,1.00,0.00,1.00 -391,76.80,19.20,1.00,0.00,1.00 -392,-100.80,-19.20,1.00,0.00,1.00 -393,86.40,19.20,1.00,0.00,1.00 -394,-86.40,-19.20,1.00,0.00,1.00 -395,96.00,19.20,1.00,0.00,1.00 -396,-76.80,-19.20,1.00,0.00,1.00 -397,105.60,19.20,1.00,0.00,1.00 -398,-67.20,-19.20,1.00,0.00,1.00 -399,115.20,19.20,1.00,0.00,1.00 -400,-57.60,-19.20,1.00,0.00,1.00 -401,124.80,19.20,1.00,0.00,1.00 -402,-48.00,-14.40,1.00,0.00,1.00 -403,134.40,14.40,1.00,0.00,1.00 -404,-38.40,-14.40,1.00,0.00,1.00 -405,144.00,14.40,1.00,0.00,1.00 -406,-28.80,-9.60,1.00,0.00,1.00 -407,153.60,9.60,1.00,0.00,1.00 -408,-19.20,-9.60,1.00,0.00,1.00 -409,163.20,4.80,1.00,0.00,1.00 -410,-9.60,-4.80,1.00,0.00,1.00 -411,172.80,4.80,1.00,0.00,1.00 -412,-0.00,-0.00,1.00,0.00,1.00 -413,-177.60,-0.00,1.00,0.00,1.00 -414,4.80,4.80,1.00,0.00,1.00 -415,-168.00,-4.80,1.00,0.00,1.00 -416,14.40,4.80,1.00,0.00,1.00 -417,-158.40,-9.60,1.00,0.00,1.00 -418,24.00,9.60,1.00,0.00,1.00 -419,-148.80,-9.60,1.00,0.00,1.00 -420,33.60,14.40,1.00,0.00,1.00 -421,-139.20,-14.40,1.00,0.00,1.00 -422,43.20,14.40,1.00,0.00,1.00 -423,-129.60,-14.40,1.00,0.00,1.00 -424,52.80,19.20,1.00,0.00,1.00 -425,-120.00,-19.20,1.00,0.00,1.00 -426,62.40,19.20,1.00,0.00,1.00 -427,-110.40,-19.20,1.00,0.00,1.00 -428,72.00,19.20,1.00,0.00,1.00 -429,-100.80,-19.20,1.00,0.00,1.00 -430,81.60,19.20,1.00,0.00,1.00 -431,-91.20,-19.20,1.00,0.00,1.00 -432,96.00,19.20,1.00,0.00,1.00 -433,-81.60,-19.20,1.00,0.00,1.00 -434,105.60,19.20,1.00,0.00,1.00 -435,-72.00,-19.20,1.00,0.00,1.00 -436,115.20,19.20,1.00,0.00,1.00 -437,-62.40,-19.20,1.00,0.00,1.00 -438,124.80,19.20,1.00,0.00,1.00 -439,-52.80,-14.40,1.00,0.00,1.00 -440,134.40,14.40,1.00,0.00,1.00 -441,-43.20,-14.40,1.00,0.00,1.00 -442,144.00,14.40,1.00,0.00,1.00 -443,-33.60,-9.60,1.00,0.00,1.00 -444,153.60,9.60,1.00,0.00,1.00 -445,-24.00,-9.60,1.00,0.00,1.00 -446,163.20,4.80,1.00,0.00,1.00 -447,-14.40,-4.80,1.00,0.00,1.00 -448,172.80,4.80,1.00,0.00,1.00 -449,-4.80,-0.00,1.00,0.00,1.00 -450,0.00,0.00,1.00,0.00,1.00 -451,-177.60,-0.00,1.00,0.00,1.00 -452,9.60,4.80,1.00,0.00,1.00 -453,-168.00,-4.80,1.00,0.00,1.00 -454,19.20,4.80,1.00,0.00,1.00 -455,-158.40,-4.80,1.00,0.00,1.00 -456,28.80,9.60,1.00,0.00,1.00 -457,-148.80,-9.60,1.00,0.00,1.00 -458,38.40,9.60,1.00,0.00,1.00 -459,-139.20,-9.60,1.00,0.00,1.00 -460,48.00,9.60,1.00,0.00,1.00 -461,-129.60,-14.40,1.00,0.00,1.00 -462,57.60,14.40,1.00,0.00,1.00 -463,-120.00,-14.40,1.00,0.00,1.00 -464,67.20,14.40,1.00,0.00,1.00 -465,-110.40,-14.40,1.00,0.00,1.00 -466,76.80,14.40,1.00,0.00,1.00 -467,-100.80,-14.40,1.00,0.00,1.00 -468,86.40,14.40,1.00,0.00,1.00 -469,-86.40,-14.40,1.00,0.00,1.00 -470,96.00,14.40,1.00,0.00,1.00 -471,-76.80,-14.40,1.00,0.00,1.00 -472,105.60,14.40,1.00,0.00,1.00 -473,-67.20,-14.40,1.00,0.00,1.00 -474,115.20,14.40,1.00,0.00,1.00 -475,-57.60,-14.40,1.00,0.00,1.00 -476,124.80,14.40,1.00,0.00,1.00 -477,-48.00,-14.40,1.00,0.00,1.00 -478,134.40,9.60,1.00,0.00,1.00 -479,-38.40,-9.60,1.00,0.00,1.00 -480,144.00,9.60,1.00,0.00,1.00 -481,-28.80,-9.60,1.00,0.00,1.00 -482,153.60,4.80,1.00,0.00,1.00 -483,-19.20,-4.80,1.00,0.00,1.00 -484,163.20,4.80,1.00,0.00,1.00 -485,-9.60,-4.80,1.00,0.00,1.00 -486,172.80,0.00,1.00,0.00,1.00 -487,-0.00,-0.00,1.00,0.00,1.00 -488,-177.60,-0.00,1.00,0.00,1.00 -489,4.80,0.00,1.00,0.00,1.00 -490,-168.00,-4.80,1.00,0.00,1.00 -491,14.40,4.80,1.00,0.00,1.00 -492,-158.40,-4.80,1.00,0.00,1.00 -493,24.00,4.80,1.00,0.00,1.00 -494,-148.80,-9.60,1.00,0.00,1.00 -495,33.60,9.60,1.00,0.00,1.00 -496,-139.20,-9.60,1.00,0.00,1.00 -497,43.20,9.60,1.00,0.00,1.00 -498,-129.60,-14.40,1.00,0.00,1.00 -499,52.80,14.40,1.00,0.00,1.00 -500,-120.00,-14.40,1.00,0.00,1.00 -501,62.40,14.40,1.00,0.00,1.00 -502,-110.40,-14.40,1.00,0.00,1.00 -503,72.00,14.40,1.00,0.00,1.00 -504,-100.80,-14.40,1.00,0.00,1.00 -505,81.60,14.40,1.00,0.00,1.00 -506,-91.20,-14.40,1.00,0.00,1.00 -507,96.00,14.40,1.00,0.00,1.00 -508,-81.60,-14.40,1.00,0.00,1.00 -509,105.60,14.40,1.00,0.00,1.00 -510,-72.00,-14.40,1.00,0.00,1.00 -511,115.20,14.40,1.00,0.00,1.00 -512,-62.40,-14.40,1.00,0.00,1.00 -513,124.80,14.40,1.00,0.00,1.00 -514,-52.80,-14.40,1.00,0.00,1.00 -515,134.40,9.60,1.00,0.00,1.00 -516,-43.20,-9.60,1.00,0.00,1.00 -517,144.00,9.60,1.00,0.00,1.00 -518,-33.60,-9.60,1.00,0.00,1.00 -519,153.60,9.60,1.00,0.00,1.00 -520,-24.00,-4.80,1.00,0.00,1.00 -521,163.20,4.80,1.00,0.00,1.00 -522,-14.40,-4.80,1.00,0.00,1.00 -523,172.80,4.80,1.00,0.00,1.00 -524,-4.80,-0.00,1.00,0.00,1.00 -525,0.00,0.00,1.00,0.00,1.00 -526,-177.60,-0.00,1.00,0.00,1.00 -527,9.60,0.00,1.00,0.00,1.00 -528,-168.00,-4.80,1.00,0.00,1.00 -529,19.20,4.80,1.00,0.00,1.00 -530,-158.40,-4.80,1.00,0.00,1.00 -531,28.80,4.80,1.00,0.00,1.00 -532,-148.80,-4.80,1.00,0.00,1.00 -533,38.40,4.80,1.00,0.00,1.00 -534,-139.20,-9.60,1.00,0.00,1.00 -535,48.00,9.60,1.00,0.00,1.00 -536,-129.60,-9.60,1.00,0.00,1.00 -537,57.60,9.60,1.00,0.00,1.00 -538,-120.00,-9.60,1.00,0.00,1.00 -539,67.20,9.60,1.00,0.00,1.00 -540,-110.40,-9.60,1.00,0.00,1.00 -541,76.80,9.60,1.00,0.00,1.00 -542,-100.80,-9.60,1.00,0.00,1.00 -543,86.40,9.60,1.00,0.00,1.00 -544,-86.40,-9.60,1.00,0.00,1.00 -545,96.00,9.60,1.00,0.00,1.00 -546,-76.80,-9.60,1.00,0.00,1.00 -547,105.60,9.60,1.00,0.00,1.00 -548,-67.20,-9.60,1.00,0.00,1.00 -549,115.20,9.60,1.00,0.00,1.00 -550,-57.60,-9.60,1.00,0.00,1.00 -551,124.80,9.60,1.00,0.00,1.00 -552,-48.00,-9.60,1.00,0.00,1.00 -553,134.40,9.60,1.00,0.00,1.00 -554,-38.40,-9.60,1.00,0.00,1.00 -555,144.00,4.80,1.00,0.00,1.00 -556,-28.80,-4.80,1.00,0.00,1.00 -557,153.60,4.80,1.00,0.00,1.00 -558,-19.20,-4.80,1.00,0.00,1.00 -559,163.20,4.80,1.00,0.00,1.00 -560,-9.60,-0.00,1.00,0.00,1.00 -561,172.80,0.00,1.00,0.00,1.00 -562,-0.00,-0.00,1.00,0.00,1.00 -563,-177.60,-0.00,1.00,0.00,1.00 -564,4.80,0.00,1.00,0.00,1.00 -565,-168.00,-0.00,1.00,0.00,1.00 -566,14.40,4.80,1.00,0.00,1.00 -567,-158.40,-4.80,1.00,0.00,1.00 -568,24.00,4.80,1.00,0.00,1.00 -569,-148.80,-4.80,1.00,0.00,1.00 -570,33.60,4.80,1.00,0.00,1.00 -571,-139.20,-9.60,1.00,0.00,1.00 -572,43.20,9.60,1.00,0.00,1.00 -573,-129.60,-9.60,1.00,0.00,1.00 -574,52.80,9.60,1.00,0.00,1.00 -575,-120.00,-9.60,1.00,0.00,1.00 -576,62.40,9.60,1.00,0.00,1.00 -577,-110.40,-9.60,1.00,0.00,1.00 -578,72.00,9.60,1.00,0.00,1.00 -579,-100.80,-9.60,1.00,0.00,1.00 -580,81.60,9.60,1.00,0.00,1.00 -581,-91.20,-9.60,1.00,0.00,1.00 -582,96.00,9.60,1.00,0.00,1.00 -583,-81.60,-9.60,1.00,0.00,1.00 -584,105.60,9.60,1.00,0.00,1.00 -585,-72.00,-9.60,1.00,0.00,1.00 -586,115.20,9.60,1.00,0.00,1.00 -587,-62.40,-9.60,1.00,0.00,1.00 -588,124.80,9.60,1.00,0.00,1.00 -589,-52.80,-9.60,1.00,0.00,1.00 -590,134.40,9.60,1.00,0.00,1.00 -591,-43.20,-9.60,1.00,0.00,1.00 -592,144.00,4.80,1.00,0.00,1.00 -593,-33.60,-4.80,1.00,0.00,1.00 -594,153.60,4.80,1.00,0.00,1.00 -595,-24.00,-4.80,1.00,0.00,1.00 -596,163.20,4.80,1.00,0.00,1.00 -597,-14.40,-4.80,1.00,0.00,1.00 -598,172.80,0.00,1.00,0.00,1.00 -599,-4.80,-0.00,1.00,0.00,1.00 -600,0.00,0.00,1.00,0.00,1.00 -601,-177.60,-0.00,1.00,0.00,1.00 -602,9.60,0.00,1.00,0.00,1.00 -603,-168.00,-0.00,1.00,0.00,1.00 -604,19.20,0.00,1.00,0.00,1.00 -605,-158.40,-4.80,1.00,0.00,1.00 -606,28.80,4.80,1.00,0.00,1.00 -607,-148.80,-4.80,1.00,0.00,1.00 -608,38.40,4.80,1.00,0.00,1.00 -609,-139.20,-4.80,1.00,0.00,1.00 -610,48.00,4.80,1.00,0.00,1.00 -611,-129.60,-4.80,1.00,0.00,1.00 -612,57.60,4.80,1.00,0.00,1.00 -613,-120.00,-4.80,1.00,0.00,1.00 -614,67.20,4.80,1.00,0.00,1.00 -615,-110.40,-4.80,1.00,0.00,1.00 -616,76.80,4.80,1.00,0.00,1.00 -617,-100.80,-4.80,1.00,0.00,1.00 -618,86.40,4.80,1.00,0.00,1.00 -619,-86.40,-4.80,1.00,0.00,1.00 -620,96.00,4.80,1.00,0.00,1.00 -621,-76.80,-4.80,1.00,0.00,1.00 -622,105.60,4.80,1.00,0.00,1.00 -623,-67.20,-4.80,1.00,0.00,1.00 -624,115.20,4.80,1.00,0.00,1.00 -625,-57.60,-4.80,1.00,0.00,1.00 -626,124.80,4.80,1.00,0.00,1.00 -627,-48.00,-4.80,1.00,0.00,1.00 -628,134.40,4.80,1.00,0.00,1.00 -629,-38.40,-4.80,1.00,0.00,1.00 -630,144.00,4.80,1.00,0.00,1.00 -631,-28.80,-4.80,1.00,0.00,1.00 -632,153.60,4.80,1.00,0.00,1.00 -633,-19.20,-4.80,1.00,0.00,1.00 -634,163.20,0.00,1.00,0.00,1.00 -635,-9.60,-0.00,1.00,0.00,1.00 -636,172.80,0.00,1.00,0.00,1.00 -637,-0.00,-0.00,1.00,0.00,1.00 -638,-177.60,-0.00,1.00,0.00,1.00 -639,4.80,0.00,1.00,0.00,1.00 -640,-168.00,-0.00,1.00,0.00,1.00 -641,14.40,0.00,1.00,0.00,1.00 -642,-158.40,-4.80,1.00,0.00,1.00 -643,24.00,4.80,1.00,0.00,1.00 -644,-148.80,-4.80,1.00,0.00,1.00 -645,33.60,4.80,1.00,0.00,1.00 -646,-139.20,-4.80,1.00,0.00,1.00 -647,43.20,4.80,1.00,0.00,1.00 -648,-129.60,-4.80,1.00,0.00,1.00 -649,52.80,4.80,1.00,0.00,1.00 -650,-120.00,-4.80,1.00,0.00,1.00 -651,62.40,4.80,1.00,0.00,1.00 -652,-110.40,-4.80,1.00,0.00,1.00 -653,72.00,4.80,1.00,0.00,1.00 -654,-100.80,-4.80,1.00,0.00,1.00 -655,81.60,4.80,1.00,0.00,1.00 -656,-91.20,-4.80,1.00,0.00,1.00 -657,96.00,4.80,1.00,0.00,1.00 -658,-81.60,-4.80,1.00,0.00,1.00 -659,105.60,4.80,1.00,0.00,1.00 -660,-72.00,-4.80,1.00,0.00,1.00 -661,115.20,4.80,1.00,0.00,1.00 -662,-62.40,-4.80,1.00,0.00,1.00 -663,124.80,4.80,1.00,0.00,1.00 -664,-52.80,-4.80,1.00,0.00,1.00 -665,134.40,4.80,1.00,0.00,1.00 -666,-43.20,-4.80,1.00,0.00,1.00 -667,144.00,4.80,1.00,0.00,1.00 -668,-33.60,-4.80,1.00,0.00,1.00 -669,153.60,4.80,1.00,0.00,1.00 -670,-24.00,-4.80,1.00,0.00,1.00 -671,163.20,0.00,1.00,0.00,1.00 -672,-14.40,-0.00,1.00,0.00,1.00 -673,172.80,0.00,1.00,0.00,1.00 -674,-4.80,-0.00,1.00,0.00,1.00 -675,0.00,0.00,1.00,0.00,1.00 -676,-177.60,-0.00,1.00,0.00,1.00 -677,9.60,0.00,1.00,0.00,1.00 -678,-168.00,-0.00,1.00,0.00,1.00 -679,19.20,0.00,1.00,0.00,1.00 -680,-158.40,-0.00,1.00,0.00,1.00 -681,28.80,0.00,1.00,0.00,1.00 -682,-148.80,-0.00,1.00,0.00,1.00 -683,38.40,0.00,1.00,0.00,1.00 -684,-139.20,-0.00,1.00,0.00,1.00 -685,48.00,0.00,1.00,0.00,1.00 -686,-129.60,-0.00,1.00,0.00,1.00 -687,57.60,0.00,1.00,0.00,1.00 -688,-120.00,-0.00,1.00,0.00,1.00 -689,67.20,0.00,1.00,0.00,1.00 -690,-110.40,-0.00,1.00,0.00,1.00 -691,76.80,0.00,1.00,0.00,1.00 -692,-100.80,-0.00,1.00,0.00,1.00 -693,86.40,0.00,1.00,0.00,1.00 -694,-86.40,-0.00,1.00,0.00,1.00 -695,96.00,0.00,1.00,0.00,1.00 -696,-76.80,-0.00,1.00,0.00,1.00 -697,105.60,0.00,1.00,0.00,1.00 -698,-67.20,-0.00,1.00,0.00,1.00 -699,115.20,0.00,1.00,0.00,1.00 -700,-57.60,-0.00,1.00,0.00,1.00 -701,124.80,0.00,1.00,0.00,1.00 -702,-48.00,-0.00,1.00,0.00,1.00 -703,134.40,0.00,1.00,0.00,1.00 -704,-38.40,-0.00,1.00,0.00,1.00 -705,144.00,0.00,1.00,0.00,1.00 -706,-28.80,-0.00,1.00,0.00,1.00 -707,153.60,0.00,1.00,0.00,1.00 -708,-19.20,-0.00,1.00,0.00,1.00 -709,163.20,0.00,1.00,0.00,1.00 -710,-9.60,-0.00,1.00,0.00,1.00 -711,172.80,0.00,1.00,0.00,1.00 -712,-0.00,-0.00,1.00,0.00,1.00 -713,-177.60,-0.00,1.00,0.00,1.00 -714,4.80,0.00,1.00,0.00,1.00 -715,-168.00,-0.00,1.00,0.00,1.00 -716,14.40,0.00,1.00,0.00,1.00 -717,-158.40,-0.00,1.00,0.00,1.00 -718,24.00,0.00,1.00,0.00,1.00 -719,-148.80,-0.00,1.00,0.00,1.00 -720,33.60,0.00,1.00,0.00,1.00 -721,-139.20,-0.00,1.00,0.00,1.00 -722,43.20,0.00,1.00,0.00,1.00 -723,-129.60,-0.00,1.00,0.00,1.00 -724,52.80,0.00,1.00,0.00,1.00 -725,-120.00,-0.00,1.00,0.00,1.00 -726,62.40,0.00,1.00,0.00,1.00 -727,-110.40,-0.00,1.00,0.00,1.00 -728,72.00,0.00,1.00,0.00,1.00 -729,-100.80,-0.00,1.00,0.00,1.00 -730,81.60,0.00,1.00,0.00,1.00 -731,-91.20,-0.00,1.00,0.00,1.00 -732,96.00,0.00,1.00,0.00,1.00 -733,-81.60,-0.00,1.00,0.00,1.00 -734,105.60,0.00,1.00,0.00,1.00 -735,-72.00,-0.00,1.00,0.00,1.00 -736,115.20,0.00,1.00,0.00,1.00 -737,-62.40,-0.00,1.00,0.00,1.00 -738,124.80,0.00,1.00,0.00,1.00 -739,-52.80,-0.00,1.00,0.00,1.00 -740,134.40,0.00,1.00,0.00,1.00 -741,-43.20,-0.00,1.00,0.00,1.00 -742,144.00,0.00,1.00,0.00,1.00 -743,-33.60,-0.00,1.00,0.00,1.00 -744,153.60,0.00,1.00,0.00,1.00 -745,-24.00,-0.00,1.00,0.00,1.00 -746,163.20,0.00,1.00,0.00,1.00 -747,-14.40,-0.00,1.00,0.00,1.00 -748,172.80,0.00,1.00,0.00,1.00 -749,-4.80,-0.00,1.00,0.00,1.00 -750,0.00,0.00,1.00,0.00,1.00 -751,-177.60,0.00,1.00,0.00,1.00 -752,9.60,-0.00,1.00,0.00,1.00 -753,-168.00,0.00,1.00,0.00,1.00 -754,19.20,-0.00,1.00,0.00,1.00 -755,-158.40,0.00,1.00,0.00,1.00 -756,28.80,-0.00,1.00,0.00,1.00 -757,-148.80,0.00,1.00,0.00,1.00 -758,38.40,-0.00,1.00,0.00,1.00 -759,-139.20,0.00,1.00,0.00,1.00 -760,48.00,-0.00,1.00,0.00,1.00 -761,-129.60,0.00,1.00,0.00,1.00 -762,57.60,-4.80,1.00,0.00,1.00 -763,-120.00,4.80,1.00,0.00,1.00 -764,67.20,-4.80,1.00,0.00,1.00 -765,-110.40,4.80,1.00,0.00,1.00 -766,76.80,-4.80,1.00,0.00,1.00 -767,-100.80,4.80,1.00,0.00,1.00 -768,86.40,-4.80,1.00,0.00,1.00 -769,-86.40,4.80,1.00,0.00,1.00 -770,96.00,-4.80,1.00,0.00,1.00 -771,-76.80,4.80,1.00,0.00,1.00 -772,105.60,-4.80,1.00,0.00,1.00 -773,-67.20,4.80,1.00,0.00,1.00 -774,115.20,-4.80,1.00,0.00,1.00 -775,-57.60,4.80,1.00,0.00,1.00 -776,124.80,-4.80,1.00,0.00,1.00 -777,-48.00,0.00,1.00,0.00,1.00 -778,134.40,-0.00,1.00,0.00,1.00 -779,-38.40,0.00,1.00,0.00,1.00 -780,144.00,-0.00,1.00,0.00,1.00 -781,-28.80,0.00,1.00,0.00,1.00 -782,153.60,-0.00,1.00,0.00,1.00 -783,-19.20,0.00,1.00,0.00,1.00 -784,163.20,-0.00,1.00,0.00,1.00 -785,-9.60,0.00,1.00,0.00,1.00 -786,172.80,-0.00,1.00,0.00,1.00 -787,-0.00,0.00,1.00,0.00,1.00 -788,-177.60,0.00,1.00,0.00,1.00 -789,4.80,-0.00,1.00,0.00,1.00 -790,-168.00,0.00,1.00,0.00,1.00 -791,14.40,-0.00,1.00,0.00,1.00 -792,-158.40,0.00,1.00,0.00,1.00 -793,24.00,-0.00,1.00,0.00,1.00 -794,-148.80,0.00,1.00,0.00,1.00 -795,33.60,-0.00,1.00,0.00,1.00 -796,-139.20,0.00,1.00,0.00,1.00 -797,43.20,-0.00,1.00,0.00,1.00 -798,-129.60,0.00,1.00,0.00,1.00 -799,52.80,-4.80,1.00,0.00,1.00 -800,-120.00,4.80,1.00,0.00,1.00 -801,62.40,-4.80,1.00,0.00,1.00 -802,-110.40,4.80,1.00,0.00,1.00 -803,72.00,-4.80,1.00,0.00,1.00 -804,-100.80,4.80,1.00,0.00,1.00 -805,81.60,-4.80,1.00,0.00,1.00 -806,-91.20,4.80,1.00,0.00,1.00 -807,96.00,-4.80,1.00,0.00,1.00 -808,-81.60,4.80,1.00,0.00,1.00 -809,105.60,-4.80,1.00,0.00,1.00 -810,-72.00,4.80,1.00,0.00,1.00 -811,115.20,-4.80,1.00,0.00,1.00 -812,-62.40,4.80,1.00,0.00,1.00 -813,124.80,-4.80,1.00,0.00,1.00 -814,-52.80,0.00,1.00,0.00,1.00 -815,134.40,-0.00,1.00,0.00,1.00 -816,-43.20,0.00,1.00,0.00,1.00 -817,144.00,-0.00,1.00,0.00,1.00 -818,-33.60,0.00,1.00,0.00,1.00 -819,153.60,-0.00,1.00,0.00,1.00 -820,-24.00,0.00,1.00,0.00,1.00 -821,163.20,-0.00,1.00,0.00,1.00 -822,-14.40,0.00,1.00,0.00,1.00 -823,172.80,-0.00,1.00,0.00,1.00 -824,-4.80,0.00,1.00,0.00,1.00 -825,0.00,0.00,1.00,0.00,1.00 -826,-177.60,0.00,1.00,0.00,1.00 -827,9.60,-0.00,1.00,0.00,1.00 -828,-168.00,0.00,1.00,0.00,1.00 -829,19.20,-4.80,1.00,0.00,1.00 -830,-158.40,4.80,1.00,0.00,1.00 -831,28.80,-4.80,1.00,0.00,1.00 -832,-148.80,4.80,1.00,0.00,1.00 -833,38.40,-4.80,1.00,0.00,1.00 -834,-139.20,4.80,1.00,0.00,1.00 -835,48.00,-4.80,1.00,0.00,1.00 -836,-129.60,4.80,1.00,0.00,1.00 -837,57.60,-4.80,1.00,0.00,1.00 -838,-120.00,4.80,1.00,0.00,1.00 -839,67.20,-4.80,1.00,0.00,1.00 -840,-110.40,9.60,1.00,0.00,1.00 -841,76.80,-9.60,1.00,0.00,1.00 -842,-100.80,9.60,1.00,0.00,1.00 -843,86.40,-9.60,1.00,0.00,1.00 -844,-86.40,9.60,1.00,0.00,1.00 -845,96.00,-9.60,1.00,0.00,1.00 -846,-76.80,9.60,1.00,0.00,1.00 -847,105.60,-9.60,1.00,0.00,1.00 -848,-67.20,9.60,1.00,0.00,1.00 -849,115.20,-4.80,1.00,0.00,1.00 -850,-57.60,4.80,1.00,0.00,1.00 -851,124.80,-4.80,1.00,0.00,1.00 -852,-48.00,4.80,1.00,0.00,1.00 -853,134.40,-4.80,1.00,0.00,1.00 -854,-38.40,4.80,1.00,0.00,1.00 -855,144.00,-4.80,1.00,0.00,1.00 -856,-28.80,4.80,1.00,0.00,1.00 -857,153.60,-4.80,1.00,0.00,1.00 -858,-19.20,4.80,1.00,0.00,1.00 -859,163.20,-0.00,1.00,0.00,1.00 -860,-9.60,0.00,1.00,0.00,1.00 -861,172.80,-0.00,1.00,0.00,1.00 -862,-0.00,0.00,1.00,0.00,1.00 -863,-177.60,0.00,1.00,0.00,1.00 -864,4.80,-0.00,1.00,0.00,1.00 -865,-168.00,0.00,1.00,0.00,1.00 -866,14.40,-0.00,1.00,0.00,1.00 -867,-158.40,4.80,1.00,0.00,1.00 -868,24.00,-4.80,1.00,0.00,1.00 -869,-148.80,4.80,1.00,0.00,1.00 -870,33.60,-4.80,1.00,0.00,1.00 -871,-139.20,4.80,1.00,0.00,1.00 -872,43.20,-4.80,1.00,0.00,1.00 -873,-129.60,4.80,1.00,0.00,1.00 -874,52.80,-4.80,1.00,0.00,1.00 -875,-120.00,4.80,1.00,0.00,1.00 -876,62.40,-4.80,1.00,0.00,1.00 -877,-110.40,9.60,1.00,0.00,1.00 -878,72.00,-9.60,1.00,0.00,1.00 -879,-100.80,9.60,1.00,0.00,1.00 -880,81.60,-9.60,1.00,0.00,1.00 -881,-91.20,9.60,1.00,0.00,1.00 -882,96.00,-9.60,1.00,0.00,1.00 -883,-81.60,9.60,1.00,0.00,1.00 -884,105.60,-9.60,1.00,0.00,1.00 -885,-72.00,9.60,1.00,0.00,1.00 -886,115.20,-4.80,1.00,0.00,1.00 -887,-62.40,4.80,1.00,0.00,1.00 -888,124.80,-4.80,1.00,0.00,1.00 -889,-52.80,4.80,1.00,0.00,1.00 -890,134.40,-4.80,1.00,0.00,1.00 -891,-43.20,4.80,1.00,0.00,1.00 -892,144.00,-4.80,1.00,0.00,1.00 -893,-33.60,4.80,1.00,0.00,1.00 -894,153.60,-4.80,1.00,0.00,1.00 -895,-24.00,4.80,1.00,0.00,1.00 -896,163.20,-4.80,1.00,0.00,1.00 -897,-14.40,0.00,1.00,0.00,1.00 -898,172.80,-0.00,1.00,0.00,1.00 -899,-4.80,0.00,1.00,0.00,1.00 -900,0.00,0.00,1.00,0.00,1.00 -901,-177.60,0.00,1.00,0.00,1.00 -902,9.60,-0.00,1.00,0.00,1.00 -903,-168.00,4.80,1.00,0.00,1.00 -904,19.20,-4.80,1.00,0.00,1.00 -905,-158.40,4.80,1.00,0.00,1.00 -906,28.80,-4.80,1.00,0.00,1.00 -907,-148.80,4.80,1.00,0.00,1.00 -908,38.40,-9.60,1.00,0.00,1.00 -909,-139.20,9.60,1.00,0.00,1.00 -910,48.00,-9.60,1.00,0.00,1.00 -911,-129.60,9.60,1.00,0.00,1.00 -912,57.60,-9.60,1.00,0.00,1.00 -913,-120.00,9.60,1.00,0.00,1.00 -914,67.20,-9.60,1.00,0.00,1.00 -915,-110.40,9.60,1.00,0.00,1.00 -916,76.80,-14.40,1.00,0.00,1.00 -917,-100.80,14.40,1.00,0.00,1.00 -918,86.40,-14.40,1.00,0.00,1.00 -919,-86.40,14.40,1.00,0.00,1.00 -920,96.00,-14.40,1.00,0.00,1.00 -921,-76.80,14.40,1.00,0.00,1.00 -922,105.60,-14.40,1.00,0.00,1.00 -923,-67.20,9.60,1.00,0.00,1.00 -924,115.20,-9.60,1.00,0.00,1.00 -925,-57.60,9.60,1.00,0.00,1.00 -926,124.80,-9.60,1.00,0.00,1.00 -927,-48.00,9.60,1.00,0.00,1.00 -928,134.40,-9.60,1.00,0.00,1.00 -929,-38.40,9.60,1.00,0.00,1.00 -930,144.00,-9.60,1.00,0.00,1.00 -931,-28.80,4.80,1.00,0.00,1.00 -932,153.60,-4.80,1.00,0.00,1.00 -933,-19.20,4.80,1.00,0.00,1.00 -934,163.20,-4.80,1.00,0.00,1.00 -935,-9.60,4.80,1.00,0.00,1.00 -936,172.80,-0.00,1.00,0.00,1.00 -937,-0.00,0.00,1.00,0.00,1.00 -938,-177.60,0.00,1.00,0.00,1.00 -939,4.80,-0.00,1.00,0.00,1.00 -940,-168.00,4.80,1.00,0.00,1.00 -941,14.40,-4.80,1.00,0.00,1.00 -942,-158.40,4.80,1.00,0.00,1.00 -943,24.00,-4.80,1.00,0.00,1.00 -944,-148.80,4.80,1.00,0.00,1.00 -945,33.60,-9.60,1.00,0.00,1.00 -946,-139.20,9.60,1.00,0.00,1.00 -947,43.20,-9.60,1.00,0.00,1.00 -948,-129.60,9.60,1.00,0.00,1.00 -949,52.80,-9.60,1.00,0.00,1.00 -950,-120.00,9.60,1.00,0.00,1.00 -951,62.40,-9.60,1.00,0.00,1.00 -952,-110.40,9.60,1.00,0.00,1.00 -953,72.00,-14.40,1.00,0.00,1.00 -954,-100.80,14.40,1.00,0.00,1.00 -955,81.60,-14.40,1.00,0.00,1.00 -956,-91.20,14.40,1.00,0.00,1.00 -957,96.00,-14.40,1.00,0.00,1.00 -958,-81.60,14.40,1.00,0.00,1.00 -959,105.60,-14.40,1.00,0.00,1.00 -960,-72.00,9.60,1.00,0.00,1.00 -961,115.20,-9.60,1.00,0.00,1.00 -962,-62.40,9.60,1.00,0.00,1.00 -963,124.80,-9.60,1.00,0.00,1.00 -964,-52.80,9.60,1.00,0.00,1.00 -965,134.40,-9.60,1.00,0.00,1.00 -966,-43.20,9.60,1.00,0.00,1.00 -967,144.00,-9.60,1.00,0.00,1.00 -968,-33.60,4.80,1.00,0.00,1.00 -969,153.60,-4.80,1.00,0.00,1.00 -970,-24.00,4.80,1.00,0.00,1.00 -971,163.20,-4.80,1.00,0.00,1.00 -972,-14.40,4.80,1.00,0.00,1.00 -973,172.80,-0.00,1.00,0.00,1.00 -974,-4.80,0.00,1.00,0.00,1.00 -975,0.00,0.00,1.00,0.00,1.00 -976,-177.60,0.00,1.00,0.00,1.00 -977,9.60,-4.80,1.00,0.00,1.00 -978,-168.00,4.80,1.00,0.00,1.00 -979,19.20,-4.80,1.00,0.00,1.00 -980,-158.40,4.80,1.00,0.00,1.00 -981,28.80,-9.60,1.00,0.00,1.00 -982,-148.80,9.60,1.00,0.00,1.00 -983,38.40,-9.60,1.00,0.00,1.00 -984,-139.20,9.60,1.00,0.00,1.00 -985,48.00,-14.40,1.00,0.00,1.00 -986,-129.60,14.40,1.00,0.00,1.00 -987,57.60,-14.40,1.00,0.00,1.00 -988,-120.00,14.40,1.00,0.00,1.00 -989,67.20,-14.40,1.00,0.00,1.00 -990,-110.40,14.40,1.00,0.00,1.00 -991,76.80,-19.20,1.00,0.00,1.00 -992,-100.80,19.20,1.00,0.00,1.00 -993,86.40,-19.20,1.00,0.00,1.00 -994,-86.40,19.20,1.00,0.00,1.00 -995,96.00,-19.20,1.00,0.00,1.00 -996,-76.80,19.20,1.00,0.00,1.00 -997,105.60,-14.40,1.00,0.00,1.00 -998,-67.20,14.40,1.00,0.00,1.00 -999,115.20,-14.40,1.00,0.00,1.00 -1000,-57.60,14.40,1.00,0.00,1.00 -1001,124.80,-14.40,1.00,0.00,1.00 -1002,-48.00,14.40,1.00,0.00,1.00 -1003,134.40,-14.40,1.00,0.00,1.00 -1004,-38.40,9.60,1.00,0.00,1.00 -1005,144.00,-9.60,1.00,0.00,1.00 -1006,-28.80,9.60,1.00,0.00,1.00 -1007,153.60,-9.60,1.00,0.00,1.00 -1008,-19.20,4.80,1.00,0.00,1.00 -1009,163.20,-4.80,1.00,0.00,1.00 -1010,-9.60,4.80,1.00,0.00,1.00 -1011,172.80,-0.00,1.00,0.00,1.00 -1012,-0.00,0.00,1.00,0.00,1.00 -1013,-177.60,0.00,1.00,0.00,1.00 -1014,4.80,-0.00,1.00,0.00,1.00 -1015,-168.00,4.80,1.00,0.00,1.00 -1016,14.40,-4.80,1.00,0.00,1.00 -1017,-158.40,4.80,1.00,0.00,1.00 -1018,24.00,-9.60,1.00,0.00,1.00 -1019,-148.80,9.60,1.00,0.00,1.00 -1020,33.60,-9.60,1.00,0.00,1.00 -1021,-139.20,9.60,1.00,0.00,1.00 -1022,43.20,-14.40,1.00,0.00,1.00 -1023,-129.60,14.40,1.00,0.00,1.00 -1024,52.80,-14.40,1.00,0.00,1.00 -1025,-120.00,14.40,1.00,0.00,1.00 -1026,62.40,-14.40,1.00,0.00,1.00 -1027,-110.40,14.40,1.00,0.00,1.00 -1028,72.00,-14.40,1.00,0.00,1.00 -1029,-100.80,19.20,1.00,0.00,1.00 -1030,81.60,-19.20,1.00,0.00,1.00 -1031,-91.20,19.20,1.00,0.00,1.00 -1032,96.00,-19.20,1.00,0.00,1.00 -1033,-81.60,19.20,1.00,0.00,1.00 -1034,105.60,-19.20,1.00,0.00,1.00 -1035,-72.00,14.40,1.00,0.00,1.00 -1036,115.20,-14.40,1.00,0.00,1.00 -1037,-62.40,14.40,1.00,0.00,1.00 -1038,124.80,-14.40,1.00,0.00,1.00 -1039,-52.80,14.40,1.00,0.00,1.00 -1040,134.40,-14.40,1.00,0.00,1.00 -1041,-43.20,9.60,1.00,0.00,1.00 -1042,144.00,-9.60,1.00,0.00,1.00 -1043,-33.60,9.60,1.00,0.00,1.00 -1044,153.60,-9.60,1.00,0.00,1.00 -1045,-24.00,4.80,1.00,0.00,1.00 -1046,163.20,-4.80,1.00,0.00,1.00 -1047,-14.40,4.80,1.00,0.00,1.00 -1048,172.80,-4.80,1.00,0.00,1.00 -1049,-4.80,0.00,1.00,0.00,1.00 -1050,0.00,0.00,1.00,0.00,1.00 -1051,-177.60,0.00,1.00,0.00,1.00 -1052,9.60,-4.80,1.00,0.00,1.00 -1053,-168.00,4.80,1.00,0.00,1.00 -1054,19.20,-4.80,1.00,0.00,1.00 -1055,-158.40,9.60,1.00,0.00,1.00 -1056,28.80,-9.60,1.00,0.00,1.00 -1057,-148.80,14.40,1.00,0.00,1.00 -1058,38.40,-14.40,1.00,0.00,1.00 -1059,-139.20,14.40,1.00,0.00,1.00 -1060,48.00,-14.40,1.00,0.00,1.00 -1061,-129.60,19.20,1.00,0.00,1.00 -1062,57.60,-19.20,1.00,0.00,1.00 -1063,-120.00,19.20,1.00,0.00,1.00 -1064,67.20,-19.20,1.00,0.00,1.00 -1065,-110.40,19.20,1.00,0.00,1.00 -1066,76.80,-19.20,1.00,0.00,1.00 -1067,-100.80,24.00,1.00,0.00,1.00 -1068,86.40,-24.00,1.00,0.00,1.00 -1069,-86.40,24.00,1.00,0.00,1.00 -1070,96.00,-24.00,1.00,0.00,1.00 -1071,-76.80,24.00,1.00,0.00,1.00 -1072,105.60,-19.20,1.00,0.00,1.00 -1073,-67.20,19.20,1.00,0.00,1.00 -1074,115.20,-19.20,1.00,0.00,1.00 -1075,-57.60,19.20,1.00,0.00,1.00 -1076,124.80,-19.20,1.00,0.00,1.00 -1077,-48.00,19.20,1.00,0.00,1.00 -1078,134.40,-14.40,1.00,0.00,1.00 -1079,-38.40,14.40,1.00,0.00,1.00 -1080,144.00,-14.40,1.00,0.00,1.00 -1081,-28.80,9.60,1.00,0.00,1.00 -1082,153.60,-9.60,1.00,0.00,1.00 -1083,-19.20,9.60,1.00,0.00,1.00 -1084,163.20,-4.80,1.00,0.00,1.00 -1085,-9.60,4.80,1.00,0.00,1.00 -1086,172.80,-4.80,1.00,0.00,1.00 -1087,-0.00,0.00,1.00,0.00,1.00 -1088,-177.60,0.00,1.00,0.00,1.00 -1089,4.80,-4.80,1.00,0.00,1.00 -1090,-168.00,4.80,1.00,0.00,1.00 -1091,14.40,-4.80,1.00,0.00,1.00 -1092,-158.40,9.60,1.00,0.00,1.00 -1093,24.00,-9.60,1.00,0.00,1.00 -1094,-148.80,9.60,1.00,0.00,1.00 -1095,33.60,-14.40,1.00,0.00,1.00 -1096,-139.20,14.40,1.00,0.00,1.00 -1097,43.20,-14.40,1.00,0.00,1.00 -1098,-129.60,19.20,1.00,0.00,1.00 -1099,52.80,-19.20,1.00,0.00,1.00 -1100,-120.00,19.20,1.00,0.00,1.00 -1101,62.40,-19.20,1.00,0.00,1.00 -1102,-110.40,19.20,1.00,0.00,1.00 -1103,72.00,-19.20,1.00,0.00,1.00 -1104,-100.80,24.00,1.00,0.00,1.00 -1105,81.60,-24.00,1.00,0.00,1.00 -1106,-91.20,24.00,1.00,0.00,1.00 -1107,96.00,-24.00,1.00,0.00,1.00 -1108,-81.60,24.00,1.00,0.00,1.00 -1109,105.60,-19.20,1.00,0.00,1.00 -1110,-72.00,19.20,1.00,0.00,1.00 -1111,115.20,-19.20,1.00,0.00,1.00 -1112,-62.40,19.20,1.00,0.00,1.00 -1113,124.80,-19.20,1.00,0.00,1.00 -1114,-52.80,19.20,1.00,0.00,1.00 -1115,134.40,-14.40,1.00,0.00,1.00 -1116,-43.20,14.40,1.00,0.00,1.00 -1117,144.00,-14.40,1.00,0.00,1.00 -1118,-33.60,14.40,1.00,0.00,1.00 -1119,153.60,-9.60,1.00,0.00,1.00 -1120,-24.00,9.60,1.00,0.00,1.00 -1121,163.20,-4.80,1.00,0.00,1.00 -1122,-14.40,4.80,1.00,0.00,1.00 -1123,172.80,-4.80,1.00,0.00,1.00 -1124,-4.80,0.00,1.00,0.00,1.00 -1125,0.00,0.00,1.00,0.00,1.00 -1126,-177.60,0.00,1.00,0.00,1.00 -1127,9.60,-4.80,1.00,0.00,1.00 -1128,-168.00,4.80,1.00,0.00,1.00 -1129,19.20,-9.60,1.00,0.00,1.00 -1130,-158.40,9.60,1.00,0.00,1.00 -1131,24.00,-14.40,1.00,0.00,1.00 -1132,-148.80,14.40,1.00,0.00,1.00 -1133,33.60,-14.40,1.00,0.00,1.00 -1134,-139.20,19.20,1.00,0.00,1.00 -1135,43.20,-19.20,1.00,0.00,1.00 -1136,-129.60,19.20,1.00,0.00,1.00 -1137,52.80,-24.00,1.00,0.00,1.00 -1138,-120.00,24.00,1.00,0.00,1.00 -1139,62.40,-24.00,1.00,0.00,1.00 -1140,-110.40,24.00,1.00,0.00,1.00 -1141,76.80,-24.00,1.00,0.00,1.00 -1142,-100.80,28.80,1.00,0.00,1.00 -1143,86.40,-28.80,1.00,0.00,1.00 -1144,-86.40,28.80,1.00,0.00,1.00 -1145,96.00,-28.80,1.00,0.00,1.00 -1146,-76.80,28.80,1.00,0.00,1.00 -1147,105.60,-24.00,1.00,0.00,1.00 -1148,-67.20,24.00,1.00,0.00,1.00 -1149,120.00,-24.00,1.00,0.00,1.00 -1150,-57.60,24.00,1.00,0.00,1.00 -1151,129.60,-24.00,1.00,0.00,1.00 -1152,-48.00,19.20,1.00,0.00,1.00 -1153,139.20,-19.20,1.00,0.00,1.00 -1154,-38.40,19.20,1.00,0.00,1.00 -1155,148.80,-14.40,1.00,0.00,1.00 -1156,-28.80,14.40,1.00,0.00,1.00 -1157,158.40,-9.60,1.00,0.00,1.00 -1158,-19.20,9.60,1.00,0.00,1.00 -1159,163.20,-9.60,1.00,0.00,1.00 -1160,-9.60,4.80,1.00,0.00,1.00 -1161,172.80,-4.80,1.00,0.00,1.00 -1162,-0.00,0.00,1.00,0.00,1.00 -1163,-177.60,0.00,1.00,0.00,1.00 -1164,4.80,-4.80,1.00,0.00,1.00 -1165,-168.00,4.80,1.00,0.00,1.00 -1166,14.40,-9.60,1.00,0.00,1.00 -1167,-158.40,9.60,1.00,0.00,1.00 -1168,24.00,-9.60,1.00,0.00,1.00 -1169,-153.60,14.40,1.00,0.00,1.00 -1170,33.60,-14.40,1.00,0.00,1.00 -1171,-144.00,19.20,1.00,0.00,1.00 -1172,43.20,-19.20,1.00,0.00,1.00 -1173,-134.40,19.20,1.00,0.00,1.00 -1174,52.80,-24.00,1.00,0.00,1.00 -1175,-124.80,24.00,1.00,0.00,1.00 -1176,62.40,-24.00,1.00,0.00,1.00 -1177,-110.40,24.00,1.00,0.00,1.00 -1178,72.00,-24.00,1.00,0.00,1.00 -1179,-100.80,28.80,1.00,0.00,1.00 -1180,81.60,-28.80,1.00,0.00,1.00 -1181,-91.20,28.80,1.00,0.00,1.00 -1182,96.00,-28.80,1.00,0.00,1.00 -1183,-81.60,28.80,1.00,0.00,1.00 -1184,105.60,-24.00,1.00,0.00,1.00 -1185,-72.00,24.00,1.00,0.00,1.00 -1186,115.20,-24.00,1.00,0.00,1.00 -1187,-57.60,24.00,1.00,0.00,1.00 -1188,124.80,-24.00,1.00,0.00,1.00 -1189,-48.00,19.20,1.00,0.00,1.00 -1190,134.40,-19.20,1.00,0.00,1.00 -1191,-38.40,19.20,1.00,0.00,1.00 -1192,144.00,-14.40,1.00,0.00,1.00 -1193,-28.80,14.40,1.00,0.00,1.00 -1194,153.60,-14.40,1.00,0.00,1.00 -1195,-24.00,9.60,1.00,0.00,1.00 -1196,163.20,-9.60,1.00,0.00,1.00 -1197,-14.40,4.80,1.00,0.00,1.00 -1198,172.80,-4.80,1.00,0.00,1.00 -1199,-4.80,0.00,1.00,0.00,1.00 -1200,0.00,0.00,1.00,0.00,1.00 -1201,-177.60,4.80,1.00,0.00,1.00 -1202,9.60,-4.80,1.00,0.00,1.00 -1203,-168.00,9.60,1.00,0.00,1.00 -1204,14.40,-9.60,1.00,0.00,1.00 -1205,-158.40,14.40,1.00,0.00,1.00 -1206,24.00,-14.40,1.00,0.00,1.00 -1207,-148.80,19.20,1.00,0.00,1.00 -1208,33.60,-19.20,1.00,0.00,1.00 -1209,-139.20,19.20,1.00,0.00,1.00 -1210,43.20,-24.00,1.00,0.00,1.00 -1211,-129.60,24.00,1.00,0.00,1.00 -1212,52.80,-28.80,1.00,0.00,1.00 -1213,-120.00,28.80,1.00,0.00,1.00 -1214,62.40,-28.80,1.00,0.00,1.00 -1215,-110.40,28.80,1.00,0.00,1.00 -1216,76.80,-28.80,1.00,0.00,1.00 -1217,-100.80,33.60,1.00,0.00,1.00 -1218,86.40,-33.60,1.00,0.00,1.00 -1219,-86.40,33.60,1.00,0.00,1.00 -1220,96.00,-33.60,1.00,0.00,1.00 -1221,-76.80,28.80,1.00,0.00,1.00 -1222,110.40,-28.80,1.00,0.00,1.00 -1223,-67.20,28.80,1.00,0.00,1.00 -1224,120.00,-28.80,1.00,0.00,1.00 -1225,-57.60,28.80,1.00,0.00,1.00 -1226,129.60,-24.00,1.00,0.00,1.00 -1227,-48.00,24.00,1.00,0.00,1.00 -1228,139.20,-24.00,1.00,0.00,1.00 -1229,-38.40,19.20,1.00,0.00,1.00 -1230,148.80,-19.20,1.00,0.00,1.00 -1231,-28.80,14.40,1.00,0.00,1.00 -1232,158.40,-14.40,1.00,0.00,1.00 -1233,-19.20,9.60,1.00,0.00,1.00 -1234,168.00,-9.60,1.00,0.00,1.00 -1235,-9.60,4.80,1.00,0.00,1.00 -1236,172.80,-4.80,1.00,0.00,1.00 -1237,-0.00,0.00,1.00,0.00,1.00 -1238,-177.60,0.00,1.00,0.00,1.00 -1239,4.80,-4.80,1.00,0.00,1.00 -1240,-168.00,4.80,1.00,0.00,1.00 -1241,14.40,-9.60,1.00,0.00,1.00 -1242,-163.20,9.60,1.00,0.00,1.00 -1243,24.00,-14.40,1.00,0.00,1.00 -1244,-153.60,14.40,1.00,0.00,1.00 -1245,33.60,-19.20,1.00,0.00,1.00 -1246,-144.00,19.20,1.00,0.00,1.00 -1247,43.20,-24.00,1.00,0.00,1.00 -1248,-134.40,24.00,1.00,0.00,1.00 -1249,52.80,-24.00,1.00,0.00,1.00 -1250,-124.80,28.80,1.00,0.00,1.00 -1251,62.40,-28.80,1.00,0.00,1.00 -1252,-115.20,28.80,1.00,0.00,1.00 -1253,72.00,-28.80,1.00,0.00,1.00 -1254,-100.80,28.80,1.00,0.00,1.00 -1255,81.60,-33.60,1.00,0.00,1.00 -1256,-91.20,33.60,1.00,0.00,1.00 -1257,96.00,-33.60,1.00,0.00,1.00 -1258,-81.60,33.60,1.00,0.00,1.00 -1259,105.60,-28.80,1.00,0.00,1.00 -1260,-67.20,28.80,1.00,0.00,1.00 -1261,115.20,-28.80,1.00,0.00,1.00 -1262,-57.60,28.80,1.00,0.00,1.00 -1263,124.80,-28.80,1.00,0.00,1.00 -1264,-48.00,24.00,1.00,0.00,1.00 -1265,134.40,-24.00,1.00,0.00,1.00 -1266,-38.40,19.20,1.00,0.00,1.00 -1267,144.00,-19.20,1.00,0.00,1.00 -1268,-28.80,19.20,1.00,0.00,1.00 -1269,153.60,-14.40,1.00,0.00,1.00 -1270,-19.20,14.40,1.00,0.00,1.00 -1271,163.20,-9.60,1.00,0.00,1.00 -1272,-14.40,9.60,1.00,0.00,1.00 -1273,172.80,-4.80,1.00,0.00,1.00 -1274,-4.80,4.80,1.00,0.00,1.00 -1275,0.00,0.00,1.00,0.00,1.00 -1276,-177.60,4.80,1.00,0.00,1.00 -1277,9.60,-4.80,1.00,0.00,1.00 -1278,-168.00,9.60,1.00,0.00,1.00 -1279,14.40,-9.60,1.00,0.00,1.00 -1280,-158.40,14.40,1.00,0.00,1.00 -1281,24.00,-14.40,1.00,0.00,1.00 -1282,-153.60,19.20,1.00,0.00,1.00 -1283,33.60,-24.00,1.00,0.00,1.00 -1284,-144.00,24.00,1.00,0.00,1.00 -1285,43.20,-24.00,1.00,0.00,1.00 -1286,-134.40,28.80,1.00,0.00,1.00 -1287,52.80,-28.80,1.00,0.00,1.00 -1288,-124.80,33.60,1.00,0.00,1.00 -1289,62.40,-33.60,1.00,0.00,1.00 -1290,-110.40,33.60,1.00,0.00,1.00 -1291,72.00,-33.60,1.00,0.00,1.00 -1292,-100.80,38.40,1.00,0.00,1.00 -1293,86.40,-38.40,1.00,0.00,1.00 -1294,-86.40,38.40,1.00,0.00,1.00 -1295,96.00,-38.40,1.00,0.00,1.00 -1296,-76.80,33.60,1.00,0.00,1.00 -1297,110.40,-33.60,1.00,0.00,1.00 -1298,-67.20,33.60,1.00,0.00,1.00 -1299,120.00,-33.60,1.00,0.00,1.00 -1300,-52.80,28.80,1.00,0.00,1.00 -1301,129.60,-28.80,1.00,0.00,1.00 -1302,-43.20,28.80,1.00,0.00,1.00 -1303,139.20,-24.00,1.00,0.00,1.00 -1304,-33.60,24.00,1.00,0.00,1.00 -1305,148.80,-19.20,1.00,0.00,1.00 -1306,-24.00,19.20,1.00,0.00,1.00 -1307,158.40,-14.40,1.00,0.00,1.00 -1308,-19.20,14.40,1.00,0.00,1.00 -1309,168.00,-9.60,1.00,0.00,1.00 -1310,-9.60,4.80,1.00,0.00,1.00 -1311,172.80,-4.80,1.00,0.00,1.00 -1312,-0.00,0.00,1.00,0.00,1.00 -1313,-177.60,0.00,1.00,0.00,1.00 -1314,4.80,-4.80,1.00,0.00,1.00 -1315,-168.00,4.80,1.00,0.00,1.00 -1316,14.40,-9.60,1.00,0.00,1.00 -1317,-163.20,14.40,1.00,0.00,1.00 -1318,24.00,-14.40,1.00,0.00,1.00 -1319,-153.60,19.20,1.00,0.00,1.00 -1320,28.80,-19.20,1.00,0.00,1.00 -1321,-144.00,24.00,1.00,0.00,1.00 -1322,38.40,-24.00,1.00,0.00,1.00 -1323,-134.40,28.80,1.00,0.00,1.00 -1324,48.00,-28.80,1.00,0.00,1.00 -1325,-124.80,28.80,1.00,0.00,1.00 -1326,57.60,-33.60,1.00,0.00,1.00 -1327,-115.20,33.60,1.00,0.00,1.00 -1328,72.00,-33.60,1.00,0.00,1.00 -1329,-105.60,33.60,1.00,0.00,1.00 -1330,81.60,-38.40,1.00,0.00,1.00 -1331,-91.20,38.40,1.00,0.00,1.00 -1332,96.00,-38.40,1.00,0.00,1.00 -1333,-81.60,38.40,1.00,0.00,1.00 -1334,105.60,-33.60,1.00,0.00,1.00 -1335,-67.20,33.60,1.00,0.00,1.00 -1336,120.00,-33.60,1.00,0.00,1.00 -1337,-57.60,33.60,1.00,0.00,1.00 -1338,129.60,-28.80,1.00,0.00,1.00 -1339,-48.00,28.80,1.00,0.00,1.00 -1340,139.20,-24.00,1.00,0.00,1.00 -1341,-38.40,24.00,1.00,0.00,1.00 -1342,148.80,-24.00,1.00,0.00,1.00 -1343,-28.80,19.20,1.00,0.00,1.00 -1344,158.40,-14.40,1.00,0.00,1.00 -1345,-19.20,14.40,1.00,0.00,1.00 -1346,163.20,-9.60,1.00,0.00,1.00 -1347,-9.60,9.60,1.00,0.00,1.00 -1348,172.80,-4.80,1.00,0.00,1.00 -1349,-4.80,4.80,1.00,0.00,1.00 -1350,0.00,0.00,1.00,0.00,1.00 -1351,-177.60,4.80,1.00,0.00,1.00 -1352,9.60,-4.80,1.00,0.00,1.00 -1353,-168.00,9.60,1.00,0.00,1.00 -1354,14.40,-14.40,1.00,0.00,1.00 -1355,-163.20,14.40,1.00,0.00,1.00 -1356,24.00,-19.20,1.00,0.00,1.00 -1357,-153.60,19.20,1.00,0.00,1.00 -1358,28.80,-24.00,1.00,0.00,1.00 -1359,-144.00,28.80,1.00,0.00,1.00 -1360,38.40,-28.80,1.00,0.00,1.00 -1361,-134.40,33.60,1.00,0.00,1.00 -1362,48.00,-33.60,1.00,0.00,1.00 -1363,-124.80,33.60,1.00,0.00,1.00 -1364,62.40,-38.40,1.00,0.00,1.00 -1365,-115.20,38.40,1.00,0.00,1.00 -1366,72.00,-38.40,1.00,0.00,1.00 -1367,-100.80,43.20,1.00,0.00,1.00 -1368,86.40,-43.20,1.00,0.00,1.00 -1369,-86.40,43.20,1.00,0.00,1.00 -1370,96.00,-43.20,1.00,0.00,1.00 -1371,-76.80,38.40,1.00,0.00,1.00 -1372,110.40,-38.40,1.00,0.00,1.00 -1373,-62.40,38.40,1.00,0.00,1.00 -1374,120.00,-38.40,1.00,0.00,1.00 -1375,-52.80,33.60,1.00,0.00,1.00 -1376,134.40,-33.60,1.00,0.00,1.00 -1377,-43.20,28.80,1.00,0.00,1.00 -1378,144.00,-28.80,1.00,0.00,1.00 -1379,-33.60,24.00,1.00,0.00,1.00 -1380,153.60,-24.00,1.00,0.00,1.00 -1381,-24.00,19.20,1.00,0.00,1.00 -1382,158.40,-19.20,1.00,0.00,1.00 -1383,-14.40,14.40,1.00,0.00,1.00 -1384,168.00,-9.60,1.00,0.00,1.00 -1385,-9.60,9.60,1.00,0.00,1.00 -1386,172.80,-4.80,1.00,0.00,1.00 -1387,-0.00,0.00,1.00,0.00,1.00 -1388,-177.60,0.00,1.00,0.00,1.00 -1389,4.80,-4.80,1.00,0.00,1.00 -1390,-172.80,9.60,1.00,0.00,1.00 -1391,14.40,-9.60,1.00,0.00,1.00 -1392,-163.20,14.40,1.00,0.00,1.00 -1393,19.20,-19.20,1.00,0.00,1.00 -1394,-153.60,19.20,1.00,0.00,1.00 -1395,28.80,-24.00,1.00,0.00,1.00 -1396,-148.80,24.00,1.00,0.00,1.00 -1397,38.40,-28.80,1.00,0.00,1.00 -1398,-139.20,28.80,1.00,0.00,1.00 -1399,48.00,-33.60,1.00,0.00,1.00 -1400,-129.60,33.60,1.00,0.00,1.00 -1401,57.60,-38.40,1.00,0.00,1.00 -1402,-115.20,38.40,1.00,0.00,1.00 -1403,67.20,-38.40,1.00,0.00,1.00 -1404,-105.60,38.40,1.00,0.00,1.00 -1405,81.60,-43.20,1.00,0.00,1.00 -1406,-91.20,43.20,1.00,0.00,1.00 -1407,96.00,-43.20,1.00,0.00,1.00 -1408,-76.80,43.20,1.00,0.00,1.00 -1409,105.60,-38.40,1.00,0.00,1.00 -1410,-67.20,38.40,1.00,0.00,1.00 -1411,120.00,-38.40,1.00,0.00,1.00 -1412,-52.80,33.60,1.00,0.00,1.00 -1413,129.60,-33.60,1.00,0.00,1.00 -1414,-43.20,33.60,1.00,0.00,1.00 -1415,139.20,-28.80,1.00,0.00,1.00 -1416,-33.60,28.80,1.00,0.00,1.00 -1417,148.80,-24.00,1.00,0.00,1.00 -1418,-28.80,19.20,1.00,0.00,1.00 -1419,158.40,-19.20,1.00,0.00,1.00 -1420,-19.20,14.40,1.00,0.00,1.00 -1421,163.20,-14.40,1.00,0.00,1.00 -1422,-9.60,9.60,1.00,0.00,1.00 -1423,172.80,-4.80,1.00,0.00,1.00 -1424,-4.80,4.80,1.00,0.00,1.00 -1425,0.00,0.00,1.00,0.00,1.00 -1426,-177.60,4.80,1.00,0.00,1.00 -1427,4.80,-4.80,1.00,0.00,1.00 -1428,-168.00,9.60,1.00,0.00,1.00 -1429,14.40,-14.40,1.00,0.00,1.00 -1430,-163.20,19.20,1.00,0.00,1.00 -1431,19.20,-19.20,1.00,0.00,1.00 -1432,-153.60,24.00,1.00,0.00,1.00 -1433,28.80,-28.80,1.00,0.00,1.00 -1434,-148.80,28.80,1.00,0.00,1.00 -1435,38.40,-33.60,1.00,0.00,1.00 -1436,-139.20,33.60,1.00,0.00,1.00 -1437,48.00,-38.40,1.00,0.00,1.00 -1438,-124.80,38.40,1.00,0.00,1.00 -1439,57.60,-43.20,1.00,0.00,1.00 -1440,-115.20,43.20,1.00,0.00,1.00 -1441,72.00,-43.20,1.00,0.00,1.00 -1442,-100.80,43.20,1.00,0.00,1.00 -1443,86.40,-48.00,1.00,0.00,1.00 -1444,-86.40,48.00,1.00,0.00,1.00 -1445,100.80,-48.00,1.00,0.00,1.00 -1446,-76.80,43.20,1.00,0.00,1.00 -1447,110.40,-43.20,1.00,0.00,1.00 -1448,-62.40,43.20,1.00,0.00,1.00 -1449,124.80,-38.40,1.00,0.00,1.00 -1450,-48.00,38.40,1.00,0.00,1.00 -1451,134.40,-38.40,1.00,0.00,1.00 -1452,-38.40,33.60,1.00,0.00,1.00 -1453,144.00,-28.80,1.00,0.00,1.00 -1454,-28.80,28.80,1.00,0.00,1.00 -1455,153.60,-24.00,1.00,0.00,1.00 -1456,-24.00,24.00,1.00,0.00,1.00 -1457,163.20,-19.20,1.00,0.00,1.00 -1458,-14.40,14.40,1.00,0.00,1.00 -1459,168.00,-14.40,1.00,0.00,1.00 -1460,-9.60,9.60,1.00,0.00,1.00 -1461,172.80,-4.80,1.00,0.00,1.00 -1462,-0.00,0.00,1.00,0.00,1.00 -1463,-177.60,0.00,1.00,0.00,1.00 -1464,4.80,-4.80,1.00,0.00,1.00 -1465,-172.80,9.60,1.00,0.00,1.00 -1466,9.60,-14.40,1.00,0.00,1.00 -1467,-163.20,14.40,1.00,0.00,1.00 -1468,19.20,-19.20,1.00,0.00,1.00 -1469,-158.40,24.00,1.00,0.00,1.00 -1470,28.80,-24.00,1.00,0.00,1.00 -1471,-148.80,28.80,1.00,0.00,1.00 -1472,33.60,-28.80,1.00,0.00,1.00 -1473,-139.20,33.60,1.00,0.00,1.00 -1474,43.20,-38.40,1.00,0.00,1.00 -1475,-129.60,38.40,1.00,0.00,1.00 -1476,57.60,-38.40,1.00,0.00,1.00 -1477,-120.00,43.20,1.00,0.00,1.00 -1478,67.20,-43.20,1.00,0.00,1.00 -1479,-105.60,43.20,1.00,0.00,1.00 -1480,81.60,-48.00,1.00,0.00,1.00 -1481,-91.20,48.00,1.00,0.00,1.00 -1482,96.00,-48.00,1.00,0.00,1.00 -1483,-76.80,43.20,1.00,0.00,1.00 -1484,110.40,-43.20,1.00,0.00,1.00 -1485,-67.20,43.20,1.00,0.00,1.00 -1486,120.00,-43.20,1.00,0.00,1.00 -1487,-52.80,38.40,1.00,0.00,1.00 -1488,134.40,-38.40,1.00,0.00,1.00 -1489,-43.20,33.60,1.00,0.00,1.00 -1490,144.00,-33.60,1.00,0.00,1.00 -1491,-33.60,28.80,1.00,0.00,1.00 -1492,153.60,-28.80,1.00,0.00,1.00 -1493,-24.00,24.00,1.00,0.00,1.00 -1494,158.40,-19.20,1.00,0.00,1.00 -1495,-19.20,19.20,1.00,0.00,1.00 -1496,168.00,-14.40,1.00,0.00,1.00 -1497,-9.60,9.60,1.00,0.00,1.00 -1498,172.80,-4.80,1.00,0.00,1.00 -1499,-4.80,4.80,1.00,0.00,1.00 diff --git a/tests/renderer/data/stvISM4.csv b/tests/renderer/data/stvISM4.csv deleted file mode 100644 index f3a2884ff0..0000000000 --- a/tests/renderer/data/stvISM4.csv +++ /dev/null @@ -1,1500 +0,0 @@ -0,-0.00,0.00,1.00,0.00,1.00 -1,-0.00,4.80,1.00,0.00,1.00 -2,-0.00,9.60,1.00,0.00,1.00 -3,-0.00,14.40,1.00,0.00,1.00 -4,-0.00,19.20,1.00,0.00,1.00 -5,-0.00,24.00,1.00,0.00,1.00 -6,-0.00,28.80,1.00,0.00,1.00 -7,-0.00,33.60,1.00,0.00,1.00 -8,-0.00,38.40,1.00,0.00,1.00 -9,-0.00,43.20,1.00,0.00,1.00 -10,-0.00,48.00,1.00,0.00,1.00 -11,-0.00,52.80,1.00,0.00,1.00 -12,-0.00,57.60,1.00,0.00,1.00 -13,-0.00,62.40,1.00,0.00,1.00 -14,-0.00,67.20,1.00,0.00,1.00 -15,-0.00,72.00,1.00,0.00,1.00 -16,-0.00,76.80,1.00,0.00,1.00 -17,-0.00,81.60,1.00,0.00,1.00 -18,-0.00,86.40,1.00,0.00,1.00 -19,-177.60,91.20,1.00,0.00,1.00 -20,-177.60,86.40,1.00,0.00,1.00 -21,-177.60,81.60,1.00,0.00,1.00 -22,-177.60,76.80,1.00,0.00,1.00 -23,-177.60,72.00,1.00,0.00,1.00 -24,-177.60,67.20,1.00,0.00,1.00 -25,177.60,62.40,1.00,0.00,1.00 -26,177.60,57.60,1.00,0.00,1.00 -27,177.60,52.80,1.00,0.00,1.00 -28,177.60,48.00,1.00,0.00,1.00 -29,177.60,43.20,1.00,0.00,1.00 -30,177.60,38.40,1.00,0.00,1.00 -31,177.60,33.60,1.00,0.00,1.00 -32,177.60,28.80,1.00,0.00,1.00 -33,177.60,24.00,1.00,0.00,1.00 -34,177.60,19.20,1.00,0.00,1.00 -35,177.60,14.40,1.00,0.00,1.00 -36,177.60,9.60,1.00,0.00,1.00 -37,177.60,4.80,1.00,0.00,1.00 -38,-177.60,-0.00,1.00,0.00,1.00 -39,-177.60,-4.80,1.00,0.00,1.00 -40,-177.60,-9.60,1.00,0.00,1.00 -41,-177.60,-14.40,1.00,0.00,1.00 -42,-177.60,-19.20,1.00,0.00,1.00 -43,-177.60,-24.00,1.00,0.00,1.00 -44,-177.60,-28.80,1.00,0.00,1.00 -45,-177.60,-33.60,1.00,0.00,1.00 -46,-177.60,-38.40,1.00,0.00,1.00 -47,-177.60,-48.00,1.00,0.00,1.00 -48,-177.60,-48.00,1.00,0.00,1.00 -49,-177.60,-52.80,1.00,0.00,1.00 -50,-177.60,-57.60,1.00,0.00,1.00 -51,177.60,-62.40,1.00,0.00,1.00 -52,177.60,-67.20,1.00,0.00,1.00 -53,177.60,-76.80,1.00,0.00,1.00 -54,177.60,-76.80,1.00,0.00,1.00 -55,177.60,-86.40,1.00,0.00,1.00 -56,177.60,-91.20,1.00,0.00,1.00 -57,0.00,-86.40,1.00,0.00,1.00 -58,0.00,-81.60,1.00,0.00,1.00 -59,0.00,-76.80,1.00,0.00,1.00 -60,0.00,-72.00,1.00,0.00,1.00 -61,0.00,-67.20,1.00,0.00,1.00 -62,0.00,-62.40,1.00,0.00,1.00 -63,0.00,-57.60,1.00,0.00,1.00 -64,0.00,-52.80,1.00,0.00,1.00 -65,0.00,-48.00,1.00,0.00,1.00 -66,0.00,-43.20,1.00,0.00,1.00 -67,0.00,-38.40,1.00,0.00,1.00 -68,0.00,-33.60,1.00,0.00,1.00 -69,0.00,-28.80,1.00,0.00,1.00 -70,0.00,-24.00,1.00,0.00,1.00 -71,0.00,-19.20,1.00,0.00,1.00 -72,0.00,-14.40,1.00,0.00,1.00 -73,0.00,-9.60,1.00,0.00,1.00 -74,0.00,-4.80,1.00,0.00,1.00 -75,0.00,0.00,1.00,0.00,1.00 -76,0.00,4.80,1.00,0.00,1.00 -77,0.00,9.60,1.00,0.00,1.00 -78,0.00,14.40,1.00,0.00,1.00 -79,0.00,19.20,1.00,0.00,1.00 -80,0.00,24.00,1.00,0.00,1.00 -81,4.80,28.80,1.00,0.00,1.00 -82,4.80,33.60,1.00,0.00,1.00 -83,4.80,38.40,1.00,0.00,1.00 -84,4.80,43.20,1.00,0.00,1.00 -85,4.80,48.00,1.00,0.00,1.00 -86,4.80,52.80,1.00,0.00,1.00 -87,9.60,57.60,1.00,0.00,1.00 -88,9.60,62.40,1.00,0.00,1.00 -89,9.60,67.20,1.00,0.00,1.00 -90,14.40,72.00,1.00,0.00,1.00 -91,19.20,76.80,1.00,0.00,1.00 -92,28.80,81.60,1.00,0.00,1.00 -93,52.80,86.40,1.00,0.00,1.00 -94,105.60,86.40,1.00,0.00,1.00 -95,139.20,81.60,1.00,0.00,1.00 -96,158.40,76.80,1.00,0.00,1.00 -97,163.20,72.00,1.00,0.00,1.00 -98,168.00,67.20,1.00,0.00,1.00 -99,168.00,62.40,1.00,0.00,1.00 -100,172.80,57.60,1.00,0.00,1.00 -101,172.80,52.80,1.00,0.00,1.00 -102,172.80,48.00,1.00,0.00,1.00 -103,172.80,43.20,1.00,0.00,1.00 -104,177.60,38.40,1.00,0.00,1.00 -105,177.60,33.60,1.00,0.00,1.00 -106,177.60,28.80,1.00,0.00,1.00 -107,177.60,24.00,1.00,0.00,1.00 -108,177.60,19.20,1.00,0.00,1.00 -109,177.60,14.40,1.00,0.00,1.00 -110,177.60,9.60,1.00,0.00,1.00 -111,177.60,4.80,1.00,0.00,1.00 -112,177.60,0.00,1.00,0.00,1.00 -113,-177.60,-0.00,1.00,0.00,1.00 -114,-177.60,-4.80,1.00,0.00,1.00 -115,-177.60,-9.60,1.00,0.00,1.00 -116,-177.60,-14.40,1.00,0.00,1.00 -117,-177.60,-19.20,1.00,0.00,1.00 -118,-177.60,-24.00,1.00,0.00,1.00 -119,-177.60,-28.80,1.00,0.00,1.00 -120,-177.60,-33.60,1.00,0.00,1.00 -121,-177.60,-38.40,1.00,0.00,1.00 -122,-172.80,-43.20,1.00,0.00,1.00 -123,-172.80,-48.00,1.00,0.00,1.00 -124,-172.80,-52.80,1.00,0.00,1.00 -125,-172.80,-57.60,1.00,0.00,1.00 -126,-168.00,-62.40,1.00,0.00,1.00 -127,-168.00,-67.20,1.00,0.00,1.00 -128,-163.20,-72.00,1.00,0.00,1.00 -129,-158.40,-76.80,1.00,0.00,1.00 -130,-139.20,-81.60,1.00,0.00,1.00 -131,-105.60,-86.40,1.00,0.00,1.00 -132,-52.80,-86.40,1.00,0.00,1.00 -133,-28.80,-81.60,1.00,0.00,1.00 -134,-19.20,-76.80,1.00,0.00,1.00 -135,-14.40,-72.00,1.00,0.00,1.00 -136,-9.60,-67.20,1.00,0.00,1.00 -137,-9.60,-62.40,1.00,0.00,1.00 -138,-9.60,-57.60,1.00,0.00,1.00 -139,-4.80,-52.80,1.00,0.00,1.00 -140,-4.80,-48.00,1.00,0.00,1.00 -141,-4.80,-43.20,1.00,0.00,1.00 -142,-4.80,-38.40,1.00,0.00,1.00 -143,-4.80,-33.60,1.00,0.00,1.00 -144,-4.80,-28.80,1.00,0.00,1.00 -145,-0.00,-24.00,1.00,0.00,1.00 -146,-0.00,-19.20,1.00,0.00,1.00 -147,-0.00,-14.40,1.00,0.00,1.00 -148,-0.00,-9.60,1.00,0.00,1.00 -149,-0.00,-4.80,1.00,0.00,1.00 -150,0.00,0.00,1.00,0.00,1.00 -151,0.00,4.80,1.00,0.00,1.00 -152,0.00,9.60,1.00,0.00,1.00 -153,4.80,14.40,1.00,0.00,1.00 -154,4.80,19.20,1.00,0.00,1.00 -155,4.80,24.00,1.00,0.00,1.00 -156,4.80,28.80,1.00,0.00,1.00 -157,4.80,33.60,1.00,0.00,1.00 -158,9.60,38.40,1.00,0.00,1.00 -159,9.60,43.20,1.00,0.00,1.00 -160,9.60,48.00,1.00,0.00,1.00 -161,14.40,52.80,1.00,0.00,1.00 -162,14.40,57.60,1.00,0.00,1.00 -163,19.20,62.40,1.00,0.00,1.00 -164,24.00,67.20,1.00,0.00,1.00 -165,28.80,72.00,1.00,0.00,1.00 -166,33.60,72.00,1.00,0.00,1.00 -167,48.00,76.80,1.00,0.00,1.00 -168,67.20,81.60,1.00,0.00,1.00 -169,96.00,81.60,1.00,0.00,1.00 -170,120.00,76.80,1.00,0.00,1.00 -171,139.20,76.80,1.00,0.00,1.00 -172,148.80,72.00,1.00,0.00,1.00 -173,153.60,67.20,1.00,0.00,1.00 -174,158.40,62.40,1.00,0.00,1.00 -175,163.20,57.60,1.00,0.00,1.00 -176,168.00,52.80,1.00,0.00,1.00 -177,168.00,48.00,1.00,0.00,1.00 -178,168.00,43.20,1.00,0.00,1.00 -179,172.80,38.40,1.00,0.00,1.00 -180,172.80,33.60,1.00,0.00,1.00 -181,172.80,28.80,1.00,0.00,1.00 -182,177.60,24.00,1.00,0.00,1.00 -183,177.60,19.20,1.00,0.00,1.00 -184,177.60,14.40,1.00,0.00,1.00 -185,177.60,9.60,1.00,0.00,1.00 -186,177.60,4.80,1.00,0.00,1.00 -187,177.60,0.00,1.00,0.00,1.00 -188,-177.60,-0.00,1.00,0.00,1.00 -189,-177.60,-4.80,1.00,0.00,1.00 -190,-177.60,-9.60,1.00,0.00,1.00 -191,-177.60,-14.40,1.00,0.00,1.00 -192,-177.60,-19.20,1.00,0.00,1.00 -193,-177.60,-24.00,1.00,0.00,1.00 -194,-172.80,-28.80,1.00,0.00,1.00 -195,-172.80,-33.60,1.00,0.00,1.00 -196,-172.80,-38.40,1.00,0.00,1.00 -197,-168.00,-43.20,1.00,0.00,1.00 -198,-168.00,-48.00,1.00,0.00,1.00 -199,-168.00,-52.80,1.00,0.00,1.00 -200,-163.20,-57.60,1.00,0.00,1.00 -201,-158.40,-62.40,1.00,0.00,1.00 -202,-153.60,-67.20,1.00,0.00,1.00 -203,-148.80,-72.00,1.00,0.00,1.00 -204,-139.20,-76.80,1.00,0.00,1.00 -205,-120.00,-76.80,1.00,0.00,1.00 -206,-96.00,-81.60,1.00,0.00,1.00 -207,-67.20,-81.60,1.00,0.00,1.00 -208,-48.00,-76.80,1.00,0.00,1.00 -209,-33.60,-72.00,1.00,0.00,1.00 -210,-28.80,-72.00,1.00,0.00,1.00 -211,-24.00,-67.20,1.00,0.00,1.00 -212,-19.20,-62.40,1.00,0.00,1.00 -213,-14.40,-57.60,1.00,0.00,1.00 -214,-14.40,-52.80,1.00,0.00,1.00 -215,-9.60,-48.00,1.00,0.00,1.00 -216,-9.60,-43.20,1.00,0.00,1.00 -217,-9.60,-38.40,1.00,0.00,1.00 -218,-4.80,-33.60,1.00,0.00,1.00 -219,-4.80,-28.80,1.00,0.00,1.00 -220,-4.80,-24.00,1.00,0.00,1.00 -221,-4.80,-19.20,1.00,0.00,1.00 -222,-4.80,-14.40,1.00,0.00,1.00 -223,-0.00,-9.60,1.00,0.00,1.00 -224,-0.00,-4.80,1.00,0.00,1.00 -225,0.00,0.00,1.00,0.00,1.00 -226,0.00,4.80,1.00,0.00,1.00 -227,4.80,9.60,1.00,0.00,1.00 -228,4.80,14.40,1.00,0.00,1.00 -229,4.80,19.20,1.00,0.00,1.00 -230,4.80,24.00,1.00,0.00,1.00 -231,9.60,28.80,1.00,0.00,1.00 -232,9.60,33.60,1.00,0.00,1.00 -233,9.60,38.40,1.00,0.00,1.00 -234,14.40,43.20,1.00,0.00,1.00 -235,14.40,48.00,1.00,0.00,1.00 -236,19.20,52.80,1.00,0.00,1.00 -237,19.20,52.80,1.00,0.00,1.00 -238,24.00,57.60,1.00,0.00,1.00 -239,28.80,62.40,1.00,0.00,1.00 -240,38.40,67.20,1.00,0.00,1.00 -241,48.00,72.00,1.00,0.00,1.00 -242,57.60,72.00,1.00,0.00,1.00 -243,76.80,76.80,1.00,0.00,1.00 -244,96.00,76.80,1.00,0.00,1.00 -245,115.20,76.80,1.00,0.00,1.00 -246,129.60,72.00,1.00,0.00,1.00 -247,139.20,67.20,1.00,0.00,1.00 -248,144.00,67.20,1.00,0.00,1.00 -249,153.60,62.40,1.00,0.00,1.00 -250,158.40,57.60,1.00,0.00,1.00 -251,158.40,52.80,1.00,0.00,1.00 -252,163.20,48.00,1.00,0.00,1.00 -253,168.00,43.20,1.00,0.00,1.00 -254,168.00,38.40,1.00,0.00,1.00 -255,168.00,33.60,1.00,0.00,1.00 -256,172.80,28.80,1.00,0.00,1.00 -257,172.80,24.00,1.00,0.00,1.00 -258,172.80,19.20,1.00,0.00,1.00 -259,177.60,14.40,1.00,0.00,1.00 -260,177.60,9.60,1.00,0.00,1.00 -261,177.60,4.80,1.00,0.00,1.00 -262,177.60,0.00,1.00,0.00,1.00 -263,-177.60,-0.00,1.00,0.00,1.00 -264,-177.60,-4.80,1.00,0.00,1.00 -265,-177.60,-9.60,1.00,0.00,1.00 -266,-177.60,-14.40,1.00,0.00,1.00 -267,-172.80,-19.20,1.00,0.00,1.00 -268,-172.80,-24.00,1.00,0.00,1.00 -269,-172.80,-28.80,1.00,0.00,1.00 -270,-168.00,-33.60,1.00,0.00,1.00 -271,-168.00,-38.40,1.00,0.00,1.00 -272,-168.00,-43.20,1.00,0.00,1.00 -273,-163.20,-48.00,1.00,0.00,1.00 -274,-158.40,-52.80,1.00,0.00,1.00 -275,-158.40,-57.60,1.00,0.00,1.00 -276,-153.60,-62.40,1.00,0.00,1.00 -277,-144.00,-67.20,1.00,0.00,1.00 -278,-139.20,-67.20,1.00,0.00,1.00 -279,-129.60,-72.00,1.00,0.00,1.00 -280,-115.20,-76.80,1.00,0.00,1.00 -281,-96.00,-76.80,1.00,0.00,1.00 -282,-76.80,-76.80,1.00,0.00,1.00 -283,-57.60,-72.00,1.00,0.00,1.00 -284,-48.00,-72.00,1.00,0.00,1.00 -285,-38.40,-67.20,1.00,0.00,1.00 -286,-28.80,-62.40,1.00,0.00,1.00 -287,-24.00,-57.60,1.00,0.00,1.00 -288,-19.20,-52.80,1.00,0.00,1.00 -289,-19.20,-52.80,1.00,0.00,1.00 -290,-14.40,-48.00,1.00,0.00,1.00 -291,-14.40,-43.20,1.00,0.00,1.00 -292,-9.60,-38.40,1.00,0.00,1.00 -293,-9.60,-33.60,1.00,0.00,1.00 -294,-9.60,-28.80,1.00,0.00,1.00 -295,-4.80,-24.00,1.00,0.00,1.00 -296,-4.80,-19.20,1.00,0.00,1.00 -297,-4.80,-14.40,1.00,0.00,1.00 -298,-4.80,-9.60,1.00,0.00,1.00 -299,-0.00,-4.80,1.00,0.00,1.00 -300,0.00,0.00,1.00,0.00,1.00 -301,0.00,4.80,1.00,0.00,1.00 -302,4.80,9.60,1.00,0.00,1.00 -303,4.80,14.40,1.00,0.00,1.00 -304,4.80,19.20,1.00,0.00,1.00 -305,9.60,24.00,1.00,0.00,1.00 -306,9.60,28.80,1.00,0.00,1.00 -307,14.40,33.60,1.00,0.00,1.00 -308,14.40,33.60,1.00,0.00,1.00 -309,19.20,38.40,1.00,0.00,1.00 -310,19.20,43.20,1.00,0.00,1.00 -311,24.00,48.00,1.00,0.00,1.00 -312,28.80,52.80,1.00,0.00,1.00 -313,33.60,57.60,1.00,0.00,1.00 -314,38.40,62.40,1.00,0.00,1.00 -315,43.20,62.40,1.00,0.00,1.00 -316,52.80,67.20,1.00,0.00,1.00 -317,67.20,67.20,1.00,0.00,1.00 -318,76.80,72.00,1.00,0.00,1.00 -319,96.00,72.00,1.00,0.00,1.00 -320,105.60,72.00,1.00,0.00,1.00 -321,120.00,67.20,1.00,0.00,1.00 -322,129.60,67.20,1.00,0.00,1.00 -323,139.20,62.40,1.00,0.00,1.00 -324,144.00,57.60,1.00,0.00,1.00 -325,148.80,52.80,1.00,0.00,1.00 -326,153.60,52.80,1.00,0.00,1.00 -327,158.40,48.00,1.00,0.00,1.00 -328,163.20,43.20,1.00,0.00,1.00 -329,163.20,38.40,1.00,0.00,1.00 -330,168.00,33.60,1.00,0.00,1.00 -331,168.00,28.80,1.00,0.00,1.00 -332,172.80,24.00,1.00,0.00,1.00 -333,172.80,19.20,1.00,0.00,1.00 -334,172.80,14.40,1.00,0.00,1.00 -335,177.60,9.60,1.00,0.00,1.00 -336,177.60,4.80,1.00,0.00,1.00 -337,177.60,0.00,1.00,0.00,1.00 -338,-177.60,-0.00,1.00,0.00,1.00 -339,-177.60,-4.80,1.00,0.00,1.00 -340,-177.60,-9.60,1.00,0.00,1.00 -341,-172.80,-14.40,1.00,0.00,1.00 -342,-172.80,-19.20,1.00,0.00,1.00 -343,-172.80,-24.00,1.00,0.00,1.00 -344,-168.00,-28.80,1.00,0.00,1.00 -345,-168.00,-33.60,1.00,0.00,1.00 -346,-163.20,-38.40,1.00,0.00,1.00 -347,-163.20,-43.20,1.00,0.00,1.00 -348,-158.40,-48.00,1.00,0.00,1.00 -349,-153.60,-52.80,1.00,0.00,1.00 -350,-148.80,-52.80,1.00,0.00,1.00 -351,-144.00,-57.60,1.00,0.00,1.00 -352,-139.20,-62.40,1.00,0.00,1.00 -353,-129.60,-67.20,1.00,0.00,1.00 -354,-120.00,-67.20,1.00,0.00,1.00 -355,-105.60,-72.00,1.00,0.00,1.00 -356,-96.00,-72.00,1.00,0.00,1.00 -357,-76.80,-72.00,1.00,0.00,1.00 -358,-67.20,-67.20,1.00,0.00,1.00 -359,-52.80,-67.20,1.00,0.00,1.00 -360,-43.20,-62.40,1.00,0.00,1.00 -361,-38.40,-62.40,1.00,0.00,1.00 -362,-33.60,-57.60,1.00,0.00,1.00 -363,-28.80,-52.80,1.00,0.00,1.00 -364,-24.00,-48.00,1.00,0.00,1.00 -365,-19.20,-43.20,1.00,0.00,1.00 -366,-19.20,-38.40,1.00,0.00,1.00 -367,-14.40,-33.60,1.00,0.00,1.00 -368,-14.40,-33.60,1.00,0.00,1.00 -369,-9.60,-28.80,1.00,0.00,1.00 -370,-9.60,-24.00,1.00,0.00,1.00 -371,-4.80,-19.20,1.00,0.00,1.00 -372,-4.80,-14.40,1.00,0.00,1.00 -373,-4.80,-9.60,1.00,0.00,1.00 -374,-0.00,-4.80,1.00,0.00,1.00 -375,0.00,0.00,1.00,0.00,1.00 -376,0.00,4.80,1.00,0.00,1.00 -377,4.80,9.60,1.00,0.00,1.00 -378,4.80,14.40,1.00,0.00,1.00 -379,9.60,19.20,1.00,0.00,1.00 -380,9.60,24.00,1.00,0.00,1.00 -381,14.40,24.00,1.00,0.00,1.00 -382,14.40,28.80,1.00,0.00,1.00 -383,19.20,33.60,1.00,0.00,1.00 -384,19.20,38.40,1.00,0.00,1.00 -385,24.00,43.20,1.00,0.00,1.00 -386,28.80,48.00,1.00,0.00,1.00 -387,33.60,52.80,1.00,0.00,1.00 -388,38.40,52.80,1.00,0.00,1.00 -389,43.20,57.60,1.00,0.00,1.00 -390,52.80,62.40,1.00,0.00,1.00 -391,62.40,62.40,1.00,0.00,1.00 -392,72.00,62.40,1.00,0.00,1.00 -393,81.60,67.20,1.00,0.00,1.00 -394,91.20,67.20,1.00,0.00,1.00 -395,105.60,67.20,1.00,0.00,1.00 -396,115.20,62.40,1.00,0.00,1.00 -397,124.80,62.40,1.00,0.00,1.00 -398,134.40,57.60,1.00,0.00,1.00 -399,139.20,57.60,1.00,0.00,1.00 -400,144.00,52.80,1.00,0.00,1.00 -401,148.80,48.00,1.00,0.00,1.00 -402,153.60,43.20,1.00,0.00,1.00 -403,158.40,38.40,1.00,0.00,1.00 -404,158.40,38.40,1.00,0.00,1.00 -405,163.20,33.60,1.00,0.00,1.00 -406,168.00,28.80,1.00,0.00,1.00 -407,168.00,24.00,1.00,0.00,1.00 -408,172.80,19.20,1.00,0.00,1.00 -409,172.80,14.40,1.00,0.00,1.00 -410,172.80,9.60,1.00,0.00,1.00 -411,177.60,4.80,1.00,0.00,1.00 -412,177.60,0.00,1.00,0.00,1.00 -413,-177.60,-0.00,1.00,0.00,1.00 -414,-177.60,-4.80,1.00,0.00,1.00 -415,-172.80,-9.60,1.00,0.00,1.00 -416,-172.80,-14.40,1.00,0.00,1.00 -417,-172.80,-19.20,1.00,0.00,1.00 -418,-168.00,-24.00,1.00,0.00,1.00 -419,-168.00,-28.80,1.00,0.00,1.00 -420,-163.20,-33.60,1.00,0.00,1.00 -421,-158.40,-38.40,1.00,0.00,1.00 -422,-158.40,-38.40,1.00,0.00,1.00 -423,-153.60,-43.20,1.00,0.00,1.00 -424,-148.80,-48.00,1.00,0.00,1.00 -425,-144.00,-52.80,1.00,0.00,1.00 -426,-139.20,-57.60,1.00,0.00,1.00 -427,-134.40,-57.60,1.00,0.00,1.00 -428,-124.80,-62.40,1.00,0.00,1.00 -429,-115.20,-62.40,1.00,0.00,1.00 -430,-105.60,-67.20,1.00,0.00,1.00 -431,-91.20,-67.20,1.00,0.00,1.00 -432,-81.60,-67.20,1.00,0.00,1.00 -433,-72.00,-62.40,1.00,0.00,1.00 -434,-62.40,-62.40,1.00,0.00,1.00 -435,-52.80,-62.40,1.00,0.00,1.00 -436,-43.20,-57.60,1.00,0.00,1.00 -437,-38.40,-52.80,1.00,0.00,1.00 -438,-33.60,-52.80,1.00,0.00,1.00 -439,-28.80,-48.00,1.00,0.00,1.00 -440,-24.00,-43.20,1.00,0.00,1.00 -441,-19.20,-38.40,1.00,0.00,1.00 -442,-19.20,-33.60,1.00,0.00,1.00 -443,-14.40,-28.80,1.00,0.00,1.00 -444,-14.40,-24.00,1.00,0.00,1.00 -445,-9.60,-24.00,1.00,0.00,1.00 -446,-9.60,-19.20,1.00,0.00,1.00 -447,-4.80,-14.40,1.00,0.00,1.00 -448,-4.80,-9.60,1.00,0.00,1.00 -449,-0.00,-4.80,1.00,0.00,1.00 -450,0.00,0.00,1.00,0.00,1.00 -451,0.00,4.80,1.00,0.00,1.00 -452,4.80,9.60,1.00,0.00,1.00 -453,4.80,14.40,1.00,0.00,1.00 -454,9.60,14.40,1.00,0.00,1.00 -455,14.40,19.20,1.00,0.00,1.00 -456,14.40,24.00,1.00,0.00,1.00 -457,19.20,28.80,1.00,0.00,1.00 -458,19.20,33.60,1.00,0.00,1.00 -459,24.00,38.40,1.00,0.00,1.00 -460,28.80,38.40,1.00,0.00,1.00 -461,33.60,43.20,1.00,0.00,1.00 -462,38.40,48.00,1.00,0.00,1.00 -463,43.20,52.80,1.00,0.00,1.00 -464,48.00,52.80,1.00,0.00,1.00 -465,57.60,57.60,1.00,0.00,1.00 -466,62.40,57.60,1.00,0.00,1.00 -467,72.00,62.40,1.00,0.00,1.00 -468,81.60,62.40,1.00,0.00,1.00 -469,91.20,62.40,1.00,0.00,1.00 -470,100.80,62.40,1.00,0.00,1.00 -471,110.40,57.60,1.00,0.00,1.00 -472,120.00,57.60,1.00,0.00,1.00 -473,129.60,57.60,1.00,0.00,1.00 -474,134.40,52.80,1.00,0.00,1.00 -475,139.20,48.00,1.00,0.00,1.00 -476,144.00,48.00,1.00,0.00,1.00 -477,148.80,43.20,1.00,0.00,1.00 -478,153.60,38.40,1.00,0.00,1.00 -479,158.40,33.60,1.00,0.00,1.00 -480,158.40,28.80,1.00,0.00,1.00 -481,163.20,28.80,1.00,0.00,1.00 -482,168.00,24.00,1.00,0.00,1.00 -483,168.00,19.20,1.00,0.00,1.00 -484,172.80,14.40,1.00,0.00,1.00 -485,172.80,9.60,1.00,0.00,1.00 -486,177.60,4.80,1.00,0.00,1.00 -487,177.60,0.00,1.00,0.00,1.00 -488,-177.60,-0.00,1.00,0.00,1.00 -489,-177.60,-4.80,1.00,0.00,1.00 -490,-172.80,-9.60,1.00,0.00,1.00 -491,-172.80,-14.40,1.00,0.00,1.00 -492,-168.00,-19.20,1.00,0.00,1.00 -493,-168.00,-24.00,1.00,0.00,1.00 -494,-163.20,-28.80,1.00,0.00,1.00 -495,-158.40,-28.80,1.00,0.00,1.00 -496,-158.40,-33.60,1.00,0.00,1.00 -497,-153.60,-38.40,1.00,0.00,1.00 -498,-148.80,-43.20,1.00,0.00,1.00 -499,-144.00,-48.00,1.00,0.00,1.00 -500,-139.20,-48.00,1.00,0.00,1.00 -501,-134.40,-52.80,1.00,0.00,1.00 -502,-129.60,-57.60,1.00,0.00,1.00 -503,-120.00,-57.60,1.00,0.00,1.00 -504,-110.40,-57.60,1.00,0.00,1.00 -505,-100.80,-62.40,1.00,0.00,1.00 -506,-91.20,-62.40,1.00,0.00,1.00 -507,-81.60,-62.40,1.00,0.00,1.00 -508,-72.00,-62.40,1.00,0.00,1.00 -509,-62.40,-57.60,1.00,0.00,1.00 -510,-57.60,-57.60,1.00,0.00,1.00 -511,-48.00,-52.80,1.00,0.00,1.00 -512,-43.20,-52.80,1.00,0.00,1.00 -513,-38.40,-48.00,1.00,0.00,1.00 -514,-33.60,-43.20,1.00,0.00,1.00 -515,-28.80,-38.40,1.00,0.00,1.00 -516,-24.00,-38.40,1.00,0.00,1.00 -517,-19.20,-33.60,1.00,0.00,1.00 -518,-19.20,-28.80,1.00,0.00,1.00 -519,-14.40,-24.00,1.00,0.00,1.00 -520,-14.40,-19.20,1.00,0.00,1.00 -521,-9.60,-14.40,1.00,0.00,1.00 -522,-4.80,-14.40,1.00,0.00,1.00 -523,-4.80,-9.60,1.00,0.00,1.00 -524,-0.00,-4.80,1.00,0.00,1.00 -525,0.00,0.00,1.00,0.00,1.00 -526,4.80,4.80,1.00,0.00,1.00 -527,4.80,9.60,1.00,0.00,1.00 -528,9.60,9.60,1.00,0.00,1.00 -529,9.60,14.40,1.00,0.00,1.00 -530,14.40,19.20,1.00,0.00,1.00 -531,19.20,24.00,1.00,0.00,1.00 -532,19.20,28.80,1.00,0.00,1.00 -533,24.00,28.80,1.00,0.00,1.00 -534,28.80,33.60,1.00,0.00,1.00 -535,33.60,38.40,1.00,0.00,1.00 -536,38.40,43.20,1.00,0.00,1.00 -537,43.20,43.20,1.00,0.00,1.00 -538,48.00,48.00,1.00,0.00,1.00 -539,52.80,48.00,1.00,0.00,1.00 -540,57.60,52.80,1.00,0.00,1.00 -541,67.20,52.80,1.00,0.00,1.00 -542,76.80,57.60,1.00,0.00,1.00 -543,81.60,57.60,1.00,0.00,1.00 -544,91.20,57.60,1.00,0.00,1.00 -545,100.80,57.60,1.00,0.00,1.00 -546,110.40,52.80,1.00,0.00,1.00 -547,115.20,52.80,1.00,0.00,1.00 -548,124.80,52.80,1.00,0.00,1.00 -549,129.60,48.00,1.00,0.00,1.00 -550,134.40,48.00,1.00,0.00,1.00 -551,139.20,43.20,1.00,0.00,1.00 -552,144.00,38.40,1.00,0.00,1.00 -553,148.80,38.40,1.00,0.00,1.00 -554,153.60,33.60,1.00,0.00,1.00 -555,158.40,28.80,1.00,0.00,1.00 -556,163.20,24.00,1.00,0.00,1.00 -557,163.20,24.00,1.00,0.00,1.00 -558,168.00,19.20,1.00,0.00,1.00 -559,172.80,14.40,1.00,0.00,1.00 -560,172.80,9.60,1.00,0.00,1.00 -561,177.60,4.80,1.00,0.00,1.00 -562,177.60,0.00,1.00,0.00,1.00 -563,-177.60,-0.00,1.00,0.00,1.00 -564,-177.60,-4.80,1.00,0.00,1.00 -565,-172.80,-9.60,1.00,0.00,1.00 -566,-172.80,-14.40,1.00,0.00,1.00 -567,-168.00,-19.20,1.00,0.00,1.00 -568,-163.20,-24.00,1.00,0.00,1.00 -569,-163.20,-24.00,1.00,0.00,1.00 -570,-158.40,-28.80,1.00,0.00,1.00 -571,-153.60,-33.60,1.00,0.00,1.00 -572,-148.80,-38.40,1.00,0.00,1.00 -573,-144.00,-38.40,1.00,0.00,1.00 -574,-139.20,-43.20,1.00,0.00,1.00 -575,-134.40,-48.00,1.00,0.00,1.00 -576,-129.60,-48.00,1.00,0.00,1.00 -577,-124.80,-52.80,1.00,0.00,1.00 -578,-115.20,-52.80,1.00,0.00,1.00 -579,-110.40,-52.80,1.00,0.00,1.00 -580,-100.80,-57.60,1.00,0.00,1.00 -581,-91.20,-57.60,1.00,0.00,1.00 -582,-81.60,-57.60,1.00,0.00,1.00 -583,-76.80,-57.60,1.00,0.00,1.00 -584,-67.20,-52.80,1.00,0.00,1.00 -585,-57.60,-52.80,1.00,0.00,1.00 -586,-52.80,-48.00,1.00,0.00,1.00 -587,-48.00,-48.00,1.00,0.00,1.00 -588,-43.20,-43.20,1.00,0.00,1.00 -589,-38.40,-43.20,1.00,0.00,1.00 -590,-33.60,-38.40,1.00,0.00,1.00 -591,-28.80,-33.60,1.00,0.00,1.00 -592,-24.00,-28.80,1.00,0.00,1.00 -593,-19.20,-28.80,1.00,0.00,1.00 -594,-19.20,-24.00,1.00,0.00,1.00 -595,-14.40,-19.20,1.00,0.00,1.00 -596,-9.60,-14.40,1.00,0.00,1.00 -597,-9.60,-9.60,1.00,0.00,1.00 -598,-4.80,-9.60,1.00,0.00,1.00 -599,-4.80,-4.80,1.00,0.00,1.00 -600,0.00,0.00,1.00,0.00,1.00 -601,4.80,4.80,1.00,0.00,1.00 -602,4.80,9.60,1.00,0.00,1.00 -603,9.60,9.60,1.00,0.00,1.00 -604,14.40,14.40,1.00,0.00,1.00 -605,14.40,19.20,1.00,0.00,1.00 -606,19.20,24.00,1.00,0.00,1.00 -607,24.00,24.00,1.00,0.00,1.00 -608,24.00,28.80,1.00,0.00,1.00 -609,28.80,33.60,1.00,0.00,1.00 -610,33.60,33.60,1.00,0.00,1.00 -611,38.40,38.40,1.00,0.00,1.00 -612,43.20,43.20,1.00,0.00,1.00 -613,48.00,43.20,1.00,0.00,1.00 -614,57.60,48.00,1.00,0.00,1.00 -615,62.40,48.00,1.00,0.00,1.00 -616,67.20,48.00,1.00,0.00,1.00 -617,76.80,52.80,1.00,0.00,1.00 -618,86.40,52.80,1.00,0.00,1.00 -619,91.20,52.80,1.00,0.00,1.00 -620,100.80,52.80,1.00,0.00,1.00 -621,105.60,48.00,1.00,0.00,1.00 -622,115.20,48.00,1.00,0.00,1.00 -623,120.00,48.00,1.00,0.00,1.00 -624,124.80,43.20,1.00,0.00,1.00 -625,134.40,43.20,1.00,0.00,1.00 -626,139.20,38.40,1.00,0.00,1.00 -627,144.00,38.40,1.00,0.00,1.00 -628,148.80,33.60,1.00,0.00,1.00 -629,153.60,28.80,1.00,0.00,1.00 -630,153.60,28.80,1.00,0.00,1.00 -631,158.40,24.00,1.00,0.00,1.00 -632,163.20,19.20,1.00,0.00,1.00 -633,168.00,14.40,1.00,0.00,1.00 -634,168.00,14.40,1.00,0.00,1.00 -635,172.80,9.60,1.00,0.00,1.00 -636,177.60,4.80,1.00,0.00,1.00 -637,177.60,0.00,1.00,0.00,1.00 -638,-177.60,-0.00,1.00,0.00,1.00 -639,-177.60,-4.80,1.00,0.00,1.00 -640,-172.80,-9.60,1.00,0.00,1.00 -641,-168.00,-14.40,1.00,0.00,1.00 -642,-168.00,-14.40,1.00,0.00,1.00 -643,-163.20,-19.20,1.00,0.00,1.00 -644,-158.40,-24.00,1.00,0.00,1.00 -645,-153.60,-28.80,1.00,0.00,1.00 -646,-153.60,-28.80,1.00,0.00,1.00 -647,-148.80,-33.60,1.00,0.00,1.00 -648,-144.00,-38.40,1.00,0.00,1.00 -649,-139.20,-38.40,1.00,0.00,1.00 -650,-134.40,-43.20,1.00,0.00,1.00 -651,-124.80,-43.20,1.00,0.00,1.00 -652,-120.00,-48.00,1.00,0.00,1.00 -653,-115.20,-48.00,1.00,0.00,1.00 -654,-105.60,-48.00,1.00,0.00,1.00 -655,-100.80,-52.80,1.00,0.00,1.00 -656,-91.20,-52.80,1.00,0.00,1.00 -657,-86.40,-52.80,1.00,0.00,1.00 -658,-76.80,-52.80,1.00,0.00,1.00 -659,-67.20,-48.00,1.00,0.00,1.00 -660,-62.40,-48.00,1.00,0.00,1.00 -661,-57.60,-48.00,1.00,0.00,1.00 -662,-48.00,-43.20,1.00,0.00,1.00 -663,-43.20,-43.20,1.00,0.00,1.00 -664,-38.40,-38.40,1.00,0.00,1.00 -665,-33.60,-33.60,1.00,0.00,1.00 -666,-28.80,-33.60,1.00,0.00,1.00 -667,-24.00,-28.80,1.00,0.00,1.00 -668,-24.00,-24.00,1.00,0.00,1.00 -669,-19.20,-24.00,1.00,0.00,1.00 -670,-14.40,-19.20,1.00,0.00,1.00 -671,-14.40,-14.40,1.00,0.00,1.00 -672,-9.60,-9.60,1.00,0.00,1.00 -673,-4.80,-9.60,1.00,0.00,1.00 -674,-4.80,-4.80,1.00,0.00,1.00 -675,0.00,0.00,1.00,0.00,1.00 -676,4.80,4.80,1.00,0.00,1.00 -677,4.80,4.80,1.00,0.00,1.00 -678,9.60,9.60,1.00,0.00,1.00 -679,14.40,14.40,1.00,0.00,1.00 -680,19.20,19.20,1.00,0.00,1.00 -681,19.20,19.20,1.00,0.00,1.00 -682,24.00,24.00,1.00,0.00,1.00 -683,28.80,28.80,1.00,0.00,1.00 -684,33.60,28.80,1.00,0.00,1.00 -685,38.40,33.60,1.00,0.00,1.00 -686,43.20,33.60,1.00,0.00,1.00 -687,48.00,38.40,1.00,0.00,1.00 -688,52.80,38.40,1.00,0.00,1.00 -689,57.60,43.20,1.00,0.00,1.00 -690,62.40,43.20,1.00,0.00,1.00 -691,72.00,43.20,1.00,0.00,1.00 -692,76.80,48.00,1.00,0.00,1.00 -693,86.40,48.00,1.00,0.00,1.00 -694,91.20,48.00,1.00,0.00,1.00 -695,100.80,48.00,1.00,0.00,1.00 -696,105.60,48.00,1.00,0.00,1.00 -697,110.40,43.20,1.00,0.00,1.00 -698,120.00,43.20,1.00,0.00,1.00 -699,124.80,43.20,1.00,0.00,1.00 -700,129.60,38.40,1.00,0.00,1.00 -701,134.40,38.40,1.00,0.00,1.00 -702,139.20,33.60,1.00,0.00,1.00 -703,144.00,33.60,1.00,0.00,1.00 -704,148.80,28.80,1.00,0.00,1.00 -705,153.60,24.00,1.00,0.00,1.00 -706,158.40,24.00,1.00,0.00,1.00 -707,163.20,19.20,1.00,0.00,1.00 -708,163.20,14.40,1.00,0.00,1.00 -709,168.00,14.40,1.00,0.00,1.00 -710,172.80,9.60,1.00,0.00,1.00 -711,172.80,4.80,1.00,0.00,1.00 -712,177.60,0.00,1.00,0.00,1.00 -713,-177.60,-0.00,1.00,0.00,1.00 -714,-172.80,-4.80,1.00,0.00,1.00 -715,-172.80,-9.60,1.00,0.00,1.00 -716,-168.00,-14.40,1.00,0.00,1.00 -717,-163.20,-14.40,1.00,0.00,1.00 -718,-163.20,-19.20,1.00,0.00,1.00 -719,-158.40,-24.00,1.00,0.00,1.00 -720,-153.60,-24.00,1.00,0.00,1.00 -721,-148.80,-28.80,1.00,0.00,1.00 -722,-144.00,-33.60,1.00,0.00,1.00 -723,-139.20,-33.60,1.00,0.00,1.00 -724,-134.40,-38.40,1.00,0.00,1.00 -725,-129.60,-38.40,1.00,0.00,1.00 -726,-124.80,-43.20,1.00,0.00,1.00 -727,-120.00,-43.20,1.00,0.00,1.00 -728,-110.40,-43.20,1.00,0.00,1.00 -729,-105.60,-48.00,1.00,0.00,1.00 -730,-100.80,-48.00,1.00,0.00,1.00 -731,-91.20,-48.00,1.00,0.00,1.00 -732,-86.40,-48.00,1.00,0.00,1.00 -733,-76.80,-48.00,1.00,0.00,1.00 -734,-72.00,-43.20,1.00,0.00,1.00 -735,-62.40,-43.20,1.00,0.00,1.00 -736,-57.60,-43.20,1.00,0.00,1.00 -737,-52.80,-38.40,1.00,0.00,1.00 -738,-48.00,-38.40,1.00,0.00,1.00 -739,-43.20,-33.60,1.00,0.00,1.00 -740,-38.40,-33.60,1.00,0.00,1.00 -741,-33.60,-28.80,1.00,0.00,1.00 -742,-28.80,-28.80,1.00,0.00,1.00 -743,-24.00,-24.00,1.00,0.00,1.00 -744,-19.20,-19.20,1.00,0.00,1.00 -745,-19.20,-19.20,1.00,0.00,1.00 -746,-14.40,-14.40,1.00,0.00,1.00 -747,-9.60,-9.60,1.00,0.00,1.00 -748,-4.80,-4.80,1.00,0.00,1.00 -749,-4.80,-4.80,1.00,0.00,1.00 -750,0.00,0.00,1.00,0.00,1.00 -751,4.80,4.80,1.00,0.00,1.00 -752,4.80,4.80,1.00,0.00,1.00 -753,9.60,9.60,1.00,0.00,1.00 -754,14.40,14.40,1.00,0.00,1.00 -755,19.20,14.40,1.00,0.00,1.00 -756,24.00,19.20,1.00,0.00,1.00 -757,24.00,24.00,1.00,0.00,1.00 -758,28.80,24.00,1.00,0.00,1.00 -759,33.60,28.80,1.00,0.00,1.00 -760,38.40,28.80,1.00,0.00,1.00 -761,43.20,33.60,1.00,0.00,1.00 -762,48.00,33.60,1.00,0.00,1.00 -763,52.80,38.40,1.00,0.00,1.00 -764,62.40,38.40,1.00,0.00,1.00 -765,67.20,38.40,1.00,0.00,1.00 -766,72.00,38.40,1.00,0.00,1.00 -767,76.80,43.20,1.00,0.00,1.00 -768,86.40,43.20,1.00,0.00,1.00 -769,91.20,43.20,1.00,0.00,1.00 -770,96.00,43.20,1.00,0.00,1.00 -771,105.60,43.20,1.00,0.00,1.00 -772,110.40,38.40,1.00,0.00,1.00 -773,115.20,38.40,1.00,0.00,1.00 -774,120.00,38.40,1.00,0.00,1.00 -775,129.60,33.60,1.00,0.00,1.00 -776,134.40,33.60,1.00,0.00,1.00 -777,139.20,28.80,1.00,0.00,1.00 -778,144.00,28.80,1.00,0.00,1.00 -779,148.80,24.00,1.00,0.00,1.00 -780,153.60,24.00,1.00,0.00,1.00 -781,153.60,19.20,1.00,0.00,1.00 -782,158.40,19.20,1.00,0.00,1.00 -783,163.20,14.40,1.00,0.00,1.00 -784,168.00,9.60,1.00,0.00,1.00 -785,172.80,9.60,1.00,0.00,1.00 -786,172.80,4.80,1.00,0.00,1.00 -787,177.60,0.00,1.00,0.00,1.00 -788,-177.60,-0.00,1.00,0.00,1.00 -789,-172.80,-4.80,1.00,0.00,1.00 -790,-172.80,-9.60,1.00,0.00,1.00 -791,-168.00,-9.60,1.00,0.00,1.00 -792,-163.20,-14.40,1.00,0.00,1.00 -793,-158.40,-19.20,1.00,0.00,1.00 -794,-153.60,-19.20,1.00,0.00,1.00 -795,-153.60,-24.00,1.00,0.00,1.00 -796,-148.80,-24.00,1.00,0.00,1.00 -797,-144.00,-28.80,1.00,0.00,1.00 -798,-139.20,-28.80,1.00,0.00,1.00 -799,-134.40,-33.60,1.00,0.00,1.00 -800,-129.60,-33.60,1.00,0.00,1.00 -801,-120.00,-38.40,1.00,0.00,1.00 -802,-115.20,-38.40,1.00,0.00,1.00 -803,-110.40,-38.40,1.00,0.00,1.00 -804,-105.60,-43.20,1.00,0.00,1.00 -805,-96.00,-43.20,1.00,0.00,1.00 -806,-91.20,-43.20,1.00,0.00,1.00 -807,-86.40,-43.20,1.00,0.00,1.00 -808,-76.80,-43.20,1.00,0.00,1.00 -809,-72.00,-38.40,1.00,0.00,1.00 -810,-67.20,-38.40,1.00,0.00,1.00 -811,-62.40,-38.40,1.00,0.00,1.00 -812,-52.80,-38.40,1.00,0.00,1.00 -813,-48.00,-33.60,1.00,0.00,1.00 -814,-43.20,-33.60,1.00,0.00,1.00 -815,-38.40,-28.80,1.00,0.00,1.00 -816,-33.60,-28.80,1.00,0.00,1.00 -817,-28.80,-24.00,1.00,0.00,1.00 -818,-24.00,-24.00,1.00,0.00,1.00 -819,-24.00,-19.20,1.00,0.00,1.00 -820,-19.20,-14.40,1.00,0.00,1.00 -821,-14.40,-14.40,1.00,0.00,1.00 -822,-9.60,-9.60,1.00,0.00,1.00 -823,-4.80,-4.80,1.00,0.00,1.00 -824,-4.80,-4.80,1.00,0.00,1.00 -825,0.00,0.00,1.00,0.00,1.00 -826,4.80,4.80,1.00,0.00,1.00 -827,9.60,4.80,1.00,0.00,1.00 -828,9.60,9.60,1.00,0.00,1.00 -829,14.40,9.60,1.00,0.00,1.00 -830,19.20,14.40,1.00,0.00,1.00 -831,24.00,19.20,1.00,0.00,1.00 -832,28.80,19.20,1.00,0.00,1.00 -833,33.60,24.00,1.00,0.00,1.00 -834,38.40,24.00,1.00,0.00,1.00 -835,43.20,28.80,1.00,0.00,1.00 -836,48.00,28.80,1.00,0.00,1.00 -837,52.80,28.80,1.00,0.00,1.00 -838,57.60,33.60,1.00,0.00,1.00 -839,62.40,33.60,1.00,0.00,1.00 -840,67.20,33.60,1.00,0.00,1.00 -841,72.00,38.40,1.00,0.00,1.00 -842,81.60,38.40,1.00,0.00,1.00 -843,86.40,38.40,1.00,0.00,1.00 -844,91.20,38.40,1.00,0.00,1.00 -845,96.00,38.40,1.00,0.00,1.00 -846,105.60,38.40,1.00,0.00,1.00 -847,110.40,33.60,1.00,0.00,1.00 -848,115.20,33.60,1.00,0.00,1.00 -849,120.00,33.60,1.00,0.00,1.00 -850,124.80,33.60,1.00,0.00,1.00 -851,129.60,28.80,1.00,0.00,1.00 -852,134.40,28.80,1.00,0.00,1.00 -853,139.20,24.00,1.00,0.00,1.00 -854,144.00,24.00,1.00,0.00,1.00 -855,148.80,19.20,1.00,0.00,1.00 -856,153.60,19.20,1.00,0.00,1.00 -857,158.40,14.40,1.00,0.00,1.00 -858,163.20,14.40,1.00,0.00,1.00 -859,168.00,9.60,1.00,0.00,1.00 -860,168.00,9.60,1.00,0.00,1.00 -861,172.80,4.80,1.00,0.00,1.00 -862,177.60,0.00,1.00,0.00,1.00 -863,-177.60,-0.00,1.00,0.00,1.00 -864,-172.80,-4.80,1.00,0.00,1.00 -865,-168.00,-9.60,1.00,0.00,1.00 -866,-168.00,-9.60,1.00,0.00,1.00 -867,-163.20,-14.40,1.00,0.00,1.00 -868,-158.40,-14.40,1.00,0.00,1.00 -869,-153.60,-19.20,1.00,0.00,1.00 -870,-148.80,-19.20,1.00,0.00,1.00 -871,-144.00,-24.00,1.00,0.00,1.00 -872,-139.20,-24.00,1.00,0.00,1.00 -873,-134.40,-28.80,1.00,0.00,1.00 -874,-129.60,-28.80,1.00,0.00,1.00 -875,-124.80,-33.60,1.00,0.00,1.00 -876,-120.00,-33.60,1.00,0.00,1.00 -877,-115.20,-33.60,1.00,0.00,1.00 -878,-110.40,-33.60,1.00,0.00,1.00 -879,-105.60,-38.40,1.00,0.00,1.00 -880,-96.00,-38.40,1.00,0.00,1.00 -881,-91.20,-38.40,1.00,0.00,1.00 -882,-86.40,-38.40,1.00,0.00,1.00 -883,-81.60,-38.40,1.00,0.00,1.00 -884,-72.00,-38.40,1.00,0.00,1.00 -885,-67.20,-33.60,1.00,0.00,1.00 -886,-62.40,-33.60,1.00,0.00,1.00 -887,-57.60,-33.60,1.00,0.00,1.00 -888,-52.80,-28.80,1.00,0.00,1.00 -889,-48.00,-28.80,1.00,0.00,1.00 -890,-43.20,-28.80,1.00,0.00,1.00 -891,-38.40,-24.00,1.00,0.00,1.00 -892,-33.60,-24.00,1.00,0.00,1.00 -893,-28.80,-19.20,1.00,0.00,1.00 -894,-24.00,-19.20,1.00,0.00,1.00 -895,-19.20,-14.40,1.00,0.00,1.00 -896,-14.40,-9.60,1.00,0.00,1.00 -897,-9.60,-9.60,1.00,0.00,1.00 -898,-9.60,-4.80,1.00,0.00,1.00 -899,-4.80,-4.80,1.00,0.00,1.00 -900,0.00,0.00,1.00,0.00,1.00 -901,4.80,4.80,1.00,0.00,1.00 -902,9.60,4.80,1.00,0.00,1.00 -903,14.40,9.60,1.00,0.00,1.00 -904,14.40,9.60,1.00,0.00,1.00 -905,19.20,14.40,1.00,0.00,1.00 -906,24.00,14.40,1.00,0.00,1.00 -907,28.80,19.20,1.00,0.00,1.00 -908,33.60,19.20,1.00,0.00,1.00 -909,38.40,19.20,1.00,0.00,1.00 -910,43.20,24.00,1.00,0.00,1.00 -911,48.00,24.00,1.00,0.00,1.00 -912,52.80,28.80,1.00,0.00,1.00 -913,57.60,28.80,1.00,0.00,1.00 -914,62.40,28.80,1.00,0.00,1.00 -915,67.20,28.80,1.00,0.00,1.00 -916,76.80,33.60,1.00,0.00,1.00 -917,81.60,33.60,1.00,0.00,1.00 -918,86.40,33.60,1.00,0.00,1.00 -919,91.20,33.60,1.00,0.00,1.00 -920,96.00,33.60,1.00,0.00,1.00 -921,100.80,33.60,1.00,0.00,1.00 -922,110.40,28.80,1.00,0.00,1.00 -923,115.20,28.80,1.00,0.00,1.00 -924,120.00,28.80,1.00,0.00,1.00 -925,124.80,28.80,1.00,0.00,1.00 -926,129.60,24.00,1.00,0.00,1.00 -927,134.40,24.00,1.00,0.00,1.00 -928,139.20,24.00,1.00,0.00,1.00 -929,144.00,19.20,1.00,0.00,1.00 -930,148.80,19.20,1.00,0.00,1.00 -931,153.60,14.40,1.00,0.00,1.00 -932,158.40,14.40,1.00,0.00,1.00 -933,163.20,9.60,1.00,0.00,1.00 -934,168.00,9.60,1.00,0.00,1.00 -935,168.00,4.80,1.00,0.00,1.00 -936,172.80,4.80,1.00,0.00,1.00 -937,177.60,0.00,1.00,0.00,1.00 -938,-177.60,-0.00,1.00,0.00,1.00 -939,-172.80,-4.80,1.00,0.00,1.00 -940,-168.00,-4.80,1.00,0.00,1.00 -941,-168.00,-9.60,1.00,0.00,1.00 -942,-163.20,-9.60,1.00,0.00,1.00 -943,-158.40,-14.40,1.00,0.00,1.00 -944,-153.60,-14.40,1.00,0.00,1.00 -945,-148.80,-19.20,1.00,0.00,1.00 -946,-144.00,-19.20,1.00,0.00,1.00 -947,-139.20,-24.00,1.00,0.00,1.00 -948,-134.40,-24.00,1.00,0.00,1.00 -949,-129.60,-24.00,1.00,0.00,1.00 -950,-124.80,-28.80,1.00,0.00,1.00 -951,-120.00,-28.80,1.00,0.00,1.00 -952,-115.20,-28.80,1.00,0.00,1.00 -953,-110.40,-28.80,1.00,0.00,1.00 -954,-100.80,-33.60,1.00,0.00,1.00 -955,-96.00,-33.60,1.00,0.00,1.00 -956,-91.20,-33.60,1.00,0.00,1.00 -957,-86.40,-33.60,1.00,0.00,1.00 -958,-81.60,-33.60,1.00,0.00,1.00 -959,-76.80,-33.60,1.00,0.00,1.00 -960,-67.20,-28.80,1.00,0.00,1.00 -961,-62.40,-28.80,1.00,0.00,1.00 -962,-57.60,-28.80,1.00,0.00,1.00 -963,-52.80,-28.80,1.00,0.00,1.00 -964,-48.00,-24.00,1.00,0.00,1.00 -965,-43.20,-24.00,1.00,0.00,1.00 -966,-38.40,-19.20,1.00,0.00,1.00 -967,-33.60,-19.20,1.00,0.00,1.00 -968,-28.80,-19.20,1.00,0.00,1.00 -969,-24.00,-14.40,1.00,0.00,1.00 -970,-19.20,-14.40,1.00,0.00,1.00 -971,-14.40,-9.60,1.00,0.00,1.00 -972,-14.40,-9.60,1.00,0.00,1.00 -973,-9.60,-4.80,1.00,0.00,1.00 -974,-4.80,-4.80,1.00,0.00,1.00 -975,0.00,0.00,1.00,0.00,1.00 -976,4.80,0.00,1.00,0.00,1.00 -977,9.60,4.80,1.00,0.00,1.00 -978,14.40,4.80,1.00,0.00,1.00 -979,19.20,9.60,1.00,0.00,1.00 -980,19.20,9.60,1.00,0.00,1.00 -981,24.00,14.40,1.00,0.00,1.00 -982,28.80,14.40,1.00,0.00,1.00 -983,33.60,14.40,1.00,0.00,1.00 -984,38.40,19.20,1.00,0.00,1.00 -985,43.20,19.20,1.00,0.00,1.00 -986,48.00,24.00,1.00,0.00,1.00 -987,52.80,24.00,1.00,0.00,1.00 -988,57.60,24.00,1.00,0.00,1.00 -989,62.40,24.00,1.00,0.00,1.00 -990,72.00,24.00,1.00,0.00,1.00 -991,76.80,28.80,1.00,0.00,1.00 -992,81.60,28.80,1.00,0.00,1.00 -993,86.40,28.80,1.00,0.00,1.00 -994,91.20,28.80,1.00,0.00,1.00 -995,96.00,28.80,1.00,0.00,1.00 -996,100.80,28.80,1.00,0.00,1.00 -997,105.60,28.80,1.00,0.00,1.00 -998,110.40,24.00,1.00,0.00,1.00 -999,120.00,24.00,1.00,0.00,1.00 -1000,124.80,24.00,1.00,0.00,1.00 -1001,129.60,24.00,1.00,0.00,1.00 -1002,134.40,19.20,1.00,0.00,1.00 -1003,139.20,19.20,1.00,0.00,1.00 -1004,144.00,19.20,1.00,0.00,1.00 -1005,148.80,14.40,1.00,0.00,1.00 -1006,153.60,14.40,1.00,0.00,1.00 -1007,158.40,9.60,1.00,0.00,1.00 -1008,158.40,9.60,1.00,0.00,1.00 -1009,163.20,9.60,1.00,0.00,1.00 -1010,168.00,4.80,1.00,0.00,1.00 -1011,172.80,4.80,1.00,0.00,1.00 -1012,177.60,0.00,1.00,0.00,1.00 -1013,-177.60,-0.00,1.00,0.00,1.00 -1014,-172.80,-4.80,1.00,0.00,1.00 -1015,-168.00,-4.80,1.00,0.00,1.00 -1016,-163.20,-9.60,1.00,0.00,1.00 -1017,-158.40,-9.60,1.00,0.00,1.00 -1018,-158.40,-9.60,1.00,0.00,1.00 -1019,-153.60,-14.40,1.00,0.00,1.00 -1020,-148.80,-14.40,1.00,0.00,1.00 -1021,-144.00,-19.20,1.00,0.00,1.00 -1022,-139.20,-19.20,1.00,0.00,1.00 -1023,-134.40,-19.20,1.00,0.00,1.00 -1024,-129.60,-24.00,1.00,0.00,1.00 -1025,-124.80,-24.00,1.00,0.00,1.00 -1026,-120.00,-24.00,1.00,0.00,1.00 -1027,-110.40,-24.00,1.00,0.00,1.00 -1028,-105.60,-28.80,1.00,0.00,1.00 -1029,-100.80,-28.80,1.00,0.00,1.00 -1030,-96.00,-28.80,1.00,0.00,1.00 -1031,-91.20,-28.80,1.00,0.00,1.00 -1032,-86.40,-28.80,1.00,0.00,1.00 -1033,-81.60,-28.80,1.00,0.00,1.00 -1034,-76.80,-28.80,1.00,0.00,1.00 -1035,-72.00,-24.00,1.00,0.00,1.00 -1036,-62.40,-24.00,1.00,0.00,1.00 -1037,-57.60,-24.00,1.00,0.00,1.00 -1038,-52.80,-24.00,1.00,0.00,1.00 -1039,-48.00,-24.00,1.00,0.00,1.00 -1040,-43.20,-19.20,1.00,0.00,1.00 -1041,-38.40,-19.20,1.00,0.00,1.00 -1042,-33.60,-14.40,1.00,0.00,1.00 -1043,-28.80,-14.40,1.00,0.00,1.00 -1044,-24.00,-14.40,1.00,0.00,1.00 -1045,-19.20,-9.60,1.00,0.00,1.00 -1046,-19.20,-9.60,1.00,0.00,1.00 -1047,-14.40,-4.80,1.00,0.00,1.00 -1048,-9.60,-4.80,1.00,0.00,1.00 -1049,-4.80,-0.00,1.00,0.00,1.00 -1050,0.00,0.00,1.00,0.00,1.00 -1051,4.80,0.00,1.00,0.00,1.00 -1052,9.60,4.80,1.00,0.00,1.00 -1053,14.40,4.80,1.00,0.00,1.00 -1054,19.20,9.60,1.00,0.00,1.00 -1055,24.00,9.60,1.00,0.00,1.00 -1056,28.80,9.60,1.00,0.00,1.00 -1057,33.60,14.40,1.00,0.00,1.00 -1058,38.40,14.40,1.00,0.00,1.00 -1059,43.20,14.40,1.00,0.00,1.00 -1060,48.00,14.40,1.00,0.00,1.00 -1061,52.80,19.20,1.00,0.00,1.00 -1062,57.60,19.20,1.00,0.00,1.00 -1063,62.40,19.20,1.00,0.00,1.00 -1064,67.20,19.20,1.00,0.00,1.00 -1065,72.00,24.00,1.00,0.00,1.00 -1066,76.80,24.00,1.00,0.00,1.00 -1067,81.60,24.00,1.00,0.00,1.00 -1068,86.40,24.00,1.00,0.00,1.00 -1069,91.20,24.00,1.00,0.00,1.00 -1070,96.00,24.00,1.00,0.00,1.00 -1071,100.80,24.00,1.00,0.00,1.00 -1072,105.60,24.00,1.00,0.00,1.00 -1073,110.40,19.20,1.00,0.00,1.00 -1074,115.20,19.20,1.00,0.00,1.00 -1075,120.00,19.20,1.00,0.00,1.00 -1076,124.80,19.20,1.00,0.00,1.00 -1077,129.60,19.20,1.00,0.00,1.00 -1078,134.40,14.40,1.00,0.00,1.00 -1079,139.20,14.40,1.00,0.00,1.00 -1080,144.00,14.40,1.00,0.00,1.00 -1081,148.80,9.60,1.00,0.00,1.00 -1082,153.60,9.60,1.00,0.00,1.00 -1083,158.40,9.60,1.00,0.00,1.00 -1084,163.20,4.80,1.00,0.00,1.00 -1085,168.00,4.80,1.00,0.00,1.00 -1086,172.80,4.80,1.00,0.00,1.00 -1087,177.60,0.00,1.00,0.00,1.00 -1088,-177.60,-0.00,1.00,0.00,1.00 -1089,-172.80,-4.80,1.00,0.00,1.00 -1090,-168.00,-4.80,1.00,0.00,1.00 -1091,-163.20,-4.80,1.00,0.00,1.00 -1092,-158.40,-9.60,1.00,0.00,1.00 -1093,-153.60,-9.60,1.00,0.00,1.00 -1094,-148.80,-9.60,1.00,0.00,1.00 -1095,-144.00,-14.40,1.00,0.00,1.00 -1096,-139.20,-14.40,1.00,0.00,1.00 -1097,-134.40,-14.40,1.00,0.00,1.00 -1098,-129.60,-19.20,1.00,0.00,1.00 -1099,-124.80,-19.20,1.00,0.00,1.00 -1100,-120.00,-19.20,1.00,0.00,1.00 -1101,-115.20,-19.20,1.00,0.00,1.00 -1102,-110.40,-19.20,1.00,0.00,1.00 -1103,-105.60,-24.00,1.00,0.00,1.00 -1104,-100.80,-24.00,1.00,0.00,1.00 -1105,-96.00,-24.00,1.00,0.00,1.00 -1106,-91.20,-24.00,1.00,0.00,1.00 -1107,-86.40,-24.00,1.00,0.00,1.00 -1108,-81.60,-24.00,1.00,0.00,1.00 -1109,-76.80,-24.00,1.00,0.00,1.00 -1110,-72.00,-24.00,1.00,0.00,1.00 -1111,-67.20,-19.20,1.00,0.00,1.00 -1112,-62.40,-19.20,1.00,0.00,1.00 -1113,-57.60,-19.20,1.00,0.00,1.00 -1114,-52.80,-19.20,1.00,0.00,1.00 -1115,-48.00,-14.40,1.00,0.00,1.00 -1116,-43.20,-14.40,1.00,0.00,1.00 -1117,-38.40,-14.40,1.00,0.00,1.00 -1118,-33.60,-14.40,1.00,0.00,1.00 -1119,-28.80,-9.60,1.00,0.00,1.00 -1120,-24.00,-9.60,1.00,0.00,1.00 -1121,-19.20,-9.60,1.00,0.00,1.00 -1122,-14.40,-4.80,1.00,0.00,1.00 -1123,-9.60,-4.80,1.00,0.00,1.00 -1124,-4.80,-0.00,1.00,0.00,1.00 -1125,0.00,0.00,1.00,0.00,1.00 -1126,4.80,0.00,1.00,0.00,1.00 -1127,9.60,4.80,1.00,0.00,1.00 -1128,14.40,4.80,1.00,0.00,1.00 -1129,19.20,4.80,1.00,0.00,1.00 -1130,24.00,9.60,1.00,0.00,1.00 -1131,28.80,9.60,1.00,0.00,1.00 -1132,33.60,9.60,1.00,0.00,1.00 -1133,38.40,9.60,1.00,0.00,1.00 -1134,43.20,14.40,1.00,0.00,1.00 -1135,48.00,14.40,1.00,0.00,1.00 -1136,52.80,14.40,1.00,0.00,1.00 -1137,57.60,14.40,1.00,0.00,1.00 -1138,62.40,14.40,1.00,0.00,1.00 -1139,67.20,14.40,1.00,0.00,1.00 -1140,72.00,19.20,1.00,0.00,1.00 -1141,76.80,19.20,1.00,0.00,1.00 -1142,81.60,19.20,1.00,0.00,1.00 -1143,86.40,19.20,1.00,0.00,1.00 -1144,91.20,19.20,1.00,0.00,1.00 -1145,96.00,19.20,1.00,0.00,1.00 -1146,100.80,19.20,1.00,0.00,1.00 -1147,105.60,19.20,1.00,0.00,1.00 -1148,110.40,19.20,1.00,0.00,1.00 -1149,115.20,14.40,1.00,0.00,1.00 -1150,120.00,14.40,1.00,0.00,1.00 -1151,124.80,14.40,1.00,0.00,1.00 -1152,129.60,14.40,1.00,0.00,1.00 -1153,134.40,14.40,1.00,0.00,1.00 -1154,139.20,9.60,1.00,0.00,1.00 -1155,144.00,9.60,1.00,0.00,1.00 -1156,148.80,9.60,1.00,0.00,1.00 -1157,153.60,9.60,1.00,0.00,1.00 -1158,158.40,4.80,1.00,0.00,1.00 -1159,163.20,4.80,1.00,0.00,1.00 -1160,168.00,4.80,1.00,0.00,1.00 -1161,172.80,0.00,1.00,0.00,1.00 -1162,177.60,0.00,1.00,0.00,1.00 -1163,-177.60,-0.00,1.00,0.00,1.00 -1164,-172.80,-0.00,1.00,0.00,1.00 -1165,-168.00,-4.80,1.00,0.00,1.00 -1166,-163.20,-4.80,1.00,0.00,1.00 -1167,-158.40,-4.80,1.00,0.00,1.00 -1168,-153.60,-9.60,1.00,0.00,1.00 -1169,-148.80,-9.60,1.00,0.00,1.00 -1170,-144.00,-9.60,1.00,0.00,1.00 -1171,-139.20,-9.60,1.00,0.00,1.00 -1172,-134.40,-14.40,1.00,0.00,1.00 -1173,-129.60,-14.40,1.00,0.00,1.00 -1174,-124.80,-14.40,1.00,0.00,1.00 -1175,-120.00,-14.40,1.00,0.00,1.00 -1176,-115.20,-14.40,1.00,0.00,1.00 -1177,-110.40,-19.20,1.00,0.00,1.00 -1178,-105.60,-19.20,1.00,0.00,1.00 -1179,-100.80,-19.20,1.00,0.00,1.00 -1180,-96.00,-19.20,1.00,0.00,1.00 -1181,-91.20,-19.20,1.00,0.00,1.00 -1182,-86.40,-19.20,1.00,0.00,1.00 -1183,-81.60,-19.20,1.00,0.00,1.00 -1184,-76.80,-19.20,1.00,0.00,1.00 -1185,-72.00,-19.20,1.00,0.00,1.00 -1186,-67.20,-14.40,1.00,0.00,1.00 -1187,-62.40,-14.40,1.00,0.00,1.00 -1188,-57.60,-14.40,1.00,0.00,1.00 -1189,-52.80,-14.40,1.00,0.00,1.00 -1190,-48.00,-14.40,1.00,0.00,1.00 -1191,-43.20,-14.40,1.00,0.00,1.00 -1192,-38.40,-9.60,1.00,0.00,1.00 -1193,-33.60,-9.60,1.00,0.00,1.00 -1194,-28.80,-9.60,1.00,0.00,1.00 -1195,-24.00,-9.60,1.00,0.00,1.00 -1196,-19.20,-4.80,1.00,0.00,1.00 -1197,-14.40,-4.80,1.00,0.00,1.00 -1198,-9.60,-4.80,1.00,0.00,1.00 -1199,-4.80,-0.00,1.00,0.00,1.00 -1200,0.00,0.00,1.00,0.00,1.00 -1201,4.80,0.00,1.00,0.00,1.00 -1202,9.60,0.00,1.00,0.00,1.00 -1203,14.40,4.80,1.00,0.00,1.00 -1204,19.20,4.80,1.00,0.00,1.00 -1205,24.00,4.80,1.00,0.00,1.00 -1206,28.80,4.80,1.00,0.00,1.00 -1207,33.60,9.60,1.00,0.00,1.00 -1208,38.40,9.60,1.00,0.00,1.00 -1209,43.20,9.60,1.00,0.00,1.00 -1210,48.00,9.60,1.00,0.00,1.00 -1211,52.80,9.60,1.00,0.00,1.00 -1212,57.60,9.60,1.00,0.00,1.00 -1213,62.40,9.60,1.00,0.00,1.00 -1214,67.20,14.40,1.00,0.00,1.00 -1215,72.00,14.40,1.00,0.00,1.00 -1216,76.80,14.40,1.00,0.00,1.00 -1217,81.60,14.40,1.00,0.00,1.00 -1218,86.40,14.40,1.00,0.00,1.00 -1219,91.20,14.40,1.00,0.00,1.00 -1220,96.00,14.40,1.00,0.00,1.00 -1221,100.80,14.40,1.00,0.00,1.00 -1222,105.60,14.40,1.00,0.00,1.00 -1223,110.40,14.40,1.00,0.00,1.00 -1224,115.20,9.60,1.00,0.00,1.00 -1225,120.00,9.60,1.00,0.00,1.00 -1226,124.80,9.60,1.00,0.00,1.00 -1227,129.60,9.60,1.00,0.00,1.00 -1228,134.40,9.60,1.00,0.00,1.00 -1229,139.20,9.60,1.00,0.00,1.00 -1230,144.00,9.60,1.00,0.00,1.00 -1231,148.80,4.80,1.00,0.00,1.00 -1232,153.60,4.80,1.00,0.00,1.00 -1233,158.40,4.80,1.00,0.00,1.00 -1234,163.20,4.80,1.00,0.00,1.00 -1235,168.00,4.80,1.00,0.00,1.00 -1236,172.80,0.00,1.00,0.00,1.00 -1237,177.60,0.00,1.00,0.00,1.00 -1238,-177.60,-0.00,1.00,0.00,1.00 -1239,-172.80,-0.00,1.00,0.00,1.00 -1240,-168.00,-4.80,1.00,0.00,1.00 -1241,-163.20,-4.80,1.00,0.00,1.00 -1242,-158.40,-4.80,1.00,0.00,1.00 -1243,-153.60,-4.80,1.00,0.00,1.00 -1244,-148.80,-4.80,1.00,0.00,1.00 -1245,-144.00,-9.60,1.00,0.00,1.00 -1246,-139.20,-9.60,1.00,0.00,1.00 -1247,-134.40,-9.60,1.00,0.00,1.00 -1248,-129.60,-9.60,1.00,0.00,1.00 -1249,-124.80,-9.60,1.00,0.00,1.00 -1250,-120.00,-9.60,1.00,0.00,1.00 -1251,-115.20,-9.60,1.00,0.00,1.00 -1252,-110.40,-14.40,1.00,0.00,1.00 -1253,-105.60,-14.40,1.00,0.00,1.00 -1254,-100.80,-14.40,1.00,0.00,1.00 -1255,-96.00,-14.40,1.00,0.00,1.00 -1256,-91.20,-14.40,1.00,0.00,1.00 -1257,-86.40,-14.40,1.00,0.00,1.00 -1258,-81.60,-14.40,1.00,0.00,1.00 -1259,-76.80,-14.40,1.00,0.00,1.00 -1260,-72.00,-14.40,1.00,0.00,1.00 -1261,-67.20,-14.40,1.00,0.00,1.00 -1262,-62.40,-9.60,1.00,0.00,1.00 -1263,-57.60,-9.60,1.00,0.00,1.00 -1264,-52.80,-9.60,1.00,0.00,1.00 -1265,-48.00,-9.60,1.00,0.00,1.00 -1266,-43.20,-9.60,1.00,0.00,1.00 -1267,-38.40,-9.60,1.00,0.00,1.00 -1268,-33.60,-9.60,1.00,0.00,1.00 -1269,-28.80,-4.80,1.00,0.00,1.00 -1270,-24.00,-4.80,1.00,0.00,1.00 -1271,-19.20,-4.80,1.00,0.00,1.00 -1272,-14.40,-4.80,1.00,0.00,1.00 -1273,-9.60,-0.00,1.00,0.00,1.00 -1274,-4.80,-0.00,1.00,0.00,1.00 -1275,0.00,0.00,1.00,0.00,1.00 -1276,4.80,0.00,1.00,0.00,1.00 -1277,9.60,0.00,1.00,0.00,1.00 -1278,14.40,0.00,1.00,0.00,1.00 -1279,19.20,4.80,1.00,0.00,1.00 -1280,24.00,4.80,1.00,0.00,1.00 -1281,28.80,4.80,1.00,0.00,1.00 -1282,33.60,4.80,1.00,0.00,1.00 -1283,38.40,4.80,1.00,0.00,1.00 -1284,43.20,4.80,1.00,0.00,1.00 -1285,48.00,4.80,1.00,0.00,1.00 -1286,52.80,4.80,1.00,0.00,1.00 -1287,57.60,4.80,1.00,0.00,1.00 -1288,62.40,9.60,1.00,0.00,1.00 -1289,67.20,9.60,1.00,0.00,1.00 -1290,72.00,9.60,1.00,0.00,1.00 -1291,76.80,9.60,1.00,0.00,1.00 -1292,81.60,9.60,1.00,0.00,1.00 -1293,86.40,9.60,1.00,0.00,1.00 -1294,91.20,9.60,1.00,0.00,1.00 -1295,96.00,9.60,1.00,0.00,1.00 -1296,100.80,9.60,1.00,0.00,1.00 -1297,105.60,9.60,1.00,0.00,1.00 -1298,110.40,9.60,1.00,0.00,1.00 -1299,115.20,9.60,1.00,0.00,1.00 -1300,120.00,9.60,1.00,0.00,1.00 -1301,124.80,4.80,1.00,0.00,1.00 -1302,129.60,4.80,1.00,0.00,1.00 -1303,134.40,4.80,1.00,0.00,1.00 -1304,139.20,4.80,1.00,0.00,1.00 -1305,144.00,4.80,1.00,0.00,1.00 -1306,148.80,4.80,1.00,0.00,1.00 -1307,153.60,4.80,1.00,0.00,1.00 -1308,158.40,4.80,1.00,0.00,1.00 -1309,163.20,4.80,1.00,0.00,1.00 -1310,168.00,0.00,1.00,0.00,1.00 -1311,172.80,0.00,1.00,0.00,1.00 -1312,177.60,0.00,1.00,0.00,1.00 -1313,-177.60,-0.00,1.00,0.00,1.00 -1314,-172.80,-0.00,1.00,0.00,1.00 -1315,-168.00,-0.00,1.00,0.00,1.00 -1316,-163.20,-4.80,1.00,0.00,1.00 -1317,-158.40,-4.80,1.00,0.00,1.00 -1318,-153.60,-4.80,1.00,0.00,1.00 -1319,-148.80,-4.80,1.00,0.00,1.00 -1320,-144.00,-4.80,1.00,0.00,1.00 -1321,-139.20,-4.80,1.00,0.00,1.00 -1322,-134.40,-4.80,1.00,0.00,1.00 -1323,-129.60,-4.80,1.00,0.00,1.00 -1324,-124.80,-4.80,1.00,0.00,1.00 -1325,-120.00,-9.60,1.00,0.00,1.00 -1326,-115.20,-9.60,1.00,0.00,1.00 -1327,-110.40,-9.60,1.00,0.00,1.00 -1328,-105.60,-9.60,1.00,0.00,1.00 -1329,-100.80,-9.60,1.00,0.00,1.00 -1330,-96.00,-9.60,1.00,0.00,1.00 -1331,-91.20,-9.60,1.00,0.00,1.00 -1332,-86.40,-9.60,1.00,0.00,1.00 -1333,-81.60,-9.60,1.00,0.00,1.00 -1334,-76.80,-9.60,1.00,0.00,1.00 -1335,-72.00,-9.60,1.00,0.00,1.00 -1336,-67.20,-9.60,1.00,0.00,1.00 -1337,-62.40,-9.60,1.00,0.00,1.00 -1338,-57.60,-4.80,1.00,0.00,1.00 -1339,-52.80,-4.80,1.00,0.00,1.00 -1340,-48.00,-4.80,1.00,0.00,1.00 -1341,-43.20,-4.80,1.00,0.00,1.00 -1342,-38.40,-4.80,1.00,0.00,1.00 -1343,-33.60,-4.80,1.00,0.00,1.00 -1344,-28.80,-4.80,1.00,0.00,1.00 -1345,-24.00,-4.80,1.00,0.00,1.00 -1346,-19.20,-4.80,1.00,0.00,1.00 -1347,-14.40,-0.00,1.00,0.00,1.00 -1348,-9.60,-0.00,1.00,0.00,1.00 -1349,-4.80,-0.00,1.00,0.00,1.00 -1350,0.00,0.00,1.00,0.00,1.00 -1351,4.80,0.00,1.00,0.00,1.00 -1352,9.60,0.00,1.00,0.00,1.00 -1353,14.40,0.00,1.00,0.00,1.00 -1354,19.20,0.00,1.00,0.00,1.00 -1355,24.00,0.00,1.00,0.00,1.00 -1356,28.80,0.00,1.00,0.00,1.00 -1357,33.60,0.00,1.00,0.00,1.00 -1358,38.40,0.00,1.00,0.00,1.00 -1359,43.20,4.80,1.00,0.00,1.00 -1360,48.00,4.80,1.00,0.00,1.00 -1361,52.80,4.80,1.00,0.00,1.00 -1362,57.60,4.80,1.00,0.00,1.00 -1363,62.40,4.80,1.00,0.00,1.00 -1364,67.20,4.80,1.00,0.00,1.00 -1365,72.00,4.80,1.00,0.00,1.00 -1366,76.80,4.80,1.00,0.00,1.00 -1367,81.60,4.80,1.00,0.00,1.00 -1368,86.40,4.80,1.00,0.00,1.00 -1369,91.20,4.80,1.00,0.00,1.00 -1370,96.00,4.80,1.00,0.00,1.00 -1371,100.80,4.80,1.00,0.00,1.00 -1372,105.60,4.80,1.00,0.00,1.00 -1373,110.40,4.80,1.00,0.00,1.00 -1374,115.20,4.80,1.00,0.00,1.00 -1375,120.00,4.80,1.00,0.00,1.00 -1376,124.80,4.80,1.00,0.00,1.00 -1377,129.60,4.80,1.00,0.00,1.00 -1378,134.40,4.80,1.00,0.00,1.00 -1379,139.20,0.00,1.00,0.00,1.00 -1380,144.00,0.00,1.00,0.00,1.00 -1381,148.80,0.00,1.00,0.00,1.00 -1382,153.60,0.00,1.00,0.00,1.00 -1383,158.40,0.00,1.00,0.00,1.00 -1384,163.20,0.00,1.00,0.00,1.00 -1385,168.00,0.00,1.00,0.00,1.00 -1386,172.80,0.00,1.00,0.00,1.00 -1387,177.60,0.00,1.00,0.00,1.00 -1388,-177.60,-0.00,1.00,0.00,1.00 -1389,-172.80,-0.00,1.00,0.00,1.00 -1390,-168.00,-0.00,1.00,0.00,1.00 -1391,-163.20,-0.00,1.00,0.00,1.00 -1392,-158.40,-0.00,1.00,0.00,1.00 -1393,-153.60,-0.00,1.00,0.00,1.00 -1394,-148.80,-0.00,1.00,0.00,1.00 -1395,-144.00,-0.00,1.00,0.00,1.00 -1396,-139.20,-0.00,1.00,0.00,1.00 -1397,-134.40,-4.80,1.00,0.00,1.00 -1398,-129.60,-4.80,1.00,0.00,1.00 -1399,-124.80,-4.80,1.00,0.00,1.00 -1400,-120.00,-4.80,1.00,0.00,1.00 -1401,-115.20,-4.80,1.00,0.00,1.00 -1402,-110.40,-4.80,1.00,0.00,1.00 -1403,-105.60,-4.80,1.00,0.00,1.00 -1404,-100.80,-4.80,1.00,0.00,1.00 -1405,-96.00,-4.80,1.00,0.00,1.00 -1406,-91.20,-4.80,1.00,0.00,1.00 -1407,-86.40,-4.80,1.00,0.00,1.00 -1408,-81.60,-4.80,1.00,0.00,1.00 -1409,-76.80,-4.80,1.00,0.00,1.00 -1410,-72.00,-4.80,1.00,0.00,1.00 -1411,-67.20,-4.80,1.00,0.00,1.00 -1412,-62.40,-4.80,1.00,0.00,1.00 -1413,-57.60,-4.80,1.00,0.00,1.00 -1414,-52.80,-4.80,1.00,0.00,1.00 -1415,-48.00,-4.80,1.00,0.00,1.00 -1416,-43.20,-4.80,1.00,0.00,1.00 -1417,-38.40,-0.00,1.00,0.00,1.00 -1418,-33.60,-0.00,1.00,0.00,1.00 -1419,-28.80,-0.00,1.00,0.00,1.00 -1420,-24.00,-0.00,1.00,0.00,1.00 -1421,-19.20,-0.00,1.00,0.00,1.00 -1422,-14.40,-0.00,1.00,0.00,1.00 -1423,-9.60,-0.00,1.00,0.00,1.00 -1424,-4.80,-0.00,1.00,0.00,1.00 -1425,0.00,0.00,1.00,0.00,1.00 -1426,4.80,-0.00,1.00,0.00,1.00 -1427,9.60,-0.00,1.00,0.00,1.00 -1428,14.40,-0.00,1.00,0.00,1.00 -1429,19.20,-0.00,1.00,0.00,1.00 -1430,24.00,-0.00,1.00,0.00,1.00 -1431,28.80,-0.00,1.00,0.00,1.00 -1432,33.60,-0.00,1.00,0.00,1.00 -1433,38.40,-0.00,1.00,0.00,1.00 -1434,43.20,-0.00,1.00,0.00,1.00 -1435,48.00,-0.00,1.00,0.00,1.00 -1436,52.80,-0.00,1.00,0.00,1.00 -1437,57.60,-0.00,1.00,0.00,1.00 -1438,62.40,-0.00,1.00,0.00,1.00 -1439,67.20,-0.00,1.00,0.00,1.00 -1440,72.00,-0.00,1.00,0.00,1.00 -1441,76.80,-0.00,1.00,0.00,1.00 -1442,81.60,-0.00,1.00,0.00,1.00 -1443,86.40,-0.00,1.00,0.00,1.00 -1444,91.20,-0.00,1.00,0.00,1.00 -1445,96.00,-0.00,1.00,0.00,1.00 -1446,100.80,-0.00,1.00,0.00,1.00 -1447,105.60,-0.00,1.00,0.00,1.00 -1448,110.40,-0.00,1.00,0.00,1.00 -1449,115.20,-0.00,1.00,0.00,1.00 -1450,120.00,-0.00,1.00,0.00,1.00 -1451,124.80,-0.00,1.00,0.00,1.00 -1452,129.60,-0.00,1.00,0.00,1.00 -1453,134.40,-0.00,1.00,0.00,1.00 -1454,139.20,-0.00,1.00,0.00,1.00 -1455,144.00,-0.00,1.00,0.00,1.00 -1456,148.80,-0.00,1.00,0.00,1.00 -1457,153.60,-0.00,1.00,0.00,1.00 -1458,158.40,-0.00,1.00,0.00,1.00 -1459,163.20,-0.00,1.00,0.00,1.00 -1460,168.00,-0.00,1.00,0.00,1.00 -1461,172.80,-0.00,1.00,0.00,1.00 -1462,177.60,-0.00,1.00,0.00,1.00 -1463,-177.60,0.00,1.00,0.00,1.00 -1464,-172.80,0.00,1.00,0.00,1.00 -1465,-168.00,0.00,1.00,0.00,1.00 -1466,-163.20,0.00,1.00,0.00,1.00 -1467,-158.40,0.00,1.00,0.00,1.00 -1468,-153.60,0.00,1.00,0.00,1.00 -1469,-148.80,0.00,1.00,0.00,1.00 -1470,-144.00,0.00,1.00,0.00,1.00 -1471,-139.20,0.00,1.00,0.00,1.00 -1472,-134.40,0.00,1.00,0.00,1.00 -1473,-129.60,0.00,1.00,0.00,1.00 -1474,-124.80,0.00,1.00,0.00,1.00 -1475,-120.00,0.00,1.00,0.00,1.00 -1476,-115.20,0.00,1.00,0.00,1.00 -1477,-110.40,0.00,1.00,0.00,1.00 -1478,-105.60,0.00,1.00,0.00,1.00 -1479,-100.80,0.00,1.00,0.00,1.00 -1480,-96.00,0.00,1.00,0.00,1.00 -1481,-91.20,0.00,1.00,0.00,1.00 -1482,-86.40,0.00,1.00,0.00,1.00 -1483,-81.60,0.00,1.00,0.00,1.00 -1484,-76.80,0.00,1.00,0.00,1.00 -1485,-72.00,0.00,1.00,0.00,1.00 -1486,-67.20,0.00,1.00,0.00,1.00 -1487,-62.40,0.00,1.00,0.00,1.00 -1488,-57.60,0.00,1.00,0.00,1.00 -1489,-52.80,0.00,1.00,0.00,1.00 -1490,-48.00,0.00,1.00,0.00,1.00 -1491,-43.20,0.00,1.00,0.00,1.00 -1492,-38.40,0.00,1.00,0.00,1.00 -1493,-33.60,0.00,1.00,0.00,1.00 -1494,-28.80,0.00,1.00,0.00,1.00 -1495,-24.00,0.00,1.00,0.00,1.00 -1496,-19.20,0.00,1.00,0.00,1.00 -1497,-14.40,0.00,1.00,0.00,1.00 -1498,-9.60,0.00,1.00,0.00,1.00 -1499,-4.80,0.00,1.00,0.00,1.00 diff --git a/tests/renderer/data/stv_IVASMASA_1dir1TC.met b/tests/renderer/data/stv_IVASMASA_1dir1TC.met deleted file mode 100644 index f2ce23bd20..0000000000 --- a/tests/renderer/data/stv_IVASMASA_1dir1TC.met +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:6349efe3448d28979b80744bcdc29d57f1c025704939b42d7b913d7fc3f23ccc -size 102300 diff --git a/tests/renderer/data/stv_IVASMASA_1dir1TC.pcm b/tests/renderer/data/stv_IVASMASA_1dir1TC.pcm deleted file mode 100644 index 8f2bfc54e0..0000000000 --- a/tests/renderer/data/stv_IVASMASA_1dir1TC.pcm +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:4dbbaa5c75c36bc74a100bc5721bc3cf2af4e22e2854a5b85c93532556afc776 -size 288000 diff --git a/tests/renderer/data/stv_IVASMASA_1dir2TC.met b/tests/renderer/data/stv_IVASMASA_1dir2TC.met deleted file mode 100644 index 00acdae539..0000000000 --- a/tests/renderer/data/stv_IVASMASA_1dir2TC.met +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:5a1f87bfe360dbd221a94583aa68a58ef050e968a63351730d643f2dc2cac4e1 -size 204600 diff --git a/tests/renderer/data/stv_IVASMASA_1dir2TC.pcm b/tests/renderer/data/stv_IVASMASA_1dir2TC.pcm deleted file mode 100644 index 491e75f868..0000000000 --- a/tests/renderer/data/stv_IVASMASA_1dir2TC.pcm +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:cd34c99b89d9c1ed3514c3f8e32faf6b82fbc8bf364bc464904fc1c745266350 -size 1152000 diff --git a/tests/renderer/data/stv_IVASMASA_2dir1TC.met b/tests/renderer/data/stv_IVASMASA_2dir1TC.met deleted file mode 100644 index 6468877408..0000000000 --- a/tests/renderer/data/stv_IVASMASA_2dir1TC.met +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d125a4c4e3989ac55f9c2617f464431feae4ede9b2e15d087d3271c0a4a56303 -size 319800 diff --git a/tests/renderer/data/stv_IVASMASA_2dir1TC.pcm b/tests/renderer/data/stv_IVASMASA_2dir1TC.pcm deleted file mode 100644 index 7c7209de2d..0000000000 --- a/tests/renderer/data/stv_IVASMASA_2dir1TC.pcm +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:5afc7014451a8599f8399e3a503a29b23d22843ef482c0a701d4c46f6329ebc4 -size 576000 diff --git a/tests/renderer/data/stv_IVASMASA_2dir2TC.met b/tests/renderer/data/stv_IVASMASA_2dir2TC.met deleted file mode 100644 index 1b62022af5..0000000000 --- a/tests/renderer/data/stv_IVASMASA_2dir2TC.met +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:2eb412d646d7a32c77413dea54dc44cf45dc49e6d8c2de19abe4f4b93a91fa4a -size 159900 diff --git a/tests/renderer/data/stv_IVASMASA_2dir2TC.pcm b/tests/renderer/data/stv_IVASMASA_2dir2TC.pcm deleted file mode 100644 index ac8d4d341a..0000000000 --- a/tests/renderer/data/stv_IVASMASA_2dir2TC.pcm +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:5d6c264295987b7db2a9a6a1352dd0b9c91a824fcc37c5631e0ba39e92df33f8 -size 576000 diff --git a/tests/renderer/utils.py b/tests/renderer/utils.py index 89ffbe0f6d..017c56a97b 100644 --- a/tests/renderer/utils.py +++ b/tests/renderer/utils.py @@ -236,7 +236,7 @@ def run_crend_unittest( in_meta_files: Optional[list] = None, trj_file: Optional[str] = None, ) -> Tuple[np.ndarray, int]: - """CuT creation with standalone renderer""" + """Reference creation with standalone renderer""" if trj_file is not None: trj_name = f"_{trj_file.stem}" else: @@ -285,7 +285,7 @@ def run_td_standalone( in_meta_files: Optional[list] = None, trj_file: Optional[str] = None, ): - """CuT creation with TD Object renderer""" + """Reference creation with TD Object renderer""" if trj_file is not None: trj_name = f"_{trj_file.stem}" else: @@ -346,7 +346,7 @@ def run_pyscripts( in_meta_files: Optional[list] = None, trj_file: Optional[str] = None, ) -> Tuple[np.ndarray, int]: - """Reference rendering with pyaudio3dtools""" + """Reference creation with pyaudio3dtools""" if trj_file is not None: trj_name = f"_{trj_file.stem}" else: -- GitLab From c4a782fa4f4098b4e52eb9708152db8bf8ca538e Mon Sep 17 00:00:00 2001 From: Archit Tamarapu Date: Mon, 7 Nov 2022 09:03:18 +0100 Subject: [PATCH 077/101] formatting --- apps/renderer.c | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/apps/renderer.c b/apps/renderer.c index 95f18e993c..e78b824586 100644 --- a/apps/renderer.c +++ b/apps/renderer.c @@ -104,29 +104,27 @@ extern int16_t *ptr_max_stack; extern int32_t wc_frame; extern char location_max_stack[256]; -/* clang-format off */ /*------------------------------------------------------------------------------------------* -* Function to print complexity & memory estimates -*------------------------------------------------------------------------------------------*/ -static void print_mem_renderer(size_t SRAM_size) + * Function to print complexity & memory estimates + *------------------------------------------------------------------------------------------*/ +static void print_mem_renderer( size_t SRAM_size ) { - fprintf( stdout, "\n\n --- Renderer cmdln demo memory usage --- \n\n" ); + fprintf( stdout, "\n\n --- Renderer cmdln demo memory usage --- \n\n" ); - fprintf( stdout, "PROM size (renderer): %d words (or instructions)\n", PROM_Size_lib_rend ); - fprintf( stdout, "Stack size: %d words in %s() in frame #%d\n", ( ptr_base_stack - ptr_max_stack ) * sizeof( int16_t ) / sizeof( float ), location_max_stack, wc_frame ); - fprintf( stdout, "Table ROM size(renderer): %d words\n", (Const_Data_Size_ivas_rom_rend() ) / sizeof( float ) ); - fprintf( stdout, "Table ROM size (binaural renderer): %ld words\n", ( Const_Data_Size_ivas_rom_binauralRen() + Const_Data_Size_ivas_rom_TdBinauralR() + Const_Data_Size_ivas_rom_binaural_cr() ) / sizeof( float ) ); + fprintf( stdout, "PROM size (renderer): %d words (or instructions)\n", PROM_Size_lib_rend ); + fprintf( stdout, "Stack size: %d words in %s() in frame #%d\n", ( ptr_base_stack - ptr_max_stack ) * sizeof( int16_t ) / sizeof( float ), location_max_stack, wc_frame ); + fprintf( stdout, "Table ROM size(renderer): %d words\n", ( Const_Data_Size_ivas_rom_rend() ) / sizeof( float ) ); + fprintf( stdout, "Table ROM size (binaural renderer): %ld words\n", ( Const_Data_Size_ivas_rom_binauralRen() + Const_Data_Size_ivas_rom_TdBinauralR() + Const_Data_Size_ivas_rom_binaural_cr() ) / sizeof( float ) ); #ifdef RAM_COUNTING_TOOL - fprintf( stdout, "Static RAM size: %d words\n\n", SRAM_size ); + fprintf( stdout, "Static RAM size: %d words\n\n", SRAM_size ); #endif - print_stack_call_tree(); + print_stack_call_tree(); - fprintf( stdout, "Note: this is an optimistic estimate of the memory consumption assuming\n" ); - fprintf( stdout, " that each variable (short, long or float) in the codec requires\n" ); - fprintf( stdout, " 32 bits of memory and may therefore be represented by 1 word.\n" ); - fprintf( stdout, " The following formula is used: sizeof('memory array')/sizeof(float)\n\n" ); + fprintf( stdout, "Note: this is an optimistic estimate of the memory consumption assuming\n" ); + fprintf( stdout, " that each variable (short, long or float) in the codec requires\n" ); + fprintf( stdout, " 32 bits of memory and may therefore be represented by 1 word.\n" ); + fprintf( stdout, " The following formula is used: sizeof('memory array')/sizeof(float)\n\n" ); } -/* clang-format on */ #endif typedef struct -- GitLab From 04a43b6e619277ccfff53435a4b7e640b6edf0c5 Mon Sep 17 00:00:00 2001 From: Archit Tamarapu Date: Mon, 7 Nov 2022 10:48:56 +0100 Subject: [PATCH 078/101] fixes for instrumentation --- apps/renderer.c | 2 +- lib_rend/ivas_crend.c | 4 +++- lib_rend/ivas_objectRenderer.c | 5 +++++ 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/apps/renderer.c b/apps/renderer.c index e78b824586..8ae84fe7d2 100644 --- a/apps/renderer.c +++ b/apps/renderer.c @@ -1000,7 +1000,7 @@ int32_t main( int32_t argc, char **argv ) #endif #ifdef WMOPS print_wmops(); - /* print_mem_renderer( SRAM_size ); */ + print_mem_renderer( SRAM_size ); #endif return 0; diff --git a/lib_rend/ivas_crend.c b/lib_rend/ivas_crend.c index 0a5b28cb98..960e92bf49 100644 --- a/lib_rend/ivas_crend.c +++ b/lib_rend/ivas_crend.c @@ -1779,7 +1779,7 @@ ivas_error ivas_rend_crendProcess( IVAS_REND_AudioConfigType inConfigType; ivas_error error; - wmops_sub_start( "ivas_crend_process" ); + wmops_sub_start( "ivas_rend_crendProcess" ); in_config = getIvasAudioConfigFromRendAudioConfig( inConfig ); inConfigType = getAudioConfigType( inConfig ); @@ -1815,6 +1815,8 @@ ivas_error ivas_rend_crendProcess( mvr2r( pcm_tmp[i], output[i], output_frame ); } + wmops_sub_end(); + return IVAS_ERR_OK; } diff --git a/lib_rend/ivas_objectRenderer.c b/lib_rend/ivas_objectRenderer.c index e4f0706193..ce974189cb 100644 --- a/lib_rend/ivas_objectRenderer.c +++ b/lib_rend/ivas_objectRenderer.c @@ -678,6 +678,8 @@ ivas_error ivas_rend_TDObjRenderFrame( IVAS_FORMAT ivas_format; IVAS_REND_AudioConfigType inConfigType; + wmops_sub_start( "ivas_rend_TDObjRenderFrame" ); + inConfigType = getAudioConfigType( inConfig ); lfe_idx = LFE_CHANNEL; if ( inConfigType == IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED ) @@ -754,6 +756,9 @@ ivas_error ivas_rend_TDObjRenderFrame( // v_add( reverb_signal[1], output[1], output[1], output_frame ); // } // } + + wmops_sub_end(); + return IVAS_ERR_OK; } #endif -- GitLab From 8d4bc4826633340556c1db25f723f40f7a9c1e3c Mon Sep 17 00:00:00 2001 From: Archit Tamarapu Date: Mon, 7 Nov 2022 11:02:01 +0100 Subject: [PATCH 079/101] [tests] always log executed command --- tests/renderer/utils.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/renderer/utils.py b/tests/renderer/utils.py index 017c56a97b..9811d73500 100644 --- a/tests/renderer/utils.py +++ b/tests/renderer/utils.py @@ -26,6 +26,7 @@ the United Nations Convention on Contracts on the International Sales of Goods. """ +import logging import subprocess as sp import sys from pathlib import Path @@ -49,6 +50,7 @@ def test_info(request): def run_cmd(cmd): + logging.info(f"\nRunning command\n{' '.join(cmd)}\n") try: sp.run(cmd, check=True, capture_output=True, text=True) except sp.CalledProcessError as e: -- GitLab From ff02f5d0c9e77b056a66aa02304210ef83a1734f Mon Sep 17 00:00:00 2001 From: vaclav Date: Mon, 7 Nov 2022 12:00:24 +0100 Subject: [PATCH 080/101] - editorial changes - "VE2AT" comments --- Workspace_msvc/lib_rend.vcxproj | 1 + apps/renderer.c | 325 ++++++---- lib_dec/ivas_dirac_dec_binaural_functions.c | 4 +- lib_dec/ivas_ism_renderer.c | 2 +- lib_dec/ivas_mono_dmx_renderer.c | 2 +- lib_dec/ivas_out_setup_conversion.c | 2 +- lib_dec/ivas_rom_dec.c | 2 +- lib_dec/ivas_stat_dec.h | 16 +- lib_dec/ivas_vbap.c | 2 +- lib_rend/ivas_crend.c | 30 +- lib_rend/ivas_lib_rend_internal.h | 34 +- lib_rend/ivas_limiter.c | 2 +- lib_rend/ivas_objectRenderer.c | 24 +- lib_rend/ivas_output_init.c | 2 +- lib_rend/lib_rend.c | 684 +++++++++----------- lib_rend/lib_rend.h | 42 +- 16 files changed, 594 insertions(+), 580 deletions(-) diff --git a/Workspace_msvc/lib_rend.vcxproj b/Workspace_msvc/lib_rend.vcxproj index e87baf5605..c3a1268694 100644 --- a/Workspace_msvc/lib_rend.vcxproj +++ b/Workspace_msvc/lib_rend.vcxproj @@ -229,6 +229,7 @@ + diff --git a/apps/renderer.c b/apps/renderer.c index 95f18e993c..41e0b53a5d 100644 --- a/apps/renderer.c +++ b/apps/renderer.c @@ -182,7 +182,7 @@ typedef struct InputConfig inConfig; OutputConfig outConfig; char inMetadataFilePaths[RENDERER_MAX_ISM_INPUTS][RENDERER_MAX_CLI_ARG_LENGTH]; - int32_t numInMetadataFiles; + int16_t numInMetadataFiles; char headRotationFilePath[RENDERER_MAX_CLI_ARG_LENGTH]; char customHrtfFilePath[RENDERER_MAX_CLI_ARG_LENGTH]; char renderConfigFilePath[RENDERER_MAX_CLI_ARG_LENGTH]; @@ -318,7 +318,7 @@ static const CmdLnParser_Option cliOptions[] = { static const int32_t numCliOptions = sizeof( cliOptions ) / sizeof( CmdLnParser_Option ); static IVAS_REND_AudioConfig ambisonicsOrderToEnum( - int32_t order ); + const int16_t order ); static void parseSceneDescriptionFile( char *path, @@ -332,7 +332,7 @@ static ivas_error parseCustomLayoutFile( IVAS_CUSTOM_LS_DATA *pLsSetupCustom ); static CmdlnArgs parseCmdlnArgs( - int32_t argc, + const int argc, char **argv ); static IsmPositionProvider *IsmPositionProvider_open( @@ -348,12 +348,12 @@ static void IsmPositionProvider_close( static void readFromShorthandMetadata( IsmPositionProvider *positionProvider, ObjectPositionBuffer *objectMetadataBuffer, - uint32_t objIdx ); + const uint32_t objIdx ); void getMetadataFromFileReader( IsmFileReader *ismReader, ObjectPositionBuffer *objectMetadataBuffer, - uint32_t objIdx ); + const uint32_t objIdx ); static void splitConfigFile( const char *mdfFilePath, @@ -394,11 +394,9 @@ static void parseMetadata( IsmPositionProvider *positionProvider, MasaFileReader **masaReaders ); -static void convert_backslash( - char *str ); +static void convert_backslash( char *str ); -static void remove_cr( - char *str ); +static void remove_cr( char *str ); static void clearString( char *str ); @@ -408,37 +406,33 @@ static void printSupportedAudioConfigs( void ); static IVAS_REND_AudioConfig parseAudioConfig( const char *configString ); -static void convertInputBuffer( const int16_t *intBuffer, - int32_t numIntSamplesPerChannel, /* Number of samples per channel in the int buffer */ - int32_t numFloatSamplesPerChannel, /* Per-channel length of the float buffer. If > numIntSamplesPerChannel, remaining samples will be set to 0. */ - int32_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 ); + +static void convertOutputBuffer( const float *floatBuffer, const int16_t numSamplesPerChannel, const int16_t numChannels, int16_t *intBuffer ); -static void convertOutputBuffer( const float *floatBuffer, - int32_t numSamplesPerChannel, - int32_t numChannels, - int16_t *intBuffer ); -static IVAS_REND_ReadOnlyAudioBuffer getReadOnlySubBuffer( IVAS_REND_AudioBuffer buffer, int32_t chBeginIdx, int32_t numChannels ) +static IVAS_REND_ReadOnlyAudioBuffer getReadOnlySubBuffer( IVAS_REND_AudioBuffer buffer, const int16_t chBeginIdx, const int16_t numChannels ) { IVAS_REND_ReadOnlyAudioBuffer subBuffer; subBuffer.config = buffer.config; - subBuffer.config.numChannels = (int16_t) numChannels; + subBuffer.config.numChannels = numChannels; subBuffer.data = buffer.data + subBuffer.config.numSamplesPerChannel * chBeginIdx; return subBuffer; } -static int32_t getTotalNumInChannels( IVAS_REND_HANDLE hIvasRend, - IVAS_REND_InputId mcIds[RENDERER_MAX_MC_INPUTS], - IVAS_REND_InputId ismIds[RENDERER_MAX_ISM_INPUTS], - IVAS_REND_InputId sbaIds[RENDERER_MAX_SBA_INPUTS] ) +static int16_t getTotalNumInChannels( + IVAS_REND_HANDLE hIvasRend, + IVAS_REND_InputId mcIds[RENDERER_MAX_MC_INPUTS], + IVAS_REND_InputId ismIds[RENDERER_MAX_ISM_INPUTS], + IVAS_REND_InputId sbaIds[RENDERER_MAX_SBA_INPUTS] ) { - int32_t totalNumInChannels = 0; + int16_t totalNumInChannels = 0; + int16_t i, numInputChannels; ivas_error error; - for ( int32_t i = 0; i < RENDERER_MAX_MC_INPUTS; ++i ) + for ( i = 0; i < RENDERER_MAX_MC_INPUTS; ++i ) { if ( mcIds[i] == 0 ) { @@ -446,7 +440,6 @@ static int32_t getTotalNumInChannels( IVAS_REND_HANDLE hIvasRend, continue; } - int32_t numInputChannels; if ( ( error = IVAS_REND_GetInputNumChannels( hIvasRend, mcIds[i], &numInputChannels ) ) != IVAS_ERR_OK ) { fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); @@ -455,7 +448,7 @@ static int32_t getTotalNumInChannels( IVAS_REND_HANDLE hIvasRend, totalNumInChannels += numInputChannels; } - for ( int32_t i = 0; i < RENDERER_MAX_ISM_INPUTS; ++i ) + for ( i = 0; i < RENDERER_MAX_ISM_INPUTS; ++i ) { if ( ismIds[i] == 0 ) { @@ -463,7 +456,6 @@ static int32_t getTotalNumInChannels( IVAS_REND_HANDLE hIvasRend, continue; } - int32_t numInputChannels; if ( ( error = IVAS_REND_GetInputNumChannels( hIvasRend, ismIds[i], &numInputChannels ) ) != IVAS_ERR_OK ) { fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); @@ -472,7 +464,7 @@ static int32_t getTotalNumInChannels( IVAS_REND_HANDLE hIvasRend, totalNumInChannels += numInputChannels; } - for ( int32_t i = 0; i < RENDERER_MAX_SBA_INPUTS; ++i ) + for ( i = 0; i < RENDERER_MAX_SBA_INPUTS; ++i ) { if ( sbaIds[i] == 0 ) { @@ -480,7 +472,7 @@ static int32_t getTotalNumInChannels( IVAS_REND_HANDLE hIvasRend, continue; } - int32_t numInputChannels; + if ( ( error = IVAS_REND_GetInputNumChannels( hIvasRend, sbaIds[i], &numInputChannels ) ) != IVAS_ERR_OK ) { fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); @@ -492,7 +484,11 @@ static int32_t getTotalNumInChannels( IVAS_REND_HANDLE hIvasRend, return totalNumInChannels; } -static void setupWithSingleFormatInput( CmdlnArgs args, char *audioFilePath, IsmPositionProvider *positionProvider, MasaFileReader **masaReaders ) +static void setupWithSingleFormatInput( + CmdlnArgs args, + char *audioFilePath, + IsmPositionProvider *positionProvider, + MasaFileReader **masaReaders ) { /* With single-format input, inputFilePath is the path to input audio file. */ strncpy( audioFilePath, args.inputFilePath, FILENAME_MAX - 1 ); @@ -519,7 +515,7 @@ static void setupWithSingleFormatInput( CmdlnArgs args, char *audioFilePath, Ism else if ( args.inConfig.numAudioObjects != 0 ) { positionProvider->numObjects = args.inConfig.numAudioObjects; - for ( int32_t i = 0; i < positionProvider->numObjects; ++i ) + for ( int16_t i = 0; i < positionProvider->numObjects; ++i ) { /* It is allowed on CLI to have no metadata for an ISM input - skip opening if string is empty or contains "NULL" */ char charBuf[FILENAME_MAX]; @@ -540,7 +536,8 @@ static void setupWithSingleFormatInput( CmdlnArgs args, char *audioFilePath, Ism } } -static float dBToLin( float gain_dB ) +static float dBToLin( + const float gain_dB ) { return powf( 10.0f, gain_dB / 20.0f ); } @@ -548,7 +545,9 @@ static float dBToLin( float gain_dB ) /* ============================================================================ */ -int32_t main( int32_t argc, char **argv ) +int main( + int argc, + char **argv ) { IVAS_REND_HANDLE hIvasRend; HeadRotFileReader *headRotReader = NULL; @@ -573,6 +572,7 @@ int32_t main( int32_t argc, char **argv ) int16_t delayNumSamples_orig = 0; int16_t zeroPad = 0; int32_t delayTimeScale = 0; + int16_t i, numChannels; ivas_error error = IVAS_ERR_OK; #ifdef WMOPS size_t SRAM_size; @@ -587,7 +587,7 @@ int32_t main( int32_t argc, char **argv ) mem_count_init( 0, USE_32BITS ); #endif - for ( int32_t i = 0; i < RENDERER_MAX_MASA_INPUTS; ++i ) + for ( i = 0; i < RENDERER_MAX_MASA_INPUTS; ++i ) { masaReaders[i] = NULL; hMasaMetadata[i] = NULL; @@ -648,7 +648,7 @@ int32_t main( int32_t argc, char **argv ) { args.sampleRate = inFileSampleRate; } - const int32_t frameSize_smpls = 20 * args.sampleRate / 1000; + const int16_t frameSize_smpls = (int16_t) ( 20 * args.sampleRate / 1000 ); IVAS_REND_InputId mcIds[RENDERER_MAX_MC_INPUTS] = { 0 }; IVAS_REND_InputId ismIds[RENDERER_MAX_ISM_INPUTS] = { 0 }; @@ -669,7 +669,7 @@ int32_t main( int32_t argc, char **argv ) } } - for ( int32_t i = 0; i < args.inConfig.numMultiChannelBuses; ++i ) + for ( i = 0; i < args.inConfig.numMultiChannelBuses; ++i ) { if ( ( error = IVAS_REND_AddInput( hIvasRend, args.inConfig.multiChannelBuses[i].audioConfig, &mcIds[i] ) ) != IVAS_ERR_OK ) { @@ -695,7 +695,7 @@ int32_t main( int32_t argc, char **argv ) /* TODO(sgi): Test custom LFE routing here */ } - for ( int32_t i = 0; i < args.inConfig.numAudioObjects; ++i ) + for ( i = 0; i < args.inConfig.numAudioObjects; ++i ) { if ( ( error = IVAS_REND_AddInput( hIvasRend, IVAS_REND_AUDIO_CONFIG_OBJECT, &ismIds[i] ) ) != IVAS_ERR_OK ) { @@ -710,7 +710,7 @@ int32_t main( int32_t argc, char **argv ) } } - for ( int32_t i = 0; i < args.inConfig.numAmbisonicsBuses; ++i ) + for ( i = 0; i < args.inConfig.numAmbisonicsBuses; ++i ) { if ( ( error = IVAS_REND_AddInput( hIvasRend, args.inConfig.ambisonicsBuses[i].audioConfig, &sbaIds[i] ) ) != IVAS_ERR_OK ) { @@ -725,7 +725,7 @@ int32_t main( int32_t argc, char **argv ) } } - const int32_t totalNumInChannels = getTotalNumInChannels( hIvasRend, mcIds, ismIds, sbaIds ); + const int16_t totalNumInChannels = getTotalNumInChannels( hIvasRend, mcIds, ismIds, sbaIds ); if ( AudioFileReader_getNumChannels( audioReader ) != 0 /* If input file is raw PCM, audio reader has no info about number of channels */ && totalNumInChannels != AudioFileReader_getNumChannels( audioReader ) ) { @@ -733,7 +733,7 @@ int32_t main( int32_t argc, char **argv ) exit( -1 ); } - for ( int32_t i = 0; i < args.inConfig.numMasaBuses; ++i ) + for ( i = 0; i < args.inConfig.numMasaBuses; ++i ) { if ( masaReaders[i] != NULL ) { @@ -741,7 +741,7 @@ int32_t main( int32_t argc, char **argv ) } } - int32_t numOutChannels; + int16_t numOutChannels; if ( ( error = IVAS_REND_NumOutChannels( hIvasRend, &numOutChannels ) ) != IVAS_ERR_OK ) { fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); @@ -788,7 +788,7 @@ int32_t main( int32_t argc, char **argv ) while ( 1 ) { - int32_t num_in_channels; + int16_t num_in_channels; num_in_channels = inBuffer.config.numChannels; /* Read the input data */ @@ -821,7 +821,7 @@ int32_t main( int32_t argc, char **argv ) } #endif - for ( int32_t i = 0; i < RENDERER_MAX_MASA_INPUTS; ++i ) + for ( i = 0; i < RENDERER_MAX_MASA_INPUTS; ++i ) { if ( masaReaders[i] != NULL ) { @@ -847,15 +847,14 @@ int32_t main( int32_t argc, char **argv ) IVAS_REND_SetHeadRotation( hIvasRend, NULL ); } - for ( int32_t i = 0; i < args.inConfig.numMultiChannelBuses; ++i ) + for ( i = 0; i < args.inConfig.numMultiChannelBuses; ++i ) { - int32_t numChannels; if ( ( error = IVAS_REND_GetInputNumChannels( hIvasRend, mcIds[i], &numChannels ) ) != IVAS_ERR_OK ) { fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); exit( -1 ); } - IVAS_REND_ReadOnlyAudioBuffer tmpBuffer = getReadOnlySubBuffer( inBuffer, args.inConfig.multiChannelBuses[i].inputChannelIndex, numChannels ); + IVAS_REND_ReadOnlyAudioBuffer tmpBuffer = getReadOnlySubBuffer( inBuffer, (int16_t) args.inConfig.multiChannelBuses[i].inputChannelIndex, numChannels ); if ( ( error = IVAS_REND_FeedInputAudio( hIvasRend, mcIds[i], tmpBuffer ) ) != IVAS_ERR_OK ) { @@ -864,9 +863,9 @@ int32_t main( int32_t argc, char **argv ) } } - for ( int32_t i = 0; i < args.inConfig.numAudioObjects; ++i ) + for ( i = 0; i < args.inConfig.numAudioObjects; ++i ) { - IVAS_REND_ReadOnlyAudioBuffer tmpBuffer = getReadOnlySubBuffer( inBuffer, args.inConfig.audioObjects[i].inputChannelIndex, 1 ); + IVAS_REND_ReadOnlyAudioBuffer tmpBuffer = getReadOnlySubBuffer( inBuffer, (int16_t) args.inConfig.audioObjects[i].inputChannelIndex, 1 ); if ( ( error = IVAS_REND_FeedInputAudio( hIvasRend, ismIds[i], tmpBuffer ) ) != IVAS_ERR_OK ) { @@ -881,15 +880,14 @@ int32_t main( int32_t argc, char **argv ) } } - for ( int32_t i = 0; i < args.inConfig.numAmbisonicsBuses; ++i ) + for ( i = 0; i < args.inConfig.numAmbisonicsBuses; ++i ) { - int32_t numChannels; if ( ( error = IVAS_REND_GetInputNumChannels( hIvasRend, sbaIds[i], &numChannels ) ) != IVAS_ERR_OK ) { fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); exit( -1 ); } - IVAS_REND_ReadOnlyAudioBuffer tmpBuffer = getReadOnlySubBuffer( inBuffer, args.inConfig.ambisonicsBuses[i].inputChannelIndex, numChannels ); + IVAS_REND_ReadOnlyAudioBuffer tmpBuffer = getReadOnlySubBuffer( inBuffer, (int16_t) args.inConfig.ambisonicsBuses[i].inputChannelIndex, numChannels ); if ( ( error = IVAS_REND_FeedInputAudio( hIvasRend, sbaIds[i], tmpBuffer ) ) != IVAS_ERR_OK ) { @@ -900,7 +898,7 @@ int32_t main( int32_t argc, char **argv ) IVAS_REND_GetSamples( hIvasRend, outBuffer ); - int32_t num_out_channels; + int16_t num_out_channels; num_out_channels = outBuffer.config.numChannels; /* Convert from float to int and from packed to interleaved. @@ -982,7 +980,7 @@ int32_t main( int32_t argc, char **argv ) count_free( inFloatBuffer ); count_free( outInt16Buffer ); count_free( outFloatBuffer ); - for ( int32_t i = 0; i < RENDERER_MAX_MASA_INPUTS; ++i ) + for ( i = 0; i < RENDERER_MAX_MASA_INPUTS; ++i ) { MasaFileReader_close( &masaReaders[i] ); } @@ -1008,7 +1006,8 @@ int32_t main( int32_t argc, char **argv ) return 0; } -static IVAS_REND_AudioConfig ambisonicsOrderToEnum( int32_t order ) +static IVAS_REND_AudioConfig ambisonicsOrderToEnum( + const int16_t order ) { switch ( order ) { @@ -1023,7 +1022,10 @@ static IVAS_REND_AudioConfig ambisonicsOrderToEnum( int32_t order ) return IVAS_REND_AUDIO_CONFIG_UNKNOWN; } -static bool parseInConfig( const char *inFormatStr, InputConfig *inConfig, bool *sceneDescriptionInput ) +static bool parseInConfig( + const char *inFormatStr, + InputConfig *inConfig, + bool *sceneDescriptionInput ) { char charBuf[FILENAME_MAX]; @@ -1091,7 +1093,7 @@ static bool parseInConfig( const char *inFormatStr, InputConfig *inConfig, bool fprintf( stderr, "Too many objects at input. Max %d supported.", RENDERER_MAX_ISM_INPUTS ); return false; } - for ( int32_t i = 0; i < inConfig->numAudioObjects; ++i ) + for ( int16_t i = 0; i < inConfig->numAudioObjects; ++i ) { inConfig->audioObjects[i].audioConfig = audioConfig; inConfig->audioObjects[i].inputChannelIndex = i; @@ -1132,7 +1134,9 @@ static bool parseInConfig( const char *inFormatStr, InputConfig *inConfig, bool return true; } -static bool parseOutConfig( const char *outputFormatStr, OutputConfig *outConfig ) +static bool parseOutConfig( + const char *outputFormatStr, + OutputConfig *outConfig ) { ivas_error error; @@ -1152,7 +1156,9 @@ static bool parseOutConfig( const char *outputFormatStr, OutputConfig *outConfig return true; } -static int8_t parseDiegeticPan( char *value, float *noDiegeticPan ) +static int8_t parseDiegeticPan( + char *value, + float *noDiegeticPan ) { int8_t success; success = 1; @@ -1183,7 +1189,9 @@ static int8_t parseDiegeticPan( char *value, float *noDiegeticPan ) return success ? 0 : -1; } -static int8_t parseOrientationTracking( char *value, int8_t *tracking_type ) +static int8_t parseOrientationTracking( + char *value, + int8_t *tracking_type ) { int8_t success; success = 1; @@ -1207,7 +1215,8 @@ static int8_t parseOrientationTracking( char *value, int8_t *tracking_type ) return success ? 0 : -1; } -static IVAS_REND_AudioConfig parseAudioConfig( const char *configString ) +static IVAS_REND_AudioConfig parseAudioConfig( + const char *configString ) { char charBuf[14]; charBuf[13] = '\0'; @@ -1283,7 +1292,8 @@ static IVAS_REND_AudioConfig parseAudioConfig( const char *configString ) return IVAS_REND_AUDIO_CONFIG_UNKNOWN; } -static const CmdLnParser_Option *findOptionById( int32_t id ) +static const CmdLnParser_Option *findOptionById( + const int32_t id ) { for ( int32_t i = 0; i < numCliOptions; ++i ) { @@ -1296,7 +1306,8 @@ static const CmdLnParser_Option *findOptionById( int32_t id ) return NULL; } -static bool checkRequiredArgs( CmdlnArgs args ) +static bool checkRequiredArgs( + CmdlnArgs args ) { const CmdLnParser_Option *tmpOption; @@ -1339,7 +1350,8 @@ static bool checkRequiredArgs( CmdlnArgs args ) return !missingRequiredArg; } -static CmdlnArgs defaultArgs( const char *executableName ) +static CmdlnArgs defaultArgs( + const char *executableName ) { CmdlnArgs args; @@ -1380,7 +1392,11 @@ static CmdlnArgs defaultArgs( const char *executableName ) return args; } -static void parseOption( int32_t optionId, char **optionValues, int16_t numOptionValues, void *pOutputStruct ) +static void parseOption( + const int32_t optionId, + char **optionValues, + const int16_t numOptionValues, + void *pOutputStruct ) { CmdlnArgs *args = pOutputStruct; @@ -1403,7 +1419,7 @@ static void parseOption( int32_t optionId, char **optionValues, int16_t numOptio break; case CmdLnOptionId_inputMetadata: assert( numOptionValues <= RENDERER_MAX_ISM_INPUTS ); - for ( int32_t i = 0; i < numOptionValues; ++i ) + for ( int16_t i = 0; i < numOptionValues; ++i ) { strncpy( args->inMetadataFilePaths[i], optionValues[i], RENDERER_MAX_CLI_ARG_LENGTH - 1 ); } @@ -1481,9 +1497,13 @@ static void parseOption( int32_t optionId, char **optionValues, int16_t numOptio assert( 0 && "This should be unreachable - all command line options should be explicitly handled." ); break; } + + return; } -static CmdlnArgs parseCmdlnArgs( int32_t argc, char **argv ) +static CmdlnArgs parseCmdlnArgs( + const int argc, + char **argv ) { CmdlnArgs args = defaultArgs( argv[0] ); @@ -1501,10 +1521,11 @@ static CmdlnArgs parseCmdlnArgs( int32_t argc, char **argv ) } -IsmPositionProvider *IsmPositionProvider_open( void ) +IsmPositionProvider *IsmPositionProvider_open( + void ) { IsmPositionProvider *ipp; - uint32_t i; + uint16_t i; ipp = (IsmPositionProvider *) count_malloc( sizeof( IsmPositionProvider ) ); ipp->frameCounter = 0; @@ -1525,7 +1546,7 @@ IsmPositionProvider *IsmPositionProvider_open( void ) void getMetadataFromFileReader( IsmFileReader *ismReader, ObjectPositionBuffer *objectMetadataBuffer, - uint32_t objIdx ) + const uint32_t objIdx ) { IVAS_ISM_METADATA ismMetadata; ivas_error error; @@ -1538,11 +1559,14 @@ void getMetadataFromFileReader( objectMetadataBuffer->positions[objIdx].azimuth = ismMetadata.azimuth; objectMetadataBuffer->positions[objIdx].elevation = ismMetadata.elevation; + + return; } -void readFromShorthandMetadata( IsmPositionProvider *positionProvider, - ObjectPositionBuffer *objectMetadataBuffer, - uint32_t objIdx ) +void readFromShorthandMetadata( + IsmPositionProvider *positionProvider, + ObjectPositionBuffer *objectMetadataBuffer, + const uint32_t objIdx ) { uint32_t preUpdatePositionIdx; uint32_t postUpdatePositionIdx; @@ -1560,6 +1584,8 @@ void readFromShorthandMetadata( IsmPositionProvider *positionProvider, postUpdatePositionIdx = positionProvider->currentPositionIdxs[objIdx]; objectMetadataBuffer->positions[objIdx] = positionProvider->positions[objIdx][postUpdatePositionIdx]; + + return; } void IsmPositionProvider_getNextFrame( @@ -1596,6 +1622,8 @@ void IsmPositionProvider_getNextFrame( } ++positionProvider->frameCounter; + + return; } void IsmPositionProvider_close( IsmPositionProvider *positionProvider ) @@ -1626,13 +1654,16 @@ void IsmPositionProvider_close( IsmPositionProvider *positionProvider ) } count_free( positionProvider ); + + return; } -static void splitConfigFile( const char *mdfFilePath, - char *metadataString, - uint32_t *metadataStringLength, - char *wavFileName, - uint32_t *wavFileNameLength ) +static void splitConfigFile( + const char *mdfFilePath, + char *metadataString, + uint32_t *metadataStringLength, + char *wavFileName, + uint32_t *wavFileNameLength ) { FILE *file; uint32_t bufferlength; @@ -1683,10 +1714,15 @@ static void splitConfigFile( const char *mdfFilePath, *metadataStringLength = mdlength + 1; fclose( file ); + + return; } /* r: pointer to character following last found delimiter */ -static char *readNextMetadataChunkFrom( char *start_char, char *line, const char *delimiter ) +static char *readNextMetadataChunkFrom( + char *start_char, + char *line, + const char *delimiter ) { char *token; @@ -1709,12 +1745,16 @@ static char *readNextMetadataChunkFrom( char *start_char, char *line, const char } /* r: pointer to character following last found delimiter */ -static char *readNextMetadataChunk( char *line, const char *delimiter ) +static char *readNextMetadataChunk( + char *line, + const char *delimiter ) { return readNextMetadataChunkFrom( NULL, line, delimiter ); } -static void parseUint8( const char *line, uint8_t *ret ) +static void parseUint8( + const char *line, + uint8_t *ret ) { char *ptr; ptr = NULL; @@ -1725,9 +1765,13 @@ static void parseUint8( const char *line, uint8_t *ret ) fprintf( stderr, "Cannot parse string \"%s\" as an integer value\n", line ); exit( -1 ); } + + return; } -static int8_t parseUint32( const char *line, uint32_t *ret ) +static int8_t parseUint32( + const char *line, + uint32_t *ret ) { char *ptr; ptr = NULL; @@ -1741,7 +1785,9 @@ static int8_t parseUint32( const char *line, uint32_t *ret ) return 0; } -static int8_t parseInt32( const char *line, int32_t *ret ) +static int8_t parseInt32( + const char *line, + int32_t *ret ) { char *ptr; ptr = NULL; @@ -1796,11 +1842,14 @@ static void parseOptionalInputValues( parse_pos = readNextMetadataChunkFrom( parse_pos, line, "\n" ); } + + return; } -static void parseObjectPosition( char *line, - IVAS_REND_AudioObjectPosition *position, - uint16_t *positionDuration ) +static void parseObjectPosition( + char *line, + IVAS_REND_AudioObjectPosition *position, + uint16_t *positionDuration ) { char *endptr; @@ -1829,6 +1878,8 @@ static void parseObjectPosition( char *line, fprintf( stderr, "Error reading metadata\n" ); exit( -1 ); } + + return; } static void parseIsm( @@ -1836,7 +1887,7 @@ static void parseIsm( char *inDir, InputConfig *inConfig, IsmPositionProvider *positionProvider, - int32_t idx ) + const int32_t idx ) { uint32_t numberOfObjectPositionsToRead; uint32_t i; @@ -1874,11 +1925,14 @@ static void parseIsm( /* Read optional values */ parseOptionalInputValues( line, &inConfig->audioObjects[idx].gain_dB ); + + return; } -static void parseSba( char *line, - InputConfig *inConfig, - int32_t idx ) +static void parseSba( + char *line, + InputConfig *inConfig, + const int32_t idx ) { uint8_t ambiOrder; @@ -1892,11 +1946,14 @@ static void parseSba( char *line, /* Read optional values */ parseOptionalInputValues( line, &inConfig->ambisonicsBuses[idx].gain_dB ); + + return; } -static void parseMc( char *line, - InputConfig *inConfig, - int32_t idx ) +static void parseMc( + char *line, + InputConfig *inConfig, + const int32_t idx ) { readNextMetadataChunk( line, "\n" ); parseInt32( line, &inConfig->multiChannelBuses[idx].inputChannelIndex ); @@ -1915,6 +1972,8 @@ static void parseMc( char *line, /* Read optional values */ parseOptionalInputValues( line, &inConfig->multiChannelBuses[idx].gain_dB ); + + return; } static void parseMasa( @@ -1922,7 +1981,7 @@ static void parseMasa( char *inDir, InputConfig *inConfig, MasaFileReader **masaReaders, - int32_t idx ) + const int32_t idx ) { readNextMetadataChunk( line, "\n" ); parseInt32( line, &inConfig->masaBuses[idx].inputChannelIndex ); @@ -1954,6 +2013,8 @@ static void parseMasa( /* Read optional values */ parseOptionalInputValues( line, &inConfig->masaBuses[idx].gain_dB ); + + return; } static ivas_error parseCustomLayoutFile( @@ -2103,9 +2164,16 @@ static void parseMetadata( fprintf( stderr, "Trailing text in metadata file\n" ); exit( -1 ); } + + return; } -static void parseSceneDescriptionFile( char *path, char *audioFilePath, InputConfig *inConfig, IsmPositionProvider *positionProvider, MasaFileReader **masaReaders ) +static void parseSceneDescriptionFile( + char *path, + char *audioFilePath, + InputConfig *inConfig, + IsmPositionProvider *positionProvider, + MasaFileReader **masaReaders ) { uint32_t inAudioFilePathLen; char inAudioFilePath[FILENAME_MAX]; @@ -2116,11 +2184,7 @@ static void parseSceneDescriptionFile( char *path, char *audioFilePath, InputCon inAudioFilePathLen = FILENAME_MAX; mtdStrLen = RENDERER_MAX_METADATA_LENGTH; - splitConfigFile( path, - mtdStr, - &mtdStrLen, - inAudioFilePath, - &inAudioFilePathLen ); + splitConfigFile( path, mtdStr, &mtdStrLen, inAudioFilePath, &inAudioFilePathLen ); remove_cr( mtdStr ); convert_backslash( inAudioFilePath ); @@ -2143,7 +2207,7 @@ static void parseSceneDescriptionFile( char *path, char *audioFilePath, InputCon static void printSupportedAudioConfigs() { - uint32_t i; + uint16_t i; const char *supportedFormats[] = { "MONO", "STEREO", @@ -2167,14 +2231,18 @@ static void printSupportedAudioConfigs() { fprintf( stdout, "%s\n", supportedFormats[i] ); } + + return; } -static void convert_backslash( char *str ) +// VE2AT: possibly move these functions to cmdln_parser.c ? +static void convert_backslash( + char *str ) { - int32_t i, len; + int16_t i, len; /* check that all backslashes are correct on the given platform */ - len = strlen( str ); + len = (int16_t) strlen( str ); for ( i = 0; i < len; i++ ) { @@ -2190,6 +2258,8 @@ static void convert_backslash( char *str ) } #endif } + + return; } static void remove_cr( char *str ) @@ -2203,14 +2273,20 @@ static void remove_cr( char *str ) strcpy( pos, pos + 1 ); pos = strchr( pos, '\r' ); } + + return; } -static void clearString( char *str ) +static void clearString( + char *str ) { str[0] = '\0'; + + return; } -static bool isEmptyString( const char *str ) +static bool isEmptyString( + const char *str ) { return str[0] == '\0'; } @@ -2221,17 +2297,18 @@ static bool isEmptyString( const char *str ) * 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, - int32_t numIntSamplesPerChannel, - int32_t numFloatSamplesPerChannel, - int32_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 ) { - int32_t chnl, smpl, i; + int16_t chnl, smpl, i; i = 0; - for ( smpl = 0; smpl < numFloatSamplesPerChannel; ++smpl ) { for ( chnl = 0; chnl < numChannels; ++chnl ) @@ -2248,6 +2325,8 @@ static void convertInputBuffer( const int16_t *intBuffer, ++i; } } + + return; } /*--------------------------------------------------------------------------* @@ -2256,12 +2335,14 @@ static void convertInputBuffer( const int16_t *intBuffer, * 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, - int32_t numSamplesPerChannel, - int32_t numChannels, - int16_t *intBuffer ) + +static void convertOutputBuffer( + const float *floatBuffer, + const int16_t numSamplesPerChannel, + const int16_t numChannels, + int16_t *intBuffer ) { - int32_t chnl, smpl, i; + int16_t chnl, smpl, i; i = 0; @@ -2274,9 +2355,13 @@ static void convertOutputBuffer( const float *floatBuffer, ++i; } } + + return; } #else -int32_t main( int32_t argc, char **argv ) +int main( + int argc, + char **argv ) { (void) argc; (void) argv; diff --git a/lib_dec/ivas_dirac_dec_binaural_functions.c b/lib_dec/ivas_dirac_dec_binaural_functions.c index ca9f0a4587..1418193139 100644 --- a/lib_dec/ivas_dirac_dec_binaural_functions.c +++ b/lib_dec/ivas_dirac_dec_binaural_functions.c @@ -29,7 +29,7 @@ the United Nations Convention on Contracts on the International Sales of Goods. *******************************************************************************************************/ - +// VE2AT: move to lib_rend ? #include #include "options.h" #include @@ -37,7 +37,7 @@ #include "prot.h" #include "ivas_prot.h" #include "ivas_cnst.h" -#include "ivas_rom_binauralRenderer.h" +#include "ivas_rom_binauralRenderer.h" // VE2AT: what about to put these includes ust into ivas_rom_rend.c ? #include "ivas_rom_dec.h" #ifdef DEBUGGING #include "debug.h" diff --git a/lib_dec/ivas_ism_renderer.c b/lib_dec/ivas_ism_renderer.c index 0e7f5f864a..f27d49b111 100644 --- a/lib_dec/ivas_ism_renderer.c +++ b/lib_dec/ivas_ism_renderer.c @@ -29,7 +29,7 @@ the United Nations Convention on Contracts on the International Sales of Goods. *******************************************************************************************************/ - +// VE2AT: move to lib_rend ? #include #include "options.h" #include "ivas_cnst.h" diff --git a/lib_dec/ivas_mono_dmx_renderer.c b/lib_dec/ivas_mono_dmx_renderer.c index 468b0215b0..20b677075e 100644 --- a/lib_dec/ivas_mono_dmx_renderer.c +++ b/lib_dec/ivas_mono_dmx_renderer.c @@ -29,7 +29,7 @@ the United Nations Convention on Contracts on the International Sales of Goods. *******************************************************************************************************/ - +// VE2AT: move to lib_rend ? #include #include "options.h" #include diff --git a/lib_dec/ivas_out_setup_conversion.c b/lib_dec/ivas_out_setup_conversion.c index 9ed27e56c3..55f53bae73 100644 --- a/lib_dec/ivas_out_setup_conversion.c +++ b/lib_dec/ivas_out_setup_conversion.c @@ -29,7 +29,7 @@ the United Nations Convention on Contracts on the International Sales of Goods. *******************************************************************************************************/ - +// VE2AT: move to lib_rend ? #include #include #include "options.h" diff --git a/lib_dec/ivas_rom_dec.c b/lib_dec/ivas_rom_dec.c index 3a08c33e79..c79bc38019 100644 --- a/lib_dec/ivas_rom_dec.c +++ b/lib_dec/ivas_rom_dec.c @@ -516,7 +516,7 @@ const int16_t sba_map_tc[8] = /*----------------------------------------------------------------------------------* * FASTCONV and PARAMETRIC binaural renderer ROM tables *----------------------------------------------------------------------------------*/ - +// VE2AT: move to in ivas_rom_dec ? const float surCohEne[MASA_NUM_DEFINED_SUR_SPR_COH_ENE_BINS] = { 3.0903f, 2.0053f, 1.0860f, 0.8072f, 0.7079f diff --git a/lib_dec/ivas_stat_dec.h b/lib_dec/ivas_stat_dec.h index 2f1b2cc519..50369fab6d 100644 --- a/lib_dec/ivas_stat_dec.h +++ b/lib_dec/ivas_stat_dec.h @@ -41,7 +41,7 @@ #include "ivas_stat_com.h" #include "ivas_stat_rend.h" #ifdef EXT_RENDERER -#include "common_api_types.h" +#include "common_api_types.h" // VE2AT: don't we want to avoid this include in the library? I admit that the rules hefre are not 100% clear to me but introducing it just for IVAS_QUATERNION is not necessry I think #endif @@ -984,7 +984,7 @@ typedef struct mct_dec_data_structure /*----------------------------------------------------------------------------------* * EFAP structures *----------------------------------------------------------------------------------*/ - +// VE2AT: move to ivas_rom_rend.h ? typedef struct EFAP_VERTEX { float azi; /* azimuth of the loudspeaker */ @@ -1047,7 +1047,7 @@ typedef struct EFAP /*----------------------------------------------------------------------------------* * VBAP structures *----------------------------------------------------------------------------------*/ - +// VE2AT: move to ivas_rom_rend.h ? enum SpeakerNodeGroup { SPEAKER_NODE_BOTTOM_HALF, @@ -1105,7 +1105,7 @@ typedef struct vbap_data_structure /*----------------------------------------------------------------------------------* * renderer structures *----------------------------------------------------------------------------------*/ - +// VE2AT: move to ivas_rom_rend.h ? typedef struct renderer_struct { float prev_gains[MAX_CICP_CHANNELS - 1][MAX_OUTPUT_CHANNELS]; @@ -1172,7 +1172,7 @@ typedef struct ivas_masa_decoder_struct /*----------------------------------------------------------------------------------* * Binaural Rendering structure *----------------------------------------------------------------------------------*/ - +// VE2AT: move to ivas_rom_rend.h ? /* Binaural reverberator structure */ typedef struct ivas_binaural_reverb_struct { @@ -1291,7 +1291,7 @@ typedef struct ivas_binaural_rendering_struct /*----------------------------------------------------------------------------------* * Head tracking data structure *----------------------------------------------------------------------------------*/ - +// VE2AT: move to ivas_rom_rend.h ? #ifndef EXT_RENDERER /* Quaternion type for head orientation */ typedef struct Quaternion_struct @@ -1324,7 +1324,7 @@ typedef struct ivas_binaural_head_track_struct /*----------------------------------------------------------------------------------* * TD ISm Object Renderer structure *----------------------------------------------------------------------------------*/ - +// VE2AT: move to ivas_rom_rend.h ? typedef struct { SFX_OpMode_t OpMode; /* Operating mode. This effect can only be TRANSIENT or OFF. */ @@ -1632,7 +1632,7 @@ typedef struct ivas_binaural_td_rendering_struct /*------------------------------------------------------------------------------------------* * Crend structures *------------------------------------------------------------------------------------------*/ - +// VE2AT: move to ivas_rom_rend.h ? typedef struct ivas_hrtfs_structure { float *pOut_to_bin_re[MAX_INTERN_CHANNELS][BINAURAL_CHANNELS]; diff --git a/lib_dec/ivas_vbap.c b/lib_dec/ivas_vbap.c index 2534854e8b..f0960bd127 100644 --- a/lib_dec/ivas_vbap.c +++ b/lib_dec/ivas_vbap.c @@ -29,7 +29,7 @@ the United Nations Convention on Contracts on the International Sales of Goods. *******************************************************************************************************/ - +// VE2AT: move to lib_rend ? #include #include "options.h" #include diff --git a/lib_rend/ivas_crend.c b/lib_rend/ivas_crend.c index 0a5b28cb98..8d291f7832 100644 --- a/lib_rend/ivas_crend.c +++ b/lib_rend/ivas_crend.c @@ -1148,7 +1148,7 @@ ivas_error ivas_rend_openCrend( CREND_WRAPPER *pCrend, IVAS_REND_AudioConfig inConfig, IVAS_REND_AudioConfig outConfig, - int32_t output_Fs ) + const int32_t output_Fs ) { /* TODO tmu : Based on ivas_crend_open() - could be harmonized / refactored */ int16_t i, subframe_length; @@ -1304,12 +1304,12 @@ ivas_error ivas_rend_openCrend( ivas_error ivas_rend_initCrend( CREND_WRAPPER *pCrend, - IVAS_REND_AudioConfig inConfig, - IVAS_REND_AudioConfig outConfig, - int32_t output_Fs ) + const IVAS_REND_AudioConfig inConfig, + const IVAS_REND_AudioConfig outConfig, + const int32_t output_Fs ) { int16_t i, j, tmp; - int32_t nchan_in; + int16_t nchan_in; bool use_brir; IVAS_REND_AudioConfigType inConfigType; HRTFS_HANDLE hHrtf; @@ -1349,7 +1349,7 @@ ivas_error ivas_rend_initCrend( { return error; } - hHrtf->max_num_ir = (int16_t) nchan_in; + hHrtf->max_num_ir = nchan_in; if ( hHrtf->max_num_ir <= 0 ) { @@ -1767,13 +1767,13 @@ ivas_error ivas_rend_closeCrend( ivas_error ivas_rend_crendProcess( const CREND_WRAPPER *pCrend, - IVAS_REND_AudioConfig inConfig, - IVAS_REND_AudioConfig outConfig, + const IVAS_REND_AudioConfig inConfig, + const IVAS_REND_AudioConfig outConfig, float output[][L_FRAME48k], /* i/o: input/output audio channels */ - int32_t output_Fs ) + const int32_t output_Fs ) { int16_t i, subframe_idx, output_frame; - int32_t nchan_out; + int16_t nchan_out; float pcm_tmp[BINAURAL_CHANNELS][L_FRAME48k]; AUDIO_CONFIG in_config; IVAS_REND_AudioConfigType inConfigType; @@ -1830,19 +1830,17 @@ ivas_error ivas_rend_crendConvolver( IVAS_REND_AudioConfig outConfig, float pcm_in[][L_FRAME48k], float pcm_out[][L_FRAME48k], - int32_t output_Fs, + const int32_t output_Fs, const int16_t i_ts ) { int16_t i, j, k, m; int16_t subframe_length, idx_in; int16_t lfe_idx_in; int16_t offset, offset_in, offset_diffuse; - int32_t nchan_in, nchan_out; + int16_t nchan_in, nchan_out; float *pIn; - float *pFreq_buf_re; - float *pFreq_buf_im; - float *pFreq_filt_re; - float *pFreq_filt_im; + float *pFreq_buf_re, *pFreq_buf_im; + float *pFreq_filt_re, *pFreq_filt_im; float pOut[L_FRAME48k * 2]; float tmp_out_re[L_FRAME48k], tmp_out_im[L_FRAME48k]; diff --git a/lib_rend/ivas_lib_rend_internal.h b/lib_rend/ivas_lib_rend_internal.h index 9edfcc46a9..3e8651f522 100644 --- a/lib_rend/ivas_lib_rend_internal.h +++ b/lib_rend/ivas_lib_rend_internal.h @@ -28,44 +28,44 @@ typedef struct } CREND_WRAPPER; IVAS_REND_AudioConfigType getAudioConfigType( - IVAS_REND_AudioConfig config ); + const IVAS_REND_AudioConfig config ); ivas_error getAudioConfigNumChannels( - IVAS_REND_AudioConfig config, - int32_t *numChannels ); + const IVAS_REND_AudioConfig config, + int16_t *numChannels ); AUDIO_CONFIG getIvasAudioConfigFromRendAudioConfig( IVAS_REND_AudioConfig config ); ivas_error ivas_rend_openCrend( CREND_WRAPPER *pCrend, - IVAS_REND_AudioConfig inConfig, - IVAS_REND_AudioConfig outConfig, - int32_t output_Fs ); + const IVAS_REND_AudioConfig inConfig, + const IVAS_REND_AudioConfig outConfig, + const int32_t output_Fs ); ivas_error ivas_rend_initCrend( CREND_WRAPPER *pCrend, - IVAS_REND_AudioConfig inConfig, - IVAS_REND_AudioConfig outConfig, - int32_t output_Fs ); + const IVAS_REND_AudioConfig inConfig, + const IVAS_REND_AudioConfig outConfig, + const int32_t output_Fs ); ivas_error ivas_rend_closeCrend( CREND_WRAPPER *pCrend ); ivas_error ivas_rend_crendProcess( const CREND_WRAPPER *pCrend, - IVAS_REND_AudioConfig inConfig, - IVAS_REND_AudioConfig outConfig, + const IVAS_REND_AudioConfig inConfig, + const IVAS_REND_AudioConfig outConfig, float output[][L_FRAME48k], /* i/o: input/output audio channels */ - int32_t output_Fs ); + const int32_t output_Fs ); ivas_error ivas_rend_crendConvolver( const CREND_WRAPPER *pCrend, - IVAS_REND_AudioConfig inConfig, - IVAS_REND_AudioConfig outConfig, + const IVAS_REND_AudioConfig inConfig, + const IVAS_REND_AudioConfig outConfig, float pcm_in[][L_FRAME48k], float pcm_out[][L_FRAME48k], - int32_t output_Fs, + const int32_t output_Fs, const int16_t i_ts ); ivas_error ivas_rend_TDObjRenderFrame( @@ -81,9 +81,9 @@ ivas_error ivas_rend_TDObjRenderFrame( ivas_error ivas_rend_TDObjRendOpen( TDREND_WRAPPER *pTDRend, - IVAS_REND_AudioConfig inConfig, + const IVAS_REND_AudioConfig inConfig, LSSETUP_CUSTOM_STRUCT *customLsInput, - int32_t outFs ); + const int32_t output_Fs ); #endif #endif diff --git a/lib_rend/ivas_limiter.c b/lib_rend/ivas_limiter.c index 25fad180b9..a4dffb180d 100644 --- a/lib_rend/ivas_limiter.c +++ b/lib_rend/ivas_limiter.c @@ -29,7 +29,7 @@ the United Nations Convention on Contracts on the International Sales of Goods. *******************************************************************************************************/ - +// VE2AT: keep in lib_rend or move to lib_dec ? #include #include #include diff --git a/lib_rend/ivas_objectRenderer.c b/lib_rend/ivas_objectRenderer.c index e4f0706193..a2109db59d 100644 --- a/lib_rend/ivas_objectRenderer.c +++ b/lib_rend/ivas_objectRenderer.c @@ -51,7 +51,9 @@ *---------------------------------------------------------------------*/ static ivas_error TDREND_GetMix( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, float output[][L_FRAME48k], const int16_t subframe_length, const int32_t output_Fs, const int16_t subframe_idx ); + static void TDREND_Clear_Update_flags( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd ); + static void TDREND_Update_listener_orientation( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, const int16_t headRotEnabled, #ifdef EXT_RENDERER @@ -269,9 +271,7 @@ void ObjRenderIVASFrame( for ( subframe_idx = 0; subframe_idx < MAX_PARAM_SPATIAL_SUBFRAMES; subframe_idx++ ) { /* Update the listener's location/orientation */ - TDREND_Update_listener_orientation( st_ivas->hBinRendererTd, - st_ivas->hDecoderConfig->Opt_Headrotation, - ( st_ivas->hHeadTrackData != NULL ) ? &st_ivas->hHeadTrackData->Quaternions[subframe_idx] : NULL ); + TDREND_Update_listener_orientation( st_ivas->hBinRendererTd, st_ivas->hDecoderConfig->Opt_Headrotation, ( st_ivas->hHeadTrackData != NULL ) ? &st_ivas->hHeadTrackData->Quaternions[subframe_idx] : NULL ); if ( ( st_ivas->hRenderConfig != NULL ) && ( st_ivas->hRenderConfig->roomAcoustics.late_reverb_on ) ) { @@ -512,7 +512,7 @@ ivas_error ivas_rend_TDObjRendOpen( TDREND_WRAPPER *pTDRend, IVAS_REND_AudioConfig inConfig, LSSETUP_CUSTOM_STRUCT *customLsInput, - int32_t outFs ) + const int32_t outFs ) { /* TODO tmu : Based on ivas_td_binaural_open() - could be harmonized / refactored - review error handling @@ -526,7 +526,7 @@ ivas_error ivas_rend_TDObjRendOpen( float Pos[3]; float Dir[3]; TDREND_DirAtten_t *DirAtten_p; - int32_t nchan_rend; + int16_t nchan_rend; ivas_error error; error = IVAS_ERR_OK; @@ -645,7 +645,6 @@ ivas_error ivas_rend_TDObjRendOpen( pTDRend->binaural_latency_ns = (int32_t) ( BINAURAL_TD_LATENCY_S * 1000000000.f ); - return IVAS_ERR_OK; } @@ -672,7 +671,7 @@ ivas_error ivas_rend_TDObjRenderFrame( int16_t subframe_idx; ISM_METADATA_HANDLE hIsmMetaData[1]; int16_t lfe_idx; - int32_t num_src; + int16_t num_src; /* TODO tmu : pass down renderer config struct */ // float reverb_signal[BINAURAL_CHANNELS][L_FRAME48k]; IVAS_FORMAT ivas_format; @@ -714,12 +713,7 @@ ivas_error ivas_rend_TDObjRenderFrame( // } /* Update object position(s) */ - TDREND_Update_object_positions( pTDRend->hBinRendererTd, - (int16_t) num_src, - lfe_idx, - ivas_format, - hIsmMetaData, - output ); + TDREND_Update_object_positions( pTDRend->hBinRendererTd, num_src, lfe_idx, ivas_format, hIsmMetaData, output ); /* TODO tmu : needs a refactor / better approach */ if ( ivas_format == ISM_FORMAT ) @@ -730,9 +724,7 @@ ivas_error ivas_rend_TDObjRenderFrame( for ( subframe_idx = 0; subframe_idx < MAX_PARAM_SPATIAL_SUBFRAMES; subframe_idx++ ) { /* Update the listener's location/orientation */ - TDREND_Update_listener_orientation( pTDRend->hBinRendererTd, - headRotData->headRotEnabled, - ( headRotData != NULL ) ? &headRotData->headPositions[subframe_idx] : NULL ); + TDREND_Update_listener_orientation( pTDRend->hBinRendererTd, headRotData->headRotEnabled, ( headRotData != NULL ) ? &headRotData->headPositions[subframe_idx] : NULL ); /* TODO tmu : pass down renderer config struct */ // if ( ( hRenderConfig != NULL ) && ( hRenderConfig->roomAcoustics.late_reverb_on ) ) diff --git a/lib_rend/ivas_output_init.c b/lib_rend/ivas_output_init.c index 005db1d4ac..2cbd476ac1 100644 --- a/lib_rend/ivas_output_init.c +++ b/lib_rend/ivas_output_init.c @@ -29,7 +29,7 @@ the United Nations Convention on Contracts on the International Sales of Goods. *******************************************************************************************************/ - +// VE2AT: keep in lib_rend or move to lib_dec ? #include #include #include "options.h" diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index 2cb50d4507..fb928d637d 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -154,14 +154,8 @@ struct IVAS_REND IVAS_REND_HeadRotData headRotData; }; -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 */ -); - -static IVAS_QUATERNION quaternionInit( void ) +static IVAS_QUATERNION quaternionInit( + void ) { IVAS_QUATERNION q; q.w = 1.0f; @@ -169,12 +163,17 @@ static IVAS_QUATERNION quaternionInit( void ) return q; } -static float *getSmplPtr( IVAS_REND_AudioBuffer buffer, uint32_t chnlIdx, uint32_t smplIdx ) +static float *getSmplPtr( + IVAS_REND_AudioBuffer buffer, + uint32_t chnlIdx, + uint32_t smplIdx ) { return buffer.data + chnlIdx * buffer.config.numSamplesPerChannel + smplIdx; } -static void copyBufferTo2dArray( const IVAS_REND_AudioBuffer buffer, float array[MAX_OUTPUT_CHANNELS][L_FRAME48k] ) +static void copyBufferTo2dArray( + const IVAS_REND_AudioBuffer buffer, + float array[MAX_OUTPUT_CHANNELS][L_FRAME48k] ) { uint32_t smplIdx; uint32_t chnlIdx; @@ -189,11 +188,15 @@ static void copyBufferTo2dArray( const IVAS_REND_AudioBuffer buffer, float array array[chnlIdx][smplIdx] = *readPtr++; } } + + return; } -static void accumulate2dArrayToBuffer( float array[MAX_OUTPUT_CHANNELS][L_FRAME48k], IVAS_REND_AudioBuffer *buffer ) +static void accumulate2dArrayToBuffer( + float array[MAX_OUTPUT_CHANNELS][L_FRAME48k], + IVAS_REND_AudioBuffer *buffer ) { - int32_t smplIdx, chnlIdx; + int16_t smplIdx, chnlIdx; float *writePtr; writePtr = buffer->data; @@ -204,6 +207,8 @@ static void accumulate2dArrayToBuffer( float array[MAX_OUTPUT_CHANNELS][L_FRAME4 *writePtr++ += array[chnlIdx][smplIdx]; } } + + return; } /*-------------------------------------------------------------------* @@ -211,8 +216,10 @@ static void accumulate2dArrayToBuffer( float array[MAX_OUTPUT_CHANNELS][L_FRAME4 * * In-place saturation control for multichannel buffers with adaptive release time * - * r: number of clipped output samples + * *-------------------------------------------------------------------*/ + +/*! 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 */ @@ -257,7 +264,8 @@ static int32_t limitRendererOutput( return numClipping; } -static AUDIO_CONFIG rendAudioConfigToIvasAudioConfig( IVAS_REND_AudioConfig rendConfig ) +static AUDIO_CONFIG rendAudioConfigToIvasAudioConfig( // VE2AT: similar is defined again at line 397, why? + IVAS_REND_AudioConfig rendConfig ) { switch ( rendConfig ) { @@ -300,7 +308,8 @@ static AUDIO_CONFIG rendAudioConfigToIvasAudioConfig( IVAS_REND_AudioConfig rend return AUDIO_CONFIG_INVALID; } -static ivas_error validateOutputAudioConfig( IVAS_REND_AudioConfig outConfig ) +static ivas_error validateOutputAudioConfig( + IVAS_REND_AudioConfig outConfig ) { switch ( outConfig ) { @@ -325,13 +334,16 @@ static ivas_error validateOutputAudioConfig( IVAS_REND_AudioConfig outConfig ) return IVAS_ERR_INVALID_OUTPUT_FORMAT; } -IVAS_REND_AudioConfigType getAudioConfigType( IVAS_REND_AudioConfig config ) +IVAS_REND_AudioConfigType getAudioConfigType( + IVAS_REND_AudioConfig config ) { /* By definition, config type is the second byte (from LSB) of IVAS_REND_AudioConfig enum. */ - return ( config & 0xFF00 ) >> 8; + return ( config & 0xFF00 ) >> 8; // VE2AT: MSVC returns warning C4244: 'return': conversion from 'int' to 'IVAS_REND_InputId', possible loss of data } -static ivas_error validateOutputSampleRate( int32_t sampleRate, IVAS_REND_AudioConfig outConfig ) +static ivas_error validateOutputSampleRate( + const int32_t sampleRate, + const IVAS_REND_AudioConfig outConfig ) { if ( getAudioConfigType( outConfig ) != IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL ) { @@ -352,7 +364,9 @@ static ivas_error validateOutputSampleRate( int32_t sampleRate, IVAS_REND_AudioC return IVAS_ERR_INVALID_SAMPLING_RATE; } -ivas_error getAudioConfigNumChannels( IVAS_REND_AudioConfig config, int32_t *numChannels ) +ivas_error getAudioConfigNumChannels( + const IVAS_REND_AudioConfig config, + int16_t *numChannels ) { switch ( config ) { @@ -394,7 +408,8 @@ ivas_error getAudioConfigNumChannels( IVAS_REND_AudioConfig config, int32_t *num return IVAS_ERR_OK; } -AUDIO_CONFIG getIvasAudioConfigFromRendAudioConfig( IVAS_REND_AudioConfig config ) +AUDIO_CONFIG getIvasAudioConfigFromRendAudioConfig( + IVAS_REND_AudioConfig config ) { switch ( config ) { @@ -427,7 +442,10 @@ AUDIO_CONFIG getIvasAudioConfigFromRendAudioConfig( IVAS_REND_AudioConfig config } } -static ivas_error initLimiter( IVAS_LIMITER_HANDLE *phLimiter, int32_t numChannels, int32_t sampleRate ) +static ivas_error initLimiter( + IVAS_LIMITER_HANDLE *phLimiter, + const int16_t numChannels, + const int32_t sampleRate ) { /* If re-initializing with unchanged values, return early */ if ( *phLimiter != NULL && @@ -452,7 +470,8 @@ static ivas_error initLimiter( IVAS_LIMITER_HANDLE *phLimiter, int32_t numChanne return IVAS_ERR_OK; } -static LSSETUP_CUSTOM_STRUCT defaultCustomLs( void ) +static LSSETUP_CUSTOM_STRUCT defaultCustomLs( + void ) { LSSETUP_CUSTOM_STRUCT ls; @@ -470,7 +489,9 @@ static LSSETUP_CUSTOM_STRUCT defaultCustomLs( void ) return ls; } -static ivas_error getSpeakerAzimuths( IVAS_REND_AudioConfig config, const float **azimuths ) +static ivas_error getSpeakerAzimuths( + IVAS_REND_AudioConfig config, + const float **azimuths ) { switch ( config ) { @@ -502,7 +523,9 @@ static ivas_error getSpeakerAzimuths( IVAS_REND_AudioConfig config, const float return IVAS_ERR_OK; } -static ivas_error getSpeakerElevations( IVAS_REND_AudioConfig config, const float **elevations ) +static ivas_error getSpeakerElevations( + IVAS_REND_AudioConfig config, + const float **elevations ) { switch ( config ) { @@ -534,7 +557,9 @@ static ivas_error getSpeakerElevations( IVAS_REND_AudioConfig config, const floa return IVAS_ERR_OK; } -static ivas_error getAmbisonicsOrder( IVAS_REND_AudioConfig config, int16_t *order ) +static ivas_error getAmbisonicsOrder( + IVAS_REND_AudioConfig config, + int16_t *order ) { switch ( config ) { @@ -554,7 +579,9 @@ static ivas_error getAmbisonicsOrder( IVAS_REND_AudioConfig config, int16_t *ord return IVAS_ERR_OK; } -static ivas_error getNumNonLfeChannelsInSpeakerLayout( IVAS_REND_AudioConfig config, int16_t *numNonLfeChannels ) +static ivas_error getNumNonLfeChannelsInSpeakerLayout( + IVAS_REND_AudioConfig config, + int16_t *numNonLfeChannels ) { switch ( config ) { @@ -589,8 +616,8 @@ static ivas_error getMcConfigValues( LSSETUP_CUSTOM_STRUCT inCustomLs, const float **azimuth, const float **elevation, - int32_t *lfe_idx, - int32_t *is_planar ) + int16_t *lfe_idx, + int16_t *is_planar ) { int16_t i; @@ -637,7 +664,10 @@ static ivas_error getMcConfigValues( return IVAS_ERR_OK; } -static ivas_error initEfap( EFAP_WRAPPER *pEfapWrapper, IVAS_REND_AudioConfig outConfig, const LSSETUP_CUSTOM_STRUCT *pCustomLsOut ) +static ivas_error initEfap( + EFAP_WRAPPER *pEfapWrapper, + IVAS_REND_AudioConfig outConfig, + const LSSETUP_CUSTOM_STRUCT *pCustomLsOut ) { ivas_error error; const float *azimuths; @@ -669,11 +699,7 @@ static ivas_error initEfap( EFAP_WRAPPER *pEfapWrapper, IVAS_REND_AudioConfig ou if ( outConfig == IVAS_REND_AUDIO_CONFIG_LS_CUSTOM ) { - if ( ( error = efap_init_data( &pEfapWrapper->hEfap, - pCustomLsOut->ls_azimuth, - pCustomLsOut->ls_elevation, - pCustomLsOut->num_spk, - EFAP_MODE_EFAP ) ) != IVAS_ERR_OK ) + if ( ( error = efap_init_data( &pEfapWrapper->hEfap, pCustomLsOut->ls_azimuth, pCustomLsOut->ls_elevation, pCustomLsOut->num_spk, EFAP_MODE_EFAP ) ) != IVAS_ERR_OK ) { return error; } @@ -692,11 +718,7 @@ static ivas_error initEfap( EFAP_WRAPPER *pEfapWrapper, IVAS_REND_AudioConfig ou { return error; } - if ( ( error = efap_init_data( &pEfapWrapper->hEfap, - azimuths, - elevations, - numNonLfeChannels, - EFAP_MODE_EFAP ) ) != IVAS_ERR_OK ) + if ( ( error = efap_init_data( &pEfapWrapper->hEfap, azimuths, elevations, numNonLfeChannels, EFAP_MODE_EFAP ) ) != IVAS_ERR_OK ) { return error; } @@ -705,16 +727,17 @@ static ivas_error initEfap( EFAP_WRAPPER *pEfapWrapper, IVAS_REND_AudioConfig ou return IVAS_ERR_OK; } -static ivas_error getEfapGains( EFAP_WRAPPER efapWrapper, - const float azi, - const float ele, - pan_vector panGains ) +static ivas_error getEfapGains( + EFAP_WRAPPER efapWrapper, + const float azi, + const float ele, + pan_vector panGains ) { pan_vector tmpPanGains; /* tmp pan gain buffer without LFE channels */ float *readPtr; - int32_t i; + int16_t i; int16_t lfeCount; - int32_t numChannels; + int16_t numChannels; ivas_error error; /* EFAP returns an array of gains only for non-LFE speakers */ @@ -788,21 +811,28 @@ static void initHeadRotation( { hIvasRend->headRotData.headPositions[i] = quaternionInit(); } + + return; } -static void initRotMatrix( rotation_matrix rot_mat ) +static void initRotMatrix( + rotation_matrix rot_mat ) { int16_t i; + /* Initialize rotation matrices */ for ( i = 0; i < 3; i++ ) { set_zero( rot_mat[i], 3 ); rot_mat[i][i] = 1.f; } + + return; } -static void initRotGains( rotation_gains rot_gains ) +static void initRotGains( + rotation_gains rot_gains ) { int16_t i; /* Set gains to passthrough */ @@ -811,9 +841,15 @@ static void initRotGains( rotation_gains rot_gains ) set_zero( rot_gains[i], MAX_INPUT_CHANNELS ); rot_gains[i][i] = 1.f; } + + return; } -static void initRendInputBase( input_base *inputBase, IVAS_REND_AudioConfig inConfig, IVAS_REND_InputId id, rendering_context rendCtx ) +static void initRendInputBase( + input_base *inputBase, + const IVAS_REND_AudioConfig inConfig, + const IVAS_REND_InputId id, + const rendering_context rendCtx ) { inputBase->inConfig = inConfig; inputBase->id = id; @@ -826,9 +862,12 @@ static void initRendInputBase( input_base *inputBase, IVAS_REND_AudioConfig inCo inputBase->inputBuffer.data = inputBase->bufferData; set_zero( inputBase->bufferData, MAX_BUFFER_LENGTH ); + + return; } -static IVAS_REND_AudioObjectPosition defaultObjectPosition( void ) +static IVAS_REND_AudioObjectPosition defaultObjectPosition( + void ) { IVAS_REND_AudioObjectPosition pos; @@ -838,7 +877,8 @@ static IVAS_REND_AudioObjectPosition defaultObjectPosition( void ) return pos; } -static rendering_context getRendCtx( IVAS_REND_HANDLE hIvasRend ) +static rendering_context getRendCtx( + IVAS_REND_HANDLE hIvasRend ) { rendering_context ctx; @@ -854,7 +894,8 @@ static rendering_context getRendCtx( IVAS_REND_HANDLE hIvasRend ) return ctx; } -static TDREND_WRAPPER defaultTdRendWrapper( void ) +static TDREND_WRAPPER defaultTdRendWrapper( + void ) { TDREND_WRAPPER w; @@ -865,7 +906,8 @@ static TDREND_WRAPPER defaultTdRendWrapper( void ) return w; } -static CREND_WRAPPER defaultCrendWrapper( void ) +static CREND_WRAPPER defaultCrendWrapper( + void ) { CREND_WRAPPER w; @@ -878,8 +920,8 @@ static CREND_WRAPPER defaultCrendWrapper( void ) static ivas_error setRendInputActiveIsm( void *input, - IVAS_REND_AudioConfig inConfig, - IVAS_REND_InputId id ) + const IVAS_REND_AudioConfig inConfig, + const IVAS_REND_InputId id ) { ivas_error error; rendering_context rendCtx; @@ -901,17 +943,11 @@ static ivas_error setRendInputActiveIsm( error = IVAS_ERR_OK; if ( outConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL ) { - error = ivas_rend_TDObjRendOpen( &inputIsm->tdRendWrapper, - inConfig, - NULL, - *rendCtx.pOutSampleRate ); + error = ivas_rend_TDObjRendOpen( &inputIsm->tdRendWrapper, inConfig, NULL, *rendCtx.pOutSampleRate ); } else if ( outConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM ) { - error = ivas_rend_openCrend( &inputIsm->crendWrapper, - IVAS_REND_AUDIO_CONFIG_7_1_4, - outConfig, - *rendCtx.pOutSampleRate ); + error = ivas_rend_openCrend( &inputIsm->crendWrapper, IVAS_REND_AUDIO_CONFIG_7_1_4, outConfig, *rendCtx.pOutSampleRate ); } if ( error != IVAS_ERR_OK ) { @@ -921,7 +957,8 @@ static ivas_error setRendInputActiveIsm( return IVAS_ERR_OK; } -static void clearInputIsm( input_ism *inputIsm ) +static void clearInputIsm( + input_ism *inputIsm ) { rendering_context rendCtx; @@ -941,16 +978,18 @@ static void clearInputIsm( input_ism *inputIsm ) } } -static void copyLsConversionMatrixToPanMatrix( const LS_CONVERSION_MATRIX *lsConvMatrix, pan_matrix panMatrix ) +static void copyLsConversionMatrixToPanMatrix( + const LS_CONVERSION_MATRIX *lsConvMatrix, + pan_matrix panMatrix ) { - int32_t i; - int32_t inCh, outCh; - int32_t numNonZeroGains; - int32_t numColumns; + int16_t i; + int16_t inCh, outCh; + int16_t numNonZeroGains; + int16_t numColumns; /* Index 0 is special and describes the following values */ numNonZeroGains = lsConvMatrix[0].index; - numColumns = (int32_t) lsConvMatrix[0].value; + numColumns = (int16_t) lsConvMatrix[0].value; for ( i = 1; i < numNonZeroGains + 1; ++i ) { @@ -959,22 +998,28 @@ static void copyLsConversionMatrixToPanMatrix( const LS_CONVERSION_MATRIX *lsCon panMatrix[inCh][outCh] = lsConvMatrix[i].value; } + + return; } -static void setZeroPanMatrix( pan_matrix panMatrix ) +static void setZeroPanMatrix( + pan_matrix panMatrix ) { - int32_t i; + int16_t i; for ( i = 0; i < MAX_INPUT_CHANNELS; ++i ) { set_zero( panMatrix[i], MAX_OUTPUT_CHANNELS ); } + + return; } /* Note: this only sets non-zero elements, call setZeroPanMatrix() to init first. */ -static void fillIdentityPanMatrix( pan_matrix panMatrix ) +static void fillIdentityPanMatrix( + pan_matrix panMatrix ) { - int32_t i; + int16_t i; for ( i = 0; i < min( MAX_INPUT_CHANNELS, MAX_OUTPUT_CHANNELS ); ++i ) { @@ -982,17 +1027,20 @@ static void fillIdentityPanMatrix( pan_matrix panMatrix ) } } -static ivas_error initMcPanGainsWithIdentMatrix( input_mc *inputMc ) +static ivas_error initMcPanGainsWithIdentMatrix( + input_mc *inputMc ) { fillIdentityPanMatrix( inputMc->panGains ); return IVAS_ERR_OK; } -static ivas_error initMcPanGainsWithConversionMapping( input_mc *inputMc, IVAS_REND_AudioConfig outConfig ) +static ivas_error initMcPanGainsWithConversionMapping( + input_mc *inputMc, + const IVAS_REND_AudioConfig outConfig ) { AUDIO_CONFIG ivasConfigIn, ivasConfigOut; - int32_t i; + int16_t i; ivasConfigIn = rendAudioConfigToIvasAudioConfig( inputMc->base.inConfig ); ivasConfigOut = rendAudioConfigToIvasAudioConfig( outConfig ); @@ -1066,10 +1114,7 @@ static ivas_error initMcPanGainsWithEfap( input_mc *inputMc, IVAS_REND_AudioConf ++outChIdx; } - if ( ( error = getEfapGains( *inputMc->base.ctx.pEfapOutWrapper, - spkAzi[i], - spkEle[i], - inputMc->panGains[outChIdx] ) ) != IVAS_ERR_OK ) + if ( ( error = getEfapGains( *inputMc->base.ctx.pEfapOutWrapper, spkAzi[i], spkEle[i], inputMc->panGains[outChIdx] ) ) != IVAS_ERR_OK ) { return error; } @@ -1087,7 +1132,9 @@ static ivas_error initMcPanGainsWithEfap( input_mc *inputMc, IVAS_REND_AudioConf return IVAS_ERR_OK; } -static ivas_error getRendInputNumChannels( const void *rendInput, int32_t *numInChannels ) +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: @@ -1116,10 +1163,11 @@ static ivas_error getRendInputNumChannels( const void *rendInput, int32_t *numIn return IVAS_ERR_OK; } -static ivas_error initMcPanGainsWithMonoOut( input_mc *inputMc ) +static ivas_error initMcPanGainsWithMonoOut( + input_mc *inputMc ) { - int32_t i; - int32_t numInChannels; + int16_t i; + int16_t numInChannels; ivas_error error; if ( ( error = getRendInputNumChannels( inputMc, &numInChannels ) ) != IVAS_ERR_OK ) @@ -1137,12 +1185,13 @@ static ivas_error initMcPanGainsWithMonoOut( input_mc *inputMc ) return IVAS_ERR_OK; } -static ivas_error initMcPanGainsWithStereoLookup( input_mc *inputMc ) +static ivas_error initMcPanGainsWithStereoLookup( + input_mc *inputMc ) { - int32_t readIdx; - int32_t writeIdx; + int16_t readIdx; + int16_t writeIdx; bool skipSideSpeakers; - int32_t numInChannels; + int16_t numInChannels; ivas_error error; /* Special case - MONO input. @@ -1189,7 +1238,7 @@ static bool configsAreEqual( IVAS_REND_AudioConfig configB, LSSETUP_CUSTOM_STRUCT customLsB ) { - int32_t i; + int16_t i; /* Both input and output are custom LS - compare structs */ if ( configA == IVAS_REND_AUDIO_CONFIG_LS_CUSTOM && configB == IVAS_REND_AUDIO_CONFIG_LS_CUSTOM ) @@ -1230,7 +1279,9 @@ static bool configsAreEqual( return configA == configB; } -static ivas_error updateMcPanGainsForMcOut( input_mc *inputMc, IVAS_REND_AudioConfig outConfig ) +static ivas_error updateMcPanGainsForMcOut( + input_mc *inputMc, + const IVAS_REND_AudioConfig outConfig ) { ivas_error error; @@ -1246,10 +1297,7 @@ static ivas_error updateMcPanGainsForMcOut( input_mc *inputMc, IVAS_REND_AudioCo +-----------+----------+---------------+-----------+--------------------+ */ - if ( configsAreEqual( inputMc->base.inConfig, - inputMc->customLsInput, - outConfig, - *inputMc->base.ctx.pCustomLsOut ) ) + if ( configsAreEqual( inputMc->base.inConfig, inputMc->customLsInput, outConfig, *inputMc->base.ctx.pCustomLsOut ) ) { error = initMcPanGainsWithIdentMatrix( inputMc ); } @@ -1275,7 +1323,9 @@ static ivas_error updateMcPanGainsForMcOut( input_mc *inputMc, IVAS_REND_AudioCo return error; } -static ivas_error updateMcPanGainsForAmbiOut( input_mc *inputMc, IVAS_REND_AudioConfig outConfig ) +static ivas_error updateMcPanGainsForAmbiOut( + input_mc *inputMc, + const IVAS_REND_AudioConfig outConfig ) { int16_t ch_in, ch_out, lfeIdx; int16_t numNonLfeInChannels, outAmbiOrder; @@ -1308,10 +1358,7 @@ static ivas_error updateMcPanGainsForAmbiOut( input_mc *inputMc, IVAS_REND_Audio { ++ch_out; } - ivas_dirac_dec_get_response( (int16_t) spkAzi[ch_in], - (int16_t) spkEle[ch_in], - inputMc->panGains[ch_out], - outAmbiOrder ); + ivas_dirac_dec_get_response( (int16_t) spkAzi[ch_in], (int16_t) spkEle[ch_in], inputMc->panGains[ch_out], outAmbiOrder ); } } else @@ -1331,19 +1378,18 @@ static ivas_error updateMcPanGainsForAmbiOut( input_mc *inputMc, IVAS_REND_Audio } } - ivas_dirac_dec_get_response( (int16_t) spkAzi[ch_in], - (int16_t) spkEle[ch_in], - inputMc->panGains[ch_out], - outAmbiOrder ); + ivas_dirac_dec_get_response( (int16_t) spkAzi[ch_in], (int16_t) spkEle[ch_in], inputMc->panGains[ch_out], outAmbiOrder ); } } return IVAS_ERR_OK; } -static ivas_error updateMcPanGains( input_mc *inputMc, IVAS_REND_AudioConfig outConfig ) +static ivas_error updateMcPanGains( + input_mc *inputMc, + const IVAS_REND_AudioConfig outConfig ) { - int32_t i; + int16_t i; ivas_error error; /* Reset to all zeros - some functions below only write non-zero elements. */ @@ -1402,7 +1448,7 @@ static ivas_error updateMcPanGains( input_mc *inputMc, IVAS_REND_AudioConfig out See issue: https://forge.3gpp.org/rep/ivas-codec-pc/ivas-codec/-/issues/81 */ static void tmpFixBuggyTdBinRendInit( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd ) { - int32_t i, j; + int16_t i, j; for ( i = 0; i < hBinRendererTd->NumOfSrcs; ++i ) { @@ -1419,8 +1465,8 @@ static void tmpFixBuggyTdBinRendInit( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRen static ivas_error initMcBinauralRendering( input_mc *inputMc, - IVAS_REND_AudioConfig inConfig, - IVAS_REND_AudioConfig outConfig ) + const IVAS_REND_AudioConfig inConfig, + const IVAS_REND_AudioConfig outConfig ) { ivas_error error; int32_t outSampleRate; @@ -1456,10 +1502,7 @@ static ivas_error initMcBinauralRendering( // if ( initTDRend ) { - if ( ( error = ivas_rend_TDObjRendOpen( &inputMc->tdRendWrapper, - inConfig, - &inputMc->customLsInput, - outSampleRate ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_rend_TDObjRendOpen( &inputMc->tdRendWrapper, inConfig, &inputMc->customLsInput, outSampleRate ) ) != IVAS_ERR_OK ) { return error; } @@ -1469,10 +1512,7 @@ static ivas_error initMcBinauralRendering( } { - if ( ( error = ivas_rend_openCrend( &inputMc->crendWrapper, - ( inConfig == IVAS_REND_AUDIO_CONFIG_LS_CUSTOM ) ? IVAS_REND_AUDIO_CONFIG_7_1_4 : inConfig, - outConfig, - outSampleRate ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_rend_openCrend( &inputMc->crendWrapper, ( inConfig == IVAS_REND_AUDIO_CONFIG_LS_CUSTOM ) ? IVAS_REND_AUDIO_CONFIG_7_1_4 : inConfig, outConfig, outSampleRate ) ) != IVAS_ERR_OK ) { return error; } @@ -1538,8 +1578,8 @@ static IVAS_REND_LfeRouting defaultLfeRouting( static ivas_error setRendInputActiveMc( void *input, - IVAS_REND_AudioConfig inConfig, - IVAS_REND_InputId id ) + const IVAS_REND_AudioConfig inConfig, + const IVAS_REND_InputId id ) { ivas_error error; rendering_context rendCtx; @@ -1556,10 +1596,7 @@ static ivas_error setRendInputActiveMc( inputMc->tdRendWrapper = defaultTdRendWrapper(); inputMc->crendWrapper = defaultCrendWrapper(); initRotGains( inputMc->rot_gains_prev ); - inputMc->lfeRouting = defaultLfeRouting( inConfig, - inputMc->customLsInput, - outConfig, - *inputMc->base.ctx.pCustomLsOut ); + inputMc->lfeRouting = defaultLfeRouting( inConfig, inputMc->customLsInput, outConfig, *inputMc->base.ctx.pCustomLsOut ); if ( outConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL || outConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM ) { @@ -1577,7 +1614,8 @@ static ivas_error setRendInputActiveMc( return IVAS_ERR_OK; } -static void clearInputMc( input_mc *inputMc ) +static void clearInputMc( + input_mc *inputMc ) { rendering_context rendCtx; @@ -1599,11 +1637,13 @@ static void clearInputMc( input_mc *inputMc ) ivas_td_binaural_close( &inputMc->tdRendWrapper.hBinRendererTd ); inputMc->tdRendWrapper.hHrtfTD = NULL; } + + return; } static ivas_error initSbaPanGainsForMcOut( input_sba *inputSba, - IVAS_REND_AudioConfig outConfig, + const IVAS_REND_AudioConfig outConfig, const LSSETUP_CUSTOM_STRUCT *outSetupCustom ) { int16_t ambiOrderIn; @@ -1671,7 +1711,9 @@ static ivas_error initSbaPanGainsForMcOut( return IVAS_ERR_OK; } -static ivas_error initSbaPanGainsForSbaOut( input_sba *inputSba, IVAS_REND_AudioConfig outConfig ) +static ivas_error initSbaPanGainsForSbaOut( + input_sba *inputSba, + const IVAS_REND_AudioConfig outConfig ) { ivas_error error; error = IVAS_ERR_OK; @@ -1687,7 +1729,9 @@ static ivas_error initSbaPanGainsForSbaOut( input_sba *inputSba, IVAS_REND_Audio return error; } -static ivas_error updateSbaPanGains( input_sba *inputSba, IVAS_REND_AudioConfig outConfig ) +static ivas_error updateSbaPanGains( + input_sba *inputSba, + const IVAS_REND_AudioConfig outConfig ) { ivas_error error; IVAS_REND_AudioConfig inConfig; @@ -1711,20 +1755,14 @@ static ivas_error updateSbaPanGains( input_sba *inputSba, IVAS_REND_AudioConfig switch ( outConfig ) { case IVAS_REND_AUDIO_CONFIG_BINAURAL: - error = ivas_rend_openCrend( &inputSba->crendWrapper, - inConfig, - outConfig, - *rendCtx.pOutSampleRate ); + error = ivas_rend_openCrend( &inputSba->crendWrapper, inConfig, outConfig, *rendCtx.pOutSampleRate ); break; case IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM: if ( ( error = initSbaPanGainsForMcOut( inputSba, IVAS_REND_AUDIO_CONFIG_7_1_4, NULL ) ) != IVAS_ERR_OK ) { return error; } - error = ivas_rend_openCrend( &inputSba->crendWrapper, - IVAS_REND_AUDIO_CONFIG_7_1_4, - outConfig, - *rendCtx.pOutSampleRate ); + error = ivas_rend_openCrend( &inputSba->crendWrapper, IVAS_REND_AUDIO_CONFIG_7_1_4, outConfig, *rendCtx.pOutSampleRate ); break; default: return IVAS_ERR_INVALID_OUTPUT_FORMAT; @@ -1744,8 +1782,8 @@ static ivas_error updateSbaPanGains( input_sba *inputSba, IVAS_REND_AudioConfig static ivas_error setRendInputActiveSba( void *input, - IVAS_REND_AudioConfig inConfig, - IVAS_REND_InputId id ) + const IVAS_REND_AudioConfig inConfig, + const IVAS_REND_InputId id ) { ivas_error error; rendering_context rendCtx; @@ -1769,7 +1807,8 @@ static ivas_error setRendInputActiveSba( return error; } -static void clearInputSba( input_sba *inputSba ) +static void clearInputSba( + input_sba *inputSba ) { rendering_context rendCtx; @@ -1782,17 +1821,19 @@ static void clearInputSba( input_sba *inputSba ) { ivas_rend_closeCrend( &inputSba->crendWrapper ); } + + return; } ivas_error IVAS_REND_Open( IVAS_REND_HANDLE *phIvasRend, - int32_t outputSampleRate, - IVAS_REND_AudioConfig outConfig ) + const int32_t outputSampleRate, + const IVAS_REND_AudioConfig outConfig ) { int16_t i; IVAS_REND_HANDLE hIvasRend; ivas_error error; - int32_t numOutChannels; + int16_t numOutChannels; /*-----------------------------------------------------------------* * Validate function arguments @@ -1844,36 +1885,28 @@ ivas_error IVAS_REND_Open( /* Initialize inputs */ for ( i = 0; i < RENDERER_MAX_ISM_INPUTS; ++i ) { - initRendInputBase( &hIvasRend->inputsIsm[i].base, - IVAS_REND_AUDIO_CONFIG_UNKNOWN, - 0, - getRendCtx( hIvasRend ) ); + initRendInputBase( &hIvasRend->inputsIsm[i].base, IVAS_REND_AUDIO_CONFIG_UNKNOWN, 0, getRendCtx( hIvasRend ) ); hIvasRend->inputsIsm[i].crendWrapper.hCrend = NULL; hIvasRend->inputsIsm[i].tdRendWrapper.hBinRendererTd = NULL; } for ( i = 0; i < RENDERER_MAX_MC_INPUTS; ++i ) { - initRendInputBase( &hIvasRend->inputsMc[i].base, - IVAS_REND_AUDIO_CONFIG_UNKNOWN, - 0, - getRendCtx( hIvasRend ) ); + initRendInputBase( &hIvasRend->inputsMc[i].base, IVAS_REND_AUDIO_CONFIG_UNKNOWN, 0, getRendCtx( hIvasRend ) ); hIvasRend->inputsMc[i].efapInWrapper.hEfap = NULL; hIvasRend->inputsMc[i].crendWrapper.hCrend = NULL; hIvasRend->inputsMc[i].tdRendWrapper.hBinRendererTd = NULL; } for ( i = 0; i < RENDERER_MAX_SBA_INPUTS; ++i ) { - initRendInputBase( &hIvasRend->inputsSba[i].base, - IVAS_REND_AUDIO_CONFIG_UNKNOWN, - 0, - getRendCtx( hIvasRend ) ); + initRendInputBase( &hIvasRend->inputsSba[i].base, IVAS_REND_AUDIO_CONFIG_UNKNOWN, 0, getRendCtx( hIvasRend ) ); hIvasRend->inputsSba[i].crendWrapper.hCrend = NULL; } return IVAS_ERR_OK; } -static LSSETUP_CUSTOM_STRUCT makeCustomLsSetup( IVAS_CUSTOM_LS_DATA rendCustomLsLayout ) +static LSSETUP_CUSTOM_STRUCT makeCustomLsSetup( + const IVAS_CUSTOM_LS_DATA rendCustomLsLayout ) { int16_t i; LSSETUP_CUSTOM_STRUCT customLs; @@ -1899,9 +1932,10 @@ static LSSETUP_CUSTOM_STRUCT makeCustomLsSetup( IVAS_CUSTOM_LS_DATA rendCustomLs return customLs; } -static ivas_error validateCustomLsLayout( IVAS_CUSTOM_LS_DATA layout ) +static ivas_error validateCustomLsLayout( + const IVAS_CUSTOM_LS_DATA layout ) { - int32_t i; + int16_t i; /* Negative number of speakers or LFEs makes no sense */ if ( layout.num_spk < 0 || layout.num_lfe < 0 ) @@ -1927,11 +1961,10 @@ static ivas_error validateCustomLsLayout( IVAS_CUSTOM_LS_DATA layout ) ivas_error IVAS_REND_ConfigureCustomOutputLoudspeakerLayout( IVAS_REND_HANDLE hIvasRend, - IVAS_CUSTOM_LS_DATA layout ) + const IVAS_CUSTOM_LS_DATA layout ) { - int32_t numOutChannels; + int16_t i, numOutChannels; ivas_error error; - int32_t i; input_mc *inputMc; input_sba *inputSba; @@ -1960,14 +1993,10 @@ ivas_error IVAS_REND_ConfigureCustomOutputLoudspeakerLayout( { return error; } - initLimiter( &hIvasRend->hLimiter, - numOutChannels, - hIvasRend->sampleRateOut ); + initLimiter( &hIvasRend->hLimiter, numOutChannels, hIvasRend->sampleRateOut ); /* Re-initialize EFAP - output layout has changed or has been fully defined for the first time */ - initEfap( &hIvasRend->efapOutWrapper, - hIvasRend->outputConfig, - &hIvasRend->customLsOut ); + initEfap( &hIvasRend->efapOutWrapper, hIvasRend->outputConfig, &hIvasRend->customLsOut ); /* Re-initialize panning gains for each active MC input, This includes re-initializing * LFE handling for the new output layout, which means custom LFE handling is overwritten, @@ -1980,10 +2009,9 @@ ivas_error IVAS_REND_ConfigureCustomOutputLoudspeakerLayout( /* Input inactive, skip. */ continue; } - inputMc->lfeRouting = defaultLfeRouting( inputMc->base.inConfig, - inputMc->customLsInput, - hIvasRend->outputConfig, - *inputMc->base.ctx.pCustomLsOut ); + + inputMc->lfeRouting = defaultLfeRouting( inputMc->base.inConfig, inputMc->customLsInput, hIvasRend->outputConfig, *inputMc->base.ctx.pCustomLsOut ); + if ( ( error = updateMcPanGains( inputMc, hIvasRend->outputConfig ) ) != IVAS_ERR_OK ) { return error; @@ -2010,7 +2038,7 @@ ivas_error IVAS_REND_ConfigureCustomOutputLoudspeakerLayout( ivas_error IVAS_REND_NumOutChannels( IVAS_REND_CONST_HANDLE hIvasRend, - int32_t *numOutChannels ) + int16_t *numOutChannels ) { ivas_error error; @@ -2042,7 +2070,9 @@ ivas_error IVAS_REND_NumOutChannels( return IVAS_ERR_OK; } -static IVAS_REND_InputId makeInputId( IVAS_REND_AudioConfig config, int32_t inputIndex ) +static IVAS_REND_InputId makeInputId( + IVAS_REND_AudioConfig config, + const int32_t inputIndex ) { /* Put config type in second byte (from LSB), put index + 1 in first byte * @@ -2050,7 +2080,10 @@ static IVAS_REND_InputId makeInputId( IVAS_REND_AudioConfig config, int32_t inpu return getAudioConfigType( config ) << 8 | ( inputIndex + 1 ); } -static ivas_error getInputById( IVAS_REND_HANDLE hIvasRend, IVAS_REND_InputId inputId, void **ppInput ) +static ivas_error getInputById( + IVAS_REND_HANDLE hIvasRend, + IVAS_REND_InputId inputId, + void **ppInput ) { int32_t inputIndex; IVAS_REND_AudioConfigType configType; @@ -2105,7 +2138,10 @@ static ivas_error getInputById( IVAS_REND_HANDLE hIvasRend, IVAS_REND_InputId in } /* Unfortunately code duplication here is the only way to avoid warnings about const casting */ -static ivas_error getConstInputById( IVAS_REND_CONST_HANDLE hIvasRend, IVAS_REND_InputId inputId, const void **ppInput ) +static ivas_error getConstInputById( + IVAS_REND_CONST_HANDLE hIvasRend, + const IVAS_REND_InputId inputId, + const void **ppInput ) { int32_t inputIndex; IVAS_REND_AudioConfigType configType; @@ -2246,19 +2282,14 @@ ivas_error IVAS_REND_AddInput( } /* Find first free input in array corresponding to input type */ - if ( ( error = findFreeInputSlot( inputsArray, - inputStructSize, - maxNumInputsOfType, - &inputIndex ) ) != IVAS_ERR_OK ) + if ( ( error = findFreeInputSlot( inputsArray, inputStructSize, maxNumInputsOfType, &inputIndex ) ) != IVAS_ERR_OK ) { return error; } *inputId = makeInputId( inConfig, inputIndex ); - if ( ( error = activateInput( (uint8_t *) inputsArray + inputStructSize * inputIndex, - inConfig, - *inputId ) ) != IVAS_ERR_OK ) + if ( ( error = activateInput( (uint8_t *) inputsArray + inputStructSize * inputIndex, inConfig, *inputId ) ) != IVAS_ERR_OK ) { return error; } @@ -2268,8 +2299,8 @@ ivas_error IVAS_REND_AddInput( ivas_error IVAS_REND_ConfigureCustomInputLoudspeakerLayout( IVAS_REND_HANDLE hIvasRend, - IVAS_REND_InputId inputId, - IVAS_CUSTOM_LS_DATA layout ) + const IVAS_REND_InputId inputId, + const IVAS_CUSTOM_LS_DATA layout ) { input_mc *inputMc; ivas_error error; @@ -2301,10 +2332,7 @@ ivas_error IVAS_REND_ConfigureCustomInputLoudspeakerLayout( * set for the MC input. */ inputMc->customLsInput = makeCustomLsSetup( layout ); - inputMc->lfeRouting = defaultLfeRouting( inputMc->base.inConfig, - inputMc->customLsInput, - hIvasRend->outputConfig, - *inputMc->base.ctx.pCustomLsOut ); + inputMc->lfeRouting = defaultLfeRouting( inputMc->base.inConfig, inputMc->customLsInput, hIvasRend->outputConfig, *inputMc->base.ctx.pCustomLsOut ); initEfap( &inputMc->efapInWrapper, inputMc->base.inConfig, &inputMc->customLsInput ); @@ -2325,8 +2353,8 @@ ivas_error IVAS_REND_ConfigureCustomInputLoudspeakerLayout( ivas_error IVAS_REND_SetInputGain( IVAS_REND_HANDLE hIvasRend, - IVAS_REND_InputId inputId, - float gain /* linear gain, not in dB */ + const IVAS_REND_InputId inputId, + const float gain /* linear gain, not in dB */ ) { input_base *inputBase; @@ -2350,7 +2378,8 @@ ivas_error IVAS_REND_SetInputGain( return IVAS_ERR_OK; } -static int32_t getNumLfeChannels( input_mc *inputMc ) +static int32_t getNumLfeChannels( + input_mc *inputMc ) { switch ( inputMc->base.inConfig ) { @@ -2371,8 +2400,8 @@ static int32_t getNumLfeChannels( input_mc *inputMc ) ivas_error IVAS_REND_SetInputLfeRouting( IVAS_REND_HANDLE hIvasRend, - IVAS_REND_InputId inputId, - IVAS_REND_LfeRouting lfeRouting ) + const IVAS_REND_InputId inputId, + const IVAS_REND_LfeRouting lfeRouting ) { input_base *pInputBase; input_mc *pInputMc; @@ -2413,7 +2442,7 @@ ivas_error IVAS_REND_SetInputLfeRouting( ivas_error IVAS_REND_RemoveInput( IVAS_REND_HANDLE hIvasRend, - IVAS_REND_InputId inputId ) + const IVAS_REND_InputId inputId ) { ivas_error error; input_base *inputBase; @@ -2451,8 +2480,8 @@ ivas_error IVAS_REND_RemoveInput( ivas_error IVAS_REND_GetInputNumChannels( IVAS_REND_CONST_HANDLE hIvasRend, - IVAS_REND_InputId inputId, - int32_t *numChannels ) + const IVAS_REND_InputId inputId, + int16_t *numChannels ) { ivas_error error; const input_base *pInput; @@ -2537,12 +2566,12 @@ ivas_error IVAS_REND_GetDelay( ivas_error IVAS_REND_FeedInputAudio( IVAS_REND_HANDLE hIvasRend, - IVAS_REND_InputId inputId, - IVAS_REND_ReadOnlyAudioBuffer inputAudio ) + const IVAS_REND_InputId inputId, + const IVAS_REND_ReadOnlyAudioBuffer inputAudio ) { ivas_error error; input_base *inputBase; - int32_t numInputChannels; + int16_t numInputChannels; /*-----------------------------------------------------------------* * Validate function arguments @@ -2582,9 +2611,7 @@ ivas_error IVAS_REND_FeedInputAudio( inputBase->inputBuffer.config = inputAudio.config; - mvr2r( inputAudio.data, - inputBase->inputBuffer.data, - inputAudio.config.numSamplesPerChannel * inputAudio.config.numChannels ); + mvr2r( inputAudio.data, inputBase->inputBuffer.data, inputAudio.config.numSamplesPerChannel * inputAudio.config.numChannels ); inputBase->numNewSamplesPerChannel = inputAudio.config.numSamplesPerChannel; @@ -2593,8 +2620,8 @@ ivas_error IVAS_REND_FeedInputAudio( ivas_error IVAS_REND_FeedInputObjectMetadata( IVAS_REND_HANDLE hIvasRend, - IVAS_REND_InputId inputId, - IVAS_REND_AudioObjectPosition objectPosition ) + const IVAS_REND_InputId inputId, + const IVAS_REND_AudioObjectPosition objectPosition ) { input_base *inputBase; input_ism *inputIsm; @@ -2741,6 +2768,8 @@ static void renderBufferChannel( IVAS_REND_AudioBuffer outAudio ) { renderBufferChannelLerp( inAudio, inChannelIdx, outputGains, NULL, outAudio ); + + return; } static ivas_error rotateFrameMc( @@ -2755,20 +2784,18 @@ static ivas_error rotateFrameMc( { int16_t i; int16_t subframe_idx, subframe_len; - int16_t azimuth, elevation; - int32_t is_planar_setup, lfe_idx; - int32_t nchan; - int32_t ch_in, ch_out; - int32_t ch_in_woLFE, ch_out_woLFE; - + int16_t is_planar_setup, lfe_idx; + int16_t nchan; + int16_t ch_in, ch_out; + int16_t ch_in_woLFE, ch_out_woLFE; float *readPtr, *writePtr; const float *ls_azimuth, *ls_elevation; rotation_matrix Rmat; rotation_gains gains; float tmp_gains[MAX_INPUT_CHANNELS]; - wmops_sub_start("rotateFrameMc"); + wmops_sub_start( "rotateFrameMc" ); if ( inConfig != IVAS_REND_AUDIO_CONFIG_LS_CUSTOM ) { @@ -2779,12 +2806,7 @@ static ivas_error rotateFrameMc( nchan = inCustomLs.num_spk + inCustomLs.num_lfe; } - getMcConfigValues( inConfig, - inCustomLs, - &ls_azimuth, - &ls_elevation, - &lfe_idx, - &is_planar_setup ); + getMcConfigValues( inConfig, inCustomLs, &ls_azimuth, &ls_elevation, &lfe_idx, &is_planar_setup ); /* initialize gains to passthrough */ for ( ch_in = 0; ch_in < nchan; ch_in++ ) @@ -2812,20 +2834,11 @@ static ivas_error rotateFrameMc( ch_in_woLFE = ( ( lfe_idx > 0 ) && ( ch_in >= lfe_idx ) ) ? ch_in - 1 : ch_in; /* gains for current subframe rotation */ - rotateAziEle( ls_azimuth[ch_in_woLFE], - ls_elevation[ch_in_woLFE], - &azimuth, - &elevation, - Rmat, - (int16_t) is_planar_setup ); + rotateAziEle( ls_azimuth[ch_in_woLFE], ls_elevation[ch_in_woLFE], &azimuth, &elevation, Rmat, is_planar_setup ); if ( hEFAPdata != NULL && ( ls_azimuth[ch_in_woLFE] != azimuth || ls_elevation[ch_in_woLFE] != elevation ) ) { - efap_determine_gains( hEFAPdata, - tmp_gains, - azimuth, - elevation, - EFAP_MODE_EFAP ); + efap_determine_gains( hEFAPdata, tmp_gains, azimuth, elevation, EFAP_MODE_EFAP ); for ( ch_out = 0; ch_out < nchan; ch_out++ ) { @@ -2885,13 +2898,12 @@ static ivas_error rotateFrameSba( int16_t m1, m2; int16_t shd_rot_max_order; int16_t subframe_idx, subframe_len; - float *readPtr, *writePtr; rotation_matrix Rmat; float tmpRot[2 * HEADROT_ORDER + 1]; rotation_gains gains; - wmops_sub_start("rotateFrameSba"); + wmops_sub_start( "rotateFrameSba" ); getAmbisonicsOrder( inConfig, &shd_rot_max_order ); @@ -2977,10 +2989,9 @@ static ivas_error renderIsmToBinaural( IVAS_REND_AudioBuffer outAudio ) { float tmpTDRendBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; - ivas_error error; - wmops_sub_start("renderIsmToBinaural"); + wmops_sub_start( "renderIsmToBinaural" ); copyBufferTo2dArray( ismInput->base.inputBuffer, tmpTDRendBuffer ); @@ -3011,11 +3022,10 @@ static ivas_error renderIsmToBinauralRoom( int16_t i; int16_t azi_rot, ele_rot; int16_t subframe_idx, subframe_len; - int32_t tmp; + int16_t tmp; rotation_matrix Rmat; float tmpCrendBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; IVAS_QUATERNION quat; - ivas_error error; pan_vector currentPanGains; pan_vector previousPanGains; @@ -3023,7 +3033,7 @@ static ivas_error renderIsmToBinauralRoom( IVAS_REND_AudioObjectPosition rotatedPos; const IVAS_REND_HeadRotData *headRotData; - wmops_sub_start("renderIsmToBinauralRoom"); + wmops_sub_start( "renderIsmToBinauralRoom" ); headRotData = ismInput->base.ctx.pHeadRotData; rotatedPos = defaultObjectPosition(); @@ -3050,12 +3060,7 @@ static ivas_error renderIsmToBinauralRoom( /* previous position gains */ if ( headRotData->headRotEnabled ) { - rotateAziEle( ismInput->previousPos.azimuth, - ismInput->previousPos.elevation, - &azi_rot, - &ele_rot, - ismInput->rot_mat_prev, - 0 ); + rotateAziEle( ismInput->previousPos.azimuth, ismInput->previousPos.elevation, &azi_rot, &ele_rot, ismInput->rot_mat_prev, 0 ); rotatedPos.azimuth = (float) azi_rot; rotatedPos.elevation = (float) ele_rot; } @@ -3070,12 +3075,7 @@ static ivas_error renderIsmToBinauralRoom( /* current position gains */ if ( headRotData->headRotEnabled ) { - rotateAziEle( ismInput->currentPos.azimuth, - ismInput->currentPos.elevation, - &azi_rot, - &ele_rot, - Rmat, - 0 ); + rotateAziEle( ismInput->currentPos.azimuth, ismInput->currentPos.elevation, &azi_rot, &ele_rot, Rmat, 0 ); rotatedPos.azimuth = (float) azi_rot; rotatedPos.elevation = (float) ele_rot; } @@ -3095,23 +3095,15 @@ static ivas_error renderIsmToBinauralRoom( /* intermediate rendering to 7_1_4 */ tmpMcBuffer = ismInput->base.inputBuffer; getAudioConfigNumChannels( IVAS_REND_AUDIO_CONFIG_7_1_4, &tmp ); - tmpMcBuffer.config.numChannels = (int16_t) tmp; + tmpMcBuffer.config.numChannels = tmp; tmpMcBuffer.data = count_malloc( tmpMcBuffer.config.numSamplesPerChannel * tmpMcBuffer.config.numChannels * sizeof( float ) ); set_zero( tmpMcBuffer.data, tmpMcBuffer.config.numSamplesPerChannel * tmpMcBuffer.config.numChannels ); - renderBufferChannelLerp( ismInput->base.inputBuffer, - 0, - currentPanGains, - previousPanGains, - tmpMcBuffer ); + renderBufferChannelLerp( ismInput->base.inputBuffer, 0, currentPanGains, previousPanGains, tmpMcBuffer ); copyBufferTo2dArray( tmpMcBuffer, tmpCrendBuffer ); - ivas_rend_crendProcess( &ismInput->crendWrapper, - IVAS_REND_AUDIO_CONFIG_7_1_4, - IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM, - tmpCrendBuffer, - *ismInput->base.ctx.pOutSampleRate ); + ivas_rend_crendProcess( &ismInput->crendWrapper, IVAS_REND_AUDIO_CONFIG_7_1_4, IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM, tmpCrendBuffer, *ismInput->base.ctx.pOutSampleRate ); accumulate2dArrayToBuffer( tmpCrendBuffer, &outAudio ); @@ -3124,37 +3116,27 @@ static ivas_error renderIsmToBinauralRoom( static ivas_error renderIsmToMc( const input_ism *ismInput, - IVAS_REND_AudioBuffer outAudio ) + const IVAS_REND_AudioBuffer outAudio ) { pan_vector currentPanGains; pan_vector previousPanGains; ivas_error error; - wmops_sub_start("renderIsmToMc"); + wmops_sub_start( "renderIsmToMc" ); /* TODO(sgi): Possible optimization: less processing needed if position didn't change */ - if ( ( error = getEfapGains( *ismInput->base.ctx.pEfapOutWrapper, - ismInput->currentPos.azimuth, - ismInput->currentPos.elevation, - currentPanGains ) ) != IVAS_ERR_OK ) + if ( ( error = getEfapGains( *ismInput->base.ctx.pEfapOutWrapper, ismInput->currentPos.azimuth, ismInput->currentPos.elevation, currentPanGains ) ) != IVAS_ERR_OK ) { return error; } - if ( ( error = getEfapGains( *ismInput->base.ctx.pEfapOutWrapper, - ismInput->previousPos.azimuth, - ismInput->previousPos.elevation, - previousPanGains ) ) != IVAS_ERR_OK ) + if ( ( error = getEfapGains( *ismInput->base.ctx.pEfapOutWrapper, ismInput->previousPos.azimuth, ismInput->previousPos.elevation, previousPanGains ) ) != IVAS_ERR_OK ) { return error; } /* Assume num channels in audio buffer to be 1. * This should have been validated in IVAS_REND_FeedInputAudio() */ - renderBufferChannelLerp( ismInput->base.inputBuffer, - 0, - currentPanGains, - previousPanGains, - outAudio ); + renderBufferChannelLerp( ismInput->base.inputBuffer, 0, currentPanGains, previousPanGains, outAudio ); wmops_sub_end(); @@ -3163,17 +3145,17 @@ static ivas_error renderIsmToMc( static ivas_error renderIsmToSba( const input_ism *ismInput, - IVAS_REND_AudioConfig outConfig, - IVAS_REND_AudioBuffer outAudio ) + const IVAS_REND_AudioConfig outConfig, + const IVAS_REND_AudioBuffer outAudio ) { int16_t ambiOrderOut; - int32_t numOutChannels; + int16_t numOutChannels; pan_vector currentPanGains; pan_vector previousPanGains; ivas_error error; error = IVAS_ERR_OK; - wmops_sub_start("renderIsmToSba"); + wmops_sub_start( "renderIsmToSba" ); if ( ( error = getAudioConfigNumChannels( outConfig, &numOutChannels ) ) != IVAS_ERR_OK ) { @@ -3184,10 +3166,7 @@ static ivas_error renderIsmToSba( return error; } - ivas_dirac_dec_get_response( (int16_t) ismInput->previousPos.azimuth, - (int16_t) ismInput->previousPos.elevation, - previousPanGains, - (int16_t) ambiOrderOut ); + ivas_dirac_dec_get_response( (int16_t) ismInput->previousPos.azimuth, (int16_t) ismInput->previousPos.elevation, previousPanGains, ambiOrderOut ); if ( ( ismInput->currentPos.azimuth == ismInput->previousPos.azimuth ) && ( ismInput->currentPos.elevation == ismInput->previousPos.elevation ) ) @@ -3196,19 +3175,12 @@ static ivas_error renderIsmToSba( } else { - ivas_dirac_dec_get_response( (int16_t) ismInput->currentPos.azimuth, - (int16_t) ismInput->currentPos.elevation, - currentPanGains, - (int16_t) ambiOrderOut ); + ivas_dirac_dec_get_response( (int16_t) ismInput->currentPos.azimuth, (int16_t) ismInput->currentPos.elevation, currentPanGains, ambiOrderOut ); } /* Assume num channels in audio buffer to be 1. * This should have been validated in IVAS_REND_FeedInputAudio() */ - renderBufferChannelLerp( ismInput->base.inputBuffer, - 0, - currentPanGains, - previousPanGains, - outAudio ); + renderBufferChannelLerp( ismInput->base.inputBuffer, 0, currentPanGains, previousPanGains, outAudio ); wmops_sub_end(); @@ -3217,8 +3189,8 @@ static ivas_error renderIsmToSba( static ivas_error renderInputIsm( input_ism *ismInput, - IVAS_REND_AudioConfig outConfig, - IVAS_REND_AudioBuffer outAudio ) + const IVAS_REND_AudioConfig outConfig, + const IVAS_REND_AudioBuffer outAudio ) { ivas_error error; IVAS_REND_AudioBuffer inAudio; @@ -3233,10 +3205,7 @@ static ivas_error renderInputIsm( ismInput->base.numNewSamplesPerChannel = 0; /* Apply input gain to new audio */ - v_multc( inAudio.data, - ismInput->base.gain, - inAudio.data, - inAudio.config.numSamplesPerChannel * inAudio.config.numChannels ); + v_multc( inAudio.data, ismInput->base.gain, inAudio.data, inAudio.config.numSamplesPerChannel * inAudio.config.numChannels ); switch ( getAudioConfigType( outConfig ) ) @@ -3276,7 +3245,7 @@ static ivas_error renderActiveInputsIsm( IVAS_REND_HANDLE hIvasRend, IVAS_REND_AudioBuffer outAudio ) { - int32_t i; + int16_t i; input_ism *pCurrentInput; ivas_error error; @@ -3287,9 +3256,7 @@ static ivas_error renderActiveInputsIsm( /* Skip inactive inputs */ continue; } - if ( ( error = renderInputIsm( pCurrentInput, - hIvasRend->outputConfig, - outAudio ) ) != IVAS_ERR_OK ) + if ( ( error = renderInputIsm( pCurrentInput, hIvasRend->outputConfig, outAudio ) ) != IVAS_ERR_OK ) { return error; } @@ -3309,7 +3276,7 @@ static ivas_error renderLfeToBinaural( assert( ( outAudio.config.numChannels == 2 ) && "Must be binaural output" ); - wmops_sub_start("renderLfeToBinaural"); + wmops_sub_start( "renderLfeToBinaural" ); gain = GAIN_LFE; @@ -3349,7 +3316,7 @@ static ivas_error renderLfeToBinaural( static ivas_error renderMcToBinaural( input_mc *mcInput, - IVAS_REND_AudioConfig outConfig, + const IVAS_REND_AudioConfig outConfig, IVAS_REND_AudioBuffer outAudio ) { int8_t headRotEnabled; @@ -3359,7 +3326,7 @@ static ivas_error renderMcToBinaural( ivas_error error; IVAS_REND_AudioBuffer tmpRotBuffer; - wmops_sub_start("renderMcToBinaural"); + wmops_sub_start( "renderMcToBinaural" ); headRotEnabled = mcInput->base.ctx.pHeadRotData->headRotEnabled; inConfig = mcInput->base.inConfig; @@ -3407,11 +3374,7 @@ static ivas_error renderMcToBinaural( } /* call CREND */ - if ( ( error = ivas_rend_crendProcess( &mcInput->crendWrapper, - mcInput->base.inConfig, - outConfig, - tmpRendBuffer, - *mcInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_rend_crendProcess( &mcInput->crendWrapper, mcInput->base.inConfig, outConfig, tmpRendBuffer, *mcInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) { return error; } @@ -3429,7 +3392,7 @@ static ivas_error renderMcToBinaural( static ivas_error renderMcToBinauralRoom( input_mc *mcInput, - IVAS_REND_AudioConfig outConfig, + const IVAS_REND_AudioConfig outConfig, IVAS_REND_AudioBuffer outAudio ) { float tmpCrendBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; @@ -3437,7 +3400,7 @@ static ivas_error renderMcToBinauralRoom( ivas_error error; IVAS_REND_AudioBuffer tmpRotBuffer; - wmops_sub_start("renderMcToBinauralRoom"); + wmops_sub_start( "renderMcToBinauralRoom" ); /* apply rotation */ if ( mcInput->base.ctx.pHeadRotData->headRotEnabled ) @@ -3463,11 +3426,7 @@ static ivas_error renderMcToBinauralRoom( } /* call CREND */ - if ( ( error = ivas_rend_crendProcess( &mcInput->crendWrapper, - mcInput->base.inConfig, - outConfig, - tmpCrendBuffer, - *mcInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_rend_crendProcess( &mcInput->crendWrapper, mcInput->base.inConfig, outConfig, tmpCrendBuffer, *mcInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) { return error; } @@ -3485,20 +3444,21 @@ static ivas_error renderMcToBinauralRoom( static ivas_error renderMcCustomLsToBinauralRoom( input_mc *mcInput, - IVAS_REND_AudioConfig outConfig, + const IVAS_REND_AudioConfig outConfig, IVAS_REND_AudioBuffer outAudio ) { int8_t headRotEnabled; int16_t i; - int32_t tmp; + int16_t tmp; float tmpCrendBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; - ivas_error error; IVAS_REND_AudioBuffer tmpRotBuffer; IVAS_REND_AudioBuffer tmpMcBuffer; IVAS_REND_AudioBuffer *tmpBufPtr; - wmops_sub_start("renderMcCustomLsToBinauralRoom"); + wmops_sub_start( "renderMcCustomLsToBinauralRoom" ); + + tmpRotBuffer = outAudio; /* avoid compilation warning */ headRotEnabled = mcInput->base.ctx.pHeadRotData->headRotEnabled; @@ -3528,19 +3488,12 @@ static ivas_error renderMcCustomLsToBinauralRoom( tmpBufPtr = ( headRotEnabled ) ? &tmpRotBuffer : &mcInput->base.inputBuffer; for ( i = 0; i < mcInput->base.inputBuffer.config.numChannels; i++ ) { - renderBufferChannel( *tmpBufPtr, - i, - mcInput->panGains[i], - tmpMcBuffer ); + renderBufferChannel( *tmpBufPtr, i, mcInput->panGains[i], tmpMcBuffer ); } copyBufferTo2dArray( tmpMcBuffer, tmpCrendBuffer ); /* call CREND */ - if ( ( error = ivas_rend_crendProcess( &mcInput->crendWrapper, - IVAS_REND_AUDIO_CONFIG_7_1_4, - outConfig, - tmpCrendBuffer, - *mcInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_rend_crendProcess( &mcInput->crendWrapper, IVAS_REND_AUDIO_CONFIG_7_1_4, outConfig, tmpCrendBuffer, *mcInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) { return error; } @@ -3565,10 +3518,10 @@ static ivas_error renderMcToMc( const input_mc *mcInput, IVAS_REND_AudioBuffer outAudio ) { - int32_t i; + int16_t i; IVAS_REND_AudioBuffer inAudio; - wmops_sub_start("renderMcToMc"); + wmops_sub_start( "renderMcToMc" ); inAudio = mcInput->base.inputBuffer; @@ -3586,10 +3539,10 @@ static ivas_error renderMcToSba( const input_mc *mcInput, IVAS_REND_AudioBuffer outAudio ) { - int32_t i; + int16_t i; IVAS_REND_AudioBuffer inAudio; - wmops_sub_start("renderMcToSba"); + wmops_sub_start( "renderMcToSba" ); inAudio = mcInput->base.inputBuffer; @@ -3670,7 +3623,7 @@ static ivas_error renderActiveInputsMc( IVAS_REND_HANDLE hIvasRend, IVAS_REND_AudioBuffer outAudio ) { - int32_t i; + int16_t i; input_mc *pCurrentInput; ivas_error error; @@ -3681,9 +3634,7 @@ static ivas_error renderActiveInputsMc( /* Skip inactive inputs */ continue; } - if ( ( error = renderInputMc( pCurrentInput, - hIvasRend->outputConfig, - outAudio ) ) != IVAS_ERR_OK ) + if ( ( error = renderInputMc( pCurrentInput, hIvasRend->outputConfig, outAudio ) ) != IVAS_ERR_OK ) { return error; } @@ -3696,10 +3647,10 @@ static ivas_error renderSbaToMc( const input_sba *sbaInput, IVAS_REND_AudioBuffer outAudio ) { - int32_t i; + int16_t i; IVAS_REND_AudioBuffer inAudio; - wmops_sub_start("renderSbaToMc"); + wmops_sub_start( "renderSbaToMc" ); inAudio = sbaInput->base.inputBuffer; @@ -3717,10 +3668,10 @@ static ivas_error renderSbaToSba( const input_sba *sbaInput, IVAS_REND_AudioBuffer outAudio ) { - int32_t i; + int16_t i; IVAS_REND_AudioBuffer inAudio; - wmops_sub_start("renderSbaToSba"); + wmops_sub_start( "renderSbaToSba" ); inAudio = sbaInput->base.inputBuffer; @@ -3736,7 +3687,7 @@ static ivas_error renderSbaToSba( static ivas_error renderSbaToBinaural( input_sba *sbaInput, - IVAS_REND_AudioConfig outConfig, + const IVAS_REND_AudioConfig outConfig, IVAS_REND_AudioBuffer outAudio ) { float tmpCrendBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; @@ -3744,7 +3695,7 @@ static ivas_error renderSbaToBinaural( ivas_error error; IVAS_REND_AudioBuffer tmpRotBuffer; - wmops_sub_start("renderSbaToBinaural"); + wmops_sub_start( "renderSbaToBinaural" ); /* apply rotation */ if ( sbaInput->base.ctx.pHeadRotData->headRotEnabled ) @@ -3770,11 +3721,7 @@ static ivas_error renderSbaToBinaural( } /* call CREND */ - if ( ( error = ivas_rend_crendProcess( &sbaInput->crendWrapper, - sbaInput->base.inConfig, - outConfig, - tmpCrendBuffer, - *sbaInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_rend_crendProcess( &sbaInput->crendWrapper, sbaInput->base.inConfig, outConfig, tmpCrendBuffer, *sbaInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) { return error; } @@ -3788,12 +3735,12 @@ static ivas_error renderSbaToBinaural( static ivas_error renderSbaToBinauralRoom( input_sba *sbaInput, - IVAS_REND_AudioConfig outConfig, + const IVAS_REND_AudioConfig outConfig, IVAS_REND_AudioBuffer outAudio ) { int8_t headRotEnabled; int16_t i; - int32_t tmp; + int16_t tmp; float tmpCrendBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; ivas_error error; @@ -3801,7 +3748,9 @@ static ivas_error renderSbaToBinauralRoom( IVAS_REND_AudioBuffer tmpMcBuffer; IVAS_REND_AudioBuffer *tmpBufPtr; - wmops_sub_start("renderSbaToBinauralRoom"); + tmpRotBuffer = outAudio; /* avoid compilation warning */ + + wmops_sub_start( "renderSbaToBinauralRoom" ); headRotEnabled = sbaInput->base.ctx.pHeadRotData->headRotEnabled; @@ -3811,14 +3760,9 @@ static ivas_error renderSbaToBinauralRoom( tmpRotBuffer = sbaInput->base.inputBuffer; tmpRotBuffer.data = count_malloc( tmpRotBuffer.config.numSamplesPerChannel * tmpRotBuffer.config.numChannels * sizeof( float ) ); /* copy input for in-place rotation */ - mvr2r( sbaInput->base.inputBuffer.data, tmpRotBuffer.data, - tmpRotBuffer.config.numChannels * tmpRotBuffer.config.numSamplesPerChannel ); + mvr2r( sbaInput->base.inputBuffer.data, tmpRotBuffer.data, tmpRotBuffer.config.numChannels * tmpRotBuffer.config.numSamplesPerChannel ); - rotateFrameSba( sbaInput->base.inputBuffer, - sbaInput->base.inConfig, - sbaInput->base.ctx.pHeadRotData, - sbaInput->rot_gains_prev, - tmpRotBuffer ); + rotateFrameSba( sbaInput->base.inputBuffer, sbaInput->base.inConfig, sbaInput->base.ctx.pHeadRotData, sbaInput->rot_gains_prev, tmpRotBuffer ); } /* intermediate rendering to 7_1_4 */ @@ -3826,26 +3770,18 @@ static ivas_error renderSbaToBinauralRoom( getAudioConfigNumChannels( IVAS_REND_AUDIO_CONFIG_7_1_4, &tmp ); tmpMcBuffer.config.numChannels = (int16_t) tmp; tmpMcBuffer.data = count_malloc( tmpMcBuffer.config.numSamplesPerChannel * tmpMcBuffer.config.numChannels * sizeof( float ) ); - set_zero( tmpMcBuffer.data, - tmpMcBuffer.config.numChannels * tmpMcBuffer.config.numSamplesPerChannel ); + set_zero( tmpMcBuffer.data, tmpMcBuffer.config.numChannels * tmpMcBuffer.config.numSamplesPerChannel ); tmpBufPtr = ( headRotEnabled ) ? &tmpRotBuffer : &sbaInput->base.inputBuffer; for ( i = 0; i < sbaInput->base.inputBuffer.config.numChannels; i++ ) { - renderBufferChannel( *tmpBufPtr, - i, - sbaInput->hoaDecMtx[i], - tmpMcBuffer ); + renderBufferChannel( *tmpBufPtr, i, sbaInput->hoaDecMtx[i], tmpMcBuffer ); } copyBufferTo2dArray( tmpMcBuffer, tmpCrendBuffer ); /* call CREND */ - if ( ( error = ivas_rend_crendProcess( &sbaInput->crendWrapper, - IVAS_REND_AUDIO_CONFIG_7_1_4, - outConfig, - tmpCrendBuffer, - *sbaInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_rend_crendProcess( &sbaInput->crendWrapper, IVAS_REND_AUDIO_CONFIG_7_1_4, outConfig, tmpCrendBuffer, *sbaInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) { return error; } @@ -3865,7 +3801,7 @@ static ivas_error renderSbaToBinauralRoom( static ivas_error renderInputSba( input_sba *sbaInput, - IVAS_REND_AudioConfig outConfig, + const IVAS_REND_AudioConfig outConfig, IVAS_REND_AudioBuffer outAudio ) { ivas_error error; @@ -3923,7 +3859,7 @@ static ivas_error renderActiveInputsSba( IVAS_REND_HANDLE hIvasRend, IVAS_REND_AudioBuffer outAudio ) { - int32_t i; + int16_t i; input_sba *pCurrentInput; ivas_error error; @@ -3934,9 +3870,8 @@ static ivas_error renderActiveInputsSba( /* Skip inactive inputs */ continue; } - if ( ( error = renderInputSba( pCurrentInput, - hIvasRend->outputConfig, - outAudio ) ) != IVAS_ERR_OK ) + + if ( ( error = renderInputSba( pCurrentInput, hIvasRend->outputConfig, outAudio ) ) != IVAS_ERR_OK ) { return error; } @@ -3950,7 +3885,7 @@ ivas_error IVAS_REND_GetSamples( IVAS_REND_AudioBuffer outAudio ) { ivas_error error; - int32_t numOutChannels; + int16_t numOutChannels; /*-----------------------------------------------------------------* * Validate function arguments @@ -4007,9 +3942,10 @@ ivas_error IVAS_REND_GetSamples( return IVAS_ERR_OK; } -void IVAS_REND_Close( IVAS_REND_HANDLE *phIvasRend ) +void IVAS_REND_Close( + IVAS_REND_HANDLE *phIvasRend ) { - uint32_t i; + uint16_t i; IVAS_REND_HANDLE hIvasRend; /*-----------------------------------------------------------------* @@ -4045,6 +3981,8 @@ void IVAS_REND_Close( IVAS_REND_HANDLE *phIvasRend ) count_free( hIvasRend ); *phIvasRend = NULL; + + return; } #ifdef DEBUGGING diff --git a/lib_rend/lib_rend.h b/lib_rend/lib_rend.h index b9aad11e84..ef37770bf0 100644 --- a/lib_rend/lib_rend.h +++ b/lib_rend/lib_rend.h @@ -132,11 +132,11 @@ typedef enum IVAS_REND_AUDIO_CONFIG_UNKNOWN = IVAS_REND_AUDIO_CONFIG_TYPE_UNKNOWN << 8 | 0, } IVAS_REND_AudioConfig; -typedef uint32_t IVAS_REND_InputId; +typedef uint16_t IVAS_REND_InputId; typedef struct { - int32_t numLfeChannels; + int16_t numLfeChannels; float lfeOutputGains[IVAS_MAX_INPUT_LFE_CHANNELS][IVAS_MAX_OUTPUT_CHANNELS]; } IVAS_REND_LfeRouting; @@ -149,14 +149,14 @@ typedef struct ivas_error IVAS_REND_Open( IVAS_REND_HANDLE *phIvasRend, /* i/o: Pointer to renderer handle */ - int32_t outputSampleRate, /* i : output sampling rate */ - IVAS_REND_AudioConfig outConfig /* i : output audio config */ + const int32_t outputSampleRate, /* i : output sampling rate */ + const IVAS_REND_AudioConfig outConfig /* i : output audio config */ ); /* Note: this will reset custom LFE routings set for any MC input */ ivas_error IVAS_REND_ConfigureCustomOutputLoudspeakerLayout( IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ - IVAS_CUSTOM_LS_DATA layout /* i : custom loudspeaker layout for renderer output */ + const IVAS_CUSTOM_LS_DATA layout /* i : custom loudspeaker layout for renderer output */ ); /* Support for custom HRTFs will be added in the future. */ @@ -170,43 +170,43 @@ ivas_error IVAS_REND_SetCustomHrtf( ivas_error IVAS_REND_NumOutChannels( IVAS_REND_CONST_HANDLE hIvasRend, /* i : Renderer handle */ - int32_t *numOutChannels /* o : number of output channels */ + int16_t *numOutChannels /* o : number of output channels */ ); ivas_error IVAS_REND_AddInput( IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ - IVAS_REND_AudioConfig inConfig, /* i : audio config for a new input */ + const IVAS_REND_AudioConfig inConfig, /* i : audio config for a new input */ IVAS_REND_InputId *inputId /* o : ID of the new input */ ); /* Note: this will reset any custom LFE routing set for the input */ ivas_error IVAS_REND_ConfigureCustomInputLoudspeakerLayout( IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ - IVAS_REND_InputId inputId, /* i : ID of the input */ - IVAS_CUSTOM_LS_DATA layout /* i : custom loudspeaker layout for input */ + const IVAS_REND_InputId inputId, /* i : ID of the input */ + const IVAS_CUSTOM_LS_DATA layout /* i : custom loudspeaker layout for input */ ); ivas_error IVAS_REND_SetInputGain( IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ - IVAS_REND_InputId inputId, /* i : ID of the input */ - float gain /* i : linear gain (not in dB) */ + const IVAS_REND_InputId inputId, /* i : ID of the input */ + const float gain /* i : linear gain (not in dB) */ ); ivas_error IVAS_REND_SetInputLfeRouting( IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ - IVAS_REND_InputId inputId, /* i : ID of the input */ - IVAS_REND_LfeRouting lfeRouting /* i : custom LFE routing struct */ + const IVAS_REND_InputId inputId, /* i : ID of the input */ + const IVAS_REND_LfeRouting lfeRouting /* i : custom LFE routing struct */ ); ivas_error IVAS_REND_RemoveInput( IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ - IVAS_REND_InputId inputId /* i : ID of the input */ + const IVAS_REND_InputId inputId /* i : ID of the input */ ); ivas_error IVAS_REND_GetInputNumChannels( IVAS_REND_CONST_HANDLE hIvasRend, /* i : Renderer handle */ - IVAS_REND_InputId inputId, /* i : ID of the input */ - int32_t *numChannels /* o : number of channels of the input */ + const IVAS_REND_InputId inputId, /* i : ID of the input */ + int16_t *numChannels /* o : number of channels of the input */ ); ivas_error IVAS_REND_GetDelay( @@ -219,20 +219,20 @@ ivas_error IVAS_REND_GetDelay( ivas_error IVAS_REND_FeedInputAudio( IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ - IVAS_REND_InputId inputId, /* i : ID of the input */ - IVAS_REND_ReadOnlyAudioBuffer inputAudio /* i : buffer with input audio */ + const IVAS_REND_InputId inputId, /* i : ID of the input */ + const IVAS_REND_ReadOnlyAudioBuffer inputAudio /* i : buffer with input audio */ ); ivas_error IVAS_REND_FeedInputObjectMetadata( IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ - IVAS_REND_InputId inputId, /* i : ID of the input */ - IVAS_REND_AudioObjectPosition objectPosition /* i : object position struct */ + const IVAS_REND_InputId inputId, /* i : ID of the input */ + const IVAS_REND_AudioObjectPosition objectPosition /* i : object position struct */ ); /* Support for MASA input will be added in the future. */ ivas_error IVAS_REND_FeedInputMasaMetadata( IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ - IVAS_REND_InputId inputId, /* i : ID of the input */ + const IVAS_REND_InputId inputId, /* i : ID of the input */ void* TODO ); -- GitLab From 94753c436b22d9700411708ff670dab0c8032330 Mon Sep 17 00:00:00 2001 From: Archit Tamarapu Date: Mon, 7 Nov 2022 15:17:02 +0100 Subject: [PATCH 081/101] small tweak to instrumentation printout + add junit reports to CI --- .gitlab-ci.yml | 8 ++++---- apps/renderer.c | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 4b2fafe1f8..e0bb40e805 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -316,7 +316,7 @@ external-renderer-make-pytest: - make -j IVAS_rend - make -j unittests - make -j --directory scripts/td_object_renderer/object_renderer_standalone - - python3 -m pytest -q --log-level ERROR -n auto -rA tests/renderer/test_renderer.py + - python3 -m pytest -q --log-level ERROR -n auto -rA --junit-xml=report-junit.xml tests/renderer/test_renderer.py # test external renderer executable with cmake + asan external-renderer-cmake-asan-pytest: @@ -329,7 +329,7 @@ external-renderer-cmake-asan-pytest: - python3 ci/disable_ram_counting.py - cmake -B cmake-build -G "Unix Makefiles" -DCLANG=asan -DCOPY_EXECUTABLES_FROM_BUILD_DIR=true - cmake --build cmake-build -- -j - - python3 -m pytest -q --log-level ERROR -n auto -rA tests/renderer/test_renderer.py + - python3 -m pytest -q --log-level ERROR -n auto -rA --junit-xml=report-junit.xml tests/renderer/test_renderer.py # test external renderer executable with cmake + msan external-renderer-cmake-msan-pytest: @@ -342,7 +342,7 @@ external-renderer-cmake-msan-pytest: - python3 ci/disable_ram_counting.py - cmake -B cmake-build -G "Unix Makefiles" -DCLANG=msan -DCOPY_EXECUTABLES_FROM_BUILD_DIR=true - cmake --build cmake-build -- -j - - python3 -m pytest -q --log-level ERROR -n auto -rA tests/renderer/test_renderer.py + - python3 -m pytest -q --log-level ERROR -n auto -rA --junit-xml=report-junit.xml tests/renderer/test_renderer.py # test external renderer executable with cmake vs decoder renderer external-renderer-cmake-vs-decoder-pytest: @@ -354,7 +354,7 @@ external-renderer-cmake-vs-decoder-pytest: script: - cmake -B cmake-build -G "Unix Makefiles" -DCOPY_EXECUTABLES_FROM_BUILD_DIR=true -DDEC_TO_REND_FLOAT_DUMP=true - cmake --build cmake-build -- -j - - python3 -m pytest -q --log-level ERROR -n 1 -rA tests/renderer/test_renderer_vs_decoder.py + - python3 -m pytest -q --log-level ERROR -n 1 -rA --junit-xml=report-junit.xml tests/renderer/test_renderer_vs_decoder.py # compare bit exactness between target and source branch ivas-pytest-on-merge-request: diff --git a/apps/renderer.c b/apps/renderer.c index 7c3cc55ea6..f29eab5b7a 100644 --- a/apps/renderer.c +++ b/apps/renderer.c @@ -109,7 +109,7 @@ extern char location_max_stack[256]; *------------------------------------------------------------------------------------------*/ static void print_mem_renderer( size_t SRAM_size ) { - fprintf( stdout, "\n\n --- Renderer cmdln demo memory usage --- \n\n" ); + fprintf( stdout, "\n\n --- Renderer memory usage --- \n\n" ); fprintf( stdout, "PROM size (renderer): %d words (or instructions)\n", PROM_Size_lib_rend ); fprintf( stdout, "Stack size: %d words in %s() in frame #%d\n", ( ptr_base_stack - ptr_max_stack ) * sizeof( int16_t ) / sizeof( float ), location_max_stack, wc_frame ); -- GitLab From 0057307ddcde6dde98aa3742c103e37be8ba4c87 Mon Sep 17 00:00:00 2001 From: Archit Tamarapu Date: Mon, 7 Nov 2022 15:31:06 +0100 Subject: [PATCH 082/101] ci updates --- .gitlab-ci.yml | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index e0bb40e805..a74510491a 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -317,6 +317,15 @@ external-renderer-make-pytest: - make -j unittests - make -j --directory scripts/td_object_renderer/object_renderer_standalone - python3 -m pytest -q --log-level ERROR -n auto -rA --junit-xml=report-junit.xml tests/renderer/test_renderer.py + artifacts: + name: "mr-$CI_MERGE_REQUEST_IID--sha-$CI_COMMIT_SHORT_SHA--job-$CI_JOB_NAME--results" + when: always + paths: + - report-junit.xml + expose_as: "external renderer make pytest results" + reports: + junit: + - report-junit.xml # test external renderer executable with cmake + asan external-renderer-cmake-asan-pytest: @@ -330,6 +339,15 @@ external-renderer-cmake-asan-pytest: - cmake -B cmake-build -G "Unix Makefiles" -DCLANG=asan -DCOPY_EXECUTABLES_FROM_BUILD_DIR=true - cmake --build cmake-build -- -j - python3 -m pytest -q --log-level ERROR -n auto -rA --junit-xml=report-junit.xml tests/renderer/test_renderer.py + artifacts: + name: "mr-$CI_MERGE_REQUEST_IID--sha-$CI_COMMIT_SHORT_SHA--job-$CI_JOB_NAME--results" + when: always + paths: + - report-junit.xml + expose_as: "external renderer cmake asan pytest results" + reports: + junit: + - report-junit.xml # test external renderer executable with cmake + msan external-renderer-cmake-msan-pytest: @@ -343,6 +361,15 @@ external-renderer-cmake-msan-pytest: - cmake -B cmake-build -G "Unix Makefiles" -DCLANG=msan -DCOPY_EXECUTABLES_FROM_BUILD_DIR=true - cmake --build cmake-build -- -j - python3 -m pytest -q --log-level ERROR -n auto -rA --junit-xml=report-junit.xml tests/renderer/test_renderer.py + artifacts: + name: "mr-$CI_MERGE_REQUEST_IID--sha-$CI_COMMIT_SHORT_SHA--job-$CI_JOB_NAME--results" + when: always + paths: + - report-junit.xml + expose_as: "external renderer cmake msan pytest results" + reports: + junit: + - report-junit.xml # test external renderer executable with cmake vs decoder renderer external-renderer-cmake-vs-decoder-pytest: @@ -355,6 +382,15 @@ external-renderer-cmake-vs-decoder-pytest: - cmake -B cmake-build -G "Unix Makefiles" -DCOPY_EXECUTABLES_FROM_BUILD_DIR=true -DDEC_TO_REND_FLOAT_DUMP=true - cmake --build cmake-build -- -j - python3 -m pytest -q --log-level ERROR -n 1 -rA --junit-xml=report-junit.xml tests/renderer/test_renderer_vs_decoder.py + artifacts: + name: "mr-$CI_MERGE_REQUEST_IID--sha-$CI_COMMIT_SHORT_SHA--job-$CI_JOB_NAME--results" + when: always + paths: + - report-junit.xml + expose_as: "external renderer cmake vs decoder results" + reports: + junit: + - report-junit.xml # compare bit exactness between target and source branch ivas-pytest-on-merge-request: -- GitLab From 2ebf0e7b99819fe947b0ef38d07cf2efee79b439 Mon Sep 17 00:00:00 2001 From: Remco Stoutjesdijk Date: Tue, 8 Nov 2022 00:03:30 +0100 Subject: [PATCH 083/101] fix 21 renderer test fails --- apps/renderer.c | 2 +- lib_rend/lib_rend.c | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/apps/renderer.c b/apps/renderer.c index 05de0db262..7cae5dd044 100644 --- a/apps/renderer.c +++ b/apps/renderer.c @@ -665,7 +665,7 @@ int32_t main( int32_t argc, char **argv ) } /* === Configure === */ - if ( ( error = IVAS_REND_InitConfig( hIvasRend, headRotReader != NULL, args.renderConfigFilePath[0] != '\0' ) ) != IVAS_ERR_OK ) + if ( ( error = IVAS_REND_InitConfig( hIvasRend, headRotReader != NULL, strlen(args.renderConfigFilePath) != 0 ) ) != IVAS_ERR_OK ) { exit( -1 ); } diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index aa3fb2599f..9366003b08 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -2650,11 +2650,19 @@ ivas_error IVAS_REND_InitConfig( IVAS_REND_HANDLE st, { st->enableHeadRotation = 1; } + else + { + st->enableHeadRotation = 0; + } if ( rendererConfigEnabled ) { st->rendererConfigEnabled = 1; } + else + { + st->rendererConfigEnabled = 0; + } if ( ( error = ivas_render_config_open( &( st->hRendererConfig ) ) ) != IVAS_ERR_OK ) { -- GitLab From 034ca33e5ac406f2c8b8c637fbb49aab17a258d9 Mon Sep 17 00:00:00 2001 From: Remco Stoutjesdijk Date: Tue, 8 Nov 2022 14:46:20 +0100 Subject: [PATCH 084/101] merge with FhG/external-renderer --- apps/encoder.c | 34 +- apps/renderer.c | 365 +++++---- ci/run_scheduled_sanitizer_test.py | 7 +- ci/smoke_test.sh | 7 +- lib_com/cnst.h | 3 + lib_com/fill_spectrum.c | 8 - lib_com/ivas_cnst.h | 12 +- lib_com/ivas_cov_smooth.c | 41 +- lib_com/ivas_error.h | 3 + lib_com/ivas_prot.h | 75 +- lib_com/ivas_rom_com.c | 32 +- lib_com/ivas_sba_config.c | 34 +- lib_com/ivas_spar_com.c | 31 +- lib_com/ivas_stat_com.h | 10 - lib_com/ivas_stereo_psychlpc_com.c | 16 +- lib_com/options.h | 23 +- lib_com/vlpc_2st_com.c | 3 +- lib_debug/mem_count.c | 5 +- lib_dec/dec_tcx.c | 16 +- lib_dec/igf_dec.c | 7 +- lib_dec/init_dec.c | 7 +- lib_dec/ivas_agc_dec.c | 15 + lib_dec/ivas_core_dec.c | 24 +- lib_dec/ivas_corecoder_dec_reconfig.c | 4 - lib_dec/ivas_dirac_dec.c | 6 +- lib_dec/ivas_dirac_dec_binaural_functions.c | 4 +- lib_dec/ivas_init_dec.c | 31 +- lib_dec/ivas_ism_param_dec.c | 94 --- lib_dec/ivas_ism_renderer.c | 2 +- lib_dec/ivas_mct_dec_mct.c | 4 - lib_dec/ivas_mdct_core_dec.c | 6 - lib_dec/ivas_mono_dmx_renderer.c | 2 +- lib_dec/ivas_out_setup_conversion.c | 2 +- lib_dec/ivas_post_proc.c | 4 + lib_dec/ivas_rom_dec.c | 2 +- lib_dec/ivas_sba_dec.c | 779 ++++++++++++-------- lib_dec/ivas_spar_decoder.c | 39 +- lib_dec/ivas_spar_md_dec.c | 429 +++++------ lib_dec/ivas_stat_dec.h | 21 +- lib_dec/ivas_stereo_mdct_core_dec.c | 4 - lib_dec/ivas_stereo_mdct_stereo_dec.c | 12 - lib_dec/ivas_tcx_core_dec.c | 70 ++ lib_dec/ivas_vbap.c | 2 +- lib_dec/lib_dec.c | 2 +- lib_enc/igf_enc.c | 6 +- lib_enc/init_enc.c | 7 +- lib_enc/ivas_agc_enc.c | 52 +- lib_enc/ivas_core_enc.c | 18 +- lib_enc/ivas_core_pre_proc.c | 12 +- lib_enc/ivas_core_pre_proc_front.c | 2 +- lib_enc/ivas_corecoder_enc_reconfig.c | 2 - lib_enc/ivas_cpe_enc.c | 4 - lib_enc/ivas_dirac_enc.c | 38 +- lib_enc/ivas_enc.c | 22 +- lib_enc/ivas_enc_cov_handler.c | 71 +- lib_enc/ivas_entropy_coder.c | 15 - lib_enc/ivas_front_vad.c | 4 + lib_enc/ivas_init_enc.c | 2 - lib_enc/ivas_ism_enc.c | 4 - lib_enc/ivas_ism_param_enc.c | 212 ------ lib_enc/ivas_mcmasa_enc.c | 8 +- lib_enc/ivas_mct_core_enc.c | 2 - lib_enc/ivas_sba_enc.c | 497 ++++++------- lib_enc/ivas_sce_enc.c | 12 - lib_enc/ivas_sns_enc.c | 1 - lib_enc/ivas_spar_encoder.c | 266 +------ lib_enc/ivas_spar_md_enc.c | 132 +--- lib_enc/ivas_stat_enc.h | 35 +- lib_enc/lib_enc.c | 100 ++- lib_enc/lib_enc.h | 8 +- lib_rend/ivas_allrad_dec.c | 4 - lib_rend/ivas_crend.c | 40 +- lib_rend/ivas_efap.c | 22 - lib_rend/ivas_lib_rend_internal.h | 38 +- lib_rend/ivas_limiter.c | 2 +- lib_rend/ivas_objectRenderer.c | 29 +- lib_rend/ivas_output_init.c | 14 +- lib_rend/lib_rend.c | 684 ++++++++--------- lib_rend/lib_rend.h | 42 +- 79 files changed, 2045 insertions(+), 2659 deletions(-) diff --git a/apps/encoder.c b/apps/encoder.c index c039cba91b..836775b342 100644 --- a/apps/encoder.c +++ b/apps/encoder.c @@ -120,11 +120,13 @@ typedef struct const char *ca_config_file; bool mimeOutput; +#ifdef DEBUG_AGC_ENCODER_CMD_OPTION #ifdef AGC_ENABLE_FOR_LBR IVAS_ENC_AGC agc; #else bool agc; -#endif +#endif /* AGC_ENABLE_FOR_LBR */ +#endif /* DEBUG_AGC_ENCODER_CMD_OPTION */ bool pca; #ifdef DEBUG_FOA_AGC FILE *agcBitstream; /* temporary */ @@ -450,11 +452,25 @@ int main( } break; case IVAS_ENC_INPUT_SBA: + if ( ( error = + IVAS_ENC_ConfigureForAmbisonics( + hIvasEnc, + arg.inputFs, + totalBitrate, + arg.max_bwidth_user, + bandwidth, + arg.dtxConfig, + arg.inputFormatConfig.sba.order, + arg.inputFormatConfig.sba.isPlanar, +#ifdef DEBUG_AGC_ENCODER_CMD_OPTION + arg.agc, +#endif + arg.pca #ifdef DEBUG_SBA_AUDIO_DUMP - if ( ( error = IVAS_ENC_ConfigureForAmbisonics( hIvasEnc, arg.inputFs, totalBitrate, arg.max_bwidth_user, bandwidth, arg.dtxConfig, arg.inputFormatConfig.sba.order, arg.inputFormatConfig.sba.isPlanar, arg.agc, arg.pca, &numTransportChannels ) ) != IVAS_ERR_OK ) -#else - if ( ( error = IVAS_ENC_ConfigureForAmbisonics( hIvasEnc, arg.inputFs, totalBitrate, arg.max_bwidth_user, bandwidth, arg.dtxConfig, arg.inputFormatConfig.sba.order, arg.inputFormatConfig.sba.isPlanar, arg.agc, arg.pca ) ) != IVAS_ERR_OK ) + , + &numTransportChannels #endif + ) ) != IVAS_ERR_OK ) { fprintf( stderr, "\nIVAS_ENC_ConfigureForAmbisonics failed: %s\n\n", IVAS_ENC_GetErrorMessage( error ) ); goto cleanup; @@ -880,11 +896,13 @@ static void initArgStruct( EncArguments *arg ) arg->ca_config_file = NULL; arg->mimeOutput = false; +#ifdef DEBUG_AGC_ENCODER_CMD_OPTION #ifdef AGC_ENABLE_FOR_LBR arg->agc = IVAS_ENC_AGC_UNDEFINED; #else arg->agc = IVAS_DEFAULT_AGC; -#endif +#endif /* AGC_ENABLE_FOR_LBR */ +#endif /* DEBUG_AGC_ENCODER_CMD_OPTION */ arg->pca = false; #ifdef DEBUG_FOA_AGC arg->agcBitstream = NULL; @@ -1390,6 +1408,7 @@ static bool parseCmdlIVAS_enc( arg->inputFormatConfig.stereoToMonoDownmix = true; i++; } +#ifdef DEBUG_AGC_ENCODER_CMD_OPTION else if ( strcmp( argv_to_upper, "-AGC" ) == 0 ) { i++; @@ -1415,6 +1434,7 @@ static bool parseCmdlIVAS_enc( return false; } } +#endif else if ( strcmp( argv_to_upper, "-BYPASS" ) == 0 ) // VE: should be renamed to "-pca" { i++; @@ -1654,13 +1674,15 @@ static void usage_enc( void ) #ifdef DEBUG_SBA fprintf( stdout, "-tag : Tag name for intermediate debug files\n" ); #endif +#ifdef DEBUG_AGC_ENCODER_CMD_OPTION #ifdef AGC_ENABLE_FOR_LBR fprintf( stdout, "-agc op : SBA Adaptive gain control, op = (0, 1). \n" ); fprintf( stdout, " By default op is 1 (activated) for bitrates between 24400 and 32000,\n" ); fprintf( stdout, " otherwise it is 0 (deactivated) for all other bitrates\n" ); #else fprintf( stdout, "-agc op : SBA Adaptive gain control, op = (0, 1), by default op is 0 or deactivated\n" ); -#endif +#endif /* AGC_ENABLE_FOR_LBR */ +#endif /* DEBUG_AGC_ENCODER_CMD_OPTION */ fprintf( stdout, "-bypass mode : SBA PCA by-pass, mode = (1, 2), 1 = PCA off, 2 = signal adaptive, default is 1\n" ); #ifdef DEBUGGING diff --git a/apps/renderer.c b/apps/renderer.c index 7cae5dd044..c7c1b8cf8f 100644 --- a/apps/renderer.c +++ b/apps/renderer.c @@ -41,10 +41,10 @@ #include "hrtf_file_reader.h" #include "ism_file_reader.h" #include "lib_rend.h" -#include "render_config_reader.h" #include "ls_custom_file_reader.h" #include "masa_file_reader.h" #include "prot.h" +#include "render_config_reader.h" #ifdef WMOPS #include "PROM_Size_lib_rend.h" #include "wmops.h" @@ -104,29 +104,27 @@ extern int16_t *ptr_max_stack; extern int32_t wc_frame; extern char location_max_stack[256]; -/* clang-format off */ /*------------------------------------------------------------------------------------------* -* Function to print complexity & memory estimates -*------------------------------------------------------------------------------------------*/ -static void print_mem_renderer(size_t SRAM_size) + * Function to print complexity & memory estimates + *------------------------------------------------------------------------------------------*/ +static void print_mem_renderer( size_t SRAM_size ) { - fprintf( stdout, "\n\n --- Renderer cmdln demo memory usage --- \n\n" ); + fprintf( stdout, "\n\n --- Renderer memory usage --- \n\n" ); - fprintf( stdout, "PROM size (renderer): %d words (or instructions)\n", PROM_Size_lib_rend ); - fprintf( stdout, "Stack size: %d words in %s() in frame #%d\n", ( ptr_base_stack - ptr_max_stack ) * sizeof( int16_t ) / sizeof( float ), location_max_stack, wc_frame ); - fprintf( stdout, "Table ROM size(renderer): %d words\n", (Const_Data_Size_ivas_rom_rend() ) / sizeof( float ) ); - fprintf( stdout, "Table ROM size (binaural renderer): %ld words\n", ( Const_Data_Size_ivas_rom_binauralRen() + Const_Data_Size_ivas_rom_TdBinauralR() + Const_Data_Size_ivas_rom_binaural_cr() ) / sizeof( float ) ); + fprintf( stdout, "PROM size (renderer): %d words (or instructions)\n", PROM_Size_lib_rend ); + fprintf( stdout, "Stack size: %d words in %s() in frame #%d\n", ( ptr_base_stack - ptr_max_stack ) * sizeof( int16_t ) / sizeof( float ), location_max_stack, wc_frame ); + fprintf( stdout, "Table ROM size(renderer): %d words\n", ( Const_Data_Size_ivas_rom_rend() ) / sizeof( float ) ); + fprintf( stdout, "Table ROM size (binaural renderer): %ld words\n", ( Const_Data_Size_ivas_rom_binauralRen() + Const_Data_Size_ivas_rom_TdBinauralR() + Const_Data_Size_ivas_rom_binaural_cr() ) / sizeof( float ) ); #ifdef RAM_COUNTING_TOOL - fprintf( stdout, "Static RAM size: %d words\n\n", SRAM_size ); + fprintf( stdout, "Static RAM size: %d words\n\n", SRAM_size ); #endif - print_stack_call_tree(); + print_stack_call_tree(); - fprintf( stdout, "Note: this is an optimistic estimate of the memory consumption assuming\n" ); - fprintf( stdout, " that each variable (short, long or float) in the codec requires\n" ); - fprintf( stdout, " 32 bits of memory and may therefore be represented by 1 word.\n" ); - fprintf( stdout, " The following formula is used: sizeof('memory array')/sizeof(float)\n\n" ); + fprintf( stdout, "Note: this is an optimistic estimate of the memory consumption assuming\n" ); + fprintf( stdout, " that each variable (short, long or float) in the codec requires\n" ); + fprintf( stdout, " 32 bits of memory and may therefore be represented by 1 word.\n" ); + fprintf( stdout, " The following formula is used: sizeof('memory array')/sizeof(float)\n\n" ); } -/* clang-format on */ #endif typedef struct @@ -182,7 +180,7 @@ typedef struct InputConfig inConfig; OutputConfig outConfig; char inMetadataFilePaths[RENDERER_MAX_ISM_INPUTS][RENDERER_MAX_CLI_ARG_LENGTH]; - int32_t numInMetadataFiles; + int16_t numInMetadataFiles; char headRotationFilePath[RENDERER_MAX_CLI_ARG_LENGTH]; char customHrtfFilePath[RENDERER_MAX_CLI_ARG_LENGTH]; char renderConfigFilePath[RENDERER_MAX_CLI_ARG_LENGTH]; @@ -318,7 +316,7 @@ static const CmdLnParser_Option cliOptions[] = { static const int32_t numCliOptions = sizeof( cliOptions ) / sizeof( CmdLnParser_Option ); static IVAS_REND_AudioConfig ambisonicsOrderToEnum( - int32_t order ); + const int16_t order ); static void parseSceneDescriptionFile( char *path, @@ -332,7 +330,7 @@ static ivas_error parseCustomLayoutFile( IVAS_CUSTOM_LS_DATA *pLsSetupCustom ); static CmdlnArgs parseCmdlnArgs( - int32_t argc, + const int argc, char **argv ); static IsmPositionProvider *IsmPositionProvider_open( @@ -348,12 +346,12 @@ static void IsmPositionProvider_close( static void readFromShorthandMetadata( IsmPositionProvider *positionProvider, ObjectPositionBuffer *objectMetadataBuffer, - uint32_t objIdx ); + const uint32_t objIdx ); void getMetadataFromFileReader( IsmFileReader *ismReader, ObjectPositionBuffer *objectMetadataBuffer, - uint32_t objIdx ); + const uint32_t objIdx ); static void splitConfigFile( const char *mdfFilePath, @@ -394,11 +392,9 @@ static void parseMetadata( IsmPositionProvider *positionProvider, MasaFileReader **masaReaders ); -static void convert_backslash( - char *str ); +static void convert_backslash( char *str ); -static void remove_cr( - char *str ); +static void remove_cr( char *str ); static void clearString( char *str ); @@ -408,37 +404,33 @@ static void printSupportedAudioConfigs( void ); static IVAS_REND_AudioConfig parseAudioConfig( const char *configString ); -static void convertInputBuffer( const int16_t *intBuffer, - int32_t numIntSamplesPerChannel, /* Number of samples per channel in the int buffer */ - int32_t numFloatSamplesPerChannel, /* Per-channel length of the float buffer. If > numIntSamplesPerChannel, remaining samples will be set to 0. */ - int32_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 ); -static void convertOutputBuffer( const float *floatBuffer, - int32_t numSamplesPerChannel, - int32_t numChannels, - int16_t *intBuffer ); +static void convertOutputBuffer( const float *floatBuffer, const int16_t numSamplesPerChannel, const int16_t numChannels, int16_t *intBuffer ); -static IVAS_REND_ReadOnlyAudioBuffer getReadOnlySubBuffer( IVAS_REND_AudioBuffer buffer, int32_t chBeginIdx, int32_t numChannels ) + +static IVAS_REND_ReadOnlyAudioBuffer getReadOnlySubBuffer( IVAS_REND_AudioBuffer buffer, const int16_t chBeginIdx, const int16_t numChannels ) { IVAS_REND_ReadOnlyAudioBuffer subBuffer; subBuffer.config = buffer.config; - subBuffer.config.numChannels = (int16_t) numChannels; + subBuffer.config.numChannels = numChannels; subBuffer.data = buffer.data + subBuffer.config.numSamplesPerChannel * chBeginIdx; return subBuffer; } -static int32_t getTotalNumInChannels( IVAS_REND_HANDLE hIvasRend, - IVAS_REND_InputId mcIds[RENDERER_MAX_MC_INPUTS], - IVAS_REND_InputId ismIds[RENDERER_MAX_ISM_INPUTS], - IVAS_REND_InputId sbaIds[RENDERER_MAX_SBA_INPUTS] ) +static int16_t getTotalNumInChannels( + IVAS_REND_HANDLE hIvasRend, + IVAS_REND_InputId mcIds[RENDERER_MAX_MC_INPUTS], + IVAS_REND_InputId ismIds[RENDERER_MAX_ISM_INPUTS], + IVAS_REND_InputId sbaIds[RENDERER_MAX_SBA_INPUTS] ) { - int32_t totalNumInChannels = 0; + int16_t totalNumInChannels = 0; + int16_t i, numInputChannels; ivas_error error; - for ( int32_t i = 0; i < RENDERER_MAX_MC_INPUTS; ++i ) + for ( i = 0; i < RENDERER_MAX_MC_INPUTS; ++i ) { if ( mcIds[i] == 0 ) { @@ -446,7 +438,6 @@ static int32_t getTotalNumInChannels( IVAS_REND_HANDLE hIvasRend, continue; } - int32_t numInputChannels; if ( ( error = IVAS_REND_GetInputNumChannels( hIvasRend, mcIds[i], &numInputChannels ) ) != IVAS_ERR_OK ) { fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); @@ -455,7 +446,7 @@ static int32_t getTotalNumInChannels( IVAS_REND_HANDLE hIvasRend, totalNumInChannels += numInputChannels; } - for ( int32_t i = 0; i < RENDERER_MAX_ISM_INPUTS; ++i ) + for ( i = 0; i < RENDERER_MAX_ISM_INPUTS; ++i ) { if ( ismIds[i] == 0 ) { @@ -463,7 +454,6 @@ static int32_t getTotalNumInChannels( IVAS_REND_HANDLE hIvasRend, continue; } - int32_t numInputChannels; if ( ( error = IVAS_REND_GetInputNumChannels( hIvasRend, ismIds[i], &numInputChannels ) ) != IVAS_ERR_OK ) { fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); @@ -472,7 +462,7 @@ static int32_t getTotalNumInChannels( IVAS_REND_HANDLE hIvasRend, totalNumInChannels += numInputChannels; } - for ( int32_t i = 0; i < RENDERER_MAX_SBA_INPUTS; ++i ) + for ( i = 0; i < RENDERER_MAX_SBA_INPUTS; ++i ) { if ( sbaIds[i] == 0 ) { @@ -480,7 +470,7 @@ static int32_t getTotalNumInChannels( IVAS_REND_HANDLE hIvasRend, continue; } - int32_t numInputChannels; + if ( ( error = IVAS_REND_GetInputNumChannels( hIvasRend, sbaIds[i], &numInputChannels ) ) != IVAS_ERR_OK ) { fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); @@ -492,7 +482,11 @@ static int32_t getTotalNumInChannels( IVAS_REND_HANDLE hIvasRend, return totalNumInChannels; } -static void setupWithSingleFormatInput( CmdlnArgs args, char *audioFilePath, IsmPositionProvider *positionProvider, MasaFileReader **masaReaders ) +static void setupWithSingleFormatInput( + CmdlnArgs args, + char *audioFilePath, + IsmPositionProvider *positionProvider, + MasaFileReader **masaReaders ) { /* With single-format input, inputFilePath is the path to input audio file. */ strncpy( audioFilePath, args.inputFilePath, FILENAME_MAX - 1 ); @@ -519,7 +513,7 @@ static void setupWithSingleFormatInput( CmdlnArgs args, char *audioFilePath, Ism else if ( args.inConfig.numAudioObjects != 0 ) { positionProvider->numObjects = args.inConfig.numAudioObjects; - for ( int32_t i = 0; i < positionProvider->numObjects; ++i ) + for ( int16_t i = 0; i < positionProvider->numObjects; ++i ) { /* It is allowed on CLI to have no metadata for an ISM input - skip opening if string is empty or contains "NULL" */ char charBuf[FILENAME_MAX]; @@ -540,7 +534,8 @@ static void setupWithSingleFormatInput( CmdlnArgs args, char *audioFilePath, Ism } } -static float dBToLin( float gain_dB ) +static float dBToLin( + const float gain_dB ) { return powf( 10.0f, gain_dB / 20.0f ); } @@ -548,7 +543,9 @@ static float dBToLin( float gain_dB ) /* ============================================================================ */ -int32_t main( int32_t argc, char **argv ) +int main( + int argc, + char **argv ) { IVAS_REND_HANDLE hIvasRend; HeadRotFileReader *headRotReader = NULL; @@ -573,6 +570,7 @@ int32_t main( int32_t argc, char **argv ) int16_t delayNumSamples_orig = 0; int16_t zeroPad = 0; int32_t delayTimeScale = 0; + int16_t i, numChannels; ivas_error error = IVAS_ERR_OK; #ifdef WMOPS size_t SRAM_size; @@ -587,7 +585,7 @@ int32_t main( int32_t argc, char **argv ) mem_count_init( 0, USE_32BITS ); #endif - for ( int32_t i = 0; i < RENDERER_MAX_MASA_INPUTS; ++i ) + for ( i = 0; i < RENDERER_MAX_MASA_INPUTS; ++i ) { masaReaders[i] = NULL; hMasaMetadata[i] = NULL; @@ -613,11 +611,7 @@ int32_t main( int32_t argc, char **argv ) if ( !isEmptyString( args.renderConfigFilePath ) ) { - if ( ( error = RenderConfigReader_open( args.renderConfigFilePath , &renderConfigReader ) ) != IVAS_ERR_OK ) - { - fprintf( stderr, "\nError: Can't open Renderer configuration file %s \n\n", args.renderConfigFilePath ); - exit( -1 ); - } + RenderConfigReader_open( args.renderConfigFilePath, &renderConfigReader ); } /* Initialize main input files, i.e. audio and metadata */ @@ -652,7 +646,7 @@ int32_t main( int32_t argc, char **argv ) { args.sampleRate = inFileSampleRate; } - const int32_t frameSize_smpls = 20 * args.sampleRate / 1000; + const int16_t frameSize_smpls = (int16_t) ( 20 * args.sampleRate / 1000 ); IVAS_REND_InputId mcIds[RENDERER_MAX_MC_INPUTS] = { 0 }; IVAS_REND_InputId ismIds[RENDERER_MAX_ISM_INPUTS] = { 0 }; @@ -709,7 +703,7 @@ int32_t main( int32_t argc, char **argv ) } } - for ( int32_t i = 0; i < args.inConfig.numMultiChannelBuses; ++i ) + for ( i = 0; i < args.inConfig.numMultiChannelBuses; ++i ) { if ( ( error = IVAS_REND_AddInput( hIvasRend, args.inConfig.multiChannelBuses[i].audioConfig, &mcIds[i] ) ) != IVAS_ERR_OK ) { @@ -735,7 +729,7 @@ int32_t main( int32_t argc, char **argv ) /* TODO(sgi): Test custom LFE routing here */ } - for ( int32_t i = 0; i < args.inConfig.numAudioObjects; ++i ) + for ( i = 0; i < args.inConfig.numAudioObjects; ++i ) { if ( ( error = IVAS_REND_AddInput( hIvasRend, IVAS_REND_AUDIO_CONFIG_OBJECT, &ismIds[i] ) ) != IVAS_ERR_OK ) { @@ -750,7 +744,7 @@ int32_t main( int32_t argc, char **argv ) } } - for ( int32_t i = 0; i < args.inConfig.numAmbisonicsBuses; ++i ) + for ( i = 0; i < args.inConfig.numAmbisonicsBuses; ++i ) { if ( ( error = IVAS_REND_AddInput( hIvasRend, args.inConfig.ambisonicsBuses[i].audioConfig, &sbaIds[i] ) ) != IVAS_ERR_OK ) { @@ -765,7 +759,7 @@ int32_t main( int32_t argc, char **argv ) } } - const int32_t totalNumInChannels = getTotalNumInChannels( hIvasRend, mcIds, ismIds, sbaIds ); + const int16_t totalNumInChannels = getTotalNumInChannels( hIvasRend, mcIds, ismIds, sbaIds ); if ( AudioFileReader_getNumChannels( audioReader ) != 0 /* If input file is raw PCM, audio reader has no info about number of channels */ && totalNumInChannels != AudioFileReader_getNumChannels( audioReader ) ) { @@ -773,7 +767,7 @@ int32_t main( int32_t argc, char **argv ) exit( -1 ); } - for ( int32_t i = 0; i < args.inConfig.numMasaBuses; ++i ) + for ( i = 0; i < args.inConfig.numMasaBuses; ++i ) { if ( masaReaders[i] != NULL ) { @@ -781,7 +775,7 @@ int32_t main( int32_t argc, char **argv ) } } - int32_t numOutChannels; + int16_t numOutChannels; if ( ( error = IVAS_REND_NumOutChannels( hIvasRend, &numOutChannels ) ) != IVAS_ERR_OK ) { fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); @@ -828,7 +822,7 @@ int32_t main( int32_t argc, char **argv ) while ( 1 ) { - int32_t num_in_channels; + int16_t num_in_channels; num_in_channels = inBuffer.config.numChannels; /* Read the input data */ @@ -861,7 +855,7 @@ int32_t main( int32_t argc, char **argv ) } #endif - for ( int32_t i = 0; i < RENDERER_MAX_MASA_INPUTS; ++i ) + for ( i = 0; i < RENDERER_MAX_MASA_INPUTS; ++i ) { if ( masaReaders[i] != NULL ) { @@ -887,15 +881,14 @@ int32_t main( int32_t argc, char **argv ) IVAS_REND_SetHeadRotation( hIvasRend, NULL ); } - for ( int32_t i = 0; i < args.inConfig.numMultiChannelBuses; ++i ) + for ( i = 0; i < args.inConfig.numMultiChannelBuses; ++i ) { - int32_t numChannels; if ( ( error = IVAS_REND_GetInputNumChannels( hIvasRend, mcIds[i], &numChannels ) ) != IVAS_ERR_OK ) { fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); exit( -1 ); } - IVAS_REND_ReadOnlyAudioBuffer tmpBuffer = getReadOnlySubBuffer( inBuffer, args.inConfig.multiChannelBuses[i].inputChannelIndex, numChannels ); + IVAS_REND_ReadOnlyAudioBuffer tmpBuffer = getReadOnlySubBuffer( inBuffer, (int16_t) args.inConfig.multiChannelBuses[i].inputChannelIndex, numChannels ); if ( ( error = IVAS_REND_FeedInputAudio( hIvasRend, mcIds[i], tmpBuffer ) ) != IVAS_ERR_OK ) { @@ -904,9 +897,9 @@ int32_t main( int32_t argc, char **argv ) } } - for ( int32_t i = 0; i < args.inConfig.numAudioObjects; ++i ) + for ( i = 0; i < args.inConfig.numAudioObjects; ++i ) { - IVAS_REND_ReadOnlyAudioBuffer tmpBuffer = getReadOnlySubBuffer( inBuffer, args.inConfig.audioObjects[i].inputChannelIndex, 1 ); + IVAS_REND_ReadOnlyAudioBuffer tmpBuffer = getReadOnlySubBuffer( inBuffer, (int16_t) args.inConfig.audioObjects[i].inputChannelIndex, 1 ); if ( ( error = IVAS_REND_FeedInputAudio( hIvasRend, ismIds[i], tmpBuffer ) ) != IVAS_ERR_OK ) { @@ -921,15 +914,14 @@ int32_t main( int32_t argc, char **argv ) } } - for ( int32_t i = 0; i < args.inConfig.numAmbisonicsBuses; ++i ) + for ( i = 0; i < args.inConfig.numAmbisonicsBuses; ++i ) { - int32_t numChannels; if ( ( error = IVAS_REND_GetInputNumChannels( hIvasRend, sbaIds[i], &numChannels ) ) != IVAS_ERR_OK ) { fprintf( stderr, "Error: %s\n", ivas_error_to_string( error ) ); exit( -1 ); } - IVAS_REND_ReadOnlyAudioBuffer tmpBuffer = getReadOnlySubBuffer( inBuffer, args.inConfig.ambisonicsBuses[i].inputChannelIndex, numChannels ); + IVAS_REND_ReadOnlyAudioBuffer tmpBuffer = getReadOnlySubBuffer( inBuffer, (int16_t) args.inConfig.ambisonicsBuses[i].inputChannelIndex, numChannels ); if ( ( error = IVAS_REND_FeedInputAudio( hIvasRend, sbaIds[i], tmpBuffer ) ) != IVAS_ERR_OK ) { @@ -940,7 +932,7 @@ int32_t main( int32_t argc, char **argv ) IVAS_REND_GetSamples( hIvasRend, outBuffer ); - int32_t num_out_channels; + int16_t num_out_channels; num_out_channels = outBuffer.config.numChannels; /* Convert from float to int and from packed to interleaved. @@ -1022,7 +1014,7 @@ int32_t main( int32_t argc, char **argv ) count_free( inFloatBuffer ); count_free( outInt16Buffer ); count_free( outFloatBuffer ); - for ( int32_t i = 0; i < RENDERER_MAX_MASA_INPUTS; ++i ) + for ( i = 0; i < RENDERER_MAX_MASA_INPUTS; ++i ) { MasaFileReader_close( &masaReaders[i] ); } @@ -1042,13 +1034,14 @@ int32_t main( int32_t argc, char **argv ) #endif #ifdef WMOPS print_wmops(); - /* print_mem_renderer( SRAM_size ); */ + print_mem_renderer( SRAM_size ); #endif return 0; } -static IVAS_REND_AudioConfig ambisonicsOrderToEnum( int32_t order ) +static IVAS_REND_AudioConfig ambisonicsOrderToEnum( + const int16_t order ) { switch ( order ) { @@ -1063,7 +1056,10 @@ static IVAS_REND_AudioConfig ambisonicsOrderToEnum( int32_t order ) return IVAS_REND_AUDIO_CONFIG_UNKNOWN; } -static bool parseInConfig( const char *inFormatStr, InputConfig *inConfig, bool *sceneDescriptionInput ) +static bool parseInConfig( + const char *inFormatStr, + InputConfig *inConfig, + bool *sceneDescriptionInput ) { char charBuf[FILENAME_MAX]; @@ -1131,7 +1127,7 @@ static bool parseInConfig( const char *inFormatStr, InputConfig *inConfig, bool fprintf( stderr, "Too many objects at input. Max %d supported.", RENDERER_MAX_ISM_INPUTS ); return false; } - for ( int32_t i = 0; i < inConfig->numAudioObjects; ++i ) + for ( int16_t i = 0; i < inConfig->numAudioObjects; ++i ) { inConfig->audioObjects[i].audioConfig = audioConfig; inConfig->audioObjects[i].inputChannelIndex = i; @@ -1172,7 +1168,9 @@ static bool parseInConfig( const char *inFormatStr, InputConfig *inConfig, bool return true; } -static bool parseOutConfig( const char *outputFormatStr, OutputConfig *outConfig ) +static bool parseOutConfig( + const char *outputFormatStr, + OutputConfig *outConfig ) { ivas_error error; @@ -1192,7 +1190,9 @@ static bool parseOutConfig( const char *outputFormatStr, OutputConfig *outConfig return true; } -static int8_t parseDiegeticPan( char *value, float *noDiegeticPan ) +static int8_t parseDiegeticPan( + char *value, + float *noDiegeticPan ) { int8_t success; success = 1; @@ -1223,7 +1223,9 @@ static int8_t parseDiegeticPan( char *value, float *noDiegeticPan ) return success ? 0 : -1; } -static int8_t parseOrientationTracking( char *value, int8_t *tracking_type ) +static int8_t parseOrientationTracking( + char *value, + int8_t *tracking_type ) { int8_t success; success = 1; @@ -1247,7 +1249,8 @@ static int8_t parseOrientationTracking( char *value, int8_t *tracking_type ) return success ? 0 : -1; } -static IVAS_REND_AudioConfig parseAudioConfig( const char *configString ) +static IVAS_REND_AudioConfig parseAudioConfig( + const char *configString ) { char charBuf[14]; charBuf[13] = '\0'; @@ -1323,7 +1326,8 @@ static IVAS_REND_AudioConfig parseAudioConfig( const char *configString ) return IVAS_REND_AUDIO_CONFIG_UNKNOWN; } -static const CmdLnParser_Option *findOptionById( int32_t id ) +static const CmdLnParser_Option *findOptionById( + const int32_t id ) { for ( int32_t i = 0; i < numCliOptions; ++i ) { @@ -1336,7 +1340,8 @@ static const CmdLnParser_Option *findOptionById( int32_t id ) return NULL; } -static bool checkRequiredArgs( CmdlnArgs args ) +static bool checkRequiredArgs( + CmdlnArgs args ) { const CmdLnParser_Option *tmpOption; @@ -1379,7 +1384,8 @@ static bool checkRequiredArgs( CmdlnArgs args ) return !missingRequiredArg; } -static CmdlnArgs defaultArgs( const char *executableName ) +static CmdlnArgs defaultArgs( + const char *executableName ) { CmdlnArgs args; @@ -1420,7 +1426,11 @@ static CmdlnArgs defaultArgs( const char *executableName ) return args; } -static void parseOption( int32_t optionId, char **optionValues, int16_t numOptionValues, void *pOutputStruct ) +static void parseOption( + const int32_t optionId, + char **optionValues, + const int16_t numOptionValues, + void *pOutputStruct ) { CmdlnArgs *args = pOutputStruct; @@ -1443,7 +1453,7 @@ static void parseOption( int32_t optionId, char **optionValues, int16_t numOptio break; case CmdLnOptionId_inputMetadata: assert( numOptionValues <= RENDERER_MAX_ISM_INPUTS ); - for ( int32_t i = 0; i < numOptionValues; ++i ) + for ( int16_t i = 0; i < numOptionValues; ++i ) { strncpy( args->inMetadataFilePaths[i], optionValues[i], RENDERER_MAX_CLI_ARG_LENGTH - 1 ); } @@ -1521,9 +1531,13 @@ static void parseOption( int32_t optionId, char **optionValues, int16_t numOptio assert( 0 && "This should be unreachable - all command line options should be explicitly handled." ); break; } + + return; } -static CmdlnArgs parseCmdlnArgs( int32_t argc, char **argv ) +static CmdlnArgs parseCmdlnArgs( + const int argc, + char **argv ) { CmdlnArgs args = defaultArgs( argv[0] ); @@ -1541,10 +1555,11 @@ static CmdlnArgs parseCmdlnArgs( int32_t argc, char **argv ) } -IsmPositionProvider *IsmPositionProvider_open( void ) +IsmPositionProvider *IsmPositionProvider_open( + void ) { IsmPositionProvider *ipp; - uint32_t i; + uint16_t i; ipp = (IsmPositionProvider *) count_malloc( sizeof( IsmPositionProvider ) ); ipp->frameCounter = 0; @@ -1565,7 +1580,7 @@ IsmPositionProvider *IsmPositionProvider_open( void ) void getMetadataFromFileReader( IsmFileReader *ismReader, ObjectPositionBuffer *objectMetadataBuffer, - uint32_t objIdx ) + const uint32_t objIdx ) { IVAS_ISM_METADATA ismMetadata; ivas_error error; @@ -1578,11 +1593,14 @@ void getMetadataFromFileReader( objectMetadataBuffer->positions[objIdx].azimuth = ismMetadata.azimuth; objectMetadataBuffer->positions[objIdx].elevation = ismMetadata.elevation; + + return; } -void readFromShorthandMetadata( IsmPositionProvider *positionProvider, - ObjectPositionBuffer *objectMetadataBuffer, - uint32_t objIdx ) +void readFromShorthandMetadata( + IsmPositionProvider *positionProvider, + ObjectPositionBuffer *objectMetadataBuffer, + const uint32_t objIdx ) { uint32_t preUpdatePositionIdx; uint32_t postUpdatePositionIdx; @@ -1600,6 +1618,8 @@ void readFromShorthandMetadata( IsmPositionProvider *positionProvider, postUpdatePositionIdx = positionProvider->currentPositionIdxs[objIdx]; objectMetadataBuffer->positions[objIdx] = positionProvider->positions[objIdx][postUpdatePositionIdx]; + + return; } void IsmPositionProvider_getNextFrame( @@ -1636,6 +1656,8 @@ void IsmPositionProvider_getNextFrame( } ++positionProvider->frameCounter; + + return; } void IsmPositionProvider_close( IsmPositionProvider *positionProvider ) @@ -1666,13 +1688,16 @@ void IsmPositionProvider_close( IsmPositionProvider *positionProvider ) } count_free( positionProvider ); + + return; } -static void splitConfigFile( const char *mdfFilePath, - char *metadataString, - uint32_t *metadataStringLength, - char *wavFileName, - uint32_t *wavFileNameLength ) +static void splitConfigFile( + const char *mdfFilePath, + char *metadataString, + uint32_t *metadataStringLength, + char *wavFileName, + uint32_t *wavFileNameLength ) { FILE *file; uint32_t bufferlength; @@ -1723,10 +1748,15 @@ static void splitConfigFile( const char *mdfFilePath, *metadataStringLength = mdlength + 1; fclose( file ); + + return; } /* r: pointer to character following last found delimiter */ -static char *readNextMetadataChunkFrom( char *start_char, char *line, const char *delimiter ) +static char *readNextMetadataChunkFrom( + char *start_char, + char *line, + const char *delimiter ) { char *token; @@ -1749,12 +1779,16 @@ static char *readNextMetadataChunkFrom( char *start_char, char *line, const char } /* r: pointer to character following last found delimiter */ -static char *readNextMetadataChunk( char *line, const char *delimiter ) +static char *readNextMetadataChunk( + char *line, + const char *delimiter ) { return readNextMetadataChunkFrom( NULL, line, delimiter ); } -static void parseUint8( const char *line, uint8_t *ret ) +static void parseUint8( + const char *line, + uint8_t *ret ) { char *ptr; ptr = NULL; @@ -1765,9 +1799,13 @@ static void parseUint8( const char *line, uint8_t *ret ) fprintf( stderr, "Cannot parse string \"%s\" as an integer value\n", line ); exit( -1 ); } + + return; } -static int8_t parseUint32( const char *line, uint32_t *ret ) +static int8_t parseUint32( + const char *line, + uint32_t *ret ) { char *ptr; ptr = NULL; @@ -1781,7 +1819,9 @@ static int8_t parseUint32( const char *line, uint32_t *ret ) return 0; } -static int8_t parseInt32( const char *line, int32_t *ret ) +static int8_t parseInt32( + const char *line, + int32_t *ret ) { char *ptr; ptr = NULL; @@ -1836,11 +1876,14 @@ static void parseOptionalInputValues( parse_pos = readNextMetadataChunkFrom( parse_pos, line, "\n" ); } + + return; } -static void parseObjectPosition( char *line, - IVAS_REND_AudioObjectPosition *position, - uint16_t *positionDuration ) +static void parseObjectPosition( + char *line, + IVAS_REND_AudioObjectPosition *position, + uint16_t *positionDuration ) { char *endptr; @@ -1869,6 +1912,8 @@ static void parseObjectPosition( char *line, fprintf( stderr, "Error reading metadata\n" ); exit( -1 ); } + + return; } static void parseIsm( @@ -1876,7 +1921,7 @@ static void parseIsm( char *inDir, InputConfig *inConfig, IsmPositionProvider *positionProvider, - int32_t idx ) + const int32_t idx ) { uint32_t numberOfObjectPositionsToRead; uint32_t i; @@ -1914,11 +1959,14 @@ static void parseIsm( /* Read optional values */ parseOptionalInputValues( line, &inConfig->audioObjects[idx].gain_dB ); + + return; } -static void parseSba( char *line, - InputConfig *inConfig, - int32_t idx ) +static void parseSba( + char *line, + InputConfig *inConfig, + const int32_t idx ) { uint8_t ambiOrder; @@ -1932,11 +1980,14 @@ static void parseSba( char *line, /* Read optional values */ parseOptionalInputValues( line, &inConfig->ambisonicsBuses[idx].gain_dB ); + + return; } -static void parseMc( char *line, - InputConfig *inConfig, - int32_t idx ) +static void parseMc( + char *line, + InputConfig *inConfig, + const int32_t idx ) { readNextMetadataChunk( line, "\n" ); parseInt32( line, &inConfig->multiChannelBuses[idx].inputChannelIndex ); @@ -1955,6 +2006,8 @@ static void parseMc( char *line, /* Read optional values */ parseOptionalInputValues( line, &inConfig->multiChannelBuses[idx].gain_dB ); + + return; } static void parseMasa( @@ -1962,7 +2015,7 @@ static void parseMasa( char *inDir, InputConfig *inConfig, MasaFileReader **masaReaders, - int32_t idx ) + const int32_t idx ) { readNextMetadataChunk( line, "\n" ); parseInt32( line, &inConfig->masaBuses[idx].inputChannelIndex ); @@ -1994,6 +2047,8 @@ static void parseMasa( /* Read optional values */ parseOptionalInputValues( line, &inConfig->masaBuses[idx].gain_dB ); + + return; } static ivas_error parseCustomLayoutFile( @@ -2143,9 +2198,16 @@ static void parseMetadata( fprintf( stderr, "Trailing text in metadata file\n" ); exit( -1 ); } + + return; } -static void parseSceneDescriptionFile( char *path, char *audioFilePath, InputConfig *inConfig, IsmPositionProvider *positionProvider, MasaFileReader **masaReaders ) +static void parseSceneDescriptionFile( + char *path, + char *audioFilePath, + InputConfig *inConfig, + IsmPositionProvider *positionProvider, + MasaFileReader **masaReaders ) { uint32_t inAudioFilePathLen; char inAudioFilePath[FILENAME_MAX]; @@ -2156,11 +2218,7 @@ static void parseSceneDescriptionFile( char *path, char *audioFilePath, InputCon inAudioFilePathLen = FILENAME_MAX; mtdStrLen = RENDERER_MAX_METADATA_LENGTH; - splitConfigFile( path, - mtdStr, - &mtdStrLen, - inAudioFilePath, - &inAudioFilePathLen ); + splitConfigFile( path, mtdStr, &mtdStrLen, inAudioFilePath, &inAudioFilePathLen ); remove_cr( mtdStr ); convert_backslash( inAudioFilePath ); @@ -2183,7 +2241,7 @@ static void parseSceneDescriptionFile( char *path, char *audioFilePath, InputCon static void printSupportedAudioConfigs() { - uint32_t i; + uint16_t i; const char *supportedFormats[] = { "MONO", "STEREO", @@ -2207,14 +2265,18 @@ static void printSupportedAudioConfigs() { fprintf( stdout, "%s\n", supportedFormats[i] ); } + + return; } -static void convert_backslash( char *str ) +// VE2AT: possibly move these functions to cmdln_parser.c ? +static void convert_backslash( + char *str ) { - int32_t i, len; + int16_t i, len; /* check that all backslashes are correct on the given platform */ - len = (int32_t) strlen( str ); + len = (int16_t) strlen( str ); for ( i = 0; i < len; i++ ) { @@ -2230,6 +2292,8 @@ static void convert_backslash( char *str ) } #endif } + + return; } static void remove_cr( char *str ) @@ -2243,14 +2307,20 @@ static void remove_cr( char *str ) strcpy( pos, pos + 1 ); pos = strchr( pos, '\r' ); } + + return; } -static void clearString( char *str ) +static void clearString( + char *str ) { str[0] = '\0'; + + return; } -static bool isEmptyString( const char *str ) +static bool isEmptyString( + const char *str ) { return str[0] == '\0'; } @@ -2261,17 +2331,18 @@ static bool isEmptyString( const char *str ) * 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, - int32_t numIntSamplesPerChannel, - int32_t numFloatSamplesPerChannel, - int32_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 ) { - int32_t chnl, smpl, i; + int16_t chnl, smpl, i; i = 0; - for ( smpl = 0; smpl < numFloatSamplesPerChannel; ++smpl ) { for ( chnl = 0; chnl < numChannels; ++chnl ) @@ -2288,6 +2359,8 @@ static void convertInputBuffer( const int16_t *intBuffer, ++i; } } + + return; } /*--------------------------------------------------------------------------* @@ -2296,12 +2369,14 @@ static void convertInputBuffer( const int16_t *intBuffer, * 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, - int32_t numSamplesPerChannel, - int32_t numChannels, - int16_t *intBuffer ) + +static void convertOutputBuffer( + const float *floatBuffer, + const int16_t numSamplesPerChannel, + const int16_t numChannels, + int16_t *intBuffer ) { - int32_t chnl, smpl, i; + int16_t chnl, smpl, i; i = 0; @@ -2314,9 +2389,13 @@ static void convertOutputBuffer( const float *floatBuffer, ++i; } } + + return; } #else -int32_t main( int32_t argc, char **argv ) +int main( + int argc, + char **argv ) { (void) argc; (void) argv; diff --git a/ci/run_scheduled_sanitizer_test.py b/ci/run_scheduled_sanitizer_test.py index 4f3cd25c0b..6696e184c2 100644 --- a/ci/run_scheduled_sanitizer_test.py +++ b/ci/run_scheduled_sanitizer_test.py @@ -6,8 +6,8 @@ import subprocess import pathlib -DURATION = "120" -CFG = "ci_linux.json" +DURATION = "30" +CFG = "ci_linux_ltv.json" SUPPORTED_TESTS = ["CLANG1", "CLANG2", "CLANG3", "VALGRIND"] EP_FILE = "ep_015.g192" GENPATT_CMD = f"gen-patt -tailstat -fer -g192 -gamma 0 -rate 0.15 -tol 0.001 -reset -n {int(DURATION) * 50} {EP_FILE}" @@ -48,9 +48,6 @@ def get_modes(in_format: str) -> list: in_format = "MC_" + in_format + "_b" mode_list = [m for m in output.splitlines() if in_format in m] - if "SBA" in in_format: - # rate switching not implemented yet - mode_list = [m for m in mode_list if not "_rs" in m] return mode_list diff --git a/ci/smoke_test.sh b/ci/smoke_test.sh index b8c4bdd3f0..e3caac3533 100755 --- a/ci/smoke_test.sh +++ b/ci/smoke_test.sh @@ -8,8 +8,5 @@ fi make clean make all -j 8 -# get all modes except SBA rate switching (which is broken currently) -list=$(./scripts/runIvasCodec.py -l | grep -v "SBA.*rs") -./scripts/runIvasCodec.py -p ./scripts/config/ci_linux.json -m $list -U 1 | tee smoke_test_output.txt - -./scripts/runIvasCodec.py -p ./scripts/config/ci_linux.json -m $list -U 1 -D="-fec 15" --decoder_only | tee smoke_test_output_plc.txt +./scripts/runIvasCodec.py -p ./scripts/config/ci_linux.json -U 1 | tee smoke_test_output.txt +./scripts/runIvasCodec.py -p ./scripts/config/ci_linux.json -U 1 -D="-fec 15" --decoder_only | tee smoke_test_output_plc.txt diff --git a/lib_com/cnst.h b/lib_com/cnst.h index e62ef001dc..be668b01c7 100644 --- a/lib_com/cnst.h +++ b/lib_com/cnst.h @@ -132,6 +132,9 @@ enum{ #define MAX_V_MULT_MAT 100 /* maximum array length for the function v_mult_mat() */ +#define SBA_AGC_FORCE_ENABLE 1 +#define SBA_AGC_FORCE_DISABLE 0 +#define SBA_AGC_DEFAULT -1 /*----------------------------------------------------------------------------------* * Layers diff --git a/lib_com/fill_spectrum.c b/lib_com/fill_spectrum.c index c1837d5140..a3dbcf304b 100644 --- a/lib_com/fill_spectrum.c +++ b/lib_com/fill_spectrum.c @@ -90,18 +90,10 @@ void fill_spectrum( const int16_t element_mode /* i : element mode */ ) { -#ifdef FIX_I178_HQ_BUFFER_OVERRUN float CodeBook[L_SPEC48k_EXT]; -#else - float CodeBook[FREQ_LENGTH]; -#endif int16_t cb_size = 0; int16_t last_sfm; -#ifdef FIX_I178_HQ_BUFFER_OVERRUN float CodeBook_mod[L_SPEC48k_EXT]; -#else - float CodeBook_mod[FREQ_LENGTH]; -#endif float norm_adj[NB_SFM]; int16_t high_sfm = 23; int16_t flag_32K_env_hangover; diff --git a/lib_com/ivas_cnst.h b/lib_com/ivas_cnst.h index 3708e0181c..e0c1e0e501 100644 --- a/lib_com/ivas_cnst.h +++ b/lib_com/ivas_cnst.h @@ -837,11 +837,19 @@ typedef enum { * SBA Constants *----------------------------------------------------------------------------------*/ +#define SBA_FOA_ORDER 1 +#define SBA_HOA2_ORDER 2 +#define SBA_HOA3_ORDER 3 + #define SBA_PLANAR_BITS 1 #define SBA_ORDER_BITS 2 + #define SBA_MIN_BRATE_HOA IVAS_256k #define SBA_NHARM_HOA3 16 #define SBA_T_DESIGN_11_SIZE 70 +#ifdef FIX_SBA_DTX_DECODE_ERROR +#define SBA_DTX_BITRATE_THRESHOLD IVAS_80k +#endif typedef enum { @@ -1325,11 +1333,7 @@ typedef enum #define PANNING_ELE_RESOLUTION 5 #define EFAP_MAX_CHAN_NUM 5 /* Maximum number of channels that constitute a polygon, 4 or 5 */ -#ifdef ALLRAD_OPTIM #define EFAP_MAX_POLY_SET 50 /* Upper bound on number of polygons; with a Speaker setup of 16.0, we obtain 44 polygons/triangles in the matlab implementation. */ -#else -#define EFAP_MAX_POLY_SET 70 /* Upper bound on number of polygons; with a Speaker setup of 26.0, we obtain 54 polygons/triangles in the matlab implementation. */ -#endif #define EFAP_MODE_EFAP 0 /* EFAP Panning */ #define EFAP_MODE_EFIP 1 /* EFIP Panning */ diff --git a/lib_com/ivas_cov_smooth.c b/lib_com/ivas_cov_smooth.c index 0015871287..eaaec6a982 100644 --- a/lib_com/ivas_cov_smooth.c +++ b/lib_com/ivas_cov_smooth.c @@ -169,36 +169,22 @@ void ivas_spar_covar_smooth_enc_close( static void ivas_compute_smooth_cov( ivas_cov_smooth_state_t *hCovState, -#ifndef SBA_SPAR_HARM - ivas_cov_smooth_in_buf_t *pIn_buf, -#endif ivas_filterbank_t *pFb, float *pCov_buf[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], float *pPrior_cov_buf[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], const float fac, const int16_t start_band, - const int16_t end_band -#ifdef SBA_SPAR_HARM - , + const int16_t end_band, const int16_t num_ch, - const int16_t transient_det -#endif -) + const int16_t transient_det ) { int16_t i, j, k; int16_t prev_idx = hCovState->prior_bank_idx; -#ifndef SBA_SPAR_HARM - int16_t num_ch = pIn_buf->num_ch; -#endif float factor = 0; assert( end_band <= pFb->filterbank_num_bands ); -#ifdef SBA_SPAR_HARM if ( prev_idx == -1 || transient_det == 1 ) -#else - if ( prev_idx == -1 || pIn_buf->reset_cov == 1 ) -#endif { for ( i = 0; i < num_ch; i++ ) { @@ -243,42 +229,23 @@ static void ivas_compute_smooth_cov( void ivas_cov_smooth_process( ivas_cov_smooth_state_t *hCovState, /* i/o: Covariance state handle */ -#ifdef SBA_SPAR_HARM float *cov_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], -#else - ivas_cov_smooth_in_buf_t *pIn_buf, -#endif ivas_filterbank_t *pFb, /* i/o: FB handle */ const int16_t start_band, - const int16_t end_band -#ifdef SBA_SPAR_HARM - , + const int16_t end_band, const int16_t num_ch, - const int16_t transient_det -#endif -) + const int16_t transient_det ) { int16_t i, j; -#ifndef SBA_SPAR_HARM - int16_t num_ch = pIn_buf->num_ch; -#endif int16_t num_bands = end_band - start_band; -#ifdef SBA_SPAR_HARM ivas_compute_smooth_cov( hCovState, pFb, cov_real, hCovState->pPrior_cov_real, 1e-20f, start_band, end_band, num_ch, transient_det ); -#else - ivas_compute_smooth_cov( hCovState, pIn_buf, pFb, pIn_buf->cov_real, hCovState->pPrior_cov_real, 1e-20f, start_band, end_band ); -#endif for ( i = 0; i < num_ch; i++ ) { for ( j = 0; j < num_ch; j++ ) { -#ifdef SBA_SPAR_HARM mvr2r( &cov_real[i][j][start_band], &hCovState->pPrior_cov_real[i][j][start_band], num_bands ); -#else - mvr2r( &pIn_buf->cov_real[i][j][start_band], &hCovState->pPrior_cov_real[i][j][start_band], num_bands ); -#endif } } diff --git a/lib_com/ivas_error.h b/lib_com/ivas_error.h index 8168a6c6d6..bfc9396f09 100644 --- a/lib_com/ivas_error.h +++ b/lib_com/ivas_error.h @@ -93,6 +93,9 @@ typedef enum IVAS_ERR_WRONG_NUM_CHANNELS, IVAS_ERR_INVALID_BUFFER_SIZE, #endif +#ifdef DEBUG_AGC_ENCODER_CMD_OPTION + IVAS_ERR_INVALID_AGC, +#endif /*----------------------------------------* * input data errors * diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index 7de6bde693..71622fd939 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -44,9 +44,6 @@ #include "ivas_stat_dec.h" #include "ivas_stat_com.h" #include "ivas_error_utils.h" -#ifdef AGC_ENABLE_FOR_LBR -#include "lib_enc.h" -#endif /* clang-format off */ @@ -108,7 +105,17 @@ ivas_error mct_enc_reconfigure( Encoder_Struct *st_ivas, /* i/o: IVAS encoder structure */ const uint16_t b_nchan_change /* i : flag indicating different channel count */ ); - +#ifdef SBA_BR_SWITCHING +ivas_error ivas_sba_enc_reinit( + Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ +); +#endif +#ifdef SBA_BR_SWITCHING +int16_t get_sba_reinit_flag( + int32_t ivas_total_bitrate, /* i: current bitrate */ + int32_t last_ivas_total_brate /* i: previous bitrate */ +); +#endif ivas_error ivas_sba_enc_reconfigure( Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ ); @@ -125,14 +132,12 @@ void ivas_mct_enc_close( MCT_ENC_HANDLE hMCT /* i/o: MCT encoder structure */ ); -#ifdef CORECODER_BITRATE_SWITCHING ivas_error ivas_corecoder_enc_reconfig( Encoder_Struct *st_ivas, /* i/o: IVAS encoder structure */ const int16_t nSCE_old, /* i : number of SCEs in previous frame */ const int16_t nCPE_old, /* i : number of CPEs in previous frame */ const int16_t nchan_transport_old /* i : number of TCs in previous frame */ ); -#endif ivas_error ivas_sce_enc( Encoder_Struct *st_ivas, /* i/o: IVAS encoder structure */ @@ -206,9 +211,7 @@ ivas_error pre_proc_ivas( Encoder_State *st, /* i/o: encoder state structure */ const int16_t last_element_mode, /* i : last element mode */ const int32_t element_brate, /* i : element bitrate */ -#ifdef CORECODER_BITRATE_SWITCHING const int32_t last_element_brate, /* i : last element bitrate */ -#endif const int16_t input_frame, /* i : frame length */ float old_inp_12k8[], /* i/o: buffer of old input signal */ float old_inp_16k[], /* i/o: buffer of old input signal @ 16kHz */ @@ -333,7 +336,6 @@ void ivas_mct_dec_close( MCT_DEC_HANDLE *hMCT /* i/o: MCT decoder structure */ ); -#ifdef CORECODER_BITRATE_SWITCHING ivas_error ivas_corecoder_dec_reconfig( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ const int16_t nSCE_old, /* i : number of SCEs in previous frame */ @@ -346,7 +348,6 @@ ivas_error ivas_hp20_dec_reconfig( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ const int16_t nchan_hp20_old /* i : number of HP20 filters in previous frame*/ ); -#endif ivas_error ivas_sce_dec( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ @@ -418,9 +419,7 @@ ivas_error ivas_core_enc( float enerBuffer[CPE_CHANNELS][CLDFB_NO_CHANNELS_MAX], /* i : energy buffer */ float fft_buff[CPE_CHANNELS][2 * L_FFT], /* i : FFT buffer */ const int16_t tdm_SM_flag, /* i : channel combination scheme flag */ -#ifdef CORECODER_BITRATE_SWITCHING const int16_t ivas_format, /* i : IVAS format */ -#endif const int16_t flag_16k_smc /* i : flag to indicate if the OL SMC is run at 16 kHz */ ); @@ -2169,12 +2168,8 @@ void stereo_decoder_tcx( const int16_t core_l, /* i : core for left channel (TCX20/TCX10) */ const int16_t core_r, /* i : core for right channel (TCX20/TCX10) */ const int16_t igf, /* i : flag for IGF activity */ -#ifdef FIX_TCX10_STEREO_PROC const int16_t L_frameTCX_l, /* i : TCX frame length of left channel */ const int16_t L_frameTCX_r, /* i : TCX frame length of right channel */ -#else - const int16_t L_frame, /* i : TCX frame length */ -#endif const int16_t mct_on, /* i : flag mct block (1) or stereo (0) */ const int16_t last_core_l, /* i : last core for left channel */ const int16_t last_core_r, /* i : last core for right channel */ @@ -3030,10 +3025,8 @@ void ivas_dirac_param_est_enc( float **pp_fr_real, float **pp_fr_imag, const int16_t input_frame -#ifdef SBA_HOA_HBR_IMPROV , const SBA_MODE sba_mode -#endif ); /*----------------------------------------------------------------------------------* @@ -3055,7 +3048,11 @@ void ivas_sba_config( int16_t *nCPE, /* o : number of CPEs */ int16_t *element_mode /* o : element mode of the core coder */ ); - +#ifdef SBA_BR_SWITCHING +ivas_error ivas_sba_dec_reinit( + Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ +); +#endif ivas_error ivas_sba_dec_reconfigure( Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ ); @@ -3093,13 +3090,11 @@ int16_t ivas_sba_get_nchan_metadata( const int16_t sba_order /* i : Ambisonic (SBA) order */ ); -#ifdef SBA_HOA_HBR_IMPROV /*! r: flag indicating to code SPAR HOA MD for all bands */ int16_t ivas_sba_get_spar_hoa_md_flag( const int16_t sba_order, /* i : Ambisonic (SBA) order */ const int32_t ivas_total_brate /* i : IVAS total bitrate */ ); -#endif void ivas_sba_zero_vert_comp( float sba_data[][L_FRAME48k], /* i/o: SBA data frame */ @@ -3783,9 +3778,12 @@ void ivas_sba_prototype_renderer( /* AGC */ #ifdef AGC_ENABLE_FOR_LBR -int16_t ivas_agc_enc_get_enablement_flag( - IVAS_ENC_AGC agc_configuration, /* i : configuration used when encoder was initialised from cmd line */ - int16_t nchan_transport /* i : number of transport channels */ +/*! r: AGC enable flag */ +int16_t ivas_agc_enc_get_flag( +#ifdef DEBUG_AGC_ENCODER_CMD_OPTION + int16_t agc_configuration, /* i : AGC configuration from command-line */ +#endif + int16_t nchan_transport /* i : number of transport channels */ ); #endif @@ -3929,19 +3927,11 @@ void ivas_spar_md_enc_close( ivas_error ivas_spar_md_enc_process( ivas_spar_md_enc_state_t *hMdEnc, /* i/o: SPAR MD encoder handle */ const ENCODER_CONFIG_HANDLE hEncoderConfig, /* i : configuration structure */ -#ifdef SBA_SPAR_HARM float *cov_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], float *cov_dtx_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], -#else - ivas_spar_md_enc_in_buf_t *pIn_buf, -#endif BSTR_ENC_HANDLE hMetaData, /* i/o: MetaData handle */ -#ifdef SBA_SPAR_HARM int16_t dtx_vad, const int16_t nchan_inp, -#else - const int16_t dtx_silence_mode, -#endif const int16_t sba_order /* i : Ambisonic (SBA) order */ ); @@ -4005,10 +3995,8 @@ ivas_error ivas_spar_md_dec_open( ivas_spar_md_dec_state_t **hMdDec_out, /* i/o: SPAR MD decoder handle */ const DECODER_CONFIG_HANDLE hDecoderConfig, /* i : configuration structure */ const int16_t num_channels /* i : number of internal channels */ -#ifdef SBA_HOA_HBR_IMPROV , const int16_t sba_order /* i : SBA order */ -#endif ); void ivas_spar_md_dec_close( @@ -4028,7 +4016,8 @@ void ivas_spar_get_parameters( ivas_error ivas_spar_md_dec_init( ivas_spar_md_dec_state_t *hMdDec, /* i/o: SPAR MD decoder handle */ const DECODER_CONFIG_HANDLE hDecoderConfig, /* i : configuration structure */ - const int16_t num_channels /* i : number of internal channels */ + const int16_t num_channels, /* i : number of internal channels */ + const int16_t sba_order /* i : SBA order */ ); void ivas_spar_md_dec_process( @@ -4081,24 +4070,16 @@ void ivas_spar_covar_enc_close( void ivas_enc_cov_handler_process( ivas_enc_cov_handler_state_t *hCovEnc, /* i/o: SPAR Covar. encoder handle */ -#ifdef SBA_SPAR_HARM float **ppIn_FR_real, float **ppIn_FR_imag, float *cov_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], float *cov_dtx_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], -#else - ivas_enc_cov_handler_in_buf_t *pIn_buf, - float *cov_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], - float *cov_dtx_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], -#endif ivas_filterbank_t *pFb, /* i/o: FB handle */ const int16_t start_band, const int16_t end_band -#ifdef SBA_SPAR_HARM ,const int16_t nchan_inp, const int16_t dtx_vad, const int16_t transient_det -#endif ); ivas_error ivas_spar_covar_smooth_enc_open( @@ -4115,19 +4096,13 @@ void ivas_spar_covar_smooth_enc_close( void ivas_cov_smooth_process( ivas_cov_smooth_state_t *hCovState, /* i/o: Covariance state handle */ -#ifdef SBA_SPAR_HARM float *cov_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], -#else - ivas_cov_smooth_in_buf_t *pIn_buf, -#endif ivas_filterbank_t *pFb, /* i/o: FB handle */ const int16_t start_band, const int16_t end_band -#ifdef SBA_SPAR_HARM , const int16_t num_ch, const int16_t transient_det -#endif ); /* Transient detector module */ @@ -4876,10 +4851,8 @@ void computeReferencePower_enc( float *reference_power, /* o : Estimated power */ const int16_t enc_param_start_band, /* i : first band to process */ const int16_t num_freq_bands /* i : Number of frequency bands */ -#ifdef SBA_HOA_HBR_IMPROV , const SBA_MODE sba_mode /* i : SBA mode */ -#endif ); diff --git a/lib_com/ivas_rom_com.c b/lib_com/ivas_rom_com.c index 4169e4ee92..c843d5ddc4 100644 --- a/lib_com/ivas_rom_com.c +++ b/lib_com/ivas_rom_com.c @@ -903,57 +903,57 @@ const ivas_spar_br_table_t ivas_spar_br_table_consts[IVAS_SPAR_BR_TABLE_LEN] = { /* When AGC is ON additional (AGC_BITS_PER_CH+1) bits may be taken from each core-coder channel so minimum core-coder bitrate per channel can be min core-coder bitrates as per the table - AGC_BITS_PER_CH */ - { 24400, 0, 1, FB, 24000, 1, WYXZ, 1, 0,{ { 16400, 14850, 24350 } }, + { 24400, 0, SBA_FOA_ORDER, FB, 24000, 1, WYXZ, 1, 0,{ { 16400, 14850, 24350 } }, { { 15, 1, 5, 1 },{ 15, 1, 3, 1 },{ 7, 1, 3, 1 } }, 0, 0, 0 }, - { 32000, 0, 1, FB, 24000, 1, WYXZ, 1, 0,{ { 24000, 20450, 31950 } }, + { 32000, 0, SBA_FOA_ORDER, FB, 24000, 1, WYXZ, 1, 0,{ { 24000, 20450, 31950 } }, { { 21, 1, 5, 1 },{ 15, 1, 5, 1 },{ 15, 1, 3, 1 } }, 0, 0, 0 }, - { 48000, 0, 1, FB, 24000, 2, WYXZ, 0, 0,{ { 24000, 21000, 31950 },{ 16000, 15000, 20400 } }, + { 48000, 0, SBA_FOA_ORDER, FB, 24000, 2, WYXZ, 0, 0,{ { 24000, 21000, 31950 },{ 16000, 15000, 20400 } }, { { 15, 7, 5, 1 },{ 15, 7, 3, 1 },{ 7, 7, 3, 1 } }, 1, 0, 0 }, - { 64000, 0, 1, FB, 24000, 2, WYXZ, 0, 0,{ { 38000, 34050, 56000 },{ 16000, 15600, 20400 } },{ { 21, 7, 5, 1 },{ 15, 7, 5, 1 },{ 15, 7, 3, 1 } }, 1, 1, 0 }, + { 64000, 0, SBA_FOA_ORDER, FB, 24000, 2, WYXZ, 0, 0,{ { 38000, 34050, 56000 },{ 16000, 15600, 20400 } },{ { 21, 7, 5, 1 },{ 15, 7, 5, 1 },{ 15, 7, 3, 1 } }, 1, 1, 0 }, - { 80000, 0, 1, FB, 24000, 2, WYXZ, 0, 0,{ { 46000, 43000, 56000 },{ 24000, 23000, 31950 } }, + { 80000, 0, SBA_FOA_ORDER, FB, 24000, 2, WYXZ, 0, 0,{ { 46000, 43000, 56000 },{ 24000, 23000, 31950 } }, { { 21, 7, 5, 1 },{ 15, 7, 5, 1 },{ 15, 7, 3, 1 } }, 1, 0, 0 }, - { 96000, 0, 1, FB, 24000, 3, WYXZ, 0, 0,{ { 47000, 42600, 56000 },{ 23000, 22600, 31950 },{ 16000, 15600, 20400 } }, + { 96000, 0, SBA_FOA_ORDER, FB, 24000, 3, WYXZ, 0, 0,{ { 47000, 42600, 56000 },{ 23000, 22600, 31950 },{ 16000, 15600, 20400 } }, { { 21, 9, 9, 1 },{ 21, 7, 5, 1 },{ 21, 7, 5, 1 } }, 1, 0, 0 }, - { 128000, 0, 1, FB, 24000, 3, WYXZ, 0, 0,{ { 55000, 50000, 56000 },{ 36000, 36000, 56000 },{ 27000, 27000, 31950 } }, + { 128000, 0, SBA_FOA_ORDER, FB, 24000, 3, WYXZ, 0, 0,{ { 55000, 50000, 56000 },{ 36000, 36000, 56000 },{ 27000, 27000, 31950 } }, { { 21, 11, 9, 1 },{ 21, 9, 7, 1 },{ 21, 7, 7, 1 } }, 1, 0, 0 }, - { 160000, 0, 1, FB, 24000, 3, WYXZ, 0, 0,{ { 74000, 70900, 112000 },{ 41000, 40050, 56000 },{ 35000, 34050, 56000 } }, + { 160000, 0, SBA_FOA_ORDER, FB, 24000, 3, WYXZ, 0, 0,{ { 74000, 70900, 112000 },{ 41000, 40050, 56000 },{ 35000, 34050, 56000 } }, { { 21, 11, 11, 1 },{ 21, 9, 9, 1 },{ 21, 7, 7, 1 } }, 1, 0, 0 }, - { 192000, 0, 1, FB, 24000, 3, WYXZ, 0, 0,{ { 90000, 87900, 112000 },{ 50000, 48050, 56000 },{ 42000, 41050, 56000 } }, + { 192000, 0, SBA_FOA_ORDER, FB, 24000, 3, WYXZ, 0, 0,{ { 90000, 87900, 112000 },{ 50000, 48050, 56000 },{ 42000, 41050, 56000 } }, { { 21, 11, 11, 1 },{ 21, 9, 9, 1 },{ 21, 7, 7, 1 } }, 1, 0, 0 }, - { 256000, 0, 1, FB, 24000, 4, WYXZ, 0, 0,{ { 90000, 85000, 112000 },{ 70000, 69000, 112000 },{ 50000, 48950, 56000 },{ 36400, 35600, 56000 } }, + { 256000, 0, SBA_FOA_ORDER, FB, 24000, 4, WYXZ, 0, 0,{ { 90000, 85000, 112000 },{ 70000, 69000, 112000 },{ 50000, 48950, 56000 },{ 36400, 35600, 56000 } }, { { 31, 1, 1, 1 },{ 1, 1, 1, 1 },{ 1, 1, 1, 1 } }, 1, 2, 0 }, - { 256000, 0, 2, FB, 24000, 4, WYXZ, 0, 0,{ { 84650, 83000, 112000 },{ 65850, 64550, 56000 },{ 47000, 46100, 48000 },{ 28200, 27650, 40000 } }, + { 256000, 0, SBA_HOA2_ORDER, FB, 24000, 4, WYXZ, 0, 0,{ { 84650, 83000, 112000 },{ 65850, 64550, 56000 },{ 47000, 46100, 48000 },{ 28200, 27650, 40000 } }, { { 31, 11, 11, 1 },{ 1, 1, 1, 1 },{ 1, 1, 1, 1 } }, 1, 2, 0 }, - { 256000, 0, 3, FB, 24000, 4, WYXZ, 0, 0,{ { 76300, 73550, 112000 },{ 59350, 57200, 56000 },{ 42400, 40850, 48000 },{ 25450, 24500, 40000 } }, + { 256000, 0, SBA_HOA3_ORDER, FB, 24000, 4, WYXZ, 0, 0,{ { 76300, 73550, 112000 },{ 59350, 57200, 56000 },{ 42400, 40850, 48000 },{ 25450, 24500, 40000 } }, { { 31, 11, 11, 1 },{ 1, 1, 1, 1 },{ 31, 1, 1, 1 } }, 1, 2, 0 }, { 384000, 0, 1, FB, 24000, 4, WYXZ, 0, 0,{ { 128000, 128000, 128000 },{ 100000, 100000, 128000 },{ 79850, 79850, 104000 },{ 66600, 66600, 104000 } }, // not yet optimized { { 31, 1, 1, 1 },{ 1, 1, 1, 1 },{ 1, 1, 1, 1 } }, 1, 2, 0 }, - { 384000, 0, 2, FB, 24000, 4, WYXZ, 0, 0,{ { 128000, 128000, 128000 },{ 105350, 103300, 112000 },{ 75200, 73750, 96000 },{ 45100, 44250, 48000 } }, // just added as a place holder, not necessarily operational + { 384000, 0, SBA_HOA2_ORDER, FB, 24000, 4, WYXZ, 0, 0,{ { 128000, 128000, 128000 },{ 105350, 103300, 112000 },{ 75200, 73750, 96000 },{ 45100, 44250, 48000 } }, // just added as a place holder, not necessarily operational { { 31, 11, 11, 1 },{ 1, 1, 1, 1 },{ 1, 1, 1, 1 } }, 1, 2, 0 }, - { 384000, 0, 3, FB, 24000, 4, WYXZ, 0, 0,{ { 124300, 121550, 128000 },{ 96700, 94550, 112000 },{ 69050, 67500, 96000 },{ 41450, 40500, 48000 } }, // just added as a place holder, not necessarily operational + { 384000, 0, SBA_HOA3_ORDER, FB, 24000, 4, WYXZ, 0, 0,{ { 124300, 121550, 128000 },{ 96700, 94550, 112000 },{ 69050, 67500, 96000 },{ 41450, 40500, 48000 } }, // just added as a place holder, not necessarily operational { { 31, 11, 11, 1 },{ 1, 1, 1, 1 },{ 1, 1, 1, 1 } }, 1, 2, 0 }, { 512000, 0, 1, FB, 24000, 4, WYXZ, 0, 0,{ { 128000, 128000, 128000 },{ 128000, 128000, 128000 },{ 128000, 128000, 128000 }, {118450, 118450, 128000 } }, // not yet optimized { { 31, 1, 1, 1 },{ 1, 1, 1, 1 },{ 1, 1, 1, 1 } }, 1, 2, 0 }, - { 512000, 0, 2, FB, 24000, 4, WYXZ, 0, 0,{ { 128000, 128000, 128000 },{ 128000, 128000, 128000 },{ 128000, 128000, 128000 },{ 97700, 93300, 128000 } }, // not yet optimized + { 512000, 0, SBA_HOA2_ORDER, FB, 24000, 4, WYXZ, 0, 0,{ { 128000, 128000, 128000 },{ 128000, 128000, 128000 },{ 128000, 128000, 128000 },{ 97700, 93300, 128000 } }, // not yet optimized { { 31, 11, 11, 1 },{ 1, 1, 1, 1 },{ 1, 1, 1, 1 } }, 1, 2, 0 }, - { 512000, 0, 3, FB, 24000, 4, WYXZ, 0, 0,{ { 128000, 128000, 128000 },{ 128000, 128000, 128000 },{ 127200, 122550, 128000 },{ 76300, 73550, 128000 } }, // not yet optimized + { 512000, 0, SBA_HOA3_ORDER, FB, 24000, 4, WYXZ, 0, 0,{ { 128000, 128000, 128000 },{ 128000, 128000, 128000 },{ 127200, 122550, 128000 },{ 76300, 73550, 128000 } }, // not yet optimized { { 31, 11, 11, 1 },{ 1, 1, 1, 1 },{ 1, 1, 1, 1 } }, 1, 2, 0 }, }; diff --git a/lib_com/ivas_sba_config.c b/lib_com/ivas_sba_config.c index cf22cf38ff..5b6cfd48cb 100644 --- a/lib_com/ivas_sba_config.c +++ b/lib_com/ivas_sba_config.c @@ -71,8 +71,26 @@ SBA_MODE ivas_sba_mode_select( return sba_mode; } - - +#ifdef SBA_BR_SWITCHING +/*-------------------------------------------------------------------* + * get_sba_reinit_flag() + * + * Get SBA reinitialisation flag + *-------------------------------------------------------------------*/ +int16_t get_sba_reinit_flag( + int32_t ivas_total_bitrate, /* i : Current bitrate */ + int32_t last_ivas_total_brate /* i : Previous bitrate */ +) +{ + int16_t sba_reinit_flag; + sba_reinit_flag = 0; + if ( ivas_total_bitrate != last_ivas_total_brate && ( last_ivas_total_brate > IVAS_SID_5k2 ) && ( ivas_total_bitrate > IVAS_SID_5k2 ) ) + { + sba_reinit_flag = 1; + } + return sba_reinit_flag; +} +#endif /*-------------------------------------------------------------------* * ivas_sba_config() * @@ -194,7 +212,7 @@ int16_t ivas_sba_get_analysis_order( if ( ivas_total_brate < SBA_MIN_BRATE_HOA ) { /* Hard coding the sba_analysis_order as 1 as higher not supported below SBA_MIN_BRATE_HOA bitrate */ - sba_analysis_order = 1; + sba_analysis_order = SBA_FOA_ORDER; } return sba_analysis_order; @@ -213,15 +231,15 @@ int16_t ivas_sba_get_order_transport( { int16_t sba_order; - sba_order = 1; + sba_order = SBA_FOA_ORDER; if ( nchan_transport > 6 ) { - sba_order = 3; + sba_order = SBA_HOA3_ORDER; } else if ( nchan_transport > 4 ) { - sba_order = 2; + sba_order = SBA_HOA2_ORDER; } return ( sba_order ); @@ -268,7 +286,7 @@ int16_t ivas_sba_get_nchan_metadata( { int16_t nb_channels; - if ( sba_order == 1 ) + if ( sba_order == SBA_FOA_ORDER ) { nb_channels = FOA_CHANNELS; } @@ -281,7 +299,6 @@ int16_t ivas_sba_get_nchan_metadata( return ( nb_channels ); } -#ifdef SBA_HOA_HBR_IMPROV /*-------------------------------------------------------------------* * ivas_sba_get_spar_hoa_md_flag() * @@ -307,7 +324,6 @@ int16_t ivas_sba_get_spar_hoa_md_flag( return spar_hoa_md_flag; } -#endif /*-------------------------------------------------------------------* * ivas_sba_zero_vert_comp() diff --git a/lib_com/ivas_spar_com.c b/lib_com/ivas_spar_com.c index b5821e4632..89b59d9392 100644 --- a/lib_com/ivas_spar_com.c +++ b/lib_com/ivas_spar_com.c @@ -1667,8 +1667,8 @@ void ivas_get_spar_md_from_dirac( remix_order = remix_order_set[hSpar_md_cfg->remix_unmix_order]; - num_ch = 2 * order + 2; - hoa2_ch = 6; + num_ch = ivas_sba_get_nchan_metadata( order ); + hoa2_ch = ivas_sba_get_nchan_metadata( SBA_HOA2_ORDER ); foa_ch = FOA_CHANNELS; diff_norm_order1 = 3.0f; diff_norm_order2 = 5.0f; @@ -1687,6 +1687,7 @@ void ivas_get_spar_md_from_dirac( { float P_norm[3]; int16_t idx; + ndm = hSpar_md_cfg->num_dmx_chans_per_band[start_band - 1]; P_norm[0] = 0.0f; for ( i = 0; i < max( 0, foa_ch - ndm ); i++ ) @@ -1737,11 +1738,6 @@ void ivas_get_spar_md_from_dirac( /*SPAR from DirAC*/ set_f( response_avg, 0.0f, MAX_OUTPUT_CHANNELS ); -#ifndef SBA_HOA_HBR_IMPROV - set_f( hSpar_md->band_coeffs[band + i_ts * IVAS_MAX_NUM_BANDS].pred_re, 0.0f, IVAS_SPAR_MAX_CH - 1 ); - set_f( &hSpar_md->band_coeffs[band + i_ts * IVAS_MAX_NUM_BANDS].C_re[0][0], 0.0f, ( IVAS_SPAR_MAX_CH - IVAS_SPAR_MAX_DMX_CHS ) * ( IVAS_SPAR_MAX_DMX_CHS - 1 ) ); - set_f( &hSpar_md->band_coeffs[band + i_ts * IVAS_MAX_NUM_BANDS].P_re[0], 0.0f, ( IVAS_SPAR_MAX_CH - 1 ) ); -#endif if ( n_ts > 1 ) { ivas_dirac_dec_get_response( (int16_t) azi_dirac[band][i_ts], (int16_t) ele_dirac[band][i_ts], response_avg, order ); @@ -1759,7 +1755,7 @@ void ivas_get_spar_md_from_dirac( int16_t num_ch_order, hoa2_ch_order; num_ch_order = ivas_sba_get_nchan( order, 0 ); - hoa2_ch_order = 9; + hoa2_ch_order = ivas_sba_get_nchan( SBA_HOA2_ORDER, 0 ); for ( ch = 0; ch < num_ch_order; ch++ ) { @@ -2114,17 +2110,7 @@ void ivas_spar_set_bitrate_config( pSpar_md_cfg->agc_bits_ch_idx = ivas_spar_br_table_consts[table_idx].agc_bits_ch_idx; ivas_spar_get_uniform_quant_strat( pSpar_md_cfg, table_idx ); - if ( pSpar_md_cfg->quant_strat->C.q_levels[0] == 0 || pSpar_md_cfg->quant_strat->C.q_levels[1] == 0 || pSpar_md_cfg->quant_strat->PR.q_levels[0] == 0 || pSpar_md_cfg->quant_strat->PR.q_levels[1] == 0 || pSpar_md_cfg->quant_strat->P_c.q_levels[0] == 0 || pSpar_md_cfg->quant_strat->P_c.q_levels[1] == 0 || pSpar_md_cfg->quant_strat->P_r.q_levels[0] == 0 || pSpar_md_cfg->quant_strat->P_r.q_levels[1] == 0 ) - { - pSpar_md_cfg->gen_bs = 0; - } - else - { - if ( 0 != pSpar_md_cfg->gen_bs ) - { - pSpar_md_cfg->quant_strat_bits = ivas_get_bits_to_encode( MAX_QUANT_STRATS ); - } - } + pSpar_md_cfg->quant_strat_bits = ivas_get_bits_to_encode( MAX_QUANT_STRATS ); /* BLOCK: getEntropyCoderModels */ @@ -2136,18 +2122,19 @@ void ivas_spar_set_bitrate_config( ivas_total_brate = ivas_spar_br_table_consts[table_idx].ivas_total_brate; sba_order = ivas_spar_br_table_consts[table_idx].sba_order; - ivas_get_spar_table_idx( ivas_total_brate, sba_order, ivas_spar_br_table_consts[table_idx].bwidth, &code, &length ); + ivas_get_spar_table_idx( ivas_total_brate, sba_order, ivas_spar_br_table_consts[table_idx].bwidth, &length, &code ); for ( i = 0; i < pSpar_md_cfg->nchan_transport; i++ ) { total_bits += (int16_t) ( ivas_spar_br_table_consts[table_idx].core_brs[i][0] / FRAMES_PER_SEC ); max_bits += (int16_t) ( ivas_spar_br_table_consts[table_idx].core_brs[i][1] / FRAMES_PER_SEC ); } - pSpar_md_cfg->tgt_bits_per_blk = (int16_t) ( ivas_total_brate / FRAMES_PER_SEC ) - IVAS_FORMAT_SIGNALING_NBITS_SBA - SBA_PLANAR_BITS - SBA_ORDER_BITS - length - total_bits; + pSpar_md_cfg->tgt_bits_per_blk = (int16_t) ( ivas_total_brate / FRAMES_PER_SEC ) - IVAS_FORMAT_SIGNALING_NBITS_SBA - SBA_PLANAR_BITS - SBA_ORDER_BITS - length - total_bits; pSpar_md_cfg->max_bits_per_blk = (int16_t) ( ivas_total_brate / FRAMES_PER_SEC ) - IVAS_FORMAT_SIGNALING_NBITS_SBA - SBA_PLANAR_BITS - SBA_ORDER_BITS - length - max_bits; md_coding_bits_header = SPAR_NUM_CODING_STRAT_BITS + pSpar_md_cfg->quant_strat_bits; + pSpar_md_cfg->tgt_bits_per_blk -= md_coding_bits_header; pSpar_md_cfg->max_bits_per_blk -= md_coding_bits_header; @@ -2156,9 +2143,11 @@ void ivas_spar_set_bitrate_config( pSpar_md_cfg->tgt_bits_per_blk += md_coding_bits_header; pSpar_md_cfg->max_bits_per_blk += md_coding_bits_header; + return; } + #ifdef FIX_I1_113 /*-----------------------------------------------------------------------------------------* * Function ivas_spar_bitrate_dist() diff --git a/lib_com/ivas_stat_com.h b/lib_com/ivas_stat_com.h index 026191559b..8dd59f1d18 100644 --- a/lib_com/ivas_stat_com.h +++ b/lib_com/ivas_stat_com.h @@ -229,7 +229,6 @@ typedef struct ivas_spar_md_com_cfg int16_t active_w; int16_t remix_unmix_order; ivas_quant_strat_t quant_strat[MAX_QUANT_STRATS]; - int16_t gen_bs; int16_t quant_strat_bits; int16_t nchan_transport; int16_t num_quant_strats; @@ -352,15 +351,6 @@ typedef struct ivas_cov_smooth_cfg_t } ivas_cov_smooth_cfg_t; -#ifndef SBA_SPAR_HARM -typedef struct ivas_cov_smooth_in_buf_t -{ - float *cov_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH]; - int16_t num_ch; - int16_t reset_cov; - -} ivas_cov_smooth_in_buf_t; -#endif /* SPAR bitrate constant table structure */ typedef struct ivas_spar_br_table_t diff --git a/lib_com/ivas_stereo_psychlpc_com.c b/lib_com/ivas_stereo_psychlpc_com.c index 3cbca73cc0..8a50caaa29 100644 --- a/lib_com/ivas_stereo_psychlpc_com.c +++ b/lib_com/ivas_stereo_psychlpc_com.c @@ -68,14 +68,14 @@ static void SpectrumWeighting_Init( * initialize a PsychoacousticParameters structure *-------------------------------------------------------------------*/ - ivas_error - PsychoacousticParameters_Init( - const int32_t sr_core, /* i : sampling rate of core-coder */ - const int16_t nBins, /* i : Number of bins (spectral lines) */ - const int8_t nBands, /* i : Number of spectrum subbands */ - const int16_t isTCX20, /* i : Flag indicating if the subband division is for TCX20 or TCX10 */ - const int16_t isWarped, /* i : Flag indicating if the scale is linear or warped */ - PsychoacousticParameters *pPsychParams ) +ivas_error +PsychoacousticParameters_Init( + const int32_t sr_core, /* i : sampling rate of core-coder */ + const int16_t nBins, /* i : Number of bins (spectral lines) */ + const int8_t nBands, /* i : Number of spectrum subbands */ + const int16_t isTCX20, /* i : Flag indicating if the subband division is for TCX20 or TCX10 */ + const int16_t isWarped, /* i : Flag indicating if the scale is linear or warped */ + PsychoacousticParameters *pPsychParams ) { if ( pPsychParams == NULL ) diff --git a/lib_com/options.h b/lib_com/options.h index 884fb23615..71b4d7f6f0 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -126,6 +126,7 @@ #endif /*#define SPAR_HOA_DBG*/ /* SPAR HOA debug statements */ /*#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 */ #endif /* #################### End DEBUGGING switches ############################ */ @@ -143,25 +144,25 @@ /*#define ITD_WINNER_GAIN_MODIFY */ /* ITD optimization - WORK IN PROGRESS */ /*#define FIX_I4_OL_PITCH*/ /* fix open-loop pitch used for EVS core switching */ /*#define FIX_I1_113*/ /* under review : MCT bit distribution optimization for SBA high bitrates*/ - -#define FIX_I13_TCX_TNS_ISSUE /* Issue 13: Fix reported artifacts. Bug in TNS with TCX5 */ -#define FIX_TCX10_STEREO_PROC /* Issue 11 */ -#define CORECODER_BITRATE_SWITCHING /* Issue 133: support bitrate switching in core-coder */ -#define ISM_BITRATE_SWITCHING /* Issue 115: Support for Bitrate Switching in ISM */ -#define SBA_SPAR_HARM /* Issue 92: maintenance of the SBA SPAR functions */ -#define FIX_155_HP20_ISSUE /* Issue 155: apply hp20 on all input channels instead of just 2 channels */ -#define EFAP_FIX_POLY /* Issue 167: fix bug in EFAP polygon selection */ -#define SBA_HOA_HBR_IMPROV /* issue 91: Improvements to SBA high bitrate HOA3 coding */ -#define ALLRAD_OPTIM /* Issue 159: Optimize memory allocation for ALLRAD */ -#define FIX_I178_HQ_BUFFER_OVERRUN /* issue 178: Buffer overrun in HQ core decoder -- spectral filling buffer did not account for extended transition frame in IVAS */ #define PRINT_SBA_ORDER /* Issue 179: print-out also the SBA order of IVAS SBA format to stdout */ #define EXT_RENDERER /* FhG: external renderer library and standalone application */ #define FIX_EFAP_MATH /* fix for EFAP: remove angle quantization and a bug in polygon lookup causing incorrect gains. minor tweak for ALLRAD. non-BE for modes using EFAP */ +#define SPAR_STEREO_NO_DIRAC /* Issue 180: skip DirAC processing channels for stereo output */ #define AGC_TUNING_IMPROVEMENT /* Issue 168: Enable AGC for low bit rate (1 TC) */ #ifdef AGC_TUNING_IMPROVEMENT #define AGC_ENABLE_FOR_LBR /* Issue 168: Enable AGC for low bit rate (1 TC) */ #endif +#define FIX_I173_I174 /* Issues 173 and 174: Remove frame and subframe index from ISm metadata and headtracking respectively. */ +#define FIX_TCX_DEC_RECONF_BFI +#define FIX_SBA_DTX_DECODE_ERROR /* Issue 176: SBA decoder error with DTX at 80kbps SWB, Issue 21: SBA front-VAD threshold (203) */ +#define FIX_124_DONT_ALLOC_PLCINFO_IN_IVAS /* Issue 124: do not allocate unused plc struct in IVAS modes which is only used in EVS mono */ +/*#define FIX_MCT_PLC_RECOVERY*/ /* Issue 184: scale the old synthesis part correctly in the first good frame after lost frames in MCT modes - to be activated after previous switch is merged */ +#define FIX_MSAN_ERROR_STEREO_RATE_SWITCHING /* addresses Issue 177 */ +#define SBA_BR_SWITCHING /* Issue 114: Changes for sba bit rate switching*/ +#define FIX_AGC_WINFUNC_MEMORY /* Issue 62: lower agc_com.winFunc memory consumption */ + + /* ################## End DEVELOPMENT switches ######################### */ /* clang-format on */ diff --git a/lib_com/vlpc_2st_com.c b/lib_com/vlpc_2st_com.c index f027ecd8ea..86fdf68c5f 100644 --- a/lib_com/vlpc_2st_com.c +++ b/lib_com/vlpc_2st_com.c @@ -52,8 +52,7 @@ void lsf_weight_2st( const float *lsfq, float *w, const int16_t mode, - const int32_t sr_core -) + const int32_t sr_core ) { int16_t i; float d[M + 1]; diff --git a/lib_debug/mem_count.c b/lib_debug/mem_count.c index b12639ae3f..ca4832399f 100644 --- a/lib_debug/mem_count.c +++ b/lib_debug/mem_count.c @@ -93,8 +93,11 @@ typedef INT64 int64_t; /* This is the maximum number of allocations for which to keep information. It can be increased if required. */ +#ifdef SBA_BR_SWITCHING +#define MAX_INFO_RECORDS 8000 +#else #define MAX_INFO_RECORDS 3000 - +#endif /* This is the length after which the function name will be truncated when the summary is printed. */ #define MAX_FUNCTION_NAME_LENGTH 18 diff --git a/lib_dec/dec_tcx.c b/lib_dec/dec_tcx.c index c74564e1f7..20e4dedbe3 100644 --- a/lib_dec/dec_tcx.c +++ b/lib_dec/dec_tcx.c @@ -152,7 +152,11 @@ void decoder_tcx_post( if ( bfi && !st->use_partial_copy ) { /* run lpc gain compensation not for waveform adjustment */ +#ifdef FIX_124_DONT_ALLOC_PLCINFO_IN_IVAS + if ( !st->enablePlcWaveadjust || ( st->hPlcInfo != NULL && st->hPlcInfo->concealment_method == TCX_TONAL ) ) +#else if ( !st->enablePlcWaveadjust || st->hPlcInfo->concealment_method == TCX_TONAL ) +#endif { float gainHelperFB = hTcxDec->gainHelper; float stepCompensateFB = hTcxDec->stepCompensate * st->L_frame / hTcxDec->L_frameTCX; @@ -1465,12 +1469,6 @@ void decoder_tcx_tns( isTCX5 = 1; tcx5SpectrumDeinterleaving( L >> 1, x ); -#ifndef FIX_I13_TCX_TNS_ISSUE - if ( hTcxCfg->fIsTNSAllowed && fUseTns != 0 && bfi != 1 && tnsData->tnsOnWhitenedSpectra == whitenedDomain ) - { - tcx5TnsGrouping( L >> 1, hTcxCfg->tnsConfig[0][0].iFilterBorders[0] >> 1, x ); - } -#endif } } @@ -1488,12 +1486,10 @@ void decoder_tcx_tns( /* Apply TNS to get the reconstructed signal */ SetTnsConfig( hTcxCfg, L_frame_glob == st->L_frame, ( st->last_core == ACELP_CORE ) && ( frame_cnt == 0 ) ); -#ifdef FIX_I13_TCX_TNS_ISSUE if ( ( L_frame == st->L_frame >> 1 ) && st->tcxonly && isTCX5 ) { tcx5TnsGrouping( L >> 1, hTcxCfg->tnsConfig[0][0].iFilterBorders[0] >> 1, x ); } -#endif ApplyTnsFilter( hTcxCfg->pCurrentTnsConfig, tnsData, x, 0 ); #ifdef DEBUG_PLOT @@ -1502,9 +1498,6 @@ void decoder_tcx_tns( if ( ( L_frame == st->L_frame >> 1 ) && st->tcxonly && isTCX5 ) { -#ifndef FIX_I13_TCX_TNS_ISSUE - tcx5TnsUngrouping( L_frameTCX >> 1, hTcxCfg->tnsConfig[0][0].iFilterBorders[0] >> 1, x, DEC ); -#else if ( st->element_mode == EVS_MONO || L_spec < L_frameTCX ) /* TBC: this is temporary to maintain EVS BE, this is a bug and should be fixed also for EVS (see issue 13) */ { tcx5TnsUngrouping( L_frameTCX >> 1, hTcxCfg->tnsConfig[0][0].iFilterBorders[0] >> 1, x, DEC ); @@ -1513,7 +1506,6 @@ void decoder_tcx_tns( { tcx5TnsUngrouping( L >> 1, hTcxCfg->tnsConfig[0][0].iFilterBorders[0] >> 1, x, DEC ); } -#endif } } diff --git a/lib_dec/igf_dec.c b/lib_dec/igf_dec.c index f876391b2d..2cded75928 100644 --- a/lib_dec/igf_dec.c +++ b/lib_dec/igf_dec.c @@ -679,8 +679,8 @@ static void IGF_appl( float *pSpectralData, /* i/o: Q31 | MDCT spectrum */ const float *igf_spec, /* i : Q31 | prepared IGF spectrum */ float *virtualSpec, /* o : Q31 | virtual IGF spectrum, used for temp flattening */ - int16_t *flag_sparse, /* o : Q0 | temp flattening indicator */ - const int16_t bfi_apply_damping /* i : flag to indicate if damping for lost frames should be applied */ + int16_t *flag_sparse, /* o : Q0 | temp flattening indicator */ + const int16_t bfi_apply_damping /* i : flag to indicate if damping for lost frames should be applied */ ) { H_IGF_GRID hGrid; @@ -1240,8 +1240,7 @@ void IGFDecApplyStereo( const int16_t *coreMsMask, const int16_t restrict_hopsize, const int16_t bfi, /* i : frame loss == 1, frame good == 0 */ - const int16_t bfi_apply_damping -) + const int16_t bfi_apply_damping ) { IGF_DEC_PRIVATE_DATA_HANDLE hPrivateDataL, hPrivateDataR; H_IGF_GRID hGrid; diff --git a/lib_dec/init_dec.c b/lib_dec/init_dec.c index 4f022e2811..4b74ccebb9 100644 --- a/lib_dec/init_dec.c +++ b/lib_dec/init_dec.c @@ -661,7 +661,11 @@ ivas_error init_decoder( * Mode 2 initialization *-----------------------------------------------------------------*/ +#ifdef FIX_124_DONT_ALLOC_PLCINFO_IN_IVAS + if ( st->element_mode == EVS_MONO ) +#else if ( idchan == 0 && st->element_mode != IVAS_CPE_MDCT ) +#endif { if ( ( st->hPlcInfo = (T_PLCInfo_HANDLE) count_malloc( sizeof( T_PLCInfo ) ) ) == NULL ) { @@ -685,8 +689,9 @@ ivas_error init_decoder( st->hTECDec = NULL; } +#ifndef FIX_124_DONT_ALLOC_PLCINFO_IN_IVAS // the initialziation is done in open_decoder_LPD() st->enablePlcWaveadjust = 0; - +#endif /* Init Core Decoder */ open_decoder_LPD( st, st->total_brate, st->last_total_brate, st->bwidth, 0, st->element_mode, 1 ); diff --git a/lib_dec/ivas_agc_dec.c b/lib_dec/ivas_agc_dec.c index 81039651d8..e522574bb2 100644 --- a/lib_dec/ivas_agc_dec.c +++ b/lib_dec/ivas_agc_dec.c @@ -98,7 +98,11 @@ ivas_error ivas_spar_agc_dec_open( ) { ivas_agc_dec_state_t *hAgc; +#ifdef FIX_AGC_WINFUNC_MEMORY + int16_t output_frame, delay; +#else int16_t output_frame; +#endif if ( ( hAgc = (ivas_agc_dec_state_t *) count_malloc( sizeof( ivas_agc_dec_state_t ) ) ) == NULL ) { @@ -106,8 +110,15 @@ ivas_error ivas_spar_agc_dec_open( } output_frame = (int16_t) ( output_Fs / FRAMES_PER_SEC ); +#ifdef FIX_AGC_WINFUNC_MEMORY + delay = NS2SA( output_Fs, ( IVAS_ENC_DELAY_NS + IVAS_DEC_DELAY_NS ) ); +#endif +#ifdef FIX_AGC_WINFUNC_MEMORY + if ( ( hAgc->agc_com.winFunc = (float *) count_malloc( sizeof( float ) * ( output_frame - delay ) ) ) == NULL ) +#else if ( ( hAgc->agc_com.winFunc = (float *) count_malloc( sizeof( float ) * output_frame ) ) == NULL ) +#endif { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for AGC decoder" ); } @@ -122,7 +133,11 @@ ivas_error ivas_spar_agc_dec_open( return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for AGC decoder" ); } +#ifdef FIX_AGC_WINFUNC_MEMORY + ivas_agc_dec_init( hAgc, output_frame, delay ); +#else ivas_agc_dec_init( hAgc, output_frame, NS2SA( output_Fs, ( IVAS_ENC_DELAY_NS + IVAS_DEC_DELAY_NS ) ) ); +#endif *hAgcDec = hAgc; diff --git a/lib_dec/ivas_core_dec.c b/lib_dec/ivas_core_dec.c index fd5d5b3c1e..5c189b7d32 100644 --- a/lib_dec/ivas_core_dec.c +++ b/lib_dec/ivas_core_dec.c @@ -181,13 +181,32 @@ ivas_error ivas_core_dec( st->flagGuidedAcelp = 0; } +#ifdef FIX_124_DONT_ALLOC_PLCINFO_IN_IVAS +#ifdef FIX_MCT_PLC_RECOVERY + if ( !st->bfi && st->prev_bfi && ( st->last_core_bfi == TCX_20_CORE || st->last_core_bfi == TCX_10_CORE ) && st->hTcxDec != NULL ) +#else + if ( !st->bfi && st->prev_bfi && ( st->last_core_bfi == TCX_20_CORE || st->last_core_bfi == TCX_10_CORE ) && st->hTcxDec != NULL && hMCT == NULL ) +#endif + { + float gain; + + gain = st->hTcxDec->conceal_eof_gain * st->last_concealed_gain_syn_deemph; + v_multc( st->hHQ_core->old_out, gain, st->hHQ_core->old_out, st->hTcxDec->L_frameTCX ); + v_multc( st->hHQ_core->old_outLB, gain, st->hHQ_core->old_outLB, st->L_frame ); + + if ( !st->hTcxCfg->last_aldo ) + { + v_multc( st->hTcxDec->syn_OverlFB, gain, st->hTcxDec->syn_OverlFB, st->hTcxCfg->tcx_mdct_window_lengthFB ); + v_multc( st->hTcxDec->syn_Overl, gain, st->hTcxDec->syn_Overl, st->hTcxCfg->tcx_mdct_window_length ); + } + } +#else /* PLC: [TCX: Fade-out-recovery] - overlapping part needs to be attenuated for first good frame */ if ( !st->bfi && st->prev_bfi && ( st->last_core_bfi == TCX_20_CORE || st->last_core_bfi == TCX_10_CORE ) ) { float gain; - gain = ( st->element_mode == IVAS_CPE_MDCT ) ? st->hTcxDec->conceal_eof_gain : - ( st->hPlcInfo != NULL ) ? st->hPlcInfo->recovery_gain : 0.0f; + gain = ( st->element_mode == IVAS_CPE_MDCT ) ? st->hTcxDec->conceal_eof_gain : ( st->hPlcInfo != NULL ) ? st->hPlcInfo->recovery_gain : 0.0f; if ( ( st->element_mode == IVAS_CPE_MDCT && hMCT == NULL ) || ( st->hPlcInfo != NULL ) ) { @@ -201,6 +220,7 @@ ivas_error ivas_core_dec( } } } +#endif set_f( voice_factors[n], 0.f, NB_SUBFR16k ); set_f( hb_synth[n], 0.0f, L_FRAME48k ); diff --git a/lib_dec/ivas_corecoder_dec_reconfig.c b/lib_dec/ivas_corecoder_dec_reconfig.c index cebd170100..b11ba6cd39 100644 --- a/lib_dec/ivas_corecoder_dec_reconfig.c +++ b/lib_dec/ivas_corecoder_dec_reconfig.c @@ -46,7 +46,6 @@ #include "wmops.h" -#ifdef CORECODER_BITRATE_SWITCHING /*-------------------------------------------------------------------* * ivas_corecoder_dec_reconfig() * @@ -272,9 +271,7 @@ ivas_error ivas_corecoder_dec_reconfig( *-----------------------------------------------------------------*/ /// VE: this could be merged with part of ivas_init_decoder() -#ifdef ISM_BITRATE_SWITCHING if ( st_ivas->ivas_format == SBA_FORMAT ) -#endif { if ( st_ivas->sba_mode == SBA_MODE_SPAR && st_ivas->nchan_transport == 1 ) { @@ -401,4 +398,3 @@ ivas_error ivas_hp20_dec_reconfig( return error; } -#endif diff --git a/lib_dec/ivas_dirac_dec.c b/lib_dec/ivas_dirac_dec.c index ec9a712065..d7feb33256 100644 --- a/lib_dec/ivas_dirac_dec.c +++ b/lib_dec/ivas_dirac_dec.c @@ -234,13 +234,13 @@ ivas_error ivas_dirac_dec_config( if ( hDirAC->hOutSetup.ambisonics_order == -1 ) { - hDirAC->hOutSetup.ambisonics_order = 3; /* Order 3 is used by default in DirAC for SHD processing */ + hDirAC->hOutSetup.ambisonics_order = SBA_HOA3_ORDER; /* Order 3 is used by default in DirAC for SHD processing */ if ( hDirAC->hOutSetup.output_config == AUDIO_CONFIG_MONO || hDirAC->hOutSetup.output_config == AUDIO_CONFIG_STEREO ) { - hDirAC->hOutSetup.ambisonics_order = 1; + hDirAC->hOutSetup.ambisonics_order = SBA_FOA_ORDER; } } - else if ( hDirAC->hOutSetup.ambisonics_order >= 1 ) + else if ( hDirAC->hOutSetup.ambisonics_order >= SBA_FOA_ORDER ) { mvr2r( ls_azimuth_4d4, ls_azimuth, DIRAC_HOA_RENDERING_NUM_VIRT_DECORR_LS ); mvr2r( ls_elevation_4d4, ls_elevation, DIRAC_HOA_RENDERING_NUM_VIRT_DECORR_LS ); diff --git a/lib_dec/ivas_dirac_dec_binaural_functions.c b/lib_dec/ivas_dirac_dec_binaural_functions.c index ca9f0a4587..1418193139 100644 --- a/lib_dec/ivas_dirac_dec_binaural_functions.c +++ b/lib_dec/ivas_dirac_dec_binaural_functions.c @@ -29,7 +29,7 @@ the United Nations Convention on Contracts on the International Sales of Goods. *******************************************************************************************************/ - +// VE2AT: move to lib_rend ? #include #include "options.h" #include @@ -37,7 +37,7 @@ #include "prot.h" #include "ivas_prot.h" #include "ivas_cnst.h" -#include "ivas_rom_binauralRenderer.h" +#include "ivas_rom_binauralRenderer.h" // VE2AT: what about to put these includes ust into ivas_rom_rend.c ? #include "ivas_rom_dec.h" #ifdef DEBUGGING #include "debug.h" diff --git a/lib_dec/ivas_init_dec.c b/lib_dec/ivas_init_dec.c index e3849dfbe0..5cc318b86f 100644 --- a/lib_dec/ivas_init_dec.c +++ b/lib_dec/ivas_init_dec.c @@ -69,7 +69,6 @@ ivas_error ivas_dec_setup( Decoder_State *st; int32_t ivas_total_brate; ivas_error error; - error = IVAS_ERR_OK; num_bits_read = 0; @@ -128,10 +127,24 @@ ivas_error ivas_dec_setup( num_bits_read += SBA_ORDER_BITS; if ( st_ivas->ini_frame > 0 && ivas_total_brate != st_ivas->hDecoderConfig->last_ivas_total_brate && ivas_total_brate > IVAS_SID_5k2 ) { - if ( ( error = ivas_sba_dec_reconfigure( st_ivas ) ) != IVAS_ERR_OK ) +#ifdef SBA_BR_SWITCHING + if ( get_sba_reinit_flag( ivas_total_brate, st_ivas->hDecoderConfig->last_ivas_total_brate ) ) { - return error; + if ( ( error = ivas_sba_dec_reinit( st_ivas ) ) != IVAS_ERR_OK ) + { + return error; + } + } + else + { +#endif + if ( ( error = ivas_sba_dec_reconfigure( st_ivas ) ) != IVAS_ERR_OK ) + { + return error; + } +#ifdef SBA_BR_SWITCHING } +#endif } else { @@ -410,7 +423,7 @@ static ivas_error ivas_read_format( // TBD: needs more work for HOA if ( st_ivas->sba_analysis_order == 0 ) { - st_ivas->sba_analysis_order = 1; + st_ivas->sba_analysis_order = SBA_FOA_ORDER; } if ( idx == 1 ) { @@ -790,7 +803,11 @@ ivas_error ivas_init_decoder( return error; } - if ( hDecoderConfig->output_config != AUDIO_CONFIG_FOA ) + if ( hDecoderConfig->output_config != AUDIO_CONFIG_FOA +#ifdef SPAR_STEREO_NO_DIRAC + && st_ivas->hDecoderConfig->output_config != AUDIO_CONFIG_STEREO && st_ivas->hDecoderConfig->output_config != AUDIO_CONFIG_MONO +#endif + ) { if ( ( error = ivas_dirac_dec_open( st_ivas ) ) != IVAS_ERR_OK ) { @@ -887,9 +904,7 @@ ivas_error ivas_init_decoder( } st_ivas->hCPE[0]->hCoreCoder[0] = st_ivas->hSCE[0]->hCoreCoder[0]; /* don't allocate unnecessary core coder, simply point to core coder of SCE element */ -#ifdef CORECODER_BITRATE_SWITCHING st_ivas->hCPE[0]->hCoreCoder[1] = NULL; -#endif } if ( st_ivas->nCPE > 1 ) @@ -1087,9 +1102,7 @@ ivas_error ivas_init_decoder( } st_ivas->hCPE[0]->hCoreCoder[0] = st_ivas->hSCE[0]->hCoreCoder[0]; /* don't allocate unnecessary core coder, simply point to core coder of SCE element */ -#ifdef CORECODER_BITRATE_SWITCHING st_ivas->hCPE[0]->hCoreCoder[1] = NULL; -#endif } /* set CNA/CNG flags */ diff --git a/lib_dec/ivas_ism_param_dec.c b/lib_dec/ivas_ism_param_dec.c index c6c1f99c9c..8ebf27afb5 100644 --- a/lib_dec/ivas_ism_param_dec.c +++ b/lib_dec/ivas_ism_param_dec.c @@ -1004,7 +1004,6 @@ void ivas_param_ism_params_to_masa_param_mapping( } -#ifdef ISM_BITRATE_SWITCHING /*-------------------------------------------------------------------------* * ivas_ism_bitrate_switching() * @@ -1018,9 +1017,6 @@ static ivas_error ivas_ism_bitrate_switching( const int16_t num_obj /* i : number of objects in the bitstream */ ) { -#ifndef CORECODER_BITRATE_SWITCHING - int16_t sce_id; -#endif ivas_error error; int32_t element_brate_tmp[MAX_NUM_OBJECTS]; @@ -1029,85 +1025,9 @@ static ivas_error ivas_ism_bitrate_switching( ivas_ism_config( st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->nchan_transport, num_obj, NULL, NULL, NULL, element_brate_tmp, NULL, NULL ); st_ivas->nSCE = st_ivas->nchan_transport; -#ifdef CORECODER_BITRATE_SWITCHING ivas_corecoder_dec_reconfig( st_ivas, nchan_transport_old, 0, nchan_transport_old, 0 ); -#else - if ( st_ivas->nchan_transport > nchan_transport_old ) - { - /* Initialize for new bitrate */ - for ( sce_id = 0; sce_id < nchan_transport_old; sce_id++ ) - { - st_ivas->hSCE[sce_id]->element_brate = st_ivas->hDecoderConfig->ivas_total_brate / st_ivas->nchan_transport; - st_ivas->hSCE[sce_id]->hCoreCoder[0]->total_brate = st_ivas->hSCE[sce_id]->element_brate; /* dummy initialization for getting right pointers initialization of input buffers in init_coder_ace_plus() */ - } - /* Initialize some memories */ - for ( sce_id = nchan_transport_old; sce_id < st_ivas->nchan_transport; sce_id++ ) - { - if ( ( error = create_sce_dec( st_ivas, sce_id, element_brate_tmp[sce_id] ) ) != IVAS_ERR_OK ) - { - return error; - } - } - } - else - { - /* Initialize for new bitrate */ - for ( sce_id = 0; sce_id < st_ivas->nchan_transport; sce_id++ ) - { - st_ivas->hSCE[sce_id]->element_brate = st_ivas->hDecoderConfig->ivas_total_brate / st_ivas->nchan_transport; - st_ivas->hSCE[sce_id]->hCoreCoder[0]->total_brate = st_ivas->hSCE[sce_id]->element_brate; /* dummy initialization for getting right pointers initialization of input buffers in init_coder_ace_plus() */ - } - - /* Destroy the core coder memory */ - for ( ; sce_id < nchan_transport_old; sce_id++ ) - { - destroy_sce_dec( st_ivas->hSCE[sce_id] ); - st_ivas->hSCE[sce_id] = NULL; - } - } -#endif - -#ifdef CORECODER_BITRATE_SWITCHING ivas_hp20_dec_reconfig( st_ivas, nchan_transport_old ); -#else - /* destroy the memory of hp20*/ - if ( st_ivas->mem_hp20_out != NULL ) - { - for ( sce_id = 0; sce_id < nchan_transport_old; sce_id++ ) - { - count_free( st_ivas->mem_hp20_out[sce_id] ); - st_ivas->mem_hp20_out[sce_id] = NULL; - } - count_free( st_ivas->mem_hp20_out ); - st_ivas->mem_hp20_out = NULL; - } - - /* re initialize the memory of hp20 */ - /* set number of input channels used for analysis/coding */ - - if ( st_ivas->nchan_transport > 0 ) - { - if ( ( st_ivas->mem_hp20_out = (float **) count_malloc( st_ivas->nchan_transport * sizeof( float * ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for HP20 filter memory\n" ) ); - } - } - else - { - st_ivas->mem_hp20_out = NULL; - } - - for ( sce_id = 0; sce_id < st_ivas->nchan_transport; sce_id++ ) - { - if ( ( st_ivas->mem_hp20_out[sce_id] = (float *) count_malloc( L_HP20_MEM * sizeof( float ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for HP20 filter memory\n" ) ); - } - - set_f( st_ivas->mem_hp20_out[sce_id], 0.0f, L_HP20_MEM ); - } -#endif /* Initialize the needed renderer struct and destroy the unnecessary renderer struct */ @@ -1215,7 +1135,6 @@ static ivas_error ivas_ism_bitrate_switching( return error; } -#endif /*------------------------------------------------------------------------- * ivas_ism_dec_config() @@ -1233,9 +1152,7 @@ ivas_error ivas_ism_dec_config( int32_t ivas_total_brate; ISM_MODE last_ism_mode; ivas_error error; -#ifdef ISM_BITRATE_SWITCHING int16_t nchan_transport_old; -#endif error = IVAS_ERR_OK; @@ -1243,14 +1160,12 @@ ivas_error ivas_ism_dec_config( /* store last frame ISM mode */ last_ism_mode = st_ivas->ism_mode; -#ifdef ISM_BITRATE_SWITCHING /* Assumes that num of input objects are constant */ nchan_transport_old = num_obj; if ( last_ism_mode == ISM_MODE_PARAM ) { nchan_transport_old = 2; } -#endif if ( !st_ivas->bfi && ivas_total_brate != IVAS_SID_5k2 && ivas_total_brate != FRAME_NO_DATA ) { @@ -1269,7 +1184,6 @@ ivas_error ivas_ism_dec_config( if ( st_ivas->ini_active_frame != 0 ) { -#ifdef ISM_BITRATE_SWITCHING /* ISM bit-rate switching */ if ( st_ivas->hDecoderConfig->last_ivas_total_brate != IVAS_SID_5k2 && st_ivas->hDecoderConfig->last_ivas_total_brate != FRAME_NO_DATA ) { @@ -1278,14 +1192,6 @@ ivas_error ivas_ism_dec_config( ivas_ism_bitrate_switching( st_ivas, nchan_transport_old, last_ism_mode, num_obj ); } } -#else - /* ISM format switching */ - if ( st_ivas->ism_mode != last_ism_mode ) - { - /*ivas_ism_dec_reconfigure( st_ivas );*/ - return IVAS_ERROR( IVAS_ERR_RECONFIGURE_NOT_SUPPORTED, "\n\n!!! Error: ISM format switching not supported yet!!!\n\n" ); - } -#endif } } else if ( !st_ivas->bfi && ivas_total_brate == IVAS_SID_5k2 ) diff --git a/lib_dec/ivas_ism_renderer.c b/lib_dec/ivas_ism_renderer.c index 0e7f5f864a..f27d49b111 100644 --- a/lib_dec/ivas_ism_renderer.c +++ b/lib_dec/ivas_ism_renderer.c @@ -29,7 +29,7 @@ the United Nations Convention on Contracts on the International Sales of Goods. *******************************************************************************************************/ - +// VE2AT: move to lib_rend ? #include #include "options.h" #include "ivas_cnst.h" diff --git a/lib_dec/ivas_mct_dec_mct.c b/lib_dec/ivas_mct_dec_mct.c index 2dd7b18d52..6b8f9b74fa 100644 --- a/lib_dec/ivas_mct_dec_mct.c +++ b/lib_dec/ivas_mct_dec_mct.c @@ -220,11 +220,7 @@ void apply_MCT_dec( { hBlock = hMCT->hBlockData[pair]; -#ifdef FIX_TCX10_STEREO_PROC stereo_decoder_tcx( hBlock->hStereoMdct, hBlock->mask, &x[hBlock->ch2][0], &x[hBlock->ch1][0], &x[hBlock->ch2][0], hBlock->hStereoMdct->mdct_stereo_mode, sts[hBlock->ch1]->core, sts[hBlock->ch2]->core, sts[0]->igf, sts[0]->hTcxDec->L_frameTCX, sts[1]->hTcxDec->L_frameTCX, 1, TCX_20_CORE, TCX_20_CORE, 0 ); -#else - stereo_decoder_tcx( hBlock->hStereoMdct, hBlock->mask, &x[hBlock->ch2][0], &x[hBlock->ch1][0], &x[hBlock->ch2][0], hBlock->hStereoMdct->mdct_stereo_mode, sts[hBlock->ch1]->core, sts[hBlock->ch2]->core, sts[0]->igf, sts[0]->hTcxDec->L_frameTCX, 1, TCX_20_CORE, TCX_20_CORE, 0 ); -#endif } applyGlobalILD( sts, hMCT, x ); diff --git a/lib_dec/ivas_mdct_core_dec.c b/lib_dec/ivas_mdct_core_dec.c index 748475dc5c..3e186d61b8 100644 --- a/lib_dec/ivas_mdct_core_dec.c +++ b/lib_dec/ivas_mdct_core_dec.c @@ -494,16 +494,10 @@ void ivas_mdct_core_invQ( if ( bfi && !MCT_flag && ( hCPE->hStereoMdct->mdct_stereo_mode[0] > SMDCT_DUAL_MONO || hCPE->hStereoMdct->mdct_stereo_mode[1] > SMDCT_DUAL_MONO ) ) { L_frameTCX[0] = sts[0]->L_frameTCX_past; -#ifdef FIX_TCX10_STEREO_PROC L_frameTCX[1] = sts[1]->L_frameTCX_past; -#endif mvr2r( sts[0]->hTonalMDCTConc->lastBlockData.spectralData, tmp_ms_sig[0], L_frameTCX[0] ); mvr2r( sts[1]->hTonalMDCTConc->lastBlockData.spectralData, tmp_ms_sig[1], L_frameTCX[0] ); -#ifdef FIX_TCX10_STEREO_PROC stereo_decoder_tcx( hCPE->hStereoMdct, ms_mask, x_0[1], &sts[0]->hTonalMDCTConc->lastBlockData.spectralData, &sts[1]->hTonalMDCTConc->lastBlockData.spectralData, &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, 1 ); -#else - stereo_decoder_tcx( hCPE->hStereoMdct, ms_mask, x_0[1], &sts[0]->hTonalMDCTConc->lastBlockData.spectralData, &sts[1]->hTonalMDCTConc->lastBlockData.spectralData, &hCPE->hStereoMdct->mdct_stereo_mode[0], sts[0]->core, sts[1]->core, sts[0]->igf, L_frameTCX[0], 0, sts[0]->last_core, sts[1]->last_core, 1 ); -#endif } if ( bfi ) diff --git a/lib_dec/ivas_mono_dmx_renderer.c b/lib_dec/ivas_mono_dmx_renderer.c index 468b0215b0..20b677075e 100644 --- a/lib_dec/ivas_mono_dmx_renderer.c +++ b/lib_dec/ivas_mono_dmx_renderer.c @@ -29,7 +29,7 @@ the United Nations Convention on Contracts on the International Sales of Goods. *******************************************************************************************************/ - +// VE2AT: move to lib_rend ? #include #include "options.h" #include diff --git a/lib_dec/ivas_out_setup_conversion.c b/lib_dec/ivas_out_setup_conversion.c index 9ed27e56c3..55f53bae73 100644 --- a/lib_dec/ivas_out_setup_conversion.c +++ b/lib_dec/ivas_out_setup_conversion.c @@ -29,7 +29,7 @@ the United Nations Convention on Contracts on the International Sales of Goods. *******************************************************************************************************/ - +// VE2AT: move to lib_rend ? #include #include #include "options.h" diff --git a/lib_dec/ivas_post_proc.c b/lib_dec/ivas_post_proc.c index a295a8b2a2..b2cc27d5ef 100644 --- a/lib_dec/ivas_post_proc.c +++ b/lib_dec/ivas_post_proc.c @@ -478,7 +478,11 @@ void stereo_dft_dec_core_switching( mvr2r( output, pAp_input, st->L_frame ); } +#ifdef FIX_MSAN_ERROR_STEREO_RATE_SWITCHING + if ( st->last_core == ACELP_CORE && !( st->prev_bfi == 1 && st->last_core == ACELP_CORE && st->last_con_tcx == 1 ) && !st->tcxonly ) /* ACELP -> TCX/HQ-Core */ +#else if ( st->last_core == ACELP_CORE && !( st->prev_bfi == 1 && st->last_core == ACELP_CORE && st->last_con_tcx == 1 ) ) /* ACELP -> TCX/HQ-Core */ +#endif { mvr2r( tcx_core_buf, tmp_fade, ap_fade_len ); for ( i = 0; i < ap_fade_len; i++ ) diff --git a/lib_dec/ivas_rom_dec.c b/lib_dec/ivas_rom_dec.c index 3a08c33e79..c79bc38019 100644 --- a/lib_dec/ivas_rom_dec.c +++ b/lib_dec/ivas_rom_dec.c @@ -516,7 +516,7 @@ const int16_t sba_map_tc[8] = /*----------------------------------------------------------------------------------* * FASTCONV and PARAMETRIC binaural renderer ROM tables *----------------------------------------------------------------------------------*/ - +// VE2AT: move to in ivas_rom_dec ? const float surCohEne[MASA_NUM_DEFINED_SUR_SPR_COH_ENE_BINS] = { 3.0903f, 2.0053f, 1.0860f, 0.8072f, 0.7079f diff --git a/lib_dec/ivas_sba_dec.c b/lib_dec/ivas_sba_dec.c index 0f1bedbad7..fe043c746b 100644 --- a/lib_dec/ivas_sba_dec.c +++ b/lib_dec/ivas_sba_dec.c @@ -45,378 +45,618 @@ #include "wmops.h" +#ifdef SBA_BR_SWITCHING /*-------------------------------------------------------------------* - * ivas_sba_dec_decoder() + * ivas_sba_dec_reinit() * - * Reconfigure IVAS SBA decoder + * Reinitialisation of IVAS SBA decoder *-------------------------------------------------------------------*/ -ivas_error ivas_sba_dec_reconfigure( +ivas_error ivas_sba_dec_reinit( Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ ) { -#ifdef CORECODER_BITRATE_SWITCHING - int16_t i; - int16_t nchan_transport, nchan_transport_old; - int16_t nSCE_old, nCPE_old, nchan_hp20_old; -#else - int16_t i, n, sce_id, cpe_id; - int16_t nchan_transport, nchan_transport_old; - int16_t nSCE_old, nCPE_old; -#endif - AUDIO_CONFIG intern_config_old; - int16_t numCldfbAnalyses_old, numCldfbAnalyses, numCldfbSyntheses, numCldfbSyntheses_old; - int16_t sba_dirac_stereo_flag_old; - int32_t ivas_total_brate, last_ivas_total_brate; + int16_t i, k, n; + int16_t sce_id, cpe_id; + int16_t numCldfbAnalyses; + int16_t numCldfbSyntheses; + int32_t output_Fs, ivas_total_brate; + AUDIO_CONFIG output_config; + DECODER_CONFIG_HANDLE hDecoderConfig; ivas_error error; error = IVAS_ERR_OK; - ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate; - last_ivas_total_brate = st_ivas->hDecoderConfig->last_ivas_total_brate; + output_Fs = st_ivas->hDecoderConfig->output_Fs; + hDecoderConfig = st_ivas->hDecoderConfig; + output_config = hDecoderConfig->output_config; + ivas_total_brate = hDecoderConfig->ivas_total_brate; - /*-----------------------------------------------------------------* - * Allocate, initalize, and configure SBA and rendering handles - *-----------------------------------------------------------------*/ + hDecoderConfig->last_ivas_total_brate = ivas_total_brate; + /*------------------------------------------------------------------------------------------* + * Closing Decoder handles before Reinitialisation + *------------------------------------------------------------------------------------------*/ + /* Qmetadata handle */ + ivas_qmetadata_close( &st_ivas->hQMetaData ); - ivas_init_dec_get_num_cldfb_instances( st_ivas, &numCldfbAnalyses_old, &numCldfbSyntheses_old ); - numCldfbAnalyses = 0; + /* DirAC handle */ + if ( st_ivas->hDirAC != NULL ) + { + if ( st_ivas->ivas_format == ISM_FORMAT ) + { + ivas_param_ism_dec_close( st_ivas->hDirAC, st_ivas->hDecoderConfig->output_config ); + } + else + { + ivas_dirac_dec_close( st_ivas->hDirAC ); + } + st_ivas->hDirAC = NULL; + } -#ifdef CORECODER_BITRATE_SWITCHING - nchan_hp20_old = getNumChanSynthesis( st_ivas ); -#endif + /* Spar handle */ + if ( st_ivas->hSpar != NULL ) + { + ivas_spar_dec_close( st_ivas->hSpar, st_ivas->hDecoderConfig->output_Fs ); + st_ivas->hSpar = NULL; + } - nSCE_old = st_ivas->nSCE; - nCPE_old = st_ivas->nCPE; - nchan_transport_old = st_ivas->nchan_transport; - sba_dirac_stereo_flag_old = st_ivas->sba_dirac_stereo_flag; + /* SCE handles */ + for ( i = 0; i < MAX_SCE; i++ ) + { + if ( st_ivas->hSCE[i] != NULL ) + { + destroy_sce_dec( st_ivas->hSCE[i] ); + st_ivas->hSCE[i] = NULL; + } + } - st_ivas->sba_analysis_order = ivas_sba_get_analysis_order( ivas_total_brate, st_ivas->sba_order ); + /* CPE handles */ + for ( i = 0; i < MAX_CPE; i++ ) + { + if ( st_ivas->hCPE[i] != NULL ) + { + /* set pointer to NULL as core coder already deallocated in destroy_sce_dec() */ + if ( st_ivas->sba_dirac_stereo_flag ) + { + st_ivas->hCPE[i]->hCoreCoder[0] = NULL; + st_ivas->hCPE[i]->hCoreCoder[1] = NULL; + } + destroy_cpe_dec( st_ivas->hCPE[i] ); + st_ivas->hCPE[i] = NULL; + } + } - ivas_sba_config( ivas_total_brate, st_ivas->sba_analysis_order, -1, &nchan_transport, st_ivas->sba_planar, &st_ivas->nSCE, &st_ivas->nCPE, &st_ivas->element_mode_init ); + /* MCT handle */ + ivas_mct_dec_close( &st_ivas->hMCT ); - st_ivas->nchan_transport = nchan_transport; + /* HP20 filter handles */ + if ( st_ivas->mem_hp20_out != NULL ) + { + for ( i = 0; i < getNumChanSynthesis( st_ivas ); i++ ) + { + count_free( st_ivas->mem_hp20_out[i] ); + st_ivas->mem_hp20_out[i] = NULL; + } + count_free( st_ivas->mem_hp20_out ); + st_ivas->mem_hp20_out = NULL; + } - /* renderer might have changed */ - intern_config_old = st_ivas->intern_config; - ivas_renderer_select( st_ivas ); + /* HOA decoder matrix */ + if ( st_ivas->hoa_dec_mtx != NULL ) + { + count_free( st_ivas->hoa_dec_mtx ); + st_ivas->hoa_dec_mtx = NULL; + } - /* side effect of the renderer selection can be a changed internal config */ - if ( st_ivas->intern_config != intern_config_old ) + /* Parametric MC handle */ + ivas_param_mc_dec_close( &st_ivas->hParamMC ); + + /* EFAP handle */ + efap_free_data( &st_ivas->hEFAPdata ); + + /* VBAP handle */ + vbap_free_data( &( st_ivas->hVBAPdata ) ); + + /* Fastconv binaural renderer handle */ + ivas_binRenderer_close( &st_ivas->hBinRenderer ); + + /* Parametric binaural renderer handle */ + ivas_dirac_dec_close_binaural_data( &st_ivas->hDiracDecBin ); + + /* Crend handle */ + ivas_crend_close( st_ivas ); + + /* LS config converter handle */ + ivas_ls_setup_conversion_close( &st_ivas->hLsSetUpConversion ); + + /* Custom LS configuration handle */ + if ( st_ivas->hLsSetupCustom != NULL ) { - ivas_output_init( &( st_ivas->hIntSetup ), st_ivas->intern_config ); + count_free( st_ivas->hLsSetupCustom ); + st_ivas->hLsSetupCustom = NULL; } - if ( st_ivas->sba_mode != SBA_MODE_SPAR ) + /* MASA decoder structure */ + if ( st_ivas->hMasa != NULL ) { - st_ivas->sba_dirac_stereo_flag = ( st_ivas->nchan_transport == 1 && st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_STEREO ); + ivas_masa_dec_close( st_ivas->hMasa ); + st_ivas->hMasa = NULL; + } - if ( ( error = ivas_dirac_sba_config( st_ivas->hQMetaData, &st_ivas->nchan_transport, &st_ivas->nSCE, &st_ivas->nCPE, &st_ivas->element_mode_init, ivas_total_brate, st_ivas->sba_analysis_order, st_ivas->sba_mode, -1 ) ) != IVAS_ERR_OK ) + /* Downmix structure */ + if ( st_ivas->hMonoDmxRenderer != NULL ) + { + count_free( st_ivas->hMonoDmxRenderer ); + st_ivas->hMonoDmxRenderer = NULL; + } + + /* Head track data handle */ + if ( st_ivas->hHeadTrackData != NULL ) + { + count_free( st_ivas->hHeadTrackData ); + st_ivas->hHeadTrackData = NULL; + } + + /* Time Domain binaural renderer handle */ + if ( st_ivas->hBinRendererTd != NULL ) + { + ivas_td_binaural_close( &st_ivas->hBinRendererTd ); + } + else if ( st_ivas->hHrtfTD != NULL ) + { + /* Case when HRTF filter is mistakenly specified but TD renderer was not active */ + if ( st_ivas->hHrtfTD->ModelParams.UseItdModel && !st_ivas->hHrtfTD->ModelParams.modelROM ) { - return error; + BSplineModelEvalITDDealloc( &st_ivas->hHrtfTD->ModelParamsITD ); } + + BSplineModelEvalDealloc( &st_ivas->hHrtfTD->ModelParams, &st_ivas->hHrtfTD->ModelEval ); + + ivas_HRTF_binary_close( &st_ivas->hHrtfTD ); } - else - { - int16_t sba_order_internal; - sba_order_internal = min( st_ivas->sba_analysis_order, IVAS_MAX_SBA_ORDER ); - ivas_spar_config( st_ivas->hDecoderConfig->ivas_total_brate, sba_order_internal, &st_ivas->nchan_transport, &st_ivas->nSCE, &st_ivas->nCPE, &st_ivas->hSpar->core_nominal_brate, st_ivas->sid_format ); + /* Config. Renderer */ + ivas_render_config_close( &( st_ivas->hRenderConfig ) ); - if ( ( error = ivas_dirac_sba_config( st_ivas->hQMetaData, &st_ivas->nchan_transport, &st_ivas->nSCE, &st_ivas->nCPE, &st_ivas->element_mode_init, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->sba_analysis_order, st_ivas->sba_mode, IVAS_MAX_NUM_BANDS - SPAR_DIRAC_SPLIT_START_BAND ) ) != IVAS_ERR_OK ) + for ( i = 0; i < MAX_INTERN_CHANNELS; i++ ) + { + if ( st_ivas->cldfbAnaDec[i] != NULL ) { - return error; + deleteCldfb( &( st_ivas->cldfbAnaDec[i] ) ); + st_ivas->cldfbAnaDec[i] = NULL; } } - if ( st_ivas->renderer_type != RENDERER_DISABLE && st_ivas->renderer_type != RENDERER_SBA_LINEAR_DEC && ( last_ivas_total_brate > IVAS_SID_5k2 || nchan_transport != nchan_transport_old ) && ( st_ivas->sba_mode != SBA_MODE_SPAR ) ) + for ( i = 0; i < MAX_OUTPUT_CHANNELS; i++ ) { - if ( st_ivas->hDirAC != NULL ) + if ( st_ivas->cldfbSynDec[i] != NULL ) { - if ( ( error = ivas_dirac_dec_config( st_ivas, DIRAC_RECONFIGURE ) ) != IVAS_ERR_OK ) - { - return error; - } + deleteCldfb( &( st_ivas->cldfbSynDec[i] ) ); + st_ivas->cldfbSynDec[i] = NULL; } - else + } + + /*------------------------------------------------------------------------------------------* + * Reopening Decoder handles for Reinitialisation + *------------------------------------------------------------------------------------------*/ + + /* Allocate and initialize Custom loudspeaker layout handle */ + if ( st_ivas->hDecoderConfig->Opt_LsCustom ) + { + if ( ( error = ivas_ls_custom_open( &( st_ivas->hLsSetupCustom ) ) ) != IVAS_ERR_OK ) { - if ( ( error = ivas_dirac_dec_config( st_ivas, DIRAC_OPEN ) ) != IVAS_ERR_OK ) - { - return error; - } + return error; } } - else if ( st_ivas->renderer_type == RENDERER_DISABLE || ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_DEC && st_ivas->sba_mode != SBA_MODE_SPAR ) ) + + /* Allocate and initialize Head-Tracking handle */ + if ( st_ivas->hDecoderConfig->Opt_Headrotation ) { - if ( st_ivas->hDirAC != NULL ) + if ( ( error = ivas_headTrack_open( &( st_ivas->hHeadTrackData ) ) ) != IVAS_ERR_OK ) { - ivas_dirac_dec_close( st_ivas->hDirAC ); - st_ivas->hDirAC = NULL; + return error; } + } - if ( st_ivas->hVBAPdata != NULL ) + /* Allocate HRTF binary handle */ + if ( st_ivas->hDecoderConfig->Opt_HRTF_binary ) + { + if ( ( error = ivas_HRTF_binary_open( &( st_ivas->hHrtfTD ) ) ) != IVAS_ERR_OK ) { - vbap_free_data( &( st_ivas->hVBAPdata ) ); + return error; } } - /*-----------------------------------------------------------------* - * Allocate, initalize, and configure SCE/CPE/MCT handles - *-----------------------------------------------------------------*/ - -#ifdef CORECODER_BITRATE_SWITCHING - ivas_corecoder_dec_reconfig( st_ivas, nSCE_old, nCPE_old, nchan_transport_old, sba_dirac_stereo_flag_old ); - - /*-----------------------------------------------------------------* - * HP20 memories - *-----------------------------------------------------------------*/ - - ivas_hp20_dec_reconfig( st_ivas, nchan_hp20_old ); -#else - - if ( nchan_transport == nchan_transport_old ) + st_ivas->sba_dirac_stereo_flag = 0; + /*Reconfigure output paramaters*/ + 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 ); + ivas_renderer_select( st_ivas ); + ivas_output_init( &( st_ivas->hIntSetup ), st_ivas->intern_config ); + if ( ( error = ivas_qmetadata_open( &( st_ivas->hQMetaData ) ) ) != IVAS_ERR_OK ) { - for ( sce_id = 0; sce_id < st_ivas->nSCE; sce_id++ ) + return error; + } + if ( st_ivas->sba_mode == SBA_MODE_SPAR ) + { + if ( ( error = ivas_spar_dec_open( st_ivas ) ) != IVAS_ERR_OK ) { - st_ivas->hSCE[sce_id]->element_brate = ivas_total_brate / st_ivas->nchan_transport; - st_ivas->hSCE[sce_id]->hCoreCoder[0]->total_brate = st_ivas->hSCE[sce_id]->element_brate; /* dummy initialization for getting right pointers initialization of input buffers in init_coder_ace_plus() */ + return error; } - for ( cpe_id = 0; cpe_id < st_ivas->nCPE; cpe_id++ ) + if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_DEC && st_ivas->hOutSetup.is_loudspeaker_setup ) { - st_ivas->hCPE[cpe_id]->element_brate = ( ivas_total_brate / st_ivas->nchan_transport ) * CPE_CHANNELS; - - /* prepare bitstream buffers */ - for ( n = 0; n < CPE_CHANNELS; n++ ) + if ( ( error = ivas_sba_get_hoa_dec_matrix( st_ivas->hOutSetup, &st_ivas->hoa_dec_mtx, st_ivas->hIntSetup.ambisonics_order ) ) != IVAS_ERR_OK ) { - st_ivas->hCPE[cpe_id]->hCoreCoder[n]->total_brate = st_ivas->hCPE[cpe_id]->element_brate / ( st_ivas->nCPE > 1 ? 1 : CPE_CHANNELS ); /* dummy initialization for getting right pointers initialization of input buffers in init_coder_ace_plus() */ + return error; } } - if ( st_ivas->nCPE > 1 ) + if ( ( error = ivas_dirac_sba_config( st_ivas->hQMetaData, &st_ivas->nchan_transport, &st_ivas->nSCE, &st_ivas->nCPE, &st_ivas->element_mode_init, ivas_total_brate, st_ivas->sba_analysis_order, st_ivas->sba_mode, IVAS_MAX_NUM_BANDS - SPAR_DIRAC_SPLIT_START_BAND ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( hDecoderConfig->output_config != AUDIO_CONFIG_FOA ) { - if ( ( error = mct_dec_reconfigure( st_ivas, 0 ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_dirac_dec_open( st_ivas ) ) != IVAS_ERR_OK ) { return error; } + + for ( k = 0; k < DIRAC_MAX_NBANDS; k++ ) + { + st_ivas->hSpar->dirac_to_spar_md_bands[k] = st_ivas->hDirAC->dirac_to_spar_md_bands[k]; + } + st_ivas->hSpar->enc_param_start_band = st_ivas->hDirAC->hConfig->enc_param_start_band; + } + else + { + int16_t band_grouping[IVAS_MAX_NUM_BANDS + 1]; + + st_ivas->hSpar->enc_param_start_band = min( IVAS_MAX_NUM_BANDS, SPAR_DIRAC_SPLIT_START_BAND ); + + ivas_dirac_config_bands( band_grouping, IVAS_MAX_NUM_BANDS, (int16_t) ( st_ivas->hDecoderConfig->output_Fs * INV_CLDFB_BANDWIDTH + 0.5f ), + st_ivas->hSpar->dirac_to_spar_md_bands, st_ivas->hQMetaData->useLowerBandRes, st_ivas->hSpar->enc_param_start_band, 0 ); } } else { - int16_t nSCE_existing; - int16_t nCPE_existing; + if ( ( error = ivas_dirac_sba_config( st_ivas->hQMetaData, &st_ivas->nchan_transport, &st_ivas->nSCE, &st_ivas->nCPE, &st_ivas->element_mode_init, ivas_total_brate, st_ivas->sba_analysis_order, st_ivas->sba_mode, -1 ) ) != IVAS_ERR_OK ) + { + return error; + } - nSCE_existing = min( nSCE_old, st_ivas->nSCE ); - nCPE_existing = min( nCPE_old, st_ivas->nCPE ); + st_ivas->sba_dirac_stereo_flag = ( st_ivas->nchan_transport == 1 && output_config == AUDIO_CONFIG_STEREO ); - /* destroy superfluous core coder elements */ - for ( sce_id = st_ivas->nSCE; sce_id < nSCE_old; sce_id++ ) + if ( ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_DEC ) && st_ivas->hOutSetup.is_loudspeaker_setup ) { - destroy_sce_dec( st_ivas->hSCE[sce_id] ); - st_ivas->hSCE[sce_id] = NULL; + int16_t ambisonics_order; + + ambisonics_order = ivas_sba_get_order_transport( st_ivas->nchan_transport ); // VE: is it needed ? - /* remove dummy CPE needed for 1TC->Stereo rendering via DFT stereo*/ - if ( sba_dirac_stereo_flag_old ) + if ( ( error = ivas_sba_get_hoa_dec_matrix( st_ivas->hOutSetup, &st_ivas->hoa_dec_mtx, ambisonics_order ) ) != IVAS_ERR_OK ) { -#ifdef DEBUGGING - assert( st_ivas->hCPE[0] ); -#endif - st_ivas->hCPE[0]->hCoreCoder[0] = st_ivas->hCPE[0]->hCoreCoder[1] = NULL; - destroy_cpe_dec( st_ivas->hCPE[0] ); - st_ivas->hCPE[0] = NULL; + return error; } } + else if ( ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM || st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV_ROOM ) && !st_ivas->hIntSetup.is_loudspeaker_setup ) + { + IVAS_OUTPUT_SETUP out_setup; - for ( cpe_id = st_ivas->nCPE; cpe_id < nCPE_old; cpe_id++ ) + ivas_output_init( &out_setup, AUDIO_CONFIG_7_1_4 ); + if ( ( error = ivas_sba_get_hoa_dec_matrix( out_setup, &st_ivas->hoa_dec_mtx, st_ivas->hIntSetup.ambisonics_order ) ) != IVAS_ERR_OK ) + { + return error; + } + } + } + if ( st_ivas->renderer_type != RENDERER_BINAURAL_MIXER_CONV && st_ivas->renderer_type != RENDERER_BINAURAL_MIXER_CONV_ROOM && + st_ivas->renderer_type != RENDERER_DISABLE && st_ivas->renderer_type != RENDERER_SBA_LINEAR_DEC && st_ivas->sba_mode != SBA_MODE_SPAR ) + { + if ( ( error = ivas_dirac_dec_open( st_ivas ) ) != IVAS_ERR_OK ) { - destroy_cpe_dec( st_ivas->hCPE[cpe_id] ); - st_ivas->hCPE[cpe_id] = NULL; + return error; } - - if ( st_ivas->nCPE <= 1 && st_ivas->hMCT != NULL ) + } + for ( sce_id = 0; sce_id < st_ivas->nSCE; sce_id++ ) + { + if ( ( error = create_sce_dec( st_ivas, sce_id, ivas_total_brate / st_ivas->nchan_transport ) ) != IVAS_ERR_OK ) { - ivas_mct_dec_close( &st_ivas->hMCT ); + return error; } - /* special case, if we have MCT now and had a single CPE before, remove the MDCT Stereo handles from the first CPE*/ - if ( st_ivas->nCPE > 1 && nCPE_old == 1 ) + reset_indices_dec( st_ivas->hSCE[sce_id]->hCoreCoder[0] ); + } + + for ( cpe_id = 0; cpe_id < st_ivas->nCPE; cpe_id++ ) + { + if ( ( error = create_cpe_dec( st_ivas, cpe_id, ( ivas_total_brate / st_ivas->nchan_transport ) * CPE_CHANNELS ) ) != IVAS_ERR_OK ) { - count_free( st_ivas->hCPE[0]->hStereoMdct ); - st_ivas->hCPE[0]->hStereoMdct = NULL; + return error; } - for ( sce_id = 0; sce_id < nSCE_existing; sce_id++ ) + for ( n = 0; n < CPE_CHANNELS; n++ ) { - st_ivas->hSCE[sce_id]->element_brate = ivas_total_brate / st_ivas->nchan_transport; - st_ivas->hSCE[sce_id]->hCoreCoder[0]->total_brate = st_ivas->hSCE[sce_id]->element_brate; /* dummy initialization for getting right pointers initialization of input buffers in init_coder_ace_plus() */ + reset_indices_dec( st_ivas->hCPE[cpe_id]->hCoreCoder[n] ); } - for ( ; sce_id < st_ivas->nSCE; sce_id++ ) + } + + /* create CPE element for DFT Stereo like upmix */ + if ( st_ivas->sba_dirac_stereo_flag ) + { + if ( ( error = create_cpe_dec( st_ivas, cpe_id, ivas_total_brate / ( st_ivas->nSCE + st_ivas->nCPE ) ) ) != IVAS_ERR_OK ) { - if ( ( error = create_sce_dec( st_ivas, sce_id, ivas_total_brate / st_ivas->nchan_transport ) ) != IVAS_ERR_OK ) - { - return error; - } + return error; } - for ( cpe_id = 0; cpe_id < nCPE_existing; cpe_id++ ) - { - st_ivas->hCPE[cpe_id]->element_brate = ( ivas_total_brate / st_ivas->nchan_transport ) * CPE_CHANNELS; + st_ivas->hCPE[0]->hCoreCoder[0] = st_ivas->hSCE[0]->hCoreCoder[0]; /* don't allocate unnecessary core coder, simply point to core coder of SCE element */ + } - /* prepare bitstream buffers */ - for ( n = 0; n < CPE_CHANNELS; n++ ) - { - st_ivas->hCPE[cpe_id]->hCoreCoder[n]->total_brate = st_ivas->hCPE[cpe_id]->element_brate / ( st_ivas->nCPE > 1 ? 1 : CPE_CHANNELS ); /* dummy initialization for getting right pointers initialization of input buffers in init_coder_ace_plus() */ - } - } - for ( ; cpe_id < st_ivas->nCPE; cpe_id++ ) + /* set CNA/CNG flags */ + if ( st_ivas->sba_mode == SBA_MODE_SPAR && st_ivas->nchan_transport == 1 ) + { + st_ivas->hSCE[0]->hCoreCoder[0]->cna_dirac_flag = 0; /* Todo: Check if these can be enabled */ + st_ivas->hSCE[0]->hCoreCoder[0]->cng_sba_flag = 0; + } + else if ( st_ivas->nchan_transport == 1 && ( ( st_ivas->renderer_type == RENDERER_DIRAC && st_ivas->hDirAC->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD ) || ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM || st_ivas->renderer_type == RENDERER_STEREO_PARAMETRIC ) ) ) + { + st_ivas->hSCE[0]->hCoreCoder[0]->cna_dirac_flag = 1; + st_ivas->hSCE[0]->hCoreCoder[0]->cng_sba_flag = 1; + } + else if ( st_ivas->nchan_transport == 2 ) + { + for ( n = 0; n < CPE_CHANNELS; n++ ) { - if ( ( error = create_cpe_dec( st_ivas, cpe_id, ( ivas_total_brate / st_ivas->nchan_transport ) * CPE_CHANNELS ) ) != IVAS_ERR_OK ) - { - return error; - } + st_ivas->hCPE[0]->hCoreCoder[n]->cna_dirac_flag = 0; /* Todo: Check if these can be enabled */ + st_ivas->hCPE[0]->hCoreCoder[n]->cng_sba_flag = 1; } + } - /* create CPE element for DFT Stereo like upmix */ - if ( st_ivas->sba_dirac_stereo_flag ) + if ( st_ivas->nCPE > 1 ) + { + if ( ( error = create_mct_dec( st_ivas ) ) != IVAS_ERR_OK ) { - if ( ( error = create_cpe_dec( st_ivas, 0, ivas_total_brate / ( st_ivas->nSCE + st_ivas->nCPE ) ) ) != IVAS_ERR_OK ) - { - return error; - } + return error; + } + } + /* set number of output channels used for synthesis/decoding */ + n = getNumChanSynthesis( st_ivas ); - st_ivas->hCPE[0]->hCoreCoder[0] = st_ivas->hSCE[0]->hCoreCoder[0]; /* don't allocate unnecessary core coder, simply point to core coder of SCE element */ + if ( n > 0 ) + { + if ( ( st_ivas->mem_hp20_out = (float **) count_malloc( n * sizeof( float * ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for HP20 filter memory\n" ) ); } + } + else + { + st_ivas->mem_hp20_out = NULL; + } - if ( st_ivas->nCPE > 1 && nCPE_old <= 1 ) + for ( i = 0; i < n; i++ ) + { + if ( ( st_ivas->mem_hp20_out[i] = (float *) count_malloc( L_HP20_MEM * sizeof( float ) ) ) == NULL ) { - if ( nCPE_old == 1 ) - { - /* set correct nominal bitrates and igf config already here, needed for the correct init of the MDCT Stereo handles for MCT */ - for ( n = 0; n < CPE_CHANNELS; n++ ) - { - st_ivas->hCPE[0]->hCoreCoder[n]->total_brate = st_ivas->hCPE[0]->element_brate; - st_ivas->hCPE[0]->hCoreCoder[n]->bits_frame_nominal = (int16_t) ( st_ivas->hCPE[0]->element_brate / FRAMES_PER_SEC ); - st_ivas->hCPE[0]->hCoreCoder[n]->igf = 0; - } - } + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for HP20 filter memory\n" ) ); + } - if ( ( error = create_mct_dec( st_ivas ) ) != IVAS_ERR_OK ) - { - return error; - } + set_f( st_ivas->mem_hp20_out[i], 0.0f, L_HP20_MEM ); + } + if ( st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_BINAURAL || st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_BINAURAL_ROOM ) + { + if ( ( error = ivas_render_config_open( &( st_ivas->hRenderConfig ) ) ) != IVAS_ERR_OK ) + { + return error; } - else if ( st_ivas->hMCT != NULL && st_ivas->nCPE > 1 ) + if ( ivas_render_config_init_from_rom( &st_ivas->hRenderConfig, st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_BINAURAL_ROOM ) != IVAS_ERR_OK ) { - if ( ( error = mct_dec_reconfigure( st_ivas, st_ivas->nCPE != nCPE_old ) ) != IVAS_ERR_OK ) - { - return error; - } + return IVAS_ERR_INTERNAL_FATAL; + } + } + if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) + { + if ( ( error = ivas_binRenderer_open( st_ivas ) ) != IVAS_ERR_OK ) + { + return error; + } + } + else if ( 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_dirac_dec_init_binaural_data( st_ivas ) ) != IVAS_ERR_OK ) + { + return error; + } + } + else if ( st_ivas->renderer_type == RENDERER_BINAURAL_OBJECTS_TD ) + { + if ( ( error = ivas_td_binaural_open( st_ivas ) ) != IVAS_ERR_OK ) + { + return error; } - /* special case, if we have a single CPE and had MCT before we need to init the MDCT stereo handles here */ - if ( st_ivas->nCPE == 1 && nCPE_old > 1 ) + if ( st_ivas->hRenderConfig->roomAcoustics.late_reverb_on ) { - if ( ( st_ivas->hCPE[st_ivas->nCPE - 1]->hStereoMdct = (STEREO_MDCT_DEC_DATA_HANDLE) count_malloc( sizeof( STEREO_MDCT_DEC_DATA ) ) ) == NULL ) + if ( ( st_ivas->hCrend = (CREND_HANDLE) count_malloc( sizeof( CREND_DATA ) ) ) == NULL ) { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for MDCT Stereo \n" ) ); + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR Crend\n" ); } + } + } + else if ( st_ivas->renderer_type == RENDERER_MC ) + { + if ( ( error = ivas_ls_setup_conversion_open( st_ivas ) ) != IVAS_ERR_OK ) + { + return error; + } + } + else if ( st_ivas->renderer_type == RENDERER_MONO_DOWNMIX ) + { + if ( ( error = ivas_mono_dmx_renderer_open( st_ivas ) ) != IVAS_ERR_OK ) + { + return error; + } + } + else if ( st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV || st_ivas->renderer_type == RENDERER_BINAURAL_MIXER_CONV_ROOM ) + { + if ( ivas_crend_open( st_ivas ) != IVAS_ERR_OK ) + { + return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "ivas_crend_open failed" ); + } + } + ivas_init_dec_get_num_cldfb_instances( st_ivas, &numCldfbAnalyses, &numCldfbSyntheses ); - st_ivas->hCPE[st_ivas->nCPE - 1]->hStereoMdct->use_itd = 0; - st_ivas->hCPE[st_ivas->nCPE - 1]->hStereoMdct->reverse_dmx = 0; - st_ivas->hCPE[st_ivas->nCPE - 1]->hStereoMdct->smooth_ratio = 1.f; + for ( i = 0; i < numCldfbAnalyses; i++ ) + { + if ( ( error = openCldfb( &( st_ivas->cldfbAnaDec[i] ), CLDFB_ANALYSIS, output_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) + { + return error; + } + } + for ( ; i < MAX_INTERN_CHANNELS; i++ ) + { + st_ivas->cldfbAnaDec[i] = NULL; + } - for ( n = 0; n < CPE_CHANNELS; n++ ) - { - /* reset mct_chan_mode */ - st_ivas->hCPE[0]->hCoreCoder[n]->mct_chan_mode = MCT_CHAN_MODE_REGULAR; - } + for ( i = 0; i < numCldfbSyntheses; i++ ) + { + if ( ( error = openCldfb( &( st_ivas->cldfbSynDec[i] ), CLDFB_SYNTHESIS, output_Fs, CLDFB_PROTOTYPE_5_00MS ) ) != IVAS_ERR_OK ) + { + return error; } + } + for ( ; i < MAX_OUTPUT_CHANNELS; i++ ) + { + st_ivas->cldfbSynDec[i] = NULL; + } - /*-----------------------------------------------------------------* - * HP20 memories - *-----------------------------------------------------------------*/ + /* CLDFB Interpolation weights */ + if ( st_ivas->ivas_format == SBA_FORMAT && st_ivas->sba_mode == SBA_MODE_SPAR ) + { + ivas_spar_get_cldfb_gains( st_ivas->hSpar, st_ivas->cldfbAnaDec[0], st_ivas->cldfbSynDec[0], hDecoderConfig ); + } + return error; +} +#endif - if ( nchan_transport > nchan_transport_old ) - { - /* create additional hp20 memories */ - float **old_mem_hp20_out; - uint16_t n_old; +/*-------------------------------------------------------------------* + * ivas_sba_dec_decoder() + * + * Reconfigure IVAS SBA decoder + *-------------------------------------------------------------------*/ - if ( sba_dirac_stereo_flag_old ) - { - n_old = CPE_CHANNELS; - } - else - { - n_old = nchan_transport_old; - } - n = st_ivas->nchan_transport; +ivas_error ivas_sba_dec_reconfigure( + Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ +) +{ + int16_t i; + int16_t nchan_transport, nchan_transport_old; + int16_t nSCE_old, nCPE_old, nchan_hp20_old; + AUDIO_CONFIG intern_config_old; + int16_t numCldfbAnalyses_old, numCldfbAnalyses, numCldfbSyntheses, numCldfbSyntheses_old; + int16_t sba_dirac_stereo_flag_old; + int32_t ivas_total_brate, last_ivas_total_brate; + ivas_error error; - /* save old mem_hp_20 pointer */ - old_mem_hp20_out = st_ivas->mem_hp20_out; - st_ivas->mem_hp20_out = NULL; - if ( ( st_ivas->mem_hp20_out = (float **) count_malloc( n * sizeof( float * ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for HP20 filter memory\n" ) ); - } + error = IVAS_ERR_OK; - for ( i = 0; i < n_old; i++ ) - { - st_ivas->mem_hp20_out[i] = old_mem_hp20_out[i]; - old_mem_hp20_out[i] = NULL; - } - for ( ; i < nchan_transport; i++ ) - { - if ( ( st_ivas->mem_hp20_out[i] = (float *) count_malloc( L_HP20_MEM * sizeof( float ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for HP20 filter memory\n" ) ); - } + ivas_total_brate = st_ivas->hDecoderConfig->ivas_total_brate; + last_ivas_total_brate = st_ivas->hDecoderConfig->last_ivas_total_brate; - set_f( st_ivas->mem_hp20_out[i], 0.0f, L_HP20_MEM ); - } + /*-----------------------------------------------------------------* + * Allocate, initalize, and configure SBA and rendering handles + *-----------------------------------------------------------------*/ - count_free( old_mem_hp20_out ); - old_mem_hp20_out = NULL; - } - else if ( nchan_transport < nchan_transport_old ) - { - /* remove superfluous hp20 memories */ - float **old_mem_hp20_out; + ivas_init_dec_get_num_cldfb_instances( st_ivas, &numCldfbAnalyses_old, &numCldfbSyntheses_old ); + numCldfbAnalyses = 0; - if ( st_ivas->sba_dirac_stereo_flag ) - { - n = CPE_CHANNELS; - } - else - { - n = st_ivas->nchan_transport; - } + nchan_hp20_old = getNumChanSynthesis( st_ivas ); - /* save old mem_hp_20 pointer */ - old_mem_hp20_out = st_ivas->mem_hp20_out; - st_ivas->mem_hp20_out = NULL; - if ( ( st_ivas->mem_hp20_out = (float **) count_malloc( n * sizeof( float * ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for HP20 filter memory\n" ) ); - } + nSCE_old = st_ivas->nSCE; + nCPE_old = st_ivas->nCPE; + nchan_transport_old = st_ivas->nchan_transport; + sba_dirac_stereo_flag_old = st_ivas->sba_dirac_stereo_flag; + + st_ivas->sba_analysis_order = ivas_sba_get_analysis_order( ivas_total_brate, st_ivas->sba_order ); + + ivas_sba_config( ivas_total_brate, st_ivas->sba_analysis_order, -1, &nchan_transport, st_ivas->sba_planar, &st_ivas->nSCE, &st_ivas->nCPE, &st_ivas->element_mode_init ); + + st_ivas->nchan_transport = nchan_transport; + + /* renderer might have changed */ + intern_config_old = st_ivas->intern_config; + ivas_renderer_select( st_ivas ); + + /* side effect of the renderer selection can be a changed internal config */ + if ( st_ivas->intern_config != intern_config_old ) + { + ivas_output_init( &( st_ivas->hIntSetup ), st_ivas->intern_config ); + } - for ( i = 0; i < n; i++ ) + if ( st_ivas->sba_mode != SBA_MODE_SPAR ) + { + st_ivas->sba_dirac_stereo_flag = ( st_ivas->nchan_transport == 1 && st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_STEREO ); + if ( ( error = ivas_dirac_sba_config( st_ivas->hQMetaData, &st_ivas->nchan_transport, &st_ivas->nSCE, &st_ivas->nCPE, &st_ivas->element_mode_init, ivas_total_brate, st_ivas->sba_analysis_order, st_ivas->sba_mode, -1 ) ) != IVAS_ERR_OK ) + { + return error; + } + } + else + { + int16_t sba_order_internal; + + sba_order_internal = min( st_ivas->sba_analysis_order, IVAS_MAX_SBA_ORDER ); + ivas_spar_config( st_ivas->hDecoderConfig->ivas_total_brate, sba_order_internal, &st_ivas->nchan_transport, &st_ivas->nSCE, &st_ivas->nCPE, &st_ivas->hSpar->core_nominal_brate, st_ivas->sid_format ); + + if ( ( error = ivas_dirac_sba_config( st_ivas->hQMetaData, &st_ivas->nchan_transport, &st_ivas->nSCE, &st_ivas->nCPE, &st_ivas->element_mode_init, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->sba_analysis_order, st_ivas->sba_mode, IVAS_MAX_NUM_BANDS - SPAR_DIRAC_SPLIT_START_BAND ) ) != IVAS_ERR_OK ) + { + return error; + } + } + + if ( st_ivas->renderer_type != RENDERER_DISABLE && st_ivas->renderer_type != RENDERER_SBA_LINEAR_DEC && ( last_ivas_total_brate > IVAS_SID_5k2 || nchan_transport != nchan_transport_old ) && ( st_ivas->sba_mode != SBA_MODE_SPAR ) ) + { + if ( st_ivas->hDirAC != NULL ) + { + if ( ( error = ivas_dirac_dec_config( st_ivas, DIRAC_RECONFIGURE ) ) != IVAS_ERR_OK ) { - st_ivas->mem_hp20_out[i] = old_mem_hp20_out[i]; - old_mem_hp20_out[i] = NULL; + return error; } - for ( ; i < nchan_transport_old; i++ ) + } + else + { + if ( ( error = ivas_dirac_dec_config( st_ivas, DIRAC_OPEN ) ) != IVAS_ERR_OK ) { - count_free( old_mem_hp20_out[i] ); - old_mem_hp20_out[i] = NULL; + return error; } + } + } + else if ( st_ivas->renderer_type == RENDERER_DISABLE || ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_DEC && st_ivas->sba_mode != SBA_MODE_SPAR ) ) + { + if ( st_ivas->hDirAC != NULL ) + { + ivas_dirac_dec_close( st_ivas->hDirAC ); + st_ivas->hDirAC = NULL; + } - count_free( old_mem_hp20_out ); - old_mem_hp20_out = NULL; + if ( st_ivas->hVBAPdata != NULL ) + { + vbap_free_data( &( st_ivas->hVBAPdata ) ); } } -#endif + + /*-----------------------------------------------------------------* + * Allocate, initalize, and configure SCE/CPE/MCT handles + *-----------------------------------------------------------------*/ + + ivas_corecoder_dec_reconfig( st_ivas, nSCE_old, nCPE_old, nchan_transport_old, sba_dirac_stereo_flag_old ); + + /*-----------------------------------------------------------------* + * HP20 memories + *-----------------------------------------------------------------*/ + + ivas_hp20_dec_reconfig( st_ivas, nchan_hp20_old ); /*-----------------------------------------------------------------* * CLDFB instances @@ -477,49 +717,6 @@ ivas_error ivas_sba_dec_reconfigure( } } -#ifndef CORECODER_BITRATE_SWITCHING - /*-----------------------------------------------------------------* - * Set CNA/CNG flags - *-----------------------------------------------------------------*/ - - if ( st_ivas->sba_mode == SBA_MODE_SPAR && st_ivas->nchan_transport == 1 ) - { - /* skip as done in init function */ - } - else if ( st_ivas->nchan_transport == 1 && ( ( st_ivas->renderer_type == RENDERER_DIRAC && st_ivas->hDirAC->synthesisConf == DIRAC_SYNTHESIS_GAIN_SHD ) || ( st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC || st_ivas->renderer_type == RENDERER_BINAURAL_PARAMETRIC_ROOM ) ) ) - { - st_ivas->hSCE[0]->hCoreCoder[0]->cna_dirac_flag = 1; - st_ivas->hSCE[0]->hCoreCoder[0]->cng_sba_flag = 1; - } - else if ( st_ivas->nchan_transport == 2 ) - { - for ( n = 0; n < CPE_CHANNELS; n++ ) - { - st_ivas->hCPE[0]->hCoreCoder[n]->cna_dirac_flag = 0; - st_ivas->hCPE[0]->hCoreCoder[n]->cng_sba_flag = 1; - } - } - else - { - for ( cpe_id = 0; cpe_id < st_ivas->nCPE; cpe_id++ ) - { - for ( n = 0; n < CPE_CHANNELS; n++ ) - { - st_ivas->hCPE[cpe_id]->hCoreCoder[n]->cna_dirac_flag = 0; - st_ivas->hCPE[cpe_id]->hCoreCoder[n]->cng_sba_flag = 0; - } - } - } - - /* special case, if the decoder goes from 1TC DTX to 2TC active frame (in case the bitstream started with an SBA SID frame), allocate DTX memories */ - if ( last_ivas_total_brate <= IVAS_SID_5k2 && st_ivas->nCPE >= 1 ) - { - if ( ( error = initMdctStereoDtxData( st_ivas->hCPE[0] ) ) != IVAS_ERR_OK ) - { - return error; - } - } -#endif /*-------------------------------------------------------------------* * Reallocate and initialize binaural rendering handles diff --git a/lib_dec/ivas_spar_decoder.c b/lib_dec/ivas_spar_decoder.c index eea34b31dc..d196cda9b6 100644 --- a/lib_dec/ivas_spar_decoder.c +++ b/lib_dec/ivas_spar_decoder.c @@ -89,12 +89,7 @@ ivas_error ivas_spar_dec_open( } /* MD handle */ - if ( ( error = ivas_spar_md_dec_open( &hSpar->hMdDec, st_ivas->hDecoderConfig, num_channels_internal -#ifdef SBA_HOA_HBR_IMPROV - , - sba_order_internal -#endif - ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_spar_md_dec_open( &hSpar->hMdDec, st_ivas->hDecoderConfig, num_channels_internal, sba_order_internal ) ) != IVAS_ERR_OK ) { return error; } @@ -649,13 +644,11 @@ static void ivas_spar_dec_MD( { ivas_parse_spar_header( hDecoderConfig->ivas_total_brate, sba_order, st0, &table_idx ); -#ifdef SBA_HOA_HBR_IMPROV if ( hSpar->hMdDec->spar_hoa_md_flag ) { hSpar->hMdDec->spar_md.num_bands = IVAS_MAX_NUM_BANDS; } else -#endif { hSpar->hMdDec->spar_md.num_bands = min( SPAR_DIRAC_SPLIT_START_BAND, IVAS_MAX_NUM_BANDS ); } @@ -665,7 +658,7 @@ static void ivas_spar_dec_MD( hSpar->hMdDec->table_idx = table_idx; hSpar->hTdDecorr->ducking_flag = ivas_spar_br_table_consts[table_idx].td_ducking; - ivas_spar_md_dec_init( hSpar->hMdDec, hDecoderConfig, num_channels ); + ivas_spar_md_dec_init( hSpar->hMdDec, hDecoderConfig, num_channels, sba_order ); } } @@ -801,11 +794,7 @@ void ivas_spar_get_parameters( weight = ivas_spar_get_cldfb_slot_gain( hSpar, hDecoderConfig, ts, &ts0, &ts1, &weight_20ms ); -#ifdef SBA_HOA_HBR_IMPROV split_band = hSpar->hMdDec->spar_md.num_bands; -#else - split_band = SPAR_DIRAC_SPLIT_START_BAND; -#endif for ( spar_band = 0; spar_band < num_spar_bands; spar_band++ ) { @@ -1022,20 +1011,17 @@ void ivas_spar_dec_upmixer( { mvr2r( pPcm_tmp[hSpar->hTdDecorr->num_apd_outputs - 1 - i], output[nchan_internal - 1 - i], output_frame ); } - - hSpar->hFbMixer->fb_cfg->num_in_chans = num_in_ingest; - } - else - { - hSpar->hFbMixer->fb_cfg->num_in_chans = num_in_ingest; } + hSpar->hFbMixer->fb_cfg->num_in_chans = num_in_ingest; + + /*---------------------------------------------------------------------* * Prepare CLDFB buffers *---------------------------------------------------------------------*/ /* set-up pointers */ - if ( st_ivas->hDecoderConfig->output_config != AUDIO_CONFIG_FOA ) + if ( hDecoderConfig->output_config != AUDIO_CONFIG_FOA ) { /* at this point, output channels are used as intermediate procesing buffers */ for ( in_ch = 0; in_ch < MAX_OUTPUT_CHANNELS; in_ch++ ) @@ -1076,7 +1062,7 @@ void ivas_spar_dec_upmixer( /* determine if we can skip certain data */ ivas_spar_get_skip_mat( hSpar, numch_out, numch_in, num_spar_bands, b_skip_mat ); /* this can be precomputed based on bitrate and format*/ - numch_out_dirac = st_ivas->hDecoderConfig->nchan_out; + numch_out_dirac = hDecoderConfig->nchan_out; for ( int16_t i_sf = 0; i_sf < MAX_PARAM_SPATIAL_SUBFRAMES; i_sf++ ) { @@ -1097,7 +1083,7 @@ void ivas_spar_dec_upmixer( for ( ts = 0; ts < MAX_PARAM_SPATIAL_SUBFRAMES; ts++ ) { /* determine SPAR parameters for this time slots */ - ivas_spar_get_parameters( hSpar, st_ivas->hDecoderConfig, ts + i_sf * MAX_PARAM_SPATIAL_SUBFRAMES, numch_out, numch_in, num_spar_bands, mixer_mat ); + ivas_spar_get_parameters( hSpar, hDecoderConfig, ts + i_sf * MAX_PARAM_SPATIAL_SUBFRAMES, numch_out, numch_in, num_spar_bands, mixer_mat ); for ( cldfb_band = 0; cldfb_band < num_cldfb_bands; cldfb_band++ ) { @@ -1146,7 +1132,11 @@ void ivas_spar_dec_upmixer( } } - if ( st_ivas->hDecoderConfig->output_config != AUDIO_CONFIG_FOA ) + if ( hDecoderConfig->output_config != AUDIO_CONFIG_FOA +#ifdef SPAR_STEREO_NO_DIRAC + && hDecoderConfig->output_config != AUDIO_CONFIG_STEREO && hDecoderConfig->output_config != AUDIO_CONFIG_MONO +#endif + ) { ivas_dirac_dec( st_ivas, output, nchan_internal, cldfb_in_ts_re, cldfb_in_ts_im, i_sf ); } @@ -1171,8 +1161,7 @@ void ivas_spar_dec_upmixer( } else { - if ( st_ivas->hDecoderConfig->output_config == AUDIO_CONFIG_FOA || - !( st_ivas->hOutSetup.output_config == AUDIO_CONFIG_BINAURAL || st_ivas->hOutSetup.output_config == AUDIO_CONFIG_BINAURAL_ROOM ) ) + if ( hDecoderConfig->output_config == AUDIO_CONFIG_FOA || !( st_ivas->hOutSetup.output_config == AUDIO_CONFIG_BINAURAL || st_ivas->hOutSetup.output_config == AUDIO_CONFIG_BINAURAL_ROOM ) ) { for ( ts = 0; ts < MAX_PARAM_SPATIAL_SUBFRAMES; ts++ ) { diff --git a/lib_dec/ivas_spar_md_dec.c b/lib_dec/ivas_spar_md_dec.c index 3d5f03b208..0feda3a83c 100644 --- a/lib_dec/ivas_spar_md_dec.c +++ b/lib_dec/ivas_spar_md_dec.c @@ -82,7 +82,9 @@ static void ivas_spar_md_fill_invalid_bands( ivas_spar_dec_matrices_t *pSpar_coe 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 ); + 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 use_planar_coeff, const int16_t sba_inactive_mode ); @@ -249,11 +251,8 @@ static ivas_error ivas_spar_md_dec_matrix_open( ivas_error ivas_spar_md_dec_open( ivas_spar_md_dec_state_t **hMdDec_out, /* i/o: SPAR MD decoder handle */ const DECODER_CONFIG_HANDLE hDecoderConfig, /* i : configuration structure */ - const int16_t num_channels /* i : number of internal channels */ -#ifdef SBA_HOA_HBR_IMPROV - , - const int16_t sba_order /* i : SBA order */ -#endif + const int16_t num_channels, /* i : number of internal channels */ + const int16_t sba_order /* i : SBA order */ ) { ivas_spar_md_dec_state_t *hMdDec; @@ -271,12 +270,9 @@ ivas_error ivas_spar_md_dec_open( return error; } -#ifdef SBA_HOA_HBR_IMPROV - hMdDec->spar_hoa_md_flag = ivas_sba_get_spar_hoa_md_flag( sba_order, hDecoderConfig->ivas_total_brate ); -#endif hMdDec->table_idx = 0; /* just to initialize state variables*/ - if ( ( error = ivas_spar_md_dec_init( hMdDec, hDecoderConfig, num_channels ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_spar_md_dec_init( hMdDec, hDecoderConfig, num_channels, sba_order ) ) != IVAS_ERR_OK ) { return error; } @@ -437,28 +433,18 @@ void ivas_spar_md_dec_close( ivas_error ivas_spar_md_dec_init( ivas_spar_md_dec_state_t *hMdDec, /* i/o: SPAR MD decoder handle */ const DECODER_CONFIG_HANDLE hDecoderConfig, /* i : configuration structure */ - const int16_t num_channels /* i : number of internal channels */ + const int16_t num_channels, /* i : number of internal channels */ + const int16_t sba_order /* i : SBA order */ ) { int16_t i, j, k; int16_t nchan_transport; float pFC[IVAS_MAX_NUM_BANDS], PR_minmax[2]; - hMdDec->spar_md_cfg.gen_bs = 1; // VE2DB : always 1 - can it be removed? - -#ifdef SBA_HOA_HBR_IMPROV + hMdDec->spar_hoa_md_flag = ivas_sba_get_spar_hoa_md_flag( sba_order, hDecoderConfig->ivas_total_brate ); hMdDec->spar_md.num_bands = ( hMdDec->spar_hoa_md_flag ) ? IVAS_MAX_NUM_BANDS : min( IVAS_MAX_NUM_BANDS, SPAR_DIRAC_SPLIT_START_BAND ); -#else - hMdDec->spar_md.num_bands = min( IVAS_MAX_NUM_BANDS, SPAR_DIRAC_SPLIT_START_BAND ); -#endif - ivas_spar_set_bitrate_config( &hMdDec->spar_md_cfg, hMdDec->table_idx, -#ifdef SBA_HOA_HBR_IMPROV - hMdDec->spar_md.num_bands -#else - min( IVAS_MAX_NUM_BANDS, SPAR_DIRAC_SPLIT_START_BAND ) -#endif - ); + ivas_spar_set_bitrate_config( &hMdDec->spar_md_cfg, hMdDec->table_idx, hMdDec->spar_md.num_bands ); nchan_transport = hMdDec->spar_md_cfg.nchan_transport; @@ -641,7 +627,7 @@ void ivas_spar_md_dec_process( char f_name[100]; int16_t num_bands = nB; int16_t num_subframes = 1, num_block_groups = 1, num_elements = 1, byte_size = sizeof( float ); - int16_t num_ch = 2 * sba_order + 2; + int16_t num_ch = ivas_sba_get_nchan_metadata( sba_order ); for ( b = 0; b < num_bands; b++ ) { sprintf( f_name, "spar_band_pred_coeffs_dec.bin" ); @@ -684,33 +670,20 @@ void ivas_spar_md_dec_process( } #endif -#ifndef SBA_SPAR_HARM - /* SPAR to DirAC and DirAC to SPAR conversion */ // VE2DB: -> "DirAC to SPAR conversion" only? - if ( st_ivas->sba_mode == SBA_MODE_SPAR ) // VE2DB: this looks obsolete - { -#else /* SPAR to DirAC conversion */ -#endif - ivas_spar_to_dirac( st_ivas, hMdDec, dtx_vad, num_bands_out ); + ivas_spar_to_dirac( st_ivas, hMdDec, dtx_vad, num_bands_out ); - /* set correct number of bands*/ - nB = IVAS_MAX_NUM_BANDS; - if ( bw == IVAS_RED_BAND_FACT ) - { - nB = nB >> 1; - } -#ifndef SBA_SPAR_HARM + /* set correct number of bands*/ + nB = IVAS_MAX_NUM_BANDS; + if ( bw == IVAS_RED_BAND_FACT ) + { + nB = nB >> 1; } -#endif /* expand DirAC MD to all time slots */ for ( i_ts = 1; i_ts < MAX_PARAM_SPATIAL_SUBFRAMES; i_ts++ ) { -#ifdef SBA_HOA_HBR_IMPROV for ( b = 0; b < hMdDec->spar_md.num_bands; b++ ) -#else - for ( b = 0; b < min( IVAS_MAX_NUM_BANDS, SPAR_DIRAC_SPLIT_START_BAND ); b++ ) -#endif { for ( j = 0; j < IVAS_SPAR_MAX_CH - 1; j++ ) { @@ -1371,7 +1344,6 @@ void ivas_spar_dec_gen_umx_mat( ) { int16_t i, j, b, i_ts, num_out_ch; - int16_t fb_ducking_flag = 0; // VE2DB: always 0 - can it be removed? num_out_ch = hMdDec->spar_md_cfg.num_umx_chs; @@ -1400,11 +1372,6 @@ void ivas_spar_dec_gen_umx_mat( } } } - - if ( fb_ducking_flag ) - { - assert( 0 ); /* fb_ducking_flag not supported */ - } } else { @@ -1419,7 +1386,7 @@ void ivas_spar_dec_gen_umx_mat( } } } - + #ifdef DEBUG_SBA_MD_DUMP { static FILE *f_mat = 0; @@ -1464,226 +1431,220 @@ static void ivas_spar_dec_parse_md_bs( const int16_t sba_inactive_mode ) { int16_t i, j, k, num_bands; + int16_t ii, jj, ndec, ndm, b, idx; uint16_t qsi; ivas_quant_strat_t qs; int16_t strat, freq_diff, no_ec; int16_t do_diff[IVAS_MAX_NUM_BANDS]; - int16_t planarCP = 0; + int16_t planarCP; + float quant[IVAS_SPAR_MAX_C_COEFF]; *dtx_vad = 1; *bands_bw = 1; qsi = 0; num_bands = hMdDec->spar_md.num_bands; - if ( hMdDec->spar_md_cfg.gen_bs == 1 ) + if ( ivas_total_brate > IVAS_SID_5k2 ) { - if ( ivas_total_brate > IVAS_SID_5k2 ) + if ( hMdDec->spar_md_cfg.quant_strat_bits > 0 ) { - if ( hMdDec->spar_md_cfg.quant_strat_bits > 0 ) + if ( ivas_total_brate >= BRATE_SPAR_Q_STRAT ) { - if ( ivas_total_brate >= BRATE_SPAR_Q_STRAT ) - { - /*only one bit written for quantization strategy to indicate either a fixed quantization strategy or dtx_vad==0 */ - qsi = get_next_indice( st0, 1 ); - if ( qsi == 1 ) - { - *dtx_vad = 0; - } - } - else + /*only one bit written for quantization strategy to indicate either a fixed quantization strategy or dtx_vad==0 */ + qsi = get_next_indice( st0, 1 ); + if ( qsi == 1 ) { - if ( sba_inactive_mode == 1 ) - { - *dtx_vad = 0; - qsi = hMdDec->spar_md_cfg.quant_strat_bits + 1; - } - else - { - qsi = get_next_indice( st0, hMdDec->spar_md_cfg.quant_strat_bits ); - } + *dtx_vad = 0; } } else { - qsi = 0; + if ( sba_inactive_mode == 1 ) + { + *dtx_vad = 0; + qsi = hMdDec->spar_md_cfg.quant_strat_bits + 1; + } + else + { + qsi = get_next_indice( st0, hMdDec->spar_md_cfg.quant_strat_bits ); + } } } else { - *dtx_vad = 0; + qsi = 0; } + } + else + { + *dtx_vad = 0; + } - hMdDec->dtx_vad = *dtx_vad; + hMdDec->dtx_vad = *dtx_vad; - if ( *dtx_vad == 0 ) - { - *nB = SPAR_DTX_BANDS; - *bands_bw = num_bands / *nB; + if ( *dtx_vad == 0 ) + { + *nB = SPAR_DTX_BANDS; + *bands_bw = num_bands / *nB; - for ( i = 0; i < *nB; i++ ) + for ( i = 0; i < *nB; i++ ) + { + for ( j = 0; j < IVAS_SPAR_MAX_CH - 1; j++ ) { - for ( j = 0; j < IVAS_SPAR_MAX_CH - 1; j++ ) - { - hMdDec->spar_md.band_coeffs[i].pred_re[j] = 0; - hMdDec->spar_md.band_coeffs[i].P_re[j] = 0; - } - hMdDec->valid_bands[i] = 1; + hMdDec->spar_md.band_coeffs[i].pred_re[j] = 0; + hMdDec->spar_md.band_coeffs[i].P_re[j] = 0; } - for ( i = 0; i < num_bands; i++ ) + hMdDec->valid_bands[i] = 1; + } + + for ( i = 0; i < num_bands; i++ ) + { + for ( j = 0; j < ( IVAS_SPAR_MAX_CH - IVAS_SPAR_MAX_DMX_CHS ); j++ ) { - for ( j = 0; j < ( IVAS_SPAR_MAX_CH - IVAS_SPAR_MAX_DMX_CHS ); j++ ) + for ( k = 0; k < ( IVAS_SPAR_MAX_DMX_CHS - 1 ); k++ ) { - for ( k = 0; k < ( IVAS_SPAR_MAX_DMX_CHS - 1 ); k++ ) - { - hMdDec->spar_md.band_coeffs[i].C_re[j][k] = 0; - } + hMdDec->spar_md.band_coeffs[i].C_re[j][k] = 0; } } + } + + 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 ); - 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 ); + for ( i = *nB - 1; i >= 0; i-- ) + { + ndec = hMdDec->spar_md_cfg.num_decorr_per_band[( *bands_bw ) * i]; + + for ( b = *bands_bw - 1; b >= 0; b-- ) { - int16_t ndec, b, idx; - for ( i = *nB - 1; i >= 0; i-- ) + idx = i * *bands_bw + b; + for ( j = 0; j < FOA_CHANNELS - 1; j++ ) { - ndec = hMdDec->spar_md_cfg.num_decorr_per_band[( *bands_bw ) * i]; - - for ( b = *bands_bw - 1; b >= 0; b-- ) - { - idx = i * *bands_bw + 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; - } + hMdDec->spar_md.band_coeffs[idx].pred_re[j] = hMdDec->spar_md.band_coeffs[i].pred_re[j]; } - *nB = num_bands; - *bands_bw = 1; + 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; } - - return; } - qs = hMdDec->spar_md_cfg.quant_strat[qsi]; - if ( ( qsi == 2 ) && ( use_planar_coeff ) ) - { - planarCP = 1; + *nB = num_bands; + *bands_bw = 1; + + return; + } + + qs = hMdDec->spar_md_cfg.quant_strat[qsi]; + + planarCP = 0; + if ( ( qsi == 2 ) && ( use_planar_coeff ) ) + { + planarCP = 1; #ifdef SPAR_HOA_DBG - fprintf( stdout, "planarCP = 1\n" ); + fprintf( stdout, "planarCP = 1\n" ); #endif - } - strat = get_next_indice( st0, 3 ); + } + strat = get_next_indice( st0, 3 ); + #ifdef SPAR_HOA_DBG - /*fprintf(stdout, "\n\n no_ec = %d, strat = %d\n", no_ec, strat);*/ + /*fprintf(stdout, "\n\n no_ec = %d, strat = %d\n", no_ec, strat);*/ #endif - freq_diff = 0; - no_ec = 0; + freq_diff = 0; + no_ec = 0; - if ( strat < 2 ) + if ( strat < 2 ) + { + *bands_bw = strat + 1; + *nB = num_bands / *bands_bw; + for ( i = 0; i < *nB; i++ ) { - *bands_bw = strat + 1; - *nB = num_bands / *bands_bw; - for ( i = 0; i < *nB; i++ ) - { - do_diff[i] = 0; - } + do_diff[i] = 0; } - else if ( strat < 4 ) + } + else if ( strat < 4 ) + { + *bands_bw = strat - 1; + *nB = num_bands / *bands_bw; + for ( i = 0; i < *nB; i++ ) { - *bands_bw = strat - 1; - *nB = num_bands / *bands_bw; - for ( i = 0; i < *nB; i++ ) - { - do_diff[i] = 0; - } - no_ec = 1; + do_diff[i] = 0; } - else - { - *bands_bw = 1; - *nB = num_bands; - - for ( i = 0; i < *nB; i++ ) - { - do_diff[i] = ( ( ( i + 1 ) & 3 ) != strat - 4 ); - } + no_ec = 1; + } + else + { + *bands_bw = 1; + *nB = num_bands; - ivas_map_prior_coeffs_quant( &hMdDec->spar_md_prev, &hMdDec->spar_md_cfg, qsi, *nB ); + for ( i = 0; i < *nB; i++ ) + { + do_diff[i] = ( ( ( i + 1 ) & 3 ) != strat - 4 ); } + + ivas_map_prior_coeffs_quant( &hMdDec->spar_md_prev, &hMdDec->spar_md_cfg, qsi, *nB ); + } #ifdef SPAR_HOA_DBG - fprintf( stdout, "\n\n no_ec = %d, strat = %d\n", no_ec, strat ); + fprintf( stdout, "\n\n no_ec = %d, strat = %d\n", no_ec, strat ); #endif - hMdDec->spar_md_cfg.prev_quant_idx = qsi; + hMdDec->spar_md_cfg.prev_quant_idx = qsi; - if ( no_ec == 0 ) - { - ivas_decode_arith_bs( hMdDec, st0, qsi, *nB, *bands_bw, do_diff, freq_diff, planarCP ); - } - else - { - ivas_decode_huffman_bs( hMdDec, st0, qsi, *nB, *bands_bw, planarCP ); - } + if ( no_ec == 0 ) + { + ivas_decode_arith_bs( hMdDec, st0, qsi, *nB, *bands_bw, do_diff, freq_diff, planarCP ); + } + else + { + ivas_decode_huffman_bs( hMdDec, st0, qsi, *nB, *bands_bw, planarCP ); + } - for ( i = 0; i < *nB; i++ ) - { - int16_t ii, jj; - int16_t ndec = hMdDec->spar_md_cfg.num_decorr_per_band[( *bands_bw ) * i]; - int16_t ndm = hMdDec->spar_md_cfg.num_dmx_chans_per_band[( *bands_bw ) * i]; - float quant[IVAS_SPAR_MAX_C_COEFF]; - ivas_deindex_real_index( hMdDec->spar_md.band_coeffs_idx[i].pred_index_re, qs.PR.q_levels[0], qs.PR.min, qs.PR.max, hMdDec->spar_md.band_coeffs[i].pred_re, ndm + ndec - 1 ); + for ( i = 0; i < *nB; i++ ) + { + ndec = hMdDec->spar_md_cfg.num_decorr_per_band[( *bands_bw ) * i]; + ndm = hMdDec->spar_md_cfg.num_dmx_chans_per_band[( *bands_bw ) * i]; - j = 0; - for ( ii = 0; ii < ndec; ii++ ) - { - for ( jj = 0; jj < ndm - 1; jj++ ) - { - quant[j] = hMdDec->spar_md.band_coeffs[i].C_re[ii][jj]; - j++; - } - } - ivas_deindex_real_index( hMdDec->spar_md.band_coeffs_idx[i].drct_index_re, qs.C.q_levels[0], qs.C.min, qs.C.max, quant, ndec * ( ndm - 1 ) ); - j = 0; - for ( ii = 0; ii < ndec; ii++ ) - { - for ( jj = 0; jj < ndm - 1; jj++ ) - { - hMdDec->spar_md.band_coeffs[i].C_re[ii][jj] = quant[j]; - j++; - } - } - ivas_deindex_real_index( hMdDec->spar_md.band_coeffs_idx[i].decd_index_re, qs.P_r.q_levels[0], qs.P_r.min, qs.P_r.max, hMdDec->spar_md.band_coeffs[i].P_re, ndm + ndec - 1 ); - /* Store prior coefficient indices */ - for ( j = 0; j < ndm + ndec - 1; j++ ) - { - hMdDec->spar_md_prev.band_coeffs_idx[i].pred_index_re[j] = hMdDec->spar_md.band_coeffs_idx[i].pred_index_re[j]; - } - for ( j = 0; j < ndec * ( ndm - 1 ); j++ ) + ivas_deindex_real_index( hMdDec->spar_md.band_coeffs_idx[i].pred_index_re, qs.PR.q_levels[0], qs.PR.min, qs.PR.max, hMdDec->spar_md.band_coeffs[i].pred_re, ndm + ndec - 1 ); + + j = 0; + for ( ii = 0; ii < ndec; ii++ ) + { + for ( jj = 0; jj < ndm - 1; jj++ ) { - hMdDec->spar_md_prev.band_coeffs_idx[i].drct_index_re[j] = hMdDec->spar_md.band_coeffs_idx[i].drct_index_re[j]; + quant[j] = hMdDec->spar_md.band_coeffs[i].C_re[ii][jj]; + j++; } - for ( j = 0; j < ndec; j++ ) + } + + ivas_deindex_real_index( hMdDec->spar_md.band_coeffs_idx[i].drct_index_re, qs.C.q_levels[0], qs.C.min, qs.C.max, quant, ndec * ( ndm - 1 ) ); + + j = 0; + for ( ii = 0; ii < ndec; ii++ ) + { + for ( jj = 0; jj < ndm - 1; jj++ ) { - hMdDec->spar_md_prev.band_coeffs_idx[i].decd_index_re[j] = hMdDec->spar_md.band_coeffs_idx[i].decd_index_re[j]; + hMdDec->spar_md.band_coeffs[i].C_re[ii][jj] = quant[j]; + j++; } - hMdDec->valid_bands[i] |= ( do_diff[i] == 0 ) ? 1 : 0; } - } - else - { - *dtx_vad = hMdDec->spar_md.dtx_vad; - *nB = num_bands; - *bands_bw = num_bands / *nB; - for ( i = 0; i < *nB; i++ ) + ivas_deindex_real_index( hMdDec->spar_md.band_coeffs_idx[i].decd_index_re, qs.P_r.q_levels[0], qs.P_r.min, qs.P_r.max, hMdDec->spar_md.band_coeffs[i].P_re, ndm + ndec - 1 ); + + /* Store prior coefficient indices */ + for ( j = 0; j < ndm + ndec - 1; j++ ) { - hMdDec->valid_bands[i] = 1; + hMdDec->spar_md_prev.band_coeffs_idx[i].pred_index_re[j] = hMdDec->spar_md.band_coeffs_idx[i].pred_index_re[j]; + } + for ( j = 0; j < ndec * ( ndm - 1 ); j++ ) + { + hMdDec->spar_md_prev.band_coeffs_idx[i].drct_index_re[j] = hMdDec->spar_md.band_coeffs_idx[i].drct_index_re[j]; + } + for ( j = 0; j < ndec; j++ ) + { + hMdDec->spar_md_prev.band_coeffs_idx[i].decd_index_re[j] = hMdDec->spar_md.band_coeffs_idx[i].decd_index_re[j]; } + hMdDec->valid_bands[i] |= ( do_diff[i] == 0 ) ? 1 : 0; } + #ifdef SPAR_HOA_DBG int16_t b; b = 0; @@ -1776,14 +1737,14 @@ static void ivas_decode_arith_bs( const int16_t freq_diff, const int16_t planarCP ) { - int16_t i, ndm, ndec; + int16_t i, j, ndm, ndec; ivas_cell_dim_t pred_cell_dims[IVAS_MAX_NUM_BANDS]; ivas_cell_dim_t drct_cell_dims[IVAS_MAX_NUM_BANDS]; ivas_cell_dim_t decd_cell_dims[IVAS_MAX_NUM_BANDS]; ivas_cell_dim_t decx_cell_dims[IVAS_MAX_NUM_BANDS]; int16_t symbol_arr_re[IVAS_MAX_INPUT_LEN]; int16_t symbol_arr_old_re[IVAS_MAX_INPUT_LEN]; - int16_t any_diff = 0; + int16_t any_diff; for ( i = 0; i < nB; i++ ) { @@ -1791,7 +1752,6 @@ static void ivas_decode_arith_bs( ndec = hMdDec->spar_md_cfg.num_decorr_per_band[bands_bw * i]; pred_cell_dims[i].dim1 = ndm + ndec - 1; -#ifdef SBA_HOA_HBR_IMPROV if ( hMdDec->spar_hoa_md_flag ) { if ( i >= SPAR_DIRAC_SPLIT_START_BAND ) @@ -1799,7 +1759,6 @@ static void ivas_decode_arith_bs( pred_cell_dims[i].dim1 -= ( FOA_CHANNELS - 1 ); } } -#endif pred_cell_dims[i].dim2 = 1; drct_cell_dims[i].dim1 = ndec; drct_cell_dims[i].dim2 = ndm - 1; @@ -1809,6 +1768,7 @@ static void ivas_decode_arith_bs( decx_cell_dims[i].dim2 = 1; } + any_diff = 0; for ( i = 0; i < nB; i++ ) { if ( pDo_diff[i] != 0 ) @@ -1820,10 +1780,8 @@ static void ivas_decode_arith_bs( if ( any_diff == 1 ) { -#ifdef SBA_HOA_HBR_IMPROV if ( hMdDec->spar_hoa_md_flag ) { - int16_t j; for ( i = 0; i < nB; i++ ) { if ( i >= SPAR_DIRAC_SPLIT_START_BAND ) @@ -1836,7 +1794,6 @@ static void ivas_decode_arith_bs( } } } -#endif ivas_copy_band_coeffs_idx_to_arr( hMdDec->spar_md_prev.band_coeffs_idx_mapped, nB, symbol_arr_old_re, pred_cell_dims, PRED_COEFF, planarCP ); } @@ -1845,10 +1802,8 @@ static void ivas_decode_arith_bs( ivas_fill_band_coeffs_idx( hMdDec->spar_md.band_coeffs_idx, nB, symbol_arr_re, pred_cell_dims, PRED_COEFF, planarCP ); -#ifdef SBA_HOA_HBR_IMPROV if ( hMdDec->spar_hoa_md_flag ) { - int16_t j; for ( i = 0; i < nB; i++ ) { if ( i >= SPAR_DIRAC_SPLIT_START_BAND ) @@ -1865,7 +1820,6 @@ static void ivas_decode_arith_bs( } } } -#endif if ( any_diff == 1 ) { @@ -2102,12 +2056,11 @@ static void ivas_decode_huffman_bs( const int16_t planarCP ) { int16_t i, j; + int16_t ndm, ndec; + int16_t pred_dim, drct_dim, decd_dim, pred_offset; for ( i = 0; i < nB; i++ ) { - int16_t ndm, ndec; - int16_t pred_dim, drct_dim, decd_dim, pred_offset; - ndm = hMdDec->spar_md_cfg.num_dmx_chans_per_band[bands_bw * i]; ndec = hMdDec->spar_md_cfg.num_decorr_per_band[bands_bw * i]; @@ -2115,7 +2068,6 @@ static void ivas_decode_huffman_bs( drct_dim = ndec * ( ndm - 1 ); decd_dim = ndec; pred_offset = 0; -#ifdef SBA_HOA_HBR_IMPROV if ( hMdDec->spar_hoa_md_flag ) { if ( i >= SPAR_DIRAC_SPLIT_START_BAND ) @@ -2123,15 +2075,12 @@ static void ivas_decode_huffman_bs( pred_offset = FOA_CHANNELS - 1; } } -#endif for ( j = pred_offset; j < pred_dim; j++ ) { - ivas_huffman_decode( &hMdDec->huff_coeffs.pred_huff_re[qsi], st0, - &hMdDec->spar_md.band_coeffs_idx[i].pred_index_re[j] ); + ivas_huffman_decode( &hMdDec->huff_coeffs.pred_huff_re[qsi], st0, &hMdDec->spar_md.band_coeffs_idx[i].pred_index_re[j] ); } -#ifdef SBA_HOA_HBR_IMPROV if ( hMdDec->spar_hoa_md_flag ) { if ( i >= SPAR_DIRAC_SPLIT_START_BAND ) @@ -2142,7 +2091,6 @@ static void ivas_decode_huffman_bs( } } } -#endif for ( j = 0; j < drct_dim; j++ ) { @@ -2152,8 +2100,7 @@ static void ivas_decode_huffman_bs( } else { - ivas_huffman_decode( &hMdDec->huff_coeffs.drct_huff_re[qsi], st0, - &hMdDec->spar_md.band_coeffs_idx[i].drct_index_re[j] ); + ivas_huffman_decode( &hMdDec->huff_coeffs.drct_huff_re[qsi], st0, &hMdDec->spar_md.band_coeffs_idx[i].drct_index_re[j] ); } } @@ -2165,8 +2112,7 @@ static void ivas_decode_huffman_bs( } else { - ivas_huffman_decode( &hMdDec->huff_coeffs.decd_huff_re[qsi], st0, - &hMdDec->spar_md.band_coeffs_idx[i].decd_index_re[j] ); + ivas_huffman_decode( &hMdDec->huff_coeffs.decd_huff_re[qsi], st0, &hMdDec->spar_md.band_coeffs_idx[i].decd_index_re[j] ); } } } @@ -2390,6 +2336,7 @@ static void ivas_spar_unquant_dtx_indicies( pr_min_max[0] = pSpar_md->min_max[0]; pr_min_max[1] = pSpar_md->min_max[1]; + for ( b = 0; b < nB; b++ ) { for ( i = 0; i < FOA_CHANNELS - 1; i++ ) @@ -2427,7 +2374,7 @@ static void ivas_parse_parameter_bitstream_dtx( int16_t *num_dmx_per_band, int16_t *num_dec_per_band ) { - int16_t i, j; + int16_t i, j, ndec, ndm; float val; int16_t idx; float pr_min_max[2]; @@ -2440,8 +2387,8 @@ static void ivas_parse_parameter_bitstream_dtx( for ( i = 0; i < num_bands; i++ ) { - int16_t ndec = num_dec_per_band[bw * i]; - int16_t ndm = num_dmx_per_band[bw * i]; + ndec = num_dec_per_band[bw * i]; + ndm = num_dmx_per_band[bw * i]; for ( j = 0; j < FOA_CHANNELS - 1; j++ ) { @@ -2794,14 +2741,7 @@ void ivas_spar_to_dirac( /* DirAC MD averaged over 4 subframes and converted to SPAR format similar to encoder processing */ if ( hMdDec->spar_md_cfg.nchan_transport > 1 ) { - ivas_get_spar_md_from_dirac( azi_dirac, ele_dirac, diffuseness, 1, NULL, &hMdDec->spar_md, &hMdDec->spar_md_cfg, - end_band, num_bands_out, -#ifdef SBA_HOA_HBR_IMPROV - ( hMdDec->spar_hoa_md_flag ) ? 1 : sba_order_internal, -#else - sba_order_internal, -#endif - dtx_vad, NULL ); + ivas_get_spar_md_from_dirac( azi_dirac, ele_dirac, diffuseness, 1, NULL, &hMdDec->spar_md, &hMdDec->spar_md_cfg, end_band, num_bands_out, ( hMdDec->spar_hoa_md_flag ) ? 1 : sba_order_internal, dtx_vad, NULL ); /* temporarily copy frame-wise prediction coefficients in DirAC bands*/ for ( pred_idx = 0; pred_idx < FOA_CHANNELS - 1; pred_idx++ ) @@ -2813,14 +2753,7 @@ void ivas_spar_to_dirac( } } - ivas_get_spar_md_from_dirac( azi_dirac, ele_dirac, diffuseness, MAX_PARAM_SPATIAL_SUBFRAMES, NULL, &hMdDec->spar_md, &hMdDec->spar_md_cfg, - end_band, num_bands_out, -#ifdef SBA_HOA_HBR_IMPROV - ( hMdDec->spar_hoa_md_flag ) ? 1 : sba_order_internal, -#else - sba_order_internal, -#endif - dtx_vad, NULL ); + ivas_get_spar_md_from_dirac( azi_dirac, ele_dirac, diffuseness, MAX_PARAM_SPATIAL_SUBFRAMES, NULL, &hMdDec->spar_md, &hMdDec->spar_md_cfg, end_band, num_bands_out, ( hMdDec->spar_hoa_md_flag ) ? 1 : sba_order_internal, dtx_vad, NULL ); /* expand DirAC TC 20ms MD for residual channels to all subframes*/ for ( block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; block++ ) diff --git a/lib_dec/ivas_stat_dec.h b/lib_dec/ivas_stat_dec.h index 75af2658d3..50369fab6d 100644 --- a/lib_dec/ivas_stat_dec.h +++ b/lib_dec/ivas_stat_dec.h @@ -41,7 +41,7 @@ #include "ivas_stat_com.h" #include "ivas_stat_rend.h" #ifdef EXT_RENDERER -#include "common_api_types.h" +#include "common_api_types.h" // VE2AT: don't we want to avoid this include in the library? I admit that the rules hefre are not 100% clear to me but introducing it just for IVAS_QUATERNION is not necessry I think #endif @@ -807,9 +807,7 @@ typedef struct ivas_spar_md_dec_state_t ivas_huff_coeffs_t huff_coeffs; int16_t table_idx; int16_t dtx_vad; -#ifdef SBA_HOA_HBR_IMPROV int16_t spar_hoa_md_flag; -#endif } ivas_spar_md_dec_state_t; @@ -876,7 +874,7 @@ typedef struct ivas_spar_dec_lib_t int16_t dirac_to_spar_md_bands[DIRAC_MAX_NBANDS]; int16_t enc_param_start_band; int32_t core_nominal_brate; /* Nominal bitrate for core coding */ - int32_t i_subframe; + int16_t i_subframe; #ifdef DEBUG_SBA_AUDIO_DUMP int16_t numOutChannels; @@ -986,7 +984,7 @@ typedef struct mct_dec_data_structure /*----------------------------------------------------------------------------------* * EFAP structures *----------------------------------------------------------------------------------*/ - +// VE2AT: move to ivas_rom_rend.h ? typedef struct EFAP_VERTEX { float azi; /* azimuth of the loudspeaker */ @@ -1049,7 +1047,7 @@ typedef struct EFAP /*----------------------------------------------------------------------------------* * VBAP structures *----------------------------------------------------------------------------------*/ - +// VE2AT: move to ivas_rom_rend.h ? enum SpeakerNodeGroup { SPEAKER_NODE_BOTTOM_HALF, @@ -1107,7 +1105,7 @@ typedef struct vbap_data_structure /*----------------------------------------------------------------------------------* * renderer structures *----------------------------------------------------------------------------------*/ - +// VE2AT: move to ivas_rom_rend.h ? typedef struct renderer_struct { float prev_gains[MAX_CICP_CHANNELS - 1][MAX_OUTPUT_CHANNELS]; @@ -1174,7 +1172,7 @@ typedef struct ivas_masa_decoder_struct /*----------------------------------------------------------------------------------* * Binaural Rendering structure *----------------------------------------------------------------------------------*/ - +// VE2AT: move to ivas_rom_rend.h ? /* Binaural reverberator structure */ typedef struct ivas_binaural_reverb_struct { @@ -1293,7 +1291,7 @@ typedef struct ivas_binaural_rendering_struct /*----------------------------------------------------------------------------------* * Head tracking data structure *----------------------------------------------------------------------------------*/ - +// VE2AT: move to ivas_rom_rend.h ? #ifndef EXT_RENDERER /* Quaternion type for head orientation */ typedef struct Quaternion_struct @@ -1326,7 +1324,7 @@ typedef struct ivas_binaural_head_track_struct /*----------------------------------------------------------------------------------* * TD ISm Object Renderer structure *----------------------------------------------------------------------------------*/ - +// VE2AT: move to ivas_rom_rend.h ? typedef struct { SFX_OpMode_t OpMode; /* Operating mode. This effect can only be TRANSIENT or OFF. */ @@ -1634,7 +1632,7 @@ typedef struct ivas_binaural_td_rendering_struct /*------------------------------------------------------------------------------------------* * Crend structures *------------------------------------------------------------------------------------------*/ - +// VE2AT: move to ivas_rom_rend.h ? typedef struct ivas_hrtfs_structure { float *pOut_to_bin_re[MAX_INTERN_CHANNELS][BINAURAL_CHANNELS]; @@ -1656,6 +1654,7 @@ typedef struct ivas_hrtfs_structure /* Reverberator structures */ + typedef struct ivas_roomAcoustics_t { int16_t override; diff --git a/lib_dec/ivas_stereo_mdct_core_dec.c b/lib_dec/ivas_stereo_mdct_core_dec.c index 82ad3fc95b..d0d05f1fa0 100644 --- a/lib_dec/ivas_stereo_mdct_core_dec.c +++ b/lib_dec/ivas_stereo_mdct_core_dec.c @@ -340,11 +340,7 @@ void stereo_mdct_core_dec( #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 -#ifdef FIX_TCX10_STEREO_PROC 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 ); -#else - 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], 0, sts[0]->last_core, sts[1]->last_core, 0 ); -#endif } ivas_mdct_core_tns_ns( hCPE, 0, fUseTns, tnsData, x, Aq, 0 ); diff --git a/lib_dec/ivas_stereo_mdct_stereo_dec.c b/lib_dec/ivas_stereo_mdct_stereo_dec.c index 1bdbb5eda7..67b893a9f2 100644 --- a/lib_dec/ivas_stereo_mdct_stereo_dec.c +++ b/lib_dec/ivas_stereo_mdct_stereo_dec.c @@ -214,12 +214,8 @@ void stereo_decoder_tcx( const int16_t core_l, /* i : core for left channel (TCX20/TCX10) */ const int16_t core_r, /* i : core for right channel (TCX20/TCX10) */ const int16_t igf, /* i : flag for IGF activity */ -#ifdef FIX_TCX10_STEREO_PROC const int16_t L_frameTCX_l, /* i : TCX frame length of left channel */ const int16_t L_frameTCX_r, /* i : TCX frame length of right channel */ -#else - const int16_t L_frame, /* i : TCX frame length */ -#endif const int16_t mct_on, /* i : flag mct block (1) or stereo (0) */ const int16_t last_core_l, /* i : last core for left channel */ const int16_t last_core_r, /* i : last core for right channel */ @@ -333,19 +329,11 @@ void stereo_decoder_tcx( if ( ( nrgRatio > 1.0f ) && ( k < ( ( core_r == TCX_20_CORE ) ? 1 : NB_DIV ) ) ) { -#ifdef FIX_TCX10_STEREO_PROC v_multc( spec_r[k], nrgRatio, spec_r[k], L_frameTCX_r ); -#else - v_multc( spec_r[k], nrgRatio, spec_r[k], L_frame / ( ( core_r == TCX_20_CORE ) ? 1 : NB_DIV ) ); -#endif } else if ( ( nrgRatio < 1.0f ) && ( k < ( ( core_l == TCX_20_CORE ) ? 1 : NB_DIV ) ) ) { -#ifdef FIX_TCX10_STEREO_PROC v_multc( spec_l[k], 1.0f / nrgRatio, spec_l[k], L_frameTCX_l ); -#else - v_multc( spec_l[k], 1.0f / nrgRatio, spec_l[k], L_frame / ( ( core_l == TCX_20_CORE ) ? 1 : NB_DIV ) ); -#endif } } } /* for k */ diff --git a/lib_dec/ivas_tcx_core_dec.c b/lib_dec/ivas_tcx_core_dec.c index 41196b6b02..8e56ed5ef7 100644 --- a/lib_dec/ivas_tcx_core_dec.c +++ b/lib_dec/ivas_tcx_core_dec.c @@ -51,7 +51,14 @@ * Local prototypes *-------------------------------------------------------------*/ +#ifdef FIX_TCX_DEC_RECONF_BFI +static void dec_prm_tcx( Decoder_State *st, int16_t param[], int16_t param_lpc[], int16_t *total_nbbits, const int16_t last_element_mode, int16_t *bitsRead ); +#else static void dec_prm_tcx( Decoder_State *st, int16_t param[], int16_t param_lpc[], int16_t *total_nbbits, int16_t *bitsRead ); +#endif +#ifdef FIX_TCX_DEC_RECONF_BFI +static void stereo_tcx_dec_mode_switch_reconf( Decoder_State *st, const int16_t MCT_flag, const int16_t last_element_mode ); +#endif /*-------------------------------------------------------------* @@ -66,7 +73,9 @@ void stereo_tcx_init_dec( const int16_t last_element_mode /* i : element mode of previous frame */ ) { +#ifndef FIX_TCX_DEC_RECONF_BFI int16_t frame_size_index; +#endif TCX_LTP_DEC_HANDLE hTcxLtpDec = st->hTcxLtpDec; TCX_DEC_HANDLE hTcxDec = st->hTcxDec; @@ -125,9 +134,19 @@ void stereo_tcx_init_dec( } } +#ifdef FIX_TCX_DEC_RECONF_BFI + if ( ( st->bits_frame_nominal != st->last_bits_frame_nominal ) || + ( st->bwidth != st->last_bwidth ) || + ( st->last_core != TCX_20_CORE && st->last_core != TCX_10_CORE && !( st->prev_bfi == 1 && st->last_core == ACELP_CORE && st->last_con_tcx == 1 ) ) || + ( st->idchan == 1 && st->element_mode == IVAS_CPE_MDCT && last_element_mode != IVAS_CPE_MDCT ) ) +#else if ( ( st->bits_frame_nominal != st->last_bits_frame_nominal ) || ( st->bwidth != st->last_bwidth ) || ( st->last_core != TCX_20_CORE && st->last_core != TCX_10_CORE && !( st->prev_bfi == 1 && st->last_core == ACELP_CORE && st->last_con_tcx == 1 ) ) || ( st->idchan == 1 && st->element_mode == IVAS_CPE_MDCT && last_element_mode != IVAS_CPE_MDCT ) ) +#endif { /*re-initialization*/ +#ifdef FIX_TCX_DEC_RECONF_BFI + stereo_tcx_dec_mode_switch_reconf( st, MCT_flag, last_element_mode ); +#else st->rate_switching_init = 1; /* Identify frame type - TCX Reconfiguration */ @@ -151,6 +170,7 @@ void stereo_tcx_init_dec( /* Reconfigure Core */ mode_switch_decoder_LPD( st, st->bwidth, st->bits_frame_nominal * FRAMES_PER_SEC, st->last_bits_frame_nominal * FRAMES_PER_SEC, frame_size_index, MCT_flag, last_element_mode ); +#endif } return; @@ -284,7 +304,11 @@ void stereo_tcx_core_dec( tcx_current_overlap_mode = st->hTcxCfg->tcx_curr_overlap_mode; #endif +#ifdef FIX_TCX_DEC_RECONF_BFI + dec_prm_tcx( st, param, param_lpc, &total_nbbits, last_element_mode, &bitsRead ); +#else dec_prm_tcx( st, param, param_lpc, &total_nbbits, &bitsRead ); +#endif #ifdef FIX_IVAS_337 /*IVAS-337 consider BER */ if ( !st->rate_switching_init && st->BER_detect ) @@ -808,6 +832,9 @@ static void dec_prm_tcx( int16_t param[], /* o : decoded parameters */ int16_t param_lpc[], /* o : LPC parameters */ int16_t *total_nbbits, /* i/o: number of bits / decoded bits */ +#ifdef FIX_TCX_DEC_RECONF_BFI + const int16_t last_element_mode, +#endif int16_t *bitsRead /* o : number of read bits */ ) { @@ -861,6 +888,14 @@ static void dec_prm_tcx( st->prev_bfi = 1; } +#ifdef FIX_TCX_DEC_RECONF_BFI + /* possible need for reconfiguration can only be decided correctly once last_core_from_bs has been decoded */ + if ( ( st->last_core != st->last_core_from_bs ) && ( st->last_core_from_bs != TCX_20_CORE && st->last_core_from_bs != TCX_10_CORE && !( st->prev_bfi == 1 && st->last_core_from_bs == ACELP_CORE && st->last_con_tcx == 1 ) ) ) + { + stereo_tcx_dec_mode_switch_reconf( st, 0, last_element_mode ); + } +#endif + st->last_core = st->last_core_from_bs; /*for TCX 10 force last_core to be TCX since ACELP as previous core is forbidden*/ @@ -923,3 +958,38 @@ static void dec_prm_tcx( return; } + +#ifdef FIX_TCX_DEC_RECONF_BFI +static void stereo_tcx_dec_mode_switch_reconf( + Decoder_State *st, + const int16_t MCT_flag, + const int16_t last_element_mode +) +{ + int16_t frame_size_index; + + st->rate_switching_init = 1; + + /* Identify frame type - TCX Reconfiguration */ + for ( frame_size_index = 0; frame_size_index < FRAME_SIZE_NB; frame_size_index++ ) + { + if ( frame_size_index < FRAME_SIZE_NB - 1 ) + { + if ( ( FrameSizeConfig[frame_size_index].frame_bits <= st->bits_frame_nominal ) && ( FrameSizeConfig[frame_size_index + 1].frame_bits > st->bits_frame_nominal ) ) + { + break; + } + } + else + { + if ( FrameSizeConfig[frame_size_index].frame_bits <= st->bits_frame_nominal ) + { + break; + } + } + } + + /* Reconfigure Core */ + mode_switch_decoder_LPD( st, st->bwidth, st->bits_frame_nominal * FRAMES_PER_SEC, st->last_bits_frame_nominal * FRAMES_PER_SEC, frame_size_index, MCT_flag, last_element_mode ); +} +#endif diff --git a/lib_dec/ivas_vbap.c b/lib_dec/ivas_vbap.c index 2534854e8b..f0960bd127 100644 --- a/lib_dec/ivas_vbap.c +++ b/lib_dec/ivas_vbap.c @@ -29,7 +29,7 @@ the United Nations Convention on Contracts on the International Sales of Goods. *******************************************************************************************************/ - +// VE2AT: move to lib_rend ? #include #include "options.h" #include diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index c63a2e064e..d16d1f2494 100644 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -1767,7 +1767,7 @@ static ivas_error printConfigInfo_dec( else if ( st_ivas->ivas_format == SBA_FORMAT ) { #ifdef PRINT_SBA_ORDER - fprintf( stdout, "Input configuration: Scene Based Analysis, Ambisonic order %i%s, %d transport channel(s)\n", st_ivas->sba_order, st_ivas->sba_planar ? " (Planar)" : "", st_ivas->nchan_transport ); + fprintf( stdout, "Input configuration: Scene Based Audio, Ambisonic order %i%s, %d transport channel(s)\n", st_ivas->sba_order, st_ivas->sba_planar ? " (Planar)" : "", st_ivas->nchan_transport ); #else fprintf( stdout, "Input configuration: SBA - %d transport channel(s) %s\n", st_ivas->nchan_transport, st_ivas->sba_planar ? "(Planar)" : "" ); #endif diff --git a/lib_enc/igf_enc.c b/lib_enc/igf_enc.c index 6050354a8f..e355cd2083 100755 --- a/lib_enc/igf_enc.c +++ b/lib_enc/igf_enc.c @@ -462,7 +462,7 @@ static void IGF_CalculateEnvelope( float diffSFM; float shiftedSFM = 0.f; - tmp_tb = IGF_getSFM_new( pPowerSpectrum, hPrivateData->logSpec, swb_offset[sfb], swb_offset[sfb + 1] ) / IGF_getCrest_new( hPrivateData->logSpec, swb_offset[sfb], swb_offset[sfb + 1] ); + tmp_tb = IGF_getSFM_new( pPowerSpectrum, hPrivateData->logSpec, swb_offset[sfb], swb_offset[sfb + 1] ) / IGF_getCrest_new( hPrivateData->logSpec, swb_offset[sfb], swb_offset[sfb + 1] ); tmp_sb = IGF_getSFM_new( pPowerSpectrum, hPrivateData->logSpec, tmp, strt_cpy ) / IGF_getCrest_new( hPrivateData->logSpec, tmp, strt_cpy ); if ( last_core_acelp || hPrivateData->wasTransient ) @@ -494,12 +494,12 @@ static void IGF_CalculateEnvelope( if ( slope < -threshold ) { int16_t shift = width >> 1; - shiftedSFM = IGF_getSFM_new( pPowerSpectrum, hPrivateData->logSpec, swb_offset[sfb] - shift, swb_offset[sfb + 1] - shift ) / IGF_getCrest_new ( hPrivateData->logSpec, swb_offset[sfb] - shift, swb_offset[sfb + 1] - shift ); + shiftedSFM = IGF_getSFM_new( pPowerSpectrum, hPrivateData->logSpec, swb_offset[sfb] - shift, swb_offset[sfb + 1] - shift ) / IGF_getCrest_new( hPrivateData->logSpec, swb_offset[sfb] - shift, swb_offset[sfb + 1] - shift ); } else if ( ( slope > 1.f * threshold ) && ( sfb != hGrid->sfbWrap[hGrid->nTiles] - 1 ) ) { int16_t shift = width >> 1; - shiftedSFM = IGF_getSFM_new( pPowerSpectrum, hPrivateData->logSpec, swb_offset[sfb] + shift, swb_offset[sfb + 1] + shift ) / IGF_getCrest_new ( hPrivateData->logSpec, swb_offset[sfb] + shift, swb_offset[sfb + 1] + shift ); + shiftedSFM = IGF_getSFM_new( pPowerSpectrum, hPrivateData->logSpec, swb_offset[sfb] + shift, swb_offset[sfb + 1] + shift ) / IGF_getCrest_new( hPrivateData->logSpec, swb_offset[sfb] + shift, swb_offset[sfb + 1] + shift ); } if ( shiftedSFM > 0.04f ) diff --git a/lib_enc/init_enc.c b/lib_enc/init_enc.c index 1ae2f48c66..4e4ab24369 100644 --- a/lib_enc/init_enc.c +++ b/lib_enc/init_enc.c @@ -785,7 +785,12 @@ ivas_error init_encoder( } initFdCngEnc( st->hFdCngEnc, st->input_Fs, st->cldfbAnaEnc->scale ); - configureFdCngEnc( st->hFdCngEnc, st->bwidth, st->rf_mode && st->total_brate == ACELP_13k20 ? ACELP_9k60 : st->total_brate ); + + /* initialization for IVAS modes happens in first frame pre-processing */ + if ( st->element_mode == EVS_MONO ) + { + configureFdCngEnc( st->hFdCngEnc, st->bwidth, st->rf_mode && st->total_brate == ACELP_13k20 ? ACELP_9k60 : st->total_brate ); + } } else { diff --git a/lib_enc/ivas_agc_enc.c b/lib_enc/ivas_agc_enc.c index 0f3274f43c..b7f69b38b0 100644 --- a/lib_enc/ivas_agc_enc.c +++ b/lib_enc/ivas_agc_enc.c @@ -60,24 +60,42 @@ static int16_t ivas_agc_writeBits( FILE *stream, const int16_t n_channels, ivas_ #endif #ifdef AGC_ENABLE_FOR_LBR +#ifdef DEBUG_AGC_ENCODER_CMD_OPTION /*-----------------------------------------------------------------------------------------* - * Function ivas_agc_enc_get_enablement_flag() + * Function ivas_agc_enc_get_flag() * * This function determines if AGC should be enabled or disabled. * 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. * *-----------------------------------------------------------------------------------------*/ +#else +/*-----------------------------------------------------------------------------------------* + * Function ivas_agc_enc_get_flag() + * + * This function determines if AGC should be enabled or disabled. + * AGC is enabled only if there is one transport channel. + * + *-----------------------------------------------------------------------------------------*/ +#endif -int16_t ivas_agc_enc_get_enablement_flag( - IVAS_ENC_AGC agc_configuration, - int16_t nchan_transport ) +/*! r: AGC enable flag */ +int16_t ivas_agc_enc_get_flag( +#ifdef DEBUG_AGC_ENCODER_CMD_OPTION + int16_t agc_configuration, /* i : AGC configuration from command-line */ +#endif + int16_t nchan_transport /* i : number of transport channels */ +) { - return (int16_t) ( ( agc_configuration == IVAS_ENC_AGC_UNDEFINED ) - ? ( nchan_transport == 1 ) - : agc_configuration ); -} +#ifdef DEBUG_AGC_ENCODER_CMD_OPTION + return (int16_t) ( ( agc_configuration == SBA_AGC_DEFAULT ) + ? ( nchan_transport == 1 ) + : agc_configuration ); +#else + return (int16_t) ( nchan_transport == 1 ); #endif +} +#endif /* AGC_ENABLE_FOR_LBR */ /*-----------------------------------------------------------------------------------------* * Function ivas_agc_enc_init() @@ -127,6 +145,7 @@ static void ivas_agc_enc_init( return; } + /*------------------------------------------------------------------------- * ivas_spar_agc_enc_open() * @@ -140,7 +159,11 @@ ivas_error ivas_spar_agc_enc_open( ) { ivas_agc_enc_state_t *hAgc; +#ifdef FIX_AGC_WINFUNC_MEMORY + int16_t input_frame, delay; +#else int16_t input_frame; +#endif if ( ( hAgc = (ivas_agc_enc_state_t *) count_malloc( sizeof( ivas_agc_enc_state_t ) ) ) == NULL ) { @@ -148,8 +171,15 @@ ivas_error ivas_spar_agc_enc_open( } input_frame = (int16_t) ( input_Fs / FRAMES_PER_SEC ); +#ifdef FIX_AGC_WINFUNC_MEMORY + delay = NS2SA( input_Fs, ( IVAS_ENC_DELAY_NS + IVAS_DEC_DELAY_NS ) ); +#endif +#ifdef FIX_AGC_WINFUNC_MEMORY + if ( ( hAgc->agc_com.winFunc = (float *) count_malloc( sizeof( float ) * ( input_frame - delay ) ) ) == NULL ) +#else if ( ( hAgc->agc_com.winFunc = (float *) count_malloc( sizeof( float ) * input_frame ) ) == NULL ) +#endif { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR AGC encoder" ); } @@ -164,13 +194,18 @@ ivas_error ivas_spar_agc_enc_open( return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR AGC encoder" ); } +#ifdef FIX_AGC_WINFUNC_MEMORY + ivas_agc_enc_init( hAgc, input_frame, nchan_inp, delay ); +#else ivas_agc_enc_init( hAgc, input_frame, nchan_inp, NS2SA( input_Fs, ( IVAS_ENC_DELAY_NS + IVAS_DEC_DELAY_NS ) ) ); +#endif *hAgcEnc = hAgc; return IVAS_ERR_OK; } + /*------------------------------------------------------------------------- * ivas_spar_agc_enc_close() * @@ -203,6 +238,7 @@ void ivas_spar_agc_enc_close( return; } + /*-----------------------------------------------------------------------------------------* * Function ivas_agc_enc_process() * diff --git a/lib_enc/ivas_core_enc.c b/lib_enc/ivas_core_enc.c index 597f1d5854..b863944b57 100644 --- a/lib_enc/ivas_core_enc.c +++ b/lib_enc/ivas_core_enc.c @@ -79,10 +79,8 @@ ivas_error ivas_core_enc( float enerBuffer[CPE_CHANNELS][CLDFB_NO_CHANNELS_MAX], /* i : energy buffer */ float fft_buff[CPE_CHANNELS][2 * L_FFT], /* i : FFT buffer */ const int16_t tdm_SM_or_LRTD_Pri, /* i : channel combination scheme flag in TD stereo OR LRTD primary channel */ -#ifdef CORECODER_BITRATE_SWITCHING - const int16_t ivas_format, /* i : IVAS format */ -#endif - const int16_t flag_16k_smc /* i : flag to indicate if the OL SMC is run at 16 kHz */ + const int16_t ivas_format, /* i : IVAS format */ + const int16_t flag_16k_smc /* i : flag to indicate if the OL SMC is run at 16 kHz */ ) { int16_t n, input_frame; @@ -104,11 +102,7 @@ ivas_error ivas_core_enc( int16_t unbits[CPE_CHANNELS]; float tdm_lspQ_PCh[M], tdm_lsfQ_PCh[M]; int16_t last_element_mode, tdm_Pitch_reuse_flag; -#ifdef CORECODER_BITRATE_SWITCHING int32_t element_brate, last_element_brate, input_Fs; -#else - int32_t element_brate, input_Fs; -#endif ivas_error error; wmops_sub_start( "ivas_core_enc" ); @@ -127,9 +121,7 @@ ivas_error ivas_core_enc( hStereoTD = NULL; hStereoICBWE = NULL; element_brate = hSCE->element_brate; -#ifdef CORECODER_BITRATE_SWITCHING last_element_brate = hSCE->last_element_brate; -#endif last_element_mode = IVAS_SCE; tdm_Pitch_reuse_flag = -1; } @@ -144,9 +136,7 @@ ivas_error ivas_core_enc( sts = hCPE->hCoreCoder; hStereoICBWE = hCPE->hStereoICBWE; element_brate = hCPE->element_brate; -#ifdef CORECODER_BITRATE_SWITCHING last_element_brate = hCPE->last_element_brate; -#endif last_element_mode = hCPE->last_element_mode; if ( hCPE->hStereoTD != NULL ) @@ -187,11 +177,7 @@ ivas_error ivas_core_enc( * Pre-processing, incl. Decision matrix *---------------------------------------------------------------------*/ -#ifdef CORECODER_BITRATE_SWITCHING if ( ( error = pre_proc_ivas( st, last_element_mode, element_brate, ivas_format == SBA_FORMAT ? last_element_brate : element_brate, input_frame, old_inp_12k8[n], old_inp_16k[n], &inp[n], &ener[n], A[n], Aw[n], epsP[n], lsp_new[n], lsp_mid[n], new_inp_resamp16k[n], &Voicing_flag[n], old_wsp[n], loc_harm[n], cor_map_sum[n], vad_flag_dtx[n], enerBuffer[n], fft_buff[n], MCT_flag, vad_hover_flag[n], flag_16k_smc ) ) != IVAS_ERR_OK ) -#else - if ( ( error = pre_proc_ivas( st, last_element_mode, element_brate, input_frame, old_inp_12k8[n], old_inp_16k[n], &inp[n], &ener[n], A[n], Aw[n], epsP[n], lsp_new[n], lsp_mid[n], new_inp_resamp16k[n], &Voicing_flag[n], old_wsp[n], loc_harm[n], cor_map_sum[n], vad_flag_dtx[n], enerBuffer[n], fft_buff[n], MCT_flag, vad_hover_flag[n], flag_16k_smc ) ) != IVAS_ERR_OK ) -#endif { return error; } diff --git a/lib_enc/ivas_core_pre_proc.c b/lib_enc/ivas_core_pre_proc.c index 3cc206e65e..acbacc09e0 100644 --- a/lib_enc/ivas_core_pre_proc.c +++ b/lib_enc/ivas_core_pre_proc.c @@ -52,12 +52,10 @@ *--------------------------------------------------------------------*/ ivas_error pre_proc_ivas( - Encoder_State *st, /* i/o: encoder state structure */ - const int16_t last_element_mode, /* i : last element mode */ - const int32_t element_brate, /* i : element bitrate */ -#ifdef CORECODER_BITRATE_SWITCHING - const int32_t last_element_brate, /* i : last element bitrate */ -#endif + Encoder_State *st, /* i/o: encoder state structure */ + const int16_t last_element_mode, /* i : last element mode */ + const int32_t element_brate, /* i : element bitrate */ + const int32_t last_element_brate, /* i : last element bitrate */ const int16_t input_frame, /* i : frame length */ float old_inp_12k8[], /* i/o: buffer of old input signal */ float old_inp_16k[], /* i/o: buffer of old input signal @ 16kHz */ @@ -278,12 +276,10 @@ ivas_error pre_proc_ivas( { st->hTcxEnc->tfm_mem = 0.75f; } -#ifdef CORECODER_BITRATE_SWITCHING else if ( element_brate != last_element_brate ) { SetModeIndex( st, st->bits_frame_nominal * FRAMES_PER_SEC, element_mode, MCT_flag ); } -#endif /*-----------------------------------------------------------------* diff --git a/lib_enc/ivas_core_pre_proc_front.c b/lib_enc/ivas_core_pre_proc_front.c index 51a549505f..b4336bdf62 100644 --- a/lib_enc/ivas_core_pre_proc_front.c +++ b/lib_enc/ivas_core_pre_proc_front.c @@ -553,7 +553,7 @@ ivas_error pre_proc_front_ivas( * Adjust FD-CNG Noise Estimator *----------------------------------------------------------------*/ - if ( st->hFdCngEnc != NULL && ( last_element_brate != element_brate || st->last_bwidth != st->bwidth ) ) + if ( st->hFdCngEnc != NULL && ( st->ini_frame == 0 || last_element_brate != element_brate || st->last_bwidth != st->bwidth ) ) { configureFdCngEnc( st->hFdCngEnc, max( st->input_bwidth, WB ), st->bits_frame_nominal * FRAMES_PER_SEC ); if ( hCPE != NULL ) diff --git a/lib_enc/ivas_corecoder_enc_reconfig.c b/lib_enc/ivas_corecoder_enc_reconfig.c index f4b302eefd..dffd53bb93 100644 --- a/lib_enc/ivas_corecoder_enc_reconfig.c +++ b/lib_enc/ivas_corecoder_enc_reconfig.c @@ -43,7 +43,6 @@ #include "wmops.h" -#ifdef CORECODER_BITRATE_SWITCHING /*-------------------------------------------------------------------* * ivas_corecoder_enc_reconfig() * @@ -393,4 +392,3 @@ ivas_error ivas_corecoder_enc_reconfig( return error; } -#endif diff --git a/lib_enc/ivas_cpe_enc.c b/lib_enc/ivas_cpe_enc.c index 491a9ab358..e047defac6 100644 --- a/lib_enc/ivas_cpe_enc.c +++ b/lib_enc/ivas_cpe_enc.c @@ -612,11 +612,7 @@ ivas_error ivas_cpe_enc( * Core Encoder *----------------------------------------------------------------*/ -#ifdef CORECODER_BITRATE_SWITCHING if ( ( error = ivas_core_enc( NULL, hCPE, st_ivas->hMCT, n_CoreChannels, old_inp_12k8, old_inp_16k, Etot, ener, A, Aw, epsP, lsp_new, lsp_mid, vad_hover_flag, attack_flag, realBuffer, imagBuffer, old_wsp, loc_harm, cor_map_sum, vad_flag_dtx, enerBuffer, fft_buff, tdm_SM_or_LRTD_Pri, ivas_format, 0 ) ) != IVAS_ERR_OK ) -#else - if ( ( error = ivas_core_enc( NULL, hCPE, st_ivas->hMCT, n_CoreChannels, old_inp_12k8, old_inp_16k, Etot, ener, A, Aw, epsP, lsp_new, lsp_mid, vad_hover_flag, attack_flag, realBuffer, imagBuffer, old_wsp, loc_harm, cor_map_sum, vad_flag_dtx, enerBuffer, fft_buff, tdm_SM_or_LRTD_Pri, 0 ) ) != IVAS_ERR_OK ) -#endif { return error; } diff --git a/lib_enc/ivas_dirac_enc.c b/lib_enc/ivas_dirac_enc.c index 6d281256d9..96a005a0b3 100644 --- a/lib_enc/ivas_dirac_enc.c +++ b/lib_enc/ivas_dirac_enc.c @@ -334,12 +334,8 @@ void ivas_dirac_enc( set_zero( data_f[2], input_frame ); } - ivas_dirac_param_est_enc( hDirAC, &( hQMetaData->q_direction[0] ), hQMetaData->useLowerRes, data_f, NULL, NULL, input_frame -#ifdef SBA_HOA_HBR_IMPROV - , - SBA_MODE_DIRAC -#endif - ); + ivas_dirac_param_est_enc( hDirAC, &( hQMetaData->q_direction[0] ), hQMetaData->useLowerRes, data_f, NULL, NULL, input_frame, + SBA_MODE_DIRAC ); /* encode parameters */ if ( sba_planar || hQMetaData->useLowerRes ) { @@ -457,7 +453,6 @@ void ivas_dirac_enc_spar_delay_synchro( { int16_t ch_idx; float tmp_buffer[L_FRAME48k]; -#ifdef CORECODER_BITRATE_SWITCHING Encoder_State *sts[MCT_MAX_BLOCKS]; int16_t sce_id, cpe_id, i_chan; @@ -487,7 +482,6 @@ void ivas_dirac_enc_spar_delay_synchro( mvr2r( sts[ch_idx]->input, st_ivas->hDirAC->sba_synchro_buffer[ch_idx], st_ivas->hDirAC->num_samples_synchro_delay ); } } -#endif for ( ch_idx = 0; ch_idx < DIRAC_MAX_ANA_CHANS; ch_idx++ ) { @@ -514,18 +508,14 @@ void computeReferencePower_enc( float *reference_power, /* o : Estimated power */ const int16_t enc_param_start_band, /* i : first band to process */ const int16_t num_freq_bands /* i : Number of frequency bands */ -#ifdef SBA_HOA_HBR_IMPROV , const SBA_MODE sba_mode /* i : SBA mode */ -#endif ) { int16_t brange[2]; int16_t ch_idx, i, j; -#ifdef SBA_HOA_HBR_IMPROV float reference_power_W[DIRAC_MAX_NBANDS]; -#endif for ( i = 0; i < num_freq_bands; i++ ) { @@ -533,19 +523,13 @@ void computeReferencePower_enc( brange[1] = band_grouping[i + enc_param_start_band + 1]; reference_power[i] = 0; -#ifdef SBA_HOA_HBR_IMPROV reference_power_W[i] = 0; for ( j = brange[0]; j < brange[1]; j++ ) { reference_power_W[i] += ( Cldfb_RealBuffer[0][j] * Cldfb_RealBuffer[0][j] ) + ( Cldfb_ImagBuffer[0][j] * Cldfb_ImagBuffer[0][j] ); } reference_power[i] += reference_power_W[i]; -#endif -#ifdef SBA_HOA_HBR_IMPROV for ( ch_idx = 1; ch_idx < DIRAC_MAX_ANA_CHANS; ch_idx++ ) -#else - for ( ch_idx = 0; ch_idx < DIRAC_MAX_ANA_CHANS; ch_idx++ ) -#endif { /* abs()^2 */ for ( j = brange[0]; j < brange[1]; j++ ) @@ -556,7 +540,6 @@ void computeReferencePower_enc( } v_multc( reference_power, 0.5f, reference_power, num_freq_bands ); -#ifdef SBA_HOA_HBR_IMPROV if ( sba_mode == SBA_MODE_SPAR ) { for ( i = 0; i < num_freq_bands; i++ ) @@ -564,7 +547,6 @@ void computeReferencePower_enc( reference_power[i] = max( reference_power[i], reference_power_W[i] ); } } -#endif return; } @@ -583,12 +565,8 @@ void ivas_dirac_param_est_enc( float data_f[][L_FRAME48k], float **pp_fr_real, float **pp_fr_imag, - const int16_t input_frame -#ifdef SBA_HOA_HBR_IMPROV - , - const SBA_MODE sba_mode -#endif -) + const int16_t input_frame, + const SBA_MODE sba_mode ) { int16_t i, d, ts, index, l_ts, num_freq_bands; int16_t band_m_idx, block_m_idx; @@ -686,12 +664,8 @@ void ivas_dirac_param_est_enc( Cldfb_ImagBuffer, reference_power[ts], hDirAC->hConfig->enc_param_start_band, - num_freq_bands -#ifdef SBA_HOA_HBR_IMPROV - , - sba_mode -#endif - ); + num_freq_bands, + sba_mode ); computeIntensityVector_enc( hDirAC, diff --git a/lib_enc/ivas_enc.c b/lib_enc/ivas_enc.c index 75ffc5212d..7be1f11c49 100644 --- a/lib_enc/ivas_enc.c +++ b/lib_enc/ivas_enc.c @@ -65,7 +65,9 @@ ivas_error ivas_enc( float data_f[MAX_INPUT_CHANNELS][L_FRAME48k]; /* IVAS_fmToDo: buffer can be allocated dynamically based on the number of analysed channels */ int32_t ivas_total_brate; ivas_error error; - +#ifdef SBA_BR_SWITCHING + int16_t sba_reinit_flag; +#endif error = IVAS_ERR_OK; wmops_sub_start( "ivas_enc" ); @@ -85,6 +87,20 @@ ivas_error ivas_enc( n_samples_chan = n_samples / nchan_inp; set_s( nb_bits_metadata, 0, MAX_SCE ); +#ifdef SBA_BR_SWITCHING + sba_reinit_flag = 0; + if ( ivas_format == SBA_FORMAT ) + { + sba_reinit_flag = get_sba_reinit_flag( ivas_total_brate, st_ivas->hEncoderConfig->last_ivas_total_brate ); + if ( sba_reinit_flag ) + { + if ( ( error = ivas_sba_enc_reinit( st_ivas ) ) != IVAS_ERR_OK ) + { + return error; + } + } + } +#endif /*----------------------------------------------------------------* * convert 'short' input data to 'float' @@ -189,7 +205,11 @@ ivas_error ivas_enc( /* SBA/MASA configuration */ if ( ivas_format == SBA_FORMAT ) { +#ifndef SBA_BR_SWITCHING if ( st_ivas->sba_mode == SBA_MODE_DIRAC ) +#else + if ( ( st_ivas->sba_mode == SBA_MODE_DIRAC ) && ( !sba_reinit_flag ) ) +#endif { if ( ( error = ivas_sba_enc_reconfigure( st_ivas ) ) != IVAS_ERR_OK ) { diff --git a/lib_enc/ivas_enc_cov_handler.c b/lib_enc/ivas_enc_cov_handler.c index 907b8c5908..933c2c5de9 100644 --- a/lib_enc/ivas_enc_cov_handler.c +++ b/lib_enc/ivas_enc_cov_handler.c @@ -141,44 +141,23 @@ void ivas_spar_covar_enc_close( void ivas_enc_cov_handler_process( ivas_enc_cov_handler_state_t *hCovEnc, /* i/o: SPAR Covar. encoder handle */ -#ifdef SBA_SPAR_HARM float **ppIn_FR_real, float **ppIn_FR_imag, float *cov_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], float *cov_dtx_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], -#else - ivas_enc_cov_handler_in_buf_t *pIn_buf, - float *cov_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], - float *cov_dtx_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], -#endif ivas_filterbank_t *pFb, /* i/o: FB handle */ const int16_t start_band, - const int16_t end_band -#ifdef SBA_SPAR_HARM - , + const int16_t end_band, const int16_t num_ch, const int16_t dtx_vad, - const int16_t transient_det -#endif -) + const int16_t transient_det ) { int16_t i, j; -#ifdef SBA_SPAR_HARM int16_t dtx_cov_flag; dtx_cov_flag = ( dtx_vad == 1 ) ? 0 : 1; -#else - ivas_cov_smooth_in_buf_t pCov_in_buf; - int16_t num_ch = pIn_buf->num_ch; - - pCov_in_buf.num_ch = num_ch; -#endif -#ifdef SBA_SPAR_HARM ivas_band_cov( ppIn_FR_real, ppIn_FR_imag, num_ch, hCovEnc->num_bins, -#else - ivas_band_cov( pIn_buf->ppIn_FR_real, pIn_buf->ppIn_FR_imag, pIn_buf->num_ch, hCovEnc->num_bins, -#endif pFb->fb_bin_to_band.short_stride, pFb->fb_bin_to_band.pp_short_stride_bin_to_band, pFb->fb_bin_to_band.p_short_stride_start_bin_per_band, @@ -213,36 +192,20 @@ void ivas_enc_cov_handler_process( { for ( j = 0; j < num_ch; j++ ) { -#ifndef SBA_SPAR_HARM - pCov_in_buf.cov_real[i][j] = cov_real[i][j]; -#endif mvr2r( cov_real[i][j], cov_dtx_real[i][j], pFb->filterbank_num_bands ); } } -#ifdef SBA_SPAR_HARM ivas_cov_smooth_process( hCovEnc->pCov_state, cov_real, pFb, start_band, end_band, num_ch, transient_det ); -#else - ivas_cov_smooth_process( hCovEnc->pCov_state, &pCov_in_buf, pFb, start_band, end_band ); -#endif -#ifdef SBA_SPAR_HARM if ( dtx_cov_flag == 0 ) -#else - if ( pIn_buf->dtx_cov_flag == 0 ) -#endif { for ( i = 0; i < num_ch; i++ ) { for ( j = 0; j < num_ch; j++ ) { -#ifdef SBA_SPAR_HARM mvr2r( cov_real[i][j], hCovEnc->pCov_dtx_state->pPrior_cov_real[i][j], pFb->filterbank_num_bands ); mvr2r( cov_real[i][j], cov_dtx_real[i][j], pFb->filterbank_num_bands ); -#else - mvr2r( pCov_in_buf.cov_real[i][j], hCovEnc->pCov_dtx_state->pPrior_cov_real[i][j], pFb->filterbank_num_bands ); - mvr2r( pCov_in_buf.cov_real[i][j], cov_dtx_real[i][j], pFb->filterbank_num_bands ); -#endif } } @@ -250,46 +213,16 @@ void ivas_enc_cov_handler_process( } else { -#ifdef SBA_SPAR_HARM if ( transient_det == 0 ) -#else - if ( pIn_buf->transient_det == 0 ) -#endif { -#ifdef SBA_SPAR_HARM ivas_cov_smooth_process( hCovEnc->pCov_dtx_state, cov_dtx_real, pFb, start_band, end_band, num_ch, transient_det ); -#else - for ( i = 0; i < num_ch; i++ ) - { - for ( j = 0; j < num_ch; j++ ) - { - pCov_in_buf.cov_real[i][j] = cov_dtx_real[i][j]; - } - } - - pCov_in_buf.reset_cov = 0; - ivas_cov_smooth_process( hCovEnc->pCov_dtx_state, &pCov_in_buf, pFb, start_band, end_band ); -#endif hCovEnc->prior_dtx_present = 1; } else { if ( hCovEnc->prior_dtx_present == 0 ) { -#ifdef SBA_SPAR_HARM ivas_cov_smooth_process( hCovEnc->pCov_dtx_state, cov_dtx_real, pFb, start_band, end_band, num_ch, transient_det ); -#else - for ( i = 0; i < num_ch; i++ ) - { - for ( j = 0; j < num_ch; j++ ) - { - pCov_in_buf.cov_real[i][j] = cov_dtx_real[i][j]; - } - } - - pCov_in_buf.reset_cov = 1; - ivas_cov_smooth_process( hCovEnc->pCov_dtx_state, &pCov_in_buf, pFb, start_band, end_band ); -#endif hCovEnc->prior_dtx_present = 1; } else diff --git a/lib_enc/ivas_entropy_coder.c b/lib_enc/ivas_entropy_coder.c index 7f5ab7b996..a3714821f3 100644 --- a/lib_enc/ivas_entropy_coder.c +++ b/lib_enc/ivas_entropy_coder.c @@ -316,17 +316,13 @@ void ivas_arith_encode_cmplx_cell_array( int16_t input[IVAS_MAX_INPUT_LEN]; ivas_cell_dim_t cell_dim[IVAS_MAX_NUM_BANDS], cell_dim_diff[IVAS_MAX_NUM_BANDS]; int16_t len, idx, i, j, idx1; -#ifdef SBA_HOA_HBR_IMPROV int16_t total_len; -#endif idx1 = 0; if ( any_diff == 1 ) { idx = 0; -#ifdef SBA_HOA_HBR_IMPROV total_len = 0; -#endif for ( i = 0; i < nB; i++ ) { len = ( pCell_dims[i].dim1 * pCell_dims[i].dim2 ); @@ -334,13 +330,8 @@ void ivas_arith_encode_cmplx_cell_array( { for ( j = 0; j < len; j++ ) { -#ifdef SBA_HOA_HBR_IMPROV input_old[idx] = pSymbol_old_re[total_len + j]; input_new[idx++] = pSymbol_re[total_len + j]; -#else - input_old[idx] = pSymbol_old_re[i * len + j]; - input_new[idx++] = pSymbol_re[i * len + j]; -#endif } cell_dim_diff[i].dim1 = pCell_dims[i].dim1; cell_dim_diff[i].dim2 = pCell_dims[i].dim2; @@ -351,20 +342,14 @@ void ivas_arith_encode_cmplx_cell_array( { for ( j = 0; j < len; j++ ) { -#ifdef SBA_HOA_HBR_IMPROV input[idx1++] = pSymbol_re[total_len + j]; -#else - input[idx1++] = pSymbol_re[i * len + j]; -#endif } cell_dim_diff[i].dim1 = 0; cell_dim_diff[i].dim2 = 0; cell_dim[i].dim1 = pCell_dims[i].dim1; cell_dim[i].dim2 = pCell_dims[i].dim2; } -#ifdef SBA_HOA_HBR_IMPROV total_len += len; -#endif } #ifdef SPAR_HOA_DBG /*if ( 0 )*/ /*(pCell_dims[0].dim1 == 12)*/ diff --git a/lib_enc/ivas_front_vad.c b/lib_enc/ivas_front_vad.c index 1d18af7761..62eeee5a02 100644 --- a/lib_enc/ivas_front_vad.c +++ b/lib_enc/ivas_front_vad.c @@ -396,7 +396,11 @@ ivas_error front_vad_spar( hFrontVad = hSpar->hFrontVad; st = hSpar->hCoreCoderVAD; +#ifdef FIX_SBA_DTX_DECODE_ERROR + if ( hEncoderConfig->Opt_DTX_ON && hEncoderConfig->ivas_total_brate <= SBA_DTX_BITRATE_THRESHOLD ) +#else if ( hEncoderConfig->Opt_DTX_ON && hEncoderConfig->ivas_total_brate <= IVAS_80k ) +#endif { /*------------------------------------------------------------------* * Initialization diff --git a/lib_enc/ivas_init_enc.c b/lib_enc/ivas_init_enc.c index 8d79594c7e..18280a60e2 100644 --- a/lib_enc/ivas_init_enc.c +++ b/lib_enc/ivas_init_enc.c @@ -190,12 +190,10 @@ int16_t getNumChanAnalysis( { n = st_ivas->hEncoderConfig->nchan_inp; } -#ifdef FIX_155_HP20_ISSUE else if ( st_ivas->hEncoderConfig->ivas_format == ISM_FORMAT && st_ivas->ism_mode == ISM_MODE_PARAM ) { n = st_ivas->hEncoderConfig->nchan_inp; } -#endif return n; } diff --git a/lib_enc/ivas_ism_enc.c b/lib_enc/ivas_ism_enc.c index 2122dcf874..3c8a1f04b3 100644 --- a/lib_enc/ivas_ism_enc.c +++ b/lib_enc/ivas_ism_enc.c @@ -262,11 +262,7 @@ ivas_error ivas_ism_enc( * Encoder *----------------------------------------------------------------*/ -#ifdef CORECODER_BITRATE_SWITCHING if ( ( error = ivas_core_enc( hSCE, NULL, NULL, 1, old_inp_12k8[sce_id], old_inp_16k[sce_id], Etot[sce_id], ener[sce_id], A[sce_id], Aw[sce_id], epsP[sce_id], lsp_new[sce_id], lsp_mid[sce_id], vad_hover_flag[sce_id], attack_flag[sce_id], realBuffer[sce_id], imagBuffer[sce_id], old_wsp[sce_id], loc_harm[sce_id], cor_map_sum[sce_id], vad_flag_dtx[sce_id], enerBuffer[sce_id], fft_buff[sce_id], 0, ISM_FORMAT, 0 ) ) != IVAS_ERR_OK ) -#else - if ( ( error = ivas_core_enc( hSCE, NULL, NULL, 1, old_inp_12k8[sce_id], old_inp_16k[sce_id], Etot[sce_id], ener[sce_id], A[sce_id], Aw[sce_id], epsP[sce_id], lsp_new[sce_id], lsp_mid[sce_id], vad_hover_flag[sce_id], attack_flag[sce_id], realBuffer[sce_id], imagBuffer[sce_id], old_wsp[sce_id], loc_harm[sce_id], cor_map_sum[sce_id], vad_flag_dtx[sce_id], enerBuffer[sce_id], fft_buff[sce_id], 0, 0 ) ) != IVAS_ERR_OK ) -#endif { return error; } diff --git a/lib_enc/ivas_ism_param_enc.c b/lib_enc/ivas_ism_param_enc.c index 3358e41e21..8dcdef30b5 100644 --- a/lib_enc/ivas_ism_param_enc.c +++ b/lib_enc/ivas_ism_param_enc.c @@ -41,11 +41,6 @@ #include "ivas_rom_com.h" #include "wmops.h" -#ifndef FIX_155_HP20_ISSUE -#ifdef CORECODER_BITRATE_SWITCHING -static ivas_error ivas_hp20_reconfig( Encoder_Struct *st_ivas, const int16_t nchan_hp20_old ); -#endif -#endif /*------------------------------------------------------------------------- * Local function definitions *------------------------------------------------------------------------*/ @@ -419,14 +414,7 @@ ivas_error ivas_ism_enc_config( { ivas_error error; ISM_MODE last_ism_mode; -#ifdef ISM_BITRATE_SWITCHING -#ifdef CORECODER_BITRATE_SWITCHING int16_t nchan_transport_old; -#else - int16_t nSCE_old, nchan_transport_old; - int16_t sce_id, n; -#endif -#endif error = IVAS_ERR_OK; last_ism_mode = st_ivas->ism_mode; @@ -434,18 +422,11 @@ ivas_error ivas_ism_enc_config( /* select ISM format mode */ st_ivas->ism_mode = ivas_ism_mode_select( st_ivas->hEncoderConfig->nchan_inp, st_ivas->hEncoderConfig->ivas_total_brate ); -#ifdef ISM_BITRATE_SWITCHING /* ISM bit-rate switching */ if ( ( st_ivas->ism_mode != last_ism_mode ) || ( st_ivas->hEncoderConfig->ivas_total_brate != st_ivas->hEncoderConfig->last_ivas_total_brate ) ) { int32_t element_brate_tmp[MAX_NUM_OBJECTS]; -#ifndef CORECODER_BITRATE_SWITCHING - Indice *ind_list_sce, *ind_list_metadata; -#endif -#ifndef CORECODER_BITRATE_SWITCHING - nSCE_old = st_ivas->nSCE; -#endif nchan_transport_old = st_ivas->nchan_transport; /* Reset and Initialize */ @@ -463,60 +444,7 @@ ivas_error ivas_ism_enc_config( ivas_ism_config( st_ivas->hEncoderConfig->ivas_total_brate, st_ivas->nchan_transport, st_ivas->hEncoderConfig->nchan_inp, NULL, NULL, NULL, element_brate_tmp, NULL, NULL ); -#ifdef CORECODER_BITRATE_SWITCHING ivas_corecoder_enc_reconfig( st_ivas, nchan_transport_old, 0, nchan_transport_old ); -#else - if ( st_ivas->nSCE > nSCE_old ) - { - /* Reconfigure the core coders */ - for ( sce_id = 0; sce_id < nSCE_old; sce_id++ ) - { - copy_encoder_config( st_ivas, st_ivas->hSCE[sce_id]->hCoreCoder[0], 0 ); - st_ivas->hSCE[sce_id]->element_brate = st_ivas->hEncoderConfig->ivas_total_brate / st_ivas->nchan_transport; - st_ivas->hSCE[sce_id]->hCoreCoder[0]->total_brate = st_ivas->hSCE[sce_id]->element_brate; /* dummy initialization for getting right pointers initialization of input buffers in init_coder_ace_plus() */ - } - - /* Initialize the extra required memory */ - ind_list_sce = st_ivas->hSCE[0]->hCoreCoder[0]->hBstr->ind_list; - ind_list_metadata = st_ivas->hSCE[0]->hMetaData->ind_list; - - for ( sce_id = nSCE_old; sce_id < st_ivas->nSCE; sce_id++ ) - { - /* Initialize the Core Coder */ - if ( ( error = create_sce_enc( st_ivas, sce_id, element_brate_tmp[sce_id] ) ) != IVAS_ERR_OK ) - { - return error; - } - - /* prepare bitstream buffers */ - st_ivas->hSCE[sce_id]->hCoreCoder[0]->hBstr->ind_list = ind_list_sce + ( sce_id * MAX_NUM_INDICES ); - reset_indices_enc( st_ivas->hSCE[sce_id]->hCoreCoder[0]->hBstr, MAX_NUM_INDICES ); - - st_ivas->hSCE[sce_id]->hMetaData->ind_list = ind_list_metadata + ( sce_id * MAX_BITS_METADATA ); - reset_indices_enc( st_ivas->hSCE[sce_id]->hMetaData, MAX_BITS_METADATA ); - } - } - else - { - /* Reconfigure the Core Coders */ - for ( sce_id = 0; sce_id < st_ivas->nSCE; sce_id++ ) - { - copy_encoder_config( st_ivas, st_ivas->hSCE[sce_id]->hCoreCoder[0], 0 ); - st_ivas->hSCE[sce_id]->element_brate = st_ivas->hEncoderConfig->ivas_total_brate / st_ivas->nchan_transport; - st_ivas->hSCE[sce_id]->hCoreCoder[0]->total_brate = st_ivas->hSCE[sce_id]->element_brate; /* dummy initialization for getting right pointers initialization of input buffers in init_coder_ace_plus() */ - } - - /* Delete the extra memory */ - for ( sce_id = st_ivas->nSCE; sce_id < nSCE_old; sce_id++ ) - { - if ( st_ivas->hSCE[sce_id] != NULL ) - { - destroy_sce_enc( st_ivas->hSCE[sce_id] ); - st_ivas->hSCE[sce_id] = NULL; - } - } - } -#endif if ( st_ivas->ism_mode == ISM_MODE_PARAM && last_ism_mode == ISM_MODE_DISC ) { @@ -533,147 +461,7 @@ ivas_error ivas_ism_enc_config( ivas_param_ism_enc_close( st_ivas->hDirAC, st_ivas->hEncoderConfig->input_Fs ); st_ivas->hDirAC = NULL; } - -#ifndef FIX_155_HP20_ISSUE -#ifdef CORECODER_BITRATE_SWITCHING - ivas_hp20_reconfig( st_ivas, nchan_transport_old ); -#else - /* destroy the memory of hp20*/ - if ( st_ivas->mem_hp20_in != NULL ) - { - for ( sce_id = 0; sce_id < nSCE_old; sce_id++ ) - { - count_free( st_ivas->mem_hp20_in[sce_id] ); - st_ivas->mem_hp20_in[sce_id] = NULL; - } - count_free( st_ivas->mem_hp20_in ); - st_ivas->mem_hp20_in = NULL; - } - - /* re initialize the memory of hp20 */ - /* set number of input channels used for analysis/coding */ - n = getNumChanAnalysis( st_ivas ); - - if ( n > 0 ) - { - if ( ( st_ivas->mem_hp20_in = (float **) count_malloc( n * sizeof( float * ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for HP20 filter memory\n" ) ); - } - } - else - { - st_ivas->mem_hp20_in = NULL; - } - - for ( sce_id = 0; sce_id < n; sce_id++ ) - { - if ( ( st_ivas->mem_hp20_in[sce_id] = (float *) count_malloc( L_HP20_MEM * sizeof( float ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for HP20 filter memory\n" ) ); - } - - set_f( st_ivas->mem_hp20_in[sce_id], 0.0f, L_HP20_MEM ); - } -#endif -#endif } -#else - /* ISM format switching */ - if ( st_ivas->ism_mode != last_ism_mode ) - { - /*ivas_ism_dec_reconfigure( st_ivas );*/ - return IVAS_ERROR( IVAS_ERR_RECONFIGURE_NOT_SUPPORTED, "Error: ISM format switching not supported yet!!!\n\n" ); - } -#endif return error; } - -#ifndef FIX_155_HP20_ISSUE -#ifdef CORECODER_BITRATE_SWITCHING -// VE: this is the same function as at the decoder -> harmonize them to a new file ivas_corecoder_reconfig.c -/*-------------------------------------------------------------------* - * ivas_hp20_dec_reconfig() - * - * Allocate, initialize, and configure HP20 memory handles in case of bitrate switching - *-------------------------------------------------------------------*/ - -static ivas_error ivas_hp20_reconfig( - Encoder_Struct *st_ivas, /* i/o: IVAS encoder structure */ - const int16_t nchan_hp20_old /* i : number of HP20 filters in previous frame */ -) -{ - int16_t i, nchan_hp20; - float **old_mem_hp20_out; - ivas_error error; - - error = IVAS_ERR_OK; - - /*-----------------------------------------------------------------* - * HP20 memories - *-----------------------------------------------------------------*/ - - nchan_hp20 = getNumChanAnalysis( st_ivas ); - - if ( nchan_hp20 > nchan_hp20_old ) - { - /* save old mem_hp_20 pointer */ - old_mem_hp20_out = st_ivas->mem_hp20_in; - st_ivas->mem_hp20_in = NULL; - - if ( ( st_ivas->mem_hp20_in = (float **) count_malloc( nchan_hp20 * sizeof( float * ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for HP20 filter memory\n" ) ); - } - - for ( i = 0; i < nchan_hp20_old; i++ ) - { - st_ivas->mem_hp20_in[i] = old_mem_hp20_out[i]; - old_mem_hp20_out[i] = NULL; - } - /* create additional hp20 memories */ - for ( ; i < nchan_hp20; i++ ) - { - if ( ( st_ivas->mem_hp20_in[i] = (float *) count_malloc( L_HP20_MEM * sizeof( float ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for HP20 filter memory\n" ) ); - } - - set_f( st_ivas->mem_hp20_in[i], 0.0f, L_HP20_MEM ); - } - - count_free( old_mem_hp20_out ); - old_mem_hp20_out = NULL; - } - else if ( nchan_hp20 < nchan_hp20_old ) - { - /* save old mem_hp_20 pointer */ - old_mem_hp20_out = st_ivas->mem_hp20_in; - st_ivas->mem_hp20_in = NULL; - - if ( ( st_ivas->mem_hp20_in = (float **) count_malloc( nchan_hp20 * sizeof( float * ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for HP20 filter memory\n" ) ); - } - - for ( i = 0; i < nchan_hp20; i++ ) - { - st_ivas->mem_hp20_in[i] = old_mem_hp20_out[i]; - old_mem_hp20_out[i] = NULL; - } - /* remove superfluous hp20 memories */ - for ( ; i < nchan_hp20_old; i++ ) - { - count_free( old_mem_hp20_out[i] ); - old_mem_hp20_out[i] = NULL; - } - - count_free( old_mem_hp20_out ); - old_mem_hp20_out = NULL; - } - - return error; -} -#endif -#endif diff --git a/lib_enc/ivas_mcmasa_enc.c b/lib_enc/ivas_mcmasa_enc.c index 1329e572ae..de816f3bf7 100644 --- a/lib_enc/ivas_mcmasa_enc.c +++ b/lib_enc/ivas_mcmasa_enc.c @@ -892,12 +892,8 @@ void ivas_mcmasa_param_est_enc( intensity_even_real ); computeReferencePower_enc( hMcMasa->band_grouping, FoaEven_RealBuffer, FoaEven_ImagBuffer, reference_power[ts], 0, - num_freq_bands -#ifdef SBA_HOA_HBR_IMPROV - , - SBA_MODE_NONE -#endif - ); + num_freq_bands, + SBA_MODE_NONE ); /* Fill buffers of length "averaging_length" time slots for intensity and energy */ hMcMasa->index_buffer_intensity = ( hMcMasa->index_buffer_intensity % hMcMasa->no_col_avg_diff ) + 1; /* averaging_length = 32 */ diff --git a/lib_enc/ivas_mct_core_enc.c b/lib_enc/ivas_mct_core_enc.c index f682a380f7..30e7022698 100644 --- a/lib_enc/ivas_mct_core_enc.c +++ b/lib_enc/ivas_mct_core_enc.c @@ -178,7 +178,6 @@ static void AdjustChannelRatios( } chBitRatios[1] += ratio_diff; -#ifdef SBA_HOA_HBR_IMPROV /* make sure final ratios are within range*/ sum_ratio = 0.0f; for ( i = 0; i < nChannels; i++ ) @@ -190,7 +189,6 @@ static void AdjustChannelRatios( cur_ratio = chBitRatios[i] / sum_ratio; chBitRatios[i] = min( BITRATE_MCT_RATIO_RANGE - 1, max( 1, (uint16_t) ( BITRATE_MCT_RATIO_RANGE * cur_ratio + 0.5f ) ) ); } -#endif return; } diff --git a/lib_enc/ivas_sba_enc.c b/lib_enc/ivas_sba_enc.c index d4c7c70b21..aca565b64d 100644 --- a/lib_enc/ivas_sba_enc.c +++ b/lib_enc/ivas_sba_enc.c @@ -93,329 +93,260 @@ void ivas_sba_getTCs( return; } - +#ifdef SBA_BR_SWITCHING /*-------------------------------------------------------------------* - * ivas_sba_enc_reconfigure() + * ivas_sba_enc_reinit() * - * Reconfigure IVAS SBA encoder + * Reinitialise IVAS SBA encoder *-------------------------------------------------------------------*/ -ivas_error ivas_sba_enc_reconfigure( +ivas_error ivas_sba_enc_reinit( Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ ) { - int16_t nSCE_old, nCPE_old, nchan_transport_old; -#ifndef CORECODER_BITRATE_SWITCHING - int16_t n, sce_id, cpe_id; + int16_t nSCE_old; + int16_t nCPE_old; + int16_t sce_id; + int16_t cpe_id; + int16_t n; Indice *ind_list_metadata; -#endif int32_t ivas_total_brate; + int16_t i, nchan_inp; ivas_error error; + ENCODER_CONFIG_HANDLE hEncoderConfig; + Indice *ind_list; + BSTR_ENC_HANDLE hBstr; + BSTR_ENC_HANDLE hMetaData; + hEncoderConfig = st_ivas->hEncoderConfig; + ivas_total_brate = hEncoderConfig->ivas_total_brate; error = IVAS_ERR_OK; - + nchan_inp = st_ivas->hEncoderConfig->nchan_inp; ivas_total_brate = st_ivas->hEncoderConfig->ivas_total_brate; - if ( ivas_total_brate != st_ivas->hEncoderConfig->last_ivas_total_brate ) + nCPE_old = st_ivas->nCPE; + nSCE_old = st_ivas->nSCE; + ind_list_metadata = NULL; + + + ind_list = NULL; + hBstr = NULL; + hMetaData = NULL; + + /* get the index list pointers */ + if ( nSCE_old ) { - nchan_transport_old = st_ivas->nchan_transport; - nCPE_old = st_ivas->nCPE; - nSCE_old = st_ivas->nSCE; -#ifndef CORECODER_BITRATE_SWITCHING - ind_list_metadata = NULL; -#endif + hBstr = st_ivas->hSCE[0]->hCoreCoder[0]->hBstr; + hMetaData = st_ivas->hSCE[0]->hMetaData; + } + else if ( nCPE_old ) + { + hBstr = st_ivas->hCPE[0]->hCoreCoder[0]->hBstr; + hMetaData = st_ivas->hCPE[nCPE_old - 1]->hMetaData; + } - st_ivas->sba_analysis_order = ivas_sba_get_analysis_order( ivas_total_brate, st_ivas->hEncoderConfig->sba_order ); + /* save bitstream information */ + ind_list = hBstr->ind_list; + ind_list_metadata = hMetaData->ind_list; - ivas_dirac_enc_reconfigure( st_ivas ); + /*------------------------------------------------------------------------------------------* + * Closing Encoder handles before Reinitialisation + *------------------------------------------------------------------------------------------*/ + /* Q Metadata handle */ + ivas_qmetadata_close( &( st_ivas->hQMetaData ) ); + /* DirAC handle */ + if ( st_ivas->hDirAC != NULL ) + { + ivas_dirac_enc_close( st_ivas->hDirAC, st_ivas->hEncoderConfig->input_Fs ); -#ifdef CORECODER_BITRATE_SWITCHING - /*-----------------------------------------------------------------* - * Allocate, initalize, and configure SCE/CPE/MCT handles - *-----------------------------------------------------------------*/ + st_ivas->hDirAC = NULL; + } - ivas_corecoder_enc_reconfig( st_ivas, nSCE_old, nCPE_old, nchan_transport_old ); -#else + /* SPAR handle */ + if ( st_ivas->hSpar != NULL ) + { + ivas_spar_enc_close( st_ivas->hSpar, st_ivas->hEncoderConfig->input_Fs, nchan_inp ); + st_ivas->hSpar = NULL; + } + /* SCE handles */ + for ( i = 0; i < MAX_SCE; i++ ) + { + if ( st_ivas->hSCE[i] != NULL ) + { + destroy_sce_enc( st_ivas->hSCE[i] ); + st_ivas->hSCE[i] = NULL; + } + } - if ( hEncoderConfig->nchan_transport == nchan_transport_old ) + /* CPE handles */ + for ( i = 0; i < MAX_CPE; i++ ) + { + if ( st_ivas->hCPE[i] != NULL ) { - for ( sce_id = 0; sce_id < st_ivas->nSCE; sce_id++ ) - { - copy_encoder_config( st_ivas, st_ivas->hSCE[sce_id]->hCoreCoder[0], 0 ); - st_ivas->hSCE[sce_id]->element_brate = ivas_total_brate / st_ivas->nchan_transport; - st_ivas->hSCE[sce_id]->hCoreCoder[0]->total_brate = st_ivas->hSCE[sce_id]->element_brate; /* dummy initialization for getting right pointers initialization of input buffers in init_coder_ace_plus() */ - } + destroy_cpe_enc( st_ivas->hCPE[i] ); + st_ivas->hCPE[i] = NULL; + } + } + /* MCT handle */ + if ( st_ivas->hMCT != NULL ) + { + ivas_mct_enc_close( st_ivas->hMCT ); + st_ivas->hMCT = NULL; + } + if ( st_ivas->mem_hp20_in != NULL ) + { + n = getNumChanAnalysis( st_ivas ); - for ( cpe_id = 0; cpe_id < st_ivas->nCPE; cpe_id++ ) - { - st_ivas->hCPE[cpe_id]->element_brate = ( ivas_total_brate / st_ivas->nchan_transport ) * CPE_CHANNELS; - /* prepare bitstream buffers */ - for ( n = 0; n < CPE_CHANNELS; n++ ) - { - copy_encoder_config( st_ivas, st_ivas->hCPE[cpe_id]->hCoreCoder[n], 0 ); - - st_ivas->hCPE[cpe_id]->hCoreCoder[n]->total_brate = st_ivas->hCPE[cpe_id]->element_brate / ( st_ivas->nCPE > 1 ? 1 : CPE_CHANNELS ); /* dummy initialization for getting right pointers initialization of input buffers in init_coder_ace_plus() */ - } - } + for ( i = 0; i < n; i++ ) + { + count_free( st_ivas->mem_hp20_in[i] ); + st_ivas->mem_hp20_in[i] = NULL; + } + count_free( st_ivas->mem_hp20_in ); + st_ivas->mem_hp20_in = NULL; + } - if ( st_ivas->nCPE > 1 ) - { - if ( ( error = mct_enc_reconfigure( st_ivas, 0 ) ) != IVAS_ERR_OK ) - { - return error; - } - } + /*------------------------------------------------------------------------------------------* + * Reopening Encoder handles for Reinitialisation + *------------------------------------------------------------------------------------------*/ + + if ( ( error = ivas_qmetadata_open( &( st_ivas->hQMetaData ) ) ) != IVAS_ERR_OK ) + { + return error; + } + + st_ivas->sba_mode = ivas_sba_mode_select( ivas_total_brate ); + st_ivas->sba_analysis_order = ivas_sba_get_analysis_order( ivas_total_brate, st_ivas->hEncoderConfig->sba_order ); + + if ( st_ivas->sba_mode == SBA_MODE_SPAR ) + { + if ( ( error = ivas_spar_enc_open( st_ivas ) ) != IVAS_ERR_OK ) + { + return error; } - else + } + + if ( ( error = ivas_dirac_enc_open( st_ivas ) ) != IVAS_ERR_OK ) + { + return error; + } + + + for ( sce_id = 0; sce_id < st_ivas->nSCE; sce_id++ ) + { + if ( ( error = create_sce_enc( st_ivas, sce_id, ivas_total_brate / st_ivas->nchan_transport ) ) != IVAS_ERR_OK ) { - Indice *ind_list; - int16_t nb_bits_tot; - int16_t next_ind; - int16_t last_ind; - BSTR_ENC_HANDLE hBstr; - BSTR_ENC_HANDLE hMetaData; - - ind_list = NULL; - hBstr = NULL; - hMetaData = NULL; - - /* get the index list pointers */ - if ( nSCE_old ) - { - hBstr = st_ivas->hSCE[0]->hCoreCoder[0]->hBstr; - hMetaData = st_ivas->hSCE[0]->hMetaData; - } - else if ( nCPE_old ) - { - hBstr = st_ivas->hCPE[0]->hCoreCoder[0]->hBstr; - hMetaData = st_ivas->hCPE[nCPE_old - 1]->hMetaData; - } -#ifdef DEBUGGING - else - { - assert( 0 && "At least one SCE or one CPE should have existed before!\n" ); - } -#endif + return error; + } - /* save bitstream information */ - ind_list = hBstr->ind_list; - nb_bits_tot = hBstr->nb_bits_tot; - next_ind = hBstr->next_ind; - last_ind = hBstr->last_ind; - ind_list_metadata = hMetaData->ind_list; + /* prepare bitstream buffers */ + st_ivas->hSCE[sce_id]->hCoreCoder[0]->hBstr->ind_list = ind_list + sce_id * MAX_NUM_INDICES; + reset_indices_enc( st_ivas->hSCE[sce_id]->hCoreCoder[0]->hBstr, MAX_NUM_INDICES ); - /* destroy superfluous core coder elements */ - for ( sce_id = st_ivas->nSCE; sce_id < nSCE_old; sce_id++ ) - { - destroy_sce_enc( st_ivas->hSCE[sce_id] ); - st_ivas->hSCE[sce_id] = NULL; - } + st_ivas->hSCE[sce_id]->hMetaData->ind_list = ind_list_metadata + sce_id * MAX_BITS_METADATA; + reset_indices_enc( st_ivas->hSCE[sce_id]->hMetaData, MAX_BITS_METADATA ); - for ( cpe_id = st_ivas->nCPE; cpe_id < nCPE_old; cpe_id++ ) - { - destroy_cpe_enc( st_ivas->hCPE[cpe_id] ); - st_ivas->hCPE[cpe_id] = NULL; - } + if ( st_ivas->sba_mode == SBA_MODE_SPAR && st_ivas->hEncoderConfig->Opt_DTX_ON ) + { + st_ivas->hSCE[sce_id]->hCoreCoder[0]->dtx_sce_sba = 1; + } + } - if ( st_ivas->nCPE <= 1 && st_ivas->hMCT != NULL ) - { - ivas_mct_enc_close( st_ivas->hMCT ); - st_ivas->hMCT = NULL; - } + for ( cpe_id = 0; cpe_id < st_ivas->nCPE; cpe_id++ ) + { + if ( ( error = create_cpe_enc( st_ivas, cpe_id, ( ivas_total_brate / st_ivas->nchan_transport ) * CPE_CHANNELS ) ) != IVAS_ERR_OK ) + { + return error; + } - /* special case, if we have MCT now and had a single CPE before, remove the MDCT Stereo handles */ - if ( st_ivas->nCPE > 1 && nCPE_old == 1 ) - { - count_free( st_ivas->hCPE[0]->hStereoMdct ); - st_ivas->hCPE[0]->hStereoMdct = NULL; - } + /* prepare bitstream buffers */ + for ( n = 0; n < CPE_CHANNELS; n++ ) + { + st_ivas->hCPE[cpe_id]->hCoreCoder[n]->hBstr->ind_list = ind_list + ( cpe_id * CPE_CHANNELS + n ) * MAX_NUM_INDICES; + reset_indices_enc( st_ivas->hCPE[cpe_id]->hCoreCoder[n]->hBstr, MAX_NUM_INDICES ); - /* create missing core coder elements and set element bitrates for alrady existing ones */ - if ( st_ivas->nSCE > 0 ) + if ( hEncoderConfig->Opt_DTX_ON ) { - int16_t nSCE_existing; - nSCE_existing = min( nSCE_old, st_ivas->nSCE ); - for ( sce_id = 0; sce_id < nSCE_existing; sce_id++ ) - { - copy_encoder_config( st_ivas, st_ivas->hSCE[sce_id]->hCoreCoder[0], 0 ); - st_ivas->hSCE[sce_id]->element_brate = ivas_total_brate / st_ivas->nchan_transport; - st_ivas->hSCE[sce_id]->hCoreCoder[0]->total_brate = st_ivas->hSCE[sce_id]->element_brate; /* dummy initialization for getting right pointers initialization of input buffers in init_coder_ace_plus() */ - } - for ( sce_id = nSCE_existing; sce_id < st_ivas->nSCE; sce_id++ ) - { - if ( ( error = create_sce_enc( st_ivas, sce_id, ivas_total_brate / st_ivas->nchan_transport ) ) != IVAS_ERR_OK ) - { - return error; - } - - /* prepare bitstream buffers */ - st_ivas->hSCE[sce_id]->hCoreCoder[0]->hBstr->ind_list = ind_list + sce_id * MAX_NUM_INDICES; - - /* only reset indices if it is not the first index list, this already contains the IVAS format bits */ - if ( sce_id > 0 ) - { - reset_indices_enc( st_ivas->hSCE[sce_id]->hCoreCoder[0]->hBstr, MAX_NUM_INDICES ); - } - else - { - st_ivas->hSCE[sce_id]->hCoreCoder[0]->hBstr->last_ind = last_ind; - st_ivas->hSCE[sce_id]->hCoreCoder[0]->hBstr->nb_bits_tot = nb_bits_tot; - st_ivas->hSCE[sce_id]->hCoreCoder[0]->hBstr->next_ind = next_ind; - } - - st_ivas->hSCE[sce_id]->hMetaData->ind_list = ind_list_metadata + sce_id * MAX_BITS_METADATA; - reset_indices_enc( st_ivas->hSCE[sce_id]->hMetaData, MAX_BITS_METADATA ); - } + st_ivas->hCPE[cpe_id]->hCoreCoder[n]->cng_sba_flag = 1; } + } - if ( st_ivas->nCPE > 0 ) - { - int16_t nCPE_existing; - nCPE_existing = min( nCPE_old, st_ivas->nCPE ); - for ( cpe_id = 0; cpe_id < nCPE_existing; cpe_id++ ) - { - st_ivas->hCPE[cpe_id]->element_brate = ( ivas_total_brate / st_ivas->nchan_transport ) * CPE_CHANNELS; - - /* prepare bitstream buffers */ - for ( n = 0; n < CPE_CHANNELS; n++ ) - { - copy_encoder_config( st_ivas, st_ivas->hCPE[cpe_id]->hCoreCoder[n], 0 ); - st_ivas->hCPE[cpe_id]->hCoreCoder[n]->total_brate = st_ivas->hCPE[cpe_id]->element_brate / ( st_ivas->nCPE > 1 ? 1 : CPE_CHANNELS ); /* dummy initialization for getting right pointers initialization of input buffers in init_coder_ace_plus() */ - } - } - - for ( cpe_id = nCPE_existing; cpe_id < st_ivas->nCPE; cpe_id++ ) - { - if ( ( error = create_cpe_enc( st_ivas, cpe_id, ( ivas_total_brate / st_ivas->nchan_transport ) * CPE_CHANNELS ) ) != IVAS_ERR_OK ) - { - return error; - } - - /* prepare bitstream buffers */ - for ( n = 0; n < CPE_CHANNELS; n++ ) - { - st_ivas->hCPE[cpe_id]->hCoreCoder[n]->hBstr->ind_list = ind_list + ( cpe_id * CPE_CHANNELS + n ) * MAX_NUM_INDICES; - if ( cpe_id * CPE_CHANNELS + n > 0 ) - { - reset_indices_enc( st_ivas->hCPE[cpe_id]->hCoreCoder[n]->hBstr, MAX_NUM_INDICES ); - } - else - { - st_ivas->hCPE[cpe_id]->hCoreCoder[n]->hBstr->last_ind = last_ind; - st_ivas->hCPE[cpe_id]->hCoreCoder[n]->hBstr->nb_bits_tot = nb_bits_tot; - st_ivas->hCPE[cpe_id]->hCoreCoder[n]->hBstr->next_ind = next_ind; - } - - if ( st_ivas->hEncoderConfig->Opt_DTX_ON ) - { - st_ivas->hCPE[cpe_id]->hCoreCoder[n]->cng_sba_flag = 1; - } - } - } - } + /* Metadata only initialized for the last CPE index */ + if ( cpe_id == st_ivas->nCPE - 1 ) + { + st_ivas->hCPE[cpe_id]->hMetaData->ind_list = ind_list_metadata + sce_id * MAX_BITS_METADATA; + reset_indices_enc( st_ivas->hCPE[cpe_id]->hMetaData, MAX_BITS_METADATA ); + } + } - if ( st_ivas->nCPE > 1 && nCPE_old <= 1 ) - { - if ( nCPE_old == 1 ) - { - /* set correct nominal bitrates and igf config already here, needed for the correct init of the MDCT Stereo handles for MCT */ - for ( n = 0; n < CPE_CHANNELS; n++ ) - { - st_ivas->hCPE[0]->hCoreCoder[n]->total_brate = st_ivas->hCPE[0]->element_brate; - - st_ivas->hCPE[0]->hCoreCoder[n]->bits_frame_nominal = (int16_t) ( st_ivas->hCPE[0]->element_brate / FRAMES_PER_SEC ); - st_ivas->hCPE[0]->hCoreCoder[n]->igf = getIgfPresent( st_ivas->hCPE[0]->hCoreCoder[n]->element_mode, - st_ivas->hCPE[0]->hCoreCoder[n]->bits_frame_nominal * FRAMES_PER_SEC, - st_ivas->hCPE[0]->hCoreCoder[n]->bwidth, - st_ivas->hCPE[0]->hCoreCoder[n]->rf_mode, - st_ivas->hCPE[0]->hCoreCoder[n]->mct_chan_mode ); - - if ( st_ivas->hCPE[0]->hCoreCoder[n]->igf ) - { - IGFEncSetMode( st_ivas->hCPE[0]->hCoreCoder[n]->hIGFEnc, - st_ivas->hCPE[0]->element_brate, - st_ivas->hCPE[0]->hCoreCoder[n]->bwidth, - st_ivas->hCPE[0]->hCoreCoder[n]->element_mode, - st_ivas->hCPE[0]->hCoreCoder[n]->rf_mode ); - } - } - } - - if ( ( error = create_mct_enc( st_ivas ) ) != IVAS_ERR_OK ) - { - return error; - } - } - else if ( st_ivas->hMCT != NULL && st_ivas->nCPE > 1 ) - { - if ( ( error = mct_enc_reconfigure( st_ivas, st_ivas->nCPE != nCPE_old ) ) != IVAS_ERR_OK ) - { - return error; - } - } + if ( st_ivas->nCPE > 1 ) + { + if ( ( error = create_mct_enc( st_ivas ) ) != IVAS_ERR_OK ) + { + return error; + } + } + n = getNumChanAnalysis( st_ivas ); - /* metadata handling for CPEs */ - if ( st_ivas->nCPE > 0 ) - { - if ( st_ivas->hCPE[st_ivas->nCPE - 1]->hMetaData == NULL ) - { - if ( ( st_ivas->hCPE[st_ivas->nCPE - 1]->hMetaData = (BSTR_ENC_HANDLE) count_malloc( sizeof( BSTR_ENC_DATA ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for MetaData structure\n" ) ); - } - } - - st_ivas->hCPE[st_ivas->nCPE - 1]->hMetaData->ind_list = ind_list_metadata; - reset_indices_enc( st_ivas->hCPE[st_ivas->nCPE - 1]->hMetaData, MAX_BITS_METADATA ); - - for ( cpe_id = 0; cpe_id < st_ivas->nCPE - 1; cpe_id++ ) - { - if ( st_ivas->hCPE[cpe_id]->hMetaData != NULL ) - { - count_free( st_ivas->hCPE[cpe_id]->hMetaData ); - st_ivas->hCPE[cpe_id]->hMetaData = NULL; - } - } - } + if ( n > 0 ) + { + if ( ( st_ivas->mem_hp20_in = (float **) count_malloc( n * sizeof( float * ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for HP20 filter memory\n" ) ); + } + } + else + { + st_ivas->mem_hp20_in = NULL; + } - /* special case, if we have a single CPE and had MCT before we need to init the MDCT stereo handles here */ - if ( st_ivas->nCPE == 1 && nCPE_old > 1 ) - { - if ( ( st_ivas->hCPE[st_ivas->nCPE - 1]->hStereoMdct = (STEREO_MDCT_ENC_DATA_HANDLE) count_malloc( sizeof( STEREO_MDCT_ENC_DATA ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for MDCT Stereo \n" ) ); - } - - /* set correct nominal bitrates and igf config already here, needed for the correct init of the MDCT Stereo handle */ - for ( n = 0; n < CPE_CHANNELS; n++ ) - { - st_ivas->hCPE[0]->hCoreCoder[n]->total_brate = st_ivas->hCPE[0]->element_brate; - - st_ivas->hCPE[0]->hCoreCoder[n]->bits_frame_nominal = (int16_t) ( st_ivas->hCPE[0]->element_brate / FRAMES_PER_SEC ); - st_ivas->hCPE[0]->hCoreCoder[n]->igf = getIgfPresent( st_ivas->hCPE[0]->hCoreCoder[n]->element_mode, - st_ivas->hCPE[0]->hCoreCoder[n]->bits_frame_nominal * FRAMES_PER_SEC, - st_ivas->hCPE[0]->hCoreCoder[n]->bwidth, - st_ivas->hCPE[0]->hCoreCoder[n]->rf_mode, - st_ivas->hCPE[0]->hCoreCoder[n]->mct_chan_mode ); - - if ( st_ivas->hCPE[0]->hCoreCoder[n]->igf ) - { - IGFEncSetMode( st_ivas->hCPE[0]->hCoreCoder[n]->hIGFEnc, - st_ivas->hCPE[0]->element_brate, - st_ivas->hCPE[0]->hCoreCoder[n]->bwidth, - st_ivas->hCPE[0]->hCoreCoder[n]->element_mode, - st_ivas->hCPE[0]->hCoreCoder[n]->rf_mode ); - } - /* reset mct_chan_mode */ - st_ivas->hCPE[0]->hCoreCoder[n]->mct_chan_mode = MCT_CHAN_MODE_REGULAR; - } - - initMdctStereoEncData( st_ivas->hCPE[st_ivas->nCPE - 1]->hStereoMdct, st_ivas->hEncoderConfig->ivas_format, st_ivas->hCPE[st_ivas->nCPE - 1]->element_mode, st_ivas->hCPE[st_ivas->nCPE - 1]->element_brate, st_ivas->hEncoderConfig->max_bwidth, 0, NULL, 1 ); - st_ivas->hCPE[st_ivas->nCPE - 1]->hStereoMdct->isSBAStereoMode = ( ( st_ivas->hEncoderConfig->ivas_format == SBA_FORMAT ) && ( st_ivas->nchan_transport == 2 ) ); - } + for ( i = 0; i < n; i++ ) + { + if ( ( st_ivas->mem_hp20_in[i] = (float *) count_malloc( L_HP20_MEM * sizeof( float ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for HP20 filter memory\n" ) ); } + + set_f( st_ivas->mem_hp20_in[i], 0.0f, L_HP20_MEM ); + } + return error; +} #endif +/*-------------------------------------------------------------------* + * ivas_sba_enc_reconfigure() + * + * Reconfigure IVAS SBA encoder + *-------------------------------------------------------------------*/ + +ivas_error ivas_sba_enc_reconfigure( + Encoder_Struct *st_ivas /* i/o: IVAS encoder structure */ +) +{ + int16_t nSCE_old, nCPE_old, nchan_transport_old; + int32_t ivas_total_brate; + ivas_error error; + + error = IVAS_ERR_OK; + + ivas_total_brate = st_ivas->hEncoderConfig->ivas_total_brate; + + if ( ivas_total_brate != st_ivas->hEncoderConfig->last_ivas_total_brate ) + { + nchan_transport_old = st_ivas->nchan_transport; + nCPE_old = st_ivas->nCPE; + nSCE_old = st_ivas->nSCE; + + st_ivas->sba_analysis_order = ivas_sba_get_analysis_order( ivas_total_brate, st_ivas->hEncoderConfig->sba_order ); + + ivas_dirac_enc_reconfigure( st_ivas ); + + + /*-----------------------------------------------------------------* + * Allocate, initalize, and configure SCE/CPE/MCT handles + *-----------------------------------------------------------------*/ + + ivas_corecoder_enc_reconfig( st_ivas, nSCE_old, nCPE_old, nchan_transport_old ); } return error; diff --git a/lib_enc/ivas_sce_enc.c b/lib_enc/ivas_sce_enc.c index 2592b578f6..0b49c56854 100644 --- a/lib_enc/ivas_sce_enc.c +++ b/lib_enc/ivas_sce_enc.c @@ -166,15 +166,11 @@ ivas_error ivas_sce_enc( st->total_brate = hSCE->element_brate - nb_bits_metadata * FRAMES_PER_SEC; /* set flag for sampling rate of OL S/M classifier */ -#ifdef CORECODER_BITRATE_SWITCHING // VE2EF: TBV whether it can be done more efficiently flag_16k_smc = 0; if ( st_ivas->hEncoderConfig->ivas_format == SBA_FORMAT && ( st_ivas->hEncoderConfig->ivas_total_brate == IVAS_24k4 || st_ivas->hEncoderConfig->ivas_total_brate == IVAS_32k ) && hSCE->element_brate == hSCE->last_element_brate ) { flag_16k_smc = 1; } -#else - flag_16k_smc = ( st_ivas->hEncoderConfig->ivas_format == SBA_FORMAT && ( st_ivas->hEncoderConfig->ivas_total_brate == IVAS_24k4 || st_ivas->hEncoderConfig->ivas_total_brate == IVAS_32k ) ); -#endif #ifdef DEBUG_MODE_INFO dbgwrite( st->input - NS2SA( st->input_Fs, ACELP_LOOK_NS ), sizeof( float ), input_frame, 1, "res/input_DMX" ); @@ -241,11 +237,7 @@ ivas_error ivas_sce_enc( * Encoder *----------------------------------------------------------------*/ -#ifdef CORECODER_BITRATE_SWITCHING if ( ( error = ivas_core_enc( hSCE, NULL, NULL, 1, old_inp_12k8, old_inp_16k, Etot, ener, A, Aw, epsP, lsp_new, lsp_mid, vad_hover_flag, attack_flag, realBuffer, imagBuffer, old_wsp, loc_harm, cor_map_sum, vad_flag_dtx, enerBuffer, fft_buff, 0, ivas_format, flag_16k_smc ) ) != IVAS_ERR_OK ) -#else - if ( ( error = ivas_core_enc( hSCE, NULL, NULL, 1, old_inp_12k8, old_inp_16k, Etot, ener, A, Aw, epsP, lsp_new, lsp_mid, vad_hover_flag, attack_flag, realBuffer, imagBuffer, old_wsp, loc_harm, cor_map_sum, vad_flag_dtx, enerBuffer, fft_buff, 0, flag_16k_smc ) ) != IVAS_ERR_OK ) -#endif { return error; } @@ -257,9 +249,7 @@ ivas_error ivas_sce_enc( /* update input samples buffer */ mvr2r( st->input, st->old_input_signal, input_frame ); -#ifdef CORECODER_BITRATE_SWITCHING hSCE->last_element_brate = hSCE->element_brate; -#endif #ifdef DEBUG_MODE_INFO { @@ -307,9 +297,7 @@ ivas_error create_sce_enc( hSCE->sce_id = sce_id; hSCE->element_brate = element_brate; -#ifdef CORECODER_BITRATE_SWITCHING hSCE->last_element_brate = hSCE->element_brate; -#endif /*-----------------------------------------------------------------* * Metadata: allocate and initialize diff --git a/lib_enc/ivas_sns_enc.c b/lib_enc/ivas_sns_enc.c index 6790f0cf6d..45c04ac9ea 100644 --- a/lib_enc/ivas_sns_enc.c +++ b/lib_enc/ivas_sns_enc.c @@ -44,7 +44,6 @@ #include "wmops.h" - /*------------------------------------------------------------------- * sns_1st_cod() * diff --git a/lib_enc/ivas_spar_encoder.c b/lib_enc/ivas_spar_encoder.c index b5f00848a8..00d185fe08 100644 --- a/lib_enc/ivas_spar_encoder.c +++ b/lib_enc/ivas_spar_encoder.c @@ -121,13 +121,23 @@ ivas_error ivas_spar_enc_open( /* AGC handle */ #ifdef AGC_ENABLE_FOR_LBR - hSpar->AGC_Enable = ivas_agc_enc_get_enablement_flag( hEncoderConfig->Opt_AGC_ON, nchan_transport ); +#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 +#endif + +#ifdef AGC_ENABLE_FOR_LBR + hSpar->hAgcEnc = NULL; + if ( hSpar->AGC_Enable ) #endif - if ( ( error = ivas_spar_agc_enc_open( &hSpar->hAgcEnc, input_Fs, nchan_inp ) ) != IVAS_ERR_OK ) { - return error; + if ( ( error = ivas_spar_agc_enc_open( &hSpar->hAgcEnc, input_Fs, nchan_inp ) ) != IVAS_ERR_OK ) + { + return error; + } } - /* PCA handle */ hSpar->hPCA = NULL; if ( hEncoderConfig->Opt_PCA_ON ) @@ -151,11 +161,11 @@ ivas_error ivas_spar_enc_open( if ( st_ivas->nchan_transport == 1 ) { - st_ivas->hEncoderConfig->element_mode_init = IVAS_SCE; + hEncoderConfig->element_mode_init = IVAS_SCE; } else { - st_ivas->hEncoderConfig->element_mode_init = IVAS_CPE_MDCT; + hEncoderConfig->element_mode_init = IVAS_CPE_MDCT; } /*-----------------------------------------------------------------* @@ -233,7 +243,6 @@ void ivas_spar_enc_close( hSpar->hFrontVad = NULL; } - num_chans = hSpar->hFbMixer->fb_cfg->num_in_chans; assert( num_chans <= nchan_inp ); @@ -288,7 +297,7 @@ ivas_error ivas_spar_enc( hEncoderConfig = st_ivas->hEncoderConfig; /* front VAD */ - if ( ( error = front_vad_spar( st_ivas->hSpar, data_f[0], st_ivas->hEncoderConfig, input_frame ) ) != IVAS_ERR_OK ) + if ( ( error = front_vad_spar( st_ivas->hSpar, data_f[0], hEncoderConfig, input_frame ) ) != IVAS_ERR_OK ) { return error; } @@ -310,8 +319,13 @@ ivas_error ivas_spar_enc( *nb_bits_metadata = hMetaData->nb_bits_tot; +#ifdef FIX_SBA_DTX_DECODE_ERROR + /* Force IVAS front pre-proc decision for higher bitrates */ + if ( hEncoderConfig->ivas_total_brate > SBA_DTX_BITRATE_THRESHOLD || hEncoderConfig->Opt_DTX_ON == 0 ) +#else /* temp hack to not force IVAS front pre-proc decision for higher bitrates */ if ( hEncoderConfig->ivas_total_brate > IVAS_64k || hEncoderConfig->Opt_DTX_ON == 0 ) +#endif { st_ivas->hSpar->front_vad_flag = 0; } @@ -319,69 +333,6 @@ ivas_error ivas_spar_enc( return error; } -#ifndef SBA_SPAR_HARM -/*-----------------------------------------------------------------------------------------* - * Function ivas_spar_enc_get_windowed_fr() - * - * Get windowed FRs - *-----------------------------------------------------------------------------------------*/ - -static void ivas_spar_enc_get_windowed_fr( - IVAS_FB_MIXER_HANDLE hFbMixer, - float *pIn_blocks[IVAS_SPAR_MAX_CH], - ivas_enc_cov_handler_in_buf_t *pCov_in_buf, - const int16_t input_frame, - const int16_t nchan_inp, - const int16_t num_past_samples ) -{ - int16_t i, j, rev_offset; - - for ( i = 0; i < nchan_inp; i++ ) - { - const int16_t stride = hFbMixer->pFb->fb_bin_to_band.short_stride; - float tmp_buf[MDFT_FB_BANDS_240 * 2]; - int16_t win_len = (int16_t) hFbMixer->ana_window_offset; - float *mdft_in_ptr = tmp_buf + stride - win_len; - float tmp_in_block[L_FRAME48k + MDFT_FB_BANDS_240]; - float *data_ptr = tmp_in_block; - float *fr_re_ptr = pCov_in_buf->ppIn_FR_real[i]; - float *fr_im_ptr = pCov_in_buf->ppIn_FR_imag[i]; - - set_f( tmp_buf, 0, MDFT_FB_BANDS_240 * 2 ); - - /* copy input data, because pIn_blocks and fr_re_ptr + fr_im_ptr use the same memory */ - mvr2r( &pIn_blocks[i][input_frame - num_past_samples], tmp_in_block, input_frame + win_len ); - - for ( int16_t blk = 0; blk < input_frame / stride; blk++ ) - { - - for ( j = 0; j < win_len; j++ ) - { - mdft_in_ptr[j] = data_ptr[j] * hFbMixer->pAna_window[j]; - } - - for ( j = win_len; j < stride; j++ ) - { - mdft_in_ptr[j] = data_ptr[j]; - } - - rev_offset = win_len - 1; - for ( j = stride; j < stride + win_len; j++ ) - { - mdft_in_ptr[j] = data_ptr[j] * hFbMixer->pAna_window[rev_offset--]; - } - - ivas_mdft( tmp_buf, fr_re_ptr, fr_im_ptr, stride << 1, stride ); - - data_ptr += stride; - fr_re_ptr += stride; - fr_im_ptr += stride; - } - } - - return; -} -#endif /*-----------------------------------------------------------------------------------------* * Function ivas_spar_enc_process() @@ -399,24 +350,11 @@ static ivas_error ivas_spar_enc_process( { float pcm_tmp[IVAS_SPAR_MAX_CH][L_FRAME48k * 2]; float *p_pcm_tmp[IVAS_SPAR_MAX_CH]; -#ifdef SBA_SPAR_HARM int16_t i, j, b, i_ts, input_frame, transient_det, dtx_vad; -#else - int16_t i, j, k, b, i_ts, input_frame, num_bands_bw; - int16_t dtx_vad, dtx_cov_flag, dtx_silence_mode; -#endif int32_t ivas_total_brate, input_Fs; -#ifndef SBA_SPAR_HARM - ivas_enc_cov_handler_in_buf_t cov_in_buf; -#endif float *cov_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH]; float *cov_dtx_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH]; -#ifdef SBA_SPAR_HARM int16_t nchan_inp, nchan_transport, sba_order; -#else - ivas_spar_md_enc_in_buf_t md_in_buf; - int16_t nchan_inp, nchan_transport, bwidth, sba_order; -#endif int16_t table_idx; int16_t in_out_mixer_map[IVAS_MAX_FB_MIXER_OUT_CH][IVAS_MAX_SPAR_FB_MIXER_IN_CH]; ivas_error error; @@ -451,19 +389,11 @@ static ivas_error ivas_spar_enc_process( mvr2r( data_f[HOA_keep_ind[i]], data_f[i], input_frame ); } -#ifndef SBA_SPAR_HARM - table_idx = ivas_get_spar_table_idx( ivas_total_brate, sba_order, SPAR_CONFIG_BW, NULL, NULL ); -#endif - /*-----------------------------------------------------------------------------------------* * Transient detector *-----------------------------------------------------------------------------------------*/ -#ifdef SBA_SPAR_HARM transient_det = ivas_transient_det_process( hSpar->hTranDet, data_f[0], input_frame ); -#else - cov_in_buf.transient_det = ivas_transient_det_process( hSpar->hTranDet, data_f[0], input_frame ); -#endif /* store previous input samples for W in local buffer */ assert( num_del_samples <= IVAS_FB_1MS_48K_SAMP ); @@ -482,27 +412,12 @@ static ivas_error ivas_spar_enc_process( ivas_fb_mixer_pcm_ingest( hSpar->hFbMixer, data_f, p_pcm_tmp, input_frame ); /* prepare Parameter MDFT analysis */ -#ifdef SBA_SPAR_HARM for ( i = 0; i < nchan_inp; i++ ) { ppIn_FR_real[i] = p_pcm_tmp[i]; ppIn_FR_imag[i] = p_pcm_tmp[i] + input_frame; p_pcm_tmp[i] = &data_f[i][0]; } -#else - for ( i = 0; i < nchan_inp; i++ ) - { - cov_in_buf.ppIn_FR_real[i] = p_pcm_tmp[i]; - cov_in_buf.ppIn_FR_imag[i] = p_pcm_tmp[i] + input_frame; - } - - for ( i = 0; i < nchan_inp; i++ ) - { - p_pcm_tmp[i] = &data_f[i][0]; - ppIn_FR_real[i] = cov_in_buf.ppIn_FR_real[i]; - ppIn_FR_imag[i] = cov_in_buf.ppIn_FR_imag[i]; - } -#endif l_ts = input_frame / MAX_PARAM_SPATIAL_SUBFRAMES; @@ -522,41 +437,18 @@ static ivas_error ivas_spar_enc_process( /* turn pointers back to the local buffer, needed for the following processing */ for ( i = 0; i < nchan_inp; i++ ) { -#ifdef SBA_SPAR_HARM ppIn_FR_real[i] = pcm_tmp[i]; ppIn_FR_imag[i] = pcm_tmp[i] + input_frame; -#endif p_pcm_tmp[i] = pcm_tmp[i]; } -#ifndef SBA_SPAR_HARM - cov_in_buf.num_ch = nchan_inp; -#endif - dtx_vad = ( hEncoderConfig->Opt_DTX_ON == 1 ) ? front_vad_flag : 1; /*-----------------------------------------------------------------------------------------* * DirAC encoding *-----------------------------------------------------------------------------------------*/ -#ifdef SBA_SPAR_HARM - ivas_dirac_param_est_enc( st_ivas->hDirAC, hQMetaData->q_direction, hQMetaData->useLowerRes, - data_f, ppIn_FR_real, ppIn_FR_imag, input_frame -#ifdef SBA_HOA_HBR_IMPROV - , - st_ivas->sba_mode -#endif - ); -#else - ivas_dirac_param_est_enc( st_ivas->hDirAC, hQMetaData->q_direction, hQMetaData->useLowerRes, - data_f, cov_in_buf.ppIn_FR_real, cov_in_buf.ppIn_FR_imag, input_frame -#ifdef SBA_HOA_HBR_IMPROV - , - st_ivas->sba_mode -#endif - ); -#endif - + ivas_dirac_param_est_enc( st_ivas->hDirAC, hQMetaData->q_direction, hQMetaData->useLowerRes, data_f, ppIn_FR_real, ppIn_FR_imag, input_frame, st_ivas->sba_mode ); if ( hQMetaData->q_direction->cfg.nbands > 0 ) { @@ -641,26 +533,10 @@ static ivas_error ivas_spar_enc_process( } } -#ifndef SBA_SPAR_HARM - /*-----------------------------------------------------------------------------------------* - * Pre-proc flags - *-----------------------------------------------------------------------------------------*/ - - /* use just VAD function to get VAD flags */ - dtx_vad = ( hEncoderConfig->Opt_DTX_ON == 1 ) ? front_vad_flag : 1; - dtx_cov_flag = ( dtx_vad == 1 ) ? 0 : 1; - dtx_silence_mode = 0; // VE2DB: this variable is always 0 - please review or remove it - bwidth = ivas_get_bw_idx_from_sample_rate( input_Fs ); - bwidth = min( bwidth, hEncoderConfig->max_bwidth ); -#endif - /*-----------------------------------------------------------------------------------------* * Covariance process *-----------------------------------------------------------------------------------------*/ -#ifndef SBA_SPAR_HARM - cov_in_buf.num_ch = nchan_inp; -#endif for ( i = 0; i < nchan_inp; i++ ) { for ( j = 0; j < nchan_inp; j++ ) @@ -670,104 +546,31 @@ static ivas_error ivas_spar_enc_process( } } -#ifdef SBA_SPAR_HARM ivas_enc_cov_handler_process( hSpar->hCovEnc, ppIn_FR_real, ppIn_FR_imag, cov_real, cov_dtx_real, hSpar->hFbMixer->pFb, 0, hSpar->hFbMixer->pFb->filterbank_num_bands, nchan_inp, dtx_vad, transient_det ); -#else - cov_in_buf.dtx_cov_flag = dtx_cov_flag; - - ivas_enc_cov_handler_process( hSpar->hCovEnc, &cov_in_buf, cov_real, cov_dtx_real, hSpar->hFbMixer->pFb, 0, hSpar->hFbMixer->pFb->filterbank_num_bands ); -#endif /*-----------------------------------------------------------------------------------------* * Set SPAR bitrates *-----------------------------------------------------------------------------------------*/ -#ifdef SBA_SPAR_HARM table_idx = ivas_get_spar_table_idx( ivas_total_brate, sba_order, SPAR_CONFIG_BW, NULL, NULL ); -#endif if ( hSpar->hMdEnc->table_idx != table_idx ) { hSpar->hMdEnc->table_idx = table_idx; - ivas_spar_set_bitrate_config( &hSpar->hMdEnc->spar_md_cfg, table_idx, -#ifdef SBA_HOA_HBR_IMPROV - ( hSpar->hMdEnc->spar_hoa_md_flag ) ? IVAS_MAX_NUM_BANDS : SPAR_DIRAC_SPLIT_START_BAND -#else - SPAR_DIRAC_SPLIT_START_BAND -#endif - ); + ivas_spar_set_bitrate_config( &hSpar->hMdEnc->spar_md_cfg, table_idx, ( hSpar->hMdEnc->spar_hoa_md_flag ) ? IVAS_MAX_NUM_BANDS : SPAR_DIRAC_SPLIT_START_BAND ); } -#ifdef SBA_SPAR_HARM nchan_transport = st_ivas->nchan_transport; -#else - nchan_transport = hSpar->hMdEnc->spar_md_cfg.nchan_transport; -#endif /*-----------------------------------------------------------------------------------------* * MetaData encoder *-----------------------------------------------------------------------------------------*/ -#ifdef SBA_SPAR_HARM -#ifdef SBA_HOA_HBR_IMPROV if ( hSpar->hMdEnc->spar_hoa_md_flag == 0 ) -#endif { ivas_spar_md_enc_process( hSpar->hMdEnc, hEncoderConfig, cov_real, cov_dtx_real, hMetaData, dtx_vad, nchan_inp, sba_order ); } -#else - num_bands_bw = ivas_get_num_bands_from_bw_idx( bwidth ); - - if ( dtx_vad == 0 ) - { - for ( i = 0; i < nchan_inp; i++ ) - { - for ( j = 0; j < nchan_inp; j++ ) - { - md_in_buf.cov_real[i][j] = cov_dtx_real[i][j]; - for ( k = num_bands_bw; k < IVAS_MAX_NUM_BANDS; k++ ) - { - md_in_buf.cov_real[i][j][k] = 0; - } - } - } - } - else - { - for ( i = 0; i < nchan_inp; i++ ) - { - for ( j = 0; j < nchan_inp; j++ ) - { - md_in_buf.cov_real[i][j] = cov_real[i][j]; - for ( k = num_bands_bw; k < IVAS_MAX_NUM_BANDS; k++ ) - { - md_in_buf.cov_real[i][j][k] = 0; - } - } - } - } - md_in_buf.num_bands = ivas_get_num_bands_from_bw_idx( SPAR_CONFIG_BW ); -#ifdef SBA_HOA_HBR_IMPROV - if ( hSpar->hMdEnc->spar_hoa_md_flag == 0 ) -#endif - { - md_in_buf.num_bands = min( md_in_buf.num_bands, SPAR_DIRAC_SPLIT_START_BAND ); - } - - md_in_buf.dtx_vad = dtx_vad; - -#ifdef SBA_HOA_HBR_IMPROV - if ( hSpar->hMdEnc->spar_hoa_md_flag == 0 ) -#endif - { - ivas_spar_md_enc_process( hSpar->hMdEnc, hEncoderConfig, &md_in_buf, hMetaData, dtx_silence_mode, sba_order ); - } -#endif - -#ifndef SBA_SPAR_HARM - if ( st_ivas->sba_mode == SBA_MODE_SPAR ) // VE2DB: this looks obsolete -#endif { float azi_dirac[IVAS_MAX_NUM_BANDS][MAX_PARAM_SPATIAL_SUBFRAMES]; float ele_dirac[IVAS_MAX_NUM_BANDS][MAX_PARAM_SPATIAL_SUBFRAMES]; @@ -800,33 +603,20 @@ static ivas_error ivas_spar_enc_process( Wscale_d[b] = 1.0f; for ( i = 1; i < nchan_inp; i++ ) { -#ifdef SBA_SPAR_HARM Wscale_d[b] += cov_real[i][i][b] / max( EPSILON, cov_real[0][0][b] ); -#else - Wscale_d[b] += md_in_buf.cov_real[i][i][b] / max( EPSILON, md_in_buf.cov_real[0][0][b] ); -#endif } Wscale_d[b] = Wscale_d[b] / ( 1.0f + (float) sba_order ); /*DirAC normalized signal variance sums to 1 + order*/ Wscale_d[b] = sqrtf( Wscale_d[b] ); Wscale_d[b] = min( 2.0f, max( Wscale_d[b], 1.0f ) ); } - ivas_get_spar_md_from_dirac( azi_dirac, ele_dirac, diffuseness, 1, hSpar->hMdEnc->mixer_mat, &hSpar->hMdEnc->spar_md, &hSpar->hMdEnc->spar_md_cfg, - d_start_band, d_end_band, -#ifdef SBA_HOA_HBR_IMPROV - ( hSpar->hMdEnc->spar_hoa_md_flag ) ? 1 : sba_order, -#else - sba_order, -#endif - dtx_vad, Wscale_d ); + ivas_get_spar_md_from_dirac( azi_dirac, ele_dirac, diffuseness, 1, hSpar->hMdEnc->mixer_mat, &hSpar->hMdEnc->spar_md, &hSpar->hMdEnc->spar_md_cfg, d_start_band, d_end_band, ( hSpar->hMdEnc->spar_hoa_md_flag ) ? 1 : sba_order, dtx_vad, Wscale_d ); } -#ifdef SBA_HOA_HBR_IMPROV if ( hSpar->hMdEnc->spar_hoa_md_flag ) { ivas_spar_md_enc_process( hSpar->hMdEnc, hEncoderConfig, cov_real, cov_dtx_real, hMetaData, dtx_vad, nchan_inp, sba_order ); } -#endif /*-----------------------------------------------------------------------------------------* * FB mixer @@ -894,7 +684,7 @@ static ivas_error ivas_spar_enc_process( } else { - if ( ivas_total_brate == PCA_BRATE && sba_order == 1 ) + if ( ivas_total_brate == PCA_BRATE && sba_order == SBA_FOA_ORDER ) { /* write PCA bypass bit */ push_next_indice( hMetaData, PCA_MODE_INACTIVE, 1 ); @@ -935,6 +725,10 @@ static ivas_error ivas_spar_enc_process( } else { + /* IVAS_fmToDo: This AGC on/off bit should be removed when the command line option to force enable/disable AGC is + * removed. + * On the decoder side, ivas_agc_enc_get_flag could be used instead to determine if AGC is on or not. The + * ivas_agc_enc_get_flag function should be moved to ivas_agc_com.c and renamed when this occurs. */ push_next_indice( hMetaData, 0, 1 ); } } diff --git a/lib_enc/ivas_spar_md_enc.c b/lib_enc/ivas_spar_md_enc.c index 263d32292a..e6e8b0db61 100644 --- a/lib_enc/ivas_spar_md_enc.c +++ b/lib_enc/ivas_spar_md_enc.c @@ -82,11 +82,14 @@ static void ivas_select_next_strat( ivas_strats_t prior_strat, ivas_strats_t cs[ static void ivas_store_prior_coeffs( ivas_spar_md_enc_state_t *hMdEnc, const int16_t num_bands, const int16_t bands_bw, const int16_t strat, const int16_t dtx_vad, const int16_t qsi ); -static void ivas_write_spar_md_bitstream( ivas_spar_md_enc_state_t *hMdEnc, const int16_t nB, const int16_t bands_bw, BSTR_ENC_HANDLE hMetaData, const int32_t ivas_total_brate, const int16_t dtx_silence_mode, const int16_t strat, const int16_t qsi, const int16_t planarCP ); +static void ivas_write_spar_md_bitstream( ivas_spar_md_enc_state_t *hMdEnc, const int16_t nB, const int16_t bands_bw, BSTR_ENC_HANDLE hMetaData, const int32_t ivas_total_brate, const int16_t strat, const int16_t qsi, const int16_t planarCP ); static ivas_error ivas_spar_md_enc_init( ivas_spar_md_enc_state_t *hMdEnc, const ENCODER_CONFIG_HANDLE hEncoderConfig, const int16_t sba_order ); + static void ivas_spar_quant_pred_coeffs_dtx( ivas_spar_md_t *pSpar_md, const float *pValues, const int16_t ndm, int16_t *pIndex, const int16_t dim1, float *pQuant ); + static void ivas_quant_p_per_band_dtx( float *pP_mat, const int16_t num_dec, const int16_t num_dmx, int16_t *ppIdx_pd, float *pP_out, const int16_t num_ch ); + static void ivas_write_parameter_bitstream_dtx( ivas_spar_md_t *pSpar_md, BSTR_ENC_HANDLE hMetaData, int16_t *num_dmx, int16_t *num_dec, const int16_t num_bands ); static void ivas_quant_p_per_band( ivas_band_coeffs_t *pband_coeffs, ivas_band_coeffs_ind_t *pBand_coeffs_idx, ivas_quant_strat_t *pQs, const int16_t num_ch ); @@ -119,11 +122,7 @@ ivas_error ivas_spar_md_enc_open( return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR MD encoder" ); } - num_channels = 2 * sba_order + 2; - -#ifdef SBA_HOA_HBR_IMPROV - hMdEnc->spar_hoa_md_flag = ivas_sba_get_spar_hoa_md_flag( sba_order, hEncoderConfig->ivas_total_brate ); -#endif + num_channels = ivas_sba_get_nchan_metadata( sba_order ); if ( ( hMdEnc->spar_md.band_coeffs = (ivas_band_coeffs_t *) count_malloc( IVAS_MAX_NUM_BANDS * sizeof( ivas_band_coeffs_t ) ) ) == NULL ) { @@ -319,18 +318,12 @@ static ivas_error ivas_spar_md_enc_init( float PR_minmax[2]; int16_t num_channels, i, j, k; + hMdEnc->spar_hoa_md_flag = ivas_sba_get_spar_hoa_md_flag( sba_order, hEncoderConfig->ivas_total_brate ); num_channels = ivas_sba_get_nchan_metadata( sba_order ); table_idx = ivas_get_spar_table_idx( hEncoderConfig->ivas_total_brate, sba_order, SPAR_CONFIG_BW, NULL, NULL ); - hMdEnc->spar_md_cfg.gen_bs = 1; - ivas_spar_set_bitrate_config( &hMdEnc->spar_md_cfg, table_idx, -#ifdef SBA_HOA_HBR_IMPROV - ( hMdEnc->spar_hoa_md_flag ) ? IVAS_MAX_NUM_BANDS : SPAR_DIRAC_SPLIT_START_BAND -#else - SPAR_DIRAC_SPLIT_START_BAND -#endif - ); + 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 ); /* get FB coefficients */ for ( i = 0; i < IVAS_MAX_NUM_BANDS; i++ ) @@ -339,19 +332,6 @@ static ivas_error ivas_spar_md_enc_init( } ivas_spar_set_enc_config( hMdEnc, hMdEnc->spar_md_cfg.max_freq_per_chan, hMdEnc->spar_md_cfg.nchan_transport, pFC, num_channels ); - /* - if(hMdEnc->spar_md_cfg.quant_strat[0].C.q_levels[0] == 0 || hMdEnc->spar_md_cfg.quant_strat[0].C.q_levels[1] == 0 - || hMdEnc->spar_md_cfg.quant_strat[0].PR.q_levels[0] == 0 || hMdEnc->spar_md_cfg.quant_strat[0].PR.q_levels[1] == 0 - || hMdEnc->spar_md_cfg.quant_strat[0].P_c.q_levels[0] == 0 || hMdEnc->spar_md_cfg.quant_strat[0].P_c.q_levels[1] == 0 - || hMdEnc->spar_md_cfg.quant_strat[0].P_r.q_levels[0] == 0 || hMdEnc->spar_md_cfg.quant_strat[0].P_r.q_levels[1] == 0) - { - hMdEnc->spar_md_cfg.gen_bs = 0; - } - else if(0 != hMdEnc->spar_md_cfg.gen_bs) - { - hMdEnc->spar_md_cfg.quant_strat_bits = ivas_get_bits_to_encode(MAX_QUANT_STRATS); - } -*/ if ( hMdEnc->spar_md_cfg.nchan_transport != 2 && ( ( hMdEnc->spar_md_cfg.remix_unmix_order == 1 ) || ( hMdEnc->spar_md_cfg.remix_unmix_order == 2 ) ) ) { @@ -562,35 +542,20 @@ static void write_metadata_buffer( ivas_error ivas_spar_md_enc_process( ivas_spar_md_enc_state_t *hMdEnc, /* i/o: SPAR MD encoder handle */ const ENCODER_CONFIG_HANDLE hEncoderConfig, /* i : configuration structure */ -#ifdef SBA_SPAR_HARM float *cov_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], float *cov_dtx_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], -#else - ivas_spar_md_enc_in_buf_t *pIn_buf, -#endif BSTR_ENC_HANDLE hMetaData, /* i/o: MetaData handle */ -#ifdef SBA_SPAR_HARM int16_t dtx_vad, const int16_t nchan_inp, -#else - const int16_t dtx_silence_mode, -#endif const int16_t sba_order /* i : Ambisonic (SBA) order */ ) { float pred_coeffs_re[IVAS_SPAR_MAX_CH - 1][IVAS_MAX_NUM_BANDS]; float dm_fv_re[IVAS_SPAR_MAX_CH - 1][IVAS_MAX_NUM_BANDS]; -#ifdef SBA_HOA_HBR_IMPROV float pred_coeffs_re_local[IVAS_SPAR_MAX_CH - 1][IVAS_MAX_NUM_BANDS]; -#endif int16_t i, b, qsi, ndm, ndec, num_ch, num_quant_strats; int16_t j, planarCP; -#ifdef SBA_SPAR_HARM int16_t k, bwidth, num_bands, num_bands_full, num_bands_bw; -#else - int16_t num_bands = pIn_buf->num_bands; - int16_t dtx_vad = pIn_buf->dtx_vad; -#endif int16_t active_w, nchan_transport, dmx_switch, strat; int16_t nB, bands_bw, packed_ok = 0; ivas_strats_t cs[MAX_CODING_STRATS]; @@ -605,14 +570,11 @@ ivas_error ivas_spar_md_enc_process( active_w = hMdEnc->spar_md_cfg.active_w; nchan_transport = hMdEnc->spar_md_cfg.nchan_transport; -#ifdef SBA_SPAR_HARM bwidth = ivas_get_bw_idx_from_sample_rate( hEncoderConfig->input_Fs ); bwidth = min( bwidth, hEncoderConfig->max_bwidth ); num_bands = ivas_get_num_bands_from_bw_idx( SPAR_CONFIG_BW ); -#ifdef SBA_HOA_HBR_IMPROV if ( hMdEnc->spar_hoa_md_flag == 0 ) -#endif { num_bands = min( num_bands, SPAR_DIRAC_SPLIT_START_BAND ); } @@ -626,30 +588,22 @@ ivas_error ivas_spar_md_enc_process( for ( j = 0; j < nchan_inp; j++ ) { cov_real[i][j] = cov_dtx_real[i][j]; - for ( k = num_bands_bw; k < IVAS_MAX_NUM_BANDS; k++ ) - { - cov_real[i][j][k] = 0; - } } } } - else + + for ( i = 0; i < nchan_inp; i++ ) { - for ( i = 0; i < nchan_inp; i++ ) + for ( j = 0; j < nchan_inp; j++ ) { - for ( j = 0; j < nchan_inp; j++ ) + for ( k = num_bands_bw; k < IVAS_MAX_NUM_BANDS; k++ ) { - cov_real[i][j] = cov_real[i][j]; - for ( k = num_bands_bw; k < IVAS_MAX_NUM_BANDS; k++ ) - { - cov_real[i][j][k] = 0; - } + cov_real[i][j][k] = 0; } } } -#endif - if ( hEncoderConfig->ivas_total_brate == BRATE_SPAR_Q_STRAT && sba_order == 1 ) + if ( hEncoderConfig->ivas_total_brate == BRATE_SPAR_Q_STRAT && sba_order == SBA_FOA_ORDER ) { /* make sure that qsi is always 0 (temporary bits are '00') */ num_quant_strats = 1; @@ -662,12 +616,6 @@ ivas_error ivas_spar_md_enc_process( next_ind_start = hMetaData->next_ind; last_ind_start = hMetaData->last_ind; -#ifndef SBA_SPAR_HARM - if ( hEncoderConfig->Opt_DTX_ON == 0 ) - { - dtx_vad = 1; - } -#endif dmx_switch = 0; @@ -676,11 +624,7 @@ ivas_error ivas_spar_md_enc_process( nB = SPAR_DTX_BANDS; bands_bw = num_bands / nB; -#ifdef SBA_SPAR_HARM ivas_band_mixer( cov_real, num_ch, &num_bands, bands_bw ); -#else - ivas_band_mixer( pIn_buf->cov_real, num_ch, &num_bands, bands_bw ); -#endif } else { @@ -688,7 +632,6 @@ ivas_error ivas_spar_md_enc_process( bands_bw = 1; } -#ifdef SBA_HOA_HBR_IMPROV if ( hMdEnc->spar_hoa_md_flag ) { for ( b = SPAR_DIRAC_SPLIT_START_BAND; b < num_bands; b++ ) @@ -700,15 +643,9 @@ ivas_error ivas_spar_md_enc_process( } } } -#endif -#ifdef SBA_SPAR_HARM ivas_compute_spar_params( cov_real, dm_fv_re, 0, hMdEnc->mixer_mat, 0, nB, dtx_vad, num_ch, bands_bw, active_w, &hMdEnc->spar_md_cfg, &hMdEnc->spar_md, Wscale, 0 ); -#else - ivas_compute_spar_params( pIn_buf->cov_real, dm_fv_re, 0, hMdEnc->mixer_mat, 0, nB, dtx_vad, num_ch, - bands_bw, active_w, &hMdEnc->spar_md_cfg, &hMdEnc->spar_md, Wscale, 0 ); -#endif for ( i = 0; i < num_ch; i++ ) { @@ -755,11 +692,7 @@ ivas_error ivas_spar_md_enc_process( if ( ndm != num_ch ) { -#ifdef SBA_SPAR_HARM ivas_calc_c_p_coeffs( &hMdEnc->spar_md, cov_real, 0, hMdEnc->mixer_mat_local, num_ch, ndm, b, dtx_vad, 1, planarCP ); -#else - ivas_calc_c_p_coeffs( &hMdEnc->spar_md, pIn_buf->cov_real, 0, hMdEnc->mixer_mat_local, num_ch, ndm, b, dtx_vad, 1, planarCP ); -#endif } } } @@ -838,7 +771,6 @@ ivas_error ivas_spar_md_enc_process( } } -#ifdef SBA_HOA_HBR_IMPROV if ( hMdEnc->spar_hoa_md_flag ) { for ( b = SPAR_DIRAC_SPLIT_START_BAND; b < num_bands; b++ ) @@ -852,7 +784,6 @@ ivas_error ivas_spar_md_enc_process( } } } -#endif ivas_create_fullr_dmx_mat( pred_coeffs_re, dm_fv_re, hMdEnc->mixer_mat, num_ch, 0, num_bands, active_w, &hMdEnc->spar_md_cfg ); @@ -868,11 +799,7 @@ ivas_error ivas_spar_md_enc_process( if ( ( ndm != num_ch ) && ( ndm != 1 ) ) { -#ifdef SBA_SPAR_HARM ivas_calc_c_p_coeffs( &hMdEnc->spar_md, cov_real, 0, hMdEnc->mixer_mat, num_ch, ndm, b, dtx_vad, 0, planarCP ); -#else - ivas_calc_c_p_coeffs( &hMdEnc->spar_md, pIn_buf->cov_real, 0, hMdEnc->mixer_mat, num_ch, ndm, b, dtx_vad, 0, planarCP ); -#endif #ifdef SPAR_HOA_DBG /*fprintf(stderr, "\n\n C coefficients: band %d\n", b); @@ -933,16 +860,7 @@ ivas_error ivas_spar_md_enc_process( /* band mixing */ if ( bands_bw > 1 ) { -#ifdef SBA_SPAR_HARM ivas_band_mixing( hMdEnc, num_ch, num_bands, nchan_transport, num_bands_full ); -#else - ivas_band_mixing( hMdEnc, num_ch, num_bands, nchan_transport, pIn_buf->num_bands ); -#endif - } - - if ( hMdEnc->spar_md_cfg.gen_bs == 0 ) - { - break; } if ( dtx_vad == 0 ) @@ -960,14 +878,14 @@ ivas_error ivas_spar_md_enc_process( { reset_indices_enc( &hMetaData_tmp, MAX_BITS_METADATA ); - ivas_write_spar_md_bitstream( hMdEnc, num_bands, bands_bw, &hMetaData_tmp, hEncoderConfig->ivas_total_brate, 0, strat, qsi, planarCP ); + ivas_write_spar_md_bitstream( hMdEnc, num_bands, bands_bw, &hMetaData_tmp, hEncoderConfig->ivas_total_brate, strat, qsi, planarCP ); if ( hMetaData->nb_bits_tot == bit_pos_start || hMetaData_tmp.nb_bits_tot < ( hMetaData->nb_bits_tot - bit_pos_start ) ) { write_metadata_buffer( &hMetaData_tmp, hMetaData, bit_pos_start, next_ind_start, last_ind_start ); code_strat = strat; } - if ( hMetaData->nb_bits_tot - bit_pos_start + ( ( ( hEncoderConfig->ivas_total_brate == IVAS_256k ) && ( sba_order == 1 ) ) ? 1 : 0 ) <= hMdEnc->spar_md_cfg.tgt_bits_per_blk ) + if ( hMetaData->nb_bits_tot - bit_pos_start + ( ( ( hEncoderConfig->ivas_total_brate == IVAS_256k ) && ( sba_order == SBA_FOA_ORDER ) ) ? 1 : 0 ) <= hMdEnc->spar_md_cfg.tgt_bits_per_blk ) { packed_ok = 1; break; @@ -980,7 +898,7 @@ ivas_error ivas_spar_md_enc_process( break; } - if ( hMetaData->nb_bits_tot - bit_pos_start + ( ( ( hEncoderConfig->ivas_total_brate == IVAS_256k ) && ( sba_order == 1 ) ) ? 1 : 0 ) <= hMdEnc->spar_md_cfg.max_bits_per_blk ) + if ( hMetaData->nb_bits_tot - bit_pos_start + ( ( ( hEncoderConfig->ivas_total_brate == IVAS_256k ) && ( sba_order == SBA_FOA_ORDER ) ) ? 1 : 0 ) <= hMdEnc->spar_md_cfg.max_bits_per_blk ) { break; } @@ -1158,17 +1076,14 @@ ivas_error ivas_spar_md_enc_process( } #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 == 1 ) ) ? 1 : 0 ); + 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 - if ( hMdEnc->spar_md_cfg.gen_bs == 1 ) - { - ivas_store_prior_coeffs( hMdEnc, num_bands, bands_bw, code_strat, dtx_vad, qsi ); - } + ivas_store_prior_coeffs( hMdEnc, num_bands, bands_bw, code_strat, dtx_vad, qsi ); hMdEnc->spar_md.dtx_vad = dtx_vad; hMdEnc->spar_md.num_bands = num_bands; @@ -1236,7 +1151,6 @@ static void ivas_write_spar_md_bitstream( const int16_t bands_bw, BSTR_ENC_HANDLE hMetaData, const int32_t ivas_total_brate, - const int16_t dtx_silence_mode, // VE2DB: it is always 0 -> remove it? const int16_t strat, const int16_t qsi, const int16_t planarCP ) @@ -1250,7 +1164,7 @@ static void ivas_write_spar_md_bitstream( } /* write quant strat */ - if ( dtx_silence_mode == 0 && ivas_total_brate >= BRATE_SPAR_Q_STRAT ) + if ( ivas_total_brate >= BRATE_SPAR_Q_STRAT ) { push_next_indice( hMetaData, qsi >> 1, hMdEnc->spar_md_cfg.quant_strat_bits - 1 ); } @@ -1355,7 +1269,6 @@ static void ivas_get_huffman_coded_bs( pred_coeff_dim = ndm + ndec - 1; pred_offset = 0; -#ifdef SBA_HOA_HBR_IMPROV if ( hMdEnc->spar_hoa_md_flag ) { if ( i >= SPAR_DIRAC_SPLIT_START_BAND ) @@ -1363,7 +1276,6 @@ static void ivas_get_huffman_coded_bs( pred_offset = FOA_CHANNELS - 1; } } -#endif if ( planarCP ) { @@ -1446,7 +1358,6 @@ static void ivas_get_arith_coded_bs( ndm = hMdEnc->spar_md_cfg.num_dmx_chans_per_band[bands_bw * i]; ndec = hMdEnc->spar_md_cfg.num_decorr_per_band[bands_bw * i]; pred_cell_dims[i].dim1 = ndm + ndec - 1; -#ifdef SBA_HOA_HBR_IMPROV if ( hMdEnc->spar_hoa_md_flag ) { if ( i >= SPAR_DIRAC_SPLIT_START_BAND ) @@ -1454,7 +1365,6 @@ static void ivas_get_arith_coded_bs( pred_cell_dims[i].dim1 -= ( FOA_CHANNELS - 1 ); } } -#endif pred_cell_dims[i].dim2 = 1; drct_cell_dims[i].dim1 = ndec; drct_cell_dims[i].dim2 = ndm - 1; @@ -1473,7 +1383,6 @@ static void ivas_get_arith_coded_bs( break; } } -#ifdef SBA_HOA_HBR_IMPROV if ( hMdEnc->spar_hoa_md_flag ) { int16_t j; @@ -1494,7 +1403,6 @@ static void ivas_get_arith_coded_bs( } } } -#endif ivas_copy_band_coeffs_idx_to_arr( hMdEnc->spar_md.band_coeffs_idx, nB, symbol_arr_re, pred_cell_dims, PRED_COEFF, planarCP ); if ( any_diff == 1 ) @@ -1506,7 +1414,6 @@ static void ivas_get_arith_coded_bs( ivas_arith_encode_cmplx_cell_array( &hMdEnc->arith_coeffs.pred_arith_re[qsi], &hMdEnc->arith_coeffs.pred_arith_re_diff[qsi], pDo_diff, nB, symbol_arr_re, symbol_arr_old_re, pred_cell_dims, hMetaData, any_diff ); -#ifdef SBA_HOA_HBR_IMPROV if ( hMdEnc->spar_hoa_md_flag ) { int16_t j; @@ -1526,7 +1433,6 @@ static void ivas_get_arith_coded_bs( } } } -#endif #ifdef SPAR_HOA_DBG /*fprintf(stderr, "\n\n band_indexes:\n"); diff --git a/lib_enc/ivas_stat_enc.h b/lib_enc/ivas_stat_enc.h index 531e69d85a..4ae2e2f41f 100644 --- a/lib_enc/ivas_stat_enc.h +++ b/lib_enc/ivas_stat_enc.h @@ -40,9 +40,6 @@ #include "stat_enc.h" #include "ivas_cnst.h" #include "ivas_stat_com.h" -#ifdef AGC_ENABLE_FOR_LBR -#include "lib_enc.h" -#endif /*----------------------------------------------------------------------------------* * DFT Stereo encoder structures @@ -631,17 +628,6 @@ typedef struct ivas_enc_cov_handler_state_t } ivas_enc_cov_handler_state_t; -#ifndef SBA_SPAR_HARM -typedef struct ivas_enc_cov_handler_in_buf_t -{ - float *ppIn_FR_real[IVAS_SPAR_MAX_CH]; - float *ppIn_FR_imag[IVAS_SPAR_MAX_CH]; - int16_t num_ch; - int16_t transient_det; - int16_t dtx_cov_flag; - -} ivas_enc_cov_handler_in_buf_t; -#endif /* SPAR MD structures */ typedef struct ivas_spar_md_enc_state_t @@ -659,20 +645,9 @@ typedef struct ivas_spar_md_enc_state_t ivas_arith_coeffs_t arith_coeffs; ivas_huff_coeffs_t huff_coeffs; int16_t table_idx; -#ifdef SBA_HOA_HBR_IMPROV int16_t spar_hoa_md_flag; -#endif } ivas_spar_md_enc_state_t; -#ifndef SBA_SPAR_HARM -typedef struct ivas_spar_md_enc_in_buf_t -{ - float *cov_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH]; - int16_t num_bands; - int16_t dtx_vad; - -} ivas_spar_md_enc_in_buf_t; -#endif /* PCA structure */ typedef struct { @@ -850,11 +825,9 @@ typedef struct stereo_cng_enc typedef struct sce_enc_data_structure { - int16_t sce_id; /* SCE # identifier */ - int32_t element_brate; /* SCE element total bitrate in bps */ -#ifdef CORECODER_BITRATE_SWITCHING + int16_t sce_id; /* SCE # identifier */ + int32_t element_brate; /* SCE element total bitrate in bps */ int32_t last_element_brate; /* last SCE element bitrate in bps */ -#endif BSTR_ENC_HANDLE hMetaData; /* Metadata bitstream handle */ @@ -1027,10 +1000,8 @@ typedef struct encoder_config_structure int16_t Opt_SC_VBR; /* flag indicating SC-VBR mode */ int16_t last_Opt_SC_VBR; /* flag indicating prev frame's SC-VBR mode */ -#ifdef AGC_ENABLE_FOR_LBR - IVAS_ENC_AGC Opt_AGC_ON; /* flag indicating AGC operation in SBA */ -#else /* temp. development parameters */ +#ifdef DEBUG_AGC_ENCODER_CMD_OPTION int16_t Opt_AGC_ON; /* flag indicating AGC operation in SBA */ #endif int16_t Opt_PCA_ON; /* flag indicating PCA operation in SBA */ diff --git a/lib_enc/lib_enc.c b/lib_enc/lib_enc.c index 6e674502f5..079a73922b 100755 --- a/lib_enc/lib_enc.c +++ b/lib_enc/lib_enc.c @@ -78,12 +78,13 @@ static int16_t getInputBufferSize( const Encoder_Struct *st_ivas ); static ivas_error doCommonConfigureChecks( IVAS_ENC_HANDLE hIvasEnc ); static ivas_error doCommonSetterChecks( IVAS_ENC_HANDLE hIvasEnc ); static ivas_error sanitizeBandwidth( const IVAS_ENC_HANDLE hIvasEnc ); -#ifdef ISM_BITRATE_SWITCHING static ivas_error sanitizeBitrateISM( const ENCODER_CONFIG_HANDLE hEncoderConfig ); -#endif 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 ); @@ -451,11 +452,13 @@ 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 #ifdef AGC_ENABLE_FOR_LBR const IVAS_ENC_AGC Opt_AGC_ON, /* i : AGC on/off/undefined flag */ #else const bool Opt_AGC_ON, /* i : AGC on/off flag */ -#endif +#endif /* AGC_ENABLE_FOR_LBR */ +#endif /* DEBUG_AGC_ENCODER_CMD_OPTION */ const bool Opt_PCA_ON /* i : PCA option flag */ #ifdef DEBUG_SBA_AUDIO_DUMP , @@ -477,13 +480,21 @@ ivas_error IVAS_ENC_ConfigureForAmbisonics( hEncoderConfig->element_mode_init = IVAS_SCE; /* Just needs to be something not mono, will be set later */ hEncoderConfig->sba_planar = isPlanar; hEncoderConfig->sba_order = order; + /* 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 #ifdef AGC_ENABLE_FOR_LBR - hEncoderConfig->Opt_AGC_ON = Opt_AGC_ON; + if ( ( error = agcAPIToInternal( Opt_AGC_ON, &( hEncoderConfig->Opt_AGC_ON ) ) ) != IVAS_ERR_OK ) + { + return error; + } #else hEncoderConfig->Opt_AGC_ON = (int16_t) Opt_AGC_ON; -#endif +#endif /* AGC_ENABLE_FOR_LBR */ +#endif /* DEBUG_AGC_ENCODER_CMD_OPTION */ + hEncoderConfig->Opt_PCA_ON = (int16_t) Opt_PCA_ON; hIvasEnc->maxBandwidthUser = max_bwidth_user; @@ -772,29 +783,10 @@ static ivas_error configureEncoder( } else if ( hEncoderConfig->ivas_format == ISM_FORMAT ) { -#ifdef ISM_BITRATE_SWITCHING if ( ( error = sanitizeBitrateISM( hEncoderConfig ) ) != IVAS_ERR_OK ) { return error; } -#else - if ( hEncoderConfig->ivas_total_brate > IVAS_256k ) - { - return IVAS_ERROR( IVAS_ERR_INVALID_BITRATE, "Too high bitrate for ISm specified in IVAS: %d", hEncoderConfig->ivas_total_brate ); - } - if ( hEncoderConfig->ivas_total_brate < IVAS_16k4 && hEncoderConfig->nchan_inp == 2 ) - { - return IVAS_ERROR( IVAS_ERR_INVALID_BITRATE, "Too low bitrate for 2 ISm specified in IVAS: %d", hEncoderConfig->ivas_total_brate ); - } - if ( hEncoderConfig->ivas_total_brate < IVAS_24k4 && hEncoderConfig->nchan_inp == 3 ) - { - return IVAS_ERROR( IVAS_ERR_INVALID_BITRATE, "Too low bitrate for 3 ISm specified in IVAS: %d", hEncoderConfig->ivas_total_brate ); - } - if ( hEncoderConfig->ivas_total_brate < IVAS_24k4 && hEncoderConfig->nchan_inp == 4 ) - { - return IVAS_ERROR( IVAS_ERR_INVALID_BITRATE, "Too low bitrate for 4 ISm specified in IVAS: %d", hEncoderConfig->ivas_total_brate ); - } -#endif } else if ( hEncoderConfig->ivas_format == SBA_FORMAT ) { @@ -897,16 +889,19 @@ 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 #ifdef AGC_ENABLE_FOR_LBR - if ( hEncoderConfig->Opt_AGC_ON == IVAS_ENC_AGC_ENABLED && !( hEncoderConfig->ivas_format == SBA_FORMAT && ivas_sba_mode_select( hEncoderConfig->ivas_total_brate ) == SBA_MODE_SPAR ) ) + if ( hEncoderConfig->Opt_AGC_ON == SBA_AGC_FORCE_ENABLE && !( hEncoderConfig->ivas_format == SBA_FORMAT && ivas_sba_mode_select( hEncoderConfig->ivas_total_brate ) == SBA_MODE_SPAR ) ) #else if ( hEncoderConfig->Opt_AGC_ON && !( hEncoderConfig->ivas_format == SBA_FORMAT && ivas_sba_mode_select( hEncoderConfig->ivas_total_brate ) == SBA_MODE_SPAR ) ) -#endif +#endif /* AGC_ENABLE_FOR_LBR */ { return IVAS_ERROR( IVAS_ERR_NOT_SUPPORTED_OPTION, "AGC supported in SBA format at bitrates >= 24.4 kbps only." ); } +#endif /* DEBUG_AGC_ENCODER_CMD_OPTION */ + - if ( hEncoderConfig->Opt_PCA_ON && !( hEncoderConfig->ivas_format == SBA_FORMAT && hEncoderConfig->ivas_total_brate == PCA_BRATE && hEncoderConfig->sba_order == 1 ) ) + if ( hEncoderConfig->Opt_PCA_ON && !( hEncoderConfig->ivas_format == SBA_FORMAT && hEncoderConfig->ivas_total_brate == PCA_BRATE && hEncoderConfig->sba_order == SBA_FOA_ORDER ) ) { return IVAS_ERROR( IVAS_ERR_NOT_SUPPORTED_OPTION, "PCA supported at SBA FOA 256 kbps only." ); } @@ -1514,7 +1509,7 @@ static ivas_error printConfigInfo_enc( else if ( hEncoderConfig->ivas_format == SBA_FORMAT ) { #ifdef PRINT_SBA_ORDER - fprintf( stdout, "IVAS format: Scene Based Analysis, Ambisonic order %i %s ", hEncoderConfig->sba_order, hEncoderConfig->sba_planar ? "(Planar)" : "" ); + fprintf( stdout, "IVAS format: Scene Based Audio, Ambisonic order %i %s ", hEncoderConfig->sba_order, hEncoderConfig->sba_planar ? "(Planar)" : "" ); #else fprintf( stdout, "IVAS format: Scene Based Analysis %s ", hEncoderConfig->sba_planar ? "(Planar)" : "" ); #endif @@ -1522,16 +1517,17 @@ static ivas_error printConfigInfo_enc( { fprintf( stdout, "- PCA configured with signal adaptive decision " ); } +#ifdef DEBUG_AGC_ENCODER_CMD_OPTION #ifdef AGC_ENABLE_FOR_LBR switch ( hEncoderConfig->Opt_AGC_ON ) { - case IVAS_ENC_AGC_ENABLED: + case SBA_AGC_FORCE_ENABLE: fprintf( stdout, "- AGC FORCED ON " ); break; - case IVAS_ENC_AGC_DISABLED: + case SBA_AGC_FORCE_DISABLE: fprintf( stdout, "- AGC FORCED OFF " ); break; - case IVAS_ENC_AGC_UNDEFINED: + case SBA_AGC_DEFAULT: fprintf( stdout, "- AGC default mode " ); break; default: @@ -1543,7 +1539,10 @@ static ivas_error printConfigInfo_enc( { fprintf( stdout, "- AGC ON " ); } -#endif +#endif /* AGC_ENABLE_FOR_LBR */ +#else + fprintf( stdout, "- AGC default mode " ); +#endif /* DEBUG_AGC_ENCODER_CMD_OPTION */ fprintf( stdout, "\n" ); } else if ( hEncoderConfig->ivas_format == MASA_FORMAT ) @@ -1669,9 +1668,7 @@ static ivas_error setBitrate( { Encoder_Struct *st_ivas; ENCODER_CONFIG_HANDLE hEncoderConfig; -#ifdef ISM_BITRATE_SWITCHING ivas_error error; -#endif st_ivas = hIvasEnc->st_ivas; hEncoderConfig = st_ivas->hEncoderConfig; @@ -1718,7 +1715,6 @@ static ivas_error setBitrate( } } -#ifdef ISM_BITRATE_SWITCHING if ( hEncoderConfig->ivas_format == ISM_FORMAT ) { if ( ( error = sanitizeBitrateISM( hEncoderConfig ) ) != IVAS_ERR_OK ) @@ -1726,7 +1722,6 @@ static ivas_error setBitrate( return error; } } -#endif st_ivas->codec_mode = MODE1; @@ -1954,7 +1949,6 @@ static ivas_error sanitizeBandwidth( } -#ifdef ISM_BITRATE_SWITCHING /*---------------------------------------------------------------------* * sanitizeBitrateISM() * @@ -1986,7 +1980,6 @@ static ivas_error sanitizeBitrateISM( return IVAS_ERR_OK; } -#endif /*---------------------------------------------------------------------* @@ -2082,6 +2075,31 @@ static ivas_error bandwidthApiToInternal( return IVAS_ERR_OK; } +#ifdef DEBUG_AGC_ENCODER_CMD_OPTION +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 + /*---------------------------------------------------------------------* * fecIndicatorApiToInternal() @@ -2216,11 +2234,13 @@ static void init_encoder_config( hEncoderConfig->stereo_dmx_evs = 0; hEncoderConfig->sba_order = 0; hEncoderConfig->sba_planar = 0; +#ifdef DEBUG_AGC_ENCODER_CMD_OPTION #ifdef AGC_ENABLE_FOR_LBR - hEncoderConfig->Opt_AGC_ON = IVAS_ENC_AGC_UNDEFINED; + hEncoderConfig->Opt_AGC_ON = SBA_AGC_DEFAULT; #else hEncoderConfig->Opt_AGC_ON = 0; -#endif +#endif /* AGC_ENABLE_FOR_LBR */ +#endif /* DEBUG_AGC_ENCODER_CMD_OPTION */ hEncoderConfig->Opt_PCA_ON = 0; return; diff --git a/lib_enc/lib_enc.h b/lib_enc/lib_enc.h index 20eef7b1fe..373da97f96 100644 --- a/lib_enc/lib_enc.h +++ b/lib_enc/lib_enc.h @@ -124,13 +124,15 @@ typedef enum _IVAS_ENC_FORCED_MODE #endif #ifdef AGC_ENABLE_FOR_LBR +#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 /* DEBUG_AGC_ENCODER_CMD_OPTION */ +#endif /* AGC_ENABLE_FOR_LBR */ /*---------------------------------------------------------------------* * Encoder structures @@ -197,11 +199,13 @@ 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 #ifdef AGC_ENABLE_FOR_LBR const IVAS_ENC_AGC Opt_AGC_ON, /* i : AGC on/off/undefined flag */ #else const bool Opt_AGC_ON, /* i : AGC on/off flag */ -#endif +#endif /* AGC_ENABLE_FOR_LBR */ +#endif /* DEBUG_AGC_ENCODER_CMD_OPTION */ const bool Opt_PCA_ON /* i : PCA option flag */ #ifdef DEBUG_SBA_AUDIO_DUMP , diff --git a/lib_rend/ivas_allrad_dec.c b/lib_rend/ivas_allrad_dec.c index 119b89b2cc..a61f543cb1 100644 --- a/lib_rend/ivas_allrad_dec.c +++ b/lib_rend/ivas_allrad_dec.c @@ -108,11 +108,7 @@ ivas_error ivas_sba_get_hoa_dec_matrix( /* Allocate memory */ assert( *hoa_dec_mtx == NULL && "hoa_dec_mtx != NULL" ); -#ifdef ALLRAD_OPTIM if ( ( *hoa_dec_mtx = (float *) count_malloc( SBA_NHARM_HOA3 * ( hOutSetup.nchan_out_woLFE ) * sizeof( float ) ) ) == NULL ) -#else - if ( ( *hoa_dec_mtx = (float *) count_malloc( SBA_NHARM_HOA3 * MAX_OUTPUT_CHANNELS * sizeof( float ) ) ) == NULL ) -#endif { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "ALLRAD: Cannot allocate memory!" ) ); } diff --git a/lib_rend/ivas_crend.c b/lib_rend/ivas_crend.c index ae910b1f25..698612b1ad 100644 --- a/lib_rend/ivas_crend.c +++ b/lib_rend/ivas_crend.c @@ -1146,10 +1146,10 @@ ivas_error ivas_crend_process( ivas_error ivas_rend_openCrend( CREND_WRAPPER *pCrend, - IVAS_REND_AudioConfig inConfig, - IVAS_REND_AudioConfig outConfig, + const IVAS_REND_AudioConfig inConfig, + const IVAS_REND_AudioConfig outConfig, RENDER_CONFIG_DATA *hRendCfg, - int32_t output_Fs ) + const int32_t output_Fs ) { /* TODO tmu : Based on ivas_crend_open() - could be harmonized / refactored */ int16_t i, subframe_length; @@ -1309,13 +1309,13 @@ ivas_error ivas_rend_openCrend( ivas_error ivas_rend_initCrend( CREND_WRAPPER *pCrend, - IVAS_REND_AudioConfig inConfig, - IVAS_REND_AudioConfig outConfig, + const IVAS_REND_AudioConfig inConfig, + const IVAS_REND_AudioConfig outConfig, RENDER_CONFIG_DATA *hRendCfg, - int32_t output_Fs ) + const int32_t output_Fs ) { int16_t i, j, tmp; - int32_t nchan_in; + int16_t nchan_in; bool use_brir; IVAS_REND_AudioConfigType inConfigType; HRTFS_HANDLE hHrtf; @@ -1353,7 +1353,7 @@ ivas_error ivas_rend_initCrend( { return error; } - hHrtf->max_num_ir = (int16_t) nchan_in; + hHrtf->max_num_ir = nchan_in; if ( hHrtf->max_num_ir <= 0 ) { @@ -1764,26 +1764,26 @@ ivas_error ivas_rend_closeCrend( } /*-----------------------------------------------------------------------------------------* - * Function ivas_rend_crend_process() + * Function ivas_rend_crend_Process() * * Process call for IVAS Crend renderer *-----------------------------------------------------------------------------------------*/ ivas_error ivas_rend_crendProcess( const CREND_WRAPPER *pCrend, - IVAS_REND_AudioConfig inConfig, - IVAS_REND_AudioConfig outConfig, + const IVAS_REND_AudioConfig inConfig, + const IVAS_REND_AudioConfig outConfig, float output[][L_FRAME48k], /* i/o: input/output audio channels */ - int32_t output_Fs ) + const int32_t output_Fs ) { int16_t i, subframe_idx, output_frame; - int32_t nchan_out; + int16_t nchan_out; float pcm_tmp[BINAURAL_CHANNELS][L_FRAME48k]; AUDIO_CONFIG in_config; IVAS_REND_AudioConfigType inConfigType; ivas_error error; - wmops_sub_start( "ivas_crend_process" ); + wmops_sub_start( "ivas_rend_crendProcess" ); in_config = getIvasAudioConfigFromRendAudioConfig( inConfig ); inConfigType = getAudioConfigType( inConfig ); @@ -1819,6 +1819,8 @@ ivas_error ivas_rend_crendProcess( mvr2r( pcm_tmp[i], output[i], output_frame ); } + wmops_sub_end(); + return IVAS_ERR_OK; } @@ -1834,19 +1836,17 @@ ivas_error ivas_rend_crendConvolver( IVAS_REND_AudioConfig outConfig, float pcm_in[][L_FRAME48k], float pcm_out[][L_FRAME48k], - int32_t output_Fs, + const int32_t output_Fs, const int16_t i_ts ) { int16_t i, j, k, m; int16_t subframe_length, idx_in; int16_t lfe_idx_in; int16_t offset, offset_in, offset_diffuse; - int32_t nchan_in, nchan_out; + int16_t nchan_in, nchan_out; float *pIn; - float *pFreq_buf_re; - float *pFreq_buf_im; - float *pFreq_filt_re; - float *pFreq_filt_im; + float *pFreq_buf_re, *pFreq_buf_im; + float *pFreq_filt_re, *pFreq_filt_im; float pOut[L_FRAME48k * 2]; float tmp_out_re[L_FRAME48k], tmp_out_im[L_FRAME48k]; diff --git a/lib_rend/ivas_efap.c b/lib_rend/ivas_efap.c index 1c58e0a25e..8a3dd6ad05 100644 --- a/lib_rend/ivas_efap.c +++ b/lib_rend/ivas_efap.c @@ -100,9 +100,7 @@ static float vertex_distance( const EFAP_VERTEX *vtxArray, const EFAP_LS_TRIANGL static float point_plane_distance( const float P1[3], const float P2[3], const float P3[3], const float X[3] ); -#ifdef EFAP_FIX_POLY static float point_poly_distance( const EFAP_POLYSET poly, const float X[3] ); -#endif static void efap_crossp( const float *v1, const float *v2, float *v ); static int16_t find_int_in_tri( const EFAP_LS_TRIANGLE *tri, const int16_t n, const int16_t r, int16_t *pos ); @@ -127,9 +125,7 @@ static int16_t in_poly( const float P[2], const EFAP_POLYSET poly ); static int16_t in_tri( float A[2], float B[2], float C[2], float P_minus_A[2] ); -#ifdef EFAP_FIX_POLY static void sph2cart( const float azi, const float ele, float *pos ); -#endif /*-----------------------------------------------------------------------* * Global function definitions @@ -1506,13 +1502,7 @@ static void add_vertex( vtxArray[pos].ele = ( ( -180.0f > tmp ) ? -180.0f : tmp ); /* Converting spherical coordinates to cartesians, assuming radius = 1 */ -#ifdef EFAP_FIX_POLY sph2cart( vtxArray[pos].azi, vtxArray[pos].ele, &vtxArray[pos].pos[0] ); -#else - vtxArray[pos].pos[0] = cosf( vtxArray[pos].azi * PI_OVER_180 ) * cosf( vtxArray[pos].ele * PI_OVER_180 ); - vtxArray[pos].pos[1] = sinf( vtxArray[pos].azi * PI_OVER_180 ) * cosf( vtxArray[pos].ele * PI_OVER_180 ); - vtxArray[pos].pos[2] = sinf( vtxArray[pos].ele * PI_OVER_180 ); -#endif /* Computing the index defined by idx = idxAziTmp + 181 * idxEleTmp */ @@ -1604,7 +1594,6 @@ static float vertex_distance( return point_plane_distance( A, B, C, P ); } -#ifdef EFAP_FIX_POLY /*-------------------------------------------------------------------------* * point_poly_distance() * @@ -1624,7 +1613,6 @@ static float point_poly_distance( return point_plane_distance( P1, P2, P3, X ); } -#endif /*-------------------------------------------------------------------------* * point_plane_distance() @@ -2116,7 +2104,6 @@ static int16_t get_poly_num( ) { int16_t i; -#ifdef EFAP_FIX_POLY int16_t num_poly, found_poly; int16_t poly_tmp[EFAP_MAX_CHAN_NUM]; float poly_dist[EFAP_MAX_CHAN_NUM]; @@ -2129,12 +2116,10 @@ static int16_t get_poly_num( sph2cart( P[0], P[1], &pos[0] ); /* Filter the polygon list with a fast 2d check */ -#endif for ( i = 0; i < polyData->numPoly; ++i ) { if ( in_poly( P, polyData->polysetArray[i] ) ) { -#ifdef EFAP_FIX_POLY /* select only polygons which are visible from the point */ dist_tmp = point_poly_distance( polyData->polysetArray[i], pos ); if ( dist_tmp == 0 ) @@ -2147,12 +2132,8 @@ static int16_t get_poly_num( poly_dist[num_poly] = dist_tmp; num_poly++; } -#else - return i; -#endif } } -#ifdef EFAP_FIX_POLY if ( num_poly == 0 ) { return -1; @@ -2171,9 +2152,6 @@ static int16_t get_poly_num( } return found_poly; -#else - return -1; -#endif } diff --git a/lib_rend/ivas_lib_rend_internal.h b/lib_rend/ivas_lib_rend_internal.h index 773b75309b..94a762c315 100644 --- a/lib_rend/ivas_lib_rend_internal.h +++ b/lib_rend/ivas_lib_rend_internal.h @@ -60,46 +60,46 @@ typedef struct } CREND_WRAPPER; IVAS_REND_AudioConfigType getAudioConfigType( - IVAS_REND_AudioConfig config ); + const IVAS_REND_AudioConfig config ); ivas_error getAudioConfigNumChannels( - IVAS_REND_AudioConfig config, - int32_t *numChannels ); + const IVAS_REND_AudioConfig config, + int16_t *numChannels ); AUDIO_CONFIG getIvasAudioConfigFromRendAudioConfig( IVAS_REND_AudioConfig config ); ivas_error ivas_rend_openCrend( CREND_WRAPPER *pCrend, - IVAS_REND_AudioConfig inConfig, - IVAS_REND_AudioConfig outConfig, - RENDER_CONFIG_DATA *hRend, - int32_t output_Fs ); + const IVAS_REND_AudioConfig inConfig, + const IVAS_REND_AudioConfig outConfig, + RENDER_CONFIG_DATA *hRendCfg, + const int32_t output_Fs ); ivas_error ivas_rend_initCrend( CREND_WRAPPER *pCrend, - IVAS_REND_AudioConfig inConfig, - IVAS_REND_AudioConfig outConfig, - RENDER_CONFIG_DATA *hRend, - int32_t output_Fs ); + const IVAS_REND_AudioConfig inConfig, + const IVAS_REND_AudioConfig outConfig, + RENDER_CONFIG_DATA *hRendCfg, + const int32_t output_Fs ); ivas_error ivas_rend_closeCrend( CREND_WRAPPER *pCrend ); ivas_error ivas_rend_crendProcess( const CREND_WRAPPER *pCrend, - IVAS_REND_AudioConfig inConfig, - IVAS_REND_AudioConfig outConfig, + const IVAS_REND_AudioConfig inConfig, + const IVAS_REND_AudioConfig outConfig, float output[][L_FRAME48k], /* i/o: input/output audio channels */ - int32_t output_Fs ); + const int32_t output_Fs ); ivas_error ivas_rend_crendConvolver( const CREND_WRAPPER *pCrend, - IVAS_REND_AudioConfig inConfig, - IVAS_REND_AudioConfig outConfig, + const IVAS_REND_AudioConfig inConfig, + const IVAS_REND_AudioConfig outConfig, float pcm_in[][L_FRAME48k], float pcm_out[][L_FRAME48k], - int32_t output_Fs, + const int32_t output_Fs, const int16_t i_ts ); ivas_error ivas_rend_TDObjRenderFrame( @@ -115,9 +115,9 @@ ivas_error ivas_rend_TDObjRenderFrame( ivas_error ivas_rend_TDObjRendOpen( TDREND_WRAPPER *pTDRend, - IVAS_REND_AudioConfig inConfig, + const IVAS_REND_AudioConfig inConfig, LSSETUP_CUSTOM_STRUCT *customLsInput, - int32_t outFs ); + const int32_t output_Fs ); #endif #endif diff --git a/lib_rend/ivas_limiter.c b/lib_rend/ivas_limiter.c index 25fad180b9..a4dffb180d 100644 --- a/lib_rend/ivas_limiter.c +++ b/lib_rend/ivas_limiter.c @@ -29,7 +29,7 @@ the United Nations Convention on Contracts on the International Sales of Goods. *******************************************************************************************************/ - +// VE2AT: keep in lib_rend or move to lib_dec ? #include #include #include diff --git a/lib_rend/ivas_objectRenderer.c b/lib_rend/ivas_objectRenderer.c index e4f0706193..7bd892cdac 100644 --- a/lib_rend/ivas_objectRenderer.c +++ b/lib_rend/ivas_objectRenderer.c @@ -51,7 +51,9 @@ *---------------------------------------------------------------------*/ static ivas_error TDREND_GetMix( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, float output[][L_FRAME48k], const int16_t subframe_length, const int32_t output_Fs, const int16_t subframe_idx ); + static void TDREND_Clear_Update_flags( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd ); + static void TDREND_Update_listener_orientation( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd, const int16_t headRotEnabled, #ifdef EXT_RENDERER @@ -269,9 +271,7 @@ void ObjRenderIVASFrame( for ( subframe_idx = 0; subframe_idx < MAX_PARAM_SPATIAL_SUBFRAMES; subframe_idx++ ) { /* Update the listener's location/orientation */ - TDREND_Update_listener_orientation( st_ivas->hBinRendererTd, - st_ivas->hDecoderConfig->Opt_Headrotation, - ( st_ivas->hHeadTrackData != NULL ) ? &st_ivas->hHeadTrackData->Quaternions[subframe_idx] : NULL ); + TDREND_Update_listener_orientation( st_ivas->hBinRendererTd, st_ivas->hDecoderConfig->Opt_Headrotation, ( st_ivas->hHeadTrackData != NULL ) ? &st_ivas->hHeadTrackData->Quaternions[subframe_idx] : NULL ); if ( ( st_ivas->hRenderConfig != NULL ) && ( st_ivas->hRenderConfig->roomAcoustics.late_reverb_on ) ) { @@ -512,7 +512,7 @@ ivas_error ivas_rend_TDObjRendOpen( TDREND_WRAPPER *pTDRend, IVAS_REND_AudioConfig inConfig, LSSETUP_CUSTOM_STRUCT *customLsInput, - int32_t outFs ) + const int32_t outFs ) { /* TODO tmu : Based on ivas_td_binaural_open() - could be harmonized / refactored - review error handling @@ -526,7 +526,7 @@ ivas_error ivas_rend_TDObjRendOpen( float Pos[3]; float Dir[3]; TDREND_DirAtten_t *DirAtten_p; - int32_t nchan_rend; + int16_t nchan_rend; ivas_error error; error = IVAS_ERR_OK; @@ -645,7 +645,6 @@ ivas_error ivas_rend_TDObjRendOpen( pTDRend->binaural_latency_ns = (int32_t) ( BINAURAL_TD_LATENCY_S * 1000000000.f ); - return IVAS_ERR_OK; } @@ -672,12 +671,14 @@ ivas_error ivas_rend_TDObjRenderFrame( int16_t subframe_idx; ISM_METADATA_HANDLE hIsmMetaData[1]; int16_t lfe_idx; - int32_t num_src; + int16_t num_src; /* TODO tmu : pass down renderer config struct */ // float reverb_signal[BINAURAL_CHANNELS][L_FRAME48k]; IVAS_FORMAT ivas_format; IVAS_REND_AudioConfigType inConfigType; + wmops_sub_start( "ivas_rend_TDObjRenderFrame" ); + inConfigType = getAudioConfigType( inConfig ); lfe_idx = LFE_CHANNEL; if ( inConfigType == IVAS_REND_AUDIO_CONFIG_TYPE_CHANNEL_BASED ) @@ -714,12 +715,7 @@ ivas_error ivas_rend_TDObjRenderFrame( // } /* Update object position(s) */ - TDREND_Update_object_positions( pTDRend->hBinRendererTd, - (int16_t) num_src, - lfe_idx, - ivas_format, - hIsmMetaData, - output ); + TDREND_Update_object_positions( pTDRend->hBinRendererTd, num_src, lfe_idx, ivas_format, hIsmMetaData, output ); /* TODO tmu : needs a refactor / better approach */ if ( ivas_format == ISM_FORMAT ) @@ -730,9 +726,7 @@ ivas_error ivas_rend_TDObjRenderFrame( for ( subframe_idx = 0; subframe_idx < MAX_PARAM_SPATIAL_SUBFRAMES; subframe_idx++ ) { /* Update the listener's location/orientation */ - TDREND_Update_listener_orientation( pTDRend->hBinRendererTd, - headRotData->headRotEnabled, - ( headRotData != NULL ) ? &headRotData->headPositions[subframe_idx] : NULL ); + TDREND_Update_listener_orientation( pTDRend->hBinRendererTd, headRotData->headRotEnabled, ( headRotData != NULL ) ? &headRotData->headPositions[subframe_idx] : NULL ); /* TODO tmu : pass down renderer config struct */ // if ( ( hRenderConfig != NULL ) && ( hRenderConfig->roomAcoustics.late_reverb_on ) ) @@ -754,6 +748,9 @@ ivas_error ivas_rend_TDObjRenderFrame( // v_add( reverb_signal[1], output[1], output[1], output_frame ); // } // } + + wmops_sub_end(); + return IVAS_ERR_OK; } #endif diff --git a/lib_rend/ivas_output_init.c b/lib_rend/ivas_output_init.c index 307b29e74a..2cbd476ac1 100644 --- a/lib_rend/ivas_output_init.c +++ b/lib_rend/ivas_output_init.c @@ -29,7 +29,7 @@ the United Nations Convention on Contracts on the International Sales of Goods. *******************************************************************************************************/ - +// VE2AT: keep in lib_rend or move to lib_dec ? #include #include #include "options.h" @@ -171,13 +171,13 @@ void ivas_output_init( hOutSetup->ls_elevation = ls_elevation_CICP2; break; case AUDIO_CONFIG_FOA: - hOutSetup->ambisonics_order = 1; + hOutSetup->ambisonics_order = SBA_FOA_ORDER; break; case AUDIO_CONFIG_HOA2: - hOutSetup->ambisonics_order = 2; + hOutSetup->ambisonics_order = SBA_HOA2_ORDER; break; case AUDIO_CONFIG_HOA3: - hOutSetup->ambisonics_order = 3; + hOutSetup->ambisonics_order = SBA_HOA3_ORDER; break; case AUDIO_CONFIG_5_1: hOutSetup->num_lfe = 1; @@ -515,6 +515,12 @@ void ivas_renderer_select( { *internal_config = output_config; } +#ifdef SPAR_STEREO_NO_DIRAC + else if ( output_config == AUDIO_CONFIG_MONO || output_config == AUDIO_CONFIG_STEREO ) + { + *internal_config = AUDIO_CONFIG_FOA; + } +#endif else { *internal_config = AUDIO_CONFIG_HOA3; diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index 9366003b08..87babcdb47 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -152,22 +152,16 @@ struct IVAS_REND IVAS_REND_AudioConfig outputConfig; EFAP_WRAPPER efapOutWrapper; IVAS_LSSETUP_CUSTOM_STRUCT customLsOut; - - int8_t enableHeadRotation; /* head rotation flag */ + + int8_t enableHeadRotation; IVAS_REND_HeadRotData headRotData; int8_t rendererConfigEnabled; RENDER_CONFIG_DATA *hRendererConfig; /* Renderer config pointer */ }; -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 */ -); - -static IVAS_QUATERNION quaternionInit( void ) +static IVAS_QUATERNION quaternionInit( + void ) { IVAS_QUATERNION q; q.w = 1.0f; @@ -175,12 +169,17 @@ static IVAS_QUATERNION quaternionInit( void ) return q; } -static float *getSmplPtr( IVAS_REND_AudioBuffer buffer, uint32_t chnlIdx, uint32_t smplIdx ) +static float *getSmplPtr( + IVAS_REND_AudioBuffer buffer, + uint32_t chnlIdx, + uint32_t smplIdx ) { return buffer.data + chnlIdx * buffer.config.numSamplesPerChannel + smplIdx; } -static void copyBufferTo2dArray( const IVAS_REND_AudioBuffer buffer, float array[MAX_OUTPUT_CHANNELS][L_FRAME48k] ) +static void copyBufferTo2dArray( + const IVAS_REND_AudioBuffer buffer, + float array[MAX_OUTPUT_CHANNELS][L_FRAME48k] ) { uint32_t smplIdx; uint32_t chnlIdx; @@ -195,11 +194,15 @@ static void copyBufferTo2dArray( const IVAS_REND_AudioBuffer buffer, float array array[chnlIdx][smplIdx] = *readPtr++; } } + + return; } -static void accumulate2dArrayToBuffer( float array[MAX_OUTPUT_CHANNELS][L_FRAME48k], IVAS_REND_AudioBuffer *buffer ) +static void accumulate2dArrayToBuffer( + float array[MAX_OUTPUT_CHANNELS][L_FRAME48k], + IVAS_REND_AudioBuffer *buffer ) { - int32_t smplIdx, chnlIdx; + int16_t smplIdx, chnlIdx; float *writePtr; writePtr = buffer->data; @@ -210,6 +213,8 @@ static void accumulate2dArrayToBuffer( float array[MAX_OUTPUT_CHANNELS][L_FRAME4 *writePtr++ += array[chnlIdx][smplIdx]; } } + + return; } /*-------------------------------------------------------------------* @@ -217,8 +222,10 @@ static void accumulate2dArrayToBuffer( float array[MAX_OUTPUT_CHANNELS][L_FRAME4 * * In-place saturation control for multichannel buffers with adaptive release time * - * r: number of clipped output samples + * *-------------------------------------------------------------------*/ + +/*! 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 */ @@ -263,7 +270,8 @@ static int32_t limitRendererOutput( return numClipping; } -static AUDIO_CONFIG rendAudioConfigToIvasAudioConfig( IVAS_REND_AudioConfig rendConfig ) +static AUDIO_CONFIG rendAudioConfigToIvasAudioConfig( // VE2AT: similar is defined again at line 397, why? + IVAS_REND_AudioConfig rendConfig ) { switch ( rendConfig ) { @@ -306,7 +314,8 @@ static AUDIO_CONFIG rendAudioConfigToIvasAudioConfig( IVAS_REND_AudioConfig rend return AUDIO_CONFIG_INVALID; } -static ivas_error validateOutputAudioConfig( IVAS_REND_AudioConfig outConfig ) +static ivas_error validateOutputAudioConfig( + IVAS_REND_AudioConfig outConfig ) { switch ( outConfig ) { @@ -331,13 +340,16 @@ static ivas_error validateOutputAudioConfig( IVAS_REND_AudioConfig outConfig ) return IVAS_ERR_INVALID_OUTPUT_FORMAT; } -IVAS_REND_AudioConfigType getAudioConfigType( IVAS_REND_AudioConfig config ) +IVAS_REND_AudioConfigType getAudioConfigType( + IVAS_REND_AudioConfig config ) { /* By definition, config type is the second byte (from LSB) of IVAS_REND_AudioConfig enum. */ - return ( config & 0xFF00 ) >> 8; + return ( config & 0xFF00 ) >> 8; // VE2AT: MSVC returns warning C4244: 'return': conversion from 'int' to 'IVAS_REND_InputId', possible loss of data } -static ivas_error validateOutputSampleRate( int32_t sampleRate, IVAS_REND_AudioConfig outConfig ) +static ivas_error validateOutputSampleRate( + const int32_t sampleRate, + const IVAS_REND_AudioConfig outConfig ) { if ( getAudioConfigType( outConfig ) != IVAS_REND_AUDIO_CONFIG_TYPE_BINAURAL ) { @@ -358,7 +370,9 @@ static ivas_error validateOutputSampleRate( int32_t sampleRate, IVAS_REND_AudioC return IVAS_ERR_INVALID_SAMPLING_RATE; } -ivas_error getAudioConfigNumChannels( IVAS_REND_AudioConfig config, int32_t *numChannels ) +ivas_error getAudioConfigNumChannels( + const IVAS_REND_AudioConfig config, + int16_t *numChannels ) { switch ( config ) { @@ -400,7 +414,8 @@ ivas_error getAudioConfigNumChannels( IVAS_REND_AudioConfig config, int32_t *num return IVAS_ERR_OK; } -AUDIO_CONFIG getIvasAudioConfigFromRendAudioConfig( IVAS_REND_AudioConfig config ) +AUDIO_CONFIG getIvasAudioConfigFromRendAudioConfig( + IVAS_REND_AudioConfig config ) { switch ( config ) { @@ -433,7 +448,10 @@ AUDIO_CONFIG getIvasAudioConfigFromRendAudioConfig( IVAS_REND_AudioConfig config } } -static ivas_error initLimiter( IVAS_LIMITER_HANDLE *phLimiter, int32_t numChannels, int32_t sampleRate ) +static ivas_error initLimiter( + IVAS_LIMITER_HANDLE *phLimiter, + const int16_t numChannels, + const int32_t sampleRate ) { /* If re-initializing with unchanged values, return early */ if ( *phLimiter != NULL && @@ -458,7 +476,8 @@ static ivas_error initLimiter( IVAS_LIMITER_HANDLE *phLimiter, int32_t numChanne return IVAS_ERR_OK; } -static LSSETUP_CUSTOM_STRUCT defaultCustomLs( void ) +static LSSETUP_CUSTOM_STRUCT defaultCustomLs( + void ) { LSSETUP_CUSTOM_STRUCT ls; @@ -476,7 +495,9 @@ static LSSETUP_CUSTOM_STRUCT defaultCustomLs( void ) return ls; } -static ivas_error getSpeakerAzimuths( IVAS_REND_AudioConfig config, const float **azimuths ) +static ivas_error getSpeakerAzimuths( + IVAS_REND_AudioConfig config, + const float **azimuths ) { switch ( config ) { @@ -508,7 +529,9 @@ static ivas_error getSpeakerAzimuths( IVAS_REND_AudioConfig config, const float return IVAS_ERR_OK; } -static ivas_error getSpeakerElevations( IVAS_REND_AudioConfig config, const float **elevations ) +static ivas_error getSpeakerElevations( + IVAS_REND_AudioConfig config, + const float **elevations ) { switch ( config ) { @@ -540,7 +563,9 @@ static ivas_error getSpeakerElevations( IVAS_REND_AudioConfig config, const floa return IVAS_ERR_OK; } -static ivas_error getAmbisonicsOrder( IVAS_REND_AudioConfig config, int16_t *order ) +static ivas_error getAmbisonicsOrder( + IVAS_REND_AudioConfig config, + int16_t *order ) { switch ( config ) { @@ -560,7 +585,9 @@ static ivas_error getAmbisonicsOrder( IVAS_REND_AudioConfig config, int16_t *ord return IVAS_ERR_OK; } -static ivas_error getNumNonLfeChannelsInSpeakerLayout( IVAS_REND_AudioConfig config, int16_t *numNonLfeChannels ) +static ivas_error getNumNonLfeChannelsInSpeakerLayout( + IVAS_REND_AudioConfig config, + int16_t *numNonLfeChannels ) { switch ( config ) { @@ -595,8 +622,8 @@ static ivas_error getMcConfigValues( LSSETUP_CUSTOM_STRUCT inCustomLs, const float **azimuth, const float **elevation, - int32_t *lfe_idx, - int32_t *is_planar ) + int16_t *lfe_idx, + int16_t *is_planar ) { int16_t i; @@ -643,7 +670,10 @@ static ivas_error getMcConfigValues( return IVAS_ERR_OK; } -static ivas_error initEfap( EFAP_WRAPPER *pEfapWrapper, IVAS_REND_AudioConfig outConfig, const LSSETUP_CUSTOM_STRUCT *pCustomLsOut ) +static ivas_error initEfap( + EFAP_WRAPPER *pEfapWrapper, + IVAS_REND_AudioConfig outConfig, + const LSSETUP_CUSTOM_STRUCT *pCustomLsOut ) { ivas_error error; const float *azimuths; @@ -675,11 +705,7 @@ static ivas_error initEfap( EFAP_WRAPPER *pEfapWrapper, IVAS_REND_AudioConfig ou if ( outConfig == IVAS_REND_AUDIO_CONFIG_LS_CUSTOM ) { - if ( ( error = efap_init_data( &pEfapWrapper->hEfap, - pCustomLsOut->ls_azimuth, - pCustomLsOut->ls_elevation, - pCustomLsOut->num_spk, - EFAP_MODE_EFAP ) ) != IVAS_ERR_OK ) + if ( ( error = efap_init_data( &pEfapWrapper->hEfap, pCustomLsOut->ls_azimuth, pCustomLsOut->ls_elevation, pCustomLsOut->num_spk, EFAP_MODE_EFAP ) ) != IVAS_ERR_OK ) { return error; } @@ -698,11 +724,7 @@ static ivas_error initEfap( EFAP_WRAPPER *pEfapWrapper, IVAS_REND_AudioConfig ou { return error; } - if ( ( error = efap_init_data( &pEfapWrapper->hEfap, - azimuths, - elevations, - numNonLfeChannels, - EFAP_MODE_EFAP ) ) != IVAS_ERR_OK ) + if ( ( error = efap_init_data( &pEfapWrapper->hEfap, azimuths, elevations, numNonLfeChannels, EFAP_MODE_EFAP ) ) != IVAS_ERR_OK ) { return error; } @@ -711,16 +733,17 @@ static ivas_error initEfap( EFAP_WRAPPER *pEfapWrapper, IVAS_REND_AudioConfig ou return IVAS_ERR_OK; } -static ivas_error getEfapGains( EFAP_WRAPPER efapWrapper, - const float azi, - const float ele, - pan_vector panGains ) +static ivas_error getEfapGains( + EFAP_WRAPPER efapWrapper, + const float azi, + const float ele, + pan_vector panGains ) { pan_vector tmpPanGains; /* tmp pan gain buffer without LFE channels */ float *readPtr; - int32_t i; + int16_t i; int16_t lfeCount; - int32_t numChannels; + int16_t numChannels; ivas_error error; /* EFAP returns an array of gains only for non-LFE speakers */ @@ -794,21 +817,28 @@ static void initHeadRotation( { hIvasRend->headRotData.headPositions[i] = quaternionInit(); } + + return; } -static void initRotMatrix( rotation_matrix rot_mat ) +static void initRotMatrix( + rotation_matrix rot_mat ) { int16_t i; + /* Initialize rotation matrices */ for ( i = 0; i < 3; i++ ) { set_zero( rot_mat[i], 3 ); rot_mat[i][i] = 1.f; } + + return; } -static void initRotGains( rotation_gains rot_gains ) +static void initRotGains( + rotation_gains rot_gains ) { int16_t i; /* Set gains to passthrough */ @@ -817,9 +847,15 @@ static void initRotGains( rotation_gains rot_gains ) set_zero( rot_gains[i], MAX_INPUT_CHANNELS ); rot_gains[i][i] = 1.f; } + + return; } -static void initRendInputBase( input_base *inputBase, IVAS_REND_AudioConfig inConfig, IVAS_REND_InputId id, rendering_context rendCtx ) +static void initRendInputBase( + input_base *inputBase, + const IVAS_REND_AudioConfig inConfig, + const IVAS_REND_InputId id, + const rendering_context rendCtx ) { inputBase->inConfig = inConfig; inputBase->id = id; @@ -832,9 +868,12 @@ static void initRendInputBase( input_base *inputBase, IVAS_REND_AudioConfig inCo inputBase->inputBuffer.data = inputBase->bufferData; set_zero( inputBase->bufferData, MAX_BUFFER_LENGTH ); + + return; } -static IVAS_REND_AudioObjectPosition defaultObjectPosition( void ) +static IVAS_REND_AudioObjectPosition defaultObjectPosition( + void ) { IVAS_REND_AudioObjectPosition pos; @@ -844,7 +883,8 @@ static IVAS_REND_AudioObjectPosition defaultObjectPosition( void ) return pos; } -static rendering_context getRendCtx( IVAS_REND_HANDLE hIvasRend ) +static rendering_context getRendCtx( + IVAS_REND_HANDLE hIvasRend ) { rendering_context ctx; @@ -860,7 +900,8 @@ static rendering_context getRendCtx( IVAS_REND_HANDLE hIvasRend ) return ctx; } -static TDREND_WRAPPER defaultTdRendWrapper( void ) +static TDREND_WRAPPER defaultTdRendWrapper( + void ) { TDREND_WRAPPER w; @@ -871,7 +912,8 @@ static TDREND_WRAPPER defaultTdRendWrapper( void ) return w; } -static CREND_WRAPPER defaultCrendWrapper( void ) +static CREND_WRAPPER defaultCrendWrapper( + void ) { CREND_WRAPPER w; @@ -884,8 +926,8 @@ static CREND_WRAPPER defaultCrendWrapper( void ) static ivas_error setRendInputActiveIsm( void *input, - IVAS_REND_AudioConfig inConfig, - IVAS_REND_InputId id, + const IVAS_REND_AudioConfig inConfig, + const IVAS_REND_InputId id, RENDER_CONFIG_DATA *hRendCfg ) { ivas_error error; @@ -908,10 +950,7 @@ static ivas_error setRendInputActiveIsm( error = IVAS_ERR_OK; if ( outConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL ) { - error = ivas_rend_TDObjRendOpen( &inputIsm->tdRendWrapper, - inConfig, - NULL, - *rendCtx.pOutSampleRate ); + error = ivas_rend_TDObjRendOpen( &inputIsm->tdRendWrapper, inConfig, NULL, *rendCtx.pOutSampleRate ); } else if ( outConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM ) { @@ -929,7 +968,8 @@ static ivas_error setRendInputActiveIsm( return IVAS_ERR_OK; } -static void clearInputIsm( input_ism *inputIsm ) +static void clearInputIsm( + input_ism *inputIsm ) { rendering_context rendCtx; @@ -949,16 +989,18 @@ static void clearInputIsm( input_ism *inputIsm ) } } -static void copyLsConversionMatrixToPanMatrix( const LS_CONVERSION_MATRIX *lsConvMatrix, pan_matrix panMatrix ) +static void copyLsConversionMatrixToPanMatrix( + const LS_CONVERSION_MATRIX *lsConvMatrix, + pan_matrix panMatrix ) { - int32_t i; - int32_t inCh, outCh; - int32_t numNonZeroGains; - int32_t numColumns; + int16_t i; + int16_t inCh, outCh; + int16_t numNonZeroGains; + int16_t numColumns; /* Index 0 is special and describes the following values */ numNonZeroGains = lsConvMatrix[0].index; - numColumns = (int32_t) lsConvMatrix[0].value; + numColumns = (int16_t) lsConvMatrix[0].value; for ( i = 1; i < numNonZeroGains + 1; ++i ) { @@ -967,22 +1009,28 @@ static void copyLsConversionMatrixToPanMatrix( const LS_CONVERSION_MATRIX *lsCon panMatrix[inCh][outCh] = lsConvMatrix[i].value; } + + return; } -static void setZeroPanMatrix( pan_matrix panMatrix ) +static void setZeroPanMatrix( + pan_matrix panMatrix ) { - int32_t i; + int16_t i; for ( i = 0; i < MAX_INPUT_CHANNELS; ++i ) { set_zero( panMatrix[i], MAX_OUTPUT_CHANNELS ); } + + return; } /* Note: this only sets non-zero elements, call setZeroPanMatrix() to init first. */ -static void fillIdentityPanMatrix( pan_matrix panMatrix ) +static void fillIdentityPanMatrix( + pan_matrix panMatrix ) { - int32_t i; + int16_t i; for ( i = 0; i < min( MAX_INPUT_CHANNELS, MAX_OUTPUT_CHANNELS ); ++i ) { @@ -990,17 +1038,20 @@ static void fillIdentityPanMatrix( pan_matrix panMatrix ) } } -static ivas_error initMcPanGainsWithIdentMatrix( input_mc *inputMc ) +static ivas_error initMcPanGainsWithIdentMatrix( + input_mc *inputMc ) { fillIdentityPanMatrix( inputMc->panGains ); return IVAS_ERR_OK; } -static ivas_error initMcPanGainsWithConversionMapping( input_mc *inputMc, IVAS_REND_AudioConfig outConfig ) +static ivas_error initMcPanGainsWithConversionMapping( + input_mc *inputMc, + const IVAS_REND_AudioConfig outConfig ) { AUDIO_CONFIG ivasConfigIn, ivasConfigOut; - int32_t i; + int16_t i; ivasConfigIn = rendAudioConfigToIvasAudioConfig( inputMc->base.inConfig ); ivasConfigOut = rendAudioConfigToIvasAudioConfig( outConfig ); @@ -1074,10 +1125,7 @@ static ivas_error initMcPanGainsWithEfap( input_mc *inputMc, IVAS_REND_AudioConf ++outChIdx; } - if ( ( error = getEfapGains( *inputMc->base.ctx.pEfapOutWrapper, - spkAzi[i], - spkEle[i], - inputMc->panGains[outChIdx] ) ) != IVAS_ERR_OK ) + if ( ( error = getEfapGains( *inputMc->base.ctx.pEfapOutWrapper, spkAzi[i], spkEle[i], inputMc->panGains[outChIdx] ) ) != IVAS_ERR_OK ) { return error; } @@ -1095,7 +1143,9 @@ static ivas_error initMcPanGainsWithEfap( input_mc *inputMc, IVAS_REND_AudioConf return IVAS_ERR_OK; } -static ivas_error getRendInputNumChannels( const void *rendInput, int32_t *numInChannels ) +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: @@ -1124,10 +1174,11 @@ static ivas_error getRendInputNumChannels( const void *rendInput, int32_t *numIn return IVAS_ERR_OK; } -static ivas_error initMcPanGainsWithMonoOut( input_mc *inputMc ) +static ivas_error initMcPanGainsWithMonoOut( + input_mc *inputMc ) { - int32_t i; - int32_t numInChannels; + int16_t i; + int16_t numInChannels; ivas_error error; if ( ( error = getRendInputNumChannels( inputMc, &numInChannels ) ) != IVAS_ERR_OK ) @@ -1145,12 +1196,13 @@ static ivas_error initMcPanGainsWithMonoOut( input_mc *inputMc ) return IVAS_ERR_OK; } -static ivas_error initMcPanGainsWithStereoLookup( input_mc *inputMc ) +static ivas_error initMcPanGainsWithStereoLookup( + input_mc *inputMc ) { - int32_t readIdx; - int32_t writeIdx; + int16_t readIdx; + int16_t writeIdx; bool skipSideSpeakers; - int32_t numInChannels; + int16_t numInChannels; ivas_error error; /* Special case - MONO input. @@ -1197,7 +1249,7 @@ static bool configsAreEqual( IVAS_REND_AudioConfig configB, LSSETUP_CUSTOM_STRUCT customLsB ) { - int32_t i; + int16_t i; /* Both input and output are custom LS - compare structs */ if ( configA == IVAS_REND_AUDIO_CONFIG_LS_CUSTOM && configB == IVAS_REND_AUDIO_CONFIG_LS_CUSTOM ) @@ -1238,7 +1290,9 @@ static bool configsAreEqual( return configA == configB; } -static ivas_error updateMcPanGainsForMcOut( input_mc *inputMc, IVAS_REND_AudioConfig outConfig ) +static ivas_error updateMcPanGainsForMcOut( + input_mc *inputMc, + const IVAS_REND_AudioConfig outConfig ) { ivas_error error; @@ -1254,10 +1308,7 @@ static ivas_error updateMcPanGainsForMcOut( input_mc *inputMc, IVAS_REND_AudioCo +-----------+----------+---------------+-----------+--------------------+ */ - if ( configsAreEqual( inputMc->base.inConfig, - inputMc->customLsInput, - outConfig, - *inputMc->base.ctx.pCustomLsOut ) ) + if ( configsAreEqual( inputMc->base.inConfig, inputMc->customLsInput, outConfig, *inputMc->base.ctx.pCustomLsOut ) ) { error = initMcPanGainsWithIdentMatrix( inputMc ); } @@ -1283,7 +1334,9 @@ static ivas_error updateMcPanGainsForMcOut( input_mc *inputMc, IVAS_REND_AudioCo return error; } -static ivas_error updateMcPanGainsForAmbiOut( input_mc *inputMc, IVAS_REND_AudioConfig outConfig ) +static ivas_error updateMcPanGainsForAmbiOut( + input_mc *inputMc, + const IVAS_REND_AudioConfig outConfig ) { int16_t ch_in, ch_out, lfeIdx; int16_t numNonLfeInChannels, outAmbiOrder; @@ -1316,10 +1369,7 @@ static ivas_error updateMcPanGainsForAmbiOut( input_mc *inputMc, IVAS_REND_Audio { ++ch_out; } - ivas_dirac_dec_get_response( (int16_t) spkAzi[ch_in], - (int16_t) spkEle[ch_in], - inputMc->panGains[ch_out], - outAmbiOrder ); + ivas_dirac_dec_get_response( (int16_t) spkAzi[ch_in], (int16_t) spkEle[ch_in], inputMc->panGains[ch_out], outAmbiOrder ); } } else @@ -1339,19 +1389,18 @@ static ivas_error updateMcPanGainsForAmbiOut( input_mc *inputMc, IVAS_REND_Audio } } - ivas_dirac_dec_get_response( (int16_t) spkAzi[ch_in], - (int16_t) spkEle[ch_in], - inputMc->panGains[ch_out], - outAmbiOrder ); + ivas_dirac_dec_get_response( (int16_t) spkAzi[ch_in], (int16_t) spkEle[ch_in], inputMc->panGains[ch_out], outAmbiOrder ); } } return IVAS_ERR_OK; } -static ivas_error updateMcPanGains( input_mc *inputMc, IVAS_REND_AudioConfig outConfig ) +static ivas_error updateMcPanGains( + input_mc *inputMc, + const IVAS_REND_AudioConfig outConfig ) { - int32_t i; + int16_t i; ivas_error error; /* Reset to all zeros - some functions below only write non-zero elements. */ @@ -1410,7 +1459,7 @@ static ivas_error updateMcPanGains( input_mc *inputMc, IVAS_REND_AudioConfig out See issue: https://forge.3gpp.org/rep/ivas-codec-pc/ivas-codec/-/issues/81 */ static void tmpFixBuggyTdBinRendInit( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRendererTd ) { - int32_t i, j; + int16_t i, j; for ( i = 0; i < hBinRendererTd->NumOfSrcs; ++i ) { @@ -1427,8 +1476,8 @@ static void tmpFixBuggyTdBinRendInit( BINAURAL_TD_OBJECT_RENDERER_HANDLE hBinRen static ivas_error initMcBinauralRendering( input_mc *inputMc, - IVAS_REND_AudioConfig inConfig, - IVAS_REND_AudioConfig outConfig, + const IVAS_REND_AudioConfig inConfig, + const IVAS_REND_AudioConfig outConfig, RENDER_CONFIG_DATA *hRendCfg ) { ivas_error error; @@ -1465,10 +1514,7 @@ static ivas_error initMcBinauralRendering( // if ( initTDRend ) { - if ( ( error = ivas_rend_TDObjRendOpen( &inputMc->tdRendWrapper, - inConfig, - &inputMc->customLsInput, - outSampleRate ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_rend_TDObjRendOpen( &inputMc->tdRendWrapper, inConfig, &inputMc->customLsInput, outSampleRate ) ) != IVAS_ERR_OK ) { return error; } @@ -1548,8 +1594,8 @@ static IVAS_REND_LfeRouting defaultLfeRouting( static ivas_error setRendInputActiveMc( void *input, - IVAS_REND_AudioConfig inConfig, - IVAS_REND_InputId id, + const IVAS_REND_AudioConfig inConfig, + const IVAS_REND_InputId id, RENDER_CONFIG_DATA *hRendCfg ) { ivas_error error; @@ -1567,10 +1613,7 @@ static ivas_error setRendInputActiveMc( inputMc->tdRendWrapper = defaultTdRendWrapper(); inputMc->crendWrapper = defaultCrendWrapper(); initRotGains( inputMc->rot_gains_prev ); - inputMc->lfeRouting = defaultLfeRouting( inConfig, - inputMc->customLsInput, - outConfig, - *inputMc->base.ctx.pCustomLsOut ); + inputMc->lfeRouting = defaultLfeRouting( inConfig, inputMc->customLsInput, outConfig, *inputMc->base.ctx.pCustomLsOut ); if ( outConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL || outConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM ) { @@ -1588,7 +1631,8 @@ static ivas_error setRendInputActiveMc( return IVAS_ERR_OK; } -static void clearInputMc( input_mc *inputMc ) +static void clearInputMc( + input_mc *inputMc ) { rendering_context rendCtx; @@ -1610,11 +1654,13 @@ static void clearInputMc( input_mc *inputMc ) ivas_td_binaural_close( &inputMc->tdRendWrapper.hBinRendererTd ); inputMc->tdRendWrapper.hHrtfTD = NULL; } + + return; } static ivas_error initSbaPanGainsForMcOut( input_sba *inputSba, - IVAS_REND_AudioConfig outConfig, + const IVAS_REND_AudioConfig outConfig, const LSSETUP_CUSTOM_STRUCT *outSetupCustom ) { int16_t ambiOrderIn; @@ -1682,7 +1728,9 @@ static ivas_error initSbaPanGainsForMcOut( return IVAS_ERR_OK; } -static ivas_error initSbaPanGainsForSbaOut( input_sba *inputSba, IVAS_REND_AudioConfig outConfig ) +static ivas_error initSbaPanGainsForSbaOut( + input_sba *inputSba, + const IVAS_REND_AudioConfig outConfig ) { ivas_error error; error = IVAS_ERR_OK; @@ -1698,7 +1746,10 @@ static ivas_error initSbaPanGainsForSbaOut( input_sba *inputSba, IVAS_REND_Audio return error; } -static ivas_error updateSbaPanGains( input_sba *inputSba, IVAS_REND_AudioConfig outConfig, RENDER_CONFIG_DATA *hRendCfg ) +static ivas_error updateSbaPanGains( + input_sba *inputSba, + const IVAS_REND_AudioConfig outConfig, + RENDER_CONFIG_DATA *hRendCfg ) { ivas_error error; IVAS_REND_AudioConfig inConfig; @@ -1722,22 +1773,14 @@ static ivas_error updateSbaPanGains( input_sba *inputSba, IVAS_REND_AudioConfig switch ( outConfig ) { case IVAS_REND_AUDIO_CONFIG_BINAURAL: - error = ivas_rend_openCrend( &inputSba->crendWrapper, - inConfig, - outConfig, - hRendCfg, - *rendCtx.pOutSampleRate ); + error = ivas_rend_openCrend( &inputSba->crendWrapper, inConfig, outConfig, hRendCfg, *rendCtx.pOutSampleRate ); break; case IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM: if ( ( error = initSbaPanGainsForMcOut( inputSba, IVAS_REND_AUDIO_CONFIG_7_1_4, NULL ) ) != IVAS_ERR_OK ) { return error; } - error = ivas_rend_openCrend( &inputSba->crendWrapper, - IVAS_REND_AUDIO_CONFIG_7_1_4, - outConfig, - hRendCfg, - *rendCtx.pOutSampleRate ); + error = ivas_rend_openCrend( &inputSba->crendWrapper, IVAS_REND_AUDIO_CONFIG_7_1_4, outConfig, hRendCfg, *rendCtx.pOutSampleRate ); break; default: return IVAS_ERR_INVALID_OUTPUT_FORMAT; @@ -1757,8 +1800,8 @@ static ivas_error updateSbaPanGains( input_sba *inputSba, IVAS_REND_AudioConfig static ivas_error setRendInputActiveSba( void *input, - IVAS_REND_AudioConfig inConfig, - IVAS_REND_InputId id, + const IVAS_REND_AudioConfig inConfig, + const IVAS_REND_InputId id, RENDER_CONFIG_DATA *hRendCfg ) { ivas_error error; @@ -1783,7 +1826,8 @@ static ivas_error setRendInputActiveSba( return error; } -static void clearInputSba( input_sba *inputSba ) +static void clearInputSba( + input_sba *inputSba ) { rendering_context rendCtx; @@ -1796,17 +1840,19 @@ static void clearInputSba( input_sba *inputSba ) { ivas_rend_closeCrend( &inputSba->crendWrapper ); } + + return; } ivas_error IVAS_REND_Open( IVAS_REND_HANDLE *phIvasRend, - int32_t outputSampleRate, - IVAS_REND_AudioConfig outConfig ) + const int32_t outputSampleRate, + const IVAS_REND_AudioConfig outConfig ) { int16_t i; IVAS_REND_HANDLE hIvasRend; ivas_error error; - int32_t numOutChannels; + int16_t numOutChannels; /*-----------------------------------------------------------------* * Validate function arguments @@ -1858,36 +1904,28 @@ ivas_error IVAS_REND_Open( /* Initialize inputs */ for ( i = 0; i < RENDERER_MAX_ISM_INPUTS; ++i ) { - initRendInputBase( &hIvasRend->inputsIsm[i].base, - IVAS_REND_AUDIO_CONFIG_UNKNOWN, - 0, - getRendCtx( hIvasRend ) ); + initRendInputBase( &hIvasRend->inputsIsm[i].base, IVAS_REND_AUDIO_CONFIG_UNKNOWN, 0, getRendCtx( hIvasRend ) ); hIvasRend->inputsIsm[i].crendWrapper.hCrend = NULL; hIvasRend->inputsIsm[i].tdRendWrapper.hBinRendererTd = NULL; } for ( i = 0; i < RENDERER_MAX_MC_INPUTS; ++i ) { - initRendInputBase( &hIvasRend->inputsMc[i].base, - IVAS_REND_AUDIO_CONFIG_UNKNOWN, - 0, - getRendCtx( hIvasRend ) ); + initRendInputBase( &hIvasRend->inputsMc[i].base, IVAS_REND_AUDIO_CONFIG_UNKNOWN, 0, getRendCtx( hIvasRend ) ); hIvasRend->inputsMc[i].efapInWrapper.hEfap = NULL; hIvasRend->inputsMc[i].crendWrapper.hCrend = NULL; hIvasRend->inputsMc[i].tdRendWrapper.hBinRendererTd = NULL; } for ( i = 0; i < RENDERER_MAX_SBA_INPUTS; ++i ) { - initRendInputBase( &hIvasRend->inputsSba[i].base, - IVAS_REND_AUDIO_CONFIG_UNKNOWN, - 0, - getRendCtx( hIvasRend ) ); + initRendInputBase( &hIvasRend->inputsSba[i].base, IVAS_REND_AUDIO_CONFIG_UNKNOWN, 0, getRendCtx( hIvasRend ) ); hIvasRend->inputsSba[i].crendWrapper.hCrend = NULL; } return IVAS_ERR_OK; } -static LSSETUP_CUSTOM_STRUCT makeCustomLsSetup( IVAS_CUSTOM_LS_DATA rendCustomLsLayout ) +static LSSETUP_CUSTOM_STRUCT makeCustomLsSetup( + const IVAS_CUSTOM_LS_DATA rendCustomLsLayout ) { int16_t i; LSSETUP_CUSTOM_STRUCT customLs; @@ -1913,9 +1951,10 @@ static LSSETUP_CUSTOM_STRUCT makeCustomLsSetup( IVAS_CUSTOM_LS_DATA rendCustomLs return customLs; } -static ivas_error validateCustomLsLayout( IVAS_CUSTOM_LS_DATA layout ) +static ivas_error validateCustomLsLayout( + const IVAS_CUSTOM_LS_DATA layout ) { - int32_t i; + int16_t i; /* Negative number of speakers or LFEs makes no sense */ if ( layout.num_spk < 0 || layout.num_lfe < 0 ) @@ -1941,11 +1980,10 @@ static ivas_error validateCustomLsLayout( IVAS_CUSTOM_LS_DATA layout ) ivas_error IVAS_REND_ConfigureCustomOutputLoudspeakerLayout( IVAS_REND_HANDLE hIvasRend, - IVAS_CUSTOM_LS_DATA layout ) + const IVAS_CUSTOM_LS_DATA layout ) { - int32_t numOutChannels; + int16_t i, numOutChannels; ivas_error error; - int32_t i; input_mc *inputMc; input_sba *inputSba; @@ -1974,14 +2012,10 @@ ivas_error IVAS_REND_ConfigureCustomOutputLoudspeakerLayout( { return error; } - initLimiter( &hIvasRend->hLimiter, - numOutChannels, - hIvasRend->sampleRateOut ); + initLimiter( &hIvasRend->hLimiter, numOutChannels, hIvasRend->sampleRateOut ); /* Re-initialize EFAP - output layout has changed or has been fully defined for the first time */ - initEfap( &hIvasRend->efapOutWrapper, - hIvasRend->outputConfig, - &hIvasRend->customLsOut ); + initEfap( &hIvasRend->efapOutWrapper, hIvasRend->outputConfig, &hIvasRend->customLsOut ); /* Re-initialize panning gains for each active MC input, This includes re-initializing * LFE handling for the new output layout, which means custom LFE handling is overwritten, @@ -1994,10 +2028,9 @@ ivas_error IVAS_REND_ConfigureCustomOutputLoudspeakerLayout( /* Input inactive, skip. */ continue; } - inputMc->lfeRouting = defaultLfeRouting( inputMc->base.inConfig, - inputMc->customLsInput, - hIvasRend->outputConfig, - *inputMc->base.ctx.pCustomLsOut ); + + inputMc->lfeRouting = defaultLfeRouting( inputMc->base.inConfig, inputMc->customLsInput, hIvasRend->outputConfig, *inputMc->base.ctx.pCustomLsOut ); + if ( ( error = updateMcPanGains( inputMc, hIvasRend->outputConfig ) ) != IVAS_ERR_OK ) { return error; @@ -2024,7 +2057,7 @@ ivas_error IVAS_REND_ConfigureCustomOutputLoudspeakerLayout( ivas_error IVAS_REND_NumOutChannels( IVAS_REND_CONST_HANDLE hIvasRend, - int32_t *numOutChannels ) + int16_t *numOutChannels ) { ivas_error error; @@ -2056,7 +2089,9 @@ ivas_error IVAS_REND_NumOutChannels( return IVAS_ERR_OK; } -static IVAS_REND_InputId makeInputId( IVAS_REND_AudioConfig config, int32_t inputIndex ) +static IVAS_REND_InputId makeInputId( + IVAS_REND_AudioConfig config, + const int32_t inputIndex ) { /* Put config type in second byte (from LSB), put index + 1 in first byte * @@ -2064,7 +2099,10 @@ static IVAS_REND_InputId makeInputId( IVAS_REND_AudioConfig config, int32_t inpu return getAudioConfigType( config ) << 8 | ( inputIndex + 1 ); } -static ivas_error getInputById( IVAS_REND_HANDLE hIvasRend, IVAS_REND_InputId inputId, void **ppInput ) +static ivas_error getInputById( + IVAS_REND_HANDLE hIvasRend, + IVAS_REND_InputId inputId, + void **ppInput ) { int32_t inputIndex; IVAS_REND_AudioConfigType configType; @@ -2119,7 +2157,10 @@ static ivas_error getInputById( IVAS_REND_HANDLE hIvasRend, IVAS_REND_InputId in } /* Unfortunately code duplication here is the only way to avoid warnings about const casting */ -static ivas_error getConstInputById( IVAS_REND_CONST_HANDLE hIvasRend, IVAS_REND_InputId inputId, const void **ppInput ) +static ivas_error getConstInputById( + IVAS_REND_CONST_HANDLE hIvasRend, + const IVAS_REND_InputId inputId, + const void **ppInput ) { int32_t inputIndex; IVAS_REND_AudioConfigType configType; @@ -2260,20 +2301,14 @@ ivas_error IVAS_REND_AddInput( } /* Find first free input in array corresponding to input type */ - if ( ( error = findFreeInputSlot( inputsArray, - inputStructSize, - maxNumInputsOfType, - &inputIndex ) ) != IVAS_ERR_OK ) + if ( ( error = findFreeInputSlot( inputsArray, inputStructSize, maxNumInputsOfType, &inputIndex ) ) != IVAS_ERR_OK ) { return error; } *inputId = makeInputId( inConfig, inputIndex ); - if ( ( error = activateInput( (uint8_t *) inputsArray + inputStructSize * inputIndex, - inConfig, - *inputId, - hIvasRend->hRendererConfig ) ) != IVAS_ERR_OK ) + if ( ( error = activateInput( (uint8_t *) inputsArray + inputStructSize * inputIndex, inConfig, *inputId, hIvasRend->hRendererConfig ) ) != IVAS_ERR_OK ) { return error; } @@ -2283,8 +2318,8 @@ ivas_error IVAS_REND_AddInput( ivas_error IVAS_REND_ConfigureCustomInputLoudspeakerLayout( IVAS_REND_HANDLE hIvasRend, - IVAS_REND_InputId inputId, - IVAS_CUSTOM_LS_DATA layout ) + const IVAS_REND_InputId inputId, + const IVAS_CUSTOM_LS_DATA layout ) { input_mc *inputMc; ivas_error error; @@ -2316,10 +2351,7 @@ ivas_error IVAS_REND_ConfigureCustomInputLoudspeakerLayout( * set for the MC input. */ inputMc->customLsInput = makeCustomLsSetup( layout ); - inputMc->lfeRouting = defaultLfeRouting( inputMc->base.inConfig, - inputMc->customLsInput, - hIvasRend->outputConfig, - *inputMc->base.ctx.pCustomLsOut ); + inputMc->lfeRouting = defaultLfeRouting( inputMc->base.inConfig, inputMc->customLsInput, hIvasRend->outputConfig, *inputMc->base.ctx.pCustomLsOut ); initEfap( &inputMc->efapInWrapper, inputMc->base.inConfig, &inputMc->customLsInput ); @@ -2340,8 +2372,8 @@ ivas_error IVAS_REND_ConfigureCustomInputLoudspeakerLayout( ivas_error IVAS_REND_SetInputGain( IVAS_REND_HANDLE hIvasRend, - IVAS_REND_InputId inputId, - float gain /* linear gain, not in dB */ + const IVAS_REND_InputId inputId, + const float gain /* linear gain, not in dB */ ) { input_base *inputBase; @@ -2365,7 +2397,8 @@ ivas_error IVAS_REND_SetInputGain( return IVAS_ERR_OK; } -static int32_t getNumLfeChannels( input_mc *inputMc ) +static int32_t getNumLfeChannels( + input_mc *inputMc ) { switch ( inputMc->base.inConfig ) { @@ -2386,8 +2419,8 @@ static int32_t getNumLfeChannels( input_mc *inputMc ) ivas_error IVAS_REND_SetInputLfeRouting( IVAS_REND_HANDLE hIvasRend, - IVAS_REND_InputId inputId, - IVAS_REND_LfeRouting lfeRouting ) + const IVAS_REND_InputId inputId, + const IVAS_REND_LfeRouting lfeRouting ) { input_base *pInputBase; input_mc *pInputMc; @@ -2428,7 +2461,7 @@ ivas_error IVAS_REND_SetInputLfeRouting( ivas_error IVAS_REND_RemoveInput( IVAS_REND_HANDLE hIvasRend, - IVAS_REND_InputId inputId ) + const IVAS_REND_InputId inputId ) { ivas_error error; input_base *inputBase; @@ -2466,8 +2499,8 @@ ivas_error IVAS_REND_RemoveInput( ivas_error IVAS_REND_GetInputNumChannels( IVAS_REND_CONST_HANDLE hIvasRend, - IVAS_REND_InputId inputId, - int32_t *numChannels ) + const IVAS_REND_InputId inputId, + int16_t *numChannels ) { ivas_error error; const input_base *pInput; @@ -2552,12 +2585,12 @@ ivas_error IVAS_REND_GetDelay( ivas_error IVAS_REND_FeedInputAudio( IVAS_REND_HANDLE hIvasRend, - IVAS_REND_InputId inputId, - IVAS_REND_ReadOnlyAudioBuffer inputAudio ) + const IVAS_REND_InputId inputId, + const IVAS_REND_ReadOnlyAudioBuffer inputAudio ) { ivas_error error; input_base *inputBase; - int32_t numInputChannels; + int16_t numInputChannels; /*-----------------------------------------------------------------* * Validate function arguments @@ -2597,9 +2630,7 @@ ivas_error IVAS_REND_FeedInputAudio( inputBase->inputBuffer.config = inputAudio.config; - mvr2r( inputAudio.data, - inputBase->inputBuffer.data, - inputAudio.config.numSamplesPerChannel * inputAudio.config.numChannels ); + mvr2r( inputAudio.data, inputBase->inputBuffer.data, inputAudio.config.numSamplesPerChannel * inputAudio.config.numChannels ); inputBase->numNewSamplesPerChannel = inputAudio.config.numSamplesPerChannel; @@ -2608,8 +2639,8 @@ ivas_error IVAS_REND_FeedInputAudio( ivas_error IVAS_REND_FeedInputObjectMetadata( IVAS_REND_HANDLE hIvasRend, - IVAS_REND_InputId inputId, - IVAS_REND_AudioObjectPosition objectPosition ) + const IVAS_REND_InputId inputId, + const IVAS_REND_AudioObjectPosition objectPosition ) { input_base *inputBase; input_ism *inputIsm; @@ -2873,6 +2904,8 @@ static void renderBufferChannel( IVAS_REND_AudioBuffer outAudio ) { renderBufferChannelLerp( inAudio, inChannelIdx, outputGains, NULL, outAudio ); + + return; } static ivas_error rotateFrameMc( @@ -2887,20 +2920,18 @@ static ivas_error rotateFrameMc( { int16_t i; int16_t subframe_idx, subframe_len; - int16_t azimuth, elevation; - int32_t is_planar_setup, lfe_idx; - int32_t nchan; - int32_t ch_in, ch_out; - int32_t ch_in_woLFE, ch_out_woLFE; - + int16_t is_planar_setup, lfe_idx; + int16_t nchan; + int16_t ch_in, ch_out; + int16_t ch_in_woLFE, ch_out_woLFE; float *readPtr, *writePtr; const float *ls_azimuth, *ls_elevation; rotation_matrix Rmat; rotation_gains gains; float tmp_gains[MAX_INPUT_CHANNELS]; - wmops_sub_start("rotateFrameMc"); + wmops_sub_start( "rotateFrameMc" ); if ( inConfig != IVAS_REND_AUDIO_CONFIG_LS_CUSTOM ) { @@ -2911,12 +2942,7 @@ static ivas_error rotateFrameMc( nchan = inCustomLs.num_spk + inCustomLs.num_lfe; } - getMcConfigValues( inConfig, - inCustomLs, - &ls_azimuth, - &ls_elevation, - &lfe_idx, - &is_planar_setup ); + getMcConfigValues( inConfig, inCustomLs, &ls_azimuth, &ls_elevation, &lfe_idx, &is_planar_setup ); /* initialize gains to passthrough */ for ( ch_in = 0; ch_in < nchan; ch_in++ ) @@ -2944,20 +2970,11 @@ static ivas_error rotateFrameMc( ch_in_woLFE = ( ( lfe_idx > 0 ) && ( ch_in >= lfe_idx ) ) ? ch_in - 1 : ch_in; /* gains for current subframe rotation */ - rotateAziEle( ls_azimuth[ch_in_woLFE], - ls_elevation[ch_in_woLFE], - &azimuth, - &elevation, - Rmat, - (int16_t) is_planar_setup ); + rotateAziEle( ls_azimuth[ch_in_woLFE], ls_elevation[ch_in_woLFE], &azimuth, &elevation, Rmat, is_planar_setup ); if ( hEFAPdata != NULL && ( ls_azimuth[ch_in_woLFE] != azimuth || ls_elevation[ch_in_woLFE] != elevation ) ) { - efap_determine_gains( hEFAPdata, - tmp_gains, - azimuth, - elevation, - EFAP_MODE_EFAP ); + efap_determine_gains( hEFAPdata, tmp_gains, azimuth, elevation, EFAP_MODE_EFAP ); for ( ch_out = 0; ch_out < nchan; ch_out++ ) { @@ -3017,13 +3034,12 @@ static ivas_error rotateFrameSba( int16_t m1, m2; int16_t shd_rot_max_order; int16_t subframe_idx, subframe_len; - float *readPtr, *writePtr; rotation_matrix Rmat; float tmpRot[2 * HEADROT_ORDER + 1]; rotation_gains gains; - wmops_sub_start("rotateFrameSba"); + wmops_sub_start( "rotateFrameSba" ); getAmbisonicsOrder( inConfig, &shd_rot_max_order ); @@ -3109,10 +3125,9 @@ static ivas_error renderIsmToBinaural( IVAS_REND_AudioBuffer outAudio ) { float tmpTDRendBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; - ivas_error error; - wmops_sub_start("renderIsmToBinaural"); + wmops_sub_start( "renderIsmToBinaural" ); copyBufferTo2dArray( ismInput->base.inputBuffer, tmpTDRendBuffer ); @@ -3143,11 +3158,10 @@ static ivas_error renderIsmToBinauralRoom( int16_t i; int16_t azi_rot, ele_rot; int16_t subframe_idx, subframe_len; - int32_t tmp; + int16_t tmp; rotation_matrix Rmat; float tmpCrendBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; IVAS_QUATERNION quat; - ivas_error error; pan_vector currentPanGains; pan_vector previousPanGains; @@ -3155,7 +3169,7 @@ static ivas_error renderIsmToBinauralRoom( IVAS_REND_AudioObjectPosition rotatedPos; const IVAS_REND_HeadRotData *headRotData; - wmops_sub_start("renderIsmToBinauralRoom"); + wmops_sub_start( "renderIsmToBinauralRoom" ); headRotData = ismInput->base.ctx.pHeadRotData; rotatedPos = defaultObjectPosition(); @@ -3182,12 +3196,7 @@ static ivas_error renderIsmToBinauralRoom( /* previous position gains */ if ( headRotData->headRotEnabled ) { - rotateAziEle( ismInput->previousPos.azimuth, - ismInput->previousPos.elevation, - &azi_rot, - &ele_rot, - ismInput->rot_mat_prev, - 0 ); + rotateAziEle( ismInput->previousPos.azimuth, ismInput->previousPos.elevation, &azi_rot, &ele_rot, ismInput->rot_mat_prev, 0 ); rotatedPos.azimuth = (float) azi_rot; rotatedPos.elevation = (float) ele_rot; } @@ -3202,12 +3211,7 @@ static ivas_error renderIsmToBinauralRoom( /* current position gains */ if ( headRotData->headRotEnabled ) { - rotateAziEle( ismInput->currentPos.azimuth, - ismInput->currentPos.elevation, - &azi_rot, - &ele_rot, - Rmat, - 0 ); + rotateAziEle( ismInput->currentPos.azimuth, ismInput->currentPos.elevation, &azi_rot, &ele_rot, Rmat, 0 ); rotatedPos.azimuth = (float) azi_rot; rotatedPos.elevation = (float) ele_rot; } @@ -3227,23 +3231,15 @@ static ivas_error renderIsmToBinauralRoom( /* intermediate rendering to 7_1_4 */ tmpMcBuffer = ismInput->base.inputBuffer; getAudioConfigNumChannels( IVAS_REND_AUDIO_CONFIG_7_1_4, &tmp ); - tmpMcBuffer.config.numChannels = (int16_t) tmp; + tmpMcBuffer.config.numChannels = tmp; tmpMcBuffer.data = count_malloc( tmpMcBuffer.config.numSamplesPerChannel * tmpMcBuffer.config.numChannels * sizeof( float ) ); set_zero( tmpMcBuffer.data, tmpMcBuffer.config.numSamplesPerChannel * tmpMcBuffer.config.numChannels ); - renderBufferChannelLerp( ismInput->base.inputBuffer, - 0, - currentPanGains, - previousPanGains, - tmpMcBuffer ); + renderBufferChannelLerp( ismInput->base.inputBuffer, 0, currentPanGains, previousPanGains, tmpMcBuffer ); copyBufferTo2dArray( tmpMcBuffer, tmpCrendBuffer ); - ivas_rend_crendProcess( &ismInput->crendWrapper, - IVAS_REND_AUDIO_CONFIG_7_1_4, - IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM, - tmpCrendBuffer, - *ismInput->base.ctx.pOutSampleRate ); + ivas_rend_crendProcess( &ismInput->crendWrapper, IVAS_REND_AUDIO_CONFIG_7_1_4, IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM, tmpCrendBuffer, *ismInput->base.ctx.pOutSampleRate ); accumulate2dArrayToBuffer( tmpCrendBuffer, &outAudio ); @@ -3256,37 +3252,27 @@ static ivas_error renderIsmToBinauralRoom( static ivas_error renderIsmToMc( const input_ism *ismInput, - IVAS_REND_AudioBuffer outAudio ) + const IVAS_REND_AudioBuffer outAudio ) { pan_vector currentPanGains; pan_vector previousPanGains; ivas_error error; - wmops_sub_start("renderIsmToMc"); + wmops_sub_start( "renderIsmToMc" ); /* TODO(sgi): Possible optimization: less processing needed if position didn't change */ - if ( ( error = getEfapGains( *ismInput->base.ctx.pEfapOutWrapper, - ismInput->currentPos.azimuth, - ismInput->currentPos.elevation, - currentPanGains ) ) != IVAS_ERR_OK ) + if ( ( error = getEfapGains( *ismInput->base.ctx.pEfapOutWrapper, ismInput->currentPos.azimuth, ismInput->currentPos.elevation, currentPanGains ) ) != IVAS_ERR_OK ) { return error; } - if ( ( error = getEfapGains( *ismInput->base.ctx.pEfapOutWrapper, - ismInput->previousPos.azimuth, - ismInput->previousPos.elevation, - previousPanGains ) ) != IVAS_ERR_OK ) + if ( ( error = getEfapGains( *ismInput->base.ctx.pEfapOutWrapper, ismInput->previousPos.azimuth, ismInput->previousPos.elevation, previousPanGains ) ) != IVAS_ERR_OK ) { return error; } /* Assume num channels in audio buffer to be 1. * This should have been validated in IVAS_REND_FeedInputAudio() */ - renderBufferChannelLerp( ismInput->base.inputBuffer, - 0, - currentPanGains, - previousPanGains, - outAudio ); + renderBufferChannelLerp( ismInput->base.inputBuffer, 0, currentPanGains, previousPanGains, outAudio ); wmops_sub_end(); @@ -3295,17 +3281,17 @@ static ivas_error renderIsmToMc( static ivas_error renderIsmToSba( const input_ism *ismInput, - IVAS_REND_AudioConfig outConfig, - IVAS_REND_AudioBuffer outAudio ) + const IVAS_REND_AudioConfig outConfig, + const IVAS_REND_AudioBuffer outAudio ) { int16_t ambiOrderOut; - int32_t numOutChannels; + int16_t numOutChannels; pan_vector currentPanGains; pan_vector previousPanGains; ivas_error error; error = IVAS_ERR_OK; - wmops_sub_start("renderIsmToSba"); + wmops_sub_start( "renderIsmToSba" ); if ( ( error = getAudioConfigNumChannels( outConfig, &numOutChannels ) ) != IVAS_ERR_OK ) { @@ -3316,10 +3302,7 @@ static ivas_error renderIsmToSba( return error; } - ivas_dirac_dec_get_response( (int16_t) ismInput->previousPos.azimuth, - (int16_t) ismInput->previousPos.elevation, - previousPanGains, - (int16_t) ambiOrderOut ); + ivas_dirac_dec_get_response( (int16_t) ismInput->previousPos.azimuth, (int16_t) ismInput->previousPos.elevation, previousPanGains, ambiOrderOut ); if ( ( ismInput->currentPos.azimuth == ismInput->previousPos.azimuth ) && ( ismInput->currentPos.elevation == ismInput->previousPos.elevation ) ) @@ -3328,19 +3311,12 @@ static ivas_error renderIsmToSba( } else { - ivas_dirac_dec_get_response( (int16_t) ismInput->currentPos.azimuth, - (int16_t) ismInput->currentPos.elevation, - currentPanGains, - (int16_t) ambiOrderOut ); + ivas_dirac_dec_get_response( (int16_t) ismInput->currentPos.azimuth, (int16_t) ismInput->currentPos.elevation, currentPanGains, ambiOrderOut ); } /* Assume num channels in audio buffer to be 1. * This should have been validated in IVAS_REND_FeedInputAudio() */ - renderBufferChannelLerp( ismInput->base.inputBuffer, - 0, - currentPanGains, - previousPanGains, - outAudio ); + renderBufferChannelLerp( ismInput->base.inputBuffer, 0, currentPanGains, previousPanGains, outAudio ); wmops_sub_end(); @@ -3349,8 +3325,8 @@ static ivas_error renderIsmToSba( static ivas_error renderInputIsm( input_ism *ismInput, - IVAS_REND_AudioConfig outConfig, - IVAS_REND_AudioBuffer outAudio ) + const IVAS_REND_AudioConfig outConfig, + const IVAS_REND_AudioBuffer outAudio ) { ivas_error error; IVAS_REND_AudioBuffer inAudio; @@ -3365,10 +3341,7 @@ static ivas_error renderInputIsm( ismInput->base.numNewSamplesPerChannel = 0; /* Apply input gain to new audio */ - v_multc( inAudio.data, - ismInput->base.gain, - inAudio.data, - inAudio.config.numSamplesPerChannel * inAudio.config.numChannels ); + v_multc( inAudio.data, ismInput->base.gain, inAudio.data, inAudio.config.numSamplesPerChannel * inAudio.config.numChannels ); switch ( getAudioConfigType( outConfig ) ) @@ -3408,7 +3381,7 @@ static ivas_error renderActiveInputsIsm( IVAS_REND_HANDLE hIvasRend, IVAS_REND_AudioBuffer outAudio ) { - int32_t i; + int16_t i; input_ism *pCurrentInput; ivas_error error; @@ -3419,9 +3392,7 @@ static ivas_error renderActiveInputsIsm( /* Skip inactive inputs */ continue; } - if ( ( error = renderInputIsm( pCurrentInput, - hIvasRend->outputConfig, - outAudio ) ) != IVAS_ERR_OK ) + if ( ( error = renderInputIsm( pCurrentInput, hIvasRend->outputConfig, outAudio ) ) != IVAS_ERR_OK ) { return error; } @@ -3441,7 +3412,7 @@ static ivas_error renderLfeToBinaural( assert( ( outAudio.config.numChannels == 2 ) && "Must be binaural output" ); - wmops_sub_start("renderLfeToBinaural"); + wmops_sub_start( "renderLfeToBinaural" ); gain = GAIN_LFE; @@ -3481,7 +3452,7 @@ static ivas_error renderLfeToBinaural( static ivas_error renderMcToBinaural( input_mc *mcInput, - IVAS_REND_AudioConfig outConfig, + const IVAS_REND_AudioConfig outConfig, IVAS_REND_AudioBuffer outAudio ) { int8_t headRotEnabled; @@ -3491,7 +3462,7 @@ static ivas_error renderMcToBinaural( ivas_error error; IVAS_REND_AudioBuffer tmpRotBuffer; - wmops_sub_start("renderMcToBinaural"); + wmops_sub_start( "renderMcToBinaural" ); headRotEnabled = mcInput->base.ctx.pHeadRotData->headRotEnabled; inConfig = mcInput->base.inConfig; @@ -3539,11 +3510,7 @@ static ivas_error renderMcToBinaural( } /* call CREND */ - if ( ( error = ivas_rend_crendProcess( &mcInput->crendWrapper, - mcInput->base.inConfig, - outConfig, - tmpRendBuffer, - *mcInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_rend_crendProcess( &mcInput->crendWrapper, mcInput->base.inConfig, outConfig, tmpRendBuffer, *mcInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) { return error; } @@ -3561,7 +3528,7 @@ static ivas_error renderMcToBinaural( static ivas_error renderMcToBinauralRoom( input_mc *mcInput, - IVAS_REND_AudioConfig outConfig, + const IVAS_REND_AudioConfig outConfig, IVAS_REND_AudioBuffer outAudio ) { float tmpCrendBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; @@ -3569,7 +3536,7 @@ static ivas_error renderMcToBinauralRoom( ivas_error error; IVAS_REND_AudioBuffer tmpRotBuffer; - wmops_sub_start("renderMcToBinauralRoom"); + wmops_sub_start( "renderMcToBinauralRoom" ); /* apply rotation */ if ( mcInput->base.ctx.pHeadRotData->headRotEnabled ) @@ -3595,11 +3562,7 @@ static ivas_error renderMcToBinauralRoom( } /* call CREND */ - if ( ( error = ivas_rend_crendProcess( &mcInput->crendWrapper, - mcInput->base.inConfig, - outConfig, - tmpCrendBuffer, - *mcInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_rend_crendProcess( &mcInput->crendWrapper, mcInput->base.inConfig, outConfig, tmpCrendBuffer, *mcInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) { return error; } @@ -3617,20 +3580,21 @@ static ivas_error renderMcToBinauralRoom( static ivas_error renderMcCustomLsToBinauralRoom( input_mc *mcInput, - IVAS_REND_AudioConfig outConfig, + const IVAS_REND_AudioConfig outConfig, IVAS_REND_AudioBuffer outAudio ) { int8_t headRotEnabled; int16_t i; - int32_t tmp; + int16_t tmp; float tmpCrendBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; - ivas_error error; IVAS_REND_AudioBuffer tmpRotBuffer; IVAS_REND_AudioBuffer tmpMcBuffer; IVAS_REND_AudioBuffer *tmpBufPtr; - wmops_sub_start("renderMcCustomLsToBinauralRoom"); + wmops_sub_start( "renderMcCustomLsToBinauralRoom" ); + + tmpRotBuffer = outAudio; /* avoid compilation warning */ headRotEnabled = mcInput->base.ctx.pHeadRotData->headRotEnabled; @@ -3660,19 +3624,12 @@ static ivas_error renderMcCustomLsToBinauralRoom( tmpBufPtr = ( headRotEnabled ) ? &tmpRotBuffer : &mcInput->base.inputBuffer; for ( i = 0; i < mcInput->base.inputBuffer.config.numChannels; i++ ) { - renderBufferChannel( *tmpBufPtr, - i, - mcInput->panGains[i], - tmpMcBuffer ); + renderBufferChannel( *tmpBufPtr, i, mcInput->panGains[i], tmpMcBuffer ); } copyBufferTo2dArray( tmpMcBuffer, tmpCrendBuffer ); /* call CREND */ - if ( ( error = ivas_rend_crendProcess( &mcInput->crendWrapper, - IVAS_REND_AUDIO_CONFIG_7_1_4, - outConfig, - tmpCrendBuffer, - *mcInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_rend_crendProcess( &mcInput->crendWrapper, IVAS_REND_AUDIO_CONFIG_7_1_4, outConfig, tmpCrendBuffer, *mcInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) { return error; } @@ -3697,10 +3654,10 @@ static ivas_error renderMcToMc( const input_mc *mcInput, IVAS_REND_AudioBuffer outAudio ) { - int32_t i; + int16_t i; IVAS_REND_AudioBuffer inAudio; - wmops_sub_start("renderMcToMc"); + wmops_sub_start( "renderMcToMc" ); inAudio = mcInput->base.inputBuffer; @@ -3718,10 +3675,10 @@ static ivas_error renderMcToSba( const input_mc *mcInput, IVAS_REND_AudioBuffer outAudio ) { - int32_t i; + int16_t i; IVAS_REND_AudioBuffer inAudio; - wmops_sub_start("renderMcToSba"); + wmops_sub_start( "renderMcToSba" ); inAudio = mcInput->base.inputBuffer; @@ -3802,7 +3759,7 @@ static ivas_error renderActiveInputsMc( IVAS_REND_HANDLE hIvasRend, IVAS_REND_AudioBuffer outAudio ) { - int32_t i; + int16_t i; input_mc *pCurrentInput; ivas_error error; @@ -3813,10 +3770,7 @@ static ivas_error renderActiveInputsMc( /* Skip inactive inputs */ continue; } - - if ( ( error = renderInputMc( pCurrentInput, - hIvasRend->outputConfig, - outAudio ) ) != IVAS_ERR_OK ) + if ( ( error = renderInputMc( pCurrentInput, hIvasRend->outputConfig, outAudio ) ) != IVAS_ERR_OK ) { return error; } @@ -3829,10 +3783,10 @@ static ivas_error renderSbaToMc( const input_sba *sbaInput, IVAS_REND_AudioBuffer outAudio ) { - int32_t i; + int16_t i; IVAS_REND_AudioBuffer inAudio; - wmops_sub_start("renderSbaToMc"); + wmops_sub_start( "renderSbaToMc" ); inAudio = sbaInput->base.inputBuffer; @@ -3850,10 +3804,10 @@ static ivas_error renderSbaToSba( const input_sba *sbaInput, IVAS_REND_AudioBuffer outAudio ) { - int32_t i; + int16_t i; IVAS_REND_AudioBuffer inAudio; - wmops_sub_start("renderSbaToSba"); + wmops_sub_start( "renderSbaToSba" ); inAudio = sbaInput->base.inputBuffer; @@ -3869,7 +3823,7 @@ static ivas_error renderSbaToSba( static ivas_error renderSbaToBinaural( input_sba *sbaInput, - IVAS_REND_AudioConfig outConfig, + const IVAS_REND_AudioConfig outConfig, IVAS_REND_AudioBuffer outAudio ) { float tmpCrendBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; @@ -3877,7 +3831,7 @@ static ivas_error renderSbaToBinaural( ivas_error error; IVAS_REND_AudioBuffer tmpRotBuffer; - wmops_sub_start("renderSbaToBinaural"); + wmops_sub_start( "renderSbaToBinaural" ); /* apply rotation */ if ( sbaInput->base.ctx.pHeadRotData->headRotEnabled ) @@ -3903,11 +3857,7 @@ static ivas_error renderSbaToBinaural( } /* call CREND */ - if ( ( error = ivas_rend_crendProcess( &sbaInput->crendWrapper, - sbaInput->base.inConfig, - outConfig, - tmpCrendBuffer, - *sbaInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_rend_crendProcess( &sbaInput->crendWrapper, sbaInput->base.inConfig, outConfig, tmpCrendBuffer, *sbaInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) { return error; } @@ -3921,12 +3871,12 @@ static ivas_error renderSbaToBinaural( static ivas_error renderSbaToBinauralRoom( input_sba *sbaInput, - IVAS_REND_AudioConfig outConfig, + const IVAS_REND_AudioConfig outConfig, IVAS_REND_AudioBuffer outAudio ) { int8_t headRotEnabled; int16_t i; - int32_t tmp; + int16_t tmp; float tmpCrendBuffer[MAX_OUTPUT_CHANNELS][L_FRAME48k]; ivas_error error; @@ -3934,7 +3884,9 @@ static ivas_error renderSbaToBinauralRoom( IVAS_REND_AudioBuffer tmpMcBuffer; IVAS_REND_AudioBuffer *tmpBufPtr; - wmops_sub_start("renderSbaToBinauralRoom"); + tmpRotBuffer = outAudio; /* avoid compilation warning */ + + wmops_sub_start( "renderSbaToBinauralRoom" ); headRotEnabled = sbaInput->base.ctx.pHeadRotData->headRotEnabled; @@ -3944,14 +3896,9 @@ static ivas_error renderSbaToBinauralRoom( tmpRotBuffer = sbaInput->base.inputBuffer; tmpRotBuffer.data = count_malloc( tmpRotBuffer.config.numSamplesPerChannel * tmpRotBuffer.config.numChannels * sizeof( float ) ); /* copy input for in-place rotation */ - mvr2r( sbaInput->base.inputBuffer.data, tmpRotBuffer.data, - tmpRotBuffer.config.numChannels * tmpRotBuffer.config.numSamplesPerChannel ); + mvr2r( sbaInput->base.inputBuffer.data, tmpRotBuffer.data, tmpRotBuffer.config.numChannels * tmpRotBuffer.config.numSamplesPerChannel ); - rotateFrameSba( sbaInput->base.inputBuffer, - sbaInput->base.inConfig, - sbaInput->base.ctx.pHeadRotData, - sbaInput->rot_gains_prev, - tmpRotBuffer ); + rotateFrameSba( sbaInput->base.inputBuffer, sbaInput->base.inConfig, sbaInput->base.ctx.pHeadRotData, sbaInput->rot_gains_prev, tmpRotBuffer ); } /* intermediate rendering to 7_1_4 */ @@ -3959,26 +3906,18 @@ static ivas_error renderSbaToBinauralRoom( getAudioConfigNumChannels( IVAS_REND_AUDIO_CONFIG_7_1_4, &tmp ); tmpMcBuffer.config.numChannels = (int16_t) tmp; tmpMcBuffer.data = count_malloc( tmpMcBuffer.config.numSamplesPerChannel * tmpMcBuffer.config.numChannels * sizeof( float ) ); - set_zero( tmpMcBuffer.data, - tmpMcBuffer.config.numChannels * tmpMcBuffer.config.numSamplesPerChannel ); + set_zero( tmpMcBuffer.data, tmpMcBuffer.config.numChannels * tmpMcBuffer.config.numSamplesPerChannel ); tmpBufPtr = ( headRotEnabled ) ? &tmpRotBuffer : &sbaInput->base.inputBuffer; for ( i = 0; i < sbaInput->base.inputBuffer.config.numChannels; i++ ) { - renderBufferChannel( *tmpBufPtr, - i, - sbaInput->hoaDecMtx[i], - tmpMcBuffer ); + renderBufferChannel( *tmpBufPtr, i, sbaInput->hoaDecMtx[i], tmpMcBuffer ); } copyBufferTo2dArray( tmpMcBuffer, tmpCrendBuffer ); /* call CREND */ - if ( ( error = ivas_rend_crendProcess( &sbaInput->crendWrapper, - IVAS_REND_AUDIO_CONFIG_7_1_4, - outConfig, - tmpCrendBuffer, - *sbaInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_rend_crendProcess( &sbaInput->crendWrapper, IVAS_REND_AUDIO_CONFIG_7_1_4, outConfig, tmpCrendBuffer, *sbaInput->base.ctx.pOutSampleRate ) ) != IVAS_ERR_OK ) { return error; } @@ -3998,7 +3937,7 @@ static ivas_error renderSbaToBinauralRoom( static ivas_error renderInputSba( input_sba *sbaInput, - IVAS_REND_AudioConfig outConfig, + const IVAS_REND_AudioConfig outConfig, IVAS_REND_AudioBuffer outAudio ) { ivas_error error; @@ -4056,7 +3995,7 @@ static ivas_error renderActiveInputsSba( IVAS_REND_HANDLE hIvasRend, IVAS_REND_AudioBuffer outAudio ) { - int32_t i; + int16_t i; input_sba *pCurrentInput; ivas_error error; @@ -4067,9 +4006,8 @@ static ivas_error renderActiveInputsSba( /* Skip inactive inputs */ continue; } - if ( ( error = renderInputSba( pCurrentInput, - hIvasRend->outputConfig, - outAudio ) ) != IVAS_ERR_OK ) + + if ( ( error = renderInputSba( pCurrentInput, hIvasRend->outputConfig, outAudio ) ) != IVAS_ERR_OK ) { return error; } @@ -4083,7 +4021,7 @@ ivas_error IVAS_REND_GetSamples( IVAS_REND_AudioBuffer outAudio ) { ivas_error error; - int32_t numOutChannels; + int16_t numOutChannels; /*-----------------------------------------------------------------* * Validate function arguments @@ -4140,9 +4078,10 @@ ivas_error IVAS_REND_GetSamples( return IVAS_ERR_OK; } -void IVAS_REND_Close( IVAS_REND_HANDLE *phIvasRend ) +void IVAS_REND_Close( + IVAS_REND_HANDLE *phIvasRend ) { - uint32_t i; + uint16_t i; IVAS_REND_HANDLE hIvasRend; /*-----------------------------------------------------------------* @@ -4177,11 +4116,12 @@ void IVAS_REND_Close( IVAS_REND_HANDLE *phIvasRend ) /* clear Config. Renderer */ ivas_render_config_close( &( hIvasRend->hRendererConfig ) ); - ivas_limiter_close( &hIvasRend->hLimiter ); count_free( hIvasRend ); *phIvasRend = NULL; + + return; } #ifdef DEBUGGING diff --git a/lib_rend/lib_rend.h b/lib_rend/lib_rend.h index 924bc0e6fe..831823ad60 100644 --- a/lib_rend/lib_rend.h +++ b/lib_rend/lib_rend.h @@ -132,11 +132,11 @@ typedef enum IVAS_REND_AUDIO_CONFIG_UNKNOWN = IVAS_REND_AUDIO_CONFIG_TYPE_UNKNOWN << 8 | 0, } IVAS_REND_AudioConfig; -typedef uint32_t IVAS_REND_InputId; +typedef uint16_t IVAS_REND_InputId; typedef struct { - int32_t numLfeChannels; + int16_t numLfeChannels; float lfeOutputGains[IVAS_MAX_INPUT_LFE_CHANNELS][IVAS_MAX_OUTPUT_CHANNELS]; } IVAS_REND_LfeRouting; @@ -149,14 +149,14 @@ typedef struct ivas_error IVAS_REND_Open( IVAS_REND_HANDLE *phIvasRend, /* i/o: Pointer to renderer handle */ - int32_t outputSampleRate, /* i : output sampling rate */ - IVAS_REND_AudioConfig outConfig /* i : output audio config */ + const int32_t outputSampleRate, /* i : output sampling rate */ + const IVAS_REND_AudioConfig outConfig /* i : output audio config */ ); /* Note: this will reset custom LFE routings set for any MC input */ ivas_error IVAS_REND_ConfigureCustomOutputLoudspeakerLayout( IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ - IVAS_CUSTOM_LS_DATA layout /* i : custom loudspeaker layout for renderer output */ + const IVAS_CUSTOM_LS_DATA layout /* i : custom loudspeaker layout for renderer output */ ); /* Support for custom HRTFs will be added in the future. */ @@ -170,43 +170,43 @@ ivas_error IVAS_REND_SetCustomHrtf( ivas_error IVAS_REND_NumOutChannels( IVAS_REND_CONST_HANDLE hIvasRend, /* i : Renderer handle */ - int32_t *numOutChannels /* o : number of output channels */ + int16_t *numOutChannels /* o : number of output channels */ ); ivas_error IVAS_REND_AddInput( IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ - IVAS_REND_AudioConfig inConfig, /* i : audio config for a new input */ + const IVAS_REND_AudioConfig inConfig, /* i : audio config for a new input */ IVAS_REND_InputId *inputId /* o : ID of the new input */ ); /* Note: this will reset any custom LFE routing set for the input */ ivas_error IVAS_REND_ConfigureCustomInputLoudspeakerLayout( IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ - IVAS_REND_InputId inputId, /* i : ID of the input */ - IVAS_CUSTOM_LS_DATA layout /* i : custom loudspeaker layout for input */ + const IVAS_REND_InputId inputId, /* i : ID of the input */ + const IVAS_CUSTOM_LS_DATA layout /* i : custom loudspeaker layout for input */ ); ivas_error IVAS_REND_SetInputGain( IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ - IVAS_REND_InputId inputId, /* i : ID of the input */ - float gain /* i : linear gain (not in dB) */ + const IVAS_REND_InputId inputId, /* i : ID of the input */ + const float gain /* i : linear gain (not in dB) */ ); ivas_error IVAS_REND_SetInputLfeRouting( IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ - IVAS_REND_InputId inputId, /* i : ID of the input */ - IVAS_REND_LfeRouting lfeRouting /* i : custom LFE routing struct */ + const IVAS_REND_InputId inputId, /* i : ID of the input */ + const IVAS_REND_LfeRouting lfeRouting /* i : custom LFE routing struct */ ); ivas_error IVAS_REND_RemoveInput( IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ - IVAS_REND_InputId inputId /* i : ID of the input */ + const IVAS_REND_InputId inputId /* i : ID of the input */ ); ivas_error IVAS_REND_GetInputNumChannels( IVAS_REND_CONST_HANDLE hIvasRend, /* i : Renderer handle */ - IVAS_REND_InputId inputId, /* i : ID of the input */ - int32_t *numChannels /* o : number of channels of the input */ + const IVAS_REND_InputId inputId, /* i : ID of the input */ + int16_t *numChannels /* o : number of channels of the input */ ); ivas_error IVAS_REND_GetDelay( @@ -219,20 +219,20 @@ ivas_error IVAS_REND_GetDelay( ivas_error IVAS_REND_FeedInputAudio( IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ - IVAS_REND_InputId inputId, /* i : ID of the input */ - IVAS_REND_ReadOnlyAudioBuffer inputAudio /* i : buffer with input audio */ + const IVAS_REND_InputId inputId, /* i : ID of the input */ + const IVAS_REND_ReadOnlyAudioBuffer inputAudio /* i : buffer with input audio */ ); ivas_error IVAS_REND_FeedInputObjectMetadata( IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ - IVAS_REND_InputId inputId, /* i : ID of the input */ - IVAS_REND_AudioObjectPosition objectPosition /* i : object position struct */ + const IVAS_REND_InputId inputId, /* i : ID of the input */ + const IVAS_REND_AudioObjectPosition objectPosition /* i : object position struct */ ); /* Support for MASA input will be added in the future. */ ivas_error IVAS_REND_FeedInputMasaMetadata( IVAS_REND_HANDLE hIvasRend, /* i/o: Renderer handle */ - IVAS_REND_InputId inputId, /* i : ID of the input */ + const IVAS_REND_InputId inputId, /* i : ID of the input */ void* TODO ); -- GitLab From 1fce6cf4c04fc7f0c5be331dc7e1ea93caa75cc6 Mon Sep 17 00:00:00 2001 From: Archit Tamarapu Date: Tue, 8 Nov 2022 17:32:53 +0100 Subject: [PATCH 085/101] [tests] add more information about xfail reasons - correct path to MASA test files - address a TODO for EFAP --- lib_rend/ivas_efap.c | 4 ++ tests/renderer/constants.py | 93 +++++++++++++++++++++---------------- 2 files changed, 56 insertions(+), 41 deletions(-) diff --git a/lib_rend/ivas_efap.c b/lib_rend/ivas_efap.c index 8a3dd6ad05..8314d3117f 100644 --- a/lib_rend/ivas_efap.c +++ b/lib_rend/ivas_efap.c @@ -155,8 +155,12 @@ ivas_error efap_init_data( if ( !speaker_node_azi_deg || !speaker_node_ele_deg ) { hEFAPdata = NULL; +#ifdef EXT_RENDERER + return IVAS_ERROR( IVAS_ERR_WRONG_PARAMS, "EFAP requires arrays of speaker azimuths and elevations" ); +#else /* TODO: is this path correct behaviour or and error ? */ return IVAS_ERR_OK; +#endif } /*-----------------------------------------------------------------* diff --git a/tests/renderer/constants.py b/tests/renderer/constants.py index ff2e008438..1cefbda25d 100644 --- a/tests/renderer/constants.py +++ b/tests/renderer/constants.py @@ -149,10 +149,10 @@ FORMAT_TO_FILE = { # "ISM2": TEST_VECTOR_DIR.joinpath("spectral_test_ism2.txt"), # "ISM3": TEST_VECTOR_DIR.joinpath("spectral_test_ism3.txt"), # "ISM4": TEST_VECTOR_DIR.joinpath("spectral_test_ism4.txt"), - "MASA1": NCHAN_TO_FILE[1], - "MASA2": NCHAN_TO_FILE[2], - # "MASA1": TEST_VECTOR_DIR.joinpath("stv_IVASMASA_1dir1TC.pcm"), - # "MASA2": TEST_VECTOR_DIR.joinpath("stv_IVASMASA_2dir2TC.pcm"), + # "MASA1": NCHAN_TO_FILE[1], + # "MASA2": NCHAN_TO_FILE[2], + "MASA1": TESTV_DIR.joinpath("stv_IVASMASA_1dir1TC.pcm"), + "MASA2": TESTV_DIR.joinpath("stv_IVASMASA_2dir2TC.pcm"), "META": TEST_VECTOR_DIR.joinpath("mixed_scene.txt"), "16ch_8+4+4": NCHAN_TO_FILE[16], "4d0": NCHAN_TO_FILE[4], @@ -182,8 +182,8 @@ FORMAT_TO_METADATA_FILES = { str(TESTV_DIR.joinpath("stvISM3.csv")), str(TESTV_DIR.joinpath("stvISM4.csv")), ], - "MASA1": [str(TESTV_DIR.joinpath("stv_IVASMASAQ_1dir1TC.met"))], - "MASA2": [str(TESTV_DIR.joinpath("stv_IVASMASAQ_2dir2TC.met"))], + "MASA1": [str(TESTV_DIR.joinpath("stv_IVASMASA_1dir1TC.met"))], + "MASA2": [str(TESTV_DIR.joinpath("stv_IVASMASA_2dir2TC.met"))], } FORMAT_TO_IVAS = { @@ -284,7 +284,8 @@ pass_snr = { # TODO needs debugging "test_ambisonics_binaural_headrotation[HOA2-BINAURAL-full_circle_in_15s]": 18, "test_ambisonics_binaural_headrotation[HOA3-BINAURAL-full_circle_in_15s]": 15, - # Crend unit test does not support SHD BRIRs + # Failure reason: Crend unit test does not support intermediate conversion to 7_1_4 or SHD BRIRs + # Comparison with pyaudio3dtools results in bad SNR "test_ambisonics_binaural_headrotation[FOA-BINAURAL_ROOM-full_circle_in_15s]": 0, "test_ambisonics_binaural_headrotation[FOA-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 0, "test_ambisonics_binaural_headrotation[HOA2-BINAURAL_ROOM-full_circle_in_15s]": 0, @@ -296,8 +297,8 @@ pass_snr = { "test_ambisonics_binaural_static[FOA-BINAURAL_ROOM]": 0, "test_ambisonics_binaural_static[HOA2-BINAURAL_ROOM]": 0, "test_ambisonics_binaural_static[HOA3-BINAURAL_ROOM]": 0, - # TD Object Renderer used internally, comparison to pyaudio3dtools has bad SNR - # TD Object Renderer standalone does not support custom LS + # Failure reason: TD Object Renderer standalone does not support custom LS input + # Comparison with pyaudio3dtools results in bad SNR "test_custom_ls_input_binaural[16ch_8+4+4-BINAURAL]": 0, "test_custom_ls_input_binaural[16ch_8+4+4-BINAURAL_ROOM]": 0, "test_custom_ls_input_binaural[4d4-BINAURAL]": 0, @@ -322,9 +323,9 @@ pass_snr = { "test_custom_ls_input_binaural[itu_4+5+1-BINAURAL_ROOM]": 3, "test_custom_ls_input_binaural[t_design_4-BINAURAL]": 0, "test_custom_ls_input_binaural[t_design_4-BINAURAL_ROOM]": 0, - # Crend used internally, comparison to pyaudio3dtools has bad SNR - # Crend unit test does not support ISM rendering - # 5ms rendering still TODO in renderer + # TODO need to verify 5ms rendering in external renderer + # Crend unit test does not support intermediate conversion to 7_1_4 + # Comparison with pyaudio3dtools results in bad SNR "test_ism_binaural_headrotation[ISM1-BINAURAL_ROOM-full_circle_in_15s]": 9, "test_ism_binaural_headrotation[ISM1-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 4, "test_ism_binaural_headrotation[ISM2-BINAURAL_ROOM-full_circle_in_15s]": 10, @@ -340,7 +341,8 @@ pass_snr = { "test_ism_binaural_static[ISM2-BINAURAL_ROOM]": 21, "test_ism_binaural_static[ISM3-BINAURAL_ROOM]": 21, "test_ism_binaural_static[ISM4-BINAURAL_ROOM]": 21, - # TODO needs debugging, minor differences could be due to crossfades or metadata position rounding + # TODO needs debugging + # Failure reason: minor differences could be due to crossfades or metadata position rounding "test_ism[ISM1-5_1_2]": 48, "test_ism[ISM1-5_1_4]": 48, "test_ism[ISM1-5_1]": 48, @@ -377,19 +379,26 @@ pass_snr = { "test_ism[ISM4-HOA2]": 36, "test_ism[ISM4-HOA3]": 33, "test_ism[ISM4-STEREO]": 57, - # bitexact except for delay alignment of LFE signal (Issue 59) + # TODO delay alignment of LFE in binaural output + # Failure reason: bitexact except for delay alignment of LFE signal (Issue 59) "test_multichannel_binaural_headrotation[5_1-BINAURAL-full_circle_in_15s]": 7, "test_multichannel_binaural_headrotation[5_1-BINAURAL-rotate_yaw_pitch_roll1]": 6, "test_multichannel_binaural_headrotation[7_1-BINAURAL-full_circle_in_15s]": 8, "test_multichannel_binaural_headrotation[7_1-BINAURAL-rotate_yaw_pitch_roll1]": 8, - # TODO minor differences, needs debugging + # Failure reason: bitexact except for clicks and differences in center channel, could be due to crossfades "test_multichannel_binaural_headrotation[5_1_2-BINAURAL-full_circle_in_15s]": 30, "test_multichannel_binaural_headrotation[5_1_2-BINAURAL-rotate_yaw_pitch_roll1]": 30, "test_multichannel_binaural_headrotation[5_1_4-BINAURAL-full_circle_in_15s]": 29, "test_multichannel_binaural_headrotation[5_1_4-BINAURAL-rotate_yaw_pitch_roll1]": 29, "test_multichannel_binaural_headrotation[7_1_4-BINAURAL-full_circle_in_15s]": 30, "test_multichannel_binaural_headrotation[7_1_4-BINAURAL-rotate_yaw_pitch_roll1]": 30, - # headrotation may be applied differently + "test_multichannel_binaural_static[5_1_2-BINAURAL]": 30, + "test_multichannel_binaural_static[5_1_4-BINAURAL]": 29, + "test_multichannel_binaural_static[5_1-BINAURAL]": 27, + "test_multichannel_binaural_static[7_1-BINAURAL]": 30, + "test_multichannel_binaural_static[7_1_4-BINAURAL]": 30, + # TODO needs debugging + # Failure reason: headrotation may be applied differently, differences increase progressively "test_multichannel_binaural_headrotation[5_1-BINAURAL_ROOM-full_circle_in_15s]": 10, "test_multichannel_binaural_headrotation[5_1-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 4, "test_multichannel_binaural_headrotation[5_1_2-BINAURAL_ROOM-full_circle_in_15s]": 11, @@ -400,39 +409,38 @@ pass_snr = { "test_multichannel_binaural_headrotation[7_1-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 3, "test_multichannel_binaural_headrotation[7_1_4-BINAURAL_ROOM-full_circle_in_15s]": 10, "test_multichannel_binaural_headrotation[7_1_4-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 3, - # TODO minor differences, needs debugging (same as headrotation case) - "test_multichannel_binaural_static[5_1_2-BINAURAL]": 30, - "test_multichannel_binaural_static[5_1_4-BINAURAL]": 29, - "test_multichannel_binaural_static[5_1-BINAURAL]": 27, - "test_multichannel_binaural_static[7_1-BINAURAL]": 30, - "test_multichannel_binaural_static[7_1_4-BINAURAL]": 30, ##################################### # # External vs Internal Renderer tests # ##################################### - # TODO conversion to 7_1_4 might be different (as indicated by next section of tests), needs debugging + # Failure reason: only fails for this trajectory with very high SNR, possible minor diff. in crossfade + # or due to usage of multiple TD Object Renderer instances + "test_ism_binaural_headrotation_vs_decoder[ISM2-BINAURAL-rotate_yaw_pitch_roll1]": 84, + "test_ism_binaural_headrotation_vs_decoder[ISM3-BINAURAL-rotate_yaw_pitch_roll1]": 78, + "test_ism_binaural_headrotation_vs_decoder[ISM4-BINAURAL-rotate_yaw_pitch_roll1]": 85, + # TODO needs investigation + # Failure reason: conversion to 7_1_4 could be implemented differently w.r.t decoder "test_ism_binaural_headrotation_vs_decoder[ISM1-BINAURAL_ROOM-full_circle_in_15s]": 15, "test_ism_binaural_headrotation_vs_decoder[ISM1-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 15, "test_ism_binaural_headrotation_vs_decoder[ISM2-BINAURAL_ROOM-full_circle_in_15s]": 12, "test_ism_binaural_headrotation_vs_decoder[ISM2-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 13, - "test_ism_binaural_headrotation_vs_decoder[ISM2-BINAURAL-rotate_yaw_pitch_roll1]": 84, "test_ism_binaural_headrotation_vs_decoder[ISM3-BINAURAL_ROOM-full_circle_in_15s]": 12, "test_ism_binaural_headrotation_vs_decoder[ISM3-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 13, - "test_ism_binaural_headrotation_vs_decoder[ISM3-BINAURAL-rotate_yaw_pitch_roll1]": 78, "test_ism_binaural_headrotation_vs_decoder[ISM4-BINAURAL_ROOM-full_circle_in_15s]": 12, "test_ism_binaural_headrotation_vs_decoder[ISM4-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 13, - "test_ism_binaural_headrotation_vs_decoder[ISM4-BINAURAL-rotate_yaw_pitch_roll1]": 85, "test_ism_binaural_static_vs_decoder[ISM1-BINAURAL_ROOM]": 15, "test_ism_binaural_static_vs_decoder[ISM2-BINAURAL_ROOM]": 12, "test_ism_binaural_static_vs_decoder[ISM3-BINAURAL_ROOM]": 12, "test_ism_binaural_static_vs_decoder[ISM4-BINAURAL_ROOM]": 12, - # TODO ISM to stereo panning is done via EFAP in the renderer and tangent law in decoder, harmonize + # TODO harmonize panning to stereo + # Failure reason ISM to stereo panning is done via EFAP in the renderer and tangent law in decoder, harmonize "test_ism_vs_decoder[ISM1-STEREO]": 8, "test_ism_vs_decoder[ISM2-STEREO]": 17, "test_ism_vs_decoder[ISM3-STEREO]": 14, "test_ism_vs_decoder[ISM4-STEREO]": 14, - # TODO loudspeaker and ambisonics rendering could be due to crossfades or metadata position rounding + # TODO needs investigation + # Failure reason: likely differences between metadata position rounding (decoder uses ceil()) and crossfades "test_ism_vs_decoder[ISM1-5_1_2]": 26, "test_ism_vs_decoder[ISM1-5_1]": 26, "test_ism_vs_decoder[ISM1-5_1_4]": 26, @@ -467,43 +475,46 @@ pass_snr = { "test_ism_vs_decoder[ISM4-HOA2]": 30, "test_ism_vs_decoder[ISM4-HOA3]": 29, "test_ism_vs_decoder[ISM4-MONO]": 77, - # TODO needs debugging + # TODO needs investigation + # Failure reason: headrotation and crossfade could have differences "test_multichannel_binaural_headrotation_vs_decoder[5_1_2-BINAURAL-full_circle_in_15s]": 4, - "test_multichannel_binaural_headrotation_vs_decoder[5_1_2-BINAURAL_ROOM-full_circle_in_15s]": 6, - "test_multichannel_binaural_headrotation_vs_decoder[5_1_2-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 0, "test_multichannel_binaural_headrotation_vs_decoder[5_1_2-BINAURAL-rotate_yaw_pitch_roll1]": 0, "test_multichannel_binaural_headrotation_vs_decoder[5_1_4-BINAURAL-full_circle_in_15s]": 4, - "test_multichannel_binaural_headrotation_vs_decoder[5_1_4-BINAURAL_ROOM-full_circle_in_15s]": 7, - "test_multichannel_binaural_headrotation_vs_decoder[5_1_4-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 0, "test_multichannel_binaural_headrotation_vs_decoder[5_1_4-BINAURAL-rotate_yaw_pitch_roll1]": 0, - "test_multichannel_binaural_headrotation_vs_decoder[5_1-BINAURAL_ROOM-full_circle_in_15s]": 5, - "test_multichannel_binaural_headrotation_vs_decoder[5_1-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 0, "test_multichannel_binaural_headrotation_vs_decoder[7_1_4-BINAURAL-full_circle_in_15s]": 4, - "test_multichannel_binaural_headrotation_vs_decoder[7_1_4-BINAURAL_ROOM-full_circle_in_15s]": 5, - "test_multichannel_binaural_headrotation_vs_decoder[7_1_4-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 0, "test_multichannel_binaural_headrotation_vs_decoder[7_1_4-BINAURAL-rotate_yaw_pitch_roll1]": 0, + # TODO needs investigation + "test_multichannel_binaural_headrotation_vs_decoder[5_1-BINAURAL_ROOM-full_circle_in_15s]": 5, + "test_multichannel_binaural_headrotation_vs_decoder[5_1-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 0, + "test_multichannel_binaural_headrotation_vs_decoder[5_1_2-BINAURAL_ROOM-full_circle_in_15s]": 6, + "test_multichannel_binaural_headrotation_vs_decoder[5_1_2-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 0, + "test_multichannel_binaural_headrotation_vs_decoder[5_1_4-BINAURAL_ROOM-full_circle_in_15s]": 7, + "test_multichannel_binaural_headrotation_vs_decoder[5_1_4-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 0, "test_multichannel_binaural_headrotation_vs_decoder[7_1-BINAURAL_ROOM-full_circle_in_15s]": 5, "test_multichannel_binaural_headrotation_vs_decoder[7_1-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 0, - # TODO needs debugging + "test_multichannel_binaural_headrotation_vs_decoder[7_1_4-BINAURAL_ROOM-full_circle_in_15s]": 5, + "test_multichannel_binaural_headrotation_vs_decoder[7_1_4-BINAURAL_ROOM-rotate_yaw_pitch_roll1]": 0, + # TODO needs investigation "test_multichannel_binaural_static_vs_decoder[5_1_2-BINAURAL_ROOM]": 18, "test_multichannel_binaural_static_vs_decoder[5_1_4-BINAURAL_ROOM]": 18, "test_multichannel_binaural_static_vs_decoder[5_1-BINAURAL_ROOM]": 18, "test_multichannel_binaural_static_vs_decoder[7_1_4-BINAURAL_ROOM]": 18, "test_multichannel_binaural_static_vs_decoder[7_1-BINAURAL_ROOM]": 19, - # TODO Mono downmix significantly different, needs a fix + # Failure reason: Mono downmix significantly different, needs a fix "test_multichannel_vs_decoder[5_1_2-MONO]": 1, "test_multichannel_vs_decoder[5_1_4-MONO]": 1, "test_multichannel_vs_decoder[5_1-MONO]": 1, "test_multichannel_vs_decoder[7_1_4-MONO]": 1, "test_multichannel_vs_decoder[7_1-MONO]": 1, "test_multichannel_vs_decoder[STEREO-MONO]": 17, - # TODO Stereo downmix differs slightly, needs debugging + # Failure reason: Stereo downmix differs slightly, needs a fix "test_multichannel_vs_decoder[5_1_2-STEREO]": 44, "test_multichannel_vs_decoder[5_1_4-STEREO]": 48, "test_multichannel_vs_decoder[5_1-STEREO]": 48, "test_multichannel_vs_decoder[7_1_4-STEREO]": 46, "test_multichannel_vs_decoder[7_1-STEREO]": 44, - # TODO minor differences, needs debugging + # TODO needs investigation + # Failure reason: possibly due to minor differences in crossfades "test_multichannel_vs_decoder[5_1_2-5_1_4]": 63, "test_multichannel_vs_decoder[5_1_2-5_1]": 63, "test_multichannel_vs_decoder[5_1_2-7_1_4]": 63, -- GitLab From 202bcfa4c994d7218181df14cec952c1c784520a Mon Sep 17 00:00:00 2001 From: Archit Tamarapu Date: Tue, 8 Nov 2022 18:12:24 +0100 Subject: [PATCH 086/101] [cleanup] accept FIX_I173_I174 in renderer_standalone.c to fix pipeline --- .../renderer_standalone.c | 38 ------------------- 1 file changed, 38 deletions(-) diff --git a/scripts/td_object_renderer/object_renderer_standalone/object_renderer_standalone/renderer_standalone.c b/scripts/td_object_renderer/object_renderer_standalone/object_renderer_standalone/renderer_standalone.c index 82c4d83abc..8f5b5354ae 100644 --- a/scripts/td_object_renderer/object_renderer_standalone/object_renderer_standalone/renderer_standalone.c +++ b/scripts/td_object_renderer/object_renderer_standalone/object_renderer_standalone/renderer_standalone.c @@ -52,11 +52,7 @@ *------------------------------------------------------------------------------------------*/ #define META_LINE_LENGTH 200 /* max number of characters at one line of metadata input/output file */ -#ifdef FIX_I173_I174 #define NUM_ISM_METADATA_PER_LINE 4 /* Number of ISM metadata per line in a metadata file */ -#else -#define NUM_ISM_METADATA_PER_LINE 5 /* Number of ISM metadata per line in a metadata file */ -#endif /*---------------------------------------------------------------------* * Local function prototypes @@ -130,9 +126,6 @@ int main( int argc, char *argv[] ) FILE *f_input; FILE *f_output; FILE *f_quat_traj; -#ifndef FIX_I173_I174 - int32_t tmp; -#endif float x, y, z, w; FILE *f_metadata[MAX_NUM_OBJECTS]; Decoder_Struct st_ivas_static; @@ -166,9 +159,7 @@ int main( int argc, char *argv[] ) { return IVAS_ERR_FAILED_ALLOC; } -#ifdef FIX_I173_I174 st_ivas->hDecoderConfig->Opt_Headrotation = FALSE; -#endif /* ISm metadata handles */ for ( n = 0; n < MAX_NUM_OBJECTS; n++ ) @@ -325,9 +316,7 @@ int main( int argc, char *argv[] ) fprintf( stderr, "Can not allocate memory for head-tracking\n" ); exit( -1 ); } -#ifdef FIX_I173_I174 st_ivas->hDecoderConfig->Opt_Headrotation = TRUE; -#endif } else { @@ -407,11 +396,7 @@ int main( int argc, char *argv[] ) { for ( i = 0; i < 4; i++ ) /* MAX_PARAM_SPATIAL_SUBFRAMES = 4 */ { -#ifdef FIX_I173_I174 if ( 4 == fscanf( f_quat_traj, "%f,%f,%f,%f", &w, &x, &y, &z ) ) -#else - if ( 5 == fscanf( f_quat_traj, "%d,%f,%f,%f,%f", &tmp, &w, &x, &y, &z ) ) -#endif { st_ivas->hHeadTrackData->num_quaternions = -1; @@ -559,9 +544,6 @@ static void readMetadata( float meta_prm[NUM_ISM_METADATA_PER_LINE]; char *char_ptr; int16_t j; -#ifndef FIX_I173_I174 - int32_t time_stamp; -#endif if ( fgets( char_buff, META_LINE_LENGTH, file ) == NULL ) { @@ -569,33 +551,13 @@ static void readMetadata( exit( -1 ); } -#ifdef FIX_I173_I174 j = 0; char_ptr = strtok( char_buff, "," ); meta_prm[j++] = (float) atof( char_ptr ); -#else - char_ptr = strtok( char_buff, "," ); -#ifndef FIX_I173_I174 - time_stamp = (int32_t) atoi( char_ptr ); - - if ( time_stamp != frame ) - { - fprintf( stderr, "\n!!!Error: Wrong time-stamp while reading ISM metadata input file. Exiting!!!\n\n" ); - exit( -1 ); - } -#endif - - j = 0; -#endif while ( char_ptr != NULL && j < NUM_ISM_METADATA_PER_LINE ) { -#ifndef FIX_I173_I174 - meta_prm[j++] = (float) atof( char_ptr ); - char_ptr = strtok( NULL, "," ); -#else char_ptr = strtok( NULL, "," ); meta_prm[j++] = (float) atof( char_ptr ); -#endif } hIsmMetaData->azimuth = meta_prm[0]; -- GitLab From 53d4d17e9907c02b0cafcb65eaa63bfe98f0629f Mon Sep 17 00:00:00 2001 From: Archit Tamarapu Date: Tue, 8 Nov 2022 18:21:22 +0100 Subject: [PATCH 087/101] [formatting] apply clang-format patch from CI job --- lib_rend/ivas_rotation.c | 28 ++++++++++++++-------------- lib_rend/ivas_stat_rend.h | 9 +++++---- lib_rend/lib_rend.c | 2 +- 3 files changed, 20 insertions(+), 19 deletions(-) diff --git a/lib_rend/ivas_rotation.c b/lib_rend/ivas_rotation.c index 372930616f..e3c6ee6985 100644 --- a/lib_rend/ivas_rotation.c +++ b/lib_rend/ivas_rotation.c @@ -108,7 +108,7 @@ void QuatToRotMat( #else const Quaternion quat, /* i : quaternion describing the rotation */ #endif - float Rmat[3][3] /* o : real-space rotation matrix for this rotation */ + float Rmat[3][3] /* o : real-space rotation matrix for this rotation */ ) { float s1, s2, s3, c1, c2, c3; @@ -181,9 +181,9 @@ void Quat2Euler( #else const Quaternion quat, /* i : quaternion describing the rotation */ #endif - float *yaw, /* o : yaw */ - float *pitch, /* o : pitch */ - float *roll /* o : roll */ + float *yaw, /* o : yaw */ + float *pitch, /* o : pitch */ + float *roll /* o : roll */ ) { if ( quat.w != -3.0 ) @@ -310,11 +310,11 @@ void rotateFrame_shd( HEAD_TRACK_DATA_HANDLE hHeadTrackData, /* i : head track handle */ float output[][L_FRAME48k], /* i/o: unrotated HOA3 signal buffer in TD */ #ifndef EXT_RENDERER - const int32_t output_fs, /* i : output sampling frequency */ + const int32_t output_fs, /* i : output sampling frequency */ #endif - const int16_t subframe_len, /* i : subframe length per channel */ - const IVAS_OUTPUT_SETUP hTransSetup, /* i : format for rotation */ - const int16_t subframe_idx /* i : subframe index */ + const int16_t subframe_len, /* i : subframe length per channel */ + const IVAS_OUTPUT_SETUP hTransSetup, /* i : format for rotation */ + const int16_t subframe_idx /* i : subframe index */ ) { int16_t i, l, n, m; @@ -445,12 +445,12 @@ void rotateFrame_sd( HEAD_TRACK_DATA_HANDLE hHeadTrackData, /* i : head track handle */ float output[][L_FRAME48k], /* i/o: unrotated SD signal buffer in TD */ #ifndef EXT_RENDERER - const int32_t output_Fs, /* i : output sampling frequency */ + const int32_t output_Fs, /* i : output sampling frequency */ #endif - const int16_t subframe_len, /* i : subframe length per channel */ - const IVAS_OUTPUT_SETUP hTransSetup, /* i : format for rotation */ - const EFAP_HANDLE hEFAPdata, /* i : EFAP structure */ - const int16_t subframe_idx /* i : subframe index */ + const int16_t subframe_len, /* i : subframe length per channel */ + const IVAS_OUTPUT_SETUP hTransSetup, /* i : format for rotation */ + const EFAP_HANDLE hEFAPdata, /* i : EFAP structure */ + const int16_t subframe_idx /* i : subframe index */ ) { int16_t i, j; @@ -934,7 +934,7 @@ static float SHrot_w( } } - void SHrotmatgen( +void SHrotmatgen( float SHrotmat[HEADROT_SHMAT_DIM][HEADROT_SHMAT_DIM], /* o : rotation matrix in SHD */ float Rmat[3][3], /* i : real-space rotation matrix */ const int16_t order /* i : ambisonics order */ diff --git a/lib_rend/ivas_stat_rend.h b/lib_rend/ivas_stat_rend.h index 21b5e3be29..a38b8d96c1 100644 --- a/lib_rend/ivas_stat_rend.h +++ b/lib_rend/ivas_stat_rend.h @@ -92,10 +92,11 @@ typedef struct ivas_LS_setup_custom } LSSETUP_CUSTOM_STRUCT, *LSSETUP_CUSTOM_HANDLE; /* Channel types in a channel-based config */ -typedef enum { - CHANNEL_TYPE_UNUSED = 0, - CHANNEL_TYPE_SPEAKER, - CHANNEL_TYPE_LFE +typedef enum +{ + CHANNEL_TYPE_UNUSED = 0, + CHANNEL_TYPE_SPEAKER, + CHANNEL_TYPE_LFE } ChannelType; #endif /* IVAS_STAT_REND_H */ diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index fb928d637d..a1aad87651 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -216,7 +216,7 @@ static void accumulate2dArrayToBuffer( * * In-place saturation control for multichannel buffers with adaptive release time * - * + * *-------------------------------------------------------------------*/ /*! r: number of clipped output samples */ -- GitLab From 08c34b5f1f4f874409624f07457ad8fa2f6e4553 Mon Sep 17 00:00:00 2001 From: Archit Tamarapu Date: Tue, 8 Nov 2022 18:35:18 +0100 Subject: [PATCH 088/101] [formatting] apply patch from CI job --- apps/renderer.c | 4 ++-- lib_rend/ivas_crend.c | 15 +++++++-------- lib_rend/lib_rend.c | 16 ++++++++-------- 3 files changed, 17 insertions(+), 18 deletions(-) diff --git a/apps/renderer.c b/apps/renderer.c index c7c1b8cf8f..d626db7d42 100644 --- a/apps/renderer.c +++ b/apps/renderer.c @@ -659,7 +659,7 @@ int main( } /* === Configure === */ - if ( ( error = IVAS_REND_InitConfig( hIvasRend, headRotReader != NULL, strlen(args.renderConfigFilePath) != 0 ) ) != IVAS_ERR_OK ) + if ( ( error = IVAS_REND_InitConfig( hIvasRend, headRotReader != NULL, strlen( args.renderConfigFilePath ) != 0 ) ) != IVAS_ERR_OK ) { exit( -1 ); } @@ -667,7 +667,7 @@ int main( if ( args.renderConfigFilePath[0] != '\0' ) { IVAS_RENDER_CONFIG_DATA renderConfig; - + /* sanity check */ if ( args.outConfig.audioConfig != IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM ) { diff --git a/lib_rend/ivas_crend.c b/lib_rend/ivas_crend.c index 698612b1ad..d1b79ca3d5 100644 --- a/lib_rend/ivas_crend.c +++ b/lib_rend/ivas_crend.c @@ -1277,14 +1277,13 @@ ivas_error ivas_rend_openCrend( hCrend->hTrack = NULL; } - if ( ( hRendCfg != NULL ) && (hRendCfg->roomAcoustics.late_reverb_on ) ) + if ( ( hRendCfg != NULL ) && ( hRendCfg->roomAcoustics.late_reverb_on ) ) { - if ( ( error = ivas_reverb_open( &(hCrend->hReverb), - getIvasAudioConfigFromRendAudioConfig( inConfig ), - pCrend->hHrtfCrend, - hRendCfg, - output_Fs - ) ) != IVAS_ERR_OK ) + if ( ( error = ivas_reverb_open( &( hCrend->hReverb ), + getIvasAudioConfigFromRendAudioConfig( inConfig ), + pCrend->hHrtfCrend, + hRendCfg, + output_Fs ) ) != IVAS_ERR_OK ) { return error; } @@ -1343,7 +1342,7 @@ ivas_error ivas_rend_initCrend( /* set BRIR flag */ use_brir = false; - if ( (hRendCfg != NULL && hRendCfg->roomAcoustics.use_brir ) || outConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM ) + if ( ( hRendCfg != NULL && hRendCfg->roomAcoustics.use_brir ) || outConfig == IVAS_REND_AUDIO_CONFIG_BINAURAL_ROOM ) { use_brir = true; } diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index 0572f560f0..a7966aa4da 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -152,12 +152,12 @@ struct IVAS_REND IVAS_REND_AudioConfig outputConfig; EFAP_WRAPPER efapOutWrapper; IVAS_LSSETUP_CUSTOM_STRUCT customLsOut; - + int8_t enableHeadRotation; IVAS_REND_HeadRotData headRotData; int8_t rendererConfigEnabled; - RENDER_CONFIG_DATA *hRendererConfig; /* Renderer config pointer */ + RENDER_CONFIG_DATA *hRendererConfig; /* Renderer config pointer */ }; static IVAS_QUATERNION quaternionInit( @@ -1747,9 +1747,9 @@ static ivas_error initSbaPanGainsForSbaOut( } static ivas_error updateSbaPanGains( - input_sba *inputSba, - const IVAS_REND_AudioConfig outConfig, - RENDER_CONFIG_DATA *hRendCfg ) + input_sba *inputSba, + const IVAS_REND_AudioConfig outConfig, + RENDER_CONFIG_DATA *hRendCfg ) { ivas_error error; IVAS_REND_AudioConfig inConfig; @@ -2672,8 +2672,8 @@ ivas_error IVAS_REND_FeedInputObjectMetadata( } ivas_error IVAS_REND_InitConfig( IVAS_REND_HANDLE st, - bool headRotationEnabled, - bool rendererConfigEnabled ) + bool headRotationEnabled, + bool rendererConfigEnabled ) { ivas_error error; @@ -2694,7 +2694,7 @@ ivas_error IVAS_REND_InitConfig( IVAS_REND_HANDLE st, { st->rendererConfigEnabled = 0; } - + if ( ( error = ivas_render_config_open( &( st->hRendererConfig ) ) ) != IVAS_ERR_OK ) { return error; -- GitLab From f97bb51ef9af7fb1cfb9de1fa72d3fa305274e45 Mon Sep 17 00:00:00 2001 From: Archit Tamarapu Date: Tue, 8 Nov 2022 19:02:18 +0100 Subject: [PATCH 089/101] [ci] pytest.ini - prevent pytest from running renderer tests - comment out external-renderer-cmake-vs-decoder-pytest and move to tests/renderer/run_test_renderer_vs_decoder.sh - add .external-renderer-pytest-on-merge-request to be enabled after merge to main --- .gitlab-ci.yml | 31 ++++++++++++++++++- pytest.ini | 3 +- .../renderer/run_test_renderer_vs_decoder.sh | 10 ++++++ 3 files changed, 42 insertions(+), 2 deletions(-) create mode 100755 tests/renderer/run_test_renderer_vs_decoder.sh diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index ba05b4168d..d37d77bdfe 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -372,7 +372,8 @@ external-renderer-cmake-msan-pytest: - report-junit.xml # test external renderer executable with cmake vs decoder renderer -external-renderer-cmake-vs-decoder-pytest: +# TODO @tmu @knj @sgi -> converted to script, decide whether to re-enable later +.external-renderer-cmake-vs-decoder-pytest: extends: - .test-job-linux - .rules-merge-request @@ -392,6 +393,34 @@ external-renderer-cmake-vs-decoder-pytest: junit: - report-junit.xml +# compare external renderer bitexactness between target and source branch +# TODO @knj please update +.external-renderer-pytest-on-merge-request: + extends: + - .test-job-linux + - .rules-merge-request + needs: ["build-codec-linux-make"] + stage: compare + script: + - make -j IVAS_rend + - make -j unittests + - make -j --directory scripts/td_object_renderer/object_renderer_standalone + - git checkout main + - python3 -m pytest -q --log-level ERROR -n auto -rA --junit-xml=report-junit.xml tests/renderer/test_renderer.py + - mv tests/renderer/ref tests/renderer/ref_main + - git checkout FhG/external-renderer + - python3 -m pytest -q --log-level ERROR -n auto -rA --junit-xml=report-junit.xml tests/renderer/test_renderer.py + - python scripts/batch_comp_audio.py ./tests/renderer/ref_main ./tests/renderer/ref + artifacts: + name: "mr-$CI_MERGE_REQUEST_IID--sha-$CI_COMMIT_SHORT_SHA--job-$CI_JOB_NAME--results" + when: always + paths: + - report-junit.xml + expose_as: "external renderer pytest on merge request results" + reports: + junit: + - report-junit.xml + # compare bit exactness between target and source branch ivas-pytest-on-merge-request: extends: diff --git a/pytest.ini b/pytest.ini index 4e8666cb52..bb4169677b 100644 --- a/pytest.ini +++ b/pytest.ini @@ -1,7 +1,8 @@ # pytest.ini # note: per convention, this file is placed in the root directory of the repository [pytest] -addopts = -ra --tb=short --basetemp=./tmp -n auto -v +# TODO remove ignore after tests are harmonized +addopts = -ra --tb=short --basetemp=./tmp -n auto -v --ignore=tests/renderer # Write captured system-out log messages to JUnit report. junit_logging = system-out # Do not capture log information for passing tests to JUnit report. diff --git a/tests/renderer/run_test_renderer_vs_decoder.sh b/tests/renderer/run_test_renderer_vs_decoder.sh new file mode 100755 index 0000000000..215a6435b0 --- /dev/null +++ b/tests/renderer/run_test_renderer_vs_decoder.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +# WARNING! This script is a temporary helper, ideally these steps should be done manually and the pytest suite also run manually +cd ../../ +mkdir build +cmake -B build -G "Unix Makefiles" -DDEC_TO_REND_FLOAT_DUMP=true -DCOPY_EXECUTABLES_FROM_BUILD_DIR=true +cmake --build build -- -j +python3 -m pytest -q -n 1 -rA tests/renderer/test_renderer_vs_decoder.py + +echo "WARNING! Existing executables in root were overwritten!" -- GitLab From aa9fbeb5e3dfbb3383468af4eaf0d4a9d1252ed3 Mon Sep 17 00:00:00 2001 From: Jan Kiene Date: Wed, 9 Nov 2022 08:50:34 +0100 Subject: [PATCH 090/101] first batch of work for ext-rend-pytest-on-mr --- .gitlab-ci.yml | 61 +++++++++++++++++++++++++++++++++++++------------- 1 file changed, 46 insertions(+), 15 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index d37d77bdfe..0a3b6145d2 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -44,8 +44,21 @@ stages: .get-previous-merge-commit-sha: &get-previous-merge-commit-sha - previous_merge_commit=$(git --no-pager log --merges HEAD~1 -n 1 --pretty=format:%H) -.merge_request_comparison_setup: - &merge_request_comparison_setup ### build test binaries, initial clean for paranoia reasons +.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) + + + +.merge-request-comparison-setup-codec: + &merge-request-comparison-setup-codec ### build test binaries, initial clean for paranoia reasons - make clean - mkdir build - cd build @@ -61,14 +74,9 @@ stages: - source_branch_commit_sha=$(git rev-parse HEAD) ### checkout version to compare against - # 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-fetch-target-branch - ### 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) + - *mr-get-target-commit - git checkout $target_commit ### build reference binaries @@ -394,23 +402,46 @@ external-renderer-cmake-msan-pytest: - report-junit.xml # compare external renderer bitexactness between target and source branch -# TODO @knj please update +# TODO: to be tested after first merge .external-renderer-pytest-on-merge-request: extends: - .test-job-linux - .rules-merge-request needs: ["build-codec-linux-make"] + timeout: "12 minutes" stage: compare script: + - *print-common-info + + # some helper variables - "|| true" to prevent failures from grep not finding anything + - non_be_flag=$(echo $CI_MERGE_REQUEST_TITLE | grep -c --ignore-case "\[rend(erer)*[ -]*non[ -]*be\]") || true + - ref_using_main=$(echo $CI_MERGE_REQUEST_TITLE | grep -c --ignore-case "\[ref[ -]*using[ -]*main\]") || true + + # store the current commit hash + - source_branch_commit_sha=$(git rev-parse HEAD) + + # TODO: implement ref_using_main + + - *mr-fetch-target-branch + - *mr-get-target-commit + - git checkout $target_commit + + # run ext renderer test on target branch - make -j IVAS_rend - make -j unittests - make -j --directory scripts/td_object_renderer/object_renderer_standalone - - git checkout main - python3 -m pytest -q --log-level ERROR -n auto -rA --junit-xml=report-junit.xml tests/renderer/test_renderer.py - mv tests/renderer/ref tests/renderer/ref_main - - git checkout FhG/external-renderer + + # run ext renderer test on branch to be merged + - git checkout $source_branch_commit_sha + - make clean + - make -j IVAS_rend + - make -j unittests + - make -j --directory scripts/td_object_renderer/object_renderer_standalone - python3 -m pytest -q --log-level ERROR -n auto -rA --junit-xml=report-junit.xml tests/renderer/test_renderer.py - - python scripts/batch_comp_audio.py ./tests/renderer/ref_main ./tests/renderer/ref + - python scripts/batch_comp_audio.py ./tests/renderer/ref_main ./tests/renderer/ref | tee comparison_result.txt + # TODO: implmement actual comparison artifacts: name: "mr-$CI_MERGE_REQUEST_IID--sha-$CI_COMMIT_SHORT_SHA--job-$CI_JOB_NAME--results" when: always @@ -431,7 +462,7 @@ ivas-pytest-on-merge-request: timeout: "10 minutes" script: - *print-common-info - - *merge_request_comparison_setup + - *merge-request-comparison-setup-codec # some helper variables - "|| true" to prevent failures from grep not finding anything - non_be_flag=$(echo $CI_MERGE_REQUEST_TITLE | grep -c --ignore-case "\[non[ -]*be\]") || true @@ -479,7 +510,7 @@ evs-pytest-on-merge-request: timeout: "10 minutes" script: - *print-common-info - - *merge_request_comparison_setup + - *merge-request-comparison-setup-codec # some helper variables - "|| true" to prevent failures from grep not finding anything - non_be_flag=$(echo $CI_MERGE_REQUEST_TITLE | grep -c --ignore-case "\[evs[ -]*non[ -]*be\]") || true -- GitLab From fb478d63580adead46a20bda91c2279a8f3a64b2 Mon Sep 17 00:00:00 2001 From: knj Date: Wed, 9 Nov 2022 11:23:35 +0100 Subject: [PATCH 091/101] add pytest cases for be comparison on mergerequest --- tests/renderer/constants.py | 2 + tests/renderer/test_renderer_be_comparison.py | 201 ++++++++++++++++++ tests/renderer/utils.py | 16 +- 3 files changed, 216 insertions(+), 3 deletions(-) create mode 100644 tests/renderer/test_renderer_be_comparison.py diff --git a/tests/renderer/constants.py b/tests/renderer/constants.py index 1cefbda25d..cb2d580ec3 100644 --- a/tests/renderer/constants.py +++ b/tests/renderer/constants.py @@ -40,6 +40,8 @@ CUSTOM_LAYOUT_DIR = SCRIPTS_DIR.joinpath("ls_layouts") HR_TRAJECTORY_DIR = SCRIPTS_DIR.joinpath("trajectories") TESTV_DIR = SCRIPTS_DIR.joinpath("testv") +BIN_SUFFIX_MERGETARGET = "_ref" + """ Encoder commandline template """ IVAS_COD_CMD = [ str(TESTS_DIR.parent.parent.joinpath("IVAS_cod")), diff --git a/tests/renderer/test_renderer_be_comparison.py b/tests/renderer/test_renderer_be_comparison.py new file mode 100644 index 0000000000..5d89136a89 --- /dev/null +++ b/tests/renderer/test_renderer_be_comparison.py @@ -0,0 +1,201 @@ +#!/usr/bin/env python3 + +""" + (C) 2022 Baseline Development Group 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 Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation. All Rights Reserved. + + This software is protected by copyright law and by international treaties. + The Baseline Development Group 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 Corporation, Qualcomm Technologies, Inc., and VoiceAge Corporation retain full ownership + rights in their respective contributions in the software. No license of any kind, including but not + limited to patent license, of any foregoing parties is hereby granted by implication, estoppel or + otherwise. + + 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/or 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. +""" + + +import pytest +from .utils import * + + +""" Ambisonics """ + + +@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS) +@pytest.mark.parametrize("in_fmt", INPUT_FORMATS_AMBI) +def test_ambisonics(test_info, in_fmt, out_fmt): + compare_renderer_vs_mergetarget(test_info, in_fmt, out_fmt) + + +@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL) +@pytest.mark.parametrize("in_fmt", INPUT_FORMATS_AMBI) +def test_ambisonics_binaural_static(test_info, in_fmt, out_fmt): + compare_renderer_vs_mergetarget(test_info, in_fmt, out_fmt) + + +@pytest.mark.parametrize("trj_file", HR_TRAJECTORIES_TO_TEST) +@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL) +@pytest.mark.parametrize("in_fmt", INPUT_FORMATS_AMBI) +def test_ambisonics_binaural_headrotation(test_info, in_fmt, out_fmt, trj_file): + compare_renderer_vs_mergetarget( + test_info, + in_fmt, + out_fmt, + trj_file=HR_TRAJECTORY_DIR.joinpath(f"{trj_file}.csv"), + ) + + +""" Multichannel """ + + +@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS) +@pytest.mark.parametrize("in_fmt", INPUT_FORMATS_MC) +def test_multichannel(test_info, in_fmt, out_fmt): + compare_renderer_vs_mergetarget(test_info, in_fmt, out_fmt) + + +@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL) +@pytest.mark.parametrize("in_fmt", INPUT_FORMATS_MC) +def test_multichannel_binaural_static(test_info, in_fmt, out_fmt): + if in_fmt in ["MONO", "STEREO"]: + pytest.skip("MONO or STEREO to Binaural rendering unsupported") + + compare_renderer_vs_mergetarget(test_info, in_fmt, out_fmt) + + +@pytest.mark.parametrize("trj_file", HR_TRAJECTORIES_TO_TEST) +@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL) +@pytest.mark.parametrize("in_fmt", INPUT_FORMATS_MC) +def test_multichannel_binaural_headrotation(test_info, in_fmt, out_fmt, trj_file): + if in_fmt in ["MONO", "STEREO"]: + pytest.skip("MONO or STEREO to Binaural rendering unsupported") + + compare_renderer_vs_mergetarget( + test_info, + in_fmt, + out_fmt, + trj_file=HR_TRAJECTORY_DIR.joinpath(f"{trj_file}.csv"), + ) + + +""" ISM """ + + +@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS) +@pytest.mark.parametrize("in_fmt", INPUT_FORMATS_ISM) +def test_ism(test_info, in_fmt, out_fmt): + compare_renderer_vs_mergetarget( + test_info, in_fmt, out_fmt, in_meta_files=FORMAT_TO_METADATA_FILES[in_fmt] + ) + + +@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL) +@pytest.mark.parametrize("in_fmt", INPUT_FORMATS_ISM) +def test_ism_binaural_static(test_info, in_fmt, out_fmt): + try: + in_meta_files = FORMAT_TO_METADATA_FILES[in_fmt] + except: + in_meta_files = None + + compare_renderer_vs_mergetarget( + test_info, in_fmt, out_fmt, in_meta_files=in_meta_files + ) + + +@pytest.mark.parametrize("trj_file", HR_TRAJECTORIES_TO_TEST) +@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL) +@pytest.mark.parametrize("in_fmt", INPUT_FORMATS_ISM) +def test_ism_binaural_headrotation(test_info, in_fmt, out_fmt, trj_file): + try: + in_meta_files = FORMAT_TO_METADATA_FILES[in_fmt] + except: + in_meta_files = None + + compare_renderer_vs_mergetarget( + test_info, + in_fmt, + out_fmt, + trj_file=HR_TRAJECTORY_DIR.joinpath(f"{trj_file}.csv"), + in_meta_files=in_meta_files, + ) + + +""" MASA """ +# TODO: MASA inputs not supported yet + +""" Custom loudspeaker layouts """ + + +@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS) +@pytest.mark.parametrize("in_layout", CUSTOM_LS_TO_TEST) +def test_custom_ls_input(test_info, in_layout, out_fmt): + compare_renderer_vs_mergetarget( + test_info, CUSTOM_LAYOUT_DIR.joinpath(f"{in_layout}.txt"), out_fmt + ) + + +@pytest.mark.parametrize("out_fmt", CUSTOM_LS_TO_TEST) +@pytest.mark.parametrize("in_fmt", OUTPUT_FORMATS) +def test_custom_ls_output(test_info, in_fmt, out_fmt): + compare_renderer_vs_mergetarget( + test_info, in_fmt, CUSTOM_LAYOUT_DIR.joinpath(f"{out_fmt}.txt") + ) + + +@pytest.mark.parametrize("out_fmt", CUSTOM_LS_TO_TEST) +@pytest.mark.parametrize("in_fmt", CUSTOM_LS_TO_TEST) +def test_custom_ls_input_output(test_info, in_fmt, out_fmt): + compare_renderer_vs_mergetarget( + test_info, + CUSTOM_LAYOUT_DIR.joinpath(f"{in_fmt}.txt"), + CUSTOM_LAYOUT_DIR.joinpath(f"{out_fmt}.txt"), + ) + + +@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL) +@pytest.mark.parametrize("in_layout", CUSTOM_LS_TO_TEST) +def test_custom_ls_input_binaural(test_info, in_layout, out_fmt): + compare_renderer_vs_mergetarget( + test_info, + CUSTOM_LAYOUT_DIR.joinpath(f"{in_layout}.txt"), + out_fmt, + ) + + +@pytest.mark.parametrize("trj_file", HR_TRAJECTORIES_TO_TEST) +@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS_BINAURAL) +@pytest.mark.parametrize("in_layout", CUSTOM_LS_TO_TEST) +def test_custom_ls_input_binaural_headrotation(test_info, in_layout, out_fmt, trj_file): + compare_renderer_vs_mergetarget( + test_info, + CUSTOM_LAYOUT_DIR.joinpath(f"{in_layout}.txt"), + out_fmt, + trj_file=HR_TRAJECTORY_DIR.joinpath(f"{trj_file}.csv"), + ) + + +""" Metadata / scene description input """ + + +@pytest.mark.parametrize("out_fmt", OUTPUT_FORMATS) +@pytest.mark.parametrize("in_fmt", METADATA_SCENES_TO_TEST) +def test_metadata(test_info, in_fmt, out_fmt): + compare_renderer_vs_mergetarget( + test_info, + "META", + out_fmt, + metadata_input=TEST_VECTOR_DIR.joinpath(f"{in_fmt}.txt"), + ) diff --git a/tests/renderer/utils.py b/tests/renderer/utils.py index 9811d73500..3fbf6521a6 100644 --- a/tests/renderer/utils.py +++ b/tests/renderer/utils.py @@ -151,6 +151,7 @@ def run_renderer( metadata_input: Optional[str] = None, in_meta_files: Optional[list] = None, trj_file: Optional[str] = None, + binary_suffix: str = "", ) -> Tuple[np.ndarray, int]: """CuT creation with standalone renderer""" if trj_file is not None: @@ -175,6 +176,9 @@ def run_renderer( out_file = str(OUTPUT_PATH_CUT.joinpath(f"{in_name}_to_{out_name}{trj_name}.wav")) + # append suffix to binary filename + RENDERER_CMD[0] += binary_suffix + cmd = RENDERER_CMD[:] cmd[2] = str(in_file) cmd[4] = str(in_fmt) @@ -259,9 +263,7 @@ def run_crend_unittest( in_file = FORMAT_TO_FILE[in_fmt] in_name = in_fmt - out_file = str( - OUTPUT_PATH_REF.joinpath(f"{in_name}_to_{out_name}{trj_name}.wav") - ) + out_file = str(OUTPUT_PATH_REF.joinpath(f"{in_name}_to_{out_name}{trj_name}.wav")) cmd = CREND_CMD[:] cmd[6] = FORMAT_TO_CREND_FORMAT[str(in_fmt)] @@ -384,6 +386,14 @@ def run_pyscripts( return pyaudio3dtools.audiofile.readfile(out_file) +def compare_renderer_vs_mergetarget(test_info, in_fmt, out_fmt, **kwargs): + ref, ref_fs = run_renderer(in_fmt, out_fmt, **kwargs) + cut, cut_fs = run_renderer( + in_fmt, out_fmt, binary_suffix=BIN_SUFFIX_MERGETARGET, **kwargs + ) + check_BE(test_info, ref, ref_fs, cut, cut_fs) + + def compare_renderer_vs_pyscripts(test_info, in_fmt, out_fmt, **kwargs): ref, ref_fs = run_pyscripts(in_fmt, out_fmt, **kwargs) cut, cut_fs = run_renderer(in_fmt, out_fmt, **kwargs) -- GitLab From f8a289fa3814cdd689dca3ab41427fd1becf833a Mon Sep 17 00:00:00 2001 From: knj Date: Wed, 9 Nov 2022 11:31:02 +0100 Subject: [PATCH 092/101] use new test for BE comparison --- .gitlab-ci.yml | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 0a3b6145d2..e7e2754712 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -408,46 +408,49 @@ external-renderer-cmake-msan-pytest: - .test-job-linux - .rules-merge-request needs: ["build-codec-linux-make"] - timeout: "12 minutes" + # TODO: set reasonable timeout, will most likely take less + timeout: "20 minutes" stage: compare script: - *print-common-info # some helper variables - "|| true" to prevent failures from grep not finding anything - non_be_flag=$(echo $CI_MERGE_REQUEST_TITLE | grep -c --ignore-case "\[rend(erer)*[ -]*non[ -]*be\]") || true - - ref_using_main=$(echo $CI_MERGE_REQUEST_TITLE | grep -c --ignore-case "\[ref[ -]*using[ -]*main\]") || true + # TODO: needs splitting the test between reference and cut generation + #- ref_using_main=$(echo $CI_MERGE_REQUEST_TITLE | grep -c --ignore-case "\[ref[ -]*using[ -]*main\]") || true # store the current commit hash - source_branch_commit_sha=$(git rev-parse HEAD) - # TODO: implement ref_using_main - - *mr-fetch-target-branch - *mr-get-target-commit - git checkout $target_commit - # run ext renderer test on target branch + # build reference binaries - make -j IVAS_rend - - make -j unittests - - make -j --directory scripts/td_object_renderer/object_renderer_standalone - - python3 -m pytest -q --log-level ERROR -n auto -rA --junit-xml=report-junit.xml tests/renderer/test_renderer.py - - mv tests/renderer/ref tests/renderer/ref_main + - mv IVAS_rend IVAS_rend_ref - # run ext renderer test on branch to be merged + # back to source branch - git checkout $source_branch_commit_sha - make clean - make -j IVAS_rend - - make -j unittests - - make -j --directory scripts/td_object_renderer/object_renderer_standalone - - python3 -m pytest -q --log-level ERROR -n auto -rA --junit-xml=report-junit.xml tests/renderer/test_renderer.py - - python scripts/batch_comp_audio.py ./tests/renderer/ref_main ./tests/renderer/ref | tee comparison_result.txt - # TODO: implmement actual comparison + + # run test + - exit_code=0 + - python3 -m pytest -q --log-level ERROR -n auto -rA --junit-xml=report-junit.xml tests/renderer/test_renderer_be_comparison.py || 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" when: always paths: - report-junit.xml - expose_as: "external renderer pytest on merge request results" + expose_as: "pytest external renderer results" reports: junit: - report-junit.xml -- GitLab From 9a39ae657387dc85d5db467c786799e6189096ac Mon Sep 17 00:00:00 2001 From: knj Date: Wed, 9 Nov 2022 11:36:38 +0100 Subject: [PATCH 093/101] fix mixup of ref and cut --- tests/renderer/utils.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/renderer/utils.py b/tests/renderer/utils.py index 3fbf6521a6..928998ecdc 100644 --- a/tests/renderer/utils.py +++ b/tests/renderer/utils.py @@ -387,10 +387,10 @@ def run_pyscripts( def compare_renderer_vs_mergetarget(test_info, in_fmt, out_fmt, **kwargs): - ref, ref_fs = run_renderer(in_fmt, out_fmt, **kwargs) - cut, cut_fs = run_renderer( + ref, ref_fs = run_renderer( in_fmt, out_fmt, binary_suffix=BIN_SUFFIX_MERGETARGET, **kwargs ) + cut, cut_fs = run_renderer(in_fmt, out_fmt, **kwargs) check_BE(test_info, ref, ref_fs, cut, cut_fs) -- GitLab From 610f75bce44ed166c40aa5d934c6355ca25b7795 Mon Sep 17 00:00:00 2001 From: Archit Tamarapu Date: Wed, 9 Nov 2022 11:31:38 +0100 Subject: [PATCH 094/101] - remove IVAS_REND.enableHeadRotation since it is part of IVAS_REND.headRotData - fix a bug in compare_audio.py --- apps/renderer.c | 2 +- lib_rend/lib_rend.c | 17 ++++++----------- lib_rend/lib_rend.h | 1 - tests/renderer/compare_audio.py | 2 +- 4 files changed, 8 insertions(+), 14 deletions(-) diff --git a/apps/renderer.c b/apps/renderer.c index d626db7d42..8097424cec 100644 --- a/apps/renderer.c +++ b/apps/renderer.c @@ -659,7 +659,7 @@ int main( } /* === Configure === */ - if ( ( error = IVAS_REND_InitConfig( hIvasRend, headRotReader != NULL, strlen( args.renderConfigFilePath ) != 0 ) ) != IVAS_ERR_OK ) + if ( ( error = IVAS_REND_InitConfig( hIvasRend, strlen( args.renderConfigFilePath ) != 0 ) ) != IVAS_ERR_OK ) { exit( -1 ); } diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index a7966aa4da..21b60018e3 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -87,6 +87,11 @@ typedef struct const LSSETUP_CUSTOM_STRUCT *pCustomLsOut; const EFAP_WRAPPER *pEfapOutWrapper; const IVAS_REND_HeadRotData *pHeadRotData; + /* TODO @Philips : would this be a better place to store the render config data? + * bearing in mind we could have multiple inputs to the renderer, we might neeed to accomodate + * multiple rendering configurations unless one global one can be used. If this is not relevant, + * feel free to remove this TODO. + */ } rendering_context; /* Common base for input structs */ @@ -148,12 +153,12 @@ struct IVAS_REND input_mc inputsMc[RENDERER_MAX_MC_INPUTS]; input_sba inputsSba[RENDERER_MAX_SBA_INPUTS]; + /* TODO @Philips - inputConfig should not be stored here, but read from e.g. input_mc->input_base.inConfig, please remove this */ IVAS_REND_AudioConfig inputConfig; IVAS_REND_AudioConfig outputConfig; EFAP_WRAPPER efapOutWrapper; IVAS_LSSETUP_CUSTOM_STRUCT customLsOut; - int8_t enableHeadRotation; IVAS_REND_HeadRotData headRotData; int8_t rendererConfigEnabled; @@ -2672,20 +2677,10 @@ ivas_error IVAS_REND_FeedInputObjectMetadata( } ivas_error IVAS_REND_InitConfig( IVAS_REND_HANDLE st, - bool headRotationEnabled, bool rendererConfigEnabled ) { ivas_error error; - if ( headRotationEnabled ) - { - st->enableHeadRotation = 1; - } - else - { - st->enableHeadRotation = 0; - } - if ( rendererConfigEnabled ) { st->rendererConfigEnabled = 1; diff --git a/lib_rend/lib_rend.h b/lib_rend/lib_rend.h index 831823ad60..99d4b7af25 100644 --- a/lib_rend/lib_rend.h +++ b/lib_rend/lib_rend.h @@ -238,7 +238,6 @@ ivas_error IVAS_REND_FeedInputMasaMetadata( ivas_error IVAS_REND_InitConfig( IVAS_REND_HANDLE st, /* i/o: Renderer handle */ - bool headRotationEnabled, /* i : enable head rotation for binaural output, ignored for other output formats */ bool rendererConfigEnabled /* i : flag indicating if a renderer configuration file was supplied */ ); diff --git a/tests/renderer/compare_audio.py b/tests/renderer/compare_audio.py index e7bd34f6df..bf3ce26c93 100644 --- a/tests/renderer/compare_audio.py +++ b/tests/renderer/compare_audio.py @@ -52,7 +52,7 @@ def compare_audio_arrays( category=RuntimeWarning, ) left = left[:, :cmp_ch] - right = right[:, cmp_ch] + right = right[:, :cmp_ch] if left.shape[0] != right.shape[0]: cmp_smp = min(left.shape[0], right.shape[0]) -- GitLab From b022f01e36252fc618a7bdaa8b8a0108231ab871 Mon Sep 17 00:00:00 2001 From: Archit Tamarapu Date: Wed, 9 Nov 2022 13:29:49 +0100 Subject: [PATCH 095/101] [formatting] apply patch from ci job --- lib_rend/lib_rend.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index 21b60018e3..d52635b688 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -87,11 +87,11 @@ typedef struct const LSSETUP_CUSTOM_STRUCT *pCustomLsOut; const EFAP_WRAPPER *pEfapOutWrapper; const IVAS_REND_HeadRotData *pHeadRotData; - /* TODO @Philips : would this be a better place to store the render config data? - * bearing in mind we could have multiple inputs to the renderer, we might neeed to accomodate + /* TODO @Philips : would this be a better place to store the render config data? + * bearing in mind we could have multiple inputs to the renderer, we might neeed to accomodate * multiple rendering configurations unless one global one can be used. If this is not relevant, * feel free to remove this TODO. - */ + */ } rendering_context; /* Common base for input structs */ -- GitLab From d8a429b572b239dcfef22137f7d66a62b6395bc8 Mon Sep 17 00:00:00 2001 From: kiene Date: Wed, 9 Nov 2022 14:14:38 +0100 Subject: [PATCH 096/101] fix error in test and add argument for output path --- tests/renderer/utils.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tests/renderer/utils.py b/tests/renderer/utils.py index 928998ecdc..8a4ecf739b 100644 --- a/tests/renderer/utils.py +++ b/tests/renderer/utils.py @@ -151,6 +151,7 @@ def run_renderer( metadata_input: Optional[str] = None, in_meta_files: Optional[list] = None, trj_file: Optional[str] = None, + output_path_base: str = OUTPUT_PATH_CUT, binary_suffix: str = "", ) -> Tuple[np.ndarray, int]: """CuT creation with standalone renderer""" @@ -174,10 +175,8 @@ def run_renderer( in_file = FORMAT_TO_FILE[in_fmt] in_name = in_fmt - out_file = str(OUTPUT_PATH_CUT.joinpath(f"{in_name}_to_{out_name}{trj_name}.wav")) + out_file = str(output_path_base.joinpath(f"{in_name}_to_{out_name}{trj_name}.wav")) - # append suffix to binary filename - RENDERER_CMD[0] += binary_suffix cmd = RENDERER_CMD[:] cmd[2] = str(in_file) @@ -185,6 +184,8 @@ def run_renderer( cmd[6] = str(out_file) cmd[8] = str(out_fmt) + cmd[0] += binary_suffix + if in_meta_files is not None: cmd[5:5] = ["-im", *in_meta_files] @@ -388,7 +389,7 @@ def run_pyscripts( def compare_renderer_vs_mergetarget(test_info, in_fmt, out_fmt, **kwargs): ref, ref_fs = run_renderer( - in_fmt, out_fmt, binary_suffix=BIN_SUFFIX_MERGETARGET, **kwargs + in_fmt, out_fmt, binary_suffix=BIN_SUFFIX_MERGETARGET, output_path_base=OUTPUT_PATH_REF, **kwargs ) cut, cut_fs = run_renderer(in_fmt, out_fmt, **kwargs) check_BE(test_info, ref, ref_fs, cut, cut_fs) -- GitLab From 005ccc4b250030aa45ed5a0e4bfd48222d954548 Mon Sep 17 00:00:00 2001 From: Archit Tamarapu Date: Wed, 9 Nov 2022 14:17:01 +0100 Subject: [PATCH 097/101] [pre-merge] fix inconsistencies between branch and main + MSVC warnings --- .gitlab-ci.yml | 5 +++++ apps/encoder.c | 10 ++-------- apps/renderer.c | 6 +++--- lib_com/common_api_types.h | 5 +++++ lib_com/ivas_cnst.h | 2 ++ lib_com/ivas_error.h | 26 +++++++++++++++----------- lib_com/ivas_prot.h | 8 ++++++-- lib_enc/lib_enc.c | 8 ++++++++ lib_rend/lib_rend.c | 2 +- lib_util/audio_file_reader.c | 18 +++++++++++------- lib_util/audio_file_reader.h | 2 +- 11 files changed, 59 insertions(+), 33 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index e7e2754712..bfe23c7fe7 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -10,6 +10,7 @@ variables: EXIT_CODE_NON_BE: 123 EXIT_CODE_FAIL: 1 + # This sets when pipelines are created. Jobs have more specific rules to restrict them. workflow: rules: @@ -136,6 +137,7 @@ stages: rules: - if: $CI_PIPELINE_SOURCE == 'schedule' && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH + # templates to define stages and platforms .test-job-linux: tags: @@ -147,6 +149,7 @@ stages: tags: - ivas-linux + # template for test jobs on linux that need the TESTV_DIR .test-job-linux-needs-testv-dir: extends: .test-job-linux @@ -162,6 +165,7 @@ stages: exit_codes: - 123 + # --------------------------------------------------------------- # Validation jobs # --------------------------------------------------------------- @@ -180,6 +184,7 @@ check-if-branch-is-up-to-date-with-main: - echo $commits_behind_count - if [ $commits_behind_count -eq 0 ]; then exit 0; else exit 1; fi; + # --------------------------------------------------------------- # Build jobs # --------------------------------------------------------------- diff --git a/apps/encoder.c b/apps/encoder.c index 7d2de90dd0..df0cf8f9ca 100644 --- a/apps/encoder.c +++ b/apps/encoder.c @@ -264,18 +264,12 @@ int main( /*------------------------------------------------------------------------------------------* * Open input audio file *------------------------------------------------------------------------------------------*/ - int32_t inFileSampleRate = 0; - if ( AudioFileReader_open( &audioReader, arg.inputWavFilename, &inFileSampleRate ) != IVAS_ERR_OK ) + + if ( AudioFileReader_open( &audioReader, arg.inputWavFilename, arg.inputFs ) != IVAS_ERR_OK ) { fprintf( stderr, "\nCan't open %s\n\n", arg.inputWavFilename ); goto cleanup; } - if ( inFileSampleRate != 0 && /* inFileSampleRate will remain zero if input file is raw PCM */ - inFileSampleRate != arg.inputFs ) - { - fprintf( stderr, "Sampling rate mismatch: %d Hz requested, but %d Hz found in file %s\n", arg.inputFs, inFileSampleRate, arg.inputWavFilename ); - goto cleanup; - } /*------------------------------------------------------------------------------------------* * Open output bitstream file diff --git a/apps/renderer.c b/apps/renderer.c index 8097424cec..c64aaf5c93 100644 --- a/apps/renderer.c +++ b/apps/renderer.c @@ -176,7 +176,7 @@ typedef struct char executableName[RENDERER_MAX_CLI_ARG_LENGTH]; char inputFilePath[RENDERER_MAX_CLI_ARG_LENGTH]; char outputFilePath[RENDERER_MAX_CLI_ARG_LENGTH]; - int32_t sampleRate; + uint32_t sampleRate; InputConfig inConfig; OutputConfig outConfig; char inMetadataFilePaths[RENDERER_MAX_ISM_INPUTS][RENDERER_MAX_CLI_ARG_LENGTH]; @@ -626,8 +626,8 @@ int main( setupWithSingleFormatInput( args, audioFilePath, positionProvider, masaReaders ); } - int32_t inFileSampleRate = 0; - if ( AudioFileReader_open( &audioReader, audioFilePath, &inFileSampleRate ) != IVAS_ERR_OK ) + uint32_t inFileSampleRate = 0; + if ( AudioFileReader_open( &audioReader, audioFilePath, inFileSampleRate ) != IVAS_ERR_OK ) { fprintf( stderr, "Error opening file: %s\n", audioFilePath ); exit( -1 ); diff --git a/lib_com/common_api_types.h b/lib_com/common_api_types.h index 85ff059120..0fd3e7c552 100644 --- a/lib_com/common_api_types.h +++ b/lib_com/common_api_types.h @@ -79,7 +79,11 @@ typedef struct _IVAS_ISM_METADATA float gainFactor; } IVAS_ISM_METADATA; +#ifdef EXT_RENDERER typedef struct +#else +typedef struct _IVAS_QUATERNION +#endif { float w, x, y, z; @@ -127,6 +131,7 @@ typedef struct _IVAS_LS_CUSTOM_LAYOUT float elevation[IVAS_MAX_OUTPUT_CHANNELS]; int16_t num_lfe; int16_t lfe_idx[IVAS_MAX_OUTPUT_CHANNELS]; + } IVAS_CUSTOM_LS_DATA; typedef struct ivas_LS_setup_custom *IVAS_LSSETUP_CUSTOM_HANDLE; diff --git a/lib_com/ivas_cnst.h b/lib_com/ivas_cnst.h index 56c42cb287..0074be76d2 100644 --- a/lib_com/ivas_cnst.h +++ b/lib_com/ivas_cnst.h @@ -193,8 +193,10 @@ typedef enum #define IVAS_MAX_SBA_ORDER 3 /* Maximum supported Ambisonics order */ +#ifdef EXT_RENDERER #define IVAS_LIMITER_THRESHOLD 32729 /* -0.01 dBFS */ #define IVAS_LIMITER_ATTACK_SECONDS 0.005f +#endif #define IVAS_NUM_SUPPORTED_FS 3 /* number of supported sampling-rates in IVAS */ /*----------------------------------------------------------------------------------* diff --git a/lib_com/ivas_error.h b/lib_com/ivas_error.h index bfc9396f09..fdf03190de 100644 --- a/lib_com/ivas_error.h +++ b/lib_com/ivas_error.h @@ -59,7 +59,11 @@ typedef enum IVAS_ERR_INVALID_CICP_INDEX, IVAS_ERR_INVALID_BITRATE, IVAS_ERR_INVALID_MASA_CONFIG, +#ifdef EXT_RENDERER IVAS_ERR_TOO_MANY_INPUTS, +#else + IVAS_ERR_TOO_MANY_OBJECT_INPUTS, +#endif IVAS_ERR_INDEX_OUT_OF_BOUNDS, IVAS_ERR_RECONFIGURE_NOT_SUPPORTED, IVAS_ERR_INVALID_FEC_CONFIG, @@ -135,6 +139,17 @@ typedef enum static inline const char *ivas_error_to_string( ivas_error error_code ) { + /* For error categories that are likely to still have many changes to + * specific error codes, return one string per category */ + if ( ( error_code & 0xF000 ) == 0x1000 ) + { + return "API error"; + } + if ( ( error_code & 0xF000 ) == 0x2000 ) + { + return "data error"; + } + /* For categories that are unlikely to change, use more specific strings */ switch ( error_code ) { @@ -174,17 +189,6 @@ static inline const char *ivas_error_to_string( ivas_error error_code ) break; } - /* For error categories that are likely to still have many changes to - * specific error codes, return one string per category */ - if ( ( error_code & 0xF000 ) == 0x1000 ) - { - return "API error"; - } - if ( ( error_code & 0xF000 ) == 0x2000 ) - { - return "data error"; - } - return "Unknown error"; } diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index 9266f29273..eac8ec005a 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -4585,7 +4585,7 @@ void rotateFrame_shd( HEAD_TRACK_DATA_HANDLE hHeadTrackData, /* i : head track handle */ float output[][L_FRAME48k], /* i/o: unrotated HOA3 signal buffer in TD */ #ifndef EXT_RENDERER - const int32_t output_fs, /* i : output sampling frequency */ + const int32_t output_Fs, /* i : output sampling frequency */ #endif const int16_t subframe_len, /* i : subframe length per channel */ const IVAS_OUTPUT_SETUP hTransSetup, /* i : format for rotation */ @@ -4596,7 +4596,7 @@ void rotateFrame_sd( HEAD_TRACK_DATA_HANDLE hHeadTrackData, /* i : head track handle */ float output[][L_FRAME48k], /* i/o: unrotated SD signal buffer in TD */ #ifndef EXT_RENDERER - const int32_t output_fs, /* i : output sampling frequency */ + const int32_t output_Fs, /* i : output sampling frequency */ #endif const int16_t subframe_len, /* i : subframe length per channel */ const IVAS_OUTPUT_SETUP hTransSetup, /* i : format for rotation */ @@ -4768,7 +4768,11 @@ ivas_error ivas_ls_custom_output_init( void ivas_ls_custom_setup( IVAS_OUTPUT_SETUP_HANDLE hOutSetup, /* o : IVAS output setup handle */ +#ifdef EXT_RENDERER const LSSETUP_CUSTOM_STRUCT *hLsSetupCustom /* i : Custom loudspeaker setup handle */ +#else + const LSSETUP_CUSTOM_HANDLE hLsSetupCustom /* i : Custom loudspeaker setup handle */ +#endif ); diff --git a/lib_enc/lib_enc.c b/lib_enc/lib_enc.c index 73f6e69ef1..04e9ed4233 100755 --- a/lib_enc/lib_enc.c +++ b/lib_enc/lib_enc.c @@ -378,7 +378,11 @@ ivas_error IVAS_ENC_ConfigureForObjects( if ( numObjects > MAX_NUM_OBJECTS ) { +#ifdef EXT_RENDERER return IVAS_ERR_TOO_MANY_INPUTS; +#else + return IVAS_ERR_TOO_MANY_OBJECT_INPUTS; +#endif } st_ivas = hIvasEnc->st_ivas; @@ -1361,7 +1365,11 @@ const char *IVAS_ENC_GetErrorMessage( return "invalid bitrate"; case IVAS_ERR_INVALID_MASA_CONFIG: return "invalid MASA config"; +#ifdef EXT_RENDERER case IVAS_ERR_TOO_MANY_INPUTS: +#else + case IVAS_ERR_TOO_MANY_OBJECT_INPUTS: +#endif return "too many object inputs provided"; case IVAS_ERR_INDEX_OUT_OF_BOUNDS: return "index out of bounds"; diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index d52635b688..ef38d00c19 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -2101,7 +2101,7 @@ static IVAS_REND_InputId makeInputId( /* 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 getAudioConfigType( config ) << 8 | ( inputIndex + 1 ); + return (IVAS_REND_InputId) ( ( getAudioConfigType( config ) << 8 ) | ( inputIndex + 1 ) ); } static ivas_error getInputById( diff --git a/lib_util/audio_file_reader.c b/lib_util/audio_file_reader.c index d2c38cbb17..b6e7c6eb6d 100644 --- a/lib_util/audio_file_reader.c +++ b/lib_util/audio_file_reader.c @@ -32,7 +32,6 @@ #include "audio_file_reader.h" #include "tinywavein_c.h" -#include #include #include "wmops.h" @@ -55,13 +54,12 @@ static int8_t AudioFileReader_open_raw( static int8_t AudioFileReader_open_wav( AudioFileReader *self, const char *fileName, - int32_t *sampleRate ) + uint32_t expSampleRate ) { - uint32_t sampleRate_, samplesInFile; + uint32_t sampleRate, samplesInFile; int16_t bps; - self->wavFile = OpenWav( fileName, &sampleRate_, &self->numChannels, &samplesInFile, &bps ); - *sampleRate = sampleRate_; + self->wavFile = OpenWav( fileName, &sampleRate, &self->numChannels, &samplesInFile, &bps ); if ( !self->wavFile ) { @@ -69,6 +67,12 @@ static int8_t AudioFileReader_open_wav( return -1; } + if ( sampleRate != expSampleRate ) + { + fprintf( stderr, "Input wav file has unexpected samplerate (should be %d): %s\n", expSampleRate, fileName ); + return -1; + } + return 0; } @@ -77,7 +81,7 @@ static int8_t AudioFileReader_open_wav( ivas_error AudioFileReader_open( AudioFileReader **audioReader, /* o : AudioFileReader handle */ const char *fileName, /* i : path to wav/raw pcm file */ - int32_t *sampleRate /* o : sample rate of wav file, unused with pcm */ + uint32_t expSampleRate /* i : expected sample rate */ ) { AudioFileReader *self; @@ -104,7 +108,7 @@ ivas_error AudioFileReader_open( if ( fileNameLen > wavSuffixLen && strncmp( fileName + fileNameLen - wavSuffixLen, wavSuffix, wavSuffixLen ) == 0 ) { - retCode = AudioFileReader_open_wav( self, fileName, sampleRate ); + retCode = AudioFileReader_open_wav( self, fileName, expSampleRate ); } else { diff --git a/lib_util/audio_file_reader.h b/lib_util/audio_file_reader.h index 0fc9b1f4a1..c7d6ac0d6e 100644 --- a/lib_util/audio_file_reader.h +++ b/lib_util/audio_file_reader.h @@ -44,7 +44,7 @@ typedef struct AudioFileReader AudioFileReader; ivas_error AudioFileReader_open( AudioFileReader **audioReader, /* o : AudioFileReader handle */ const char *fileName, /* i : path to wav/raw pcm file */ - int32_t *sampleRate /* o : sample rate of wav file, unused with pcm */ + uint32_t expSampleRate /* i : expected sample rate */ ); /*! r: number of read samples */ -- GitLab From 5d812f05bc29af6c3948891967a59945cd3eaf52 Mon Sep 17 00:00:00 2001 From: Archit Tamarapu Date: Wed, 9 Nov 2022 14:35:09 +0100 Subject: [PATCH 098/101] [pre-merge] fix more inconsistencies + accomodate change to AudioFileReader_open() --- apps/renderer.c | 2 +- lib_rend/ivas_crend.c | 2 +- lib_rend/ivas_limiter.c | 26 ++++++++++++++++++++++++++ lib_rend/ivas_ls_custom_dec.c | 5 +++++ lib_rend/ivas_objectRenderer.c | 6 ++++-- lib_rend/ivas_rotation.c | 9 ++++++++- 6 files changed, 45 insertions(+), 5 deletions(-) diff --git a/apps/renderer.c b/apps/renderer.c index c64aaf5c93..df0b6ef871 100644 --- a/apps/renderer.c +++ b/apps/renderer.c @@ -627,7 +627,7 @@ int main( } uint32_t inFileSampleRate = 0; - if ( AudioFileReader_open( &audioReader, audioFilePath, inFileSampleRate ) != IVAS_ERR_OK ) + if ( AudioFileReader_open( &audioReader, audioFilePath, args.sampleRate ) != IVAS_ERR_OK ) { fprintf( stderr, "Error opening file: %s\n", audioFilePath ); exit( -1 ); diff --git a/lib_rend/ivas_crend.c b/lib_rend/ivas_crend.c index d1b79ca3d5..3782f5789e 100644 --- a/lib_rend/ivas_crend.c +++ b/lib_rend/ivas_crend.c @@ -31,13 +31,13 @@ *******************************************************************************************************/ #include -#include #include "options.h" #include "prot.h" #include "ivas_prot.h" #include "ivas_cnst.h" #include "ivas_rom_rend.h" #include "ivas_stat_dec.h" +#include #include "ivas_rom_binaural_crend_head.h" #ifdef EXT_RENDERER #include "lib_rend.h" diff --git a/lib_rend/ivas_limiter.c b/lib_rend/ivas_limiter.c index a4dffb180d..fd116223c5 100644 --- a/lib_rend/ivas_limiter.c +++ b/lib_rend/ivas_limiter.c @@ -39,6 +39,16 @@ #include "wmops.h" #include +#ifndef EXT_RENDERER +/*----------------------------------------------------------------------------------* + * Local constants + *----------------------------------------------------------------------------------*/ + +#define LIMITER_THRESHOLD 32729 /* -0.01 dBFS */ +#define LIMITER_ATTACK_SECONDS 0.005f + +#endif + /*-------------------------------------------------------------------* * detect_strong_saturations() * @@ -63,11 +73,19 @@ static int16_t detect_strong_saturations( *strong_saturation_cnt = 50; apply_strong_limiting = 1; } +#ifdef EXT_RENDERER else if ( max_val > 3 * IVAS_LIMITER_THRESHOLD && *strong_saturation_cnt > 0 ) +#else + else if ( max_val > 3 * LIMITER_THRESHOLD && *strong_saturation_cnt > 0 ) +#endif { apply_strong_limiting = 1; } +#ifdef EXT_RENDERER else if ( max_val > 10 * IVAS_LIMITER_THRESHOLD ) +#else + else if ( max_val > 10 * LIMITER_THRESHOLD ) +#endif { *strong_saturation_cnt += 20; *strong_saturation_cnt = min( *strong_saturation_cnt, 50 ); @@ -122,7 +140,11 @@ IVAS_LIMITER_HANDLE ivas_limiter_open( hLimiter->sampling_rate = sampling_rate; hLimiter->gain = 1.f; hLimiter->release_heuristic = 0.f; +#ifdef EXT_RENDERER hLimiter->attack_constant = powf( 0.01f, 1.0f / ( IVAS_LIMITER_ATTACK_SECONDS * sampling_rate ) ); +#else + hLimiter->attack_constant = powf( 0.01f, 1.0f / ( LIMITER_ATTACK_SECONDS * sampling_rate ) ); +#endif hLimiter->strong_saturation_count = 0; #ifdef DEBUGGING hLimiter->cnt_frames_limited = 0; @@ -194,7 +216,11 @@ void ivas_limiter_dec( channels[c] = output[c]; } +#ifdef EXT_RENDERER limiter_process( hLimiter, output_frame, IVAS_LIMITER_THRESHOLD, BER_detect, &hLimiter->strong_saturation_count ); +#else + limiter_process( hLimiter, output_frame, LIMITER_THRESHOLD, BER_detect, &hLimiter->strong_saturation_count ); +#endif return; } diff --git a/lib_rend/ivas_ls_custom_dec.c b/lib_rend/ivas_ls_custom_dec.c index 28bd8c1dd8..4f10420363 100644 --- a/lib_rend/ivas_ls_custom_dec.c +++ b/lib_rend/ivas_ls_custom_dec.c @@ -79,8 +79,13 @@ ivas_error ivas_ls_custom_open( *-------------------------------------------------------------------------*/ void ivas_ls_custom_setup( +#ifdef EXT_RENDERER IVAS_OUTPUT_SETUP_HANDLE hOutSetup, /* o : IVAS output setup handle */ const LSSETUP_CUSTOM_STRUCT *hLsSetupCustom /* i : Custom loudspeaker setup handle */ +#else + IVAS_OUTPUT_SETUP_HANDLE hOutSetup, /* o : IVAS output setup handle */ + const LSSETUP_CUSTOM_HANDLE hLsSetupCustom /* i : Custom loudspeaker setup handle */ +#endif ) { hOutSetup->output_config = AUDIO_CONFIG_LS_CUSTOM; diff --git a/lib_rend/ivas_objectRenderer.c b/lib_rend/ivas_objectRenderer.c index 7bd892cdac..31bc3b5e0a 100644 --- a/lib_rend/ivas_objectRenderer.c +++ b/lib_rend/ivas_objectRenderer.c @@ -31,10 +31,10 @@ *******************************************************************************************************/ #include -#include #include "options.h" #include "prot.h" #include "ivas_prot.h" +#include #include "wmops.h" #include "ivas_rom_com.h" #ifdef EXT_RENDERER @@ -271,7 +271,9 @@ void ObjRenderIVASFrame( for ( subframe_idx = 0; subframe_idx < MAX_PARAM_SPATIAL_SUBFRAMES; subframe_idx++ ) { /* Update the listener's location/orientation */ - TDREND_Update_listener_orientation( st_ivas->hBinRendererTd, st_ivas->hDecoderConfig->Opt_Headrotation, ( st_ivas->hHeadTrackData != NULL ) ? &st_ivas->hHeadTrackData->Quaternions[subframe_idx] : NULL ); + TDREND_Update_listener_orientation( st_ivas->hBinRendererTd, + st_ivas->hDecoderConfig->Opt_Headrotation, + ( st_ivas->hHeadTrackData != NULL ) ? &st_ivas->hHeadTrackData->Quaternions[subframe_idx] : NULL ); if ( ( st_ivas->hRenderConfig != NULL ) && ( st_ivas->hRenderConfig->roomAcoustics.late_reverb_on ) ) { diff --git a/lib_rend/ivas_rotation.c b/lib_rend/ivas_rotation.c index d8af4fe69a..4f5ba72d39 100644 --- a/lib_rend/ivas_rotation.c +++ b/lib_rend/ivas_rotation.c @@ -46,6 +46,7 @@ #include "wmops.h" #ifndef EXT_RENDERER + /*-----------------------------------------------------------------------* * Local Constants *-----------------------------------------------------------------------*/ @@ -54,11 +55,13 @@ #define HEADROT_SHMAT_DIM ( HEADROT_ORDER + 1 ) * ( HEADROT_ORDER + 1 ) #define HEADROT_SHMAT_DIM2 HEADROT_SHMAT_DIM *HEADROT_SHMAT_DIM + /*-----------------------------------------------------------------------* * Local Function prototypes *-----------------------------------------------------------------------*/ static void SHrotmatgen( float SHrotmat[HEADROT_SHMAT_DIM][HEADROT_SHMAT_DIM], float Rmat[3][3], const int16_t order ); + #endif /*-----------------------------------------------------------------------* @@ -310,7 +313,7 @@ void rotateFrame_shd( HEAD_TRACK_DATA_HANDLE hHeadTrackData, /* i : head track handle */ float output[][L_FRAME48k], /* i/o: unrotated HOA3 signal buffer in TD */ #ifndef EXT_RENDERER - const int32_t output_fs, /* i : output sampling frequency */ + const int32_t output_Fs, /* i : output sampling frequency */ #endif const int16_t subframe_len, /* i : subframe length per channel */ const IVAS_OUTPUT_SETUP hTransSetup, /* i : format for rotation */ @@ -934,7 +937,11 @@ static float SHrot_w( } } +#ifdef EXT_RENDERER void SHrotmatgen( +#else +static void SHrotmatgen( +#endif float SHrotmat[HEADROT_SHMAT_DIM][HEADROT_SHMAT_DIM], /* o : rotation matrix in SHD */ float Rmat[3][3], /* i : real-space rotation matrix */ const int16_t order /* i : ambisonics order */ -- GitLab From dd2f16eac782dc358deb344510279f5f775c251f Mon Sep 17 00:00:00 2001 From: Archit Tamarapu Date: Wed, 9 Nov 2022 14:55:55 +0100 Subject: [PATCH 099/101] revert changes from 005ccc4b for AudioFileReader_open() - required and cannot be wrapped in EXT_RENDERER --- apps/encoder.c | 10 ++++++++-- apps/renderer.c | 6 +++--- lib_util/audio_file_reader.c | 18 +++++++----------- lib_util/audio_file_reader.h | 2 +- 4 files changed, 19 insertions(+), 17 deletions(-) diff --git a/apps/encoder.c b/apps/encoder.c index df0cf8f9ca..7d2de90dd0 100644 --- a/apps/encoder.c +++ b/apps/encoder.c @@ -264,12 +264,18 @@ int main( /*------------------------------------------------------------------------------------------* * Open input audio file *------------------------------------------------------------------------------------------*/ - - if ( AudioFileReader_open( &audioReader, arg.inputWavFilename, arg.inputFs ) != IVAS_ERR_OK ) + int32_t inFileSampleRate = 0; + if ( AudioFileReader_open( &audioReader, arg.inputWavFilename, &inFileSampleRate ) != IVAS_ERR_OK ) { fprintf( stderr, "\nCan't open %s\n\n", arg.inputWavFilename ); goto cleanup; } + if ( inFileSampleRate != 0 && /* inFileSampleRate will remain zero if input file is raw PCM */ + inFileSampleRate != arg.inputFs ) + { + fprintf( stderr, "Sampling rate mismatch: %d Hz requested, but %d Hz found in file %s\n", arg.inputFs, inFileSampleRate, arg.inputWavFilename ); + goto cleanup; + } /*------------------------------------------------------------------------------------------* * Open output bitstream file diff --git a/apps/renderer.c b/apps/renderer.c index df0b6ef871..8097424cec 100644 --- a/apps/renderer.c +++ b/apps/renderer.c @@ -176,7 +176,7 @@ typedef struct char executableName[RENDERER_MAX_CLI_ARG_LENGTH]; char inputFilePath[RENDERER_MAX_CLI_ARG_LENGTH]; char outputFilePath[RENDERER_MAX_CLI_ARG_LENGTH]; - uint32_t sampleRate; + int32_t sampleRate; InputConfig inConfig; OutputConfig outConfig; char inMetadataFilePaths[RENDERER_MAX_ISM_INPUTS][RENDERER_MAX_CLI_ARG_LENGTH]; @@ -626,8 +626,8 @@ int main( setupWithSingleFormatInput( args, audioFilePath, positionProvider, masaReaders ); } - uint32_t inFileSampleRate = 0; - if ( AudioFileReader_open( &audioReader, audioFilePath, args.sampleRate ) != IVAS_ERR_OK ) + int32_t inFileSampleRate = 0; + if ( AudioFileReader_open( &audioReader, audioFilePath, &inFileSampleRate ) != IVAS_ERR_OK ) { fprintf( stderr, "Error opening file: %s\n", audioFilePath ); exit( -1 ); diff --git a/lib_util/audio_file_reader.c b/lib_util/audio_file_reader.c index b6e7c6eb6d..d2c38cbb17 100644 --- a/lib_util/audio_file_reader.c +++ b/lib_util/audio_file_reader.c @@ -32,6 +32,7 @@ #include "audio_file_reader.h" #include "tinywavein_c.h" +#include #include #include "wmops.h" @@ -54,12 +55,13 @@ static int8_t AudioFileReader_open_raw( static int8_t AudioFileReader_open_wav( AudioFileReader *self, const char *fileName, - uint32_t expSampleRate ) + int32_t *sampleRate ) { - uint32_t sampleRate, samplesInFile; + uint32_t sampleRate_, samplesInFile; int16_t bps; - self->wavFile = OpenWav( fileName, &sampleRate, &self->numChannels, &samplesInFile, &bps ); + self->wavFile = OpenWav( fileName, &sampleRate_, &self->numChannels, &samplesInFile, &bps ); + *sampleRate = sampleRate_; if ( !self->wavFile ) { @@ -67,12 +69,6 @@ static int8_t AudioFileReader_open_wav( return -1; } - if ( sampleRate != expSampleRate ) - { - fprintf( stderr, "Input wav file has unexpected samplerate (should be %d): %s\n", expSampleRate, fileName ); - return -1; - } - return 0; } @@ -81,7 +77,7 @@ static int8_t AudioFileReader_open_wav( ivas_error AudioFileReader_open( AudioFileReader **audioReader, /* o : AudioFileReader handle */ const char *fileName, /* i : path to wav/raw pcm file */ - uint32_t expSampleRate /* i : expected sample rate */ + int32_t *sampleRate /* o : sample rate of wav file, unused with pcm */ ) { AudioFileReader *self; @@ -108,7 +104,7 @@ ivas_error AudioFileReader_open( if ( fileNameLen > wavSuffixLen && strncmp( fileName + fileNameLen - wavSuffixLen, wavSuffix, wavSuffixLen ) == 0 ) { - retCode = AudioFileReader_open_wav( self, fileName, expSampleRate ); + retCode = AudioFileReader_open_wav( self, fileName, sampleRate ); } else { diff --git a/lib_util/audio_file_reader.h b/lib_util/audio_file_reader.h index c7d6ac0d6e..0fc9b1f4a1 100644 --- a/lib_util/audio_file_reader.h +++ b/lib_util/audio_file_reader.h @@ -44,7 +44,7 @@ typedef struct AudioFileReader AudioFileReader; ivas_error AudioFileReader_open( AudioFileReader **audioReader, /* o : AudioFileReader handle */ const char *fileName, /* i : path to wav/raw pcm file */ - uint32_t expSampleRate /* i : expected sample rate */ + int32_t *sampleRate /* o : sample rate of wav file, unused with pcm */ ); /*! r: number of read samples */ -- GitLab From 8878cca6b77b9be8cfc230fa30490bffbccfff12 Mon Sep 17 00:00:00 2001 From: Archit Tamarapu Date: Wed, 9 Nov 2022 15:14:10 +0100 Subject: [PATCH 100/101] temporarily disable FIX_EFAP_MATH since it breaks BE --- lib_com/options.h | 2 +- tests/renderer/constants.py | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/lib_com/options.h b/lib_com/options.h index 7e32d95326..42247e6582 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -146,7 +146,7 @@ #define FIX_I1_113 /* under review : MCT bit distribution optimization for SBA high bitrates*/ #define PRINT_SBA_ORDER /* Issue 179: print-out also the SBA order of IVAS SBA format to stdout */ #define EXT_RENDERER /* FhG: external renderer library and standalone application */ -#define FIX_EFAP_MATH /* fix for EFAP: remove angle quantization and a bug in polygon lookup causing incorrect gains. minor tweak for ALLRAD. non-BE for modes using EFAP */ +// #define FIX_EFAP_MATH /* fix for EFAP: remove angle quantization and a bug in polygon lookup causing incorrect gains. minor tweak for ALLRAD. non-BE for modes using EFAP */ #define FIX_124_DONT_ALLOC_PLCINFO_IN_IVAS /* Issue 124: do not allocate unused plc struct in IVAS modes which is only used in EVS mono */ #define FIX_MCT_PLC_RECOVERY /* Issue 184: scale the old synthesis part correctly in the first good frame after lost frames in MCT modes - to be activated after previous switch is merged */ #define SBA_BR_SWITCHING /* Issue 114: Changes for sba bit rate switching*/ diff --git a/tests/renderer/constants.py b/tests/renderer/constants.py index cb2d580ec3..63659f2904 100644 --- a/tests/renderer/constants.py +++ b/tests/renderer/constants.py @@ -284,6 +284,8 @@ pass_snr = { # #################################################################### # TODO needs debugging + "test_ambisonics_binaural_headrotation[FOA-BINAURAL-full_circle_in_15s]": 63, + "test_ambisonics_binaural_headrotation[FOA-BINAURAL-rotate_yaw_pitch_roll1]": 44, "test_ambisonics_binaural_headrotation[HOA2-BINAURAL-full_circle_in_15s]": 18, "test_ambisonics_binaural_headrotation[HOA3-BINAURAL-full_circle_in_15s]": 15, # Failure reason: Crend unit test does not support intermediate conversion to 7_1_4 or SHD BRIRs -- GitLab From fc4435dc79382991eb106518f5369ea3b8e28729 Mon Sep 17 00:00:00 2001 From: Archit Tamarapu Date: Wed, 9 Nov 2022 15:25:19 +0100 Subject: [PATCH 101/101] Revert "temporarily disable FIX_EFAP_MATH since it breaks BE" This reverts commit 8878cca6b77b9be8cfc230fa30490bffbccfff12. --- lib_com/options.h | 2 +- tests/renderer/constants.py | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/lib_com/options.h b/lib_com/options.h index 42247e6582..7e32d95326 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -146,7 +146,7 @@ #define FIX_I1_113 /* under review : MCT bit distribution optimization for SBA high bitrates*/ #define PRINT_SBA_ORDER /* Issue 179: print-out also the SBA order of IVAS SBA format to stdout */ #define EXT_RENDERER /* FhG: external renderer library and standalone application */ -// #define FIX_EFAP_MATH /* fix for EFAP: remove angle quantization and a bug in polygon lookup causing incorrect gains. minor tweak for ALLRAD. non-BE for modes using EFAP */ +#define FIX_EFAP_MATH /* fix for EFAP: remove angle quantization and a bug in polygon lookup causing incorrect gains. minor tweak for ALLRAD. non-BE for modes using EFAP */ #define FIX_124_DONT_ALLOC_PLCINFO_IN_IVAS /* Issue 124: do not allocate unused plc struct in IVAS modes which is only used in EVS mono */ #define FIX_MCT_PLC_RECOVERY /* Issue 184: scale the old synthesis part correctly in the first good frame after lost frames in MCT modes - to be activated after previous switch is merged */ #define SBA_BR_SWITCHING /* Issue 114: Changes for sba bit rate switching*/ diff --git a/tests/renderer/constants.py b/tests/renderer/constants.py index 63659f2904..cb2d580ec3 100644 --- a/tests/renderer/constants.py +++ b/tests/renderer/constants.py @@ -284,8 +284,6 @@ pass_snr = { # #################################################################### # TODO needs debugging - "test_ambisonics_binaural_headrotation[FOA-BINAURAL-full_circle_in_15s]": 63, - "test_ambisonics_binaural_headrotation[FOA-BINAURAL-rotate_yaw_pitch_roll1]": 44, "test_ambisonics_binaural_headrotation[HOA2-BINAURAL-full_circle_in_15s]": 18, "test_ambisonics_binaural_headrotation[HOA3-BINAURAL-full_circle_in_15s]": 15, # Failure reason: Crend unit test does not support intermediate conversion to 7_1_4 or SHD BRIRs -- GitLab